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