19 #include <linux/slab.h>
23 #define __SB_MIXER_C__
30 #define SBPRO_RECORDING_DEVICES (SOUND_MASK_LINE | SOUND_MASK_MIC | SOUND_MASK_CD)
33 #define SGNXPRO_RECORDING_DEVICES SBPRO_RECORDING_DEVICES
35 #define SBPRO_MIXER_DEVICES (SOUND_MASK_SYNTH | SOUND_MASK_PCM | SOUND_MASK_LINE | SOUND_MASK_MIC | \
36 SOUND_MASK_CD | SOUND_MASK_VOLUME)
43 #define SGNXPRO_MIXER_DEVICES (SBPRO_MIXER_DEVICES|SOUND_MASK_BASS| \
44 SOUND_MASK_TREBLE|SOUND_MASK_SPEAKER )
46 #define SB16_RECORDING_DEVICES (SOUND_MASK_SYNTH | SOUND_MASK_LINE | SOUND_MASK_MIC | \
49 #define SB16_OUTFILTER_DEVICES (SOUND_MASK_LINE | SOUND_MASK_MIC | \
52 #define SB16_MIXER_DEVICES (SOUND_MASK_SYNTH | SOUND_MASK_PCM | SOUND_MASK_SPEAKER | SOUND_MASK_LINE | SOUND_MASK_MIC | \
54 SOUND_MASK_IGAIN | SOUND_MASK_OGAIN | \
55 SOUND_MASK_VOLUME | SOUND_MASK_BASS | SOUND_MASK_TREBLE | \
61 #define ALS007_MIXER_DEVICES (SOUND_MASK_SYNTH | SOUND_MASK_LINE | \
62 SOUND_MASK_PCM | SOUND_MASK_MIC | \
121 static int smg_default_levels[32] =
142 static int sb_default_levels[32] =
199 static char smw_mix_regs[] =
220 static int sbmixnum = 1;
222 static void sb_mixer_reset(
sb_devc * devc);
229 static int detect_mixer(
sb_devc * devc)
235 static void oss_change_bits(
sb_devc *devc,
unsigned char *
regval,
int dev,
int chn,
int newval)
240 mask = (1 << (*devc->
iomap)[dev][chn].nbits) - 1;
241 newval = (
int) ((newval * mask) + 50) / 100;
245 *regval &= ~(mask << shift);
246 *regval |= (newval &
mask) << shift;
249 static int sb_mixer_get(
sb_devc * devc,
int dev)
264 for (i = 0; i <
sizeof(smw_mix_regs); i++)
265 if (smw_mix_regs[i] != 0)
270 sb_mixer_reset(devc);
278 if ((dev < 0) || (dev >= devc->
iomap_sz))
287 oss_change_bits(devc, &val, dev,
LEFT_CHN, left);
299 return left | (left << 8);
307 oss_change_bits(devc, &val, dev,
RIGHT_CHN, right);
311 return left | (right << 8);
342 if (dev < 0 || dev >=
ARRAY_SIZE(smw_mix_regs))
344 reg = smw_mix_regs[
dev];
347 sb_setmixer(devc, reg, (24 - (24 * left / 100)) | 0x20);
348 sb_setmixer(devc, reg + 1, (24 - (24 * right / 100)) | 0x40);
352 return left | (right << 8);
355 static int sb_mixer_set(
sb_devc * devc,
int dev,
int value)
357 int left = value & 0x000000ff;
358 int right = (value & 0x0000ff00) >> 8;
366 if ((dev < 0) || (dev > 31))
375 switch (devc->
model) {
377 retval = smw_mixer_set(devc, dev, left, right);
393 static void set_recsrc(
sb_devc * devc,
int src)
398 static int set_recmask(
sb_devc * devc,
int mask)
401 unsigned char regimageL, regimageR;
482 regimageL = regimageR = 0;
485 if ((1 << i) & devmask)
487 regimageL |= sb16_recmasks_L[
i];
488 regimageR |= sb16_recmasks_R[
i];
500 static int set_outmask(
sb_devc * devc,
int mask)
503 unsigned char regimage;
517 if ((1 << i) & devmask)
519 regimage |= (sb16_recmasks_L[
i] | sb16_recmasks_R[
i]);
533 static int sb_mixer_ioctl(
int dev,
unsigned int cmd,
void __user *
arg)
556 if (devc->
minor < 15)
560 if (val == 0 || val == 1)
572 if (((cmd >> 8) & 0xff) ==
'M')
581 ret = set_recmask(devc, val);
585 ret = set_outmask(devc, val);
589 ret = sb_mixer_set(devc, cmd & 0xff, val);
592 else switch (cmd & 0xff)
628 ret = sb_mixer_get(devc, cmd & 0xff);
640 .name =
"Sound Blaster",
641 .ioctl = sb_mixer_ioctl
648 .name =
"Avance ALS-007",
649 .ioctl = sb_mixer_ioctl
652 static void sb_mixer_reset(
sb_devc * devc)
659 if (devc->
sbmo.sm_games)
665 sb_mixer_set(devc, i, devc->
levels[i]);
682 if (!(mixer_type = detect_mixer(devc)))
695 devc->
iomap = &sbpro_mix;
707 devc->
iomap = &sbpro_mix;
719 devc->
iomap = &sb16_mix;
725 devc->
iomap = &als007_mix;
758 sb_mixer_reset(devc);