diff options
author | Ed Maste <emaste@FreeBSD.org> | 2022-03-18 20:34:05 +0000 |
---|---|---|
committer | Ed Maste <emaste@FreeBSD.org> | 2022-03-19 00:33:19 +0000 |
commit | 92e6b4712b53d105c0b63e8792da9f28f044bb23 (patch) | |
tree | 08b735e53d639b98f46d6a9627603ca473e56302 | |
parent | 1d7f6de5cfc2f752ced8361124566da11f9bc78a (diff) | |
download | src-92e6b4712b53.tar.gz src-92e6b4712b53.zip |
Retire broken snd_ds1 and snd_maestro drivers
In 2012 joel@ reported[1] that these were not functional, and they do
not appear to have been fixed since.
[1] https://lists.freebsd.org/pipermail/freebsd-multimedia/2012-January/012751.html
Reported by: joel
Relnotes: Yes
Sponsored by: The FreeBSD Foundation
-rw-r--r-- | ObsoleteFiles.inc | 4 | ||||
-rw-r--r-- | share/man/man4/Makefile | 2 | ||||
-rw-r--r-- | share/man/man4/pcm.4 | 6 | ||||
-rw-r--r-- | share/man/man4/snd_ds1.4 | 76 | ||||
-rw-r--r-- | share/man/man4/snd_maestro.4 | 81 | ||||
-rw-r--r-- | sys/conf/NOTES | 4 | ||||
-rw-r--r-- | sys/conf/files | 2 | ||||
-rw-r--r-- | sys/dev/sound/driver.c | 2 | ||||
-rw-r--r-- | sys/dev/sound/pci/ds1.c | 1103 | ||||
-rw-r--r-- | sys/dev/sound/pci/ds1.h | 147 | ||||
-rw-r--r-- | sys/dev/sound/pci/maestro.c | 2043 | ||||
-rw-r--r-- | sys/dev/sound/pci/maestro_reg.h | 382 | ||||
-rw-r--r-- | sys/modules/sound/driver/Makefile | 5 | ||||
-rw-r--r-- | sys/modules/sound/driver/ds1/Makefile | 9 | ||||
-rw-r--r-- | sys/modules/sound/driver/maestro/Makefile | 9 |
15 files changed, 6 insertions, 3869 deletions
diff --git a/ObsoleteFiles.inc b/ObsoleteFiles.inc index c59d6464c63e..6daff798a1b3 100644 --- a/ObsoleteFiles.inc +++ b/ObsoleteFiles.inc @@ -52,6 +52,10 @@ # xargs -n1 | sort | uniq -d; # done +# 20200318: snd_ds1 and snd_maestro drivers removed +OLD_FILES+=usr/share/man/man4/snd_ds1.4.gz +OLD_FILES+=usr/share/man/man4/snd_maestro.4.gz + # 20220307: remove 330.news OLD_FILES+=etc/periodic/daily/330.news diff --git a/share/man/man4/Makefile b/share/man/man4/Makefile index 7e847065994b..251b09081b34 100644 --- a/share/man/man4/Makefile +++ b/share/man/man4/Makefile @@ -505,7 +505,6 @@ MAN= aac.4 \ snd_cmi.4 \ snd_cs4281.4 \ snd_csa.4 \ - snd_ds1.4 \ snd_emu10k1.4 \ snd_emu10kx.4 \ snd_envy24.4 \ @@ -518,7 +517,6 @@ MAN= aac.4 \ snd_hdspe.4 \ snd_ich.4 \ snd_maestro3.4 \ - snd_maestro.4 \ snd_mss.4 \ snd_neomagic.4 \ snd_sbc.4 \ diff --git a/share/man/man4/pcm.4 b/share/man/man4/pcm.4 index ea128c46a900..a4e20decf2b6 100644 --- a/share/man/man4/pcm.4 +++ b/share/man/man4/pcm.4 @@ -91,8 +91,6 @@ The following bridge device drivers are available: .It .Xr snd_davbus 4 (enabled by default on powerpc) .It -.Xr snd_ds1 4 -.It .Xr snd_emu10k1 4 .It .Xr snd_emu10kx 4 (enabled by default on amd64, i386) @@ -115,8 +113,6 @@ The following bridge device drivers are available: .It .Xr snd_ich 4 (enabled by default on amd64, i386) .It -.Xr snd_maestro 4 -.It .Xr snd_maestro3 4 .It .Xr snd_mss 4 @@ -710,7 +706,6 @@ A device node is not created properly. .Xr snd_cs4281 4 , .Xr snd_csa 4 , .Xr snd_davbus 4 , -.Xr snd_ds1 4 , .Xr snd_emu10k1 4 , .Xr snd_emu10kx 4 , .Xr snd_envy24 4 , @@ -722,7 +717,6 @@ A device node is not created properly. .Xr snd_hda 4 , .Xr snd_hdspe 4 , .Xr snd_ich 4 , -.Xr snd_maestro 4 , .Xr snd_maestro3 4 , .Xr snd_mss 4 , .Xr snd_neomagic 4 , diff --git a/share/man/man4/snd_ds1.4 b/share/man/man4/snd_ds1.4 deleted file mode 100644 index e462e2eece63..000000000000 --- a/share/man/man4/snd_ds1.4 +++ /dev/null @@ -1,76 +0,0 @@ -.\" Copyright (c) 2004 Atte Peltomaki -.\" All rights reserved. -.\" -.\" Redistribution and use in source and binary forms, with or without -.\" modification, are permitted provided that the following conditions -.\" are met: -.\" 1. Redistributions of source code must retain the above copyright -.\" notice, this list of conditions and the following disclaimer. -.\" 2. Redistributions in binary form must reproduce the above copyright -.\" notice, this list of conditions and the following disclaimer in the -.\" documentation and/or other materials provided with the distribution. -.\" -.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND -.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -.\" ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE -.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL -.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS -.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) -.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT -.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY -.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF -.\" SUCH DAMAGE. -.\" -.\" $FreeBSD$ -.\" -.Dd March 18, 2022 -.Dt SND_DS1 4 -.Os -.Sh NAME -.Nm snd_ds1 -.Nd "Yamaha DS-1 PCI bridge device driver" -.Sh SYNOPSIS -To compile this driver into the kernel, place the following lines in your -kernel configuration file: -.Bd -ragged -offset indent -.Cd "device sound" -.Cd "device snd_ds1" -.Ed -.Pp -Alternatively, to load the driver as a module at boot time, place the -following line in -.Xr loader.conf 5 : -.Bd -literal -offset indent -snd_ds1_load="YES" -.Ed -.Sh DESCRIPTION -The -.Nm -bridge driver allows the generic audio driver -.Xr sound 4 -to attach to the Yamaha DS-1 sound card. -.Sh HARDWARE -The -.Nm -driver supports the following sound cards: -.Pp -.Bl -bullet -compact -.It -Yamaha DS-1 -.It -Yamaha DS-1E -.El -.Sh SEE ALSO -.Xr sound 4 -.Sh HISTORY -The -.Nm -device driver first appeared in -.Fx 4.1 . -.Pp -This driver will be removed in -.Fx 14 . -Users who require it may have better luck with the audio/oss port or package. -.Sh AUTHORS -.An Cameron Grant Aq Mt cg@FreeBSD.org diff --git a/share/man/man4/snd_maestro.4 b/share/man/man4/snd_maestro.4 deleted file mode 100644 index c9c2f969bfa7..000000000000 --- a/share/man/man4/snd_maestro.4 +++ /dev/null @@ -1,81 +0,0 @@ -.\" Copyright (c) 2004 Jorge Mario G. Mazo -.\" All rights reserved. -.\" -.\" Redistribution and use in source and binary forms, with or without -.\" modification, are permitted provided that the following conditions -.\" are met: -.\" 1. Redistributions of source code must retain the above copyright -.\" notice, this list of conditions and the following disclaimer. -.\" 2. Redistributions in binary form must reproduce the above copyright -.\" notice, this list of conditions and the following disclaimer in the -.\" documentation and/or other materials provided with the distribution. -.\" -.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND -.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -.\" ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE -.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL -.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS -.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) -.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT -.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY -.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF -.\" SUCH DAMAGE. -.\" -.\" $FreeBSD$ -.\" -.Dd March 18, 2022 -.Dt SND_MAESTRO 4 -.Os -.Sh NAME -.Nm snd_maestro -.Nd "ESS Maestro bridge device driver" -.Sh SYNOPSIS -To compile this driver into the kernel, place the following lines in your -kernel configuration file: -.Bd -ragged -offset indent -.Cd "device sound" -.Cd "device snd_maestro" -.Ed -.Pp -Alternatively, to load the driver as a module at boot time, place the -following line in -.Xr loader.conf 5 : -.Bd -literal -offset indent -snd_maestro_load="YES" -.Ed -.Sh DESCRIPTION -The -.Nm -bridge driver allows the generic audio driver -.Xr sound 4 -to attach to ESS Maestro based sound chips. -This chipset is very popular in notebook computers, but it is -also very used in a wide selection of cheap OEM sound cards. -.Sh HARDWARE -The -.Nm -driver supports the following PCI sound cards: -.Pp -.Bl -bullet -compact -.It -ESS Technology Maestro-1 -.It -ESS Technology Maestro-2 -.It -ESS Technology Maestro-2E -.El -.Sh SEE ALSO -.Xr snd_maestro3 4 , -.Xr sound 4 -.Sh HISTORY -The -.Nm -device driver first appeared in -.Fx 4.2 . -.Pp -This driver will be removed in -.Fx 14 . -.Sh AUTHORS -This manual page was written by -.An Jorge Mario G. Mazo Aq Mt jgutie11@eafit.edu.co . diff --git a/sys/conf/NOTES b/sys/conf/NOTES index 5b64b212165c..178134f46ee5 100644 --- a/sys/conf/NOTES +++ b/sys/conf/NOTES @@ -2041,7 +2041,6 @@ device sound # snd_cs4281: Crystal Semiconductor CS4281 PCI. # snd_csa: Crystal Semiconductor CS461x/428x PCI. (except # 4281) -# snd_ds1: Yamaha DS-1 PCI. # snd_emu10k1: Creative EMU10K1 PCI and EMU10K2 (Audigy) PCI. # snd_emu10kx: Creative SoundBlaster Live! and Audigy # snd_envy24: VIA Envy24 and compatible, needs snd_spicds. @@ -2057,7 +2056,6 @@ device sound # snd_ich: Intel ICH AC'97 and some more audio controllers # embedded in a chipset, for example nVidia # nForce controllers. -# snd_maestro: ESS Technology Maestro-1/2x PCI. # snd_maestro3: ESS Technology Maestro-3/Allegro PCI. # snd_mss: Microsoft Sound System ISA PnP/non-PnP. # snd_neomagic: Neomagic 256 AV/ZX PCI. @@ -2082,7 +2080,6 @@ device snd_atiixp device snd_cmi device snd_cs4281 device snd_csa -device snd_ds1 device snd_emu10k1 device snd_emu10kx device snd_envy24 @@ -2094,7 +2091,6 @@ device snd_gusc device snd_hda device snd_hdspe device snd_ich -device snd_maestro device snd_maestro3 device snd_mss device snd_neomagic diff --git a/sys/conf/files b/sys/conf/files index e3d4e0f01b03..57bd2693f532 100644 --- a/sys/conf/files +++ b/sys/conf/files @@ -3103,7 +3103,6 @@ dev/sound/pci/cmi.c optional snd_cmi pci dev/sound/pci/cs4281.c optional snd_cs4281 pci dev/sound/pci/csa.c optional snd_csa pci dev/sound/pci/csapcm.c optional snd_csa pci -dev/sound/pci/ds1.c optional snd_ds1 pci dev/sound/pci/emu10k1.c optional snd_emu10k1 pci dev/sound/pci/emu10kx.c optional snd_emu10kx pci dev/sound/pci/emu10kx-pcm.c optional snd_emu10kx pci @@ -3113,7 +3112,6 @@ dev/sound/pci/envy24ht.c optional snd_envy24ht pci dev/sound/pci/es137x.c optional snd_es137x pci dev/sound/pci/fm801.c optional snd_fm801 pci dev/sound/pci/ich.c optional snd_ich pci -dev/sound/pci/maestro.c optional snd_maestro pci dev/sound/pci/maestro3.c optional snd_maestro3 pci dev/sound/pci/neomagic.c optional snd_neomagic pci dev/sound/pci/solo.c optional snd_solo pci diff --git a/sys/dev/sound/driver.c b/sys/dev/sound/driver.c index 06833430edb4..fab67a4591d2 100644 --- a/sys/dev/sound/driver.c +++ b/sys/dev/sound/driver.c @@ -65,7 +65,6 @@ MODULE_DEPEND(snd_driver, snd_cmi, 1, 1, 1); MODULE_DEPEND(snd_driver, snd_cs4281, 1, 1, 1); MODULE_DEPEND(snd_driver, snd_csa, 1, 1, 1); MODULE_DEPEND(snd_driver, snd_csapcm, 1, 1, 1); -MODULE_DEPEND(snd_driver, snd_ds1, 1, 1, 1); MODULE_DEPEND(snd_driver, snd_emu10kx, 1, 1, 1); MODULE_DEPEND(snd_driver, snd_envy24, 1, 1, 1); MODULE_DEPEND(snd_driver, snd_envy24ht, 1, 1, 1); @@ -75,7 +74,6 @@ MODULE_DEPEND(snd_driver, snd_fm801, 1, 1, 1); MODULE_DEPEND(snd_driver, snd_gusc, 1, 1, 1); MODULE_DEPEND(snd_driver, snd_hda, 1, 1, 1); MODULE_DEPEND(snd_driver, snd_ich, 1, 1, 1); -MODULE_DEPEND(snd_driver, snd_maestro, 1, 1, 1); MODULE_DEPEND(snd_driver, snd_maestro3, 1, 1, 1); MODULE_DEPEND(snd_driver, snd_mss, 1, 1, 1); MODULE_DEPEND(snd_driver, snd_neomagic, 1, 1, 1); diff --git a/sys/dev/sound/pci/ds1.c b/sys/dev/sound/pci/ds1.c deleted file mode 100644 index d9641b632051..000000000000 --- a/sys/dev/sound/pci/ds1.c +++ /dev/null @@ -1,1103 +0,0 @@ -/*- - * SPDX-License-Identifier: BSD-2-Clause-FreeBSD - * - * Copyright (c) 2000 Cameron Grant <cg@freebsd.org> - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHERIN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THEPOSSIBILITY OF - * SUCH DAMAGE. - */ - -#ifdef HAVE_KERNEL_OPTION_HEADERS -#include "opt_snd.h" -#endif - -#include <dev/sound/pcm/sound.h> -#include <dev/sound/pcm/ac97.h> - -#include <dev/pci/pcireg.h> -#include <dev/pci/pcivar.h> - -#include <dev/sound/pci/ds1.h> -#include <dev/sound/pci/ds1-fw.h> - -SND_DECLARE_FILE("$FreeBSD$"); - -/* -------------------------------------------------------------------- */ - -#define DS1_CHANS 4 -#define DS1_RECPRIMARY 0 -#define DS1_IRQHZ ((48000 << 8) / 256) -#define DS1_BUFFSIZE 4096 - -struct pbank { - volatile u_int32_t Format; - volatile u_int32_t LoopDefault; - volatile u_int32_t PgBase; - volatile u_int32_t PgLoop; - volatile u_int32_t PgLoopEnd; - volatile u_int32_t PgLoopFrac; - volatile u_int32_t PgDeltaEnd; - volatile u_int32_t LpfKEnd; - volatile u_int32_t EgGainEnd; - volatile u_int32_t LchGainEnd; - volatile u_int32_t RchGainEnd; - volatile u_int32_t Effect1GainEnd; - volatile u_int32_t Effect2GainEnd; - volatile u_int32_t Effect3GainEnd; - volatile u_int32_t LpfQ; - volatile u_int32_t Status; - volatile u_int32_t NumOfFrames; - volatile u_int32_t LoopCount; - volatile u_int32_t PgStart; - volatile u_int32_t PgStartFrac; - volatile u_int32_t PgDelta; - volatile u_int32_t LpfK; - volatile u_int32_t EgGain; - volatile u_int32_t LchGain; - volatile u_int32_t RchGain; - volatile u_int32_t Effect1Gain; - volatile u_int32_t Effect2Gain; - volatile u_int32_t Effect3Gain; - volatile u_int32_t LpfD1; - volatile u_int32_t LpfD2; -}; - -struct rbank { - volatile u_int32_t PgBase; - volatile u_int32_t PgLoopEnd; - volatile u_int32_t PgStart; - volatile u_int32_t NumOfLoops; -}; - -struct sc_info; - -/* channel registers */ -struct sc_pchinfo { - int run, spd, dir, fmt; - struct snd_dbuf *buffer; - struct pcm_channel *channel; - volatile struct pbank *lslot, *rslot; - int lsnum, rsnum; - struct sc_info *parent; -}; - -struct sc_rchinfo { - int run, spd, dir, fmt, num; - struct snd_dbuf *buffer; - struct pcm_channel *channel; - volatile struct rbank *slot; - struct sc_info *parent; -}; - -/* device private data */ -struct sc_info { - device_t dev; - u_int32_t type, rev; - u_int32_t cd2id, ctrlbase; - - bus_space_tag_t st; - bus_space_handle_t sh; - bus_dma_tag_t buffer_dmat, control_dmat; - bus_dmamap_t map; - - struct resource *reg, *irq; - int regid, irqid; - void *ih; - struct mtx *lock; - - void *regbase; - u_int32_t *pbase, pbankbase, pbanksize; - volatile struct pbank *pbank[2 * 64]; - volatile struct rbank *rbank; - int pslotfree, currbank, pchn, rchn; - unsigned int bufsz; - - struct sc_pchinfo pch[DS1_CHANS]; - struct sc_rchinfo rch[2]; -}; - -struct { - u_int32_t dev, subdev; - char *name; - u_int32_t *mcode; -} ds_devs[] = { - {0x00041073, 0, "Yamaha DS-1 (YMF724)", CntrlInst}, - {0x000d1073, 0, "Yamaha DS-1E (YMF724F)", CntrlInst1E}, - {0x00051073, 0, "Yamaha DS-1? (YMF734)", CntrlInst}, - {0x00081073, 0, "Yamaha DS-1? (YMF737)", CntrlInst}, - {0x00201073, 0, "Yamaha DS-1? (YMF738)", CntrlInst}, - {0x00061073, 0, "Yamaha DS-1? (YMF738_TEG)", CntrlInst}, - {0x000a1073, 0x00041073, "Yamaha DS-1 (YMF740)", CntrlInst}, - {0x000a1073, 0x000a1073, "Yamaha DS-1 (YMF740B)", CntrlInst}, - {0x000a1073, 0x53328086, "Yamaha DS-1 (YMF740I)", CntrlInst}, - {0x000a1073, 0, "Yamaha DS-1 (YMF740?)", CntrlInst}, - {0x000c1073, 0, "Yamaha DS-1E (YMF740C)", CntrlInst1E}, - {0x00101073, 0, "Yamaha DS-1E (YMF744)", CntrlInst1E}, - {0x00121073, 0, "Yamaha DS-1E (YMF754)", CntrlInst1E}, - {0, 0, NULL, NULL} -}; - -/* -------------------------------------------------------------------- */ - -/* - * prototypes - */ - -/* stuff */ -static int ds_init(struct sc_info *); -static void ds_intr(void *); - -/* talk to the card */ -static u_int32_t ds_rd(struct sc_info *, int, int); -static void ds_wr(struct sc_info *, int, u_int32_t, int); - -/* -------------------------------------------------------------------- */ - -static u_int32_t ds_recfmt[] = { - SND_FORMAT(AFMT_U8, 1, 0), - SND_FORMAT(AFMT_U8, 2, 0), - SND_FORMAT(AFMT_S8, 1, 0), - SND_FORMAT(AFMT_S8, 2, 0), - SND_FORMAT(AFMT_S16_LE, 1, 0), - SND_FORMAT(AFMT_S16_LE, 2, 0), - SND_FORMAT(AFMT_U16_LE, 1, 0), - SND_FORMAT(AFMT_U16_LE, 2, 0), - 0 -}; -static struct pcmchan_caps ds_reccaps = {4000, 48000, ds_recfmt, 0}; - -static u_int32_t ds_playfmt[] = { - SND_FORMAT(AFMT_U8, 1, 0), - SND_FORMAT(AFMT_U8, 2, 0), - /* SND_FORMAT(AFMT_S16_LE, 1, 0), */ - SND_FORMAT(AFMT_S16_LE, 2, 0), - 0 -}; -static struct pcmchan_caps ds_playcaps = {4000, 96000, ds_playfmt, 0}; - -/* -------------------------------------------------------------------- */ -/* Hardware */ -static u_int32_t -ds_rd(struct sc_info *sc, int regno, int size) -{ - switch (size) { - case 1: - return bus_space_read_1(sc->st, sc->sh, regno); - case 2: - return bus_space_read_2(sc->st, sc->sh, regno); - case 4: - return bus_space_read_4(sc->st, sc->sh, regno); - default: - return 0xffffffff; - } -} - -static void -ds_wr(struct sc_info *sc, int regno, u_int32_t data, int size) -{ - switch (size) { - case 1: - bus_space_write_1(sc->st, sc->sh, regno, data); - break; - case 2: - bus_space_write_2(sc->st, sc->sh, regno, data); - break; - case 4: - bus_space_write_4(sc->st, sc->sh, regno, data); - break; - } -} - -static void -wrl(struct sc_info *sc, u_int32_t *ptr, u_int32_t val) -{ - *(volatile u_int32_t *)ptr = val; - bus_space_barrier(sc->st, sc->sh, 0, 0, BUS_SPACE_BARRIER_WRITE); -} - -/* -------------------------------------------------------------------- */ -/* ac97 codec */ -static int -ds_cdbusy(struct sc_info *sc, int sec) -{ - int i, reg; - - reg = sec? YDSXGR_SECSTATUSADR : YDSXGR_PRISTATUSADR; - i = YDSXG_AC97TIMEOUT; - while (i > 0) { - if (!(ds_rd(sc, reg, 2) & 0x8000)) - return 0; - i--; - } - return ETIMEDOUT; -} - -static u_int32_t -ds_initcd(kobj_t obj, void *devinfo) -{ - struct sc_info *sc = (struct sc_info *)devinfo; - u_int32_t x; - - x = pci_read_config(sc->dev, PCIR_DSXGCTRL, 1); - if (x & 0x03) { - pci_write_config(sc->dev, PCIR_DSXGCTRL, x & ~0x03, 1); - pci_write_config(sc->dev, PCIR_DSXGCTRL, x | 0x03, 1); - pci_write_config(sc->dev, PCIR_DSXGCTRL, x & ~0x03, 1); - /* - * The YMF740 on some Intel motherboards requires a pretty - * hefty delay after this reset for some reason... Otherwise: - * "pcm0: ac97 codec init failed" - * Maybe this is needed for all YMF740's? - * 400ms and 500ms here seem to work, 300ms does not. - * - * do it for all chips -cg - */ - DELAY(500000); - } - - return ds_cdbusy(sc, 0)? 0 : 1; -} - -static int -ds_rdcd(kobj_t obj, void *devinfo, int regno) -{ - struct sc_info *sc = (struct sc_info *)devinfo; - int sec, cid, i; - u_int32_t cmd, reg; - - sec = regno & 0x100; - regno &= 0xff; - cid = sec? (sc->cd2id << 8) : 0; - reg = sec? YDSXGR_SECSTATUSDATA : YDSXGR_PRISTATUSDATA; - if (sec && cid == 0) - return 0xffffffff; - - cmd = YDSXG_AC97READCMD | cid | regno; - ds_wr(sc, YDSXGR_AC97CMDADR, cmd, 2); - - if (ds_cdbusy(sc, sec)) - return 0xffffffff; - - if (sc->type == 11 && sc->rev < 2) - for (i = 0; i < 600; i++) - ds_rd(sc, reg, 2); - - return ds_rd(sc, reg, 2); -} - -static int -ds_wrcd(kobj_t obj, void *devinfo, int regno, u_int32_t data) -{ - struct sc_info *sc = (struct sc_info *)devinfo; - int sec, cid; - u_int32_t cmd; - - sec = regno & 0x100; - regno &= 0xff; - cid = sec? (sc->cd2id << 8) : 0; - if (sec && cid == 0) - return ENXIO; - - cmd = YDSXG_AC97WRITECMD | cid | regno; - cmd <<= 16; - cmd |= data; - ds_wr(sc, YDSXGR_AC97CMDDATA, cmd, 4); - - return ds_cdbusy(sc, sec); -} - -static kobj_method_t ds_ac97_methods[] = { - KOBJMETHOD(ac97_init, ds_initcd), - KOBJMETHOD(ac97_read, ds_rdcd), - KOBJMETHOD(ac97_write, ds_wrcd), - KOBJMETHOD_END -}; -AC97_DECLARE(ds_ac97); - -/* -------------------------------------------------------------------- */ - -static void -ds_enadsp(struct sc_info *sc, int on) -{ - u_int32_t v, i; - - v = on? 1 : 0; - if (on) { - ds_wr(sc, YDSXGR_CONFIG, 0x00000001, 4); - } else { - if (ds_rd(sc, YDSXGR_CONFIG, 4)) - ds_wr(sc, YDSXGR_CONFIG, 0x00000000, 4); - i = YDSXG_WORKBITTIMEOUT; - while (i > 0) { - if (!(ds_rd(sc, YDSXGR_CONFIG, 4) & 0x00000002)) - break; - i--; - } - } -} - -static volatile struct pbank * -ds_allocpslot(struct sc_info *sc) -{ - int slot; - - if (sc->pslotfree > 63) - return NULL; - slot = sc->pslotfree++; - return sc->pbank[slot * 2]; -} - -static int -ds_initpbank(volatile struct pbank *pb, int ch, int stereo, int b16, u_int32_t rate, bus_addr_t base, u_int32_t len) -{ - u_int32_t lv[] = {1, 1, 0, 0, 0}; - u_int32_t rv[] = {1, 0, 1, 0, 0}; - u_int32_t e1[] = {0, 0, 0, 0, 0}; - u_int32_t e2[] = {1, 0, 0, 1, 0}; - u_int32_t e3[] = {1, 0, 0, 0, 1}; - int ss, i; - u_int32_t delta; - - struct { - int rate, fK, fQ; - } speedinfo[] = { - { 100, 0x00570000, 0x35280000}, - { 2000, 0x06aa0000, 0x34a70000}, - { 8000, 0x18b20000, 0x32020000}, - {11025, 0x20930000, 0x31770000}, - {16000, 0x2b9a0000, 0x31390000}, - {22050, 0x35a10000, 0x31c90000}, - {32000, 0x3eaa0000, 0x33d00000}, -/* {44100, 0x04646000, 0x370a0000}, -*/ {48000, 0x40000000, 0x40000000}, - }; - - ss = b16? 1 : 0; - ss += stereo? 1 : 0; - delta = (65536 * rate) / 48000; - i = 0; - while (i < 7 && speedinfo[i].rate < rate) - i++; - - pb->Format = stereo? 0x00010000 : 0; - pb->Format |= b16? 0 : 0x80000000; - pb->Format |= (stereo && (ch == 2 || ch == 4))? 0x00000001 : 0; - pb->LoopDefault = 0; - pb->PgBase = base; - pb->PgLoop = 0; - pb->PgLoopEnd = len >> ss; - pb->PgLoopFrac = 0; - pb->Status = 0; - pb->NumOfFrames = 0; - pb->LoopCount = 0; - pb->PgStart = 0; - pb->PgStartFrac = 0; - pb->PgDelta = pb->PgDeltaEnd = delta << 12; - pb->LpfQ = speedinfo[i].fQ; - pb->LpfK = pb->LpfKEnd = speedinfo[i].fK; - pb->LpfD1 = pb->LpfD2 = 0; - pb->EgGain = pb->EgGainEnd = 0x40000000; - pb->LchGain = pb->LchGainEnd = lv[ch] * 0x40000000; - pb->RchGain = pb->RchGainEnd = rv[ch] * 0x40000000; - pb->Effect1Gain = pb->Effect1GainEnd = e1[ch] * 0x40000000; - pb->Effect2Gain = pb->Effect2GainEnd = e2[ch] * 0x40000000; - pb->Effect3Gain = pb->Effect3GainEnd = e3[ch] * 0x40000000; - - return 0; -} - -static void -ds_enapslot(struct sc_info *sc, int slot, int go) -{ - wrl(sc, &sc->pbase[slot + 1], go? (sc->pbankbase + 2 * slot * sc->pbanksize) : 0); - /* printf("pbase[%d] = 0x%x\n", slot + 1, go? (sc->pbankbase + 2 * slot * sc->pbanksize) : 0); */ -} - -static void -ds_setuppch(struct sc_pchinfo *ch) -{ - int stereo, b16, c, sz; - bus_addr_t addr; - - stereo = (AFMT_CHANNEL(ch->fmt) > 1)? 1 : 0; - b16 = (ch->fmt & AFMT_16BIT)? 1 : 0; - c = stereo? 1 : 0; - addr = sndbuf_getbufaddr(ch->buffer); - sz = sndbuf_getsize(ch->buffer); - - ds_initpbank(ch->lslot, c, stereo, b16, ch->spd, addr, sz); - ds_initpbank(ch->lslot + 1, c, stereo, b16, ch->spd, addr, sz); - ds_initpbank(ch->rslot, 2, stereo, b16, ch->spd, addr, sz); - ds_initpbank(ch->rslot + 1, 2, stereo, b16, ch->spd, addr, sz); -} - -static void -ds_setuprch(struct sc_rchinfo *ch) -{ - struct sc_info *sc = ch->parent; - int stereo, b16, i, sz, pri; - u_int32_t x, y; - bus_addr_t addr; - - stereo = (AFMT_CHANNEL(ch->fmt) > 1)? 1 : 0; - b16 = (ch->fmt & AFMT_16BIT)? 1 : 0; - addr = sndbuf_getbufaddr(ch->buffer); - sz = sndbuf_getsize(ch->buffer); - pri = (ch->num == DS1_RECPRIMARY)? 1 : 0; - - for (i = 0; i < 2; i++) { - ch->slot[i].PgBase = addr; - ch->slot[i].PgLoopEnd = sz; - ch->slot[i].PgStart = 0; - ch->slot[i].NumOfLoops = 0; - } - x = (b16? 0x00 : 0x01) | (stereo? 0x02 : 0x00); - y = (48000 * 4096) / ch->spd; - y--; - /* printf("pri = %d, x = %d, y = %d\n", pri, x, y); */ - ds_wr(sc, pri? YDSXGR_ADCFORMAT : YDSXGR_RECFORMAT, x, 4); - ds_wr(sc, pri? YDSXGR_ADCSLOTSR : YDSXGR_RECSLOTSR, y, 4); -} - -/* -------------------------------------------------------------------- */ -/* play channel interface */ -static void * -ds1pchan_init(kobj_t obj, void *devinfo, struct snd_dbuf *b, struct pcm_channel *c, int dir) -{ - struct sc_info *sc = devinfo; - struct sc_pchinfo *ch; - - KASSERT(dir == PCMDIR_PLAY, ("ds1pchan_init: bad direction")); - - ch = &sc->pch[sc->pchn++]; - ch->buffer = b; - ch->parent = sc; - ch->channel = c; - ch->dir = dir; - ch->fmt = SND_FORMAT(AFMT_U8, 1, 0); - ch->spd = 8000; - ch->run = 0; - if (sndbuf_alloc(ch->buffer, sc->buffer_dmat, 0, sc->bufsz) != 0) - return NULL; - else { - ch->lsnum = sc->pslotfree; - ch->lslot = ds_allocpslot(sc); - ch->rsnum = sc->pslotfree; - ch->rslot = ds_allocpslot(sc); - ds_setuppch(ch); - return ch; - } -} - -static int -ds1pchan_setformat(kobj_t obj, void *data, u_int32_t format) -{ - struct sc_pchinfo *ch = data; - - ch->fmt = format; - - return 0; -} - -static u_int32_t -ds1pchan_setspeed(kobj_t obj, void *data, u_int32_t speed) -{ - struct sc_pchinfo *ch = data; - - ch->spd = speed; - - return speed; -} - -static u_int32_t -ds1pchan_setblocksize(kobj_t obj, void *data, u_int32_t blocksize) -{ - struct sc_pchinfo *ch = data; - struct sc_info *sc = ch->parent; - int drate; - - /* irq rate is fixed at 187.5hz */ - drate = ch->spd * sndbuf_getalign(ch->buffer); - blocksize = roundup2((drate << 8) / DS1_IRQHZ, 4); - sndbuf_resize(ch->buffer, sc->bufsz / blocksize, blocksize); - - return blocksize; -} - -/* semantic note: must start at beginning of buffer */ -static int -ds1pchan_trigger(kobj_t obj, void *data, int go) -{ - struct sc_pchinfo *ch = data; - struct sc_info *sc = ch->parent; - int stereo; - - if (!PCMTRIG_COMMON(go)) - return 0; - stereo = (AFMT_CHANNEL(ch->fmt) > 1)? 1 : 0; - if (go == PCMTRIG_START) { - ch->run = 1; - ds_setuppch(ch); - ds_enapslot(sc, ch->lsnum, 1); - ds_enapslot(sc, ch->rsnum, stereo); - snd_mtxlock(sc->lock); - ds_wr(sc, YDSXGR_MODE, 0x00000003, 4); - snd_mtxunlock(sc->lock); - } else { - ch->run = 0; - /* ds_setuppch(ch); */ - ds_enapslot(sc, ch->lsnum, 0); - ds_enapslot(sc, ch->rsnum, 0); - } - - return 0; -} - -static u_int32_t -ds1pchan_getptr(kobj_t obj, void *data) -{ - struct sc_pchinfo *ch = data; - struct sc_info *sc = ch->parent; - volatile struct pbank *bank; - int ss; - u_int32_t ptr; - - ss = (AFMT_CHANNEL(ch->fmt) > 1)? 1 : 0; - ss += (ch->fmt & AFMT_16BIT)? 1 : 0; - - bank = ch->lslot + sc->currbank; - /* printf("getptr: %d\n", bank->PgStart << ss); */ - ptr = bank->PgStart; - ptr <<= ss; - return ptr; -} - -static struct pcmchan_caps * -ds1pchan_getcaps(kobj_t obj, void *data) -{ - return &ds_playcaps; -} - -static kobj_method_t ds1pchan_methods[] = { - KOBJMETHOD(channel_init, ds1pchan_init), - KOBJMETHOD(channel_setformat, ds1pchan_setformat), - KOBJMETHOD(channel_setspeed, ds1pchan_setspeed), - KOBJMETHOD(channel_setblocksize, ds1pchan_setblocksize), - KOBJMETHOD(channel_trigger, ds1pchan_trigger), - KOBJMETHOD(channel_getptr, ds1pchan_getptr), - KOBJMETHOD(channel_getcaps, ds1pchan_getcaps), - KOBJMETHOD_END -}; -CHANNEL_DECLARE(ds1pchan); - -/* -------------------------------------------------------------------- */ -/* record channel interface */ -static void * -ds1rchan_init(kobj_t obj, void *devinfo, struct snd_dbuf *b, struct pcm_channel *c, int dir) -{ - struct sc_info *sc = devinfo; - struct sc_rchinfo *ch; - - KASSERT(dir == PCMDIR_REC, ("ds1rchan_init: bad direction")); - - ch = &sc->rch[sc->rchn]; - ch->num = sc->rchn++; - ch->buffer = b; - ch->parent = sc; - ch->channel = c; - ch->dir = dir; - ch->fmt = SND_FORMAT(AFMT_U8, 1, 0); - ch->spd = 8000; - if (sndbuf_alloc(ch->buffer, sc->buffer_dmat, 0, sc->bufsz) != 0) - return NULL; - else { - ch->slot = (ch->num == DS1_RECPRIMARY)? sc->rbank + 2: sc->rbank; - ds_setuprch(ch); - return ch; - } -} - -static int -ds1rchan_setformat(kobj_t obj, void *data, u_int32_t format) -{ - struct sc_rchinfo *ch = data; - - ch->fmt = format; - - return 0; -} - -static u_int32_t -ds1rchan_setspeed(kobj_t obj, void *data, u_int32_t speed) -{ - struct sc_rchinfo *ch = data; - - ch->spd = speed; - - return speed; -} - -static u_int32_t -ds1rchan_setblocksize(kobj_t obj, void *data, u_int32_t blocksize) -{ - struct sc_rchinfo *ch = data; - struct sc_info *sc = ch->parent; - int drate; - - /* irq rate is fixed at 187.5hz */ - drate = ch->spd * sndbuf_getalign(ch->buffer); - blocksize = roundup2((drate << 8) / DS1_IRQHZ, 4); - sndbuf_resize(ch->buffer, sc->bufsz / blocksize, blocksize); - - return blocksize; -} - -/* semantic note: must start at beginning of buffer */ -static int -ds1rchan_trigger(kobj_t obj, void *data, int go) -{ - struct sc_rchinfo *ch = data; - struct sc_info *sc = ch->parent; - u_int32_t x; - - if (!PCMTRIG_COMMON(go)) - return 0; - if (go == PCMTRIG_START) { - ch->run = 1; - ds_setuprch(ch); - snd_mtxlock(sc->lock); - x = ds_rd(sc, YDSXGR_MAPOFREC, 4); - x |= (ch->num == DS1_RECPRIMARY)? 0x02 : 0x01; - ds_wr(sc, YDSXGR_MAPOFREC, x, 4); - ds_wr(sc, YDSXGR_MODE, 0x00000003, 4); - snd_mtxunlock(sc->lock); - } else { - ch->run = 0; - snd_mtxlock(sc->lock); - x = ds_rd(sc, YDSXGR_MAPOFREC, 4); - x &= ~((ch->num == DS1_RECPRIMARY)? 0x02 : 0x01); - ds_wr(sc, YDSXGR_MAPOFREC, x, 4); - snd_mtxunlock(sc->lock); - } - - return 0; -} - -static u_int32_t -ds1rchan_getptr(kobj_t obj, void *data) -{ - struct sc_rchinfo *ch = data; - struct sc_info *sc = ch->parent; - - return ch->slot[sc->currbank].PgStart; -} - -static struct pcmchan_caps * -ds1rchan_getcaps(kobj_t obj, void *data) -{ - return &ds_reccaps; -} - -static kobj_method_t ds1rchan_methods[] = { - KOBJMETHOD(channel_init, ds1rchan_init), - KOBJMETHOD(channel_setformat, ds1rchan_setformat), - KOBJMETHOD(channel_setspeed, ds1rchan_setspeed), - KOBJMETHOD(channel_setblocksize, ds1rchan_setblocksize), - KOBJMETHOD(channel_trigger, ds1rchan_trigger), - KOBJMETHOD(channel_getptr, ds1rchan_getptr), - KOBJMETHOD(channel_getcaps, ds1rchan_getcaps), - KOBJMETHOD_END -}; -CHANNEL_DECLARE(ds1rchan); - -/* -------------------------------------------------------------------- */ -/* The interrupt handler */ -static void -ds_intr(void *p) -{ - struct sc_info *sc = (struct sc_info *)p; - u_int32_t i, x; - - snd_mtxlock(sc->lock); - i = ds_rd(sc, YDSXGR_STATUS, 4); - if (i & 0x00008000) - device_printf(sc->dev, "timeout irq\n"); - if (i & 0x80008000) { - ds_wr(sc, YDSXGR_STATUS, i & 0x80008000, 4); - sc->currbank = ds_rd(sc, YDSXGR_CTRLSELECT, 4) & 0x00000001; - - x = 0; - for (i = 0; i < DS1_CHANS; i++) { - if (sc->pch[i].run) { - x = 1; - snd_mtxunlock(sc->lock); - chn_intr(sc->pch[i].channel); - snd_mtxlock(sc->lock); - } - } - for (i = 0; i < 2; i++) { - if (sc->rch[i].run) { - x = 1; - snd_mtxunlock(sc->lock); - chn_intr(sc->rch[i].channel); - snd_mtxlock(sc->lock); - } - } - i = ds_rd(sc, YDSXGR_MODE, 4); - if (x) - ds_wr(sc, YDSXGR_MODE, i | 0x00000002, 4); - } - snd_mtxunlock(sc->lock); -} - -/* -------------------------------------------------------------------- */ - -/* - * Probe and attach the card - */ - -static void -ds_setmap(void *arg, bus_dma_segment_t *segs, int nseg, int error) -{ - struct sc_info *sc = arg; - - sc->ctrlbase = error? 0 : (u_int32_t)segs->ds_addr; - - if (bootverbose) { - printf("ds1: setmap (%lx, %lx), nseg=%d, error=%d\n", - (unsigned long)segs->ds_addr, (unsigned long)segs->ds_len, - nseg, error); - } -} - -static int -ds_init(struct sc_info *sc) -{ - int i; - u_int32_t *ci, r, pcs, rcs, ecs, ws, memsz, cb; - u_int8_t *t; - void *buf; - - ci = ds_devs[sc->type].mcode; - - ds_wr(sc, YDSXGR_NATIVEDACOUTVOL, 0x00000000, 4); - ds_enadsp(sc, 0); - ds_wr(sc, YDSXGR_MODE, 0x00010000, 4); - ds_wr(sc, YDSXGR_MODE, 0x00000000, 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); - r = ds_rd(sc, YDSXGR_GLOBALCTRL, 2); - ds_wr(sc, YDSXGR_GLOBALCTRL, r & ~0x0007, 2); - - for (i = 0; i < YDSXG_DSPLENGTH; i += 4) - ds_wr(sc, YDSXGR_DSPINSTRAM + i, DspInst[i >> 2], 4); - - for (i = 0; i < YDSXG_CTRLLENGTH; i += 4) - ds_wr(sc, YDSXGR_CTRLINSTRAM + i, ci[i >> 2], 4); - - ds_enadsp(sc, 1); - - pcs = 0; - for (i = 100; i > 0; i--) { - pcs = ds_rd(sc, YDSXGR_PLAYCTRLSIZE, 4) << 2; - if (pcs == sizeof(struct pbank)) - break; - DELAY(1000); - } - if (pcs != sizeof(struct pbank)) { - device_printf(sc->dev, "preposterous playctrlsize (%d)\n", pcs); - return -1; - } - rcs = ds_rd(sc, YDSXGR_RECCTRLSIZE, 4) << 2; - ecs = ds_rd(sc, YDSXGR_EFFCTRLSIZE, 4) << 2; - ws = ds_rd(sc, YDSXGR_WORKSIZE, 4) << 2; - - memsz = 64 * 2 * pcs + 2 * 2 * rcs + 5 * 2 * ecs + ws; - memsz += (64 + 1) * 4; - - if (sc->regbase == NULL) { - if (bus_dma_tag_create(bus_get_dma_tag(sc->dev), 2, 0, - BUS_SPACE_MAXADDR_32BIT, - BUS_SPACE_MAXADDR, - NULL, NULL, memsz, 1, memsz, 0, NULL, - NULL, &sc->control_dmat)) - return -1; - if (bus_dmamem_alloc(sc->control_dmat, &buf, BUS_DMA_NOWAIT, &sc->map)) - return -1; - if (bus_dmamap_load(sc->control_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); - return -1; - } - sc->regbase = buf; - } else - buf = sc->regbase; - - cb = 0; - t = buf; - ds_wr(sc, YDSXGR_WORKBASE, sc->ctrlbase + cb, 4); - cb += ws; - sc->pbase = (u_int32_t *)(t + cb); - /* printf("pbase = %p -> 0x%x\n", sc->pbase, sc->ctrlbase + cb); */ - ds_wr(sc, YDSXGR_PLAYCTRLBASE, sc->ctrlbase + cb, 4); - cb += (64 + 1) * 4; - sc->rbank = (struct rbank *)(t + cb); - ds_wr(sc, YDSXGR_RECCTRLBASE, sc->ctrlbase + cb, 4); - cb += 2 * 2 * rcs; - ds_wr(sc, YDSXGR_EFFCTRLBASE, sc->ctrlbase + cb, 4); - cb += 5 * 2 * ecs; - - sc->pbankbase = sc->ctrlbase + cb; - sc->pbanksize = pcs; - for (i = 0; i < 64; i++) { - wrl(sc, &sc->pbase[i + 1], 0); - sc->pbank[i * 2] = (struct pbank *)(t + cb); - /* printf("pbank[%d] = %p -> 0x%x; ", i * 2, (struct pbank *)(t + cb), sc->ctrlbase + cb - vtophys(t + cb)); */ - cb += pcs; - sc->pbank[i * 2 + 1] = (struct pbank *)(t + cb); - /* printf("pbank[%d] = %p -> 0x%x\n", i * 2 + 1, (struct pbank *)(t + cb), sc->ctrlbase + cb - vtophys(t + cb)); */ - cb += pcs; - } - wrl(sc, &sc->pbase[0], DS1_CHANS * 2); - - sc->pchn = sc->rchn = 0; - ds_wr(sc, YDSXGR_NATIVEDACOUTVOL, 0x3fff3fff, 4); - ds_wr(sc, YDSXGR_NATIVEADCINVOL, 0x3fff3fff, 4); - ds_wr(sc, YDSXGR_NATIVEDACINVOL, 0x3fff3fff, 4); - - return 0; -} - -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->control_dmat, sc->map); - bus_dmamem_free(sc->control_dmat, sc->regbase, sc->map); - - return 0; -} - -static int -ds_finddev(u_int32_t dev, u_int32_t subdev) -{ - int i; - - for (i = 0; ds_devs[i].dev; i++) { - if (ds_devs[i].dev == dev && - (ds_devs[i].subdev == subdev || ds_devs[i].subdev == 0)) - return i; - } - return -1; -} - -static int -ds_pci_probe(device_t dev) -{ - int i; - u_int32_t subdev; - - subdev = (pci_get_subdevice(dev) << 16) | pci_get_subvendor(dev); - i = ds_finddev(pci_get_devid(dev), subdev); - if (i >= 0) { - device_set_desc(dev, ds_devs[i].name); - return BUS_PROBE_DEFAULT; - } else - return ENXIO; -} - -static int -ds_pci_attach(device_t dev) -{ - u_int32_t subdev, i; - struct sc_info *sc; - struct ac97_info *codec = NULL; - char status[SND_STATUSLEN]; - - sc = malloc(sizeof(*sc), M_DEVBUF, M_WAITOK | M_ZERO); - sc->lock = snd_mtxcreate(device_get_nameunit(dev), "snd_ds1 softc"); - sc->dev = dev; - subdev = (pci_get_subdevice(dev) << 16) | pci_get_subvendor(dev); - sc->type = ds_finddev(pci_get_devid(dev), subdev); - sc->rev = pci_get_revid(dev); - - pci_enable_busmaster(dev); - - sc->regid = PCIR_BAR(0); - sc->reg = bus_alloc_resource_any(dev, SYS_RES_MEMORY, &sc->regid, - RF_ACTIVE); - if (!sc->reg) { - device_printf(dev, "unable to map register space\n"); - goto bad; - } - - sc->st = rman_get_bustag(sc->reg); - sc->sh = rman_get_bushandle(sc->reg); - - sc->bufsz = pcm_getbuffersize(dev, 4096, DS1_BUFFSIZE, 65536); - - if (bus_dma_tag_create(/*parent*/bus_get_dma_tag(dev), /*alignment*/2, - /*boundary*/0, - /*lowaddr*/BUS_SPACE_MAXADDR_32BIT, - /*highaddr*/BUS_SPACE_MAXADDR, - /*filter*/NULL, /*filterarg*/NULL, - /*maxsize*/sc->bufsz, /*nsegments*/1, /*maxsegz*/0x3ffff, - /*flags*/0, /*lockfunc*/NULL, - /*lockarg*/NULL, &sc->buffer_dmat) != 0) { - device_printf(dev, "unable to create dma tag\n"); - goto bad; - } - - sc->regbase = NULL; - if (ds_init(sc) == -1) { - device_printf(dev, "unable to initialize the card\n"); - goto bad; - } - - codec = AC97_CREATE(dev, sc, ds_ac97); - if (codec == NULL) - goto bad; - /* - * Turn on inverted external amplifier sense flags for few - * 'special' boards. - */ - switch (subdev) { - case 0x81171033: /* NEC ValueStar (VT550/0) */ - ac97_setflags(codec, ac97_getflags(codec) | AC97_F_EAPD_INV); - break; - default: - break; - } - mixer_init(dev, ac97_getmixerclass(), codec); - - sc->irqid = 0; - sc->irq = bus_alloc_resource_any(dev, SYS_RES_IRQ, &sc->irqid, - RF_ACTIVE | RF_SHAREABLE); - if (!sc->irq || snd_setup_intr(dev, sc->irq, INTR_MPSAFE, ds_intr, sc, &sc->ih)) { - device_printf(dev, "unable to map interrupt\n"); - goto bad; - } - - snprintf(status, SND_STATUSLEN, "at memory 0x%jx irq %jd %s", - rman_get_start(sc->reg), rman_get_start(sc->irq),PCM_KLDSTRING(snd_ds1)); - - if (pcm_register(dev, sc, DS1_CHANS, 2)) - goto bad; - for (i = 0; i < DS1_CHANS; i++) - pcm_addchan(dev, PCMDIR_PLAY, &ds1pchan_class, sc); - for (i = 0; i < 2; i++) - pcm_addchan(dev, PCMDIR_REC, &ds1rchan_class, sc); - pcm_setstatus(dev, status); - - return 0; - -bad: - if (codec) - ac97_destroy(codec); - 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); - if (sc->buffer_dmat) - bus_dma_tag_destroy(sc->buffer_dmat); - if (sc->control_dmat) - bus_dma_tag_destroy(sc->control_dmat); - if (sc->lock) - snd_mtxfree(sc->lock); - free(sc, M_DEVBUF); - return ENXIO; -} - -static int -ds_pci_resume(device_t dev) -{ - struct sc_info *sc; - - sc = pcm_getdevinfo(dev); - - if (ds_init(sc) == -1) { - device_printf(dev, "unable to reinitialize the card\n"); - return ENXIO; - } - 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); - bus_release_resource(dev, SYS_RES_MEMORY, sc->regid, sc->reg); - bus_teardown_intr(dev, sc->irq, sc->ih); - bus_release_resource(dev, SYS_RES_IRQ, sc->irqid, sc->irq); - bus_dma_tag_destroy(sc->buffer_dmat); - bus_dma_tag_destroy(sc->control_dmat); - snd_mtxfree(sc->lock); - 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_detach, ds_pci_detach), - DEVMETHOD(device_resume, ds_pci_resume), - { 0, 0 } -}; - -static driver_t ds1_driver = { - "pcm", - ds1_methods, - PCM_SOFTC_SIZE, -}; - -DRIVER_MODULE(snd_ds1, pci, ds1_driver, pcm_devclass, 0, 0); -MODULE_DEPEND(snd_ds1, sound, SOUND_MINVER, SOUND_PREFVER, SOUND_MAXVER); -MODULE_VERSION(snd_ds1, 1); diff --git a/sys/dev/sound/pci/ds1.h b/sys/dev/sound/pci/ds1.h deleted file mode 100644 index 9c01f0e287fa..000000000000 --- a/sys/dev/sound/pci/ds1.h +++ /dev/null @@ -1,147 +0,0 @@ -/* - * ======================================================================= - * title : define - * company : YAMAHA - * author : Taichi Sugiyama - * create Data : 28/Sep/99 - * ======================================================================= - * $FreeBSD$ - */ - -/* ----- YAMAHA DS-XG Devices -------------------------------------------- */ -#define YAMAHA 0x1073 -#define YMF724 0x0004 -#define YMF724F 0x000d -#define YMF734 0x0005 -#define YMF737 0x0008 -#define YMF738 0x0020 -#define YMF740 0x000a -#define YMF740C 0x000c -#define YMF744 0x0010 -#define YMF754 0x0012 -#define YMF738_TEG 0x0006 -#define DEVICE4CH(x) ((x == YMF738) || (x == YMF744) || (x == YMF754)) - -#define PCIR_DSXGCTRL 0x48 -/* ----- interrupt flag -------------------------------------------------- */ -#define YDSXG_DEFINT 0x01 -#define YDSXG_TIMERINT 0x02 - -/* ----- AC97 ------------------------------------------------------------ */ -#define YDSXG_AC97TIMEOUT 1000 -#define YDSXG_AC97READCMD 0x8000 -#define YDSXG_AC97WRITECMD 0x0000 -#define YDSXG_AC97READFALSE 0xFFFF - -/* ----- AC97 register map _---------------------------------------------- */ -#define AC97R_GPIOSTATUS 0x54 - -/* ----- work buffer ----------------------------------------------------- */ -#define DEF_WORKBUFFLENGTH 0x0400 - -/* ----- register size --------------------------------------------------- */ -#define YDSXG_MAPLENGTH 0x8000 -#define YDSXG_DSPLENGTH 0x0080 -#define YDSXG_CTRLLENGTH 0x3000 - -/* ----- register map ---------------------------------------------------- */ -#define YDSXGR_INTFLAG 0x0004 -#define YDSXGR_ACTIVITY 0x0006 -#define YDSXGR_GLOBALCTRL 0x0008 -#define YDSXGR_ZVCTRL 0x000A -#define YDSXGR_TIMERCTRL 0x0010 -#define YDSXGR_TIMERCOUNT 0x0012 -#define YDSXGR_SPDIFOUTCTRL 0x0018 -#define YDSXGR_SPDIFOUTSTATUS 0x001C -#define YDSXGR_EEPROMCTRL 0x0020 -#define YDSXGR_SPDIFINCTRL 0x0034 -#define YDSXGR_SPDIFINSTATUS 0x0038 -#define YDSXGR_DSPPROGRAMDL 0x0048 -#define YDSXGR_DLCNTRL 0x004C -#define YDSXGR_GPIOININTFLAG 0x0050 -#define YDSXGR_GPIOININTENABLE 0x0052 -#define YDSXGR_GPIOINSTATUS 0x0054 -#define YDSXGR_GPIOOUTCTRL 0x0056 -#define YDSXGR_GPIOFUNCENABLE 0x0058 -#define YDSXGR_GPIOTYPECONFIG 0x005A -#define YDSXGR_AC97CMDDATA 0x0060 -#define YDSXGR_AC97CMDADR 0x0062 -#define YDSXGR_PRISTATUSDATA 0x0064 -#define YDSXGR_PRISTATUSADR 0x0066 -#define YDSXGR_SECSTATUSDATA 0x0068 -#define YDSXGR_SECSTATUSADR 0x006A -#define YDSXGR_SECCONFIG 0x0070 -#define YDSXGR_LEGACYOUTVOL 0x0080 -#define YDSXGR_LEGACYOUTVOLL 0x0080 -#define YDSXGR_LEGACYOUTVOLR 0x0082 -#define YDSXGR_NATIVEDACOUTVOL 0x0084 -#define YDSXGR_NATIVEDACOUTVOLL 0x0084 -#define YDSXGR_NATIVEDACOUTVOLR 0x0086 -#define YDSXGR_SPDIFOUTVOL 0x0088 -#define YDSXGR_SPDIFOUTVOLL 0x0088 -#define YDSXGR_SPDIFOUTVOLR 0x008A -#define YDSXGR_AC3OUTVOL 0x008C -#define YDSXGR_AC3OUTVOLL 0x008C -#define YDSXGR_AC3OUTVOLR 0x008E -#define YDSXGR_PRIADCOUTVOL 0x0090 -#define YDSXGR_PRIADCOUTVOLL 0x0090 -#define YDSXGR_PRIADCOUTVOLR 0x0092 -#define YDSXGR_LEGACYLOOPVOL 0x0094 -#define YDSXGR_LEGACYLOOPVOLL 0x0094 -#define YDSXGR_LEGACYLOOPVOLR 0x0096 -#define YDSXGR_NATIVEDACLOOPVOL 0x0098 -#define YDSXGR_NATIVEDACLOOPVOLL 0x0098 -#define YDSXGR_NATIVEDACLOOPVOLR 0x009A -#define YDSXGR_SPDIFLOOPVOL 0x009C -#define YDSXGR_SPDIFLOOPVOLL 0x009E -#define YDSXGR_SPDIFLOOPVOLR 0x009E -#define YDSXGR_AC3LOOPVOL 0x00A0 -#define YDSXGR_AC3LOOPVOLL 0x00A0 -#define YDSXGR_AC3LOOPVOLR 0x00A2 -#define YDSXGR_PRIADCLOOPVOL 0x00A4 -#define YDSXGR_PRIADCLOOPVOLL 0x00A4 -#define YDSXGR_PRIADCLOOPVOLR 0x00A6 -#define YDSXGR_NATIVEADCINVOL 0x00A8 -#define YDSXGR_NATIVEADCINVOLL 0x00A8 -#define YDSXGR_NATIVEADCINVOLR 0x00AA -#define YDSXGR_NATIVEDACINVOL 0x00AC -#define YDSXGR_NATIVEDACINVOLL 0x00AC -#define YDSXGR_NATIVEDACINVOLR 0x00AE -#define YDSXGR_BUF441OUTVOL 0x00B0 -#define YDSXGR_BUF441OUTVOLL 0x00B0 -#define YDSXGR_BUF441OUTVOLR 0x00B2 -#define YDSXGR_BUF441LOOPVOL 0x00B4 -#define YDSXGR_BUF441LOOPVOLL 0x00B4 -#define YDSXGR_BUF441LOOPVOLR 0x00B6 -#define YDSXGR_SPDIFOUTVOL2 0x00B8 -#define YDSXGR_SPDIFOUTVOL2L 0x00B8 -#define YDSXGR_SPDIFOUTVOL2R 0x00BA -#define YDSXGR_SPDIFLOOPVOL2 0x00BC -#define YDSXGR_SPDIFLOOPVOL2L 0x00BC -#define YDSXGR_SPDIFLOOPVOL2R 0x00BE -#define YDSXGR_ADCSLOTSR 0x00C0 -#define YDSXGR_RECSLOTSR 0x00C4 -#define YDSXGR_ADCFORMAT 0x00C8 -#define YDSXGR_RECFORMAT 0x00CC -#define YDSXGR_P44SLOTSR 0x00D0 -#define YDSXGR_STATUS 0x0100 -#define YDSXGR_CTRLSELECT 0x0104 -#define YDSXGR_MODE 0x0108 -#define YDSXGR_SAMPLECOUNT 0x010C -#define YDSXGR_NUMOFSAMPLES 0x0110 -#define YDSXGR_CONFIG 0x0114 -#define YDSXGR_PLAYCTRLSIZE 0x0140 -#define YDSXGR_RECCTRLSIZE 0x0144 -#define YDSXGR_EFFCTRLSIZE 0x0148 -#define YDSXGR_WORKSIZE 0x014C -#define YDSXGR_MAPOFREC 0x0150 -#define YDSXGR_MAPOFEFFECT 0x0154 -#define YDSXGR_PLAYCTRLBASE 0x0158 -#define YDSXGR_RECCTRLBASE 0x015C -#define YDSXGR_EFFCTRLBASE 0x0160 -#define YDSXGR_WORKBASE 0x0164 -#define YDSXGR_DSPINSTRAM 0x1000 -#define YDSXGR_CTRLINSTRAM 0x4000 - -/* ----- time out -------------------------------------------------------- */ -#define YDSXG_WORKBITTIMEOUT 250000 diff --git a/sys/dev/sound/pci/maestro.c b/sys/dev/sound/pci/maestro.c deleted file mode 100644 index 3caccdb12fe9..000000000000 --- a/sys/dev/sound/pci/maestro.c +++ /dev/null @@ -1,2043 +0,0 @@ -/*- - * SPDX-License-Identifier: BSD-2-Clause-FreeBSD - * - * Copyright (c) 2000-2004 Taku YAMAMOTO <taku@tackymt.homeip.net> - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * maestro.c,v 1.23.2.1 2003/10/03 18:21:38 taku Exp - */ - -/* - * Credits: - * - * Part of this code (especially in many magic numbers) was heavily inspired - * by the Linux driver originally written by - * Alan Cox <alan.cox@linux.org>, modified heavily by - * Zach Brown <zab@zabbo.net>. - * - * busdma()-ize and buffer size reduction were suggested by - * Cameron Grant <cg@freebsd.org>. - * Also he showed me the way to use busdma() suite. - * - * Internal speaker problems on NEC VersaPro's and Dell Inspiron 7500 - * were looked at by - * Munehiro Matsuda <haro@tk.kubota.co.jp>, - * who brought patches based on the Linux driver with some simplification. - * - * Hardware volume controller was implemented by - * John Baldwin <jhb@freebsd.org>. - */ - -#ifdef HAVE_KERNEL_OPTION_HEADERS -#include "opt_snd.h" -#endif - -#include <dev/sound/pcm/sound.h> -#include <dev/sound/pcm/ac97.h> -#include <dev/pci/pcireg.h> -#include <dev/pci/pcivar.h> - -#include <dev/sound/pci/maestro_reg.h> - -SND_DECLARE_FILE("$FreeBSD$"); - -/* - * PCI IDs of supported chips: - * - * MAESTRO-1 0x01001285 - * MAESTRO-2 0x1968125d - * MAESTRO-2E 0x1978125d - */ - -#define MAESTRO_1_PCI_ID 0x01001285 -#define MAESTRO_2_PCI_ID 0x1968125d -#define MAESTRO_2E_PCI_ID 0x1978125d - -#define NEC_SUBID1 0x80581033 /* Taken from Linux driver */ -#define NEC_SUBID2 0x803c1033 /* NEC VersaProNX VA26D */ - -#ifdef AGG_MAXPLAYCH -# if AGG_MAXPLAYCH > 4 -# undef AGG_MAXPLAYCH -# define AGG_MAXPLAYCH 4 -# endif -#else -# define AGG_MAXPLAYCH 4 -#endif - -#define AGG_DEFAULT_BUFSZ 0x4000 /* 0x1000, but gets underflows */ - -#ifndef PCIR_BAR -#define PCIR_BAR(x) (PCIR_MAPS + (x) * 4) -#endif - -/* ----------------------------- - * Data structures. - */ -struct agg_chinfo { - /* parent softc */ - struct agg_info *parent; - - /* FreeBSD newpcm related */ - struct pcm_channel *channel; - struct snd_dbuf *buffer; - - /* OS independent */ - bus_dmamap_t map; - bus_addr_t phys; /* channel buffer physical address */ - bus_addr_t base; /* channel buffer segment base */ - u_int32_t blklen; /* DMA block length in WORDs */ - u_int32_t buflen; /* channel buffer length in WORDs */ - u_int32_t speed; - unsigned num : 3; - unsigned stereo : 1; - unsigned qs16 : 1; /* quantum size is 16bit */ - unsigned us : 1; /* in unsigned format */ -}; - -struct agg_rchinfo { - /* parent softc */ - struct agg_info *parent; - - /* FreeBSD newpcm related */ - struct pcm_channel *channel; - struct snd_dbuf *buffer; - - /* OS independent */ - bus_dmamap_t map; - bus_addr_t phys; /* channel buffer physical address */ - bus_addr_t base; /* channel buffer segment base */ - u_int32_t blklen; /* DMA block length in WORDs */ - u_int32_t buflen; /* channel buffer length in WORDs */ - u_int32_t speed; - unsigned : 3; - unsigned stereo : 1; - bus_addr_t srcphys; - int16_t *src; /* stereo peer buffer */ - int16_t *sink; /* channel buffer pointer */ - volatile u_int32_t hwptr; /* ready point in 16bit sample */ -}; - -struct agg_info { - /* FreeBSD newbus related */ - device_t dev; - - /* I wonder whether bus_space_* are in common in *BSD... */ - struct resource *reg; - int regid; - bus_space_tag_t st; - bus_space_handle_t sh; - - struct resource *irq; - int irqid; - void *ih; - - bus_dma_tag_t buf_dmat; - bus_dma_tag_t stat_dmat; - - /* FreeBSD SMPng related */ - struct mtx lock; /* mutual exclusion */ - /* FreeBSD newpcm related */ - struct ac97_info *codec; - - /* OS independent */ - bus_dmamap_t stat_map; - u_int8_t *stat; /* status buffer pointer */ - bus_addr_t phys; /* status buffer physical address */ - unsigned int bufsz; /* channel buffer size in bytes */ - u_int playchns; - volatile u_int active; - struct agg_chinfo pch[AGG_MAXPLAYCH]; - struct agg_rchinfo rch; - volatile u_int8_t curpwr; /* current power status: D[0-3] */ -}; - -/* ----------------------------- - * Sysctls for debug. - */ -static unsigned int powerstate_active = PCI_POWERSTATE_D1; -#ifdef MAESTRO_AGGRESSIVE_POWERSAVE -static unsigned int powerstate_idle = PCI_POWERSTATE_D2; -#else -static unsigned int powerstate_idle = PCI_POWERSTATE_D1; -#endif -static unsigned int powerstate_init = PCI_POWERSTATE_D2; - -/* XXX: this should move to a device specific sysctl dev.pcm.X.debug.Y via - device_get_sysctl_*() as discussed on multimedia@ in msg-id - <861wujij2q.fsf@xps.des.no> */ -static SYSCTL_NODE(_debug, OID_AUTO, maestro, CTLFLAG_RD | CTLFLAG_MPSAFE, 0, - ""); -SYSCTL_UINT(_debug_maestro, OID_AUTO, powerstate_active, CTLFLAG_RW, - &powerstate_active, 0, "The Dx power state when active (0-1)"); -SYSCTL_UINT(_debug_maestro, OID_AUTO, powerstate_idle, CTLFLAG_RW, - &powerstate_idle, 0, "The Dx power state when idle (0-2)"); -SYSCTL_UINT(_debug_maestro, OID_AUTO, powerstate_init, CTLFLAG_RW, - &powerstate_init, 0, - "The Dx power state prior to the first use (0-2)"); - -/* ----------------------------- - * Prototypes - */ - -static void agg_sleep(struct agg_info*, const char *wmesg, int msec); - -#if 0 -static __inline u_int32_t agg_rd(struct agg_info*, int, int size); -static __inline void agg_wr(struct agg_info*, int, u_int32_t data, - int size); -#endif -static int agg_rdcodec(struct agg_info*, int); -static int agg_wrcodec(struct agg_info*, int, u_int32_t); - -static void ringbus_setdest(struct agg_info*, int, int); - -static u_int16_t wp_rdreg(struct agg_info*, u_int16_t); -static void wp_wrreg(struct agg_info*, u_int16_t, u_int16_t); -static u_int16_t wp_rdapu(struct agg_info*, unsigned, u_int16_t); -static void wp_wrapu(struct agg_info*, unsigned, u_int16_t, u_int16_t); -static void wp_settimer(struct agg_info*, u_int); -static void wp_starttimer(struct agg_info*); -static void wp_stoptimer(struct agg_info*); - -#if 0 -static u_int16_t wc_rdreg(struct agg_info*, u_int16_t); -#endif -static void wc_wrreg(struct agg_info*, u_int16_t, u_int16_t); -#if 0 -static u_int16_t wc_rdchctl(struct agg_info*, int); -#endif -static void wc_wrchctl(struct agg_info*, int, u_int16_t); - -static void agg_stopclock(struct agg_info*, int part, int st); - -static void agg_initcodec(struct agg_info*); -static void agg_init(struct agg_info*); -static void agg_power(struct agg_info*, int); - -static void aggch_start_dac(struct agg_chinfo*); -static void aggch_stop_dac(struct agg_chinfo*); -static void aggch_start_adc(struct agg_rchinfo*); -static void aggch_stop_adc(struct agg_rchinfo*); -static void aggch_feed_adc_stereo(struct agg_rchinfo*); -static void aggch_feed_adc_mono(struct agg_rchinfo*); - -#ifdef AGG_JITTER_CORRECTION -static void suppress_jitter(struct agg_chinfo*); -static void suppress_rec_jitter(struct agg_rchinfo*); -#endif - -static void set_timer(struct agg_info*); - -static void agg_intr(void *); -static int agg_probe(device_t); -static int agg_attach(device_t); -static int agg_detach(device_t); -static int agg_suspend(device_t); -static int agg_resume(device_t); -static int agg_shutdown(device_t); - -static void *dma_malloc(bus_dma_tag_t, u_int32_t, bus_addr_t*, - bus_dmamap_t *); -static void dma_free(bus_dma_tag_t, void *, bus_dmamap_t); - -/* ----------------------------- - * Subsystems. - */ - -/* locking */ -#define agg_lock(sc) snd_mtxlock(&((sc)->lock)) -#define agg_unlock(sc) snd_mtxunlock(&((sc)->lock)) - -static void -agg_sleep(struct agg_info *sc, const char *wmesg, int msec) -{ - int timo; - - timo = msec * hz / 1000; - if (timo == 0) - timo = 1; - msleep(sc, &sc->lock, PWAIT, wmesg, timo); -} - -/* I/O port */ - -#if 0 -static __inline u_int32_t -agg_rd(struct agg_info *sc, int regno, int size) -{ - switch (size) { - case 1: - return bus_space_read_1(sc->st, sc->sh, regno); - case 2: - return bus_space_read_2(sc->st, sc->sh, regno); - case 4: - return bus_space_read_4(sc->st, sc->sh, regno); - default: - return ~(u_int32_t)0; - } -} -#endif - -#define AGG_RD(sc, regno, size) \ - bus_space_read_##size( \ - ((struct agg_info*)(sc))->st, \ - ((struct agg_info*)(sc))->sh, (regno)) - -#if 0 -static __inline void -agg_wr(struct agg_info *sc, int regno, u_int32_t data, int size) -{ - switch (size) { - case 1: - bus_space_write_1(sc->st, sc->sh, regno, data); - break; - case 2: - bus_space_write_2(sc->st, sc->sh, regno, data); - break; - case 4: - bus_space_write_4(sc->st, sc->sh, regno, data); - break; - } -} -#endif - -#define AGG_WR(sc, regno, data, size) \ - bus_space_write_##size( \ - ((struct agg_info*)(sc))->st, \ - ((struct agg_info*)(sc))->sh, (regno), (data)) - -/* -------------------------------------------------------------------- */ - -/* Codec/Ringbus */ - -static int -agg_codec_wait4idle(struct agg_info *ess) -{ - unsigned t = 26; - - while (AGG_RD(ess, PORT_CODEC_STAT, 1) & CODEC_STAT_MASK) { - if (--t == 0) - return EBUSY; - DELAY(2); /* 20.8us / 13 */ - } - return 0; -} - -static int -agg_rdcodec(struct agg_info *ess, int regno) -{ - int ret; - - /* We have to wait for a SAFE time to write addr/data */ - if (agg_codec_wait4idle(ess)) { - /* Timed out. No read performed. */ - device_printf(ess->dev, "agg_rdcodec() PROGLESS timed out.\n"); - return -1; - } - - AGG_WR(ess, PORT_CODEC_CMD, CODEC_CMD_READ | regno, 1); - /*DELAY(21); * AC97 cycle = 20.8usec */ - - /* Wait for data retrieve */ - if (!agg_codec_wait4idle(ess)) { - ret = AGG_RD(ess, PORT_CODEC_REG, 2); - } else { - /* Timed out. No read performed. */ - device_printf(ess->dev, "agg_rdcodec() RW_DONE timed out.\n"); - ret = -1; - } - - return ret; -} - -static int -agg_wrcodec(struct agg_info *ess, int regno, u_int32_t data) -{ - /* We have to wait for a SAFE time to write addr/data */ - if (agg_codec_wait4idle(ess)) { - /* Timed out. Abort writing. */ - device_printf(ess->dev, "agg_wrcodec() PROGLESS timed out.\n"); - return -1; - } - - AGG_WR(ess, PORT_CODEC_REG, data, 2); - AGG_WR(ess, PORT_CODEC_CMD, CODEC_CMD_WRITE | regno, 1); - - /* Wait for write completion */ - if (agg_codec_wait4idle(ess)) { - /* Timed out. */ - device_printf(ess->dev, "agg_wrcodec() RW_DONE timed out.\n"); - return -1; - } - - return 0; -} - -static void -ringbus_setdest(struct agg_info *ess, int src, int dest) -{ - u_int32_t data; - - data = AGG_RD(ess, PORT_RINGBUS_CTRL, 4); - data &= ~(0xfU << src); - data |= (0xfU & dest) << src; - AGG_WR(ess, PORT_RINGBUS_CTRL, data, 4); -} - -/* -------------------------------------------------------------------- */ - -/* Wave Processor */ - -static u_int16_t -wp_rdreg(struct agg_info *ess, u_int16_t reg) -{ - AGG_WR(ess, PORT_DSP_INDEX, reg, 2); - return AGG_RD(ess, PORT_DSP_DATA, 2); -} - -static void -wp_wrreg(struct agg_info *ess, u_int16_t reg, u_int16_t data) -{ - AGG_WR(ess, PORT_DSP_INDEX, reg, 2); - AGG_WR(ess, PORT_DSP_DATA, data, 2); -} - -static int -wp_wait_data(struct agg_info *ess, u_int16_t data) -{ - unsigned t = 0; - - while (AGG_RD(ess, PORT_DSP_DATA, 2) != data) { - if (++t == 1000) { - return EAGAIN; - } - AGG_WR(ess, PORT_DSP_DATA, data, 2); - } - - return 0; -} - -static u_int16_t -wp_rdapu(struct agg_info *ess, unsigned ch, u_int16_t reg) -{ - wp_wrreg(ess, WPREG_CRAM_PTR, reg | (ch << 4)); - if (wp_wait_data(ess, reg | (ch << 4)) != 0) - device_printf(ess->dev, "wp_rdapu() indexing timed out.\n"); - return wp_rdreg(ess, WPREG_DATA_PORT); -} - -static void -wp_wrapu(struct agg_info *ess, unsigned ch, u_int16_t reg, u_int16_t data) -{ - wp_wrreg(ess, WPREG_CRAM_PTR, reg | (ch << 4)); - if (wp_wait_data(ess, reg | (ch << 4)) == 0) { - wp_wrreg(ess, WPREG_DATA_PORT, data); - if (wp_wait_data(ess, data) != 0) - device_printf(ess->dev, - "wp_wrapu() write timed out.\n"); - } else { - device_printf(ess->dev, "wp_wrapu() indexing timed out.\n"); - } -} - -static void -apu_setparam(struct agg_info *ess, int apuch, - u_int32_t wpwa, u_int16_t size, int16_t pan, u_int dv) -{ - wp_wrapu(ess, apuch, APUREG_WAVESPACE, (wpwa >> 8) & APU_64KPAGE_MASK); - wp_wrapu(ess, apuch, APUREG_CURPTR, wpwa); - wp_wrapu(ess, apuch, APUREG_ENDPTR, wpwa + size); - wp_wrapu(ess, apuch, APUREG_LOOPLEN, size); - wp_wrapu(ess, apuch, APUREG_ROUTING, 0); - wp_wrapu(ess, apuch, APUREG_AMPLITUDE, 0xf000); - wp_wrapu(ess, apuch, APUREG_POSITION, 0x8f00 - | (APU_RADIUS_MASK & (RADIUS_CENTERCIRCLE << APU_RADIUS_SHIFT)) - | (APU_PAN_MASK & ((pan + PAN_FRONT) << APU_PAN_SHIFT))); - wp_wrapu(ess, apuch, APUREG_FREQ_LOBYTE, - APU_plus6dB | ((dv & 0xff) << APU_FREQ_LOBYTE_SHIFT)); - wp_wrapu(ess, apuch, APUREG_FREQ_HIWORD, dv >> 8); -} - -static void -wp_settimer(struct agg_info *ess, u_int divide) -{ - u_int prescale = 0; - - RANGE(divide, 2, 32 << 7); - - for (; divide > 32; divide >>= 1) { - prescale++; - divide++; - } - - for (; prescale < 7 && divide > 2 && !(divide & 1); divide >>= 1) - prescale++; - - wp_wrreg(ess, WPREG_TIMER_ENABLE, 0); - wp_wrreg(ess, WPREG_TIMER_FREQ, 0x9000 | - (prescale << WP_TIMER_FREQ_PRESCALE_SHIFT) | (divide - 1)); - wp_wrreg(ess, WPREG_TIMER_ENABLE, 1); -} - -static void -wp_starttimer(struct agg_info *ess) -{ - AGG_WR(ess, PORT_INT_STAT, 1, 2); - AGG_WR(ess, PORT_HOSTINT_CTRL, HOSTINT_CTRL_DSOUND_INT_ENABLED - | AGG_RD(ess, PORT_HOSTINT_CTRL, 2), 2); - wp_wrreg(ess, WPREG_TIMER_START, 1); -} - -static void -wp_stoptimer(struct agg_info *ess) -{ - AGG_WR(ess, PORT_HOSTINT_CTRL, ~HOSTINT_CTRL_DSOUND_INT_ENABLED - & AGG_RD(ess, PORT_HOSTINT_CTRL, 2), 2); - AGG_WR(ess, PORT_INT_STAT, 1, 2); - wp_wrreg(ess, WPREG_TIMER_START, 0); -} - -/* -------------------------------------------------------------------- */ - -/* WaveCache */ - -#if 0 -static u_int16_t -wc_rdreg(struct agg_info *ess, u_int16_t reg) -{ - AGG_WR(ess, PORT_WAVCACHE_INDEX, reg, 2); - return AGG_RD(ess, PORT_WAVCACHE_DATA, 2); -} -#endif - -static void -wc_wrreg(struct agg_info *ess, u_int16_t reg, u_int16_t data) -{ - AGG_WR(ess, PORT_WAVCACHE_INDEX, reg, 2); - AGG_WR(ess, PORT_WAVCACHE_DATA, data, 2); -} - -#if 0 -static u_int16_t -wc_rdchctl(struct agg_info *ess, int ch) -{ - return wc_rdreg(ess, ch << 3); -} -#endif - -static void -wc_wrchctl(struct agg_info *ess, int ch, u_int16_t data) -{ - wc_wrreg(ess, ch << 3, data); -} - -/* -------------------------------------------------------------------- */ - -/* Power management */ -static void -agg_stopclock(struct agg_info *ess, int part, int st) -{ - u_int32_t data; - - data = pci_read_config(ess->dev, CONF_ACPI_STOPCLOCK, 4); - if (part < 16) { - if (st == PCI_POWERSTATE_D1) - data &= ~(1 << part); - else - data |= (1 << part); - if (st == PCI_POWERSTATE_D1 || st == PCI_POWERSTATE_D2) - data |= (0x10000 << part); - else - data &= ~(0x10000 << part); - pci_write_config(ess->dev, CONF_ACPI_STOPCLOCK, data, 4); - } -} - -/* ----------------------------- - * Controller. - */ - -static void -agg_initcodec(struct agg_info* ess) -{ - u_int16_t data; - - if (AGG_RD(ess, PORT_RINGBUS_CTRL, 4) & RINGBUS_CTRL_ACLINK_ENABLED) { - AGG_WR(ess, PORT_RINGBUS_CTRL, 0, 4); - DELAY(104); /* 20.8us * (4 + 1) */ - } - /* XXX - 2nd codec should be looked at. */ - AGG_WR(ess, PORT_RINGBUS_CTRL, RINGBUS_CTRL_AC97_SWRESET, 4); - DELAY(2); - AGG_WR(ess, PORT_RINGBUS_CTRL, RINGBUS_CTRL_ACLINK_ENABLED, 4); - DELAY(50); - - if (agg_rdcodec(ess, 0) < 0) { - AGG_WR(ess, PORT_RINGBUS_CTRL, 0, 4); - DELAY(21); - - /* Try cold reset. */ - device_printf(ess->dev, "will perform cold reset.\n"); - data = AGG_RD(ess, PORT_GPIO_DIR, 2); - if (pci_read_config(ess->dev, 0x58, 2) & 1) - data |= 0x10; - data |= 0x009 & ~AGG_RD(ess, PORT_GPIO_DATA, 2); - AGG_WR(ess, PORT_GPIO_MASK, 0xff6, 2); - AGG_WR(ess, PORT_GPIO_DIR, data | 0x009, 2); - AGG_WR(ess, PORT_GPIO_DATA, 0x000, 2); - DELAY(2); - AGG_WR(ess, PORT_GPIO_DATA, 0x001, 2); - DELAY(1); - AGG_WR(ess, PORT_GPIO_DATA, 0x009, 2); - agg_sleep(ess, "agginicd", 500); - AGG_WR(ess, PORT_GPIO_DIR, data, 2); - DELAY(84); /* 20.8us * 4 */ - AGG_WR(ess, PORT_RINGBUS_CTRL, RINGBUS_CTRL_ACLINK_ENABLED, 4); - DELAY(50); - } -} - -static void -agg_init(struct agg_info* ess) -{ - u_int32_t data; - - /* Setup PCI config registers. */ - - /* Disable all legacy emulations. */ - data = pci_read_config(ess->dev, CONF_LEGACY, 2); - data |= LEGACY_DISABLED; - pci_write_config(ess->dev, CONF_LEGACY, data, 2); - - /* Disconnect from CHI. (Makes Dell inspiron 7500 work?) - * Enable posted write. - * Prefer PCI timing rather than that of ISA. - * Don't swap L/R. */ - data = pci_read_config(ess->dev, CONF_MAESTRO, 4); - data |= MAESTRO_PMC; - data |= MAESTRO_CHIBUS | MAESTRO_POSTEDWRITE | MAESTRO_DMA_PCITIMING; - data &= ~MAESTRO_SWAP_LR; - pci_write_config(ess->dev, CONF_MAESTRO, data, 4); - - /* Turn off unused parts if necessary. */ - /* consult CONF_MAESTRO. */ - if (data & MAESTRO_SPDIF) - agg_stopclock(ess, ACPI_PART_SPDIF, PCI_POWERSTATE_D2); - else - agg_stopclock(ess, ACPI_PART_SPDIF, PCI_POWERSTATE_D1); - if (data & MAESTRO_HWVOL) - agg_stopclock(ess, ACPI_PART_HW_VOL, PCI_POWERSTATE_D3); - else - agg_stopclock(ess, ACPI_PART_HW_VOL, PCI_POWERSTATE_D1); - - /* parts that never be used */ - agg_stopclock(ess, ACPI_PART_978, PCI_POWERSTATE_D1); - agg_stopclock(ess, ACPI_PART_DAA, PCI_POWERSTATE_D1); - agg_stopclock(ess, ACPI_PART_GPIO, PCI_POWERSTATE_D1); - agg_stopclock(ess, ACPI_PART_SB, PCI_POWERSTATE_D1); - agg_stopclock(ess, ACPI_PART_FM, PCI_POWERSTATE_D1); - agg_stopclock(ess, ACPI_PART_MIDI, PCI_POWERSTATE_D1); - agg_stopclock(ess, ACPI_PART_GAME_PORT, PCI_POWERSTATE_D1); - - /* parts that will be used only when play/recording */ - agg_stopclock(ess, ACPI_PART_WP, PCI_POWERSTATE_D2); - - /* parts that should always be turned on */ - agg_stopclock(ess, ACPI_PART_CODEC_CLOCK, PCI_POWERSTATE_D3); - agg_stopclock(ess, ACPI_PART_GLUE, PCI_POWERSTATE_D3); - agg_stopclock(ess, ACPI_PART_PCI_IF, PCI_POWERSTATE_D3); - agg_stopclock(ess, ACPI_PART_RINGBUS, PCI_POWERSTATE_D3); - - /* Reset direct sound. */ - AGG_WR(ess, PORT_HOSTINT_CTRL, HOSTINT_CTRL_SOFT_RESET, 2); - DELAY(100); - AGG_WR(ess, PORT_HOSTINT_CTRL, 0, 2); - DELAY(100); - AGG_WR(ess, PORT_HOSTINT_CTRL, HOSTINT_CTRL_DSOUND_RESET, 2); - DELAY(100); - AGG_WR(ess, PORT_HOSTINT_CTRL, 0, 2); - DELAY(100); - - /* Enable hardware volume control interruption. */ - if (data & MAESTRO_HWVOL) /* XXX - why not use device flags? */ - AGG_WR(ess, PORT_HOSTINT_CTRL,HOSTINT_CTRL_HWVOL_ENABLED, 2); - - /* Setup Wave Processor. */ - - /* Enable WaveCache, set DMA base address. */ - wp_wrreg(ess, WPREG_WAVE_ROMRAM, - WP_WAVE_VIRTUAL_ENABLED | WP_WAVE_DRAM_ENABLED); - wp_wrreg(ess, WPREG_CRAM_DATA, 0); - - AGG_WR(ess, PORT_WAVCACHE_CTRL, - WAVCACHE_ENABLED | WAVCACHE_WTSIZE_2MB | WAVCACHE_SGC_32_47, 2); - - for (data = WAVCACHE_PCMBAR; data < WAVCACHE_PCMBAR + 4; data++) - wc_wrreg(ess, data, ess->phys >> WAVCACHE_BASEADDR_SHIFT); - - /* Setup Codec/Ringbus. */ - agg_initcodec(ess); - AGG_WR(ess, PORT_RINGBUS_CTRL, - RINGBUS_CTRL_RINGBUS_ENABLED | RINGBUS_CTRL_ACLINK_ENABLED, 4); - - wp_wrreg(ess, 0x08, 0xB004); - wp_wrreg(ess, 0x09, 0x001B); - wp_wrreg(ess, 0x0A, 0x8000); - wp_wrreg(ess, 0x0B, 0x3F37); - wp_wrreg(ess, WPREG_BASE, 0x8598); /* Parallel I/O */ - wp_wrreg(ess, WPREG_BASE + 1, 0x7632); - ringbus_setdest(ess, RINGBUS_SRC_ADC, - RINGBUS_DEST_STEREO | RINGBUS_DEST_DSOUND_IN); - ringbus_setdest(ess, RINGBUS_SRC_DSOUND, - RINGBUS_DEST_STEREO | RINGBUS_DEST_DAC); - - /* Enable S/PDIF if necessary. */ - if (pci_read_config(ess->dev, CONF_MAESTRO, 4) & MAESTRO_SPDIF) - /* XXX - why not use device flags? */ - AGG_WR(ess, PORT_RINGBUS_CTRL_B, RINGBUS_CTRL_SPDIF | - AGG_RD(ess, PORT_RINGBUS_CTRL_B, 1), 1); - - /* Setup ASSP. Needed for Dell Inspiron 7500? */ - AGG_WR(ess, PORT_ASSP_CTRL_B, 0x00, 1); - AGG_WR(ess, PORT_ASSP_CTRL_A, 0x03, 1); - AGG_WR(ess, PORT_ASSP_CTRL_C, 0x00, 1); - - /* - * Setup GPIO. - * There seems to be speciality with NEC systems. - */ - switch (pci_get_subvendor(ess->dev) - | (pci_get_subdevice(ess->dev) << 16)) { - case NEC_SUBID1: - case NEC_SUBID2: - /* Matthew Braithwaite <matt@braithwaite.net> reported that - * NEC Versa LX doesn't need GPIO operation. */ - AGG_WR(ess, PORT_GPIO_MASK, 0x9ff, 2); - AGG_WR(ess, PORT_GPIO_DIR, - AGG_RD(ess, PORT_GPIO_DIR, 2) | 0x600, 2); - AGG_WR(ess, PORT_GPIO_DATA, 0x200, 2); - break; - } -} - -/* Deals power state transition. Must be called with softc->lock held. */ -static void -agg_power(struct agg_info *ess, int status) -{ - u_int8_t lastpwr; - - lastpwr = ess->curpwr; - if (lastpwr == status) - return; - - switch (status) { - case PCI_POWERSTATE_D0: - case PCI_POWERSTATE_D1: - switch (lastpwr) { - case PCI_POWERSTATE_D2: - pci_set_powerstate(ess->dev, status); - /* Turn on PCM-related parts. */ - agg_wrcodec(ess, AC97_REG_POWER, 0); - DELAY(100); -#if 0 - if ((agg_rdcodec(ess, AC97_REG_POWER) & 3) != 3) - device_printf(ess->dev, - "warning: codec not ready.\n"); -#endif - AGG_WR(ess, PORT_RINGBUS_CTRL, - (AGG_RD(ess, PORT_RINGBUS_CTRL, 4) - & ~RINGBUS_CTRL_ACLINK_ENABLED) - | RINGBUS_CTRL_RINGBUS_ENABLED, 4); - DELAY(50); - AGG_WR(ess, PORT_RINGBUS_CTRL, - AGG_RD(ess, PORT_RINGBUS_CTRL, 4) - | RINGBUS_CTRL_ACLINK_ENABLED, 4); - break; - case PCI_POWERSTATE_D3: - /* Initialize. */ - pci_set_powerstate(ess->dev, PCI_POWERSTATE_D0); - DELAY(100); - agg_init(ess); - /* FALLTHROUGH */ - case PCI_POWERSTATE_D0: - case PCI_POWERSTATE_D1: - pci_set_powerstate(ess->dev, status); - break; - } - break; - case PCI_POWERSTATE_D2: - switch (lastpwr) { - case PCI_POWERSTATE_D3: - /* Initialize. */ - pci_set_powerstate(ess->dev, PCI_POWERSTATE_D0); - DELAY(100); - agg_init(ess); - /* FALLTHROUGH */ - case PCI_POWERSTATE_D0: - case PCI_POWERSTATE_D1: - /* Turn off PCM-related parts. */ - AGG_WR(ess, PORT_RINGBUS_CTRL, - AGG_RD(ess, PORT_RINGBUS_CTRL, 4) - & ~RINGBUS_CTRL_RINGBUS_ENABLED, 4); - DELAY(100); - agg_wrcodec(ess, AC97_REG_POWER, 0x300); - DELAY(100); - break; - } - pci_set_powerstate(ess->dev, status); - break; - case PCI_POWERSTATE_D3: - /* Entirely power down. */ - agg_wrcodec(ess, AC97_REG_POWER, 0xdf00); - DELAY(100); - AGG_WR(ess, PORT_RINGBUS_CTRL, 0, 4); - /*DELAY(1);*/ - if (lastpwr != PCI_POWERSTATE_D2) - wp_stoptimer(ess); - AGG_WR(ess, PORT_HOSTINT_CTRL, 0, 2); - AGG_WR(ess, PORT_HOSTINT_STAT, 0xff, 1); - pci_set_powerstate(ess->dev, status); - break; - default: - /* Invalid power state; let it ignored. */ - status = lastpwr; - break; - } - - ess->curpwr = status; -} - -/* -------------------------------------------------------------------- */ - -/* Channel controller. */ - -static void -aggch_start_dac(struct agg_chinfo *ch) -{ - bus_addr_t wpwa; - u_int32_t speed; - u_int16_t size, apuch, wtbar, wcreg, aputype; - u_int dv; - int pan; - - speed = ch->speed; - wpwa = (ch->phys - ch->base) >> 1; - wtbar = 0xc & (wpwa >> WPWA_WTBAR_SHIFT(2)); - wcreg = (ch->phys - 16) & WAVCACHE_CHCTL_ADDRTAG_MASK; - size = ch->buflen; - apuch = (ch->num << 1) | 32; - pan = PAN_RIGHT - PAN_FRONT; - - if (ch->stereo) { - wcreg |= WAVCACHE_CHCTL_STEREO; - if (ch->qs16) { - aputype = APUTYPE_16BITSTEREO; - wpwa >>= 1; - size >>= 1; - pan = -pan; - } else - aputype = APUTYPE_8BITSTEREO; - } else { - pan = 0; - if (ch->qs16) - aputype = APUTYPE_16BITLINEAR; - else { - aputype = APUTYPE_8BITLINEAR; - speed >>= 1; - } - } - if (ch->us) - wcreg |= WAVCACHE_CHCTL_U8; - - if (wtbar > 8) - wtbar = (wtbar >> 1) + 4; - - dv = (((speed % 48000) << 16) + 24000) / 48000 - + ((speed / 48000) << 16); - - agg_lock(ch->parent); - agg_power(ch->parent, powerstate_active); - - wc_wrreg(ch->parent, WAVCACHE_WTBAR + wtbar, - ch->base >> WAVCACHE_BASEADDR_SHIFT); - wc_wrreg(ch->parent, WAVCACHE_WTBAR + wtbar + 1, - ch->base >> WAVCACHE_BASEADDR_SHIFT); - if (wtbar < 8) { - wc_wrreg(ch->parent, WAVCACHE_WTBAR + wtbar + 2, - ch->base >> WAVCACHE_BASEADDR_SHIFT); - wc_wrreg(ch->parent, WAVCACHE_WTBAR + wtbar + 3, - ch->base >> WAVCACHE_BASEADDR_SHIFT); - } - wc_wrchctl(ch->parent, apuch, wcreg); - wc_wrchctl(ch->parent, apuch + 1, wcreg); - - apu_setparam(ch->parent, apuch, wpwa, size, pan, dv); - if (ch->stereo) { - if (ch->qs16) - wpwa |= (WPWA_STEREO >> 1); - apu_setparam(ch->parent, apuch + 1, wpwa, size, -pan, dv); - - critical_enter(); - wp_wrapu(ch->parent, apuch, APUREG_APUTYPE, - (aputype << APU_APUTYPE_SHIFT) | APU_DMA_ENABLED | 0xf); - wp_wrapu(ch->parent, apuch + 1, APUREG_APUTYPE, - (aputype << APU_APUTYPE_SHIFT) | APU_DMA_ENABLED | 0xf); - critical_exit(); - } else { - wp_wrapu(ch->parent, apuch, APUREG_APUTYPE, - (aputype << APU_APUTYPE_SHIFT) | APU_DMA_ENABLED | 0xf); - } - - /* to mark that this channel is ready for intr. */ - ch->parent->active |= (1 << ch->num); - - set_timer(ch->parent); - wp_starttimer(ch->parent); - agg_unlock(ch->parent); -} - -static void -aggch_stop_dac(struct agg_chinfo *ch) -{ - agg_lock(ch->parent); - - /* to mark that this channel no longer needs further intrs. */ - ch->parent->active &= ~(1 << ch->num); - - wp_wrapu(ch->parent, (ch->num << 1) | 32, APUREG_APUTYPE, - APUTYPE_INACTIVE << APU_APUTYPE_SHIFT); - wp_wrapu(ch->parent, (ch->num << 1) | 33, APUREG_APUTYPE, - APUTYPE_INACTIVE << APU_APUTYPE_SHIFT); - - if (ch->parent->active) { - set_timer(ch->parent); - wp_starttimer(ch->parent); - } else { - wp_stoptimer(ch->parent); - agg_power(ch->parent, powerstate_idle); - } - agg_unlock(ch->parent); -} - -static void -aggch_start_adc(struct agg_rchinfo *ch) -{ - bus_addr_t wpwa, wpwa2; - u_int16_t wcreg, wcreg2; - u_int dv; - int pan; - - /* speed > 48000 not cared */ - dv = ((ch->speed << 16) + 24000) / 48000; - - /* RATECONV doesn't seem to like dv == 0x10000. */ - if (dv == 0x10000) - dv--; - - if (ch->stereo) { - wpwa = (ch->srcphys - ch->base) >> 1; - wpwa2 = (ch->srcphys + ch->parent->bufsz/2 - ch->base) >> 1; - wcreg = (ch->srcphys - 16) & WAVCACHE_CHCTL_ADDRTAG_MASK; - wcreg2 = (ch->base - 16) & WAVCACHE_CHCTL_ADDRTAG_MASK; - pan = PAN_LEFT - PAN_FRONT; - } else { - wpwa = (ch->phys - ch->base) >> 1; - wpwa2 = (ch->srcphys - ch->base) >> 1; - wcreg = (ch->phys - 16) & WAVCACHE_CHCTL_ADDRTAG_MASK; - wcreg2 = (ch->base - 16) & WAVCACHE_CHCTL_ADDRTAG_MASK; - pan = 0; - } - - agg_lock(ch->parent); - - ch->hwptr = 0; - agg_power(ch->parent, powerstate_active); - - /* Invalidate WaveCache. */ - wc_wrchctl(ch->parent, 0, wcreg | WAVCACHE_CHCTL_STEREO); - wc_wrchctl(ch->parent, 1, wcreg | WAVCACHE_CHCTL_STEREO); - wc_wrchctl(ch->parent, 2, wcreg2 | WAVCACHE_CHCTL_STEREO); - wc_wrchctl(ch->parent, 3, wcreg2 | WAVCACHE_CHCTL_STEREO); - - /* Load APU registers. */ - /* APU #0 : Sample rate converter for left/center. */ - apu_setparam(ch->parent, 0, WPWA_USE_SYSMEM | wpwa, - ch->buflen >> ch->stereo, 0, dv); - wp_wrapu(ch->parent, 0, APUREG_AMPLITUDE, 0); - wp_wrapu(ch->parent, 0, APUREG_ROUTING, 2 << APU_DATASRC_A_SHIFT); - - /* APU #1 : Sample rate converter for right. */ - apu_setparam(ch->parent, 1, WPWA_USE_SYSMEM | wpwa2, - ch->buflen >> ch->stereo, 0, dv); - wp_wrapu(ch->parent, 1, APUREG_AMPLITUDE, 0); - wp_wrapu(ch->parent, 1, APUREG_ROUTING, 3 << APU_DATASRC_A_SHIFT); - - /* APU #2 : Input mixer for left. */ - apu_setparam(ch->parent, 2, WPWA_USE_SYSMEM | 0, - ch->parent->bufsz >> 2, pan, 0x10000); - wp_wrapu(ch->parent, 2, APUREG_AMPLITUDE, 0); - wp_wrapu(ch->parent, 2, APUREG_EFFECT_GAIN, 0xf0); - wp_wrapu(ch->parent, 2, APUREG_ROUTING, 0x15 << APU_DATASRC_A_SHIFT); - - /* APU #3 : Input mixer for right. */ - apu_setparam(ch->parent, 3, WPWA_USE_SYSMEM | (ch->parent->bufsz >> 2), - ch->parent->bufsz >> 2, -pan, 0x10000); - wp_wrapu(ch->parent, 3, APUREG_AMPLITUDE, 0); - wp_wrapu(ch->parent, 3, APUREG_EFFECT_GAIN, 0xf0); - wp_wrapu(ch->parent, 3, APUREG_ROUTING, 0x14 << APU_DATASRC_A_SHIFT); - - /* to mark this channel ready for intr. */ - ch->parent->active |= (1 << ch->parent->playchns); - - /* start adc */ - critical_enter(); - wp_wrapu(ch->parent, 0, APUREG_APUTYPE, - (APUTYPE_RATECONV << APU_APUTYPE_SHIFT) | APU_DMA_ENABLED | 0xf); - wp_wrapu(ch->parent, 1, APUREG_APUTYPE, - (APUTYPE_RATECONV << APU_APUTYPE_SHIFT) | APU_DMA_ENABLED | 0xf); - wp_wrapu(ch->parent, 2, APUREG_APUTYPE, - (APUTYPE_INPUTMIXER << APU_APUTYPE_SHIFT) | 0xf); - wp_wrapu(ch->parent, 3, APUREG_APUTYPE, - (APUTYPE_INPUTMIXER << APU_APUTYPE_SHIFT) | 0xf); - critical_exit(); - - set_timer(ch->parent); - wp_starttimer(ch->parent); - agg_unlock(ch->parent); -} - -static void -aggch_stop_adc(struct agg_rchinfo *ch) -{ - int apuch; - - agg_lock(ch->parent); - - /* to mark that this channel no longer needs further intrs. */ - ch->parent->active &= ~(1 << ch->parent->playchns); - - for (apuch = 0; apuch < 4; apuch++) - wp_wrapu(ch->parent, apuch, APUREG_APUTYPE, - APUTYPE_INACTIVE << APU_APUTYPE_SHIFT); - - if (ch->parent->active) { - set_timer(ch->parent); - wp_starttimer(ch->parent); - } else { - wp_stoptimer(ch->parent); - agg_power(ch->parent, powerstate_idle); - } - agg_unlock(ch->parent); -} - -/* - * Feed from L/R channel of ADC to destination with stereo interleaving. - * This function expects n not overwrapping the buffer boundary. - * Note that n is measured in sample unit. - * - * XXX - this function works in 16bit stereo format only. - */ -static void -interleave(int16_t *l, int16_t *r, int16_t *p, unsigned n) -{ - int16_t *end; - - for (end = l + n; l < end; ) { - *p++ = *l++; - *p++ = *r++; - } -} - -static void -aggch_feed_adc_stereo(struct agg_rchinfo *ch) -{ - unsigned cur, last; - int16_t *src2; - - agg_lock(ch->parent); - cur = wp_rdapu(ch->parent, 0, APUREG_CURPTR); - agg_unlock(ch->parent); - cur -= 0xffff & ((ch->srcphys - ch->base) >> 1); - last = ch->hwptr; - src2 = ch->src + ch->parent->bufsz/4; - - if (cur < last) { - interleave(ch->src + last, src2 + last, - ch->sink + 2*last, ch->buflen/2 - last); - interleave(ch->src, src2, - ch->sink, cur); - } else if (cur > last) - interleave(ch->src + last, src2 + last, - ch->sink + 2*last, cur - last); - ch->hwptr = cur; -} - -/* - * Feed from R channel of ADC and mixdown to destination L/center. - * This function expects n not overwrapping the buffer boundary. - * Note that n is measured in sample unit. - * - * XXX - this function works in 16bit monoral format only. - */ -static void -mixdown(int16_t *src, int16_t *dest, unsigned n) -{ - int16_t *end; - - for (end = dest + n; dest < end; dest++) - *dest = (int16_t)(((int)*dest - (int)*src++) / 2); -} - -static void -aggch_feed_adc_mono(struct agg_rchinfo *ch) -{ - unsigned cur, last; - - agg_lock(ch->parent); - cur = wp_rdapu(ch->parent, 0, APUREG_CURPTR); - agg_unlock(ch->parent); - cur -= 0xffff & ((ch->phys - ch->base) >> 1); - last = ch->hwptr; - - if (cur < last) { - mixdown(ch->src + last, ch->sink + last, ch->buflen - last); - mixdown(ch->src, ch->sink, cur); - } else if (cur > last) - mixdown(ch->src + last, ch->sink + last, cur - last); - ch->hwptr = cur; -} - -#ifdef AGG_JITTER_CORRECTION -/* - * Stereo jitter suppressor. - * Sometimes playback pointers differ in stereo-paired channels. - * Calling this routine within intr fixes the problem. - */ -static void -suppress_jitter(struct agg_chinfo *ch) -{ - if (ch->stereo) { - int cp1, cp2, diff /*, halfsize*/ ; - - /*halfsize = (ch->qs16? ch->buflen >> 2 : ch->buflen >> 1);*/ - cp1 = wp_rdapu(ch->parent, (ch->num << 1) | 32, APUREG_CURPTR); - cp2 = wp_rdapu(ch->parent, (ch->num << 1) | 33, APUREG_CURPTR); - if (cp1 != cp2) { - diff = (cp1 > cp2 ? cp1 - cp2 : cp2 - cp1); - if (diff > 1 /* && diff < halfsize*/ ) - AGG_WR(ch->parent, PORT_DSP_DATA, cp1, 2); - } - } -} - -static void -suppress_rec_jitter(struct agg_rchinfo *ch) -{ - int cp1, cp2, diff /*, halfsize*/ ; - - /*halfsize = (ch->stereo? ch->buflen >> 2 : ch->buflen >> 1);*/ - cp1 = (ch->stereo? ch->parent->bufsz >> 2 : ch->parent->bufsz >> 1) - + wp_rdapu(ch->parent, 0, APUREG_CURPTR); - cp2 = wp_rdapu(ch->parent, 1, APUREG_CURPTR); - if (cp1 != cp2) { - diff = (cp1 > cp2 ? cp1 - cp2 : cp2 - cp1); - if (diff > 1 /* && diff < halfsize*/ ) - AGG_WR(ch->parent, PORT_DSP_DATA, cp1, 2); - } -} -#endif - -static u_int -calc_timer_div(struct agg_chinfo *ch) -{ - u_int speed; - - speed = ch->speed; -#ifdef INVARIANTS - if (speed == 0) { - printf("snd_maestro: pch[%d].speed == 0, which shouldn't\n", - ch->num); - speed = 1; - } -#endif - return (48000 * (ch->blklen << (!ch->qs16 + !ch->stereo)) - + speed - 1) / speed; -} - -static u_int -calc_timer_div_rch(struct agg_rchinfo *ch) -{ - u_int speed; - - speed = ch->speed; -#ifdef INVARIANTS - if (speed == 0) { - printf("snd_maestro: rch.speed == 0, which shouldn't\n"); - speed = 1; - } -#endif - return (48000 * (ch->blklen << (!ch->stereo)) - + speed - 1) / speed; -} - -static void -set_timer(struct agg_info *ess) -{ - int i; - u_int dv = 32 << 7, newdv; - - for (i = 0; i < ess->playchns; i++) - if ((ess->active & (1 << i)) && - (dv > (newdv = calc_timer_div(ess->pch + i)))) - dv = newdv; - if ((ess->active & (1 << i)) && - (dv > (newdv = calc_timer_div_rch(&ess->rch)))) - dv = newdv; - - wp_settimer(ess, dv); -} - -/* ----------------------------- - * Newpcm glue. - */ - -/* AC97 mixer interface. */ - -static u_int32_t -agg_ac97_init(kobj_t obj, void *sc) -{ - struct agg_info *ess = sc; - - return (AGG_RD(ess, PORT_CODEC_STAT, 1) & CODEC_STAT_MASK)? 0 : 1; -} - -static int -agg_ac97_read(kobj_t obj, void *sc, int regno) -{ - struct agg_info *ess = sc; - int ret; - - /* XXX sound locking violation: agg_lock(ess); */ - ret = agg_rdcodec(ess, regno); - /* agg_unlock(ess); */ - return ret; -} - -static int -agg_ac97_write(kobj_t obj, void *sc, int regno, u_int32_t data) -{ - struct agg_info *ess = sc; - int ret; - - /* XXX sound locking violation: agg_lock(ess); */ - ret = agg_wrcodec(ess, regno, data); - /* agg_unlock(ess); */ - return ret; -} - -static kobj_method_t agg_ac97_methods[] = { - KOBJMETHOD(ac97_init, agg_ac97_init), - KOBJMETHOD(ac97_read, agg_ac97_read), - KOBJMETHOD(ac97_write, agg_ac97_write), - KOBJMETHOD_END -}; -AC97_DECLARE(agg_ac97); - -/* -------------------------------------------------------------------- */ - -/* Playback channel. */ - -static void * -aggpch_init(kobj_t obj, void *devinfo, struct snd_dbuf *b, - struct pcm_channel *c, int dir) -{ - struct agg_info *ess = devinfo; - struct agg_chinfo *ch; - bus_addr_t physaddr; - void *p; - - KASSERT((dir == PCMDIR_PLAY), - ("aggpch_init() called for RECORDING channel!")); - ch = ess->pch + ess->playchns; - - ch->parent = ess; - ch->channel = c; - ch->buffer = b; - ch->num = ess->playchns; - - p = dma_malloc(ess->buf_dmat, ess->bufsz, &physaddr, &ch->map); - if (p == NULL) - return NULL; - ch->phys = physaddr; - ch->base = physaddr & ((~(bus_addr_t)0) << WAVCACHE_BASEADDR_SHIFT); - - sndbuf_setup(b, p, ess->bufsz); - ch->blklen = sndbuf_getblksz(b) / 2; - ch->buflen = sndbuf_getsize(b) / 2; - ess->playchns++; - - return ch; -} - -static void -adjust_pchbase(struct agg_chinfo *chans, u_int n, u_int size) -{ - struct agg_chinfo *pchs[AGG_MAXPLAYCH]; - u_int i, j, k; - bus_addr_t base; - - /* sort pchs by phys address */ - for (i = 0; i < n; i++) { - for (j = 0; j < i; j++) - if (chans[i].phys < pchs[j]->phys) { - for (k = i; k > j; k--) - pchs[k] = pchs[k - 1]; - break; - } - pchs[j] = chans + i; - } - - /* use new base register if next buffer can not be addressed - via current base. */ -#define BASE_SHIFT (WPWA_WTBAR_SHIFT(2) + 2 + 1) - base = pchs[0]->base; - for (k = 1, i = 1; i < n; i++) { - if (pchs[i]->phys + size - base >= 1 << BASE_SHIFT) - /* not addressable: assign new base */ - base = (pchs[i]->base -= k++ << BASE_SHIFT); - else - pchs[i]->base = base; - } -#undef BASE_SHIFT - - if (bootverbose) { - printf("Total of %d bases are assigned.\n", k); - for (i = 0; i < n; i++) { - printf("ch.%d: phys 0x%llx, wpwa 0x%llx\n", - i, (long long)chans[i].phys, - (long long)(chans[i].phys - - chans[i].base) >> 1); - } - } -} - -static int -aggpch_free(kobj_t obj, void *data) -{ - struct agg_chinfo *ch = data; - struct agg_info *ess = ch->parent; - - /* free up buffer - called after channel stopped */ - dma_free(ess->buf_dmat, sndbuf_getbuf(ch->buffer), ch->map); - - /* return 0 if ok */ - return 0; -} - -static int -aggpch_setformat(kobj_t obj, void *data, u_int32_t format) -{ - struct agg_chinfo *ch = data; - - if (format & AFMT_BIGENDIAN || format & AFMT_U16_LE) - return EINVAL; - ch->stereo = ch->qs16 = ch->us = 0; - if (AFMT_CHANNEL(format) > 1) - ch->stereo = 1; - - if (format & AFMT_U8 || format & AFMT_S8) { - if (format & AFMT_U8) - ch->us = 1; - } else - ch->qs16 = 1; - return 0; -} - -static u_int32_t -aggpch_setspeed(kobj_t obj, void *data, u_int32_t speed) -{ - - ((struct agg_chinfo*)data)->speed = speed; - - return (speed); -} - -static u_int32_t -aggpch_setblocksize(kobj_t obj, void *data, u_int32_t blocksize) -{ - struct agg_chinfo *ch = data; - int blkcnt; - - /* try to keep at least 20msec DMA space */ - blkcnt = (ch->speed << (ch->stereo + ch->qs16)) / (50 * blocksize); - RANGE(blkcnt, 2, ch->parent->bufsz / blocksize); - - if (sndbuf_getsize(ch->buffer) != blkcnt * blocksize) { - sndbuf_resize(ch->buffer, blkcnt, blocksize); - blkcnt = sndbuf_getblkcnt(ch->buffer); - blocksize = sndbuf_getblksz(ch->buffer); - } else { - sndbuf_setblkcnt(ch->buffer, blkcnt); - sndbuf_setblksz(ch->buffer, blocksize); - } - - ch->blklen = blocksize / 2; - ch->buflen = blkcnt * blocksize / 2; - return blocksize; -} - -static int -aggpch_trigger(kobj_t obj, void *data, int go) -{ - struct agg_chinfo *ch = data; - - switch (go) { - case PCMTRIG_EMLDMAWR: - break; - case PCMTRIG_START: - aggch_start_dac(ch); - break; - case PCMTRIG_ABORT: - case PCMTRIG_STOP: - aggch_stop_dac(ch); - break; - } - return 0; -} - -static u_int32_t -aggpch_getptr(kobj_t obj, void *data) -{ - struct agg_chinfo *ch = data; - u_int32_t cp; - - agg_lock(ch->parent); - cp = wp_rdapu(ch->parent, (ch->num << 1) | 32, APUREG_CURPTR); - agg_unlock(ch->parent); - - return ch->qs16 && ch->stereo - ? (cp << 2) - ((0xffff << 2) & (ch->phys - ch->base)) - : (cp << 1) - ((0xffff << 1) & (ch->phys - ch->base)); -} - -static struct pcmchan_caps * -aggpch_getcaps(kobj_t obj, void *data) -{ - static u_int32_t playfmt[] = { - SND_FORMAT(AFMT_U8, 1, 0), - SND_FORMAT(AFMT_U8, 2, 0), - SND_FORMAT(AFMT_S8, 1, 0), - SND_FORMAT(AFMT_S8, 2, 0), - SND_FORMAT(AFMT_S16_LE, 1, 0), - SND_FORMAT(AFMT_S16_LE, 2, 0), - 0 - }; - static struct pcmchan_caps playcaps = {8000, 48000, playfmt, 0}; - - return &playcaps; -} - -static kobj_method_t aggpch_methods[] = { - KOBJMETHOD(channel_init, aggpch_init), - KOBJMETHOD(channel_free, aggpch_free), - KOBJMETHOD(channel_setformat, aggpch_setformat), - KOBJMETHOD(channel_setspeed, aggpch_setspeed), - KOBJMETHOD(channel_setblocksize, aggpch_setblocksize), - KOBJMETHOD(channel_trigger, aggpch_trigger), - KOBJMETHOD(channel_getptr, aggpch_getptr), - KOBJMETHOD(channel_getcaps, aggpch_getcaps), - KOBJMETHOD_END -}; -CHANNEL_DECLARE(aggpch); - -/* -------------------------------------------------------------------- */ - -/* Recording channel. */ - -static void * -aggrch_init(kobj_t obj, void *devinfo, struct snd_dbuf *b, - struct pcm_channel *c, int dir) -{ - struct agg_info *ess = devinfo; - struct agg_rchinfo *ch; - u_int8_t *p; - - KASSERT((dir == PCMDIR_REC), - ("aggrch_init() called for PLAYBACK channel!")); - ch = &ess->rch; - - ch->parent = ess; - ch->channel = c; - ch->buffer = b; - - /* Uses the bottom-half of the status buffer. */ - p = ess->stat + ess->bufsz; - ch->phys = ess->phys + ess->bufsz; - ch->base = ess->phys; - ch->src = (int16_t *)(p + ess->bufsz); - ch->srcphys = ch->phys + ess->bufsz; - ch->sink = (int16_t *)p; - - sndbuf_setup(b, p, ess->bufsz); - ch->blklen = sndbuf_getblksz(b) / 2; - ch->buflen = sndbuf_getsize(b) / 2; - - return ch; -} - -static int -aggrch_setformat(kobj_t obj, void *data, u_int32_t format) -{ - struct agg_rchinfo *ch = data; - - if (!(format & AFMT_S16_LE)) - return EINVAL; - if (AFMT_CHANNEL(format) > 1) - ch->stereo = 1; - else - ch->stereo = 0; - return 0; -} - -static u_int32_t -aggrch_setspeed(kobj_t obj, void *data, u_int32_t speed) -{ - - ((struct agg_rchinfo*)data)->speed = speed; - - return (speed); -} - -static u_int32_t -aggrch_setblocksize(kobj_t obj, void *data, u_int32_t blocksize) -{ - struct agg_rchinfo *ch = data; - int blkcnt; - - /* try to keep at least 20msec DMA space */ - blkcnt = (ch->speed << ch->stereo) / (25 * blocksize); - RANGE(blkcnt, 2, ch->parent->bufsz / blocksize); - - if (sndbuf_getsize(ch->buffer) != blkcnt * blocksize) { - sndbuf_resize(ch->buffer, blkcnt, blocksize); - blkcnt = sndbuf_getblkcnt(ch->buffer); - blocksize = sndbuf_getblksz(ch->buffer); - } else { - sndbuf_setblkcnt(ch->buffer, blkcnt); - sndbuf_setblksz(ch->buffer, blocksize); - } - - ch->blklen = blocksize / 2; - ch->buflen = blkcnt * blocksize / 2; - return blocksize; -} - -static int -aggrch_trigger(kobj_t obj, void *sc, int go) -{ - struct agg_rchinfo *ch = sc; - - switch (go) { - case PCMTRIG_EMLDMARD: - if (ch->stereo) - aggch_feed_adc_stereo(ch); - else - aggch_feed_adc_mono(ch); - break; - case PCMTRIG_START: - aggch_start_adc(ch); - break; - case PCMTRIG_ABORT: - case PCMTRIG_STOP: - aggch_stop_adc(ch); - break; - } - return 0; -} - -static u_int32_t -aggrch_getptr(kobj_t obj, void *sc) -{ - struct agg_rchinfo *ch = sc; - - return ch->stereo? ch->hwptr << 2 : ch->hwptr << 1; -} - -static struct pcmchan_caps * -aggrch_getcaps(kobj_t obj, void *sc) -{ - static u_int32_t recfmt[] = { - SND_FORMAT(AFMT_S16_LE, 1, 0), - SND_FORMAT(AFMT_S16_LE, 2, 0), - 0 - }; - static struct pcmchan_caps reccaps = {8000, 48000, recfmt, 0}; - - return &reccaps; -} - -static kobj_method_t aggrch_methods[] = { - KOBJMETHOD(channel_init, aggrch_init), - /* channel_free: no-op */ - KOBJMETHOD(channel_setformat, aggrch_setformat), - KOBJMETHOD(channel_setspeed, aggrch_setspeed), - KOBJMETHOD(channel_setblocksize, aggrch_setblocksize), - KOBJMETHOD(channel_trigger, aggrch_trigger), - KOBJMETHOD(channel_getptr, aggrch_getptr), - KOBJMETHOD(channel_getcaps, aggrch_getcaps), - KOBJMETHOD_END -}; -CHANNEL_DECLARE(aggrch); - -/* ----------------------------- - * Bus space. - */ - -static void -agg_intr(void *sc) -{ - struct agg_info* ess = sc; - register u_int8_t status; - int i; - u_int m; - - status = AGG_RD(ess, PORT_HOSTINT_STAT, 1); - if (!status) - return; - - /* Acknowledge intr. */ - AGG_WR(ess, PORT_HOSTINT_STAT, status, 1); - - if (status & HOSTINT_STAT_DSOUND) { -#ifdef AGG_JITTER_CORRECTION - agg_lock(ess); -#endif - if (ess->curpwr <= PCI_POWERSTATE_D1) { - AGG_WR(ess, PORT_INT_STAT, 1, 2); -#ifdef AGG_JITTER_CORRECTION - for (i = 0, m = 1; i < ess->playchns; i++, m <<= 1) { - if (ess->active & m) - suppress_jitter(ess->pch + i); - } - if (ess->active & m) - suppress_rec_jitter(&ess->rch); - agg_unlock(ess); -#endif - for (i = 0, m = 1; i < ess->playchns; i++, m <<= 1) { - if (ess->active & m) { - if (ess->curpwr <= PCI_POWERSTATE_D1) - chn_intr(ess->pch[i].channel); - else { - m = 0; - break; - } - } - } - if ((ess->active & m) - && ess->curpwr <= PCI_POWERSTATE_D1) - chn_intr(ess->rch.channel); - } -#ifdef AGG_JITTER_CORRECTION - else - agg_unlock(ess); -#endif - } - - if (status & HOSTINT_STAT_HWVOL) { - register u_int8_t event; - - agg_lock(ess); - event = AGG_RD(ess, PORT_HWVOL_MASTER, 1); - AGG_WR(ess, PORT_HWVOL_MASTER, HWVOL_NOP, 1); - agg_unlock(ess); - - switch (event) { - case HWVOL_UP: - mixer_hwvol_step(ess->dev, 1, 1); - break; - case HWVOL_DOWN: - mixer_hwvol_step(ess->dev, -1, -1); - break; - case HWVOL_NOP: - break; - default: - if (event & HWVOL_MUTE) { - mixer_hwvol_mute(ess->dev); - break; - } - device_printf(ess->dev, - "%s: unknown HWVOL event 0x%x\n", - device_get_nameunit(ess->dev), event); - } - } -} - -static void -setmap(void *arg, bus_dma_segment_t *segs, int nseg, int error) -{ - bus_addr_t *phys = arg; - - *phys = error? 0 : segs->ds_addr; - - if (bootverbose) { - printf("setmap (%lx, %lx), nseg=%d, error=%d\n", - (unsigned long)segs->ds_addr, (unsigned long)segs->ds_len, - nseg, error); - } -} - -static void * -dma_malloc(bus_dma_tag_t dmat, u_int32_t sz, bus_addr_t *phys, - bus_dmamap_t *map) -{ - void *buf; - - if (bus_dmamem_alloc(dmat, &buf, BUS_DMA_NOWAIT, map)) - return NULL; - if (bus_dmamap_load(dmat, *map, buf, sz, setmap, phys, - BUS_DMA_NOWAIT) != 0 || *phys == 0) { - bus_dmamem_free(dmat, buf, *map); - return NULL; - } - return buf; -} - -static void -dma_free(bus_dma_tag_t dmat, void *buf, bus_dmamap_t map) -{ - bus_dmamap_unload(dmat, map); - bus_dmamem_free(dmat, buf, map); -} - -static int -agg_probe(device_t dev) -{ - char *s = NULL; - - switch (pci_get_devid(dev)) { - case MAESTRO_1_PCI_ID: - s = "ESS Technology Maestro-1"; - break; - - case MAESTRO_2_PCI_ID: - s = "ESS Technology Maestro-2"; - break; - - case MAESTRO_2E_PCI_ID: - s = "ESS Technology Maestro-2E"; - break; - } - - if (s != NULL && pci_get_class(dev) == PCIC_MULTIMEDIA) { - device_set_desc(dev, s); - return BUS_PROBE_DEFAULT; - } - return ENXIO; -} - -static int -agg_attach(device_t dev) -{ - struct agg_info *ess = NULL; - u_int32_t data; - int regid = PCIR_BAR(0); - struct resource *reg = NULL; - struct ac97_info *codec = NULL; - int irqid = 0; - struct resource *irq = NULL; - void *ih = NULL; - char status[SND_STATUSLEN]; - int dacn, ret = 0; - - ess = malloc(sizeof(*ess), M_DEVBUF, M_WAITOK | M_ZERO); - ess->dev = dev; - - mtx_init(&ess->lock, device_get_desc(dev), "snd_maestro softc", - MTX_DEF | MTX_RECURSE); - - if (resource_int_value(device_get_name(dev), device_get_unit(dev), - "dac", &dacn) == 0) { - if (dacn < 1) - dacn = 1; - else if (dacn > AGG_MAXPLAYCH) - dacn = AGG_MAXPLAYCH; - } else - dacn = AGG_MAXPLAYCH; - - ess->bufsz = pcm_getbuffersize(dev, 4096, AGG_DEFAULT_BUFSZ, 65536); - if (bus_dma_tag_create(/*parent*/ bus_get_dma_tag(dev), - /*align */ 4, 1 << (16+1), - /*limit */ MAESTRO_MAXADDR, BUS_SPACE_MAXADDR, - /*filter*/ NULL, NULL, - /*size */ ess->bufsz, 1, 0x3ffff, - /*flags */ 0, - /*lock */ NULL, NULL, - &ess->buf_dmat) != 0) { - device_printf(dev, "unable to create dma tag\n"); - ret = ENOMEM; - goto bad; - } - - if (bus_dma_tag_create(/*parent*/ bus_get_dma_tag(dev), - /*align */ 1 << WAVCACHE_BASEADDR_SHIFT, - 1 << (16+1), - /*limit */ MAESTRO_MAXADDR, BUS_SPACE_MAXADDR, - /*filter*/ NULL, NULL, - /*size */ 3*ess->bufsz, 1, 0x3ffff, - /*flags */ 0, - /*lock */ NULL, NULL, - &ess->stat_dmat) != 0) { - device_printf(dev, "unable to create dma tag\n"); - ret = ENOMEM; - goto bad; - } - - /* Allocate the room for brain-damaging status buffer. */ - ess->stat = dma_malloc(ess->stat_dmat, 3*ess->bufsz, &ess->phys, - &ess->stat_map); - if (ess->stat == NULL) { - device_printf(dev, "cannot allocate status buffer\n"); - ret = ENOMEM; - goto bad; - } - if (bootverbose) - device_printf(dev, "Maestro status/record buffer: %#llx\n", - (long long)ess->phys); - - /* State D0-uninitialized. */ - ess->curpwr = PCI_POWERSTATE_D3; - pci_set_powerstate(dev, PCI_POWERSTATE_D0); - - pci_enable_busmaster(dev); - - /* Allocate resources. */ - reg = bus_alloc_resource_any(dev, SYS_RES_IOPORT, ®id, RF_ACTIVE); - if (reg != NULL) { - ess->reg = reg; - ess->regid = regid; - ess->st = rman_get_bustag(reg); - ess->sh = rman_get_bushandle(reg); - } else { - device_printf(dev, "unable to map register space\n"); - ret = ENXIO; - goto bad; - } - irq = bus_alloc_resource_any(dev, SYS_RES_IRQ, &irqid, - RF_ACTIVE | RF_SHAREABLE); - if (irq != NULL) { - ess->irq = irq; - ess->irqid = irqid; - } else { - device_printf(dev, "unable to map interrupt\n"); - ret = ENXIO; - goto bad; - } - - /* Setup resources. */ - if (snd_setup_intr(dev, irq, INTR_MPSAFE, agg_intr, ess, &ih)) { - device_printf(dev, "unable to setup interrupt\n"); - ret = ENXIO; - goto bad; - } else - ess->ih = ih; - - /* Transition from D0-uninitialized to D0. */ - agg_lock(ess); - agg_power(ess, PCI_POWERSTATE_D0); - if (agg_rdcodec(ess, 0) == 0x80) { - /* XXX - TODO: PT101 */ - agg_unlock(ess); - device_printf(dev, "PT101 codec detected!\n"); - ret = ENXIO; - goto bad; - } - agg_unlock(ess); - codec = AC97_CREATE(dev, ess, agg_ac97); - if (codec == NULL) { - device_printf(dev, "failed to create AC97 codec softc!\n"); - ret = ENOMEM; - goto bad; - } - if (mixer_init(dev, ac97_getmixerclass(), codec) == -1) { - device_printf(dev, "mixer initialization failed!\n"); - ret = ENXIO; - goto bad; - } - ess->codec = codec; - - ret = pcm_register(dev, ess, dacn, 1); - if (ret) - goto bad; - - mixer_hwvol_init(dev); - agg_lock(ess); - agg_power(ess, powerstate_init); - agg_unlock(ess); - for (data = 0; data < dacn; data++) - pcm_addchan(dev, PCMDIR_PLAY, &aggpch_class, ess); - pcm_addchan(dev, PCMDIR_REC, &aggrch_class, ess); - adjust_pchbase(ess->pch, ess->playchns, ess->bufsz); - - snprintf(status, SND_STATUSLEN, - "port 0x%jx-0x%jx irq %jd at device %d.%d on pci%d", - rman_get_start(reg), rman_get_end(reg), rman_get_start(irq), - pci_get_slot(dev), pci_get_function(dev), pci_get_bus(dev)); - pcm_setstatus(dev, status); - - return 0; - - bad: - if (codec != NULL) - ac97_destroy(codec); - if (ih != NULL) - bus_teardown_intr(dev, irq, ih); - if (irq != NULL) - bus_release_resource(dev, SYS_RES_IRQ, irqid, irq); - if (reg != NULL) - bus_release_resource(dev, SYS_RES_IOPORT, regid, reg); - if (ess != NULL) { - if (ess->stat != NULL) - dma_free(ess->stat_dmat, ess->stat, ess->stat_map); - if (ess->stat_dmat != NULL) - bus_dma_tag_destroy(ess->stat_dmat); - if (ess->buf_dmat != NULL) - bus_dma_tag_destroy(ess->buf_dmat); - mtx_destroy(&ess->lock); - free(ess, M_DEVBUF); - } - - return ret; -} - -static int -agg_detach(device_t dev) -{ - struct agg_info *ess = pcm_getdevinfo(dev); - int r; - u_int16_t icr; - - icr = AGG_RD(ess, PORT_HOSTINT_CTRL, 2); - AGG_WR(ess, PORT_HOSTINT_CTRL, 0, 2); - - agg_lock(ess); - if (ess->active) { - AGG_WR(ess, PORT_HOSTINT_CTRL, icr, 2); - agg_unlock(ess); - return EBUSY; - } - agg_unlock(ess); - - r = pcm_unregister(dev); - if (r) { - AGG_WR(ess, PORT_HOSTINT_CTRL, icr, 2); - return r; - } - - agg_lock(ess); - agg_power(ess, PCI_POWERSTATE_D3); - agg_unlock(ess); - - bus_teardown_intr(dev, ess->irq, ess->ih); - bus_release_resource(dev, SYS_RES_IRQ, ess->irqid, ess->irq); - bus_release_resource(dev, SYS_RES_IOPORT, ess->regid, ess->reg); - dma_free(ess->stat_dmat, ess->stat, ess->stat_map); - bus_dma_tag_destroy(ess->stat_dmat); - bus_dma_tag_destroy(ess->buf_dmat); - mtx_destroy(&ess->lock); - free(ess, M_DEVBUF); - return 0; -} - -static int -agg_suspend(device_t dev) -{ - struct agg_info *ess = pcm_getdevinfo(dev); - - AGG_WR(ess, PORT_HOSTINT_CTRL, 0, 2); - agg_lock(ess); - agg_power(ess, PCI_POWERSTATE_D3); - agg_unlock(ess); - - return 0; -} - -static int -agg_resume(device_t dev) -{ - int i; - struct agg_info *ess = pcm_getdevinfo(dev); - - for (i = 0; i < ess->playchns; i++) - if (ess->active & (1 << i)) - aggch_start_dac(ess->pch + i); - if (ess->active & (1 << i)) - aggch_start_adc(&ess->rch); - - agg_lock(ess); - if (!ess->active) - agg_power(ess, powerstate_init); - agg_unlock(ess); - - if (mixer_reinit(dev)) { - device_printf(dev, "unable to reinitialize the mixer\n"); - return ENXIO; - } - - return 0; -} - -static int -agg_shutdown(device_t dev) -{ - struct agg_info *ess = pcm_getdevinfo(dev); - - agg_lock(ess); - agg_power(ess, PCI_POWERSTATE_D3); - agg_unlock(ess); - - return 0; -} - -static device_method_t agg_methods[] = { - DEVMETHOD(device_probe, agg_probe), - DEVMETHOD(device_attach, agg_attach), - DEVMETHOD(device_detach, agg_detach), - DEVMETHOD(device_suspend, agg_suspend), - DEVMETHOD(device_resume, agg_resume), - DEVMETHOD(device_shutdown, agg_shutdown), - { 0, 0 } -}; - -static driver_t agg_driver = { - "pcm", - agg_methods, - PCM_SOFTC_SIZE, -}; - -/*static devclass_t pcm_devclass;*/ - -DRIVER_MODULE(snd_maestro, pci, agg_driver, pcm_devclass, 0, 0); -MODULE_DEPEND(snd_maestro, sound, SOUND_MINVER, SOUND_PREFVER, SOUND_MAXVER); -MODULE_VERSION(snd_maestro, 1); diff --git a/sys/dev/sound/pci/maestro_reg.h b/sys/dev/sound/pci/maestro_reg.h deleted file mode 100644 index 5ec691ca8e8b..000000000000 --- a/sys/dev/sound/pci/maestro_reg.h +++ /dev/null @@ -1,382 +0,0 @@ -/*- - * SPDX-License-Identifier: BSD-2-Clause-FreeBSD - * - * Copyright (c) 1999-2000 Taku YAMAMOTO <taku@cent.saitama-u.ac.jp> - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * maestro_reg.h,v 1.13 2001/11/11 18:29:46 taku Exp - * $FreeBSD$ - */ - -#ifndef MAESTRO_REG_H_INCLUDED -#define MAESTRO_REG_H_INCLUDED - -/* ----------------------------- - * PCI config registers - */ - -/* Legacy emulation */ -#define CONF_LEGACY 0x40 - -#define LEGACY_DISABLED 0x8000 - -/* Chip configurations */ -#define CONF_MAESTRO 0x50 -#define MAESTRO_PMC 0x08000000 -#define MAESTRO_SPDIF 0x01000000 -#define MAESTRO_HWVOL 0x00800000 -#define MAESTRO_CHIBUS 0x00100000 -#define MAESTRO_POSTEDWRITE 0x00000080 -#define MAESTRO_DMA_PCITIMING 0x00000040 -#define MAESTRO_SWAP_LR 0x00000020 - -/* ACPI configurations */ -#define CONF_ACPI_STOPCLOCK 0x54 -#define ACPI_PART_2ndC_CLOCK 15 -#define ACPI_PART_CODEC_CLOCK 14 -#define ACPI_PART_978 13 /* Docking station or something */ -#define ACPI_PART_SPDIF 12 -#define ACPI_PART_GLUE 11 /* What? */ -#define ACPI_PART_DAA 10 -#define ACPI_PART_PCI_IF 9 -#define ACPI_PART_HW_VOL 8 -#define ACPI_PART_GPIO 7 -#define ACPI_PART_ASSP 6 -#define ACPI_PART_SB 5 -#define ACPI_PART_FM 4 -#define ACPI_PART_RINGBUS 3 -#define ACPI_PART_MIDI 2 -#define ACPI_PART_GAME_PORT 1 -#define ACPI_PART_WP 0 - -/* Power management */ -#define CONF_PM_PTR 0x34 /* BYTE R */ -#define PM_CID 0 /* BYTE R */ -#define PPMI_CID 1 -#define PM_CTRL 4 /* BYTE RW */ -#define PPMI_D0 0 /* Full power */ -#define PPMI_D1 1 /* Medium power */ -#define PPMI_D2 2 /* Low power */ -#define PPMI_D3 3 /* Turned off */ - -/* ----------------------------- - * I/O ports - */ - -/* Direct Sound Processor (aka WP) */ -#define PORT_DSP_DATA 0x00 /* WORD RW */ -#define PORT_DSP_INDEX 0x02 /* WORD RW */ -#define PORT_INT_STAT 0x04 /* WORD RW */ -#define PORT_SAMPLE_CNT 0x06 /* WORD RO */ - -/* WaveCache */ -#define PORT_WAVCACHE_INDEX 0x10 /* WORD RW */ -#define PORT_WAVCACHE_DATA 0x12 /* WORD RW */ -#define WAVCACHE_PCMBAR 0x1fc -#define WAVCACHE_WTBAR 0x1f0 -#define WAVCACHE_BASEADDR_SHIFT 12 - -#define WAVCACHE_CHCTL_ADDRTAG_MASK 0xfff8 -#define WAVCACHE_CHCTL_U8 0x0004 -#define WAVCACHE_CHCTL_STEREO 0x0002 -#define WAVCACHE_CHCTL_DECREMENTAL 0x0001 - -#define PORT_WAVCACHE_CTRL 0x14 /* WORD RW */ -#define WAVCACHE_EXTRA_CH_ENABLED 0x0200 -#define WAVCACHE_ENABLED 0x0100 -#define WAVCACHE_CH_60_ENABLED 0x0080 -#define WAVCACHE_WTSIZE_MASK 0x0060 -#define WAVCACHE_WTSIZE_1MB 0x0000 -#define WAVCACHE_WTSIZE_2MB 0x0020 -#define WAVCACHE_WTSIZE_4MB 0x0040 -#define WAVCACHE_WTSIZE_8MB 0x0060 -#define WAVCACHE_SGC_MASK 0x000c -#define WAVCACHE_SGC_DISABLED 0x0000 -#define WAVCACHE_SGC_40_47 0x0004 -#define WAVCACHE_SGC_32_47 0x0008 -#define WAVCACHE_TESTMODE 0x0001 - -/* Host Interruption */ -#define PORT_HOSTINT_CTRL 0x18 /* WORD RW */ -#define HOSTINT_CTRL_SOFT_RESET 0x8000 -#define HOSTINT_CTRL_DSOUND_RESET 0x4000 -#define HOSTINT_CTRL_HW_VOL_TO_PME 0x0400 -#define HOSTINT_CTRL_CLKRUN_ENABLED 0x0100 -#define HOSTINT_CTRL_HWVOL_ENABLED 0x0040 -#define HOSTINT_CTRL_ASSP_INT_ENABLED 0x0010 -#define HOSTINT_CTRL_ISDN_INT_ENABLED 0x0008 -#define HOSTINT_CTRL_DSOUND_INT_ENABLED 0x0004 -#define HOSTINT_CTRL_MPU401_INT_ENABLED 0x0002 -#define HOSTINT_CTRL_SB_INT_ENABLED 0x0001 - -#define PORT_HOSTINT_STAT 0x1a /* BYTE RW */ -#define HOSTINT_STAT_HWVOL 0x40 -#define HOSTINT_STAT_ASSP 0x10 -#define HOSTINT_STAT_ISDN 0x08 -#define HOSTINT_STAT_DSOUND 0x04 -#define HOSTINT_STAT_MPU401 0x02 -#define HOSTINT_STAT_SB 0x01 - -/* Hardware volume */ -#define PORT_HWVOL_CTRL 0x1b /* BYTE RW */ -#define HWVOL_CTRL_SPLIT_SHADOW 0x01 - -#define PORT_HWVOL_VOICE_SHADOW 0x1c /* BYTE RW */ -#define PORT_HWVOL_VOICE 0x1d /* BYTE RW */ -#define PORT_HWVOL_MASTER_SHADOW 0x1e /* BYTE RW */ -#define PORT_HWVOL_MASTER 0x1f /* BYTE RW */ -#define HWVOL_NOP 0x88 -#define HWVOL_MUTE 0x11 -#define HWVOL_UP 0xaa -#define HWVOL_DOWN 0x66 - -/* CODEC */ -#define PORT_CODEC_CMD 0x30 /* BYTE W */ -#define CODEC_CMD_READ 0x80 -#define CODEC_CMD_WRITE 0x00 -#define CODEC_CMD_ADDR_MASK 0x7f - -#define PORT_CODEC_STAT 0x30 /* BYTE R */ -#define CODEC_STAT_MASK 0x01 -#define CODEC_STAT_RW_DONE 0x00 -#define CODEC_STAT_PROGLESS 0x01 - -#define PORT_CODEC_REG 0x32 /* WORD RW */ - -/* Ring bus control */ -#define PORT_RINGBUS_CTRL 0x34 /* DWORD RW */ -#define RINGBUS_CTRL_I2S_ENABLED 0x80000000 -#define RINGBUS_CTRL_RINGBUS_ENABLED 0x20000000 -#define RINGBUS_CTRL_ACLINK_ENABLED 0x10000000 -#define RINGBUS_CTRL_AC97_SWRESET 0x08000000 - -#define RINGBUS_SRC_MIC 20 -#define RINGBUS_SRC_I2S 16 -#define RINGBUS_SRC_ADC 12 -#define RINGBUS_SRC_MODEM 8 -#define RINGBUS_SRC_DSOUND 4 -#define RINGBUS_SRC_ASSP 0 - -#define RINGBUS_DEST_MONORAL 000 -#define RINGBUS_DEST_STEREO 010 -#define RINGBUS_DEST_NONE 0 -#define RINGBUS_DEST_DAC 1 -#define RINGBUS_DEST_MODEM_IN 2 -#define RINGBUS_DEST_RESERVED3 3 -#define RINGBUS_DEST_DSOUND_IN 4 -#define RINGBUS_DEST_ASSP_IN 5 - -/* Ring bus control B */ -#define PORT_RINGBUS_CTRL_B 0x38 /* BYTE RW */ -#define RINGBUS_CTRL_SSPE 0x40 -#define RINGBUS_CTRL_2ndCODEC 0x20 -#define RINGBUS_CTRL_SPDIF 0x10 -#define RINGBUS_CTRL_ITB_DISABLE 0x08 -#define RINGBUS_CTRL_CODEC_ID_MASK 0x03 -#define RINGBUS_CTRL_CODEC_ID_AC98 2 - -/* General Purpose I/O */ -#define PORT_GPIO_DATA 0x60 /* WORD RW */ -#define PORT_GPIO_MASK 0x64 /* WORD RW */ -#define PORT_GPIO_DIR 0x68 /* WORD RW */ - -/* Application Specific Signal Processor */ -#define PORT_ASSP_MEM_INDEX 0x80 /* DWORD RW */ -#define PORT_ASSP_MEM_DATA 0x84 /* WORD RW */ -#define PORT_ASSP_CTRL_A 0xa2 /* BYTE RW */ -#define PORT_ASSP_CTRL_B 0xa4 /* BYTE RW */ -#define PORT_ASSP_CTRL_C 0xa6 /* BYTE RW */ -#define PORT_ASSP_HOST_WR_INDEX 0xa8 /* BYTE W */ -#define PORT_ASSP_HOST_WR_DATA 0xaa /* BYTE RW */ -#define PORT_ASSP_INT_STAT 0xac /* BYTE RW */ - -/* ----------------------------- - * Wave Processor Indexed Data Registers. - */ - -#define WPREG_DATA_PORT 0 -#define WPREG_CRAM_PTR 1 -#define WPREG_CRAM_DATA 2 -#define WPREG_WAVE_DATA 3 -#define WPREG_WAVE_PTR_LOW 4 -#define WPREG_WAVE_PTR_HIGH 5 - -#define WPREG_TIMER_FREQ 6 -#define WP_TIMER_FREQ_PRESCALE_MASK 0x00e0 /* actual - 9 */ -#define WP_TIMER_FREQ_PRESCALE_SHIFT 5 -#define WP_TIMER_FREQ_DIVIDE_MASK 0x001f -#define WP_TIMER_FREQ_DIVIDE_SHIFT 0 - -#define WPREG_WAVE_ROMRAM 7 -#define WP_WAVE_VIRTUAL_ENABLED 0x0400 -#define WP_WAVE_8BITRAM_ENABLED 0x0200 -#define WP_WAVE_DRAM_ENABLED 0x0100 -#define WP_WAVE_RAMSPLIT_MASK 0x00ff -#define WP_WAVE_RAMSPLIT_SHIFT 0 - -#define WPREG_BASE 12 -#define WP_PARAOUT_BASE_MASK 0xf000 -#define WP_PARAOUT_BASE_SHIFT 12 -#define WP_PARAIN_BASE_MASK 0x0f00 -#define WP_PARAIN_BASE_SHIFT 8 -#define WP_SERIAL0_BASE_MASK 0x00f0 -#define WP_SERIAL0_BASE_SHIFT 4 -#define WP_SERIAL1_BASE_MASK 0x000f -#define WP_SERIAL1_BASE_SHIFT 0 - -#define WPREG_TIMER_ENABLE 17 -#define WPREG_TIMER_START 23 - -/* ----------------------------- - * Audio Processing Unit. - */ -#define APUREG_APUTYPE 0 -#define APU_DMA_ENABLED 0x4000 -#define APU_INT_ON_LOOP 0x2000 -#define APU_ENDCURVE 0x1000 -#define APU_APUTYPE_MASK 0x00f0 -#define APU_FILTERTYPE_MASK 0x000c -#define APU_FILTERQ_MASK 0x0003 - -/* APU types */ -#define APU_APUTYPE_SHIFT 4 - -#define APUTYPE_INACTIVE 0 -#define APUTYPE_16BITLINEAR 1 -#define APUTYPE_16BITSTEREO 2 -#define APUTYPE_8BITLINEAR 3 -#define APUTYPE_8BITSTEREO 4 -#define APUTYPE_8BITDIFF 5 -#define APUTYPE_DIGITALDELAY 6 -#define APUTYPE_DUALTAP_READER 7 -#define APUTYPE_CORRELATOR 8 -#define APUTYPE_INPUTMIXER 9 -#define APUTYPE_WAVETABLE 10 -#define APUTYPE_RATECONV 11 -#define APUTYPE_16BITPINGPONG 12 -/* APU type 13 through 15 are reserved. */ - -/* Filter types */ -#define APU_FILTERTYPE_SHIFT 2 - -#define FILTERTYPE_2POLE_LOPASS 0 -#define FILTERTYPE_2POLE_BANDPASS 1 -#define FILTERTYPE_2POLE_HIPASS 2 -#define FILTERTYPE_1POLE_LOPASS 3 -#define FILTERTYPE_1POLE_HIPASS 4 -#define FILTERTYPE_PASSTHROUGH 5 - -/* Filter Q */ -#define APU_FILTERQ_SHIFT 0 - -#define FILTERQ_LESSQ 0 -#define FILTERQ_MOREQ 3 - -/* APU register 2 */ -#define APUREG_FREQ_LOBYTE 2 -#define APU_FREQ_LOBYTE_MASK 0xff00 -#define APU_plus6dB 0x0010 - -/* APU register 3 */ -#define APUREG_FREQ_HIWORD 3 -#define APU_FREQ_HIWORD_MASK 0x0fff - -/* Frequency */ -#define APU_FREQ_LOBYTE_SHIFT 8 -#define APU_FREQ_HIWORD_SHIFT 0 -#define FREQ_Hz2DIV(freq) (((u_int64_t)(freq) << 16) / 48000) - -/* APU register 4 */ -#define APUREG_WAVESPACE 4 -#define APU_64KPAGE_MASK 0xff00 - -/* 64KW (==128KB) Page */ -#define APU_64KPAGE_SHIFT 8 - -/* Wave Processor Wavespace Address */ -#define WPWA_MAX ((1 << 22) - 1) -#define WPWA_STEREO (1 << 23) -#define WPWA_USE_SYSMEM (1 << 22) - -#define WPWA_WTBAR_SHIFT(wtsz) WPWA_WTBAR_SHIFT_##wtsz -#define WPWA_WTBAR_SHIFT_1 15 -#define WPWA_WTBAR_SHIFT_2 16 -#define WPWA_WTBAR_SHIFT_4 17 -#define WPWA_WTBAR_SHIFT_8 18 - -#define WPWA_PCMBAR_SHIFT 20 - -/* APU register 5 - 7 */ -#define APUREG_CURPTR 5 -#define APUREG_ENDPTR 6 -#define APUREG_LOOPLEN 7 - -/* APU register 8 */ -#define APUREG_EFFECT_GAIN 8 - -/* Effect gain? */ -#define APUREG_EFFECT_GAIN_MASK 0x00ff - -/* APU register 9 */ -#define APUREG_AMPLITUDE 9 -#define APU_AMPLITUDE_NOW_MASK 0xff00 -#define APU_AMPLITUDE_DEST_MASK 0x00ff - -/* Amplitude now? */ -#define APU_AMPLITUDE_NOW_SHIFT 8 - -/* APU register 10 */ -#define APUREG_POSITION 10 -#define APU_RADIUS_MASK 0x00c0 -#define APU_PAN_MASK 0x003f - -/* Radius control. */ -#define APU_RADIUS_SHIFT 6 -#define RADIUS_CENTERCIRCLE 0 -#define RADIUS_MIDDLE 1 -#define RADIUS_OUTSIDE 2 - -/* Polar pan. */ -#define APU_PAN_SHIFT 0 -#define PAN_RIGHT 0x00 -#define PAN_FRONT 0x08 -#define PAN_LEFT 0x10 - -/* Source routing. */ -#define APUREG_ROUTING 11 -#define APU_INVERT_POLARITY_B 0x8000 -#define APU_DATASRC_B_MASK 0x7f00 -#define APU_INVERT_POLARITY_A 0x0080 -#define APU_DATASRC_A_MASK 0x007f - -#define APU_DATASRC_A_SHIFT 0 -#define APU_DATASRC_B_SHIFT 8 - -/* ----------------------------- - * Limits. - */ -#define WPWA_MAXADDR ((1 << 23) - 1) -#define MAESTRO_MAXADDR ((1 << 28) - 1) - -#endif /* MAESTRO_REG_H_INCLUDED */ diff --git a/sys/modules/sound/driver/Makefile b/sys/modules/sound/driver/Makefile index 8c21a719966a..7b461cb09cb6 100644 --- a/sys/modules/sound/driver/Makefile +++ b/sys/modules/sound/driver/Makefile @@ -6,14 +6,13 @@ SYSDIR?=${SRCTOP}/sys # Modules that include binary-only blobs of microcode should be selectable by # MK_SOURCELESS_UCODE option (see below). -SUBDIR= ad1816 als4000 atiixp cs4281 ${_csa} ${_ds1} emu10k1 emu10kx -SUBDIR+= envy24 envy24ht es137x ess fm801 hda hdspe ich maestro +SUBDIR= ad1816 als4000 atiixp cs4281 ${_csa} emu10k1 emu10kx +SUBDIR+= envy24 envy24ht es137x ess fm801 hda hdspe ich SUBDIR+= ${_maestro3} neomagic sb16 sb8 sbc solo spicds t4dwave via8233 SUBDIR+= via82c686 vibes driver uaudio .if ${MK_SOURCELESS_UCODE} != "no" _csa= csa -_ds1= ds1 _maestro3= maestro3 .endif diff --git a/sys/modules/sound/driver/ds1/Makefile b/sys/modules/sound/driver/ds1/Makefile deleted file mode 100644 index 57d57674397d..000000000000 --- a/sys/modules/sound/driver/ds1/Makefile +++ /dev/null @@ -1,9 +0,0 @@ -# $FreeBSD$ - -.PATH: ${SRCTOP}/sys/dev/sound/pci - -KMOD= snd_ds1 -SRCS= device_if.h bus_if.h pci_if.h -SRCS+= ds1.c - -.include <bsd.kmod.mk> diff --git a/sys/modules/sound/driver/maestro/Makefile b/sys/modules/sound/driver/maestro/Makefile deleted file mode 100644 index fe69bd6ce578..000000000000 --- a/sys/modules/sound/driver/maestro/Makefile +++ /dev/null @@ -1,9 +0,0 @@ -# $FreeBSD$ - -.PATH: ${SRCTOP}/sys/dev/sound/pci - -KMOD= snd_maestro -SRCS= device_if.h bus_if.h pci_if.h -SRCS+= maestro.c - -.include <bsd.kmod.mk> |