1
2
3
4
5
6
7
8
9
10
11
12
13#ifndef __PINCTRL_SUNXI_H
14#define __PINCTRL_SUNXI_H
15
16#include <linux/kernel.h>
17#include <linux/spinlock.h>
18
19#define PA_BASE 0
20#define PB_BASE 32
21#define PC_BASE 64
22#define PD_BASE 96
23#define PE_BASE 128
24#define PF_BASE 160
25#define PG_BASE 192
26#define PH_BASE 224
27#define PI_BASE 256
28#define PL_BASE 352
29#define PM_BASE 384
30#define PN_BASE 416
31
32#define SUNXI_PINCTRL_PIN(bank, pin) \
33 PINCTRL_PIN(P ## bank ## _BASE + (pin), "P" #bank #pin)
34
35#define SUNXI_PIN_NAME_MAX_LEN 5
36
37#define BANK_MEM_SIZE 0x24
38#define MUX_REGS_OFFSET 0x0
39#define DATA_REGS_OFFSET 0x10
40#define DLEVEL_REGS_OFFSET 0x14
41#define PULL_REGS_OFFSET 0x1c
42
43#define PINS_PER_BANK 32
44#define MUX_PINS_PER_REG 8
45#define MUX_PINS_BITS 4
46#define MUX_PINS_MASK 0x0f
47#define DATA_PINS_PER_REG 32
48#define DATA_PINS_BITS 1
49#define DATA_PINS_MASK 0x01
50#define DLEVEL_PINS_PER_REG 16
51#define DLEVEL_PINS_BITS 2
52#define DLEVEL_PINS_MASK 0x03
53#define PULL_PINS_PER_REG 16
54#define PULL_PINS_BITS 2
55#define PULL_PINS_MASK 0x03
56
57#define IRQ_PER_BANK 32
58
59#define IRQ_CFG_REG 0x200
60#define IRQ_CFG_IRQ_PER_REG 8
61#define IRQ_CFG_IRQ_BITS 4
62#define IRQ_CFG_IRQ_MASK ((1 << IRQ_CFG_IRQ_BITS) - 1)
63#define IRQ_CTRL_REG 0x210
64#define IRQ_CTRL_IRQ_PER_REG 32
65#define IRQ_CTRL_IRQ_BITS 1
66#define IRQ_CTRL_IRQ_MASK ((1 << IRQ_CTRL_IRQ_BITS) - 1)
67#define IRQ_STATUS_REG 0x214
68#define IRQ_STATUS_IRQ_PER_REG 32
69#define IRQ_STATUS_IRQ_BITS 1
70#define IRQ_STATUS_IRQ_MASK ((1 << IRQ_STATUS_IRQ_BITS) - 1)
71
72#define IRQ_DEBOUNCE_REG 0x218
73
74#define IRQ_MEM_SIZE 0x20
75
76#define IRQ_EDGE_RISING 0x00
77#define IRQ_EDGE_FALLING 0x01
78#define IRQ_LEVEL_HIGH 0x02
79#define IRQ_LEVEL_LOW 0x03
80#define IRQ_EDGE_BOTH 0x04
81
82#define SUN4I_FUNC_INPUT 0
83#define SUN4I_FUNC_IRQ 6
84
85#define PINCTRL_SUN5I_A10S BIT(1)
86#define PINCTRL_SUN5I_A13 BIT(2)
87#define PINCTRL_SUN5I_GR8 BIT(3)
88#define PINCTRL_SUN6I_A31 BIT(4)
89#define PINCTRL_SUN6I_A31S BIT(5)
90
91struct sunxi_desc_function {
92 unsigned long variant;
93 const char *name;
94 u8 muxval;
95 u8 irqbank;
96 u8 irqnum;
97};
98
99struct sunxi_desc_pin {
100 struct pinctrl_pin_desc pin;
101 unsigned long variant;
102 struct sunxi_desc_function *functions;
103};
104
105struct sunxi_pinctrl_desc {
106 const struct sunxi_desc_pin *pins;
107 int npins;
108 unsigned pin_base;
109 unsigned irq_banks;
110 unsigned irq_bank_base;
111 bool irq_read_needs_mux;
112};
113
114struct sunxi_pinctrl_function {
115 const char *name;
116 const char **groups;
117 unsigned ngroups;
118};
119
120struct sunxi_pinctrl_group {
121 const char *name;
122 unsigned pin;
123};
124
125struct sunxi_pinctrl {
126 void __iomem *membase;
127 struct gpio_chip *chip;
128 const struct sunxi_pinctrl_desc *desc;
129 struct device *dev;
130 struct irq_domain *domain;
131 struct sunxi_pinctrl_function *functions;
132 unsigned nfunctions;
133 struct sunxi_pinctrl_group *groups;
134 unsigned ngroups;
135 int *irq;
136 unsigned *irq_array;
137 raw_spinlock_t lock;
138 struct pinctrl_dev *pctl_dev;
139 unsigned long variant;
140};
141
142#define SUNXI_PIN(_pin, ...) \
143 { \
144 .pin = _pin, \
145 .functions = (struct sunxi_desc_function[]){ \
146 __VA_ARGS__, { } }, \
147 }
148
149#define SUNXI_PIN_VARIANT(_pin, _variant, ...) \
150 { \
151 .pin = _pin, \
152 .variant = _variant, \
153 .functions = (struct sunxi_desc_function[]){ \
154 __VA_ARGS__, { } }, \
155 }
156
157#define SUNXI_FUNCTION(_val, _name) \
158 { \
159 .name = _name, \
160 .muxval = _val, \
161 }
162
163#define SUNXI_FUNCTION_VARIANT(_val, _name, _variant) \
164 { \
165 .name = _name, \
166 .muxval = _val, \
167 .variant = _variant, \
168 }
169
170#define SUNXI_FUNCTION_IRQ(_val, _irq) \
171 { \
172 .name = "irq", \
173 .muxval = _val, \
174 .irqnum = _irq, \
175 }
176
177#define SUNXI_FUNCTION_IRQ_BANK(_val, _bank, _irq) \
178 { \
179 .name = "irq", \
180 .muxval = _val, \
181 .irqbank = _bank, \
182 .irqnum = _irq, \
183 }
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202static inline u32 sunxi_mux_reg(u16 pin)
203{
204 u8 bank = pin / PINS_PER_BANK;
205 u32 offset = bank * BANK_MEM_SIZE;
206 offset += MUX_REGS_OFFSET;
207 offset += pin % PINS_PER_BANK / MUX_PINS_PER_REG * 0x04;
208 return round_down(offset, 4);
209}
210
211static inline u32 sunxi_mux_offset(u16 pin)
212{
213 u32 pin_num = pin % MUX_PINS_PER_REG;
214 return pin_num * MUX_PINS_BITS;
215}
216
217static inline u32 sunxi_data_reg(u16 pin)
218{
219 u8 bank = pin / PINS_PER_BANK;
220 u32 offset = bank * BANK_MEM_SIZE;
221 offset += DATA_REGS_OFFSET;
222 offset += pin % PINS_PER_BANK / DATA_PINS_PER_REG * 0x04;
223 return round_down(offset, 4);
224}
225
226static inline u32 sunxi_data_offset(u16 pin)
227{
228 u32 pin_num = pin % DATA_PINS_PER_REG;
229 return pin_num * DATA_PINS_BITS;
230}
231
232static inline u32 sunxi_dlevel_reg(u16 pin)
233{
234 u8 bank = pin / PINS_PER_BANK;
235 u32 offset = bank * BANK_MEM_SIZE;
236 offset += DLEVEL_REGS_OFFSET;
237 offset += pin % PINS_PER_BANK / DLEVEL_PINS_PER_REG * 0x04;
238 return round_down(offset, 4);
239}
240
241static inline u32 sunxi_dlevel_offset(u16 pin)
242{
243 u32 pin_num = pin % DLEVEL_PINS_PER_REG;
244 return pin_num * DLEVEL_PINS_BITS;
245}
246
247static inline u32 sunxi_pull_reg(u16 pin)
248{
249 u8 bank = pin / PINS_PER_BANK;
250 u32 offset = bank * BANK_MEM_SIZE;
251 offset += PULL_REGS_OFFSET;
252 offset += pin % PINS_PER_BANK / PULL_PINS_PER_REG * 0x04;
253 return round_down(offset, 4);
254}
255
256static inline u32 sunxi_pull_offset(u16 pin)
257{
258 u32 pin_num = pin % PULL_PINS_PER_REG;
259 return pin_num * PULL_PINS_BITS;
260}
261
262static inline u32 sunxi_irq_cfg_reg(u16 irq, unsigned bank_base)
263{
264 u8 bank = irq / IRQ_PER_BANK;
265 u8 reg = (irq % IRQ_PER_BANK) / IRQ_CFG_IRQ_PER_REG * 0x04;
266
267 return IRQ_CFG_REG + (bank_base + bank) * IRQ_MEM_SIZE + reg;
268}
269
270static inline u32 sunxi_irq_cfg_offset(u16 irq)
271{
272 u32 irq_num = irq % IRQ_CFG_IRQ_PER_REG;
273 return irq_num * IRQ_CFG_IRQ_BITS;
274}
275
276static inline u32 sunxi_irq_ctrl_reg_from_bank(u8 bank, unsigned bank_base)
277{
278 return IRQ_CTRL_REG + (bank_base + bank) * IRQ_MEM_SIZE;
279}
280
281static inline u32 sunxi_irq_ctrl_reg(u16 irq, unsigned bank_base)
282{
283 u8 bank = irq / IRQ_PER_BANK;
284
285 return sunxi_irq_ctrl_reg_from_bank(bank, bank_base);
286}
287
288static inline u32 sunxi_irq_ctrl_offset(u16 irq)
289{
290 u32 irq_num = irq % IRQ_CTRL_IRQ_PER_REG;
291 return irq_num * IRQ_CTRL_IRQ_BITS;
292}
293
294static inline u32 sunxi_irq_debounce_reg_from_bank(u8 bank, unsigned bank_base)
295{
296 return IRQ_DEBOUNCE_REG + (bank_base + bank) * IRQ_MEM_SIZE;
297}
298
299static inline u32 sunxi_irq_status_reg_from_bank(u8 bank, unsigned bank_base)
300{
301 return IRQ_STATUS_REG + (bank_base + bank) * IRQ_MEM_SIZE;
302}
303
304static inline u32 sunxi_irq_status_reg(u16 irq, unsigned bank_base)
305{
306 u8 bank = irq / IRQ_PER_BANK;
307
308 return sunxi_irq_status_reg_from_bank(bank, bank_base);
309}
310
311static inline u32 sunxi_irq_status_offset(u16 irq)
312{
313 u32 irq_num = irq % IRQ_STATUS_IRQ_PER_REG;
314 return irq_num * IRQ_STATUS_IRQ_BITS;
315}
316
317int sunxi_pinctrl_init_with_variant(struct platform_device *pdev,
318 const struct sunxi_pinctrl_desc *desc,
319 unsigned long variant);
320
321#define sunxi_pinctrl_init(_dev, _desc) \
322 sunxi_pinctrl_init_with_variant(_dev, _desc, 0)
323
324#endif
325