4 * Driver for the ICS2101 mixer of GUS v3.7.
6 * Copyright by Hannu Savolainen 1994
8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted provided that the following conditions are
10 * met: 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer. 2.
12 * Redistributions in binary form must reproduce the above copyright notice,
13 * this list of conditions and the following disclaimer in the documentation
14 * and/or other materials provided with the distribution.
16 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND ANY
17 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19 * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR
20 * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
21 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
22 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
23 * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
24 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
25 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
30 #include <i386/isa/sound/sound_config.h>
32 #if defined(CONFIG_GUS)
34 #include <i386/isa/sound/ultrasound.h>
35 #include <i386/isa/sound/gus_hw.h>
37 #define MIX_DEVS (SOUND_MASK_MIC|SOUND_MASK_LINE| \
39 SOUND_MASK_CD | SOUND_MASK_VOLUME)
41 extern sound_os_info *gus_osp;
43 static int volumes[ICS_MIXDEVS];
44 static int left_fix[ICS_MIXDEVS] = {1, 1, 1, 2, 1, 2};
45 static int right_fix[ICS_MIXDEVS] = {2, 2, 2, 1, 2, 1};
51 * Experimental volume scaling by Risto Kankkunen. This should give
52 * smoother volume response than just a plain multiplication.
57 vol = (31 * vol + 50) / 100;
67 return ((e << 4) + vol);
71 write_mix(int dev, int chn, int vol)
75 int ctrl_addr = dev << 3;
76 int attn_addr = dev << 3;
80 if (chn == CHN_LEFT) {
91 outb(u_MixSelect, ctrl_addr);
92 outb(u_MixData, selector[dev]);
93 outb(u_MixSelect, attn_addr);
94 outb(u_MixData, (unsigned char) vol);
99 set_volumes(int dev, int vol)
101 int left = vol & 0x00ff;
102 int right = (vol >> 8) & 0x00ff;
104 RANGE (left, 0, 100);
105 RANGE (right, 0, 100);
107 write_mix(dev, CHN_LEFT, left);
108 write_mix(dev, CHN_RIGHT, right);
110 vol = left + (right << 8);
116 ics2101_mixer_ioctl(int dev, unsigned int cmd, ioctl_arg arg)
118 if (((cmd >> 8) & 0xff) == 'M') {
120 switch (cmd & 0xff) {
121 case SOUND_MIXER_RECSRC:
122 return gus_default_mixer_ioctl(dev, cmd, arg);
125 case SOUND_MIXER_MIC:
126 return *(int *) arg = set_volumes(DEV_MIC, (*(int *) arg));
130 return *(int *) arg = set_volumes(DEV_CD, (*(int *) arg));
133 case SOUND_MIXER_LINE:
134 return *(int *) arg = set_volumes(DEV_LINE, (*(int *) arg));
137 case SOUND_MIXER_SYNTH:
138 return *(int *) arg = set_volumes(DEV_GF1, (*(int *) arg));
141 case SOUND_MIXER_VOLUME:
142 return *(int *) arg = set_volumes(DEV_VOL, (*(int *) arg));
149 switch (cmd & 0xff) { /* Return parameters */
151 case SOUND_MIXER_RECSRC:
152 return gus_default_mixer_ioctl(dev, cmd, arg);
155 case SOUND_MIXER_DEVMASK:
156 return *(int *) arg = MIX_DEVS;
159 case SOUND_MIXER_STEREODEVS:
160 return *(int *) arg = SOUND_MASK_LINE | SOUND_MASK_CD |
161 SOUND_MASK_SYNTH | SOUND_MASK_VOLUME | SOUND_MASK_MIC;
164 case SOUND_MIXER_RECMASK:
165 return *(int *) arg = SOUND_MASK_MIC | SOUND_MASK_LINE;
168 case SOUND_MIXER_CAPS:
169 return *(int *) arg = 0;
172 case SOUND_MIXER_MIC:
173 return *(int *) arg = volumes[DEV_MIC];
176 case SOUND_MIXER_LINE:
177 return *(int *) arg = volumes[DEV_LINE];
181 return *(int *) arg = volumes[DEV_CD];
184 case SOUND_MIXER_VOLUME:
185 return *(int *) arg = volumes[DEV_VOL];
188 case SOUND_MIXER_SYNTH:
189 return *(int *) arg = volumes[DEV_GF1];
199 static struct mixer_operations ics2101_mixer_operations =
201 "ICS2101 Multimedia Mixer",
210 if (num_mixers < MAX_MIXER_DEV) {
211 mixer_devs[num_mixers++] = &ics2101_mixer_operations;
214 * Some GUS v3.7 cards had some channels flipped. Disable the
215 * flipping feature if the model id is other than 5.
218 if (inb(u_MixSelect) != 5) {
219 for (i = 0; i < ICS_MIXDEVS; i++)
221 for (i = 0; i < ICS_MIXDEVS; i++)
224 set_volumes(DEV_GF1, 0x5a5a);
225 set_volumes(DEV_CD, 0x5a5a);
226 set_volumes(DEV_MIC, 0x0000);
227 set_volumes(DEV_LINE, 0x5a5a);
228 set_volumes(DEV_VOL, 0x5a5a);
229 set_volumes(DEV_UNUSED, 0x0000);