2 * Copyright (c) by Jaroslav Kysela <perex@perex.cz>
3 * Universal interface for Audio Codec '97
5 * For more details look to AC '97 component specification revision 2.2
6 * by Intel Corporation (http://developer.intel.com) and to datasheets
10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of the GNU General Public License as published by
12 * the Free Software Foundation; either version 2 of the License, or
13 * (at your option) any later version.
15 * This program is distributed in the hope that it will be useful,
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 * GNU General Public License for more details.
20 * You should have received a copy of the GNU General Public License
21 * along with this program; if not, write to the Free Software
22 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
26 #include "ac97_local.h"
27 #include "ac97_patch.h"
30 * Forward declarations
33 static struct snd_kcontrol
*snd_ac97_find_mixer_ctl(struct snd_ac97
*ac97
,
35 static int snd_ac97_add_vmaster(struct snd_ac97
*ac97
, char *name
,
36 const unsigned int *tlv
,
37 const char * const *slaves
);
40 * Chip specific initialization
43 static int patch_build_controls(struct snd_ac97
* ac97
, const struct snd_kcontrol_new
*controls
, int count
)
47 for (idx
= 0; idx
< count
; idx
++)
48 if ((err
= snd_ctl_add(ac97
->bus
->card
, snd_ac97_cnew(&controls
[idx
], ac97
))) < 0)
53 /* replace with a new TLV */
54 static void reset_tlv(struct snd_ac97
*ac97
, const char *name
,
55 const unsigned int *tlv
)
57 struct snd_ctl_elem_id sid
;
58 struct snd_kcontrol
*kctl
;
59 memset(&sid
, 0, sizeof(sid
));
60 strcpy(sid
.name
, name
);
61 sid
.iface
= SNDRV_CTL_ELEM_IFACE_MIXER
;
62 kctl
= snd_ctl_find_id(ac97
->bus
->card
, &sid
);
63 if (kctl
&& kctl
->tlv
.p
)
67 /* set to the page, update bits and restore the page */
68 static int ac97_update_bits_page(struct snd_ac97
*ac97
, unsigned short reg
, unsigned short mask
, unsigned short value
, unsigned short page
)
70 unsigned short page_save
;
73 mutex_lock(&ac97
->page_mutex
);
74 page_save
= snd_ac97_read(ac97
, AC97_INT_PAGING
) & AC97_PAGE_MASK
;
75 snd_ac97_update_bits(ac97
, AC97_INT_PAGING
, AC97_PAGE_MASK
, page
);
76 ret
= snd_ac97_update_bits(ac97
, reg
, mask
, value
);
77 snd_ac97_update_bits(ac97
, AC97_INT_PAGING
, AC97_PAGE_MASK
, page_save
);
78 mutex_unlock(&ac97
->page_mutex
); /* unlock paging */
83 * shared line-in/mic controls
85 static int ac97_surround_jack_mode_info(struct snd_kcontrol
*kcontrol
, struct snd_ctl_elem_info
*uinfo
)
87 static const char * const texts
[] = { "Shared", "Independent" };
89 return snd_ctl_enum_info(uinfo
, 1, 2, texts
);
92 static int ac97_surround_jack_mode_get(struct snd_kcontrol
*kcontrol
, struct snd_ctl_elem_value
*ucontrol
)
94 struct snd_ac97
*ac97
= snd_kcontrol_chip(kcontrol
);
96 ucontrol
->value
.enumerated
.item
[0] = ac97
->indep_surround
;
100 static int ac97_surround_jack_mode_put(struct snd_kcontrol
*kcontrol
, struct snd_ctl_elem_value
*ucontrol
)
102 struct snd_ac97
*ac97
= snd_kcontrol_chip(kcontrol
);
103 unsigned char indep
= !!ucontrol
->value
.enumerated
.item
[0];
105 if (indep
!= ac97
->indep_surround
) {
106 ac97
->indep_surround
= indep
;
107 if (ac97
->build_ops
->update_jacks
)
108 ac97
->build_ops
->update_jacks(ac97
);
114 static int ac97_channel_mode_info(struct snd_kcontrol
*kcontrol
, struct snd_ctl_elem_info
*uinfo
)
116 static const char * const texts
[] = { "2ch", "4ch", "6ch", "8ch" };
118 return snd_ctl_enum_info(uinfo
, 1, kcontrol
->private_value
, texts
);
121 static int ac97_channel_mode_get(struct snd_kcontrol
*kcontrol
, struct snd_ctl_elem_value
*ucontrol
)
123 struct snd_ac97
*ac97
= snd_kcontrol_chip(kcontrol
);
125 ucontrol
->value
.enumerated
.item
[0] = ac97
->channel_mode
;
129 static int ac97_channel_mode_put(struct snd_kcontrol
*kcontrol
, struct snd_ctl_elem_value
*ucontrol
)
131 struct snd_ac97
*ac97
= snd_kcontrol_chip(kcontrol
);
132 unsigned char mode
= ucontrol
->value
.enumerated
.item
[0];
134 if (mode
>= kcontrol
->private_value
)
137 if (mode
!= ac97
->channel_mode
) {
138 ac97
->channel_mode
= mode
;
139 if (ac97
->build_ops
->update_jacks
)
140 ac97
->build_ops
->update_jacks(ac97
);
146 #define AC97_SURROUND_JACK_MODE_CTL \
148 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
149 .name = "Surround Jack Mode", \
150 .info = ac97_surround_jack_mode_info, \
151 .get = ac97_surround_jack_mode_get, \
152 .put = ac97_surround_jack_mode_put, \
155 #define AC97_CHANNEL_MODE_CTL \
157 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
158 .name = "Channel Mode", \
159 .info = ac97_channel_mode_info, \
160 .get = ac97_channel_mode_get, \
161 .put = ac97_channel_mode_put, \
162 .private_value = 3, \
165 #define AC97_CHANNEL_MODE_4CH_CTL \
167 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
168 .name = "Channel Mode", \
169 .info = ac97_channel_mode_info, \
170 .get = ac97_channel_mode_get, \
171 .put = ac97_channel_mode_put, \
172 .private_value = 2, \
175 #define AC97_CHANNEL_MODE_8CH_CTL \
177 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
178 .name = "Channel Mode", \
179 .info = ac97_channel_mode_info, \
180 .get = ac97_channel_mode_get, \
181 .put = ac97_channel_mode_put, \
182 .private_value = 4, \
185 static inline int is_surround_on(struct snd_ac97
*ac97
)
187 return ac97
->channel_mode
>= 1;
190 static inline int is_clfe_on(struct snd_ac97
*ac97
)
192 return ac97
->channel_mode
>= 2;
195 /* system has shared jacks with surround out enabled */
196 static inline int is_shared_surrout(struct snd_ac97
*ac97
)
198 return !ac97
->indep_surround
&& is_surround_on(ac97
);
201 /* system has shared jacks with center/lfe out enabled */
202 static inline int is_shared_clfeout(struct snd_ac97
*ac97
)
204 return !ac97
->indep_surround
&& is_clfe_on(ac97
);
207 /* system has shared jacks with line in enabled */
208 static inline int is_shared_linein(struct snd_ac97
*ac97
)
210 return !ac97
->indep_surround
&& !is_surround_on(ac97
);
213 /* system has shared jacks with mic in enabled */
214 static inline int is_shared_micin(struct snd_ac97
*ac97
)
216 return !ac97
->indep_surround
&& !is_clfe_on(ac97
);
219 static inline int alc850_is_aux_back_surround(struct snd_ac97
*ac97
)
221 return is_surround_on(ac97
);
224 /* The following snd_ac97_ymf753_... items added by David Shust (dshust@shustring.com) */
225 /* Modified for YMF743 by Keita Maehara <maehara@debian.org> */
227 /* It is possible to indicate to the Yamaha YMF7x3 the type of
228 speakers being used. */
230 static int snd_ac97_ymf7x3_info_speaker(struct snd_kcontrol
*kcontrol
,
231 struct snd_ctl_elem_info
*uinfo
)
233 static const char * const texts
[3] = {
234 "Standard", "Small", "Smaller"
237 return snd_ctl_enum_info(uinfo
, 1, 3, texts
);
240 static int snd_ac97_ymf7x3_get_speaker(struct snd_kcontrol
*kcontrol
,
241 struct snd_ctl_elem_value
*ucontrol
)
243 struct snd_ac97
*ac97
= snd_kcontrol_chip(kcontrol
);
246 val
= ac97
->regs
[AC97_YMF7X3_3D_MODE_SEL
];
247 val
= (val
>> 10) & 3;
248 if (val
> 0) /* 0 = invalid */
250 ucontrol
->value
.enumerated
.item
[0] = val
;
254 static int snd_ac97_ymf7x3_put_speaker(struct snd_kcontrol
*kcontrol
,
255 struct snd_ctl_elem_value
*ucontrol
)
257 struct snd_ac97
*ac97
= snd_kcontrol_chip(kcontrol
);
260 if (ucontrol
->value
.enumerated
.item
[0] > 2)
262 val
= (ucontrol
->value
.enumerated
.item
[0] + 1) << 10;
263 return snd_ac97_update(ac97
, AC97_YMF7X3_3D_MODE_SEL
, val
);
266 static const struct snd_kcontrol_new snd_ac97_ymf7x3_controls_speaker
=
268 .iface
= SNDRV_CTL_ELEM_IFACE_MIXER
,
269 .name
= "3D Control - Speaker",
270 .info
= snd_ac97_ymf7x3_info_speaker
,
271 .get
= snd_ac97_ymf7x3_get_speaker
,
272 .put
= snd_ac97_ymf7x3_put_speaker
,
275 /* It is possible to indicate to the Yamaha YMF7x3 the source to
276 direct to the S/PDIF output. */
277 static int snd_ac97_ymf7x3_spdif_source_info(struct snd_kcontrol
*kcontrol
,
278 struct snd_ctl_elem_info
*uinfo
)
280 static const char * const texts
[2] = { "AC-Link", "A/D Converter" };
282 return snd_ctl_enum_info(uinfo
, 1, 2, texts
);
285 static int snd_ac97_ymf7x3_spdif_source_get(struct snd_kcontrol
*kcontrol
,
286 struct snd_ctl_elem_value
*ucontrol
)
288 struct snd_ac97
*ac97
= snd_kcontrol_chip(kcontrol
);
291 val
= ac97
->regs
[AC97_YMF7X3_DIT_CTRL
];
292 ucontrol
->value
.enumerated
.item
[0] = (val
>> 1) & 1;
296 static int snd_ac97_ymf7x3_spdif_source_put(struct snd_kcontrol
*kcontrol
,
297 struct snd_ctl_elem_value
*ucontrol
)
299 struct snd_ac97
*ac97
= snd_kcontrol_chip(kcontrol
);
302 if (ucontrol
->value
.enumerated
.item
[0] > 1)
304 val
= ucontrol
->value
.enumerated
.item
[0] << 1;
305 return snd_ac97_update_bits(ac97
, AC97_YMF7X3_DIT_CTRL
, 0x0002, val
);
308 static int patch_yamaha_ymf7x3_3d(struct snd_ac97
*ac97
)
310 struct snd_kcontrol
*kctl
;
313 kctl
= snd_ac97_cnew(&snd_ac97_controls_3d
[0], ac97
);
314 err
= snd_ctl_add(ac97
->bus
->card
, kctl
);
317 strcpy(kctl
->id
.name
, "3D Control - Wide");
318 kctl
->private_value
= AC97_SINGLE_VALUE(AC97_3D_CONTROL
, 9, 7, 0);
319 snd_ac97_write_cache(ac97
, AC97_3D_CONTROL
, 0x0000);
320 err
= snd_ctl_add(ac97
->bus
->card
,
321 snd_ac97_cnew(&snd_ac97_ymf7x3_controls_speaker
,
325 snd_ac97_write_cache(ac97
, AC97_YMF7X3_3D_MODE_SEL
, 0x0c00);
329 static const struct snd_kcontrol_new snd_ac97_yamaha_ymf743_controls_spdif
[3] =
331 AC97_SINGLE(SNDRV_CTL_NAME_IEC958("", PLAYBACK
, SWITCH
),
332 AC97_YMF7X3_DIT_CTRL
, 0, 1, 0),
334 .iface
= SNDRV_CTL_ELEM_IFACE_MIXER
,
335 .name
= SNDRV_CTL_NAME_IEC958("", PLAYBACK
, NONE
) "Source",
336 .info
= snd_ac97_ymf7x3_spdif_source_info
,
337 .get
= snd_ac97_ymf7x3_spdif_source_get
,
338 .put
= snd_ac97_ymf7x3_spdif_source_put
,
340 AC97_SINGLE(SNDRV_CTL_NAME_IEC958("", NONE
, NONE
) "Mute",
341 AC97_YMF7X3_DIT_CTRL
, 2, 1, 1)
344 static int patch_yamaha_ymf743_build_spdif(struct snd_ac97
*ac97
)
348 err
= patch_build_controls(ac97
, &snd_ac97_controls_spdif
[0], 3);
351 err
= patch_build_controls(ac97
,
352 snd_ac97_yamaha_ymf743_controls_spdif
, 3);
355 /* set default PCM S/PDIF params */
356 /* PCM audio,no copyright,no preemphasis,PCM coder,original */
357 snd_ac97_write_cache(ac97
, AC97_YMF7X3_DIT_CTRL
, 0xa201);
361 static const struct snd_ac97_build_ops patch_yamaha_ymf743_ops
= {
362 .build_spdif
= patch_yamaha_ymf743_build_spdif
,
363 .build_3d
= patch_yamaha_ymf7x3_3d
,
366 static int patch_yamaha_ymf743(struct snd_ac97
*ac97
)
368 ac97
->build_ops
= &patch_yamaha_ymf743_ops
;
369 ac97
->caps
|= AC97_BC_BASS_TREBLE
;
370 ac97
->caps
|= 0x04 << 10; /* Yamaha 3D enhancement */
371 ac97
->rates
[AC97_RATES_SPDIF
] = SNDRV_PCM_RATE_48000
; /* 48k only */
372 ac97
->ext_id
|= AC97_EI_SPDIF
; /* force the detection of spdif */
376 /* The AC'97 spec states that the S/PDIF signal is to be output at pin 48.
377 The YMF753 will output the S/PDIF signal to pin 43, 47 (EAPD), or 48.
378 By default, no output pin is selected, and the S/PDIF signal is not output.
379 There is also a bit to mute S/PDIF output in a vendor-specific register. */
380 static int snd_ac97_ymf753_spdif_output_pin_info(struct snd_kcontrol
*kcontrol
, struct snd_ctl_elem_info
*uinfo
)
382 static const char * const texts
[3] = { "Disabled", "Pin 43", "Pin 48" };
384 return snd_ctl_enum_info(uinfo
, 1, 3, texts
);
387 static int snd_ac97_ymf753_spdif_output_pin_get(struct snd_kcontrol
*kcontrol
, struct snd_ctl_elem_value
*ucontrol
)
389 struct snd_ac97
*ac97
= snd_kcontrol_chip(kcontrol
);
392 val
= ac97
->regs
[AC97_YMF7X3_DIT_CTRL
];
393 ucontrol
->value
.enumerated
.item
[0] = (val
& 0x0008) ? 2 : (val
& 0x0020) ? 1 : 0;
397 static int snd_ac97_ymf753_spdif_output_pin_put(struct snd_kcontrol
*kcontrol
, struct snd_ctl_elem_value
*ucontrol
)
399 struct snd_ac97
*ac97
= snd_kcontrol_chip(kcontrol
);
402 if (ucontrol
->value
.enumerated
.item
[0] > 2)
404 val
= (ucontrol
->value
.enumerated
.item
[0] == 2) ? 0x0008 :
405 (ucontrol
->value
.enumerated
.item
[0] == 1) ? 0x0020 : 0;
406 return snd_ac97_update_bits(ac97
, AC97_YMF7X3_DIT_CTRL
, 0x0028, val
);
407 /* The following can be used to direct S/PDIF output to pin 47 (EAPD).
408 snd_ac97_write_cache(ac97, 0x62, snd_ac97_read(ac97, 0x62) | 0x0008); */
411 static const struct snd_kcontrol_new snd_ac97_ymf753_controls_spdif
[3] = {
413 .iface
= SNDRV_CTL_ELEM_IFACE_MIXER
,
414 .name
= SNDRV_CTL_NAME_IEC958("",PLAYBACK
,NONE
) "Source",
415 .info
= snd_ac97_ymf7x3_spdif_source_info
,
416 .get
= snd_ac97_ymf7x3_spdif_source_get
,
417 .put
= snd_ac97_ymf7x3_spdif_source_put
,
420 .iface
= SNDRV_CTL_ELEM_IFACE_MIXER
,
421 .name
= SNDRV_CTL_NAME_IEC958("",PLAYBACK
,NONE
) "Output Pin",
422 .info
= snd_ac97_ymf753_spdif_output_pin_info
,
423 .get
= snd_ac97_ymf753_spdif_output_pin_get
,
424 .put
= snd_ac97_ymf753_spdif_output_pin_put
,
426 AC97_SINGLE(SNDRV_CTL_NAME_IEC958("", NONE
, NONE
) "Mute",
427 AC97_YMF7X3_DIT_CTRL
, 2, 1, 1)
430 static int patch_yamaha_ymf753_post_spdif(struct snd_ac97
* ac97
)
434 if ((err
= patch_build_controls(ac97
, snd_ac97_ymf753_controls_spdif
, ARRAY_SIZE(snd_ac97_ymf753_controls_spdif
))) < 0)
439 static const struct snd_ac97_build_ops patch_yamaha_ymf753_ops
= {
440 .build_3d
= patch_yamaha_ymf7x3_3d
,
441 .build_post_spdif
= patch_yamaha_ymf753_post_spdif
444 static int patch_yamaha_ymf753(struct snd_ac97
* ac97
)
446 /* Patch for Yamaha YMF753, Copyright (c) by David Shust, dshust@shustring.com.
447 This chip has nonstandard and extended behaviour with regard to its S/PDIF output.
448 The AC'97 spec states that the S/PDIF signal is to be output at pin 48.
449 The YMF753 will ouput the S/PDIF signal to pin 43, 47 (EAPD), or 48.
450 By default, no output pin is selected, and the S/PDIF signal is not output.
451 There is also a bit to mute S/PDIF output in a vendor-specific register.
453 ac97
->build_ops
= &patch_yamaha_ymf753_ops
;
454 ac97
->caps
|= AC97_BC_BASS_TREBLE
;
455 ac97
->caps
|= 0x04 << 10; /* Yamaha 3D enhancement */
460 * May 2, 2003 Liam Girdwood <lrg@slimlogic.co.uk>
461 * removed broken wolfson00 patch.
462 * added support for WM9705,WM9708,WM9709,WM9710,WM9711,WM9712 and WM9717.
465 static const struct snd_kcontrol_new wm97xx_snd_ac97_controls
[] = {
466 AC97_DOUBLE("Front Playback Volume", AC97_WM97XX_FMIXER_VOL
, 8, 0, 31, 1),
467 AC97_SINGLE("Front Playback Switch", AC97_WM97XX_FMIXER_VOL
, 15, 1, 1),
470 static int patch_wolfson_wm9703_specific(struct snd_ac97
* ac97
)
472 /* This is known to work for the ViewSonic ViewPad 1000
473 * Randolph Bentson <bentson@holmsjoen.com>
474 * WM9703/9707/9708/9717
478 for (i
= 0; i
< ARRAY_SIZE(wm97xx_snd_ac97_controls
); i
++) {
479 if ((err
= snd_ctl_add(ac97
->bus
->card
, snd_ac97_cnew(&wm97xx_snd_ac97_controls
[i
], ac97
))) < 0)
482 snd_ac97_write_cache(ac97
, AC97_WM97XX_FMIXER_VOL
, 0x0808);
486 static const struct snd_ac97_build_ops patch_wolfson_wm9703_ops
= {
487 .build_specific
= patch_wolfson_wm9703_specific
,
490 static int patch_wolfson03(struct snd_ac97
* ac97
)
492 ac97
->build_ops
= &patch_wolfson_wm9703_ops
;
496 static const struct snd_kcontrol_new wm9704_snd_ac97_controls
[] = {
497 AC97_DOUBLE("Front Playback Volume", AC97_WM97XX_FMIXER_VOL
, 8, 0, 31, 1),
498 AC97_SINGLE("Front Playback Switch", AC97_WM97XX_FMIXER_VOL
, 15, 1, 1),
499 AC97_DOUBLE("Rear Playback Volume", AC97_WM9704_RMIXER_VOL
, 8, 0, 31, 1),
500 AC97_SINGLE("Rear Playback Switch", AC97_WM9704_RMIXER_VOL
, 15, 1, 1),
501 AC97_DOUBLE("Rear DAC Volume", AC97_WM9704_RPCM_VOL
, 8, 0, 31, 1),
502 AC97_DOUBLE("Surround Volume", AC97_SURROUND_MASTER
, 8, 0, 31, 1),
505 static int patch_wolfson_wm9704_specific(struct snd_ac97
* ac97
)
508 for (i
= 0; i
< ARRAY_SIZE(wm9704_snd_ac97_controls
); i
++) {
509 if ((err
= snd_ctl_add(ac97
->bus
->card
, snd_ac97_cnew(&wm9704_snd_ac97_controls
[i
], ac97
))) < 0)
512 /* patch for DVD noise */
513 snd_ac97_write_cache(ac97
, AC97_WM9704_TEST
, 0x0200);
517 static const struct snd_ac97_build_ops patch_wolfson_wm9704_ops
= {
518 .build_specific
= patch_wolfson_wm9704_specific
,
521 static int patch_wolfson04(struct snd_ac97
* ac97
)
524 ac97
->build_ops
= &patch_wolfson_wm9704_ops
;
528 static int patch_wolfson05(struct snd_ac97
* ac97
)
531 ac97
->build_ops
= &patch_wolfson_wm9703_ops
;
532 #ifdef CONFIG_TOUCHSCREEN_WM9705
533 /* WM9705 touchscreen uses AUX and VIDEO for touch */
534 ac97
->flags
|= AC97_HAS_NO_VIDEO
| AC97_HAS_NO_AUX
;
539 static const char* wm9711_alc_select
[] = {"None", "Left", "Right", "Stereo"};
540 static const char* wm9711_alc_mix
[] = {"Stereo", "Right", "Left", "None"};
541 static const char* wm9711_out3_src
[] = {"Left", "VREF", "Left + Right", "Mono"};
542 static const char* wm9711_out3_lrsrc
[] = {"Master Mix", "Headphone Mix"};
543 static const char* wm9711_rec_adc
[] = {"Stereo", "Left", "Right", "Mute"};
544 static const char* wm9711_base
[] = {"Linear Control", "Adaptive Boost"};
545 static const char* wm9711_rec_gain
[] = {"+1.5dB Steps", "+0.75dB Steps"};
546 static const char* wm9711_mic
[] = {"Mic 1", "Differential", "Mic 2", "Stereo"};
547 static const char* wm9711_rec_sel
[] =
548 {"Mic 1", "NC", "NC", "Master Mix", "Line", "Headphone Mix", "Phone Mix", "Phone"};
549 static const char* wm9711_ng_type
[] = {"Constant Gain", "Mute"};
551 static const struct ac97_enum wm9711_enum
[] = {
552 AC97_ENUM_SINGLE(AC97_PCI_SVID
, 14, 4, wm9711_alc_select
),
553 AC97_ENUM_SINGLE(AC97_VIDEO
, 10, 4, wm9711_alc_mix
),
554 AC97_ENUM_SINGLE(AC97_AUX
, 9, 4, wm9711_out3_src
),
555 AC97_ENUM_SINGLE(AC97_AUX
, 8, 2, wm9711_out3_lrsrc
),
556 AC97_ENUM_SINGLE(AC97_REC_SEL
, 12, 4, wm9711_rec_adc
),
557 AC97_ENUM_SINGLE(AC97_MASTER_TONE
, 15, 2, wm9711_base
),
558 AC97_ENUM_DOUBLE(AC97_REC_GAIN
, 14, 6, 2, wm9711_rec_gain
),
559 AC97_ENUM_SINGLE(AC97_MIC
, 5, 4, wm9711_mic
),
560 AC97_ENUM_DOUBLE(AC97_REC_SEL
, 8, 0, 8, wm9711_rec_sel
),
561 AC97_ENUM_SINGLE(AC97_PCI_SVID
, 5, 2, wm9711_ng_type
),
564 static const struct snd_kcontrol_new wm9711_snd_ac97_controls
[] = {
565 AC97_SINGLE("ALC Target Volume", AC97_CODEC_CLASS_REV
, 12, 15, 0),
566 AC97_SINGLE("ALC Hold Time", AC97_CODEC_CLASS_REV
, 8, 15, 0),
567 AC97_SINGLE("ALC Decay Time", AC97_CODEC_CLASS_REV
, 4, 15, 0),
568 AC97_SINGLE("ALC Attack Time", AC97_CODEC_CLASS_REV
, 0, 15, 0),
569 AC97_ENUM("ALC Function", wm9711_enum
[0]),
570 AC97_SINGLE("ALC Max Volume", AC97_PCI_SVID
, 11, 7, 1),
571 AC97_SINGLE("ALC ZC Timeout", AC97_PCI_SVID
, 9, 3, 1),
572 AC97_SINGLE("ALC ZC Switch", AC97_PCI_SVID
, 8, 1, 0),
573 AC97_SINGLE("ALC NG Switch", AC97_PCI_SVID
, 7, 1, 0),
574 AC97_ENUM("ALC NG Type", wm9711_enum
[9]),
575 AC97_SINGLE("ALC NG Threshold", AC97_PCI_SVID
, 0, 31, 1),
577 AC97_SINGLE("Side Tone Switch", AC97_VIDEO
, 15, 1, 1),
578 AC97_SINGLE("Side Tone Volume", AC97_VIDEO
, 12, 7, 1),
579 AC97_ENUM("ALC Headphone Mux", wm9711_enum
[1]),
580 AC97_SINGLE("ALC Headphone Volume", AC97_VIDEO
, 7, 7, 1),
582 AC97_SINGLE("Out3 Switch", AC97_AUX
, 15, 1, 1),
583 AC97_SINGLE("Out3 ZC Switch", AC97_AUX
, 7, 1, 0),
584 AC97_ENUM("Out3 Mux", wm9711_enum
[2]),
585 AC97_ENUM("Out3 LR Mux", wm9711_enum
[3]),
586 AC97_SINGLE("Out3 Volume", AC97_AUX
, 0, 31, 1),
588 AC97_SINGLE("Beep to Headphone Switch", AC97_PC_BEEP
, 15, 1, 1),
589 AC97_SINGLE("Beep to Headphone Volume", AC97_PC_BEEP
, 12, 7, 1),
590 AC97_SINGLE("Beep to Side Tone Switch", AC97_PC_BEEP
, 11, 1, 1),
591 AC97_SINGLE("Beep to Side Tone Volume", AC97_PC_BEEP
, 8, 7, 1),
592 AC97_SINGLE("Beep to Phone Switch", AC97_PC_BEEP
, 7, 1, 1),
593 AC97_SINGLE("Beep to Phone Volume", AC97_PC_BEEP
, 4, 7, 1),
595 AC97_SINGLE("Aux to Headphone Switch", AC97_CD
, 15, 1, 1),
596 AC97_SINGLE("Aux to Headphone Volume", AC97_CD
, 12, 7, 1),
597 AC97_SINGLE("Aux to Side Tone Switch", AC97_CD
, 11, 1, 1),
598 AC97_SINGLE("Aux to Side Tone Volume", AC97_CD
, 8, 7, 1),
599 AC97_SINGLE("Aux to Phone Switch", AC97_CD
, 7, 1, 1),
600 AC97_SINGLE("Aux to Phone Volume", AC97_CD
, 4, 7, 1),
602 AC97_SINGLE("Phone to Headphone Switch", AC97_PHONE
, 15, 1, 1),
603 AC97_SINGLE("Phone to Master Switch", AC97_PHONE
, 14, 1, 1),
605 AC97_SINGLE("Line to Headphone Switch", AC97_LINE
, 15, 1, 1),
606 AC97_SINGLE("Line to Master Switch", AC97_LINE
, 14, 1, 1),
607 AC97_SINGLE("Line to Phone Switch", AC97_LINE
, 13, 1, 1),
609 AC97_SINGLE("PCM Playback to Headphone Switch", AC97_PCM
, 15, 1, 1),
610 AC97_SINGLE("PCM Playback to Master Switch", AC97_PCM
, 14, 1, 1),
611 AC97_SINGLE("PCM Playback to Phone Switch", AC97_PCM
, 13, 1, 1),
613 AC97_SINGLE("Capture 20dB Boost Switch", AC97_REC_SEL
, 14, 1, 0),
614 AC97_ENUM("Capture to Phone Mux", wm9711_enum
[4]),
615 AC97_SINGLE("Capture to Phone 20dB Boost Switch", AC97_REC_SEL
, 11, 1, 1),
616 AC97_ENUM("Capture Select", wm9711_enum
[8]),
618 AC97_SINGLE("3D Upper Cut-off Switch", AC97_3D_CONTROL
, 5, 1, 1),
619 AC97_SINGLE("3D Lower Cut-off Switch", AC97_3D_CONTROL
, 4, 1, 1),
621 AC97_ENUM("Bass Control", wm9711_enum
[5]),
622 AC97_SINGLE("Bass Cut-off Switch", AC97_MASTER_TONE
, 12, 1, 1),
623 AC97_SINGLE("Tone Cut-off Switch", AC97_MASTER_TONE
, 4, 1, 1),
624 AC97_SINGLE("Playback Attenuate (-6dB) Switch", AC97_MASTER_TONE
, 6, 1, 0),
626 AC97_SINGLE("ADC Switch", AC97_REC_GAIN
, 15, 1, 1),
627 AC97_ENUM("Capture Volume Steps", wm9711_enum
[6]),
628 AC97_DOUBLE("Capture Volume", AC97_REC_GAIN
, 8, 0, 63, 1),
629 AC97_SINGLE("Capture ZC Switch", AC97_REC_GAIN
, 7, 1, 0),
631 AC97_SINGLE("Mic 1 to Phone Switch", AC97_MIC
, 14, 1, 1),
632 AC97_SINGLE("Mic 2 to Phone Switch", AC97_MIC
, 13, 1, 1),
633 AC97_ENUM("Mic Select Source", wm9711_enum
[7]),
634 AC97_SINGLE("Mic 1 Volume", AC97_MIC
, 8, 31, 1),
635 AC97_SINGLE("Mic 2 Volume", AC97_MIC
, 0, 31, 1),
636 AC97_SINGLE("Mic 20dB Boost Switch", AC97_MIC
, 7, 1, 0),
638 AC97_SINGLE("Master Left Inv Switch", AC97_MASTER
, 6, 1, 0),
639 AC97_SINGLE("Master ZC Switch", AC97_MASTER
, 7, 1, 0),
640 AC97_SINGLE("Headphone ZC Switch", AC97_HEADPHONE
, 7, 1, 0),
641 AC97_SINGLE("Mono ZC Switch", AC97_MASTER_MONO
, 7, 1, 0),
644 static int patch_wolfson_wm9711_specific(struct snd_ac97
* ac97
)
648 for (i
= 0; i
< ARRAY_SIZE(wm9711_snd_ac97_controls
); i
++) {
649 if ((err
= snd_ctl_add(ac97
->bus
->card
, snd_ac97_cnew(&wm9711_snd_ac97_controls
[i
], ac97
))) < 0)
652 snd_ac97_write_cache(ac97
, AC97_CODEC_CLASS_REV
, 0x0808);
653 snd_ac97_write_cache(ac97
, AC97_PCI_SVID
, 0x0808);
654 snd_ac97_write_cache(ac97
, AC97_VIDEO
, 0x0808);
655 snd_ac97_write_cache(ac97
, AC97_AUX
, 0x0808);
656 snd_ac97_write_cache(ac97
, AC97_PC_BEEP
, 0x0808);
657 snd_ac97_write_cache(ac97
, AC97_CD
, 0x0000);
661 static const struct snd_ac97_build_ops patch_wolfson_wm9711_ops
= {
662 .build_specific
= patch_wolfson_wm9711_specific
,
665 static int patch_wolfson11(struct snd_ac97
* ac97
)
668 ac97
->build_ops
= &patch_wolfson_wm9711_ops
;
670 ac97
->flags
|= AC97_HAS_NO_REC_GAIN
| AC97_STEREO_MUTES
| AC97_HAS_NO_MIC
|
671 AC97_HAS_NO_PC_BEEP
| AC97_HAS_NO_VIDEO
| AC97_HAS_NO_CD
;
676 static const char* wm9713_mic_mixer
[] = {"Stereo", "Mic 1", "Mic 2", "Mute"};
677 static const char* wm9713_rec_mux
[] = {"Stereo", "Left", "Right", "Mute"};
678 static const char* wm9713_rec_src
[] =
679 {"Mic 1", "Mic 2", "Line", "Mono In", "Headphone Mix", "Master Mix",
681 static const char* wm9713_rec_gain
[] = {"+1.5dB Steps", "+0.75dB Steps"};
682 static const char* wm9713_alc_select
[] = {"None", "Left", "Right", "Stereo"};
683 static const char* wm9713_mono_pga
[] = {"Vmid", "Zh", "Mono Mix", "Inv 1"};
684 static const char* wm9713_spk_pga
[] =
685 {"Vmid", "Zh", "Headphone Mix", "Master Mix", "Inv", "NC", "NC", "NC"};
686 static const char* wm9713_hp_pga
[] = {"Vmid", "Zh", "Headphone Mix", "NC"};
687 static const char* wm9713_out3_pga
[] = {"Vmid", "Zh", "Inv 1", "NC"};
688 static const char* wm9713_out4_pga
[] = {"Vmid", "Zh", "Inv 2", "NC"};
689 static const char* wm9713_dac_inv
[] =
690 {"Off", "Mono Mix", "Master Mix", "Headphone Mix L", "Headphone Mix R",
691 "Headphone Mix Mono", "NC", "Vmid"};
692 static const char* wm9713_base
[] = {"Linear Control", "Adaptive Boost"};
693 static const char* wm9713_ng_type
[] = {"Constant Gain", "Mute"};
695 static const struct ac97_enum wm9713_enum
[] = {
696 AC97_ENUM_SINGLE(AC97_LINE
, 3, 4, wm9713_mic_mixer
),
697 AC97_ENUM_SINGLE(AC97_VIDEO
, 14, 4, wm9713_rec_mux
),
698 AC97_ENUM_SINGLE(AC97_VIDEO
, 9, 4, wm9713_rec_mux
),
699 AC97_ENUM_DOUBLE(AC97_VIDEO
, 3, 0, 8, wm9713_rec_src
),
700 AC97_ENUM_DOUBLE(AC97_CD
, 14, 6, 2, wm9713_rec_gain
),
701 AC97_ENUM_SINGLE(AC97_PCI_SVID
, 14, 4, wm9713_alc_select
),
702 AC97_ENUM_SINGLE(AC97_REC_GAIN
, 14, 4, wm9713_mono_pga
),
703 AC97_ENUM_DOUBLE(AC97_REC_GAIN
, 11, 8, 8, wm9713_spk_pga
),
704 AC97_ENUM_DOUBLE(AC97_REC_GAIN
, 6, 4, 4, wm9713_hp_pga
),
705 AC97_ENUM_SINGLE(AC97_REC_GAIN
, 2, 4, wm9713_out3_pga
),
706 AC97_ENUM_SINGLE(AC97_REC_GAIN
, 0, 4, wm9713_out4_pga
),
707 AC97_ENUM_DOUBLE(AC97_REC_GAIN_MIC
, 13, 10, 8, wm9713_dac_inv
),
708 AC97_ENUM_SINGLE(AC97_GENERAL_PURPOSE
, 15, 2, wm9713_base
),
709 AC97_ENUM_SINGLE(AC97_PCI_SVID
, 5, 2, wm9713_ng_type
),
712 static const struct snd_kcontrol_new wm13_snd_ac97_controls
[] = {
713 AC97_DOUBLE("Line In Volume", AC97_PC_BEEP
, 8, 0, 31, 1),
714 AC97_SINGLE("Line In to Headphone Switch", AC97_PC_BEEP
, 15, 1, 1),
715 AC97_SINGLE("Line In to Master Switch", AC97_PC_BEEP
, 14, 1, 1),
716 AC97_SINGLE("Line In to Mono Switch", AC97_PC_BEEP
, 13, 1, 1),
718 AC97_DOUBLE("PCM Playback Volume", AC97_PHONE
, 8, 0, 31, 1),
719 AC97_SINGLE("PCM Playback to Headphone Switch", AC97_PHONE
, 15, 1, 1),
720 AC97_SINGLE("PCM Playback to Master Switch", AC97_PHONE
, 14, 1, 1),
721 AC97_SINGLE("PCM Playback to Mono Switch", AC97_PHONE
, 13, 1, 1),
723 AC97_SINGLE("Mic 1 Volume", AC97_MIC
, 8, 31, 1),
724 AC97_SINGLE("Mic 2 Volume", AC97_MIC
, 0, 31, 1),
725 AC97_SINGLE("Mic 1 to Mono Switch", AC97_LINE
, 7, 1, 1),
726 AC97_SINGLE("Mic 2 to Mono Switch", AC97_LINE
, 6, 1, 1),
727 AC97_SINGLE("Mic Boost (+20dB) Switch", AC97_LINE
, 5, 1, 0),
728 AC97_ENUM("Mic to Headphone Mux", wm9713_enum
[0]),
729 AC97_SINGLE("Mic Headphone Mixer Volume", AC97_LINE
, 0, 7, 1),
731 AC97_SINGLE("Capture Switch", AC97_CD
, 15, 1, 1),
732 AC97_ENUM("Capture Volume Steps", wm9713_enum
[4]),
733 AC97_DOUBLE("Capture Volume", AC97_CD
, 8, 0, 15, 0),
734 AC97_SINGLE("Capture ZC Switch", AC97_CD
, 7, 1, 0),
736 AC97_ENUM("Capture to Headphone Mux", wm9713_enum
[1]),
737 AC97_SINGLE("Capture to Headphone Volume", AC97_VIDEO
, 11, 7, 1),
738 AC97_ENUM("Capture to Mono Mux", wm9713_enum
[2]),
739 AC97_SINGLE("Capture to Mono Boost (+20dB) Switch", AC97_VIDEO
, 8, 1, 0),
740 AC97_SINGLE("Capture ADC Boost (+20dB) Switch", AC97_VIDEO
, 6, 1, 0),
741 AC97_ENUM("Capture Select", wm9713_enum
[3]),
743 AC97_SINGLE("ALC Target Volume", AC97_CODEC_CLASS_REV
, 12, 15, 0),
744 AC97_SINGLE("ALC Hold Time", AC97_CODEC_CLASS_REV
, 8, 15, 0),
745 AC97_SINGLE("ALC Decay Time ", AC97_CODEC_CLASS_REV
, 4, 15, 0),
746 AC97_SINGLE("ALC Attack Time", AC97_CODEC_CLASS_REV
, 0, 15, 0),
747 AC97_ENUM("ALC Function", wm9713_enum
[5]),
748 AC97_SINGLE("ALC Max Volume", AC97_PCI_SVID
, 11, 7, 0),
749 AC97_SINGLE("ALC ZC Timeout", AC97_PCI_SVID
, 9, 3, 0),
750 AC97_SINGLE("ALC ZC Switch", AC97_PCI_SVID
, 8, 1, 0),
751 AC97_SINGLE("ALC NG Switch", AC97_PCI_SVID
, 7, 1, 0),
752 AC97_ENUM("ALC NG Type", wm9713_enum
[13]),
753 AC97_SINGLE("ALC NG Threshold", AC97_PCI_SVID
, 0, 31, 0),
755 AC97_DOUBLE("Master ZC Switch", AC97_MASTER
, 14, 6, 1, 0),
756 AC97_DOUBLE("Headphone ZC Switch", AC97_HEADPHONE
, 14, 6, 1, 0),
757 AC97_DOUBLE("Out3/4 ZC Switch", AC97_MASTER_MONO
, 14, 6, 1, 0),
758 AC97_SINGLE("Master Right Switch", AC97_MASTER
, 7, 1, 1),
759 AC97_SINGLE("Headphone Right Switch", AC97_HEADPHONE
, 7, 1, 1),
760 AC97_SINGLE("Out3/4 Right Switch", AC97_MASTER_MONO
, 7, 1, 1),
762 AC97_SINGLE("Mono In to Headphone Switch", AC97_MASTER_TONE
, 15, 1, 1),
763 AC97_SINGLE("Mono In to Master Switch", AC97_MASTER_TONE
, 14, 1, 1),
764 AC97_SINGLE("Mono In Volume", AC97_MASTER_TONE
, 8, 31, 1),
765 AC97_SINGLE("Mono Switch", AC97_MASTER_TONE
, 7, 1, 1),
766 AC97_SINGLE("Mono ZC Switch", AC97_MASTER_TONE
, 6, 1, 0),
767 AC97_SINGLE("Mono Volume", AC97_MASTER_TONE
, 0, 31, 1),
769 AC97_SINGLE("Beep to Headphone Switch", AC97_AUX
, 15, 1, 1),
770 AC97_SINGLE("Beep to Headphone Volume", AC97_AUX
, 12, 7, 1),
771 AC97_SINGLE("Beep to Master Switch", AC97_AUX
, 11, 1, 1),
772 AC97_SINGLE("Beep to Master Volume", AC97_AUX
, 8, 7, 1),
773 AC97_SINGLE("Beep to Mono Switch", AC97_AUX
, 7, 1, 1),
774 AC97_SINGLE("Beep to Mono Volume", AC97_AUX
, 4, 7, 1),
776 AC97_SINGLE("Voice to Headphone Switch", AC97_PCM
, 15, 1, 1),
777 AC97_SINGLE("Voice to Headphone Volume", AC97_PCM
, 12, 7, 1),
778 AC97_SINGLE("Voice to Master Switch", AC97_PCM
, 11, 1, 1),
779 AC97_SINGLE("Voice to Master Volume", AC97_PCM
, 8, 7, 1),
780 AC97_SINGLE("Voice to Mono Switch", AC97_PCM
, 7, 1, 1),
781 AC97_SINGLE("Voice to Mono Volume", AC97_PCM
, 4, 7, 1),
783 AC97_SINGLE("Aux to Headphone Switch", AC97_REC_SEL
, 15, 1, 1),
784 AC97_SINGLE("Aux to Headphone Volume", AC97_REC_SEL
, 12, 7, 1),
785 AC97_SINGLE("Aux to Master Switch", AC97_REC_SEL
, 11, 1, 1),
786 AC97_SINGLE("Aux to Master Volume", AC97_REC_SEL
, 8, 7, 1),
787 AC97_SINGLE("Aux to Mono Switch", AC97_REC_SEL
, 7, 1, 1),
788 AC97_SINGLE("Aux to Mono Volume", AC97_REC_SEL
, 4, 7, 1),
790 AC97_ENUM("Mono Input Mux", wm9713_enum
[6]),
791 AC97_ENUM("Master Input Mux", wm9713_enum
[7]),
792 AC97_ENUM("Headphone Input Mux", wm9713_enum
[8]),
793 AC97_ENUM("Out 3 Input Mux", wm9713_enum
[9]),
794 AC97_ENUM("Out 4 Input Mux", wm9713_enum
[10]),
796 AC97_ENUM("Bass Control", wm9713_enum
[12]),
797 AC97_SINGLE("Bass Cut-off Switch", AC97_GENERAL_PURPOSE
, 12, 1, 1),
798 AC97_SINGLE("Tone Cut-off Switch", AC97_GENERAL_PURPOSE
, 4, 1, 1),
799 AC97_SINGLE("Playback Attenuate (-6dB) Switch", AC97_GENERAL_PURPOSE
, 6, 1, 0),
800 AC97_SINGLE("Bass Volume", AC97_GENERAL_PURPOSE
, 8, 15, 1),
801 AC97_SINGLE("Tone Volume", AC97_GENERAL_PURPOSE
, 0, 15, 1),
804 static const struct snd_kcontrol_new wm13_snd_ac97_controls_3d
[] = {
805 AC97_ENUM("Inv Input Mux", wm9713_enum
[11]),
806 AC97_SINGLE("3D Upper Cut-off Switch", AC97_REC_GAIN_MIC
, 5, 1, 0),
807 AC97_SINGLE("3D Lower Cut-off Switch", AC97_REC_GAIN_MIC
, 4, 1, 0),
808 AC97_SINGLE("3D Depth", AC97_REC_GAIN_MIC
, 0, 15, 1),
811 static int patch_wolfson_wm9713_3d (struct snd_ac97
* ac97
)
815 for (i
= 0; i
< ARRAY_SIZE(wm13_snd_ac97_controls_3d
); i
++) {
816 if ((err
= snd_ctl_add(ac97
->bus
->card
, snd_ac97_cnew(&wm13_snd_ac97_controls_3d
[i
], ac97
))) < 0)
822 static int patch_wolfson_wm9713_specific(struct snd_ac97
* ac97
)
826 for (i
= 0; i
< ARRAY_SIZE(wm13_snd_ac97_controls
); i
++) {
827 if ((err
= snd_ctl_add(ac97
->bus
->card
, snd_ac97_cnew(&wm13_snd_ac97_controls
[i
], ac97
))) < 0)
830 snd_ac97_write_cache(ac97
, AC97_PC_BEEP
, 0x0808);
831 snd_ac97_write_cache(ac97
, AC97_PHONE
, 0x0808);
832 snd_ac97_write_cache(ac97
, AC97_MIC
, 0x0808);
833 snd_ac97_write_cache(ac97
, AC97_LINE
, 0x00da);
834 snd_ac97_write_cache(ac97
, AC97_CD
, 0x0808);
835 snd_ac97_write_cache(ac97
, AC97_VIDEO
, 0xd612);
836 snd_ac97_write_cache(ac97
, AC97_REC_GAIN
, 0x1ba0);
841 static void patch_wolfson_wm9713_suspend (struct snd_ac97
* ac97
)
843 snd_ac97_write_cache(ac97
, AC97_EXTENDED_MID
, 0xfeff);
844 snd_ac97_write_cache(ac97
, AC97_EXTENDED_MSTATUS
, 0xffff);
847 static void patch_wolfson_wm9713_resume (struct snd_ac97
* ac97
)
849 snd_ac97_write_cache(ac97
, AC97_EXTENDED_MID
, 0xda00);
850 snd_ac97_write_cache(ac97
, AC97_EXTENDED_MSTATUS
, 0x3810);
851 snd_ac97_write_cache(ac97
, AC97_POWERDOWN
, 0x0);
855 static const struct snd_ac97_build_ops patch_wolfson_wm9713_ops
= {
856 .build_specific
= patch_wolfson_wm9713_specific
,
857 .build_3d
= patch_wolfson_wm9713_3d
,
859 .suspend
= patch_wolfson_wm9713_suspend
,
860 .resume
= patch_wolfson_wm9713_resume
864 static int patch_wolfson13(struct snd_ac97
* ac97
)
867 ac97
->build_ops
= &patch_wolfson_wm9713_ops
;
869 ac97
->flags
|= AC97_HAS_NO_REC_GAIN
| AC97_STEREO_MUTES
| AC97_HAS_NO_PHONE
|
870 AC97_HAS_NO_PC_BEEP
| AC97_HAS_NO_VIDEO
| AC97_HAS_NO_CD
| AC97_HAS_NO_TONE
|
872 ac97
->scaps
&= ~AC97_SCAP_MODEM
;
874 snd_ac97_write_cache(ac97
, AC97_EXTENDED_MID
, 0xda00);
875 snd_ac97_write_cache(ac97
, AC97_EXTENDED_MSTATUS
, 0x3810);
876 snd_ac97_write_cache(ac97
, AC97_POWERDOWN
, 0x0);
884 static int patch_tritech_tr28028(struct snd_ac97
* ac97
)
886 snd_ac97_write_cache(ac97
, 0x26, 0x0300);
887 snd_ac97_write_cache(ac97
, 0x26, 0x0000);
888 snd_ac97_write_cache(ac97
, AC97_SURROUND_MASTER
, 0x0000);
889 snd_ac97_write_cache(ac97
, AC97_SPDIF
, 0x0000);
894 * Sigmatel STAC97xx codecs
896 static int patch_sigmatel_stac9700_3d(struct snd_ac97
* ac97
)
898 struct snd_kcontrol
*kctl
;
901 if ((err
= snd_ctl_add(ac97
->bus
->card
, kctl
= snd_ac97_cnew(&snd_ac97_controls_3d
[0], ac97
))) < 0)
903 strcpy(kctl
->id
.name
, "3D Control Sigmatel - Depth");
904 kctl
->private_value
= AC97_SINGLE_VALUE(AC97_3D_CONTROL
, 2, 3, 0);
905 snd_ac97_write_cache(ac97
, AC97_3D_CONTROL
, 0x0000);
909 static int patch_sigmatel_stac9708_3d(struct snd_ac97
* ac97
)
911 struct snd_kcontrol
*kctl
;
914 if ((err
= snd_ctl_add(ac97
->bus
->card
, kctl
= snd_ac97_cnew(&snd_ac97_controls_3d
[0], ac97
))) < 0)
916 strcpy(kctl
->id
.name
, "3D Control Sigmatel - Depth");
917 kctl
->private_value
= AC97_SINGLE_VALUE(AC97_3D_CONTROL
, 0, 3, 0);
918 if ((err
= snd_ctl_add(ac97
->bus
->card
, kctl
= snd_ac97_cnew(&snd_ac97_controls_3d
[0], ac97
))) < 0)
920 strcpy(kctl
->id
.name
, "3D Control Sigmatel - Rear Depth");
921 kctl
->private_value
= AC97_SINGLE_VALUE(AC97_3D_CONTROL
, 2, 3, 0);
922 snd_ac97_write_cache(ac97
, AC97_3D_CONTROL
, 0x0000);
926 static const struct snd_kcontrol_new snd_ac97_sigmatel_4speaker
=
927 AC97_SINGLE("Sigmatel 4-Speaker Stereo Playback Switch",
928 AC97_SIGMATEL_DAC2INVERT
, 2, 1, 0);
930 /* "Sigmatel " removed due to excessive name length: */
931 static const struct snd_kcontrol_new snd_ac97_sigmatel_phaseinvert
=
932 AC97_SINGLE("Surround Phase Inversion Playback Switch",
933 AC97_SIGMATEL_DAC2INVERT
, 3, 1, 0);
935 static const struct snd_kcontrol_new snd_ac97_sigmatel_controls
[] = {
936 AC97_SINGLE("Sigmatel DAC 6dB Attenuate", AC97_SIGMATEL_ANALOG
, 1, 1, 0),
937 AC97_SINGLE("Sigmatel ADC 6dB Attenuate", AC97_SIGMATEL_ANALOG
, 0, 1, 0)
940 static int patch_sigmatel_stac97xx_specific(struct snd_ac97
* ac97
)
944 snd_ac97_write_cache(ac97
, AC97_SIGMATEL_ANALOG
, snd_ac97_read(ac97
, AC97_SIGMATEL_ANALOG
) & ~0x0003);
945 if (snd_ac97_try_bit(ac97
, AC97_SIGMATEL_ANALOG
, 1))
946 if ((err
= patch_build_controls(ac97
, &snd_ac97_sigmatel_controls
[0], 1)) < 0)
948 if (snd_ac97_try_bit(ac97
, AC97_SIGMATEL_ANALOG
, 0))
949 if ((err
= patch_build_controls(ac97
, &snd_ac97_sigmatel_controls
[1], 1)) < 0)
951 if (snd_ac97_try_bit(ac97
, AC97_SIGMATEL_DAC2INVERT
, 2))
952 if ((err
= patch_build_controls(ac97
, &snd_ac97_sigmatel_4speaker
, 1)) < 0)
954 if (snd_ac97_try_bit(ac97
, AC97_SIGMATEL_DAC2INVERT
, 3))
955 if ((err
= patch_build_controls(ac97
, &snd_ac97_sigmatel_phaseinvert
, 1)) < 0)
960 static const struct snd_ac97_build_ops patch_sigmatel_stac9700_ops
= {
961 .build_3d
= patch_sigmatel_stac9700_3d
,
962 .build_specific
= patch_sigmatel_stac97xx_specific
965 static int patch_sigmatel_stac9700(struct snd_ac97
* ac97
)
967 ac97
->build_ops
= &patch_sigmatel_stac9700_ops
;
971 static int snd_ac97_stac9708_put_bias(struct snd_kcontrol
*kcontrol
, struct snd_ctl_elem_value
*ucontrol
)
973 struct snd_ac97
*ac97
= snd_kcontrol_chip(kcontrol
);
976 mutex_lock(&ac97
->page_mutex
);
977 snd_ac97_write(ac97
, AC97_SIGMATEL_BIAS1
, 0xabba);
978 err
= snd_ac97_update_bits(ac97
, AC97_SIGMATEL_BIAS2
, 0x0010,
979 (ucontrol
->value
.integer
.value
[0] & 1) << 4);
980 snd_ac97_write(ac97
, AC97_SIGMATEL_BIAS1
, 0);
981 mutex_unlock(&ac97
->page_mutex
);
985 static const struct snd_kcontrol_new snd_ac97_stac9708_bias_control
= {
986 .iface
= SNDRV_CTL_ELEM_IFACE_MIXER
,
987 .name
= "Sigmatel Output Bias Switch",
988 .info
= snd_ac97_info_volsw
,
989 .get
= snd_ac97_get_volsw
,
990 .put
= snd_ac97_stac9708_put_bias
,
991 .private_value
= AC97_SINGLE_VALUE(AC97_SIGMATEL_BIAS2
, 4, 1, 0),
994 static int patch_sigmatel_stac9708_specific(struct snd_ac97
*ac97
)
998 /* the register bit is writable, but the function is not implemented: */
999 snd_ac97_remove_ctl(ac97
, "PCM Out Path & Mute", NULL
);
1001 snd_ac97_rename_vol_ctl(ac97
, "Headphone Playback", "Sigmatel Surround Playback");
1002 if ((err
= patch_build_controls(ac97
, &snd_ac97_stac9708_bias_control
, 1)) < 0)
1004 return patch_sigmatel_stac97xx_specific(ac97
);
1007 static const struct snd_ac97_build_ops patch_sigmatel_stac9708_ops
= {
1008 .build_3d
= patch_sigmatel_stac9708_3d
,
1009 .build_specific
= patch_sigmatel_stac9708_specific
1012 static int patch_sigmatel_stac9708(struct snd_ac97
* ac97
)
1014 unsigned int codec72
, codec6c
;
1016 ac97
->build_ops
= &patch_sigmatel_stac9708_ops
;
1017 ac97
->caps
|= 0x10; /* HP (sigmatel surround) support */
1019 codec72
= snd_ac97_read(ac97
, AC97_SIGMATEL_BIAS2
) & 0x8000;
1020 codec6c
= snd_ac97_read(ac97
, AC97_SIGMATEL_ANALOG
);
1022 if ((codec72
==0) && (codec6c
==0)) {
1023 snd_ac97_write_cache(ac97
, AC97_SIGMATEL_CIC1
, 0xabba);
1024 snd_ac97_write_cache(ac97
, AC97_SIGMATEL_CIC2
, 0x1000);
1025 snd_ac97_write_cache(ac97
, AC97_SIGMATEL_BIAS1
, 0xabba);
1026 snd_ac97_write_cache(ac97
, AC97_SIGMATEL_BIAS2
, 0x0007);
1027 } else if ((codec72
==0x8000) && (codec6c
==0)) {
1028 snd_ac97_write_cache(ac97
, AC97_SIGMATEL_CIC1
, 0xabba);
1029 snd_ac97_write_cache(ac97
, AC97_SIGMATEL_CIC2
, 0x1001);
1030 snd_ac97_write_cache(ac97
, AC97_SIGMATEL_DAC2INVERT
, 0x0008);
1031 } else if ((codec72
==0x8000) && (codec6c
==0x0080)) {
1034 snd_ac97_write_cache(ac97
, AC97_SIGMATEL_MULTICHN
, 0x0000);
1038 static int patch_sigmatel_stac9721(struct snd_ac97
* ac97
)
1040 ac97
->build_ops
= &patch_sigmatel_stac9700_ops
;
1041 if (snd_ac97_read(ac97
, AC97_SIGMATEL_ANALOG
) == 0) {
1042 // patch for SigmaTel
1043 snd_ac97_write_cache(ac97
, AC97_SIGMATEL_CIC1
, 0xabba);
1044 snd_ac97_write_cache(ac97
, AC97_SIGMATEL_CIC2
, 0x4000);
1045 snd_ac97_write_cache(ac97
, AC97_SIGMATEL_BIAS1
, 0xabba);
1046 snd_ac97_write_cache(ac97
, AC97_SIGMATEL_BIAS2
, 0x0002);
1048 snd_ac97_write_cache(ac97
, AC97_SIGMATEL_MULTICHN
, 0x0000);
1052 static int patch_sigmatel_stac9744(struct snd_ac97
* ac97
)
1054 // patch for SigmaTel
1055 ac97
->build_ops
= &patch_sigmatel_stac9700_ops
;
1056 snd_ac97_write_cache(ac97
, AC97_SIGMATEL_CIC1
, 0xabba);
1057 snd_ac97_write_cache(ac97
, AC97_SIGMATEL_CIC2
, 0x0000); /* is this correct? --jk */
1058 snd_ac97_write_cache(ac97
, AC97_SIGMATEL_BIAS1
, 0xabba);
1059 snd_ac97_write_cache(ac97
, AC97_SIGMATEL_BIAS2
, 0x0002);
1060 snd_ac97_write_cache(ac97
, AC97_SIGMATEL_MULTICHN
, 0x0000);
1064 static int patch_sigmatel_stac9756(struct snd_ac97
* ac97
)
1066 // patch for SigmaTel
1067 ac97
->build_ops
= &patch_sigmatel_stac9700_ops
;
1068 snd_ac97_write_cache(ac97
, AC97_SIGMATEL_CIC1
, 0xabba);
1069 snd_ac97_write_cache(ac97
, AC97_SIGMATEL_CIC2
, 0x0000); /* is this correct? --jk */
1070 snd_ac97_write_cache(ac97
, AC97_SIGMATEL_BIAS1
, 0xabba);
1071 snd_ac97_write_cache(ac97
, AC97_SIGMATEL_BIAS2
, 0x0002);
1072 snd_ac97_write_cache(ac97
, AC97_SIGMATEL_MULTICHN
, 0x0000);
1076 static int snd_ac97_stac9758_output_jack_info(struct snd_kcontrol
*kcontrol
, struct snd_ctl_elem_info
*uinfo
)
1078 static const char * const texts
[5] = {
1079 "Input/Disabled", "Front Output",
1080 "Rear Output", "Center/LFE Output", "Mixer Output" };
1082 return snd_ctl_enum_info(uinfo
, 1, 5, texts
);
1085 static int snd_ac97_stac9758_output_jack_get(struct snd_kcontrol
*kcontrol
, struct snd_ctl_elem_value
*ucontrol
)
1087 struct snd_ac97
*ac97
= snd_kcontrol_chip(kcontrol
);
1088 int shift
= kcontrol
->private_value
;
1091 val
= ac97
->regs
[AC97_SIGMATEL_OUTSEL
] >> shift
;
1093 ucontrol
->value
.enumerated
.item
[0] = 0;
1095 ucontrol
->value
.enumerated
.item
[0] = 1 + (val
& 3);
1099 static int snd_ac97_stac9758_output_jack_put(struct snd_kcontrol
*kcontrol
, struct snd_ctl_elem_value
*ucontrol
)
1101 struct snd_ac97
*ac97
= snd_kcontrol_chip(kcontrol
);
1102 int shift
= kcontrol
->private_value
;
1105 if (ucontrol
->value
.enumerated
.item
[0] > 4)
1107 if (ucontrol
->value
.enumerated
.item
[0] == 0)
1110 val
= 4 | (ucontrol
->value
.enumerated
.item
[0] - 1);
1111 return ac97_update_bits_page(ac97
, AC97_SIGMATEL_OUTSEL
,
1112 7 << shift
, val
<< shift
, 0);
1115 static int snd_ac97_stac9758_input_jack_info(struct snd_kcontrol
*kcontrol
, struct snd_ctl_elem_info
*uinfo
)
1117 static const char * const texts
[7] = {
1118 "Mic2 Jack", "Mic1 Jack", "Line In Jack",
1119 "Front Jack", "Rear Jack", "Center/LFE Jack", "Mute" };
1121 return snd_ctl_enum_info(uinfo
, 1, 7, texts
);
1124 static int snd_ac97_stac9758_input_jack_get(struct snd_kcontrol
*kcontrol
, struct snd_ctl_elem_value
*ucontrol
)
1126 struct snd_ac97
*ac97
= snd_kcontrol_chip(kcontrol
);
1127 int shift
= kcontrol
->private_value
;
1130 val
= ac97
->regs
[AC97_SIGMATEL_INSEL
];
1131 ucontrol
->value
.enumerated
.item
[0] = (val
>> shift
) & 7;
1135 static int snd_ac97_stac9758_input_jack_put(struct snd_kcontrol
*kcontrol
, struct snd_ctl_elem_value
*ucontrol
)
1137 struct snd_ac97
*ac97
= snd_kcontrol_chip(kcontrol
);
1138 int shift
= kcontrol
->private_value
;
1140 return ac97_update_bits_page(ac97
, AC97_SIGMATEL_INSEL
, 7 << shift
,
1141 ucontrol
->value
.enumerated
.item
[0] << shift
, 0);
1144 static int snd_ac97_stac9758_phonesel_info(struct snd_kcontrol
*kcontrol
, struct snd_ctl_elem_info
*uinfo
)
1146 static const char * const texts
[3] = {
1147 "None", "Front Jack", "Rear Jack"
1150 return snd_ctl_enum_info(uinfo
, 1, 3, texts
);
1153 static int snd_ac97_stac9758_phonesel_get(struct snd_kcontrol
*kcontrol
, struct snd_ctl_elem_value
*ucontrol
)
1155 struct snd_ac97
*ac97
= snd_kcontrol_chip(kcontrol
);
1157 ucontrol
->value
.enumerated
.item
[0] = ac97
->regs
[AC97_SIGMATEL_IOMISC
] & 3;
1161 static int snd_ac97_stac9758_phonesel_put(struct snd_kcontrol
*kcontrol
, struct snd_ctl_elem_value
*ucontrol
)
1163 struct snd_ac97
*ac97
= snd_kcontrol_chip(kcontrol
);
1165 return ac97_update_bits_page(ac97
, AC97_SIGMATEL_IOMISC
, 3,
1166 ucontrol
->value
.enumerated
.item
[0], 0);
1169 #define STAC9758_OUTPUT_JACK(xname, shift) \
1170 { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, \
1171 .info = snd_ac97_stac9758_output_jack_info, \
1172 .get = snd_ac97_stac9758_output_jack_get, \
1173 .put = snd_ac97_stac9758_output_jack_put, \
1174 .private_value = shift }
1175 #define STAC9758_INPUT_JACK(xname, shift) \
1176 { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, \
1177 .info = snd_ac97_stac9758_input_jack_info, \
1178 .get = snd_ac97_stac9758_input_jack_get, \
1179 .put = snd_ac97_stac9758_input_jack_put, \
1180 .private_value = shift }
1181 static const struct snd_kcontrol_new snd_ac97_sigmatel_stac9758_controls
[] = {
1182 STAC9758_OUTPUT_JACK("Mic1 Jack", 1),
1183 STAC9758_OUTPUT_JACK("LineIn Jack", 4),
1184 STAC9758_OUTPUT_JACK("Front Jack", 7),
1185 STAC9758_OUTPUT_JACK("Rear Jack", 10),
1186 STAC9758_OUTPUT_JACK("Center/LFE Jack", 13),
1187 STAC9758_INPUT_JACK("Mic Input Source", 0),
1188 STAC9758_INPUT_JACK("Line Input Source", 8),
1190 .iface
= SNDRV_CTL_ELEM_IFACE_MIXER
,
1191 .name
= "Headphone Amp",
1192 .info
= snd_ac97_stac9758_phonesel_info
,
1193 .get
= snd_ac97_stac9758_phonesel_get
,
1194 .put
= snd_ac97_stac9758_phonesel_put
1196 AC97_SINGLE("Exchange Center/LFE", AC97_SIGMATEL_IOMISC
, 4, 1, 0),
1197 AC97_SINGLE("Headphone +3dB Boost", AC97_SIGMATEL_IOMISC
, 8, 1, 0)
1200 static int patch_sigmatel_stac9758_specific(struct snd_ac97
*ac97
)
1204 err
= patch_sigmatel_stac97xx_specific(ac97
);
1207 err
= patch_build_controls(ac97
, snd_ac97_sigmatel_stac9758_controls
,
1208 ARRAY_SIZE(snd_ac97_sigmatel_stac9758_controls
));
1212 snd_ac97_rename_vol_ctl(ac97
, "Headphone Playback", "Front Playback");
1213 /* DAC-A to Mix = PCM */
1214 /* DAC-B direct = Surround */
1216 snd_ac97_rename_vol_ctl(ac97
, "Video Playback", "Surround Mix Playback");
1217 /* DAC-C direct = Center/LFE */
1222 static const struct snd_ac97_build_ops patch_sigmatel_stac9758_ops
= {
1223 .build_3d
= patch_sigmatel_stac9700_3d
,
1224 .build_specific
= patch_sigmatel_stac9758_specific
1227 static int patch_sigmatel_stac9758(struct snd_ac97
* ac97
)
1229 static unsigned short regs
[4] = {
1230 AC97_SIGMATEL_OUTSEL
,
1231 AC97_SIGMATEL_IOMISC
,
1232 AC97_SIGMATEL_INSEL
,
1233 AC97_SIGMATEL_VARIOUS
1235 static unsigned short def_regs
[4] = {
1236 /* OUTSEL */ 0xd794, /* CL:CL, SR:SR, LO:MX, LI:DS, MI:DS */
1237 /* IOMISC */ 0x2001,
1238 /* INSEL */ 0x0201, /* LI:LI, MI:M1 */
1239 /* VARIOUS */ 0x0040
1241 static unsigned short m675_regs
[4] = {
1242 /* OUTSEL */ 0xfc70, /* CL:MX, SR:MX, LO:DS, LI:MX, MI:DS */
1243 /* IOMISC */ 0x2102, /* HP amp on */
1244 /* INSEL */ 0x0203, /* LI:LI, MI:FR */
1245 /* VARIOUS */ 0x0041 /* stereo mic */
1247 unsigned short *pregs
= def_regs
;
1250 /* Gateway M675 notebook */
1252 ac97
->subsystem_vendor
== 0x107b &&
1253 ac97
->subsystem_device
== 0x0601)
1256 // patch for SigmaTel
1257 ac97
->build_ops
= &patch_sigmatel_stac9758_ops
;
1258 /* FIXME: assume only page 0 for writing cache */
1259 snd_ac97_update_bits(ac97
, AC97_INT_PAGING
, AC97_PAGE_MASK
, AC97_PAGE_VENDOR
);
1260 for (i
= 0; i
< 4; i
++)
1261 snd_ac97_write_cache(ac97
, regs
[i
], pregs
[i
]);
1263 ac97
->flags
|= AC97_STEREO_MUTES
;
1268 * Cirrus Logic CS42xx codecs
1270 static const struct snd_kcontrol_new snd_ac97_cirrus_controls_spdif
[2] = {
1271 AC97_SINGLE(SNDRV_CTL_NAME_IEC958("",PLAYBACK
,SWITCH
), AC97_CSR_SPDIF
, 15, 1, 0),
1272 AC97_SINGLE(SNDRV_CTL_NAME_IEC958("",PLAYBACK
,NONE
) "AC97-SPSA", AC97_CSR_ACMODE
, 0, 3, 0)
1275 static int patch_cirrus_build_spdif(struct snd_ac97
* ac97
)
1279 /* con mask, pro mask, default */
1280 if ((err
= patch_build_controls(ac97
, &snd_ac97_controls_spdif
[0], 3)) < 0)
1283 if ((err
= patch_build_controls(ac97
, &snd_ac97_cirrus_controls_spdif
[0], 1)) < 0)
1285 switch (ac97
->id
& AC97_ID_CS_MASK
) {
1286 case AC97_ID_CS4205
:
1287 if ((err
= patch_build_controls(ac97
, &snd_ac97_cirrus_controls_spdif
[1], 1)) < 0)
1291 /* set default PCM S/PDIF params */
1292 /* consumer,PCM audio,no copyright,no preemphasis,PCM coder,original,48000Hz */
1293 snd_ac97_write_cache(ac97
, AC97_CSR_SPDIF
, 0x0a20);
1297 static const struct snd_ac97_build_ops patch_cirrus_ops
= {
1298 .build_spdif
= patch_cirrus_build_spdif
1301 static int patch_cirrus_spdif(struct snd_ac97
* ac97
)
1303 /* Basically, the cs4201/cs4205/cs4297a has non-standard sp/dif registers.
1304 WHY CAN'T ANYONE FOLLOW THE BLOODY SPEC? *sigh*
1305 - sp/dif EA ID is not set, but sp/dif is always present.
1306 - enable/disable is spdif register bit 15.
1307 - sp/dif control register is 0x68. differs from AC97:
1308 - valid is bit 14 (vs 15)
1310 - only 44.1/48k [00 = 48, 01=44,1] (AC97 is 00=44.1, 10=48)
1311 - sp/dif ssource select is in 0x5e bits 0,1.
1314 ac97
->build_ops
= &patch_cirrus_ops
;
1315 ac97
->flags
|= AC97_CS_SPDIF
;
1316 ac97
->rates
[AC97_RATES_SPDIF
] &= ~SNDRV_PCM_RATE_32000
;
1317 ac97
->ext_id
|= AC97_EI_SPDIF
; /* force the detection of spdif */
1318 snd_ac97_write_cache(ac97
, AC97_CSR_ACMODE
, 0x0080);
1322 static int patch_cirrus_cs4299(struct snd_ac97
* ac97
)
1324 /* force the detection of PC Beep */
1325 ac97
->flags
|= AC97_HAS_PC_BEEP
;
1327 return patch_cirrus_spdif(ac97
);
1333 static const struct snd_kcontrol_new snd_ac97_conexant_controls_spdif
[1] = {
1334 AC97_SINGLE(SNDRV_CTL_NAME_IEC958("",PLAYBACK
,SWITCH
), AC97_CXR_AUDIO_MISC
, 3, 1, 0),
1337 static int patch_conexant_build_spdif(struct snd_ac97
* ac97
)
1341 /* con mask, pro mask, default */
1342 if ((err
= patch_build_controls(ac97
, &snd_ac97_controls_spdif
[0], 3)) < 0)
1345 if ((err
= patch_build_controls(ac97
, &snd_ac97_conexant_controls_spdif
[0], 1)) < 0)
1347 /* set default PCM S/PDIF params */
1348 /* consumer,PCM audio,no copyright,no preemphasis,PCM coder,original,48000Hz */
1349 snd_ac97_write_cache(ac97
, AC97_CXR_AUDIO_MISC
,
1350 snd_ac97_read(ac97
, AC97_CXR_AUDIO_MISC
) & ~(AC97_CXR_SPDIFEN
|AC97_CXR_COPYRGT
|AC97_CXR_SPDIF_MASK
));
1354 static const struct snd_ac97_build_ops patch_conexant_ops
= {
1355 .build_spdif
= patch_conexant_build_spdif
1358 static int patch_conexant(struct snd_ac97
* ac97
)
1360 ac97
->build_ops
= &patch_conexant_ops
;
1361 ac97
->flags
|= AC97_CX_SPDIF
;
1362 ac97
->ext_id
|= AC97_EI_SPDIF
; /* force the detection of spdif */
1363 ac97
->rates
[AC97_RATES_SPDIF
] = SNDRV_PCM_RATE_48000
; /* 48k only */
1367 static int patch_cx20551(struct snd_ac97
*ac97
)
1369 snd_ac97_update_bits(ac97
, 0x5c, 0x01, 0x01);
1374 * Analog Device AD18xx, AD19xx codecs
1377 static void ad18xx_resume(struct snd_ac97
*ac97
)
1379 static unsigned short setup_regs
[] = {
1380 AC97_AD_MISC
, AC97_AD_SERIAL_CFG
, AC97_AD_JACK_SPDIF
,
1384 for (i
= 0; i
< (int)ARRAY_SIZE(setup_regs
); i
++) {
1385 unsigned short reg
= setup_regs
[i
];
1386 if (test_bit(reg
, ac97
->reg_accessed
)) {
1387 snd_ac97_write(ac97
, reg
, ac97
->regs
[reg
]);
1388 snd_ac97_read(ac97
, reg
);
1392 if (! (ac97
->flags
& AC97_AD_MULTI
))
1393 /* normal restore */
1394 snd_ac97_restore_status(ac97
);
1396 /* restore the AD18xx codec configurations */
1397 for (codec
= 0; codec
< 3; codec
++) {
1398 if (! ac97
->spec
.ad18xx
.id
[codec
])
1400 /* select single codec */
1401 snd_ac97_update_bits(ac97
, AC97_AD_SERIAL_CFG
, 0x7000,
1402 ac97
->spec
.ad18xx
.unchained
[codec
] | ac97
->spec
.ad18xx
.chained
[codec
]);
1403 ac97
->bus
->ops
->write(ac97
, AC97_AD_CODEC_CFG
, ac97
->spec
.ad18xx
.codec_cfg
[codec
]);
1405 /* select all codecs */
1406 snd_ac97_update_bits(ac97
, AC97_AD_SERIAL_CFG
, 0x7000, 0x7000);
1408 /* restore status */
1409 for (i
= 2; i
< 0x7c ; i
+= 2) {
1410 if (i
== AC97_POWERDOWN
|| i
== AC97_EXTENDED_ID
)
1412 if (test_bit(i
, ac97
->reg_accessed
)) {
1413 /* handle multi codecs for AD18xx */
1414 if (i
== AC97_PCM
) {
1415 for (codec
= 0; codec
< 3; codec
++) {
1416 if (! ac97
->spec
.ad18xx
.id
[codec
])
1418 /* select single codec */
1419 snd_ac97_update_bits(ac97
, AC97_AD_SERIAL_CFG
, 0x7000,
1420 ac97
->spec
.ad18xx
.unchained
[codec
] | ac97
->spec
.ad18xx
.chained
[codec
]);
1421 /* update PCM bits */
1422 ac97
->bus
->ops
->write(ac97
, AC97_PCM
, ac97
->spec
.ad18xx
.pcmreg
[codec
]);
1424 /* select all codecs */
1425 snd_ac97_update_bits(ac97
, AC97_AD_SERIAL_CFG
, 0x7000, 0x7000);
1427 } else if (i
== AC97_AD_TEST
||
1428 i
== AC97_AD_CODEC_CFG
||
1429 i
== AC97_AD_SERIAL_CFG
)
1430 continue; /* ignore */
1432 snd_ac97_write(ac97
, i
, ac97
->regs
[i
]);
1433 snd_ac97_read(ac97
, i
);
1437 snd_ac97_restore_iec958(ac97
);
1440 static void ad1888_resume(struct snd_ac97
*ac97
)
1442 ad18xx_resume(ac97
);
1443 snd_ac97_write_cache(ac97
, AC97_CODEC_CLASS_REV
, 0x8080);
1448 static const struct snd_ac97_res_table ad1819_restbl
[] = {
1449 { AC97_PHONE
, 0x9f1f },
1450 { AC97_MIC
, 0x9f1f },
1451 { AC97_LINE
, 0x9f1f },
1452 { AC97_CD
, 0x9f1f },
1453 { AC97_VIDEO
, 0x9f1f },
1454 { AC97_AUX
, 0x9f1f },
1455 { AC97_PCM
, 0x9f1f },
1456 { } /* terminator */
1459 static int patch_ad1819(struct snd_ac97
* ac97
)
1461 unsigned short scfg
;
1463 // patch for Analog Devices
1464 scfg
= snd_ac97_read(ac97
, AC97_AD_SERIAL_CFG
);
1465 snd_ac97_write_cache(ac97
, AC97_AD_SERIAL_CFG
, scfg
| 0x7000); /* select all codecs */
1466 ac97
->res_table
= ad1819_restbl
;
1470 static unsigned short patch_ad1881_unchained(struct snd_ac97
* ac97
, int idx
, unsigned short mask
)
1474 // test for unchained codec
1475 snd_ac97_update_bits(ac97
, AC97_AD_SERIAL_CFG
, 0x7000, mask
);
1476 snd_ac97_write_cache(ac97
, AC97_AD_CODEC_CFG
, 0x0000); /* ID0C, ID1C, SDIE = off */
1477 val
= snd_ac97_read(ac97
, AC97_VENDOR_ID2
);
1478 if ((val
& 0xff40) != 0x5340)
1480 ac97
->spec
.ad18xx
.unchained
[idx
] = mask
;
1481 ac97
->spec
.ad18xx
.id
[idx
] = val
;
1482 ac97
->spec
.ad18xx
.codec_cfg
[idx
] = 0x0000;
1486 static int patch_ad1881_chained1(struct snd_ac97
* ac97
, int idx
, unsigned short codec_bits
)
1488 static int cfg_bits
[3] = { 1<<12, 1<<14, 1<<13 };
1491 snd_ac97_update_bits(ac97
, AC97_AD_SERIAL_CFG
, 0x7000, cfg_bits
[idx
]);
1492 snd_ac97_write_cache(ac97
, AC97_AD_CODEC_CFG
, 0x0004); // SDIE
1493 val
= snd_ac97_read(ac97
, AC97_VENDOR_ID2
);
1494 if ((val
& 0xff40) != 0x5340)
1497 snd_ac97_write_cache(ac97
, AC97_AD_CODEC_CFG
, codec_bits
);
1498 ac97
->spec
.ad18xx
.chained
[idx
] = cfg_bits
[idx
];
1499 ac97
->spec
.ad18xx
.id
[idx
] = val
;
1500 ac97
->spec
.ad18xx
.codec_cfg
[idx
] = codec_bits
? codec_bits
: 0x0004;
1504 static void patch_ad1881_chained(struct snd_ac97
* ac97
, int unchained_idx
, int cidx1
, int cidx2
)
1506 // already detected?
1507 if (ac97
->spec
.ad18xx
.unchained
[cidx1
] || ac97
->spec
.ad18xx
.chained
[cidx1
])
1509 if (ac97
->spec
.ad18xx
.unchained
[cidx2
] || ac97
->spec
.ad18xx
.chained
[cidx2
])
1511 if (cidx1
< 0 && cidx2
< 0)
1513 // test for chained codecs
1514 snd_ac97_update_bits(ac97
, AC97_AD_SERIAL_CFG
, 0x7000,
1515 ac97
->spec
.ad18xx
.unchained
[unchained_idx
]);
1516 snd_ac97_write_cache(ac97
, AC97_AD_CODEC_CFG
, 0x0002); // ID1C
1517 ac97
->spec
.ad18xx
.codec_cfg
[unchained_idx
] = 0x0002;
1520 patch_ad1881_chained1(ac97
, cidx1
, 0);
1521 else if (patch_ad1881_chained1(ac97
, cidx1
, 0x0006)) // SDIE | ID1C
1522 patch_ad1881_chained1(ac97
, cidx2
, 0);
1523 else if (patch_ad1881_chained1(ac97
, cidx2
, 0x0006)) // SDIE | ID1C
1524 patch_ad1881_chained1(ac97
, cidx1
, 0);
1525 } else if (cidx2
>= 0) {
1526 patch_ad1881_chained1(ac97
, cidx2
, 0);
1530 static const struct snd_ac97_build_ops patch_ad1881_build_ops
= {
1532 .resume
= ad18xx_resume
1536 static int patch_ad1881(struct snd_ac97
* ac97
)
1538 static const char cfg_idxs
[3][2] = {
1544 // patch for Analog Devices
1545 unsigned short codecs
[3];
1549 val
= snd_ac97_read(ac97
, AC97_AD_SERIAL_CFG
);
1550 snd_ac97_write_cache(ac97
, AC97_AD_SERIAL_CFG
, val
);
1551 codecs
[0] = patch_ad1881_unchained(ac97
, 0, (1<<12));
1552 codecs
[1] = patch_ad1881_unchained(ac97
, 1, (1<<14));
1553 codecs
[2] = patch_ad1881_unchained(ac97
, 2, (1<<13));
1555 if (! (codecs
[0] || codecs
[1] || codecs
[2]))
1558 for (idx
= 0; idx
< 3; idx
++)
1559 if (ac97
->spec
.ad18xx
.unchained
[idx
])
1560 patch_ad1881_chained(ac97
, idx
, cfg_idxs
[idx
][0], cfg_idxs
[idx
][1]);
1562 if (ac97
->spec
.ad18xx
.id
[1]) {
1563 ac97
->flags
|= AC97_AD_MULTI
;
1564 ac97
->scaps
|= AC97_SCAP_SURROUND_DAC
;
1566 if (ac97
->spec
.ad18xx
.id
[2]) {
1567 ac97
->flags
|= AC97_AD_MULTI
;
1568 ac97
->scaps
|= AC97_SCAP_CENTER_LFE_DAC
;
1572 /* select all codecs */
1573 snd_ac97_update_bits(ac97
, AC97_AD_SERIAL_CFG
, 0x7000, 0x7000);
1574 /* check if only one codec is present */
1575 for (idx
= num
= 0; idx
< 3; idx
++)
1576 if (ac97
->spec
.ad18xx
.id
[idx
])
1579 /* ok, deselect all ID bits */
1580 snd_ac97_write_cache(ac97
, AC97_AD_CODEC_CFG
, 0x0000);
1581 ac97
->spec
.ad18xx
.codec_cfg
[0] =
1582 ac97
->spec
.ad18xx
.codec_cfg
[1] =
1583 ac97
->spec
.ad18xx
.codec_cfg
[2] = 0x0000;
1585 /* required for AD1886/AD1885 combination */
1586 ac97
->ext_id
= snd_ac97_read(ac97
, AC97_EXTENDED_ID
);
1587 if (ac97
->spec
.ad18xx
.id
[0]) {
1588 ac97
->id
&= 0xffff0000;
1589 ac97
->id
|= ac97
->spec
.ad18xx
.id
[0];
1591 ac97
->build_ops
= &patch_ad1881_build_ops
;
1595 static const struct snd_kcontrol_new snd_ac97_controls_ad1885
[] = {
1596 AC97_SINGLE("Digital Mono Direct", AC97_AD_MISC
, 11, 1, 0),
1597 /* AC97_SINGLE("Digital Audio Mode", AC97_AD_MISC, 12, 1, 0), */ /* seems problematic */
1598 AC97_SINGLE("Low Power Mixer", AC97_AD_MISC
, 14, 1, 0),
1599 AC97_SINGLE("Zero Fill DAC", AC97_AD_MISC
, 15, 1, 0),
1600 AC97_SINGLE("Headphone Jack Sense", AC97_AD_JACK_SPDIF
, 9, 1, 1), /* inverted */
1601 AC97_SINGLE("Line Jack Sense", AC97_AD_JACK_SPDIF
, 8, 1, 1), /* inverted */
1604 static const DECLARE_TLV_DB_SCALE(db_scale_6bit_6db_max
, -8850, 150, 0);
1606 static int patch_ad1885_specific(struct snd_ac97
* ac97
)
1610 if ((err
= patch_build_controls(ac97
, snd_ac97_controls_ad1885
, ARRAY_SIZE(snd_ac97_controls_ad1885
))) < 0)
1612 reset_tlv(ac97
, "Headphone Playback Volume",
1613 db_scale_6bit_6db_max
);
1617 static const struct snd_ac97_build_ops patch_ad1885_build_ops
= {
1618 .build_specific
= &patch_ad1885_specific
,
1620 .resume
= ad18xx_resume
1624 static int patch_ad1885(struct snd_ac97
* ac97
)
1627 /* This is required to deal with the Intel D815EEAL2 */
1628 /* i.e. Line out is actually headphone out from codec */
1631 snd_ac97_write_cache(ac97
, AC97_AD_MISC
, 0x0404);
1633 ac97
->build_ops
= &patch_ad1885_build_ops
;
1637 static int patch_ad1886_specific(struct snd_ac97
* ac97
)
1639 reset_tlv(ac97
, "Headphone Playback Volume",
1640 db_scale_6bit_6db_max
);
1644 static const struct snd_ac97_build_ops patch_ad1886_build_ops
= {
1645 .build_specific
= &patch_ad1886_specific
,
1647 .resume
= ad18xx_resume
1651 static int patch_ad1886(struct snd_ac97
* ac97
)
1654 /* Presario700 workaround */
1655 /* for Jack Sense/SPDIF Register misetting causing */
1656 snd_ac97_write_cache(ac97
, AC97_AD_JACK_SPDIF
, 0x0010);
1657 ac97
->build_ops
= &patch_ad1886_build_ops
;
1661 /* MISC bits (AD1888/AD1980/AD1985 register 0x76) */
1662 #define AC97_AD198X_MBC 0x0003 /* mic boost */
1663 #define AC97_AD198X_MBC_20 0x0000 /* +20dB */
1664 #define AC97_AD198X_MBC_10 0x0001 /* +10dB */
1665 #define AC97_AD198X_MBC_30 0x0002 /* +30dB */
1666 #define AC97_AD198X_VREFD 0x0004 /* VREF high-Z */
1667 #define AC97_AD198X_VREFH 0x0008 /* 0=2.25V, 1=3.7V */
1668 #define AC97_AD198X_VREF_0 0x000c /* 0V (AD1985 only) */
1669 #define AC97_AD198X_VREF_MASK (AC97_AD198X_VREFH | AC97_AD198X_VREFD)
1670 #define AC97_AD198X_VREF_SHIFT 2
1671 #define AC97_AD198X_SRU 0x0010 /* sample rate unlock */
1672 #define AC97_AD198X_LOSEL 0x0020 /* LINE_OUT amplifiers input select */
1673 #define AC97_AD198X_2MIC 0x0040 /* 2-channel mic select */
1674 #define AC97_AD198X_SPRD 0x0080 /* SPREAD enable */
1675 #define AC97_AD198X_DMIX0 0x0100 /* downmix mode: */
1676 /* 0 = 6-to-4, 1 = 6-to-2 downmix */
1677 #define AC97_AD198X_DMIX1 0x0200 /* downmix mode: 1 = enabled */
1678 #define AC97_AD198X_HPSEL 0x0400 /* headphone amplifier input select */
1679 #define AC97_AD198X_CLDIS 0x0800 /* center/lfe disable */
1680 #define AC97_AD198X_LODIS 0x1000 /* LINE_OUT disable */
1681 #define AC97_AD198X_MSPLT 0x2000 /* mute split */
1682 #define AC97_AD198X_AC97NC 0x4000 /* AC97 no compatible mode */
1683 #define AC97_AD198X_DACZ 0x8000 /* DAC zero-fill mode */
1685 /* MISC 1 bits (AD1986 register 0x76) */
1686 #define AC97_AD1986_MBC 0x0003 /* mic boost */
1687 #define AC97_AD1986_MBC_20 0x0000 /* +20dB */
1688 #define AC97_AD1986_MBC_10 0x0001 /* +10dB */
1689 #define AC97_AD1986_MBC_30 0x0002 /* +30dB */
1690 #define AC97_AD1986_LISEL0 0x0004 /* LINE_IN select bit 0 */
1691 #define AC97_AD1986_LISEL1 0x0008 /* LINE_IN select bit 1 */
1692 #define AC97_AD1986_LISEL_MASK (AC97_AD1986_LISEL1 | AC97_AD1986_LISEL0)
1693 #define AC97_AD1986_LISEL_LI 0x0000 /* LINE_IN pins as LINE_IN source */
1694 #define AC97_AD1986_LISEL_SURR 0x0004 /* SURROUND pins as LINE_IN source */
1695 #define AC97_AD1986_LISEL_MIC 0x0008 /* MIC_1/2 pins as LINE_IN source */
1696 #define AC97_AD1986_SRU 0x0010 /* sample rate unlock */
1697 #define AC97_AD1986_SOSEL 0x0020 /* SURROUND_OUT amplifiers input sel */
1698 #define AC97_AD1986_2MIC 0x0040 /* 2-channel mic select */
1699 #define AC97_AD1986_SPRD 0x0080 /* SPREAD enable */
1700 #define AC97_AD1986_DMIX0 0x0100 /* downmix mode: */
1701 /* 0 = 6-to-4, 1 = 6-to-2 downmix */
1702 #define AC97_AD1986_DMIX1 0x0200 /* downmix mode: 1 = enabled */
1703 #define AC97_AD1986_CLDIS 0x0800 /* center/lfe disable */
1704 #define AC97_AD1986_SODIS 0x1000 /* SURROUND_OUT disable */
1705 #define AC97_AD1986_MSPLT 0x2000 /* mute split (read only 1) */
1706 #define AC97_AD1986_AC97NC 0x4000 /* AC97 no compatible mode (r/o 1) */
1707 #define AC97_AD1986_DACZ 0x8000 /* DAC zero-fill mode */
1709 /* MISC 2 bits (AD1986 register 0x70) */
1710 #define AC97_AD_MISC2 0x70 /* Misc Control Bits 2 (AD1986) */
1712 #define AC97_AD1986_CVREF0 0x0004 /* C/LFE VREF_OUT 2.25V */
1713 #define AC97_AD1986_CVREF1 0x0008 /* C/LFE VREF_OUT 0V */
1714 #define AC97_AD1986_CVREF2 0x0010 /* C/LFE VREF_OUT 3.7V */
1715 #define AC97_AD1986_CVREF_MASK \
1716 (AC97_AD1986_CVREF2 | AC97_AD1986_CVREF1 | AC97_AD1986_CVREF0)
1717 #define AC97_AD1986_JSMAP 0x0020 /* Jack Sense Mapping 1 = alternate */
1718 #define AC97_AD1986_MMDIS 0x0080 /* Mono Mute Disable */
1719 #define AC97_AD1986_MVREF0 0x0400 /* MIC VREF_OUT 2.25V */
1720 #define AC97_AD1986_MVREF1 0x0800 /* MIC VREF_OUT 0V */
1721 #define AC97_AD1986_MVREF2 0x1000 /* MIC VREF_OUT 3.7V */
1722 #define AC97_AD1986_MVREF_MASK \
1723 (AC97_AD1986_MVREF2 | AC97_AD1986_MVREF1 | AC97_AD1986_MVREF0)
1725 /* MISC 3 bits (AD1986 register 0x7a) */
1726 #define AC97_AD_MISC3 0x7a /* Misc Control Bits 3 (AD1986) */
1728 #define AC97_AD1986_MMIX 0x0004 /* Mic Mix, left/right */
1729 #define AC97_AD1986_GPO 0x0008 /* General Purpose Out */
1730 #define AC97_AD1986_LOHPEN 0x0010 /* LINE_OUT headphone drive */
1731 #define AC97_AD1986_LVREF0 0x0100 /* LINE_OUT VREF_OUT 2.25V */
1732 #define AC97_AD1986_LVREF1 0x0200 /* LINE_OUT VREF_OUT 0V */
1733 #define AC97_AD1986_LVREF2 0x0400 /* LINE_OUT VREF_OUT 3.7V */
1734 #define AC97_AD1986_LVREF_MASK \
1735 (AC97_AD1986_LVREF2 | AC97_AD1986_LVREF1 | AC97_AD1986_LVREF0)
1736 #define AC97_AD1986_JSINVA 0x0800 /* Jack Sense Invert SENSE_A */
1737 #define AC97_AD1986_LOSEL 0x1000 /* LINE_OUT amplifiers input select */
1738 #define AC97_AD1986_HPSEL0 0x2000 /* Headphone amplifiers */
1739 /* input select Surround DACs */
1740 #define AC97_AD1986_HPSEL1 0x4000 /* Headphone amplifiers input */
1741 /* select C/LFE DACs */
1742 #define AC97_AD1986_JSINVB 0x8000 /* Jack Sense Invert SENSE_B */
1744 /* Serial Config bits (AD1986 register 0x74) (incomplete) */
1745 #define AC97_AD1986_OMS0 0x0100 /* Optional Mic Selector bit 0 */
1746 #define AC97_AD1986_OMS1 0x0200 /* Optional Mic Selector bit 1 */
1747 #define AC97_AD1986_OMS2 0x0400 /* Optional Mic Selector bit 2 */
1748 #define AC97_AD1986_OMS_MASK \
1749 (AC97_AD1986_OMS2 | AC97_AD1986_OMS1 | AC97_AD1986_OMS0)
1750 #define AC97_AD1986_OMS_M 0x0000 /* MIC_1/2 pins are MIC sources */
1751 #define AC97_AD1986_OMS_L 0x0100 /* LINE_IN pins are MIC sources */
1752 #define AC97_AD1986_OMS_C 0x0200 /* Center/LFE pins are MCI sources */
1753 #define AC97_AD1986_OMS_MC 0x0400 /* Mix of MIC and C/LFE pins */
1754 /* are MIC sources */
1755 #define AC97_AD1986_OMS_ML 0x0500 /* MIX of MIC and LINE_IN pins */
1756 /* are MIC sources */
1757 #define AC97_AD1986_OMS_LC 0x0600 /* MIX of LINE_IN and C/LFE pins */
1758 /* are MIC sources */
1759 #define AC97_AD1986_OMS_MLC 0x0700 /* MIX of MIC, LINE_IN, C/LFE pins */
1760 /* are MIC sources */
1763 static int snd_ac97_ad198x_spdif_source_info(struct snd_kcontrol
*kcontrol
, struct snd_ctl_elem_info
*uinfo
)
1765 static const char * const texts
[2] = { "AC-Link", "A/D Converter" };
1767 return snd_ctl_enum_info(uinfo
, 1, 2, texts
);
1770 static int snd_ac97_ad198x_spdif_source_get(struct snd_kcontrol
*kcontrol
, struct snd_ctl_elem_value
*ucontrol
)
1772 struct snd_ac97
*ac97
= snd_kcontrol_chip(kcontrol
);
1775 val
= ac97
->regs
[AC97_AD_SERIAL_CFG
];
1776 ucontrol
->value
.enumerated
.item
[0] = (val
>> 2) & 1;
1780 static int snd_ac97_ad198x_spdif_source_put(struct snd_kcontrol
*kcontrol
, struct snd_ctl_elem_value
*ucontrol
)
1782 struct snd_ac97
*ac97
= snd_kcontrol_chip(kcontrol
);
1785 if (ucontrol
->value
.enumerated
.item
[0] > 1)
1787 val
= ucontrol
->value
.enumerated
.item
[0] << 2;
1788 return snd_ac97_update_bits(ac97
, AC97_AD_SERIAL_CFG
, 0x0004, val
);
1791 static const struct snd_kcontrol_new snd_ac97_ad198x_spdif_source
= {
1792 .iface
= SNDRV_CTL_ELEM_IFACE_MIXER
,
1793 .name
= SNDRV_CTL_NAME_IEC958("",PLAYBACK
,NONE
) "Source",
1794 .info
= snd_ac97_ad198x_spdif_source_info
,
1795 .get
= snd_ac97_ad198x_spdif_source_get
,
1796 .put
= snd_ac97_ad198x_spdif_source_put
,
1799 static int patch_ad198x_post_spdif(struct snd_ac97
* ac97
)
1801 return patch_build_controls(ac97
, &snd_ac97_ad198x_spdif_source
, 1);
1804 static const struct snd_kcontrol_new snd_ac97_ad1981x_jack_sense
[] = {
1805 AC97_SINGLE("Headphone Jack Sense", AC97_AD_JACK_SPDIF
, 11, 1, 0),
1806 AC97_SINGLE("Line Jack Sense", AC97_AD_JACK_SPDIF
, 12, 1, 0),
1809 /* black list to avoid HP/Line jack-sense controls
1810 * (SS vendor << 16 | device)
1812 static unsigned int ad1981_jacks_blacklist
[] = {
1813 0x10140523, /* Thinkpad R40 */
1814 0x10140534, /* Thinkpad X31 */
1815 0x10140537, /* Thinkpad T41p */
1816 0x1014053e, /* Thinkpad R40e */
1817 0x10140554, /* Thinkpad T42p/R50p */
1818 0x10140567, /* Thinkpad T43p 2668-G7U */
1819 0x10140581, /* Thinkpad X41-2527 */
1820 0x10280160, /* Dell Dimension 2400 */
1821 0x104380b0, /* Asus A7V8X-MX */
1822 0x11790241, /* Toshiba Satellite A-15 S127 */
1823 0x1179ff10, /* Toshiba P500 */
1824 0x144dc01a, /* Samsung NP-X20C004/SEG */
1828 static int check_list(struct snd_ac97
*ac97
, const unsigned int *list
)
1830 u32 subid
= ((u32
)ac97
->subsystem_vendor
<< 16) | ac97
->subsystem_device
;
1831 for (; *list
; list
++)
1837 static int patch_ad1981a_specific(struct snd_ac97
* ac97
)
1839 if (check_list(ac97
, ad1981_jacks_blacklist
))
1841 return patch_build_controls(ac97
, snd_ac97_ad1981x_jack_sense
,
1842 ARRAY_SIZE(snd_ac97_ad1981x_jack_sense
));
1845 static const struct snd_ac97_build_ops patch_ad1981a_build_ops
= {
1846 .build_post_spdif
= patch_ad198x_post_spdif
,
1847 .build_specific
= patch_ad1981a_specific
,
1849 .resume
= ad18xx_resume
1853 /* white list to enable HP jack-sense bits
1854 * (SS vendor << 16 | device)
1856 static unsigned int ad1981_jacks_whitelist
[] = {
1857 0x0e11005a, /* HP nc4000/4010 */
1858 0x103c0890, /* HP nc6000 */
1859 0x103c0938, /* HP nc4220 */
1860 0x103c099c, /* HP nx6110 */
1861 0x103c0944, /* HP nc6220 */
1862 0x103c0934, /* HP nc8220 */
1863 0x103c006d, /* HP nx9105 */
1864 0x103c300d, /* HP Compaq dc5100 SFF(PT003AW) */
1865 0x17340088, /* FSC Scenic-W */
1869 static void check_ad1981_hp_jack_sense(struct snd_ac97
*ac97
)
1871 if (check_list(ac97
, ad1981_jacks_whitelist
))
1872 /* enable headphone jack sense */
1873 snd_ac97_update_bits(ac97
, AC97_AD_JACK_SPDIF
, 1<<11, 1<<11);
1876 static int patch_ad1981a(struct snd_ac97
*ac97
)
1879 ac97
->build_ops
= &patch_ad1981a_build_ops
;
1880 snd_ac97_update_bits(ac97
, AC97_AD_MISC
, AC97_AD198X_MSPLT
, AC97_AD198X_MSPLT
);
1881 ac97
->flags
|= AC97_STEREO_MUTES
;
1882 check_ad1981_hp_jack_sense(ac97
);
1886 static const struct snd_kcontrol_new snd_ac97_ad198x_2cmic
=
1887 AC97_SINGLE("Stereo Mic", AC97_AD_MISC
, 6, 1, 0);
1889 static int patch_ad1981b_specific(struct snd_ac97
*ac97
)
1893 if ((err
= patch_build_controls(ac97
, &snd_ac97_ad198x_2cmic
, 1)) < 0)
1895 if (check_list(ac97
, ad1981_jacks_blacklist
))
1897 return patch_build_controls(ac97
, snd_ac97_ad1981x_jack_sense
,
1898 ARRAY_SIZE(snd_ac97_ad1981x_jack_sense
));
1901 static const struct snd_ac97_build_ops patch_ad1981b_build_ops
= {
1902 .build_post_spdif
= patch_ad198x_post_spdif
,
1903 .build_specific
= patch_ad1981b_specific
,
1905 .resume
= ad18xx_resume
1909 static int patch_ad1981b(struct snd_ac97
*ac97
)
1912 ac97
->build_ops
= &patch_ad1981b_build_ops
;
1913 snd_ac97_update_bits(ac97
, AC97_AD_MISC
, AC97_AD198X_MSPLT
, AC97_AD198X_MSPLT
);
1914 ac97
->flags
|= AC97_STEREO_MUTES
;
1915 check_ad1981_hp_jack_sense(ac97
);
1919 #define snd_ac97_ad1888_lohpsel_info snd_ctl_boolean_mono_info
1921 static int snd_ac97_ad1888_lohpsel_get(struct snd_kcontrol
*kcontrol
, struct snd_ctl_elem_value
*ucontrol
)
1923 struct snd_ac97
*ac97
= snd_kcontrol_chip(kcontrol
);
1926 val
= ac97
->regs
[AC97_AD_MISC
];
1927 ucontrol
->value
.integer
.value
[0] = !(val
& AC97_AD198X_LOSEL
);
1928 if (ac97
->spec
.ad18xx
.lo_as_master
)
1929 ucontrol
->value
.integer
.value
[0] =
1930 !ucontrol
->value
.integer
.value
[0];
1934 static int snd_ac97_ad1888_lohpsel_put(struct snd_kcontrol
*kcontrol
, struct snd_ctl_elem_value
*ucontrol
)
1936 struct snd_ac97
*ac97
= snd_kcontrol_chip(kcontrol
);
1939 val
= !ucontrol
->value
.integer
.value
[0];
1940 if (ac97
->spec
.ad18xx
.lo_as_master
)
1942 val
= val
? (AC97_AD198X_LOSEL
| AC97_AD198X_HPSEL
) : 0;
1943 return snd_ac97_update_bits(ac97
, AC97_AD_MISC
,
1944 AC97_AD198X_LOSEL
| AC97_AD198X_HPSEL
, val
);
1947 static int snd_ac97_ad1888_downmix_info(struct snd_kcontrol
*kcontrol
, struct snd_ctl_elem_info
*uinfo
)
1949 static const char * const texts
[3] = {"Off", "6 -> 4", "6 -> 2"};
1951 return snd_ctl_enum_info(uinfo
, 1, 3, texts
);
1954 static int snd_ac97_ad1888_downmix_get(struct snd_kcontrol
*kcontrol
, struct snd_ctl_elem_value
*ucontrol
)
1956 struct snd_ac97
*ac97
= snd_kcontrol_chip(kcontrol
);
1959 val
= ac97
->regs
[AC97_AD_MISC
];
1960 if (!(val
& AC97_AD198X_DMIX1
))
1961 ucontrol
->value
.enumerated
.item
[0] = 0;
1963 ucontrol
->value
.enumerated
.item
[0] = 1 + ((val
>> 8) & 1);
1967 static int snd_ac97_ad1888_downmix_put(struct snd_kcontrol
*kcontrol
, struct snd_ctl_elem_value
*ucontrol
)
1969 struct snd_ac97
*ac97
= snd_kcontrol_chip(kcontrol
);
1972 if (ucontrol
->value
.enumerated
.item
[0] > 2)
1974 if (ucontrol
->value
.enumerated
.item
[0] == 0)
1977 val
= AC97_AD198X_DMIX1
|
1978 ((ucontrol
->value
.enumerated
.item
[0] - 1) << 8);
1979 return snd_ac97_update_bits(ac97
, AC97_AD_MISC
,
1980 AC97_AD198X_DMIX0
| AC97_AD198X_DMIX1
, val
);
1983 static void ad1888_update_jacks(struct snd_ac97
*ac97
)
1985 unsigned short val
= 0;
1986 /* clear LODIS if shared jack is to be used for Surround out */
1987 if (!ac97
->spec
.ad18xx
.lo_as_master
&& is_shared_linein(ac97
))
1989 /* clear CLDIS if shared jack is to be used for C/LFE out */
1990 if (is_shared_micin(ac97
))
1992 /* shared Line-In */
1993 snd_ac97_update_bits(ac97
, AC97_AD_MISC
, (1 << 11) | (1 << 12), val
);
1996 static const struct snd_kcontrol_new snd_ac97_ad1888_controls
[] = {
1998 .iface
= SNDRV_CTL_ELEM_IFACE_MIXER
,
1999 .name
= "Exchange Front/Surround",
2000 .info
= snd_ac97_ad1888_lohpsel_info
,
2001 .get
= snd_ac97_ad1888_lohpsel_get
,
2002 .put
= snd_ac97_ad1888_lohpsel_put
2004 AC97_SINGLE("V_REFOUT Enable", AC97_AD_MISC
, AC97_AD_VREFD_SHIFT
, 1, 1),
2005 AC97_SINGLE("High Pass Filter Enable", AC97_AD_TEST2
,
2006 AC97_AD_HPFD_SHIFT
, 1, 1),
2007 AC97_SINGLE("Spread Front to Surround and Center/LFE", AC97_AD_MISC
, 7, 1, 0),
2009 .iface
= SNDRV_CTL_ELEM_IFACE_MIXER
,
2011 .info
= snd_ac97_ad1888_downmix_info
,
2012 .get
= snd_ac97_ad1888_downmix_get
,
2013 .put
= snd_ac97_ad1888_downmix_put
2015 AC97_SURROUND_JACK_MODE_CTL
,
2016 AC97_CHANNEL_MODE_CTL
,
2018 AC97_SINGLE("Headphone Jack Sense", AC97_AD_JACK_SPDIF
, 10, 1, 0),
2019 AC97_SINGLE("Line Jack Sense", AC97_AD_JACK_SPDIF
, 12, 1, 0),
2022 static int patch_ad1888_specific(struct snd_ac97
*ac97
)
2024 if (!ac97
->spec
.ad18xx
.lo_as_master
) {
2025 /* rename 0x04 as "Master" and 0x02 as "Master Surround" */
2026 snd_ac97_rename_vol_ctl(ac97
, "Master Playback",
2027 "Master Surround Playback");
2028 snd_ac97_rename_vol_ctl(ac97
, "Headphone Playback",
2031 return patch_build_controls(ac97
, snd_ac97_ad1888_controls
, ARRAY_SIZE(snd_ac97_ad1888_controls
));
2034 static const struct snd_ac97_build_ops patch_ad1888_build_ops
= {
2035 .build_post_spdif
= patch_ad198x_post_spdif
,
2036 .build_specific
= patch_ad1888_specific
,
2038 .resume
= ad1888_resume
,
2040 .update_jacks
= ad1888_update_jacks
,
2043 static int patch_ad1888(struct snd_ac97
* ac97
)
2045 unsigned short misc
;
2048 ac97
->build_ops
= &patch_ad1888_build_ops
;
2051 * LO can be used as a real line-out on some devices,
2052 * and we need to revert the front/surround mixer switches
2054 if (ac97
->subsystem_vendor
== 0x1043 &&
2055 ac97
->subsystem_device
== 0x1193) /* ASUS A9T laptop */
2056 ac97
->spec
.ad18xx
.lo_as_master
= 1;
2058 misc
= snd_ac97_read(ac97
, AC97_AD_MISC
);
2059 /* AD-compatible mode */
2060 /* Stereo mutes enabled */
2061 misc
|= AC97_AD198X_MSPLT
| AC97_AD198X_AC97NC
;
2062 if (!ac97
->spec
.ad18xx
.lo_as_master
)
2063 /* Switch FRONT/SURROUND LINE-OUT/HP-OUT default connection */
2064 /* it seems that most vendors connect line-out connector to
2065 * headphone out of AC'97
2067 misc
|= AC97_AD198X_LOSEL
| AC97_AD198X_HPSEL
;
2069 snd_ac97_write_cache(ac97
, AC97_AD_MISC
, misc
);
2070 ac97
->flags
|= AC97_STEREO_MUTES
;
2074 static int patch_ad1980_specific(struct snd_ac97
*ac97
)
2078 if ((err
= patch_ad1888_specific(ac97
)) < 0)
2080 return patch_build_controls(ac97
, &snd_ac97_ad198x_2cmic
, 1);
2083 static const struct snd_ac97_build_ops patch_ad1980_build_ops
= {
2084 .build_post_spdif
= patch_ad198x_post_spdif
,
2085 .build_specific
= patch_ad1980_specific
,
2087 .resume
= ad18xx_resume
,
2089 .update_jacks
= ad1888_update_jacks
,
2092 static int patch_ad1980(struct snd_ac97
* ac97
)
2095 ac97
->build_ops
= &patch_ad1980_build_ops
;
2099 static int snd_ac97_ad1985_vrefout_info(struct snd_kcontrol
*kcontrol
,
2100 struct snd_ctl_elem_info
*uinfo
)
2102 static const char * const texts
[4] = {
2103 "High-Z", "3.7 V", "2.25 V", "0 V"
2106 return snd_ctl_enum_info(uinfo
, 1, 4, texts
);
2109 static int snd_ac97_ad1985_vrefout_get(struct snd_kcontrol
*kcontrol
,
2110 struct snd_ctl_elem_value
*ucontrol
)
2112 static const int reg2ctrl
[4] = {2, 0, 1, 3};
2113 struct snd_ac97
*ac97
= snd_kcontrol_chip(kcontrol
);
2115 val
= (ac97
->regs
[AC97_AD_MISC
] & AC97_AD198X_VREF_MASK
)
2116 >> AC97_AD198X_VREF_SHIFT
;
2117 ucontrol
->value
.enumerated
.item
[0] = reg2ctrl
[val
];
2121 static int snd_ac97_ad1985_vrefout_put(struct snd_kcontrol
*kcontrol
,
2122 struct snd_ctl_elem_value
*ucontrol
)
2124 static const int ctrl2reg
[4] = {1, 2, 0, 3};
2125 struct snd_ac97
*ac97
= snd_kcontrol_chip(kcontrol
);
2128 if (ucontrol
->value
.enumerated
.item
[0] > 3)
2130 val
= ctrl2reg
[ucontrol
->value
.enumerated
.item
[0]]
2131 << AC97_AD198X_VREF_SHIFT
;
2132 return snd_ac97_update_bits(ac97
, AC97_AD_MISC
,
2133 AC97_AD198X_VREF_MASK
, val
);
2136 static const struct snd_kcontrol_new snd_ac97_ad1985_controls
[] = {
2137 AC97_SINGLE("Exchange Center/LFE", AC97_AD_SERIAL_CFG
, 3, 1, 0),
2139 .iface
= SNDRV_CTL_ELEM_IFACE_MIXER
,
2140 .name
= "Exchange Front/Surround",
2141 .info
= snd_ac97_ad1888_lohpsel_info
,
2142 .get
= snd_ac97_ad1888_lohpsel_get
,
2143 .put
= snd_ac97_ad1888_lohpsel_put
2145 AC97_SINGLE("High Pass Filter Enable", AC97_AD_TEST2
, 12, 1, 1),
2146 AC97_SINGLE("Spread Front to Surround and Center/LFE",
2147 AC97_AD_MISC
, 7, 1, 0),
2149 .iface
= SNDRV_CTL_ELEM_IFACE_MIXER
,
2151 .info
= snd_ac97_ad1888_downmix_info
,
2152 .get
= snd_ac97_ad1888_downmix_get
,
2153 .put
= snd_ac97_ad1888_downmix_put
2156 .iface
= SNDRV_CTL_ELEM_IFACE_MIXER
,
2158 .info
= snd_ac97_ad1985_vrefout_info
,
2159 .get
= snd_ac97_ad1985_vrefout_get
,
2160 .put
= snd_ac97_ad1985_vrefout_put
2162 AC97_SURROUND_JACK_MODE_CTL
,
2163 AC97_CHANNEL_MODE_CTL
,
2165 AC97_SINGLE("Headphone Jack Sense", AC97_AD_JACK_SPDIF
, 10, 1, 0),
2166 AC97_SINGLE("Line Jack Sense", AC97_AD_JACK_SPDIF
, 12, 1, 0),
2169 static void ad1985_update_jacks(struct snd_ac97
*ac97
)
2171 ad1888_update_jacks(ac97
);
2172 /* clear OMS if shared jack is to be used for C/LFE out */
2173 snd_ac97_update_bits(ac97
, AC97_AD_SERIAL_CFG
, 1 << 9,
2174 is_shared_micin(ac97
) ? 1 << 9 : 0);
2177 static int patch_ad1985_specific(struct snd_ac97
*ac97
)
2181 /* rename 0x04 as "Master" and 0x02 as "Master Surround" */
2182 snd_ac97_rename_vol_ctl(ac97
, "Master Playback",
2183 "Master Surround Playback");
2184 snd_ac97_rename_vol_ctl(ac97
, "Headphone Playback", "Master Playback");
2186 if ((err
= patch_build_controls(ac97
, &snd_ac97_ad198x_2cmic
, 1)) < 0)
2189 return patch_build_controls(ac97
, snd_ac97_ad1985_controls
,
2190 ARRAY_SIZE(snd_ac97_ad1985_controls
));
2193 static const struct snd_ac97_build_ops patch_ad1985_build_ops
= {
2194 .build_post_spdif
= patch_ad198x_post_spdif
,
2195 .build_specific
= patch_ad1985_specific
,
2197 .resume
= ad18xx_resume
,
2199 .update_jacks
= ad1985_update_jacks
,
2202 static int patch_ad1985(struct snd_ac97
* ac97
)
2204 unsigned short misc
;
2207 ac97
->build_ops
= &patch_ad1985_build_ops
;
2208 misc
= snd_ac97_read(ac97
, AC97_AD_MISC
);
2209 /* switch front/surround line-out/hp-out */
2210 /* AD-compatible mode */
2211 /* Stereo mutes enabled */
2212 snd_ac97_write_cache(ac97
, AC97_AD_MISC
, misc
|
2216 AC97_AD198X_AC97NC
);
2217 ac97
->flags
|= AC97_STEREO_MUTES
;
2219 /* update current jack configuration */
2220 ad1985_update_jacks(ac97
);
2222 /* on AD1985 rev. 3, AC'97 revision bits are zero */
2223 ac97
->ext_id
= (ac97
->ext_id
& ~AC97_EI_REV_MASK
) | AC97_EI_REV_23
;
2227 #define snd_ac97_ad1986_bool_info snd_ctl_boolean_mono_info
2229 static int snd_ac97_ad1986_lososel_get(struct snd_kcontrol
*kcontrol
,
2230 struct snd_ctl_elem_value
*ucontrol
)
2232 struct snd_ac97
*ac97
= snd_kcontrol_chip(kcontrol
);
2235 val
= ac97
->regs
[AC97_AD_MISC3
];
2236 ucontrol
->value
.integer
.value
[0] = (val
& AC97_AD1986_LOSEL
) != 0;
2240 static int snd_ac97_ad1986_lososel_put(struct snd_kcontrol
*kcontrol
,
2241 struct snd_ctl_elem_value
*ucontrol
)
2243 struct snd_ac97
*ac97
= snd_kcontrol_chip(kcontrol
);
2246 int sprd
= (ac97
->regs
[AC97_AD_MISC
] & AC97_AD1986_SPRD
) != 0;
2248 ret0
= snd_ac97_update_bits(ac97
, AC97_AD_MISC3
, AC97_AD1986_LOSEL
,
2249 ucontrol
->value
.integer
.value
[0] != 0
2250 ? AC97_AD1986_LOSEL
: 0);
2254 /* SOSEL is set to values of "Spread" or "Exchange F/S" controls */
2255 ret1
= snd_ac97_update_bits(ac97
, AC97_AD_MISC
, AC97_AD1986_SOSEL
,
2256 (ucontrol
->value
.integer
.value
[0] != 0
2258 ? AC97_AD1986_SOSEL
: 0);
2262 return (ret0
> 0 || ret1
> 0) ? 1 : 0;
2265 static int snd_ac97_ad1986_spread_get(struct snd_kcontrol
*kcontrol
,
2266 struct snd_ctl_elem_value
*ucontrol
)
2268 struct snd_ac97
*ac97
= snd_kcontrol_chip(kcontrol
);
2271 val
= ac97
->regs
[AC97_AD_MISC
];
2272 ucontrol
->value
.integer
.value
[0] = (val
& AC97_AD1986_SPRD
) != 0;
2276 static int snd_ac97_ad1986_spread_put(struct snd_kcontrol
*kcontrol
,
2277 struct snd_ctl_elem_value
*ucontrol
)
2279 struct snd_ac97
*ac97
= snd_kcontrol_chip(kcontrol
);
2282 int sprd
= (ac97
->regs
[AC97_AD_MISC3
] & AC97_AD1986_LOSEL
) != 0;
2284 ret0
= snd_ac97_update_bits(ac97
, AC97_AD_MISC
, AC97_AD1986_SPRD
,
2285 ucontrol
->value
.integer
.value
[0] != 0
2286 ? AC97_AD1986_SPRD
: 0);
2290 /* SOSEL is set to values of "Spread" or "Exchange F/S" controls */
2291 ret1
= snd_ac97_update_bits(ac97
, AC97_AD_MISC
, AC97_AD1986_SOSEL
,
2292 (ucontrol
->value
.integer
.value
[0] != 0
2294 ? AC97_AD1986_SOSEL
: 0);
2298 return (ret0
> 0 || ret1
> 0) ? 1 : 0;
2301 static int snd_ac97_ad1986_miclisel_get(struct snd_kcontrol
*kcontrol
,
2302 struct snd_ctl_elem_value
*ucontrol
)
2304 struct snd_ac97
*ac97
= snd_kcontrol_chip(kcontrol
);
2306 ucontrol
->value
.integer
.value
[0] = ac97
->spec
.ad18xx
.swap_mic_linein
;
2310 static int snd_ac97_ad1986_miclisel_put(struct snd_kcontrol
*kcontrol
,
2311 struct snd_ctl_elem_value
*ucontrol
)
2313 struct snd_ac97
*ac97
= snd_kcontrol_chip(kcontrol
);
2314 unsigned char swap
= ucontrol
->value
.integer
.value
[0] != 0;
2316 if (swap
!= ac97
->spec
.ad18xx
.swap_mic_linein
) {
2317 ac97
->spec
.ad18xx
.swap_mic_linein
= swap
;
2318 if (ac97
->build_ops
->update_jacks
)
2319 ac97
->build_ops
->update_jacks(ac97
);
2325 static int snd_ac97_ad1986_vrefout_get(struct snd_kcontrol
*kcontrol
,
2326 struct snd_ctl_elem_value
*ucontrol
)
2328 /* Use MIC_1/2 V_REFOUT as the "get" value */
2329 struct snd_ac97
*ac97
= snd_kcontrol_chip(kcontrol
);
2331 unsigned short reg
= ac97
->regs
[AC97_AD_MISC2
];
2332 if ((reg
& AC97_AD1986_MVREF0
) != 0)
2334 else if ((reg
& AC97_AD1986_MVREF1
) != 0)
2336 else if ((reg
& AC97_AD1986_MVREF2
) != 0)
2340 ucontrol
->value
.enumerated
.item
[0] = val
;
2344 static int snd_ac97_ad1986_vrefout_put(struct snd_kcontrol
*kcontrol
,
2345 struct snd_ctl_elem_value
*ucontrol
)
2347 struct snd_ac97
*ac97
= snd_kcontrol_chip(kcontrol
);
2348 unsigned short cval
;
2349 unsigned short lval
;
2350 unsigned short mval
;
2355 switch (ucontrol
->value
.enumerated
.item
[0])
2357 case 0: /* High-Z */
2363 cval
= AC97_AD1986_CVREF2
;
2364 lval
= AC97_AD1986_LVREF2
;
2365 mval
= AC97_AD1986_MVREF2
;
2367 case 2: /* 2.25 V */
2368 cval
= AC97_AD1986_CVREF0
;
2369 lval
= AC97_AD1986_LVREF0
;
2370 mval
= AC97_AD1986_MVREF0
;
2373 cval
= AC97_AD1986_CVREF1
;
2374 lval
= AC97_AD1986_LVREF1
;
2375 mval
= AC97_AD1986_MVREF1
;
2381 cret
= snd_ac97_update_bits(ac97
, AC97_AD_MISC2
,
2382 AC97_AD1986_CVREF_MASK
, cval
);
2385 lret
= snd_ac97_update_bits(ac97
, AC97_AD_MISC3
,
2386 AC97_AD1986_LVREF_MASK
, lval
);
2389 mret
= snd_ac97_update_bits(ac97
, AC97_AD_MISC2
,
2390 AC97_AD1986_MVREF_MASK
, mval
);
2394 return (cret
> 0 || lret
> 0 || mret
> 0) ? 1 : 0;
2397 static const struct snd_kcontrol_new snd_ac97_ad1986_controls
[] = {
2398 AC97_SINGLE("Exchange Center/LFE", AC97_AD_SERIAL_CFG
, 3, 1, 0),
2400 .iface
= SNDRV_CTL_ELEM_IFACE_MIXER
,
2401 .name
= "Exchange Front/Surround",
2402 .info
= snd_ac97_ad1986_bool_info
,
2403 .get
= snd_ac97_ad1986_lososel_get
,
2404 .put
= snd_ac97_ad1986_lososel_put
2407 .iface
= SNDRV_CTL_ELEM_IFACE_MIXER
,
2408 .name
= "Exchange Mic/Line In",
2409 .info
= snd_ac97_ad1986_bool_info
,
2410 .get
= snd_ac97_ad1986_miclisel_get
,
2411 .put
= snd_ac97_ad1986_miclisel_put
2414 .iface
= SNDRV_CTL_ELEM_IFACE_MIXER
,
2415 .name
= "Spread Front to Surround and Center/LFE",
2416 .info
= snd_ac97_ad1986_bool_info
,
2417 .get
= snd_ac97_ad1986_spread_get
,
2418 .put
= snd_ac97_ad1986_spread_put
2421 .iface
= SNDRV_CTL_ELEM_IFACE_MIXER
,
2423 .info
= snd_ac97_ad1888_downmix_info
,
2424 .get
= snd_ac97_ad1888_downmix_get
,
2425 .put
= snd_ac97_ad1888_downmix_put
2428 .iface
= SNDRV_CTL_ELEM_IFACE_MIXER
,
2430 .info
= snd_ac97_ad1985_vrefout_info
,
2431 .get
= snd_ac97_ad1986_vrefout_get
,
2432 .put
= snd_ac97_ad1986_vrefout_put
2434 AC97_SURROUND_JACK_MODE_CTL
,
2435 AC97_CHANNEL_MODE_CTL
,
2437 AC97_SINGLE("Headphone Jack Sense", AC97_AD_JACK_SPDIF
, 10, 1, 0),
2438 AC97_SINGLE("Line Jack Sense", AC97_AD_JACK_SPDIF
, 12, 1, 0)
2441 static void ad1986_update_jacks(struct snd_ac97
*ac97
)
2443 unsigned short misc_val
= 0;
2444 unsigned short ser_val
;
2446 /* disable SURROUND and CENTER/LFE if not surround mode */
2447 if (!is_surround_on(ac97
))
2448 misc_val
|= AC97_AD1986_SODIS
;
2449 if (!is_clfe_on(ac97
))
2450 misc_val
|= AC97_AD1986_CLDIS
;
2452 /* select line input (default=LINE_IN, SURROUND or MIC_1/2) */
2453 if (is_shared_linein(ac97
))
2454 misc_val
|= AC97_AD1986_LISEL_SURR
;
2455 else if (ac97
->spec
.ad18xx
.swap_mic_linein
!= 0)
2456 misc_val
|= AC97_AD1986_LISEL_MIC
;
2457 snd_ac97_update_bits(ac97
, AC97_AD_MISC
,
2458 AC97_AD1986_SODIS
| AC97_AD1986_CLDIS
|
2459 AC97_AD1986_LISEL_MASK
,
2462 /* select microphone input (MIC_1/2, Center/LFE or LINE_IN) */
2463 if (is_shared_micin(ac97
))
2464 ser_val
= AC97_AD1986_OMS_C
;
2465 else if (ac97
->spec
.ad18xx
.swap_mic_linein
!= 0)
2466 ser_val
= AC97_AD1986_OMS_L
;
2468 ser_val
= AC97_AD1986_OMS_M
;
2469 snd_ac97_update_bits(ac97
, AC97_AD_SERIAL_CFG
,
2470 AC97_AD1986_OMS_MASK
,
2474 static int patch_ad1986_specific(struct snd_ac97
*ac97
)
2478 if ((err
= patch_build_controls(ac97
, &snd_ac97_ad198x_2cmic
, 1)) < 0)
2481 return patch_build_controls(ac97
, snd_ac97_ad1986_controls
,
2482 ARRAY_SIZE(snd_ac97_ad1985_controls
));
2485 static const struct snd_ac97_build_ops patch_ad1986_build_ops
= {
2486 .build_post_spdif
= patch_ad198x_post_spdif
,
2487 .build_specific
= patch_ad1986_specific
,
2489 .resume
= ad18xx_resume
,
2491 .update_jacks
= ad1986_update_jacks
,
2494 static int patch_ad1986(struct snd_ac97
* ac97
)
2497 ac97
->build_ops
= &patch_ad1986_build_ops
;
2498 ac97
->flags
|= AC97_STEREO_MUTES
;
2500 /* update current jack configuration */
2501 ad1986_update_jacks(ac97
);
2507 * realtek ALC203: use mono-out for pin 37
2509 static int patch_alc203(struct snd_ac97
*ac97
)
2511 snd_ac97_update_bits(ac97
, 0x7a, 0x400, 0x400);
2516 * realtek ALC65x/850 codecs
2518 static void alc650_update_jacks(struct snd_ac97
*ac97
)
2522 /* shared Line-In / Surround Out */
2523 shared
= is_shared_surrout(ac97
);
2524 snd_ac97_update_bits(ac97
, AC97_ALC650_MULTICH
, 1 << 9,
2525 shared
? (1 << 9) : 0);
2526 /* update shared Mic In / Center/LFE Out */
2527 shared
= is_shared_clfeout(ac97
);
2528 /* disable/enable vref */
2529 snd_ac97_update_bits(ac97
, AC97_ALC650_CLOCK
, 1 << 12,
2530 shared
? (1 << 12) : 0);
2531 /* turn on/off center-on-mic */
2532 snd_ac97_update_bits(ac97
, AC97_ALC650_MULTICH
, 1 << 10,
2533 shared
? (1 << 10) : 0);
2534 /* GPIO0 high for mic */
2535 snd_ac97_update_bits(ac97
, AC97_ALC650_GPIO_STATUS
, 0x100,
2536 shared
? 0 : 0x100);
2539 static int alc650_swap_surround_put(struct snd_kcontrol
*kcontrol
,
2540 struct snd_ctl_elem_value
*ucontrol
)
2542 struct snd_ac97
*ac97
= snd_kcontrol_chip(kcontrol
);
2543 struct snd_pcm_chmap
*map
= ac97
->chmaps
[SNDRV_PCM_STREAM_PLAYBACK
];
2546 if (ucontrol
->value
.integer
.value
[0])
2547 map
->chmap
= snd_pcm_std_chmaps
;
2549 map
->chmap
= snd_pcm_alt_chmaps
;
2551 return snd_ac97_put_volsw(kcontrol
, ucontrol
);
2554 static const struct snd_kcontrol_new snd_ac97_controls_alc650
[] = {
2555 AC97_SINGLE("Duplicate Front", AC97_ALC650_MULTICH
, 0, 1, 0),
2556 AC97_SINGLE("Surround Down Mix", AC97_ALC650_MULTICH
, 1, 1, 0),
2557 AC97_SINGLE("Center/LFE Down Mix", AC97_ALC650_MULTICH
, 2, 1, 0),
2558 AC97_SINGLE("Exchange Center/LFE", AC97_ALC650_MULTICH
, 3, 1, 0),
2559 /* 4: Analog Input To Surround */
2560 /* 5: Analog Input To Center/LFE */
2561 /* 6: Independent Master Volume Right */
2562 /* 7: Independent Master Volume Left */
2564 /* 9: Line-In/Surround share */
2565 /* 10: Mic/CLFE share */
2566 /* 11-13: in IEC958 controls */
2568 .iface
= SNDRV_CTL_ELEM_IFACE_MIXER
,
2569 .name
= "Swap Surround Slot",
2570 .info
= snd_ac97_info_volsw
,
2571 .get
= snd_ac97_get_volsw
,
2572 .put
= alc650_swap_surround_put
,
2573 .private_value
= AC97_SINGLE_VALUE(AC97_ALC650_MULTICH
, 14, 1, 0),
2575 #if 0 /* always set in patch_alc650 */
2576 AC97_SINGLE("IEC958 Input Clock Enable", AC97_ALC650_CLOCK
, 0, 1, 0),
2577 AC97_SINGLE("IEC958 Input Pin Enable", AC97_ALC650_CLOCK
, 1, 1, 0),
2578 AC97_SINGLE("Surround DAC Switch", AC97_ALC650_SURR_DAC_VOL
, 15, 1, 1),
2579 AC97_DOUBLE("Surround DAC Volume", AC97_ALC650_SURR_DAC_VOL
, 8, 0, 31, 1),
2580 AC97_SINGLE("Center/LFE DAC Switch", AC97_ALC650_LFE_DAC_VOL
, 15, 1, 1),
2581 AC97_DOUBLE("Center/LFE DAC Volume", AC97_ALC650_LFE_DAC_VOL
, 8, 0, 31, 1),
2583 AC97_SURROUND_JACK_MODE_CTL
,
2584 AC97_CHANNEL_MODE_CTL
,
2587 static const struct snd_kcontrol_new snd_ac97_spdif_controls_alc650
[] = {
2588 AC97_SINGLE(SNDRV_CTL_NAME_IEC958("",CAPTURE
,SWITCH
), AC97_ALC650_MULTICH
, 11, 1, 0),
2589 AC97_SINGLE("Analog to IEC958 Output", AC97_ALC650_MULTICH
, 12, 1, 0),
2590 /* disable this controls since it doesn't work as expected */
2591 /* AC97_SINGLE("IEC958 Input Monitor", AC97_ALC650_MULTICH, 13, 1, 0), */
2594 static const DECLARE_TLV_DB_SCALE(db_scale_5bit_3db_max
, -4350, 150, 0);
2596 static int patch_alc650_specific(struct snd_ac97
* ac97
)
2600 if ((err
= patch_build_controls(ac97
, snd_ac97_controls_alc650
, ARRAY_SIZE(snd_ac97_controls_alc650
))) < 0)
2602 if (ac97
->ext_id
& AC97_EI_SPDIF
) {
2603 if ((err
= patch_build_controls(ac97
, snd_ac97_spdif_controls_alc650
, ARRAY_SIZE(snd_ac97_spdif_controls_alc650
))) < 0)
2606 if (ac97
->id
!= AC97_ID_ALC650F
)
2607 reset_tlv(ac97
, "Master Playback Volume",
2608 db_scale_5bit_3db_max
);
2612 static const struct snd_ac97_build_ops patch_alc650_ops
= {
2613 .build_specific
= patch_alc650_specific
,
2614 .update_jacks
= alc650_update_jacks
2617 static int patch_alc650(struct snd_ac97
* ac97
)
2621 ac97
->build_ops
= &patch_alc650_ops
;
2623 /* determine the revision */
2624 val
= snd_ac97_read(ac97
, AC97_ALC650_REVISION
) & 0x3f;
2626 ac97
->id
= 0x414c4720; /* Old version */
2627 else if (val
< 0x10)
2628 ac97
->id
= 0x414c4721; /* D version */
2629 else if (val
< 0x20)
2630 ac97
->id
= 0x414c4722; /* E version */
2631 else if (val
< 0x30)
2632 ac97
->id
= 0x414c4723; /* F version */
2634 /* revision E or F */
2635 /* FIXME: what about revision D ? */
2636 ac97
->spec
.dev_flags
= (ac97
->id
== 0x414c4722 ||
2637 ac97
->id
== 0x414c4723);
2639 /* enable AC97_ALC650_GPIO_SETUP, AC97_ALC650_CLOCK for R/W */
2640 snd_ac97_write_cache(ac97
, AC97_ALC650_GPIO_STATUS
,
2641 snd_ac97_read(ac97
, AC97_ALC650_GPIO_STATUS
) | 0x8000);
2643 /* Enable SPDIF-IN only on Rev.E and above */
2644 val
= snd_ac97_read(ac97
, AC97_ALC650_CLOCK
);
2645 /* SPDIF IN with pin 47 */
2646 if (ac97
->spec
.dev_flags
&&
2647 /* ASUS A6KM requires EAPD */
2648 ! (ac97
->subsystem_vendor
== 0x1043 &&
2649 ac97
->subsystem_device
== 0x1103))
2650 val
|= 0x03; /* enable */
2652 val
&= ~0x03; /* disable */
2653 snd_ac97_write_cache(ac97
, AC97_ALC650_CLOCK
, val
);
2655 /* set default: slot 3,4,7,8,6,9
2656 spdif-in monitor off, analog-spdif off, spdif-in off
2657 center on mic off, surround on line-in off
2658 downmix off, duplicate front off
2660 snd_ac97_write_cache(ac97
, AC97_ALC650_MULTICH
, 0);
2662 /* set GPIO0 for mic bias */
2663 /* GPIO0 pin output, no interrupt, high */
2664 snd_ac97_write_cache(ac97
, AC97_ALC650_GPIO_SETUP
,
2665 snd_ac97_read(ac97
, AC97_ALC650_GPIO_SETUP
) | 0x01);
2666 snd_ac97_write_cache(ac97
, AC97_ALC650_GPIO_STATUS
,
2667 (snd_ac97_read(ac97
, AC97_ALC650_GPIO_STATUS
) | 0x100) & ~0x10);
2669 /* full DAC volume */
2670 snd_ac97_write_cache(ac97
, AC97_ALC650_SURR_DAC_VOL
, 0x0808);
2671 snd_ac97_write_cache(ac97
, AC97_ALC650_LFE_DAC_VOL
, 0x0808);
2675 static void alc655_update_jacks(struct snd_ac97
*ac97
)
2679 /* shared Line-In / Surround Out */
2680 shared
= is_shared_surrout(ac97
);
2681 ac97_update_bits_page(ac97
, AC97_ALC650_MULTICH
, 1 << 9,
2682 shared
? (1 << 9) : 0, 0);
2683 /* update shared Mic In / Center/LFE Out */
2684 shared
= is_shared_clfeout(ac97
);
2685 /* misc control; vrefout disable */
2686 snd_ac97_update_bits(ac97
, AC97_ALC650_CLOCK
, 1 << 12,
2687 shared
? (1 << 12) : 0);
2688 ac97_update_bits_page(ac97
, AC97_ALC650_MULTICH
, 1 << 10,
2689 shared
? (1 << 10) : 0, 0);
2692 static const struct snd_kcontrol_new snd_ac97_controls_alc655
[] = {
2693 AC97_PAGE_SINGLE("Duplicate Front", AC97_ALC650_MULTICH
, 0, 1, 0, 0),
2694 AC97_SURROUND_JACK_MODE_CTL
,
2695 AC97_CHANNEL_MODE_CTL
,
2698 static int alc655_iec958_route_info(struct snd_kcontrol
*kcontrol
, struct snd_ctl_elem_info
*uinfo
)
2700 static const char * const texts_655
[3] = {
2701 "PCM", "Analog In", "IEC958 In"
2703 static const char * const texts_658
[4] = {
2704 "PCM", "Analog1 In", "Analog2 In", "IEC958 In"
2706 struct snd_ac97
*ac97
= snd_kcontrol_chip(kcontrol
);
2708 if (ac97
->spec
.dev_flags
)
2709 return snd_ctl_enum_info(uinfo
, 1, 4, texts_658
);
2711 return snd_ctl_enum_info(uinfo
, 1, 3, texts_655
);
2714 static int alc655_iec958_route_get(struct snd_kcontrol
*kcontrol
, struct snd_ctl_elem_value
*ucontrol
)
2716 struct snd_ac97
*ac97
= snd_kcontrol_chip(kcontrol
);
2719 val
= ac97
->regs
[AC97_ALC650_MULTICH
];
2720 val
= (val
>> 12) & 3;
2721 if (ac97
->spec
.dev_flags
&& val
== 3)
2723 ucontrol
->value
.enumerated
.item
[0] = val
;
2727 static int alc655_iec958_route_put(struct snd_kcontrol
*kcontrol
, struct snd_ctl_elem_value
*ucontrol
)
2729 struct snd_ac97
*ac97
= snd_kcontrol_chip(kcontrol
);
2731 return ac97_update_bits_page(ac97
, AC97_ALC650_MULTICH
, 3 << 12,
2732 (unsigned short)ucontrol
->value
.enumerated
.item
[0] << 12,
2736 static const struct snd_kcontrol_new snd_ac97_spdif_controls_alc655
[] = {
2737 AC97_PAGE_SINGLE(SNDRV_CTL_NAME_IEC958("",CAPTURE
,SWITCH
), AC97_ALC650_MULTICH
, 11, 1, 0, 0),
2738 /* disable this controls since it doesn't work as expected */
2739 /* AC97_PAGE_SINGLE("IEC958 Input Monitor", AC97_ALC650_MULTICH, 14, 1, 0, 0), */
2741 .iface
= SNDRV_CTL_ELEM_IFACE_MIXER
,
2742 .name
= SNDRV_CTL_NAME_IEC958("",PLAYBACK
,NONE
) "Source",
2743 .info
= alc655_iec958_route_info
,
2744 .get
= alc655_iec958_route_get
,
2745 .put
= alc655_iec958_route_put
,
2749 static int patch_alc655_specific(struct snd_ac97
* ac97
)
2753 if ((err
= patch_build_controls(ac97
, snd_ac97_controls_alc655
, ARRAY_SIZE(snd_ac97_controls_alc655
))) < 0)
2755 if (ac97
->ext_id
& AC97_EI_SPDIF
) {
2756 if ((err
= patch_build_controls(ac97
, snd_ac97_spdif_controls_alc655
, ARRAY_SIZE(snd_ac97_spdif_controls_alc655
))) < 0)
2762 static const struct snd_ac97_build_ops patch_alc655_ops
= {
2763 .build_specific
= patch_alc655_specific
,
2764 .update_jacks
= alc655_update_jacks
2767 static int patch_alc655(struct snd_ac97
* ac97
)
2771 if (ac97
->id
== AC97_ID_ALC658
) {
2772 ac97
->spec
.dev_flags
= 1; /* ALC658 */
2773 if ((snd_ac97_read(ac97
, AC97_ALC650_REVISION
) & 0x3f) == 2) {
2774 ac97
->id
= AC97_ID_ALC658D
;
2775 ac97
->spec
.dev_flags
= 2;
2779 ac97
->build_ops
= &patch_alc655_ops
;
2781 /* assume only page 0 for writing cache */
2782 snd_ac97_update_bits(ac97
, AC97_INT_PAGING
, AC97_PAGE_MASK
, AC97_PAGE_VENDOR
);
2784 /* adjust default values */
2785 val
= snd_ac97_read(ac97
, 0x7a); /* misc control */
2786 if (ac97
->spec
.dev_flags
) /* ALC658 */
2787 val
&= ~(1 << 1); /* Pin 47 is spdif input pin */
2789 if (ac97
->subsystem_vendor
== 0x1462 &&
2790 (ac97
->subsystem_device
== 0x0131 || /* MSI S270 laptop */
2791 ac97
->subsystem_device
== 0x0161 || /* LG K1 Express */
2792 ac97
->subsystem_device
== 0x0351 || /* MSI L725 laptop */
2793 ac97
->subsystem_device
== 0x0471 || /* MSI L720 laptop */
2794 ac97
->subsystem_device
== 0x0061)) /* MSI S250 laptop */
2795 val
&= ~(1 << 1); /* Pin 47 is EAPD (for internal speaker) */
2797 val
|= (1 << 1); /* Pin 47 is spdif input pin */
2798 /* this seems missing on some hardwares */
2799 ac97
->ext_id
|= AC97_EI_SPDIF
;
2801 val
&= ~(1 << 12); /* vref enable */
2802 snd_ac97_write_cache(ac97
, 0x7a, val
);
2803 /* set default: spdif-in enabled,
2804 spdif-in monitor off, spdif-in PCM off
2805 center on mic off, surround on line-in off
2808 snd_ac97_write_cache(ac97
, AC97_ALC650_MULTICH
, 1<<15);
2810 /* full DAC volume */
2811 snd_ac97_write_cache(ac97
, AC97_ALC650_SURR_DAC_VOL
, 0x0808);
2812 snd_ac97_write_cache(ac97
, AC97_ALC650_LFE_DAC_VOL
, 0x0808);
2814 /* update undocumented bit... */
2815 if (ac97
->id
== AC97_ID_ALC658D
)
2816 snd_ac97_update_bits(ac97
, 0x74, 0x0800, 0x0800);
2822 #define AC97_ALC850_JACK_SELECT 0x76
2823 #define AC97_ALC850_MISC1 0x7a
2824 #define AC97_ALC850_MULTICH 0x6a
2826 static void alc850_update_jacks(struct snd_ac97
*ac97
)
2829 int aux_is_back_surround
;
2831 /* shared Line-In / Surround Out */
2832 shared
= is_shared_surrout(ac97
);
2833 /* SURR 1kOhm (bit4), Amp (bit5) */
2834 snd_ac97_update_bits(ac97
, AC97_ALC850_MISC1
, (1<<4)|(1<<5),
2835 shared
? (1<<5) : (1<<4));
2836 /* LINE-IN = 0, SURROUND = 2 */
2837 snd_ac97_update_bits(ac97
, AC97_ALC850_JACK_SELECT
, 7 << 12,
2838 shared
? (2<<12) : (0<<12));
2839 /* update shared Mic In / Center/LFE Out */
2840 shared
= is_shared_clfeout(ac97
);
2841 /* Vref disable (bit12), 1kOhm (bit13) */
2842 snd_ac97_update_bits(ac97
, AC97_ALC850_MISC1
, (1<<12)|(1<<13),
2843 shared
? (1<<12) : (1<<13));
2844 /* MIC-IN = 1, CENTER-LFE = 5 */
2845 snd_ac97_update_bits(ac97
, AC97_ALC850_JACK_SELECT
, 7 << 4,
2846 shared
? (5<<4) : (1<<4));
2848 aux_is_back_surround
= alc850_is_aux_back_surround(ac97
);
2849 /* Aux is Back Surround */
2850 snd_ac97_update_bits(ac97
, AC97_ALC850_MULTICH
, 1 << 10,
2851 aux_is_back_surround
? (1<<10) : (0<<10));
2854 static const struct snd_kcontrol_new snd_ac97_controls_alc850
[] = {
2855 AC97_PAGE_SINGLE("Duplicate Front", AC97_ALC650_MULTICH
, 0, 1, 0, 0),
2856 AC97_SINGLE("Mic Front Input Switch", AC97_ALC850_JACK_SELECT
, 15, 1, 1),
2857 AC97_SURROUND_JACK_MODE_CTL
,
2858 AC97_CHANNEL_MODE_8CH_CTL
,
2861 static int patch_alc850_specific(struct snd_ac97
*ac97
)
2865 if ((err
= patch_build_controls(ac97
, snd_ac97_controls_alc850
, ARRAY_SIZE(snd_ac97_controls_alc850
))) < 0)
2867 if (ac97
->ext_id
& AC97_EI_SPDIF
) {
2868 if ((err
= patch_build_controls(ac97
, snd_ac97_spdif_controls_alc655
, ARRAY_SIZE(snd_ac97_spdif_controls_alc655
))) < 0)
2874 static const struct snd_ac97_build_ops patch_alc850_ops
= {
2875 .build_specific
= patch_alc850_specific
,
2876 .update_jacks
= alc850_update_jacks
2879 static int patch_alc850(struct snd_ac97
*ac97
)
2881 ac97
->build_ops
= &patch_alc850_ops
;
2883 ac97
->spec
.dev_flags
= 0; /* for IEC958 playback route - ALC655 compatible */
2884 ac97
->flags
|= AC97_HAS_8CH
;
2886 /* assume only page 0 for writing cache */
2887 snd_ac97_update_bits(ac97
, AC97_INT_PAGING
, AC97_PAGE_MASK
, AC97_PAGE_VENDOR
);
2889 /* adjust default values */
2890 /* set default: spdif-in enabled,
2891 spdif-in monitor off, spdif-in PCM off
2892 center on mic off, surround on line-in off
2894 NB default bit 10=0 = Aux is Capture, not Back Surround
2896 snd_ac97_write_cache(ac97
, AC97_ALC650_MULTICH
, 1<<15);
2897 /* SURR_OUT: on, Surr 1kOhm: on, Surr Amp: off, Front 1kOhm: off
2898 * Front Amp: on, Vref: enable, Center 1kOhm: on, Mix: on
2900 snd_ac97_write_cache(ac97
, 0x7a, (1<<1)|(1<<4)|(0<<5)|(1<<6)|
2901 (1<<7)|(0<<12)|(1<<13)|(0<<14));
2902 /* detection UIO2,3: all path floating, UIO3: MIC, Vref2: disable,
2903 * UIO1: FRONT, Vref3: disable, UIO3: LINE, Front-Mic: mute
2905 snd_ac97_write_cache(ac97
, 0x76, (0<<0)|(0<<2)|(1<<4)|(1<<7)|(2<<8)|
2906 (1<<11)|(0<<12)|(1<<15));
2908 /* full DAC volume */
2909 snd_ac97_write_cache(ac97
, AC97_ALC650_SURR_DAC_VOL
, 0x0808);
2910 snd_ac97_write_cache(ac97
, AC97_ALC650_LFE_DAC_VOL
, 0x0808);
2914 static int patch_aztech_azf3328_specific(struct snd_ac97
*ac97
)
2916 struct snd_kcontrol
*kctl_3d_center
=
2917 snd_ac97_find_mixer_ctl(ac97
, "3D Control - Center");
2918 struct snd_kcontrol
*kctl_3d_depth
=
2919 snd_ac97_find_mixer_ctl(ac97
, "3D Control - Depth");
2922 * 3D register is different from AC97 standard layout
2923 * (also do some renaming, to resemble Windows driver naming)
2925 if (kctl_3d_center
) {
2926 kctl_3d_center
->private_value
=
2927 AC97_SINGLE_VALUE(AC97_3D_CONTROL
, 1, 0x07, 0);
2928 snd_ac97_rename_vol_ctl(ac97
,
2929 "3D Control - Center", "3D Control - Width"
2933 kctl_3d_depth
->private_value
=
2934 AC97_SINGLE_VALUE(AC97_3D_CONTROL
, 8, 0x03, 0);
2936 /* Aztech Windows driver calls the
2937 equivalent control "Modem Playback", thus rename it: */
2938 snd_ac97_rename_vol_ctl(ac97
,
2939 "Master Mono Playback", "Modem Playback"
2941 snd_ac97_rename_vol_ctl(ac97
,
2942 "Headphone Playback", "FM Synth Playback"
2948 static const struct snd_ac97_build_ops patch_aztech_azf3328_ops
= {
2949 .build_specific
= patch_aztech_azf3328_specific
2952 static int patch_aztech_azf3328(struct snd_ac97
*ac97
)
2954 ac97
->build_ops
= &patch_aztech_azf3328_ops
;
2959 * C-Media CM97xx codecs
2961 static void cm9738_update_jacks(struct snd_ac97
*ac97
)
2963 /* shared Line-In / Surround Out */
2964 snd_ac97_update_bits(ac97
, AC97_CM9738_VENDOR_CTRL
, 1 << 10,
2965 is_shared_surrout(ac97
) ? (1 << 10) : 0);
2968 static const struct snd_kcontrol_new snd_ac97_cm9738_controls
[] = {
2969 AC97_SINGLE("Duplicate Front", AC97_CM9738_VENDOR_CTRL
, 13, 1, 0),
2970 AC97_SURROUND_JACK_MODE_CTL
,
2971 AC97_CHANNEL_MODE_4CH_CTL
,
2974 static int patch_cm9738_specific(struct snd_ac97
* ac97
)
2976 return patch_build_controls(ac97
, snd_ac97_cm9738_controls
, ARRAY_SIZE(snd_ac97_cm9738_controls
));
2979 static const struct snd_ac97_build_ops patch_cm9738_ops
= {
2980 .build_specific
= patch_cm9738_specific
,
2981 .update_jacks
= cm9738_update_jacks
2984 static int patch_cm9738(struct snd_ac97
* ac97
)
2986 ac97
->build_ops
= &patch_cm9738_ops
;
2987 /* FIXME: can anyone confirm below? */
2988 /* CM9738 has no PCM volume although the register reacts */
2989 ac97
->flags
|= AC97_HAS_NO_PCM_VOL
;
2990 snd_ac97_write_cache(ac97
, AC97_PCM
, 0x8000);
2995 static int snd_ac97_cmedia_spdif_playback_source_info(struct snd_kcontrol
*kcontrol
, struct snd_ctl_elem_info
*uinfo
)
2997 static const char * const texts
[] = { "Analog", "Digital" };
2999 return snd_ctl_enum_info(uinfo
, 1, 2, texts
);
3002 static int snd_ac97_cmedia_spdif_playback_source_get(struct snd_kcontrol
*kcontrol
, struct snd_ctl_elem_value
*ucontrol
)
3004 struct snd_ac97
*ac97
= snd_kcontrol_chip(kcontrol
);
3007 val
= ac97
->regs
[AC97_CM9739_SPDIF_CTRL
];
3008 ucontrol
->value
.enumerated
.item
[0] = (val
>> 1) & 0x01;
3012 static int snd_ac97_cmedia_spdif_playback_source_put(struct snd_kcontrol
*kcontrol
, struct snd_ctl_elem_value
*ucontrol
)
3014 struct snd_ac97
*ac97
= snd_kcontrol_chip(kcontrol
);
3016 return snd_ac97_update_bits(ac97
, AC97_CM9739_SPDIF_CTRL
,
3018 (ucontrol
->value
.enumerated
.item
[0] & 0x01) << 1);
3021 static const struct snd_kcontrol_new snd_ac97_cm9739_controls_spdif
[] = {
3022 /* BIT 0: SPDI_EN - always true */
3023 { /* BIT 1: SPDIFS */
3024 .iface
= SNDRV_CTL_ELEM_IFACE_MIXER
,
3025 .name
= SNDRV_CTL_NAME_IEC958("",PLAYBACK
,NONE
) "Source",
3026 .info
= snd_ac97_cmedia_spdif_playback_source_info
,
3027 .get
= snd_ac97_cmedia_spdif_playback_source_get
,
3028 .put
= snd_ac97_cmedia_spdif_playback_source_put
,
3030 /* BIT 2: IG_SPIV */
3031 AC97_SINGLE(SNDRV_CTL_NAME_IEC958("",CAPTURE
,NONE
) "Valid Switch", AC97_CM9739_SPDIF_CTRL
, 2, 1, 0),
3033 AC97_SINGLE(SNDRV_CTL_NAME_IEC958("",CAPTURE
,NONE
) "Monitor", AC97_CM9739_SPDIF_CTRL
, 3, 1, 0),
3034 /* BIT 4: SPI2SDI */
3035 AC97_SINGLE(SNDRV_CTL_NAME_IEC958("",CAPTURE
,SWITCH
), AC97_CM9739_SPDIF_CTRL
, 4, 1, 0),
3036 /* BIT 8: SPD32 - 32bit SPDIF - not supported yet */
3039 static void cm9739_update_jacks(struct snd_ac97
*ac97
)
3041 /* shared Line-In / Surround Out */
3042 snd_ac97_update_bits(ac97
, AC97_CM9739_MULTI_CHAN
, 1 << 10,
3043 is_shared_surrout(ac97
) ? (1 << 10) : 0);
3044 /* shared Mic In / Center/LFE Out **/
3045 snd_ac97_update_bits(ac97
, AC97_CM9739_MULTI_CHAN
, 0x3000,
3046 is_shared_clfeout(ac97
) ? 0x1000 : 0x2000);
3049 static const struct snd_kcontrol_new snd_ac97_cm9739_controls
[] = {
3050 AC97_SURROUND_JACK_MODE_CTL
,
3051 AC97_CHANNEL_MODE_CTL
,
3054 static int patch_cm9739_specific(struct snd_ac97
* ac97
)
3056 return patch_build_controls(ac97
, snd_ac97_cm9739_controls
, ARRAY_SIZE(snd_ac97_cm9739_controls
));
3059 static int patch_cm9739_post_spdif(struct snd_ac97
* ac97
)
3061 return patch_build_controls(ac97
, snd_ac97_cm9739_controls_spdif
, ARRAY_SIZE(snd_ac97_cm9739_controls_spdif
));
3064 static const struct snd_ac97_build_ops patch_cm9739_ops
= {
3065 .build_specific
= patch_cm9739_specific
,
3066 .build_post_spdif
= patch_cm9739_post_spdif
,
3067 .update_jacks
= cm9739_update_jacks
3070 static int patch_cm9739(struct snd_ac97
* ac97
)
3074 ac97
->build_ops
= &patch_cm9739_ops
;
3076 /* CM9739/A has no Master and PCM volume although the register reacts */
3077 ac97
->flags
|= AC97_HAS_NO_MASTER_VOL
| AC97_HAS_NO_PCM_VOL
;
3078 snd_ac97_write_cache(ac97
, AC97_MASTER
, 0x8000);
3079 snd_ac97_write_cache(ac97
, AC97_PCM
, 0x8000);
3082 val
= snd_ac97_read(ac97
, AC97_EXTENDED_STATUS
);
3083 if (val
& AC97_EA_SPCV
) {
3084 /* enable spdif in */
3085 snd_ac97_write_cache(ac97
, AC97_CM9739_SPDIF_CTRL
,
3086 snd_ac97_read(ac97
, AC97_CM9739_SPDIF_CTRL
) | 0x01);
3087 ac97
->rates
[AC97_RATES_SPDIF
] = SNDRV_PCM_RATE_48000
; /* 48k only */
3089 ac97
->ext_id
&= ~AC97_EI_SPDIF
; /* disable extended-id */
3090 ac97
->rates
[AC97_RATES_SPDIF
] = 0;
3093 /* set-up multi channel */
3094 /* bit 14: 0 = SPDIF, 1 = EAPD */
3095 /* bit 13: enable internal vref output for mic */
3096 /* bit 12: disable center/lfe (swithable) */
3097 /* bit 10: disable surround/line (switchable) */
3098 /* bit 9: mix 2 surround off */
3099 /* bit 4: undocumented; 0 mutes the CM9739A, which defaults to 1 */
3100 /* bit 3: undocumented; surround? */
3102 val
= snd_ac97_read(ac97
, AC97_CM9739_MULTI_CHAN
) & (1 << 4);
3105 if (! (ac97
->ext_id
& AC97_EI_SPDIF
))
3107 snd_ac97_write_cache(ac97
, AC97_CM9739_MULTI_CHAN
, val
);
3109 /* FIXME: set up GPIO */
3110 snd_ac97_write_cache(ac97
, 0x70, 0x0100);
3111 snd_ac97_write_cache(ac97
, 0x72, 0x0020);
3112 /* Special exception for ASUS W1000/CMI9739. It does not have an SPDIF in. */
3114 ac97
->subsystem_vendor
== 0x1043 &&
3115 ac97
->subsystem_device
== 0x1843) {
3116 snd_ac97_write_cache(ac97
, AC97_CM9739_SPDIF_CTRL
,
3117 snd_ac97_read(ac97
, AC97_CM9739_SPDIF_CTRL
) & ~0x01);
3118 snd_ac97_write_cache(ac97
, AC97_CM9739_MULTI_CHAN
,
3119 snd_ac97_read(ac97
, AC97_CM9739_MULTI_CHAN
) | (1 << 14));
3125 #define AC97_CM9761_MULTI_CHAN 0x64
3126 #define AC97_CM9761_FUNC 0x66
3127 #define AC97_CM9761_SPDIF_CTRL 0x6c
3129 static void cm9761_update_jacks(struct snd_ac97
*ac97
)
3131 /* FIXME: check the bits for each model
3132 * model 83 is confirmed to work
3134 static unsigned short surr_on
[3][2] = {
3135 { 0x0008, 0x0000 }, /* 9761-78 & 82 */
3136 { 0x0000, 0x0008 }, /* 9761-82 rev.B */
3137 { 0x0000, 0x0008 }, /* 9761-83 */
3139 static unsigned short clfe_on
[3][2] = {
3140 { 0x0000, 0x1000 }, /* 9761-78 & 82 */
3141 { 0x1000, 0x0000 }, /* 9761-82 rev.B */
3142 { 0x0000, 0x1000 }, /* 9761-83 */
3144 static unsigned short surr_shared
[3][2] = {
3145 { 0x0000, 0x0400 }, /* 9761-78 & 82 */
3146 { 0x0000, 0x0400 }, /* 9761-82 rev.B */
3147 { 0x0000, 0x0400 }, /* 9761-83 */
3149 static unsigned short clfe_shared
[3][2] = {
3150 { 0x2000, 0x0880 }, /* 9761-78 & 82 */
3151 { 0x0000, 0x2880 }, /* 9761-82 rev.B */
3152 { 0x2000, 0x0800 }, /* 9761-83 */
3154 unsigned short val
= 0;
3156 val
|= surr_on
[ac97
->spec
.dev_flags
][is_surround_on(ac97
)];
3157 val
|= clfe_on
[ac97
->spec
.dev_flags
][is_clfe_on(ac97
)];
3158 val
|= surr_shared
[ac97
->spec
.dev_flags
][is_shared_surrout(ac97
)];
3159 val
|= clfe_shared
[ac97
->spec
.dev_flags
][is_shared_clfeout(ac97
)];
3161 snd_ac97_update_bits(ac97
, AC97_CM9761_MULTI_CHAN
, 0x3c88, val
);
3164 static const struct snd_kcontrol_new snd_ac97_cm9761_controls
[] = {
3165 AC97_SURROUND_JACK_MODE_CTL
,
3166 AC97_CHANNEL_MODE_CTL
,
3169 static int cm9761_spdif_out_source_info(struct snd_kcontrol
*kcontrol
, struct snd_ctl_elem_info
*uinfo
)
3171 static const char * const texts
[] = { "AC-Link", "ADC", "SPDIF-In" };
3173 return snd_ctl_enum_info(uinfo
, 1, 3, texts
);
3176 static int cm9761_spdif_out_source_get(struct snd_kcontrol
*kcontrol
, struct snd_ctl_elem_value
*ucontrol
)
3178 struct snd_ac97
*ac97
= snd_kcontrol_chip(kcontrol
);
3180 if (ac97
->regs
[AC97_CM9761_FUNC
] & 0x1)
3181 ucontrol
->value
.enumerated
.item
[0] = 2; /* SPDIF-loopback */
3182 else if (ac97
->regs
[AC97_CM9761_SPDIF_CTRL
] & 0x2)
3183 ucontrol
->value
.enumerated
.item
[0] = 1; /* ADC loopback */
3185 ucontrol
->value
.enumerated
.item
[0] = 0; /* AC-link */
3189 static int cm9761_spdif_out_source_put(struct snd_kcontrol
*kcontrol
, struct snd_ctl_elem_value
*ucontrol
)
3191 struct snd_ac97
*ac97
= snd_kcontrol_chip(kcontrol
);
3193 if (ucontrol
->value
.enumerated
.item
[0] == 2)
3194 return snd_ac97_update_bits(ac97
, AC97_CM9761_FUNC
, 0x1, 0x1);
3195 snd_ac97_update_bits(ac97
, AC97_CM9761_FUNC
, 0x1, 0);
3196 return snd_ac97_update_bits(ac97
, AC97_CM9761_SPDIF_CTRL
, 0x2,
3197 ucontrol
->value
.enumerated
.item
[0] == 1 ? 0x2 : 0);
3200 static const char * const cm9761_dac_clock
[] = {
3201 "AC-Link", "SPDIF-In", "Both"
3203 static const struct ac97_enum cm9761_dac_clock_enum
=
3204 AC97_ENUM_SINGLE(AC97_CM9761_SPDIF_CTRL
, 9, 3, cm9761_dac_clock
);
3206 static const struct snd_kcontrol_new snd_ac97_cm9761_controls_spdif
[] = {
3207 { /* BIT 1: SPDIFS */
3208 .iface
= SNDRV_CTL_ELEM_IFACE_MIXER
,
3209 .name
= SNDRV_CTL_NAME_IEC958("",PLAYBACK
,NONE
) "Source",
3210 .info
= cm9761_spdif_out_source_info
,
3211 .get
= cm9761_spdif_out_source_get
,
3212 .put
= cm9761_spdif_out_source_put
,
3214 /* BIT 2: IG_SPIV */
3215 AC97_SINGLE(SNDRV_CTL_NAME_IEC958("",CAPTURE
,NONE
) "Valid Switch", AC97_CM9761_SPDIF_CTRL
, 2, 1, 0),
3217 AC97_SINGLE(SNDRV_CTL_NAME_IEC958("",CAPTURE
,NONE
) "Monitor", AC97_CM9761_SPDIF_CTRL
, 3, 1, 0),
3218 /* BIT 4: SPI2SDI */
3219 AC97_SINGLE(SNDRV_CTL_NAME_IEC958("",CAPTURE
,SWITCH
), AC97_CM9761_SPDIF_CTRL
, 4, 1, 0),
3220 /* BIT 9-10: DAC_CTL */
3221 AC97_ENUM("DAC Clock Source", cm9761_dac_clock_enum
),
3224 static int patch_cm9761_post_spdif(struct snd_ac97
* ac97
)
3226 return patch_build_controls(ac97
, snd_ac97_cm9761_controls_spdif
, ARRAY_SIZE(snd_ac97_cm9761_controls_spdif
));
3229 static int patch_cm9761_specific(struct snd_ac97
* ac97
)
3231 return patch_build_controls(ac97
, snd_ac97_cm9761_controls
, ARRAY_SIZE(snd_ac97_cm9761_controls
));
3234 static const struct snd_ac97_build_ops patch_cm9761_ops
= {
3235 .build_specific
= patch_cm9761_specific
,
3236 .build_post_spdif
= patch_cm9761_post_spdif
,
3237 .update_jacks
= cm9761_update_jacks
3240 static int patch_cm9761(struct snd_ac97
*ac97
)
3244 /* CM9761 has no PCM volume although the register reacts */
3245 /* Master volume seems to have _some_ influence on the analog
3248 ac97
->flags
|= /*AC97_HAS_NO_MASTER_VOL |*/ AC97_HAS_NO_PCM_VOL
;
3249 snd_ac97_write_cache(ac97
, AC97_MASTER
, 0x8808);
3250 snd_ac97_write_cache(ac97
, AC97_PCM
, 0x8808);
3252 ac97
->spec
.dev_flags
= 0; /* 1 = model 82 revision B, 2 = model 83 */
3253 if (ac97
->id
== AC97_ID_CM9761_82
) {
3255 /* check page 1, reg 0x60 */
3256 val
= snd_ac97_read(ac97
, AC97_INT_PAGING
);
3257 snd_ac97_write_cache(ac97
, AC97_INT_PAGING
, (val
& ~0x0f) | 0x01);
3258 tmp
= snd_ac97_read(ac97
, 0x60);
3259 ac97
->spec
.dev_flags
= tmp
& 1; /* revision B? */
3260 snd_ac97_write_cache(ac97
, AC97_INT_PAGING
, val
);
3261 } else if (ac97
->id
== AC97_ID_CM9761_83
)
3262 ac97
->spec
.dev_flags
= 2;
3264 ac97
->build_ops
= &patch_cm9761_ops
;
3267 /* force the SPDIF bit in ext_id - codec doesn't set this bit! */
3268 ac97
->ext_id
|= AC97_EI_SPDIF
;
3269 /* to be sure: we overwrite the ext status bits */
3270 snd_ac97_write_cache(ac97
, AC97_EXTENDED_STATUS
, 0x05c0);
3271 /* Don't set 0x0200 here. This results in the silent analog output */
3272 snd_ac97_write_cache(ac97
, AC97_CM9761_SPDIF_CTRL
, 0x0001); /* enable spdif-in */
3273 ac97
->rates
[AC97_RATES_SPDIF
] = SNDRV_PCM_RATE_48000
; /* 48k only */
3275 /* set-up multi channel */
3276 /* bit 15: pc master beep off
3277 * bit 14: pin47 = EAPD/SPDIF
3278 * bit 13: vref ctl [= cm9739]
3279 * bit 12: CLFE control (reverted on rev B)
3280 * bit 11: Mic/center share (reverted on rev B)
3281 * bit 10: suddound/line share
3282 * bit 9: Analog-in mix -> surround
3283 * bit 8: Analog-in mix -> CLFE
3284 * bit 7: Mic/LFE share (mic/center/lfe)
3285 * bit 5: vref select (9761A)
3286 * bit 4: front control
3287 * bit 3: surround control (revereted with rev B)
3290 * bit 0: mic boost level (0=20dB, 1=30dB)
3294 if (ac97
->spec
.dev_flags
)
3299 val
= snd_ac97_read(ac97
, AC97_CM9761_MULTI_CHAN
);
3300 val
|= (1 << 4); /* front on */
3301 snd_ac97_write_cache(ac97
, AC97_CM9761_MULTI_CHAN
, val
);
3303 /* FIXME: set up GPIO */
3304 snd_ac97_write_cache(ac97
, 0x70, 0x0100);
3305 snd_ac97_write_cache(ac97
, 0x72, 0x0020);
3310 #define AC97_CM9780_SIDE 0x60
3311 #define AC97_CM9780_JACK 0x62
3312 #define AC97_CM9780_MIXER 0x64
3313 #define AC97_CM9780_MULTI_CHAN 0x66
3314 #define AC97_CM9780_SPDIF 0x6c
3316 static const char * const cm9780_ch_select
[] = {
3317 "Front", "Side", "Center/LFE", "Rear"
3319 static const struct ac97_enum cm9780_ch_select_enum
=
3320 AC97_ENUM_SINGLE(AC97_CM9780_MULTI_CHAN
, 6, 4, cm9780_ch_select
);
3321 static const struct snd_kcontrol_new cm9780_controls
[] = {
3322 AC97_DOUBLE("Side Playback Switch", AC97_CM9780_SIDE
, 15, 7, 1, 1),
3323 AC97_DOUBLE("Side Playback Volume", AC97_CM9780_SIDE
, 8, 0, 31, 0),
3324 AC97_ENUM("Side Playback Route", cm9780_ch_select_enum
),
3327 static int patch_cm9780_specific(struct snd_ac97
*ac97
)
3329 return patch_build_controls(ac97
, cm9780_controls
, ARRAY_SIZE(cm9780_controls
));
3332 static const struct snd_ac97_build_ops patch_cm9780_ops
= {
3333 .build_specific
= patch_cm9780_specific
,
3334 .build_post_spdif
= patch_cm9761_post_spdif
/* identical with CM9761 */
3337 static int patch_cm9780(struct snd_ac97
*ac97
)
3341 ac97
->build_ops
= &patch_cm9780_ops
;
3344 if (ac97
->ext_id
& AC97_EI_SPDIF
) {
3345 ac97
->rates
[AC97_RATES_SPDIF
] = SNDRV_PCM_RATE_48000
; /* 48k only */
3346 val
= snd_ac97_read(ac97
, AC97_CM9780_SPDIF
);
3347 val
|= 0x1; /* SPDI_EN */
3348 snd_ac97_write_cache(ac97
, AC97_CM9780_SPDIF
, val
);
3357 static const struct snd_kcontrol_new snd_ac97_controls_vt1613
[] = {
3358 AC97_SINGLE("DC Offset removal", 0x5a, 10, 1, 0),
3361 static int patch_vt1613_specific(struct snd_ac97
*ac97
)
3363 return patch_build_controls(ac97
, &snd_ac97_controls_vt1613
[0],
3364 ARRAY_SIZE(snd_ac97_controls_vt1613
));
3367 static const struct snd_ac97_build_ops patch_vt1613_ops
= {
3368 .build_specific
= patch_vt1613_specific
3371 static int patch_vt1613(struct snd_ac97
*ac97
)
3373 ac97
->build_ops
= &patch_vt1613_ops
;
3375 ac97
->flags
|= AC97_HAS_NO_VIDEO
;
3376 ac97
->caps
|= AC97_BC_HEADPHONE
;
3384 static const struct snd_kcontrol_new snd_ac97_controls_vt1616
[] = {
3385 AC97_SINGLE("DC Offset removal", 0x5a, 10, 1, 0),
3386 AC97_SINGLE("Alternate Level to Surround Out", 0x5a, 15, 1, 0),
3387 AC97_SINGLE("Downmix LFE and Center to Front", 0x5a, 12, 1, 0),
3388 AC97_SINGLE("Downmix Surround to Front", 0x5a, 11, 1, 0),
3391 static const char * const slave_vols_vt1616
[] = {
3392 "Front Playback Volume",
3393 "Surround Playback Volume",
3394 "Center Playback Volume",
3395 "LFE Playback Volume",
3399 static const char * const slave_sws_vt1616
[] = {
3400 "Front Playback Switch",
3401 "Surround Playback Switch",
3402 "Center Playback Switch",
3403 "LFE Playback Switch",
3407 /* find a mixer control element with the given name */
3408 static struct snd_kcontrol
*snd_ac97_find_mixer_ctl(struct snd_ac97
*ac97
,
3411 struct snd_ctl_elem_id id
;
3412 memset(&id
, 0, sizeof(id
));
3413 id
.iface
= SNDRV_CTL_ELEM_IFACE_MIXER
;
3414 strcpy(id
.name
, name
);
3415 return snd_ctl_find_id(ac97
->bus
->card
, &id
);
3418 /* create a virtual master control and add slaves */
3419 static int snd_ac97_add_vmaster(struct snd_ac97
*ac97
, char *name
,
3420 const unsigned int *tlv
,
3421 const char * const *slaves
)
3423 struct snd_kcontrol
*kctl
;
3424 const char * const *s
;
3427 kctl
= snd_ctl_make_virtual_master(name
, tlv
);
3430 err
= snd_ctl_add(ac97
->bus
->card
, kctl
);
3434 for (s
= slaves
; *s
; s
++) {
3435 struct snd_kcontrol
*sctl
;
3437 sctl
= snd_ac97_find_mixer_ctl(ac97
, *s
);
3439 dev_dbg(ac97
->bus
->card
->dev
,
3440 "Cannot find slave %s, skipped\n", *s
);
3443 err
= snd_ctl_add_slave(kctl
, sctl
);
3450 static int patch_vt1616_specific(struct snd_ac97
* ac97
)
3452 struct snd_kcontrol
*kctl
;
3455 if (snd_ac97_try_bit(ac97
, 0x5a, 9))
3456 if ((err
= patch_build_controls(ac97
, &snd_ac97_controls_vt1616
[0], 1)) < 0)
3458 if ((err
= patch_build_controls(ac97
, &snd_ac97_controls_vt1616
[1], ARRAY_SIZE(snd_ac97_controls_vt1616
) - 1)) < 0)
3461 /* There is already a misnamed master switch. Rename it. */
3462 kctl
= snd_ac97_find_mixer_ctl(ac97
, "Master Playback Volume");
3466 snd_ac97_rename_vol_ctl(ac97
, "Master Playback", "Front Playback");
3468 err
= snd_ac97_add_vmaster(ac97
, "Master Playback Volume",
3469 kctl
->tlv
.p
, slave_vols_vt1616
);
3473 err
= snd_ac97_add_vmaster(ac97
, "Master Playback Switch",
3474 NULL
, slave_sws_vt1616
);
3481 static const struct snd_ac97_build_ops patch_vt1616_ops
= {
3482 .build_specific
= patch_vt1616_specific
3485 static int patch_vt1616(struct snd_ac97
* ac97
)
3487 ac97
->build_ops
= &patch_vt1616_ops
;
3496 * unfortunately, the vt1617a stashes the twiddlers required for
3497 * noodling the i/o jacks on 2 different regs. that means that we can't
3498 * use the easy way provided by AC97_ENUM_DOUBLE() we have to write
3501 * NB: this is absolutely and utterly different from the vt1618. dunno
3505 /* copied from ac97_surround_jack_mode_info() */
3506 static int snd_ac97_vt1617a_smart51_info(struct snd_kcontrol
*kcontrol
,
3507 struct snd_ctl_elem_info
*uinfo
)
3509 /* ordering in this list reflects vt1617a docs for Reg 20 and
3510 * 7a and Table 6 that lays out the matrix NB WRT Table6: SM51
3511 * is SM51EN *AND* it's Bit14, not Bit15 so the table is very
3512 * counter-intuitive */
3514 static const char * const texts
[] = {"LineIn Mic1", "LineIn Mic1 Mic3",
3515 "Surr LFE/C Mic3", "LineIn LFE/C Mic3",
3516 "LineIn Mic2", "LineIn Mic2 Mic1",
3517 "Surr LFE Mic1", "Surr LFE Mic1 Mic2"};
3519 return snd_ctl_enum_info(uinfo
, 1, 8, texts
);
3522 static int snd_ac97_vt1617a_smart51_get(struct snd_kcontrol
*kcontrol
,
3523 struct snd_ctl_elem_value
*ucontrol
)
3525 ushort usSM51
, usMS
;
3527 struct snd_ac97
*pac97
;
3529 pac97
= snd_kcontrol_chip(kcontrol
); /* grab codec handle */
3531 /* grab our desired bits, then mash them together in a manner
3532 * consistent with Table 6 on page 17 in the 1617a docs */
3534 usSM51
= snd_ac97_read(pac97
, 0x7a) >> 14;
3535 usMS
= snd_ac97_read(pac97
, 0x20) >> 8;
3537 ucontrol
->value
.enumerated
.item
[0] = (usSM51
<< 1) + usMS
;
3542 static int snd_ac97_vt1617a_smart51_put(struct snd_kcontrol
*kcontrol
,
3543 struct snd_ctl_elem_value
*ucontrol
)
3545 ushort usSM51
, usMS
, usReg
;
3547 struct snd_ac97
*pac97
;
3549 pac97
= snd_kcontrol_chip(kcontrol
); /* grab codec handle */
3551 usSM51
= ucontrol
->value
.enumerated
.item
[0] >> 1;
3552 usMS
= ucontrol
->value
.enumerated
.item
[0] & 1;
3554 /* push our values into the register - consider that things will be left
3555 * in a funky state if the write fails */
3557 usReg
= snd_ac97_read(pac97
, 0x7a);
3558 snd_ac97_write_cache(pac97
, 0x7a, (usReg
& 0x3FFF) + (usSM51
<< 14));
3559 usReg
= snd_ac97_read(pac97
, 0x20);
3560 snd_ac97_write_cache(pac97
, 0x20, (usReg
& 0xFEFF) + (usMS
<< 8));
3565 static const struct snd_kcontrol_new snd_ac97_controls_vt1617a
[] = {
3567 AC97_SINGLE("Center/LFE Exchange", 0x5a, 8, 1, 0),
3569 * These are used to enable/disable surround sound on motherboards
3570 * that have 3 bidirectional analog jacks
3573 .iface
= SNDRV_CTL_ELEM_IFACE_MIXER
,
3574 .name
= "Smart 5.1 Select",
3575 .info
= snd_ac97_vt1617a_smart51_info
,
3576 .get
= snd_ac97_vt1617a_smart51_get
,
3577 .put
= snd_ac97_vt1617a_smart51_put
,
3581 static int patch_vt1617a(struct snd_ac97
* ac97
)
3586 /* we choose to not fail out at this point, but we tell the
3587 caller when we return */
3589 err
= patch_build_controls(ac97
, &snd_ac97_controls_vt1617a
[0],
3590 ARRAY_SIZE(snd_ac97_controls_vt1617a
));
3592 /* bring analog power consumption to normal by turning off the
3593 * headphone amplifier, like WinXP driver for EPIA SP
3595 /* We need to check the bit before writing it.
3596 * On some (many?) hardwares, setting bit actually clears it!
3598 val
= snd_ac97_read(ac97
, 0x5c);
3600 snd_ac97_write_cache(ac97
, 0x5c, 0x20);
3602 ac97
->ext_id
|= AC97_EI_SPDIF
; /* force the detection of spdif */
3603 ac97
->rates
[AC97_RATES_SPDIF
] = SNDRV_PCM_RATE_44100
| SNDRV_PCM_RATE_48000
;
3604 ac97
->build_ops
= &patch_vt1616_ops
;
3609 /* VIA VT1618 8 CHANNEL AC97 CODEC
3611 * VIA implements 'Smart 5.1' completely differently on the 1618 than
3612 * it does on the 1617a. awesome! They seem to have sourced this
3613 * particular revision of the technology from somebody else, it's
3614 * called Universal Audio Jack and it shows up on some other folk's chips
3617 * ordering in this list reflects vt1618 docs for Reg 60h and
3618 * the block diagram, DACs are as follows:
3621 * OUT_1 -> Surround,
3624 * Unlike the 1617a, each OUT has a consistent set of mappings
3625 * for all bitpatterns other than 00:
3631 * Special Case of 00:
3633 * OUT_0 Mixed Output
3637 * I have no idea what the hell Reserved does, but on an MSI
3638 * CN700T, i have to set it to get 5.1 output - YMMV, bad
3641 * If other chips use Universal Audio Jack, then this code might be applicable
3645 struct vt1618_uaj_item
{
3646 unsigned short mask
;
3647 unsigned short shift
;
3648 const char * const items
[4];
3651 /* This list reflects the vt1618 docs for Vendor Defined Register 0x60. */
3653 static struct vt1618_uaj_item vt1618_uaj
[3] = {
3659 "Speaker Out", "DAC Unmixed Out", "Line In", "Mic In"
3667 "Surround Out", "DAC Unmixed Out", "Line In", "Mic In"
3675 "Center LFE Out", "DAC Unmixed Out", "Line In", "Mic In"
3680 static int snd_ac97_vt1618_UAJ_info(struct snd_kcontrol
*kcontrol
,
3681 struct snd_ctl_elem_info
*uinfo
)
3683 return snd_ctl_enum_info(uinfo
, 1, 4,
3684 vt1618_uaj
[kcontrol
->private_value
].items
);
3687 /* All of the vt1618 Universal Audio Jack twiddlers are on
3688 * Vendor Defined Register 0x60, page 0. The bits, and thus
3689 * the mask, are the only thing that changes
3691 static int snd_ac97_vt1618_UAJ_get(struct snd_kcontrol
*kcontrol
,
3692 struct snd_ctl_elem_value
*ucontrol
)
3694 unsigned short datpag
, uaj
;
3695 struct snd_ac97
*pac97
= snd_kcontrol_chip(kcontrol
);
3697 mutex_lock(&pac97
->page_mutex
);
3699 datpag
= snd_ac97_read(pac97
, AC97_INT_PAGING
) & AC97_PAGE_MASK
;
3700 snd_ac97_update_bits(pac97
, AC97_INT_PAGING
, AC97_PAGE_MASK
, 0);
3702 uaj
= snd_ac97_read(pac97
, 0x60) &
3703 vt1618_uaj
[kcontrol
->private_value
].mask
;
3705 snd_ac97_update_bits(pac97
, AC97_INT_PAGING
, AC97_PAGE_MASK
, datpag
);
3706 mutex_unlock(&pac97
->page_mutex
);
3708 ucontrol
->value
.enumerated
.item
[0] = uaj
>>
3709 vt1618_uaj
[kcontrol
->private_value
].shift
;
3714 static int snd_ac97_vt1618_UAJ_put(struct snd_kcontrol
*kcontrol
,
3715 struct snd_ctl_elem_value
*ucontrol
)
3717 return ac97_update_bits_page(snd_kcontrol_chip(kcontrol
), 0x60,
3718 vt1618_uaj
[kcontrol
->private_value
].mask
,
3719 ucontrol
->value
.enumerated
.item
[0]<<
3720 vt1618_uaj
[kcontrol
->private_value
].shift
,
3724 /* config aux in jack - not found on 3 jack motherboards or soundcards */
3726 static int snd_ac97_vt1618_aux_info(struct snd_kcontrol
*kcontrol
,
3727 struct snd_ctl_elem_info
*uinfo
)
3729 static const char * const txt_aux
[] = {"Aux In", "Back Surr Out"};
3731 return snd_ctl_enum_info(uinfo
, 1, 2, txt_aux
);
3734 static int snd_ac97_vt1618_aux_get(struct snd_kcontrol
*kcontrol
,
3735 struct snd_ctl_elem_value
*ucontrol
)
3737 ucontrol
->value
.enumerated
.item
[0] =
3738 (snd_ac97_read(snd_kcontrol_chip(kcontrol
), 0x5c) & 0x0008)>>3;
3742 static int snd_ac97_vt1618_aux_put(struct snd_kcontrol
*kcontrol
,
3743 struct snd_ctl_elem_value
*ucontrol
)
3745 /* toggle surround rear dac power */
3747 snd_ac97_update_bits(snd_kcontrol_chip(kcontrol
), 0x5c, 0x0008,
3748 ucontrol
->value
.enumerated
.item
[0] << 3);
3750 /* toggle aux in surround rear out jack */
3752 return snd_ac97_update_bits(snd_kcontrol_chip(kcontrol
), 0x76, 0x0008,
3753 ucontrol
->value
.enumerated
.item
[0] << 3);
3756 static const struct snd_kcontrol_new snd_ac97_controls_vt1618
[] = {
3757 AC97_SINGLE("Exchange Center/LFE", 0x5a, 8, 1, 0),
3758 AC97_SINGLE("DC Offset", 0x5a, 10, 1, 0),
3759 AC97_SINGLE("Soft Mute", 0x5c, 0, 1, 1),
3760 AC97_SINGLE("Headphone Amp", 0x5c, 5, 1, 1),
3761 AC97_DOUBLE("Back Surr Volume", 0x5e, 8, 0, 31, 1),
3762 AC97_SINGLE("Back Surr Switch", 0x5e, 15, 1, 1),
3764 .iface
= SNDRV_CTL_ELEM_IFACE_MIXER
,
3765 .name
= "Speaker Jack Mode",
3766 .info
= snd_ac97_vt1618_UAJ_info
,
3767 .get
= snd_ac97_vt1618_UAJ_get
,
3768 .put
= snd_ac97_vt1618_UAJ_put
,
3772 .iface
= SNDRV_CTL_ELEM_IFACE_MIXER
,
3773 .name
= "Line Jack Mode",
3774 .info
= snd_ac97_vt1618_UAJ_info
,
3775 .get
= snd_ac97_vt1618_UAJ_get
,
3776 .put
= snd_ac97_vt1618_UAJ_put
,
3780 .iface
= SNDRV_CTL_ELEM_IFACE_MIXER
,
3781 .name
= "Mic Jack Mode",
3782 .info
= snd_ac97_vt1618_UAJ_info
,
3783 .get
= snd_ac97_vt1618_UAJ_get
,
3784 .put
= snd_ac97_vt1618_UAJ_put
,
3788 .iface
= SNDRV_CTL_ELEM_IFACE_MIXER
,
3789 .name
= "Aux Jack Mode",
3790 .info
= snd_ac97_vt1618_aux_info
,
3791 .get
= snd_ac97_vt1618_aux_get
,
3792 .put
= snd_ac97_vt1618_aux_put
,
3796 static int patch_vt1618(struct snd_ac97
*ac97
)
3798 return patch_build_controls(ac97
, snd_ac97_controls_vt1618
,
3799 ARRAY_SIZE(snd_ac97_controls_vt1618
));
3804 static void it2646_update_jacks(struct snd_ac97
*ac97
)
3806 /* shared Line-In / Surround Out */
3807 snd_ac97_update_bits(ac97
, 0x76, 1 << 9,
3808 is_shared_surrout(ac97
) ? (1<<9) : 0);
3809 /* shared Mic / Center/LFE Out */
3810 snd_ac97_update_bits(ac97
, 0x76, 1 << 10,
3811 is_shared_clfeout(ac97
) ? (1<<10) : 0);
3814 static const struct snd_kcontrol_new snd_ac97_controls_it2646
[] = {
3815 AC97_SURROUND_JACK_MODE_CTL
,
3816 AC97_CHANNEL_MODE_CTL
,
3819 static const struct snd_kcontrol_new snd_ac97_spdif_controls_it2646
[] = {
3820 AC97_SINGLE(SNDRV_CTL_NAME_IEC958("",CAPTURE
,SWITCH
), 0x76, 11, 1, 0),
3821 AC97_SINGLE("Analog to IEC958 Output", 0x76, 12, 1, 0),
3822 AC97_SINGLE("IEC958 Input Monitor", 0x76, 13, 1, 0),
3825 static int patch_it2646_specific(struct snd_ac97
* ac97
)
3828 if ((err
= patch_build_controls(ac97
, snd_ac97_controls_it2646
, ARRAY_SIZE(snd_ac97_controls_it2646
))) < 0)
3830 if ((err
= patch_build_controls(ac97
, snd_ac97_spdif_controls_it2646
, ARRAY_SIZE(snd_ac97_spdif_controls_it2646
))) < 0)
3835 static const struct snd_ac97_build_ops patch_it2646_ops
= {
3836 .build_specific
= patch_it2646_specific
,
3837 .update_jacks
= it2646_update_jacks
3840 static int patch_it2646(struct snd_ac97
* ac97
)
3842 ac97
->build_ops
= &patch_it2646_ops
;
3843 /* full DAC volume */
3844 snd_ac97_write_cache(ac97
, 0x5E, 0x0808);
3845 snd_ac97_write_cache(ac97
, 0x7A, 0x0808);
3853 #define AC97_SI3036_CHIP_ID 0x5a
3854 #define AC97_SI3036_LINE_CFG 0x5c
3856 static const struct snd_kcontrol_new snd_ac97_controls_si3036
[] = {
3857 AC97_DOUBLE("Modem Speaker Volume", 0x5c, 14, 12, 3, 1)
3860 static int patch_si3036_specific(struct snd_ac97
* ac97
)
3863 for (idx
= 0; idx
< ARRAY_SIZE(snd_ac97_controls_si3036
); idx
++)
3864 if ((err
= snd_ctl_add(ac97
->bus
->card
, snd_ctl_new1(&snd_ac97_controls_si3036
[idx
], ac97
))) < 0)
3869 static const struct snd_ac97_build_ops patch_si3036_ops
= {
3870 .build_specific
= patch_si3036_specific
,
3873 static int mpatch_si3036(struct snd_ac97
* ac97
)
3875 ac97
->build_ops
= &patch_si3036_ops
;
3876 snd_ac97_write_cache(ac97
, 0x5c, 0xf210 );
3877 snd_ac97_write_cache(ac97
, 0x68, 0);
3884 * We use a static resolution table since LM4550 codec cannot be
3885 * properly autoprobed to determine the resolution via
3886 * check_volume_resolution().
3889 static struct snd_ac97_res_table lm4550_restbl
[] = {
3890 { AC97_MASTER
, 0x1f1f },
3891 { AC97_HEADPHONE
, 0x1f1f },
3892 { AC97_MASTER_MONO
, 0x001f },
3893 { AC97_PC_BEEP
, 0x001f }, /* LSB is ignored */
3894 { AC97_PHONE
, 0x001f },
3895 { AC97_MIC
, 0x001f },
3896 { AC97_LINE
, 0x1f1f },
3897 { AC97_CD
, 0x1f1f },
3898 { AC97_VIDEO
, 0x1f1f },
3899 { AC97_AUX
, 0x1f1f },
3900 { AC97_PCM
, 0x1f1f },
3901 { AC97_REC_GAIN
, 0x0f0f },
3902 { } /* terminator */
3905 static int patch_lm4550(struct snd_ac97
*ac97
)
3907 ac97
->res_table
= lm4550_restbl
;
3912 * UCB1400 codec (http://www.semiconductors.philips.com/acrobat_download/datasheets/UCB1400-02.pdf)
3914 static const struct snd_kcontrol_new snd_ac97_controls_ucb1400
[] = {
3915 /* enable/disable headphone driver which allows direct connection to
3916 stereo headphone without the use of external DC blocking
3918 AC97_SINGLE("Headphone Driver", 0x6a, 6, 1, 0),
3919 /* Filter used to compensate the DC offset is added in the ADC to remove idle
3920 tones from the audio band. */
3921 AC97_SINGLE("DC Filter", 0x6a, 4, 1, 0),
3922 /* Control smart-low-power mode feature. Allows automatic power down
3923 of unused blocks in the ADC analog front end and the PLL. */
3924 AC97_SINGLE("Smart Low Power Mode", 0x6c, 4, 3, 0),
3927 static int patch_ucb1400_specific(struct snd_ac97
* ac97
)
3930 for (idx
= 0; idx
< ARRAY_SIZE(snd_ac97_controls_ucb1400
); idx
++)
3931 if ((err
= snd_ctl_add(ac97
->bus
->card
, snd_ctl_new1(&snd_ac97_controls_ucb1400
[idx
], ac97
))) < 0)
3936 static const struct snd_ac97_build_ops patch_ucb1400_ops
= {
3937 .build_specific
= patch_ucb1400_specific
,
3940 static int patch_ucb1400(struct snd_ac97
* ac97
)
3942 ac97
->build_ops
= &patch_ucb1400_ops
;
3943 /* enable headphone driver and smart low power mode by default */
3944 snd_ac97_write_cache(ac97
, 0x6a, 0x0050);
3945 snd_ac97_write_cache(ac97
, 0x6c, 0x0030);