The Design and Implementation of the FreeBSD Operating System, Second Edition
Now available: The Design and Implementation of the FreeBSD Operating System (Second Edition)


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]

FreeBSD/Linux Kernel Cross Reference
sys/arm/freescale/imx/imx_gpio.c

Version: -  FREEBSD  -  FREEBSD-13-STABLE  -  FREEBSD-13-0  -  FREEBSD-12-STABLE  -  FREEBSD-12-0  -  FREEBSD-11-STABLE  -  FREEBSD-11-0  -  FREEBSD-10-STABLE  -  FREEBSD-10-0  -  FREEBSD-9-STABLE  -  FREEBSD-9-0  -  FREEBSD-8-STABLE  -  FREEBSD-8-0  -  FREEBSD-7-STABLE  -  FREEBSD-7-0  -  FREEBSD-6-STABLE  -  FREEBSD-6-0  -  FREEBSD-5-STABLE  -  FREEBSD-5-0  -  FREEBSD-4-STABLE  -  FREEBSD-3-STABLE  -  FREEBSD22  -  l41  -  OPENBSD  -  linux-2.6  -  MK84  -  PLAN9  -  xnu-8792 
SearchContext: -  none  -  3  -  10 

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

Cache object: cba7dc0298e0041fd897d178b80d506b


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]


This page is part of the FreeBSD/Linux Linux Kernel Cross-Reference, and was automatically generated using a modified version of the LXR engine.