• 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 "lcd_fb_intf.h"
12 #include "dev_lcd_fb.h"
13 
lcd_fb_malloc(u32 size)14 void *lcd_fb_malloc(u32 size)
15 {
16 	return kmalloc(size, GFP_KERNEL | __GFP_ZERO);
17 }
18 
19 /*
20 *******************************************************************************
21 *                     lcd_fb_register_irq
22 *
23 * Description:
24 *    irq register
25 *
26 * Parameters:
27 *    irqno	    ��input.  irq no
28 *    flags	    ��input.
29 *    Handler	    ��input.  isr handler
30 *    pArg	        ��input.  para
31 *    DataSize	    ��input.  len of para
32 *    prio	        ��input.    priority
33 
34 *
35 * Return value:
36 *
37 *
38 * note:
39 *    typedef s32 (*ISRCallback)( void *pArg)��
40 *
41 *******************************************************************************
42 */
lcd_fb_register_irq(u32 IrqNo,u32 Flags,void * Handler,void * pArg,u32 DataSize,u32 Prio)43 int lcd_fb_register_irq(u32 IrqNo, u32 Flags, void *Handler, void *pArg,
44 			  u32 DataSize, u32 Prio)
45 {
46 	lcd_fb_inf("%s, irqNo=%d, Handler=0x%p, pArg=0x%p\n", __func__, IrqNo,
47 	      Handler, pArg);
48 	return request_irq(IrqNo, (irq_handler_t) Handler, 0x0,
49 			   "dispaly", pArg);
50 }
51 
52 /*
53 *******************************************************************************
54 *                     lcd_fb_unregister_irq
55 *
56 * Description:
57 *    irq unregister
58 *
59 * Parameters:
60 *    irqno	��input.  irq no
61 *    handler	��input.  isr handler
62 *    Argment	��input.    para
63 *
64 * Return value:
65 *    void
66 *
67 * note:
68 *    void
69 *
70 *******************************************************************************
71 */
lcd_fb_unregister_irq(u32 IrqNo,void * Handler,void * pArg)72 void lcd_fb_unregister_irq(u32 IrqNo, void *Handler, void *pArg)
73 {
74 	free_irq(IrqNo, pArg);
75 }
76 
77 /*
78 *******************************************************************************
79 *                     lcd_fb_enable_irq
80 *
81 * Description:
82 *    enable irq
83 *
84 * Parameters:
85 *    irqno ��input.  irq no
86 *
87 * Return value:
88 *    void
89 *
90 * note:
91 *    void
92 *
93 *******************************************************************************
94 */
lcd_fb_enable_irq(u32 IrqNo)95 void lcd_fb_enable_irq(u32 IrqNo)
96 {
97 	/* enable_irq(IrqNo); */
98 }
99 
100 /*
101 *******************************************************************************
102 *                     lcd_fb_disable_irq
103 *
104 * Description:
105 *    disable irq
106 *
107 * Parameters:
108 *     irqno ��input.  irq no
109 *
110 * Return value:
111 *    void
112 *
113 * note:
114 *    void
115 *
116 *******************************************************************************
117 */
lcd_fb_disable_irq(u32 IrqNo)118 void lcd_fb_disable_irq(u32 IrqNo)
119 {
120 	/* disable_irq(IrqNo); */
121 }
122 
123 /* type: 0:invalid, 1: int; 2:str, 3: gpio */
lcd_fb_script_get_item(char * main_name,char * sub_name,int value[],int type)124 int lcd_fb_script_get_item(char *main_name, char *sub_name, int value[],
125 			     int type)
126 {
127 	char compat[32];
128 	u32 len = 0;
129 	struct device_node *node;
130 	int ret = 0;
131 	enum of_gpio_flags flags;
132 
133 	len = sprintf(compat, "allwinner,sunxi-%s", main_name);
134 	if (len > 32)
135 		lcd_fb_wrn("size of mian_name is out of range\n");
136 
137 	node = of_find_compatible_node(NULL, NULL, compat);
138 	if (!node) {
139 		lcd_fb_wrn("of_find_compatible_node %s fail\n", compat);
140 		return ret;
141 	}
142 
143 	if (type == 1) {
144 		if (of_property_read_u32_array(node, sub_name, value, 1))
145 			lcd_fb_inf("of_property_read_u32_array %s.%s fail\n",
146 			      main_name, sub_name);
147 		else
148 			ret = type;
149 	} else if (type == 2) {
150 		const char *str;
151 
152 		if (of_property_read_string(node, sub_name, &str))
153 			lcd_fb_inf("of_property_read_string %s.%s fail\n", main_name,
154 			      sub_name);
155 		else {
156 			ret = type;
157 			memcpy((void *)value, str, strlen(str) + 1);
158 		}
159 	} else if (type == 3) {
160 		int gpio;
161 		struct disp_gpio_info *gpio_info = (struct disp_gpio_info *)value;
162 
163 		/* gpio is invalid by default */
164 		gpio_info->gpio = -1;
165 		gpio_info->name[0] = '\0';
166 
167 		gpio = of_get_named_gpio_flags(node, sub_name, 0, &flags);
168 		if (!gpio_is_valid(gpio))
169 			return -EINVAL;
170 
171 		gpio_info->gpio = gpio;
172 		memcpy(gpio_info->name, sub_name, strlen(sub_name) + 1);
173 		gpio_info->value = (flags == OF_GPIO_ACTIVE_LOW) ? 0 : 1;
174 		lcd_fb_inf("%s.%s gpio=%d, value:%d\n", main_name, sub_name,
175 		      gpio_info->gpio, gpio_info->value);
176 	}
177 
178 	return ret;
179 }
180 
lcd_fb_get_ic_ver(void)181 int lcd_fb_get_ic_ver(void)
182 {
183 	return 0;
184 }
185 
lcd_fb_gpio_request(struct disp_gpio_info * gpio_info)186 int lcd_fb_gpio_request(struct disp_gpio_info *gpio_info)
187 {
188 	int ret = 0;
189 
190 	if (!gpio_info) {
191 		lcd_fb_wrn("%s: gpio_info is null\n", __func__);
192 		return -1;
193 	}
194 
195 	/* As some GPIOs are not essential, here return 0 to avoid error */
196 	if (!strlen(gpio_info->name))
197 		return 0;
198 
199 	if (!gpio_is_valid(gpio_info->gpio)) {
200 		lcd_fb_wrn("%s: gpio (%d) is invalid\n", __func__, gpio_info->gpio);
201 		return -1;
202 	}
203 	ret = gpio_direction_output(gpio_info->gpio, gpio_info->value);
204 	if (ret) {
205 		lcd_fb_wrn("%s failed, gpio_name=%s, gpio=%d, value=%d, ret=%d\n", __func__,
206 		      gpio_info->name, gpio_info->gpio, gpio_info->value, ret);
207 		return -1;
208 	}
209 	lcd_fb_inf("%s, gpio_name=%s, gpio=%d, value=%d, ret=%d\n", __func__,
210 		gpio_info->name, gpio_info->gpio, gpio_info->value, ret);
211 
212 	return ret;
213 }
214 
lcd_fb_gpio_request_simple(struct disp_gpio_info * gpio_list,u32 group_count_max)215 int lcd_fb_gpio_request_simple(struct disp_gpio_info *gpio_list,
216 				 u32 group_count_max)
217 {
218 #if 0
219 	int ret = 0;
220 	struct gpio_config pin_cfg;
221 
222 	if (gpio_list == NULL)
223 		return 0;
224 
225 	pin_cfg.gpio = gpio_list->gpio;
226 	pin_cfg.mul_sel = gpio_list->mul_sel;
227 	pin_cfg.pull = gpio_list->pull;
228 	pin_cfg.drv_level = gpio_list->drv_level;
229 	pin_cfg.data = gpio_list->data;
230 	ret = gpio_request(pin_cfg.gpio, NULL);
231 	if (ret != 0) {
232 		lcd_fb_wrn("%s failed, gpio_name=%s, gpio=%d, ret=%d\n", __func__,
233 		      gpio_list->gpio_name, gpio_list->gpio, ret);
234 		return ret;
235 	}
236 
237 	lcd_fb_inf("%s, gpio_name=%s, gpio=%d, ret=%d\n", __func__,
238 	      gpio_list->gpio_name, gpio_list->gpio, ret);
239 	ret = pin_cfg.gpio;
240 
241 	return ret;
242 #endif
243 	return 0;
244 }
lcd_fb_gpio_release(struct disp_gpio_info * gpio_info)245 int lcd_fb_gpio_release(struct disp_gpio_info *gpio_info)
246 {
247 	if (!gpio_info) {
248 		lcd_fb_wrn("%s: gpio_info is null\n", __func__);
249 		return -1;
250 	}
251 	if (!strlen(gpio_info->name))
252 		return -1;
253 
254 	if (!gpio_is_valid(gpio_info->gpio)) {
255 		lcd_fb_wrn("%s: gpio(%d) is invalid\n", __func__, gpio_info->gpio);
256 		return -1;
257 	}
258 
259 	gpio_free(gpio_info->gpio);
260 	return 0;
261 }
262 
263 /* direction: 0:input, 1:output */
lcd_fb_gpio_set_direction(u32 p_handler,u32 direction,const char * gpio_name)264 int lcd_fb_gpio_set_direction(u32 p_handler, u32 direction,
265 				const char *gpio_name)
266 {
267 	int ret = -1;
268 
269 	if (p_handler) {
270 		if (direction) {
271 			s32 value;
272 
273 			value = __gpio_get_value(p_handler);
274 			ret = gpio_direction_output(p_handler, value);
275 			if (ret != 0)
276 				lcd_fb_wrn("gpio_direction_output fail!\n");
277 		} else {
278 			ret = gpio_direction_input(p_handler);
279 			if (ret != 0)
280 				lcd_fb_wrn("gpio_direction_input fail!\n");
281 		}
282 	} else {
283 		lcd_fb_wrn("OSAL_GPIO_DevSetONEPIN_IO_STATUS, hdl is NULL\n");
284 		ret = -1;
285 	}
286 	return ret;
287 }
288 
lcd_fb_gpio_get_value(u32 p_handler,const char * gpio_name)289 int lcd_fb_gpio_get_value(u32 p_handler, const char *gpio_name)
290 {
291 	if (p_handler)
292 		return __gpio_get_value(p_handler);
293 	lcd_fb_wrn("OSAL_GPIO_DevREAD_ONEPIN_DATA, hdl is NULL\n");
294 
295 	return -1;
296 }
297 
lcd_fb_gpio_set_value(u32 p_handler,u32 value_to_gpio,const char * gpio_name)298 int lcd_fb_gpio_set_value(u32 p_handler, u32 value_to_gpio,
299 			    const char *gpio_name)
300 {
301 	if (p_handler)
302 		__gpio_set_value(p_handler, value_to_gpio);
303 	else
304 		lcd_fb_wrn("OSAL_GPIO_DevWRITE_ONEPIN_DATA, hdl is NULL\n");
305 
306 	return 0;
307 }
308 
lcd_fb_pin_set_state(char * dev_name,char * name)309 int lcd_fb_pin_set_state(char *dev_name, char *name)
310 {
311 	char compat[32];
312 	u32 len = 0;
313 	struct device_node *node;
314 	struct platform_device *pdev;
315 	struct pinctrl *pctl;
316 	struct pinctrl_state *state;
317 	int ret = -1;
318 
319 	len = sprintf(compat, "allwinner,sunxi-%s", dev_name);
320 	if (len > 32)
321 		lcd_fb_wrn("size of mian_name is out of range\n");
322 
323 	node = of_find_compatible_node(NULL, NULL, compat);
324 	if (!node) {
325 		lcd_fb_wrn("of_find_compatible_node %s fail\n", compat);
326 		goto exit;
327 	}
328 
329 	pdev = of_find_device_by_node(node);
330 	if (!node) {
331 		lcd_fb_wrn("of_find_device_by_node for %s fail\n", compat);
332 		goto exit;
333 	}
334 
335 	pctl = pinctrl_get(&pdev->dev);
336 	if (IS_ERR(pctl)) {
337 		/*not every lcd need pin config*/
338 		lcd_fb_inf("pinctrl_get for %s fail\n", compat);
339 		ret = PTR_ERR(pctl);
340 		goto exit;
341 	}
342 
343 	state = pinctrl_lookup_state(pctl, name);
344 	if (IS_ERR(state)) {
345 		lcd_fb_wrn("pinctrl_lookup_state for %s fail\n", compat);
346 		ret = PTR_ERR(state);
347 		goto exit;
348 	}
349 
350 	ret = pinctrl_select_state(pctl, state);
351 	if (ret < 0) {
352 		lcd_fb_wrn("pinctrl_select_state(%s) for %s fail\n", name, compat);
353 		goto exit;
354 	}
355 	ret = 0;
356 exit:
357 	return ret;
358 }
359 
lcd_fb_power_enable(char * name)360 int lcd_fb_power_enable(char *name)
361 {
362 	int ret = 0;
363 #if defined(CONFIG_AW_AXP) || defined(CONFIG_REGULATOR)
364 	struct regulator *regu = NULL;
365 
366 #ifdef CONFIG_SUNXI_REGULATOR_DT
367 	regu = regulator_get(g_drv_info.device, name);
368 #else
369 	regu = regulator_get(NULL, name);
370 #endif
371 	if (IS_ERR(regu)) {
372 		lcd_fb_wrn("some error happen, fail to get regulator %s\n", name);
373 		goto exit;
374 	}
375 
376 	/* enalbe regulator */
377 	ret = regulator_enable(regu);
378 	if (ret != 0) {
379 		lcd_fb_wrn("some error happen, fail to enable regulator %s!\n", name);
380 		goto exit1;
381 	} else {
382 		lcd_fb_inf("suceess to enable regulator %s!\n", name);
383 	}
384 
385 exit1:
386 	/* put regulater, when module exit */
387 	regulator_put(regu);
388 exit:
389 #endif
390 	return ret;
391 }
392 
lcd_fb_power_disable(char * name)393 int lcd_fb_power_disable(char *name)
394 {
395 	int ret = 0;
396 #if defined(CONFIG_AW_AXP) || defined(CONFIG_REGULATOR)
397 	struct regulator *regu = NULL;
398 
399 #ifdef CONFIG_SUNXI_REGULATOR_DT
400 	regu = regulator_get(g_drv_info.device, name);
401 #else
402 	regu = regulator_get(NULL, name);
403 #endif
404 	if (IS_ERR(regu)) {
405 		lcd_fb_wrn("some error happen, fail to get regulator %s\n", name);
406 		goto exit;
407 	}
408 	/* disalbe regulator */
409 	ret = regulator_disable(regu);
410 	if (ret != 0) {
411 		lcd_fb_wrn("some error happen, fail to disable regulator %s!\n", name);
412 		goto exit1;
413 	} else {
414 		lcd_fb_inf("suceess to disable regulator %s!\n", name);
415 	}
416 
417 exit1:
418 	/* put regulater, when module exit */
419 	regulator_put(regu);
420 exit:
421 #endif
422 	return ret;
423 }
424 
disp_delay_ms(u32 ms)425 s32 disp_delay_ms(u32 ms)
426 {
427 	u32 timeout = msecs_to_jiffies(ms);
428 
429 	set_current_state(TASK_UNINTERRUPTIBLE);
430 	schedule_timeout(timeout);
431 	return 0;
432 }
433 
disp_delay_us(u32 us)434 s32 disp_delay_us(u32 us)
435 {
436 	udelay(us);
437 
438 	return 0;
439 }
440 
441 #if defined(CONFIG_PWM_SUNXI) || defined(CONFIG_PWM_SUNXI_NEW) ||              \
442 	defined(CONFIG_PWM_SUNXI_GROUP)
lcd_fb_pwm_request(u32 pwm_id)443 uintptr_t lcd_fb_pwm_request(u32 pwm_id)
444 {
445 	uintptr_t ret = 0;
446 
447 	struct pwm_device *pwm_dev;
448 
449 	pwm_dev = pwm_request(pwm_id, "lcd");
450 
451 	if ((pwm_dev == NULL) || IS_ERR(pwm_dev))
452 		lcd_fb_wrn("lcd_fb_pwm_request pwm %d fail!\n", pwm_id);
453 	else
454 		lcd_fb_inf("lcd_fb_pwm_request pwm %d success!\n", pwm_id);
455 	ret = (uintptr_t) pwm_dev;
456 
457 	return ret;
458 }
459 
lcd_fb_pwm_free(uintptr_t p_handler)460 int lcd_fb_pwm_free(uintptr_t p_handler)
461 {
462 	int ret = 0;
463 	struct pwm_device *pwm_dev;
464 
465 	pwm_dev = (struct pwm_device *)p_handler;
466 	if ((pwm_dev == NULL) || IS_ERR(pwm_dev)) {
467 		lcd_fb_wrn("lcd_fb_pwm_free, handle is NULL!\n");
468 		ret = -1;
469 	} else {
470 		pwm_free(pwm_dev);
471 		lcd_fb_inf("lcd_fb_pwm_free pwm %d\n", pwm_dev->pwm);
472 	}
473 
474 	return ret;
475 }
476 
lcd_fb_pwm_enable(uintptr_t p_handler)477 int lcd_fb_pwm_enable(uintptr_t p_handler)
478 {
479 	int ret = 0;
480 	struct pwm_device *pwm_dev;
481 
482 	pwm_dev = (struct pwm_device *)p_handler;
483 	if ((pwm_dev == NULL) || IS_ERR(pwm_dev)) {
484 		lcd_fb_wrn("lcd_fb_pwm_Enable, handle is NULL!\n");
485 		ret = -1;
486 	} else {
487 		ret = pwm_enable(pwm_dev);
488 		lcd_fb_inf("lcd_fb_pwm_Enable pwm %d\n", pwm_dev->pwm);
489 	}
490 
491 	return ret;
492 }
493 
lcd_fb_pwm_disable(uintptr_t p_handler)494 int lcd_fb_pwm_disable(uintptr_t p_handler)
495 {
496 	int ret = 0;
497 	struct pwm_device *pwm_dev;
498 
499 	pwm_dev = (struct pwm_device *)p_handler;
500 	if ((pwm_dev == NULL) || IS_ERR(pwm_dev)) {
501 		lcd_fb_wrn("lcd_fb_pwm_Disable, handle is NULL!\n");
502 		ret = -1;
503 	} else {
504 		pwm_disable(pwm_dev);
505 		lcd_fb_inf("lcd_fb_pwm_Disable pwm %d\n", pwm_dev->pwm);
506 	}
507 
508 	return ret;
509 }
510 
lcd_fb_pwm_config(uintptr_t p_handler,int duty_ns,int period_ns)511 int lcd_fb_pwm_config(uintptr_t p_handler, int duty_ns, int period_ns)
512 {
513 	int ret = 0;
514 	struct pwm_device *pwm_dev;
515 
516 	pwm_dev = (struct pwm_device *)p_handler;
517 	if ((pwm_dev == NULL) || IS_ERR(pwm_dev)) {
518 		lcd_fb_wrn("lcd_fb_pwm_Config, handle is NULL!\n");
519 		ret = -1;
520 	} else {
521 		ret = pwm_config(pwm_dev, duty_ns, period_ns);
522 		lcd_fb_dbg("lcd_fb_pwm_Config pwm %d, <%d / %d>\n",
523 			pwm_dev->pwm, duty_ns, period_ns);
524 	}
525 
526 	return ret;
527 }
528 
lcd_fb_pwm_set_polarity(uintptr_t p_handler,int polarity)529 int lcd_fb_pwm_set_polarity(uintptr_t p_handler, int polarity)
530 {
531 	int ret = 0;
532 	struct pwm_state state;
533 	struct pwm_device *pwm_dev;
534 
535 	pwm_dev = (struct pwm_device *)p_handler;
536 	if ((pwm_dev == NULL) || IS_ERR(pwm_dev)) {
537 		lcd_fb_wrn("disp_sys_pwm_Set_Polarity, handle is NULL!\n");
538 		ret = -1;
539 	} else {
540 		memset(&state, 0, sizeof(struct pwm_state));
541 		pwm_get_state(pwm_dev, &state);
542 		state.polarity = polarity;
543 		ret = pwm_apply_state(pwm_dev, &state);
544 		lcd_fb_wrn("disp_sys_pwm_Set_Polarity pwm %d, active %s\n",
545 		      pwm_dev->pwm, (polarity == 0) ? "high" : "low");
546 	}
547 
548 	return ret;
549 }
550 #else
lcd_fb_pwm_request(u32 pwm_id)551 uintptr_t lcd_fb_pwm_request(u32 pwm_id)
552 {
553 	uintptr_t ret = 0;
554 
555 	return ret;
556 }
557 
lcd_fb_pwm_free(uintptr_t p_handler)558 int lcd_fb_pwm_free(uintptr_t p_handler)
559 {
560 	int ret = 0;
561 
562 	return ret;
563 }
564 
lcd_fb_pwm_enable(uintptr_t p_handler)565 int lcd_fb_pwm_enable(uintptr_t p_handler)
566 {
567 	int ret = 0;
568 
569 	return ret;
570 }
571 
lcd_fb_pwm_disable(uintptr_t p_handler)572 int lcd_fb_pwm_disable(uintptr_t p_handler)
573 {
574 	int ret = 0;
575 
576 	return ret;
577 }
578 
lcd_fb_pwm_config(uintptr_t p_handler,int duty_ns,int period_ns)579 int lcd_fb_pwm_config(uintptr_t p_handler, int duty_ns, int period_ns)
580 {
581 	int ret = 0;
582 
583 	return ret;
584 }
585 
lcd_fb_pwm_set_polarity(uintptr_t p_handler,int polarity)586 int lcd_fb_pwm_set_polarity(uintptr_t p_handler, int polarity)
587 {
588 	int ret = 0;
589 
590 	return ret;
591 }
592 
593 #endif
594