diff --git a/ObsoleteFiles.inc b/ObsoleteFiles.inc index 1d5ee5863b56..3b906ed221d2 100644 --- a/ObsoleteFiles.inc +++ b/ObsoleteFiles.inc @@ -58,6 +58,9 @@ OLD_FILES+=usr/share/man/man4/snd_ad1816.4 OLD_FILES+=usr/share/man/man4/snd_ess.4 OLD_FILES+=usr/share/man/man4/snd_gusc.4 OLD_FILES+=usr/share/man/man4/snd_mss.4 +OLD_FILES+=usr/share/man/man4/snd_sb16.4 +OLD_FILES+=usr/share/man/man4/snd_sb8.4 +OLD_FILES+=usr/share/man/man4/snd_sbc.4 # 20220612: new clang import which bumps version from 14.0.4 to 14.0.5 OLD_FILES+=usr/lib/clang/14.0.4/include/cuda_wrappers/algorithm diff --git a/share/man/man4/Makefile b/share/man/man4/Makefile index 00304c094987..613e823d4731 100644 --- a/share/man/man4/Makefile +++ b/share/man/man4/Makefile @@ -517,7 +517,6 @@ MAN= aac.4 \ snd_ich.4 \ snd_maestro3.4 \ snd_neomagic.4 \ - snd_sbc.4 \ snd_solo.4 \ snd_spicds.4 \ snd_t4dwave.4 \ @@ -737,8 +736,6 @@ MLINKS+=sk.4 if_sk.4 MLINKS+=smp.4 SMP.4 MLINKS+=smsc.4 if_smsc.4 MLINKS+=snd_envy24.4 snd_ak452x.4 -MLINKS+=snd_sbc.4 snd_sb16.4 \ - snd_sbc.4 snd_sb8.4 MLINKS+=${_spkr.4} ${_speaker.4} MLINKS+=splash.4 screensaver.4 MLINKS+=ste.4 if_ste.4 diff --git a/share/man/man4/pcm.4 b/share/man/man4/pcm.4 index b1ad16eece37..b4f55443f95c 100644 --- a/share/man/man4/pcm.4 +++ b/share/man/man4/pcm.4 @@ -111,12 +111,6 @@ The following bridge device drivers are available: .It .Xr snd_neomagic 4 .It -snd_sb16 -.It -snd_sb8 -.It -.Xr snd_sbc 4 -.It .Xr snd_solo 4 .It .Xr snd_spicds 4 @@ -708,7 +702,6 @@ A device node is not created properly. .Xr snd_ich 4 , .Xr snd_maestro3 4 , .Xr snd_neomagic 4 , -.Xr snd_sbc 4 , .Xr snd_solo 4 , .Xr snd_spicds 4 , .Xr snd_t4dwave 4 , diff --git a/share/man/man4/snd_sbc.4 b/share/man/man4/snd_sbc.4 deleted file mode 100644 index e15d23081fb7..000000000000 --- a/share/man/man4/snd_sbc.4 +++ /dev/null @@ -1,135 +0,0 @@ -.\" -.\" Copyright (c) 1999 Seigo Tanimura -.\" 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 19, 2022 -.Dt SND_SBC 4 -.Os -.Sh NAME -.Nm snd_sbc , -.Nm snd_sb16 , -.Nm snd_sb8 -.Nd Creative Sound Blaster ISA and compatible bridge device driver -.Sh DEPRECATION NOTICE -This driver is scheduled for removal prior to the release of -.Fx 14.0 . -.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_sbc" -.Cd "device snd_sb16" -.Cd "device snd_sb8" -.Ed -.Pp -Alternatively, to load the driver as a module at boot time, place the -following lines in -.Xr loader.conf 5 : -.Bd -literal -offset indent -snd_sbc_load="YES" -snd_sb16_load="YES" -snd_sb8_load="YES" -.Ed -.Pp -Non-PnP cards require the following lines in -.Xr device.hints 5 : -.Bd -literal -offset indent -hint.sbc.0.at="isa" -hint.sbc.0.port="0x220" -hint.sbc.0.irq="5" -hint.sbc.0.drq="1" -hint.sbc.0.flags="0x15" -.Ed -.Sh DESCRIPTION -The -.Nm -bridge driver allows the generic audio driver -.Xr sound 4 -to attach to Creative Sound Blaster ISA (mostly SB16 or SB8, known as -SoundBlaster Pro) compatible audio cards. -.Pp -The value of flags specifies the secondary DMA channel. -If the secondary -DMA channel is C, set the flags to (C | 0x10). -For a sound card without the -secondary DMA channel, the flags should be set to zero. -.Sh HARDWARE -The -.Nm -driver supports the following sound cards: -.Pp -.Bl -bullet -compact -.It -Avance Asound 110 -.It -Avance Logic ALS100+ -.It -Avance Logic ALS120 -.It -Creative SB16 -.It -Creative SB32 -.It -Creative AWE64 -.It -Creative AWE64 Gold -.It -Creative ViBRA16C -.It -Creative ViBRA16X -.It -ESS ES1681 -.It -ESS ES1688 -.It -ESS ES1868 -.It -ESS ES1869 -.It -ESS ES1878 -.It -ESS ES1879 -.It -ESS ES1888 -.El -.Sh DIAGNOSTICS -.Bl -diag -.It sb_dspwr(XX) timed out. -A command to the DSP has timed out. -Check the I/O port configuration. -.It bad irq XX (5/7/9/10 valid) -The IRQ given to the driver is not valid. -.El -.Sh SEE ALSO -.Xr sound 4 -.Sh HISTORY -The -.Nm -device driver first appeared in -.Fx 4.0 . -.Sh AUTHORS -.An Seigo Tanimura Aq Mt tanimura@r.dl.itc.u-tokyo.ac.jp diff --git a/sys/conf/files b/sys/conf/files index 28c2d3b69fe4..e2e0ca9759db 100644 --- a/sys/conf/files +++ b/sys/conf/files @@ -3089,9 +3089,6 @@ dev/smc/if_smc_fdt.c optional smc fdt dev/snp/snp.c optional snp dev/sound/clone.c optional sound dev/sound/unit.c optional sound -dev/sound/isa/sb16.c optional snd_sb16 isa -dev/sound/isa/sb8.c optional snd_sb8 isa -dev/sound/isa/sbc.c optional snd_sbc isa dev/sound/isa/sndbuf_dma.c optional sound isa dev/sound/pci/als4000.c optional snd_als4000 pci dev/sound/pci/atiixp.c optional snd_atiixp pci diff --git a/sys/dev/sound/driver.c b/sys/dev/sound/driver.c index ae26de6e8f7a..eb134d944e24 100644 --- a/sys/dev/sound/driver.c +++ b/sys/dev/sound/driver.c @@ -73,9 +73,6 @@ MODULE_DEPEND(snd_driver, snd_hda, 1, 1, 1); MODULE_DEPEND(snd_driver, snd_ich, 1, 1, 1); MODULE_DEPEND(snd_driver, snd_maestro3, 1, 1, 1); MODULE_DEPEND(snd_driver, snd_neomagic, 1, 1, 1); -MODULE_DEPEND(snd_driver, snd_sb16, 1, 1, 1); -MODULE_DEPEND(snd_driver, snd_sb8, 1, 1, 1); -MODULE_DEPEND(snd_driver, snd_sbc, 1, 1, 1); MODULE_DEPEND(snd_driver, snd_solo, 1, 1, 1); MODULE_DEPEND(snd_driver, snd_spicds, 1, 1, 1); MODULE_DEPEND(snd_driver, snd_t4dwave, 1, 1, 1); diff --git a/sys/dev/sound/isa/sb16.c b/sys/dev/sound/isa/sb16.c deleted file mode 100644 index cece651951ff..000000000000 --- a/sys/dev/sound/isa/sb16.c +++ /dev/null @@ -1,912 +0,0 @@ -/*- - * SPDX-License-Identifier: BSD-2-Clause-FreeBSD - * - * Copyright (c) 1999 Cameron Grant - * Copyright (c) 1997,1998 Luigi Rizzo - * - * Derived from files in the Voxware 3.5 distribution, - * Copyright by Hannu Savolainen 1994, under the same copyright - * conditions. - * 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. - */ - -#ifdef HAVE_KERNEL_OPTION_HEADERS -#include "opt_snd.h" -#endif - -#include - -#include -#include - -#include - -#include "mixer_if.h" - -SND_DECLARE_FILE("$FreeBSD$"); - -#define SB16_BUFFSIZE 4096 -#define PLAIN_SB16(x) ((((x)->bd_flags) & (BD_F_SB16|BD_F_SB16X)) == BD_F_SB16) - -static u_int32_t sb16_fmt8[] = { - SND_FORMAT(AFMT_U8, 1, 0), - SND_FORMAT(AFMT_U8, 2, 0), - 0 -}; -static struct pcmchan_caps sb16_caps8 = {5000, 45000, sb16_fmt8, 0}; - -static u_int32_t sb16_fmt16[] = { - SND_FORMAT(AFMT_S16_LE, 1, 0), - SND_FORMAT(AFMT_S16_LE, 2, 0), - 0 -}; -static struct pcmchan_caps sb16_caps16 = {5000, 45000, sb16_fmt16, 0}; - -static u_int32_t sb16x_fmt[] = { - 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 sb16x_caps = {5000, 49000, sb16x_fmt, 0}; - -struct sb_info; - -struct sb_chinfo { - struct sb_info *parent; - struct pcm_channel *channel; - struct snd_dbuf *buffer; - int dir, run, dch; - u_int32_t fmt, spd, blksz; -}; - -struct sb_info { - struct resource *io_base; /* I/O address for the board */ - struct resource *irq; - struct resource *drq1; - struct resource *drq2; - void *ih; - bus_dma_tag_t parent_dmat; - - unsigned int bufsize; - int bd_id; - u_long bd_flags; /* board-specific flags */ - int prio, prio16; - struct sb_chinfo pch, rch; - device_t parent_dev; -}; - -#if 0 -static void sb_lock(struct sb_info *sb); -static void sb_unlock(struct sb_info *sb); -static int sb_rd(struct sb_info *sb, int reg); -static void sb_wr(struct sb_info *sb, int reg, u_int8_t val); -static int sb_cmd(struct sb_info *sb, u_char val); -/* static int sb_cmd1(struct sb_info *sb, u_char cmd, int val); */ -static int sb_cmd2(struct sb_info *sb, u_char cmd, int val); -static u_int sb_get_byte(struct sb_info *sb); -static void sb_setmixer(struct sb_info *sb, u_int port, u_int value); -static int sb_getmixer(struct sb_info *sb, u_int port); -static int sb_reset_dsp(struct sb_info *sb); - -static void sb_intr(void *arg); -#endif - -/* - * Common code for the midi and pcm functions - * - * sb_cmd write a single byte to the CMD port. - * sb_cmd1 write a CMD + 1 byte arg - * sb_cmd2 write a CMD + 2 byte arg - * sb_get_byte returns a single byte from the DSP data port - */ - -static void -sb_lock(struct sb_info *sb) { - sbc_lock(device_get_softc(sb->parent_dev)); -} - -static void -sb_lockassert(struct sb_info *sb) { - sbc_lockassert(device_get_softc(sb->parent_dev)); -} - -static void -sb_unlock(struct sb_info *sb) { - sbc_unlock(device_get_softc(sb->parent_dev)); -} - -static int -port_rd(struct resource *port, int off) -{ - return bus_space_read_1(rman_get_bustag(port), rman_get_bushandle(port), off); -} - -static void -port_wr(struct resource *port, int off, u_int8_t data) -{ - bus_space_write_1(rman_get_bustag(port), rman_get_bushandle(port), off, data); -} - -static int -sb_rd(struct sb_info *sb, int reg) -{ - return port_rd(sb->io_base, reg); -} - -static void -sb_wr(struct sb_info *sb, int reg, u_int8_t val) -{ - port_wr(sb->io_base, reg, val); -} - -static int -sb_dspwr(struct sb_info *sb, u_char val) -{ - int i; - - for (i = 0; i < 1000; i++) { - if ((sb_rd(sb, SBDSP_STATUS) & 0x80)) - DELAY((i > 100)? 1000 : 10); - else { - sb_wr(sb, SBDSP_CMD, val); - return 1; - } - } - if (curthread->td_intr_nesting_level == 0) - printf("sb_dspwr(0x%02x) timed out.\n", val); - return 0; -} - -static int -sb_cmd(struct sb_info *sb, u_char val) -{ -#if 0 - printf("sb_cmd: %x\n", val); -#endif - return sb_dspwr(sb, val); -} - -/* -static int -sb_cmd1(struct sb_info *sb, u_char cmd, int val) -{ -#if 0 - printf("sb_cmd1: %x, %x\n", cmd, val); -#endif - if (sb_dspwr(sb, cmd)) { - return sb_dspwr(sb, val & 0xff); - } else return 0; -} -*/ - -static int -sb_cmd2(struct sb_info *sb, u_char cmd, int val) -{ - int r; - -#if 0 - printf("sb_cmd2: %x, %x\n", cmd, val); -#endif - sb_lockassert(sb); - r = 0; - if (sb_dspwr(sb, cmd)) { - if (sb_dspwr(sb, val & 0xff)) { - if (sb_dspwr(sb, (val >> 8) & 0xff)) { - r = 1; - } - } - } - - return r; -} - -/* - * in the SB, there is a set of indirect "mixer" registers with - * address at offset 4, data at offset 5 - */ -static void -sb_setmixer(struct sb_info *sb, u_int port, u_int value) -{ - sb_lock(sb); - sb_wr(sb, SB_MIX_ADDR, (u_char) (port & 0xff)); /* Select register */ - DELAY(10); - sb_wr(sb, SB_MIX_DATA, (u_char) (value & 0xff)); - DELAY(10); - sb_unlock(sb); -} - -static int -sb_getmixer(struct sb_info *sb, u_int port) -{ - int val; - - sb_lockassert(sb); - sb_wr(sb, SB_MIX_ADDR, (u_char) (port & 0xff)); /* Select register */ - DELAY(10); - val = sb_rd(sb, SB_MIX_DATA); - DELAY(10); - - return val; -} - -static u_int -sb_get_byte(struct sb_info *sb) -{ - int i; - - for (i = 1000; i > 0; i--) { - if (sb_rd(sb, DSP_DATA_AVAIL) & 0x80) - return sb_rd(sb, DSP_READ); - else - DELAY(20); - } - return 0xffff; -} - -static int -sb_reset_dsp(struct sb_info *sb) -{ - u_char b; - - sb_lockassert(sb); - sb_wr(sb, SBDSP_RST, 3); - DELAY(100); - sb_wr(sb, SBDSP_RST, 0); - b = sb_get_byte(sb); - if (b != 0xAA) { - DEB(printf("sb_reset_dsp 0x%lx failed\n", - rman_get_start(sb->io_base))); - return ENXIO; /* Sorry */ - } - return 0; -} - -/************************************************************/ - -struct sb16_mixent { - int reg; - int bits; - int ofs; - int stereo; -}; - -static const struct sb16_mixent sb16_mixtab[32] = { - [SOUND_MIXER_VOLUME] = { 0x30, 5, 3, 1 }, - [SOUND_MIXER_PCM] = { 0x32, 5, 3, 1 }, - [SOUND_MIXER_SYNTH] = { 0x34, 5, 3, 1 }, - [SOUND_MIXER_CD] = { 0x36, 5, 3, 1 }, - [SOUND_MIXER_LINE] = { 0x38, 5, 3, 1 }, - [SOUND_MIXER_MIC] = { 0x3a, 5, 3, 0 }, - [SOUND_MIXER_SPEAKER] = { 0x3b, 5, 3, 0 }, - [SOUND_MIXER_IGAIN] = { 0x3f, 2, 6, 1 }, - [SOUND_MIXER_OGAIN] = { 0x41, 2, 6, 1 }, - [SOUND_MIXER_TREBLE] = { 0x44, 4, 4, 1 }, - [SOUND_MIXER_BASS] = { 0x46, 4, 4, 1 }, - [SOUND_MIXER_LINE1] = { 0x52, 5, 3, 1 } -}; - -static int -sb16mix_init(struct snd_mixer *m) -{ - struct sb_info *sb = mix_getdevinfo(m); - - mix_setdevs(m, SOUND_MASK_SYNTH | SOUND_MASK_PCM | SOUND_MASK_SPEAKER | - SOUND_MASK_LINE | SOUND_MASK_MIC | SOUND_MASK_CD | - SOUND_MASK_IGAIN | SOUND_MASK_OGAIN | SOUND_MASK_LINE1 | - SOUND_MASK_VOLUME | SOUND_MASK_BASS | SOUND_MASK_TREBLE); - - mix_setrecdevs(m, SOUND_MASK_SYNTH | SOUND_MASK_LINE | - SOUND_MASK_LINE1 | SOUND_MASK_MIC | SOUND_MASK_CD); - - sb_setmixer(sb, 0x3c, 0x1f); /* make all output active */ - - sb_setmixer(sb, 0x3d, 0); /* make all inputs-l off */ - sb_setmixer(sb, 0x3e, 0); /* make all inputs-r off */ - - return 0; -} - -static int -rel2abs_volume(int x, int max) -{ - int temp; - - temp = ((x * max) + 50) / 100; - if (temp > max) - temp = max; - else if (temp < 0) - temp = 0; - return (temp); -} - -static int -sb16mix_set(struct snd_mixer *m, unsigned dev, unsigned left, unsigned right) -{ - struct sb_info *sb = mix_getdevinfo(m); - const struct sb16_mixent *e; - int max; - - e = &sb16_mixtab[dev]; - max = (1 << e->bits) - 1; - - left = rel2abs_volume(left, max); - right = rel2abs_volume(right, max); - - sb_setmixer(sb, e->reg, left << e->ofs); - if (e->stereo) - sb_setmixer(sb, e->reg + 1, right << e->ofs); - else - right = left; - - left = (left * 100) / max; - right = (right * 100) / max; - - return left | (right << 8); -} - -static u_int32_t -sb16mix_setrecsrc(struct snd_mixer *m, u_int32_t src) -{ - struct sb_info *sb = mix_getdevinfo(m); - u_char recdev_l, recdev_r; - - recdev_l = 0; - recdev_r = 0; - if (src & SOUND_MASK_MIC) { - recdev_l |= 0x01; /* mono mic */ - recdev_r |= 0x01; - } - - if (src & SOUND_MASK_CD) { - recdev_l |= 0x04; /* l cd */ - recdev_r |= 0x02; /* r cd */ - } - - if (src & SOUND_MASK_LINE) { - recdev_l |= 0x10; /* l line */ - recdev_r |= 0x08; /* r line */ - } - - if (src & SOUND_MASK_SYNTH) { - recdev_l |= 0x40; /* l midi */ - recdev_r |= 0x20; /* r midi */ - } - - sb_setmixer(sb, SB16_IMASK_L, recdev_l); - sb_setmixer(sb, SB16_IMASK_R, recdev_r); - - /* Switch on/off FM tuner source */ - if (src & SOUND_MASK_LINE1) - sb_setmixer(sb, 0x4a, 0x0c); - else - sb_setmixer(sb, 0x4a, 0x00); - - /* - * since the same volume controls apply to the input and - * output sections, the best approach to have a consistent - * behaviour among cards would be to disable the output path - * on devices which are used to record. - * However, since users like to have feedback, we only disable - * the mic -- permanently. - */ - sb_setmixer(sb, SB16_OMASK, 0x1f & ~1); - - return src; -} - -static kobj_method_t sb16mix_mixer_methods[] = { - KOBJMETHOD(mixer_init, sb16mix_init), - KOBJMETHOD(mixer_set, sb16mix_set), - KOBJMETHOD(mixer_setrecsrc, sb16mix_setrecsrc), - KOBJMETHOD_END -}; -MIXER_DECLARE(sb16mix_mixer); - -/************************************************************/ - -static void -sb16_release_resources(struct sb_info *sb, device_t dev) -{ - if (sb->irq) { - if (sb->ih) - bus_teardown_intr(dev, sb->irq, sb->ih); - bus_release_resource(dev, SYS_RES_IRQ, 0, sb->irq); - sb->irq = NULL; - } - if (sb->drq2) { - if (sb->drq2 != sb->drq1) { - isa_dma_release(rman_get_start(sb->drq2)); - bus_release_resource(dev, SYS_RES_DRQ, 1, sb->drq2); - } - sb->drq2 = NULL; - } - if (sb->drq1) { - isa_dma_release(rman_get_start(sb->drq1)); - bus_release_resource(dev, SYS_RES_DRQ, 0, sb->drq1); - sb->drq1 = NULL; - } - if (sb->io_base) { - bus_release_resource(dev, SYS_RES_IOPORT, 0, sb->io_base); - sb->io_base = NULL; - } - if (sb->parent_dmat) { - bus_dma_tag_destroy(sb->parent_dmat); - sb->parent_dmat = 0; - } - free(sb, M_DEVBUF); -} - -static int -sb16_alloc_resources(struct sb_info *sb, device_t dev) -{ - int rid; - - rid = 0; - if (!sb->io_base) - sb->io_base = bus_alloc_resource_any(dev, SYS_RES_IOPORT, - &rid, RF_ACTIVE); - - rid = 0; - if (!sb->irq) - sb->irq = bus_alloc_resource_any(dev, SYS_RES_IRQ, &rid, - RF_ACTIVE); - - rid = 0; - if (!sb->drq1) - sb->drq1 = bus_alloc_resource_any(dev, SYS_RES_DRQ, &rid, - RF_ACTIVE); - - rid = 1; - if (!sb->drq2) - sb->drq2 = bus_alloc_resource_any(dev, SYS_RES_DRQ, &rid, - RF_ACTIVE); - - if (sb->io_base && sb->drq1 && sb->irq) { - isa_dma_acquire(rman_get_start(sb->drq1)); - isa_dmainit(rman_get_start(sb->drq1), sb->bufsize); - - if (sb->drq2) { - isa_dma_acquire(rman_get_start(sb->drq2)); - isa_dmainit(rman_get_start(sb->drq2), sb->bufsize); - } else { - sb->drq2 = sb->drq1; - pcm_setflags(dev, pcm_getflags(dev) | SD_F_SIMPLEX); - } - return 0; - } else return ENXIO; -} - -/* sbc does locking for us */ -static void -sb_intr(void *arg) -{ - struct sb_info *sb = (struct sb_info *)arg; - int reason, c; - - /* - * The Vibra16X has separate flags for 8 and 16 bit transfers, but - * I have no idea how to tell capture from playback interrupts... - */ - - reason = 0; - sb_lock(sb); - c = sb_getmixer(sb, IRQ_STAT); - if (c & 1) - sb_rd(sb, DSP_DATA_AVAIL); /* 8-bit int ack */ - - if (c & 2) - sb_rd(sb, DSP_DATA_AVL16); /* 16-bit int ack */ - sb_unlock(sb); - - /* - * this tells us if the source is 8-bit or 16-bit dma. We - * have to check the io channel to map it to read or write... - */ - - if (sb->bd_flags & BD_F_SB16X) { - if (c & 1) { /* 8-bit format */ - if (sb->pch.fmt & AFMT_8BIT) - reason |= 1; - if (sb->rch.fmt & AFMT_8BIT) - reason |= 2; - } - if (c & 2) { /* 16-bit format */ - if (sb->pch.fmt & AFMT_16BIT) - reason |= 1; - if (sb->rch.fmt & AFMT_16BIT) - reason |= 2; - } - } else { - if (c & 1) { /* 8-bit dma */ - if (sb->pch.dch == 1) - reason |= 1; - if (sb->rch.dch == 1) - reason |= 2; - } - if (c & 2) { /* 16-bit dma */ - if (sb->pch.dch == 2) - reason |= 1; - if (sb->rch.dch == 2) - reason |= 2; - } - } -#if 0 - printf("sb_intr: reason=%d c=0x%x\n", reason, c); -#endif - if ((reason & 1) && (sb->pch.run)) - chn_intr(sb->pch.channel); - - if ((reason & 2) && (sb->rch.run)) - chn_intr(sb->rch.channel); -} - -static int -sb_setup(struct sb_info *sb) -{ - struct sb_chinfo *ch; - u_int8_t v; - int l, pprio; - - sb_lock(sb); - if (sb->bd_flags & BD_F_DMARUN) - sndbuf_dma(sb->pch.buffer, PCMTRIG_STOP); - if (sb->bd_flags & BD_F_DMARUN2) - sndbuf_dma(sb->rch.buffer, PCMTRIG_STOP); - sb->bd_flags &= ~(BD_F_DMARUN | BD_F_DMARUN2); - - sb_reset_dsp(sb); - - if (sb->bd_flags & BD_F_SB16X) { - /* full-duplex doesn't work! */ - pprio = sb->pch.run? 1 : 0; - sndbuf_dmasetup(sb->pch.buffer, pprio? sb->drq1 : sb->drq2); - sb->pch.dch = pprio? 1 : 0; - sndbuf_dmasetup(sb->rch.buffer, pprio? sb->drq2 : sb->drq1); - sb->rch.dch = pprio? 2 : 1; - } else { - if (sb->pch.run && sb->rch.run) { - pprio = (sb->rch.fmt & AFMT_16BIT)? 0 : 1; - sndbuf_dmasetup(sb->pch.buffer, pprio? sb->drq2 : sb->drq1); - sb->pch.dch = pprio? 2 : 1; - sndbuf_dmasetup(sb->rch.buffer, pprio? sb->drq1 : sb->drq2); - sb->rch.dch = pprio? 1 : 2; - } else { - if (sb->pch.run) { - sndbuf_dmasetup(sb->pch.buffer, (sb->pch.fmt & AFMT_16BIT)? sb->drq2 : sb->drq1); - sb->pch.dch = (sb->pch.fmt & AFMT_16BIT)? 2 : 1; - sndbuf_dmasetup(sb->rch.buffer, (sb->pch.fmt & AFMT_16BIT)? sb->drq1 : sb->drq2); - sb->rch.dch = (sb->pch.fmt & AFMT_16BIT)? 1 : 2; - } else if (sb->rch.run) { - sndbuf_dmasetup(sb->pch.buffer, (sb->rch.fmt & AFMT_16BIT)? sb->drq1 : sb->drq2); - sb->pch.dch = (sb->rch.fmt & AFMT_16BIT)? 1 : 2; - sndbuf_dmasetup(sb->rch.buffer, (sb->rch.fmt & AFMT_16BIT)? sb->drq2 : sb->drq1); - sb->rch.dch = (sb->rch.fmt & AFMT_16BIT)? 2 : 1; - } - } - } - - sndbuf_dmasetdir(sb->pch.buffer, PCMDIR_PLAY); - sndbuf_dmasetdir(sb->rch.buffer, PCMDIR_REC); - - /* - printf("setup: [pch = %d, pfmt = %d, pgo = %d] [rch = %d, rfmt = %d, rgo = %d]\n", - sb->pch.dch, sb->pch.fmt, sb->pch.run, sb->rch.dch, sb->rch.fmt, sb->rch.run); - */ - - ch = &sb->pch; - if (ch->run) { - l = ch->blksz; - if (ch->fmt & AFMT_16BIT) - l >>= 1; - l--; - - /* play speed */ - RANGE(ch->spd, 5000, 45000); - sb_cmd(sb, DSP_CMD_OUT16); - sb_cmd(sb, ch->spd >> 8); - sb_cmd(sb, ch->spd & 0xff); - - /* play format, length */ - v = DSP_F16_AUTO | DSP_F16_FIFO_ON | DSP_F16_DAC; - v |= (ch->fmt & AFMT_16BIT)? DSP_DMA16 : DSP_DMA8; - sb_cmd(sb, v); - - v = (AFMT_CHANNEL(ch->fmt) > 1)? DSP_F16_STEREO : 0; - v |= (ch->fmt & AFMT_SIGNED)? DSP_F16_SIGNED : 0; - sb_cmd2(sb, v, l); - sndbuf_dma(ch->buffer, PCMTRIG_START); - sb->bd_flags |= BD_F_DMARUN; - } - - ch = &sb->rch; - if (ch->run) { - l = ch->blksz; - if (ch->fmt & AFMT_16BIT) - l >>= 1; - l--; - - /* record speed */ - RANGE(ch->spd, 5000, 45000); - sb_cmd(sb, DSP_CMD_IN16); - sb_cmd(sb, ch->spd >> 8); - sb_cmd(sb, ch->spd & 0xff); - - /* record format, length */ - v = DSP_F16_AUTO | DSP_F16_FIFO_ON | DSP_F16_ADC; - v |= (ch->fmt & AFMT_16BIT)? DSP_DMA16 : DSP_DMA8; - sb_cmd(sb, v); - - v = (AFMT_CHANNEL(ch->fmt) > 1)? DSP_F16_STEREO : 0; - v |= (ch->fmt & AFMT_SIGNED)? DSP_F16_SIGNED : 0; - sb_cmd2(sb, v, l); - sndbuf_dma(ch->buffer, PCMTRIG_START); - sb->bd_flags |= BD_F_DMARUN2; - } - sb_unlock(sb); - - return 0; -} - -/* channel interface */ -static void * -sb16chan_init(kobj_t obj, void *devinfo, struct snd_dbuf *b, struct pcm_channel *c, int dir) -{ - struct sb_info *sb = devinfo; - struct sb_chinfo *ch = (dir == PCMDIR_PLAY)? &sb->pch : &sb->rch; - - ch->parent = sb; - ch->channel = c; - ch->buffer = b; - ch->dir = dir; - - if (sndbuf_alloc(ch->buffer, sb->parent_dmat, 0, sb->bufsize) != 0) - return NULL; - - return ch; -} - -static int -sb16chan_setformat(kobj_t obj, void *data, u_int32_t format) -{ - struct sb_chinfo *ch = data; - struct sb_info *sb = ch->parent; - - ch->fmt = format; - sb->prio = ch->dir; - sb->prio16 = (ch->fmt & AFMT_16BIT)? 1 : 0; - - return 0; -} - -static u_int32_t -sb16chan_setspeed(kobj_t obj, void *data, u_int32_t speed) -{ - struct sb_chinfo *ch = data; - - ch->spd = speed; - return speed; -} - -static u_int32_t -sb16chan_setblocksize(kobj_t obj, void *data, u_int32_t blocksize) -{ - struct sb_chinfo *ch = data; - - ch->blksz = blocksize; - return ch->blksz; -} - -static int -sb16chan_trigger(kobj_t obj, void *data, int go) -{ - struct sb_chinfo *ch = data; - struct sb_info *sb = ch->parent; - - if (!PCMTRIG_COMMON(go)) - return 0; - - if (go == PCMTRIG_START) - ch->run = 1; - else - ch->run = 0; - - sb_setup(sb); - - return 0; -} - -static u_int32_t -sb16chan_getptr(kobj_t obj, void *data) -{ - struct sb_chinfo *ch = data; - - return sndbuf_dmaptr(ch->buffer); -} - -static struct pcmchan_caps * -sb16chan_getcaps(kobj_t obj, void *data) -{ - struct sb_chinfo *ch = data; - struct sb_info *sb = ch->parent; - - if ((sb->prio == 0) || (sb->prio == ch->dir)) - return &sb16x_caps; - else - return sb->prio16? &sb16_caps8 : &sb16_caps16; -} - -static int -sb16chan_resetdone(kobj_t obj, void *data) -{ - struct sb_chinfo *ch = data; - struct sb_info *sb = ch->parent; - - sb->prio = 0; - - return 0; -} - -static kobj_method_t sb16chan_methods[] = { - KOBJMETHOD(channel_init, sb16chan_init), - KOBJMETHOD(channel_resetdone, sb16chan_resetdone), - KOBJMETHOD(channel_setformat, sb16chan_setformat), - KOBJMETHOD(channel_setspeed, sb16chan_setspeed), - KOBJMETHOD(channel_setblocksize, sb16chan_setblocksize), - KOBJMETHOD(channel_trigger, sb16chan_trigger), - KOBJMETHOD(channel_getptr, sb16chan_getptr), - KOBJMETHOD(channel_getcaps, sb16chan_getcaps), - KOBJMETHOD_END -}; -CHANNEL_DECLARE(sb16chan); - -/************************************************************/ - -static int -sb16_probe(device_t dev) -{ - char buf[64]; - uintptr_t func, ver, f; - - /* The parent device has already been probed. */ - BUS_READ_IVAR(device_get_parent(dev), dev, 0, &func); - if (func != SCF_PCM) - return (ENXIO); - - BUS_READ_IVAR(device_get_parent(dev), dev, 1, &ver); - f = (ver & 0xffff0000) >> 16; - ver &= 0x0000ffff; - if (f & BD_F_SB16) { - snprintf(buf, sizeof buf, "SB16 DSP %d.%02d%s", (int) ver >> 8, (int) ver & 0xff, - (f & BD_F_SB16X)? " (ViBRA16X)" : ""); - device_set_desc_copy(dev, buf); - return 0; - } else - return (ENXIO); -} - -static int -sb16_attach(device_t dev) -{ - struct sb_info *sb; - uintptr_t ver; - char status[SND_STATUSLEN], status2[SND_STATUSLEN]; - - gone_in_dev(dev, 14, "ISA sound driver"); - sb = malloc(sizeof(*sb), M_DEVBUF, M_WAITOK | M_ZERO); - sb->parent_dev = device_get_parent(dev); - BUS_READ_IVAR(sb->parent_dev, dev, 1, &ver); - sb->bd_id = ver & 0x0000ffff; - sb->bd_flags = (ver & 0xffff0000) >> 16; - sb->bufsize = pcm_getbuffersize(dev, 4096, SB16_BUFFSIZE, 65536); - - if (sb16_alloc_resources(sb, dev)) - goto no; - sb_lock(sb); - if (sb_reset_dsp(sb)) { - sb_unlock(sb); - goto no; - } - sb_unlock(sb); - if (mixer_init(dev, &sb16mix_mixer_class, sb)) - goto no; - if (snd_setup_intr(dev, sb->irq, 0, sb_intr, sb, &sb->ih)) - goto no; - - if (sb->bd_flags & BD_F_SB16X) - pcm_setflags(dev, pcm_getflags(dev) | SD_F_SIMPLEX); - - sb->prio = 0; - - if (bus_dma_tag_create(/*parent*/bus_get_dma_tag(dev), /*alignment*/2, - /*boundary*/0, - /*lowaddr*/BUS_SPACE_MAXADDR_24BIT, - /*highaddr*/BUS_SPACE_MAXADDR, - /*filter*/NULL, /*filterarg*/NULL, - /*maxsize*/sb->bufsize, /*nsegments*/1, - /*maxsegz*/0x3ffff, /*flags*/0, - /*lockfunc*/NULL, /*lockarg*/NULL, - &sb->parent_dmat) != 0) { - device_printf(dev, "unable to create dma tag\n"); - goto no; - } - - if (!(pcm_getflags(dev) & SD_F_SIMPLEX)) - snprintf(status2, SND_STATUSLEN, ":%jd", rman_get_start(sb->drq2)); - else - status2[0] = '\0'; - - snprintf(status, SND_STATUSLEN, "at io 0x%jx irq %jd drq %jd%s bufsz %u %s", - rman_get_start(sb->io_base), rman_get_start(sb->irq), - rman_get_start(sb->drq1), status2, sb->bufsize, - PCM_KLDSTRING(snd_sb16)); - - if (pcm_register(dev, sb, 1, 1)) - goto no; - pcm_addchan(dev, PCMDIR_REC, &sb16chan_class, sb); - pcm_addchan(dev, PCMDIR_PLAY, &sb16chan_class, sb); - - pcm_setstatus(dev, status); - - return 0; - -no: - sb16_release_resources(sb, dev); - return ENXIO; -} - -static int -sb16_detach(device_t dev) -{ - int r; - struct sb_info *sb; - - r = pcm_unregister(dev); - if (r) - return r; - - sb = pcm_getdevinfo(dev); - sb16_release_resources(sb, dev); - return 0; -} - -static device_method_t sb16_methods[] = { - /* Device interface */ - DEVMETHOD(device_probe, sb16_probe), - DEVMETHOD(device_attach, sb16_attach), - DEVMETHOD(device_detach, sb16_detach), - { 0, 0 } -}; - -static driver_t sb16_driver = { - "pcm", - sb16_methods, - PCM_SOFTC_SIZE, -}; - -DRIVER_MODULE(snd_sb16, sbc, sb16_driver, 0, 0); -MODULE_DEPEND(snd_sb16, sound, SOUND_MINVER, SOUND_PREFVER, SOUND_MAXVER); -MODULE_DEPEND(snd_sb16, snd_sbc, 1, 1, 1); -MODULE_VERSION(snd_sb16, 1); diff --git a/sys/dev/sound/isa/sb8.c b/sys/dev/sound/isa/sb8.c deleted file mode 100644 index 3d3ac9d84ec8..000000000000 --- a/sys/dev/sound/isa/sb8.c +++ /dev/null @@ -1,803 +0,0 @@ -/*- - * SPDX-License-Identifier: BSD-2-Clause-FreeBSD - * - * Copyright (c) 1999 Cameron Grant - * Copyright (c) 1997,1998 Luigi Rizzo - * - * Derived from files in the Voxware 3.5 distribution, - * Copyright by Hannu Savolainen 1994, under the same copyright - * conditions. - * 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. - */ - -#ifdef HAVE_KERNEL_OPTION_HEADERS -#include "opt_snd.h" -#endif - -#include - -#include -#include - -#include - -#include "mixer_if.h" - -SND_DECLARE_FILE("$FreeBSD$"); - -#define SB_DEFAULT_BUFSZ 4096 - -static u_int32_t sb_fmt[] = { - SND_FORMAT(AFMT_U8, 1, 0), - 0 -}; -static struct pcmchan_caps sb200_playcaps = {4000, 23000, sb_fmt, 0}; -static struct pcmchan_caps sb200_reccaps = {4000, 13000, sb_fmt, 0}; -static struct pcmchan_caps sb201_playcaps = {4000, 44100, sb_fmt, 0}; -static struct pcmchan_caps sb201_reccaps = {4000, 15000, sb_fmt, 0}; - -static u_int32_t sbpro_fmt[] = { - SND_FORMAT(AFMT_U8, 1, 0), - SND_FORMAT(AFMT_U8, 2, 0), - 0 -}; -static struct pcmchan_caps sbpro_playcaps = {4000, 44100, sbpro_fmt, 0}; -static struct pcmchan_caps sbpro_reccaps = {4000, 44100, sbpro_fmt, 0}; - -struct sb_info; - -struct sb_chinfo { - struct sb_info *parent; - struct pcm_channel *channel; - struct snd_dbuf *buffer; - int dir; - u_int32_t fmt, spd, blksz; -}; - -struct sb_info { - device_t parent_dev; - struct resource *io_base; /* I/O address for the board */ - struct resource *irq; - struct resource *drq; - void *ih; - bus_dma_tag_t parent_dmat; - - unsigned int bufsize; - int bd_id; - u_long bd_flags; /* board-specific flags */ - struct sb_chinfo pch, rch; -}; - -static int sb_rd(struct sb_info *sb, int reg); -static void sb_wr(struct sb_info *sb, int reg, u_int8_t val); -static int sb_dspready(struct sb_info *sb); -static int sb_cmd(struct sb_info *sb, u_char val); -static int sb_cmd1(struct sb_info *sb, u_char cmd, int val); -static int sb_cmd2(struct sb_info *sb, u_char cmd, int val); -static u_int sb_get_byte(struct sb_info *sb); -static void sb_setmixer(struct sb_info *sb, u_int port, u_int value); -static int sb_getmixer(struct sb_info *sb, u_int port); -static int sb_reset_dsp(struct sb_info *sb); - -static void sb_intr(void *arg); -static int sb_speed(struct sb_chinfo *ch); -static int sb_start(struct sb_chinfo *ch); -static int sb_stop(struct sb_chinfo *ch); - -/* - * Common code for the midi and pcm functions - * - * sb_cmd write a single byte to the CMD port. - * sb_cmd1 write a CMD + 1 byte arg - * sb_cmd2 write a CMD + 2 byte arg - * sb_get_byte returns a single byte from the DSP data port - */ - -static void -sb_lock(struct sb_info *sb) { - sbc_lock(device_get_softc(sb->parent_dev)); -} - -static void -sb_unlock(struct sb_info *sb) { - sbc_unlock(device_get_softc(sb->parent_dev)); -} - -static int -port_rd(struct resource *port, int off) -{ - return bus_space_read_1(rman_get_bustag(port), rman_get_bushandle(port), off); -} - -static void -port_wr(struct resource *port, int off, u_int8_t data) -{ - bus_space_write_1(rman_get_bustag(port), rman_get_bushandle(port), off, data); -} - -static int -sb_rd(struct sb_info *sb, int reg) -{ - return port_rd(sb->io_base, reg); -} - -static void -sb_wr(struct sb_info *sb, int reg, u_int8_t val) -{ - port_wr(sb->io_base, reg, val); -} - -static int -sb_dspready(struct sb_info *sb) -{ - return ((sb_rd(sb, SBDSP_STATUS) & 0x80) == 0); -} - -static int -sb_dspwr(struct sb_info *sb, u_char val) -{ - int i; - - for (i = 0; i < 1000; i++) { - if (sb_dspready(sb)) { - sb_wr(sb, SBDSP_CMD, val); - return 1; - } - if (i > 10) DELAY((i > 100)? 1000 : 10); - } - printf("sb_dspwr(0x%02x) timed out.\n", val); - return 0; -} - -static int -sb_cmd(struct sb_info *sb, u_char val) -{ -#if 0 - printf("sb_cmd: %x\n", val); -#endif - return sb_dspwr(sb, val); -} - -static int -sb_cmd1(struct sb_info *sb, u_char cmd, int val) -{ -#if 0 - printf("sb_cmd1: %x, %x\n", cmd, val); -#endif - if (sb_dspwr(sb, cmd)) { - return sb_dspwr(sb, val & 0xff); - } else return 0; -} - -static int -sb_cmd2(struct sb_info *sb, u_char cmd, int val) -{ -#if 0 - printf("sb_cmd2: %x, %x\n", cmd, val); -#endif - if (sb_dspwr(sb, cmd)) { - return sb_dspwr(sb, val & 0xff) && - sb_dspwr(sb, (val >> 8) & 0xff); - } else return 0; -} - -/* - * in the SB, there is a set of indirect "mixer" registers with - * address at offset 4, data at offset 5 - * - * we don't need to interlock these, the mixer lock will suffice. - */ -static void -sb_setmixer(struct sb_info *sb, u_int port, u_int value) -{ - sb_wr(sb, SB_MIX_ADDR, (u_char) (port & 0xff)); /* Select register */ - DELAY(10); - sb_wr(sb, SB_MIX_DATA, (u_char) (value & 0xff)); - DELAY(10); -} - -static int -sb_getmixer(struct sb_info *sb, u_int port) -{ - int val; - - sb_wr(sb, SB_MIX_ADDR, (u_char) (port & 0xff)); /* Select register */ - DELAY(10); - val = sb_rd(sb, SB_MIX_DATA); - DELAY(10); - - return val; -} - -static u_int -sb_get_byte(struct sb_info *sb) -{ - int i; - - for (i = 1000; i > 0; i--) { - if (sb_rd(sb, DSP_DATA_AVAIL) & 0x80) - return sb_rd(sb, DSP_READ); - else - DELAY(20); - } - return 0xffff; -} - -static int -sb_reset_dsp(struct sb_info *sb) -{ - sb_wr(sb, SBDSP_RST, 3); - DELAY(100); - sb_wr(sb, SBDSP_RST, 0); - if (sb_get_byte(sb) != 0xAA) { - DEB(printf("sb_reset_dsp 0x%lx failed\n", - rman_get_start(sb->io_base))); - return ENXIO; /* Sorry */ - } - return 0; -} - -static void -sb_release_resources(struct sb_info *sb, device_t dev) -{ - if (sb->irq) { - if (sb->ih) - bus_teardown_intr(dev, sb->irq, sb->ih); - bus_release_resource(dev, SYS_RES_IRQ, 0, sb->irq); - sb->irq = NULL; - } - if (sb->drq) { - isa_dma_release(rman_get_start(sb->drq)); - bus_release_resource(dev, SYS_RES_DRQ, 0, sb->drq); - sb->drq = NULL; - } - if (sb->io_base) { - bus_release_resource(dev, SYS_RES_IOPORT, 0, sb->io_base); - sb->io_base = NULL; - } - if (sb->parent_dmat) { - bus_dma_tag_destroy(sb->parent_dmat); - sb->parent_dmat = 0; - } - free(sb, M_DEVBUF); -} - -static int -sb_alloc_resources(struct sb_info *sb, device_t dev) -{ - int rid; - - rid = 0; - if (!sb->io_base) - sb->io_base = bus_alloc_resource_any(dev, SYS_RES_IOPORT, - &rid, RF_ACTIVE); - rid = 0; - if (!sb->irq) - sb->irq = bus_alloc_resource_any(dev, SYS_RES_IRQ, - &rid, RF_ACTIVE); - rid = 0; - if (!sb->drq) - sb->drq = bus_alloc_resource_any(dev, SYS_RES_DRQ, - &rid, RF_ACTIVE); - - if (sb->io_base && sb->drq && sb->irq) { - isa_dma_acquire(rman_get_start(sb->drq)); - isa_dmainit(rman_get_start(sb->drq), sb->bufsize); - - return 0; - } else return ENXIO; -} - -/************************************************************/ - -static int -sbpromix_init(struct snd_mixer *m) -{ - struct sb_info *sb = mix_getdevinfo(m); - - mix_setdevs(m, SOUND_MASK_SYNTH | SOUND_MASK_PCM | SOUND_MASK_LINE | - SOUND_MASK_MIC | SOUND_MASK_CD | SOUND_MASK_VOLUME); - - mix_setrecdevs(m, SOUND_MASK_LINE | SOUND_MASK_MIC | SOUND_MASK_CD); - - sb_setmixer(sb, 0, 1); /* reset mixer */ - - return 0; -} - -static int -sbpromix_set(struct snd_mixer *m, unsigned dev, unsigned left, unsigned right) -{ - struct sb_info *sb = mix_getdevinfo(m); - int reg, max; - u_char val; - - max = 7; - switch (dev) { - case SOUND_MIXER_PCM: - reg = 0x04; - break; - - case SOUND_MIXER_MIC: - reg = 0x0a; - max = 3; - break; - - case SOUND_MIXER_VOLUME: - reg = 0x22; - break; - - case SOUND_MIXER_SYNTH: - reg = 0x26; - break; - - case SOUND_MIXER_CD: - reg = 0x28; - break; - - case SOUND_MIXER_LINE: - reg = 0x2e; - break; - - default: - return -1; - } - - left = (left * max) / 100; - right = (dev == SOUND_MIXER_MIC)? left : ((right * max) / 100); - - val = (dev == SOUND_MIXER_MIC)? (left << 1) : (left << 5 | right << 1); - sb_setmixer(sb, reg, val); - - left = (left * 100) / max; - right = (right * 100) / max; - - return left | (right << 8); -} - -static u_int32_t -sbpromix_setrecsrc(struct snd_mixer *m, u_int32_t src) -{ - struct sb_info *sb = mix_getdevinfo(m); - u_char recdev; - - if (src == SOUND_MASK_LINE) - recdev = 0x06; - else if (src == SOUND_MASK_CD) - recdev = 0x02; - else { /* default: mic */ - src = SOUND_MASK_MIC; - recdev = 0; - } - sb_setmixer(sb, RECORD_SRC, recdev | (sb_getmixer(sb, RECORD_SRC) & ~0x07)); - - return src; -} - -static kobj_method_t sbpromix_mixer_methods[] = { - KOBJMETHOD(mixer_init, sbpromix_init), - KOBJMETHOD(mixer_set, sbpromix_set), - KOBJMETHOD(mixer_setrecsrc, sbpromix_setrecsrc), - KOBJMETHOD_END -}; -MIXER_DECLARE(sbpromix_mixer); - -/************************************************************/ - -static int -sbmix_init(struct snd_mixer *m) -{ - struct sb_info *sb = mix_getdevinfo(m); - - mix_setdevs(m, SOUND_MASK_SYNTH | SOUND_MASK_PCM | SOUND_MASK_CD | SOUND_MASK_VOLUME); - - mix_setrecdevs(m, 0); - - sb_setmixer(sb, 0, 1); /* reset mixer */ - - return 0; -} - -static int -sbmix_set(struct snd_mixer *m, unsigned dev, unsigned left, unsigned right) -{ - struct sb_info *sb = mix_getdevinfo(m); - int reg, max; - - max = 7; - switch (dev) { - case SOUND_MIXER_VOLUME: - reg = 0x2; - break; - - case SOUND_MIXER_SYNTH: - reg = 0x6; - break; - - case SOUND_MIXER_CD: - reg = 0x8; - break; - - case SOUND_MIXER_PCM: - reg = 0x0a; - max = 3; - break; - - default: - return -1; - } - - left = (left * max) / 100; - - sb_setmixer(sb, reg, left << 1); - - left = (left * 100) / max; - - return left | (left << 8); -} - -static u_int32_t -sbmix_setrecsrc(struct snd_mixer *m, u_int32_t src) -{ - return 0; -} - -static kobj_method_t sbmix_mixer_methods[] = { - KOBJMETHOD(mixer_init, sbmix_init), - KOBJMETHOD(mixer_set, sbmix_set), - KOBJMETHOD(mixer_setrecsrc, sbmix_setrecsrc), - KOBJMETHOD_END -}; -MIXER_DECLARE(sbmix_mixer); - -/************************************************************/ - -static void -sb_intr(void *arg) -{ - struct sb_info *sb = (struct sb_info *)arg; - - sb_lock(sb); - if (sndbuf_runsz(sb->pch.buffer) > 0) { - sb_unlock(sb); - chn_intr(sb->pch.channel); - sb_lock(sb); - } - - if (sndbuf_runsz(sb->rch.buffer) > 0) { - sb_unlock(sb); - chn_intr(sb->rch.channel); - sb_lock(sb); - } - - sb_rd(sb, DSP_DATA_AVAIL); /* int ack */ - sb_unlock(sb); -} - -static int -sb_speed(struct sb_chinfo *ch) -{ - struct sb_info *sb = ch->parent; - int play = (ch->dir == PCMDIR_PLAY)? 1 : 0; - int stereo = (AFMT_CHANNEL(ch->fmt) > 1)? 1 : 0; - int speed, tmp, thresh, max; - u_char tconst; - - if (sb->bd_id >= 0x300) { - thresh = stereo? 11025 : 23000; - max = stereo? 22050 : 44100; - } else if (sb->bd_id > 0x200) { - thresh = play? 23000 : 13000; - max = play? 44100 : 15000; - } else { - thresh = 999999; - max = play? 23000 : 13000; - } - - speed = ch->spd; - if (speed > max) - speed = max; - - sb_lock(sb); - sb->bd_flags &= ~BD_F_HISPEED; - if (speed > thresh) - sb->bd_flags |= BD_F_HISPEED; - - tmp = 65536 - (256000000 / (speed << stereo)); - tconst = tmp >> 8; - - sb_cmd1(sb, 0x40, tconst); /* set time constant */ - - speed = (256000000 / (65536 - tmp)) >> stereo; - - ch->spd = speed; - sb_unlock(sb); - return speed; -} - -static int -sb_start(struct sb_chinfo *ch) -{ - struct sb_info *sb = ch->parent; - int play = (ch->dir == PCMDIR_PLAY)? 1 : 0; - int stereo = (AFMT_CHANNEL(ch->fmt) > 1)? 1 : 0; - int l = ch->blksz; - u_char i; - - l--; - - sb_lock(sb); - if (play) - sb_cmd(sb, DSP_CMD_SPKON); - - if (sb->bd_flags & BD_F_HISPEED) - i = play? 0x90 : 0x98; - else - i = play? 0x1c : 0x2c; - - sb_setmixer(sb, 0x0e, stereo? 2 : 0); - sb_cmd2(sb, 0x48, l); - sb_cmd(sb, i); - - sb->bd_flags |= BD_F_DMARUN; - sb_unlock(sb); - return 0; -} - -static int -sb_stop(struct sb_chinfo *ch) -{ - struct sb_info *sb = ch->parent; - int play = (ch->dir == PCMDIR_PLAY)? 1 : 0; - - sb_lock(sb); - if (sb->bd_flags & BD_F_HISPEED) - sb_reset_dsp(sb); - else { -#if 0 - /* - * NOTE: DSP_CMD_DMAEXIT_8 does not work with old - * soundblaster. - */ - sb_cmd(sb, DSP_CMD_DMAEXIT_8); -#endif - sb_reset_dsp(sb); - } - - if (play) - sb_cmd(sb, DSP_CMD_SPKOFF); /* speaker off */ - sb_unlock(sb); - sb->bd_flags &= ~BD_F_DMARUN; - return 0; -} - -/* channel interface */ -static void * -sbchan_init(kobj_t obj, void *devinfo, struct snd_dbuf *b, struct pcm_channel *c, int dir) -{ - struct sb_info *sb = devinfo; - struct sb_chinfo *ch = (dir == PCMDIR_PLAY)? &sb->pch : &sb->rch; - - ch->parent = sb; - ch->channel = c; - ch->dir = dir; - ch->buffer = b; - if (sndbuf_alloc(ch->buffer, sb->parent_dmat, 0, sb->bufsize) != 0) - return NULL; - sndbuf_dmasetup(ch->buffer, sb->drq); - return ch; -} - -static int -sbchan_setformat(kobj_t obj, void *data, u_int32_t format) -{ - struct sb_chinfo *ch = data; - - ch->fmt = format; - return 0; -} - -static u_int32_t -sbchan_setspeed(kobj_t obj, void *data, u_int32_t speed) -{ - struct sb_chinfo *ch = data; - - ch->spd = speed; - return sb_speed(ch); -} - -static u_int32_t -sbchan_setblocksize(kobj_t obj, void *data, u_int32_t blocksize) -{ - struct sb_chinfo *ch = data; - - ch->blksz = blocksize; - return ch->blksz; -} - -static int -sbchan_trigger(kobj_t obj, void *data, int go) -{ - struct sb_chinfo *ch = data; - - if (!PCMTRIG_COMMON(go)) - return 0; - - sndbuf_dma(ch->buffer, go); - if (go == PCMTRIG_START) - sb_start(ch); - else - sb_stop(ch); - return 0; -} - -static u_int32_t -sbchan_getptr(kobj_t obj, void *data) -{ - struct sb_chinfo *ch = data; - - return sndbuf_dmaptr(ch->buffer); -} - -static struct pcmchan_caps * -sbchan_getcaps(kobj_t obj, void *data) -{ - struct sb_chinfo *ch = data; - int p = (ch->dir == PCMDIR_PLAY)? 1 : 0; - - if (ch->parent->bd_id == 0x200) - return p? &sb200_playcaps : &sb200_reccaps; - if (ch->parent->bd_id < 0x300) - return p? &sb201_playcaps : &sb201_reccaps; - return p? &sbpro_playcaps : &sbpro_reccaps; -} - -static kobj_method_t sbchan_methods[] = { - KOBJMETHOD(channel_init, sbchan_init), - KOBJMETHOD(channel_setformat, sbchan_setformat), - KOBJMETHOD(channel_setspeed, sbchan_setspeed), - KOBJMETHOD(channel_setblocksize, sbchan_setblocksize), - KOBJMETHOD(channel_trigger, sbchan_trigger), - KOBJMETHOD(channel_getptr, sbchan_getptr), - KOBJMETHOD(channel_getcaps, sbchan_getcaps), - KOBJMETHOD_END -}; -CHANNEL_DECLARE(sbchan); - -/************************************************************/ - -static int -sb_probe(device_t dev) -{ - char buf[64]; - uintptr_t func, ver, f; - - /* The parent device has already been probed. */ - BUS_READ_IVAR(device_get_parent(dev), dev, 0, &func); - if (func != SCF_PCM) - return (ENXIO); - - BUS_READ_IVAR(device_get_parent(dev), dev, 1, &ver); - f = (ver & 0xffff0000) >> 16; - ver &= 0x0000ffff; - if ((f & BD_F_ESS) || (ver >= 0x400)) - return (ENXIO); - - snprintf(buf, sizeof buf, "SB DSP %d.%02d", (int) ver >> 8, (int) ver & 0xff); - - device_set_desc_copy(dev, buf); - - return 0; -} - -static int -sb_attach(device_t dev) -{ - struct sb_info *sb; - char status[SND_STATUSLEN]; - uintptr_t ver; - - gone_in_dev(dev, 14, "ISA sound driver"); - sb = malloc(sizeof(*sb), M_DEVBUF, M_WAITOK | M_ZERO); - sb->parent_dev = device_get_parent(dev); - BUS_READ_IVAR(device_get_parent(dev), dev, 1, &ver); - sb->bd_id = ver & 0x0000ffff; - sb->bd_flags = (ver & 0xffff0000) >> 16; - sb->bufsize = pcm_getbuffersize(dev, 4096, SB_DEFAULT_BUFSZ, 65536); - - if (sb_alloc_resources(sb, dev)) - goto no; - if (sb_reset_dsp(sb)) - goto no; - if (mixer_init(dev, (sb->bd_id < 0x300)? &sbmix_mixer_class : &sbpromix_mixer_class, sb)) - goto no; - if (snd_setup_intr(dev, sb->irq, 0, sb_intr, sb, &sb->ih)) - goto no; - - pcm_setflags(dev, pcm_getflags(dev) | SD_F_SIMPLEX); - - if (bus_dma_tag_create(/*parent*/bus_get_dma_tag(dev), /*alignment*/2, - /*boundary*/0, - /*lowaddr*/BUS_SPACE_MAXADDR_24BIT, - /*highaddr*/BUS_SPACE_MAXADDR, - /*filter*/NULL, /*filterarg*/NULL, - /*maxsize*/sb->bufsize, /*nsegments*/1, - /*maxsegz*/0x3ffff, /*flags*/0, - /*lockfunc*/NULL, /*lockarg*/NULL, - &sb->parent_dmat) != 0) { - device_printf(dev, "unable to create dma tag\n"); - goto no; - } - - snprintf(status, SND_STATUSLEN, "at io 0x%jx irq %jd drq %jd bufsz %u %s", - rman_get_start(sb->io_base), rman_get_start(sb->irq), - rman_get_start(sb->drq), sb->bufsize, PCM_KLDSTRING(snd_sb8)); - - if (pcm_register(dev, sb, 1, 1)) - goto no; - pcm_addchan(dev, PCMDIR_REC, &sbchan_class, sb); - pcm_addchan(dev, PCMDIR_PLAY, &sbchan_class, sb); - - pcm_setstatus(dev, status); - - return 0; - -no: - sb_release_resources(sb, dev); - return ENXIO; -} - -static int -sb_detach(device_t dev) -{ - int r; - struct sb_info *sb; - - r = pcm_unregister(dev); - if (r) - return r; - - sb = pcm_getdevinfo(dev); - sb_release_resources(sb, dev); - return 0; -} - -static device_method_t sb_methods[] = { - /* Device interface */ - DEVMETHOD(device_probe, sb_probe), - DEVMETHOD(device_attach, sb_attach), - DEVMETHOD(device_detach, sb_detach), - { 0, 0 } -}; - -static driver_t sb_driver = { - "pcm", - sb_methods, - PCM_SOFTC_SIZE, -}; - -DRIVER_MODULE(snd_sb8, sbc, sb_driver, 0, 0); -MODULE_DEPEND(snd_sb8, sound, SOUND_MINVER, SOUND_PREFVER, SOUND_MAXVER); -MODULE_DEPEND(snd_sb8, snd_sbc, 1, 1, 1); -MODULE_VERSION(snd_sb8, 1); diff --git a/sys/dev/sound/isa/sbc.c b/sys/dev/sound/isa/sbc.c deleted file mode 100644 index 344e0c2dd2d3..000000000000 --- a/sys/dev/sound/isa/sbc.c +++ /dev/null @@ -1,752 +0,0 @@ -/*- - * SPDX-License-Identifier: BSD-2-Clause-FreeBSD - * - * Copyright (c) 1999 Seigo Tanimura - * 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. - */ - -#ifdef HAVE_KERNEL_OPTION_HEADERS -#include "opt_snd.h" -#endif - -#include -#include -#include - -#include - -SND_DECLARE_FILE("$FreeBSD$"); - -#define IO_MAX 3 -#define IRQ_MAX 1 -#define DRQ_MAX 2 -#define INTR_MAX 2 - -struct sbc_softc; - -struct sbc_ihl { - driver_intr_t *intr[INTR_MAX]; - void *intr_arg[INTR_MAX]; - struct sbc_softc *parent; -}; - -/* Here is the parameter structure per a device. */ -struct sbc_softc { - device_t dev; /* device */ - device_t child_pcm, child_midi1, child_midi2; - - int io_rid[IO_MAX]; /* io port rids */ - struct resource *io[IO_MAX]; /* io port resources */ - int io_alloced[IO_MAX]; /* io port alloc flag */ - - int irq_rid[IRQ_MAX]; /* irq rids */ - struct resource *irq[IRQ_MAX]; /* irq resources */ - int irq_alloced[IRQ_MAX]; /* irq alloc flag */ - - int drq_rid[DRQ_MAX]; /* drq rids */ - struct resource *drq[DRQ_MAX]; /* drq resources */ - int drq_alloced[DRQ_MAX]; /* drq alloc flag */ - - struct sbc_ihl ihl[IRQ_MAX]; - - void *ih[IRQ_MAX]; - - struct mtx *lock; - - u_int32_t bd_ver; -}; - -static int sbc_probe(device_t dev); -static int sbc_attach(device_t dev); -static void sbc_intr(void *p); - -static struct resource *sbc_alloc_resource(device_t bus, device_t child, int type, int *rid, - rman_res_t start, rman_res_t end, rman_res_t count, u_int flags); -static int sbc_release_resource(device_t bus, device_t child, int type, int rid, - struct resource *r); -static int sbc_setup_intr(device_t dev, device_t child, struct resource *irq, - int flags, - driver_filter_t *filter, - driver_intr_t *intr, - void *arg, void **cookiep); -static int sbc_teardown_intr(device_t dev, device_t child, struct resource *irq, - void *cookie); - -static int alloc_resource(struct sbc_softc *scp); -static int release_resource(struct sbc_softc *scp); - -static int io_range[3] = {0x10, 0x2, 0x4}; - -static int sb_rd(struct resource *io, int reg); -static void sb_wr(struct resource *io, int reg, u_int8_t val); -static int sb_dspready(struct resource *io); -static int sb_cmd(struct resource *io, u_char val); -static u_int sb_get_byte(struct resource *io); -static void sb_setmixer(struct resource *io, u_int port, u_int value); - -static void -sbc_lockinit(struct sbc_softc *scp) -{ - scp->lock = snd_mtxcreate(device_get_nameunit(scp->dev), - "snd_sbc softc"); -} - -static void -sbc_lockdestroy(struct sbc_softc *scp) -{ - snd_mtxfree(scp->lock); -} - -void -sbc_lock(struct sbc_softc *scp) -{ - snd_mtxlock(scp->lock); -} - -void -sbc_lockassert(struct sbc_softc *scp) -{ - snd_mtxassert(scp->lock); -} - -void -sbc_unlock(struct sbc_softc *scp) -{ - snd_mtxunlock(scp->lock); -} - -static int -sb_rd(struct resource *io, int reg) -{ - return bus_space_read_1(rman_get_bustag(io), - rman_get_bushandle(io), - reg); -} - -static void -sb_wr(struct resource *io, int reg, u_int8_t val) -{ - bus_space_write_1(rman_get_bustag(io), - rman_get_bushandle(io), - reg, val); -} - -static int -sb_dspready(struct resource *io) -{ - return ((sb_rd(io, SBDSP_STATUS) & 0x80) == 0); -} - -static int -sb_dspwr(struct resource *io, u_char val) -{ - int i; - - for (i = 0; i < 1000; i++) { - if (sb_dspready(io)) { - sb_wr(io, SBDSP_CMD, val); - return 1; - } - if (i > 10) DELAY((i > 100)? 1000 : 10); - } - printf("sb_dspwr(0x%02x) timed out.\n", val); - return 0; -} - -static int -sb_cmd(struct resource *io, u_char val) -{ - return sb_dspwr(io, val); -} - -static void -sb_setmixer(struct resource *io, u_int port, u_int value) -{ - u_long flags; - - flags = spltty(); - sb_wr(io, SB_MIX_ADDR, (u_char) (port & 0xff)); /* Select register */ - DELAY(10); - sb_wr(io, SB_MIX_DATA, (u_char) (value & 0xff)); - DELAY(10); - splx(flags); -} - -static u_int -sb_get_byte(struct resource *io) -{ - int i; - - for (i = 1000; i > 0; i--) { - if (sb_rd(io, DSP_DATA_AVAIL) & 0x80) - return sb_rd(io, DSP_READ); - else - DELAY(20); - } - return 0xffff; -} - -static int -sb_reset_dsp(struct resource *io) -{ - sb_wr(io, SBDSP_RST, 3); - DELAY(100); - sb_wr(io, SBDSP_RST, 0); - return (sb_get_byte(io) == 0xAA)? 0 : ENXIO; -} - -static int -sb_identify_board(struct resource *io) -{ - int ver, essver, rev; - - sb_cmd(io, DSP_CMD_GETVER); /* Get version */ - ver = (sb_get_byte(io) << 8) | sb_get_byte(io); - if (ver < 0x100 || ver > 0x4ff) return 0; - if (ver == 0x0301) { - /* Try to detect ESS chips. */ - sb_cmd(io, DSP_CMD_GETID); /* Return ident. bytes. */ - essver = (sb_get_byte(io) << 8) | sb_get_byte(io); - rev = essver & 0x000f; - essver &= 0xfff0; - if (essver == 0x4880) ver |= 0x1000; - else if (essver == 0x6880) ver = 0x0500 | rev; - } - return ver; -} - -static struct isa_pnp_id sbc_ids[] = { - {0x01008c0e, "Creative ViBRA16C"}, /* CTL0001 */ - {0x31008c0e, "Creative SB16/SB32"}, /* CTL0031 */ - {0x41008c0e, "Creative SB16/SB32"}, /* CTL0041 */ - {0x42008c0e, "Creative SB AWE64"}, /* CTL0042 */ - {0x43008c0e, "Creative ViBRA16X"}, /* CTL0043 */ - {0x44008c0e, "Creative SB AWE64 Gold"}, /* CTL0044 */ - {0x45008c0e, "Creative SB AWE64"}, /* CTL0045 */ - {0x46008c0e, "Creative SB AWE64"}, /* CTL0046 */ - - {0x01000000, "Avance Logic ALS100+"}, /* @@@0001 - ViBRA16X clone */ - {0x01100000, "Avance Asound 110"}, /* @@@1001 */ - {0x01200000, "Avance Logic ALS120"}, /* @@@2001 - ViBRA16X clone */ - - {0x81167316, "ESS ES1681"}, /* ESS1681 */ - {0x02017316, "ESS ES1688"}, /* ESS1688 */ - {0x68097316, "ESS ES1688"}, /* ESS1688 */ - {0x68187316, "ESS ES1868"}, /* ESS1868 */ - {0x03007316, "ESS ES1869"}, /* ESS1869 */ - {0x69187316, "ESS ES1869"}, /* ESS1869 */ - {0xabb0110e, "ESS ES1869 (Compaq OEM)"}, /* CPQb0ab */ - {0xacb0110e, "ESS ES1869 (Compaq OEM)"}, /* CPQb0ac */ - {0x78187316, "ESS ES1878"}, /* ESS1878 */ - {0x79187316, "ESS ES1879"}, /* ESS1879 */ - {0x88187316, "ESS ES1888"}, /* ESS1888 */ - {0x07017316, "ESS ES1888 (DEC OEM)"}, /* ESS0107 */ - {0x06017316, "ESS ES1888 (Dell OEM)"}, /* ESS0106 */ - {0} -}; - -static int -sbc_probe(device_t dev) -{ - char *s = NULL; - u_int32_t lid, vid; - - lid = isa_get_logicalid(dev); - vid = isa_get_vendorid(dev); - if (lid) { - if (lid == 0x01000000 && vid != 0x01009305) /* ALS0001 */ - return ENXIO; - /* Check pnp ids */ - return ISA_PNP_PROBE(device_get_parent(dev), dev, sbc_ids); - } else { - int rid = 0, ver; - struct resource *io; - - io = bus_alloc_resource_anywhere(dev, SYS_RES_IOPORT, &rid, - 16, RF_ACTIVE); - if (!io) goto bad; - if (sb_reset_dsp(io)) goto bad2; - ver = sb_identify_board(io); - if (ver == 0) goto bad2; - switch ((ver & 0x00000f00) >> 8) { - case 1: - device_set_desc(dev, "SoundBlaster 1.0 (not supported)"); - s = NULL; - break; - - case 2: - s = "SoundBlaster 2.0"; - break; - - case 3: - s = (ver & 0x0000f000)? "ESS 488" : "SoundBlaster Pro"; - break; - - case 4: - s = "SoundBlaster 16"; - break; - - case 5: - s = (ver & 0x00000008)? "ESS 688" : "ESS 1688"; - break; - } - if (s) device_set_desc(dev, s); -bad2: bus_release_resource(dev, SYS_RES_IOPORT, rid, io); -bad: return s? 0 : ENXIO; - } -} - -static int -sbc_attach(device_t dev) -{ - char *err = NULL; - struct sbc_softc *scp; - struct sndcard_func *func; - u_int32_t logical_id = isa_get_logicalid(dev); - int flags = device_get_flags(dev); - int f, dh, dl, x, irq, i; - - gone_in_dev(dev, 14, "ISA sound driver"); - if (!logical_id && (flags & DV_F_DUAL_DMA)) { - bus_set_resource(dev, SYS_RES_DRQ, 1, - flags & DV_F_DRQ_MASK, 1); - } - - scp = device_get_softc(dev); - bzero(scp, sizeof(*scp)); - scp->dev = dev; - sbc_lockinit(scp); - err = "alloc_resource"; - if (alloc_resource(scp)) goto bad; - - err = "sb_reset_dsp"; - if (sb_reset_dsp(scp->io[0])) goto bad; - err = "sb_identify_board"; - scp->bd_ver = sb_identify_board(scp->io[0]) & 0x00000fff; - if (scp->bd_ver == 0) goto bad; - f = 0; - if (logical_id == 0x01200000 && scp->bd_ver < 0x0400) scp->bd_ver = 0x0499; - switch ((scp->bd_ver & 0x0f00) >> 8) { - case 1: /* old sound blaster has nothing... */ - break; - - case 2: - f |= BD_F_DUP_MIDI; - if (scp->bd_ver > 0x200) f |= BD_F_MIX_CT1335; - break; - - case 5: - f |= BD_F_ESS; - scp->bd_ver = 0x0301; - case 3: - f |= BD_F_DUP_MIDI | BD_F_MIX_CT1345; - break; - - case 4: - f |= BD_F_SB16 | BD_F_MIX_CT1745; - if (scp->drq[0]) dl = rman_get_start(scp->drq[0]); else dl = -1; - if (scp->drq[1]) dh = rman_get_start(scp->drq[1]); else dh = dl; - if (!logical_id && (dh < dl)) { - struct resource *r; - r = scp->drq[0]; - scp->drq[0] = scp->drq[1]; - scp->drq[1] = r; - dl = rman_get_start(scp->drq[0]); - dh = rman_get_start(scp->drq[1]); - } - /* soft irq/dma configuration */ - x = -1; - irq = rman_get_start(scp->irq[0]); - if (irq == 5) x = 2; - else if (irq == 7) x = 4; - else if (irq == 9) x = 1; - else if (irq == 10) x = 8; - if (x == -1) { - err = "bad irq (5/7/9/10 valid)"; - goto bad; - } - else sb_setmixer(scp->io[0], IRQ_NR, x); - sb_setmixer(scp->io[0], DMA_NR, (1 << dh) | (1 << dl)); - if (bootverbose) { - device_printf(dev, "setting card to irq %d, drq %d", irq, dl); - if (dl != dh) printf(", %d", dh); - printf("\n"); - } - break; - } - - switch (logical_id) { - case 0x43008c0e: /* CTL0043 */ - case 0x01200000: - case 0x01000000: - f |= BD_F_SB16X; - break; - } - scp->bd_ver |= f << 16; - - err = "setup_intr"; - for (i = 0; i < IRQ_MAX; i++) { - scp->ihl[i].parent = scp; - if (snd_setup_intr(dev, scp->irq[i], 0, sbc_intr, &scp->ihl[i], &scp->ih[i])) - goto bad; - } - - /* PCM Audio */ - func = malloc(sizeof(struct sndcard_func), M_DEVBUF, M_NOWAIT | M_ZERO); - if (func == NULL) goto bad; - func->func = SCF_PCM; - scp->child_pcm = device_add_child(dev, "pcm", -1); - device_set_ivars(scp->child_pcm, func); - - /* Midi Interface */ - func = malloc(sizeof(struct sndcard_func), M_DEVBUF, M_NOWAIT | M_ZERO); - if (func == NULL) goto bad; - func->func = SCF_MIDI; - scp->child_midi1 = device_add_child(dev, "midi", -1); - device_set_ivars(scp->child_midi1, func); - - /* OPL FM Synthesizer */ - func = malloc(sizeof(struct sndcard_func), M_DEVBUF, M_NOWAIT | M_ZERO); - if (func == NULL) goto bad; - func->func = SCF_SYNTH; - scp->child_midi2 = device_add_child(dev, "midi", -1); - device_set_ivars(scp->child_midi2, func); - - /* probe/attach kids */ - bus_generic_attach(dev); - - return (0); - -bad: if (err) device_printf(dev, "%s\n", err); - release_resource(scp); - return (ENXIO); -} - -static int -sbc_detach(device_t dev) -{ - struct sbc_softc *scp = device_get_softc(dev); - - sbc_lock(scp); - device_delete_child(dev, scp->child_midi2); - device_delete_child(dev, scp->child_midi1); - device_delete_child(dev, scp->child_pcm); - release_resource(scp); - sbc_lockdestroy(scp); - return bus_generic_detach(dev); -} - -static void -sbc_intr(void *p) -{ - struct sbc_ihl *ihl = p; - int i; - - /* sbc_lock(ihl->parent); */ - i = 0; - while (i < INTR_MAX) { - if (ihl->intr[i] != NULL) ihl->intr[i](ihl->intr_arg[i]); - i++; - } - /* sbc_unlock(ihl->parent); */ -} - -static int -sbc_setup_intr(device_t dev, device_t child, struct resource *irq, int flags, - driver_filter_t *filter, - driver_intr_t *intr, - void *arg, void **cookiep) -{ - struct sbc_softc *scp = device_get_softc(dev); - struct sbc_ihl *ihl = NULL; - int i, ret; - - if (filter != NULL) { - printf("sbc.c: we cannot use a filter here\n"); - return (EINVAL); - } - sbc_lock(scp); - i = 0; - while (i < IRQ_MAX) { - if (irq == scp->irq[i]) ihl = &scp->ihl[i]; - i++; - } - ret = 0; - if (ihl == NULL) ret = EINVAL; - i = 0; - while ((ret == 0) && (i < INTR_MAX)) { - if (ihl->intr[i] == NULL) { - ihl->intr[i] = intr; - ihl->intr_arg[i] = arg; - *cookiep = &ihl->intr[i]; - ret = -1; - } else i++; - } - sbc_unlock(scp); - return (ret > 0)? EINVAL : 0; -} - -static int -sbc_teardown_intr(device_t dev, device_t child, struct resource *irq, - void *cookie) -{ - struct sbc_softc *scp = device_get_softc(dev); - struct sbc_ihl *ihl = NULL; - int i, ret; - - sbc_lock(scp); - i = 0; - while (i < IRQ_MAX) { - if (irq == scp->irq[i]) ihl = &scp->ihl[i]; - i++; - } - ret = 0; - if (ihl == NULL) ret = EINVAL; - i = 0; - while ((ret == 0) && (i < INTR_MAX)) { - if (cookie == &ihl->intr[i]) { - ihl->intr[i] = NULL; - ihl->intr_arg[i] = NULL; - return 0; - } else i++; - } - sbc_unlock(scp); - return (ret > 0)? EINVAL : 0; -} - -static struct resource * -sbc_alloc_resource(device_t bus, device_t child, int type, int *rid, - rman_res_t start, rman_res_t end, rman_res_t count, u_int flags) -{ - struct sbc_softc *scp; - int *alloced, rid_max, alloced_max; - struct resource **res; - - scp = device_get_softc(bus); - switch (type) { - case SYS_RES_IOPORT: - alloced = scp->io_alloced; - res = scp->io; - rid_max = IO_MAX - 1; - alloced_max = 1; - break; - case SYS_RES_DRQ: - alloced = scp->drq_alloced; - res = scp->drq; - rid_max = DRQ_MAX - 1; - alloced_max = 1; - break; - case SYS_RES_IRQ: - alloced = scp->irq_alloced; - res = scp->irq; - rid_max = IRQ_MAX - 1; - alloced_max = INTR_MAX; /* pcm and mpu may share the irq. */ - break; - default: - return (NULL); - } - - if (*rid > rid_max || alloced[*rid] == alloced_max) - return (NULL); - - alloced[*rid]++; - return (res[*rid]); -} - -static int -sbc_release_resource(device_t bus, device_t child, int type, int rid, - struct resource *r) -{ - struct sbc_softc *scp; - int *alloced, rid_max; - - scp = device_get_softc(bus); - switch (type) { - case SYS_RES_IOPORT: - alloced = scp->io_alloced; - rid_max = IO_MAX - 1; - break; - case SYS_RES_DRQ: - alloced = scp->drq_alloced; - rid_max = DRQ_MAX - 1; - break; - case SYS_RES_IRQ: - alloced = scp->irq_alloced; - rid_max = IRQ_MAX - 1; - break; - default: - return (1); - } - - if (rid > rid_max || alloced[rid] == 0) - return (1); - - alloced[rid]--; - return (0); -} - -static int -sbc_read_ivar(device_t bus, device_t dev, int index, uintptr_t * result) -{ - struct sbc_softc *scp = device_get_softc(bus); - struct sndcard_func *func = device_get_ivars(dev); - - switch (index) { - case 0: - *result = func->func; - break; - - case 1: - *result = scp->bd_ver; - break; - - default: - return ENOENT; - } - - return 0; -} - -static int -sbc_write_ivar(device_t bus, device_t dev, - int index, uintptr_t value) -{ - switch (index) { - case 0: - case 1: - return EINVAL; - - default: - return (ENOENT); - } -} - -static int -alloc_resource(struct sbc_softc *scp) -{ - int i; - - for (i = 0 ; i < IO_MAX ; i++) { - if (scp->io[i] == NULL) { - scp->io_rid[i] = i; - scp->io[i] = bus_alloc_resource_anywhere(scp->dev, - SYS_RES_IOPORT, - &scp->io_rid[i], - io_range[i], - RF_ACTIVE); - if (i == 0 && scp->io[i] == NULL) - return (1); - scp->io_alloced[i] = 0; - } - } - for (i = 0 ; i < DRQ_MAX ; i++) { - if (scp->drq[i] == NULL) { - scp->drq_rid[i] = i; - scp->drq[i] = bus_alloc_resource_any(scp->dev, - SYS_RES_DRQ, - &scp->drq_rid[i], - RF_ACTIVE); - if (i == 0 && scp->drq[i] == NULL) - return (1); - scp->drq_alloced[i] = 0; - } - } - for (i = 0 ; i < IRQ_MAX ; i++) { - if (scp->irq[i] == NULL) { - scp->irq_rid[i] = i; - scp->irq[i] = bus_alloc_resource_any(scp->dev, - SYS_RES_IRQ, - &scp->irq_rid[i], - RF_ACTIVE); - if (i == 0 && scp->irq[i] == NULL) - return (1); - scp->irq_alloced[i] = 0; - } - } - return (0); -} - -static int -release_resource(struct sbc_softc *scp) -{ - int i; - - for (i = 0 ; i < IO_MAX ; i++) { - if (scp->io[i] != NULL) { - bus_release_resource(scp->dev, SYS_RES_IOPORT, scp->io_rid[i], scp->io[i]); - scp->io[i] = NULL; - } - } - for (i = 0 ; i < DRQ_MAX ; i++) { - if (scp->drq[i] != NULL) { - bus_release_resource(scp->dev, SYS_RES_DRQ, scp->drq_rid[i], scp->drq[i]); - scp->drq[i] = NULL; - } - } - for (i = 0 ; i < IRQ_MAX ; i++) { - if (scp->irq[i] != NULL) { - if (scp->ih[i] != NULL) - bus_teardown_intr(scp->dev, scp->irq[i], scp->ih[i]); - scp->ih[i] = NULL; - bus_release_resource(scp->dev, SYS_RES_IRQ, scp->irq_rid[i], scp->irq[i]); - scp->irq[i] = NULL; - } - } - return (0); -} - -static device_method_t sbc_methods[] = { - /* Device interface */ - DEVMETHOD(device_probe, sbc_probe), - DEVMETHOD(device_attach, sbc_attach), - DEVMETHOD(device_detach, sbc_detach), - DEVMETHOD(device_shutdown, bus_generic_shutdown), - DEVMETHOD(device_suspend, bus_generic_suspend), - DEVMETHOD(device_resume, bus_generic_resume), - - /* Bus interface */ - DEVMETHOD(bus_read_ivar, sbc_read_ivar), - DEVMETHOD(bus_write_ivar, sbc_write_ivar), - DEVMETHOD(bus_alloc_resource, sbc_alloc_resource), - DEVMETHOD(bus_release_resource, sbc_release_resource), - DEVMETHOD(bus_activate_resource, bus_generic_activate_resource), - DEVMETHOD(bus_deactivate_resource, bus_generic_deactivate_resource), - DEVMETHOD(bus_setup_intr, sbc_setup_intr), - DEVMETHOD(bus_teardown_intr, sbc_teardown_intr), - - DEVMETHOD_END -}; - -static driver_t sbc_driver = { - "sbc", - sbc_methods, - sizeof(struct sbc_softc), -}; - -/* sbc can be attached to an isa bus. */ -DRIVER_MODULE(snd_sbc, isa, sbc_driver, 0, 0); -DRIVER_MODULE(snd_sbc, acpi, sbc_driver, 0, 0); -MODULE_DEPEND(snd_sbc, sound, SOUND_MINVER, SOUND_PREFVER, SOUND_MAXVER); -MODULE_VERSION(snd_sbc, 1); -ISA_PNP_INFO(sbc_ids); diff --git a/sys/modules/sound/driver/Makefile b/sys/modules/sound/driver/Makefile index 1cb26748740f..94fdd23d3154 100644 --- a/sys/modules/sound/driver/Makefile +++ b/sys/modules/sound/driver/Makefile @@ -8,7 +8,7 @@ SYSDIR?=${SRCTOP}/sys SUBDIR= als4000 atiixp cs4281 ${_csa} emu10k1 emu10kx SUBDIR+= envy24 envy24ht es137x fm801 hda hdspe ich -SUBDIR+= ${_maestro3} neomagic sb16 sb8 sbc solo spicds t4dwave via8233 +SUBDIR+= ${_maestro3} neomagic solo spicds t4dwave via8233 SUBDIR+= via82c686 vibes driver uaudio .if ${MK_SOURCELESS_UCODE} != "no" diff --git a/sys/modules/sound/driver/sb16/Makefile b/sys/modules/sound/driver/sb16/Makefile deleted file mode 100644 index 083a7203e860..000000000000 --- a/sys/modules/sound/driver/sb16/Makefile +++ /dev/null @@ -1,9 +0,0 @@ -# $FreeBSD$ - -.PATH: ${SRCTOP}/sys/dev/sound/isa - -KMOD= snd_sb16 -SRCS= device_if.h bus_if.h isa_if.h pci_if.h -SRCS+= sb16.c - -.include diff --git a/sys/modules/sound/driver/sb8/Makefile b/sys/modules/sound/driver/sb8/Makefile deleted file mode 100644 index 7d9ff49e3e78..000000000000 --- a/sys/modules/sound/driver/sb8/Makefile +++ /dev/null @@ -1,9 +0,0 @@ -# $FreeBSD$ - -.PATH: ${SRCTOP}/sys/dev/sound/isa - -KMOD= snd_sb8 -SRCS= device_if.h bus_if.h isa_if.h pci_if.h -SRCS+= sb8.c - -.include diff --git a/sys/modules/sound/driver/sbc/Makefile b/sys/modules/sound/driver/sbc/Makefile deleted file mode 100644 index bde54a077696..000000000000 --- a/sys/modules/sound/driver/sbc/Makefile +++ /dev/null @@ -1,11 +0,0 @@ -# $FreeBSD$ - -.PATH: ${SRCTOP}/sys/dev/sound/isa - -KMOD= snd_sbc -SRCS= device_if.h bus_if.h isa_if.h pci_if.h -SRCS+= sbc.c - -EXPORT_SYMS= YES - -.include