1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
Index: firmware/export/config/ipodcolor.h
===================================================================
--- firmware/export/config/ipodcolor.h  (revision 29015)
+++ firmware/export/config/ipodcolor.h  (working copy)
@@ -58,6 +58,9 @@
 #define LCD_DEPTH  16   /* 65536 colours */
 #define LCD_PIXELFORMAT RGB565SWAPPED /* rgb565 byte-swapped */

+/* Define this if the LCD can shut down */
+#define HAVE_LCD_SHUTDOWN
+
 /* LCD stays visible without backlight - simulator hint */
 #define HAVE_TRANSFLECTIVE_LCD

Index: firmware/export/config/ipodnano1g.h
===================================================================
--- firmware/export/config/ipodnano1g.h  (revision 29015)
+++ firmware/export/config/ipodnano1g.h  (working copy)
@@ -58,6 +58,9 @@
 #define LCD_DEPTH  16   /* 65536 colours */
 #define LCD_PIXELFORMAT RGB565SWAPPED /* rgb565 byte-swapped */

+/* Define this if the LCD can shut down */
+#define HAVE_LCD_SHUTDOWN
+
 /* LCD stays visible without backlight - simulator hint */
 #define HAVE_TRANSFLECTIVE_LCD

Index: firmware/target/arm/ipod/backlight-nano_video.c
===================================================================
--- firmware/target/arm/ipod/backlight-nano_video.c  (revision 29015)
+++ firmware/target/arm/ipod/backlight-nano_video.c  (working copy)
@@ -97,7 +97,6 @@
     {
         GPIO_CLEAR_BITWISE(GPIOD_OUTPUT_VAL, 0x80);
         GPIO_CLEAR_BITWISE(GPIOB_OUTPUT_VAL, 0x08);
-        sleep(HZ/20);
     }
     enabled = on;
 }
Index: firmware/target/arm/ipod/lcd-color_nano.c
===================================================================
--- firmware/target/arm/ipod/lcd-color_nano.c  (revision 29015)
+++ firmware/target/arm/ipod/lcd-color_nano.c  (working copy)
@@ -31,6 +31,7 @@
 #include "kernel.h"
 #include "system.h"
 #include "hwcompat.h"
+#include "backlight-target.h"

 /* LCD command codes for HD66789R */
 #define LCD_CNTL_RAM_ADDR_SET           0x21
@@ -39,7 +40,7 @@
 #define LCD_CNTL_VERT_RAM_ADDR_POS      0x45

 /*** globals ***/
-int lcd_type = 1; /* 0 = "old" Color/Photo, 1 = "new" Color & Nano */
+int lcd_type = 1; /* 0,2 = "old" Color/Photo; 1,3 = similar to HD66789R */

 static inline void lcd_wait_write(void)
 {
@@ -48,7 +49,7 @@

 static void lcd_cmd_data(unsigned cmd, unsigned data)
 {
-    if (lcd_type == 0) {  /* 16 bit transfers */
+    if ((lcd_type&1) == 0) {  /* 16 bit transfers */
         lcd_wait_write();
         LCD2_PORT = LCD2_CMD_MASK | cmd;
         lcd_wait_write();
@@ -91,22 +92,11 @@
     if (IPOD_HW_REVISION == 0x60000) {
         lcd_type = 0;
     } else {
-        int gpio_a01, gpio_a04;
-
-        /* A01 */
-        gpio_a01 = (GPIOA_INPUT_VAL & 0x2) >> 1;
-        /* A04 */
-        gpio_a04 = (GPIOA_INPUT_VAL & 0x10) >> 4;
-
-        if (((gpio_a01 << 1) | gpio_a04) == 0 || ((gpio_a01 << 1) | gpio_a04) == 2) {
-            lcd_type = 0;
-        } else {
-            lcd_type = 1;
-        }
+        lcd_type = (GPIOA_INPUT_VAL & 0x2) | ((GPIOA_INPUT_VAL & 0x10) >> 4);
     }
-    if (lcd_type == 0) {
+    if ((lcd_type&1) == 0) {
         lcd_cmd_data(0xef, 0x0);
-        lcd_cmd_data(0x1, 0x0);
+        lcd_cmd_data(0x01, 0x0);
         lcd_cmd_data(0x80, 0x1);
         lcd_cmd_data(0x10, 0xc);
         lcd_cmd_data(0x18, 0x6);
@@ -114,12 +104,49 @@
         lcd_cmd_data(0x7e, 0x5);
         lcd_cmd_data(0x7f, 0x1);
     }
-
 #elif CONFIG_LCD == LCD_IPODNANO
     /* iPodLinux doesn't appear have any LCD init code for the Nano */
 #endif
 }

+#ifdef HAVE_LCD_SHUTDOWN
+void lcd_shutdown(void) {
+    /* Immediately switch off the backlight to avoid flashing. */
+#if defined(IPOD_NANO)
+    _backlight_hw_enable(false);
+#elif defined(IPOD_COLOR)
+    _backlight_off();
+#endif
+
+    if ((lcd_type&1) == 0) {
+        /* lcd_type 0 and 2 */
+        lcd_cmd_data(0x00EF, 0x0000);
+        lcd_cmd_data(0x0080, 0x0000); udelay(1000);
+        lcd_cmd_data(0x0001, 0x0001);
+    } else if (lcd_type == 1) {
+        /* lcd_type 1 */
+        lcd_cmd_data(0x0007, 0x0236); sleep( 40*HZ/1000);
+        lcd_cmd_data(0x0007, 0x0226); sleep( 40*HZ/1000);
+        lcd_cmd_data(0x0007, 0x0204);
+        lcd_cmd_data(0x0010, 0x7574); sleep(200*HZ/1000);
+        lcd_cmd_data(0x0010, 0x7504); sleep( 50*HZ/1000);
+        lcd_cmd_data(0x0010, 0x0501);
+    } else {
+        /* lcd_type 3 */
+        lcd_cmd_data(0x0007, 0x4016); sleep( 20*HZ/1000);
+        lcd_cmd_data(0x0059, 0x0011); sleep( 20*HZ/1000);
+        lcd_cmd_data(0x0059, 0x0003); sleep( 20*HZ/1000);
+        lcd_cmd_data(0x0059, 0x0002); sleep( 20*HZ/1000);
+        lcd_cmd_data(0x0010, 0x6360); sleep(200*HZ/1000);
+        lcd_cmd_data(0x0010, 0x6300); sleep( 50*HZ/1000);
+        lcd_cmd_data(0x0010, 0x0300);
+        lcd_cmd_data(0x0059, 0x0000);
+        lcd_cmd_data(0x0007, 0x4004);
+        lcd_cmd_data(0x0010, 0x0301);
+    }
+}
+#endif
+
 /* Helper function to set up drawing region and start drawing */
 static void lcd_setup_drawing_region(int x, int y, int width, int height)
 {
@@ -139,7 +166,7 @@
 #endif

     /* setup the drawing region */
-    if (lcd_type == 0) {
+    if ((lcd_type&1) == 0) {
         lcd_cmd_data(0x12, y0);      /* start vert */
         lcd_cmd_data(0x13, x0);      /* start horiz */
         lcd_cmd_data(0x15, y1);      /* end vert */