blob: b607d10e4cbd84f96a96a6b03cbf373014ac07e9 [file] [log] [blame]
Stefan Wahrena62c3672018-11-10 17:15:11 +01001// SPDX-License-Identifier: GPL-2.0+
Simon Arlotte1b2dc72012-09-27 22:10:11 -06002/*
3 * Driver for Broadcom BCM2835 GPIO unit (pinctrl + GPIO)
4 *
5 * Copyright (C) 2012 Chris Boot, Simon Arlott, Stephen Warren
6 *
7 * This driver is inspired by:
8 * pinctrl-nomadik.c, please see original file for copyright information
9 * pinctrl-tegra.c, please see original file for copyright information
Simon Arlotte1b2dc72012-09-27 22:10:11 -060010 */
11
12#include <linux/bitmap.h>
13#include <linux/bug.h>
14#include <linux/delay.h>
15#include <linux/device.h>
16#include <linux/err.h>
Linus Walleije19a5f72015-12-08 22:01:00 +010017#include <linux/gpio/driver.h>
Simon Arlotte1b2dc72012-09-27 22:10:11 -060018#include <linux/io.h>
19#include <linux/irq.h>
20#include <linux/irqdesc.h>
Paul Gortmaker34f46842017-05-22 16:56:48 -040021#include <linux/init.h>
Florian Fainelli920fecc2020-05-30 17:11:01 -070022#include <linux/interrupt.h>
Florian Fainelli4434f4c52021-10-19 15:11:21 -070023#include <linux/module.h>
Simon Arlotte1b2dc72012-09-27 22:10:11 -060024#include <linux/of_address.h>
25#include <linux/of.h>
26#include <linux/of_irq.h>
27#include <linux/pinctrl/consumer.h>
28#include <linux/pinctrl/machine.h>
29#include <linux/pinctrl/pinconf.h>
30#include <linux/pinctrl/pinctrl.h>
31#include <linux/pinctrl/pinmux.h>
Matheus Castello0de70492018-04-30 20:42:13 -040032#include <linux/pinctrl/pinconf-generic.h>
Simon Arlotte1b2dc72012-09-27 22:10:11 -060033#include <linux/platform_device.h>
34#include <linux/seq_file.h>
35#include <linux/slab.h>
36#include <linux/spinlock.h>
37#include <linux/types.h>
Matheus Castello0de70492018-04-30 20:42:13 -040038#include <dt-bindings/pinctrl/bcm2835.h>
Simon Arlotte1b2dc72012-09-27 22:10:11 -060039
40#define MODULE_NAME "pinctrl-bcm2835"
41#define BCM2835_NUM_GPIOS 54
Stefan Wahrenb1d84a32020-02-08 14:02:54 +010042#define BCM2711_NUM_GPIOS 58
Simon Arlotte1b2dc72012-09-27 22:10:11 -060043#define BCM2835_NUM_BANKS 2
Phil Elwell00445b52015-02-24 13:40:50 +000044#define BCM2835_NUM_IRQS 3
Simon Arlotte1b2dc72012-09-27 22:10:11 -060045
Simon Arlotte1b2dc72012-09-27 22:10:11 -060046/* GPIO register offsets */
47#define GPFSEL0 0x0 /* Function Select */
48#define GPSET0 0x1c /* Pin Output Set */
49#define GPCLR0 0x28 /* Pin Output Clear */
50#define GPLEV0 0x34 /* Pin Level */
51#define GPEDS0 0x40 /* Pin Event Detect Status */
52#define GPREN0 0x4c /* Pin Rising Edge Detect Enable */
53#define GPFEN0 0x58 /* Pin Falling Edge Detect Enable */
54#define GPHEN0 0x64 /* Pin High Detect Enable */
55#define GPLEN0 0x70 /* Pin Low Detect Enable */
56#define GPAREN0 0x7c /* Pin Async Rising Edge Detect */
57#define GPAFEN0 0x88 /* Pin Async Falling Edge Detect */
58#define GPPUD 0x94 /* Pin Pull-up/down Enable */
59#define GPPUDCLK0 0x98 /* Pin Pull-up/down Enable Clock */
Stefan Wahrene38a9a42019-07-22 08:23:25 +020060#define GP_GPIO_PUP_PDN_CNTRL_REG0 0xe4 /* 2711 Pin Pull-up/down select */
Simon Arlotte1b2dc72012-09-27 22:10:11 -060061
62#define FSEL_REG(p) (GPFSEL0 + (((p) / 10) * 4))
63#define FSEL_SHIFT(p) (((p) % 10) * 3)
64#define GPIO_REG_OFFSET(p) ((p) / 32)
65#define GPIO_REG_SHIFT(p) ((p) % 32)
66
Stefan Wahrene38a9a42019-07-22 08:23:25 +020067#define PUD_2711_MASK 0x3
68#define PUD_2711_REG_OFFSET(p) ((p) / 16)
69#define PUD_2711_REG_SHIFT(p) (((p) % 16) * 2)
70
Nathan Chancellorb40ac082018-10-31 17:46:54 -070071/* argument: bcm2835_pinconf_pull */
72#define BCM2835_PINCONF_PARAM_PULL (PIN_CONFIG_END + 1)
Simon Arlotte1b2dc72012-09-27 22:10:11 -060073
Stefan Wahrene38a9a42019-07-22 08:23:25 +020074#define BCM2711_PULL_NONE 0x0
75#define BCM2711_PULL_UP 0x1
76#define BCM2711_PULL_DOWN 0x2
77
Simon Arlotte1b2dc72012-09-27 22:10:11 -060078struct bcm2835_pinctrl {
79 struct device *dev;
80 void __iomem *base;
Florian Fainelli920fecc2020-05-30 17:11:01 -070081 int *wake_irq;
Simon Arlotte1b2dc72012-09-27 22:10:11 -060082
83 /* note: locking assumes each bank will have its own unsigned long */
84 unsigned long enabled_irq_map[BCM2835_NUM_BANKS];
Stefan Wahrenb1d84a32020-02-08 14:02:54 +010085 unsigned int irq_type[BCM2711_NUM_GPIOS];
Simon Arlotte1b2dc72012-09-27 22:10:11 -060086
87 struct pinctrl_dev *pctl_dev;
Simon Arlotte1b2dc72012-09-27 22:10:11 -060088 struct gpio_chip gpio_chip;
Stefan Wahren90bfaf02020-02-08 14:02:53 +010089 struct pinctrl_desc pctl_desc;
Simon Arlotte1b2dc72012-09-27 22:10:11 -060090 struct pinctrl_gpio_range gpio_range;
91
Lukas Wunner3c7b30f2018-10-27 10:15:33 +020092 raw_spinlock_t irq_lock[BCM2835_NUM_BANKS];
Simon Arlotte1b2dc72012-09-27 22:10:11 -060093};
94
Simon Arlotte1b2dc72012-09-27 22:10:11 -060095/* pins are just named GPIO0..GPIO53 */
96#define BCM2835_GPIO_PIN(a) PINCTRL_PIN(a, "gpio" #a)
Sachin Kamate8ed9122013-06-18 14:34:24 +053097static struct pinctrl_pin_desc bcm2835_gpio_pins[] = {
Simon Arlotte1b2dc72012-09-27 22:10:11 -060098 BCM2835_GPIO_PIN(0),
99 BCM2835_GPIO_PIN(1),
100 BCM2835_GPIO_PIN(2),
101 BCM2835_GPIO_PIN(3),
102 BCM2835_GPIO_PIN(4),
103 BCM2835_GPIO_PIN(5),
104 BCM2835_GPIO_PIN(6),
105 BCM2835_GPIO_PIN(7),
106 BCM2835_GPIO_PIN(8),
107 BCM2835_GPIO_PIN(9),
108 BCM2835_GPIO_PIN(10),
109 BCM2835_GPIO_PIN(11),
110 BCM2835_GPIO_PIN(12),
111 BCM2835_GPIO_PIN(13),
112 BCM2835_GPIO_PIN(14),
113 BCM2835_GPIO_PIN(15),
114 BCM2835_GPIO_PIN(16),
115 BCM2835_GPIO_PIN(17),
116 BCM2835_GPIO_PIN(18),
117 BCM2835_GPIO_PIN(19),
118 BCM2835_GPIO_PIN(20),
119 BCM2835_GPIO_PIN(21),
120 BCM2835_GPIO_PIN(22),
121 BCM2835_GPIO_PIN(23),
122 BCM2835_GPIO_PIN(24),
123 BCM2835_GPIO_PIN(25),
124 BCM2835_GPIO_PIN(26),
125 BCM2835_GPIO_PIN(27),
126 BCM2835_GPIO_PIN(28),
127 BCM2835_GPIO_PIN(29),
128 BCM2835_GPIO_PIN(30),
129 BCM2835_GPIO_PIN(31),
130 BCM2835_GPIO_PIN(32),
131 BCM2835_GPIO_PIN(33),
132 BCM2835_GPIO_PIN(34),
133 BCM2835_GPIO_PIN(35),
134 BCM2835_GPIO_PIN(36),
135 BCM2835_GPIO_PIN(37),
136 BCM2835_GPIO_PIN(38),
137 BCM2835_GPIO_PIN(39),
138 BCM2835_GPIO_PIN(40),
139 BCM2835_GPIO_PIN(41),
140 BCM2835_GPIO_PIN(42),
141 BCM2835_GPIO_PIN(43),
142 BCM2835_GPIO_PIN(44),
143 BCM2835_GPIO_PIN(45),
144 BCM2835_GPIO_PIN(46),
145 BCM2835_GPIO_PIN(47),
146 BCM2835_GPIO_PIN(48),
147 BCM2835_GPIO_PIN(49),
148 BCM2835_GPIO_PIN(50),
149 BCM2835_GPIO_PIN(51),
150 BCM2835_GPIO_PIN(52),
151 BCM2835_GPIO_PIN(53),
Stefan Wahrenb1d84a32020-02-08 14:02:54 +0100152 BCM2835_GPIO_PIN(54),
153 BCM2835_GPIO_PIN(55),
154 BCM2835_GPIO_PIN(56),
155 BCM2835_GPIO_PIN(57),
Simon Arlotte1b2dc72012-09-27 22:10:11 -0600156};
157
158/* one pin per group */
159static const char * const bcm2835_gpio_groups[] = {
160 "gpio0",
161 "gpio1",
162 "gpio2",
163 "gpio3",
164 "gpio4",
165 "gpio5",
166 "gpio6",
167 "gpio7",
168 "gpio8",
169 "gpio9",
170 "gpio10",
171 "gpio11",
172 "gpio12",
173 "gpio13",
174 "gpio14",
175 "gpio15",
176 "gpio16",
177 "gpio17",
178 "gpio18",
179 "gpio19",
180 "gpio20",
181 "gpio21",
182 "gpio22",
183 "gpio23",
184 "gpio24",
185 "gpio25",
186 "gpio26",
187 "gpio27",
188 "gpio28",
189 "gpio29",
190 "gpio30",
191 "gpio31",
192 "gpio32",
193 "gpio33",
194 "gpio34",
195 "gpio35",
196 "gpio36",
197 "gpio37",
198 "gpio38",
199 "gpio39",
200 "gpio40",
201 "gpio41",
202 "gpio42",
203 "gpio43",
204 "gpio44",
205 "gpio45",
206 "gpio46",
207 "gpio47",
208 "gpio48",
209 "gpio49",
210 "gpio50",
211 "gpio51",
212 "gpio52",
213 "gpio53",
Stefan Wahrenb1d84a32020-02-08 14:02:54 +0100214 "gpio54",
215 "gpio55",
216 "gpio56",
217 "gpio57",
Simon Arlotte1b2dc72012-09-27 22:10:11 -0600218};
219
220enum bcm2835_fsel {
Simon Arlotte1b2dc72012-09-27 22:10:11 -0600221 BCM2835_FSEL_COUNT = 8,
222 BCM2835_FSEL_MASK = 0x7,
223};
224
225static const char * const bcm2835_functions[BCM2835_FSEL_COUNT] = {
226 [BCM2835_FSEL_GPIO_IN] = "gpio_in",
227 [BCM2835_FSEL_GPIO_OUT] = "gpio_out",
228 [BCM2835_FSEL_ALT0] = "alt0",
229 [BCM2835_FSEL_ALT1] = "alt1",
230 [BCM2835_FSEL_ALT2] = "alt2",
231 [BCM2835_FSEL_ALT3] = "alt3",
232 [BCM2835_FSEL_ALT4] = "alt4",
233 [BCM2835_FSEL_ALT5] = "alt5",
234};
235
236static const char * const irq_type_names[] = {
237 [IRQ_TYPE_NONE] = "none",
238 [IRQ_TYPE_EDGE_RISING] = "edge-rising",
239 [IRQ_TYPE_EDGE_FALLING] = "edge-falling",
240 [IRQ_TYPE_EDGE_BOTH] = "edge-both",
241 [IRQ_TYPE_LEVEL_HIGH] = "level-high",
242 [IRQ_TYPE_LEVEL_LOW] = "level-low",
243};
244
245static inline u32 bcm2835_gpio_rd(struct bcm2835_pinctrl *pc, unsigned reg)
246{
247 return readl(pc->base + reg);
248}
249
250static inline void bcm2835_gpio_wr(struct bcm2835_pinctrl *pc, unsigned reg,
251 u32 val)
252{
253 writel(val, pc->base + reg);
254}
255
256static inline int bcm2835_gpio_get_bit(struct bcm2835_pinctrl *pc, unsigned reg,
257 unsigned bit)
258{
259 reg += GPIO_REG_OFFSET(bit) * 4;
260 return (bcm2835_gpio_rd(pc, reg) >> GPIO_REG_SHIFT(bit)) & 1;
261}
262
263/* note NOT a read/modify/write cycle */
264static inline void bcm2835_gpio_set_bit(struct bcm2835_pinctrl *pc,
265 unsigned reg, unsigned bit)
266{
267 reg += GPIO_REG_OFFSET(bit) * 4;
268 bcm2835_gpio_wr(pc, reg, BIT(GPIO_REG_SHIFT(bit)));
269}
270
271static inline enum bcm2835_fsel bcm2835_pinctrl_fsel_get(
272 struct bcm2835_pinctrl *pc, unsigned pin)
273{
274 u32 val = bcm2835_gpio_rd(pc, FSEL_REG(pin));
275 enum bcm2835_fsel status = (val >> FSEL_SHIFT(pin)) & BCM2835_FSEL_MASK;
276
277 dev_dbg(pc->dev, "get %08x (%u => %s)\n", val, pin,
278 bcm2835_functions[status]);
279
280 return status;
281}
282
283static inline void bcm2835_pinctrl_fsel_set(
284 struct bcm2835_pinctrl *pc, unsigned pin,
285 enum bcm2835_fsel fsel)
286{
287 u32 val = bcm2835_gpio_rd(pc, FSEL_REG(pin));
288 enum bcm2835_fsel cur = (val >> FSEL_SHIFT(pin)) & BCM2835_FSEL_MASK;
289
290 dev_dbg(pc->dev, "read %08x (%u => %s)\n", val, pin,
291 bcm2835_functions[cur]);
292
293 if (cur == fsel)
294 return;
295
296 if (cur != BCM2835_FSEL_GPIO_IN && fsel != BCM2835_FSEL_GPIO_IN) {
297 /* always transition through GPIO_IN */
298 val &= ~(BCM2835_FSEL_MASK << FSEL_SHIFT(pin));
299 val |= BCM2835_FSEL_GPIO_IN << FSEL_SHIFT(pin);
300
301 dev_dbg(pc->dev, "trans %08x (%u <= %s)\n", val, pin,
302 bcm2835_functions[BCM2835_FSEL_GPIO_IN]);
303 bcm2835_gpio_wr(pc, FSEL_REG(pin), val);
304 }
305
306 val &= ~(BCM2835_FSEL_MASK << FSEL_SHIFT(pin));
307 val |= fsel << FSEL_SHIFT(pin);
308
309 dev_dbg(pc->dev, "write %08x (%u <= %s)\n", val, pin,
310 bcm2835_functions[fsel]);
311 bcm2835_gpio_wr(pc, FSEL_REG(pin), val);
312}
313
Simon Arlotte1b2dc72012-09-27 22:10:11 -0600314static int bcm2835_gpio_direction_input(struct gpio_chip *chip, unsigned offset)
315{
316 return pinctrl_gpio_direction_input(chip->base + offset);
317}
318
319static int bcm2835_gpio_get(struct gpio_chip *chip, unsigned offset)
320{
Linus Walleije19a5f72015-12-08 22:01:00 +0100321 struct bcm2835_pinctrl *pc = gpiochip_get_data(chip);
Simon Arlotte1b2dc72012-09-27 22:10:11 -0600322
323 return bcm2835_gpio_get_bit(pc, GPLEV0, offset);
324}
325
Stefan Wahren20b3d2a2016-03-28 14:58:24 +0000326static int bcm2835_gpio_get_direction(struct gpio_chip *chip, unsigned int offset)
327{
328 struct bcm2835_pinctrl *pc = gpiochip_get_data(chip);
329 enum bcm2835_fsel fsel = bcm2835_pinctrl_fsel_get(pc, offset);
330
331 /* Alternative function doesn't clearly provide a direction */
332 if (fsel > BCM2835_FSEL_GPIO_OUT)
333 return -EINVAL;
334
Matti Vaittinen3c827872020-02-14 15:57:12 +0200335 if (fsel == BCM2835_FSEL_GPIO_IN)
336 return GPIO_LINE_DIRECTION_IN;
337
338 return GPIO_LINE_DIRECTION_OUT;
Stefan Wahren20b3d2a2016-03-28 14:58:24 +0000339}
340
Simon Arlotte1b2dc72012-09-27 22:10:11 -0600341static void bcm2835_gpio_set(struct gpio_chip *chip, unsigned offset, int value)
342{
Linus Walleije19a5f72015-12-08 22:01:00 +0100343 struct bcm2835_pinctrl *pc = gpiochip_get_data(chip);
Simon Arlotte1b2dc72012-09-27 22:10:11 -0600344
345 bcm2835_gpio_set_bit(pc, value ? GPSET0 : GPCLR0, offset);
346}
347
Stefan Wahren4c02cba2015-11-19 00:32:27 +0000348static int bcm2835_gpio_direction_output(struct gpio_chip *chip,
349 unsigned offset, int value)
350{
351 bcm2835_gpio_set(chip, offset, value);
352 return pinctrl_gpio_direction_output(chip->base + offset);
353}
354
Gustavo A. R. Silva531bcf72017-07-11 13:03:39 -0500355static const struct gpio_chip bcm2835_gpio_chip = {
Simon Arlotte1b2dc72012-09-27 22:10:11 -0600356 .label = MODULE_NAME,
357 .owner = THIS_MODULE,
Jonas Gorski98c85d52015-10-11 17:34:19 +0200358 .request = gpiochip_generic_request,
359 .free = gpiochip_generic_free,
Simon Arlotte1b2dc72012-09-27 22:10:11 -0600360 .direction_input = bcm2835_gpio_direction_input,
361 .direction_output = bcm2835_gpio_direction_output,
Stefan Wahren20b3d2a2016-03-28 14:58:24 +0000362 .get_direction = bcm2835_gpio_get_direction,
Simon Arlotte1b2dc72012-09-27 22:10:11 -0600363 .get = bcm2835_gpio_get,
364 .set = bcm2835_gpio_set,
Stefan Wahrenb6e55312019-02-03 14:02:34 +0100365 .set_config = gpiochip_generic_config,
Simon Arlotte1b2dc72012-09-27 22:10:11 -0600366 .base = -1,
367 .ngpio = BCM2835_NUM_GPIOS,
Linus Walleij9fb1f392013-12-04 14:42:46 +0100368 .can_sleep = false,
Simon Arlotte1b2dc72012-09-27 22:10:11 -0600369};
370
Stefan Wahrenb1d84a32020-02-08 14:02:54 +0100371static const struct gpio_chip bcm2711_gpio_chip = {
372 .label = "pinctrl-bcm2711",
373 .owner = THIS_MODULE,
374 .request = gpiochip_generic_request,
375 .free = gpiochip_generic_free,
376 .direction_input = bcm2835_gpio_direction_input,
377 .direction_output = bcm2835_gpio_direction_output,
378 .get_direction = bcm2835_gpio_get_direction,
379 .get = bcm2835_gpio_get,
380 .set = bcm2835_gpio_set,
381 .set_config = gpiochip_generic_config,
382 .base = -1,
383 .ngpio = BCM2711_NUM_GPIOS,
384 .can_sleep = false,
385};
386
Linus Walleij85ae9e52016-11-14 18:48:19 +0100387static void bcm2835_gpio_irq_handle_bank(struct bcm2835_pinctrl *pc,
388 unsigned int bank, u32 mask)
Simon Arlotte1b2dc72012-09-27 22:10:11 -0600389{
Simon Arlotte1b2dc72012-09-27 22:10:11 -0600390 unsigned long events;
391 unsigned offset;
392 unsigned gpio;
Simon Arlotte1b2dc72012-09-27 22:10:11 -0600393
394 events = bcm2835_gpio_rd(pc, GPEDS0 + bank * 4);
Phil Elwell00445b52015-02-24 13:40:50 +0000395 events &= mask;
Simon Arlotte1b2dc72012-09-27 22:10:11 -0600396 events &= pc->enabled_irq_map[bank];
397 for_each_set_bit(offset, &events, 32) {
398 gpio = (32 * bank) + offset;
Marc Zyngiera9cb09b2021-05-04 17:42:18 +0100399 generic_handle_domain_irq(pc->gpio_chip.irq.domain,
400 gpio);
Simon Arlotte1b2dc72012-09-27 22:10:11 -0600401 }
Phil Elwell00445b52015-02-24 13:40:50 +0000402}
403
Linus Walleij85ae9e52016-11-14 18:48:19 +0100404static void bcm2835_gpio_irq_handler(struct irq_desc *desc)
Phil Elwell00445b52015-02-24 13:40:50 +0000405{
Linus Walleij85ae9e52016-11-14 18:48:19 +0100406 struct gpio_chip *chip = irq_desc_get_handler_data(desc);
407 struct bcm2835_pinctrl *pc = gpiochip_get_data(chip);
408 struct irq_chip *host_chip = irq_desc_get_chip(desc);
409 int irq = irq_desc_get_irq(desc);
410 int group;
411 int i;
Phil Elwell00445b52015-02-24 13:40:50 +0000412
Linus Walleij73345a12019-08-12 08:27:29 +0200413 for (i = 0; i < BCM2835_NUM_IRQS; i++) {
414 if (chip->irq.parents[i] == irq) {
Thierry Reding0d885e92017-07-20 18:59:12 +0200415 group = i;
Linus Walleij85ae9e52016-11-14 18:48:19 +0100416 break;
417 }
418 }
419 /* This should not happen, every IRQ has a bank */
Jason Wang29d45a62021-06-24 14:49:13 +0800420 BUG_ON(i == BCM2835_NUM_IRQS);
Linus Walleij85ae9e52016-11-14 18:48:19 +0100421
422 chained_irq_enter(host_chip, desc);
423
424 switch (group) {
Phil Elwell00445b52015-02-24 13:40:50 +0000425 case 0: /* IRQ0 covers GPIOs 0-27 */
Linus Walleij85ae9e52016-11-14 18:48:19 +0100426 bcm2835_gpio_irq_handle_bank(pc, 0, 0x0fffffff);
Phil Elwell00445b52015-02-24 13:40:50 +0000427 break;
428 case 1: /* IRQ1 covers GPIOs 28-45 */
Linus Walleij85ae9e52016-11-14 18:48:19 +0100429 bcm2835_gpio_irq_handle_bank(pc, 0, 0xf0000000);
430 bcm2835_gpio_irq_handle_bank(pc, 1, 0x00003fff);
Phil Elwell00445b52015-02-24 13:40:50 +0000431 break;
Stefan Wahrenb1d84a32020-02-08 14:02:54 +0100432 case 2: /* IRQ2 covers GPIOs 46-57 */
Linus Walleij85ae9e52016-11-14 18:48:19 +0100433 bcm2835_gpio_irq_handle_bank(pc, 1, 0x003fc000);
Phil Elwell00445b52015-02-24 13:40:50 +0000434 break;
435 }
436
Linus Walleij85ae9e52016-11-14 18:48:19 +0100437 chained_irq_exit(host_chip, desc);
Simon Arlotte1b2dc72012-09-27 22:10:11 -0600438}
439
Florian Fainelli920fecc2020-05-30 17:11:01 -0700440static irqreturn_t bcm2835_gpio_wake_irq_handler(int irq, void *dev_id)
441{
442 return IRQ_HANDLED;
443}
444
Simon Arlotte1b2dc72012-09-27 22:10:11 -0600445static inline void __bcm2835_gpio_irq_config(struct bcm2835_pinctrl *pc,
446 unsigned reg, unsigned offset, bool enable)
447{
448 u32 value;
449 reg += GPIO_REG_OFFSET(offset) * 4;
450 value = bcm2835_gpio_rd(pc, reg);
451 if (enable)
452 value |= BIT(GPIO_REG_SHIFT(offset));
453 else
454 value &= ~(BIT(GPIO_REG_SHIFT(offset)));
455 bcm2835_gpio_wr(pc, reg, value);
456}
457
458/* fast path for IRQ handler */
459static void bcm2835_gpio_irq_config(struct bcm2835_pinctrl *pc,
460 unsigned offset, bool enable)
461{
462 switch (pc->irq_type[offset]) {
463 case IRQ_TYPE_EDGE_RISING:
464 __bcm2835_gpio_irq_config(pc, GPREN0, offset, enable);
465 break;
466
467 case IRQ_TYPE_EDGE_FALLING:
468 __bcm2835_gpio_irq_config(pc, GPFEN0, offset, enable);
469 break;
470
471 case IRQ_TYPE_EDGE_BOTH:
472 __bcm2835_gpio_irq_config(pc, GPREN0, offset, enable);
473 __bcm2835_gpio_irq_config(pc, GPFEN0, offset, enable);
474 break;
475
476 case IRQ_TYPE_LEVEL_HIGH:
477 __bcm2835_gpio_irq_config(pc, GPHEN0, offset, enable);
478 break;
479
480 case IRQ_TYPE_LEVEL_LOW:
481 __bcm2835_gpio_irq_config(pc, GPLEN0, offset, enable);
482 break;
483 }
484}
485
486static void bcm2835_gpio_irq_enable(struct irq_data *data)
487{
Linus Walleij85ae9e52016-11-14 18:48:19 +0100488 struct gpio_chip *chip = irq_data_get_irq_chip_data(data);
489 struct bcm2835_pinctrl *pc = gpiochip_get_data(chip);
Simon Arlotte1b2dc72012-09-27 22:10:11 -0600490 unsigned gpio = irqd_to_hwirq(data);
491 unsigned offset = GPIO_REG_SHIFT(gpio);
492 unsigned bank = GPIO_REG_OFFSET(gpio);
493 unsigned long flags;
494
Lukas Wunner3c7b30f2018-10-27 10:15:33 +0200495 raw_spin_lock_irqsave(&pc->irq_lock[bank], flags);
Simon Arlotte1b2dc72012-09-27 22:10:11 -0600496 set_bit(offset, &pc->enabled_irq_map[bank]);
497 bcm2835_gpio_irq_config(pc, gpio, true);
Lukas Wunner3c7b30f2018-10-27 10:15:33 +0200498 raw_spin_unlock_irqrestore(&pc->irq_lock[bank], flags);
Simon Arlotte1b2dc72012-09-27 22:10:11 -0600499}
500
501static void bcm2835_gpio_irq_disable(struct irq_data *data)
502{
Linus Walleij85ae9e52016-11-14 18:48:19 +0100503 struct gpio_chip *chip = irq_data_get_irq_chip_data(data);
504 struct bcm2835_pinctrl *pc = gpiochip_get_data(chip);
Simon Arlotte1b2dc72012-09-27 22:10:11 -0600505 unsigned gpio = irqd_to_hwirq(data);
506 unsigned offset = GPIO_REG_SHIFT(gpio);
507 unsigned bank = GPIO_REG_OFFSET(gpio);
508 unsigned long flags;
509
Lukas Wunner3c7b30f2018-10-27 10:15:33 +0200510 raw_spin_lock_irqsave(&pc->irq_lock[bank], flags);
Simon Arlotte1b2dc72012-09-27 22:10:11 -0600511 bcm2835_gpio_irq_config(pc, gpio, false);
Jonathan Bell714b1dd2015-06-30 12:35:39 +0100512 /* Clear events that were latched prior to clearing event sources */
513 bcm2835_gpio_set_bit(pc, GPEDS0, gpio);
Simon Arlotte1b2dc72012-09-27 22:10:11 -0600514 clear_bit(offset, &pc->enabled_irq_map[bank]);
Lukas Wunner3c7b30f2018-10-27 10:15:33 +0200515 raw_spin_unlock_irqrestore(&pc->irq_lock[bank], flags);
Simon Arlotte1b2dc72012-09-27 22:10:11 -0600516}
517
518static int __bcm2835_gpio_irq_set_type_disabled(struct bcm2835_pinctrl *pc,
519 unsigned offset, unsigned int type)
520{
521 switch (type) {
522 case IRQ_TYPE_NONE:
523 case IRQ_TYPE_EDGE_RISING:
524 case IRQ_TYPE_EDGE_FALLING:
525 case IRQ_TYPE_EDGE_BOTH:
526 case IRQ_TYPE_LEVEL_HIGH:
527 case IRQ_TYPE_LEVEL_LOW:
528 pc->irq_type[offset] = type;
529 break;
530
531 default:
532 return -EINVAL;
533 }
534 return 0;
535}
536
537/* slower path for reconfiguring IRQ type */
538static int __bcm2835_gpio_irq_set_type_enabled(struct bcm2835_pinctrl *pc,
539 unsigned offset, unsigned int type)
540{
541 switch (type) {
542 case IRQ_TYPE_NONE:
543 if (pc->irq_type[offset] != type) {
544 bcm2835_gpio_irq_config(pc, offset, false);
545 pc->irq_type[offset] = type;
546 }
547 break;
548
549 case IRQ_TYPE_EDGE_RISING:
550 if (pc->irq_type[offset] == IRQ_TYPE_EDGE_BOTH) {
551 /* RISING already enabled, disable FALLING */
552 pc->irq_type[offset] = IRQ_TYPE_EDGE_FALLING;
553 bcm2835_gpio_irq_config(pc, offset, false);
554 pc->irq_type[offset] = type;
555 } else if (pc->irq_type[offset] != type) {
556 bcm2835_gpio_irq_config(pc, offset, false);
557 pc->irq_type[offset] = type;
558 bcm2835_gpio_irq_config(pc, offset, true);
559 }
560 break;
561
562 case IRQ_TYPE_EDGE_FALLING:
563 if (pc->irq_type[offset] == IRQ_TYPE_EDGE_BOTH) {
564 /* FALLING already enabled, disable RISING */
565 pc->irq_type[offset] = IRQ_TYPE_EDGE_RISING;
566 bcm2835_gpio_irq_config(pc, offset, false);
567 pc->irq_type[offset] = type;
568 } else if (pc->irq_type[offset] != type) {
569 bcm2835_gpio_irq_config(pc, offset, false);
570 pc->irq_type[offset] = type;
571 bcm2835_gpio_irq_config(pc, offset, true);
572 }
573 break;
574
575 case IRQ_TYPE_EDGE_BOTH:
576 if (pc->irq_type[offset] == IRQ_TYPE_EDGE_RISING) {
577 /* RISING already enabled, enable FALLING too */
578 pc->irq_type[offset] = IRQ_TYPE_EDGE_FALLING;
579 bcm2835_gpio_irq_config(pc, offset, true);
580 pc->irq_type[offset] = type;
581 } else if (pc->irq_type[offset] == IRQ_TYPE_EDGE_FALLING) {
582 /* FALLING already enabled, enable RISING too */
583 pc->irq_type[offset] = IRQ_TYPE_EDGE_RISING;
584 bcm2835_gpio_irq_config(pc, offset, true);
585 pc->irq_type[offset] = type;
586 } else if (pc->irq_type[offset] != type) {
587 bcm2835_gpio_irq_config(pc, offset, false);
588 pc->irq_type[offset] = type;
589 bcm2835_gpio_irq_config(pc, offset, true);
590 }
591 break;
592
593 case IRQ_TYPE_LEVEL_HIGH:
594 case IRQ_TYPE_LEVEL_LOW:
595 if (pc->irq_type[offset] != type) {
596 bcm2835_gpio_irq_config(pc, offset, false);
597 pc->irq_type[offset] = type;
598 bcm2835_gpio_irq_config(pc, offset, true);
599 }
600 break;
601
602 default:
603 return -EINVAL;
604 }
605 return 0;
606}
607
608static int bcm2835_gpio_irq_set_type(struct irq_data *data, unsigned int type)
609{
Linus Walleij85ae9e52016-11-14 18:48:19 +0100610 struct gpio_chip *chip = irq_data_get_irq_chip_data(data);
611 struct bcm2835_pinctrl *pc = gpiochip_get_data(chip);
Simon Arlotte1b2dc72012-09-27 22:10:11 -0600612 unsigned gpio = irqd_to_hwirq(data);
613 unsigned offset = GPIO_REG_SHIFT(gpio);
614 unsigned bank = GPIO_REG_OFFSET(gpio);
615 unsigned long flags;
616 int ret;
617
Lukas Wunner3c7b30f2018-10-27 10:15:33 +0200618 raw_spin_lock_irqsave(&pc->irq_lock[bank], flags);
Simon Arlotte1b2dc72012-09-27 22:10:11 -0600619
620 if (test_bit(offset, &pc->enabled_irq_map[bank]))
621 ret = __bcm2835_gpio_irq_set_type_enabled(pc, gpio, type);
622 else
623 ret = __bcm2835_gpio_irq_set_type_disabled(pc, gpio, type);
624
Charles Keepaxb8a19382015-04-07 11:43:45 +0100625 if (type & IRQ_TYPE_EDGE_BOTH)
Thomas Gleixner1aa74fd2015-06-23 15:52:41 +0200626 irq_set_handler_locked(data, handle_edge_irq);
Charles Keepaxb8a19382015-04-07 11:43:45 +0100627 else
Thomas Gleixner1aa74fd2015-06-23 15:52:41 +0200628 irq_set_handler_locked(data, handle_level_irq);
Charles Keepaxb8a19382015-04-07 11:43:45 +0100629
Lukas Wunner3c7b30f2018-10-27 10:15:33 +0200630 raw_spin_unlock_irqrestore(&pc->irq_lock[bank], flags);
Simon Arlotte1b2dc72012-09-27 22:10:11 -0600631
632 return ret;
633}
634
Charles Keepaxb8a19382015-04-07 11:43:45 +0100635static void bcm2835_gpio_irq_ack(struct irq_data *data)
636{
Linus Walleij85ae9e52016-11-14 18:48:19 +0100637 struct gpio_chip *chip = irq_data_get_irq_chip_data(data);
638 struct bcm2835_pinctrl *pc = gpiochip_get_data(chip);
Charles Keepaxb8a19382015-04-07 11:43:45 +0100639 unsigned gpio = irqd_to_hwirq(data);
640
641 bcm2835_gpio_set_bit(pc, GPEDS0, gpio);
642}
643
Florian Fainelli920fecc2020-05-30 17:11:01 -0700644static int bcm2835_gpio_irq_set_wake(struct irq_data *data, unsigned int on)
645{
646 struct gpio_chip *chip = irq_data_get_irq_chip_data(data);
647 struct bcm2835_pinctrl *pc = gpiochip_get_data(chip);
648 unsigned gpio = irqd_to_hwirq(data);
649 unsigned int irqgroup;
650 int ret = -EINVAL;
651
652 if (!pc->wake_irq)
653 return ret;
654
655 if (gpio <= 27)
656 irqgroup = 0;
657 else if (gpio >= 28 && gpio <= 45)
658 irqgroup = 1;
659 else if (gpio >= 46 && gpio <= 57)
660 irqgroup = 2;
661 else
662 return ret;
663
664 if (on)
665 ret = enable_irq_wake(pc->wake_irq[irqgroup]);
666 else
667 ret = disable_irq_wake(pc->wake_irq[irqgroup]);
668
669 return ret;
670}
671
Simon Arlotte1b2dc72012-09-27 22:10:11 -0600672static struct irq_chip bcm2835_gpio_irq_chip = {
673 .name = MODULE_NAME,
674 .irq_enable = bcm2835_gpio_irq_enable,
675 .irq_disable = bcm2835_gpio_irq_disable,
676 .irq_set_type = bcm2835_gpio_irq_set_type,
Charles Keepaxb8a19382015-04-07 11:43:45 +0100677 .irq_ack = bcm2835_gpio_irq_ack,
678 .irq_mask = bcm2835_gpio_irq_disable,
679 .irq_unmask = bcm2835_gpio_irq_enable,
Florian Fainelli920fecc2020-05-30 17:11:01 -0700680 .irq_set_wake = bcm2835_gpio_irq_set_wake,
681 .flags = IRQCHIP_MASK_ON_SUSPEND,
Simon Arlotte1b2dc72012-09-27 22:10:11 -0600682};
683
684static int bcm2835_pctl_get_groups_count(struct pinctrl_dev *pctldev)
685{
Stefan Wahrenb1d84a32020-02-08 14:02:54 +0100686 return BCM2835_NUM_GPIOS;
Simon Arlotte1b2dc72012-09-27 22:10:11 -0600687}
688
689static const char *bcm2835_pctl_get_group_name(struct pinctrl_dev *pctldev,
690 unsigned selector)
691{
692 return bcm2835_gpio_groups[selector];
693}
694
695static int bcm2835_pctl_get_group_pins(struct pinctrl_dev *pctldev,
696 unsigned selector,
697 const unsigned **pins,
698 unsigned *num_pins)
699{
700 *pins = &bcm2835_gpio_pins[selector].number;
701 *num_pins = 1;
702
703 return 0;
704}
705
706static void bcm2835_pctl_pin_dbg_show(struct pinctrl_dev *pctldev,
707 struct seq_file *s,
708 unsigned offset)
709{
710 struct bcm2835_pinctrl *pc = pinctrl_dev_get_drvdata(pctldev);
Linus Walleij85ae9e52016-11-14 18:48:19 +0100711 struct gpio_chip *chip = &pc->gpio_chip;
Simon Arlotte1b2dc72012-09-27 22:10:11 -0600712 enum bcm2835_fsel fsel = bcm2835_pinctrl_fsel_get(pc, offset);
713 const char *fname = bcm2835_functions[fsel];
714 int value = bcm2835_gpio_get_bit(pc, GPLEV0, offset);
Thierry Redingf0fbe7b2017-11-07 19:15:47 +0100715 int irq = irq_find_mapping(chip->irq.domain, offset);
Simon Arlotte1b2dc72012-09-27 22:10:11 -0600716
717 seq_printf(s, "function %s in %s; irq %d (%s)",
718 fname, value ? "hi" : "lo",
719 irq, irq_type_names[pc->irq_type[offset]]);
720}
721
722static void bcm2835_pctl_dt_free_map(struct pinctrl_dev *pctldev,
723 struct pinctrl_map *maps, unsigned num_maps)
724{
725 int i;
726
727 for (i = 0; i < num_maps; i++)
728 if (maps[i].type == PIN_MAP_TYPE_CONFIGS_PIN)
729 kfree(maps[i].data.configs.configs);
730
731 kfree(maps);
732}
733
734static int bcm2835_pctl_dt_node_to_map_func(struct bcm2835_pinctrl *pc,
735 struct device_node *np, u32 pin, u32 fnum,
736 struct pinctrl_map **maps)
737{
738 struct pinctrl_map *map = *maps;
739
740 if (fnum >= ARRAY_SIZE(bcm2835_functions)) {
Rob Herringf5292d02017-07-18 16:43:23 -0500741 dev_err(pc->dev, "%pOF: invalid brcm,function %d\n", np, fnum);
Simon Arlotte1b2dc72012-09-27 22:10:11 -0600742 return -EINVAL;
743 }
744
745 map->type = PIN_MAP_TYPE_MUX_GROUP;
746 map->data.mux.group = bcm2835_gpio_groups[pin];
747 map->data.mux.function = bcm2835_functions[fnum];
748 (*maps)++;
749
750 return 0;
751}
752
753static int bcm2835_pctl_dt_node_to_map_pull(struct bcm2835_pinctrl *pc,
754 struct device_node *np, u32 pin, u32 pull,
755 struct pinctrl_map **maps)
756{
757 struct pinctrl_map *map = *maps;
758 unsigned long *configs;
759
760 if (pull > 2) {
Rob Herringf5292d02017-07-18 16:43:23 -0500761 dev_err(pc->dev, "%pOF: invalid brcm,pull %d\n", np, pull);
Simon Arlotte1b2dc72012-09-27 22:10:11 -0600762 return -EINVAL;
763 }
764
765 configs = kzalloc(sizeof(*configs), GFP_KERNEL);
766 if (!configs)
767 return -ENOMEM;
Matheus Castello0de70492018-04-30 20:42:13 -0400768 configs[0] = pinconf_to_config_packed(BCM2835_PINCONF_PARAM_PULL, pull);
Simon Arlotte1b2dc72012-09-27 22:10:11 -0600769
770 map->type = PIN_MAP_TYPE_CONFIGS_PIN;
771 map->data.configs.group_or_pin = bcm2835_gpio_pins[pin].name;
772 map->data.configs.configs = configs;
773 map->data.configs.num_configs = 1;
774 (*maps)++;
775
776 return 0;
777}
778
Simon Arlotte1b2dc72012-09-27 22:10:11 -0600779static int bcm2835_pctl_dt_node_to_map(struct pinctrl_dev *pctldev,
780 struct device_node *np,
Matheus Castello0de70492018-04-30 20:42:13 -0400781 struct pinctrl_map **map, unsigned int *num_maps)
Simon Arlotte1b2dc72012-09-27 22:10:11 -0600782{
783 struct bcm2835_pinctrl *pc = pinctrl_dev_get_drvdata(pctldev);
784 struct property *pins, *funcs, *pulls;
785 int num_pins, num_funcs, num_pulls, maps_per_pin;
786 struct pinctrl_map *maps, *cur_map;
787 int i, err;
788 u32 pin, func, pull;
789
Matheus Castello0de70492018-04-30 20:42:13 -0400790 /* Check for generic binding in this node */
791 err = pinconf_generic_dt_node_to_map_all(pctldev, np, map, num_maps);
792 if (err || *num_maps)
793 return err;
794
795 /* Generic binding did not find anything continue with legacy parse */
Simon Arlotte1b2dc72012-09-27 22:10:11 -0600796 pins = of_find_property(np, "brcm,pins", NULL);
797 if (!pins) {
Rob Herringf5292d02017-07-18 16:43:23 -0500798 dev_err(pc->dev, "%pOF: missing brcm,pins property\n", np);
Simon Arlotte1b2dc72012-09-27 22:10:11 -0600799 return -EINVAL;
800 }
801
802 funcs = of_find_property(np, "brcm,function", NULL);
803 pulls = of_find_property(np, "brcm,pull", NULL);
804
805 if (!funcs && !pulls) {
806 dev_err(pc->dev,
Rob Herringf5292d02017-07-18 16:43:23 -0500807 "%pOF: neither brcm,function nor brcm,pull specified\n",
808 np);
Simon Arlotte1b2dc72012-09-27 22:10:11 -0600809 return -EINVAL;
810 }
811
812 num_pins = pins->length / 4;
813 num_funcs = funcs ? (funcs->length / 4) : 0;
814 num_pulls = pulls ? (pulls->length / 4) : 0;
815
816 if (num_funcs > 1 && num_funcs != num_pins) {
817 dev_err(pc->dev,
Rob Herringf5292d02017-07-18 16:43:23 -0500818 "%pOF: brcm,function must have 1 or %d entries\n",
819 np, num_pins);
Simon Arlotte1b2dc72012-09-27 22:10:11 -0600820 return -EINVAL;
821 }
822
823 if (num_pulls > 1 && num_pulls != num_pins) {
824 dev_err(pc->dev,
Rob Herringf5292d02017-07-18 16:43:23 -0500825 "%pOF: brcm,pull must have 1 or %d entries\n",
826 np, num_pins);
Simon Arlotte1b2dc72012-09-27 22:10:11 -0600827 return -EINVAL;
828 }
829
830 maps_per_pin = 0;
831 if (num_funcs)
832 maps_per_pin++;
833 if (num_pulls)
834 maps_per_pin++;
Kees Cook6396bb22018-06-12 14:03:40 -0700835 cur_map = maps = kcalloc(num_pins * maps_per_pin, sizeof(*maps),
836 GFP_KERNEL);
Simon Arlotte1b2dc72012-09-27 22:10:11 -0600837 if (!maps)
838 return -ENOMEM;
839
840 for (i = 0; i < num_pins; i++) {
Stephen Warrence63d6d2013-03-28 05:09:57 +0000841 err = of_property_read_u32_index(np, "brcm,pins", i, &pin);
842 if (err)
843 goto out;
Stefan Wahrenb1d84a32020-02-08 14:02:54 +0100844 if (pin >= pc->pctl_desc.npins) {
Rob Herringf5292d02017-07-18 16:43:23 -0500845 dev_err(pc->dev, "%pOF: invalid brcm,pins value %d\n",
846 np, pin);
Simon Arlotte1b2dc72012-09-27 22:10:11 -0600847 err = -EINVAL;
848 goto out;
849 }
850
851 if (num_funcs) {
Stephen Warrence63d6d2013-03-28 05:09:57 +0000852 err = of_property_read_u32_index(np, "brcm,function",
853 (num_funcs > 1) ? i : 0, &func);
854 if (err)
855 goto out;
Simon Arlotte1b2dc72012-09-27 22:10:11 -0600856 err = bcm2835_pctl_dt_node_to_map_func(pc, np, pin,
857 func, &cur_map);
858 if (err)
859 goto out;
860 }
861 if (num_pulls) {
Stephen Warrence63d6d2013-03-28 05:09:57 +0000862 err = of_property_read_u32_index(np, "brcm,pull",
Phil Elwell2c7e3302016-02-29 17:30:08 -0800863 (num_pulls > 1) ? i : 0, &pull);
Stephen Warrence63d6d2013-03-28 05:09:57 +0000864 if (err)
865 goto out;
Simon Arlotte1b2dc72012-09-27 22:10:11 -0600866 err = bcm2835_pctl_dt_node_to_map_pull(pc, np, pin,
867 pull, &cur_map);
868 if (err)
869 goto out;
870 }
871 }
872
873 *map = maps;
874 *num_maps = num_pins * maps_per_pin;
875
876 return 0;
877
878out:
Stefan Wahren53653c62015-12-21 00:44:04 +0000879 bcm2835_pctl_dt_free_map(pctldev, maps, num_pins * maps_per_pin);
Simon Arlotte1b2dc72012-09-27 22:10:11 -0600880 return err;
881}
882
Laurent Pinchart022ab142013-02-16 10:25:07 +0100883static const struct pinctrl_ops bcm2835_pctl_ops = {
Simon Arlotte1b2dc72012-09-27 22:10:11 -0600884 .get_groups_count = bcm2835_pctl_get_groups_count,
885 .get_group_name = bcm2835_pctl_get_group_name,
886 .get_group_pins = bcm2835_pctl_get_group_pins,
887 .pin_dbg_show = bcm2835_pctl_pin_dbg_show,
888 .dt_node_to_map = bcm2835_pctl_dt_node_to_map,
889 .dt_free_map = bcm2835_pctl_dt_free_map,
890};
891
Phil Elwellccca1ad2016-05-06 12:32:47 +0100892static int bcm2835_pmx_free(struct pinctrl_dev *pctldev,
893 unsigned offset)
894{
895 struct bcm2835_pinctrl *pc = pinctrl_dev_get_drvdata(pctldev);
896
897 /* disable by setting to GPIO_IN */
898 bcm2835_pinctrl_fsel_set(pc, offset, BCM2835_FSEL_GPIO_IN);
899 return 0;
900}
901
Simon Arlotte1b2dc72012-09-27 22:10:11 -0600902static int bcm2835_pmx_get_functions_count(struct pinctrl_dev *pctldev)
903{
904 return BCM2835_FSEL_COUNT;
905}
906
907static const char *bcm2835_pmx_get_function_name(struct pinctrl_dev *pctldev,
908 unsigned selector)
909{
910 return bcm2835_functions[selector];
911}
912
913static int bcm2835_pmx_get_function_groups(struct pinctrl_dev *pctldev,
914 unsigned selector,
915 const char * const **groups,
916 unsigned * const num_groups)
917{
918 /* every pin can do every function */
919 *groups = bcm2835_gpio_groups;
Stefan Wahrenb1d84a32020-02-08 14:02:54 +0100920 *num_groups = BCM2835_NUM_GPIOS;
Simon Arlotte1b2dc72012-09-27 22:10:11 -0600921
922 return 0;
923}
924
Linus Walleij03e9f0c2014-09-03 13:02:56 +0200925static int bcm2835_pmx_set(struct pinctrl_dev *pctldev,
Simon Arlotte1b2dc72012-09-27 22:10:11 -0600926 unsigned func_selector,
927 unsigned group_selector)
928{
929 struct bcm2835_pinctrl *pc = pinctrl_dev_get_drvdata(pctldev);
930
931 bcm2835_pinctrl_fsel_set(pc, group_selector, func_selector);
932
933 return 0;
934}
935
Simon Arlotte1b2dc72012-09-27 22:10:11 -0600936static void bcm2835_pmx_gpio_disable_free(struct pinctrl_dev *pctldev,
937 struct pinctrl_gpio_range *range,
938 unsigned offset)
939{
940 struct bcm2835_pinctrl *pc = pinctrl_dev_get_drvdata(pctldev);
941
942 /* disable by setting to GPIO_IN */
943 bcm2835_pinctrl_fsel_set(pc, offset, BCM2835_FSEL_GPIO_IN);
944}
945
946static int bcm2835_pmx_gpio_set_direction(struct pinctrl_dev *pctldev,
947 struct pinctrl_gpio_range *range,
948 unsigned offset,
949 bool input)
950{
951 struct bcm2835_pinctrl *pc = pinctrl_dev_get_drvdata(pctldev);
952 enum bcm2835_fsel fsel = input ?
953 BCM2835_FSEL_GPIO_IN : BCM2835_FSEL_GPIO_OUT;
954
955 bcm2835_pinctrl_fsel_set(pc, offset, fsel);
956
957 return 0;
958}
959
Laurent Pinchart022ab142013-02-16 10:25:07 +0100960static const struct pinmux_ops bcm2835_pmx_ops = {
Phil Elwellccca1ad2016-05-06 12:32:47 +0100961 .free = bcm2835_pmx_free,
Simon Arlotte1b2dc72012-09-27 22:10:11 -0600962 .get_functions_count = bcm2835_pmx_get_functions_count,
963 .get_function_name = bcm2835_pmx_get_function_name,
964 .get_function_groups = bcm2835_pmx_get_function_groups,
Linus Walleij03e9f0c2014-09-03 13:02:56 +0200965 .set_mux = bcm2835_pmx_set,
Simon Arlotte1b2dc72012-09-27 22:10:11 -0600966 .gpio_disable_free = bcm2835_pmx_gpio_disable_free,
967 .gpio_set_direction = bcm2835_pmx_gpio_set_direction,
968};
969
970static int bcm2835_pinconf_get(struct pinctrl_dev *pctldev,
971 unsigned pin, unsigned long *config)
972{
973 /* No way to read back config in HW */
974 return -ENOTSUPP;
975}
976
Matheus Castello0de70492018-04-30 20:42:13 -0400977static void bcm2835_pull_config_set(struct bcm2835_pinctrl *pc,
978 unsigned int pin, unsigned int arg)
979{
980 u32 off, bit;
981
982 off = GPIO_REG_OFFSET(pin);
983 bit = GPIO_REG_SHIFT(pin);
984
985 bcm2835_gpio_wr(pc, GPPUD, arg & 3);
986 /*
987 * BCM2835 datasheet say to wait 150 cycles, but not of what.
988 * But the VideoCore firmware delay for this operation
989 * based nearly on the same amount of VPU cycles and this clock
990 * runs at 250 MHz.
991 */
992 udelay(1);
993 bcm2835_gpio_wr(pc, GPPUDCLK0 + (off * 4), BIT(bit));
994 udelay(1);
995 bcm2835_gpio_wr(pc, GPPUDCLK0 + (off * 4), 0);
996}
997
Simon Arlotte1b2dc72012-09-27 22:10:11 -0600998static int bcm2835_pinconf_set(struct pinctrl_dev *pctldev,
Matheus Castello0de70492018-04-30 20:42:13 -0400999 unsigned int pin, unsigned long *configs,
1000 unsigned int num_configs)
Simon Arlotte1b2dc72012-09-27 22:10:11 -06001001{
1002 struct bcm2835_pinctrl *pc = pinctrl_dev_get_drvdata(pctldev);
Matheus Castello0de70492018-04-30 20:42:13 -04001003 u32 param, arg;
Sherman Yin03b054e2013-08-27 11:32:12 -07001004 int i;
Simon Arlotte1b2dc72012-09-27 22:10:11 -06001005
Sherman Yin03b054e2013-08-27 11:32:12 -07001006 for (i = 0; i < num_configs; i++) {
Matheus Castello0de70492018-04-30 20:42:13 -04001007 param = pinconf_to_config_param(configs[i]);
1008 arg = pinconf_to_config_argument(configs[i]);
Simon Arlotte1b2dc72012-09-27 22:10:11 -06001009
Matheus Castello0de70492018-04-30 20:42:13 -04001010 switch (param) {
1011 /* Set legacy brcm,pull */
1012 case BCM2835_PINCONF_PARAM_PULL:
1013 bcm2835_pull_config_set(pc, pin, arg);
1014 break;
1015
1016 /* Set pull generic bindings */
1017 case PIN_CONFIG_BIAS_DISABLE:
1018 bcm2835_pull_config_set(pc, pin, BCM2835_PUD_OFF);
1019 break;
1020
1021 case PIN_CONFIG_BIAS_PULL_DOWN:
1022 bcm2835_pull_config_set(pc, pin, BCM2835_PUD_DOWN);
1023 break;
1024
1025 case PIN_CONFIG_BIAS_PULL_UP:
1026 bcm2835_pull_config_set(pc, pin, BCM2835_PUD_UP);
1027 break;
1028
Matheus Castello90b60552018-04-30 20:42:14 -04001029 /* Set output-high or output-low */
1030 case PIN_CONFIG_OUTPUT:
1031 bcm2835_gpio_set_bit(pc, arg ? GPSET0 : GPCLR0, pin);
1032 break;
1033
Matheus Castello0de70492018-04-30 20:42:13 -04001034 default:
Stefan Wahrenb6e55312019-02-03 14:02:34 +01001035 return -ENOTSUPP;
Simon Arlotte1b2dc72012-09-27 22:10:11 -06001036
Matheus Castello0de70492018-04-30 20:42:13 -04001037 } /* switch param type */
Sherman Yin03b054e2013-08-27 11:32:12 -07001038 } /* for each config */
Simon Arlotte1b2dc72012-09-27 22:10:11 -06001039
1040 return 0;
1041}
1042
Laurent Pinchart022ab142013-02-16 10:25:07 +01001043static const struct pinconf_ops bcm2835_pinconf_ops = {
Stefan Wahren1cb66f02019-02-03 14:02:33 +01001044 .is_generic = true,
Simon Arlotte1b2dc72012-09-27 22:10:11 -06001045 .pin_config_get = bcm2835_pinconf_get,
1046 .pin_config_set = bcm2835_pinconf_set,
1047};
1048
Stefan Wahrene38a9a42019-07-22 08:23:25 +02001049static void bcm2711_pull_config_set(struct bcm2835_pinctrl *pc,
1050 unsigned int pin, unsigned int arg)
1051{
1052 u32 shifter;
1053 u32 value;
1054 u32 off;
1055
1056 off = PUD_2711_REG_OFFSET(pin);
1057 shifter = PUD_2711_REG_SHIFT(pin);
1058
1059 value = bcm2835_gpio_rd(pc, GP_GPIO_PUP_PDN_CNTRL_REG0 + (off * 4));
1060 value &= ~(PUD_2711_MASK << shifter);
1061 value |= (arg << shifter);
1062 bcm2835_gpio_wr(pc, GP_GPIO_PUP_PDN_CNTRL_REG0 + (off * 4), value);
1063}
1064
1065static int bcm2711_pinconf_set(struct pinctrl_dev *pctldev,
1066 unsigned int pin, unsigned long *configs,
1067 unsigned int num_configs)
1068{
1069 struct bcm2835_pinctrl *pc = pinctrl_dev_get_drvdata(pctldev);
1070 u32 param, arg;
1071 int i;
1072
1073 for (i = 0; i < num_configs; i++) {
1074 param = pinconf_to_config_param(configs[i]);
1075 arg = pinconf_to_config_argument(configs[i]);
1076
1077 switch (param) {
1078 /* convert legacy brcm,pull */
1079 case BCM2835_PINCONF_PARAM_PULL:
1080 if (arg == BCM2835_PUD_UP)
1081 arg = BCM2711_PULL_UP;
1082 else if (arg == BCM2835_PUD_DOWN)
1083 arg = BCM2711_PULL_DOWN;
1084 else
1085 arg = BCM2711_PULL_NONE;
1086
1087 bcm2711_pull_config_set(pc, pin, arg);
1088 break;
1089
1090 /* Set pull generic bindings */
1091 case PIN_CONFIG_BIAS_DISABLE:
1092 bcm2711_pull_config_set(pc, pin, BCM2711_PULL_NONE);
1093 break;
1094 case PIN_CONFIG_BIAS_PULL_DOWN:
1095 bcm2711_pull_config_set(pc, pin, BCM2711_PULL_DOWN);
1096 break;
1097 case PIN_CONFIG_BIAS_PULL_UP:
1098 bcm2711_pull_config_set(pc, pin, BCM2711_PULL_UP);
1099 break;
1100
1101 /* Set output-high or output-low */
1102 case PIN_CONFIG_OUTPUT:
1103 bcm2835_gpio_set_bit(pc, arg ? GPSET0 : GPCLR0, pin);
1104 break;
1105
1106 default:
1107 return -ENOTSUPP;
1108 }
1109 } /* for each config */
1110
1111 return 0;
1112}
1113
1114static const struct pinconf_ops bcm2711_pinconf_ops = {
1115 .is_generic = true,
1116 .pin_config_get = bcm2835_pinconf_get,
1117 .pin_config_set = bcm2711_pinconf_set,
1118};
1119
Stefan Wahren90bfaf02020-02-08 14:02:53 +01001120static const struct pinctrl_desc bcm2835_pinctrl_desc = {
Simon Arlotte1b2dc72012-09-27 22:10:11 -06001121 .name = MODULE_NAME,
1122 .pins = bcm2835_gpio_pins,
Stefan Wahrenb1d84a32020-02-08 14:02:54 +01001123 .npins = BCM2835_NUM_GPIOS,
Simon Arlotte1b2dc72012-09-27 22:10:11 -06001124 .pctlops = &bcm2835_pctl_ops,
1125 .pmxops = &bcm2835_pmx_ops,
1126 .confops = &bcm2835_pinconf_ops,
1127 .owner = THIS_MODULE,
1128};
1129
Stefan Wahren90bfaf02020-02-08 14:02:53 +01001130static const struct pinctrl_desc bcm2711_pinctrl_desc = {
Stefan Wahrenb1d84a32020-02-08 14:02:54 +01001131 .name = "pinctrl-bcm2711",
Stefan Wahren90bfaf02020-02-08 14:02:53 +01001132 .pins = bcm2835_gpio_pins,
Stefan Wahrenb1d84a32020-02-08 14:02:54 +01001133 .npins = BCM2711_NUM_GPIOS,
Stefan Wahren90bfaf02020-02-08 14:02:53 +01001134 .pctlops = &bcm2835_pctl_ops,
1135 .pmxops = &bcm2835_pmx_ops,
1136 .confops = &bcm2711_pinconf_ops,
1137 .owner = THIS_MODULE,
1138};
1139
1140static const struct pinctrl_gpio_range bcm2835_pinctrl_gpio_range = {
Simon Arlotte1b2dc72012-09-27 22:10:11 -06001141 .name = MODULE_NAME,
1142 .npins = BCM2835_NUM_GPIOS,
1143};
1144
Stefan Wahrenb1d84a32020-02-08 14:02:54 +01001145static const struct pinctrl_gpio_range bcm2711_pinctrl_gpio_range = {
1146 .name = "pinctrl-bcm2711",
1147 .npins = BCM2711_NUM_GPIOS,
1148};
1149
Stefan Wahren90bfaf02020-02-08 14:02:53 +01001150struct bcm_plat_data {
1151 const struct gpio_chip *gpio_chip;
1152 const struct pinctrl_desc *pctl_desc;
1153 const struct pinctrl_gpio_range *gpio_range;
1154};
1155
1156static const struct bcm_plat_data bcm2835_plat_data = {
1157 .gpio_chip = &bcm2835_gpio_chip,
1158 .pctl_desc = &bcm2835_pinctrl_desc,
1159 .gpio_range = &bcm2835_pinctrl_gpio_range,
1160};
1161
1162static const struct bcm_plat_data bcm2711_plat_data = {
Stefan Wahrenb1d84a32020-02-08 14:02:54 +01001163 .gpio_chip = &bcm2711_gpio_chip,
Stefan Wahren90bfaf02020-02-08 14:02:53 +01001164 .pctl_desc = &bcm2711_pinctrl_desc,
Stefan Wahrenb1d84a32020-02-08 14:02:54 +01001165 .gpio_range = &bcm2711_pinctrl_gpio_range,
Stefan Wahren90bfaf02020-02-08 14:02:53 +01001166};
1167
Stefan Wahrene38a9a42019-07-22 08:23:25 +02001168static const struct of_device_id bcm2835_pinctrl_match[] = {
1169 {
1170 .compatible = "brcm,bcm2835-gpio",
Stefan Wahren90bfaf02020-02-08 14:02:53 +01001171 .data = &bcm2835_plat_data,
Stefan Wahrene38a9a42019-07-22 08:23:25 +02001172 },
1173 {
1174 .compatible = "brcm,bcm2711-gpio",
Stefan Wahren90bfaf02020-02-08 14:02:53 +01001175 .data = &bcm2711_plat_data,
Stefan Wahrene38a9a42019-07-22 08:23:25 +02001176 },
Florian Fainelli562c8562020-05-30 17:11:00 -07001177 {
1178 .compatible = "brcm,bcm7211-gpio",
1179 .data = &bcm2711_plat_data,
1180 },
Stefan Wahrene38a9a42019-07-22 08:23:25 +02001181 {}
1182};
1183
Greg Kroah-Hartman150632b2012-12-21 13:10:23 -08001184static int bcm2835_pinctrl_probe(struct platform_device *pdev)
Simon Arlotte1b2dc72012-09-27 22:10:11 -06001185{
1186 struct device *dev = &pdev->dev;
1187 struct device_node *np = dev->of_node;
Stefan Wahren90bfaf02020-02-08 14:02:53 +01001188 const struct bcm_plat_data *pdata;
Simon Arlotte1b2dc72012-09-27 22:10:11 -06001189 struct bcm2835_pinctrl *pc;
Linus Walleij73345a12019-08-12 08:27:29 +02001190 struct gpio_irq_chip *girq;
Simon Arlotte1b2dc72012-09-27 22:10:11 -06001191 struct resource iomem;
1192 int err, i;
Stefan Wahrene38a9a42019-07-22 08:23:25 +02001193 const struct of_device_id *match;
Florian Fainelli920fecc2020-05-30 17:11:01 -07001194 int is_7211 = 0;
Stefan Wahrene38a9a42019-07-22 08:23:25 +02001195
Stefan Wahrenb1d84a32020-02-08 14:02:54 +01001196 BUILD_BUG_ON(ARRAY_SIZE(bcm2835_gpio_pins) != BCM2711_NUM_GPIOS);
1197 BUILD_BUG_ON(ARRAY_SIZE(bcm2835_gpio_groups) != BCM2711_NUM_GPIOS);
Simon Arlotte1b2dc72012-09-27 22:10:11 -06001198
1199 pc = devm_kzalloc(dev, sizeof(*pc), GFP_KERNEL);
1200 if (!pc)
1201 return -ENOMEM;
1202
1203 platform_set_drvdata(pdev, pc);
1204 pc->dev = dev;
1205
1206 err = of_address_to_resource(np, 0, &iomem);
1207 if (err) {
1208 dev_err(dev, "could not get IO memory\n");
1209 return err;
1210 }
1211
Thierry Reding9e0c1fb2013-01-21 11:09:14 +01001212 pc->base = devm_ioremap_resource(dev, &iomem);
1213 if (IS_ERR(pc->base))
1214 return PTR_ERR(pc->base);
Simon Arlotte1b2dc72012-09-27 22:10:11 -06001215
Stefan Wahren90bfaf02020-02-08 14:02:53 +01001216 match = of_match_node(bcm2835_pinctrl_match, pdev->dev.of_node);
1217 if (!match)
1218 return -EINVAL;
1219
1220 pdata = match->data;
Florian Fainelli920fecc2020-05-30 17:11:01 -07001221 is_7211 = of_device_is_compatible(np, "brcm,bcm7211-gpio");
Stefan Wahren90bfaf02020-02-08 14:02:53 +01001222
1223 pc->gpio_chip = *pdata->gpio_chip;
Linus Walleij58383c782015-11-04 09:56:26 +01001224 pc->gpio_chip.parent = dev;
Simon Arlotte1b2dc72012-09-27 22:10:11 -06001225 pc->gpio_chip.of_node = np;
1226
Simon Arlotte1b2dc72012-09-27 22:10:11 -06001227 for (i = 0; i < BCM2835_NUM_BANKS; i++) {
1228 unsigned long events;
1229 unsigned offset;
Simon Arlotte1b2dc72012-09-27 22:10:11 -06001230
1231 /* clear event detection flags */
1232 bcm2835_gpio_wr(pc, GPREN0 + i * 4, 0);
1233 bcm2835_gpio_wr(pc, GPFEN0 + i * 4, 0);
1234 bcm2835_gpio_wr(pc, GPHEN0 + i * 4, 0);
1235 bcm2835_gpio_wr(pc, GPLEN0 + i * 4, 0);
1236 bcm2835_gpio_wr(pc, GPAREN0 + i * 4, 0);
1237 bcm2835_gpio_wr(pc, GPAFEN0 + i * 4, 0);
1238
1239 /* clear all the events */
1240 events = bcm2835_gpio_rd(pc, GPEDS0 + i * 4);
1241 for_each_set_bit(offset, &events, 32)
1242 bcm2835_gpio_wr(pc, GPEDS0 + i * 4, BIT(offset));
1243
Lukas Wunner3c7b30f2018-10-27 10:15:33 +02001244 raw_spin_lock_init(&pc->irq_lock[i]);
Phil Elwell00445b52015-02-24 13:40:50 +00001245 }
1246
Phil Elwell266423e2021-12-06 09:22:36 +00001247 pc->pctl_desc = *pdata->pctl_desc;
1248 pc->pctl_dev = devm_pinctrl_register(dev, &pc->pctl_desc, pc);
1249 if (IS_ERR(pc->pctl_dev)) {
1250 gpiochip_remove(&pc->gpio_chip);
1251 return PTR_ERR(pc->pctl_dev);
1252 }
1253
1254 pc->gpio_range = *pdata->gpio_range;
1255 pc->gpio_range.base = pc->gpio_chip.base;
1256 pc->gpio_range.gc = &pc->gpio_chip;
1257 pinctrl_add_gpio_range(pc->pctl_dev, &pc->gpio_range);
1258
Linus Walleij73345a12019-08-12 08:27:29 +02001259 girq = &pc->gpio_chip.irq;
1260 girq->chip = &bcm2835_gpio_irq_chip;
1261 girq->parent_handler = bcm2835_gpio_irq_handler;
1262 girq->num_parents = BCM2835_NUM_IRQS;
1263 girq->parents = devm_kcalloc(dev, BCM2835_NUM_IRQS,
1264 sizeof(*girq->parents),
1265 GFP_KERNEL);
Phil Elwell266423e2021-12-06 09:22:36 +00001266 if (!girq->parents) {
1267 pinctrl_remove_gpio_range(pc->pctl_dev, &pc->gpio_range);
Linus Walleij73345a12019-08-12 08:27:29 +02001268 return -ENOMEM;
Phil Elwell266423e2021-12-06 09:22:36 +00001269 }
Florian Fainelli920fecc2020-05-30 17:11:01 -07001270
1271 if (is_7211) {
1272 pc->wake_irq = devm_kcalloc(dev, BCM2835_NUM_IRQS,
1273 sizeof(*pc->wake_irq),
1274 GFP_KERNEL);
1275 if (!pc->wake_irq)
1276 return -ENOMEM;
1277 }
1278
Linus Walleij73345a12019-08-12 08:27:29 +02001279 /*
1280 * Use the same handler for all groups: this is necessary
1281 * since we use one gpiochip to cover all lines - the
1282 * irq handler then needs to figure out which group and
1283 * bank that was firing the IRQ and look up the per-group
1284 * and bank data.
1285 */
Florian Fainelli920fecc2020-05-30 17:11:01 -07001286 for (i = 0; i < BCM2835_NUM_IRQS; i++) {
1287 int len;
1288 char *name;
1289
Linus Walleij73345a12019-08-12 08:27:29 +02001290 girq->parents[i] = irq_of_parse_and_map(np, i);
Phil Elwell4bc80da2021-05-21 12:01:58 +03001291 if (!is_7211) {
1292 if (!girq->parents[i]) {
1293 girq->num_parents = i;
1294 break;
1295 }
Florian Fainelli920fecc2020-05-30 17:11:01 -07001296 continue;
Phil Elwell4bc80da2021-05-21 12:01:58 +03001297 }
Florian Fainelli920fecc2020-05-30 17:11:01 -07001298 /* Skip over the all banks interrupts */
1299 pc->wake_irq[i] = irq_of_parse_and_map(np, i +
1300 BCM2835_NUM_IRQS + 1);
1301
1302 len = strlen(dev_name(pc->dev)) + 16;
1303 name = devm_kzalloc(pc->dev, len, GFP_KERNEL);
1304 if (!name)
1305 return -ENOMEM;
1306
1307 snprintf(name, len, "%s:bank%d", dev_name(pc->dev), i);
1308
1309 /* These are optional interrupts */
1310 err = devm_request_irq(dev, pc->wake_irq[i],
1311 bcm2835_gpio_wake_irq_handler,
1312 IRQF_SHARED, name, pc);
1313 if (err)
1314 dev_warn(dev, "unable to request wake IRQ %d\n",
1315 pc->wake_irq[i]);
1316 }
1317
Linus Walleij73345a12019-08-12 08:27:29 +02001318 girq->default_type = IRQ_TYPE_NONE;
1319 girq->handler = handle_level_irq;
1320
Linus Walleije19a5f72015-12-08 22:01:00 +01001321 err = gpiochip_add_data(&pc->gpio_chip, pc);
Simon Arlotte1b2dc72012-09-27 22:10:11 -06001322 if (err) {
1323 dev_err(dev, "could not add GPIO chip\n");
Phil Elwell266423e2021-12-06 09:22:36 +00001324 pinctrl_remove_gpio_range(pc->pctl_dev, &pc->gpio_range);
Simon Arlotte1b2dc72012-09-27 22:10:11 -06001325 return err;
1326 }
1327
Simon Arlotte1b2dc72012-09-27 22:10:11 -06001328 return 0;
1329}
1330
Simon Arlotte1b2dc72012-09-27 22:10:11 -06001331static struct platform_driver bcm2835_pinctrl_driver = {
1332 .probe = bcm2835_pinctrl_probe,
Simon Arlotte1b2dc72012-09-27 22:10:11 -06001333 .driver = {
1334 .name = MODULE_NAME,
Simon Arlotte1b2dc72012-09-27 22:10:11 -06001335 .of_match_table = bcm2835_pinctrl_match,
Paul Gortmaker34f46842017-05-22 16:56:48 -04001336 .suppress_bind_attrs = true,
Simon Arlotte1b2dc72012-09-27 22:10:11 -06001337 },
1338};
Florian Fainelli4434f4c52021-10-19 15:11:21 -07001339module_platform_driver(bcm2835_pinctrl_driver);
1340
1341MODULE_AUTHOR("Chris Boot");
1342MODULE_AUTHOR("Simon Arlott");
1343MODULE_AUTHOR("Stephen Warren");
1344MODULE_DESCRIPTION("Broadcom BCM2835/2711 pinctrl and GPIO driver");
1345MODULE_LICENSE("GPL");