1*4882a593Smuzhiyun /*
2*4882a593Smuzhiyun * Allwinner A1X SoCs pinctrl driver.
3*4882a593Smuzhiyun *
4*4882a593Smuzhiyun * Copyright (C) 2012 Maxime Ripard
5*4882a593Smuzhiyun *
6*4882a593Smuzhiyun * Maxime Ripard <maxime.ripard@free-electrons.com>
7*4882a593Smuzhiyun *
8*4882a593Smuzhiyun * This file is licensed under the terms of the GNU General Public
9*4882a593Smuzhiyun * License version 2. This program is licensed "as is" without any
10*4882a593Smuzhiyun * warranty of any kind, whether express or implied.
11*4882a593Smuzhiyun */
12*4882a593Smuzhiyun
13*4882a593Smuzhiyun #ifndef __PINCTRL_SUNXI_H
14*4882a593Smuzhiyun #define __PINCTRL_SUNXI_H
15*4882a593Smuzhiyun
16*4882a593Smuzhiyun #include <linux/kernel.h>
17*4882a593Smuzhiyun #include <linux/spinlock.h>
18*4882a593Smuzhiyun
19*4882a593Smuzhiyun #define PA_BASE 0
20*4882a593Smuzhiyun #define PB_BASE 32
21*4882a593Smuzhiyun #define PC_BASE 64
22*4882a593Smuzhiyun #define PD_BASE 96
23*4882a593Smuzhiyun #define PE_BASE 128
24*4882a593Smuzhiyun #define PF_BASE 160
25*4882a593Smuzhiyun #define PG_BASE 192
26*4882a593Smuzhiyun #define PH_BASE 224
27*4882a593Smuzhiyun #define PI_BASE 256
28*4882a593Smuzhiyun #define PL_BASE 352
29*4882a593Smuzhiyun #define PM_BASE 384
30*4882a593Smuzhiyun #define PN_BASE 416
31*4882a593Smuzhiyun
32*4882a593Smuzhiyun #define SUNXI_PINCTRL_PIN(bank, pin) \
33*4882a593Smuzhiyun PINCTRL_PIN(P ## bank ## _BASE + (pin), "P" #bank #pin)
34*4882a593Smuzhiyun
35*4882a593Smuzhiyun #define SUNXI_PIN_NAME_MAX_LEN 5
36*4882a593Smuzhiyun
37*4882a593Smuzhiyun #define BANK_MEM_SIZE 0x24
38*4882a593Smuzhiyun #define MUX_REGS_OFFSET 0x0
39*4882a593Smuzhiyun #define DATA_REGS_OFFSET 0x10
40*4882a593Smuzhiyun #define DLEVEL_REGS_OFFSET 0x14
41*4882a593Smuzhiyun #define PULL_REGS_OFFSET 0x1c
42*4882a593Smuzhiyun
43*4882a593Smuzhiyun #define PINS_PER_BANK 32
44*4882a593Smuzhiyun #define MUX_PINS_PER_REG 8
45*4882a593Smuzhiyun #define MUX_PINS_BITS 4
46*4882a593Smuzhiyun #define MUX_PINS_MASK 0x0f
47*4882a593Smuzhiyun #define DATA_PINS_PER_REG 32
48*4882a593Smuzhiyun #define DATA_PINS_BITS 1
49*4882a593Smuzhiyun #define DATA_PINS_MASK 0x01
50*4882a593Smuzhiyun #define DLEVEL_PINS_PER_REG 16
51*4882a593Smuzhiyun #define DLEVEL_PINS_BITS 2
52*4882a593Smuzhiyun #define DLEVEL_PINS_MASK 0x03
53*4882a593Smuzhiyun #define PULL_PINS_PER_REG 16
54*4882a593Smuzhiyun #define PULL_PINS_BITS 2
55*4882a593Smuzhiyun #define PULL_PINS_MASK 0x03
56*4882a593Smuzhiyun
57*4882a593Smuzhiyun #define IRQ_PER_BANK 32
58*4882a593Smuzhiyun
59*4882a593Smuzhiyun #define IRQ_CFG_REG 0x200
60*4882a593Smuzhiyun #define IRQ_CFG_IRQ_PER_REG 8
61*4882a593Smuzhiyun #define IRQ_CFG_IRQ_BITS 4
62*4882a593Smuzhiyun #define IRQ_CFG_IRQ_MASK ((1 << IRQ_CFG_IRQ_BITS) - 1)
63*4882a593Smuzhiyun #define IRQ_CTRL_REG 0x210
64*4882a593Smuzhiyun #define IRQ_CTRL_IRQ_PER_REG 32
65*4882a593Smuzhiyun #define IRQ_CTRL_IRQ_BITS 1
66*4882a593Smuzhiyun #define IRQ_CTRL_IRQ_MASK ((1 << IRQ_CTRL_IRQ_BITS) - 1)
67*4882a593Smuzhiyun #define IRQ_STATUS_REG 0x214
68*4882a593Smuzhiyun #define IRQ_STATUS_IRQ_PER_REG 32
69*4882a593Smuzhiyun #define IRQ_STATUS_IRQ_BITS 1
70*4882a593Smuzhiyun #define IRQ_STATUS_IRQ_MASK ((1 << IRQ_STATUS_IRQ_BITS) - 1)
71*4882a593Smuzhiyun
72*4882a593Smuzhiyun #define IRQ_DEBOUNCE_REG 0x218
73*4882a593Smuzhiyun
74*4882a593Smuzhiyun #define IRQ_MEM_SIZE 0x20
75*4882a593Smuzhiyun
76*4882a593Smuzhiyun #define IRQ_EDGE_RISING 0x00
77*4882a593Smuzhiyun #define IRQ_EDGE_FALLING 0x01
78*4882a593Smuzhiyun #define IRQ_LEVEL_HIGH 0x02
79*4882a593Smuzhiyun #define IRQ_LEVEL_LOW 0x03
80*4882a593Smuzhiyun #define IRQ_EDGE_BOTH 0x04
81*4882a593Smuzhiyun
82*4882a593Smuzhiyun #define GRP_CFG_REG 0x300
83*4882a593Smuzhiyun
84*4882a593Smuzhiyun #define IO_BIAS_MASK GENMASK(3, 0)
85*4882a593Smuzhiyun
86*4882a593Smuzhiyun #define SUN4I_FUNC_INPUT 0
87*4882a593Smuzhiyun #define SUN4I_FUNC_IRQ 6
88*4882a593Smuzhiyun
89*4882a593Smuzhiyun #define PINCTRL_SUN5I_A10S BIT(1)
90*4882a593Smuzhiyun #define PINCTRL_SUN5I_A13 BIT(2)
91*4882a593Smuzhiyun #define PINCTRL_SUN5I_GR8 BIT(3)
92*4882a593Smuzhiyun #define PINCTRL_SUN6I_A31 BIT(4)
93*4882a593Smuzhiyun #define PINCTRL_SUN6I_A31S BIT(5)
94*4882a593Smuzhiyun #define PINCTRL_SUN4I_A10 BIT(6)
95*4882a593Smuzhiyun #define PINCTRL_SUN7I_A20 BIT(7)
96*4882a593Smuzhiyun #define PINCTRL_SUN8I_R40 BIT(8)
97*4882a593Smuzhiyun #define PINCTRL_SUN8I_V3 BIT(9)
98*4882a593Smuzhiyun #define PINCTRL_SUN8I_V3S BIT(10)
99*4882a593Smuzhiyun
100*4882a593Smuzhiyun #define PIO_POW_MOD_SEL_REG 0x340
101*4882a593Smuzhiyun
102*4882a593Smuzhiyun enum sunxi_desc_bias_voltage {
103*4882a593Smuzhiyun BIAS_VOLTAGE_NONE,
104*4882a593Smuzhiyun /*
105*4882a593Smuzhiyun * Bias voltage configuration is done through
106*4882a593Smuzhiyun * Pn_GRP_CONFIG registers, as seen on A80 SoC.
107*4882a593Smuzhiyun */
108*4882a593Smuzhiyun BIAS_VOLTAGE_GRP_CONFIG,
109*4882a593Smuzhiyun /*
110*4882a593Smuzhiyun * Bias voltage is set through PIO_POW_MOD_SEL_REG
111*4882a593Smuzhiyun * register, as seen on H6 SoC, for example.
112*4882a593Smuzhiyun */
113*4882a593Smuzhiyun BIAS_VOLTAGE_PIO_POW_MODE_SEL,
114*4882a593Smuzhiyun };
115*4882a593Smuzhiyun
116*4882a593Smuzhiyun struct sunxi_desc_function {
117*4882a593Smuzhiyun unsigned long variant;
118*4882a593Smuzhiyun const char *name;
119*4882a593Smuzhiyun u8 muxval;
120*4882a593Smuzhiyun u8 irqbank;
121*4882a593Smuzhiyun u8 irqnum;
122*4882a593Smuzhiyun };
123*4882a593Smuzhiyun
124*4882a593Smuzhiyun struct sunxi_desc_pin {
125*4882a593Smuzhiyun struct pinctrl_pin_desc pin;
126*4882a593Smuzhiyun unsigned long variant;
127*4882a593Smuzhiyun struct sunxi_desc_function *functions;
128*4882a593Smuzhiyun };
129*4882a593Smuzhiyun
130*4882a593Smuzhiyun struct sunxi_pinctrl_desc {
131*4882a593Smuzhiyun const struct sunxi_desc_pin *pins;
132*4882a593Smuzhiyun int npins;
133*4882a593Smuzhiyun unsigned pin_base;
134*4882a593Smuzhiyun unsigned irq_banks;
135*4882a593Smuzhiyun const unsigned int *irq_bank_map;
136*4882a593Smuzhiyun bool irq_read_needs_mux;
137*4882a593Smuzhiyun bool disable_strict_mode;
138*4882a593Smuzhiyun enum sunxi_desc_bias_voltage io_bias_cfg_variant;
139*4882a593Smuzhiyun };
140*4882a593Smuzhiyun
141*4882a593Smuzhiyun struct sunxi_pinctrl_function {
142*4882a593Smuzhiyun const char *name;
143*4882a593Smuzhiyun const char **groups;
144*4882a593Smuzhiyun unsigned ngroups;
145*4882a593Smuzhiyun };
146*4882a593Smuzhiyun
147*4882a593Smuzhiyun struct sunxi_pinctrl_group {
148*4882a593Smuzhiyun const char *name;
149*4882a593Smuzhiyun unsigned pin;
150*4882a593Smuzhiyun };
151*4882a593Smuzhiyun
152*4882a593Smuzhiyun struct sunxi_pinctrl_regulator {
153*4882a593Smuzhiyun struct regulator *regulator;
154*4882a593Smuzhiyun refcount_t refcount;
155*4882a593Smuzhiyun };
156*4882a593Smuzhiyun
157*4882a593Smuzhiyun struct sunxi_pinctrl {
158*4882a593Smuzhiyun void __iomem *membase;
159*4882a593Smuzhiyun struct gpio_chip *chip;
160*4882a593Smuzhiyun const struct sunxi_pinctrl_desc *desc;
161*4882a593Smuzhiyun struct device *dev;
162*4882a593Smuzhiyun struct sunxi_pinctrl_regulator regulators[9];
163*4882a593Smuzhiyun struct irq_domain *domain;
164*4882a593Smuzhiyun struct sunxi_pinctrl_function *functions;
165*4882a593Smuzhiyun unsigned nfunctions;
166*4882a593Smuzhiyun struct sunxi_pinctrl_group *groups;
167*4882a593Smuzhiyun unsigned ngroups;
168*4882a593Smuzhiyun int *irq;
169*4882a593Smuzhiyun unsigned *irq_array;
170*4882a593Smuzhiyun raw_spinlock_t lock;
171*4882a593Smuzhiyun struct pinctrl_dev *pctl_dev;
172*4882a593Smuzhiyun unsigned long variant;
173*4882a593Smuzhiyun };
174*4882a593Smuzhiyun
175*4882a593Smuzhiyun #define SUNXI_PIN(_pin, ...) \
176*4882a593Smuzhiyun { \
177*4882a593Smuzhiyun .pin = _pin, \
178*4882a593Smuzhiyun .functions = (struct sunxi_desc_function[]){ \
179*4882a593Smuzhiyun __VA_ARGS__, { } }, \
180*4882a593Smuzhiyun }
181*4882a593Smuzhiyun
182*4882a593Smuzhiyun #define SUNXI_PIN_VARIANT(_pin, _variant, ...) \
183*4882a593Smuzhiyun { \
184*4882a593Smuzhiyun .pin = _pin, \
185*4882a593Smuzhiyun .variant = _variant, \
186*4882a593Smuzhiyun .functions = (struct sunxi_desc_function[]){ \
187*4882a593Smuzhiyun __VA_ARGS__, { } }, \
188*4882a593Smuzhiyun }
189*4882a593Smuzhiyun
190*4882a593Smuzhiyun #define SUNXI_FUNCTION(_val, _name) \
191*4882a593Smuzhiyun { \
192*4882a593Smuzhiyun .name = _name, \
193*4882a593Smuzhiyun .muxval = _val, \
194*4882a593Smuzhiyun }
195*4882a593Smuzhiyun
196*4882a593Smuzhiyun #define SUNXI_FUNCTION_VARIANT(_val, _name, _variant) \
197*4882a593Smuzhiyun { \
198*4882a593Smuzhiyun .name = _name, \
199*4882a593Smuzhiyun .muxval = _val, \
200*4882a593Smuzhiyun .variant = _variant, \
201*4882a593Smuzhiyun }
202*4882a593Smuzhiyun
203*4882a593Smuzhiyun #define SUNXI_FUNCTION_IRQ(_val, _irq) \
204*4882a593Smuzhiyun { \
205*4882a593Smuzhiyun .name = "irq", \
206*4882a593Smuzhiyun .muxval = _val, \
207*4882a593Smuzhiyun .irqnum = _irq, \
208*4882a593Smuzhiyun }
209*4882a593Smuzhiyun
210*4882a593Smuzhiyun #define SUNXI_FUNCTION_IRQ_BANK(_val, _bank, _irq) \
211*4882a593Smuzhiyun { \
212*4882a593Smuzhiyun .name = "irq", \
213*4882a593Smuzhiyun .muxval = _val, \
214*4882a593Smuzhiyun .irqbank = _bank, \
215*4882a593Smuzhiyun .irqnum = _irq, \
216*4882a593Smuzhiyun }
217*4882a593Smuzhiyun
218*4882a593Smuzhiyun /*
219*4882a593Smuzhiyun * The sunXi PIO registers are organized as is:
220*4882a593Smuzhiyun * 0x00 - 0x0c Muxing values.
221*4882a593Smuzhiyun * 8 pins per register, each pin having a 4bits value
222*4882a593Smuzhiyun * 0x10 Pin values
223*4882a593Smuzhiyun * 32 bits per register, each pin corresponding to one bit
224*4882a593Smuzhiyun * 0x14 - 0x18 Drive level
225*4882a593Smuzhiyun * 16 pins per register, each pin having a 2bits value
226*4882a593Smuzhiyun * 0x1c - 0x20 Pull-Up values
227*4882a593Smuzhiyun * 16 pins per register, each pin having a 2bits value
228*4882a593Smuzhiyun *
229*4882a593Smuzhiyun * This is for the first bank. Each bank will have the same layout,
230*4882a593Smuzhiyun * with an offset being a multiple of 0x24.
231*4882a593Smuzhiyun *
232*4882a593Smuzhiyun * The following functions calculate from the pin number the register
233*4882a593Smuzhiyun * and the bit offset that we should access.
234*4882a593Smuzhiyun */
sunxi_mux_reg(u16 pin)235*4882a593Smuzhiyun static inline u32 sunxi_mux_reg(u16 pin)
236*4882a593Smuzhiyun {
237*4882a593Smuzhiyun u8 bank = pin / PINS_PER_BANK;
238*4882a593Smuzhiyun u32 offset = bank * BANK_MEM_SIZE;
239*4882a593Smuzhiyun offset += MUX_REGS_OFFSET;
240*4882a593Smuzhiyun offset += pin % PINS_PER_BANK / MUX_PINS_PER_REG * 0x04;
241*4882a593Smuzhiyun return round_down(offset, 4);
242*4882a593Smuzhiyun }
243*4882a593Smuzhiyun
sunxi_mux_offset(u16 pin)244*4882a593Smuzhiyun static inline u32 sunxi_mux_offset(u16 pin)
245*4882a593Smuzhiyun {
246*4882a593Smuzhiyun u32 pin_num = pin % MUX_PINS_PER_REG;
247*4882a593Smuzhiyun return pin_num * MUX_PINS_BITS;
248*4882a593Smuzhiyun }
249*4882a593Smuzhiyun
sunxi_data_reg(u16 pin)250*4882a593Smuzhiyun static inline u32 sunxi_data_reg(u16 pin)
251*4882a593Smuzhiyun {
252*4882a593Smuzhiyun u8 bank = pin / PINS_PER_BANK;
253*4882a593Smuzhiyun u32 offset = bank * BANK_MEM_SIZE;
254*4882a593Smuzhiyun offset += DATA_REGS_OFFSET;
255*4882a593Smuzhiyun offset += pin % PINS_PER_BANK / DATA_PINS_PER_REG * 0x04;
256*4882a593Smuzhiyun return round_down(offset, 4);
257*4882a593Smuzhiyun }
258*4882a593Smuzhiyun
sunxi_data_offset(u16 pin)259*4882a593Smuzhiyun static inline u32 sunxi_data_offset(u16 pin)
260*4882a593Smuzhiyun {
261*4882a593Smuzhiyun u32 pin_num = pin % DATA_PINS_PER_REG;
262*4882a593Smuzhiyun return pin_num * DATA_PINS_BITS;
263*4882a593Smuzhiyun }
264*4882a593Smuzhiyun
sunxi_dlevel_reg(u16 pin)265*4882a593Smuzhiyun static inline u32 sunxi_dlevel_reg(u16 pin)
266*4882a593Smuzhiyun {
267*4882a593Smuzhiyun u8 bank = pin / PINS_PER_BANK;
268*4882a593Smuzhiyun u32 offset = bank * BANK_MEM_SIZE;
269*4882a593Smuzhiyun offset += DLEVEL_REGS_OFFSET;
270*4882a593Smuzhiyun offset += pin % PINS_PER_BANK / DLEVEL_PINS_PER_REG * 0x04;
271*4882a593Smuzhiyun return round_down(offset, 4);
272*4882a593Smuzhiyun }
273*4882a593Smuzhiyun
sunxi_dlevel_offset(u16 pin)274*4882a593Smuzhiyun static inline u32 sunxi_dlevel_offset(u16 pin)
275*4882a593Smuzhiyun {
276*4882a593Smuzhiyun u32 pin_num = pin % DLEVEL_PINS_PER_REG;
277*4882a593Smuzhiyun return pin_num * DLEVEL_PINS_BITS;
278*4882a593Smuzhiyun }
279*4882a593Smuzhiyun
sunxi_pull_reg(u16 pin)280*4882a593Smuzhiyun static inline u32 sunxi_pull_reg(u16 pin)
281*4882a593Smuzhiyun {
282*4882a593Smuzhiyun u8 bank = pin / PINS_PER_BANK;
283*4882a593Smuzhiyun u32 offset = bank * BANK_MEM_SIZE;
284*4882a593Smuzhiyun offset += PULL_REGS_OFFSET;
285*4882a593Smuzhiyun offset += pin % PINS_PER_BANK / PULL_PINS_PER_REG * 0x04;
286*4882a593Smuzhiyun return round_down(offset, 4);
287*4882a593Smuzhiyun }
288*4882a593Smuzhiyun
sunxi_pull_offset(u16 pin)289*4882a593Smuzhiyun static inline u32 sunxi_pull_offset(u16 pin)
290*4882a593Smuzhiyun {
291*4882a593Smuzhiyun u32 pin_num = pin % PULL_PINS_PER_REG;
292*4882a593Smuzhiyun return pin_num * PULL_PINS_BITS;
293*4882a593Smuzhiyun }
294*4882a593Smuzhiyun
sunxi_irq_hw_bank_num(const struct sunxi_pinctrl_desc * desc,u8 bank)295*4882a593Smuzhiyun static inline u32 sunxi_irq_hw_bank_num(const struct sunxi_pinctrl_desc *desc, u8 bank)
296*4882a593Smuzhiyun {
297*4882a593Smuzhiyun if (!desc->irq_bank_map)
298*4882a593Smuzhiyun return bank;
299*4882a593Smuzhiyun else
300*4882a593Smuzhiyun return desc->irq_bank_map[bank];
301*4882a593Smuzhiyun }
302*4882a593Smuzhiyun
sunxi_irq_cfg_reg(const struct sunxi_pinctrl_desc * desc,u16 irq)303*4882a593Smuzhiyun static inline u32 sunxi_irq_cfg_reg(const struct sunxi_pinctrl_desc *desc,
304*4882a593Smuzhiyun u16 irq)
305*4882a593Smuzhiyun {
306*4882a593Smuzhiyun u8 bank = irq / IRQ_PER_BANK;
307*4882a593Smuzhiyun u8 reg = (irq % IRQ_PER_BANK) / IRQ_CFG_IRQ_PER_REG * 0x04;
308*4882a593Smuzhiyun
309*4882a593Smuzhiyun return IRQ_CFG_REG +
310*4882a593Smuzhiyun sunxi_irq_hw_bank_num(desc, bank) * IRQ_MEM_SIZE + reg;
311*4882a593Smuzhiyun }
312*4882a593Smuzhiyun
sunxi_irq_cfg_offset(u16 irq)313*4882a593Smuzhiyun static inline u32 sunxi_irq_cfg_offset(u16 irq)
314*4882a593Smuzhiyun {
315*4882a593Smuzhiyun u32 irq_num = irq % IRQ_CFG_IRQ_PER_REG;
316*4882a593Smuzhiyun return irq_num * IRQ_CFG_IRQ_BITS;
317*4882a593Smuzhiyun }
318*4882a593Smuzhiyun
sunxi_irq_ctrl_reg_from_bank(const struct sunxi_pinctrl_desc * desc,u8 bank)319*4882a593Smuzhiyun static inline u32 sunxi_irq_ctrl_reg_from_bank(const struct sunxi_pinctrl_desc *desc, u8 bank)
320*4882a593Smuzhiyun {
321*4882a593Smuzhiyun return IRQ_CTRL_REG + sunxi_irq_hw_bank_num(desc, bank) * IRQ_MEM_SIZE;
322*4882a593Smuzhiyun }
323*4882a593Smuzhiyun
sunxi_irq_ctrl_reg(const struct sunxi_pinctrl_desc * desc,u16 irq)324*4882a593Smuzhiyun static inline u32 sunxi_irq_ctrl_reg(const struct sunxi_pinctrl_desc *desc,
325*4882a593Smuzhiyun u16 irq)
326*4882a593Smuzhiyun {
327*4882a593Smuzhiyun u8 bank = irq / IRQ_PER_BANK;
328*4882a593Smuzhiyun
329*4882a593Smuzhiyun return sunxi_irq_ctrl_reg_from_bank(desc, bank);
330*4882a593Smuzhiyun }
331*4882a593Smuzhiyun
sunxi_irq_ctrl_offset(u16 irq)332*4882a593Smuzhiyun static inline u32 sunxi_irq_ctrl_offset(u16 irq)
333*4882a593Smuzhiyun {
334*4882a593Smuzhiyun u32 irq_num = irq % IRQ_CTRL_IRQ_PER_REG;
335*4882a593Smuzhiyun return irq_num * IRQ_CTRL_IRQ_BITS;
336*4882a593Smuzhiyun }
337*4882a593Smuzhiyun
sunxi_irq_debounce_reg_from_bank(const struct sunxi_pinctrl_desc * desc,u8 bank)338*4882a593Smuzhiyun static inline u32 sunxi_irq_debounce_reg_from_bank(const struct sunxi_pinctrl_desc *desc, u8 bank)
339*4882a593Smuzhiyun {
340*4882a593Smuzhiyun return IRQ_DEBOUNCE_REG +
341*4882a593Smuzhiyun sunxi_irq_hw_bank_num(desc, bank) * IRQ_MEM_SIZE;
342*4882a593Smuzhiyun }
343*4882a593Smuzhiyun
sunxi_irq_status_reg_from_bank(const struct sunxi_pinctrl_desc * desc,u8 bank)344*4882a593Smuzhiyun static inline u32 sunxi_irq_status_reg_from_bank(const struct sunxi_pinctrl_desc *desc, u8 bank)
345*4882a593Smuzhiyun {
346*4882a593Smuzhiyun return IRQ_STATUS_REG +
347*4882a593Smuzhiyun sunxi_irq_hw_bank_num(desc, bank) * IRQ_MEM_SIZE;
348*4882a593Smuzhiyun }
349*4882a593Smuzhiyun
sunxi_irq_status_reg(const struct sunxi_pinctrl_desc * desc,u16 irq)350*4882a593Smuzhiyun static inline u32 sunxi_irq_status_reg(const struct sunxi_pinctrl_desc *desc,
351*4882a593Smuzhiyun u16 irq)
352*4882a593Smuzhiyun {
353*4882a593Smuzhiyun u8 bank = irq / IRQ_PER_BANK;
354*4882a593Smuzhiyun
355*4882a593Smuzhiyun return sunxi_irq_status_reg_from_bank(desc, bank);
356*4882a593Smuzhiyun }
357*4882a593Smuzhiyun
sunxi_irq_status_offset(u16 irq)358*4882a593Smuzhiyun static inline u32 sunxi_irq_status_offset(u16 irq)
359*4882a593Smuzhiyun {
360*4882a593Smuzhiyun u32 irq_num = irq % IRQ_STATUS_IRQ_PER_REG;
361*4882a593Smuzhiyun return irq_num * IRQ_STATUS_IRQ_BITS;
362*4882a593Smuzhiyun }
363*4882a593Smuzhiyun
sunxi_grp_config_reg(u16 pin)364*4882a593Smuzhiyun static inline u32 sunxi_grp_config_reg(u16 pin)
365*4882a593Smuzhiyun {
366*4882a593Smuzhiyun u8 bank = pin / PINS_PER_BANK;
367*4882a593Smuzhiyun
368*4882a593Smuzhiyun return GRP_CFG_REG + bank * 0x4;
369*4882a593Smuzhiyun }
370*4882a593Smuzhiyun
371*4882a593Smuzhiyun int sunxi_pinctrl_init_with_variant(struct platform_device *pdev,
372*4882a593Smuzhiyun const struct sunxi_pinctrl_desc *desc,
373*4882a593Smuzhiyun unsigned long variant);
374*4882a593Smuzhiyun
375*4882a593Smuzhiyun #define sunxi_pinctrl_init(_dev, _desc) \
376*4882a593Smuzhiyun sunxi_pinctrl_init_with_variant(_dev, _desc, 0)
377*4882a593Smuzhiyun
378*4882a593Smuzhiyun #endif /* __PINCTRL_SUNXI_H */
379