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
, const char **slaves
);
39 * Chip specific initialization
42 static int patch_build_controls(struct snd_ac97
* ac97
, const struct snd_kcontrol_new
*controls
, int count
)
46 for (idx
= 0; idx
< count
; idx
++)
47 if ((err
= snd_ctl_add(ac97
->bus
->card
, snd_ac97_cnew(&controls
[idx
], ac97
))) < 0)
52 /* replace with a new TLV */
53 static void reset_tlv(struct snd_ac97
*ac97
, const char *name
,
54 const unsigned int *tlv
)
56 struct snd_ctl_elem_id sid
;
57 struct snd_kcontrol
*kctl
;
58 memset(&sid
, 0, sizeof(sid
));
59 strcpy(sid
.name
, name
);
60 sid
.iface
= SNDRV_CTL_ELEM_IFACE_MIXER
;
61 kctl
= snd_ctl_find_id(ac97
->bus
->card
, &sid
);
62 if (kctl
&& kctl
->tlv
.p
)
66 /* set to the page, update bits and restore the page */
67 static int ac97_update_bits_page(struct snd_ac97
*ac97
, unsigned short reg
, unsigned short mask
, unsigned short value
, unsigned short page
)
69 unsigned short page_save
;
72 mutex_lock(&ac97
->page_mutex
);
73 page_save
= snd_ac97_read(ac97
, AC97_INT_PAGING
) & AC97_PAGE_MASK
;
74 snd_ac97_update_bits(ac97
, AC97_INT_PAGING
, AC97_PAGE_MASK
, page
);
75 ret
= snd_ac97_update_bits(ac97
, reg
, mask
, value
);
76 snd_ac97_update_bits(ac97
, AC97_INT_PAGING
, AC97_PAGE_MASK
, page_save
);
77 mutex_unlock(&ac97
->page_mutex
); /* unlock paging */
82 * shared line-in/mic controls
84 static int ac97_enum_text_info(struct snd_kcontrol
*kcontrol
, struct snd_ctl_elem_info
*uinfo
,
85 const char **texts
, unsigned int nums
)
87 uinfo
->type
= SNDRV_CTL_ELEM_TYPE_ENUMERATED
;
89 uinfo
->value
.enumerated
.items
= nums
;
90 if (uinfo
->value
.enumerated
.item
> nums
- 1)
91 uinfo
->value
.enumerated
.item
= nums
- 1;
92 strcpy(uinfo
->value
.enumerated
.name
, texts
[uinfo
->value
.enumerated
.item
]);
96 static int ac97_surround_jack_mode_info(struct snd_kcontrol
*kcontrol
, struct snd_ctl_elem_info
*uinfo
)
98 static const char *texts
[] = { "Shared", "Independent" };
99 return ac97_enum_text_info(kcontrol
, uinfo
, texts
, 2);
102 static int ac97_surround_jack_mode_get(struct snd_kcontrol
*kcontrol
, struct snd_ctl_elem_value
*ucontrol
)
104 struct snd_ac97
*ac97
= snd_kcontrol_chip(kcontrol
);
106 ucontrol
->value
.enumerated
.item
[0] = ac97
->indep_surround
;
110 static int ac97_surround_jack_mode_put(struct snd_kcontrol
*kcontrol
, struct snd_ctl_elem_value
*ucontrol
)
112 struct snd_ac97
*ac97
= snd_kcontrol_chip(kcontrol
);
113 unsigned char indep
= !!ucontrol
->value
.enumerated
.item
[0];
115 if (indep
!= ac97
->indep_surround
) {
116 ac97
->indep_surround
= indep
;
117 if (ac97
->build_ops
->update_jacks
)
118 ac97
->build_ops
->update_jacks(ac97
);
124 static int ac97_channel_mode_info(struct snd_kcontrol
*kcontrol
, struct snd_ctl_elem_info
*uinfo
)
126 static const char *texts
[] = { "2ch", "4ch", "6ch", "8ch" };
127 return ac97_enum_text_info(kcontrol
, uinfo
, texts
,
128 kcontrol
->private_value
);
131 static int ac97_channel_mode_get(struct snd_kcontrol
*kcontrol
, struct snd_ctl_elem_value
*ucontrol
)
133 struct snd_ac97
*ac97
= snd_kcontrol_chip(kcontrol
);
135 ucontrol
->value
.enumerated
.item
[0] = ac97
->channel_mode
;
139 static int ac97_channel_mode_put(struct snd_kcontrol
*kcontrol
, struct snd_ctl_elem_value
*ucontrol
)
141 struct snd_ac97
*ac97
= snd_kcontrol_chip(kcontrol
);
142 unsigned char mode
= ucontrol
->value
.enumerated
.item
[0];
144 if (mode
>= kcontrol
->private_value
)
147 if (mode
!= ac97
->channel_mode
) {
148 ac97
->channel_mode
= mode
;
149 if (ac97
->build_ops
->update_jacks
)
150 ac97
->build_ops
->update_jacks(ac97
);
156 #define AC97_SURROUND_JACK_MODE_CTL \
158 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
159 .name = "Surround Jack Mode", \
160 .info = ac97_surround_jack_mode_info, \
161 .get = ac97_surround_jack_mode_get, \
162 .put = ac97_surround_jack_mode_put, \
165 #define AC97_CHANNEL_MODE_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 = 3, \
175 #define AC97_CHANNEL_MODE_4CH_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 = 2, \
185 #define AC97_CHANNEL_MODE_8CH_CTL \
187 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
188 .name = "Channel Mode", \
189 .info = ac97_channel_mode_info, \
190 .get = ac97_channel_mode_get, \
191 .put = ac97_channel_mode_put, \
192 .private_value = 4, \
195 static inline int is_surround_on(struct snd_ac97
*ac97
)
197 return ac97
->channel_mode
>= 1;
200 static inline int is_clfe_on(struct snd_ac97
*ac97
)
202 return ac97
->channel_mode
>= 2;
205 /* system has shared jacks with surround out enabled */
206 static inline int is_shared_surrout(struct snd_ac97
*ac97
)
208 return !ac97
->indep_surround
&& is_surround_on(ac97
);
211 /* system has shared jacks with center/lfe out enabled */
212 static inline int is_shared_clfeout(struct snd_ac97
*ac97
)
214 return !ac97
->indep_surround
&& is_clfe_on(ac97
);
217 /* system has shared jacks with line in enabled */
218 static inline int is_shared_linein(struct snd_ac97
*ac97
)
220 return !ac97
->indep_surround
&& !is_surround_on(ac97
);
223 /* system has shared jacks with mic in enabled */
224 static inline int is_shared_micin(struct snd_ac97
*ac97
)
226 return !ac97
->indep_surround
&& !is_clfe_on(ac97
);
229 static inline int alc850_is_aux_back_surround(struct snd_ac97
*ac97
)
231 return is_surround_on(ac97
);
234 /* The following snd_ac97_ymf753_... items added by David Shust (dshust@shustring.com) */
235 /* Modified for YMF743 by Keita Maehara <maehara@debian.org> */
237 /* It is possible to indicate to the Yamaha YMF7x3 the type of
238 speakers being used. */
240 static int snd_ac97_ymf7x3_info_speaker(struct snd_kcontrol
*kcontrol
,
241 struct snd_ctl_elem_info
*uinfo
)
243 static char *texts
[3] = {
244 "Standard", "Small", "Smaller"
247 uinfo
->type
= SNDRV_CTL_ELEM_TYPE_ENUMERATED
;
249 uinfo
->value
.enumerated
.items
= 3;
250 if (uinfo
->value
.enumerated
.item
> 2)
251 uinfo
->value
.enumerated
.item
= 2;
252 strcpy(uinfo
->value
.enumerated
.name
, texts
[uinfo
->value
.enumerated
.item
]);
256 static int snd_ac97_ymf7x3_get_speaker(struct snd_kcontrol
*kcontrol
,
257 struct snd_ctl_elem_value
*ucontrol
)
259 struct snd_ac97
*ac97
= snd_kcontrol_chip(kcontrol
);
262 val
= ac97
->regs
[AC97_YMF7X3_3D_MODE_SEL
];
263 val
= (val
>> 10) & 3;
264 if (val
> 0) /* 0 = invalid */
266 ucontrol
->value
.enumerated
.item
[0] = val
;
270 static int snd_ac97_ymf7x3_put_speaker(struct snd_kcontrol
*kcontrol
,
271 struct snd_ctl_elem_value
*ucontrol
)
273 struct snd_ac97
*ac97
= snd_kcontrol_chip(kcontrol
);
276 if (ucontrol
->value
.enumerated
.item
[0] > 2)
278 val
= (ucontrol
->value
.enumerated
.item
[0] + 1) << 10;
279 return snd_ac97_update(ac97
, AC97_YMF7X3_3D_MODE_SEL
, val
);
282 static const struct snd_kcontrol_new snd_ac97_ymf7x3_controls_speaker
=
284 .iface
= SNDRV_CTL_ELEM_IFACE_MIXER
,
285 .name
= "3D Control - Speaker",
286 .info
= snd_ac97_ymf7x3_info_speaker
,
287 .get
= snd_ac97_ymf7x3_get_speaker
,
288 .put
= snd_ac97_ymf7x3_put_speaker
,
291 /* It is possible to indicate to the Yamaha YMF7x3 the source to
292 direct to the S/PDIF output. */
293 static int snd_ac97_ymf7x3_spdif_source_info(struct snd_kcontrol
*kcontrol
,
294 struct snd_ctl_elem_info
*uinfo
)
296 static char *texts
[2] = { "AC-Link", "A/D Converter" };
298 uinfo
->type
= SNDRV_CTL_ELEM_TYPE_ENUMERATED
;
300 uinfo
->value
.enumerated
.items
= 2;
301 if (uinfo
->value
.enumerated
.item
> 1)
302 uinfo
->value
.enumerated
.item
= 1;
303 strcpy(uinfo
->value
.enumerated
.name
, texts
[uinfo
->value
.enumerated
.item
]);
307 static int snd_ac97_ymf7x3_spdif_source_get(struct snd_kcontrol
*kcontrol
,
308 struct snd_ctl_elem_value
*ucontrol
)
310 struct snd_ac97
*ac97
= snd_kcontrol_chip(kcontrol
);
313 val
= ac97
->regs
[AC97_YMF7X3_DIT_CTRL
];
314 ucontrol
->value
.enumerated
.item
[0] = (val
>> 1) & 1;
318 static int snd_ac97_ymf7x3_spdif_source_put(struct snd_kcontrol
*kcontrol
,
319 struct snd_ctl_elem_value
*ucontrol
)
321 struct snd_ac97
*ac97
= snd_kcontrol_chip(kcontrol
);
324 if (ucontrol
->value
.enumerated
.item
[0] > 1)
326 val
= ucontrol
->value
.enumerated
.item
[0] << 1;
327 return snd_ac97_update_bits(ac97
, AC97_YMF7X3_DIT_CTRL
, 0x0002, val
);
330 static int patch_yamaha_ymf7x3_3d(struct snd_ac97
*ac97
)
332 struct snd_kcontrol
*kctl
;
335 kctl
= snd_ac97_cnew(&snd_ac97_controls_3d
[0], ac97
);
336 err
= snd_ctl_add(ac97
->bus
->card
, kctl
);
339 strcpy(kctl
->id
.name
, "3D Control - Wide");
340 kctl
->private_value
= AC97_SINGLE_VALUE(AC97_3D_CONTROL
, 9, 7, 0);
341 snd_ac97_write_cache(ac97
, AC97_3D_CONTROL
, 0x0000);
342 err
= snd_ctl_add(ac97
->bus
->card
,
343 snd_ac97_cnew(&snd_ac97_ymf7x3_controls_speaker
,
347 snd_ac97_write_cache(ac97
, AC97_YMF7X3_3D_MODE_SEL
, 0x0c00);
351 static const struct snd_kcontrol_new snd_ac97_yamaha_ymf743_controls_spdif
[3] =
353 AC97_SINGLE(SNDRV_CTL_NAME_IEC958("", PLAYBACK
, SWITCH
),
354 AC97_YMF7X3_DIT_CTRL
, 0, 1, 0),
356 .iface
= SNDRV_CTL_ELEM_IFACE_MIXER
,
357 .name
= SNDRV_CTL_NAME_IEC958("", PLAYBACK
, NONE
) "Source",
358 .info
= snd_ac97_ymf7x3_spdif_source_info
,
359 .get
= snd_ac97_ymf7x3_spdif_source_get
,
360 .put
= snd_ac97_ymf7x3_spdif_source_put
,
362 AC97_SINGLE(SNDRV_CTL_NAME_IEC958("", NONE
, NONE
) "Mute",
363 AC97_YMF7X3_DIT_CTRL
, 2, 1, 1)
366 static int patch_yamaha_ymf743_build_spdif(struct snd_ac97
*ac97
)
370 err
= patch_build_controls(ac97
, &snd_ac97_controls_spdif
[0], 3);
373 err
= patch_build_controls(ac97
,
374 snd_ac97_yamaha_ymf743_controls_spdif
, 3);
377 /* set default PCM S/PDIF params */
378 /* PCM audio,no copyright,no preemphasis,PCM coder,original */
379 snd_ac97_write_cache(ac97
, AC97_YMF7X3_DIT_CTRL
, 0xa201);
383 static const struct snd_ac97_build_ops patch_yamaha_ymf743_ops
= {
384 .build_spdif
= patch_yamaha_ymf743_build_spdif
,
385 .build_3d
= patch_yamaha_ymf7x3_3d
,
388 static int patch_yamaha_ymf743(struct snd_ac97
*ac97
)
390 ac97
->build_ops
= &patch_yamaha_ymf743_ops
;
391 ac97
->caps
|= AC97_BC_BASS_TREBLE
;
392 ac97
->caps
|= 0x04 << 10; /* Yamaha 3D enhancement */
393 ac97
->rates
[AC97_RATES_SPDIF
] = SNDRV_PCM_RATE_48000
; /* 48k only */
394 ac97
->ext_id
|= AC97_EI_SPDIF
; /* force the detection of spdif */
398 /* The AC'97 spec states that the S/PDIF signal is to be output at pin 48.
399 The YMF753 will output the S/PDIF signal to pin 43, 47 (EAPD), or 48.
400 By default, no output pin is selected, and the S/PDIF signal is not output.
401 There is also a bit to mute S/PDIF output in a vendor-specific register. */
402 static int snd_ac97_ymf753_spdif_output_pin_info(struct snd_kcontrol
*kcontrol
, struct snd_ctl_elem_info
*uinfo
)
404 static char *texts
[3] = { "Disabled", "Pin 43", "Pin 48" };
406 uinfo
->type
= SNDRV_CTL_ELEM_TYPE_ENUMERATED
;
408 uinfo
->value
.enumerated
.items
= 3;
409 if (uinfo
->value
.enumerated
.item
> 2)
410 uinfo
->value
.enumerated
.item
= 2;
411 strcpy(uinfo
->value
.enumerated
.name
, texts
[uinfo
->value
.enumerated
.item
]);
415 static int snd_ac97_ymf753_spdif_output_pin_get(struct snd_kcontrol
*kcontrol
, struct snd_ctl_elem_value
*ucontrol
)
417 struct snd_ac97
*ac97
= snd_kcontrol_chip(kcontrol
);
420 val
= ac97
->regs
[AC97_YMF7X3_DIT_CTRL
];
421 ucontrol
->value
.enumerated
.item
[0] = (val
& 0x0008) ? 2 : (val
& 0x0020) ? 1 : 0;
425 static int snd_ac97_ymf753_spdif_output_pin_put(struct snd_kcontrol
*kcontrol
, struct snd_ctl_elem_value
*ucontrol
)
427 struct snd_ac97
*ac97
= snd_kcontrol_chip(kcontrol
);
430 if (ucontrol
->value
.enumerated
.item
[0] > 2)
432 val
= (ucontrol
->value
.enumerated
.item
[0] == 2) ? 0x0008 :
433 (ucontrol
->value
.enumerated
.item
[0] == 1) ? 0x0020 : 0;
434 return snd_ac97_update_bits(ac97
, AC97_YMF7X3_DIT_CTRL
, 0x0028, val
);
435 /* The following can be used to direct S/PDIF output to pin 47 (EAPD).
436 snd_ac97_write_cache(ac97, 0x62, snd_ac97_read(ac97, 0x62) | 0x0008); */
439 static const struct snd_kcontrol_new snd_ac97_ymf753_controls_spdif
[3] = {
441 .iface
= SNDRV_CTL_ELEM_IFACE_MIXER
,
442 .name
= SNDRV_CTL_NAME_IEC958("",PLAYBACK
,NONE
) "Source",
443 .info
= snd_ac97_ymf7x3_spdif_source_info
,
444 .get
= snd_ac97_ymf7x3_spdif_source_get
,
445 .put
= snd_ac97_ymf7x3_spdif_source_put
,
448 .iface
= SNDRV_CTL_ELEM_IFACE_MIXER
,
449 .name
= SNDRV_CTL_NAME_IEC958("",PLAYBACK
,NONE
) "Output Pin",
450 .info
= snd_ac97_ymf753_spdif_output_pin_info
,
451 .get
= snd_ac97_ymf753_spdif_output_pin_get
,
452 .put
= snd_ac97_ymf753_spdif_output_pin_put
,
454 AC97_SINGLE(SNDRV_CTL_NAME_IEC958("", NONE
, NONE
) "Mute",
455 AC97_YMF7X3_DIT_CTRL
, 2, 1, 1)
458 static int patch_yamaha_ymf753_post_spdif(struct snd_ac97
* ac97
)
462 if ((err
= patch_build_controls(ac97
, snd_ac97_ymf753_controls_spdif
, ARRAY_SIZE(snd_ac97_ymf753_controls_spdif
))) < 0)
467 static const struct snd_ac97_build_ops patch_yamaha_ymf753_ops
= {
468 .build_3d
= patch_yamaha_ymf7x3_3d
,
469 .build_post_spdif
= patch_yamaha_ymf753_post_spdif
472 static int patch_yamaha_ymf753(struct snd_ac97
* ac97
)
474 /* Patch for Yamaha YMF753, Copyright (c) by David Shust, dshust@shustring.com.
475 This chip has nonstandard and extended behaviour with regard to its S/PDIF output.
476 The AC'97 spec states that the S/PDIF signal is to be output at pin 48.
477 The YMF753 will ouput the S/PDIF signal to pin 43, 47 (EAPD), or 48.
478 By default, no output pin is selected, and the S/PDIF signal is not output.
479 There is also a bit to mute S/PDIF output in a vendor-specific register.
481 ac97
->build_ops
= &patch_yamaha_ymf753_ops
;
482 ac97
->caps
|= AC97_BC_BASS_TREBLE
;
483 ac97
->caps
|= 0x04 << 10; /* Yamaha 3D enhancement */
488 * May 2, 2003 Liam Girdwood <lrg@slimlogic.co.uk>
489 * removed broken wolfson00 patch.
490 * added support for WM9705,WM9708,WM9709,WM9710,WM9711,WM9712 and WM9717.
493 static const struct snd_kcontrol_new wm97xx_snd_ac97_controls
[] = {
494 AC97_DOUBLE("Front Playback Volume", AC97_WM97XX_FMIXER_VOL
, 8, 0, 31, 1),
495 AC97_SINGLE("Front Playback Switch", AC97_WM97XX_FMIXER_VOL
, 15, 1, 1),
498 static int patch_wolfson_wm9703_specific(struct snd_ac97
* ac97
)
500 /* This is known to work for the ViewSonic ViewPad 1000
501 * Randolph Bentson <bentson@holmsjoen.com>
502 * WM9703/9707/9708/9717
506 for (i
= 0; i
< ARRAY_SIZE(wm97xx_snd_ac97_controls
); i
++) {
507 if ((err
= snd_ctl_add(ac97
->bus
->card
, snd_ac97_cnew(&wm97xx_snd_ac97_controls
[i
], ac97
))) < 0)
510 snd_ac97_write_cache(ac97
, AC97_WM97XX_FMIXER_VOL
, 0x0808);
514 static const struct snd_ac97_build_ops patch_wolfson_wm9703_ops
= {
515 .build_specific
= patch_wolfson_wm9703_specific
,
518 static int patch_wolfson03(struct snd_ac97
* ac97
)
520 ac97
->build_ops
= &patch_wolfson_wm9703_ops
;
524 static const struct snd_kcontrol_new wm9704_snd_ac97_controls
[] = {
525 AC97_DOUBLE("Front Playback Volume", AC97_WM97XX_FMIXER_VOL
, 8, 0, 31, 1),
526 AC97_SINGLE("Front Playback Switch", AC97_WM97XX_FMIXER_VOL
, 15, 1, 1),
527 AC97_DOUBLE("Rear Playback Volume", AC97_WM9704_RMIXER_VOL
, 8, 0, 31, 1),
528 AC97_SINGLE("Rear Playback Switch", AC97_WM9704_RMIXER_VOL
, 15, 1, 1),
529 AC97_DOUBLE("Rear DAC Volume", AC97_WM9704_RPCM_VOL
, 8, 0, 31, 1),
530 AC97_DOUBLE("Surround Volume", AC97_SURROUND_MASTER
, 8, 0, 31, 1),
533 static int patch_wolfson_wm9704_specific(struct snd_ac97
* ac97
)
536 for (i
= 0; i
< ARRAY_SIZE(wm9704_snd_ac97_controls
); i
++) {
537 if ((err
= snd_ctl_add(ac97
->bus
->card
, snd_ac97_cnew(&wm9704_snd_ac97_controls
[i
], ac97
))) < 0)
540 /* patch for DVD noise */
541 snd_ac97_write_cache(ac97
, AC97_WM9704_TEST
, 0x0200);
545 static const struct snd_ac97_build_ops patch_wolfson_wm9704_ops
= {
546 .build_specific
= patch_wolfson_wm9704_specific
,
549 static int patch_wolfson04(struct snd_ac97
* ac97
)
552 ac97
->build_ops
= &patch_wolfson_wm9704_ops
;
556 static int patch_wolfson05(struct snd_ac97
* ac97
)
559 ac97
->build_ops
= &patch_wolfson_wm9703_ops
;
560 #ifdef CONFIG_TOUCHSCREEN_WM9705
561 /* WM9705 touchscreen uses AUX and VIDEO for touch */
562 ac97
->flags
|= AC97_HAS_NO_VIDEO
| AC97_HAS_NO_AUX
;
567 static const char* wm9711_alc_select
[] = {"None", "Left", "Right", "Stereo"};
568 static const char* wm9711_alc_mix
[] = {"Stereo", "Right", "Left", "None"};
569 static const char* wm9711_out3_src
[] = {"Left", "VREF", "Left + Right", "Mono"};
570 static const char* wm9711_out3_lrsrc
[] = {"Master Mix", "Headphone Mix"};
571 static const char* wm9711_rec_adc
[] = {"Stereo", "Left", "Right", "Mute"};
572 static const char* wm9711_base
[] = {"Linear Control", "Adaptive Boost"};
573 static const char* wm9711_rec_gain
[] = {"+1.5dB Steps", "+0.75dB Steps"};
574 static const char* wm9711_mic
[] = {"Mic 1", "Differential", "Mic 2", "Stereo"};
575 static const char* wm9711_rec_sel
[] =
576 {"Mic 1", "NC", "NC", "Master Mix", "Line", "Headphone Mix", "Phone Mix", "Phone"};
577 static const char* wm9711_ng_type
[] = {"Constant Gain", "Mute"};
579 static const struct ac97_enum wm9711_enum
[] = {
580 AC97_ENUM_SINGLE(AC97_PCI_SVID
, 14, 4, wm9711_alc_select
),
581 AC97_ENUM_SINGLE(AC97_VIDEO
, 10, 4, wm9711_alc_mix
),
582 AC97_ENUM_SINGLE(AC97_AUX
, 9, 4, wm9711_out3_src
),
583 AC97_ENUM_SINGLE(AC97_AUX
, 8, 2, wm9711_out3_lrsrc
),
584 AC97_ENUM_SINGLE(AC97_REC_SEL
, 12, 4, wm9711_rec_adc
),
585 AC97_ENUM_SINGLE(AC97_MASTER_TONE
, 15, 2, wm9711_base
),
586 AC97_ENUM_DOUBLE(AC97_REC_GAIN
, 14, 6, 2, wm9711_rec_gain
),
587 AC97_ENUM_SINGLE(AC97_MIC
, 5, 4, wm9711_mic
),
588 AC97_ENUM_DOUBLE(AC97_REC_SEL
, 8, 0, 8, wm9711_rec_sel
),
589 AC97_ENUM_SINGLE(AC97_PCI_SVID
, 5, 2, wm9711_ng_type
),
592 static const struct snd_kcontrol_new wm9711_snd_ac97_controls
[] = {
593 AC97_SINGLE("ALC Target Volume", AC97_CODEC_CLASS_REV
, 12, 15, 0),
594 AC97_SINGLE("ALC Hold Time", AC97_CODEC_CLASS_REV
, 8, 15, 0),
595 AC97_SINGLE("ALC Decay Time", AC97_CODEC_CLASS_REV
, 4, 15, 0),
596 AC97_SINGLE("ALC Attack Time", AC97_CODEC_CLASS_REV
, 0, 15, 0),
597 AC97_ENUM("ALC Function", wm9711_enum
[0]),
598 AC97_SINGLE("ALC Max Volume", AC97_PCI_SVID
, 11, 7, 1),
599 AC97_SINGLE("ALC ZC Timeout", AC97_PCI_SVID
, 9, 3, 1),
600 AC97_SINGLE("ALC ZC Switch", AC97_PCI_SVID
, 8, 1, 0),
601 AC97_SINGLE("ALC NG Switch", AC97_PCI_SVID
, 7, 1, 0),
602 AC97_ENUM("ALC NG Type", wm9711_enum
[9]),
603 AC97_SINGLE("ALC NG Threshold", AC97_PCI_SVID
, 0, 31, 1),
605 AC97_SINGLE("Side Tone Switch", AC97_VIDEO
, 15, 1, 1),
606 AC97_SINGLE("Side Tone Volume", AC97_VIDEO
, 12, 7, 1),
607 AC97_ENUM("ALC Headphone Mux", wm9711_enum
[1]),
608 AC97_SINGLE("ALC Headphone Volume", AC97_VIDEO
, 7, 7, 1),
610 AC97_SINGLE("Out3 Switch", AC97_AUX
, 15, 1, 1),
611 AC97_SINGLE("Out3 ZC Switch", AC97_AUX
, 7, 1, 0),
612 AC97_ENUM("Out3 Mux", wm9711_enum
[2]),
613 AC97_ENUM("Out3 LR Mux", wm9711_enum
[3]),
614 AC97_SINGLE("Out3 Volume", AC97_AUX
, 0, 31, 1),
616 AC97_SINGLE("Beep to Headphone Switch", AC97_PC_BEEP
, 15, 1, 1),
617 AC97_SINGLE("Beep to Headphone Volume", AC97_PC_BEEP
, 12, 7, 1),
618 AC97_SINGLE("Beep to Side Tone Switch", AC97_PC_BEEP
, 11, 1, 1),
619 AC97_SINGLE("Beep to Side Tone Volume", AC97_PC_BEEP
, 8, 7, 1),
620 AC97_SINGLE("Beep to Phone Switch", AC97_PC_BEEP
, 7, 1, 1),
621 AC97_SINGLE("Beep to Phone Volume", AC97_PC_BEEP
, 4, 7, 1),
623 AC97_SINGLE("Aux to Headphone Switch", AC97_CD
, 15, 1, 1),
624 AC97_SINGLE("Aux to Headphone Volume", AC97_CD
, 12, 7, 1),
625 AC97_SINGLE("Aux to Side Tone Switch", AC97_CD
, 11, 1, 1),
626 AC97_SINGLE("Aux to Side Tone Volume", AC97_CD
, 8, 7, 1),
627 AC97_SINGLE("Aux to Phone Switch", AC97_CD
, 7, 1, 1),
628 AC97_SINGLE("Aux to Phone Volume", AC97_CD
, 4, 7, 1),
630 AC97_SINGLE("Phone to Headphone Switch", AC97_PHONE
, 15, 1, 1),
631 AC97_SINGLE("Phone to Master Switch", AC97_PHONE
, 14, 1, 1),
633 AC97_SINGLE("Line to Headphone Switch", AC97_LINE
, 15, 1, 1),
634 AC97_SINGLE("Line to Master Switch", AC97_LINE
, 14, 1, 1),
635 AC97_SINGLE("Line to Phone Switch", AC97_LINE
, 13, 1, 1),
637 AC97_SINGLE("PCM Playback to Headphone Switch", AC97_PCM
, 15, 1, 1),
638 AC97_SINGLE("PCM Playback to Master Switch", AC97_PCM
, 14, 1, 1),
639 AC97_SINGLE("PCM Playback to Phone Switch", AC97_PCM
, 13, 1, 1),
641 AC97_SINGLE("Capture 20dB Boost Switch", AC97_REC_SEL
, 14, 1, 0),
642 AC97_ENUM("Capture to Phone Mux", wm9711_enum
[4]),
643 AC97_SINGLE("Capture to Phone 20dB Boost Switch", AC97_REC_SEL
, 11, 1, 1),
644 AC97_ENUM("Capture Select", wm9711_enum
[8]),
646 AC97_SINGLE("3D Upper Cut-off Switch", AC97_3D_CONTROL
, 5, 1, 1),
647 AC97_SINGLE("3D Lower Cut-off Switch", AC97_3D_CONTROL
, 4, 1, 1),
649 AC97_ENUM("Bass Control", wm9711_enum
[5]),
650 AC97_SINGLE("Bass Cut-off Switch", AC97_MASTER_TONE
, 12, 1, 1),
651 AC97_SINGLE("Tone Cut-off Switch", AC97_MASTER_TONE
, 4, 1, 1),
652 AC97_SINGLE("Playback Attenuate (-6dB) Switch", AC97_MASTER_TONE
, 6, 1, 0),
654 AC97_SINGLE("ADC Switch", AC97_REC_GAIN
, 15, 1, 1),
655 AC97_ENUM("Capture Volume Steps", wm9711_enum
[6]),
656 AC97_DOUBLE("Capture Volume", AC97_REC_GAIN
, 8, 0, 63, 1),
657 AC97_SINGLE("Capture ZC Switch", AC97_REC_GAIN
, 7, 1, 0),
659 AC97_SINGLE("Mic 1 to Phone Switch", AC97_MIC
, 14, 1, 1),
660 AC97_SINGLE("Mic 2 to Phone Switch", AC97_MIC
, 13, 1, 1),
661 AC97_ENUM("Mic Select Source", wm9711_enum
[7]),
662 AC97_SINGLE("Mic 1 Volume", AC97_MIC
, 8, 31, 1),
663 AC97_SINGLE("Mic 2 Volume", AC97_MIC
, 0, 31, 1),
664 AC97_SINGLE("Mic 20dB Boost Switch", AC97_MIC
, 7, 1, 0),
666 AC97_SINGLE("Master Left Inv Switch", AC97_MASTER
, 6, 1, 0),
667 AC97_SINGLE("Master ZC Switch", AC97_MASTER
, 7, 1, 0),
668 AC97_SINGLE("Headphone ZC Switch", AC97_HEADPHONE
, 7, 1, 0),
669 AC97_SINGLE("Mono ZC Switch", AC97_MASTER_MONO
, 7, 1, 0),
672 static int patch_wolfson_wm9711_specific(struct snd_ac97
* ac97
)
676 for (i
= 0; i
< ARRAY_SIZE(wm9711_snd_ac97_controls
); i
++) {
677 if ((err
= snd_ctl_add(ac97
->bus
->card
, snd_ac97_cnew(&wm9711_snd_ac97_controls
[i
], ac97
))) < 0)
680 snd_ac97_write_cache(ac97
, AC97_CODEC_CLASS_REV
, 0x0808);
681 snd_ac97_write_cache(ac97
, AC97_PCI_SVID
, 0x0808);
682 snd_ac97_write_cache(ac97
, AC97_VIDEO
, 0x0808);
683 snd_ac97_write_cache(ac97
, AC97_AUX
, 0x0808);
684 snd_ac97_write_cache(ac97
, AC97_PC_BEEP
, 0x0808);
685 snd_ac97_write_cache(ac97
, AC97_CD
, 0x0000);
689 static const struct snd_ac97_build_ops patch_wolfson_wm9711_ops
= {
690 .build_specific
= patch_wolfson_wm9711_specific
,
693 static int patch_wolfson11(struct snd_ac97
* ac97
)
696 ac97
->build_ops
= &patch_wolfson_wm9711_ops
;
698 ac97
->flags
|= AC97_HAS_NO_REC_GAIN
| AC97_STEREO_MUTES
| AC97_HAS_NO_MIC
|
699 AC97_HAS_NO_PC_BEEP
| AC97_HAS_NO_VIDEO
| AC97_HAS_NO_CD
;
704 static const char* wm9713_mic_mixer
[] = {"Stereo", "Mic 1", "Mic 2", "Mute"};
705 static const char* wm9713_rec_mux
[] = {"Stereo", "Left", "Right", "Mute"};
706 static const char* wm9713_rec_src
[] =
707 {"Mic 1", "Mic 2", "Line", "Mono In", "Headphone Mix", "Master Mix",
709 static const char* wm9713_rec_gain
[] = {"+1.5dB Steps", "+0.75dB Steps"};
710 static const char* wm9713_alc_select
[] = {"None", "Left", "Right", "Stereo"};
711 static const char* wm9713_mono_pga
[] = {"Vmid", "Zh", "Mono Mix", "Inv 1"};
712 static const char* wm9713_spk_pga
[] =
713 {"Vmid", "Zh", "Headphone Mix", "Master Mix", "Inv", "NC", "NC", "NC"};
714 static const char* wm9713_hp_pga
[] = {"Vmid", "Zh", "Headphone Mix", "NC"};
715 static const char* wm9713_out3_pga
[] = {"Vmid", "Zh", "Inv 1", "NC"};
716 static const char* wm9713_out4_pga
[] = {"Vmid", "Zh", "Inv 2", "NC"};
717 static const char* wm9713_dac_inv
[] =
718 {"Off", "Mono Mix", "Master Mix", "Headphone Mix L", "Headphone Mix R",
719 "Headphone Mix Mono", "NC", "Vmid"};
720 static const char* wm9713_base
[] = {"Linear Control", "Adaptive Boost"};
721 static const char* wm9713_ng_type
[] = {"Constant Gain", "Mute"};
723 static const struct ac97_enum wm9713_enum
[] = {
724 AC97_ENUM_SINGLE(AC97_LINE
, 3, 4, wm9713_mic_mixer
),
725 AC97_ENUM_SINGLE(AC97_VIDEO
, 14, 4, wm9713_rec_mux
),
726 AC97_ENUM_SINGLE(AC97_VIDEO
, 9, 4, wm9713_rec_mux
),
727 AC97_ENUM_DOUBLE(AC97_VIDEO
, 3, 0, 8, wm9713_rec_src
),
728 AC97_ENUM_DOUBLE(AC97_CD
, 14, 6, 2, wm9713_rec_gain
),
729 AC97_ENUM_SINGLE(AC97_PCI_SVID
, 14, 4, wm9713_alc_select
),
730 AC97_ENUM_SINGLE(AC97_REC_GAIN
, 14, 4, wm9713_mono_pga
),
731 AC97_ENUM_DOUBLE(AC97_REC_GAIN
, 11, 8, 8, wm9713_spk_pga
),
732 AC97_ENUM_DOUBLE(AC97_REC_GAIN
, 6, 4, 4, wm9713_hp_pga
),
733 AC97_ENUM_SINGLE(AC97_REC_GAIN
, 2, 4, wm9713_out3_pga
),
734 AC97_ENUM_SINGLE(AC97_REC_GAIN
, 0, 4, wm9713_out4_pga
),
735 AC97_ENUM_DOUBLE(AC97_REC_GAIN_MIC
, 13, 10, 8, wm9713_dac_inv
),
736 AC97_ENUM_SINGLE(AC97_GENERAL_PURPOSE
, 15, 2, wm9713_base
),
737 AC97_ENUM_SINGLE(AC97_PCI_SVID
, 5, 2, wm9713_ng_type
),
740 static const struct snd_kcontrol_new wm13_snd_ac97_controls
[] = {
741 AC97_DOUBLE("Line In Volume", AC97_PC_BEEP
, 8, 0, 31, 1),
742 AC97_SINGLE("Line In to Headphone Switch", AC97_PC_BEEP
, 15, 1, 1),
743 AC97_SINGLE("Line In to Master Switch", AC97_PC_BEEP
, 14, 1, 1),
744 AC97_SINGLE("Line In to Mono Switch", AC97_PC_BEEP
, 13, 1, 1),
746 AC97_DOUBLE("PCM Playback Volume", AC97_PHONE
, 8, 0, 31, 1),
747 AC97_SINGLE("PCM Playback to Headphone Switch", AC97_PHONE
, 15, 1, 1),
748 AC97_SINGLE("PCM Playback to Master Switch", AC97_PHONE
, 14, 1, 1),
749 AC97_SINGLE("PCM Playback to Mono Switch", AC97_PHONE
, 13, 1, 1),
751 AC97_SINGLE("Mic 1 Volume", AC97_MIC
, 8, 31, 1),
752 AC97_SINGLE("Mic 2 Volume", AC97_MIC
, 0, 31, 1),
753 AC97_SINGLE("Mic 1 to Mono Switch", AC97_LINE
, 7, 1, 1),
754 AC97_SINGLE("Mic 2 to Mono Switch", AC97_LINE
, 6, 1, 1),
755 AC97_SINGLE("Mic Boost (+20dB) Switch", AC97_LINE
, 5, 1, 0),
756 AC97_ENUM("Mic to Headphone Mux", wm9713_enum
[0]),
757 AC97_SINGLE("Mic Headphone Mixer Volume", AC97_LINE
, 0, 7, 1),
759 AC97_SINGLE("Capture Switch", AC97_CD
, 15, 1, 1),
760 AC97_ENUM("Capture Volume Steps", wm9713_enum
[4]),
761 AC97_DOUBLE("Capture Volume", AC97_CD
, 8, 0, 15, 0),
762 AC97_SINGLE("Capture ZC Switch", AC97_CD
, 7, 1, 0),
764 AC97_ENUM("Capture to Headphone Mux", wm9713_enum
[1]),
765 AC97_SINGLE("Capture to Headphone Volume", AC97_VIDEO
, 11, 7, 1),
766 AC97_ENUM("Capture to Mono Mux", wm9713_enum
[2]),
767 AC97_SINGLE("Capture to Mono Boost (+20dB) Switch", AC97_VIDEO
, 8, 1, 0),
768 AC97_SINGLE("Capture ADC Boost (+20dB) Switch", AC97_VIDEO
, 6, 1, 0),
769 AC97_ENUM("Capture Select", wm9713_enum
[3]),
771 AC97_SINGLE("ALC Target Volume", AC97_CODEC_CLASS_REV
, 12, 15, 0),
772 AC97_SINGLE("ALC Hold Time", AC97_CODEC_CLASS_REV
, 8, 15, 0),
773 AC97_SINGLE("ALC Decay Time ", AC97_CODEC_CLASS_REV
, 4, 15, 0),
774 AC97_SINGLE("ALC Attack Time", AC97_CODEC_CLASS_REV
, 0, 15, 0),
775 AC97_ENUM("ALC Function", wm9713_enum
[5]),
776 AC97_SINGLE("ALC Max Volume", AC97_PCI_SVID
, 11, 7, 0),
777 AC97_SINGLE("ALC ZC Timeout", AC97_PCI_SVID
, 9, 3, 0),
778 AC97_SINGLE("ALC ZC Switch", AC97_PCI_SVID
, 8, 1, 0),
779 AC97_SINGLE("ALC NG Switch", AC97_PCI_SVID
, 7, 1, 0),
780 AC97_ENUM("ALC NG Type", wm9713_enum
[13]),
781 AC97_SINGLE("ALC NG Threshold", AC97_PCI_SVID
, 0, 31, 0),
783 AC97_DOUBLE("Master ZC Switch", AC97_MASTER
, 14, 6, 1, 0),
784 AC97_DOUBLE("Headphone ZC Switch", AC97_HEADPHONE
, 14, 6, 1, 0),
785 AC97_DOUBLE("Out3/4 ZC Switch", AC97_MASTER_MONO
, 14, 6, 1, 0),
786 AC97_SINGLE("Master Right Switch", AC97_MASTER
, 7, 1, 1),
787 AC97_SINGLE("Headphone Right Switch", AC97_HEADPHONE
, 7, 1, 1),
788 AC97_SINGLE("Out3/4 Right Switch", AC97_MASTER_MONO
, 7, 1, 1),
790 AC97_SINGLE("Mono In to Headphone Switch", AC97_MASTER_TONE
, 15, 1, 1),
791 AC97_SINGLE("Mono In to Master Switch", AC97_MASTER_TONE
, 14, 1, 1),
792 AC97_SINGLE("Mono In Volume", AC97_MASTER_TONE
, 8, 31, 1),
793 AC97_SINGLE("Mono Switch", AC97_MASTER_TONE
, 7, 1, 1),
794 AC97_SINGLE("Mono ZC Switch", AC97_MASTER_TONE
, 6, 1, 0),
795 AC97_SINGLE("Mono Volume", AC97_MASTER_TONE
, 0, 31, 1),
797 AC97_SINGLE("Beep to Headphone Switch", AC97_AUX
, 15, 1, 1),
798 AC97_SINGLE("Beep to Headphone Volume", AC97_AUX
, 12, 7, 1),
799 AC97_SINGLE("Beep to Master Switch", AC97_AUX
, 11, 1, 1),
800 AC97_SINGLE("Beep to Master Volume", AC97_AUX
, 8, 7, 1),
801 AC97_SINGLE("Beep to Mono Switch", AC97_AUX
, 7, 1, 1),
802 AC97_SINGLE("Beep to Mono Volume", AC97_AUX
, 4, 7, 1),
804 AC97_SINGLE("Voice to Headphone Switch", AC97_PCM
, 15, 1, 1),
805 AC97_SINGLE("Voice to Headphone Volume", AC97_PCM
, 12, 7, 1),
806 AC97_SINGLE("Voice to Master Switch", AC97_PCM
, 11, 1, 1),
807 AC97_SINGLE("Voice to Master Volume", AC97_PCM
, 8, 7, 1),
808 AC97_SINGLE("Voice to Mono Switch", AC97_PCM
, 7, 1, 1),
809 AC97_SINGLE("Voice to Mono Volume", AC97_PCM
, 4, 7, 1),
811 AC97_SINGLE("Aux to Headphone Switch", AC97_REC_SEL
, 15, 1, 1),
812 AC97_SINGLE("Aux to Headphone Volume", AC97_REC_SEL
, 12, 7, 1),
813 AC97_SINGLE("Aux to Master Switch", AC97_REC_SEL
, 11, 1, 1),
814 AC97_SINGLE("Aux to Master Volume", AC97_REC_SEL
, 8, 7, 1),
815 AC97_SINGLE("Aux to Mono Switch", AC97_REC_SEL
, 7, 1, 1),
816 AC97_SINGLE("Aux to Mono Volume", AC97_REC_SEL
, 4, 7, 1),
818 AC97_ENUM("Mono Input Mux", wm9713_enum
[6]),
819 AC97_ENUM("Master Input Mux", wm9713_enum
[7]),
820 AC97_ENUM("Headphone Input Mux", wm9713_enum
[8]),
821 AC97_ENUM("Out 3 Input Mux", wm9713_enum
[9]),
822 AC97_ENUM("Out 4 Input Mux", wm9713_enum
[10]),
824 AC97_ENUM("Bass Control", wm9713_enum
[12]),
825 AC97_SINGLE("Bass Cut-off Switch", AC97_GENERAL_PURPOSE
, 12, 1, 1),
826 AC97_SINGLE("Tone Cut-off Switch", AC97_GENERAL_PURPOSE
, 4, 1, 1),
827 AC97_SINGLE("Playback Attenuate (-6dB) Switch", AC97_GENERAL_PURPOSE
, 6, 1, 0),
828 AC97_SINGLE("Bass Volume", AC97_GENERAL_PURPOSE
, 8, 15, 1),
829 AC97_SINGLE("Tone Volume", AC97_GENERAL_PURPOSE
, 0, 15, 1),
832 static const struct snd_kcontrol_new wm13_snd_ac97_controls_3d
[] = {
833 AC97_ENUM("Inv Input Mux", wm9713_enum
[11]),
834 AC97_SINGLE("3D Upper Cut-off Switch", AC97_REC_GAIN_MIC
, 5, 1, 0),
835 AC97_SINGLE("3D Lower Cut-off Switch", AC97_REC_GAIN_MIC
, 4, 1, 0),
836 AC97_SINGLE("3D Depth", AC97_REC_GAIN_MIC
, 0, 15, 1),
839 static int patch_wolfson_wm9713_3d (struct snd_ac97
* ac97
)
843 for (i
= 0; i
< ARRAY_SIZE(wm13_snd_ac97_controls_3d
); i
++) {
844 if ((err
= snd_ctl_add(ac97
->bus
->card
, snd_ac97_cnew(&wm13_snd_ac97_controls_3d
[i
], ac97
))) < 0)
850 static int patch_wolfson_wm9713_specific(struct snd_ac97
* ac97
)
854 for (i
= 0; i
< ARRAY_SIZE(wm13_snd_ac97_controls
); i
++) {
855 if ((err
= snd_ctl_add(ac97
->bus
->card
, snd_ac97_cnew(&wm13_snd_ac97_controls
[i
], ac97
))) < 0)
858 snd_ac97_write_cache(ac97
, AC97_PC_BEEP
, 0x0808);
859 snd_ac97_write_cache(ac97
, AC97_PHONE
, 0x0808);
860 snd_ac97_write_cache(ac97
, AC97_MIC
, 0x0808);
861 snd_ac97_write_cache(ac97
, AC97_LINE
, 0x00da);
862 snd_ac97_write_cache(ac97
, AC97_CD
, 0x0808);
863 snd_ac97_write_cache(ac97
, AC97_VIDEO
, 0xd612);
864 snd_ac97_write_cache(ac97
, AC97_REC_GAIN
, 0x1ba0);
869 static void patch_wolfson_wm9713_suspend (struct snd_ac97
* ac97
)
871 snd_ac97_write_cache(ac97
, AC97_EXTENDED_MID
, 0xfeff);
872 snd_ac97_write_cache(ac97
, AC97_EXTENDED_MSTATUS
, 0xffff);
875 static void patch_wolfson_wm9713_resume (struct snd_ac97
* ac97
)
877 snd_ac97_write_cache(ac97
, AC97_EXTENDED_MID
, 0xda00);
878 snd_ac97_write_cache(ac97
, AC97_EXTENDED_MSTATUS
, 0x3810);
879 snd_ac97_write_cache(ac97
, AC97_POWERDOWN
, 0x0);
883 static const struct snd_ac97_build_ops patch_wolfson_wm9713_ops
= {
884 .build_specific
= patch_wolfson_wm9713_specific
,
885 .build_3d
= patch_wolfson_wm9713_3d
,
887 .suspend
= patch_wolfson_wm9713_suspend
,
888 .resume
= patch_wolfson_wm9713_resume
892 static int patch_wolfson13(struct snd_ac97
* ac97
)
895 ac97
->build_ops
= &patch_wolfson_wm9713_ops
;
897 ac97
->flags
|= AC97_HAS_NO_REC_GAIN
| AC97_STEREO_MUTES
| AC97_HAS_NO_PHONE
|
898 AC97_HAS_NO_PC_BEEP
| AC97_HAS_NO_VIDEO
| AC97_HAS_NO_CD
| AC97_HAS_NO_TONE
|
900 ac97
->scaps
&= ~AC97_SCAP_MODEM
;
902 snd_ac97_write_cache(ac97
, AC97_EXTENDED_MID
, 0xda00);
903 snd_ac97_write_cache(ac97
, AC97_EXTENDED_MSTATUS
, 0x3810);
904 snd_ac97_write_cache(ac97
, AC97_POWERDOWN
, 0x0);
912 static int patch_tritech_tr28028(struct snd_ac97
* ac97
)
914 snd_ac97_write_cache(ac97
, 0x26, 0x0300);
915 snd_ac97_write_cache(ac97
, 0x26, 0x0000);
916 snd_ac97_write_cache(ac97
, AC97_SURROUND_MASTER
, 0x0000);
917 snd_ac97_write_cache(ac97
, AC97_SPDIF
, 0x0000);
922 * Sigmatel STAC97xx codecs
924 static int patch_sigmatel_stac9700_3d(struct snd_ac97
* ac97
)
926 struct snd_kcontrol
*kctl
;
929 if ((err
= snd_ctl_add(ac97
->bus
->card
, kctl
= snd_ac97_cnew(&snd_ac97_controls_3d
[0], ac97
))) < 0)
931 strcpy(kctl
->id
.name
, "3D Control Sigmatel - Depth");
932 kctl
->private_value
= AC97_SINGLE_VALUE(AC97_3D_CONTROL
, 2, 3, 0);
933 snd_ac97_write_cache(ac97
, AC97_3D_CONTROL
, 0x0000);
937 static int patch_sigmatel_stac9708_3d(struct snd_ac97
* ac97
)
939 struct snd_kcontrol
*kctl
;
942 if ((err
= snd_ctl_add(ac97
->bus
->card
, kctl
= snd_ac97_cnew(&snd_ac97_controls_3d
[0], ac97
))) < 0)
944 strcpy(kctl
->id
.name
, "3D Control Sigmatel - Depth");
945 kctl
->private_value
= AC97_SINGLE_VALUE(AC97_3D_CONTROL
, 0, 3, 0);
946 if ((err
= snd_ctl_add(ac97
->bus
->card
, kctl
= snd_ac97_cnew(&snd_ac97_controls_3d
[0], ac97
))) < 0)
948 strcpy(kctl
->id
.name
, "3D Control Sigmatel - Rear Depth");
949 kctl
->private_value
= AC97_SINGLE_VALUE(AC97_3D_CONTROL
, 2, 3, 0);
950 snd_ac97_write_cache(ac97
, AC97_3D_CONTROL
, 0x0000);
954 static const struct snd_kcontrol_new snd_ac97_sigmatel_4speaker
=
955 AC97_SINGLE("Sigmatel 4-Speaker Stereo Playback Switch",
956 AC97_SIGMATEL_DAC2INVERT
, 2, 1, 0);
958 /* "Sigmatel " removed due to excessive name length: */
959 static const struct snd_kcontrol_new snd_ac97_sigmatel_phaseinvert
=
960 AC97_SINGLE("Surround Phase Inversion Playback Switch",
961 AC97_SIGMATEL_DAC2INVERT
, 3, 1, 0);
963 static const struct snd_kcontrol_new snd_ac97_sigmatel_controls
[] = {
964 AC97_SINGLE("Sigmatel DAC 6dB Attenuate", AC97_SIGMATEL_ANALOG
, 1, 1, 0),
965 AC97_SINGLE("Sigmatel ADC 6dB Attenuate", AC97_SIGMATEL_ANALOG
, 0, 1, 0)
968 static int patch_sigmatel_stac97xx_specific(struct snd_ac97
* ac97
)
972 snd_ac97_write_cache(ac97
, AC97_SIGMATEL_ANALOG
, snd_ac97_read(ac97
, AC97_SIGMATEL_ANALOG
) & ~0x0003);
973 if (snd_ac97_try_bit(ac97
, AC97_SIGMATEL_ANALOG
, 1))
974 if ((err
= patch_build_controls(ac97
, &snd_ac97_sigmatel_controls
[0], 1)) < 0)
976 if (snd_ac97_try_bit(ac97
, AC97_SIGMATEL_ANALOG
, 0))
977 if ((err
= patch_build_controls(ac97
, &snd_ac97_sigmatel_controls
[1], 1)) < 0)
979 if (snd_ac97_try_bit(ac97
, AC97_SIGMATEL_DAC2INVERT
, 2))
980 if ((err
= patch_build_controls(ac97
, &snd_ac97_sigmatel_4speaker
, 1)) < 0)
982 if (snd_ac97_try_bit(ac97
, AC97_SIGMATEL_DAC2INVERT
, 3))
983 if ((err
= patch_build_controls(ac97
, &snd_ac97_sigmatel_phaseinvert
, 1)) < 0)
988 static const struct snd_ac97_build_ops patch_sigmatel_stac9700_ops
= {
989 .build_3d
= patch_sigmatel_stac9700_3d
,
990 .build_specific
= patch_sigmatel_stac97xx_specific
993 static int patch_sigmatel_stac9700(struct snd_ac97
* ac97
)
995 ac97
->build_ops
= &patch_sigmatel_stac9700_ops
;
999 static int snd_ac97_stac9708_put_bias(struct snd_kcontrol
*kcontrol
, struct snd_ctl_elem_value
*ucontrol
)
1001 struct snd_ac97
*ac97
= snd_kcontrol_chip(kcontrol
);
1004 mutex_lock(&ac97
->page_mutex
);
1005 snd_ac97_write(ac97
, AC97_SIGMATEL_BIAS1
, 0xabba);
1006 err
= snd_ac97_update_bits(ac97
, AC97_SIGMATEL_BIAS2
, 0x0010,
1007 (ucontrol
->value
.integer
.value
[0] & 1) << 4);
1008 snd_ac97_write(ac97
, AC97_SIGMATEL_BIAS1
, 0);
1009 mutex_unlock(&ac97
->page_mutex
);
1013 static const struct snd_kcontrol_new snd_ac97_stac9708_bias_control
= {
1014 .iface
= SNDRV_CTL_ELEM_IFACE_MIXER
,
1015 .name
= "Sigmatel Output Bias Switch",
1016 .info
= snd_ac97_info_volsw
,
1017 .get
= snd_ac97_get_volsw
,
1018 .put
= snd_ac97_stac9708_put_bias
,
1019 .private_value
= AC97_SINGLE_VALUE(AC97_SIGMATEL_BIAS2
, 4, 1, 0),
1022 static int patch_sigmatel_stac9708_specific(struct snd_ac97
*ac97
)
1026 /* the register bit is writable, but the function is not implemented: */
1027 snd_ac97_remove_ctl(ac97
, "PCM Out Path & Mute", NULL
);
1029 snd_ac97_rename_vol_ctl(ac97
, "Headphone Playback", "Sigmatel Surround Playback");
1030 if ((err
= patch_build_controls(ac97
, &snd_ac97_stac9708_bias_control
, 1)) < 0)
1032 return patch_sigmatel_stac97xx_specific(ac97
);
1035 static const struct snd_ac97_build_ops patch_sigmatel_stac9708_ops
= {
1036 .build_3d
= patch_sigmatel_stac9708_3d
,
1037 .build_specific
= patch_sigmatel_stac9708_specific
1040 static int patch_sigmatel_stac9708(struct snd_ac97
* ac97
)
1042 unsigned int codec72
, codec6c
;
1044 ac97
->build_ops
= &patch_sigmatel_stac9708_ops
;
1045 ac97
->caps
|= 0x10; /* HP (sigmatel surround) support */
1047 codec72
= snd_ac97_read(ac97
, AC97_SIGMATEL_BIAS2
) & 0x8000;
1048 codec6c
= snd_ac97_read(ac97
, AC97_SIGMATEL_ANALOG
);
1050 if ((codec72
==0) && (codec6c
==0)) {
1051 snd_ac97_write_cache(ac97
, AC97_SIGMATEL_CIC1
, 0xabba);
1052 snd_ac97_write_cache(ac97
, AC97_SIGMATEL_CIC2
, 0x1000);
1053 snd_ac97_write_cache(ac97
, AC97_SIGMATEL_BIAS1
, 0xabba);
1054 snd_ac97_write_cache(ac97
, AC97_SIGMATEL_BIAS2
, 0x0007);
1055 } else if ((codec72
==0x8000) && (codec6c
==0)) {
1056 snd_ac97_write_cache(ac97
, AC97_SIGMATEL_CIC1
, 0xabba);
1057 snd_ac97_write_cache(ac97
, AC97_SIGMATEL_CIC2
, 0x1001);
1058 snd_ac97_write_cache(ac97
, AC97_SIGMATEL_DAC2INVERT
, 0x0008);
1059 } else if ((codec72
==0x8000) && (codec6c
==0x0080)) {
1062 snd_ac97_write_cache(ac97
, AC97_SIGMATEL_MULTICHN
, 0x0000);
1066 static int patch_sigmatel_stac9721(struct snd_ac97
* ac97
)
1068 ac97
->build_ops
= &patch_sigmatel_stac9700_ops
;
1069 if (snd_ac97_read(ac97
, AC97_SIGMATEL_ANALOG
) == 0) {
1070 // patch for SigmaTel
1071 snd_ac97_write_cache(ac97
, AC97_SIGMATEL_CIC1
, 0xabba);
1072 snd_ac97_write_cache(ac97
, AC97_SIGMATEL_CIC2
, 0x4000);
1073 snd_ac97_write_cache(ac97
, AC97_SIGMATEL_BIAS1
, 0xabba);
1074 snd_ac97_write_cache(ac97
, AC97_SIGMATEL_BIAS2
, 0x0002);
1076 snd_ac97_write_cache(ac97
, AC97_SIGMATEL_MULTICHN
, 0x0000);
1080 static int patch_sigmatel_stac9744(struct snd_ac97
* ac97
)
1082 // patch for SigmaTel
1083 ac97
->build_ops
= &patch_sigmatel_stac9700_ops
;
1084 snd_ac97_write_cache(ac97
, AC97_SIGMATEL_CIC1
, 0xabba);
1085 snd_ac97_write_cache(ac97
, AC97_SIGMATEL_CIC2
, 0x0000); /* is this correct? --jk */
1086 snd_ac97_write_cache(ac97
, AC97_SIGMATEL_BIAS1
, 0xabba);
1087 snd_ac97_write_cache(ac97
, AC97_SIGMATEL_BIAS2
, 0x0002);
1088 snd_ac97_write_cache(ac97
, AC97_SIGMATEL_MULTICHN
, 0x0000);
1092 static int patch_sigmatel_stac9756(struct snd_ac97
* ac97
)
1094 // patch for SigmaTel
1095 ac97
->build_ops
= &patch_sigmatel_stac9700_ops
;
1096 snd_ac97_write_cache(ac97
, AC97_SIGMATEL_CIC1
, 0xabba);
1097 snd_ac97_write_cache(ac97
, AC97_SIGMATEL_CIC2
, 0x0000); /* is this correct? --jk */
1098 snd_ac97_write_cache(ac97
, AC97_SIGMATEL_BIAS1
, 0xabba);
1099 snd_ac97_write_cache(ac97
, AC97_SIGMATEL_BIAS2
, 0x0002);
1100 snd_ac97_write_cache(ac97
, AC97_SIGMATEL_MULTICHN
, 0x0000);
1104 static int snd_ac97_stac9758_output_jack_info(struct snd_kcontrol
*kcontrol
, struct snd_ctl_elem_info
*uinfo
)
1106 static char *texts
[5] = { "Input/Disabled", "Front Output",
1107 "Rear Output", "Center/LFE Output", "Mixer Output" };
1109 uinfo
->type
= SNDRV_CTL_ELEM_TYPE_ENUMERATED
;
1111 uinfo
->value
.enumerated
.items
= 5;
1112 if (uinfo
->value
.enumerated
.item
> 4)
1113 uinfo
->value
.enumerated
.item
= 4;
1114 strcpy(uinfo
->value
.enumerated
.name
, texts
[uinfo
->value
.enumerated
.item
]);
1118 static int snd_ac97_stac9758_output_jack_get(struct snd_kcontrol
*kcontrol
, struct snd_ctl_elem_value
*ucontrol
)
1120 struct snd_ac97
*ac97
= snd_kcontrol_chip(kcontrol
);
1121 int shift
= kcontrol
->private_value
;
1124 val
= ac97
->regs
[AC97_SIGMATEL_OUTSEL
] >> shift
;
1126 ucontrol
->value
.enumerated
.item
[0] = 0;
1128 ucontrol
->value
.enumerated
.item
[0] = 1 + (val
& 3);
1132 static int snd_ac97_stac9758_output_jack_put(struct snd_kcontrol
*kcontrol
, struct snd_ctl_elem_value
*ucontrol
)
1134 struct snd_ac97
*ac97
= snd_kcontrol_chip(kcontrol
);
1135 int shift
= kcontrol
->private_value
;
1138 if (ucontrol
->value
.enumerated
.item
[0] > 4)
1140 if (ucontrol
->value
.enumerated
.item
[0] == 0)
1143 val
= 4 | (ucontrol
->value
.enumerated
.item
[0] - 1);
1144 return ac97_update_bits_page(ac97
, AC97_SIGMATEL_OUTSEL
,
1145 7 << shift
, val
<< shift
, 0);
1148 static int snd_ac97_stac9758_input_jack_info(struct snd_kcontrol
*kcontrol
, struct snd_ctl_elem_info
*uinfo
)
1150 static char *texts
[7] = { "Mic2 Jack", "Mic1 Jack", "Line In Jack",
1151 "Front Jack", "Rear Jack", "Center/LFE Jack", "Mute" };
1153 uinfo
->type
= SNDRV_CTL_ELEM_TYPE_ENUMERATED
;
1155 uinfo
->value
.enumerated
.items
= 7;
1156 if (uinfo
->value
.enumerated
.item
> 6)
1157 uinfo
->value
.enumerated
.item
= 6;
1158 strcpy(uinfo
->value
.enumerated
.name
, texts
[uinfo
->value
.enumerated
.item
]);
1162 static int snd_ac97_stac9758_input_jack_get(struct snd_kcontrol
*kcontrol
, struct snd_ctl_elem_value
*ucontrol
)
1164 struct snd_ac97
*ac97
= snd_kcontrol_chip(kcontrol
);
1165 int shift
= kcontrol
->private_value
;
1168 val
= ac97
->regs
[AC97_SIGMATEL_INSEL
];
1169 ucontrol
->value
.enumerated
.item
[0] = (val
>> shift
) & 7;
1173 static int snd_ac97_stac9758_input_jack_put(struct snd_kcontrol
*kcontrol
, struct snd_ctl_elem_value
*ucontrol
)
1175 struct snd_ac97
*ac97
= snd_kcontrol_chip(kcontrol
);
1176 int shift
= kcontrol
->private_value
;
1178 return ac97_update_bits_page(ac97
, AC97_SIGMATEL_INSEL
, 7 << shift
,
1179 ucontrol
->value
.enumerated
.item
[0] << shift
, 0);
1182 static int snd_ac97_stac9758_phonesel_info(struct snd_kcontrol
*kcontrol
, struct snd_ctl_elem_info
*uinfo
)
1184 static char *texts
[3] = { "None", "Front Jack", "Rear Jack" };
1186 uinfo
->type
= SNDRV_CTL_ELEM_TYPE_ENUMERATED
;
1188 uinfo
->value
.enumerated
.items
= 3;
1189 if (uinfo
->value
.enumerated
.item
> 2)
1190 uinfo
->value
.enumerated
.item
= 2;
1191 strcpy(uinfo
->value
.enumerated
.name
, texts
[uinfo
->value
.enumerated
.item
]);
1195 static int snd_ac97_stac9758_phonesel_get(struct snd_kcontrol
*kcontrol
, struct snd_ctl_elem_value
*ucontrol
)
1197 struct snd_ac97
*ac97
= snd_kcontrol_chip(kcontrol
);
1199 ucontrol
->value
.enumerated
.item
[0] = ac97
->regs
[AC97_SIGMATEL_IOMISC
] & 3;
1203 static int snd_ac97_stac9758_phonesel_put(struct snd_kcontrol
*kcontrol
, struct snd_ctl_elem_value
*ucontrol
)
1205 struct snd_ac97
*ac97
= snd_kcontrol_chip(kcontrol
);
1207 return ac97_update_bits_page(ac97
, AC97_SIGMATEL_IOMISC
, 3,
1208 ucontrol
->value
.enumerated
.item
[0], 0);
1211 #define STAC9758_OUTPUT_JACK(xname, shift) \
1212 { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, \
1213 .info = snd_ac97_stac9758_output_jack_info, \
1214 .get = snd_ac97_stac9758_output_jack_get, \
1215 .put = snd_ac97_stac9758_output_jack_put, \
1216 .private_value = shift }
1217 #define STAC9758_INPUT_JACK(xname, shift) \
1218 { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, \
1219 .info = snd_ac97_stac9758_input_jack_info, \
1220 .get = snd_ac97_stac9758_input_jack_get, \
1221 .put = snd_ac97_stac9758_input_jack_put, \
1222 .private_value = shift }
1223 static const struct snd_kcontrol_new snd_ac97_sigmatel_stac9758_controls
[] = {
1224 STAC9758_OUTPUT_JACK("Mic1 Jack", 1),
1225 STAC9758_OUTPUT_JACK("LineIn Jack", 4),
1226 STAC9758_OUTPUT_JACK("Front Jack", 7),
1227 STAC9758_OUTPUT_JACK("Rear Jack", 10),
1228 STAC9758_OUTPUT_JACK("Center/LFE Jack", 13),
1229 STAC9758_INPUT_JACK("Mic Input Source", 0),
1230 STAC9758_INPUT_JACK("Line Input Source", 8),
1232 .iface
= SNDRV_CTL_ELEM_IFACE_MIXER
,
1233 .name
= "Headphone Amp",
1234 .info
= snd_ac97_stac9758_phonesel_info
,
1235 .get
= snd_ac97_stac9758_phonesel_get
,
1236 .put
= snd_ac97_stac9758_phonesel_put
1238 AC97_SINGLE("Exchange Center/LFE", AC97_SIGMATEL_IOMISC
, 4, 1, 0),
1239 AC97_SINGLE("Headphone +3dB Boost", AC97_SIGMATEL_IOMISC
, 8, 1, 0)
1242 static int patch_sigmatel_stac9758_specific(struct snd_ac97
*ac97
)
1246 err
= patch_sigmatel_stac97xx_specific(ac97
);
1249 err
= patch_build_controls(ac97
, snd_ac97_sigmatel_stac9758_controls
,
1250 ARRAY_SIZE(snd_ac97_sigmatel_stac9758_controls
));
1254 snd_ac97_rename_vol_ctl(ac97
, "Headphone Playback", "Front Playback");
1255 /* DAC-A to Mix = PCM */
1256 /* DAC-B direct = Surround */
1258 snd_ac97_rename_vol_ctl(ac97
, "Video Playback", "Surround Mix Playback");
1259 /* DAC-C direct = Center/LFE */
1264 static const struct snd_ac97_build_ops patch_sigmatel_stac9758_ops
= {
1265 .build_3d
= patch_sigmatel_stac9700_3d
,
1266 .build_specific
= patch_sigmatel_stac9758_specific
1269 static int patch_sigmatel_stac9758(struct snd_ac97
* ac97
)
1271 static unsigned short regs
[4] = {
1272 AC97_SIGMATEL_OUTSEL
,
1273 AC97_SIGMATEL_IOMISC
,
1274 AC97_SIGMATEL_INSEL
,
1275 AC97_SIGMATEL_VARIOUS
1277 static unsigned short def_regs
[4] = {
1278 /* OUTSEL */ 0xd794, /* CL:CL, SR:SR, LO:MX, LI:DS, MI:DS */
1279 /* IOMISC */ 0x2001,
1280 /* INSEL */ 0x0201, /* LI:LI, MI:M1 */
1281 /* VARIOUS */ 0x0040
1283 static unsigned short m675_regs
[4] = {
1284 /* OUTSEL */ 0xfc70, /* CL:MX, SR:MX, LO:DS, LI:MX, MI:DS */
1285 /* IOMISC */ 0x2102, /* HP amp on */
1286 /* INSEL */ 0x0203, /* LI:LI, MI:FR */
1287 /* VARIOUS */ 0x0041 /* stereo mic */
1289 unsigned short *pregs
= def_regs
;
1292 /* Gateway M675 notebook */
1294 ac97
->subsystem_vendor
== 0x107b &&
1295 ac97
->subsystem_device
== 0x0601)
1298 // patch for SigmaTel
1299 ac97
->build_ops
= &patch_sigmatel_stac9758_ops
;
1300 /* FIXME: assume only page 0 for writing cache */
1301 snd_ac97_update_bits(ac97
, AC97_INT_PAGING
, AC97_PAGE_MASK
, AC97_PAGE_VENDOR
);
1302 for (i
= 0; i
< 4; i
++)
1303 snd_ac97_write_cache(ac97
, regs
[i
], pregs
[i
]);
1305 ac97
->flags
|= AC97_STEREO_MUTES
;
1310 * Cirrus Logic CS42xx codecs
1312 static const struct snd_kcontrol_new snd_ac97_cirrus_controls_spdif
[2] = {
1313 AC97_SINGLE(SNDRV_CTL_NAME_IEC958("",PLAYBACK
,SWITCH
), AC97_CSR_SPDIF
, 15, 1, 0),
1314 AC97_SINGLE(SNDRV_CTL_NAME_IEC958("",PLAYBACK
,NONE
) "AC97-SPSA", AC97_CSR_ACMODE
, 0, 3, 0)
1317 static int patch_cirrus_build_spdif(struct snd_ac97
* ac97
)
1321 /* con mask, pro mask, default */
1322 if ((err
= patch_build_controls(ac97
, &snd_ac97_controls_spdif
[0], 3)) < 0)
1325 if ((err
= patch_build_controls(ac97
, &snd_ac97_cirrus_controls_spdif
[0], 1)) < 0)
1327 switch (ac97
->id
& AC97_ID_CS_MASK
) {
1328 case AC97_ID_CS4205
:
1329 if ((err
= patch_build_controls(ac97
, &snd_ac97_cirrus_controls_spdif
[1], 1)) < 0)
1333 /* set default PCM S/PDIF params */
1334 /* consumer,PCM audio,no copyright,no preemphasis,PCM coder,original,48000Hz */
1335 snd_ac97_write_cache(ac97
, AC97_CSR_SPDIF
, 0x0a20);
1339 static const struct snd_ac97_build_ops patch_cirrus_ops
= {
1340 .build_spdif
= patch_cirrus_build_spdif
1343 static int patch_cirrus_spdif(struct snd_ac97
* ac97
)
1345 /* Basically, the cs4201/cs4205/cs4297a has non-standard sp/dif registers.
1346 WHY CAN'T ANYONE FOLLOW THE BLOODY SPEC? *sigh*
1347 - sp/dif EA ID is not set, but sp/dif is always present.
1348 - enable/disable is spdif register bit 15.
1349 - sp/dif control register is 0x68. differs from AC97:
1350 - valid is bit 14 (vs 15)
1352 - only 44.1/48k [00 = 48, 01=44,1] (AC97 is 00=44.1, 10=48)
1353 - sp/dif ssource select is in 0x5e bits 0,1.
1356 ac97
->build_ops
= &patch_cirrus_ops
;
1357 ac97
->flags
|= AC97_CS_SPDIF
;
1358 ac97
->rates
[AC97_RATES_SPDIF
] &= ~SNDRV_PCM_RATE_32000
;
1359 ac97
->ext_id
|= AC97_EI_SPDIF
; /* force the detection of spdif */
1360 snd_ac97_write_cache(ac97
, AC97_CSR_ACMODE
, 0x0080);
1364 static int patch_cirrus_cs4299(struct snd_ac97
* ac97
)
1366 /* force the detection of PC Beep */
1367 ac97
->flags
|= AC97_HAS_PC_BEEP
;
1369 return patch_cirrus_spdif(ac97
);
1375 static const struct snd_kcontrol_new snd_ac97_conexant_controls_spdif
[1] = {
1376 AC97_SINGLE(SNDRV_CTL_NAME_IEC958("",PLAYBACK
,SWITCH
), AC97_CXR_AUDIO_MISC
, 3, 1, 0),
1379 static int patch_conexant_build_spdif(struct snd_ac97
* ac97
)
1383 /* con mask, pro mask, default */
1384 if ((err
= patch_build_controls(ac97
, &snd_ac97_controls_spdif
[0], 3)) < 0)
1387 if ((err
= patch_build_controls(ac97
, &snd_ac97_conexant_controls_spdif
[0], 1)) < 0)
1389 /* set default PCM S/PDIF params */
1390 /* consumer,PCM audio,no copyright,no preemphasis,PCM coder,original,48000Hz */
1391 snd_ac97_write_cache(ac97
, AC97_CXR_AUDIO_MISC
,
1392 snd_ac97_read(ac97
, AC97_CXR_AUDIO_MISC
) & ~(AC97_CXR_SPDIFEN
|AC97_CXR_COPYRGT
|AC97_CXR_SPDIF_MASK
));
1396 static const struct snd_ac97_build_ops patch_conexant_ops
= {
1397 .build_spdif
= patch_conexant_build_spdif
1400 static int patch_conexant(struct snd_ac97
* ac97
)
1402 ac97
->build_ops
= &patch_conexant_ops
;
1403 ac97
->flags
|= AC97_CX_SPDIF
;
1404 ac97
->ext_id
|= AC97_EI_SPDIF
; /* force the detection of spdif */
1405 ac97
->rates
[AC97_RATES_SPDIF
] = SNDRV_PCM_RATE_48000
; /* 48k only */
1409 static int patch_cx20551(struct snd_ac97
*ac97
)
1411 snd_ac97_update_bits(ac97
, 0x5c, 0x01, 0x01);
1416 * Analog Device AD18xx, AD19xx codecs
1419 static void ad18xx_resume(struct snd_ac97
*ac97
)
1421 static unsigned short setup_regs
[] = {
1422 AC97_AD_MISC
, AC97_AD_SERIAL_CFG
, AC97_AD_JACK_SPDIF
,
1426 for (i
= 0; i
< (int)ARRAY_SIZE(setup_regs
); i
++) {
1427 unsigned short reg
= setup_regs
[i
];
1428 if (test_bit(reg
, ac97
->reg_accessed
)) {
1429 snd_ac97_write(ac97
, reg
, ac97
->regs
[reg
]);
1430 snd_ac97_read(ac97
, reg
);
1434 if (! (ac97
->flags
& AC97_AD_MULTI
))
1435 /* normal restore */
1436 snd_ac97_restore_status(ac97
);
1438 /* restore the AD18xx codec configurations */
1439 for (codec
= 0; codec
< 3; codec
++) {
1440 if (! ac97
->spec
.ad18xx
.id
[codec
])
1442 /* select single codec */
1443 snd_ac97_update_bits(ac97
, AC97_AD_SERIAL_CFG
, 0x7000,
1444 ac97
->spec
.ad18xx
.unchained
[codec
] | ac97
->spec
.ad18xx
.chained
[codec
]);
1445 ac97
->bus
->ops
->write(ac97
, AC97_AD_CODEC_CFG
, ac97
->spec
.ad18xx
.codec_cfg
[codec
]);
1447 /* select all codecs */
1448 snd_ac97_update_bits(ac97
, AC97_AD_SERIAL_CFG
, 0x7000, 0x7000);
1450 /* restore status */
1451 for (i
= 2; i
< 0x7c ; i
+= 2) {
1452 if (i
== AC97_POWERDOWN
|| i
== AC97_EXTENDED_ID
)
1454 if (test_bit(i
, ac97
->reg_accessed
)) {
1455 /* handle multi codecs for AD18xx */
1456 if (i
== AC97_PCM
) {
1457 for (codec
= 0; codec
< 3; codec
++) {
1458 if (! ac97
->spec
.ad18xx
.id
[codec
])
1460 /* select single codec */
1461 snd_ac97_update_bits(ac97
, AC97_AD_SERIAL_CFG
, 0x7000,
1462 ac97
->spec
.ad18xx
.unchained
[codec
] | ac97
->spec
.ad18xx
.chained
[codec
]);
1463 /* update PCM bits */
1464 ac97
->bus
->ops
->write(ac97
, AC97_PCM
, ac97
->spec
.ad18xx
.pcmreg
[codec
]);
1466 /* select all codecs */
1467 snd_ac97_update_bits(ac97
, AC97_AD_SERIAL_CFG
, 0x7000, 0x7000);
1469 } else if (i
== AC97_AD_TEST
||
1470 i
== AC97_AD_CODEC_CFG
||
1471 i
== AC97_AD_SERIAL_CFG
)
1472 continue; /* ignore */
1474 snd_ac97_write(ac97
, i
, ac97
->regs
[i
]);
1475 snd_ac97_read(ac97
, i
);
1479 snd_ac97_restore_iec958(ac97
);
1482 static void ad1888_resume(struct snd_ac97
*ac97
)
1484 ad18xx_resume(ac97
);
1485 snd_ac97_write_cache(ac97
, AC97_CODEC_CLASS_REV
, 0x8080);
1490 static const struct snd_ac97_res_table ad1819_restbl
[] = {
1491 { AC97_PHONE
, 0x9f1f },
1492 { AC97_MIC
, 0x9f1f },
1493 { AC97_LINE
, 0x9f1f },
1494 { AC97_CD
, 0x9f1f },
1495 { AC97_VIDEO
, 0x9f1f },
1496 { AC97_AUX
, 0x9f1f },
1497 { AC97_PCM
, 0x9f1f },
1498 { } /* terminator */
1501 static int patch_ad1819(struct snd_ac97
* ac97
)
1503 unsigned short scfg
;
1505 // patch for Analog Devices
1506 scfg
= snd_ac97_read(ac97
, AC97_AD_SERIAL_CFG
);
1507 snd_ac97_write_cache(ac97
, AC97_AD_SERIAL_CFG
, scfg
| 0x7000); /* select all codecs */
1508 ac97
->res_table
= ad1819_restbl
;
1512 static unsigned short patch_ad1881_unchained(struct snd_ac97
* ac97
, int idx
, unsigned short mask
)
1516 // test for unchained codec
1517 snd_ac97_update_bits(ac97
, AC97_AD_SERIAL_CFG
, 0x7000, mask
);
1518 snd_ac97_write_cache(ac97
, AC97_AD_CODEC_CFG
, 0x0000); /* ID0C, ID1C, SDIE = off */
1519 val
= snd_ac97_read(ac97
, AC97_VENDOR_ID2
);
1520 if ((val
& 0xff40) != 0x5340)
1522 ac97
->spec
.ad18xx
.unchained
[idx
] = mask
;
1523 ac97
->spec
.ad18xx
.id
[idx
] = val
;
1524 ac97
->spec
.ad18xx
.codec_cfg
[idx
] = 0x0000;
1528 static int patch_ad1881_chained1(struct snd_ac97
* ac97
, int idx
, unsigned short codec_bits
)
1530 static int cfg_bits
[3] = { 1<<12, 1<<14, 1<<13 };
1533 snd_ac97_update_bits(ac97
, AC97_AD_SERIAL_CFG
, 0x7000, cfg_bits
[idx
]);
1534 snd_ac97_write_cache(ac97
, AC97_AD_CODEC_CFG
, 0x0004); // SDIE
1535 val
= snd_ac97_read(ac97
, AC97_VENDOR_ID2
);
1536 if ((val
& 0xff40) != 0x5340)
1539 snd_ac97_write_cache(ac97
, AC97_AD_CODEC_CFG
, codec_bits
);
1540 ac97
->spec
.ad18xx
.chained
[idx
] = cfg_bits
[idx
];
1541 ac97
->spec
.ad18xx
.id
[idx
] = val
;
1542 ac97
->spec
.ad18xx
.codec_cfg
[idx
] = codec_bits
? codec_bits
: 0x0004;
1546 static void patch_ad1881_chained(struct snd_ac97
* ac97
, int unchained_idx
, int cidx1
, int cidx2
)
1548 // already detected?
1549 if (ac97
->spec
.ad18xx
.unchained
[cidx1
] || ac97
->spec
.ad18xx
.chained
[cidx1
])
1551 if (ac97
->spec
.ad18xx
.unchained
[cidx2
] || ac97
->spec
.ad18xx
.chained
[cidx2
])
1553 if (cidx1
< 0 && cidx2
< 0)
1555 // test for chained codecs
1556 snd_ac97_update_bits(ac97
, AC97_AD_SERIAL_CFG
, 0x7000,
1557 ac97
->spec
.ad18xx
.unchained
[unchained_idx
]);
1558 snd_ac97_write_cache(ac97
, AC97_AD_CODEC_CFG
, 0x0002); // ID1C
1559 ac97
->spec
.ad18xx
.codec_cfg
[unchained_idx
] = 0x0002;
1562 patch_ad1881_chained1(ac97
, cidx1
, 0);
1563 else if (patch_ad1881_chained1(ac97
, cidx1
, 0x0006)) // SDIE | ID1C
1564 patch_ad1881_chained1(ac97
, cidx2
, 0);
1565 else if (patch_ad1881_chained1(ac97
, cidx2
, 0x0006)) // SDIE | ID1C
1566 patch_ad1881_chained1(ac97
, cidx1
, 0);
1567 } else if (cidx2
>= 0) {
1568 patch_ad1881_chained1(ac97
, cidx2
, 0);
1572 static const struct snd_ac97_build_ops patch_ad1881_build_ops
= {
1574 .resume
= ad18xx_resume
1578 static int patch_ad1881(struct snd_ac97
* ac97
)
1580 static const char cfg_idxs
[3][2] = {
1586 // patch for Analog Devices
1587 unsigned short codecs
[3];
1591 val
= snd_ac97_read(ac97
, AC97_AD_SERIAL_CFG
);
1592 snd_ac97_write_cache(ac97
, AC97_AD_SERIAL_CFG
, val
);
1593 codecs
[0] = patch_ad1881_unchained(ac97
, 0, (1<<12));
1594 codecs
[1] = patch_ad1881_unchained(ac97
, 1, (1<<14));
1595 codecs
[2] = patch_ad1881_unchained(ac97
, 2, (1<<13));
1597 if (! (codecs
[0] || codecs
[1] || codecs
[2]))
1600 for (idx
= 0; idx
< 3; idx
++)
1601 if (ac97
->spec
.ad18xx
.unchained
[idx
])
1602 patch_ad1881_chained(ac97
, idx
, cfg_idxs
[idx
][0], cfg_idxs
[idx
][1]);
1604 if (ac97
->spec
.ad18xx
.id
[1]) {
1605 ac97
->flags
|= AC97_AD_MULTI
;
1606 ac97
->scaps
|= AC97_SCAP_SURROUND_DAC
;
1608 if (ac97
->spec
.ad18xx
.id
[2]) {
1609 ac97
->flags
|= AC97_AD_MULTI
;
1610 ac97
->scaps
|= AC97_SCAP_CENTER_LFE_DAC
;
1614 /* select all codecs */
1615 snd_ac97_update_bits(ac97
, AC97_AD_SERIAL_CFG
, 0x7000, 0x7000);
1616 /* check if only one codec is present */
1617 for (idx
= num
= 0; idx
< 3; idx
++)
1618 if (ac97
->spec
.ad18xx
.id
[idx
])
1621 /* ok, deselect all ID bits */
1622 snd_ac97_write_cache(ac97
, AC97_AD_CODEC_CFG
, 0x0000);
1623 ac97
->spec
.ad18xx
.codec_cfg
[0] =
1624 ac97
->spec
.ad18xx
.codec_cfg
[1] =
1625 ac97
->spec
.ad18xx
.codec_cfg
[2] = 0x0000;
1627 /* required for AD1886/AD1885 combination */
1628 ac97
->ext_id
= snd_ac97_read(ac97
, AC97_EXTENDED_ID
);
1629 if (ac97
->spec
.ad18xx
.id
[0]) {
1630 ac97
->id
&= 0xffff0000;
1631 ac97
->id
|= ac97
->spec
.ad18xx
.id
[0];
1633 ac97
->build_ops
= &patch_ad1881_build_ops
;
1637 static const struct snd_kcontrol_new snd_ac97_controls_ad1885
[] = {
1638 AC97_SINGLE("Digital Mono Direct", AC97_AD_MISC
, 11, 1, 0),
1639 /* AC97_SINGLE("Digital Audio Mode", AC97_AD_MISC, 12, 1, 0), */ /* seems problematic */
1640 AC97_SINGLE("Low Power Mixer", AC97_AD_MISC
, 14, 1, 0),
1641 AC97_SINGLE("Zero Fill DAC", AC97_AD_MISC
, 15, 1, 0),
1642 AC97_SINGLE("Headphone Jack Sense", AC97_AD_JACK_SPDIF
, 9, 1, 1), /* inverted */
1643 AC97_SINGLE("Line Jack Sense", AC97_AD_JACK_SPDIF
, 8, 1, 1), /* inverted */
1646 static const DECLARE_TLV_DB_SCALE(db_scale_6bit_6db_max
, -8850, 150, 0);
1648 static int patch_ad1885_specific(struct snd_ac97
* ac97
)
1652 if ((err
= patch_build_controls(ac97
, snd_ac97_controls_ad1885
, ARRAY_SIZE(snd_ac97_controls_ad1885
))) < 0)
1654 reset_tlv(ac97
, "Headphone Playback Volume",
1655 db_scale_6bit_6db_max
);
1659 static const struct snd_ac97_build_ops patch_ad1885_build_ops
= {
1660 .build_specific
= &patch_ad1885_specific
,
1662 .resume
= ad18xx_resume
1666 static int patch_ad1885(struct snd_ac97
* ac97
)
1669 /* This is required to deal with the Intel D815EEAL2 */
1670 /* i.e. Line out is actually headphone out from codec */
1673 snd_ac97_write_cache(ac97
, AC97_AD_MISC
, 0x0404);
1675 ac97
->build_ops
= &patch_ad1885_build_ops
;
1679 static int patch_ad1886_specific(struct snd_ac97
* ac97
)
1681 reset_tlv(ac97
, "Headphone Playback Volume",
1682 db_scale_6bit_6db_max
);
1686 static const struct snd_ac97_build_ops patch_ad1886_build_ops
= {
1687 .build_specific
= &patch_ad1886_specific
,
1689 .resume
= ad18xx_resume
1693 static int patch_ad1886(struct snd_ac97
* ac97
)
1696 /* Presario700 workaround */
1697 /* for Jack Sense/SPDIF Register misetting causing */
1698 snd_ac97_write_cache(ac97
, AC97_AD_JACK_SPDIF
, 0x0010);
1699 ac97
->build_ops
= &patch_ad1886_build_ops
;
1703 /* MISC bits (AD1888/AD1980/AD1985 register 0x76) */
1704 #define AC97_AD198X_MBC 0x0003 /* mic boost */
1705 #define AC97_AD198X_MBC_20 0x0000 /* +20dB */
1706 #define AC97_AD198X_MBC_10 0x0001 /* +10dB */
1707 #define AC97_AD198X_MBC_30 0x0002 /* +30dB */
1708 #define AC97_AD198X_VREFD 0x0004 /* VREF high-Z */
1709 #define AC97_AD198X_VREFH 0x0008 /* 0=2.25V, 1=3.7V */
1710 #define AC97_AD198X_VREF_0 0x000c /* 0V (AD1985 only) */
1711 #define AC97_AD198X_VREF_MASK (AC97_AD198X_VREFH | AC97_AD198X_VREFD)
1712 #define AC97_AD198X_VREF_SHIFT 2
1713 #define AC97_AD198X_SRU 0x0010 /* sample rate unlock */
1714 #define AC97_AD198X_LOSEL 0x0020 /* LINE_OUT amplifiers input select */
1715 #define AC97_AD198X_2MIC 0x0040 /* 2-channel mic select */
1716 #define AC97_AD198X_SPRD 0x0080 /* SPREAD enable */
1717 #define AC97_AD198X_DMIX0 0x0100 /* downmix mode: */
1718 /* 0 = 6-to-4, 1 = 6-to-2 downmix */
1719 #define AC97_AD198X_DMIX1 0x0200 /* downmix mode: 1 = enabled */
1720 #define AC97_AD198X_HPSEL 0x0400 /* headphone amplifier input select */
1721 #define AC97_AD198X_CLDIS 0x0800 /* center/lfe disable */
1722 #define AC97_AD198X_LODIS 0x1000 /* LINE_OUT disable */
1723 #define AC97_AD198X_MSPLT 0x2000 /* mute split */
1724 #define AC97_AD198X_AC97NC 0x4000 /* AC97 no compatible mode */
1725 #define AC97_AD198X_DACZ 0x8000 /* DAC zero-fill mode */
1727 /* MISC 1 bits (AD1986 register 0x76) */
1728 #define AC97_AD1986_MBC 0x0003 /* mic boost */
1729 #define AC97_AD1986_MBC_20 0x0000 /* +20dB */
1730 #define AC97_AD1986_MBC_10 0x0001 /* +10dB */
1731 #define AC97_AD1986_MBC_30 0x0002 /* +30dB */
1732 #define AC97_AD1986_LISEL0 0x0004 /* LINE_IN select bit 0 */
1733 #define AC97_AD1986_LISEL1 0x0008 /* LINE_IN select bit 1 */
1734 #define AC97_AD1986_LISEL_MASK (AC97_AD1986_LISEL1 | AC97_AD1986_LISEL0)
1735 #define AC97_AD1986_LISEL_LI 0x0000 /* LINE_IN pins as LINE_IN source */
1736 #define AC97_AD1986_LISEL_SURR 0x0004 /* SURROUND pins as LINE_IN source */
1737 #define AC97_AD1986_LISEL_MIC 0x0008 /* MIC_1/2 pins as LINE_IN source */
1738 #define AC97_AD1986_SRU 0x0010 /* sample rate unlock */
1739 #define AC97_AD1986_SOSEL 0x0020 /* SURROUND_OUT amplifiers input sel */
1740 #define AC97_AD1986_2MIC 0x0040 /* 2-channel mic select */
1741 #define AC97_AD1986_SPRD 0x0080 /* SPREAD enable */
1742 #define AC97_AD1986_DMIX0 0x0100 /* downmix mode: */
1743 /* 0 = 6-to-4, 1 = 6-to-2 downmix */
1744 #define AC97_AD1986_DMIX1 0x0200 /* downmix mode: 1 = enabled */
1745 #define AC97_AD1986_CLDIS 0x0800 /* center/lfe disable */
1746 #define AC97_AD1986_SODIS 0x1000 /* SURROUND_OUT disable */
1747 #define AC97_AD1986_MSPLT 0x2000 /* mute split (read only 1) */
1748 #define AC97_AD1986_AC97NC 0x4000 /* AC97 no compatible mode (r/o 1) */
1749 #define AC97_AD1986_DACZ 0x8000 /* DAC zero-fill mode */
1751 /* MISC 2 bits (AD1986 register 0x70) */
1752 #define AC97_AD_MISC2 0x70 /* Misc Control Bits 2 (AD1986) */
1754 #define AC97_AD1986_CVREF0 0x0004 /* C/LFE VREF_OUT 2.25V */
1755 #define AC97_AD1986_CVREF1 0x0008 /* C/LFE VREF_OUT 0V */
1756 #define AC97_AD1986_CVREF2 0x0010 /* C/LFE VREF_OUT 3.7V */
1757 #define AC97_AD1986_CVREF_MASK \
1758 (AC97_AD1986_CVREF2 | AC97_AD1986_CVREF1 | AC97_AD1986_CVREF0)
1759 #define AC97_AD1986_JSMAP 0x0020 /* Jack Sense Mapping 1 = alternate */
1760 #define AC97_AD1986_MMDIS 0x0080 /* Mono Mute Disable */
1761 #define AC97_AD1986_MVREF0 0x0400 /* MIC VREF_OUT 2.25V */
1762 #define AC97_AD1986_MVREF1 0x0800 /* MIC VREF_OUT 0V */
1763 #define AC97_AD1986_MVREF2 0x1000 /* MIC VREF_OUT 3.7V */
1764 #define AC97_AD1986_MVREF_MASK \
1765 (AC97_AD1986_MVREF2 | AC97_AD1986_MVREF1 | AC97_AD1986_MVREF0)
1767 /* MISC 3 bits (AD1986 register 0x7a) */
1768 #define AC97_AD_MISC3 0x7a /* Misc Control Bits 3 (AD1986) */
1770 #define AC97_AD1986_MMIX 0x0004 /* Mic Mix, left/right */
1771 #define AC97_AD1986_GPO 0x0008 /* General Purpose Out */
1772 #define AC97_AD1986_LOHPEN 0x0010 /* LINE_OUT headphone drive */
1773 #define AC97_AD1986_LVREF0 0x0100 /* LINE_OUT VREF_OUT 2.25V */
1774 #define AC97_AD1986_LVREF1 0x0200 /* LINE_OUT VREF_OUT 0V */
1775 #define AC97_AD1986_LVREF2 0x0400 /* LINE_OUT VREF_OUT 3.7V */
1776 #define AC97_AD1986_LVREF_MASK \
1777 (AC97_AD1986_LVREF2 | AC97_AD1986_LVREF1 | AC97_AD1986_LVREF0)
1778 #define AC97_AD1986_JSINVA 0x0800 /* Jack Sense Invert SENSE_A */
1779 #define AC97_AD1986_LOSEL 0x1000 /* LINE_OUT amplifiers input select */
1780 #define AC97_AD1986_HPSEL0 0x2000 /* Headphone amplifiers */
1781 /* input select Surround DACs */
1782 #define AC97_AD1986_HPSEL1 0x4000 /* Headphone amplifiers input */
1783 /* select C/LFE DACs */
1784 #define AC97_AD1986_JSINVB 0x8000 /* Jack Sense Invert SENSE_B */
1786 /* Serial Config bits (AD1986 register 0x74) (incomplete) */
1787 #define AC97_AD1986_OMS0 0x0100 /* Optional Mic Selector bit 0 */
1788 #define AC97_AD1986_OMS1 0x0200 /* Optional Mic Selector bit 1 */
1789 #define AC97_AD1986_OMS2 0x0400 /* Optional Mic Selector bit 2 */
1790 #define AC97_AD1986_OMS_MASK \
1791 (AC97_AD1986_OMS2 | AC97_AD1986_OMS1 | AC97_AD1986_OMS0)
1792 #define AC97_AD1986_OMS_M 0x0000 /* MIC_1/2 pins are MIC sources */
1793 #define AC97_AD1986_OMS_L 0x0100 /* LINE_IN pins are MIC sources */
1794 #define AC97_AD1986_OMS_C 0x0200 /* Center/LFE pins are MCI sources */
1795 #define AC97_AD1986_OMS_MC 0x0400 /* Mix of MIC and C/LFE pins */
1796 /* are MIC sources */
1797 #define AC97_AD1986_OMS_ML 0x0500 /* MIX of MIC and LINE_IN pins */
1798 /* are MIC sources */
1799 #define AC97_AD1986_OMS_LC 0x0600 /* MIX of LINE_IN and C/LFE pins */
1800 /* are MIC sources */
1801 #define AC97_AD1986_OMS_MLC 0x0700 /* MIX of MIC, LINE_IN, C/LFE pins */
1802 /* are MIC sources */
1805 static int snd_ac97_ad198x_spdif_source_info(struct snd_kcontrol
*kcontrol
, struct snd_ctl_elem_info
*uinfo
)
1807 static char *texts
[2] = { "AC-Link", "A/D Converter" };
1809 uinfo
->type
= SNDRV_CTL_ELEM_TYPE_ENUMERATED
;
1811 uinfo
->value
.enumerated
.items
= 2;
1812 if (uinfo
->value
.enumerated
.item
> 1)
1813 uinfo
->value
.enumerated
.item
= 1;
1814 strcpy(uinfo
->value
.enumerated
.name
, texts
[uinfo
->value
.enumerated
.item
]);
1818 static int snd_ac97_ad198x_spdif_source_get(struct snd_kcontrol
*kcontrol
, struct snd_ctl_elem_value
*ucontrol
)
1820 struct snd_ac97
*ac97
= snd_kcontrol_chip(kcontrol
);
1823 val
= ac97
->regs
[AC97_AD_SERIAL_CFG
];
1824 ucontrol
->value
.enumerated
.item
[0] = (val
>> 2) & 1;
1828 static int snd_ac97_ad198x_spdif_source_put(struct snd_kcontrol
*kcontrol
, struct snd_ctl_elem_value
*ucontrol
)
1830 struct snd_ac97
*ac97
= snd_kcontrol_chip(kcontrol
);
1833 if (ucontrol
->value
.enumerated
.item
[0] > 1)
1835 val
= ucontrol
->value
.enumerated
.item
[0] << 2;
1836 return snd_ac97_update_bits(ac97
, AC97_AD_SERIAL_CFG
, 0x0004, val
);
1839 static const struct snd_kcontrol_new snd_ac97_ad198x_spdif_source
= {
1840 .iface
= SNDRV_CTL_ELEM_IFACE_MIXER
,
1841 .name
= SNDRV_CTL_NAME_IEC958("",PLAYBACK
,NONE
) "Source",
1842 .info
= snd_ac97_ad198x_spdif_source_info
,
1843 .get
= snd_ac97_ad198x_spdif_source_get
,
1844 .put
= snd_ac97_ad198x_spdif_source_put
,
1847 static int patch_ad198x_post_spdif(struct snd_ac97
* ac97
)
1849 return patch_build_controls(ac97
, &snd_ac97_ad198x_spdif_source
, 1);
1852 static const struct snd_kcontrol_new snd_ac97_ad1981x_jack_sense
[] = {
1853 AC97_SINGLE("Headphone Jack Sense", AC97_AD_JACK_SPDIF
, 11, 1, 0),
1854 AC97_SINGLE("Line Jack Sense", AC97_AD_JACK_SPDIF
, 12, 1, 0),
1857 /* black list to avoid HP/Line jack-sense controls
1858 * (SS vendor << 16 | device)
1860 static unsigned int ad1981_jacks_blacklist
[] = {
1861 0x10140523, /* Thinkpad R40 */
1862 0x10140534, /* Thinkpad X31 */
1863 0x10140537, /* Thinkpad T41p */
1864 0x1014053e, /* Thinkpad R40e */
1865 0x10140554, /* Thinkpad T42p/R50p */
1866 0x10140567, /* Thinkpad T43p 2668-G7U */
1867 0x10140581, /* Thinkpad X41-2527 */
1868 0x10280160, /* Dell Dimension 2400 */
1869 0x104380b0, /* Asus A7V8X-MX */
1870 0x11790241, /* Toshiba Satellite A-15 S127 */
1871 0x1179ff10, /* Toshiba P500 */
1872 0x144dc01a, /* Samsung NP-X20C004/SEG */
1876 static int check_list(struct snd_ac97
*ac97
, const unsigned int *list
)
1878 u32 subid
= ((u32
)ac97
->subsystem_vendor
<< 16) | ac97
->subsystem_device
;
1879 for (; *list
; list
++)
1885 static int patch_ad1981a_specific(struct snd_ac97
* ac97
)
1887 if (check_list(ac97
, ad1981_jacks_blacklist
))
1889 return patch_build_controls(ac97
, snd_ac97_ad1981x_jack_sense
,
1890 ARRAY_SIZE(snd_ac97_ad1981x_jack_sense
));
1893 static const struct snd_ac97_build_ops patch_ad1981a_build_ops
= {
1894 .build_post_spdif
= patch_ad198x_post_spdif
,
1895 .build_specific
= patch_ad1981a_specific
,
1897 .resume
= ad18xx_resume
1901 /* white list to enable HP jack-sense bits
1902 * (SS vendor << 16 | device)
1904 static unsigned int ad1981_jacks_whitelist
[] = {
1905 0x0e11005a, /* HP nc4000/4010 */
1906 0x103c0890, /* HP nc6000 */
1907 0x103c0938, /* HP nc4220 */
1908 0x103c099c, /* HP nx6110 */
1909 0x103c0944, /* HP nc6220 */
1910 0x103c0934, /* HP nc8220 */
1911 0x103c006d, /* HP nx9105 */
1912 0x103c300d, /* HP Compaq dc5100 SFF(PT003AW) */
1913 0x17340088, /* FSC Scenic-W */
1917 static void check_ad1981_hp_jack_sense(struct snd_ac97
*ac97
)
1919 if (check_list(ac97
, ad1981_jacks_whitelist
))
1920 /* enable headphone jack sense */
1921 snd_ac97_update_bits(ac97
, AC97_AD_JACK_SPDIF
, 1<<11, 1<<11);
1924 static int patch_ad1981a(struct snd_ac97
*ac97
)
1927 ac97
->build_ops
= &patch_ad1981a_build_ops
;
1928 snd_ac97_update_bits(ac97
, AC97_AD_MISC
, AC97_AD198X_MSPLT
, AC97_AD198X_MSPLT
);
1929 ac97
->flags
|= AC97_STEREO_MUTES
;
1930 check_ad1981_hp_jack_sense(ac97
);
1934 static const struct snd_kcontrol_new snd_ac97_ad198x_2cmic
=
1935 AC97_SINGLE("Stereo Mic", AC97_AD_MISC
, 6, 1, 0);
1937 static int patch_ad1981b_specific(struct snd_ac97
*ac97
)
1941 if ((err
= patch_build_controls(ac97
, &snd_ac97_ad198x_2cmic
, 1)) < 0)
1943 if (check_list(ac97
, ad1981_jacks_blacklist
))
1945 return patch_build_controls(ac97
, snd_ac97_ad1981x_jack_sense
,
1946 ARRAY_SIZE(snd_ac97_ad1981x_jack_sense
));
1949 static const struct snd_ac97_build_ops patch_ad1981b_build_ops
= {
1950 .build_post_spdif
= patch_ad198x_post_spdif
,
1951 .build_specific
= patch_ad1981b_specific
,
1953 .resume
= ad18xx_resume
1957 static int patch_ad1981b(struct snd_ac97
*ac97
)
1960 ac97
->build_ops
= &patch_ad1981b_build_ops
;
1961 snd_ac97_update_bits(ac97
, AC97_AD_MISC
, AC97_AD198X_MSPLT
, AC97_AD198X_MSPLT
);
1962 ac97
->flags
|= AC97_STEREO_MUTES
;
1963 check_ad1981_hp_jack_sense(ac97
);
1967 #define snd_ac97_ad1888_lohpsel_info snd_ctl_boolean_mono_info
1969 static int snd_ac97_ad1888_lohpsel_get(struct snd_kcontrol
*kcontrol
, struct snd_ctl_elem_value
*ucontrol
)
1971 struct snd_ac97
*ac97
= snd_kcontrol_chip(kcontrol
);
1974 val
= ac97
->regs
[AC97_AD_MISC
];
1975 ucontrol
->value
.integer
.value
[0] = !(val
& AC97_AD198X_LOSEL
);
1976 if (ac97
->spec
.ad18xx
.lo_as_master
)
1977 ucontrol
->value
.integer
.value
[0] =
1978 !ucontrol
->value
.integer
.value
[0];
1982 static int snd_ac97_ad1888_lohpsel_put(struct snd_kcontrol
*kcontrol
, struct snd_ctl_elem_value
*ucontrol
)
1984 struct snd_ac97
*ac97
= snd_kcontrol_chip(kcontrol
);
1987 val
= !ucontrol
->value
.integer
.value
[0];
1988 if (ac97
->spec
.ad18xx
.lo_as_master
)
1990 val
= val
? (AC97_AD198X_LOSEL
| AC97_AD198X_HPSEL
) : 0;
1991 return snd_ac97_update_bits(ac97
, AC97_AD_MISC
,
1992 AC97_AD198X_LOSEL
| AC97_AD198X_HPSEL
, val
);
1995 static int snd_ac97_ad1888_downmix_info(struct snd_kcontrol
*kcontrol
, struct snd_ctl_elem_info
*uinfo
)
1997 static char *texts
[3] = {"Off", "6 -> 4", "6 -> 2"};
1999 uinfo
->type
= SNDRV_CTL_ELEM_TYPE_ENUMERATED
;
2001 uinfo
->value
.enumerated
.items
= 3;
2002 if (uinfo
->value
.enumerated
.item
> 2)
2003 uinfo
->value
.enumerated
.item
= 2;
2004 strcpy(uinfo
->value
.enumerated
.name
, texts
[uinfo
->value
.enumerated
.item
]);
2008 static int snd_ac97_ad1888_downmix_get(struct snd_kcontrol
*kcontrol
, struct snd_ctl_elem_value
*ucontrol
)
2010 struct snd_ac97
*ac97
= snd_kcontrol_chip(kcontrol
);
2013 val
= ac97
->regs
[AC97_AD_MISC
];
2014 if (!(val
& AC97_AD198X_DMIX1
))
2015 ucontrol
->value
.enumerated
.item
[0] = 0;
2017 ucontrol
->value
.enumerated
.item
[0] = 1 + ((val
>> 8) & 1);
2021 static int snd_ac97_ad1888_downmix_put(struct snd_kcontrol
*kcontrol
, struct snd_ctl_elem_value
*ucontrol
)
2023 struct snd_ac97
*ac97
= snd_kcontrol_chip(kcontrol
);
2026 if (ucontrol
->value
.enumerated
.item
[0] > 2)
2028 if (ucontrol
->value
.enumerated
.item
[0] == 0)
2031 val
= AC97_AD198X_DMIX1
|
2032 ((ucontrol
->value
.enumerated
.item
[0] - 1) << 8);
2033 return snd_ac97_update_bits(ac97
, AC97_AD_MISC
,
2034 AC97_AD198X_DMIX0
| AC97_AD198X_DMIX1
, val
);
2037 static void ad1888_update_jacks(struct snd_ac97
*ac97
)
2039 unsigned short val
= 0;
2040 /* clear LODIS if shared jack is to be used for Surround out */
2041 if (!ac97
->spec
.ad18xx
.lo_as_master
&& is_shared_linein(ac97
))
2043 /* clear CLDIS if shared jack is to be used for C/LFE out */
2044 if (is_shared_micin(ac97
))
2046 /* shared Line-In */
2047 snd_ac97_update_bits(ac97
, AC97_AD_MISC
, (1 << 11) | (1 << 12), val
);
2050 static const struct snd_kcontrol_new snd_ac97_ad1888_controls
[] = {
2052 .iface
= SNDRV_CTL_ELEM_IFACE_MIXER
,
2053 .name
= "Exchange Front/Surround",
2054 .info
= snd_ac97_ad1888_lohpsel_info
,
2055 .get
= snd_ac97_ad1888_lohpsel_get
,
2056 .put
= snd_ac97_ad1888_lohpsel_put
2058 AC97_SINGLE("V_REFOUT Enable", AC97_AD_MISC
, AC97_AD_VREFD_SHIFT
, 1, 1),
2059 AC97_SINGLE("High Pass Filter Enable", AC97_AD_TEST2
,
2060 AC97_AD_HPFD_SHIFT
, 1, 1),
2061 AC97_SINGLE("Spread Front to Surround and Center/LFE", AC97_AD_MISC
, 7, 1, 0),
2063 .iface
= SNDRV_CTL_ELEM_IFACE_MIXER
,
2065 .info
= snd_ac97_ad1888_downmix_info
,
2066 .get
= snd_ac97_ad1888_downmix_get
,
2067 .put
= snd_ac97_ad1888_downmix_put
2069 AC97_SURROUND_JACK_MODE_CTL
,
2070 AC97_CHANNEL_MODE_CTL
,
2072 AC97_SINGLE("Headphone Jack Sense", AC97_AD_JACK_SPDIF
, 10, 1, 0),
2073 AC97_SINGLE("Line Jack Sense", AC97_AD_JACK_SPDIF
, 12, 1, 0),
2076 static int patch_ad1888_specific(struct snd_ac97
*ac97
)
2078 if (!ac97
->spec
.ad18xx
.lo_as_master
) {
2079 /* rename 0x04 as "Master" and 0x02 as "Master Surround" */
2080 snd_ac97_rename_vol_ctl(ac97
, "Master Playback",
2081 "Master Surround Playback");
2082 snd_ac97_rename_vol_ctl(ac97
, "Headphone Playback",
2085 return patch_build_controls(ac97
, snd_ac97_ad1888_controls
, ARRAY_SIZE(snd_ac97_ad1888_controls
));
2088 static const struct snd_ac97_build_ops patch_ad1888_build_ops
= {
2089 .build_post_spdif
= patch_ad198x_post_spdif
,
2090 .build_specific
= patch_ad1888_specific
,
2092 .resume
= ad1888_resume
,
2094 .update_jacks
= ad1888_update_jacks
,
2097 static int patch_ad1888(struct snd_ac97
* ac97
)
2099 unsigned short misc
;
2102 ac97
->build_ops
= &patch_ad1888_build_ops
;
2105 * LO can be used as a real line-out on some devices,
2106 * and we need to revert the front/surround mixer switches
2108 if (ac97
->subsystem_vendor
== 0x1043 &&
2109 ac97
->subsystem_device
== 0x1193) /* ASUS A9T laptop */
2110 ac97
->spec
.ad18xx
.lo_as_master
= 1;
2112 misc
= snd_ac97_read(ac97
, AC97_AD_MISC
);
2113 /* AD-compatible mode */
2114 /* Stereo mutes enabled */
2115 misc
|= AC97_AD198X_MSPLT
| AC97_AD198X_AC97NC
;
2116 if (!ac97
->spec
.ad18xx
.lo_as_master
)
2117 /* Switch FRONT/SURROUND LINE-OUT/HP-OUT default connection */
2118 /* it seems that most vendors connect line-out connector to
2119 * headphone out of AC'97
2121 misc
|= AC97_AD198X_LOSEL
| AC97_AD198X_HPSEL
;
2123 snd_ac97_write_cache(ac97
, AC97_AD_MISC
, misc
);
2124 ac97
->flags
|= AC97_STEREO_MUTES
;
2128 static int patch_ad1980_specific(struct snd_ac97
*ac97
)
2132 if ((err
= patch_ad1888_specific(ac97
)) < 0)
2134 return patch_build_controls(ac97
, &snd_ac97_ad198x_2cmic
, 1);
2137 static const struct snd_ac97_build_ops patch_ad1980_build_ops
= {
2138 .build_post_spdif
= patch_ad198x_post_spdif
,
2139 .build_specific
= patch_ad1980_specific
,
2141 .resume
= ad18xx_resume
,
2143 .update_jacks
= ad1888_update_jacks
,
2146 static int patch_ad1980(struct snd_ac97
* ac97
)
2149 ac97
->build_ops
= &patch_ad1980_build_ops
;
2153 static int snd_ac97_ad1985_vrefout_info(struct snd_kcontrol
*kcontrol
,
2154 struct snd_ctl_elem_info
*uinfo
)
2156 static char *texts
[4] = {"High-Z", "3.7 V", "2.25 V", "0 V"};
2158 uinfo
->type
= SNDRV_CTL_ELEM_TYPE_ENUMERATED
;
2160 uinfo
->value
.enumerated
.items
= 4;
2161 if (uinfo
->value
.enumerated
.item
> 3)
2162 uinfo
->value
.enumerated
.item
= 3;
2163 strcpy(uinfo
->value
.enumerated
.name
,
2164 texts
[uinfo
->value
.enumerated
.item
]);
2168 static int snd_ac97_ad1985_vrefout_get(struct snd_kcontrol
*kcontrol
,
2169 struct snd_ctl_elem_value
*ucontrol
)
2171 static const int reg2ctrl
[4] = {2, 0, 1, 3};
2172 struct snd_ac97
*ac97
= snd_kcontrol_chip(kcontrol
);
2174 val
= (ac97
->regs
[AC97_AD_MISC
] & AC97_AD198X_VREF_MASK
)
2175 >> AC97_AD198X_VREF_SHIFT
;
2176 ucontrol
->value
.enumerated
.item
[0] = reg2ctrl
[val
];
2180 static int snd_ac97_ad1985_vrefout_put(struct snd_kcontrol
*kcontrol
,
2181 struct snd_ctl_elem_value
*ucontrol
)
2183 static const int ctrl2reg
[4] = {1, 2, 0, 3};
2184 struct snd_ac97
*ac97
= snd_kcontrol_chip(kcontrol
);
2187 if (ucontrol
->value
.enumerated
.item
[0] > 3)
2189 val
= ctrl2reg
[ucontrol
->value
.enumerated
.item
[0]]
2190 << AC97_AD198X_VREF_SHIFT
;
2191 return snd_ac97_update_bits(ac97
, AC97_AD_MISC
,
2192 AC97_AD198X_VREF_MASK
, val
);
2195 static const struct snd_kcontrol_new snd_ac97_ad1985_controls
[] = {
2196 AC97_SINGLE("Exchange Center/LFE", AC97_AD_SERIAL_CFG
, 3, 1, 0),
2198 .iface
= SNDRV_CTL_ELEM_IFACE_MIXER
,
2199 .name
= "Exchange Front/Surround",
2200 .info
= snd_ac97_ad1888_lohpsel_info
,
2201 .get
= snd_ac97_ad1888_lohpsel_get
,
2202 .put
= snd_ac97_ad1888_lohpsel_put
2204 AC97_SINGLE("High Pass Filter Enable", AC97_AD_TEST2
, 12, 1, 1),
2205 AC97_SINGLE("Spread Front to Surround and Center/LFE",
2206 AC97_AD_MISC
, 7, 1, 0),
2208 .iface
= SNDRV_CTL_ELEM_IFACE_MIXER
,
2210 .info
= snd_ac97_ad1888_downmix_info
,
2211 .get
= snd_ac97_ad1888_downmix_get
,
2212 .put
= snd_ac97_ad1888_downmix_put
2215 .iface
= SNDRV_CTL_ELEM_IFACE_MIXER
,
2217 .info
= snd_ac97_ad1985_vrefout_info
,
2218 .get
= snd_ac97_ad1985_vrefout_get
,
2219 .put
= snd_ac97_ad1985_vrefout_put
2221 AC97_SURROUND_JACK_MODE_CTL
,
2222 AC97_CHANNEL_MODE_CTL
,
2224 AC97_SINGLE("Headphone Jack Sense", AC97_AD_JACK_SPDIF
, 10, 1, 0),
2225 AC97_SINGLE("Line Jack Sense", AC97_AD_JACK_SPDIF
, 12, 1, 0),
2228 static void ad1985_update_jacks(struct snd_ac97
*ac97
)
2230 ad1888_update_jacks(ac97
);
2231 /* clear OMS if shared jack is to be used for C/LFE out */
2232 snd_ac97_update_bits(ac97
, AC97_AD_SERIAL_CFG
, 1 << 9,
2233 is_shared_micin(ac97
) ? 1 << 9 : 0);
2236 static int patch_ad1985_specific(struct snd_ac97
*ac97
)
2240 /* rename 0x04 as "Master" and 0x02 as "Master Surround" */
2241 snd_ac97_rename_vol_ctl(ac97
, "Master Playback",
2242 "Master Surround Playback");
2243 snd_ac97_rename_vol_ctl(ac97
, "Headphone Playback", "Master Playback");
2245 if ((err
= patch_build_controls(ac97
, &snd_ac97_ad198x_2cmic
, 1)) < 0)
2248 return patch_build_controls(ac97
, snd_ac97_ad1985_controls
,
2249 ARRAY_SIZE(snd_ac97_ad1985_controls
));
2252 static const struct snd_ac97_build_ops patch_ad1985_build_ops
= {
2253 .build_post_spdif
= patch_ad198x_post_spdif
,
2254 .build_specific
= patch_ad1985_specific
,
2256 .resume
= ad18xx_resume
,
2258 .update_jacks
= ad1985_update_jacks
,
2261 static int patch_ad1985(struct snd_ac97
* ac97
)
2263 unsigned short misc
;
2266 ac97
->build_ops
= &patch_ad1985_build_ops
;
2267 misc
= snd_ac97_read(ac97
, AC97_AD_MISC
);
2268 /* switch front/surround line-out/hp-out */
2269 /* AD-compatible mode */
2270 /* Stereo mutes enabled */
2271 snd_ac97_write_cache(ac97
, AC97_AD_MISC
, misc
|
2275 AC97_AD198X_AC97NC
);
2276 ac97
->flags
|= AC97_STEREO_MUTES
;
2278 /* update current jack configuration */
2279 ad1985_update_jacks(ac97
);
2281 /* on AD1985 rev. 3, AC'97 revision bits are zero */
2282 ac97
->ext_id
= (ac97
->ext_id
& ~AC97_EI_REV_MASK
) | AC97_EI_REV_23
;
2286 #define snd_ac97_ad1986_bool_info snd_ctl_boolean_mono_info
2288 static int snd_ac97_ad1986_lososel_get(struct snd_kcontrol
*kcontrol
,
2289 struct snd_ctl_elem_value
*ucontrol
)
2291 struct snd_ac97
*ac97
= snd_kcontrol_chip(kcontrol
);
2294 val
= ac97
->regs
[AC97_AD_MISC3
];
2295 ucontrol
->value
.integer
.value
[0] = (val
& AC97_AD1986_LOSEL
) != 0;
2299 static int snd_ac97_ad1986_lososel_put(struct snd_kcontrol
*kcontrol
,
2300 struct snd_ctl_elem_value
*ucontrol
)
2302 struct snd_ac97
*ac97
= snd_kcontrol_chip(kcontrol
);
2305 int sprd
= (ac97
->regs
[AC97_AD_MISC
] & AC97_AD1986_SPRD
) != 0;
2307 ret0
= snd_ac97_update_bits(ac97
, AC97_AD_MISC3
, AC97_AD1986_LOSEL
,
2308 ucontrol
->value
.integer
.value
[0] != 0
2309 ? AC97_AD1986_LOSEL
: 0);
2313 /* SOSEL is set to values of "Spread" or "Exchange F/S" controls */
2314 ret1
= snd_ac97_update_bits(ac97
, AC97_AD_MISC
, AC97_AD1986_SOSEL
,
2315 (ucontrol
->value
.integer
.value
[0] != 0
2317 ? AC97_AD1986_SOSEL
: 0);
2321 return (ret0
> 0 || ret1
> 0) ? 1 : 0;
2324 static int snd_ac97_ad1986_spread_get(struct snd_kcontrol
*kcontrol
,
2325 struct snd_ctl_elem_value
*ucontrol
)
2327 struct snd_ac97
*ac97
= snd_kcontrol_chip(kcontrol
);
2330 val
= ac97
->regs
[AC97_AD_MISC
];
2331 ucontrol
->value
.integer
.value
[0] = (val
& AC97_AD1986_SPRD
) != 0;
2335 static int snd_ac97_ad1986_spread_put(struct snd_kcontrol
*kcontrol
,
2336 struct snd_ctl_elem_value
*ucontrol
)
2338 struct snd_ac97
*ac97
= snd_kcontrol_chip(kcontrol
);
2341 int sprd
= (ac97
->regs
[AC97_AD_MISC3
] & AC97_AD1986_LOSEL
) != 0;
2343 ret0
= snd_ac97_update_bits(ac97
, AC97_AD_MISC
, AC97_AD1986_SPRD
,
2344 ucontrol
->value
.integer
.value
[0] != 0
2345 ? AC97_AD1986_SPRD
: 0);
2349 /* SOSEL is set to values of "Spread" or "Exchange F/S" controls */
2350 ret1
= snd_ac97_update_bits(ac97
, AC97_AD_MISC
, AC97_AD1986_SOSEL
,
2351 (ucontrol
->value
.integer
.value
[0] != 0
2353 ? AC97_AD1986_SOSEL
: 0);
2357 return (ret0
> 0 || ret1
> 0) ? 1 : 0;
2360 static int snd_ac97_ad1986_miclisel_get(struct snd_kcontrol
*kcontrol
,
2361 struct snd_ctl_elem_value
*ucontrol
)
2363 struct snd_ac97
*ac97
= snd_kcontrol_chip(kcontrol
);
2365 ucontrol
->value
.integer
.value
[0] = ac97
->spec
.ad18xx
.swap_mic_linein
;
2369 static int snd_ac97_ad1986_miclisel_put(struct snd_kcontrol
*kcontrol
,
2370 struct snd_ctl_elem_value
*ucontrol
)
2372 struct snd_ac97
*ac97
= snd_kcontrol_chip(kcontrol
);
2373 unsigned char swap
= ucontrol
->value
.integer
.value
[0] != 0;
2375 if (swap
!= ac97
->spec
.ad18xx
.swap_mic_linein
) {
2376 ac97
->spec
.ad18xx
.swap_mic_linein
= swap
;
2377 if (ac97
->build_ops
->update_jacks
)
2378 ac97
->build_ops
->update_jacks(ac97
);
2384 static int snd_ac97_ad1986_vrefout_get(struct snd_kcontrol
*kcontrol
,
2385 struct snd_ctl_elem_value
*ucontrol
)
2387 /* Use MIC_1/2 V_REFOUT as the "get" value */
2388 struct snd_ac97
*ac97
= snd_kcontrol_chip(kcontrol
);
2390 unsigned short reg
= ac97
->regs
[AC97_AD_MISC2
];
2391 if ((reg
& AC97_AD1986_MVREF0
) != 0)
2393 else if ((reg
& AC97_AD1986_MVREF1
) != 0)
2395 else if ((reg
& AC97_AD1986_MVREF2
) != 0)
2399 ucontrol
->value
.enumerated
.item
[0] = val
;
2403 static int snd_ac97_ad1986_vrefout_put(struct snd_kcontrol
*kcontrol
,
2404 struct snd_ctl_elem_value
*ucontrol
)
2406 struct snd_ac97
*ac97
= snd_kcontrol_chip(kcontrol
);
2407 unsigned short cval
;
2408 unsigned short lval
;
2409 unsigned short mval
;
2414 switch (ucontrol
->value
.enumerated
.item
[0])
2416 case 0: /* High-Z */
2422 cval
= AC97_AD1986_CVREF2
;
2423 lval
= AC97_AD1986_LVREF2
;
2424 mval
= AC97_AD1986_MVREF2
;
2426 case 2: /* 2.25 V */
2427 cval
= AC97_AD1986_CVREF0
;
2428 lval
= AC97_AD1986_LVREF0
;
2429 mval
= AC97_AD1986_MVREF0
;
2432 cval
= AC97_AD1986_CVREF1
;
2433 lval
= AC97_AD1986_LVREF1
;
2434 mval
= AC97_AD1986_MVREF1
;
2440 cret
= snd_ac97_update_bits(ac97
, AC97_AD_MISC2
,
2441 AC97_AD1986_CVREF_MASK
, cval
);
2444 lret
= snd_ac97_update_bits(ac97
, AC97_AD_MISC3
,
2445 AC97_AD1986_LVREF_MASK
, lval
);
2448 mret
= snd_ac97_update_bits(ac97
, AC97_AD_MISC2
,
2449 AC97_AD1986_MVREF_MASK
, mval
);
2453 return (cret
> 0 || lret
> 0 || mret
> 0) ? 1 : 0;
2456 static const struct snd_kcontrol_new snd_ac97_ad1986_controls
[] = {
2457 AC97_SINGLE("Exchange Center/LFE", AC97_AD_SERIAL_CFG
, 3, 1, 0),
2459 .iface
= SNDRV_CTL_ELEM_IFACE_MIXER
,
2460 .name
= "Exchange Front/Surround",
2461 .info
= snd_ac97_ad1986_bool_info
,
2462 .get
= snd_ac97_ad1986_lososel_get
,
2463 .put
= snd_ac97_ad1986_lososel_put
2466 .iface
= SNDRV_CTL_ELEM_IFACE_MIXER
,
2467 .name
= "Exchange Mic/Line In",
2468 .info
= snd_ac97_ad1986_bool_info
,
2469 .get
= snd_ac97_ad1986_miclisel_get
,
2470 .put
= snd_ac97_ad1986_miclisel_put
2473 .iface
= SNDRV_CTL_ELEM_IFACE_MIXER
,
2474 .name
= "Spread Front to Surround and Center/LFE",
2475 .info
= snd_ac97_ad1986_bool_info
,
2476 .get
= snd_ac97_ad1986_spread_get
,
2477 .put
= snd_ac97_ad1986_spread_put
2480 .iface
= SNDRV_CTL_ELEM_IFACE_MIXER
,
2482 .info
= snd_ac97_ad1888_downmix_info
,
2483 .get
= snd_ac97_ad1888_downmix_get
,
2484 .put
= snd_ac97_ad1888_downmix_put
2487 .iface
= SNDRV_CTL_ELEM_IFACE_MIXER
,
2489 .info
= snd_ac97_ad1985_vrefout_info
,
2490 .get
= snd_ac97_ad1986_vrefout_get
,
2491 .put
= snd_ac97_ad1986_vrefout_put
2493 AC97_SURROUND_JACK_MODE_CTL
,
2494 AC97_CHANNEL_MODE_CTL
,
2496 AC97_SINGLE("Headphone Jack Sense", AC97_AD_JACK_SPDIF
, 10, 1, 0),
2497 AC97_SINGLE("Line Jack Sense", AC97_AD_JACK_SPDIF
, 12, 1, 0)
2500 static void ad1986_update_jacks(struct snd_ac97
*ac97
)
2502 unsigned short misc_val
= 0;
2503 unsigned short ser_val
;
2505 /* disable SURROUND and CENTER/LFE if not surround mode */
2506 if (!is_surround_on(ac97
))
2507 misc_val
|= AC97_AD1986_SODIS
;
2508 if (!is_clfe_on(ac97
))
2509 misc_val
|= AC97_AD1986_CLDIS
;
2511 /* select line input (default=LINE_IN, SURROUND or MIC_1/2) */
2512 if (is_shared_linein(ac97
))
2513 misc_val
|= AC97_AD1986_LISEL_SURR
;
2514 else if (ac97
->spec
.ad18xx
.swap_mic_linein
!= 0)
2515 misc_val
|= AC97_AD1986_LISEL_MIC
;
2516 snd_ac97_update_bits(ac97
, AC97_AD_MISC
,
2517 AC97_AD1986_SODIS
| AC97_AD1986_CLDIS
|
2518 AC97_AD1986_LISEL_MASK
,
2521 /* select microphone input (MIC_1/2, Center/LFE or LINE_IN) */
2522 if (is_shared_micin(ac97
))
2523 ser_val
= AC97_AD1986_OMS_C
;
2524 else if (ac97
->spec
.ad18xx
.swap_mic_linein
!= 0)
2525 ser_val
= AC97_AD1986_OMS_L
;
2527 ser_val
= AC97_AD1986_OMS_M
;
2528 snd_ac97_update_bits(ac97
, AC97_AD_SERIAL_CFG
,
2529 AC97_AD1986_OMS_MASK
,
2533 static int patch_ad1986_specific(struct snd_ac97
*ac97
)
2537 if ((err
= patch_build_controls(ac97
, &snd_ac97_ad198x_2cmic
, 1)) < 0)
2540 return patch_build_controls(ac97
, snd_ac97_ad1986_controls
,
2541 ARRAY_SIZE(snd_ac97_ad1985_controls
));
2544 static const struct snd_ac97_build_ops patch_ad1986_build_ops
= {
2545 .build_post_spdif
= patch_ad198x_post_spdif
,
2546 .build_specific
= patch_ad1986_specific
,
2548 .resume
= ad18xx_resume
,
2550 .update_jacks
= ad1986_update_jacks
,
2553 static int patch_ad1986(struct snd_ac97
* ac97
)
2556 ac97
->build_ops
= &patch_ad1986_build_ops
;
2557 ac97
->flags
|= AC97_STEREO_MUTES
;
2559 /* update current jack configuration */
2560 ad1986_update_jacks(ac97
);
2566 * realtek ALC203: use mono-out for pin 37
2568 static int patch_alc203(struct snd_ac97
*ac97
)
2570 snd_ac97_update_bits(ac97
, 0x7a, 0x400, 0x400);
2575 * realtek ALC65x/850 codecs
2577 static void alc650_update_jacks(struct snd_ac97
*ac97
)
2581 /* shared Line-In / Surround Out */
2582 shared
= is_shared_surrout(ac97
);
2583 snd_ac97_update_bits(ac97
, AC97_ALC650_MULTICH
, 1 << 9,
2584 shared
? (1 << 9) : 0);
2585 /* update shared Mic In / Center/LFE Out */
2586 shared
= is_shared_clfeout(ac97
);
2587 /* disable/enable vref */
2588 snd_ac97_update_bits(ac97
, AC97_ALC650_CLOCK
, 1 << 12,
2589 shared
? (1 << 12) : 0);
2590 /* turn on/off center-on-mic */
2591 snd_ac97_update_bits(ac97
, AC97_ALC650_MULTICH
, 1 << 10,
2592 shared
? (1 << 10) : 0);
2593 /* GPIO0 high for mic */
2594 snd_ac97_update_bits(ac97
, AC97_ALC650_GPIO_STATUS
, 0x100,
2595 shared
? 0 : 0x100);
2598 static int alc650_swap_surround_put(struct snd_kcontrol
*kcontrol
,
2599 struct snd_ctl_elem_value
*ucontrol
)
2601 struct snd_ac97
*ac97
= snd_kcontrol_chip(kcontrol
);
2602 struct snd_pcm_chmap
*map
= ac97
->chmaps
[SNDRV_PCM_STREAM_PLAYBACK
];
2605 if (ucontrol
->value
.integer
.value
[0])
2606 map
->chmap
= snd_pcm_std_chmaps
;
2608 map
->chmap
= snd_pcm_alt_chmaps
;
2610 return snd_ac97_put_volsw(kcontrol
, ucontrol
);
2613 static const struct snd_kcontrol_new snd_ac97_controls_alc650
[] = {
2614 AC97_SINGLE("Duplicate Front", AC97_ALC650_MULTICH
, 0, 1, 0),
2615 AC97_SINGLE("Surround Down Mix", AC97_ALC650_MULTICH
, 1, 1, 0),
2616 AC97_SINGLE("Center/LFE Down Mix", AC97_ALC650_MULTICH
, 2, 1, 0),
2617 AC97_SINGLE("Exchange Center/LFE", AC97_ALC650_MULTICH
, 3, 1, 0),
2618 /* 4: Analog Input To Surround */
2619 /* 5: Analog Input To Center/LFE */
2620 /* 6: Independent Master Volume Right */
2621 /* 7: Independent Master Volume Left */
2623 /* 9: Line-In/Surround share */
2624 /* 10: Mic/CLFE share */
2625 /* 11-13: in IEC958 controls */
2627 .iface
= SNDRV_CTL_ELEM_IFACE_MIXER
,
2628 .name
= "Swap Surround Slot",
2629 .info
= snd_ac97_info_volsw
,
2630 .get
= snd_ac97_get_volsw
,
2631 .put
= alc650_swap_surround_put
,
2632 .private_value
= AC97_SINGLE_VALUE(AC97_ALC650_MULTICH
, 14, 1, 0),
2634 #if 0 /* always set in patch_alc650 */
2635 AC97_SINGLE("IEC958 Input Clock Enable", AC97_ALC650_CLOCK
, 0, 1, 0),
2636 AC97_SINGLE("IEC958 Input Pin Enable", AC97_ALC650_CLOCK
, 1, 1, 0),
2637 AC97_SINGLE("Surround DAC Switch", AC97_ALC650_SURR_DAC_VOL
, 15, 1, 1),
2638 AC97_DOUBLE("Surround DAC Volume", AC97_ALC650_SURR_DAC_VOL
, 8, 0, 31, 1),
2639 AC97_SINGLE("Center/LFE DAC Switch", AC97_ALC650_LFE_DAC_VOL
, 15, 1, 1),
2640 AC97_DOUBLE("Center/LFE DAC Volume", AC97_ALC650_LFE_DAC_VOL
, 8, 0, 31, 1),
2642 AC97_SURROUND_JACK_MODE_CTL
,
2643 AC97_CHANNEL_MODE_CTL
,
2646 static const struct snd_kcontrol_new snd_ac97_spdif_controls_alc650
[] = {
2647 AC97_SINGLE(SNDRV_CTL_NAME_IEC958("",CAPTURE
,SWITCH
), AC97_ALC650_MULTICH
, 11, 1, 0),
2648 AC97_SINGLE("Analog to IEC958 Output", AC97_ALC650_MULTICH
, 12, 1, 0),
2649 /* disable this controls since it doesn't work as expected */
2650 /* AC97_SINGLE("IEC958 Input Monitor", AC97_ALC650_MULTICH, 13, 1, 0), */
2653 static const DECLARE_TLV_DB_SCALE(db_scale_5bit_3db_max
, -4350, 150, 0);
2655 static int patch_alc650_specific(struct snd_ac97
* ac97
)
2659 if ((err
= patch_build_controls(ac97
, snd_ac97_controls_alc650
, ARRAY_SIZE(snd_ac97_controls_alc650
))) < 0)
2661 if (ac97
->ext_id
& AC97_EI_SPDIF
) {
2662 if ((err
= patch_build_controls(ac97
, snd_ac97_spdif_controls_alc650
, ARRAY_SIZE(snd_ac97_spdif_controls_alc650
))) < 0)
2665 if (ac97
->id
!= AC97_ID_ALC650F
)
2666 reset_tlv(ac97
, "Master Playback Volume",
2667 db_scale_5bit_3db_max
);
2671 static const struct snd_ac97_build_ops patch_alc650_ops
= {
2672 .build_specific
= patch_alc650_specific
,
2673 .update_jacks
= alc650_update_jacks
2676 static int patch_alc650(struct snd_ac97
* ac97
)
2680 ac97
->build_ops
= &patch_alc650_ops
;
2682 /* determine the revision */
2683 val
= snd_ac97_read(ac97
, AC97_ALC650_REVISION
) & 0x3f;
2685 ac97
->id
= 0x414c4720; /* Old version */
2686 else if (val
< 0x10)
2687 ac97
->id
= 0x414c4721; /* D version */
2688 else if (val
< 0x20)
2689 ac97
->id
= 0x414c4722; /* E version */
2690 else if (val
< 0x30)
2691 ac97
->id
= 0x414c4723; /* F version */
2693 /* revision E or F */
2694 /* FIXME: what about revision D ? */
2695 ac97
->spec
.dev_flags
= (ac97
->id
== 0x414c4722 ||
2696 ac97
->id
== 0x414c4723);
2698 /* enable AC97_ALC650_GPIO_SETUP, AC97_ALC650_CLOCK for R/W */
2699 snd_ac97_write_cache(ac97
, AC97_ALC650_GPIO_STATUS
,
2700 snd_ac97_read(ac97
, AC97_ALC650_GPIO_STATUS
) | 0x8000);
2702 /* Enable SPDIF-IN only on Rev.E and above */
2703 val
= snd_ac97_read(ac97
, AC97_ALC650_CLOCK
);
2704 /* SPDIF IN with pin 47 */
2705 if (ac97
->spec
.dev_flags
&&
2706 /* ASUS A6KM requires EAPD */
2707 ! (ac97
->subsystem_vendor
== 0x1043 &&
2708 ac97
->subsystem_device
== 0x1103))
2709 val
|= 0x03; /* enable */
2711 val
&= ~0x03; /* disable */
2712 snd_ac97_write_cache(ac97
, AC97_ALC650_CLOCK
, val
);
2714 /* set default: slot 3,4,7,8,6,9
2715 spdif-in monitor off, analog-spdif off, spdif-in off
2716 center on mic off, surround on line-in off
2717 downmix off, duplicate front off
2719 snd_ac97_write_cache(ac97
, AC97_ALC650_MULTICH
, 0);
2721 /* set GPIO0 for mic bias */
2722 /* GPIO0 pin output, no interrupt, high */
2723 snd_ac97_write_cache(ac97
, AC97_ALC650_GPIO_SETUP
,
2724 snd_ac97_read(ac97
, AC97_ALC650_GPIO_SETUP
) | 0x01);
2725 snd_ac97_write_cache(ac97
, AC97_ALC650_GPIO_STATUS
,
2726 (snd_ac97_read(ac97
, AC97_ALC650_GPIO_STATUS
) | 0x100) & ~0x10);
2728 /* full DAC volume */
2729 snd_ac97_write_cache(ac97
, AC97_ALC650_SURR_DAC_VOL
, 0x0808);
2730 snd_ac97_write_cache(ac97
, AC97_ALC650_LFE_DAC_VOL
, 0x0808);
2734 static void alc655_update_jacks(struct snd_ac97
*ac97
)
2738 /* shared Line-In / Surround Out */
2739 shared
= is_shared_surrout(ac97
);
2740 ac97_update_bits_page(ac97
, AC97_ALC650_MULTICH
, 1 << 9,
2741 shared
? (1 << 9) : 0, 0);
2742 /* update shared Mic In / Center/LFE Out */
2743 shared
= is_shared_clfeout(ac97
);
2744 /* misc control; vrefout disable */
2745 snd_ac97_update_bits(ac97
, AC97_ALC650_CLOCK
, 1 << 12,
2746 shared
? (1 << 12) : 0);
2747 ac97_update_bits_page(ac97
, AC97_ALC650_MULTICH
, 1 << 10,
2748 shared
? (1 << 10) : 0, 0);
2751 static const struct snd_kcontrol_new snd_ac97_controls_alc655
[] = {
2752 AC97_PAGE_SINGLE("Duplicate Front", AC97_ALC650_MULTICH
, 0, 1, 0, 0),
2753 AC97_SURROUND_JACK_MODE_CTL
,
2754 AC97_CHANNEL_MODE_CTL
,
2757 static int alc655_iec958_route_info(struct snd_kcontrol
*kcontrol
, struct snd_ctl_elem_info
*uinfo
)
2759 static char *texts_655
[3] = { "PCM", "Analog In", "IEC958 In" };
2760 static char *texts_658
[4] = { "PCM", "Analog1 In", "Analog2 In", "IEC958 In" };
2761 struct snd_ac97
*ac97
= snd_kcontrol_chip(kcontrol
);
2763 uinfo
->type
= SNDRV_CTL_ELEM_TYPE_ENUMERATED
;
2765 uinfo
->value
.enumerated
.items
= ac97
->spec
.dev_flags
? 4 : 3;
2766 if (uinfo
->value
.enumerated
.item
>= uinfo
->value
.enumerated
.items
)
2767 uinfo
->value
.enumerated
.item
= uinfo
->value
.enumerated
.items
- 1;
2768 strcpy(uinfo
->value
.enumerated
.name
,
2769 ac97
->spec
.dev_flags
?
2770 texts_658
[uinfo
->value
.enumerated
.item
] :
2771 texts_655
[uinfo
->value
.enumerated
.item
]);
2775 static int alc655_iec958_route_get(struct snd_kcontrol
*kcontrol
, struct snd_ctl_elem_value
*ucontrol
)
2777 struct snd_ac97
*ac97
= snd_kcontrol_chip(kcontrol
);
2780 val
= ac97
->regs
[AC97_ALC650_MULTICH
];
2781 val
= (val
>> 12) & 3;
2782 if (ac97
->spec
.dev_flags
&& val
== 3)
2784 ucontrol
->value
.enumerated
.item
[0] = val
;
2788 static int alc655_iec958_route_put(struct snd_kcontrol
*kcontrol
, struct snd_ctl_elem_value
*ucontrol
)
2790 struct snd_ac97
*ac97
= snd_kcontrol_chip(kcontrol
);
2792 return ac97_update_bits_page(ac97
, AC97_ALC650_MULTICH
, 3 << 12,
2793 (unsigned short)ucontrol
->value
.enumerated
.item
[0] << 12,
2797 static const struct snd_kcontrol_new snd_ac97_spdif_controls_alc655
[] = {
2798 AC97_PAGE_SINGLE(SNDRV_CTL_NAME_IEC958("",CAPTURE
,SWITCH
), AC97_ALC650_MULTICH
, 11, 1, 0, 0),
2799 /* disable this controls since it doesn't work as expected */
2800 /* AC97_PAGE_SINGLE("IEC958 Input Monitor", AC97_ALC650_MULTICH, 14, 1, 0, 0), */
2802 .iface
= SNDRV_CTL_ELEM_IFACE_MIXER
,
2803 .name
= SNDRV_CTL_NAME_IEC958("",PLAYBACK
,NONE
) "Source",
2804 .info
= alc655_iec958_route_info
,
2805 .get
= alc655_iec958_route_get
,
2806 .put
= alc655_iec958_route_put
,
2810 static int patch_alc655_specific(struct snd_ac97
* ac97
)
2814 if ((err
= patch_build_controls(ac97
, snd_ac97_controls_alc655
, ARRAY_SIZE(snd_ac97_controls_alc655
))) < 0)
2816 if (ac97
->ext_id
& AC97_EI_SPDIF
) {
2817 if ((err
= patch_build_controls(ac97
, snd_ac97_spdif_controls_alc655
, ARRAY_SIZE(snd_ac97_spdif_controls_alc655
))) < 0)
2823 static const struct snd_ac97_build_ops patch_alc655_ops
= {
2824 .build_specific
= patch_alc655_specific
,
2825 .update_jacks
= alc655_update_jacks
2828 static int patch_alc655(struct snd_ac97
* ac97
)
2832 if (ac97
->id
== AC97_ID_ALC658
) {
2833 ac97
->spec
.dev_flags
= 1; /* ALC658 */
2834 if ((snd_ac97_read(ac97
, AC97_ALC650_REVISION
) & 0x3f) == 2) {
2835 ac97
->id
= AC97_ID_ALC658D
;
2836 ac97
->spec
.dev_flags
= 2;
2840 ac97
->build_ops
= &patch_alc655_ops
;
2842 /* assume only page 0 for writing cache */
2843 snd_ac97_update_bits(ac97
, AC97_INT_PAGING
, AC97_PAGE_MASK
, AC97_PAGE_VENDOR
);
2845 /* adjust default values */
2846 val
= snd_ac97_read(ac97
, 0x7a); /* misc control */
2847 if (ac97
->spec
.dev_flags
) /* ALC658 */
2848 val
&= ~(1 << 1); /* Pin 47 is spdif input pin */
2850 if (ac97
->subsystem_vendor
== 0x1462 &&
2851 (ac97
->subsystem_device
== 0x0131 || /* MSI S270 laptop */
2852 ac97
->subsystem_device
== 0x0161 || /* LG K1 Express */
2853 ac97
->subsystem_device
== 0x0351 || /* MSI L725 laptop */
2854 ac97
->subsystem_device
== 0x0471 || /* MSI L720 laptop */
2855 ac97
->subsystem_device
== 0x0061)) /* MSI S250 laptop */
2856 val
&= ~(1 << 1); /* Pin 47 is EAPD (for internal speaker) */
2858 val
|= (1 << 1); /* Pin 47 is spdif input pin */
2859 /* this seems missing on some hardwares */
2860 ac97
->ext_id
|= AC97_EI_SPDIF
;
2862 val
&= ~(1 << 12); /* vref enable */
2863 snd_ac97_write_cache(ac97
, 0x7a, val
);
2864 /* set default: spdif-in enabled,
2865 spdif-in monitor off, spdif-in PCM off
2866 center on mic off, surround on line-in off
2869 snd_ac97_write_cache(ac97
, AC97_ALC650_MULTICH
, 1<<15);
2871 /* full DAC volume */
2872 snd_ac97_write_cache(ac97
, AC97_ALC650_SURR_DAC_VOL
, 0x0808);
2873 snd_ac97_write_cache(ac97
, AC97_ALC650_LFE_DAC_VOL
, 0x0808);
2875 /* update undocumented bit... */
2876 if (ac97
->id
== AC97_ID_ALC658D
)
2877 snd_ac97_update_bits(ac97
, 0x74, 0x0800, 0x0800);
2883 #define AC97_ALC850_JACK_SELECT 0x76
2884 #define AC97_ALC850_MISC1 0x7a
2885 #define AC97_ALC850_MULTICH 0x6a
2887 static void alc850_update_jacks(struct snd_ac97
*ac97
)
2890 int aux_is_back_surround
;
2892 /* shared Line-In / Surround Out */
2893 shared
= is_shared_surrout(ac97
);
2894 /* SURR 1kOhm (bit4), Amp (bit5) */
2895 snd_ac97_update_bits(ac97
, AC97_ALC850_MISC1
, (1<<4)|(1<<5),
2896 shared
? (1<<5) : (1<<4));
2897 /* LINE-IN = 0, SURROUND = 2 */
2898 snd_ac97_update_bits(ac97
, AC97_ALC850_JACK_SELECT
, 7 << 12,
2899 shared
? (2<<12) : (0<<12));
2900 /* update shared Mic In / Center/LFE Out */
2901 shared
= is_shared_clfeout(ac97
);
2902 /* Vref disable (bit12), 1kOhm (bit13) */
2903 snd_ac97_update_bits(ac97
, AC97_ALC850_MISC1
, (1<<12)|(1<<13),
2904 shared
? (1<<12) : (1<<13));
2905 /* MIC-IN = 1, CENTER-LFE = 5 */
2906 snd_ac97_update_bits(ac97
, AC97_ALC850_JACK_SELECT
, 7 << 4,
2907 shared
? (5<<4) : (1<<4));
2909 aux_is_back_surround
= alc850_is_aux_back_surround(ac97
);
2910 /* Aux is Back Surround */
2911 snd_ac97_update_bits(ac97
, AC97_ALC850_MULTICH
, 1 << 10,
2912 aux_is_back_surround
? (1<<10) : (0<<10));
2915 static const struct snd_kcontrol_new snd_ac97_controls_alc850
[] = {
2916 AC97_PAGE_SINGLE("Duplicate Front", AC97_ALC650_MULTICH
, 0, 1, 0, 0),
2917 AC97_SINGLE("Mic Front Input Switch", AC97_ALC850_JACK_SELECT
, 15, 1, 1),
2918 AC97_SURROUND_JACK_MODE_CTL
,
2919 AC97_CHANNEL_MODE_8CH_CTL
,
2922 static int patch_alc850_specific(struct snd_ac97
*ac97
)
2926 if ((err
= patch_build_controls(ac97
, snd_ac97_controls_alc850
, ARRAY_SIZE(snd_ac97_controls_alc850
))) < 0)
2928 if (ac97
->ext_id
& AC97_EI_SPDIF
) {
2929 if ((err
= patch_build_controls(ac97
, snd_ac97_spdif_controls_alc655
, ARRAY_SIZE(snd_ac97_spdif_controls_alc655
))) < 0)
2935 static const struct snd_ac97_build_ops patch_alc850_ops
= {
2936 .build_specific
= patch_alc850_specific
,
2937 .update_jacks
= alc850_update_jacks
2940 static int patch_alc850(struct snd_ac97
*ac97
)
2942 ac97
->build_ops
= &patch_alc850_ops
;
2944 ac97
->spec
.dev_flags
= 0; /* for IEC958 playback route - ALC655 compatible */
2945 ac97
->flags
|= AC97_HAS_8CH
;
2947 /* assume only page 0 for writing cache */
2948 snd_ac97_update_bits(ac97
, AC97_INT_PAGING
, AC97_PAGE_MASK
, AC97_PAGE_VENDOR
);
2950 /* adjust default values */
2951 /* set default: spdif-in enabled,
2952 spdif-in monitor off, spdif-in PCM off
2953 center on mic off, surround on line-in off
2955 NB default bit 10=0 = Aux is Capture, not Back Surround
2957 snd_ac97_write_cache(ac97
, AC97_ALC650_MULTICH
, 1<<15);
2958 /* SURR_OUT: on, Surr 1kOhm: on, Surr Amp: off, Front 1kOhm: off
2959 * Front Amp: on, Vref: enable, Center 1kOhm: on, Mix: on
2961 snd_ac97_write_cache(ac97
, 0x7a, (1<<1)|(1<<4)|(0<<5)|(1<<6)|
2962 (1<<7)|(0<<12)|(1<<13)|(0<<14));
2963 /* detection UIO2,3: all path floating, UIO3: MIC, Vref2: disable,
2964 * UIO1: FRONT, Vref3: disable, UIO3: LINE, Front-Mic: mute
2966 snd_ac97_write_cache(ac97
, 0x76, (0<<0)|(0<<2)|(1<<4)|(1<<7)|(2<<8)|
2967 (1<<11)|(0<<12)|(1<<15));
2969 /* full DAC volume */
2970 snd_ac97_write_cache(ac97
, AC97_ALC650_SURR_DAC_VOL
, 0x0808);
2971 snd_ac97_write_cache(ac97
, AC97_ALC650_LFE_DAC_VOL
, 0x0808);
2975 static int patch_aztech_azf3328_specific(struct snd_ac97
*ac97
)
2977 struct snd_kcontrol
*kctl_3d_center
=
2978 snd_ac97_find_mixer_ctl(ac97
, "3D Control - Center");
2979 struct snd_kcontrol
*kctl_3d_depth
=
2980 snd_ac97_find_mixer_ctl(ac97
, "3D Control - Depth");
2983 * 3D register is different from AC97 standard layout
2984 * (also do some renaming, to resemble Windows driver naming)
2986 if (kctl_3d_center
) {
2987 kctl_3d_center
->private_value
=
2988 AC97_SINGLE_VALUE(AC97_3D_CONTROL
, 1, 0x07, 0);
2989 snd_ac97_rename_vol_ctl(ac97
,
2990 "3D Control - Center", "3D Control - Width"
2994 kctl_3d_depth
->private_value
=
2995 AC97_SINGLE_VALUE(AC97_3D_CONTROL
, 8, 0x03, 0);
2997 /* Aztech Windows driver calls the
2998 equivalent control "Modem Playback", thus rename it: */
2999 snd_ac97_rename_vol_ctl(ac97
,
3000 "Master Mono Playback", "Modem Playback"
3002 snd_ac97_rename_vol_ctl(ac97
,
3003 "Headphone Playback", "FM Synth Playback"
3009 static const struct snd_ac97_build_ops patch_aztech_azf3328_ops
= {
3010 .build_specific
= patch_aztech_azf3328_specific
3013 static int patch_aztech_azf3328(struct snd_ac97
*ac97
)
3015 ac97
->build_ops
= &patch_aztech_azf3328_ops
;
3020 * C-Media CM97xx codecs
3022 static void cm9738_update_jacks(struct snd_ac97
*ac97
)
3024 /* shared Line-In / Surround Out */
3025 snd_ac97_update_bits(ac97
, AC97_CM9738_VENDOR_CTRL
, 1 << 10,
3026 is_shared_surrout(ac97
) ? (1 << 10) : 0);
3029 static const struct snd_kcontrol_new snd_ac97_cm9738_controls
[] = {
3030 AC97_SINGLE("Duplicate Front", AC97_CM9738_VENDOR_CTRL
, 13, 1, 0),
3031 AC97_SURROUND_JACK_MODE_CTL
,
3032 AC97_CHANNEL_MODE_4CH_CTL
,
3035 static int patch_cm9738_specific(struct snd_ac97
* ac97
)
3037 return patch_build_controls(ac97
, snd_ac97_cm9738_controls
, ARRAY_SIZE(snd_ac97_cm9738_controls
));
3040 static const struct snd_ac97_build_ops patch_cm9738_ops
= {
3041 .build_specific
= patch_cm9738_specific
,
3042 .update_jacks
= cm9738_update_jacks
3045 static int patch_cm9738(struct snd_ac97
* ac97
)
3047 ac97
->build_ops
= &patch_cm9738_ops
;
3048 /* FIXME: can anyone confirm below? */
3049 /* CM9738 has no PCM volume although the register reacts */
3050 ac97
->flags
|= AC97_HAS_NO_PCM_VOL
;
3051 snd_ac97_write_cache(ac97
, AC97_PCM
, 0x8000);
3056 static int snd_ac97_cmedia_spdif_playback_source_info(struct snd_kcontrol
*kcontrol
, struct snd_ctl_elem_info
*uinfo
)
3058 static char *texts
[] = { "Analog", "Digital" };
3060 uinfo
->type
= SNDRV_CTL_ELEM_TYPE_ENUMERATED
;
3062 uinfo
->value
.enumerated
.items
= 2;
3063 if (uinfo
->value
.enumerated
.item
> 1)
3064 uinfo
->value
.enumerated
.item
= 1;
3065 strcpy(uinfo
->value
.enumerated
.name
, texts
[uinfo
->value
.enumerated
.item
]);
3069 static int snd_ac97_cmedia_spdif_playback_source_get(struct snd_kcontrol
*kcontrol
, struct snd_ctl_elem_value
*ucontrol
)
3071 struct snd_ac97
*ac97
= snd_kcontrol_chip(kcontrol
);
3074 val
= ac97
->regs
[AC97_CM9739_SPDIF_CTRL
];
3075 ucontrol
->value
.enumerated
.item
[0] = (val
>> 1) & 0x01;
3079 static int snd_ac97_cmedia_spdif_playback_source_put(struct snd_kcontrol
*kcontrol
, struct snd_ctl_elem_value
*ucontrol
)
3081 struct snd_ac97
*ac97
= snd_kcontrol_chip(kcontrol
);
3083 return snd_ac97_update_bits(ac97
, AC97_CM9739_SPDIF_CTRL
,
3085 (ucontrol
->value
.enumerated
.item
[0] & 0x01) << 1);
3088 static const struct snd_kcontrol_new snd_ac97_cm9739_controls_spdif
[] = {
3089 /* BIT 0: SPDI_EN - always true */
3090 { /* BIT 1: SPDIFS */
3091 .iface
= SNDRV_CTL_ELEM_IFACE_MIXER
,
3092 .name
= SNDRV_CTL_NAME_IEC958("",PLAYBACK
,NONE
) "Source",
3093 .info
= snd_ac97_cmedia_spdif_playback_source_info
,
3094 .get
= snd_ac97_cmedia_spdif_playback_source_get
,
3095 .put
= snd_ac97_cmedia_spdif_playback_source_put
,
3097 /* BIT 2: IG_SPIV */
3098 AC97_SINGLE(SNDRV_CTL_NAME_IEC958("",CAPTURE
,NONE
) "Valid Switch", AC97_CM9739_SPDIF_CTRL
, 2, 1, 0),
3100 AC97_SINGLE(SNDRV_CTL_NAME_IEC958("",CAPTURE
,NONE
) "Monitor", AC97_CM9739_SPDIF_CTRL
, 3, 1, 0),
3101 /* BIT 4: SPI2SDI */
3102 AC97_SINGLE(SNDRV_CTL_NAME_IEC958("",CAPTURE
,SWITCH
), AC97_CM9739_SPDIF_CTRL
, 4, 1, 0),
3103 /* BIT 8: SPD32 - 32bit SPDIF - not supported yet */
3106 static void cm9739_update_jacks(struct snd_ac97
*ac97
)
3108 /* shared Line-In / Surround Out */
3109 snd_ac97_update_bits(ac97
, AC97_CM9739_MULTI_CHAN
, 1 << 10,
3110 is_shared_surrout(ac97
) ? (1 << 10) : 0);
3111 /* shared Mic In / Center/LFE Out **/
3112 snd_ac97_update_bits(ac97
, AC97_CM9739_MULTI_CHAN
, 0x3000,
3113 is_shared_clfeout(ac97
) ? 0x1000 : 0x2000);
3116 static const struct snd_kcontrol_new snd_ac97_cm9739_controls
[] = {
3117 AC97_SURROUND_JACK_MODE_CTL
,
3118 AC97_CHANNEL_MODE_CTL
,
3121 static int patch_cm9739_specific(struct snd_ac97
* ac97
)
3123 return patch_build_controls(ac97
, snd_ac97_cm9739_controls
, ARRAY_SIZE(snd_ac97_cm9739_controls
));
3126 static int patch_cm9739_post_spdif(struct snd_ac97
* ac97
)
3128 return patch_build_controls(ac97
, snd_ac97_cm9739_controls_spdif
, ARRAY_SIZE(snd_ac97_cm9739_controls_spdif
));
3131 static const struct snd_ac97_build_ops patch_cm9739_ops
= {
3132 .build_specific
= patch_cm9739_specific
,
3133 .build_post_spdif
= patch_cm9739_post_spdif
,
3134 .update_jacks
= cm9739_update_jacks
3137 static int patch_cm9739(struct snd_ac97
* ac97
)
3141 ac97
->build_ops
= &patch_cm9739_ops
;
3143 /* CM9739/A has no Master and PCM volume although the register reacts */
3144 ac97
->flags
|= AC97_HAS_NO_MASTER_VOL
| AC97_HAS_NO_PCM_VOL
;
3145 snd_ac97_write_cache(ac97
, AC97_MASTER
, 0x8000);
3146 snd_ac97_write_cache(ac97
, AC97_PCM
, 0x8000);
3149 val
= snd_ac97_read(ac97
, AC97_EXTENDED_STATUS
);
3150 if (val
& AC97_EA_SPCV
) {
3151 /* enable spdif in */
3152 snd_ac97_write_cache(ac97
, AC97_CM9739_SPDIF_CTRL
,
3153 snd_ac97_read(ac97
, AC97_CM9739_SPDIF_CTRL
) | 0x01);
3154 ac97
->rates
[AC97_RATES_SPDIF
] = SNDRV_PCM_RATE_48000
; /* 48k only */
3156 ac97
->ext_id
&= ~AC97_EI_SPDIF
; /* disable extended-id */
3157 ac97
->rates
[AC97_RATES_SPDIF
] = 0;
3160 /* set-up multi channel */
3161 /* bit 14: 0 = SPDIF, 1 = EAPD */
3162 /* bit 13: enable internal vref output for mic */
3163 /* bit 12: disable center/lfe (swithable) */
3164 /* bit 10: disable surround/line (switchable) */
3165 /* bit 9: mix 2 surround off */
3166 /* bit 4: undocumented; 0 mutes the CM9739A, which defaults to 1 */
3167 /* bit 3: undocumented; surround? */
3169 val
= snd_ac97_read(ac97
, AC97_CM9739_MULTI_CHAN
) & (1 << 4);
3172 if (! (ac97
->ext_id
& AC97_EI_SPDIF
))
3174 snd_ac97_write_cache(ac97
, AC97_CM9739_MULTI_CHAN
, val
);
3176 /* FIXME: set up GPIO */
3177 snd_ac97_write_cache(ac97
, 0x70, 0x0100);
3178 snd_ac97_write_cache(ac97
, 0x72, 0x0020);
3179 /* Special exception for ASUS W1000/CMI9739. It does not have an SPDIF in. */
3181 ac97
->subsystem_vendor
== 0x1043 &&
3182 ac97
->subsystem_device
== 0x1843) {
3183 snd_ac97_write_cache(ac97
, AC97_CM9739_SPDIF_CTRL
,
3184 snd_ac97_read(ac97
, AC97_CM9739_SPDIF_CTRL
) & ~0x01);
3185 snd_ac97_write_cache(ac97
, AC97_CM9739_MULTI_CHAN
,
3186 snd_ac97_read(ac97
, AC97_CM9739_MULTI_CHAN
) | (1 << 14));
3192 #define AC97_CM9761_MULTI_CHAN 0x64
3193 #define AC97_CM9761_FUNC 0x66
3194 #define AC97_CM9761_SPDIF_CTRL 0x6c
3196 static void cm9761_update_jacks(struct snd_ac97
*ac97
)
3198 /* FIXME: check the bits for each model
3199 * model 83 is confirmed to work
3201 static unsigned short surr_on
[3][2] = {
3202 { 0x0008, 0x0000 }, /* 9761-78 & 82 */
3203 { 0x0000, 0x0008 }, /* 9761-82 rev.B */
3204 { 0x0000, 0x0008 }, /* 9761-83 */
3206 static unsigned short clfe_on
[3][2] = {
3207 { 0x0000, 0x1000 }, /* 9761-78 & 82 */
3208 { 0x1000, 0x0000 }, /* 9761-82 rev.B */
3209 { 0x0000, 0x1000 }, /* 9761-83 */
3211 static unsigned short surr_shared
[3][2] = {
3212 { 0x0000, 0x0400 }, /* 9761-78 & 82 */
3213 { 0x0000, 0x0400 }, /* 9761-82 rev.B */
3214 { 0x0000, 0x0400 }, /* 9761-83 */
3216 static unsigned short clfe_shared
[3][2] = {
3217 { 0x2000, 0x0880 }, /* 9761-78 & 82 */
3218 { 0x0000, 0x2880 }, /* 9761-82 rev.B */
3219 { 0x2000, 0x0800 }, /* 9761-83 */
3221 unsigned short val
= 0;
3223 val
|= surr_on
[ac97
->spec
.dev_flags
][is_surround_on(ac97
)];
3224 val
|= clfe_on
[ac97
->spec
.dev_flags
][is_clfe_on(ac97
)];
3225 val
|= surr_shared
[ac97
->spec
.dev_flags
][is_shared_surrout(ac97
)];
3226 val
|= clfe_shared
[ac97
->spec
.dev_flags
][is_shared_clfeout(ac97
)];
3228 snd_ac97_update_bits(ac97
, AC97_CM9761_MULTI_CHAN
, 0x3c88, val
);
3231 static const struct snd_kcontrol_new snd_ac97_cm9761_controls
[] = {
3232 AC97_SURROUND_JACK_MODE_CTL
,
3233 AC97_CHANNEL_MODE_CTL
,
3236 static int cm9761_spdif_out_source_info(struct snd_kcontrol
*kcontrol
, struct snd_ctl_elem_info
*uinfo
)
3238 static char *texts
[] = { "AC-Link", "ADC", "SPDIF-In" };
3240 uinfo
->type
= SNDRV_CTL_ELEM_TYPE_ENUMERATED
;
3242 uinfo
->value
.enumerated
.items
= 3;
3243 if (uinfo
->value
.enumerated
.item
> 2)
3244 uinfo
->value
.enumerated
.item
= 2;
3245 strcpy(uinfo
->value
.enumerated
.name
, texts
[uinfo
->value
.enumerated
.item
]);
3249 static int cm9761_spdif_out_source_get(struct snd_kcontrol
*kcontrol
, struct snd_ctl_elem_value
*ucontrol
)
3251 struct snd_ac97
*ac97
= snd_kcontrol_chip(kcontrol
);
3253 if (ac97
->regs
[AC97_CM9761_FUNC
] & 0x1)
3254 ucontrol
->value
.enumerated
.item
[0] = 2; /* SPDIF-loopback */
3255 else if (ac97
->regs
[AC97_CM9761_SPDIF_CTRL
] & 0x2)
3256 ucontrol
->value
.enumerated
.item
[0] = 1; /* ADC loopback */
3258 ucontrol
->value
.enumerated
.item
[0] = 0; /* AC-link */
3262 static int cm9761_spdif_out_source_put(struct snd_kcontrol
*kcontrol
, struct snd_ctl_elem_value
*ucontrol
)
3264 struct snd_ac97
*ac97
= snd_kcontrol_chip(kcontrol
);
3266 if (ucontrol
->value
.enumerated
.item
[0] == 2)
3267 return snd_ac97_update_bits(ac97
, AC97_CM9761_FUNC
, 0x1, 0x1);
3268 snd_ac97_update_bits(ac97
, AC97_CM9761_FUNC
, 0x1, 0);
3269 return snd_ac97_update_bits(ac97
, AC97_CM9761_SPDIF_CTRL
, 0x2,
3270 ucontrol
->value
.enumerated
.item
[0] == 1 ? 0x2 : 0);
3273 static const char *cm9761_dac_clock
[] = { "AC-Link", "SPDIF-In", "Both" };
3274 static const struct ac97_enum cm9761_dac_clock_enum
=
3275 AC97_ENUM_SINGLE(AC97_CM9761_SPDIF_CTRL
, 9, 3, cm9761_dac_clock
);
3277 static const struct snd_kcontrol_new snd_ac97_cm9761_controls_spdif
[] = {
3278 { /* BIT 1: SPDIFS */
3279 .iface
= SNDRV_CTL_ELEM_IFACE_MIXER
,
3280 .name
= SNDRV_CTL_NAME_IEC958("",PLAYBACK
,NONE
) "Source",
3281 .info
= cm9761_spdif_out_source_info
,
3282 .get
= cm9761_spdif_out_source_get
,
3283 .put
= cm9761_spdif_out_source_put
,
3285 /* BIT 2: IG_SPIV */
3286 AC97_SINGLE(SNDRV_CTL_NAME_IEC958("",CAPTURE
,NONE
) "Valid Switch", AC97_CM9761_SPDIF_CTRL
, 2, 1, 0),
3288 AC97_SINGLE(SNDRV_CTL_NAME_IEC958("",CAPTURE
,NONE
) "Monitor", AC97_CM9761_SPDIF_CTRL
, 3, 1, 0),
3289 /* BIT 4: SPI2SDI */
3290 AC97_SINGLE(SNDRV_CTL_NAME_IEC958("",CAPTURE
,SWITCH
), AC97_CM9761_SPDIF_CTRL
, 4, 1, 0),
3291 /* BIT 9-10: DAC_CTL */
3292 AC97_ENUM("DAC Clock Source", cm9761_dac_clock_enum
),
3295 static int patch_cm9761_post_spdif(struct snd_ac97
* ac97
)
3297 return patch_build_controls(ac97
, snd_ac97_cm9761_controls_spdif
, ARRAY_SIZE(snd_ac97_cm9761_controls_spdif
));
3300 static int patch_cm9761_specific(struct snd_ac97
* ac97
)
3302 return patch_build_controls(ac97
, snd_ac97_cm9761_controls
, ARRAY_SIZE(snd_ac97_cm9761_controls
));
3305 static const struct snd_ac97_build_ops patch_cm9761_ops
= {
3306 .build_specific
= patch_cm9761_specific
,
3307 .build_post_spdif
= patch_cm9761_post_spdif
,
3308 .update_jacks
= cm9761_update_jacks
3311 static int patch_cm9761(struct snd_ac97
*ac97
)
3315 /* CM9761 has no PCM volume although the register reacts */
3316 /* Master volume seems to have _some_ influence on the analog
3319 ac97
->flags
|= /*AC97_HAS_NO_MASTER_VOL |*/ AC97_HAS_NO_PCM_VOL
;
3320 snd_ac97_write_cache(ac97
, AC97_MASTER
, 0x8808);
3321 snd_ac97_write_cache(ac97
, AC97_PCM
, 0x8808);
3323 ac97
->spec
.dev_flags
= 0; /* 1 = model 82 revision B, 2 = model 83 */
3324 if (ac97
->id
== AC97_ID_CM9761_82
) {
3326 /* check page 1, reg 0x60 */
3327 val
= snd_ac97_read(ac97
, AC97_INT_PAGING
);
3328 snd_ac97_write_cache(ac97
, AC97_INT_PAGING
, (val
& ~0x0f) | 0x01);
3329 tmp
= snd_ac97_read(ac97
, 0x60);
3330 ac97
->spec
.dev_flags
= tmp
& 1; /* revision B? */
3331 snd_ac97_write_cache(ac97
, AC97_INT_PAGING
, val
);
3332 } else if (ac97
->id
== AC97_ID_CM9761_83
)
3333 ac97
->spec
.dev_flags
= 2;
3335 ac97
->build_ops
= &patch_cm9761_ops
;
3338 /* force the SPDIF bit in ext_id - codec doesn't set this bit! */
3339 ac97
->ext_id
|= AC97_EI_SPDIF
;
3340 /* to be sure: we overwrite the ext status bits */
3341 snd_ac97_write_cache(ac97
, AC97_EXTENDED_STATUS
, 0x05c0);
3342 /* Don't set 0x0200 here. This results in the silent analog output */
3343 snd_ac97_write_cache(ac97
, AC97_CM9761_SPDIF_CTRL
, 0x0001); /* enable spdif-in */
3344 ac97
->rates
[AC97_RATES_SPDIF
] = SNDRV_PCM_RATE_48000
; /* 48k only */
3346 /* set-up multi channel */
3347 /* bit 15: pc master beep off
3348 * bit 14: pin47 = EAPD/SPDIF
3349 * bit 13: vref ctl [= cm9739]
3350 * bit 12: CLFE control (reverted on rev B)
3351 * bit 11: Mic/center share (reverted on rev B)
3352 * bit 10: suddound/line share
3353 * bit 9: Analog-in mix -> surround
3354 * bit 8: Analog-in mix -> CLFE
3355 * bit 7: Mic/LFE share (mic/center/lfe)
3356 * bit 5: vref select (9761A)
3357 * bit 4: front control
3358 * bit 3: surround control (revereted with rev B)
3361 * bit 0: mic boost level (0=20dB, 1=30dB)
3365 if (ac97
->spec
.dev_flags
)
3370 val
= snd_ac97_read(ac97
, AC97_CM9761_MULTI_CHAN
);
3371 val
|= (1 << 4); /* front on */
3372 snd_ac97_write_cache(ac97
, AC97_CM9761_MULTI_CHAN
, val
);
3374 /* FIXME: set up GPIO */
3375 snd_ac97_write_cache(ac97
, 0x70, 0x0100);
3376 snd_ac97_write_cache(ac97
, 0x72, 0x0020);
3381 #define AC97_CM9780_SIDE 0x60
3382 #define AC97_CM9780_JACK 0x62
3383 #define AC97_CM9780_MIXER 0x64
3384 #define AC97_CM9780_MULTI_CHAN 0x66
3385 #define AC97_CM9780_SPDIF 0x6c
3387 static const char *cm9780_ch_select
[] = { "Front", "Side", "Center/LFE", "Rear" };
3388 static const struct ac97_enum cm9780_ch_select_enum
=
3389 AC97_ENUM_SINGLE(AC97_CM9780_MULTI_CHAN
, 6, 4, cm9780_ch_select
);
3390 static const struct snd_kcontrol_new cm9780_controls
[] = {
3391 AC97_DOUBLE("Side Playback Switch", AC97_CM9780_SIDE
, 15, 7, 1, 1),
3392 AC97_DOUBLE("Side Playback Volume", AC97_CM9780_SIDE
, 8, 0, 31, 0),
3393 AC97_ENUM("Side Playback Route", cm9780_ch_select_enum
),
3396 static int patch_cm9780_specific(struct snd_ac97
*ac97
)
3398 return patch_build_controls(ac97
, cm9780_controls
, ARRAY_SIZE(cm9780_controls
));
3401 static const struct snd_ac97_build_ops patch_cm9780_ops
= {
3402 .build_specific
= patch_cm9780_specific
,
3403 .build_post_spdif
= patch_cm9761_post_spdif
/* identical with CM9761 */
3406 static int patch_cm9780(struct snd_ac97
*ac97
)
3410 ac97
->build_ops
= &patch_cm9780_ops
;
3413 if (ac97
->ext_id
& AC97_EI_SPDIF
) {
3414 ac97
->rates
[AC97_RATES_SPDIF
] = SNDRV_PCM_RATE_48000
; /* 48k only */
3415 val
= snd_ac97_read(ac97
, AC97_CM9780_SPDIF
);
3416 val
|= 0x1; /* SPDI_EN */
3417 snd_ac97_write_cache(ac97
, AC97_CM9780_SPDIF
, val
);
3426 static const struct snd_kcontrol_new snd_ac97_controls_vt1616
[] = {
3427 AC97_SINGLE("DC Offset removal", 0x5a, 10, 1, 0),
3428 AC97_SINGLE("Alternate Level to Surround Out", 0x5a, 15, 1, 0),
3429 AC97_SINGLE("Downmix LFE and Center to Front", 0x5a, 12, 1, 0),
3430 AC97_SINGLE("Downmix Surround to Front", 0x5a, 11, 1, 0),
3433 static const char *slave_vols_vt1616
[] = {
3434 "Front Playback Volume",
3435 "Surround Playback Volume",
3436 "Center Playback Volume",
3437 "LFE Playback Volume",
3441 static const char *slave_sws_vt1616
[] = {
3442 "Front Playback Switch",
3443 "Surround Playback Switch",
3444 "Center Playback Switch",
3445 "LFE Playback Switch",
3449 /* find a mixer control element with the given name */
3450 static struct snd_kcontrol
*snd_ac97_find_mixer_ctl(struct snd_ac97
*ac97
,
3453 struct snd_ctl_elem_id id
;
3454 memset(&id
, 0, sizeof(id
));
3455 id
.iface
= SNDRV_CTL_ELEM_IFACE_MIXER
;
3456 strcpy(id
.name
, name
);
3457 return snd_ctl_find_id(ac97
->bus
->card
, &id
);
3460 /* create a virtual master control and add slaves */
3461 static int snd_ac97_add_vmaster(struct snd_ac97
*ac97
, char *name
,
3462 const unsigned int *tlv
, const char **slaves
)
3464 struct snd_kcontrol
*kctl
;
3468 kctl
= snd_ctl_make_virtual_master(name
, tlv
);
3471 err
= snd_ctl_add(ac97
->bus
->card
, kctl
);
3475 for (s
= slaves
; *s
; s
++) {
3476 struct snd_kcontrol
*sctl
;
3478 sctl
= snd_ac97_find_mixer_ctl(ac97
, *s
);
3480 snd_printdd("Cannot find slave %s, skipped\n", *s
);
3483 err
= snd_ctl_add_slave(kctl
, sctl
);
3490 static int patch_vt1616_specific(struct snd_ac97
* ac97
)
3492 struct snd_kcontrol
*kctl
;
3495 if (snd_ac97_try_bit(ac97
, 0x5a, 9))
3496 if ((err
= patch_build_controls(ac97
, &snd_ac97_controls_vt1616
[0], 1)) < 0)
3498 if ((err
= patch_build_controls(ac97
, &snd_ac97_controls_vt1616
[1], ARRAY_SIZE(snd_ac97_controls_vt1616
) - 1)) < 0)
3501 /* There is already a misnamed master switch. Rename it. */
3502 kctl
= snd_ac97_find_mixer_ctl(ac97
, "Master Playback Volume");
3506 snd_ac97_rename_vol_ctl(ac97
, "Master Playback", "Front Playback");
3508 err
= snd_ac97_add_vmaster(ac97
, "Master Playback Volume",
3509 kctl
->tlv
.p
, slave_vols_vt1616
);
3513 err
= snd_ac97_add_vmaster(ac97
, "Master Playback Switch",
3514 NULL
, slave_sws_vt1616
);
3521 static const struct snd_ac97_build_ops patch_vt1616_ops
= {
3522 .build_specific
= patch_vt1616_specific
3525 static int patch_vt1616(struct snd_ac97
* ac97
)
3527 ac97
->build_ops
= &patch_vt1616_ops
;
3536 * unfortunately, the vt1617a stashes the twiddlers required for
3537 * noodling the i/o jacks on 2 different regs. that means that we can't
3538 * use the easy way provided by AC97_ENUM_DOUBLE() we have to write
3541 * NB: this is absolutely and utterly different from the vt1618. dunno
3545 /* copied from ac97_surround_jack_mode_info() */
3546 static int snd_ac97_vt1617a_smart51_info(struct snd_kcontrol
*kcontrol
,
3547 struct snd_ctl_elem_info
*uinfo
)
3549 /* ordering in this list reflects vt1617a docs for Reg 20 and
3550 * 7a and Table 6 that lays out the matrix NB WRT Table6: SM51
3551 * is SM51EN *AND* it's Bit14, not Bit15 so the table is very
3552 * counter-intuitive */
3554 static const char* texts
[] = { "LineIn Mic1", "LineIn Mic1 Mic3",
3555 "Surr LFE/C Mic3", "LineIn LFE/C Mic3",
3556 "LineIn Mic2", "LineIn Mic2 Mic1",
3557 "Surr LFE Mic1", "Surr LFE Mic1 Mic2"};
3558 return ac97_enum_text_info(kcontrol
, uinfo
, texts
, 8);
3561 static int snd_ac97_vt1617a_smart51_get(struct snd_kcontrol
*kcontrol
,
3562 struct snd_ctl_elem_value
*ucontrol
)
3564 ushort usSM51
, usMS
;
3566 struct snd_ac97
*pac97
;
3568 pac97
= snd_kcontrol_chip(kcontrol
); /* grab codec handle */
3570 /* grab our desired bits, then mash them together in a manner
3571 * consistent with Table 6 on page 17 in the 1617a docs */
3573 usSM51
= snd_ac97_read(pac97
, 0x7a) >> 14;
3574 usMS
= snd_ac97_read(pac97
, 0x20) >> 8;
3576 ucontrol
->value
.enumerated
.item
[0] = (usSM51
<< 1) + usMS
;
3581 static int snd_ac97_vt1617a_smart51_put(struct snd_kcontrol
*kcontrol
,
3582 struct snd_ctl_elem_value
*ucontrol
)
3584 ushort usSM51
, usMS
, usReg
;
3586 struct snd_ac97
*pac97
;
3588 pac97
= snd_kcontrol_chip(kcontrol
); /* grab codec handle */
3590 usSM51
= ucontrol
->value
.enumerated
.item
[0] >> 1;
3591 usMS
= ucontrol
->value
.enumerated
.item
[0] & 1;
3593 /* push our values into the register - consider that things will be left
3594 * in a funky state if the write fails */
3596 usReg
= snd_ac97_read(pac97
, 0x7a);
3597 snd_ac97_write_cache(pac97
, 0x7a, (usReg
& 0x3FFF) + (usSM51
<< 14));
3598 usReg
= snd_ac97_read(pac97
, 0x20);
3599 snd_ac97_write_cache(pac97
, 0x20, (usReg
& 0xFEFF) + (usMS
<< 8));
3604 static const struct snd_kcontrol_new snd_ac97_controls_vt1617a
[] = {
3606 AC97_SINGLE("Center/LFE Exchange", 0x5a, 8, 1, 0),
3608 * These are used to enable/disable surround sound on motherboards
3609 * that have 3 bidirectional analog jacks
3612 .iface
= SNDRV_CTL_ELEM_IFACE_MIXER
,
3613 .name
= "Smart 5.1 Select",
3614 .info
= snd_ac97_vt1617a_smart51_info
,
3615 .get
= snd_ac97_vt1617a_smart51_get
,
3616 .put
= snd_ac97_vt1617a_smart51_put
,
3620 static int patch_vt1617a(struct snd_ac97
* ac97
)
3625 /* we choose to not fail out at this point, but we tell the
3626 caller when we return */
3628 err
= patch_build_controls(ac97
, &snd_ac97_controls_vt1617a
[0],
3629 ARRAY_SIZE(snd_ac97_controls_vt1617a
));
3631 /* bring analog power consumption to normal by turning off the
3632 * headphone amplifier, like WinXP driver for EPIA SP
3634 /* We need to check the bit before writing it.
3635 * On some (many?) hardwares, setting bit actually clears it!
3637 val
= snd_ac97_read(ac97
, 0x5c);
3639 snd_ac97_write_cache(ac97
, 0x5c, 0x20);
3641 ac97
->ext_id
|= AC97_EI_SPDIF
; /* force the detection of spdif */
3642 ac97
->rates
[AC97_RATES_SPDIF
] = SNDRV_PCM_RATE_44100
| SNDRV_PCM_RATE_48000
;
3643 ac97
->build_ops
= &patch_vt1616_ops
;
3648 /* VIA VT1618 8 CHANNEL AC97 CODEC
3650 * VIA implements 'Smart 5.1' completely differently on the 1618 than
3651 * it does on the 1617a. awesome! They seem to have sourced this
3652 * particular revision of the technology from somebody else, it's
3653 * called Universal Audio Jack and it shows up on some other folk's chips
3656 * ordering in this list reflects vt1618 docs for Reg 60h and
3657 * the block diagram, DACs are as follows:
3660 * OUT_1 -> Surround,
3663 * Unlike the 1617a, each OUT has a consistent set of mappings
3664 * for all bitpatterns other than 00:
3670 * Special Case of 00:
3672 * OUT_0 Mixed Output
3676 * I have no idea what the hell Reserved does, but on an MSI
3677 * CN700T, i have to set it to get 5.1 output - YMMV, bad
3680 * If other chips use Universal Audio Jack, then this code might be applicable
3684 struct vt1618_uaj_item
{
3685 unsigned short mask
;
3686 unsigned short shift
;
3687 const char *items
[4];
3690 /* This list reflects the vt1618 docs for Vendor Defined Register 0x60. */
3692 static struct vt1618_uaj_item vt1618_uaj
[3] = {
3698 "Speaker Out", "DAC Unmixed Out", "Line In", "Mic In"
3706 "Surround Out", "DAC Unmixed Out", "Line In", "Mic In"
3714 "Center LFE Out", "DAC Unmixed Out", "Line In", "Mic In"
3719 static int snd_ac97_vt1618_UAJ_info(struct snd_kcontrol
*kcontrol
,
3720 struct snd_ctl_elem_info
*uinfo
)
3722 return ac97_enum_text_info(kcontrol
, uinfo
,
3723 vt1618_uaj
[kcontrol
->private_value
].items
,
3727 /* All of the vt1618 Universal Audio Jack twiddlers are on
3728 * Vendor Defined Register 0x60, page 0. The bits, and thus
3729 * the mask, are the only thing that changes
3731 static int snd_ac97_vt1618_UAJ_get(struct snd_kcontrol
*kcontrol
,
3732 struct snd_ctl_elem_value
*ucontrol
)
3734 unsigned short datpag
, uaj
;
3735 struct snd_ac97
*pac97
= snd_kcontrol_chip(kcontrol
);
3737 mutex_lock(&pac97
->page_mutex
);
3739 datpag
= snd_ac97_read(pac97
, AC97_INT_PAGING
) & AC97_PAGE_MASK
;
3740 snd_ac97_update_bits(pac97
, AC97_INT_PAGING
, AC97_PAGE_MASK
, 0);
3742 uaj
= snd_ac97_read(pac97
, 0x60) &
3743 vt1618_uaj
[kcontrol
->private_value
].mask
;
3745 snd_ac97_update_bits(pac97
, AC97_INT_PAGING
, AC97_PAGE_MASK
, datpag
);
3746 mutex_unlock(&pac97
->page_mutex
);
3748 ucontrol
->value
.enumerated
.item
[0] = uaj
>>
3749 vt1618_uaj
[kcontrol
->private_value
].shift
;
3754 static int snd_ac97_vt1618_UAJ_put(struct snd_kcontrol
*kcontrol
,
3755 struct snd_ctl_elem_value
*ucontrol
)
3757 return ac97_update_bits_page(snd_kcontrol_chip(kcontrol
), 0x60,
3758 vt1618_uaj
[kcontrol
->private_value
].mask
,
3759 ucontrol
->value
.enumerated
.item
[0]<<
3760 vt1618_uaj
[kcontrol
->private_value
].shift
,
3764 /* config aux in jack - not found on 3 jack motherboards or soundcards */
3766 static int snd_ac97_vt1618_aux_info(struct snd_kcontrol
*kcontrol
,
3767 struct snd_ctl_elem_info
*uinfo
)
3769 static const char *txt_aux
[] = {"Aux In", "Back Surr Out"};
3771 return ac97_enum_text_info(kcontrol
, uinfo
, txt_aux
, 2);
3774 static int snd_ac97_vt1618_aux_get(struct snd_kcontrol
*kcontrol
,
3775 struct snd_ctl_elem_value
*ucontrol
)
3777 ucontrol
->value
.enumerated
.item
[0] =
3778 (snd_ac97_read(snd_kcontrol_chip(kcontrol
), 0x5c) & 0x0008)>>3;
3782 static int snd_ac97_vt1618_aux_put(struct snd_kcontrol
*kcontrol
,
3783 struct snd_ctl_elem_value
*ucontrol
)
3785 /* toggle surround rear dac power */
3787 snd_ac97_update_bits(snd_kcontrol_chip(kcontrol
), 0x5c, 0x0008,
3788 ucontrol
->value
.enumerated
.item
[0] << 3);
3790 /* toggle aux in surround rear out jack */
3792 return snd_ac97_update_bits(snd_kcontrol_chip(kcontrol
), 0x76, 0x0008,
3793 ucontrol
->value
.enumerated
.item
[0] << 3);
3796 static const struct snd_kcontrol_new snd_ac97_controls_vt1618
[] = {
3797 AC97_SINGLE("Exchange Center/LFE", 0x5a, 8, 1, 0),
3798 AC97_SINGLE("DC Offset", 0x5a, 10, 1, 0),
3799 AC97_SINGLE("Soft Mute", 0x5c, 0, 1, 1),
3800 AC97_SINGLE("Headphone Amp", 0x5c, 5, 1, 1),
3801 AC97_DOUBLE("Back Surr Volume", 0x5e, 8, 0, 31, 1),
3802 AC97_SINGLE("Back Surr Switch", 0x5e, 15, 1, 1),
3804 .iface
= SNDRV_CTL_ELEM_IFACE_MIXER
,
3805 .name
= "Speaker Jack Mode",
3806 .info
= snd_ac97_vt1618_UAJ_info
,
3807 .get
= snd_ac97_vt1618_UAJ_get
,
3808 .put
= snd_ac97_vt1618_UAJ_put
,
3812 .iface
= SNDRV_CTL_ELEM_IFACE_MIXER
,
3813 .name
= "Line Jack Mode",
3814 .info
= snd_ac97_vt1618_UAJ_info
,
3815 .get
= snd_ac97_vt1618_UAJ_get
,
3816 .put
= snd_ac97_vt1618_UAJ_put
,
3820 .iface
= SNDRV_CTL_ELEM_IFACE_MIXER
,
3821 .name
= "Mic Jack Mode",
3822 .info
= snd_ac97_vt1618_UAJ_info
,
3823 .get
= snd_ac97_vt1618_UAJ_get
,
3824 .put
= snd_ac97_vt1618_UAJ_put
,
3828 .iface
= SNDRV_CTL_ELEM_IFACE_MIXER
,
3829 .name
= "Aux Jack Mode",
3830 .info
= snd_ac97_vt1618_aux_info
,
3831 .get
= snd_ac97_vt1618_aux_get
,
3832 .put
= snd_ac97_vt1618_aux_put
,
3836 static int patch_vt1618(struct snd_ac97
*ac97
)
3838 return patch_build_controls(ac97
, snd_ac97_controls_vt1618
,
3839 ARRAY_SIZE(snd_ac97_controls_vt1618
));
3844 static void it2646_update_jacks(struct snd_ac97
*ac97
)
3846 /* shared Line-In / Surround Out */
3847 snd_ac97_update_bits(ac97
, 0x76, 1 << 9,
3848 is_shared_surrout(ac97
) ? (1<<9) : 0);
3849 /* shared Mic / Center/LFE Out */
3850 snd_ac97_update_bits(ac97
, 0x76, 1 << 10,
3851 is_shared_clfeout(ac97
) ? (1<<10) : 0);
3854 static const struct snd_kcontrol_new snd_ac97_controls_it2646
[] = {
3855 AC97_SURROUND_JACK_MODE_CTL
,
3856 AC97_CHANNEL_MODE_CTL
,
3859 static const struct snd_kcontrol_new snd_ac97_spdif_controls_it2646
[] = {
3860 AC97_SINGLE(SNDRV_CTL_NAME_IEC958("",CAPTURE
,SWITCH
), 0x76, 11, 1, 0),
3861 AC97_SINGLE("Analog to IEC958 Output", 0x76, 12, 1, 0),
3862 AC97_SINGLE("IEC958 Input Monitor", 0x76, 13, 1, 0),
3865 static int patch_it2646_specific(struct snd_ac97
* ac97
)
3868 if ((err
= patch_build_controls(ac97
, snd_ac97_controls_it2646
, ARRAY_SIZE(snd_ac97_controls_it2646
))) < 0)
3870 if ((err
= patch_build_controls(ac97
, snd_ac97_spdif_controls_it2646
, ARRAY_SIZE(snd_ac97_spdif_controls_it2646
))) < 0)
3875 static const struct snd_ac97_build_ops patch_it2646_ops
= {
3876 .build_specific
= patch_it2646_specific
,
3877 .update_jacks
= it2646_update_jacks
3880 static int patch_it2646(struct snd_ac97
* ac97
)
3882 ac97
->build_ops
= &patch_it2646_ops
;
3883 /* full DAC volume */
3884 snd_ac97_write_cache(ac97
, 0x5E, 0x0808);
3885 snd_ac97_write_cache(ac97
, 0x7A, 0x0808);
3893 #define AC97_SI3036_CHIP_ID 0x5a
3894 #define AC97_SI3036_LINE_CFG 0x5c
3896 static const struct snd_kcontrol_new snd_ac97_controls_si3036
[] = {
3897 AC97_DOUBLE("Modem Speaker Volume", 0x5c, 14, 12, 3, 1)
3900 static int patch_si3036_specific(struct snd_ac97
* ac97
)
3903 for (idx
= 0; idx
< ARRAY_SIZE(snd_ac97_controls_si3036
); idx
++)
3904 if ((err
= snd_ctl_add(ac97
->bus
->card
, snd_ctl_new1(&snd_ac97_controls_si3036
[idx
], ac97
))) < 0)
3909 static const struct snd_ac97_build_ops patch_si3036_ops
= {
3910 .build_specific
= patch_si3036_specific
,
3913 static int mpatch_si3036(struct snd_ac97
* ac97
)
3915 ac97
->build_ops
= &patch_si3036_ops
;
3916 snd_ac97_write_cache(ac97
, 0x5c, 0xf210 );
3917 snd_ac97_write_cache(ac97
, 0x68, 0);
3924 * We use a static resolution table since LM4550 codec cannot be
3925 * properly autoprobed to determine the resolution via
3926 * check_volume_resolution().
3929 static struct snd_ac97_res_table lm4550_restbl
[] = {
3930 { AC97_MASTER
, 0x1f1f },
3931 { AC97_HEADPHONE
, 0x1f1f },
3932 { AC97_MASTER_MONO
, 0x001f },
3933 { AC97_PC_BEEP
, 0x001f }, /* LSB is ignored */
3934 { AC97_PHONE
, 0x001f },
3935 { AC97_MIC
, 0x001f },
3936 { AC97_LINE
, 0x1f1f },
3937 { AC97_CD
, 0x1f1f },
3938 { AC97_VIDEO
, 0x1f1f },
3939 { AC97_AUX
, 0x1f1f },
3940 { AC97_PCM
, 0x1f1f },
3941 { AC97_REC_GAIN
, 0x0f0f },
3942 { } /* terminator */
3945 static int patch_lm4550(struct snd_ac97
*ac97
)
3947 ac97
->res_table
= lm4550_restbl
;
3952 * UCB1400 codec (http://www.semiconductors.philips.com/acrobat_download/datasheets/UCB1400-02.pdf)
3954 static const struct snd_kcontrol_new snd_ac97_controls_ucb1400
[] = {
3955 /* enable/disable headphone driver which allows direct connection to
3956 stereo headphone without the use of external DC blocking
3958 AC97_SINGLE("Headphone Driver", 0x6a, 6, 1, 0),
3959 /* Filter used to compensate the DC offset is added in the ADC to remove idle
3960 tones from the audio band. */
3961 AC97_SINGLE("DC Filter", 0x6a, 4, 1, 0),
3962 /* Control smart-low-power mode feature. Allows automatic power down
3963 of unused blocks in the ADC analog front end and the PLL. */
3964 AC97_SINGLE("Smart Low Power Mode", 0x6c, 4, 3, 0),
3967 static int patch_ucb1400_specific(struct snd_ac97
* ac97
)
3970 for (idx
= 0; idx
< ARRAY_SIZE(snd_ac97_controls_ucb1400
); idx
++)
3971 if ((err
= snd_ctl_add(ac97
->bus
->card
, snd_ctl_new1(&snd_ac97_controls_ucb1400
[idx
], ac97
))) < 0)
3976 static const struct snd_ac97_build_ops patch_ucb1400_ops
= {
3977 .build_specific
= patch_ucb1400_specific
,
3980 static int patch_ucb1400(struct snd_ac97
* ac97
)
3982 ac97
->build_ops
= &patch_ucb1400_ops
;
3983 /* enable headphone driver and smart low power mode by default */
3984 snd_ac97_write_cache(ac97
, 0x6a, 0x0050);
3985 snd_ac97_write_cache(ac97
, 0x6c, 0x0030);