summaryrefslogtreecommitdiff
path: root/firmware/target/arm
diff options
context:
space:
mode:
Diffstat (limited to 'firmware/target/arm')
-rw-r--r--firmware/target/arm/s5l8700/ipodnano2g/backlight-nano2g.c11
-rw-r--r--firmware/target/arm/s5l8700/ipodnano2g/lcd-nano2g.c490
2 files changed, 471 insertions, 30 deletions
diff --git a/firmware/target/arm/s5l8700/ipodnano2g/backlight-nano2g.c b/firmware/target/arm/s5l8700/ipodnano2g/backlight-nano2g.c
index 705b5858bf..060dcccae4 100644
--- a/firmware/target/arm/s5l8700/ipodnano2g/backlight-nano2g.c
+++ b/firmware/target/arm/s5l8700/ipodnano2g/backlight-nano2g.c
@@ -21,10 +21,15 @@
21#include <stdbool.h> 21#include <stdbool.h>
22 22
23#include "config.h" 23#include "config.h"
24#include "kernel.h"
24#include "backlight.h" 25#include "backlight.h"
25#include "backlight-target.h" 26#include "backlight-target.h"
26#include "pmu-target.h" 27#include "pmu-target.h"
27 28
29#ifdef HAVE_LCD_SLEEP
30void lcd_awake(void);
31void lcd_update(void);
32#endif
28 33
29void _backlight_set_brightness(int brightness) 34void _backlight_set_brightness(int brightness)
30{ 35{
@@ -33,6 +38,12 @@ void _backlight_set_brightness(int brightness)
33 38
34void _backlight_on(void) 39void _backlight_on(void)
35{ 40{
41 if(pmu_read(0x29) == 1) return;
42#ifdef HAVE_LCD_SLEEP
43 lcd_awake();
44 lcd_update();
45 sleep(HZ/10);
46#endif
36 pmu_write(0x29, 1); 47 pmu_write(0x29, 1);
37} 48}
38 49
diff --git a/firmware/target/arm/s5l8700/ipodnano2g/lcd-nano2g.c b/firmware/target/arm/s5l8700/ipodnano2g/lcd-nano2g.c
index 0600c77b62..f2d0c3458f 100644
--- a/firmware/target/arm/s5l8700/ipodnano2g/lcd-nano2g.c
+++ b/firmware/target/arm/s5l8700/ipodnano2g/lcd-nano2g.c
@@ -57,13 +57,341 @@
57#define R_ROW_ADDR_SET 0x2b 57#define R_ROW_ADDR_SET 0x2b
58#define R_MEMORY_WRITE 0x2c 58#define R_MEMORY_WRITE 0x2c
59 59
60
61/** globals **/ 60/** globals **/
62 61
63int lcd_type; /* also needed in debug-s5l8700.c */ 62int lcd_type; /* also needed in debug-s5l8700.c */
64static int xoffset; /* needed for flip */ 63static int xoffset; /* needed for flip */
65 64static bool lcd_ispowered;
66/** hardware access functions */ 65
66#ifdef HAVE_LCD_SLEEP
67
68#define SLEEP 0
69#define CMD8 1
70#define CMD16 2
71#define DATA8 3
72#define DATA16 4
73
74unsigned short lcd_init_sequence_0[] = {
75 CMD16, 0x00a4,
76 DATA16, 0x0001,
77 SLEEP, 0x0000,
78 CMD16, 0x0001,
79 DATA16, 0x0100,
80 CMD16, 0x0002,
81 DATA16, 0x0300,
82 CMD16, 0x0003,
83 DATA16, 0x1230,
84 CMD16, 0x0008,
85 DATA16, 0x0404,
86 CMD16, 0x0008,
87 DATA16, 0x0404,
88 CMD16, 0x000e,
89 DATA16, 0x0010,
90 CMD16, 0x0070,
91 DATA16, 0x1000,
92 CMD16, 0x0071,
93 DATA16, 0x0001,
94 CMD16, 0x0030,
95 DATA16, 0x0002,
96 CMD16, 0x0031,
97 DATA16, 0x0400,
98 CMD16, 0x0032,
99 DATA16, 0x0007,
100 CMD16, 0x0033,
101 DATA16, 0x0500,
102 CMD16, 0x0034,
103 DATA16, 0x0007,
104 CMD16, 0x0035,
105 DATA16, 0x0703,
106 CMD16, 0x0036,
107 DATA16, 0x0507,
108 CMD16, 0x0037,
109 DATA16, 0x0005,
110 CMD16, 0x0038,
111 DATA16, 0x0407,
112 CMD16, 0x0039,
113 DATA16, 0x000e,
114 CMD16, 0x0040,
115 DATA16, 0x0202,
116 CMD16, 0x0041,
117 DATA16, 0x0003,
118 CMD16, 0x0042,
119 DATA16, 0x0000,
120 CMD16, 0x0043,
121 DATA16, 0x0200,
122 CMD16, 0x0044,
123 DATA16, 0x0707,
124 CMD16, 0x0045,
125 DATA16, 0x0407,
126 CMD16, 0x0046,
127 DATA16, 0x0505,
128 CMD16, 0x0047,
129 DATA16, 0x0002,
130 CMD16, 0x0048,
131 DATA16, 0x0004,
132 CMD16, 0x0049,
133 DATA16, 0x0004,
134 CMD16, 0x0060,
135 DATA16, 0x0202,
136 CMD16, 0x0061,
137 DATA16, 0x0003,
138 CMD16, 0x0062,
139 DATA16, 0x0000,
140 CMD16, 0x0063,
141 DATA16, 0x0200,
142 CMD16, 0x0064,
143 DATA16, 0x0707,
144 CMD16, 0x0065,
145 DATA16, 0x0407,
146 CMD16, 0x0066,
147 DATA16, 0x0505,
148 CMD16, 0x0068,
149 DATA16, 0x0004,
150 CMD16, 0x0069,
151 DATA16, 0x0004,
152 CMD16, 0x0007,
153 DATA16, 0x0001,
154 CMD16, 0x0018,
155 DATA16, 0x0001,
156 CMD16, 0x0010,
157 DATA16, 0x1690,
158 CMD16, 0x0011,
159 DATA16, 0x0100,
160 CMD16, 0x0012,
161 DATA16, 0x0117,
162 CMD16, 0x0013,
163 DATA16, 0x0f80,
164 CMD16, 0x0012,
165 DATA16, 0x0137,
166 CMD16, 0x0020,
167 DATA16, 0x0000,
168 CMD16, 0x0021,
169 DATA16, 0x0000,
170 CMD16, 0x0050,
171 DATA16, 0x0000,
172 CMD16, 0x0051,
173 DATA16, 0x00af,
174 CMD16, 0x0052,
175 DATA16, 0x0000,
176 CMD16, 0x0053,
177 DATA16, 0x0083,
178 CMD16, 0x0090,
179 DATA16, 0x0003,
180 CMD16, 0x0091,
181 DATA16, 0x0000,
182 CMD16, 0x0092,
183 DATA16, 0x0101,
184 CMD16, 0x0098,
185 DATA16, 0x0400,
186 CMD16, 0x0099,
187 DATA16, 0x1302,
188 CMD16, 0x009a,
189 DATA16, 0x0202,
190 CMD16, 0x009b,
191 DATA16, 0x0200,
192 SLEEP, 0x0000,
193 CMD16, 0x0007,
194 DATA16, 0x0021,
195 CMD16, 0x0012,
196 DATA16, 0x0137,
197 SLEEP, 0x0000,
198 CMD16, 0x0007,
199 DATA16, 0x0021,
200 CMD16, 0x0012,
201 DATA16, 0x1137,
202 SLEEP, 0x0000,
203 CMD16, 0x0007,
204 DATA16, 0x0233,
205};
206
207unsigned short lcd_init_sequence_1[] = {
208 CMD8, 0x01,
209 DATA8, 0x00,
210 SLEEP, 0,
211 CMD8, 0xB1,
212 DATA8, 0x16,
213 DATA8, 0x03,
214 CMD8, 0xB2,
215 DATA8, 0x17,
216 DATA8, 0x03,
217 CMD8, 0xB4,
218 DATA8, 0x00,
219 CMD8, 0xB6,
220 DATA8, 0x01,
221 CMD8, 0xB7,
222 DATA8, 0x00,
223 DATA8, 0x00,
224 DATA8, 0x02,
225 DATA8, 0x00,
226 DATA8, 0x06,
227 DATA8, 0x26,
228 DATA8, 0x2D,
229 DATA8, 0x27,
230 DATA8, 0x55,
231 DATA8, 0x27,
232 CMD8, 0xB8,
233 DATA8, 0x10,
234 CMD8, 0xB9,
235 DATA8, 0x52,
236 DATA8, 0x12,
237 DATA8, 0x03,
238 CMD8, 0xC0,
239 DATA8, 0x0A,
240 DATA8, 0x10,
241 DATA8, 0x10,
242 CMD8, 0xC2,
243 DATA8, 0x14,
244 DATA8, 0x23,
245 CMD8, 0xC3,
246 DATA8, 0x12,
247 DATA8, 0x23,
248 CMD8, 0xC6,
249 DATA8, 0x48,
250 CMD8, 0xE0,
251 DATA8, 0x20,
252 DATA8, 0x71,
253 DATA8, 0x17,
254 DATA8, 0x09,
255 DATA8, 0x70,
256 DATA8, 0x0C,
257 DATA8, 0x13,
258 DATA8, 0x25,
259 CMD8, 0xE1,
260 DATA8, 0x37,
261 DATA8, 0x00,
262 DATA8, 0x63,
263 DATA8, 0x11,
264 DATA8, 0xD9,
265 DATA8, 0x00,
266 DATA8, 0x12,
267 DATA8, 0x01,
268 CMD8, 0xE2,
269 DATA8, 0x42,
270 DATA8, 0x42,
271 DATA8, 0x60,
272 DATA8, 0x08,
273 DATA8, 0xB4,
274 DATA8, 0x07,
275 DATA8, 0x0E,
276 DATA8, 0x90,
277 CMD8, 0xE3,
278 DATA8, 0x47,
279 DATA8, 0x60,
280 DATA8, 0x66,
281 DATA8, 0x09,
282 DATA8, 0x6A,
283 DATA8, 0x02,
284 DATA8, 0x0E,
285 DATA8, 0x09,
286 CMD8, 0xE4,
287 DATA8, 0x11,
288 DATA8, 0x40,
289 DATA8, 0x03,
290 DATA8, 0x0A,
291 DATA8, 0xC1,
292 DATA8, 0x0D,
293 DATA8, 0x17,
294 DATA8, 0x30,
295 CMD8, 0xE5,
296 DATA8, 0x00,
297 DATA8, 0x30,
298 DATA8, 0x77,
299 DATA8, 0x1C,
300 DATA8, 0xFB,
301 DATA8, 0x00,
302 DATA8, 0x13,
303 DATA8, 0x07,
304 CMD8, 0xE6,
305 DATA8, 0x01,
306 CMD8, 0x35,
307 DATA8, 0x00,
308 CMD8, 0x36,
309 DATA8, 0x00,
310 CMD8, 0xF2,
311 DATA8, 0x40,
312 CMD8, 0xF3,
313 DATA8, 0x50,
314 CMD8, 0xFB,
315 DATA8, 0x01,
316 CMD8, 0x11,
317 DATA8, 0x00,
318 SLEEP, 0,
319 CMD8, 0x3A,
320 DATA8, 0x65,
321 CMD8, 0x29,
322 DATA8, 0x00,
323};
324
325unsigned short lcd_init_sequence_2[] = {
326 CMD8, 0x01,
327 SLEEP, 0,
328 CMD8, 0x11,
329 SLEEP, 0,
330 CMD8, 0x3a,
331 DATA8, 0x65,
332 CMD8, 0xab,
333 CMD8, 0x35,
334 DATA8, 0x00,
335 CMD8, 0xf2,
336 DATA8, 0x01,
337 CMD8, 0xe0,
338 DATA8, 0x71,
339 DATA8, 0x76,
340 DATA8, 0x25,
341 DATA8, 0x01,
342 DATA8, 0xa5,
343 DATA8, 0x09,
344 DATA8, 0x15,
345 DATA8, 0x11,
346 CMD8, 0xe1,
347 DATA8, 0x40,
348 DATA8, 0x21,
349 DATA8, 0x64,
350 DATA8, 0x13,
351 DATA8, 0xf3,
352 DATA8, 0x0b,
353 DATA8, 0x00,
354 DATA8, 0x00,
355 CMD8, 0xe2,
356 DATA8, 0x71,
357 DATA8, 0x65,
358 DATA8, 0x24,
359 DATA8, 0x08,
360 DATA8, 0x97,
361 DATA8, 0x01,
362 DATA8, 0x15,
363 DATA8, 0x11,
364 CMD8, 0xe3,
365 DATA8, 0x51,
366 DATA8, 0x01,
367 DATA8, 0x62,
368 DATA8, 0x13,
369 DATA8, 0xf3,
370 DATA8, 0x0b,
371 DATA8, 0x00,
372 DATA8, 0x00,
373 CMD8, 0xe4,
374 DATA8, 0x71,
375 DATA8, 0x57,
376 DATA8, 0x31,
377 DATA8, 0x01,
378 DATA8, 0x82,
379 DATA8, 0x04,
380 DATA8, 0x1f,
381 DATA8, 0x11,
382 CMD8, 0xe5,
383 DATA8, 0x64,
384 DATA8, 0x41,
385 DATA8, 0x64,
386 DATA8, 0x19,
387 DATA8, 0xb3,
388 DATA8, 0x09,
389 DATA8, 0x00,
390 DATA8, 0x00,
391 CMD8, 0x29,
392};
393
394#endif /* HAVE_LCD_SLEEP */
67 395
68static inline void s5l_lcd_write_cmd_data(int cmd, int data) 396static inline void s5l_lcd_write_cmd_data(int cmd, int data)
69{ 397{
@@ -84,7 +412,21 @@ static inline void s5l_lcd_write_cmd(unsigned short cmd)
84 LCD_WCMD = cmd; 412 LCD_WCMD = cmd;
85} 413}
86 414
87static inline void s5l_lcd_write_data(int data) 415static inline void s5l_lcd_write_wcmd(unsigned short cmd)
416{
417 while (LCD_STATUS & 0x10);
418 LCD_WCMD = cmd >> 8;
419 while (LCD_STATUS & 0x10);
420 LCD_WCMD = cmd & 0xff;
421}
422
423static inline void s5l_lcd_write_data(unsigned short data)
424{
425 while (LCD_STATUS & 0x10);
426 LCD_WDATA = data & 0xff;
427}
428
429static inline void s5l_lcd_write_wdata(unsigned short data)
88{ 430{
89 while (LCD_STATUS & 0x10); 431 while (LCD_STATUS & 0x10);
90 LCD_WDATA = data >> 8; 432 LCD_WDATA = data >> 8;
@@ -125,6 +467,89 @@ void lcd_set_flip(bool yesno)
125 } 467 }
126} 468}
127 469
470bool lcd_active(void)
471{
472 return lcd_ispowered;
473}
474
475#ifdef HAVE_LCD_SLEEP
476
477void lcd_wakeup(void)
478{
479 unsigned short *lcd_init_sequence;
480 unsigned int lcd_init_sequence_length;
481 int type = lcd_type;
482
483 pmu_ldo_set_voltage(2, 17);
484 PWRCONEXT &= ~0x80;
485 PCON2 = 0x33333333;
486 PCON3 = 0x11113333;
487 PCON4 = 0x33333333;
488 PCON13 &= ~0xf; /* Set pin 0 to input */
489 PCON14 &= ~0xf0; /* Set pin 1 to input */
490
491 if((((PDAT13 & 1) == 1) && ((PDAT14 & 2) == 2))||
492 (((PDAT13 & 1) == 0) && ((PDAT14 & 2) == 0)))
493 {
494 type = 2; /* there is a third lcd type which behaves like type 7 (LDS176) but needs to be initialized differently */
495 }
496
497 if(type == 0)
498 {
499 lcd_init_sequence = lcd_init_sequence_0;
500 lcd_init_sequence_length = (sizeof(lcd_init_sequence_0) - 1)/sizeof(unsigned short);
501 }
502 else if(type == 1)
503 {
504 lcd_init_sequence = lcd_init_sequence_1;
505 lcd_init_sequence_length = (sizeof(lcd_init_sequence_1) - 1)/sizeof(unsigned short);
506 }
507 else
508 {
509 lcd_init_sequence = lcd_init_sequence_2;
510 lcd_init_sequence_length = (sizeof(lcd_init_sequence_2) - 1)/sizeof(unsigned short);
511 }
512
513 /* reset the lcd chip */
514
515 LCD_RST_TIME = 0x7FFF;
516 LCD_DRV_RST = 0;
517 sleep(0);
518 LCD_DRV_RST = 1;
519 sleep(HZ / 100);
520
521 for(unsigned int i=0;i<lcd_init_sequence_length;i+=2)
522 {
523 switch(lcd_init_sequence[i])
524 {
525 case CMD8:
526 s5l_lcd_write_cmd(lcd_init_sequence[i+1]);
527 break;
528 case DATA8:
529 s5l_lcd_write_data(lcd_init_sequence[i+1]);
530 break;
531 case CMD16:
532 s5l_lcd_write_wcmd(lcd_init_sequence[i+1]);
533 break;
534 case DATA16:
535 s5l_lcd_write_wdata(lcd_init_sequence[i+1]);
536 break;
537 case SLEEP:
538 sleep(lcd_init_sequence[i+1]);
539 break;
540 default:
541 break;
542 }
543 }
544 lcd_ispowered = true;
545}
546
547void lcd_awake(void)
548{
549 if(!lcd_active()) lcd_wakeup();
550}
551#endif
552
128void lcd_shutdown(void) 553void lcd_shutdown(void)
129{ 554{
130 pmu_write(0x2b, 0); /* Kill the backlight, instantly. */ 555 pmu_write(0x2b, 0); /* Kill the backlight, instantly. */
@@ -145,12 +570,26 @@ void lcd_shutdown(void)
145 else 570 else
146 { 571 {
147 s5l_lcd_write_cmd(R_DISPLAY_OFF); 572 s5l_lcd_write_cmd(R_DISPLAY_OFF);
148 s5l_lcd_write_data(0); 573 s5l_lcd_write_wdata(0);
149 s5l_lcd_write_data(0); 574 s5l_lcd_write_wdata(0);
150 s5l_lcd_write_cmd(R_SLEEP_IN); 575 s5l_lcd_write_cmd(R_SLEEP_IN);
151 s5l_lcd_write_data(0); 576 s5l_lcd_write_wdata(0);
152 s5l_lcd_write_data(0); 577 s5l_lcd_write_wdata(0);
153 } 578 }
579
580 PCON2 = 0;
581 PCON3 = 0;
582 PCON4 = 0;
583 PWRCONEXT |= 0x80;
584 sleep(HZ / 20);
585 pmu_ldo_set_voltage(2, 1);
586
587 lcd_ispowered = false;
588}
589
590void lcd_sleep(void)
591{
592 lcd_shutdown();
154} 593}
155 594
156/* LCD init */ 595/* LCD init */
@@ -166,18 +605,9 @@ void lcd_init_device(void)
166 else 605 else
167 lcd_type = 1; /* Similar to LDS176 - aka "type 7" */ 606 lcd_type = 1; /* Similar to LDS176 - aka "type 7" */
168 607
169 /* Now init according to lcd type */ 608 lcd_ispowered = true;
170 if (lcd_type == 0) {
171 /* TODO */
172
173 /* Entry Mode: AM=0, I/D1=1, I/D0=1, ORG=0, HWM=1, BGR=1 */
174 s5l_lcd_write_cmd_data(R_ENTRY_MODE, 0x1230);
175 } else {
176 /* TODO */
177 }
178} 609}
179 610
180
181/*** Update functions ***/ 611/*** Update functions ***/
182 612
183static inline void lcd_write_pixel(fb_data pixel) 613static inline void lcd_write_pixel(fb_data pixel)
@@ -209,12 +639,12 @@ void lcd_update(void)
209 s5l_lcd_write_cmd(R_WRITE_DATA_TO_GRAM); 639 s5l_lcd_write_cmd(R_WRITE_DATA_TO_GRAM);
210 } else { 640 } else {
211 s5l_lcd_write_cmd(R_COLUMN_ADDR_SET); 641 s5l_lcd_write_cmd(R_COLUMN_ADDR_SET);
212 s5l_lcd_write_data(0); /* Start column */ 642 s5l_lcd_write_wdata(0); /* Start column */
213 s5l_lcd_write_data(LCD_WIDTH-1); /* End column */ 643 s5l_lcd_write_wdata(LCD_WIDTH-1); /* End column */
214 644
215 s5l_lcd_write_cmd(R_ROW_ADDR_SET); 645 s5l_lcd_write_cmd(R_ROW_ADDR_SET);
216 s5l_lcd_write_data(0); /* Start row */ 646 s5l_lcd_write_wdata(0); /* Start row */
217 s5l_lcd_write_data(LCD_HEIGHT-1); /* End row */ 647 s5l_lcd_write_wdata(LCD_HEIGHT-1); /* End row */
218 648
219 s5l_lcd_write_cmd(R_MEMORY_WRITE); 649 s5l_lcd_write_cmd(R_MEMORY_WRITE);
220 } 650 }
@@ -254,12 +684,12 @@ void lcd_update_rect(int x, int y, int width, int height)
254 s5l_lcd_write_cmd(R_WRITE_DATA_TO_GRAM); 684 s5l_lcd_write_cmd(R_WRITE_DATA_TO_GRAM);
255 } else { 685 } else {
256 s5l_lcd_write_cmd(R_COLUMN_ADDR_SET); 686 s5l_lcd_write_cmd(R_COLUMN_ADDR_SET);
257 s5l_lcd_write_data(x0); /* Start column */ 687 s5l_lcd_write_wdata(x0); /* Start column */
258 s5l_lcd_write_data(x1); /* End column */ 688 s5l_lcd_write_wdata(x1); /* End column */
259 689
260 s5l_lcd_write_cmd(R_ROW_ADDR_SET); 690 s5l_lcd_write_cmd(R_ROW_ADDR_SET);
261 s5l_lcd_write_data(y0); /* Start row */ 691 s5l_lcd_write_wdata(y0); /* Start row */
262 s5l_lcd_write_data(y1); /* End row */ 692 s5l_lcd_write_wdata(y1); /* End row */
263 693
264 s5l_lcd_write_cmd(R_MEMORY_WRITE); 694 s5l_lcd_write_cmd(R_MEMORY_WRITE);
265 } 695 }
@@ -337,12 +767,12 @@ void lcd_blit_yuv(unsigned char * const src[3],
337 s5l_lcd_write_cmd(R_WRITE_DATA_TO_GRAM); 767 s5l_lcd_write_cmd(R_WRITE_DATA_TO_GRAM);
338 } else { 768 } else {
339 s5l_lcd_write_cmd(R_COLUMN_ADDR_SET); 769 s5l_lcd_write_cmd(R_COLUMN_ADDR_SET);
340 s5l_lcd_write_data(x0); /* Start column */ 770 s5l_lcd_write_wdata(x0); /* Start column */
341 s5l_lcd_write_data(x1); /* End column */ 771 s5l_lcd_write_wdata(x1); /* End column */
342 772
343 s5l_lcd_write_cmd(R_ROW_ADDR_SET); 773 s5l_lcd_write_cmd(R_ROW_ADDR_SET);
344 s5l_lcd_write_data(y0); /* Start row */ 774 s5l_lcd_write_wdata(y0); /* Start row */
345 s5l_lcd_write_data(y1); /* End row */ 775 s5l_lcd_write_wdata(y1); /* End row */
346 776
347 s5l_lcd_write_cmd(R_MEMORY_WRITE); 777 s5l_lcd_write_cmd(R_MEMORY_WRITE);
348 } 778 }