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

Cache object: 17b41daca603a0470760bb0e31c4099c


[ 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.