1*4882a593Smuzhiyun // SPDX-License-Identifier: GPL-2.0-only
2*4882a593Smuzhiyun /*
3*4882a593Smuzhiyun * Copyright (C) 2014-2017 Broadcom
4*4882a593Smuzhiyun */
5*4882a593Smuzhiyun
6*4882a593Smuzhiyun /*
7*4882a593Smuzhiyun * This file contains the Broadcom Iproc GPIO driver that supports 3
8*4882a593Smuzhiyun * GPIO controllers on Iproc including the ASIU GPIO controller, the
9*4882a593Smuzhiyun * chipCommonG GPIO controller, and the always-on GPIO controller. Basic
10*4882a593Smuzhiyun * PINCONF such as bias pull up/down, and drive strength are also supported
11*4882a593Smuzhiyun * in this driver.
12*4882a593Smuzhiyun *
13*4882a593Smuzhiyun * It provides the functionality where pins from the GPIO can be
14*4882a593Smuzhiyun * individually muxed to GPIO function, if individual pad
15*4882a593Smuzhiyun * configuration is supported, through the interaction with respective
16*4882a593Smuzhiyun * SoCs IOMUX controller.
17*4882a593Smuzhiyun */
18*4882a593Smuzhiyun
19*4882a593Smuzhiyun #include <linux/kernel.h>
20*4882a593Smuzhiyun #include <linux/slab.h>
21*4882a593Smuzhiyun #include <linux/interrupt.h>
22*4882a593Smuzhiyun #include <linux/io.h>
23*4882a593Smuzhiyun #include <linux/gpio/driver.h>
24*4882a593Smuzhiyun #include <linux/ioport.h>
25*4882a593Smuzhiyun #include <linux/of_device.h>
26*4882a593Smuzhiyun #include <linux/of_irq.h>
27*4882a593Smuzhiyun #include <linux/pinctrl/pinctrl.h>
28*4882a593Smuzhiyun #include <linux/pinctrl/pinconf.h>
29*4882a593Smuzhiyun #include <linux/pinctrl/pinconf-generic.h>
30*4882a593Smuzhiyun
31*4882a593Smuzhiyun #include "../pinctrl-utils.h"
32*4882a593Smuzhiyun
33*4882a593Smuzhiyun #define IPROC_GPIO_DATA_IN_OFFSET 0x00
34*4882a593Smuzhiyun #define IPROC_GPIO_DATA_OUT_OFFSET 0x04
35*4882a593Smuzhiyun #define IPROC_GPIO_OUT_EN_OFFSET 0x08
36*4882a593Smuzhiyun #define IPROC_GPIO_INT_TYPE_OFFSET 0x0c
37*4882a593Smuzhiyun #define IPROC_GPIO_INT_DE_OFFSET 0x10
38*4882a593Smuzhiyun #define IPROC_GPIO_INT_EDGE_OFFSET 0x14
39*4882a593Smuzhiyun #define IPROC_GPIO_INT_MSK_OFFSET 0x18
40*4882a593Smuzhiyun #define IPROC_GPIO_INT_STAT_OFFSET 0x1c
41*4882a593Smuzhiyun #define IPROC_GPIO_INT_MSTAT_OFFSET 0x20
42*4882a593Smuzhiyun #define IPROC_GPIO_INT_CLR_OFFSET 0x24
43*4882a593Smuzhiyun #define IPROC_GPIO_PAD_RES_OFFSET 0x34
44*4882a593Smuzhiyun #define IPROC_GPIO_RES_EN_OFFSET 0x38
45*4882a593Smuzhiyun
46*4882a593Smuzhiyun /* drive strength control for ASIU GPIO */
47*4882a593Smuzhiyun #define IPROC_GPIO_ASIU_DRV0_CTRL_OFFSET 0x58
48*4882a593Smuzhiyun
49*4882a593Smuzhiyun /* pinconf for CCM GPIO */
50*4882a593Smuzhiyun #define IPROC_GPIO_PULL_DN_OFFSET 0x10
51*4882a593Smuzhiyun #define IPROC_GPIO_PULL_UP_OFFSET 0x14
52*4882a593Smuzhiyun
53*4882a593Smuzhiyun /* pinconf for CRMU(aon) GPIO and CCM GPIO*/
54*4882a593Smuzhiyun #define IPROC_GPIO_DRV_CTRL_OFFSET 0x00
55*4882a593Smuzhiyun
56*4882a593Smuzhiyun #define GPIO_BANK_SIZE 0x200
57*4882a593Smuzhiyun #define NGPIOS_PER_BANK 32
58*4882a593Smuzhiyun #define GPIO_BANK(pin) ((pin) / NGPIOS_PER_BANK)
59*4882a593Smuzhiyun
60*4882a593Smuzhiyun #define IPROC_GPIO_REG(pin, reg) (GPIO_BANK(pin) * GPIO_BANK_SIZE + (reg))
61*4882a593Smuzhiyun #define IPROC_GPIO_SHIFT(pin) ((pin) % NGPIOS_PER_BANK)
62*4882a593Smuzhiyun
63*4882a593Smuzhiyun #define GPIO_DRV_STRENGTH_BIT_SHIFT 20
64*4882a593Smuzhiyun #define GPIO_DRV_STRENGTH_BITS 3
65*4882a593Smuzhiyun #define GPIO_DRV_STRENGTH_BIT_MASK ((1 << GPIO_DRV_STRENGTH_BITS) - 1)
66*4882a593Smuzhiyun
67*4882a593Smuzhiyun enum iproc_pinconf_param {
68*4882a593Smuzhiyun IPROC_PINCONF_DRIVE_STRENGTH = 0,
69*4882a593Smuzhiyun IPROC_PINCONF_BIAS_DISABLE,
70*4882a593Smuzhiyun IPROC_PINCONF_BIAS_PULL_UP,
71*4882a593Smuzhiyun IPROC_PINCONF_BIAS_PULL_DOWN,
72*4882a593Smuzhiyun IPROC_PINCON_MAX,
73*4882a593Smuzhiyun };
74*4882a593Smuzhiyun
75*4882a593Smuzhiyun enum iproc_pinconf_ctrl_type {
76*4882a593Smuzhiyun IOCTRL_TYPE_AON = 1,
77*4882a593Smuzhiyun IOCTRL_TYPE_CDRU,
78*4882a593Smuzhiyun IOCTRL_TYPE_INVALID,
79*4882a593Smuzhiyun };
80*4882a593Smuzhiyun
81*4882a593Smuzhiyun /*
82*4882a593Smuzhiyun * Iproc GPIO core
83*4882a593Smuzhiyun *
84*4882a593Smuzhiyun * @dev: pointer to device
85*4882a593Smuzhiyun * @base: I/O register base for Iproc GPIO controller
86*4882a593Smuzhiyun * @io_ctrl: I/O register base for certain type of Iproc GPIO controller that
87*4882a593Smuzhiyun * has the PINCONF support implemented outside of the GPIO block
88*4882a593Smuzhiyun * @lock: lock to protect access to I/O registers
89*4882a593Smuzhiyun * @gc: GPIO chip
90*4882a593Smuzhiyun * @num_banks: number of GPIO banks, each bank supports up to 32 GPIOs
91*4882a593Smuzhiyun * @pinmux_is_supported: flag to indicate this GPIO controller contains pins
92*4882a593Smuzhiyun * that can be individually muxed to GPIO
93*4882a593Smuzhiyun * @pinconf_disable: contains a list of PINCONF parameters that need to be
94*4882a593Smuzhiyun * disabled
95*4882a593Smuzhiyun * @nr_pinconf_disable: total number of PINCONF parameters that need to be
96*4882a593Smuzhiyun * disabled
97*4882a593Smuzhiyun * @pctl: pointer to pinctrl_dev
98*4882a593Smuzhiyun * @pctldesc: pinctrl descriptor
99*4882a593Smuzhiyun */
100*4882a593Smuzhiyun struct iproc_gpio {
101*4882a593Smuzhiyun struct device *dev;
102*4882a593Smuzhiyun
103*4882a593Smuzhiyun void __iomem *base;
104*4882a593Smuzhiyun void __iomem *io_ctrl;
105*4882a593Smuzhiyun enum iproc_pinconf_ctrl_type io_ctrl_type;
106*4882a593Smuzhiyun
107*4882a593Smuzhiyun raw_spinlock_t lock;
108*4882a593Smuzhiyun
109*4882a593Smuzhiyun struct irq_chip irqchip;
110*4882a593Smuzhiyun struct gpio_chip gc;
111*4882a593Smuzhiyun unsigned num_banks;
112*4882a593Smuzhiyun
113*4882a593Smuzhiyun bool pinmux_is_supported;
114*4882a593Smuzhiyun
115*4882a593Smuzhiyun enum pin_config_param *pinconf_disable;
116*4882a593Smuzhiyun unsigned int nr_pinconf_disable;
117*4882a593Smuzhiyun
118*4882a593Smuzhiyun struct pinctrl_dev *pctl;
119*4882a593Smuzhiyun struct pinctrl_desc pctldesc;
120*4882a593Smuzhiyun };
121*4882a593Smuzhiyun
122*4882a593Smuzhiyun /*
123*4882a593Smuzhiyun * Mapping from PINCONF pins to GPIO pins is 1-to-1
124*4882a593Smuzhiyun */
iproc_pin_to_gpio(unsigned pin)125*4882a593Smuzhiyun static inline unsigned iproc_pin_to_gpio(unsigned pin)
126*4882a593Smuzhiyun {
127*4882a593Smuzhiyun return pin;
128*4882a593Smuzhiyun }
129*4882a593Smuzhiyun
130*4882a593Smuzhiyun /**
131*4882a593Smuzhiyun * iproc_set_bit - set or clear one bit (corresponding to the GPIO pin) in a
132*4882a593Smuzhiyun * Iproc GPIO register
133*4882a593Smuzhiyun *
134*4882a593Smuzhiyun * @chip: Iproc GPIO device
135*4882a593Smuzhiyun * @reg: register offset
136*4882a593Smuzhiyun * @gpio: GPIO pin
137*4882a593Smuzhiyun * @set: set or clear
138*4882a593Smuzhiyun */
iproc_set_bit(struct iproc_gpio * chip,unsigned int reg,unsigned gpio,bool set)139*4882a593Smuzhiyun static inline void iproc_set_bit(struct iproc_gpio *chip, unsigned int reg,
140*4882a593Smuzhiyun unsigned gpio, bool set)
141*4882a593Smuzhiyun {
142*4882a593Smuzhiyun unsigned int offset = IPROC_GPIO_REG(gpio, reg);
143*4882a593Smuzhiyun unsigned int shift = IPROC_GPIO_SHIFT(gpio);
144*4882a593Smuzhiyun u32 val;
145*4882a593Smuzhiyun
146*4882a593Smuzhiyun val = readl(chip->base + offset);
147*4882a593Smuzhiyun if (set)
148*4882a593Smuzhiyun val |= BIT(shift);
149*4882a593Smuzhiyun else
150*4882a593Smuzhiyun val &= ~BIT(shift);
151*4882a593Smuzhiyun writel(val, chip->base + offset);
152*4882a593Smuzhiyun }
153*4882a593Smuzhiyun
iproc_get_bit(struct iproc_gpio * chip,unsigned int reg,unsigned gpio)154*4882a593Smuzhiyun static inline bool iproc_get_bit(struct iproc_gpio *chip, unsigned int reg,
155*4882a593Smuzhiyun unsigned gpio)
156*4882a593Smuzhiyun {
157*4882a593Smuzhiyun unsigned int offset = IPROC_GPIO_REG(gpio, reg);
158*4882a593Smuzhiyun unsigned int shift = IPROC_GPIO_SHIFT(gpio);
159*4882a593Smuzhiyun
160*4882a593Smuzhiyun return !!(readl(chip->base + offset) & BIT(shift));
161*4882a593Smuzhiyun }
162*4882a593Smuzhiyun
iproc_gpio_irq_handler(struct irq_desc * desc)163*4882a593Smuzhiyun static void iproc_gpio_irq_handler(struct irq_desc *desc)
164*4882a593Smuzhiyun {
165*4882a593Smuzhiyun struct gpio_chip *gc = irq_desc_get_handler_data(desc);
166*4882a593Smuzhiyun struct iproc_gpio *chip = gpiochip_get_data(gc);
167*4882a593Smuzhiyun struct irq_chip *irq_chip = irq_desc_get_chip(desc);
168*4882a593Smuzhiyun int i, bit;
169*4882a593Smuzhiyun
170*4882a593Smuzhiyun chained_irq_enter(irq_chip, desc);
171*4882a593Smuzhiyun
172*4882a593Smuzhiyun /* go through the entire GPIO banks and handle all interrupts */
173*4882a593Smuzhiyun for (i = 0; i < chip->num_banks; i++) {
174*4882a593Smuzhiyun unsigned long val = readl(chip->base + (i * GPIO_BANK_SIZE) +
175*4882a593Smuzhiyun IPROC_GPIO_INT_MSTAT_OFFSET);
176*4882a593Smuzhiyun
177*4882a593Smuzhiyun for_each_set_bit(bit, &val, NGPIOS_PER_BANK) {
178*4882a593Smuzhiyun unsigned pin = NGPIOS_PER_BANK * i + bit;
179*4882a593Smuzhiyun int child_irq = irq_find_mapping(gc->irq.domain, pin);
180*4882a593Smuzhiyun
181*4882a593Smuzhiyun /*
182*4882a593Smuzhiyun * Clear the interrupt before invoking the
183*4882a593Smuzhiyun * handler, so we do not leave any window
184*4882a593Smuzhiyun */
185*4882a593Smuzhiyun writel(BIT(bit), chip->base + (i * GPIO_BANK_SIZE) +
186*4882a593Smuzhiyun IPROC_GPIO_INT_CLR_OFFSET);
187*4882a593Smuzhiyun
188*4882a593Smuzhiyun generic_handle_irq(child_irq);
189*4882a593Smuzhiyun }
190*4882a593Smuzhiyun }
191*4882a593Smuzhiyun
192*4882a593Smuzhiyun chained_irq_exit(irq_chip, desc);
193*4882a593Smuzhiyun }
194*4882a593Smuzhiyun
195*4882a593Smuzhiyun
iproc_gpio_irq_ack(struct irq_data * d)196*4882a593Smuzhiyun static void iproc_gpio_irq_ack(struct irq_data *d)
197*4882a593Smuzhiyun {
198*4882a593Smuzhiyun struct gpio_chip *gc = irq_data_get_irq_chip_data(d);
199*4882a593Smuzhiyun struct iproc_gpio *chip = gpiochip_get_data(gc);
200*4882a593Smuzhiyun unsigned gpio = d->hwirq;
201*4882a593Smuzhiyun unsigned int offset = IPROC_GPIO_REG(gpio,
202*4882a593Smuzhiyun IPROC_GPIO_INT_CLR_OFFSET);
203*4882a593Smuzhiyun unsigned int shift = IPROC_GPIO_SHIFT(gpio);
204*4882a593Smuzhiyun u32 val = BIT(shift);
205*4882a593Smuzhiyun
206*4882a593Smuzhiyun writel(val, chip->base + offset);
207*4882a593Smuzhiyun }
208*4882a593Smuzhiyun
209*4882a593Smuzhiyun /**
210*4882a593Smuzhiyun * iproc_gpio_irq_set_mask - mask/unmask a GPIO interrupt
211*4882a593Smuzhiyun *
212*4882a593Smuzhiyun * @d: IRQ chip data
213*4882a593Smuzhiyun * @unmask: mask/unmask GPIO interrupt
214*4882a593Smuzhiyun */
iproc_gpio_irq_set_mask(struct irq_data * d,bool unmask)215*4882a593Smuzhiyun static void iproc_gpio_irq_set_mask(struct irq_data *d, bool unmask)
216*4882a593Smuzhiyun {
217*4882a593Smuzhiyun struct gpio_chip *gc = irq_data_get_irq_chip_data(d);
218*4882a593Smuzhiyun struct iproc_gpio *chip = gpiochip_get_data(gc);
219*4882a593Smuzhiyun unsigned gpio = d->hwirq;
220*4882a593Smuzhiyun
221*4882a593Smuzhiyun iproc_set_bit(chip, IPROC_GPIO_INT_MSK_OFFSET, gpio, unmask);
222*4882a593Smuzhiyun }
223*4882a593Smuzhiyun
iproc_gpio_irq_mask(struct irq_data * d)224*4882a593Smuzhiyun static void iproc_gpio_irq_mask(struct irq_data *d)
225*4882a593Smuzhiyun {
226*4882a593Smuzhiyun struct gpio_chip *gc = irq_data_get_irq_chip_data(d);
227*4882a593Smuzhiyun struct iproc_gpio *chip = gpiochip_get_data(gc);
228*4882a593Smuzhiyun unsigned long flags;
229*4882a593Smuzhiyun
230*4882a593Smuzhiyun raw_spin_lock_irqsave(&chip->lock, flags);
231*4882a593Smuzhiyun iproc_gpio_irq_set_mask(d, false);
232*4882a593Smuzhiyun raw_spin_unlock_irqrestore(&chip->lock, flags);
233*4882a593Smuzhiyun }
234*4882a593Smuzhiyun
iproc_gpio_irq_unmask(struct irq_data * d)235*4882a593Smuzhiyun static void iproc_gpio_irq_unmask(struct irq_data *d)
236*4882a593Smuzhiyun {
237*4882a593Smuzhiyun struct gpio_chip *gc = irq_data_get_irq_chip_data(d);
238*4882a593Smuzhiyun struct iproc_gpio *chip = gpiochip_get_data(gc);
239*4882a593Smuzhiyun unsigned long flags;
240*4882a593Smuzhiyun
241*4882a593Smuzhiyun raw_spin_lock_irqsave(&chip->lock, flags);
242*4882a593Smuzhiyun iproc_gpio_irq_set_mask(d, true);
243*4882a593Smuzhiyun raw_spin_unlock_irqrestore(&chip->lock, flags);
244*4882a593Smuzhiyun }
245*4882a593Smuzhiyun
iproc_gpio_irq_set_type(struct irq_data * d,unsigned int type)246*4882a593Smuzhiyun static int iproc_gpio_irq_set_type(struct irq_data *d, unsigned int type)
247*4882a593Smuzhiyun {
248*4882a593Smuzhiyun struct gpio_chip *gc = irq_data_get_irq_chip_data(d);
249*4882a593Smuzhiyun struct iproc_gpio *chip = gpiochip_get_data(gc);
250*4882a593Smuzhiyun unsigned gpio = d->hwirq;
251*4882a593Smuzhiyun bool level_triggered = false;
252*4882a593Smuzhiyun bool dual_edge = false;
253*4882a593Smuzhiyun bool rising_or_high = false;
254*4882a593Smuzhiyun unsigned long flags;
255*4882a593Smuzhiyun
256*4882a593Smuzhiyun switch (type & IRQ_TYPE_SENSE_MASK) {
257*4882a593Smuzhiyun case IRQ_TYPE_EDGE_RISING:
258*4882a593Smuzhiyun rising_or_high = true;
259*4882a593Smuzhiyun break;
260*4882a593Smuzhiyun
261*4882a593Smuzhiyun case IRQ_TYPE_EDGE_FALLING:
262*4882a593Smuzhiyun break;
263*4882a593Smuzhiyun
264*4882a593Smuzhiyun case IRQ_TYPE_EDGE_BOTH:
265*4882a593Smuzhiyun dual_edge = true;
266*4882a593Smuzhiyun break;
267*4882a593Smuzhiyun
268*4882a593Smuzhiyun case IRQ_TYPE_LEVEL_HIGH:
269*4882a593Smuzhiyun level_triggered = true;
270*4882a593Smuzhiyun rising_or_high = true;
271*4882a593Smuzhiyun break;
272*4882a593Smuzhiyun
273*4882a593Smuzhiyun case IRQ_TYPE_LEVEL_LOW:
274*4882a593Smuzhiyun level_triggered = true;
275*4882a593Smuzhiyun break;
276*4882a593Smuzhiyun
277*4882a593Smuzhiyun default:
278*4882a593Smuzhiyun dev_err(chip->dev, "invalid GPIO IRQ type 0x%x\n",
279*4882a593Smuzhiyun type);
280*4882a593Smuzhiyun return -EINVAL;
281*4882a593Smuzhiyun }
282*4882a593Smuzhiyun
283*4882a593Smuzhiyun raw_spin_lock_irqsave(&chip->lock, flags);
284*4882a593Smuzhiyun iproc_set_bit(chip, IPROC_GPIO_INT_TYPE_OFFSET, gpio,
285*4882a593Smuzhiyun level_triggered);
286*4882a593Smuzhiyun iproc_set_bit(chip, IPROC_GPIO_INT_DE_OFFSET, gpio, dual_edge);
287*4882a593Smuzhiyun iproc_set_bit(chip, IPROC_GPIO_INT_EDGE_OFFSET, gpio,
288*4882a593Smuzhiyun rising_or_high);
289*4882a593Smuzhiyun
290*4882a593Smuzhiyun if (type & IRQ_TYPE_EDGE_BOTH)
291*4882a593Smuzhiyun irq_set_handler_locked(d, handle_edge_irq);
292*4882a593Smuzhiyun else
293*4882a593Smuzhiyun irq_set_handler_locked(d, handle_level_irq);
294*4882a593Smuzhiyun
295*4882a593Smuzhiyun raw_spin_unlock_irqrestore(&chip->lock, flags);
296*4882a593Smuzhiyun
297*4882a593Smuzhiyun dev_dbg(chip->dev,
298*4882a593Smuzhiyun "gpio:%u level_triggered:%d dual_edge:%d rising_or_high:%d\n",
299*4882a593Smuzhiyun gpio, level_triggered, dual_edge, rising_or_high);
300*4882a593Smuzhiyun
301*4882a593Smuzhiyun return 0;
302*4882a593Smuzhiyun }
303*4882a593Smuzhiyun
304*4882a593Smuzhiyun /*
305*4882a593Smuzhiyun * Request the Iproc IOMUX pinmux controller to mux individual pins to GPIO
306*4882a593Smuzhiyun */
iproc_gpio_request(struct gpio_chip * gc,unsigned offset)307*4882a593Smuzhiyun static int iproc_gpio_request(struct gpio_chip *gc, unsigned offset)
308*4882a593Smuzhiyun {
309*4882a593Smuzhiyun struct iproc_gpio *chip = gpiochip_get_data(gc);
310*4882a593Smuzhiyun unsigned gpio = gc->base + offset;
311*4882a593Smuzhiyun
312*4882a593Smuzhiyun /* not all Iproc GPIO pins can be muxed individually */
313*4882a593Smuzhiyun if (!chip->pinmux_is_supported)
314*4882a593Smuzhiyun return 0;
315*4882a593Smuzhiyun
316*4882a593Smuzhiyun return pinctrl_gpio_request(gpio);
317*4882a593Smuzhiyun }
318*4882a593Smuzhiyun
iproc_gpio_free(struct gpio_chip * gc,unsigned offset)319*4882a593Smuzhiyun static void iproc_gpio_free(struct gpio_chip *gc, unsigned offset)
320*4882a593Smuzhiyun {
321*4882a593Smuzhiyun struct iproc_gpio *chip = gpiochip_get_data(gc);
322*4882a593Smuzhiyun unsigned gpio = gc->base + offset;
323*4882a593Smuzhiyun
324*4882a593Smuzhiyun if (!chip->pinmux_is_supported)
325*4882a593Smuzhiyun return;
326*4882a593Smuzhiyun
327*4882a593Smuzhiyun pinctrl_gpio_free(gpio);
328*4882a593Smuzhiyun }
329*4882a593Smuzhiyun
iproc_gpio_direction_input(struct gpio_chip * gc,unsigned gpio)330*4882a593Smuzhiyun static int iproc_gpio_direction_input(struct gpio_chip *gc, unsigned gpio)
331*4882a593Smuzhiyun {
332*4882a593Smuzhiyun struct iproc_gpio *chip = gpiochip_get_data(gc);
333*4882a593Smuzhiyun unsigned long flags;
334*4882a593Smuzhiyun
335*4882a593Smuzhiyun raw_spin_lock_irqsave(&chip->lock, flags);
336*4882a593Smuzhiyun iproc_set_bit(chip, IPROC_GPIO_OUT_EN_OFFSET, gpio, false);
337*4882a593Smuzhiyun raw_spin_unlock_irqrestore(&chip->lock, flags);
338*4882a593Smuzhiyun
339*4882a593Smuzhiyun dev_dbg(chip->dev, "gpio:%u set input\n", gpio);
340*4882a593Smuzhiyun
341*4882a593Smuzhiyun return 0;
342*4882a593Smuzhiyun }
343*4882a593Smuzhiyun
iproc_gpio_direction_output(struct gpio_chip * gc,unsigned gpio,int val)344*4882a593Smuzhiyun static int iproc_gpio_direction_output(struct gpio_chip *gc, unsigned gpio,
345*4882a593Smuzhiyun int val)
346*4882a593Smuzhiyun {
347*4882a593Smuzhiyun struct iproc_gpio *chip = gpiochip_get_data(gc);
348*4882a593Smuzhiyun unsigned long flags;
349*4882a593Smuzhiyun
350*4882a593Smuzhiyun raw_spin_lock_irqsave(&chip->lock, flags);
351*4882a593Smuzhiyun iproc_set_bit(chip, IPROC_GPIO_OUT_EN_OFFSET, gpio, true);
352*4882a593Smuzhiyun iproc_set_bit(chip, IPROC_GPIO_DATA_OUT_OFFSET, gpio, !!(val));
353*4882a593Smuzhiyun raw_spin_unlock_irqrestore(&chip->lock, flags);
354*4882a593Smuzhiyun
355*4882a593Smuzhiyun dev_dbg(chip->dev, "gpio:%u set output, value:%d\n", gpio, val);
356*4882a593Smuzhiyun
357*4882a593Smuzhiyun return 0;
358*4882a593Smuzhiyun }
359*4882a593Smuzhiyun
iproc_gpio_get_direction(struct gpio_chip * gc,unsigned int gpio)360*4882a593Smuzhiyun static int iproc_gpio_get_direction(struct gpio_chip *gc, unsigned int gpio)
361*4882a593Smuzhiyun {
362*4882a593Smuzhiyun struct iproc_gpio *chip = gpiochip_get_data(gc);
363*4882a593Smuzhiyun unsigned int offset = IPROC_GPIO_REG(gpio, IPROC_GPIO_OUT_EN_OFFSET);
364*4882a593Smuzhiyun unsigned int shift = IPROC_GPIO_SHIFT(gpio);
365*4882a593Smuzhiyun
366*4882a593Smuzhiyun if (readl(chip->base + offset) & BIT(shift))
367*4882a593Smuzhiyun return GPIO_LINE_DIRECTION_OUT;
368*4882a593Smuzhiyun
369*4882a593Smuzhiyun return GPIO_LINE_DIRECTION_IN;
370*4882a593Smuzhiyun }
371*4882a593Smuzhiyun
iproc_gpio_set(struct gpio_chip * gc,unsigned gpio,int val)372*4882a593Smuzhiyun static void iproc_gpio_set(struct gpio_chip *gc, unsigned gpio, int val)
373*4882a593Smuzhiyun {
374*4882a593Smuzhiyun struct iproc_gpio *chip = gpiochip_get_data(gc);
375*4882a593Smuzhiyun unsigned long flags;
376*4882a593Smuzhiyun
377*4882a593Smuzhiyun raw_spin_lock_irqsave(&chip->lock, flags);
378*4882a593Smuzhiyun iproc_set_bit(chip, IPROC_GPIO_DATA_OUT_OFFSET, gpio, !!(val));
379*4882a593Smuzhiyun raw_spin_unlock_irqrestore(&chip->lock, flags);
380*4882a593Smuzhiyun
381*4882a593Smuzhiyun dev_dbg(chip->dev, "gpio:%u set, value:%d\n", gpio, val);
382*4882a593Smuzhiyun }
383*4882a593Smuzhiyun
iproc_gpio_get(struct gpio_chip * gc,unsigned gpio)384*4882a593Smuzhiyun static int iproc_gpio_get(struct gpio_chip *gc, unsigned gpio)
385*4882a593Smuzhiyun {
386*4882a593Smuzhiyun struct iproc_gpio *chip = gpiochip_get_data(gc);
387*4882a593Smuzhiyun unsigned int offset = IPROC_GPIO_REG(gpio,
388*4882a593Smuzhiyun IPROC_GPIO_DATA_IN_OFFSET);
389*4882a593Smuzhiyun unsigned int shift = IPROC_GPIO_SHIFT(gpio);
390*4882a593Smuzhiyun
391*4882a593Smuzhiyun return !!(readl(chip->base + offset) & BIT(shift));
392*4882a593Smuzhiyun }
393*4882a593Smuzhiyun
394*4882a593Smuzhiyun /*
395*4882a593Smuzhiyun * Mapping of the iProc PINCONF parameters to the generic pin configuration
396*4882a593Smuzhiyun * parameters
397*4882a593Smuzhiyun */
398*4882a593Smuzhiyun static const enum pin_config_param iproc_pinconf_disable_map[] = {
399*4882a593Smuzhiyun [IPROC_PINCONF_DRIVE_STRENGTH] = PIN_CONFIG_DRIVE_STRENGTH,
400*4882a593Smuzhiyun [IPROC_PINCONF_BIAS_DISABLE] = PIN_CONFIG_BIAS_DISABLE,
401*4882a593Smuzhiyun [IPROC_PINCONF_BIAS_PULL_UP] = PIN_CONFIG_BIAS_PULL_UP,
402*4882a593Smuzhiyun [IPROC_PINCONF_BIAS_PULL_DOWN] = PIN_CONFIG_BIAS_PULL_DOWN,
403*4882a593Smuzhiyun };
404*4882a593Smuzhiyun
iproc_pinconf_param_is_disabled(struct iproc_gpio * chip,enum pin_config_param param)405*4882a593Smuzhiyun static bool iproc_pinconf_param_is_disabled(struct iproc_gpio *chip,
406*4882a593Smuzhiyun enum pin_config_param param)
407*4882a593Smuzhiyun {
408*4882a593Smuzhiyun unsigned int i;
409*4882a593Smuzhiyun
410*4882a593Smuzhiyun if (!chip->nr_pinconf_disable)
411*4882a593Smuzhiyun return false;
412*4882a593Smuzhiyun
413*4882a593Smuzhiyun for (i = 0; i < chip->nr_pinconf_disable; i++)
414*4882a593Smuzhiyun if (chip->pinconf_disable[i] == param)
415*4882a593Smuzhiyun return true;
416*4882a593Smuzhiyun
417*4882a593Smuzhiyun return false;
418*4882a593Smuzhiyun }
419*4882a593Smuzhiyun
iproc_pinconf_disable_map_create(struct iproc_gpio * chip,unsigned long disable_mask)420*4882a593Smuzhiyun static int iproc_pinconf_disable_map_create(struct iproc_gpio *chip,
421*4882a593Smuzhiyun unsigned long disable_mask)
422*4882a593Smuzhiyun {
423*4882a593Smuzhiyun unsigned int map_size = ARRAY_SIZE(iproc_pinconf_disable_map);
424*4882a593Smuzhiyun unsigned int bit, nbits = 0;
425*4882a593Smuzhiyun
426*4882a593Smuzhiyun /* figure out total number of PINCONF parameters to disable */
427*4882a593Smuzhiyun for_each_set_bit(bit, &disable_mask, map_size)
428*4882a593Smuzhiyun nbits++;
429*4882a593Smuzhiyun
430*4882a593Smuzhiyun if (!nbits)
431*4882a593Smuzhiyun return 0;
432*4882a593Smuzhiyun
433*4882a593Smuzhiyun /*
434*4882a593Smuzhiyun * Allocate an array to store PINCONF parameters that need to be
435*4882a593Smuzhiyun * disabled
436*4882a593Smuzhiyun */
437*4882a593Smuzhiyun chip->pinconf_disable = devm_kcalloc(chip->dev, nbits,
438*4882a593Smuzhiyun sizeof(*chip->pinconf_disable),
439*4882a593Smuzhiyun GFP_KERNEL);
440*4882a593Smuzhiyun if (!chip->pinconf_disable)
441*4882a593Smuzhiyun return -ENOMEM;
442*4882a593Smuzhiyun
443*4882a593Smuzhiyun chip->nr_pinconf_disable = nbits;
444*4882a593Smuzhiyun
445*4882a593Smuzhiyun /* now store these parameters */
446*4882a593Smuzhiyun nbits = 0;
447*4882a593Smuzhiyun for_each_set_bit(bit, &disable_mask, map_size)
448*4882a593Smuzhiyun chip->pinconf_disable[nbits++] = iproc_pinconf_disable_map[bit];
449*4882a593Smuzhiyun
450*4882a593Smuzhiyun return 0;
451*4882a593Smuzhiyun }
452*4882a593Smuzhiyun
iproc_get_groups_count(struct pinctrl_dev * pctldev)453*4882a593Smuzhiyun static int iproc_get_groups_count(struct pinctrl_dev *pctldev)
454*4882a593Smuzhiyun {
455*4882a593Smuzhiyun return 1;
456*4882a593Smuzhiyun }
457*4882a593Smuzhiyun
458*4882a593Smuzhiyun /*
459*4882a593Smuzhiyun * Only one group: "gpio_grp", since this local pinctrl device only performs
460*4882a593Smuzhiyun * GPIO specific PINCONF configurations
461*4882a593Smuzhiyun */
iproc_get_group_name(struct pinctrl_dev * pctldev,unsigned selector)462*4882a593Smuzhiyun static const char *iproc_get_group_name(struct pinctrl_dev *pctldev,
463*4882a593Smuzhiyun unsigned selector)
464*4882a593Smuzhiyun {
465*4882a593Smuzhiyun return "gpio_grp";
466*4882a593Smuzhiyun }
467*4882a593Smuzhiyun
468*4882a593Smuzhiyun static const struct pinctrl_ops iproc_pctrl_ops = {
469*4882a593Smuzhiyun .get_groups_count = iproc_get_groups_count,
470*4882a593Smuzhiyun .get_group_name = iproc_get_group_name,
471*4882a593Smuzhiyun .dt_node_to_map = pinconf_generic_dt_node_to_map_pin,
472*4882a593Smuzhiyun .dt_free_map = pinctrl_utils_free_map,
473*4882a593Smuzhiyun };
474*4882a593Smuzhiyun
iproc_gpio_set_pull(struct iproc_gpio * chip,unsigned gpio,bool disable,bool pull_up)475*4882a593Smuzhiyun static int iproc_gpio_set_pull(struct iproc_gpio *chip, unsigned gpio,
476*4882a593Smuzhiyun bool disable, bool pull_up)
477*4882a593Smuzhiyun {
478*4882a593Smuzhiyun void __iomem *base;
479*4882a593Smuzhiyun unsigned long flags;
480*4882a593Smuzhiyun unsigned int shift;
481*4882a593Smuzhiyun u32 val_1, val_2;
482*4882a593Smuzhiyun
483*4882a593Smuzhiyun raw_spin_lock_irqsave(&chip->lock, flags);
484*4882a593Smuzhiyun if (chip->io_ctrl_type == IOCTRL_TYPE_CDRU) {
485*4882a593Smuzhiyun base = chip->io_ctrl;
486*4882a593Smuzhiyun shift = IPROC_GPIO_SHIFT(gpio);
487*4882a593Smuzhiyun
488*4882a593Smuzhiyun val_1 = readl(base + IPROC_GPIO_PULL_UP_OFFSET);
489*4882a593Smuzhiyun val_2 = readl(base + IPROC_GPIO_PULL_DN_OFFSET);
490*4882a593Smuzhiyun if (disable) {
491*4882a593Smuzhiyun /* no pull-up or pull-down */
492*4882a593Smuzhiyun val_1 &= ~BIT(shift);
493*4882a593Smuzhiyun val_2 &= ~BIT(shift);
494*4882a593Smuzhiyun } else if (pull_up) {
495*4882a593Smuzhiyun val_1 |= BIT(shift);
496*4882a593Smuzhiyun val_2 &= ~BIT(shift);
497*4882a593Smuzhiyun } else {
498*4882a593Smuzhiyun val_1 &= ~BIT(shift);
499*4882a593Smuzhiyun val_2 |= BIT(shift);
500*4882a593Smuzhiyun }
501*4882a593Smuzhiyun writel(val_1, base + IPROC_GPIO_PULL_UP_OFFSET);
502*4882a593Smuzhiyun writel(val_2, base + IPROC_GPIO_PULL_DN_OFFSET);
503*4882a593Smuzhiyun } else {
504*4882a593Smuzhiyun if (disable) {
505*4882a593Smuzhiyun iproc_set_bit(chip, IPROC_GPIO_RES_EN_OFFSET, gpio,
506*4882a593Smuzhiyun false);
507*4882a593Smuzhiyun } else {
508*4882a593Smuzhiyun iproc_set_bit(chip, IPROC_GPIO_PAD_RES_OFFSET, gpio,
509*4882a593Smuzhiyun pull_up);
510*4882a593Smuzhiyun iproc_set_bit(chip, IPROC_GPIO_RES_EN_OFFSET, gpio,
511*4882a593Smuzhiyun true);
512*4882a593Smuzhiyun }
513*4882a593Smuzhiyun }
514*4882a593Smuzhiyun
515*4882a593Smuzhiyun raw_spin_unlock_irqrestore(&chip->lock, flags);
516*4882a593Smuzhiyun dev_dbg(chip->dev, "gpio:%u set pullup:%d\n", gpio, pull_up);
517*4882a593Smuzhiyun
518*4882a593Smuzhiyun return 0;
519*4882a593Smuzhiyun }
520*4882a593Smuzhiyun
iproc_gpio_get_pull(struct iproc_gpio * chip,unsigned gpio,bool * disable,bool * pull_up)521*4882a593Smuzhiyun static void iproc_gpio_get_pull(struct iproc_gpio *chip, unsigned gpio,
522*4882a593Smuzhiyun bool *disable, bool *pull_up)
523*4882a593Smuzhiyun {
524*4882a593Smuzhiyun void __iomem *base;
525*4882a593Smuzhiyun unsigned long flags;
526*4882a593Smuzhiyun unsigned int shift;
527*4882a593Smuzhiyun u32 val_1, val_2;
528*4882a593Smuzhiyun
529*4882a593Smuzhiyun raw_spin_lock_irqsave(&chip->lock, flags);
530*4882a593Smuzhiyun if (chip->io_ctrl_type == IOCTRL_TYPE_CDRU) {
531*4882a593Smuzhiyun base = chip->io_ctrl;
532*4882a593Smuzhiyun shift = IPROC_GPIO_SHIFT(gpio);
533*4882a593Smuzhiyun
534*4882a593Smuzhiyun val_1 = readl(base + IPROC_GPIO_PULL_UP_OFFSET) & BIT(shift);
535*4882a593Smuzhiyun val_2 = readl(base + IPROC_GPIO_PULL_DN_OFFSET) & BIT(shift);
536*4882a593Smuzhiyun
537*4882a593Smuzhiyun *pull_up = val_1 ? true : false;
538*4882a593Smuzhiyun *disable = (val_1 | val_2) ? false : true;
539*4882a593Smuzhiyun
540*4882a593Smuzhiyun } else {
541*4882a593Smuzhiyun *disable = !iproc_get_bit(chip, IPROC_GPIO_RES_EN_OFFSET, gpio);
542*4882a593Smuzhiyun *pull_up = iproc_get_bit(chip, IPROC_GPIO_PAD_RES_OFFSET, gpio);
543*4882a593Smuzhiyun }
544*4882a593Smuzhiyun raw_spin_unlock_irqrestore(&chip->lock, flags);
545*4882a593Smuzhiyun }
546*4882a593Smuzhiyun
547*4882a593Smuzhiyun #define DRV_STRENGTH_OFFSET(gpio, bit, type) ((type) == IOCTRL_TYPE_AON ? \
548*4882a593Smuzhiyun ((2 - (bit)) * 4 + IPROC_GPIO_DRV_CTRL_OFFSET) : \
549*4882a593Smuzhiyun ((type) == IOCTRL_TYPE_CDRU) ? \
550*4882a593Smuzhiyun ((bit) * 4 + IPROC_GPIO_DRV_CTRL_OFFSET) : \
551*4882a593Smuzhiyun ((bit) * 4 + IPROC_GPIO_REG(gpio, IPROC_GPIO_ASIU_DRV0_CTRL_OFFSET)))
552*4882a593Smuzhiyun
iproc_gpio_set_strength(struct iproc_gpio * chip,unsigned gpio,unsigned strength)553*4882a593Smuzhiyun static int iproc_gpio_set_strength(struct iproc_gpio *chip, unsigned gpio,
554*4882a593Smuzhiyun unsigned strength)
555*4882a593Smuzhiyun {
556*4882a593Smuzhiyun void __iomem *base;
557*4882a593Smuzhiyun unsigned int i, offset, shift;
558*4882a593Smuzhiyun u32 val;
559*4882a593Smuzhiyun unsigned long flags;
560*4882a593Smuzhiyun
561*4882a593Smuzhiyun /* make sure drive strength is supported */
562*4882a593Smuzhiyun if (strength < 2 || strength > 16 || (strength % 2))
563*4882a593Smuzhiyun return -ENOTSUPP;
564*4882a593Smuzhiyun
565*4882a593Smuzhiyun if (chip->io_ctrl) {
566*4882a593Smuzhiyun base = chip->io_ctrl;
567*4882a593Smuzhiyun } else {
568*4882a593Smuzhiyun base = chip->base;
569*4882a593Smuzhiyun }
570*4882a593Smuzhiyun
571*4882a593Smuzhiyun shift = IPROC_GPIO_SHIFT(gpio);
572*4882a593Smuzhiyun
573*4882a593Smuzhiyun dev_dbg(chip->dev, "gpio:%u set drive strength:%d mA\n", gpio,
574*4882a593Smuzhiyun strength);
575*4882a593Smuzhiyun
576*4882a593Smuzhiyun raw_spin_lock_irqsave(&chip->lock, flags);
577*4882a593Smuzhiyun strength = (strength / 2) - 1;
578*4882a593Smuzhiyun for (i = 0; i < GPIO_DRV_STRENGTH_BITS; i++) {
579*4882a593Smuzhiyun offset = DRV_STRENGTH_OFFSET(gpio, i, chip->io_ctrl_type);
580*4882a593Smuzhiyun val = readl(base + offset);
581*4882a593Smuzhiyun val &= ~BIT(shift);
582*4882a593Smuzhiyun val |= ((strength >> i) & 0x1) << shift;
583*4882a593Smuzhiyun writel(val, base + offset);
584*4882a593Smuzhiyun }
585*4882a593Smuzhiyun raw_spin_unlock_irqrestore(&chip->lock, flags);
586*4882a593Smuzhiyun
587*4882a593Smuzhiyun return 0;
588*4882a593Smuzhiyun }
589*4882a593Smuzhiyun
iproc_gpio_get_strength(struct iproc_gpio * chip,unsigned gpio,u16 * strength)590*4882a593Smuzhiyun static int iproc_gpio_get_strength(struct iproc_gpio *chip, unsigned gpio,
591*4882a593Smuzhiyun u16 *strength)
592*4882a593Smuzhiyun {
593*4882a593Smuzhiyun void __iomem *base;
594*4882a593Smuzhiyun unsigned int i, offset, shift;
595*4882a593Smuzhiyun u32 val;
596*4882a593Smuzhiyun unsigned long flags;
597*4882a593Smuzhiyun
598*4882a593Smuzhiyun if (chip->io_ctrl) {
599*4882a593Smuzhiyun base = chip->io_ctrl;
600*4882a593Smuzhiyun } else {
601*4882a593Smuzhiyun base = chip->base;
602*4882a593Smuzhiyun }
603*4882a593Smuzhiyun
604*4882a593Smuzhiyun shift = IPROC_GPIO_SHIFT(gpio);
605*4882a593Smuzhiyun
606*4882a593Smuzhiyun raw_spin_lock_irqsave(&chip->lock, flags);
607*4882a593Smuzhiyun *strength = 0;
608*4882a593Smuzhiyun for (i = 0; i < GPIO_DRV_STRENGTH_BITS; i++) {
609*4882a593Smuzhiyun offset = DRV_STRENGTH_OFFSET(gpio, i, chip->io_ctrl_type);
610*4882a593Smuzhiyun val = readl(base + offset) & BIT(shift);
611*4882a593Smuzhiyun val >>= shift;
612*4882a593Smuzhiyun *strength += (val << i);
613*4882a593Smuzhiyun }
614*4882a593Smuzhiyun
615*4882a593Smuzhiyun /* convert to mA */
616*4882a593Smuzhiyun *strength = (*strength + 1) * 2;
617*4882a593Smuzhiyun raw_spin_unlock_irqrestore(&chip->lock, flags);
618*4882a593Smuzhiyun
619*4882a593Smuzhiyun return 0;
620*4882a593Smuzhiyun }
621*4882a593Smuzhiyun
iproc_pin_config_get(struct pinctrl_dev * pctldev,unsigned pin,unsigned long * config)622*4882a593Smuzhiyun static int iproc_pin_config_get(struct pinctrl_dev *pctldev, unsigned pin,
623*4882a593Smuzhiyun unsigned long *config)
624*4882a593Smuzhiyun {
625*4882a593Smuzhiyun struct iproc_gpio *chip = pinctrl_dev_get_drvdata(pctldev);
626*4882a593Smuzhiyun enum pin_config_param param = pinconf_to_config_param(*config);
627*4882a593Smuzhiyun unsigned gpio = iproc_pin_to_gpio(pin);
628*4882a593Smuzhiyun u16 arg;
629*4882a593Smuzhiyun bool disable, pull_up;
630*4882a593Smuzhiyun int ret;
631*4882a593Smuzhiyun
632*4882a593Smuzhiyun if (iproc_pinconf_param_is_disabled(chip, param))
633*4882a593Smuzhiyun return -ENOTSUPP;
634*4882a593Smuzhiyun
635*4882a593Smuzhiyun switch (param) {
636*4882a593Smuzhiyun case PIN_CONFIG_BIAS_DISABLE:
637*4882a593Smuzhiyun iproc_gpio_get_pull(chip, gpio, &disable, &pull_up);
638*4882a593Smuzhiyun if (disable)
639*4882a593Smuzhiyun return 0;
640*4882a593Smuzhiyun else
641*4882a593Smuzhiyun return -EINVAL;
642*4882a593Smuzhiyun
643*4882a593Smuzhiyun case PIN_CONFIG_BIAS_PULL_UP:
644*4882a593Smuzhiyun iproc_gpio_get_pull(chip, gpio, &disable, &pull_up);
645*4882a593Smuzhiyun if (!disable && pull_up)
646*4882a593Smuzhiyun return 0;
647*4882a593Smuzhiyun else
648*4882a593Smuzhiyun return -EINVAL;
649*4882a593Smuzhiyun
650*4882a593Smuzhiyun case PIN_CONFIG_BIAS_PULL_DOWN:
651*4882a593Smuzhiyun iproc_gpio_get_pull(chip, gpio, &disable, &pull_up);
652*4882a593Smuzhiyun if (!disable && !pull_up)
653*4882a593Smuzhiyun return 0;
654*4882a593Smuzhiyun else
655*4882a593Smuzhiyun return -EINVAL;
656*4882a593Smuzhiyun
657*4882a593Smuzhiyun case PIN_CONFIG_DRIVE_STRENGTH:
658*4882a593Smuzhiyun ret = iproc_gpio_get_strength(chip, gpio, &arg);
659*4882a593Smuzhiyun if (ret)
660*4882a593Smuzhiyun return ret;
661*4882a593Smuzhiyun *config = pinconf_to_config_packed(param, arg);
662*4882a593Smuzhiyun
663*4882a593Smuzhiyun return 0;
664*4882a593Smuzhiyun
665*4882a593Smuzhiyun default:
666*4882a593Smuzhiyun return -ENOTSUPP;
667*4882a593Smuzhiyun }
668*4882a593Smuzhiyun
669*4882a593Smuzhiyun return -ENOTSUPP;
670*4882a593Smuzhiyun }
671*4882a593Smuzhiyun
iproc_pin_config_set(struct pinctrl_dev * pctldev,unsigned pin,unsigned long * configs,unsigned num_configs)672*4882a593Smuzhiyun static int iproc_pin_config_set(struct pinctrl_dev *pctldev, unsigned pin,
673*4882a593Smuzhiyun unsigned long *configs, unsigned num_configs)
674*4882a593Smuzhiyun {
675*4882a593Smuzhiyun struct iproc_gpio *chip = pinctrl_dev_get_drvdata(pctldev);
676*4882a593Smuzhiyun enum pin_config_param param;
677*4882a593Smuzhiyun u32 arg;
678*4882a593Smuzhiyun unsigned i, gpio = iproc_pin_to_gpio(pin);
679*4882a593Smuzhiyun int ret = -ENOTSUPP;
680*4882a593Smuzhiyun
681*4882a593Smuzhiyun for (i = 0; i < num_configs; i++) {
682*4882a593Smuzhiyun param = pinconf_to_config_param(configs[i]);
683*4882a593Smuzhiyun
684*4882a593Smuzhiyun if (iproc_pinconf_param_is_disabled(chip, param))
685*4882a593Smuzhiyun return -ENOTSUPP;
686*4882a593Smuzhiyun
687*4882a593Smuzhiyun arg = pinconf_to_config_argument(configs[i]);
688*4882a593Smuzhiyun
689*4882a593Smuzhiyun switch (param) {
690*4882a593Smuzhiyun case PIN_CONFIG_BIAS_DISABLE:
691*4882a593Smuzhiyun ret = iproc_gpio_set_pull(chip, gpio, true, false);
692*4882a593Smuzhiyun if (ret < 0)
693*4882a593Smuzhiyun goto out;
694*4882a593Smuzhiyun break;
695*4882a593Smuzhiyun
696*4882a593Smuzhiyun case PIN_CONFIG_BIAS_PULL_UP:
697*4882a593Smuzhiyun ret = iproc_gpio_set_pull(chip, gpio, false, true);
698*4882a593Smuzhiyun if (ret < 0)
699*4882a593Smuzhiyun goto out;
700*4882a593Smuzhiyun break;
701*4882a593Smuzhiyun
702*4882a593Smuzhiyun case PIN_CONFIG_BIAS_PULL_DOWN:
703*4882a593Smuzhiyun ret = iproc_gpio_set_pull(chip, gpio, false, false);
704*4882a593Smuzhiyun if (ret < 0)
705*4882a593Smuzhiyun goto out;
706*4882a593Smuzhiyun break;
707*4882a593Smuzhiyun
708*4882a593Smuzhiyun case PIN_CONFIG_DRIVE_STRENGTH:
709*4882a593Smuzhiyun ret = iproc_gpio_set_strength(chip, gpio, arg);
710*4882a593Smuzhiyun if (ret < 0)
711*4882a593Smuzhiyun goto out;
712*4882a593Smuzhiyun break;
713*4882a593Smuzhiyun
714*4882a593Smuzhiyun default:
715*4882a593Smuzhiyun dev_err(chip->dev, "invalid configuration\n");
716*4882a593Smuzhiyun return -ENOTSUPP;
717*4882a593Smuzhiyun }
718*4882a593Smuzhiyun } /* for each config */
719*4882a593Smuzhiyun
720*4882a593Smuzhiyun out:
721*4882a593Smuzhiyun return ret;
722*4882a593Smuzhiyun }
723*4882a593Smuzhiyun
724*4882a593Smuzhiyun static const struct pinconf_ops iproc_pconf_ops = {
725*4882a593Smuzhiyun .is_generic = true,
726*4882a593Smuzhiyun .pin_config_get = iproc_pin_config_get,
727*4882a593Smuzhiyun .pin_config_set = iproc_pin_config_set,
728*4882a593Smuzhiyun };
729*4882a593Smuzhiyun
730*4882a593Smuzhiyun /*
731*4882a593Smuzhiyun * Iproc GPIO controller supports some PINCONF related configurations such as
732*4882a593Smuzhiyun * pull up, pull down, and drive strength, when the pin is configured to GPIO
733*4882a593Smuzhiyun *
734*4882a593Smuzhiyun * Here a local pinctrl device is created with simple 1-to-1 pin mapping to the
735*4882a593Smuzhiyun * local GPIO pins
736*4882a593Smuzhiyun */
iproc_gpio_register_pinconf(struct iproc_gpio * chip)737*4882a593Smuzhiyun static int iproc_gpio_register_pinconf(struct iproc_gpio *chip)
738*4882a593Smuzhiyun {
739*4882a593Smuzhiyun struct pinctrl_desc *pctldesc = &chip->pctldesc;
740*4882a593Smuzhiyun struct pinctrl_pin_desc *pins;
741*4882a593Smuzhiyun struct gpio_chip *gc = &chip->gc;
742*4882a593Smuzhiyun int i;
743*4882a593Smuzhiyun
744*4882a593Smuzhiyun pins = devm_kcalloc(chip->dev, gc->ngpio, sizeof(*pins), GFP_KERNEL);
745*4882a593Smuzhiyun if (!pins)
746*4882a593Smuzhiyun return -ENOMEM;
747*4882a593Smuzhiyun
748*4882a593Smuzhiyun for (i = 0; i < gc->ngpio; i++) {
749*4882a593Smuzhiyun pins[i].number = i;
750*4882a593Smuzhiyun pins[i].name = devm_kasprintf(chip->dev, GFP_KERNEL,
751*4882a593Smuzhiyun "gpio-%d", i);
752*4882a593Smuzhiyun if (!pins[i].name)
753*4882a593Smuzhiyun return -ENOMEM;
754*4882a593Smuzhiyun }
755*4882a593Smuzhiyun
756*4882a593Smuzhiyun pctldesc->name = dev_name(chip->dev);
757*4882a593Smuzhiyun pctldesc->pctlops = &iproc_pctrl_ops;
758*4882a593Smuzhiyun pctldesc->pins = pins;
759*4882a593Smuzhiyun pctldesc->npins = gc->ngpio;
760*4882a593Smuzhiyun pctldesc->confops = &iproc_pconf_ops;
761*4882a593Smuzhiyun
762*4882a593Smuzhiyun chip->pctl = devm_pinctrl_register(chip->dev, pctldesc, chip);
763*4882a593Smuzhiyun if (IS_ERR(chip->pctl)) {
764*4882a593Smuzhiyun dev_err(chip->dev, "unable to register pinctrl device\n");
765*4882a593Smuzhiyun return PTR_ERR(chip->pctl);
766*4882a593Smuzhiyun }
767*4882a593Smuzhiyun
768*4882a593Smuzhiyun return 0;
769*4882a593Smuzhiyun }
770*4882a593Smuzhiyun
771*4882a593Smuzhiyun static const struct of_device_id iproc_gpio_of_match[] = {
772*4882a593Smuzhiyun { .compatible = "brcm,iproc-gpio" },
773*4882a593Smuzhiyun { .compatible = "brcm,cygnus-ccm-gpio" },
774*4882a593Smuzhiyun { .compatible = "brcm,cygnus-asiu-gpio" },
775*4882a593Smuzhiyun { .compatible = "brcm,cygnus-crmu-gpio" },
776*4882a593Smuzhiyun { .compatible = "brcm,iproc-nsp-gpio" },
777*4882a593Smuzhiyun { .compatible = "brcm,iproc-stingray-gpio" },
778*4882a593Smuzhiyun { /* sentinel */ }
779*4882a593Smuzhiyun };
780*4882a593Smuzhiyun
iproc_gpio_probe(struct platform_device * pdev)781*4882a593Smuzhiyun static int iproc_gpio_probe(struct platform_device *pdev)
782*4882a593Smuzhiyun {
783*4882a593Smuzhiyun struct device *dev = &pdev->dev;
784*4882a593Smuzhiyun struct resource *res;
785*4882a593Smuzhiyun struct iproc_gpio *chip;
786*4882a593Smuzhiyun struct gpio_chip *gc;
787*4882a593Smuzhiyun u32 ngpios, pinconf_disable_mask = 0;
788*4882a593Smuzhiyun int irq, ret;
789*4882a593Smuzhiyun bool no_pinconf = false;
790*4882a593Smuzhiyun enum iproc_pinconf_ctrl_type io_ctrl_type = IOCTRL_TYPE_INVALID;
791*4882a593Smuzhiyun
792*4882a593Smuzhiyun /* NSP does not support drive strength config */
793*4882a593Smuzhiyun if (of_device_is_compatible(dev->of_node, "brcm,iproc-nsp-gpio"))
794*4882a593Smuzhiyun pinconf_disable_mask = BIT(IPROC_PINCONF_DRIVE_STRENGTH);
795*4882a593Smuzhiyun /* Stingray does not support pinconf in this controller */
796*4882a593Smuzhiyun else if (of_device_is_compatible(dev->of_node,
797*4882a593Smuzhiyun "brcm,iproc-stingray-gpio"))
798*4882a593Smuzhiyun no_pinconf = true;
799*4882a593Smuzhiyun
800*4882a593Smuzhiyun chip = devm_kzalloc(dev, sizeof(*chip), GFP_KERNEL);
801*4882a593Smuzhiyun if (!chip)
802*4882a593Smuzhiyun return -ENOMEM;
803*4882a593Smuzhiyun
804*4882a593Smuzhiyun chip->dev = dev;
805*4882a593Smuzhiyun platform_set_drvdata(pdev, chip);
806*4882a593Smuzhiyun
807*4882a593Smuzhiyun chip->base = devm_platform_ioremap_resource(pdev, 0);
808*4882a593Smuzhiyun if (IS_ERR(chip->base)) {
809*4882a593Smuzhiyun dev_err(dev, "unable to map I/O memory\n");
810*4882a593Smuzhiyun return PTR_ERR(chip->base);
811*4882a593Smuzhiyun }
812*4882a593Smuzhiyun
813*4882a593Smuzhiyun res = platform_get_resource(pdev, IORESOURCE_MEM, 1);
814*4882a593Smuzhiyun if (res) {
815*4882a593Smuzhiyun chip->io_ctrl = devm_ioremap_resource(dev, res);
816*4882a593Smuzhiyun if (IS_ERR(chip->io_ctrl)) {
817*4882a593Smuzhiyun dev_err(dev, "unable to map I/O memory\n");
818*4882a593Smuzhiyun return PTR_ERR(chip->io_ctrl);
819*4882a593Smuzhiyun }
820*4882a593Smuzhiyun if (of_device_is_compatible(dev->of_node,
821*4882a593Smuzhiyun "brcm,cygnus-ccm-gpio"))
822*4882a593Smuzhiyun io_ctrl_type = IOCTRL_TYPE_CDRU;
823*4882a593Smuzhiyun else
824*4882a593Smuzhiyun io_ctrl_type = IOCTRL_TYPE_AON;
825*4882a593Smuzhiyun }
826*4882a593Smuzhiyun
827*4882a593Smuzhiyun chip->io_ctrl_type = io_ctrl_type;
828*4882a593Smuzhiyun
829*4882a593Smuzhiyun if (of_property_read_u32(dev->of_node, "ngpios", &ngpios)) {
830*4882a593Smuzhiyun dev_err(&pdev->dev, "missing ngpios DT property\n");
831*4882a593Smuzhiyun return -ENODEV;
832*4882a593Smuzhiyun }
833*4882a593Smuzhiyun
834*4882a593Smuzhiyun raw_spin_lock_init(&chip->lock);
835*4882a593Smuzhiyun
836*4882a593Smuzhiyun gc = &chip->gc;
837*4882a593Smuzhiyun gc->base = -1;
838*4882a593Smuzhiyun gc->ngpio = ngpios;
839*4882a593Smuzhiyun chip->num_banks = (ngpios + NGPIOS_PER_BANK - 1) / NGPIOS_PER_BANK;
840*4882a593Smuzhiyun gc->label = dev_name(dev);
841*4882a593Smuzhiyun gc->parent = dev;
842*4882a593Smuzhiyun gc->of_node = dev->of_node;
843*4882a593Smuzhiyun gc->request = iproc_gpio_request;
844*4882a593Smuzhiyun gc->free = iproc_gpio_free;
845*4882a593Smuzhiyun gc->direction_input = iproc_gpio_direction_input;
846*4882a593Smuzhiyun gc->direction_output = iproc_gpio_direction_output;
847*4882a593Smuzhiyun gc->get_direction = iproc_gpio_get_direction;
848*4882a593Smuzhiyun gc->set = iproc_gpio_set;
849*4882a593Smuzhiyun gc->get = iproc_gpio_get;
850*4882a593Smuzhiyun
851*4882a593Smuzhiyun chip->pinmux_is_supported = of_property_read_bool(dev->of_node,
852*4882a593Smuzhiyun "gpio-ranges");
853*4882a593Smuzhiyun
854*4882a593Smuzhiyun /* optional GPIO interrupt support */
855*4882a593Smuzhiyun irq = platform_get_irq_optional(pdev, 0);
856*4882a593Smuzhiyun if (irq > 0) {
857*4882a593Smuzhiyun struct irq_chip *irqc;
858*4882a593Smuzhiyun struct gpio_irq_chip *girq;
859*4882a593Smuzhiyun
860*4882a593Smuzhiyun irqc = &chip->irqchip;
861*4882a593Smuzhiyun irqc->name = dev_name(dev);
862*4882a593Smuzhiyun irqc->irq_ack = iproc_gpio_irq_ack;
863*4882a593Smuzhiyun irqc->irq_mask = iproc_gpio_irq_mask;
864*4882a593Smuzhiyun irqc->irq_unmask = iproc_gpio_irq_unmask;
865*4882a593Smuzhiyun irqc->irq_set_type = iproc_gpio_irq_set_type;
866*4882a593Smuzhiyun irqc->irq_enable = iproc_gpio_irq_unmask;
867*4882a593Smuzhiyun irqc->irq_disable = iproc_gpio_irq_mask;
868*4882a593Smuzhiyun
869*4882a593Smuzhiyun girq = &gc->irq;
870*4882a593Smuzhiyun girq->chip = irqc;
871*4882a593Smuzhiyun girq->parent_handler = iproc_gpio_irq_handler;
872*4882a593Smuzhiyun girq->num_parents = 1;
873*4882a593Smuzhiyun girq->parents = devm_kcalloc(dev, 1,
874*4882a593Smuzhiyun sizeof(*girq->parents),
875*4882a593Smuzhiyun GFP_KERNEL);
876*4882a593Smuzhiyun if (!girq->parents)
877*4882a593Smuzhiyun return -ENOMEM;
878*4882a593Smuzhiyun girq->parents[0] = irq;
879*4882a593Smuzhiyun girq->default_type = IRQ_TYPE_NONE;
880*4882a593Smuzhiyun girq->handler = handle_bad_irq;
881*4882a593Smuzhiyun }
882*4882a593Smuzhiyun
883*4882a593Smuzhiyun ret = gpiochip_add_data(gc, chip);
884*4882a593Smuzhiyun if (ret < 0) {
885*4882a593Smuzhiyun dev_err(dev, "unable to add GPIO chip\n");
886*4882a593Smuzhiyun return ret;
887*4882a593Smuzhiyun }
888*4882a593Smuzhiyun
889*4882a593Smuzhiyun if (!no_pinconf) {
890*4882a593Smuzhiyun ret = iproc_gpio_register_pinconf(chip);
891*4882a593Smuzhiyun if (ret) {
892*4882a593Smuzhiyun dev_err(dev, "unable to register pinconf\n");
893*4882a593Smuzhiyun goto err_rm_gpiochip;
894*4882a593Smuzhiyun }
895*4882a593Smuzhiyun
896*4882a593Smuzhiyun if (pinconf_disable_mask) {
897*4882a593Smuzhiyun ret = iproc_pinconf_disable_map_create(chip,
898*4882a593Smuzhiyun pinconf_disable_mask);
899*4882a593Smuzhiyun if (ret) {
900*4882a593Smuzhiyun dev_err(dev,
901*4882a593Smuzhiyun "unable to create pinconf disable map\n");
902*4882a593Smuzhiyun goto err_rm_gpiochip;
903*4882a593Smuzhiyun }
904*4882a593Smuzhiyun }
905*4882a593Smuzhiyun }
906*4882a593Smuzhiyun
907*4882a593Smuzhiyun return 0;
908*4882a593Smuzhiyun
909*4882a593Smuzhiyun err_rm_gpiochip:
910*4882a593Smuzhiyun gpiochip_remove(gc);
911*4882a593Smuzhiyun
912*4882a593Smuzhiyun return ret;
913*4882a593Smuzhiyun }
914*4882a593Smuzhiyun
915*4882a593Smuzhiyun static struct platform_driver iproc_gpio_driver = {
916*4882a593Smuzhiyun .driver = {
917*4882a593Smuzhiyun .name = "iproc-gpio",
918*4882a593Smuzhiyun .of_match_table = iproc_gpio_of_match,
919*4882a593Smuzhiyun },
920*4882a593Smuzhiyun .probe = iproc_gpio_probe,
921*4882a593Smuzhiyun };
922*4882a593Smuzhiyun
iproc_gpio_init(void)923*4882a593Smuzhiyun static int __init iproc_gpio_init(void)
924*4882a593Smuzhiyun {
925*4882a593Smuzhiyun return platform_driver_register(&iproc_gpio_driver);
926*4882a593Smuzhiyun }
927*4882a593Smuzhiyun arch_initcall_sync(iproc_gpio_init);
928