This source file includes following definitions.
- scale_vol
- write_mix
- set_volumes
- ics2101_mixer_ioctl
- ics2101_mixer_init
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30 #include "sound_config.h"
31 #if defined(CONFIG_GUS)
32
33 #include <linux/ultrasound.h>
34 #include "gus_hw.h"
35
36 #define MIX_DEVS (SOUND_MASK_MIC|SOUND_MASK_LINE| \
37 SOUND_MASK_SYNTH| \
38 SOUND_MASK_CD | SOUND_MASK_VOLUME)
39
40 extern sound_os_info *gus_osp;
41 extern int gus_base;
42 static int volumes[ICS_MIXDEVS];
43 static int left_fix[ICS_MIXDEVS] =
44 {1, 1, 1, 2, 1, 2};
45 static int right_fix[ICS_MIXDEVS] =
46 {2, 2, 2, 1, 2, 1};
47
48 static int
49 scale_vol (int vol)
50 {
51
52
53
54
55
56 int e;
57
58 if (vol < 0)
59 vol = 0;
60 if (vol > 100)
61 vol = 100;
62 vol = (31 * vol + 50) / 100;
63 e = 0;
64 if (vol)
65 {
66 while (vol < 16)
67 {
68 vol <<= 1;
69 e--;
70 }
71 vol -= 16;
72 e += 7;
73 }
74 return ((e << 4) + vol);
75 }
76
77 static void
78 write_mix (int dev, int chn, int vol)
79 {
80 int *selector;
81 unsigned long flags;
82 int ctrl_addr = dev << 3;
83 int attn_addr = dev << 3;
84
85 vol = scale_vol (vol);
86
87 if (chn == CHN_LEFT)
88 {
89 selector = left_fix;
90 ctrl_addr |= 0x00;
91 attn_addr |= 0x02;
92 }
93 else
94 {
95 selector = right_fix;
96 ctrl_addr |= 0x01;
97 attn_addr |= 0x03;
98 }
99
100 save_flags (flags);
101 cli ();
102 outb (ctrl_addr, u_MixSelect);
103 outb (selector[dev], u_MixData);
104 outb (attn_addr, u_MixSelect);
105 outb ((unsigned char) vol, u_MixData);
106 restore_flags (flags);
107 }
108
109 static int
110 set_volumes (int dev, int vol)
111 {
112 int left = vol & 0x00ff;
113 int right = (vol >> 8) & 0x00ff;
114
115 if (left < 0)
116 left = 0;
117 if (left > 100)
118 left = 100;
119 if (right < 0)
120 right = 0;
121 if (right > 100)
122 right = 100;
123
124 write_mix (dev, CHN_LEFT, left);
125 write_mix (dev, CHN_RIGHT, right);
126
127 vol = left + (right << 8);
128 volumes[dev] = vol;
129 return vol;
130 }
131
132 static int
133 ics2101_mixer_ioctl (int dev, unsigned int cmd, ioctl_arg arg)
134 {
135 if (((cmd >> 8) & 0xff) == 'M')
136 {
137 if (_IOC_DIR (cmd) & _IOC_WRITE)
138 switch (cmd & 0xff)
139 {
140 case SOUND_MIXER_RECSRC:
141 return gus_default_mixer_ioctl (dev, cmd, arg);
142 break;
143
144 case SOUND_MIXER_MIC:
145 return snd_ioctl_return ((int *) arg, set_volumes (DEV_MIC, get_fs_long ((long *) arg)));
146 break;
147
148 case SOUND_MIXER_CD:
149 return snd_ioctl_return ((int *) arg, set_volumes (DEV_CD, get_fs_long ((long *) arg)));
150 break;
151
152 case SOUND_MIXER_LINE:
153 return snd_ioctl_return ((int *) arg, set_volumes (DEV_LINE, get_fs_long ((long *) arg)));
154 break;
155
156 case SOUND_MIXER_SYNTH:
157 return snd_ioctl_return ((int *) arg, set_volumes (DEV_GF1, get_fs_long ((long *) arg)));
158 break;
159
160 case SOUND_MIXER_VOLUME:
161 return snd_ioctl_return ((int *) arg, set_volumes (DEV_VOL, get_fs_long ((long *) arg)));
162 break;
163
164 default:
165 return -EINVAL;
166 }
167 else
168 switch (cmd & 0xff)
169
170
171 {
172
173 case SOUND_MIXER_RECSRC:
174 return gus_default_mixer_ioctl (dev, cmd, arg);
175 break;
176
177 case SOUND_MIXER_DEVMASK:
178 return snd_ioctl_return ((int *) arg, MIX_DEVS);
179 break;
180
181 case SOUND_MIXER_STEREODEVS:
182 return snd_ioctl_return ((int *) arg, SOUND_MASK_LINE | SOUND_MASK_CD | SOUND_MASK_SYNTH | SOUND_MASK_VOLUME | SOUND_MASK_MIC);
183 break;
184
185 case SOUND_MIXER_RECMASK:
186 return snd_ioctl_return ((int *) arg, SOUND_MASK_MIC | SOUND_MASK_LINE);
187 break;
188
189 case SOUND_MIXER_CAPS:
190 return snd_ioctl_return ((int *) arg, 0);
191 break;
192
193 case SOUND_MIXER_MIC:
194 return snd_ioctl_return ((int *) arg, volumes[DEV_MIC]);
195 break;
196
197 case SOUND_MIXER_LINE:
198 return snd_ioctl_return ((int *) arg, volumes[DEV_LINE]);
199 break;
200
201 case SOUND_MIXER_CD:
202 return snd_ioctl_return ((int *) arg, volumes[DEV_CD]);
203 break;
204
205 case SOUND_MIXER_VOLUME:
206 return snd_ioctl_return ((int *) arg, volumes[DEV_VOL]);
207 break;
208
209 case SOUND_MIXER_SYNTH:
210 return snd_ioctl_return ((int *) arg, volumes[DEV_GF1]);
211 break;
212
213 default:
214 return -EINVAL;
215 }
216 }
217
218 return -EINVAL;
219 }
220
221 static struct mixer_operations ics2101_mixer_operations =
222 {
223 "ICS2101 Multimedia Mixer",
224 ics2101_mixer_ioctl
225 };
226
227 long
228 ics2101_mixer_init (long mem_start)
229 {
230 int i;
231
232 if (num_mixers < MAX_MIXER_DEV)
233 {
234 mixer_devs[num_mixers++] = &ics2101_mixer_operations;
235
236
237
238
239
240
241 if (inb (u_MixSelect) != 5)
242 {
243 for (i = 0; i < ICS_MIXDEVS; i++)
244 left_fix[i] = 1;
245 for (i = 0; i < ICS_MIXDEVS; i++)
246 right_fix[i] = 2;
247 }
248
249 set_volumes (DEV_GF1, 0x5a5a);
250 set_volumes (DEV_CD, 0x5a5a);
251 set_volumes (DEV_MIC, 0x0000);
252 set_volumes (DEV_LINE, 0x5a5a);
253 set_volumes (DEV_VOL, 0x5a5a);
254 set_volumes (DEV_UNUSED, 0x0000);
255 }
256
257 return mem_start;
258 }
259
260 #endif