tizen 2.4 release
[kernel/u-boot-tm1.git] / drivers / video / lcd_hx8357.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 <common.h>
18 #include <asm/arch/sc8810_lcd.h>
19 #define mdelay(a) udelay(a * 1000)
20 #define printk printf
21
22 //#define  LCD_DEBUG
23 #ifdef LCD_DEBUG
24 #define LCD_PRINT printk
25 #else
26 #define LCD_PRINT(...)
27 #endif
28
29
30 static int32_t hx8357_init(struct lcd_spec *self)
31 {
32         Send_data send_cmd = self->info.mcu->ops->send_cmd;
33         #if 0
34         Send_cmd_data send_cmd_data = self->info.mcu->ops->send_cmd_data;
35         #endif
36         Send_data send_data = self->info.mcu->ops->send_data;
37
38         LCD_PRINT("hx8357_init\n");
39
40         //mdelay(130);
41         //send_cmd(0x11);        // Sleep out
42         //mdelay(150);
43         send_cmd(0x21);        // Display Inversion ON
44         send_cmd(0x3A);
45         send_data(0x06);       // Interface
46         send_cmd(0xB9);
47         send_data(0xFF);
48         send_data(0x83);
49         send_data(0x57);       // Set EXTC
50         mdelay(5);
51         send_cmd(0xCC);
52         send_data(0x07);       // Set panel
53 #ifndef CONFIG_FB_LCD_NOFMARK
54         send_cmd(0x35);  // TE on
55         send_data(0x00);  //TE Mode 0
56 #endif
57
58         //send_cmd_data(0x36, 0x00); //tong test
59         //send_cmd_data(0x36, 0xc0); //tong test
60         send_cmd(0x36);
61         send_data(0x00);
62
63         send_cmd(0xB3);
64         //send_data(0x40);
65         send_data(0x00); //tong test
66
67         send_data(0x00);
68         send_data(0x06);
69         send_data(0x06);       // Set RGB I/F 
70         send_cmd(0xB6);
71         send_data(0x4D);       // VCOMDC
72         send_cmd(0xB1);
73         send_data(0x00);
74         send_data(0x12);
75         send_data(0x19);
76         send_data(0x1A);
77         send_data(0x83);
78         send_data(0x48);       // [2]0012); ,VG); =3DDVD); ,VGL=(-2DDVD); ) [3]VSPROUT=4.27V [4]VSNROUT=(-4.31)V
79         send_cmd(0xB4);
80         send_data(0x02);
81         send_data(0x40);
82         send_data(0x00);
83         send_data(0x2A);
84         send_data(0x2A);
85         send_data(0x0D);
86         send_data(0x40);       // [1]0000); =Column,0001); =1-dot,0002); =2-dot,0003); =4-dot  
87         send_cmd(0xC0);
88         send_data(0x36);
89         send_data(0x30);
90         send_data(0x01);
91         send_data(0x3C);
92         send_data(0xC8);
93         send_data(0x08);          
94         send_cmd(0xB5);
95         send_data(0x05);
96         send_data(0x05);         
97       
98   send_cmd(0xE0);    // Gamma
99   send_data(0x00);   // P0
100   send_data(0x06);   // P1
101   send_data(0x0A);   // P2
102   send_data(0x1F);   // P3
103   send_data(0x29);   // P4
104   send_data(0x3D);   //; P5
105   send_data(0x4B);   //; P6
106   send_data(0x53);   //; P7
107   send_data(0x46);   //; P8
108   send_data(0x40);   //; P9
109   send_data(0x3A);   //; P10    
110   send_data(0x37);   //; P11    
111   send_data(0x2F);   //; P12    
112   send_data(0x2A);   //; P13    
113   send_data(0x28);   //; P14    
114   send_data(0x07);   //; P15
115  
116   send_data(0x00);   //; N0     
117   send_data(0x06);   //; N1     
118   send_data(0x0A);   //; N2     
119   send_data(0x1F);   //; N3                                                     
120   send_data(0x29);   //; N4     
121   send_data(0x3D);   //; N5     
122   send_data(0x4B);   //; N6
123   send_data(0x53);   //; N7
124   send_data(0x46);   //; N8
125   send_data(0x40);   //; N9
126   send_data(0x3A);   //; N10
127   send_data(0x37);   //; N11
128   send_data(0x2F);   //; N12
129   send_data(0x2A);   //; N13                    
130   send_data(0x28);   //; N14
131   send_data(0x07);   //; N15
132  
133   send_data(0x00);   //
134   send_data(0x01); 
135       
136         mdelay(130);
137   send_cmd(0x11);        // Sleep out
138   mdelay(150);
139         send_cmd(0x29);    // display on
140         mdelay(5);
141
142         //send_cmd(0x002C);
143
144
145         return 0;
146 }
147
148 static int32_t hx8357_set_window(struct lcd_spec *self,
149                 uint16_t left, uint16_t top, uint16_t right, uint16_t bottom)
150 {
151         Send_data send_cmd = self->info.mcu->ops->send_cmd;
152         Send_data send_data = self->info.mcu->ops->send_data;
153
154         LCD_PRINT("hx8357_set_window: %d, %d, %d, %d\n",left, top, right, bottom);
155     
156         /* set window size  */
157
158 send_cmd(0x2A);
159 send_data(left  >> 8);
160 send_data(left  & 0xff);
161 send_data(right  >> 8);
162 send_data(right  & 0xff);
163
164
165 send_cmd(0x2B);
166 send_data(top  >> 8);
167 send_data(top  & 0xff);
168 send_data(bottom  >> 8);
169 send_data(bottom  & 0xff);
170
171 send_cmd(0x002C);
172
173         return 0;
174 }
175
176 static int32_t hx8357_invalidate(struct lcd_spec *self)
177 {
178         LCD_PRINT("hx8357_invalidate\n");
179
180         return self->ops->lcd_set_window(self, 0, 0, 
181                         self->width - 1, self->height - 1);
182         
183 }
184
185 static int32_t hx8357_invalidate_rect(struct lcd_spec *self,
186                                 uint16_t left, uint16_t top,
187                                 uint16_t right, uint16_t bottom)
188 {
189
190         LCD_PRINT("hx8357_invalidate_rect \n");
191
192         // TE scaneline
193         //send_cmd_data(0x000b, (top >> 8));
194         //send_cmd_data(0x000c, (top & 0xff));
195         return self->ops->lcd_set_window(self, left, top, 
196                         right, bottom);
197 }
198
199
200 static int32_t hx8357_set_direction(struct lcd_spec *self, uint16_t direction)
201 {
202
203         LCD_PRINT("hx8357_set_direction\n");
204         self->direction = direction;
205         
206         return 0;
207 }
208
209 static int32_t hx8357_enter_sleep(struct lcd_spec *self, uint8_t is_sleep)
210 {
211         Send_data send_cmd = self->info.mcu->ops->send_cmd;
212
213         if(is_sleep) 
214         {
215                 send_cmd(0x10); // SLEEP
216         }
217         else
218         {
219                 send_cmd(0x11); // SLPOUT
220         }
221         return 0;
222 }
223 static uint32_t hx8357_read_id(struct lcd_spec *self)
224 {
225       Send_data send_cmd = self->info.mcu->ops->send_cmd;
226         Read_data read_data = self->info.mcu->ops->read_data;
227       Send_data send_data = self->info.mcu->ops->send_data;
228       uint32_t uID = 0;
229       uint32_t uICID[5] = {0};
230       uint32_t i;
231 #if 0
232       send_cmd(0xB0);
233       send_data(0x00);
234       send_cmd(0xBF);
235       for(i = 0; i < 5; i++)
236       {
237           uICID[i] = read_data();
238           printk("[tong][uboot]hx8357_read_id: uICID[%d] = 0x%x\n", i, uICID[i]);        
239       }
240
241       if((uICID[1] == 0x01) && (uICID[2] == 0x22) && (uICID[3] == 0x15) && (uICID[4] == 0x81))
242       {
243           printk("[tong][uboot]LCD driver IC: r61581\n");
244           return -1;
245       }
246       else
247       {
248           printk("[tong][uboot]LCD driver IC: hx8357c\n");
249       }
250 #else
251       send_cmd(0xB9);
252       send_data(0xFF);
253       send_data(0x83);
254       send_data(0x57);
255
256       send_cmd(0xD0);
257       for(i = 0; i < 2; i++)
258       {
259           uICID[i] = read_data();
260           printk("[tong][uboot]hx8357_read_id: uICID[%d] = 0x%x\n", i, uICID[i]);        
261       }
262
263       if((uICID[1] == 0x90))
264       {
265           printk("[tong][uboot]LCD driver IC: hx8357c\n");
266       }
267       else
268       {
269           printk("[tong][uboot]LCD driver IC: r61581\n");
270           return -1;
271       }
272
273
274 #endif
275       send_cmd(0xDA);
276       uID = read_data();
277       printk("[tong][uboot]hx8357_read_id: 0x%x from addr:0xDA\n", uID);
278
279         return (0x8357|uID);
280 }
281
282 static struct lcd_operations lcd_hx8357_operations = {
283         .lcd_init = hx8357_init,
284         .lcd_set_window = hx8357_set_window,
285         .lcd_invalidate_rect= hx8357_invalidate_rect,
286         .lcd_invalidate = hx8357_invalidate,
287         .lcd_set_direction = hx8357_set_direction,
288         .lcd_enter_sleep = hx8357_enter_sleep,
289         .lcd_readid          = hx8357_read_id,
290 };
291
292 static struct timing_mcu lcd_hx8357_timing[] = {
293
294 [LCD_REGISTER_TIMING] = {                    // read/write register timing
295         .rcss = 55,
296         .rlpw = 45,
297         .rhpw = 130,
298         .wcss = 30,
299         .wlpw = 30,
300         .whpw = 30,
301         },
302 [LCD_GRAM_TIMING] = {                    // read/write gram timing
303                 .rcss = 355,
304                 .rlpw = 345,
305                 .rhpw = 110,
306                 .wcss = 30,
307                 .wlpw = 30,
308                 .whpw = 30,
309         },
310
311 };
312
313 static struct info_mcu lcd_hx8357_info = {
314         .bus_mode = LCD_BUS_8080,
315         .bus_width = 18,
316         .timing = lcd_hx8357_timing,
317         .ops = NULL,
318 };
319
320 struct lcd_spec lcd_panel_hx8357 = {
321         .width = 320,
322         .height = 480,
323         .mode = LCD_MODE_MCU,
324         .direction = LCD_DIRECT_NORMAL,
325         .info = {.mcu = &lcd_hx8357_info},
326         .ops = &lcd_hx8357_operations,
327 };
328