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

Annotation of sys/dev/isa/mpu401.c, Revision 1.1.1.1

1.1       nbrk        1: /*     $OpenBSD: mpu401.c,v 1.10 2006/04/07 22:41:33 jsg Exp $ */
                      2: /*     $NetBSD: mpu401.c,v 1.3 1998/11/25 22:17:06 augustss Exp $      */
                      3:
                      4: /*
                      5:  * Copyright (c) 1998 The NetBSD Foundation, Inc.
                      6:  * All rights reserved.
                      7:  *
                      8:  * This code is derived from software contributed to The NetBSD Foundation
                      9:  * by Lennart Augustsson (augustss@netbsd.org).
                     10:  *
                     11:  * Redistribution and use in source and binary forms, with or without
                     12:  * modification, are permitted provided that the following conditions
                     13:  * are met:
                     14:  * 1. Redistributions of source code must retain the above copyright
                     15:  *    notice, this list of conditions and the following disclaimer.
                     16:  * 2. Redistributions in binary form must reproduce the above copyright
                     17:  *    notice, this list of conditions and the following disclaimer in the
                     18:  *    documentation and/or other materials provided with the distribution.
                     19:  * 3. All advertising materials mentioning features or use of this software
                     20:  *    must display the following acknowledgement:
                     21:  *        This product includes software developed by the NetBSD
                     22:  *        Foundation, Inc. and its contributors.
                     23:  * 4. Neither the name of The NetBSD Foundation nor the names of its
                     24:  *    contributors may be used to endorse or promote products derived
                     25:  *    from this software without specific prior written permission.
                     26:  *
                     27:  * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
                     28:  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
                     29:  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
                     30:  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
                     31:  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
                     32:  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
                     33:  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
                     34:  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
                     35:  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
                     36:  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
                     37:  * POSSIBILITY OF SUCH DAMAGE.
                     38:  */
                     39:
                     40: #include <sys/param.h>
                     41: #include <sys/systm.h>
                     42: #include <sys/errno.h>
                     43: #include <sys/ioctl.h>
                     44: #include <sys/syslog.h>
                     45: #include <sys/device.h>
                     46: #include <sys/proc.h>
                     47: #include <sys/buf.h>
                     48:
                     49: #include <machine/cpu.h>
                     50: #include <machine/intr.h>
                     51: #include <machine/bus.h>
                     52:
                     53: #include <dev/midi_if.h>
                     54:
                     55: #include <dev/isa/isavar.h>
                     56: #include <dev/isa/isadmavar.h>
                     57:
                     58: #include <dev/ic/mpuvar.h>
                     59:
                     60: #ifndef splaudio
                     61: #define splaudio() splbio()    /* XXX found in audio_if.h normally */
                     62: #endif
                     63:
                     64: #ifdef AUDIO_DEBUG
                     65: #define DPRINTF(x)     if (mpu401debug) printf x
                     66: #define DPRINTFN(n,x)  if (mpu401debug >= (n)) printf x
                     67: int    mpu401debug = 0;
                     68: #else
                     69: #define DPRINTF(x)
                     70: #define DPRINTFN(n,x)
                     71: #endif
                     72:
                     73: #define MPU_GETSTATUS(iot, ioh) (bus_space_read_1(iot, ioh, MPU_STATUS))
                     74:
                     75: int    mpu_reset(struct mpu_softc *);
                     76: static __inline int mpu_waitready(struct mpu_softc *);
                     77: void   mpu_readinput(struct mpu_softc *);
                     78:
                     79: struct cfdriver mpu_cd = {
                     80:        NULL, "mpu", DV_DULL
                     81: };
                     82:
                     83: struct midi_hw_if mpu_midi_hw_if = {
                     84:        mpu_open,
                     85:        mpu_close,
                     86:        mpu_output,
                     87:        0,                      /* flush */
                     88:        mpu_getinfo,
                     89:        0,                      /* ioctl */
                     90: };
                     91:
                     92: int
                     93: mpu_find(v)
                     94:        void *v;
                     95: {
                     96:        struct mpu_softc *sc = v;
                     97:
                     98:        if (MPU_GETSTATUS(sc->iot, sc->ioh) == 0xff) {
                     99:                DPRINTF(("mpu_find: No status\n"));
                    100:                goto bad;
                    101:        }
                    102:        sc->open = 0;
                    103:        sc->intr = 0;
                    104:        if (mpu_reset(sc) == 0)
                    105:                return 1;
                    106: bad:
                    107:        return 0;
                    108: }
                    109:
                    110: static __inline int
                    111: mpu_waitready(sc)
                    112:        struct mpu_softc *sc;
                    113: {
                    114:        int i;
                    115:
                    116:        for(i = 0; i < MPU_MAXWAIT; i++) {
                    117:                if (!(MPU_GETSTATUS(sc->iot, sc->ioh) & MPU_OUTPUT_BUSY))
                    118:                        return 0;
                    119:                delay(10);
                    120:        }
                    121:        return 1;
                    122: }
                    123:
                    124: int
                    125: mpu_reset(sc)
                    126:        struct mpu_softc *sc;
                    127: {
                    128:        bus_space_tag_t iot = sc->iot;
                    129:        bus_space_handle_t ioh = sc->ioh;
                    130:        int i;
                    131:        int s;
                    132:
                    133:        if (mpu_waitready(sc)) {
                    134:                DPRINTF(("mpu_reset: not ready\n"));
                    135:                return EIO;
                    136:        }
                    137:        s = splaudio();         /* Don't let the interrupt get our ACK. */
                    138:        bus_space_write_1(iot, ioh, MPU_COMMAND, MPU_RESET);
                    139:        for(i = 0; i < 2*MPU_MAXWAIT; i++) {
                    140:                if (!(MPU_GETSTATUS(iot, ioh) & MPU_INPUT_EMPTY) &&
                    141:                    bus_space_read_1(iot, ioh, MPU_DATA) == MPU_ACK) {
                    142:                        splx(s);
                    143:                        return 0;
                    144:                }
                    145:        }
                    146:        splx(s);
                    147:        DPRINTF(("mpu_reset: No ACK\n"));
                    148:        return EIO;
                    149: }
                    150:
                    151: int
                    152: mpu_open(v, flags, iintr, ointr, arg)
                    153:        void *v;
                    154:        int flags;
                    155:        void (*iintr)(void *, int);
                    156:        void (*ointr)(void *);
                    157:        void *arg;
                    158: {
                    159:        struct mpu_softc *sc = v;
                    160:
                    161:         DPRINTF(("mpu_open: sc=%p\n", sc));
                    162:
                    163:        if (sc->open)
                    164:                return EBUSY;
                    165:        if (mpu_reset(sc) != 0)
                    166:                return EIO;
                    167:
                    168:        bus_space_write_1(sc->iot, sc->ioh, MPU_COMMAND, MPU_UART_MODE);
                    169:        sc->open = 1;
                    170:        sc->intr = iintr;
                    171:        sc->arg = arg;
                    172:        return 0;
                    173: }
                    174:
                    175: void
                    176: mpu_close(v)
                    177:        void *v;
                    178: {
                    179:        struct mpu_softc *sc = v;
                    180:
                    181:         DPRINTF(("mpu_close: sc=%p\n", sc));
                    182:
                    183:        sc->open = 0;
                    184:        sc->intr = 0;
                    185:        mpu_reset(sc); /* exit UART mode */
                    186: }
                    187:
                    188: void
                    189: mpu_readinput(sc)
                    190:        struct mpu_softc *sc;
                    191: {
                    192:        bus_space_tag_t iot = sc->iot;
                    193:        bus_space_handle_t ioh = sc->ioh;
                    194:        int data;
                    195:
                    196:        while(!(MPU_GETSTATUS(iot, ioh) & MPU_INPUT_EMPTY)) {
                    197:                data = bus_space_read_1(iot, ioh, MPU_DATA);
                    198:                DPRINTFN(3, ("mpu_rea: sc=%p 0x%02x\n", sc, data));
                    199:                if (sc->intr)
                    200:                        sc->intr(sc->arg, data);
                    201:        }
                    202: }
                    203:
                    204: int
                    205: mpu_output(v, d)
                    206:        void *v;
                    207:        int d;
                    208: {
                    209:        struct mpu_softc *sc = v;
                    210:        int s;
                    211:
                    212:        DPRINTFN(3, ("mpu_output: sc=%p 0x%02x\n", sc, d));
                    213:        if (!(MPU_GETSTATUS(sc->iot, sc->ioh) & MPU_INPUT_EMPTY)) {
                    214:                s = splaudio();
                    215:                mpu_readinput(sc);
                    216:                splx(s);
                    217:        }
                    218:        if (mpu_waitready(sc)) {
                    219:                DPRINTF(("mpu_output: not ready\n"));
                    220:                return EIO;
                    221:        }
                    222:        bus_space_write_1(sc->iot, sc->ioh, MPU_DATA, d);
                    223:        return 0;
                    224: }
                    225:
                    226: void
                    227: mpu_getinfo(addr, mi)
                    228:        void *addr;
                    229:        struct midi_info *mi;
                    230: {
                    231:        mi->name = "MPU-401 MIDI UART";
                    232:        mi->props = 0;
                    233: }
                    234:
                    235: int
                    236: mpu_intr(v)
                    237:        void *v;
                    238: {
                    239:        struct mpu_softc *sc = v;
                    240:
                    241:        if (MPU_GETSTATUS(sc->iot, sc->ioh) & MPU_INPUT_EMPTY) {
                    242:                DPRINTF(("mpu_intr: no data\n"));
                    243:                return 0;
                    244:        }
                    245:        mpu_readinput(sc);
                    246:        return 1;
                    247: }

CVSweb