[BACK]Return to gpioow.c CVS log [TXT][DIR] Up to [local] / sys / dev / gpio

Annotation of sys/dev/gpio/gpioow.c, Revision 1.1.1.1

1.1       nbrk        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: }

CVSweb