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/10.2/sys/arm/rockchip/rk30xx_gpio.c 278786 2015-02-14 21:16:19Z loos $");
   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/cpu.h>
   45 #include <machine/cpufunc.h>
   46 #include <machine/resource.h>
   47 #include <machine/fdt.h>
   48 #include <machine/intr.h>
   49 
   50 #include <dev/fdt/fdt_common.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          128
   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 #define RK30_GPIO_INPUT                 0
   75 #define RK30_GPIO_OUTPUT                1
   76 
   77 struct rk30_gpio_softc {
   78         device_t                sc_dev;
   79         struct mtx              sc_mtx;
   80         struct resource *       sc_mem_res;
   81         struct resource *       sc_irq_res;
   82         bus_space_tag_t         sc_bst;
   83         bus_space_handle_t      sc_bsh;
   84         void *                  sc_intrhand;
   85         int                     sc_gpio_npins;
   86         struct gpio_pin         sc_gpio_pins[RK30_GPIO_PINS];
   87 };
   88 
   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_PORTS_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         uint32_t bank, func, offset;
  135 
  136         bank = pin / 32;
  137         pin = pin % 32;
  138         offset = 1 << pin;
  139 
  140         func = RK30_GPIO_READ(sc, RK30_GPIO_SWPORT_DDR);
  141         func &= offset;
  142 
  143         return (func);
  144 }
  145 
  146 static uint32_t
  147 rk30_gpio_func_flag(uint32_t nfunc)
  148 {
  149 
  150         switch (nfunc) {
  151         case RK30_GPIO_INPUT:
  152                 return (GPIO_PIN_INPUT);
  153         case RK30_GPIO_OUTPUT:
  154                 return (GPIO_PIN_OUTPUT);
  155         }
  156         return (0);
  157 }
  158 
  159 static void
  160 rk30_gpio_set_function(struct rk30_gpio_softc *sc, uint32_t pin, uint32_t f)
  161 {
  162         uint32_t bank, data, offset;
  163 
  164         /* Must be called with lock held. */
  165         RK30_GPIO_LOCK_ASSERT(sc);
  166 
  167         bank = pin / 32;
  168         pin = pin % 32;
  169         offset = 1 << pin;
  170 
  171         data = RK30_GPIO_READ(sc, RK30_GPIO_SWPORT_DDR);
  172         if (f)
  173                 data |= offset;
  174         else
  175                 data &= ~offset;
  176         RK30_GPIO_WRITE(sc, RK30_GPIO_SWPORT_DDR, data);
  177 }
  178 
  179 static void
  180 rk30_gpio_set_pud(struct rk30_gpio_softc *sc, uint32_t pin, uint32_t state)
  181 {
  182         uint32_t bank;
  183 
  184         bank = pin / 32;
  185 
  186         /* Must be called with lock held. */
  187         RK30_GPIO_LOCK_ASSERT(sc);
  188 
  189         if (bank == 0 && pin < 12)
  190                 rk30_pmu_gpio_pud(pin, state);
  191         else
  192                 rk30_grf_gpio_pud(bank, pin, state);
  193 }
  194 
  195 static void
  196 rk30_gpio_pin_configure(struct rk30_gpio_softc *sc, struct gpio_pin *pin,
  197     unsigned int flags)
  198 {
  199 
  200         RK30_GPIO_LOCK(sc);
  201 
  202         /*
  203          * Manage input/output.
  204          */
  205         if (flags & (GPIO_PIN_INPUT|GPIO_PIN_OUTPUT)) {
  206                 pin->gp_flags &= ~(GPIO_PIN_INPUT|GPIO_PIN_OUTPUT);
  207                 if (flags & GPIO_PIN_OUTPUT) {
  208                         pin->gp_flags |= GPIO_PIN_OUTPUT;
  209                         rk30_gpio_set_function(sc, pin->gp_pin,
  210                             RK30_GPIO_OUTPUT);
  211                 } else {
  212                         pin->gp_flags |= GPIO_PIN_INPUT;
  213                         rk30_gpio_set_function(sc, pin->gp_pin,
  214                             RK30_GPIO_INPUT);
  215                 }
  216         }
  217 
  218         /* Manage Pull-up/pull-down. */
  219         pin->gp_flags &= ~(GPIO_PIN_PULLUP|GPIO_PIN_PULLDOWN);
  220         if (flags & (GPIO_PIN_PULLUP|GPIO_PIN_PULLDOWN)) {
  221                 if (flags & GPIO_PIN_PULLUP) {
  222                         pin->gp_flags |= GPIO_PIN_PULLUP;
  223                         rk30_gpio_set_pud(sc, pin->gp_pin, 
  224                             RK30_GPIO_PULLUP);
  225                 } else {
  226                         pin->gp_flags |= GPIO_PIN_PULLDOWN;
  227                         rk30_gpio_set_pud(sc, pin->gp_pin, 
  228                             RK30_GPIO_PULLDOWN);
  229                 }
  230         } else
  231                 rk30_gpio_set_pud(sc, pin->gp_pin, RK30_GPIO_NONE);
  232 
  233         RK30_GPIO_UNLOCK(sc);
  234 }
  235 
  236 static int
  237 rk30_gpio_pin_max(device_t dev, int *maxpin)
  238 {
  239 
  240         *maxpin = RK30_GPIO_PINS - 1;
  241         return (0);
  242 }
  243 
  244 static int
  245 rk30_gpio_pin_getcaps(device_t dev, uint32_t pin, uint32_t *caps)
  246 {
  247         struct rk30_gpio_softc *sc = device_get_softc(dev);
  248         int i;
  249 
  250         for (i = 0; i < sc->sc_gpio_npins; i++) {
  251                 if (sc->sc_gpio_pins[i].gp_pin == pin)
  252                         break;
  253         }
  254 
  255         if (i >= sc->sc_gpio_npins)
  256                 return (EINVAL);
  257 
  258         RK30_GPIO_LOCK(sc);
  259         *caps = sc->sc_gpio_pins[i].gp_caps;
  260         RK30_GPIO_UNLOCK(sc);
  261 
  262         return (0);
  263 }
  264 
  265 static int
  266 rk30_gpio_pin_getflags(device_t dev, uint32_t pin, uint32_t *flags)
  267 {
  268         struct rk30_gpio_softc *sc = device_get_softc(dev);
  269         int i;
  270 
  271         for (i = 0; i < sc->sc_gpio_npins; i++) {
  272                 if (sc->sc_gpio_pins[i].gp_pin == pin)
  273                         break;
  274         }
  275 
  276         if (i >= sc->sc_gpio_npins)
  277                 return (EINVAL);
  278 
  279         RK30_GPIO_LOCK(sc);
  280         *flags = sc->sc_gpio_pins[i].gp_flags;
  281         RK30_GPIO_UNLOCK(sc);
  282 
  283         return (0);
  284 }
  285 
  286 static int
  287 rk30_gpio_pin_getname(device_t dev, uint32_t pin, char *name)
  288 {
  289         struct rk30_gpio_softc *sc = device_get_softc(dev);
  290         int i;
  291 
  292         for (i = 0; i < sc->sc_gpio_npins; i++) {
  293                 if (sc->sc_gpio_pins[i].gp_pin == pin)
  294                         break;
  295         }
  296 
  297         if (i >= sc->sc_gpio_npins)
  298                 return (EINVAL);
  299 
  300         RK30_GPIO_LOCK(sc);
  301         memcpy(name, sc->sc_gpio_pins[i].gp_name, GPIOMAXNAME);
  302         RK30_GPIO_UNLOCK(sc);
  303 
  304         return (0);
  305 }
  306 
  307 static int
  308 rk30_gpio_pin_setflags(device_t dev, uint32_t pin, uint32_t flags)
  309 {
  310         struct rk30_gpio_softc *sc = device_get_softc(dev);
  311         int i;
  312 
  313         for (i = 0; i < sc->sc_gpio_npins; i++) {
  314                 if (sc->sc_gpio_pins[i].gp_pin == pin)
  315                         break;
  316         }
  317 
  318         if (i >= sc->sc_gpio_npins)
  319                 return (EINVAL);
  320 
  321         rk30_gpio_pin_configure(sc, &sc->sc_gpio_pins[i], flags);
  322 
  323         return (0);
  324 }
  325 
  326 static int
  327 rk30_gpio_pin_set(device_t dev, uint32_t pin, unsigned int value)
  328 {
  329         struct rk30_gpio_softc *sc = device_get_softc(dev);
  330         uint32_t bank, offset, data;
  331         int i;
  332 
  333         for (i = 0; i < sc->sc_gpio_npins; i++) {
  334                 if (sc->sc_gpio_pins[i].gp_pin == pin)
  335                         break;
  336         }
  337 
  338         if (i >= sc->sc_gpio_npins)
  339                 return (EINVAL);
  340 
  341         bank = pin / 32;
  342         pin = pin % 32;
  343         offset = 1 << pin;
  344 
  345         RK30_GPIO_LOCK(sc);
  346         data = RK30_GPIO_READ(sc, RK30_GPIO_SWPORT_DDR);
  347         data |= offset;
  348         RK30_GPIO_WRITE(sc, RK30_GPIO_SWPORT_DDR, data);
  349 
  350         data = RK30_GPIO_READ(sc, RK30_GPIO_SWPORT_DR);
  351         if (value)
  352                 data |= offset;
  353         else
  354                 data &= ~offset;
  355         RK30_GPIO_WRITE(sc, RK30_GPIO_SWPORT_DR, data);
  356         RK30_GPIO_UNLOCK(sc);
  357 
  358         return (0);
  359 }
  360 
  361 static int
  362 rk30_gpio_pin_get(device_t dev, uint32_t pin, unsigned int *val)
  363 {
  364         struct rk30_gpio_softc *sc = device_get_softc(dev);
  365         uint32_t bank, offset, reg_data;
  366         int i;
  367 
  368         for (i = 0; i < sc->sc_gpio_npins; i++) {
  369                 if (sc->sc_gpio_pins[i].gp_pin == pin)
  370                         break;
  371         }
  372 
  373         if (i >= sc->sc_gpio_npins)
  374                 return (EINVAL);
  375 
  376         bank = pin / 32;
  377         pin = pin % 32;
  378         offset = 1 << pin;
  379 
  380         RK30_GPIO_LOCK(sc);
  381         reg_data = RK30_GPIO_READ(sc, RK30_GPIO_EXT_PORT);
  382         RK30_GPIO_UNLOCK(sc);
  383         *val = (reg_data & offset) ? 1 : 0;
  384 
  385         return (0);
  386 }
  387 
  388 static int
  389 rk30_gpio_pin_toggle(device_t dev, uint32_t pin)
  390 {
  391         struct rk30_gpio_softc *sc = device_get_softc(dev);
  392         uint32_t bank, data, offset;
  393         int i;
  394 
  395         for (i = 0; i < sc->sc_gpio_npins; i++) {
  396                 if (sc->sc_gpio_pins[i].gp_pin == pin)
  397                         break;
  398         }
  399 
  400         if (i >= sc->sc_gpio_npins)
  401                 return (EINVAL);
  402 
  403         bank = pin / 32;
  404         pin = pin % 32;
  405         offset = 1 << pin;
  406 
  407         RK30_GPIO_LOCK(sc);
  408         data = RK30_GPIO_READ(sc, RK30_GPIO_SWPORT_DDR);
  409         if (data & offset)
  410                 data &= ~offset;
  411         else
  412                 data |= offset;
  413         RK30_GPIO_WRITE(sc, RK30_GPIO_SWPORT_DDR, data);
  414 
  415         data = RK30_GPIO_READ(sc, RK30_GPIO_SWPORT_DR);
  416         if (data & offset)
  417                 data &= ~offset;
  418         else
  419                 data |= offset;
  420         RK30_GPIO_WRITE(sc, RK30_GPIO_SWPORT_DR, data);
  421         RK30_GPIO_UNLOCK(sc);
  422 
  423         return (0);
  424 }
  425 
  426 static int
  427 rk30_gpio_probe(device_t dev)
  428 {
  429 
  430         if (!ofw_bus_status_okay(dev))
  431                 return (ENXIO);
  432 
  433         if (!ofw_bus_is_compatible(dev, "rockchip,rk30xx-gpio"))
  434                 return (ENXIO);
  435 
  436         device_set_desc(dev, "Rockchip RK30XX GPIO controller");
  437         return (BUS_PROBE_DEFAULT);
  438 }
  439 
  440 static int
  441 rk30_gpio_attach(device_t dev)
  442 {
  443         struct rk30_gpio_softc *sc = device_get_softc(dev);
  444         uint32_t func;
  445         int i, rid;
  446         phandle_t gpio;
  447 
  448         if (rk30_gpio_sc)
  449                 return (ENXIO);
  450 
  451         sc->sc_dev = dev;
  452 
  453         mtx_init(&sc->sc_mtx, "rk30 gpio", "gpio", MTX_DEF);
  454 
  455         rid = 0;
  456         sc->sc_mem_res = bus_alloc_resource_any(dev, SYS_RES_MEMORY, &rid,
  457             RF_ACTIVE);
  458         if (!sc->sc_mem_res) {
  459                 device_printf(dev, "cannot allocate memory window\n");
  460                 return (ENXIO);
  461         }
  462 
  463         sc->sc_bst = rman_get_bustag(sc->sc_mem_res);
  464         sc->sc_bsh = rman_get_bushandle(sc->sc_mem_res);
  465 
  466         rid = 0;
  467         sc->sc_irq_res = bus_alloc_resource_any(dev, SYS_RES_IRQ, &rid,
  468             RF_ACTIVE);
  469         if (!sc->sc_irq_res) {
  470                 bus_release_resource(dev, SYS_RES_MEMORY, 0, sc->sc_mem_res);
  471                 device_printf(dev, "cannot allocate interrupt\n");
  472                 return (ENXIO);
  473         }
  474 
  475         /* Find our node. */
  476         gpio = ofw_bus_get_node(sc->sc_dev);
  477 
  478         if (!OF_hasprop(gpio, "gpio-controller"))
  479                 /* Node is not a GPIO controller. */
  480                 goto fail;
  481 
  482         /* Initialize the software controlled pins. */
  483         for (i = 0; i < RK30_GPIO_PINS; i++) {
  484                 snprintf(sc->sc_gpio_pins[i].gp_name, GPIOMAXNAME,
  485                     "pin %d", i);
  486                 func = rk30_gpio_get_function(sc, i);
  487                 sc->sc_gpio_pins[i].gp_pin = i;
  488                 sc->sc_gpio_pins[i].gp_caps = RK30_GPIO_DEFAULT_CAPS;
  489                 sc->sc_gpio_pins[i].gp_flags = rk30_gpio_func_flag(func);
  490         }
  491         sc->sc_gpio_npins = i;
  492 
  493         device_add_child(dev, "gpioc", -1);
  494         device_add_child(dev, "gpiobus", -1);
  495 
  496         rk30_gpio_sc = sc;
  497 
  498         rk30_gpio_init();
  499         
  500         return (bus_generic_attach(dev));
  501 
  502 fail:
  503         if (sc->sc_irq_res)
  504                 bus_release_resource(dev, SYS_RES_IRQ, 0, sc->sc_irq_res);
  505         if (sc->sc_mem_res)
  506                 bus_release_resource(dev, SYS_RES_MEMORY, 0, sc->sc_mem_res);
  507         return (ENXIO);
  508 }
  509 
  510 static int
  511 rk30_gpio_detach(device_t dev)
  512 {
  513 
  514         return (EBUSY);
  515 }
  516 
  517 static device_method_t rk30_gpio_methods[] = {
  518         /* Device interface */
  519         DEVMETHOD(device_probe,         rk30_gpio_probe),
  520         DEVMETHOD(device_attach,        rk30_gpio_attach),
  521         DEVMETHOD(device_detach,        rk30_gpio_detach),
  522 
  523         /* GPIO protocol */
  524         DEVMETHOD(gpio_pin_max,         rk30_gpio_pin_max),
  525         DEVMETHOD(gpio_pin_getname,     rk30_gpio_pin_getname),
  526         DEVMETHOD(gpio_pin_getflags,    rk30_gpio_pin_getflags),
  527         DEVMETHOD(gpio_pin_getcaps,     rk30_gpio_pin_getcaps),
  528         DEVMETHOD(gpio_pin_setflags,    rk30_gpio_pin_setflags),
  529         DEVMETHOD(gpio_pin_get,         rk30_gpio_pin_get),
  530         DEVMETHOD(gpio_pin_set,         rk30_gpio_pin_set),
  531         DEVMETHOD(gpio_pin_toggle,      rk30_gpio_pin_toggle),
  532 
  533         DEVMETHOD_END
  534 };
  535 
  536 static devclass_t rk30_gpio_devclass;
  537 
  538 static driver_t rk30_gpio_driver = {
  539         "gpio",
  540         rk30_gpio_methods,
  541         sizeof(struct rk30_gpio_softc),
  542 };
  543 
  544 DRIVER_MODULE(rk30_gpio, simplebus, rk30_gpio_driver, rk30_gpio_devclass, 0, 0);
  545 
  546 int
  547 rk30_gpios_prop_handle(phandle_t ctrl, pcell_t *gpios, int len)
  548 {
  549         struct rk30_gpio_softc *sc;
  550         pcell_t gpio_cells;
  551         int inc, t, tuples, tuple_size;
  552         int dir, flags, pin, i;
  553         u_long gpio_ctrl, size;
  554 
  555         sc = rk30_gpio_sc;
  556         if (sc == NULL)
  557                 return ENXIO;
  558 
  559         if (OF_getprop(ctrl, "#gpio-cells", &gpio_cells, sizeof(pcell_t)) < 0)
  560                 return (ENXIO);
  561 
  562         gpio_cells = fdt32_to_cpu(gpio_cells);
  563         if (gpio_cells != 2)
  564                 return (ENXIO);
  565 
  566         tuple_size = gpio_cells * sizeof(pcell_t) + sizeof(phandle_t);
  567         tuples = len / tuple_size;
  568 
  569         if (fdt_regsize(ctrl, &gpio_ctrl, &size))
  570                 return (ENXIO);
  571 
  572         /*
  573          * Skip controller reference, since controller's phandle is given
  574          * explicitly (in a function argument).
  575          */
  576         inc = sizeof(ihandle_t) / sizeof(pcell_t);
  577         gpios += inc;
  578         for (t = 0; t < tuples; t++) {
  579                 pin = fdt32_to_cpu(gpios[0]);
  580                 dir = fdt32_to_cpu(gpios[1]);
  581                 flags = fdt32_to_cpu(gpios[2]);
  582 
  583                 for (i = 0; i < sc->sc_gpio_npins; i++) {
  584                         if (sc->sc_gpio_pins[i].gp_pin == pin)
  585                                 break;
  586                 }
  587                 if (i >= sc->sc_gpio_npins)
  588                         return (EINVAL);
  589 
  590                 rk30_gpio_pin_configure(sc, &sc->sc_gpio_pins[i], flags);
  591 
  592                 if (dir == 1) {
  593                         /* Input. */
  594                         rk30_gpio_pin_set(sc->sc_dev, pin, RK30_GPIO_INPUT);
  595                 } else {
  596                         /* Output. */
  597                         rk30_gpio_pin_set(sc->sc_dev, pin, RK30_GPIO_OUTPUT);
  598                 }
  599                 gpios += gpio_cells + inc;
  600         }
  601 
  602         return (0);
  603 }
  604 
  605 #define MAX_PINS_PER_NODE       5
  606 #define GPIOS_PROP_CELLS        4
  607 
  608 static int
  609 rk30_gpio_init(void)
  610 {
  611         phandle_t child, parent, root, ctrl;
  612         pcell_t gpios[MAX_PINS_PER_NODE * GPIOS_PROP_CELLS];
  613         struct gpio_ctrl_entry *e;
  614         int len, rv;
  615 
  616         root = OF_finddevice("/");
  617         len = 0;
  618         parent = root;
  619 
  620         /* Traverse through entire tree to find nodes with 'gpios' prop */
  621         for (child = OF_child(parent); child != 0; child = OF_peer(child)) {
  622 
  623                 /* Find a 'leaf'. Start the search from this node. */
  624                 while (OF_child(child)) {
  625                         parent = child;
  626                         child = OF_child(child);
  627                 }
  628                 if ((len = OF_getproplen(child, "gpios")) > 0) {
  629 
  630                         if (len > sizeof(gpios))
  631                                 return (ENXIO);
  632 
  633                         /* Get 'gpios' property. */
  634                         OF_getprop(child, "gpios", &gpios, len);
  635 
  636                         e = (struct gpio_ctrl_entry *)&gpio_controllers;
  637 
  638                         /* Find and call a handler. */
  639                         for (; e->compat; e++) {
  640                                 /*
  641                                  * First cell of 'gpios' property should
  642                                  * contain a ref. to a node defining GPIO
  643                                  * controller.
  644                                  */
  645                                 ctrl = OF_node_from_xref(fdt32_to_cpu(gpios[0]));
  646 
  647                                 if (fdt_is_compatible(ctrl, e->compat))
  648                                         /* Call a handler. */
  649                                         if ((rv = e->handler(ctrl,
  650                                             (pcell_t *)&gpios, len)))
  651                                                 return (rv);
  652                         }
  653                 }
  654 
  655                 if (OF_peer(child) == 0) {
  656                         /* No more siblings. */
  657                         child = parent;
  658                         parent = OF_parent(child);
  659                 }
  660         }
  661         return (0);
  662 }

Cache object: a3bc7e2182bb86b28afca815c2cb2dbc


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