diff options
author | markm <markm@FreeBSD.org> | 1997-10-31 06:30:22 +0000 |
---|---|---|
committer | markm <markm@FreeBSD.org> | 1997-10-31 06:30:22 +0000 |
commit | be4808f6e2badf1629d651d8f1d2f5c7707e47a8 (patch) | |
tree | 9a3e498c45ec2bf39c7d1c79c9aa4bab90d109e8 /sys/i386/isa/sound/ics2101.c | |
parent | 17d7551904f5e100c3f914c00c72350a63a49dfa (diff) | |
download | FreeBSD-src-be4808f6e2badf1629d651d8f1d2f5c7707e47a8.zip FreeBSD-src-be4808f6e2badf1629d651d8f1d2f5c7707e47a8.tar.gz |
Upgrade the sound sources to Amancio Hasty's latest-and-greatest.
This is based on Voxware 3.5, and corresponds to Amancio's `guspnp21'.
Bug reports to Amancio, please!
Diffstat (limited to 'sys/i386/isa/sound/ics2101.c')
-rw-r--r-- | sys/i386/isa/sound/ics2101.c | 365 |
1 files changed, 167 insertions, 198 deletions
diff --git a/sys/i386/isa/sound/ics2101.c b/sys/i386/isa/sound/ics2101.c index cec1e51..4df8bde 100644 --- a/sys/i386/isa/sound/ics2101.c +++ b/sys/i386/isa/sound/ics2101.c @@ -1,10 +1,10 @@ /* * sound/ics2101.c - * + * * Driver for the ICS2101 mixer of GUS v3.7. - * + * * Copyright by Hannu Savolainen 1994 - * + * * 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 @@ -12,7 +12,7 @@ * 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 @@ -24,241 +24,210 @@ * 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. - * + * */ #include <i386/isa/sound/sound_config.h> -#if defined(CONFIGURE_SOUNDCARD) && !defined(EXCLUDE_GUS) -#include <machine/ultrasound.h> +#if defined(CONFIG_GUS) + +#include <i386/isa/sound/ultrasound.h> #include <i386/isa/sound/gus_hw.h> #define MIX_DEVS (SOUND_MASK_MIC|SOUND_MASK_LINE| \ SOUND_MASK_SYNTH| \ SOUND_MASK_CD | SOUND_MASK_VOLUME) +extern sound_os_info *gus_osp; extern int gus_base; static int volumes[ICS_MIXDEVS]; -static int left_fix[ICS_MIXDEVS] = -{1, 1, 1, 2, 1, 2}; -static int right_fix[ICS_MIXDEVS] = -{2, 2, 2, 1, 2, 1}; +static int left_fix[ICS_MIXDEVS] = {1, 1, 1, 2, 1, 2}; +static int right_fix[ICS_MIXDEVS] = {2, 2, 2, 1, 2, 1}; static int -scale_vol (int vol) +scale_vol(int vol) { -#if 1 - /* - * Experimental volume scaling by Risto Kankkunen. - * This should give smoother volume response than just - * a plain multiplication. - */ - int e; - - if (vol < 0) - vol = 0; - if (vol > 100) - vol = 100; - vol = (31 * vol + 50) / 100; - e = 0; - if (vol) - { - while (vol < 16) - { - vol <<= 1; - e--; + /* + * Experimental volume scaling by Risto Kankkunen. This should give + * smoother volume response than just a plain multiplication. + */ + int e; + + RANGE(vol, 0, 100); + vol = (31 * vol + 50) / 100; + e = 0; + if (vol) { + while (vol < 16) { + vol <<= 1; + e--; } - vol -= 16; - e += 7; + vol -= 16; + e += 7; } - return ((e << 4) + vol); -#else - return ((vol * 127) + 50) / 100; -#endif + return ((e << 4) + vol); } static void -write_mix (int dev, int chn, int vol) +write_mix(int dev, int chn, int vol) { - int *selector; - unsigned long flags; - int ctrl_addr = dev << 3; - int attn_addr = dev << 3; - - vol = scale_vol (vol); - - if (chn == CHN_LEFT) - { - selector = left_fix; - ctrl_addr |= 0x00; - attn_addr |= 0x02; - } - else - { - selector = right_fix; - ctrl_addr |= 0x01; - attn_addr |= 0x03; + int *selector; + unsigned long flags; + int ctrl_addr = dev << 3; + int attn_addr = dev << 3; + + vol = scale_vol(vol); + + if (chn == CHN_LEFT) { + selector = left_fix; + ctrl_addr |= 0x00; + attn_addr |= 0x02; + } else { + selector = right_fix; + ctrl_addr |= 0x01; + attn_addr |= 0x03; } - DISABLE_INTR (flags); - OUTB (ctrl_addr, u_MixSelect); - OUTB (selector[dev], u_MixData); - OUTB (attn_addr, u_MixSelect); - OUTB ((unsigned char) vol, u_MixData); - RESTORE_INTR (flags); + flags = splhigh(); + outb(u_MixSelect, ctrl_addr); + outb(u_MixData, selector[dev]); + outb(u_MixSelect, attn_addr); + outb(u_MixData, (unsigned char) vol); + splx(flags); } static int -set_volumes (int dev, int vol) +set_volumes(int dev, int vol) { - int left = vol & 0x00ff; - int right = (vol >> 8) & 0x00ff; - - if (left < 0) - left = 0; - if (left > 100) - left = 100; - if (right < 0) - right = 0; - if (right > 100) - right = 100; - - write_mix (dev, CHN_LEFT, left); - write_mix (dev, CHN_RIGHT, right); - - vol = left + (right << 8); - volumes[dev] = vol; - return vol; + int left = vol & 0x00ff; + int right = (vol >> 8) & 0x00ff; + + RANGE (left, 0, 100); + RANGE (right, 0, 100); + + write_mix(dev, CHN_LEFT, left); + write_mix(dev, CHN_RIGHT, right); + + vol = left + (right << 8); + volumes[dev] = vol; + return vol; } static int -ics2101_mixer_ioctl (int dev, unsigned int cmd, unsigned int arg) +ics2101_mixer_ioctl(int dev, unsigned int cmd, ioctl_arg arg) { - if (((cmd >> 8) & 0xff) == 'M') - { - if (cmd & IOC_IN) - switch (cmd & 0xff) - { - case SOUND_MIXER_RECSRC: - return gus_default_mixer_ioctl (dev, cmd, arg); - break; - - case SOUND_MIXER_MIC: - return IOCTL_OUT (arg, set_volumes (DEV_MIC, IOCTL_IN (arg))); - break; - - case SOUND_MIXER_CD: - return IOCTL_OUT (arg, set_volumes (DEV_CD, IOCTL_IN (arg))); - break; - - case SOUND_MIXER_LINE: - return IOCTL_OUT (arg, set_volumes (DEV_LINE, IOCTL_IN (arg))); - break; - - case SOUND_MIXER_SYNTH: - return IOCTL_OUT (arg, set_volumes (DEV_GF1, IOCTL_IN (arg))); - break; - - case SOUND_MIXER_VOLUME: - return IOCTL_OUT (arg, set_volumes (DEV_VOL, IOCTL_IN (arg))); - break; - - default: - return RET_ERROR (EINVAL); - } - else - switch (cmd & 0xff) /* - * Return parameters - */ - { - - case SOUND_MIXER_RECSRC: - return gus_default_mixer_ioctl (dev, cmd, arg); - break; - - case SOUND_MIXER_DEVMASK: - return IOCTL_OUT (arg, MIX_DEVS); - break; - - case SOUND_MIXER_STEREODEVS: - return IOCTL_OUT (arg, SOUND_MASK_LINE | SOUND_MASK_CD | - SOUND_MASK_SYNTH | SOUND_MASK_VOLUME | - SOUND_MASK_MIC); - break; - - case SOUND_MIXER_RECMASK: - return IOCTL_OUT (arg, SOUND_MASK_MIC | SOUND_MASK_LINE); - break; - - case SOUND_MIXER_CAPS: - return IOCTL_OUT (arg, 0); - break; - - case SOUND_MIXER_MIC: - return IOCTL_OUT (arg, volumes[DEV_MIC]); - break; - - case SOUND_MIXER_LINE: - return IOCTL_OUT (arg, volumes[DEV_LINE]); - break; - - case SOUND_MIXER_CD: - return IOCTL_OUT (arg, volumes[DEV_CD]); - break; - - case SOUND_MIXER_VOLUME: - return IOCTL_OUT (arg, volumes[DEV_VOL]); - break; - - case SOUND_MIXER_SYNTH: - return IOCTL_OUT (arg, volumes[DEV_GF1]); - break; - - default: - return RET_ERROR (EINVAL); - } + if (((cmd >> 8) & 0xff) == 'M') { + if (cmd & IOC_IN) + switch (cmd & 0xff) { + case SOUND_MIXER_RECSRC: + return gus_default_mixer_ioctl(dev, cmd, arg); + break; + + case SOUND_MIXER_MIC: + return *(int *) arg = set_volumes(DEV_MIC, (*(int *) arg)); + break; + + case SOUND_MIXER_CD: + return *(int *) arg = set_volumes(DEV_CD, (*(int *) arg)); + break; + + case SOUND_MIXER_LINE: + return *(int *) arg = set_volumes(DEV_LINE, (*(int *) arg)); + break; + + case SOUND_MIXER_SYNTH: + return *(int *) arg = set_volumes(DEV_GF1, (*(int *) arg)); + break; + + case SOUND_MIXER_VOLUME: + return *(int *) arg = set_volumes(DEV_VOL, (*(int *) arg)); + break; + + default: + return -(EINVAL); + } + else + switch (cmd & 0xff) { /* Return parameters */ + + case SOUND_MIXER_RECSRC: + return gus_default_mixer_ioctl(dev, cmd, arg); + break; + + case SOUND_MIXER_DEVMASK: + return *(int *) arg = MIX_DEVS; + break; + + case SOUND_MIXER_STEREODEVS: + return *(int *) arg = SOUND_MASK_LINE | SOUND_MASK_CD | + SOUND_MASK_SYNTH | SOUND_MASK_VOLUME | SOUND_MASK_MIC; + break; + + case SOUND_MIXER_RECMASK: + return *(int *) arg = SOUND_MASK_MIC | SOUND_MASK_LINE; + break; + + case SOUND_MIXER_CAPS: + return *(int *) arg = 0; + break; + + case SOUND_MIXER_MIC: + return *(int *) arg = volumes[DEV_MIC]; + break; + + case SOUND_MIXER_LINE: + return *(int *) arg = volumes[DEV_LINE]; + break; + + case SOUND_MIXER_CD: + return *(int *) arg = volumes[DEV_CD]; + break; + + case SOUND_MIXER_VOLUME: + return *(int *) arg = volumes[DEV_VOL]; + break; + + case SOUND_MIXER_SYNTH: + return *(int *) arg = volumes[DEV_GF1]; + break; + + default: + return -(EINVAL); + } } - - return RET_ERROR (EINVAL); + return -(EINVAL); } static struct mixer_operations ics2101_mixer_operations = { - "ICS2101 Multimedia Mixer", - ics2101_mixer_ioctl + "ICS2101 Multimedia Mixer", + ics2101_mixer_ioctl }; -long -ics2101_mixer_init (long mem_start) +void +ics2101_mixer_init() { - int i; - - if (num_mixers < MAX_MIXER_DEV) - { - mixer_devs[num_mixers++] = &ics2101_mixer_operations; - - /* - * Some GUS v3.7 cards had some channels flipped. Disable - * the flipping feature if the model id is other than 5. - */ - - if (INB (u_MixSelect) != 5) - { - for (i = 0; i < ICS_MIXDEVS; i++) - left_fix[i] = 1; - for (i = 0; i < ICS_MIXDEVS; i++) - right_fix[i] = 2; - } + int i; - set_volumes (DEV_GF1, 0x5a5a); - set_volumes (DEV_CD, 0x5a5a); - set_volumes (DEV_MIC, 0x0000); - set_volumes (DEV_LINE, 0x5a5a); - set_volumes (DEV_VOL, 0x5a5a); - set_volumes (DEV_UNUSED, 0x0000); - } + if (num_mixers < MAX_MIXER_DEV) { + mixer_devs[num_mixers++] = &ics2101_mixer_operations; - return mem_start; + /* + * Some GUS v3.7 cards had some channels flipped. Disable the + * flipping feature if the model id is other than 5. + */ + + if (inb(u_MixSelect) != 5) { + for (i = 0; i < ICS_MIXDEVS; i++) + left_fix[i] = 1; + for (i = 0; i < ICS_MIXDEVS; i++) + right_fix[i] = 2; + } + set_volumes(DEV_GF1, 0x5a5a); + set_volumes(DEV_CD, 0x5a5a); + set_volumes(DEV_MIC, 0x0000); + set_volumes(DEV_LINE, 0x5a5a); + set_volumes(DEV_VOL, 0x5a5a); + set_volumes(DEV_UNUSED, 0x0000); + } } #endif |