• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 = &para;
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