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

Cache object: 48bfe698b886977dc86ca6bc126b3b36


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