Branch data Line data Source code
1 : : // SPDX-License-Identifier: GPL-2.0+
2 : : /*
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
10 : : */
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>
17 : : #include <linux/gpio/driver.h>
18 : : #include <linux/io.h>
19 : : #include <linux/irq.h>
20 : : #include <linux/irqdesc.h>
21 : : #include <linux/init.h>
22 : : #include <linux/of_address.h>
23 : : #include <linux/of.h>
24 : : #include <linux/of_irq.h>
25 : : #include <linux/pinctrl/consumer.h>
26 : : #include <linux/pinctrl/machine.h>
27 : : #include <linux/pinctrl/pinconf.h>
28 : : #include <linux/pinctrl/pinctrl.h>
29 : : #include <linux/pinctrl/pinmux.h>
30 : : #include <linux/pinctrl/pinconf-generic.h>
31 : : #include <linux/platform_device.h>
32 : : #include <linux/seq_file.h>
33 : : #include <linux/slab.h>
34 : : #include <linux/spinlock.h>
35 : : #include <linux/types.h>
36 : : #include <dt-bindings/pinctrl/bcm2835.h>
37 : :
38 : : #define MODULE_NAME "pinctrl-bcm2835"
39 : : #define BCM2835_NUM_GPIOS 54
40 : : #define BCM2835_NUM_BANKS 2
41 : : #define BCM2835_NUM_IRQS 3
42 : :
43 : : #define BCM2835_PIN_BITMAP_SZ \
44 : : DIV_ROUND_UP(BCM2835_NUM_GPIOS, sizeof(unsigned long) * 8)
45 : :
46 : : /* 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 */
60 : : #define GP_GPIO_PUP_PDN_CNTRL_REG0 0xe4 /* 2711 Pin Pull-up/down select */
61 : :
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 : :
67 : : #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 : :
71 : : /* argument: bcm2835_pinconf_pull */
72 : : #define BCM2835_PINCONF_PARAM_PULL (PIN_CONFIG_END + 1)
73 : :
74 : : #define BCM2711_PULL_NONE 0x0
75 : : #define BCM2711_PULL_UP 0x1
76 : : #define BCM2711_PULL_DOWN 0x2
77 : :
78 : : struct bcm2835_pinctrl {
79 : : struct device *dev;
80 : : void __iomem *base;
81 : : int irq[BCM2835_NUM_IRQS];
82 : :
83 : : /* note: locking assumes each bank will have its own unsigned long */
84 : : unsigned long enabled_irq_map[BCM2835_NUM_BANKS];
85 : : unsigned int irq_type[BCM2835_NUM_GPIOS];
86 : :
87 : : struct pinctrl_dev *pctl_dev;
88 : : struct gpio_chip gpio_chip;
89 : : struct pinctrl_gpio_range gpio_range;
90 : :
91 : : raw_spinlock_t irq_lock[BCM2835_NUM_BANKS];
92 : : };
93 : :
94 : : /* pins are just named GPIO0..GPIO53 */
95 : : #define BCM2835_GPIO_PIN(a) PINCTRL_PIN(a, "gpio" #a)
96 : : static struct pinctrl_pin_desc bcm2835_gpio_pins[] = {
97 : : BCM2835_GPIO_PIN(0),
98 : : BCM2835_GPIO_PIN(1),
99 : : BCM2835_GPIO_PIN(2),
100 : : BCM2835_GPIO_PIN(3),
101 : : BCM2835_GPIO_PIN(4),
102 : : BCM2835_GPIO_PIN(5),
103 : : BCM2835_GPIO_PIN(6),
104 : : BCM2835_GPIO_PIN(7),
105 : : BCM2835_GPIO_PIN(8),
106 : : BCM2835_GPIO_PIN(9),
107 : : BCM2835_GPIO_PIN(10),
108 : : BCM2835_GPIO_PIN(11),
109 : : BCM2835_GPIO_PIN(12),
110 : : BCM2835_GPIO_PIN(13),
111 : : BCM2835_GPIO_PIN(14),
112 : : BCM2835_GPIO_PIN(15),
113 : : BCM2835_GPIO_PIN(16),
114 : : BCM2835_GPIO_PIN(17),
115 : : BCM2835_GPIO_PIN(18),
116 : : BCM2835_GPIO_PIN(19),
117 : : BCM2835_GPIO_PIN(20),
118 : : BCM2835_GPIO_PIN(21),
119 : : BCM2835_GPIO_PIN(22),
120 : : BCM2835_GPIO_PIN(23),
121 : : BCM2835_GPIO_PIN(24),
122 : : BCM2835_GPIO_PIN(25),
123 : : BCM2835_GPIO_PIN(26),
124 : : BCM2835_GPIO_PIN(27),
125 : : BCM2835_GPIO_PIN(28),
126 : : BCM2835_GPIO_PIN(29),
127 : : BCM2835_GPIO_PIN(30),
128 : : BCM2835_GPIO_PIN(31),
129 : : BCM2835_GPIO_PIN(32),
130 : : BCM2835_GPIO_PIN(33),
131 : : BCM2835_GPIO_PIN(34),
132 : : BCM2835_GPIO_PIN(35),
133 : : BCM2835_GPIO_PIN(36),
134 : : BCM2835_GPIO_PIN(37),
135 : : BCM2835_GPIO_PIN(38),
136 : : BCM2835_GPIO_PIN(39),
137 : : BCM2835_GPIO_PIN(40),
138 : : BCM2835_GPIO_PIN(41),
139 : : BCM2835_GPIO_PIN(42),
140 : : BCM2835_GPIO_PIN(43),
141 : : BCM2835_GPIO_PIN(44),
142 : : BCM2835_GPIO_PIN(45),
143 : : BCM2835_GPIO_PIN(46),
144 : : BCM2835_GPIO_PIN(47),
145 : : BCM2835_GPIO_PIN(48),
146 : : BCM2835_GPIO_PIN(49),
147 : : BCM2835_GPIO_PIN(50),
148 : : BCM2835_GPIO_PIN(51),
149 : : BCM2835_GPIO_PIN(52),
150 : : BCM2835_GPIO_PIN(53),
151 : : };
152 : :
153 : : /* one pin per group */
154 : : static const char * const bcm2835_gpio_groups[] = {
155 : : "gpio0",
156 : : "gpio1",
157 : : "gpio2",
158 : : "gpio3",
159 : : "gpio4",
160 : : "gpio5",
161 : : "gpio6",
162 : : "gpio7",
163 : : "gpio8",
164 : : "gpio9",
165 : : "gpio10",
166 : : "gpio11",
167 : : "gpio12",
168 : : "gpio13",
169 : : "gpio14",
170 : : "gpio15",
171 : : "gpio16",
172 : : "gpio17",
173 : : "gpio18",
174 : : "gpio19",
175 : : "gpio20",
176 : : "gpio21",
177 : : "gpio22",
178 : : "gpio23",
179 : : "gpio24",
180 : : "gpio25",
181 : : "gpio26",
182 : : "gpio27",
183 : : "gpio28",
184 : : "gpio29",
185 : : "gpio30",
186 : : "gpio31",
187 : : "gpio32",
188 : : "gpio33",
189 : : "gpio34",
190 : : "gpio35",
191 : : "gpio36",
192 : : "gpio37",
193 : : "gpio38",
194 : : "gpio39",
195 : : "gpio40",
196 : : "gpio41",
197 : : "gpio42",
198 : : "gpio43",
199 : : "gpio44",
200 : : "gpio45",
201 : : "gpio46",
202 : : "gpio47",
203 : : "gpio48",
204 : : "gpio49",
205 : : "gpio50",
206 : : "gpio51",
207 : : "gpio52",
208 : : "gpio53",
209 : : };
210 : :
211 : : enum bcm2835_fsel {
212 : : BCM2835_FSEL_COUNT = 8,
213 : : BCM2835_FSEL_MASK = 0x7,
214 : : };
215 : :
216 : : static const char * const bcm2835_functions[BCM2835_FSEL_COUNT] = {
217 : : [BCM2835_FSEL_GPIO_IN] = "gpio_in",
218 : : [BCM2835_FSEL_GPIO_OUT] = "gpio_out",
219 : : [BCM2835_FSEL_ALT0] = "alt0",
220 : : [BCM2835_FSEL_ALT1] = "alt1",
221 : : [BCM2835_FSEL_ALT2] = "alt2",
222 : : [BCM2835_FSEL_ALT3] = "alt3",
223 : : [BCM2835_FSEL_ALT4] = "alt4",
224 : : [BCM2835_FSEL_ALT5] = "alt5",
225 : : };
226 : :
227 : : static const char * const irq_type_names[] = {
228 : : [IRQ_TYPE_NONE] = "none",
229 : : [IRQ_TYPE_EDGE_RISING] = "edge-rising",
230 : : [IRQ_TYPE_EDGE_FALLING] = "edge-falling",
231 : : [IRQ_TYPE_EDGE_BOTH] = "edge-both",
232 : : [IRQ_TYPE_LEVEL_HIGH] = "level-high",
233 : : [IRQ_TYPE_LEVEL_LOW] = "level-low",
234 : : };
235 : :
236 : : static inline u32 bcm2835_gpio_rd(struct bcm2835_pinctrl *pc, unsigned reg)
237 : : {
238 : 34776 : return readl(pc->base + reg);
239 : : }
240 : :
241 : : static inline void bcm2835_gpio_wr(struct bcm2835_pinctrl *pc, unsigned reg,
242 : : u32 val)
243 : : {
244 : 2432034 : writel(val, pc->base + reg);
245 : : }
246 : :
247 : : static inline int bcm2835_gpio_get_bit(struct bcm2835_pinctrl *pc, unsigned reg,
248 : : unsigned bit)
249 : : {
250 : 621 : reg += GPIO_REG_OFFSET(bit) * 4;
251 : 621 : return (bcm2835_gpio_rd(pc, reg) >> GPIO_REG_SHIFT(bit)) & 1;
252 : : }
253 : :
254 : : /* note NOT a read/modify/write cycle */
255 : : static inline void bcm2835_gpio_set_bit(struct bcm2835_pinctrl *pc,
256 : : unsigned reg, unsigned bit)
257 : : {
258 : 2424168 : reg += GPIO_REG_OFFSET(bit) * 4;
259 : 2424168 : bcm2835_gpio_wr(pc, reg, BIT(GPIO_REG_SHIFT(bit)));
260 : : }
261 : :
262 : : static inline enum bcm2835_fsel bcm2835_pinctrl_fsel_get(
263 : : struct bcm2835_pinctrl *pc, unsigned pin)
264 : : {
265 : 11592 : u32 val = bcm2835_gpio_rd(pc, FSEL_REG(pin));
266 : 11592 : enum bcm2835_fsel status = (val >> FSEL_SHIFT(pin)) & BCM2835_FSEL_MASK;
267 : :
268 : : dev_dbg(pc->dev, "get %08x (%u => %s)\n", val, pin,
269 : : bcm2835_functions[status]);
270 : :
271 : : return status;
272 : : }
273 : :
274 : 4761 : static inline void bcm2835_pinctrl_fsel_set(
275 : : struct bcm2835_pinctrl *pc, unsigned pin,
276 : : enum bcm2835_fsel fsel)
277 : : {
278 : 4761 : u32 val = bcm2835_gpio_rd(pc, FSEL_REG(pin));
279 : 4761 : enum bcm2835_fsel cur = (val >> FSEL_SHIFT(pin)) & BCM2835_FSEL_MASK;
280 : :
281 : : dev_dbg(pc->dev, "read %08x (%u => %s)\n", val, pin,
282 : : bcm2835_functions[cur]);
283 : :
284 [ + + ]: 4761 : if (cur == fsel)
285 : 4761 : return;
286 : :
287 [ + + ]: 4140 : if (cur != BCM2835_FSEL_GPIO_IN && fsel != BCM2835_FSEL_GPIO_IN) {
288 : : /* always transition through GPIO_IN */
289 : 1242 : val &= ~(BCM2835_FSEL_MASK << FSEL_SHIFT(pin));
290 : : val |= BCM2835_FSEL_GPIO_IN << FSEL_SHIFT(pin);
291 : :
292 : : dev_dbg(pc->dev, "trans %08x (%u <= %s)\n", val, pin,
293 : : bcm2835_functions[BCM2835_FSEL_GPIO_IN]);
294 : : bcm2835_gpio_wr(pc, FSEL_REG(pin), val);
295 : : }
296 : :
297 : 4140 : val &= ~(BCM2835_FSEL_MASK << FSEL_SHIFT(pin));
298 : 4140 : val |= fsel << FSEL_SHIFT(pin);
299 : :
300 : : dev_dbg(pc->dev, "write %08x (%u <= %s)\n", val, pin,
301 : : bcm2835_functions[fsel]);
302 : : bcm2835_gpio_wr(pc, FSEL_REG(pin), val);
303 : : }
304 : :
305 : 207 : static int bcm2835_gpio_direction_input(struct gpio_chip *chip, unsigned offset)
306 : : {
307 : 207 : return pinctrl_gpio_direction_input(chip->base + offset);
308 : : }
309 : :
310 : 621 : static int bcm2835_gpio_get(struct gpio_chip *chip, unsigned offset)
311 : : {
312 : 621 : struct bcm2835_pinctrl *pc = gpiochip_get_data(chip);
313 : :
314 : 621 : return bcm2835_gpio_get_bit(pc, GPLEV0, offset);
315 : : }
316 : :
317 : 11592 : static int bcm2835_gpio_get_direction(struct gpio_chip *chip, unsigned int offset)
318 : : {
319 : 11592 : struct bcm2835_pinctrl *pc = gpiochip_get_data(chip);
320 : : enum bcm2835_fsel fsel = bcm2835_pinctrl_fsel_get(pc, offset);
321 : :
322 : : /* Alternative function doesn't clearly provide a direction */
323 [ + + ]: 11592 : if (fsel > BCM2835_FSEL_GPIO_OUT)
324 : : return -EINVAL;
325 : :
326 : 9315 : return (fsel == BCM2835_FSEL_GPIO_IN);
327 : : }
328 : :
329 : 2424168 : static void bcm2835_gpio_set(struct gpio_chip *chip, unsigned offset, int value)
330 : : {
331 : 2424168 : struct bcm2835_pinctrl *pc = gpiochip_get_data(chip);
332 : :
333 [ + + ]: 2424168 : bcm2835_gpio_set_bit(pc, value ? GPSET0 : GPCLR0, offset);
334 : 2424168 : }
335 : :
336 : 414 : static int bcm2835_gpio_direction_output(struct gpio_chip *chip,
337 : : unsigned offset, int value)
338 : : {
339 : 414 : bcm2835_gpio_set(chip, offset, value);
340 : 414 : return pinctrl_gpio_direction_output(chip->base + offset);
341 : : }
342 : :
343 : : static const struct gpio_chip bcm2835_gpio_chip = {
344 : : .label = MODULE_NAME,
345 : : .owner = THIS_MODULE,
346 : : .request = gpiochip_generic_request,
347 : : .free = gpiochip_generic_free,
348 : : .direction_input = bcm2835_gpio_direction_input,
349 : : .direction_output = bcm2835_gpio_direction_output,
350 : : .get_direction = bcm2835_gpio_get_direction,
351 : : .get = bcm2835_gpio_get,
352 : : .set = bcm2835_gpio_set,
353 : : .set_config = gpiochip_generic_config,
354 : : .base = 0,
355 : : .ngpio = BCM2835_NUM_GPIOS,
356 : : .can_sleep = false,
357 : : };
358 : :
359 : 0 : static void bcm2835_gpio_irq_handle_bank(struct bcm2835_pinctrl *pc,
360 : : unsigned int bank, u32 mask)
361 : : {
362 : : unsigned long events;
363 : : unsigned offset;
364 : : unsigned gpio;
365 : :
366 : 0 : events = bcm2835_gpio_rd(pc, GPEDS0 + bank * 4);
367 : 0 : events &= mask;
368 : 0 : events &= pc->enabled_irq_map[bank];
369 [ # # ]: 0 : for_each_set_bit(offset, &events, 32) {
370 : 0 : gpio = (32 * bank) + offset;
371 : 0 : generic_handle_irq(irq_linear_revmap(pc->gpio_chip.irq.domain,
372 : : gpio));
373 : : }
374 : 0 : }
375 : :
376 : 0 : static void bcm2835_gpio_irq_handler(struct irq_desc *desc)
377 : : {
378 : : struct gpio_chip *chip = irq_desc_get_handler_data(desc);
379 : 0 : struct bcm2835_pinctrl *pc = gpiochip_get_data(chip);
380 : : struct irq_chip *host_chip = irq_desc_get_chip(desc);
381 : 0 : int irq = irq_desc_get_irq(desc);
382 : : int group;
383 : : int i;
384 : :
385 [ # # ]: 0 : for (i = 0; i < ARRAY_SIZE(pc->irq); i++) {
386 [ # # ]: 0 : if (pc->irq[i] == irq) {
387 : 0 : group = i;
388 : 0 : break;
389 : : }
390 : : }
391 : : /* This should not happen, every IRQ has a bank */
392 [ # # ]: 0 : if (i == ARRAY_SIZE(pc->irq))
393 : 0 : BUG();
394 : :
395 : 0 : chained_irq_enter(host_chip, desc);
396 : :
397 [ # # # # ]: 0 : switch (group) {
398 : : case 0: /* IRQ0 covers GPIOs 0-27 */
399 : 0 : bcm2835_gpio_irq_handle_bank(pc, 0, 0x0fffffff);
400 : 0 : break;
401 : : case 1: /* IRQ1 covers GPIOs 28-45 */
402 : 0 : bcm2835_gpio_irq_handle_bank(pc, 0, 0xf0000000);
403 : 0 : bcm2835_gpio_irq_handle_bank(pc, 1, 0x00003fff);
404 : 0 : break;
405 : : case 2: /* IRQ2 covers GPIOs 46-53 */
406 : 0 : bcm2835_gpio_irq_handle_bank(pc, 1, 0x003fc000);
407 : 0 : break;
408 : : }
409 : :
410 : : chained_irq_exit(host_chip, desc);
411 : 0 : }
412 : :
413 : 0 : static inline void __bcm2835_gpio_irq_config(struct bcm2835_pinctrl *pc,
414 : : unsigned reg, unsigned offset, bool enable)
415 : : {
416 : : u32 value;
417 : 0 : reg += GPIO_REG_OFFSET(offset) * 4;
418 : : value = bcm2835_gpio_rd(pc, reg);
419 [ # # ]: 0 : if (enable)
420 : 0 : value |= BIT(GPIO_REG_SHIFT(offset));
421 : : else
422 : 0 : value &= ~(BIT(GPIO_REG_SHIFT(offset)));
423 : : bcm2835_gpio_wr(pc, reg, value);
424 : 0 : }
425 : :
426 : : /* fast path for IRQ handler */
427 : 0 : static void bcm2835_gpio_irq_config(struct bcm2835_pinctrl *pc,
428 : : unsigned offset, bool enable)
429 : : {
430 [ # # # # : 0 : switch (pc->irq_type[offset]) {
# # ]
431 : : case IRQ_TYPE_EDGE_RISING:
432 : 0 : __bcm2835_gpio_irq_config(pc, GPREN0, offset, enable);
433 : 0 : break;
434 : :
435 : : case IRQ_TYPE_EDGE_FALLING:
436 : 0 : __bcm2835_gpio_irq_config(pc, GPFEN0, offset, enable);
437 : 0 : break;
438 : :
439 : : case IRQ_TYPE_EDGE_BOTH:
440 : 0 : __bcm2835_gpio_irq_config(pc, GPREN0, offset, enable);
441 : 0 : __bcm2835_gpio_irq_config(pc, GPFEN0, offset, enable);
442 : 0 : break;
443 : :
444 : : case IRQ_TYPE_LEVEL_HIGH:
445 : 0 : __bcm2835_gpio_irq_config(pc, GPHEN0, offset, enable);
446 : 0 : break;
447 : :
448 : : case IRQ_TYPE_LEVEL_LOW:
449 : 0 : __bcm2835_gpio_irq_config(pc, GPLEN0, offset, enable);
450 : 0 : break;
451 : : }
452 : 0 : }
453 : :
454 : 0 : static void bcm2835_gpio_irq_enable(struct irq_data *data)
455 : : {
456 : : struct gpio_chip *chip = irq_data_get_irq_chip_data(data);
457 : 0 : struct bcm2835_pinctrl *pc = gpiochip_get_data(chip);
458 : : unsigned gpio = irqd_to_hwirq(data);
459 : 0 : unsigned offset = GPIO_REG_SHIFT(gpio);
460 : 0 : unsigned bank = GPIO_REG_OFFSET(gpio);
461 : : unsigned long flags;
462 : :
463 : 0 : raw_spin_lock_irqsave(&pc->irq_lock[bank], flags);
464 : 0 : set_bit(offset, &pc->enabled_irq_map[bank]);
465 : 0 : bcm2835_gpio_irq_config(pc, gpio, true);
466 : 0 : raw_spin_unlock_irqrestore(&pc->irq_lock[bank], flags);
467 : 0 : }
468 : :
469 : 0 : static void bcm2835_gpio_irq_disable(struct irq_data *data)
470 : : {
471 : : struct gpio_chip *chip = irq_data_get_irq_chip_data(data);
472 : 0 : struct bcm2835_pinctrl *pc = gpiochip_get_data(chip);
473 : : unsigned gpio = irqd_to_hwirq(data);
474 : 0 : unsigned offset = GPIO_REG_SHIFT(gpio);
475 : 0 : unsigned bank = GPIO_REG_OFFSET(gpio);
476 : : unsigned long flags;
477 : :
478 : 0 : raw_spin_lock_irqsave(&pc->irq_lock[bank], flags);
479 : 0 : bcm2835_gpio_irq_config(pc, gpio, false);
480 : : /* Clear events that were latched prior to clearing event sources */
481 : : bcm2835_gpio_set_bit(pc, GPEDS0, gpio);
482 : 0 : clear_bit(offset, &pc->enabled_irq_map[bank]);
483 : 0 : raw_spin_unlock_irqrestore(&pc->irq_lock[bank], flags);
484 : 0 : }
485 : :
486 : : static int __bcm2835_gpio_irq_set_type_disabled(struct bcm2835_pinctrl *pc,
487 : : unsigned offset, unsigned int type)
488 : : {
489 [ # # ]: 0 : switch (type) {
490 : : case IRQ_TYPE_NONE:
491 : : case IRQ_TYPE_EDGE_RISING:
492 : : case IRQ_TYPE_EDGE_FALLING:
493 : : case IRQ_TYPE_EDGE_BOTH:
494 : : case IRQ_TYPE_LEVEL_HIGH:
495 : : case IRQ_TYPE_LEVEL_LOW:
496 : 0 : pc->irq_type[offset] = type;
497 : : break;
498 : :
499 : : default:
500 : : return -EINVAL;
501 : : }
502 : : return 0;
503 : : }
504 : :
505 : : /* slower path for reconfiguring IRQ type */
506 : 0 : static int __bcm2835_gpio_irq_set_type_enabled(struct bcm2835_pinctrl *pc,
507 : : unsigned offset, unsigned int type)
508 : : {
509 [ # # # # : 0 : switch (type) {
# # ]
510 : : case IRQ_TYPE_NONE:
511 [ # # ]: 0 : if (pc->irq_type[offset] != type) {
512 : 0 : bcm2835_gpio_irq_config(pc, offset, false);
513 : 0 : pc->irq_type[offset] = type;
514 : : }
515 : : break;
516 : :
517 : : case IRQ_TYPE_EDGE_RISING:
518 [ # # ]: 0 : if (pc->irq_type[offset] == IRQ_TYPE_EDGE_BOTH) {
519 : : /* RISING already enabled, disable FALLING */
520 : 0 : pc->irq_type[offset] = IRQ_TYPE_EDGE_FALLING;
521 : 0 : bcm2835_gpio_irq_config(pc, offset, false);
522 : 0 : pc->irq_type[offset] = type;
523 [ # # ]: 0 : } else if (pc->irq_type[offset] != type) {
524 : 0 : bcm2835_gpio_irq_config(pc, offset, false);
525 : 0 : pc->irq_type[offset] = type;
526 : 0 : bcm2835_gpio_irq_config(pc, offset, true);
527 : : }
528 : : break;
529 : :
530 : : case IRQ_TYPE_EDGE_FALLING:
531 [ # # ]: 0 : if (pc->irq_type[offset] == IRQ_TYPE_EDGE_BOTH) {
532 : : /* FALLING already enabled, disable RISING */
533 : 0 : pc->irq_type[offset] = IRQ_TYPE_EDGE_RISING;
534 : 0 : bcm2835_gpio_irq_config(pc, offset, false);
535 : 0 : pc->irq_type[offset] = type;
536 [ # # ]: 0 : } else if (pc->irq_type[offset] != type) {
537 : 0 : bcm2835_gpio_irq_config(pc, offset, false);
538 : 0 : pc->irq_type[offset] = type;
539 : 0 : bcm2835_gpio_irq_config(pc, offset, true);
540 : : }
541 : : break;
542 : :
543 : : case IRQ_TYPE_EDGE_BOTH:
544 [ # # ]: 0 : if (pc->irq_type[offset] == IRQ_TYPE_EDGE_RISING) {
545 : : /* RISING already enabled, enable FALLING too */
546 : 0 : pc->irq_type[offset] = IRQ_TYPE_EDGE_FALLING;
547 : 0 : bcm2835_gpio_irq_config(pc, offset, true);
548 : 0 : pc->irq_type[offset] = type;
549 [ # # ]: 0 : } else if (pc->irq_type[offset] == IRQ_TYPE_EDGE_FALLING) {
550 : : /* FALLING already enabled, enable RISING too */
551 : 0 : pc->irq_type[offset] = IRQ_TYPE_EDGE_RISING;
552 : 0 : bcm2835_gpio_irq_config(pc, offset, true);
553 : 0 : pc->irq_type[offset] = type;
554 [ # # ]: 0 : } else if (pc->irq_type[offset] != type) {
555 : 0 : bcm2835_gpio_irq_config(pc, offset, false);
556 : 0 : pc->irq_type[offset] = type;
557 : 0 : bcm2835_gpio_irq_config(pc, offset, true);
558 : : }
559 : : break;
560 : :
561 : : case IRQ_TYPE_LEVEL_HIGH:
562 : : case IRQ_TYPE_LEVEL_LOW:
563 [ # # ]: 0 : if (pc->irq_type[offset] != type) {
564 : 0 : bcm2835_gpio_irq_config(pc, offset, false);
565 : 0 : pc->irq_type[offset] = type;
566 : 0 : bcm2835_gpio_irq_config(pc, offset, true);
567 : : }
568 : : break;
569 : :
570 : : default:
571 : : return -EINVAL;
572 : : }
573 : : return 0;
574 : : }
575 : :
576 : 0 : static int bcm2835_gpio_irq_set_type(struct irq_data *data, unsigned int type)
577 : : {
578 : : struct gpio_chip *chip = irq_data_get_irq_chip_data(data);
579 : 0 : struct bcm2835_pinctrl *pc = gpiochip_get_data(chip);
580 : : unsigned gpio = irqd_to_hwirq(data);
581 : 0 : unsigned offset = GPIO_REG_SHIFT(gpio);
582 : 0 : unsigned bank = GPIO_REG_OFFSET(gpio);
583 : : unsigned long flags;
584 : : int ret;
585 : :
586 : 0 : raw_spin_lock_irqsave(&pc->irq_lock[bank], flags);
587 : :
588 [ # # ]: 0 : if (test_bit(offset, &pc->enabled_irq_map[bank]))
589 : 0 : ret = __bcm2835_gpio_irq_set_type_enabled(pc, gpio, type);
590 : : else
591 : : ret = __bcm2835_gpio_irq_set_type_disabled(pc, gpio, type);
592 : :
593 [ # # ]: 0 : if (type & IRQ_TYPE_EDGE_BOTH)
594 : : irq_set_handler_locked(data, handle_edge_irq);
595 : : else
596 : : irq_set_handler_locked(data, handle_level_irq);
597 : :
598 : 0 : raw_spin_unlock_irqrestore(&pc->irq_lock[bank], flags);
599 : :
600 : 0 : return ret;
601 : : }
602 : :
603 : 0 : static void bcm2835_gpio_irq_ack(struct irq_data *data)
604 : : {
605 : : struct gpio_chip *chip = irq_data_get_irq_chip_data(data);
606 : 0 : struct bcm2835_pinctrl *pc = gpiochip_get_data(chip);
607 : : unsigned gpio = irqd_to_hwirq(data);
608 : :
609 : : bcm2835_gpio_set_bit(pc, GPEDS0, gpio);
610 : 0 : }
611 : :
612 : : static struct irq_chip bcm2835_gpio_irq_chip = {
613 : : .name = MODULE_NAME,
614 : : .irq_enable = bcm2835_gpio_irq_enable,
615 : : .irq_disable = bcm2835_gpio_irq_disable,
616 : : .irq_set_type = bcm2835_gpio_irq_set_type,
617 : : .irq_ack = bcm2835_gpio_irq_ack,
618 : : .irq_mask = bcm2835_gpio_irq_disable,
619 : : .irq_unmask = bcm2835_gpio_irq_enable,
620 : : };
621 : :
622 : 2898 : static int bcm2835_pctl_get_groups_count(struct pinctrl_dev *pctldev)
623 : : {
624 : 2898 : return ARRAY_SIZE(bcm2835_gpio_groups);
625 : : }
626 : :
627 : 145935 : static const char *bcm2835_pctl_get_group_name(struct pinctrl_dev *pctldev,
628 : : unsigned selector)
629 : : {
630 : 145935 : return bcm2835_gpio_groups[selector];
631 : : }
632 : :
633 : 4140 : static int bcm2835_pctl_get_group_pins(struct pinctrl_dev *pctldev,
634 : : unsigned selector,
635 : : const unsigned **pins,
636 : : unsigned *num_pins)
637 : : {
638 : 4140 : *pins = &bcm2835_gpio_pins[selector].number;
639 : 4140 : *num_pins = 1;
640 : :
641 : 4140 : return 0;
642 : : }
643 : :
644 : 0 : static void bcm2835_pctl_pin_dbg_show(struct pinctrl_dev *pctldev,
645 : : struct seq_file *s,
646 : : unsigned offset)
647 : : {
648 : 0 : struct bcm2835_pinctrl *pc = pinctrl_dev_get_drvdata(pctldev);
649 : : struct gpio_chip *chip = &pc->gpio_chip;
650 : : enum bcm2835_fsel fsel = bcm2835_pinctrl_fsel_get(pc, offset);
651 : 0 : const char *fname = bcm2835_functions[fsel];
652 : : int value = bcm2835_gpio_get_bit(pc, GPLEV0, offset);
653 : 0 : int irq = irq_find_mapping(chip->irq.domain, offset);
654 : :
655 [ # # ]: 0 : seq_printf(s, "function %s in %s; irq %d (%s)",
656 : : fname, value ? "hi" : "lo",
657 : 0 : irq, irq_type_names[pc->irq_type[offset]]);
658 : 0 : }
659 : :
660 : 207 : static void bcm2835_pctl_dt_free_map(struct pinctrl_dev *pctldev,
661 : : struct pinctrl_map *maps, unsigned num_maps)
662 : : {
663 : : int i;
664 : :
665 [ + + ]: 1449 : for (i = 0; i < num_maps; i++)
666 [ - + ]: 1242 : if (maps[i].type == PIN_MAP_TYPE_CONFIGS_PIN)
667 : 0 : kfree(maps[i].data.configs.configs);
668 : :
669 : 207 : kfree(maps);
670 : 207 : }
671 : :
672 : 2898 : static int bcm2835_pctl_dt_node_to_map_func(struct bcm2835_pinctrl *pc,
673 : : struct device_node *np, u32 pin, u32 fnum,
674 : : struct pinctrl_map **maps)
675 : : {
676 : 2898 : struct pinctrl_map *map = *maps;
677 : :
678 [ - + ]: 2898 : if (fnum >= ARRAY_SIZE(bcm2835_functions)) {
679 : 0 : dev_err(pc->dev, "%pOF: invalid brcm,function %d\n", np, fnum);
680 : 0 : return -EINVAL;
681 : : }
682 : :
683 : 2898 : map->type = PIN_MAP_TYPE_MUX_GROUP;
684 : 2898 : map->data.mux.group = bcm2835_gpio_groups[pin];
685 : 2898 : map->data.mux.function = bcm2835_functions[fnum];
686 : 2898 : (*maps)++;
687 : :
688 : 2898 : return 0;
689 : : }
690 : :
691 : 0 : static int bcm2835_pctl_dt_node_to_map_pull(struct bcm2835_pinctrl *pc,
692 : : struct device_node *np, u32 pin, u32 pull,
693 : : struct pinctrl_map **maps)
694 : : {
695 : 0 : struct pinctrl_map *map = *maps;
696 : : unsigned long *configs;
697 : :
698 [ # # ]: 0 : if (pull > 2) {
699 : 0 : dev_err(pc->dev, "%pOF: invalid brcm,pull %d\n", np, pull);
700 : 0 : return -EINVAL;
701 : : }
702 : :
703 : 0 : configs = kzalloc(sizeof(*configs), GFP_KERNEL);
704 [ # # ]: 0 : if (!configs)
705 : : return -ENOMEM;
706 : 0 : configs[0] = pinconf_to_config_packed(BCM2835_PINCONF_PARAM_PULL, pull);
707 : :
708 : 0 : map->type = PIN_MAP_TYPE_CONFIGS_PIN;
709 : 0 : map->data.configs.group_or_pin = bcm2835_gpio_pins[pin].name;
710 : 0 : map->data.configs.configs = configs;
711 : 0 : map->data.configs.num_configs = 1;
712 : 0 : (*maps)++;
713 : :
714 : 0 : return 0;
715 : : }
716 : :
717 : 621 : static int bcm2835_pctl_dt_node_to_map(struct pinctrl_dev *pctldev,
718 : : struct device_node *np,
719 : : struct pinctrl_map **map, unsigned int *num_maps)
720 : : {
721 : 621 : struct bcm2835_pinctrl *pc = pinctrl_dev_get_drvdata(pctldev);
722 : : struct property *pins, *funcs, *pulls;
723 : : int num_pins, num_funcs, num_pulls, maps_per_pin;
724 : : struct pinctrl_map *maps, *cur_map;
725 : : int i, err;
726 : : u32 pin, func, pull;
727 : :
728 : : /* Check for generic binding in this node */
729 : : err = pinconf_generic_dt_node_to_map_all(pctldev, np, map, num_maps);
730 [ + - + - ]: 621 : if (err || *num_maps)
731 : : return err;
732 : :
733 : : /* Generic binding did not find anything continue with legacy parse */
734 : 621 : pins = of_find_property(np, "brcm,pins", NULL);
735 [ - + ]: 621 : if (!pins) {
736 : 0 : dev_err(pc->dev, "%pOF: missing brcm,pins property\n", np);
737 : 0 : return -EINVAL;
738 : : }
739 : :
740 : 621 : funcs = of_find_property(np, "brcm,function", NULL);
741 : 621 : pulls = of_find_property(np, "brcm,pull", NULL);
742 : :
743 [ - + ]: 621 : if (!funcs && !pulls) {
744 : 0 : dev_err(pc->dev,
745 : : "%pOF: neither brcm,function nor brcm,pull specified\n",
746 : : np);
747 : 0 : return -EINVAL;
748 : : }
749 : :
750 : 621 : num_pins = pins->length / 4;
751 [ + - ]: 621 : num_funcs = funcs ? (funcs->length / 4) : 0;
752 [ - + ]: 621 : num_pulls = pulls ? (pulls->length / 4) : 0;
753 : :
754 [ - + ]: 621 : if (num_funcs > 1 && num_funcs != num_pins) {
755 : 0 : dev_err(pc->dev,
756 : : "%pOF: brcm,function must have 1 or %d entries\n",
757 : : np, num_pins);
758 : 0 : return -EINVAL;
759 : : }
760 : :
761 [ - + ]: 621 : if (num_pulls > 1 && num_pulls != num_pins) {
762 : 0 : dev_err(pc->dev,
763 : : "%pOF: brcm,pull must have 1 or %d entries\n",
764 : : np, num_pins);
765 : 0 : return -EINVAL;
766 : : }
767 : :
768 : : maps_per_pin = 0;
769 [ + - ]: 621 : if (num_funcs)
770 : : maps_per_pin++;
771 [ - + ]: 621 : if (num_pulls)
772 : 0 : maps_per_pin++;
773 : 1242 : cur_map = maps = kcalloc(num_pins * maps_per_pin, sizeof(*maps),
774 : : GFP_KERNEL);
775 [ + - ]: 621 : if (!maps)
776 : : return -ENOMEM;
777 : :
778 [ + + ]: 2898 : for (i = 0; i < num_pins; i++) {
779 : 2898 : err = of_property_read_u32_index(np, "brcm,pins", i, &pin);
780 [ + - ]: 2898 : if (err)
781 : : goto out;
782 [ - + ]: 2898 : if (pin >= ARRAY_SIZE(bcm2835_gpio_pins)) {
783 : 0 : dev_err(pc->dev, "%pOF: invalid brcm,pins value %d\n",
784 : : np, pin);
785 : : err = -EINVAL;
786 : 0 : goto out;
787 : : }
788 : :
789 [ + - ]: 2898 : if (num_funcs) {
790 [ - + ]: 2898 : err = of_property_read_u32_index(np, "brcm,function",
791 : : (num_funcs > 1) ? i : 0, &func);
792 [ + - ]: 2898 : if (err)
793 : : goto out;
794 : 2898 : err = bcm2835_pctl_dt_node_to_map_func(pc, np, pin,
795 : : func, &cur_map);
796 [ + - ]: 2898 : if (err)
797 : : goto out;
798 : : }
799 [ - + ]: 2898 : if (num_pulls) {
800 [ # # ]: 0 : err = of_property_read_u32_index(np, "brcm,pull",
801 : : (num_pulls > 1) ? i : 0, &pull);
802 [ # # ]: 0 : if (err)
803 : : goto out;
804 : 0 : err = bcm2835_pctl_dt_node_to_map_pull(pc, np, pin,
805 : : pull, &cur_map);
806 [ # # ]: 0 : if (err)
807 : : goto out;
808 : : }
809 : : }
810 : :
811 : 621 : *map = maps;
812 : 621 : *num_maps = num_pins * maps_per_pin;
813 : :
814 : 621 : return 0;
815 : :
816 : : out:
817 : 0 : bcm2835_pctl_dt_free_map(pctldev, maps, num_pins * maps_per_pin);
818 : 0 : return err;
819 : : }
820 : :
821 : : static const struct pinctrl_ops bcm2835_pctl_ops = {
822 : : .get_groups_count = bcm2835_pctl_get_groups_count,
823 : : .get_group_name = bcm2835_pctl_get_group_name,
824 : : .get_group_pins = bcm2835_pctl_get_group_pins,
825 : : .pin_dbg_show = bcm2835_pctl_pin_dbg_show,
826 : : .dt_node_to_map = bcm2835_pctl_dt_node_to_map,
827 : : .dt_free_map = bcm2835_pctl_dt_free_map,
828 : : };
829 : :
830 : 1242 : static int bcm2835_pmx_free(struct pinctrl_dev *pctldev,
831 : : unsigned offset)
832 : : {
833 : 1242 : struct bcm2835_pinctrl *pc = pinctrl_dev_get_drvdata(pctldev);
834 : :
835 : : /* disable by setting to GPIO_IN */
836 : 1242 : bcm2835_pinctrl_fsel_set(pc, offset, BCM2835_FSEL_GPIO_IN);
837 : 1242 : return 0;
838 : : }
839 : :
840 : 3105 : static int bcm2835_pmx_get_functions_count(struct pinctrl_dev *pctldev)
841 : : {
842 : 3105 : return BCM2835_FSEL_COUNT;
843 : : }
844 : :
845 : 16146 : static const char *bcm2835_pmx_get_function_name(struct pinctrl_dev *pctldev,
846 : : unsigned selector)
847 : : {
848 : 16146 : return bcm2835_functions[selector];
849 : : }
850 : :
851 : 2898 : static int bcm2835_pmx_get_function_groups(struct pinctrl_dev *pctldev,
852 : : unsigned selector,
853 : : const char * const **groups,
854 : : unsigned * const num_groups)
855 : : {
856 : : /* every pin can do every function */
857 : 2898 : *groups = bcm2835_gpio_groups;
858 : 2898 : *num_groups = ARRAY_SIZE(bcm2835_gpio_groups);
859 : :
860 : 2898 : return 0;
861 : : }
862 : :
863 : 2898 : static int bcm2835_pmx_set(struct pinctrl_dev *pctldev,
864 : : unsigned func_selector,
865 : : unsigned group_selector)
866 : : {
867 : 2898 : struct bcm2835_pinctrl *pc = pinctrl_dev_get_drvdata(pctldev);
868 : :
869 : 2898 : bcm2835_pinctrl_fsel_set(pc, group_selector, func_selector);
870 : :
871 : 2898 : return 0;
872 : : }
873 : :
874 : 0 : static void bcm2835_pmx_gpio_disable_free(struct pinctrl_dev *pctldev,
875 : : struct pinctrl_gpio_range *range,
876 : : unsigned offset)
877 : : {
878 : 0 : struct bcm2835_pinctrl *pc = pinctrl_dev_get_drvdata(pctldev);
879 : :
880 : : /* disable by setting to GPIO_IN */
881 : 0 : bcm2835_pinctrl_fsel_set(pc, offset, BCM2835_FSEL_GPIO_IN);
882 : 0 : }
883 : :
884 : 621 : static int bcm2835_pmx_gpio_set_direction(struct pinctrl_dev *pctldev,
885 : : struct pinctrl_gpio_range *range,
886 : : unsigned offset,
887 : : bool input)
888 : : {
889 : 621 : struct bcm2835_pinctrl *pc = pinctrl_dev_get_drvdata(pctldev);
890 [ + + ]: 621 : enum bcm2835_fsel fsel = input ?
891 : : BCM2835_FSEL_GPIO_IN : BCM2835_FSEL_GPIO_OUT;
892 : :
893 : 621 : bcm2835_pinctrl_fsel_set(pc, offset, fsel);
894 : :
895 : 621 : return 0;
896 : : }
897 : :
898 : : static const struct pinmux_ops bcm2835_pmx_ops = {
899 : : .free = bcm2835_pmx_free,
900 : : .get_functions_count = bcm2835_pmx_get_functions_count,
901 : : .get_function_name = bcm2835_pmx_get_function_name,
902 : : .get_function_groups = bcm2835_pmx_get_function_groups,
903 : : .set_mux = bcm2835_pmx_set,
904 : : .gpio_disable_free = bcm2835_pmx_gpio_disable_free,
905 : : .gpio_set_direction = bcm2835_pmx_gpio_set_direction,
906 : : };
907 : :
908 : 0 : static int bcm2835_pinconf_get(struct pinctrl_dev *pctldev,
909 : : unsigned pin, unsigned long *config)
910 : : {
911 : : /* No way to read back config in HW */
912 : 0 : return -ENOTSUPP;
913 : : }
914 : :
915 : 0 : static void bcm2835_pull_config_set(struct bcm2835_pinctrl *pc,
916 : : unsigned int pin, unsigned int arg)
917 : : {
918 : : u32 off, bit;
919 : :
920 : 0 : off = GPIO_REG_OFFSET(pin);
921 : 0 : bit = GPIO_REG_SHIFT(pin);
922 : :
923 : 0 : bcm2835_gpio_wr(pc, GPPUD, arg & 3);
924 : : /*
925 : : * BCM2835 datasheet say to wait 150 cycles, but not of what.
926 : : * But the VideoCore firmware delay for this operation
927 : : * based nearly on the same amount of VPU cycles and this clock
928 : : * runs at 250 MHz.
929 : : */
930 : 0 : udelay(1);
931 : 0 : bcm2835_gpio_wr(pc, GPPUDCLK0 + (off * 4), BIT(bit));
932 : 0 : udelay(1);
933 : : bcm2835_gpio_wr(pc, GPPUDCLK0 + (off * 4), 0);
934 : 0 : }
935 : :
936 : 828 : static int bcm2835_pinconf_set(struct pinctrl_dev *pctldev,
937 : : unsigned int pin, unsigned long *configs,
938 : : unsigned int num_configs)
939 : : {
940 : 828 : struct bcm2835_pinctrl *pc = pinctrl_dev_get_drvdata(pctldev);
941 : : u32 param, arg;
942 : : int i;
943 : :
944 [ + - ]: 828 : for (i = 0; i < num_configs; i++) {
945 : 828 : param = pinconf_to_config_param(configs[i]);
946 : : arg = pinconf_to_config_argument(configs[i]);
947 : :
948 [ - - - - : 828 : switch (param) {
- + ]
949 : : /* Set legacy brcm,pull */
950 : : case BCM2835_PINCONF_PARAM_PULL:
951 : 0 : bcm2835_pull_config_set(pc, pin, arg);
952 : 0 : break;
953 : :
954 : : /* Set pull generic bindings */
955 : : case PIN_CONFIG_BIAS_DISABLE:
956 : 0 : bcm2835_pull_config_set(pc, pin, BCM2835_PUD_OFF);
957 : 0 : break;
958 : :
959 : : case PIN_CONFIG_BIAS_PULL_DOWN:
960 : 0 : bcm2835_pull_config_set(pc, pin, BCM2835_PUD_DOWN);
961 : 0 : break;
962 : :
963 : : case PIN_CONFIG_BIAS_PULL_UP:
964 : 0 : bcm2835_pull_config_set(pc, pin, BCM2835_PUD_UP);
965 : 0 : break;
966 : :
967 : : /* Set output-high or output-low */
968 : : case PIN_CONFIG_OUTPUT:
969 [ # # ]: 0 : bcm2835_gpio_set_bit(pc, arg ? GPSET0 : GPCLR0, pin);
970 : : break;
971 : :
972 : : default:
973 : : return -ENOTSUPP;
974 : :
975 : : } /* switch param type */
976 : : } /* for each config */
977 : :
978 : : return 0;
979 : : }
980 : :
981 : : static const struct pinconf_ops bcm2835_pinconf_ops = {
982 : : .is_generic = true,
983 : : .pin_config_get = bcm2835_pinconf_get,
984 : : .pin_config_set = bcm2835_pinconf_set,
985 : : };
986 : :
987 : 0 : static void bcm2711_pull_config_set(struct bcm2835_pinctrl *pc,
988 : : unsigned int pin, unsigned int arg)
989 : : {
990 : : u32 shifter;
991 : : u32 value;
992 : : u32 off;
993 : :
994 : 0 : off = PUD_2711_REG_OFFSET(pin);
995 : 0 : shifter = PUD_2711_REG_SHIFT(pin);
996 : :
997 : 0 : value = bcm2835_gpio_rd(pc, GP_GPIO_PUP_PDN_CNTRL_REG0 + (off * 4));
998 : 0 : value &= ~(PUD_2711_MASK << shifter);
999 : 0 : value |= (arg << shifter);
1000 : : bcm2835_gpio_wr(pc, GP_GPIO_PUP_PDN_CNTRL_REG0 + (off * 4), value);
1001 : 0 : }
1002 : :
1003 : 0 : static int bcm2711_pinconf_set(struct pinctrl_dev *pctldev,
1004 : : unsigned int pin, unsigned long *configs,
1005 : : unsigned int num_configs)
1006 : : {
1007 : 0 : struct bcm2835_pinctrl *pc = pinctrl_dev_get_drvdata(pctldev);
1008 : : u32 param, arg;
1009 : : int i;
1010 : :
1011 [ # # ]: 0 : for (i = 0; i < num_configs; i++) {
1012 : 0 : param = pinconf_to_config_param(configs[i]);
1013 : : arg = pinconf_to_config_argument(configs[i]);
1014 : :
1015 [ # # # # : 0 : switch (param) {
# # ]
1016 : : /* convert legacy brcm,pull */
1017 : : case BCM2835_PINCONF_PARAM_PULL:
1018 [ # # ]: 0 : if (arg == BCM2835_PUD_UP)
1019 : : arg = BCM2711_PULL_UP;
1020 [ # # ]: 0 : else if (arg == BCM2835_PUD_DOWN)
1021 : : arg = BCM2711_PULL_DOWN;
1022 : : else
1023 : : arg = BCM2711_PULL_NONE;
1024 : :
1025 : 0 : bcm2711_pull_config_set(pc, pin, arg);
1026 : 0 : break;
1027 : :
1028 : : /* Set pull generic bindings */
1029 : : case PIN_CONFIG_BIAS_DISABLE:
1030 : 0 : bcm2711_pull_config_set(pc, pin, BCM2711_PULL_NONE);
1031 : 0 : break;
1032 : : case PIN_CONFIG_BIAS_PULL_DOWN:
1033 : 0 : bcm2711_pull_config_set(pc, pin, BCM2711_PULL_DOWN);
1034 : 0 : break;
1035 : : case PIN_CONFIG_BIAS_PULL_UP:
1036 : 0 : bcm2711_pull_config_set(pc, pin, BCM2711_PULL_UP);
1037 : 0 : break;
1038 : :
1039 : : /* Set output-high or output-low */
1040 : : case PIN_CONFIG_OUTPUT:
1041 [ # # ]: 0 : bcm2835_gpio_set_bit(pc, arg ? GPSET0 : GPCLR0, pin);
1042 : : break;
1043 : :
1044 : : default:
1045 : : return -ENOTSUPP;
1046 : : }
1047 : : } /* for each config */
1048 : :
1049 : : return 0;
1050 : : }
1051 : :
1052 : : static const struct pinconf_ops bcm2711_pinconf_ops = {
1053 : : .is_generic = true,
1054 : : .pin_config_get = bcm2835_pinconf_get,
1055 : : .pin_config_set = bcm2711_pinconf_set,
1056 : : };
1057 : :
1058 : : static struct pinctrl_desc bcm2835_pinctrl_desc = {
1059 : : .name = MODULE_NAME,
1060 : : .pins = bcm2835_gpio_pins,
1061 : : .npins = ARRAY_SIZE(bcm2835_gpio_pins),
1062 : : .pctlops = &bcm2835_pctl_ops,
1063 : : .pmxops = &bcm2835_pmx_ops,
1064 : : .confops = &bcm2835_pinconf_ops,
1065 : : .owner = THIS_MODULE,
1066 : : };
1067 : :
1068 : : static struct pinctrl_gpio_range bcm2835_pinctrl_gpio_range = {
1069 : : .name = MODULE_NAME,
1070 : : .npins = BCM2835_NUM_GPIOS,
1071 : : };
1072 : :
1073 : : static const struct of_device_id bcm2835_pinctrl_match[] = {
1074 : : {
1075 : : .compatible = "brcm,bcm2835-gpio",
1076 : : .data = &bcm2835_pinconf_ops,
1077 : : },
1078 : : {
1079 : : .compatible = "brcm,bcm2711-gpio",
1080 : : .data = &bcm2711_pinconf_ops,
1081 : : },
1082 : : {}
1083 : : };
1084 : :
1085 : 207 : static int bcm2835_pinctrl_probe(struct platform_device *pdev)
1086 : : {
1087 : 207 : struct device *dev = &pdev->dev;
1088 : 207 : struct device_node *np = dev->of_node;
1089 : : struct bcm2835_pinctrl *pc;
1090 : : struct resource iomem;
1091 : : int err, i;
1092 : : const struct of_device_id *match;
1093 : :
1094 : : BUILD_BUG_ON(ARRAY_SIZE(bcm2835_gpio_pins) != BCM2835_NUM_GPIOS);
1095 : : BUILD_BUG_ON(ARRAY_SIZE(bcm2835_gpio_groups) != BCM2835_NUM_GPIOS);
1096 : :
1097 : : pc = devm_kzalloc(dev, sizeof(*pc), GFP_KERNEL);
1098 [ + - ]: 207 : if (!pc)
1099 : : return -ENOMEM;
1100 : :
1101 : : platform_set_drvdata(pdev, pc);
1102 : 207 : pc->dev = dev;
1103 : :
1104 : 207 : err = of_address_to_resource(np, 0, &iomem);
1105 [ - + ]: 207 : if (err) {
1106 : 0 : dev_err(dev, "could not get IO memory\n");
1107 : 0 : return err;
1108 : : }
1109 : :
1110 : 207 : pc->base = devm_ioremap_resource(dev, &iomem);
1111 [ - + ]: 207 : if (IS_ERR(pc->base))
1112 : 0 : return PTR_ERR(pc->base);
1113 : :
1114 : 207 : pc->gpio_chip = bcm2835_gpio_chip;
1115 : 207 : pc->gpio_chip.parent = dev;
1116 : 207 : pc->gpio_chip.of_node = np;
1117 : :
1118 [ + + ]: 621 : for (i = 0; i < BCM2835_NUM_BANKS; i++) {
1119 : : unsigned long events;
1120 : : unsigned offset;
1121 : :
1122 : : /* clear event detection flags */
1123 : 414 : bcm2835_gpio_wr(pc, GPREN0 + i * 4, 0);
1124 : 414 : bcm2835_gpio_wr(pc, GPFEN0 + i * 4, 0);
1125 : 414 : bcm2835_gpio_wr(pc, GPHEN0 + i * 4, 0);
1126 : 414 : bcm2835_gpio_wr(pc, GPLEN0 + i * 4, 0);
1127 : 414 : bcm2835_gpio_wr(pc, GPAREN0 + i * 4, 0);
1128 : 414 : bcm2835_gpio_wr(pc, GPAFEN0 + i * 4, 0);
1129 : :
1130 : : /* clear all the events */
1131 : 828 : events = bcm2835_gpio_rd(pc, GPEDS0 + i * 4);
1132 [ - + ]: 414 : for_each_set_bit(offset, &events, 32)
1133 : 0 : bcm2835_gpio_wr(pc, GPEDS0 + i * 4, BIT(offset));
1134 : :
1135 : 414 : raw_spin_lock_init(&pc->irq_lock[i]);
1136 : : }
1137 : :
1138 : 207 : match = of_match_node(bcm2835_pinctrl_match, pdev->dev.of_node);
1139 [ + - ]: 207 : if (match) {
1140 : 207 : bcm2835_pinctrl_desc.confops =
1141 : 207 : (const struct pinconf_ops *)match->data;
1142 : : }
1143 : :
1144 : 207 : pc->pctl_dev = devm_pinctrl_register(dev, &bcm2835_pinctrl_desc, pc);
1145 [ - + ]: 207 : if (IS_ERR(pc->pctl_dev))
1146 : 0 : return PTR_ERR(pc->pctl_dev);
1147 : :
1148 : 207 : pc->gpio_range = bcm2835_pinctrl_gpio_range;
1149 : 207 : pc->gpio_range.base = pc->gpio_chip.base;
1150 : 207 : pc->gpio_range.gc = &pc->gpio_chip;
1151 : 207 : pinctrl_add_gpio_range(pc->pctl_dev, &pc->gpio_range);
1152 : :
1153 : 207 : err = devm_gpiochip_add_data(dev, &pc->gpio_chip, pc);
1154 [ - + ]: 207 : if (err) {
1155 : 0 : dev_err(dev, "could not add GPIO chip\n");
1156 : 0 : pinctrl_remove_gpio_range(pc->pctl_dev, &pc->gpio_range);
1157 : 0 : return err;
1158 : : }
1159 : :
1160 : : err = gpiochip_irqchip_add(&pc->gpio_chip, &bcm2835_gpio_irq_chip,
1161 : : 0, handle_level_irq, IRQ_TYPE_NONE);
1162 [ + - ]: 207 : if (err) {
1163 : 0 : dev_info(dev, "could not add irqchip\n");
1164 : 0 : pinctrl_remove_gpio_range(pc->pctl_dev, &pc->gpio_range);
1165 : 0 : return err;
1166 : : }
1167 : :
1168 [ + + ]: 621 : for (i = 0; i < BCM2835_NUM_IRQS; i++) {
1169 : 621 : pc->irq[i] = irq_of_parse_and_map(np, i);
1170 : :
1171 [ + + ]: 621 : if (pc->irq[i] == 0)
1172 : 207 : continue;
1173 : :
1174 : : /*
1175 : : * Use the same handler for all groups: this is necessary
1176 : : * since we use one gpiochip to cover all lines - the
1177 : : * irq handler then needs to figure out which group and
1178 : : * bank that was firing the IRQ and look up the per-group
1179 : : * and bank data.
1180 : : */
1181 : 414 : gpiochip_set_chained_irqchip(&pc->gpio_chip,
1182 : : &bcm2835_gpio_irq_chip,
1183 : : pc->irq[i],
1184 : : bcm2835_gpio_irq_handler);
1185 : : }
1186 : :
1187 : : return 0;
1188 : : }
1189 : :
1190 : : static struct platform_driver bcm2835_pinctrl_driver = {
1191 : : .probe = bcm2835_pinctrl_probe,
1192 : : .driver = {
1193 : : .name = MODULE_NAME,
1194 : : .of_match_table = bcm2835_pinctrl_match,
1195 : : .suppress_bind_attrs = true,
1196 : : },
1197 : : };
1198 : 207 : builtin_platform_driver(bcm2835_pinctrl_driver);
|