[BACK]Return to pas.c CVS log [TXT][DIR] Up to [cvs.NetBSD.org] / src / sys / dev / isa

Annotation of src/sys/dev/isa/pas.c, Revision 1.67

1.67    ! cube        1: /*     $NetBSD: pas.c,v 1.66 2007/10/19 12:00:21 ad Exp $      */
1.1       brezak      2:
                      3: /*
                      4:  * Copyright (c) 1991-1993 Regents of the University of California.
                      5:  * All rights reserved.
                      6:  *
                      7:  * Redistribution and use in source and binary forms, with or without
                      8:  * modification, are permitted provided that the following conditions
                      9:  * are met:
                     10:  * 1. Redistributions of source code must retain the above copyright
                     11:  *    notice, this list of conditions and the following disclaimer.
                     12:  * 2. Redistributions in binary form must reproduce the above copyright
                     13:  *    notice, this list of conditions and the following disclaimer in the
                     14:  *    documentation and/or other materials provided with the distribution.
                     15:  * 3. All advertising materials mentioning features or use of this software
                     16:  *    must display the following acknowledgement:
                     17:  *     This product includes software developed by the Computer Systems
                     18:  *     Engineering Group at Lawrence Berkeley Laboratory.
                     19:  * 4. Neither the name of the University nor of the Laboratory may be used
                     20:  *    to endorse or promote products derived from this software without
                     21:  *    specific prior written permission.
                     22:  *
                     23:  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
                     24:  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
                     25:  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
                     26:  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
                     27:  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
                     28:  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
                     29:  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
                     30:  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
                     31:  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
                     32:  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
                     33:  * SUCH DAMAGE.
                     34:  *
                     35:  */
                     36: /*
1.61      kent       37:  * jfw 7/13/97 - The soundblaster code requires the generic bus-space
1.28      augustss   38:  * structures to be set up properly.  Rather than go to the effort of making
                     39:  * code for a dead line fully generic, properly set up the SB structures and
                     40:  * leave the rest x86/ISA/default-configuration specific.  If you have a
                     41:  * REAL computer, go buy a REAL sound card.
                     42:  */
                     43: /*
1.1       brezak     44:  * Todo:
1.61      kent       45:  *     - look at other PAS drivers (for PAS native suport)
                     46:  *     - use common sb.c once emulation is setup
1.1       brezak     47:  */
1.42      augustss   48: /*
                     49:  * jfw 6/21/98 - WARNING:  the PAS native IO ports are scattered all around
                     50:  * IO port space (0x0388, 0x738B, 0xBF88, 0x2789, ...) which will make proper
                     51:  * reservation a real pain, so I'm not going to do it (while fixing the
                     52:  * current reservation code to "work").  As a sanity check, I reserve the
                     53:  * 0x0388 base address, but you probably shouldn't even think of trying this
                     54:  * driver unless you're certain you have the hardware installed and it doesn't
                     55:  * conflict with other hardware...
                     56:  */
                     57:
1.51      lukem      58:
                     59: #include <sys/cdefs.h>
1.67    ! cube       60: __KERNEL_RCSID(0, "$NetBSD: pas.c,v 1.66 2007/10/19 12:00:21 ad Exp $");
1.1       brezak     61:
                     62: #include <sys/param.h>
                     63: #include <sys/systm.h>
                     64: #include <sys/errno.h>
                     65: #include <sys/ioctl.h>
                     66: #include <sys/syslog.h>
                     67: #include <sys/device.h>
                     68: #include <sys/proc.h>
                     69:
1.66      ad         70: #include <sys/cpu.h>
                     71: #include <sys/intr.h>
                     72: #include <sys/bus.h>
1.1       brezak     73: #include <machine/pio.h>
                     74:
                     75: #include <sys/audioio.h>
                     76: #include <dev/audio_if.h>
1.44      augustss   77: #include <dev/midi_if.h>
1.1       brezak     78:
1.5       cgd        79: #include <dev/isa/isavar.h>
                     80: #include <dev/isa/isadmavar.h>
1.1       brezak     81:
1.6       cgd        82: #include <dev/isa/sbdspvar.h>
                     83: #include <dev/isa/sbreg.h>
1.1       brezak     84:
                     85: #define DEFINE_TRANSLATIONS
1.6       cgd        86: #include <dev/isa/pasreg.h>
1.1       brezak     87:
1.8       brezak     88: #ifdef AUDIO_DEBUG
1.19      christos   89: #define DPRINTF(x)     if (pasdebug) printf x
1.1       brezak     90: int    pasdebug = 0;
                     91: #else
                     92: #define DPRINTF(x)
                     93: #endif
                     94:
                     95: /*
                     96:  * Software state, per SoundBlaster card.
                     97:  * The soundblaster has multiple functionality, which we must demultiplex.
                     98:  * One approach is to have one major device number for the soundblaster card,
                     99:  * and use different minor numbers to indicate which hardware function
                    100:  * we want.  This would make for one large driver.  Instead our approach
                    101:  * is to partition the design into a set of drivers that share an underlying
                    102:  * piece of hardware.  Most things are hard to share, for example, the audio
                    103:  * and midi ports.  For audio, we might want to mix two processes' signals,
                    104:  * and for midi we might want to merge streams (this is hard due to
                    105:  * running status).  Moreover, we should be able to re-use the high-level
                    106:  * modules with other kinds of hardware.  In this module, we only handle the
                    107:  * most basic communications with the sb card.
                    108:  */
                    109: struct pas_softc {
1.20      mikel     110:        struct sbdsp_softc sc_sbdsp;    /* base device, &c. */
1.61      kent      111:        bus_space_handle_t pas_port_handle;    /* the pas-specific port */
1.1       brezak    112:
                    113:        int model;
                    114:        int rev;
                    115: };
                    116:
1.61      kent      117: int    pas_getdev(void *, struct audio_device *);
                    118: void   pasconf(int, int, int, int);
1.1       brezak    119:
                    120:
                    121: /*
                    122:  * Define our interface to the higher level audio driver.
                    123:  */
                    124:
1.60      yamt      125: const struct audio_hw_if pas_hw_if = {
1.33      augustss  126:        sbdsp_open,
1.1       brezak    127:        sbdsp_close,
1.30      augustss  128:        0,
1.1       brezak    129:        sbdsp_query_encoding,
1.26      augustss  130:        sbdsp_set_params,
1.1       brezak    131:        sbdsp_round_blocksize,
1.30      augustss  132:        0,
1.43      mycroft   133:        0,
                    134:        0,
                    135:        0,
                    136:        0,
1.46      mycroft   137:        sbdsp_halt_output,
                    138:        sbdsp_halt_input,
1.1       brezak    139:        sbdsp_speaker_ctl,
                    140:        pas_getdev,
1.30      augustss  141:        0,
1.1       brezak    142:        sbdsp_mixer_set_port,
                    143:        sbdsp_mixer_get_port,
                    144:        sbdsp_mixer_query_devinfo,
1.29      augustss  145:        sb_malloc,
                    146:        sb_free,
1.45      mycroft   147:        sb_round_buffersize,
1.61      kent      148:        sb_mappage,
1.33      augustss  149:        sbdsp_get_props,
1.43      mycroft   150:        sbdsp_trigger_output,
                    151:        sbdsp_trigger_input,
1.50      augustss  152:        0,
1.63      christos  153:        NULL,
1.1       brezak    154: };
                    155:
                    156: /* The Address Translation code is used to convert I/O register addresses to
                    157:    be relative to the given base -register */
                    158:
1.61      kent      159: static const char *pasnames[] = {
1.1       brezak    160:        "",
                    161:        "Plus",
                    162:        "CDPC",
1.3       brezak    163:        "16",
                    164:        "16Basic"
1.1       brezak    165: };
                    166:
                    167: static struct audio_device pas_device = {
                    168:        "PAS,??",
                    169:        "",
                    170:        "pas"
                    171: };
                    172:
                    173: /*XXX assume default I/O base address */
1.48      lukem     174: #define pasread(p) inb((p))
                    175: #define paswrite(d, p) outb((p), (d))
1.1       brezak    176:
                    177: void
1.61      kent      178: pasconf(int model, int sbbase, int sbirq, int sbdrq)
1.1       brezak    179: {
1.61      kent      180:
1.1       brezak    181:        paswrite(0x00, INTERRUPT_MASK);
                    182:        /* Local timer control register */
                    183:        paswrite(0x36, SAMPLE_COUNTER_CONTROL);
                    184:        /* Sample rate timer (16 bit) */
                    185:        paswrite(0x36, SAMPLE_RATE_TIMER);
                    186:        paswrite(0, SAMPLE_RATE_TIMER);
                    187:        /* Local timer control register */
                    188:        paswrite(0x74, SAMPLE_COUNTER_CONTROL);
                    189:        /* Sample count register (16 bit) */
                    190:        paswrite(0x74, SAMPLE_BUFFER_COUNTER);
                    191:        paswrite(0, SAMPLE_BUFFER_COUNTER);
                    192:
                    193:        paswrite(P_C_PCM_MONO | P_C_PCM_DAC_MODE |
1.61      kent      194:            P_C_MIXER_CROSS_L_TO_L | P_C_MIXER_CROSS_R_TO_R,
                    195:            PCM_CONTROL);
1.1       brezak    196:        paswrite(S_M_PCM_RESET | S_M_FM_RESET |
1.61      kent      197:            S_M_SB_RESET | S_M_MIXER_RESET, SERIAL_MIXER);
1.1       brezak    198:
                    199: /*XXX*/
                    200:        paswrite(I_C_1_BOOT_RESET_ENABLE|1, IO_CONFIGURATION_1);
                    201:
                    202:        paswrite(I_C_2_PCM_DMA_DISABLED, IO_CONFIGURATION_2);
                    203:        paswrite(I_C_3_PCM_IRQ_DISABLED, IO_CONFIGURATION_3);
1.61      kent      204:
                    205: #ifdef BROKEN_BUS_CLOCK
1.1       brezak    206:        paswrite(S_C_1_PCS_ENABLE | S_C_1_PCS_STEREO | S_C_1_PCS_REALSOUND |
1.61      kent      207:            S_C_1_FM_EMULATE_CLOCK, SYSTEM_CONFIGURATION_1);
1.1       brezak    208: #else
                    209:        paswrite(S_C_1_PCS_ENABLE | S_C_1_PCS_STEREO | S_C_1_PCS_REALSOUND,
1.61      kent      210:            SYSTEM_CONFIGURATION_1);
1.1       brezak    211: #endif
                    212:
                    213:        /*XXX*/
                    214:        paswrite(0, SYSTEM_CONFIGURATION_2);
                    215:        paswrite(0, SYSTEM_CONFIGURATION_3);
                    216:
                    217:        /* Sets mute off and selects filter rate of 17.897 kHz */
                    218:        paswrite(F_F_MIXER_UNMUTE | 0x01, FILTER_FREQUENCY);
                    219:
1.3       brezak    220:        if (model == PAS_16 || model == PAS_16BASIC)
1.1       brezak    221:                paswrite(8, PRESCALE_DIVIDER);
                    222:        else
                    223:                paswrite(0, PRESCALE_DIVIDER);
                    224:
                    225:        paswrite(P_M_MV508_ADDRESS | P_M_MV508_PCM, PARALLEL_MIXER);
                    226:        paswrite(5, PARALLEL_MIXER);
1.61      kent      227:
1.1       brezak    228:        /*
                    229:         * Setup SoundBlaster emulation.
                    230:         */
                    231:        paswrite((sbbase >> 4) & 0xf, EMULATION_ADDRESS);
                    232:        paswrite(E_C_SB_IRQ_translate[sbirq] | E_C_SB_DMA_translate[sbdrq],
1.61      kent      233:            EMULATION_CONFIGURATION);
1.1       brezak    234:        paswrite(C_E_SB_ENABLE, COMPATIBILITY_ENABLE);
                    235:
                    236:        /*
                    237:         * Set mid-range levels.
                    238:         */
                    239:        paswrite(P_M_MV508_ADDRESS | P_M_MV508_MODE, PARALLEL_MIXER);
1.61      kent      240:        paswrite(P_M_MV508_LOUDNESS | P_M_MV508_ENHANCE_NONE, PARALLEL_MIXER);
1.1       brezak    241:
                    242:        paswrite(P_M_MV508_ADDRESS | P_M_MV508_MASTER_A, PARALLEL_MIXER);
                    243:        paswrite(50, PARALLEL_MIXER);
                    244:        paswrite(P_M_MV508_ADDRESS | P_M_MV508_MASTER_B, PARALLEL_MIXER);
                    245:        paswrite(50, PARALLEL_MIXER);
                    246:
1.61      kent      247:        paswrite(P_M_MV508_ADDRESS | P_M_MV508_MIXER | P_M_MV508_SB,
                    248:            PARALLEL_MIXER);
1.1       brezak    249:        paswrite(P_M_MV508_OUTPUTMIX | 30, PARALLEL_MIXER);
                    250:
1.61      kent      251:        paswrite(P_M_MV508_ADDRESS | P_M_MV508_MIXER | P_M_MV508_MIC,
                    252:            PARALLEL_MIXER);
1.1       brezak    253:        paswrite(P_M_MV508_INPUTMIX | 30, PARALLEL_MIXER);
                    254: }
                    255:
1.67    ! cube      256: int    pasprobe(device_t, cfdata_t, void *);
        !           257: void   pasattach(device_t, device_t, void *);
        !           258: static int pasfind(cfdata_t, struct pas_softc *,
1.61      kent      259:     struct isa_attach_args *, int);
1.42      augustss  260: /* argument to pasfind */
                    261: #define PASPROBE  1
                    262: #define PASATTACH 0
1.12      mycroft   263:
1.67    ! cube      264: CFATTACH_DECL_NEW(pas, sizeof(struct pas_softc),
1.56      thorpej   265:     pasprobe, pasattach, NULL, NULL);
1.1       brezak    266:
                    267: /*
                    268:  * Probe / attach routines.
                    269:  */
                    270:
                    271: int
1.67    ! cube      272: pasprobe(device_t parent, cfdata_t match, void *aux)
1.1       brezak    273: {
1.61      kent      274:        struct isa_attach_args *ia;
                    275:        struct pas_softc probesc, *sc;
1.39      augustss  276:
1.61      kent      277:        ia = aux;
                    278:        sc = &probesc;
1.52      thorpej   279:        if (ia->ia_nio < 1)
1.61      kent      280:                return 0;
1.52      thorpej   281:        if (ia->ia_nirq < 1)
1.61      kent      282:                return 0;
1.52      thorpej   283:        if (ia->ia_ndrq < 1)
1.61      kent      284:                return 0;
1.52      thorpej   285:
                    286:        if (ISA_DIRECT_CONFIG(ia))
1.61      kent      287:                return 0;
1.52      thorpej   288:
1.49      thorpej   289:        memset(sc, 0, sizeof *sc);
1.67    ! cube      290:        return pasfind(match, sc, aux, PASPROBE);
1.39      augustss  291: }
                    292:
                    293: /*
                    294:  * Probe for the soundblaster hardware.
                    295:  */
                    296: static int
1.67    ! cube      297: pasfind(cfdata_t match, struct pas_softc *sc,
1.61      kent      298:     struct isa_attach_args *ia, int probing)
1.39      augustss  299: {
1.35      augustss  300:        int iobase;
1.1       brezak    301:        u_char id, t;
1.61      kent      302:        int rc;
1.1       brezak    303:
1.61      kent      304:        rc = 0;                 /* failure */
                    305:        /* ensure we can set this up as a sound blaster */
                    306:        if (!SB_BASE_VALID(ia->ia_io[0].ir_addr)) {
1.52      thorpej   307:                printf("pas: configured SB iobase 0x%x invalid\n",
                    308:                    ia->ia_io[0].ir_addr);
1.28      augustss  309:                return 0;
                    310:        }
                    311:
1.42      augustss  312:        if (bus_space_map(sc->sc_sbdsp.sc_iot, PAS_DEFAULT_BASE, 1, 0,
1.61      kent      313:            &sc->pas_port_handle)) {
1.42      augustss  314:                printf("pas: can't map base register %x in probe\n",
1.61      kent      315:                    PAS_DEFAULT_BASE);
1.42      augustss  316:                return 0;
                    317:        }
                    318:
1.1       brezak    319:        /*
                    320:         * WARNING: Setting an option like W:1 or so that disables
                    321:         * warm boot reset of the card will screw up this detect code
                    322:         * something fierce.  Adding code to handle this means possibly
                    323:         * interfering with other cards on the bus if you have something
1.61      kent      324:         * on base port 0x388.  SO be forewarned.
1.1       brezak    325:         */
                    326:        /* Talk to first board */
                    327:        outb(MASTER_DECODE, 0xbc);
                    328:        /* Set base address */
                    329:
                    330: #if 0
                    331:        /* XXX Need to setup pseudo device */
                    332:        /* XXX What are good io addrs ? */
                    333:        if (iobase != PAS_DEFAULT_BASE) {
1.19      christos  334:                printf("pas: configured iobase %d invalid\n", iobase);
1.1       brezak    335:                return 0;
                    336:        }
                    337: #else
                    338:        /* Start out talking to native PAS */
                    339:        iobase = PAS_DEFAULT_BASE;
                    340: #endif
                    341:
                    342:        outb(MASTER_DECODE, iobase >> 2);
                    343:        /* One wait-state */
                    344:        paswrite(1, WAIT_STATE);
                    345:
                    346:        id = pasread(INTERRUPT_MASK);
                    347:        if (id == 0xff || id == 0xfe) {
                    348:                /* sanity */
                    349:                DPRINTF(("pas: bogus card id\n"));
1.42      augustss  350:                goto unmap1;
1.1       brezak    351:        }
                    352:        /*
                    353:         * We probably have a PAS-series board, now check for a
                    354:         * PAS2-series board by trying to change the board revision
                    355:         * bits.  PAS2-series hardware won't let you do this because
                    356:         * the bits are read-only.
                    357:         */
                    358:        t = id ^ 0xe0;
                    359:        paswrite(t, INTERRUPT_MASK);
                    360:        t = inb(INTERRUPT_MASK);
                    361:        paswrite(id, INTERRUPT_MASK);
                    362:
                    363:        if (t != id) {
                    364:                /* Not a PAS2 */
1.19      christos  365:                printf("pas: detected card but PAS2 test failed\n");
1.42      augustss  366:                goto unmap1;
1.1       brezak    367:        }
                    368:        /*XXX*/
                    369:        t = pasread(OPERATION_MODE_1) & 0xf;
                    370:        sc->model = O_M_1_to_card[t];
                    371:        if (sc->model != 0) {
                    372:                sc->rev = pasread(BOARD_REV_ID);
1.61      kent      373:        } else {
1.1       brezak    374:                DPRINTF(("pas: bogus model id\n"));
1.42      augustss  375:                goto unmap1;
1.1       brezak    376:        }
                    377:
1.61      kent      378:        if (sc->model >= 0) {
                    379:                if (ia->ia_irq[0].ir_irq == ISA_UNKNOWN_IRQ) {
                    380:                        printf("pas: sb emulation requires known irq\n");
1.42      augustss  381:                        goto unmap1;
1.61      kent      382:                }
                    383:                pasconf(sc->model, ia->ia_io[0].ir_addr,
                    384:                    ia->ia_irq[0].ir_irq, 1);
                    385:        } else {
                    386:                DPRINTF(("pas: could not probe pas\n"));
1.42      augustss  387:                goto unmap1;
1.61      kent      388:        }
1.1       brezak    389:
1.28      augustss  390:        /* Now a SoundBlaster, so set up proper bus-space hooks
                    391:          * appropriately
                    392:          */
                    393:
1.52      thorpej   394:        sc->sc_sbdsp.sc_iobase = ia->ia_io[0].ir_addr;
1.24      augustss  395:        sc->sc_sbdsp.sc_iot = ia->ia_iot;
1.28      augustss  396:
                    397:        /* Map i/o space [we map 24 ports which is the max of the sb and pro */
1.52      thorpej   398:        if (bus_space_map(sc->sc_sbdsp.sc_iot, ia->ia_io[0].ir_addr,
                    399:            SBP_NPORT, 0, &sc->sc_sbdsp.sc_ioh)) {
1.28      augustss  400:                printf("pas: can't map i/o space 0x%x/%d in probe\n",
1.52      thorpej   401:                    ia->ia_io[0].ir_addr, SBP_NPORT);
1.47      jdolecek  402:                goto unmap1;
1.28      augustss  403:        }
                    404:
1.1       brezak    405:        if (sbdsp_reset(&sc->sc_sbdsp) < 0) {
                    406:                DPRINTF(("pas: couldn't reset card\n"));
1.28      augustss  407:                goto unmap;
1.1       brezak    408:        }
                    409:
                    410:        /*
                    411:         * Cannot auto-discover DMA channel.
                    412:         */
1.52      thorpej   413:        if (!SB_DRQ_VALID(ia->ia_drq[0].ir_drq)) {
1.57      wiz       414:                printf("pas: configured DMA chan %d invalid\n",
1.52      thorpej   415:                    ia->ia_drq[0].ir_drq);
1.28      augustss  416:                goto unmap;
1.1       brezak    417:        }
1.52      thorpej   418:        if (!SB_IRQ_VALID(ia->ia_irq[0].ir_irq)) {
                    419:                printf("pas: configured irq chan %d invalid\n",
                    420:                    ia->ia_drq[0].ir_drq);
1.28      augustss  421:                goto unmap;
1.1       brezak    422:        }
                    423:
1.52      thorpej   424:        sc->sc_sbdsp.sc_irq = ia->ia_irq[0].ir_irq;
                    425:        sc->sc_sbdsp.sc_drq8 = ia->ia_drq[0].ir_drq;
1.23      jtk       426:        sc->sc_sbdsp.sc_drq16 = -1; /* XXX */
1.61      kent      427:
1.67    ! cube      428:        if (sbdsp_probe(&sc->sc_sbdsp, match) == 0) {
1.1       brezak    429:                DPRINTF(("pas: sbdsp probe failed\n"));
1.28      augustss  430:                goto unmap;
1.1       brezak    431:        }
                    432:
1.42      augustss  433:        rc = 1;
1.52      thorpej   434:
                    435:        if (probing) {
                    436:                ia->ia_nio = 1;
                    437:                ia->ia_io[0].ir_size = SBP_NPORT;
                    438:
                    439:                ia->ia_nirq = 1;
                    440:                ia->ia_ndrq = 1;
                    441:
                    442:                ia->ia_niomem = 0;
                    443:        }
1.28      augustss  444:
                    445:  unmap:
1.42      augustss  446:        if (rc == 0 || probing)
1.61      kent      447:                bus_space_unmap(sc->sc_sbdsp.sc_iot, sc->sc_sbdsp.sc_ioh,
                    448:                    SBP_NPORT);
1.42      augustss  449:  unmap1:
                    450:        if (rc == 0 || probing)
1.61      kent      451:                bus_space_unmap(sc->sc_sbdsp.sc_iot, PAS_DEFAULT_BASE, 1);
1.42      augustss  452:        return rc;
1.1       brezak    453: }
                    454:
                    455: /*
                    456:  * Attach hardware to driver, attach hardware driver to audio
                    457:  * pseudo-device driver .
                    458:  */
                    459: void
1.67    ! cube      460: pasattach(device_t parent, device_t self, void *aux)
1.1       brezak    461: {
1.61      kent      462:        struct pas_softc *sc;
                    463:        struct isa_attach_args *ia;
                    464:        int iobase;
                    465:
1.67    ! cube      466:        sc = device_private(self);
        !           467:        sc->sc_sbdsp.sc_dev = self;
1.61      kent      468:        ia = (struct isa_attach_args *)aux;
                    469:        iobase = ia->ia_io[0].ir_addr;
1.67    ! cube      470:        if (!pasfind(device_cfdata(self), sc, ia, PASATTACH)) {
        !           471:                aprint_error_dev(self, "pasfind failed\n");
1.39      augustss  472:                return;
                    473:        }
                    474:
1.40      thorpej   475:        sc->sc_sbdsp.sc_ic = ia->ia_ic;
1.20      mikel     476:        sc->sc_sbdsp.sc_iobase = iobase;
1.52      thorpej   477:        sc->sc_sbdsp.sc_ih = isa_intr_establish(ia->ia_ic, ia->ia_irq[0].ir_irq,
1.20      mikel     478:            IST_EDGE, IPL_AUDIO, sbdsp_intr, &sc->sc_sbdsp);
1.1       brezak    479:
1.67    ! cube      480:        aprint_normal(" ProAudio Spectrum %s [rev %d] ", pasnames[sc->model],
1.20      mikel     481:            sc->rev);
1.61      kent      482:
1.1       brezak    483:        sbdsp_attach(&sc->sc_sbdsp);
                    484:
1.58      itojun    485:        snprintf(pas_device.name, sizeof(pas_device.name), "pas,%s",
                    486:            pasnames[sc->model]);
                    487:        snprintf(pas_device.version, sizeof(pas_device.version), "%d",
                    488:            sc->rev);
1.1       brezak    489:
1.67    ! cube      490:        audio_attach_mi(&pas_hw_if, &sc->sc_sbdsp, sc->sc_sbdsp.sc_dev);
1.1       brezak    491: }
                    492:
                    493: int
1.65      christos  494: pas_getdev(void *addr, struct audio_device *retp)
1.1       brezak    495: {
1.61      kent      496:
1.1       brezak    497:        *retp = pas_device;
                    498:        return 0;
                    499: }

CVSweb <webmaster@jp.NetBSD.org>