Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
freebsd
GitHub Repository: freebsd/freebsd-src
Path: blob/main/sys/arm/freescale/imx/imx_gpio.c
39536 views
1
/*-
2
* Copyright (c) 2012, 2013 The FreeBSD Foundation
3
*
4
* This software was developed by Oleksandr Rybalko under sponsorship
5
* from the FreeBSD Foundation.
6
*
7
* Redistribution and use in source and binary forms, with or without
8
* modification, are permitted provided that the following conditions
9
* are met:
10
* 1. Redistributions of source code must retain the above copyright
11
* notice, this list of conditions and the following disclaimer.
12
* 2. Redistributions in binary form must reproduce the above copyright
13
* notice, this list of conditions and the following disclaimer in the
14
* documentation and/or other materials provided with the distribution.
15
*
16
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
17
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
18
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
19
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
20
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
21
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
22
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
23
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
24
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
25
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
26
* SUCH DAMAGE.
27
*/
28
29
/*
30
* Freescale i.MX515 GPIO driver.
31
*/
32
33
#include <sys/cdefs.h>
34
#include "opt_platform.h"
35
36
#include <sys/param.h>
37
#include <sys/systm.h>
38
#include <sys/bus.h>
39
40
#include <sys/kernel.h>
41
#include <sys/module.h>
42
#include <sys/rman.h>
43
#include <sys/lock.h>
44
#include <sys/mutex.h>
45
#include <sys/gpio.h>
46
#include <sys/proc.h>
47
48
#include <machine/bus.h>
49
#include <machine/intr.h>
50
#include <machine/resource.h>
51
52
#include <dev/gpio/gpiobusvar.h>
53
#include <dev/ofw/openfirm.h>
54
#include <dev/ofw/ofw_bus.h>
55
#include <dev/ofw/ofw_bus_subr.h>
56
57
#if defined(__aarch64__)
58
#define IMX_ENABLE_CLOCKS
59
#endif
60
61
#ifdef IMX_ENABLE_CLOCKS
62
#include <dev/clk/clk.h>
63
#endif
64
65
#include "gpio_if.h"
66
67
#ifdef INTRNG
68
#include "pic_if.h"
69
#endif
70
71
#define WRITE4(_sc, _r, _v) \
72
bus_space_write_4((_sc)->sc_iot, (_sc)->sc_ioh, (_r), (_v))
73
#define READ4(_sc, _r) \
74
bus_space_read_4((_sc)->sc_iot, (_sc)->sc_ioh, (_r))
75
#define SET4(_sc, _r, _m) \
76
WRITE4((_sc), (_r), READ4((_sc), (_r)) | (_m))
77
#define CLEAR4(_sc, _r, _m) \
78
WRITE4((_sc), (_r), READ4((_sc), (_r)) & ~(_m))
79
80
/* Registers definition for Freescale i.MX515 GPIO controller */
81
82
#define IMX_GPIO_DR_REG 0x000 /* Pin Data */
83
#define IMX_GPIO_OE_REG 0x004 /* Set Pin Output */
84
#define IMX_GPIO_PSR_REG 0x008 /* Pad Status */
85
#define IMX_GPIO_ICR1_REG 0x00C /* Interrupt Configuration */
86
#define IMX_GPIO_ICR2_REG 0x010 /* Interrupt Configuration */
87
#define GPIO_ICR_COND_LOW 0
88
#define GPIO_ICR_COND_HIGH 1
89
#define GPIO_ICR_COND_RISE 2
90
#define GPIO_ICR_COND_FALL 3
91
#define GPIO_ICR_COND_MASK 0x3
92
#define IMX_GPIO_IMR_REG 0x014 /* Interrupt Mask Register */
93
#define IMX_GPIO_ISR_REG 0x018 /* Interrupt Status Register */
94
#define IMX_GPIO_EDGE_REG 0x01C /* Edge Detect Register */
95
96
#ifdef INTRNG
97
#define DEFAULT_CAPS (GPIO_PIN_INPUT | GPIO_PIN_OUTPUT | \
98
GPIO_INTR_LEVEL_LOW | GPIO_INTR_LEVEL_HIGH | GPIO_INTR_EDGE_RISING | \
99
GPIO_INTR_EDGE_FALLING | GPIO_INTR_EDGE_BOTH)
100
#else
101
#define DEFAULT_CAPS (GPIO_PIN_INPUT | GPIO_PIN_OUTPUT)
102
#endif
103
104
#define NGPIO 32
105
106
#ifdef INTRNG
107
struct gpio_irqsrc {
108
struct intr_irqsrc gi_isrc;
109
u_int gi_irq;
110
uint32_t gi_mode;
111
};
112
#endif
113
114
struct imx51_gpio_softc {
115
device_t dev;
116
device_t sc_busdev;
117
struct mtx sc_mtx;
118
struct resource *sc_res[3]; /* 1 x mem, 2 x IRQ */
119
void *gpio_ih[2];
120
bus_space_tag_t sc_iot;
121
bus_space_handle_t sc_ioh;
122
int gpio_npins;
123
struct gpio_pin gpio_pins[NGPIO];
124
#ifdef INTRNG
125
struct gpio_irqsrc gpio_pic_irqsrc[NGPIO];
126
#endif
127
#ifdef IMX_ENABLE_CLOCKS
128
clk_t clk;
129
#endif
130
};
131
132
static struct ofw_compat_data compat_data[] = {
133
{"fsl,imx8mq-gpio", 1},
134
{"fsl,imx6q-gpio", 1},
135
{"fsl,imx53-gpio", 1},
136
{"fsl,imx51-gpio", 1},
137
{"fsl,imx35-gpio", 1},
138
{NULL, 0}
139
};
140
141
static struct resource_spec imx_gpio_spec[] = {
142
{ SYS_RES_MEMORY, 0, RF_ACTIVE },
143
{ SYS_RES_IRQ, 0, RF_ACTIVE },
144
{ SYS_RES_IRQ, 1, RF_ACTIVE },
145
{ -1, 0 }
146
};
147
#define FIRST_IRQRES 1
148
#define NUM_IRQRES 2
149
150
/*
151
* Helpers
152
*/
153
static void imx51_gpio_pin_configure(struct imx51_gpio_softc *,
154
struct gpio_pin *, uint32_t);
155
156
/*
157
* Driver stuff
158
*/
159
static int imx51_gpio_probe(device_t);
160
static int imx51_gpio_attach(device_t);
161
static int imx51_gpio_detach(device_t);
162
163
/*
164
* GPIO interface
165
*/
166
static device_t imx51_gpio_get_bus(device_t);
167
static int imx51_gpio_pin_max(device_t, int *);
168
static int imx51_gpio_pin_getcaps(device_t, uint32_t, uint32_t *);
169
static int imx51_gpio_pin_getflags(device_t, uint32_t, uint32_t *);
170
static int imx51_gpio_pin_getname(device_t, uint32_t, char *);
171
static int imx51_gpio_pin_setflags(device_t, uint32_t, uint32_t);
172
static int imx51_gpio_pin_set(device_t, uint32_t, unsigned int);
173
static int imx51_gpio_pin_get(device_t, uint32_t, unsigned int *);
174
static int imx51_gpio_pin_toggle(device_t, uint32_t pin);
175
176
#ifdef INTRNG
177
static int
178
gpio_pic_map_fdt(struct imx51_gpio_softc *sc, struct intr_map_data_fdt *daf,
179
u_int *irqp, uint32_t *modep)
180
{
181
u_int irq;
182
uint32_t mode;
183
184
/*
185
* From devicetree/bindings/gpio/fsl-imx-gpio.txt:
186
* #interrupt-cells: 2. The first cell is the GPIO number. The second
187
* cell bits[3:0] is used to specify trigger type and level flags:
188
* 1 = low-to-high edge triggered.
189
* 2 = high-to-low edge triggered.
190
* 4 = active high level-sensitive.
191
* 8 = active low level-sensitive.
192
* We can do any single one of these modes, and also edge low+high
193
* (i.e., trigger on both edges); other combinations are not supported.
194
*/
195
196
if (daf->ncells != 2) {
197
device_printf(sc->dev, "Invalid #interrupt-cells\n");
198
return (EINVAL);
199
}
200
201
irq = daf->cells[0];
202
if (irq >= sc->gpio_npins) {
203
device_printf(sc->dev, "Invalid interrupt number %u\n", irq);
204
return (EINVAL);
205
}
206
switch (daf->cells[1]) {
207
case 1:
208
mode = GPIO_INTR_EDGE_RISING;
209
break;
210
case 2:
211
mode = GPIO_INTR_EDGE_FALLING;
212
break;
213
case 3:
214
mode = GPIO_INTR_EDGE_BOTH;
215
break;
216
case 4:
217
mode = GPIO_INTR_LEVEL_HIGH;
218
break;
219
case 8:
220
mode = GPIO_INTR_LEVEL_LOW;
221
break;
222
default:
223
device_printf(sc->dev, "Unsupported interrupt mode 0x%2x\n",
224
daf->cells[1]);
225
return (ENOTSUP);
226
}
227
*irqp = irq;
228
if (modep != NULL)
229
*modep = mode;
230
return (0);
231
}
232
233
static int
234
gpio_pic_map_gpio(struct imx51_gpio_softc *sc, struct intr_map_data_gpio *dag,
235
u_int *irqp, uint32_t *modep)
236
{
237
u_int irq;
238
239
irq = dag->gpio_pin_num;
240
if (irq >= sc->gpio_npins) {
241
device_printf(sc->dev, "Invalid interrupt number %u\n", irq);
242
return (EINVAL);
243
}
244
245
switch (dag->gpio_intr_mode) {
246
case GPIO_INTR_LEVEL_LOW:
247
case GPIO_INTR_LEVEL_HIGH:
248
case GPIO_INTR_EDGE_RISING:
249
case GPIO_INTR_EDGE_FALLING:
250
case GPIO_INTR_EDGE_BOTH:
251
break;
252
default:
253
device_printf(sc->dev, "Unsupported interrupt mode 0x%8x\n",
254
dag->gpio_intr_mode);
255
return (EINVAL);
256
}
257
258
*irqp = irq;
259
if (modep != NULL)
260
*modep = dag->gpio_intr_mode;
261
return (0);
262
}
263
264
static int
265
gpio_pic_map(struct imx51_gpio_softc *sc, struct intr_map_data *data,
266
u_int *irqp, uint32_t *modep)
267
{
268
269
switch (data->type) {
270
case INTR_MAP_DATA_FDT:
271
return (gpio_pic_map_fdt(sc, (struct intr_map_data_fdt *)data,
272
irqp, modep));
273
case INTR_MAP_DATA_GPIO:
274
return (gpio_pic_map_gpio(sc, (struct intr_map_data_gpio *)data,
275
irqp, modep));
276
default:
277
return (ENOTSUP);
278
}
279
}
280
281
static int
282
gpio_pic_map_intr(device_t dev, struct intr_map_data *data,
283
struct intr_irqsrc **isrcp)
284
{
285
int error;
286
u_int irq;
287
struct imx51_gpio_softc *sc;
288
289
sc = device_get_softc(dev);
290
error = gpio_pic_map(sc, data, &irq, NULL);
291
if (error == 0)
292
*isrcp = &sc->gpio_pic_irqsrc[irq].gi_isrc;
293
return (error);
294
}
295
296
static int
297
gpio_pic_teardown_intr(device_t dev, struct intr_irqsrc *isrc,
298
struct resource *res, struct intr_map_data *data)
299
{
300
struct imx51_gpio_softc *sc;
301
struct gpio_irqsrc *gi;
302
303
sc = device_get_softc(dev);
304
if (isrc->isrc_handlers == 0) {
305
gi = (struct gpio_irqsrc *)isrc;
306
gi->gi_mode = GPIO_INTR_CONFORM;
307
308
// XXX Not sure this is necessary
309
mtx_lock_spin(&sc->sc_mtx);
310
CLEAR4(sc, IMX_GPIO_IMR_REG, (1U << gi->gi_irq));
311
WRITE4(sc, IMX_GPIO_ISR_REG, (1U << gi->gi_irq));
312
mtx_unlock_spin(&sc->sc_mtx);
313
}
314
return (0);
315
}
316
317
static int
318
gpio_pic_setup_intr(device_t dev, struct intr_irqsrc *isrc,
319
struct resource *res, struct intr_map_data *data)
320
{
321
struct imx51_gpio_softc *sc;
322
struct gpio_irqsrc *gi;
323
int error;
324
u_int icfg, irq, reg, shift, wrk;
325
uint32_t mode;
326
327
if (data == NULL)
328
return (ENOTSUP);
329
330
sc = device_get_softc(dev);
331
gi = (struct gpio_irqsrc *)isrc;
332
333
/* Get config for interrupt. */
334
error = gpio_pic_map(sc, data, &irq, &mode);
335
if (error != 0)
336
return (error);
337
if (gi->gi_irq != irq)
338
return (EINVAL);
339
340
/* Compare config if this is not first setup. */
341
if (isrc->isrc_handlers != 0)
342
return (gi->gi_mode == mode ? 0 : EINVAL);
343
gi->gi_mode = mode;
344
345
/*
346
* To interrupt on both edges we have to use the EDGE register. The
347
* manual says it only exists for backwards compatibilty with older imx
348
* chips, but it's also the only way to configure interrupting on both
349
* edges. If the EDGE bit is on, the corresponding ICRn bit is ignored.
350
*/
351
mtx_lock_spin(&sc->sc_mtx);
352
if (mode == GPIO_INTR_EDGE_BOTH) {
353
SET4(sc, IMX_GPIO_EDGE_REG, (1u << irq));
354
} else {
355
CLEAR4(sc, IMX_GPIO_EDGE_REG, (1u << irq));
356
switch (mode) {
357
default:
358
/* silence warnings; default can't actually happen. */
359
/* FALLTHROUGH */
360
case GPIO_INTR_LEVEL_LOW:
361
icfg = GPIO_ICR_COND_LOW;
362
break;
363
case GPIO_INTR_LEVEL_HIGH:
364
icfg = GPIO_ICR_COND_HIGH;
365
break;
366
case GPIO_INTR_EDGE_RISING:
367
icfg = GPIO_ICR_COND_RISE;
368
break;
369
case GPIO_INTR_EDGE_FALLING:
370
icfg = GPIO_ICR_COND_FALL;
371
break;
372
}
373
if (irq < 16) {
374
reg = IMX_GPIO_ICR1_REG;
375
shift = 2 * irq;
376
} else {
377
reg = IMX_GPIO_ICR2_REG;
378
shift = 2 * (irq - 16);
379
}
380
wrk = READ4(sc, reg);
381
wrk &= ~(GPIO_ICR_COND_MASK << shift);
382
wrk |= icfg << shift;
383
WRITE4(sc, reg, wrk);
384
}
385
WRITE4(sc, IMX_GPIO_ISR_REG, (1u << irq));
386
SET4(sc, IMX_GPIO_IMR_REG, (1u << irq));
387
mtx_unlock_spin(&sc->sc_mtx);
388
389
return (0);
390
}
391
392
/*
393
* this is mask_intr
394
*/
395
static void
396
gpio_pic_disable_intr(device_t dev, struct intr_irqsrc *isrc)
397
{
398
struct imx51_gpio_softc *sc;
399
u_int irq;
400
401
sc = device_get_softc(dev);
402
irq = ((struct gpio_irqsrc *)isrc)->gi_irq;
403
404
mtx_lock_spin(&sc->sc_mtx);
405
CLEAR4(sc, IMX_GPIO_IMR_REG, (1U << irq));
406
mtx_unlock_spin(&sc->sc_mtx);
407
}
408
409
/*
410
* this is unmask_intr
411
*/
412
static void
413
gpio_pic_enable_intr(device_t dev, struct intr_irqsrc *isrc)
414
{
415
struct imx51_gpio_softc *sc;
416
u_int irq;
417
418
sc = device_get_softc(dev);
419
irq = ((struct gpio_irqsrc *)isrc)->gi_irq;
420
421
mtx_lock_spin(&sc->sc_mtx);
422
SET4(sc, IMX_GPIO_IMR_REG, (1U << irq));
423
mtx_unlock_spin(&sc->sc_mtx);
424
}
425
426
static void
427
gpio_pic_post_filter(device_t dev, struct intr_irqsrc *isrc)
428
{
429
struct imx51_gpio_softc *sc;
430
u_int irq;
431
432
sc = device_get_softc(dev);
433
irq = ((struct gpio_irqsrc *)isrc)->gi_irq;
434
435
arm_irq_memory_barrier(0);
436
/* EOI. W1C reg so no r-m-w, no locking needed. */
437
WRITE4(sc, IMX_GPIO_ISR_REG, (1U << irq));
438
}
439
440
static void
441
gpio_pic_post_ithread(device_t dev, struct intr_irqsrc *isrc)
442
{
443
struct imx51_gpio_softc *sc;
444
u_int irq;
445
446
sc = device_get_softc(dev);
447
irq = ((struct gpio_irqsrc *)isrc)->gi_irq;
448
449
arm_irq_memory_barrier(0);
450
/* EOI. W1C reg so no r-m-w, no locking needed. */
451
WRITE4(sc, IMX_GPIO_ISR_REG, (1U << irq));
452
gpio_pic_enable_intr(dev, isrc);
453
}
454
455
static void
456
gpio_pic_pre_ithread(device_t dev, struct intr_irqsrc *isrc)
457
{
458
gpio_pic_disable_intr(dev, isrc);
459
}
460
461
static int
462
gpio_pic_filter(void *arg)
463
{
464
struct imx51_gpio_softc *sc;
465
struct intr_irqsrc *isrc;
466
uint32_t i, interrupts;
467
468
sc = arg;
469
mtx_lock_spin(&sc->sc_mtx);
470
interrupts = READ4(sc, IMX_GPIO_ISR_REG) & READ4(sc, IMX_GPIO_IMR_REG);
471
mtx_unlock_spin(&sc->sc_mtx);
472
473
for (i = 0; interrupts != 0; i++, interrupts >>= 1) {
474
if ((interrupts & 0x1) == 0)
475
continue;
476
isrc = &sc->gpio_pic_irqsrc[i].gi_isrc;
477
if (intr_isrc_dispatch(isrc, curthread->td_intr_frame) != 0) {
478
gpio_pic_disable_intr(sc->dev, isrc);
479
gpio_pic_post_filter(sc->dev, isrc);
480
device_printf(sc->dev, "Stray irq %u disabled\n", i);
481
}
482
}
483
484
return (FILTER_HANDLED);
485
}
486
487
/*
488
* Initialize our isrcs and register them with intrng.
489
*/
490
static int
491
gpio_pic_register_isrcs(struct imx51_gpio_softc *sc)
492
{
493
int error;
494
uint32_t irq;
495
const char *name;
496
497
name = device_get_nameunit(sc->dev);
498
for (irq = 0; irq < NGPIO; irq++) {
499
sc->gpio_pic_irqsrc[irq].gi_irq = irq;
500
sc->gpio_pic_irqsrc[irq].gi_mode = GPIO_INTR_CONFORM;
501
502
error = intr_isrc_register(&sc->gpio_pic_irqsrc[irq].gi_isrc,
503
sc->dev, 0, "%s,%u", name, irq);
504
if (error != 0) {
505
/* XXX call intr_isrc_deregister() */
506
device_printf(sc->dev, "%s failed", __func__);
507
return (error);
508
}
509
}
510
return (0);
511
}
512
#endif
513
514
/*
515
*
516
*/
517
static void
518
imx51_gpio_pin_configure(struct imx51_gpio_softc *sc, struct gpio_pin *pin,
519
unsigned int flags)
520
{
521
u_int newflags, pad;
522
523
mtx_lock_spin(&sc->sc_mtx);
524
525
/*
526
* Manage input/output; other flags not supported yet (maybe not ever,
527
* since we have no connection to the pad config registers from here).
528
*
529
* When setting a pin to output, honor the PRESET_[LOW,HIGH] flags if
530
* present. Otherwise, for glitchless transitions on pins with pulls,
531
* read the current state of the pad and preset the DR register to drive
532
* the current value onto the pin before enabling the pin for output.
533
*
534
* Note that changes to pin->gp_flags must be acccumulated in newflags
535
* and stored with a single writeback to gp_flags at the end, to enable
536
* unlocked reads of that value elsewhere. This is only about unlocked
537
* access to gp_flags from elsewhere; we still use locking in this
538
* function to protect r-m-w access to the hardware registers.
539
*/
540
if (flags & (GPIO_PIN_INPUT | GPIO_PIN_OUTPUT)) {
541
newflags = pin->gp_flags & ~(GPIO_PIN_INPUT | GPIO_PIN_OUTPUT);
542
if (flags & GPIO_PIN_OUTPUT) {
543
if (flags & GPIO_PIN_PRESET_LOW) {
544
pad = 0;
545
} else if (flags & GPIO_PIN_PRESET_HIGH) {
546
pad = 1;
547
} else {
548
if (flags & GPIO_PIN_OPENDRAIN)
549
pad = READ4(sc, IMX_GPIO_PSR_REG);
550
else
551
pad = READ4(sc, IMX_GPIO_DR_REG);
552
pad = (pad >> pin->gp_pin) & 1;
553
}
554
newflags |= GPIO_PIN_OUTPUT;
555
SET4(sc, IMX_GPIO_DR_REG, (pad << pin->gp_pin));
556
SET4(sc, IMX_GPIO_OE_REG, (1U << pin->gp_pin));
557
} else {
558
newflags |= GPIO_PIN_INPUT;
559
CLEAR4(sc, IMX_GPIO_OE_REG, (1U << pin->gp_pin));
560
}
561
pin->gp_flags = newflags;
562
}
563
564
mtx_unlock_spin(&sc->sc_mtx);
565
}
566
567
static device_t
568
imx51_gpio_get_bus(device_t dev)
569
{
570
struct imx51_gpio_softc *sc;
571
572
sc = device_get_softc(dev);
573
574
return (sc->sc_busdev);
575
}
576
577
static int
578
imx51_gpio_pin_max(device_t dev, int *maxpin)
579
{
580
struct imx51_gpio_softc *sc;
581
582
sc = device_get_softc(dev);
583
*maxpin = sc->gpio_npins - 1;
584
585
return (0);
586
}
587
588
static int
589
imx51_gpio_pin_getcaps(device_t dev, uint32_t pin, uint32_t *caps)
590
{
591
struct imx51_gpio_softc *sc;
592
593
sc = device_get_softc(dev);
594
595
if (pin >= sc->gpio_npins)
596
return (EINVAL);
597
598
*caps = sc->gpio_pins[pin].gp_caps;
599
600
return (0);
601
}
602
603
static int
604
imx51_gpio_pin_getflags(device_t dev, uint32_t pin, uint32_t *flags)
605
{
606
struct imx51_gpio_softc *sc;
607
608
sc = device_get_softc(dev);
609
610
if (pin >= sc->gpio_npins)
611
return (EINVAL);
612
613
*flags = sc->gpio_pins[pin].gp_flags;
614
615
return (0);
616
}
617
618
static int
619
imx51_gpio_pin_getname(device_t dev, uint32_t pin, char *name)
620
{
621
struct imx51_gpio_softc *sc;
622
623
sc = device_get_softc(dev);
624
if (pin >= sc->gpio_npins)
625
return (EINVAL);
626
627
mtx_lock_spin(&sc->sc_mtx);
628
memcpy(name, sc->gpio_pins[pin].gp_name, GPIOMAXNAME);
629
mtx_unlock_spin(&sc->sc_mtx);
630
631
return (0);
632
}
633
634
static int
635
imx51_gpio_pin_setflags(device_t dev, uint32_t pin, uint32_t flags)
636
{
637
struct imx51_gpio_softc *sc;
638
639
sc = device_get_softc(dev);
640
641
if (pin >= sc->gpio_npins)
642
return (EINVAL);
643
644
imx51_gpio_pin_configure(sc, &sc->gpio_pins[pin], flags);
645
646
return (0);
647
}
648
649
static int
650
imx51_gpio_pin_set(device_t dev, uint32_t pin, unsigned int value)
651
{
652
struct imx51_gpio_softc *sc;
653
654
sc = device_get_softc(dev);
655
656
if (pin >= sc->gpio_npins)
657
return (EINVAL);
658
659
mtx_lock_spin(&sc->sc_mtx);
660
if (value)
661
SET4(sc, IMX_GPIO_DR_REG, (1U << pin));
662
else
663
CLEAR4(sc, IMX_GPIO_DR_REG, (1U << pin));
664
mtx_unlock_spin(&sc->sc_mtx);
665
666
return (0);
667
}
668
669
static int
670
imx51_gpio_pin_get(device_t dev, uint32_t pin, unsigned int *val)
671
{
672
struct imx51_gpio_softc *sc;
673
674
sc = device_get_softc(dev);
675
676
if (pin >= sc->gpio_npins)
677
return (EINVAL);
678
679
/*
680
* Normally a pin set for output can be read by reading the DR reg which
681
* indicates what value is being driven to that pin. The exception is
682
* pins configured for open-drain mode, in which case we have to read
683
* the pad status register in case the pin is being driven externally.
684
* Doing so requires that the SION bit be configured in pinmux, which
685
* isn't the case for most normal gpio pins, so only try to read via PSR
686
* if the OPENDRAIN flag is set, and it's the user's job to correctly
687
* configure SION along with open-drain output mode for those pins.
688
*/
689
if (sc->gpio_pins[pin].gp_flags & GPIO_PIN_OPENDRAIN)
690
*val = (READ4(sc, IMX_GPIO_PSR_REG) >> pin) & 1;
691
else
692
*val = (READ4(sc, IMX_GPIO_DR_REG) >> pin) & 1;
693
694
return (0);
695
}
696
697
static int
698
imx51_gpio_pin_toggle(device_t dev, uint32_t pin)
699
{
700
struct imx51_gpio_softc *sc;
701
702
sc = device_get_softc(dev);
703
704
if (pin >= sc->gpio_npins)
705
return (EINVAL);
706
707
mtx_lock_spin(&sc->sc_mtx);
708
WRITE4(sc, IMX_GPIO_DR_REG,
709
(READ4(sc, IMX_GPIO_DR_REG) ^ (1U << pin)));
710
mtx_unlock_spin(&sc->sc_mtx);
711
712
return (0);
713
}
714
715
static int
716
imx51_gpio_pin_access_32(device_t dev, uint32_t first_pin, uint32_t clear_pins,
717
uint32_t change_pins, uint32_t *orig_pins)
718
{
719
struct imx51_gpio_softc *sc;
720
721
if (first_pin != 0)
722
return (EINVAL);
723
724
sc = device_get_softc(dev);
725
726
if (orig_pins != NULL)
727
*orig_pins = READ4(sc, IMX_GPIO_DR_REG);
728
729
if ((clear_pins | change_pins) != 0) {
730
mtx_lock_spin(&sc->sc_mtx);
731
WRITE4(sc, IMX_GPIO_DR_REG,
732
(READ4(sc, IMX_GPIO_DR_REG) & ~clear_pins) ^ change_pins);
733
mtx_unlock_spin(&sc->sc_mtx);
734
}
735
736
return (0);
737
}
738
739
static int
740
imx51_gpio_pin_config_32(device_t dev, uint32_t first_pin, uint32_t num_pins,
741
uint32_t *pin_flags)
742
{
743
struct imx51_gpio_softc *sc;
744
u_int i;
745
uint32_t bit, drclr, drset, flags, oeclr, oeset, pads;
746
747
sc = device_get_softc(dev);
748
749
if (first_pin != 0 || num_pins > sc->gpio_npins)
750
return (EINVAL);
751
752
drclr = drset = oeclr = oeset = 0;
753
pads = READ4(sc, IMX_GPIO_DR_REG);
754
755
for (i = 0; i < num_pins; ++i) {
756
bit = 1u << i;
757
flags = pin_flags[i];
758
if (flags & GPIO_PIN_INPUT) {
759
oeclr |= bit;
760
} else if (flags & GPIO_PIN_OUTPUT) {
761
oeset |= bit;
762
if (flags & GPIO_PIN_PRESET_LOW)
763
drclr |= bit;
764
else if (flags & GPIO_PIN_PRESET_HIGH)
765
drset |= bit;
766
else /* Drive whatever it's now pulled to. */
767
drset |= pads & bit;
768
}
769
}
770
771
mtx_lock_spin(&sc->sc_mtx);
772
WRITE4(sc, IMX_GPIO_DR_REG,
773
(READ4(sc, IMX_GPIO_DR_REG) & ~drclr) | drset);
774
WRITE4(sc, IMX_GPIO_OE_REG,
775
(READ4(sc, IMX_GPIO_OE_REG) & ~oeclr) | oeset);
776
mtx_unlock_spin(&sc->sc_mtx);
777
778
return (0);
779
}
780
781
static int
782
imx51_gpio_probe(device_t dev)
783
{
784
785
if (!ofw_bus_status_okay(dev))
786
return (ENXIO);
787
788
if (ofw_bus_search_compatible(dev, compat_data)->ocd_data != 0) {
789
device_set_desc(dev, "Freescale i.MX GPIO Controller");
790
return (BUS_PROBE_DEFAULT);
791
}
792
793
return (ENXIO);
794
}
795
796
static int
797
imx51_gpio_attach(device_t dev)
798
{
799
struct imx51_gpio_softc *sc;
800
int i, irq, unit;
801
#ifdef IMX_ENABLE_CLOCKS
802
int err;
803
#endif
804
805
sc = device_get_softc(dev);
806
sc->dev = dev;
807
sc->gpio_npins = NGPIO;
808
809
mtx_init(&sc->sc_mtx, device_get_nameunit(sc->dev), NULL, MTX_SPIN);
810
811
#ifdef IMX_ENABLE_CLOCKS
812
if (clk_get_by_ofw_index(sc->dev, 0, 0, &sc->clk) != 0) {
813
device_printf(dev, "could not get clock");
814
return (ENOENT);
815
}
816
817
err = clk_enable(sc->clk);
818
if (err != 0) {
819
device_printf(sc->dev, "could not enable ipg clock\n");
820
return (err);
821
}
822
#endif
823
824
if (bus_alloc_resources(dev, imx_gpio_spec, sc->sc_res)) {
825
device_printf(dev, "could not allocate resources\n");
826
bus_release_resources(dev, imx_gpio_spec, sc->sc_res);
827
mtx_destroy(&sc->sc_mtx);
828
return (ENXIO);
829
}
830
831
sc->sc_iot = rman_get_bustag(sc->sc_res[0]);
832
sc->sc_ioh = rman_get_bushandle(sc->sc_res[0]);
833
/*
834
* Mask off all interrupts in hardware, then set up interrupt handling.
835
*/
836
WRITE4(sc, IMX_GPIO_IMR_REG, 0);
837
for (irq = 0; irq < 2; irq++) {
838
#ifdef INTRNG
839
if ((bus_setup_intr(dev, sc->sc_res[1 + irq], INTR_TYPE_CLK,
840
gpio_pic_filter, NULL, sc, &sc->gpio_ih[irq]))) {
841
device_printf(dev,
842
"WARNING: unable to register interrupt handler\n");
843
imx51_gpio_detach(dev);
844
return (ENXIO);
845
}
846
#endif
847
}
848
849
unit = device_get_unit(dev);
850
for (i = 0; i < sc->gpio_npins; i++) {
851
sc->gpio_pins[i].gp_pin = i;
852
sc->gpio_pins[i].gp_caps = DEFAULT_CAPS;
853
sc->gpio_pins[i].gp_flags =
854
(READ4(sc, IMX_GPIO_OE_REG) & (1U << i)) ? GPIO_PIN_OUTPUT :
855
GPIO_PIN_INPUT;
856
snprintf(sc->gpio_pins[i].gp_name, GPIOMAXNAME,
857
"GPIO%d_IO%02d", unit + 1, i);
858
}
859
860
#ifdef INTRNG
861
gpio_pic_register_isrcs(sc);
862
intr_pic_register(dev, OF_xref_from_node(ofw_bus_get_node(dev)));
863
#endif
864
sc->sc_busdev = gpiobus_add_bus(dev);
865
866
if (sc->sc_busdev == NULL) {
867
imx51_gpio_detach(dev);
868
return (ENXIO);
869
}
870
871
bus_attach_children(dev);
872
return (0);
873
}
874
875
static int
876
imx51_gpio_detach(device_t dev)
877
{
878
int irq;
879
struct imx51_gpio_softc *sc;
880
#ifdef IMX_ENABLE_CLOCKS
881
int error;
882
#endif
883
884
sc = device_get_softc(dev);
885
886
#ifdef IMX_ENABLE_CLOCKS
887
error = clk_disable(sc->clk);
888
if (error != 0) {
889
device_printf(sc->dev, "could not disable ipg clock\n");
890
return (error);
891
}
892
#endif
893
894
gpiobus_detach_bus(dev);
895
for (irq = 0; irq < NUM_IRQRES; irq++) {
896
if (sc->gpio_ih[irq])
897
bus_teardown_intr(dev, sc->sc_res[irq + FIRST_IRQRES],
898
sc->gpio_ih[irq]);
899
}
900
bus_release_resources(dev, imx_gpio_spec, sc->sc_res);
901
mtx_destroy(&sc->sc_mtx);
902
903
return(0);
904
}
905
906
static phandle_t
907
imx51_gpio_get_node(device_t bus, device_t dev)
908
{
909
/*
910
* Share controller node with gpiobus device
911
*/
912
return ofw_bus_get_node(bus);
913
}
914
915
static device_method_t imx51_gpio_methods[] = {
916
DEVMETHOD(device_probe, imx51_gpio_probe),
917
DEVMETHOD(device_attach, imx51_gpio_attach),
918
DEVMETHOD(device_detach, imx51_gpio_detach),
919
920
#ifdef INTRNG
921
/* Bus interface */
922
DEVMETHOD(bus_setup_intr, bus_generic_setup_intr),
923
DEVMETHOD(bus_teardown_intr, bus_generic_teardown_intr),
924
925
/* Interrupt controller interface */
926
DEVMETHOD(pic_disable_intr, gpio_pic_disable_intr),
927
DEVMETHOD(pic_enable_intr, gpio_pic_enable_intr),
928
DEVMETHOD(pic_map_intr, gpio_pic_map_intr),
929
DEVMETHOD(pic_setup_intr, gpio_pic_setup_intr),
930
DEVMETHOD(pic_teardown_intr, gpio_pic_teardown_intr),
931
DEVMETHOD(pic_post_filter, gpio_pic_post_filter),
932
DEVMETHOD(pic_post_ithread, gpio_pic_post_ithread),
933
DEVMETHOD(pic_pre_ithread, gpio_pic_pre_ithread),
934
#endif
935
936
/* OFW methods */
937
DEVMETHOD(ofw_bus_get_node, imx51_gpio_get_node),
938
939
/* GPIO protocol */
940
DEVMETHOD(gpio_get_bus, imx51_gpio_get_bus),
941
DEVMETHOD(gpio_pin_max, imx51_gpio_pin_max),
942
DEVMETHOD(gpio_pin_getname, imx51_gpio_pin_getname),
943
DEVMETHOD(gpio_pin_getflags, imx51_gpio_pin_getflags),
944
DEVMETHOD(gpio_pin_getcaps, imx51_gpio_pin_getcaps),
945
DEVMETHOD(gpio_pin_setflags, imx51_gpio_pin_setflags),
946
DEVMETHOD(gpio_pin_get, imx51_gpio_pin_get),
947
DEVMETHOD(gpio_pin_set, imx51_gpio_pin_set),
948
DEVMETHOD(gpio_pin_toggle, imx51_gpio_pin_toggle),
949
DEVMETHOD(gpio_pin_access_32, imx51_gpio_pin_access_32),
950
DEVMETHOD(gpio_pin_config_32, imx51_gpio_pin_config_32),
951
{0, 0},
952
};
953
954
static driver_t imx51_gpio_driver = {
955
"gpio",
956
imx51_gpio_methods,
957
sizeof(struct imx51_gpio_softc),
958
};
959
960
EARLY_DRIVER_MODULE(imx51_gpio, simplebus, imx51_gpio_driver, 0, 0,
961
BUS_PASS_INTERRUPT + BUS_PASS_ORDER_LATE);
962
963