tizen 2.4 release
[kernel/u-boot-tm1.git] / drivers / video / lcd_hx8357_1.c
1 /* drivers/video/sc8800g/sc8800g_lcd_hx8357.c
2  *
3  * Support for HX8357 LCD device
4  *
5  * Copyright (C) 2010 Spreadtrum
6  *
7  * This software is licensed under the terms of the GNU General Public
8  * License version 2, as published by the Free Software Foundation, and
9  * may be copied, distributed, and modified under those terms.
10  *
11  * This program is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14  * GNU General Public License for more details.
15  */
16
17 #include <asm/arch/sc8810_lcd.h>
18 #define printk printf
19
20 //#define  LCD_DEBUG
21 #ifdef LCD_DEBUG
22 #define LCD_PRINT printk
23 #else
24 #define LCD_PRINT(...)
25 #endif
26
27 static int32_t hx8357_init(struct lcd_spec *self)
28 {
29         Send_data send_cmd = self->info.mcu->ops->send_cmd;
30         Send_cmd_data send_cmd_data = self->info.mcu->ops->send_cmd_data;
31         Send_data send_data = self->info.mcu->ops->send_data;
32
33         LCD_PRINT("hx8357_init\n");
34
35         send_cmd_data(0x00ff, 0x00);  //Command page 0
36         LCD_DelayMS(15);  //delay
37         send_cmd_data(0x001a, 0x0004);  //VGH VGL VCL DDVDH
38         send_cmd_data(0x001b, 0x001c);
39
40         /*power setting*/
41         send_cmd_data(0x0023, 0x0091);// set VCOM offset,VMF=0x52
42         send_cmd_data(0x0024, 0x0069);//set VCOMH voltage,VHH=0x64
43         send_cmd_data(0x0025, 0x0063); //set VCOML voltage,VML=0x71
44         send_cmd_data(0x0019, 0x0001);
45         LCD_DelayMS(10);  //delay
46         send_cmd_data(0x001a, 0x0001); //VGH VGL VCL DDVDH
47         send_cmd_data(0x001f, 0x008a);
48         send_cmd_data(0x0001, 0x0000);
49         send_cmd_data(0x001c, 0x0005);
50         send_cmd_data(0x001f, 0x0082);
51         LCD_DelayMS(10); //delay
52         send_cmd_data(0x001f, 0x0092);
53         LCD_DelayMS(10); //delay
54         send_cmd_data(0x001f, 0x00d4);
55
56         /* set GRAM area 320*480 */
57         send_cmd_data(0x0002, 0x0000);
58         send_cmd_data(0x0003, 0x0000);
59         send_cmd_data(0x0004, 0x0001);
60         send_cmd_data(0x0005, 0x003f);
61         send_cmd_data(0x0006, 0x0000);
62         send_cmd_data(0x0007, 0x0000);
63         send_cmd_data(0x0008, 0x0001);
64
65         send_cmd_data(0x0016, 0x0009); //set my mx mv bgr
66         send_cmd_data(0x0017, 0x0005); //16-bit pixel
67         send_cmd_data(0x0018, 0x0022); //Fosc=130%*5.2MHZ 21
68         send_cmd_data(0x001d, 0x0000); //FS0[1:0]=01,set the operating frequency of the step-up circuit 1
69         send_cmd_data(0x001e, 0x0000);
70
71         send_cmd_data(0x0026, 0x0033);
72         send_cmd_data(0x0027, 0x0001);
73         send_cmd_data(0x0029, 0x0000);
74         send_cmd_data(0x002a, 0x0000);
75         send_cmd_data(0x002b, 0x0001); //0A
76         send_cmd_data(0x002c, 0x000a);
77         send_cmd_data(0x002d, 0x0020);
78         send_cmd_data(0x002e, 0x00a3);
79         send_cmd_data(0x002f, 0x0000);
80         send_cmd_data(0x0031, 0x0000);
81         send_cmd_data(0x0032, 0x0000);
82         send_cmd_data(0x0033, 0x0008);
83         send_cmd_data(0x0034, 0x0002);
84         send_cmd_data(0x0036, 0x0002);  //REV
85         
86         /* Gamma  */
87         send_cmd_data(0x0040, 0x0001);
88         send_cmd_data(0x0041, 0x0012);
89         send_cmd_data(0x0042, 0x0019);
90         send_cmd_data(0x0043, 0x0026);
91         send_cmd_data(0x0044, 0x002c);
92         send_cmd_data(0x0045, 0x003c);
93         send_cmd_data(0x0046, 0x000b);
94         send_cmd_data(0x0047, 0x005f);
95         send_cmd_data(0x0048, 0x0000);
96         send_cmd_data(0x0049, 0x0008);
97         send_cmd_data(0x004a, 0x000b);
98         send_cmd_data(0x004b, 0x0010);
99         send_cmd_data(0x004c, 0x0016);
100
101         send_cmd_data(0x0050, 0x0001);
102         send_cmd_data(0x0051, 0x001d);
103         send_cmd_data(0x0052, 0x0021);
104         send_cmd_data(0x0053, 0x0034);
105         send_cmd_data(0x0054, 0x0037);
106         send_cmd_data(0x0055, 0x003f);
107         send_cmd_data(0x0056, 0x0029);
108         send_cmd_data(0x0057, 0x007f);
109         send_cmd_data(0x0058, 0x0001);
110         send_cmd_data(0x0059, 0x0012);
111         send_cmd_data(0x005a, 0x001b);
112         send_cmd_data(0x005b, 0x001e);
113         send_cmd_data(0x005c, 0x001a);
114         send_cmd_data(0x005d, 0x0055);
115
116         send_cmd_data(0x0060, 0x0008);
117         send_cmd_data(0x00f2, 0x0000);
118         send_cmd_data(0x00e4, 0x001f); //EQVCI_M1=0x00
119         send_cmd_data(0x00e5, 0x001f); //EQGND_M1=0x1c
120         send_cmd_data(0x00e6, 0x0020); //EQVCI_M0=0x1c
121         send_cmd_data(0x00e7, 0x0000); //EQGND_M0=0x1c
122         send_cmd_data(0x00e8, 0x00d1);
123         send_cmd_data(0x00e9, 0x00c0);
124         send_cmd_data(0x0028, 0x0038);
125         LCD_DelayMS(80);  //delay
126         send_cmd_data(0x0028, 0x003c); //GON=0,DTE=0,D[1:0]=01
127
128         send_cmd_data(0x0080, 0x0000);
129         send_cmd_data(0x0081, 0x0000);
130         send_cmd_data(0x0082, 0x0000);
131         send_cmd_data(0x0083, 0x0000);
132
133         send_cmd(0x0022);
134
135         if (0) {
136                 int i;
137                 for (i=0; i<320*480/2; i++)
138                         send_data(0x1234);
139                 for (i=0; i< 320*480/2; i++)
140                         send_data(0x4321);
141         }
142
143         return 0;
144 }
145
146 static int32_t hx8357_set_window(struct lcd_spec *self,
147                 uint16_t left, uint16_t top, uint16_t right, uint16_t bottom)
148 {
149         Send_data send_cmd = self->info.mcu->ops->send_cmd;
150         Send_cmd_data send_cmd_data = self->info.mcu->ops->send_cmd_data;
151         Send_data send_data = self->info.mcu->ops->send_data;
152
153         LCD_PRINT("hx8357_set_window: %d, %d, %d, %d\n",left, top, right, bottom);
154     
155         /* set window size  */
156         send_cmd_data(0x0002, (left  >> 8));
157         send_cmd_data(0x0003, (left  & 0xff));
158         send_cmd_data(0x0004, (right >> 8));
159         send_cmd_data(0x0005, (right & 0xff));
160
161         send_cmd_data(0x0006, (top    >> 8));
162         send_cmd_data(0x0007, (top    &  0xff));
163         send_cmd_data(0x0008, (bottom >> 8));
164         send_cmd_data(0x0009, (bottom &  0xff));
165
166         switch (self->direction) {
167         case LCD_DIRECT_NORMAL:
168         default:
169                 send_cmd_data(0x0080, (left >> 8));
170                 send_cmd_data(0x0081, (left &  0xff));
171                 send_cmd_data(0x0082, (top  >> 8));
172                 send_cmd_data(0x0083, (top  &  0xff));
173                 break;
174
175         case LCD_DIRECT_ROT_90:
176                 send_cmd_data(0x0080, (top >> 8));
177                 send_cmd_data(0x0081, (top & 0xff));
178                 send_cmd_data(0x0082, (left >> 8));
179                 send_cmd_data(0x0083, (left & 0xff));
180             break;
181
182         case LCD_DIRECT_ROT_180:
183         case LCD_DIRECT_MIR_HV:
184                 send_cmd_data(0x0080, (right >> 8));
185                 send_cmd_data(0x0081, (right & 0xff));
186                 send_cmd_data(0x0082, (bottom >> 8));
187                 send_cmd_data(0x0083, (bottom & 0xff));
188                 break;
189
190         case LCD_DIRECT_ROT_270:
191                 send_cmd_data(0x0080, (bottom >> 8));
192                 send_cmd_data(0x0081, (bottom & 0xff));
193                 send_cmd_data(0x0082, (left >> 8));
194                 send_cmd_data(0x0083, (left & 0xff));
195             break;
196
197         case LCD_DIRECT_MIR_H:
198                 send_cmd_data(0x0080, (left >> 8));
199                 send_cmd_data(0x0081, (left & 0xff));
200                 send_cmd_data(0x0082, (bottom >> 8));
201                 send_cmd_data(0x0083, (bottom & 0xff));
202                 break;
203
204         case LCD_DIRECT_MIR_V:
205                 send_cmd_data(0x0080, (right >> 8));
206                 send_cmd_data(0x0081, (right & 0xff));
207                 send_cmd_data(0x0082, (top >> 8));
208                 send_cmd_data(0x0083, (top & 0xff));
209             break;
210         }
211         
212         send_cmd(0x0022);
213
214         return 0;
215 }
216
217 static int32_t hx8357_invalidate(struct lcd_spec *self)
218 {
219         LCD_PRINT("hx8357_invalidate\n");
220
221         return self->ops->lcd_set_window(self, 0, 0, 
222                         self->width - 1, self->height - 1);
223         
224 }
225
226 static int32_t hx8357_invalidate_rect(struct lcd_spec *self,
227                                 uint16_t left, uint16_t top,
228                                 uint16_t right, uint16_t bottom)
229 {
230         Send_cmd_data send_cmd_data = self->info.mcu->ops->send_cmd_data;
231
232         LCD_PRINT("hx8357_invalidate_rect \n");
233
234         // TE scaneline
235         send_cmd_data(0x000b, (top >> 8));
236         send_cmd_data(0x000c, (top & 0xff));
237         return self->ops->lcd_set_window(self, left, top, 
238                         right, bottom);
239 }
240
241
242 static int32_t hx8357_set_direction(struct lcd_spec *self, uint16_t direction)
243 {
244         Send_cmd_data send_cmd_data = self->info.mcu->ops->send_cmd_data;
245
246         LCD_PRINT("hx8357_set_direction\n");
247
248         switch (direction) {
249         case LCD_DIRECT_NORMAL:
250                 send_cmd_data(0x0016, 0x0009);
251                 break;
252         case LCD_DIRECT_ROT_90:
253                 send_cmd_data(0x0016, 0x0069);
254                 break;
255         case LCD_DIRECT_ROT_180:
256                 send_cmd_data(0x0016, 0x00c9);
257                 break;
258         case LCD_DIRECT_ROT_270:
259                 send_cmd_data(0x0016, 0x00a9);
260                 break;
261         case LCD_DIRECT_MIR_H:
262                 send_cmd_data(0x0016, 0x00c8);
263                 break;
264         case LCD_DIRECT_MIR_V:
265                 send_cmd_data(0x0016, 0x0008);
266                 break;
267         case LCD_DIRECT_MIR_HV:
268                 send_cmd_data(0x0016, 0x0048);
269                 break;
270         default:
271                 LCD_PRINT("unknown lcd direction!\n");
272                 send_cmd_data(0x0016, 0x0009);
273                 direction = LCD_DIRECT_NORMAL;
274                 break;
275         }
276
277         self->direction = direction;
278         
279         return 0;
280 }
281
282 static int32_t hx8357_enter_sleep(struct lcd_spec *self, uint8_t is_sleep)
283 {
284         Send_cmd_data send_cmd_data = self->info.mcu->ops->send_cmd_data;
285
286         if(is_sleep) {
287                 send_cmd_data(0x00FF, 0x00);//Select Command Page 0
288                 // Display off Setting
289                 send_cmd_data(0x0028, 0x38); // GON=1, DTE=1, D[1:0]=10
290                 LCD_DelayMS(40);  //delay       
291                 send_cmd_data(0x0028, 0x04); // GON=0, DTE=0, D[1:0]=01
292                 // Power off Setting
293                 send_cmd_data(0x001F, 0x90); // Stop VCOMG
294                 // GAS_EN=1, VCOMG=0, PON=1, DK=0, XDK=0, DDVDH_TRI=0, STB=0
295                 LCD_DelayMS(5);  //delay        
296                 send_cmd_data(0x001F, 0x88);// Stop step-up circuit
297                 // GAS_EN=1, VCOMG=1, PON=0, DK=1, XDK=1, DDVDH_TRI=0, STB=0
298                 send_cmd_data(0x001C, 0x00);// AP=000
299                 send_cmd_data(0x001F, 0x89);// Enter Standby mode
300                 //GAS_EN=1, VCOMG=0, PON=0, DK=1, XDK=0, DDVDH_TRI=0, STB=1
301                 send_cmd_data(0x0019, 0x00);//OSC_EN=0, Stop to Oscillate
302         }
303         else {
304                 send_cmd_data(0x00FF, 0x00);//Select Command Page 0
305                 send_cmd_data(0x0019, 0x01);//OSC_EN=1, Start to Oscillate
306                 LCD_DelayMS(5);  //delay
307                 send_cmd_data(0x001F, 0x88);
308                 //GAS_EN=1, VCOMG=0, PON=0, DK=1, XDK=0, DDVDH_TRI=0, STB=0
309                 // Power on Setting
310                 send_cmd_data(0x001C, 0x03);// AP=011
311                 send_cmd_data(0x001F, 0x80);// Exit standby mode and Step-up circuit 1 enable
312                 // GAS_EN=1, VCOMG=0, PON=0, DK=0, XDK=0, DDVDH_TRI=0, STB=0
313                 LCD_DelayMS(5);  //delay
314                 send_cmd_data(0x001F, 0x90);// Step-up circuit 2 enable
315                 // GAS_EN=1, VCOMG=0, PON=1, DK=0, XDK=0, DDVDH_TRI=0, STB=0
316                 LCD_DelayMS(5);  //delay
317                 send_cmd_data(0x001F, 0xD4);
318                 // GAS_EN=1, VCOMG=1, PON=1, DK=0, XDK=1, DDVDH_TRI=0, STB=0
319                 LCD_DelayMS(5);  //delay
320                 // Display on Setting
321                 send_cmd_data(0x0028, 0x08);// GON=0, DTE=0, D[1:0]=01
322                 LCD_DelayMS(40);  //delay
323                 send_cmd_data(0x0028, 0x38);// GON=1, DTE=1, D[1:0]=10
324                 LCD_DelayMS(40);  //delay
325                 send_cmd_data(0x0028, 0x3C);// GON=1, DTE=1, D[1:0]=11
326         }
327         return 0;
328 }
329
330 static struct lcd_operations lcd_hx8357_operations = {
331         .lcd_init = hx8357_init,
332         .lcd_set_window = hx8357_set_window,
333         .lcd_invalidate_rect= hx8357_invalidate_rect,
334         .lcd_invalidate = hx8357_invalidate,
335         .lcd_set_direction = hx8357_set_direction,
336         .lcd_enter_sleep = hx8357_enter_sleep,
337 };
338
339 static struct timing_mcu lcd_hx8357_timing[] = {
340 [LCD_REGISTER_TIMING] = {                    // read/write register timing
341                 .rcss = 15,  // 15ns
342                 .rlpw = 60,
343                 .rhpw = 60,
344                 .wcss = 10,
345                 .wlpw = 35,
346                 .whpw = 35,
347         },
348 [LCD_GRAM_TIMING] = {                    // read/write gram timing
349                 .rcss = 15,  // 15ns
350                 .rlpw = 60,
351                 .rhpw = 60,
352                 .wcss = 10,
353                 .wlpw = 35,
354                 .whpw = 35,
355         },
356 };
357
358 static struct info_mcu lcd_hx8357_info = {
359         .bus_mode = LCD_BUS_8080,
360         .bus_width = 16,
361         .timing = lcd_hx8357_timing,
362         .ops = NULL,
363 };
364
365 struct lcd_spec lcd_panel_hx8357 = {
366         .width = 320,
367         .height = 480,
368         .mode = LCD_MODE_MCU,
369         .direction = LCD_DIRECT_NORMAL,
370         .info = {.mcu = &lcd_hx8357_info},
371         .ops = &lcd_hx8357_operations,
372 };