source: rtems-libbsd/freebsd/sys/arm/freescale/imx/imx_gpio.c @ 06dd40e

55-freebsd-126-freebsd-12
Last change on this file since 06dd40e was 06dd40e, checked in by Sebastian Huber <sebastian.huber@…>, on 09/24/18 at 11:45:52

imx/imx_gpio.c: Port to RTEMS

Update #3525.

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