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

Cache object: 786b3471f291c39fd8f589ab380f86c9


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