import PULS_20160108
[GitHub/mt8127/android_kernel_alcatel_ttab.git] / drivers / misc / mediatek / lcm / hx8363_6575_dsi / hx8363_6575_dsi.c
1 #ifndef BUILD_LK
2 #include <linux/string.h>
3 #endif
4 #include "lcm_drv.h"
5
6 // ---------------------------------------------------------------------------
7 // Local Constants
8 // ---------------------------------------------------------------------------
9
10 #define FRAME_WIDTH (480)
11 #define FRAME_HEIGHT (800)
12
13 #define REGFLAG_DELAY 0XFE
14 #define REGFLAG_END_OF_TABLE 0xFF // END OF REGISTERS MARKER
15
16 // ---------------------------------------------------------------------------
17 // Local Variables
18 // ---------------------------------------------------------------------------
19
20 static LCM_UTIL_FUNCS lcm_util = {0};
21
22 #define SET_RESET_PIN(v) (lcm_util.set_reset_pin((v)))
23
24 #define UDELAY(n) (lcm_util.udelay(n))
25 #define MDELAY(n) (lcm_util.mdelay(n))
26
27
28 // ---------------------------------------------------------------------------
29 // Local Functions
30 // ---------------------------------------------------------------------------
31
32 #define dsi_set_cmdq_V2(cmd, count, ppara, force_update) lcm_util.dsi_set_cmdq_V2(cmd, count, ppara, force_update)
33 #define dsi_set_cmdq(pdata, queue_size, force_update) lcm_util.dsi_set_cmdq(pdata, queue_size, force_update)
34 #define wrtie_cmd(cmd) lcm_util.dsi_write_cmd(cmd)
35 #define write_regs(addr, pdata, byte_nums) lcm_util.dsi_write_regs(addr, pdata, byte_nums)
36 #define read_reg lcm_util.dsi_read_reg()
37
38
39 struct LCM_setting_table {
40 unsigned cmd;
41 unsigned char count;
42 unsigned char para_list[64];
43 };
44
45
46 static struct LCM_setting_table lcm_initialization_setting[] = {
47
48 /*
49 Note :
50
51 Data ID will depends on the following rule.
52
53 count of parameters > 1 => Data ID = 0x39
54 count of parameters = 1 => Data ID = 0x15
55 count of parameters = 0 => Data ID = 0x05
56
57 Structure Format :
58
59 {DCS command, count of parameters, {parameter list}}
60 {REGFLAG_DELAY, milliseconds of time, {}},
61
62 ...
63
64 Setting ending by predefined flag
65
66 {REGFLAG_END_OF_TABLE, 0x00, {}}
67 */
68
69 {0xB9, 3, {0xFF, 0x83, 0x63}},
70 {REGFLAG_DELAY, 10, {}},
71
72 {0xB0, 2, {0x01, 0x08}},
73 {REGFLAG_DELAY, 10, {}},
74
75 #if 0
76 {0xB1, 19, {0x01, 0x00, 0x44, 0x07,
77 0x01, 0x11, 0x11, 0x2F,
78 0x37, 0x27, 0x27, 0x40,
79 0x32, 0x00, 0xE6, 0xE6,
80 0xE6, 0xE6, 0xE6}},
81 #else//new 20120224
82 {0xB1, 19, {0x01, 0x00, 0x44, 0x07,
83 0x01, 0x0E, 0x0E, 0x21,
84 0x29, 0x3F, 0x3F, 0x40,
85 0x32, 0x00, 0xE6, 0xE6,
86 0xE6, 0xE6, 0xE6}},
87
88 #endif
89 {REGFLAG_DELAY, 10, {}},
90
91 {0xB2, 2, {0x08, 0x00}},
92 {REGFLAG_DELAY, 10, {}},
93
94 {0xB4, 7, {0x02, 0x19, 0x9C, 0x08,
95 0x19, 0x05, 0x73}},
96 {REGFLAG_DELAY, 10, {}},
97
98 {0xB6, 1, {0x1C}},
99 {REGFLAG_DELAY, 10, {}},
100
101 {0xBF, 1, {0x05, 0x60, 0x00, 0x10}},
102 {REGFLAG_DELAY, 10, {}},
103
104 #if 0
105 {0xE2, 1, {0x01}},//0x01=dynamic,0x00=static
106 {REGFLAG_DELAY, 10, {}},
107
108 {0xE5, 1, {0x15}},//0x15 L, 0x16 M, 0x17 H
109 {REGFLAG_DELAY, 10, {}},
110 #endif
111
112 // ENABLE FMARK
113 {0x44, 2, {((FRAME_HEIGHT/2)>>8), ((FRAME_HEIGHT/2)&0xFF)}},
114 {0x35, 1, {0x00}},
115 // SET GAMMA
116 #if 0
117 {0xE0, 34, {0x00, 0x0A, 0x0F, 0x2F,
118 0x32, 0x3F, 0x22, 0x42,
119 0x85, 0x89, 0xCC, 0xD1,
120 0xD6, 0x15, 0x15, 0x12,
121 0x18, 0x00, 0x0A, 0x0F,
122 0x2F, 0x32, 0x3F, 0x22,
123 0x42, 0x85, 0x89, 0xCC,
124 0xD1, 0xD6, 0x15, 0x15,
125 0x12, 0x18}},
126 #else//new 20120224
127 {0xE0, 34, {0x00, 0x06, 0x0A, 0x12,
128 0x15, 0x3B, 0x1D, 0x34,
129 0x87, 0x8E, 0xCC, 0xCF,
130 0xCE, 0x0E, 0x12, 0x11,
131 0x18, 0x00, 0x06, 0x0A,
132 0x12, 0x15, 0x3B, 0x1D,
133 0x34, 0x87, 0x8E, 0xCC,
134 0xCF, 0xCE, 0x0E, 0x12,
135 0x11, 0x18}},
136
137 #endif
138 {REGFLAG_DELAY, 10, {}},
139
140 {0xBA, 14, {0x11, 0x00, 0x56, 0xC6,
141 0x10, 0x89, 0xFF, 0x0F,
142 0x33, 0x6E, 0x04, 0x07,
143 0x9A, 0x14}},
144
145 {0xC2, 1, {0x04}},
146 {REGFLAG_DELAY, 10, {}},
147
148 {0x3A, 1, {0x77}},
149 {REGFLAG_DELAY, 10, {}},
150
151 {0x36, 1, {0x0A}},
152 {REGFLAG_DELAY, 10, {}},
153
154 {0x51, 1, {0x00}},
155 {REGFLAG_DELAY, 10, {}},
156
157 {0x53, 1, {0x24}},
158 {REGFLAG_DELAY, 10, {}},
159
160 {0x55, 1, {0x01}},
161 {REGFLAG_DELAY, 10, {}},
162
163 {0x5E, 1, {0x70}},
164 {REGFLAG_DELAY, 10, {}},
165
166 {0xC9, 2, {0x00,0X03}},//17.143kHz
167 {REGFLAG_DELAY, 10, {}},
168
169 // Note
170 // Strongly recommend not to set Sleep out / Display On here. That will cause messed frame to be shown as later the backlight is on.
171
172
173 // Setting ending by predefined flag
174 {REGFLAG_END_OF_TABLE, 0x00, {}}
175 };
176
177 /*
178 static struct LCM_setting_table lcm_set_window[] = {
179 {0x2A, 4, {0x00, 0x00, (FRAME_WIDTH>>8), (FRAME_WIDTH&0xFF)}},
180 {0x2B, 4, {0x00, 0x00, (FRAME_HEIGHT>>8), (FRAME_HEIGHT&0xFF)}},
181 {REGFLAG_END_OF_TABLE, 0x00, {}}
182 };
183 */
184
185 static struct LCM_setting_table lcm_sleep_out_setting[] = {
186 // Sleep Out
187 {0x11, 1, {0x00}},
188 {REGFLAG_DELAY, 120, {}},
189
190 // Display ON
191 {0x29, 1, {0x00}},
192 {REGFLAG_DELAY, 20, {}},
193 {REGFLAG_END_OF_TABLE, 0x00, {}}
194 };
195
196
197 static struct LCM_setting_table lcm_deep_sleep_mode_in_setting[] = {
198 // Display off sequence
199 {0x28, 1, {0x00}},
200
201 // Sleep Mode On
202 {0x10, 1, {0x00}},
203 {REGFLAG_DELAY, 120, {}},
204
205 {REGFLAG_END_OF_TABLE, 0x00, {}}
206 };
207
208
209 static struct LCM_setting_table lcm_backlight_level_setting[] = {
210 {0x51, 1, {0xFF}},
211 {REGFLAG_END_OF_TABLE, 0x00, {}}
212 };
213
214 static struct LCM_setting_table lcm_backlight_mode_setting[] = {
215 {0x55, 1, {0x1}},
216 {REGFLAG_END_OF_TABLE, 0x00, {}}
217 };
218
219
220 static void push_table(struct LCM_setting_table *table, unsigned int count, unsigned char force_update)
221 {
222 unsigned int i;
223
224 for(i = 0; i < count; i++) {
225
226 unsigned cmd;
227 cmd = table[i].cmd;
228
229 switch (cmd) {
230
231 case REGFLAG_DELAY :
232 MDELAY(table[i].count);
233 break;
234
235 case REGFLAG_END_OF_TABLE :
236 break;
237
238 default:
239 dsi_set_cmdq_V2(cmd, table[i].count, table[i].para_list, force_update);
240 }
241 }
242
243 }
244
245
246 // ---------------------------------------------------------------------------
247 // LCM Driver Implementations
248 // ---------------------------------------------------------------------------
249
250 static void lcm_set_util_funcs(const LCM_UTIL_FUNCS *util)
251 {
252 memcpy(&lcm_util, util, sizeof(LCM_UTIL_FUNCS));
253 }
254
255
256 static void lcm_get_params(LCM_PARAMS *params)
257 {
258 memset(params, 0, sizeof(LCM_PARAMS));
259
260 params->type = LCM_TYPE_DSI;
261
262 params->width = FRAME_WIDTH;
263 params->height = FRAME_HEIGHT;
264
265 // enable tearing-free
266 params->dbi.te_mode = LCM_DBI_TE_MODE_VSYNC_ONLY;
267 params->dbi.te_edge_polarity = LCM_POLARITY_RISING;
268
269 params->dsi.mode = CMD_MODE;
270
271 // DSI
272 /* Command mode setting */
273 params->dsi.LANE_NUM = LCM_TWO_LANE;
274 //The following defined the fomat for data coming from LCD engine.
275 params->dsi.data_format.color_order = LCM_COLOR_ORDER_RGB;
276 params->dsi.data_format.trans_seq = LCM_DSI_TRANS_SEQ_MSB_FIRST;
277 params->dsi.data_format.padding = LCM_DSI_PADDING_ON_LSB;
278 params->dsi.data_format.format = LCM_DSI_FORMAT_RGB888;
279
280 // Highly depends on LCD driver capability.
281 params->dsi.packet_size=256;
282
283 // Video mode setting
284 params->dsi.PS=LCM_PACKED_PS_24BIT_RGB888;
285
286 params->dsi.word_count=480*3;
287 params->dsi.vertical_sync_active=2;
288 params->dsi.vertical_backporch=2;
289 params->dsi.vertical_frontporch=2;
290 params->dsi.vertical_active_line=800;
291
292 params->dsi.line_byte=2180; // 2256 = 752*3
293 params->dsi.horizontal_sync_active_byte=26;
294 params->dsi.horizontal_backporch_byte=206;
295 params->dsi.horizontal_frontporch_byte=206;
296 params->dsi.rgb_byte=(480*3+6);
297
298 params->dsi.horizontal_sync_active_word_count=20;
299 params->dsi.horizontal_backporch_word_count=200;
300 params->dsi.horizontal_frontporch_word_count=200;
301
302 // Bit rate calculation
303 params->dsi.pll_div1=38; // fref=26MHz, fvco=fref*(div1+1) (div1=0~63, fvco=500MHZ~1GHz)
304 params->dsi.pll_div2=1; // div2=0~15: fout=fvo/(2*div2)
305
306 }
307
308
309 static void lcm_init(void)
310 {
311 SET_RESET_PIN(1);
312 SET_RESET_PIN(0);
313 MDELAY(1);
314 SET_RESET_PIN(1);
315 MDELAY(10);
316
317 push_table(lcm_initialization_setting, sizeof(lcm_initialization_setting) / sizeof(struct LCM_setting_table), 1);
318 }
319
320
321 static void lcm_suspend(void)
322 {
323 push_table(lcm_deep_sleep_mode_in_setting, sizeof(lcm_deep_sleep_mode_in_setting) / sizeof(struct LCM_setting_table), 1);
324 }
325
326
327 static void lcm_resume(void)
328 {
329 push_table(lcm_sleep_out_setting, sizeof(lcm_sleep_out_setting) / sizeof(struct LCM_setting_table), 1);
330 }
331
332
333 static void lcm_update(unsigned int x, unsigned int y,
334 unsigned int width, unsigned int height)
335 {
336 unsigned int x0 = x;
337 unsigned int y0 = y;
338 unsigned int x1 = x0 + width - 1;
339 unsigned int y1 = y0 + height - 1;
340
341 unsigned char x0_MSB = ((x0>>8)&0xFF);
342 unsigned char x0_LSB = (x0&0xFF);
343 unsigned char x1_MSB = ((x1>>8)&0xFF);
344 unsigned char x1_LSB = (x1&0xFF);
345 unsigned char y0_MSB = ((y0>>8)&0xFF);
346 unsigned char y0_LSB = (y0&0xFF);
347 unsigned char y1_MSB = ((y1>>8)&0xFF);
348 unsigned char y1_LSB = (y1&0xFF);
349
350 unsigned int data_array[16];
351
352 data_array[0]= 0x00053902;
353 data_array[1]= (x1_MSB<<24)|(x0_LSB<<16)|(x0_MSB<<8)|0x2a;
354 data_array[2]= (x1_LSB);
355 data_array[3]= 0x00053902;
356 data_array[4]= (y1_MSB<<24)|(y0_LSB<<16)|(y0_MSB<<8)|0x2b;
357 data_array[5]= (y1_LSB);
358 data_array[6]= 0x002c3909;
359
360 dsi_set_cmdq(data_array, 7, 0);
361
362 }
363
364
365 static void lcm_setbacklight(unsigned int level)
366 {
367 unsigned int default_level = 0;
368 unsigned int mapped_level = 0;
369
370 //for LGE backlight IC mapping table
371 if(level > 255)
372 level = 255;
373
374 if(level >0)
375 mapped_level = default_level+(level)*(255-default_level)/(255);
376 else
377 mapped_level=0;
378
379 // Refresh value of backlight level.
380 lcm_backlight_level_setting[0].para_list[0] = mapped_level;
381
382 push_table(lcm_backlight_level_setting, sizeof(lcm_backlight_level_setting) / sizeof(struct LCM_setting_table), 1);
383 }
384
385 static void lcm_setbacklight_mode(unsigned int mode)
386 {
387 lcm_backlight_mode_setting[0].para_list[0] = mode;
388 push_table(lcm_backlight_mode_setting, sizeof(lcm_backlight_mode_setting) / sizeof(struct LCM_setting_table), 1);
389 }
390
391 //static void lcm_setpwm(unsigned int divider)
392 //{
393 // TBD
394 //}
395
396
397 //static unsigned int lcm_getpwm(unsigned int divider)
398 //{
399 // ref freq = 15MHz, B0h setting 0x80, so 80.6% * freq is pwm_clk;
400 // pwm_clk / 255 / 2(lcm_setpwm() 6th params) = pwm_duration = 23706
401 // unsigned int pwm_clk = 23706 / (1<<divider);
402 // return pwm_clk;
403 //}
404
405
406 // ---------------------------------------------------------------------------
407 // Get LCM Driver Hooks
408 // ---------------------------------------------------------------------------
409 LCM_DRIVER hx8363_6575_dsi_lcm_drv =
410 {
411 .name = "hx8363_6575_dsi",
412 .set_util_funcs = lcm_set_util_funcs,
413 .get_params = lcm_get_params,
414 .init = lcm_init,
415 .suspend = lcm_suspend,
416 .resume = lcm_resume,
417 .update = lcm_update,
418 .set_backlight = lcm_setbacklight,
419 .set_backlight_mode = lcm_setbacklight_mode,
420 //.set_pwm = lcm_setpwm,
421 //.get_pwm = lcm_getpwm
422 };