This source file includes following definitions.
- patch_build_controls
- reset_tlv
- ac97_update_bits_page
- ac97_surround_jack_mode_info
- ac97_surround_jack_mode_get
- ac97_surround_jack_mode_put
- ac97_channel_mode_info
- ac97_channel_mode_get
- ac97_channel_mode_put
- is_surround_on
- is_clfe_on
- is_shared_surrout
- is_shared_clfeout
- is_shared_linein
- is_shared_micin
- alc850_is_aux_back_surround
- snd_ac97_ymf7x3_info_speaker
- snd_ac97_ymf7x3_get_speaker
- snd_ac97_ymf7x3_put_speaker
- snd_ac97_ymf7x3_spdif_source_info
- snd_ac97_ymf7x3_spdif_source_get
- snd_ac97_ymf7x3_spdif_source_put
- patch_yamaha_ymf7x3_3d
- patch_yamaha_ymf743_build_spdif
- patch_yamaha_ymf743
- snd_ac97_ymf753_spdif_output_pin_info
- snd_ac97_ymf753_spdif_output_pin_get
- snd_ac97_ymf753_spdif_output_pin_put
- patch_yamaha_ymf753_post_spdif
- patch_yamaha_ymf753
- patch_wolfson_wm9703_specific
- patch_wolfson03
- patch_wolfson_wm9704_specific
- patch_wolfson04
- patch_wolfson05
- patch_wolfson_wm9711_specific
- patch_wolfson11
- patch_wolfson_wm9713_3d
- patch_wolfson_wm9713_specific
- patch_wolfson_wm9713_suspend
- patch_wolfson_wm9713_resume
- patch_wolfson13
- patch_tritech_tr28028
- patch_sigmatel_stac9700_3d
- patch_sigmatel_stac9708_3d
- patch_sigmatel_stac97xx_specific
- patch_sigmatel_stac9700
- snd_ac97_stac9708_put_bias
- patch_sigmatel_stac9708_specific
- patch_sigmatel_stac9708
- patch_sigmatel_stac9721
- patch_sigmatel_stac9744
- patch_sigmatel_stac9756
- snd_ac97_stac9758_output_jack_info
- snd_ac97_stac9758_output_jack_get
- snd_ac97_stac9758_output_jack_put
- snd_ac97_stac9758_input_jack_info
- snd_ac97_stac9758_input_jack_get
- snd_ac97_stac9758_input_jack_put
- snd_ac97_stac9758_phonesel_info
- snd_ac97_stac9758_phonesel_get
- snd_ac97_stac9758_phonesel_put
- patch_sigmatel_stac9758_specific
- patch_sigmatel_stac9758
- patch_cirrus_build_spdif
- patch_cirrus_spdif
- patch_cirrus_cs4299
- patch_conexant_build_spdif
- patch_conexant
- patch_cx20551
- ad18xx_resume
- ad1888_resume
- patch_ad1819
- patch_ad1881_unchained
- patch_ad1881_chained1
- patch_ad1881_chained
- patch_ad1881
- patch_ad1885_specific
- patch_ad1885
- patch_ad1886_specific
- patch_ad1886
- snd_ac97_ad198x_spdif_source_info
- snd_ac97_ad198x_spdif_source_get
- snd_ac97_ad198x_spdif_source_put
- patch_ad198x_post_spdif
- check_list
- patch_ad1981a_specific
- check_ad1981_hp_jack_sense
- patch_ad1981a
- patch_ad1981b_specific
- patch_ad1981b
- snd_ac97_ad1888_lohpsel_get
- snd_ac97_ad1888_lohpsel_put
- snd_ac97_ad1888_downmix_info
- snd_ac97_ad1888_downmix_get
- snd_ac97_ad1888_downmix_put
- ad1888_update_jacks
- patch_ad1888_specific
- patch_ad1888
- patch_ad1980_specific
- patch_ad1980
- snd_ac97_ad1985_vrefout_info
- snd_ac97_ad1985_vrefout_get
- snd_ac97_ad1985_vrefout_put
- ad1985_update_jacks
- patch_ad1985_specific
- patch_ad1985
- snd_ac97_ad1986_lososel_get
- snd_ac97_ad1986_lososel_put
- snd_ac97_ad1986_spread_get
- snd_ac97_ad1986_spread_put
- snd_ac97_ad1986_miclisel_get
- snd_ac97_ad1986_miclisel_put
- snd_ac97_ad1986_vrefout_get
- snd_ac97_ad1986_vrefout_put
- ad1986_update_jacks
- patch_ad1986_specific
- patch_ad1986
- patch_alc203
- alc650_update_jacks
- alc650_swap_surround_put
- patch_alc650_specific
- patch_alc650
- alc655_update_jacks
- alc655_iec958_route_info
- alc655_iec958_route_get
- alc655_iec958_route_put
- patch_alc655_specific
- patch_alc655
- alc850_update_jacks
- patch_alc850_specific
- patch_alc850
- patch_aztech_azf3328_specific
- patch_aztech_azf3328
- cm9738_update_jacks
- patch_cm9738_specific
- patch_cm9738
- snd_ac97_cmedia_spdif_playback_source_info
- snd_ac97_cmedia_spdif_playback_source_get
- snd_ac97_cmedia_spdif_playback_source_put
- cm9739_update_jacks
- patch_cm9739_specific
- patch_cm9739_post_spdif
- patch_cm9739
- cm9761_update_jacks
- cm9761_spdif_out_source_info
- cm9761_spdif_out_source_get
- cm9761_spdif_out_source_put
- patch_cm9761_post_spdif
- patch_cm9761_specific
- patch_cm9761
- patch_cm9780_specific
- patch_cm9780
- patch_vt1613_specific
- patch_vt1613
- snd_ac97_find_mixer_ctl
- snd_ac97_add_vmaster
- patch_vt1616_specific
- patch_vt1616
- snd_ac97_vt1617a_smart51_info
- snd_ac97_vt1617a_smart51_get
- snd_ac97_vt1617a_smart51_put
- patch_vt1617a
- snd_ac97_vt1618_UAJ_info
- snd_ac97_vt1618_UAJ_get
- snd_ac97_vt1618_UAJ_put
- snd_ac97_vt1618_aux_info
- snd_ac97_vt1618_aux_get
- snd_ac97_vt1618_aux_put
- patch_vt1618
- it2646_update_jacks
- patch_it2646_specific
- patch_it2646
- patch_si3036_specific
- mpatch_si3036
- patch_lm4550
- patch_ucb1400_specific
- patch_ucb1400
1
2
3
4
5
6
7
8
9
10
11 #include "ac97_local.h"
12 #include "ac97_patch.h"
13
14
15
16
17
18 static struct snd_kcontrol *snd_ac97_find_mixer_ctl(struct snd_ac97 *ac97,
19 const char *name);
20 static int snd_ac97_add_vmaster(struct snd_ac97 *ac97, char *name,
21 const unsigned int *tlv,
22 const char * const *slaves);
23
24
25
26
27
28 static int patch_build_controls(struct snd_ac97 * ac97, const struct snd_kcontrol_new *controls, int count)
29 {
30 int idx, err;
31
32 for (idx = 0; idx < count; idx++)
33 if ((err = snd_ctl_add(ac97->bus->card, snd_ac97_cnew(&controls[idx], ac97))) < 0)
34 return err;
35 return 0;
36 }
37
38
39 static void reset_tlv(struct snd_ac97 *ac97, const char *name,
40 const unsigned int *tlv)
41 {
42 struct snd_ctl_elem_id sid;
43 struct snd_kcontrol *kctl;
44 memset(&sid, 0, sizeof(sid));
45 strcpy(sid.name, name);
46 sid.iface = SNDRV_CTL_ELEM_IFACE_MIXER;
47 kctl = snd_ctl_find_id(ac97->bus->card, &sid);
48 if (kctl && kctl->tlv.p)
49 kctl->tlv.p = tlv;
50 }
51
52
53 static int ac97_update_bits_page(struct snd_ac97 *ac97, unsigned short reg, unsigned short mask, unsigned short value, unsigned short page)
54 {
55 unsigned short page_save;
56 int ret;
57
58 mutex_lock(&ac97->page_mutex);
59 page_save = snd_ac97_read(ac97, AC97_INT_PAGING) & AC97_PAGE_MASK;
60 snd_ac97_update_bits(ac97, AC97_INT_PAGING, AC97_PAGE_MASK, page);
61 ret = snd_ac97_update_bits(ac97, reg, mask, value);
62 snd_ac97_update_bits(ac97, AC97_INT_PAGING, AC97_PAGE_MASK, page_save);
63 mutex_unlock(&ac97->page_mutex);
64 return ret;
65 }
66
67
68
69
70 static int ac97_surround_jack_mode_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo)
71 {
72 static const char * const texts[] = { "Shared", "Independent" };
73
74 return snd_ctl_enum_info(uinfo, 1, 2, texts);
75 }
76
77 static int ac97_surround_jack_mode_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
78 {
79 struct snd_ac97 *ac97 = snd_kcontrol_chip(kcontrol);
80
81 ucontrol->value.enumerated.item[0] = ac97->indep_surround;
82 return 0;
83 }
84
85 static int ac97_surround_jack_mode_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
86 {
87 struct snd_ac97 *ac97 = snd_kcontrol_chip(kcontrol);
88 unsigned char indep = !!ucontrol->value.enumerated.item[0];
89
90 if (indep != ac97->indep_surround) {
91 ac97->indep_surround = indep;
92 if (ac97->build_ops->update_jacks)
93 ac97->build_ops->update_jacks(ac97);
94 return 1;
95 }
96 return 0;
97 }
98
99 static int ac97_channel_mode_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo)
100 {
101 static const char * const texts[] = { "2ch", "4ch", "6ch", "8ch" };
102
103 return snd_ctl_enum_info(uinfo, 1, kcontrol->private_value, texts);
104 }
105
106 static int ac97_channel_mode_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
107 {
108 struct snd_ac97 *ac97 = snd_kcontrol_chip(kcontrol);
109
110 ucontrol->value.enumerated.item[0] = ac97->channel_mode;
111 return 0;
112 }
113
114 static int ac97_channel_mode_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
115 {
116 struct snd_ac97 *ac97 = snd_kcontrol_chip(kcontrol);
117 unsigned char mode = ucontrol->value.enumerated.item[0];
118
119 if (mode >= kcontrol->private_value)
120 return -EINVAL;
121
122 if (mode != ac97->channel_mode) {
123 ac97->channel_mode = mode;
124 if (ac97->build_ops->update_jacks)
125 ac97->build_ops->update_jacks(ac97);
126 return 1;
127 }
128 return 0;
129 }
130
131 #define AC97_SURROUND_JACK_MODE_CTL \
132 { \
133 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
134 .name = "Surround Jack Mode", \
135 .info = ac97_surround_jack_mode_info, \
136 .get = ac97_surround_jack_mode_get, \
137 .put = ac97_surround_jack_mode_put, \
138 }
139
140 #define AC97_CHANNEL_MODE_CTL \
141 { \
142 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
143 .name = "Channel Mode", \
144 .info = ac97_channel_mode_info, \
145 .get = ac97_channel_mode_get, \
146 .put = ac97_channel_mode_put, \
147 .private_value = 3, \
148 }
149
150 #define AC97_CHANNEL_MODE_4CH_CTL \
151 { \
152 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
153 .name = "Channel Mode", \
154 .info = ac97_channel_mode_info, \
155 .get = ac97_channel_mode_get, \
156 .put = ac97_channel_mode_put, \
157 .private_value = 2, \
158 }
159
160 #define AC97_CHANNEL_MODE_8CH_CTL \
161 { \
162 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
163 .name = "Channel Mode", \
164 .info = ac97_channel_mode_info, \
165 .get = ac97_channel_mode_get, \
166 .put = ac97_channel_mode_put, \
167 .private_value = 4, \
168 }
169
170 static inline int is_surround_on(struct snd_ac97 *ac97)
171 {
172 return ac97->channel_mode >= 1;
173 }
174
175 static inline int is_clfe_on(struct snd_ac97 *ac97)
176 {
177 return ac97->channel_mode >= 2;
178 }
179
180
181 static inline int is_shared_surrout(struct snd_ac97 *ac97)
182 {
183 return !ac97->indep_surround && is_surround_on(ac97);
184 }
185
186
187 static inline int is_shared_clfeout(struct snd_ac97 *ac97)
188 {
189 return !ac97->indep_surround && is_clfe_on(ac97);
190 }
191
192
193 static inline int is_shared_linein(struct snd_ac97 *ac97)
194 {
195 return !ac97->indep_surround && !is_surround_on(ac97);
196 }
197
198
199 static inline int is_shared_micin(struct snd_ac97 *ac97)
200 {
201 return !ac97->indep_surround && !is_clfe_on(ac97);
202 }
203
204 static inline int alc850_is_aux_back_surround(struct snd_ac97 *ac97)
205 {
206 return is_surround_on(ac97);
207 }
208
209
210
211
212
213
214
215 static int snd_ac97_ymf7x3_info_speaker(struct snd_kcontrol *kcontrol,
216 struct snd_ctl_elem_info *uinfo)
217 {
218 static const char * const texts[3] = {
219 "Standard", "Small", "Smaller"
220 };
221
222 return snd_ctl_enum_info(uinfo, 1, 3, texts);
223 }
224
225 static int snd_ac97_ymf7x3_get_speaker(struct snd_kcontrol *kcontrol,
226 struct snd_ctl_elem_value *ucontrol)
227 {
228 struct snd_ac97 *ac97 = snd_kcontrol_chip(kcontrol);
229 unsigned short val;
230
231 val = ac97->regs[AC97_YMF7X3_3D_MODE_SEL];
232 val = (val >> 10) & 3;
233 if (val > 0)
234 val--;
235 ucontrol->value.enumerated.item[0] = val;
236 return 0;
237 }
238
239 static int snd_ac97_ymf7x3_put_speaker(struct snd_kcontrol *kcontrol,
240 struct snd_ctl_elem_value *ucontrol)
241 {
242 struct snd_ac97 *ac97 = snd_kcontrol_chip(kcontrol);
243 unsigned short val;
244
245 if (ucontrol->value.enumerated.item[0] > 2)
246 return -EINVAL;
247 val = (ucontrol->value.enumerated.item[0] + 1) << 10;
248 return snd_ac97_update(ac97, AC97_YMF7X3_3D_MODE_SEL, val);
249 }
250
251 static const struct snd_kcontrol_new snd_ac97_ymf7x3_controls_speaker =
252 {
253 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
254 .name = "3D Control - Speaker",
255 .info = snd_ac97_ymf7x3_info_speaker,
256 .get = snd_ac97_ymf7x3_get_speaker,
257 .put = snd_ac97_ymf7x3_put_speaker,
258 };
259
260
261
262 static int snd_ac97_ymf7x3_spdif_source_info(struct snd_kcontrol *kcontrol,
263 struct snd_ctl_elem_info *uinfo)
264 {
265 static const char * const texts[2] = { "AC-Link", "A/D Converter" };
266
267 return snd_ctl_enum_info(uinfo, 1, 2, texts);
268 }
269
270 static int snd_ac97_ymf7x3_spdif_source_get(struct snd_kcontrol *kcontrol,
271 struct snd_ctl_elem_value *ucontrol)
272 {
273 struct snd_ac97 *ac97 = snd_kcontrol_chip(kcontrol);
274 unsigned short val;
275
276 val = ac97->regs[AC97_YMF7X3_DIT_CTRL];
277 ucontrol->value.enumerated.item[0] = (val >> 1) & 1;
278 return 0;
279 }
280
281 static int snd_ac97_ymf7x3_spdif_source_put(struct snd_kcontrol *kcontrol,
282 struct snd_ctl_elem_value *ucontrol)
283 {
284 struct snd_ac97 *ac97 = snd_kcontrol_chip(kcontrol);
285 unsigned short val;
286
287 if (ucontrol->value.enumerated.item[0] > 1)
288 return -EINVAL;
289 val = ucontrol->value.enumerated.item[0] << 1;
290 return snd_ac97_update_bits(ac97, AC97_YMF7X3_DIT_CTRL, 0x0002, val);
291 }
292
293 static int patch_yamaha_ymf7x3_3d(struct snd_ac97 *ac97)
294 {
295 struct snd_kcontrol *kctl;
296 int err;
297
298 kctl = snd_ac97_cnew(&snd_ac97_controls_3d[0], ac97);
299 err = snd_ctl_add(ac97->bus->card, kctl);
300 if (err < 0)
301 return err;
302 strcpy(kctl->id.name, "3D Control - Wide");
303 kctl->private_value = AC97_SINGLE_VALUE(AC97_3D_CONTROL, 9, 7, 0);
304 snd_ac97_write_cache(ac97, AC97_3D_CONTROL, 0x0000);
305 err = snd_ctl_add(ac97->bus->card,
306 snd_ac97_cnew(&snd_ac97_ymf7x3_controls_speaker,
307 ac97));
308 if (err < 0)
309 return err;
310 snd_ac97_write_cache(ac97, AC97_YMF7X3_3D_MODE_SEL, 0x0c00);
311 return 0;
312 }
313
314 static const struct snd_kcontrol_new snd_ac97_yamaha_ymf743_controls_spdif[3] =
315 {
316 AC97_SINGLE(SNDRV_CTL_NAME_IEC958("", PLAYBACK, SWITCH),
317 AC97_YMF7X3_DIT_CTRL, 0, 1, 0),
318 {
319 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
320 .name = SNDRV_CTL_NAME_IEC958("", PLAYBACK, NONE) "Source",
321 .info = snd_ac97_ymf7x3_spdif_source_info,
322 .get = snd_ac97_ymf7x3_spdif_source_get,
323 .put = snd_ac97_ymf7x3_spdif_source_put,
324 },
325 AC97_SINGLE(SNDRV_CTL_NAME_IEC958("", NONE, NONE) "Mute",
326 AC97_YMF7X3_DIT_CTRL, 2, 1, 1)
327 };
328
329 static int patch_yamaha_ymf743_build_spdif(struct snd_ac97 *ac97)
330 {
331 int err;
332
333 err = patch_build_controls(ac97, &snd_ac97_controls_spdif[0], 3);
334 if (err < 0)
335 return err;
336 err = patch_build_controls(ac97,
337 snd_ac97_yamaha_ymf743_controls_spdif, 3);
338 if (err < 0)
339 return err;
340
341
342 snd_ac97_write_cache(ac97, AC97_YMF7X3_DIT_CTRL, 0xa201);
343 return 0;
344 }
345
346 static const struct snd_ac97_build_ops patch_yamaha_ymf743_ops = {
347 .build_spdif = patch_yamaha_ymf743_build_spdif,
348 .build_3d = patch_yamaha_ymf7x3_3d,
349 };
350
351 static int patch_yamaha_ymf743(struct snd_ac97 *ac97)
352 {
353 ac97->build_ops = &patch_yamaha_ymf743_ops;
354 ac97->caps |= AC97_BC_BASS_TREBLE;
355 ac97->caps |= 0x04 << 10;
356 ac97->rates[AC97_RATES_SPDIF] = SNDRV_PCM_RATE_48000;
357 ac97->ext_id |= AC97_EI_SPDIF;
358 return 0;
359 }
360
361
362
363
364
365 static int snd_ac97_ymf753_spdif_output_pin_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo)
366 {
367 static const char * const texts[3] = { "Disabled", "Pin 43", "Pin 48" };
368
369 return snd_ctl_enum_info(uinfo, 1, 3, texts);
370 }
371
372 static int snd_ac97_ymf753_spdif_output_pin_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
373 {
374 struct snd_ac97 *ac97 = snd_kcontrol_chip(kcontrol);
375 unsigned short val;
376
377 val = ac97->regs[AC97_YMF7X3_DIT_CTRL];
378 ucontrol->value.enumerated.item[0] = (val & 0x0008) ? 2 : (val & 0x0020) ? 1 : 0;
379 return 0;
380 }
381
382 static int snd_ac97_ymf753_spdif_output_pin_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
383 {
384 struct snd_ac97 *ac97 = snd_kcontrol_chip(kcontrol);
385 unsigned short val;
386
387 if (ucontrol->value.enumerated.item[0] > 2)
388 return -EINVAL;
389 val = (ucontrol->value.enumerated.item[0] == 2) ? 0x0008 :
390 (ucontrol->value.enumerated.item[0] == 1) ? 0x0020 : 0;
391 return snd_ac97_update_bits(ac97, AC97_YMF7X3_DIT_CTRL, 0x0028, val);
392
393
394 }
395
396 static const struct snd_kcontrol_new snd_ac97_ymf753_controls_spdif[3] = {
397 {
398 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
399 .name = SNDRV_CTL_NAME_IEC958("",PLAYBACK,NONE) "Source",
400 .info = snd_ac97_ymf7x3_spdif_source_info,
401 .get = snd_ac97_ymf7x3_spdif_source_get,
402 .put = snd_ac97_ymf7x3_spdif_source_put,
403 },
404 {
405 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
406 .name = SNDRV_CTL_NAME_IEC958("",PLAYBACK,NONE) "Output Pin",
407 .info = snd_ac97_ymf753_spdif_output_pin_info,
408 .get = snd_ac97_ymf753_spdif_output_pin_get,
409 .put = snd_ac97_ymf753_spdif_output_pin_put,
410 },
411 AC97_SINGLE(SNDRV_CTL_NAME_IEC958("", NONE, NONE) "Mute",
412 AC97_YMF7X3_DIT_CTRL, 2, 1, 1)
413 };
414
415 static int patch_yamaha_ymf753_post_spdif(struct snd_ac97 * ac97)
416 {
417 int err;
418
419 if ((err = patch_build_controls(ac97, snd_ac97_ymf753_controls_spdif, ARRAY_SIZE(snd_ac97_ymf753_controls_spdif))) < 0)
420 return err;
421 return 0;
422 }
423
424 static const struct snd_ac97_build_ops patch_yamaha_ymf753_ops = {
425 .build_3d = patch_yamaha_ymf7x3_3d,
426 .build_post_spdif = patch_yamaha_ymf753_post_spdif
427 };
428
429 static int patch_yamaha_ymf753(struct snd_ac97 * ac97)
430 {
431
432
433
434
435
436
437
438 ac97->build_ops = &patch_yamaha_ymf753_ops;
439 ac97->caps |= AC97_BC_BASS_TREBLE;
440 ac97->caps |= 0x04 << 10;
441 return 0;
442 }
443
444
445
446
447
448
449
450 static const struct snd_kcontrol_new wm97xx_snd_ac97_controls[] = {
451 AC97_DOUBLE("Front Playback Volume", AC97_WM97XX_FMIXER_VOL, 8, 0, 31, 1),
452 AC97_SINGLE("Front Playback Switch", AC97_WM97XX_FMIXER_VOL, 15, 1, 1),
453 };
454
455 static int patch_wolfson_wm9703_specific(struct snd_ac97 * ac97)
456 {
457
458
459
460
461 int err, i;
462
463 for (i = 0; i < ARRAY_SIZE(wm97xx_snd_ac97_controls); i++) {
464 if ((err = snd_ctl_add(ac97->bus->card, snd_ac97_cnew(&wm97xx_snd_ac97_controls[i], ac97))) < 0)
465 return err;
466 }
467 snd_ac97_write_cache(ac97, AC97_WM97XX_FMIXER_VOL, 0x0808);
468 return 0;
469 }
470
471 static const struct snd_ac97_build_ops patch_wolfson_wm9703_ops = {
472 .build_specific = patch_wolfson_wm9703_specific,
473 };
474
475 static int patch_wolfson03(struct snd_ac97 * ac97)
476 {
477 ac97->build_ops = &patch_wolfson_wm9703_ops;
478 return 0;
479 }
480
481 static const struct snd_kcontrol_new wm9704_snd_ac97_controls[] = {
482 AC97_DOUBLE("Front Playback Volume", AC97_WM97XX_FMIXER_VOL, 8, 0, 31, 1),
483 AC97_SINGLE("Front Playback Switch", AC97_WM97XX_FMIXER_VOL, 15, 1, 1),
484 AC97_DOUBLE("Rear Playback Volume", AC97_WM9704_RMIXER_VOL, 8, 0, 31, 1),
485 AC97_SINGLE("Rear Playback Switch", AC97_WM9704_RMIXER_VOL, 15, 1, 1),
486 AC97_DOUBLE("Rear DAC Volume", AC97_WM9704_RPCM_VOL, 8, 0, 31, 1),
487 AC97_DOUBLE("Surround Volume", AC97_SURROUND_MASTER, 8, 0, 31, 1),
488 };
489
490 static int patch_wolfson_wm9704_specific(struct snd_ac97 * ac97)
491 {
492 int err, i;
493 for (i = 0; i < ARRAY_SIZE(wm9704_snd_ac97_controls); i++) {
494 if ((err = snd_ctl_add(ac97->bus->card, snd_ac97_cnew(&wm9704_snd_ac97_controls[i], ac97))) < 0)
495 return err;
496 }
497
498 snd_ac97_write_cache(ac97, AC97_WM9704_TEST, 0x0200);
499 return 0;
500 }
501
502 static const struct snd_ac97_build_ops patch_wolfson_wm9704_ops = {
503 .build_specific = patch_wolfson_wm9704_specific,
504 };
505
506 static int patch_wolfson04(struct snd_ac97 * ac97)
507 {
508
509 ac97->build_ops = &patch_wolfson_wm9704_ops;
510 return 0;
511 }
512
513 static int patch_wolfson05(struct snd_ac97 * ac97)
514 {
515
516 ac97->build_ops = &patch_wolfson_wm9703_ops;
517 #ifdef CONFIG_TOUCHSCREEN_WM9705
518
519 ac97->flags |= AC97_HAS_NO_VIDEO | AC97_HAS_NO_AUX;
520 #endif
521 return 0;
522 }
523
524 static const char* wm9711_alc_select[] = {"None", "Left", "Right", "Stereo"};
525 static const char* wm9711_alc_mix[] = {"Stereo", "Right", "Left", "None"};
526 static const char* wm9711_out3_src[] = {"Left", "VREF", "Left + Right", "Mono"};
527 static const char* wm9711_out3_lrsrc[] = {"Master Mix", "Headphone Mix"};
528 static const char* wm9711_rec_adc[] = {"Stereo", "Left", "Right", "Mute"};
529 static const char* wm9711_base[] = {"Linear Control", "Adaptive Boost"};
530 static const char* wm9711_rec_gain[] = {"+1.5dB Steps", "+0.75dB Steps"};
531 static const char* wm9711_mic[] = {"Mic 1", "Differential", "Mic 2", "Stereo"};
532 static const char* wm9711_rec_sel[] =
533 {"Mic 1", "NC", "NC", "Master Mix", "Line", "Headphone Mix", "Phone Mix", "Phone"};
534 static const char* wm9711_ng_type[] = {"Constant Gain", "Mute"};
535
536 static const struct ac97_enum wm9711_enum[] = {
537 AC97_ENUM_SINGLE(AC97_PCI_SVID, 14, 4, wm9711_alc_select),
538 AC97_ENUM_SINGLE(AC97_VIDEO, 10, 4, wm9711_alc_mix),
539 AC97_ENUM_SINGLE(AC97_AUX, 9, 4, wm9711_out3_src),
540 AC97_ENUM_SINGLE(AC97_AUX, 8, 2, wm9711_out3_lrsrc),
541 AC97_ENUM_SINGLE(AC97_REC_SEL, 12, 4, wm9711_rec_adc),
542 AC97_ENUM_SINGLE(AC97_MASTER_TONE, 15, 2, wm9711_base),
543 AC97_ENUM_DOUBLE(AC97_REC_GAIN, 14, 6, 2, wm9711_rec_gain),
544 AC97_ENUM_SINGLE(AC97_MIC, 5, 4, wm9711_mic),
545 AC97_ENUM_DOUBLE(AC97_REC_SEL, 8, 0, 8, wm9711_rec_sel),
546 AC97_ENUM_SINGLE(AC97_PCI_SVID, 5, 2, wm9711_ng_type),
547 };
548
549 static const struct snd_kcontrol_new wm9711_snd_ac97_controls[] = {
550 AC97_SINGLE("ALC Target Volume", AC97_CODEC_CLASS_REV, 12, 15, 0),
551 AC97_SINGLE("ALC Hold Time", AC97_CODEC_CLASS_REV, 8, 15, 0),
552 AC97_SINGLE("ALC Decay Time", AC97_CODEC_CLASS_REV, 4, 15, 0),
553 AC97_SINGLE("ALC Attack Time", AC97_CODEC_CLASS_REV, 0, 15, 0),
554 AC97_ENUM("ALC Function", wm9711_enum[0]),
555 AC97_SINGLE("ALC Max Volume", AC97_PCI_SVID, 11, 7, 1),
556 AC97_SINGLE("ALC ZC Timeout", AC97_PCI_SVID, 9, 3, 1),
557 AC97_SINGLE("ALC ZC Switch", AC97_PCI_SVID, 8, 1, 0),
558 AC97_SINGLE("ALC NG Switch", AC97_PCI_SVID, 7, 1, 0),
559 AC97_ENUM("ALC NG Type", wm9711_enum[9]),
560 AC97_SINGLE("ALC NG Threshold", AC97_PCI_SVID, 0, 31, 1),
561
562 AC97_SINGLE("Side Tone Switch", AC97_VIDEO, 15, 1, 1),
563 AC97_SINGLE("Side Tone Volume", AC97_VIDEO, 12, 7, 1),
564 AC97_ENUM("ALC Headphone Mux", wm9711_enum[1]),
565 AC97_SINGLE("ALC Headphone Volume", AC97_VIDEO, 7, 7, 1),
566
567 AC97_SINGLE("Out3 Switch", AC97_AUX, 15, 1, 1),
568 AC97_SINGLE("Out3 ZC Switch", AC97_AUX, 7, 1, 0),
569 AC97_ENUM("Out3 Mux", wm9711_enum[2]),
570 AC97_ENUM("Out3 LR Mux", wm9711_enum[3]),
571 AC97_SINGLE("Out3 Volume", AC97_AUX, 0, 31, 1),
572
573 AC97_SINGLE("Beep to Headphone Switch", AC97_PC_BEEP, 15, 1, 1),
574 AC97_SINGLE("Beep to Headphone Volume", AC97_PC_BEEP, 12, 7, 1),
575 AC97_SINGLE("Beep to Side Tone Switch", AC97_PC_BEEP, 11, 1, 1),
576 AC97_SINGLE("Beep to Side Tone Volume", AC97_PC_BEEP, 8, 7, 1),
577 AC97_SINGLE("Beep to Phone Switch", AC97_PC_BEEP, 7, 1, 1),
578 AC97_SINGLE("Beep to Phone Volume", AC97_PC_BEEP, 4, 7, 1),
579
580 AC97_SINGLE("Aux to Headphone Switch", AC97_CD, 15, 1, 1),
581 AC97_SINGLE("Aux to Headphone Volume", AC97_CD, 12, 7, 1),
582 AC97_SINGLE("Aux to Side Tone Switch", AC97_CD, 11, 1, 1),
583 AC97_SINGLE("Aux to Side Tone Volume", AC97_CD, 8, 7, 1),
584 AC97_SINGLE("Aux to Phone Switch", AC97_CD, 7, 1, 1),
585 AC97_SINGLE("Aux to Phone Volume", AC97_CD, 4, 7, 1),
586
587 AC97_SINGLE("Phone to Headphone Switch", AC97_PHONE, 15, 1, 1),
588 AC97_SINGLE("Phone to Master Switch", AC97_PHONE, 14, 1, 1),
589
590 AC97_SINGLE("Line to Headphone Switch", AC97_LINE, 15, 1, 1),
591 AC97_SINGLE("Line to Master Switch", AC97_LINE, 14, 1, 1),
592 AC97_SINGLE("Line to Phone Switch", AC97_LINE, 13, 1, 1),
593
594 AC97_SINGLE("PCM Playback to Headphone Switch", AC97_PCM, 15, 1, 1),
595 AC97_SINGLE("PCM Playback to Master Switch", AC97_PCM, 14, 1, 1),
596 AC97_SINGLE("PCM Playback to Phone Switch", AC97_PCM, 13, 1, 1),
597
598 AC97_SINGLE("Capture 20dB Boost Switch", AC97_REC_SEL, 14, 1, 0),
599 AC97_ENUM("Capture to Phone Mux", wm9711_enum[4]),
600 AC97_SINGLE("Capture to Phone 20dB Boost Switch", AC97_REC_SEL, 11, 1, 1),
601 AC97_ENUM("Capture Select", wm9711_enum[8]),
602
603 AC97_SINGLE("3D Upper Cut-off Switch", AC97_3D_CONTROL, 5, 1, 1),
604 AC97_SINGLE("3D Lower Cut-off Switch", AC97_3D_CONTROL, 4, 1, 1),
605
606 AC97_ENUM("Bass Control", wm9711_enum[5]),
607 AC97_SINGLE("Bass Cut-off Switch", AC97_MASTER_TONE, 12, 1, 1),
608 AC97_SINGLE("Tone Cut-off Switch", AC97_MASTER_TONE, 4, 1, 1),
609 AC97_SINGLE("Playback Attenuate (-6dB) Switch", AC97_MASTER_TONE, 6, 1, 0),
610
611 AC97_SINGLE("ADC Switch", AC97_REC_GAIN, 15, 1, 1),
612 AC97_ENUM("Capture Volume Steps", wm9711_enum[6]),
613 AC97_DOUBLE("Capture Volume", AC97_REC_GAIN, 8, 0, 63, 1),
614 AC97_SINGLE("Capture ZC Switch", AC97_REC_GAIN, 7, 1, 0),
615
616 AC97_SINGLE("Mic 1 to Phone Switch", AC97_MIC, 14, 1, 1),
617 AC97_SINGLE("Mic 2 to Phone Switch", AC97_MIC, 13, 1, 1),
618 AC97_ENUM("Mic Select Source", wm9711_enum[7]),
619 AC97_SINGLE("Mic 1 Volume", AC97_MIC, 8, 31, 1),
620 AC97_SINGLE("Mic 2 Volume", AC97_MIC, 0, 31, 1),
621 AC97_SINGLE("Mic 20dB Boost Switch", AC97_MIC, 7, 1, 0),
622
623 AC97_SINGLE("Master Left Inv Switch", AC97_MASTER, 6, 1, 0),
624 AC97_SINGLE("Master ZC Switch", AC97_MASTER, 7, 1, 0),
625 AC97_SINGLE("Headphone ZC Switch", AC97_HEADPHONE, 7, 1, 0),
626 AC97_SINGLE("Mono ZC Switch", AC97_MASTER_MONO, 7, 1, 0),
627 };
628
629 static int patch_wolfson_wm9711_specific(struct snd_ac97 * ac97)
630 {
631 int err, i;
632
633 for (i = 0; i < ARRAY_SIZE(wm9711_snd_ac97_controls); i++) {
634 if ((err = snd_ctl_add(ac97->bus->card, snd_ac97_cnew(&wm9711_snd_ac97_controls[i], ac97))) < 0)
635 return err;
636 }
637 snd_ac97_write_cache(ac97, AC97_CODEC_CLASS_REV, 0x0808);
638 snd_ac97_write_cache(ac97, AC97_PCI_SVID, 0x0808);
639 snd_ac97_write_cache(ac97, AC97_VIDEO, 0x0808);
640 snd_ac97_write_cache(ac97, AC97_AUX, 0x0808);
641 snd_ac97_write_cache(ac97, AC97_PC_BEEP, 0x0808);
642 snd_ac97_write_cache(ac97, AC97_CD, 0x0000);
643 return 0;
644 }
645
646 static const struct snd_ac97_build_ops patch_wolfson_wm9711_ops = {
647 .build_specific = patch_wolfson_wm9711_specific,
648 };
649
650 static int patch_wolfson11(struct snd_ac97 * ac97)
651 {
652
653 ac97->build_ops = &patch_wolfson_wm9711_ops;
654
655 ac97->flags |= AC97_HAS_NO_REC_GAIN | AC97_STEREO_MUTES | AC97_HAS_NO_MIC |
656 AC97_HAS_NO_PC_BEEP | AC97_HAS_NO_VIDEO | AC97_HAS_NO_CD;
657
658 return 0;
659 }
660
661 static const char* wm9713_mic_mixer[] = {"Stereo", "Mic 1", "Mic 2", "Mute"};
662 static const char* wm9713_rec_mux[] = {"Stereo", "Left", "Right", "Mute"};
663 static const char* wm9713_rec_src[] =
664 {"Mic 1", "Mic 2", "Line", "Mono In", "Headphone Mix", "Master Mix",
665 "Mono Mix", "Zh"};
666 static const char* wm9713_rec_gain[] = {"+1.5dB Steps", "+0.75dB Steps"};
667 static const char* wm9713_alc_select[] = {"None", "Left", "Right", "Stereo"};
668 static const char* wm9713_mono_pga[] = {"Vmid", "Zh", "Mono Mix", "Inv 1"};
669 static const char* wm9713_spk_pga[] =
670 {"Vmid", "Zh", "Headphone Mix", "Master Mix", "Inv", "NC", "NC", "NC"};
671 static const char* wm9713_hp_pga[] = {"Vmid", "Zh", "Headphone Mix", "NC"};
672 static const char* wm9713_out3_pga[] = {"Vmid", "Zh", "Inv 1", "NC"};
673 static const char* wm9713_out4_pga[] = {"Vmid", "Zh", "Inv 2", "NC"};
674 static const char* wm9713_dac_inv[] =
675 {"Off", "Mono Mix", "Master Mix", "Headphone Mix L", "Headphone Mix R",
676 "Headphone Mix Mono", "NC", "Vmid"};
677 static const char* wm9713_base[] = {"Linear Control", "Adaptive Boost"};
678 static const char* wm9713_ng_type[] = {"Constant Gain", "Mute"};
679
680 static const struct ac97_enum wm9713_enum[] = {
681 AC97_ENUM_SINGLE(AC97_LINE, 3, 4, wm9713_mic_mixer),
682 AC97_ENUM_SINGLE(AC97_VIDEO, 14, 4, wm9713_rec_mux),
683 AC97_ENUM_SINGLE(AC97_VIDEO, 9, 4, wm9713_rec_mux),
684 AC97_ENUM_DOUBLE(AC97_VIDEO, 3, 0, 8, wm9713_rec_src),
685 AC97_ENUM_DOUBLE(AC97_CD, 14, 6, 2, wm9713_rec_gain),
686 AC97_ENUM_SINGLE(AC97_PCI_SVID, 14, 4, wm9713_alc_select),
687 AC97_ENUM_SINGLE(AC97_REC_GAIN, 14, 4, wm9713_mono_pga),
688 AC97_ENUM_DOUBLE(AC97_REC_GAIN, 11, 8, 8, wm9713_spk_pga),
689 AC97_ENUM_DOUBLE(AC97_REC_GAIN, 6, 4, 4, wm9713_hp_pga),
690 AC97_ENUM_SINGLE(AC97_REC_GAIN, 2, 4, wm9713_out3_pga),
691 AC97_ENUM_SINGLE(AC97_REC_GAIN, 0, 4, wm9713_out4_pga),
692 AC97_ENUM_DOUBLE(AC97_REC_GAIN_MIC, 13, 10, 8, wm9713_dac_inv),
693 AC97_ENUM_SINGLE(AC97_GENERAL_PURPOSE, 15, 2, wm9713_base),
694 AC97_ENUM_SINGLE(AC97_PCI_SVID, 5, 2, wm9713_ng_type),
695 };
696
697 static const struct snd_kcontrol_new wm13_snd_ac97_controls[] = {
698 AC97_DOUBLE("Line In Volume", AC97_PC_BEEP, 8, 0, 31, 1),
699 AC97_SINGLE("Line In to Headphone Switch", AC97_PC_BEEP, 15, 1, 1),
700 AC97_SINGLE("Line In to Master Switch", AC97_PC_BEEP, 14, 1, 1),
701 AC97_SINGLE("Line In to Mono Switch", AC97_PC_BEEP, 13, 1, 1),
702
703 AC97_DOUBLE("PCM Playback Volume", AC97_PHONE, 8, 0, 31, 1),
704 AC97_SINGLE("PCM Playback to Headphone Switch", AC97_PHONE, 15, 1, 1),
705 AC97_SINGLE("PCM Playback to Master Switch", AC97_PHONE, 14, 1, 1),
706 AC97_SINGLE("PCM Playback to Mono Switch", AC97_PHONE, 13, 1, 1),
707
708 AC97_SINGLE("Mic 1 Volume", AC97_MIC, 8, 31, 1),
709 AC97_SINGLE("Mic 2 Volume", AC97_MIC, 0, 31, 1),
710 AC97_SINGLE("Mic 1 to Mono Switch", AC97_LINE, 7, 1, 1),
711 AC97_SINGLE("Mic 2 to Mono Switch", AC97_LINE, 6, 1, 1),
712 AC97_SINGLE("Mic Boost (+20dB) Switch", AC97_LINE, 5, 1, 0),
713 AC97_ENUM("Mic to Headphone Mux", wm9713_enum[0]),
714 AC97_SINGLE("Mic Headphone Mixer Volume", AC97_LINE, 0, 7, 1),
715
716 AC97_SINGLE("Capture Switch", AC97_CD, 15, 1, 1),
717 AC97_ENUM("Capture Volume Steps", wm9713_enum[4]),
718 AC97_DOUBLE("Capture Volume", AC97_CD, 8, 0, 15, 0),
719 AC97_SINGLE("Capture ZC Switch", AC97_CD, 7, 1, 0),
720
721 AC97_ENUM("Capture to Headphone Mux", wm9713_enum[1]),
722 AC97_SINGLE("Capture to Headphone Volume", AC97_VIDEO, 11, 7, 1),
723 AC97_ENUM("Capture to Mono Mux", wm9713_enum[2]),
724 AC97_SINGLE("Capture to Mono Boost (+20dB) Switch", AC97_VIDEO, 8, 1, 0),
725 AC97_SINGLE("Capture ADC Boost (+20dB) Switch", AC97_VIDEO, 6, 1, 0),
726 AC97_ENUM("Capture Select", wm9713_enum[3]),
727
728 AC97_SINGLE("ALC Target Volume", AC97_CODEC_CLASS_REV, 12, 15, 0),
729 AC97_SINGLE("ALC Hold Time", AC97_CODEC_CLASS_REV, 8, 15, 0),
730 AC97_SINGLE("ALC Decay Time ", AC97_CODEC_CLASS_REV, 4, 15, 0),
731 AC97_SINGLE("ALC Attack Time", AC97_CODEC_CLASS_REV, 0, 15, 0),
732 AC97_ENUM("ALC Function", wm9713_enum[5]),
733 AC97_SINGLE("ALC Max Volume", AC97_PCI_SVID, 11, 7, 0),
734 AC97_SINGLE("ALC ZC Timeout", AC97_PCI_SVID, 9, 3, 0),
735 AC97_SINGLE("ALC ZC Switch", AC97_PCI_SVID, 8, 1, 0),
736 AC97_SINGLE("ALC NG Switch", AC97_PCI_SVID, 7, 1, 0),
737 AC97_ENUM("ALC NG Type", wm9713_enum[13]),
738 AC97_SINGLE("ALC NG Threshold", AC97_PCI_SVID, 0, 31, 0),
739
740 AC97_DOUBLE("Master ZC Switch", AC97_MASTER, 14, 6, 1, 0),
741 AC97_DOUBLE("Headphone ZC Switch", AC97_HEADPHONE, 14, 6, 1, 0),
742 AC97_DOUBLE("Out3/4 ZC Switch", AC97_MASTER_MONO, 14, 6, 1, 0),
743 AC97_SINGLE("Master Right Switch", AC97_MASTER, 7, 1, 1),
744 AC97_SINGLE("Headphone Right Switch", AC97_HEADPHONE, 7, 1, 1),
745 AC97_SINGLE("Out3/4 Right Switch", AC97_MASTER_MONO, 7, 1, 1),
746
747 AC97_SINGLE("Mono In to Headphone Switch", AC97_MASTER_TONE, 15, 1, 1),
748 AC97_SINGLE("Mono In to Master Switch", AC97_MASTER_TONE, 14, 1, 1),
749 AC97_SINGLE("Mono In Volume", AC97_MASTER_TONE, 8, 31, 1),
750 AC97_SINGLE("Mono Switch", AC97_MASTER_TONE, 7, 1, 1),
751 AC97_SINGLE("Mono ZC Switch", AC97_MASTER_TONE, 6, 1, 0),
752 AC97_SINGLE("Mono Volume", AC97_MASTER_TONE, 0, 31, 1),
753
754 AC97_SINGLE("Beep to Headphone Switch", AC97_AUX, 15, 1, 1),
755 AC97_SINGLE("Beep to Headphone Volume", AC97_AUX, 12, 7, 1),
756 AC97_SINGLE("Beep to Master Switch", AC97_AUX, 11, 1, 1),
757 AC97_SINGLE("Beep to Master Volume", AC97_AUX, 8, 7, 1),
758 AC97_SINGLE("Beep to Mono Switch", AC97_AUX, 7, 1, 1),
759 AC97_SINGLE("Beep to Mono Volume", AC97_AUX, 4, 7, 1),
760
761 AC97_SINGLE("Voice to Headphone Switch", AC97_PCM, 15, 1, 1),
762 AC97_SINGLE("Voice to Headphone Volume", AC97_PCM, 12, 7, 1),
763 AC97_SINGLE("Voice to Master Switch", AC97_PCM, 11, 1, 1),
764 AC97_SINGLE("Voice to Master Volume", AC97_PCM, 8, 7, 1),
765 AC97_SINGLE("Voice to Mono Switch", AC97_PCM, 7, 1, 1),
766 AC97_SINGLE("Voice to Mono Volume", AC97_PCM, 4, 7, 1),
767
768 AC97_SINGLE("Aux to Headphone Switch", AC97_REC_SEL, 15, 1, 1),
769 AC97_SINGLE("Aux to Headphone Volume", AC97_REC_SEL, 12, 7, 1),
770 AC97_SINGLE("Aux to Master Switch", AC97_REC_SEL, 11, 1, 1),
771 AC97_SINGLE("Aux to Master Volume", AC97_REC_SEL, 8, 7, 1),
772 AC97_SINGLE("Aux to Mono Switch", AC97_REC_SEL, 7, 1, 1),
773 AC97_SINGLE("Aux to Mono Volume", AC97_REC_SEL, 4, 7, 1),
774
775 AC97_ENUM("Mono Input Mux", wm9713_enum[6]),
776 AC97_ENUM("Master Input Mux", wm9713_enum[7]),
777 AC97_ENUM("Headphone Input Mux", wm9713_enum[8]),
778 AC97_ENUM("Out 3 Input Mux", wm9713_enum[9]),
779 AC97_ENUM("Out 4 Input Mux", wm9713_enum[10]),
780
781 AC97_ENUM("Bass Control", wm9713_enum[12]),
782 AC97_SINGLE("Bass Cut-off Switch", AC97_GENERAL_PURPOSE, 12, 1, 1),
783 AC97_SINGLE("Tone Cut-off Switch", AC97_GENERAL_PURPOSE, 4, 1, 1),
784 AC97_SINGLE("Playback Attenuate (-6dB) Switch", AC97_GENERAL_PURPOSE, 6, 1, 0),
785 AC97_SINGLE("Bass Volume", AC97_GENERAL_PURPOSE, 8, 15, 1),
786 AC97_SINGLE("Tone Volume", AC97_GENERAL_PURPOSE, 0, 15, 1),
787 };
788
789 static const struct snd_kcontrol_new wm13_snd_ac97_controls_3d[] = {
790 AC97_ENUM("Inv Input Mux", wm9713_enum[11]),
791 AC97_SINGLE("3D Upper Cut-off Switch", AC97_REC_GAIN_MIC, 5, 1, 0),
792 AC97_SINGLE("3D Lower Cut-off Switch", AC97_REC_GAIN_MIC, 4, 1, 0),
793 AC97_SINGLE("3D Depth", AC97_REC_GAIN_MIC, 0, 15, 1),
794 };
795
796 static int patch_wolfson_wm9713_3d (struct snd_ac97 * ac97)
797 {
798 int err, i;
799
800 for (i = 0; i < ARRAY_SIZE(wm13_snd_ac97_controls_3d); i++) {
801 if ((err = snd_ctl_add(ac97->bus->card, snd_ac97_cnew(&wm13_snd_ac97_controls_3d[i], ac97))) < 0)
802 return err;
803 }
804 return 0;
805 }
806
807 static int patch_wolfson_wm9713_specific(struct snd_ac97 * ac97)
808 {
809 int err, i;
810
811 for (i = 0; i < ARRAY_SIZE(wm13_snd_ac97_controls); i++) {
812 if ((err = snd_ctl_add(ac97->bus->card, snd_ac97_cnew(&wm13_snd_ac97_controls[i], ac97))) < 0)
813 return err;
814 }
815 snd_ac97_write_cache(ac97, AC97_PC_BEEP, 0x0808);
816 snd_ac97_write_cache(ac97, AC97_PHONE, 0x0808);
817 snd_ac97_write_cache(ac97, AC97_MIC, 0x0808);
818 snd_ac97_write_cache(ac97, AC97_LINE, 0x00da);
819 snd_ac97_write_cache(ac97, AC97_CD, 0x0808);
820 snd_ac97_write_cache(ac97, AC97_VIDEO, 0xd612);
821 snd_ac97_write_cache(ac97, AC97_REC_GAIN, 0x1ba0);
822 return 0;
823 }
824
825 #ifdef CONFIG_PM
826 static void patch_wolfson_wm9713_suspend (struct snd_ac97 * ac97)
827 {
828 snd_ac97_write_cache(ac97, AC97_EXTENDED_MID, 0xfeff);
829 snd_ac97_write_cache(ac97, AC97_EXTENDED_MSTATUS, 0xffff);
830 }
831
832 static void patch_wolfson_wm9713_resume (struct snd_ac97 * ac97)
833 {
834 snd_ac97_write_cache(ac97, AC97_EXTENDED_MID, 0xda00);
835 snd_ac97_write_cache(ac97, AC97_EXTENDED_MSTATUS, 0x3810);
836 snd_ac97_write_cache(ac97, AC97_POWERDOWN, 0x0);
837 }
838 #endif
839
840 static const struct snd_ac97_build_ops patch_wolfson_wm9713_ops = {
841 .build_specific = patch_wolfson_wm9713_specific,
842 .build_3d = patch_wolfson_wm9713_3d,
843 #ifdef CONFIG_PM
844 .suspend = patch_wolfson_wm9713_suspend,
845 .resume = patch_wolfson_wm9713_resume
846 #endif
847 };
848
849 static int patch_wolfson13(struct snd_ac97 * ac97)
850 {
851
852 ac97->build_ops = &patch_wolfson_wm9713_ops;
853
854 ac97->flags |= AC97_HAS_NO_REC_GAIN | AC97_STEREO_MUTES | AC97_HAS_NO_PHONE |
855 AC97_HAS_NO_PC_BEEP | AC97_HAS_NO_VIDEO | AC97_HAS_NO_CD | AC97_HAS_NO_TONE |
856 AC97_HAS_NO_STD_PCM;
857 ac97->scaps &= ~AC97_SCAP_MODEM;
858
859 snd_ac97_write_cache(ac97, AC97_EXTENDED_MID, 0xda00);
860 snd_ac97_write_cache(ac97, AC97_EXTENDED_MSTATUS, 0x3810);
861 snd_ac97_write_cache(ac97, AC97_POWERDOWN, 0x0);
862
863 return 0;
864 }
865
866
867
868
869 static int patch_tritech_tr28028(struct snd_ac97 * ac97)
870 {
871 snd_ac97_write_cache(ac97, 0x26, 0x0300);
872 snd_ac97_write_cache(ac97, 0x26, 0x0000);
873 snd_ac97_write_cache(ac97, AC97_SURROUND_MASTER, 0x0000);
874 snd_ac97_write_cache(ac97, AC97_SPDIF, 0x0000);
875 return 0;
876 }
877
878
879
880
881 static int patch_sigmatel_stac9700_3d(struct snd_ac97 * ac97)
882 {
883 struct snd_kcontrol *kctl;
884 int err;
885
886 if ((err = snd_ctl_add(ac97->bus->card, kctl = snd_ac97_cnew(&snd_ac97_controls_3d[0], ac97))) < 0)
887 return err;
888 strcpy(kctl->id.name, "3D Control Sigmatel - Depth");
889 kctl->private_value = AC97_SINGLE_VALUE(AC97_3D_CONTROL, 2, 3, 0);
890 snd_ac97_write_cache(ac97, AC97_3D_CONTROL, 0x0000);
891 return 0;
892 }
893
894 static int patch_sigmatel_stac9708_3d(struct snd_ac97 * ac97)
895 {
896 struct snd_kcontrol *kctl;
897 int err;
898
899 if ((err = snd_ctl_add(ac97->bus->card, kctl = snd_ac97_cnew(&snd_ac97_controls_3d[0], ac97))) < 0)
900 return err;
901 strcpy(kctl->id.name, "3D Control Sigmatel - Depth");
902 kctl->private_value = AC97_SINGLE_VALUE(AC97_3D_CONTROL, 0, 3, 0);
903 if ((err = snd_ctl_add(ac97->bus->card, kctl = snd_ac97_cnew(&snd_ac97_controls_3d[0], ac97))) < 0)
904 return err;
905 strcpy(kctl->id.name, "3D Control Sigmatel - Rear Depth");
906 kctl->private_value = AC97_SINGLE_VALUE(AC97_3D_CONTROL, 2, 3, 0);
907 snd_ac97_write_cache(ac97, AC97_3D_CONTROL, 0x0000);
908 return 0;
909 }
910
911 static const struct snd_kcontrol_new snd_ac97_sigmatel_4speaker =
912 AC97_SINGLE("Sigmatel 4-Speaker Stereo Playback Switch",
913 AC97_SIGMATEL_DAC2INVERT, 2, 1, 0);
914
915
916 static const struct snd_kcontrol_new snd_ac97_sigmatel_phaseinvert =
917 AC97_SINGLE("Surround Phase Inversion Playback Switch",
918 AC97_SIGMATEL_DAC2INVERT, 3, 1, 0);
919
920 static const struct snd_kcontrol_new snd_ac97_sigmatel_controls[] = {
921 AC97_SINGLE("Sigmatel DAC 6dB Attenuate", AC97_SIGMATEL_ANALOG, 1, 1, 0),
922 AC97_SINGLE("Sigmatel ADC 6dB Attenuate", AC97_SIGMATEL_ANALOG, 0, 1, 0)
923 };
924
925 static int patch_sigmatel_stac97xx_specific(struct snd_ac97 * ac97)
926 {
927 int err;
928
929 snd_ac97_write_cache(ac97, AC97_SIGMATEL_ANALOG, snd_ac97_read(ac97, AC97_SIGMATEL_ANALOG) & ~0x0003);
930 if (snd_ac97_try_bit(ac97, AC97_SIGMATEL_ANALOG, 1))
931 if ((err = patch_build_controls(ac97, &snd_ac97_sigmatel_controls[0], 1)) < 0)
932 return err;
933 if (snd_ac97_try_bit(ac97, AC97_SIGMATEL_ANALOG, 0))
934 if ((err = patch_build_controls(ac97, &snd_ac97_sigmatel_controls[1], 1)) < 0)
935 return err;
936 if (snd_ac97_try_bit(ac97, AC97_SIGMATEL_DAC2INVERT, 2))
937 if ((err = patch_build_controls(ac97, &snd_ac97_sigmatel_4speaker, 1)) < 0)
938 return err;
939 if (snd_ac97_try_bit(ac97, AC97_SIGMATEL_DAC2INVERT, 3))
940 if ((err = patch_build_controls(ac97, &snd_ac97_sigmatel_phaseinvert, 1)) < 0)
941 return err;
942 return 0;
943 }
944
945 static const struct snd_ac97_build_ops patch_sigmatel_stac9700_ops = {
946 .build_3d = patch_sigmatel_stac9700_3d,
947 .build_specific = patch_sigmatel_stac97xx_specific
948 };
949
950 static int patch_sigmatel_stac9700(struct snd_ac97 * ac97)
951 {
952 ac97->build_ops = &patch_sigmatel_stac9700_ops;
953 return 0;
954 }
955
956 static int snd_ac97_stac9708_put_bias(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
957 {
958 struct snd_ac97 *ac97 = snd_kcontrol_chip(kcontrol);
959 int err;
960
961 mutex_lock(&ac97->page_mutex);
962 snd_ac97_write(ac97, AC97_SIGMATEL_BIAS1, 0xabba);
963 err = snd_ac97_update_bits(ac97, AC97_SIGMATEL_BIAS2, 0x0010,
964 (ucontrol->value.integer.value[0] & 1) << 4);
965 snd_ac97_write(ac97, AC97_SIGMATEL_BIAS1, 0);
966 mutex_unlock(&ac97->page_mutex);
967 return err;
968 }
969
970 static const struct snd_kcontrol_new snd_ac97_stac9708_bias_control = {
971 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
972 .name = "Sigmatel Output Bias Switch",
973 .info = snd_ac97_info_volsw,
974 .get = snd_ac97_get_volsw,
975 .put = snd_ac97_stac9708_put_bias,
976 .private_value = AC97_SINGLE_VALUE(AC97_SIGMATEL_BIAS2, 4, 1, 0),
977 };
978
979 static int patch_sigmatel_stac9708_specific(struct snd_ac97 *ac97)
980 {
981 int err;
982
983
984 snd_ac97_remove_ctl(ac97, "PCM Out Path & Mute", NULL);
985
986 snd_ac97_rename_vol_ctl(ac97, "Headphone Playback", "Sigmatel Surround Playback");
987 if ((err = patch_build_controls(ac97, &snd_ac97_stac9708_bias_control, 1)) < 0)
988 return err;
989 return patch_sigmatel_stac97xx_specific(ac97);
990 }
991
992 static const struct snd_ac97_build_ops patch_sigmatel_stac9708_ops = {
993 .build_3d = patch_sigmatel_stac9708_3d,
994 .build_specific = patch_sigmatel_stac9708_specific
995 };
996
997 static int patch_sigmatel_stac9708(struct snd_ac97 * ac97)
998 {
999 unsigned int codec72, codec6c;
1000
1001 ac97->build_ops = &patch_sigmatel_stac9708_ops;
1002 ac97->caps |= 0x10;
1003
1004 codec72 = snd_ac97_read(ac97, AC97_SIGMATEL_BIAS2) & 0x8000;
1005 codec6c = snd_ac97_read(ac97, AC97_SIGMATEL_ANALOG);
1006
1007 if ((codec72==0) && (codec6c==0)) {
1008 snd_ac97_write_cache(ac97, AC97_SIGMATEL_CIC1, 0xabba);
1009 snd_ac97_write_cache(ac97, AC97_SIGMATEL_CIC2, 0x1000);
1010 snd_ac97_write_cache(ac97, AC97_SIGMATEL_BIAS1, 0xabba);
1011 snd_ac97_write_cache(ac97, AC97_SIGMATEL_BIAS2, 0x0007);
1012 } else if ((codec72==0x8000) && (codec6c==0)) {
1013 snd_ac97_write_cache(ac97, AC97_SIGMATEL_CIC1, 0xabba);
1014 snd_ac97_write_cache(ac97, AC97_SIGMATEL_CIC2, 0x1001);
1015 snd_ac97_write_cache(ac97, AC97_SIGMATEL_DAC2INVERT, 0x0008);
1016 } else if ((codec72==0x8000) && (codec6c==0x0080)) {
1017
1018 }
1019 snd_ac97_write_cache(ac97, AC97_SIGMATEL_MULTICHN, 0x0000);
1020 return 0;
1021 }
1022
1023 static int patch_sigmatel_stac9721(struct snd_ac97 * ac97)
1024 {
1025 ac97->build_ops = &patch_sigmatel_stac9700_ops;
1026 if (snd_ac97_read(ac97, AC97_SIGMATEL_ANALOG) == 0) {
1027
1028 snd_ac97_write_cache(ac97, AC97_SIGMATEL_CIC1, 0xabba);
1029 snd_ac97_write_cache(ac97, AC97_SIGMATEL_CIC2, 0x4000);
1030 snd_ac97_write_cache(ac97, AC97_SIGMATEL_BIAS1, 0xabba);
1031 snd_ac97_write_cache(ac97, AC97_SIGMATEL_BIAS2, 0x0002);
1032 }
1033 snd_ac97_write_cache(ac97, AC97_SIGMATEL_MULTICHN, 0x0000);
1034 return 0;
1035 }
1036
1037 static int patch_sigmatel_stac9744(struct snd_ac97 * ac97)
1038 {
1039
1040 ac97->build_ops = &patch_sigmatel_stac9700_ops;
1041 snd_ac97_write_cache(ac97, AC97_SIGMATEL_CIC1, 0xabba);
1042 snd_ac97_write_cache(ac97, AC97_SIGMATEL_CIC2, 0x0000);
1043 snd_ac97_write_cache(ac97, AC97_SIGMATEL_BIAS1, 0xabba);
1044 snd_ac97_write_cache(ac97, AC97_SIGMATEL_BIAS2, 0x0002);
1045 snd_ac97_write_cache(ac97, AC97_SIGMATEL_MULTICHN, 0x0000);
1046 return 0;
1047 }
1048
1049 static int patch_sigmatel_stac9756(struct snd_ac97 * ac97)
1050 {
1051
1052 ac97->build_ops = &patch_sigmatel_stac9700_ops;
1053 snd_ac97_write_cache(ac97, AC97_SIGMATEL_CIC1, 0xabba);
1054 snd_ac97_write_cache(ac97, AC97_SIGMATEL_CIC2, 0x0000);
1055 snd_ac97_write_cache(ac97, AC97_SIGMATEL_BIAS1, 0xabba);
1056 snd_ac97_write_cache(ac97, AC97_SIGMATEL_BIAS2, 0x0002);
1057 snd_ac97_write_cache(ac97, AC97_SIGMATEL_MULTICHN, 0x0000);
1058 return 0;
1059 }
1060
1061 static int snd_ac97_stac9758_output_jack_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo)
1062 {
1063 static const char * const texts[5] = {
1064 "Input/Disabled", "Front Output",
1065 "Rear Output", "Center/LFE Output", "Mixer Output" };
1066
1067 return snd_ctl_enum_info(uinfo, 1, 5, texts);
1068 }
1069
1070 static int snd_ac97_stac9758_output_jack_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
1071 {
1072 struct snd_ac97 *ac97 = snd_kcontrol_chip(kcontrol);
1073 int shift = kcontrol->private_value;
1074 unsigned short val;
1075
1076 val = ac97->regs[AC97_SIGMATEL_OUTSEL] >> shift;
1077 if (!(val & 4))
1078 ucontrol->value.enumerated.item[0] = 0;
1079 else
1080 ucontrol->value.enumerated.item[0] = 1 + (val & 3);
1081 return 0;
1082 }
1083
1084 static int snd_ac97_stac9758_output_jack_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
1085 {
1086 struct snd_ac97 *ac97 = snd_kcontrol_chip(kcontrol);
1087 int shift = kcontrol->private_value;
1088 unsigned short val;
1089
1090 if (ucontrol->value.enumerated.item[0] > 4)
1091 return -EINVAL;
1092 if (ucontrol->value.enumerated.item[0] == 0)
1093 val = 0;
1094 else
1095 val = 4 | (ucontrol->value.enumerated.item[0] - 1);
1096 return ac97_update_bits_page(ac97, AC97_SIGMATEL_OUTSEL,
1097 7 << shift, val << shift, 0);
1098 }
1099
1100 static int snd_ac97_stac9758_input_jack_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo)
1101 {
1102 static const char * const texts[7] = {
1103 "Mic2 Jack", "Mic1 Jack", "Line In Jack",
1104 "Front Jack", "Rear Jack", "Center/LFE Jack", "Mute" };
1105
1106 return snd_ctl_enum_info(uinfo, 1, 7, texts);
1107 }
1108
1109 static int snd_ac97_stac9758_input_jack_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
1110 {
1111 struct snd_ac97 *ac97 = snd_kcontrol_chip(kcontrol);
1112 int shift = kcontrol->private_value;
1113 unsigned short val;
1114
1115 val = ac97->regs[AC97_SIGMATEL_INSEL];
1116 ucontrol->value.enumerated.item[0] = (val >> shift) & 7;
1117 return 0;
1118 }
1119
1120 static int snd_ac97_stac9758_input_jack_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
1121 {
1122 struct snd_ac97 *ac97 = snd_kcontrol_chip(kcontrol);
1123 int shift = kcontrol->private_value;
1124
1125 return ac97_update_bits_page(ac97, AC97_SIGMATEL_INSEL, 7 << shift,
1126 ucontrol->value.enumerated.item[0] << shift, 0);
1127 }
1128
1129 static int snd_ac97_stac9758_phonesel_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo)
1130 {
1131 static const char * const texts[3] = {
1132 "None", "Front Jack", "Rear Jack"
1133 };
1134
1135 return snd_ctl_enum_info(uinfo, 1, 3, texts);
1136 }
1137
1138 static int snd_ac97_stac9758_phonesel_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
1139 {
1140 struct snd_ac97 *ac97 = snd_kcontrol_chip(kcontrol);
1141
1142 ucontrol->value.enumerated.item[0] = ac97->regs[AC97_SIGMATEL_IOMISC] & 3;
1143 return 0;
1144 }
1145
1146 static int snd_ac97_stac9758_phonesel_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
1147 {
1148 struct snd_ac97 *ac97 = snd_kcontrol_chip(kcontrol);
1149
1150 return ac97_update_bits_page(ac97, AC97_SIGMATEL_IOMISC, 3,
1151 ucontrol->value.enumerated.item[0], 0);
1152 }
1153
1154 #define STAC9758_OUTPUT_JACK(xname, shift) \
1155 { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, \
1156 .info = snd_ac97_stac9758_output_jack_info, \
1157 .get = snd_ac97_stac9758_output_jack_get, \
1158 .put = snd_ac97_stac9758_output_jack_put, \
1159 .private_value = shift }
1160 #define STAC9758_INPUT_JACK(xname, shift) \
1161 { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, \
1162 .info = snd_ac97_stac9758_input_jack_info, \
1163 .get = snd_ac97_stac9758_input_jack_get, \
1164 .put = snd_ac97_stac9758_input_jack_put, \
1165 .private_value = shift }
1166 static const struct snd_kcontrol_new snd_ac97_sigmatel_stac9758_controls[] = {
1167 STAC9758_OUTPUT_JACK("Mic1 Jack", 1),
1168 STAC9758_OUTPUT_JACK("LineIn Jack", 4),
1169 STAC9758_OUTPUT_JACK("Front Jack", 7),
1170 STAC9758_OUTPUT_JACK("Rear Jack", 10),
1171 STAC9758_OUTPUT_JACK("Center/LFE Jack", 13),
1172 STAC9758_INPUT_JACK("Mic Input Source", 0),
1173 STAC9758_INPUT_JACK("Line Input Source", 8),
1174 {
1175 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1176 .name = "Headphone Amp",
1177 .info = snd_ac97_stac9758_phonesel_info,
1178 .get = snd_ac97_stac9758_phonesel_get,
1179 .put = snd_ac97_stac9758_phonesel_put
1180 },
1181 AC97_SINGLE("Exchange Center/LFE", AC97_SIGMATEL_IOMISC, 4, 1, 0),
1182 AC97_SINGLE("Headphone +3dB Boost", AC97_SIGMATEL_IOMISC, 8, 1, 0)
1183 };
1184
1185 static int patch_sigmatel_stac9758_specific(struct snd_ac97 *ac97)
1186 {
1187 int err;
1188
1189 err = patch_sigmatel_stac97xx_specific(ac97);
1190 if (err < 0)
1191 return err;
1192 err = patch_build_controls(ac97, snd_ac97_sigmatel_stac9758_controls,
1193 ARRAY_SIZE(snd_ac97_sigmatel_stac9758_controls));
1194 if (err < 0)
1195 return err;
1196
1197 snd_ac97_rename_vol_ctl(ac97, "Headphone Playback", "Front Playback");
1198
1199
1200
1201 snd_ac97_rename_vol_ctl(ac97, "Video Playback", "Surround Mix Playback");
1202
1203
1204 return 0;
1205 }
1206
1207 static const struct snd_ac97_build_ops patch_sigmatel_stac9758_ops = {
1208 .build_3d = patch_sigmatel_stac9700_3d,
1209 .build_specific = patch_sigmatel_stac9758_specific
1210 };
1211
1212 static int patch_sigmatel_stac9758(struct snd_ac97 * ac97)
1213 {
1214 static unsigned short regs[4] = {
1215 AC97_SIGMATEL_OUTSEL,
1216 AC97_SIGMATEL_IOMISC,
1217 AC97_SIGMATEL_INSEL,
1218 AC97_SIGMATEL_VARIOUS
1219 };
1220 static unsigned short def_regs[4] = {
1221 0xd794,
1222 0x2001,
1223 0x0201,
1224 0x0040
1225 };
1226 static unsigned short m675_regs[4] = {
1227 0xfc70,
1228 0x2102,
1229 0x0203,
1230 0x0041
1231 };
1232 unsigned short *pregs = def_regs;
1233 int i;
1234
1235
1236 if (ac97->pci &&
1237 ac97->subsystem_vendor == 0x107b &&
1238 ac97->subsystem_device == 0x0601)
1239 pregs = m675_regs;
1240
1241
1242 ac97->build_ops = &patch_sigmatel_stac9758_ops;
1243
1244 snd_ac97_update_bits(ac97, AC97_INT_PAGING, AC97_PAGE_MASK, AC97_PAGE_VENDOR);
1245 for (i = 0; i < 4; i++)
1246 snd_ac97_write_cache(ac97, regs[i], pregs[i]);
1247
1248 ac97->flags |= AC97_STEREO_MUTES;
1249 return 0;
1250 }
1251
1252
1253
1254
1255 static const struct snd_kcontrol_new snd_ac97_cirrus_controls_spdif[2] = {
1256 AC97_SINGLE(SNDRV_CTL_NAME_IEC958("",PLAYBACK,SWITCH), AC97_CSR_SPDIF, 15, 1, 0),
1257 AC97_SINGLE(SNDRV_CTL_NAME_IEC958("",PLAYBACK,NONE) "AC97-SPSA", AC97_CSR_ACMODE, 0, 3, 0)
1258 };
1259
1260 static int patch_cirrus_build_spdif(struct snd_ac97 * ac97)
1261 {
1262 int err;
1263
1264
1265 if ((err = patch_build_controls(ac97, &snd_ac97_controls_spdif[0], 3)) < 0)
1266 return err;
1267
1268 if ((err = patch_build_controls(ac97, &snd_ac97_cirrus_controls_spdif[0], 1)) < 0)
1269 return err;
1270 switch (ac97->id & AC97_ID_CS_MASK) {
1271 case AC97_ID_CS4205:
1272 if ((err = patch_build_controls(ac97, &snd_ac97_cirrus_controls_spdif[1], 1)) < 0)
1273 return err;
1274 break;
1275 }
1276
1277
1278 snd_ac97_write_cache(ac97, AC97_CSR_SPDIF, 0x0a20);
1279 return 0;
1280 }
1281
1282 static const struct snd_ac97_build_ops patch_cirrus_ops = {
1283 .build_spdif = patch_cirrus_build_spdif
1284 };
1285
1286 static int patch_cirrus_spdif(struct snd_ac97 * ac97)
1287 {
1288
1289
1290
1291
1292
1293
1294
1295
1296
1297
1298
1299 ac97->build_ops = &patch_cirrus_ops;
1300 ac97->flags |= AC97_CS_SPDIF;
1301 ac97->rates[AC97_RATES_SPDIF] &= ~SNDRV_PCM_RATE_32000;
1302 ac97->ext_id |= AC97_EI_SPDIF;
1303 snd_ac97_write_cache(ac97, AC97_CSR_ACMODE, 0x0080);
1304 return 0;
1305 }
1306
1307 static int patch_cirrus_cs4299(struct snd_ac97 * ac97)
1308 {
1309
1310 ac97->flags |= AC97_HAS_PC_BEEP;
1311
1312 return patch_cirrus_spdif(ac97);
1313 }
1314
1315
1316
1317
1318 static const struct snd_kcontrol_new snd_ac97_conexant_controls_spdif[1] = {
1319 AC97_SINGLE(SNDRV_CTL_NAME_IEC958("",PLAYBACK,SWITCH), AC97_CXR_AUDIO_MISC, 3, 1, 0),
1320 };
1321
1322 static int patch_conexant_build_spdif(struct snd_ac97 * ac97)
1323 {
1324 int err;
1325
1326
1327 if ((err = patch_build_controls(ac97, &snd_ac97_controls_spdif[0], 3)) < 0)
1328 return err;
1329
1330 if ((err = patch_build_controls(ac97, &snd_ac97_conexant_controls_spdif[0], 1)) < 0)
1331 return err;
1332
1333
1334 snd_ac97_write_cache(ac97, AC97_CXR_AUDIO_MISC,
1335 snd_ac97_read(ac97, AC97_CXR_AUDIO_MISC) & ~(AC97_CXR_SPDIFEN|AC97_CXR_COPYRGT|AC97_CXR_SPDIF_MASK));
1336 return 0;
1337 }
1338
1339 static const struct snd_ac97_build_ops patch_conexant_ops = {
1340 .build_spdif = patch_conexant_build_spdif
1341 };
1342
1343 static int patch_conexant(struct snd_ac97 * ac97)
1344 {
1345 ac97->build_ops = &patch_conexant_ops;
1346 ac97->flags |= AC97_CX_SPDIF;
1347 ac97->ext_id |= AC97_EI_SPDIF;
1348 ac97->rates[AC97_RATES_SPDIF] = SNDRV_PCM_RATE_48000;
1349 return 0;
1350 }
1351
1352 static int patch_cx20551(struct snd_ac97 *ac97)
1353 {
1354 snd_ac97_update_bits(ac97, 0x5c, 0x01, 0x01);
1355 return 0;
1356 }
1357
1358
1359
1360
1361 #ifdef CONFIG_PM
1362 static void ad18xx_resume(struct snd_ac97 *ac97)
1363 {
1364 static unsigned short setup_regs[] = {
1365 AC97_AD_MISC, AC97_AD_SERIAL_CFG, AC97_AD_JACK_SPDIF,
1366 };
1367 int i, codec;
1368
1369 for (i = 0; i < (int)ARRAY_SIZE(setup_regs); i++) {
1370 unsigned short reg = setup_regs[i];
1371 if (test_bit(reg, ac97->reg_accessed)) {
1372 snd_ac97_write(ac97, reg, ac97->regs[reg]);
1373 snd_ac97_read(ac97, reg);
1374 }
1375 }
1376
1377 if (! (ac97->flags & AC97_AD_MULTI))
1378
1379 snd_ac97_restore_status(ac97);
1380 else {
1381
1382 for (codec = 0; codec < 3; codec++) {
1383 if (! ac97->spec.ad18xx.id[codec])
1384 continue;
1385
1386 snd_ac97_update_bits(ac97, AC97_AD_SERIAL_CFG, 0x7000,
1387 ac97->spec.ad18xx.unchained[codec] | ac97->spec.ad18xx.chained[codec]);
1388 ac97->bus->ops->write(ac97, AC97_AD_CODEC_CFG, ac97->spec.ad18xx.codec_cfg[codec]);
1389 }
1390
1391 snd_ac97_update_bits(ac97, AC97_AD_SERIAL_CFG, 0x7000, 0x7000);
1392
1393
1394 for (i = 2; i < 0x7c ; i += 2) {
1395 if (i == AC97_POWERDOWN || i == AC97_EXTENDED_ID)
1396 continue;
1397 if (test_bit(i, ac97->reg_accessed)) {
1398
1399 if (i == AC97_PCM) {
1400 for (codec = 0; codec < 3; codec++) {
1401 if (! ac97->spec.ad18xx.id[codec])
1402 continue;
1403
1404 snd_ac97_update_bits(ac97, AC97_AD_SERIAL_CFG, 0x7000,
1405 ac97->spec.ad18xx.unchained[codec] | ac97->spec.ad18xx.chained[codec]);
1406
1407 ac97->bus->ops->write(ac97, AC97_PCM, ac97->spec.ad18xx.pcmreg[codec]);
1408 }
1409
1410 snd_ac97_update_bits(ac97, AC97_AD_SERIAL_CFG, 0x7000, 0x7000);
1411 continue;
1412 } else if (i == AC97_AD_TEST ||
1413 i == AC97_AD_CODEC_CFG ||
1414 i == AC97_AD_SERIAL_CFG)
1415 continue;
1416 }
1417 snd_ac97_write(ac97, i, ac97->regs[i]);
1418 snd_ac97_read(ac97, i);
1419 }
1420 }
1421
1422 snd_ac97_restore_iec958(ac97);
1423 }
1424
1425 static void ad1888_resume(struct snd_ac97 *ac97)
1426 {
1427 ad18xx_resume(ac97);
1428 snd_ac97_write_cache(ac97, AC97_CODEC_CLASS_REV, 0x8080);
1429 }
1430
1431 #endif
1432
1433 static const struct snd_ac97_res_table ad1819_restbl[] = {
1434 { AC97_PHONE, 0x9f1f },
1435 { AC97_MIC, 0x9f1f },
1436 { AC97_LINE, 0x9f1f },
1437 { AC97_CD, 0x9f1f },
1438 { AC97_VIDEO, 0x9f1f },
1439 { AC97_AUX, 0x9f1f },
1440 { AC97_PCM, 0x9f1f },
1441 { }
1442 };
1443
1444 static int patch_ad1819(struct snd_ac97 * ac97)
1445 {
1446 unsigned short scfg;
1447
1448
1449 scfg = snd_ac97_read(ac97, AC97_AD_SERIAL_CFG);
1450 snd_ac97_write_cache(ac97, AC97_AD_SERIAL_CFG, scfg | 0x7000);
1451 ac97->res_table = ad1819_restbl;
1452 return 0;
1453 }
1454
1455 static unsigned short patch_ad1881_unchained(struct snd_ac97 * ac97, int idx, unsigned short mask)
1456 {
1457 unsigned short val;
1458
1459
1460 snd_ac97_update_bits(ac97, AC97_AD_SERIAL_CFG, 0x7000, mask);
1461 snd_ac97_write_cache(ac97, AC97_AD_CODEC_CFG, 0x0000);
1462 val = snd_ac97_read(ac97, AC97_VENDOR_ID2);
1463 if ((val & 0xff40) != 0x5340)
1464 return 0;
1465 ac97->spec.ad18xx.unchained[idx] = mask;
1466 ac97->spec.ad18xx.id[idx] = val;
1467 ac97->spec.ad18xx.codec_cfg[idx] = 0x0000;
1468 return mask;
1469 }
1470
1471 static int patch_ad1881_chained1(struct snd_ac97 * ac97, int idx, unsigned short codec_bits)
1472 {
1473 static int cfg_bits[3] = { 1<<12, 1<<14, 1<<13 };
1474 unsigned short val;
1475
1476 snd_ac97_update_bits(ac97, AC97_AD_SERIAL_CFG, 0x7000, cfg_bits[idx]);
1477 snd_ac97_write_cache(ac97, AC97_AD_CODEC_CFG, 0x0004);
1478 val = snd_ac97_read(ac97, AC97_VENDOR_ID2);
1479 if ((val & 0xff40) != 0x5340)
1480 return 0;
1481 if (codec_bits)
1482 snd_ac97_write_cache(ac97, AC97_AD_CODEC_CFG, codec_bits);
1483 ac97->spec.ad18xx.chained[idx] = cfg_bits[idx];
1484 ac97->spec.ad18xx.id[idx] = val;
1485 ac97->spec.ad18xx.codec_cfg[idx] = codec_bits ? codec_bits : 0x0004;
1486 return 1;
1487 }
1488
1489 static void patch_ad1881_chained(struct snd_ac97 * ac97, int unchained_idx, int cidx1, int cidx2)
1490 {
1491
1492 if (ac97->spec.ad18xx.unchained[cidx1] || ac97->spec.ad18xx.chained[cidx1])
1493 cidx1 = -1;
1494 if (ac97->spec.ad18xx.unchained[cidx2] || ac97->spec.ad18xx.chained[cidx2])
1495 cidx2 = -1;
1496 if (cidx1 < 0 && cidx2 < 0)
1497 return;
1498
1499 snd_ac97_update_bits(ac97, AC97_AD_SERIAL_CFG, 0x7000,
1500 ac97->spec.ad18xx.unchained[unchained_idx]);
1501 snd_ac97_write_cache(ac97, AC97_AD_CODEC_CFG, 0x0002);
1502 ac97->spec.ad18xx.codec_cfg[unchained_idx] = 0x0002;
1503 if (cidx1 >= 0) {
1504 if (cidx2 < 0)
1505 patch_ad1881_chained1(ac97, cidx1, 0);
1506 else if (patch_ad1881_chained1(ac97, cidx1, 0x0006))
1507 patch_ad1881_chained1(ac97, cidx2, 0);
1508 else if (patch_ad1881_chained1(ac97, cidx2, 0x0006))
1509 patch_ad1881_chained1(ac97, cidx1, 0);
1510 } else if (cidx2 >= 0) {
1511 patch_ad1881_chained1(ac97, cidx2, 0);
1512 }
1513 }
1514
1515 static const struct snd_ac97_build_ops patch_ad1881_build_ops = {
1516 #ifdef CONFIG_PM
1517 .resume = ad18xx_resume
1518 #endif
1519 };
1520
1521 static int patch_ad1881(struct snd_ac97 * ac97)
1522 {
1523 static const char cfg_idxs[3][2] = {
1524 {2, 1},
1525 {0, 2},
1526 {0, 1}
1527 };
1528
1529
1530 unsigned short codecs[3];
1531 unsigned short val;
1532 int idx, num;
1533
1534 val = snd_ac97_read(ac97, AC97_AD_SERIAL_CFG);
1535 snd_ac97_write_cache(ac97, AC97_AD_SERIAL_CFG, val);
1536 codecs[0] = patch_ad1881_unchained(ac97, 0, (1<<12));
1537 codecs[1] = patch_ad1881_unchained(ac97, 1, (1<<14));
1538 codecs[2] = patch_ad1881_unchained(ac97, 2, (1<<13));
1539
1540 if (! (codecs[0] || codecs[1] || codecs[2]))
1541 goto __end;
1542
1543 for (idx = 0; idx < 3; idx++)
1544 if (ac97->spec.ad18xx.unchained[idx])
1545 patch_ad1881_chained(ac97, idx, cfg_idxs[idx][0], cfg_idxs[idx][1]);
1546
1547 if (ac97->spec.ad18xx.id[1]) {
1548 ac97->flags |= AC97_AD_MULTI;
1549 ac97->scaps |= AC97_SCAP_SURROUND_DAC;
1550 }
1551 if (ac97->spec.ad18xx.id[2]) {
1552 ac97->flags |= AC97_AD_MULTI;
1553 ac97->scaps |= AC97_SCAP_CENTER_LFE_DAC;
1554 }
1555
1556 __end:
1557
1558 snd_ac97_update_bits(ac97, AC97_AD_SERIAL_CFG, 0x7000, 0x7000);
1559
1560 for (idx = num = 0; idx < 3; idx++)
1561 if (ac97->spec.ad18xx.id[idx])
1562 num++;
1563 if (num == 1) {
1564
1565 snd_ac97_write_cache(ac97, AC97_AD_CODEC_CFG, 0x0000);
1566 ac97->spec.ad18xx.codec_cfg[0] =
1567 ac97->spec.ad18xx.codec_cfg[1] =
1568 ac97->spec.ad18xx.codec_cfg[2] = 0x0000;
1569 }
1570
1571 ac97->ext_id = snd_ac97_read(ac97, AC97_EXTENDED_ID);
1572 if (ac97->spec.ad18xx.id[0]) {
1573 ac97->id &= 0xffff0000;
1574 ac97->id |= ac97->spec.ad18xx.id[0];
1575 }
1576 ac97->build_ops = &patch_ad1881_build_ops;
1577 return 0;
1578 }
1579
1580 static const struct snd_kcontrol_new snd_ac97_controls_ad1885[] = {
1581 AC97_SINGLE("Digital Mono Direct", AC97_AD_MISC, 11, 1, 0),
1582
1583 AC97_SINGLE("Low Power Mixer", AC97_AD_MISC, 14, 1, 0),
1584 AC97_SINGLE("Zero Fill DAC", AC97_AD_MISC, 15, 1, 0),
1585 AC97_SINGLE("Headphone Jack Sense", AC97_AD_JACK_SPDIF, 9, 1, 1),
1586 AC97_SINGLE("Line Jack Sense", AC97_AD_JACK_SPDIF, 8, 1, 1),
1587 };
1588
1589 static const DECLARE_TLV_DB_SCALE(db_scale_6bit_6db_max, -8850, 150, 0);
1590
1591 static int patch_ad1885_specific(struct snd_ac97 * ac97)
1592 {
1593 int err;
1594
1595 if ((err = patch_build_controls(ac97, snd_ac97_controls_ad1885, ARRAY_SIZE(snd_ac97_controls_ad1885))) < 0)
1596 return err;
1597 reset_tlv(ac97, "Headphone Playback Volume",
1598 db_scale_6bit_6db_max);
1599 return 0;
1600 }
1601
1602 static const struct snd_ac97_build_ops patch_ad1885_build_ops = {
1603 .build_specific = &patch_ad1885_specific,
1604 #ifdef CONFIG_PM
1605 .resume = ad18xx_resume
1606 #endif
1607 };
1608
1609 static int patch_ad1885(struct snd_ac97 * ac97)
1610 {
1611 patch_ad1881(ac97);
1612
1613
1614
1615
1616 snd_ac97_write_cache(ac97, AC97_AD_MISC, 0x0404);
1617
1618 ac97->build_ops = &patch_ad1885_build_ops;
1619 return 0;
1620 }
1621
1622 static int patch_ad1886_specific(struct snd_ac97 * ac97)
1623 {
1624 reset_tlv(ac97, "Headphone Playback Volume",
1625 db_scale_6bit_6db_max);
1626 return 0;
1627 }
1628
1629 static const struct snd_ac97_build_ops patch_ad1886_build_ops = {
1630 .build_specific = &patch_ad1886_specific,
1631 #ifdef CONFIG_PM
1632 .resume = ad18xx_resume
1633 #endif
1634 };
1635
1636 static int patch_ad1886(struct snd_ac97 * ac97)
1637 {
1638 patch_ad1881(ac97);
1639
1640
1641 snd_ac97_write_cache(ac97, AC97_AD_JACK_SPDIF, 0x0010);
1642 ac97->build_ops = &patch_ad1886_build_ops;
1643 return 0;
1644 }
1645
1646
1647 #define AC97_AD198X_MBC 0x0003
1648 #define AC97_AD198X_MBC_20 0x0000
1649 #define AC97_AD198X_MBC_10 0x0001
1650 #define AC97_AD198X_MBC_30 0x0002
1651 #define AC97_AD198X_VREFD 0x0004
1652 #define AC97_AD198X_VREFH 0x0008
1653 #define AC97_AD198X_VREF_0 0x000c
1654 #define AC97_AD198X_VREF_MASK (AC97_AD198X_VREFH | AC97_AD198X_VREFD)
1655 #define AC97_AD198X_VREF_SHIFT 2
1656 #define AC97_AD198X_SRU 0x0010
1657 #define AC97_AD198X_LOSEL 0x0020
1658 #define AC97_AD198X_2MIC 0x0040
1659 #define AC97_AD198X_SPRD 0x0080
1660 #define AC97_AD198X_DMIX0 0x0100
1661
1662 #define AC97_AD198X_DMIX1 0x0200
1663 #define AC97_AD198X_HPSEL 0x0400
1664 #define AC97_AD198X_CLDIS 0x0800
1665 #define AC97_AD198X_LODIS 0x1000
1666 #define AC97_AD198X_MSPLT 0x2000
1667 #define AC97_AD198X_AC97NC 0x4000
1668 #define AC97_AD198X_DACZ 0x8000
1669
1670
1671 #define AC97_AD1986_MBC 0x0003
1672 #define AC97_AD1986_MBC_20 0x0000
1673 #define AC97_AD1986_MBC_10 0x0001
1674 #define AC97_AD1986_MBC_30 0x0002
1675 #define AC97_AD1986_LISEL0 0x0004
1676 #define AC97_AD1986_LISEL1 0x0008
1677 #define AC97_AD1986_LISEL_MASK (AC97_AD1986_LISEL1 | AC97_AD1986_LISEL0)
1678 #define AC97_AD1986_LISEL_LI 0x0000
1679 #define AC97_AD1986_LISEL_SURR 0x0004
1680 #define AC97_AD1986_LISEL_MIC 0x0008
1681 #define AC97_AD1986_SRU 0x0010
1682 #define AC97_AD1986_SOSEL 0x0020
1683 #define AC97_AD1986_2MIC 0x0040
1684 #define AC97_AD1986_SPRD 0x0080
1685 #define AC97_AD1986_DMIX0 0x0100
1686
1687 #define AC97_AD1986_DMIX1 0x0200
1688 #define AC97_AD1986_CLDIS 0x0800
1689 #define AC97_AD1986_SODIS 0x1000
1690 #define AC97_AD1986_MSPLT 0x2000
1691 #define AC97_AD1986_AC97NC 0x4000
1692 #define AC97_AD1986_DACZ 0x8000
1693
1694
1695 #define AC97_AD_MISC2 0x70
1696
1697 #define AC97_AD1986_CVREF0 0x0004
1698 #define AC97_AD1986_CVREF1 0x0008
1699 #define AC97_AD1986_CVREF2 0x0010
1700 #define AC97_AD1986_CVREF_MASK \
1701 (AC97_AD1986_CVREF2 | AC97_AD1986_CVREF1 | AC97_AD1986_CVREF0)
1702 #define AC97_AD1986_JSMAP 0x0020
1703 #define AC97_AD1986_MMDIS 0x0080
1704 #define AC97_AD1986_MVREF0 0x0400
1705 #define AC97_AD1986_MVREF1 0x0800
1706 #define AC97_AD1986_MVREF2 0x1000
1707 #define AC97_AD1986_MVREF_MASK \
1708 (AC97_AD1986_MVREF2 | AC97_AD1986_MVREF1 | AC97_AD1986_MVREF0)
1709
1710
1711 #define AC97_AD_MISC3 0x7a
1712
1713 #define AC97_AD1986_MMIX 0x0004
1714 #define AC97_AD1986_GPO 0x0008
1715 #define AC97_AD1986_LOHPEN 0x0010
1716 #define AC97_AD1986_LVREF0 0x0100
1717 #define AC97_AD1986_LVREF1 0x0200
1718 #define AC97_AD1986_LVREF2 0x0400
1719 #define AC97_AD1986_LVREF_MASK \
1720 (AC97_AD1986_LVREF2 | AC97_AD1986_LVREF1 | AC97_AD1986_LVREF0)
1721 #define AC97_AD1986_JSINVA 0x0800
1722 #define AC97_AD1986_LOSEL 0x1000
1723 #define AC97_AD1986_HPSEL0 0x2000
1724
1725 #define AC97_AD1986_HPSEL1 0x4000
1726
1727 #define AC97_AD1986_JSINVB 0x8000
1728
1729
1730 #define AC97_AD1986_OMS0 0x0100
1731 #define AC97_AD1986_OMS1 0x0200
1732 #define AC97_AD1986_OMS2 0x0400
1733 #define AC97_AD1986_OMS_MASK \
1734 (AC97_AD1986_OMS2 | AC97_AD1986_OMS1 | AC97_AD1986_OMS0)
1735 #define AC97_AD1986_OMS_M 0x0000
1736 #define AC97_AD1986_OMS_L 0x0100
1737 #define AC97_AD1986_OMS_C 0x0200
1738 #define AC97_AD1986_OMS_MC 0x0400
1739
1740 #define AC97_AD1986_OMS_ML 0x0500
1741
1742 #define AC97_AD1986_OMS_LC 0x0600
1743
1744 #define AC97_AD1986_OMS_MLC 0x0700
1745
1746
1747
1748 static int snd_ac97_ad198x_spdif_source_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo)
1749 {
1750 static const char * const texts[2] = { "AC-Link", "A/D Converter" };
1751
1752 return snd_ctl_enum_info(uinfo, 1, 2, texts);
1753 }
1754
1755 static int snd_ac97_ad198x_spdif_source_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
1756 {
1757 struct snd_ac97 *ac97 = snd_kcontrol_chip(kcontrol);
1758 unsigned short val;
1759
1760 val = ac97->regs[AC97_AD_SERIAL_CFG];
1761 ucontrol->value.enumerated.item[0] = (val >> 2) & 1;
1762 return 0;
1763 }
1764
1765 static int snd_ac97_ad198x_spdif_source_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
1766 {
1767 struct snd_ac97 *ac97 = snd_kcontrol_chip(kcontrol);
1768 unsigned short val;
1769
1770 if (ucontrol->value.enumerated.item[0] > 1)
1771 return -EINVAL;
1772 val = ucontrol->value.enumerated.item[0] << 2;
1773 return snd_ac97_update_bits(ac97, AC97_AD_SERIAL_CFG, 0x0004, val);
1774 }
1775
1776 static const struct snd_kcontrol_new snd_ac97_ad198x_spdif_source = {
1777 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1778 .name = SNDRV_CTL_NAME_IEC958("",PLAYBACK,NONE) "Source",
1779 .info = snd_ac97_ad198x_spdif_source_info,
1780 .get = snd_ac97_ad198x_spdif_source_get,
1781 .put = snd_ac97_ad198x_spdif_source_put,
1782 };
1783
1784 static int patch_ad198x_post_spdif(struct snd_ac97 * ac97)
1785 {
1786 return patch_build_controls(ac97, &snd_ac97_ad198x_spdif_source, 1);
1787 }
1788
1789 static const struct snd_kcontrol_new snd_ac97_ad1981x_jack_sense[] = {
1790 AC97_SINGLE("Headphone Jack Sense", AC97_AD_JACK_SPDIF, 11, 1, 0),
1791 AC97_SINGLE("Line Jack Sense", AC97_AD_JACK_SPDIF, 12, 1, 0),
1792 };
1793
1794
1795
1796
1797 static unsigned int ad1981_jacks_blacklist[] = {
1798 0x10140523,
1799 0x10140534,
1800 0x10140537,
1801 0x1014053e,
1802 0x10140554,
1803 0x10140567,
1804 0x10140581,
1805 0x10280160,
1806 0x104380b0,
1807 0x11790241,
1808 0x1179ff10,
1809 0x144dc01a,
1810 0
1811 };
1812
1813 static int check_list(struct snd_ac97 *ac97, const unsigned int *list)
1814 {
1815 u32 subid = ((u32)ac97->subsystem_vendor << 16) | ac97->subsystem_device;
1816 for (; *list; list++)
1817 if (*list == subid)
1818 return 1;
1819 return 0;
1820 }
1821
1822 static int patch_ad1981a_specific(struct snd_ac97 * ac97)
1823 {
1824 if (check_list(ac97, ad1981_jacks_blacklist))
1825 return 0;
1826 return patch_build_controls(ac97, snd_ac97_ad1981x_jack_sense,
1827 ARRAY_SIZE(snd_ac97_ad1981x_jack_sense));
1828 }
1829
1830 static const struct snd_ac97_build_ops patch_ad1981a_build_ops = {
1831 .build_post_spdif = patch_ad198x_post_spdif,
1832 .build_specific = patch_ad1981a_specific,
1833 #ifdef CONFIG_PM
1834 .resume = ad18xx_resume
1835 #endif
1836 };
1837
1838
1839
1840
1841 static unsigned int ad1981_jacks_whitelist[] = {
1842 0x0e11005a,
1843 0x103c0890,
1844 0x103c0938,
1845 0x103c099c,
1846 0x103c0944,
1847 0x103c0934,
1848 0x103c006d,
1849 0x103c300d,
1850 0x17340088,
1851 0
1852 };
1853
1854 static void check_ad1981_hp_jack_sense(struct snd_ac97 *ac97)
1855 {
1856 if (check_list(ac97, ad1981_jacks_whitelist))
1857
1858 snd_ac97_update_bits(ac97, AC97_AD_JACK_SPDIF, 1<<11, 1<<11);
1859 }
1860
1861 static int patch_ad1981a(struct snd_ac97 *ac97)
1862 {
1863 patch_ad1881(ac97);
1864 ac97->build_ops = &patch_ad1981a_build_ops;
1865 snd_ac97_update_bits(ac97, AC97_AD_MISC, AC97_AD198X_MSPLT, AC97_AD198X_MSPLT);
1866 ac97->flags |= AC97_STEREO_MUTES;
1867 check_ad1981_hp_jack_sense(ac97);
1868 return 0;
1869 }
1870
1871 static const struct snd_kcontrol_new snd_ac97_ad198x_2cmic =
1872 AC97_SINGLE("Stereo Mic", AC97_AD_MISC, 6, 1, 0);
1873
1874 static int patch_ad1981b_specific(struct snd_ac97 *ac97)
1875 {
1876 int err;
1877
1878 if ((err = patch_build_controls(ac97, &snd_ac97_ad198x_2cmic, 1)) < 0)
1879 return err;
1880 if (check_list(ac97, ad1981_jacks_blacklist))
1881 return 0;
1882 return patch_build_controls(ac97, snd_ac97_ad1981x_jack_sense,
1883 ARRAY_SIZE(snd_ac97_ad1981x_jack_sense));
1884 }
1885
1886 static const struct snd_ac97_build_ops patch_ad1981b_build_ops = {
1887 .build_post_spdif = patch_ad198x_post_spdif,
1888 .build_specific = patch_ad1981b_specific,
1889 #ifdef CONFIG_PM
1890 .resume = ad18xx_resume
1891 #endif
1892 };
1893
1894 static int patch_ad1981b(struct snd_ac97 *ac97)
1895 {
1896 patch_ad1881(ac97);
1897 ac97->build_ops = &patch_ad1981b_build_ops;
1898 snd_ac97_update_bits(ac97, AC97_AD_MISC, AC97_AD198X_MSPLT, AC97_AD198X_MSPLT);
1899 ac97->flags |= AC97_STEREO_MUTES;
1900 check_ad1981_hp_jack_sense(ac97);
1901 return 0;
1902 }
1903
1904 #define snd_ac97_ad1888_lohpsel_info snd_ctl_boolean_mono_info
1905
1906 static int snd_ac97_ad1888_lohpsel_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
1907 {
1908 struct snd_ac97 *ac97 = snd_kcontrol_chip(kcontrol);
1909 unsigned short val;
1910
1911 val = ac97->regs[AC97_AD_MISC];
1912 ucontrol->value.integer.value[0] = !(val & AC97_AD198X_LOSEL);
1913 if (ac97->spec.ad18xx.lo_as_master)
1914 ucontrol->value.integer.value[0] =
1915 !ucontrol->value.integer.value[0];
1916 return 0;
1917 }
1918
1919 static int snd_ac97_ad1888_lohpsel_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
1920 {
1921 struct snd_ac97 *ac97 = snd_kcontrol_chip(kcontrol);
1922 unsigned short val;
1923
1924 val = !ucontrol->value.integer.value[0];
1925 if (ac97->spec.ad18xx.lo_as_master)
1926 val = !val;
1927 val = val ? (AC97_AD198X_LOSEL | AC97_AD198X_HPSEL) : 0;
1928 return snd_ac97_update_bits(ac97, AC97_AD_MISC,
1929 AC97_AD198X_LOSEL | AC97_AD198X_HPSEL, val);
1930 }
1931
1932 static int snd_ac97_ad1888_downmix_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo)
1933 {
1934 static const char * const texts[3] = {"Off", "6 -> 4", "6 -> 2"};
1935
1936 return snd_ctl_enum_info(uinfo, 1, 3, texts);
1937 }
1938
1939 static int snd_ac97_ad1888_downmix_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
1940 {
1941 struct snd_ac97 *ac97 = snd_kcontrol_chip(kcontrol);
1942 unsigned short val;
1943
1944 val = ac97->regs[AC97_AD_MISC];
1945 if (!(val & AC97_AD198X_DMIX1))
1946 ucontrol->value.enumerated.item[0] = 0;
1947 else
1948 ucontrol->value.enumerated.item[0] = 1 + ((val >> 8) & 1);
1949 return 0;
1950 }
1951
1952 static int snd_ac97_ad1888_downmix_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
1953 {
1954 struct snd_ac97 *ac97 = snd_kcontrol_chip(kcontrol);
1955 unsigned short val;
1956
1957 if (ucontrol->value.enumerated.item[0] > 2)
1958 return -EINVAL;
1959 if (ucontrol->value.enumerated.item[0] == 0)
1960 val = 0;
1961 else
1962 val = AC97_AD198X_DMIX1 |
1963 ((ucontrol->value.enumerated.item[0] - 1) << 8);
1964 return snd_ac97_update_bits(ac97, AC97_AD_MISC,
1965 AC97_AD198X_DMIX0 | AC97_AD198X_DMIX1, val);
1966 }
1967
1968 static void ad1888_update_jacks(struct snd_ac97 *ac97)
1969 {
1970 unsigned short val = 0;
1971
1972 if (!ac97->spec.ad18xx.lo_as_master && is_shared_linein(ac97))
1973 val |= (1 << 12);
1974
1975 if (is_shared_micin(ac97))
1976 val |= (1 << 11);
1977
1978 snd_ac97_update_bits(ac97, AC97_AD_MISC, (1 << 11) | (1 << 12), val);
1979 }
1980
1981 static const struct snd_kcontrol_new snd_ac97_ad1888_controls[] = {
1982 {
1983 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1984 .name = "Exchange Front/Surround",
1985 .info = snd_ac97_ad1888_lohpsel_info,
1986 .get = snd_ac97_ad1888_lohpsel_get,
1987 .put = snd_ac97_ad1888_lohpsel_put
1988 },
1989 AC97_SINGLE("V_REFOUT Enable", AC97_AD_MISC, AC97_AD_VREFD_SHIFT, 1, 1),
1990 AC97_SINGLE("High Pass Filter Enable", AC97_AD_TEST2,
1991 AC97_AD_HPFD_SHIFT, 1, 1),
1992 AC97_SINGLE("Spread Front to Surround and Center/LFE", AC97_AD_MISC, 7, 1, 0),
1993 {
1994 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1995 .name = "Downmix",
1996 .info = snd_ac97_ad1888_downmix_info,
1997 .get = snd_ac97_ad1888_downmix_get,
1998 .put = snd_ac97_ad1888_downmix_put
1999 },
2000 AC97_SURROUND_JACK_MODE_CTL,
2001 AC97_CHANNEL_MODE_CTL,
2002
2003 AC97_SINGLE("Headphone Jack Sense", AC97_AD_JACK_SPDIF, 10, 1, 0),
2004 AC97_SINGLE("Line Jack Sense", AC97_AD_JACK_SPDIF, 12, 1, 0),
2005 };
2006
2007 static int patch_ad1888_specific(struct snd_ac97 *ac97)
2008 {
2009 if (!ac97->spec.ad18xx.lo_as_master) {
2010
2011 snd_ac97_rename_vol_ctl(ac97, "Master Playback",
2012 "Master Surround Playback");
2013 snd_ac97_rename_vol_ctl(ac97, "Headphone Playback",
2014 "Master Playback");
2015 }
2016 return patch_build_controls(ac97, snd_ac97_ad1888_controls, ARRAY_SIZE(snd_ac97_ad1888_controls));
2017 }
2018
2019 static const struct snd_ac97_build_ops patch_ad1888_build_ops = {
2020 .build_post_spdif = patch_ad198x_post_spdif,
2021 .build_specific = patch_ad1888_specific,
2022 #ifdef CONFIG_PM
2023 .resume = ad1888_resume,
2024 #endif
2025 .update_jacks = ad1888_update_jacks,
2026 };
2027
2028 static int patch_ad1888(struct snd_ac97 * ac97)
2029 {
2030 unsigned short misc;
2031
2032 patch_ad1881(ac97);
2033 ac97->build_ops = &patch_ad1888_build_ops;
2034
2035
2036
2037
2038
2039 if (ac97->subsystem_vendor == 0x1043 &&
2040 ac97->subsystem_device == 0x1193)
2041 ac97->spec.ad18xx.lo_as_master = 1;
2042
2043 misc = snd_ac97_read(ac97, AC97_AD_MISC);
2044
2045
2046 misc |= AC97_AD198X_MSPLT | AC97_AD198X_AC97NC;
2047 if (!ac97->spec.ad18xx.lo_as_master)
2048
2049
2050
2051
2052 misc |= AC97_AD198X_LOSEL | AC97_AD198X_HPSEL;
2053
2054 snd_ac97_write_cache(ac97, AC97_AD_MISC, misc);
2055 ac97->flags |= AC97_STEREO_MUTES;
2056 return 0;
2057 }
2058
2059 static int patch_ad1980_specific(struct snd_ac97 *ac97)
2060 {
2061 int err;
2062
2063 if ((err = patch_ad1888_specific(ac97)) < 0)
2064 return err;
2065 return patch_build_controls(ac97, &snd_ac97_ad198x_2cmic, 1);
2066 }
2067
2068 static const struct snd_ac97_build_ops patch_ad1980_build_ops = {
2069 .build_post_spdif = patch_ad198x_post_spdif,
2070 .build_specific = patch_ad1980_specific,
2071 #ifdef CONFIG_PM
2072 .resume = ad18xx_resume,
2073 #endif
2074 .update_jacks = ad1888_update_jacks,
2075 };
2076
2077 static int patch_ad1980(struct snd_ac97 * ac97)
2078 {
2079 patch_ad1888(ac97);
2080 ac97->build_ops = &patch_ad1980_build_ops;
2081 return 0;
2082 }
2083
2084 static int snd_ac97_ad1985_vrefout_info(struct snd_kcontrol *kcontrol,
2085 struct snd_ctl_elem_info *uinfo)
2086 {
2087 static const char * const texts[4] = {
2088 "High-Z", "3.7 V", "2.25 V", "0 V"
2089 };
2090
2091 return snd_ctl_enum_info(uinfo, 1, 4, texts);
2092 }
2093
2094 static int snd_ac97_ad1985_vrefout_get(struct snd_kcontrol *kcontrol,
2095 struct snd_ctl_elem_value *ucontrol)
2096 {
2097 static const int reg2ctrl[4] = {2, 0, 1, 3};
2098 struct snd_ac97 *ac97 = snd_kcontrol_chip(kcontrol);
2099 unsigned short val;
2100 val = (ac97->regs[AC97_AD_MISC] & AC97_AD198X_VREF_MASK)
2101 >> AC97_AD198X_VREF_SHIFT;
2102 ucontrol->value.enumerated.item[0] = reg2ctrl[val];
2103 return 0;
2104 }
2105
2106 static int snd_ac97_ad1985_vrefout_put(struct snd_kcontrol *kcontrol,
2107 struct snd_ctl_elem_value *ucontrol)
2108 {
2109 static const int ctrl2reg[4] = {1, 2, 0, 3};
2110 struct snd_ac97 *ac97 = snd_kcontrol_chip(kcontrol);
2111 unsigned short val;
2112
2113 if (ucontrol->value.enumerated.item[0] > 3)
2114 return -EINVAL;
2115 val = ctrl2reg[ucontrol->value.enumerated.item[0]]
2116 << AC97_AD198X_VREF_SHIFT;
2117 return snd_ac97_update_bits(ac97, AC97_AD_MISC,
2118 AC97_AD198X_VREF_MASK, val);
2119 }
2120
2121 static const struct snd_kcontrol_new snd_ac97_ad1985_controls[] = {
2122 AC97_SINGLE("Exchange Center/LFE", AC97_AD_SERIAL_CFG, 3, 1, 0),
2123 {
2124 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
2125 .name = "Exchange Front/Surround",
2126 .info = snd_ac97_ad1888_lohpsel_info,
2127 .get = snd_ac97_ad1888_lohpsel_get,
2128 .put = snd_ac97_ad1888_lohpsel_put
2129 },
2130 AC97_SINGLE("High Pass Filter Enable", AC97_AD_TEST2, 12, 1, 1),
2131 AC97_SINGLE("Spread Front to Surround and Center/LFE",
2132 AC97_AD_MISC, 7, 1, 0),
2133 {
2134 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
2135 .name = "Downmix",
2136 .info = snd_ac97_ad1888_downmix_info,
2137 .get = snd_ac97_ad1888_downmix_get,
2138 .put = snd_ac97_ad1888_downmix_put
2139 },
2140 {
2141 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
2142 .name = "V_REFOUT",
2143 .info = snd_ac97_ad1985_vrefout_info,
2144 .get = snd_ac97_ad1985_vrefout_get,
2145 .put = snd_ac97_ad1985_vrefout_put
2146 },
2147 AC97_SURROUND_JACK_MODE_CTL,
2148 AC97_CHANNEL_MODE_CTL,
2149
2150 AC97_SINGLE("Headphone Jack Sense", AC97_AD_JACK_SPDIF, 10, 1, 0),
2151 AC97_SINGLE("Line Jack Sense", AC97_AD_JACK_SPDIF, 12, 1, 0),
2152 };
2153
2154 static void ad1985_update_jacks(struct snd_ac97 *ac97)
2155 {
2156 ad1888_update_jacks(ac97);
2157
2158 snd_ac97_update_bits(ac97, AC97_AD_SERIAL_CFG, 1 << 9,
2159 is_shared_micin(ac97) ? 1 << 9 : 0);
2160 }
2161
2162 static int patch_ad1985_specific(struct snd_ac97 *ac97)
2163 {
2164 int err;
2165
2166
2167 snd_ac97_rename_vol_ctl(ac97, "Master Playback",
2168 "Master Surround Playback");
2169 snd_ac97_rename_vol_ctl(ac97, "Headphone Playback", "Master Playback");
2170
2171 if ((err = patch_build_controls(ac97, &snd_ac97_ad198x_2cmic, 1)) < 0)
2172 return err;
2173
2174 return patch_build_controls(ac97, snd_ac97_ad1985_controls,
2175 ARRAY_SIZE(snd_ac97_ad1985_controls));
2176 }
2177
2178 static const struct snd_ac97_build_ops patch_ad1985_build_ops = {
2179 .build_post_spdif = patch_ad198x_post_spdif,
2180 .build_specific = patch_ad1985_specific,
2181 #ifdef CONFIG_PM
2182 .resume = ad18xx_resume,
2183 #endif
2184 .update_jacks = ad1985_update_jacks,
2185 };
2186
2187 static int patch_ad1985(struct snd_ac97 * ac97)
2188 {
2189 unsigned short misc;
2190
2191 patch_ad1881(ac97);
2192 ac97->build_ops = &patch_ad1985_build_ops;
2193 misc = snd_ac97_read(ac97, AC97_AD_MISC);
2194
2195
2196
2197 snd_ac97_write_cache(ac97, AC97_AD_MISC, misc |
2198 AC97_AD198X_LOSEL |
2199 AC97_AD198X_HPSEL |
2200 AC97_AD198X_MSPLT |
2201 AC97_AD198X_AC97NC);
2202 ac97->flags |= AC97_STEREO_MUTES;
2203
2204
2205 ad1985_update_jacks(ac97);
2206
2207
2208 ac97->ext_id = (ac97->ext_id & ~AC97_EI_REV_MASK) | AC97_EI_REV_23;
2209 return 0;
2210 }
2211
2212 #define snd_ac97_ad1986_bool_info snd_ctl_boolean_mono_info
2213
2214 static int snd_ac97_ad1986_lososel_get(struct snd_kcontrol *kcontrol,
2215 struct snd_ctl_elem_value *ucontrol)
2216 {
2217 struct snd_ac97 *ac97 = snd_kcontrol_chip(kcontrol);
2218 unsigned short val;
2219
2220 val = ac97->regs[AC97_AD_MISC3];
2221 ucontrol->value.integer.value[0] = (val & AC97_AD1986_LOSEL) != 0;
2222 return 0;
2223 }
2224
2225 static int snd_ac97_ad1986_lososel_put(struct snd_kcontrol *kcontrol,
2226 struct snd_ctl_elem_value *ucontrol)
2227 {
2228 struct snd_ac97 *ac97 = snd_kcontrol_chip(kcontrol);
2229 int ret0;
2230 int ret1;
2231 int sprd = (ac97->regs[AC97_AD_MISC] & AC97_AD1986_SPRD) != 0;
2232
2233 ret0 = snd_ac97_update_bits(ac97, AC97_AD_MISC3, AC97_AD1986_LOSEL,
2234 ucontrol->value.integer.value[0] != 0
2235 ? AC97_AD1986_LOSEL : 0);
2236 if (ret0 < 0)
2237 return ret0;
2238
2239
2240 ret1 = snd_ac97_update_bits(ac97, AC97_AD_MISC, AC97_AD1986_SOSEL,
2241 (ucontrol->value.integer.value[0] != 0
2242 || sprd)
2243 ? AC97_AD1986_SOSEL : 0);
2244 if (ret1 < 0)
2245 return ret1;
2246
2247 return (ret0 > 0 || ret1 > 0) ? 1 : 0;
2248 }
2249
2250 static int snd_ac97_ad1986_spread_get(struct snd_kcontrol *kcontrol,
2251 struct snd_ctl_elem_value *ucontrol)
2252 {
2253 struct snd_ac97 *ac97 = snd_kcontrol_chip(kcontrol);
2254 unsigned short val;
2255
2256 val = ac97->regs[AC97_AD_MISC];
2257 ucontrol->value.integer.value[0] = (val & AC97_AD1986_SPRD) != 0;
2258 return 0;
2259 }
2260
2261 static int snd_ac97_ad1986_spread_put(struct snd_kcontrol *kcontrol,
2262 struct snd_ctl_elem_value *ucontrol)
2263 {
2264 struct snd_ac97 *ac97 = snd_kcontrol_chip(kcontrol);
2265 int ret0;
2266 int ret1;
2267 int sprd = (ac97->regs[AC97_AD_MISC3] & AC97_AD1986_LOSEL) != 0;
2268
2269 ret0 = snd_ac97_update_bits(ac97, AC97_AD_MISC, AC97_AD1986_SPRD,
2270 ucontrol->value.integer.value[0] != 0
2271 ? AC97_AD1986_SPRD : 0);
2272 if (ret0 < 0)
2273 return ret0;
2274
2275
2276 ret1 = snd_ac97_update_bits(ac97, AC97_AD_MISC, AC97_AD1986_SOSEL,
2277 (ucontrol->value.integer.value[0] != 0
2278 || sprd)
2279 ? AC97_AD1986_SOSEL : 0);
2280 if (ret1 < 0)
2281 return ret1;
2282
2283 return (ret0 > 0 || ret1 > 0) ? 1 : 0;
2284 }
2285
2286 static int snd_ac97_ad1986_miclisel_get(struct snd_kcontrol *kcontrol,
2287 struct snd_ctl_elem_value *ucontrol)
2288 {
2289 struct snd_ac97 *ac97 = snd_kcontrol_chip(kcontrol);
2290
2291 ucontrol->value.integer.value[0] = ac97->spec.ad18xx.swap_mic_linein;
2292 return 0;
2293 }
2294
2295 static int snd_ac97_ad1986_miclisel_put(struct snd_kcontrol *kcontrol,
2296 struct snd_ctl_elem_value *ucontrol)
2297 {
2298 struct snd_ac97 *ac97 = snd_kcontrol_chip(kcontrol);
2299 unsigned char swap = ucontrol->value.integer.value[0] != 0;
2300
2301 if (swap != ac97->spec.ad18xx.swap_mic_linein) {
2302 ac97->spec.ad18xx.swap_mic_linein = swap;
2303 if (ac97->build_ops->update_jacks)
2304 ac97->build_ops->update_jacks(ac97);
2305 return 1;
2306 }
2307 return 0;
2308 }
2309
2310 static int snd_ac97_ad1986_vrefout_get(struct snd_kcontrol *kcontrol,
2311 struct snd_ctl_elem_value *ucontrol)
2312 {
2313
2314 struct snd_ac97 *ac97 = snd_kcontrol_chip(kcontrol);
2315 unsigned short val;
2316 unsigned short reg = ac97->regs[AC97_AD_MISC2];
2317 if ((reg & AC97_AD1986_MVREF0) != 0)
2318 val = 2;
2319 else if ((reg & AC97_AD1986_MVREF1) != 0)
2320 val = 3;
2321 else if ((reg & AC97_AD1986_MVREF2) != 0)
2322 val = 1;
2323 else
2324 val = 0;
2325 ucontrol->value.enumerated.item[0] = val;
2326 return 0;
2327 }
2328
2329 static int snd_ac97_ad1986_vrefout_put(struct snd_kcontrol *kcontrol,
2330 struct snd_ctl_elem_value *ucontrol)
2331 {
2332 struct snd_ac97 *ac97 = snd_kcontrol_chip(kcontrol);
2333 unsigned short cval;
2334 unsigned short lval;
2335 unsigned short mval;
2336 int cret;
2337 int lret;
2338 int mret;
2339
2340 switch (ucontrol->value.enumerated.item[0])
2341 {
2342 case 0:
2343 cval = 0;
2344 lval = 0;
2345 mval = 0;
2346 break;
2347 case 1:
2348 cval = AC97_AD1986_CVREF2;
2349 lval = AC97_AD1986_LVREF2;
2350 mval = AC97_AD1986_MVREF2;
2351 break;
2352 case 2:
2353 cval = AC97_AD1986_CVREF0;
2354 lval = AC97_AD1986_LVREF0;
2355 mval = AC97_AD1986_MVREF0;
2356 break;
2357 case 3:
2358 cval = AC97_AD1986_CVREF1;
2359 lval = AC97_AD1986_LVREF1;
2360 mval = AC97_AD1986_MVREF1;
2361 break;
2362 default:
2363 return -EINVAL;
2364 }
2365
2366 cret = snd_ac97_update_bits(ac97, AC97_AD_MISC2,
2367 AC97_AD1986_CVREF_MASK, cval);
2368 if (cret < 0)
2369 return cret;
2370 lret = snd_ac97_update_bits(ac97, AC97_AD_MISC3,
2371 AC97_AD1986_LVREF_MASK, lval);
2372 if (lret < 0)
2373 return lret;
2374 mret = snd_ac97_update_bits(ac97, AC97_AD_MISC2,
2375 AC97_AD1986_MVREF_MASK, mval);
2376 if (mret < 0)
2377 return mret;
2378
2379 return (cret > 0 || lret > 0 || mret > 0) ? 1 : 0;
2380 }
2381
2382 static const struct snd_kcontrol_new snd_ac97_ad1986_controls[] = {
2383 AC97_SINGLE("Exchange Center/LFE", AC97_AD_SERIAL_CFG, 3, 1, 0),
2384 {
2385 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
2386 .name = "Exchange Front/Surround",
2387 .info = snd_ac97_ad1986_bool_info,
2388 .get = snd_ac97_ad1986_lososel_get,
2389 .put = snd_ac97_ad1986_lososel_put
2390 },
2391 {
2392 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
2393 .name = "Exchange Mic/Line In",
2394 .info = snd_ac97_ad1986_bool_info,
2395 .get = snd_ac97_ad1986_miclisel_get,
2396 .put = snd_ac97_ad1986_miclisel_put
2397 },
2398 {
2399 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
2400 .name = "Spread Front to Surround and Center/LFE",
2401 .info = snd_ac97_ad1986_bool_info,
2402 .get = snd_ac97_ad1986_spread_get,
2403 .put = snd_ac97_ad1986_spread_put
2404 },
2405 {
2406 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
2407 .name = "Downmix",
2408 .info = snd_ac97_ad1888_downmix_info,
2409 .get = snd_ac97_ad1888_downmix_get,
2410 .put = snd_ac97_ad1888_downmix_put
2411 },
2412 {
2413 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
2414 .name = "V_REFOUT",
2415 .info = snd_ac97_ad1985_vrefout_info,
2416 .get = snd_ac97_ad1986_vrefout_get,
2417 .put = snd_ac97_ad1986_vrefout_put
2418 },
2419 AC97_SURROUND_JACK_MODE_CTL,
2420 AC97_CHANNEL_MODE_CTL,
2421
2422 AC97_SINGLE("Headphone Jack Sense", AC97_AD_JACK_SPDIF, 10, 1, 0),
2423 AC97_SINGLE("Line Jack Sense", AC97_AD_JACK_SPDIF, 12, 1, 0)
2424 };
2425
2426 static void ad1986_update_jacks(struct snd_ac97 *ac97)
2427 {
2428 unsigned short misc_val = 0;
2429 unsigned short ser_val;
2430
2431
2432 if (!is_surround_on(ac97))
2433 misc_val |= AC97_AD1986_SODIS;
2434 if (!is_clfe_on(ac97))
2435 misc_val |= AC97_AD1986_CLDIS;
2436
2437
2438 if (is_shared_linein(ac97))
2439 misc_val |= AC97_AD1986_LISEL_SURR;
2440 else if (ac97->spec.ad18xx.swap_mic_linein != 0)
2441 misc_val |= AC97_AD1986_LISEL_MIC;
2442 snd_ac97_update_bits(ac97, AC97_AD_MISC,
2443 AC97_AD1986_SODIS | AC97_AD1986_CLDIS |
2444 AC97_AD1986_LISEL_MASK,
2445 misc_val);
2446
2447
2448 if (is_shared_micin(ac97))
2449 ser_val = AC97_AD1986_OMS_C;
2450 else if (ac97->spec.ad18xx.swap_mic_linein != 0)
2451 ser_val = AC97_AD1986_OMS_L;
2452 else
2453 ser_val = AC97_AD1986_OMS_M;
2454 snd_ac97_update_bits(ac97, AC97_AD_SERIAL_CFG,
2455 AC97_AD1986_OMS_MASK,
2456 ser_val);
2457 }
2458
2459 static int patch_ad1986_specific(struct snd_ac97 *ac97)
2460 {
2461 int err;
2462
2463 if ((err = patch_build_controls(ac97, &snd_ac97_ad198x_2cmic, 1)) < 0)
2464 return err;
2465
2466 return patch_build_controls(ac97, snd_ac97_ad1986_controls,
2467 ARRAY_SIZE(snd_ac97_ad1985_controls));
2468 }
2469
2470 static const struct snd_ac97_build_ops patch_ad1986_build_ops = {
2471 .build_post_spdif = patch_ad198x_post_spdif,
2472 .build_specific = patch_ad1986_specific,
2473 #ifdef CONFIG_PM
2474 .resume = ad18xx_resume,
2475 #endif
2476 .update_jacks = ad1986_update_jacks,
2477 };
2478
2479 static int patch_ad1986(struct snd_ac97 * ac97)
2480 {
2481 patch_ad1881(ac97);
2482 ac97->build_ops = &patch_ad1986_build_ops;
2483 ac97->flags |= AC97_STEREO_MUTES;
2484
2485
2486 ad1986_update_jacks(ac97);
2487
2488 return 0;
2489 }
2490
2491
2492
2493
2494 static int patch_alc203(struct snd_ac97 *ac97)
2495 {
2496 snd_ac97_update_bits(ac97, 0x7a, 0x400, 0x400);
2497 return 0;
2498 }
2499
2500
2501
2502
2503 static void alc650_update_jacks(struct snd_ac97 *ac97)
2504 {
2505 int shared;
2506
2507
2508 shared = is_shared_surrout(ac97);
2509 snd_ac97_update_bits(ac97, AC97_ALC650_MULTICH, 1 << 9,
2510 shared ? (1 << 9) : 0);
2511
2512 shared = is_shared_clfeout(ac97);
2513
2514 snd_ac97_update_bits(ac97, AC97_ALC650_CLOCK, 1 << 12,
2515 shared ? (1 << 12) : 0);
2516
2517 snd_ac97_update_bits(ac97, AC97_ALC650_MULTICH, 1 << 10,
2518 shared ? (1 << 10) : 0);
2519
2520 snd_ac97_update_bits(ac97, AC97_ALC650_GPIO_STATUS, 0x100,
2521 shared ? 0 : 0x100);
2522 }
2523
2524 static int alc650_swap_surround_put(struct snd_kcontrol *kcontrol,
2525 struct snd_ctl_elem_value *ucontrol)
2526 {
2527 struct snd_ac97 *ac97 = snd_kcontrol_chip(kcontrol);
2528 struct snd_pcm_chmap *map = ac97->chmaps[SNDRV_PCM_STREAM_PLAYBACK];
2529
2530 if (map) {
2531 if (ucontrol->value.integer.value[0])
2532 map->chmap = snd_pcm_std_chmaps;
2533 else
2534 map->chmap = snd_pcm_alt_chmaps;
2535 }
2536 return snd_ac97_put_volsw(kcontrol, ucontrol);
2537 }
2538
2539 static const struct snd_kcontrol_new snd_ac97_controls_alc650[] = {
2540 AC97_SINGLE("Duplicate Front", AC97_ALC650_MULTICH, 0, 1, 0),
2541 AC97_SINGLE("Surround Down Mix", AC97_ALC650_MULTICH, 1, 1, 0),
2542 AC97_SINGLE("Center/LFE Down Mix", AC97_ALC650_MULTICH, 2, 1, 0),
2543 AC97_SINGLE("Exchange Center/LFE", AC97_ALC650_MULTICH, 3, 1, 0),
2544
2545
2546
2547
2548
2549
2550
2551
2552 {
2553 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
2554 .name = "Swap Surround Slot",
2555 .info = snd_ac97_info_volsw,
2556 .get = snd_ac97_get_volsw,
2557 .put = alc650_swap_surround_put,
2558 .private_value = AC97_SINGLE_VALUE(AC97_ALC650_MULTICH, 14, 1, 0),
2559 },
2560 #if 0
2561 AC97_SINGLE("IEC958 Input Clock Enable", AC97_ALC650_CLOCK, 0, 1, 0),
2562 AC97_SINGLE("IEC958 Input Pin Enable", AC97_ALC650_CLOCK, 1, 1, 0),
2563 AC97_SINGLE("Surround DAC Switch", AC97_ALC650_SURR_DAC_VOL, 15, 1, 1),
2564 AC97_DOUBLE("Surround DAC Volume", AC97_ALC650_SURR_DAC_VOL, 8, 0, 31, 1),
2565 AC97_SINGLE("Center/LFE DAC Switch", AC97_ALC650_LFE_DAC_VOL, 15, 1, 1),
2566 AC97_DOUBLE("Center/LFE DAC Volume", AC97_ALC650_LFE_DAC_VOL, 8, 0, 31, 1),
2567 #endif
2568 AC97_SURROUND_JACK_MODE_CTL,
2569 AC97_CHANNEL_MODE_CTL,
2570 };
2571
2572 static const struct snd_kcontrol_new snd_ac97_spdif_controls_alc650[] = {
2573 AC97_SINGLE(SNDRV_CTL_NAME_IEC958("",CAPTURE,SWITCH), AC97_ALC650_MULTICH, 11, 1, 0),
2574 AC97_SINGLE("Analog to IEC958 Output", AC97_ALC650_MULTICH, 12, 1, 0),
2575
2576
2577 };
2578
2579 static const DECLARE_TLV_DB_SCALE(db_scale_5bit_3db_max, -4350, 150, 0);
2580
2581 static int patch_alc650_specific(struct snd_ac97 * ac97)
2582 {
2583 int err;
2584
2585 if ((err = patch_build_controls(ac97, snd_ac97_controls_alc650, ARRAY_SIZE(snd_ac97_controls_alc650))) < 0)
2586 return err;
2587 if (ac97->ext_id & AC97_EI_SPDIF) {
2588 if ((err = patch_build_controls(ac97, snd_ac97_spdif_controls_alc650, ARRAY_SIZE(snd_ac97_spdif_controls_alc650))) < 0)
2589 return err;
2590 }
2591 if (ac97->id != AC97_ID_ALC650F)
2592 reset_tlv(ac97, "Master Playback Volume",
2593 db_scale_5bit_3db_max);
2594 return 0;
2595 }
2596
2597 static const struct snd_ac97_build_ops patch_alc650_ops = {
2598 .build_specific = patch_alc650_specific,
2599 .update_jacks = alc650_update_jacks
2600 };
2601
2602 static int patch_alc650(struct snd_ac97 * ac97)
2603 {
2604 unsigned short val;
2605
2606 ac97->build_ops = &patch_alc650_ops;
2607
2608
2609 val = snd_ac97_read(ac97, AC97_ALC650_REVISION) & 0x3f;
2610 if (val < 3)
2611 ac97->id = 0x414c4720;
2612 else if (val < 0x10)
2613 ac97->id = 0x414c4721;
2614 else if (val < 0x20)
2615 ac97->id = 0x414c4722;
2616 else if (val < 0x30)
2617 ac97->id = 0x414c4723;
2618
2619
2620
2621 ac97->spec.dev_flags = (ac97->id == 0x414c4722 ||
2622 ac97->id == 0x414c4723);
2623
2624
2625 snd_ac97_write_cache(ac97, AC97_ALC650_GPIO_STATUS,
2626 snd_ac97_read(ac97, AC97_ALC650_GPIO_STATUS) | 0x8000);
2627
2628
2629 val = snd_ac97_read(ac97, AC97_ALC650_CLOCK);
2630
2631 if (ac97->spec.dev_flags &&
2632
2633 ! (ac97->subsystem_vendor == 0x1043 &&
2634 ac97->subsystem_device == 0x1103))
2635 val |= 0x03;
2636 else
2637 val &= ~0x03;
2638 snd_ac97_write_cache(ac97, AC97_ALC650_CLOCK, val);
2639
2640
2641
2642
2643
2644
2645 snd_ac97_write_cache(ac97, AC97_ALC650_MULTICH, 0);
2646
2647
2648
2649 snd_ac97_write_cache(ac97, AC97_ALC650_GPIO_SETUP,
2650 snd_ac97_read(ac97, AC97_ALC650_GPIO_SETUP) | 0x01);
2651 snd_ac97_write_cache(ac97, AC97_ALC650_GPIO_STATUS,
2652 (snd_ac97_read(ac97, AC97_ALC650_GPIO_STATUS) | 0x100) & ~0x10);
2653
2654
2655 snd_ac97_write_cache(ac97, AC97_ALC650_SURR_DAC_VOL, 0x0808);
2656 snd_ac97_write_cache(ac97, AC97_ALC650_LFE_DAC_VOL, 0x0808);
2657 return 0;
2658 }
2659
2660 static void alc655_update_jacks(struct snd_ac97 *ac97)
2661 {
2662 int shared;
2663
2664
2665 shared = is_shared_surrout(ac97);
2666 ac97_update_bits_page(ac97, AC97_ALC650_MULTICH, 1 << 9,
2667 shared ? (1 << 9) : 0, 0);
2668
2669 shared = is_shared_clfeout(ac97);
2670
2671 snd_ac97_update_bits(ac97, AC97_ALC650_CLOCK, 1 << 12,
2672 shared ? (1 << 12) : 0);
2673 ac97_update_bits_page(ac97, AC97_ALC650_MULTICH, 1 << 10,
2674 shared ? (1 << 10) : 0, 0);
2675 }
2676
2677 static const struct snd_kcontrol_new snd_ac97_controls_alc655[] = {
2678 AC97_PAGE_SINGLE("Duplicate Front", AC97_ALC650_MULTICH, 0, 1, 0, 0),
2679 AC97_SURROUND_JACK_MODE_CTL,
2680 AC97_CHANNEL_MODE_CTL,
2681 };
2682
2683 static int alc655_iec958_route_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo)
2684 {
2685 static const char * const texts_655[3] = {
2686 "PCM", "Analog In", "IEC958 In"
2687 };
2688 static const char * const texts_658[4] = {
2689 "PCM", "Analog1 In", "Analog2 In", "IEC958 In"
2690 };
2691 struct snd_ac97 *ac97 = snd_kcontrol_chip(kcontrol);
2692
2693 if (ac97->spec.dev_flags)
2694 return snd_ctl_enum_info(uinfo, 1, 4, texts_658);
2695 else
2696 return snd_ctl_enum_info(uinfo, 1, 3, texts_655);
2697 }
2698
2699 static int alc655_iec958_route_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
2700 {
2701 struct snd_ac97 *ac97 = snd_kcontrol_chip(kcontrol);
2702 unsigned short val;
2703
2704 val = ac97->regs[AC97_ALC650_MULTICH];
2705 val = (val >> 12) & 3;
2706 if (ac97->spec.dev_flags && val == 3)
2707 val = 0;
2708 ucontrol->value.enumerated.item[0] = val;
2709 return 0;
2710 }
2711
2712 static int alc655_iec958_route_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
2713 {
2714 struct snd_ac97 *ac97 = snd_kcontrol_chip(kcontrol);
2715
2716 return ac97_update_bits_page(ac97, AC97_ALC650_MULTICH, 3 << 12,
2717 (unsigned short)ucontrol->value.enumerated.item[0] << 12,
2718 0);
2719 }
2720
2721 static const struct snd_kcontrol_new snd_ac97_spdif_controls_alc655[] = {
2722 AC97_PAGE_SINGLE(SNDRV_CTL_NAME_IEC958("",CAPTURE,SWITCH), AC97_ALC650_MULTICH, 11, 1, 0, 0),
2723
2724
2725 {
2726 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
2727 .name = SNDRV_CTL_NAME_IEC958("",PLAYBACK,NONE) "Source",
2728 .info = alc655_iec958_route_info,
2729 .get = alc655_iec958_route_get,
2730 .put = alc655_iec958_route_put,
2731 },
2732 };
2733
2734 static int patch_alc655_specific(struct snd_ac97 * ac97)
2735 {
2736 int err;
2737
2738 if ((err = patch_build_controls(ac97, snd_ac97_controls_alc655, ARRAY_SIZE(snd_ac97_controls_alc655))) < 0)
2739 return err;
2740 if (ac97->ext_id & AC97_EI_SPDIF) {
2741 if ((err = patch_build_controls(ac97, snd_ac97_spdif_controls_alc655, ARRAY_SIZE(snd_ac97_spdif_controls_alc655))) < 0)
2742 return err;
2743 }
2744 return 0;
2745 }
2746
2747 static const struct snd_ac97_build_ops patch_alc655_ops = {
2748 .build_specific = patch_alc655_specific,
2749 .update_jacks = alc655_update_jacks
2750 };
2751
2752 static int patch_alc655(struct snd_ac97 * ac97)
2753 {
2754 unsigned int val;
2755
2756 if (ac97->id == AC97_ID_ALC658) {
2757 ac97->spec.dev_flags = 1;
2758 if ((snd_ac97_read(ac97, AC97_ALC650_REVISION) & 0x3f) == 2) {
2759 ac97->id = AC97_ID_ALC658D;
2760 ac97->spec.dev_flags = 2;
2761 }
2762 }
2763
2764 ac97->build_ops = &patch_alc655_ops;
2765
2766
2767 snd_ac97_update_bits(ac97, AC97_INT_PAGING, AC97_PAGE_MASK, AC97_PAGE_VENDOR);
2768
2769
2770 val = snd_ac97_read(ac97, 0x7a);
2771 if (ac97->spec.dev_flags)
2772 val &= ~(1 << 1);
2773 else {
2774 if (ac97->subsystem_vendor == 0x1462 &&
2775 (ac97->subsystem_device == 0x0131 ||
2776 ac97->subsystem_device == 0x0161 ||
2777 ac97->subsystem_device == 0x0351 ||
2778 ac97->subsystem_device == 0x0471 ||
2779 ac97->subsystem_device == 0x0061))
2780 val &= ~(1 << 1);
2781 else
2782 val |= (1 << 1);
2783
2784 ac97->ext_id |= AC97_EI_SPDIF;
2785 }
2786 val &= ~(1 << 12);
2787 snd_ac97_write_cache(ac97, 0x7a, val);
2788
2789
2790
2791
2792
2793 snd_ac97_write_cache(ac97, AC97_ALC650_MULTICH, 1<<15);
2794
2795
2796 snd_ac97_write_cache(ac97, AC97_ALC650_SURR_DAC_VOL, 0x0808);
2797 snd_ac97_write_cache(ac97, AC97_ALC650_LFE_DAC_VOL, 0x0808);
2798
2799
2800 if (ac97->id == AC97_ID_ALC658D)
2801 snd_ac97_update_bits(ac97, 0x74, 0x0800, 0x0800);
2802
2803 return 0;
2804 }
2805
2806
2807 #define AC97_ALC850_JACK_SELECT 0x76
2808 #define AC97_ALC850_MISC1 0x7a
2809 #define AC97_ALC850_MULTICH 0x6a
2810
2811 static void alc850_update_jacks(struct snd_ac97 *ac97)
2812 {
2813 int shared;
2814 int aux_is_back_surround;
2815
2816
2817 shared = is_shared_surrout(ac97);
2818
2819 snd_ac97_update_bits(ac97, AC97_ALC850_MISC1, (1<<4)|(1<<5),
2820 shared ? (1<<5) : (1<<4));
2821
2822 snd_ac97_update_bits(ac97, AC97_ALC850_JACK_SELECT, 7 << 12,
2823 shared ? (2<<12) : (0<<12));
2824
2825 shared = is_shared_clfeout(ac97);
2826
2827 snd_ac97_update_bits(ac97, AC97_ALC850_MISC1, (1<<12)|(1<<13),
2828 shared ? (1<<12) : (1<<13));
2829
2830 snd_ac97_update_bits(ac97, AC97_ALC850_JACK_SELECT, 7 << 4,
2831 shared ? (5<<4) : (1<<4));
2832
2833 aux_is_back_surround = alc850_is_aux_back_surround(ac97);
2834
2835 snd_ac97_update_bits(ac97, AC97_ALC850_MULTICH, 1 << 10,
2836 aux_is_back_surround ? (1<<10) : (0<<10));
2837 }
2838
2839 static const struct snd_kcontrol_new snd_ac97_controls_alc850[] = {
2840 AC97_PAGE_SINGLE("Duplicate Front", AC97_ALC650_MULTICH, 0, 1, 0, 0),
2841 AC97_SINGLE("Mic Front Input Switch", AC97_ALC850_JACK_SELECT, 15, 1, 1),
2842 AC97_SURROUND_JACK_MODE_CTL,
2843 AC97_CHANNEL_MODE_8CH_CTL,
2844 };
2845
2846 static int patch_alc850_specific(struct snd_ac97 *ac97)
2847 {
2848 int err;
2849
2850 if ((err = patch_build_controls(ac97, snd_ac97_controls_alc850, ARRAY_SIZE(snd_ac97_controls_alc850))) < 0)
2851 return err;
2852 if (ac97->ext_id & AC97_EI_SPDIF) {
2853 if ((err = patch_build_controls(ac97, snd_ac97_spdif_controls_alc655, ARRAY_SIZE(snd_ac97_spdif_controls_alc655))) < 0)
2854 return err;
2855 }
2856 return 0;
2857 }
2858
2859 static const struct snd_ac97_build_ops patch_alc850_ops = {
2860 .build_specific = patch_alc850_specific,
2861 .update_jacks = alc850_update_jacks
2862 };
2863
2864 static int patch_alc850(struct snd_ac97 *ac97)
2865 {
2866 ac97->build_ops = &patch_alc850_ops;
2867
2868 ac97->spec.dev_flags = 0;
2869 ac97->flags |= AC97_HAS_8CH;
2870
2871
2872 snd_ac97_update_bits(ac97, AC97_INT_PAGING, AC97_PAGE_MASK, AC97_PAGE_VENDOR);
2873
2874
2875
2876
2877
2878
2879
2880
2881 snd_ac97_write_cache(ac97, AC97_ALC650_MULTICH, 1<<15);
2882
2883
2884
2885 snd_ac97_write_cache(ac97, 0x7a, (1<<1)|(1<<4)|(0<<5)|(1<<6)|
2886 (1<<7)|(0<<12)|(1<<13)|(0<<14));
2887
2888
2889
2890 snd_ac97_write_cache(ac97, 0x76, (0<<0)|(0<<2)|(1<<4)|(1<<7)|(2<<8)|
2891 (1<<11)|(0<<12)|(1<<15));
2892
2893
2894 snd_ac97_write_cache(ac97, AC97_ALC650_SURR_DAC_VOL, 0x0808);
2895 snd_ac97_write_cache(ac97, AC97_ALC650_LFE_DAC_VOL, 0x0808);
2896 return 0;
2897 }
2898
2899 static int patch_aztech_azf3328_specific(struct snd_ac97 *ac97)
2900 {
2901 struct snd_kcontrol *kctl_3d_center =
2902 snd_ac97_find_mixer_ctl(ac97, "3D Control - Center");
2903 struct snd_kcontrol *kctl_3d_depth =
2904 snd_ac97_find_mixer_ctl(ac97, "3D Control - Depth");
2905
2906
2907
2908
2909
2910 if (kctl_3d_center) {
2911 kctl_3d_center->private_value =
2912 AC97_SINGLE_VALUE(AC97_3D_CONTROL, 1, 0x07, 0);
2913 snd_ac97_rename_vol_ctl(ac97,
2914 "3D Control - Center", "3D Control - Width"
2915 );
2916 }
2917 if (kctl_3d_depth)
2918 kctl_3d_depth->private_value =
2919 AC97_SINGLE_VALUE(AC97_3D_CONTROL, 8, 0x03, 0);
2920
2921
2922
2923 snd_ac97_rename_vol_ctl(ac97,
2924 "Master Mono Playback", "Modem Playback"
2925 );
2926 snd_ac97_rename_vol_ctl(ac97,
2927 "Headphone Playback", "FM Synth Playback"
2928 );
2929
2930 return 0;
2931 }
2932
2933 static const struct snd_ac97_build_ops patch_aztech_azf3328_ops = {
2934 .build_specific = patch_aztech_azf3328_specific
2935 };
2936
2937 static int patch_aztech_azf3328(struct snd_ac97 *ac97)
2938 {
2939 ac97->build_ops = &patch_aztech_azf3328_ops;
2940 return 0;
2941 }
2942
2943
2944
2945
2946 static void cm9738_update_jacks(struct snd_ac97 *ac97)
2947 {
2948
2949 snd_ac97_update_bits(ac97, AC97_CM9738_VENDOR_CTRL, 1 << 10,
2950 is_shared_surrout(ac97) ? (1 << 10) : 0);
2951 }
2952
2953 static const struct snd_kcontrol_new snd_ac97_cm9738_controls[] = {
2954 AC97_SINGLE("Duplicate Front", AC97_CM9738_VENDOR_CTRL, 13, 1, 0),
2955 AC97_SURROUND_JACK_MODE_CTL,
2956 AC97_CHANNEL_MODE_4CH_CTL,
2957 };
2958
2959 static int patch_cm9738_specific(struct snd_ac97 * ac97)
2960 {
2961 return patch_build_controls(ac97, snd_ac97_cm9738_controls, ARRAY_SIZE(snd_ac97_cm9738_controls));
2962 }
2963
2964 static const struct snd_ac97_build_ops patch_cm9738_ops = {
2965 .build_specific = patch_cm9738_specific,
2966 .update_jacks = cm9738_update_jacks
2967 };
2968
2969 static int patch_cm9738(struct snd_ac97 * ac97)
2970 {
2971 ac97->build_ops = &patch_cm9738_ops;
2972
2973
2974 ac97->flags |= AC97_HAS_NO_PCM_VOL;
2975 snd_ac97_write_cache(ac97, AC97_PCM, 0x8000);
2976
2977 return 0;
2978 }
2979
2980 static int snd_ac97_cmedia_spdif_playback_source_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo)
2981 {
2982 static const char * const texts[] = { "Analog", "Digital" };
2983
2984 return snd_ctl_enum_info(uinfo, 1, 2, texts);
2985 }
2986
2987 static int snd_ac97_cmedia_spdif_playback_source_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
2988 {
2989 struct snd_ac97 *ac97 = snd_kcontrol_chip(kcontrol);
2990 unsigned short val;
2991
2992 val = ac97->regs[AC97_CM9739_SPDIF_CTRL];
2993 ucontrol->value.enumerated.item[0] = (val >> 1) & 0x01;
2994 return 0;
2995 }
2996
2997 static int snd_ac97_cmedia_spdif_playback_source_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
2998 {
2999 struct snd_ac97 *ac97 = snd_kcontrol_chip(kcontrol);
3000
3001 return snd_ac97_update_bits(ac97, AC97_CM9739_SPDIF_CTRL,
3002 0x01 << 1,
3003 (ucontrol->value.enumerated.item[0] & 0x01) << 1);
3004 }
3005
3006 static const struct snd_kcontrol_new snd_ac97_cm9739_controls_spdif[] = {
3007
3008 {
3009 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
3010 .name = SNDRV_CTL_NAME_IEC958("",PLAYBACK,NONE) "Source",
3011 .info = snd_ac97_cmedia_spdif_playback_source_info,
3012 .get = snd_ac97_cmedia_spdif_playback_source_get,
3013 .put = snd_ac97_cmedia_spdif_playback_source_put,
3014 },
3015
3016 AC97_SINGLE(SNDRV_CTL_NAME_IEC958("",CAPTURE,NONE) "Valid Switch", AC97_CM9739_SPDIF_CTRL, 2, 1, 0),
3017
3018 AC97_SINGLE(SNDRV_CTL_NAME_IEC958("",CAPTURE,NONE) "Monitor", AC97_CM9739_SPDIF_CTRL, 3, 1, 0),
3019
3020 AC97_SINGLE(SNDRV_CTL_NAME_IEC958("",CAPTURE,SWITCH), AC97_CM9739_SPDIF_CTRL, 4, 1, 0),
3021
3022 };
3023
3024 static void cm9739_update_jacks(struct snd_ac97 *ac97)
3025 {
3026
3027 snd_ac97_update_bits(ac97, AC97_CM9739_MULTI_CHAN, 1 << 10,
3028 is_shared_surrout(ac97) ? (1 << 10) : 0);
3029
3030 snd_ac97_update_bits(ac97, AC97_CM9739_MULTI_CHAN, 0x3000,
3031 is_shared_clfeout(ac97) ? 0x1000 : 0x2000);
3032 }
3033
3034 static const struct snd_kcontrol_new snd_ac97_cm9739_controls[] = {
3035 AC97_SURROUND_JACK_MODE_CTL,
3036 AC97_CHANNEL_MODE_CTL,
3037 };
3038
3039 static int patch_cm9739_specific(struct snd_ac97 * ac97)
3040 {
3041 return patch_build_controls(ac97, snd_ac97_cm9739_controls, ARRAY_SIZE(snd_ac97_cm9739_controls));
3042 }
3043
3044 static int patch_cm9739_post_spdif(struct snd_ac97 * ac97)
3045 {
3046 return patch_build_controls(ac97, snd_ac97_cm9739_controls_spdif, ARRAY_SIZE(snd_ac97_cm9739_controls_spdif));
3047 }
3048
3049 static const struct snd_ac97_build_ops patch_cm9739_ops = {
3050 .build_specific = patch_cm9739_specific,
3051 .build_post_spdif = patch_cm9739_post_spdif,
3052 .update_jacks = cm9739_update_jacks
3053 };
3054
3055 static int patch_cm9739(struct snd_ac97 * ac97)
3056 {
3057 unsigned short val;
3058
3059 ac97->build_ops = &patch_cm9739_ops;
3060
3061
3062 ac97->flags |= AC97_HAS_NO_MASTER_VOL | AC97_HAS_NO_PCM_VOL;
3063 snd_ac97_write_cache(ac97, AC97_MASTER, 0x8000);
3064 snd_ac97_write_cache(ac97, AC97_PCM, 0x8000);
3065
3066
3067 val = snd_ac97_read(ac97, AC97_EXTENDED_STATUS);
3068 if (val & AC97_EA_SPCV) {
3069
3070 snd_ac97_write_cache(ac97, AC97_CM9739_SPDIF_CTRL,
3071 snd_ac97_read(ac97, AC97_CM9739_SPDIF_CTRL) | 0x01);
3072 ac97->rates[AC97_RATES_SPDIF] = SNDRV_PCM_RATE_48000;
3073 } else {
3074 ac97->ext_id &= ~AC97_EI_SPDIF;
3075 ac97->rates[AC97_RATES_SPDIF] = 0;
3076 }
3077
3078
3079
3080
3081
3082
3083
3084
3085
3086
3087 val = snd_ac97_read(ac97, AC97_CM9739_MULTI_CHAN) & (1 << 4);
3088 val |= (1 << 3);
3089 val |= (1 << 13);
3090 if (! (ac97->ext_id & AC97_EI_SPDIF))
3091 val |= (1 << 14);
3092 snd_ac97_write_cache(ac97, AC97_CM9739_MULTI_CHAN, val);
3093
3094
3095 snd_ac97_write_cache(ac97, 0x70, 0x0100);
3096 snd_ac97_write_cache(ac97, 0x72, 0x0020);
3097
3098 if (ac97->pci &&
3099 ac97->subsystem_vendor == 0x1043 &&
3100 ac97->subsystem_device == 0x1843) {
3101 snd_ac97_write_cache(ac97, AC97_CM9739_SPDIF_CTRL,
3102 snd_ac97_read(ac97, AC97_CM9739_SPDIF_CTRL) & ~0x01);
3103 snd_ac97_write_cache(ac97, AC97_CM9739_MULTI_CHAN,
3104 snd_ac97_read(ac97, AC97_CM9739_MULTI_CHAN) | (1 << 14));
3105 }
3106
3107 return 0;
3108 }
3109
3110 #define AC97_CM9761_MULTI_CHAN 0x64
3111 #define AC97_CM9761_FUNC 0x66
3112 #define AC97_CM9761_SPDIF_CTRL 0x6c
3113
3114 static void cm9761_update_jacks(struct snd_ac97 *ac97)
3115 {
3116
3117
3118
3119 static unsigned short surr_on[3][2] = {
3120 { 0x0008, 0x0000 },
3121 { 0x0000, 0x0008 },
3122 { 0x0000, 0x0008 },
3123 };
3124 static unsigned short clfe_on[3][2] = {
3125 { 0x0000, 0x1000 },
3126 { 0x1000, 0x0000 },
3127 { 0x0000, 0x1000 },
3128 };
3129 static unsigned short surr_shared[3][2] = {
3130 { 0x0000, 0x0400 },
3131 { 0x0000, 0x0400 },
3132 { 0x0000, 0x0400 },
3133 };
3134 static unsigned short clfe_shared[3][2] = {
3135 { 0x2000, 0x0880 },
3136 { 0x0000, 0x2880 },
3137 { 0x2000, 0x0800 },
3138 };
3139 unsigned short val = 0;
3140
3141 val |= surr_on[ac97->spec.dev_flags][is_surround_on(ac97)];
3142 val |= clfe_on[ac97->spec.dev_flags][is_clfe_on(ac97)];
3143 val |= surr_shared[ac97->spec.dev_flags][is_shared_surrout(ac97)];
3144 val |= clfe_shared[ac97->spec.dev_flags][is_shared_clfeout(ac97)];
3145
3146 snd_ac97_update_bits(ac97, AC97_CM9761_MULTI_CHAN, 0x3c88, val);
3147 }
3148
3149 static const struct snd_kcontrol_new snd_ac97_cm9761_controls[] = {
3150 AC97_SURROUND_JACK_MODE_CTL,
3151 AC97_CHANNEL_MODE_CTL,
3152 };
3153
3154 static int cm9761_spdif_out_source_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo)
3155 {
3156 static const char * const texts[] = { "AC-Link", "ADC", "SPDIF-In" };
3157
3158 return snd_ctl_enum_info(uinfo, 1, 3, texts);
3159 }
3160
3161 static int cm9761_spdif_out_source_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
3162 {
3163 struct snd_ac97 *ac97 = snd_kcontrol_chip(kcontrol);
3164
3165 if (ac97->regs[AC97_CM9761_FUNC] & 0x1)
3166 ucontrol->value.enumerated.item[0] = 2;
3167 else if (ac97->regs[AC97_CM9761_SPDIF_CTRL] & 0x2)
3168 ucontrol->value.enumerated.item[0] = 1;
3169 else
3170 ucontrol->value.enumerated.item[0] = 0;
3171 return 0;
3172 }
3173
3174 static int cm9761_spdif_out_source_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
3175 {
3176 struct snd_ac97 *ac97 = snd_kcontrol_chip(kcontrol);
3177
3178 if (ucontrol->value.enumerated.item[0] == 2)
3179 return snd_ac97_update_bits(ac97, AC97_CM9761_FUNC, 0x1, 0x1);
3180 snd_ac97_update_bits(ac97, AC97_CM9761_FUNC, 0x1, 0);
3181 return snd_ac97_update_bits(ac97, AC97_CM9761_SPDIF_CTRL, 0x2,
3182 ucontrol->value.enumerated.item[0] == 1 ? 0x2 : 0);
3183 }
3184
3185 static const char * const cm9761_dac_clock[] = {
3186 "AC-Link", "SPDIF-In", "Both"
3187 };
3188 static const struct ac97_enum cm9761_dac_clock_enum =
3189 AC97_ENUM_SINGLE(AC97_CM9761_SPDIF_CTRL, 9, 3, cm9761_dac_clock);
3190
3191 static const struct snd_kcontrol_new snd_ac97_cm9761_controls_spdif[] = {
3192 {
3193 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
3194 .name = SNDRV_CTL_NAME_IEC958("",PLAYBACK,NONE) "Source",
3195 .info = cm9761_spdif_out_source_info,
3196 .get = cm9761_spdif_out_source_get,
3197 .put = cm9761_spdif_out_source_put,
3198 },
3199
3200 AC97_SINGLE(SNDRV_CTL_NAME_IEC958("",CAPTURE,NONE) "Valid Switch", AC97_CM9761_SPDIF_CTRL, 2, 1, 0),
3201
3202 AC97_SINGLE(SNDRV_CTL_NAME_IEC958("",CAPTURE,NONE) "Monitor", AC97_CM9761_SPDIF_CTRL, 3, 1, 0),
3203
3204 AC97_SINGLE(SNDRV_CTL_NAME_IEC958("",CAPTURE,SWITCH), AC97_CM9761_SPDIF_CTRL, 4, 1, 0),
3205
3206 AC97_ENUM("DAC Clock Source", cm9761_dac_clock_enum),
3207 };
3208
3209 static int patch_cm9761_post_spdif(struct snd_ac97 * ac97)
3210 {
3211 return patch_build_controls(ac97, snd_ac97_cm9761_controls_spdif, ARRAY_SIZE(snd_ac97_cm9761_controls_spdif));
3212 }
3213
3214 static int patch_cm9761_specific(struct snd_ac97 * ac97)
3215 {
3216 return patch_build_controls(ac97, snd_ac97_cm9761_controls, ARRAY_SIZE(snd_ac97_cm9761_controls));
3217 }
3218
3219 static const struct snd_ac97_build_ops patch_cm9761_ops = {
3220 .build_specific = patch_cm9761_specific,
3221 .build_post_spdif = patch_cm9761_post_spdif,
3222 .update_jacks = cm9761_update_jacks
3223 };
3224
3225 static int patch_cm9761(struct snd_ac97 *ac97)
3226 {
3227 unsigned short val;
3228
3229
3230
3231
3232
3233 ac97->flags |= AC97_HAS_NO_PCM_VOL;
3234 snd_ac97_write_cache(ac97, AC97_MASTER, 0x8808);
3235 snd_ac97_write_cache(ac97, AC97_PCM, 0x8808);
3236
3237 ac97->spec.dev_flags = 0;
3238 if (ac97->id == AC97_ID_CM9761_82) {
3239 unsigned short tmp;
3240
3241 val = snd_ac97_read(ac97, AC97_INT_PAGING);
3242 snd_ac97_write_cache(ac97, AC97_INT_PAGING, (val & ~0x0f) | 0x01);
3243 tmp = snd_ac97_read(ac97, 0x60);
3244 ac97->spec.dev_flags = tmp & 1;
3245 snd_ac97_write_cache(ac97, AC97_INT_PAGING, val);
3246 } else if (ac97->id == AC97_ID_CM9761_83)
3247 ac97->spec.dev_flags = 2;
3248
3249 ac97->build_ops = &patch_cm9761_ops;
3250
3251
3252
3253 ac97->ext_id |= AC97_EI_SPDIF;
3254
3255 snd_ac97_write_cache(ac97, AC97_EXTENDED_STATUS, 0x05c0);
3256
3257 snd_ac97_write_cache(ac97, AC97_CM9761_SPDIF_CTRL, 0x0001);
3258 ac97->rates[AC97_RATES_SPDIF] = SNDRV_PCM_RATE_48000;
3259
3260
3261
3262
3263
3264
3265
3266
3267
3268
3269
3270
3271
3272
3273
3274
3275
3276
3277
3278 #if 0
3279 if (ac97->spec.dev_flags)
3280 val = 0x0214;
3281 else
3282 val = 0x321c;
3283 #endif
3284 val = snd_ac97_read(ac97, AC97_CM9761_MULTI_CHAN);
3285 val |= (1 << 4);
3286 snd_ac97_write_cache(ac97, AC97_CM9761_MULTI_CHAN, val);
3287
3288
3289 snd_ac97_write_cache(ac97, 0x70, 0x0100);
3290 snd_ac97_write_cache(ac97, 0x72, 0x0020);
3291
3292 return 0;
3293 }
3294
3295 #define AC97_CM9780_SIDE 0x60
3296 #define AC97_CM9780_JACK 0x62
3297 #define AC97_CM9780_MIXER 0x64
3298 #define AC97_CM9780_MULTI_CHAN 0x66
3299 #define AC97_CM9780_SPDIF 0x6c
3300
3301 static const char * const cm9780_ch_select[] = {
3302 "Front", "Side", "Center/LFE", "Rear"
3303 };
3304 static const struct ac97_enum cm9780_ch_select_enum =
3305 AC97_ENUM_SINGLE(AC97_CM9780_MULTI_CHAN, 6, 4, cm9780_ch_select);
3306 static const struct snd_kcontrol_new cm9780_controls[] = {
3307 AC97_DOUBLE("Side Playback Switch", AC97_CM9780_SIDE, 15, 7, 1, 1),
3308 AC97_DOUBLE("Side Playback Volume", AC97_CM9780_SIDE, 8, 0, 31, 0),
3309 AC97_ENUM("Side Playback Route", cm9780_ch_select_enum),
3310 };
3311
3312 static int patch_cm9780_specific(struct snd_ac97 *ac97)
3313 {
3314 return patch_build_controls(ac97, cm9780_controls, ARRAY_SIZE(cm9780_controls));
3315 }
3316
3317 static const struct snd_ac97_build_ops patch_cm9780_ops = {
3318 .build_specific = patch_cm9780_specific,
3319 .build_post_spdif = patch_cm9761_post_spdif
3320 };
3321
3322 static int patch_cm9780(struct snd_ac97 *ac97)
3323 {
3324 unsigned short val;
3325
3326 ac97->build_ops = &patch_cm9780_ops;
3327
3328
3329 if (ac97->ext_id & AC97_EI_SPDIF) {
3330 ac97->rates[AC97_RATES_SPDIF] = SNDRV_PCM_RATE_48000;
3331 val = snd_ac97_read(ac97, AC97_CM9780_SPDIF);
3332 val |= 0x1;
3333 snd_ac97_write_cache(ac97, AC97_CM9780_SPDIF, val);
3334 }
3335
3336 return 0;
3337 }
3338
3339
3340
3341
3342 static const struct snd_kcontrol_new snd_ac97_controls_vt1613[] = {
3343 AC97_SINGLE("DC Offset removal", 0x5a, 10, 1, 0),
3344 };
3345
3346 static int patch_vt1613_specific(struct snd_ac97 *ac97)
3347 {
3348 return patch_build_controls(ac97, &snd_ac97_controls_vt1613[0],
3349 ARRAY_SIZE(snd_ac97_controls_vt1613));
3350 };
3351
3352 static const struct snd_ac97_build_ops patch_vt1613_ops = {
3353 .build_specific = patch_vt1613_specific
3354 };
3355
3356 static int patch_vt1613(struct snd_ac97 *ac97)
3357 {
3358 ac97->build_ops = &patch_vt1613_ops;
3359
3360 ac97->flags |= AC97_HAS_NO_VIDEO;
3361 ac97->caps |= AC97_BC_HEADPHONE;
3362
3363 return 0;
3364 }
3365
3366
3367
3368
3369 static const struct snd_kcontrol_new snd_ac97_controls_vt1616[] = {
3370 AC97_SINGLE("DC Offset removal", 0x5a, 10, 1, 0),
3371 AC97_SINGLE("Alternate Level to Surround Out", 0x5a, 15, 1, 0),
3372 AC97_SINGLE("Downmix LFE and Center to Front", 0x5a, 12, 1, 0),
3373 AC97_SINGLE("Downmix Surround to Front", 0x5a, 11, 1, 0),
3374 };
3375
3376 static const char * const slave_vols_vt1616[] = {
3377 "Front Playback Volume",
3378 "Surround Playback Volume",
3379 "Center Playback Volume",
3380 "LFE Playback Volume",
3381 NULL
3382 };
3383
3384 static const char * const slave_sws_vt1616[] = {
3385 "Front Playback Switch",
3386 "Surround Playback Switch",
3387 "Center Playback Switch",
3388 "LFE Playback Switch",
3389 NULL
3390 };
3391
3392
3393 static struct snd_kcontrol *snd_ac97_find_mixer_ctl(struct snd_ac97 *ac97,
3394 const char *name)
3395 {
3396 struct snd_ctl_elem_id id;
3397 memset(&id, 0, sizeof(id));
3398 id.iface = SNDRV_CTL_ELEM_IFACE_MIXER;
3399 strcpy(id.name, name);
3400 return snd_ctl_find_id(ac97->bus->card, &id);
3401 }
3402
3403
3404 static int snd_ac97_add_vmaster(struct snd_ac97 *ac97, char *name,
3405 const unsigned int *tlv,
3406 const char * const *slaves)
3407 {
3408 struct snd_kcontrol *kctl;
3409 const char * const *s;
3410 int err;
3411
3412 kctl = snd_ctl_make_virtual_master(name, tlv);
3413 if (!kctl)
3414 return -ENOMEM;
3415 err = snd_ctl_add(ac97->bus->card, kctl);
3416 if (err < 0)
3417 return err;
3418
3419 for (s = slaves; *s; s++) {
3420 struct snd_kcontrol *sctl;
3421
3422 sctl = snd_ac97_find_mixer_ctl(ac97, *s);
3423 if (!sctl) {
3424 dev_dbg(ac97->bus->card->dev,
3425 "Cannot find slave %s, skipped\n", *s);
3426 continue;
3427 }
3428 err = snd_ctl_add_slave(kctl, sctl);
3429 if (err < 0)
3430 return err;
3431 }
3432 return 0;
3433 }
3434
3435 static int patch_vt1616_specific(struct snd_ac97 * ac97)
3436 {
3437 struct snd_kcontrol *kctl;
3438 int err;
3439
3440 if (snd_ac97_try_bit(ac97, 0x5a, 9))
3441 if ((err = patch_build_controls(ac97, &snd_ac97_controls_vt1616[0], 1)) < 0)
3442 return err;
3443 if ((err = patch_build_controls(ac97, &snd_ac97_controls_vt1616[1], ARRAY_SIZE(snd_ac97_controls_vt1616) - 1)) < 0)
3444 return err;
3445
3446
3447 kctl = snd_ac97_find_mixer_ctl(ac97, "Master Playback Volume");
3448 if (!kctl)
3449 return -EINVAL;
3450
3451 snd_ac97_rename_vol_ctl(ac97, "Master Playback", "Front Playback");
3452
3453 err = snd_ac97_add_vmaster(ac97, "Master Playback Volume",
3454 kctl->tlv.p, slave_vols_vt1616);
3455 if (err < 0)
3456 return err;
3457
3458 err = snd_ac97_add_vmaster(ac97, "Master Playback Switch",
3459 NULL, slave_sws_vt1616);
3460 if (err < 0)
3461 return err;
3462
3463 return 0;
3464 }
3465
3466 static const struct snd_ac97_build_ops patch_vt1616_ops = {
3467 .build_specific = patch_vt1616_specific
3468 };
3469
3470 static int patch_vt1616(struct snd_ac97 * ac97)
3471 {
3472 ac97->build_ops = &patch_vt1616_ops;
3473 return 0;
3474 }
3475
3476
3477
3478
3479
3480
3481
3482
3483
3484
3485
3486
3487
3488
3489
3490
3491 static int snd_ac97_vt1617a_smart51_info(struct snd_kcontrol *kcontrol,
3492 struct snd_ctl_elem_info *uinfo)
3493 {
3494
3495
3496
3497
3498
3499 static const char * const texts[] = {"LineIn Mic1", "LineIn Mic1 Mic3",
3500 "Surr LFE/C Mic3", "LineIn LFE/C Mic3",
3501 "LineIn Mic2", "LineIn Mic2 Mic1",
3502 "Surr LFE Mic1", "Surr LFE Mic1 Mic2"};
3503
3504 return snd_ctl_enum_info(uinfo, 1, 8, texts);
3505 }
3506
3507 static int snd_ac97_vt1617a_smart51_get(struct snd_kcontrol *kcontrol,
3508 struct snd_ctl_elem_value *ucontrol)
3509 {
3510 ushort usSM51, usMS;
3511
3512 struct snd_ac97 *pac97;
3513
3514 pac97 = snd_kcontrol_chip(kcontrol);
3515
3516
3517
3518
3519 usSM51 = snd_ac97_read(pac97, 0x7a) >> 14;
3520 usMS = snd_ac97_read(pac97, 0x20) >> 8;
3521
3522 ucontrol->value.enumerated.item[0] = (usSM51 << 1) + usMS;
3523
3524 return 0;
3525 }
3526
3527 static int snd_ac97_vt1617a_smart51_put(struct snd_kcontrol *kcontrol,
3528 struct snd_ctl_elem_value *ucontrol)
3529 {
3530 ushort usSM51, usMS, usReg;
3531
3532 struct snd_ac97 *pac97;
3533
3534 pac97 = snd_kcontrol_chip(kcontrol);
3535
3536 usSM51 = ucontrol->value.enumerated.item[0] >> 1;
3537 usMS = ucontrol->value.enumerated.item[0] & 1;
3538
3539
3540
3541
3542 usReg = snd_ac97_read(pac97, 0x7a);
3543 snd_ac97_write_cache(pac97, 0x7a, (usReg & 0x3FFF) + (usSM51 << 14));
3544 usReg = snd_ac97_read(pac97, 0x20);
3545 snd_ac97_write_cache(pac97, 0x20, (usReg & 0xFEFF) + (usMS << 8));
3546
3547 return 0;
3548 }
3549
3550 static const struct snd_kcontrol_new snd_ac97_controls_vt1617a[] = {
3551
3552 AC97_SINGLE("Center/LFE Exchange", 0x5a, 8, 1, 0),
3553
3554
3555
3556
3557 {
3558 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
3559 .name = "Smart 5.1 Select",
3560 .info = snd_ac97_vt1617a_smart51_info,
3561 .get = snd_ac97_vt1617a_smart51_get,
3562 .put = snd_ac97_vt1617a_smart51_put,
3563 },
3564 };
3565
3566 static int patch_vt1617a(struct snd_ac97 * ac97)
3567 {
3568 int err = 0;
3569 int val;
3570
3571
3572
3573
3574 err = patch_build_controls(ac97, &snd_ac97_controls_vt1617a[0],
3575 ARRAY_SIZE(snd_ac97_controls_vt1617a));
3576
3577
3578
3579
3580
3581
3582
3583 val = snd_ac97_read(ac97, 0x5c);
3584 if (!(val & 0x20))
3585 snd_ac97_write_cache(ac97, 0x5c, 0x20);
3586
3587 ac97->ext_id |= AC97_EI_SPDIF;
3588 ac97->rates[AC97_RATES_SPDIF] = SNDRV_PCM_RATE_44100 | SNDRV_PCM_RATE_48000;
3589 ac97->build_ops = &patch_vt1616_ops;
3590
3591 return err;
3592 }
3593
3594
3595
3596
3597
3598
3599
3600
3601
3602
3603
3604
3605
3606
3607
3608
3609
3610
3611
3612
3613
3614
3615
3616
3617
3618
3619
3620
3621
3622
3623
3624
3625
3626
3627
3628
3629
3630 struct vt1618_uaj_item {
3631 unsigned short mask;
3632 unsigned short shift;
3633 const char * const items[4];
3634 };
3635
3636
3637
3638 static struct vt1618_uaj_item vt1618_uaj[3] = {
3639 {
3640
3641 .mask = 0x03,
3642 .shift = 0,
3643 .items = {
3644 "Speaker Out", "DAC Unmixed Out", "Line In", "Mic In"
3645 }
3646 },
3647 {
3648
3649 .mask = 0x0c,
3650 .shift = 2,
3651 .items = {
3652 "Surround Out", "DAC Unmixed Out", "Line In", "Mic In"
3653 }
3654 },
3655 {
3656
3657 .mask = 0x30,
3658 .shift = 4,
3659 .items = {
3660 "Center LFE Out", "DAC Unmixed Out", "Line In", "Mic In"
3661 },
3662 },
3663 };
3664
3665 static int snd_ac97_vt1618_UAJ_info(struct snd_kcontrol *kcontrol,
3666 struct snd_ctl_elem_info *uinfo)
3667 {
3668 return snd_ctl_enum_info(uinfo, 1, 4,
3669 vt1618_uaj[kcontrol->private_value].items);
3670 }
3671
3672
3673
3674
3675
3676 static int snd_ac97_vt1618_UAJ_get(struct snd_kcontrol *kcontrol,
3677 struct snd_ctl_elem_value *ucontrol)
3678 {
3679 unsigned short datpag, uaj;
3680 struct snd_ac97 *pac97 = snd_kcontrol_chip(kcontrol);
3681
3682 mutex_lock(&pac97->page_mutex);
3683
3684 datpag = snd_ac97_read(pac97, AC97_INT_PAGING) & AC97_PAGE_MASK;
3685 snd_ac97_update_bits(pac97, AC97_INT_PAGING, AC97_PAGE_MASK, 0);
3686
3687 uaj = snd_ac97_read(pac97, 0x60) &
3688 vt1618_uaj[kcontrol->private_value].mask;
3689
3690 snd_ac97_update_bits(pac97, AC97_INT_PAGING, AC97_PAGE_MASK, datpag);
3691 mutex_unlock(&pac97->page_mutex);
3692
3693 ucontrol->value.enumerated.item[0] = uaj >>
3694 vt1618_uaj[kcontrol->private_value].shift;
3695
3696 return 0;
3697 }
3698
3699 static int snd_ac97_vt1618_UAJ_put(struct snd_kcontrol *kcontrol,
3700 struct snd_ctl_elem_value *ucontrol)
3701 {
3702 return ac97_update_bits_page(snd_kcontrol_chip(kcontrol), 0x60,
3703 vt1618_uaj[kcontrol->private_value].mask,
3704 ucontrol->value.enumerated.item[0]<<
3705 vt1618_uaj[kcontrol->private_value].shift,
3706 0);
3707 }
3708
3709
3710
3711 static int snd_ac97_vt1618_aux_info(struct snd_kcontrol *kcontrol,
3712 struct snd_ctl_elem_info *uinfo)
3713 {
3714 static const char * const txt_aux[] = {"Aux In", "Back Surr Out"};
3715
3716 return snd_ctl_enum_info(uinfo, 1, 2, txt_aux);
3717 }
3718
3719 static int snd_ac97_vt1618_aux_get(struct snd_kcontrol *kcontrol,
3720 struct snd_ctl_elem_value *ucontrol)
3721 {
3722 ucontrol->value.enumerated.item[0] =
3723 (snd_ac97_read(snd_kcontrol_chip(kcontrol), 0x5c) & 0x0008)>>3;
3724 return 0;
3725 }
3726
3727 static int snd_ac97_vt1618_aux_put(struct snd_kcontrol *kcontrol,
3728 struct snd_ctl_elem_value *ucontrol)
3729 {
3730
3731
3732 snd_ac97_update_bits(snd_kcontrol_chip(kcontrol), 0x5c, 0x0008,
3733 ucontrol->value.enumerated.item[0] << 3);
3734
3735
3736
3737 return snd_ac97_update_bits(snd_kcontrol_chip(kcontrol), 0x76, 0x0008,
3738 ucontrol->value.enumerated.item[0] << 3);
3739 }
3740
3741 static const struct snd_kcontrol_new snd_ac97_controls_vt1618[] = {
3742 AC97_SINGLE("Exchange Center/LFE", 0x5a, 8, 1, 0),
3743 AC97_SINGLE("DC Offset", 0x5a, 10, 1, 0),
3744 AC97_SINGLE("Soft Mute", 0x5c, 0, 1, 1),
3745 AC97_SINGLE("Headphone Amp", 0x5c, 5, 1, 1),
3746 AC97_DOUBLE("Back Surr Volume", 0x5e, 8, 0, 31, 1),
3747 AC97_SINGLE("Back Surr Switch", 0x5e, 15, 1, 1),
3748 {
3749 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
3750 .name = "Speaker Jack Mode",
3751 .info = snd_ac97_vt1618_UAJ_info,
3752 .get = snd_ac97_vt1618_UAJ_get,
3753 .put = snd_ac97_vt1618_UAJ_put,
3754 .private_value = 0
3755 },
3756 {
3757 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
3758 .name = "Line Jack Mode",
3759 .info = snd_ac97_vt1618_UAJ_info,
3760 .get = snd_ac97_vt1618_UAJ_get,
3761 .put = snd_ac97_vt1618_UAJ_put,
3762 .private_value = 1
3763 },
3764 {
3765 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
3766 .name = "Mic Jack Mode",
3767 .info = snd_ac97_vt1618_UAJ_info,
3768 .get = snd_ac97_vt1618_UAJ_get,
3769 .put = snd_ac97_vt1618_UAJ_put,
3770 .private_value = 2
3771 },
3772 {
3773 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
3774 .name = "Aux Jack Mode",
3775 .info = snd_ac97_vt1618_aux_info,
3776 .get = snd_ac97_vt1618_aux_get,
3777 .put = snd_ac97_vt1618_aux_put,
3778 }
3779 };
3780
3781 static int patch_vt1618(struct snd_ac97 *ac97)
3782 {
3783 return patch_build_controls(ac97, snd_ac97_controls_vt1618,
3784 ARRAY_SIZE(snd_ac97_controls_vt1618));
3785 }
3786
3787
3788
3789 static void it2646_update_jacks(struct snd_ac97 *ac97)
3790 {
3791
3792 snd_ac97_update_bits(ac97, 0x76, 1 << 9,
3793 is_shared_surrout(ac97) ? (1<<9) : 0);
3794
3795 snd_ac97_update_bits(ac97, 0x76, 1 << 10,
3796 is_shared_clfeout(ac97) ? (1<<10) : 0);
3797 }
3798
3799 static const struct snd_kcontrol_new snd_ac97_controls_it2646[] = {
3800 AC97_SURROUND_JACK_MODE_CTL,
3801 AC97_CHANNEL_MODE_CTL,
3802 };
3803
3804 static const struct snd_kcontrol_new snd_ac97_spdif_controls_it2646[] = {
3805 AC97_SINGLE(SNDRV_CTL_NAME_IEC958("",CAPTURE,SWITCH), 0x76, 11, 1, 0),
3806 AC97_SINGLE("Analog to IEC958 Output", 0x76, 12, 1, 0),
3807 AC97_SINGLE("IEC958 Input Monitor", 0x76, 13, 1, 0),
3808 };
3809
3810 static int patch_it2646_specific(struct snd_ac97 * ac97)
3811 {
3812 int err;
3813 if ((err = patch_build_controls(ac97, snd_ac97_controls_it2646, ARRAY_SIZE(snd_ac97_controls_it2646))) < 0)
3814 return err;
3815 if ((err = patch_build_controls(ac97, snd_ac97_spdif_controls_it2646, ARRAY_SIZE(snd_ac97_spdif_controls_it2646))) < 0)
3816 return err;
3817 return 0;
3818 }
3819
3820 static const struct snd_ac97_build_ops patch_it2646_ops = {
3821 .build_specific = patch_it2646_specific,
3822 .update_jacks = it2646_update_jacks
3823 };
3824
3825 static int patch_it2646(struct snd_ac97 * ac97)
3826 {
3827 ac97->build_ops = &patch_it2646_ops;
3828
3829 snd_ac97_write_cache(ac97, 0x5E, 0x0808);
3830 snd_ac97_write_cache(ac97, 0x7A, 0x0808);
3831 return 0;
3832 }
3833
3834
3835
3836
3837
3838 #define AC97_SI3036_CHIP_ID 0x5a
3839 #define AC97_SI3036_LINE_CFG 0x5c
3840
3841 static const struct snd_kcontrol_new snd_ac97_controls_si3036[] = {
3842 AC97_DOUBLE("Modem Speaker Volume", 0x5c, 14, 12, 3, 1)
3843 };
3844
3845 static int patch_si3036_specific(struct snd_ac97 * ac97)
3846 {
3847 int idx, err;
3848 for (idx = 0; idx < ARRAY_SIZE(snd_ac97_controls_si3036); idx++)
3849 if ((err = snd_ctl_add(ac97->bus->card, snd_ctl_new1(&snd_ac97_controls_si3036[idx], ac97))) < 0)
3850 return err;
3851 return 0;
3852 }
3853
3854 static const struct snd_ac97_build_ops patch_si3036_ops = {
3855 .build_specific = patch_si3036_specific,
3856 };
3857
3858 static int mpatch_si3036(struct snd_ac97 * ac97)
3859 {
3860 ac97->build_ops = &patch_si3036_ops;
3861 snd_ac97_write_cache(ac97, 0x5c, 0xf210 );
3862 snd_ac97_write_cache(ac97, 0x68, 0);
3863 return 0;
3864 }
3865
3866
3867
3868
3869
3870
3871
3872
3873
3874 static struct snd_ac97_res_table lm4550_restbl[] = {
3875 { AC97_MASTER, 0x1f1f },
3876 { AC97_HEADPHONE, 0x1f1f },
3877 { AC97_MASTER_MONO, 0x001f },
3878 { AC97_PC_BEEP, 0x001f },
3879 { AC97_PHONE, 0x001f },
3880 { AC97_MIC, 0x001f },
3881 { AC97_LINE, 0x1f1f },
3882 { AC97_CD, 0x1f1f },
3883 { AC97_VIDEO, 0x1f1f },
3884 { AC97_AUX, 0x1f1f },
3885 { AC97_PCM, 0x1f1f },
3886 { AC97_REC_GAIN, 0x0f0f },
3887 { }
3888 };
3889
3890 static int patch_lm4550(struct snd_ac97 *ac97)
3891 {
3892 ac97->res_table = lm4550_restbl;
3893 return 0;
3894 }
3895
3896
3897
3898
3899 static const struct snd_kcontrol_new snd_ac97_controls_ucb1400[] = {
3900
3901
3902
3903 AC97_SINGLE("Headphone Driver", 0x6a, 6, 1, 0),
3904
3905
3906 AC97_SINGLE("DC Filter", 0x6a, 4, 1, 0),
3907
3908
3909 AC97_SINGLE("Smart Low Power Mode", 0x6c, 4, 3, 0),
3910 };
3911
3912 static int patch_ucb1400_specific(struct snd_ac97 * ac97)
3913 {
3914 int idx, err;
3915 for (idx = 0; idx < ARRAY_SIZE(snd_ac97_controls_ucb1400); idx++)
3916 if ((err = snd_ctl_add(ac97->bus->card, snd_ctl_new1(&snd_ac97_controls_ucb1400[idx], ac97))) < 0)
3917 return err;
3918 return 0;
3919 }
3920
3921 static const struct snd_ac97_build_ops patch_ucb1400_ops = {
3922 .build_specific = patch_ucb1400_specific,
3923 };
3924
3925 static int patch_ucb1400(struct snd_ac97 * ac97)
3926 {
3927 ac97->build_ops = &patch_ucb1400_ops;
3928
3929 snd_ac97_write_cache(ac97, 0x6a, 0x0050);
3930 snd_ac97_write_cache(ac97, 0x6c, 0x0030);
3931 return 0;
3932 }