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

Annotation of sys/dev/isa/ym.c, Revision 1.1

1.1     ! nbrk        1: /* $OpenBSD: ym.c,v 1.13 2006/04/07 22:41:33 jsg Exp $ */
        !             2:
        !             3:
        !             4: /*
        !             5:  * Copyright (c) 1998 Constantine Sapuntzakis. All rights reserved.
        !             6:  *
        !             7:  * Redistribution and use in source and binary forms, with or without
        !             8:  * modification, are permitted provided that the following conditions
        !             9:  * are met:
        !            10:  * 1. Redistributions of source code must retain the above copyright
        !            11:  *    notice, this list of conditions and the following disclaimer.
        !            12:  * 2. Redistributions in binary form must reproduce the above copyright
        !            13:  *    notice, this list of conditions and the following disclaimer in the
        !            14:  *    documentation and/or other materials provided with the distribution.
        !            15:  * 3. The name of the author may not be used to endorse or promote products
        !            16:  *    derived from this software without specific prior written permission.
        !            17:  *
        !            18:  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
        !            19:  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
        !            20:  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
        !            21:  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
        !            22:  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
        !            23:  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
        !            24:  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
        !            25:  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
        !            26:  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
        !            27:  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
        !            28:  */
        !            29:
        !            30: #include "midi.h"
        !            31:
        !            32: #include <sys/param.h>
        !            33: #include <sys/systm.h>
        !            34: #include <sys/errno.h>
        !            35: #include <sys/ioctl.h>
        !            36: #include <sys/syslog.h>
        !            37: #include <sys/device.h>
        !            38: #include <sys/proc.h>
        !            39: #include <sys/buf.h>
        !            40:
        !            41: #include <machine/cpu.h>
        !            42: #include <machine/intr.h>
        !            43: #include <machine/bus.h>
        !            44:
        !            45: #include <sys/audioio.h>
        !            46: #include <dev/audio_if.h>
        !            47: #include <dev/midi_if.h>
        !            48:
        !            49: #include <dev/isa/isavar.h>
        !            50: #include <dev/isa/isadmavar.h>
        !            51:
        !            52: #include <dev/ic/ad1848reg.h>
        !            53: #include <dev/isa/ad1848var.h>
        !            54: #include <dev/ic/opl3sa3reg.h>
        !            55: #include <dev/ic/mpuvar.h>
        !            56: #include <dev/isa/ymvar.h>
        !            57:
        !            58: int ym_getdev(void *, struct audio_device *);
        !            59: int ym_mixer_set_port(void *, mixer_ctrl_t *);
        !            60: int ym_mixer_get_port(void *, mixer_ctrl_t *);
        !            61: int ym_query_devinfo(void *, mixer_devinfo_t *);
        !            62: int ym_intr(void *);
        !            63:
        !            64: static void ym_mute(struct ym_softc *, int, int);
        !            65: static void ym_set_master_gain(struct ym_softc *, struct ad1848_volume *);
        !            66: static void ym_set_mic_gain(struct ym_softc *, int);
        !            67: static void ym_set_3d(struct ym_softc *, mixer_ctrl_t *,
        !            68:        struct ad1848_volume *, int);
        !            69:
        !            70: struct audio_hw_if ym_hw_if = {
        !            71:        ad1848_open,
        !            72:        ad1848_close,
        !            73:        NULL,
        !            74:        ad1848_query_encoding,
        !            75:        ad1848_set_params,
        !            76:        ad1848_round_blocksize,
        !            77:        ad1848_commit_settings,
        !            78:        ad1848_dma_init_output,
        !            79:        ad1848_dma_init_input,
        !            80:        ad1848_dma_output,
        !            81:        ad1848_dma_input,
        !            82:        ad1848_halt_out_dma,
        !            83:        ad1848_halt_in_dma,
        !            84:        NULL,
        !            85:        ym_getdev,
        !            86:        NULL,
        !            87:        ym_mixer_set_port,
        !            88:        ym_mixer_get_port,
        !            89:        ym_query_devinfo,
        !            90:        ad1848_malloc,
        !            91:        ad1848_free,
        !            92:        ad1848_round,
        !            93:        ad1848_mappage,
        !            94:        ad1848_get_props,
        !            95:        NULL,
        !            96:        NULL
        !            97: };
        !            98:
        !            99:
        !           100: struct cfdriver ym_cd = {
        !           101:        NULL, "ym", DV_DULL
        !           102: };
        !           103:
        !           104: struct audio_device ym_device = {
        !           105:        "ym,ad1848",
        !           106:        "",
        !           107:        "ym"
        !           108: };
        !           109:
        !           110: static __inline int ym_read(struct ym_softc *, int);
        !           111: static __inline void ym_write(struct ym_softc *, int, int);
        !           112:
        !           113: #if NMIDI > 0
        !           114: int    ym_mpu401_open(void *, int, void (*iintr)(void *, int),
        !           115:            void (*ointr)(void *), void *arg);
        !           116: void   ym_mpu401_close(void *);
        !           117: int    ym_mpu401_output(void *, int);
        !           118: void   ym_mpu401_getinfo(void *, struct midi_info *);
        !           119:
        !           120: struct midi_hw_if ym_mpu401_hw_if = {
        !           121:        ym_mpu401_open,
        !           122:        ym_mpu401_close,
        !           123:        ym_mpu401_output,
        !           124:        0,              /* flush */
        !           125:        ym_mpu401_getinfo,
        !           126:        0,              /* ioctl */
        !           127: };
        !           128: #endif
        !           129:
        !           130: int
        !           131: ym_intr(v)
        !           132:        void   *v;
        !           133: {
        !           134: #if NMIDI > 0
        !           135:        struct ym_softc *sc = v;
        !           136:
        !           137:        if ( /* XXX && */ sc->sc_hasmpu)
        !           138:                mpu_intr(&sc->sc_mpu_sc);
        !           139: #endif
        !           140:        return ad1848_intr(v);
        !           141: }
        !           142:
        !           143: void
        !           144: ym_attach(sc)
        !           145:        struct ym_softc *sc;
        !           146:
        !           147: {
        !           148:        struct ad1848_volume vol_mid = {220, 220};
        !           149: #if NMIDI > 0
        !           150:        struct midi_hw_if *mhw = &ym_mpu401_hw_if;
        !           151: #endif
        !           152:
        !           153:        sc->sc_ih = isa_intr_establish(sc->sc_ic, sc->ym_irq, IST_EDGE,
        !           154:            IPL_AUDIO, ym_intr, &sc->sc_ad1848, sc->sc_dev.dv_xname);
        !           155:
        !           156:        ad1848_attach(&sc->sc_ad1848);
        !           157:        printf("\n");
        !           158:        sc->sc_ad1848.parent = sc;
        !           159:
        !           160:        /* Establish chip in well known mode */
        !           161:        ym_set_master_gain(sc, &vol_mid);
        !           162:        ym_set_mic_gain(sc, 0);
        !           163:        sc->master_mute = 0;
        !           164:        ym_mute(sc, SA3_VOL_L, sc->master_mute);
        !           165:        ym_mute(sc, SA3_VOL_R, sc->master_mute);
        !           166:
        !           167:        sc->mic_mute = 1;
        !           168:        ym_mute(sc, SA3_MIC_VOL, sc->mic_mute);
        !           169:
        !           170: #if NMIDI > 0
        !           171:        sc->sc_hasmpu = 0;
        !           172:        if (sc->sc_mpu_sc.iobase) {
        !           173:                sc->sc_mpu_sc.iot = sc->sc_iot;
        !           174:                if (mpu_find(&sc->sc_mpu_sc)) {
        !           175:                        sc->sc_hasmpu = 1;
        !           176:                        mhw = &ym_mpu401_hw_if;
        !           177:                }
        !           178:        }
        !           179:        midi_attach_mi(mhw, sc, &sc->sc_dev);
        !           180: #endif
        !           181:
        !           182:        audio_attach_mi(&ym_hw_if, &sc->sc_ad1848, &sc->sc_dev);
        !           183: }
        !           184:
        !           185: static __inline int
        !           186: ym_read(sc, reg)
        !           187:        struct ym_softc *sc;
        !           188:        int     reg;
        !           189: {
        !           190:        bus_space_write_1(sc->sc_iot, sc->sc_controlioh, SA3_CTL_INDEX,
        !           191:            (reg & 0xff));
        !           192:        return (bus_space_read_1(sc->sc_iot, sc->sc_controlioh, SA3_CTL_DATA));
        !           193: }
        !           194:
        !           195: static __inline void
        !           196: ym_write(sc, reg, data)
        !           197:        struct ym_softc *sc;
        !           198:        int     reg;
        !           199:        int     data;
        !           200: {
        !           201:        bus_space_write_1(sc->sc_iot, sc->sc_controlioh, SA3_CTL_INDEX,
        !           202:            (reg & 0xff));
        !           203:        bus_space_write_1(sc->sc_iot, sc->sc_controlioh, SA3_CTL_DATA,
        !           204:            (data & 0xff));
        !           205: }
        !           206:
        !           207:
        !           208:
        !           209: int
        !           210: ym_getdev(addr, retp)
        !           211:        void   *addr;
        !           212:        struct audio_device *retp;
        !           213: {
        !           214:        *retp = ym_device;
        !           215:        return 0;
        !           216: }
        !           217:
        !           218:
        !           219: static ad1848_devmap_t mappings[] = {
        !           220:        { YM_MIDI_LVL, AD1848_KIND_LVL, AD1848_AUX2_CHANNEL },
        !           221:        { YM_CD_LVL, AD1848_KIND_LVL, AD1848_AUX1_CHANNEL },
        !           222:        { YM_DAC_LVL, AD1848_KIND_LVL, AD1848_DAC_CHANNEL },
        !           223:        { YM_LINE_LVL, AD1848_KIND_LVL, AD1848_LINE_CHANNEL },
        !           224:        { YM_SPEAKER_LVL, AD1848_KIND_LVL, AD1848_MONO_CHANNEL },
        !           225:        { YM_MONITOR_LVL, AD1848_KIND_LVL, AD1848_MONITOR_CHANNEL },
        !           226:        { YM_MIDI_MUTE, AD1848_KIND_MUTE, AD1848_AUX2_CHANNEL },
        !           227:        { YM_CD_MUTE, AD1848_KIND_MUTE, AD1848_AUX1_CHANNEL },
        !           228:        { YM_DAC_MUTE, AD1848_KIND_MUTE, AD1848_DAC_CHANNEL },
        !           229:        { YM_LINE_MUTE, AD1848_KIND_MUTE, AD1848_LINE_CHANNEL },
        !           230:        { YM_SPEAKER_MUTE, AD1848_KIND_MUTE, AD1848_MONO_CHANNEL },
        !           231:        { YM_MONITOR_MUTE, AD1848_KIND_MUTE, AD1848_MONITOR_CHANNEL },
        !           232:        { YM_REC_LVL, AD1848_KIND_RECORDGAIN, -1 },
        !           233:        { YM_RECORD_SOURCE, AD1848_KIND_RECORDSOURCE, -1 }
        !           234: };
        !           235:
        !           236: #define NUMMAP (sizeof(mappings) / sizeof(mappings[0]))
        !           237:
        !           238:
        !           239: static void
        !           240: ym_mute(sc, left_reg, mute)
        !           241:        struct ym_softc *sc;
        !           242:        int     left_reg;
        !           243:        int     mute;
        !           244: {
        !           245:        u_int8_t reg;
        !           246:
        !           247:        reg = ym_read(sc, left_reg);
        !           248:        if (mute)
        !           249:                ym_write(sc, left_reg, reg | 0x80);
        !           250:        else
        !           251:                ym_write(sc, left_reg, reg & ~0x80);
        !           252: }
        !           253:
        !           254: static void
        !           255: ym_set_master_gain(sc, vol)
        !           256:        struct ym_softc *sc;
        !           257:        struct ad1848_volume *vol;
        !           258: {
        !           259:        u_int   atten;
        !           260:
        !           261:        sc->master_gain = *vol;
        !           262:
        !           263:        atten = ((AUDIO_MAX_GAIN - vol->left) * (SA3_VOL_MV + 1)) /
        !           264:           (AUDIO_MAX_GAIN + 1);
        !           265:
        !           266:        ym_write(sc, SA3_VOL_L, (ym_read(sc, SA3_VOL_L) & ~SA3_VOL_MV) | atten);
        !           267:
        !           268:        atten = ((AUDIO_MAX_GAIN - vol->right) * (SA3_VOL_MV + 1)) /
        !           269:           (AUDIO_MAX_GAIN + 1);
        !           270:
        !           271:        ym_write(sc, SA3_VOL_R, (ym_read(sc, SA3_VOL_R) & ~SA3_VOL_MV) | atten);
        !           272: }
        !           273:
        !           274: static void
        !           275: ym_set_mic_gain(sc, vol)
        !           276:        struct ym_softc *sc;
        !           277:        int vol;
        !           278: {
        !           279:        u_int   atten;
        !           280:
        !           281:        sc->mic_gain = vol;
        !           282:
        !           283:        atten = ((AUDIO_MAX_GAIN - vol) * (SA3_MIC_MCV + 1)) /
        !           284:            (AUDIO_MAX_GAIN + 1);
        !           285:
        !           286:        ym_write(sc, SA3_MIC_VOL,
        !           287:            (ym_read(sc, SA3_MIC_VOL) & ~SA3_MIC_MCV) | atten);
        !           288: }
        !           289:
        !           290: static void
        !           291: ym_set_3d(sc, cp, val, reg)
        !           292:        struct ym_softc *sc;
        !           293:        mixer_ctrl_t *cp;
        !           294:        struct ad1848_volume *val;
        !           295:        int reg;
        !           296: {
        !           297:        u_int8_t e;
        !           298:
        !           299:        ad1848_to_vol(cp, val);
        !           300:
        !           301:        e = (val->left * (SA3_3D_BITS + 1) + (SA3_3D_BITS + 1) / 2) /
        !           302:                (AUDIO_MAX_GAIN + 1) << SA3_3D_LSHIFT |
        !           303:            (val->right * (SA3_3D_BITS + 1) + (SA3_3D_BITS + 1) / 2) /
        !           304:                (AUDIO_MAX_GAIN + 1) << SA3_3D_RSHIFT;
        !           305:
        !           306:        ym_write(sc, reg, e);
        !           307: }
        !           308:
        !           309: int
        !           310: ym_mixer_set_port(addr, cp)
        !           311:        void   *addr;
        !           312:        mixer_ctrl_t *cp;
        !           313: {
        !           314:        struct ad1848_softc *ac = addr;
        !           315:        struct ym_softc *sc = ac->parent;
        !           316:        struct ad1848_volume vol;
        !           317:        int     error = ad1848_mixer_set_port(ac, mappings, NUMMAP, cp);
        !           318:
        !           319:        if (error != ENXIO)
        !           320:                return (error);
        !           321:
        !           322:        error = 0;
        !           323:
        !           324:        switch (cp->dev) {
        !           325:        case YM_OUTPUT_LVL:
        !           326:                ad1848_to_vol(cp, &vol);
        !           327:                ym_set_master_gain(sc, &vol);
        !           328:                break;
        !           329:
        !           330:        case YM_OUTPUT_MUTE:
        !           331:                sc->master_mute = (cp->un.ord != 0);
        !           332:                ym_mute(sc, SA3_VOL_L, sc->master_mute);
        !           333:                ym_mute(sc, SA3_VOL_R, sc->master_mute);
        !           334:                break;
        !           335:
        !           336:        case YM_MIC_LVL:
        !           337:                if (cp->un.value.num_channels != 1)
        !           338:                        error = EINVAL;
        !           339:                else
        !           340:                        ym_set_mic_gain(sc,
        !           341:                            cp->un.value.level[AUDIO_MIXER_LEVEL_MONO]);
        !           342:                break;
        !           343:
        !           344:        case YM_MASTER_EQMODE:
        !           345:                sc->sc_eqmode = cp->un.ord & SA3_SYS_CTL_YMODE;
        !           346:                ym_write(sc, SA3_SYS_CTL, (ym_read(sc, SA3_SYS_CTL) &
        !           347:                    ~SA3_SYS_CTL_YMODE) | sc->sc_eqmode);
        !           348:                break;
        !           349:
        !           350:        case YM_MASTER_TREBLE:
        !           351:                ym_set_3d(sc, cp, &sc->sc_treble, SA3_3D_TREBLE);
        !           352:                break;
        !           353:
        !           354:        case YM_MASTER_BASS:
        !           355:                ym_set_3d(sc, cp, &sc->sc_bass, SA3_3D_BASS);
        !           356:                break;
        !           357:
        !           358:        case YM_MASTER_WIDE:
        !           359:                ym_set_3d(sc, cp, &sc->sc_wide, SA3_3D_WIDE);
        !           360:                break;
        !           361:
        !           362:        case YM_MIC_MUTE:
        !           363:                sc->mic_mute = (cp->un.ord != 0);
        !           364:                ym_mute(sc, SA3_MIC_VOL, sc->mic_mute);
        !           365:                break;
        !           366:
        !           367:        default:
        !           368:                return ENXIO;
        !           369:                /* NOTREACHED */
        !           370:        }
        !           371:
        !           372:        return (error);
        !           373: }
        !           374:
        !           375: int
        !           376: ym_mixer_get_port(addr, cp)
        !           377:        void   *addr;
        !           378:        mixer_ctrl_t *cp;
        !           379: {
        !           380:        struct ad1848_softc *ac = addr;
        !           381:        struct ym_softc *sc = ac->parent;
        !           382:
        !           383:        int     error = ad1848_mixer_get_port(ac, mappings, NUMMAP, cp);
        !           384:
        !           385:        if (error != ENXIO)
        !           386:                return (error);
        !           387:
        !           388:        error = 0;
        !           389:
        !           390:        switch (cp->dev) {
        !           391:        case YM_OUTPUT_LVL:
        !           392:                ad1848_from_vol(cp, &sc->master_gain);
        !           393:                break;
        !           394:
        !           395:        case YM_OUTPUT_MUTE:
        !           396:                cp->un.ord = sc->master_mute;
        !           397:                break;
        !           398:
        !           399:        case YM_MIC_LVL:
        !           400:                if (cp->un.value.num_channels != 1)
        !           401:                        error = EINVAL;
        !           402:                cp->un.value.level[AUDIO_MIXER_LEVEL_MONO] = sc->mic_gain;
        !           403:                break;
        !           404:
        !           405:        case YM_MASTER_EQMODE:
        !           406:                cp->un.ord = sc->sc_eqmode;
        !           407:                break;
        !           408:
        !           409:        case YM_MASTER_TREBLE:
        !           410:                ad1848_from_vol(cp, &sc->sc_treble);
        !           411:                break;
        !           412:
        !           413:        case YM_MASTER_BASS:
        !           414:                ad1848_from_vol(cp, &sc->sc_bass);
        !           415:                break;
        !           416:
        !           417:        case YM_MASTER_WIDE:
        !           418:                ad1848_from_vol(cp, &sc->sc_wide);
        !           419:                break;
        !           420:
        !           421:        case YM_MIC_MUTE:
        !           422:                cp->un.ord = sc->mic_mute;
        !           423:                break;
        !           424:
        !           425:        default:
        !           426:                error = ENXIO;
        !           427:                break;
        !           428:        }
        !           429:
        !           430:        return (error);
        !           431: }
        !           432:
        !           433: static char *mixer_classes[] = {
        !           434:        AudioCinputs, AudioCrecord, AudioCoutputs, AudioCmonitor,
        !           435:        AudioCequalization
        !           436: };
        !           437:
        !           438: int
        !           439: ym_query_devinfo(addr, dip)
        !           440:        void   *addr;
        !           441:        mixer_devinfo_t *dip;
        !           442: {
        !           443:        static char *mixer_port_names[] = { AudioNmidi, AudioNcd, AudioNdac,
        !           444:                AudioNline, AudioNspeaker, AudioNmicrophone, AudioNmonitor
        !           445:        };
        !           446:
        !           447:        dip->next = dip->prev = AUDIO_MIXER_LAST;
        !           448:
        !           449:        switch (dip->index) {
        !           450:        case YM_INPUT_CLASS:    /* input class descriptor */
        !           451:        case YM_OUTPUT_CLASS:
        !           452:        case YM_MONITOR_CLASS:
        !           453:        case YM_RECORD_CLASS:
        !           454:        case YM_EQ_CLASS:
        !           455:                dip->type = AUDIO_MIXER_CLASS;
        !           456:                dip->mixer_class = dip->index;
        !           457:                strlcpy(dip->label.name,
        !           458:                    mixer_classes[dip->index - YM_INPUT_CLASS],
        !           459:                    sizeof dip->label.name);
        !           460:                break;
        !           461:
        !           462:        case YM_MIDI_LVL:
        !           463:        case YM_CD_LVL:
        !           464:        case YM_DAC_LVL:
        !           465:        case YM_LINE_LVL:
        !           466:        case YM_SPEAKER_LVL:
        !           467:        case YM_MIC_LVL:
        !           468:        case YM_MONITOR_LVL:
        !           469:                dip->type = AUDIO_MIXER_VALUE;
        !           470:                if (dip->index == YM_MONITOR_LVL)
        !           471:                        dip->mixer_class = YM_MONITOR_CLASS;
        !           472:                else
        !           473:                        dip->mixer_class = YM_INPUT_CLASS;
        !           474:
        !           475:                dip->next = dip->index + 7;
        !           476:
        !           477:                strlcpy(dip->label.name,
        !           478:                    mixer_port_names[dip->index - YM_MIDI_LVL],
        !           479:                    sizeof dip->label.name);
        !           480:
        !           481:                if (dip->index == YM_SPEAKER_LVL ||
        !           482:                    dip->index == YM_MIC_LVL)
        !           483:                        dip->un.v.num_channels = 1;
        !           484:                else
        !           485:                        dip->un.v.num_channels = 2;
        !           486:
        !           487:                strlcpy(dip->un.v.units.name, AudioNvolume,
        !           488:                    sizeof dip->un.v.units.name);
        !           489:                break;
        !           490:
        !           491:        case YM_MIDI_MUTE:
        !           492:        case YM_CD_MUTE:
        !           493:        case YM_DAC_MUTE:
        !           494:        case YM_LINE_MUTE:
        !           495:        case YM_SPEAKER_MUTE:
        !           496:        case YM_MIC_MUTE:
        !           497:        case YM_MONITOR_MUTE:
        !           498:                if (dip->index == YM_MONITOR_MUTE)
        !           499:                        dip->mixer_class = YM_MONITOR_CLASS;
        !           500:                else
        !           501:                        dip->mixer_class = YM_INPUT_CLASS;
        !           502:                dip->type = AUDIO_MIXER_ENUM;
        !           503:                dip->prev = dip->index - 7;
        !           504: mute:
        !           505:                strlcpy(dip->label.name, AudioNmute, sizeof dip->label.name);
        !           506:                dip->un.e.num_mem = 2;
        !           507:                strlcpy(dip->un.e.member[0].label.name, AudioNoff,
        !           508:                    sizeof dip->un.e.member[0].label.name);
        !           509:                dip->un.e.member[0].ord = 0;
        !           510:                strlcpy(dip->un.e.member[1].label.name, AudioNon,
        !           511:                    sizeof dip->un.e.member[1].label.name);
        !           512:                dip->un.e.member[1].ord = 1;
        !           513:                break;
        !           514:
        !           515:
        !           516:        case YM_OUTPUT_LVL:
        !           517:                dip->type = AUDIO_MIXER_VALUE;
        !           518:                dip->mixer_class = YM_OUTPUT_CLASS;
        !           519:                dip->next = YM_OUTPUT_MUTE;
        !           520:                strlcpy(dip->label.name, AudioNmaster, sizeof dip->label.name);
        !           521:                dip->un.v.num_channels = 2;
        !           522:                strlcpy(dip->un.v.units.name, AudioNvolume,
        !           523:                    sizeof dip->un.v.units.name);
        !           524:                break;
        !           525:
        !           526:        case YM_OUTPUT_MUTE:
        !           527:                dip->mixer_class = YM_OUTPUT_CLASS;
        !           528:                dip->type = AUDIO_MIXER_ENUM;
        !           529:                dip->prev = YM_OUTPUT_LVL;
        !           530:                goto mute;
        !           531:
        !           532:        case YM_REC_LVL:        /* record level */
        !           533:                dip->type = AUDIO_MIXER_VALUE;
        !           534:                dip->mixer_class = YM_RECORD_CLASS;
        !           535:                dip->next = YM_RECORD_SOURCE;
        !           536:                strlcpy(dip->label.name, AudioNrecord, sizeof dip->label.name);
        !           537:                dip->un.v.num_channels = 2;
        !           538:                strlcpy(dip->un.v.units.name, AudioNvolume,
        !           539:                    sizeof dip->un.v.units.name);
        !           540:                break;
        !           541:
        !           542:
        !           543:        case YM_RECORD_SOURCE:
        !           544:                dip->mixer_class = YM_RECORD_CLASS;
        !           545:                dip->type = AUDIO_MIXER_ENUM;
        !           546:                dip->prev = YM_REC_LVL;
        !           547:                strlcpy(dip->label.name, AudioNsource, sizeof dip->label.name);
        !           548:                dip->un.e.num_mem = 4;
        !           549:                strlcpy(dip->un.e.member[0].label.name, AudioNmicrophone,
        !           550:                    sizeof dip->un.e.member[0].label.name);
        !           551:                dip->un.e.member[0].ord = MIC_IN_PORT;
        !           552:                strlcpy(dip->un.e.member[1].label.name, AudioNline,
        !           553:                    sizeof dip->un.e.member[1].label.name);
        !           554:                dip->un.e.member[1].ord = LINE_IN_PORT;
        !           555:                strlcpy(dip->un.e.member[2].label.name, AudioNdac,
        !           556:                    sizeof dip->un.e.member[2].label.name);
        !           557:                dip->un.e.member[2].ord = DAC_IN_PORT;
        !           558:                strlcpy(dip->un.e.member[3].label.name, AudioNcd,
        !           559:                    sizeof dip->un.e.member[3].label.name);
        !           560:                dip->un.e.member[3].ord = AUX1_IN_PORT;
        !           561:                break;
        !           562:
        !           563:        case YM_MASTER_EQMODE:
        !           564:                dip->type = AUDIO_MIXER_ENUM;
        !           565:                dip->mixer_class = YM_EQ_CLASS;
        !           566:                strlcpy(dip->label.name, AudioNmode, sizeof dip->label.name);
        !           567:                strlcpy(dip->un.v.units.name, AudioNmode,
        !           568:                    sizeof dip->un.v.units.name);
        !           569:                dip->un.e.num_mem = 4;
        !           570:                strlcpy(dip->un.e.member[0].label.name, AudioNdesktop,
        !           571:                    sizeof dip->un.e.member[0].label.name);
        !           572:                dip->un.e.member[0].ord = SA3_SYS_CTL_YMODE0;
        !           573:                strlcpy(dip->un.e.member[1].label.name, AudioNlaptop,
        !           574:                    sizeof dip->un.e.member[1].label.name);
        !           575:                dip->un.e.member[1].ord = SA3_SYS_CTL_YMODE1;
        !           576:                strlcpy(dip->un.e.member[2].label.name, AudioNsubnote,
        !           577:                    sizeof dip->un.e.member[2].label.name);
        !           578:                dip->un.e.member[2].ord = SA3_SYS_CTL_YMODE2;
        !           579:                strlcpy(dip->un.e.member[3].label.name, AudioNhifi,
        !           580:                    sizeof dip->un.e.member[3].label.name);
        !           581:                dip->un.e.member[3].ord = SA3_SYS_CTL_YMODE3;
        !           582:                break;
        !           583:
        !           584:        case YM_MASTER_TREBLE:
        !           585:                dip->type = AUDIO_MIXER_VALUE;
        !           586:                dip->mixer_class = YM_EQ_CLASS;
        !           587:                strlcpy(dip->label.name, AudioNtreble, sizeof dip->label.name);
        !           588:                dip->un.v.num_channels = 2;
        !           589:                strlcpy(dip->un.v.units.name, AudioNtreble,
        !           590:                    sizeof dip->un.v.units.name);
        !           591:                break;
        !           592:
        !           593:        case YM_MASTER_BASS:
        !           594:                dip->type = AUDIO_MIXER_VALUE;
        !           595:                dip->mixer_class = YM_EQ_CLASS;
        !           596:                strlcpy(dip->label.name, AudioNbass, sizeof dip->label.name);
        !           597:                dip->un.v.num_channels = 2;
        !           598:                strlcpy(dip->un.v.units.name, AudioNbass,
        !           599:                    sizeof dip->un.v.units.name);
        !           600:                break;
        !           601:
        !           602:        case YM_MASTER_WIDE:
        !           603:                dip->type = AUDIO_MIXER_VALUE;
        !           604:                dip->mixer_class = YM_EQ_CLASS;
        !           605:                strlcpy(dip->label.name, AudioNsurround,
        !           606:                    sizeof dip->label.name);
        !           607:                dip->un.v.num_channels = 2;
        !           608:                strlcpy(dip->un.v.units.name, AudioNsurround,
        !           609:                    sizeof dip->un.v.units.name);
        !           610:                break;
        !           611:
        !           612:        default:
        !           613:                return ENXIO;
        !           614:                /* NOTREACHED */
        !           615:        }
        !           616:
        !           617:        return 0;
        !           618: }
        !           619: #if NMIDI > 0
        !           620:
        !           621: #define YMMPU(a) (&((struct ym_softc *)addr)->sc_mpu_sc)
        !           622:
        !           623: int
        !           624: ym_mpu401_open(addr, flags, iintr, ointr, arg)
        !           625:        void   *addr;
        !           626:        int     flags;
        !           627:        void    (*iintr)(void *, int);
        !           628:        void    (*ointr)(void *);
        !           629:        void   *arg;
        !           630: {
        !           631:        return mpu_open(YMMPU(addr), flags, iintr, ointr, arg);
        !           632: }
        !           633:
        !           634: int
        !           635: ym_mpu401_output(addr, d)
        !           636:        void   *addr;
        !           637:        int     d;
        !           638: {
        !           639:        return mpu_output(YMMPU(addr), d);
        !           640: }
        !           641:
        !           642: void
        !           643: ym_mpu401_close(addr)
        !           644:        void   *addr;
        !           645: {
        !           646:        mpu_close(YMMPU(addr));
        !           647: }
        !           648:
        !           649: void
        !           650: ym_mpu401_getinfo(addr, mi)
        !           651:        void   *addr;
        !           652:        struct midi_info *mi;
        !           653: {
        !           654:        mi->name = "YM MPU-401 UART";
        !           655:        mi->props = 0;
        !           656: }
        !           657: #endif

CVSweb