diff options
Diffstat (limited to 'sys/dev/sound/pci/ds1.c')
-rw-r--r-- | sys/dev/sound/pci/ds1.c | 76 |
1 files changed, 66 insertions, 10 deletions
diff --git a/sys/dev/sound/pci/ds1.c b/sys/dev/sound/pci/ds1.c index 81ecaa7..1d21064 100644 --- a/sys/dev/sound/pci/ds1.c +++ b/sys/dev/sound/pci/ds1.c @@ -109,6 +109,7 @@ struct sc_info { bus_space_tag_t st; bus_space_handle_t sh; bus_dma_tag_t parent_dmat; + bus_dmamap_t map; struct resource *reg, *irq; int regid, irqid; @@ -216,6 +217,14 @@ static pcm_channel ds_pchantemplate = { ds1pchan_trigger, ds1pchan_getptr, ds1pchan_getcaps, + NULL, /* free */ + NULL, /* nop1 */ + NULL, /* nop2 */ + NULL, /* nop3 */ + NULL, /* nop4 */ + NULL, /* nop5 */ + NULL, /* nop6 */ + NULL, /* nop7 */ }; static pcm_channel ds_rchantemplate = { @@ -227,6 +236,14 @@ static pcm_channel ds_rchantemplate = { ds1rchan_trigger, ds1rchan_getptr, ds1rchan_getcaps, + NULL, /* free */ + NULL, /* nop1 */ + NULL, /* nop2 */ + NULL, /* nop3 */ + NULL, /* nop4 */ + NULL, /* nop5 */ + NULL, /* nop6 */ + NULL, /* nop7 */ }; /* -------------------------------------------------------------------- */ @@ -778,7 +795,6 @@ ds_init(struct sc_info *sc) u_int32_t *ci, r, pcs, rcs, ecs, ws, memsz, cb; u_int8_t *t; void *buf; - bus_dmamap_t map; ci = ds_devs[sc->type].mcode; @@ -821,9 +837,9 @@ ds_init(struct sc_info *sc) memsz += (64 + 1) * 4; if (sc->regbase == NULL) { - if (bus_dmamem_alloc(sc->parent_dmat, &buf, BUS_DMA_NOWAIT, &map)) + if (bus_dmamem_alloc(sc->parent_dmat, &buf, BUS_DMA_NOWAIT, &sc->map)) return -1; - if (bus_dmamap_load(sc->parent_dmat, map, buf, memsz, ds_setmap, sc, 0) + if (bus_dmamap_load(sc->parent_dmat, sc->map, buf, memsz, ds_setmap, sc, 0) || !sc->ctrlbase) { device_printf(sc->dev, "pcs=%d, rcs=%d, ecs=%d, ws=%d, memsz=%d\n", pcs, rcs, ecs, ws, memsz); @@ -868,6 +884,27 @@ ds_init(struct sc_info *sc) } static int +ds_uninit(struct sc_info *sc) +{ + ds_wr(sc, YDSXGR_NATIVEDACOUTVOL, 0x00000000, 4); + ds_wr(sc, YDSXGR_NATIVEADCINVOL, 0, 4); + ds_wr(sc, YDSXGR_NATIVEDACINVOL, 0, 4); + ds_enadsp(sc, 0); + ds_wr(sc, YDSXGR_MODE, 0x00010000, 4); + ds_wr(sc, YDSXGR_MAPOFREC, 0x00000000, 4); + ds_wr(sc, YDSXGR_MAPOFEFFECT, 0x00000000, 4); + ds_wr(sc, YDSXGR_PLAYCTRLBASE, 0x00000000, 4); + ds_wr(sc, YDSXGR_RECCTRLBASE, 0x00000000, 4); + ds_wr(sc, YDSXGR_EFFCTRLBASE, 0x00000000, 4); + ds_wr(sc, YDSXGR_GLOBALCTRL, 0, 2); + + bus_dmamap_unload(sc->parent_dmat, sc->map); + bus_dmamem_free(sc->parent_dmat, sc->regbase, sc->map); + + return 0; +} + +static int ds_finddev(u_int32_t dev, u_int32_t subdev) { int i; @@ -898,14 +935,12 @@ ds_pci_probe(device_t dev) static int ds_pci_attach(device_t dev) { - snddev_info *d; u_int32_t data; u_int32_t subdev, i; struct sc_info *sc; struct ac97_info *codec; char status[SND_STATUSLEN]; - d = device_get_softc(dev); if ((sc = malloc(sizeof(*sc), M_DEVBUF, M_NOWAIT)) == NULL) { device_printf(dev, "cannot allocate softc\n"); return ENXIO; @@ -952,7 +987,7 @@ ds_pci_attach(device_t dev) codec = ac97_create(dev, sc, ds_initcd, ds_rdcd, ds_wrcd); if (codec == NULL) goto bad; - mixer_init(d, &ac97_mixer, codec); + mixer_init(dev, &ac97_mixer, codec); sc->irqid = 0; sc->irq = bus_alloc_resource(dev, SYS_RES_IRQ, &sc->irqid, @@ -990,28 +1025,49 @@ bad: static int ds_pci_resume(device_t dev) { - snddev_info *d; struct sc_info *sc; - d = device_get_softc(dev); sc = pcm_getdevinfo(dev); if (ds_init(sc) == -1) { device_printf(dev, "unable to reinitialize the card\n"); return ENXIO; } - if (mixer_reinit(d) == -1) { + if (mixer_reinit(dev) == -1) { device_printf(dev, "unable to reinitialize the mixer\n"); return ENXIO; } return 0; } +static int +ds_pci_detach(device_t dev) +{ + int r; + struct sc_info *sc; + + r = pcm_unregister(dev); + if (r) + return r; + + sc = pcm_getdevinfo(dev); + ds_uninit(sc); + if (sc->reg) + bus_release_resource(dev, SYS_RES_MEMORY, sc->regid, sc->reg); + if (sc->ih) + bus_teardown_intr(dev, sc->irq, sc->ih); + if (sc->irq) + bus_release_resource(dev, SYS_RES_IRQ, sc->irqid, sc->irq); + free(sc, M_DEVBUF); + return 0; +} + static device_method_t ds1_methods[] = { /* Device interface */ DEVMETHOD(device_probe, ds_pci_probe), DEVMETHOD(device_attach, ds_pci_attach), - DEVMETHOD(device_resume, ds_pci_resume), + DEVMETHOD(device_detach, ds_pci_detach), + DEVMETHOD(device_resume, ds_pci_resume), { 0, 0 } }; |