summaryrefslogtreecommitdiffstats
path: root/firmware/target/mips/ingenic_jz47xx/xduoo_x3/lcd-xduoo_x3.c
diff options
context:
space:
mode:
Diffstat (limited to 'firmware/target/mips/ingenic_jz47xx/xduoo_x3/lcd-xduoo_x3.c')
-rw-r--r--firmware/target/mips/ingenic_jz47xx/xduoo_x3/lcd-xduoo_x3.c127
1 files changed, 115 insertions, 12 deletions
diff --git a/firmware/target/mips/ingenic_jz47xx/xduoo_x3/lcd-xduoo_x3.c b/firmware/target/mips/ingenic_jz47xx/xduoo_x3/lcd-xduoo_x3.c
index ea29ce266d..ce8840f9d2 100644
--- a/firmware/target/mips/ingenic_jz47xx/xduoo_x3/lcd-xduoo_x3.c
+++ b/firmware/target/mips/ingenic_jz47xx/xduoo_x3/lcd-xduoo_x3.c
@@ -148,11 +148,79 @@ void lcd_enable_power(bool onoff)
static bool display_on = false; /* used by lcd_enable */
/*** hardware configuration ***/
+int lcd_default_contrast(void)
+{
+ return DEFAULT_CONTRAST_SETTING;
+}
void lcd_set_contrast(int val)
{
- lcd_write_command(LCD_CNTL_CONTRAST);
- lcd_write_command(val);
+ static int last_val = 0xFFFFFF;
+
+ if (val >= 0) /* brightness menu */
+ {
+ lcd_write_command(LCD_CNTL_CONTRAST);
+ lcd_write_command(val);
+ }
+ else if (val != last_val)
+ {
+ /* here we change the voltage level and drive times
+ * longer precharge = dimmer display
+ * higher voltage = shorter precharge required
+ */
+ int precharge;
+ int vcomdsel;
+ switch (val)
+ {
+ case -9:
+ precharge = 0xFF;
+ vcomdsel = 0x10;
+ break;
+ case -8:
+ precharge = 0xF9;
+ vcomdsel = 0x10;
+ break;
+ case -7:
+ precharge = 0xF6;
+ vcomdsel = 0x20;
+ break;
+ default:
+ case -6:
+ precharge = 0xF1;
+ vcomdsel = 0x30;
+ break;
+ case -5:
+ precharge = 0xF1;
+ vcomdsel = 0x40;
+ break;
+ case -4:
+ precharge = 0x91;
+ vcomdsel = 0x50;
+ break;
+ case -3:
+ precharge = 0x61;
+ vcomdsel = 0x60;
+ break;
+ case -2:
+ precharge = 0x31;
+ vcomdsel = 0x65;
+ break;
+ case -1:
+ precharge = 0x11;
+ vcomdsel = 0x70;
+ break;
+ }
+ last_val = val;
+ lcd_enable(false);
+ /* Set pre-charge period */
+ lcd_write_command(LCD_SET_PRECHARGE_PERIOD);
+ lcd_write_command(precharge); /* VCC Generated by Internal DC/DC Circuit */
+
+ /* Set VCOM deselect level */
+ lcd_write_command(LCD_SET_VCOM_DESELECT_LEVEL);
+ lcd_write_command(vcomdsel);
+ lcd_enable(true);
+ }
}
void lcd_set_invert_display(bool yesno)
@@ -252,7 +320,7 @@ void lcd_init_device(void)
/* Set VCOM deselect level */
lcd_write_command(LCD_SET_VCOM_DESELECT_LEVEL);
- lcd_write_command(0x40);
+ lcd_write_command(0x20);
/* Set normal display mode (not every pixel ON) */
lcd_write_command(LCD_SET_ENTIRE_DISPLAY_OFF);
@@ -275,6 +343,22 @@ void lcd_init_device(void)
/*** Update functions ***/
+/* returns LCD_CNTL_HIGHCOL or'd with higher 4 bits of
+ the 8-bit column address for the display data RAM.
+*/
+static inline int get_column_high_byte(const int x)
+{
+ return (LCD_CNTL_HIGHCOL | (((x+LCD_COL_OFFSET) >> 4) & 0xf));
+}
+
+/* returns LCD_CNTL_LOWCOL or'd with lower 4 bits of
+ the 8-bit column address for the display data RAM.
+*/
+static inline int get_column_low_byte(const int x)
+{
+ return (LCD_CNTL_LOWCOL | ((x+LCD_COL_OFFSET) & 0xf));
+}
+
/* Performance function that works with an external buffer
note that by and bheight are in 8-pixel units! */
void lcd_blit_mono(const unsigned char *data, int x, int by, int width,
@@ -283,12 +367,15 @@ void lcd_blit_mono(const unsigned char *data, int x, int by, int width,
if(!display_on)
return;
+ const int column_high = get_column_high_byte(x);
+ const int column_low = get_column_low_byte(x);
+
/* Copy display bitmap to hardware */
while (bheight--)
{
lcd_write_command (LCD_CNTL_PAGE | (by++ & 0xf));
- lcd_write_command (LCD_CNTL_HIGHCOL | (((x+LCD_COL_OFFSET)>>4) & 0xf));
- lcd_write_command (LCD_CNTL_LOWCOL | ((x+LCD_COL_OFFSET) & 0xf));
+ lcd_write_command (column_high);
+ lcd_write_command (column_low);
lcd_write_data(data, width);
data += stride;
@@ -306,6 +393,7 @@ void lcd_grey_data(unsigned char *values, unsigned char *phases, int count)
unsigned long *lpha = (unsigned long *)phases;
const unsigned long mask = 0x80808080;
+ __gpio_set_pin(PIN_LCD_DC);
while(count--)
{
/* calculate disp data from phase we only use the last byte (8bits) */
@@ -320,7 +408,12 @@ void lcd_grey_data(unsigned char *values, unsigned char *phases, int count)
lpha[0] = lval[0] + (lpha[0] & ~mask);
lpha[1] = lval[1] + (lpha[1] & ~mask);
- lcd_write_data((const fb_data*) &ltmp, 1);
+ REG_GPIO_PXDATC(2) = 0x000030FC;
+ REG_GPIO_PXDATS(2) = ((ltmp & 0xC0) << 6) | ((ltmp & 0x3F) << 2);
+ __gpio_clear_pin(PIN_LCD_WR);
+ bitdelay();
+ __gpio_set_pin(PIN_LCD_WR);
+ bitdelay();
lpha+=2;
lval+=2;
@@ -335,13 +428,16 @@ void lcd_blit_grey_phase(unsigned char *values, unsigned char *phases,
if(!display_on)
return;
+ const int column_high = get_column_high_byte(x);
+ const int column_low = get_column_low_byte(x);
+
stride <<= 3; /* 8 pixels per block */
/* Copy display bitmap to hardware */
while (bheight--)
{
lcd_write_command (LCD_CNTL_PAGE | (by++ & 0xf));
- lcd_write_command (LCD_CNTL_HIGHCOL | (((x+LCD_COL_OFFSET)>>4) & 0xf));
- lcd_write_command (LCD_CNTL_LOWCOL | ((x+LCD_COL_OFFSET) & 0xf));
+ lcd_write_command (column_high);
+ lcd_write_command (column_low);
lcd_grey_data(values, phases, width);
@@ -361,12 +457,16 @@ void lcd_update(void)
if(!display_on)
return;
+
+ const int column_high = get_column_high_byte(0);
+ const int column_low = get_column_low_byte(0);
+
/* Copy display bitmap to hardware */
for (y = 0; y < LCD_FBHEIGHT; y++)
{
lcd_write_command (LCD_CNTL_PAGE | (y & 0xf));
- lcd_write_command (LCD_CNTL_HIGHCOL | ((LCD_COL_OFFSET >> 4) & 0xf));
- lcd_write_command (LCD_CNTL_LOWCOL | (LCD_COL_OFFSET & 0xf));
+ lcd_write_command (column_high);
+ lcd_write_command (column_low);
lcd_write_data (FBADDR(0, y), LCD_WIDTH);
}
@@ -381,6 +481,9 @@ void lcd_update_rect(int x, int y, int width, int height)
if(!display_on)
return;
+ const int column_high = get_column_high_byte(x);
+ const int column_low = get_column_low_byte(x);
+
/* The Y coordinates have to work on even 8 pixel rows */
if (x < 0)
{
@@ -413,8 +516,8 @@ void lcd_update_rect(int x, int y, int width, int height)
for (; y <= ymax; y++)
{
lcd_write_command (LCD_CNTL_PAGE | (y & 0xf));
- lcd_write_command (LCD_CNTL_HIGHCOL | (((x+LCD_COL_OFFSET) >> 4) & 0xf));
- lcd_write_command (LCD_CNTL_LOWCOL | ((x+LCD_COL_OFFSET) & 0xf));
+ lcd_write_command (column_high);
+ lcd_write_command (column_low);
lcd_write_data (FBADDR(x,y), width);
}