tizen 2.4 release
[profile/mobile/platform/kernel/linux-3.10-sc7730.git] / drivers / video / sprdfb / lcd / lcd_ili9806e_mipi.c
1 /* drivers/video/sc8825/lcd_ili9806e_mipi.c\r
2  *\r
3  * Support for ili9806e mipi LCD device\r
4  *\r
5  * Copyright (C) 2010 Spreadtrum\r
6  *\r
7  * This software is licensed under the terms of the GNU General Public\r
8  * License version 2, as published by the Free Software Foundation, and\r
9  * may be copied, distributed, and modified under those terms.\r
10  *\r
11  * This program is distributed in the hope that it will be useful,\r
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of\r
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r
14  * GNU General Public License for more details.\r
15  */\r
16 \r
17 #include <linux/kernel.h>\r
18 #include <linux/bug.h>\r
19 #include <linux/delay.h>\r
20 #include "../sprdfb_panel.h"\r
21 \r
22 //#define  LCD_DEBUG\r
23 #ifdef LCD_DEBUG\r
24 #define LCD_PRINT printk\r
25 #else\r
26 #define LCD_PRINT(...)\r
27 #endif\r
28 \r
29 #define MAX_DATA   48\r
30 \r
31 typedef struct LCM_Init_Code_tag {\r
32         unsigned int tag;\r
33         unsigned char data[MAX_DATA];\r
34 }LCM_Init_Code;\r
35 \r
36 typedef struct LCM_force_cmd_code_tag{\r
37         unsigned int datatype;\r
38         LCM_Init_Code real_cmd_code;\r
39 }LCM_Force_Cmd_Code;\r
40 \r
41 #define LCM_TAG_SHIFT 24\r
42 #define LCM_TAG_MASK  ((1 << 24) -1)\r
43 #define LCM_SEND(len) ((1 << LCM_TAG_SHIFT)| len)\r
44 #define LCM_SLEEP(ms) ((2 << LCM_TAG_SHIFT)| ms)\r
45 //#define ARRAY_SIZE(array) ( sizeof(array) / sizeof(array[0]))\r
46 \r
47 #define LCM_TAG_SEND  (1<< 0)\r
48 #define LCM_TAG_SLEEP (1 << 1)\r
49 \r
50 #if 0 /*For SS*/\r
51 static LCM_Init_Code init_data[] = {\r
52         {LCM_SEND(8), {6, 0,0xFF,0xFF,0x98,0x06,0x04,0x01}},\r
53         {LCM_SLEEP(5)},\r
54 \r
55         {LCM_SEND(2), {0x08,0x10}},\r
56 \r
57         {LCM_SEND(2), {0x21,0x01}},\r
58 \r
59         {LCM_SEND(2), {0x30,0x02}},\r
60         {LCM_SEND(2), {0x31,0x00}}, //0x02\r
61 \r
62         {LCM_SEND(2), {0x60,0x07}},\r
63         {LCM_SEND(2), {0x61,0x06}},\r
64         {LCM_SEND(2), {0x62,0x06}},\r
65         {LCM_SEND(2), {0x63,0x04}},\r
66 \r
67         {LCM_SEND(2), {0x40,0x14}},\r
68         {LCM_SEND(2), {0x41,0x44}},//22\r
69         {LCM_SEND(2), {0x42,0x01}},\r
70         {LCM_SEND(2), {0x43,0x89}},\r
71         {LCM_SEND(2), {0x44,0x89}},\r
72         {LCM_SEND(2), {0x45,0x1b}},\r
73         {LCM_SEND(2), {0x46,0x44}},\r
74         {LCM_SEND(2), {0x47,0x44}},\r
75 \r
76         {LCM_SEND(2), {0x50,0x85}},\r
77         {LCM_SEND(2), {0x51,0x85}},\r
78         {LCM_SEND(2), {0x52,0x00}},\r
79         {LCM_SEND(2), {0x53,0x64}},//90\r
80 \r
81         //{LCM_SEND(8), {6, 0,0xFF,0xFF,0x98,0x06,0x04,0x01}},\r
82 \r
83         {LCM_SEND(2), {0xA0,0x00}},\r
84         {LCM_SEND(2), {0xA1,0x00}},//01\r
85         {LCM_SEND(2), {0xA2,0x03}},//08\r
86         {LCM_SEND(2), {0xA3,0x0e}},//0e\r
87         {LCM_SEND(2), {0xA4,0x08}},//08\r
88         {LCM_SEND(2), {0xA5,0x1f}},//19\r
89         {LCM_SEND(2), {0xA6,0x0f}},//0b\r
90         {LCM_SEND(2), {0xA7,0x0b}},//0a\r
91         {LCM_SEND(2), {0xA8,0x03}},//02\r
92         {LCM_SEND(2), {0xA9,0x06}},//08\r
93         {LCM_SEND(2), {0xAA,0x05}},//04\r
94         {LCM_SEND(2), {0xAB,0x02}},//03\r
95         {LCM_SEND(2), {0xAC,0x0e}},//0a\r
96         {LCM_SEND(2), {0xAD,0x25}},//2c\r
97         {LCM_SEND(2), {0xAE,0x1d}},//28\r
98         {LCM_SEND(2), {0xAF,0x00}},\r
99 \r
100         {LCM_SEND(2), {0xC0,0x00}},//00\r
101         {LCM_SEND(2), {0xC1,0x04}},//02\r
102         {LCM_SEND(2), {0xC2,0x0f}},//09\r
103         {LCM_SEND(2), {0xC3,0x10}},//0e\r
104         {LCM_SEND(2), {0xC4,0x0b}},//09\r
105         {LCM_SEND(2), {0xC5,0x1e}},//19\r
106         {LCM_SEND(2), {0xC6,0x09}},//0a\r
107         {LCM_SEND(2), {0xC7,0x0a}},//0a\r
108         {LCM_SEND(2), {0xC8,0x00}},//02\r
109         {LCM_SEND(2), {0xC9,0x0a}},//07\r
110         {LCM_SEND(2), {0xCA,0x01}},//05\r
111         {LCM_SEND(2), {0xCB,0x06}},//04\r
112         {LCM_SEND(2), {0xCC,0x09}},//0a\r
113         {LCM_SEND(2), {0xCD,0x2a}},//2d\r
114         {LCM_SEND(2), {0xCE,0x28}},//28\r
115         {LCM_SEND(2), {0xCF,0x00}},//00\r
116 \r
117         {LCM_SEND(8), {6, 0,0xFF,0xFF,0x98,0x06,0x04,0x06}},\r
118         {LCM_SEND(2), {0x00,0xa0}},\r
119         {LCM_SEND(2), {0x01,0x05}},\r
120         {LCM_SEND(2), {0x02,0x00}},\r
121         {LCM_SEND(2), {0x03,0x00}},\r
122         {LCM_SEND(2), {0x04,0x01}},\r
123         {LCM_SEND(2), {0x05,0x01}},\r
124         {LCM_SEND(2), {0x06,0x88}},\r
125         {LCM_SEND(2), {0x07,0x04}},\r
126         {LCM_SEND(2), {0x08,0x01}},\r
127         {LCM_SEND(2), {0x09,0x90}},\r
128         {LCM_SEND(2), {0x0A,0x04}},\r
129         {LCM_SEND(2), {0x0B,0x01}},\r
130         {LCM_SEND(2), {0x0C,0x01}},\r
131         {LCM_SEND(2), {0x0D,0x01}},\r
132         {LCM_SEND(2), {0x0E,0x00}},\r
133         {LCM_SEND(2), {0x0F,0x00}},\r
134 \r
135         {LCM_SEND(2), {0x10,0x55}},\r
136         {LCM_SEND(2), {0x11,0x50}},\r
137         {LCM_SEND(2), {0x12,0x01}},\r
138         {LCM_SEND(2), {0x13,0x85}},\r
139         {LCM_SEND(2), {0x14,0x85}},\r
140         {LCM_SEND(2), {0x15,0xc0}},\r
141         {LCM_SEND(2), {0x16,0x0B}},\r
142         {LCM_SEND(2), {0x17,0x00}},\r
143         {LCM_SEND(2), {0x18,0x00}},\r
144         {LCM_SEND(2), {0x19,0x00}},\r
145         {LCM_SEND(2), {0x1A,0x00}},\r
146         {LCM_SEND(2), {0x1B,0x00}},\r
147         {LCM_SEND(2), {0x1C,0x00}},\r
148         {LCM_SEND(2), {0x1D,0x00}},\r
149 \r
150         {LCM_SEND(2), {0x20,0x01}},\r
151         {LCM_SEND(2), {0x21,0x23}},\r
152         {LCM_SEND(2), {0x22,0x45}},\r
153         {LCM_SEND(2), {0x23,0x67}},\r
154         {LCM_SEND(2), {0x24,0x01}},\r
155         {LCM_SEND(2), {0x25,0x23}},\r
156         {LCM_SEND(2), {0x26,0x45}},\r
157         {LCM_SEND(2), {0x27,0x67}},\r
158 \r
159         {LCM_SEND(2), {0x30,0x02}},\r
160         {LCM_SEND(2), {0x31,0x22}},\r
161         {LCM_SEND(2), {0x32,0x11}},\r
162         {LCM_SEND(2), {0x33,0xaa}},\r
163         {LCM_SEND(2), {0x34,0xbb}},\r
164         {LCM_SEND(2), {0x35,0x66}},\r
165         {LCM_SEND(2), {0x36,0x00}},\r
166         {LCM_SEND(2), {0x37,0x22}},\r
167         {LCM_SEND(2), {0x38,0x22}},\r
168         {LCM_SEND(2), {0x39,0x22}},\r
169         {LCM_SEND(2), {0x3A,0x22}},\r
170         {LCM_SEND(2), {0x3B,0x22}},\r
171         {LCM_SEND(2), {0x3C,0x22}},\r
172         {LCM_SEND(2), {0x3D,0x22}},\r
173         {LCM_SEND(2), {0x3E,0x22}},\r
174         {LCM_SEND(2), {0x3F,0x22}},\r
175 \r
176         {LCM_SEND(2), {0x40,0x22}},\r
177         {LCM_SEND(2), {0x53,0x1a}},\r
178 \r
179         {LCM_SEND(8), {6, 0,0xFF,0xFF,0x98,0x06,0x04,0x07}},\r
180         {LCM_SEND(2), {0x18,0x1d}},\r
181         {LCM_SEND(2), {0x17,0x12}},\r
182 \r
183         {LCM_SEND(2), {0x02,0x77}},\r
184 \r
185         {LCM_SEND(2), {0xe1,0x79}},\r
186 \r
187         {LCM_SEND(2), {0x06,0x13}},\r
188 \r
189         {LCM_SEND(8), {6, 0,0xFF,0xFF,0x98,0x06,0x04,0x00}},\r
190 \r
191 //      {LCM_SEND(2), {0x35,0x00}},\r
192 \r
193         {LCM_SEND(1), {0x11}},\r
194         {LCM_SLEEP(120)},\r
195 \r
196         {LCM_SEND(1), {0x29}},\r
197         {LCM_SLEEP(1)},\r
198 \r
199 //      {LCM_SEND(8), {6, 0,0xFF,0xFF,0x98,0x06,0x04,0x08}},\r
200 };\r
201 \r
202 #else /*For SPRD*/\r
203 static LCM_Init_Code init_data[] = {\r
204         {LCM_SEND(8), {6, 0,0xFF,0xFF,0x98,0x06,0x04,0x01}},// Change to Page 1\r
205         {LCM_SLEEP(5)},\r
206 \r
207         {LCM_SEND(2), {0x08,0x10}},// output SDA\r
208 \r
209         {LCM_SEND(2), {0x21,0x01}},// DE = 1 Active\r
210 \r
211         {LCM_SEND(2), {0x30,0x02}},// 480 X 800\r
212         {LCM_SEND(2), {0x31,0x02}}, // 2-dot Inversion\r
213 \r
214         {LCM_SEND(2), {0x50,0x78}},// VGMP\r
215         {LCM_SEND(2), {0x51,0x78}},// VGMN\r
216         {LCM_SEND(2), {0x52,0x00}}, //Flicker\r
217         {LCM_SEND(2), {0x53,0x61}},//Flicker\r
218 \r
219         {LCM_SEND(2), {0x60,0x07}},// SDTI\r
220         {LCM_SEND(2), {0x61,0x00}},// CRTI\r
221         {LCM_SEND(2), {0x62,0x08}},// EQTI\r
222         {LCM_SEND(2), {0x63,0x00}}, // PCTI\r
223 \r
224         {LCM_SEND(2), {0x40,0x15}},// VGH/VGL\r
225         {LCM_SEND(2), {0x41,0x44}}, // VGH/VGL\r
226         {LCM_SEND(2), {0x42,0x03}},// VGH/VGL\r
227         {LCM_SEND(2), {0x43,0x89}},// VGH/VGL\r
228         {LCM_SEND(2), {0x44,0x82}},// VGH/VGL\r
229 \r
230 //++++++++++++++++++ Gamma Setting ++++++++++++++++++//\r
231 \r
232         {LCM_SEND(8), {6, 0,0xFF,0xFF,0x98,0x06,0x04,0x01}},// Change to Page 1\r
233 \r
234         {LCM_SEND(2), {0xA0,0x00}},// Gamma 0\r
235         {LCM_SEND(2), {0xA1,0x06}},// Gamma 4\r
236         {LCM_SEND(2), {0xA2,0x0c}},// Gamma 8\r
237         {LCM_SEND(2), {0xA3,0x12}},// Gamma 16\r
238         {LCM_SEND(2), {0xA4,0x0d}},// Gamma 24\r
239         {LCM_SEND(2), {0xA5,0x1f}},// Gamma 52\r
240         {LCM_SEND(2), {0xA6,0x0b}},// Gamma 80\r
241         {LCM_SEND(2), {0xA7,0x08}},// Gamma 108\r
242         {LCM_SEND(2), {0xA8,0x04}},// Gamma 147\r
243         {LCM_SEND(2), {0xA9,0x0a}},// Gamma 175\r
244         {LCM_SEND(2), {0xAA,0x06}},// Gamma 203\r
245         {LCM_SEND(2), {0xAB,0x04}},// Gamma 231\r
246         {LCM_SEND(2), {0xAC,0x10}},// Gamma 239\r
247         {LCM_SEND(2), {0xAD,0x37}},// Gamma 247\r
248         {LCM_SEND(2), {0xAE,0x30}},// Gamma 251\r
249         {LCM_SEND(2), {0xAF,0x07}},// Gamma 255\r
250 \r
251 ///==============Nagitive\r
252         {LCM_SEND(2), {0xC0,0x00}}, // Gamma 0\r
253         {LCM_SEND(2), {0xC1,0x06}}, // Gamma 4\r
254         {LCM_SEND(2), {0xC2,0x1f}}, // Gamma 8\r
255         {LCM_SEND(2), {0xC3,0x06}}, // Gamma 16\r
256         {LCM_SEND(2), {0xC4,0x04}}, // Gamma 24\r
257         {LCM_SEND(2), {0xC5,0x13}}, // Gamma 52\r
258         {LCM_SEND(2), {0xC6,0x05}}, // Gamma 80\r
259         {LCM_SEND(2), {0xC7,0x05}}, // Gamma 108\r
260         {LCM_SEND(2), {0xC8,0x03}}, // Gamma 147\r
261         {LCM_SEND(2), {0xC9,0x06}}, // Gamma 175\r
262         {LCM_SEND(2), {0xCA,0x06}}, // Gamma 203\r
263         {LCM_SEND(2), {0xCB,0x03}}, // Gamma 231\r
264         {LCM_SEND(2), {0xCC,0x01}}, // Gamma 239\r
265         {LCM_SEND(2), {0xCD,0x27}}, // Gamma 247\r
266         {LCM_SEND(2), {0xCE,0x24}}, // Gamma 251\r
267         {LCM_SEND(2), {0xCF,0x07}}, // Gamma 255\r
268 \r
269         {LCM_SEND(8), {6, 0,0xFF,0xFF,0x98,0x06,0x04,0x06}}, // Change to Page 6\r
270 \r
271         {LCM_SEND(2), {0x00,0x3c}},\r
272         {LCM_SEND(2), {0x01,0x06}},\r
273         {LCM_SEND(2), {0x02,0x00}},\r
274         {LCM_SEND(2), {0x03,0x00}},\r
275         {LCM_SEND(2), {0x04,0x0d}},\r
276         {LCM_SEND(2), {0x05,0x0d}},\r
277         {LCM_SEND(2), {0x06,0x80}},\r
278         {LCM_SEND(2), {0x07,0x04}},\r
279         {LCM_SEND(2), {0x08,0x03}},\r
280         {LCM_SEND(2), {0x09,0x00}},\r
281         {LCM_SEND(2), {0x0A,0x00}},\r
282         {LCM_SEND(2), {0x0B,0x00}},\r
283         {LCM_SEND(2), {0x0C,0x0d}},\r
284         {LCM_SEND(2), {0x0D,0x0d}},\r
285         {LCM_SEND(2), {0x0E,0x00}},\r
286         {LCM_SEND(2), {0x0F,0x00}},\r
287 \r
288         {LCM_SEND(2), {0x10,0x50}},\r
289         {LCM_SEND(2), {0x11,0xd0}},\r
290         {LCM_SEND(2), {0x12,0x00}},\r
291         {LCM_SEND(2), {0x13,0x00}},\r
292         {LCM_SEND(2), {0x14,0x00}},\r
293         {LCM_SEND(2), {0x15,0xc0}},\r
294         {LCM_SEND(2), {0x16,0x08}},\r
295         {LCM_SEND(2), {0x17,0x00}},\r
296         {LCM_SEND(2), {0x18,0x00}},\r
297         {LCM_SEND(2), {0x19,0x00}},\r
298         {LCM_SEND(2), {0x1A,0x00}},\r
299         {LCM_SEND(2), {0x1B,0x00}},\r
300         {LCM_SEND(2), {0x1C,0x48}},\r
301         {LCM_SEND(2), {0x1D,0x00}},\r
302 \r
303         {LCM_SEND(2), {0x20,0x01}},\r
304         {LCM_SEND(2), {0x21,0x23}},\r
305         {LCM_SEND(2), {0x22,0x45}},\r
306         {LCM_SEND(2), {0x23,0x67}},\r
307         {LCM_SEND(2), {0x24,0x01}},\r
308         {LCM_SEND(2), {0x25,0x23}},\r
309         {LCM_SEND(2), {0x26,0x45}},\r
310         {LCM_SEND(2), {0x27,0x67}},\r
311 \r
312         {LCM_SEND(2), {0x30,0x13}},\r
313         {LCM_SEND(2), {0x31,0x22}},\r
314         {LCM_SEND(2), {0x32,0xdd}},\r
315         {LCM_SEND(2), {0x33,0xcc}},\r
316         {LCM_SEND(2), {0x34,0xbb}},\r
317         {LCM_SEND(2), {0x35,0xaa}},\r
318         {LCM_SEND(2), {0x36,0x22}},\r
319         {LCM_SEND(2), {0x37,0x26}},\r
320         {LCM_SEND(2), {0x38,0x72}},\r
321         {LCM_SEND(2), {0x39,0xff}},\r
322         {LCM_SEND(2), {0x3A,0x22}},\r
323         {LCM_SEND(2), {0x3B,0xee}},\r
324         {LCM_SEND(2), {0x3C,0x22}},\r
325         {LCM_SEND(2), {0x3D,0x22}},\r
326         {LCM_SEND(2), {0x3E,0x22}},\r
327         {LCM_SEND(2), {0x3F,0x22}},\r
328         {LCM_SEND(2), {0x52,0x10}}, /*reduce current when battery charging*/\r
329 \r
330         {LCM_SEND(2), {0x40,0x22}},\r
331 \r
332         {LCM_SEND(2), {0x58,0xa7}},//refresh black after resume\r
333 \r
334         {LCM_SEND(8), {6, 0,0xFF,0xFF,0x98,0x06,0x04,0x07}}, // Change to Page 7\r
335         {LCM_SEND(2), {0x17,0x22}},\r
336 \r
337         {LCM_SEND(2), {0x02,0x77}},\r
338 \r
339 //****************************************************************************//\r
340         {LCM_SEND(8), {6, 0,0xFF,0xFF,0x98,0x06,0x04,0x00}}, // Change to Page 0\r
341 \r
342         {LCM_SEND(1), {0x11}},\r
343         {LCM_SLEEP(120)},\r
344 \r
345         {LCM_SEND(1), {0x29}},\r
346         {LCM_SLEEP(10)},\r
347  };\r
348 \r
349 #endif\r
350 static LCM_Init_Code sleep_in[] =  {\r
351     {LCM_SEND(8), {6, 0,0xFF,0xFF,0x98,0x06,0x04,0x00}},\r
352     {LCM_SLEEP(1)},\r
353 \r
354     {LCM_SEND(1), {0x28}},\r
355     {LCM_SLEEP(120)},\r
356     {LCM_SEND(1), {0x10}},\r
357     {LCM_SLEEP(10)},\r
358     {LCM_SEND(8), {6, 0,0xFF,0xFF,0x98,0x06,0x04,0x01}},\r
359     {LCM_SLEEP(1)},\r
360 \r
361     {LCM_SEND(2), {0x58,0x91}},\r
362 };\r
363 \r
364 static LCM_Init_Code sleep_out[] =  {\r
365     {LCM_SEND(1), {0x11}},\r
366     {LCM_SLEEP(120)},\r
367     {LCM_SEND(1), {0x29}},\r
368     {LCM_SLEEP(20)},\r
369 };\r
370 \r
371 static LCM_Force_Cmd_Code rd_prep_code[]={\r
372         {0x39, {LCM_SEND(8), {0x6, 0, 0xFF, 0xFF, 0x98, 0x06,0x04,0x01}}},\r
373         {0x37, {LCM_SEND(2), {0x3, 0}}},\r
374 };\r
375 \r
376 static LCM_Force_Cmd_Code rd_prep_code_1[]={\r
377         {0x37, {LCM_SEND(2), {0x1, 0}}},\r
378 };\r
379 static int32_t ili9806e_mipi_init(struct panel_spec *self)\r
380 {\r
381         int32_t i;\r
382         LCM_Init_Code *init = init_data;\r
383         unsigned int tag;\r
384 \r
385         mipi_set_cmd_mode_t mipi_set_cmd_mode = self->info.mipi->ops->mipi_set_cmd_mode;\r
386         mipi_gen_write_t mipi_gen_write = self->info.mipi->ops->mipi_gen_write;\r
387         mipi_eotp_set_t mipi_eotp_set = self->info.mipi->ops->mipi_eotp_set;\r
388 \r
389         pr_debug(KERN_DEBUG "ili9806e_mipi_init\n");\r
390 \r
391         msleep(2);\r
392         mipi_set_cmd_mode();\r
393         mipi_eotp_set(1,0);\r
394 \r
395         for(i = 0; i < ARRAY_SIZE(init_data); i++){\r
396                 tag = (init->tag >>24);\r
397                 if(tag & LCM_TAG_SEND){\r
398                         mipi_gen_write(init->data, (init->tag & LCM_TAG_MASK));\r
399                         udelay(20);\r
400                 }else if(tag & LCM_TAG_SLEEP){\r
401                         //udelay((init->tag & LCM_TAG_MASK) * 1000);\r
402                                 msleep(init->tag & LCM_TAG_MASK);\r
403                 }\r
404                 init++;\r
405         }\r
406         mipi_eotp_set(1,1);\r
407 \r
408         return 0;\r
409 }\r
410 \r
411 static uint32_t ili9806e_readid(struct panel_spec *self)\r
412 {\r
413         /*Jessica TODO: need read id*/\r
414         int32_t i = 0;\r
415         uint32_t j =0;\r
416         LCM_Force_Cmd_Code * rd_prepare = rd_prep_code;\r
417         uint8_t read_data[3] = {0};\r
418         int32_t read_rtn = 0;\r
419         unsigned int tag = 0;\r
420         mipi_set_cmd_mode_t mipi_set_cmd_mode = self->info.mipi->ops->mipi_set_cmd_mode;\r
421         mipi_force_write_t mipi_force_write = self->info.mipi->ops->mipi_force_write;\r
422         mipi_force_read_t mipi_force_read = self->info.mipi->ops->mipi_force_read;\r
423         mipi_eotp_set_t mipi_eotp_set = self->info.mipi->ops->mipi_eotp_set;\r
424 \r
425         printk("lcd_ili9806e_mipi read id!\n");\r
426 \r
427         mipi_set_cmd_mode();\r
428         mipi_eotp_set(1,0);\r
429 \r
430         for(j = 0; j < 4; j++){\r
431                 rd_prepare = rd_prep_code;\r
432                 for(i = 0; i < ARRAY_SIZE(rd_prep_code); i++){\r
433                         tag = (rd_prepare->real_cmd_code.tag >> 24);\r
434                         if(tag & LCM_TAG_SEND){\r
435                                 mipi_force_write(rd_prepare->datatype, rd_prepare->real_cmd_code.data, (rd_prepare->real_cmd_code.tag & LCM_TAG_MASK));\r
436                         }else if(tag & LCM_TAG_SLEEP){\r
437                                 msleep((rd_prepare->real_cmd_code.tag & LCM_TAG_MASK));\r
438                         }\r
439                         rd_prepare++;\r
440                 }\r
441                 read_rtn = mipi_force_read(0x02, 3,(uint8_t *)read_data);\r
442                 printk("lcd_ili9806e_mipi read id 0xc5 value is 0x%x, 0x%x, 0x%x!\n", read_data[0], read_data[1], read_data[2]);\r
443 \r
444                 if((0x04 == read_data[0])){\r
445                         printk("lcd_ili9806e_mipi read id success!\n");\r
446                         mipi_eotp_set(1,1);\r
447                         return 0x04;\r
448                 }\r
449         }\r
450         mipi_eotp_set(1,1);\r
451         return 0x0;\r
452 }\r
453 \r
454 static int32_t ili9806e_enter_sleep(struct panel_spec *self, uint8_t is_sleep)\r
455 {\r
456         int32_t i;\r
457         LCM_Init_Code *sleep_in_out = NULL;\r
458         unsigned int tag;\r
459         int32_t size = 0;\r
460 \r
461         mipi_gen_write_t mipi_gen_write = self->info.mipi->ops->mipi_gen_write;\r
462         mipi_eotp_set_t mipi_eotp_set = self->info.mipi->ops->mipi_eotp_set;\r
463 \r
464         printk(KERN_DEBUG "ili9806e_enter_sleep, is_sleep = %d\n", is_sleep);\r
465 \r
466         if(is_sleep){\r
467                 sleep_in_out = sleep_in;\r
468                 size = ARRAY_SIZE(sleep_in);\r
469         }else{\r
470                 sleep_in_out = sleep_out;\r
471                 size = ARRAY_SIZE(sleep_out);\r
472         }\r
473         mipi_eotp_set(1,0);\r
474 \r
475         for(i = 0; i <size ; i++){\r
476                 tag = (sleep_in_out->tag >>24);\r
477                 if(tag & LCM_TAG_SEND){\r
478                         mipi_gen_write(sleep_in_out->data, (sleep_in_out->tag & LCM_TAG_MASK));\r
479                 }else if(tag & LCM_TAG_SLEEP){\r
480                         //udelay((sleep_in_out->tag & LCM_TAG_MASK) * 1000);\r
481                         msleep((sleep_in_out->tag & LCM_TAG_MASK));\r
482                 }\r
483                 sleep_in_out++;\r
484         }\r
485         return 0;\r
486 }\r
487 \r
488 static uint32_t ili9806e_readpowermode(struct panel_spec *self)\r
489 {\r
490         int32_t i = 0;\r
491         uint32_t j =0;\r
492         LCM_Force_Cmd_Code * rd_prepare = rd_prep_code_1;\r
493         uint8_t read_data[1] = {0};\r
494         int32_t read_rtn = 0;\r
495         unsigned int tag = 0;\r
496         uint32_t reg_val_1 = 0;\r
497         uint32_t reg_val_2 = 0;\r
498 \r
499         mipi_force_write_t mipi_force_write = self->info.mipi->ops->mipi_force_write;\r
500         mipi_force_read_t mipi_force_read = self->info.mipi->ops->mipi_force_read;\r
501         mipi_eotp_set_t mipi_eotp_set = self->info.mipi->ops->mipi_eotp_set;\r
502 \r
503         pr_debug("lcd_ili9806e_mipi read power mode!\n");\r
504         mipi_eotp_set(0,1);\r
505 \r
506         for(j = 0; j < 4; j++){\r
507                 rd_prepare = rd_prep_code_1;\r
508                 for(i = 0; i < ARRAY_SIZE(rd_prep_code_1); i++){\r
509                         tag = (rd_prepare->real_cmd_code.tag >> 24);\r
510                         if(tag & LCM_TAG_SEND){\r
511                                 mipi_force_write(rd_prepare->datatype, rd_prepare->real_cmd_code.data, (rd_prepare->real_cmd_code.tag & LCM_TAG_MASK));\r
512                         }else if(tag & LCM_TAG_SLEEP){\r
513                                 msleep((rd_prepare->real_cmd_code.tag & LCM_TAG_MASK));\r
514                         }\r
515                         rd_prepare++;\r
516                 }\r
517 \r
518                 read_rtn = mipi_force_read(0x0A, 1,(uint8_t *)read_data);\r
519                 //printk("lcd_ili9806e mipi read power mode 0x0A value is 0x%x! , read result(%d)\n", read_data[0], read_rtn);\r
520 \r
521                 if((0x9c == read_data[0])  && (0 == read_rtn)){\r
522                         pr_debug("lcd_ili9806e_mipi read power mode success!\n");\r
523                         mipi_eotp_set(1,1);\r
524                         return 0x9c;\r
525                 }\r
526         }\r
527 \r
528         mipi_eotp_set(1,1);\r
529         return 0x0;\r
530 }\r
531 \r
532 \r
533 static uint32_t ili9806e_check_esd(struct panel_spec *self)\r
534 {\r
535         uint32_t power_mode;\r
536 \r
537         pr_debug("ili9806e_check_esd!\n");\r
538         mipi_set_lp_mode_t mipi_set_data_lp_mode = self->info.mipi->ops->mipi_set_data_lp_mode;\r
539         mipi_set_hs_mode_t mipi_set_data_hs_mode = self->info.mipi->ops->mipi_set_data_hs_mode;\r
540 \r
541         mipi_set_lp_mode_t mipi_set_lp_mode = self->info.mipi->ops->mipi_set_lp_mode;\r
542         mipi_set_hs_mode_t mipi_set_hs_mode = self->info.mipi->ops->mipi_set_hs_mode;\r
543         uint16_t work_mode = self->info.mipi->work_mode;\r
544 \r
545         if(SPRDFB_MIPI_MODE_CMD==work_mode){\r
546                 mipi_set_lp_mode();\r
547         }else{\r
548                 mipi_set_data_lp_mode();\r
549         }\r
550         power_mode = ili9806e_readpowermode(self);\r
551         //power_mode = 0x0;\r
552         if(SPRDFB_MIPI_MODE_CMD==work_mode){\r
553                 mipi_set_hs_mode();\r
554         }else{\r
555                 mipi_set_data_hs_mode();\r
556         }\r
557         if(power_mode == 0x9c){\r
558                 pr_debug("ili9806e_check_esd OK!\n");\r
559                 return 1;\r
560         }else{\r
561                 printk("ili9806e_check_esd fail!(0x%x)\n", power_mode);\r
562                 return 0;\r
563         }\r
564 }\r
565 \r
566 static uint32_t ili9806e_mipi_after_suspend(struct panel_spec *self)\r
567 {\r
568         return 0;\r
569 }\r
570 \r
571 static struct panel_operations lcd_ili9806e_mipi_operations = {\r
572         .panel_init = ili9806e_mipi_init,\r
573         .panel_readid = ili9806e_readid,\r
574         .panel_enter_sleep = ili9806e_enter_sleep,\r
575         .panel_esd_check = ili9806e_check_esd,\r
576         .panel_after_suspend = ili9806e_mipi_after_suspend,\r
577 \r
578 };\r
579
580 static struct timing_rgb lcd_ili9806e_mipi_timing = {\r
581         .hfp = 60,  /* unit: pixel */// 100\r
582         .hbp = 80,//80\r
583         .hsync = 60,//6\r
584         .vfp = 20, /*unit: line*/\r
585         .vbp = 14,\r
586         .vsync =6, //6,\r
587 };\r
588 \r
589 static struct info_mipi lcd_ili9806e_mipi_info = {\r
590         .work_mode  = SPRDFB_MIPI_MODE_VIDEO,\r
591         .video_bus_width = 24, /*18,16*/\r
592         .lan_number = 2,\r
593         .phy_feq = 500*1000, //500->10MHz,400->8M in lp mode\r
594         .h_sync_pol = SPRDFB_POLARITY_POS,\r
595         .v_sync_pol = SPRDFB_POLARITY_POS,\r
596         .de_pol = SPRDFB_POLARITY_POS,\r
597         .te_pol = SPRDFB_POLARITY_POS,\r
598         .color_mode_pol = SPRDFB_POLARITY_NEG,\r
599         .shut_down_pol = SPRDFB_POLARITY_NEG,\r
600         .timing = &lcd_ili9806e_mipi_timing,\r
601         .ops = NULL,\r
602 };\r
603 \r
604 struct panel_spec lcd_ili9806e_mipi_spec = {\r
605         //.cap = PANEL_CAP_NOT_TEAR_SYNC,\r
606         .width = 480,\r
607         .height = 800,\r
608         .fps = 60,\r
609         .type = LCD_MODE_DSI,\r
610         .direction = LCD_DIRECT_NORMAL,\r
611         .is_clean_lcd = true,\r
612         .reset_timing = {5, 15, 120},\r
613         .info = {\r
614                 .mipi = &lcd_ili9806e_mipi_info\r
615         },\r
616         .ops = &lcd_ili9806e_mipi_operations,\r
617 };\r
618 \r
619 struct panel_cfg lcd_ili9806e_mipi = {\r
620         /* this panel can only be main lcd */\r
621         .dev_id = SPRDFB_MAINLCD_ID,\r
622         .lcd_id = 0x04,\r
623         .lcd_name = "lcd_ili9806e_mipi",\r
624         .panel = &lcd_ili9806e_mipi_spec,\r
625 };\r
626 \r
627 static int __init lcd_ili9806e_mipi_init(void)\r
628 {\r
629         return sprdfb_panel_register(&lcd_ili9806e_mipi);\r
630 }\r
631 \r
632 subsys_initcall(lcd_ili9806e_mipi_init);\r