• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2018 Allwinner Technology Limited. All rights reserved.
3  * Albert Yu <yuxyun@allwinnertech.com>
4  *
5  * This program is free software; you can redistribute it and/or modify
6  * it under the terms of the GNU General Public License version 2 as
7  * published by the Free Software Foundation.
8  *
9  */
10 #ifndef __LINUX_LEDS_SUNXI_H
11 #define __LINUX_LEDS_SUNXI_H
12 
13 #include <linux/device.h>
14 #include <linux/list.h>
15 #include <linux/mutex.h>
16 #include <linux/rwsem.h>
17 #include <linux/spinlock.h>
18 #include <linux/timer.h>
19 #include <linux/workqueue.h>
20 
21 #define HEXADECIMAL	(0x10)
22 #define REG_INTERVAL	(0x04)
23 #define REG_CL		(0x0c)
24 
25 #define RESULT_COMPLETE	1
26 #define RESULT_ERR	2
27 
28 #define SUNXI_LEDC_REG_BASE_ADDR 0x06700000
29 
30 #define SUNXI_MAX_LED_COUNT 1024
31 
32 #define SUNXI_DEFAULT_LED_COUNT 8
33 
34 #define SUNXI_RESET_TIME_MIN_NS 84
35 #define SUNXI_RESET_TIME_MAX_NS 327000
36 
37 #define SUNXI_T1H_MIN_NS 84
38 #define SUNXI_T1H_MAX_NS 2560
39 
40 #define SUNXI_T1L_MIN_NS 84
41 #define SUNXI_T1L_MAX_NS 1280
42 
43 #define SUNXI_T0H_MIN_NS 84
44 #define SUNXI_T0H_MAX_NS 1280
45 
46 #define SUNXI_T0L_MIN_NS 84
47 #define SUNXI_T0L_MAX_NS 2560
48 
49 #define SUNXI_WAIT_TIME0_MIN_NS 84
50 #define SUNXI_WAIT_TIME0_MAX_NS 10000
51 
52 #define SUNXI_WAIT_TIME1_MIN_NS 84
53 #define SUNXI_WAIT_TIME1_MAX_NS 85000000000
54 
55 #define SUNXI_WAIT_DATA_TIME_MIN_NS 84
56 #define SUNXI_WAIT_DATA_TIME_MAX_NS_IC 655000
57 #define SUNXI_WAIT_DATA_TIME_MAX_NS_FPGA 20000000
58 
59 #define SUNXI_LEDC_FIFO_DEPTH 32 /* 32 * 4 bytes */
60 #define SUNXI_LEDC_FIFO_TRIG_LEVEL 15
61 
62 #if defined(CONFIG_FPGA_V4_PLATFORM) || defined(CONFIG_FPGA_V7_PLATFORM)
63 #define SUNXI_FPGA_LEDC
64 #endif
65 
66 enum sunxi_ledc_output_mode_val {
67 	SUNXI_OUTPUT_GRB = 0 << 6,
68 	SUNXI_OUTPUT_GBR = 1 << 6,
69 	SUNXI_OUTPUT_RGB = 2 << 6,
70 	SUNXI_OUTPUT_RBG = 3 << 6,
71 	SUNXI_OUTPUT_BGR = 4 << 6,
72 	SUNXI_OUTPUT_BRG = 5 << 6
73 };
74 
75 struct sunxi_ledc_output_mode {
76 	char *str;
77 	enum sunxi_ledc_output_mode_val val;
78 };
79 
80 enum sunxi_ledc_trans_mode_val {
81 	LEDC_TRANS_CPU_MODE,
82 	LEDC_TRANS_DMA_MODE
83 };
84 
85 enum sunxi_ledc_reg {
86 	LEDC_CTRL_REG_OFFSET              = 0x00,
87 	LED_T01_TIMING_CTRL_REG_OFFSET    = 0x04,
88 	LEDC_DATA_FINISH_CNT_REG_OFFSET   = 0x08,
89 	LED_RESET_TIMING_CTRL_REG_OFFSET  = 0x0c,
90 	LEDC_WAIT_TIME0_CTRL_REG          = 0x10,
91 	LEDC_DATA_REG_OFFSET              = 0x14,
92 	LEDC_DMA_CTRL_REG                 = 0x18,
93 	LEDC_INT_CTRL_REG_OFFSET          = 0x1c,
94 	LEDC_INT_STS_REG_OFFSET           = 0x20,
95 	LEDC_WAIT_TIME1_CTRL_REG          = 0x28,
96 	LEDC_VER_NUM_REG                  = 0x2c,
97 	LEDC_FIFO_DATA                    = 0x30,
98 	LEDC_TOTAL_REG_SIZE = LEDC_FIFO_DATA + SUNXI_LEDC_FIFO_DEPTH
99 };
100 
101 enum sunxi_ledc_irq_ctrl_reg {
102 	LEDC_TRANS_FINISH_INT_EN     = (1 << 0),
103 	LEDC_FIFO_CPUREQ_INT_EN      = (1 << 1),
104 	LEDC_WAITDATA_TIMEOUT_INT_EN = (1 << 3),
105 	LEDC_FIFO_OVERFLOW_INT_EN    = (1 << 4),
106 	LEDC_GLOBAL_INT_EN           = (1 << 5),
107 };
108 
109 enum sunxi_ledc_irq_status_reg {
110 	LEDC_TRANS_FINISH_INT     = (1 << 0),
111 	LEDC_FIFO_CPUREQ_INT      = (1 << 1),
112 	LEDC_WAITDATA_TIMEOUT_INT = (1 << 3),
113 	LEDC_FIFO_OVERFLOW_INT    = (1 << 4),
114 	LEDC_FIFO_FULL            = (1 << 16),
115 	LEDC_FIFO_EMPTY           = (1 << 17),
116 };
117 
118 enum sunxi_led_type {
119 	LED_TYPE_R,
120 	LED_TYPE_G,
121 	LED_TYPE_B
122 };
123 
124 struct sunxi_led_info {
125 	enum sunxi_led_type type;
126 	struct led_classdev cdev;
127 };
128 
129 struct sunxi_led_classdev_group {
130 	u32 led_num;
131 	struct sunxi_led_info r;
132 	struct sunxi_led_info g;
133 	struct sunxi_led_info b;
134 };
135 
136 static u32 sunxi_led_regs_offset[] = {
137 	LEDC_CTRL_REG_OFFSET,
138 	LED_RESET_TIMING_CTRL_REG_OFFSET,
139 	LED_T01_TIMING_CTRL_REG_OFFSET,
140 	LEDC_WAIT_TIME0_CTRL_REG,
141 	LEDC_WAIT_TIME1_CTRL_REG,
142 	LEDC_INT_CTRL_REG_OFFSET,
143 #ifndef SUNXI_FPGA_LEDC
144 	LEDC_DATA_FINISH_CNT_REG_OFFSET,
145 #endif
146 };
147 
148 struct sunxi_led {
149 	u32 reset_ns;
150 	u32 t1h_ns;
151 	u32 t1l_ns;
152 	u32 t0h_ns;
153 	u32 t0l_ns;
154 	u32 wait_time0_ns;
155 	unsigned long long wait_time1_ns;
156 	u32 wait_data_time_ns;
157 	u32 irqnum;
158 	u32 led_count;
159 	u32 *data;
160 	u32 length;
161 	u8 result;
162 	spinlock_t lock;
163 	struct device *dev;
164 	dma_addr_t src_dma;
165 	struct dma_chan *dma_chan;
166 	wait_queue_head_t wait;
167 	struct timespec64 start_time;
168 	struct clk *clk_ledc;
169 	struct clk *clk_cpuapb;
170 	struct pinctrl *pctrl;
171 	void __iomem *iomem_reg_base;
172 	struct resource	*res;
173 	struct sunxi_ledc_output_mode output_mode;
174 	struct sunxi_led_classdev_group *pcdev_group;
175 	struct dentry *debugfs_dir;
176 	char regulator_id[16];
177 	struct regulator *regulator;
178 	struct reset_control *reset;
179 	u32 regs_backup[ARRAY_SIZE(sunxi_led_regs_offset)];
180 };
181 
182 enum {
183 	DEBUG_INIT    = 1U << 0,
184 	DEBUG_SUSPEND = 1U << 1,
185 	DEBUG_INFO    = 1U << 2,
186 	DEBUG_INFO1   = 1U << 3,
187 	DEBUG_INFO2   = 1U << 4,
188 };
189 
190 #endif /* __LINUX_LEDS_SUNXI_H */
191