[BACK]Return to daadio.c CVS log [TXT][DIR] Up to [local] / sys / arch / sparc / dev

Annotation of sys/arch/sparc/dev/daadio.c, Revision 1.1

1.1     ! nbrk        1: /*     $OpenBSD: daadio.c,v 1.6 2004/09/29 07:35:11 miod Exp $ */
        !             2:
        !             3: /*
        !             4:  * Copyright (c) 1999 Jason L. Wright (jason@thought.net)
        !             5:  * All rights reserved.
        !             6:  *
        !             7:  * This software was developed by Jason L. Wright under contract with
        !             8:  * RTMX Incorporated (http://www.rtmx.com).
        !             9:  *
        !            10:  * Redistribution and use in source and binary forms, with or without
        !            11:  * modification, are permitted provided that the following conditions
        !            12:  * are met:
        !            13:  * 1. Redistributions of source code must retain the above copyright
        !            14:  *    notice, this list of conditions and the following disclaimer.
        !            15:  * 2. Redistributions in binary form must reproduce the above copyright
        !            16:  *    notice, this list of conditions and the following disclaimer in the
        !            17:  *    documentation and/or other materials provided with the distribution.
        !            18:  *
        !            19:  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
        !            20:  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
        !            21:  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
        !            22:  * DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT,
        !            23:  * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
        !            24:  * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
        !            25:  * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
        !            26:  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
        !            27:  * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
        !            28:  * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
        !            29:  * POSSIBILITY OF SUCH DAMAGE.
        !            30:  */
        !            31:
        !            32: /*
        !            33:  * Driver for the MATRIX Corporation MD-DAADIO digital->analog,
        !            34:  * analog->digial, parallel i/o VME board.
        !            35:  */
        !            36:
        !            37: #include <sys/param.h>
        !            38: #include <sys/systm.h>
        !            39: #include <sys/kernel.h>
        !            40: #include <sys/errno.h>
        !            41: #include <sys/ioctl.h>
        !            42: #include <sys/syslog.h>
        !            43: #include <sys/device.h>
        !            44: #include <sys/malloc.h>
        !            45: #include <sys/conf.h>
        !            46: #include <sys/fcntl.h>
        !            47: #include <sys/proc.h>
        !            48:
        !            49: #include <machine/autoconf.h>
        !            50: #include <sparc/cpu.h>
        !            51: #include <sparc/sparc/cpuvar.h>
        !            52: #include <sparc/dev/sbusvar.h>
        !            53: #include <sparc/dev/dmareg.h>  /* for SBUS_BURST_* */
        !            54: #include <machine/daadioio.h>
        !            55:
        !            56: #include <sparc/dev/fgareg.h>
        !            57: #include <sparc/dev/fgavar.h>
        !            58: #include <sparc/dev/daadioreg.h>
        !            59:
        !            60: int    daadiomatch(struct device *, void *, void *);
        !            61: void   daadioattach(struct device *, struct device *, void *);
        !            62: int    daadiointr(void *);
        !            63:
        !            64: struct daadio_softc {
        !            65:        struct          device sc_dv;           /* base device */
        !            66:        struct          daadioregs *sc_regs;    /* registers */
        !            67:        struct          intrhand sc_ih;         /* interrupt vectoring */
        !            68:        struct          daadio_adc *sc_adc_p;
        !            69:        int             sc_adc_done;
        !            70:        int             sc_flags;               /* flags */
        !            71: #define        DAF_LOCKED      0x1
        !            72: #define        DAF_WANTED      0x2
        !            73:        u_int16_t       sc_adc_val;
        !            74:        u_int8_t        sc_ier;                 /* software copy of ier */
        !            75: };
        !            76:
        !            77: struct cfattach daadio_ca = {
        !            78:        sizeof (struct daadio_softc), daadiomatch, daadioattach
        !            79: };
        !            80:
        !            81: struct cfdriver daadio_cd = {
        !            82:        NULL, "daadio", DV_DULL
        !            83: };
        !            84:
        !            85: void   daadio_ier_setbit(struct daadio_softc *, u_int8_t);
        !            86: void   daadio_ier_clearbit(struct daadio_softc *, u_int8_t);
        !            87: int    daadio_adc(struct daadio_softc *, struct daadio_adc *);
        !            88:
        !            89: int    daadioopen(dev_t, int, int, struct proc *);
        !            90: int    daadioclose(dev_t, int, int, struct proc *);
        !            91: int    daadioioctl(dev_t, u_long, caddr_t, int, struct proc *);
        !            92:
        !            93: int
        !            94: daadiomatch(parent, vcf, aux)
        !            95:        struct device *parent;
        !            96:        void *vcf, *aux;
        !            97: {
        !            98:        struct cfdata *cf = vcf;
        !            99:        struct confargs *ca = aux;
        !           100:        struct daadioregs *regs;
        !           101:
        !           102:        if (ca->ca_bustype != BUS_FGA_A16D16)
        !           103:                return (0);
        !           104:
        !           105:        if (strcmp(ca->ca_ra.ra_name, cf->cf_driver->cd_name))
        !           106:                return (0);
        !           107:
        !           108:        if (ca->ca_ra.ra_reg[0].rr_len < sizeof(struct daadioboard))
        !           109:                return (0);
        !           110:
        !           111:        regs = ca->ca_ra.ra_reg[0].rr_paddr;
        !           112:        if (probeget((caddr_t)&regs->sid, 1) != -1)
        !           113:                return (1);
        !           114:
        !           115:        return (0);
        !           116: }
        !           117:
        !           118: void
        !           119: daadioattach(parent, self, aux)
        !           120:        struct device *parent, *self;
        !           121:        void *aux;
        !           122: {
        !           123:        struct confargs *ca = aux;
        !           124:        struct daadio_softc *sc = (struct daadio_softc *)self;
        !           125:
        !           126:        sc->sc_regs = mapiodev(&(ca->ca_ra.ra_reg[0]), 0,
        !           127:            sizeof(struct daadioboard));
        !           128:
        !           129:        sc->sc_regs->pio_pattern = sc->sc_regs->pio_porta;
        !           130:        sc->sc_regs->sid = ca->ca_ra.ra_intr[0].int_vec;
        !           131:        sc->sc_regs->gvrilr &= ~ILR_IRQ_MASK;
        !           132:        sc->sc_regs->gvrilr |= (ca->ca_ra.ra_intr[0].int_pri << ILR_IRQ_SHIFT)
        !           133:            & ILR_IRQ_MASK;
        !           134:        sc->sc_ih.ih_fun = daadiointr;
        !           135:        sc->sc_ih.ih_arg = sc;
        !           136:        fvmeintrestablish(parent, ca->ca_ra.ra_intr[0].int_vec,
        !           137:            ca->ca_ra.ra_intr[0].int_pri, &sc->sc_ih, self->dv_xname);
        !           138:        daadio_ier_setbit(sc, IER_PIOEVENT);
        !           139:        daadio_ier_setbit(sc, IER_CONVERSION);
        !           140:
        !           141:        printf(": level %d vec 0x%x\n",
        !           142:            ca->ca_ra.ra_intr[0].int_pri, ca->ca_ra.ra_intr[0].int_vec);
        !           143: }
        !           144:
        !           145: int
        !           146: daadiointr(vsc)
        !           147:        void *vsc;
        !           148: {
        !           149:        struct daadio_softc *sc = vsc;
        !           150:        struct daadioregs *regs = sc->sc_regs;
        !           151:        u_int8_t val, isr;
        !           152:        int r = 0;
        !           153:
        !           154:        isr = regs->isr;
        !           155:
        !           156:        if (isr & ISR_PIOEVENT) {
        !           157:                val = regs->pio_porta;
        !           158:                printf("pio value: %x\n", val);
        !           159:                r = 1;
        !           160:                regs->pio_pattern = val;
        !           161:        }
        !           162:
        !           163:        if (isr & ISR_CONVERSION) {
        !           164:                r = 1;
        !           165:                sc->sc_adc_val = sc->sc_regs->adc12bit[0];
        !           166:                sc->sc_adc_done = 1;
        !           167:                if (sc->sc_adc_p != NULL)
        !           168:                        wakeup(sc->sc_adc_p);
        !           169:        }
        !           170:
        !           171:        return (r);
        !           172: }
        !           173:
        !           174: void
        !           175: daadio_ier_setbit(sc, v)
        !           176:        struct daadio_softc *sc;
        !           177:        u_int8_t v;
        !           178: {
        !           179:        sc->sc_ier |= v;
        !           180:        sc->sc_regs->ier = sc->sc_ier;
        !           181: }
        !           182:
        !           183: void
        !           184: daadio_ier_clearbit(sc, v)
        !           185:        struct daadio_softc *sc;
        !           186:        u_int8_t v;
        !           187: {
        !           188:        sc->sc_ier &= ~v;
        !           189:        sc->sc_regs->ier = sc->sc_ier;
        !           190: }
        !           191:
        !           192: #define        DAADIO_CARD(d)  ((minor(d) >> 6) & 3)
        !           193:
        !           194: int
        !           195: daadioopen(dev, flags, mode, p)
        !           196:        dev_t dev;
        !           197:        int flags, mode;
        !           198:        struct proc *p;
        !           199: {
        !           200:        struct daadio_softc *sc;
        !           201:        int card = DAADIO_CARD(dev);
        !           202:
        !           203:        if (card >= daadio_cd.cd_ndevs)
        !           204:                return (ENXIO);
        !           205:        sc = daadio_cd.cd_devs[card];
        !           206:        if (sc == NULL)
        !           207:                return (ENXIO);
        !           208:        return (0);
        !           209: }
        !           210:
        !           211: int
        !           212: daadioclose(dev, flags, mode, p)
        !           213:        dev_t dev;
        !           214:        int flags, mode;
        !           215:        struct proc *p;
        !           216: {
        !           217:        return (0);
        !           218: }
        !           219:
        !           220: int
        !           221: daadioioctl(dev, cmd, data, flags, p)
        !           222:        dev_t dev;
        !           223:        u_long cmd;
        !           224:        caddr_t data;
        !           225:        int flags;
        !           226:        struct proc *p;
        !           227: {
        !           228:        struct daadio_softc *sc = daadio_cd.cd_devs[DAADIO_CARD(dev)];
        !           229:        struct daadio_adc *adc = (struct daadio_adc *)data;
        !           230:        struct daadio_dac *dac = (struct daadio_dac *)data;
        !           231:        struct daadio_pio *pio = (struct daadio_pio *)data;
        !           232:        int error = 0;
        !           233:        u_int8_t reg, val;
        !           234:
        !           235:        switch (cmd) {
        !           236:        case DIOGADC:
        !           237:                error = daadio_adc(sc, adc);
        !           238:                break;
        !           239:        case DIOGPIO:
        !           240:                switch (pio->dap_reg) {
        !           241:                case 0:
        !           242:                        pio->dap_val = sc->sc_regs->pio_porta;
        !           243:                        break;
        !           244:                case 1:
        !           245:                        pio->dap_val = sc->sc_regs->pio_portb;
        !           246:                        break;
        !           247:                case 2:
        !           248:                        pio->dap_val = sc->sc_regs->pio_portc;
        !           249:                        break;
        !           250:                case 3:
        !           251:                        pio->dap_val = sc->sc_regs->pio_portd;
        !           252:                        break;
        !           253:                case 4:
        !           254:                        pio->dap_val = sc->sc_regs->pio_porte;
        !           255:                        break;
        !           256:                case 5:
        !           257:                        pio->dap_val = sc->sc_regs->pio_portf;
        !           258:                        break;
        !           259:                default:
        !           260:                        error = EINVAL;
        !           261:                        break;
        !           262:                }
        !           263:                break;
        !           264:        case DIOSPIO:
        !           265:                if ((flags & FWRITE) == 0) {
        !           266:                        error = EPERM;
        !           267:                        break;
        !           268:                }
        !           269:                switch (pio->dap_reg) {
        !           270:                case 0:
        !           271:                        sc->sc_regs->pio_porta = pio->dap_val;
        !           272:                        break;
        !           273:                case 1:
        !           274:                        sc->sc_regs->pio_portb = pio->dap_val;
        !           275:                        break;
        !           276:                case 2:
        !           277:                        sc->sc_regs->pio_portc = pio->dap_val;
        !           278:                        break;
        !           279:                case 3:
        !           280:                        sc->sc_regs->pio_portd = pio->dap_val;
        !           281:                        break;
        !           282:                case 4:
        !           283:                        sc->sc_regs->pio_porte = pio->dap_val;
        !           284:                        break;
        !           285:                case 5:
        !           286:                        sc->sc_regs->pio_portf = pio->dap_val;
        !           287:                        break;
        !           288:                default:
        !           289:                        error = EINVAL;
        !           290:                        break;
        !           291:                }
        !           292:                break;
        !           293:        case DIOSOPIO:
        !           294:                if ((flags & FWRITE) == 0) {
        !           295:                        error = EPERM;
        !           296:                        break;
        !           297:                }
        !           298:                if (pio->dap_reg >= 6) {
        !           299:                        error = EINVAL;
        !           300:                        break;
        !           301:                }
        !           302:
        !           303:                reg = sc->sc_regs->pio_oc;
        !           304:                val = (1 << pio->dap_reg);
        !           305:
        !           306:                if (pio->dap_val)
        !           307:                        reg |= val;
        !           308:                else
        !           309:                        reg &= ~val;
        !           310:
        !           311:                sc->sc_regs->pio_oc = reg;
        !           312:                break;
        !           313:        case DIOGOPIO:
        !           314:                if (pio->dap_reg >= 6) {
        !           315:                        error = EINVAL;
        !           316:                        break;
        !           317:                }
        !           318:
        !           319:                reg = sc->sc_regs->pio_oc;
        !           320:                val = (1 << pio->dap_reg);
        !           321:
        !           322:                if ((reg & val) != 0)
        !           323:                        pio->dap_val = 1;
        !           324:                else
        !           325:                        pio->dap_val = 0;
        !           326:                break;
        !           327:        case DIOSDAC:
        !           328:                if ((flags & FWRITE) == 0) {
        !           329:                        error = EPERM;
        !           330:                        break;
        !           331:                }
        !           332:                if (dac->dac_reg >= 8) {
        !           333:                        error = EINVAL;
        !           334:                        break;
        !           335:                }
        !           336:                sc->sc_regs->dac_channel[dac->dac_reg] = dac->dac_val;
        !           337:                break;
        !           338:        default:
        !           339:                error = ENOTTY;
        !           340:        }
        !           341:
        !           342:        return (error);
        !           343: }
        !           344:
        !           345: int
        !           346: daadio_adc(sc, adc)
        !           347:        struct daadio_softc *sc;
        !           348:        struct daadio_adc *adc;
        !           349: {
        !           350:        int s, err = 0;
        !           351:
        !           352:        if (adc->dad_reg >= 32)
        !           353:                return (EINVAL);
        !           354:
        !           355:        s = splhigh();
        !           356:
        !           357:        /* Lock device. */
        !           358:        while ((sc->sc_flags & DAF_LOCKED) != 0) {
        !           359:                sc->sc_flags |= DAF_WANTED;
        !           360:                if ((err = tsleep(sc, PWAIT, "daadio", 0)) != 0)
        !           361:                        goto out;
        !           362:        }
        !           363:        sc->sc_flags |= DAF_LOCKED;
        !           364:
        !           365:        /* Start conversion. */
        !           366:        sc->sc_adc_done = 0;
        !           367:        sc->sc_adc_p = adc;
        !           368:        sc->sc_regs->adc12bit[adc->dad_reg] = 0;
        !           369:
        !           370:        /* Wait for conversion. */
        !           371:        while (sc->sc_adc_done == 0)
        !           372:                if ((err = tsleep(sc->sc_adc_p, PWAIT, "daadio", 0)) != 0)
        !           373:                        goto out;
        !           374:        sc->sc_adc_p = NULL;
        !           375:        adc->dad_val = sc->sc_adc_val;
        !           376:
        !           377:        /* Unlock device. */
        !           378:        sc->sc_flags &= ~DAF_LOCKED;
        !           379:        if (sc->sc_flags & DAF_WANTED) {
        !           380:                sc->sc_flags &= ~DAF_WANTED;
        !           381:                wakeup(sc);
        !           382:        }
        !           383:
        !           384: out:
        !           385:        splx(s);
        !           386:        return (err);
        !           387: }

CVSweb