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