root/dev/gpio/gpioow.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. gpioow_match
  2. gpioow_attach
  3. gpioow_detach
  4. gpioow_activate
  5. gpioow_ow_reset
  6. gpioow_ow_bit
  7. gpioow_bb_rx
  8. gpioow_bb_tx
  9. gpioow_bb_get
  10. gpioow_bb_set

    1 /*      $OpenBSD: gpioow.c,v 1.2 2006/06/23 06:27:11 miod Exp $ */
    2 
    3 /*
    4  * Copyright (c) 2006 Alexander Yurchenko <grange@openbsd.org>
    5  *
    6  * Permission to use, copy, modify, and distribute this software for any
    7  * purpose with or without fee is hereby granted, provided that the above
    8  * copyright notice and this permission notice appear in all copies.
    9  *
   10  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
   11  * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
   12  * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
   13  * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
   14  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
   15  * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
   16  * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
   17  */
   18 
   19 /*
   20  * 1-Wire bus bit-banging through GPIO pin.
   21  */
   22 
   23 #include <sys/param.h>
   24 #include <sys/systm.h>
   25 #include <sys/device.h>
   26 #include <sys/gpio.h>
   27 
   28 #include <dev/gpio/gpiovar.h>
   29 
   30 #include <dev/onewire/onewirevar.h>
   31 
   32 #define GPIOOW_NPINS            1
   33 #define GPIOOW_PIN_DATA         0
   34 
   35 struct gpioow_softc {
   36         struct device           sc_dev;
   37 
   38         void *                  sc_gpio;
   39         struct gpio_pinmap      sc_map;
   40         int                     __map[GPIOOW_NPINS];
   41 
   42         struct onewire_bus      sc_ow_bus;
   43         struct device *         sc_ow_dev;
   44 
   45         int                     sc_data;
   46         int                     sc_dying;
   47 };
   48 
   49 int     gpioow_match(struct device *, void *, void *);
   50 void    gpioow_attach(struct device *, struct device *, void *);
   51 int     gpioow_detach(struct device *, int);
   52 int     gpioow_activate(struct device *, enum devact);
   53 
   54 int     gpioow_ow_reset(void *);
   55 int     gpioow_ow_bit(void *, int);
   56 
   57 void    gpioow_bb_rx(void *);
   58 void    gpioow_bb_tx(void *);
   59 int     gpioow_bb_get(void *);
   60 void    gpioow_bb_set(void *, int);
   61 
   62 struct cfattach gpioow_ca = {
   63         sizeof(struct gpioow_softc),
   64         gpioow_match,
   65         gpioow_attach,
   66         gpioow_detach,
   67         gpioow_activate
   68 };
   69 
   70 struct cfdriver gpioow_cd = {
   71         NULL, "gpioow", DV_DULL
   72 };
   73 
   74 static const struct onewire_bbops gpioow_bbops = {
   75         gpioow_bb_rx,
   76         gpioow_bb_tx,
   77         gpioow_bb_get,
   78         gpioow_bb_set
   79 };
   80 
   81 int
   82 gpioow_match(struct device *parent, void *match, void *aux)
   83 {
   84         struct cfdata *cf = match;
   85 
   86         return (strcmp(cf->cf_driver->cd_name, "gpioow") == 0);
   87 }
   88 
   89 void
   90 gpioow_attach(struct device *parent, struct device *self, void *aux)
   91 {
   92         struct gpioow_softc *sc = (struct gpioow_softc *)self;
   93         struct gpio_attach_args *ga = aux;
   94         struct onewirebus_attach_args oba;
   95         int caps;
   96 
   97         /* Check that we have enough pins */
   98         if (gpio_npins(ga->ga_mask) != GPIOOW_NPINS) {
   99                 printf(": invalid pin mask\n");
  100                 return;
  101         }
  102 
  103         /* Map pins */
  104         sc->sc_gpio = ga->ga_gpio;
  105         sc->sc_map.pm_map = sc->__map;
  106         if (gpio_pin_map(sc->sc_gpio, ga->ga_offset, ga->ga_mask,
  107             &sc->sc_map)) {
  108                 printf(": can't map pins\n");
  109                 return;
  110         }
  111 
  112         /* Configure data pin */
  113         caps = gpio_pin_caps(sc->sc_gpio, &sc->sc_map, GPIOOW_PIN_DATA);
  114         if (!(caps & GPIO_PIN_OUTPUT)) {
  115                 printf(": data pin is unable to drive output\n");
  116                 goto fail;
  117         }
  118         if (!(caps & GPIO_PIN_INPUT)) {
  119                 printf(": data pin is unable to read input\n");
  120                 goto fail;
  121         }
  122         printf(": DATA[%d]", sc->sc_map.pm_map[GPIOOW_PIN_DATA]);
  123         sc->sc_data = GPIO_PIN_OUTPUT;
  124         if (caps & GPIO_PIN_OPENDRAIN) {
  125                 printf(" open-drain");
  126                 sc->sc_data |= GPIO_PIN_OPENDRAIN;
  127         } else if ((caps & GPIO_PIN_PUSHPULL) && (caps & GPIO_PIN_TRISTATE)) {
  128                 printf(" push-pull tri-state");
  129                 sc->sc_data |= GPIO_PIN_PUSHPULL;
  130         }
  131         if (caps & GPIO_PIN_PULLUP) {
  132                 printf(" pull-up");
  133                 sc->sc_data |= GPIO_PIN_PULLUP;
  134         }
  135         gpio_pin_ctl(sc->sc_gpio, &sc->sc_map, GPIOOW_PIN_DATA, sc->sc_data);
  136 
  137         printf("\n");
  138 
  139         /* Attach 1-Wire bus */
  140         sc->sc_ow_bus.bus_cookie = sc;
  141         sc->sc_ow_bus.bus_reset = gpioow_ow_reset;
  142         sc->sc_ow_bus.bus_bit = gpioow_ow_bit;
  143 
  144         bzero(&oba, sizeof(oba));
  145         oba.oba_bus = &sc->sc_ow_bus;
  146         sc->sc_ow_dev = config_found(self, &oba, onewirebus_print);
  147 
  148         return;
  149 
  150 fail:
  151         gpio_pin_unmap(sc->sc_gpio, &sc->sc_map);
  152 }
  153 
  154 int
  155 gpioow_detach(struct device *self, int flags)
  156 {
  157         struct gpioow_softc *sc = (struct gpioow_softc *)self;
  158         int rv = 0;
  159 
  160         if (sc->sc_ow_dev != NULL)
  161                 rv = config_detach(sc->sc_ow_dev, flags);
  162 
  163         return (rv);
  164 }
  165 
  166 int
  167 gpioow_activate(struct device *self, enum devact act)
  168 {
  169         struct gpioow_softc *sc = (struct gpioow_softc *)self;
  170         int rv = 0;
  171 
  172         switch (act) {
  173         case DVACT_ACTIVATE:
  174                 break;
  175         case DVACT_DEACTIVATE:
  176                 sc->sc_dying = 1;
  177                 if (sc->sc_ow_dev != NULL)
  178                         rv = config_deactivate(sc->sc_ow_dev);
  179                 break;
  180         }
  181 
  182         return (rv);
  183 }
  184 
  185 int
  186 gpioow_ow_reset(void *arg)
  187 {
  188         return (onewire_bb_reset(&gpioow_bbops, arg));
  189 }
  190 
  191 int
  192 gpioow_ow_bit(void *arg, int value)
  193 {
  194         return (onewire_bb_bit(&gpioow_bbops, arg, value));
  195 }
  196 
  197 void
  198 gpioow_bb_rx(void *arg)
  199 {
  200         struct gpioow_softc *sc = arg;
  201         int data = sc->sc_data;
  202 
  203         data &= ~(GPIO_PIN_INPUT | GPIO_PIN_OUTPUT | GPIO_PIN_TRISTATE);
  204         data |= GPIO_PIN_INPUT;
  205         if (data & GPIO_PIN_PUSHPULL)
  206                 data |= GPIO_PIN_TRISTATE;
  207         if (sc->sc_data != data) {
  208                 sc->sc_data = data;
  209                 gpio_pin_ctl(sc->sc_gpio, &sc->sc_map, GPIOOW_PIN_DATA,
  210                     sc->sc_data);
  211         }
  212 }
  213 
  214 void
  215 gpioow_bb_tx(void *arg)
  216 {
  217         struct gpioow_softc *sc = arg;
  218         int data = sc->sc_data;
  219 
  220         data &= ~(GPIO_PIN_INPUT | GPIO_PIN_OUTPUT | GPIO_PIN_TRISTATE);
  221         data |= GPIO_PIN_OUTPUT;
  222         if (sc->sc_data != data) {
  223                 sc->sc_data = data;
  224                 gpio_pin_ctl(sc->sc_gpio, &sc->sc_map, GPIOOW_PIN_DATA,
  225                     sc->sc_data);
  226         }
  227 }
  228 
  229 int
  230 gpioow_bb_get(void *arg)
  231 {
  232         struct gpioow_softc *sc = arg;
  233 
  234         return (gpio_pin_read(sc->sc_gpio, &sc->sc_map, GPIOOW_PIN_DATA) ==
  235             GPIO_PIN_HIGH ? 1 : 0);
  236 }
  237 
  238 void
  239 gpioow_bb_set(void *arg, int value)
  240 {
  241         struct gpioow_softc *sc = arg;
  242 
  243         gpio_pin_write(sc->sc_gpio, &sc->sc_map, GPIOOW_PIN_DATA,
  244             value ? GPIO_PIN_HIGH : GPIO_PIN_LOW);
  245 }

/* [<][>][^][v][top][bottom][index][help] */