Index: firmware/export/config/ipodnano2g.h =================================================================== --- firmware/export/config/ipodnano2g.h (revision 28182) +++ firmware/export/config/ipodnano2g.h (working copy) @@ -41,9 +41,6 @@ /* define this to enable JPEG decoding */ #define HAVE_JPEG -/* define this if the LCD can shut down */ -#define HAVE_LCD_SHUTDOWN - /* define this if you can invert the colours on your LCD */ //#define HAVE_LCD_INVERT @@ -88,12 +85,16 @@ #define LCD_DEPTH 16 /* pseudo 262.144 colors */ #define LCD_PIXELFORMAT RGB565 /* rgb565 */ +/* Define this if the LCD can shut down */ +#define HAVE_LCD_SHUTDOWN + /* Define this if your LCD can be enabled/disabled */ -//#define HAVE_LCD_ENABLE +#define HAVE_LCD_ENABLE /* Define this if your LCD can be put to sleep. HAVE_LCD_ENABLE should be defined as well. */ -//#define HAVE_LCD_SLEEP +#define HAVE_LCD_SLEEP +#define HAVE_LCD_SLEEP_SETTING #define CONFIG_KEYPAD IPOD_4G_PAD Index: firmware/target/arm/s5l8700/ipodnano2g/lcd-nano2g.c =================================================================== --- firmware/target/arm/s5l8700/ipodnano2g/lcd-nano2g.c (revision 28182) +++ firmware/target/arm/s5l8700/ipodnano2g/lcd-nano2g.c (working copy) @@ -62,9 +62,56 @@ int lcd_type; /* also needed in debug-s5l8700.c */ static int xoffset; /* needed for flip */ +static bool lcd_ispowered; /** hardware access functions */ +static void lcd_send_cmd(uint32_t cmd) __attribute__((naked, noinline)); +static void lcd_send_cmd(uint32_t cmd) +{ + (void)cmd; + asm volatile( + "mov r2, #0x38000000 \n\t" + "orr r2, r2, #0x600000 \n\t" + "lsc_wait: \n\t" + "ldrh r1, [r2,#0x1c] \n\t" + "tst r1, #0x10 \n\t" + "bne lsc_wait \n\t" + "strh r0, [r2,#0x4] \n\t" + "mov pc, lr \n\t" + ); +} + +static void lcd_7_send_data(uint32_t data) __attribute__((naked, noinline)); +static void lcd_7_send_data(uint32_t data) +{ + (void)data; + asm volatile( + "mov r2, #0x38000000 \n\t" + "orr r2, r2, #0x600000 \n\t" + "and r0, r0, #0xff \n\t" + "strh r0, [r2,#0x40] \n\t" + "ls7d_wait: \n\t" + "ldrh r1, [r2,#0x1c] \n\t" + "tst r1, #0x10 \n\t" + "bne ls7d_wait \n\t" + "mov pc, lr \n\t" + ); +} + +static void lcd_delay(uint32_t time) __attribute__((naked, noinline)); +static void lcd_delay(uint32_t time) +{ + (void)time; + asm volatile( + "mov r0, r0,lsl#16 \n\t" + "ld_wait: \n\t" + "subs r0, r0, #1 \n\t" + "bne ld_wait \n\t" + "mov pc, lr \n\t" + ); +} + static inline void s5l_lcd_write_cmd_data(int cmd, int data) { while (LCD_STATUS & 0x10); @@ -84,6 +131,14 @@ LCD_WCMD = cmd; } +static inline void s5l_lcd_write_cmd_2(unsigned short cmd) +{ + while (LCD_STATUS & 0x10); + LCD_WCMD = cmd >> 8; + while (LCD_STATUS & 0x10); + LCD_WCMD = cmd & 0xff; +} + static inline void s5l_lcd_write_data(int data) { while (LCD_STATUS & 0x10); @@ -125,11 +180,26 @@ } } +bool lcd_active(void) +{ + return lcd_ispowered; +} + +void lcd_awake(void) +{ + if(!lcd_active()) lcd_init_device(); +} + void lcd_shutdown(void) { pmu_write(0x2b, 0); /* Kill the backlight, instantly. */ pmu_write(0x29, 0); + lcd_sleep(); +} + +void lcd_sleep(void) +{ if (lcd_type == 0) { s5l_lcd_write_cmd_data(R_DISPLAY_CONTROL_1, 0x232); @@ -151,6 +221,7 @@ s5l_lcd_write_data(0); s5l_lcd_write_data(0); } + lcd_ispowered = false; } /* LCD init */ @@ -166,18 +237,357 @@ else lcd_type = 1; /* Similar to LDS176 - aka "type 7" */ + /* reset the lcd chip */ + /* + LCD_RST_TIME = 0x7FFF; + LCD_DRV_RST = 0; + lcd_delay(1); + LCD_DRV_RST = 1; + lcd_delay(5); +*/ /* Now init according to lcd type */ if (lcd_type == 0) { - /* TODO */ + s5l_lcd_write_cmd_2(0xa4); + s5l_lcd_write_data(0x01); + sleep(0); + s5l_lcd_write_cmd_2(0x01); + s5l_lcd_write_data(0x0100); + + s5l_lcd_write_cmd_2(0x02); + s5l_lcd_write_data(0x0300); + + s5l_lcd_write_cmd_2(0x03); + s5l_lcd_write_data(0x1230); + + s5l_lcd_write_cmd_2(0x08); + s5l_lcd_write_data(0x0404); + + s5l_lcd_write_cmd_2(0x0e); + s5l_lcd_write_data(0x10); + + s5l_lcd_write_cmd_2(0x70); + s5l_lcd_write_data(0x1000); + + s5l_lcd_write_cmd_2(0x71); + s5l_lcd_write_data(0x01); + + s5l_lcd_write_cmd_2(0x30); + s5l_lcd_write_data(0x02); + + s5l_lcd_write_cmd_2(0x31); + s5l_lcd_write_data(0x0400); + + s5l_lcd_write_cmd_2(0x32); + s5l_lcd_write_data(0x07); + + s5l_lcd_write_cmd_2(0x33); + s5l_lcd_write_data(0x0500); + + s5l_lcd_write_cmd_2(0x34); + s5l_lcd_write_data(0x07); + + s5l_lcd_write_cmd_2(0x35); + s5l_lcd_write_data(0x0703); + + s5l_lcd_write_cmd_2(0x36); + s5l_lcd_write_data(0x0507); + + s5l_lcd_write_cmd_2(0x37); + s5l_lcd_write_data(0x05); + + s5l_lcd_write_cmd_2(0x38); + s5l_lcd_write_data(0x0407); + + s5l_lcd_write_cmd_2(0x39); + s5l_lcd_write_data(0x0e); + + s5l_lcd_write_cmd_2(0x40); + s5l_lcd_write_data(0x0202); + + s5l_lcd_write_cmd_2(0x41); + s5l_lcd_write_data(0x03); + + s5l_lcd_write_cmd_2(0x42); + s5l_lcd_write_data(0x00); + + s5l_lcd_write_cmd_2(0x43); + s5l_lcd_write_data(0x0200); + + s5l_lcd_write_cmd_2(0x44); + s5l_lcd_write_data(0x0707); + + s5l_lcd_write_cmd_2(0x45); + s5l_lcd_write_data(0x0407); + + s5l_lcd_write_cmd_2(0x46); + s5l_lcd_write_data(0x0505); + + s5l_lcd_write_cmd_2(0x47); + s5l_lcd_write_data(0x02); + + s5l_lcd_write_cmd_2(0x48); + s5l_lcd_write_data(0x04); + + s5l_lcd_write_cmd_2(0x49); + s5l_lcd_write_data(0x04); + + s5l_lcd_write_cmd_2(0x60); + s5l_lcd_write_data(0x0202); + + s5l_lcd_write_cmd_2(0x61); + s5l_lcd_write_data(0x03); + + s5l_lcd_write_cmd_2(0x62); + s5l_lcd_write_data(0x00); + + s5l_lcd_write_cmd_2(0x63); + s5l_lcd_write_data(0x0200); + + s5l_lcd_write_cmd_2(0x64); + s5l_lcd_write_data(0x0707); + + s5l_lcd_write_cmd_2(0x65); + s5l_lcd_write_data(0x0407); + + s5l_lcd_write_cmd_2(0x66); + s5l_lcd_write_data(0x0505); + + s5l_lcd_write_cmd_2(0x68); + s5l_lcd_write_data(0x04); + + s5l_lcd_write_cmd_2(0x69); + s5l_lcd_write_data(0x04); + + s5l_lcd_write_cmd_2(0x07); + s5l_lcd_write_data(0x01); + + s5l_lcd_write_cmd_2(0x18); + s5l_lcd_write_data(0x01); + + s5l_lcd_write_cmd_2(0x10); + s5l_lcd_write_data(0x1690); + + s5l_lcd_write_cmd_2(0x11); + s5l_lcd_write_data(0x0100); + + s5l_lcd_write_cmd_2(0x12); + s5l_lcd_write_data(0x0117); + + s5l_lcd_write_cmd_2(0x13); + s5l_lcd_write_data(0x0f80); + + s5l_lcd_write_cmd_2(0x12); + s5l_lcd_write_data(0x0137); + + s5l_lcd_write_cmd_2(0x20); + s5l_lcd_write_data(0x00); + + s5l_lcd_write_cmd_2(0x21); + s5l_lcd_write_data(0x00); + + s5l_lcd_write_cmd_2(0x50); + s5l_lcd_write_data(0x00); + + s5l_lcd_write_cmd_2(0x51); + s5l_lcd_write_data(0xaf); + + s5l_lcd_write_cmd_2(0x52); + s5l_lcd_write_data(0x00); + + s5l_lcd_write_cmd_2(0x53); + s5l_lcd_write_data(0x83); + + s5l_lcd_write_cmd_2(0x90); + s5l_lcd_write_data(0x03); + + s5l_lcd_write_cmd_2(0x91); + s5l_lcd_write_data(0x00); + + s5l_lcd_write_cmd_2(0x92); + s5l_lcd_write_data(0x0101); + + s5l_lcd_write_cmd_2(0x98); + s5l_lcd_write_data(0x0400); + + s5l_lcd_write_cmd_2(0x99); + s5l_lcd_write_data(0x1302); + + s5l_lcd_write_cmd_2(0x9a); + s5l_lcd_write_data(0x0202); + + s5l_lcd_write_cmd_2(0x9b); + s5l_lcd_write_data(0x0200); + sleep(0); + + s5l_lcd_write_cmd_2(0x07); + s5l_lcd_write_data(0x21); + + s5l_lcd_write_cmd_2(0x12); + s5l_lcd_write_data(0x0137); + sleep(0); + + s5l_lcd_write_cmd_2(0x07); + s5l_lcd_write_data(0x21); + + s5l_lcd_write_cmd_2(0x12); + s5l_lcd_write_data(0x1137); + sleep(0); + + s5l_lcd_write_cmd_2(0x07); + s5l_lcd_write_data(0x0233); + /* Entry Mode: AM=0, I/D1=1, I/D0=1, ORG=0, HWM=1, BGR=1 */ - s5l_lcd_write_cmd_data(R_ENTRY_MODE, 0x1230); + s5l_lcd_write_cmd_data(R_ENTRY_MODE, 0x1230); } else { - /* TODO */ + lcd_send_cmd(0x01); + lcd_7_send_data(0x00); + + lcd_delay(10); + + lcd_send_cmd(0xB1); + lcd_7_send_data(0x16); + lcd_7_send_data(0x03); + + lcd_send_cmd(0xB2); + lcd_7_send_data(0x17); + lcd_7_send_data(0x03); + + lcd_send_cmd(0xB4); + lcd_7_send_data(0x00); + + lcd_send_cmd(0xB6); + lcd_7_send_data(0x01); + + lcd_send_cmd(0xB7); + lcd_7_send_data(0x00); + lcd_7_send_data(0x00); + lcd_7_send_data(0x02); + lcd_7_send_data(0x00); + lcd_7_send_data(0x06); + lcd_7_send_data(0x26); + lcd_7_send_data(0x2D); + lcd_7_send_data(0x27); + lcd_7_send_data(0x55); + lcd_7_send_data(0x27); + + lcd_send_cmd(0xB8); + lcd_7_send_data(0x10); + + lcd_send_cmd(0xB9); + lcd_7_send_data(0x52); + lcd_7_send_data(0x12); + lcd_7_send_data(0x03); + + lcd_send_cmd(0xC0); + lcd_7_send_data(0x0A); + lcd_7_send_data(0x10); + lcd_7_send_data(0x10); + + lcd_send_cmd(0xC2); + lcd_7_send_data(0x14); + lcd_7_send_data(0x23); + + lcd_send_cmd(0xC3); + lcd_7_send_data(0x12); + lcd_7_send_data(0x23); + + lcd_send_cmd(0xC6); + lcd_7_send_data(0x48); + + lcd_send_cmd(0xE0); + lcd_7_send_data(0x20); + lcd_7_send_data(0x71); + lcd_7_send_data(0x17); + lcd_7_send_data(0x09); + lcd_7_send_data(0x70); + lcd_7_send_data(0x0C); + lcd_7_send_data(0x13); + lcd_7_send_data(0x25); + + lcd_send_cmd(0xE1); + lcd_7_send_data(0x37); + lcd_7_send_data(0x00); + lcd_7_send_data(0x63); + lcd_7_send_data(0x11); + lcd_7_send_data(0xD9); + lcd_7_send_data(0x00); + lcd_7_send_data(0x12); + lcd_7_send_data(0x01); + + lcd_send_cmd(0xE2); + lcd_7_send_data(0x42); + lcd_7_send_data(0x42); + lcd_7_send_data(0x60); + lcd_7_send_data(0x08); + lcd_7_send_data(0xB4); + lcd_7_send_data(0x07); + lcd_7_send_data(0x0E); + lcd_7_send_data(0x90); + + lcd_send_cmd(0xE3); + lcd_7_send_data(0x47); + lcd_7_send_data(0x60); + lcd_7_send_data(0x66); + lcd_7_send_data(0x09); + lcd_7_send_data(0x6A); + lcd_7_send_data(0x02); + lcd_7_send_data(0x0E); + lcd_7_send_data(0x09); + + lcd_send_cmd(0xE4); + lcd_7_send_data(0x11); + lcd_7_send_data(0x40); + lcd_7_send_data(0x03); + lcd_7_send_data(0x0A); + lcd_7_send_data(0xC1); + lcd_7_send_data(0x0D); + lcd_7_send_data(0x17); + lcd_7_send_data(0x30); + + lcd_send_cmd(0xE5); + lcd_7_send_data(0x00); + lcd_7_send_data(0x30); + lcd_7_send_data(0x77); + lcd_7_send_data(0x1C); + lcd_7_send_data(0xFB); + lcd_7_send_data(0x00); + lcd_7_send_data(0x13); + lcd_7_send_data(0x07); + + lcd_send_cmd(0xE6); + lcd_7_send_data(0x01); + + lcd_send_cmd(0x35); + lcd_7_send_data(0x00); + + lcd_send_cmd(0x36); + lcd_7_send_data(0x00); + + lcd_send_cmd(0xF2); + lcd_7_send_data(0x40); + + lcd_send_cmd(0xF3); + lcd_7_send_data(0x50); + + lcd_send_cmd(0xFB); + lcd_7_send_data(0x01); + + lcd_send_cmd(0x11); + lcd_7_send_data(0x00); + + lcd_delay(20); + + lcd_send_cmd(0x3A); + lcd_7_send_data(0x65); + + lcd_send_cmd(0x29); + lcd_7_send_data(0x00); } + + lcd_ispowered = true; } - /*** Update functions ***/ static inline void lcd_write_pixel(fb_data pixel) Index: firmware/target/arm/s5l8700/ipodnano2g/backlight-nano2g.c =================================================================== --- firmware/target/arm/s5l8700/ipodnano2g/backlight-nano2g.c (revision 28182) +++ firmware/target/arm/s5l8700/ipodnano2g/backlight-nano2g.c (working copy) @@ -25,6 +25,9 @@ #include "backlight-target.h" #include "pmu-target.h" +#ifdef HAVE_LCD_SLEEP +void lcd_awake(void); +#endif void _backlight_set_brightness(int brightness) { @@ -33,6 +36,9 @@ void _backlight_on(void) { +#ifdef HAVE_LCD_SLEEP + lcd_awake(); +#endif pmu_write(0x29, 1); }