blob: c4ebfa852b4249f7edbd14cc0b1256112815fed2 [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{
Hans Verkuil1a4541b2021-12-06 14:16:47 +0100316 struct bcm2835_pinctrl *pc = gpiochip_get_data(chip);
317
318 bcm2835_pinctrl_fsel_set(pc, offset, BCM2835_FSEL_GPIO_IN);
319 return 0;
Simon Arlotte1b2dc72012-09-27 22:10:11 -0600320}
321
322static int bcm2835_gpio_get(struct gpio_chip *chip, unsigned offset)
323{
Linus Walleije19a5f72015-12-08 22:01:00 +0100324 struct bcm2835_pinctrl *pc = gpiochip_get_data(chip);
Simon Arlotte1b2dc72012-09-27 22:10:11 -0600325
326 return bcm2835_gpio_get_bit(pc, GPLEV0, offset);
327}
328
Stefan Wahren20b3d2a2016-03-28 14:58:24 +0000329static int bcm2835_gpio_get_direction(struct gpio_chip *chip, unsigned int offset)
330{
331 struct bcm2835_pinctrl *pc = gpiochip_get_data(chip);
332 enum bcm2835_fsel fsel = bcm2835_pinctrl_fsel_get(pc, offset);
333
334 /* Alternative function doesn't clearly provide a direction */
335 if (fsel > BCM2835_FSEL_GPIO_OUT)
336 return -EINVAL;
337
Matti Vaittinen3c827872020-02-14 15:57:12 +0200338 if (fsel == BCM2835_FSEL_GPIO_IN)
339 return GPIO_LINE_DIRECTION_IN;
340
341 return GPIO_LINE_DIRECTION_OUT;
Stefan Wahren20b3d2a2016-03-28 14:58:24 +0000342}
343
Simon Arlotte1b2dc72012-09-27 22:10:11 -0600344static void bcm2835_gpio_set(struct gpio_chip *chip, unsigned offset, int value)
345{
Linus Walleije19a5f72015-12-08 22:01:00 +0100346 struct bcm2835_pinctrl *pc = gpiochip_get_data(chip);
Simon Arlotte1b2dc72012-09-27 22:10:11 -0600347
348 bcm2835_gpio_set_bit(pc, value ? GPSET0 : GPCLR0, offset);
349}
350
Stefan Wahren4c02cba2015-11-19 00:32:27 +0000351static int bcm2835_gpio_direction_output(struct gpio_chip *chip,
352 unsigned offset, int value)
353{
Hans Verkuil1a4541b2021-12-06 14:16:47 +0100354 struct bcm2835_pinctrl *pc = gpiochip_get_data(chip);
355
356 bcm2835_gpio_set_bit(pc, value ? GPSET0 : GPCLR0, offset);
357 bcm2835_pinctrl_fsel_set(pc, offset, BCM2835_FSEL_GPIO_OUT);
358 return 0;
Stefan Wahren4c02cba2015-11-19 00:32:27 +0000359}
360
Gustavo A. R. Silva531bcf72017-07-11 13:03:39 -0500361static const struct gpio_chip bcm2835_gpio_chip = {
Simon Arlotte1b2dc72012-09-27 22:10:11 -0600362 .label = MODULE_NAME,
363 .owner = THIS_MODULE,
Jonas Gorski98c85d52015-10-11 17:34:19 +0200364 .request = gpiochip_generic_request,
365 .free = gpiochip_generic_free,
Simon Arlotte1b2dc72012-09-27 22:10:11 -0600366 .direction_input = bcm2835_gpio_direction_input,
367 .direction_output = bcm2835_gpio_direction_output,
Stefan Wahren20b3d2a2016-03-28 14:58:24 +0000368 .get_direction = bcm2835_gpio_get_direction,
Simon Arlotte1b2dc72012-09-27 22:10:11 -0600369 .get = bcm2835_gpio_get,
370 .set = bcm2835_gpio_set,
Stefan Wahrenb6e55312019-02-03 14:02:34 +0100371 .set_config = gpiochip_generic_config,
Simon Arlotte1b2dc72012-09-27 22:10:11 -0600372 .base = -1,
373 .ngpio = BCM2835_NUM_GPIOS,
Linus Walleij9fb1f392013-12-04 14:42:46 +0100374 .can_sleep = false,
Simon Arlotte1b2dc72012-09-27 22:10:11 -0600375};
376
Stefan Wahrenb1d84a32020-02-08 14:02:54 +0100377static const struct gpio_chip bcm2711_gpio_chip = {
378 .label = "pinctrl-bcm2711",
379 .owner = THIS_MODULE,
380 .request = gpiochip_generic_request,
381 .free = gpiochip_generic_free,
382 .direction_input = bcm2835_gpio_direction_input,
383 .direction_output = bcm2835_gpio_direction_output,
384 .get_direction = bcm2835_gpio_get_direction,
385 .get = bcm2835_gpio_get,
386 .set = bcm2835_gpio_set,
387 .set_config = gpiochip_generic_config,
388 .base = -1,
389 .ngpio = BCM2711_NUM_GPIOS,
390 .can_sleep = false,
391};
392
Linus Walleij85ae9e52016-11-14 18:48:19 +0100393static void bcm2835_gpio_irq_handle_bank(struct bcm2835_pinctrl *pc,
394 unsigned int bank, u32 mask)
Simon Arlotte1b2dc72012-09-27 22:10:11 -0600395{
Simon Arlotte1b2dc72012-09-27 22:10:11 -0600396 unsigned long events;
397 unsigned offset;
398 unsigned gpio;
Simon Arlotte1b2dc72012-09-27 22:10:11 -0600399
400 events = bcm2835_gpio_rd(pc, GPEDS0 + bank * 4);
Phil Elwell00445b52015-02-24 13:40:50 +0000401 events &= mask;
Simon Arlotte1b2dc72012-09-27 22:10:11 -0600402 events &= pc->enabled_irq_map[bank];
403 for_each_set_bit(offset, &events, 32) {
404 gpio = (32 * bank) + offset;
Marc Zyngiera9cb09b2021-05-04 17:42:18 +0100405 generic_handle_domain_irq(pc->gpio_chip.irq.domain,
406 gpio);
Simon Arlotte1b2dc72012-09-27 22:10:11 -0600407 }
Phil Elwell00445b52015-02-24 13:40:50 +0000408}
409
Linus Walleij85ae9e52016-11-14 18:48:19 +0100410static void bcm2835_gpio_irq_handler(struct irq_desc *desc)
Phil Elwell00445b52015-02-24 13:40:50 +0000411{
Linus Walleij85ae9e52016-11-14 18:48:19 +0100412 struct gpio_chip *chip = irq_desc_get_handler_data(desc);
413 struct bcm2835_pinctrl *pc = gpiochip_get_data(chip);
414 struct irq_chip *host_chip = irq_desc_get_chip(desc);
415 int irq = irq_desc_get_irq(desc);
Linus Walleijdc1b2422021-12-09 14:45:13 +0100416 int group = 0;
Linus Walleij85ae9e52016-11-14 18:48:19 +0100417 int i;
Phil Elwell00445b52015-02-24 13:40:50 +0000418
Linus Walleij73345a12019-08-12 08:27:29 +0200419 for (i = 0; i < BCM2835_NUM_IRQS; i++) {
420 if (chip->irq.parents[i] == irq) {
Thierry Reding0d885e92017-07-20 18:59:12 +0200421 group = i;
Linus Walleij85ae9e52016-11-14 18:48:19 +0100422 break;
423 }
424 }
425 /* This should not happen, every IRQ has a bank */
Jason Wang29d45a62021-06-24 14:49:13 +0800426 BUG_ON(i == BCM2835_NUM_IRQS);
Linus Walleij85ae9e52016-11-14 18:48:19 +0100427
428 chained_irq_enter(host_chip, desc);
429
430 switch (group) {
Phil Elwell00445b52015-02-24 13:40:50 +0000431 case 0: /* IRQ0 covers GPIOs 0-27 */
Linus Walleij85ae9e52016-11-14 18:48:19 +0100432 bcm2835_gpio_irq_handle_bank(pc, 0, 0x0fffffff);
Phil Elwell00445b52015-02-24 13:40:50 +0000433 break;
434 case 1: /* IRQ1 covers GPIOs 28-45 */
Linus Walleij85ae9e52016-11-14 18:48:19 +0100435 bcm2835_gpio_irq_handle_bank(pc, 0, 0xf0000000);
436 bcm2835_gpio_irq_handle_bank(pc, 1, 0x00003fff);
Phil Elwell00445b52015-02-24 13:40:50 +0000437 break;
Stefan Wahrenb1d84a32020-02-08 14:02:54 +0100438 case 2: /* IRQ2 covers GPIOs 46-57 */
Linus Walleij85ae9e52016-11-14 18:48:19 +0100439 bcm2835_gpio_irq_handle_bank(pc, 1, 0x003fc000);
Phil Elwell00445b52015-02-24 13:40:50 +0000440 break;
441 }
442
Linus Walleij85ae9e52016-11-14 18:48:19 +0100443 chained_irq_exit(host_chip, desc);
Simon Arlotte1b2dc72012-09-27 22:10:11 -0600444}
445
Florian Fainelli920fecc2020-05-30 17:11:01 -0700446static irqreturn_t bcm2835_gpio_wake_irq_handler(int irq, void *dev_id)
447{
448 return IRQ_HANDLED;
449}
450
Simon Arlotte1b2dc72012-09-27 22:10:11 -0600451static inline void __bcm2835_gpio_irq_config(struct bcm2835_pinctrl *pc,
452 unsigned reg, unsigned offset, bool enable)
453{
454 u32 value;
455 reg += GPIO_REG_OFFSET(offset) * 4;
456 value = bcm2835_gpio_rd(pc, reg);
457 if (enable)
458 value |= BIT(GPIO_REG_SHIFT(offset));
459 else
460 value &= ~(BIT(GPIO_REG_SHIFT(offset)));
461 bcm2835_gpio_wr(pc, reg, value);
462}
463
464/* fast path for IRQ handler */
465static void bcm2835_gpio_irq_config(struct bcm2835_pinctrl *pc,
466 unsigned offset, bool enable)
467{
468 switch (pc->irq_type[offset]) {
469 case IRQ_TYPE_EDGE_RISING:
470 __bcm2835_gpio_irq_config(pc, GPREN0, offset, enable);
471 break;
472
473 case IRQ_TYPE_EDGE_FALLING:
474 __bcm2835_gpio_irq_config(pc, GPFEN0, offset, enable);
475 break;
476
477 case IRQ_TYPE_EDGE_BOTH:
478 __bcm2835_gpio_irq_config(pc, GPREN0, offset, enable);
479 __bcm2835_gpio_irq_config(pc, GPFEN0, offset, enable);
480 break;
481
482 case IRQ_TYPE_LEVEL_HIGH:
483 __bcm2835_gpio_irq_config(pc, GPHEN0, offset, enable);
484 break;
485
486 case IRQ_TYPE_LEVEL_LOW:
487 __bcm2835_gpio_irq_config(pc, GPLEN0, offset, enable);
488 break;
489 }
490}
491
492static void bcm2835_gpio_irq_enable(struct irq_data *data)
493{
Linus Walleij85ae9e52016-11-14 18:48:19 +0100494 struct gpio_chip *chip = irq_data_get_irq_chip_data(data);
495 struct bcm2835_pinctrl *pc = gpiochip_get_data(chip);
Simon Arlotte1b2dc72012-09-27 22:10:11 -0600496 unsigned gpio = irqd_to_hwirq(data);
497 unsigned offset = GPIO_REG_SHIFT(gpio);
498 unsigned bank = GPIO_REG_OFFSET(gpio);
499 unsigned long flags;
500
Lukas Wunner3c7b30f2018-10-27 10:15:33 +0200501 raw_spin_lock_irqsave(&pc->irq_lock[bank], flags);
Simon Arlotte1b2dc72012-09-27 22:10:11 -0600502 set_bit(offset, &pc->enabled_irq_map[bank]);
503 bcm2835_gpio_irq_config(pc, gpio, true);
Lukas Wunner3c7b30f2018-10-27 10:15:33 +0200504 raw_spin_unlock_irqrestore(&pc->irq_lock[bank], flags);
Simon Arlotte1b2dc72012-09-27 22:10:11 -0600505}
506
507static void bcm2835_gpio_irq_disable(struct irq_data *data)
508{
Linus Walleij85ae9e52016-11-14 18:48:19 +0100509 struct gpio_chip *chip = irq_data_get_irq_chip_data(data);
510 struct bcm2835_pinctrl *pc = gpiochip_get_data(chip);
Simon Arlotte1b2dc72012-09-27 22:10:11 -0600511 unsigned gpio = irqd_to_hwirq(data);
512 unsigned offset = GPIO_REG_SHIFT(gpio);
513 unsigned bank = GPIO_REG_OFFSET(gpio);
514 unsigned long flags;
515
Lukas Wunner3c7b30f2018-10-27 10:15:33 +0200516 raw_spin_lock_irqsave(&pc->irq_lock[bank], flags);
Simon Arlotte1b2dc72012-09-27 22:10:11 -0600517 bcm2835_gpio_irq_config(pc, gpio, false);
Jonathan Bell714b1dd2015-06-30 12:35:39 +0100518 /* Clear events that were latched prior to clearing event sources */
519 bcm2835_gpio_set_bit(pc, GPEDS0, gpio);
Simon Arlotte1b2dc72012-09-27 22:10:11 -0600520 clear_bit(offset, &pc->enabled_irq_map[bank]);
Lukas Wunner3c7b30f2018-10-27 10:15:33 +0200521 raw_spin_unlock_irqrestore(&pc->irq_lock[bank], flags);
Simon Arlotte1b2dc72012-09-27 22:10:11 -0600522}
523
524static int __bcm2835_gpio_irq_set_type_disabled(struct bcm2835_pinctrl *pc,
525 unsigned offset, unsigned int type)
526{
527 switch (type) {
528 case IRQ_TYPE_NONE:
529 case IRQ_TYPE_EDGE_RISING:
530 case IRQ_TYPE_EDGE_FALLING:
531 case IRQ_TYPE_EDGE_BOTH:
532 case IRQ_TYPE_LEVEL_HIGH:
533 case IRQ_TYPE_LEVEL_LOW:
534 pc->irq_type[offset] = type;
535 break;
536
537 default:
538 return -EINVAL;
539 }
540 return 0;
541}
542
543/* slower path for reconfiguring IRQ type */
544static int __bcm2835_gpio_irq_set_type_enabled(struct bcm2835_pinctrl *pc,
545 unsigned offset, unsigned int type)
546{
547 switch (type) {
548 case IRQ_TYPE_NONE:
549 if (pc->irq_type[offset] != type) {
550 bcm2835_gpio_irq_config(pc, offset, false);
551 pc->irq_type[offset] = type;
552 }
553 break;
554
555 case IRQ_TYPE_EDGE_RISING:
556 if (pc->irq_type[offset] == IRQ_TYPE_EDGE_BOTH) {
557 /* RISING already enabled, disable FALLING */
558 pc->irq_type[offset] = IRQ_TYPE_EDGE_FALLING;
559 bcm2835_gpio_irq_config(pc, offset, false);
560 pc->irq_type[offset] = type;
561 } else if (pc->irq_type[offset] != type) {
562 bcm2835_gpio_irq_config(pc, offset, false);
563 pc->irq_type[offset] = type;
564 bcm2835_gpio_irq_config(pc, offset, true);
565 }
566 break;
567
568 case IRQ_TYPE_EDGE_FALLING:
569 if (pc->irq_type[offset] == IRQ_TYPE_EDGE_BOTH) {
570 /* FALLING already enabled, disable RISING */
571 pc->irq_type[offset] = IRQ_TYPE_EDGE_RISING;
572 bcm2835_gpio_irq_config(pc, offset, false);
573 pc->irq_type[offset] = type;
574 } else if (pc->irq_type[offset] != type) {
575 bcm2835_gpio_irq_config(pc, offset, false);
576 pc->irq_type[offset] = type;
577 bcm2835_gpio_irq_config(pc, offset, true);
578 }
579 break;
580
581 case IRQ_TYPE_EDGE_BOTH:
582 if (pc->irq_type[offset] == IRQ_TYPE_EDGE_RISING) {
583 /* RISING already enabled, enable FALLING too */
584 pc->irq_type[offset] = IRQ_TYPE_EDGE_FALLING;
585 bcm2835_gpio_irq_config(pc, offset, true);
586 pc->irq_type[offset] = type;
587 } else if (pc->irq_type[offset] == IRQ_TYPE_EDGE_FALLING) {
588 /* FALLING already enabled, enable RISING too */
589 pc->irq_type[offset] = IRQ_TYPE_EDGE_RISING;
590 bcm2835_gpio_irq_config(pc, offset, true);
591 pc->irq_type[offset] = type;
592 } else if (pc->irq_type[offset] != type) {
593 bcm2835_gpio_irq_config(pc, offset, false);
594 pc->irq_type[offset] = type;
595 bcm2835_gpio_irq_config(pc, offset, true);
596 }
597 break;
598
599 case IRQ_TYPE_LEVEL_HIGH:
600 case IRQ_TYPE_LEVEL_LOW:
601 if (pc->irq_type[offset] != type) {
602 bcm2835_gpio_irq_config(pc, offset, false);
603 pc->irq_type[offset] = type;
604 bcm2835_gpio_irq_config(pc, offset, true);
605 }
606 break;
607
608 default:
609 return -EINVAL;
610 }
611 return 0;
612}
613
614static int bcm2835_gpio_irq_set_type(struct irq_data *data, unsigned int type)
615{
Linus Walleij85ae9e52016-11-14 18:48:19 +0100616 struct gpio_chip *chip = irq_data_get_irq_chip_data(data);
617 struct bcm2835_pinctrl *pc = gpiochip_get_data(chip);
Simon Arlotte1b2dc72012-09-27 22:10:11 -0600618 unsigned gpio = irqd_to_hwirq(data);
619 unsigned offset = GPIO_REG_SHIFT(gpio);
620 unsigned bank = GPIO_REG_OFFSET(gpio);
621 unsigned long flags;
622 int ret;
623
Lukas Wunner3c7b30f2018-10-27 10:15:33 +0200624 raw_spin_lock_irqsave(&pc->irq_lock[bank], flags);
Simon Arlotte1b2dc72012-09-27 22:10:11 -0600625
626 if (test_bit(offset, &pc->enabled_irq_map[bank]))
627 ret = __bcm2835_gpio_irq_set_type_enabled(pc, gpio, type);
628 else
629 ret = __bcm2835_gpio_irq_set_type_disabled(pc, gpio, type);
630
Charles Keepaxb8a19382015-04-07 11:43:45 +0100631 if (type & IRQ_TYPE_EDGE_BOTH)
Thomas Gleixner1aa74fd2015-06-23 15:52:41 +0200632 irq_set_handler_locked(data, handle_edge_irq);
Charles Keepaxb8a19382015-04-07 11:43:45 +0100633 else
Thomas Gleixner1aa74fd2015-06-23 15:52:41 +0200634 irq_set_handler_locked(data, handle_level_irq);
Charles Keepaxb8a19382015-04-07 11:43:45 +0100635
Lukas Wunner3c7b30f2018-10-27 10:15:33 +0200636 raw_spin_unlock_irqrestore(&pc->irq_lock[bank], flags);
Simon Arlotte1b2dc72012-09-27 22:10:11 -0600637
638 return ret;
639}
640
Charles Keepaxb8a19382015-04-07 11:43:45 +0100641static void bcm2835_gpio_irq_ack(struct irq_data *data)
642{
Linus Walleij85ae9e52016-11-14 18:48:19 +0100643 struct gpio_chip *chip = irq_data_get_irq_chip_data(data);
644 struct bcm2835_pinctrl *pc = gpiochip_get_data(chip);
Charles Keepaxb8a19382015-04-07 11:43:45 +0100645 unsigned gpio = irqd_to_hwirq(data);
646
647 bcm2835_gpio_set_bit(pc, GPEDS0, gpio);
648}
649
Florian Fainelli920fecc2020-05-30 17:11:01 -0700650static int bcm2835_gpio_irq_set_wake(struct irq_data *data, unsigned int on)
651{
652 struct gpio_chip *chip = irq_data_get_irq_chip_data(data);
653 struct bcm2835_pinctrl *pc = gpiochip_get_data(chip);
654 unsigned gpio = irqd_to_hwirq(data);
655 unsigned int irqgroup;
656 int ret = -EINVAL;
657
658 if (!pc->wake_irq)
659 return ret;
660
661 if (gpio <= 27)
662 irqgroup = 0;
663 else if (gpio >= 28 && gpio <= 45)
664 irqgroup = 1;
665 else if (gpio >= 46 && gpio <= 57)
666 irqgroup = 2;
667 else
668 return ret;
669
670 if (on)
671 ret = enable_irq_wake(pc->wake_irq[irqgroup]);
672 else
673 ret = disable_irq_wake(pc->wake_irq[irqgroup]);
674
675 return ret;
676}
677
Simon Arlotte1b2dc72012-09-27 22:10:11 -0600678static struct irq_chip bcm2835_gpio_irq_chip = {
679 .name = MODULE_NAME,
680 .irq_enable = bcm2835_gpio_irq_enable,
681 .irq_disable = bcm2835_gpio_irq_disable,
682 .irq_set_type = bcm2835_gpio_irq_set_type,
Charles Keepaxb8a19382015-04-07 11:43:45 +0100683 .irq_ack = bcm2835_gpio_irq_ack,
684 .irq_mask = bcm2835_gpio_irq_disable,
685 .irq_unmask = bcm2835_gpio_irq_enable,
Florian Fainelli920fecc2020-05-30 17:11:01 -0700686 .irq_set_wake = bcm2835_gpio_irq_set_wake,
687 .flags = IRQCHIP_MASK_ON_SUSPEND,
Simon Arlotte1b2dc72012-09-27 22:10:11 -0600688};
689
690static int bcm2835_pctl_get_groups_count(struct pinctrl_dev *pctldev)
691{
Stefan Wahrenb1d84a32020-02-08 14:02:54 +0100692 return BCM2835_NUM_GPIOS;
Simon Arlotte1b2dc72012-09-27 22:10:11 -0600693}
694
695static const char *bcm2835_pctl_get_group_name(struct pinctrl_dev *pctldev,
696 unsigned selector)
697{
698 return bcm2835_gpio_groups[selector];
699}
700
701static int bcm2835_pctl_get_group_pins(struct pinctrl_dev *pctldev,
702 unsigned selector,
703 const unsigned **pins,
704 unsigned *num_pins)
705{
706 *pins = &bcm2835_gpio_pins[selector].number;
707 *num_pins = 1;
708
709 return 0;
710}
711
712static void bcm2835_pctl_pin_dbg_show(struct pinctrl_dev *pctldev,
713 struct seq_file *s,
714 unsigned offset)
715{
716 struct bcm2835_pinctrl *pc = pinctrl_dev_get_drvdata(pctldev);
Linus Walleij85ae9e52016-11-14 18:48:19 +0100717 struct gpio_chip *chip = &pc->gpio_chip;
Simon Arlotte1b2dc72012-09-27 22:10:11 -0600718 enum bcm2835_fsel fsel = bcm2835_pinctrl_fsel_get(pc, offset);
719 const char *fname = bcm2835_functions[fsel];
720 int value = bcm2835_gpio_get_bit(pc, GPLEV0, offset);
Thierry Redingf0fbe7b2017-11-07 19:15:47 +0100721 int irq = irq_find_mapping(chip->irq.domain, offset);
Simon Arlotte1b2dc72012-09-27 22:10:11 -0600722
723 seq_printf(s, "function %s in %s; irq %d (%s)",
724 fname, value ? "hi" : "lo",
725 irq, irq_type_names[pc->irq_type[offset]]);
726}
727
728static void bcm2835_pctl_dt_free_map(struct pinctrl_dev *pctldev,
729 struct pinctrl_map *maps, unsigned num_maps)
730{
731 int i;
732
733 for (i = 0; i < num_maps; i++)
734 if (maps[i].type == PIN_MAP_TYPE_CONFIGS_PIN)
735 kfree(maps[i].data.configs.configs);
736
737 kfree(maps);
738}
739
740static int bcm2835_pctl_dt_node_to_map_func(struct bcm2835_pinctrl *pc,
741 struct device_node *np, u32 pin, u32 fnum,
742 struct pinctrl_map **maps)
743{
744 struct pinctrl_map *map = *maps;
745
746 if (fnum >= ARRAY_SIZE(bcm2835_functions)) {
Rob Herringf5292d02017-07-18 16:43:23 -0500747 dev_err(pc->dev, "%pOF: invalid brcm,function %d\n", np, fnum);
Simon Arlotte1b2dc72012-09-27 22:10:11 -0600748 return -EINVAL;
749 }
750
751 map->type = PIN_MAP_TYPE_MUX_GROUP;
752 map->data.mux.group = bcm2835_gpio_groups[pin];
753 map->data.mux.function = bcm2835_functions[fnum];
754 (*maps)++;
755
756 return 0;
757}
758
759static int bcm2835_pctl_dt_node_to_map_pull(struct bcm2835_pinctrl *pc,
760 struct device_node *np, u32 pin, u32 pull,
761 struct pinctrl_map **maps)
762{
763 struct pinctrl_map *map = *maps;
764 unsigned long *configs;
765
766 if (pull > 2) {
Rob Herringf5292d02017-07-18 16:43:23 -0500767 dev_err(pc->dev, "%pOF: invalid brcm,pull %d\n", np, pull);
Simon Arlotte1b2dc72012-09-27 22:10:11 -0600768 return -EINVAL;
769 }
770
771 configs = kzalloc(sizeof(*configs), GFP_KERNEL);
772 if (!configs)
773 return -ENOMEM;
Matheus Castello0de70492018-04-30 20:42:13 -0400774 configs[0] = pinconf_to_config_packed(BCM2835_PINCONF_PARAM_PULL, pull);
Simon Arlotte1b2dc72012-09-27 22:10:11 -0600775
776 map->type = PIN_MAP_TYPE_CONFIGS_PIN;
777 map->data.configs.group_or_pin = bcm2835_gpio_pins[pin].name;
778 map->data.configs.configs = configs;
779 map->data.configs.num_configs = 1;
780 (*maps)++;
781
782 return 0;
783}
784
Simon Arlotte1b2dc72012-09-27 22:10:11 -0600785static int bcm2835_pctl_dt_node_to_map(struct pinctrl_dev *pctldev,
786 struct device_node *np,
Matheus Castello0de70492018-04-30 20:42:13 -0400787 struct pinctrl_map **map, unsigned int *num_maps)
Simon Arlotte1b2dc72012-09-27 22:10:11 -0600788{
789 struct bcm2835_pinctrl *pc = pinctrl_dev_get_drvdata(pctldev);
790 struct property *pins, *funcs, *pulls;
791 int num_pins, num_funcs, num_pulls, maps_per_pin;
792 struct pinctrl_map *maps, *cur_map;
793 int i, err;
794 u32 pin, func, pull;
795
Matheus Castello0de70492018-04-30 20:42:13 -0400796 /* Check for generic binding in this node */
797 err = pinconf_generic_dt_node_to_map_all(pctldev, np, map, num_maps);
798 if (err || *num_maps)
799 return err;
800
801 /* Generic binding did not find anything continue with legacy parse */
Simon Arlotte1b2dc72012-09-27 22:10:11 -0600802 pins = of_find_property(np, "brcm,pins", NULL);
803 if (!pins) {
Rob Herringf5292d02017-07-18 16:43:23 -0500804 dev_err(pc->dev, "%pOF: missing brcm,pins property\n", np);
Simon Arlotte1b2dc72012-09-27 22:10:11 -0600805 return -EINVAL;
806 }
807
808 funcs = of_find_property(np, "brcm,function", NULL);
809 pulls = of_find_property(np, "brcm,pull", NULL);
810
811 if (!funcs && !pulls) {
812 dev_err(pc->dev,
Rob Herringf5292d02017-07-18 16:43:23 -0500813 "%pOF: neither brcm,function nor brcm,pull specified\n",
814 np);
Simon Arlotte1b2dc72012-09-27 22:10:11 -0600815 return -EINVAL;
816 }
817
818 num_pins = pins->length / 4;
819 num_funcs = funcs ? (funcs->length / 4) : 0;
820 num_pulls = pulls ? (pulls->length / 4) : 0;
821
822 if (num_funcs > 1 && num_funcs != num_pins) {
823 dev_err(pc->dev,
Rob Herringf5292d02017-07-18 16:43:23 -0500824 "%pOF: brcm,function must have 1 or %d entries\n",
825 np, num_pins);
Simon Arlotte1b2dc72012-09-27 22:10:11 -0600826 return -EINVAL;
827 }
828
829 if (num_pulls > 1 && num_pulls != num_pins) {
830 dev_err(pc->dev,
Rob Herringf5292d02017-07-18 16:43:23 -0500831 "%pOF: brcm,pull must have 1 or %d entries\n",
832 np, num_pins);
Simon Arlotte1b2dc72012-09-27 22:10:11 -0600833 return -EINVAL;
834 }
835
836 maps_per_pin = 0;
837 if (num_funcs)
838 maps_per_pin++;
839 if (num_pulls)
840 maps_per_pin++;
Kees Cook6396bb22018-06-12 14:03:40 -0700841 cur_map = maps = kcalloc(num_pins * maps_per_pin, sizeof(*maps),
842 GFP_KERNEL);
Simon Arlotte1b2dc72012-09-27 22:10:11 -0600843 if (!maps)
844 return -ENOMEM;
845
846 for (i = 0; i < num_pins; i++) {
Stephen Warrence63d6d2013-03-28 05:09:57 +0000847 err = of_property_read_u32_index(np, "brcm,pins", i, &pin);
848 if (err)
849 goto out;
Stefan Wahrenb1d84a32020-02-08 14:02:54 +0100850 if (pin >= pc->pctl_desc.npins) {
Rob Herringf5292d02017-07-18 16:43:23 -0500851 dev_err(pc->dev, "%pOF: invalid brcm,pins value %d\n",
852 np, pin);
Simon Arlotte1b2dc72012-09-27 22:10:11 -0600853 err = -EINVAL;
854 goto out;
855 }
856
857 if (num_funcs) {
Stephen Warrence63d6d2013-03-28 05:09:57 +0000858 err = of_property_read_u32_index(np, "brcm,function",
859 (num_funcs > 1) ? i : 0, &func);
860 if (err)
861 goto out;
Simon Arlotte1b2dc72012-09-27 22:10:11 -0600862 err = bcm2835_pctl_dt_node_to_map_func(pc, np, pin,
863 func, &cur_map);
864 if (err)
865 goto out;
866 }
867 if (num_pulls) {
Stephen Warrence63d6d2013-03-28 05:09:57 +0000868 err = of_property_read_u32_index(np, "brcm,pull",
Phil Elwell2c7e3302016-02-29 17:30:08 -0800869 (num_pulls > 1) ? i : 0, &pull);
Stephen Warrence63d6d2013-03-28 05:09:57 +0000870 if (err)
871 goto out;
Simon Arlotte1b2dc72012-09-27 22:10:11 -0600872 err = bcm2835_pctl_dt_node_to_map_pull(pc, np, pin,
873 pull, &cur_map);
874 if (err)
875 goto out;
876 }
877 }
878
879 *map = maps;
880 *num_maps = num_pins * maps_per_pin;
881
882 return 0;
883
884out:
Stefan Wahren53653c62015-12-21 00:44:04 +0000885 bcm2835_pctl_dt_free_map(pctldev, maps, num_pins * maps_per_pin);
Simon Arlotte1b2dc72012-09-27 22:10:11 -0600886 return err;
887}
888
Laurent Pinchart022ab142013-02-16 10:25:07 +0100889static const struct pinctrl_ops bcm2835_pctl_ops = {
Simon Arlotte1b2dc72012-09-27 22:10:11 -0600890 .get_groups_count = bcm2835_pctl_get_groups_count,
891 .get_group_name = bcm2835_pctl_get_group_name,
892 .get_group_pins = bcm2835_pctl_get_group_pins,
893 .pin_dbg_show = bcm2835_pctl_pin_dbg_show,
894 .dt_node_to_map = bcm2835_pctl_dt_node_to_map,
895 .dt_free_map = bcm2835_pctl_dt_free_map,
896};
897
Phil Elwellccca1ad2016-05-06 12:32:47 +0100898static int bcm2835_pmx_free(struct pinctrl_dev *pctldev,
899 unsigned offset)
900{
901 struct bcm2835_pinctrl *pc = pinctrl_dev_get_drvdata(pctldev);
902
903 /* disable by setting to GPIO_IN */
904 bcm2835_pinctrl_fsel_set(pc, offset, BCM2835_FSEL_GPIO_IN);
905 return 0;
906}
907
Simon Arlotte1b2dc72012-09-27 22:10:11 -0600908static int bcm2835_pmx_get_functions_count(struct pinctrl_dev *pctldev)
909{
910 return BCM2835_FSEL_COUNT;
911}
912
913static const char *bcm2835_pmx_get_function_name(struct pinctrl_dev *pctldev,
914 unsigned selector)
915{
916 return bcm2835_functions[selector];
917}
918
919static int bcm2835_pmx_get_function_groups(struct pinctrl_dev *pctldev,
920 unsigned selector,
921 const char * const **groups,
922 unsigned * const num_groups)
923{
924 /* every pin can do every function */
925 *groups = bcm2835_gpio_groups;
Stefan Wahrenb1d84a32020-02-08 14:02:54 +0100926 *num_groups = BCM2835_NUM_GPIOS;
Simon Arlotte1b2dc72012-09-27 22:10:11 -0600927
928 return 0;
929}
930
Linus Walleij03e9f0c2014-09-03 13:02:56 +0200931static int bcm2835_pmx_set(struct pinctrl_dev *pctldev,
Simon Arlotte1b2dc72012-09-27 22:10:11 -0600932 unsigned func_selector,
933 unsigned group_selector)
934{
935 struct bcm2835_pinctrl *pc = pinctrl_dev_get_drvdata(pctldev);
936
937 bcm2835_pinctrl_fsel_set(pc, group_selector, func_selector);
938
939 return 0;
940}
941
Simon Arlotte1b2dc72012-09-27 22:10:11 -0600942static void bcm2835_pmx_gpio_disable_free(struct pinctrl_dev *pctldev,
943 struct pinctrl_gpio_range *range,
944 unsigned offset)
945{
946 struct bcm2835_pinctrl *pc = pinctrl_dev_get_drvdata(pctldev);
947
948 /* disable by setting to GPIO_IN */
949 bcm2835_pinctrl_fsel_set(pc, offset, BCM2835_FSEL_GPIO_IN);
950}
951
952static int bcm2835_pmx_gpio_set_direction(struct pinctrl_dev *pctldev,
953 struct pinctrl_gpio_range *range,
954 unsigned offset,
955 bool input)
956{
957 struct bcm2835_pinctrl *pc = pinctrl_dev_get_drvdata(pctldev);
958 enum bcm2835_fsel fsel = input ?
959 BCM2835_FSEL_GPIO_IN : BCM2835_FSEL_GPIO_OUT;
960
961 bcm2835_pinctrl_fsel_set(pc, offset, fsel);
962
963 return 0;
964}
965
Laurent Pinchart022ab142013-02-16 10:25:07 +0100966static const struct pinmux_ops bcm2835_pmx_ops = {
Phil Elwellccca1ad2016-05-06 12:32:47 +0100967 .free = bcm2835_pmx_free,
Simon Arlotte1b2dc72012-09-27 22:10:11 -0600968 .get_functions_count = bcm2835_pmx_get_functions_count,
969 .get_function_name = bcm2835_pmx_get_function_name,
970 .get_function_groups = bcm2835_pmx_get_function_groups,
Linus Walleij03e9f0c2014-09-03 13:02:56 +0200971 .set_mux = bcm2835_pmx_set,
Simon Arlotte1b2dc72012-09-27 22:10:11 -0600972 .gpio_disable_free = bcm2835_pmx_gpio_disable_free,
973 .gpio_set_direction = bcm2835_pmx_gpio_set_direction,
974};
975
976static int bcm2835_pinconf_get(struct pinctrl_dev *pctldev,
977 unsigned pin, unsigned long *config)
978{
979 /* No way to read back config in HW */
980 return -ENOTSUPP;
981}
982
Matheus Castello0de70492018-04-30 20:42:13 -0400983static void bcm2835_pull_config_set(struct bcm2835_pinctrl *pc,
984 unsigned int pin, unsigned int arg)
985{
986 u32 off, bit;
987
988 off = GPIO_REG_OFFSET(pin);
989 bit = GPIO_REG_SHIFT(pin);
990
991 bcm2835_gpio_wr(pc, GPPUD, arg & 3);
992 /*
993 * BCM2835 datasheet say to wait 150 cycles, but not of what.
994 * But the VideoCore firmware delay for this operation
995 * based nearly on the same amount of VPU cycles and this clock
996 * runs at 250 MHz.
997 */
998 udelay(1);
999 bcm2835_gpio_wr(pc, GPPUDCLK0 + (off * 4), BIT(bit));
1000 udelay(1);
1001 bcm2835_gpio_wr(pc, GPPUDCLK0 + (off * 4), 0);
1002}
1003
Simon Arlotte1b2dc72012-09-27 22:10:11 -06001004static int bcm2835_pinconf_set(struct pinctrl_dev *pctldev,
Matheus Castello0de70492018-04-30 20:42:13 -04001005 unsigned int pin, unsigned long *configs,
1006 unsigned int num_configs)
Simon Arlotte1b2dc72012-09-27 22:10:11 -06001007{
1008 struct bcm2835_pinctrl *pc = pinctrl_dev_get_drvdata(pctldev);
Matheus Castello0de70492018-04-30 20:42:13 -04001009 u32 param, arg;
Sherman Yin03b054e2013-08-27 11:32:12 -07001010 int i;
Simon Arlotte1b2dc72012-09-27 22:10:11 -06001011
Sherman Yin03b054e2013-08-27 11:32:12 -07001012 for (i = 0; i < num_configs; i++) {
Matheus Castello0de70492018-04-30 20:42:13 -04001013 param = pinconf_to_config_param(configs[i]);
1014 arg = pinconf_to_config_argument(configs[i]);
Simon Arlotte1b2dc72012-09-27 22:10:11 -06001015
Matheus Castello0de70492018-04-30 20:42:13 -04001016 switch (param) {
1017 /* Set legacy brcm,pull */
1018 case BCM2835_PINCONF_PARAM_PULL:
1019 bcm2835_pull_config_set(pc, pin, arg);
1020 break;
1021
1022 /* Set pull generic bindings */
1023 case PIN_CONFIG_BIAS_DISABLE:
1024 bcm2835_pull_config_set(pc, pin, BCM2835_PUD_OFF);
1025 break;
1026
1027 case PIN_CONFIG_BIAS_PULL_DOWN:
1028 bcm2835_pull_config_set(pc, pin, BCM2835_PUD_DOWN);
1029 break;
1030
1031 case PIN_CONFIG_BIAS_PULL_UP:
1032 bcm2835_pull_config_set(pc, pin, BCM2835_PUD_UP);
1033 break;
1034
Matheus Castello90b60552018-04-30 20:42:14 -04001035 /* Set output-high or output-low */
1036 case PIN_CONFIG_OUTPUT:
1037 bcm2835_gpio_set_bit(pc, arg ? GPSET0 : GPCLR0, pin);
1038 break;
1039
Matheus Castello0de70492018-04-30 20:42:13 -04001040 default:
Stefan Wahrenb6e55312019-02-03 14:02:34 +01001041 return -ENOTSUPP;
Simon Arlotte1b2dc72012-09-27 22:10:11 -06001042
Matheus Castello0de70492018-04-30 20:42:13 -04001043 } /* switch param type */
Sherman Yin03b054e2013-08-27 11:32:12 -07001044 } /* for each config */
Simon Arlotte1b2dc72012-09-27 22:10:11 -06001045
1046 return 0;
1047}
1048
Laurent Pinchart022ab142013-02-16 10:25:07 +01001049static const struct pinconf_ops bcm2835_pinconf_ops = {
Stefan Wahren1cb66f02019-02-03 14:02:33 +01001050 .is_generic = true,
Simon Arlotte1b2dc72012-09-27 22:10:11 -06001051 .pin_config_get = bcm2835_pinconf_get,
1052 .pin_config_set = bcm2835_pinconf_set,
1053};
1054
Stefan Wahrene38a9a42019-07-22 08:23:25 +02001055static void bcm2711_pull_config_set(struct bcm2835_pinctrl *pc,
1056 unsigned int pin, unsigned int arg)
1057{
1058 u32 shifter;
1059 u32 value;
1060 u32 off;
1061
1062 off = PUD_2711_REG_OFFSET(pin);
1063 shifter = PUD_2711_REG_SHIFT(pin);
1064
1065 value = bcm2835_gpio_rd(pc, GP_GPIO_PUP_PDN_CNTRL_REG0 + (off * 4));
1066 value &= ~(PUD_2711_MASK << shifter);
1067 value |= (arg << shifter);
1068 bcm2835_gpio_wr(pc, GP_GPIO_PUP_PDN_CNTRL_REG0 + (off * 4), value);
1069}
1070
1071static int bcm2711_pinconf_set(struct pinctrl_dev *pctldev,
1072 unsigned int pin, unsigned long *configs,
1073 unsigned int num_configs)
1074{
1075 struct bcm2835_pinctrl *pc = pinctrl_dev_get_drvdata(pctldev);
1076 u32 param, arg;
1077 int i;
1078
1079 for (i = 0; i < num_configs; i++) {
1080 param = pinconf_to_config_param(configs[i]);
1081 arg = pinconf_to_config_argument(configs[i]);
1082
1083 switch (param) {
1084 /* convert legacy brcm,pull */
1085 case BCM2835_PINCONF_PARAM_PULL:
1086 if (arg == BCM2835_PUD_UP)
1087 arg = BCM2711_PULL_UP;
1088 else if (arg == BCM2835_PUD_DOWN)
1089 arg = BCM2711_PULL_DOWN;
1090 else
1091 arg = BCM2711_PULL_NONE;
1092
1093 bcm2711_pull_config_set(pc, pin, arg);
1094 break;
1095
1096 /* Set pull generic bindings */
1097 case PIN_CONFIG_BIAS_DISABLE:
1098 bcm2711_pull_config_set(pc, pin, BCM2711_PULL_NONE);
1099 break;
1100 case PIN_CONFIG_BIAS_PULL_DOWN:
1101 bcm2711_pull_config_set(pc, pin, BCM2711_PULL_DOWN);
1102 break;
1103 case PIN_CONFIG_BIAS_PULL_UP:
1104 bcm2711_pull_config_set(pc, pin, BCM2711_PULL_UP);
1105 break;
1106
1107 /* Set output-high or output-low */
1108 case PIN_CONFIG_OUTPUT:
1109 bcm2835_gpio_set_bit(pc, arg ? GPSET0 : GPCLR0, pin);
1110 break;
1111
1112 default:
1113 return -ENOTSUPP;
1114 }
1115 } /* for each config */
1116
1117 return 0;
1118}
1119
1120static const struct pinconf_ops bcm2711_pinconf_ops = {
1121 .is_generic = true,
1122 .pin_config_get = bcm2835_pinconf_get,
1123 .pin_config_set = bcm2711_pinconf_set,
1124};
1125
Stefan Wahren90bfaf02020-02-08 14:02:53 +01001126static const struct pinctrl_desc bcm2835_pinctrl_desc = {
Simon Arlotte1b2dc72012-09-27 22:10:11 -06001127 .name = MODULE_NAME,
1128 .pins = bcm2835_gpio_pins,
Stefan Wahrenb1d84a32020-02-08 14:02:54 +01001129 .npins = BCM2835_NUM_GPIOS,
Simon Arlotte1b2dc72012-09-27 22:10:11 -06001130 .pctlops = &bcm2835_pctl_ops,
1131 .pmxops = &bcm2835_pmx_ops,
1132 .confops = &bcm2835_pinconf_ops,
1133 .owner = THIS_MODULE,
1134};
1135
Stefan Wahren90bfaf02020-02-08 14:02:53 +01001136static const struct pinctrl_desc bcm2711_pinctrl_desc = {
Stefan Wahrenb1d84a32020-02-08 14:02:54 +01001137 .name = "pinctrl-bcm2711",
Stefan Wahren90bfaf02020-02-08 14:02:53 +01001138 .pins = bcm2835_gpio_pins,
Stefan Wahrenb1d84a32020-02-08 14:02:54 +01001139 .npins = BCM2711_NUM_GPIOS,
Stefan Wahren90bfaf02020-02-08 14:02:53 +01001140 .pctlops = &bcm2835_pctl_ops,
1141 .pmxops = &bcm2835_pmx_ops,
1142 .confops = &bcm2711_pinconf_ops,
1143 .owner = THIS_MODULE,
1144};
1145
1146static const struct pinctrl_gpio_range bcm2835_pinctrl_gpio_range = {
Simon Arlotte1b2dc72012-09-27 22:10:11 -06001147 .name = MODULE_NAME,
1148 .npins = BCM2835_NUM_GPIOS,
1149};
1150
Stefan Wahrenb1d84a32020-02-08 14:02:54 +01001151static const struct pinctrl_gpio_range bcm2711_pinctrl_gpio_range = {
1152 .name = "pinctrl-bcm2711",
1153 .npins = BCM2711_NUM_GPIOS,
1154};
1155
Stefan Wahren90bfaf02020-02-08 14:02:53 +01001156struct bcm_plat_data {
1157 const struct gpio_chip *gpio_chip;
1158 const struct pinctrl_desc *pctl_desc;
1159 const struct pinctrl_gpio_range *gpio_range;
1160};
1161
1162static const struct bcm_plat_data bcm2835_plat_data = {
1163 .gpio_chip = &bcm2835_gpio_chip,
1164 .pctl_desc = &bcm2835_pinctrl_desc,
1165 .gpio_range = &bcm2835_pinctrl_gpio_range,
1166};
1167
1168static const struct bcm_plat_data bcm2711_plat_data = {
Stefan Wahrenb1d84a32020-02-08 14:02:54 +01001169 .gpio_chip = &bcm2711_gpio_chip,
Stefan Wahren90bfaf02020-02-08 14:02:53 +01001170 .pctl_desc = &bcm2711_pinctrl_desc,
Stefan Wahrenb1d84a32020-02-08 14:02:54 +01001171 .gpio_range = &bcm2711_pinctrl_gpio_range,
Stefan Wahren90bfaf02020-02-08 14:02:53 +01001172};
1173
Stefan Wahrene38a9a42019-07-22 08:23:25 +02001174static const struct of_device_id bcm2835_pinctrl_match[] = {
1175 {
1176 .compatible = "brcm,bcm2835-gpio",
Stefan Wahren90bfaf02020-02-08 14:02:53 +01001177 .data = &bcm2835_plat_data,
Stefan Wahrene38a9a42019-07-22 08:23:25 +02001178 },
1179 {
1180 .compatible = "brcm,bcm2711-gpio",
Stefan Wahren90bfaf02020-02-08 14:02:53 +01001181 .data = &bcm2711_plat_data,
Stefan Wahrene38a9a42019-07-22 08:23:25 +02001182 },
Florian Fainelli562c8562020-05-30 17:11:00 -07001183 {
1184 .compatible = "brcm,bcm7211-gpio",
1185 .data = &bcm2711_plat_data,
1186 },
Stefan Wahrene38a9a42019-07-22 08:23:25 +02001187 {}
1188};
1189
Greg Kroah-Hartman150632b2012-12-21 13:10:23 -08001190static int bcm2835_pinctrl_probe(struct platform_device *pdev)
Simon Arlotte1b2dc72012-09-27 22:10:11 -06001191{
1192 struct device *dev = &pdev->dev;
1193 struct device_node *np = dev->of_node;
Stefan Wahren90bfaf02020-02-08 14:02:53 +01001194 const struct bcm_plat_data *pdata;
Simon Arlotte1b2dc72012-09-27 22:10:11 -06001195 struct bcm2835_pinctrl *pc;
Linus Walleij73345a12019-08-12 08:27:29 +02001196 struct gpio_irq_chip *girq;
Simon Arlotte1b2dc72012-09-27 22:10:11 -06001197 struct resource iomem;
1198 int err, i;
Stefan Wahrene38a9a42019-07-22 08:23:25 +02001199 const struct of_device_id *match;
Florian Fainelli920fecc2020-05-30 17:11:01 -07001200 int is_7211 = 0;
Stefan Wahrene38a9a42019-07-22 08:23:25 +02001201
Stefan Wahrenb1d84a32020-02-08 14:02:54 +01001202 BUILD_BUG_ON(ARRAY_SIZE(bcm2835_gpio_pins) != BCM2711_NUM_GPIOS);
1203 BUILD_BUG_ON(ARRAY_SIZE(bcm2835_gpio_groups) != BCM2711_NUM_GPIOS);
Simon Arlotte1b2dc72012-09-27 22:10:11 -06001204
1205 pc = devm_kzalloc(dev, sizeof(*pc), GFP_KERNEL);
1206 if (!pc)
1207 return -ENOMEM;
1208
1209 platform_set_drvdata(pdev, pc);
1210 pc->dev = dev;
1211
1212 err = of_address_to_resource(np, 0, &iomem);
1213 if (err) {
1214 dev_err(dev, "could not get IO memory\n");
1215 return err;
1216 }
1217
Thierry Reding9e0c1fb2013-01-21 11:09:14 +01001218 pc->base = devm_ioremap_resource(dev, &iomem);
1219 if (IS_ERR(pc->base))
1220 return PTR_ERR(pc->base);
Simon Arlotte1b2dc72012-09-27 22:10:11 -06001221
Stefan Wahren90bfaf02020-02-08 14:02:53 +01001222 match = of_match_node(bcm2835_pinctrl_match, pdev->dev.of_node);
1223 if (!match)
1224 return -EINVAL;
1225
1226 pdata = match->data;
Florian Fainelli920fecc2020-05-30 17:11:01 -07001227 is_7211 = of_device_is_compatible(np, "brcm,bcm7211-gpio");
Stefan Wahren90bfaf02020-02-08 14:02:53 +01001228
1229 pc->gpio_chip = *pdata->gpio_chip;
Linus Walleij58383c782015-11-04 09:56:26 +01001230 pc->gpio_chip.parent = dev;
Simon Arlotte1b2dc72012-09-27 22:10:11 -06001231
Simon Arlotte1b2dc72012-09-27 22:10:11 -06001232 for (i = 0; i < BCM2835_NUM_BANKS; i++) {
1233 unsigned long events;
1234 unsigned offset;
Simon Arlotte1b2dc72012-09-27 22:10:11 -06001235
1236 /* clear event detection flags */
1237 bcm2835_gpio_wr(pc, GPREN0 + i * 4, 0);
1238 bcm2835_gpio_wr(pc, GPFEN0 + i * 4, 0);
1239 bcm2835_gpio_wr(pc, GPHEN0 + i * 4, 0);
1240 bcm2835_gpio_wr(pc, GPLEN0 + i * 4, 0);
1241 bcm2835_gpio_wr(pc, GPAREN0 + i * 4, 0);
1242 bcm2835_gpio_wr(pc, GPAFEN0 + i * 4, 0);
1243
1244 /* clear all the events */
1245 events = bcm2835_gpio_rd(pc, GPEDS0 + i * 4);
1246 for_each_set_bit(offset, &events, 32)
1247 bcm2835_gpio_wr(pc, GPEDS0 + i * 4, BIT(offset));
1248
Lukas Wunner3c7b30f2018-10-27 10:15:33 +02001249 raw_spin_lock_init(&pc->irq_lock[i]);
Phil Elwell00445b52015-02-24 13:40:50 +00001250 }
1251
Phil Elwell266423e2021-12-06 09:22:36 +00001252 pc->pctl_desc = *pdata->pctl_desc;
1253 pc->pctl_dev = devm_pinctrl_register(dev, &pc->pctl_desc, pc);
1254 if (IS_ERR(pc->pctl_dev)) {
1255 gpiochip_remove(&pc->gpio_chip);
1256 return PTR_ERR(pc->pctl_dev);
1257 }
1258
1259 pc->gpio_range = *pdata->gpio_range;
1260 pc->gpio_range.base = pc->gpio_chip.base;
1261 pc->gpio_range.gc = &pc->gpio_chip;
1262 pinctrl_add_gpio_range(pc->pctl_dev, &pc->gpio_range);
1263
Linus Walleij73345a12019-08-12 08:27:29 +02001264 girq = &pc->gpio_chip.irq;
1265 girq->chip = &bcm2835_gpio_irq_chip;
1266 girq->parent_handler = bcm2835_gpio_irq_handler;
1267 girq->num_parents = BCM2835_NUM_IRQS;
1268 girq->parents = devm_kcalloc(dev, BCM2835_NUM_IRQS,
1269 sizeof(*girq->parents),
1270 GFP_KERNEL);
Phil Elwell266423e2021-12-06 09:22:36 +00001271 if (!girq->parents) {
1272 pinctrl_remove_gpio_range(pc->pctl_dev, &pc->gpio_range);
Linus Walleij73345a12019-08-12 08:27:29 +02001273 return -ENOMEM;
Phil Elwell266423e2021-12-06 09:22:36 +00001274 }
Florian Fainelli920fecc2020-05-30 17:11:01 -07001275
1276 if (is_7211) {
1277 pc->wake_irq = devm_kcalloc(dev, BCM2835_NUM_IRQS,
1278 sizeof(*pc->wake_irq),
1279 GFP_KERNEL);
1280 if (!pc->wake_irq)
1281 return -ENOMEM;
1282 }
1283
Linus Walleij73345a12019-08-12 08:27:29 +02001284 /*
1285 * Use the same handler for all groups: this is necessary
1286 * since we use one gpiochip to cover all lines - the
1287 * irq handler then needs to figure out which group and
1288 * bank that was firing the IRQ and look up the per-group
1289 * and bank data.
1290 */
Florian Fainelli920fecc2020-05-30 17:11:01 -07001291 for (i = 0; i < BCM2835_NUM_IRQS; i++) {
1292 int len;
1293 char *name;
1294
Linus Walleij73345a12019-08-12 08:27:29 +02001295 girq->parents[i] = irq_of_parse_and_map(np, i);
Phil Elwell4bc80da2021-05-21 12:01:58 +03001296 if (!is_7211) {
1297 if (!girq->parents[i]) {
1298 girq->num_parents = i;
1299 break;
1300 }
Florian Fainelli920fecc2020-05-30 17:11:01 -07001301 continue;
Phil Elwell4bc80da2021-05-21 12:01:58 +03001302 }
Florian Fainelli920fecc2020-05-30 17:11:01 -07001303 /* Skip over the all banks interrupts */
1304 pc->wake_irq[i] = irq_of_parse_and_map(np, i +
1305 BCM2835_NUM_IRQS + 1);
1306
1307 len = strlen(dev_name(pc->dev)) + 16;
1308 name = devm_kzalloc(pc->dev, len, GFP_KERNEL);
1309 if (!name)
1310 return -ENOMEM;
1311
1312 snprintf(name, len, "%s:bank%d", dev_name(pc->dev), i);
1313
1314 /* These are optional interrupts */
1315 err = devm_request_irq(dev, pc->wake_irq[i],
1316 bcm2835_gpio_wake_irq_handler,
1317 IRQF_SHARED, name, pc);
1318 if (err)
1319 dev_warn(dev, "unable to request wake IRQ %d\n",
1320 pc->wake_irq[i]);
1321 }
1322
Linus Walleij73345a12019-08-12 08:27:29 +02001323 girq->default_type = IRQ_TYPE_NONE;
1324 girq->handler = handle_level_irq;
1325
Linus Walleije19a5f72015-12-08 22:01:00 +01001326 err = gpiochip_add_data(&pc->gpio_chip, pc);
Simon Arlotte1b2dc72012-09-27 22:10:11 -06001327 if (err) {
1328 dev_err(dev, "could not add GPIO chip\n");
Phil Elwell266423e2021-12-06 09:22:36 +00001329 pinctrl_remove_gpio_range(pc->pctl_dev, &pc->gpio_range);
Simon Arlotte1b2dc72012-09-27 22:10:11 -06001330 return err;
1331 }
1332
Simon Arlotte1b2dc72012-09-27 22:10:11 -06001333 return 0;
1334}
1335
Simon Arlotte1b2dc72012-09-27 22:10:11 -06001336static struct platform_driver bcm2835_pinctrl_driver = {
1337 .probe = bcm2835_pinctrl_probe,
Simon Arlotte1b2dc72012-09-27 22:10:11 -06001338 .driver = {
1339 .name = MODULE_NAME,
Simon Arlotte1b2dc72012-09-27 22:10:11 -06001340 .of_match_table = bcm2835_pinctrl_match,
Paul Gortmaker34f46842017-05-22 16:56:48 -04001341 .suppress_bind_attrs = true,
Simon Arlotte1b2dc72012-09-27 22:10:11 -06001342 },
1343};
Florian Fainelli4434f4c52021-10-19 15:11:21 -07001344module_platform_driver(bcm2835_pinctrl_driver);
1345
1346MODULE_AUTHOR("Chris Boot");
1347MODULE_AUTHOR("Simon Arlott");
1348MODULE_AUTHOR("Stephen Warren");
1349MODULE_DESCRIPTION("Broadcom BCM2835/2711 pinctrl and GPIO driver");
1350MODULE_LICENSE("GPL");