[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

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