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