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

Cache object: 06ba9070535eb8aab91dd67a6c6ede33


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