Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
freebsd
GitHub Repository: freebsd/freebsd-src
Path: blob/main/sys/arm/broadcom/bcm2835/bcm2835_gpio.c
39566 views
1
/*-
2
* SPDX-License-Identifier: BSD-2-Clause
3
*
4
* Copyright (c) 2012 Oleksandr Tymoshenko <[email protected]>
5
* Copyright (c) 2012-2015 Luiz Otavio O Souza <[email protected]>
6
* All rights reserved.
7
*
8
* Redistribution and use in source and binary forms, with or without
9
* modification, are permitted provided that the following conditions
10
* are met:
11
* 1. Redistributions of source code must retain the above copyright
12
* notice, this list of conditions and the following disclaimer.
13
* 2. Redistributions in binary form must reproduce the above copyright
14
* notice, this list of conditions and the following disclaimer in the
15
* documentation and/or other materials provided with the distribution.
16
*
17
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
18
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
19
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
20
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
21
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
22
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
23
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
24
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
25
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
26
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
27
* SUCH DAMAGE.
28
*
29
*/
30
#include <sys/cdefs.h>
31
#include "opt_platform.h"
32
33
#include <sys/param.h>
34
#include <sys/systm.h>
35
#include <sys/bus.h>
36
#include <sys/gpio.h>
37
#include <sys/interrupt.h>
38
#include <sys/kernel.h>
39
#include <sys/lock.h>
40
#include <sys/module.h>
41
#include <sys/mutex.h>
42
#include <sys/proc.h>
43
#include <sys/rman.h>
44
#include <sys/sysctl.h>
45
46
#include <machine/bus.h>
47
#include <machine/intr.h>
48
49
#include <dev/fdt/fdt_pinctrl.h>
50
#include <dev/gpio/gpiobusvar.h>
51
#include <dev/ofw/ofw_bus.h>
52
53
#include "gpio_if.h"
54
55
#include "pic_if.h"
56
57
#ifdef DEBUG
58
#define dprintf(fmt, args...) do { printf("%s(): ", __func__); \
59
printf(fmt,##args); } while (0)
60
#else
61
#define dprintf(fmt, args...)
62
#endif
63
64
#define BCM_GPIO_IRQS 4
65
#define BCM_GPIO_PINS_PER_BANK 32
66
#define BCM2835_GPIO_PINS 54
67
#define BCM2711_GPIO_PINS 58
68
#define BCM_GPIO_PINS BCM2711_GPIO_PINS
69
70
#define BCM_GPIO_DEFAULT_CAPS (GPIO_PIN_INPUT | GPIO_PIN_OUTPUT | \
71
GPIO_PIN_PULLUP | GPIO_PIN_PULLDOWN | GPIO_INTR_LEVEL_LOW | \
72
GPIO_INTR_LEVEL_HIGH | GPIO_INTR_EDGE_RISING | \
73
GPIO_INTR_EDGE_FALLING | GPIO_INTR_EDGE_BOTH)
74
75
#define BCM2835_FSEL_GPIO_IN 0
76
#define BCM2835_FSEL_GPIO_OUT 1
77
#define BCM2835_FSEL_ALT5 2
78
#define BCM2835_FSEL_ALT4 3
79
#define BCM2835_FSEL_ALT0 4
80
#define BCM2835_FSEL_ALT1 5
81
#define BCM2835_FSEL_ALT2 6
82
#define BCM2835_FSEL_ALT3 7
83
84
#define BCM2835_PUD_OFF 0
85
#define BCM2835_PUD_DOWN 1
86
#define BCM2835_PUD_UP 2
87
88
#define BCM2711_PUD_OFF 0
89
#define BCM2711_PUD_DOWN 2
90
#define BCM2711_PUD_UP 1
91
92
static struct resource_spec bcm_gpio_res_spec[] = {
93
{ SYS_RES_MEMORY, 0, RF_ACTIVE },
94
{ SYS_RES_IRQ, 0, RF_ACTIVE }, /* bank 0 interrupt */
95
{ SYS_RES_IRQ, 1, RF_ACTIVE }, /* bank 1 interrupt */
96
{ -1, 0, 0 }
97
};
98
99
struct bcm_gpio_sysctl {
100
struct bcm_gpio_softc *sc;
101
uint32_t pin;
102
};
103
104
struct bcm_gpio_irqsrc {
105
struct intr_irqsrc bgi_isrc;
106
uint32_t bgi_irq;
107
uint32_t bgi_mode;
108
uint32_t bgi_mask;
109
};
110
111
struct bcm_gpio_softc {
112
device_t sc_dev;
113
device_t sc_busdev;
114
struct mtx sc_mtx;
115
struct resource * sc_res[BCM_GPIO_IRQS + 1];
116
bus_space_tag_t sc_bst;
117
bus_space_handle_t sc_bsh;
118
void * sc_intrhand[BCM_GPIO_IRQS];
119
bool sc_is2711;
120
u_int sc_maxpins;
121
int sc_gpio_npins;
122
int sc_ro_npins;
123
int sc_ro_pins[BCM_GPIO_PINS];
124
struct gpio_pin sc_gpio_pins[BCM_GPIO_PINS];
125
struct bcm_gpio_sysctl sc_sysctl[BCM_GPIO_PINS];
126
struct bcm_gpio_irqsrc sc_isrcs[BCM_GPIO_PINS];
127
};
128
129
enum bcm_gpio_pud {
130
BCM_GPIO_NONE,
131
BCM_GPIO_PULLDOWN,
132
BCM_GPIO_PULLUP,
133
};
134
135
#define BCM_GPIO_LOCK(_sc) mtx_lock_spin(&(_sc)->sc_mtx)
136
#define BCM_GPIO_UNLOCK(_sc) mtx_unlock_spin(&(_sc)->sc_mtx)
137
#define BCM_GPIO_LOCK_ASSERT(_sc) mtx_assert(&(_sc)->sc_mtx, MA_OWNED)
138
#define BCM_GPIO_WRITE(_sc, _off, _val) \
139
bus_space_write_4((_sc)->sc_bst, (_sc)->sc_bsh, _off, _val)
140
#define BCM_GPIO_READ(_sc, _off) \
141
bus_space_read_4((_sc)->sc_bst, (_sc)->sc_bsh, _off)
142
#define BCM_GPIO_CLEAR_BITS(_sc, _off, _bits) \
143
BCM_GPIO_WRITE(_sc, _off, BCM_GPIO_READ(_sc, _off) & ~(_bits))
144
#define BCM_GPIO_SET_BITS(_sc, _off, _bits) \
145
BCM_GPIO_WRITE(_sc, _off, BCM_GPIO_READ(_sc, _off) | _bits)
146
#define BCM_GPIO_BANK(a) (a / BCM_GPIO_PINS_PER_BANK)
147
#define BCM_GPIO_MASK(a) (1U << (a % BCM_GPIO_PINS_PER_BANK))
148
149
#define BCM_GPIO_GPFSEL(_bank) (0x00 + _bank * 4) /* Function Select */
150
#define BCM_GPIO_GPSET(_bank) (0x1c + _bank * 4) /* Pin Out Set */
151
#define BCM_GPIO_GPCLR(_bank) (0x28 + _bank * 4) /* Pin Out Clear */
152
#define BCM_GPIO_GPLEV(_bank) (0x34 + _bank * 4) /* Pin Level */
153
#define BCM_GPIO_GPEDS(_bank) (0x40 + _bank * 4) /* Event Status */
154
#define BCM_GPIO_GPREN(_bank) (0x4c + _bank * 4) /* Rising Edge irq */
155
#define BCM_GPIO_GPFEN(_bank) (0x58 + _bank * 4) /* Falling Edge irq */
156
#define BCM_GPIO_GPHEN(_bank) (0x64 + _bank * 4) /* High Level irq */
157
#define BCM_GPIO_GPLEN(_bank) (0x70 + _bank * 4) /* Low Level irq */
158
#define BCM_GPIO_GPAREN(_bank) (0x7c + _bank * 4) /* Async Rising Edge */
159
#define BCM_GPIO_GPAFEN(_bank) (0x88 + _bank * 4) /* Async Falling Egde */
160
#define BCM2835_GPIO_GPPUD(_bank) (0x94) /* Pin Pull up/down */
161
#define BCM2835_GPIO_GPPUDCLK(_bank) (0x98 + _bank * 4) /* Pin Pull up clock */
162
163
#define BCM2711_GPIO_GPPUD(x) (0x0e4 + (x) * sizeof(uint32_t)) /* Pin Pull up/down */
164
#define BCM2711_GPIO_MASK (0x3)
165
#define BCM2711_GPIO_SHIFT(n) (((n) % 16) * 2)
166
#define BCM2711_GPIO_REGID(n) ((n) / 16)
167
168
static struct ofw_compat_data compat_data[] = {
169
{"broadcom,bcm2835-gpio", 1},
170
{"brcm,bcm2835-gpio", 1},
171
{"brcm,bcm2711-gpio", 1},
172
{NULL, 0}
173
};
174
175
static struct bcm_gpio_softc *bcm_gpio_sc = NULL;
176
177
static int bcm_gpio_intr_bank0(void *arg);
178
static int bcm_gpio_intr_bank1(void *arg);
179
static int bcm_gpio_pic_attach(struct bcm_gpio_softc *sc);
180
static int bcm_gpio_pic_detach(struct bcm_gpio_softc *sc);
181
182
static int
183
bcm_gpio_pin_is_ro(struct bcm_gpio_softc *sc, int pin)
184
{
185
int i;
186
187
for (i = 0; i < sc->sc_ro_npins; i++)
188
if (pin == sc->sc_ro_pins[i])
189
return (1);
190
return (0);
191
}
192
193
static uint32_t
194
bcm_gpio_get_function(struct bcm_gpio_softc *sc, uint32_t pin)
195
{
196
uint32_t bank, func, offset;
197
198
/* Five banks, 10 pins per bank, 3 bits per pin. */
199
bank = pin / 10;
200
offset = (pin - bank * 10) * 3;
201
202
BCM_GPIO_LOCK(sc);
203
func = (BCM_GPIO_READ(sc, BCM_GPIO_GPFSEL(bank)) >> offset) & 7;
204
BCM_GPIO_UNLOCK(sc);
205
206
return (func);
207
}
208
209
static void
210
bcm_gpio_func_str(uint32_t nfunc, char *buf, int bufsize)
211
{
212
213
switch (nfunc) {
214
case BCM2835_FSEL_GPIO_IN:
215
strncpy(buf, "input", bufsize);
216
break;
217
case BCM2835_FSEL_GPIO_OUT:
218
strncpy(buf, "output", bufsize);
219
break;
220
case BCM2835_FSEL_ALT0:
221
strncpy(buf, "alt0", bufsize);
222
break;
223
case BCM2835_FSEL_ALT1:
224
strncpy(buf, "alt1", bufsize);
225
break;
226
case BCM2835_FSEL_ALT2:
227
strncpy(buf, "alt2", bufsize);
228
break;
229
case BCM2835_FSEL_ALT3:
230
strncpy(buf, "alt3", bufsize);
231
break;
232
case BCM2835_FSEL_ALT4:
233
strncpy(buf, "alt4", bufsize);
234
break;
235
case BCM2835_FSEL_ALT5:
236
strncpy(buf, "alt5", bufsize);
237
break;
238
default:
239
strncpy(buf, "invalid", bufsize);
240
}
241
}
242
243
static int
244
bcm_gpio_str_func(char *func, uint32_t *nfunc)
245
{
246
247
if (strcasecmp(func, "input") == 0)
248
*nfunc = BCM2835_FSEL_GPIO_IN;
249
else if (strcasecmp(func, "output") == 0)
250
*nfunc = BCM2835_FSEL_GPIO_OUT;
251
else if (strcasecmp(func, "alt0") == 0)
252
*nfunc = BCM2835_FSEL_ALT0;
253
else if (strcasecmp(func, "alt1") == 0)
254
*nfunc = BCM2835_FSEL_ALT1;
255
else if (strcasecmp(func, "alt2") == 0)
256
*nfunc = BCM2835_FSEL_ALT2;
257
else if (strcasecmp(func, "alt3") == 0)
258
*nfunc = BCM2835_FSEL_ALT3;
259
else if (strcasecmp(func, "alt4") == 0)
260
*nfunc = BCM2835_FSEL_ALT4;
261
else if (strcasecmp(func, "alt5") == 0)
262
*nfunc = BCM2835_FSEL_ALT5;
263
else
264
return (-1);
265
266
return (0);
267
}
268
269
static uint32_t
270
bcm_gpio_func_flag(uint32_t nfunc)
271
{
272
273
switch (nfunc) {
274
case BCM2835_FSEL_GPIO_IN:
275
return (GPIO_PIN_INPUT);
276
case BCM2835_FSEL_GPIO_OUT:
277
return (GPIO_PIN_OUTPUT);
278
}
279
return (0);
280
}
281
282
static void
283
bcm_gpio_set_function(struct bcm_gpio_softc *sc, uint32_t pin, uint32_t f)
284
{
285
uint32_t bank, data, offset;
286
287
/* Must be called with lock held. */
288
BCM_GPIO_LOCK_ASSERT(sc);
289
290
/* Five banks, 10 pins per bank, 3 bits per pin. */
291
bank = pin / 10;
292
offset = (pin - bank * 10) * 3;
293
294
data = BCM_GPIO_READ(sc, BCM_GPIO_GPFSEL(bank));
295
data &= ~(7 << offset);
296
data |= (f << offset);
297
BCM_GPIO_WRITE(sc, BCM_GPIO_GPFSEL(bank), data);
298
}
299
300
static void
301
bcm_gpio_set_pud(struct bcm_gpio_softc *sc, uint32_t pin, uint32_t state)
302
{
303
/* Must be called with lock held. */
304
BCM_GPIO_LOCK_ASSERT(sc);
305
306
if (sc->sc_is2711) { /* BCM2711 */
307
u_int regid = BCM2711_GPIO_REGID(pin);
308
u_int shift = BCM2711_GPIO_SHIFT(pin);
309
uint32_t reg;
310
311
switch (state) {
312
case BCM2835_PUD_OFF:
313
state = BCM2711_PUD_OFF;
314
break;
315
case BCM2835_PUD_DOWN:
316
state = BCM2711_PUD_DOWN;
317
break;
318
case BCM2835_PUD_UP:
319
state = BCM2711_PUD_UP;
320
break;
321
}
322
323
reg = BCM_GPIO_READ(sc, BCM2711_GPIO_GPPUD(regid));
324
reg &= ~(BCM2711_GPIO_MASK << shift);
325
reg |= (state << shift);
326
BCM_GPIO_WRITE(sc, BCM2711_GPIO_GPPUD(regid), reg);
327
} else { /* BCM2835 */
328
uint32_t bank;
329
330
bank = BCM_GPIO_BANK(pin);
331
BCM_GPIO_WRITE(sc, BCM2835_GPIO_GPPUD(0), state);
332
BCM_GPIO_WRITE(sc, BCM2835_GPIO_GPPUDCLK(bank), BCM_GPIO_MASK(pin));
333
BCM_GPIO_WRITE(sc, BCM2835_GPIO_GPPUD(0), 0);
334
BCM_GPIO_WRITE(sc, BCM2835_GPIO_GPPUDCLK(bank), 0);
335
}
336
}
337
338
static void
339
bcm_gpio_set_alternate(device_t dev, uint32_t pin, uint32_t nfunc)
340
{
341
struct bcm_gpio_softc *sc;
342
int i;
343
344
sc = device_get_softc(dev);
345
BCM_GPIO_LOCK(sc);
346
347
/* Set the pin function. */
348
bcm_gpio_set_function(sc, pin, nfunc);
349
350
/* Update the pin flags. */
351
for (i = 0; i < sc->sc_gpio_npins; i++) {
352
if (sc->sc_gpio_pins[i].gp_pin == pin)
353
break;
354
}
355
if (i < sc->sc_gpio_npins)
356
sc->sc_gpio_pins[i].gp_flags = bcm_gpio_func_flag(nfunc);
357
358
BCM_GPIO_UNLOCK(sc);
359
}
360
361
static void
362
bcm_gpio_pin_configure(struct bcm_gpio_softc *sc, struct gpio_pin *pin,
363
unsigned int flags)
364
{
365
366
BCM_GPIO_LOCK(sc);
367
368
/*
369
* Manage input/output.
370
*/
371
if (flags & (GPIO_PIN_INPUT|GPIO_PIN_OUTPUT)) {
372
pin->gp_flags &= ~(GPIO_PIN_INPUT|GPIO_PIN_OUTPUT);
373
if (flags & GPIO_PIN_OUTPUT) {
374
pin->gp_flags |= GPIO_PIN_OUTPUT;
375
bcm_gpio_set_function(sc, pin->gp_pin,
376
BCM2835_FSEL_GPIO_OUT);
377
} else {
378
pin->gp_flags |= GPIO_PIN_INPUT;
379
bcm_gpio_set_function(sc, pin->gp_pin,
380
BCM2835_FSEL_GPIO_IN);
381
}
382
}
383
384
/* Manage Pull-up/pull-down. */
385
pin->gp_flags &= ~(GPIO_PIN_PULLUP|GPIO_PIN_PULLDOWN);
386
if (flags & (GPIO_PIN_PULLUP|GPIO_PIN_PULLDOWN)) {
387
if (flags & GPIO_PIN_PULLUP) {
388
pin->gp_flags |= GPIO_PIN_PULLUP;
389
bcm_gpio_set_pud(sc, pin->gp_pin, BCM_GPIO_PULLUP);
390
} else {
391
pin->gp_flags |= GPIO_PIN_PULLDOWN;
392
bcm_gpio_set_pud(sc, pin->gp_pin, BCM_GPIO_PULLDOWN);
393
}
394
} else
395
bcm_gpio_set_pud(sc, pin->gp_pin, BCM_GPIO_NONE);
396
397
BCM_GPIO_UNLOCK(sc);
398
}
399
400
static device_t
401
bcm_gpio_get_bus(device_t dev)
402
{
403
struct bcm_gpio_softc *sc;
404
405
sc = device_get_softc(dev);
406
407
return (sc->sc_busdev);
408
}
409
410
static int
411
bcm_gpio_pin_max(device_t dev, int *maxpin)
412
{
413
struct bcm_gpio_softc *sc;
414
415
sc = device_get_softc(dev);
416
*maxpin = sc->sc_maxpins - 1;
417
return (0);
418
}
419
420
static int
421
bcm_gpio_pin_getcaps(device_t dev, uint32_t pin, uint32_t *caps)
422
{
423
struct bcm_gpio_softc *sc = device_get_softc(dev);
424
int i;
425
426
for (i = 0; i < sc->sc_gpio_npins; i++) {
427
if (sc->sc_gpio_pins[i].gp_pin == pin)
428
break;
429
}
430
431
if (i >= sc->sc_gpio_npins)
432
return (EINVAL);
433
434
BCM_GPIO_LOCK(sc);
435
*caps = sc->sc_gpio_pins[i].gp_caps;
436
BCM_GPIO_UNLOCK(sc);
437
438
return (0);
439
}
440
441
static int
442
bcm_gpio_pin_getflags(device_t dev, uint32_t pin, uint32_t *flags)
443
{
444
struct bcm_gpio_softc *sc = device_get_softc(dev);
445
int i;
446
447
for (i = 0; i < sc->sc_gpio_npins; i++) {
448
if (sc->sc_gpio_pins[i].gp_pin == pin)
449
break;
450
}
451
452
if (i >= sc->sc_gpio_npins)
453
return (EINVAL);
454
455
BCM_GPIO_LOCK(sc);
456
*flags = sc->sc_gpio_pins[i].gp_flags;
457
BCM_GPIO_UNLOCK(sc);
458
459
return (0);
460
}
461
462
static int
463
bcm_gpio_pin_getname(device_t dev, uint32_t pin, char *name)
464
{
465
struct bcm_gpio_softc *sc = device_get_softc(dev);
466
int i;
467
468
for (i = 0; i < sc->sc_gpio_npins; i++) {
469
if (sc->sc_gpio_pins[i].gp_pin == pin)
470
break;
471
}
472
473
if (i >= sc->sc_gpio_npins)
474
return (EINVAL);
475
476
BCM_GPIO_LOCK(sc);
477
memcpy(name, sc->sc_gpio_pins[i].gp_name, GPIOMAXNAME);
478
BCM_GPIO_UNLOCK(sc);
479
480
return (0);
481
}
482
483
static int
484
bcm_gpio_pin_setflags(device_t dev, uint32_t pin, uint32_t flags)
485
{
486
struct bcm_gpio_softc *sc = device_get_softc(dev);
487
int i;
488
489
for (i = 0; i < sc->sc_gpio_npins; i++) {
490
if (sc->sc_gpio_pins[i].gp_pin == pin)
491
break;
492
}
493
494
if (i >= sc->sc_gpio_npins)
495
return (EINVAL);
496
497
/* We never touch on read-only/reserved pins. */
498
if (bcm_gpio_pin_is_ro(sc, pin))
499
return (EINVAL);
500
501
bcm_gpio_pin_configure(sc, &sc->sc_gpio_pins[i], flags);
502
503
return (0);
504
}
505
506
static int
507
bcm_gpio_pin_set(device_t dev, uint32_t pin, unsigned int value)
508
{
509
struct bcm_gpio_softc *sc = device_get_softc(dev);
510
uint32_t bank, reg;
511
int i;
512
513
for (i = 0; i < sc->sc_gpio_npins; i++) {
514
if (sc->sc_gpio_pins[i].gp_pin == pin)
515
break;
516
}
517
if (i >= sc->sc_gpio_npins)
518
return (EINVAL);
519
/* We never write to read-only/reserved pins. */
520
if (bcm_gpio_pin_is_ro(sc, pin))
521
return (EINVAL);
522
BCM_GPIO_LOCK(sc);
523
bank = BCM_GPIO_BANK(pin);
524
if (value)
525
reg = BCM_GPIO_GPSET(bank);
526
else
527
reg = BCM_GPIO_GPCLR(bank);
528
BCM_GPIO_WRITE(sc, reg, BCM_GPIO_MASK(pin));
529
BCM_GPIO_UNLOCK(sc);
530
531
return (0);
532
}
533
534
static int
535
bcm_gpio_pin_get(device_t dev, uint32_t pin, unsigned int *val)
536
{
537
struct bcm_gpio_softc *sc = device_get_softc(dev);
538
uint32_t bank, reg_data;
539
int i;
540
541
for (i = 0; i < sc->sc_gpio_npins; i++) {
542
if (sc->sc_gpio_pins[i].gp_pin == pin)
543
break;
544
}
545
if (i >= sc->sc_gpio_npins)
546
return (EINVAL);
547
bank = BCM_GPIO_BANK(pin);
548
BCM_GPIO_LOCK(sc);
549
reg_data = BCM_GPIO_READ(sc, BCM_GPIO_GPLEV(bank));
550
BCM_GPIO_UNLOCK(sc);
551
*val = (reg_data & BCM_GPIO_MASK(pin)) ? 1 : 0;
552
553
return (0);
554
}
555
556
static int
557
bcm_gpio_pin_toggle(device_t dev, uint32_t pin)
558
{
559
struct bcm_gpio_softc *sc = device_get_softc(dev);
560
uint32_t bank, data, reg;
561
int i;
562
563
for (i = 0; i < sc->sc_gpio_npins; i++) {
564
if (sc->sc_gpio_pins[i].gp_pin == pin)
565
break;
566
}
567
if (i >= sc->sc_gpio_npins)
568
return (EINVAL);
569
/* We never write to read-only/reserved pins. */
570
if (bcm_gpio_pin_is_ro(sc, pin))
571
return (EINVAL);
572
BCM_GPIO_LOCK(sc);
573
bank = BCM_GPIO_BANK(pin);
574
data = BCM_GPIO_READ(sc, BCM_GPIO_GPLEV(bank));
575
if (data & BCM_GPIO_MASK(pin))
576
reg = BCM_GPIO_GPCLR(bank);
577
else
578
reg = BCM_GPIO_GPSET(bank);
579
BCM_GPIO_WRITE(sc, reg, BCM_GPIO_MASK(pin));
580
BCM_GPIO_UNLOCK(sc);
581
582
return (0);
583
}
584
585
static int
586
bcm_gpio_func_proc(SYSCTL_HANDLER_ARGS)
587
{
588
char buf[16];
589
struct bcm_gpio_softc *sc;
590
struct bcm_gpio_sysctl *sc_sysctl;
591
uint32_t nfunc;
592
int error;
593
594
sc_sysctl = arg1;
595
sc = sc_sysctl->sc;
596
597
/* Get the current pin function. */
598
nfunc = bcm_gpio_get_function(sc, sc_sysctl->pin);
599
bcm_gpio_func_str(nfunc, buf, sizeof(buf));
600
601
error = sysctl_handle_string(oidp, buf, sizeof(buf), req);
602
if (error != 0 || req->newptr == NULL)
603
return (error);
604
/* Ignore changes on read-only pins. */
605
if (bcm_gpio_pin_is_ro(sc, sc_sysctl->pin))
606
return (0);
607
/* Parse the user supplied string and check for a valid pin function. */
608
if (bcm_gpio_str_func(buf, &nfunc) != 0)
609
return (EINVAL);
610
611
/* Update the pin alternate function. */
612
bcm_gpio_set_alternate(sc->sc_dev, sc_sysctl->pin, nfunc);
613
614
return (0);
615
}
616
617
static void
618
bcm_gpio_sysctl_init(struct bcm_gpio_softc *sc)
619
{
620
char pinbuf[3];
621
struct bcm_gpio_sysctl *sc_sysctl;
622
struct sysctl_ctx_list *ctx;
623
struct sysctl_oid *tree_node, *pin_node, *pinN_node;
624
struct sysctl_oid_list *tree, *pin_tree, *pinN_tree;
625
int i;
626
627
/*
628
* Add per-pin sysctl tree/handlers.
629
*/
630
ctx = device_get_sysctl_ctx(sc->sc_dev);
631
tree_node = device_get_sysctl_tree(sc->sc_dev);
632
tree = SYSCTL_CHILDREN(tree_node);
633
pin_node = SYSCTL_ADD_NODE(ctx, tree, OID_AUTO, "pin",
634
CTLFLAG_RD | CTLFLAG_MPSAFE, NULL, "GPIO Pins");
635
pin_tree = SYSCTL_CHILDREN(pin_node);
636
637
for (i = 0; i < sc->sc_gpio_npins; i++) {
638
snprintf(pinbuf, sizeof(pinbuf), "%d", i);
639
pinN_node = SYSCTL_ADD_NODE(ctx, pin_tree, OID_AUTO, pinbuf,
640
CTLFLAG_RD | CTLFLAG_MPSAFE, NULL, "GPIO Pin");
641
pinN_tree = SYSCTL_CHILDREN(pinN_node);
642
643
sc->sc_sysctl[i].sc = sc;
644
sc_sysctl = &sc->sc_sysctl[i];
645
sc_sysctl->sc = sc;
646
sc_sysctl->pin = sc->sc_gpio_pins[i].gp_pin;
647
SYSCTL_ADD_PROC(ctx, pinN_tree, OID_AUTO, "function",
648
CTLFLAG_RW | CTLTYPE_STRING | CTLFLAG_NEEDGIANT, sc_sysctl,
649
sizeof(struct bcm_gpio_sysctl), bcm_gpio_func_proc,
650
"A", "Pin Function");
651
}
652
}
653
654
static int
655
bcm_gpio_get_ro_pins(struct bcm_gpio_softc *sc, phandle_t node,
656
const char *propname, const char *label)
657
{
658
int i, need_comma, npins, range_start, range_stop;
659
pcell_t *pins;
660
661
/* Get the property data. */
662
npins = OF_getencprop_alloc_multi(node, propname, sizeof(*pins),
663
(void **)&pins);
664
if (npins < 0)
665
return (-1);
666
if (npins == 0) {
667
OF_prop_free(pins);
668
return (0);
669
}
670
for (i = 0; i < npins; i++)
671
sc->sc_ro_pins[i + sc->sc_ro_npins] = pins[i];
672
sc->sc_ro_npins += npins;
673
need_comma = 0;
674
device_printf(sc->sc_dev, "%s pins: ", label);
675
range_start = range_stop = pins[0];
676
for (i = 1; i < npins; i++) {
677
if (pins[i] != range_stop + 1) {
678
if (need_comma)
679
printf(",");
680
if (range_start != range_stop)
681
printf("%d-%d", range_start, range_stop);
682
else
683
printf("%d", range_start);
684
range_start = range_stop = pins[i];
685
need_comma = 1;
686
} else
687
range_stop++;
688
}
689
if (need_comma)
690
printf(",");
691
if (range_start != range_stop)
692
printf("%d-%d.\n", range_start, range_stop);
693
else
694
printf("%d.\n", range_start);
695
OF_prop_free(pins);
696
697
return (0);
698
}
699
700
static int
701
bcm_gpio_get_reserved_pins(struct bcm_gpio_softc *sc)
702
{
703
char *name;
704
phandle_t gpio, node, reserved;
705
ssize_t len;
706
707
/* Get read-only pins if they're provided */
708
gpio = ofw_bus_get_node(sc->sc_dev);
709
if (bcm_gpio_get_ro_pins(sc, gpio, "broadcom,read-only",
710
"read-only") != 0)
711
return (0);
712
/* Traverse the GPIO subnodes to find the reserved pins node. */
713
reserved = 0;
714
node = OF_child(gpio);
715
while ((node != 0) && (reserved == 0)) {
716
len = OF_getprop_alloc(node, "name", (void **)&name);
717
if (len == -1)
718
return (-1);
719
if (strcmp(name, "reserved") == 0)
720
reserved = node;
721
OF_prop_free(name);
722
node = OF_peer(node);
723
}
724
if (reserved == 0)
725
return (-1);
726
/* Get the reserved pins. */
727
if (bcm_gpio_get_ro_pins(sc, reserved, "broadcom,pins",
728
"reserved") != 0)
729
return (-1);
730
731
return (0);
732
}
733
734
static int
735
bcm_gpio_probe(device_t dev)
736
{
737
738
if (!ofw_bus_status_okay(dev))
739
return (ENXIO);
740
741
if (ofw_bus_search_compatible(dev, compat_data)->ocd_data == 0)
742
return (ENXIO);
743
744
device_set_desc(dev, "BCM2708/2835 GPIO controller");
745
return (BUS_PROBE_DEFAULT);
746
}
747
748
static int
749
bcm_gpio_intr_attach(device_t dev)
750
{
751
struct bcm_gpio_softc *sc;
752
753
/*
754
* Only first two interrupt lines are used. Third line is
755
* mirrored second line and forth line is common for all banks.
756
*/
757
sc = device_get_softc(dev);
758
if (sc->sc_res[1] == NULL || sc->sc_res[2] == NULL)
759
return (-1);
760
761
if (bcm_gpio_pic_attach(sc) != 0) {
762
device_printf(dev, "unable to attach PIC\n");
763
return (-1);
764
}
765
if (bus_setup_intr(dev, sc->sc_res[1], INTR_TYPE_MISC | INTR_MPSAFE,
766
bcm_gpio_intr_bank0, NULL, sc, &sc->sc_intrhand[0]) != 0)
767
return (-1);
768
if (bus_setup_intr(dev, sc->sc_res[2], INTR_TYPE_MISC | INTR_MPSAFE,
769
bcm_gpio_intr_bank1, NULL, sc, &sc->sc_intrhand[1]) != 0)
770
return (-1);
771
772
return (0);
773
}
774
775
static void
776
bcm_gpio_intr_detach(device_t dev)
777
{
778
struct bcm_gpio_softc *sc;
779
780
sc = device_get_softc(dev);
781
if (sc->sc_intrhand[0] != NULL)
782
bus_teardown_intr(dev, sc->sc_res[1], sc->sc_intrhand[0]);
783
if (sc->sc_intrhand[1] != NULL)
784
bus_teardown_intr(dev, sc->sc_res[2], sc->sc_intrhand[1]);
785
786
bcm_gpio_pic_detach(sc);
787
}
788
789
static int
790
bcm_gpio_attach(device_t dev)
791
{
792
int i, j;
793
phandle_t gpio;
794
struct bcm_gpio_softc *sc;
795
uint32_t func;
796
797
if (bcm_gpio_sc != NULL)
798
return (ENXIO);
799
800
bcm_gpio_sc = sc = device_get_softc(dev);
801
sc->sc_dev = dev;
802
mtx_init(&sc->sc_mtx, "bcm gpio", "gpio", MTX_SPIN);
803
if (bus_alloc_resources(dev, bcm_gpio_res_spec, sc->sc_res) != 0) {
804
device_printf(dev, "cannot allocate resources\n");
805
goto fail;
806
}
807
sc->sc_bst = rman_get_bustag(sc->sc_res[0]);
808
sc->sc_bsh = rman_get_bushandle(sc->sc_res[0]);
809
/* Find our node. */
810
gpio = ofw_bus_get_node(sc->sc_dev);
811
if (!OF_hasprop(gpio, "gpio-controller"))
812
/* Node is not a GPIO controller. */
813
goto fail;
814
/* Guess I'm BCM2711 or not. */
815
sc->sc_is2711 = ofw_bus_node_is_compatible(gpio, "brcm,bcm2711-gpio");
816
sc->sc_maxpins = sc->sc_is2711 ? BCM2711_GPIO_PINS : BCM2835_GPIO_PINS;
817
/* Setup the GPIO interrupt handler. */
818
if (bcm_gpio_intr_attach(dev)) {
819
device_printf(dev, "unable to setup the gpio irq handler\n");
820
goto fail;
821
}
822
/*
823
* Find the read-only pins. These are pins we never touch or bad
824
* things could happen.
825
*/
826
if (bcm_gpio_get_reserved_pins(sc) == -1)
827
goto fail;
828
/* Initialize the software controlled pins. */
829
for (i = 0, j = 0; j < sc->sc_maxpins; j++) {
830
snprintf(sc->sc_gpio_pins[i].gp_name, GPIOMAXNAME,
831
"pin %d", j);
832
func = bcm_gpio_get_function(sc, j);
833
sc->sc_gpio_pins[i].gp_pin = j;
834
sc->sc_gpio_pins[i].gp_caps = BCM_GPIO_DEFAULT_CAPS;
835
sc->sc_gpio_pins[i].gp_flags = bcm_gpio_func_flag(func);
836
i++;
837
}
838
sc->sc_gpio_npins = i;
839
bcm_gpio_sysctl_init(sc);
840
841
fdt_pinctrl_register(dev, "brcm,pins");
842
fdt_pinctrl_configure_tree(dev);
843
sc->sc_busdev = gpiobus_add_bus(dev);
844
if (sc->sc_busdev == NULL)
845
goto fail;
846
847
bus_attach_children(dev);
848
return (0);
849
850
fail:
851
bcm_gpio_intr_detach(dev);
852
bus_release_resources(dev, bcm_gpio_res_spec, sc->sc_res);
853
mtx_destroy(&sc->sc_mtx);
854
855
return (ENXIO);
856
}
857
858
static int
859
bcm_gpio_detach(device_t dev)
860
{
861
862
return (EBUSY);
863
}
864
865
static inline void
866
bcm_gpio_modify(struct bcm_gpio_softc *sc, uint32_t reg, uint32_t mask,
867
bool set_bits)
868
{
869
870
if (set_bits)
871
BCM_GPIO_SET_BITS(sc, reg, mask);
872
else
873
BCM_GPIO_CLEAR_BITS(sc, reg, mask);
874
}
875
876
static inline void
877
bcm_gpio_isrc_eoi(struct bcm_gpio_softc *sc, struct bcm_gpio_irqsrc *bgi)
878
{
879
uint32_t bank;
880
881
/* Write 1 to clear. */
882
bank = BCM_GPIO_BANK(bgi->bgi_irq);
883
BCM_GPIO_WRITE(sc, BCM_GPIO_GPEDS(bank), bgi->bgi_mask);
884
}
885
886
static inline bool
887
bcm_gpio_isrc_is_level(struct bcm_gpio_irqsrc *bgi)
888
{
889
890
return (bgi->bgi_mode == GPIO_INTR_LEVEL_LOW ||
891
bgi->bgi_mode == GPIO_INTR_LEVEL_HIGH);
892
}
893
894
static inline void
895
bcm_gpio_isrc_mask(struct bcm_gpio_softc *sc, struct bcm_gpio_irqsrc *bgi)
896
{
897
uint32_t bank;
898
899
bank = BCM_GPIO_BANK(bgi->bgi_irq);
900
BCM_GPIO_LOCK(sc);
901
switch (bgi->bgi_mode) {
902
case GPIO_INTR_LEVEL_LOW:
903
BCM_GPIO_CLEAR_BITS(sc, BCM_GPIO_GPLEN(bank), bgi->bgi_mask);
904
break;
905
case GPIO_INTR_LEVEL_HIGH:
906
BCM_GPIO_CLEAR_BITS(sc, BCM_GPIO_GPHEN(bank), bgi->bgi_mask);
907
break;
908
case GPIO_INTR_EDGE_RISING:
909
BCM_GPIO_CLEAR_BITS(sc, BCM_GPIO_GPREN(bank), bgi->bgi_mask);
910
break;
911
case GPIO_INTR_EDGE_FALLING:
912
BCM_GPIO_CLEAR_BITS(sc, BCM_GPIO_GPFEN(bank), bgi->bgi_mask);
913
break;
914
case GPIO_INTR_EDGE_BOTH:
915
BCM_GPIO_CLEAR_BITS(sc, BCM_GPIO_GPREN(bank), bgi->bgi_mask);
916
BCM_GPIO_CLEAR_BITS(sc, BCM_GPIO_GPFEN(bank), bgi->bgi_mask);
917
break;
918
}
919
BCM_GPIO_UNLOCK(sc);
920
}
921
922
static inline void
923
bcm_gpio_isrc_unmask(struct bcm_gpio_softc *sc, struct bcm_gpio_irqsrc *bgi)
924
{
925
uint32_t bank;
926
927
bank = BCM_GPIO_BANK(bgi->bgi_irq);
928
BCM_GPIO_LOCK(sc);
929
switch (bgi->bgi_mode) {
930
case GPIO_INTR_LEVEL_LOW:
931
BCM_GPIO_SET_BITS(sc, BCM_GPIO_GPLEN(bank), bgi->bgi_mask);
932
break;
933
case GPIO_INTR_LEVEL_HIGH:
934
BCM_GPIO_SET_BITS(sc, BCM_GPIO_GPHEN(bank), bgi->bgi_mask);
935
break;
936
case GPIO_INTR_EDGE_RISING:
937
BCM_GPIO_SET_BITS(sc, BCM_GPIO_GPREN(bank), bgi->bgi_mask);
938
break;
939
case GPIO_INTR_EDGE_FALLING:
940
BCM_GPIO_SET_BITS(sc, BCM_GPIO_GPFEN(bank), bgi->bgi_mask);
941
break;
942
case GPIO_INTR_EDGE_BOTH:
943
BCM_GPIO_SET_BITS(sc, BCM_GPIO_GPREN(bank), bgi->bgi_mask);
944
BCM_GPIO_SET_BITS(sc, BCM_GPIO_GPFEN(bank), bgi->bgi_mask);
945
break;
946
}
947
BCM_GPIO_UNLOCK(sc);
948
}
949
950
static int
951
bcm_gpio_intr_internal(struct bcm_gpio_softc *sc, uint32_t bank)
952
{
953
u_int irq;
954
struct bcm_gpio_irqsrc *bgi;
955
uint32_t reg;
956
957
/* Do not care of spurious interrupt on GPIO. */
958
reg = BCM_GPIO_READ(sc, BCM_GPIO_GPEDS(bank));
959
while (reg != 0) {
960
irq = BCM_GPIO_PINS_PER_BANK * bank + ffs(reg) - 1;
961
bgi = sc->sc_isrcs + irq;
962
if (!bcm_gpio_isrc_is_level(bgi))
963
bcm_gpio_isrc_eoi(sc, bgi);
964
if (intr_isrc_dispatch(&bgi->bgi_isrc,
965
curthread->td_intr_frame) != 0) {
966
bcm_gpio_isrc_mask(sc, bgi);
967
if (bcm_gpio_isrc_is_level(bgi))
968
bcm_gpio_isrc_eoi(sc, bgi);
969
device_printf(sc->sc_dev, "Stray irq %u disabled\n",
970
irq);
971
}
972
reg &= ~bgi->bgi_mask;
973
}
974
return (FILTER_HANDLED);
975
}
976
977
static int
978
bcm_gpio_intr_bank0(void *arg)
979
{
980
981
return (bcm_gpio_intr_internal(arg, 0));
982
}
983
984
static int
985
bcm_gpio_intr_bank1(void *arg)
986
{
987
988
return (bcm_gpio_intr_internal(arg, 1));
989
}
990
991
static int
992
bcm_gpio_pic_attach(struct bcm_gpio_softc *sc)
993
{
994
int error;
995
uint32_t irq;
996
const char *name;
997
998
name = device_get_nameunit(sc->sc_dev);
999
for (irq = 0; irq < sc->sc_maxpins; irq++) {
1000
sc->sc_isrcs[irq].bgi_irq = irq;
1001
sc->sc_isrcs[irq].bgi_mask = BCM_GPIO_MASK(irq);
1002
sc->sc_isrcs[irq].bgi_mode = GPIO_INTR_CONFORM;
1003
1004
error = intr_isrc_register(&sc->sc_isrcs[irq].bgi_isrc,
1005
sc->sc_dev, 0, "%s,%u", name, irq);
1006
if (error != 0)
1007
return (error); /* XXX deregister ISRCs */
1008
}
1009
if (intr_pic_register(sc->sc_dev,
1010
OF_xref_from_node(ofw_bus_get_node(sc->sc_dev))) == NULL)
1011
return (ENXIO);
1012
1013
return (0);
1014
}
1015
1016
static int
1017
bcm_gpio_pic_detach(struct bcm_gpio_softc *sc)
1018
{
1019
1020
/*
1021
* There has not been established any procedure yet
1022
* how to detach PIC from living system correctly.
1023
*/
1024
device_printf(sc->sc_dev, "%s: not implemented yet\n", __func__);
1025
return (EBUSY);
1026
}
1027
1028
static void
1029
bcm_gpio_pic_config_intr(struct bcm_gpio_softc *sc, struct bcm_gpio_irqsrc *bgi,
1030
uint32_t mode)
1031
{
1032
uint32_t bank;
1033
1034
bank = BCM_GPIO_BANK(bgi->bgi_irq);
1035
BCM_GPIO_LOCK(sc);
1036
bcm_gpio_modify(sc, BCM_GPIO_GPREN(bank), bgi->bgi_mask,
1037
mode == GPIO_INTR_EDGE_RISING || mode == GPIO_INTR_EDGE_BOTH);
1038
bcm_gpio_modify(sc, BCM_GPIO_GPFEN(bank), bgi->bgi_mask,
1039
mode == GPIO_INTR_EDGE_FALLING || mode == GPIO_INTR_EDGE_BOTH);
1040
bcm_gpio_modify(sc, BCM_GPIO_GPHEN(bank), bgi->bgi_mask,
1041
mode == GPIO_INTR_LEVEL_HIGH);
1042
bcm_gpio_modify(sc, BCM_GPIO_GPLEN(bank), bgi->bgi_mask,
1043
mode == GPIO_INTR_LEVEL_LOW);
1044
bgi->bgi_mode = mode;
1045
BCM_GPIO_UNLOCK(sc);
1046
}
1047
1048
static void
1049
bcm_gpio_pic_disable_intr(device_t dev, struct intr_irqsrc *isrc)
1050
{
1051
struct bcm_gpio_softc *sc = device_get_softc(dev);
1052
struct bcm_gpio_irqsrc *bgi = (struct bcm_gpio_irqsrc *)isrc;
1053
1054
bcm_gpio_isrc_mask(sc, bgi);
1055
}
1056
1057
static void
1058
bcm_gpio_pic_enable_intr(device_t dev, struct intr_irqsrc *isrc)
1059
{
1060
struct bcm_gpio_softc *sc = device_get_softc(dev);
1061
struct bcm_gpio_irqsrc *bgi = (struct bcm_gpio_irqsrc *)isrc;
1062
1063
arm_irq_memory_barrier(bgi->bgi_irq);
1064
bcm_gpio_isrc_unmask(sc, bgi);
1065
}
1066
1067
static int
1068
bcm_gpio_pic_map_fdt(struct bcm_gpio_softc *sc, struct intr_map_data_fdt *daf,
1069
u_int *irqp, uint32_t *modep)
1070
{
1071
u_int irq;
1072
uint32_t mode;
1073
1074
/*
1075
* The first cell is the interrupt number.
1076
* The second cell is used to specify flags:
1077
* bits[3:0] trigger type and level flags:
1078
* 1 = low-to-high edge triggered.
1079
* 2 = high-to-low edge triggered.
1080
* 4 = active high level-sensitive.
1081
* 8 = active low level-sensitive.
1082
*/
1083
if (daf->ncells != 2)
1084
return (EINVAL);
1085
1086
irq = daf->cells[0];
1087
if (irq >= sc->sc_maxpins || bcm_gpio_pin_is_ro(sc, irq))
1088
return (EINVAL);
1089
1090
/* Only reasonable modes are supported. */
1091
if (daf->cells[1] == 1)
1092
mode = GPIO_INTR_EDGE_RISING;
1093
else if (daf->cells[1] == 2)
1094
mode = GPIO_INTR_EDGE_FALLING;
1095
else if (daf->cells[1] == 3)
1096
mode = GPIO_INTR_EDGE_BOTH;
1097
else if (daf->cells[1] == 4)
1098
mode = GPIO_INTR_LEVEL_HIGH;
1099
else if (daf->cells[1] == 8)
1100
mode = GPIO_INTR_LEVEL_LOW;
1101
else
1102
return (EINVAL);
1103
1104
*irqp = irq;
1105
if (modep != NULL)
1106
*modep = mode;
1107
return (0);
1108
}
1109
1110
static int
1111
bcm_gpio_pic_map_gpio(struct bcm_gpio_softc *sc, struct intr_map_data_gpio *dag,
1112
u_int *irqp, uint32_t *modep)
1113
{
1114
u_int irq;
1115
uint32_t mode;
1116
1117
irq = dag->gpio_pin_num;
1118
if (irq >= sc->sc_maxpins || bcm_gpio_pin_is_ro(sc, irq))
1119
return (EINVAL);
1120
1121
mode = dag->gpio_intr_mode;
1122
if (mode != GPIO_INTR_LEVEL_LOW && mode != GPIO_INTR_LEVEL_HIGH &&
1123
mode != GPIO_INTR_EDGE_RISING && mode != GPIO_INTR_EDGE_FALLING &&
1124
mode != GPIO_INTR_EDGE_BOTH)
1125
return (EINVAL);
1126
1127
*irqp = irq;
1128
if (modep != NULL)
1129
*modep = mode;
1130
return (0);
1131
}
1132
1133
static int
1134
bcm_gpio_pic_map(struct bcm_gpio_softc *sc, struct intr_map_data *data,
1135
u_int *irqp, uint32_t *modep)
1136
{
1137
1138
switch (data->type) {
1139
case INTR_MAP_DATA_FDT:
1140
return (bcm_gpio_pic_map_fdt(sc,
1141
(struct intr_map_data_fdt *)data, irqp, modep));
1142
case INTR_MAP_DATA_GPIO:
1143
return (bcm_gpio_pic_map_gpio(sc,
1144
(struct intr_map_data_gpio *)data, irqp, modep));
1145
default:
1146
return (ENOTSUP);
1147
}
1148
}
1149
1150
static int
1151
bcm_gpio_pic_map_intr(device_t dev, struct intr_map_data *data,
1152
struct intr_irqsrc **isrcp)
1153
{
1154
int error;
1155
u_int irq;
1156
struct bcm_gpio_softc *sc = device_get_softc(dev);
1157
1158
error = bcm_gpio_pic_map(sc, data, &irq, NULL);
1159
if (error == 0)
1160
*isrcp = &sc->sc_isrcs[irq].bgi_isrc;
1161
return (error);
1162
}
1163
1164
static void
1165
bcm_gpio_pic_post_filter(device_t dev, struct intr_irqsrc *isrc)
1166
{
1167
struct bcm_gpio_softc *sc = device_get_softc(dev);
1168
struct bcm_gpio_irqsrc *bgi = (struct bcm_gpio_irqsrc *)isrc;
1169
1170
if (bcm_gpio_isrc_is_level(bgi))
1171
bcm_gpio_isrc_eoi(sc, bgi);
1172
}
1173
1174
static void
1175
bcm_gpio_pic_post_ithread(device_t dev, struct intr_irqsrc *isrc)
1176
{
1177
1178
bcm_gpio_pic_enable_intr(dev, isrc);
1179
}
1180
1181
static void
1182
bcm_gpio_pic_pre_ithread(device_t dev, struct intr_irqsrc *isrc)
1183
{
1184
struct bcm_gpio_softc *sc = device_get_softc(dev);
1185
struct bcm_gpio_irqsrc *bgi = (struct bcm_gpio_irqsrc *)isrc;
1186
1187
bcm_gpio_isrc_mask(sc, bgi);
1188
if (bcm_gpio_isrc_is_level(bgi))
1189
bcm_gpio_isrc_eoi(sc, bgi);
1190
}
1191
1192
static int
1193
bcm_gpio_pic_setup_intr(device_t dev, struct intr_irqsrc *isrc,
1194
struct resource *res, struct intr_map_data *data)
1195
{
1196
u_int irq;
1197
uint32_t mode;
1198
struct bcm_gpio_softc *sc;
1199
struct bcm_gpio_irqsrc *bgi;
1200
1201
if (data == NULL)
1202
return (ENOTSUP);
1203
1204
sc = device_get_softc(dev);
1205
bgi = (struct bcm_gpio_irqsrc *)isrc;
1206
1207
/* Get and check config for an interrupt. */
1208
if (bcm_gpio_pic_map(sc, data, &irq, &mode) != 0 || bgi->bgi_irq != irq)
1209
return (EINVAL);
1210
1211
/*
1212
* If this is a setup for another handler,
1213
* only check that its configuration match.
1214
*/
1215
if (isrc->isrc_handlers != 0)
1216
return (bgi->bgi_mode == mode ? 0 : EINVAL);
1217
1218
bcm_gpio_pic_config_intr(sc, bgi, mode);
1219
return (0);
1220
}
1221
1222
static int
1223
bcm_gpio_pic_teardown_intr(device_t dev, struct intr_irqsrc *isrc,
1224
struct resource *res, struct intr_map_data *data)
1225
{
1226
struct bcm_gpio_softc *sc = device_get_softc(dev);
1227
struct bcm_gpio_irqsrc *bgi = (struct bcm_gpio_irqsrc *)isrc;
1228
1229
if (isrc->isrc_handlers == 0)
1230
bcm_gpio_pic_config_intr(sc, bgi, GPIO_INTR_CONFORM);
1231
return (0);
1232
}
1233
1234
static phandle_t
1235
bcm_gpio_get_node(device_t bus, device_t dev)
1236
{
1237
1238
/* We only have one child, the GPIO bus, which needs our own node. */
1239
return (ofw_bus_get_node(bus));
1240
}
1241
1242
static int
1243
bcm_gpio_configure_pins(device_t dev, phandle_t cfgxref)
1244
{
1245
phandle_t cfgnode;
1246
int i, pintuples, pulltuples;
1247
uint32_t pin;
1248
uint32_t *pins;
1249
uint32_t *pulls;
1250
uint32_t function;
1251
1252
cfgnode = OF_node_from_xref(cfgxref);
1253
1254
pins = NULL;
1255
pintuples = OF_getencprop_alloc_multi(cfgnode, "brcm,pins",
1256
sizeof(*pins), (void **)&pins);
1257
1258
char name[32];
1259
OF_getprop(cfgnode, "name", &name, sizeof(name));
1260
1261
if (pintuples < 0)
1262
return (ENOENT);
1263
1264
if (pintuples == 0)
1265
return (0); /* Empty property is not an error. */
1266
1267
if (OF_getencprop(cfgnode, "brcm,function", &function,
1268
sizeof(function)) <= 0) {
1269
OF_prop_free(pins);
1270
return (EINVAL);
1271
}
1272
1273
pulls = NULL;
1274
pulltuples = OF_getencprop_alloc_multi(cfgnode, "brcm,pull",
1275
sizeof(*pulls), (void **)&pulls);
1276
1277
if ((pulls != NULL) && (pulltuples != pintuples)) {
1278
OF_prop_free(pins);
1279
OF_prop_free(pulls);
1280
return (EINVAL);
1281
}
1282
1283
for (i = 0; i < pintuples; i++) {
1284
pin = pins[i];
1285
bcm_gpio_set_alternate(dev, pin, function);
1286
if (bootverbose)
1287
device_printf(dev, "set pin %d to func %d", pin, function);
1288
if (pulls) {
1289
if (bootverbose)
1290
printf(", pull %d", pulls[i]);
1291
switch (pulls[i]) {
1292
/* Convert to gpio(4) flags */
1293
case BCM2835_PUD_OFF:
1294
bcm_gpio_pin_setflags(dev, pin, 0);
1295
break;
1296
case BCM2835_PUD_UP:
1297
bcm_gpio_pin_setflags(dev, pin, GPIO_PIN_PULLUP);
1298
break;
1299
case BCM2835_PUD_DOWN:
1300
bcm_gpio_pin_setflags(dev, pin, GPIO_PIN_PULLDOWN);
1301
break;
1302
default:
1303
printf("%s: invalid pull value for pin %d: %d\n",
1304
name, pin, pulls[i]);
1305
}
1306
}
1307
if (bootverbose)
1308
printf("\n");
1309
}
1310
1311
OF_prop_free(pins);
1312
if (pulls)
1313
OF_prop_free(pulls);
1314
1315
return (0);
1316
}
1317
1318
static device_method_t bcm_gpio_methods[] = {
1319
/* Device interface */
1320
DEVMETHOD(device_probe, bcm_gpio_probe),
1321
DEVMETHOD(device_attach, bcm_gpio_attach),
1322
DEVMETHOD(device_detach, bcm_gpio_detach),
1323
1324
/* Bus interface */
1325
DEVMETHOD(bus_setup_intr, bus_generic_setup_intr),
1326
DEVMETHOD(bus_teardown_intr, bus_generic_teardown_intr),
1327
1328
/* GPIO protocol */
1329
DEVMETHOD(gpio_get_bus, bcm_gpio_get_bus),
1330
DEVMETHOD(gpio_pin_max, bcm_gpio_pin_max),
1331
DEVMETHOD(gpio_pin_getname, bcm_gpio_pin_getname),
1332
DEVMETHOD(gpio_pin_getflags, bcm_gpio_pin_getflags),
1333
DEVMETHOD(gpio_pin_getcaps, bcm_gpio_pin_getcaps),
1334
DEVMETHOD(gpio_pin_setflags, bcm_gpio_pin_setflags),
1335
DEVMETHOD(gpio_pin_get, bcm_gpio_pin_get),
1336
DEVMETHOD(gpio_pin_set, bcm_gpio_pin_set),
1337
DEVMETHOD(gpio_pin_toggle, bcm_gpio_pin_toggle),
1338
1339
/* Interrupt controller interface */
1340
DEVMETHOD(pic_disable_intr, bcm_gpio_pic_disable_intr),
1341
DEVMETHOD(pic_enable_intr, bcm_gpio_pic_enable_intr),
1342
DEVMETHOD(pic_map_intr, bcm_gpio_pic_map_intr),
1343
DEVMETHOD(pic_post_filter, bcm_gpio_pic_post_filter),
1344
DEVMETHOD(pic_post_ithread, bcm_gpio_pic_post_ithread),
1345
DEVMETHOD(pic_pre_ithread, bcm_gpio_pic_pre_ithread),
1346
DEVMETHOD(pic_setup_intr, bcm_gpio_pic_setup_intr),
1347
DEVMETHOD(pic_teardown_intr, bcm_gpio_pic_teardown_intr),
1348
1349
/* ofw_bus interface */
1350
DEVMETHOD(ofw_bus_get_node, bcm_gpio_get_node),
1351
1352
/* fdt_pinctrl interface */
1353
DEVMETHOD(fdt_pinctrl_configure, bcm_gpio_configure_pins),
1354
1355
DEVMETHOD_END
1356
};
1357
1358
static driver_t bcm_gpio_driver = {
1359
"gpio",
1360
bcm_gpio_methods,
1361
sizeof(struct bcm_gpio_softc),
1362
};
1363
1364
EARLY_DRIVER_MODULE(bcm_gpio, simplebus, bcm_gpio_driver, 0, 0,
1365
BUS_PASS_INTERRUPT + BUS_PASS_ORDER_LATE);
1366
1367