tizen 2.4 release
[kernel/u-boot-tm1.git] / drivers / video / lcd_ili9341s.c
1 /* drivers/video/sc8810/lcd_ili9341s.c
2  *
3  * Support for ili9341s 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
19 #include <asm/arch/sc8810_lcd.h>
20 #define mdelay(a) udelay(a * 1000)
21 #define printk printf
22
23 #define  LCD_DEBUG
24 #ifdef LCD_DEBUG
25 #define LCD_PRINT printk
26 #else
27 #define LCD_PRINT(...)
28 #endif
29
30 static void __raw_bits_or(unsigned int v, unsigned int a)
31 {
32         __raw_writel((__raw_readl(a) | v), a);
33 }
34
35 static int32_t ili9341s_init(struct lcd_spec *self)
36 {
37         Send_data send_cmd = self->info.mcu->ops->send_cmd;
38         Send_data send_data = self->info.mcu->ops->send_data;
39
40         LCD_PRINT("ili9341s_init\n");
41
42         send_cmd(0xCF); 
43         send_data(0x00); 
44         send_data(0xF9); 
45         send_data(0x30); 
46
47         send_cmd(0xED); 
48         send_data(0x64); 
49         send_data(0x03); 
50         send_data(0x12); 
51         send_data(0x81); 
52
53         send_cmd(0xCB); 
54         send_data(0x39); 
55         send_data(0x2C); 
56         send_data(0x00); 
57         send_data(0x34); 
58         send_data(0x02); 
59
60         send_cmd(0xF7); 
61         send_data(0x20); 
62         
63         send_cmd(0xEA); 
64         send_data(0x00);  
65         send_data(0x00); 
66
67         send_cmd(0xC0); 
68         send_data(0x1D);  
69
70         send_cmd(0xC1); 
71         send_data(0x10);  
72
73         send_cmd(0xC5);
74         send_data(0x3C);//14
75         send_data(0x2A);//44
76
77         send_cmd( 0xC7); 
78         send_data(0x00);
79
80         send_cmd( 0xE8);
81         send_data( 0x85);
82         send_data( 0x00);       
83         send_data( 0x78);
84
85         send_cmd( 0x35);
86         send_data( 0x00);
87
88         send_cmd( 0x36); 
89         send_data( 0xD8);
90
91         send_cmd( 0x3A); 
92         send_data( 0x05);//66
93
94         send_cmd( 0xB1);
95         send_data( 0x00);
96         send_data( 0x16);
97         
98         send_cmd( 0xB5);
99         send_data( 0x04);
100         send_data( 0x04);
101         send_data( 0x0A);
102         send_data( 0x14);
103
104         send_cmd( 0xB6); 
105         send_data( 0x0A);
106         send_data( 0xC2); 
107
108         send_cmd( 0xF6); 
109         send_data( 0x01);
110         send_data( 0x30); 
111         send_data( 0x00); 
112
113         send_cmd( 0xF2); 
114         send_data( 0x03);
115         
116         send_cmd( 0xE0); 
117         send_data( 0x0F);
118         send_data( 0x24);         
119         send_data( 0x20);
120         send_data( 0x0F);         
121         send_data( 0x0F);
122
123         send_data( 0x0B);         
124         send_data( 0x50);
125         send_data( 0xA4);         
126         send_data( 0x3E);
127         send_data( 0x06);
128
129         send_data( 0x10);
130         send_data( 0x01);
131         send_data( 0x1A);
132         send_data( 0x19);
133         send_data( 0x0F);
134
135         send_cmd( 0xE1); 
136         send_data(  0x00);
137         send_data(  0x18);        
138         send_data(  0x19);
139         send_data(  0x03);        
140         send_data(  0x0F);
141
142         send_data(  0x04);        
143         send_data(  0x31);
144         send_data(  0x53);        
145         send_data(  0x46);
146         send_data(  0x09);
147
148         send_data(  0x12);
149         send_data(  0x0F);
150         send_data(  0x26);
151         send_data(  0x2A);
152         send_data(  0x03);
153
154         send_cmd( 0xE2 ); 
155         send_data(  0x08);
156         send_data(  0x09);        
157         send_data(  0x09);
158         send_data(  0x09);        
159         send_data(  0x09);
160
161         send_data(  0x09);        
162         send_data(  0x09);
163         send_data(  0x09);        
164         send_data(  0x09);
165         send_data(  0x09);
166
167         send_data(  0x09);
168         send_data(  0x09);
169         send_data(  0x09);
170         send_data(  0x09);
171         send_data(  0x88);
172
173         send_data(  0x88);
174
175         send_cmd( 0xE3 ); 
176         send_data(  0x00);
177         send_data(  0x00);        
178         send_data(  0x00);
179         send_data(  0x00);        
180         send_data(  0x06);
181
182         send_data(  0x06);        
183         send_data(  0x07);
184         send_data(  0x03);        
185         send_data(  0x05);
186         send_data(  0x04);
187
188         send_data(  0x04);
189         send_data(  0x04);
190         send_data(  0x04);
191         send_data(  0x04);
192         send_data(  0x02);
193
194         send_data(  0x02);
195         send_data(  0x01);
196         send_data(  0x01);
197         send_data(  0x01);
198         send_data(  0x01);
199
200         send_data(  0x00);
201         send_data(  0x00);
202         send_data(  0x00);
203         send_data(  0x00);
204         send_data(  0x00);        
205
206         send_data(  0x00);
207         send_data(  0x00);
208         send_data(  0x00);
209         send_data(  0x00);
210         send_data(  0x00);
211
212         send_data(  0x00);
213         send_data(  0x00);
214         send_data(  0x00);
215         send_data(  0x00);
216         send_data(  0x00);
217
218         send_data(  0x00);
219         send_data(  0x00);
220         send_data(  0x00);
221         send_data(  0x00);
222         send_data(  0x00);
223
224         send_data(  0x00);
225         send_data(  0x00);
226         send_data(  0x00);
227         send_data(  0x00);
228         send_data(  0x00);
229
230         send_data(  0x00);
231         send_data(  0x00);
232         send_data(  0x00);
233         send_data(  0x00);
234         send_data(  0x00);
235
236         send_data(  0x00);
237         send_data(  0x00);
238         send_data(  0x00);
239         send_data(  0x00);
240         send_data(  0x00);
241
242         send_data(  0x00);
243         send_data(  0x80);
244         send_data(  0x80);
245         send_data(  0x80);
246         send_data(  0x80);
247
248         send_data(  0x82);
249         send_data(  0x82);
250         send_data(  0x82);
251         send_data(  0x82);
252
253
254         send_cmd( 0x11 ); // (SLPOUT)
255
256         mdelay(130); // 120ms
257
258         send_cmd( 0x29); // (DISPON)
259
260         mdelay(40); // 40ms
261 #if 0   
262         if (1) { //  for test the lcd
263                 int i;
264                 send_cmd(0x2C); //Write data
265                 for (i = 0; i < 240*320/3; i++)
266                         send_data(0xff);
267                 for (i = 0; i < 240*320/3; i++)
268                         send_data(0xff00);
269                 for (i = 0; i < 240*320/3; i++)
270                         send_data(0xff0000);
271         }
272         send_cmd(0x29); //Display On 
273         mdelay(120); //120ms
274         send_cmd(0x2C); //Write data
275         //mdelay(120); //120ms
276 #endif
277         LCD_PRINT("ili9341s_init: end\n");
278
279         return 0;
280 }
281
282 static int32_t ili9341s_set_window(struct lcd_spec *self,
283                 uint16_t left, uint16_t top, uint16_t right, uint16_t bottom)
284 {
285         Send_data send_cmd = self->info.mcu->ops->send_cmd;
286         Send_data send_data = self->info.mcu->ops->send_data;
287
288         LCD_PRINT("ili9341s_set_window\n");
289     
290         send_cmd(0x2A); // col
291         send_data((left >> 8));
292         send_data((left & 0xFF));
293         send_data((right >> 8));
294         send_data((right & 0xFF));
295
296         send_cmd(0x2B); // row
297         send_data((top >> 8));
298         send_data((top & 0xFF));
299         send_data((bottom >> 8));
300         send_data((bottom & 0xFF));
301         
302         send_cmd(0x2C); //Write data
303
304         return 0;
305 }
306
307
308 static int32_t ili9341s_invalidate(struct lcd_spec *self)
309 {
310         LCD_PRINT("ili9341s_invalidate\n");
311
312         return self->ops->lcd_set_window(self, 0, 0, 
313                         self->width-1, self->height-1);
314         
315 }
316
317 static int32_t ili9341s_invalidate_rect(struct lcd_spec *self,
318                                 uint16_t left, uint16_t top,
319                                 uint16_t right, uint16_t bottom)
320 {
321         Send_data send_cmd = self->info.mcu->ops->send_cmd;
322         Send_data send_data = self->info.mcu->ops->send_data;
323
324         LCD_PRINT("ili9341s_invalidate_rect : (%d, %d, %d, %d)\n",left, top, right, bottom);
325
326         //send_cmd(0x44); // TE scanline
327         //send_data((top >> 8));
328         //send_data((top & 0xFF));
329
330         return self->ops->lcd_set_window(self, left, top, 
331                         right, bottom);
332 }
333
334 static int32_t ili9341s_set_direction(struct lcd_spec *self, uint16_t direction)
335 {
336         Send_data send_cmd = self->info.mcu->ops->send_cmd;
337         Send_data send_data = self->info.mcu->ops->send_data;
338
339         LCD_PRINT("ili9341s_set_direction\n");
340 #if 0   
341         send_cmd(0x36);
342
343         switch (direction) {
344         case LCD_DIRECT_NORMAL:
345                 send_data(0);
346                 break;
347         case LCD_DIRECT_ROT_90:
348                 send_data(0xA0);
349                 break;
350         case LCD_DIRECT_ROT_180:
351                 send_data(0x60);
352                 break;
353         case LCD_DIRECT_ROT_270:
354                 send_data(0xB0);
355                 break;
356         case LCD_DIRECT_MIR_H:
357                 send_data(0x40);
358                 break;
359         case LCD_DIRECT_MIR_V:
360                 send_data(0x10);
361                 break;
362         case LCD_DIRECT_MIR_HV:
363                 send_data(0xE0);
364                 break;
365         default:
366                 LCD_PRINT("unknown lcd direction!\n");
367                 send_data(0x0);
368                 direction = LCD_DIRECT_NORMAL;
369                 break;
370         }
371
372         self->direction = direction;
373 #endif  
374         return 0;
375 }
376
377 static int32_t ili9341s_enter_sleep(struct lcd_spec *self, uint8_t is_sleep)
378 {
379         Send_data send_cmd = self->info.mcu->ops->send_cmd;
380
381         if(is_sleep) {
382                 //Sleep In
383                 send_cmd(0x10);
384                 mdelay(120); 
385         }
386         else {
387                 //Sleep Out
388                 send_cmd(0x11);
389                 mdelay(120); 
390         }
391         return 0;
392 }
393
394 static uint32_t ili9341s_read_id(struct lcd_spec *self)
395 {
396         int lcd_id = 0;
397         Send_data send_cmd = self->info.mcu->ops->send_cmd;
398         Send_data send_data = self->info.mcu->ops->send_data;
399         Read_data read_data = self->info.mcu->ops->read_data;
400
401         send_cmd(0x04);
402         read_data();
403         lcd_id = read_data();
404         LCD_PRINT("11111read_id=%x---------------------\n",lcd_id);
405         lcd_id = read_data();
406         LCD_PRINT("read_id=%x---------------------\n",lcd_id);
407         lcd_id = read_data();
408         LCD_PRINT("read_id=%x---------------------\n",lcd_id);
409         return 0x61;
410
411         send_cmd(0x04);
412         read_data();
413         return read_data(); 
414 }
415
416 static struct lcd_operations lcd_ili9341s_operations = {
417         .lcd_init            = ili9341s_init,
418         .lcd_set_window      = ili9341s_set_window,
419         .lcd_invalidate      = ili9341s_invalidate,
420         .lcd_invalidate_rect = ili9341s_invalidate_rect,
421         .lcd_set_direction   = ili9341s_set_direction,
422         .lcd_enter_sleep     = ili9341s_enter_sleep,
423         .lcd_readid          = ili9341s_read_id,
424 };
425 #if 0
426 static struct timing_mcu lcd_ili9341s_timing = {
427         .rcss = 170,  // 25 ns
428         .rlpw = 50,
429         .rhpw = 100,
430         .wcss = 70,
431         .wlpw = 20,
432         .whpw = 20,
433 };
434 #endif
435
436 static struct timing_mcu lcd_ili9341s_timing[] = {
437 [LCD_REGISTER_TIMING] = {        
438         .rcss = 25,  // 25 ns
439         .rlpw = 45,
440         .rhpw = 90,
441         .wcss = 0,
442         .wlpw = 15,
443         .whpw = 15,
444 },
445 [LCD_GRAM_TIMING] = {        
446         .rcss = 25,  // 25 ns
447         .rlpw = 45,
448         .rhpw = 90,
449         .wcss = 0,
450         .wlpw = 15,
451         .whpw = 15,
452 }
453
454 };
455
456 static struct info_mcu lcd_ili9341s_info = {
457         .bus_mode = LCD_BUS_8080,
458         .bus_width = 16,
459         .timing = &lcd_ili9341s_timing,
460         .ops = NULL,
461 };
462
463 struct lcd_spec lcd_panel_ili9341s = {
464         .width = 240,
465         .height = 320,
466         .mode = LCD_MODE_MCU,
467         .direction = LCD_DIRECT_NORMAL,
468         .info = {.mcu = &lcd_ili9341s_info},
469         .ops = &lcd_ili9341s_operations,
470 };
471