• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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(&current_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