summaryrefslogtreecommitdiffstats
path: root/drivers/sound/ics2101.c
diff options
context:
space:
mode:
authorRalf Baechle <ralf@linux-mips.org>1997-12-06 23:51:34 +0000
committerRalf Baechle <ralf@linux-mips.org>1997-12-06 23:51:34 +0000
commit230e5ab6a084ed50470f101934782dbf54b0d06b (patch)
tree5dd821c8d33f450470588e7a543f74bf74306e9e /drivers/sound/ics2101.c
parentc9b1c8a64c6444d189856f1e26bdcb8b4cd0113a (diff)
Merge with Linux 2.1.67.
Diffstat (limited to 'drivers/sound/ics2101.c')
-rw-r--r--drivers/sound/ics2101.c354
1 files changed, 169 insertions, 185 deletions
diff --git a/drivers/sound/ics2101.c b/drivers/sound/ics2101.c
index 07666ec29..3c47f5a50 100644
--- a/drivers/sound/ics2101.c
+++ b/drivers/sound/ics2101.c
@@ -14,7 +14,7 @@
#include "sound_config.h"
-#if defined(CONFIG_GUSHW)
+#if defined(CONFIG_GUSHW) || defined(MODULE)
#include <linux/ultrasound.h>
#include "gus_hw.h"
@@ -31,222 +31,206 @@ static int left_fix[ICS_MIXDEVS] =
static int right_fix[ICS_MIXDEVS] =
{2, 2, 2, 1, 2, 1};
-static int
-scale_vol (int vol)
+static int scale_vol(int vol)
{
- /*
- * 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)
+ /*
+ * 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)
{
- vol <<= 1;
- e--;
+ while (vol < 16)
+ {
+ vol <<= 1;
+ e--;
+ }
+ vol -= 16;
+ e += 7;
}
- vol -= 16;
- e += 7;
- }
- return ((e << 4) + vol);
+ return ((e << 4) + vol);
}
-static void
-write_mix (int dev, int chn, int vol)
+static void 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;
- }
-
- save_flags (flags);
- cli ();
- outb ((ctrl_addr), u_MixSelect);
- outb ((selector[dev]), u_MixData);
- outb ((attn_addr), u_MixSelect);
- outb (((unsigned char) vol), u_MixData);
- restore_flags (flags);
+ 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;
+ }
+
+ save_flags(flags);
+ cli();
+ outb((ctrl_addr), u_MixSelect);
+ outb((selector[dev]), u_MixData);
+ outb((attn_addr), u_MixSelect);
+ outb(((unsigned char) vol), u_MixData);
+ restore_flags(flags);
}
-static int
-set_volumes (int dev, int vol)
+static int 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;
+
+ 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;
}
-static int
-ics2101_mixer_ioctl (int dev, unsigned int cmd, caddr_t arg)
+static int ics2101_mixer_ioctl(int dev, unsigned int cmd, caddr_t arg)
{
- if (((cmd >> 8) & 0xff) == 'M')
- {
- if (_SIOC_DIR (cmd) & _SIOC_WRITE)
+ if (((cmd >> 8) & 0xff) == 'M')
{
- int val;
+ if (_SIOC_DIR(cmd) & _SIOC_WRITE)
+ {
+ int val;
+
+ val = *(int *) arg;
+
+ switch (cmd & 0xff)
+ {
+ case SOUND_MIXER_RECSRC:
+ return gus_default_mixer_ioctl(dev, cmd, arg);
+
+ case SOUND_MIXER_MIC:
+ return (*(int *) arg = set_volumes(DEV_MIC, val));
+
+ case SOUND_MIXER_CD:
+ return (*(int *) arg = set_volumes(DEV_CD, val));
- val = *(int *) arg;
+ case SOUND_MIXER_LINE:
+ return (*(int *) arg = set_volumes(DEV_LINE, val));
- switch (cmd & 0xff)
- {
- case SOUND_MIXER_RECSRC:
- return gus_default_mixer_ioctl (dev, cmd, arg);
- break;
+ case SOUND_MIXER_SYNTH:
+ return (*(int *) arg = set_volumes(DEV_GF1, val));
- case SOUND_MIXER_MIC:
- return (*(int *) arg = set_volumes (DEV_MIC, val));
- break;
+ case SOUND_MIXER_VOLUME:
+ return (*(int *) arg = set_volumes(DEV_VOL, val));
- case SOUND_MIXER_CD:
- return (*(int *) arg = set_volumes (DEV_CD, val));
- break;
+ default:
+ return -EINVAL;
+ }
+ }
+ else
+ {
+ switch (cmd & 0xff) /*
+ * Return parameters
+ */
+ {
- case SOUND_MIXER_LINE:
- return (*(int *) arg = set_volumes (DEV_LINE, val));
- break;
+ case SOUND_MIXER_RECSRC:
+ return gus_default_mixer_ioctl(dev, cmd, arg);
- case SOUND_MIXER_SYNTH:
- return (*(int *) arg = set_volumes (DEV_GF1, val));
- break;
+ case SOUND_MIXER_DEVMASK:
+ return (*(int *) arg = MIX_DEVS);
- case SOUND_MIXER_VOLUME:
- return (*(int *) arg = set_volumes (DEV_VOL, val));
- break;
+ case SOUND_MIXER_STEREODEVS:
+ return (*(int *) arg = SOUND_MASK_LINE | SOUND_MASK_CD | SOUND_MASK_SYNTH | SOUND_MASK_VOLUME | SOUND_MASK_MIC);
- default:
- return -EINVAL;
- }
+ case SOUND_MIXER_RECMASK:
+ return (*(int *) arg = SOUND_MASK_MIC | SOUND_MASK_LINE);
+
+ case SOUND_MIXER_CAPS:
+ return (*(int *) arg = 0);
+ break;
+
+ case SOUND_MIXER_MIC:
+ return (*(int *) arg = volumes[DEV_MIC]);
+
+ case SOUND_MIXER_LINE:
+ return (*(int *) arg = volumes[DEV_LINE]);
+
+ case SOUND_MIXER_CD:
+ return (*(int *) arg = volumes[DEV_CD]);
+
+ case SOUND_MIXER_VOLUME:
+ return (*(int *) arg = volumes[DEV_VOL]);
+
+ case SOUND_MIXER_SYNTH:
+ return (*(int *) arg = volumes[DEV_GF1]);
+
+ 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 -EINVAL;
+ return -EINVAL;
}
static struct mixer_operations ics2101_mixer_operations =
{
- "ICS2101",
- "ICS2101 Multimedia Mixer",
- ics2101_mixer_ioctl
+ "ICS2101",
+ "ICS2101 Multimedia Mixer",
+ ics2101_mixer_ioctl
};
-void
-ics2101_mixer_init (void)
+int
+ics2101_mixer_init(void)
{
- 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.
- */
+ int i;
+ int n;
- if (inb (u_MixSelect) != 5)
+ if ((n = sound_alloc_mixerdev()) != -1)
{
- for (i = 0; i < ICS_MIXDEVS; i++)
- left_fix[i] = 1;
- for (i = 0; i < ICS_MIXDEVS; i++)
- right_fix[i] = 2;
+ n = num_mixers;
+ mixer_devs[n] = &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;
+ }
+ 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);
}
-
- 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);
- }
-
+ return n;
}
#endif