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

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

1.1     ! nbrk        1: /*     $OpenBSD: aria.c,v 1.13 2006/05/11 18:50:18 miod Exp $ */
        !             2:
        !             3: /*
        !             4:  * Copyright (c) 1995, 1996 Roland C. Dowdeswell.  All rights reserved.
        !             5:  *
        !             6:  * Redistribution and use in source and binary forms, with or without
        !             7:  * modification, are permitted provided that the following conditions
        !             8:  * are met:
        !             9:  * 1. Redistributions of source code must retain the above copyright
        !            10:  *    notice, this list of conditions and the following disclaimer.
        !            11:  * 2. Redistributions in binary form must reproduce the above copyright
        !            12:  *    notice, this list of conditions and the following disclaimer in the
        !            13:  *    documentation and/or other materials provided with the distribution.
        !            14:  * 3. All advertising materials mentioning features or use of this software
        !            15:  *    must display the following acknowledgement:
        !            16:  *      This product includes software developed by Roland C. Dowdeswell.
        !            17:  * 4. The name of the authors may not be used to endorse or promote products
        !            18:  *      derived from this software without specific prior written permission.
        !            19:  *
        !            20:  * THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS OR
        !            21:  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
        !            22:  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
        !            23:  * IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY DIRECT, INDIRECT,
        !            24:  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
        !            25:  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
        !            26:  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
        !            27:  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
        !            28:  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
        !            29:  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
        !            30:  */
        !            31:
        !            32: /*
        !            33:  * TODO:
        !            34:  *  o   Test the driver on cards other than a single
        !            35:  *      Prometheus Aria 16.
        !            36:  *  o   Look into where aria_prometheus_kludge() belongs.
        !            37:  *  o   Add some dma code.  It accomplishes its goal by
        !            38:  *      direct IO at the moment.
        !            39:  *  o   Look into return values on aria_set_sr(), if there is
        !            40:  *      no matching rate.  (I think that this behaves in the
        !            41:  *      same way as sbdsp.c)
        !            42:  *  o   Different programs should be able to open the device
        !            43:  *      with O_RDONLY and O_WRONLY at the same time.  But I
        !            44:  *      do not see support for this in /sys/dev/audio.c, so
        !            45:  *     I cannot effectively code it.
        !            46:  *  o   Separate the debugging code, with a #define.
        !            47:  *      Write more into aria_printsc().
        !            48:  *  o   Rework the mixer interface.
        !            49:  *       o   Deal with the lvls better.  We need to do better mapping
        !            50:  *           between logarithmic scales and the one byte that
        !            51:  *           we are passed.
        !            52:  *       o   Deal better with cards that have no mixer.
        !            53:  *
        !            54:  * roland@imrryr.org
        !            55:  * update from http://www.imrryr.org/NetBSD/hacks/aria/
        !            56:  */
        !            57:
        !            58: #include "aria.h"
        !            59: #if NARIA > 0
        !            60:
        !            61: #include <sys/param.h>
        !            62: #include <sys/systm.h>
        !            63: #include <sys/errno.h>
        !            64: #include <sys/ioctl.h>
        !            65: #include <sys/syslog.h>
        !            66: #include <sys/device.h>
        !            67: #include <sys/proc.h>
        !            68: #include <sys/buf.h>
        !            69:
        !            70: #include <machine/cpu.h>
        !            71: #include <machine/pio.h>
        !            72:
        !            73: #include <sys/audioio.h>
        !            74: #include <dev/audio_if.h>
        !            75:
        !            76: #include <dev/mulaw.h>
        !            77: #include <dev/isa/isavar.h>
        !            78: #include <dev/isa/isadmavar.h>
        !            79:
        !            80: #include <dev/isa/ariareg.h>
        !            81:
        !            82: #define FREAD 1
        !            83: #define FWRITE 2
        !            84:
        !            85: #ifdef AUDIO_DEBUG
        !            86: extern void Dprintf(const char *, ...);
        !            87: #define DPRINTF(x)     if (ariadebug) Dprintf x
        !            88: int    ariadebug = 0;
        !            89: #else
        !            90: #define DPRINTF(x)
        !            91: #endif
        !            92:
        !            93: struct aria_mixdev_info {
        !            94:        u_char  num_channels;
        !            95:        u_char  level[2];
        !            96:        u_char  mute;
        !            97: };
        !            98:
        !            99: struct aria_mixmaster {
        !           100:        u_char num_channels;
        !           101:        u_char level[2];
        !           102:        u_char treble[2];
        !           103:        u_char bass[2];
        !           104: };
        !           105:
        !           106: struct aria_softc {
        !           107:        struct  device sc_dev;          /* base device */
        !           108:        struct  isadev sc_id;           /* ISA device */
        !           109:        void    *sc_ih;                 /* interrupt vectoring */
        !           110:
        !           111:        u_short sc_iobase;              /* I/O port base address */
        !           112:        u_short sc_irq;                 /* interrupt */
        !           113:        u_short sc_drq;                 /* dma chan */
        !           114:
        !           115:        u_short sc_open;                /* reference count of open calls */
        !           116:        u_short sc_play;                /* non-paused play chans 2**chan */
        !           117:        u_short sc_record;              /* non-paused record chans 2**chan */
        !           118:        u_short sc_change;              /* to keep track of changes of a type */
        !           119:        u_short gain[2];                /* left/right gain (play) */
        !           120:        u_int   spkr_state;             /* non-null is on */
        !           121:
        !           122:        u_long  sc_rate;                /* Sample rate for input and output */
        !           123:        u_int   sc_encoding;            /* audio encoding -- ulaw/linear */
        !           124:        int     sc_chans;               /* # of channels */
        !           125:        int     sc_precision;           /* # bits per sample */
        !           126:
        !           127:        u_long  sc_interrupts;          /* number of interrupts taken */
        !           128:        void    (*sc_rintr)(void *);    /* record transfer completion intr handler */
        !           129:        void    (*sc_pintr)(void *);    /* play transfer completion intr handler */
        !           130:        void    *sc_rarg;               /* arg for sc_rintr() */
        !           131:        void    *sc_parg;               /* arg for sc_pintr() */
        !           132:
        !           133:        int     sc_blocksize;           /* literal dio block size */
        !           134:        void    *sc_rdiobuffer;         /* record: where the next samples should be */
        !           135:        void    *sc_pdiobuffer;         /* play:   where the next samples are */
        !           136:
        !           137:        u_short sc_hardware;            /* bit field of hardware present */
        !           138: #define ARIA_TELEPHONE 0x0001          /* has telephone input */
        !           139: #define ARIA_MIXER     0x0002          /* has SC18075 digital mixer */
        !           140: #define ARIA_MODEL     0x0004          /* is SC18025 (=0) or SC18026 (=1) */
        !           141:
        !           142:        struct aria_mixdev_info aria_mix[6];
        !           143:        struct aria_mixmaster ariamix_master;
        !           144:        u_char  aria_mix_source;
        !           145: };
        !           146:
        !           147: struct {
        !           148:        int sendcmd;
        !           149:        int wmidi;
        !           150: } ariaerr;
        !           151:
        !           152:
        !           153:
        !           154: int    ariaprobe();
        !           155: void   ariaattach(struct device *, struct device *, void *);
        !           156: void   ariaclose(void *);
        !           157: int    ariaopen(dev_t, int);
        !           158: int    aria_getdev(void *, struct audio_device *);
        !           159:
        !           160: void   aria_do_kludge(u_short, u_short, u_short, u_short, u_short);
        !           161: void   aria_prometheus_kludge(struct isa_attach_args *);
        !           162:
        !           163: int    aria_set_sr(void *, u_long);
        !           164: u_long aria_get_sr(void *);
        !           165: int    aria_query_encoding(void *, struct audio_encoding *);
        !           166: int    aria_set_format(void *, u_int, u_int);
        !           167: int    aria_get_encoding(void *);
        !           168: int    aria_get_precision(void *);
        !           169: int    aria_set_channels(void *, int);
        !           170: int    aria_get_channels(void *);
        !           171: int    aria_round_blocksize(void *, int);
        !           172: int    aria_set_out_port(void *, int);
        !           173: int    aria_get_out_port(void *);
        !           174: int    aria_set_in_port(void *, int);
        !           175: int    aria_get_in_port(void *);
        !           176: int    aria_speaker_ctl(void *, int);
        !           177: int    aria_commit_settings(void *);
        !           178:
        !           179: int    aria_start_output(void *, void *, int, void (*)(), void *);
        !           180: int    aria_start_input(void *, void *, int, void (*)(), void *);
        !           181:
        !           182: int    aria_halt_input(void *);
        !           183: int    aria_halt_output(void *);
        !           184: int    aria_cont(void *);
        !           185:
        !           186: int    aria_sendcmd(u_short, u_short, int, int, int);
        !           187:
        !           188: u_short        aria_getdspmem(u_short, u_short);
        !           189: u_short        aria_putdspmem(u_short, u_short, u_short);
        !           190:
        !           191: int    aria_intr(void *);
        !           192: short  ariaversion(struct aria_softc *);
        !           193:
        !           194: int    aria_setfd(void *, int);
        !           195:
        !           196: void   aria_mix_write(struct aria_softc *, int, int);
        !           197: int    aria_mix_read(struct aria_softc *, int);
        !           198:
        !           199: int    aria_mixer_set_port(void *, mixer_ctrl_t *);
        !           200: int    aria_mixer_get_port(void *, mixer_ctrl_t *);
        !           201: int    aria_mixer_query_devinfo(void *, mixer_devinfo_t *);
        !           202:
        !           203: /*
        !           204:  * Mixer defines...
        !           205:  */
        !           206:
        !           207: struct cfattach aria_ca = {
        !           208:        sizeof(struct aria_softc), ariaprobe, ariaattach
        !           209: };
        !           210:
        !           211: struct cfdriver aria_cd = {
        !           212:        NULL, "aria", DV_DULL
        !           213: };
        !           214:
        !           215: struct audio_device aria_device = {
        !           216:        "Aria 16(se)",
        !           217:        "x",
        !           218:        "aria"
        !           219: };
        !           220:
        !           221: /*
        !           222:  * Define our interface to the higher level audio driver.
        !           223:  */
        !           224:
        !           225: struct audio_hw_if aria_hw_if = {
        !           226:        ariaopen,
        !           227:        ariaclose,
        !           228:        NULL,
        !           229:        aria_set_sr,
        !           230:        aria_get_sr,
        !           231:        aria_set_sr,
        !           232:        aria_get_sr,
        !           233:        aria_query_encoding,
        !           234:        aria_set_format,
        !           235:        aria_get_encoding,
        !           236:        aria_get_precision,
        !           237:        aria_set_channels,
        !           238:        aria_get_channels,
        !           239:        aria_round_blocksize,
        !           240:        aria_set_out_port,
        !           241:        aria_get_out_port,
        !           242:        aria_set_in_port,
        !           243:        aria_get_in_port,
        !           244:        aria_commit_settings,
        !           245:        mulaw_expand,
        !           246:        mulaw_compress,
        !           247:        aria_start_output,
        !           248:        aria_start_input,
        !           249:        aria_halt_input,
        !           250:        aria_halt_output,
        !           251:        aria_cont,
        !           252:        aria_cont,
        !           253:        aria_speaker_ctl,
        !           254:        aria_getdev,
        !           255:        aria_setfd,
        !           256:        aria_mixer_set_port,
        !           257:        aria_mixer_get_port,
        !           258:        aria_mixer_query_devinfo,
        !           259:        1,      /* full-duplex */
        !           260:        0,
        !           261:        NULL,
        !           262:        NULL
        !           263: };
        !           264:
        !           265: /*
        !           266:  * Probe / attach routines.
        !           267:  */
        !           268:
        !           269: /*
        !           270:  * Probe for the aria hardware.
        !           271:  */
        !           272: int
        !           273: ariaprobe(parent, self, aux)
        !           274:        struct device *parent, *self;
        !           275:        void *aux;
        !           276: {
        !           277:        register struct aria_softc *sc = (void *)self;
        !           278:        register struct isa_attach_args *ia = aux;
        !           279:         struct cfdata *cf = sc->sc_dev.dv_cfdata;
        !           280:        register u_short iobase = ia->ia_iobase;
        !           281:        static u_char irq_conf[11] = {
        !           282:            -1, -1, 0x01, -1, -1, 0x02, -1, 0x04, -1, 0x01, 0x08
        !           283:        };
        !           284:        int i,j;
        !           285:        int flags = cf->cf_flags;
        !           286:
        !           287:        if (!ARIA_BASE_VALID(ia->ia_iobase)) {
        !           288:                printf("aria: configured iobase %d invalid\n", ia->ia_iobase);
        !           289:                return 0;
        !           290:        }
        !           291:        sc->sc_iobase = iobase;
        !           292:
        !           293:        if (!ARIA_IRQ_VALID(ia->ia_irq)) {
        !           294:                printf("aria: configured irq %d invalid\n", ia->ia_irq);
        !           295:                return 0;
        !           296:        }
        !           297:
        !           298:        sc->sc_irq = ia->ia_irq;
        !           299:
        !           300:        if (flags & ARIAR_PROMETHEUS_KLUDGE)
        !           301:                aria_prometheus_kludge(ia);
        !           302:
        !           303:        if (aria_reset(sc) != 0) {
        !           304:                DPRINTF(("aria: aria probe failed\n"));
        !           305:                return 0;
        !           306:        }
        !           307:
        !           308:        ia->ia_iosize = ARIADSP_NPORT;
        !           309:        return 1;
        !           310: }
        !           311:
        !           312:
        !           313:
        !           314: /*
        !           315:  * I didn't call this a kludge for
        !           316:  * nothing.  This is cribbed from
        !           317:  * ariainit, the author of that
        !           318:  * disassembled some code to discover
        !           319:  * how to set up the initial values of
        !           320:  * the card.  Without this, the card
        !           321:  * is dead. (It will not respond to _any_
        !           322:  * input at all.)
        !           323:  *
        !           324:  * ariainit can be found (ftp) at:
        !           325:  * ftp://ftp.wi.leidenuniv.nl/pub/audio/aria/programming/contrib/ariainit.zip
        !           326:  * currently.
        !           327:  */
        !           328:
        !           329: void
        !           330: aria_prometheus_kludge(ia)
        !           331:        register struct isa_attach_args *ia;
        !           332: {
        !           333:        int     i, j;
        !           334:        u_short end;
        !           335:        u_short rba = ia->ia_iobase;
        !           336:
        !           337:        DPRINTF(("aria_prometheus_kludge\n"));
        !           338:
        !           339: /* Begin Config Sequence */
        !           340:
        !           341:         outb(0x204, 0x4c);
        !           342:         outb(0x205, 0x42);
        !           343:         outb(0x206, 0x00);
        !           344:         outw(0x200, 0x0f);
        !           345:         outb(0x201, 0x00);
        !           346:         outw(0x200, 0x02);
        !           347:         outb(0x201, rba>>2);
        !           348:
        !           349: /* These next three lines set up the iobase, and the irq; and disable the drq.  */
        !           350:
        !           351:        aria_do_kludge(0x111, ((ia->ia_iobase-0x280)>>2)+0xA0, 0xbf, 0xa0, rba);
        !           352:        aria_do_kludge(0x011, ia->ia_irq-6, 0xf8, 0x00, rba);
        !           353:        aria_do_kludge(0x011, 0x00, 0xef, 0x00, rba);
        !           354:
        !           355: /* The rest of these lines just disable everything else */
        !           356:
        !           357:        aria_do_kludge(0x113, 0x00, 0x88, 0x00, rba);
        !           358:        aria_do_kludge(0x013, 0x00, 0xf8, 0x00, rba);
        !           359:        aria_do_kludge(0x013, 0x00, 0xef, 0x00, rba);
        !           360:        aria_do_kludge(0x117, 0x00, 0x88, 0x00, rba);
        !           361:        aria_do_kludge(0x017, 0x00, 0xff, 0x00, rba);
        !           362:
        !           363: /* End Sequence */
        !           364:
        !           365:        outb(0x200, 0x0f);
        !           366:        end = inb(rba);
        !           367:        outw(0x200, 0x0f);
        !           368:        outb(0x201, end|0x80);
        !           369:        inb(0x200);
        !           370: /*
        !           371:  * This delay is necessary for some reason,
        !           372:  * at least it would crash, and sometimes not
        !           373:  * probe properly if it did not exist.
        !           374:  */
        !           375:        delay(1000000);
        !           376: }
        !           377:
        !           378: void
        !           379: aria_do_kludge(func, bits, and, or, rba)
        !           380:        u_short func;
        !           381:        u_short bits;
        !           382:        u_short and;
        !           383:        u_short or;
        !           384:        u_short rba;
        !           385: {
        !           386:        u_int i;
        !           387:        if (func & 0x100) {
        !           388:                func &= ~0x100;
        !           389:                if (bits) {
        !           390:                        outw(0x200, func-1);
        !           391:                        outb(0x201, bits);
        !           392:                }
        !           393:        } else
        !           394:                or |= bits;
        !           395:
        !           396:        outb(0x200, func);
        !           397:        i = inb(rba);
        !           398:        outw(0x200, func);
        !           399:        outb(0x201, (i&and) | or);
        !           400: }
        !           401:
        !           402: /*
        !           403:  * Attach hardware to driver, attach hardware driver to audio
        !           404:  * pseudo-device driver.
        !           405:  */
        !           406: void
        !           407: ariaattach(parent, self, aux)
        !           408:        struct device *parent, *self;
        !           409:        void *aux;
        !           410: {
        !           411:        register struct aria_softc *sc = (struct aria_softc *)self;
        !           412:        struct isa_attach_args *ia = (struct isa_attach_args *)aux;
        !           413:        register u_short iobase = ia->ia_iobase;
        !           414:        register u_short i;
        !           415:        int err;
        !           416:
        !           417:        sc->sc_ih = isa_intr_establish(ia->ia_ic, ia->ia_irq, IST_EDGE,
        !           418:            IPL_AUDIO, aria_intr, sc, sc->sc_dev.dv_xname);
        !           419:
        !           420:        i = aria_getdspmem(iobase, ARIAA_HARDWARE_A);
        !           421:
        !           422:        sc->sc_hardware  = 0;
        !           423:        sc->sc_hardware |= ((i>>13)&0x01==1)?ARIA_TELEPHONE:0;
        !           424:        sc->sc_hardware |= (((i>>5)&0x07)==0x04)?ARIA_MIXER:0;
        !           425:        sc->sc_hardware |= (aria_getdspmem(iobase, ARIAA_MODEL_A)==1)?ARIA_MODEL:0;
        !           426:
        !           427:        sc->sc_open       = 0;
        !           428:        sc->sc_play       = 0;
        !           429:        sc->sc_record     = 0;
        !           430:        sc->sc_rate       = 7875;
        !           431:        sc->sc_chans      = 1;
        !           432:        sc->sc_change     = 1;
        !           433:        sc->sc_blocksize  = 1024;
        !           434:        sc->sc_precision  = 8;
        !           435:         sc->sc_rintr      = 0;
        !           436:         sc->sc_rarg       = 0;
        !           437:         sc->sc_pintr      = 0;
        !           438:         sc->sc_parg       = 0;
        !           439:        sc->gain[0]       = 127;
        !           440:        sc->gain[1]       = 127;
        !           441:
        !           442:        for (i=0; i<6; i++) {
        !           443:                if (i == ARIAMIX_TEL_LVL)
        !           444:                        sc->aria_mix[i].num_channels = 1;
        !           445:                else
        !           446:                        sc->aria_mix[i].num_channels = 2;
        !           447:                sc->aria_mix[i].level[0] = 127;
        !           448:                sc->aria_mix[i].level[1] = 127;
        !           449:        }
        !           450:
        !           451:        sc->ariamix_master.num_channels = 2;
        !           452:        sc->ariamix_master.level[0] = 222;
        !           453:        sc->ariamix_master.level[1] = 222;
        !           454:        sc->ariamix_master.bass[0] = 127;
        !           455:        sc->ariamix_master.bass[1] = 127;
        !           456:        sc->ariamix_master.treble[0] = 127;
        !           457:        sc->ariamix_master.treble[1] = 127;
        !           458:        sc->aria_mix_source = 0;
        !           459:
        !           460:        sc->sc_change = 1;
        !           461:        aria_commit_settings(sc); /* so that my cdplayer is at the 'right' vol */
        !           462:
        !           463:        printf(": dsp %s", (ARIA_MODEL&sc->sc_hardware)?"SC18026":"SC18025");
        !           464:        if (ARIA_TELEPHONE&sc->sc_hardware)
        !           465:                printf(", tel");
        !           466:        if (ARIA_MIXER&sc->sc_hardware)
        !           467:                printf(", SC18075 mixer");
        !           468:        printf("\n");
        !           469:
        !           470:        snprintf(aria_device.version, sizeof aria_device.version, "%s",
        !           471:            (ARIA_MODEL&sc->sc_hardware?"SC18026":"SC18025"));
        !           472:
        !           473:        if ((err = audio_hardware_attach(&aria_hw_if, sc)) != 0)
        !           474:                printf("aria: could not attach to audio pseudo-device driver (%d)\n", err);
        !           475: }
        !           476:
        !           477: /*
        !           478:  * Various routines to interface to higher level audio driver
        !           479:  */
        !           480:
        !           481: int
        !           482: ariaopen(dev, flags)
        !           483:        dev_t dev;
        !           484:        int flags;
        !           485: {
        !           486:        struct aria_softc *sc;
        !           487:        register u_short iobase = sc->sc_iobase;
        !           488:        int unit = AUDIOUNIT(dev);
        !           489:        short err;
        !           490:
        !           491:        DPRINTF(("ariaopen() called\n"));
        !           492:
        !           493:        if (unit >= aria_cd.cd_ndevs)
        !           494:                return ENXIO;
        !           495:
        !           496:        sc = aria_cd.cd_devs[unit];
        !           497:
        !           498:        if (!sc || sc->sc_open != 0)
        !           499:                return ENXIO;
        !           500:
        !           501:        sc->sc_open  = 0;
        !           502:        if (flags&FREAD)
        !           503:                sc->sc_open |= ARIAR_OPEN_RECORD;
        !           504:        if (flags&FWRITE)
        !           505:                sc->sc_open |= ARIAR_OPEN_PLAY;
        !           506:        sc->sc_play  = 0;
        !           507:        sc->sc_record= 0;
        !           508:        sc->sc_rintr = 0;
        !           509:        sc->sc_rarg  = 0;
        !           510:        sc->sc_pintr = 0;
        !           511:        sc->sc_parg  = 0;
        !           512:        sc->sc_change= 1;
        !           513:
        !           514:        return 0;
        !           515: }
        !           516:
        !           517: int
        !           518: aria_getdev(addr, retp)
        !           519:        void *addr;
        !           520:        struct audio_device *retp;
        !           521: {
        !           522:        *retp = aria_device;
        !           523:        return 0;
        !           524: }
        !           525:
        !           526: #ifdef AUDIO_DEBUG
        !           527: void
        !           528: aria_printsc(struct aria_softc *sc)
        !           529: {
        !           530:        printf("open %x dmachan %d irq %d iobase %x nintr %d\n", sc->sc_open, sc->sc_drq,
        !           531:                sc->sc_irq, sc->sc_iobase, sc->sc_interrupts);
        !           532:        printf("irate %d encoding %x chans %d\n", sc->sc_rate, sc->encoding,
        !           533:                sc->sc_chans);
        !           534:        printf("\n");
        !           535: }
        !           536: #endif
        !           537:
        !           538:
        !           539: /*
        !           540:  * Various routines to interface to higher level audio driver
        !           541:  */
        !           542:
        !           543: int
        !           544: aria_set_sr(addr, sr)
        !           545:        void *addr;
        !           546:        u_long sr;
        !           547: {
        !           548:         struct aria_softc *sc = addr;
        !           549:
        !           550:        if (sr<=9000)
        !           551:                sr = 7875;
        !           552:        else if (sr<=15000)
        !           553:                sr = 11025;
        !           554:        else if (sr<=20000)
        !           555:                sr = 15750;
        !           556:        else if (sr<=25000)
        !           557:                sr = 22050;
        !           558:        else if (sr<=40000)
        !           559:                sr = 31500;
        !           560:        else
        !           561:                sr = 44100;
        !           562:
        !           563:        sc->sc_rate = sr;
        !           564:        return 0;
        !           565: }
        !           566:
        !           567: u_long
        !           568: aria_get_sr(addr)
        !           569:        void *addr;
        !           570: {
        !           571:         struct aria_softc *sc = addr;
        !           572:        return sc->sc_rate;
        !           573: }
        !           574:
        !           575: int
        !           576: aria_query_encoding(addr, fp)
        !           577:     void *addr;
        !           578:     struct audio_encoding *fp;
        !           579: {
        !           580:        register struct aria_softc *sc = addr;
        !           581:
        !           582:        switch (fp->index) {
        !           583:                case 0:
        !           584:                        strlcpy(fp->name, AudioEmulaw, sizeof fp->name);
        !           585:                        fp->format_id = AUDIO_ENCODING_ULAW;
        !           586:                        break;
        !           587:                case 1:
        !           588:                        strlcpy(fp->name, AudioEpcm16, sizeof fp->name);
        !           589:                        fp->format_id = AUDIO_ENCODING_PCM16;
        !           590:                        break;
        !           591:                default:
        !           592:                        return(EINVAL);
        !           593:                /*NOTREACHED*/
        !           594:        }
        !           595:
        !           596:        return (0);
        !           597: }
        !           598:
        !           599: int
        !           600: aria_set_format(addr, enc, precision)
        !           601:        void *addr;
        !           602:        u_int enc, prec;
        !           603: {
        !           604:         register struct aria_softc *sc = addr;
        !           605:
        !           606:        DPRINTF(("aria_set_format\n"));
        !           607:
        !           608:         switch(enc){
        !           609:         case AUDIO_ENCODING_ULAW:
        !           610:         case AUDIO_ENCODING_PCM16:
        !           611:        case AUDIO_ENCODING_PCM8:
        !           612:                break;
        !           613:         default:
        !           614:                 return (EINVAL);
        !           615:         }
        !           616:
        !           617:        if (prec!=8 && prec!=16)
        !           618:                return (EINVAL);
        !           619:
        !           620:        if (sc->encoding!=AUDIO_ENCODING_PCM16 && prec==16)
        !           621:                return (EINVAL);
        !           622:
        !           623:        sc->sc_encoding = enc;
        !           624:        sc->sc_precision = prec;
        !           625:         return (0);
        !           626: }
        !           627:
        !           628: int
        !           629: aria_get_encoding(addr)
        !           630:        void *addr;
        !           631: {
        !           632:         register struct aria_softc *sc = addr;
        !           633:
        !           634:        DPRINTF(("aria_get_encoding\n"));
        !           635:
        !           636:         return(sc->encoding);
        !           637: }
        !           638:
        !           639: int
        !           640: aria_get_precision(addr)
        !           641:        void *addr;
        !           642: {
        !           643:         struct aria_softc *sc = addr;
        !           644:
        !           645:        DPRINTF(("aria_get_precision\n"));
        !           646:
        !           647:        return sc->sc_precision;
        !           648: }
        !           649:
        !           650: int
        !           651: aria_set_channels(addr, chans)
        !           652:        void *addr;
        !           653:        int chans;
        !           654: {
        !           655:         struct aria_softc *sc = addr;
        !           656:
        !           657:        DPRINTF(("aria_set_channels\n"));
        !           658:
        !           659:        if (chans != 1 && chans != 2)
        !           660:                return EINVAL;
        !           661:
        !           662:        sc->sc_chans = chans;
        !           663:
        !           664:        return(0);
        !           665: }
        !           666:
        !           667: int
        !           668: aria_get_channels(addr)
        !           669:        void *addr;
        !           670: {
        !           671:         struct aria_softc *sc = addr;
        !           672:
        !           673:        DPRINTF(("aria_get_channels\n"));
        !           674:
        !           675:        return sc->sc_chans;
        !           676: }
        !           677:
        !           678: /*
        !           679:  * There is only one way to output on
        !           680:  * this card.
        !           681:  */
        !           682: int
        !           683: aria_set_out_port(addr, port)
        !           684:        void *addr;
        !           685:        int port;
        !           686: {
        !           687:        DPRINTF(("aria_set_out_port\n"));
        !           688:        return(0);
        !           689: }
        !           690:
        !           691: int
        !           692: aria_get_out_port(addr)
        !           693:        void *addr;
        !           694: {
        !           695:        DPRINTF(("aria_get_out_port\n"));
        !           696:        return(ARIAMIX_OUT_LVL);
        !           697: }
        !           698:
        !           699:
        !           700: int
        !           701: aria_set_in_port(addr, port)
        !           702:        void *addr;
        !           703:        int port;
        !           704: {
        !           705:        register struct aria_softc *sc = addr;
        !           706:
        !           707:        DPRINTF(("aria_set_in_port\n"));
        !           708:
        !           709:        if (port<0 || port>6)
        !           710:                return ENXIO;
        !           711:
        !           712:        sc->aria_mix_source = port;
        !           713:        return(0);
        !           714: }
        !           715:
        !           716: int
        !           717: aria_get_in_port(addr)
        !           718:        void *addr;
        !           719: {
        !           720:        register struct aria_softc *sc = addr;
        !           721:
        !           722:        DPRINTF(("aria_get_in_port\n"));
        !           723:
        !           724:        return(sc->aria_mix_source);
        !           725: }
        !           726:
        !           727: /*
        !           728:  * XXX -- to be done
        !           729:  *  I should probably just add a mixer thing, and
        !           730:  *  access it through here.
        !           731:  */
        !           732: int
        !           733: aria_speaker_ctl(addr, newstate)
        !           734:        void *addr;
        !           735:        int newstate;
        !           736: {
        !           737:        return(0);
        !           738: }
        !           739:
        !           740: /*
        !           741:  * Store blocksize in words (what the chipset
        !           742:  * understands), but report and take values
        !           743:  * in bytes.
        !           744:  */
        !           745:
        !           746: int
        !           747: aria_round_blocksize(addr, blk)
        !           748:        void *addr;
        !           749:        int blk;
        !           750: {
        !           751:        int i;
        !           752:         struct aria_softc *sc = addr;
        !           753:        for (i=64; i<1024; i*=2)
        !           754:                if (blk <= i)
        !           755:                        break;
        !           756:        sc->sc_blocksize = i;
        !           757:        sc->sc_change = 1;
        !           758:        return(i);
        !           759: }
        !           760:
        !           761: /*
        !           762:  * This is where all of the twiddling goes on.
        !           763:  */
        !           764:
        !           765: int
        !           766: aria_commit_settings(addr)
        !           767:        void *addr;
        !           768: {
        !           769:         struct aria_softc *sc = addr;
        !           770:        register u_short iobase = sc->sc_iobase;
        !           771:        u_char tones[16] = { 7, 6, 5, 4, 3, 2, 1, 0, 8, 9, 10, 11, 12, 13, 14, 15 };
        !           772:        u_short format;
        !           773:        u_short left, right;
        !           774:        u_short samp;
        !           775:        u_char i;
        !           776:
        !           777:        DPRINTF(("aria_commit_settings\n"));
        !           778:
        !           779:        switch (sc->sc_rate) {
        !           780:                case  7875: format = 0x00; samp = 0x60; break;
        !           781:                case 11025: format = 0x00; samp = 0x40; break;
        !           782:                case 15750: format = 0x10; samp = 0x60; break;
        !           783:                case 22050: format = 0x10; samp = 0x40; break;
        !           784:                case 31500: format = 0x10; samp = 0x20; break;
        !           785:                case 44100: format = 0x20; samp = 0x00; break;
        !           786:                default:    format = 0x00; samp = 0x40; break;
        !           787:        }
        !           788:
        !           789:        format |= (sc->sc_chans==2)?1:0;
        !           790:        format |= (sc->sc_precision==16)?2:0;
        !           791:
        !           792:        aria_sendcmd(iobase, ARIADSPC_FORMAT, format, -1, -1);
        !           793:        outw(iobase+ARIADSP_CONTROL, (inw(iobase+ARIADSP_STATUS)&~0x60)|samp); /* Addition parm for sample rate */
        !           794:
        !           795:        if (sc->sc_hardware&ARIA_MIXER) {
        !           796:                for (i=0; i<6; i++) {
        !           797:                        u_char source;
        !           798:                        switch(i) {
        !           799:                        case ARIAMIX_MIC_LVL:     source = 0x0001; break;
        !           800:                        case ARIAMIX_CD_LVL:      source = 0x0002; break;
        !           801:                        case ARIAMIX_LINE_IN_LVL: source = 0x0008; break;
        !           802:                        case ARIAMIX_TEL_LVL:     source = 0x0020; break;
        !           803:                        case ARIAMIX_AUX_LVL:     source = 0x0010; break;
        !           804:                        case ARIAMIX_DAC_LVL:     source = 0x0004; break;
        !           805:                        default:               source = 0x0000; break;
        !           806:                        }
        !           807:
        !           808:                        if (source != 0x0000 && source != 0x0004) {
        !           809:                                if (sc->aria_mix[i].mute == 1)
        !           810:                                        aria_sendcmd(iobase, ARIADSPC_INPMONMODE, source, 3, -1);
        !           811:                                else
        !           812:                                        aria_sendcmd(iobase, ARIADSPC_INPMONMODE, source, (sc->aria_mix[i].num_channels==2)?0:1, -1);
        !           813:
        !           814:                                aria_sendcmd(iobase, ARIADSPC_INPMONMODE, 0x8000|source, (sc->aria_mix[i].num_channels==2)?0:1, -1);
        !           815:                                aria_sendcmd(iobase, ARIADSPC_MIXERVOL, source, sc->aria_mix[i].level[0] << 7, sc->aria_mix[i].level[1] << 7);
        !           816:                        }
        !           817:
        !           818:                        if (sc->aria_mix_source == i) {
        !           819:                                aria_sendcmd(iobase, ARIADSPC_ADCSOURCE, source, -1, -1);
        !           820:
        !           821:                                if (sc->sc_open & ARIAR_OPEN_RECORD)
        !           822:                                        aria_sendcmd(iobase, ARIADSPC_ADCCONTROL, 1, -1, -1);
        !           823:                                else
        !           824:                                        aria_sendcmd(iobase, ARIADSPC_ADCCONTROL, 0, -1, -1);
        !           825:                        }
        !           826:                }
        !           827:
        !           828:                if (sc->sc_chans==2) {
        !           829:                        aria_sendcmd(iobase, ARIADSPC_CHAN_VOL, (sc->gain[0]+sc->gain[1])/2, -1, -1);
        !           830:                        aria_sendcmd(iobase, ARIADSPC_CHAN_PAN, (sc->gain[0]-sc->gain[1])/4+0x40, -1, -1);
        !           831:                } else {
        !           832:                        aria_sendcmd(iobase, ARIADSPC_CHAN_VOL, sc->gain[0], -1, -1);
        !           833:                        aria_sendcmd(iobase, ARIADSPC_CHAN_PAN, 0x40, -1, -1);
        !           834:                }
        !           835:
        !           836:                /* aria_sendcmd(iobase, ARIADSPC_MASMONMODE, (sc->ariamix_master.num_channels==2)?0:1 | (1<<8), -1, -1); */
        !           837:                aria_sendcmd(iobase, ARIADSPC_MASMONMODE, (sc->ariamix_master.num_channels==2)?0:1, -1, -1);
        !           838:
        !           839:                aria_sendcmd(iobase, ARIADSPC_MIXERVOL, 0x0004, sc->ariamix_master.level[0] << 7, sc->ariamix_master.level[1] << 7);
        !           840:
        !           841:                /* Convert treb/bass from byte to soundcard style */
        !           842:
        !           843:                left  = tones[(sc->ariamix_master.bass[0]>>4)&0x0f]<<8 | tones[(sc->ariamix_master.treble[0]>>4)&0x0f];
        !           844:                right = tones[(sc->ariamix_master.bass[1]>>4)&0x0f]<<8 | tones[(sc->ariamix_master.treble[1]>>4)&0x0f];
        !           845:
        !           846:                aria_sendcmd(iobase, ARIADSPC_TONE, left, right, -1);
        !           847:        }
        !           848:
        !           849:        if (sc->sc_change != 0)
        !           850:                aria_sendcmd(iobase, ARIADSPC_BLOCKSIZE, sc->sc_blocksize/2, -1, -1);
        !           851:
        !           852: /*
        !           853:  * If we think that the card is recording or playing, start it up again here.
        !           854:  * Some of the previous commands turn the channels off.
        !           855:  */
        !           856:
        !           857:        if (sc->sc_record&(1<<ARIAR_RECORD_CHAN)) {
        !           858:                aria_sendcmd(iobase, ARIADSPC_START_REC, ARIAR_PLAY_CHAN, -1, -1);
        !           859:                sc->sc_play |= (1<<ARIAR_RECORD_CHAN);
        !           860:        }
        !           861:
        !           862:        if (sc->sc_play&(1<<ARIAR_PLAY_CHAN)) {
        !           863:                aria_sendcmd(iobase, ARIADSPC_START_PLAY, ARIAR_PLAY_CHAN, -1, -1);
        !           864:                sc->sc_play |= (1<<ARIAR_PLAY_CHAN);
        !           865:        }
        !           866:
        !           867:        sc->sc_change = 0;
        !           868:
        !           869:        return(0);
        !           870: }
        !           871:
        !           872: void
        !           873: ariaclose(addr)
        !           874:        void *addr;
        !           875: {
        !           876:         struct aria_softc *sc = addr;
        !           877:        register u_int iobase = sc->sc_iobase;
        !           878:
        !           879:        DPRINTF(("aria_close sc=0x%x\n", sc));
        !           880:
        !           881:         sc->spkr_state = SPKR_OFF;
        !           882:         sc->sc_rintr = 0;
        !           883:         sc->sc_pintr = 0;
        !           884:        sc->sc_rdiobuffer = 0;
        !           885:        sc->sc_pdiobuffer = 0;
        !           886:
        !           887:        if (sc->sc_play&(1<<ARIAR_PLAY_CHAN) && sc->sc_open & ARIAR_OPEN_PLAY) {
        !           888:                aria_sendcmd(iobase, ARIADSPC_STOP_PLAY, ARIAR_PLAY_CHAN, -1, -1);
        !           889:                sc->sc_play &= ~(1<<ARIAR_PLAY_CHAN);
        !           890:        }
        !           891:
        !           892:        if (sc->sc_record&(1<<ARIAR_RECORD_CHAN) && sc->sc_open & ARIAR_OPEN_RECORD) {
        !           893:                aria_sendcmd(iobase, ARIADSPC_STOP_REC, ARIAR_RECORD_CHAN, -1, -1);
        !           894:                sc->sc_record &= ~(1<<ARIAR_RECORD_CHAN);
        !           895:        }
        !           896:
        !           897:        sc->sc_open = 0;
        !           898:
        !           899:        if (aria_reset(sc) != 0) {
        !           900:                delay(500);
        !           901:                aria_reset(sc);
        !           902:        }
        !           903: }
        !           904:
        !           905: /*
        !           906:  * Reset the hardware.
        !           907:  */
        !           908:
        !           909: int
        !           910: aria_reset(sc)
        !           911:        register struct aria_softc *sc;
        !           912: {
        !           913:        register u_short iobase = sc->sc_iobase;
        !           914:        int fail=0;
        !           915:
        !           916:        outw(iobase + ARIADSP_CONTROL, ARIAR_ARIA_SYNTH|ARIAR_SR22K|ARIAR_DSPINTWR);
        !           917:        aria_putdspmem(iobase, 0x6102, 0);
        !           918:
        !           919:        fail |= aria_sendcmd(iobase, ARIADSPC_SYSINIT, 0x0000, 0x0000, 0x0000);
        !           920:
        !           921:        while (aria_getdspmem(iobase, ARIAA_TASK_A) != 1)
        !           922:                ;
        !           923:
        !           924:        outw(iobase+ARIADSP_CONTROL, ARIAR_ARIA_SYNTH|ARIAR_SR22K|ARIAR_DSPINTWR|ARIAR_PCINTWR);
        !           925:        fail |= aria_sendcmd(iobase, ARIADSPC_MODE, ARIAV_MODE_NO_SYNTH,-1,-1);
        !           926:
        !           927:        return (fail);
        !           928: }
        !           929:
        !           930: /*
        !           931:  * Lower-level routines
        !           932:  */
        !           933:
        !           934: u_short
        !           935: aria_putdspmem(iobase, loc, val)
        !           936:        register u_short iobase;
        !           937:        register u_short loc;
        !           938:        register u_short val;
        !           939: {
        !           940:        outw(iobase + ARIADSP_DMAADDRESS, loc);
        !           941:        outw(iobase + ARIADSP_DMADATA, val);
        !           942: }
        !           943:
        !           944: u_short
        !           945: aria_getdspmem(iobase, loc)
        !           946:        register u_short iobase;
        !           947:        register u_short loc;
        !           948: {
        !           949:        outw(iobase+ARIADSP_DMAADDRESS, loc);
        !           950:        return inw(iobase+ARIADSP_DMADATA);
        !           951: }
        !           952:
        !           953: /*
        !           954:  * aria_sendcmd()
        !           955:  *  each full DSP command is unified into this
        !           956:  *  function.
        !           957:  */
        !           958:
        !           959: int
        !           960: aria_sendcmd(iobase, command, arg1, arg2, arg3)
        !           961:        u_short iobase;
        !           962:        u_short command;
        !           963:        int arg1;
        !           964:        int arg2;
        !           965:        int arg3;
        !           966: {
        !           967:        int i, fail = 0;
        !           968:
        !           969:        for (i = ARIAR_NPOLL; (inw(iobase + ARIADSP_STATUS) & ARIAR_BUSY) != 0 && i>0; i-- )
        !           970:                ;
        !           971:
        !           972:        fail |= (inw(iobase + ARIADSP_STATUS) & ARIAR_BUSY)==0?0:1;
        !           973:        outw(iobase + ARIADSP_WRITE, (u_short) command);
        !           974:
        !           975:        if (arg1 != -1) {
        !           976:                for (i = ARIAR_NPOLL; (inw(iobase + ARIADSP_STATUS) & ARIAR_BUSY) != 0 && i>0; i-- )
        !           977:                        ;
        !           978:
        !           979:                fail |= (inw(iobase + ARIADSP_STATUS) & ARIAR_BUSY)==0?0:2;
        !           980:                outw(iobase + ARIADSP_WRITE, (u_short) arg1);
        !           981:        }
        !           982:
        !           983:        if (arg2 != -1) {
        !           984:                for (i = ARIAR_NPOLL; (inw(iobase + ARIADSP_STATUS) & ARIAR_BUSY) != 0 && i>0; i-- )
        !           985:                        ;
        !           986:
        !           987:                fail |= (inw(iobase + ARIADSP_STATUS) & ARIAR_BUSY)==0?0:4;
        !           988:                outw(iobase + ARIADSP_WRITE, (u_short) arg2);
        !           989:        }
        !           990:
        !           991:        if (arg3 != -1) {
        !           992:                for (i = ARIAR_NPOLL; (inw(iobase + ARIADSP_STATUS) & ARIAR_BUSY) != 0 && i>0; i-- )
        !           993:                        ;
        !           994:
        !           995:                fail |= (inw(iobase + ARIADSP_STATUS) & ARIAR_BUSY)==0?0:8;
        !           996:                outw(iobase + ARIADSP_WRITE, (u_short) arg3);
        !           997:        }
        !           998:
        !           999:        for (i = ARIAR_NPOLL; (inw(iobase + ARIADSP_STATUS) & ARIAR_BUSY) != 0 && i>0; i-- )
        !          1000:                ;
        !          1001:
        !          1002:         fail |= (inw(iobase + ARIADSP_STATUS) & ARIAR_BUSY)==0?0:16;
        !          1003:        outw(iobase + ARIADSP_WRITE, (u_short) ARIADSPC_TERM);
        !          1004:
        !          1005: #ifdef AUDIO_DEBUG
        !          1006:        if (fail) {
        !          1007:                ++ariaerr.sendcmd;
        !          1008:                DPRINTF(("aria_sendcmd: failure=(%d) cmd=(0x%x) fail=(0x%x)\n", ariaerr.sendcmd, command, fail));
        !          1009:                return -1;
        !          1010:        }
        !          1011: #else
        !          1012:        if (fail != 0) {
        !          1013:                ++ariaerr.sendcmd;
        !          1014:                return -1;
        !          1015:        }
        !          1016: #endif
        !          1017:
        !          1018:        return 0;
        !          1019: }
        !          1020:
        !          1021: int
        !          1022: aria_halt_input(addr)
        !          1023:        void *addr;
        !          1024: {
        !          1025:        register struct aria_softc *sc = addr;
        !          1026:
        !          1027:        DPRINTF(("aria_halt_input\n"));
        !          1028:
        !          1029:        if (sc->sc_record&(1<<0)) {
        !          1030:                aria_sendcmd(sc->sc_iobase, ARIADSPC_STOP_REC, 0, -1, -1);
        !          1031:                sc->sc_record &= ~(1<<0);
        !          1032:        }
        !          1033:
        !          1034:        return(0);
        !          1035: }
        !          1036:
        !          1037: int
        !          1038: aria_halt_output(addr)
        !          1039:        void *addr;
        !          1040: {
        !          1041:        register struct aria_softc *sc = addr;
        !          1042:
        !          1043:        DPRINTF(("aria_halt_output\n"));
        !          1044:
        !          1045:        if (sc->sc_play & (1<<1)) {
        !          1046:                aria_sendcmd(sc->sc_iobase, ARIADSPC_STOP_PLAY, 1, -1, -1);
        !          1047:                sc->sc_play &= ~(1<<1);
        !          1048:        }
        !          1049:
        !          1050:        return(0);
        !          1051: }
        !          1052:
        !          1053: /*
        !          1054:  * This is not called in dev/audio.c?
        !          1055:  */
        !          1056: int
        !          1057: aria_cont(addr)
        !          1058:        void *addr;
        !          1059: {
        !          1060:        register struct aria_softc *sc = addr;
        !          1061:
        !          1062:        DPRINTF(("aria_cont\n"));
        !          1063:
        !          1064:        if (!(sc->sc_record&(1<<0)) && (sc->sc_open&ARIAR_OPEN_RECORD)) {
        !          1065:                aria_sendcmd(sc->sc_iobase, ARIADSPC_START_REC,  ARIAR_RECORD_CHAN, -1, -1);
        !          1066:                sc->sc_record |= ~(1<<ARIAR_RECORD_CHAN);
        !          1067:        }
        !          1068:
        !          1069:        if (!(sc->sc_play&(1<<ARIAR_PLAY_CHAN)) && (sc->sc_open&ARIAR_OPEN_PLAY)) {
        !          1070:                aria_sendcmd(sc->sc_iobase, ARIADSPC_START_PLAY, 1, -1, -1);
        !          1071:                sc->sc_play |= ~(1<<ARIAR_PLAY_CHAN);
        !          1072:        }
        !          1073:
        !          1074:        return(0);
        !          1075: }
        !          1076:
        !          1077: /*
        !          1078:  * Here we just set up the buffers.  If we receive
        !          1079:  * an interrupt without these set, it is ignored.
        !          1080:  */
        !          1081:
        !          1082: int
        !          1083: aria_start_input(addr, p, cc, intr, arg)
        !          1084:        void *addr;
        !          1085:        void *p;
        !          1086:        int cc;
        !          1087:        void (*intr)();
        !          1088:        void *arg;
        !          1089: {
        !          1090:        register struct aria_softc *sc = addr;
        !          1091:        register int i;
        !          1092:
        !          1093:        DPRINTF(("aria_start_input %d @ %x\n", cc, p));
        !          1094:
        !          1095:        if (cc != sc->sc_blocksize) {
        !          1096:                DPRINTF(("aria_start_input reqsize %d not sc_blocksize %d\n",
        !          1097:                        cc, sc->sc_blocksize));
        !          1098:                return EINVAL;
        !          1099:        }
        !          1100:
        !          1101:        sc->sc_rarg = arg;
        !          1102:        sc->sc_rintr = intr;
        !          1103:        sc->sc_rdiobuffer = p;
        !          1104:
        !          1105:        if (!(sc->sc_record&(1<<0))) {
        !          1106:                aria_sendcmd(sc->sc_iobase, ARIADSPC_START_REC,  0, -1, -1);
        !          1107:                sc->sc_record |= (1<<0);
        !          1108:        }
        !          1109:
        !          1110:        return 0;
        !          1111: }
        !          1112:
        !          1113: int
        !          1114: aria_start_output(addr, p, cc, intr, arg)
        !          1115:        void *addr;
        !          1116:        void *p;
        !          1117:        int cc;
        !          1118:        void (*intr)();
        !          1119:        void *arg;
        !          1120: {
        !          1121:        register struct aria_softc *sc = addr;
        !          1122:        register int i;
        !          1123:
        !          1124:        DPRINTF(("aria_start_output %d @ %x\n", cc, p));
        !          1125:
        !          1126:        if (cc != sc->sc_blocksize) {
        !          1127:                DPRINTF(("aria_start_output reqsize %d not sc_blocksize %d\n",
        !          1128:                        cc, sc->sc_blocksize));
        !          1129:                return EINVAL;
        !          1130:        }
        !          1131:
        !          1132:        sc->sc_parg = arg;
        !          1133:        sc->sc_pintr = intr;
        !          1134:        sc->sc_pdiobuffer = p;
        !          1135:
        !          1136:        if (!(sc->sc_play&(1<<1))) {
        !          1137:                aria_sendcmd(sc->sc_iobase, ARIADSPC_START_PLAY,  1, -1, -1);
        !          1138:                sc->sc_play |= (1<<1);
        !          1139:        }
        !          1140:
        !          1141:        return 0;
        !          1142: }
        !          1143:
        !          1144: /*
        !          1145:  * Process an interrupt.  This should be a
        !          1146:  * request (from the card) to write or read
        !          1147:  * samples.
        !          1148:  */
        !          1149: int
        !          1150: aria_intr(arg)
        !          1151:        void *arg;
        !          1152: {
        !          1153:        register struct  aria_softc *sc = arg;
        !          1154:        register u_short iobase = sc->sc_iobase;
        !          1155:        register u_short *pdata = sc->sc_pdiobuffer;
        !          1156:        register u_short *rdata = sc->sc_rdiobuffer;
        !          1157:        u_short address;
        !          1158:        int i;
        !          1159:
        !          1160:        if (inw(iobase) & 1 != 0x1)
        !          1161:                return 0;  /* not for us */
        !          1162:
        !          1163:        sc->sc_interrupts++;
        !          1164:
        !          1165:        DPRINTF(("aria_intr\n"));
        !          1166:
        !          1167:        if ((sc->sc_open & ARIAR_OPEN_PLAY) && (pdata!=NULL)) {
        !          1168:                DPRINTF(("aria_intr play=(%x)\n", pdata));
        !          1169:                address = 0x8000 - 2*(sc->sc_blocksize);
        !          1170:                address+= aria_getdspmem(iobase, ARIAA_PLAY_FIFO_A);
        !          1171:                outw(iobase+ARIADSP_DMAADDRESS, address);
        !          1172:                outsw(iobase + ARIADSP_DMADATA, pdata, sc->sc_blocksize/2);
        !          1173:                if (sc->sc_pintr != NULL)
        !          1174:                        (*sc->sc_pintr)(sc->sc_parg);
        !          1175:        }
        !          1176:
        !          1177:        if ((sc->sc_open & ARIAR_OPEN_RECORD) && (rdata!=NULL)) {
        !          1178:                DPRINTF(("aria_intr record=(%x)\n", rdata));
        !          1179:                address = 0x8000 - (sc->sc_blocksize);
        !          1180:                address+= aria_getdspmem(iobase, ARIAA_REC_FIFO_A);
        !          1181:                outw(iobase+ARIADSP_DMAADDRESS, address);
        !          1182:                insw(iobase + ARIADSP_DMADATA, rdata, sc->sc_blocksize/2);
        !          1183:                if (sc->sc_rintr != NULL)
        !          1184:                        (*sc->sc_rintr)(sc->sc_rarg);
        !          1185:        }
        !          1186:
        !          1187:        aria_sendcmd(iobase, ARIADSPC_TRANSCOMPLETE, -1, -1, -1);
        !          1188:
        !          1189:        return 1;
        !          1190: }
        !          1191:
        !          1192: int
        !          1193: aria_setfd(addr, flag)
        !          1194:        void *addr;
        !          1195:        int flag;
        !          1196: {
        !          1197: /*
        !          1198:  * okay return yes.  I'll assume that it will only
        !          1199:  * ask when the file open read/write...  Or before...
        !          1200:  */
        !          1201:        return(0);
        !          1202: }
        !          1203:
        !          1204: int
        !          1205: aria_mixer_set_port(addr, cp)
        !          1206:     void *addr;
        !          1207:     mixer_ctrl_t *cp;
        !          1208: {
        !          1209:        register struct aria_softc *sc = addr;
        !          1210:        int error = EINVAL;
        !          1211:
        !          1212:        DPRINTF(("aria_mixer_set_port\n"));
        !          1213:
        !          1214:        if (!(ARIA_MIXER&sc->sc_hardware))  /* This could be done better, no mixer still has some controls. */
        !          1215:                return ENXIO;
        !          1216:
        !          1217:        if (cp->type == AUDIO_MIXER_VALUE) {
        !          1218:                register mixer_level_t *mv = &cp->un.value;
        !          1219:                switch (cp->dev) {
        !          1220:                case ARIAMIX_MIC_LVL:
        !          1221:                        if (mv->num_channels == 1 || mv->num_channels == 2) {
        !          1222:                                sc->aria_mix[ARIAMIX_MIC_LVL].num_channels = mv->num_channels;
        !          1223:                                sc->aria_mix[ARIAMIX_MIC_LVL].level[0] = mv->level[0];
        !          1224:                                sc->aria_mix[ARIAMIX_MIC_LVL].level[1] = mv->level[1];
        !          1225:                                error = 0;
        !          1226:                        }
        !          1227:                        break;
        !          1228:
        !          1229:                case ARIAMIX_LINE_IN_LVL:
        !          1230:                        if (mv->num_channels == 1 || mv->num_channels == 2) {
        !          1231:                                sc->aria_mix[ARIAMIX_LINE_IN_LVL].num_channels = mv->num_channels;
        !          1232:                                sc->aria_mix[ARIAMIX_LINE_IN_LVL].level[0] = mv->level[0];
        !          1233:                                sc->aria_mix[ARIAMIX_LINE_IN_LVL].level[1] = mv->level[1];
        !          1234:                                error = 0;
        !          1235:                        }
        !          1236:                        break;
        !          1237:
        !          1238:                case ARIAMIX_CD_LVL:
        !          1239:                        if (mv->num_channels == 1 || mv->num_channels == 2) {
        !          1240:                                sc->aria_mix[ARIAMIX_CD_LVL].num_channels = mv->num_channels;
        !          1241:                                sc->aria_mix[ARIAMIX_CD_LVL].level[0] = mv->level[0];
        !          1242:                                sc->aria_mix[ARIAMIX_CD_LVL].level[1] = mv->level[1];
        !          1243:                                error = 0;
        !          1244:                        }
        !          1245:                        break;
        !          1246:
        !          1247:                case ARIAMIX_TEL_LVL:
        !          1248:                        if (mv->num_channels == 1) {
        !          1249:                                sc->aria_mix[ARIAMIX_TEL_LVL].num_channels = mv->num_channels;
        !          1250:                                sc->aria_mix[ARIAMIX_TEL_LVL].level[0] = mv->level[0];
        !          1251:                                error = 0;
        !          1252:                        }
        !          1253:                        break;
        !          1254:
        !          1255:                case ARIAMIX_DAC_LVL:
        !          1256:                        if (mv->num_channels == 1 || mv->num_channels == 2) {
        !          1257:                                sc->aria_mix[ARIAMIX_DAC_LVL].num_channels = mv->num_channels;
        !          1258:                                sc->aria_mix[ARIAMIX_DAC_LVL].level[0] = mv->level[0];
        !          1259:                                sc->aria_mix[ARIAMIX_DAC_LVL].level[1] = mv->level[1];
        !          1260:                                error = 0;
        !          1261:                        }
        !          1262:                        break;
        !          1263:
        !          1264:                case ARIAMIX_AUX_LVL:
        !          1265:                        if (mv->num_channels == 1 || mv->num_channels == 2) {
        !          1266:                                sc->aria_mix[ARIAMIX_AUX_LVL].num_channels = mv->num_channels;
        !          1267:                                sc->aria_mix[ARIAMIX_AUX_LVL].level[0] = mv->level[0];
        !          1268:                                sc->aria_mix[ARIAMIX_AUX_LVL].level[1] = mv->level[1];
        !          1269:                                error = 0;
        !          1270:                        }
        !          1271:                        break;
        !          1272:
        !          1273:                case ARIAMIX_MASTER_LVL:
        !          1274:                        if (mv->num_channels == 1 || mv->num_channels == 2) {
        !          1275:                                sc->ariamix_master.num_channels = mv->num_channels;
        !          1276:                                sc->ariamix_master.level[0] = mv->level[0];
        !          1277:                                sc->ariamix_master.level[1] = mv->level[1];
        !          1278:                                error = 0;
        !          1279:                        }
        !          1280:                        break;
        !          1281:
        !          1282:                case ARIAMIX_MASTER_TREBLE:
        !          1283:                        if (mv->num_channels == 2) {
        !          1284:                                sc->ariamix_master.treble[0] = (mv->level[0]==0)?1:mv->level[0];
        !          1285:                                sc->ariamix_master.treble[1] = (mv->level[1]==0)?1:mv->level[1];
        !          1286:                                error = 0;
        !          1287:                        }
        !          1288:                        break;
        !          1289:                case ARIAMIX_MASTER_BASS:
        !          1290:                        if (mv->num_channels == 2) {
        !          1291:                                sc->ariamix_master.bass[0] = (mv->level[0]==0)?1:mv->level[0];
        !          1292:                                sc->ariamix_master.bass[1] = (mv->level[1]==0)?1:mv->level[1];
        !          1293:                                error = 0;
        !          1294:                        }
        !          1295:                        break;
        !          1296:                case ARIAMIX_OUT_LVL:
        !          1297:                        if (mv->num_channels == 1 || mv->num_channels == 2) {
        !          1298:                                sc->gain[0] = mv->level[0];
        !          1299:                                sc->gain[1] = mv->level[1];
        !          1300:                                error = 0;
        !          1301:                        }
        !          1302:                        break;
        !          1303:                default:
        !          1304:                }
        !          1305:        }
        !          1306:
        !          1307:        if (cp->type == AUDIO_MIXER_ENUM)
        !          1308:                switch(cp->dev) {
        !          1309:                case ARIAMIX_RECORD_SOURCE:
        !          1310:                        if (cp->un.ord>=0 && cp->un.ord<=6) {
        !          1311:                                sc->aria_mix_source = cp->un.ord;
        !          1312:                                error = 0;
        !          1313:                        }
        !          1314:                        break;
        !          1315:
        !          1316:                case ARIAMIX_MIC_MUTE:
        !          1317:                        if (cp->un.ord == 0 || cp->un.ord == 1) {
        !          1318:                                sc->aria_mix[ARIAMIX_MIC_LVL].mute = cp->un.ord;
        !          1319:                                error = 0;
        !          1320:                        }
        !          1321:                        break;
        !          1322:
        !          1323:                case ARIAMIX_LINE_IN_MUTE:
        !          1324:                        if (cp->un.ord == 0 || cp->un.ord == 1) {
        !          1325:                                sc->aria_mix[ARIAMIX_LINE_IN_LVL].mute = cp->un.ord;
        !          1326:                                error = 0;
        !          1327:                        }
        !          1328:                        break;
        !          1329:
        !          1330:                case ARIAMIX_CD_MUTE:
        !          1331:                        if (cp->un.ord == 0 || cp->un.ord == 1) {
        !          1332:                                sc->aria_mix[ARIAMIX_CD_LVL].mute = cp->un.ord;
        !          1333:                                error = 0;
        !          1334:                        }
        !          1335:                        break;
        !          1336:
        !          1337:                case ARIAMIX_DAC_MUTE:
        !          1338:                        if (cp->un.ord == 0 || cp->un.ord == 1) {
        !          1339:                                sc->aria_mix[ARIAMIX_DAC_LVL].mute = cp->un.ord;
        !          1340:                                error = 0;
        !          1341:                        }
        !          1342:                        break;
        !          1343:
        !          1344:                case ARIAMIX_AUX_MUTE:
        !          1345:                        if (cp->un.ord == 0 || cp->un.ord == 1) {
        !          1346:                                sc->aria_mix[ARIAMIX_AUX_LVL].mute = cp->un.ord;
        !          1347:                                error = 0;
        !          1348:                        }
        !          1349:                        break;
        !          1350:
        !          1351:                case ARIAMIX_TEL_MUTE:
        !          1352:                        if (cp->un.ord == 0 || cp->un.ord == 1) {
        !          1353:                                sc->aria_mix[ARIAMIX_TEL_LVL].mute = cp->un.ord;
        !          1354:                                error = 0;
        !          1355:                        }
        !          1356:                        break;
        !          1357:
        !          1358:                default:
        !          1359:                        return ENXIO;
        !          1360:                        /* NOTREACHED */
        !          1361:                }
        !          1362:
        !          1363:        return(error);
        !          1364: }
        !          1365:
        !          1366: int
        !          1367: aria_mixer_get_port(addr, cp)
        !          1368:     void *addr;
        !          1369:     mixer_ctrl_t *cp;
        !          1370: {
        !          1371:        register struct aria_softc *sc = addr;
        !          1372:        int error = EINVAL;
        !          1373:
        !          1374:        DPRINTF(("aria_mixer_get_port\n"));
        !          1375:
        !          1376:        if (!(ARIA_MIXER&sc->sc_hardware))  /* This could be done better, no mixer still has some controls. */
        !          1377:                return ENXIO;
        !          1378:
        !          1379:        switch (cp->dev) {
        !          1380:        case ARIAMIX_MIC_LVL:
        !          1381:                if (cp->type == AUDIO_MIXER_VALUE) {
        !          1382:                        cp->un.value.num_channels = sc->aria_mix[ARIAMIX_MIC_LVL].num_channels;
        !          1383:                        cp->un.value.level[0] = sc->aria_mix[ARIAMIX_MIC_LVL].level[0];
        !          1384:                        cp->un.value.level[1] = sc->aria_mix[ARIAMIX_MIC_LVL].level[1];
        !          1385:                        error = 0;
        !          1386:                }
        !          1387:                break;
        !          1388:
        !          1389:        case ARIAMIX_LINE_IN_LVL:
        !          1390:                if (cp->type == AUDIO_MIXER_VALUE) {
        !          1391:                        cp->un.value.num_channels = sc->aria_mix[ARIAMIX_LINE_IN_LVL].num_channels;
        !          1392:                        cp->un.value.level[0] = sc->aria_mix[ARIAMIX_LINE_IN_LVL].level[0];
        !          1393:                        cp->un.value.level[1] = sc->aria_mix[ARIAMIX_LINE_IN_LVL].level[1];
        !          1394:                        error = 0;
        !          1395:                }
        !          1396:                break;
        !          1397:
        !          1398:        case ARIAMIX_CD_LVL:
        !          1399:                if (cp->type == AUDIO_MIXER_VALUE) {
        !          1400:                        cp->un.value.num_channels = sc->aria_mix[ARIAMIX_CD_LVL].num_channels;
        !          1401:                        cp->un.value.level[0] = sc->aria_mix[ARIAMIX_CD_LVL].level[0];
        !          1402:                        cp->un.value.level[1] = sc->aria_mix[ARIAMIX_CD_LVL].level[1];
        !          1403:                        error = 0;
        !          1404:                }
        !          1405:                break;
        !          1406:
        !          1407:        case ARIAMIX_TEL_LVL:
        !          1408:                if (cp->type == AUDIO_MIXER_VALUE) {
        !          1409:                        cp->un.value.num_channels = sc->aria_mix[ARIAMIX_TEL_LVL].num_channels;
        !          1410:                        cp->un.value.level[0] = sc->aria_mix[ARIAMIX_TEL_LVL].level[0];
        !          1411:                        error = 0;
        !          1412:                }
        !          1413:                break;
        !          1414:        case ARIAMIX_DAC_LVL:
        !          1415:                if (cp->type == AUDIO_MIXER_VALUE) {
        !          1416:                        cp->un.value.num_channels = sc->aria_mix[ARIAMIX_DAC_LVL].num_channels;
        !          1417:                        cp->un.value.level[0] = sc->aria_mix[ARIAMIX_DAC_LVL].level[0];
        !          1418:                        cp->un.value.level[1] = sc->aria_mix[ARIAMIX_DAC_LVL].level[1];
        !          1419:                        error = 0;
        !          1420:                }
        !          1421:                break;
        !          1422:
        !          1423:        case ARIAMIX_AUX_LVL:
        !          1424:                if (cp->type == AUDIO_MIXER_VALUE) {
        !          1425:                        cp->un.value.num_channels = sc->aria_mix[ARIAMIX_AUX_LVL].num_channels;
        !          1426:                        cp->un.value.level[0] = sc->aria_mix[ARIAMIX_AUX_LVL].level[0];
        !          1427:                        cp->un.value.level[1] = sc->aria_mix[ARIAMIX_AUX_LVL].level[1];
        !          1428:                        error = 0;
        !          1429:                }
        !          1430:                break;
        !          1431:
        !          1432:        case ARIAMIX_MIC_MUTE:
        !          1433:                if (cp->type == AUDIO_MIXER_ENUM) {
        !          1434:                        cp->un.ord = sc->aria_mix[ARIAMIX_MIC_LVL].mute;
        !          1435:                        error = 0;
        !          1436:                }
        !          1437:                break;
        !          1438:
        !          1439:        case ARIAMIX_LINE_IN_MUTE:
        !          1440:                if (cp->type == AUDIO_MIXER_ENUM) {
        !          1441:                        cp->un.ord = sc->aria_mix[ARIAMIX_LINE_IN_LVL].mute;
        !          1442:                        error = 0;
        !          1443:                }
        !          1444:                break;
        !          1445:
        !          1446:        case ARIAMIX_CD_MUTE:
        !          1447:                if (cp->type == AUDIO_MIXER_ENUM) {
        !          1448:                        cp->un.ord = sc->aria_mix[ARIAMIX_CD_LVL].mute;
        !          1449:                        error = 0;
        !          1450:                }
        !          1451:                break;
        !          1452:
        !          1453:        case ARIAMIX_DAC_MUTE:
        !          1454:                if (cp->type == AUDIO_MIXER_ENUM) {
        !          1455:                        cp->un.ord = sc->aria_mix[ARIAMIX_DAC_LVL].mute;
        !          1456:                        error = 0;
        !          1457:                }
        !          1458:                break;
        !          1459:
        !          1460:        case ARIAMIX_AUX_MUTE:
        !          1461:                if (cp->type == AUDIO_MIXER_ENUM) {
        !          1462:                        cp->un.ord = sc->aria_mix[ARIAMIX_AUX_LVL].mute;
        !          1463:                        error = 0;
        !          1464:                }
        !          1465:                break;
        !          1466:
        !          1467:        case ARIAMIX_TEL_MUTE:
        !          1468:                if (cp->type == AUDIO_MIXER_ENUM) {
        !          1469:                        cp->un.ord = sc->aria_mix[ARIAMIX_TEL_LVL].mute;
        !          1470:                        error = 0;
        !          1471:                }
        !          1472:                break;
        !          1473:
        !          1474:        case ARIAMIX_MASTER_LVL:
        !          1475:                if (cp->type == AUDIO_MIXER_VALUE) {
        !          1476:                        cp->un.value.num_channels = sc->ariamix_master.num_channels;
        !          1477:                        cp->un.value.level[0] = sc->ariamix_master.level[0];
        !          1478:                        cp->un.value.level[1] = sc->ariamix_master.level[1];
        !          1479:                        error = 0;
        !          1480:                }
        !          1481:                break;
        !          1482:
        !          1483:        case ARIAMIX_MASTER_TREBLE:
        !          1484:                if (cp->type == AUDIO_MIXER_VALUE) {
        !          1485:                        cp->un.value.num_channels = 2;
        !          1486:                        cp->un.value.level[0] = sc->ariamix_master.treble[0];
        !          1487:                        cp->un.value.level[1] = sc->ariamix_master.treble[1];
        !          1488:                        error = 0;
        !          1489:                }
        !          1490:                break;
        !          1491:
        !          1492:        case ARIAMIX_MASTER_BASS:
        !          1493:                if (cp->type == AUDIO_MIXER_VALUE) {
        !          1494:                        cp->un.value.num_channels = 2;
        !          1495:                        cp->un.value.level[0] = sc->ariamix_master.bass[0];
        !          1496:                        cp->un.value.level[1] = sc->ariamix_master.bass[1];
        !          1497:                        error = 0;
        !          1498:                }
        !          1499:                break;
        !          1500:
        !          1501:        case ARIAMIX_OUT_LVL:
        !          1502:                if (cp->type == AUDIO_MIXER_VALUE) {
        !          1503:                        cp->un.value.num_channels = sc->sc_chans;
        !          1504:                        cp->un.value.level[0] = sc->gain[0];
        !          1505:                        cp->un.value.level[1] = sc->gain[1];
        !          1506:                        error = 0;
        !          1507:                }
        !          1508:                break;
        !          1509:        case ARIAMIX_RECORD_SOURCE:
        !          1510:                if (cp->type == AUDIO_MIXER_ENUM) {
        !          1511:                        cp->un.ord = sc->aria_mix_source;
        !          1512:                        error = 0;
        !          1513:                }
        !          1514:                break;
        !          1515:
        !          1516:        default:
        !          1517:                return ENXIO;
        !          1518:                /* NOT REACHED */
        !          1519:        }
        !          1520:
        !          1521:        return(error);
        !          1522: }
        !          1523:
        !          1524: int
        !          1525: aria_mixer_query_devinfo(addr, dip)
        !          1526:           void *addr;
        !          1527:           register mixer_devinfo_t *dip;
        !          1528: {
        !          1529:
        !          1530:        register struct aria_softc *sc = addr;
        !          1531:
        !          1532:        DPRINTF(("aria_mixer_query_devinfo\n"));
        !          1533:
        !          1534:        if (!(ARIA_MIXER&sc->sc_hardware))  /* This could be done better, no mixer still has some controls. */
        !          1535:                return ENXIO;
        !          1536:
        !          1537:        dip->prev = dip->next = AUDIO_MIXER_LAST;
        !          1538:
        !          1539:        switch(dip->index) {
        !          1540:        case ARIAMIX_MIC_LVL:
        !          1541:                dip->type = AUDIO_MIXER_VALUE;
        !          1542:                dip->mixer_class = ARIAMIX_INPUT_CLASS;
        !          1543:                dip->next = ARIAMIX_MIC_MUTE;
        !          1544:                strlcpy(dip->label.name, AudioNmicrophone,
        !          1545:                    sizeof dip->label.name);
        !          1546:                dip->un.v.num_channels = 2;
        !          1547:                strlcpy(dip->un.v.units.name, AudioNvolume,
        !          1548:                    sizeof dip->un.v.units.name);
        !          1549:                break;
        !          1550:
        !          1551:        case ARIAMIX_LINE_IN_LVL:
        !          1552:                dip->type = AUDIO_MIXER_VALUE;
        !          1553:                dip->mixer_class = ARIAMIX_INPUT_CLASS;
        !          1554:                dip->next = ARIAMIX_LINE_IN_MUTE;
        !          1555:                strlcpy(dip->label.name, AudioNline, sizeof dip->label.name);
        !          1556:                dip->un.v.num_channels = 2;
        !          1557:                strlcpy(dip->un.v.units.name, AudioNvolume,
        !          1558:                    sizeof dip->un.v.units.name);
        !          1559:                break;
        !          1560:
        !          1561:        case ARIAMIX_CD_LVL:
        !          1562:                dip->type = AUDIO_MIXER_VALUE;
        !          1563:                dip->mixer_class = ARIAMIX_INPUT_CLASS;
        !          1564:                dip->next = ARIAMIX_CD_MUTE;
        !          1565:                strlcpy(dip->label.name, AudioNcd, sizeof dip->label.name);
        !          1566:                dip->un.v.num_channels = 2;
        !          1567:                strlcpy(dip->un.v.units.name, AudioNvolume,
        !          1568:                    sizeof dip->un.v.units.name);
        !          1569:                break;
        !          1570:
        !          1571:        case ARIAMIX_TEL_LVL:
        !          1572:                dip->type = AUDIO_MIXER_VALUE;
        !          1573:                dip->mixer_class = ARIAMIX_INPUT_CLASS;
        !          1574:                dip->next = ARIAMIX_TEL_MUTE;
        !          1575:                strlcpy(dip->label.name, "telephone", sizeof dip->label.name);
        !          1576:                dip->un.v.num_channels = 1;
        !          1577:                strlcpy(dip->un.v.units.name, AudioNvolume,
        !          1578:                    sizeof dip->un.v.units.name);
        !          1579:                break;
        !          1580:
        !          1581:        case ARIAMIX_DAC_LVL:
        !          1582:                dip->type = AUDIO_MIXER_VALUE;
        !          1583:                dip->mixer_class = ARIAMIX_INPUT_CLASS;
        !          1584:                dip->next = ARIAMIX_DAC_MUTE;
        !          1585:                strlcpy(dip->label.name, AudioNdac, sizeof dip->label.name);
        !          1586:                dip->un.v.num_channels = 1;
        !          1587:                strlcpy(dip->un.v.units.name, AudioNvolume,
        !          1588:                    sizeof dip->un.v.units.name);
        !          1589:                break;
        !          1590:
        !          1591:        case ARIAMIX_AUX_LVL:
        !          1592:                dip->type = AUDIO_MIXER_VALUE;
        !          1593:                dip->mixer_class = ARIAMIX_INPUT_CLASS;
        !          1594:                dip->next = ARIAMIX_AUX_MUTE;
        !          1595:                strlcpy(dip->label.name, AudioNoutput, sizeof dip->label.name);
        !          1596:                dip->un.v.num_channels = 1;
        !          1597:                strlcpy(dip->un.v.units.name, AudioNvolume,
        !          1598:                    sizeof dip->un.v.units.name);
        !          1599:                break;
        !          1600:
        !          1601:        case ARIAMIX_MIC_MUTE:
        !          1602:                dip->prev = ARIAMIX_MIC_LVL;
        !          1603:                goto mode;
        !          1604:
        !          1605:        case ARIAMIX_LINE_IN_MUTE:
        !          1606:                dip->prev = ARIAMIX_LINE_IN_LVL;
        !          1607:                goto mode;
        !          1608:
        !          1609:        case ARIAMIX_CD_MUTE:
        !          1610:                dip->prev = ARIAMIX_CD_LVL;
        !          1611:                goto mode;
        !          1612:
        !          1613:        case ARIAMIX_DAC_MUTE:
        !          1614:                dip->prev = ARIAMIX_DAC_LVL;
        !          1615:                goto mode;
        !          1616:
        !          1617:        case ARIAMIX_AUX_MUTE:
        !          1618:                dip->prev = ARIAMIX_AUX_LVL;
        !          1619:                goto mode;
        !          1620:
        !          1621:        case ARIAMIX_TEL_MUTE:
        !          1622:                dip->prev = ARIAMIX_TEL_LVL;
        !          1623:                goto mode;
        !          1624:
        !          1625: mode:
        !          1626:                dip->mixer_class = ARIAMIX_INPUT_CLASS;
        !          1627:                dip->type = AUDIO_MIXER_ENUM;
        !          1628:                strlcpy(dip->label.name, AudioNmute, sizeof dip->label.name);
        !          1629:                dip->un.e.num_mem = 2;
        !          1630:                strlcpy(dip->un.e.member[0].label.name, AudioNoff,
        !          1631:                    sizeof dip->un.e.member[0].label.name);
        !          1632:                dip->un.e.member[0].ord = 0;
        !          1633:                strlcpy(dip->un.e.member[1].label.name, AudioNon,
        !          1634:                    sizeof dip->un.e.member[0].label.name);
        !          1635:                dip->un.e.member[1].ord = 1;
        !          1636:                break;
        !          1637:
        !          1638:        case ARIAMIX_MASTER_LVL:
        !          1639:                dip->type = AUDIO_MIXER_VALUE;
        !          1640:                dip->mixer_class = ARIAMIX_OUTPUT_CLASS;
        !          1641:                dip->next = ARIAMIX_MASTER_TREBLE;
        !          1642:                strlcpy(dip->label.name, AudioNvolume, sizeof dip->label.name);
        !          1643:                dip->un.v.num_channels = 2;
        !          1644:                strlcpy(dip->un.v.units.name, AudioNvolume,
        !          1645:                    sizeof dip->un.v.units.name);
        !          1646:                break;
        !          1647:
        !          1648:        case ARIAMIX_MASTER_TREBLE:
        !          1649:                dip->type = AUDIO_MIXER_VALUE;
        !          1650:                dip->mixer_class = ARIAMIX_OUTPUT_CLASS;
        !          1651:                dip->prev = ARIAMIX_MASTER_LVL;
        !          1652:                dip->next = ARIAMIX_MASTER_BASS;
        !          1653:                strlcpy(dip->label.name, AudioNmaster, sizeof dip->label.name);
        !          1654:                dip->un.v.num_channels = 2;
        !          1655:                strlcpy(dip->un.v.units.name, AudioNtreble,
        !          1656:                    sizeof dip->un.v.units.name);
        !          1657:                break;
        !          1658:
        !          1659:        case ARIAMIX_MASTER_BASS:
        !          1660:                dip->type = AUDIO_MIXER_VALUE;
        !          1661:                dip->mixer_class = ARIAMIX_OUTPUT_CLASS;
        !          1662:                dip->prev = ARIAMIX_MASTER_TREBLE;
        !          1663:                strlcpy(dip->label.name, AudioNmaster, sizeof dip->label.name);
        !          1664:                dip->un.v.num_channels = 2;
        !          1665:                strlcpy(dip->un.v.units.name, AudioNbass,
        !          1666:                    sizeof dip->un.v.units.name);
        !          1667:                break;
        !          1668:
        !          1669:        case ARIAMIX_OUT_LVL:
        !          1670:                dip->type = AUDIO_MIXER_VALUE;
        !          1671:                dip->mixer_class = ARIAMIX_OUTPUT_CLASS;
        !          1672:                strlcpy(dip->label.name, AudioNoutput, sizeof dip->label.name);
        !          1673:                dip->un.v.num_channels = 2;
        !          1674:                strlcpy(dip->un.v.units.name, AudioNvolume,
        !          1675:                    sizeof dip->un.v.units.name);
        !          1676:                break;
        !          1677:
        !          1678:        case ARIAMIX_RECORD_SOURCE:
        !          1679:                dip->mixer_class = ARIAMIX_RECORD_CLASS;
        !          1680:                dip->type = AUDIO_MIXER_ENUM;
        !          1681:                strlcpy(dip->label.name, AudioNsource, sizeof dip->label.name);
        !          1682:                dip->un.e.num_mem = 6;
        !          1683:                strlcpy(dip->un.e.member[0].label.name, AudioNoutput,
        !          1684:                    sizeof dip->un.e.member[0].label.name);
        !          1685:                dip->un.e.member[0].ord = ARIAMIX_AUX_LVL;
        !          1686:                strlcpy(dip->un.e.member[1].label.name, AudioNmicrophone,
        !          1687:                    sizeof dip->un.e.member[0].label.name);
        !          1688:                dip->un.e.member[1].ord = ARIAMIX_MIC_LVL;
        !          1689:                strlcpy(dip->un.e.member[2].label.name, AudioNdac,
        !          1690:                    sizeof dip->un.e.member[0].label.name);
        !          1691:                dip->un.e.member[2].ord = ARIAMIX_DAC_LVL;
        !          1692:                strlcpy(dip->un.e.member[3].label.name, AudioNline,
        !          1693:                    sizeof dip->un.e.member[0].label.name);
        !          1694:                dip->un.e.member[3].ord = ARIAMIX_LINE_IN_LVL;
        !          1695:                strlcpy(dip->un.e.member[3].label.name, AudioNcd,
        !          1696:                    sizeof dip->un.e.member[0].label.name);
        !          1697:                dip->un.e.member[4].ord = ARIAMIX_CD_LVL;
        !          1698:                strlcpy(dip->un.e.member[3].label.name, "telephone",
        !          1699:                    sizeof dip->un.e.member[0].label.name);
        !          1700:                dip->un.e.member[5].ord = ARIAMIX_TEL_LVL;
        !          1701:                break;
        !          1702:
        !          1703:        case ARIAMIX_INPUT_CLASS:
        !          1704:                dip->type = AUDIO_MIXER_CLASS;
        !          1705:                dip->mixer_class = ARIAMIX_INPUT_CLASS;
        !          1706:                strlcpy(dip->label.name, AudioCInputs, sizeof dip->label.name);
        !          1707:                break;
        !          1708:
        !          1709:        case ARIAMIX_OUTPUT_CLASS:
        !          1710:                dip->type = AUDIO_MIXER_CLASS;
        !          1711:                dip->mixer_class = ARIAMIX_OUTPUT_CLASS;
        !          1712:                strlcpy(dip->label.name, AudioCOutputs,
        !          1713:                    sizeof dip->label.name);
        !          1714:                break;
        !          1715:
        !          1716:        case ARIAMIX_RECORD_CLASS:
        !          1717:                dip->type = AUDIO_MIXER_CLASS;
        !          1718:                dip->mixer_class = ARIAMIX_RECORD_CLASS;
        !          1719:                strlcpy(dip->label.name, AudioCRecord, sizeof dip->label.name);
        !          1720:                break;
        !          1721:
        !          1722:        case ARIAMIX_EQ_CLASS:
        !          1723:                dip->type = AUDIO_MIXER_CLASS;
        !          1724:                dip->mixer_class = ARIAMIX_EQ_CLASS;
        !          1725:                strlcpy(dip->label.name, AudioCEqualization,
        !          1726:                    sizeof dip->label.name);
        !          1727:                break;
        !          1728:
        !          1729:        default:
        !          1730:                return ENXIO;
        !          1731:                /*NOTREACHED*/
        !          1732:        }
        !          1733:        return 0;
        !          1734: }
        !          1735:
        !          1736: #endif /* NARIA */

CVSweb