2 #include <linux/string.h>
6 // ---------------------------------------------------------------------------
8 // ---------------------------------------------------------------------------
10 #define FRAME_WIDTH (480)
11 #define FRAME_HEIGHT (800)
13 #define REGFLAG_DELAY 0XFE
14 #define REGFLAG_END_OF_TABLE 0xFF // END OF REGISTERS MARKER
16 // ---------------------------------------------------------------------------
18 // ---------------------------------------------------------------------------
20 static LCM_UTIL_FUNCS lcm_util
= {0};
22 #define SET_RESET_PIN(v) (lcm_util.set_reset_pin((v)))
24 #define UDELAY(n) (lcm_util.udelay(n))
25 #define MDELAY(n) (lcm_util.mdelay(n))
28 // ---------------------------------------------------------------------------
30 // ---------------------------------------------------------------------------
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()
39 struct LCM_setting_table
{
42 unsigned char para_list
[64];
46 static struct LCM_setting_table lcm_initialization_setting
[] = {
51 Data ID will depends on the following rule.
53 count of parameters > 1 => Data ID = 0x39
54 count of parameters = 1 => Data ID = 0x15
55 count of parameters = 0 => Data ID = 0x05
59 {DCS command, count of parameters, {parameter list}}
60 {REGFLAG_DELAY, milliseconds of time, {}},
64 Setting ending by predefined flag
66 {REGFLAG_END_OF_TABLE, 0x00, {}}
69 {0xB9, 3, {0xFF, 0x83, 0x63}},
70 {REGFLAG_DELAY
, 10, {}},
72 {0xB0, 2, {0x01, 0x08}},
73 {REGFLAG_DELAY
, 10, {}},
76 {0xB1, 19, {0x01, 0x00, 0x44, 0x07,
77 0x01, 0x11, 0x11, 0x2F,
78 0x37, 0x27, 0x27, 0x40,
79 0x32, 0x00, 0xE6, 0xE6,
82 {0xB1, 19, {0x01, 0x00, 0x44, 0x07,
83 0x01, 0x0E, 0x0E, 0x21,
84 0x29, 0x3F, 0x3F, 0x40,
85 0x32, 0x00, 0xE6, 0xE6,
89 {REGFLAG_DELAY
, 10, {}},
91 {0xB2, 2, {0x08, 0x00}},
92 {REGFLAG_DELAY
, 10, {}},
94 {0xB4, 7, {0x02, 0x19, 0x9C, 0x08,
96 {REGFLAG_DELAY
, 10, {}},
99 {REGFLAG_DELAY
, 10, {}},
101 {0xBF, 1, {0x05, 0x60, 0x00, 0x10}},
102 {REGFLAG_DELAY
, 10, {}},
105 {0xE2, 1, {0x01}},//0x01=dynamic,0x00=static
106 {REGFLAG_DELAY
, 10, {}},
108 {0xE5, 1, {0x15}},//0x15 L, 0x16 M, 0x17 H
109 {REGFLAG_DELAY
, 10, {}},
113 {0x44, 2, {((FRAME_HEIGHT
/2)>>8), ((FRAME_HEIGHT
/2)&0xFF)}},
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,
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,
138 {REGFLAG_DELAY
, 10, {}},
140 {0xBA, 14, {0x11, 0x00, 0x56, 0xC6,
141 0x10, 0x89, 0xFF, 0x0F,
142 0x33, 0x6E, 0x04, 0x07,
146 {REGFLAG_DELAY
, 10, {}},
149 {REGFLAG_DELAY
, 10, {}},
152 {REGFLAG_DELAY
, 10, {}},
155 {REGFLAG_DELAY
, 10, {}},
158 {REGFLAG_DELAY
, 10, {}},
161 {REGFLAG_DELAY
, 10, {}},
164 {REGFLAG_DELAY
, 10, {}},
166 {0xC9, 2, {0x00,0X03}},//17.143kHz
167 {REGFLAG_DELAY
, 10, {}},
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.
173 // Setting ending by predefined flag
174 {REGFLAG_END_OF_TABLE
, 0x00, {}}
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, {}}
185 static struct LCM_setting_table lcm_sleep_out_setting
[] = {
188 {REGFLAG_DELAY
, 120, {}},
192 {REGFLAG_DELAY
, 20, {}},
193 {REGFLAG_END_OF_TABLE
, 0x00, {}}
197 static struct LCM_setting_table lcm_deep_sleep_mode_in_setting
[] = {
198 // Display off sequence
203 {REGFLAG_DELAY
, 120, {}},
205 {REGFLAG_END_OF_TABLE
, 0x00, {}}
209 static struct LCM_setting_table lcm_backlight_level_setting
[] = {
211 {REGFLAG_END_OF_TABLE
, 0x00, {}}
214 static struct LCM_setting_table lcm_backlight_mode_setting
[] = {
216 {REGFLAG_END_OF_TABLE
, 0x00, {}}
220 static void push_table(struct LCM_setting_table
*table
, unsigned int count
, unsigned char force_update
)
224 for(i
= 0; i
< count
; i
++) {
232 MDELAY(table
[i
].count
);
235 case REGFLAG_END_OF_TABLE
:
239 dsi_set_cmdq_V2(cmd
, table
[i
].count
, table
[i
].para_list
, force_update
);
246 // ---------------------------------------------------------------------------
247 // LCM Driver Implementations
248 // ---------------------------------------------------------------------------
250 static void lcm_set_util_funcs(const LCM_UTIL_FUNCS
*util
)
252 memcpy(&lcm_util
, util
, sizeof(LCM_UTIL_FUNCS
));
256 static void lcm_get_params(LCM_PARAMS
*params
)
258 memset(params
, 0, sizeof(LCM_PARAMS
));
260 params
->type
= LCM_TYPE_DSI
;
262 params
->width
= FRAME_WIDTH
;
263 params
->height
= FRAME_HEIGHT
;
265 // enable tearing-free
266 params
->dbi
.te_mode
= LCM_DBI_TE_MODE_VSYNC_ONLY
;
267 params
->dbi
.te_edge_polarity
= LCM_POLARITY_RISING
;
269 params
->dsi
.mode
= CMD_MODE
;
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
;
280 // Highly depends on LCD driver capability.
281 params
->dsi
.packet_size
=256;
283 // Video mode setting
284 params
->dsi
.PS
=LCM_PACKED_PS_24BIT_RGB888
;
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;
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);
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;
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)
309 static void lcm_init(void)
317 push_table(lcm_initialization_setting
, sizeof(lcm_initialization_setting
) / sizeof(struct LCM_setting_table
), 1);
321 static void lcm_suspend(void)
323 push_table(lcm_deep_sleep_mode_in_setting
, sizeof(lcm_deep_sleep_mode_in_setting
) / sizeof(struct LCM_setting_table
), 1);
327 static void lcm_resume(void)
329 push_table(lcm_sleep_out_setting
, sizeof(lcm_sleep_out_setting
) / sizeof(struct LCM_setting_table
), 1);
333 static void lcm_update(unsigned int x
, unsigned int y
,
334 unsigned int width
, unsigned int height
)
338 unsigned int x1
= x0
+ width
- 1;
339 unsigned int y1
= y0
+ height
- 1;
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);
350 unsigned int data_array
[16];
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;
360 dsi_set_cmdq(data_array
, 7, 0);
365 static void lcm_setbacklight(unsigned int level
)
367 unsigned int default_level
= 0;
368 unsigned int mapped_level
= 0;
370 //for LGE backlight IC mapping table
375 mapped_level
= default_level
+(level
)*(255-default_level
)/(255);
379 // Refresh value of backlight level.
380 lcm_backlight_level_setting
[0].para_list
[0] = mapped_level
;
382 push_table(lcm_backlight_level_setting
, sizeof(lcm_backlight_level_setting
) / sizeof(struct LCM_setting_table
), 1);
385 static void lcm_setbacklight_mode(unsigned int mode
)
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);
391 //static void lcm_setpwm(unsigned int divider)
397 //static unsigned int lcm_getpwm(unsigned int divider)
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);
406 // ---------------------------------------------------------------------------
407 // Get LCM Driver Hooks
408 // ---------------------------------------------------------------------------
409 LCM_DRIVER hx8363_6575_dsi_lcm_drv
=
411 .name
= "hx8363_6575_dsi",
412 .set_util_funcs
= lcm_set_util_funcs
,
413 .get_params
= lcm_get_params
,
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