1 /*
2 * Allwinner A1X SoCs pinctrl driver.
3 *
4 * Copyright (C) 2012 Maxime Ripard
5 *
6 * Maxime Ripard <maxime.ripard@free-electrons.com>
7 *
8 * This file is licensed under the terms of the GNU General Public
9 * License version 2. This program is licensed "as is" without any
10 * warranty of any kind, whether express or implied.
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 PJ_BASE 288
29 #define PK_BASE 320
30 #define PL_BASE 352
31 #define PM_BASE 384
32 #define PN_BASE 416
33
34 /* maximum number of banks per controller (PA -> PK) */
35 #define SUNXI_PINCTRL_MAX_BANKS 11
36
37 #define SUNXI_PINCTRL_PIN(bank, pin) \
38 PINCTRL_PIN(P ## bank ## _BASE + (pin), "P" #bank #pin)
39
40 #define SUNXI_PIN_NAME_MAX_LEN 5
41
42 #define BANK_MEM_SIZE 0x24
43 #define MUX_REGS_OFFSET 0x0
44 #define MUX_FIELD_WIDTH 4
45 #define DATA_REGS_OFFSET 0x10
46 #define DATA_FIELD_WIDTH 1
47 #define DLEVEL_REGS_OFFSET 0x14
48 #define DLEVEL_FIELD_WIDTH 2
49 #define PULL_REGS_OFFSET 0x1c
50 #define PULL_FIELD_WIDTH 2
51
52 #define D1_BANK_MEM_SIZE 0x30
53 #define D1_DLEVEL_FIELD_WIDTH 4
54 #define D1_PULL_REGS_OFFSET 0x24
55
56 #define PINS_PER_BANK 32
57
58 #define IRQ_PER_BANK 32
59
60 #define IRQ_CFG_REG 0x200
61 #define IRQ_CFG_IRQ_PER_REG 8
62 #define IRQ_CFG_IRQ_BITS 4
63 #define IRQ_CFG_IRQ_MASK ((1 << IRQ_CFG_IRQ_BITS) - 1)
64 #define IRQ_CTRL_REG 0x210
65 #define IRQ_CTRL_IRQ_PER_REG 32
66 #define IRQ_CTRL_IRQ_BITS 1
67 #define IRQ_CTRL_IRQ_MASK ((1 << IRQ_CTRL_IRQ_BITS) - 1)
68 #define IRQ_STATUS_REG 0x214
69 #define IRQ_STATUS_IRQ_PER_REG 32
70 #define IRQ_STATUS_IRQ_BITS 1
71 #define IRQ_STATUS_IRQ_MASK ((1 << IRQ_STATUS_IRQ_BITS) - 1)
72
73 #define IRQ_DEBOUNCE_REG 0x218
74
75 #define IRQ_MEM_SIZE 0x20
76
77 #define IRQ_EDGE_RISING 0x00
78 #define IRQ_EDGE_FALLING 0x01
79 #define IRQ_LEVEL_HIGH 0x02
80 #define IRQ_LEVEL_LOW 0x03
81 #define IRQ_EDGE_BOTH 0x04
82
83 #define GRP_CFG_REG 0x300
84
85 #define IO_BIAS_MASK GENMASK(3, 0)
86
87 #define SUN4I_FUNC_INPUT 0
88 #define SUN4I_FUNC_IRQ 6
89 #define SUN4I_FUNC_DISABLED_OLD 7
90 #define SUN4I_FUNC_DISABLED_NEW 15
91
92 #define SUNXI_PINCTRL_VARIANT_MASK GENMASK(7, 0)
93 #define SUNXI_PINCTRL_NEW_REG_LAYOUT BIT(8)
94 #define SUNXI_PINCTRL_PORTF_SWITCH BIT(9)
95 #define SUNXI_PINCTRL_ELEVEN_BANKS BIT(10)
96
97 #define PIO_POW_MOD_SEL_REG 0x340
98 #define PIO_11B_POW_MOD_SEL_REG 0x380
99 #define PIO_POW_MOD_CTL_OFS 0x004
100
101 #define PIO_BANK_K_OFFSET 0x500
102
103 enum sunxi_desc_bias_voltage {
104 BIAS_VOLTAGE_NONE,
105 /*
106 * Bias voltage configuration is done through
107 * Pn_GRP_CONFIG registers, as seen on A80 SoC.
108 */
109 BIAS_VOLTAGE_GRP_CONFIG,
110 /*
111 * Bias voltage is set through PIO_POW_MOD_SEL_REG
112 * register, as seen on H6 SoC, for example.
113 */
114 BIAS_VOLTAGE_PIO_POW_MODE_SEL,
115 /*
116 * Bias voltage is set through PIO_POW_MOD_SEL_REG
117 * and PIO_POW_MOD_CTL_REG register, as seen on
118 * A100 and D1 SoC, for example.
119 */
120 BIAS_VOLTAGE_PIO_POW_MODE_CTL,
121 };
122
123 struct sunxi_desc_function {
124 unsigned long variant;
125 const char *name;
126 u8 muxval;
127 u8 irqbank;
128 u8 irqnum;
129 };
130
131 struct sunxi_desc_pin {
132 struct pinctrl_pin_desc pin;
133 unsigned long variant;
134 struct sunxi_desc_function *functions;
135 };
136
137 struct sunxi_pinctrl_desc {
138 const struct sunxi_desc_pin *pins;
139 int npins;
140 unsigned pin_base;
141 unsigned irq_banks;
142 const unsigned int *irq_bank_map;
143 bool irq_read_needs_mux;
144 bool disable_strict_mode;
145 enum sunxi_desc_bias_voltage io_bias_cfg_variant;
146 };
147
148 struct sunxi_pinctrl_function {
149 const char *name;
150 const char **groups;
151 unsigned ngroups;
152 };
153
154 struct sunxi_pinctrl_group {
155 const char *name;
156 unsigned pin;
157 };
158
159 struct sunxi_pinctrl_regulator {
160 struct regulator *regulator;
161 refcount_t refcount;
162 };
163
164 struct sunxi_pinctrl {
165 void __iomem *membase;
166 struct gpio_chip *chip;
167 const struct sunxi_pinctrl_desc *desc;
168 struct device *dev;
169 struct sunxi_pinctrl_regulator regulators[11];
170 struct irq_domain *domain;
171 struct sunxi_pinctrl_function *functions;
172 unsigned nfunctions;
173 struct sunxi_pinctrl_group *groups;
174 unsigned ngroups;
175 int *irq;
176 unsigned *irq_array;
177 raw_spinlock_t lock;
178 struct pinctrl_dev *pctl_dev;
179 unsigned long flags;
180 u32 bank_mem_size;
181 u32 pull_regs_offset;
182 u32 dlevel_field_width;
183 u32 pow_mod_sel_offset;
184 };
185
186 #define SUNXI_PIN(_pin, ...) \
187 { \
188 .pin = _pin, \
189 .functions = (struct sunxi_desc_function[]){ \
190 __VA_ARGS__, { } }, \
191 }
192
193 #define SUNXI_PIN_VARIANT(_pin, _variant, ...) \
194 { \
195 .pin = _pin, \
196 .variant = _variant, \
197 .functions = (struct sunxi_desc_function[]){ \
198 __VA_ARGS__, { } }, \
199 }
200
201 #define SUNXI_FUNCTION(_val, _name) \
202 { \
203 .name = _name, \
204 .muxval = _val, \
205 }
206
207 #define SUNXI_FUNCTION_VARIANT(_val, _name, _variant) \
208 { \
209 .name = _name, \
210 .muxval = _val, \
211 .variant = _variant, \
212 }
213
214 #define SUNXI_FUNCTION_IRQ(_val, _irq) \
215 { \
216 .name = "irq", \
217 .muxval = _val, \
218 .irqnum = _irq, \
219 }
220
221 #define SUNXI_FUNCTION_IRQ_BANK(_val, _bank, _irq) \
222 { \
223 .name = "irq", \
224 .muxval = _val, \
225 .irqbank = _bank, \
226 .irqnum = _irq, \
227 }
228
sunxi_irq_hw_bank_num(const struct sunxi_pinctrl_desc * desc,u8 bank)229 static inline u32 sunxi_irq_hw_bank_num(const struct sunxi_pinctrl_desc *desc, u8 bank)
230 {
231 if (!desc->irq_bank_map)
232 return bank;
233 else
234 return desc->irq_bank_map[bank];
235 }
236
sunxi_irq_cfg_reg(const struct sunxi_pinctrl_desc * desc,u16 irq)237 static inline u32 sunxi_irq_cfg_reg(const struct sunxi_pinctrl_desc *desc,
238 u16 irq)
239 {
240 u8 bank = irq / IRQ_PER_BANK;
241 u8 reg = (irq % IRQ_PER_BANK) / IRQ_CFG_IRQ_PER_REG * 0x04;
242
243 return IRQ_CFG_REG +
244 sunxi_irq_hw_bank_num(desc, bank) * IRQ_MEM_SIZE + reg;
245 }
246
sunxi_irq_cfg_offset(u16 irq)247 static inline u32 sunxi_irq_cfg_offset(u16 irq)
248 {
249 u32 irq_num = irq % IRQ_CFG_IRQ_PER_REG;
250 return irq_num * IRQ_CFG_IRQ_BITS;
251 }
252
sunxi_irq_ctrl_reg_from_bank(const struct sunxi_pinctrl_desc * desc,u8 bank)253 static inline u32 sunxi_irq_ctrl_reg_from_bank(const struct sunxi_pinctrl_desc *desc, u8 bank)
254 {
255 return IRQ_CTRL_REG + sunxi_irq_hw_bank_num(desc, bank) * IRQ_MEM_SIZE;
256 }
257
sunxi_irq_ctrl_reg(const struct sunxi_pinctrl_desc * desc,u16 irq)258 static inline u32 sunxi_irq_ctrl_reg(const struct sunxi_pinctrl_desc *desc,
259 u16 irq)
260 {
261 u8 bank = irq / IRQ_PER_BANK;
262
263 return sunxi_irq_ctrl_reg_from_bank(desc, bank);
264 }
265
sunxi_irq_ctrl_offset(u16 irq)266 static inline u32 sunxi_irq_ctrl_offset(u16 irq)
267 {
268 u32 irq_num = irq % IRQ_CTRL_IRQ_PER_REG;
269 return irq_num * IRQ_CTRL_IRQ_BITS;
270 }
271
sunxi_irq_debounce_reg_from_bank(const struct sunxi_pinctrl_desc * desc,u8 bank)272 static inline u32 sunxi_irq_debounce_reg_from_bank(const struct sunxi_pinctrl_desc *desc, u8 bank)
273 {
274 return IRQ_DEBOUNCE_REG +
275 sunxi_irq_hw_bank_num(desc, bank) * IRQ_MEM_SIZE;
276 }
277
sunxi_irq_status_reg_from_bank(const struct sunxi_pinctrl_desc * desc,u8 bank)278 static inline u32 sunxi_irq_status_reg_from_bank(const struct sunxi_pinctrl_desc *desc, u8 bank)
279 {
280 return IRQ_STATUS_REG +
281 sunxi_irq_hw_bank_num(desc, bank) * IRQ_MEM_SIZE;
282 }
283
sunxi_irq_status_reg(const struct sunxi_pinctrl_desc * desc,u16 irq)284 static inline u32 sunxi_irq_status_reg(const struct sunxi_pinctrl_desc *desc,
285 u16 irq)
286 {
287 u8 bank = irq / IRQ_PER_BANK;
288
289 return sunxi_irq_status_reg_from_bank(desc, bank);
290 }
291
sunxi_irq_status_offset(u16 irq)292 static inline u32 sunxi_irq_status_offset(u16 irq)
293 {
294 u32 irq_num = irq % IRQ_STATUS_IRQ_PER_REG;
295 return irq_num * IRQ_STATUS_IRQ_BITS;
296 }
297
sunxi_grp_config_reg(u16 pin)298 static inline u32 sunxi_grp_config_reg(u16 pin)
299 {
300 u8 bank = pin / PINS_PER_BANK;
301
302 return GRP_CFG_REG + bank * 0x4;
303 }
304
305 int sunxi_pinctrl_init_with_flags(struct platform_device *pdev,
306 const struct sunxi_pinctrl_desc *desc,
307 unsigned long flags);
308
309 #define sunxi_pinctrl_init(_dev, _desc) \
310 sunxi_pinctrl_init_with_flags(_dev, _desc, 0)
311
312 int sunxi_pinctrl_dt_table_init(struct platform_device *pdev,
313 const u8 *pins_per_bank,
314 const u8 *irq_bank_muxes,
315 struct sunxi_pinctrl_desc *desc,
316 unsigned long flags);
317
318 #endif /* __PINCTRL_SUNXI_H */
319