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/rockchip/rk30xx_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) 2013 Ganbold Tsagaankhuu <ganbold@freebsd.org>
    3  * Copyright (c) 2012 Oleksandr Tymoshenko <gonzo@freebsd.org>
    4  * Copyright (c) 2012 Luiz Otavio O Souza.
    5  * All rights reserved.
    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 #include <sys/cdefs.h>
   30 __FBSDID("$FreeBSD: releng/11.1/sys/arm/rockchip/rk30xx_gpio.c 314503 2017-03-01 18:53:05Z ian $");
   31 
   32 #include <sys/param.h>
   33 #include <sys/systm.h>
   34 #include <sys/bus.h>
   35 
   36 #include <sys/kernel.h>
   37 #include <sys/module.h>
   38 #include <sys/rman.h>
   39 #include <sys/lock.h>
   40 #include <sys/mutex.h>
   41 #include <sys/gpio.h>
   42 
   43 #include <machine/bus.h>
   44 #include <machine/resource.h>
   45 #include <machine/intr.h>
   46 
   47 #include <dev/fdt/fdt_common.h>
   48 #include <dev/gpio/gpiobusvar.h>
   49 #include <dev/ofw/ofw_bus.h>
   50 #include <dev/ofw/ofw_bus_subr.h>
   51 
   52 #include "gpio_if.h"
   53 
   54 #include "rk30xx_grf.h"
   55 #include "rk30xx_pmu.h"
   56 
   57 /*
   58  * RK3188 has 4 banks of gpio.
   59  * 32 pins per bank
   60  * PA0 - PA7 | PB0 - PB7
   61  * PC0 - PC7 | PD0 - PD7
   62  */
   63 
   64 #define RK30_GPIO_PINS          32
   65 #define RK30_GPIO_DEFAULT_CAPS  (GPIO_PIN_INPUT | GPIO_PIN_OUTPUT | \
   66     GPIO_PIN_PULLUP | GPIO_PIN_PULLDOWN)
   67 
   68 #define RK30_GPIO_NONE                  0
   69 #define RK30_GPIO_PULLUP                1
   70 #define RK30_GPIO_PULLDOWN              2
   71 
   72 struct rk30_gpio_softc {
   73         device_t                sc_dev;
   74         device_t                sc_busdev;
   75         struct mtx              sc_mtx;
   76         struct resource *       sc_mem_res;
   77         struct resource *       sc_irq_res;
   78         bus_space_tag_t         sc_bst;
   79         bus_space_handle_t      sc_bsh;
   80         void *                  sc_intrhand;
   81         int                     sc_bank;
   82         int                     sc_gpio_npins;
   83         struct gpio_pin         sc_gpio_pins[RK30_GPIO_PINS];
   84 };
   85 
   86 /* We use our base address to find out our bank number. */
   87 static unsigned long rk30_gpio_base_addr[4] =
   88         { 0x2000a000, 0x2003c000, 0x2003e000, 0x20080000 };
   89 static struct rk30_gpio_softc *rk30_gpio_sc = NULL;
   90 
   91 typedef int (*gpios_phandler_t)(phandle_t, pcell_t *, int);
   92 
   93 struct gpio_ctrl_entry {
   94         const char              *compat;
   95         gpios_phandler_t        handler;
   96 };
   97 
   98 int rk30_gpios_prop_handle(phandle_t ctrl, pcell_t *gpios, int len);
   99 static int rk30_gpio_init(void);
  100 
  101 struct gpio_ctrl_entry gpio_controllers[] = {
  102         { "rockchip,rk30xx-gpio", &rk30_gpios_prop_handle },
  103         { "rockchip,rk30xx-gpio", &rk30_gpios_prop_handle },
  104         { "rockchip,rk30xx-gpio", &rk30_gpios_prop_handle },
  105         { "rockchip,rk30xx-gpio", &rk30_gpios_prop_handle },
  106         { NULL, NULL }
  107 };
  108 
  109 #define RK30_GPIO_LOCK(_sc)             mtx_lock(&_sc->sc_mtx)
  110 #define RK30_GPIO_UNLOCK(_sc)           mtx_unlock(&_sc->sc_mtx)
  111 #define RK30_GPIO_LOCK_ASSERT(_sc)      mtx_assert(&_sc->sc_mtx, MA_OWNED)
  112 
  113 #define RK30_GPIO_SWPORT_DR             0x00
  114 #define RK30_GPIO_SWPORT_DDR            0x04
  115 #define RK30_GPIO_INTEN                 0x30
  116 #define RK30_GPIO_INTMASK               0x34
  117 #define RK30_GPIO_INTTYPE_LEVEL         0x38
  118 #define RK30_GPIO_INT_POLARITY          0x3c
  119 #define RK30_GPIO_INT_STATUS            0x40
  120 #define RK30_GPIO_INT_RAWSTATUS         0x44
  121 #define RK30_GPIO_DEBOUNCE              0x48
  122 #define RK30_GPIO_PORT_EOI              0x4c
  123 #define RK30_GPIO_EXT_PORT              0x50
  124 #define RK30_GPIO_LS_SYNC               0x60
  125 
  126 #define RK30_GPIO_WRITE(_sc, _off, _val)                \
  127     bus_space_write_4(_sc->sc_bst, _sc->sc_bsh, _off, _val)
  128 #define RK30_GPIO_READ(_sc, _off)                       \
  129     bus_space_read_4(_sc->sc_bst, _sc->sc_bsh, _off)
  130 
  131 static uint32_t
  132 rk30_gpio_get_function(struct rk30_gpio_softc *sc, uint32_t pin)
  133 {
  134 
  135         if (RK30_GPIO_READ(sc, RK30_GPIO_SWPORT_DDR) & (1U << pin))
  136                 return (GPIO_PIN_OUTPUT);
  137         else
  138                 return (GPIO_PIN_INPUT);
  139 }
  140 
  141 static void
  142 rk30_gpio_set_function(struct rk30_gpio_softc *sc, uint32_t pin, uint32_t func)
  143 {
  144         uint32_t data;
  145 
  146         /* Must be called with lock held. */
  147         RK30_GPIO_LOCK_ASSERT(sc);
  148         data = RK30_GPIO_READ(sc, RK30_GPIO_SWPORT_DDR);
  149         if (func == GPIO_PIN_OUTPUT)
  150                 data |= (1U << pin);
  151         else
  152                 data &= ~(1U << pin);
  153         RK30_GPIO_WRITE(sc, RK30_GPIO_SWPORT_DDR, data);
  154 }
  155 
  156 static void
  157 rk30_gpio_set_pud(struct rk30_gpio_softc *sc, uint32_t pin, uint32_t state)
  158 {
  159         uint32_t pud;
  160 
  161         /* Must be called with lock held. */
  162         RK30_GPIO_LOCK_ASSERT(sc);
  163         switch (state) {
  164         case GPIO_PIN_PULLUP:
  165                 pud = RK30_GPIO_PULLUP;
  166                 break;
  167         case GPIO_PIN_PULLDOWN:
  168                 pud = RK30_GPIO_PULLDOWN;
  169                 break;
  170         default:
  171                 pud = RK30_GPIO_NONE;
  172         }
  173         /*
  174          * The pull up/down registers for GPIO0A and half of GPIO0B
  175          * (the first 12 pins on bank 0) are at a different location.
  176          */
  177         if (sc->sc_bank == 0 && pin < 12)
  178                 rk30_pmu_gpio_pud(pin, pud);
  179         else
  180                 rk30_grf_gpio_pud(sc->sc_bank, pin, pud);
  181 }
  182 
  183 static void
  184 rk30_gpio_pin_configure(struct rk30_gpio_softc *sc, struct gpio_pin *pin,
  185     unsigned int flags)
  186 {
  187 
  188         RK30_GPIO_LOCK(sc);
  189         /*
  190          * Manage input/output.
  191          */
  192         if (flags & (GPIO_PIN_INPUT | GPIO_PIN_OUTPUT)) {
  193                 pin->gp_flags &= ~(GPIO_PIN_INPUT | GPIO_PIN_OUTPUT);
  194                 if (flags & GPIO_PIN_OUTPUT)
  195                         pin->gp_flags |= GPIO_PIN_OUTPUT;
  196                 else
  197                         pin->gp_flags |= GPIO_PIN_INPUT;
  198                 rk30_gpio_set_function(sc, pin->gp_pin, pin->gp_flags);
  199         }
  200         /* Manage Pull-up/pull-down. */
  201         pin->gp_flags &= ~(GPIO_PIN_PULLUP | GPIO_PIN_PULLDOWN);
  202         if (flags & (GPIO_PIN_PULLUP | GPIO_PIN_PULLDOWN)) {
  203                 if (flags & GPIO_PIN_PULLUP)
  204                         pin->gp_flags |= GPIO_PIN_PULLUP;
  205                 else
  206                         pin->gp_flags |= GPIO_PIN_PULLDOWN;
  207         }
  208         rk30_gpio_set_pud(sc, pin->gp_pin, pin->gp_flags);
  209         RK30_GPIO_UNLOCK(sc);
  210 }
  211 
  212 static device_t
  213 rk30_gpio_get_bus(device_t dev)
  214 {
  215         struct rk30_gpio_softc *sc;
  216 
  217         sc = device_get_softc(dev);
  218 
  219         return (sc->sc_busdev);
  220 }
  221 
  222 static int
  223 rk30_gpio_pin_max(device_t dev, int *maxpin)
  224 {
  225 
  226         *maxpin = RK30_GPIO_PINS - 1;
  227         return (0);
  228 }
  229 
  230 static int
  231 rk30_gpio_pin_getcaps(device_t dev, uint32_t pin, uint32_t *caps)
  232 {
  233         struct rk30_gpio_softc *sc = device_get_softc(dev);
  234         int i;
  235 
  236         for (i = 0; i < sc->sc_gpio_npins; i++) {
  237                 if (sc->sc_gpio_pins[i].gp_pin == pin)
  238                         break;
  239         }
  240 
  241         if (i >= sc->sc_gpio_npins)
  242                 return (EINVAL);
  243 
  244         RK30_GPIO_LOCK(sc);
  245         *caps = sc->sc_gpio_pins[i].gp_caps;
  246         RK30_GPIO_UNLOCK(sc);
  247 
  248         return (0);
  249 }
  250 
  251 static int
  252 rk30_gpio_pin_getflags(device_t dev, uint32_t pin, uint32_t *flags)
  253 {
  254         struct rk30_gpio_softc *sc = device_get_softc(dev);
  255         int i;
  256 
  257         for (i = 0; i < sc->sc_gpio_npins; i++) {
  258                 if (sc->sc_gpio_pins[i].gp_pin == pin)
  259                         break;
  260         }
  261 
  262         if (i >= sc->sc_gpio_npins)
  263                 return (EINVAL);
  264 
  265         RK30_GPIO_LOCK(sc);
  266         *flags = sc->sc_gpio_pins[i].gp_flags;
  267         RK30_GPIO_UNLOCK(sc);
  268 
  269         return (0);
  270 }
  271 
  272 static int
  273 rk30_gpio_pin_getname(device_t dev, uint32_t pin, char *name)
  274 {
  275         struct rk30_gpio_softc *sc = device_get_softc(dev);
  276         int i;
  277 
  278         for (i = 0; i < sc->sc_gpio_npins; i++) {
  279                 if (sc->sc_gpio_pins[i].gp_pin == pin)
  280                         break;
  281         }
  282 
  283         if (i >= sc->sc_gpio_npins)
  284                 return (EINVAL);
  285 
  286         RK30_GPIO_LOCK(sc);
  287         memcpy(name, sc->sc_gpio_pins[i].gp_name, GPIOMAXNAME);
  288         RK30_GPIO_UNLOCK(sc);
  289 
  290         return (0);
  291 }
  292 
  293 static int
  294 rk30_gpio_pin_setflags(device_t dev, uint32_t pin, uint32_t flags)
  295 {
  296         struct rk30_gpio_softc *sc = device_get_softc(dev);
  297         int i;
  298 
  299         for (i = 0; i < sc->sc_gpio_npins; i++) {
  300                 if (sc->sc_gpio_pins[i].gp_pin == pin)
  301                         break;
  302         }
  303 
  304         if (i >= sc->sc_gpio_npins)
  305                 return (EINVAL);
  306 
  307         rk30_gpio_pin_configure(sc, &sc->sc_gpio_pins[i], flags);
  308 
  309         return (0);
  310 }
  311 
  312 static int
  313 rk30_gpio_pin_set(device_t dev, uint32_t pin, unsigned int value)
  314 {
  315         int i;
  316         struct rk30_gpio_softc *sc;
  317         uint32_t data;
  318 
  319         sc = device_get_softc(dev);
  320         for (i = 0; i < sc->sc_gpio_npins; i++) {
  321                 if (sc->sc_gpio_pins[i].gp_pin == pin)
  322                         break;
  323         }
  324         if (i >= sc->sc_gpio_npins)
  325                 return (EINVAL);
  326         RK30_GPIO_LOCK(sc);
  327         data = RK30_GPIO_READ(sc, RK30_GPIO_SWPORT_DR);
  328         if (value)
  329                 data |= (1U << pin);
  330         else
  331                 data &= ~(1U << pin);
  332         RK30_GPIO_WRITE(sc, RK30_GPIO_SWPORT_DR, data);
  333         RK30_GPIO_UNLOCK(sc);
  334 
  335         return (0);
  336 }
  337 
  338 static int
  339 rk30_gpio_pin_get(device_t dev, uint32_t pin, unsigned int *val)
  340 {
  341         int i;
  342         struct rk30_gpio_softc *sc;
  343         uint32_t data;
  344 
  345         sc = device_get_softc(dev);
  346         for (i = 0; i < sc->sc_gpio_npins; i++) {
  347                 if (sc->sc_gpio_pins[i].gp_pin == pin)
  348                         break;
  349         }
  350         if (i >= sc->sc_gpio_npins)
  351                 return (EINVAL);
  352         RK30_GPIO_LOCK(sc);
  353         data = RK30_GPIO_READ(sc, RK30_GPIO_EXT_PORT);
  354         RK30_GPIO_UNLOCK(sc);
  355         *val = (data & (1U << pin)) ? 1 : 0;
  356 
  357         return (0);
  358 }
  359 
  360 static int
  361 rk30_gpio_pin_toggle(device_t dev, uint32_t pin)
  362 {
  363         int i;
  364         struct rk30_gpio_softc *sc;
  365         uint32_t data;
  366 
  367         sc = device_get_softc(dev);
  368         for (i = 0; i < sc->sc_gpio_npins; i++) {
  369                 if (sc->sc_gpio_pins[i].gp_pin == pin)
  370                         break;
  371         }
  372         if (i >= sc->sc_gpio_npins)
  373                 return (EINVAL);
  374         RK30_GPIO_LOCK(sc);
  375         data = RK30_GPIO_READ(sc, RK30_GPIO_SWPORT_DR);
  376         if (data & (1U << pin))
  377                 data &= ~(1U << pin);
  378         else
  379                 data |= (1U << pin);
  380         RK30_GPIO_WRITE(sc, RK30_GPIO_SWPORT_DR, data);
  381         RK30_GPIO_UNLOCK(sc);
  382 
  383         return (0);
  384 }
  385 
  386 static int
  387 rk30_gpio_probe(device_t dev)
  388 {
  389 
  390         if (!ofw_bus_status_okay(dev))
  391                 return (ENXIO);
  392 
  393         if (!ofw_bus_is_compatible(dev, "rockchip,rk30xx-gpio"))
  394                 return (ENXIO);
  395 
  396         device_set_desc(dev, "Rockchip RK30XX GPIO controller");
  397         return (BUS_PROBE_DEFAULT);
  398 }
  399 
  400 static int
  401 rk30_gpio_attach(device_t dev)
  402 {
  403         struct rk30_gpio_softc *sc = device_get_softc(dev);
  404         int i, rid;
  405         phandle_t gpio;
  406         unsigned long start;
  407 
  408         if (rk30_gpio_sc)
  409                 return (ENXIO);
  410         sc->sc_dev = dev;
  411         mtx_init(&sc->sc_mtx, "rk30 gpio", "gpio", MTX_DEF);
  412 
  413         rid = 0;
  414         sc->sc_mem_res = bus_alloc_resource_any(dev, SYS_RES_MEMORY, &rid,
  415             RF_ACTIVE);
  416         if (!sc->sc_mem_res) {
  417                 device_printf(dev, "cannot allocate memory window\n");
  418                 goto fail;
  419         }
  420         sc->sc_bst = rman_get_bustag(sc->sc_mem_res);
  421         sc->sc_bsh = rman_get_bushandle(sc->sc_mem_res);
  422         /* Check the unit we are attaching by our base address. */
  423         sc->sc_bank = -1;
  424         start = rman_get_start(sc->sc_mem_res);
  425         for (i = 0; i < nitems(rk30_gpio_base_addr); i++) {
  426                 if (rk30_gpio_base_addr[i] == start) {
  427                         sc->sc_bank = i;
  428                         break;
  429                 }
  430         }
  431         if (sc->sc_bank == -1) {
  432                 device_printf(dev,
  433                     "unsupported device unit (only GPIO0..3 are supported)\n");
  434                 goto fail;
  435         }
  436 
  437         rid = 0;
  438         sc->sc_irq_res = bus_alloc_resource_any(dev, SYS_RES_IRQ, &rid,
  439             RF_ACTIVE);
  440         if (!sc->sc_irq_res) {
  441                 device_printf(dev, "cannot allocate interrupt\n");
  442                 goto fail;
  443         }
  444 
  445         /* Find our node. */
  446         gpio = ofw_bus_get_node(sc->sc_dev);
  447 
  448         if (!OF_hasprop(gpio, "gpio-controller"))
  449                 /* Node is not a GPIO controller. */
  450                 goto fail;
  451 
  452         /* Initialize the software controlled pins. */
  453         for (i = 0; i < RK30_GPIO_PINS; i++) {
  454                 snprintf(sc->sc_gpio_pins[i].gp_name, GPIOMAXNAME,
  455                     "pin %d", i);
  456                 sc->sc_gpio_pins[i].gp_pin = i;
  457                 sc->sc_gpio_pins[i].gp_caps = RK30_GPIO_DEFAULT_CAPS;
  458                 sc->sc_gpio_pins[i].gp_flags = rk30_gpio_get_function(sc, i);
  459         }
  460         sc->sc_gpio_npins = i;
  461         rk30_gpio_sc = sc;
  462         rk30_gpio_init();
  463         sc->sc_busdev = gpiobus_attach_bus(dev);
  464         if (sc->sc_busdev == NULL)
  465                 goto fail;
  466 
  467         return (0);
  468 
  469 fail:
  470         if (sc->sc_irq_res)
  471                 bus_release_resource(dev, SYS_RES_IRQ, 0, sc->sc_irq_res);
  472         if (sc->sc_mem_res)
  473                 bus_release_resource(dev, SYS_RES_MEMORY, 0, sc->sc_mem_res);
  474         mtx_destroy(&sc->sc_mtx);
  475 
  476         return (ENXIO);
  477 }
  478 
  479 static int
  480 rk30_gpio_detach(device_t dev)
  481 {
  482 
  483         return (EBUSY);
  484 }
  485 
  486 static device_method_t rk30_gpio_methods[] = {
  487         /* Device interface */
  488         DEVMETHOD(device_probe,         rk30_gpio_probe),
  489         DEVMETHOD(device_attach,        rk30_gpio_attach),
  490         DEVMETHOD(device_detach,        rk30_gpio_detach),
  491 
  492         /* GPIO protocol */
  493         DEVMETHOD(gpio_get_bus,         rk30_gpio_get_bus),
  494         DEVMETHOD(gpio_pin_max,         rk30_gpio_pin_max),
  495         DEVMETHOD(gpio_pin_getname,     rk30_gpio_pin_getname),
  496         DEVMETHOD(gpio_pin_getflags,    rk30_gpio_pin_getflags),
  497         DEVMETHOD(gpio_pin_getcaps,     rk30_gpio_pin_getcaps),
  498         DEVMETHOD(gpio_pin_setflags,    rk30_gpio_pin_setflags),
  499         DEVMETHOD(gpio_pin_get,         rk30_gpio_pin_get),
  500         DEVMETHOD(gpio_pin_set,         rk30_gpio_pin_set),
  501         DEVMETHOD(gpio_pin_toggle,      rk30_gpio_pin_toggle),
  502 
  503         DEVMETHOD_END
  504 };
  505 
  506 static devclass_t rk30_gpio_devclass;
  507 
  508 static driver_t rk30_gpio_driver = {
  509         "gpio",
  510         rk30_gpio_methods,
  511         sizeof(struct rk30_gpio_softc),
  512 };
  513 
  514 DRIVER_MODULE(rk30_gpio, simplebus, rk30_gpio_driver, rk30_gpio_devclass, 0, 0);
  515 
  516 int
  517 rk30_gpios_prop_handle(phandle_t ctrl, pcell_t *gpios, int len)
  518 {
  519         struct rk30_gpio_softc *sc;
  520         pcell_t gpio_cells;
  521         int inc, t, tuples, tuple_size;
  522         int dir, flags, pin, i;
  523         u_long gpio_ctrl, size;
  524 
  525         sc = rk30_gpio_sc;
  526         if (sc == NULL)
  527                 return ENXIO;
  528 
  529         if (OF_getencprop(ctrl, "#gpio-cells", &gpio_cells, sizeof(pcell_t)) < 0)
  530                 return (ENXIO);
  531         if (gpio_cells != 2)
  532                 return (ENXIO);
  533 
  534         tuple_size = gpio_cells * sizeof(pcell_t) + sizeof(phandle_t);
  535         tuples = len / tuple_size;
  536 
  537         if (fdt_regsize(ctrl, &gpio_ctrl, &size))
  538                 return (ENXIO);
  539 
  540         /*
  541          * Skip controller reference, since controller's phandle is given
  542          * explicitly (in a function argument).
  543          */
  544         inc = sizeof(ihandle_t) / sizeof(pcell_t);
  545         gpios += inc;
  546         for (t = 0; t < tuples; t++) {
  547                 pin = gpios[0];
  548                 dir = gpios[1];
  549                 flags = gpios[2];
  550 
  551                 for (i = 0; i < sc->sc_gpio_npins; i++) {
  552                         if (sc->sc_gpio_pins[i].gp_pin == pin)
  553                                 break;
  554                 }
  555                 if (i >= sc->sc_gpio_npins)
  556                         return (EINVAL);
  557 
  558                 rk30_gpio_pin_configure(sc, &sc->sc_gpio_pins[i], flags);
  559 
  560                 if (dir == 1) {
  561                         /* Input. */
  562                         rk30_gpio_pin_set(sc->sc_dev, pin, GPIO_PIN_INPUT);
  563                 } else {
  564                         /* Output. */
  565                         rk30_gpio_pin_set(sc->sc_dev, pin, GPIO_PIN_OUTPUT);
  566                 }
  567                 gpios += gpio_cells + inc;
  568         }
  569 
  570         return (0);
  571 }
  572 
  573 #define MAX_PINS_PER_NODE       5
  574 #define GPIOS_PROP_CELLS        4
  575 
  576 static int
  577 rk30_gpio_init(void)
  578 {
  579         phandle_t child, parent, root, ctrl;
  580         pcell_t gpios[MAX_PINS_PER_NODE * GPIOS_PROP_CELLS];
  581         struct gpio_ctrl_entry *e;
  582         int len, rv;
  583 
  584         root = OF_finddevice("/");
  585         len = 0;
  586         parent = root;
  587 
  588         /* Traverse through entire tree to find nodes with 'gpios' prop */
  589         for (child = OF_child(parent); child != 0; child = OF_peer(child)) {
  590 
  591                 /* Find a 'leaf'. Start the search from this node. */
  592                 while (OF_child(child)) {
  593                         parent = child;
  594                         child = OF_child(child);
  595                 }
  596                 if ((len = OF_getproplen(child, "gpios")) > 0) {
  597 
  598                         if (len > sizeof(gpios))
  599                                 return (ENXIO);
  600 
  601                         /* Get 'gpios' property. */
  602                         OF_getencprop(child, "gpios", gpios, len);
  603 
  604                         e = (struct gpio_ctrl_entry *)&gpio_controllers;
  605 
  606                         /* Find and call a handler. */
  607                         for (; e->compat; e++) {
  608                                 /*
  609                                  * First cell of 'gpios' property should
  610                                  * contain a ref. to a node defining GPIO
  611                                  * controller.
  612                                  */
  613                                 ctrl = OF_node_from_xref(gpios[0]);
  614 
  615                                 if (fdt_is_compatible(ctrl, e->compat))
  616                                         /* Call a handler. */
  617                                         if ((rv = e->handler(ctrl,
  618                                             (pcell_t *)&gpios, len)))
  619                                                 return (rv);
  620                         }
  621                 }
  622 
  623                 if (OF_peer(child) == 0) {
  624                         /* No more siblings. */
  625                         child = parent;
  626                         parent = OF_parent(child);
  627                 }
  628         }
  629         return (0);
  630 }

Cache object: 7b7455c2fe423cd7c375c8b932652bde


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