summaryrefslogtreecommitdiff
path: root/firmware/drivers/lcd-h300.c
diff options
context:
space:
mode:
authorLinus Nielsen Feltzing <linus@haxx.se>2005-12-20 23:15:27 +0000
committerLinus Nielsen Feltzing <linus@haxx.se>2005-12-20 23:15:27 +0000
commit67f00224fb8bbf92ffe952d163f35ed437b698d5 (patch)
tree1ecf9d36fdbc8830b98a77e5157d96be43196bb8 /firmware/drivers/lcd-h300.c
parentca1a1ab141f745660ebceae9d70b827314ea29b8 (diff)
downloadrockbox-67f00224fb8bbf92ffe952d163f35ed437b698d5.tar.gz
rockbox-67f00224fb8bbf92ffe952d163f35ed437b698d5.zip
patch #1385256 by Hristo Kovachev - Turn off H300 LCD while backlight is off
git-svn-id: svn://svn.rockbox.org/rockbox/trunk@8268 a1c6a512-1295-4272-9138-f99709370657
Diffstat (limited to 'firmware/drivers/lcd-h300.c')
-rw-r--r--firmware/drivers/lcd-h300.c344
1 files changed, 260 insertions, 84 deletions
diff --git a/firmware/drivers/lcd-h300.c b/firmware/drivers/lcd-h300.c
index 91a86defd4..bb2f9ec777 100644
--- a/firmware/drivers/lcd-h300.c
+++ b/firmware/drivers/lcd-h300.c
@@ -30,19 +30,68 @@
30#include "font.h" 30#include "font.h"
31#include "bidi.h" 31#include "bidi.h"
32 32
33void lcd_write_reg(int reg, int val) 33static bool display_on=false; /* is the display turned on? */
34
35/* register defines */
36#define R_START_OSC 0x00
37#define R_DRV_OUTPUT_CONTROL 0x01
38#define R_DRV_WAVEFORM_CONTROL 0x02
39#define R_ENTRY_MODE 0x03
40#define R_COMPARE_REG1 0x04
41#define R_COMPARE_REG2 0x05
42
43#define R_DISP_CONTROL1 0x07
44#define R_DISP_CONTROL2 0x08
45#define R_DISP_CONTROL3 0x09
46
47#define R_FRAME_CYCLE_CONTROL 0x0b
48#define R_EXT_DISP_IF_CONTROL 0x0c
49
50#define R_POWER_CONTROL1 0x10
51#define R_POWER_CONTROL2 0x11
52#define R_POWER_CONTROL3 0x12
53#define R_POWER_CONTROL4 0x13
54
55#define R_RAM_ADDR_SET 0x21
56#define R_WRITE_DATA_2_GRAM 0x22
57
58#define R_GAMMA_FINE_ADJ_POS1 0x30
59#define R_GAMMA_FINE_ADJ_POS2 0x31
60#define R_GAMMA_FINE_ADJ_POS3 0x32
61#define R_GAMMA_GRAD_ADJ_POS 0x33
62
63#define R_GAMMA_FINE_ADJ_NEG1 0x34
64#define R_GAMMA_FINE_ADJ_NEG2 0x35
65#define R_GAMMA_FINE_ADJ_NEG3 0x36
66#define R_GAMMA_GRAD_ADJ_NEG 0x37
67
68#define R_GAMMA_AMP_ADJ_RES_POS 0x38
69#define R_GAMMA_AMP_AVG_ADJ_RES_NEG 0x39
70
71#define R_GATE_SCAN_POS 0x40
72#define R_VERT_SCROLL_CONTROL 0x41
73#define R_1ST_SCR_DRV_POS 0x42
74#define R_2ND_SCR_DRV_POS 0x43
75#define R_HORIZ_RAM_ADDR_POS 0x44
76#define R_VERT_RAM_ADDR_POS 0x45
77
78
79/* called very frequently - inline! */
80inline void lcd_write_reg(int reg, int val)
34{ 81{
35 *(volatile unsigned short *)0xf0000000 = reg; 82 *(volatile unsigned short *)0xf0000000 = reg;
36 *(volatile unsigned short *)0xf0000002 = val; 83 *(volatile unsigned short *)0xf0000002 = val;
37} 84}
38 85
39void lcd_begin_write_gram(void) 86/* called very frequently - inline! */
87inline void lcd_begin_write_gram(void)
40{ 88{
41 *(volatile unsigned short *)0xf0000000 = 0x22; 89 *(volatile unsigned short *)0xf0000000 = R_WRITE_DATA_2_GRAM;
42} 90}
43 91
44void lcd_write_data(const unsigned short* p_bytes, int count) ICODE_ATTR; 92/* called very frequently - inline! */
45void lcd_write_data(const unsigned short* p_bytes, int count) 93inline void lcd_write_data(const unsigned short* p_bytes, int count) ICODE_ATTR;
94inline void lcd_write_data(const unsigned short* p_bytes, int count)
46{ 95{
47 while(count--) 96 while(count--)
48 *(volatile unsigned short *)0xf0000002 = *p_bytes++; 97 *(volatile unsigned short *)0xf0000002 = *p_bytes++;
@@ -94,69 +143,184 @@ void lcd_init_device(void)
94 or_l(0x00004000, &GPIO1_OUT); 143 or_l(0x00004000, &GPIO1_OUT);
95 sleep(1); 144 sleep(1);
96 145
97 lcd_write_reg(0x00, 0x0001); 146 lcd_write_reg(R_START_OSC, 0x0001); /* Start Oscilation */
98 sleep(1); 147 sleep(1);
99 lcd_write_reg(0x07, 0x0040); 148 lcd_write_reg(R_DISP_CONTROL1, 0x0040); /* zero all bits */
100 lcd_write_reg(0x12, 0x0000); 149 lcd_write_reg(R_POWER_CONTROL3, 0x0000);
101 lcd_write_reg(0x13, 0x0000); 150 lcd_write_reg(R_POWER_CONTROL4, 0x0000);
102 sleep(1); 151 sleep(1);
103 lcd_write_reg(0x11, 0x0003); 152 lcd_write_reg(R_POWER_CONTROL2, 0x0003); /* VciOUT = 0.83*VciLVL */
104 lcd_write_reg(0x12, 0x0008); 153 lcd_write_reg(R_POWER_CONTROL3, 0x0008); /* Vreg1OUT = REGP*1.90 */
105 lcd_write_reg(0x13, 0x3617); 154
106 lcd_write_reg(0x12, 0x0008); 155 /* Vcom-level amplitude = 1.23*Vreg1OUT
107 lcd_write_reg(0x10, 0x0004); 156 * VcomH-level amplitude = 0.84*Vreg1OUT */
108 lcd_write_reg(0x10, 0x0004); 157 lcd_write_reg(R_POWER_CONTROL4, 0x3617);
109 lcd_write_reg(0x11, 0x0002); 158 lcd_write_reg(R_POWER_CONTROL3, 0x0008); /* Vreg1OUT = REGP*1.90 */
110 lcd_write_reg(0x12, 0x0018); 159 lcd_write_reg(R_POWER_CONTROL1, 0x0004); /* Step-up circuit 1 ON */
111 lcd_write_reg(0x10, 0x0044); 160 lcd_write_reg(R_POWER_CONTROL1, 0x0004);
161
162 lcd_write_reg(R_POWER_CONTROL2, 0x0002); /* VciOUT = 0.87*VciLVL */
163 lcd_write_reg(R_POWER_CONTROL3, 0x0018); /* turn on VLOUT3 */
164 lcd_write_reg(R_POWER_CONTROL1, 0x0044); /* LCD power supply Op.Amp
165 const curr = 1 */
112 sleep(1); 166 sleep(1);
113 lcd_write_reg(0x10, 0x0144); 167
114 lcd_write_reg(0x10, 0x0540); 168 /* Step-up rate:
115 lcd_write_reg(0x13, 0x3218); 169 * VLOUT1 (DDVDH) = Vci1*2
116 lcd_write_reg(0x01, 0x001b); 170 * VLOUT4 (VCL) = Vci1*(-1)
117 lcd_write_reg(0x02, 0x0700); 171 * VLOUT2 (VGH) = DDVDH*3 = Vci1*6
118 lcd_write_reg(0x03, 0x7038); 172 * VLOUT3 (VGL) = - DDVDH*2 = Vci1*(-4) */
119 lcd_write_reg(0x04, 0x7030); 173 lcd_write_reg(R_POWER_CONTROL1, 0x0144);
120 lcd_write_reg(0x05, 0x0000); 174
121 lcd_write_reg(0x40, 0x0000); 175 /* Step-Up circuit 1 Off;
122 lcd_write_reg(0x41, 0x0000); 176 * VLOUT2 (VGH) = Vci1 + DDVDH*2 = Vci1*5
123 lcd_write_reg(0x42, 0xdb00); 177 * VLOUT3 (VGL) = -(Vci1+DDVDH) = Vci1*(-3) */
124 lcd_write_reg(0x43, 0x0000); 178 lcd_write_reg(R_POWER_CONTROL1, 0x0540);
125 lcd_write_reg(0x44, 0xaf00); 179
126 lcd_write_reg(0x45, 0xdb00); 180 /* Vcom-level ampl = Vreg1OUT*1.11
127 181 * VcomH-level ampl = Vreg1OUT*0.86 */
128 lcd_write_reg(0x0b, 0x0002); 182 lcd_write_reg(R_POWER_CONTROL4, 0x3218);
129 lcd_write_reg(0x0c, 0x0003); 183 /* ??Number lines invalid? */
184 lcd_write_reg(R_DRV_OUTPUT_CONTROL, 0x001b);
185
186 /* B/C = 1 ; n-line inversion form; polarity inverses at completion of
187 * driving n lines
188 * Exclusive OR = 1; polarity inversion occurs by applying an EOR to
189 * odd/even frame select signal and an n-line inversion signal.
190 * FLD = 01b (1 field interlaced scan, external display iface) */
191 lcd_write_reg(R_DRV_WAVEFORM_CONTROL, 0x0700);
192
193 /* Address counter updated in vertical direction; left to right;
194 * vertical increment horizontal increment.
195 * data format for 8bit transfer or spi = 65k (5,6,5)
196 * Reverse order of RGB to BGR for 18bit data written to GRAM
197 * Replace data on writing to GRAM */
198 lcd_write_reg(R_ENTRY_MODE, 0x7038);
199
200 /* ???? compare val = (1)1100 0011 0000b; the MSB bit is out of spec.*/
201 lcd_write_reg(R_COMPARE_REG1, 0x7030);
202 lcd_write_reg(R_COMPARE_REG2, 0x0000);
203
204 lcd_write_reg(R_GATE_SCAN_POS, 0x0000);
205 lcd_write_reg(R_VERT_SCROLL_CONTROL, 0x0000);
206
207 /* Gate Line = 0+1 = 1
208 * gate "end" line = 0xdb + 1 = 0xdc */
209 lcd_write_reg(R_1ST_SCR_DRV_POS, 0xdb00);
210 lcd_write_reg(R_2ND_SCR_DRV_POS, 0x0000);
211 lcd_write_reg(R_HORIZ_RAM_ADDR_POS, 0xaf00);/* horiz ram addr 0 - 175 */
212 lcd_write_reg(R_VERT_RAM_ADDR_POS, 0xdb00);/* vert ram addr 0 - 219 */
213
214 /* 19 clocks,no equalization */
215 lcd_write_reg(R_FRAME_CYCLE_CONTROL, 0x0002);
216
217 /* Transfer mode for RGB interface disabled
218 * internal clock operation;
219 * System interface/VSYNC interface */
220 lcd_write_reg(R_EXT_DISP_IF_CONTROL, 0x0003);
130 sleep(1); 221 sleep(1);
131 lcd_write_reg(0x10, 0x4540); 222 lcd_write_reg(R_POWER_CONTROL1, 0x4540); /* Turn on the op-amp (1) */
132 lcd_write_reg(0x07, 0x0041); 223
224 /* Enable internal display operations, not showed on the ext. display yet
225 * Source: GND; Internal: ON; Gate-Driver control signals: ON*/
226 lcd_write_reg(R_DISP_CONTROL1, 0x0041);
133 sleep(1); 227 sleep(1);
134 lcd_write_reg(0x08, 0x0808); 228
135 lcd_write_reg(0x09, 0x003f); 229 /* Front porch lines: 8; Back porch lines: 8; */
230 lcd_write_reg(R_DISP_CONTROL2, 0x0808);
231
232 /* Scan mode by the gate driver in the non-display area: disabled;
233 * Cycle of scan by the gate driver - set to 31frames(518ms),disabled by
234 * above setting */
235 lcd_write_reg(R_DISP_CONTROL3, 0x003f);
136 sleep(1); 236 sleep(1);
137 lcd_write_reg(0x07, 0x0636); 237
238 /* Vertical scrolling disabled;
239 * Gate Output: VGH/VGL;
240 * Reversed grayscale image on;
241 * Source output: Non-lit display; internal disp.operation: ON, gate-driver
242 * control signals: ON
243 * Note: bit 6 (zero based) isn't set to 1 (according to the datasheet
244 * it should be) */
245 lcd_write_reg(R_DISP_CONTROL1, 0x0636);
138 sleep(1); 246 sleep(1);
139 lcd_write_reg(0x07, 0x0626); 247 lcd_write_reg(R_DISP_CONTROL1, 0x0626);/* Gate output:VGL; 6th bit not set*/
140 sleep(1); 248 sleep(1);
141 lcd_write_reg(0x30, 0x0003); 249 lcd_write_reg(R_GAMMA_FINE_ADJ_POS1, 0x0003);
142 lcd_write_reg(0x31, 0x0707); 250 lcd_write_reg(R_GAMMA_FINE_ADJ_POS2, 0x0707);
143 lcd_write_reg(0x32, 0x0007); 251 lcd_write_reg(R_GAMMA_FINE_ADJ_POS3, 0x0007);
144 lcd_write_reg(0x33, 0x0705); 252 lcd_write_reg(R_GAMMA_GRAD_ADJ_POS, 0x0705);
145 lcd_write_reg(0x34, 0x0007); 253 lcd_write_reg(R_GAMMA_FINE_ADJ_NEG1, 0x0007);
146 lcd_write_reg(0x35, 0x0000); 254 lcd_write_reg(R_GAMMA_FINE_ADJ_NEG2, 0x0000);
147 lcd_write_reg(0x36, 0x0407); 255 lcd_write_reg(R_GAMMA_FINE_ADJ_NEG3, 0x0407);
148 lcd_write_reg(0x37, 0x0507); 256 lcd_write_reg(R_GAMMA_GRAD_ADJ_NEG, 0x0507);
149 lcd_write_reg(0x38, 0x1d09); 257 lcd_write_reg(R_GAMMA_AMP_ADJ_RES_POS, 0x1d09);
150 lcd_write_reg(0x39, 0x0303); 258 lcd_write_reg(R_GAMMA_AMP_AVG_ADJ_RES_NEG, 0x0303);
151 259
152 lcd_write_reg(0x13, 0x2610); 260 /* VcomH = Vreg1OUT*0.70
261 * Vcom amplitude = Vreg1OUT*0.78 */
262 lcd_write_reg(R_POWER_CONTROL4, 0x2610);
153 263
154 /* LCD ON */ 264 /* LCD ON
155 lcd_write_reg(0x07, 0x0061); 265 * Vertical scrolling: Originaly designated position/external display
266 * Reverse grayscale off;
267 * Internal display operation ON, Gate driver control signals: ON; Source
268 * output GND */
269 lcd_write_reg(R_DISP_CONTROL1, 0x0061);
156 sleep(1); 270 sleep(1);
157 lcd_write_reg(0x07, 0x0067); 271
272 /* init the GRAM, the framebuffer is already cleared in the
273 * device independent lcd_init() */
274 lcd_write_reg(R_RAM_ADDR_SET, 0);
275 lcd_begin_write_gram();
276 lcd_write_data((unsigned short *)lcd_framebuffer, LCD_WIDTH*LCD_HEIGHT);
277
278 /* Reverse grayscale on;
279 * Source output: display */
280 lcd_write_reg(R_DISP_CONTROL1, 0x0067);
158 sleep(1); 281 sleep(1);
159 lcd_write_reg(0x07, 0x0637); 282
283 /* Vertical Scrolling disabled
284 * Gate output: VGH/VGL
285 * 6th bit not set*/
286 lcd_write_reg(R_DISP_CONTROL1, 0x0637);
287}
288
289void lcd_enable(bool on)
290{
291 if(display_on!=on)
292 {
293 if(on)
294 {
295 lcd_init_device();
296 }
297 else
298 {
299 lcd_write_reg(R_FRAME_CYCLE_CONTROL,0x0002); /* No EQ, 19 clocks */
300
301 /* Gate Output VGH/VGL; Non-lit display internal disp. ON,
302 * gate-driver control ON; */
303 lcd_write_reg(R_DISP_CONTROL1,0x0072);
304 sleep(1);
305 lcd_write_reg(R_DISP_CONTROL1,0x0062); /* Gate Output: VGL */
306 sleep(1);
307
308 /* Gate Output VGH; Source Output: GND;
309 * internal display operation:halt
310 * Gate-Driver control signals: OFF */
311 lcd_write_reg(R_DISP_CONTROL1,0x0040);
312
313 /* Now, turn off the power */
314
315 /* Halt op. amp & step-up circuit */
316 lcd_write_reg(R_POWER_CONTROL1,0x0000);
317 lcd_write_reg(R_POWER_CONTROL3,0x0000); /* Turn OFF VLOUT3 */
318
319 /* halt negative volt ampl. */
320 lcd_write_reg(R_POWER_CONTROL4,0x0000);
321 }
322 display_on=on;
323 }
160} 324}
161 325
162/*** update functions ***/ 326/*** update functions ***/
@@ -173,6 +337,7 @@ void lcd_blit(const fb_data* data, int x, int by, int width,
173 (void)width; 337 (void)width;
174 (void)bheight; 338 (void)bheight;
175 (void)stride; 339 (void)stride;
340 /*if(display_on)*/
176} 341}
177 342
178 343
@@ -181,38 +346,49 @@ void lcd_blit(const fb_data* data, int x, int by, int width,
181void lcd_update(void) ICODE_ATTR; 346void lcd_update(void) ICODE_ATTR;
182void lcd_update(void) 347void lcd_update(void)
183{ 348{
184 /* Copy display bitmap to hardware */ 349 if(display_on){
185 lcd_write_reg(0x21, 0); 350 /* Copy display bitmap to hardware */
186 lcd_begin_write_gram(); 351 lcd_write_reg(R_RAM_ADDR_SET, 0);
187 lcd_write_data((unsigned short *)lcd_framebuffer, LCD_WIDTH*LCD_HEIGHT); 352 lcd_begin_write_gram();
353 lcd_write_data((unsigned short *)lcd_framebuffer, LCD_WIDTH*LCD_HEIGHT);
354 }
188} 355}
189 356
190/* Update a fraction of the display. */ 357/* Update a fraction of the display. */
191void lcd_update_rect(int, int, int, int) ICODE_ATTR; 358void lcd_update_rect(int, int, int, int) ICODE_ATTR;
192void lcd_update_rect(int x, int y, int width, int height) 359void lcd_update_rect(int x, int y, int width, int height)
193{ 360{
194 int ymax = y + height; 361 if(display_on) {
195 362 int ymax = y + height;
196 if(x + width > LCD_WIDTH) 363
197 width = LCD_WIDTH - x; 364 if(x + width > LCD_WIDTH)
198 if (width <= 0) 365 width = LCD_WIDTH - x;
199 return; /* nothing left to do, 0 is harmful to lcd_write_data() */ 366 if (width <= 0)
200 if(ymax >= LCD_HEIGHT) 367 return; /* nothing left to do, 0 is harmful to lcd_write_data() */
201 ymax = LCD_HEIGHT-1; 368 if(ymax >= LCD_HEIGHT)
202 369 ymax = LCD_HEIGHT-1;
203 /* set update window */ 370
204 lcd_write_reg(0x44, (ymax<<8) | y); /* horiz ram addr */ 371 /* set update window */
205 lcd_write_reg(0x45, ((x+width-1)<<8) | x); /* vert ram addr */ 372
206 lcd_write_reg(0x21, (x<<8) | y); 373 /* horiz ram addr */
207 lcd_begin_write_gram(); 374 lcd_write_reg(R_HORIZ_RAM_ADDR_POS, (ymax<<8) | y);
208 375
209 /* Copy specified rectangle bitmap to hardware */ 376 /* vert ram addr */
210 for (; y <= ymax; y++) 377 lcd_write_reg(R_VERT_RAM_ADDR_POS,((x+width-1)<<8) | x);
211 { 378 lcd_write_reg(R_RAM_ADDR_SET, (x<<8) | y);
212 lcd_write_data ((unsigned short *)&lcd_framebuffer[y][x], width); 379 lcd_begin_write_gram();
213 } 380
214 381 /* Copy specified rectangle bitmap to hardware */
215 /* reset update window */ 382 for (; y <= ymax; y++)
216 lcd_write_reg(0x44, 0xaf00); /* horiz ram addr: 0 - 175 */ 383 {
217 lcd_write_reg(0x45, 0xdb00); /* vert ram addr: 0 - 219 */ 384 lcd_write_data ((unsigned short *)&lcd_framebuffer[y][x], width);
385 }
386
387 /* reset update window */
388 /* horiz ram addr: 0 - 175 */
389 lcd_write_reg(R_HORIZ_RAM_ADDR_POS, 0xaf00);
390
391 /* vert ram addr: 0 - 219 */
392 lcd_write_reg(R_VERT_RAM_ADDR_POS, 0xdb00);
393 }
218} 394}