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 * Chip specific initialization
33 static int patch_build_controls(struct snd_ac97
* ac97
, const struct snd_kcontrol_new
*controls
, int count
)
37 for (idx
= 0; idx
< count
; idx
++)
38 if ((err
= snd_ctl_add(ac97
->bus
->card
, snd_ac97_cnew(&controls
[idx
], ac97
))) < 0)
43 /* replace with a new TLV */
44 static void reset_tlv(struct snd_ac97
*ac97
, const char *name
,
45 const unsigned int *tlv
)
47 struct snd_ctl_elem_id sid
;
48 struct snd_kcontrol
*kctl
;
49 memset(&sid
, 0, sizeof(sid
));
50 strcpy(sid
.name
, name
);
51 sid
.iface
= SNDRV_CTL_ELEM_IFACE_MIXER
;
52 kctl
= snd_ctl_find_id(ac97
->bus
->card
, &sid
);
53 if (kctl
&& kctl
->tlv
.p
)
57 /* set to the page, update bits and restore the page */
58 static int ac97_update_bits_page(struct snd_ac97
*ac97
, unsigned short reg
, unsigned short mask
, unsigned short value
, unsigned short page
)
60 unsigned short page_save
;
63 mutex_lock(&ac97
->page_mutex
);
64 page_save
= snd_ac97_read(ac97
, AC97_INT_PAGING
) & AC97_PAGE_MASK
;
65 snd_ac97_update_bits(ac97
, AC97_INT_PAGING
, AC97_PAGE_MASK
, page
);
66 ret
= snd_ac97_update_bits(ac97
, reg
, mask
, value
);
67 snd_ac97_update_bits(ac97
, AC97_INT_PAGING
, AC97_PAGE_MASK
, page_save
);
68 mutex_unlock(&ac97
->page_mutex
); /* unlock paging */
73 * shared line-in/mic controls
75 static int ac97_enum_text_info(struct snd_kcontrol
*kcontrol
, struct snd_ctl_elem_info
*uinfo
,
76 const char **texts
, unsigned int nums
)
78 uinfo
->type
= SNDRV_CTL_ELEM_TYPE_ENUMERATED
;
80 uinfo
->value
.enumerated
.items
= nums
;
81 if (uinfo
->value
.enumerated
.item
> nums
- 1)
82 uinfo
->value
.enumerated
.item
= nums
- 1;
83 strcpy(uinfo
->value
.enumerated
.name
, texts
[uinfo
->value
.enumerated
.item
]);
87 static int ac97_surround_jack_mode_info(struct snd_kcontrol
*kcontrol
, struct snd_ctl_elem_info
*uinfo
)
89 static const char *texts
[] = { "Shared", "Independent" };
90 return ac97_enum_text_info(kcontrol
, uinfo
, texts
, 2);
93 static int ac97_surround_jack_mode_get(struct snd_kcontrol
*kcontrol
, struct snd_ctl_elem_value
*ucontrol
)
95 struct snd_ac97
*ac97
= snd_kcontrol_chip(kcontrol
);
97 ucontrol
->value
.enumerated
.item
[0] = ac97
->indep_surround
;
101 static int ac97_surround_jack_mode_put(struct snd_kcontrol
*kcontrol
, struct snd_ctl_elem_value
*ucontrol
)
103 struct snd_ac97
*ac97
= snd_kcontrol_chip(kcontrol
);
104 unsigned char indep
= !!ucontrol
->value
.enumerated
.item
[0];
106 if (indep
!= ac97
->indep_surround
) {
107 ac97
->indep_surround
= indep
;
108 if (ac97
->build_ops
->update_jacks
)
109 ac97
->build_ops
->update_jacks(ac97
);
115 static int ac97_channel_mode_info(struct snd_kcontrol
*kcontrol
, struct snd_ctl_elem_info
*uinfo
)
117 static const char *texts
[] = { "2ch", "4ch", "6ch", "8ch" };
118 return ac97_enum_text_info(kcontrol
, uinfo
, texts
,
119 kcontrol
->private_value
);
122 static int ac97_channel_mode_get(struct snd_kcontrol
*kcontrol
, struct snd_ctl_elem_value
*ucontrol
)
124 struct snd_ac97
*ac97
= snd_kcontrol_chip(kcontrol
);
126 ucontrol
->value
.enumerated
.item
[0] = ac97
->channel_mode
;
130 static int ac97_channel_mode_put(struct snd_kcontrol
*kcontrol
, struct snd_ctl_elem_value
*ucontrol
)
132 struct snd_ac97
*ac97
= snd_kcontrol_chip(kcontrol
);
133 unsigned char mode
= ucontrol
->value
.enumerated
.item
[0];
135 if (mode
>= kcontrol
->private_value
)
138 if (mode
!= ac97
->channel_mode
) {
139 ac97
->channel_mode
= mode
;
140 if (ac97
->build_ops
->update_jacks
)
141 ac97
->build_ops
->update_jacks(ac97
);
147 #define AC97_SURROUND_JACK_MODE_CTL \
149 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
150 .name = "Surround Jack Mode", \
151 .info = ac97_surround_jack_mode_info, \
152 .get = ac97_surround_jack_mode_get, \
153 .put = ac97_surround_jack_mode_put, \
156 #define AC97_CHANNEL_MODE_CTL \
158 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
159 .name = "Channel Mode", \
160 .info = ac97_channel_mode_info, \
161 .get = ac97_channel_mode_get, \
162 .put = ac97_channel_mode_put, \
163 .private_value = 3, \
166 #define AC97_CHANNEL_MODE_4CH_CTL \
168 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
169 .name = "Channel Mode", \
170 .info = ac97_channel_mode_info, \
171 .get = ac97_channel_mode_get, \
172 .put = ac97_channel_mode_put, \
173 .private_value = 2, \
176 #define AC97_CHANNEL_MODE_8CH_CTL \
178 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
179 .name = "Channel Mode", \
180 .info = ac97_channel_mode_info, \
181 .get = ac97_channel_mode_get, \
182 .put = ac97_channel_mode_put, \
183 .private_value = 4, \
186 static inline int is_surround_on(struct snd_ac97
*ac97
)
188 return ac97
->channel_mode
>= 1;
191 static inline int is_clfe_on(struct snd_ac97
*ac97
)
193 return ac97
->channel_mode
>= 2;
196 /* system has shared jacks with surround out enabled */
197 static inline int is_shared_surrout(struct snd_ac97
*ac97
)
199 return !ac97
->indep_surround
&& is_surround_on(ac97
);
202 /* system has shared jacks with center/lfe out enabled */
203 static inline int is_shared_clfeout(struct snd_ac97
*ac97
)
205 return !ac97
->indep_surround
&& is_clfe_on(ac97
);
208 /* system has shared jacks with line in enabled */
209 static inline int is_shared_linein(struct snd_ac97
*ac97
)
211 return !ac97
->indep_surround
&& !is_surround_on(ac97
);
214 /* system has shared jacks with mic in enabled */
215 static inline int is_shared_micin(struct snd_ac97
*ac97
)
217 return !ac97
->indep_surround
&& !is_clfe_on(ac97
);
220 static inline int alc850_is_aux_back_surround(struct snd_ac97
*ac97
)
222 return is_surround_on(ac97
);
225 /* The following snd_ac97_ymf753_... items added by David Shust (dshust@shustring.com) */
226 /* Modified for YMF743 by Keita Maehara <maehara@debian.org> */
228 /* It is possible to indicate to the Yamaha YMF7x3 the type of
229 speakers being used. */
231 static int snd_ac97_ymf7x3_info_speaker(struct snd_kcontrol
*kcontrol
,
232 struct snd_ctl_elem_info
*uinfo
)
234 static char *texts
[3] = {
235 "Standard", "Small", "Smaller"
238 uinfo
->type
= SNDRV_CTL_ELEM_TYPE_ENUMERATED
;
240 uinfo
->value
.enumerated
.items
= 3;
241 if (uinfo
->value
.enumerated
.item
> 2)
242 uinfo
->value
.enumerated
.item
= 2;
243 strcpy(uinfo
->value
.enumerated
.name
, texts
[uinfo
->value
.enumerated
.item
]);
247 static int snd_ac97_ymf7x3_get_speaker(struct snd_kcontrol
*kcontrol
,
248 struct snd_ctl_elem_value
*ucontrol
)
250 struct snd_ac97
*ac97
= snd_kcontrol_chip(kcontrol
);
253 val
= ac97
->regs
[AC97_YMF7X3_3D_MODE_SEL
];
254 val
= (val
>> 10) & 3;
255 if (val
> 0) /* 0 = invalid */
257 ucontrol
->value
.enumerated
.item
[0] = val
;
261 static int snd_ac97_ymf7x3_put_speaker(struct snd_kcontrol
*kcontrol
,
262 struct snd_ctl_elem_value
*ucontrol
)
264 struct snd_ac97
*ac97
= snd_kcontrol_chip(kcontrol
);
267 if (ucontrol
->value
.enumerated
.item
[0] > 2)
269 val
= (ucontrol
->value
.enumerated
.item
[0] + 1) << 10;
270 return snd_ac97_update(ac97
, AC97_YMF7X3_3D_MODE_SEL
, val
);
273 static const struct snd_kcontrol_new snd_ac97_ymf7x3_controls_speaker
=
275 .iface
= SNDRV_CTL_ELEM_IFACE_MIXER
,
276 .name
= "3D Control - Speaker",
277 .info
= snd_ac97_ymf7x3_info_speaker
,
278 .get
= snd_ac97_ymf7x3_get_speaker
,
279 .put
= snd_ac97_ymf7x3_put_speaker
,
282 /* It is possible to indicate to the Yamaha YMF7x3 the source to
283 direct to the S/PDIF output. */
284 static int snd_ac97_ymf7x3_spdif_source_info(struct snd_kcontrol
*kcontrol
,
285 struct snd_ctl_elem_info
*uinfo
)
287 static char *texts
[2] = { "AC-Link", "A/D Converter" };
289 uinfo
->type
= SNDRV_CTL_ELEM_TYPE_ENUMERATED
;
291 uinfo
->value
.enumerated
.items
= 2;
292 if (uinfo
->value
.enumerated
.item
> 1)
293 uinfo
->value
.enumerated
.item
= 1;
294 strcpy(uinfo
->value
.enumerated
.name
, texts
[uinfo
->value
.enumerated
.item
]);
298 static int snd_ac97_ymf7x3_spdif_source_get(struct snd_kcontrol
*kcontrol
,
299 struct snd_ctl_elem_value
*ucontrol
)
301 struct snd_ac97
*ac97
= snd_kcontrol_chip(kcontrol
);
304 val
= ac97
->regs
[AC97_YMF7X3_DIT_CTRL
];
305 ucontrol
->value
.enumerated
.item
[0] = (val
>> 1) & 1;
309 static int snd_ac97_ymf7x3_spdif_source_put(struct snd_kcontrol
*kcontrol
,
310 struct snd_ctl_elem_value
*ucontrol
)
312 struct snd_ac97
*ac97
= snd_kcontrol_chip(kcontrol
);
315 if (ucontrol
->value
.enumerated
.item
[0] > 1)
317 val
= ucontrol
->value
.enumerated
.item
[0] << 1;
318 return snd_ac97_update_bits(ac97
, AC97_YMF7X3_DIT_CTRL
, 0x0002, val
);
321 static int patch_yamaha_ymf7x3_3d(struct snd_ac97
*ac97
)
323 struct snd_kcontrol
*kctl
;
326 kctl
= snd_ac97_cnew(&snd_ac97_controls_3d
[0], ac97
);
327 err
= snd_ctl_add(ac97
->bus
->card
, kctl
);
330 strcpy(kctl
->id
.name
, "3D Control - Wide");
331 kctl
->private_value
= AC97_SINGLE_VALUE(AC97_3D_CONTROL
, 9, 7, 0);
332 snd_ac97_write_cache(ac97
, AC97_3D_CONTROL
, 0x0000);
333 err
= snd_ctl_add(ac97
->bus
->card
,
334 snd_ac97_cnew(&snd_ac97_ymf7x3_controls_speaker
,
338 snd_ac97_write_cache(ac97
, AC97_YMF7X3_3D_MODE_SEL
, 0x0c00);
342 static const struct snd_kcontrol_new snd_ac97_yamaha_ymf743_controls_spdif
[3] =
344 AC97_SINGLE(SNDRV_CTL_NAME_IEC958("", PLAYBACK
, SWITCH
),
345 AC97_YMF7X3_DIT_CTRL
, 0, 1, 0),
347 .iface
= SNDRV_CTL_ELEM_IFACE_MIXER
,
348 .name
= SNDRV_CTL_NAME_IEC958("", PLAYBACK
, NONE
) "Source",
349 .info
= snd_ac97_ymf7x3_spdif_source_info
,
350 .get
= snd_ac97_ymf7x3_spdif_source_get
,
351 .put
= snd_ac97_ymf7x3_spdif_source_put
,
353 AC97_SINGLE(SNDRV_CTL_NAME_IEC958("", NONE
, NONE
) "Mute",
354 AC97_YMF7X3_DIT_CTRL
, 2, 1, 1)
357 static int patch_yamaha_ymf743_build_spdif(struct snd_ac97
*ac97
)
361 err
= patch_build_controls(ac97
, &snd_ac97_controls_spdif
[0], 3);
364 err
= patch_build_controls(ac97
,
365 snd_ac97_yamaha_ymf743_controls_spdif
, 3);
368 /* set default PCM S/PDIF params */
369 /* PCM audio,no copyright,no preemphasis,PCM coder,original */
370 snd_ac97_write_cache(ac97
, AC97_YMF7X3_DIT_CTRL
, 0xa201);
374 static struct snd_ac97_build_ops patch_yamaha_ymf743_ops
= {
375 .build_spdif
= patch_yamaha_ymf743_build_spdif
,
376 .build_3d
= patch_yamaha_ymf7x3_3d
,
379 static int patch_yamaha_ymf743(struct snd_ac97
*ac97
)
381 ac97
->build_ops
= &patch_yamaha_ymf743_ops
;
382 ac97
->caps
|= AC97_BC_BASS_TREBLE
;
383 ac97
->caps
|= 0x04 << 10; /* Yamaha 3D enhancement */
384 ac97
->rates
[AC97_RATES_SPDIF
] = SNDRV_PCM_RATE_48000
; /* 48k only */
385 ac97
->ext_id
|= AC97_EI_SPDIF
; /* force the detection of spdif */
389 /* The AC'97 spec states that the S/PDIF signal is to be output at pin 48.
390 The YMF753 will output the S/PDIF signal to pin 43, 47 (EAPD), or 48.
391 By default, no output pin is selected, and the S/PDIF signal is not output.
392 There is also a bit to mute S/PDIF output in a vendor-specific register. */
393 static int snd_ac97_ymf753_spdif_output_pin_info(struct snd_kcontrol
*kcontrol
, struct snd_ctl_elem_info
*uinfo
)
395 static char *texts
[3] = { "Disabled", "Pin 43", "Pin 48" };
397 uinfo
->type
= SNDRV_CTL_ELEM_TYPE_ENUMERATED
;
399 uinfo
->value
.enumerated
.items
= 3;
400 if (uinfo
->value
.enumerated
.item
> 2)
401 uinfo
->value
.enumerated
.item
= 2;
402 strcpy(uinfo
->value
.enumerated
.name
, texts
[uinfo
->value
.enumerated
.item
]);
406 static int snd_ac97_ymf753_spdif_output_pin_get(struct snd_kcontrol
*kcontrol
, struct snd_ctl_elem_value
*ucontrol
)
408 struct snd_ac97
*ac97
= snd_kcontrol_chip(kcontrol
);
411 val
= ac97
->regs
[AC97_YMF7X3_DIT_CTRL
];
412 ucontrol
->value
.enumerated
.item
[0] = (val
& 0x0008) ? 2 : (val
& 0x0020) ? 1 : 0;
416 static int snd_ac97_ymf753_spdif_output_pin_put(struct snd_kcontrol
*kcontrol
, struct snd_ctl_elem_value
*ucontrol
)
418 struct snd_ac97
*ac97
= snd_kcontrol_chip(kcontrol
);
421 if (ucontrol
->value
.enumerated
.item
[0] > 2)
423 val
= (ucontrol
->value
.enumerated
.item
[0] == 2) ? 0x0008 :
424 (ucontrol
->value
.enumerated
.item
[0] == 1) ? 0x0020 : 0;
425 return snd_ac97_update_bits(ac97
, AC97_YMF7X3_DIT_CTRL
, 0x0028, val
);
426 /* The following can be used to direct S/PDIF output to pin 47 (EAPD).
427 snd_ac97_write_cache(ac97, 0x62, snd_ac97_read(ac97, 0x62) | 0x0008); */
430 static const struct snd_kcontrol_new snd_ac97_ymf753_controls_spdif
[3] = {
432 .iface
= SNDRV_CTL_ELEM_IFACE_MIXER
,
433 .name
= SNDRV_CTL_NAME_IEC958("",PLAYBACK
,NONE
) "Source",
434 .info
= snd_ac97_ymf7x3_spdif_source_info
,
435 .get
= snd_ac97_ymf7x3_spdif_source_get
,
436 .put
= snd_ac97_ymf7x3_spdif_source_put
,
439 .iface
= SNDRV_CTL_ELEM_IFACE_MIXER
,
440 .name
= SNDRV_CTL_NAME_IEC958("",PLAYBACK
,NONE
) "Output Pin",
441 .info
= snd_ac97_ymf753_spdif_output_pin_info
,
442 .get
= snd_ac97_ymf753_spdif_output_pin_get
,
443 .put
= snd_ac97_ymf753_spdif_output_pin_put
,
445 AC97_SINGLE(SNDRV_CTL_NAME_IEC958("", NONE
, NONE
) "Mute",
446 AC97_YMF7X3_DIT_CTRL
, 2, 1, 1)
449 static int patch_yamaha_ymf753_post_spdif(struct snd_ac97
* ac97
)
453 if ((err
= patch_build_controls(ac97
, snd_ac97_ymf753_controls_spdif
, ARRAY_SIZE(snd_ac97_ymf753_controls_spdif
))) < 0)
458 static struct snd_ac97_build_ops patch_yamaha_ymf753_ops
= {
459 .build_3d
= patch_yamaha_ymf7x3_3d
,
460 .build_post_spdif
= patch_yamaha_ymf753_post_spdif
463 static int patch_yamaha_ymf753(struct snd_ac97
* ac97
)
465 /* Patch for Yamaha YMF753, Copyright (c) by David Shust, dshust@shustring.com.
466 This chip has nonstandard and extended behaviour with regard to its S/PDIF output.
467 The AC'97 spec states that the S/PDIF signal is to be output at pin 48.
468 The YMF753 will ouput the S/PDIF signal to pin 43, 47 (EAPD), or 48.
469 By default, no output pin is selected, and the S/PDIF signal is not output.
470 There is also a bit to mute S/PDIF output in a vendor-specific register.
472 ac97
->build_ops
= &patch_yamaha_ymf753_ops
;
473 ac97
->caps
|= AC97_BC_BASS_TREBLE
;
474 ac97
->caps
|= 0x04 << 10; /* Yamaha 3D enhancement */
479 * May 2, 2003 Liam Girdwood <lrg@slimlogic.co.uk>
480 * removed broken wolfson00 patch.
481 * added support for WM9705,WM9708,WM9709,WM9710,WM9711,WM9712 and WM9717.
484 static const struct snd_kcontrol_new wm97xx_snd_ac97_controls
[] = {
485 AC97_DOUBLE("Front Playback Volume", AC97_WM97XX_FMIXER_VOL
, 8, 0, 31, 1),
486 AC97_SINGLE("Front Playback Switch", AC97_WM97XX_FMIXER_VOL
, 15, 1, 1),
489 static int patch_wolfson_wm9703_specific(struct snd_ac97
* ac97
)
491 /* This is known to work for the ViewSonic ViewPad 1000
492 * Randolph Bentson <bentson@holmsjoen.com>
493 * WM9703/9707/9708/9717
497 for (i
= 0; i
< ARRAY_SIZE(wm97xx_snd_ac97_controls
); i
++) {
498 if ((err
= snd_ctl_add(ac97
->bus
->card
, snd_ac97_cnew(&wm97xx_snd_ac97_controls
[i
], ac97
))) < 0)
501 snd_ac97_write_cache(ac97
, AC97_WM97XX_FMIXER_VOL
, 0x0808);
505 static struct snd_ac97_build_ops patch_wolfson_wm9703_ops
= {
506 .build_specific
= patch_wolfson_wm9703_specific
,
509 static int patch_wolfson03(struct snd_ac97
* ac97
)
511 ac97
->build_ops
= &patch_wolfson_wm9703_ops
;
515 static const struct snd_kcontrol_new wm9704_snd_ac97_controls
[] = {
516 AC97_DOUBLE("Front Playback Volume", AC97_WM97XX_FMIXER_VOL
, 8, 0, 31, 1),
517 AC97_SINGLE("Front Playback Switch", AC97_WM97XX_FMIXER_VOL
, 15, 1, 1),
518 AC97_DOUBLE("Rear Playback Volume", AC97_WM9704_RMIXER_VOL
, 8, 0, 31, 1),
519 AC97_SINGLE("Rear Playback Switch", AC97_WM9704_RMIXER_VOL
, 15, 1, 1),
520 AC97_DOUBLE("Rear DAC Volume", AC97_WM9704_RPCM_VOL
, 8, 0, 31, 1),
521 AC97_DOUBLE("Surround Volume", AC97_SURROUND_MASTER
, 8, 0, 31, 1),
524 static int patch_wolfson_wm9704_specific(struct snd_ac97
* ac97
)
527 for (i
= 0; i
< ARRAY_SIZE(wm9704_snd_ac97_controls
); i
++) {
528 if ((err
= snd_ctl_add(ac97
->bus
->card
, snd_ac97_cnew(&wm9704_snd_ac97_controls
[i
], ac97
))) < 0)
531 /* patch for DVD noise */
532 snd_ac97_write_cache(ac97
, AC97_WM9704_TEST
, 0x0200);
536 static struct snd_ac97_build_ops patch_wolfson_wm9704_ops
= {
537 .build_specific
= patch_wolfson_wm9704_specific
,
540 static int patch_wolfson04(struct snd_ac97
* ac97
)
543 ac97
->build_ops
= &patch_wolfson_wm9704_ops
;
547 static int patch_wolfson05(struct snd_ac97
* ac97
)
550 ac97
->build_ops
= &patch_wolfson_wm9703_ops
;
551 #ifdef CONFIG_TOUCHSCREEN_WM9705
552 /* WM9705 touchscreen uses AUX and VIDEO for touch */
553 ac97
->flags
|= AC97_HAS_NO_VIDEO
| AC97_HAS_NO_AUX
;
558 static const char* wm9711_alc_select
[] = {"None", "Left", "Right", "Stereo"};
559 static const char* wm9711_alc_mix
[] = {"Stereo", "Right", "Left", "None"};
560 static const char* wm9711_out3_src
[] = {"Left", "VREF", "Left + Right", "Mono"};
561 static const char* wm9711_out3_lrsrc
[] = {"Master Mix", "Headphone Mix"};
562 static const char* wm9711_rec_adc
[] = {"Stereo", "Left", "Right", "Mute"};
563 static const char* wm9711_base
[] = {"Linear Control", "Adaptive Boost"};
564 static const char* wm9711_rec_gain
[] = {"+1.5dB Steps", "+0.75dB Steps"};
565 static const char* wm9711_mic
[] = {"Mic 1", "Differential", "Mic 2", "Stereo"};
566 static const char* wm9711_rec_sel
[] =
567 {"Mic 1", "NC", "NC", "Master Mix", "Line", "Headphone Mix", "Phone Mix", "Phone"};
568 static const char* wm9711_ng_type
[] = {"Constant Gain", "Mute"};
570 static const struct ac97_enum wm9711_enum
[] = {
571 AC97_ENUM_SINGLE(AC97_PCI_SVID
, 14, 4, wm9711_alc_select
),
572 AC97_ENUM_SINGLE(AC97_VIDEO
, 10, 4, wm9711_alc_mix
),
573 AC97_ENUM_SINGLE(AC97_AUX
, 9, 4, wm9711_out3_src
),
574 AC97_ENUM_SINGLE(AC97_AUX
, 8, 2, wm9711_out3_lrsrc
),
575 AC97_ENUM_SINGLE(AC97_REC_SEL
, 12, 4, wm9711_rec_adc
),
576 AC97_ENUM_SINGLE(AC97_MASTER_TONE
, 15, 2, wm9711_base
),
577 AC97_ENUM_DOUBLE(AC97_REC_GAIN
, 14, 6, 2, wm9711_rec_gain
),
578 AC97_ENUM_SINGLE(AC97_MIC
, 5, 4, wm9711_mic
),
579 AC97_ENUM_DOUBLE(AC97_REC_SEL
, 8, 0, 8, wm9711_rec_sel
),
580 AC97_ENUM_SINGLE(AC97_PCI_SVID
, 5, 2, wm9711_ng_type
),
583 static const struct snd_kcontrol_new wm9711_snd_ac97_controls
[] = {
584 AC97_SINGLE("ALC Target Volume", AC97_CODEC_CLASS_REV
, 12, 15, 0),
585 AC97_SINGLE("ALC Hold Time", AC97_CODEC_CLASS_REV
, 8, 15, 0),
586 AC97_SINGLE("ALC Decay Time", AC97_CODEC_CLASS_REV
, 4, 15, 0),
587 AC97_SINGLE("ALC Attack Time", AC97_CODEC_CLASS_REV
, 0, 15, 0),
588 AC97_ENUM("ALC Function", wm9711_enum
[0]),
589 AC97_SINGLE("ALC Max Volume", AC97_PCI_SVID
, 11, 7, 1),
590 AC97_SINGLE("ALC ZC Timeout", AC97_PCI_SVID
, 9, 3, 1),
591 AC97_SINGLE("ALC ZC Switch", AC97_PCI_SVID
, 8, 1, 0),
592 AC97_SINGLE("ALC NG Switch", AC97_PCI_SVID
, 7, 1, 0),
593 AC97_ENUM("ALC NG Type", wm9711_enum
[9]),
594 AC97_SINGLE("ALC NG Threshold", AC97_PCI_SVID
, 0, 31, 1),
596 AC97_SINGLE("Side Tone Switch", AC97_VIDEO
, 15, 1, 1),
597 AC97_SINGLE("Side Tone Volume", AC97_VIDEO
, 12, 7, 1),
598 AC97_ENUM("ALC Headphone Mux", wm9711_enum
[1]),
599 AC97_SINGLE("ALC Headphone Volume", AC97_VIDEO
, 7, 7, 1),
601 AC97_SINGLE("Out3 Switch", AC97_AUX
, 15, 1, 1),
602 AC97_SINGLE("Out3 ZC Switch", AC97_AUX
, 7, 1, 0),
603 AC97_ENUM("Out3 Mux", wm9711_enum
[2]),
604 AC97_ENUM("Out3 LR Mux", wm9711_enum
[3]),
605 AC97_SINGLE("Out3 Volume", AC97_AUX
, 0, 31, 1),
607 AC97_SINGLE("Beep to Headphone Switch", AC97_PC_BEEP
, 15, 1, 1),
608 AC97_SINGLE("Beep to Headphone Volume", AC97_PC_BEEP
, 12, 7, 1),
609 AC97_SINGLE("Beep to Side Tone Switch", AC97_PC_BEEP
, 11, 1, 1),
610 AC97_SINGLE("Beep to Side Tone Volume", AC97_PC_BEEP
, 8, 7, 1),
611 AC97_SINGLE("Beep to Phone Switch", AC97_PC_BEEP
, 7, 1, 1),
612 AC97_SINGLE("Beep to Phone Volume", AC97_PC_BEEP
, 4, 7, 1),
614 AC97_SINGLE("Aux to Headphone Switch", AC97_CD
, 15, 1, 1),
615 AC97_SINGLE("Aux to Headphone Volume", AC97_CD
, 12, 7, 1),
616 AC97_SINGLE("Aux to Side Tone Switch", AC97_CD
, 11, 1, 1),
617 AC97_SINGLE("Aux to Side Tone Volume", AC97_CD
, 8, 7, 1),
618 AC97_SINGLE("Aux to Phone Switch", AC97_CD
, 7, 1, 1),
619 AC97_SINGLE("Aux to Phone Volume", AC97_CD
, 4, 7, 1),
621 AC97_SINGLE("Phone to Headphone Switch", AC97_PHONE
, 15, 1, 1),
622 AC97_SINGLE("Phone to Master Switch", AC97_PHONE
, 14, 1, 1),
624 AC97_SINGLE("Line to Headphone Switch", AC97_LINE
, 15, 1, 1),
625 AC97_SINGLE("Line to Master Switch", AC97_LINE
, 14, 1, 1),
626 AC97_SINGLE("Line to Phone Switch", AC97_LINE
, 13, 1, 1),
628 AC97_SINGLE("PCM Playback to Headphone Switch", AC97_PCM
, 15, 1, 1),
629 AC97_SINGLE("PCM Playback to Master Switch", AC97_PCM
, 14, 1, 1),
630 AC97_SINGLE("PCM Playback to Phone Switch", AC97_PCM
, 13, 1, 1),
632 AC97_SINGLE("Capture 20dB Boost Switch", AC97_REC_SEL
, 14, 1, 0),
633 AC97_ENUM("Capture to Phone Mux", wm9711_enum
[4]),
634 AC97_SINGLE("Capture to Phone 20dB Boost Switch", AC97_REC_SEL
, 11, 1, 1),
635 AC97_ENUM("Capture Select", wm9711_enum
[8]),
637 AC97_SINGLE("3D Upper Cut-off Switch", AC97_3D_CONTROL
, 5, 1, 1),
638 AC97_SINGLE("3D Lower Cut-off Switch", AC97_3D_CONTROL
, 4, 1, 1),
640 AC97_ENUM("Bass Control", wm9711_enum
[5]),
641 AC97_SINGLE("Bass Cut-off Switch", AC97_MASTER_TONE
, 12, 1, 1),
642 AC97_SINGLE("Tone Cut-off Switch", AC97_MASTER_TONE
, 4, 1, 1),
643 AC97_SINGLE("Playback Attenuate (-6dB) Switch", AC97_MASTER_TONE
, 6, 1, 0),
645 AC97_SINGLE("ADC Switch", AC97_REC_GAIN
, 15, 1, 1),
646 AC97_ENUM("Capture Volume Steps", wm9711_enum
[6]),
647 AC97_DOUBLE("Capture Volume", AC97_REC_GAIN
, 8, 0, 63, 1),
648 AC97_SINGLE("Capture ZC Switch", AC97_REC_GAIN
, 7, 1, 0),
650 AC97_SINGLE("Mic 1 to Phone Switch", AC97_MIC
, 14, 1, 1),
651 AC97_SINGLE("Mic 2 to Phone Switch", AC97_MIC
, 13, 1, 1),
652 AC97_ENUM("Mic Select Source", wm9711_enum
[7]),
653 AC97_SINGLE("Mic 1 Volume", AC97_MIC
, 8, 31, 1),
654 AC97_SINGLE("Mic 2 Volume", AC97_MIC
, 0, 31, 1),
655 AC97_SINGLE("Mic 20dB Boost Switch", AC97_MIC
, 7, 1, 0),
657 AC97_SINGLE("Master Left Inv Switch", AC97_MASTER
, 6, 1, 0),
658 AC97_SINGLE("Master ZC Switch", AC97_MASTER
, 7, 1, 0),
659 AC97_SINGLE("Headphone ZC Switch", AC97_HEADPHONE
, 7, 1, 0),
660 AC97_SINGLE("Mono ZC Switch", AC97_MASTER_MONO
, 7, 1, 0),
663 static int patch_wolfson_wm9711_specific(struct snd_ac97
* ac97
)
667 for (i
= 0; i
< ARRAY_SIZE(wm9711_snd_ac97_controls
); i
++) {
668 if ((err
= snd_ctl_add(ac97
->bus
->card
, snd_ac97_cnew(&wm9711_snd_ac97_controls
[i
], ac97
))) < 0)
671 snd_ac97_write_cache(ac97
, AC97_CODEC_CLASS_REV
, 0x0808);
672 snd_ac97_write_cache(ac97
, AC97_PCI_SVID
, 0x0808);
673 snd_ac97_write_cache(ac97
, AC97_VIDEO
, 0x0808);
674 snd_ac97_write_cache(ac97
, AC97_AUX
, 0x0808);
675 snd_ac97_write_cache(ac97
, AC97_PC_BEEP
, 0x0808);
676 snd_ac97_write_cache(ac97
, AC97_CD
, 0x0000);
680 static struct snd_ac97_build_ops patch_wolfson_wm9711_ops
= {
681 .build_specific
= patch_wolfson_wm9711_specific
,
684 static int patch_wolfson11(struct snd_ac97
* ac97
)
687 ac97
->build_ops
= &patch_wolfson_wm9711_ops
;
689 ac97
->flags
|= AC97_HAS_NO_REC_GAIN
| AC97_STEREO_MUTES
| AC97_HAS_NO_MIC
|
690 AC97_HAS_NO_PC_BEEP
| AC97_HAS_NO_VIDEO
| AC97_HAS_NO_CD
;
695 static const char* wm9713_mic_mixer
[] = {"Stereo", "Mic 1", "Mic 2", "Mute"};
696 static const char* wm9713_rec_mux
[] = {"Stereo", "Left", "Right", "Mute"};
697 static const char* wm9713_rec_src
[] =
698 {"Mic 1", "Mic 2", "Line", "Mono In", "Headphone Mix", "Master Mix",
700 static const char* wm9713_rec_gain
[] = {"+1.5dB Steps", "+0.75dB Steps"};
701 static const char* wm9713_alc_select
[] = {"None", "Left", "Right", "Stereo"};
702 static const char* wm9713_mono_pga
[] = {"Vmid", "Zh", "Mono Mix", "Inv 1"};
703 static const char* wm9713_spk_pga
[] =
704 {"Vmid", "Zh", "Headphone Mix", "Master Mix", "Inv", "NC", "NC", "NC"};
705 static const char* wm9713_hp_pga
[] = {"Vmid", "Zh", "Headphone Mix", "NC"};
706 static const char* wm9713_out3_pga
[] = {"Vmid", "Zh", "Inv 1", "NC"};
707 static const char* wm9713_out4_pga
[] = {"Vmid", "Zh", "Inv 2", "NC"};
708 static const char* wm9713_dac_inv
[] =
709 {"Off", "Mono Mix", "Master Mix", "Headphone Mix L", "Headphone Mix R",
710 "Headphone Mix Mono", "NC", "Vmid"};
711 static const char* wm9713_base
[] = {"Linear Control", "Adaptive Boost"};
712 static const char* wm9713_ng_type
[] = {"Constant Gain", "Mute"};
714 static const struct ac97_enum wm9713_enum
[] = {
715 AC97_ENUM_SINGLE(AC97_LINE
, 3, 4, wm9713_mic_mixer
),
716 AC97_ENUM_SINGLE(AC97_VIDEO
, 14, 4, wm9713_rec_mux
),
717 AC97_ENUM_SINGLE(AC97_VIDEO
, 9, 4, wm9713_rec_mux
),
718 AC97_ENUM_DOUBLE(AC97_VIDEO
, 3, 0, 8, wm9713_rec_src
),
719 AC97_ENUM_DOUBLE(AC97_CD
, 14, 6, 2, wm9713_rec_gain
),
720 AC97_ENUM_SINGLE(AC97_PCI_SVID
, 14, 4, wm9713_alc_select
),
721 AC97_ENUM_SINGLE(AC97_REC_GAIN
, 14, 4, wm9713_mono_pga
),
722 AC97_ENUM_DOUBLE(AC97_REC_GAIN
, 11, 8, 8, wm9713_spk_pga
),
723 AC97_ENUM_DOUBLE(AC97_REC_GAIN
, 6, 4, 4, wm9713_hp_pga
),
724 AC97_ENUM_SINGLE(AC97_REC_GAIN
, 2, 4, wm9713_out3_pga
),
725 AC97_ENUM_SINGLE(AC97_REC_GAIN
, 0, 4, wm9713_out4_pga
),
726 AC97_ENUM_DOUBLE(AC97_REC_GAIN_MIC
, 13, 10, 8, wm9713_dac_inv
),
727 AC97_ENUM_SINGLE(AC97_GENERAL_PURPOSE
, 15, 2, wm9713_base
),
728 AC97_ENUM_SINGLE(AC97_PCI_SVID
, 5, 2, wm9713_ng_type
),
731 static const struct snd_kcontrol_new wm13_snd_ac97_controls
[] = {
732 AC97_DOUBLE("Line In Volume", AC97_PC_BEEP
, 8, 0, 31, 1),
733 AC97_SINGLE("Line In to Headphone Switch", AC97_PC_BEEP
, 15, 1, 1),
734 AC97_SINGLE("Line In to Master Switch", AC97_PC_BEEP
, 14, 1, 1),
735 AC97_SINGLE("Line In to Mono Switch", AC97_PC_BEEP
, 13, 1, 1),
737 AC97_DOUBLE("PCM Playback Volume", AC97_PHONE
, 8, 0, 31, 1),
738 AC97_SINGLE("PCM Playback to Headphone Switch", AC97_PHONE
, 15, 1, 1),
739 AC97_SINGLE("PCM Playback to Master Switch", AC97_PHONE
, 14, 1, 1),
740 AC97_SINGLE("PCM Playback to Mono Switch", AC97_PHONE
, 13, 1, 1),
742 AC97_SINGLE("Mic 1 Volume", AC97_MIC
, 8, 31, 1),
743 AC97_SINGLE("Mic 2 Volume", AC97_MIC
, 0, 31, 1),
744 AC97_SINGLE("Mic 1 to Mono Switch", AC97_LINE
, 7, 1, 1),
745 AC97_SINGLE("Mic 2 to Mono Switch", AC97_LINE
, 6, 1, 1),
746 AC97_SINGLE("Mic Boost (+20dB) Switch", AC97_LINE
, 5, 1, 0),
747 AC97_ENUM("Mic to Headphone Mux", wm9713_enum
[0]),
748 AC97_SINGLE("Mic Headphone Mixer Volume", AC97_LINE
, 0, 7, 1),
750 AC97_SINGLE("Capture Switch", AC97_CD
, 15, 1, 1),
751 AC97_ENUM("Capture Volume Steps", wm9713_enum
[4]),
752 AC97_DOUBLE("Capture Volume", AC97_CD
, 8, 0, 15, 0),
753 AC97_SINGLE("Capture ZC Switch", AC97_CD
, 7, 1, 0),
755 AC97_ENUM("Capture to Headphone Mux", wm9713_enum
[1]),
756 AC97_SINGLE("Capture to Headphone Volume", AC97_VIDEO
, 11, 7, 1),
757 AC97_ENUM("Capture to Mono Mux", wm9713_enum
[2]),
758 AC97_SINGLE("Capture to Mono Boost (+20dB) Switch", AC97_VIDEO
, 8, 1, 0),
759 AC97_SINGLE("Capture ADC Boost (+20dB) Switch", AC97_VIDEO
, 6, 1, 0),
760 AC97_ENUM("Capture Select", wm9713_enum
[3]),
762 AC97_SINGLE("ALC Target Volume", AC97_CODEC_CLASS_REV
, 12, 15, 0),
763 AC97_SINGLE("ALC Hold Time", AC97_CODEC_CLASS_REV
, 8, 15, 0),
764 AC97_SINGLE("ALC Decay Time ", AC97_CODEC_CLASS_REV
, 4, 15, 0),
765 AC97_SINGLE("ALC Attack Time", AC97_CODEC_CLASS_REV
, 0, 15, 0),
766 AC97_ENUM("ALC Function", wm9713_enum
[5]),
767 AC97_SINGLE("ALC Max Volume", AC97_PCI_SVID
, 11, 7, 0),
768 AC97_SINGLE("ALC ZC Timeout", AC97_PCI_SVID
, 9, 3, 0),
769 AC97_SINGLE("ALC ZC Switch", AC97_PCI_SVID
, 8, 1, 0),
770 AC97_SINGLE("ALC NG Switch", AC97_PCI_SVID
, 7, 1, 0),
771 AC97_ENUM("ALC NG Type", wm9713_enum
[13]),
772 AC97_SINGLE("ALC NG Threshold", AC97_PCI_SVID
, 0, 31, 0),
774 AC97_DOUBLE("Master ZC Switch", AC97_MASTER
, 14, 6, 1, 0),
775 AC97_DOUBLE("Headphone ZC Switch", AC97_HEADPHONE
, 14, 6, 1, 0),
776 AC97_DOUBLE("Out3/4 ZC Switch", AC97_MASTER_MONO
, 14, 6, 1, 0),
777 AC97_SINGLE("Master Right Switch", AC97_MASTER
, 7, 1, 1),
778 AC97_SINGLE("Headphone Right Switch", AC97_HEADPHONE
, 7, 1, 1),
779 AC97_SINGLE("Out3/4 Right Switch", AC97_MASTER_MONO
, 7, 1, 1),
781 AC97_SINGLE("Mono In to Headphone Switch", AC97_MASTER_TONE
, 15, 1, 1),
782 AC97_SINGLE("Mono In to Master Switch", AC97_MASTER_TONE
, 14, 1, 1),
783 AC97_SINGLE("Mono In Volume", AC97_MASTER_TONE
, 8, 31, 1),
784 AC97_SINGLE("Mono Switch", AC97_MASTER_TONE
, 7, 1, 1),
785 AC97_SINGLE("Mono ZC Switch", AC97_MASTER_TONE
, 6, 1, 0),
786 AC97_SINGLE("Mono Volume", AC97_MASTER_TONE
, 0, 31, 1),
788 AC97_SINGLE("Beep to Headphone Switch", AC97_AUX
, 15, 1, 1),
789 AC97_SINGLE("Beep to Headphone Volume", AC97_AUX
, 12, 7, 1),
790 AC97_SINGLE("Beep to Master Switch", AC97_AUX
, 11, 1, 1),
791 AC97_SINGLE("Beep to Master Volume", AC97_AUX
, 8, 7, 1),
792 AC97_SINGLE("Beep to Mono Switch", AC97_AUX
, 7, 1, 1),
793 AC97_SINGLE("Beep to Mono Volume", AC97_AUX
, 4, 7, 1),
795 AC97_SINGLE("Voice to Headphone Switch", AC97_PCM
, 15, 1, 1),
796 AC97_SINGLE("Voice to Headphone Volume", AC97_PCM
, 12, 7, 1),
797 AC97_SINGLE("Voice to Master Switch", AC97_PCM
, 11, 1, 1),
798 AC97_SINGLE("Voice to Master Volume", AC97_PCM
, 8, 7, 1),
799 AC97_SINGLE("Voice to Mono Switch", AC97_PCM
, 7, 1, 1),
800 AC97_SINGLE("Voice to Mono Volume", AC97_PCM
, 4, 7, 1),
802 AC97_SINGLE("Aux to Headphone Switch", AC97_REC_SEL
, 15, 1, 1),
803 AC97_SINGLE("Aux to Headphone Volume", AC97_REC_SEL
, 12, 7, 1),
804 AC97_SINGLE("Aux to Master Switch", AC97_REC_SEL
, 11, 1, 1),
805 AC97_SINGLE("Aux to Master Volume", AC97_REC_SEL
, 8, 7, 1),
806 AC97_SINGLE("Aux to Mono Switch", AC97_REC_SEL
, 7, 1, 1),
807 AC97_SINGLE("Aux to Mono Volume", AC97_REC_SEL
, 4, 7, 1),
809 AC97_ENUM("Mono Input Mux", wm9713_enum
[6]),
810 AC97_ENUM("Master Input Mux", wm9713_enum
[7]),
811 AC97_ENUM("Headphone Input Mux", wm9713_enum
[8]),
812 AC97_ENUM("Out 3 Input Mux", wm9713_enum
[9]),
813 AC97_ENUM("Out 4 Input Mux", wm9713_enum
[10]),
815 AC97_ENUM("Bass Control", wm9713_enum
[12]),
816 AC97_SINGLE("Bass Cut-off Switch", AC97_GENERAL_PURPOSE
, 12, 1, 1),
817 AC97_SINGLE("Tone Cut-off Switch", AC97_GENERAL_PURPOSE
, 4, 1, 1),
818 AC97_SINGLE("Playback Attenuate (-6dB) Switch", AC97_GENERAL_PURPOSE
, 6, 1, 0),
819 AC97_SINGLE("Bass Volume", AC97_GENERAL_PURPOSE
, 8, 15, 1),
820 AC97_SINGLE("Tone Volume", AC97_GENERAL_PURPOSE
, 0, 15, 1),
823 static const struct snd_kcontrol_new wm13_snd_ac97_controls_3d
[] = {
824 AC97_ENUM("Inv Input Mux", wm9713_enum
[11]),
825 AC97_SINGLE("3D Upper Cut-off Switch", AC97_REC_GAIN_MIC
, 5, 1, 0),
826 AC97_SINGLE("3D Lower Cut-off Switch", AC97_REC_GAIN_MIC
, 4, 1, 0),
827 AC97_SINGLE("3D Depth", AC97_REC_GAIN_MIC
, 0, 15, 1),
830 static int patch_wolfson_wm9713_3d (struct snd_ac97
* ac97
)
834 for (i
= 0; i
< ARRAY_SIZE(wm13_snd_ac97_controls_3d
); i
++) {
835 if ((err
= snd_ctl_add(ac97
->bus
->card
, snd_ac97_cnew(&wm13_snd_ac97_controls_3d
[i
], ac97
))) < 0)
841 static int patch_wolfson_wm9713_specific(struct snd_ac97
* ac97
)
845 for (i
= 0; i
< ARRAY_SIZE(wm13_snd_ac97_controls
); i
++) {
846 if ((err
= snd_ctl_add(ac97
->bus
->card
, snd_ac97_cnew(&wm13_snd_ac97_controls
[i
], ac97
))) < 0)
849 snd_ac97_write_cache(ac97
, AC97_PC_BEEP
, 0x0808);
850 snd_ac97_write_cache(ac97
, AC97_PHONE
, 0x0808);
851 snd_ac97_write_cache(ac97
, AC97_MIC
, 0x0808);
852 snd_ac97_write_cache(ac97
, AC97_LINE
, 0x00da);
853 snd_ac97_write_cache(ac97
, AC97_CD
, 0x0808);
854 snd_ac97_write_cache(ac97
, AC97_VIDEO
, 0xd612);
855 snd_ac97_write_cache(ac97
, AC97_REC_GAIN
, 0x1ba0);
860 static void patch_wolfson_wm9713_suspend (struct snd_ac97
* ac97
)
862 snd_ac97_write_cache(ac97
, AC97_EXTENDED_MID
, 0xfeff);
863 snd_ac97_write_cache(ac97
, AC97_EXTENDED_MSTATUS
, 0xffff);
866 static void patch_wolfson_wm9713_resume (struct snd_ac97
* ac97
)
868 snd_ac97_write_cache(ac97
, AC97_EXTENDED_MID
, 0xda00);
869 snd_ac97_write_cache(ac97
, AC97_EXTENDED_MSTATUS
, 0x3810);
870 snd_ac97_write_cache(ac97
, AC97_POWERDOWN
, 0x0);
874 static struct snd_ac97_build_ops patch_wolfson_wm9713_ops
= {
875 .build_specific
= patch_wolfson_wm9713_specific
,
876 .build_3d
= patch_wolfson_wm9713_3d
,
878 .suspend
= patch_wolfson_wm9713_suspend
,
879 .resume
= patch_wolfson_wm9713_resume
883 static int patch_wolfson13(struct snd_ac97
* ac97
)
886 ac97
->build_ops
= &patch_wolfson_wm9713_ops
;
888 ac97
->flags
|= AC97_HAS_NO_REC_GAIN
| AC97_STEREO_MUTES
| AC97_HAS_NO_PHONE
|
889 AC97_HAS_NO_PC_BEEP
| AC97_HAS_NO_VIDEO
| AC97_HAS_NO_CD
| AC97_HAS_NO_TONE
|
891 ac97
->scaps
&= ~AC97_SCAP_MODEM
;
893 snd_ac97_write_cache(ac97
, AC97_EXTENDED_MID
, 0xda00);
894 snd_ac97_write_cache(ac97
, AC97_EXTENDED_MSTATUS
, 0x3810);
895 snd_ac97_write_cache(ac97
, AC97_POWERDOWN
, 0x0);
903 static int patch_tritech_tr28028(struct snd_ac97
* ac97
)
905 snd_ac97_write_cache(ac97
, 0x26, 0x0300);
906 snd_ac97_write_cache(ac97
, 0x26, 0x0000);
907 snd_ac97_write_cache(ac97
, AC97_SURROUND_MASTER
, 0x0000);
908 snd_ac97_write_cache(ac97
, AC97_SPDIF
, 0x0000);
913 * Sigmatel STAC97xx codecs
915 static int patch_sigmatel_stac9700_3d(struct snd_ac97
* ac97
)
917 struct snd_kcontrol
*kctl
;
920 if ((err
= snd_ctl_add(ac97
->bus
->card
, kctl
= snd_ac97_cnew(&snd_ac97_controls_3d
[0], ac97
))) < 0)
922 strcpy(kctl
->id
.name
, "3D Control Sigmatel - Depth");
923 kctl
->private_value
= AC97_SINGLE_VALUE(AC97_3D_CONTROL
, 2, 3, 0);
924 snd_ac97_write_cache(ac97
, AC97_3D_CONTROL
, 0x0000);
928 static int patch_sigmatel_stac9708_3d(struct snd_ac97
* ac97
)
930 struct snd_kcontrol
*kctl
;
933 if ((err
= snd_ctl_add(ac97
->bus
->card
, kctl
= snd_ac97_cnew(&snd_ac97_controls_3d
[0], ac97
))) < 0)
935 strcpy(kctl
->id
.name
, "3D Control Sigmatel - Depth");
936 kctl
->private_value
= AC97_SINGLE_VALUE(AC97_3D_CONTROL
, 0, 3, 0);
937 if ((err
= snd_ctl_add(ac97
->bus
->card
, kctl
= snd_ac97_cnew(&snd_ac97_controls_3d
[0], ac97
))) < 0)
939 strcpy(kctl
->id
.name
, "3D Control Sigmatel - Rear Depth");
940 kctl
->private_value
= AC97_SINGLE_VALUE(AC97_3D_CONTROL
, 2, 3, 0);
941 snd_ac97_write_cache(ac97
, AC97_3D_CONTROL
, 0x0000);
945 static const struct snd_kcontrol_new snd_ac97_sigmatel_4speaker
=
946 AC97_SINGLE("Sigmatel 4-Speaker Stereo Playback Switch",
947 AC97_SIGMATEL_DAC2INVERT
, 2, 1, 0);
949 /* "Sigmatel " removed due to excessive name length: */
950 static const struct snd_kcontrol_new snd_ac97_sigmatel_phaseinvert
=
951 AC97_SINGLE("Surround Phase Inversion Playback Switch",
952 AC97_SIGMATEL_DAC2INVERT
, 3, 1, 0);
954 static const struct snd_kcontrol_new snd_ac97_sigmatel_controls
[] = {
955 AC97_SINGLE("Sigmatel DAC 6dB Attenuate", AC97_SIGMATEL_ANALOG
, 1, 1, 0),
956 AC97_SINGLE("Sigmatel ADC 6dB Attenuate", AC97_SIGMATEL_ANALOG
, 0, 1, 0)
959 static int patch_sigmatel_stac97xx_specific(struct snd_ac97
* ac97
)
963 snd_ac97_write_cache(ac97
, AC97_SIGMATEL_ANALOG
, snd_ac97_read(ac97
, AC97_SIGMATEL_ANALOG
) & ~0x0003);
964 if (snd_ac97_try_bit(ac97
, AC97_SIGMATEL_ANALOG
, 1))
965 if ((err
= patch_build_controls(ac97
, &snd_ac97_sigmatel_controls
[0], 1)) < 0)
967 if (snd_ac97_try_bit(ac97
, AC97_SIGMATEL_ANALOG
, 0))
968 if ((err
= patch_build_controls(ac97
, &snd_ac97_sigmatel_controls
[1], 1)) < 0)
970 if (snd_ac97_try_bit(ac97
, AC97_SIGMATEL_DAC2INVERT
, 2))
971 if ((err
= patch_build_controls(ac97
, &snd_ac97_sigmatel_4speaker
, 1)) < 0)
973 if (snd_ac97_try_bit(ac97
, AC97_SIGMATEL_DAC2INVERT
, 3))
974 if ((err
= patch_build_controls(ac97
, &snd_ac97_sigmatel_phaseinvert
, 1)) < 0)
979 static struct snd_ac97_build_ops patch_sigmatel_stac9700_ops
= {
980 .build_3d
= patch_sigmatel_stac9700_3d
,
981 .build_specific
= patch_sigmatel_stac97xx_specific
984 static int patch_sigmatel_stac9700(struct snd_ac97
* ac97
)
986 ac97
->build_ops
= &patch_sigmatel_stac9700_ops
;
990 static int snd_ac97_stac9708_put_bias(struct snd_kcontrol
*kcontrol
, struct snd_ctl_elem_value
*ucontrol
)
992 struct snd_ac97
*ac97
= snd_kcontrol_chip(kcontrol
);
995 mutex_lock(&ac97
->page_mutex
);
996 snd_ac97_write(ac97
, AC97_SIGMATEL_BIAS1
, 0xabba);
997 err
= snd_ac97_update_bits(ac97
, AC97_SIGMATEL_BIAS2
, 0x0010,
998 (ucontrol
->value
.integer
.value
[0] & 1) << 4);
999 snd_ac97_write(ac97
, AC97_SIGMATEL_BIAS1
, 0);
1000 mutex_unlock(&ac97
->page_mutex
);
1004 static const struct snd_kcontrol_new snd_ac97_stac9708_bias_control
= {
1005 .iface
= SNDRV_CTL_ELEM_IFACE_MIXER
,
1006 .name
= "Sigmatel Output Bias Switch",
1007 .info
= snd_ac97_info_volsw
,
1008 .get
= snd_ac97_get_volsw
,
1009 .put
= snd_ac97_stac9708_put_bias
,
1010 .private_value
= AC97_SINGLE_VALUE(AC97_SIGMATEL_BIAS2
, 4, 1, 0),
1013 static int patch_sigmatel_stac9708_specific(struct snd_ac97
*ac97
)
1017 /* the register bit is writable, but the function is not implemented: */
1018 snd_ac97_remove_ctl(ac97
, "PCM Out Path & Mute", NULL
);
1020 snd_ac97_rename_vol_ctl(ac97
, "Headphone Playback", "Sigmatel Surround Playback");
1021 if ((err
= patch_build_controls(ac97
, &snd_ac97_stac9708_bias_control
, 1)) < 0)
1023 return patch_sigmatel_stac97xx_specific(ac97
);
1026 static struct snd_ac97_build_ops patch_sigmatel_stac9708_ops
= {
1027 .build_3d
= patch_sigmatel_stac9708_3d
,
1028 .build_specific
= patch_sigmatel_stac9708_specific
1031 static int patch_sigmatel_stac9708(struct snd_ac97
* ac97
)
1033 unsigned int codec72
, codec6c
;
1035 ac97
->build_ops
= &patch_sigmatel_stac9708_ops
;
1036 ac97
->caps
|= 0x10; /* HP (sigmatel surround) support */
1038 codec72
= snd_ac97_read(ac97
, AC97_SIGMATEL_BIAS2
) & 0x8000;
1039 codec6c
= snd_ac97_read(ac97
, AC97_SIGMATEL_ANALOG
);
1041 if ((codec72
==0) && (codec6c
==0)) {
1042 snd_ac97_write_cache(ac97
, AC97_SIGMATEL_CIC1
, 0xabba);
1043 snd_ac97_write_cache(ac97
, AC97_SIGMATEL_CIC2
, 0x1000);
1044 snd_ac97_write_cache(ac97
, AC97_SIGMATEL_BIAS1
, 0xabba);
1045 snd_ac97_write_cache(ac97
, AC97_SIGMATEL_BIAS2
, 0x0007);
1046 } else if ((codec72
==0x8000) && (codec6c
==0)) {
1047 snd_ac97_write_cache(ac97
, AC97_SIGMATEL_CIC1
, 0xabba);
1048 snd_ac97_write_cache(ac97
, AC97_SIGMATEL_CIC2
, 0x1001);
1049 snd_ac97_write_cache(ac97
, AC97_SIGMATEL_DAC2INVERT
, 0x0008);
1050 } else if ((codec72
==0x8000) && (codec6c
==0x0080)) {
1053 snd_ac97_write_cache(ac97
, AC97_SIGMATEL_MULTICHN
, 0x0000);
1057 static int patch_sigmatel_stac9721(struct snd_ac97
* ac97
)
1059 ac97
->build_ops
= &patch_sigmatel_stac9700_ops
;
1060 if (snd_ac97_read(ac97
, AC97_SIGMATEL_ANALOG
) == 0) {
1061 // patch for SigmaTel
1062 snd_ac97_write_cache(ac97
, AC97_SIGMATEL_CIC1
, 0xabba);
1063 snd_ac97_write_cache(ac97
, AC97_SIGMATEL_CIC2
, 0x4000);
1064 snd_ac97_write_cache(ac97
, AC97_SIGMATEL_BIAS1
, 0xabba);
1065 snd_ac97_write_cache(ac97
, AC97_SIGMATEL_BIAS2
, 0x0002);
1067 snd_ac97_write_cache(ac97
, AC97_SIGMATEL_MULTICHN
, 0x0000);
1071 static int patch_sigmatel_stac9744(struct snd_ac97
* ac97
)
1073 // patch for SigmaTel
1074 ac97
->build_ops
= &patch_sigmatel_stac9700_ops
;
1075 snd_ac97_write_cache(ac97
, AC97_SIGMATEL_CIC1
, 0xabba);
1076 snd_ac97_write_cache(ac97
, AC97_SIGMATEL_CIC2
, 0x0000); /* is this correct? --jk */
1077 snd_ac97_write_cache(ac97
, AC97_SIGMATEL_BIAS1
, 0xabba);
1078 snd_ac97_write_cache(ac97
, AC97_SIGMATEL_BIAS2
, 0x0002);
1079 snd_ac97_write_cache(ac97
, AC97_SIGMATEL_MULTICHN
, 0x0000);
1083 static int patch_sigmatel_stac9756(struct snd_ac97
* ac97
)
1085 // patch for SigmaTel
1086 ac97
->build_ops
= &patch_sigmatel_stac9700_ops
;
1087 snd_ac97_write_cache(ac97
, AC97_SIGMATEL_CIC1
, 0xabba);
1088 snd_ac97_write_cache(ac97
, AC97_SIGMATEL_CIC2
, 0x0000); /* is this correct? --jk */
1089 snd_ac97_write_cache(ac97
, AC97_SIGMATEL_BIAS1
, 0xabba);
1090 snd_ac97_write_cache(ac97
, AC97_SIGMATEL_BIAS2
, 0x0002);
1091 snd_ac97_write_cache(ac97
, AC97_SIGMATEL_MULTICHN
, 0x0000);
1095 static int snd_ac97_stac9758_output_jack_info(struct snd_kcontrol
*kcontrol
, struct snd_ctl_elem_info
*uinfo
)
1097 static char *texts
[5] = { "Input/Disabled", "Front Output",
1098 "Rear Output", "Center/LFE Output", "Mixer Output" };
1100 uinfo
->type
= SNDRV_CTL_ELEM_TYPE_ENUMERATED
;
1102 uinfo
->value
.enumerated
.items
= 5;
1103 if (uinfo
->value
.enumerated
.item
> 4)
1104 uinfo
->value
.enumerated
.item
= 4;
1105 strcpy(uinfo
->value
.enumerated
.name
, texts
[uinfo
->value
.enumerated
.item
]);
1109 static int snd_ac97_stac9758_output_jack_get(struct snd_kcontrol
*kcontrol
, struct snd_ctl_elem_value
*ucontrol
)
1111 struct snd_ac97
*ac97
= snd_kcontrol_chip(kcontrol
);
1112 int shift
= kcontrol
->private_value
;
1115 val
= ac97
->regs
[AC97_SIGMATEL_OUTSEL
] >> shift
;
1117 ucontrol
->value
.enumerated
.item
[0] = 0;
1119 ucontrol
->value
.enumerated
.item
[0] = 1 + (val
& 3);
1123 static int snd_ac97_stac9758_output_jack_put(struct snd_kcontrol
*kcontrol
, struct snd_ctl_elem_value
*ucontrol
)
1125 struct snd_ac97
*ac97
= snd_kcontrol_chip(kcontrol
);
1126 int shift
= kcontrol
->private_value
;
1129 if (ucontrol
->value
.enumerated
.item
[0] > 4)
1131 if (ucontrol
->value
.enumerated
.item
[0] == 0)
1134 val
= 4 | (ucontrol
->value
.enumerated
.item
[0] - 1);
1135 return ac97_update_bits_page(ac97
, AC97_SIGMATEL_OUTSEL
,
1136 7 << shift
, val
<< shift
, 0);
1139 static int snd_ac97_stac9758_input_jack_info(struct snd_kcontrol
*kcontrol
, struct snd_ctl_elem_info
*uinfo
)
1141 static char *texts
[7] = { "Mic2 Jack", "Mic1 Jack", "Line In Jack",
1142 "Front Jack", "Rear Jack", "Center/LFE Jack", "Mute" };
1144 uinfo
->type
= SNDRV_CTL_ELEM_TYPE_ENUMERATED
;
1146 uinfo
->value
.enumerated
.items
= 7;
1147 if (uinfo
->value
.enumerated
.item
> 6)
1148 uinfo
->value
.enumerated
.item
= 6;
1149 strcpy(uinfo
->value
.enumerated
.name
, texts
[uinfo
->value
.enumerated
.item
]);
1153 static int snd_ac97_stac9758_input_jack_get(struct snd_kcontrol
*kcontrol
, struct snd_ctl_elem_value
*ucontrol
)
1155 struct snd_ac97
*ac97
= snd_kcontrol_chip(kcontrol
);
1156 int shift
= kcontrol
->private_value
;
1159 val
= ac97
->regs
[AC97_SIGMATEL_INSEL
];
1160 ucontrol
->value
.enumerated
.item
[0] = (val
>> shift
) & 7;
1164 static int snd_ac97_stac9758_input_jack_put(struct snd_kcontrol
*kcontrol
, struct snd_ctl_elem_value
*ucontrol
)
1166 struct snd_ac97
*ac97
= snd_kcontrol_chip(kcontrol
);
1167 int shift
= kcontrol
->private_value
;
1169 return ac97_update_bits_page(ac97
, AC97_SIGMATEL_INSEL
, 7 << shift
,
1170 ucontrol
->value
.enumerated
.item
[0] << shift
, 0);
1173 static int snd_ac97_stac9758_phonesel_info(struct snd_kcontrol
*kcontrol
, struct snd_ctl_elem_info
*uinfo
)
1175 static char *texts
[3] = { "None", "Front Jack", "Rear Jack" };
1177 uinfo
->type
= SNDRV_CTL_ELEM_TYPE_ENUMERATED
;
1179 uinfo
->value
.enumerated
.items
= 3;
1180 if (uinfo
->value
.enumerated
.item
> 2)
1181 uinfo
->value
.enumerated
.item
= 2;
1182 strcpy(uinfo
->value
.enumerated
.name
, texts
[uinfo
->value
.enumerated
.item
]);
1186 static int snd_ac97_stac9758_phonesel_get(struct snd_kcontrol
*kcontrol
, struct snd_ctl_elem_value
*ucontrol
)
1188 struct snd_ac97
*ac97
= snd_kcontrol_chip(kcontrol
);
1190 ucontrol
->value
.enumerated
.item
[0] = ac97
->regs
[AC97_SIGMATEL_IOMISC
] & 3;
1194 static int snd_ac97_stac9758_phonesel_put(struct snd_kcontrol
*kcontrol
, struct snd_ctl_elem_value
*ucontrol
)
1196 struct snd_ac97
*ac97
= snd_kcontrol_chip(kcontrol
);
1198 return ac97_update_bits_page(ac97
, AC97_SIGMATEL_IOMISC
, 3,
1199 ucontrol
->value
.enumerated
.item
[0], 0);
1202 #define STAC9758_OUTPUT_JACK(xname, shift) \
1203 { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, \
1204 .info = snd_ac97_stac9758_output_jack_info, \
1205 .get = snd_ac97_stac9758_output_jack_get, \
1206 .put = snd_ac97_stac9758_output_jack_put, \
1207 .private_value = shift }
1208 #define STAC9758_INPUT_JACK(xname, shift) \
1209 { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, \
1210 .info = snd_ac97_stac9758_input_jack_info, \
1211 .get = snd_ac97_stac9758_input_jack_get, \
1212 .put = snd_ac97_stac9758_input_jack_put, \
1213 .private_value = shift }
1214 static const struct snd_kcontrol_new snd_ac97_sigmatel_stac9758_controls
[] = {
1215 STAC9758_OUTPUT_JACK("Mic1 Jack", 1),
1216 STAC9758_OUTPUT_JACK("LineIn Jack", 4),
1217 STAC9758_OUTPUT_JACK("Front Jack", 7),
1218 STAC9758_OUTPUT_JACK("Rear Jack", 10),
1219 STAC9758_OUTPUT_JACK("Center/LFE Jack", 13),
1220 STAC9758_INPUT_JACK("Mic Input Source", 0),
1221 STAC9758_INPUT_JACK("Line Input Source", 8),
1223 .iface
= SNDRV_CTL_ELEM_IFACE_MIXER
,
1224 .name
= "Headphone Amp",
1225 .info
= snd_ac97_stac9758_phonesel_info
,
1226 .get
= snd_ac97_stac9758_phonesel_get
,
1227 .put
= snd_ac97_stac9758_phonesel_put
1229 AC97_SINGLE("Exchange Center/LFE", AC97_SIGMATEL_IOMISC
, 4, 1, 0),
1230 AC97_SINGLE("Headphone +3dB Boost", AC97_SIGMATEL_IOMISC
, 8, 1, 0)
1233 static int patch_sigmatel_stac9758_specific(struct snd_ac97
*ac97
)
1237 err
= patch_sigmatel_stac97xx_specific(ac97
);
1240 err
= patch_build_controls(ac97
, snd_ac97_sigmatel_stac9758_controls
,
1241 ARRAY_SIZE(snd_ac97_sigmatel_stac9758_controls
));
1245 snd_ac97_rename_vol_ctl(ac97
, "Headphone Playback", "Front Playback");
1246 /* DAC-A to Mix = PCM */
1247 /* DAC-B direct = Surround */
1249 snd_ac97_rename_vol_ctl(ac97
, "Video Playback", "Surround Mix Playback");
1250 /* DAC-C direct = Center/LFE */
1255 static struct snd_ac97_build_ops patch_sigmatel_stac9758_ops
= {
1256 .build_3d
= patch_sigmatel_stac9700_3d
,
1257 .build_specific
= patch_sigmatel_stac9758_specific
1260 static int patch_sigmatel_stac9758(struct snd_ac97
* ac97
)
1262 static unsigned short regs
[4] = {
1263 AC97_SIGMATEL_OUTSEL
,
1264 AC97_SIGMATEL_IOMISC
,
1265 AC97_SIGMATEL_INSEL
,
1266 AC97_SIGMATEL_VARIOUS
1268 static unsigned short def_regs
[4] = {
1269 /* OUTSEL */ 0xd794, /* CL:CL, SR:SR, LO:MX, LI:DS, MI:DS */
1270 /* IOMISC */ 0x2001,
1271 /* INSEL */ 0x0201, /* LI:LI, MI:M1 */
1272 /* VARIOUS */ 0x0040
1274 static unsigned short m675_regs
[4] = {
1275 /* OUTSEL */ 0xfc70, /* CL:MX, SR:MX, LO:DS, LI:MX, MI:DS */
1276 /* IOMISC */ 0x2102, /* HP amp on */
1277 /* INSEL */ 0x0203, /* LI:LI, MI:FR */
1278 /* VARIOUS */ 0x0041 /* stereo mic */
1280 unsigned short *pregs
= def_regs
;
1283 /* Gateway M675 notebook */
1285 ac97
->subsystem_vendor
== 0x107b &&
1286 ac97
->subsystem_device
== 0x0601)
1289 // patch for SigmaTel
1290 ac97
->build_ops
= &patch_sigmatel_stac9758_ops
;
1291 /* FIXME: assume only page 0 for writing cache */
1292 snd_ac97_update_bits(ac97
, AC97_INT_PAGING
, AC97_PAGE_MASK
, AC97_PAGE_VENDOR
);
1293 for (i
= 0; i
< 4; i
++)
1294 snd_ac97_write_cache(ac97
, regs
[i
], pregs
[i
]);
1296 ac97
->flags
|= AC97_STEREO_MUTES
;
1301 * Cirrus Logic CS42xx codecs
1303 static const struct snd_kcontrol_new snd_ac97_cirrus_controls_spdif
[2] = {
1304 AC97_SINGLE(SNDRV_CTL_NAME_IEC958("",PLAYBACK
,SWITCH
), AC97_CSR_SPDIF
, 15, 1, 0),
1305 AC97_SINGLE(SNDRV_CTL_NAME_IEC958("",PLAYBACK
,NONE
) "AC97-SPSA", AC97_CSR_ACMODE
, 0, 3, 0)
1308 static int patch_cirrus_build_spdif(struct snd_ac97
* ac97
)
1312 /* con mask, pro mask, default */
1313 if ((err
= patch_build_controls(ac97
, &snd_ac97_controls_spdif
[0], 3)) < 0)
1316 if ((err
= patch_build_controls(ac97
, &snd_ac97_cirrus_controls_spdif
[0], 1)) < 0)
1318 switch (ac97
->id
& AC97_ID_CS_MASK
) {
1319 case AC97_ID_CS4205
:
1320 if ((err
= patch_build_controls(ac97
, &snd_ac97_cirrus_controls_spdif
[1], 1)) < 0)
1324 /* set default PCM S/PDIF params */
1325 /* consumer,PCM audio,no copyright,no preemphasis,PCM coder,original,48000Hz */
1326 snd_ac97_write_cache(ac97
, AC97_CSR_SPDIF
, 0x0a20);
1330 static struct snd_ac97_build_ops patch_cirrus_ops
= {
1331 .build_spdif
= patch_cirrus_build_spdif
1334 static int patch_cirrus_spdif(struct snd_ac97
* ac97
)
1336 /* Basically, the cs4201/cs4205/cs4297a has non-standard sp/dif registers.
1337 WHY CAN'T ANYONE FOLLOW THE BLOODY SPEC? *sigh*
1338 - sp/dif EA ID is not set, but sp/dif is always present.
1339 - enable/disable is spdif register bit 15.
1340 - sp/dif control register is 0x68. differs from AC97:
1341 - valid is bit 14 (vs 15)
1343 - only 44.1/48k [00 = 48, 01=44,1] (AC97 is 00=44.1, 10=48)
1344 - sp/dif ssource select is in 0x5e bits 0,1.
1347 ac97
->build_ops
= &patch_cirrus_ops
;
1348 ac97
->flags
|= AC97_CS_SPDIF
;
1349 ac97
->rates
[AC97_RATES_SPDIF
] &= ~SNDRV_PCM_RATE_32000
;
1350 ac97
->ext_id
|= AC97_EI_SPDIF
; /* force the detection of spdif */
1351 snd_ac97_write_cache(ac97
, AC97_CSR_ACMODE
, 0x0080);
1355 static int patch_cirrus_cs4299(struct snd_ac97
* ac97
)
1357 /* force the detection of PC Beep */
1358 ac97
->flags
|= AC97_HAS_PC_BEEP
;
1360 return patch_cirrus_spdif(ac97
);
1366 static const struct snd_kcontrol_new snd_ac97_conexant_controls_spdif
[1] = {
1367 AC97_SINGLE(SNDRV_CTL_NAME_IEC958("",PLAYBACK
,SWITCH
), AC97_CXR_AUDIO_MISC
, 3, 1, 0),
1370 static int patch_conexant_build_spdif(struct snd_ac97
* ac97
)
1374 /* con mask, pro mask, default */
1375 if ((err
= patch_build_controls(ac97
, &snd_ac97_controls_spdif
[0], 3)) < 0)
1378 if ((err
= patch_build_controls(ac97
, &snd_ac97_conexant_controls_spdif
[0], 1)) < 0)
1380 /* set default PCM S/PDIF params */
1381 /* consumer,PCM audio,no copyright,no preemphasis,PCM coder,original,48000Hz */
1382 snd_ac97_write_cache(ac97
, AC97_CXR_AUDIO_MISC
,
1383 snd_ac97_read(ac97
, AC97_CXR_AUDIO_MISC
) & ~(AC97_CXR_SPDIFEN
|AC97_CXR_COPYRGT
|AC97_CXR_SPDIF_MASK
));
1387 static struct snd_ac97_build_ops patch_conexant_ops
= {
1388 .build_spdif
= patch_conexant_build_spdif
1391 static int patch_conexant(struct snd_ac97
* ac97
)
1393 ac97
->build_ops
= &patch_conexant_ops
;
1394 ac97
->flags
|= AC97_CX_SPDIF
;
1395 ac97
->ext_id
|= AC97_EI_SPDIF
; /* force the detection of spdif */
1396 ac97
->rates
[AC97_RATES_SPDIF
] = SNDRV_PCM_RATE_48000
; /* 48k only */
1400 static int patch_cx20551(struct snd_ac97
*ac97
)
1402 snd_ac97_update_bits(ac97
, 0x5c, 0x01, 0x01);
1407 * Analog Device AD18xx, AD19xx codecs
1410 static void ad18xx_resume(struct snd_ac97
*ac97
)
1412 static unsigned short setup_regs
[] = {
1413 AC97_AD_MISC
, AC97_AD_SERIAL_CFG
, AC97_AD_JACK_SPDIF
,
1417 for (i
= 0; i
< (int)ARRAY_SIZE(setup_regs
); i
++) {
1418 unsigned short reg
= setup_regs
[i
];
1419 if (test_bit(reg
, ac97
->reg_accessed
)) {
1420 snd_ac97_write(ac97
, reg
, ac97
->regs
[reg
]);
1421 snd_ac97_read(ac97
, reg
);
1425 if (! (ac97
->flags
& AC97_AD_MULTI
))
1426 /* normal restore */
1427 snd_ac97_restore_status(ac97
);
1429 /* restore the AD18xx codec configurations */
1430 for (codec
= 0; codec
< 3; codec
++) {
1431 if (! ac97
->spec
.ad18xx
.id
[codec
])
1433 /* select single codec */
1434 snd_ac97_update_bits(ac97
, AC97_AD_SERIAL_CFG
, 0x7000,
1435 ac97
->spec
.ad18xx
.unchained
[codec
] | ac97
->spec
.ad18xx
.chained
[codec
]);
1436 ac97
->bus
->ops
->write(ac97
, AC97_AD_CODEC_CFG
, ac97
->spec
.ad18xx
.codec_cfg
[codec
]);
1438 /* select all codecs */
1439 snd_ac97_update_bits(ac97
, AC97_AD_SERIAL_CFG
, 0x7000, 0x7000);
1441 /* restore status */
1442 for (i
= 2; i
< 0x7c ; i
+= 2) {
1443 if (i
== AC97_POWERDOWN
|| i
== AC97_EXTENDED_ID
)
1445 if (test_bit(i
, ac97
->reg_accessed
)) {
1446 /* handle multi codecs for AD18xx */
1447 if (i
== AC97_PCM
) {
1448 for (codec
= 0; codec
< 3; codec
++) {
1449 if (! ac97
->spec
.ad18xx
.id
[codec
])
1451 /* select single codec */
1452 snd_ac97_update_bits(ac97
, AC97_AD_SERIAL_CFG
, 0x7000,
1453 ac97
->spec
.ad18xx
.unchained
[codec
] | ac97
->spec
.ad18xx
.chained
[codec
]);
1454 /* update PCM bits */
1455 ac97
->bus
->ops
->write(ac97
, AC97_PCM
, ac97
->spec
.ad18xx
.pcmreg
[codec
]);
1457 /* select all codecs */
1458 snd_ac97_update_bits(ac97
, AC97_AD_SERIAL_CFG
, 0x7000, 0x7000);
1460 } else if (i
== AC97_AD_TEST
||
1461 i
== AC97_AD_CODEC_CFG
||
1462 i
== AC97_AD_SERIAL_CFG
)
1463 continue; /* ignore */
1465 snd_ac97_write(ac97
, i
, ac97
->regs
[i
]);
1466 snd_ac97_read(ac97
, i
);
1470 snd_ac97_restore_iec958(ac97
);
1473 static void ad1888_resume(struct snd_ac97
*ac97
)
1475 ad18xx_resume(ac97
);
1476 snd_ac97_write_cache(ac97
, AC97_CODEC_CLASS_REV
, 0x8080);
1481 static const struct snd_ac97_res_table ad1819_restbl
[] = {
1482 { AC97_PHONE
, 0x9f1f },
1483 { AC97_MIC
, 0x9f1f },
1484 { AC97_LINE
, 0x9f1f },
1485 { AC97_CD
, 0x9f1f },
1486 { AC97_VIDEO
, 0x9f1f },
1487 { AC97_AUX
, 0x9f1f },
1488 { AC97_PCM
, 0x9f1f },
1489 { } /* terminator */
1492 static int patch_ad1819(struct snd_ac97
* ac97
)
1494 unsigned short scfg
;
1496 // patch for Analog Devices
1497 scfg
= snd_ac97_read(ac97
, AC97_AD_SERIAL_CFG
);
1498 snd_ac97_write_cache(ac97
, AC97_AD_SERIAL_CFG
, scfg
| 0x7000); /* select all codecs */
1499 ac97
->res_table
= ad1819_restbl
;
1503 static unsigned short patch_ad1881_unchained(struct snd_ac97
* ac97
, int idx
, unsigned short mask
)
1507 // test for unchained codec
1508 snd_ac97_update_bits(ac97
, AC97_AD_SERIAL_CFG
, 0x7000, mask
);
1509 snd_ac97_write_cache(ac97
, AC97_AD_CODEC_CFG
, 0x0000); /* ID0C, ID1C, SDIE = off */
1510 val
= snd_ac97_read(ac97
, AC97_VENDOR_ID2
);
1511 if ((val
& 0xff40) != 0x5340)
1513 ac97
->spec
.ad18xx
.unchained
[idx
] = mask
;
1514 ac97
->spec
.ad18xx
.id
[idx
] = val
;
1515 ac97
->spec
.ad18xx
.codec_cfg
[idx
] = 0x0000;
1519 static int patch_ad1881_chained1(struct snd_ac97
* ac97
, int idx
, unsigned short codec_bits
)
1521 static int cfg_bits
[3] = { 1<<12, 1<<14, 1<<13 };
1524 snd_ac97_update_bits(ac97
, AC97_AD_SERIAL_CFG
, 0x7000, cfg_bits
[idx
]);
1525 snd_ac97_write_cache(ac97
, AC97_AD_CODEC_CFG
, 0x0004); // SDIE
1526 val
= snd_ac97_read(ac97
, AC97_VENDOR_ID2
);
1527 if ((val
& 0xff40) != 0x5340)
1530 snd_ac97_write_cache(ac97
, AC97_AD_CODEC_CFG
, codec_bits
);
1531 ac97
->spec
.ad18xx
.chained
[idx
] = cfg_bits
[idx
];
1532 ac97
->spec
.ad18xx
.id
[idx
] = val
;
1533 ac97
->spec
.ad18xx
.codec_cfg
[idx
] = codec_bits
? codec_bits
: 0x0004;
1537 static void patch_ad1881_chained(struct snd_ac97
* ac97
, int unchained_idx
, int cidx1
, int cidx2
)
1539 // already detected?
1540 if (ac97
->spec
.ad18xx
.unchained
[cidx1
] || ac97
->spec
.ad18xx
.chained
[cidx1
])
1542 if (ac97
->spec
.ad18xx
.unchained
[cidx2
] || ac97
->spec
.ad18xx
.chained
[cidx2
])
1544 if (cidx1
< 0 && cidx2
< 0)
1546 // test for chained codecs
1547 snd_ac97_update_bits(ac97
, AC97_AD_SERIAL_CFG
, 0x7000,
1548 ac97
->spec
.ad18xx
.unchained
[unchained_idx
]);
1549 snd_ac97_write_cache(ac97
, AC97_AD_CODEC_CFG
, 0x0002); // ID1C
1550 ac97
->spec
.ad18xx
.codec_cfg
[unchained_idx
] = 0x0002;
1553 patch_ad1881_chained1(ac97
, cidx1
, 0);
1554 else if (patch_ad1881_chained1(ac97
, cidx1
, 0x0006)) // SDIE | ID1C
1555 patch_ad1881_chained1(ac97
, cidx2
, 0);
1556 else if (patch_ad1881_chained1(ac97
, cidx2
, 0x0006)) // SDIE | ID1C
1557 patch_ad1881_chained1(ac97
, cidx1
, 0);
1558 } else if (cidx2
>= 0) {
1559 patch_ad1881_chained1(ac97
, cidx2
, 0);
1563 static struct snd_ac97_build_ops patch_ad1881_build_ops
= {
1565 .resume
= ad18xx_resume
1569 static int patch_ad1881(struct snd_ac97
* ac97
)
1571 static const char cfg_idxs
[3][2] = {
1577 // patch for Analog Devices
1578 unsigned short codecs
[3];
1582 val
= snd_ac97_read(ac97
, AC97_AD_SERIAL_CFG
);
1583 snd_ac97_write_cache(ac97
, AC97_AD_SERIAL_CFG
, val
);
1584 codecs
[0] = patch_ad1881_unchained(ac97
, 0, (1<<12));
1585 codecs
[1] = patch_ad1881_unchained(ac97
, 1, (1<<14));
1586 codecs
[2] = patch_ad1881_unchained(ac97
, 2, (1<<13));
1588 if (! (codecs
[0] || codecs
[1] || codecs
[2]))
1591 for (idx
= 0; idx
< 3; idx
++)
1592 if (ac97
->spec
.ad18xx
.unchained
[idx
])
1593 patch_ad1881_chained(ac97
, idx
, cfg_idxs
[idx
][0], cfg_idxs
[idx
][1]);
1595 if (ac97
->spec
.ad18xx
.id
[1]) {
1596 ac97
->flags
|= AC97_AD_MULTI
;
1597 ac97
->scaps
|= AC97_SCAP_SURROUND_DAC
;
1599 if (ac97
->spec
.ad18xx
.id
[2]) {
1600 ac97
->flags
|= AC97_AD_MULTI
;
1601 ac97
->scaps
|= AC97_SCAP_CENTER_LFE_DAC
;
1605 /* select all codecs */
1606 snd_ac97_update_bits(ac97
, AC97_AD_SERIAL_CFG
, 0x7000, 0x7000);
1607 /* check if only one codec is present */
1608 for (idx
= num
= 0; idx
< 3; idx
++)
1609 if (ac97
->spec
.ad18xx
.id
[idx
])
1612 /* ok, deselect all ID bits */
1613 snd_ac97_write_cache(ac97
, AC97_AD_CODEC_CFG
, 0x0000);
1614 ac97
->spec
.ad18xx
.codec_cfg
[0] =
1615 ac97
->spec
.ad18xx
.codec_cfg
[1] =
1616 ac97
->spec
.ad18xx
.codec_cfg
[2] = 0x0000;
1618 /* required for AD1886/AD1885 combination */
1619 ac97
->ext_id
= snd_ac97_read(ac97
, AC97_EXTENDED_ID
);
1620 if (ac97
->spec
.ad18xx
.id
[0]) {
1621 ac97
->id
&= 0xffff0000;
1622 ac97
->id
|= ac97
->spec
.ad18xx
.id
[0];
1624 ac97
->build_ops
= &patch_ad1881_build_ops
;
1628 static const struct snd_kcontrol_new snd_ac97_controls_ad1885
[] = {
1629 AC97_SINGLE("Digital Mono Direct", AC97_AD_MISC
, 11, 1, 0),
1630 /* AC97_SINGLE("Digital Audio Mode", AC97_AD_MISC, 12, 1, 0), */ /* seems problematic */
1631 AC97_SINGLE("Low Power Mixer", AC97_AD_MISC
, 14, 1, 0),
1632 AC97_SINGLE("Zero Fill DAC", AC97_AD_MISC
, 15, 1, 0),
1633 AC97_SINGLE("Headphone Jack Sense", AC97_AD_JACK_SPDIF
, 9, 1, 1), /* inverted */
1634 AC97_SINGLE("Line Jack Sense", AC97_AD_JACK_SPDIF
, 8, 1, 1), /* inverted */
1637 static const DECLARE_TLV_DB_SCALE(db_scale_6bit_6db_max
, -8850, 150, 0);
1639 static int patch_ad1885_specific(struct snd_ac97
* ac97
)
1643 if ((err
= patch_build_controls(ac97
, snd_ac97_controls_ad1885
, ARRAY_SIZE(snd_ac97_controls_ad1885
))) < 0)
1645 reset_tlv(ac97
, "Headphone Playback Volume",
1646 db_scale_6bit_6db_max
);
1650 static struct snd_ac97_build_ops patch_ad1885_build_ops
= {
1651 .build_specific
= &patch_ad1885_specific
,
1653 .resume
= ad18xx_resume
1657 static int patch_ad1885(struct snd_ac97
* ac97
)
1660 /* This is required to deal with the Intel D815EEAL2 */
1661 /* i.e. Line out is actually headphone out from codec */
1664 snd_ac97_write_cache(ac97
, AC97_AD_MISC
, 0x0404);
1666 ac97
->build_ops
= &patch_ad1885_build_ops
;
1670 static int patch_ad1886_specific(struct snd_ac97
* ac97
)
1672 reset_tlv(ac97
, "Headphone Playback Volume",
1673 db_scale_6bit_6db_max
);
1677 static struct snd_ac97_build_ops patch_ad1886_build_ops
= {
1678 .build_specific
= &patch_ad1886_specific
,
1680 .resume
= ad18xx_resume
1684 static int patch_ad1886(struct snd_ac97
* ac97
)
1687 /* Presario700 workaround */
1688 /* for Jack Sense/SPDIF Register misetting causing */
1689 snd_ac97_write_cache(ac97
, AC97_AD_JACK_SPDIF
, 0x0010);
1690 ac97
->build_ops
= &patch_ad1886_build_ops
;
1694 /* MISC bits (AD1888/AD1980/AD1985 register 0x76) */
1695 #define AC97_AD198X_MBC 0x0003 /* mic boost */
1696 #define AC97_AD198X_MBC_20 0x0000 /* +20dB */
1697 #define AC97_AD198X_MBC_10 0x0001 /* +10dB */
1698 #define AC97_AD198X_MBC_30 0x0002 /* +30dB */
1699 #define AC97_AD198X_VREFD 0x0004 /* VREF high-Z */
1700 #define AC97_AD198X_VREFH 0x0008 /* 0=2.25V, 1=3.7V */
1701 #define AC97_AD198X_VREF_0 0x000c /* 0V (AD1985 only) */
1702 #define AC97_AD198X_VREF_MASK (AC97_AD198X_VREFH | AC97_AD198X_VREFD)
1703 #define AC97_AD198X_VREF_SHIFT 2
1704 #define AC97_AD198X_SRU 0x0010 /* sample rate unlock */
1705 #define AC97_AD198X_LOSEL 0x0020 /* LINE_OUT amplifiers input select */
1706 #define AC97_AD198X_2MIC 0x0040 /* 2-channel mic select */
1707 #define AC97_AD198X_SPRD 0x0080 /* SPREAD enable */
1708 #define AC97_AD198X_DMIX0 0x0100 /* downmix mode: */
1709 /* 0 = 6-to-4, 1 = 6-to-2 downmix */
1710 #define AC97_AD198X_DMIX1 0x0200 /* downmix mode: 1 = enabled */
1711 #define AC97_AD198X_HPSEL 0x0400 /* headphone amplifier input select */
1712 #define AC97_AD198X_CLDIS 0x0800 /* center/lfe disable */
1713 #define AC97_AD198X_LODIS 0x1000 /* LINE_OUT disable */
1714 #define AC97_AD198X_MSPLT 0x2000 /* mute split */
1715 #define AC97_AD198X_AC97NC 0x4000 /* AC97 no compatible mode */
1716 #define AC97_AD198X_DACZ 0x8000 /* DAC zero-fill mode */
1718 /* MISC 1 bits (AD1986 register 0x76) */
1719 #define AC97_AD1986_MBC 0x0003 /* mic boost */
1720 #define AC97_AD1986_MBC_20 0x0000 /* +20dB */
1721 #define AC97_AD1986_MBC_10 0x0001 /* +10dB */
1722 #define AC97_AD1986_MBC_30 0x0002 /* +30dB */
1723 #define AC97_AD1986_LISEL0 0x0004 /* LINE_IN select bit 0 */
1724 #define AC97_AD1986_LISEL1 0x0008 /* LINE_IN select bit 1 */
1725 #define AC97_AD1986_LISEL_MASK (AC97_AD1986_LISEL1 | AC97_AD1986_LISEL0)
1726 #define AC97_AD1986_LISEL_LI 0x0000 /* LINE_IN pins as LINE_IN source */
1727 #define AC97_AD1986_LISEL_SURR 0x0004 /* SURROUND pins as LINE_IN source */
1728 #define AC97_AD1986_LISEL_MIC 0x0008 /* MIC_1/2 pins as LINE_IN source */
1729 #define AC97_AD1986_SRU 0x0010 /* sample rate unlock */
1730 #define AC97_AD1986_SOSEL 0x0020 /* SURROUND_OUT amplifiers input sel */
1731 #define AC97_AD1986_2MIC 0x0040 /* 2-channel mic select */
1732 #define AC97_AD1986_SPRD 0x0080 /* SPREAD enable */
1733 #define AC97_AD1986_DMIX0 0x0100 /* downmix mode: */
1734 /* 0 = 6-to-4, 1 = 6-to-2 downmix */
1735 #define AC97_AD1986_DMIX1 0x0200 /* downmix mode: 1 = enabled */
1736 #define AC97_AD1986_CLDIS 0x0800 /* center/lfe disable */
1737 #define AC97_AD1986_SODIS 0x1000 /* SURROUND_OUT disable */
1738 #define AC97_AD1986_MSPLT 0x2000 /* mute split (read only 1) */
1739 #define AC97_AD1986_AC97NC 0x4000 /* AC97 no compatible mode (r/o 1) */
1740 #define AC97_AD1986_DACZ 0x8000 /* DAC zero-fill mode */
1742 /* MISC 2 bits (AD1986 register 0x70) */
1743 #define AC97_AD_MISC2 0x70 /* Misc Control Bits 2 (AD1986) */
1745 #define AC97_AD1986_CVREF0 0x0004 /* C/LFE VREF_OUT 2.25V */
1746 #define AC97_AD1986_CVREF1 0x0008 /* C/LFE VREF_OUT 0V */
1747 #define AC97_AD1986_CVREF2 0x0010 /* C/LFE VREF_OUT 3.7V */
1748 #define AC97_AD1986_CVREF_MASK \
1749 (AC97_AD1986_CVREF2 | AC97_AD1986_CVREF1 | AC97_AD1986_CVREF0)
1750 #define AC97_AD1986_JSMAP 0x0020 /* Jack Sense Mapping 1 = alternate */
1751 #define AC97_AD1986_MMDIS 0x0080 /* Mono Mute Disable */
1752 #define AC97_AD1986_MVREF0 0x0400 /* MIC VREF_OUT 2.25V */
1753 #define AC97_AD1986_MVREF1 0x0800 /* MIC VREF_OUT 0V */
1754 #define AC97_AD1986_MVREF2 0x1000 /* MIC VREF_OUT 3.7V */
1755 #define AC97_AD1986_MVREF_MASK \
1756 (AC97_AD1986_MVREF2 | AC97_AD1986_MVREF1 | AC97_AD1986_MVREF0)
1758 /* MISC 3 bits (AD1986 register 0x7a) */
1759 #define AC97_AD_MISC3 0x7a /* Misc Control Bits 3 (AD1986) */
1761 #define AC97_AD1986_MMIX 0x0004 /* Mic Mix, left/right */
1762 #define AC97_AD1986_GPO 0x0008 /* General Purpose Out */
1763 #define AC97_AD1986_LOHPEN 0x0010 /* LINE_OUT headphone drive */
1764 #define AC97_AD1986_LVREF0 0x0100 /* LINE_OUT VREF_OUT 2.25V */
1765 #define AC97_AD1986_LVREF1 0x0200 /* LINE_OUT VREF_OUT 0V */
1766 #define AC97_AD1986_LVREF2 0x0400 /* LINE_OUT VREF_OUT 3.7V */
1767 #define AC97_AD1986_LVREF_MASK \
1768 (AC97_AD1986_LVREF2 | AC97_AD1986_LVREF1 | AC97_AD1986_LVREF0)
1769 #define AC97_AD1986_JSINVA 0x0800 /* Jack Sense Invert SENSE_A */
1770 #define AC97_AD1986_LOSEL 0x1000 /* LINE_OUT amplifiers input select */
1771 #define AC97_AD1986_HPSEL0 0x2000 /* Headphone amplifiers */
1772 /* input select Surround DACs */
1773 #define AC97_AD1986_HPSEL1 0x4000 /* Headphone amplifiers input */
1774 /* select C/LFE DACs */
1775 #define AC97_AD1986_JSINVB 0x8000 /* Jack Sense Invert SENSE_B */
1777 /* Serial Config bits (AD1986 register 0x74) (incomplete) */
1778 #define AC97_AD1986_OMS0 0x0100 /* Optional Mic Selector bit 0 */
1779 #define AC97_AD1986_OMS1 0x0200 /* Optional Mic Selector bit 1 */
1780 #define AC97_AD1986_OMS2 0x0400 /* Optional Mic Selector bit 2 */
1781 #define AC97_AD1986_OMS_MASK \
1782 (AC97_AD1986_OMS2 | AC97_AD1986_OMS1 | AC97_AD1986_OMS0)
1783 #define AC97_AD1986_OMS_M 0x0000 /* MIC_1/2 pins are MIC sources */
1784 #define AC97_AD1986_OMS_L 0x0100 /* LINE_IN pins are MIC sources */
1785 #define AC97_AD1986_OMS_C 0x0200 /* Center/LFE pins are MCI sources */
1786 #define AC97_AD1986_OMS_MC 0x0400 /* Mix of MIC and C/LFE pins */
1787 /* are MIC sources */
1788 #define AC97_AD1986_OMS_ML 0x0500 /* MIX of MIC and LINE_IN pins */
1789 /* are MIC sources */
1790 #define AC97_AD1986_OMS_LC 0x0600 /* MIX of LINE_IN and C/LFE pins */
1791 /* are MIC sources */
1792 #define AC97_AD1986_OMS_MLC 0x0700 /* MIX of MIC, LINE_IN, C/LFE pins */
1793 /* are MIC sources */
1796 static int snd_ac97_ad198x_spdif_source_info(struct snd_kcontrol
*kcontrol
, struct snd_ctl_elem_info
*uinfo
)
1798 static char *texts
[2] = { "AC-Link", "A/D Converter" };
1800 uinfo
->type
= SNDRV_CTL_ELEM_TYPE_ENUMERATED
;
1802 uinfo
->value
.enumerated
.items
= 2;
1803 if (uinfo
->value
.enumerated
.item
> 1)
1804 uinfo
->value
.enumerated
.item
= 1;
1805 strcpy(uinfo
->value
.enumerated
.name
, texts
[uinfo
->value
.enumerated
.item
]);
1809 static int snd_ac97_ad198x_spdif_source_get(struct snd_kcontrol
*kcontrol
, struct snd_ctl_elem_value
*ucontrol
)
1811 struct snd_ac97
*ac97
= snd_kcontrol_chip(kcontrol
);
1814 val
= ac97
->regs
[AC97_AD_SERIAL_CFG
];
1815 ucontrol
->value
.enumerated
.item
[0] = (val
>> 2) & 1;
1819 static int snd_ac97_ad198x_spdif_source_put(struct snd_kcontrol
*kcontrol
, struct snd_ctl_elem_value
*ucontrol
)
1821 struct snd_ac97
*ac97
= snd_kcontrol_chip(kcontrol
);
1824 if (ucontrol
->value
.enumerated
.item
[0] > 1)
1826 val
= ucontrol
->value
.enumerated
.item
[0] << 2;
1827 return snd_ac97_update_bits(ac97
, AC97_AD_SERIAL_CFG
, 0x0004, val
);
1830 static const struct snd_kcontrol_new snd_ac97_ad198x_spdif_source
= {
1831 .iface
= SNDRV_CTL_ELEM_IFACE_MIXER
,
1832 .name
= SNDRV_CTL_NAME_IEC958("",PLAYBACK
,NONE
) "Source",
1833 .info
= snd_ac97_ad198x_spdif_source_info
,
1834 .get
= snd_ac97_ad198x_spdif_source_get
,
1835 .put
= snd_ac97_ad198x_spdif_source_put
,
1838 static int patch_ad198x_post_spdif(struct snd_ac97
* ac97
)
1840 return patch_build_controls(ac97
, &snd_ac97_ad198x_spdif_source
, 1);
1843 static const struct snd_kcontrol_new snd_ac97_ad1981x_jack_sense
[] = {
1844 AC97_SINGLE("Headphone Jack Sense", AC97_AD_JACK_SPDIF
, 11, 1, 0),
1845 AC97_SINGLE("Line Jack Sense", AC97_AD_JACK_SPDIF
, 12, 1, 0),
1848 /* black list to avoid HP/Line jack-sense controls
1849 * (SS vendor << 16 | device)
1851 static unsigned int ad1981_jacks_blacklist
[] = {
1852 0x10140523, /* Thinkpad R40 */
1853 0x10140534, /* Thinkpad X31 */
1854 0x10140537, /* Thinkpad T41p */
1855 0x1014053e, /* Thinkpad R40e */
1856 0x10140554, /* Thinkpad T42p/R50p */
1857 0x10140567, /* Thinkpad T43p 2668-G7U */
1858 0x10140581, /* Thinkpad X41-2527 */
1859 0x10280160, /* Dell Dimension 2400 */
1860 0x104380b0, /* Asus A7V8X-MX */
1861 0x11790241, /* Toshiba Satellite A-15 S127 */
1862 0x1179ff10, /* Toshiba P500 */
1863 0x144dc01a, /* Samsung NP-X20C004/SEG */
1867 static int check_list(struct snd_ac97
*ac97
, const unsigned int *list
)
1869 u32 subid
= ((u32
)ac97
->subsystem_vendor
<< 16) | ac97
->subsystem_device
;
1870 for (; *list
; list
++)
1876 static int patch_ad1981a_specific(struct snd_ac97
* ac97
)
1878 if (check_list(ac97
, ad1981_jacks_blacklist
))
1880 return patch_build_controls(ac97
, snd_ac97_ad1981x_jack_sense
,
1881 ARRAY_SIZE(snd_ac97_ad1981x_jack_sense
));
1884 static struct snd_ac97_build_ops patch_ad1981a_build_ops
= {
1885 .build_post_spdif
= patch_ad198x_post_spdif
,
1886 .build_specific
= patch_ad1981a_specific
,
1888 .resume
= ad18xx_resume
1892 /* white list to enable HP jack-sense bits
1893 * (SS vendor << 16 | device)
1895 static unsigned int ad1981_jacks_whitelist
[] = {
1896 0x0e11005a, /* HP nc4000/4010 */
1897 0x103c0890, /* HP nc6000 */
1898 0x103c0938, /* HP nc4220 */
1899 0x103c099c, /* HP nx6110 */
1900 0x103c0944, /* HP nc6220 */
1901 0x103c0934, /* HP nc8220 */
1902 0x103c006d, /* HP nx9105 */
1903 0x103c300d, /* HP Compaq dc5100 SFF(PT003AW) */
1904 0x17340088, /* FSC Scenic-W */
1908 static void check_ad1981_hp_jack_sense(struct snd_ac97
*ac97
)
1910 if (check_list(ac97
, ad1981_jacks_whitelist
))
1911 /* enable headphone jack sense */
1912 snd_ac97_update_bits(ac97
, AC97_AD_JACK_SPDIF
, 1<<11, 1<<11);
1915 static int patch_ad1981a(struct snd_ac97
*ac97
)
1918 ac97
->build_ops
= &patch_ad1981a_build_ops
;
1919 snd_ac97_update_bits(ac97
, AC97_AD_MISC
, AC97_AD198X_MSPLT
, AC97_AD198X_MSPLT
);
1920 ac97
->flags
|= AC97_STEREO_MUTES
;
1921 check_ad1981_hp_jack_sense(ac97
);
1925 static const struct snd_kcontrol_new snd_ac97_ad198x_2cmic
=
1926 AC97_SINGLE("Stereo Mic", AC97_AD_MISC
, 6, 1, 0);
1928 static int patch_ad1981b_specific(struct snd_ac97
*ac97
)
1932 if ((err
= patch_build_controls(ac97
, &snd_ac97_ad198x_2cmic
, 1)) < 0)
1934 if (check_list(ac97
, ad1981_jacks_blacklist
))
1936 return patch_build_controls(ac97
, snd_ac97_ad1981x_jack_sense
,
1937 ARRAY_SIZE(snd_ac97_ad1981x_jack_sense
));
1940 static struct snd_ac97_build_ops patch_ad1981b_build_ops
= {
1941 .build_post_spdif
= patch_ad198x_post_spdif
,
1942 .build_specific
= patch_ad1981b_specific
,
1944 .resume
= ad18xx_resume
1948 static int patch_ad1981b(struct snd_ac97
*ac97
)
1951 ac97
->build_ops
= &patch_ad1981b_build_ops
;
1952 snd_ac97_update_bits(ac97
, AC97_AD_MISC
, AC97_AD198X_MSPLT
, AC97_AD198X_MSPLT
);
1953 ac97
->flags
|= AC97_STEREO_MUTES
;
1954 check_ad1981_hp_jack_sense(ac97
);
1958 #define snd_ac97_ad1888_lohpsel_info snd_ctl_boolean_mono_info
1960 static int snd_ac97_ad1888_lohpsel_get(struct snd_kcontrol
*kcontrol
, struct snd_ctl_elem_value
*ucontrol
)
1962 struct snd_ac97
*ac97
= snd_kcontrol_chip(kcontrol
);
1965 val
= ac97
->regs
[AC97_AD_MISC
];
1966 ucontrol
->value
.integer
.value
[0] = !(val
& AC97_AD198X_LOSEL
);
1967 if (ac97
->spec
.ad18xx
.lo_as_master
)
1968 ucontrol
->value
.integer
.value
[0] =
1969 !ucontrol
->value
.integer
.value
[0];
1973 static int snd_ac97_ad1888_lohpsel_put(struct snd_kcontrol
*kcontrol
, struct snd_ctl_elem_value
*ucontrol
)
1975 struct snd_ac97
*ac97
= snd_kcontrol_chip(kcontrol
);
1978 val
= !ucontrol
->value
.integer
.value
[0];
1979 if (ac97
->spec
.ad18xx
.lo_as_master
)
1981 val
= val
? (AC97_AD198X_LOSEL
| AC97_AD198X_HPSEL
) : 0;
1982 return snd_ac97_update_bits(ac97
, AC97_AD_MISC
,
1983 AC97_AD198X_LOSEL
| AC97_AD198X_HPSEL
, val
);
1986 static int snd_ac97_ad1888_downmix_info(struct snd_kcontrol
*kcontrol
, struct snd_ctl_elem_info
*uinfo
)
1988 static char *texts
[3] = {"Off", "6 -> 4", "6 -> 2"};
1990 uinfo
->type
= SNDRV_CTL_ELEM_TYPE_ENUMERATED
;
1992 uinfo
->value
.enumerated
.items
= 3;
1993 if (uinfo
->value
.enumerated
.item
> 2)
1994 uinfo
->value
.enumerated
.item
= 2;
1995 strcpy(uinfo
->value
.enumerated
.name
, texts
[uinfo
->value
.enumerated
.item
]);
1999 static int snd_ac97_ad1888_downmix_get(struct snd_kcontrol
*kcontrol
, struct snd_ctl_elem_value
*ucontrol
)
2001 struct snd_ac97
*ac97
= snd_kcontrol_chip(kcontrol
);
2004 val
= ac97
->regs
[AC97_AD_MISC
];
2005 if (!(val
& AC97_AD198X_DMIX1
))
2006 ucontrol
->value
.enumerated
.item
[0] = 0;
2008 ucontrol
->value
.enumerated
.item
[0] = 1 + ((val
>> 8) & 1);
2012 static int snd_ac97_ad1888_downmix_put(struct snd_kcontrol
*kcontrol
, struct snd_ctl_elem_value
*ucontrol
)
2014 struct snd_ac97
*ac97
= snd_kcontrol_chip(kcontrol
);
2017 if (ucontrol
->value
.enumerated
.item
[0] > 2)
2019 if (ucontrol
->value
.enumerated
.item
[0] == 0)
2022 val
= AC97_AD198X_DMIX1
|
2023 ((ucontrol
->value
.enumerated
.item
[0] - 1) << 8);
2024 return snd_ac97_update_bits(ac97
, AC97_AD_MISC
,
2025 AC97_AD198X_DMIX0
| AC97_AD198X_DMIX1
, val
);
2028 static void ad1888_update_jacks(struct snd_ac97
*ac97
)
2030 unsigned short val
= 0;
2031 /* clear LODIS if shared jack is to be used for Surround out */
2032 if (!ac97
->spec
.ad18xx
.lo_as_master
&& is_shared_linein(ac97
))
2034 /* clear CLDIS if shared jack is to be used for C/LFE out */
2035 if (is_shared_micin(ac97
))
2037 /* shared Line-In */
2038 snd_ac97_update_bits(ac97
, AC97_AD_MISC
, (1 << 11) | (1 << 12), val
);
2041 static const struct snd_kcontrol_new snd_ac97_ad1888_controls
[] = {
2043 .iface
= SNDRV_CTL_ELEM_IFACE_MIXER
,
2044 .name
= "Exchange Front/Surround",
2045 .info
= snd_ac97_ad1888_lohpsel_info
,
2046 .get
= snd_ac97_ad1888_lohpsel_get
,
2047 .put
= snd_ac97_ad1888_lohpsel_put
2049 AC97_SINGLE("V_REFOUT Enable", AC97_AD_MISC
, AC97_AD_VREFD_SHIFT
, 1, 1),
2050 AC97_SINGLE("High Pass Filter Enable", AC97_AD_TEST2
,
2051 AC97_AD_HPFD_SHIFT
, 1, 1),
2052 AC97_SINGLE("Spread Front to Surround and Center/LFE", AC97_AD_MISC
, 7, 1, 0),
2054 .iface
= SNDRV_CTL_ELEM_IFACE_MIXER
,
2056 .info
= snd_ac97_ad1888_downmix_info
,
2057 .get
= snd_ac97_ad1888_downmix_get
,
2058 .put
= snd_ac97_ad1888_downmix_put
2060 AC97_SURROUND_JACK_MODE_CTL
,
2061 AC97_CHANNEL_MODE_CTL
,
2063 AC97_SINGLE("Headphone Jack Sense", AC97_AD_JACK_SPDIF
, 10, 1, 0),
2064 AC97_SINGLE("Line Jack Sense", AC97_AD_JACK_SPDIF
, 12, 1, 0),
2067 static int patch_ad1888_specific(struct snd_ac97
*ac97
)
2069 if (!ac97
->spec
.ad18xx
.lo_as_master
) {
2070 /* rename 0x04 as "Master" and 0x02 as "Master Surround" */
2071 snd_ac97_rename_vol_ctl(ac97
, "Master Playback",
2072 "Master Surround Playback");
2073 snd_ac97_rename_vol_ctl(ac97
, "Headphone Playback",
2076 return patch_build_controls(ac97
, snd_ac97_ad1888_controls
, ARRAY_SIZE(snd_ac97_ad1888_controls
));
2079 static struct snd_ac97_build_ops patch_ad1888_build_ops
= {
2080 .build_post_spdif
= patch_ad198x_post_spdif
,
2081 .build_specific
= patch_ad1888_specific
,
2083 .resume
= ad1888_resume
,
2085 .update_jacks
= ad1888_update_jacks
,
2088 static int patch_ad1888(struct snd_ac97
* ac97
)
2090 unsigned short misc
;
2093 ac97
->build_ops
= &patch_ad1888_build_ops
;
2096 * LO can be used as a real line-out on some devices,
2097 * and we need to revert the front/surround mixer switches
2099 if (ac97
->subsystem_vendor
== 0x1043 &&
2100 ac97
->subsystem_device
== 0x1193) /* ASUS A9T laptop */
2101 ac97
->spec
.ad18xx
.lo_as_master
= 1;
2103 misc
= snd_ac97_read(ac97
, AC97_AD_MISC
);
2104 /* AD-compatible mode */
2105 /* Stereo mutes enabled */
2106 misc
|= AC97_AD198X_MSPLT
| AC97_AD198X_AC97NC
;
2107 if (!ac97
->spec
.ad18xx
.lo_as_master
)
2108 /* Switch FRONT/SURROUND LINE-OUT/HP-OUT default connection */
2109 /* it seems that most vendors connect line-out connector to
2110 * headphone out of AC'97
2112 misc
|= AC97_AD198X_LOSEL
| AC97_AD198X_HPSEL
;
2114 snd_ac97_write_cache(ac97
, AC97_AD_MISC
, misc
);
2115 ac97
->flags
|= AC97_STEREO_MUTES
;
2119 static int patch_ad1980_specific(struct snd_ac97
*ac97
)
2123 if ((err
= patch_ad1888_specific(ac97
)) < 0)
2125 return patch_build_controls(ac97
, &snd_ac97_ad198x_2cmic
, 1);
2128 static struct snd_ac97_build_ops patch_ad1980_build_ops
= {
2129 .build_post_spdif
= patch_ad198x_post_spdif
,
2130 .build_specific
= patch_ad1980_specific
,
2132 .resume
= ad18xx_resume
,
2134 .update_jacks
= ad1888_update_jacks
,
2137 static int patch_ad1980(struct snd_ac97
* ac97
)
2140 ac97
->build_ops
= &patch_ad1980_build_ops
;
2144 static int snd_ac97_ad1985_vrefout_info(struct snd_kcontrol
*kcontrol
,
2145 struct snd_ctl_elem_info
*uinfo
)
2147 static char *texts
[4] = {"High-Z", "3.7 V", "2.25 V", "0 V"};
2149 uinfo
->type
= SNDRV_CTL_ELEM_TYPE_ENUMERATED
;
2151 uinfo
->value
.enumerated
.items
= 4;
2152 if (uinfo
->value
.enumerated
.item
> 3)
2153 uinfo
->value
.enumerated
.item
= 3;
2154 strcpy(uinfo
->value
.enumerated
.name
,
2155 texts
[uinfo
->value
.enumerated
.item
]);
2159 static int snd_ac97_ad1985_vrefout_get(struct snd_kcontrol
*kcontrol
,
2160 struct snd_ctl_elem_value
*ucontrol
)
2162 static const int reg2ctrl
[4] = {2, 0, 1, 3};
2163 struct snd_ac97
*ac97
= snd_kcontrol_chip(kcontrol
);
2165 val
= (ac97
->regs
[AC97_AD_MISC
] & AC97_AD198X_VREF_MASK
)
2166 >> AC97_AD198X_VREF_SHIFT
;
2167 ucontrol
->value
.enumerated
.item
[0] = reg2ctrl
[val
];
2171 static int snd_ac97_ad1985_vrefout_put(struct snd_kcontrol
*kcontrol
,
2172 struct snd_ctl_elem_value
*ucontrol
)
2174 static const int ctrl2reg
[4] = {1, 2, 0, 3};
2175 struct snd_ac97
*ac97
= snd_kcontrol_chip(kcontrol
);
2178 if (ucontrol
->value
.enumerated
.item
[0] > 3)
2180 val
= ctrl2reg
[ucontrol
->value
.enumerated
.item
[0]]
2181 << AC97_AD198X_VREF_SHIFT
;
2182 return snd_ac97_update_bits(ac97
, AC97_AD_MISC
,
2183 AC97_AD198X_VREF_MASK
, val
);
2186 static const struct snd_kcontrol_new snd_ac97_ad1985_controls
[] = {
2187 AC97_SINGLE("Exchange Center/LFE", AC97_AD_SERIAL_CFG
, 3, 1, 0),
2189 .iface
= SNDRV_CTL_ELEM_IFACE_MIXER
,
2190 .name
= "Exchange Front/Surround",
2191 .info
= snd_ac97_ad1888_lohpsel_info
,
2192 .get
= snd_ac97_ad1888_lohpsel_get
,
2193 .put
= snd_ac97_ad1888_lohpsel_put
2195 AC97_SINGLE("High Pass Filter Enable", AC97_AD_TEST2
, 12, 1, 1),
2196 AC97_SINGLE("Spread Front to Surround and Center/LFE",
2197 AC97_AD_MISC
, 7, 1, 0),
2199 .iface
= SNDRV_CTL_ELEM_IFACE_MIXER
,
2201 .info
= snd_ac97_ad1888_downmix_info
,
2202 .get
= snd_ac97_ad1888_downmix_get
,
2203 .put
= snd_ac97_ad1888_downmix_put
2206 .iface
= SNDRV_CTL_ELEM_IFACE_MIXER
,
2208 .info
= snd_ac97_ad1985_vrefout_info
,
2209 .get
= snd_ac97_ad1985_vrefout_get
,
2210 .put
= snd_ac97_ad1985_vrefout_put
2212 AC97_SURROUND_JACK_MODE_CTL
,
2213 AC97_CHANNEL_MODE_CTL
,
2215 AC97_SINGLE("Headphone Jack Sense", AC97_AD_JACK_SPDIF
, 10, 1, 0),
2216 AC97_SINGLE("Line Jack Sense", AC97_AD_JACK_SPDIF
, 12, 1, 0),
2219 static void ad1985_update_jacks(struct snd_ac97
*ac97
)
2221 ad1888_update_jacks(ac97
);
2222 /* clear OMS if shared jack is to be used for C/LFE out */
2223 snd_ac97_update_bits(ac97
, AC97_AD_SERIAL_CFG
, 1 << 9,
2224 is_shared_micin(ac97
) ? 1 << 9 : 0);
2227 static int patch_ad1985_specific(struct snd_ac97
*ac97
)
2231 /* rename 0x04 as "Master" and 0x02 as "Master Surround" */
2232 snd_ac97_rename_vol_ctl(ac97
, "Master Playback",
2233 "Master Surround Playback");
2234 snd_ac97_rename_vol_ctl(ac97
, "Headphone Playback", "Master Playback");
2236 if ((err
= patch_build_controls(ac97
, &snd_ac97_ad198x_2cmic
, 1)) < 0)
2239 return patch_build_controls(ac97
, snd_ac97_ad1985_controls
,
2240 ARRAY_SIZE(snd_ac97_ad1985_controls
));
2243 static struct snd_ac97_build_ops patch_ad1985_build_ops
= {
2244 .build_post_spdif
= patch_ad198x_post_spdif
,
2245 .build_specific
= patch_ad1985_specific
,
2247 .resume
= ad18xx_resume
,
2249 .update_jacks
= ad1985_update_jacks
,
2252 static int patch_ad1985(struct snd_ac97
* ac97
)
2254 unsigned short misc
;
2257 ac97
->build_ops
= &patch_ad1985_build_ops
;
2258 misc
= snd_ac97_read(ac97
, AC97_AD_MISC
);
2259 /* switch front/surround line-out/hp-out */
2260 /* AD-compatible mode */
2261 /* Stereo mutes enabled */
2262 snd_ac97_write_cache(ac97
, AC97_AD_MISC
, misc
|
2266 AC97_AD198X_AC97NC
);
2267 ac97
->flags
|= AC97_STEREO_MUTES
;
2269 /* update current jack configuration */
2270 ad1985_update_jacks(ac97
);
2272 /* on AD1985 rev. 3, AC'97 revision bits are zero */
2273 ac97
->ext_id
= (ac97
->ext_id
& ~AC97_EI_REV_MASK
) | AC97_EI_REV_23
;
2277 #define snd_ac97_ad1986_bool_info snd_ctl_boolean_mono_info
2279 static int snd_ac97_ad1986_lososel_get(struct snd_kcontrol
*kcontrol
,
2280 struct snd_ctl_elem_value
*ucontrol
)
2282 struct snd_ac97
*ac97
= snd_kcontrol_chip(kcontrol
);
2285 val
= ac97
->regs
[AC97_AD_MISC3
];
2286 ucontrol
->value
.integer
.value
[0] = (val
& AC97_AD1986_LOSEL
) != 0;
2290 static int snd_ac97_ad1986_lososel_put(struct snd_kcontrol
*kcontrol
,
2291 struct snd_ctl_elem_value
*ucontrol
)
2293 struct snd_ac97
*ac97
= snd_kcontrol_chip(kcontrol
);
2296 int sprd
= (ac97
->regs
[AC97_AD_MISC
] & AC97_AD1986_SPRD
) != 0;
2298 ret0
= snd_ac97_update_bits(ac97
, AC97_AD_MISC3
, AC97_AD1986_LOSEL
,
2299 ucontrol
->value
.integer
.value
[0] != 0
2300 ? AC97_AD1986_LOSEL
: 0);
2304 /* SOSEL is set to values of "Spread" or "Exchange F/S" controls */
2305 ret1
= snd_ac97_update_bits(ac97
, AC97_AD_MISC
, AC97_AD1986_SOSEL
,
2306 (ucontrol
->value
.integer
.value
[0] != 0
2308 ? AC97_AD1986_SOSEL
: 0);
2312 return (ret0
> 0 || ret1
> 0) ? 1 : 0;
2315 static int snd_ac97_ad1986_spread_get(struct snd_kcontrol
*kcontrol
,
2316 struct snd_ctl_elem_value
*ucontrol
)
2318 struct snd_ac97
*ac97
= snd_kcontrol_chip(kcontrol
);
2321 val
= ac97
->regs
[AC97_AD_MISC
];
2322 ucontrol
->value
.integer
.value
[0] = (val
& AC97_AD1986_SPRD
) != 0;
2326 static int snd_ac97_ad1986_spread_put(struct snd_kcontrol
*kcontrol
,
2327 struct snd_ctl_elem_value
*ucontrol
)
2329 struct snd_ac97
*ac97
= snd_kcontrol_chip(kcontrol
);
2332 int sprd
= (ac97
->regs
[AC97_AD_MISC3
] & AC97_AD1986_LOSEL
) != 0;
2334 ret0
= snd_ac97_update_bits(ac97
, AC97_AD_MISC
, AC97_AD1986_SPRD
,
2335 ucontrol
->value
.integer
.value
[0] != 0
2336 ? AC97_AD1986_SPRD
: 0);
2340 /* SOSEL is set to values of "Spread" or "Exchange F/S" controls */
2341 ret1
= snd_ac97_update_bits(ac97
, AC97_AD_MISC
, AC97_AD1986_SOSEL
,
2342 (ucontrol
->value
.integer
.value
[0] != 0
2344 ? AC97_AD1986_SOSEL
: 0);
2348 return (ret0
> 0 || ret1
> 0) ? 1 : 0;
2351 static int snd_ac97_ad1986_miclisel_get(struct snd_kcontrol
*kcontrol
,
2352 struct snd_ctl_elem_value
*ucontrol
)
2354 struct snd_ac97
*ac97
= snd_kcontrol_chip(kcontrol
);
2356 ucontrol
->value
.integer
.value
[0] = ac97
->spec
.ad18xx
.swap_mic_linein
;
2360 static int snd_ac97_ad1986_miclisel_put(struct snd_kcontrol
*kcontrol
,
2361 struct snd_ctl_elem_value
*ucontrol
)
2363 struct snd_ac97
*ac97
= snd_kcontrol_chip(kcontrol
);
2364 unsigned char swap
= ucontrol
->value
.integer
.value
[0] != 0;
2366 if (swap
!= ac97
->spec
.ad18xx
.swap_mic_linein
) {
2367 ac97
->spec
.ad18xx
.swap_mic_linein
= swap
;
2368 if (ac97
->build_ops
->update_jacks
)
2369 ac97
->build_ops
->update_jacks(ac97
);
2375 static int snd_ac97_ad1986_vrefout_get(struct snd_kcontrol
*kcontrol
,
2376 struct snd_ctl_elem_value
*ucontrol
)
2378 /* Use MIC_1/2 V_REFOUT as the "get" value */
2379 struct snd_ac97
*ac97
= snd_kcontrol_chip(kcontrol
);
2381 unsigned short reg
= ac97
->regs
[AC97_AD_MISC2
];
2382 if ((reg
& AC97_AD1986_MVREF0
) != 0)
2384 else if ((reg
& AC97_AD1986_MVREF1
) != 0)
2386 else if ((reg
& AC97_AD1986_MVREF2
) != 0)
2390 ucontrol
->value
.enumerated
.item
[0] = val
;
2394 static int snd_ac97_ad1986_vrefout_put(struct snd_kcontrol
*kcontrol
,
2395 struct snd_ctl_elem_value
*ucontrol
)
2397 struct snd_ac97
*ac97
= snd_kcontrol_chip(kcontrol
);
2398 unsigned short cval
;
2399 unsigned short lval
;
2400 unsigned short mval
;
2405 switch (ucontrol
->value
.enumerated
.item
[0])
2407 case 0: /* High-Z */
2413 cval
= AC97_AD1986_CVREF2
;
2414 lval
= AC97_AD1986_LVREF2
;
2415 mval
= AC97_AD1986_MVREF2
;
2417 case 2: /* 2.25 V */
2418 cval
= AC97_AD1986_CVREF0
;
2419 lval
= AC97_AD1986_LVREF0
;
2420 mval
= AC97_AD1986_MVREF0
;
2423 cval
= AC97_AD1986_CVREF1
;
2424 lval
= AC97_AD1986_LVREF1
;
2425 mval
= AC97_AD1986_MVREF1
;
2431 cret
= snd_ac97_update_bits(ac97
, AC97_AD_MISC2
,
2432 AC97_AD1986_CVREF_MASK
, cval
);
2435 lret
= snd_ac97_update_bits(ac97
, AC97_AD_MISC3
,
2436 AC97_AD1986_LVREF_MASK
, lval
);
2439 mret
= snd_ac97_update_bits(ac97
, AC97_AD_MISC2
,
2440 AC97_AD1986_MVREF_MASK
, mval
);
2444 return (cret
> 0 || lret
> 0 || mret
> 0) ? 1 : 0;
2447 static const struct snd_kcontrol_new snd_ac97_ad1986_controls
[] = {
2448 AC97_SINGLE("Exchange Center/LFE", AC97_AD_SERIAL_CFG
, 3, 1, 0),
2450 .iface
= SNDRV_CTL_ELEM_IFACE_MIXER
,
2451 .name
= "Exchange Front/Surround",
2452 .info
= snd_ac97_ad1986_bool_info
,
2453 .get
= snd_ac97_ad1986_lososel_get
,
2454 .put
= snd_ac97_ad1986_lososel_put
2457 .iface
= SNDRV_CTL_ELEM_IFACE_MIXER
,
2458 .name
= "Exchange Mic/Line In",
2459 .info
= snd_ac97_ad1986_bool_info
,
2460 .get
= snd_ac97_ad1986_miclisel_get
,
2461 .put
= snd_ac97_ad1986_miclisel_put
2464 .iface
= SNDRV_CTL_ELEM_IFACE_MIXER
,
2465 .name
= "Spread Front to Surround and Center/LFE",
2466 .info
= snd_ac97_ad1986_bool_info
,
2467 .get
= snd_ac97_ad1986_spread_get
,
2468 .put
= snd_ac97_ad1986_spread_put
2471 .iface
= SNDRV_CTL_ELEM_IFACE_MIXER
,
2473 .info
= snd_ac97_ad1888_downmix_info
,
2474 .get
= snd_ac97_ad1888_downmix_get
,
2475 .put
= snd_ac97_ad1888_downmix_put
2478 .iface
= SNDRV_CTL_ELEM_IFACE_MIXER
,
2480 .info
= snd_ac97_ad1985_vrefout_info
,
2481 .get
= snd_ac97_ad1986_vrefout_get
,
2482 .put
= snd_ac97_ad1986_vrefout_put
2484 AC97_SURROUND_JACK_MODE_CTL
,
2485 AC97_CHANNEL_MODE_CTL
,
2487 AC97_SINGLE("Headphone Jack Sense", AC97_AD_JACK_SPDIF
, 10, 1, 0),
2488 AC97_SINGLE("Line Jack Sense", AC97_AD_JACK_SPDIF
, 12, 1, 0)
2491 static void ad1986_update_jacks(struct snd_ac97
*ac97
)
2493 unsigned short misc_val
= 0;
2494 unsigned short ser_val
;
2496 /* disable SURROUND and CENTER/LFE if not surround mode */
2497 if (!is_surround_on(ac97
))
2498 misc_val
|= AC97_AD1986_SODIS
;
2499 if (!is_clfe_on(ac97
))
2500 misc_val
|= AC97_AD1986_CLDIS
;
2502 /* select line input (default=LINE_IN, SURROUND or MIC_1/2) */
2503 if (is_shared_linein(ac97
))
2504 misc_val
|= AC97_AD1986_LISEL_SURR
;
2505 else if (ac97
->spec
.ad18xx
.swap_mic_linein
!= 0)
2506 misc_val
|= AC97_AD1986_LISEL_MIC
;
2507 snd_ac97_update_bits(ac97
, AC97_AD_MISC
,
2508 AC97_AD1986_SODIS
| AC97_AD1986_CLDIS
|
2509 AC97_AD1986_LISEL_MASK
,
2512 /* select microphone input (MIC_1/2, Center/LFE or LINE_IN) */
2513 if (is_shared_micin(ac97
))
2514 ser_val
= AC97_AD1986_OMS_C
;
2515 else if (ac97
->spec
.ad18xx
.swap_mic_linein
!= 0)
2516 ser_val
= AC97_AD1986_OMS_L
;
2518 ser_val
= AC97_AD1986_OMS_M
;
2519 snd_ac97_update_bits(ac97
, AC97_AD_SERIAL_CFG
,
2520 AC97_AD1986_OMS_MASK
,
2524 static int patch_ad1986_specific(struct snd_ac97
*ac97
)
2528 if ((err
= patch_build_controls(ac97
, &snd_ac97_ad198x_2cmic
, 1)) < 0)
2531 return patch_build_controls(ac97
, snd_ac97_ad1986_controls
,
2532 ARRAY_SIZE(snd_ac97_ad1985_controls
));
2535 static struct snd_ac97_build_ops patch_ad1986_build_ops
= {
2536 .build_post_spdif
= patch_ad198x_post_spdif
,
2537 .build_specific
= patch_ad1986_specific
,
2539 .resume
= ad18xx_resume
,
2541 .update_jacks
= ad1986_update_jacks
,
2544 static int patch_ad1986(struct snd_ac97
* ac97
)
2547 ac97
->build_ops
= &patch_ad1986_build_ops
;
2548 ac97
->flags
|= AC97_STEREO_MUTES
;
2550 /* update current jack configuration */
2551 ad1986_update_jacks(ac97
);
2557 * realtek ALC203: use mono-out for pin 37
2559 static int patch_alc203(struct snd_ac97
*ac97
)
2561 snd_ac97_update_bits(ac97
, 0x7a, 0x400, 0x400);
2566 * realtek ALC65x/850 codecs
2568 static void alc650_update_jacks(struct snd_ac97
*ac97
)
2572 /* shared Line-In / Surround Out */
2573 shared
= is_shared_surrout(ac97
);
2574 snd_ac97_update_bits(ac97
, AC97_ALC650_MULTICH
, 1 << 9,
2575 shared
? (1 << 9) : 0);
2576 /* update shared Mic In / Center/LFE Out */
2577 shared
= is_shared_clfeout(ac97
);
2578 /* disable/enable vref */
2579 snd_ac97_update_bits(ac97
, AC97_ALC650_CLOCK
, 1 << 12,
2580 shared
? (1 << 12) : 0);
2581 /* turn on/off center-on-mic */
2582 snd_ac97_update_bits(ac97
, AC97_ALC650_MULTICH
, 1 << 10,
2583 shared
? (1 << 10) : 0);
2584 /* GPIO0 high for mic */
2585 snd_ac97_update_bits(ac97
, AC97_ALC650_GPIO_STATUS
, 0x100,
2586 shared
? 0 : 0x100);
2589 static const struct snd_kcontrol_new snd_ac97_controls_alc650
[] = {
2590 AC97_SINGLE("Duplicate Front", AC97_ALC650_MULTICH
, 0, 1, 0),
2591 AC97_SINGLE("Surround Down Mix", AC97_ALC650_MULTICH
, 1, 1, 0),
2592 AC97_SINGLE("Center/LFE Down Mix", AC97_ALC650_MULTICH
, 2, 1, 0),
2593 AC97_SINGLE("Exchange Center/LFE", AC97_ALC650_MULTICH
, 3, 1, 0),
2594 /* 4: Analog Input To Surround */
2595 /* 5: Analog Input To Center/LFE */
2596 /* 6: Independent Master Volume Right */
2597 /* 7: Independent Master Volume Left */
2599 /* 9: Line-In/Surround share */
2600 /* 10: Mic/CLFE share */
2601 /* 11-13: in IEC958 controls */
2602 AC97_SINGLE("Swap Surround Slot", AC97_ALC650_MULTICH
, 14, 1, 0),
2603 #if 0 /* always set in patch_alc650 */
2604 AC97_SINGLE("IEC958 Input Clock Enable", AC97_ALC650_CLOCK
, 0, 1, 0),
2605 AC97_SINGLE("IEC958 Input Pin Enable", AC97_ALC650_CLOCK
, 1, 1, 0),
2606 AC97_SINGLE("Surround DAC Switch", AC97_ALC650_SURR_DAC_VOL
, 15, 1, 1),
2607 AC97_DOUBLE("Surround DAC Volume", AC97_ALC650_SURR_DAC_VOL
, 8, 0, 31, 1),
2608 AC97_SINGLE("Center/LFE DAC Switch", AC97_ALC650_LFE_DAC_VOL
, 15, 1, 1),
2609 AC97_DOUBLE("Center/LFE DAC Volume", AC97_ALC650_LFE_DAC_VOL
, 8, 0, 31, 1),
2611 AC97_SURROUND_JACK_MODE_CTL
,
2612 AC97_CHANNEL_MODE_CTL
,
2615 static const struct snd_kcontrol_new snd_ac97_spdif_controls_alc650
[] = {
2616 AC97_SINGLE(SNDRV_CTL_NAME_IEC958("",CAPTURE
,SWITCH
), AC97_ALC650_MULTICH
, 11, 1, 0),
2617 AC97_SINGLE("Analog to IEC958 Output", AC97_ALC650_MULTICH
, 12, 1, 0),
2618 /* disable this controls since it doesn't work as expected */
2619 /* AC97_SINGLE("IEC958 Input Monitor", AC97_ALC650_MULTICH, 13, 1, 0), */
2622 static const DECLARE_TLV_DB_SCALE(db_scale_5bit_3db_max
, -4350, 150, 0);
2624 static int patch_alc650_specific(struct snd_ac97
* ac97
)
2628 if ((err
= patch_build_controls(ac97
, snd_ac97_controls_alc650
, ARRAY_SIZE(snd_ac97_controls_alc650
))) < 0)
2630 if (ac97
->ext_id
& AC97_EI_SPDIF
) {
2631 if ((err
= patch_build_controls(ac97
, snd_ac97_spdif_controls_alc650
, ARRAY_SIZE(snd_ac97_spdif_controls_alc650
))) < 0)
2634 if (ac97
->id
!= AC97_ID_ALC650F
)
2635 reset_tlv(ac97
, "Master Playback Volume",
2636 db_scale_5bit_3db_max
);
2640 static struct snd_ac97_build_ops patch_alc650_ops
= {
2641 .build_specific
= patch_alc650_specific
,
2642 .update_jacks
= alc650_update_jacks
2645 static int patch_alc650(struct snd_ac97
* ac97
)
2649 ac97
->build_ops
= &patch_alc650_ops
;
2651 /* determine the revision */
2652 val
= snd_ac97_read(ac97
, AC97_ALC650_REVISION
) & 0x3f;
2654 ac97
->id
= 0x414c4720; /* Old version */
2655 else if (val
< 0x10)
2656 ac97
->id
= 0x414c4721; /* D version */
2657 else if (val
< 0x20)
2658 ac97
->id
= 0x414c4722; /* E version */
2659 else if (val
< 0x30)
2660 ac97
->id
= 0x414c4723; /* F version */
2662 /* revision E or F */
2663 /* FIXME: what about revision D ? */
2664 ac97
->spec
.dev_flags
= (ac97
->id
== 0x414c4722 ||
2665 ac97
->id
== 0x414c4723);
2667 /* enable AC97_ALC650_GPIO_SETUP, AC97_ALC650_CLOCK for R/W */
2668 snd_ac97_write_cache(ac97
, AC97_ALC650_GPIO_STATUS
,
2669 snd_ac97_read(ac97
, AC97_ALC650_GPIO_STATUS
) | 0x8000);
2671 /* Enable SPDIF-IN only on Rev.E and above */
2672 val
= snd_ac97_read(ac97
, AC97_ALC650_CLOCK
);
2673 /* SPDIF IN with pin 47 */
2674 if (ac97
->spec
.dev_flags
&&
2675 /* ASUS A6KM requires EAPD */
2676 ! (ac97
->subsystem_vendor
== 0x1043 &&
2677 ac97
->subsystem_device
== 0x1103))
2678 val
|= 0x03; /* enable */
2680 val
&= ~0x03; /* disable */
2681 snd_ac97_write_cache(ac97
, AC97_ALC650_CLOCK
, val
);
2683 /* set default: slot 3,4,7,8,6,9
2684 spdif-in monitor off, analog-spdif off, spdif-in off
2685 center on mic off, surround on line-in off
2686 downmix off, duplicate front off
2688 snd_ac97_write_cache(ac97
, AC97_ALC650_MULTICH
, 0);
2690 /* set GPIO0 for mic bias */
2691 /* GPIO0 pin output, no interrupt, high */
2692 snd_ac97_write_cache(ac97
, AC97_ALC650_GPIO_SETUP
,
2693 snd_ac97_read(ac97
, AC97_ALC650_GPIO_SETUP
) | 0x01);
2694 snd_ac97_write_cache(ac97
, AC97_ALC650_GPIO_STATUS
,
2695 (snd_ac97_read(ac97
, AC97_ALC650_GPIO_STATUS
) | 0x100) & ~0x10);
2697 /* full DAC volume */
2698 snd_ac97_write_cache(ac97
, AC97_ALC650_SURR_DAC_VOL
, 0x0808);
2699 snd_ac97_write_cache(ac97
, AC97_ALC650_LFE_DAC_VOL
, 0x0808);
2703 static void alc655_update_jacks(struct snd_ac97
*ac97
)
2707 /* shared Line-In / Surround Out */
2708 shared
= is_shared_surrout(ac97
);
2709 ac97_update_bits_page(ac97
, AC97_ALC650_MULTICH
, 1 << 9,
2710 shared
? (1 << 9) : 0, 0);
2711 /* update shared Mic In / Center/LFE Out */
2712 shared
= is_shared_clfeout(ac97
);
2713 /* misc control; vrefout disable */
2714 snd_ac97_update_bits(ac97
, AC97_ALC650_CLOCK
, 1 << 12,
2715 shared
? (1 << 12) : 0);
2716 ac97_update_bits_page(ac97
, AC97_ALC650_MULTICH
, 1 << 10,
2717 shared
? (1 << 10) : 0, 0);
2720 static const struct snd_kcontrol_new snd_ac97_controls_alc655
[] = {
2721 AC97_PAGE_SINGLE("Duplicate Front", AC97_ALC650_MULTICH
, 0, 1, 0, 0),
2722 AC97_SURROUND_JACK_MODE_CTL
,
2723 AC97_CHANNEL_MODE_CTL
,
2726 static int alc655_iec958_route_info(struct snd_kcontrol
*kcontrol
, struct snd_ctl_elem_info
*uinfo
)
2728 static char *texts_655
[3] = { "PCM", "Analog In", "IEC958 In" };
2729 static char *texts_658
[4] = { "PCM", "Analog1 In", "Analog2 In", "IEC958 In" };
2730 struct snd_ac97
*ac97
= snd_kcontrol_chip(kcontrol
);
2732 uinfo
->type
= SNDRV_CTL_ELEM_TYPE_ENUMERATED
;
2734 uinfo
->value
.enumerated
.items
= ac97
->spec
.dev_flags
? 4 : 3;
2735 if (uinfo
->value
.enumerated
.item
>= uinfo
->value
.enumerated
.items
)
2736 uinfo
->value
.enumerated
.item
= uinfo
->value
.enumerated
.items
- 1;
2737 strcpy(uinfo
->value
.enumerated
.name
,
2738 ac97
->spec
.dev_flags
?
2739 texts_658
[uinfo
->value
.enumerated
.item
] :
2740 texts_655
[uinfo
->value
.enumerated
.item
]);
2744 static int alc655_iec958_route_get(struct snd_kcontrol
*kcontrol
, struct snd_ctl_elem_value
*ucontrol
)
2746 struct snd_ac97
*ac97
= snd_kcontrol_chip(kcontrol
);
2749 val
= ac97
->regs
[AC97_ALC650_MULTICH
];
2750 val
= (val
>> 12) & 3;
2751 if (ac97
->spec
.dev_flags
&& val
== 3)
2753 ucontrol
->value
.enumerated
.item
[0] = val
;
2757 static int alc655_iec958_route_put(struct snd_kcontrol
*kcontrol
, struct snd_ctl_elem_value
*ucontrol
)
2759 struct snd_ac97
*ac97
= snd_kcontrol_chip(kcontrol
);
2761 return ac97_update_bits_page(ac97
, AC97_ALC650_MULTICH
, 3 << 12,
2762 (unsigned short)ucontrol
->value
.enumerated
.item
[0] << 12,
2766 static const struct snd_kcontrol_new snd_ac97_spdif_controls_alc655
[] = {
2767 AC97_PAGE_SINGLE(SNDRV_CTL_NAME_IEC958("",CAPTURE
,SWITCH
), AC97_ALC650_MULTICH
, 11, 1, 0, 0),
2768 /* disable this controls since it doesn't work as expected */
2769 /* AC97_PAGE_SINGLE("IEC958 Input Monitor", AC97_ALC650_MULTICH, 14, 1, 0, 0), */
2771 .iface
= SNDRV_CTL_ELEM_IFACE_MIXER
,
2772 .name
= SNDRV_CTL_NAME_IEC958("",PLAYBACK
,NONE
) "Source",
2773 .info
= alc655_iec958_route_info
,
2774 .get
= alc655_iec958_route_get
,
2775 .put
= alc655_iec958_route_put
,
2779 static int patch_alc655_specific(struct snd_ac97
* ac97
)
2783 if ((err
= patch_build_controls(ac97
, snd_ac97_controls_alc655
, ARRAY_SIZE(snd_ac97_controls_alc655
))) < 0)
2785 if (ac97
->ext_id
& AC97_EI_SPDIF
) {
2786 if ((err
= patch_build_controls(ac97
, snd_ac97_spdif_controls_alc655
, ARRAY_SIZE(snd_ac97_spdif_controls_alc655
))) < 0)
2792 static struct snd_ac97_build_ops patch_alc655_ops
= {
2793 .build_specific
= patch_alc655_specific
,
2794 .update_jacks
= alc655_update_jacks
2797 static int patch_alc655(struct snd_ac97
* ac97
)
2801 if (ac97
->id
== AC97_ID_ALC658
) {
2802 ac97
->spec
.dev_flags
= 1; /* ALC658 */
2803 if ((snd_ac97_read(ac97
, AC97_ALC650_REVISION
) & 0x3f) == 2) {
2804 ac97
->id
= AC97_ID_ALC658D
;
2805 ac97
->spec
.dev_flags
= 2;
2809 ac97
->build_ops
= &patch_alc655_ops
;
2811 /* assume only page 0 for writing cache */
2812 snd_ac97_update_bits(ac97
, AC97_INT_PAGING
, AC97_PAGE_MASK
, AC97_PAGE_VENDOR
);
2814 /* adjust default values */
2815 val
= snd_ac97_read(ac97
, 0x7a); /* misc control */
2816 if (ac97
->spec
.dev_flags
) /* ALC658 */
2817 val
&= ~(1 << 1); /* Pin 47 is spdif input pin */
2819 if (ac97
->subsystem_vendor
== 0x1462 &&
2820 (ac97
->subsystem_device
== 0x0131 || /* MSI S270 laptop */
2821 ac97
->subsystem_device
== 0x0161 || /* LG K1 Express */
2822 ac97
->subsystem_device
== 0x0351 || /* MSI L725 laptop */
2823 ac97
->subsystem_device
== 0x0471 || /* MSI L720 laptop */
2824 ac97
->subsystem_device
== 0x0061)) /* MSI S250 laptop */
2825 val
&= ~(1 << 1); /* Pin 47 is EAPD (for internal speaker) */
2827 val
|= (1 << 1); /* Pin 47 is spdif input pin */
2828 /* this seems missing on some hardwares */
2829 ac97
->ext_id
|= AC97_EI_SPDIF
;
2831 val
&= ~(1 << 12); /* vref enable */
2832 snd_ac97_write_cache(ac97
, 0x7a, val
);
2833 /* set default: spdif-in enabled,
2834 spdif-in monitor off, spdif-in PCM off
2835 center on mic off, surround on line-in off
2838 snd_ac97_write_cache(ac97
, AC97_ALC650_MULTICH
, 1<<15);
2840 /* full DAC volume */
2841 snd_ac97_write_cache(ac97
, AC97_ALC650_SURR_DAC_VOL
, 0x0808);
2842 snd_ac97_write_cache(ac97
, AC97_ALC650_LFE_DAC_VOL
, 0x0808);
2844 /* update undocumented bit... */
2845 if (ac97
->id
== AC97_ID_ALC658D
)
2846 snd_ac97_update_bits(ac97
, 0x74, 0x0800, 0x0800);
2852 #define AC97_ALC850_JACK_SELECT 0x76
2853 #define AC97_ALC850_MISC1 0x7a
2854 #define AC97_ALC850_MULTICH 0x6a
2856 static void alc850_update_jacks(struct snd_ac97
*ac97
)
2859 int aux_is_back_surround
;
2861 /* shared Line-In / Surround Out */
2862 shared
= is_shared_surrout(ac97
);
2863 /* SURR 1kOhm (bit4), Amp (bit5) */
2864 snd_ac97_update_bits(ac97
, AC97_ALC850_MISC1
, (1<<4)|(1<<5),
2865 shared
? (1<<5) : (1<<4));
2866 /* LINE-IN = 0, SURROUND = 2 */
2867 snd_ac97_update_bits(ac97
, AC97_ALC850_JACK_SELECT
, 7 << 12,
2868 shared
? (2<<12) : (0<<12));
2869 /* update shared Mic In / Center/LFE Out */
2870 shared
= is_shared_clfeout(ac97
);
2871 /* Vref disable (bit12), 1kOhm (bit13) */
2872 snd_ac97_update_bits(ac97
, AC97_ALC850_MISC1
, (1<<12)|(1<<13),
2873 shared
? (1<<12) : (1<<13));
2874 /* MIC-IN = 1, CENTER-LFE = 5 */
2875 snd_ac97_update_bits(ac97
, AC97_ALC850_JACK_SELECT
, 7 << 4,
2876 shared
? (5<<4) : (1<<4));
2878 aux_is_back_surround
= alc850_is_aux_back_surround(ac97
);
2879 /* Aux is Back Surround */
2880 snd_ac97_update_bits(ac97
, AC97_ALC850_MULTICH
, 1 << 10,
2881 aux_is_back_surround
? (1<<10) : (0<<10));
2884 static const struct snd_kcontrol_new snd_ac97_controls_alc850
[] = {
2885 AC97_PAGE_SINGLE("Duplicate Front", AC97_ALC650_MULTICH
, 0, 1, 0, 0),
2886 AC97_SINGLE("Mic Front Input Switch", AC97_ALC850_JACK_SELECT
, 15, 1, 1),
2887 AC97_SURROUND_JACK_MODE_CTL
,
2888 AC97_CHANNEL_MODE_8CH_CTL
,
2891 static int patch_alc850_specific(struct snd_ac97
*ac97
)
2895 if ((err
= patch_build_controls(ac97
, snd_ac97_controls_alc850
, ARRAY_SIZE(snd_ac97_controls_alc850
))) < 0)
2897 if (ac97
->ext_id
& AC97_EI_SPDIF
) {
2898 if ((err
= patch_build_controls(ac97
, snd_ac97_spdif_controls_alc655
, ARRAY_SIZE(snd_ac97_spdif_controls_alc655
))) < 0)
2904 static struct snd_ac97_build_ops patch_alc850_ops
= {
2905 .build_specific
= patch_alc850_specific
,
2906 .update_jacks
= alc850_update_jacks
2909 static int patch_alc850(struct snd_ac97
*ac97
)
2911 ac97
->build_ops
= &patch_alc850_ops
;
2913 ac97
->spec
.dev_flags
= 0; /* for IEC958 playback route - ALC655 compatible */
2914 ac97
->flags
|= AC97_HAS_8CH
;
2916 /* assume only page 0 for writing cache */
2917 snd_ac97_update_bits(ac97
, AC97_INT_PAGING
, AC97_PAGE_MASK
, AC97_PAGE_VENDOR
);
2919 /* adjust default values */
2920 /* set default: spdif-in enabled,
2921 spdif-in monitor off, spdif-in PCM off
2922 center on mic off, surround on line-in off
2924 NB default bit 10=0 = Aux is Capture, not Back Surround
2926 snd_ac97_write_cache(ac97
, AC97_ALC650_MULTICH
, 1<<15);
2927 /* SURR_OUT: on, Surr 1kOhm: on, Surr Amp: off, Front 1kOhm: off
2928 * Front Amp: on, Vref: enable, Center 1kOhm: on, Mix: on
2930 snd_ac97_write_cache(ac97
, 0x7a, (1<<1)|(1<<4)|(0<<5)|(1<<6)|
2931 (1<<7)|(0<<12)|(1<<13)|(0<<14));
2932 /* detection UIO2,3: all path floating, UIO3: MIC, Vref2: disable,
2933 * UIO1: FRONT, Vref3: disable, UIO3: LINE, Front-Mic: mute
2935 snd_ac97_write_cache(ac97
, 0x76, (0<<0)|(0<<2)|(1<<4)|(1<<7)|(2<<8)|
2936 (1<<11)|(0<<12)|(1<<15));
2938 /* full DAC volume */
2939 snd_ac97_write_cache(ac97
, AC97_ALC650_SURR_DAC_VOL
, 0x0808);
2940 snd_ac97_write_cache(ac97
, AC97_ALC650_LFE_DAC_VOL
, 0x0808);
2946 * C-Media CM97xx codecs
2948 static void cm9738_update_jacks(struct snd_ac97
*ac97
)
2950 /* shared Line-In / Surround Out */
2951 snd_ac97_update_bits(ac97
, AC97_CM9738_VENDOR_CTRL
, 1 << 10,
2952 is_shared_surrout(ac97
) ? (1 << 10) : 0);
2955 static const struct snd_kcontrol_new snd_ac97_cm9738_controls
[] = {
2956 AC97_SINGLE("Duplicate Front", AC97_CM9738_VENDOR_CTRL
, 13, 1, 0),
2957 AC97_SURROUND_JACK_MODE_CTL
,
2958 AC97_CHANNEL_MODE_4CH_CTL
,
2961 static int patch_cm9738_specific(struct snd_ac97
* ac97
)
2963 return patch_build_controls(ac97
, snd_ac97_cm9738_controls
, ARRAY_SIZE(snd_ac97_cm9738_controls
));
2966 static struct snd_ac97_build_ops patch_cm9738_ops
= {
2967 .build_specific
= patch_cm9738_specific
,
2968 .update_jacks
= cm9738_update_jacks
2971 static int patch_cm9738(struct snd_ac97
* ac97
)
2973 ac97
->build_ops
= &patch_cm9738_ops
;
2974 /* FIXME: can anyone confirm below? */
2975 /* CM9738 has no PCM volume although the register reacts */
2976 ac97
->flags
|= AC97_HAS_NO_PCM_VOL
;
2977 snd_ac97_write_cache(ac97
, AC97_PCM
, 0x8000);
2982 static int snd_ac97_cmedia_spdif_playback_source_info(struct snd_kcontrol
*kcontrol
, struct snd_ctl_elem_info
*uinfo
)
2984 static char *texts
[] = { "Analog", "Digital" };
2986 uinfo
->type
= SNDRV_CTL_ELEM_TYPE_ENUMERATED
;
2988 uinfo
->value
.enumerated
.items
= 2;
2989 if (uinfo
->value
.enumerated
.item
> 1)
2990 uinfo
->value
.enumerated
.item
= 1;
2991 strcpy(uinfo
->value
.enumerated
.name
, texts
[uinfo
->value
.enumerated
.item
]);
2995 static int snd_ac97_cmedia_spdif_playback_source_get(struct snd_kcontrol
*kcontrol
, struct snd_ctl_elem_value
*ucontrol
)
2997 struct snd_ac97
*ac97
= snd_kcontrol_chip(kcontrol
);
3000 val
= ac97
->regs
[AC97_CM9739_SPDIF_CTRL
];
3001 ucontrol
->value
.enumerated
.item
[0] = (val
>> 1) & 0x01;
3005 static int snd_ac97_cmedia_spdif_playback_source_put(struct snd_kcontrol
*kcontrol
, struct snd_ctl_elem_value
*ucontrol
)
3007 struct snd_ac97
*ac97
= snd_kcontrol_chip(kcontrol
);
3009 return snd_ac97_update_bits(ac97
, AC97_CM9739_SPDIF_CTRL
,
3011 (ucontrol
->value
.enumerated
.item
[0] & 0x01) << 1);
3014 static const struct snd_kcontrol_new snd_ac97_cm9739_controls_spdif
[] = {
3015 /* BIT 0: SPDI_EN - always true */
3016 { /* BIT 1: SPDIFS */
3017 .iface
= SNDRV_CTL_ELEM_IFACE_MIXER
,
3018 .name
= SNDRV_CTL_NAME_IEC958("",PLAYBACK
,NONE
) "Source",
3019 .info
= snd_ac97_cmedia_spdif_playback_source_info
,
3020 .get
= snd_ac97_cmedia_spdif_playback_source_get
,
3021 .put
= snd_ac97_cmedia_spdif_playback_source_put
,
3023 /* BIT 2: IG_SPIV */
3024 AC97_SINGLE(SNDRV_CTL_NAME_IEC958("",CAPTURE
,NONE
) "Valid Switch", AC97_CM9739_SPDIF_CTRL
, 2, 1, 0),
3026 AC97_SINGLE(SNDRV_CTL_NAME_IEC958("",CAPTURE
,NONE
) "Monitor", AC97_CM9739_SPDIF_CTRL
, 3, 1, 0),
3027 /* BIT 4: SPI2SDI */
3028 AC97_SINGLE(SNDRV_CTL_NAME_IEC958("",CAPTURE
,SWITCH
), AC97_CM9739_SPDIF_CTRL
, 4, 1, 0),
3029 /* BIT 8: SPD32 - 32bit SPDIF - not supported yet */
3032 static void cm9739_update_jacks(struct snd_ac97
*ac97
)
3034 /* shared Line-In / Surround Out */
3035 snd_ac97_update_bits(ac97
, AC97_CM9739_MULTI_CHAN
, 1 << 10,
3036 is_shared_surrout(ac97
) ? (1 << 10) : 0);
3037 /* shared Mic In / Center/LFE Out **/
3038 snd_ac97_update_bits(ac97
, AC97_CM9739_MULTI_CHAN
, 0x3000,
3039 is_shared_clfeout(ac97
) ? 0x1000 : 0x2000);
3042 static const struct snd_kcontrol_new snd_ac97_cm9739_controls
[] = {
3043 AC97_SURROUND_JACK_MODE_CTL
,
3044 AC97_CHANNEL_MODE_CTL
,
3047 static int patch_cm9739_specific(struct snd_ac97
* ac97
)
3049 return patch_build_controls(ac97
, snd_ac97_cm9739_controls
, ARRAY_SIZE(snd_ac97_cm9739_controls
));
3052 static int patch_cm9739_post_spdif(struct snd_ac97
* ac97
)
3054 return patch_build_controls(ac97
, snd_ac97_cm9739_controls_spdif
, ARRAY_SIZE(snd_ac97_cm9739_controls_spdif
));
3057 static struct snd_ac97_build_ops patch_cm9739_ops
= {
3058 .build_specific
= patch_cm9739_specific
,
3059 .build_post_spdif
= patch_cm9739_post_spdif
,
3060 .update_jacks
= cm9739_update_jacks
3063 static int patch_cm9739(struct snd_ac97
* ac97
)
3067 ac97
->build_ops
= &patch_cm9739_ops
;
3069 /* CM9739/A has no Master and PCM volume although the register reacts */
3070 ac97
->flags
|= AC97_HAS_NO_MASTER_VOL
| AC97_HAS_NO_PCM_VOL
;
3071 snd_ac97_write_cache(ac97
, AC97_MASTER
, 0x8000);
3072 snd_ac97_write_cache(ac97
, AC97_PCM
, 0x8000);
3075 val
= snd_ac97_read(ac97
, AC97_EXTENDED_STATUS
);
3076 if (val
& AC97_EA_SPCV
) {
3077 /* enable spdif in */
3078 snd_ac97_write_cache(ac97
, AC97_CM9739_SPDIF_CTRL
,
3079 snd_ac97_read(ac97
, AC97_CM9739_SPDIF_CTRL
) | 0x01);
3080 ac97
->rates
[AC97_RATES_SPDIF
] = SNDRV_PCM_RATE_48000
; /* 48k only */
3082 ac97
->ext_id
&= ~AC97_EI_SPDIF
; /* disable extended-id */
3083 ac97
->rates
[AC97_RATES_SPDIF
] = 0;
3086 /* set-up multi channel */
3087 /* bit 14: 0 = SPDIF, 1 = EAPD */
3088 /* bit 13: enable internal vref output for mic */
3089 /* bit 12: disable center/lfe (swithable) */
3090 /* bit 10: disable surround/line (switchable) */
3091 /* bit 9: mix 2 surround off */
3092 /* bit 4: undocumented; 0 mutes the CM9739A, which defaults to 1 */
3093 /* bit 3: undocumented; surround? */
3095 val
= snd_ac97_read(ac97
, AC97_CM9739_MULTI_CHAN
) & (1 << 4);
3098 if (! (ac97
->ext_id
& AC97_EI_SPDIF
))
3100 snd_ac97_write_cache(ac97
, AC97_CM9739_MULTI_CHAN
, val
);
3102 /* FIXME: set up GPIO */
3103 snd_ac97_write_cache(ac97
, 0x70, 0x0100);
3104 snd_ac97_write_cache(ac97
, 0x72, 0x0020);
3105 /* Special exception for ASUS W1000/CMI9739. It does not have an SPDIF in. */
3107 ac97
->subsystem_vendor
== 0x1043 &&
3108 ac97
->subsystem_device
== 0x1843) {
3109 snd_ac97_write_cache(ac97
, AC97_CM9739_SPDIF_CTRL
,
3110 snd_ac97_read(ac97
, AC97_CM9739_SPDIF_CTRL
) & ~0x01);
3111 snd_ac97_write_cache(ac97
, AC97_CM9739_MULTI_CHAN
,
3112 snd_ac97_read(ac97
, AC97_CM9739_MULTI_CHAN
) | (1 << 14));
3118 #define AC97_CM9761_MULTI_CHAN 0x64
3119 #define AC97_CM9761_FUNC 0x66
3120 #define AC97_CM9761_SPDIF_CTRL 0x6c
3122 static void cm9761_update_jacks(struct snd_ac97
*ac97
)
3124 /* FIXME: check the bits for each model
3125 * model 83 is confirmed to work
3127 static unsigned short surr_on
[3][2] = {
3128 { 0x0008, 0x0000 }, /* 9761-78 & 82 */
3129 { 0x0000, 0x0008 }, /* 9761-82 rev.B */
3130 { 0x0000, 0x0008 }, /* 9761-83 */
3132 static unsigned short clfe_on
[3][2] = {
3133 { 0x0000, 0x1000 }, /* 9761-78 & 82 */
3134 { 0x1000, 0x0000 }, /* 9761-82 rev.B */
3135 { 0x0000, 0x1000 }, /* 9761-83 */
3137 static unsigned short surr_shared
[3][2] = {
3138 { 0x0000, 0x0400 }, /* 9761-78 & 82 */
3139 { 0x0000, 0x0400 }, /* 9761-82 rev.B */
3140 { 0x0000, 0x0400 }, /* 9761-83 */
3142 static unsigned short clfe_shared
[3][2] = {
3143 { 0x2000, 0x0880 }, /* 9761-78 & 82 */
3144 { 0x0000, 0x2880 }, /* 9761-82 rev.B */
3145 { 0x2000, 0x0800 }, /* 9761-83 */
3147 unsigned short val
= 0;
3149 val
|= surr_on
[ac97
->spec
.dev_flags
][is_surround_on(ac97
)];
3150 val
|= clfe_on
[ac97
->spec
.dev_flags
][is_clfe_on(ac97
)];
3151 val
|= surr_shared
[ac97
->spec
.dev_flags
][is_shared_surrout(ac97
)];
3152 val
|= clfe_shared
[ac97
->spec
.dev_flags
][is_shared_clfeout(ac97
)];
3154 snd_ac97_update_bits(ac97
, AC97_CM9761_MULTI_CHAN
, 0x3c88, val
);
3157 static const struct snd_kcontrol_new snd_ac97_cm9761_controls
[] = {
3158 AC97_SURROUND_JACK_MODE_CTL
,
3159 AC97_CHANNEL_MODE_CTL
,
3162 static int cm9761_spdif_out_source_info(struct snd_kcontrol
*kcontrol
, struct snd_ctl_elem_info
*uinfo
)
3164 static char *texts
[] = { "AC-Link", "ADC", "SPDIF-In" };
3166 uinfo
->type
= SNDRV_CTL_ELEM_TYPE_ENUMERATED
;
3168 uinfo
->value
.enumerated
.items
= 3;
3169 if (uinfo
->value
.enumerated
.item
> 2)
3170 uinfo
->value
.enumerated
.item
= 2;
3171 strcpy(uinfo
->value
.enumerated
.name
, texts
[uinfo
->value
.enumerated
.item
]);
3175 static int cm9761_spdif_out_source_get(struct snd_kcontrol
*kcontrol
, struct snd_ctl_elem_value
*ucontrol
)
3177 struct snd_ac97
*ac97
= snd_kcontrol_chip(kcontrol
);
3179 if (ac97
->regs
[AC97_CM9761_FUNC
] & 0x1)
3180 ucontrol
->value
.enumerated
.item
[0] = 2; /* SPDIF-loopback */
3181 else if (ac97
->regs
[AC97_CM9761_SPDIF_CTRL
] & 0x2)
3182 ucontrol
->value
.enumerated
.item
[0] = 1; /* ADC loopback */
3184 ucontrol
->value
.enumerated
.item
[0] = 0; /* AC-link */
3188 static int cm9761_spdif_out_source_put(struct snd_kcontrol
*kcontrol
, struct snd_ctl_elem_value
*ucontrol
)
3190 struct snd_ac97
*ac97
= snd_kcontrol_chip(kcontrol
);
3192 if (ucontrol
->value
.enumerated
.item
[0] == 2)
3193 return snd_ac97_update_bits(ac97
, AC97_CM9761_FUNC
, 0x1, 0x1);
3194 snd_ac97_update_bits(ac97
, AC97_CM9761_FUNC
, 0x1, 0);
3195 return snd_ac97_update_bits(ac97
, AC97_CM9761_SPDIF_CTRL
, 0x2,
3196 ucontrol
->value
.enumerated
.item
[0] == 1 ? 0x2 : 0);
3199 static const char *cm9761_dac_clock
[] = { "AC-Link", "SPDIF-In", "Both" };
3200 static const struct ac97_enum cm9761_dac_clock_enum
=
3201 AC97_ENUM_SINGLE(AC97_CM9761_SPDIF_CTRL
, 9, 3, cm9761_dac_clock
);
3203 static const struct snd_kcontrol_new snd_ac97_cm9761_controls_spdif
[] = {
3204 { /* BIT 1: SPDIFS */
3205 .iface
= SNDRV_CTL_ELEM_IFACE_MIXER
,
3206 .name
= SNDRV_CTL_NAME_IEC958("",PLAYBACK
,NONE
) "Source",
3207 .info
= cm9761_spdif_out_source_info
,
3208 .get
= cm9761_spdif_out_source_get
,
3209 .put
= cm9761_spdif_out_source_put
,
3211 /* BIT 2: IG_SPIV */
3212 AC97_SINGLE(SNDRV_CTL_NAME_IEC958("",CAPTURE
,NONE
) "Valid Switch", AC97_CM9761_SPDIF_CTRL
, 2, 1, 0),
3214 AC97_SINGLE(SNDRV_CTL_NAME_IEC958("",CAPTURE
,NONE
) "Monitor", AC97_CM9761_SPDIF_CTRL
, 3, 1, 0),
3215 /* BIT 4: SPI2SDI */
3216 AC97_SINGLE(SNDRV_CTL_NAME_IEC958("",CAPTURE
,SWITCH
), AC97_CM9761_SPDIF_CTRL
, 4, 1, 0),
3217 /* BIT 9-10: DAC_CTL */
3218 AC97_ENUM("DAC Clock Source", cm9761_dac_clock_enum
),
3221 static int patch_cm9761_post_spdif(struct snd_ac97
* ac97
)
3223 return patch_build_controls(ac97
, snd_ac97_cm9761_controls_spdif
, ARRAY_SIZE(snd_ac97_cm9761_controls_spdif
));
3226 static int patch_cm9761_specific(struct snd_ac97
* ac97
)
3228 return patch_build_controls(ac97
, snd_ac97_cm9761_controls
, ARRAY_SIZE(snd_ac97_cm9761_controls
));
3231 static struct snd_ac97_build_ops patch_cm9761_ops
= {
3232 .build_specific
= patch_cm9761_specific
,
3233 .build_post_spdif
= patch_cm9761_post_spdif
,
3234 .update_jacks
= cm9761_update_jacks
3237 static int patch_cm9761(struct snd_ac97
*ac97
)
3241 /* CM9761 has no PCM volume although the register reacts */
3242 /* Master volume seems to have _some_ influence on the analog
3245 ac97
->flags
|= /*AC97_HAS_NO_MASTER_VOL |*/ AC97_HAS_NO_PCM_VOL
;
3246 snd_ac97_write_cache(ac97
, AC97_MASTER
, 0x8808);
3247 snd_ac97_write_cache(ac97
, AC97_PCM
, 0x8808);
3249 ac97
->spec
.dev_flags
= 0; /* 1 = model 82 revision B, 2 = model 83 */
3250 if (ac97
->id
== AC97_ID_CM9761_82
) {
3252 /* check page 1, reg 0x60 */
3253 val
= snd_ac97_read(ac97
, AC97_INT_PAGING
);
3254 snd_ac97_write_cache(ac97
, AC97_INT_PAGING
, (val
& ~0x0f) | 0x01);
3255 tmp
= snd_ac97_read(ac97
, 0x60);
3256 ac97
->spec
.dev_flags
= tmp
& 1; /* revision B? */
3257 snd_ac97_write_cache(ac97
, AC97_INT_PAGING
, val
);
3258 } else if (ac97
->id
== AC97_ID_CM9761_83
)
3259 ac97
->spec
.dev_flags
= 2;
3261 ac97
->build_ops
= &patch_cm9761_ops
;
3264 /* force the SPDIF bit in ext_id - codec doesn't set this bit! */
3265 ac97
->ext_id
|= AC97_EI_SPDIF
;
3266 /* to be sure: we overwrite the ext status bits */
3267 snd_ac97_write_cache(ac97
, AC97_EXTENDED_STATUS
, 0x05c0);
3268 /* Don't set 0x0200 here. This results in the silent analog output */
3269 snd_ac97_write_cache(ac97
, AC97_CM9761_SPDIF_CTRL
, 0x0001); /* enable spdif-in */
3270 ac97
->rates
[AC97_RATES_SPDIF
] = SNDRV_PCM_RATE_48000
; /* 48k only */
3272 /* set-up multi channel */
3273 /* bit 15: pc master beep off
3274 * bit 14: pin47 = EAPD/SPDIF
3275 * bit 13: vref ctl [= cm9739]
3276 * bit 12: CLFE control (reverted on rev B)
3277 * bit 11: Mic/center share (reverted on rev B)
3278 * bit 10: suddound/line share
3279 * bit 9: Analog-in mix -> surround
3280 * bit 8: Analog-in mix -> CLFE
3281 * bit 7: Mic/LFE share (mic/center/lfe)
3282 * bit 5: vref select (9761A)
3283 * bit 4: front control
3284 * bit 3: surround control (revereted with rev B)
3287 * bit 0: mic boost level (0=20dB, 1=30dB)
3291 if (ac97
->spec
.dev_flags
)
3296 val
= snd_ac97_read(ac97
, AC97_CM9761_MULTI_CHAN
);
3297 val
|= (1 << 4); /* front on */
3298 snd_ac97_write_cache(ac97
, AC97_CM9761_MULTI_CHAN
, val
);
3300 /* FIXME: set up GPIO */
3301 snd_ac97_write_cache(ac97
, 0x70, 0x0100);
3302 snd_ac97_write_cache(ac97
, 0x72, 0x0020);
3307 #define AC97_CM9780_SIDE 0x60
3308 #define AC97_CM9780_JACK 0x62
3309 #define AC97_CM9780_MIXER 0x64
3310 #define AC97_CM9780_MULTI_CHAN 0x66
3311 #define AC97_CM9780_SPDIF 0x6c
3313 static const char *cm9780_ch_select
[] = { "Front", "Side", "Center/LFE", "Rear" };
3314 static const struct ac97_enum cm9780_ch_select_enum
=
3315 AC97_ENUM_SINGLE(AC97_CM9780_MULTI_CHAN
, 6, 4, cm9780_ch_select
);
3316 static const struct snd_kcontrol_new cm9780_controls
[] = {
3317 AC97_DOUBLE("Side Playback Switch", AC97_CM9780_SIDE
, 15, 7, 1, 1),
3318 AC97_DOUBLE("Side Playback Volume", AC97_CM9780_SIDE
, 8, 0, 31, 0),
3319 AC97_ENUM("Side Playback Route", cm9780_ch_select_enum
),
3322 static int patch_cm9780_specific(struct snd_ac97
*ac97
)
3324 return patch_build_controls(ac97
, cm9780_controls
, ARRAY_SIZE(cm9780_controls
));
3327 static struct snd_ac97_build_ops patch_cm9780_ops
= {
3328 .build_specific
= patch_cm9780_specific
,
3329 .build_post_spdif
= patch_cm9761_post_spdif
/* identical with CM9761 */
3332 static int patch_cm9780(struct snd_ac97
*ac97
)
3336 ac97
->build_ops
= &patch_cm9780_ops
;
3339 if (ac97
->ext_id
& AC97_EI_SPDIF
) {
3340 ac97
->rates
[AC97_RATES_SPDIF
] = SNDRV_PCM_RATE_48000
; /* 48k only */
3341 val
= snd_ac97_read(ac97
, AC97_CM9780_SPDIF
);
3342 val
|= 0x1; /* SPDI_EN */
3343 snd_ac97_write_cache(ac97
, AC97_CM9780_SPDIF
, val
);
3352 static const struct snd_kcontrol_new snd_ac97_controls_vt1616
[] = {
3353 AC97_SINGLE("DC Offset removal", 0x5a, 10, 1, 0),
3354 AC97_SINGLE("Alternate Level to Surround Out", 0x5a, 15, 1, 0),
3355 AC97_SINGLE("Downmix LFE and Center to Front", 0x5a, 12, 1, 0),
3356 AC97_SINGLE("Downmix Surround to Front", 0x5a, 11, 1, 0),
3359 static const char *slave_vols_vt1616
[] = {
3360 "Front Playback Volume",
3361 "Surround Playback Volume",
3362 "Center Playback Volume",
3363 "LFE Playback Volume",
3367 static const char *slave_sws_vt1616
[] = {
3368 "Front Playback Switch",
3369 "Surround Playback Switch",
3370 "Center Playback Switch",
3371 "LFE Playback Switch",
3375 /* find a mixer control element with the given name */
3376 static struct snd_kcontrol
*snd_ac97_find_mixer_ctl(struct snd_ac97
*ac97
,
3379 struct snd_ctl_elem_id id
;
3380 memset(&id
, 0, sizeof(id
));
3381 id
.iface
= SNDRV_CTL_ELEM_IFACE_MIXER
;
3382 strcpy(id
.name
, name
);
3383 return snd_ctl_find_id(ac97
->bus
->card
, &id
);
3386 /* create a virtual master control and add slaves */
3387 static int snd_ac97_add_vmaster(struct snd_ac97
*ac97
, char *name
,
3388 const unsigned int *tlv
, const char **slaves
)
3390 struct snd_kcontrol
*kctl
;
3394 kctl
= snd_ctl_make_virtual_master(name
, tlv
);
3397 err
= snd_ctl_add(ac97
->bus
->card
, kctl
);
3401 for (s
= slaves
; *s
; s
++) {
3402 struct snd_kcontrol
*sctl
;
3404 sctl
= snd_ac97_find_mixer_ctl(ac97
, *s
);
3406 snd_printdd("Cannot find slave %s, skipped\n", *s
);
3409 err
= snd_ctl_add_slave(kctl
, sctl
);
3416 static int patch_vt1616_specific(struct snd_ac97
* ac97
)
3418 struct snd_kcontrol
*kctl
;
3421 if (snd_ac97_try_bit(ac97
, 0x5a, 9))
3422 if ((err
= patch_build_controls(ac97
, &snd_ac97_controls_vt1616
[0], 1)) < 0)
3424 if ((err
= patch_build_controls(ac97
, &snd_ac97_controls_vt1616
[1], ARRAY_SIZE(snd_ac97_controls_vt1616
) - 1)) < 0)
3427 /* There is already a misnamed master switch. Rename it. */
3428 kctl
= snd_ac97_find_mixer_ctl(ac97
, "Master Playback Volume");
3432 snd_ac97_rename_vol_ctl(ac97
, "Master Playback", "Front Playback");
3434 err
= snd_ac97_add_vmaster(ac97
, "Master Playback Volume",
3435 kctl
->tlv
.p
, slave_vols_vt1616
);
3439 err
= snd_ac97_add_vmaster(ac97
, "Master Playback Switch",
3440 NULL
, slave_sws_vt1616
);
3447 static struct snd_ac97_build_ops patch_vt1616_ops
= {
3448 .build_specific
= patch_vt1616_specific
3451 static int patch_vt1616(struct snd_ac97
* ac97
)
3453 ac97
->build_ops
= &patch_vt1616_ops
;
3462 * unfortunately, the vt1617a stashes the twiddlers required for
3463 * noodling the i/o jacks on 2 different regs. that means that we can't
3464 * use the easy way provided by AC97_ENUM_DOUBLE() we have to write
3467 * NB: this is absolutely and utterly different from the vt1618. dunno
3471 /* copied from ac97_surround_jack_mode_info() */
3472 static int snd_ac97_vt1617a_smart51_info(struct snd_kcontrol
*kcontrol
,
3473 struct snd_ctl_elem_info
*uinfo
)
3475 /* ordering in this list reflects vt1617a docs for Reg 20 and
3476 * 7a and Table 6 that lays out the matrix NB WRT Table6: SM51
3477 * is SM51EN *AND* it's Bit14, not Bit15 so the table is very
3478 * counter-intuitive */
3480 static const char* texts
[] = { "LineIn Mic1", "LineIn Mic1 Mic3",
3481 "Surr LFE/C Mic3", "LineIn LFE/C Mic3",
3482 "LineIn Mic2", "LineIn Mic2 Mic1",
3483 "Surr LFE Mic1", "Surr LFE Mic1 Mic2"};
3484 return ac97_enum_text_info(kcontrol
, uinfo
, texts
, 8);
3487 static int snd_ac97_vt1617a_smart51_get(struct snd_kcontrol
*kcontrol
,
3488 struct snd_ctl_elem_value
*ucontrol
)
3490 ushort usSM51
, usMS
;
3492 struct snd_ac97
*pac97
;
3494 pac97
= snd_kcontrol_chip(kcontrol
); /* grab codec handle */
3496 /* grab our desired bits, then mash them together in a manner
3497 * consistent with Table 6 on page 17 in the 1617a docs */
3499 usSM51
= snd_ac97_read(pac97
, 0x7a) >> 14;
3500 usMS
= snd_ac97_read(pac97
, 0x20) >> 8;
3502 ucontrol
->value
.enumerated
.item
[0] = (usSM51
<< 1) + usMS
;
3507 static int snd_ac97_vt1617a_smart51_put(struct snd_kcontrol
*kcontrol
,
3508 struct snd_ctl_elem_value
*ucontrol
)
3510 ushort usSM51
, usMS
, usReg
;
3512 struct snd_ac97
*pac97
;
3514 pac97
= snd_kcontrol_chip(kcontrol
); /* grab codec handle */
3516 usSM51
= ucontrol
->value
.enumerated
.item
[0] >> 1;
3517 usMS
= ucontrol
->value
.enumerated
.item
[0] & 1;
3519 /* push our values into the register - consider that things will be left
3520 * in a funky state if the write fails */
3522 usReg
= snd_ac97_read(pac97
, 0x7a);
3523 snd_ac97_write_cache(pac97
, 0x7a, (usReg
& 0x3FFF) + (usSM51
<< 14));
3524 usReg
= snd_ac97_read(pac97
, 0x20);
3525 snd_ac97_write_cache(pac97
, 0x20, (usReg
& 0xFEFF) + (usMS
<< 8));
3530 static const struct snd_kcontrol_new snd_ac97_controls_vt1617a
[] = {
3532 AC97_SINGLE("Center/LFE Exchange", 0x5a, 8, 1, 0),
3534 * These are used to enable/disable surround sound on motherboards
3535 * that have 3 bidirectional analog jacks
3538 .iface
= SNDRV_CTL_ELEM_IFACE_MIXER
,
3539 .name
= "Smart 5.1 Select",
3540 .info
= snd_ac97_vt1617a_smart51_info
,
3541 .get
= snd_ac97_vt1617a_smart51_get
,
3542 .put
= snd_ac97_vt1617a_smart51_put
,
3546 static int patch_vt1617a(struct snd_ac97
* ac97
)
3551 /* we choose to not fail out at this point, but we tell the
3552 caller when we return */
3554 err
= patch_build_controls(ac97
, &snd_ac97_controls_vt1617a
[0],
3555 ARRAY_SIZE(snd_ac97_controls_vt1617a
));
3557 /* bring analog power consumption to normal by turning off the
3558 * headphone amplifier, like WinXP driver for EPIA SP
3560 /* We need to check the bit before writing it.
3561 * On some (many?) hardwares, setting bit actually clears it!
3563 val
= snd_ac97_read(ac97
, 0x5c);
3565 snd_ac97_write_cache(ac97
, 0x5c, 0x20);
3567 ac97
->ext_id
|= AC97_EI_SPDIF
; /* force the detection of spdif */
3568 ac97
->rates
[AC97_RATES_SPDIF
] = SNDRV_PCM_RATE_44100
| SNDRV_PCM_RATE_48000
;
3569 ac97
->build_ops
= &patch_vt1616_ops
;
3574 /* VIA VT1618 8 CHANNEL AC97 CODEC
3576 * VIA implements 'Smart 5.1' completely differently on the 1618 than
3577 * it does on the 1617a. awesome! They seem to have sourced this
3578 * particular revision of the technology from somebody else, it's
3579 * called Universal Audio Jack and it shows up on some other folk's chips
3582 * ordering in this list reflects vt1618 docs for Reg 60h and
3583 * the block diagram, DACs are as follows:
3586 * OUT_1 -> Surround,
3589 * Unlike the 1617a, each OUT has a consistent set of mappings
3590 * for all bitpatterns other than 00:
3596 * Special Case of 00:
3598 * OUT_0 Mixed Output
3602 * I have no idea what the hell Reserved does, but on an MSI
3603 * CN700T, i have to set it to get 5.1 output - YMMV, bad
3606 * If other chips use Universal Audio Jack, then this code might be applicable
3610 struct vt1618_uaj_item
{
3611 unsigned short mask
;
3612 unsigned short shift
;
3613 const char *items
[4];
3616 /* This list reflects the vt1618 docs for Vendor Defined Register 0x60. */
3618 static struct vt1618_uaj_item vt1618_uaj
[3] = {
3624 "Speaker Out", "DAC Unmixed Out", "Line In", "Mic In"
3632 "Surround Out", "DAC Unmixed Out", "Line In", "Mic In"
3640 "Center LFE Out", "DAC Unmixed Out", "Line In", "Mic In"
3645 static int snd_ac97_vt1618_UAJ_info(struct snd_kcontrol
*kcontrol
,
3646 struct snd_ctl_elem_info
*uinfo
)
3648 return ac97_enum_text_info(kcontrol
, uinfo
,
3649 vt1618_uaj
[kcontrol
->private_value
].items
,
3653 /* All of the vt1618 Universal Audio Jack twiddlers are on
3654 * Vendor Defined Register 0x60, page 0. The bits, and thus
3655 * the mask, are the only thing that changes
3657 static int snd_ac97_vt1618_UAJ_get(struct snd_kcontrol
*kcontrol
,
3658 struct snd_ctl_elem_value
*ucontrol
)
3660 unsigned short datpag
, uaj
;
3661 struct snd_ac97
*pac97
= snd_kcontrol_chip(kcontrol
);
3663 mutex_lock(&pac97
->page_mutex
);
3665 datpag
= snd_ac97_read(pac97
, AC97_INT_PAGING
) & AC97_PAGE_MASK
;
3666 snd_ac97_update_bits(pac97
, AC97_INT_PAGING
, AC97_PAGE_MASK
, 0);
3668 uaj
= snd_ac97_read(pac97
, 0x60) &
3669 vt1618_uaj
[kcontrol
->private_value
].mask
;
3671 snd_ac97_update_bits(pac97
, AC97_INT_PAGING
, AC97_PAGE_MASK
, datpag
);
3672 mutex_unlock(&pac97
->page_mutex
);
3674 ucontrol
->value
.enumerated
.item
[0] = uaj
>>
3675 vt1618_uaj
[kcontrol
->private_value
].shift
;
3680 static int snd_ac97_vt1618_UAJ_put(struct snd_kcontrol
*kcontrol
,
3681 struct snd_ctl_elem_value
*ucontrol
)
3683 return ac97_update_bits_page(snd_kcontrol_chip(kcontrol
), 0x60,
3684 vt1618_uaj
[kcontrol
->private_value
].mask
,
3685 ucontrol
->value
.enumerated
.item
[0]<<
3686 vt1618_uaj
[kcontrol
->private_value
].shift
,
3690 /* config aux in jack - not found on 3 jack motherboards or soundcards */
3692 static int snd_ac97_vt1618_aux_info(struct snd_kcontrol
*kcontrol
,
3693 struct snd_ctl_elem_info
*uinfo
)
3695 static const char *txt_aux
[] = {"Aux In", "Back Surr Out"};
3697 return ac97_enum_text_info(kcontrol
, uinfo
, txt_aux
, 2);
3700 static int snd_ac97_vt1618_aux_get(struct snd_kcontrol
*kcontrol
,
3701 struct snd_ctl_elem_value
*ucontrol
)
3703 ucontrol
->value
.enumerated
.item
[0] =
3704 (snd_ac97_read(snd_kcontrol_chip(kcontrol
), 0x5c) & 0x0008)>>3;
3708 static int snd_ac97_vt1618_aux_put(struct snd_kcontrol
*kcontrol
,
3709 struct snd_ctl_elem_value
*ucontrol
)
3711 /* toggle surround rear dac power */
3713 snd_ac97_update_bits(snd_kcontrol_chip(kcontrol
), 0x5c, 0x0008,
3714 ucontrol
->value
.enumerated
.item
[0] << 3);
3716 /* toggle aux in surround rear out jack */
3718 return snd_ac97_update_bits(snd_kcontrol_chip(kcontrol
), 0x76, 0x0008,
3719 ucontrol
->value
.enumerated
.item
[0] << 3);
3722 static const struct snd_kcontrol_new snd_ac97_controls_vt1618
[] = {
3723 AC97_SINGLE("Exchange Center/LFE", 0x5a, 8, 1, 0),
3724 AC97_SINGLE("DC Offset", 0x5a, 10, 1, 0),
3725 AC97_SINGLE("Soft Mute", 0x5c, 0, 1, 1),
3726 AC97_SINGLE("Headphone Amp", 0x5c, 5, 1, 1),
3727 AC97_DOUBLE("Back Surr Volume", 0x5e, 8, 0, 31, 1),
3728 AC97_SINGLE("Back Surr Switch", 0x5e, 15, 1, 1),
3730 .iface
= SNDRV_CTL_ELEM_IFACE_MIXER
,
3731 .name
= "Speaker Jack Mode",
3732 .info
= snd_ac97_vt1618_UAJ_info
,
3733 .get
= snd_ac97_vt1618_UAJ_get
,
3734 .put
= snd_ac97_vt1618_UAJ_put
,
3738 .iface
= SNDRV_CTL_ELEM_IFACE_MIXER
,
3739 .name
= "Line Jack Mode",
3740 .info
= snd_ac97_vt1618_UAJ_info
,
3741 .get
= snd_ac97_vt1618_UAJ_get
,
3742 .put
= snd_ac97_vt1618_UAJ_put
,
3746 .iface
= SNDRV_CTL_ELEM_IFACE_MIXER
,
3747 .name
= "Mic Jack Mode",
3748 .info
= snd_ac97_vt1618_UAJ_info
,
3749 .get
= snd_ac97_vt1618_UAJ_get
,
3750 .put
= snd_ac97_vt1618_UAJ_put
,
3754 .iface
= SNDRV_CTL_ELEM_IFACE_MIXER
,
3755 .name
= "Aux Jack Mode",
3756 .info
= snd_ac97_vt1618_aux_info
,
3757 .get
= snd_ac97_vt1618_aux_get
,
3758 .put
= snd_ac97_vt1618_aux_put
,
3762 static int patch_vt1618(struct snd_ac97
*ac97
)
3764 return patch_build_controls(ac97
, snd_ac97_controls_vt1618
,
3765 ARRAY_SIZE(snd_ac97_controls_vt1618
));
3770 static void it2646_update_jacks(struct snd_ac97
*ac97
)
3772 /* shared Line-In / Surround Out */
3773 snd_ac97_update_bits(ac97
, 0x76, 1 << 9,
3774 is_shared_surrout(ac97
) ? (1<<9) : 0);
3775 /* shared Mic / Center/LFE Out */
3776 snd_ac97_update_bits(ac97
, 0x76, 1 << 10,
3777 is_shared_clfeout(ac97
) ? (1<<10) : 0);
3780 static const struct snd_kcontrol_new snd_ac97_controls_it2646
[] = {
3781 AC97_SURROUND_JACK_MODE_CTL
,
3782 AC97_CHANNEL_MODE_CTL
,
3785 static const struct snd_kcontrol_new snd_ac97_spdif_controls_it2646
[] = {
3786 AC97_SINGLE(SNDRV_CTL_NAME_IEC958("",CAPTURE
,SWITCH
), 0x76, 11, 1, 0),
3787 AC97_SINGLE("Analog to IEC958 Output", 0x76, 12, 1, 0),
3788 AC97_SINGLE("IEC958 Input Monitor", 0x76, 13, 1, 0),
3791 static int patch_it2646_specific(struct snd_ac97
* ac97
)
3794 if ((err
= patch_build_controls(ac97
, snd_ac97_controls_it2646
, ARRAY_SIZE(snd_ac97_controls_it2646
))) < 0)
3796 if ((err
= patch_build_controls(ac97
, snd_ac97_spdif_controls_it2646
, ARRAY_SIZE(snd_ac97_spdif_controls_it2646
))) < 0)
3801 static struct snd_ac97_build_ops patch_it2646_ops
= {
3802 .build_specific
= patch_it2646_specific
,
3803 .update_jacks
= it2646_update_jacks
3806 static int patch_it2646(struct snd_ac97
* ac97
)
3808 ac97
->build_ops
= &patch_it2646_ops
;
3809 /* full DAC volume */
3810 snd_ac97_write_cache(ac97
, 0x5E, 0x0808);
3811 snd_ac97_write_cache(ac97
, 0x7A, 0x0808);
3819 #define AC97_SI3036_CHIP_ID 0x5a
3820 #define AC97_SI3036_LINE_CFG 0x5c
3822 static const struct snd_kcontrol_new snd_ac97_controls_si3036
[] = {
3823 AC97_DOUBLE("Modem Speaker Volume", 0x5c, 14, 12, 3, 1)
3826 static int patch_si3036_specific(struct snd_ac97
* ac97
)
3829 for (idx
= 0; idx
< ARRAY_SIZE(snd_ac97_controls_si3036
); idx
++)
3830 if ((err
= snd_ctl_add(ac97
->bus
->card
, snd_ctl_new1(&snd_ac97_controls_si3036
[idx
], ac97
))) < 0)
3835 static struct snd_ac97_build_ops patch_si3036_ops
= {
3836 .build_specific
= patch_si3036_specific
,
3839 static int mpatch_si3036(struct snd_ac97
* ac97
)
3841 ac97
->build_ops
= &patch_si3036_ops
;
3842 snd_ac97_write_cache(ac97
, 0x5c, 0xf210 );
3843 snd_ac97_write_cache(ac97
, 0x68, 0);
3850 * We use a static resolution table since LM4550 codec cannot be
3851 * properly autoprobed to determine the resolution via
3852 * check_volume_resolution().
3855 static struct snd_ac97_res_table lm4550_restbl
[] = {
3856 { AC97_MASTER
, 0x1f1f },
3857 { AC97_HEADPHONE
, 0x1f1f },
3858 { AC97_MASTER_MONO
, 0x001f },
3859 { AC97_PC_BEEP
, 0x001f }, /* LSB is ignored */
3860 { AC97_PHONE
, 0x001f },
3861 { AC97_MIC
, 0x001f },
3862 { AC97_LINE
, 0x1f1f },
3863 { AC97_CD
, 0x1f1f },
3864 { AC97_VIDEO
, 0x1f1f },
3865 { AC97_AUX
, 0x1f1f },
3866 { AC97_PCM
, 0x1f1f },
3867 { AC97_REC_GAIN
, 0x0f0f },
3868 { } /* terminator */
3871 static int patch_lm4550(struct snd_ac97
*ac97
)
3873 ac97
->res_table
= lm4550_restbl
;
3878 * UCB1400 codec (http://www.semiconductors.philips.com/acrobat_download/datasheets/UCB1400-02.pdf)
3880 static const struct snd_kcontrol_new snd_ac97_controls_ucb1400
[] = {
3881 /* enable/disable headphone driver which allows direct connection to
3882 stereo headphone without the use of external DC blocking
3884 AC97_SINGLE("Headphone Driver", 0x6a, 6, 1, 0),
3885 /* Filter used to compensate the DC offset is added in the ADC to remove idle
3886 tones from the audio band. */
3887 AC97_SINGLE("DC Filter", 0x6a, 4, 1, 0),
3888 /* Control smart-low-power mode feature. Allows automatic power down
3889 of unused blocks in the ADC analog front end and the PLL. */
3890 AC97_SINGLE("Smart Low Power Mode", 0x6c, 4, 3, 0),
3893 static int patch_ucb1400_specific(struct snd_ac97
* ac97
)
3896 for (idx
= 0; idx
< ARRAY_SIZE(snd_ac97_controls_ucb1400
); idx
++)
3897 if ((err
= snd_ctl_add(ac97
->bus
->card
, snd_ctl_new1(&snd_ac97_controls_ucb1400
[idx
], ac97
))) < 0)
3902 static struct snd_ac97_build_ops patch_ucb1400_ops
= {
3903 .build_specific
= patch_ucb1400_specific
,
3906 static int patch_ucb1400(struct snd_ac97
* ac97
)
3908 ac97
->build_ops
= &patch_ucb1400_ops
;
3909 /* enable headphone driver and smart low power mode by default */
3910 snd_ac97_write_cache(ac97
, 0x6a, 0x0050);
3911 snd_ac97_write_cache(ac97
, 0x6c, 0x0030);