1*4882a593Smuzhiyun /*
2*4882a593Smuzhiyun * Atmel PIO pinctrl driver
3*4882a593Smuzhiyun *
4*4882a593Smuzhiyun * Copyright (C) 2016 Atmel Corporation
5*4882a593Smuzhiyun * Wenyou.Yang <wenyou.yang@atmel.com>
6*4882a593Smuzhiyun *
7*4882a593Smuzhiyun * SPDX-License-Identifier: GPL-2.0+
8*4882a593Smuzhiyun */
9*4882a593Smuzhiyun
10*4882a593Smuzhiyun #include <common.h>
11*4882a593Smuzhiyun #include <dm.h>
12*4882a593Smuzhiyun #include <dm/pinctrl.h>
13*4882a593Smuzhiyun #include <linux/io.h>
14*4882a593Smuzhiyun #include <linux/err.h>
15*4882a593Smuzhiyun #include <mach/at91_pio.h>
16*4882a593Smuzhiyun
17*4882a593Smuzhiyun DECLARE_GLOBAL_DATA_PTR;
18*4882a593Smuzhiyun
19*4882a593Smuzhiyun #define MAX_GPIO_BANKS 5
20*4882a593Smuzhiyun #define MAX_NB_GPIO_PER_BANK 32
21*4882a593Smuzhiyun
22*4882a593Smuzhiyun #define MAX_PINMUX_ENTRIES 200
23*4882a593Smuzhiyun
24*4882a593Smuzhiyun struct at91_pinctrl_priv {
25*4882a593Smuzhiyun struct at91_port *reg_base[MAX_GPIO_BANKS];
26*4882a593Smuzhiyun u32 nbanks;
27*4882a593Smuzhiyun };
28*4882a593Smuzhiyun
29*4882a593Smuzhiyun #define PULL_UP BIT(0)
30*4882a593Smuzhiyun #define MULTI_DRIVE BIT(1)
31*4882a593Smuzhiyun #define DEGLITCH BIT(2)
32*4882a593Smuzhiyun #define PULL_DOWN BIT(3)
33*4882a593Smuzhiyun #define DIS_SCHMIT BIT(4)
34*4882a593Smuzhiyun #define DRIVE_STRENGTH_SHIFT 5
35*4882a593Smuzhiyun #define DRIVE_STRENGTH_MASK 0x3
36*4882a593Smuzhiyun #define DRIVE_STRENGTH (DRIVE_STRENGTH_MASK << DRIVE_STRENGTH_SHIFT)
37*4882a593Smuzhiyun #define OUTPUT BIT(7)
38*4882a593Smuzhiyun #define OUTPUT_VAL_SHIFT 8
39*4882a593Smuzhiyun #define OUTPUT_VAL (0x1 << OUTPUT_VAL_SHIFT)
40*4882a593Smuzhiyun #define DEBOUNCE BIT(16)
41*4882a593Smuzhiyun #define DEBOUNCE_VAL_SHIFT 17
42*4882a593Smuzhiyun #define DEBOUNCE_VAL (0x3fff << DEBOUNCE_VAL_SHIFT)
43*4882a593Smuzhiyun
44*4882a593Smuzhiyun /**
45*4882a593Smuzhiyun * These defines will translated the dt binding settings to our internal
46*4882a593Smuzhiyun * settings. They are not necessarily the same value as the register setting.
47*4882a593Smuzhiyun * The actual drive strength current of low, medium and high must be looked up
48*4882a593Smuzhiyun * from the corresponding device datasheet. This value is different for pins
49*4882a593Smuzhiyun * that are even in the same banks. It is also dependent on VCC.
50*4882a593Smuzhiyun * DRIVE_STRENGTH_DEFAULT is just a placeholder to avoid changing the drive
51*4882a593Smuzhiyun * strength when there is no dt config for it.
52*4882a593Smuzhiyun */
53*4882a593Smuzhiyun #define DRIVE_STRENGTH_DEFAULT (0 << DRIVE_STRENGTH_SHIFT)
54*4882a593Smuzhiyun #define DRIVE_STRENGTH_LOW (1 << DRIVE_STRENGTH_SHIFT)
55*4882a593Smuzhiyun #define DRIVE_STRENGTH_MED (2 << DRIVE_STRENGTH_SHIFT)
56*4882a593Smuzhiyun #define DRIVE_STRENGTH_HI (3 << DRIVE_STRENGTH_SHIFT)
57*4882a593Smuzhiyun
58*4882a593Smuzhiyun enum at91_mux {
59*4882a593Smuzhiyun AT91_MUX_GPIO = 0,
60*4882a593Smuzhiyun AT91_MUX_PERIPH_A = 1,
61*4882a593Smuzhiyun AT91_MUX_PERIPH_B = 2,
62*4882a593Smuzhiyun AT91_MUX_PERIPH_C = 3,
63*4882a593Smuzhiyun AT91_MUX_PERIPH_D = 4,
64*4882a593Smuzhiyun };
65*4882a593Smuzhiyun
66*4882a593Smuzhiyun /**
67*4882a593Smuzhiyun * struct at91_pinctrl_mux_ops - describes an AT91 mux ops group
68*4882a593Smuzhiyun * on new IP with support for periph C and D the way to mux in
69*4882a593Smuzhiyun * periph A and B has changed
70*4882a593Smuzhiyun * So provide the right callbacks
71*4882a593Smuzhiyun * if not present means the IP does not support it
72*4882a593Smuzhiyun * @mux_A_periph: assign the corresponding pin to the peripheral A function.
73*4882a593Smuzhiyun * @mux_B_periph: assign the corresponding pin to the peripheral B function.
74*4882a593Smuzhiyun * @mux_C_periph: assign the corresponding pin to the peripheral C function.
75*4882a593Smuzhiyun * @mux_D_periph: assign the corresponding pin to the peripheral D function.
76*4882a593Smuzhiyun * @set_deglitch: enable/disable the deglitch feature.
77*4882a593Smuzhiyun * @set_debounce: enable/disable the debounce feature.
78*4882a593Smuzhiyun * @set_pulldown: enable/disable the pulldown feature.
79*4882a593Smuzhiyun * @disable_schmitt_trig: disable schmitt trigger
80*4882a593Smuzhiyun */
81*4882a593Smuzhiyun struct at91_pinctrl_mux_ops {
82*4882a593Smuzhiyun void (*mux_A_periph)(struct at91_port *pio, u32 mask);
83*4882a593Smuzhiyun void (*mux_B_periph)(struct at91_port *pio, u32 mask);
84*4882a593Smuzhiyun void (*mux_C_periph)(struct at91_port *pio, u32 mask);
85*4882a593Smuzhiyun void (*mux_D_periph)(struct at91_port *pio, u32 mask);
86*4882a593Smuzhiyun void (*set_deglitch)(struct at91_port *pio, u32 mask, bool is_on);
87*4882a593Smuzhiyun void (*set_debounce)(struct at91_port *pio, u32 mask, bool is_on,
88*4882a593Smuzhiyun u32 div);
89*4882a593Smuzhiyun void (*set_pulldown)(struct at91_port *pio, u32 mask, bool is_on);
90*4882a593Smuzhiyun void (*disable_schmitt_trig)(struct at91_port *pio, u32 mask);
91*4882a593Smuzhiyun void (*set_drivestrength)(struct at91_port *pio, u32 pin,
92*4882a593Smuzhiyun u32 strength);
93*4882a593Smuzhiyun };
94*4882a593Smuzhiyun
two_bit_pin_value_shift_amount(u32 pin)95*4882a593Smuzhiyun static u32 two_bit_pin_value_shift_amount(u32 pin)
96*4882a593Smuzhiyun {
97*4882a593Smuzhiyun /* return the shift value for a pin for "two bit" per pin registers,
98*4882a593Smuzhiyun * i.e. drive strength */
99*4882a593Smuzhiyun return 2 * ((pin >= MAX_NB_GPIO_PER_BANK/2)
100*4882a593Smuzhiyun ? pin - MAX_NB_GPIO_PER_BANK/2 : pin);
101*4882a593Smuzhiyun }
102*4882a593Smuzhiyun
at91_mux_disable_interrupt(struct at91_port * pio,u32 mask)103*4882a593Smuzhiyun static void at91_mux_disable_interrupt(struct at91_port *pio, u32 mask)
104*4882a593Smuzhiyun {
105*4882a593Smuzhiyun writel(mask, &pio->idr);
106*4882a593Smuzhiyun }
107*4882a593Smuzhiyun
at91_mux_set_pullup(struct at91_port * pio,u32 mask,bool on)108*4882a593Smuzhiyun static void at91_mux_set_pullup(struct at91_port *pio, u32 mask, bool on)
109*4882a593Smuzhiyun {
110*4882a593Smuzhiyun if (on)
111*4882a593Smuzhiyun writel(mask, &pio->mux.pio3.ppddr);
112*4882a593Smuzhiyun
113*4882a593Smuzhiyun writel(mask, (on ? &pio->puer : &pio->pudr));
114*4882a593Smuzhiyun }
115*4882a593Smuzhiyun
at91_mux_set_output(struct at91_port * pio,unsigned mask,bool is_on,bool val)116*4882a593Smuzhiyun static void at91_mux_set_output(struct at91_port *pio, unsigned mask,
117*4882a593Smuzhiyun bool is_on, bool val)
118*4882a593Smuzhiyun {
119*4882a593Smuzhiyun writel(mask, (val ? &pio->sodr : &pio->codr));
120*4882a593Smuzhiyun writel(mask, (is_on ? &pio->oer : &pio->odr));
121*4882a593Smuzhiyun }
122*4882a593Smuzhiyun
at91_mux_set_multidrive(struct at91_port * pio,u32 mask,bool on)123*4882a593Smuzhiyun static void at91_mux_set_multidrive(struct at91_port *pio, u32 mask, bool on)
124*4882a593Smuzhiyun {
125*4882a593Smuzhiyun writel(mask, (on ? &pio->mder : &pio->mddr));
126*4882a593Smuzhiyun }
127*4882a593Smuzhiyun
at91_mux_set_A_periph(struct at91_port * pio,u32 mask)128*4882a593Smuzhiyun static void at91_mux_set_A_periph(struct at91_port *pio, u32 mask)
129*4882a593Smuzhiyun {
130*4882a593Smuzhiyun writel(mask, &pio->mux.pio2.asr);
131*4882a593Smuzhiyun }
132*4882a593Smuzhiyun
at91_mux_set_B_periph(struct at91_port * pio,u32 mask)133*4882a593Smuzhiyun static void at91_mux_set_B_periph(struct at91_port *pio, u32 mask)
134*4882a593Smuzhiyun {
135*4882a593Smuzhiyun writel(mask, &pio->mux.pio2.bsr);
136*4882a593Smuzhiyun }
137*4882a593Smuzhiyun
at91_mux_pio3_set_A_periph(struct at91_port * pio,u32 mask)138*4882a593Smuzhiyun static void at91_mux_pio3_set_A_periph(struct at91_port *pio, u32 mask)
139*4882a593Smuzhiyun {
140*4882a593Smuzhiyun writel(readl(&pio->mux.pio3.abcdsr1) & ~mask, &pio->mux.pio3.abcdsr1);
141*4882a593Smuzhiyun writel(readl(&pio->mux.pio3.abcdsr2) & ~mask, &pio->mux.pio3.abcdsr2);
142*4882a593Smuzhiyun }
143*4882a593Smuzhiyun
at91_mux_pio3_set_B_periph(struct at91_port * pio,u32 mask)144*4882a593Smuzhiyun static void at91_mux_pio3_set_B_periph(struct at91_port *pio, u32 mask)
145*4882a593Smuzhiyun {
146*4882a593Smuzhiyun writel(readl(&pio->mux.pio3.abcdsr1) | mask, &pio->mux.pio3.abcdsr1);
147*4882a593Smuzhiyun writel(readl(&pio->mux.pio3.abcdsr2) & ~mask, &pio->mux.pio3.abcdsr2);
148*4882a593Smuzhiyun }
149*4882a593Smuzhiyun
at91_mux_pio3_set_C_periph(struct at91_port * pio,u32 mask)150*4882a593Smuzhiyun static void at91_mux_pio3_set_C_periph(struct at91_port *pio, u32 mask)
151*4882a593Smuzhiyun {
152*4882a593Smuzhiyun writel(readl(&pio->mux.pio3.abcdsr1) & ~mask, &pio->mux.pio3.abcdsr1);
153*4882a593Smuzhiyun writel(readl(&pio->mux.pio3.abcdsr2) | mask, &pio->mux.pio3.abcdsr2);
154*4882a593Smuzhiyun }
155*4882a593Smuzhiyun
at91_mux_pio3_set_D_periph(struct at91_port * pio,u32 mask)156*4882a593Smuzhiyun static void at91_mux_pio3_set_D_periph(struct at91_port *pio, u32 mask)
157*4882a593Smuzhiyun {
158*4882a593Smuzhiyun writel(readl(&pio->mux.pio3.abcdsr1) | mask, &pio->mux.pio3.abcdsr1);
159*4882a593Smuzhiyun writel(readl(&pio->mux.pio3.abcdsr2) | mask, &pio->mux.pio3.abcdsr2);
160*4882a593Smuzhiyun }
161*4882a593Smuzhiyun
at91_mux_set_deglitch(struct at91_port * pio,u32 mask,bool is_on)162*4882a593Smuzhiyun static void at91_mux_set_deglitch(struct at91_port *pio, u32 mask, bool is_on)
163*4882a593Smuzhiyun {
164*4882a593Smuzhiyun writel(mask, (is_on ? &pio->ifer : &pio->ifdr));
165*4882a593Smuzhiyun }
166*4882a593Smuzhiyun
at91_mux_pio3_set_deglitch(struct at91_port * pio,u32 mask,bool is_on)167*4882a593Smuzhiyun static void at91_mux_pio3_set_deglitch(struct at91_port *pio,
168*4882a593Smuzhiyun u32 mask, bool is_on)
169*4882a593Smuzhiyun {
170*4882a593Smuzhiyun if (is_on)
171*4882a593Smuzhiyun writel(mask, &pio->mux.pio3.ifscdr);
172*4882a593Smuzhiyun at91_mux_set_deglitch(pio, mask, is_on);
173*4882a593Smuzhiyun }
174*4882a593Smuzhiyun
at91_mux_pio3_set_debounce(struct at91_port * pio,u32 mask,bool is_on,u32 div)175*4882a593Smuzhiyun static void at91_mux_pio3_set_debounce(struct at91_port *pio, u32 mask,
176*4882a593Smuzhiyun bool is_on, u32 div)
177*4882a593Smuzhiyun {
178*4882a593Smuzhiyun if (is_on) {
179*4882a593Smuzhiyun writel(mask, &pio->mux.pio3.ifscer);
180*4882a593Smuzhiyun writel(div & PIO_SCDR_DIV, &pio->mux.pio3.scdr);
181*4882a593Smuzhiyun writel(mask, &pio->ifer);
182*4882a593Smuzhiyun } else {
183*4882a593Smuzhiyun writel(mask, &pio->mux.pio3.ifscdr);
184*4882a593Smuzhiyun }
185*4882a593Smuzhiyun }
186*4882a593Smuzhiyun
at91_mux_pio3_set_pulldown(struct at91_port * pio,u32 mask,bool is_on)187*4882a593Smuzhiyun static void at91_mux_pio3_set_pulldown(struct at91_port *pio,
188*4882a593Smuzhiyun u32 mask, bool is_on)
189*4882a593Smuzhiyun {
190*4882a593Smuzhiyun if (is_on)
191*4882a593Smuzhiyun writel(mask, &pio->pudr);
192*4882a593Smuzhiyun
193*4882a593Smuzhiyun writel(mask, (is_on ? &pio->mux.pio3.ppder : &pio->mux.pio3.ppddr));
194*4882a593Smuzhiyun }
195*4882a593Smuzhiyun
at91_mux_pio3_disable_schmitt_trig(struct at91_port * pio,u32 mask)196*4882a593Smuzhiyun static void at91_mux_pio3_disable_schmitt_trig(struct at91_port *pio,
197*4882a593Smuzhiyun u32 mask)
198*4882a593Smuzhiyun {
199*4882a593Smuzhiyun writel(readl(&pio->schmitt) | mask, &pio->schmitt);
200*4882a593Smuzhiyun }
201*4882a593Smuzhiyun
set_drive_strength(void * reg,u32 pin,u32 strength)202*4882a593Smuzhiyun static void set_drive_strength(void *reg, u32 pin, u32 strength)
203*4882a593Smuzhiyun {
204*4882a593Smuzhiyun u32 shift = two_bit_pin_value_shift_amount(pin);
205*4882a593Smuzhiyun
206*4882a593Smuzhiyun clrsetbits_le32(reg, DRIVE_STRENGTH_MASK << shift, strength << shift);
207*4882a593Smuzhiyun }
208*4882a593Smuzhiyun
at91_mux_sama5d3_set_drivestrength(struct at91_port * pio,u32 pin,u32 setting)209*4882a593Smuzhiyun static void at91_mux_sama5d3_set_drivestrength(struct at91_port *pio,
210*4882a593Smuzhiyun u32 pin, u32 setting)
211*4882a593Smuzhiyun {
212*4882a593Smuzhiyun void *reg;
213*4882a593Smuzhiyun
214*4882a593Smuzhiyun reg = &pio->driver12;
215*4882a593Smuzhiyun if (pin >= MAX_NB_GPIO_PER_BANK / 2)
216*4882a593Smuzhiyun reg = &pio->driver2;
217*4882a593Smuzhiyun
218*4882a593Smuzhiyun /* do nothing if setting is zero */
219*4882a593Smuzhiyun if (!setting)
220*4882a593Smuzhiyun return;
221*4882a593Smuzhiyun
222*4882a593Smuzhiyun /* strength is 1 to 1 with setting for SAMA5 */
223*4882a593Smuzhiyun set_drive_strength(reg, pin, setting);
224*4882a593Smuzhiyun }
225*4882a593Smuzhiyun
at91_mux_sam9x5_set_drivestrength(struct at91_port * pio,u32 pin,u32 setting)226*4882a593Smuzhiyun static void at91_mux_sam9x5_set_drivestrength(struct at91_port *pio,
227*4882a593Smuzhiyun u32 pin, u32 setting)
228*4882a593Smuzhiyun {
229*4882a593Smuzhiyun void *reg;
230*4882a593Smuzhiyun
231*4882a593Smuzhiyun reg = &pio->driver1;
232*4882a593Smuzhiyun if (pin >= MAX_NB_GPIO_PER_BANK / 2)
233*4882a593Smuzhiyun reg = &pio->driver12;
234*4882a593Smuzhiyun
235*4882a593Smuzhiyun /* do nothing if setting is zero */
236*4882a593Smuzhiyun if (!setting)
237*4882a593Smuzhiyun return;
238*4882a593Smuzhiyun
239*4882a593Smuzhiyun /* strength is inverse on SAM9x5s with our defines
240*4882a593Smuzhiyun * 0 = hi, 1 = med, 2 = low, 3 = rsvd */
241*4882a593Smuzhiyun setting = DRIVE_STRENGTH_HI - setting;
242*4882a593Smuzhiyun
243*4882a593Smuzhiyun set_drive_strength(reg, pin, setting);
244*4882a593Smuzhiyun }
245*4882a593Smuzhiyun
246*4882a593Smuzhiyun static struct at91_pinctrl_mux_ops at91rm9200_ops = {
247*4882a593Smuzhiyun .mux_A_periph = at91_mux_set_A_periph,
248*4882a593Smuzhiyun .mux_B_periph = at91_mux_set_B_periph,
249*4882a593Smuzhiyun .set_deglitch = at91_mux_set_deglitch,
250*4882a593Smuzhiyun };
251*4882a593Smuzhiyun
252*4882a593Smuzhiyun static struct at91_pinctrl_mux_ops at91sam9x5_ops = {
253*4882a593Smuzhiyun .mux_A_periph = at91_mux_pio3_set_A_periph,
254*4882a593Smuzhiyun .mux_B_periph = at91_mux_pio3_set_B_periph,
255*4882a593Smuzhiyun .mux_C_periph = at91_mux_pio3_set_C_periph,
256*4882a593Smuzhiyun .mux_D_periph = at91_mux_pio3_set_D_periph,
257*4882a593Smuzhiyun .set_deglitch = at91_mux_pio3_set_deglitch,
258*4882a593Smuzhiyun .set_debounce = at91_mux_pio3_set_debounce,
259*4882a593Smuzhiyun .set_pulldown = at91_mux_pio3_set_pulldown,
260*4882a593Smuzhiyun .disable_schmitt_trig = at91_mux_pio3_disable_schmitt_trig,
261*4882a593Smuzhiyun .set_drivestrength = at91_mux_sam9x5_set_drivestrength,
262*4882a593Smuzhiyun };
263*4882a593Smuzhiyun
264*4882a593Smuzhiyun static struct at91_pinctrl_mux_ops sama5d3_ops = {
265*4882a593Smuzhiyun .mux_A_periph = at91_mux_pio3_set_A_periph,
266*4882a593Smuzhiyun .mux_B_periph = at91_mux_pio3_set_B_periph,
267*4882a593Smuzhiyun .mux_C_periph = at91_mux_pio3_set_C_periph,
268*4882a593Smuzhiyun .mux_D_periph = at91_mux_pio3_set_D_periph,
269*4882a593Smuzhiyun .set_deglitch = at91_mux_pio3_set_deglitch,
270*4882a593Smuzhiyun .set_debounce = at91_mux_pio3_set_debounce,
271*4882a593Smuzhiyun .set_pulldown = at91_mux_pio3_set_pulldown,
272*4882a593Smuzhiyun .disable_schmitt_trig = at91_mux_pio3_disable_schmitt_trig,
273*4882a593Smuzhiyun .set_drivestrength = at91_mux_sama5d3_set_drivestrength,
274*4882a593Smuzhiyun };
275*4882a593Smuzhiyun
at91_mux_gpio_disable(struct at91_port * pio,u32 mask)276*4882a593Smuzhiyun static void at91_mux_gpio_disable(struct at91_port *pio, u32 mask)
277*4882a593Smuzhiyun {
278*4882a593Smuzhiyun writel(mask, &pio->pdr);
279*4882a593Smuzhiyun }
280*4882a593Smuzhiyun
at91_mux_gpio_enable(struct at91_port * pio,u32 mask,bool input)281*4882a593Smuzhiyun static void at91_mux_gpio_enable(struct at91_port *pio, u32 mask, bool input)
282*4882a593Smuzhiyun {
283*4882a593Smuzhiyun writel(mask, &pio->per);
284*4882a593Smuzhiyun writel(mask, (input ? &pio->odr : &pio->oer));
285*4882a593Smuzhiyun }
286*4882a593Smuzhiyun
at91_pmx_set(struct at91_pinctrl_mux_ops * ops,struct at91_port * pio,u32 mask,enum at91_mux mux)287*4882a593Smuzhiyun static int at91_pmx_set(struct at91_pinctrl_mux_ops *ops,
288*4882a593Smuzhiyun struct at91_port *pio, u32 mask, enum at91_mux mux)
289*4882a593Smuzhiyun {
290*4882a593Smuzhiyun at91_mux_disable_interrupt(pio, mask);
291*4882a593Smuzhiyun switch (mux) {
292*4882a593Smuzhiyun case AT91_MUX_GPIO:
293*4882a593Smuzhiyun at91_mux_gpio_enable(pio, mask, 1);
294*4882a593Smuzhiyun break;
295*4882a593Smuzhiyun case AT91_MUX_PERIPH_A:
296*4882a593Smuzhiyun ops->mux_A_periph(pio, mask);
297*4882a593Smuzhiyun break;
298*4882a593Smuzhiyun case AT91_MUX_PERIPH_B:
299*4882a593Smuzhiyun ops->mux_B_periph(pio, mask);
300*4882a593Smuzhiyun break;
301*4882a593Smuzhiyun case AT91_MUX_PERIPH_C:
302*4882a593Smuzhiyun if (!ops->mux_C_periph)
303*4882a593Smuzhiyun return -EINVAL;
304*4882a593Smuzhiyun ops->mux_C_periph(pio, mask);
305*4882a593Smuzhiyun break;
306*4882a593Smuzhiyun case AT91_MUX_PERIPH_D:
307*4882a593Smuzhiyun if (!ops->mux_D_periph)
308*4882a593Smuzhiyun return -EINVAL;
309*4882a593Smuzhiyun ops->mux_D_periph(pio, mask);
310*4882a593Smuzhiyun break;
311*4882a593Smuzhiyun }
312*4882a593Smuzhiyun if (mux)
313*4882a593Smuzhiyun at91_mux_gpio_disable(pio, mask);
314*4882a593Smuzhiyun
315*4882a593Smuzhiyun return 0;
316*4882a593Smuzhiyun }
317*4882a593Smuzhiyun
at91_pinconf_set(struct at91_pinctrl_mux_ops * ops,struct at91_port * pio,u32 pin,u32 config)318*4882a593Smuzhiyun static int at91_pinconf_set(struct at91_pinctrl_mux_ops *ops,
319*4882a593Smuzhiyun struct at91_port *pio, u32 pin, u32 config)
320*4882a593Smuzhiyun {
321*4882a593Smuzhiyun u32 mask = BIT(pin);
322*4882a593Smuzhiyun
323*4882a593Smuzhiyun if ((config & PULL_UP) && (config & PULL_DOWN))
324*4882a593Smuzhiyun return -EINVAL;
325*4882a593Smuzhiyun
326*4882a593Smuzhiyun at91_mux_set_output(pio, mask, config & OUTPUT,
327*4882a593Smuzhiyun (config & OUTPUT_VAL) >> OUTPUT_VAL_SHIFT);
328*4882a593Smuzhiyun at91_mux_set_pullup(pio, mask, config & PULL_UP);
329*4882a593Smuzhiyun at91_mux_set_multidrive(pio, mask, config & MULTI_DRIVE);
330*4882a593Smuzhiyun if (ops->set_deglitch)
331*4882a593Smuzhiyun ops->set_deglitch(pio, mask, config & DEGLITCH);
332*4882a593Smuzhiyun if (ops->set_debounce)
333*4882a593Smuzhiyun ops->set_debounce(pio, mask, config & DEBOUNCE,
334*4882a593Smuzhiyun (config & DEBOUNCE_VAL) >> DEBOUNCE_VAL_SHIFT);
335*4882a593Smuzhiyun if (ops->set_pulldown)
336*4882a593Smuzhiyun ops->set_pulldown(pio, mask, config & PULL_DOWN);
337*4882a593Smuzhiyun if (ops->disable_schmitt_trig && config & DIS_SCHMIT)
338*4882a593Smuzhiyun ops->disable_schmitt_trig(pio, mask);
339*4882a593Smuzhiyun if (ops->set_drivestrength)
340*4882a593Smuzhiyun ops->set_drivestrength(pio, pin,
341*4882a593Smuzhiyun (config & DRIVE_STRENGTH) >> DRIVE_STRENGTH_SHIFT);
342*4882a593Smuzhiyun
343*4882a593Smuzhiyun return 0;
344*4882a593Smuzhiyun }
345*4882a593Smuzhiyun
at91_pin_check_config(struct udevice * dev,u32 bank,u32 pin)346*4882a593Smuzhiyun static int at91_pin_check_config(struct udevice *dev, u32 bank, u32 pin)
347*4882a593Smuzhiyun {
348*4882a593Smuzhiyun struct at91_pinctrl_priv *priv = dev_get_priv(dev);
349*4882a593Smuzhiyun
350*4882a593Smuzhiyun if (bank >= priv->nbanks) {
351*4882a593Smuzhiyun debug("pin conf bank %d >= nbanks %d\n", bank, priv->nbanks);
352*4882a593Smuzhiyun return -EINVAL;
353*4882a593Smuzhiyun }
354*4882a593Smuzhiyun
355*4882a593Smuzhiyun if (pin >= MAX_NB_GPIO_PER_BANK) {
356*4882a593Smuzhiyun debug("pin conf pin %d >= %d\n", pin, MAX_NB_GPIO_PER_BANK);
357*4882a593Smuzhiyun return -EINVAL;
358*4882a593Smuzhiyun }
359*4882a593Smuzhiyun
360*4882a593Smuzhiyun return 0;
361*4882a593Smuzhiyun }
362*4882a593Smuzhiyun
at91_pinctrl_set_state(struct udevice * dev,struct udevice * config)363*4882a593Smuzhiyun static int at91_pinctrl_set_state(struct udevice *dev, struct udevice *config)
364*4882a593Smuzhiyun {
365*4882a593Smuzhiyun struct at91_pinctrl_priv *priv = dev_get_priv(dev);
366*4882a593Smuzhiyun const void *blob = gd->fdt_blob;
367*4882a593Smuzhiyun int node = dev_of_offset(config);
368*4882a593Smuzhiyun u32 cells[MAX_PINMUX_ENTRIES];
369*4882a593Smuzhiyun const u32 *list = cells;
370*4882a593Smuzhiyun u32 bank, pin;
371*4882a593Smuzhiyun u32 conf, mask, count, i;
372*4882a593Smuzhiyun int size;
373*4882a593Smuzhiyun int ret;
374*4882a593Smuzhiyun enum at91_mux mux;
375*4882a593Smuzhiyun struct at91_port *pio;
376*4882a593Smuzhiyun struct at91_pinctrl_mux_ops *ops =
377*4882a593Smuzhiyun (struct at91_pinctrl_mux_ops *)dev_get_driver_data(dev);
378*4882a593Smuzhiyun
379*4882a593Smuzhiyun /*
380*4882a593Smuzhiyun * the binding format is atmel,pins = <bank pin mux CONFIG ...>,
381*4882a593Smuzhiyun * do sanity check and calculate pins number
382*4882a593Smuzhiyun */
383*4882a593Smuzhiyun size = fdtdec_get_int_array_count(blob, node, "atmel,pins",
384*4882a593Smuzhiyun cells, ARRAY_SIZE(cells));
385*4882a593Smuzhiyun
386*4882a593Smuzhiyun /* we do not check return since it's safe node passed down */
387*4882a593Smuzhiyun count = size >> 2;
388*4882a593Smuzhiyun if (!count)
389*4882a593Smuzhiyun return -EINVAL;
390*4882a593Smuzhiyun
391*4882a593Smuzhiyun for (i = 0; i < count; i++) {
392*4882a593Smuzhiyun bank = *list++;
393*4882a593Smuzhiyun pin = *list++;
394*4882a593Smuzhiyun mux = *list++;
395*4882a593Smuzhiyun conf = *list++;
396*4882a593Smuzhiyun
397*4882a593Smuzhiyun ret = at91_pin_check_config(dev, bank, pin);
398*4882a593Smuzhiyun if (ret)
399*4882a593Smuzhiyun return ret;
400*4882a593Smuzhiyun
401*4882a593Smuzhiyun pio = priv->reg_base[bank];
402*4882a593Smuzhiyun mask = BIT(pin);
403*4882a593Smuzhiyun
404*4882a593Smuzhiyun ret = at91_pmx_set(ops, pio, mask, mux);
405*4882a593Smuzhiyun if (ret)
406*4882a593Smuzhiyun return ret;
407*4882a593Smuzhiyun
408*4882a593Smuzhiyun ret = at91_pinconf_set(ops, pio, pin, conf);
409*4882a593Smuzhiyun if (ret)
410*4882a593Smuzhiyun return ret;
411*4882a593Smuzhiyun }
412*4882a593Smuzhiyun
413*4882a593Smuzhiyun return 0;
414*4882a593Smuzhiyun }
415*4882a593Smuzhiyun
416*4882a593Smuzhiyun const struct pinctrl_ops at91_pinctrl_ops = {
417*4882a593Smuzhiyun .set_state = at91_pinctrl_set_state,
418*4882a593Smuzhiyun };
419*4882a593Smuzhiyun
at91_pinctrl_probe(struct udevice * dev)420*4882a593Smuzhiyun static int at91_pinctrl_probe(struct udevice *dev)
421*4882a593Smuzhiyun {
422*4882a593Smuzhiyun struct at91_pinctrl_priv *priv = dev_get_priv(dev);
423*4882a593Smuzhiyun fdt_addr_t addr_base;
424*4882a593Smuzhiyun int index;
425*4882a593Smuzhiyun
426*4882a593Smuzhiyun for (index = 0; index < MAX_GPIO_BANKS; index++) {
427*4882a593Smuzhiyun addr_base = devfdt_get_addr_index(dev, index);
428*4882a593Smuzhiyun if (addr_base == FDT_ADDR_T_NONE)
429*4882a593Smuzhiyun break;
430*4882a593Smuzhiyun
431*4882a593Smuzhiyun priv->reg_base[index] = (struct at91_port *)addr_base;
432*4882a593Smuzhiyun }
433*4882a593Smuzhiyun
434*4882a593Smuzhiyun priv->nbanks = index;
435*4882a593Smuzhiyun
436*4882a593Smuzhiyun return 0;
437*4882a593Smuzhiyun }
438*4882a593Smuzhiyun
439*4882a593Smuzhiyun static const struct udevice_id at91_pinctrl_match[] = {
440*4882a593Smuzhiyun { .compatible = "atmel,sama5d3-pinctrl", .data = (ulong)&sama5d3_ops },
441*4882a593Smuzhiyun { .compatible = "atmel,at91sam9x5-pinctrl", .data = (ulong)&at91sam9x5_ops },
442*4882a593Smuzhiyun { .compatible = "atmel,at91rm9200-pinctrl", .data = (ulong)&at91rm9200_ops },
443*4882a593Smuzhiyun {}
444*4882a593Smuzhiyun };
445*4882a593Smuzhiyun
446*4882a593Smuzhiyun U_BOOT_DRIVER(at91_pinctrl) = {
447*4882a593Smuzhiyun .name = "pinctrl_at91",
448*4882a593Smuzhiyun .id = UCLASS_PINCTRL,
449*4882a593Smuzhiyun .of_match = at91_pinctrl_match,
450*4882a593Smuzhiyun .probe = at91_pinctrl_probe,
451*4882a593Smuzhiyun .priv_auto_alloc_size = sizeof(struct at91_pinctrl_priv),
452*4882a593Smuzhiyun .ops = &at91_pinctrl_ops,
453*4882a593Smuzhiyun };
454