1 // SPDX-License-Identifier: GPL-2.0-only
2 /*
3 * drivers/leds/leds-sunxi.c - Allwinner RGB LED Driver
4 *
5 * Copyright (C) 2018 Allwinner Technology Limited. All rights reserved.
6 * http://www.allwinnertech.com
7 *
8 *Author : Albert Yu <yuxyun@allwinnertech.com>
9 * Lewis <liuyu@allwinnertech.com>
10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of the GNU General Public License version 2 as
12 * published by the Free Software Foundation.
13 *
14 */
15
16 #include <linux/module.h>
17 #include <linux/delay.h>
18 #include <linux/leds.h>
19 #include <linux/io.h>
20 #include <linux/of.h>
21 #include <linux/slab.h>
22 #include <linux/clk.h>
23 #include <linux/dmaengine.h>
24 #include <linux/interrupt.h>
25 #include <linux/platform_device.h>
26 #include <linux/pinctrl/consumer.h>
27 #include <linux/dma-mapping.h>
28 #include <linux/debugfs.h>
29 #include <linux/uaccess.h>
30 #include <linux/delay.h>
31 #include <linux/regulator/consumer.h>
32 #include <linux/reset.h>
33
34 #if IS_ENABLED(CONFIG_PM)
35 #include <linux/pm.h>
36 #endif
37 #include "ledc-sunxi.h"
38
39 /* For debug */
40 #define LED_ERR(fmt, arg...) pr_err("%s()%d - "fmt, __func__, __LINE__, ##arg)
41
42 #define dprintk(level_mask, fmt, arg...) \
43 do { \
44 if (unlikely(debug_mask & level_mask)) \
45 pr_warn("%s()%d - "fmt, __func__, __LINE__, ##arg); \
46 } while (0)
47
48 static u32 debug_mask = 1;
49 struct sunxi_led *sunxi_led_global;
50 static struct class *led_class;
51
52 #define sunxi_slave_id(d, s) (((d)<<16) | (s))
53
54 /*For Driver */
led_dump_reg(struct sunxi_led * led,u32 offset,u32 len)55 void led_dump_reg(struct sunxi_led *led, u32 offset, u32 len)
56 {
57 u32 i;
58 u8 buf[64], cnt = 0;
59
60 for (i = 0; i < len; i = i + REG_INTERVAL) {
61 if (i%HEXADECIMAL == 0)
62 cnt += sprintf(buf + cnt, "0x%08x: ",
63 (u32)(led->res->start + offset + i));
64
65 cnt += sprintf(buf + cnt, "%08x ",
66 readl(led->iomem_reg_base + offset + i));
67
68 if (i%HEXADECIMAL == REG_CL) {
69 pr_warn("%s\n", buf);
70 cnt = 0;
71 }
72 }
73 }
74
sunxi_clk_get(struct sunxi_led * led)75 static void sunxi_clk_get(struct sunxi_led *led)
76 {
77 struct device *dev = led->dev;
78 struct device_node *np = dev->of_node;
79
80 led->clk_ledc = of_clk_get(np, 0);
81 if (IS_ERR(led->clk_ledc))
82 LED_ERR("failed to get clk_ledc!\n");
83
84 led->clk_cpuapb = of_clk_get(np, 1);
85 if (IS_ERR(led->clk_cpuapb))
86 LED_ERR("failed to get clk_cpuapb!\n");
87 }
88
sunxi_clk_put(struct sunxi_led * led)89 static void sunxi_clk_put(struct sunxi_led *led)
90 {
91 clk_put(led->clk_ledc);
92 clk_put(led->clk_cpuapb);
93 led->clk_ledc = NULL;
94 led->clk_cpuapb = NULL;
95 }
96
sunxi_clk_enable(struct sunxi_led * led)97 static void sunxi_clk_enable(struct sunxi_led *led)
98 {
99 clk_prepare_enable(led->clk_ledc);
100 clk_prepare_enable(led->clk_cpuapb);
101 }
102
sunxi_clk_disable(struct sunxi_led * led)103 static void sunxi_clk_disable(struct sunxi_led *led)
104 {
105 clk_disable_unprepare(led->clk_ledc);
106 }
107
sunxi_clk_init(struct sunxi_led * led)108 static void sunxi_clk_init(struct sunxi_led *led)
109 {
110 sunxi_clk_get(led);
111 sunxi_clk_enable(led);
112 }
113
sunxi_clk_deinit(struct sunxi_led * led)114 static void sunxi_clk_deinit(struct sunxi_led *led)
115 {
116 sunxi_clk_disable(led);
117 sunxi_clk_put(led);
118 }
119
sunxi_get_reg(int offset)120 static u32 sunxi_get_reg(int offset)
121 {
122 struct sunxi_led *led = sunxi_led_global;
123 u32 value = ioread32(((u8 *)led->iomem_reg_base) + offset);
124
125 return value;
126 }
127
sunxi_set_reg(int offset,u32 value)128 static void sunxi_set_reg(int offset, u32 value)
129 {
130 struct sunxi_led *led = sunxi_led_global;
131
132 iowrite32(value, ((u8 *)led->iomem_reg_base) + offset);
133 }
134
sunxi_set_reset_ns(struct sunxi_led * led)135 static inline void sunxi_set_reset_ns(struct sunxi_led *led)
136 {
137 u32 n, reg_val;
138 u32 mask = 0x1FFF;
139 u32 min = SUNXI_RESET_TIME_MIN_NS;
140 u32 max = SUNXI_RESET_TIME_MAX_NS;
141
142 if (led->reset_ns < min || led->reset_ns > max) {
143 LED_ERR("invalid parameter, reset_ns should be %u-%u!\n",
144 min, max);
145 return;
146 }
147
148 n = (led->reset_ns - 42) / 42;
149 reg_val = sunxi_get_reg(LED_RESET_TIMING_CTRL_REG_OFFSET);
150 reg_val &= ~(mask << 16);
151 reg_val |= (n << 16);
152 sunxi_set_reg(LED_RESET_TIMING_CTRL_REG_OFFSET, reg_val);
153 }
154
sunxi_set_t1h_ns(struct sunxi_led * led)155 static inline void sunxi_set_t1h_ns(struct sunxi_led *led)
156 {
157 u32 n, reg_val;
158 u32 mask = 0x3F;
159 u32 shift = 21;
160 u32 min = SUNXI_T1H_MIN_NS;
161 u32 max = SUNXI_T1H_MAX_NS;
162
163 if (led->t1h_ns < min || led->t1h_ns > max) {
164 LED_ERR("invalid parameter, t1h_ns should be %u-%u!\n",
165 min, max);
166 return;
167 }
168
169 n = (led->t1h_ns - 42) / 42;
170 reg_val = sunxi_get_reg(LED_T01_TIMING_CTRL_REG_OFFSET);
171 reg_val &= ~(mask << shift);
172 reg_val |= n << shift;
173 sunxi_set_reg(LED_T01_TIMING_CTRL_REG_OFFSET, reg_val);
174 }
175
sunxi_set_t1l_ns(struct sunxi_led * led)176 static inline void sunxi_set_t1l_ns(struct sunxi_led *led)
177 {
178 u32 n, reg_val;
179 u32 mask = 0x1F;
180 u32 shift = 16;
181 u32 min = SUNXI_T1L_MIN_NS;
182 u32 max = SUNXI_T1L_MAX_NS;
183
184 if (led->t1l_ns < min || led->t1l_ns > max) {
185 LED_ERR("invalid parameter, t1l_ns should be %u-%u!\n",
186 min, max);
187 return;
188 }
189
190 n = (led->t1l_ns - 42) / 42;
191 reg_val = sunxi_get_reg(LED_T01_TIMING_CTRL_REG_OFFSET);
192 reg_val &= ~(mask << shift);
193 reg_val |= n << shift;
194 sunxi_set_reg(LED_T01_TIMING_CTRL_REG_OFFSET, reg_val);
195 }
196
sunxi_set_t0h_ns(struct sunxi_led * led)197 static inline void sunxi_set_t0h_ns(struct sunxi_led *led)
198 {
199 u32 n, reg_val;
200 u32 mask = 0x1F;
201 u32 shift = 6;
202 u32 min = SUNXI_T0H_MIN_NS;
203 u32 max = SUNXI_T0H_MAX_NS;
204
205 if (led->t0h_ns < min || led->t0h_ns > max) {
206 LED_ERR("invalid parameter, t0h_ns should be %u-%u!\n",
207 min, max);
208 return;
209 }
210
211 n = (led->t0h_ns - 42) / 42;
212 reg_val = sunxi_get_reg(LED_T01_TIMING_CTRL_REG_OFFSET);
213 reg_val &= ~(mask << shift);
214 reg_val |= n << shift;
215 sunxi_set_reg(LED_T01_TIMING_CTRL_REG_OFFSET, reg_val);
216 }
217
sunxi_set_t0l_ns(struct sunxi_led * led)218 static inline void sunxi_set_t0l_ns(struct sunxi_led *led)
219 {
220 u32 n, reg_val;
221 u32 min = SUNXI_T0L_MIN_NS;
222 u32 max = SUNXI_T0L_MAX_NS;
223
224 if (led->t0l_ns < min || led->t0l_ns > max) {
225 LED_ERR("invalid parameter, t0l_ns should be %u-%u!\n",
226 min, max);
227 return;
228 }
229
230 n = (led->t0l_ns - 42) / 42;
231 reg_val = sunxi_get_reg(LED_T01_TIMING_CTRL_REG_OFFSET);
232 reg_val &= ~0x3F;
233 reg_val |= n;
234 sunxi_set_reg(LED_T01_TIMING_CTRL_REG_OFFSET, reg_val);
235 }
236
sunxi_set_wait_time0_ns(struct sunxi_led * led)237 static inline void sunxi_set_wait_time0_ns(struct sunxi_led *led)
238 {
239 u32 n, reg_val;
240 u32 min = SUNXI_WAIT_TIME0_MIN_NS;
241 u32 max = SUNXI_WAIT_TIME0_MAX_NS;
242
243 if (led->wait_time0_ns < min || led->wait_time0_ns > max) {
244 LED_ERR("invalid parameter, wait_time0_ns should be %u-%u!\n",
245 min, max);
246 return;
247 }
248
249 n = (led->wait_time0_ns - 42) / 42;
250 reg_val = (1 << 8) | n;
251 sunxi_set_reg(LEDC_WAIT_TIME0_CTRL_REG, reg_val);
252 }
253
sunxi_set_wait_time1_ns(struct sunxi_led * led)254 static inline void sunxi_set_wait_time1_ns(struct sunxi_led *led)
255 {
256 unsigned long long tmp, max = SUNXI_WAIT_TIME1_MAX_NS;
257 u32 min = SUNXI_WAIT_TIME1_MIN_NS;
258 u32 n, reg_val;
259
260 if (led->wait_time1_ns < min || led->wait_time1_ns > max) {
261 LED_ERR("invalid parameter, wait_time1_ns should be %u-%llu!\n",
262 min, max);
263 return;
264 }
265
266 tmp = led->wait_time1_ns;
267 n = div_u64(tmp, 42);
268 n -= 1;
269 reg_val = (1 << 31) | n;
270 sunxi_set_reg(LEDC_WAIT_TIME1_CTRL_REG, reg_val);
271 }
272
sunxi_set_wait_data_time_ns(struct sunxi_led * led)273 static inline void sunxi_set_wait_data_time_ns(struct sunxi_led *led)
274 {
275 u32 min, max;
276 #ifndef SUNXI_FPGA_LEDC
277 u32 mask = 0x1FFF, shift = 16, reg_val = 0, n;
278 #endif
279 min = SUNXI_WAIT_DATA_TIME_MIN_NS;
280 #ifdef SUNXI_FPGA_LEDC
281 /*
282 * For FPGA platforms, it is easy to meet wait data timeout for
283 * the obvious latency of task which is because of less cpu cores
284 * and lower cpu frequency compared with IC platforms, so here we
285 * permit long enough time latency.
286 */
287 max = SUNXI_WAIT_DATA_TIME_MAX_NS_FPGA;
288 #else /* SUNXI_FPGA_LEDC */
289 max = SUNXI_WAIT_DATA_TIME_MAX_NS_IC;
290 #endif /* SUNXI_FPGA_LEDC */
291
292 if (led->wait_data_time_ns < min || led->wait_data_time_ns > max) {
293 LED_ERR("invalid parameter, wait_data_time_ns should be %u-%u!\n",
294 min, max);
295 return;
296 }
297
298 #ifndef SUNXI_FPGA_LEDC
299 n = (led->wait_data_time_ns - 42) / 42;
300 reg_val &= ~(mask << shift);
301 reg_val |= (n << shift);
302 sunxi_set_reg(LEDC_DATA_FINISH_CNT_REG_OFFSET, reg_val);
303 #endif /* SUNXI_FPGA_LEDC */
304 }
305
sunxi_ledc_set_time(struct sunxi_led * led)306 static void sunxi_ledc_set_time(struct sunxi_led *led)
307 {
308 sunxi_set_reset_ns(led);
309 sunxi_set_t1h_ns(led);
310 sunxi_set_t1l_ns(led);
311 sunxi_set_t0h_ns(led);
312 sunxi_set_t0l_ns(led);
313 sunxi_set_wait_time0_ns(led);
314 sunxi_set_wait_time1_ns(led);
315 sunxi_set_wait_data_time_ns(led);
316 }
317
sunxi_ledc_set_length(struct sunxi_led * led)318 static void sunxi_ledc_set_length(struct sunxi_led *led)
319 {
320 u32 reg_val;
321 u32 length = led->length;
322
323 if (length == 0)
324 return;
325
326 if (length > led->led_count)
327 return;
328
329 reg_val = sunxi_get_reg(LEDC_CTRL_REG_OFFSET);
330 reg_val &= ~(0x1FFF << 16);
331 reg_val |= length << 16;
332 sunxi_set_reg(LEDC_CTRL_REG_OFFSET, reg_val);
333
334 reg_val = sunxi_get_reg(LED_RESET_TIMING_CTRL_REG_OFFSET);
335 reg_val &= ~0x3FF;
336 reg_val |= length - 1;
337 sunxi_set_reg(LED_RESET_TIMING_CTRL_REG_OFFSET, reg_val);
338 }
339
sunxi_ledc_set_output_mode(struct sunxi_led * led,const char * str)340 static void sunxi_ledc_set_output_mode(struct sunxi_led *led, const char *str)
341 {
342 u32 val;
343 u32 mask = 0x7;
344 u32 shift = 6;
345 u32 reg_val = sunxi_get_reg(LEDC_CTRL_REG_OFFSET);
346
347 if (str != NULL) {
348 if (!strncmp(str, "GRB", 3))
349 val = SUNXI_OUTPUT_GRB;
350 else if (!strncmp(str, "GBR", 3))
351 val = SUNXI_OUTPUT_GBR;
352 else if (!strncmp(str, "RGB", 3))
353 val = SUNXI_OUTPUT_RGB;
354 else if (!strncmp(str, "RBG", 3))
355 val = SUNXI_OUTPUT_RBG;
356 else if (!strncmp(str, "BGR", 3))
357 val = SUNXI_OUTPUT_BGR;
358 else if (!strncmp(str, "BRG", 3))
359 val = SUNXI_OUTPUT_BRG;
360 else
361 return;
362 } else {
363 val = led->output_mode.val;
364 }
365
366 reg_val &= ~(mask << shift);
367 reg_val |= val;
368
369 sunxi_set_reg(LEDC_CTRL_REG_OFFSET, reg_val);
370
371 if (strncmp(str, led->output_mode.str, 3))
372 memcpy(led->output_mode.str, str, 3);
373
374 if (val != led->output_mode.val)
375 led->output_mode.val = val;
376 }
377
sunxi_ledc_enable_irq(u32 mask)378 static void sunxi_ledc_enable_irq(u32 mask)
379 {
380 u32 reg_val = 0;
381
382 reg_val |= mask;
383 sunxi_set_reg(LEDC_INT_CTRL_REG_OFFSET, reg_val);
384 }
385
sunxi_ledc_disable_irq(u32 mask)386 static void sunxi_ledc_disable_irq(u32 mask)
387 {
388 u32 reg_val = 0;
389
390 reg_val = sunxi_get_reg(LEDC_INT_CTRL_REG_OFFSET);
391 reg_val &= ~mask;
392 sunxi_set_reg(LEDC_INT_CTRL_REG_OFFSET, reg_val);
393 }
394
sunxi_ledc_enable(struct sunxi_led * led)395 static inline void sunxi_ledc_enable(struct sunxi_led *led)
396 {
397 u32 reg_val;
398
399 reg_val = sunxi_get_reg(LEDC_CTRL_REG_OFFSET);
400 reg_val |= 1;
401 sunxi_set_reg(LEDC_CTRL_REG_OFFSET, reg_val);
402 }
403
sunxi_ledc_reset(struct sunxi_led * led)404 static inline void sunxi_ledc_reset(struct sunxi_led *led)
405 {
406 u32 reg_val = sunxi_get_reg(LEDC_CTRL_REG_OFFSET);
407
408 sunxi_ledc_disable_irq(LEDC_TRANS_FINISH_INT_EN | LEDC_FIFO_CPUREQ_INT_EN
409 | LEDC_WAITDATA_TIMEOUT_INT_EN | LEDC_FIFO_OVERFLOW_INT_EN
410 | LEDC_GLOBAL_INT_EN);
411
412 if (debug_mask & DEBUG_INFO2) {
413 dprintk(DEBUG_INFO2, "dump reg:\n");
414 led_dump_reg(led, 0, 0x30);
415 }
416
417 reg_val |= 1 << 1;
418 sunxi_set_reg(LEDC_CTRL_REG_OFFSET, reg_val);
419 }
420
421 #ifdef CONFIG_DEBUG_FS
reset_ns_write(struct file * filp,const char __user * buf,size_t count,loff_t * offp)422 static ssize_t reset_ns_write(struct file *filp, const char __user *buf,
423 size_t count, loff_t *offp)
424 {
425 int err;
426 char buffer[64];
427 u32 min, max;
428 unsigned long val;
429 struct sunxi_led *led = sunxi_led_global;
430
431 min = SUNXI_RESET_TIME_MIN_NS;
432 max = SUNXI_RESET_TIME_MAX_NS;
433
434 if (count >= sizeof(buffer))
435 goto err_out;
436
437 if (copy_from_user(buffer, buf, count))
438 goto err_out;
439
440 buffer[count] = '\0';
441
442 err = kstrtoul(buffer, 10, &val);
443 if (err)
444 goto err_out;
445
446 if (val < min || val > max)
447 goto err_out;
448
449 led->reset_ns = val;
450 sunxi_set_reset_ns(led);
451
452 *offp += count;
453
454 return count;
455
456 err_out:
457 LED_ERR("invalid parameter, reset_ns should be %u-%u!\n",
458 min, max);
459
460 return -EINVAL;
461 }
462
reset_ns_read(struct file * filp,char __user * buf,size_t count,loff_t * offp)463 static ssize_t reset_ns_read(struct file *filp, char __user *buf,
464 size_t count, loff_t *offp)
465 {
466 int r;
467 char buffer[64];
468 struct sunxi_led *led = sunxi_led_global;
469
470 r = snprintf(buffer, 64, "%u\n", led->reset_ns);
471
472 return simple_read_from_buffer(buf, count, offp, buffer, r);
473 }
474
475 static const struct file_operations reset_ns_fops = {
476 .owner = THIS_MODULE,
477 .write = reset_ns_write,
478 .read = reset_ns_read,
479 };
480
t1h_ns_write(struct file * filp,const char __user * buf,size_t count,loff_t * offp)481 static ssize_t t1h_ns_write(struct file *filp, const char __user *buf,
482 size_t count, loff_t *offp)
483 {
484 int err;
485 char buffer[64];
486 u32 min, max;
487 unsigned long val;
488 struct sunxi_led *led = sunxi_led_global;
489
490 min = SUNXI_T1H_MIN_NS;
491 max = SUNXI_T1H_MAX_NS;
492
493 if (count >= sizeof(buffer))
494 return -EINVAL;
495
496 if (copy_from_user(buffer, buf, count))
497 return -EFAULT;
498
499 buffer[count] = '\0';
500
501 err = kstrtoul(buffer, 10, &val);
502 if (err)
503 return -EINVAL;
504
505 if (val < min || val > max)
506 goto err_out;
507
508 led->t1h_ns = val;
509
510 sunxi_set_t1h_ns(led);
511
512 *offp += count;
513
514 return count;
515
516 err_out:
517 LED_ERR("invalid parameter, t1h_ns should be %u-%u!\n",
518 min, max);
519
520 return -EINVAL;
521 }
522
t1h_ns_read(struct file * filp,char __user * buf,size_t count,loff_t * offp)523 static ssize_t t1h_ns_read(struct file *filp, char __user *buf,
524 size_t count, loff_t *offp)
525 {
526 int r;
527 char buffer[64];
528 struct sunxi_led *led = sunxi_led_global;
529
530 r = snprintf(buffer, 64, "%u\n", led->t1h_ns);
531
532 return simple_read_from_buffer(buf, count, offp, buffer, r);
533 }
534
535 static const struct file_operations t1h_ns_fops = {
536 .owner = THIS_MODULE,
537 .write = t1h_ns_write,
538 .read = t1h_ns_read,
539 };
540
t1l_ns_write(struct file * filp,const char __user * buf,size_t count,loff_t * offp)541 static ssize_t t1l_ns_write(struct file *filp, const char __user *buf,
542 size_t count, loff_t *offp)
543 {
544 int err;
545 char buffer[64];
546 u32 min, max;
547 unsigned long val;
548 struct sunxi_led *led = sunxi_led_global;
549
550 min = SUNXI_T1L_MIN_NS;
551 max = SUNXI_T1L_MAX_NS;
552
553 if (count >= sizeof(buffer))
554 goto err_out;
555
556 if (copy_from_user(buffer, buf, count))
557 goto err_out;
558
559 buffer[count] = '\0';
560
561 err = kstrtoul(buffer, 10, &val);
562 if (err)
563 goto err_out;
564
565 if (val < min || val > max)
566 goto err_out;
567
568 led->t1l_ns = val;
569 sunxi_set_t1l_ns(led);
570
571 *offp += count;
572
573 return count;
574
575 err_out:
576 LED_ERR("invalid parameter, t1l_ns should be %u-%u!\n",
577 min, max);
578
579 return -EINVAL;
580 }
581
t1l_ns_read(struct file * filp,char __user * buf,size_t count,loff_t * offp)582 static ssize_t t1l_ns_read(struct file *filp, char __user *buf,
583 size_t count, loff_t *offp)
584 {
585 int r;
586 char buffer[64];
587 struct sunxi_led *led = sunxi_led_global;
588
589 r = snprintf(buffer, 64, "%u\n", led->t1l_ns);
590
591 return simple_read_from_buffer(buf, count, offp, buffer, r);
592 }
593
594 static const struct file_operations t1l_ns_fops = {
595 .owner = THIS_MODULE,
596 .write = t1l_ns_write,
597 .read = t1l_ns_read,
598 };
599
t0h_ns_write(struct file * filp,const char __user * buf,size_t count,loff_t * offp)600 static ssize_t t0h_ns_write(struct file *filp, const char __user *buf,
601 size_t count, loff_t *offp)
602 {
603 int err;
604 char buffer[64];
605 u32 min, max;
606 unsigned long val;
607 struct sunxi_led *led = sunxi_led_global;
608
609 min = SUNXI_T0H_MIN_NS;
610 max = SUNXI_T0H_MAX_NS;
611
612 if (count >= sizeof(buffer))
613 goto err_out;
614
615 if (copy_from_user(buffer, buf, count))
616 goto err_out;
617
618 buffer[count] = '\0';
619
620 err = kstrtoul(buffer, 10, &val);
621 if (err)
622 goto err_out;
623
624 if (val < min || val > max)
625 goto err_out;
626
627 led->t0h_ns = val;
628 sunxi_set_t0h_ns(led);
629
630 *offp += count;
631
632 return count;
633
634 err_out:
635 LED_ERR("invalid parameter, t0h_ns should be %u-%u!\n",
636 min, max);
637
638 return -EINVAL;
639 }
640
t0h_ns_read(struct file * filp,char __user * buf,size_t count,loff_t * offp)641 static ssize_t t0h_ns_read(struct file *filp, char __user *buf,
642 size_t count, loff_t *offp)
643 {
644 int r;
645 char buffer[64];
646 struct sunxi_led *led = sunxi_led_global;
647
648 r = snprintf(buffer, 64, "%u\n", led->t0h_ns);
649
650 return simple_read_from_buffer(buf, count, offp, buffer, r);
651 }
652
653 static const struct file_operations t0h_ns_fops = {
654 .owner = THIS_MODULE,
655 .write = t0h_ns_write,
656 .read = t0h_ns_read,
657 };
658
t0l_ns_write(struct file * filp,const char __user * buf,size_t count,loff_t * offp)659 static ssize_t t0l_ns_write(struct file *filp, const char __user *buf,
660 size_t count, loff_t *offp)
661 {
662 int err;
663 char buffer[64];
664 u32 min, max;
665 unsigned long val;
666 struct sunxi_led *led = sunxi_led_global;
667
668 min = SUNXI_T0L_MIN_NS;
669 max = SUNXI_T0L_MAX_NS;
670
671 if (count >= sizeof(buffer))
672 goto err_out;
673
674 if (copy_from_user(buffer, buf, count))
675 goto err_out;
676
677 buffer[count] = '\0';
678
679 err = kstrtoul(buffer, 10, &val);
680 if (err)
681 goto err_out;
682
683 if (val < min || val > max)
684 goto err_out;
685
686 led->t0l_ns = val;
687 sunxi_set_t0l_ns(led);
688
689 *offp += count;
690
691 return count;
692
693 err_out:
694 LED_ERR("invalid parameter, t0l_ns should be %u-%u!\n",
695 min, max);
696
697 return -EINVAL;
698 }
699
t0l_ns_read(struct file * filp,char __user * buf,size_t count,loff_t * offp)700 static ssize_t t0l_ns_read(struct file *filp, char __user *buf,
701 size_t count, loff_t *offp)
702 {
703 int r;
704 char buffer[64];
705 struct sunxi_led *led = sunxi_led_global;
706
707 r = snprintf(buffer, 64, "%u\n", led->t0l_ns);
708
709 return simple_read_from_buffer(buf, count, offp, buffer, r);
710 }
711
712 static const struct file_operations t0l_ns_fops = {
713 .owner = THIS_MODULE,
714 .write = t0l_ns_write,
715 .read = t0l_ns_read,
716 };
717
wait_time0_ns_write(struct file * filp,const char __user * buf,size_t count,loff_t * offp)718 static ssize_t wait_time0_ns_write(struct file *filp, const char __user *buf,
719 size_t count, loff_t *offp)
720 {
721 int err;
722 char buffer[64];
723 u32 min, max;
724 unsigned long val;
725 struct sunxi_led *led = sunxi_led_global;
726
727 min = SUNXI_WAIT_TIME0_MIN_NS;
728 max = SUNXI_WAIT_TIME0_MAX_NS;
729
730 if (count >= sizeof(buffer))
731 goto err_out;
732
733 if (copy_from_user(buffer, buf, count))
734 goto err_out;
735
736 buffer[count] = '\0';
737
738 err = kstrtoul(buffer, 10, &val);
739 if (err)
740 goto err_out;
741
742 if (val < min || val > max)
743 goto err_out;
744
745 led->wait_time0_ns = val;
746 sunxi_set_wait_time0_ns(led);
747
748 *offp += count;
749
750 return count;
751
752 err_out:
753 LED_ERR("invalid parameter, wait_time0_ns should be %u-%u!\n",
754 min, max);
755
756 return -EINVAL;
757 }
758
wait_time0_ns_read(struct file * filp,char __user * buf,size_t count,loff_t * offp)759 static ssize_t wait_time0_ns_read(struct file *filp, char __user *buf,
760 size_t count, loff_t *offp)
761 {
762 int r;
763 char buffer[64];
764 struct sunxi_led *led = sunxi_led_global;
765
766 r = snprintf(buffer, 64, "%u\n", led->wait_time0_ns);
767
768 return simple_read_from_buffer(buf, count, offp, buffer, r);
769 }
770
771 static const struct file_operations wait_time0_ns_fops = {
772 .owner = THIS_MODULE,
773 .write = wait_time0_ns_write,
774 .read = wait_time0_ns_read,
775 };
776
wait_time1_ns_write(struct file * filp,const char __user * buf,size_t count,loff_t * offp)777 static ssize_t wait_time1_ns_write(struct file *filp, const char __user *buf,
778 size_t count, loff_t *offp)
779 {
780 int err;
781 char buffer[64];
782 u32 min;
783 unsigned long long max;
784 unsigned long long val;
785 struct sunxi_led *led = sunxi_led_global;
786
787 min = SUNXI_WAIT_TIME1_MIN_NS;
788 max = SUNXI_WAIT_TIME1_MAX_NS;
789
790 if (count >= sizeof(buffer))
791 goto err_out;
792
793 if (copy_from_user(buffer, buf, count))
794 goto err_out;
795
796 buffer[count] = '\0';
797
798 err = kstrtoull(buffer, 10, &val);
799 if (err)
800 goto err_out;
801
802 if (val < min || val > max)
803 goto err_out;
804
805 led->wait_time1_ns = val;
806 sunxi_set_wait_time1_ns(led);
807
808 *offp += count;
809
810 return count;
811
812 err_out:
813 LED_ERR("invalid parameter, wait_time1_ns should be %u-%lld!\n",
814 min, max);
815
816 return -EINVAL;
817 }
818
wait_time1_ns_read(struct file * filp,char __user * buf,size_t count,loff_t * offp)819 static ssize_t wait_time1_ns_read(struct file *filp, char __user *buf,
820 size_t count, loff_t *offp)
821 {
822 int r;
823 char buffer[64];
824 struct sunxi_led *led = sunxi_led_global;
825
826 r = snprintf(buffer, 64, "%lld\n", led->wait_time1_ns);
827
828 return simple_read_from_buffer(buf, count, offp, buffer, r);
829 }
830
831 static const struct file_operations wait_time1_ns_fops = {
832 .owner = THIS_MODULE,
833 .write = wait_time1_ns_write,
834 .read = wait_time1_ns_read,
835 };
836
wait_data_time_ns_write(struct file * filp,const char __user * buf,size_t count,loff_t * offp)837 static ssize_t wait_data_time_ns_write(struct file *filp,
838 const char __user *buf,
839 size_t count, loff_t *offp)
840 {
841 int err;
842 char buffer[64];
843 u32 min, max;
844 unsigned long val;
845 struct sunxi_led *led = sunxi_led_global;
846
847 min = SUNXI_WAIT_DATA_TIME_MIN_NS;
848 #ifdef SUNXI_FPGA_LEDC
849 max = SUNXI_WAIT_DATA_TIME_MAX_NS_FPGA;
850 #else
851 max = SUNXI_WAIT_DATA_TIME_MAX_NS_IC;
852 #endif
853
854 if (count >= sizeof(buffer))
855 goto err_out;
856
857 if (copy_from_user(buffer, buf, count))
858 goto err_out;
859
860 buffer[count] = '\0';
861
862 err = kstrtoul(buffer, 10, &val);
863 if (err)
864 goto err_out;
865
866 if (val < min || val > max)
867 goto err_out;
868
869 led->wait_data_time_ns = val;
870 sunxi_set_wait_data_time_ns(led);
871
872 *offp += count;
873
874 return count;
875
876 err_out:
877 LED_ERR("invalid parameter, wait_data_time_ns should be %u-%u!\n",
878 min, max);
879
880 return -EINVAL;
881 }
882
wait_data_time_ns_read(struct file * filp,char __user * buf,size_t count,loff_t * offp)883 static ssize_t wait_data_time_ns_read(struct file *filp, char __user *buf,
884 size_t count, loff_t *offp)
885 {
886 int r;
887 char buffer[64];
888 struct sunxi_led *led = sunxi_led_global;
889
890 r = snprintf(buffer, 64, "%u\n", led->wait_data_time_ns);
891
892 return simple_read_from_buffer(buf, count, offp, buffer, r);
893 }
894
895 static const struct file_operations wait_data_time_ns_fops = {
896 .owner = THIS_MODULE,
897 .write = wait_data_time_ns_write,
898 .read = wait_data_time_ns_read,
899 };
900
data_show(struct seq_file * s,void * data)901 static int data_show(struct seq_file *s, void *data)
902 {
903 int i;
904 struct sunxi_led *led = sunxi_led_global;
905
906 for (i = 0; i < led->led_count; i++) {
907 if (!(i % 4)) {
908 if (i + 4 <= led->led_count)
909 seq_printf(s, "%04d-%04d", i, i + 4);
910 else
911 seq_printf(s, "%04d-%04d", i, led->led_count);
912 }
913 seq_printf(s, " 0x%08x", led->data[i]);
914 if (((i % 4) == 3) || (i == led->led_count - 1))
915 seq_puts(s, "\n");
916 }
917
918 return 0;
919 }
920
sunxi_ledc_set_dma_mode(struct sunxi_led * led)921 static void sunxi_ledc_set_dma_mode(struct sunxi_led *led)
922 {
923 u32 reg_val = 0;
924
925 reg_val |= 1 << 5;
926 sunxi_set_reg(LEDC_DMA_CTRL_REG, reg_val);
927
928 sunxi_ledc_disable_irq(LEDC_FIFO_CPUREQ_INT_EN);
929 }
930
sunxi_ledc_set_cpu_mode(struct sunxi_led * led)931 static void sunxi_ledc_set_cpu_mode(struct sunxi_led *led)
932 {
933 u32 reg_val = 0;
934
935 reg_val &= ~(1 << 5);
936 sunxi_set_reg(LEDC_DMA_CTRL_REG, reg_val);
937
938 sunxi_ledc_enable_irq(LEDC_FIFO_CPUREQ_INT_EN);
939 }
940
data_open(struct inode * inode,struct file * file)941 static int data_open(struct inode *inode, struct file *file)
942 {
943 return single_open(file, data_show, inode->i_private);
944 }
945
946 static const struct file_operations data_fops = {
947 .owner = THIS_MODULE,
948 .open = data_open,
949 .read = seq_read,
950 .llseek = seq_lseek,
951 .release = single_release,
952 };
953
output_mode_write(struct file * filp,const char __user * buf,size_t count,loff_t * offp)954 static ssize_t output_mode_write(struct file *filp, const char __user *buf,
955 size_t count, loff_t *offp)
956 {
957 char buffer[64];
958 struct sunxi_led *led = sunxi_led_global;
959
960 if (count >= sizeof(buffer))
961 goto err_out;
962
963 if (copy_from_user(buffer, buf, count))
964 goto err_out;
965
966 buffer[count] = '\0';
967
968 sunxi_ledc_set_output_mode(led, buffer);
969
970 *offp += count;
971
972 return count;
973
974 err_out:
975 LED_ERR("invalid parameter!\n");
976
977 return -EINVAL;
978 }
979
output_mode_read(struct file * filp,char __user * buf,size_t count,loff_t * offp)980 static ssize_t output_mode_read(struct file *filp, char __user *buf,
981 size_t count, loff_t *offp)
982 {
983 int r;
984 char buffer[64];
985 struct sunxi_led *led = sunxi_led_global;
986
987 r = snprintf(buffer, 64, "%s\n", led->output_mode.str);
988
989 return simple_read_from_buffer(buf, count, offp, buffer, r);
990 }
991
992 static const struct file_operations output_mode_fops = {
993 .owner = THIS_MODULE,
994 .write = output_mode_write,
995 .read = output_mode_read,
996 };
997
hwversion_read(struct file * filp,char __user * buf,size_t count,loff_t * offp)998 static ssize_t hwversion_read(struct file *filp, char __user *buf,
999 size_t count, loff_t *offp)
1000 {
1001 int r;
1002 char buffer[64];
1003 u32 reg_val, major_ver, minor_ver;
1004
1005 reg_val = sunxi_get_reg(LEDC_VER_NUM_REG);
1006 major_ver = reg_val >> 16;
1007 minor_ver = reg_val & 0xF;
1008
1009 r = snprintf(buffer, 64, "r%up%u\n", major_ver, minor_ver);
1010
1011 return simple_read_from_buffer(buf, count, offp, buffer, r);
1012 }
1013
1014 static const struct file_operations hwversion_fops = {
1015 .owner = THIS_MODULE,
1016 .read = hwversion_read,
1017 };
1018
sunxi_led_create_debugfs(struct sunxi_led * led)1019 static void sunxi_led_create_debugfs(struct sunxi_led *led)
1020 {
1021 struct dentry *debugfs_dir, *debugfs_file;
1022
1023 debugfs_dir = debugfs_create_dir("sunxi_leds", NULL);
1024 if (IS_ERR_OR_NULL(debugfs_dir)) {
1025 LED_ERR("debugfs_create_dir failed!\n");
1026 return;
1027 }
1028
1029 led->debugfs_dir = debugfs_dir;
1030
1031 debugfs_file = debugfs_create_file("reset_ns", 0660,
1032 debugfs_dir, NULL, &reset_ns_fops);
1033 if (!debugfs_file)
1034 LED_ERR("debugfs_create_file for reset_ns failed!\n");
1035
1036 debugfs_file = debugfs_create_file("t1h_ns", 0660,
1037 debugfs_dir, NULL, &t1h_ns_fops);
1038 if (!debugfs_file)
1039 LED_ERR("debugfs_create_file for t1h_ns failed!\n");
1040
1041 debugfs_file = debugfs_create_file("t1l_ns", 0660,
1042 debugfs_dir, NULL, &t1l_ns_fops);
1043 if (!debugfs_file)
1044 LED_ERR("debugfs_create_file for t1l_ns failed!\n");
1045
1046 debugfs_file = debugfs_create_file("t0h_ns", 0660,
1047 debugfs_dir, NULL, &t0h_ns_fops);
1048 if (!debugfs_file)
1049 LED_ERR("debugfs_create_file for t0h_ns failed!\n");
1050
1051 debugfs_file = debugfs_create_file("t0l_ns", 0660,
1052 debugfs_dir, NULL, &t0l_ns_fops);
1053 if (!debugfs_file)
1054 LED_ERR("debugfs_create_file for t0l_ns failed!\n");
1055
1056 debugfs_file = debugfs_create_file("wait_time0_ns", 0660,
1057 debugfs_dir, NULL, &wait_time0_ns_fops);
1058 if (!debugfs_file)
1059 LED_ERR("debugfs_create_file for wait_time0_ns failed!\n");
1060
1061 debugfs_file = debugfs_create_file("wait_time1_ns", 0660,
1062 debugfs_dir, NULL, &wait_time1_ns_fops);
1063 if (!debugfs_file)
1064 LED_ERR("debugfs_create_file for wait_time1_ns failed!\n");
1065
1066 debugfs_file = debugfs_create_file("wait_data_time_ns", 0660,
1067 debugfs_dir, NULL, &wait_data_time_ns_fops);
1068 if (!debugfs_file)
1069 LED_ERR("debugfs_create_file for wait_data_time_ns failed!\n");
1070
1071 debugfs_file = debugfs_create_file("data", 0440,
1072 debugfs_dir, NULL, &data_fops);
1073 if (!debugfs_file)
1074 LED_ERR("debugfs_create_file for data failed!\n");
1075
1076 debugfs_file = debugfs_create_file("output_mode", 0660,
1077 debugfs_dir, NULL, &output_mode_fops);
1078 if (!debugfs_file)
1079 LED_ERR("debugfs_create_file for output_mode failed!\n");
1080
1081 if (!debugfs_file)
1082 LED_ERR("debugfs_create_file for trans_mode failed!\n");
1083
1084 debugfs_file = debugfs_create_file("hwversion", 0440,
1085 debugfs_dir, NULL, &hwversion_fops);
1086 if (!debugfs_file)
1087 LED_ERR("debugfs_create_file for hwversion failed!\n");
1088 }
1089
sunxi_led_remove_debugfs(struct sunxi_led * led)1090 static void sunxi_led_remove_debugfs(struct sunxi_led *led)
1091 {
1092 debugfs_remove_recursive(led->debugfs_dir);
1093 }
1094 #endif /* CONFIG_DEBUG_FS */
1095
sunxi_ledc_dma_callback(void * param)1096 static void sunxi_ledc_dma_callback(void *param)
1097 {
1098 dprintk(DEBUG_INFO, "finish\n");
1099 }
1100
sunxi_ledc_trans_data(struct sunxi_led * led)1101 static void sunxi_ledc_trans_data(struct sunxi_led *led)
1102 {
1103 int i, err;
1104 size_t size;
1105 unsigned long flags;
1106 phys_addr_t dst_addr;
1107 struct dma_slave_config slave_config;
1108 struct device *dev = led->dev;
1109 struct dma_async_tx_descriptor *dma_desc;
1110
1111 /* less than 32 lights use cpu transmission. */
1112 /* more than 32 lights use dma transmission. */
1113 if (led->length <= SUNXI_LEDC_FIFO_DEPTH) {
1114 dprintk(DEBUG_INFO, "cpu xfer\n");
1115 ktime_get_coarse_real_ts64(&(led->start_time));
1116 sunxi_ledc_set_time(led);
1117 sunxi_ledc_set_output_mode(led, led->output_mode.str);
1118 sunxi_ledc_set_cpu_mode(led);
1119 sunxi_ledc_set_length(led);
1120
1121 sunxi_ledc_enable_irq(LEDC_TRANS_FINISH_INT_EN | LEDC_WAITDATA_TIMEOUT_INT_EN
1122 | LEDC_FIFO_OVERFLOW_INT_EN | LEDC_GLOBAL_INT_EN);
1123
1124 sunxi_ledc_enable(led);
1125
1126 for (i = 0; i < led->length; i++)
1127 sunxi_set_reg(LEDC_DATA_REG_OFFSET, led->data[i]);
1128
1129 } else {
1130 dprintk(DEBUG_INFO, "dma xfer\n");
1131
1132 size = led->length * 4;
1133 led->src_dma = dma_map_single(dev, led->data,
1134 size, DMA_TO_DEVICE);
1135 dst_addr = led->res->start + LEDC_DATA_REG_OFFSET;
1136
1137 flags = DMA_PREP_INTERRUPT | DMA_CTRL_ACK;
1138
1139 slave_config.direction = DMA_MEM_TO_DEV;
1140 slave_config.src_addr = led->src_dma;
1141 slave_config.dst_addr = dst_addr;
1142 slave_config.src_addr_width = DMA_SLAVE_BUSWIDTH_4_BYTES;
1143 slave_config.dst_addr_width = DMA_SLAVE_BUSWIDTH_4_BYTES;
1144 slave_config.src_maxburst = 4;
1145 slave_config.dst_maxburst = 4;
1146
1147 err = dmaengine_slave_config(led->dma_chan, &slave_config);
1148 if (err < 0) {
1149 LED_ERR("dmaengine_slave_config failed!\n");
1150 return;
1151 }
1152
1153 dma_desc = dmaengine_prep_slave_single(led->dma_chan,
1154 led->src_dma,
1155 size,
1156 DMA_MEM_TO_DEV,
1157 flags);
1158 if (!dma_desc) {
1159 LED_ERR("dmaengine_prep_slave_single failed!\n");
1160 return;
1161 }
1162
1163 dma_desc->callback = sunxi_ledc_dma_callback;
1164
1165 dmaengine_submit(dma_desc);
1166 dma_async_issue_pending(led->dma_chan);
1167
1168 ktime_get_coarse_real_ts64(&(led->start_time));
1169 sunxi_ledc_set_time(led);
1170 sunxi_ledc_set_output_mode(led, led->output_mode.str);
1171 sunxi_ledc_set_dma_mode(led);
1172 sunxi_ledc_set_length(led);
1173 sunxi_ledc_enable_irq(LEDC_TRANS_FINISH_INT_EN | LEDC_WAITDATA_TIMEOUT_INT_EN
1174 | LEDC_FIFO_OVERFLOW_INT_EN | LEDC_GLOBAL_INT_EN);
1175 sunxi_ledc_enable(led);
1176 }
1177 }
1178
sunxi_ledc_clear_all_irq(void)1179 static inline void sunxi_ledc_clear_all_irq(void)
1180 {
1181 u32 reg_val = sunxi_get_reg(LEDC_INT_STS_REG_OFFSET);
1182
1183 reg_val &= ~0x1F;
1184 sunxi_set_reg(LEDC_INT_STS_REG_OFFSET, reg_val);
1185 }
1186
sunxi_ledc_clear_irq(enum sunxi_ledc_irq_status_reg irq)1187 static inline void sunxi_ledc_clear_irq(enum sunxi_ledc_irq_status_reg irq)
1188 {
1189 u32 reg_val = sunxi_get_reg(LEDC_INT_STS_REG_OFFSET);
1190
1191 reg_val &= ~irq;
1192 sunxi_set_reg(LEDC_INT_STS_REG_OFFSET, reg_val);
1193 }
1194
sunxi_ledc_dma_terminate(struct sunxi_led * led)1195 static void sunxi_ledc_dma_terminate(struct sunxi_led *led)
1196 {
1197 if (led->dma_chan) {
1198 dmaengine_terminate_all(led->dma_chan);
1199 dma_unmap_single(led->dev, led->src_dma, led->length * 4,
1200 DMA_TO_DEVICE);
1201 }
1202 }
1203
sunxi_ledc_complete(struct sunxi_led * led)1204 static int sunxi_ledc_complete(struct sunxi_led *led)
1205 {
1206 unsigned long flags = 0;
1207 unsigned long timeout = 0;
1208 u32 reg_val;
1209
1210 /*wait_event_timeout return 0 : timeout
1211 *wait_event_timeout return > 0 : thr left time
1212 * */
1213 timeout = wait_event_timeout(led->wait, led->result, 5*HZ);
1214
1215 /* dynamic close dma transmission */
1216 sunxi_ledc_dma_terminate(led);
1217
1218 if (timeout == 0) {
1219 reg_val = sunxi_get_reg(LEDC_INT_STS_REG_OFFSET);
1220 pr_err("LEDC INTERRUPT STATUS REG IS %x", reg_val);
1221 LED_ERR("led xfer timeout\n");
1222 reg_val = sunxi_get_reg(LEDC_INT_STS_REG_OFFSET);
1223 pr_err("LEDC INTERRUPT STATUS REG IS %x", reg_val);
1224 return -ETIME;
1225 } else if (led->result == RESULT_ERR) {
1226 return -ECOMM;
1227 }
1228
1229 dprintk(DEBUG_INFO, "xfer complete\n");
1230
1231 spin_lock_irqsave(&led->lock, flags);
1232 led->result = 0;
1233 spin_unlock_irqrestore(&led->lock, flags);
1234
1235 return 0;
1236 }
1237
sunxi_ledc_irq_handler(int irq,void * dev_id)1238 static irqreturn_t sunxi_ledc_irq_handler(int irq, void *dev_id)
1239 {
1240 unsigned long flags;
1241 long delta_time_ns;
1242 u32 irq_status, max_ns;
1243 struct sunxi_led *led = sunxi_led_global;
1244 struct timespec64 current_time;
1245
1246 spin_lock_irqsave(&led->lock, flags);
1247
1248 irq_status = sunxi_get_reg(LEDC_INT_STS_REG_OFFSET);
1249
1250 sunxi_ledc_clear_all_irq();
1251
1252 if (irq_status & LEDC_TRANS_FINISH_INT) {
1253 sunxi_ledc_reset(led);
1254 led->length = 0;
1255 led->result = RESULT_COMPLETE;
1256 wake_up(&led->wait);
1257 goto out;
1258 }
1259
1260 if (irq_status & LEDC_WAITDATA_TIMEOUT_INT) {
1261 ktime_get_coarse_real_ts64(¤t_time);
1262 delta_time_ns = current_time.tv_sec - led->start_time.tv_sec;
1263 delta_time_ns *= 1000 * 1000 * 1000;
1264 delta_time_ns += current_time.tv_nsec - led->start_time.tv_nsec;
1265
1266 max_ns = led->wait_data_time_ns;
1267
1268 if (delta_time_ns <= max_ns) {
1269 spin_unlock_irqrestore(&led->lock, flags);
1270 return IRQ_HANDLED;
1271 }
1272
1273 sunxi_ledc_reset(led);
1274
1275 if (delta_time_ns <= max_ns * 2) {
1276 sunxi_ledc_dma_terminate(led);
1277 sunxi_ledc_trans_data(led);
1278 } else {
1279 LED_ERR("wait time is more than %d ns,"
1280 "going to reset ledc and drop this operation!\n",
1281 max_ns);
1282 led->result = RESULT_ERR;
1283 wake_up(&led->wait);
1284 led->length = 0;
1285 }
1286
1287 goto out;
1288 }
1289
1290 if (irq_status & LEDC_FIFO_OVERFLOW_INT) {
1291 LED_ERR("there exists fifo overflow issue, irq_status=0x%x!\n",
1292 irq_status);
1293 sunxi_ledc_reset(led);
1294 led->result = RESULT_ERR;
1295 wake_up(&led->wait);
1296 led->length = 0;
1297 goto out;
1298 }
1299
1300 out:
1301 spin_unlock_irqrestore(&led->lock, flags);
1302 return IRQ_HANDLED;
1303 }
1304
sunxi_ledc_irq_init(struct sunxi_led * led)1305 static int sunxi_ledc_irq_init(struct sunxi_led *led)
1306 {
1307 int err;
1308 struct device *dev = led->dev;
1309 unsigned long flags = 0;
1310 const char *name = "ledcirq";
1311 struct platform_device *pdev;
1312
1313 pdev = container_of(dev, struct platform_device, dev);
1314
1315 spin_lock_init(&led->lock);
1316
1317 led->irqnum = platform_get_irq(pdev, 0);
1318 if (led->irqnum < 0)
1319 LED_ERR("failed to get ledc irq!\n");
1320
1321 err = request_irq(led->irqnum, sunxi_ledc_irq_handler,
1322 flags, name, dev);
1323 if (err) {
1324 LED_ERR("failed to install IRQ handler for irqnum %d\n",
1325 led->irqnum);
1326 return -EPERM;
1327 }
1328
1329 return 0;
1330 }
1331
sunxi_ledc_irq_deinit(struct sunxi_led * led)1332 static void sunxi_ledc_irq_deinit(struct sunxi_led *led)
1333 {
1334 free_irq(led->irqnum, led->dev);
1335 sunxi_ledc_disable_irq(LEDC_TRANS_FINISH_INT_EN | LEDC_FIFO_CPUREQ_INT_EN
1336 | LEDC_WAITDATA_TIMEOUT_INT_EN | LEDC_FIFO_OVERFLOW_INT_EN
1337 | LEDC_GLOBAL_INT_EN);
1338 }
1339
sunxi_ledc_pinctrl_init(struct sunxi_led * led)1340 static void sunxi_ledc_pinctrl_init(struct sunxi_led *led)
1341 {
1342 struct device *dev = led->dev;
1343 struct pinctrl *pinctrl = devm_pinctrl_get_select_default(dev);
1344
1345 led->pctrl = pinctrl;
1346 if (IS_ERR(pinctrl))
1347 LED_ERR("devm_pinctrl_get_select_default failed!\n");
1348 }
1349
led_regulator_request(struct sunxi_led * led)1350 static int led_regulator_request(struct sunxi_led *led)
1351 {
1352 struct regulator *regu = NULL;
1353
1354 /* Consider "n*" as nocare. Support "none", "nocare", "null", "" etc. */
1355 if ((led->regulator_id[0] == 'n') || (led->regulator_id[0] == 0))
1356 return 0;
1357
1358 regu = regulator_get(NULL, led->regulator_id);
1359 if (IS_ERR(regu)) {
1360 LED_ERR("get regulator %s failed!\n", led->regulator_id);
1361 return -1;
1362 }
1363 led->regulator = regu;
1364
1365 return 0;
1366 }
1367
led_regulator_release(struct sunxi_led * led)1368 static int led_regulator_release(struct sunxi_led *led)
1369 {
1370 if (led->regulator == NULL)
1371 return 0;
1372
1373 regulator_put(led->regulator);
1374 led->regulator = NULL;
1375
1376 return 1;
1377 }
1378
sunxi_ledc_dma_get(struct sunxi_led * led)1379 static int sunxi_ledc_dma_get(struct sunxi_led *led)
1380 {
1381 if (led->dma_chan == NULL) {
1382 led->dma_chan = dma_request_chan(led->dev, "tx");
1383 if (IS_ERR(led->dma_chan)) {
1384 LED_ERR("failed to get the DMA channel!\n");
1385 return -EFAULT;
1386 }
1387 }
1388 return 0;
1389 }
1390
sunxi_ledc_dma_put(struct sunxi_led * led)1391 static void sunxi_ledc_dma_put(struct sunxi_led *led)
1392 {
1393 if (led->dma_chan) {
1394 dma_release_channel(led->dma_chan);
1395 led->dma_chan = NULL;
1396 }
1397 }
1398
sunxi_set_led_brightness(struct led_classdev * led_cdev,enum led_brightness value)1399 static int sunxi_set_led_brightness(struct led_classdev *led_cdev,
1400 enum led_brightness value)
1401 {
1402 unsigned long flags;
1403 u32 r, g, b, shift, old_data, new_data, length;
1404 struct sunxi_led_info *pinfo;
1405 struct sunxi_led_classdev_group *pcdev_group;
1406 struct sunxi_led *led = sunxi_led_global;
1407 int err;
1408
1409 pinfo = container_of(led_cdev, struct sunxi_led_info, cdev);
1410
1411 switch (pinfo->type) {
1412 case LED_TYPE_G:
1413 pcdev_group = container_of(pinfo,
1414 struct sunxi_led_classdev_group, g);
1415 g = value;
1416 shift = 16;
1417 break;
1418 case LED_TYPE_R:
1419 pcdev_group = container_of(pinfo,
1420 struct sunxi_led_classdev_group, r);
1421 r = value;
1422 shift = 8;
1423 break;
1424
1425 case LED_TYPE_B:
1426 pcdev_group = container_of(pinfo,
1427 struct sunxi_led_classdev_group, b);
1428 b = value;
1429 shift = 0;
1430 break;
1431 }
1432
1433 old_data = led->data[pcdev_group->led_num];
1434 if (((old_data >> shift) & 0xFF) == value)
1435 return 0;
1436
1437 if (pinfo->type != LED_TYPE_R)
1438 r = pcdev_group->r.cdev.brightness;
1439 if (pinfo->type != LED_TYPE_G)
1440 g = pcdev_group->g.cdev.brightness;
1441 if (pinfo->type != LED_TYPE_B)
1442 b = pcdev_group->b.cdev.brightness;
1443
1444 /* LEDC treats input data as GRB by default */
1445 new_data = (g << 16) | (r << 8) | b;
1446 length = pcdev_group->led_num + 1;
1447
1448 spin_lock_irqsave(&led->lock, flags);
1449 led->data[pcdev_group->led_num] = new_data;
1450 led->length = length;
1451 spin_unlock_irqrestore(&led->lock, flags);
1452
1453 /* prepare for dma xfer, dynamic apply dma channel */
1454 if (led->length > SUNXI_LEDC_FIFO_DEPTH) {
1455 err = sunxi_ledc_dma_get(led);
1456 if (err)
1457 return err;
1458 }
1459
1460 sunxi_ledc_trans_data(led);
1461 if (debug_mask & DEBUG_INFO2) {
1462 dprintk(DEBUG_INFO2, "dump reg:\n");
1463 led_dump_reg(led, 0, 0x30);
1464 }
1465
1466 sunxi_ledc_complete(led);
1467
1468 /* dynamic release dma chan, release at the end of a transmission */
1469 if (led->length > SUNXI_LEDC_FIFO_DEPTH)
1470 sunxi_ledc_dma_put(led);
1471
1472 if (debug_mask & DEBUG_INFO1)
1473 pr_warn("num = %03u\n", length);
1474
1475 return 0;
1476 }
1477
sunxi_register_led_classdev(struct sunxi_led * led)1478 static int sunxi_register_led_classdev(struct sunxi_led *led)
1479 {
1480 int i, err;
1481 size_t size;
1482 struct device *dev = led->dev;
1483 struct led_classdev *pcdev_RGB;
1484
1485 dprintk(DEBUG_INIT, "led_classdev start\n");
1486 if (!led->led_count)
1487 led->led_count = SUNXI_DEFAULT_LED_COUNT;
1488
1489 size = sizeof(struct sunxi_led_classdev_group) * led->led_count;
1490 led->pcdev_group = kzalloc(size, GFP_KERNEL);
1491 if (!led->pcdev_group) {
1492 LED_ERR("kzalloc error\n");
1493 return -ENOMEM;
1494 }
1495
1496 for (i = 0; i < led->led_count; i++) {
1497 led->pcdev_group[i].r.type = LED_TYPE_R;
1498 pcdev_RGB = &led->pcdev_group[i].r.cdev;
1499 pcdev_RGB->name = kzalloc(16, GFP_KERNEL);
1500 sprintf((char *)pcdev_RGB->name, "sunxi_led%dr", i);
1501 pcdev_RGB->brightness = LED_OFF;
1502 pcdev_RGB->brightness_set_blocking = sunxi_set_led_brightness;
1503 pcdev_RGB->dev = dev;
1504 err = led_classdev_register(dev, pcdev_RGB);
1505 if (err < 0) {
1506 LED_ERR("led_classdev_register %s failed!\n",
1507 pcdev_RGB->name);
1508 return err;
1509 }
1510
1511 led->pcdev_group[i].g.type = LED_TYPE_G;
1512 pcdev_RGB = &led->pcdev_group[i].g.cdev;
1513 pcdev_RGB->name = kzalloc(16, GFP_KERNEL);
1514 sprintf((char *)pcdev_RGB->name, "sunxi_led%dg", i);
1515 pcdev_RGB->brightness = LED_OFF;
1516 pcdev_RGB->brightness_set_blocking = sunxi_set_led_brightness;
1517 pcdev_RGB->dev = dev;
1518 err = led_classdev_register(dev, pcdev_RGB);
1519 if (err < 0) {
1520 LED_ERR("led_classdev_register %s failed!\n",
1521 pcdev_RGB->name);
1522 return err;
1523 }
1524
1525 led->pcdev_group[i].b.type = LED_TYPE_B;
1526 pcdev_RGB = &led->pcdev_group[i].b.cdev;
1527 pcdev_RGB->name = kzalloc(16, GFP_KERNEL);
1528 sprintf((char *)pcdev_RGB->name, "sunxi_led%db", i);
1529 pcdev_RGB->brightness = LED_OFF;
1530 pcdev_RGB->brightness_set_blocking = sunxi_set_led_brightness;
1531 pcdev_RGB->dev = dev;
1532 err = led_classdev_register(dev, pcdev_RGB);
1533 if (err < 0) {
1534 LED_ERR("led_classdev_register %s failed!\n",
1535 pcdev_RGB->name);
1536 return err;
1537 }
1538
1539 led->pcdev_group[i].led_num = i;
1540 }
1541
1542 size = sizeof(u32) * led->led_count;
1543 led->data = kzalloc(size, GFP_KERNEL);
1544 if (!led->data)
1545 return -ENOMEM;
1546
1547 return 0;
1548 }
1549
sunxi_unregister_led_classdev(struct sunxi_led * led)1550 static void sunxi_unregister_led_classdev(struct sunxi_led *led)
1551 {
1552 int i;
1553
1554 for (i = 0; i < led->led_count; i++) {
1555 kfree(led->pcdev_group[i].b.cdev.name);
1556 led->pcdev_group[i].b.cdev.name = NULL;
1557 kfree(led->pcdev_group[i].g.cdev.name);
1558 led->pcdev_group[i].g.cdev.name = NULL;
1559 kfree(led->pcdev_group[i].r.cdev.name);
1560 led->pcdev_group[i].r.cdev.name = NULL;
1561 led_classdev_unregister(&led->pcdev_group[i].b.cdev);
1562 led_classdev_unregister(&led->pcdev_group[i].g.cdev);
1563 led_classdev_unregister(&led->pcdev_group[i].r.cdev);
1564 }
1565 kfree(led->data);
1566 led->data = NULL;
1567
1568
1569 kfree(led->pcdev_group);
1570 led->pcdev_group = NULL;
1571 }
1572
sunxi_get_u32_of_property(const char * propname,int * val)1573 static inline int sunxi_get_u32_of_property(const char *propname, int *val)
1574 {
1575 int err;
1576 struct sunxi_led *led = sunxi_led_global;
1577 struct device *dev = led->dev;
1578 struct device_node *np = dev->of_node;
1579
1580 err = of_property_read_u32(np, propname, val);
1581 if (err < 0)
1582 LED_ERR("failed to get the value of propname %s!\n", propname);
1583
1584 return err;
1585 }
1586
sunxi_get_str_of_property(const char * propname,const char ** out_string)1587 static inline int sunxi_get_str_of_property(const char *propname,
1588 const char **out_string)
1589 {
1590 int err;
1591 struct sunxi_led *led = sunxi_led_global;
1592 struct device *dev = led->dev;
1593 struct device_node *np = dev->of_node;
1594
1595 err = of_property_read_string(np, propname, out_string);
1596 if (err < 0)
1597 LED_ERR("failed to get the string of propname %s!\n", propname);
1598
1599 return err;
1600 }
1601
sunxi_get_para_of_property(struct sunxi_led * led)1602 static void sunxi_get_para_of_property(struct sunxi_led *led)
1603 {
1604 int err;
1605 u32 val;
1606 const char *str;
1607
1608 err = sunxi_get_u32_of_property("led_count", &val);
1609 if (!err)
1610 led->led_count = val;
1611
1612 memcpy(led->output_mode.str, "GRB", 3);
1613 led->output_mode.val = SUNXI_OUTPUT_GRB;
1614 err = sunxi_get_str_of_property("output_mode", &str);
1615 if (!err)
1616 if (!strncmp(str, "BRG", 3) ||
1617 !strncmp(str, "GBR", 3) ||
1618 !strncmp(str, "RGB", 3) ||
1619 !strncmp(str, "RBG", 3) ||
1620 !strncmp(str, "BGR", 3))
1621 memcpy(led->output_mode.str, str, 3);
1622
1623 err = sunxi_get_str_of_property("led_regulator", &str);
1624 if (!err) {
1625 if (strlen(str) >= sizeof(led->regulator_id))
1626 LED_ERR("illegal regulator id\n");
1627 else {
1628 strcpy(led->regulator_id, str);
1629 pr_info("led_regulator: %s\n", led->regulator_id);
1630 }
1631 }
1632
1633 err = sunxi_get_u32_of_property("reset_ns", &val);
1634 if (!err)
1635 led->reset_ns = val;
1636
1637 err = sunxi_get_u32_of_property("t1h_ns", &val);
1638 if (!err)
1639 led->t1h_ns = val;
1640
1641 err = sunxi_get_u32_of_property("t1l_ns", &val);
1642 if (!err)
1643 led->t1l_ns = val;
1644
1645 err = sunxi_get_u32_of_property("t0h_ns", &val);
1646 if (!err)
1647 led->t0h_ns = val;
1648
1649 err = sunxi_get_u32_of_property("t0l_ns", &val);
1650 if (!err)
1651 led->t0l_ns = val;
1652
1653 err = sunxi_get_u32_of_property("wait_time0_ns", &val);
1654 if (!err)
1655 led->wait_time0_ns = val;
1656
1657 err = sunxi_get_u32_of_property("wait_time1_ns", &val);
1658 if (!err)
1659 led->wait_time1_ns = val;
1660
1661 err = sunxi_get_u32_of_property("wait_data_time_ns", &val);
1662 if (!err)
1663 led->wait_data_time_ns = val;
1664 }
sunxi_led_set_all(struct sunxi_led * led,u8 channel,enum led_brightness value)1665 void sunxi_led_set_all(struct sunxi_led *led, u8 channel,
1666 enum led_brightness value)
1667 {
1668 u32 i;
1669 struct led_classdev *led_cdev;
1670
1671 if (channel%3 == 0) {
1672 for (i = 0; i < led->led_count; i++) {
1673 led_cdev = &led->pcdev_group[i].r.cdev;
1674 mutex_lock(&led_cdev->led_access);
1675 sunxi_set_led_brightness(led_cdev, value);
1676 mutex_unlock(&led_cdev->led_access);
1677 }
1678 } else if (channel%3 == 1) {
1679 for (i = 0; i < led->led_count; i++) {
1680 led_cdev = &led->pcdev_group[i].g.cdev;
1681 mutex_lock(&led_cdev->led_access);
1682 sunxi_set_led_brightness(led_cdev, value);
1683 mutex_unlock(&led_cdev->led_access);
1684 }
1685 } else {
1686 for (i = 0; i < led->led_count; i++) {
1687 led_cdev = &led->pcdev_group[i].b.cdev;
1688 mutex_lock(&led_cdev->led_access);
1689 sunxi_set_led_brightness(led_cdev, value);
1690 mutex_unlock(&led_cdev->led_access);
1691 }
1692 }
1693 }
1694
led_show(struct class * class,struct class_attribute * attr,char * buf)1695 static ssize_t led_show(struct class *class,
1696 struct class_attribute *attr,
1697 char *buf)
1698 {
1699 struct sunxi_led *led = sunxi_led_global;
1700
1701 sunxi_led_set_all(led, 0, 0);
1702 sunxi_led_set_all(led, 1, 0);
1703 sunxi_led_set_all(led, 2, 0);
1704
1705 sunxi_led_set_all(led, 0, 20);
1706 msleep(500);
1707 sunxi_led_set_all(led, 1, 20);
1708 msleep(500);
1709 sunxi_led_set_all(led, 2, 20);
1710 msleep(500);
1711
1712 sunxi_led_set_all(led, 0, 0);
1713 sunxi_led_set_all(led, 1, 0);
1714 sunxi_led_set_all(led, 2, 0);
1715
1716 return 0;
1717 }
1718
1719 static struct class_attribute led_class_attrs[] = {
1720 __ATTR(light, 0644, led_show, NULL),
1721 //__ATTR_NULL,
1722 };
1723
led_node_init(void)1724 static void led_node_init(void)
1725 {
1726 int i;
1727 int err;
1728 /* sys/class/led/xxx */
1729 for (i = 0; i < ARRAY_SIZE(led_class_attrs); i++) {
1730 err = class_create_file(led_class, &led_class_attrs[i]);
1731 if (err) {
1732 LED_ERR("class_create_file() failed!\n");
1733 while (i--)
1734 class_remove_file(led_class, &led_class_attrs[i]);
1735 class_destroy(led_class);
1736 led_class = NULL;
1737 }
1738 }
1739 }
1740
sunxi_led_probe(struct platform_device * pdev)1741 static int sunxi_led_probe(struct platform_device *pdev)
1742 {
1743 int err;
1744 struct sunxi_led *led;
1745 struct device *dev = &pdev->dev;
1746 struct resource *mem_res = NULL;
1747 int ret;
1748
1749 dprintk(DEBUG_INIT, "start\n");
1750
1751 led = kzalloc(sizeof(struct sunxi_led), GFP_KERNEL);
1752 if (!led) {
1753 LED_ERR("kzalloc failed\n");
1754 ret = -ENOMEM;
1755 }
1756
1757 sunxi_led_global = led;
1758
1759 platform_set_drvdata(pdev, led);
1760 led->dev = dev;
1761
1762 mem_res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
1763 if (mem_res == NULL) {
1764 LED_ERR("failed to get MEM res\n");
1765 ret = -ENXIO;
1766 goto emem;
1767 }
1768
1769 if (!request_mem_region(mem_res->start, resource_size(mem_res),
1770 mem_res->name)) {
1771 LED_ERR("failed to request mem region\n");
1772 ret = -EINVAL;
1773 goto emem;
1774 }
1775
1776 led->iomem_reg_base = ioremap(mem_res->start, resource_size(mem_res));
1777 if (!led->iomem_reg_base) {
1778 ret = -EIO;
1779 goto eiomap;
1780 }
1781 led->res = mem_res;
1782
1783 led->output_mode.str = kzalloc(3, GFP_KERNEL);
1784 if (!led->output_mode.str) {
1785 LED_ERR("kzalloc failed\n");
1786 ret = -ENOMEM;
1787 goto ezalloc_str;
1788 }
1789
1790 sunxi_get_para_of_property(led);
1791
1792 err = led_regulator_request(led);
1793 if (err < 0) {
1794 LED_ERR("request regulator failed!\n");
1795 ret = err;
1796 goto eregulator;
1797 }
1798
1799 err = sunxi_register_led_classdev(led);
1800 if (err) {
1801 LED_ERR("failed to register led classdev\n");
1802 ret = err;
1803 goto eclassdev;
1804 }
1805
1806 sunxi_ledc_set_time(led);
1807
1808 led->reset = devm_reset_control_get(&pdev->dev, NULL);
1809 if (IS_ERR(led->reset)) {
1810 LED_ERR("get reset clk error\n");
1811 return -EINVAL;
1812 }
1813 ret = reset_control_deassert(led->reset);
1814 if (ret) {
1815 LED_ERR("deassert clk error, ret:%d\n", ret);
1816 return ret;
1817 }
1818
1819 sunxi_clk_init(led);
1820
1821 init_waitqueue_head(&led->wait);
1822
1823 err = sunxi_ledc_irq_init(led);
1824 if (err) {
1825 LED_ERR("failed to init irq\n");
1826 ret = err;
1827 goto eirq;
1828 }
1829
1830 sunxi_ledc_pinctrl_init(led);
1831
1832 #ifdef CONFIG_DEBUG_FS
1833 sunxi_led_create_debugfs(led);
1834 #endif /* CONFIG_DEBUG_FS */
1835
1836 led_class = class_create(THIS_MODULE, "led");
1837 if (IS_ERR(led_class)) {
1838 LED_ERR("class_register err\n");
1839 class_destroy(led_class);
1840 ret = -EFAULT;
1841 goto eclass;
1842 }
1843 led_node_init();
1844 dprintk(DEBUG_INIT, "finish\n");
1845 return 0;
1846
1847 eclass:
1848 #ifdef CONFIG_DEBUG_FS
1849 sunxi_led_remove_debugfs(led);
1850 #endif /* CONFIG_DEBUG_FS */
1851
1852 sunxi_ledc_irq_deinit(led);
1853
1854 eirq:
1855 sunxi_unregister_led_classdev(led);
1856 sunxi_clk_deinit(led);
1857
1858 eclassdev:
1859 led_regulator_release(led);
1860
1861 eregulator:
1862 kfree(led->output_mode.str);
1863
1864 ezalloc_str:
1865 iounmap(led->iomem_reg_base);
1866 led->iomem_reg_base = NULL;
1867
1868 eiomap:
1869 release_mem_region(mem_res->start, resource_size(mem_res));
1870
1871 emem:
1872 kfree(led);
1873 return ret;
1874 }
1875
sunxi_led_remove(struct platform_device * pdev)1876 static int sunxi_led_remove(struct platform_device *pdev)
1877 {
1878 struct sunxi_led *led = platform_get_drvdata(pdev);
1879
1880 class_destroy(led_class);
1881
1882 #ifdef CONFIG_DEBUG_FS
1883 sunxi_led_remove_debugfs(led);
1884 #endif /* CONFIG_DEBUG_FS */
1885
1886 sunxi_ledc_irq_deinit(led);
1887
1888 sunxi_unregister_led_classdev(led);
1889 sunxi_clk_deinit(led);
1890
1891 led_regulator_release(led);
1892
1893 kfree(led->output_mode.str);
1894 led->output_mode.str = NULL;
1895
1896 iounmap(led->iomem_reg_base);
1897 led->iomem_reg_base = NULL;
1898
1899 release_mem_region(led->res->start, resource_size(led->res));
1900
1901 kfree(led);
1902 led = NULL;
1903
1904 dprintk(DEBUG_INIT, "finish\n");
1905 return 0;
1906 }
1907
1908 #if IS_ENABLED(CONFIG_PM)
sunxi_led_save_regs(struct sunxi_led * led)1909 static inline void sunxi_led_save_regs(struct sunxi_led *led)
1910 {
1911 int i;
1912
1913 for (i = 0; i < ARRAY_SIZE(sunxi_led_regs_offset); i++)
1914 led->regs_backup[i] = readl(led->iomem_reg_base + sunxi_led_regs_offset[i]);
1915 }
1916
sunxi_led_restore_regs(struct sunxi_led * led)1917 static inline void sunxi_led_restore_regs(struct sunxi_led *led)
1918 {
1919 int i;
1920
1921 for (i = 0; i < ARRAY_SIZE(sunxi_led_regs_offset); i++)
1922 writel(led->regs_backup[i], led->iomem_reg_base + sunxi_led_regs_offset[i]);
1923 }
1924
sunxi_led_enable_irq(struct sunxi_led * led)1925 static void sunxi_led_enable_irq(struct sunxi_led *led)
1926 {
1927 enable_irq(led->irqnum);
1928 }
1929
sunxi_led_disable_irq(struct sunxi_led * led)1930 static void sunxi_led_disable_irq(struct sunxi_led *led)
1931 {
1932 disable_irq_nosync(led->irqnum);
1933 }
1934
sunxi_led_gpio_state_select(struct sunxi_led * led,char * name)1935 static int sunxi_led_gpio_state_select(struct sunxi_led *led, char *name)
1936 {
1937 int err;
1938 struct pinctrl_state *pctrl_state;
1939
1940 pctrl_state = pinctrl_lookup_state(led->pctrl, name);
1941 if (IS_ERR(pctrl_state)) {
1942 dev_err(led->dev, "pinctrl_lookup_state(%s) failed! return %p\n",
1943 name, pctrl_state);
1944 return PTR_ERR(pctrl_state);
1945 }
1946
1947 err = pinctrl_select_state(led->pctrl, pctrl_state);
1948 if (err < 0) {
1949 dev_err(led->dev, "pinctrl_select_state(%s) failed! return %d\n",
1950 name, err);
1951 return err;
1952 }
1953
1954 return 0;
1955 }
1956
sunxi_led_enable_clk(struct sunxi_led * led)1957 static void sunxi_led_enable_clk(struct sunxi_led *led)
1958 {
1959 clk_prepare_enable(led->clk_ledc);
1960 clk_prepare_enable(led->clk_cpuapb);
1961 }
1962
sunxi_led_disable_clk(struct sunxi_led * led)1963 static void sunxi_led_disable_clk(struct sunxi_led *led)
1964 {
1965 clk_disable_unprepare(led->clk_cpuapb);
1966 clk_disable_unprepare(led->clk_ledc);
1967 }
1968
sunxi_led_power_on(struct sunxi_led * led)1969 static int sunxi_led_power_on(struct sunxi_led *led)
1970 {
1971 int err;
1972
1973 if (led->regulator == NULL)
1974 return 0;
1975
1976 err = regulator_enable(led->regulator);
1977 if (err) {
1978 dev_err(led->dev, "enable regulator %s failed!\n", led->regulator_id);
1979 return err;
1980 }
1981 return 0;
1982 }
1983
sunxi_led_power_off(struct sunxi_led * led)1984 static int sunxi_led_power_off(struct sunxi_led *led)
1985 {
1986 int err;
1987
1988 if (led->regulator == NULL)
1989 return 0;
1990
1991 err = regulator_disable(led->regulator);
1992 if (err) {
1993 dev_err(led->dev, "disable regulator %s failed!\n", led->regulator_id);
1994 return err;
1995 }
1996 return 0;
1997 }
1998
sunxi_led_suspend(struct device * dev)1999 static int sunxi_led_suspend(struct device *dev)
2000 {
2001 struct platform_device *pdev = to_platform_device(dev);
2002 struct sunxi_led *led = platform_get_drvdata(pdev);
2003
2004 dev_dbg(led->dev, "[%s] enter standby\n", __func__);
2005
2006 sunxi_led_disable_irq(led);
2007
2008 sunxi_led_save_regs(led);
2009
2010 sunxi_led_gpio_state_select(led, PINCTRL_STATE_SLEEP);
2011
2012 sunxi_led_disable_clk(led);
2013
2014 reset_control_assert(led->reset);
2015
2016 sunxi_led_power_off(led);
2017
2018 return 0;
2019 }
2020
sunxi_led_resume(struct device * dev)2021 static int sunxi_led_resume(struct device *dev)
2022 {
2023 struct platform_device *pdev = to_platform_device(dev);
2024 struct sunxi_led *led = platform_get_drvdata(pdev);
2025
2026 dev_dbg(led->dev, "[%s] return from standby\n", __func__);
2027
2028 sunxi_led_power_on(led);
2029
2030 reset_control_deassert(led->reset);
2031
2032 sunxi_led_enable_clk(led);
2033
2034 sunxi_led_gpio_state_select(led, PINCTRL_STATE_DEFAULT);
2035
2036 sunxi_led_restore_regs(led);
2037
2038 sunxi_led_enable_irq(led);
2039
2040 return 0;
2041 }
2042
2043 static const struct dev_pm_ops sunxi_led_pm_ops = {
2044 .suspend = sunxi_led_suspend,
2045 .resume = sunxi_led_resume,
2046 };
2047
2048 #define SUNXI_LED_PM_OPS (&sunxi_led_pm_ops)
2049 #endif
2050
2051 static const struct of_device_id sunxi_led_dt_ids[] = {
2052 {.compatible = "allwinner,sunxi-leds"},
2053 {},
2054 };
2055
2056 static struct platform_driver sunxi_led_driver = {
2057 .probe = sunxi_led_probe,
2058 .remove = sunxi_led_remove,
2059 .driver = {
2060 .name = "sunxi-leds",
2061 .owner = THIS_MODULE,
2062 #if IS_ENABLED(CONFIG_PM)
2063 .pm = SUNXI_LED_PM_OPS,
2064 #endif
2065 .of_match_table = sunxi_led_dt_ids,
2066 },
2067 };
2068
2069 module_platform_driver(sunxi_led_driver);
2070 module_param_named(debug, debug_mask, int, 0664);
2071
2072 MODULE_ALIAS("sunxi leds dirver");
2073 MODULE_ALIAS("platform : leds dirver");
2074 MODULE_LICENSE("GPL v2");
2075 MODULE_VERSION("1.2.1");
2076 MODULE_AUTHOR("Albert Yu <yuxyun@allwinnertech.com>");
2077 MODULE_AUTHOR("liuyu <SWCliuyus@allwinnertech.com>");
2078 MODULE_DESCRIPTION("Allwinner ledc-controller driver");
2079