summaryrefslogtreecommitdiff
path: root/firmware/drivers/lcd-ipod.c
diff options
context:
space:
mode:
Diffstat (limited to 'firmware/drivers/lcd-ipod.c')
-rw-r--r--firmware/drivers/lcd-ipod.c47
1 files changed, 23 insertions, 24 deletions
diff --git a/firmware/drivers/lcd-ipod.c b/firmware/drivers/lcd-ipod.c
index 3f777cf7a9..ab0940d56b 100644
--- a/firmware/drivers/lcd-ipod.c
+++ b/firmware/drivers/lcd-ipod.c
@@ -71,13 +71,13 @@ static inline bool timer_check(int clock_start, int usecs)
71#define R_RAM_DATA 0x12 71#define R_RAM_DATA 0x12
72 72
73/* needed for flip */ 73/* needed for flip */
74static int addr_offset = 0; 74static int addr_offset;
75#if defined(IPOD_MINI) || defined(IPOD_MINI2G) 75#if defined(IPOD_MINI) || defined(IPOD_MINI2G)
76static int pix_offset = 0; 76static int pix_offset;
77#endif 77#endif
78 78
79/* wait for LCD with timeout */ 79/* wait for LCD with timeout */
80static void lcd_wait_write(void) 80static inline void lcd_wait_write(void)
81{ 81{
82 int start = USEC_TIMER; 82 int start = USEC_TIMER;
83 83
@@ -127,7 +127,7 @@ void lcd_init_device(void)
127{ 127{
128 lcd_cmd_and_data(R_DISPLAY_CONTROL, 0x0015); 128 lcd_cmd_and_data(R_DISPLAY_CONTROL, 0x0015);
129 lcd_set_flip(false); 129 lcd_set_flip(false);
130 lcd_cmd_and_data(R_ENTRY_MODE, 0x0010); 130 lcd_cmd_and_data(R_ENTRY_MODE, 0x0000);
131 131
132#ifdef APPLE_IPOD4G 132#ifdef APPLE_IPOD4G
133 outl(inl(0x6000d004) | 0x4, 0x6000d004); /* B02 enable */ 133 outl(inl(0x6000d004) | 0x4, 0x6000d004); /* B02 enable */
@@ -180,29 +180,29 @@ void lcd_set_flip(bool yesno)
180{ 180{
181#if defined(IPOD_MINI) || defined(IPOD_MINI2G) 181#if defined(IPOD_MINI) || defined(IPOD_MINI2G)
182 if (yesno) { 182 if (yesno) {
183 /* 160x112, inverse SEG & COM order */ 183 /* 168x112, inverse COM order */
184 lcd_cmd_and_data(R_DRV_OUTPUT_CONTROL, 0x030d); 184 lcd_cmd_and_data(R_DRV_OUTPUT_CONTROL, 0x020d);
185 lcd_cmd_and_data(R_1ST_SCR_DRV_POS, 0x8316); /* 22..131 */ 185 lcd_cmd_and_data(R_1ST_SCR_DRV_POS, 0x8316); /* 22..131 */
186 addr_offset = (22 << 5) | 3; 186 addr_offset = (22 << 5) | (20 - 3);
187 pix_offset = 6; 187 pix_offset = 6;
188 } else { 188 } else {
189 /* 160x112 */ 189 /* 168x112, inverse SEG order */
190 lcd_cmd_and_data(R_DRV_OUTPUT_CONTROL, 0x000d); 190 lcd_cmd_and_data(R_DRV_OUTPUT_CONTROL, 0x010d);
191 lcd_cmd_and_data(R_1ST_SCR_DRV_POS, 0x6d00); /* 0..109 */ 191 lcd_cmd_and_data(R_1ST_SCR_DRV_POS, 0x6d00); /* 0..109 */
192 addr_offset = 0; 192 addr_offset = 20;
193 pix_offset = 0; 193 pix_offset = 0;
194 } 194 }
195#else 195#else
196 if (yesno) { 196 if (yesno) {
197 /* 160x128, inverse COM order */ 197 /* 168x128, inverse SEG & COM order */
198 lcd_cmd_and_data(R_DRV_OUTPUT_CONTROL, 0x020f); 198 lcd_cmd_and_data(R_DRV_OUTPUT_CONTROL, 0x030f);
199 lcd_cmd_and_data(R_1ST_SCR_DRV_POS, 0x8304); /* 0..127 */ 199 lcd_cmd_and_data(R_1ST_SCR_DRV_POS, 0x8304); /* 0..127 */
200 addr_offset = (4 << 5) | 1; 200 addr_offset = (4 << 5) | (20 - 1);
201 } else { 201 } else {
202 /* 160x128, inverse SEG order */ 202 /* 168x128 */
203 lcd_cmd_and_data(R_DRV_OUTPUT_CONTROL, 0x010f); 203 lcd_cmd_and_data(R_DRV_OUTPUT_CONTROL, 0x000f);
204 lcd_cmd_and_data(R_1ST_SCR_DRV_POS, 0x7f00); /* 4..131 */ 204 lcd_cmd_and_data(R_1ST_SCR_DRV_POS, 0x7f00); /* 4..131 */
205 addr_offset = 0; 205 addr_offset = 20;
206 } 206 }
207#endif 207#endif
208} 208}
@@ -230,7 +230,7 @@ void lcd_update_rect(int x, int y, int width, int height)
230 230
231 for (; y <= ymax; y++) { 231 for (; y <= ymax; y++) {
232 unsigned char *data, *data_end; 232 unsigned char *data, *data_end;
233 int ram_addr = (x | (y << 5)) + addr_offset; 233 int ram_addr = (y << 5) + addr_offset - x;
234 234
235 lcd_cmd_and_data(R_RAM_ADDR_SET, ram_addr); 235 lcd_cmd_and_data(R_RAM_ADDR_SET, ram_addr);
236 lcd_prepare_cmd(R_RAM_DATA); 236 lcd_prepare_cmd(R_RAM_DATA);
@@ -241,19 +241,18 @@ void lcd_update_rect(int x, int y, int width, int height)
241 if (pix_offset == 6) { 241 if (pix_offset == 6) {
242 data -= 2; 242 data -= 2;
243 data_end -= 1; 243 data_end -= 1;
244 unsigned cur_word = *data++ >> 4; 244 unsigned cur_word = *data++;
245 do { 245 do {
246 cur_word |= *data++ << 4; 246 cur_word = (cur_word << 8) | *data++;
247 cur_word |= *data++ << 12; 247 cur_word = (cur_word << 8) | *data++;
248 lcd_send_data(cur_word & 0xffff); 248 lcd_send_data((cur_word >> 4) & 0xffff);
249 cur_word >>= 16;
250 } while (data < data_end); 249 } while (data < data_end);
251 } else 250 } else
252#endif 251#endif
253 { 252 {
254 do { 253 do {
255 unsigned lowbyte = *data++; 254 unsigned highbyte = *data++;
256 lcd_send_data(lowbyte | (*data++ << 8)); 255 lcd_send_data((highbyte << 8) | *data++);
257 } while (data < data_end); 256 } while (data < data_end);
258 } 257 }
259 } 258 }