tizen 2.4 release
[profile/mobile/platform/kernel/u-boot-tm1.git] / drivers / video / sprdfb / lcd / lcd_ili9806e_2_mipi.c
1 /* drivers/video/sprdfb/lcd_ili9806e_2_mipi.c\r
2  *\r
3  * Support for ili9806e_2 mipi LCD device\r
4  *\r
5  * Copyright (C) 2010 Spreadtrum\r
6  *\r
7  */\r
8 \r
9 #include <asm/arch/sprd_lcd.h>\r
10 #include "../sprdfb.h"\r
11 \r
12 #define printk printf\r
13 \r
14 //#define  LCD_DEBUG\r
15 #ifdef LCD_DEBUG\r
16 #define LCD_PRINT printk\r
17 #else\r
18 #define LCD_PRINT(...)\r
19 #endif\r
20 \r
21 #define MAX_DATA   48\r
22 \r
23 typedef struct LCM_Init_Code_tag {\r
24         unsigned int tag;\r
25         unsigned char data[MAX_DATA];\r
26 }LCM_Init_Code;\r
27 \r
28 typedef struct LCM_force_cmd_code_tag{\r
29         unsigned int datatype;\r
30         LCM_Init_Code real_cmd_code;\r
31 }LCM_Force_Cmd_Code;\r
32 \r
33 #define LCM_TAG_SHIFT 24\r
34 #define LCM_TAG_MASK  ((1 << 24) -1)\r
35 #define LCM_SEND(len) ((1 << LCM_TAG_SHIFT)| len)\r
36 #define LCM_SLEEP(ms) ((2 << LCM_TAG_SHIFT)| ms)\r
37 //#define ARRAY_SIZE(array) ( sizeof(array) / sizeof(array[0]))\r
38 \r
39 #define LCM_TAG_SEND  (1<< 0)\r
40 #define LCM_TAG_SLEEP (1 << 1)\r
41 \r
42 static LCM_Init_Code init_data[] = {\r
43         {LCM_SEND(8), {6, 0,0xFF,0xFF,0x98,0x06,0x04,0x01}},// Change to Page 1\r
44         {LCM_SLEEP(5)},\r
45 \r
46         {LCM_SEND(2), {0x08,0x10}},// output SDA\r
47 \r
48         {LCM_SEND(2), {0x21,0x01}},// DE = 1 Active\r
49 \r
50         {LCM_SEND(2), {0x30,0x01}},// 480 X 854\r
51         {LCM_SEND(2), {0x31,0x02}}, // 2-dot Inversion\r
52 \r
53         {LCM_SEND(2), {0x50,0x78}},// VGMP\r
54         {LCM_SEND(2), {0x51,0x78}},// VGMN\r
55         {LCM_SEND(2), {0x52,0x00}}, //Flicker\r
56         {LCM_SEND(2), {0x53,0x49}},//Flicker\r
57 \r
58         {LCM_SEND(2), {0x60,0x0a}},// SDTI\r
59         {LCM_SEND(2), {0x61,0x00}},// CRTI\r
60         {LCM_SEND(2), {0x62,0x08}},// EQTI\r
61         {LCM_SEND(2), {0x63,0x00}}, // PCTI\r
62 \r
63         {LCM_SEND(2), {0x40,0x15}},// VGH/VGL\r
64         {LCM_SEND(2), {0x41,0x44}}, // VGH/VGL\r
65         {LCM_SEND(2), {0x42,0x01}},// VGH/VGL\r
66         {LCM_SEND(2), {0x43,0x09}},// VGH/VGL\r
67         {LCM_SEND(2), {0x44,0x07}},// VGH/VGL\r
68 \r
69 //++++++++++++++++++ Gamma Setting ++++++++++++++++++//\r
70 \r
71         {LCM_SEND(8), {6, 0,0xFF,0xFF,0x98,0x06,0x04,0x01}},// Change to Page 1\r
72 \r
73         {LCM_SEND(2), {0xA0,0x00}},// Gamma 0\r
74         {LCM_SEND(2), {0xA1,0x04}},// Gamma 4\r
75         {LCM_SEND(2), {0xA2,0x13}},// Gamma 8\r
76         {LCM_SEND(2), {0xA3,0x10}},// Gamma 16\r
77         {LCM_SEND(2), {0xA4,0x0a}},// Gamma 24\r
78         {LCM_SEND(2), {0xA5,0x15}},// Gamma 52\r
79         {LCM_SEND(2), {0xA6,0x0d}},// Gamma 80\r
80         {LCM_SEND(2), {0xA7,0x09}},// Gamma 108\r
81         {LCM_SEND(2), {0xA8,0x04}},// Gamma 147\r
82         {LCM_SEND(2), {0xA9,0x09}},// Gamma 175\r
83         {LCM_SEND(2), {0xAA,0x05}},// Gamma 203\r
84         {LCM_SEND(2), {0xAB,0x04}},// Gamma 231\r
85         {LCM_SEND(2), {0xAC,0x10}},// Gamma 239\r
86         {LCM_SEND(2), {0xAD,0x36}},// Gamma 247\r
87         {LCM_SEND(2), {0xAE,0x33}},// Gamma 251\r
88         {LCM_SEND(2), {0xAF,0x1f}},// Gamma 255\r
89 \r
90 ///==============Nagitive\r
91         {LCM_SEND(2), {0xC0,0x00}}, // Gamma 0\r
92         {LCM_SEND(2), {0xC1,0x07}}, // Gamma 4\r
93         {LCM_SEND(2), {0xC2,0x0f}}, // Gamma 8\r
94         {LCM_SEND(2), {0xC3,0x0e}}, // Gamma 16\r
95         {LCM_SEND(2), {0xC4,0x07}}, // Gamma 24\r
96         {LCM_SEND(2), {0xC5,0x15}}, // Gamma 52\r
97         {LCM_SEND(2), {0xC6,0x07}}, // Gamma 80\r
98         {LCM_SEND(2), {0xC7,0x07}}, // Gamma 108\r
99         {LCM_SEND(2), {0xC8,0x03}}, // Gamma 147\r
100         {LCM_SEND(2), {0xC9,0x09}}, // Gamma 175\r
101         {LCM_SEND(2), {0xCA,0x08}}, // Gamma 203\r
102         {LCM_SEND(2), {0xCB,0x04}}, // Gamma 231\r
103         {LCM_SEND(2), {0xCC,0x09}}, // Gamma 239\r
104         {LCM_SEND(2), {0xCD,0x26}}, // Gamma 247\r
105         {LCM_SEND(2), {0xCE,0x21}}, // Gamma 251\r
106         {LCM_SEND(2), {0xCF,0x1f}}, // Gamma 255\r
107 \r
108         {LCM_SEND(8), {6, 0,0xFF,0xFF,0x98,0x06,0x04,0x06}}, // Change to Page 6\r
109 \r
110         {LCM_SEND(2), {0x00,0x21}},\r
111         {LCM_SEND(2), {0x01,0x0a}},\r
112         {LCM_SEND(2), {0x02,0x00}},\r
113         {LCM_SEND(2), {0x03,0x00}},\r
114         {LCM_SEND(2), {0x04,0x01}},\r
115         {LCM_SEND(2), {0x05,0x01}},\r
116         {LCM_SEND(2), {0x06,0x80}},\r
117         {LCM_SEND(2), {0x07,0x06}},\r
118         {LCM_SEND(2), {0x08,0x01}},\r
119         {LCM_SEND(2), {0x09,0x80}},\r
120         {LCM_SEND(2), {0x0A,0x00}},\r
121         {LCM_SEND(2), {0x0B,0x00}},\r
122         {LCM_SEND(2), {0x0C,0x0a}},\r
123         {LCM_SEND(2), {0x0D,0x0a}},\r
124         {LCM_SEND(2), {0x0E,0x00}},\r
125         {LCM_SEND(2), {0x0F,0x00}},\r
126 \r
127         {LCM_SEND(2), {0x10,0xf0}},\r
128         {LCM_SEND(2), {0x11,0xf4}},\r
129         {LCM_SEND(2), {0x12,0x04}},\r
130         {LCM_SEND(2), {0x13,0x00}},\r
131         {LCM_SEND(2), {0x14,0x00}},\r
132         {LCM_SEND(2), {0x15,0xc0}},\r
133         {LCM_SEND(2), {0x16,0x08}},\r
134         {LCM_SEND(2), {0x17,0x00}},\r
135         {LCM_SEND(2), {0x18,0x00}},\r
136         {LCM_SEND(2), {0x19,0x00}},\r
137         {LCM_SEND(2), {0x1A,0x00}},\r
138         {LCM_SEND(2), {0x1B,0x00}},\r
139         {LCM_SEND(2), {0x1C,0x00}},\r
140         {LCM_SEND(2), {0x1D,0x00}},\r
141 \r
142         {LCM_SEND(2), {0x20,0x01}},\r
143         {LCM_SEND(2), {0x21,0x23}},\r
144         {LCM_SEND(2), {0x22,0x45}},\r
145         {LCM_SEND(2), {0x23,0x67}},\r
146         {LCM_SEND(2), {0x24,0x01}},\r
147         {LCM_SEND(2), {0x25,0x23}},\r
148         {LCM_SEND(2), {0x26,0x45}},\r
149         {LCM_SEND(2), {0x27,0x67}},\r
150 \r
151         {LCM_SEND(2), {0x30,0x11}},\r
152         {LCM_SEND(2), {0x31,0x11}},\r
153         {LCM_SEND(2), {0x32,0x00}},\r
154         {LCM_SEND(2), {0x33,0xee}},\r
155         {LCM_SEND(2), {0x34,0xff}},\r
156         {LCM_SEND(2), {0x35,0xbb}},\r
157         {LCM_SEND(2), {0x36,0xca}},\r
158         {LCM_SEND(2), {0x37,0xdd}},\r
159         {LCM_SEND(2), {0x38,0xac}},\r
160         {LCM_SEND(2), {0x39,0x76}},\r
161         {LCM_SEND(2), {0x3A,0x67}},\r
162         {LCM_SEND(2), {0x3B,0x22}},\r
163         {LCM_SEND(2), {0x3C,0x22}},\r
164         {LCM_SEND(2), {0x3D,0x22}},\r
165         {LCM_SEND(2), {0x3E,0x22}},\r
166         {LCM_SEND(2), {0x3F,0x22}},\r
167 \r
168         {LCM_SEND(2), {0x40,0x22}},\r
169 \r
170         {LCM_SEND(2), {0x52,0x10}},\r
171 \r
172         {LCM_SEND(2), {0x53,0x10}},\r
173 \r
174         {LCM_SEND(2), {0x58,0x97}},\r
175 \r
176         {LCM_SEND(8), {6, 0,0xFF,0xFF,0x98,0x06,0x04,0x07}}, // Change to Page 7\r
177         {LCM_SEND(2), {0x17,0x22}},\r
178 \r
179         {LCM_SEND(2), {0x02,0x77}},\r
180 \r
181         {LCM_SEND(2), {0xe1,0x79}},\r
182 //****************************************************************************//\r
183         {LCM_SEND(8), {6, 0,0xFF,0xFF,0x98,0x06,0x04,0x00}}, // Change to Page 0\r
184 \r
185         {LCM_SEND(1), {0x35}},\r
186 \r
187         {LCM_SEND(1), {0x11}},\r
188         {LCM_SLEEP(120)},\r
189 \r
190         {LCM_SEND(1), {0x29}},\r
191         {LCM_SLEEP(10)},\r
192  };\r
193 \r
194 static LCM_Force_Cmd_Code rd_prep_code[]={\r
195         {0x39, {LCM_SEND(8), {0x6, 0, 0xFF, 0xFF, 0x98, 0x06,0x04,0x01}}},\r
196         {0x37, {LCM_SEND(2), {0x3, 0}}},\r
197 };\r
198 \r
199 static LCM_Init_Code disp_on =  {LCM_SEND(1), {0x29}};\r
200 \r
201 static LCM_Init_Code sleep_in =  {LCM_SEND(1), {0x10}};\r
202 \r
203 static LCM_Init_Code sleep_out =  {LCM_SEND(1), {0x11}};\r
204 \r
205 static int32_t ili9806e_2_mipi_init(struct panel_spec *self)\r
206 {\r
207         int32_t i;\r
208         LCM_Init_Code *init = init_data;\r
209         unsigned int tag;\r
210 \r
211         mipi_set_cmd_mode_t mipi_set_cmd_mode = self->info.mipi->ops->mipi_set_cmd_mode;\r
212         mipi_gen_write_t mipi_gen_write = self->info.mipi->ops->mipi_gen_write;\r
213 \r
214          mipi_set_lp_mode_t mipi_set_lp_mode = self->info.mipi->ops->mipi_set_lp_mode;\r
215          mipi_set_hs_mode_t mipi_set_hs_mode = self->info.mipi->ops->mipi_set_hs_mode;\r
216         mipi_eotp_set_t mipi_eotp_set = self->info.mipi->ops->mipi_eotp_set;\r
217         LCD_PRINT("lcd_ili9806e_2_init\n");\r
218 \r
219         //mipi_set_cmd_mode();\r
220 \r
221         mdelay(5);\r
222         mipi_set_lp_mode();\r
223         //mipi_eotp_set(1,0);\r
224         for(i = 0; i < ARRAY_SIZE(init_data); i++){\r
225                 tag = (init->tag >>24);\r
226                 if(tag & LCM_TAG_SEND){\r
227                         mipi_gen_write(init->data, (init->tag & LCM_TAG_MASK));\r
228                         udelay(20);\r
229                 }else if(tag & LCM_TAG_SLEEP){\r
230                         mdelay((init->tag & LCM_TAG_MASK));\r
231                 }\r
232                 init++;\r
233         }\r
234 \r
235         mdelay(5);\r
236         mipi_set_hs_mode();\r
237         return 0;\r
238 }\r
239 \r
240 static uint32_t ili9806e_2_readid(struct panel_spec *self)\r
241 {\r
242         /*Jessica TODO: need read id*/\r
243         int32_t i = 0;\r
244         uint32 j =0;\r
245         LCM_Force_Cmd_Code * rd_prepare = rd_prep_code;\r
246         uint8_t read_data[3] = {0};\r
247         int32_t read_rtn = 0;\r
248         unsigned int tag = 0;\r
249         mipi_set_cmd_mode_t mipi_set_cmd_mode = self->info.mipi->ops->mipi_set_cmd_mode;\r
250         mipi_force_write_t mipi_force_write = self->info.mipi->ops->mipi_force_write;\r
251         mipi_force_read_t mipi_force_read = self->info.mipi->ops->mipi_force_read;\r
252         mipi_set_lp_mode_t mipi_set_lp_mode = self->info.mipi->ops->mipi_set_lp_mode;\r
253         mipi_set_hs_mode_t mipi_set_hs_mode = self->info.mipi->ops->mipi_set_hs_mode;\r
254         mipi_eotp_set_t mipi_eotp_set = self->info.mipi->ops->mipi_eotp_set;\r
255 \r
256         //return 0x6; //cg liyun 20130329\r
257 \r
258         printk("lcd_ili9806e_2_mipi read id!\n");\r
259         mipi_set_lp_mode();\r
260 \r
261         //mipi_set_cmd_mode();\r
262         for(j = 0; j < 4; j++){\r
263                 rd_prepare = rd_prep_code;\r
264                 for(i = 0; i < ARRAY_SIZE(rd_prep_code); i++){\r
265                         tag = (rd_prepare->real_cmd_code.tag >> 24);\r
266                         if(tag & LCM_TAG_SEND){\r
267                                 mipi_force_write(rd_prepare->datatype, rd_prepare->real_cmd_code.data, (rd_prepare->real_cmd_code.tag & LCM_TAG_MASK));\r
268                         }else if(tag & LCM_TAG_SLEEP){\r
269                                 mdelay((rd_prepare->real_cmd_code.tag & LCM_TAG_MASK));\r
270                         }\r
271                         rd_prepare++;\r
272                 }\r
273                 mdelay(50);\r
274                 read_rtn = mipi_force_read(0x02, 1,(uint8_t *)read_data);\r
275                 printk("lcd_ili9806e_2_mipi read id 0x02 value is 0x%x!\n", read_data[0]);\r
276 \r
277                 if((0x04 == read_data[0])){\r
278                         printk("lcd_ili9806e_2_mipi read id success!\n");\r
279                         return 0x980602;\r
280                 }\r
281         }\r
282 \r
283         mdelay(5);\r
284         mipi_set_hs_mode();\r
285         return 0;\r
286 }\r
287 \r
288 static struct panel_operations lcd_ili9806e_2_mipi_operations = {\r
289         .panel_init = ili9806e_2_mipi_init,\r
290         .panel_readid = ili9806e_2_readid,\r
291 };\r
292 \r
293 static struct timing_rgb lcd_ili9806e_2_mipi_timing = {\r
294         .hfp = 60,  /* unit: pixel */// 100\r
295         .hbp = 80,//80\r
296         .hsync = 60,//6\r
297         .vfp = 20, /*unit: line*/\r
298         .vbp = 14,\r
299         .vsync =6, //6,\r
300 };\r
301 \r
302 static struct info_mipi lcd_ili9806e_2_mipi_info = {\r
303         .work_mode  = SPRDFB_MIPI_MODE_VIDEO,\r
304         .video_bus_width = 24, /*18,16*/\r
305         .lan_number = 2,\r
306         .phy_feq = 500*1000,\r
307         .h_sync_pol = SPRDFB_POLARITY_POS,\r
308         .v_sync_pol = SPRDFB_POLARITY_POS,\r
309         .de_pol = SPRDFB_POLARITY_POS,\r
310         .te_pol = SPRDFB_POLARITY_POS,\r
311         .color_mode_pol = SPRDFB_POLARITY_NEG,\r
312         .shut_down_pol = SPRDFB_POLARITY_NEG,\r
313         .timing = &lcd_ili9806e_2_mipi_timing,\r
314         .ops = NULL,\r
315 };\r
316 \r
317 struct panel_spec lcd_ili9806e_2_mipi_spec = {\r
318         //.cap = PANEL_CAP_NOT_TEAR_SYNC,\r
319         .width = 480,\r
320         .height = 854,\r
321         .fps = 60,\r
322         .type = LCD_MODE_DSI,\r
323         .direction = LCD_DIRECT_NORMAL,\r
324         .info = {\r
325                 .mipi = &lcd_ili9806e_2_mipi_info\r
326         },\r
327         .ops = &lcd_ili9806e_2_mipi_operations,\r
328 };\r
329 \r
330 \r