Index: firmware/target/arm/as3525/sansa-fuze/lcd-fuze.c =================================================================== --- firmware/target/arm/as3525/sansa-fuze/lcd-fuze.c (Revision 19440) +++ firmware/target/arm/as3525/sansa-fuze/lcd-fuze.c (Arbeitskopie) @@ -24,6 +24,13 @@ #include "cpu.h" #include "lcd.h" +#include "kernel.h" +#include "thread.h" +#include +#include +#include "file.h" +#include "debug.h" +#include "system.h" #include "clock-target.h" /* The controller is unknown, but some registers appear to be the same as the @@ -35,19 +42,12 @@ #define R_ENTRY_MODE_HORZ 0x7030 +struct mutex lcd_mutex; static bool display_on = false; /* is the display turned on? */ static bool display_flipped = false; static int xoffset = 20; /* needed for flip */ -/* TODO: Implement this function */ -static void lcd_delay(int x) -{ - /* This is just arbitrary - the OF does something more complex */ - x *= 1024; - while (x--); -} - static void as3525_dbop_init(void) { CGU_DBOP = (1<<3) | CLK_DIV(AS3525_PCLK_FREQ, AS3525_DBOP_FREQ); @@ -69,6 +69,7 @@ static void lcd_write_cmd(int cmd) { + mutex_lock(&lcd_mutex); int x; /* Write register */ @@ -89,10 +90,12 @@ DBOP_TIMPOL_23 = 0xa167e06f; + mutex_unlock(&lcd_mutex); } void lcd_write_data(const fb_data* p_bytes, int count) { + mutex_lock(&lcd_mutex); while (count--) { DBOP_DOUT = *p_bytes++; @@ -100,6 +103,7 @@ /* Wait for fifo to empty */ while ((DBOP_STAT & (1<<10)) == 0); } + mutex_unlock(&lcd_mutex); } static void lcd_write_reg(int reg, int value) @@ -146,23 +150,14 @@ lcd_write_reg(0x07, 0); lcd_write_reg(0x13, 0); - lcd_delay(10); - lcd_write_reg(0x11, 0x3704); lcd_write_reg(0x14, 0x1a1b); lcd_write_reg(0x10, 0x3860); lcd_write_reg(0x13, 0x40); - lcd_delay(10); - lcd_write_reg(0x13, 0x60); - lcd_delay(50); - lcd_write_reg(0x13, 0x70); - - lcd_delay(40); - lcd_write_reg(0x01, 277); lcd_write_reg(0x02, (7<<8)); lcd_write_reg(R_ENTRY_MODE, R_ENTRY_MODE_HORZ); @@ -190,65 +185,42 @@ lcd_write_reg(0x48, 0x0); lcd_write_reg(0x07, 0x11); - - lcd_delay(40); - lcd_write_reg(0x07, 0x17); display_on = true; /* must be done before calling lcd_update() */ lcd_update(); } -/* I'm guessing this function is lcd_enable, but it may not be... */ void lcd_enable(bool on) { - int r0 = on; -#if 0 - r4 = 0x1db12; - [r4] = 1; -#endif - - if (r0 != 0) { + if (display_on == on) + return; /* nothing to do */ + if(on) + { + int delay = 0x200000; lcd_write_reg(0, 1); - - lcd_delay(10); - lcd_write_reg(0x10, 0); lcd_write_reg(0x11, 0x3704); lcd_write_reg(0x14, 0x1a1b); lcd_write_reg(0x10, 0x3860); lcd_write_reg(0x13, 0x40); - - lcd_delay(10); - lcd_write_reg(0x13, 0x60); - - lcd_delay(50); - lcd_write_reg(0x13, 112); - - lcd_delay(40); - lcd_write_reg(0x07, 0x11); - - lcd_delay(40); - lcd_write_reg(0x07, 0x17); - } else { + display_on = true; + /* a bit of delay before returning to + * avoid irritating flash on backlight on */ + while(delay--); + + } + else + { lcd_write_reg(0x07, 0x22); - - lcd_delay(40); - lcd_write_reg(0x07, 0); - - lcd_delay(40); - lcd_write_reg(0x10, 1); + display_on = false; } - -#if 0 - [r4] = 0; -#endif } bool lcd_enabled(void) @@ -283,28 +255,16 @@ void lcd_init_device() { + mutex_init(&lcd_mutex); as3525_dbop_init(); - GPIOA_DIR |= (1<<5); + GPIOA_DIR |= (1<<7|1<<5|1<<4|1<<3); GPIOA_PIN(5) = 0; - GPIOA_PIN(3) = (1<<3); - - GPIOA_DIR |= (1<<4) | (1<<3); - - GPIOA_PIN(3) = (1<<3); - GPIOA_PIN(4) = 0; - - GPIOA_DIR |= (1<<7); GPIOA_PIN(7) = 0; - - lcd_delay(1); - GPIOA_PIN(5) = (1<<5); - lcd_delay(1); - _display_on(); } @@ -324,6 +284,7 @@ lcd_write_reg(0x47, ymax); lcd_write_reg(0x48, ymin); lcd_write_reg(0x21, ymin); + lcd_write_cmd(0x22); } /* Update the display. @@ -354,7 +315,7 @@ if (!display_on) return; - xmax = x + width - 1; + xmax = x + width; if (xmax >= LCD_WIDTH) xmax = LCD_WIDTH - 1; /* Clip right */ if (x < 0) @@ -364,8 +325,8 @@ width = xmax - x + 1; /* Fix width */ - ymax = y + height - 1; - if (ymax > LCD_HEIGHT) + ymax = y + height; + if (ymax >= LCD_HEIGHT) ymax = LCD_HEIGHT - 1; /* Clip bottom */ if (y < 0) y = 0; /* Clip top */ @@ -387,5 +348,5 @@ lcd_write_data(ptr, width); ptr += LCD_WIDTH; } - while (++y < ymax); + while (++y <= ymax); }