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

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

1.1       nbrk        1: /*     $OpenBSD: ad1848.c,v 1.32 2005/05/22 19:40:51 art Exp $ */
                      2: /*     $NetBSD: ad1848.c,v 1.45 1998/01/30 02:02:38 augustss Exp $     */
                      3:
                      4: /*
                      5:  * Copyright (c) 1994 John Brezak
                      6:  * Copyright (c) 1991-1993 Regents of the University of California.
                      7:  * All rights reserved.
                      8:  *
                      9:  * Redistribution and use in source and binary forms, with or without
                     10:  * modification, are permitted provided that the following conditions
                     11:  * are met:
                     12:  * 1. Redistributions of source code must retain the above copyright
                     13:  *    notice, this list of conditions and the following disclaimer.
                     14:  * 2. Redistributions in binary form must reproduce the above copyright
                     15:  *    notice, this list of conditions and the following disclaimer in the
                     16:  *    documentation and/or other materials provided with the distribution.
                     17:  * 3. All advertising materials mentioning features or use of this software
                     18:  *    must display the following acknowledgement:
                     19:  *     This product includes software developed by the Computer Systems
                     20:  *     Engineering Group at Lawrence Berkeley Laboratory.
                     21:  * 4. Neither the name of the University nor of the Laboratory may be used
                     22:  *    to endorse or promote products derived from this software without
                     23:  *    specific prior written permission.
                     24:  *
                     25:  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
                     26:  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
                     27:  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
                     28:  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
                     29:  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
                     30:  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
                     31:  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
                     32:  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
                     33:  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
                     34:  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
                     35:  * SUCH DAMAGE.
                     36:  *
                     37:  */
                     38:
                     39: /*
                     40:  * Copyright by Hannu Savolainen 1994
                     41:  *
                     42:  * Redistribution and use in source and binary forms, with or without
                     43:  * modification, are permitted provided that the following conditions are
                     44:  * met: 1. Redistributions of source code must retain the above copyright
                     45:  * notice, this list of conditions and the following disclaimer. 2.
                     46:  * Redistributions in binary form must reproduce the above copyright notice,
                     47:  * this list of conditions and the following disclaimer in the documentation
                     48:  * and/or other materials provided with the distribution.
                     49:  *
                     50:  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND ANY
                     51:  * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
                     52:  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
                     53:  * DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR
                     54:  * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
                     55:  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
                     56:  * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
                     57:  * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
                     58:  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
                     59:  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
                     60:  * SUCH DAMAGE.
                     61:  *
                     62:  */
                     63: /*
                     64:  * Portions of this code are from the VOXware support for the ad1848
                     65:  * by Hannu Savolainen <hannu@voxware.pp.fi>
                     66:  *
                     67:  * Portions also supplied from the SoundBlaster driver for NetBSD.
                     68:  */
                     69:
                     70: #include <sys/param.h>
                     71: #include <sys/systm.h>
                     72: #include <sys/errno.h>
                     73: #include <sys/ioctl.h>
                     74: #include <sys/syslog.h>
                     75: #include <sys/device.h>
                     76: #include <sys/proc.h>
                     77: #include <sys/buf.h>
                     78:
                     79: #include <machine/cpu.h>
                     80: #include <machine/bus.h>
                     81:
                     82: #include <sys/audioio.h>
                     83:
                     84: #include <dev/audio_if.h>
                     85: #include <dev/auconv.h>
                     86:
                     87: #include <dev/isa/isavar.h>
                     88: #include <dev/isa/isadmavar.h>
                     89:
                     90: #include <dev/ic/ad1848reg.h>
                     91: #include <dev/ic/cs4231reg.h>
                     92: #include <dev/isa/ad1848var.h>
                     93: #include <dev/isa/cs4231var.h>
                     94:
                     95: #ifdef AUDIO_DEBUG
                     96: #define DPRINTF(x)     if (ad1848debug) printf x
                     97: int    ad1848debug = 0;
                     98: #else
                     99: #define DPRINTF(x)
                    100: #endif
                    101:
                    102: /*
                    103:  * Initial values for the indirect registers of CS4248/AD1848.
                    104:  */
                    105: static int ad1848_init_values[] = {
                    106:                        /* Left Input Control */
                    107:     GAIN_12|INPUT_MIC_GAIN_ENABLE,
                    108:                        /* Right Input Control */
                    109:     GAIN_12|INPUT_MIC_GAIN_ENABLE,
                    110:     ATTEN_12,          /* Left Aux #1 Input Control */
                    111:     ATTEN_12,          /* Right Aux #1 Input Control */
                    112:     ATTEN_12,          /* Left Aux #2 Input Control */
                    113:     ATTEN_12,          /* Right Aux #2 Input Control */
                    114:     /* bits 5-0 are attenuation select */
                    115:     ATTEN_12,          /* Left DAC output Control */
                    116:     ATTEN_12,          /* Right DAC output Control */
                    117:                        /* Clock and Data Format */
                    118:     CLOCK_XTAL1|FMT_PCM8,
                    119:                        /* Interface Config */
                    120:     SINGLE_DMA|AUTO_CAL_ENABLE,
                    121:     INTERRUPT_ENABLE,  /* Pin control */
                    122:     0x00,              /* Test and Init */
                    123:     MODE2,             /* Misc control */
                    124:     ATTEN_0<<2,                /* Digital Mix Control */
                    125:     0,                 /* Upper base Count */
                    126:     0,                 /* Lower base Count */
                    127:
                    128:     /* These are for CS4231 &c. only (additional registers): */
                    129:     0,                 /* Alt feature 1 */
                    130:     0,                 /* Alt feature 2 */
                    131:     ATTEN_12,          /* Left line in */
                    132:     ATTEN_12,          /* Right line in */
                    133:     0,                 /* Timer low */
                    134:     0,                 /* Timer high */
                    135:     0,                 /* unused */
                    136:     0,                 /* unused */
                    137:     0,                 /* IRQ status */
                    138:     0,                 /* unused */
                    139:                        /* Mono input (a.k.a speaker) (mic) Control */
                    140:     MONO_INPUT_MUTE|ATTEN_6,           /* mute speaker by default */
                    141:     0,                 /* unused */
                    142:     0,                 /* record format */
                    143:     0,                 /* Crystal Clock Select */
                    144:     0,                 /* upper record count */
                    145:     0                  /* lower record count */
                    146: };
                    147:
                    148: void   ad1848_reset(struct ad1848_softc *);
                    149: int    ad1848_set_speed(struct ad1848_softc *, u_long *);
                    150: void   ad1848_mute_monitor(void *, int);
                    151:
                    152: static int ad_read(struct ad1848_softc *, int);
                    153: static void ad_write(struct ad1848_softc *, int, int);
                    154: static void ad_set_MCE(struct ad1848_softc *, int);
                    155: static void wait_for_calibration(struct ad1848_softc *);
                    156:
                    157: #define ADREAD(sc, addr) bus_space_read_1((sc)->sc_iot, (sc)->sc_ioh, (sc)->sc_iooffs+(addr))
                    158: #define ADWRITE(sc, addr, data) bus_space_write_1((sc)->sc_iot, (sc)->sc_ioh, (sc)->sc_iooffs+(addr), (data))
                    159:
                    160: static int
                    161: ad_read(sc, reg)
                    162:     struct ad1848_softc *sc;
                    163:     int reg;
                    164: {
                    165:     int x, s;
                    166:
                    167:     s = splaudio();
                    168:     ADWRITE(sc, AD1848_IADDR, (reg & 0xff) | sc->MCE_bit);
                    169:     x = ADREAD(sc, AD1848_IDATA);
                    170:     splx(s);
                    171:     /*  printf("(%02x<-%02x) ", reg|sc->MCE_bit, x); */
                    172:
                    173:     return x;
                    174: }
                    175:
                    176: static void
                    177: ad_write(sc, reg, data)
                    178:     struct ad1848_softc *sc;
                    179:     int reg;
                    180:     int data;
                    181: {
                    182:     int s = splaudio();
                    183:     ADWRITE(sc, AD1848_IADDR, (reg & 0xff) | sc->MCE_bit);
                    184:     ADWRITE(sc, AD1848_IDATA, data & 0xff);
                    185:     splx(s);
                    186:     /* printf("(%02x->%02x) ", reg|sc->MCE_bit, data); */
                    187: }
                    188:
                    189: static void
                    190: ad_set_MCE(sc, state)
                    191:     struct ad1848_softc *sc;
                    192:     int state;
                    193: {
                    194:     if (state)
                    195:        sc->MCE_bit = MODE_CHANGE_ENABLE;
                    196:     else
                    197:        sc->MCE_bit = 0;
                    198:
                    199:     ADWRITE(sc, AD1848_IADDR, sc->MCE_bit);
                    200: }
                    201:
                    202: static void
                    203: wait_for_calibration(sc)
                    204:     struct ad1848_softc *sc;
                    205: {
                    206:     int timeout;
                    207:
                    208:     DPRINTF(("ad1848: Auto calibration started.\n"));
                    209:     /*
                    210:      * Wait until the auto calibration process has finished.
                    211:      *
                    212:      * 1) Wait until the chip becomes ready (reads don't return 0x80).
                    213:      * 2) Wait until the ACI bit of I11 gets on and then off.
                    214:      */
                    215:     timeout = 100000;
                    216:     while (timeout > 0 && ADREAD(sc, AD1848_IADDR) == SP_IN_INIT)
                    217:        timeout--;
                    218:
                    219:     if (ADREAD(sc, AD1848_IADDR) == SP_IN_INIT)
                    220:        DPRINTF(("ad1848: Auto calibration timed out(1).\n"));
                    221:
                    222:     ADWRITE(sc, AD1848_IADDR, SP_TEST_AND_INIT);
                    223:     timeout = 100000;
                    224:     while (timeout > 0 && ADREAD(sc, AD1848_IADDR) != SP_TEST_AND_INIT)
                    225:        timeout--;
                    226:
                    227:     if (ADREAD(sc, AD1848_IADDR) == SP_TEST_AND_INIT)
                    228:        DPRINTF(("ad1848: Auto calibration timed out(1.5).\n"));
                    229:
                    230:     if (!(ad_read(sc, SP_TEST_AND_INIT) & AUTO_CAL_IN_PROG)) {
                    231:        timeout = 100000;
                    232:        while (timeout > 0 && !(ad_read(sc, SP_TEST_AND_INIT) & AUTO_CAL_IN_PROG))
                    233:            timeout--;
                    234:
                    235:        if (!(ad_read(sc, SP_TEST_AND_INIT) & AUTO_CAL_IN_PROG))
                    236:            DPRINTF(("ad1848: Auto calibration timed out(2).\n"));
                    237:     }
                    238:
                    239:     timeout = 100000;
                    240:     while (timeout > 0 && ad_read(sc, SP_TEST_AND_INIT) & AUTO_CAL_IN_PROG)
                    241:        timeout--;
                    242:     if (ad_read(sc, SP_TEST_AND_INIT) & AUTO_CAL_IN_PROG)
                    243:         DPRINTF(("ad1848: Auto calibration timed out(3).\n"));
                    244: }
                    245:
                    246: #ifdef AUDIO_DEBUG
                    247: void ad1848_dump_regs(struct ad1848_softc *);
                    248:
                    249: void
                    250: ad1848_dump_regs(sc)
                    251:     struct ad1848_softc *sc;
                    252: {
                    253:     int i;
                    254:     u_char r;
                    255:
                    256:     printf("ad1848 status=%02x", ADREAD(sc, AD1848_STATUS));
                    257:     printf(" regs: ");
                    258:     for (i = 0; i < 16; i++) {
                    259:        r = ad_read(sc, i);
                    260:        printf("%02x ", r);
                    261:     }
                    262:     if (sc->mode == 2) {
                    263:            for (i = 16; i < 32; i++) {
                    264:                    r = ad_read(sc, i);
                    265:                    printf("%02x ", r);
                    266:            }
                    267:     }
                    268:     printf("\n");
                    269: }
                    270: #endif
                    271:
                    272: /*
                    273:  * Map and probe for the ad1848 chip
                    274:  */
                    275: int
                    276: ad1848_mapprobe(sc, iobase)
                    277:     struct ad1848_softc *sc;
                    278:     int iobase;
                    279: {
                    280:     if (!AD1848_BASE_VALID(iobase)) {
                    281: #ifdef AUDIO_DEBUG
                    282:        printf("ad1848: configured iobase %04x invalid\n", iobase);
                    283: #endif
                    284:        return 0;
                    285:     }
                    286:
                    287:     sc->sc_iooffs = 0;
                    288:     /* Map the AD1848 ports */
                    289:     if (bus_space_map(sc->sc_iot, iobase, AD1848_NPORT, 0, &sc->sc_ioh))
                    290:        return 0;
                    291:
                    292:     if (!ad1848_probe(sc)) {
                    293:        bus_space_unmap(sc->sc_iot, sc->sc_ioh, AD1848_NPORT);
                    294:        return 0;
                    295:     } else
                    296:        return 1;
                    297: }
                    298:
                    299: /*
                    300:  * Probe for the ad1848 chip
                    301:  */
                    302: int
                    303: ad1848_probe(sc)
                    304:     struct ad1848_softc *sc;
                    305: {
                    306:     u_char tmp, tmp1 = 0xff, tmp2 = 0xff;
                    307: #if 0
                    308:     int i;
                    309: #endif
                    310:
                    311:     /* Is there an ad1848 chip ? */
                    312:     sc->MCE_bit = MODE_CHANGE_ENABLE;
                    313:     sc->mode = 1;      /* MODE 1 = original ad1848/ad1846/cs4248 */
                    314:
                    315:     /*
                    316:      * Check that the I/O address is in use.
                    317:      *
                    318:      * The SP_IN_INIT bit of the base I/O port is known to be 0 after the
                    319:      * chip has performed its power-on initialization. Just assume
                    320:      * this has happened before the OS is starting.
                    321:      *
                    322:      * If the I/O address is unused, inb() typically returns 0xff.
                    323:      */
                    324:     tmp = ADREAD(sc, AD1848_IADDR);
                    325:     if (tmp & SP_IN_INIT) { /* Not a AD1848 */
                    326: #if 0
                    327:        DPRINTF(("ad_detect_A %x\n", tmp));
                    328: #endif
                    329:        goto bad;
                    330:     }
                    331:
                    332:     /*
                    333:      * Test if it's possible to change contents of the indirect registers.
                    334:      * Registers 0 and 1 are ADC volume registers. The bit 0x10 is read only
                    335:      * so try to avoid using it.
                    336:      */
                    337:     ad_write(sc, 0, 0xaa);
                    338:     ad_write(sc, 1, 0x45);     /* 0x55 with bit 0x10 clear */
                    339:
                    340:     if ((tmp1 = ad_read(sc, 0)) != 0xaa ||
                    341:        (tmp2 = ad_read(sc, 1)) != 0x45) {
                    342:        DPRINTF(("ad_detect_B (%x/%x)\n", tmp1, tmp2));
                    343:        goto bad;
                    344:     }
                    345:
                    346:     ad_write(sc, 0, 0x45);
                    347:     ad_write(sc, 1, 0xaa);
                    348:
                    349:     if ((tmp1 = ad_read(sc, 0)) != 0x45 ||
                    350:        (tmp2 = ad_read(sc, 1)) != 0xaa) {
                    351:        DPRINTF(("ad_detect_C (%x/%x)\n", tmp1, tmp2));
                    352:        goto bad;
                    353:     }
                    354:
                    355:     /*
                    356:      * The indirect register I12 has some read only bits. Lets
                    357:      * try to change them.
                    358:      */
                    359:     tmp = ad_read(sc, SP_MISC_INFO);
                    360:     ad_write(sc, SP_MISC_INFO, (~tmp) & 0x0f);
                    361:
                    362:     if ((tmp & 0x0f) != ((tmp1 = ad_read(sc, SP_MISC_INFO)) & 0x0f)) {
                    363:        DPRINTF(("ad_detect_D (%x)\n", tmp1));
                    364:        goto bad;
                    365:     }
                    366:
                    367:     /*
                    368:      * MSB and 4 LSBs of the reg I12 tell the chip revision.
                    369:      *
                    370:      * A preliminary version of the AD1846 data sheet stated that it
                    371:      * used an ID field of 0x0B.  The current version, however,
                    372:      * states that the AD1846 uses ID 0x0A, just like the AD1848K.
                    373:      *
                    374:      * this switch statement will need updating as newer clones arrive....
                    375:      */
                    376:     switch (tmp1 & 0x8f) {
                    377:     case 0x09:
                    378:        sc->chip_name = "AD1848J";
                    379:        break;
                    380:     case 0x0A:
                    381:        sc->chip_name = "AD1848K";
                    382:        break;
                    383: #if 0  /* See above */
                    384:     case 0x0B:
                    385:        sc->chip_name = "AD1846";
                    386:        break;
                    387: #endif
                    388:     case 0x81:
                    389:        sc->chip_name = "CS4248revB"; /* or CS4231 rev B; see below */
                    390:        break;
                    391:     case 0x89:
                    392:        sc->chip_name = "CS4248";
                    393:        break;
                    394:     case 0x8A:
                    395:        sc->chip_name = "broken"; /* CS4231/AD1845; see below */
                    396:        break;
                    397:     default:
                    398:        sc->chip_name = "unknown";
                    399:        DPRINTF(("ad1848: unknown codec version %#02X\n", (tmp1 & 0x8f)));
                    400:     }
                    401:
                    402: #if 0
                    403:     /*
                    404:      * XXX I don't know why, but this probe fails on an otherwise well-working
                    405:      * AW35/pro card, so I'll just take it out for now. [niklas@openbsd.org]
                    406:      */
                    407:
                    408:     /*
                    409:      * The original AD1848/CS4248 has just 16 indirect registers. This means
                    410:      * that I0 and I16 should return the same value (etc.).
                    411:      * Ensure that the Mode2 enable bit of I12 is 0. Otherwise this test fails
                    412:      * with CS4231, AD1845, etc.
                    413:      */
                    414:     ad_write(sc, SP_MISC_INFO, 0);     /* Mode2 = disabled */
                    415:
                    416:     for (i = 0; i < 16; i++)
                    417:        if ((tmp1 = ad_read(sc, i)) != (tmp2 = ad_read(sc, i + 16))) {
                    418:            if (i != SP_TEST_AND_INIT) {
                    419:                DPRINTF(("ad_detect_F(%d/%x/%x)\n", i, tmp1, tmp2));
                    420:                goto bad;
                    421:            }
                    422:        }
                    423: #endif
                    424:
                    425:     /*
                    426:      * Try to switch the chip to mode2 (CS4231) by setting the MODE2 bit
                    427:      * The bit 0x80 is always 1 in CS4248, CS4231, and AD1845.
                    428:      */
                    429:     ad_write(sc, SP_MISC_INFO, MODE2); /* Set mode2, clear 0x80 */
                    430:
                    431:     tmp1 = ad_read(sc, SP_MISC_INFO);
                    432:     if ((tmp1 & 0xc0) == (0x80 | MODE2)) {
                    433:        /*
                    434:         *      CS4231 or AD1845 detected - is it?
                    435:         *
                    436:         *      Verify that setting I2 doesn't change I18.
                    437:         */
                    438:        ad_write(sc, 18, 0x88); /* Set I18 to known value */
                    439:
                    440:        ad_write(sc, 2, 0x45);
                    441:        if ((tmp2 = ad_read(sc, 18)) != 0x45) { /* No change -> CS4231? */
                    442:            ad_write(sc, 2, 0xaa);
                    443:            if ((tmp2 = ad_read(sc, 18)) == 0xaa) {     /* Rotten bits? */
                    444:                DPRINTF(("ad_detect_H(%x)\n", tmp2));
                    445:                goto bad;
                    446:            }
                    447:
                    448:            /*
                    449:             *  It's a CS4231, or another clone with 32 registers.
                    450:             *  Let's find out which by checking I25.
                    451:             */
                    452:            if ((tmp1 & 0x8f) == 0x8a) {
                    453:                tmp1 = ad_read(sc, CS_VERSION_ID);
                    454:                switch (tmp1 & 0xe7) {
                    455:                case 0xA0:
                    456:                    sc->chip_name = "CS4231A";
                    457:                    break;
                    458:                case 0x80:
                    459:                    /*  XXX I25 no good, AD1845 same as CS4231 */
                    460:                    sc->chip_name = "CS4231 or AD1845";
                    461:                    break;
                    462:                case 0x82:
                    463:                case 0xa2:
                    464:                    sc->chip_name = "CS4232";
                    465:                    break;
                    466:                case 0x03:
                    467:                    sc->chip_name = "CS4236/CS4236B";
                    468:                    break;
                    469:                }
                    470:            }
                    471:            sc->mode = 2;
                    472:        }
                    473:     }
                    474:
                    475:     /* Wait for 1848 to init */
                    476:     while(ADREAD(sc, AD1848_IADDR) & SP_IN_INIT)
                    477:         ;
                    478:
                    479:     /* Wait for 1848 to autocal */
                    480:     ADWRITE(sc, AD1848_IADDR, SP_TEST_AND_INIT);
                    481:     while(ADREAD(sc, AD1848_IDATA) & AUTO_CAL_IN_PROG)
                    482:         ;
                    483:
                    484:     return 1;
                    485: bad:
                    486:     return 0;
                    487: }
                    488:
                    489: /* Unmap the I/O ports */
                    490: void
                    491: ad1848_unmap(sc)
                    492:     struct ad1848_softc *sc;
                    493: {
                    494:     bus_space_unmap(sc->sc_iot, sc->sc_ioh, AD1848_NPORT);
                    495: }
                    496:
                    497: /*
                    498:  * Attach hardware to driver, attach hardware driver to audio
                    499:  * pseudo-device driver .
                    500:  */
                    501: void
                    502: ad1848_attach(sc)
                    503:     struct ad1848_softc *sc;
                    504: {
                    505:     int i;
                    506:     struct ad1848_volume vol_mid = {220, 220};
                    507:     struct ad1848_volume vol_0   = {0, 0};
                    508:     struct audio_params pparams, rparams;
                    509:     int timeout;
                    510:
                    511:     sc->sc_locked = 0;
                    512:     sc->sc_playrun = NOTRUNNING;
                    513:     sc->sc_recrun = NOTRUNNING;
                    514:
                    515:     if (sc->sc_drq != -1) {
                    516:        if (isa_dmamap_create(sc->sc_isa, sc->sc_drq, MAX_ISADMA,
                    517:            BUS_DMA_NOWAIT|BUS_DMA_ALLOCNOW)) {
                    518:                printf("ad1848_attach: can't create map for drq %d\n",
                    519:                    sc->sc_drq);
                    520:                return;
                    521:        }
                    522:     }
                    523:     if (sc->sc_recdrq != -1 && sc->sc_recdrq != sc->sc_drq) {
                    524:        if (isa_dmamap_create(sc->sc_isa, sc->sc_recdrq, MAX_ISADMA,
                    525:            BUS_DMA_NOWAIT|BUS_DMA_ALLOCNOW)) {
                    526:                printf("ad1848_attach: can't creape map for drq %d\n",
                    527:                    sc->sc_recdrq);
                    528:                return;
                    529:        }
                    530:     }
                    531:
                    532:     /* Initialize the ad1848... */
                    533:     for (i = 0; i < 0x10; i++) {
                    534:        ad_write(sc, i, ad1848_init_values[i]);
                    535:         timeout = 100000;
                    536:         while (timeout > 0 && ad_read(sc, AD1848_IADDR) & SP_IN_INIT)
                    537:            timeout--;
                    538:     }
                    539:     /* ...and additional CS4231 stuff too */
                    540:     if (sc->mode == 2) {
                    541:            ad_write(sc, SP_INTERFACE_CONFIG, 0); /* disable SINGLE_DMA */
                    542:            for (i = 0x10; i < 0x20; i++)
                    543:                    if (ad1848_init_values[i] != 0) {
                    544:                            ad_write(sc, i, ad1848_init_values[i]);
                    545:                            timeout = 100000;
                    546:                            while (timeout > 0 &&
                    547:                                   ad_read(sc, AD1848_IADDR) & SP_IN_INIT)
                    548:                                timeout--;
                    549:                    }
                    550:     }
                    551:     ad1848_reset(sc);
                    552:
                    553:     pparams = audio_default;
                    554:     rparams = audio_default;
                    555:     (void) ad1848_set_params(sc, AUMODE_RECORD|AUMODE_PLAY, 0, &pparams, &rparams);
                    556:
                    557:     /* Set default gains */
                    558:     (void) ad1848_set_rec_gain(sc, &vol_mid);
                    559:     (void) ad1848_set_channel_gain(sc, AD1848_DAC_CHANNEL, &vol_mid);
                    560:     (void) ad1848_set_channel_gain(sc, AD1848_MONITOR_CHANNEL, &vol_0);
                    561:     (void) ad1848_set_channel_gain(sc, AD1848_AUX1_CHANNEL, &vol_mid); /* CD volume */
                    562:     if (sc->mode == 2) {
                    563:        (void) ad1848_set_channel_gain(sc, AD1848_AUX2_CHANNEL, &vol_mid); /* CD volume */
                    564:        (void) ad1848_set_channel_gain(sc, AD1848_LINE_CHANNEL, &vol_mid);
                    565:        (void) ad1848_set_channel_gain(sc, AD1848_MONO_CHANNEL, &vol_0);
                    566:        sc->mute[AD1848_MONO_CHANNEL] = MUTE_ALL;
                    567:     } else
                    568:        (void) ad1848_set_channel_gain(sc, AD1848_AUX2_CHANNEL, &vol_0);
                    569:
                    570:     /* Set default port */
                    571:     (void) ad1848_set_rec_port(sc, MIC_IN_PORT);
                    572:
                    573:     if (sc->chip_name)
                    574:        printf(": %s", sc->chip_name);
                    575: #undef WAITREADY
                    576: }
                    577:
                    578: /*
                    579:  * Various routines to interface to higher level audio driver
                    580:  */
                    581: struct ad1848_mixerinfo {
                    582:   int  left_reg;
                    583:   int  right_reg;
                    584:   int  atten_bits;
                    585:   int  atten_mask;
                    586: } mixer_channel_info[] =
                    587: { { SP_LEFT_AUX2_CONTROL, SP_RIGHT_AUX2_CONTROL, AUX_INPUT_ATTEN_BITS,
                    588:     AUX_INPUT_ATTEN_MASK },
                    589:   { SP_LEFT_AUX1_CONTROL, SP_RIGHT_AUX1_CONTROL, AUX_INPUT_ATTEN_BITS,
                    590:     AUX_INPUT_ATTEN_MASK },
                    591:   { SP_LEFT_OUTPUT_CONTROL, SP_RIGHT_OUTPUT_CONTROL,
                    592:     OUTPUT_ATTEN_BITS, OUTPUT_ATTEN_MASK },
                    593:   { CS_LEFT_LINE_CONTROL, CS_RIGHT_LINE_CONTROL, LINE_INPUT_ATTEN_BITS,
                    594:     LINE_INPUT_ATTEN_MASK },
                    595:   { CS_MONO_IO_CONTROL, 0, MONO_INPUT_ATTEN_BITS, MONO_INPUT_ATTEN_MASK },
                    596:   { SP_DIGITAL_MIX, 0, OUTPUT_ATTEN_BITS, MIX_ATTEN_MASK }
                    597: };
                    598:
                    599: /*
                    600:  *  This function doesn't set the mute flags but does use them.
                    601:  *  The mute flags reflect the mutes that have been applied by the user.
                    602:  *  However, the driver occasionally wants to mute devices (e.g. when chaing
                    603:  *  sampling rate). These operations should not affect the mute flags.
                    604:  */
                    605:
                    606: void
                    607: ad1848_mute_channel(sc, device, mute)
                    608:        struct ad1848_softc *sc;
                    609:        int device;
                    610:        int mute;
                    611: {
                    612:   u_char reg;
                    613:
                    614:   reg = ad_read(sc, mixer_channel_info[device].left_reg);
                    615:
                    616:   if (mute & MUTE_LEFT) {
                    617:     if (device == AD1848_MONITOR_CHANNEL)
                    618:         ad_write(sc, mixer_channel_info[device].left_reg, reg & 0xFE);
                    619:     else
                    620:         ad_write(sc, mixer_channel_info[device].left_reg, reg | 0x80);
                    621:   } else if (!(sc->mute[device] & MUTE_LEFT)) {
                    622:     if (device == AD1848_MONITOR_CHANNEL)
                    623:         ad_write(sc, mixer_channel_info[device].left_reg, reg | 0x01);
                    624:     else
                    625:         ad_write(sc, mixer_channel_info[device].left_reg, reg & ~0x80);
                    626:   }
                    627:
                    628:   if (!mixer_channel_info[device].right_reg) {
                    629:     return;
                    630:   }
                    631:
                    632:   reg = ad_read(sc, mixer_channel_info[device].right_reg);
                    633:
                    634:   if (mute & MUTE_RIGHT)
                    635:     ad_write(sc, mixer_channel_info[device].right_reg, reg | 0x80);
                    636:   else if (!(sc->mute[device] & MUTE_RIGHT)) {
                    637:     ad_write(sc, mixer_channel_info[device].right_reg, reg & ~0x80);
                    638:   }
                    639: }
                    640:
                    641:
                    642: int
                    643: ad1848_set_channel_gain(sc, device, gp)
                    644:     struct ad1848_softc *sc;
                    645:     int device;
                    646:     struct ad1848_volume *gp;
                    647: {
                    648:     struct ad1848_mixerinfo *info = &mixer_channel_info[device];
                    649:     u_char reg;
                    650:     u_int atten;
                    651:
                    652:     sc->gains[device] = *gp;
                    653:
                    654:     atten = ((AUDIO_MAX_GAIN - gp->left) * info->atten_bits)/AUDIO_MAX_GAIN;
                    655:
                    656:     reg = ad_read(sc, info->left_reg) & (info->atten_mask);
                    657:     if (device == AD1848_MONITOR_CHANNEL)
                    658:       reg |= ((atten & info->atten_bits) << 2);
                    659:     else
                    660:       reg |= ((atten & info->atten_bits));
                    661:
                    662:     ad_write(sc, info->left_reg, reg);
                    663:
                    664:     if (!info->right_reg)
                    665:       return (0);
                    666:
                    667:     atten = ((AUDIO_MAX_GAIN - gp->right) * info->atten_bits)/AUDIO_MAX_GAIN;
                    668:     reg = ad_read(sc, info->right_reg);
                    669:     reg &= (info->atten_mask);
                    670:     ad_write(sc, info->right_reg, (atten& info->atten_bits)|reg);
                    671:
                    672:     return(0);
                    673: }
                    674:
                    675:
                    676: int
                    677: ad1848_get_device_gain(sc, device, gp)
                    678:     struct ad1848_softc *sc;
                    679:     int device;
                    680:     struct ad1848_volume *gp;
                    681: {
                    682:     *gp = sc->gains[device];
                    683:     return(0);
                    684: }
                    685:
                    686: int
                    687: ad1848_get_rec_gain(sc, gp)
                    688:     struct ad1848_softc *sc;
                    689:     struct ad1848_volume *gp;
                    690: {
                    691:     *gp = sc->rec_gain;
                    692:     return(0);
                    693: }
                    694:
                    695: int
                    696: ad1848_set_rec_gain(sc, gp)
                    697:     struct ad1848_softc *sc;
                    698:     struct ad1848_volume *gp;
                    699: {
                    700:     u_char reg, gain;
                    701:
                    702:     DPRINTF(("ad1848_set_rec_gain: %d:%d\n", gp->left, gp->right));
                    703:
                    704:     sc->rec_gain = *gp;
                    705:
                    706:     gain = (gp->left * GAIN_22_5)/AUDIO_MAX_GAIN;
                    707:     reg = ad_read(sc, SP_LEFT_INPUT_CONTROL);
                    708:     reg &= INPUT_GAIN_MASK;
                    709:     ad_write(sc, SP_LEFT_INPUT_CONTROL, (gain&0x0f)|reg);
                    710:
                    711:     gain = (gp->right * GAIN_22_5)/AUDIO_MAX_GAIN;
                    712:     reg = ad_read(sc, SP_RIGHT_INPUT_CONTROL);
                    713:     reg &= INPUT_GAIN_MASK;
                    714:     ad_write(sc, SP_RIGHT_INPUT_CONTROL, (gain&0x0f)|reg);
                    715:
                    716:     return(0);
                    717: }
                    718:
                    719:
                    720: void
                    721: ad1848_mute_monitor(addr, mute)
                    722:        void *addr;
                    723:        int mute;
                    724: {
                    725:        struct ad1848_softc *sc = addr;
                    726:
                    727:        DPRINTF(("ad1848_mute_monitor: %smuting\n", mute ? "" : "un"));
                    728:        if (sc->mode == 2) {
                    729:                ad1848_mute_channel(sc, AD1848_DAC_CHANNEL, mute ? MUTE_ALL : 0);
                    730:                ad1848_mute_channel(sc, AD1848_MONO_CHANNEL, mute ? MUTE_MONO : 0);
                    731:                ad1848_mute_channel(sc, AD1848_LINE_CHANNEL, mute ? MUTE_ALL : 0);
                    732:        }
                    733:
                    734:        ad1848_mute_channel(sc, AD1848_AUX2_CHANNEL, mute ? MUTE_ALL : 0);
                    735:        ad1848_mute_channel(sc, AD1848_AUX1_CHANNEL, mute ? MUTE_ALL : 0);
                    736: }
                    737:
                    738: int
                    739: ad1848_set_mic_gain(sc, gp)
                    740:     struct ad1848_softc *sc;
                    741:     struct ad1848_volume *gp;
                    742: {
                    743:     u_char reg;
                    744:
                    745:     DPRINTF(("cs4231_set_mic_gain: %d\n", gp->left));
                    746:
                    747:     if (gp->left > AUDIO_MAX_GAIN/2) {
                    748:            sc->mic_gain_on = 1;
                    749:            reg = ad_read(sc, SP_LEFT_INPUT_CONTROL);
                    750:            ad_write(sc, SP_LEFT_INPUT_CONTROL, reg | INPUT_MIC_GAIN_ENABLE);
                    751:     } else {
                    752:            sc->mic_gain_on = 0;
                    753:            reg = ad_read(sc, SP_LEFT_INPUT_CONTROL);
                    754:            ad_write(sc, SP_LEFT_INPUT_CONTROL, reg & ~INPUT_MIC_GAIN_ENABLE);
                    755:     }
                    756:
                    757:     return(0);
                    758: }
                    759:
                    760: int
                    761: ad1848_get_mic_gain(sc, gp)
                    762:     struct ad1848_softc *sc;
                    763:     struct ad1848_volume *gp;
                    764: {
                    765:        if (sc->mic_gain_on)
                    766:                gp->left = gp->right = AUDIO_MAX_GAIN;
                    767:        else
                    768:                gp->left = gp->right = AUDIO_MIN_GAIN;
                    769:        return(0);
                    770: }
                    771:
                    772:
                    773: static ad1848_devmap_t *ad1848_mixer_find_dev(ad1848_devmap_t *, int, mixer_ctrl_t *);
                    774:
                    775: static ad1848_devmap_t *
                    776: ad1848_mixer_find_dev(map, cnt, cp)
                    777:   ad1848_devmap_t *map;
                    778:   int cnt;
                    779:   mixer_ctrl_t *cp;
                    780:
                    781: {
                    782:   int idx;
                    783:
                    784:   for (idx = 0; idx < cnt; idx++) {
                    785:     if (map[idx].id == cp->dev) {
                    786:       return (&map[idx]);
                    787:     }
                    788:   }
                    789:   return (NULL);
                    790: }
                    791:
                    792: int
                    793: ad1848_mixer_get_port(ac, map, cnt, cp)
                    794:   struct ad1848_softc *ac;
                    795:   struct ad1848_devmap *map;
                    796:   int cnt;
                    797:   mixer_ctrl_t *cp;
                    798: {
                    799:   ad1848_devmap_t *entry;
                    800:   struct ad1848_volume vol;
                    801:   int error = EINVAL;
                    802:   int dev;
                    803:
                    804:   if (!(entry = ad1848_mixer_find_dev(map, cnt, cp)))
                    805:     return (ENXIO);
                    806:
                    807:   dev = entry->dev;
                    808:
                    809:   switch (entry->kind) {
                    810:   case AD1848_KIND_LVL:
                    811:     if (cp->type != AUDIO_MIXER_VALUE)
                    812:       break;
                    813:
                    814:     if (dev < AD1848_AUX2_CHANNEL ||
                    815:        dev > AD1848_MONITOR_CHANNEL)
                    816:       break;
                    817:
                    818:     if (cp->un.value.num_channels != 1 &&
                    819:         mixer_channel_info[dev].right_reg == 0)
                    820:       break;
                    821:
                    822:     error = ad1848_get_device_gain(ac, dev, &vol);
                    823:     if (!error)
                    824:       ad1848_from_vol(cp, &vol);
                    825:
                    826:     break;
                    827:
                    828:   case AD1848_KIND_MUTE:
                    829:     if (cp->type != AUDIO_MIXER_ENUM) break;
                    830:
                    831:     cp->un.ord = ac->mute[dev] ? 1 : 0;
                    832:     error = 0;
                    833:     break;
                    834:
                    835:   case AD1848_KIND_RECORDGAIN:
                    836:     if (cp->type != AUDIO_MIXER_VALUE) break;
                    837:
                    838:     error = ad1848_get_rec_gain(ac, &vol);
                    839:     if (!error)
                    840:       ad1848_from_vol(cp, &vol);
                    841:
                    842:     break;
                    843:
                    844:   case AD1848_KIND_MICGAIN:
                    845:     if (cp->type != AUDIO_MIXER_VALUE) break;
                    846:
                    847:     error = ad1848_get_mic_gain(ac, &vol);
                    848:     if (!error)
                    849:       ad1848_from_vol(cp, &vol);
                    850:
                    851:     break;
                    852:
                    853:   case AD1848_KIND_RECORDSOURCE:
                    854:     if (cp->type != AUDIO_MIXER_ENUM) break;
                    855:     cp->un.ord = ad1848_get_rec_port(ac);
                    856:     error = 0;
                    857:     break;
                    858:   default:
                    859:     printf ("Invalid kind\n");
                    860:     break;
                    861:   }
                    862:
                    863:   return (error);
                    864: }
                    865:
                    866: int
                    867: ad1848_mixer_set_port(ac, map, cnt, cp)
                    868:   struct ad1848_softc *ac;
                    869:   struct ad1848_devmap *map;
                    870:   int cnt;
                    871:   mixer_ctrl_t *cp;
                    872: {
                    873:   ad1848_devmap_t *entry;
                    874:   struct ad1848_volume vol;
                    875:   int error = EINVAL;
                    876:   int dev;
                    877:
                    878:   if (!(entry = ad1848_mixer_find_dev(map, cnt, cp)))
                    879:     return (ENXIO);
                    880:
                    881:   dev = entry->dev;
                    882:
                    883:   switch (entry->kind) {
                    884:   case AD1848_KIND_LVL:
                    885:     if (cp->type != AUDIO_MIXER_VALUE)
                    886:       break;
                    887:
                    888:     if (dev < AD1848_AUX2_CHANNEL ||
                    889:        dev > AD1848_MONITOR_CHANNEL)
                    890:       break;
                    891:
                    892:     if (cp->un.value.num_channels != 1 &&
                    893:         mixer_channel_info[dev].right_reg == 0)
                    894:       break;
                    895:
                    896:     ad1848_to_vol(cp, &vol);
                    897:     error = ad1848_set_channel_gain(ac, dev, &vol);
                    898:     break;
                    899:
                    900:   case AD1848_KIND_MUTE:
                    901:     if (cp->type != AUDIO_MIXER_ENUM) break;
                    902:
                    903:     ac->mute[dev] = (cp->un.ord ? MUTE_ALL : 0);
                    904:     ad1848_mute_channel(ac, dev, ac->mute[dev]);
                    905:     error = 0;
                    906:     break;
                    907:
                    908:   case AD1848_KIND_RECORDGAIN:
                    909:     if (cp->type != AUDIO_MIXER_VALUE) break;
                    910:
                    911:     ad1848_to_vol(cp, &vol);
                    912:     error = ad1848_set_rec_gain(ac, &vol);
                    913:     break;
                    914:
                    915:   case AD1848_KIND_MICGAIN:
                    916:     if (cp->type != AUDIO_MIXER_VALUE) break;
                    917:
                    918:     ad1848_to_vol(cp, &vol);
                    919:     error = ad1848_set_mic_gain(ac, &vol);
                    920:     break;
                    921:
                    922:   case AD1848_KIND_RECORDSOURCE:
                    923:     if (cp->type != AUDIO_MIXER_ENUM) break;
                    924:
                    925:     error = ad1848_set_rec_port(ac,  cp->un.ord);
                    926:     break;
                    927:   default:
                    928:     printf ("Invalid kind\n");
                    929:     break;
                    930:   }
                    931:
                    932:   return (error);
                    933: }
                    934:
                    935:
                    936: int
                    937: ad1848_query_encoding(addr, fp)
                    938:     void *addr;
                    939:     struct audio_encoding *fp;
                    940: {
                    941:     struct ad1848_softc *sc = addr;
                    942:
                    943:     switch (fp->index) {
                    944:     case 0:
                    945:        strlcpy(fp->name, AudioEmulaw, sizeof fp->name);
                    946:        fp->encoding = AUDIO_ENCODING_ULAW;
                    947:        fp->precision = 8;
                    948:        fp->flags = 0;
                    949:        break;
                    950:     case 1:
                    951:        strlcpy(fp->name, AudioEalaw, sizeof fp->name);
                    952:        fp->encoding = AUDIO_ENCODING_ALAW;
                    953:        fp->precision = 8;
                    954:        fp->flags = 0;
                    955:        break;
                    956:     case 2:
                    957:        strlcpy(fp->name, AudioEslinear_le, sizeof fp->name);
                    958:        fp->encoding = AUDIO_ENCODING_SLINEAR_LE;
                    959:        fp->precision = 16;
                    960:        fp->flags = 0;
                    961:        break;
                    962:     case 3:
                    963:        strlcpy(fp->name, AudioEulinear, sizeof fp->name);
                    964:        fp->encoding = AUDIO_ENCODING_ULINEAR;
                    965:        fp->precision = 8;
                    966:        fp->flags = 0;
                    967:        break;
                    968:
                    969:     case 4: /* only on CS4231 */
                    970:        strlcpy(fp->name, AudioEslinear_be, sizeof fp->name);
                    971:        fp->encoding = AUDIO_ENCODING_SLINEAR_BE;
                    972:        fp->precision = 16;
                    973:        fp->flags = sc->mode == 1 ? AUDIO_ENCODINGFLAG_EMULATED : 0;
                    974:        break;
                    975:
                    976:     /* emulate some modes */
                    977:     case 5:
                    978:        strlcpy(fp->name, AudioEslinear, sizeof fp->name);
                    979:        fp->encoding = AUDIO_ENCODING_SLINEAR;
                    980:        fp->precision = 8;
                    981:        fp->flags = AUDIO_ENCODINGFLAG_EMULATED;
                    982:        break;
                    983:     case 6:
                    984:        strlcpy(fp->name, AudioEulinear_le, sizeof fp->name);
                    985:        fp->encoding = AUDIO_ENCODING_ULINEAR_LE;
                    986:        fp->precision = 16;
                    987:        fp->flags = AUDIO_ENCODINGFLAG_EMULATED;
                    988:        break;
                    989:     case 7:
                    990:        strlcpy(fp->name, AudioEulinear_be, sizeof fp->name);
                    991:        fp->encoding = AUDIO_ENCODING_ULINEAR_BE;
                    992:        fp->precision = 16;
                    993:        fp->flags = AUDIO_ENCODINGFLAG_EMULATED;
                    994:        break;
                    995:
                    996:     case 8: /* only on CS4231 */
                    997:        if (sc->mode == 1)
                    998:            return EINVAL;
                    999:        strlcpy(fp->name, AudioEadpcm, sizeof fp->name);
                   1000:        fp->encoding = AUDIO_ENCODING_ADPCM;
                   1001:        fp->precision = 8;
                   1002:        fp->flags = 0;
                   1003:        break;
                   1004:     default:
                   1005:        return EINVAL;
                   1006:        /*NOTREACHED*/
                   1007:     }
                   1008:     return (0);
                   1009: }
                   1010:
                   1011: int
                   1012: ad1848_set_params(addr, setmode, usemode, p, r)
                   1013:     void *addr;
                   1014:     int setmode, usemode;
                   1015:     struct audio_params *p, *r;
                   1016: {
                   1017:     struct ad1848_softc *sc = addr;
                   1018:     int error, bits, enc;
                   1019:     void (*pswcode)(void *, u_char *buf, int cnt);
                   1020:     void (*rswcode)(void *, u_char *buf, int cnt);
                   1021:
                   1022:     DPRINTF(("ad1848_set_params: %d %d %d %ld\n",
                   1023:             p->encoding, p->precision, p->channels, p->sample_rate));
                   1024:
                   1025:     enc = p->encoding;
                   1026:     pswcode = rswcode = 0;
                   1027:     switch (enc) {
                   1028:     case AUDIO_ENCODING_SLINEAR_LE:
                   1029:        if (p->precision == 8) {
                   1030:            enc = AUDIO_ENCODING_ULINEAR_LE;
                   1031:            pswcode = rswcode = change_sign8;
                   1032:        }
                   1033:        break;
                   1034:     case AUDIO_ENCODING_SLINEAR_BE:
                   1035:        if (p->precision == 16 && sc->mode == 1) {
                   1036:            enc = AUDIO_ENCODING_SLINEAR_LE;
                   1037:            pswcode = rswcode = swap_bytes;
                   1038:        }
                   1039:        break;
                   1040:     case AUDIO_ENCODING_ULINEAR_LE:
                   1041:        if (p->precision == 16) {
                   1042:            enc = AUDIO_ENCODING_SLINEAR_LE;
                   1043:            pswcode = rswcode = change_sign16;
                   1044:        }
                   1045:        break;
                   1046:     case AUDIO_ENCODING_ULINEAR_BE:
                   1047:        if (p->precision == 16) {
                   1048:            enc = AUDIO_ENCODING_SLINEAR_LE;
                   1049:            pswcode = swap_bytes_change_sign16;
                   1050:            rswcode = change_sign16_swap_bytes;
                   1051:        }
                   1052:        break;
                   1053:     }
                   1054:     switch (enc) {
                   1055:     case AUDIO_ENCODING_ULAW:
                   1056:        bits = FMT_ULAW >> 5;
                   1057:        break;
                   1058:     case AUDIO_ENCODING_ALAW:
                   1059:        bits = FMT_ALAW >> 5;
                   1060:        break;
                   1061:     case AUDIO_ENCODING_ADPCM:
                   1062:        bits = FMT_ADPCM >> 5;
                   1063:        break;
                   1064:     case AUDIO_ENCODING_SLINEAR_LE:
                   1065:        if (p->precision == 16)
                   1066:            bits = FMT_TWOS_COMP >> 5;
                   1067:        else
                   1068:            return EINVAL;
                   1069:        break;
                   1070:     case AUDIO_ENCODING_SLINEAR_BE:
                   1071:        if (p->precision == 16)
                   1072:            bits = FMT_TWOS_COMP_BE >> 5;
                   1073:        else
                   1074:            return EINVAL;
                   1075:        break;
                   1076:     case AUDIO_ENCODING_ULINEAR_LE:
                   1077:        if (p->precision == 8)
                   1078:            bits = FMT_PCM8 >> 5;
                   1079:        else
                   1080:            return EINVAL;
                   1081:        break;
                   1082:     default:
                   1083:        return EINVAL;
                   1084:     }
                   1085:
                   1086:     if (p->channels < 1 || p->channels > 2)
                   1087:        return EINVAL;
                   1088:
                   1089:     error = ad1848_set_speed(sc, &p->sample_rate);
                   1090:     if (error)
                   1091:        return error;
                   1092:
                   1093:     p->sw_code = pswcode;
                   1094:     r->sw_code = rswcode;
                   1095:
                   1096:     sc->format_bits = bits;
                   1097:     sc->channels = p->channels;
                   1098:     sc->precision = p->precision;
                   1099:     sc->need_commit = 1;
                   1100:
                   1101:     DPRINTF(("ad1848_set_params succeeded, bits=%x\n", bits));
                   1102:     return (0);
                   1103: }
                   1104:
                   1105: int
                   1106: ad1848_set_rec_port(sc, port)
                   1107:     struct ad1848_softc *sc;
                   1108:     int port;
                   1109: {
                   1110:     u_char inp, reg;
                   1111:
                   1112:     DPRINTF(("ad1848_set_rec_port: 0x%x\n", port));
                   1113:
                   1114:     if (port == MIC_IN_PORT) {
                   1115:        inp = MIC_INPUT;
                   1116:     }
                   1117:     else if (port == LINE_IN_PORT) {
                   1118:        inp = LINE_INPUT;
                   1119:     }
                   1120:     else if (port == DAC_IN_PORT) {
                   1121:        inp = MIXED_DAC_INPUT;
                   1122:     }
                   1123:     else if (sc->mode == 2 && port == AUX1_IN_PORT) {
                   1124:        inp = AUX_INPUT;
                   1125:     }
                   1126:     else
                   1127:        return(EINVAL);
                   1128:
                   1129:     reg = ad_read(sc, SP_LEFT_INPUT_CONTROL);
                   1130:     reg &= INPUT_SOURCE_MASK;
                   1131:     ad_write(sc, SP_LEFT_INPUT_CONTROL, (inp|reg));
                   1132:
                   1133:     reg = ad_read(sc, SP_RIGHT_INPUT_CONTROL);
                   1134:     reg &= INPUT_SOURCE_MASK;
                   1135:     ad_write(sc, SP_RIGHT_INPUT_CONTROL, (inp|reg));
                   1136:
                   1137:     sc->rec_port = port;
                   1138:
                   1139:     return(0);
                   1140: }
                   1141:
                   1142: int
                   1143: ad1848_get_rec_port(sc)
                   1144:     struct ad1848_softc *sc;
                   1145: {
                   1146:     return(sc->rec_port);
                   1147: }
                   1148:
                   1149: int
                   1150: ad1848_round_blocksize(addr, blk)
                   1151:     void *addr;
                   1152:     int blk;
                   1153: {
                   1154:     struct ad1848_softc *sc = addr;
                   1155:
                   1156:     sc->sc_lastcc = -1;
                   1157:
                   1158:     /* Round to a multiple of the biggest sample size. */
                   1159:     blk = (blk + 3) & -4;
                   1160:
                   1161:     return (blk);
                   1162: }
                   1163:
                   1164: int
                   1165: ad1848_open(addr, flags)
                   1166:     void *addr;
                   1167:     int flags;
                   1168: {
                   1169:     struct ad1848_softc *sc = addr;
                   1170:
                   1171:     DPRINTF(("ad1848_open: sc=%p\n", sc));
                   1172:
                   1173:     sc->sc_intr = 0;
                   1174:     sc->sc_lastcc = -1;
                   1175:     sc->sc_locked = 0;
                   1176:
                   1177:     /* Enable interrupts */
                   1178:     DPRINTF(("ad1848_open: enable intrs\n"));
                   1179:     ad_write(sc, SP_PIN_CONTROL, INTERRUPT_ENABLE|ad_read(sc, SP_PIN_CONTROL));
                   1180:
                   1181: #ifdef AUDIO_DEBUG
                   1182:     if (ad1848debug)
                   1183:        ad1848_dump_regs(sc);
                   1184: #endif
                   1185:
                   1186:     return 0;
                   1187: }
                   1188:
                   1189: /*
                   1190:  * Close function is called at splaudio().
                   1191:  */
                   1192: void
                   1193: ad1848_close(addr)
                   1194:     void *addr;
                   1195: {
                   1196:     struct ad1848_softc *sc = addr;
                   1197:     u_char r;
                   1198:
                   1199:     sc->sc_intr = 0;
                   1200:
                   1201:     DPRINTF(("ad1848_close: stop DMA\n"));
                   1202:     if (sc->sc_playrun != NOTRUNNING) {
                   1203:        isa_dmaabort(sc->sc_isa, sc->sc_drq);
                   1204:        sc->sc_playrun = NOTRUNNING;
                   1205:     }
                   1206:     if (sc->sc_recrun != NOTRUNNING) {
                   1207:        isa_dmaabort(sc->sc_isa, sc->sc_recdrq);
                   1208:        sc->sc_recrun = NOTRUNNING;
                   1209:     }
                   1210:     ad_write(sc, SP_LOWER_BASE_COUNT, (u_char)0);
                   1211:     ad_write(sc, SP_UPPER_BASE_COUNT, (u_char)0);
                   1212:
                   1213:     /* Disable interrupts */
                   1214:     DPRINTF(("ad1848_close: disable intrs\n"));
                   1215:     ad_write(sc, SP_PIN_CONTROL,
                   1216:             ad_read(sc, SP_PIN_CONTROL) & ~INTERRUPT_ENABLE);
                   1217:
                   1218:     DPRINTF(("ad1848_close: disable capture and playback\n"));
                   1219:     r = ad_read(sc, SP_INTERFACE_CONFIG);
                   1220:     r &= ~(CAPTURE_ENABLE|PLAYBACK_ENABLE);
                   1221:     ad_write(sc, SP_INTERFACE_CONFIG, r);
                   1222:
                   1223: #ifdef AUDIO_DEBUG
                   1224:     if (ad1848debug)
                   1225:        ad1848_dump_regs(sc);
                   1226: #endif
                   1227: }
                   1228:
                   1229: /*
                   1230:  * Lower-level routines
                   1231:  */
                   1232: int
                   1233: ad1848_commit_settings(addr)
                   1234:     void *addr;
                   1235: {
                   1236:     struct ad1848_softc *sc = addr;
                   1237:     int timeout;
                   1238:     u_char fs;
                   1239:     int s;
                   1240:
                   1241:     if (!sc->need_commit)
                   1242:        return 0;
                   1243:
                   1244:     s = splaudio();
                   1245:
                   1246:     ad1848_mute_monitor(sc, 1);
                   1247:
                   1248:     ad_set_MCE(sc, 1);         /* Enables changes to the format select reg */
                   1249:
                   1250:     fs = sc->speed_bits | (sc->format_bits << 5);
                   1251:
                   1252:     if (sc->channels == 2)
                   1253:        fs |= FMT_STEREO;
                   1254:
                   1255:     ad_write(sc, SP_CLOCK_DATA_FORMAT, fs);
                   1256:
                   1257:     /*
                   1258:      * If mode == 2 (CS4231), set I28 also. It's the capture format register.
                   1259:      */
                   1260:     if (sc->mode == 2) {
                   1261:        /* Gravis Ultrasound MAX SDK sources says something about errata
                   1262:         * sheets, with the implication that these inb()s are necessary.
                   1263:         */
                   1264:        (void)ADREAD(sc, AD1848_IDATA);
                   1265:        (void)ADREAD(sc, AD1848_IDATA);
                   1266:        /*
                   1267:         * Write to I8 starts resynchronization. Wait until it completes.
                   1268:         */
                   1269:        timeout = 100000;
                   1270:        while (timeout > 0 && ADREAD(sc, AD1848_IADDR) == SP_IN_INIT)
                   1271:            timeout--;
                   1272:
                   1273:        ad_write(sc, CS_REC_FORMAT, fs);
                   1274:        /* Gravis Ultrasound MAX SDK sources says something about errata
                   1275:         * sheets, with the implication that these inb()s are necessary.
                   1276:         */
                   1277:        (void)ADREAD(sc, AD1848_IDATA);
                   1278:        (void)ADREAD(sc, AD1848_IDATA);
                   1279:        /* Now wait for resync for capture side of the house */
                   1280:     }
                   1281:     /*
                   1282:      * Write to I8 starts resynchronization. Wait until it completes.
                   1283:      */
                   1284:     timeout = 100000;
                   1285:     while (timeout > 0 && ADREAD(sc, AD1848_IADDR) == SP_IN_INIT)
                   1286:        timeout--;
                   1287:
                   1288:     if (ADREAD(sc, AD1848_IADDR) == SP_IN_INIT)
                   1289:        printf("ad1848_commit: Auto calibration timed out\n");
                   1290:
                   1291:     /*
                   1292:      * Starts the calibration process and
                   1293:      * enters playback mode after it.
                   1294:      */
                   1295:     ad_set_MCE(sc, 0);
                   1296:     wait_for_calibration(sc);
                   1297:
                   1298:     ad1848_mute_monitor(sc, 0);
                   1299:
                   1300:     sc->sc_lastcc = -1;
                   1301:
                   1302:     splx(s);
                   1303:
                   1304:     sc->need_commit = 0;
                   1305:     return 0;
                   1306: }
                   1307:
                   1308: void
                   1309: ad1848_reset(sc)
                   1310:     struct ad1848_softc *sc;
                   1311: {
                   1312:     u_char r;
                   1313:
                   1314:     DPRINTF(("ad1848_reset\n"));
                   1315:
                   1316:     /* Clear the PEN and CEN bits */
                   1317:     r = ad_read(sc, SP_INTERFACE_CONFIG);
                   1318:     r &= ~(CAPTURE_ENABLE|PLAYBACK_ENABLE);
                   1319:     ad_write(sc, SP_INTERFACE_CONFIG, r);
                   1320:
                   1321:     if (sc->mode == 2) {
                   1322:            ADWRITE(sc, AD1848_IADDR, CS_IRQ_STATUS);
                   1323:            ADWRITE(sc, AD1848_IDATA, 0);
                   1324:     }
                   1325:     /* Clear interrupt status */
                   1326:     ADWRITE(sc, AD1848_STATUS, 0);
                   1327: #ifdef AUDIO_DEBUG
                   1328:     if (ad1848debug)
                   1329:        ad1848_dump_regs(sc);
                   1330: #endif
                   1331: }
                   1332:
                   1333: int
                   1334: ad1848_set_speed(sc, argp)
                   1335:     struct ad1848_softc *sc;
                   1336:     u_long *argp;
                   1337: {
                   1338:     /*
                   1339:      * The sampling speed is encoded in the least significant nible of I8. The
                   1340:      * LSB selects the clock source (0=24.576 MHz, 1=16.9344 MHz) and other
                   1341:      * three bits select the divisor (indirectly):
                   1342:      *
                   1343:      * The available speeds are in the following table. Keep the speeds in
                   1344:      * the increasing order.
                   1345:      */
                   1346:     typedef struct {
                   1347:        int     speed;
                   1348:        u_char  bits;
                   1349:     } speed_struct;
                   1350:     u_long arg = *argp;
                   1351:
                   1352:     static speed_struct speed_table[] =  {
                   1353:        {5510, (0 << 1) | 1},
                   1354:        {5510, (0 << 1) | 1},
                   1355:        {6620, (7 << 1) | 1},
                   1356:        {8000, (0 << 1) | 0},
                   1357:        {9600, (7 << 1) | 0},
                   1358:        {11025, (1 << 1) | 1},
                   1359:        {16000, (1 << 1) | 0},
                   1360:        {18900, (2 << 1) | 1},
                   1361:        {22050, (3 << 1) | 1},
                   1362:        {27420, (2 << 1) | 0},
                   1363:        {32000, (3 << 1) | 0},
                   1364:        {33075, (6 << 1) | 1},
                   1365:        {37800, (4 << 1) | 1},
                   1366:        {44100, (5 << 1) | 1},
                   1367:        {48000, (6 << 1) | 0}
                   1368:     };
                   1369:
                   1370:     int i, n, selected = -1;
                   1371:
                   1372:     n = sizeof(speed_table) / sizeof(speed_struct);
                   1373:
                   1374:     if (arg < speed_table[0].speed)
                   1375:        selected = 0;
                   1376:     if (arg > speed_table[n - 1].speed)
                   1377:        selected = n - 1;
                   1378:
                   1379:     for (i = 1 /*really*/ ; selected == -1 && i < n; i++)
                   1380:        if (speed_table[i].speed == arg)
                   1381:            selected = i;
                   1382:        else if (speed_table[i].speed > arg) {
                   1383:            int diff1, diff2;
                   1384:
                   1385:            diff1 = arg - speed_table[i - 1].speed;
                   1386:            diff2 = speed_table[i].speed - arg;
                   1387:
                   1388:            if (diff1 < diff2)
                   1389:                selected = i - 1;
                   1390:            else
                   1391:                selected = i;
                   1392:        }
                   1393:
                   1394:     if (selected == -1) {
                   1395:        printf("ad1848: Can't find speed???\n");
                   1396:        selected = 3;
                   1397:     }
                   1398:
                   1399:     sc->speed_bits = speed_table[selected].bits;
                   1400:     sc->need_commit = 1;
                   1401:     *argp = speed_table[selected].speed;
                   1402:
                   1403:     return (0);
                   1404: }
                   1405:
                   1406: /*
                   1407:  * Halt a DMA in progress.
                   1408:  */
                   1409: int
                   1410: ad1848_halt_out_dma(addr)
                   1411:     void *addr;
                   1412: {
                   1413:     struct ad1848_softc *sc = addr;
                   1414:     u_char reg;
                   1415:
                   1416:     DPRINTF(("ad1848: ad1848_halt_out_dma\n"));
                   1417:
                   1418:     reg = ad_read(sc, SP_INTERFACE_CONFIG);
                   1419:     ad_write(sc, SP_INTERFACE_CONFIG, (reg & ~PLAYBACK_ENABLE));
                   1420:     sc->sc_locked = 0;
                   1421:
                   1422:     return(0);
                   1423: }
                   1424:
                   1425: int
                   1426: ad1848_halt_in_dma(addr)
                   1427:     void *addr;
                   1428: {
                   1429:     struct ad1848_softc *sc = addr;
                   1430:     u_char reg;
                   1431:
                   1432:     DPRINTF(("ad1848: ad1848_halt_in_dma\n"));
                   1433:
                   1434:     reg = ad_read(sc, SP_INTERFACE_CONFIG);
                   1435:     ad_write(sc, SP_INTERFACE_CONFIG, (reg & ~CAPTURE_ENABLE));
                   1436:     sc->sc_locked = 0;
                   1437:
                   1438:     return(0);
                   1439: }
                   1440:
                   1441: int
                   1442: ad1848_dma_init_input(addr, buf, cc)
                   1443:     void *addr;
                   1444:     void *buf;
                   1445:     int cc;
                   1446: {
                   1447:     struct ad1848_softc *sc = addr;
                   1448:
                   1449:     sc->sc_recrun = DMARUNNING;
                   1450:     sc->sc_dma_flags = DMAMODE_READ | DMAMODE_LOOP;
                   1451:     sc->sc_dma_bp = buf;
                   1452:     sc->sc_dma_cnt = cc;
                   1453:     isa_dmastart(sc->sc_isa, sc->sc_recdrq, buf, cc, NULL,
                   1454:                 sc->sc_dma_flags, BUS_DMA_NOWAIT);
                   1455:     DPRINTF(("ad1848_dma_init_input: %p %d\n", buf, cc));
                   1456:     return 0;
                   1457: }
                   1458:
                   1459: /*
                   1460:  * DMA input/output are called at splaudio().
                   1461:  */
                   1462: int
                   1463: ad1848_dma_input(addr, p, cc, intr, arg)
                   1464:     void *addr;
                   1465:     void *p;
                   1466:     int cc;
                   1467:     void (*intr)(void *);
                   1468:     void *arg;
                   1469: {
                   1470:     struct ad1848_softc *sc = addr;
                   1471:     u_char reg;
                   1472:
                   1473:     if (sc->sc_locked) {
                   1474:        DPRINTF(("ad1848_dma_input: locked\n"));
                   1475:        return 0;
                   1476:     }
                   1477:
                   1478: #ifdef AUDIO_DEBUG
                   1479:     if (ad1848debug > 1)
                   1480:        printf("ad1848_dma_input: cc=%d %p (%p)\n", cc, intr, arg);
                   1481: #endif
                   1482:     sc->sc_locked = 1;
                   1483:     sc->sc_intr = intr;
                   1484:     sc->sc_arg = arg;
                   1485:
                   1486:     switch (sc->sc_recrun) {
                   1487:     case NOTRUNNING:
                   1488:        sc->sc_dma_flags = DMAMODE_READ;
                   1489:        sc->sc_dma_bp = p;
                   1490:        sc->sc_dma_cnt = cc;
                   1491:        isa_dmastart(sc->sc_isa, sc->sc_recdrq, p, cc, NULL,
                   1492:                     DMAMODE_READ, BUS_DMA_NOWAIT);
                   1493:        goto startpcm;
                   1494:     case DMARUNNING:
                   1495:        sc->sc_recrun = PCMRUNNING;
                   1496:     startpcm:
                   1497:        if (sc->precision == 16)
                   1498:            cc >>= 1;
                   1499:        if (sc->channels == 2)
                   1500:            cc >>= 1;
                   1501:        cc--;
                   1502:
                   1503:        if (sc->sc_lastcc != cc || sc->sc_mode != AUMODE_RECORD) {
                   1504:            ad_write(sc, SP_LOWER_BASE_COUNT, (u_char)(cc & 0xff));
                   1505:            ad_write(sc, SP_UPPER_BASE_COUNT, (u_char)((cc >> 8) & 0xff));
                   1506:
                   1507:            if (sc->mode == 2) {
                   1508:                ad_write(sc, CS_LOWER_REC_CNT, (u_char)(cc & 0xff));
                   1509:                ad_write(sc, CS_UPPER_REC_CNT, (u_char)((cc >> 8) & 0xff));
                   1510:            }
                   1511:
                   1512:            reg = ad_read(sc, SP_INTERFACE_CONFIG);
                   1513:            ad_write(sc, SP_INTERFACE_CONFIG, (CAPTURE_ENABLE|reg));
                   1514:
                   1515:            sc->sc_lastcc = cc;
                   1516:            sc->sc_mode = AUMODE_RECORD;
                   1517: #ifdef AUDIO_DEBUG
                   1518:            if (ad1848debug > 1)
                   1519:                    printf("ad1848_dma_input: started capture\n");
                   1520: #endif
                   1521:        }
                   1522:     case PCMRUNNING:
                   1523:        break;
                   1524:     }
                   1525:
                   1526:     return 0;
                   1527: }
                   1528:
                   1529: int
                   1530: ad1848_dma_init_output(addr, buf, cc)
                   1531:     void *addr;
                   1532:     void *buf;
                   1533:     int cc;
                   1534: {
                   1535:     struct ad1848_softc *sc = addr;
                   1536:
                   1537:     sc->sc_playrun = DMARUNNING;
                   1538:     sc->sc_dma_flags = DMAMODE_WRITE | DMAMODE_LOOP;
                   1539:     sc->sc_dma_bp = buf;
                   1540:     sc->sc_dma_cnt = cc;
                   1541:     isa_dmastart(sc->sc_isa, sc->sc_drq, buf, cc, NULL,
                   1542:                 sc->sc_dma_flags, BUS_DMA_NOWAIT);
                   1543:     DPRINTF(("ad1848_dma_init_output: %p %d\n", buf, cc));
                   1544:     return 0;
                   1545: }
                   1546:
                   1547: int
                   1548: ad1848_dma_output(addr, p, cc, intr, arg)
                   1549:     void *addr;
                   1550:     void *p;
                   1551:     int cc;
                   1552:     void (*intr)(void *);
                   1553:     void *arg;
                   1554: {
                   1555:     struct ad1848_softc *sc = addr;
                   1556:     u_char reg;
                   1557:
                   1558:     if (sc->sc_locked) {
                   1559:        DPRINTF(("ad1848_dma_output: locked\n"));
                   1560:        return 0;
                   1561:     }
                   1562:
                   1563: #ifdef AUDIO_DEBUG
                   1564:     if (ad1848debug > 0)
                   1565:        printf("ad1848_dma_output: cc=%d at %p %p (%p)\n", cc, p, intr, arg);
                   1566: #endif
                   1567:     sc->sc_locked = 1;
                   1568:     sc->sc_intr = intr;
                   1569:     sc->sc_arg = arg;
                   1570:
                   1571:     switch (sc->sc_playrun) {
                   1572:     case NOTRUNNING:
                   1573:        sc->sc_dma_flags = DMAMODE_WRITE;
                   1574:        sc->sc_dma_bp = p;
                   1575:        sc->sc_dma_cnt = cc;
                   1576:        isa_dmastart(sc->sc_isa, sc->sc_drq, p, cc, NULL,
                   1577:                     DMAMODE_WRITE, BUS_DMA_NOWAIT);
                   1578:        goto startpcm;
                   1579:     case DMARUNNING:
                   1580:        sc->sc_playrun = PCMRUNNING;
                   1581:     startpcm:
                   1582:        if (sc->precision == 16)
                   1583:            cc >>= 1;
                   1584:        if (sc->channels == 2)
                   1585:            cc >>= 1;
                   1586:        cc--;
                   1587:
                   1588:        if (sc->sc_lastcc != cc || sc->sc_mode != AUMODE_PLAY) {
                   1589:            ad_write(sc, SP_LOWER_BASE_COUNT, (u_char)(cc & 0xff));
                   1590:            ad_write(sc, SP_UPPER_BASE_COUNT, (u_char)((cc >> 8) & 0xff));
                   1591:
                   1592:            reg = ad_read(sc, SP_INTERFACE_CONFIG);
                   1593:            ad_write(sc, SP_INTERFACE_CONFIG, (PLAYBACK_ENABLE|reg));
                   1594:
                   1595:            sc->sc_lastcc = cc;
                   1596:            sc->sc_mode = AUMODE_PLAY;
                   1597:        }
                   1598:        break;
                   1599:     case PCMRUNNING:
                   1600:        break;
                   1601:     }
                   1602:
                   1603:     return 0;
                   1604: }
                   1605:
                   1606: int
                   1607: ad1848_intr(arg)
                   1608:        void *arg;
                   1609: {
                   1610:     struct ad1848_softc *sc = arg;
                   1611:     int retval = 0;
                   1612:     u_char status;
                   1613:
                   1614:     /* Get intr status */
                   1615:     status = ADREAD(sc, AD1848_STATUS);
                   1616:
                   1617: #ifdef AUDIO_DEBUG
                   1618:     if (ad1848debug > 1)
                   1619:        printf("ad1848_intr: intr=%p status=%x\n", sc->sc_intr, status);
                   1620: #endif
                   1621:     sc->sc_locked = 0;
                   1622:     sc->sc_interrupts++;
                   1623:
                   1624:     /* Handle interrupt */
                   1625:     if (sc->sc_intr && (status & INTERRUPT_STATUS)) {
                   1626:        /* ACK DMA read because it may be in a bounce buffer */
                   1627:        /* XXX Do write to mask DMA ? */
                   1628:        if ((sc->sc_dma_flags & DMAMODE_READ) && sc->sc_recrun == NOTRUNNING)
                   1629:            isa_dmadone(sc->sc_isa, sc->sc_recdrq);
                   1630:        (*sc->sc_intr)(sc->sc_arg);
                   1631:        retval = 1;
                   1632:     }
                   1633:
                   1634:     /* clear interrupt */
                   1635:     if (status & INTERRUPT_STATUS)
                   1636:        ADWRITE(sc, AD1848_STATUS, 0);
                   1637:
                   1638:     return(retval);
                   1639: }
                   1640:
                   1641: void *
                   1642: ad1848_malloc(addr, direction, size, pool, flags)
                   1643:        void *addr;
                   1644:        int direction;
                   1645:        size_t size;
                   1646:        int pool;
                   1647:        int flags;
                   1648: {
                   1649:        struct ad1848_softc *sc = addr;
                   1650:        int drq;
                   1651:
                   1652:        if (sc->sc_mode == AUMODE_RECORD)
                   1653:                drq = sc->sc_recdrq == -1 ? sc->sc_drq : sc->sc_recdrq;
                   1654:        else
                   1655:                drq = sc->sc_drq;
                   1656:
                   1657:        return isa_malloc(sc->sc_isa, drq, size, pool, flags);
                   1658: }
                   1659:
                   1660: void
                   1661: ad1848_free(addr, ptr, pool)
                   1662:        void *addr;
                   1663:        void *ptr;
                   1664:        int pool;
                   1665: {
                   1666:        isa_free(ptr, pool);
                   1667: }
                   1668:
                   1669: size_t
                   1670: ad1848_round(addr, direction, size)
                   1671:        void *addr;
                   1672:        int direction;
                   1673:        size_t size;
                   1674: {
                   1675:        if (size > MAX_ISADMA)
                   1676:                size = MAX_ISADMA;
                   1677:        return size;
                   1678: }
                   1679:
                   1680: paddr_t
                   1681: ad1848_mappage(addr, mem, off, prot)
                   1682:        void *addr;
                   1683:         void *mem;
                   1684:         off_t off;
                   1685:        int prot;
                   1686: {
                   1687:        return isa_mappage(mem, off, prot);
                   1688: }
                   1689:
                   1690: int
                   1691: ad1848_get_props(addr)
                   1692:        void *addr;
                   1693: {
                   1694:        struct ad1848_softc *sc = addr;
                   1695:
                   1696:        return AUDIO_PROP_MMAP |
                   1697:               (sc->sc_drq != sc->sc_recdrq ? AUDIO_PROP_FULLDUPLEX : 0);
                   1698: }

CVSweb