import PULS_20160108
[GitHub/mt8127/android_kernel_alcatel_ttab.git] / drivers / misc / mediatek / lcm / nt35516_qhd_dsi_cmd_tft9k1342 / nt35516_qhd_dsi_cmd_tft9k1342.c
1 #include <linux/string.h>
2 #ifndef BUILD_UBOOT
3 #include <linux/kernel.h>
4 #endif
5 #include "lcm_drv.h"
6
7 // ---------------------------------------------------------------------------
8 // Local Constants
9 // ---------------------------------------------------------------------------
10
11 #define FRAME_WIDTH (540)
12 #define FRAME_HEIGHT (960)
13
14 // ---------------------------------------------------------------------------
15 // Local Variables
16 // ---------------------------------------------------------------------------
17
18 static LCM_UTIL_FUNCS lcm_util = {0};
19
20 #define SET_RESET_PIN(v) (lcm_util.set_reset_pin((v)))
21
22 #define UDELAY(n) (lcm_util.udelay(n))
23 #define MDELAY(n) (lcm_util.mdelay(n))
24 #define REGFLAG_DELAY 0XFE
25 #define REGFLAG_END_OF_TABLE 0x00 // END OF REGISTERS MARKER
26
27
28 // ---------------------------------------------------------------------------
29 // Local Functions
30 // ---------------------------------------------------------------------------
31 #define dsi_set_cmdq_V2(cmd, count, ppara, force_update) lcm_util.dsi_set_cmdq_V2(cmd, count, ppara, force_update)
32 #define dsi_set_cmdq(pdata, queue_size, force_update) lcm_util.dsi_set_cmdq(pdata, queue_size, force_update)
33 #define wrtie_cmd(cmd) lcm_util.dsi_write_cmd(cmd)
34 #define write_regs(addr, pdata, byte_nums) lcm_util.dsi_write_regs(addr, pdata, byte_nums)
35 //#define read_reg lcm_util.dsi_read_reg()
36 #define read_reg_v2(cmd, buffer, buffer_size) lcm_util.dsi_dcs_read_lcm_reg_v2(cmd, buffer, buffer_size)
37
38
39
40 #define LCM_DSI_CMD_MODE
41
42 struct LCM_setting_table {
43 unsigned cmd;
44 unsigned char count;
45 unsigned char para_list[64];
46 };
47
48
49 static struct LCM_setting_table lcm_initialization_setting[] = {
50
51 /*
52 Note :
53
54 Data ID will depends on the following rule.
55
56 count of parameters > 1 => Data ID = 0x39
57 count of parameters = 1 => Data ID = 0x15
58 count of parameters = 0 => Data ID = 0x05
59
60 Structure Format :
61
62 {DCS command, count of parameters, {parameter list}}
63 {REGFLAG_DELAY, milliseconds of time, {}},
64
65 ...
66
67 Setting ending by predefined flag
68
69 {REGFLAG_END_OF_TABLE, 0x00, {}}
70 */
71
72
73 {0xff,4,{0xAA,0x55,0x25,0x01}},
74 {0xf3,4,{0x02,0x03,0x07,0x15}},
75 {0xF0,5,{0x55,0xAA,0x52,0x08,0x00}},
76 {0xB8,4,{0x01,0x02,0x02,0x02}},
77 {0xBC,3,{0x05,0x05,0x05}},
78 {0xF0,5,{0x55,0xAA,0x52,0x08,0x01}},
79 {0xB0,3,{0x05,0x05,0x05}},
80 {0xB1,3,{0x05,0x05,0x05}},
81 {0xB6,3,{0x44,0x44,0x44}},
82 {0xB7,3,{0x34,0x34,0x34}},
83 {0xB3,3,{0x10,0x10,0x10}},
84 {0xB9,3,{0x34,0x34,0x34}},
85 {0xB4,3,{0x0A,0x0A,0x0A}},
86 {0xBA,3,{0x14,0x14,0x14}},
87 {0xBC,3,{0x00,0xA0,0x00}},
88 {0xBD,3,{0x00,0xA0,0x00}},
89 {0xBE,1,{0x4E}},
90 {0xD1,16,{0x00,0x32,0x00,0x41,0x00,0x54,0x00,0x67,0x00,0x7A,0x00,0x98,0x00,0xB0,0x00,0xDB}} ,
91 {0xD2,16,{0x01,0x01,0x01,0x3F,0x01,0x70,0x01,0xB4,0x01,0xEC,0x01,0xED,0x02,0x1E,0x02,0x51}},
92 {0xD3,16,{0x02,0x6C,0x02,0x8D,0x02,0xA5,0x02,0xC9,0x02,0xEA,0x03,0x19,0x03,0x45,0x03,0x7A}},
93 {0xD4,4,{0x03,0xB0,0x03,0xF4}} ,
94 {0xD5,16,{0x00,0x32,0x00,0x41,0x00,0x54,0x00,0x67,0x00,0x7A,0x00,0x98,0x00,0xB0,0x00,0xDB}} ,
95 {0xD6,16,{0x01,0x01,0x01,0x3F,0x01,0x70,0x01,0xB4,0x01,0xEC,0x01,0xED,0x02,0x1E,0x02,0x51}},
96 {0xD7,16,{0x02,0x6C,0x02,0x8D,0x02,0xA5,0x02,0xC9,0x02,0xEA,0x03,0x19,0x03,0x45,0x03,0x7A}} ,
97 {0xD8,4,{0x03,0xB0,0x03,0xF4}} ,
98 {0xD9,16,{0x00,0x32,0x00,0x41,0x00,0x54,0x00,0x67,0x00,0x7A,0x00,0x98,0x00,0xB0,0x00,0xDB}},
99 {0xDD,16,{0x01,0x01,0x01,0x3F,0x01,0x70,0x01,0xB4,0x01,0xEC,0x01,0xED,0x02,0x1E,0x02,0x51}},
100 {0xDE,16,{0x02,0x6C,0x02,0x8D,0x02,0xA5,0x02,0xC9,0x02,0xEA,0x03,0x19,0x03,0x45,0x03,0x7A}} ,
101 {0xDF,4,{0x03,0xB0,0x03,0xF4}} ,
102 {0xE0,16,{0x00,0x32,0x00,0x41,0x00,0x54,0x00,0x67,0x00,0x7A,0x00,0x98,0x00,0xB0,0x00,0xDB}},
103 {0xE1,16,{0x01,0x01,0x01,0x3F,0x01,0x70,0x01,0xB4,0x01,0xEC,0x01,0xED,0x02,0x1E,0x02,0x51}} ,
104 {0xE2,16,{0x02,0x6C,0x02,0x8D,0x02,0xA5,0x02,0xC9,0x02,0xEA,0x03,0x19,0x03,0x45,0x03,0x7A}} ,
105
106 {0xE3,4,{0x03,0xB0,0x03,0xF4}} ,
107 {0xE4,16,{0x00,0x32,0x00,0x41,0x00,0x54,0x00,0x67,0x00,0x7A,0x00,0x98,0x00,0xB0,0x00,0xDB}},
108 {0xE5,16,{0x01,0x01,0x01,0x3F,0x01,0x70,0x01,0xB4,0x01,0xEC,0x01,0xED,0x02,0x1E,0x02,0x51}},
109 {0xEA,16,{0x02,0x6C,0x02,0x8D,0x02,0xA5,0x02,0xC9,0x02,0xEA,0x03,0x19,0x03,0x45,0x03,0x7A}} ,
110 {0xEB,4,{0x03,0xB0,0x03,0xF4}} ,
111
112 {0x3A,1,{0x07}},
113 {0x35,1,{0x00}},
114 {0x55,1,{2}},
115 {0x4C,1,{0x11}},
116
117 // Note
118 // Strongly recommend not to set Sleep out / Display On here. That will cause messed frame to be shown as later the backlight is on.
119
120
121 // Setting ending by predefined flag
122 {REGFLAG_END_OF_TABLE, 0x00, {}}
123 };
124 static struct LCM_setting_table lcm_sleep_out_setting[] = {
125 // Sleep Out
126 {0x11, 1, {0x00}},
127 {REGFLAG_DELAY, 20, {}},
128
129 // Display ON
130 {0x29, 1, {0x00}},
131 {REGFLAG_DELAY, 120, {}},
132 {REGFLAG_END_OF_TABLE, 0x00, {}}
133 };
134
135
136 static struct LCM_setting_table lcm_sleep_mode_in_setting[] = {
137 // Display off sequence
138 {0x28, 1, {0x00}},
139 {REGFLAG_DELAY, 200, {}},
140
141 // Sleep Mode On
142 {0x10, 1, {0x00}},
143 {REGFLAG_DELAY, 120, {}},
144 {REGFLAG_END_OF_TABLE, 0x00, {}}
145 };
146 static struct LCM_setting_table lcm_compare_id_setting[] = {
147 // Display off sequence
148 {0xF0, 5, {0x55, 0xaa, 0x52,0x08,0x00}},
149 {REGFLAG_DELAY, 10, {}},
150
151 {REGFLAG_END_OF_TABLE, 0x00, {}}
152 };
153
154 void push_table(struct LCM_setting_table *table, unsigned int count, unsigned char force_update)
155 {
156 unsigned int i;
157
158 for(i = 0; i < count; i++) {
159
160 unsigned cmd;
161 cmd = table[i].cmd;
162
163 switch (cmd) {
164
165 case REGFLAG_DELAY :
166 MDELAY(table[i].count);
167 break;
168
169 case REGFLAG_END_OF_TABLE :
170 break;
171
172 default:
173 dsi_set_cmdq_V2(cmd, table[i].count, table[i].para_list, force_update);
174 MDELAY(2);
175 }
176 }
177
178 }
179
180
181 static void init_lcm_registers(void)
182 {
183 unsigned int data_array[16];
184 }
185 // ---------------------------------------------------------------------------
186 // LCM Driver Implementations
187 // ---------------------------------------------------------------------------
188
189 static void lcm_set_util_funcs(const LCM_UTIL_FUNCS *util)
190 {
191 memcpy(&lcm_util, util, sizeof(LCM_UTIL_FUNCS));
192 }
193
194
195 static void lcm_get_params(LCM_PARAMS *params)
196 {
197 memset(params, 0, sizeof(LCM_PARAMS));
198
199 params->type = LCM_TYPE_DSI;
200
201 params->width = FRAME_WIDTH;
202 params->height = FRAME_HEIGHT;
203
204 // enable tearing-free
205 params->dbi.te_mode = LCM_DBI_TE_MODE_VSYNC_ONLY;
206 params->dbi.te_edge_polarity = LCM_POLARITY_RISING;
207
208 #if defined(LCM_DSI_CMD_MODE)
209 params->dsi.mode = CMD_MODE;
210 #else
211 params->dsi.mode = SYNC_PULSE_VDO_MODE;
212 #endif
213
214 // DSI
215 /* Command mode setting */
216 params->dsi.LANE_NUM = LCM_TWO_LANE;
217 //The following defined the fomat for data coming from LCD engine.
218 params->dsi.data_format.color_order = LCM_COLOR_ORDER_RGB;
219 params->dsi.data_format.trans_seq = LCM_DSI_TRANS_SEQ_MSB_FIRST;
220 params->dsi.data_format.padding = LCM_DSI_PADDING_ON_LSB;
221 params->dsi.data_format.format = LCM_DSI_FORMAT_RGB888;
222
223 // Highly depends on LCD driver capability.
224 // Not support in MT6573
225
226 params->dsi.DSI_WMEM_CONTI=0x3C;
227 params->dsi.DSI_RMEM_CONTI=0x3E;
228
229
230 params->dsi.packet_size=256;
231
232 // Video mode setting
233 params->dsi.intermediat_buffer_num = 2;
234
235 params->dsi.PS=LCM_PACKED_PS_24BIT_RGB888;
236
237 params->dsi.vertical_sync_active = 3;
238 params->dsi.vertical_backporch = 12;
239 params->dsi.vertical_frontporch = 2;
240 params->dsi.vertical_active_line = FRAME_HEIGHT;
241
242 params->dsi.horizontal_sync_active = 10;
243 params->dsi.horizontal_backporch = 50;
244 params->dsi.horizontal_frontporch = 50;
245 params->dsi.horizontal_active_pixel = FRAME_WIDTH;
246
247 params->dsi.LPX =12;
248
249 // Bit rate calculation
250 params->dsi.pll_div1=38; // fref=26MHz, fvco=fref*(div1+1) (div1=0~63, fvco=500MHZ~1GHz)
251 params->dsi.pll_div2=1; // div2=0~15: fout=fvo/(2*div2)
252
253 }
254
255
256 static void lcm_init(void)
257 {
258
259 SET_RESET_PIN(0);
260 MDELAY(200);
261 SET_RESET_PIN(1);
262 MDELAY(50);
263
264 push_table(lcm_initialization_setting, sizeof(lcm_initialization_setting) / sizeof(struct LCM_setting_table), 1);
265
266 }
267
268
269 static void lcm_suspend(void)
270 {
271 //push_table(lcm_sleep_mode_in_setting, sizeof(lcm_sleep_mode_in_setting) / sizeof(struct LCM_setting_table), 1);
272 //SET_RESET_PIN(0);
273 //MDELAY(1);
274 //SET_RESET_PIN(1);
275 unsigned int data_array[2];
276 #if 1
277 //data_array[0] = 0x00000504; // Display Off
278 //dsi_set_cmdq(&data_array, 1, 1);
279 //MDELAY(100);
280 data_array[0] = 0x00280500; // Display Off
281 dsi_set_cmdq(&data_array, 1, 1);
282 MDELAY(10);
283 data_array[0] = 0x00100500; // Sleep In
284 dsi_set_cmdq(&data_array, 1, 1);
285 MDELAY(100);
286 #endif
287 #ifdef BUILD_UBOOT
288 printf("zhibin uboot %s\n", __func__);
289 #else
290 printk("zhibin kernel %s\n", __func__);
291 #endif
292
293 }
294
295
296 static void lcm_resume(void)
297 {
298 //lcm_init();
299 #ifdef BUILD_UBOOT
300 printf("zhibin uboot %s\n", __func__);
301 #else
302 printk("zhibin kernel %s\n", __func__);
303
304 #endif
305 push_table(lcm_sleep_out_setting, sizeof(lcm_sleep_out_setting) / sizeof(struct LCM_setting_table), 1);
306
307 }
308
309
310 static void lcm_update(unsigned int x, unsigned int y,
311 unsigned int width, unsigned int height)
312 {
313 unsigned int x0 = x;
314 unsigned int y0 = y;
315 unsigned int x1 = x0 + width - 1;
316 unsigned int y1 = y0 + height - 1;
317
318 unsigned char x0_MSB = ((x0>>8)&0xFF);
319 unsigned char x0_LSB = (x0&0xFF);
320 unsigned char x1_MSB = ((x1>>8)&0xFF);
321 unsigned char x1_LSB = (x1&0xFF);
322 unsigned char y0_MSB = ((y0>>8)&0xFF);
323 unsigned char y0_LSB = (y0&0xFF);
324 unsigned char y1_MSB = ((y1>>8)&0xFF);
325 unsigned char y1_LSB = (y1&0xFF);
326
327 unsigned int data_array[16];
328
329 #ifdef BUILD_UBOOT
330 printf("zhibin uboot %s\n", __func__);
331 #else
332 printk("zhibin kernel %s\n", __func__);
333 #endif
334
335 data_array[0]= 0x00053902;
336 data_array[1]= (x1_MSB<<24)|(x0_LSB<<16)|(x0_MSB<<8)|0x2a;
337 data_array[2]= (x1_LSB);
338 data_array[3]= 0x00053902;
339 data_array[4]= (y1_MSB<<24)|(y0_LSB<<16)|(y0_MSB<<8)|0x2b;
340 data_array[5]= (y1_LSB);
341 data_array[6]= 0x002c3909;
342
343 dsi_set_cmdq(&data_array, 7, 0);
344
345 }
346 static unsigned int lcm_compare_id(void)
347 {
348
349 int array[4];
350 char buffer[3];
351 char id0=0;
352 char id1=0;
353 char id2=0;
354
355
356 SET_RESET_PIN(0);
357 MDELAY(200);
358 SET_RESET_PIN(1);
359 MDELAY(200);
360
361 array[0] = 0x00083700;// read id return two byte,version and id
362 dsi_set_cmdq(array, 1, 1);
363
364 read_reg_v2(0x04,buffer, 3);
365
366 id0 = buffer[0]; //should be 0x00
367 id1 = buffer[1];//should be 0x80
368 id2 = buffer[2];//should be 0x00
369 #ifdef BUILD_UBOOT
370 printf("zhibin uboot %s\n", __func__);
371 printf("%s, id0 = 0x%08x\n", __func__, id0);//should be 0x00
372 printf("%s, id1 = 0x%08x\n", __func__, id1);//should be 0x80
373 printf("%s, id2 = 0x%08x\n", __func__, id2);//should be 0x00
374 #else
375 //printk("zhibin kernel %s\n", __func__);
376 #endif
377
378 return 0;
379
380
381 }
382
383
384 LCM_DRIVER nt35516_qhd_dsi_cmd_tft9k1342_drv =
385 {
386 .name = "nt35516_dsi_tf",
387 .set_util_funcs = lcm_set_util_funcs,
388 .compare_id = lcm_compare_id,
389 .get_params = lcm_get_params,
390 .init = lcm_init,
391 .suspend = lcm_suspend,
392 .resume = lcm_resume,
393 #if defined(LCM_DSI_CMD_MODE)
394 .update = lcm_update,
395 #endif
396 };