1 /*
2 * Allwinner SoCs display driver.
3 *
4 * Copyright (C) 2016 Allwinner.
5 *
6 * This file is licensed under the terms of the GNU General Public
7 * License version 2. This program is licensed "as is" without any
8 * warranty of any kind, whether express or implied.
9 */
10
11 #include "disp_lcd.h"
12 #include "disp_display.h"
13 #include <linux/backlight.h>
14 #include <linux/hrtimer.h>
15
16 #define LCD_SPI_MAX_TRANSFER_BYTE (100*PAGE_SIZE)
17
18 struct disp_lcd_private_data {
19 struct disp_lcd_flow open_flow;
20 struct disp_lcd_flow close_flow;
21 struct disp_panel_para panel_info;
22 struct panel_extend_para panel_extend_info;
23 struct panel_extend_para panel_extend_info_set;
24 u32 panel_extend_dirty;
25 struct disp_lcd_cfg lcd_cfg;
26 struct disp_lcd_panel_fun lcd_panel_fun;
27 bool enabling;
28 bool disabling;
29 bool bl_enabled;
30 u32 enabled;
31 u32 power_enabled;
32 u32 bl_need_enabled;
33 s32 color_temperature;
34 u32 color_inverse;
35 struct {
36 uintptr_t dev;
37 u32 channel;
38 u32 polarity;
39 u32 period_ns;
40 u32 duty_ns;
41 u32 enabled;
42 } pwm_info;
43 struct backlight_device *p_bl_dev;
44 struct mutex backligt_lock;
45 struct mutex layer_mlock;
46 wait_queue_head_t wait;
47 unsigned long wait_count;
48 struct hrtimer timer;
49 struct spi_device *spi_device;
50 };
51 static spinlock_t lcd_data_lock;
52
53 static struct lcd_fb_device *lcds;
54 static struct disp_lcd_private_data *lcd_private;
55
disp_get_lcd(u32 disp)56 struct lcd_fb_device *disp_get_lcd(u32 disp)
57 {
58 if (disp > SUPPORT_MAX_LCD - 1)
59 return NULL;
60 return &lcds[disp];
61 }
disp_lcd_get_priv(struct lcd_fb_device * lcd)62 static struct disp_lcd_private_data *disp_lcd_get_priv(struct lcd_fb_device *lcd)
63 {
64 if (lcd == NULL) {
65 lcd_fb_wrn("param is NULL!\n");
66 return NULL;
67 }
68
69 return (struct disp_lcd_private_data *)lcd->priv_data;
70 }
71
disp_lcd_is_used(struct lcd_fb_device * lcd)72 static s32 disp_lcd_is_used(struct lcd_fb_device *lcd)
73 {
74 struct disp_lcd_private_data *lcdp = disp_lcd_get_priv(lcd);
75 s32 ret = 0;
76
77 if ((lcd == NULL) || (lcdp == NULL))
78 ret = 0;
79 else
80 ret = (s32)lcdp->lcd_cfg.lcd_used;
81
82 return ret;
83 }
84
lcd_parse_panel_para(u32 disp,struct disp_panel_para * info)85 static s32 lcd_parse_panel_para(u32 disp, struct disp_panel_para *info)
86 {
87 s32 ret = 0;
88 char primary_key[25];
89 s32 value = 0;
90 u32 Bpp = 0, lines = 0;
91
92 sprintf(primary_key, "lcd_fb%d", disp);
93 memset(info, 0, sizeof(struct disp_panel_para));
94
95 ret = lcd_fb_script_get_item(primary_key, "lcd_x", &value, 1);
96 if (ret == 1)
97 info->lcd_x = value;
98
99 ret = lcd_fb_script_get_item(primary_key, "lcd_y", &value, 1);
100 if (ret == 1)
101 info->lcd_y = value;
102
103 ret = lcd_fb_script_get_item(primary_key, "lcd_width", &value, 1);
104 if (ret == 1)
105 info->lcd_width = value;
106
107 ret = lcd_fb_script_get_item(primary_key, "lcd_height", &value, 1);
108 if (ret == 1)
109 info->lcd_height = value;
110
111 /*unit:Mhz, speed of rgb data transfer*/
112 ret = lcd_fb_script_get_item(primary_key, "lcd_data_speed", &value, 1);
113 if (ret == 1)
114 info->lcd_data_speed = value;
115
116 ret = lcd_fb_script_get_item(primary_key, "lcd_pwm_used", &value, 1);
117 if (ret == 1)
118 info->lcd_pwm_used = value;
119
120 if (info->lcd_pwm_used) {
121 ret = lcd_fb_script_get_item(primary_key, "lcd_pwm_ch", &value, 1);
122 if (ret == 1)
123 info->lcd_pwm_ch = value;
124
125 ret = lcd_fb_script_get_item(primary_key, "lcd_pwm_freq", &value, 1);
126 if (ret == 1)
127 info->lcd_pwm_freq = value;
128
129 ret = lcd_fb_script_get_item(primary_key, "lcd_pwm_pol", &value, 1);
130 if (ret == 1)
131 info->lcd_pwm_pol = value;
132 }
133
134 ret = lcd_fb_script_get_item(primary_key, "lcd_if", &value, 1);
135 if (ret == 1)
136 info->lcd_if = value;
137
138 ret = lcd_fb_script_get_item(primary_key, "lcd_pixel_fmt", &value, 1);
139 if (ret == 1)
140 info->lcd_pixel_fmt = value;
141
142 ret = lcd_fb_script_get_item(primary_key, "lcd_dbi_fmt", &value, 1);
143 if (ret == 1)
144 info->lcd_dbi_fmt = value;
145
146 ret = lcd_fb_script_get_item(primary_key, "lcd_dbi_clk_mode", &value, 1);
147 if (ret == 1)
148 info->lcd_dbi_clk_mode = value;
149
150 ret = lcd_fb_script_get_item(primary_key, "lcd_dbi_te", &value, 1);
151 if (ret == 1)
152 info->lcd_dbi_te = value;
153
154 ret = lcd_fb_script_get_item(primary_key, "fb_buffer_num", &value, 1);
155 if (ret == 1)
156 info->fb_buffer_num = value;
157 else
158 info->fb_buffer_num = 2;
159
160 ret = lcd_fb_script_get_item(primary_key, "lcd_dbi_if", &value, 1);
161 if (ret == 1)
162 info->dbi_if = value;
163
164
165 ret = lcd_fb_script_get_item(primary_key, "lcd_rgb_order", &value, 1);
166 if (ret == 1)
167 info->lcd_rgb_order = value;
168
169 ret = lcd_fb_script_get_item(primary_key, "lcd_fps", &value, 1);
170 if (ret == 1)
171 info->lcd_fps = value;
172 else
173 info->lcd_fps = 25;
174
175 ret = lcd_fb_script_get_item(primary_key, "lcd_spi_bus_num", &value, 1);
176 if (ret == 1)
177 info->lcd_spi_bus_num = value;
178
179 ret = lcd_fb_script_get_item(primary_key, "lcd_frm", &value, 1);
180 if (ret == 1)
181 info->lcd_frm = value;
182
183
184 ret = lcd_fb_script_get_item(primary_key, "lcd_gamma_en", &value, 1);
185 if (ret == 1)
186 info->lcd_gamma_en = value;
187
188 ret =
189 lcd_fb_script_get_item(primary_key, "lcd_model_name",
190 (int *)info->lcd_model_name, 2);
191
192 if (info->lcd_pixel_fmt <= LCDFB_FORMAT_BGR_888) {
193 Bpp = 4;
194 } else if (info->lcd_pixel_fmt == LCDFB_FORMAT_BGR_888 ||
195 info->lcd_pixel_fmt == LCDFB_FORMAT_RGB_888) {
196 Bpp = 3;
197 } else if (info->lcd_pixel_fmt >= LCDFB_FORMAT_RGB_565) {
198 Bpp = 2;
199 }
200 info->lines_per_transfer = 1;
201 lines = LCD_SPI_MAX_TRANSFER_BYTE / (info->lcd_x * Bpp);
202 for (; lines > 1; --lines) {
203 if (!(info->lcd_y % lines))
204 break;
205 }
206
207 if (lines >= 1)
208 info->lines_per_transfer = lines;
209
210 return 0;
211 }
212
lcd_get_sys_config(u32 disp,struct disp_lcd_cfg * lcd_cfg)213 static void lcd_get_sys_config(u32 disp, struct disp_lcd_cfg *lcd_cfg)
214 {
215 struct disp_gpio_info *gpio_info;
216 int value = 1;
217 char primary_key[20], sub_name[25];
218 int i = 0;
219 int ret;
220
221 sprintf(primary_key, "lcd_fb%d", disp);
222 /* lcd_used */
223 ret = lcd_fb_script_get_item(primary_key, "lcd_used", &value, 1);
224 if (ret == 1)
225 lcd_cfg->lcd_used = value;
226
227 if (lcd_cfg->lcd_used == 0)
228 return;
229
230 /* lcd_bl_en */
231 lcd_cfg->lcd_bl_en_used = 0;
232 gpio_info = &(lcd_cfg->lcd_bl_en);
233 ret =
234 lcd_fb_script_get_item(primary_key, "lcd_bl_en", (int *)gpio_info,
235 3);
236 if (ret == 3)
237 lcd_cfg->lcd_bl_en_used = 1;
238
239 sprintf(sub_name, "lcd_bl_en_power");
240 ret =
241 lcd_fb_script_get_item(primary_key, sub_name,
242 (int *)lcd_cfg->lcd_bl_en_power, 2);
243
244 /* lcd fix power */
245 for (i = 0; i < LCD_POWER_NUM; i++) {
246 if (i == 0)
247 sprintf(sub_name, "lcd_fix_power");
248 else
249 sprintf(sub_name, "lcd_fix_power%d", i);
250 lcd_cfg->lcd_power_used[i] = 0;
251 ret =
252 lcd_fb_script_get_item(primary_key, sub_name,
253 (int *)(lcd_cfg->lcd_fix_power[i]),
254 2);
255 if (ret == 2)
256 /* str */
257 lcd_cfg->lcd_fix_power_used[i] = 1;
258 }
259
260 /* lcd_power */
261 for (i = 0; i < LCD_POWER_NUM; i++) {
262 if (i == 0)
263 sprintf(sub_name, "lcd_power");
264 else
265 sprintf(sub_name, "lcd_power%d", i);
266 lcd_cfg->lcd_power_used[i] = 0;
267 ret =
268 lcd_fb_script_get_item(primary_key, sub_name,
269 (int *)(lcd_cfg->lcd_power[i]), 2);
270 if (ret == 2)
271 /* str */
272 lcd_cfg->lcd_power_used[i] = 1;
273 }
274
275 /* lcd_gpio */
276 for (i = 0; i < 6; i++) {
277 sprintf(sub_name, "lcd_gpio_%d", i);
278
279 gpio_info = &(lcd_cfg->lcd_gpio[i]);
280 ret =
281 lcd_fb_script_get_item(primary_key, sub_name,
282 (int *)gpio_info, 3);
283 if (!ret)
284 lcd_cfg->lcd_gpio_used[i] = 1;
285 }
286
287 sprintf(sub_name, "lcd_spi_dc_pin");
288 gpio_info = &(lcd_cfg->lcd_spi_dc_pin);
289 ret =
290 lcd_fb_script_get_item(primary_key, sub_name,
291 (int *)gpio_info, 3);
292
293
294 for (i = 0; i < LCD_GPIO_REGU_NUM; i++) {
295 sprintf(sub_name, "lcd_gpio_power%d", i);
296
297 ret =
298 lcd_fb_script_get_item(primary_key, sub_name,
299 (int *)lcd_cfg->lcd_gpio_power[i],
300 2);
301 }
302
303 for (i = 0; i < LCD_GPIO_REGU_NUM; i++) {
304 if (i == 0)
305 sprintf(sub_name, "lcd_pin_power");
306 else
307 sprintf(sub_name, "lcd_pin_power%d", i);
308 ret =
309 lcd_fb_script_get_item(primary_key, sub_name,
310 (int *)lcd_cfg->lcd_pin_power[i],
311 2);
312 }
313
314 /* backlight adjust */
315 value = 0;
316 lcd_fb_script_get_item(primary_key, "lcd_pwm_used", &value, 1);
317 if (value == 1) {
318 for (i = 0; i < 101; i++) {
319 sprintf(sub_name, "lcd_bl_%d_percent", i);
320 lcd_cfg->backlight_curve_adjust[i] = 0;
321
322 if (i == 100)
323 lcd_cfg->backlight_curve_adjust[i] = 255;
324
325 ret =
326 lcd_fb_script_get_item(primary_key, sub_name, &value, 1);
327 if (ret == 1) {
328 value = (value > 100) ? 100 : value;
329 value = value * 255 / 100;
330 lcd_cfg->backlight_curve_adjust[i] = value;
331 }
332 }
333 sprintf(sub_name, "lcd_backlight");
334 ret = lcd_fb_script_get_item(primary_key, sub_name, &value, 1);
335 if (ret == 1) {
336 value = (value > 256) ? 256 : value;
337 lcd_cfg->backlight_bright = value;
338 } else {
339 lcd_cfg->backlight_bright = 197;
340 }
341 }
342
343
344 }
345
disp_lcd_pin_cfg(struct lcd_fb_device * lcd,u32 bon)346 static s32 disp_lcd_pin_cfg(struct lcd_fb_device *lcd, u32 bon)
347 {
348 int i, ret;
349 struct disp_lcd_private_data *lcdp = disp_lcd_get_priv(lcd);
350 char dev_name[25];
351
352 if ((lcd == NULL) || (lcdp == NULL)) {
353 lcd_fb_wrn("NULL hdl!\n");
354 return -1;
355 }
356 lcd_fb_inf("lcd %d pin config, state %s, %d\n", lcd->disp,
357 (bon) ? "on" : "off", bon);
358
359 /* io-pad */
360 if (bon == 1) {
361 for (i = 0; i < LCD_GPIO_REGU_NUM; i++) {
362 if (!
363 ((!strcmp(lcdp->lcd_cfg.lcd_pin_power[i], ""))
364 || (!strcmp(lcdp->lcd_cfg.lcd_pin_power[i], "none"))))
365 ret = lcd_fb_power_enable(lcdp->lcd_cfg.lcd_pin_power[i]);
366 if (ret)
367 return DIS_FAIL;
368 }
369 }
370
371 sprintf(dev_name, "lcd_fb%d", lcd->disp);
372 lcd_fb_pin_set_state(dev_name,
373 (bon == 1) ?
374 DISP_PIN_STATE_ACTIVE : DISP_PIN_STATE_SLEEP);
375
376 if (bon)
377 return DIS_SUCCESS;
378
379 for (i = LCD_GPIO_REGU_NUM - 1; i >= 0; i--) {
380 if (!((!strcmp(lcdp->lcd_cfg.lcd_pin_power[i], ""))
381 || (!strcmp(lcdp->lcd_cfg.lcd_pin_power[i], "none"))))
382 ret = lcd_fb_power_disable(lcdp->lcd_cfg.lcd_pin_power[i]);
383 if (ret)
384 return DIS_FAIL;
385 }
386
387 return DIS_SUCCESS;
388 }
389
disp_lcd_pwm_enable(struct lcd_fb_device * lcd)390 static s32 disp_lcd_pwm_enable(struct lcd_fb_device *lcd)
391 {
392 struct disp_lcd_private_data *lcdp = disp_lcd_get_priv(lcd);
393
394 if ((lcd == NULL) || (lcdp == NULL)) {
395 lcd_fb_wrn("NULL hdl!\n");
396 return -1;
397 }
398
399 if (disp_lcd_is_used(lcd) && lcdp->pwm_info.dev)
400 return lcd_fb_pwm_enable(lcdp->pwm_info.dev);
401 lcd_fb_wrn("pwm device hdl is NULL\n");
402
403 return -1;
404 }
405
disp_lcd_pwm_disable(struct lcd_fb_device * lcd)406 static s32 disp_lcd_pwm_disable(struct lcd_fb_device *lcd)
407 {
408 struct disp_lcd_private_data *lcdp = disp_lcd_get_priv(lcd);
409 s32 ret = -1;
410 struct pwm_device *pwm_dev;
411
412 if ((lcd == NULL) || (lcdp == NULL)) {
413 lcd_fb_wrn("NULL hdl!\n");
414 return -1;
415 }
416
417 if (disp_lcd_is_used(lcd) && lcdp->pwm_info.dev) {
418 ret = lcd_fb_pwm_disable(lcdp->pwm_info.dev);
419 pwm_dev = (struct pwm_device *)lcdp->pwm_info.dev;
420 /*following is for reset pwm state purpose*/
421 lcd_fb_pwm_config(lcdp->pwm_info.dev,
422 pwm_dev->state.duty_cycle - 1,
423 pwm_dev->state.period);
424 lcd_fb_pwm_set_polarity(lcdp->pwm_info.dev,
425 !lcdp->pwm_info.polarity);
426 return ret;
427 }
428 lcd_fb_wrn("pwm device hdl is NULL\n");
429
430 return -1;
431 }
432
disp_lcd_backlight_enable(struct lcd_fb_device * lcd)433 static s32 disp_lcd_backlight_enable(struct lcd_fb_device *lcd)
434 {
435 int ret;
436 struct disp_gpio_info gpio_info;
437 struct disp_lcd_private_data *lcdp = disp_lcd_get_priv(lcd);
438 unsigned long flags;
439
440 if ((lcd == NULL) || (lcdp == NULL)) {
441 lcd_fb_wrn("NULL hdl!\n");
442 return -1;
443 }
444
445 spin_lock_irqsave(&lcd_data_lock, flags);
446 if (lcdp->bl_enabled) {
447 spin_unlock_irqrestore(&lcd_data_lock, flags);
448 return -EBUSY;
449 }
450
451 lcdp->bl_need_enabled = 1;
452 lcdp->bl_enabled = true;
453 spin_unlock_irqrestore(&lcd_data_lock, flags);
454
455 if (disp_lcd_is_used(lcd)) {
456 unsigned int bl;
457
458 if (lcdp->lcd_cfg.lcd_bl_en_used) {
459 /* io-pad */
460 ret = lcd_fb_power_enable(lcdp->lcd_cfg.lcd_bl_en_power);
461 if (ret)
462 return DIS_FAIL;
463
464 memcpy(&gpio_info, &(lcdp->lcd_cfg.lcd_bl_en),
465 sizeof(struct disp_gpio_info));
466
467 lcd_fb_gpio_request(&gpio_info);
468 }
469 bl = disp_lcd_get_bright(lcd);
470 disp_lcd_set_bright(lcd, bl);
471 }
472
473 return 0;
474 }
475
disp_lcd_backlight_disable(struct lcd_fb_device * lcd)476 static s32 disp_lcd_backlight_disable(struct lcd_fb_device *lcd)
477 {
478 int ret;
479 struct disp_lcd_private_data *lcdp = disp_lcd_get_priv(lcd);
480 unsigned long flags;
481
482 if ((lcd == NULL) || (lcdp == NULL)) {
483 lcd_fb_wrn("NULL hdl!\n");
484 return -1;
485 }
486
487 spin_lock_irqsave(&lcd_data_lock, flags);
488 if (!lcdp->bl_enabled) {
489 spin_unlock_irqrestore(&lcd_data_lock, flags);
490 return -EBUSY;
491 }
492
493 lcdp->bl_enabled = false;
494 spin_unlock_irqrestore(&lcd_data_lock, flags);
495
496 if (!disp_lcd_is_used(lcd))
497 return DIS_SUCCESS;
498
499 if (!lcdp->lcd_cfg.lcd_bl_en_used)
500 return DIS_SUCCESS;
501
502 ret = lcd_fb_power_disable(lcdp->lcd_cfg.lcd_bl_en_power);
503 if (ret)
504 return DIS_FAIL;
505
506 return DIS_SUCCESS;
507 }
508
disp_lcd_power_enable(struct lcd_fb_device * lcd,u32 power_id)509 static s32 disp_lcd_power_enable(struct lcd_fb_device *lcd, u32 power_id)
510 {
511 struct disp_lcd_private_data *lcdp = disp_lcd_get_priv(lcd);
512
513 if ((lcd == NULL) || (lcdp == NULL)) {
514 lcd_fb_wrn("NULL hdl!\n");
515 return -1;
516 }
517
518 if (disp_lcd_is_used(lcd)) {
519 if (lcdp->lcd_cfg.lcd_power_used[power_id] == 1) {
520 /* regulator type */
521 lcd_fb_power_enable(lcdp->lcd_cfg.
522 lcd_power[power_id]);
523 }
524 }
525
526 return 0;
527 }
528
disp_lcd_power_disable(struct lcd_fb_device * lcd,u32 power_id)529 static s32 disp_lcd_power_disable(struct lcd_fb_device *lcd, u32 power_id)
530 {
531 struct disp_lcd_private_data *lcdp = disp_lcd_get_priv(lcd);
532
533 if ((lcd == NULL) || (lcdp == NULL)) {
534 lcd_fb_wrn("NULL hdl!\n");
535 return -1;
536 }
537
538 if (disp_lcd_is_used(lcd)) {
539 if (lcdp->lcd_cfg.lcd_power_used[power_id] == 1) {
540 /* regulator type */
541 lcd_fb_power_disable(lcdp->lcd_cfg.lcd_power[power_id]);
542 }
543 }
544
545 return 0;
546 }
547
disp_lcd_bright_get_adjust_value(struct lcd_fb_device * lcd,u32 bright)548 static s32 disp_lcd_bright_get_adjust_value(struct lcd_fb_device *lcd, u32 bright)
549 {
550 struct disp_lcd_private_data *lcdp = disp_lcd_get_priv(lcd);
551
552 if ((lcd == NULL) || (lcdp == NULL)) {
553 lcd_fb_wrn("NULL hdl!\n");
554 return -1;
555 }
556 bright = (bright > 255) ? 255 : bright;
557 return lcdp->panel_extend_info.lcd_bright_curve_tbl[bright];
558 }
559
disp_lcd_bright_curve_init(struct lcd_fb_device * lcd)560 static s32 disp_lcd_bright_curve_init(struct lcd_fb_device *lcd)
561 {
562 struct disp_lcd_private_data *lcdp = disp_lcd_get_priv(lcd);
563 u32 i = 0, j = 0;
564 u32 items = 0;
565 u32 lcd_bright_curve_tbl[101][2];
566
567 if ((lcd == NULL) || (lcdp == NULL)) {
568 lcd_fb_wrn("NULL hdl!\n");
569 return -1;
570 }
571
572 for (i = 0; i < 101; i++) {
573 if (lcdp->lcd_cfg.backlight_curve_adjust[i] == 0) {
574 if (i == 0) {
575 lcd_bright_curve_tbl[items][0] = 0;
576 lcd_bright_curve_tbl[items][1] = 0;
577 items++;
578 }
579 } else {
580 lcd_bright_curve_tbl[items][0] = 255 * i / 100;
581 lcd_bright_curve_tbl[items][1] =
582 lcdp->lcd_cfg.backlight_curve_adjust[i];
583 items++;
584 }
585 }
586
587 for (i = 0; i < items - 1; i++) {
588 u32 num =
589 lcd_bright_curve_tbl[i + 1][0] - lcd_bright_curve_tbl[i][0];
590
591 for (j = 0; j < num; j++) {
592 u32 value = 0;
593
594 value =
595 lcd_bright_curve_tbl[i][1] +
596 ((lcd_bright_curve_tbl[i + 1][1] -
597 lcd_bright_curve_tbl[i][1]) * j) / num;
598 lcdp->panel_extend_info.lcd_bright_curve_tbl[lcd_bright_curve_tbl[i][0] + j]
599 = value;
600 }
601 }
602 lcdp->panel_extend_info.lcd_bright_curve_tbl[255] =
603 lcd_bright_curve_tbl[items - 1][1];
604
605 return 0;
606 }
607
disp_lcd_set_bright(struct lcd_fb_device * lcd,u32 bright)608 s32 disp_lcd_set_bright(struct lcd_fb_device *lcd, u32 bright)
609 {
610 u32 duty_ns;
611 __u64 backlight_bright = bright;
612 __u64 backlight_dimming;
613 __u64 period_ns;
614 struct disp_lcd_private_data *lcdp = disp_lcd_get_priv(lcd);
615 unsigned long flags;
616 bool bright_update = false;
617
618 if ((lcd == NULL) || (lcdp == NULL)) {
619 lcd_fb_wrn("NULL hdl!\n");
620 return -1;
621 }
622
623 spin_lock_irqsave(&lcd_data_lock, flags);
624 backlight_bright = (backlight_bright > 255) ? 255 : backlight_bright;
625 if (lcdp->lcd_cfg.backlight_bright != backlight_bright) {
626 bright_update = true;
627 lcdp->lcd_cfg.backlight_bright = backlight_bright;
628 }
629 spin_unlock_irqrestore(&lcd_data_lock, flags);
630
631 if (lcdp->pwm_info.dev) {
632 if (backlight_bright != 0)
633 backlight_bright += 1;
634 backlight_bright =
635 disp_lcd_bright_get_adjust_value(lcd, backlight_bright);
636
637 lcdp->lcd_cfg.backlight_dimming =
638 (lcdp->lcd_cfg.backlight_dimming ==
639 0) ? 256 : lcdp->lcd_cfg.backlight_dimming;
640 backlight_dimming = lcdp->lcd_cfg.backlight_dimming;
641 period_ns = lcdp->pwm_info.period_ns;
642 duty_ns =
643 (backlight_bright * backlight_dimming * period_ns / 256 +
644 128) / 256;
645 lcdp->pwm_info.duty_ns = duty_ns;
646 lcd_fb_pwm_config(lcdp->pwm_info.dev, duty_ns, period_ns);
647 }
648
649 if (lcdp->lcd_panel_fun.set_bright && lcdp->enabled) {
650 lcdp->lcd_panel_fun.set_bright(lcd->disp,
651 disp_lcd_bright_get_adjust_value
652 (lcd, bright));
653 }
654
655 return 0;
656 }
657
disp_lcd_get_bright(struct lcd_fb_device * lcd)658 s32 disp_lcd_get_bright(struct lcd_fb_device *lcd)
659 {
660 struct disp_lcd_private_data *lcdp = disp_lcd_get_priv(lcd);
661
662 if ((lcd == NULL) || (lcdp == NULL)) {
663 lcd_fb_wrn("NULL hdl!\n");
664 return -1;
665 }
666
667 return lcdp->lcd_cfg.backlight_bright;
668 }
669
disp_lcd_set_bright_dimming(struct lcd_fb_device * lcd,u32 dimming)670 static s32 disp_lcd_set_bright_dimming(struct lcd_fb_device *lcd, u32 dimming)
671 {
672 struct disp_lcd_private_data *lcdp = disp_lcd_get_priv(lcd);
673 u32 bl = 0;
674
675 if ((lcd == NULL) || (lcdp == NULL)) {
676 lcd_fb_wrn("NULL hdl!\n");
677 return -1;
678 }
679
680 dimming = dimming > 256 ? 256 : dimming;
681 lcdp->lcd_cfg.backlight_dimming = dimming;
682 bl = disp_lcd_get_bright(lcd);
683 disp_lcd_set_bright(lcd, bl);
684
685 return 0;
686 }
687
disp_lcd_get_panel_info(struct lcd_fb_device * lcd,struct disp_panel_para * info)688 static s32 disp_lcd_get_panel_info(struct lcd_fb_device *lcd,
689 struct disp_panel_para *info)
690 {
691 struct disp_lcd_private_data *lcdp = disp_lcd_get_priv(lcd);
692
693 if ((lcd == NULL) || (lcdp == NULL)) {
694 lcd_fb_wrn("NULL hdl!\n");
695 return -1;
696 }
697
698 memcpy(info, (struct disp_panel_para *) (&(lcdp->panel_info)),
699 sizeof(struct disp_panel_para));
700 return 0;
701 }
702
703
704
705 /* lcd enable except for backlight */
disp_lcd_fake_enable(struct lcd_fb_device * lcd)706 static s32 disp_lcd_fake_enable(struct lcd_fb_device *lcd)
707 {
708 lcd_fb_wrn("To be implement!\n");
709 return 0;
710 }
711
712
713
714
disp_lcd_vsync_handle(unsigned long data)715 void disp_lcd_vsync_handle(unsigned long data)
716 {
717 struct spi_device *spi = (struct spi_device *)data;
718 struct lcd_fb_device *p_lcd = NULL;
719 struct disp_lcd_private_data *lcdp = NULL;
720 int i;
721
722 for (i = 0; i < SUPPORT_MAX_LCD; ++i) {
723 p_lcd = disp_get_lcd(i);
724 if (p_lcd->spi_device == spi)
725 break;
726 }
727 lcdp = disp_lcd_get_priv(p_lcd);
728
729 lcdp->wait_count++;
730 wake_up_interruptible(&lcdp->wait);
731 }
732
disp_lcd_timer_handle(struct hrtimer * timer)733 enum hrtimer_restart disp_lcd_timer_handle(struct hrtimer *timer)
734 {
735 struct disp_lcd_private_data *lcdp =
736 container_of(timer, struct disp_lcd_private_data, timer);
737
738 hrtimer_forward(timer, timer->base->get_time(),
739 ktime_set(0, 1000000000 / lcdp->panel_info.lcd_fps));
740 disp_lcd_vsync_handle((unsigned long)lcdp->spi_device);
741
742 return HRTIMER_RESTART;
743 }
744
spi_dbi_config_init(struct disp_lcd_private_data * lcdp,struct spi_dbi_config * dbi_config)745 void spi_dbi_config_init(struct disp_lcd_private_data *lcdp, struct spi_dbi_config *dbi_config)
746 {
747 #if defined(SUPPORT_DBI_IF)
748 if (lcdp->panel_info.lcd_if == LCD_FB_IF_DBI) {
749 DBI_WRITE(dbi_config->dbi_mode);
750 DBI_MSB_FIRST(dbi_config->dbi_mode);
751 DBI_TR_COMMAND(dbi_config->dbi_mode);
752 DBI_DCX_COMMAND(dbi_config->dbi_mode);
753
754 dbi_config->dbi_format = 0;
755 dbi_config->dbi_interface = lcdp->panel_info.dbi_if;
756 if (lcdp->panel_info.lcd_pixel_fmt == LCDFB_FORMAT_RGBA_8888 ||
757 lcdp->panel_info.lcd_pixel_fmt == LCDFB_FORMAT_BGRA_8888 ||
758 lcdp->panel_info.lcd_pixel_fmt == LCDFB_FORMAT_RGBX_8888 ||
759 lcdp->panel_info.lcd_pixel_fmt == LCDFB_FORMAT_BGRX_8888) {
760 dbi_config->dbi_rgb32_alpha_pos = 1;
761 } else {
762 dbi_config->dbi_rgb32_alpha_pos = 0;
763 }
764 dbi_config->dbi_fps = lcdp->panel_info.lcd_fps;
765 dbi_config->dbi_video_v = lcdp->panel_info.lcd_x;
766 dbi_config->dbi_video_h = lcdp->panel_info.lines_per_transfer;
767 dbi_config->dbi_src_sequence = lcdp->panel_info.lcd_rgb_order;
768 dbi_config->dbi_te_en = 0;
769 dbi_config->dbi_vsync_handle = disp_lcd_vsync_handle;
770 dbi_config->dbi_clk_out_mode = lcdp->panel_info.lcd_dbi_clk_mode;
771 }
772 #endif
773 }
774
disp_lcd_spi_init(struct lcd_fb_device * lcd)775 static s32 disp_lcd_spi_init(struct lcd_fb_device *lcd)
776 {
777 int ret = -1;
778 struct spi_master *master;
779 struct spi_dbi_config dbi_config;
780 struct disp_lcd_private_data *lcdp = disp_lcd_get_priv(lcd);
781
782 if (!lcd || !lcdp) {
783 lcd_fb_wrn("Null pointer!\n");
784 return -1;
785 }
786
787 master = spi_busnum_to_master(lcdp->panel_info.lcd_spi_bus_num);
788 if (!master) {
789 lcd_fb_wrn("fail to get master\n");
790 goto OUT;
791 }
792
793 lcd->spi_device = spi_alloc_device(master);
794 if (!lcd->spi_device) {
795 lcd_fb_wrn("fail to get spi device\n");
796 goto OUT;
797 }
798 lcdp->spi_device = lcd->spi_device;
799
800 lcd->spi_device->bits_per_word = 8;
801 lcd->spi_device->max_speed_hz =
802 lcdp->panel_info.lcd_data_speed * 1000 * 1000;
803 lcd->spi_device->mode = SPI_MODE_0;
804
805 #if defined(SUPPORT_DBI_IF)
806 memset(&dbi_config, 0, sizeof(dbi_config));
807
808 if (lcdp->panel_info.lcd_if == LCD_FB_IF_DBI) {
809 DBI_WRITE(dbi_config.dbi_mode);
810 DBI_MSB_FIRST(dbi_config.dbi_mode);
811 DBI_TR_COMMAND(dbi_config.dbi_mode);
812 DBI_DCX_COMMAND(dbi_config.dbi_mode);
813
814 dbi_config.dbi_format = 0;
815 dbi_config.dbi_interface = lcdp->panel_info.dbi_if;
816 if (lcdp->panel_info.lcd_pixel_fmt == LCDFB_FORMAT_RGBA_8888 ||
817 lcdp->panel_info.lcd_pixel_fmt == LCDFB_FORMAT_BGRA_8888 ||
818 lcdp->panel_info.lcd_pixel_fmt == LCDFB_FORMAT_RGBX_8888 ||
819 lcdp->panel_info.lcd_pixel_fmt == LCDFB_FORMAT_BGRX_8888) {
820 dbi_config.dbi_rgb32_alpha_pos = 1;
821 } else {
822 dbi_config.dbi_rgb32_alpha_pos = 0;
823 }
824 dbi_config.dbi_fps = lcdp->panel_info.lcd_fps;
825 dbi_config.dbi_video_v = lcdp->panel_info.lcd_x;
826 dbi_config.dbi_video_h = lcdp->panel_info.lines_per_transfer;
827 dbi_config.dbi_src_sequence = lcdp->panel_info.lcd_rgb_order;
828 dbi_config.dbi_te_en = 0;
829 dbi_config.dbi_vsync_handle = disp_lcd_vsync_handle;
830 dbi_config.dbi_clk_out_mode = lcdp->panel_info.lcd_dbi_clk_mode;
831 }
832
833 spi_set_dbi_config(lcd->spi_device, &dbi_config);
834 #endif
835
836 ret = spi_setup(lcd->spi_device);
837 if (ret) {
838 lcd_fb_wrn("Faile to setup spi\n");
839 goto FREE;
840 }
841
842 lcd_fb_wrn("Init spi%d:bits_per_word:%d max_speed_hz:%d mode:%d\n",
843 lcdp->panel_info.lcd_spi_bus_num,
844 lcd->spi_device->bits_per_word,
845 lcd->spi_device->max_speed_hz, lcd->spi_device->mode);
846
847 ret = 0;
848 goto OUT;
849
850 FREE:
851 spi_master_put(master);
852 kfree(lcd->spi_device);
853 lcd->spi_device = NULL;
854 OUT:
855 return ret;
856 }
857
disp_lcd_enable(struct lcd_fb_device * lcd)858 static s32 disp_lcd_enable(struct lcd_fb_device *lcd)
859 {
860 unsigned long flags;
861 struct disp_lcd_private_data *lcdp = disp_lcd_get_priv(lcd);
862 int i;
863 unsigned bl;
864
865 if ((lcd == NULL) || (lcdp == NULL)) {
866 lcd_fb_wrn("NULL hdl!\n");
867 return -1;
868 }
869 lcd_fb_inf("lcd %d\n", lcd->disp);
870
871 if (disp_lcd_is_enabled(lcd) == 1)
872 return 0;
873
874 /* init fix power */
875 for (i = 0; i < LCD_POWER_NUM; i++) {
876 if (lcdp->lcd_cfg.lcd_fix_power_used[i] == 1)
877 lcd_fb_power_enable(lcdp->lcd_cfg.lcd_fix_power[i]);
878 }
879
880 spin_lock_irqsave(&lcd_data_lock, flags);
881 lcdp->enabling = 1;
882 lcdp->bl_need_enabled = 0;
883 spin_unlock_irqrestore(&lcd_data_lock, flags);
884
885 lcdp->panel_extend_info.lcd_gamma_en = lcdp->panel_info.lcd_gamma_en;
886 disp_lcd_gpio_init(lcd);
887
888 lcd_fb_pwm_config(lcdp->pwm_info.dev, lcdp->pwm_info.duty_ns,
889 lcdp->pwm_info.period_ns);
890 lcd_fb_pwm_set_polarity(lcdp->pwm_info.dev, lcdp->pwm_info.polarity);
891
892 if (disp_lcd_spi_init(lcd)) {
893 lcd_fb_wrn("Init spi fail!\n");
894 return -1;
895 }
896
897 lcdp->open_flow.func_num = 0;
898
899 if (lcdp->lcd_panel_fun.cfg_open_flow)
900 lcdp->lcd_panel_fun.cfg_open_flow(lcd->disp);
901 else
902 lcd_fb_wrn("lcd_panel_fun[%d].cfg_open_flow is NULL\n", lcd->disp);
903
904 for (i = 0; i < lcdp->open_flow.func_num; i++) {
905 if (lcdp->open_flow.func[i].func) {
906 lcdp->open_flow.func[i].func(lcd->disp);
907 lcd_fb_inf("open flow:step %d finish, to delay %d\n", i,
908 lcdp->open_flow.func[i].delay);
909 if (lcdp->open_flow.func[i].delay != 0)
910 disp_delay_ms(lcdp->open_flow.func[i].delay);
911 }
912 }
913
914 if (lcdp->panel_info.lcd_fps && !lcdp->panel_info.lcd_dbi_te) {
915 hrtimer_init(&lcdp->timer, CLOCK_MONOTONIC, HRTIMER_MODE_REL);
916 lcdp->timer.function = disp_lcd_timer_handle;
917 hrtimer_start(
918 &lcdp->timer,
919 ktime_set(0, 1000000000 / lcdp->panel_info.lcd_fps),
920 HRTIMER_MODE_REL);
921 }
922
923 spin_lock_irqsave(&lcd_data_lock, flags);
924 lcdp->enabled = 1;
925 lcdp->enabling = 0;
926 spin_unlock_irqrestore(&lcd_data_lock, flags);
927 bl = disp_lcd_get_bright(lcd);
928 disp_lcd_set_bright(lcd, bl);
929
930 return 0;
931 }
932
disp_lcd_disable(struct lcd_fb_device * lcd)933 static s32 disp_lcd_disable(struct lcd_fb_device *lcd)
934 {
935 unsigned long flags;
936 struct disp_lcd_private_data *lcdp = disp_lcd_get_priv(lcd);
937 int i;
938
939 if ((lcd == NULL) || (lcdp == NULL)) {
940 lcd_fb_wrn("NULL hdl!\n");
941 return -1;
942 }
943
944 lcd_fb_inf("lcd %d\n", lcd->disp);
945 if (disp_lcd_is_enabled(lcd) == 0)
946 return 0;
947
948 spin_lock_irqsave(&lcd_data_lock, flags);
949 lcdp->enabled = 0;
950 spin_unlock_irqrestore(&lcd_data_lock, flags);
951
952 if (lcdp->panel_info.lcd_fps && !lcdp->panel_info.lcd_dbi_te)
953 hrtimer_cancel(&lcdp->timer);
954
955 lcdp->bl_need_enabled = 0;
956 lcdp->close_flow.func_num = 0;
957 if (lcdp->lcd_panel_fun.cfg_close_flow)
958 lcdp->lcd_panel_fun.cfg_close_flow(lcd->disp);
959 else
960 lcd_fb_wrn("lcd_panel_fun[%d].cfg_close_flow is NULL\n", lcd->disp);
961
962 for (i = 0; i < lcdp->close_flow.func_num; i++) {
963 if (lcdp->close_flow.func[i].func) {
964 lcdp->close_flow.func[i].func(lcd->disp);
965 lcd_fb_inf("close flow:step %d finish, to delay %d\n", i,
966 lcdp->close_flow.func[i].delay);
967 if (lcdp->close_flow.func[i].delay != 0)
968 disp_delay_ms(lcdp->close_flow.func[i].delay);
969 }
970 }
971
972 disp_lcd_gpio_exit(lcd);
973
974 for (i = LCD_POWER_NUM - 1; i >= 0; i--) {
975 if (lcdp->lcd_cfg.lcd_fix_power_used[i] == 1)
976 lcd_fb_power_disable(lcdp->lcd_cfg.lcd_fix_power[i]);
977 }
978
979 if (lcd->spi_device) {
980 if (lcd->spi_device->master->cleanup)
981 lcd->spi_device->master->cleanup(lcd->spi_device);
982 spi_master_put(lcd->spi_device->master);
983 kfree(lcd->spi_device);
984 lcd->spi_device = NULL;
985 }
986
987 return 0;
988 }
989
disp_lcd_is_enabled(struct lcd_fb_device * lcd)990 s32 disp_lcd_is_enabled(struct lcd_fb_device *lcd)
991 {
992 struct disp_lcd_private_data *lcdp = disp_lcd_get_priv(lcd);
993
994 if ((lcd == NULL) || (lcdp == NULL)) {
995 lcd_fb_wrn("NULL hdl!\n");
996 return -1;
997 }
998
999 return (s32)lcdp->enabled;
1000 }
1001
1002 /**
1003 * disp_lcd_check_if_enabled - check lcd if be enabled status
1004 *
1005 * this function only be used by bsp_disp_sync_with_hw to check
1006 * the device enabled status when driver init
1007 */
disp_lcd_check_if_enabled(struct lcd_fb_device * lcd)1008 s32 disp_lcd_check_if_enabled(struct lcd_fb_device *lcd)
1009 {
1010 struct disp_lcd_private_data *lcdp = disp_lcd_get_priv(lcd);
1011 int ret = 1;
1012
1013 if ((lcd == NULL) || (lcdp == NULL)) {
1014 lcd_fb_wrn("NULL hdl!\n");
1015 return -1;
1016 }
1017
1018 return ret;
1019 }
1020
disp_lcd_set_open_func(struct lcd_fb_device * lcd,LCD_FUNC func,u32 delay)1021 static s32 disp_lcd_set_open_func(struct lcd_fb_device *lcd, LCD_FUNC func,
1022 u32 delay)
1023 {
1024 struct disp_lcd_private_data *lcdp = disp_lcd_get_priv(lcd);
1025
1026 if ((lcd == NULL) || (lcdp == NULL)) {
1027 lcd_fb_wrn("NULL hdl!\n");
1028 return -1;
1029 }
1030
1031 if (func) {
1032 lcdp->open_flow.func[lcdp->open_flow.func_num].func = func;
1033 lcdp->open_flow.func[lcdp->open_flow.func_num].delay = delay;
1034 lcdp->open_flow.func_num++;
1035 }
1036
1037 return 0;
1038 }
1039
disp_lcd_set_close_func(struct lcd_fb_device * lcd,LCD_FUNC func,u32 delay)1040 static s32 disp_lcd_set_close_func(struct lcd_fb_device *lcd, LCD_FUNC func,
1041 u32 delay)
1042 {
1043 struct disp_lcd_private_data *lcdp = disp_lcd_get_priv(lcd);
1044
1045 if ((lcd == NULL) || (lcdp == NULL)) {
1046 lcd_fb_wrn("NULL hdl!\n");
1047 return -1;
1048 }
1049
1050 if (func) {
1051 lcdp->close_flow.func[lcdp->close_flow.func_num].func = func;
1052 lcdp->close_flow.func[lcdp->close_flow.func_num].delay = delay;
1053 lcdp->close_flow.func_num++;
1054 }
1055
1056 return 0;
1057 }
1058
disp_lcd_set_panel_funs(struct lcd_fb_device * lcd,char * name,struct disp_lcd_panel_fun * lcd_cfg)1059 static s32 disp_lcd_set_panel_funs(struct lcd_fb_device *lcd, char *name,
1060 struct disp_lcd_panel_fun *lcd_cfg)
1061 {
1062 char primary_key[20], drv_name[32];
1063 s32 ret;
1064 struct disp_lcd_private_data *lcdp = disp_lcd_get_priv(lcd);
1065
1066 if ((lcd == NULL) || (lcdp == NULL)) {
1067 lcd_fb_wrn("NULL hdl!\n");
1068 return -1;
1069 }
1070
1071 sprintf(primary_key, "lcd_fb%d", lcd->disp);
1072
1073 ret =
1074 lcd_fb_script_get_item(primary_key, "lcd_driver_name",
1075 (int *)drv_name, 2);
1076 lcd_fb_inf("lcd %d, driver_name %s, panel_name %s\n", lcd->disp, drv_name,
1077 name);
1078 if ((ret == 2) && !strcmp(drv_name, name)) {
1079 memset(&lcdp->lcd_panel_fun,
1080 0,
1081 sizeof(struct disp_lcd_panel_fun));
1082 lcdp->lcd_panel_fun.cfg_panel_info = lcd_cfg->cfg_panel_info;
1083 lcdp->lcd_panel_fun.cfg_open_flow = lcd_cfg->cfg_open_flow;
1084 lcdp->lcd_panel_fun.cfg_close_flow = lcd_cfg->cfg_close_flow;
1085 lcdp->lcd_panel_fun.lcd_user_defined_func =
1086 lcd_cfg->lcd_user_defined_func;
1087 lcdp->lcd_panel_fun.set_bright = lcd_cfg->set_bright;
1088 lcdp->lcd_panel_fun.blank = lcd_cfg->blank;
1089 lcdp->lcd_panel_fun.set_var = lcd_cfg->set_var;
1090 lcdp->lcd_panel_fun.set_addr_win = lcd_cfg->set_addr_win;
1091 if (lcdp->lcd_panel_fun.cfg_panel_info) {
1092 lcdp->lcd_panel_fun.cfg_panel_info(&lcdp->panel_extend_info);
1093 memcpy(&lcdp->panel_extend_info_set,
1094 &lcdp->panel_extend_info, sizeof(struct panel_extend_para));
1095 } else {
1096 lcd_fb_wrn("lcd_panel_fun[%d].cfg_panel_info is NULL\n", lcd->disp);
1097 }
1098
1099 return 0;
1100 }
1101
1102 return -1;
1103 }
1104
disp_lcd_gpio_init(struct lcd_fb_device * lcd)1105 s32 disp_lcd_gpio_init(struct lcd_fb_device *lcd)
1106 {
1107 struct disp_lcd_private_data *lcdp = disp_lcd_get_priv(lcd);
1108 int i = 0;
1109 struct disp_gpio_info gpio_info[1];
1110
1111 if ((lcd == NULL) || (lcdp == NULL)) {
1112 lcd_fb_wrn("NULL hdl!\n");
1113 return -1;
1114 }
1115
1116 /* io-pad */
1117 for (i = 0; i < LCD_GPIO_REGU_NUM; i++) {
1118 if (!((!strcmp(lcdp->lcd_cfg.lcd_gpio_power[i], ""))
1119 || (!strcmp(lcdp->lcd_cfg.lcd_gpio_power[i], "none"))))
1120 lcd_fb_power_enable(lcdp->lcd_cfg.lcd_gpio_power[i]);
1121 }
1122
1123 for (i = 0; i < LCD_GPIO_NUM; i++) {
1124 if (lcdp->lcd_cfg.lcd_gpio_used[i]) {
1125 memcpy(gpio_info, &(lcdp->lcd_cfg.lcd_gpio[i]),
1126 sizeof(struct disp_gpio_info));
1127 lcd_fb_gpio_request(gpio_info);
1128 }
1129 }
1130
1131 if (strlen(lcdp->lcd_cfg.lcd_spi_dc_pin.name)) {
1132 memcpy(gpio_info, &(lcdp->lcd_cfg.lcd_spi_dc_pin),
1133 sizeof(struct disp_gpio_info));
1134 lcd_fb_gpio_request(gpio_info);
1135 }
1136
1137 return 0;
1138 }
1139
disp_lcd_gpio_exit(struct lcd_fb_device * lcd)1140 s32 disp_lcd_gpio_exit(struct lcd_fb_device *lcd)
1141 {
1142 struct disp_lcd_private_data *lcdp = disp_lcd_get_priv(lcd);
1143 int i = 0;
1144 struct disp_gpio_info gpio_info[1];
1145
1146 if ((lcd == NULL) || (lcdp == NULL)) {
1147 lcd_fb_wrn("NULL hdl!\n");
1148 return -1;
1149 }
1150
1151 for (i = 0; i < LCD_GPIO_NUM; i++) {
1152 if (lcdp->lcd_cfg.lcd_gpio_used[i]) {
1153
1154 lcd_fb_gpio_release(&lcdp->lcd_cfg.lcd_gpio[i]);
1155
1156 memcpy(gpio_info, &(lcdp->lcd_cfg.lcd_gpio[i]),
1157 sizeof(struct disp_gpio_info));
1158 }
1159 }
1160
1161 /* io-pad */
1162 for (i = LCD_GPIO_REGU_NUM - 1; i >= 0; i--) {
1163 if (!((!strcmp(lcdp->lcd_cfg.lcd_gpio_power[i], ""))
1164 || (!strcmp(lcdp->lcd_cfg.lcd_gpio_power[i], "none"))))
1165 lcd_fb_power_disable(lcdp->lcd_cfg.lcd_gpio_power[i]);
1166 }
1167
1168 if (strlen(lcdp->lcd_cfg.lcd_spi_dc_pin.name))
1169 lcd_fb_gpio_release(&lcdp->lcd_cfg.lcd_spi_dc_pin);
1170
1171 return 0;
1172
1173 }
1174
1175 /* direction: input(0), output(1) */
disp_lcd_gpio_set_direction(struct lcd_fb_device * lcd,u32 io_index,u32 direction)1176 s32 disp_lcd_gpio_set_direction(struct lcd_fb_device *lcd, u32 io_index,
1177 u32 direction)
1178 {
1179 struct disp_lcd_private_data *lcdp = disp_lcd_get_priv(lcd);
1180 char gpio_name[20];
1181
1182 if ((lcd == NULL) || (lcdp == NULL)) {
1183 lcd_fb_wrn("NULL hdl!\n");
1184 return -1;
1185 }
1186
1187 sprintf(gpio_name, "lcd_gpio_%d", io_index);
1188 return lcd_fb_gpio_set_direction(lcdp->lcd_cfg.gpio_hdl[io_index],
1189 direction, gpio_name);
1190 }
1191
disp_lcd_gpio_get_value(struct lcd_fb_device * lcd,u32 io_index)1192 s32 disp_lcd_gpio_get_value(struct lcd_fb_device *lcd, u32 io_index)
1193 {
1194 struct disp_lcd_private_data *lcdp = disp_lcd_get_priv(lcd);
1195 char gpio_name[20];
1196
1197 if ((lcd == NULL) || (lcdp == NULL)) {
1198 lcd_fb_wrn("NULL hdl!\n");
1199 return -1;
1200 }
1201
1202 sprintf(gpio_name, "lcd_gpio_%d", io_index);
1203 return lcd_fb_gpio_get_value(lcdp->lcd_cfg.gpio_hdl[io_index],
1204 gpio_name);
1205 }
1206
disp_lcd_gpio_set_value(struct lcd_fb_device * lcd,u32 io_index,u32 data)1207 s32 disp_lcd_gpio_set_value(struct lcd_fb_device *lcd, u32 io_index, u32 data)
1208 {
1209 int gpio;
1210 struct disp_lcd_private_data *lcdp = disp_lcd_get_priv(lcd);
1211 char gpio_name[20];
1212
1213 if ((lcd == NULL) || (lcdp == NULL)) {
1214 lcd_fb_wrn("NULL hdl!\n");
1215 return DIS_FAIL;
1216 }
1217
1218 if (io_index >= LCD_GPIO_NUM) {
1219 lcd_fb_wrn("gpio num out of range\n");
1220 return DIS_FAIL;
1221 }
1222 sprintf(gpio_name, "lcd_gpio_%d", io_index);
1223 gpio = lcdp->lcd_cfg.lcd_gpio[io_index].gpio;
1224 if (!gpio_is_valid(gpio)) {
1225 lcd_fb_wrn("of_get_named_gpio_flags for %s failed\n", gpio_name);
1226 return DIS_FAIL;
1227 }
1228
1229 __gpio_set_value(gpio, data);
1230
1231 return DIS_SUCCESS;
1232 }
1233
disp_lcd_get_dimensions(struct lcd_fb_device * lcd,u32 * width,u32 * height)1234 static s32 disp_lcd_get_dimensions(struct lcd_fb_device *lcd, u32 *width,
1235 u32 *height)
1236 {
1237 struct disp_lcd_private_data *lcdp = disp_lcd_get_priv(lcd);
1238
1239 if ((lcd == NULL) || (lcdp == NULL)) {
1240 lcd_fb_wrn("NULL hdl!\n");
1241 return -1;
1242 }
1243
1244 if (width)
1245 *width = lcdp->panel_info.lcd_width;
1246
1247 if (height)
1248 *height = lcdp->panel_info.lcd_height;
1249
1250 return 0;
1251 }
1252
1253
disp_lcd_update_gamma_tbl_set(struct lcd_fb_device * lcd)1254 static s32 disp_lcd_update_gamma_tbl_set(struct lcd_fb_device *lcd)
1255 {
1256 struct disp_lcd_private_data *lcdp = disp_lcd_get_priv(lcd);
1257 int i;
1258 unsigned int *gamma, *gamma_set;
1259 unsigned int r, g, b;
1260 s32 color_temperature;
1261 u32 color_inverse;
1262
1263 color_temperature = lcdp->color_temperature;
1264 color_inverse = lcdp->color_inverse;
1265 memcpy(&lcdp->panel_extend_info_set, &lcdp->panel_extend_info,
1266 sizeof(struct panel_extend_para));
1267 gamma = lcdp->panel_extend_info.lcd_gamma_tbl;
1268 gamma_set = lcdp->panel_extend_info_set.lcd_gamma_tbl;
1269 if (color_temperature > 0) {
1270 /* warm color */
1271 for (i = 0; i < 256; i++) {
1272 r = (gamma[i] >> 16) & 0xff;
1273 g = (gamma[i] >> 8) & 0xff;
1274 b = gamma[i] & 0xff;
1275
1276 g = g * (512 - color_temperature) / 512;
1277 b = b * (256 - color_temperature) / 256;
1278 r = r << 16;
1279
1280 g = g << 8;
1281 gamma_set[i] = r | g | b;
1282 }
1283 } else if (color_temperature < 0) {
1284 /* cool color */
1285 for (i = 0; i < 256; i++) {
1286 r = (gamma[i] >> 16) & 0xff;
1287 g = (gamma[i] >> 8) & 0xff;
1288 b = gamma[i] & 0xff;
1289
1290 r = r * (256 + color_temperature) / 256;
1291 g = g * (512 + color_temperature) / 512;
1292
1293 r = r << 16;
1294 g = g << 8;
1295
1296 gamma_set[i] = r | g | b;
1297 }
1298 }
1299 if (color_inverse == 1) {
1300 for (i = 0; i < 256; i++)
1301 gamma_set[i] = 0xffffffff - gamma_set[i];
1302 }
1303 if (color_inverse != 0)
1304 lcdp->panel_extend_info_set.lcd_gamma_en = 1;
1305 if (color_temperature != 0)
1306 lcdp->panel_extend_info_set.lcd_gamma_en = 1;
1307
1308 return 0;
1309 }
1310
1311
disp_lcd_set_gamma_tbl(struct lcd_fb_device * lcd,unsigned int * gamma_table,unsigned int size)1312 static s32 disp_lcd_set_gamma_tbl(struct lcd_fb_device *lcd,
1313 unsigned int *gamma_table, unsigned int size)
1314 {
1315 struct disp_lcd_private_data *lcdp = disp_lcd_get_priv(lcd);
1316 unsigned long flags;
1317
1318 if ((lcd == NULL) || (lcdp == NULL)
1319 || (gamma_table == NULL)) {
1320 lcd_fb_wrn("NULL hdl!\n");
1321 return 0;
1322 }
1323
1324 size = (size > LCD_GAMMA_TABLE_SIZE) ?
1325 LCD_GAMMA_TABLE_SIZE : size;
1326 spin_lock_irqsave(&lcd_data_lock, flags);
1327 memcpy(lcdp->panel_extend_info.lcd_gamma_tbl, gamma_table, size);
1328 disp_lcd_update_gamma_tbl_set(lcd);
1329 lcdp->panel_extend_dirty = 1;
1330 spin_unlock_irqrestore(&lcd_data_lock, flags);
1331
1332 return 0;
1333 }
1334
disp_lcd_enable_gamma(struct lcd_fb_device * lcd)1335 static s32 disp_lcd_enable_gamma(struct lcd_fb_device *lcd)
1336 {
1337 struct disp_lcd_private_data *lcdp = disp_lcd_get_priv(lcd);
1338 unsigned long flags;
1339
1340 if ((lcd == NULL) || (lcdp == NULL)) {
1341 lcd_fb_wrn("NULL hdl!\n");
1342 return 0;
1343 }
1344
1345 spin_lock_irqsave(&lcd_data_lock, flags);
1346 if (lcdp->panel_extend_info.lcd_gamma_en == 0) {
1347 lcdp->panel_extend_info.lcd_gamma_en = 1;
1348 disp_lcd_update_gamma_tbl_set(lcd);
1349 lcdp->panel_extend_dirty = 1;
1350 }
1351 spin_unlock_irqrestore(&lcd_data_lock, flags);
1352
1353 return 0;
1354 }
1355
disp_lcd_disable_gamma(struct lcd_fb_device * lcd)1356 static s32 disp_lcd_disable_gamma(struct lcd_fb_device *lcd)
1357 {
1358 struct disp_lcd_private_data *lcdp = disp_lcd_get_priv(lcd);
1359 int ret = -1;
1360
1361 if ((lcd == NULL) || (lcdp == NULL)) {
1362 lcd_fb_wrn("NULL hdl!\n");
1363 return 0;
1364 }
1365
1366 /*if (lcdp->panel_extend_info.lcd_gamma_en == 1) {*/
1367 /*lcdp->panel_extend_info.lcd_gamma_en = 0;*/
1368 /*} else {*/
1369 /*ret = 0;*/
1370 /*}*/
1371
1372 return ret;
1373 }
1374
disp_lcd_set_color_temperature(struct lcd_fb_device * lcd,s32 color_temperature)1375 static s32 disp_lcd_set_color_temperature(struct lcd_fb_device *lcd,
1376 s32 color_temperature)
1377 {
1378 struct disp_lcd_private_data *lcdp = disp_lcd_get_priv(lcd);
1379 unsigned long flags;
1380
1381 if ((lcd == NULL) || (lcdp == NULL)) {
1382 lcd_fb_wrn("NULL hdl!\n");
1383 return -1;
1384 }
1385
1386 spin_lock_irqsave(&lcd_data_lock, flags);
1387 lcdp->color_temperature = color_temperature;
1388 disp_lcd_update_gamma_tbl_set(lcd);
1389 lcdp->panel_extend_dirty = 1;
1390 spin_unlock_irqrestore(&lcd_data_lock, flags);
1391
1392 return 0;
1393 }
1394
disp_lcd_get_color_temperature(struct lcd_fb_device * lcd)1395 static s32 disp_lcd_get_color_temperature(struct lcd_fb_device *lcd)
1396 {
1397 struct disp_lcd_private_data *lcdp = disp_lcd_get_priv(lcd);
1398 unsigned long flags;
1399 s32 color_temperature = 0;
1400
1401 if ((lcd == NULL) || (lcdp == NULL)) {
1402 lcd_fb_wrn("NULL hdl!\n");
1403 return 0;
1404 }
1405
1406 spin_lock_irqsave(&lcd_data_lock, flags);
1407 color_temperature = lcdp->color_temperature;
1408 spin_unlock_irqrestore(&lcd_data_lock, flags);
1409
1410 return color_temperature;
1411 }
1412
disp_lcd_backlight_update_status(struct backlight_device * bd)1413 static int disp_lcd_backlight_update_status(struct backlight_device *bd)
1414 {
1415 struct lcd_fb_device *lcd = (struct lcd_fb_device *)bd->dev.driver_data;
1416 struct disp_lcd_private_data *lcdp = disp_lcd_get_priv(lcd);
1417
1418 lcd_fb_inf("updating sunxi_backlight, brightness=%d/%d\n",
1419 bd->props.brightness, bd->props.max_brightness);
1420
1421 mutex_lock(&lcdp->backligt_lock);
1422 if (bd->props.power != FB_BLANK_POWERDOWN) {
1423 if (!lcdp->bl_enabled)
1424 disp_lcd_backlight_enable(lcd);
1425 disp_lcd_set_bright(lcd, bd->props.brightness);
1426 } else {
1427 disp_lcd_set_bright(lcd, 0);
1428 if (lcdp->bl_enabled)
1429 disp_lcd_backlight_disable(lcd);
1430 }
1431 mutex_unlock(&lcdp->backligt_lock);
1432
1433 return 0;
1434 }
1435
disp_lcd_backlight_get_brightness(struct backlight_device * bd)1436 static int disp_lcd_backlight_get_brightness(struct backlight_device *bd)
1437 {
1438 struct lcd_fb_device *lcd = (struct lcd_fb_device *)bd->dev.driver_data;
1439 struct disp_lcd_private_data *lcdp = disp_lcd_get_priv(lcd);
1440 int ret = -1;
1441
1442 if (!lcd || !lcdp)
1443 goto OUT;
1444
1445 mutex_lock(&lcdp->backligt_lock);
1446 ret = lcdp->lcd_cfg.backlight_bright;
1447 mutex_unlock(&lcdp->backligt_lock);
1448
1449 OUT:
1450 return ret;
1451 }
1452
1453 static const struct backlight_ops sunxi_backlight_device_ops = {
1454 .update_status = disp_lcd_backlight_update_status,
1455 .get_brightness = disp_lcd_backlight_get_brightness,
1456 };
1457
disp_lcd_backlight_register(struct lcd_fb_device * lcd)1458 static s32 disp_lcd_backlight_register(struct lcd_fb_device *lcd)
1459 {
1460 struct backlight_properties props;
1461 struct disp_lcd_private_data *lcdp = disp_lcd_get_priv(lcd);
1462 char sunxi_bl_name[40] = {0};
1463
1464 if (!lcdp || !lcd->dev) {
1465 lcd_fb_wrn("NULL pointer\n");
1466 return -1;
1467 }
1468
1469 memset(&props, 0, sizeof(props));
1470 props.type = BACKLIGHT_RAW;
1471
1472 /*
1473 * Note: Everything should work even if the backlight device max
1474 * presented to the userspace is arbitrarily chosen.
1475 */
1476 props.max_brightness = 255;
1477 props.brightness = lcdp->lcd_cfg.backlight_bright;
1478
1479 props.power = FB_BLANK_UNBLANK;
1480 snprintf(sunxi_bl_name, 40, "lcd_fb%d", lcd->disp);
1481
1482 lcdp->p_bl_dev = backlight_device_register(
1483 sunxi_bl_name, lcd->dev, lcd, &sunxi_backlight_device_ops, &props);
1484
1485 if (!lcdp->p_bl_dev) {
1486 lcd_fb_wrn("backligt register fail!\n");
1487 return -2;
1488 }
1489
1490 return 0;
1491 }
1492
disp_lcd_backlight_unregister(struct lcd_fb_device * lcd)1493 static void disp_lcd_backlight_unregister(struct lcd_fb_device *lcd)
1494 {
1495 struct disp_lcd_private_data *lcdp = disp_lcd_get_priv(lcd);
1496
1497 if (lcdp->p_bl_dev) {
1498 backlight_device_unregister(lcdp->p_bl_dev);
1499 lcdp->p_bl_dev = NULL;
1500 } else
1501 lcd_fb_wrn("lcd%d:Can not find corresponding backlight device\n", lcd->disp);
1502 }
1503
1504
disp_lcd_init(struct lcd_fb_device * lcd)1505 static s32 disp_lcd_init(struct lcd_fb_device *lcd)
1506 {
1507 struct disp_lcd_private_data *lcdp = disp_lcd_get_priv(lcd);
1508 struct disp_gpio_info gpio_info;
1509 int i;
1510
1511 if ((lcd == NULL) || (lcdp == NULL)) {
1512 lcd_fb_wrn("NULL hdl!\n");
1513 return -1;
1514 }
1515 lcd_fb_inf("lcd %d\n", lcd->disp);
1516 mutex_init(&lcdp->layer_mlock);
1517 mutex_init(&lcdp->backligt_lock);
1518 init_waitqueue_head(&lcdp->wait);
1519
1520 lcd_get_sys_config(lcd->disp, &lcdp->lcd_cfg);
1521 if (disp_lcd_is_used(lcd)) {
1522 lcd_parse_panel_para(lcd->disp, &lcdp->panel_info);
1523 }
1524 disp_lcd_bright_curve_init(lcd);
1525
1526 if (disp_lcd_is_used(lcd)) {
1527 __u64 backlight_bright;
1528 __u64 period_ns, duty_ns;
1529
1530 if (lcdp->panel_info.lcd_pwm_used) {
1531 lcdp->pwm_info.channel = lcdp->panel_info.lcd_pwm_ch;
1532 lcdp->pwm_info.polarity = lcdp->panel_info.lcd_pwm_pol;
1533 lcdp->pwm_info.dev =
1534 lcd_fb_pwm_request(lcdp->panel_info.lcd_pwm_ch);
1535
1536 if (lcdp->panel_info.lcd_pwm_freq != 0) {
1537 period_ns =
1538 1000 * 1000 * 1000 /
1539 lcdp->panel_info.lcd_pwm_freq;
1540 } else {
1541 lcd_fb_wrn("lcd%d.lcd_pwm_freq is ZERO\n",
1542 lcd->disp);
1543 /* default 1khz */
1544 period_ns = 1000 * 1000 * 1000 / 1000;
1545 }
1546
1547 backlight_bright = lcdp->lcd_cfg.backlight_bright;
1548
1549 duty_ns = (backlight_bright * period_ns) / 256;
1550 lcdp->pwm_info.duty_ns = duty_ns;
1551 lcdp->pwm_info.period_ns = period_ns;
1552 disp_lcd_backlight_register(lcd);
1553 }
1554 for (i = 0; i < 256; i++) {
1555 lcdp->panel_extend_info.lcd_gamma_tbl[i] =
1556 (i << 24) | (i << 16) | (i << 8) | (i);
1557 }
1558 for (i = 0; i < LCD_GPIO_NUM; i++) {
1559 if (!lcdp->lcd_cfg.lcd_gpio_used[i])
1560 continue;
1561
1562 memcpy(&gpio_info, &(lcdp->lcd_cfg.lcd_gpio[i]),
1563 sizeof(struct disp_gpio_info));
1564 lcd_fb_gpio_request(&gpio_info);
1565 }
1566 }
1567
1568 return 0;
1569 }
1570
1571
1572
disp_lcd_exit(struct lcd_fb_device * lcd)1573 static s32 disp_lcd_exit(struct lcd_fb_device *lcd)
1574 {
1575 struct disp_lcd_private_data *lcdp = disp_lcd_get_priv(lcd);
1576
1577 if ((lcd == NULL) || (lcdp == NULL)) {
1578 lcd_fb_wrn("NULL hdl!\n");
1579 return -1;
1580 }
1581
1582 if (lcdp->panel_info.lcd_pwm_used) {
1583 disp_lcd_backlight_unregister(lcd);
1584 lcd_fb_pwm_free(lcdp->pwm_info.dev);
1585 }
1586
1587
1588 return 0;
1589 }
1590
disp_lcd_get_resolution(struct lcd_fb_device * dispdev,u32 * xres,u32 * yres)1591 s32 disp_lcd_get_resolution(struct lcd_fb_device *dispdev, u32 *xres,
1592 u32 *yres)
1593 {
1594 struct disp_lcd_private_data *lcdp = disp_lcd_get_priv(dispdev);
1595
1596 if (dispdev == NULL) {
1597 lcd_fb_wrn("NULL hdl!\n");
1598 return -1;
1599 }
1600
1601 if (xres)
1602 *xres = lcdp->panel_info.lcd_x;
1603
1604 if (yres)
1605 *yres = lcdp->panel_info.lcd_y;
1606
1607 return 0;
1608 }
1609
disp_lcd_panel_dma_transfer(struct lcd_fb_device * p_lcd,void * buf,unsigned int len)1610 static int disp_lcd_panel_dma_transfer(struct lcd_fb_device *p_lcd, void *buf,
1611 unsigned int len)
1612 {
1613 struct spi_transfer t;
1614 int ret = 0;
1615 struct spi_device *spi_device;
1616 struct spi_dbi_config dbi_config;
1617 struct disp_lcd_private_data *lcdp = disp_lcd_get_priv(p_lcd);
1618
1619 if (!p_lcd || !p_lcd->spi_device)
1620 return -1;
1621
1622 spi_device = p_lcd->spi_device;
1623 if (spi_device == NULL)
1624 lcd_fb_wrn("\n");
1625
1626 memset(&t, 0, sizeof(struct spi_transfer));
1627
1628 #if defined(SUPPORT_DBI_IF)
1629 memset(&dbi_config, 0, sizeof(dbi_config));
1630 if (lcdp->panel_info.lcd_if == LCD_FB_IF_DBI) {
1631 spi_dbi_config_init(lcdp, &dbi_config);
1632 DBI_WRITE(dbi_config.dbi_mode);
1633 DBI_MSB_FIRST(dbi_config.dbi_mode);
1634 DBI_TR_VIDEO(dbi_config.dbi_mode);
1635 DBI_DCX_DATA(dbi_config.dbi_mode);
1636 dbi_config.dbi_format = lcdp->panel_info.lcd_dbi_fmt;
1637 dbi_config.dbi_te_en = lcdp->panel_info.lcd_dbi_te;
1638 spi_set_dbi_config(p_lcd->spi_device, &dbi_config);
1639 }
1640 #endif
1641
1642 t.tx_buf = (void *)buf;
1643 t.len = len;
1644 t.speed_hz = p_lcd->spi_device->max_speed_hz;
1645
1646 ret = spi_sync_transfer(spi_device, &t, 1);
1647
1648 return ret;
1649 }
1650
_spi_dc_pin_set(struct disp_lcd_private_data * lcdp,u32 data)1651 static s32 _spi_dc_pin_set(struct disp_lcd_private_data *lcdp, u32 data)
1652 {
1653 if (!lcdp)
1654 goto OUT;
1655
1656 if (strlen(lcdp->lcd_cfg.lcd_spi_dc_pin.name))
1657 return lcd_fb_gpio_set_value(lcdp->lcd_cfg.spi_dc_pin_hdl, data,
1658 "lcd_spi_dc_pin");
1659 OUT:
1660 return -1;
1661 }
1662
disp_lcd_wait_for_vsync(struct lcd_fb_device * p_lcd)1663 int disp_lcd_wait_for_vsync(struct lcd_fb_device *p_lcd)
1664 {
1665 unsigned long count;
1666 int ret = -1;
1667 struct disp_lcd_private_data *lcdp = disp_lcd_get_priv(p_lcd);
1668
1669 count = lcdp->wait_count;
1670
1671 if (!lcdp->panel_info.lcd_fps && !lcdp->panel_info.lcd_dbi_te)
1672 goto OUT;
1673
1674 ret = wait_event_interruptible_timeout(
1675 lcdp->wait, count != lcdp->wait_count, msecs_to_jiffies(50));
1676
1677 OUT:
1678 return ret;
1679 }
1680
disp_lcd_set_layer(struct lcd_fb_device * lcd,struct fb_info * p_info)1681 int disp_lcd_set_layer(struct lcd_fb_device *lcd, struct fb_info *p_info)
1682 {
1683 int ret = -1;
1684 unsigned int i = 0, len = 0;
1685 unsigned char *addr = NULL, *end_addr = NULL;
1686 struct disp_lcd_private_data *lcdp = disp_lcd_get_priv(lcd);
1687
1688 mutex_lock(&lcdp->layer_mlock);
1689
1690 len = p_info->fix.line_length;
1691 len *= lcdp->panel_info.lines_per_transfer;
1692
1693 if (p_info) {
1694 addr = (unsigned char *)p_info->screen_base +
1695 p_info->var.yoffset * p_info->fix.line_length;
1696 end_addr = (unsigned char *)addr + p_info->fix.smem_len;
1697 for (i = 0; i < p_info->var.yres &&
1698 addr <= end_addr - p_info->fix.line_length;
1699 i += lcdp->panel_info.lines_per_transfer) {
1700 ret = disp_lcd_panel_dma_transfer(lcd, (void *)addr, len);
1701 addr = (unsigned char *)addr +
1702 p_info->fix.line_length *
1703 lcdp->panel_info.lines_per_transfer;
1704 }
1705 }
1706
1707 mutex_unlock(&lcdp->layer_mlock);
1708 return ret;
1709 }
1710
disp_lcd_set_var(struct lcd_fb_device * lcd,struct fb_info * p_info)1711 int disp_lcd_set_var(struct lcd_fb_device *lcd, struct fb_info *p_info)
1712 {
1713 int ret = -1;
1714 struct disp_lcd_private_data *lcdp = disp_lcd_get_priv(lcd);
1715
1716 mutex_lock(&lcdp->layer_mlock);
1717 if (lcdp->lcd_panel_fun.set_var && p_info)
1718 ret = lcdp->lcd_panel_fun.set_var(lcd->disp, p_info);
1719 mutex_unlock(&lcdp->layer_mlock);
1720 return ret;
1721 }
1722
disp_lcd_blank(struct lcd_fb_device * lcd,unsigned int en)1723 int disp_lcd_blank(struct lcd_fb_device *lcd, unsigned int en)
1724 {
1725 int ret = -1;
1726 struct disp_lcd_private_data *lcdp = disp_lcd_get_priv(lcd);
1727
1728 if (lcdp->lcd_panel_fun.blank)
1729 ret = lcdp->lcd_panel_fun.blank(lcd->disp, en);
1730 return ret;
1731 }
1732
disp_lcd_cmd_read(struct lcd_fb_device * p_lcd,unsigned char cmd,unsigned char * rx_buf,unsigned char len)1733 static int disp_lcd_cmd_read(struct lcd_fb_device *p_lcd, unsigned char cmd,
1734 unsigned char *rx_buf, unsigned char len)
1735 {
1736 struct spi_dbi_config dbi_config;
1737 struct disp_lcd_private_data *lcdp = disp_lcd_get_priv(p_lcd);
1738
1739 if (!p_lcd || !p_lcd->spi_device)
1740 return -1;
1741
1742 #if defined(SUPPORT_DBI_IF)
1743 spi_dbi_config_init(lcdp, &dbi_config);
1744 DBI_READ(dbi_config.dbi_mode);
1745 DBI_MSB_FIRST(dbi_config.dbi_mode);
1746 DBI_TR_COMMAND(dbi_config.dbi_mode);
1747 DBI_DCX_COMMAND(dbi_config.dbi_mode);
1748 dbi_config.dbi_format = 0;//must set rgb111
1749 dbi_config.dbi_read_bytes = len;//read 1 number
1750 spi_set_dbi_config(p_lcd->spi_device, &dbi_config);
1751
1752 #endif
1753
1754 spi_write_then_read(p_lcd->spi_device, &cmd, 1, rx_buf, 1);
1755 return 0;
1756 }
1757
disp_lcd_para_write(struct lcd_fb_device * p_lcd,unsigned char para)1758 static int disp_lcd_para_write(struct lcd_fb_device *p_lcd, unsigned char para)
1759 {
1760 struct spi_transfer t;
1761 struct spi_dbi_config dbi_config;
1762 struct disp_lcd_private_data *lcdp = disp_lcd_get_priv(p_lcd);
1763
1764 if (!p_lcd || !p_lcd->spi_device)
1765 return -1;
1766
1767 memset(&t, 0, sizeof(struct spi_transfer));
1768 #if defined(SUPPORT_DBI_IF)
1769 memset(&dbi_config, 0, sizeof(dbi_config));
1770 if (lcdp->panel_info.lcd_if == LCD_FB_IF_DBI) {
1771 spi_dbi_config_init(lcdp, &dbi_config);
1772 DBI_WRITE(dbi_config.dbi_mode);
1773 DBI_MSB_FIRST(dbi_config.dbi_mode);
1774 DBI_TR_COMMAND(dbi_config.dbi_mode);
1775 dbi_config.dbi_format = 0; // must set rgb111
1776 DBI_DCX_DATA(dbi_config.dbi_mode);
1777 spi_set_dbi_config(p_lcd->spi_device, &dbi_config);
1778 } else
1779 #endif
1780 {
1781 _spi_dc_pin_set(lcdp, 1);
1782 }
1783
1784 t.tx_buf = ¶
1785 t.len = 1;
1786 t.speed_hz = 20000000;
1787
1788 return spi_sync_transfer(p_lcd->spi_device, &t, 1);
1789 }
1790
disp_lcd_cmd_write(struct lcd_fb_device * p_lcd,unsigned char cmd)1791 static int disp_lcd_cmd_write(struct lcd_fb_device *p_lcd, unsigned char cmd)
1792 {
1793 struct spi_transfer t;
1794 struct spi_dbi_config dbi_config;
1795 struct disp_lcd_private_data *lcdp = disp_lcd_get_priv(p_lcd);
1796
1797 if (!p_lcd || !p_lcd->spi_device)
1798 return -1;
1799
1800 #if defined(SUPPORT_DBI_IF)
1801 memset(&dbi_config, 0, sizeof(dbi_config));
1802 if (lcdp->panel_info.lcd_if == LCD_FB_IF_DBI) {
1803 spi_dbi_config_init(lcdp, &dbi_config);
1804 DBI_WRITE(dbi_config.dbi_mode);
1805 DBI_MSB_FIRST(dbi_config.dbi_mode);
1806 DBI_TR_COMMAND(dbi_config.dbi_mode);
1807 DBI_DCX_COMMAND(dbi_config.dbi_mode);
1808 dbi_config.dbi_format = 0; // must set rgb111
1809 spi_set_dbi_config(p_lcd->spi_device, &dbi_config);
1810 } else
1811 #endif
1812 {
1813 _spi_dc_pin_set(lcdp, 0);
1814 }
1815 memset(&t, 0, sizeof(struct spi_transfer));
1816
1817 t.tx_buf = &cmd;
1818 t.len = 1;
1819 t.speed_hz = 20000000;
1820
1821 spi_sync_transfer(p_lcd->spi_device, &t, 1);
1822 /*restore to transfer data*/
1823 if (lcdp->panel_info.lcd_if == LCD_FB_IF_SPI)
1824 _spi_dc_pin_set(lcdp, 1);
1825 return 0;
1826 }
1827
disp_init_lcd(struct dev_lcd_fb_t * p_info)1828 s32 disp_init_lcd(struct dev_lcd_fb_t *p_info)
1829 {
1830 u32 disp = 0;
1831 struct lcd_fb_device *lcd;
1832 struct disp_lcd_private_data *lcdp;
1833 u32 hwdev_index = 0;
1834 u32 num_devices_support_lcd = SUPPORT_MAX_LCD;
1835 char primary_key[20];
1836 int ret = 0, value = 1;
1837
1838 lcd_fb_inf("disp_init_lcd\n");
1839
1840 spin_lock_init(&lcd_data_lock);
1841
1842 lcds =
1843 kmalloc_array(num_devices_support_lcd, sizeof(struct lcd_fb_device),
1844 GFP_KERNEL | __GFP_ZERO);
1845 if (lcds == NULL) {
1846 lcd_fb_wrn("malloc memory(%d bytes) fail!\n",
1847 (unsigned int)sizeof(struct lcd_fb_device) *
1848 num_devices_support_lcd);
1849 goto malloc_err;
1850 }
1851 lcd_private =
1852 (struct disp_lcd_private_data *)
1853 kmalloc(sizeof(struct disp_lcd_private_data)
1854 * num_devices_support_lcd, GFP_KERNEL | __GFP_ZERO);
1855 if (lcd_private == NULL) {
1856 lcd_fb_wrn("malloc memory(%d bytes) fail!\n",
1857 (unsigned int)sizeof(struct disp_lcd_private_data) *
1858 num_devices_support_lcd);
1859 goto malloc_err;
1860 }
1861
1862 disp = 0;
1863 for (hwdev_index = 0; hwdev_index < num_devices_support_lcd; hwdev_index++) {
1864
1865 sprintf(primary_key, "lcd_fb%d", disp);
1866 ret = lcd_fb_script_get_item(primary_key, "lcd_used", &value,
1867 1);
1868 if (ret != 1 || value != 1)
1869 continue;
1870 lcd = &lcds[disp];
1871 lcdp = &lcd_private[disp];
1872 lcd->priv_data = (void *)lcdp;
1873 ++p_info->lcd_fb_num;
1874
1875 sprintf(lcd->name, "lcd%d", disp);
1876 lcd->disp = disp;
1877 lcd->dev = p_info->device;
1878
1879 lcd->get_resolution = disp_lcd_get_resolution;
1880 lcd->enable = disp_lcd_enable;
1881 lcd->fake_enable = disp_lcd_fake_enable;
1882 lcd->disable = disp_lcd_disable;
1883 lcd->is_enabled = disp_lcd_is_enabled;
1884 lcd->set_bright = disp_lcd_set_bright;
1885 lcd->get_bright = disp_lcd_get_bright;
1886 lcd->set_bright_dimming = disp_lcd_set_bright_dimming;
1887 lcd->get_panel_info = disp_lcd_get_panel_info;
1888
1889 lcd->set_panel_func = disp_lcd_set_panel_funs;
1890 lcd->set_open_func = disp_lcd_set_open_func;
1891 lcd->set_close_func = disp_lcd_set_close_func;
1892 lcd->backlight_enable = disp_lcd_backlight_enable;
1893 lcd->backlight_disable = disp_lcd_backlight_disable;
1894 lcd->pwm_enable = disp_lcd_pwm_enable;
1895 lcd->pwm_disable = disp_lcd_pwm_disable;
1896 lcd->power_enable = disp_lcd_power_enable;
1897 lcd->power_disable = disp_lcd_power_disable;
1898 lcd->pin_cfg = disp_lcd_pin_cfg;
1899 lcd->gpio_set_value = disp_lcd_gpio_set_value;
1900 lcd->gpio_set_direction = disp_lcd_gpio_set_direction;
1901 lcd->get_dimensions = disp_lcd_get_dimensions;
1902 lcd->set_gamma_tbl = disp_lcd_set_gamma_tbl;
1903 lcd->enable_gamma = disp_lcd_enable_gamma;
1904 lcd->disable_gamma = disp_lcd_disable_gamma;
1905 lcd->set_color_temperature = disp_lcd_set_color_temperature;
1906 lcd->get_color_temperature = disp_lcd_get_color_temperature;
1907 lcd->set_layer = disp_lcd_set_layer;
1908 lcd->blank = disp_lcd_blank;
1909 lcd->set_var = disp_lcd_set_var;
1910 lcd->para_write = disp_lcd_para_write;
1911 lcd->cmd_write = disp_lcd_cmd_write;
1912 lcd->cmd_read = disp_lcd_cmd_read;
1913 lcd->wait_for_vsync = disp_lcd_wait_for_vsync;
1914
1915
1916 lcd->init = disp_lcd_init;
1917 lcd->exit = disp_lcd_exit;
1918
1919 lcd->init(lcd);
1920 lcd_fb_device_register(lcd);
1921
1922 disp++;
1923 }
1924
1925 return 0;
1926
1927 malloc_err:
1928 kfree(lcds);
1929 kfree(lcd_private);
1930 lcds = NULL;
1931 lcd_private = NULL;
1932
1933 return -1;
1934 }
1935
disp_exit_lcd(void)1936 s32 disp_exit_lcd(void)
1937 {
1938 u32 hwdev_index = 0, disp = 0;
1939 char primary_key[20];
1940 int ret = 0, value = 1;
1941 struct lcd_fb_device *lcd;
1942
1943 if (!lcds)
1944 return 0;
1945
1946 for (hwdev_index = 0; hwdev_index < SUPPORT_MAX_LCD; hwdev_index++) {
1947 sprintf(primary_key, "lcd_fb%d", disp);
1948 ret =
1949 lcd_fb_script_get_item(primary_key, "lcd_used", &value, 1);
1950 if (ret != 1 || value != 1)
1951 continue;
1952
1953 lcd = &lcds[disp];
1954 lcd_fb_device_unregister(lcd);
1955 lcd->exit(lcd);
1956 disp++;
1957 }
1958
1959 kfree(lcds);
1960 kfree(lcd_private);
1961 lcds = NULL;
1962 lcd_private = NULL;
1963 return 0;
1964 }
1965