1 /*
2 * HD audio interface patch for AD1882, AD1884, AD1981HD, AD1983, AD1984,
3 * AD1986A, AD1988
4 *
5 * Copyright (c) 2005-2007 Takashi Iwai <tiwai@suse.de>
6 *
7 * This driver is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 2 of the License, or
10 * (at your option) any later version.
11 *
12 * This driver is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, write to the Free Software
19 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
20 */
21
22 #include <sound/driver.h>
23 #include <linux/init.h>
24 #include <linux/delay.h>
25 #include <linux/slab.h>
26 #include <linux/pci.h>
27
28 #include <sound/core.h>
29 #include "hda_codec.h"
30 #include "hda_local.h"
31 #include "hda_patch.h"
32
33 struct ad198x_spec {
34 struct snd_kcontrol_new *mixers[5];
35 int num_mixers;
36
37 const struct hda_verb *init_verbs[5]; /* initialization verbs
38 * don't forget NULL termination!
39 */
40 unsigned int num_init_verbs;
41
42 /* playback */
43 struct hda_multi_out multiout; /* playback set-up
44 * max_channels, dacs must be set
45 * dig_out_nid and hp_nid are optional
46 */
47 unsigned int cur_eapd;
48 unsigned int need_dac_fix;
49
50 /* capture */
51 unsigned int num_adc_nids;
52 hda_nid_t *adc_nids;
53 hda_nid_t dig_in_nid; /* digital-in NID; optional */
54
55 /* capture source */
56 const struct hda_input_mux *input_mux;
57 hda_nid_t *capsrc_nids;
58 unsigned int cur_mux[3];
59
60 /* channel model */
61 const struct hda_channel_mode *channel_mode;
62 int num_channel_mode;
63
64 /* PCM information */
65 struct hda_pcm pcm_rec[3]; /* used in alc_build_pcms() */
66
67 unsigned int spdif_route;
68
69 /* dynamic controls, init_verbs and input_mux */
70 struct auto_pin_cfg autocfg;
71 unsigned int num_kctl_alloc, num_kctl_used;
72 struct snd_kcontrol_new *kctl_alloc;
73 struct hda_input_mux private_imux;
74 hda_nid_t private_dac_nids[AUTO_CFG_MAX_OUTS];
75
76 unsigned int jack_present :1;
77
78 #ifdef CONFIG_SND_HDA_POWER_SAVE
79 struct hda_loopback_check loopback;
80 #endif
81 /* for virtual master */
82 hda_nid_t vmaster_nid;
83 const char **slave_vols;
84 const char **slave_sws;
85 };
86
87 /*
88 * input MUX handling (common part)
89 */
90 static int ad198x_mux_enum_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo)
91 {
92 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
93 struct ad198x_spec *spec = codec->spec;
94
95 return snd_hda_input_mux_info(spec->input_mux, uinfo);
96 }
97
98 static int ad198x_mux_enum_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
99 {
100 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
101 struct ad198x_spec *spec = codec->spec;
102 unsigned int adc_idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);
103
104 ucontrol->value.enumerated.item[0] = spec->cur_mux[adc_idx];
105 return 0;
106 }
107
108 static int ad198x_mux_enum_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
109 {
110 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
111 struct ad198x_spec *spec = codec->spec;
112 unsigned int adc_idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);
113
114 return snd_hda_input_mux_put(codec, spec->input_mux, ucontrol,
115 spec->capsrc_nids[adc_idx],
116 &spec->cur_mux[adc_idx]);
117 }
118
119 /*
120 * initialization (common callbacks)
121 */
122 static int ad198x_init(struct hda_codec *codec)
123 {
124 struct ad198x_spec *spec = codec->spec;
125 int i;
126
127 for (i = 0; i < spec->num_init_verbs; i++)
128 snd_hda_sequence_write(codec, spec->init_verbs[i]);
129 return 0;
130 }
131
132 static const char *ad_slave_vols[] = {
133 "Front Playback Volume",
134 "Surround Playback Volume",
135 "Center Playback Volume",
136 "LFE Playback Volume",
137 "Side Playback Volume",
138 "Headphone Playback Volume",
139 "Mono Playback Volume",
140 "Speaker Playback Volume",
141 "IEC958 Playback Volume",
142 NULL
143 };
144
145 static const char *ad_slave_sws[] = {
146 "Front Playback Switch",
147 "Surround Playback Switch",
148 "Center Playback Switch",
149 "LFE Playback Switch",
150 "Side Playback Switch",
151 "Headphone Playback Switch",
152 "Mono Playback Switch",
153 "Speaker Playback Switch",
154 "IEC958 Playback Switch",
155 NULL
156 };
157
158 static int ad198x_build_controls(struct hda_codec *codec)
159 {
160 struct ad198x_spec *spec = codec->spec;
161 unsigned int i;
162 int err;
163
164 for (i = 0; i < spec->num_mixers; i++) {
165 err = snd_hda_add_new_ctls(codec, spec->mixers[i]);
166 if (err < 0)
167 return err;
168 }
169 if (spec->multiout.dig_out_nid) {
170 err = snd_hda_create_spdif_out_ctls(codec, spec->multiout.dig_out_nid);
171 if (err < 0)
172 return err;
173 err = snd_hda_create_spdif_share_sw(codec,
174 &spec->multiout);
175 if (err < 0)
176 return err;
177 spec->multiout.share_spdif = 1;
178 }
179 if (spec->dig_in_nid) {
180 err = snd_hda_create_spdif_in_ctls(codec, spec->dig_in_nid);
181 if (err < 0)
182 return err;
183 }
184
185 /* if we have no master control, let's create it */
186 if (!snd_hda_find_mixer_ctl(codec, "Master Playback Volume")) {
187 unsigned int vmaster_tlv[4];
188 snd_hda_set_vmaster_tlv(codec, spec->vmaster_nid,
189 HDA_OUTPUT, vmaster_tlv);
190 err = snd_hda_add_vmaster(codec, "Master Playback Volume",
191 vmaster_tlv,
192 (spec->slave_vols ?
193 spec->slave_vols : ad_slave_vols));
194 if (err < 0)
195 return err;
196 }
197 if (!snd_hda_find_mixer_ctl(codec, "Master Playback Switch")) {
198 err = snd_hda_add_vmaster(codec, "Master Playback Switch",
199 NULL,
200 (spec->slave_sws ?
201 spec->slave_sws : ad_slave_sws));
202 if (err < 0)
203 return err;
204 }
205
206 return 0;
207 }
208
209 #ifdef CONFIG_SND_HDA_POWER_SAVE
210 static int ad198x_check_power_status(struct hda_codec *codec, hda_nid_t nid)
211 {
212 struct ad198x_spec *spec = codec->spec;
213 return snd_hda_check_amp_list_power(codec, &spec->loopback, nid);
214 }
215 #endif
216
217 /*
218 * Analog playback callbacks
219 */
220 static int ad198x_playback_pcm_open(struct hda_pcm_stream *hinfo,
221 struct hda_codec *codec,
222 struct snd_pcm_substream *substream)
223 {
224 struct ad198x_spec *spec = codec->spec;
225 return snd_hda_multi_out_analog_open(codec, &spec->multiout, substream,
226 hinfo);
227 }
228
229 static int ad198x_playback_pcm_prepare(struct hda_pcm_stream *hinfo,
230 struct hda_codec *codec,
231 unsigned int stream_tag,
232 unsigned int format,
233 struct snd_pcm_substream *substream)
234 {
235 struct ad198x_spec *spec = codec->spec;
236 return snd_hda_multi_out_analog_prepare(codec, &spec->multiout, stream_tag,
237 format, substream);
238 }
239
240 static int ad198x_playback_pcm_cleanup(struct hda_pcm_stream *hinfo,
241 struct hda_codec *codec,
242 struct snd_pcm_substream *substream)
243 {
244 struct ad198x_spec *spec = codec->spec;
245 return snd_hda_multi_out_analog_cleanup(codec, &spec->multiout);
246 }
247
248 /*
249 * Digital out
250 */
251 static int ad198x_dig_playback_pcm_open(struct hda_pcm_stream *hinfo,
252 struct hda_codec *codec,
253 struct snd_pcm_substream *substream)
254 {
255 struct ad198x_spec *spec = codec->spec;
256 return snd_hda_multi_out_dig_open(codec, &spec->multiout);
257 }
258
259 static int ad198x_dig_playback_pcm_close(struct hda_pcm_stream *hinfo,
260 struct hda_codec *codec,
261 struct snd_pcm_substream *substream)
262 {
263 struct ad198x_spec *spec = codec->spec;
264 return snd_hda_multi_out_dig_close(codec, &spec->multiout);
265 }
266
267 static int ad198x_dig_playback_pcm_prepare(struct hda_pcm_stream *hinfo,
268 struct hda_codec *codec,
269 unsigned int stream_tag,
270 unsigned int format,
271 struct snd_pcm_substream *substream)
272 {
273 struct ad198x_spec *spec = codec->spec;
274 return snd_hda_multi_out_dig_prepare(codec, &spec->multiout, stream_tag,
275 format, substream);
276 }
277
278 /*
279 * Analog capture
280 */
281 static int ad198x_capture_pcm_prepare(struct hda_pcm_stream *hinfo,
282 struct hda_codec *codec,
283 unsigned int stream_tag,
284 unsigned int format,
285 struct snd_pcm_substream *substream)
286 {
287 struct ad198x_spec *spec = codec->spec;
288 snd_hda_codec_setup_stream(codec, spec->adc_nids[substream->number],
289 stream_tag, 0, format);
290 return 0;
291 }
292
293 static int ad198x_capture_pcm_cleanup(struct hda_pcm_stream *hinfo,
294 struct hda_codec *codec,
295 struct snd_pcm_substream *substream)
296 {
297 struct ad198x_spec *spec = codec->spec;
298 snd_hda_codec_cleanup_stream(codec, spec->adc_nids[substream->number]);
299 return 0;
300 }
301
302
303 /*
304 */
305 static struct hda_pcm_stream ad198x_pcm_analog_playback = {
306 .substreams = 1,
307 .channels_min = 2,
308 .channels_max = 6, /* changed later */
309 .nid = 0, /* fill later */
310 .ops = {
311 .open = ad198x_playback_pcm_open,
312 .prepare = ad198x_playback_pcm_prepare,
313 .cleanup = ad198x_playback_pcm_cleanup
314 },
315 };
316
317 static struct hda_pcm_stream ad198x_pcm_analog_capture = {
318 .substreams = 1,
319 .channels_min = 2,
320 .channels_max = 2,
321 .nid = 0, /* fill later */
322 .ops = {
323 .prepare = ad198x_capture_pcm_prepare,
324 .cleanup = ad198x_capture_pcm_cleanup
325 },
326 };
327
328 static struct hda_pcm_stream ad198x_pcm_digital_playback = {
329 .substreams = 1,
330 .channels_min = 2,
331 .channels_max = 2,
332 .nid = 0, /* fill later */
333 .ops = {
334 .open = ad198x_dig_playback_pcm_open,
335 .close = ad198x_dig_playback_pcm_close,
336 .prepare = ad198x_dig_playback_pcm_prepare
337 },
338 };
339
340 static struct hda_pcm_stream ad198x_pcm_digital_capture = {
341 .substreams = 1,
342 .channels_min = 2,
343 .channels_max = 2,
344 /* NID is set in alc_build_pcms */
345 };
346
347 static int ad198x_build_pcms(struct hda_codec *codec)
348 {
349 struct ad198x_spec *spec = codec->spec;
350 struct hda_pcm *info = spec->pcm_rec;
351
352 codec->num_pcms = 1;
353 codec->pcm_info = info;
354
355 info->name = "AD198x Analog";
356 info->stream[SNDRV_PCM_STREAM_PLAYBACK] = ad198x_pcm_analog_playback;
357 info->stream[SNDRV_PCM_STREAM_PLAYBACK].channels_max = spec->multiout.max_channels;
358 info->stream[SNDRV_PCM_STREAM_PLAYBACK].nid = spec->multiout.dac_nids[0];
359 info->stream[SNDRV_PCM_STREAM_CAPTURE] = ad198x_pcm_analog_capture;
360 info->stream[SNDRV_PCM_STREAM_CAPTURE].substreams = spec->num_adc_nids;
361 info->stream[SNDRV_PCM_STREAM_CAPTURE].nid = spec->adc_nids[0];
362
363 if (spec->multiout.dig_out_nid) {
364 info++;
365 codec->num_pcms++;
366 info->name = "AD198x Digital";
367 info->pcm_type = HDA_PCM_TYPE_SPDIF;
368 info->stream[SNDRV_PCM_STREAM_PLAYBACK] = ad198x_pcm_digital_playback;
369 info->stream[SNDRV_PCM_STREAM_PLAYBACK].nid = spec->multiout.dig_out_nid;
370 if (spec->dig_in_nid) {
371 info->stream[SNDRV_PCM_STREAM_CAPTURE] = ad198x_pcm_digital_capture;
372 info->stream[SNDRV_PCM_STREAM_CAPTURE].nid = spec->dig_in_nid;
373 }
374 }
375
376 return 0;
377 }
378
379 static void ad198x_free(struct hda_codec *codec)
380 {
381 struct ad198x_spec *spec = codec->spec;
382 unsigned int i;
383
384 if (spec->kctl_alloc) {
385 for (i = 0; i < spec->num_kctl_used; i++)
386 kfree(spec->kctl_alloc[i].name);
387 kfree(spec->kctl_alloc);
388 }
389 kfree(codec->spec);
390 }
391
392 static struct hda_codec_ops ad198x_patch_ops = {
393 .build_controls = ad198x_build_controls,
394 .build_pcms = ad198x_build_pcms,
395 .init = ad198x_init,
396 .free = ad198x_free,
397 #ifdef CONFIG_SND_HDA_POWER_SAVE
398 .check_power_status = ad198x_check_power_status,
399 #endif
400 };
401
402
403 /*
404 * EAPD control
405 * the private value = nid | (invert << 8)
406 */
407 #define ad198x_eapd_info snd_ctl_boolean_mono_info
408
409 static int ad198x_eapd_get(struct snd_kcontrol *kcontrol,
410 struct snd_ctl_elem_value *ucontrol)
411 {
412 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
413 struct ad198x_spec *spec = codec->spec;
414 int invert = (kcontrol->private_value >> 8) & 1;
415 if (invert)
416 ucontrol->value.integer.value[0] = ! spec->cur_eapd;
417 else
418 ucontrol->value.integer.value[0] = spec->cur_eapd;
419 return 0;
420 }
421
422 static int ad198x_eapd_put(struct snd_kcontrol *kcontrol,
423 struct snd_ctl_elem_value *ucontrol)
424 {
425 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
426 struct ad198x_spec *spec = codec->spec;
427 int invert = (kcontrol->private_value >> 8) & 1;
428 hda_nid_t nid = kcontrol->private_value & 0xff;
429 unsigned int eapd;
430 eapd = !!ucontrol->value.integer.value[0];
431 if (invert)
432 eapd = !eapd;
433 if (eapd == spec->cur_eapd)
434 return 0;
435 spec->cur_eapd = eapd;
436 snd_hda_codec_write_cache(codec, nid,
437 0, AC_VERB_SET_EAPD_BTLENABLE,
438 eapd ? 0x02 : 0x00);
439 return 1;
440 }
441
442 static int ad198x_ch_mode_info(struct snd_kcontrol *kcontrol,
443 struct snd_ctl_elem_info *uinfo);
444 static int ad198x_ch_mode_get(struct snd_kcontrol *kcontrol,
445 struct snd_ctl_elem_value *ucontrol);
446 static int ad198x_ch_mode_put(struct snd_kcontrol *kcontrol,
447 struct snd_ctl_elem_value *ucontrol);
448
449
450 /*
451 * AD1986A specific
452 */
453
454 #define AD1986A_SPDIF_OUT 0x02
455 #define AD1986A_FRONT_DAC 0x03
456 #define AD1986A_SURR_DAC 0x04
457 #define AD1986A_CLFE_DAC 0x05
458 #define AD1986A_ADC 0x06
459
460 static hda_nid_t ad1986a_dac_nids[3] = {
461 AD1986A_FRONT_DAC, AD1986A_SURR_DAC, AD1986A_CLFE_DAC
462 };
463 static hda_nid_t ad1986a_adc_nids[1] = { AD1986A_ADC };
464 static hda_nid_t ad1986a_capsrc_nids[1] = { 0x12 };
465
466 static struct hda_input_mux ad1986a_capture_source = {
467 .num_items = 7,
468 .items = {
469 { "Mic", 0x0 },
470 { "CD", 0x1 },
471 { "Aux", 0x3 },
472 { "Line", 0x4 },
473 { "Mix", 0x5 },
474 { "Mono", 0x6 },
475 { "Phone", 0x7 },
476 },
477 };
478
479
480 static struct hda_bind_ctls ad1986a_bind_pcm_vol = {
481 .ops = &snd_hda_bind_vol,
482 .values = {
483 HDA_COMPOSE_AMP_VAL(AD1986A_FRONT_DAC, 3, 0, HDA_OUTPUT),
484 HDA_COMPOSE_AMP_VAL(AD1986A_SURR_DAC, 3, 0, HDA_OUTPUT),
485 HDA_COMPOSE_AMP_VAL(AD1986A_CLFE_DAC, 3, 0, HDA_OUTPUT),
486 0
487 },
488 };
489
490 static struct hda_bind_ctls ad1986a_bind_pcm_sw = {
491 .ops = &snd_hda_bind_sw,
492 .values = {
493 HDA_COMPOSE_AMP_VAL(AD1986A_FRONT_DAC, 3, 0, HDA_OUTPUT),
494 HDA_COMPOSE_AMP_VAL(AD1986A_SURR_DAC, 3, 0, HDA_OUTPUT),
495 HDA_COMPOSE_AMP_VAL(AD1986A_CLFE_DAC, 3, 0, HDA_OUTPUT),
496 0
497 },
498 };
499
500 /*
501 * mixers
502 */
503 static struct snd_kcontrol_new ad1986a_mixers[] = {
504 /*
505 * bind volumes/mutes of 3 DACs as a single PCM control for simplicity
506 */
507 HDA_BIND_VOL("PCM Playback Volume", &ad1986a_bind_pcm_vol),
508 HDA_BIND_SW("PCM Playback Switch", &ad1986a_bind_pcm_sw),
509 HDA_CODEC_VOLUME("Front Playback Volume", 0x1b, 0x0, HDA_OUTPUT),
510 HDA_CODEC_MUTE("Front Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
511 HDA_CODEC_VOLUME("Surround Playback Volume", 0x1c, 0x0, HDA_OUTPUT),
512 HDA_CODEC_MUTE("Surround Playback Switch", 0x1c, 0x0, HDA_OUTPUT),
513 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x1d, 1, 0x0, HDA_OUTPUT),
514 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x1d, 2, 0x0, HDA_OUTPUT),
515 HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x1d, 1, 0x0, HDA_OUTPUT),
516 HDA_CODEC_MUTE_MONO("LFE Playback Switch", 0x1d, 2, 0x0, HDA_OUTPUT),
517 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x1a, 0x0, HDA_OUTPUT),
518 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1a, 0x0, HDA_OUTPUT),
519 HDA_CODEC_VOLUME("CD Playback Volume", 0x15, 0x0, HDA_OUTPUT),
520 HDA_CODEC_MUTE("CD Playback Switch", 0x15, 0x0, HDA_OUTPUT),
521 HDA_CODEC_VOLUME("Line Playback Volume", 0x17, 0x0, HDA_OUTPUT),
522 HDA_CODEC_MUTE("Line Playback Switch", 0x17, 0x0, HDA_OUTPUT),
523 HDA_CODEC_VOLUME("Aux Playback Volume", 0x16, 0x0, HDA_OUTPUT),
524 HDA_CODEC_MUTE("Aux Playback Switch", 0x16, 0x0, HDA_OUTPUT),
525 HDA_CODEC_VOLUME("Mic Playback Volume", 0x13, 0x0, HDA_OUTPUT),
526 HDA_CODEC_MUTE("Mic Playback Switch", 0x13, 0x0, HDA_OUTPUT),
527 HDA_CODEC_VOLUME("Mic Boost", 0x0f, 0x0, HDA_OUTPUT),
528 HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x18, 0x0, HDA_OUTPUT),
529 HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x18, 0x0, HDA_OUTPUT),
530 HDA_CODEC_VOLUME("Mono Playback Volume", 0x1e, 0x0, HDA_OUTPUT),
531 HDA_CODEC_MUTE("Mono Playback Switch", 0x1e, 0x0, HDA_OUTPUT),
532 HDA_CODEC_VOLUME("Capture Volume", 0x12, 0x0, HDA_OUTPUT),
533 HDA_CODEC_MUTE("Capture Switch", 0x12, 0x0, HDA_OUTPUT),
534 {
535 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
536 .name = "Capture Source",
537 .info = ad198x_mux_enum_info,
538 .get = ad198x_mux_enum_get,
539 .put = ad198x_mux_enum_put,
540 },
541 HDA_CODEC_MUTE("Stereo Downmix Switch", 0x09, 0x0, HDA_OUTPUT),
542 { } /* end */
543 };
544
545 /* additional mixers for 3stack mode */
546 static struct snd_kcontrol_new ad1986a_3st_mixers[] = {
547 {
548 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
549 .name = "Channel Mode",
550 .info = ad198x_ch_mode_info,
551 .get = ad198x_ch_mode_get,
552 .put = ad198x_ch_mode_put,
553 },
554 { } /* end */
555 };
556
557 /* laptop model - 2ch only */
558 static hda_nid_t ad1986a_laptop_dac_nids[1] = { AD1986A_FRONT_DAC };
559
560 /* master controls both pins 0x1a and 0x1b */
561 static struct hda_bind_ctls ad1986a_laptop_master_vol = {
562 .ops = &snd_hda_bind_vol,
563 .values = {
564 HDA_COMPOSE_AMP_VAL(0x1a, 3, 0, HDA_OUTPUT),
565 HDA_COMPOSE_AMP_VAL(0x1b, 3, 0, HDA_OUTPUT),
566 0,
567 },
568 };
569
570 static struct hda_bind_ctls ad1986a_laptop_master_sw = {
571 .ops = &snd_hda_bind_sw,
572 .values = {
573 HDA_COMPOSE_AMP_VAL(0x1a, 3, 0, HDA_OUTPUT),
574 HDA_COMPOSE_AMP_VAL(0x1b, 3, 0, HDA_OUTPUT),
575 0,
576 },
577 };
578
579 static struct snd_kcontrol_new ad1986a_laptop_mixers[] = {
580 HDA_CODEC_VOLUME("PCM Playback Volume", 0x03, 0x0, HDA_OUTPUT),
581 HDA_CODEC_MUTE("PCM Playback Switch", 0x03, 0x0, HDA_OUTPUT),
582 HDA_BIND_VOL("Master Playback Volume", &ad1986a_laptop_master_vol),
583 HDA_BIND_SW("Master Playback Switch", &ad1986a_laptop_master_sw),
584 HDA_CODEC_VOLUME("CD Playback Volume", 0x15, 0x0, HDA_OUTPUT),
585 HDA_CODEC_MUTE("CD Playback Switch", 0x15, 0x0, HDA_OUTPUT),
586 HDA_CODEC_VOLUME("Line Playback Volume", 0x17, 0x0, HDA_OUTPUT),
587 HDA_CODEC_MUTE("Line Playback Switch", 0x17, 0x0, HDA_OUTPUT),
588 HDA_CODEC_VOLUME("Aux Playback Volume", 0x16, 0x0, HDA_OUTPUT),
589 HDA_CODEC_MUTE("Aux Playback Switch", 0x16, 0x0, HDA_OUTPUT),
590 HDA_CODEC_VOLUME("Mic Playback Volume", 0x13, 0x0, HDA_OUTPUT),
591 HDA_CODEC_MUTE("Mic Playback Switch", 0x13, 0x0, HDA_OUTPUT),
592 HDA_CODEC_VOLUME("Mic Boost", 0x0f, 0x0, HDA_OUTPUT),
593 /* HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x18, 0x0, HDA_OUTPUT),
594 HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x18, 0x0, HDA_OUTPUT),
595 HDA_CODEC_VOLUME("Mono Playback Volume", 0x1e, 0x0, HDA_OUTPUT),
596 HDA_CODEC_MUTE("Mono Playback Switch", 0x1e, 0x0, HDA_OUTPUT), */
597 HDA_CODEC_VOLUME("Capture Volume", 0x12, 0x0, HDA_OUTPUT),
598 HDA_CODEC_MUTE("Capture Switch", 0x12, 0x0, HDA_OUTPUT),
599 {
600 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
601 .name = "Capture Source",
602 .info = ad198x_mux_enum_info,
603 .get = ad198x_mux_enum_get,
604 .put = ad198x_mux_enum_put,
605 },
606 { } /* end */
607 };
608
609 /* laptop-eapd model - 2ch only */
610
611 static struct hda_input_mux ad1986a_laptop_eapd_capture_source = {
612 .num_items = 3,
613 .items = {
614 { "Mic", 0x0 },
615 { "Internal Mic", 0x4 },
616 { "Mix", 0x5 },
617 },
618 };
619
620 static struct hda_input_mux ad1986a_automic_capture_source = {
621 .num_items = 2,
622 .items = {
623 { "Mic", 0x0 },
624 { "Mix", 0x5 },
625 },
626 };
627
628 static struct snd_kcontrol_new ad1986a_laptop_eapd_mixers[] = {
629 HDA_BIND_VOL("Master Playback Volume", &ad1986a_laptop_master_vol),
630 HDA_BIND_SW("Master Playback Switch", &ad1986a_laptop_master_sw),
631 HDA_CODEC_VOLUME("PCM Playback Volume", 0x03, 0x0, HDA_OUTPUT),
632 HDA_CODEC_MUTE("PCM Playback Switch", 0x03, 0x0, HDA_OUTPUT),
633 HDA_CODEC_VOLUME("Mic Playback Volume", 0x13, 0x0, HDA_OUTPUT),
634 HDA_CODEC_MUTE("Mic Playback Switch", 0x13, 0x0, HDA_OUTPUT),
635 HDA_CODEC_VOLUME("Mic Boost", 0x0f, 0x0, HDA_OUTPUT),
636 HDA_CODEC_VOLUME("Capture Volume", 0x12, 0x0, HDA_OUTPUT),
637 HDA_CODEC_MUTE("Capture Switch", 0x12, 0x0, HDA_OUTPUT),
638 {
639 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
640 .name = "Capture Source",
641 .info = ad198x_mux_enum_info,
642 .get = ad198x_mux_enum_get,
643 .put = ad198x_mux_enum_put,
644 },
645 {
646 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
647 .name = "External Amplifier",
648 .info = ad198x_eapd_info,
649 .get = ad198x_eapd_get,
650 .put = ad198x_eapd_put,
651 .private_value = 0x1b | (1 << 8), /* port-D, inversed */
652 },
653 { } /* end */
654 };
655
656 /* re-connect the mic boost input according to the jack sensing */
657 static void ad1986a_automic(struct hda_codec *codec)
658 {
659 unsigned int present;
660 present = snd_hda_codec_read(codec, 0x1f, 0, AC_VERB_GET_PIN_SENSE, 0);
661 /* 0 = 0x1f, 2 = 0x1d, 4 = mixed */
662 snd_hda_codec_write(codec, 0x0f, 0, AC_VERB_SET_CONNECT_SEL,
663 (present & AC_PINSENSE_PRESENCE) ? 0 : 2);
664 }
665
666 #define AD1986A_MIC_EVENT 0x36
667
668 static void ad1986a_automic_unsol_event(struct hda_codec *codec,
669 unsigned int res)
670 {
671 if ((res >> 26) != AD1986A_MIC_EVENT)
672 return;
673 ad1986a_automic(codec);
674 }
675
676 static int ad1986a_automic_init(struct hda_codec *codec)
677 {
678 ad198x_init(codec);
679 ad1986a_automic(codec);
680 return 0;
681 }
682
683 /* laptop-automute - 2ch only */
684
685 static void ad1986a_update_hp(struct hda_codec *codec)
686 {
687 struct ad198x_spec *spec = codec->spec;
688 unsigned int mute;
689
690 if (spec->jack_present)
691 mute = HDA_AMP_MUTE; /* mute internal speaker */
692 else
693 /* unmute internal speaker if necessary */
694 mute = snd_hda_codec_amp_read(codec, 0x1a, 0, HDA_OUTPUT, 0);
695 snd_hda_codec_amp_stereo(codec, 0x1b, HDA_OUTPUT, 0,
696 HDA_AMP_MUTE, mute);
697 }
698
699 static void ad1986a_hp_automute(struct hda_codec *codec)
700 {
701 struct ad198x_spec *spec = codec->spec;
702 unsigned int present;
703
704 present = snd_hda_codec_read(codec, 0x1a, 0, AC_VERB_GET_PIN_SENSE, 0);
705 /* Lenovo N100 seems to report the reversed bit for HP jack-sensing */
706 spec->jack_present = !(present & 0x80000000);
707 ad1986a_update_hp(codec);
708 }
709
710 #define AD1986A_HP_EVENT 0x37
711
712 static void ad1986a_hp_unsol_event(struct hda_codec *codec, unsigned int res)
713 {
714 if ((res >> 26) != AD1986A_HP_EVENT)
715 return;
716 ad1986a_hp_automute(codec);
717 }
718
719 static int ad1986a_hp_init(struct hda_codec *codec)
720 {
721 ad198x_init(codec);
722 ad1986a_hp_automute(codec);
723 return 0;
724 }
725
726 /* bind hp and internal speaker mute (with plug check) */
727 static int ad1986a_hp_master_sw_put(struct snd_kcontrol *kcontrol,
728 struct snd_ctl_elem_value *ucontrol)
729 {
730 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
731 long *valp = ucontrol->value.integer.value;
732 int change;
733
734 change = snd_hda_codec_amp_update(codec, 0x1a, 0, HDA_OUTPUT, 0,
735 HDA_AMP_MUTE,
736 valp[0] ? 0 : HDA_AMP_MUTE);
737 change |= snd_hda_codec_amp_update(codec, 0x1a, 1, HDA_OUTPUT, 0,
738 HDA_AMP_MUTE,
739 valp[1] ? 0 : HDA_AMP_MUTE);
740 if (change)
741 ad1986a_update_hp(codec);
742 return change;
743 }
744
745 static struct snd_kcontrol_new ad1986a_laptop_automute_mixers[] = {
746 HDA_BIND_VOL("Master Playback Volume", &ad1986a_laptop_master_vol),
747 {
748 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
749 .name = "Master Playback Switch",
750 .info = snd_hda_mixer_amp_switch_info,
751 .get = snd_hda_mixer_amp_switch_get,
752 .put = ad1986a_hp_master_sw_put,
753 .private_value = HDA_COMPOSE_AMP_VAL(0x1a, 3, 0, HDA_OUTPUT),
754 },
755 HDA_CODEC_VOLUME("PCM Playback Volume", 0x03, 0x0, HDA_OUTPUT),
756 HDA_CODEC_MUTE("PCM Playback Switch", 0x03, 0x0, HDA_OUTPUT),
757 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x17, 0x0, HDA_OUTPUT),
758 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x17, 0x0, HDA_OUTPUT),
759 HDA_CODEC_VOLUME("Mic Playback Volume", 0x13, 0x0, HDA_OUTPUT),
760 HDA_CODEC_MUTE("Mic Playback Switch", 0x13, 0x0, HDA_OUTPUT),
761 HDA_CODEC_VOLUME("Mic Boost", 0x0f, 0x0, HDA_OUTPUT),
762 HDA_CODEC_VOLUME("Beep Playback Volume", 0x18, 0x0, HDA_OUTPUT),
763 HDA_CODEC_MUTE("Beep Playback Switch", 0x18, 0x0, HDA_OUTPUT),
764 HDA_CODEC_VOLUME("Capture Volume", 0x12, 0x0, HDA_OUTPUT),
765 HDA_CODEC_MUTE("Capture Switch", 0x12, 0x0, HDA_OUTPUT),
766 {
767 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
768 .name = "Capture Source",
769 .info = ad198x_mux_enum_info,
770 .get = ad198x_mux_enum_get,
771 .put = ad198x_mux_enum_put,
772 },
773 {
774 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
775 .name = "External Amplifier",
776 .info = ad198x_eapd_info,
777 .get = ad198x_eapd_get,
778 .put = ad198x_eapd_put,
779 .private_value = 0x1b | (1 << 8), /* port-D, inversed */
780 },
781 { } /* end */
782 };
783
784 /*
785 * initialization verbs
786 */
787 static struct hda_verb ad1986a_init_verbs[] = {
788 /* Front, Surround, CLFE DAC; mute as default */
789 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080},
790 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080},
791 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080},
792 /* Downmix - off */
793 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080},
794 /* HP, Line-Out, Surround, CLFE selectors */
795 {0x0a, AC_VERB_SET_CONNECT_SEL, 0x0},
796 {0x0b, AC_VERB_SET_CONNECT_SEL, 0x0},
797 {0x0c, AC_VERB_SET_CONNECT_SEL, 0x0},
798 {0x0d, AC_VERB_SET_CONNECT_SEL, 0x0},
799 /* Mono selector */
800 {0x0e, AC_VERB_SET_CONNECT_SEL, 0x0},
801 /* Mic selector: Mic 1/2 pin */
802 {0x0f, AC_VERB_SET_CONNECT_SEL, 0x0},
803 /* Line-in selector: Line-in */
804 {0x10, AC_VERB_SET_CONNECT_SEL, 0x0},
805 /* Mic 1/2 swap */
806 {0x11, AC_VERB_SET_CONNECT_SEL, 0x0},
807 /* Record selector: mic */
808 {0x12, AC_VERB_SET_CONNECT_SEL, 0x0},
809 /* Mic, Phone, CD, Aux, Line-In amp; mute as default */
810 {0x13, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080},
811 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080},
812 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080},
813 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080},
814 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080},
815 /* PC beep */
816 {0x18, AC_VERB_SET_CONNECT_SEL, 0x0},
817 /* HP, Line-Out, Surround, CLFE, Mono pins; mute as default */
818 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080},
819 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080},
820 {0x1c, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080},
821 {0x1d, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080},
822 {0x1e, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080},
823 /* HP Pin */
824 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0 },
825 /* Front, Surround, CLFE Pins */
826 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
827 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
828 {0x1d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
829 /* Mono Pin */
830 {0x1e, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
831 /* Mic Pin */
832 {0x1f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
833 /* Line, Aux, CD, Beep-In Pin */
834 {0x20, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
835 {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
836 {0x22, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
837 {0x23, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
838 {0x24, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
839 { } /* end */
840 };
841
842 static struct hda_verb ad1986a_ch2_init[] = {
843 /* Surround out -> Line In */
844 { 0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
845 /* Line-in selectors */
846 { 0x10, AC_VERB_SET_CONNECT_SEL, 0x1 },
847 /* CLFE -> Mic in */
848 { 0x1d, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
849 /* Mic selector, mix C/LFE (backmic) and Mic (frontmic) */
850 { 0x0f, AC_VERB_SET_CONNECT_SEL, 0x4 },
851 { } /* end */
852 };
853
854 static struct hda_verb ad1986a_ch4_init[] = {
855 /* Surround out -> Surround */
856 { 0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
857 { 0x10, AC_VERB_SET_CONNECT_SEL, 0x0 },
858 /* CLFE -> Mic in */
859 { 0x1d, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
860 { 0x0f, AC_VERB_SET_CONNECT_SEL, 0x4 },
861 { } /* end */
862 };
863
864 static struct hda_verb ad1986a_ch6_init[] = {
865 /* Surround out -> Surround out */
866 { 0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
867 { 0x10, AC_VERB_SET_CONNECT_SEL, 0x0 },
868 /* CLFE -> CLFE */
869 { 0x1d, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
870 { 0x0f, AC_VERB_SET_CONNECT_SEL, 0x0 },
871 { } /* end */
872 };
873
874 static struct hda_channel_mode ad1986a_modes[3] = {
875 { 2, ad1986a_ch2_init },
876 { 4, ad1986a_ch4_init },
877 { 6, ad1986a_ch6_init },
878 };
879
880 /* eapd initialization */
881 static struct hda_verb ad1986a_eapd_init_verbs[] = {
882 {0x1b, AC_VERB_SET_EAPD_BTLENABLE, 0x00 },
883 {}
884 };
885
886 static struct hda_verb ad1986a_automic_verbs[] = {
887 {0x1d, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
888 {0x1f, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
889 /*{0x20, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},*/
890 {0x0f, AC_VERB_SET_CONNECT_SEL, 0x0},
891 {0x1f, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | AD1986A_MIC_EVENT},
892 {}
893 };
894
895 /* Ultra initialization */
896 static struct hda_verb ad1986a_ultra_init[] = {
897 /* eapd initialization */
898 { 0x1b, AC_VERB_SET_EAPD_BTLENABLE, 0x00 },
899 /* CLFE -> Mic in */
900 { 0x0f, AC_VERB_SET_CONNECT_SEL, 0x2 },
901 { 0x1d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
902 { 0x1d, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080 },
903 { } /* end */
904 };
905
906 /* pin sensing on HP jack */
907 static struct hda_verb ad1986a_hp_init_verbs[] = {
908 {0x1a, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | AD1986A_HP_EVENT},
909 {}
910 };
911
912
913 /* models */
914 enum {
915 AD1986A_6STACK,
916 AD1986A_3STACK,
917 AD1986A_LAPTOP,
918 AD1986A_LAPTOP_EAPD,
919 AD1986A_LAPTOP_AUTOMUTE,
920 AD1986A_ULTRA,
921 AD1986A_MODELS
922 };
923
924 static const char *ad1986a_models[AD1986A_MODELS] = {
925 [AD1986A_6STACK] = "6stack",
926 [AD1986A_3STACK] = "3stack",
927 [AD1986A_LAPTOP] = "laptop",
928 [AD1986A_LAPTOP_EAPD] = "laptop-eapd",
929 [AD1986A_LAPTOP_AUTOMUTE] = "laptop-automute",
930 [AD1986A_ULTRA] = "ultra",
931 };
932
933 static struct snd_pci_quirk ad1986a_cfg_tbl[] = {
934 SND_PCI_QUIRK(0x103c, 0x30af, "HP B2800", AD1986A_LAPTOP_EAPD),
935 SND_PCI_QUIRK(0x1043, 0x1153, "ASUS M9", AD1986A_LAPTOP_EAPD),
936 SND_PCI_QUIRK(0x1043, 0x11f7, "ASUS U5A", AD1986A_LAPTOP_EAPD),
937 SND_PCI_QUIRK(0x1043, 0x1213, "ASUS A6J", AD1986A_LAPTOP_EAPD),
938 SND_PCI_QUIRK(0x1043, 0x1263, "ASUS U5F", AD1986A_LAPTOP_EAPD),
939 SND_PCI_QUIRK(0x1043, 0x1297, "ASUS Z62F", AD1986A_LAPTOP_EAPD),
940 SND_PCI_QUIRK(0x1043, 0x12b3, "ASUS V1j", AD1986A_LAPTOP_EAPD),
941 SND_PCI_QUIRK(0x1043, 0x1302, "ASUS W3j", AD1986A_LAPTOP_EAPD),
942 SND_PCI_QUIRK(0x1043, 0x1443, "ASUS VX1", AD1986A_LAPTOP),
943 SND_PCI_QUIRK(0x1043, 0x1447, "ASUS A8J", AD1986A_3STACK),
944 SND_PCI_QUIRK(0x1043, 0x817f, "ASUS P5", AD1986A_3STACK),
945 SND_PCI_QUIRK(0x1043, 0x818f, "ASUS P5", AD1986A_LAPTOP),
946 SND_PCI_QUIRK(0x1043, 0x81b3, "ASUS P5", AD1986A_3STACK),
947 SND_PCI_QUIRK(0x1043, 0x81cb, "ASUS M2N", AD1986A_3STACK),
948 SND_PCI_QUIRK(0x1043, 0x8234, "ASUS M2N", AD1986A_3STACK),
949 SND_PCI_QUIRK(0x10de, 0xcb84, "ASUS A8N-VM", AD1986A_3STACK),
950 SND_PCI_QUIRK(0x1179, 0xff40, "Toshiba", AD1986A_LAPTOP_EAPD),
951 SND_PCI_QUIRK(0x144d, 0xb03c, "Samsung R55", AD1986A_3STACK),
952 SND_PCI_QUIRK(0x144d, 0xc01e, "FSC V2060", AD1986A_LAPTOP),
953 SND_PCI_QUIRK(0x144d, 0xc023, "Samsung X60", AD1986A_LAPTOP_EAPD),
954 SND_PCI_QUIRK(0x144d, 0xc024, "Samsung R65", AD1986A_LAPTOP_EAPD),
955 SND_PCI_QUIRK(0x144d, 0xc026, "Samsung X11", AD1986A_LAPTOP_EAPD),
956 SND_PCI_QUIRK(0x144d, 0xc027, "Samsung Q1", AD1986A_ULTRA),
957 SND_PCI_QUIRK(0x144d, 0xc504, "Samsung Q35", AD1986A_3STACK),
958 SND_PCI_QUIRK(0x17aa, 0x1011, "Lenovo M55", AD1986A_LAPTOP),
959 SND_PCI_QUIRK(0x17aa, 0x1017, "Lenovo A60", AD1986A_3STACK),
960 SND_PCI_QUIRK(0x17aa, 0x2066, "Lenovo N100", AD1986A_LAPTOP_AUTOMUTE),
961 SND_PCI_QUIRK(0x17c0, 0x2017, "Samsung M50", AD1986A_LAPTOP),
962 {}
963 };
964
965 #ifdef CONFIG_SND_HDA_POWER_SAVE
966 static struct hda_amp_list ad1986a_loopbacks[] = {
967 { 0x13, HDA_OUTPUT, 0 }, /* Mic */
968 { 0x14, HDA_OUTPUT, 0 }, /* Phone */
969 { 0x15, HDA_OUTPUT, 0 }, /* CD */
970 { 0x16, HDA_OUTPUT, 0 }, /* Aux */
971 { 0x17, HDA_OUTPUT, 0 }, /* Line */
972 { } /* end */
973 };
974 #endif
975
976 static int is_jack_available(struct hda_codec *codec, hda_nid_t nid)
977 {
978 unsigned int conf = snd_hda_codec_read(codec, nid, 0,
979 AC_VERB_GET_CONFIG_DEFAULT, 0);
980 return get_defcfg_connect(conf) != AC_JACK_PORT_NONE;
981 }
982
983 static int patch_ad1986a(struct hda_codec *codec)
984 {
985 struct ad198x_spec *spec;
986 int board_config;
987
988 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
989 if (spec == NULL)
990 return -ENOMEM;
991
992 codec->spec = spec;
993
994 spec->multiout.max_channels = 6;
995 spec->multiout.num_dacs = ARRAY_SIZE(ad1986a_dac_nids);
996 spec->multiout.dac_nids = ad1986a_dac_nids;
997 spec->multiout.dig_out_nid = AD1986A_SPDIF_OUT;
998 spec->num_adc_nids = 1;
999 spec->adc_nids = ad1986a_adc_nids;
1000 spec->capsrc_nids = ad1986a_capsrc_nids;
1001 spec->input_mux = &ad1986a_capture_source;
1002 spec->num_mixers = 1;
1003 spec->mixers[0] = ad1986a_mixers;
1004 spec->num_init_verbs = 1;
1005 spec->init_verbs[0] = ad1986a_init_verbs;
1006 #ifdef CONFIG_SND_HDA_POWER_SAVE
1007 spec->loopback.amplist = ad1986a_loopbacks;
1008 #endif
1009 spec->vmaster_nid = 0x1b;
1010
1011 codec->patch_ops = ad198x_patch_ops;
1012
1013 /* override some parameters */
1014 board_config = snd_hda_check_board_config(codec, AD1986A_MODELS,
1015 ad1986a_models,
1016 ad1986a_cfg_tbl);
1017 switch (board_config) {
1018 case AD1986A_3STACK:
1019 spec->num_mixers = 2;
1020 spec->mixers[1] = ad1986a_3st_mixers;
1021 spec->num_init_verbs = 2;
1022 spec->init_verbs[1] = ad1986a_ch2_init;
1023 spec->channel_mode = ad1986a_modes;
1024 spec->num_channel_mode = ARRAY_SIZE(ad1986a_modes);
1025 spec->need_dac_fix = 1;
1026 spec->multiout.max_channels = 2;
1027 spec->multiout.num_dacs = 1;
1028 break;
1029 case AD1986A_LAPTOP:
1030 spec->mixers[0] = ad1986a_laptop_mixers;
1031 spec->multiout.max_channels = 2;
1032 spec->multiout.num_dacs = 1;
1033 spec->multiout.dac_nids = ad1986a_laptop_dac_nids;
1034 break;
1035 case AD1986A_LAPTOP_EAPD:
1036 spec->mixers[0] = ad1986a_laptop_eapd_mixers;
1037 spec->num_init_verbs = 3;
1038 spec->init_verbs[1] = ad1986a_eapd_init_verbs;
1039 spec->init_verbs[2] = ad1986a_automic_verbs;
1040 spec->multiout.max_channels = 2;
1041 spec->multiout.num_dacs = 1;
1042 spec->multiout.dac_nids = ad1986a_laptop_dac_nids;
1043 if (!is_jack_available(codec, 0x25))
1044 spec->multiout.dig_out_nid = 0;
1045 spec->input_mux = &ad1986a_automic_capture_source;
1046 codec->patch_ops.unsol_event = ad1986a_automic_unsol_event;
1047 codec->patch_ops.init = ad1986a_automic_init;
1048 break;
1049 case AD1986A_LAPTOP_AUTOMUTE:
1050 spec->mixers[0] = ad1986a_laptop_automute_mixers;
1051 spec->num_init_verbs = 3;
1052 spec->init_verbs[1] = ad1986a_eapd_init_verbs;
1053 spec->init_verbs[2] = ad1986a_hp_init_verbs;
1054 spec->multiout.max_channels = 2;
1055 spec->multiout.num_dacs = 1;
1056 spec->multiout.dac_nids = ad1986a_laptop_dac_nids;
1057 if (!is_jack_available(codec, 0x25))
1058 spec->multiout.dig_out_nid = 0;
1059 spec->input_mux = &ad1986a_laptop_eapd_capture_source;
1060 codec->patch_ops.unsol_event = ad1986a_hp_unsol_event;
1061 codec->patch_ops.init = ad1986a_hp_init;
1062 break;
1063 case AD1986A_ULTRA:
1064 spec->mixers[0] = ad1986a_laptop_eapd_mixers;
1065 spec->num_init_verbs = 2;
1066 spec->init_verbs[1] = ad1986a_ultra_init;
1067 spec->multiout.max_channels = 2;
1068 spec->multiout.num_dacs = 1;
1069 spec->multiout.dac_nids = ad1986a_laptop_dac_nids;
1070 spec->multiout.dig_out_nid = 0;
1071 break;
1072 }
1073
1074 /* AD1986A has a hardware problem that it can't share a stream
1075 * with multiple output pins. The copy of front to surrounds
1076 * causes noisy or silent outputs at a certain timing, e.g.
1077 * changing the volume.
1078 * So, let's disable the shared stream.
1079 */
1080 spec->multiout.no_share_stream = 1;
1081
1082 return 0;
1083 }
1084
1085 /*
1086 * AD1983 specific
1087 */
1088
1089 #define AD1983_SPDIF_OUT 0x02
1090 #define AD1983_DAC 0x03
1091 #define AD1983_ADC 0x04
1092
1093 static hda_nid_t ad1983_dac_nids[1] = { AD1983_DAC };
1094 static hda_nid_t ad1983_adc_nids[1] = { AD1983_ADC };
1095 static hda_nid_t ad1983_capsrc_nids[1] = { 0x15 };
1096
1097 static struct hda_input_mux ad1983_capture_source = {
1098 .num_items = 4,
1099 .items = {
1100 { "Mic", 0x0 },
1101 { "Line", 0x1 },
1102 { "Mix", 0x2 },
1103 { "Mix Mono", 0x3 },
1104 },
1105 };
1106
1107 /*
1108 * SPDIF playback route
1109 */
1110 static int ad1983_spdif_route_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo)
1111 {
1112 static char *texts[] = { "PCM", "ADC" };
1113
1114 uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
1115 uinfo->count = 1;
1116 uinfo->value.enumerated.items = 2;
1117 if (uinfo->value.enumerated.item > 1)
1118 uinfo->value.enumerated.item = 1;
1119 strcpy(uinfo->value.enumerated.name, texts[uinfo->value.enumerated.item]);
1120 return 0;
1121 }
1122
1123 static int ad1983_spdif_route_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
1124 {
1125 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
1126 struct ad198x_spec *spec = codec->spec;
1127
1128 ucontrol->value.enumerated.item[0] = spec->spdif_route;
1129 return 0;
1130 }
1131
1132 static int ad1983_spdif_route_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
1133 {
1134 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
1135 struct ad198x_spec *spec = codec->spec;
1136
1137 if (ucontrol->value.enumerated.item[0] > 1)
1138 return -EINVAL;
1139 if (spec->spdif_route != ucontrol->value.enumerated.item[0]) {
1140 spec->spdif_route = ucontrol->value.enumerated.item[0];
1141 snd_hda_codec_write_cache(codec, spec->multiout.dig_out_nid, 0,
1142 AC_VERB_SET_CONNECT_SEL,
1143 spec->spdif_route);
1144 return 1;
1145 }
1146 return 0;
1147 }
1148
1149 static struct snd_kcontrol_new ad1983_mixers[] = {
1150 HDA_CODEC_VOLUME("Front Playback Volume", 0x05, 0x0, HDA_OUTPUT),
1151 HDA_CODEC_MUTE("Front Playback Switch", 0x05, 0x0, HDA_OUTPUT),
1152 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x06, 0x0, HDA_OUTPUT),
1153 HDA_CODEC_MUTE("Headphone Playback Switch", 0x06, 0x0, HDA_OUTPUT),
1154 HDA_CODEC_VOLUME_MONO("Mono Playback Volume", 0x07, 1, 0x0, HDA_OUTPUT),
1155 HDA_CODEC_MUTE_MONO("Mono Playback Switch", 0x07, 1, 0x0, HDA_OUTPUT),
1156 HDA_CODEC_VOLUME("PCM Playback Volume", 0x11, 0x0, HDA_OUTPUT),
1157 HDA_CODEC_MUTE("PCM Playback Switch", 0x11, 0x0, HDA_OUTPUT),
1158 HDA_CODEC_VOLUME("Mic Playback Volume", 0x12, 0x0, HDA_OUTPUT),
1159 HDA_CODEC_MUTE("Mic Playback Switch", 0x12, 0x0, HDA_OUTPUT),
1160 HDA_CODEC_VOLUME("Line Playback Volume", 0x13, 0x0, HDA_OUTPUT),
1161 HDA_CODEC_MUTE("Line Playback Switch", 0x13, 0x0, HDA_OUTPUT),
1162 HDA_CODEC_VOLUME_MONO("PC Speaker Playback Volume", 0x10, 1, 0x0, HDA_OUTPUT),
1163 HDA_CODEC_MUTE_MONO("PC Speaker Playback Switch", 0x10, 1, 0x0, HDA_OUTPUT),
1164 HDA_CODEC_VOLUME("Mic Boost", 0x0c, 0x0, HDA_OUTPUT),
1165 HDA_CODEC_VOLUME("Capture Volume", 0x15, 0x0, HDA_OUTPUT),
1166 HDA_CODEC_MUTE("Capture Switch", 0x15, 0x0, HDA_OUTPUT),
1167 {
1168 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1169 .name = "Capture Source",
1170 .info = ad198x_mux_enum_info,
1171 .get = ad198x_mux_enum_get,
1172 .put = ad198x_mux_enum_put,
1173 },
1174 {
1175 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1176 .name = SNDRV_CTL_NAME_IEC958("",PLAYBACK,NONE) "Source",
1177 .info = ad1983_spdif_route_info,
1178 .get = ad1983_spdif_route_get,
1179 .put = ad1983_spdif_route_put,
1180 },
1181 { } /* end */
1182 };
1183
1184 static struct hda_verb ad1983_init_verbs[] = {
1185 /* Front, HP, Mono; mute as default */
1186 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080},
1187 {0x06, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080},
1188 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080},
1189 /* Beep, PCM, Mic, Line-In: mute */
1190 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080},
1191 {0x11, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080},
1192 {0x12, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080},
1193 {0x13, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080},
1194 /* Front, HP selectors; from Mix */
1195 {0x05, AC_VERB_SET_CONNECT_SEL, 0x01},
1196 {0x06, AC_VERB_SET_CONNECT_SEL, 0x01},
1197 /* Mono selector; from Mix */
1198 {0x0b, AC_VERB_SET_CONNECT_SEL, 0x03},
1199 /* Mic selector; Mic */
1200 {0x0c, AC_VERB_SET_CONNECT_SEL, 0x0},
1201 /* Line-in selector: Line-in */
1202 {0x0d, AC_VERB_SET_CONNECT_SEL, 0x0},
1203 /* Mic boost: 0dB */
1204 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, 0xb000},
1205 /* Record selector: mic */
1206 {0x15, AC_VERB_SET_CONNECT_SEL, 0x0},
1207 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080},
1208 /* SPDIF route: PCM */
1209 {0x02, AC_VERB_SET_CONNECT_SEL, 0x0},
1210 /* Front Pin */
1211 {0x05, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
1212 /* HP Pin */
1213 {0x06, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0 },
1214 /* Mono Pin */
1215 {0x07, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
1216 /* Mic Pin */
1217 {0x08, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
1218 /* Line Pin */
1219 {0x09, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
1220 { } /* end */
1221 };
1222
1223 #ifdef CONFIG_SND_HDA_POWER_SAVE
1224 static struct hda_amp_list ad1983_loopbacks[] = {
1225 { 0x12, HDA_OUTPUT, 0 }, /* Mic */
1226 { 0x13, HDA_OUTPUT, 0 }, /* Line */
1227 { } /* end */
1228 };
1229 #endif
1230
1231 static int patch_ad1983(struct hda_codec *codec)
1232 {
1233 struct ad198x_spec *spec;
1234
1235 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
1236 if (spec == NULL)
1237 return -ENOMEM;
1238
1239 codec->spec = spec;
1240
1241 spec->multiout.max_channels = 2;
1242 spec->multiout.num_dacs = ARRAY_SIZE(ad1983_dac_nids);
1243 spec->multiout.dac_nids = ad1983_dac_nids;
1244 spec->multiout.dig_out_nid = AD1983_SPDIF_OUT;
1245 spec->num_adc_nids = 1;
1246 spec->adc_nids = ad1983_adc_nids;
1247 spec->capsrc_nids = ad1983_capsrc_nids;
1248 spec->input_mux = &ad1983_capture_source;
1249 spec->num_mixers = 1;
1250 spec->mixers[0] = ad1983_mixers;
1251 spec->num_init_verbs = 1;
1252 spec->init_verbs[0] = ad1983_init_verbs;
1253 spec->spdif_route = 0;
1254 #ifdef CONFIG_SND_HDA_POWER_SAVE
1255 spec->loopback.amplist = ad1983_loopbacks;
1256 #endif
1257 spec->vmaster_nid = 0x05;
1258
1259 codec->patch_ops = ad198x_patch_ops;
1260
1261 return 0;
1262 }
1263
1264
1265 /*
1266 * AD1981 HD specific
1267 */
1268
1269 #define AD1981_SPDIF_OUT 0x02
1270 #define AD1981_DAC 0x03
1271 #define AD1981_ADC 0x04
1272
1273 static hda_nid_t ad1981_dac_nids[1] = { AD1981_DAC };
1274 static hda_nid_t ad1981_adc_nids[1] = { AD1981_ADC };
1275 static hda_nid_t ad1981_capsrc_nids[1] = { 0x15 };
1276
1277 /* 0x0c, 0x09, 0x0e, 0x0f, 0x19, 0x05, 0x18, 0x17 */
1278 static struct hda_input_mux ad1981_capture_source = {
1279 .num_items = 7,
1280 .items = {
1281 { "Front Mic", 0x0 },
1282 { "Line", 0x1 },
1283 { "Mix", 0x2 },
1284 { "Mix Mono", 0x3 },
1285 { "CD", 0x4 },
1286 { "Mic", 0x6 },
1287 { "Aux", 0x7 },
1288 },
1289 };
1290
1291 static struct snd_kcontrol_new ad1981_mixers[] = {
1292 HDA_CODEC_VOLUME("Front Playback Volume", 0x05, 0x0, HDA_OUTPUT),
1293 HDA_CODEC_MUTE("Front Playback Switch", 0x05, 0x0, HDA_OUTPUT),
1294 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x06, 0x0, HDA_OUTPUT),
1295 HDA_CODEC_MUTE("Headphone Playback Switch", 0x06, 0x0, HDA_OUTPUT),
1296 HDA_CODEC_VOLUME_MONO("Mono Playback Volume", 0x07, 1, 0x0, HDA_OUTPUT),
1297 HDA_CODEC_MUTE_MONO("Mono Playback Switch", 0x07, 1, 0x0, HDA_OUTPUT),
1298 HDA_CODEC_VOLUME("PCM Playback Volume", 0x11, 0x0, HDA_OUTPUT),
1299 HDA_CODEC_MUTE("PCM Playback Switch", 0x11, 0x0, HDA_OUTPUT),
1300 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x12, 0x0, HDA_OUTPUT),
1301 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x12, 0x0, HDA_OUTPUT),
1302 HDA_CODEC_VOLUME("Line Playback Volume", 0x13, 0x0, HDA_OUTPUT),
1303 HDA_CODEC_MUTE("Line Playback Switch", 0x13, 0x0, HDA_OUTPUT),
1304 HDA_CODEC_VOLUME("Aux Playback Volume", 0x1b, 0x0, HDA_OUTPUT),
1305 HDA_CODEC_MUTE("Aux Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
1306 HDA_CODEC_VOLUME("Mic Playback Volume", 0x1c, 0x0, HDA_OUTPUT),
1307 HDA_CODEC_MUTE("Mic Playback Switch", 0x1c, 0x0, HDA_OUTPUT),
1308 HDA_CODEC_VOLUME("CD Playback Volume", 0x1d, 0x0, HDA_OUTPUT),
1309 HDA_CODEC_MUTE("CD Playback Switch", 0x1d, 0x0, HDA_OUTPUT),
1310 HDA_CODEC_VOLUME_MONO("PC Speaker Playback Volume", 0x0d, 1, 0x0, HDA_OUTPUT),
1311 HDA_CODEC_MUTE_MONO("PC Speaker Playback Switch", 0x0d, 1, 0x0, HDA_OUTPUT),
1312 HDA_CODEC_VOLUME("Front Mic Boost", 0x08, 0x0, HDA_INPUT),
1313 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0x0, HDA_INPUT),
1314 HDA_CODEC_VOLUME("Capture Volume", 0x15, 0x0, HDA_OUTPUT),
1315 HDA_CODEC_MUTE("Capture Switch", 0x15, 0x0, HDA_OUTPUT),
1316 {
1317 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1318 .name = "Capture Source",
1319 .info = ad198x_mux_enum_info,
1320 .get = ad198x_mux_enum_get,
1321 .put = ad198x_mux_enum_put,
1322 },
1323 /* identical with AD1983 */
1324 {
1325 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1326 .name = SNDRV_CTL_NAME_IEC958("",PLAYBACK,NONE) "Source",
1327 .info = ad1983_spdif_route_info,
1328 .get = ad1983_spdif_route_get,
1329 .put = ad1983_spdif_route_put,
1330 },
1331 { } /* end */
1332 };
1333
1334 static struct hda_verb ad1981_init_verbs[] = {
1335 /* Front, HP, Mono; mute as default */
1336 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080},
1337 {0x06, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080},
1338 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080},
1339 /* Beep, PCM, Front Mic, Line, Rear Mic, Aux, CD-In: mute */
1340 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080},
1341 {0x11, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080},
1342 {0x12, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080},
1343 {0x13, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080},
1344 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080},
1345 {0x1c, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080},
1346 {0x1d, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080},
1347 /* Front, HP selectors; from Mix */
1348 {0x05, AC_VERB_SET_CONNECT_SEL, 0x01},
1349 {0x06, AC_VERB_SET_CONNECT_SEL, 0x01},
1350 /* Mono selector; from Mix */
1351 {0x0b, AC_VERB_SET_CONNECT_SEL, 0x03},
1352 /* Mic Mixer; select Front Mic */
1353 {0x1e, AC_VERB_SET_AMP_GAIN_MUTE, 0xb000},
1354 {0x1f, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080},
1355 /* Mic boost: 0dB */
1356 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, 0xb000},
1357 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, 0xb000},
1358 /* Record selector: Front mic */
1359 {0x15, AC_VERB_SET_CONNECT_SEL, 0x0},
1360 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080},
1361 /* SPDIF route: PCM */
1362 {0x02, AC_VERB_SET_CONNECT_SEL, 0x0},
1363 /* Front Pin */
1364 {0x05, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
1365 /* HP Pin */
1366 {0x06, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0 },
1367 /* Mono Pin */
1368 {0x07, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
1369 /* Front & Rear Mic Pins */
1370 {0x08, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
1371 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
1372 /* Line Pin */
1373 {0x09, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
1374 /* Digital Beep */
1375 {0x0d, AC_VERB_SET_CONNECT_SEL, 0x00},
1376 /* Line-Out as Input: disabled */
1377 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080},
1378 { } /* end */
1379 };
1380
1381 #ifdef CONFIG_SND_HDA_POWER_SAVE
1382 static struct hda_amp_list ad1981_loopbacks[] = {
1383 { 0x12, HDA_OUTPUT, 0 }, /* Front Mic */
1384 { 0x13, HDA_OUTPUT, 0 }, /* Line */
1385 { 0x1b, HDA_OUTPUT, 0 }, /* Aux */
1386 { 0x1c, HDA_OUTPUT, 0 }, /* Mic */
1387 { 0x1d, HDA_OUTPUT, 0 }, /* CD */
1388 { } /* end */
1389 };
1390 #endif
1391
1392 /*
1393 * Patch for HP nx6320
1394 *
1395 * nx6320 uses EAPD in the reverse way - EAPD-on means the internal
1396 * speaker output enabled _and_ mute-LED off.
1397 */
1398
1399 #define AD1981_HP_EVENT 0x37
1400 #define AD1981_MIC_EVENT 0x38
1401
1402 static struct hda_verb ad1981_hp_init_verbs[] = {
1403 {0x05, AC_VERB_SET_EAPD_BTLENABLE, 0x00 }, /* default off */
1404 /* pin sensing on HP and Mic jacks */
1405 {0x06, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | AD1981_HP_EVENT},
1406 {0x08, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | AD1981_MIC_EVENT},
1407 {}
1408 };
1409
1410 /* turn on/off EAPD (+ mute HP) as a master switch */
1411 static int ad1981_hp_master_sw_put(struct snd_kcontrol *kcontrol,
1412 struct snd_ctl_elem_value *ucontrol)
1413 {
1414 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
1415 struct ad198x_spec *spec = codec->spec;
1416
1417 if (! ad198x_eapd_put(kcontrol, ucontrol))
1418 return 0;
1419 /* change speaker pin appropriately */
1420 snd_hda_codec_write(codec, 0x05, 0,
1421 AC_VERB_SET_PIN_WIDGET_CONTROL,
1422 spec->cur_eapd ? PIN_OUT : 0);
1423 /* toggle HP mute appropriately */
1424 snd_hda_codec_amp_stereo(codec, 0x06, HDA_OUTPUT, 0,
1425 HDA_AMP_MUTE,
1426 spec->cur_eapd ? 0 : HDA_AMP_MUTE);
1427 return 1;
1428 }
1429
1430 /* bind volumes of both NID 0x05 and 0x06 */
1431 static struct hda_bind_ctls ad1981_hp_bind_master_vol = {
1432 .ops = &snd_hda_bind_vol,
1433 .values = {
1434 HDA_COMPOSE_AMP_VAL(0x05, 3, 0, HDA_OUTPUT),
1435 HDA_COMPOSE_AMP_VAL(0x06, 3, 0, HDA_OUTPUT),
1436 0
1437 },
1438 };
1439
1440 /* mute internal speaker if HP is plugged */
1441 static void ad1981_hp_automute(struct hda_codec *codec)
1442 {
1443 unsigned int present;
1444
1445 present = snd_hda_codec_read(codec, 0x06, 0,
1446 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
1447 snd_hda_codec_amp_stereo(codec, 0x05, HDA_OUTPUT, 0,
1448 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
1449 }
1450
1451 /* toggle input of built-in and mic jack appropriately */
1452 static void ad1981_hp_automic(struct hda_codec *codec)
1453 {
1454 static struct hda_verb mic_jack_on[] = {
1455 {0x1f, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080},
1456 {0x1e, AC_VERB_SET_AMP_GAIN_MUTE, 0xb000},
1457 {}
1458 };
1459 static struct hda_verb mic_jack_off[] = {
1460 {0x1e, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080},
1461 {0x1f, AC_VERB_SET_AMP_GAIN_MUTE, 0xb000},
1462 {}
1463 };
1464 unsigned int present;
1465
1466 present = snd_hda_codec_read(codec, 0x08, 0,
1467 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
1468 if (present)
1469 snd_hda_sequence_write(codec, mic_jack_on);
1470 else
1471 snd_hda_sequence_write(codec, mic_jack_off);
1472 }
1473
1474 /* unsolicited event for HP jack sensing */
1475 static void ad1981_hp_unsol_event(struct hda_codec *codec,
1476 unsigned int res)
1477 {
1478 res >>= 26;
1479 switch (res) {
1480 case AD1981_HP_EVENT:
1481 ad1981_hp_automute(codec);
1482 break;
1483 case AD1981_MIC_EVENT:
1484 ad1981_hp_automic(codec);
1485 break;
1486 }
1487 }
1488
1489 static struct hda_input_mux ad1981_hp_capture_source = {
1490 .num_items = 3,
1491 .items = {
1492 { "Mic", 0x0 },
1493 { "Docking-Station", 0x1 },
1494 { "Mix", 0x2 },
1495 },
1496 };
1497
1498 static struct snd_kcontrol_new ad1981_hp_mixers[] = {
1499 HDA_BIND_VOL("Master Playback Volume", &ad1981_hp_bind_master_vol),
1500 {
1501 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1502 .name = "Master Playback Switch",
1503 .info = ad198x_eapd_info,
1504 .get = ad198x_eapd_get,
1505 .put = ad1981_hp_master_sw_put,
1506 .private_value = 0x05,
1507 },
1508 HDA_CODEC_VOLUME("PCM Playback Volume", 0x11, 0x0, HDA_OUTPUT),
1509 HDA_CODEC_MUTE("PCM Playback Switch", 0x11, 0x0, HDA_OUTPUT),
1510 #if 0
1511 /* FIXME: analog mic/line loopback doesn't work with my tests...
1512 * (although recording is OK)
1513 */
1514 HDA_CODEC_VOLUME("Mic Playback Volume", 0x12, 0x0, HDA_OUTPUT),
1515 HDA_CODEC_MUTE("Mic Playback Switch", 0x12, 0x0, HDA_OUTPUT),
1516 HDA_CODEC_VOLUME("Docking-Station Playback Volume", 0x13, 0x0, HDA_OUTPUT),
1517 HDA_CODEC_MUTE("Docking-Station Playback Switch", 0x13, 0x0, HDA_OUTPUT),
1518 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x1c, 0x0, HDA_OUTPUT),
1519 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x1c, 0x0, HDA_OUTPUT),
1520 /* FIXME: does this laptop have analog CD connection? */
1521 HDA_CODEC_VOLUME("CD Playback Volume", 0x1d, 0x0, HDA_OUTPUT),
1522 HDA_CODEC_MUTE("CD Playback Switch", 0x1d, 0x0, HDA_OUTPUT),
1523 #endif
1524 HDA_CODEC_VOLUME("Mic Boost", 0x08, 0x0, HDA_INPUT),
1525 HDA_CODEC_VOLUME("Internal Mic Boost", 0x18, 0x0, HDA_INPUT),
1526 HDA_CODEC_VOLUME("Capture Volume", 0x15, 0x0, HDA_OUTPUT),
1527 HDA_CODEC_MUTE("Capture Switch", 0x15, 0x0, HDA_OUTPUT),
1528 {
1529 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1530 .name = "Capture Source",
1531 .info = ad198x_mux_enum_info,
1532 .get = ad198x_mux_enum_get,
1533 .put = ad198x_mux_enum_put,
1534 },
1535 { } /* end */
1536 };
1537
1538 /* initialize jack-sensing, too */
1539 static int ad1981_hp_init(struct hda_codec *codec)
1540 {
1541 ad198x_init(codec);
1542 ad1981_hp_automute(codec);
1543 ad1981_hp_automic(codec);
1544 return 0;
1545 }
1546
1547 /* configuration for Toshiba Laptops */
1548 static struct hda_verb ad1981_toshiba_init_verbs[] = {
1549 {0x05, AC_VERB_SET_EAPD_BTLENABLE, 0x01 }, /* default on */
1550 /* pin sensing on HP and Mic jacks */
1551 {0x06, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | AD1981_HP_EVENT},
1552 {0x08, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | AD1981_MIC_EVENT},
1553 {}
1554 };
1555
1556 static struct snd_kcontrol_new ad1981_toshiba_mixers[] = {
1557 HDA_CODEC_VOLUME("Amp Volume", 0x1a, 0x0, HDA_OUTPUT),
1558 HDA_CODEC_MUTE("Amp Switch", 0x1a, 0x0, HDA_OUTPUT),
1559 { }
1560 };
1561
1562 /* configuration for Lenovo Thinkpad T60 */
1563 static struct snd_kcontrol_new ad1981_thinkpad_mixers[] = {
1564 HDA_CODEC_VOLUME("Master Playback Volume", 0x05, 0x0, HDA_OUTPUT),
1565 HDA_CODEC_MUTE("Master Playback Switch", 0x05, 0x0, HDA_OUTPUT),
1566 HDA_CODEC_VOLUME("PCM Playback Volume", 0x11, 0x0, HDA_OUTPUT),
1567 HDA_CODEC_MUTE("PCM Playback Switch", 0x11, 0x0, HDA_OUTPUT),
1568 HDA_CODEC_VOLUME("Mic Playback Volume", 0x12, 0x0, HDA_OUTPUT),
1569 HDA_CODEC_MUTE("Mic Playback Switch", 0x12, 0x0, HDA_OUTPUT),
1570 HDA_CODEC_VOLUME("CD Playback Volume", 0x1d, 0x0, HDA_OUTPUT),
1571 HDA_CODEC_MUTE("CD Playback Switch", 0x1d, 0x0, HDA_OUTPUT),
1572 HDA_CODEC_VOLUME("Mic Boost", 0x08, 0x0, HDA_INPUT),
1573 HDA_CODEC_VOLUME("Capture Volume", 0x15, 0x0, HDA_OUTPUT),
1574 HDA_CODEC_MUTE("Capture Switch", 0x15, 0x0, HDA_OUTPUT),
1575 {
1576 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1577 .name = "Capture Source",
1578 .info = ad198x_mux_enum_info,
1579 .get = ad198x_mux_enum_get,
1580 .put = ad198x_mux_enum_put,
1581 },
1582 /* identical with AD1983 */
1583 {
1584 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1585 .name = SNDRV_CTL_NAME_IEC958("",PLAYBACK,NONE) "Source",
1586 .info = ad1983_spdif_route_info,
1587 .get = ad1983_spdif_route_get,
1588 .put = ad1983_spdif_route_put,
1589 },
1590 { } /* end */
1591 };
1592
1593 static struct hda_input_mux ad1981_thinkpad_capture_source = {
1594 .num_items = 3,
1595 .items = {
1596 { "Mic", 0x0 },
1597 { "Mix", 0x2 },
1598 { "CD", 0x4 },
1599 },
1600 };
1601
1602 /* models */
1603 enum {
1604 AD1981_BASIC,
1605 AD1981_HP,
1606 AD1981_THINKPAD,
1607 AD1981_TOSHIBA,
1608 AD1981_MODELS
1609 };
1610
1611 static const char *ad1981_models[AD1981_MODELS] = {
1612 [AD1981_HP] = "hp",
1613 [AD1981_THINKPAD] = "thinkpad",
1614 [AD1981_BASIC] = "basic",
1615 [AD1981_TOSHIBA] = "toshiba"
1616 };
1617
1618 static struct snd_pci_quirk ad1981_cfg_tbl[] = {
1619 SND_PCI_QUIRK(0x1014, 0x0597, "Lenovo Z60", AD1981_THINKPAD),
1620 SND_PCI_QUIRK(0x1014, 0x05b7, "Lenovo Z60m", AD1981_THINKPAD),
1621 /* All HP models */
1622 SND_PCI_QUIRK(0x103c, 0, "HP nx", AD1981_HP),
1623 SND_PCI_QUIRK(0x1179, 0x0001, "Toshiba U205", AD1981_TOSHIBA),
1624 /* Lenovo Thinkpad T60/X60/Z6xx */
1625 SND_PCI_QUIRK(0x17aa, 0, "Lenovo Thinkpad", AD1981_THINKPAD),
1626 /* HP nx6320 (reversed SSID, H/W bug) */
1627 SND_PCI_QUIRK(0x30b0, 0x103c, "HP nx6320", AD1981_HP),
1628 {}
1629 };
1630
1631 static int patch_ad1981(struct hda_codec *codec)
1632 {
1633 struct ad198x_spec *spec;
1634 int board_config;
1635
1636 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
1637 if (spec == NULL)
1638 return -ENOMEM;
1639
1640 codec->spec = spec;
1641
1642 spec->multiout.max_channels = 2;
1643 spec->multiout.num_dacs = ARRAY_SIZE(ad1981_dac_nids);
1644 spec->multiout.dac_nids = ad1981_dac_nids;
1645 spec->multiout.dig_out_nid = AD1981_SPDIF_OUT;
1646 spec->num_adc_nids = 1;
1647 spec->adc_nids = ad1981_adc_nids;
1648 spec->capsrc_nids = ad1981_capsrc_nids;
1649 spec->input_mux = &ad1981_capture_source;
1650 spec->num_mixers = 1;
1651 spec->mixers[0] = ad1981_mixers;
1652 spec->num_init_verbs = 1;
1653 spec->init_verbs[0] = ad1981_init_verbs;
1654 spec->spdif_route = 0;
1655 #ifdef CONFIG_SND_HDA_POWER_SAVE
1656 spec->loopback.amplist = ad1981_loopbacks;
1657 #endif
1658 spec->vmaster_nid = 0x05;
1659
1660 codec->patch_ops = ad198x_patch_ops;
1661
1662 /* override some parameters */
1663 board_config = snd_hda_check_board_config(codec, AD1981_MODELS,
1664 ad1981_models,
1665 ad1981_cfg_tbl);
1666 switch (board_config) {
1667 case AD1981_HP:
1668 spec->mixers[0] = ad1981_hp_mixers;
1669 spec->num_init_verbs = 2;
1670 spec->init_verbs[1] = ad1981_hp_init_verbs;
1671 spec->multiout.dig_out_nid = 0;
1672 spec->input_mux = &ad1981_hp_capture_source;
1673
1674 codec->patch_ops.init = ad1981_hp_init;
1675 codec->patch_ops.unsol_event = ad1981_hp_unsol_event;
1676 break;
1677 case AD1981_THINKPAD:
1678 spec->mixers[0] = ad1981_thinkpad_mixers;
1679 spec->input_mux = &ad1981_thinkpad_capture_source;
1680 break;
1681 case AD1981_TOSHIBA:
1682 spec->mixers[0] = ad1981_hp_mixers;
1683 spec->mixers[1] = ad1981_toshiba_mixers;
1684 spec->num_init_verbs = 2;
1685 spec->init_verbs[1] = ad1981_toshiba_init_verbs;
1686 spec->multiout.dig_out_nid = 0;
1687 spec->input_mux = &ad1981_hp_capture_source;
1688 codec->patch_ops.init = ad1981_hp_init;
1689 codec->patch_ops.unsol_event = ad1981_hp_unsol_event;
1690 break;
1691 }
1692 return 0;
1693 }
1694
1695
1696 /*
1697 * AD1988
1698 *
1699 * Output pins and routes
1700 *
1701 * Pin Mix Sel DAC (*)
1702 * port-A 0x11 (mute/hp) <- 0x22 <- 0x37 <- 03/04/06
1703 * port-B 0x14 (mute/hp) <- 0x2b <- 0x30 <- 03/04/06
1704 * port-C 0x15 (mute) <- 0x2c <- 0x31 <- 05/0a
1705 * port-D 0x12 (mute/hp) <- 0x29 <- 04
1706 * port-E 0x17 (mute/hp) <- 0x26 <- 0x32 <- 05/0a
1707 * port-F 0x16 (mute) <- 0x2a <- 06
1708 * port-G 0x24 (mute) <- 0x27 <- 05
1709 * port-H 0x25 (mute) <- 0x28 <- 0a
1710 * mono 0x13 (mute/amp)<- 0x1e <- 0x36 <- 03/04/06
1711 *
1712 * DAC0 = 03h, DAC1 = 04h, DAC2 = 05h, DAC3 = 06h, DAC4 = 0ah
1713 * (*) DAC2/3/4 are swapped to DAC3/4/2 on AD198A rev.2 due to a h/w bug.
1714 *
1715 * Input pins and routes
1716 *
1717 * pin boost mix input # / adc input #
1718 * port-A 0x11 -> 0x38 -> mix 2, ADC 0
1719 * port-B 0x14 -> 0x39 -> mix 0, ADC 1
1720 * port-C 0x15 -> 0x3a -> 33:0 - mix 1, ADC 2
1721 * port-D 0x12 -> 0x3d -> mix 3, ADC 8
1722 * port-E 0x17 -> 0x3c -> 34:0 - mix 4, ADC 4
1723 * port-F 0x16 -> 0x3b -> mix 5, ADC 3
1724 * port-G 0x24 -> N/A -> 33:1 - mix 1, 34:1 - mix 4, ADC 6
1725 * port-H 0x25 -> N/A -> 33:2 - mix 1, 34:2 - mix 4, ADC 7
1726 *
1727 *
1728 * DAC assignment
1729 * 6stack - front/surr/CLFE/side/opt DACs - 04/06/05/0a/03
1730 * 3stack - front/surr/CLFE/opt DACs - 04/05/0a/03
1731 *
1732 * Inputs of Analog Mix (0x20)
1733 * 0:Port-B (front mic)
1734 * 1:Port-C/G/H (line-in)
1735 * 2:Port-A
1736 * 3:Port-D (line-in/2)
1737 * 4:Port-E/G/H (mic-in)
1738 * 5:Port-F (mic2-in)
1739 * 6:CD
1740 * 7:Beep
1741 *
1742 * ADC selection
1743 * 0:Port-A
1744 * 1:Port-B (front mic-in)
1745 * 2:Port-C (line-in)
1746 * 3:Port-F (mic2-in)
1747 * 4:Port-E (mic-in)
1748 * 5:CD
1749 * 6:Port-G
1750 * 7:Port-H
1751 * 8:Port-D (line-in/2)
1752 * 9:Mix
1753 *
1754 * Proposed pin assignments by the datasheet
1755 *
1756 * 6-stack
1757 * Port-A front headphone
1758 * B front mic-in
1759 * C rear line-in
1760 * D rear front-out
1761 * E rear mic-in
1762 * F rear surround
1763 * G rear CLFE
1764 * H rear side
1765 *
1766 * 3-stack
1767 * Port-A front headphone
1768 * B front mic
1769 * C rear line-in/surround
1770 * D rear front-out
1771 * E rear mic-in/CLFE
1772 *
1773 * laptop
1774 * Port-A headphone
1775 * B mic-in
1776 * C docking station
1777 * D internal speaker (with EAPD)
1778 * E/F quad mic array
1779 */
1780
1781
1782 /* models */
1783 enum {
1784 AD1988_6STACK,
1785 AD1988_6STACK_DIG,
1786 AD1988_3STACK,
1787 AD1988_3STACK_DIG,
1788 AD1988_LAPTOP,
1789 AD1988_LAPTOP_DIG,
1790 AD1988_AUTO,
1791 AD1988_MODEL_LAST,
1792 };
1793
1794 /* reivision id to check workarounds */
1795 #define AD1988A_REV2 0x100200
1796
1797 #define is_rev2(codec) \
1798 ((codec)->vendor_id == 0x11d41988 && \
1799 (codec)->revision_id == AD1988A_REV2)
1800
1801 /*
1802 * mixers
1803 */
1804
1805 static hda_nid_t ad1988_6stack_dac_nids[4] = {
1806 0x04, 0x06, 0x05, 0x0a
1807 };
1808
1809 static hda_nid_t ad1988_3stack_dac_nids[3] = {
1810 0x04, 0x05, 0x0a
1811 };
1812
1813 /* for AD1988A revision-2, DAC2-4 are swapped */
1814 static hda_nid_t ad1988_6stack_dac_nids_rev2[4] = {
1815 0x04, 0x05, 0x0a, 0x06
1816 };
1817
1818 static hda_nid_t ad1988_3stack_dac_nids_rev2[3] = {
1819 0x04, 0x0a, 0x06
1820 };
1821
1822 static hda_nid_t ad1988_adc_nids[3] = {
1823 0x08, 0x09, 0x0f
1824 };
1825
1826 static hda_nid_t ad1988_capsrc_nids[3] = {
1827 0x0c, 0x0d, 0x0e
1828 };
1829
1830 #define AD1988_SPDIF_OUT 0x02
1831 #define AD1988_SPDIF_IN 0x07
1832
1833 static struct hda_input_mux ad1988_6stack_capture_source = {
1834 .num_items = 5,
1835 .items = {
1836 { "Front Mic", 0x1 }, /* port-B */
1837 { "Line", 0x2 }, /* port-C */
1838 { "Mic", 0x4 }, /* port-E */
1839 { "CD", 0x5 },
1840 { "Mix", 0x9 },
1841 },
1842 };
1843
1844 static struct hda_input_mux ad1988_laptop_capture_source = {
1845 .num_items = 3,
1846 .items = {
1847 { "Mic/Line", 0x1 }, /* port-B */
1848 { "CD", 0x5 },
1849 { "Mix", 0x9 },
1850 },
1851 };
1852
1853 /*
1854 */
1855 static int ad198x_ch_mode_info(struct snd_kcontrol *kcontrol,
1856 struct snd_ctl_elem_info *uinfo)
1857 {
1858 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
1859 struct ad198x_spec *spec = codec->spec;
1860 return snd_hda_ch_mode_info(codec, uinfo, spec->channel_mode,
1861 spec->num_channel_mode);
1862 }
1863
1864 static int ad198x_ch_mode_get(struct snd_kcontrol *kcontrol,
1865 struct snd_ctl_elem_value *ucontrol)
1866 {
1867 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
1868 struct ad198x_spec *spec = codec->spec;
1869 return snd_hda_ch_mode_get(codec, ucontrol, spec->channel_mode,
1870 spec->num_channel_mode, spec->multiout.max_channels);
1871 }
1872
1873 static int ad198x_ch_mode_put(struct snd_kcontrol *kcontrol,
1874 struct snd_ctl_elem_value *ucontrol)
1875 {
1876 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
1877 struct ad198x_spec *spec = codec->spec;
1878 int err = snd_hda_ch_mode_put(codec, ucontrol, spec->channel_mode,
1879 spec->num_channel_mode,
1880 &spec->multiout.max_channels);
1881 if (err >= 0 && spec->need_dac_fix)
1882 spec->multiout.num_dacs = spec->multiout.max_channels / 2;
1883 return err;
1884 }
1885
1886 /* 6-stack mode */
1887 static struct snd_kcontrol_new ad1988_6stack_mixers1[] = {
1888 HDA_CODEC_VOLUME("Front Playback Volume", 0x04, 0x0, HDA_OUTPUT),
1889 HDA_CODEC_VOLUME("Surround Playback Volume", 0x06, 0x0, HDA_OUTPUT),
1890 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x05, 1, 0x0, HDA_OUTPUT),
1891 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x05, 2, 0x0, HDA_OUTPUT),
1892 HDA_CODEC_VOLUME("Side Playback Volume", 0x0a, 0x0, HDA_OUTPUT),
1893 { } /* end */
1894 };
1895
1896 static struct snd_kcontrol_new ad1988_6stack_mixers1_rev2[] = {
1897 HDA_CODEC_VOLUME("Front Playback Volume", 0x04, 0x0, HDA_OUTPUT),
1898 HDA_CODEC_VOLUME("Surround Playback Volume", 0x05, 0x0, HDA_OUTPUT),
1899 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0a, 1, 0x0, HDA_OUTPUT),
1900 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0a, 2, 0x0, HDA_OUTPUT),
1901 HDA_CODEC_VOLUME("Side Playback Volume", 0x06, 0x0, HDA_OUTPUT),
1902 { } /* end */
1903 };
1904
1905 static struct snd_kcontrol_new ad1988_6stack_mixers2[] = {
1906 HDA_BIND_MUTE("Front Playback Switch", 0x29, 2, HDA_INPUT),
1907 HDA_BIND_MUTE("Surround Playback Switch", 0x2a, 2, HDA_INPUT),
1908 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x27, 1, 2, HDA_INPUT),
1909 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x27, 2, 2, HDA_INPUT),
1910 HDA_BIND_MUTE("Side Playback Switch", 0x28, 2, HDA_INPUT),
1911 HDA_BIND_MUTE("Headphone Playback Switch", 0x22, 2, HDA_INPUT),
1912 HDA_BIND_MUTE("Mono Playback Switch", 0x1e, 2, HDA_INPUT),
1913
1914 HDA_CODEC_VOLUME("CD Playback Volume", 0x20, 0x6, HDA_INPUT),
1915 HDA_CODEC_MUTE("CD Playback Switch", 0x20, 0x6, HDA_INPUT),
1916 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x20, 0x0, HDA_INPUT),
1917 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x20, 0x0, HDA_INPUT),
1918 HDA_CODEC_VOLUME("Line Playback Volume", 0x20, 0x1, HDA_INPUT),
1919 HDA_CODEC_MUTE("Line Playback Switch", 0x20, 0x1, HDA_INPUT),
1920 HDA_CODEC_VOLUME("Mic Playback Volume", 0x20, 0x4, HDA_INPUT),
1921 HDA_CODEC_MUTE("Mic Playback Switch", 0x20, 0x4, HDA_INPUT),
1922
1923 HDA_CODEC_VOLUME("Beep Playback Volume", 0x10, 0x0, HDA_OUTPUT),
1924 HDA_CODEC_MUTE("Beep Playback Switch", 0x10, 0x0, HDA_OUTPUT),
1925
1926 HDA_CODEC_VOLUME("Analog Mix Playback Volume", 0x21, 0x0, HDA_OUTPUT),
1927 HDA_CODEC_MUTE("Analog Mix Playback Switch", 0x21, 0x0, HDA_OUTPUT),
1928
1929 HDA_CODEC_VOLUME("Front Mic Boost", 0x39, 0x0, HDA_OUTPUT),
1930 HDA_CODEC_VOLUME("Mic Boost", 0x3c, 0x0, HDA_OUTPUT),
1931
1932 { } /* end */
1933 };
1934
1935 /* 3-stack mode */
1936 static struct snd_kcontrol_new ad1988_3stack_mixers1[] = {
1937 HDA_CODEC_VOLUME("Front Playback Volume", 0x04, 0x0, HDA_OUTPUT),
1938 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0a, 0x0, HDA_OUTPUT),
1939 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x05, 1, 0x0, HDA_OUTPUT),
1940 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x05, 2, 0x0, HDA_OUTPUT),
1941 { } /* end */
1942 };
1943
1944 static struct snd_kcontrol_new ad1988_3stack_mixers1_rev2[] = {
1945 HDA_CODEC_VOLUME("Front Playback Volume", 0x04, 0x0, HDA_OUTPUT),
1946 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0a, 0x0, HDA_OUTPUT),
1947 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x06, 1, 0x0, HDA_OUTPUT),
1948 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x06, 2, 0x0, HDA_OUTPUT),
1949 { } /* end */
1950 };
1951
1952 static struct snd_kcontrol_new ad1988_3stack_mixers2[] = {
1953 HDA_BIND_MUTE("Front Playback Switch", 0x29, 2, HDA_INPUT),
1954 HDA_BIND_MUTE("Surround Playback Switch", 0x2c, 2, HDA_INPUT),
1955 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x26, 1, 2, HDA_INPUT),
1956 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x26, 2, 2, HDA_INPUT),
1957 HDA_BIND_MUTE("Headphone Playback Switch", 0x22, 2, HDA_INPUT),
1958 HDA_BIND_MUTE("Mono Playback Switch", 0x1e, 2, HDA_INPUT),
1959
1960 HDA_CODEC_VOLUME("CD Playback Volume", 0x20, 0x6, HDA_INPUT),
1961 HDA_CODEC_MUTE("CD Playback Switch", 0x20, 0x6, HDA_INPUT),
1962 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x20, 0x0, HDA_INPUT),
1963 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x20, 0x0, HDA_INPUT),
1964 HDA_CODEC_VOLUME("Line Playback Volume", 0x20, 0x1, HDA_INPUT),
1965 HDA_CODEC_MUTE("Line Playback Switch", 0x20, 0x1, HDA_INPUT),
1966 HDA_CODEC_VOLUME("Mic Playback Volume", 0x20, 0x4, HDA_INPUT),
1967 HDA_CODEC_MUTE("Mic Playback Switch", 0x20, 0x4, HDA_INPUT),
1968
1969 HDA_CODEC_VOLUME("Beep Playback Volume", 0x10, 0x0, HDA_OUTPUT),
1970 HDA_CODEC_MUTE("Beep Playback Switch", 0x10, 0x0, HDA_OUTPUT),
1971
1972 HDA_CODEC_VOLUME("Analog Mix Playback Volume", 0x21, 0x0, HDA_OUTPUT),
1973 HDA_CODEC_MUTE("Analog Mix Playback Switch", 0x21, 0x0, HDA_OUTPUT),
1974
1975 HDA_CODEC_VOLUME("Front Mic Boost", 0x39, 0x0, HDA_OUTPUT),
1976 HDA_CODEC_VOLUME("Mic Boost", 0x3c, 0x0, HDA_OUTPUT),
1977 {
1978 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1979 .name = "Channel Mode",
1980 .info = ad198x_ch_mode_info,
1981 .get = ad198x_ch_mode_get,
1982 .put = ad198x_ch_mode_put,
1983 },
1984
1985 { } /* end */
1986 };
1987
1988 /* laptop mode */
1989 static struct snd_kcontrol_new ad1988_laptop_mixers[] = {
1990 HDA_CODEC_VOLUME("PCM Playback Volume", 0x04, 0x0, HDA_OUTPUT),
1991 HDA_CODEC_MUTE("PCM Playback Switch", 0x29, 0x0, HDA_INPUT),
1992 HDA_BIND_MUTE("Mono Playback Switch", 0x1e, 2, HDA_INPUT),
1993
1994 HDA_CODEC_VOLUME("CD Playback Volume", 0x20, 0x6, HDA_INPUT),
1995 HDA_CODEC_MUTE("CD Playback Switch", 0x20, 0x6, HDA_INPUT),
1996 HDA_CODEC_VOLUME("Mic Playback Volume", 0x20, 0x0, HDA_INPUT),
1997 HDA_CODEC_MUTE("Mic Playback Switch", 0x20, 0x0, HDA_INPUT),
1998 HDA_CODEC_VOLUME("Line Playback Volume", 0x20, 0x1, HDA_INPUT),
1999 HDA_CODEC_MUTE("Line Playback Switch", 0x20, 0x1, HDA_INPUT),
2000
2001 HDA_CODEC_VOLUME("Beep Playback Volume", 0x10, 0x0, HDA_OUTPUT),
2002 HDA_CODEC_MUTE("Beep Playback Switch", 0x10, 0x0, HDA_OUTPUT),
2003
2004 HDA_CODEC_VOLUME("Analog Mix Playback Volume", 0x21, 0x0, HDA_OUTPUT),
2005 HDA_CODEC_MUTE("Analog Mix Playback Switch", 0x21, 0x0, HDA_OUTPUT),
2006
2007 HDA_CODEC_VOLUME("Mic Boost", 0x39, 0x0, HDA_OUTPUT),
2008
2009 {
2010 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
2011 .name = "External Amplifier",
2012 .info = ad198x_eapd_info,
2013 .get = ad198x_eapd_get,
2014 .put = ad198x_eapd_put,
2015 .private_value = 0x12 | (1 << 8), /* port-D, inversed */
2016 },
2017
2018 { } /* end */
2019 };
2020
2021 /* capture */
2022 static struct snd_kcontrol_new ad1988_capture_mixers[] = {
2023 HDA_CODEC_VOLUME("Capture Volume", 0x0c, 0x0, HDA_OUTPUT),
2024 HDA_CODEC_MUTE("Capture Switch", 0x0c, 0x0, HDA_OUTPUT),
2025 HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x0d, 0x0, HDA_OUTPUT),
2026 HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x0d, 0x0, HDA_OUTPUT),
2027 HDA_CODEC_VOLUME_IDX("Capture Volume", 2, 0x0e, 0x0, HDA_OUTPUT),
2028 HDA_CODEC_MUTE_IDX("Capture Switch", 2, 0x0e, 0x0, HDA_OUTPUT),
2029 {
2030 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
2031 /* The multiple "Capture Source" controls confuse alsamixer
2032 * So call somewhat different..
2033 */
2034 /* .name = "Capture Source", */
2035 .name = "Input Source",
2036 .count = 3,
2037 .info = ad198x_mux_enum_info,
2038 .get = ad198x_mux_enum_get,
2039 .put = ad198x_mux_enum_put,
2040 },
2041 { } /* end */
2042 };
2043
2044 static int ad1988_spdif_playback_source_info(struct snd_kcontrol *kcontrol,
2045 struct snd_ctl_elem_info *uinfo)
2046 {
2047 static char *texts[] = {
2048 "PCM", "ADC1", "ADC2", "ADC3"
2049 };
2050 uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
2051 uinfo->count = 1;
2052 uinfo->value.enumerated.items = 4;
2053 if (uinfo->value.enumerated.item >= 4)
2054 uinfo->value.enumerated.item = 3;
2055 strcpy(uinfo->value.enumerated.name, texts[uinfo->value.enumerated.item]);
2056 return 0;
2057 }
2058
2059 static int ad1988_spdif_playback_source_get(struct snd_kcontrol *kcontrol,
2060 struct snd_ctl_elem_value *ucontrol)
2061 {
2062 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
2063 unsigned int sel;
2064
2065 sel = snd_hda_codec_read(codec, 0x1d, 0, AC_VERB_GET_AMP_GAIN_MUTE,
2066 AC_AMP_GET_INPUT);
2067 if (!(sel & 0x80))
2068 ucontrol->value.enumerated.item[0] = 0;
2069 else {
2070 sel = snd_hda_codec_read(codec, 0x0b, 0,
2071 AC_VERB_GET_CONNECT_SEL, 0);
2072 if (sel < 3)
2073 sel++;
2074 else
2075 sel = 0;
2076 ucontrol->value.enumerated.item[0] = sel;
2077 }
2078 return 0;
2079 }
2080
2081 static int ad1988_spdif_playback_source_put(struct snd_kcontrol *kcontrol,
2082 struct snd_ctl_elem_value *ucontrol)
2083 {
2084 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
2085 unsigned int val, sel;
2086 int change;
2087
2088 val = ucontrol->value.enumerated.item[0];
2089 if (val > 3)
2090 return -EINVAL;
2091 if (!val) {
2092 sel = snd_hda_codec_read(codec, 0x1d, 0,
2093 AC_VERB_GET_AMP_GAIN_MUTE,
2094 AC_AMP_GET_INPUT);
2095 change = sel & 0x80;
2096 if (change) {
2097 snd_hda_codec_write_cache(codec, 0x1d, 0,
2098 AC_VERB_SET_AMP_GAIN_MUTE,
2099 AMP_IN_UNMUTE(0));
2100 snd_hda_codec_write_cache(codec, 0x1d, 0,
2101 AC_VERB_SET_AMP_GAIN_MUTE,
2102 AMP_IN_MUTE(1));
2103 }
2104 } else {
2105 sel = snd_hda_codec_read(codec, 0x1d, 0,
2106 AC_VERB_GET_AMP_GAIN_MUTE,
2107 AC_AMP_GET_INPUT | 0x01);
2108 change = sel & 0x80;
2109 if (change) {
2110 snd_hda_codec_write_cache(codec, 0x1d, 0,
2111 AC_VERB_SET_AMP_GAIN_MUTE,
2112 AMP_IN_MUTE(0));
2113 snd_hda_codec_write_cache(codec, 0x1d, 0,
2114 AC_VERB_SET_AMP_GAIN_MUTE,
2115 AMP_IN_UNMUTE(1));
2116 }
2117 sel = snd_hda_codec_read(codec, 0x0b, 0,
2118 AC_VERB_GET_CONNECT_SEL, 0) + 1;
2119 change |= sel != val;
2120 if (change)
2121 snd_hda_codec_write_cache(codec, 0x0b, 0,
2122 AC_VERB_SET_CONNECT_SEL,
2123 val - 1);
2124 }
2125 return change;
2126 }
2127
2128 static struct snd_kcontrol_new ad1988_spdif_out_mixers[] = {
2129 HDA_CODEC_VOLUME("IEC958 Playback Volume", 0x1b, 0x0, HDA_OUTPUT),
2130 {
2131 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
2132 .name = "IEC958 Playback Source",
2133 .info = ad1988_spdif_playback_source_info,
2134 .get = ad1988_spdif_playback_source_get,
2135 .put = ad1988_spdif_playback_source_put,
2136 },
2137 { } /* end */
2138 };
2139
2140 static struct snd_kcontrol_new ad1988_spdif_in_mixers[] = {
2141 HDA_CODEC_VOLUME("IEC958 Capture Volume", 0x1c, 0x0, HDA_INPUT),
2142 { } /* end */
2143 };
2144
2145 static struct snd_kcontrol_new ad1989_spdif_out_mixers[] = {
2146 HDA_CODEC_VOLUME("IEC958 Playback Volume", 0x1b, 0x0, HDA_OUTPUT),
2147 { } /* end */
2148 };
2149
2150 /*
2151 * initialization verbs
2152 */
2153
2154 /*
2155 * for 6-stack (+dig)
2156 */
2157 static struct hda_verb ad1988_6stack_init_verbs[] = {
2158 /* Front, Surround, CLFE, side DAC; unmute as default */
2159 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2160 {0x06, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2161 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2162 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2163 /* Port-A front headphon path */
2164 {0x37, AC_VERB_SET_CONNECT_SEL, 0x01}, /* DAC1:04h */
2165 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
2166 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
2167 {0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2168 {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
2169 /* Port-D line-out path */
2170 {0x29, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
2171 {0x29, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
2172 {0x12, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2173 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2174 /* Port-F surround path */
2175 {0x2a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
2176 {0x2a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
2177 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2178 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2179 /* Port-G CLFE path */
2180 {0x27, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
2181 {0x27, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
2182 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2183 {0x24, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2184 /* Port-H side path */
2185 {0x28, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
2186 {0x28, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
2187 {0x25, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2188 {0x25, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2189 /* Mono out path */
2190 {0x36, AC_VERB_SET_CONNECT_SEL, 0x1}, /* DAC1:04h */
2191 {0x1e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
2192 {0x1e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
2193 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2194 {0x13, AC_VERB_SET_AMP_GAIN_MUTE, 0xb01f}, /* unmute, 0dB */
2195 /* Port-B front mic-in path */
2196 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2197 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2198 {0x39, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
2199 /* Port-C line-in path */
2200 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2201 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2202 {0x3a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
2203 {0x33, AC_VERB_SET_CONNECT_SEL, 0x0},
2204 /* Port-E mic-in path */
2205 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2206 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2207 {0x3c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
2208 {0x34, AC_VERB_SET_CONNECT_SEL, 0x0},
2209 /* Analog CD Input */
2210 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2211
2212 { }
2213 };
2214
2215 static struct hda_verb ad1988_capture_init_verbs[] = {
2216 /* mute analog mix */
2217 {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
2218 {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
2219 {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
2220 {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
2221 {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
2222 {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)},
2223 {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)},
2224 {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)},
2225 /* select ADCs - front-mic */
2226 {0x0c, AC_VERB_SET_CONNECT_SEL, 0x1},
2227 {0x0d, AC_VERB_SET_CONNECT_SEL, 0x1},
2228 {0x0e, AC_VERB_SET_CONNECT_SEL, 0x1},
2229 /* ADCs; muted */
2230 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2231 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2232 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2233
2234 { }
2235 };
2236
2237 static struct hda_verb ad1988_spdif_init_verbs[] = {
2238 /* SPDIF out sel */
2239 {0x02, AC_VERB_SET_CONNECT_SEL, 0x0}, /* PCM */
2240 {0x0b, AC_VERB_SET_CONNECT_SEL, 0x0}, /* ADC1 */
2241 {0x1d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
2242 {0x1d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
2243 /* SPDIF out pin */
2244 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE | 0x27}, /* 0dB */
2245
2246 { }
2247 };
2248
2249 /* AD1989 has no ADC -> SPDIF route */
2250 static struct hda_verb ad1989_spdif_init_verbs[] = {
2251 /* SPDIF out pin */
2252 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE | 0x27}, /* 0dB */
2253 { }
2254 };
2255
2256 /*
2257 * verbs for 3stack (+dig)
2258 */
2259 static struct hda_verb ad1988_3stack_ch2_init[] = {
2260 /* set port-C to line-in */
2261 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
2262 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
2263 /* set port-E to mic-in */
2264 { 0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
2265 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
2266 { } /* end */
2267 };
2268
2269 static struct hda_verb ad1988_3stack_ch6_init[] = {
2270 /* set port-C to surround out */
2271 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
2272 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
2273 /* set port-E to CLFE out */
2274 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
2275 { 0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
2276 { } /* end */
2277 };
2278
2279 static struct hda_channel_mode ad1988_3stack_modes[2] = {
2280 { 2, ad1988_3stack_ch2_init },
2281 { 6, ad1988_3stack_ch6_init },
2282 };
2283
2284 static struct hda_verb ad1988_3stack_init_verbs[] = {
2285 /* Front, Surround, CLFE, side DAC; unmute as default */
2286 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2287 {0x06, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2288 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2289 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2290 /* Port-A front headphon path */
2291 {0x37, AC_VERB_SET_CONNECT_SEL, 0x01}, /* DAC1:04h */
2292 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
2293 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
2294 {0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2295 {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
2296 /* Port-D line-out path */
2297 {0x29, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
2298 {0x29, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
2299 {0x12, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2300 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2301 /* Mono out path */
2302 {0x36, AC_VERB_SET_CONNECT_SEL, 0x1}, /* DAC1:04h */
2303 {0x1e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
2304 {0x1e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
2305 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2306 {0x13, AC_VERB_SET_AMP_GAIN_MUTE, 0xb01f}, /* unmute, 0dB */
2307 /* Port-B front mic-in path */
2308 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2309 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2310 {0x39, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
2311 /* Port-C line-in/surround path - 6ch mode as default */
2312 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2313 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2314 {0x3a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
2315 {0x31, AC_VERB_SET_CONNECT_SEL, 0x0}, /* output sel: DAC 0x05 */
2316 {0x33, AC_VERB_SET_CONNECT_SEL, 0x0},
2317 /* Port-E mic-in/CLFE path - 6ch mode as default */
2318 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2319 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2320 {0x3c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
2321 {0x32, AC_VERB_SET_CONNECT_SEL, 0x1}, /* output sel: DAC 0x0a */
2322 {0x34, AC_VERB_SET_CONNECT_SEL, 0x0},
2323 /* mute analog mix */
2324 {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
2325 {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
2326 {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
2327 {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
2328 {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
2329 {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)},
2330 {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)},
2331 {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)},
2332 /* select ADCs - front-mic */
2333 {0x0c, AC_VERB_SET_CONNECT_SEL, 0x1},
2334 {0x0d, AC_VERB_SET_CONNECT_SEL, 0x1},
2335 {0x0e, AC_VERB_SET_CONNECT_SEL, 0x1},
2336 /* ADCs; muted */
2337 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2338 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2339 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2340 { }
2341 };
2342
2343 /*
2344 * verbs for laptop mode (+dig)
2345 */
2346 static struct hda_verb ad1988_laptop_hp_on[] = {
2347 /* unmute port-A and mute port-D */
2348 { 0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
2349 { 0x12, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
2350 { } /* end */
2351 };
2352 static struct hda_verb ad1988_laptop_hp_off[] = {
2353 /* mute port-A and unmute port-D */
2354 { 0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
2355 { 0x12, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
2356 { } /* end */
2357 };
2358
2359 #define AD1988_HP_EVENT 0x01
2360
2361 static struct hda_verb ad1988_laptop_init_verbs[] = {
2362 /* Front, Surround, CLFE, side DAC; unmute as default */
2363 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2364 {0x06, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2365 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2366 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2367 /* Port-A front headphon path */
2368 {0x37, AC_VERB_SET_CONNECT_SEL, 0x01}, /* DAC1:04h */
2369 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
2370 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
2371 {0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2372 {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
2373 /* unsolicited event for pin-sense */
2374 {0x11, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | AD1988_HP_EVENT },
2375 /* Port-D line-out path + EAPD */
2376 {0x29, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
2377 {0x29, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
2378 {0x12, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2379 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2380 {0x12, AC_VERB_SET_EAPD_BTLENABLE, 0x00}, /* EAPD-off */
2381 /* Mono out path */
2382 {0x36, AC_VERB_SET_CONNECT_SEL, 0x1}, /* DAC1:04h */
2383 {0x1e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
2384 {0x1e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
2385 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2386 {0x13, AC_VERB_SET_AMP_GAIN_MUTE, 0xb01f}, /* unmute, 0dB */
2387 /* Port-B mic-in path */
2388 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2389 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2390 {0x39, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
2391 /* Port-C docking station - try to output */
2392 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2393 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2394 {0x3a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
2395 {0x33, AC_VERB_SET_CONNECT_SEL, 0x0},
2396 /* mute analog mix */
2397 {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
2398 {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
2399 {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
2400 {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
2401 {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
2402 {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)},
2403 {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)},
2404 {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)},
2405 /* select ADCs - mic */
2406 {0x0c, AC_VERB_SET_CONNECT_SEL, 0x1},
2407 {0x0d, AC_VERB_SET_CONNECT_SEL, 0x1},
2408 {0x0e, AC_VERB_SET_CONNECT_SEL, 0x1},
2409 /* ADCs; muted */
2410 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2411 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2412 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2413 { }
2414 };
2415
2416 static void ad1988_laptop_unsol_event(struct hda_codec *codec, unsigned int res)
2417 {
2418 if ((res >> 26) != AD1988_HP_EVENT)
2419 return;
2420 if (snd_hda_codec_read(codec, 0x11, 0, AC_VERB_GET_PIN_SENSE, 0) & (1 << 31))
2421 snd_hda_sequence_write(codec, ad1988_laptop_hp_on);
2422 else
2423 snd_hda_sequence_write(codec, ad1988_laptop_hp_off);
2424 }
2425
2426 #ifdef CONFIG_SND_HDA_POWER_SAVE
2427 static struct hda_amp_list ad1988_loopbacks[] = {
2428 { 0x20, HDA_INPUT, 0 }, /* Front Mic */
2429 { 0x20, HDA_INPUT, 1 }, /* Line */
2430 { 0x20, HDA_INPUT, 4 }, /* Mic */
2431 { 0x20, HDA_INPUT, 6 }, /* CD */
2432 { } /* end */
2433 };
2434 #endif
2435
2436 /*
2437 * Automatic parse of I/O pins from the BIOS configuration
2438 */
2439
2440 #define NUM_CONTROL_ALLOC 32
2441 #define NUM_VERB_ALLOC 32
2442
2443 enum {
2444 AD_CTL_WIDGET_VOL,
2445 AD_CTL_WIDGET_MUTE,
2446 AD_CTL_BIND_MUTE,
2447 };
2448 static struct snd_kcontrol_new ad1988_control_templates[] = {
2449 HDA_CODEC_VOLUME(NULL, 0, 0, 0),
2450 HDA_CODEC_MUTE(NULL, 0, 0, 0),
2451 HDA_BIND_MUTE(NULL, 0, 0, 0),
2452 };
2453
2454 /* add dynamic controls */
2455 static int add_control(struct ad198x_spec *spec, int type, const char *name,
2456 unsigned long val)
2457 {
2458 struct snd_kcontrol_new *knew;
2459
2460 if (spec->num_kctl_used >= spec->num_kctl_alloc) {
2461 int num = spec->num_kctl_alloc + NUM_CONTROL_ALLOC;
2462
2463 knew = kcalloc(num + 1, sizeof(*knew), GFP_KERNEL); /* array + terminator */
2464 if (! knew)
2465 return -ENOMEM;
2466 if (spec->kctl_alloc) {
2467 memcpy(knew, spec->kctl_alloc, sizeof(*knew) * spec->num_kctl_alloc);
2468 kfree(spec->kctl_alloc);
2469 }
2470 spec->kctl_alloc = knew;
2471 spec->num_kctl_alloc = num;
2472 }
2473
2474 knew = &spec->kctl_alloc[spec->num_kctl_used];
2475 *knew = ad1988_control_templates[type];
2476 knew->name = kstrdup(name, GFP_KERNEL);
2477 if (! knew->name)
2478 return -ENOMEM;
2479 knew->private_value = val;
2480 spec->num_kctl_used++;
2481 return 0;
2482 }
2483
2484 #define AD1988_PIN_CD_NID 0x18
2485 #define AD1988_PIN_BEEP_NID 0x10
2486
2487 static hda_nid_t ad1988_mixer_nids[8] = {
2488 /* A B C D E F G H */
2489 0x22, 0x2b, 0x2c, 0x29, 0x26, 0x2a, 0x27, 0x28
2490 };
2491
2492 static inline hda_nid_t ad1988_idx_to_dac(struct hda_codec *codec, int idx)
2493 {
2494 static hda_nid_t idx_to_dac[8] = {
2495 /* A B C D E F G H */
2496 0x04, 0x06, 0x05, 0x04, 0x0a, 0x06, 0x05, 0x0a
2497 };
2498 static hda_nid_t idx_to_dac_rev2[8] = {
2499 /* A B C D E F G H */
2500 0x04, 0x05, 0x0a, 0x04, 0x06, 0x05, 0x0a, 0x06
2501 };
2502 if (is_rev2(codec))
2503 return idx_to_dac_rev2[idx];
2504 else
2505 return idx_to_dac[idx];
2506 }
2507
2508 static hda_nid_t ad1988_boost_nids[8] = {
2509 0x38, 0x39, 0x3a, 0x3d, 0x3c, 0x3b, 0, 0
2510 };
2511
2512 static int ad1988_pin_idx(hda_nid_t nid)
2513 {
2514 static hda_nid_t ad1988_io_pins[8] = {
2515 0x11, 0x14, 0x15, 0x12, 0x17, 0x16, 0x24, 0x25
2516 };
2517 int i;
2518 for (i = 0; i < ARRAY_SIZE(ad1988_io_pins); i++)
2519 if (ad1988_io_pins[i] == nid)
2520 return i;
2521 return 0; /* should be -1 */
2522 }
2523
2524 static int ad1988_pin_to_loopback_idx(hda_nid_t nid)
2525 {
2526 static int loopback_idx[8] = {
2527 2, 0, 1, 3, 4, 5, 1, 4
2528 };
2529 switch (nid) {
2530 case AD1988_PIN_CD_NID:
2531 return 6;
2532 default:
2533 return loopback_idx[ad1988_pin_idx(nid)];
2534 }
2535 }
2536
2537 static int ad1988_pin_to_adc_idx(hda_nid_t nid)
2538 {
2539 static int adc_idx[8] = {
2540 0, 1, 2, 8, 4, 3, 6, 7
2541 };
2542 switch (nid) {
2543 case AD1988_PIN_CD_NID:
2544 return 5;
2545 default:
2546 return adc_idx[ad1988_pin_idx(nid)];
2547 }
2548 }
2549
2550 /* fill in the dac_nids table from the parsed pin configuration */
2551 static int ad1988_auto_fill_dac_nids(struct hda_codec *codec,
2552 const struct auto_pin_cfg *cfg)
2553 {
2554 struct ad198x_spec *spec = codec->spec;
2555 int i, idx;
2556
2557 spec->multiout.dac_nids = spec->private_dac_nids;
2558
2559 /* check the pins hardwired to audio widget */
2560 for (i = 0; i < cfg->line_outs; i++) {
2561 idx = ad1988_pin_idx(cfg->line_out_pins[i]);
2562 spec->multiout.dac_nids[i] = ad1988_idx_to_dac(codec, idx);
2563 }
2564 spec->multiout.num_dacs = cfg->line_outs;
2565 return 0;
2566 }
2567
2568 /* add playback controls from the parsed DAC table */
2569 static int ad1988_auto_create_multi_out_ctls(struct ad198x_spec *spec,
2570 const struct auto_pin_cfg *cfg)
2571 {
2572 char name[32];
2573 static const char *chname[4] = { "Front", "Surround", NULL /*CLFE*/, "Side" };
2574 hda_nid_t nid;
2575 int i, err;
2576
2577 for (i = 0; i < cfg->line_outs; i++) {
2578 hda_nid_t dac = spec->multiout.dac_nids[i];
2579 if (! dac)
2580 continue;
2581 nid = ad1988_mixer_nids[ad1988_pin_idx(cfg->line_out_pins[i])];
2582 if (i == 2) {
2583 /* Center/LFE */
2584 err = add_control(spec, AD_CTL_WIDGET_VOL,
2585 "Center Playback Volume",
2586 HDA_COMPOSE_AMP_VAL(dac, 1, 0, HDA_OUTPUT));
2587 if (err < 0)
2588 return err;
2589 err = add_control(spec, AD_CTL_WIDGET_VOL,
2590 "LFE Playback Volume",
2591 HDA_COMPOSE_AMP_VAL(dac, 2, 0, HDA_OUTPUT));
2592 if (err < 0)
2593 return err;
2594 err = add_control(spec, AD_CTL_BIND_MUTE,
2595 "Center Playback Switch",
2596 HDA_COMPOSE_AMP_VAL(nid, 1, 2, HDA_INPUT));
2597 if (err < 0)
2598 return err;
2599 err = add_control(spec, AD_CTL_BIND_MUTE,
2600 "LFE Playback Switch",
2601 HDA_COMPOSE_AMP_VAL(nid, 2, 2, HDA_INPUT));
2602 if (err < 0)
2603 return err;
2604 } else {
2605 sprintf(name, "%s Playback Volume", chname[i]);
2606 err = add_control(spec, AD_CTL_WIDGET_VOL, name,
2607 HDA_COMPOSE_AMP_VAL(dac, 3, 0, HDA_OUTPUT));
2608 if (err < 0)
2609 return err;
2610 sprintf(name, "%s Playback Switch", chname[i]);
2611 err = add_control(spec, AD_CTL_BIND_MUTE, name,
2612 HDA_COMPOSE_AMP_VAL(nid, 3, 2, HDA_INPUT));
2613 if (err < 0)
2614 return err;
2615 }
2616 }
2617 return 0;
2618 }
2619
2620 /* add playback controls for speaker and HP outputs */
2621 static int ad1988_auto_create_extra_out(struct hda_codec *codec, hda_nid_t pin,
2622 const char *pfx)
2623 {
2624 struct ad198x_spec *spec = codec->spec;
2625 hda_nid_t nid;
2626 int i, idx, err;
2627 char name[32];
2628
2629 if (! pin)
2630 return 0;
2631
2632 idx = ad1988_pin_idx(pin);
2633 nid = ad1988_idx_to_dac(codec, idx);
2634 /* check whether the corresponding DAC was already taken */
2635 for (i = 0; i < spec->autocfg.line_outs; i++) {
2636 hda_nid_t pin = spec->autocfg.line_out_pins[i];
2637 hda_nid_t dac = ad1988_idx_to_dac(codec, ad1988_pin_idx(pin));
2638 if (dac == nid)
2639 break;
2640 }
2641 if (i >= spec->autocfg.line_outs) {
2642 /* specify the DAC as the extra output */
2643 if (!spec->multiout.hp_nid)
2644 spec->multiout.hp_nid = nid;
2645 else
2646 spec->multiout.extra_out_nid[0] = nid;
2647 /* control HP volume/switch on the output mixer amp */
2648 sprintf(name, "%s Playback Volume", pfx);
2649 err = add_control(spec, AD_CTL_WIDGET_VOL, name,
2650 HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT));
2651 if (err < 0)
2652 return err;
2653 }
2654 nid = ad1988_mixer_nids[idx];
2655 sprintf(name, "%s Playback Switch", pfx);
2656 if ((err = add_control(spec, AD_CTL_BIND_MUTE, name,
2657 HDA_COMPOSE_AMP_VAL(nid, 3, 2, HDA_INPUT))) < 0)
2658 return err;
2659 return 0;
2660 }
2661
2662 /* create input playback/capture controls for the given pin */
2663 static int new_analog_input(struct ad198x_spec *spec, hda_nid_t pin,
2664 const char *ctlname, int boost)
2665 {
2666 char name[32];
2667 int err, idx;
2668
2669 sprintf(name, "%s Playback Volume", ctlname);
2670 idx = ad1988_pin_to_loopback_idx(pin);
2671 if ((err = add_control(spec, AD_CTL_WIDGET_VOL, name,
2672 HDA_COMPOSE_AMP_VAL(0x20, 3, idx, HDA_INPUT))) < 0)
2673 return err;
2674 sprintf(name, "%s Playback Switch", ctlname);
2675 if ((err = add_control(spec, AD_CTL_WIDGET_MUTE, name,
2676 HDA_COMPOSE_AMP_VAL(0x20, 3, idx, HDA_INPUT))) < 0)
2677 return err;
2678 if (boost) {
2679 hda_nid_t bnid;
2680 idx = ad1988_pin_idx(pin);
2681 bnid = ad1988_boost_nids[idx];
2682 if (bnid) {
2683 sprintf(name, "%s Boost", ctlname);
2684 return add_control(spec, AD_CTL_WIDGET_VOL, name,
2685 HDA_COMPOSE_AMP_VAL(bnid, 3, idx, HDA_OUTPUT));
2686
2687 }
2688 }
2689 return 0;
2690 }
2691
2692 /* create playback/capture controls for input pins */
2693 static int ad1988_auto_create_analog_input_ctls(struct ad198x_spec *spec,
2694 const struct auto_pin_cfg *cfg)
2695 {
2696 struct hda_input_mux *imux = &spec->private_imux;
2697 int i, err;
2698
2699 for (i = 0; i < AUTO_PIN_LAST; i++) {
2700 err = new_analog_input(spec, cfg->input_pins[i],
2701 auto_pin_cfg_labels[i],
2702 i <= AUTO_PIN_FRONT_MIC);
2703 if (err < 0)
2704 return err;
2705 imux->items[imux->num_items].label = auto_pin_cfg_labels[i];
2706 imux->items[imux->num_items].index = ad1988_pin_to_adc_idx(cfg->input_pins[i]);
2707 imux->num_items++;
2708 }
2709 imux->items[imux->num_items].label = "Mix";
2710 imux->items[imux->num_items].index = 9;
2711 imux->num_items++;
2712
2713 if ((err = add_control(spec, AD_CTL_WIDGET_VOL,
2714 "Analog Mix Playback Volume",
2715 HDA_COMPOSE_AMP_VAL(0x21, 3, 0x0, HDA_OUTPUT))) < 0)
2716 return err;
2717 if ((err = add_control(spec, AD_CTL_WIDGET_MUTE,
2718 "Analog Mix Playback Switch",
2719 HDA_COMPOSE_AMP_VAL(0x21, 3, 0x0, HDA_OUTPUT))) < 0)
2720 return err;
2721
2722 return 0;
2723 }
2724
2725 static void ad1988_auto_set_output_and_unmute(struct hda_codec *codec,
2726 hda_nid_t nid, int pin_type,
2727 int dac_idx)
2728 {
2729 /* set as output */
2730 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_PIN_WIDGET_CONTROL, pin_type);
2731 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE);
2732 switch (nid) {
2733 case 0x11: /* port-A - DAC 04 */
2734 snd_hda_codec_write(codec, 0x37, 0, AC_VERB_SET_CONNECT_SEL, 0x01);
2735 break;
2736 case 0x14: /* port-B - DAC 06 */
2737 snd_hda_codec_write(codec, 0x30, 0, AC_VERB_SET_CONNECT_SEL, 0x02);
2738 break;
2739 case 0x15: /* port-C - DAC 05 */
2740 snd_hda_codec_write(codec, 0x31, 0, AC_VERB_SET_CONNECT_SEL, 0x00);
2741 break;
2742 case 0x17: /* port-E - DAC 0a */
2743 snd_hda_codec_write(codec, 0x32, 0, AC_VERB_SET_CONNECT_SEL, 0x01);
2744 break;
2745 case 0x13: /* mono - DAC 04 */
2746 snd_hda_codec_write(codec, 0x36, 0, AC_VERB_SET_CONNECT_SEL, 0x01);
2747 break;
2748 }
2749 }
2750
2751 static void ad1988_auto_init_multi_out(struct hda_codec *codec)
2752 {
2753 struct ad198x_spec *spec = codec->spec;
2754 int i;
2755
2756 for (i = 0; i < spec->autocfg.line_outs; i++) {
2757 hda_nid_t nid = spec->autocfg.line_out_pins[i];
2758 ad1988_auto_set_output_and_unmute(codec, nid, PIN_OUT, i);
2759 }
2760 }
2761
2762 static void ad1988_auto_init_extra_out(struct hda_codec *codec)
2763 {
2764 struct ad198x_spec *spec = codec->spec;
2765 hda_nid_t pin;
2766
2767 pin = spec->autocfg.speaker_pins[0];
2768 if (pin) /* connect to front */
2769 ad1988_auto_set_output_and_unmute(codec, pin, PIN_OUT, 0);
2770 pin = spec->autocfg.hp_pins[0];
2771 if (pin) /* connect to front */
2772 ad1988_auto_set_output_and_unmute(codec, pin, PIN_HP, 0);
2773 }
2774
2775 static void ad1988_auto_init_analog_input(struct hda_codec *codec)
2776 {
2777 struct ad198x_spec *spec = codec->spec;
2778 int i, idx;
2779
2780 for (i = 0; i < AUTO_PIN_LAST; i++) {
2781 hda_nid_t nid = spec->autocfg.input_pins[i];
2782 if (! nid)
2783 continue;
2784 switch (nid) {
2785 case 0x15: /* port-C */
2786 snd_hda_codec_write(codec, 0x33, 0, AC_VERB_SET_CONNECT_SEL, 0x0);
2787 break;
2788 case 0x17: /* port-E */
2789 snd_hda_codec_write(codec, 0x34, 0, AC_VERB_SET_CONNECT_SEL, 0x0);
2790 break;
2791 }
2792 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
2793 i <= AUTO_PIN_FRONT_MIC ? PIN_VREF80 : PIN_IN);
2794 if (nid != AD1988_PIN_CD_NID)
2795 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_AMP_GAIN_MUTE,
2796 AMP_OUT_MUTE);
2797 idx = ad1988_pin_idx(nid);
2798 if (ad1988_boost_nids[idx])
2799 snd_hda_codec_write(codec, ad1988_boost_nids[idx], 0,
2800 AC_VERB_SET_AMP_GAIN_MUTE,
2801 AMP_OUT_ZERO);
2802 }
2803 }
2804
2805 /* parse the BIOS configuration and set up the alc_spec */
2806 /* return 1 if successful, 0 if the proper config is not found, or a negative error code */
2807 static int ad1988_parse_auto_config(struct hda_codec *codec)
2808 {
2809 struct ad198x_spec *spec = codec->spec;
2810 int err;
2811
2812 if ((err = snd_hda_parse_pin_def_config(codec, &spec->autocfg, NULL)) < 0)
2813 return err;
2814 if ((err = ad1988_auto_fill_dac_nids(codec, &spec->autocfg)) < 0)
2815 return err;
2816 if (! spec->autocfg.line_outs)
2817 return 0; /* can't find valid BIOS pin config */
2818 if ((err = ad1988_auto_create_multi_out_ctls(spec, &spec->autocfg)) < 0 ||
2819 (err = ad1988_auto_create_extra_out(codec,
2820 spec->autocfg.speaker_pins[0],
2821 "Speaker")) < 0 ||
2822 (err = ad1988_auto_create_extra_out(codec, spec->autocfg.hp_pins[0],
2823 "Headphone")) < 0 ||
2824 (err = ad1988_auto_create_analog_input_ctls(spec, &spec->autocfg)) < 0)
2825 return err;
2826
2827 spec->multiout.max_channels = spec->multiout.num_dacs * 2;
2828
2829 if (spec->autocfg.dig_out_pin)
2830 spec->multiout.dig_out_nid = AD1988_SPDIF_OUT;
2831 if (spec->autocfg.dig_in_pin)
2832 spec->dig_in_nid = AD1988_SPDIF_IN;
2833
2834 if (spec->kctl_alloc)
2835 spec->mixers[spec->num_mixers++] = spec->kctl_alloc;
2836
2837 spec->init_verbs[spec->num_init_verbs++] = ad1988_6stack_init_verbs;
2838
2839 spec->input_mux = &spec->private_imux;
2840
2841 return 1;
2842 }
2843
2844 /* init callback for auto-configuration model -- overriding the default init */
2845 static int ad1988_auto_init(struct hda_codec *codec)
2846 {
2847 ad198x_init(codec);
2848 ad1988_auto_init_multi_out(codec);
2849 ad1988_auto_init_extra_out(codec);
2850 ad1988_auto_init_analog_input(codec);
2851 return 0;
2852 }
2853
2854
2855 /*
2856 */
2857
2858 static const char *ad1988_models[AD1988_MODEL_LAST] = {
2859 [AD1988_6STACK] = "6stack",
2860 [AD1988_6STACK_DIG] = "6stack-dig",
2861 [AD1988_3STACK] = "3stack",
2862 [AD1988_3STACK_DIG] = "3stack-dig",
2863 [AD1988_LAPTOP] = "laptop",
2864 [AD1988_LAPTOP_DIG] = "laptop-dig",
2865 [AD1988_AUTO] = "auto",
2866 };
2867
2868 static struct snd_pci_quirk ad1988_cfg_tbl[] = {
2869 SND_PCI_QUIRK(0x1043, 0x81ec, "Asus P5B-DLX", AD1988_6STACK_DIG),
2870 SND_PCI_QUIRK(0x1043, 0x81f6, "Asus M2N-SLI", AD1988_6STACK_DIG),
2871 SND_PCI_QUIRK(0x1043, 0x8277, "Asus P5K-E/WIFI-AP", AD1988_6STACK_DIG),
2872 {}
2873 };
2874
2875 static int patch_ad1988(struct hda_codec *codec)
2876 {
2877 struct ad198x_spec *spec;
2878 int board_config;
2879
2880 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
2881 if (spec == NULL)
2882 return -ENOMEM;
2883
2884 codec->spec = spec;
2885
2886 if (is_rev2(codec))
2887 snd_printk(KERN_INFO "patch_analog: AD1988A rev.2 is detected, enable workarounds\n");
2888
2889 board_config = snd_hda_check_board_config(codec, AD1988_MODEL_LAST,
2890 ad1988_models, ad1988_cfg_tbl);
2891 if (board_config < 0) {
2892 printk(KERN_INFO "hda_codec: Unknown model for AD1988, trying auto-probe from BIOS...\n");
2893 board_config = AD1988_AUTO;
2894 }
2895
2896 if (board_config == AD1988_AUTO) {
2897 /* automatic parse from the BIOS config */
2898 int err = ad1988_parse_auto_config(codec);
2899 if (err < 0) {
2900 ad198x_free(codec);
2901 return err;
2902 } else if (! err) {
2903 printk(KERN_INFO "hda_codec: Cannot set up configuration from BIOS. Using 6-stack mode...\n");
2904 board_config = AD1988_6STACK;
2905 }
2906 }
2907
2908 switch (board_config) {
2909 case AD1988_6STACK:
2910 case AD1988_6STACK_DIG:
2911 spec->multiout.max_channels = 8;
2912 spec->multiout.num_dacs = 4;
2913 if (is_rev2(codec))
2914 spec->multiout.dac_nids = ad1988_6stack_dac_nids_rev2;
2915 else
2916 spec->multiout.dac_nids = ad1988_6stack_dac_nids;
2917 spec->input_mux = &ad1988_6stack_capture_source;
2918 spec->num_mixers = 2;
2919 if (is_rev2(codec))
2920 spec->mixers[0] = ad1988_6stack_mixers1_rev2;
2921 else
2922 spec->mixers[0] = ad1988_6stack_mixers1;
2923 spec->mixers[1] = ad1988_6stack_mixers2;
2924 spec->num_init_verbs = 1;
2925 spec->init_verbs[0] = ad1988_6stack_init_verbs;
2926 if (board_config == AD1988_6STACK_DIG) {
2927 spec->multiout.dig_out_nid = AD1988_SPDIF_OUT;
2928 spec->dig_in_nid = AD1988_SPDIF_IN;
2929 }
2930 break;
2931 case AD1988_3STACK:
2932 case AD1988_3STACK_DIG:
2933 spec->multiout.max_channels = 6;
2934 spec->multiout.num_dacs = 3;
2935 if (is_rev2(codec))
2936 spec->multiout.dac_nids = ad1988_3stack_dac_nids_rev2;
2937 else
2938 spec->multiout.dac_nids = ad1988_3stack_dac_nids;
2939 spec->input_mux = &ad1988_6stack_capture_source;
2940 spec->channel_mode = ad1988_3stack_modes;
2941 spec->num_channel_mode = ARRAY_SIZE(ad1988_3stack_modes);
2942 spec->num_mixers = 2;
2943 if (is_rev2(codec))
2944 spec->mixers[0] = ad1988_3stack_mixers1_rev2;
2945 else
2946 spec->mixers[0] = ad1988_3stack_mixers1;
2947 spec->mixers[1] = ad1988_3stack_mixers2;
2948 spec->num_init_verbs = 1;
2949 spec->init_verbs[0] = ad1988_3stack_init_verbs;
2950 if (board_config == AD1988_3STACK_DIG)
2951 spec->multiout.dig_out_nid = AD1988_SPDIF_OUT;
2952 break;
2953 case AD1988_LAPTOP:
2954 case AD1988_LAPTOP_DIG:
2955 spec->multiout.max_channels = 2;
2956 spec->multiout.num_dacs = 1;
2957 spec->multiout.dac_nids = ad1988_3stack_dac_nids;
2958 spec->input_mux = &ad1988_laptop_capture_source;
2959 spec->num_mixers = 1;
2960 spec->mixers[0] = ad1988_laptop_mixers;
2961 spec->num_init_verbs = 1;
2962 spec->init_verbs[0] = ad1988_laptop_init_verbs;
2963 if (board_config == AD1988_LAPTOP_DIG)
2964 spec->multiout.dig_out_nid = AD1988_SPDIF_OUT;
2965 break;
2966 }
2967
2968 spec->num_adc_nids = ARRAY_SIZE(ad1988_adc_nids);
2969 spec->adc_nids = ad1988_adc_nids;
2970 spec->capsrc_nids = ad1988_capsrc_nids;
2971 spec->mixers[spec->num_mixers++] = ad1988_capture_mixers;
2972 spec->init_verbs[spec->num_init_verbs++] = ad1988_capture_init_verbs;
2973 if (spec->multiout.dig_out_nid) {
2974 if (codec->vendor_id >= 0x11d4989a) {
2975 spec->mixers[spec->num_mixers++] =
2976 ad1989_spdif_out_mixers;
2977 spec->init_verbs[spec->num_init_verbs++] =
2978 ad1989_spdif_init_verbs;
2979 } else {
2980 spec->mixers[spec->num_mixers++] =
2981 ad1988_spdif_out_mixers;
2982 spec->init_verbs[spec->num_init_verbs++] =
2983 ad1988_spdif_init_verbs;
2984 }
2985 }
2986 if (spec->dig_in_nid && codec->vendor_id < 0x11d4989a)
2987 spec->mixers[spec->num_mixers++] = ad1988_spdif_in_mixers;
2988
2989 codec->patch_ops = ad198x_patch_ops;
2990 switch (board_config) {
2991 case AD1988_AUTO:
2992 codec->patch_ops.init = ad1988_auto_init;
2993 break;
2994 case AD1988_LAPTOP:
2995 case AD1988_LAPTOP_DIG:
2996 codec->patch_ops.unsol_event = ad1988_laptop_unsol_event;
2997 break;
2998 }
2999 #ifdef CONFIG_SND_HDA_POWER_SAVE
3000 spec->loopback.amplist = ad1988_loopbacks;
3001 #endif
3002 spec->vmaster_nid = 0x04;
3003
3004 return 0;
3005 }
3006
3007
3008 /*
3009 * AD1884 / AD1984
3010 *
3011 * port-B - front line/mic-in
3012 * port-E - aux in/out
3013 * port-F - aux in/out
3014 * port-C - rear line/mic-in
3015 * port-D - rear line/hp-out
3016 * port-A - front line/hp-out
3017 *
3018 * AD1984 = AD1884 + two digital mic-ins
3019 *
3020 * FIXME:
3021 * For simplicity, we share the single DAC for both HP and line-outs
3022 * right now. The inidividual playbacks could be easily implemented,
3023 * but no build-up framework is given, so far.
3024 */
3025
3026 static hda_nid_t ad1884_dac_nids[1] = {
3027 0x04,
3028 };
3029
3030 static hda_nid_t ad1884_adc_nids[2] = {
3031 0x08, 0x09,
3032 };
3033
3034 static hda_nid_t ad1884_capsrc_nids[2] = {
3035 0x0c, 0x0d,
3036 };
3037
3038 #define AD1884_SPDIF_OUT 0x02
3039
3040 static struct hda_input_mux ad1884_capture_source = {
3041 .num_items = 4,
3042 .items = {
3043 { "Front Mic", 0x0 },
3044 { "Mic", 0x1 },
3045 { "CD", 0x2 },
3046 { "Mix", 0x3 },
3047 },
3048 };
3049
3050 static struct snd_kcontrol_new ad1884_base_mixers[] = {
3051 HDA_CODEC_VOLUME("PCM Playback Volume", 0x04, 0x0, HDA_OUTPUT),
3052 /* HDA_CODEC_VOLUME_IDX("PCM Playback Volume", 1, 0x03, 0x0, HDA_OUTPUT), */
3053 HDA_CODEC_MUTE("Headphone Playback Switch", 0x11, 0x0, HDA_OUTPUT),
3054 HDA_CODEC_MUTE("Front Playback Switch", 0x12, 0x0, HDA_OUTPUT),
3055 HDA_CODEC_VOLUME_MONO("Mono Playback Volume", 0x13, 1, 0x0, HDA_OUTPUT),
3056 HDA_CODEC_MUTE_MONO("Mono Playback Switch", 0x13, 1, 0x0, HDA_OUTPUT),
3057 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x20, 0x00, HDA_INPUT),
3058 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x20, 0x00, HDA_INPUT),
3059 HDA_CODEC_VOLUME("Mic Playback Volume", 0x20, 0x01, HDA_INPUT),
3060 HDA_CODEC_MUTE("Mic Playback Switch", 0x20, 0x01, HDA_INPUT),
3061 HDA_CODEC_VOLUME("CD Playback Volume", 0x20, 0x02, HDA_INPUT),
3062 HDA_CODEC_MUTE("CD Playback Switch", 0x20, 0x02, HDA_INPUT),
3063 /*
3064 HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x20, 0x03, HDA_INPUT),
3065 HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x20, 0x03, HDA_INPUT),
3066 HDA_CODEC_VOLUME("Digital Beep Playback Volume", 0x10, 0x0, HDA_OUTPUT),
3067 HDA_CODEC_MUTE("Digital Beep Playback Switch", 0x10, 0x0, HDA_OUTPUT),
3068 */
3069 HDA_CODEC_VOLUME("Mic Boost", 0x15, 0x0, HDA_INPUT),
3070 HDA_CODEC_VOLUME("Front Mic Boost", 0x14, 0x0, HDA_INPUT),
3071 HDA_CODEC_VOLUME("Capture Volume", 0x0c, 0x0, HDA_OUTPUT),
3072 HDA_CODEC_MUTE("Capture Switch", 0x0c, 0x0, HDA_OUTPUT),
3073 HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x0d, 0x0, HDA_OUTPUT),
3074 HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x0d, 0x0, HDA_OUTPUT),
3075 {
3076 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
3077 /* The multiple "Capture Source" controls confuse alsamixer
3078 * So call somewhat different..
3079 */
3080 /* .name = "Capture Source", */
3081 .name = "Input Source",
3082 .count = 2,
3083 .info = ad198x_mux_enum_info,
3084 .get = ad198x_mux_enum_get,
3085 .put = ad198x_mux_enum_put,
3086 },
3087 /* SPDIF controls */
3088 HDA_CODEC_VOLUME("IEC958 Playback Volume", 0x1b, 0x0, HDA_OUTPUT),
3089 {
3090 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
3091 .name = SNDRV_CTL_NAME_IEC958("",PLAYBACK,NONE) "Source",
3092 /* identical with ad1983 */
3093 .info = ad1983_spdif_route_info,
3094 .get = ad1983_spdif_route_get,
3095 .put = ad1983_spdif_route_put,
3096 },
3097 { } /* end */
3098 };
3099
3100 static struct snd_kcontrol_new ad1984_dmic_mixers[] = {
3101 HDA_CODEC_VOLUME("Digital Mic Capture Volume", 0x05, 0x0, HDA_INPUT),
3102 HDA_CODEC_MUTE("Digital Mic Capture Switch", 0x05, 0x0, HDA_INPUT),
3103 HDA_CODEC_VOLUME_IDX("Digital Mic Capture Volume", 1, 0x06, 0x0,
3104 HDA_INPUT),
3105 HDA_CODEC_MUTE_IDX("Digital Mic Capture Switch", 1, 0x06, 0x0,
3106 HDA_INPUT),
3107 { } /* end */
3108 };
3109
3110 /*
3111 * initialization verbs
3112 */
3113 static struct hda_verb ad1884_init_verbs[] = {
3114 /* DACs; mute as default */
3115 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
3116 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
3117 /* Port-A (HP) mixer */
3118 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
3119 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
3120 /* Port-A pin */
3121 {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
3122 {0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3123 /* HP selector - select DAC2 */
3124 {0x22, AC_VERB_SET_CONNECT_SEL, 0x1},
3125 /* Port-D (Line-out) mixer */
3126 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
3127 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
3128 /* Port-D pin */
3129 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
3130 {0x12, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3131 /* Mono-out mixer */
3132 {0x1e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
3133 {0x1e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
3134 /* Mono-out pin */
3135 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
3136 {0x13, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3137 /* Mono selector */
3138 {0x0e, AC_VERB_SET_CONNECT_SEL, 0x1},
3139 /* Port-B (front mic) pin */
3140 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3141 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3142 /* Port-C (rear mic) pin */
3143 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3144 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3145 /* Analog mixer; mute as default */
3146 {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
3147 {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
3148 {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
3149 {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
3150 /* Analog Mix output amp */
3151 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE | 0x1f}, /* 0dB */
3152 /* SPDIF output selector */
3153 {0x02, AC_VERB_SET_CONNECT_SEL, 0x0}, /* PCM */
3154 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE | 0x27}, /* 0dB */
3155 { } /* end */
3156 };
3157
3158 #ifdef CONFIG_SND_HDA_POWER_SAVE
3159 static struct hda_amp_list ad1884_loopbacks[] = {
3160 { 0x20, HDA_INPUT, 0 }, /* Front Mic */
3161 { 0x20, HDA_INPUT, 1 }, /* Mic */
3162 { 0x20, HDA_INPUT, 2 }, /* CD */
3163 { 0x20, HDA_INPUT, 4 }, /* Docking */
3164 { } /* end */
3165 };
3166 #endif
3167
3168 static const char *ad1884_slave_vols[] = {
3169 "PCM Playback Volume",
3170 "Mic Playback Volume",
3171 "Mono Playback Volume",
3172 "Front Mic Playback Volume",
3173 "Mic Playback Volume",
3174 "CD Playback Volume",
3175 "Internal Mic Playback Volume",
3176 "Docking Mic Playback Volume"
3177 "Beep Playback Volume",
3178 "IEC958 Playback Volume",
3179 NULL
3180 };
3181
3182 static int patch_ad1884(struct hda_codec *codec)
3183 {
3184 struct ad198x_spec *spec;
3185
3186 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
3187 if (spec == NULL)
3188 return -ENOMEM;
3189
3190 codec->spec = spec;
3191
3192 spec->multiout.max_channels = 2;
3193 spec->multiout.num_dacs = ARRAY_SIZE(ad1884_dac_nids);
3194 spec->multiout.dac_nids = ad1884_dac_nids;
3195 spec->multiout.dig_out_nid = AD1884_SPDIF_OUT;
3196 spec->num_adc_nids = ARRAY_SIZE(ad1884_adc_nids);
3197 spec->adc_nids = ad1884_adc_nids;
3198 spec->capsrc_nids = ad1884_capsrc_nids;
3199 spec->input_mux = &ad1884_capture_source;
3200 spec->num_mixers = 1;
3201 spec->mixers[0] = ad1884_base_mixers;
3202 spec->num_init_verbs = 1;
3203 spec->init_verbs[0] = ad1884_init_verbs;
3204 spec->spdif_route = 0;
3205 #ifdef CONFIG_SND_HDA_POWER_SAVE
3206 spec->loopback.amplist = ad1884_loopbacks;
3207 #endif
3208 spec->vmaster_nid = 0x04;
3209 /* we need to cover all playback volumes */
3210 spec->slave_vols = ad1884_slave_vols;
3211
3212 codec->patch_ops = ad198x_patch_ops;
3213
3214 return 0;
3215 }
3216
3217 /*
3218 * Lenovo Thinkpad T61/X61
3219 */
3220 static struct hda_input_mux ad1984_thinkpad_capture_source = {
3221 .num_items = 4,
3222 .items = {
3223 { "Mic", 0x0 },
3224 { "Internal Mic", 0x1 },
3225 { "Mix", 0x3 },
3226 { "Docking-Station", 0x4 },
3227 },
3228 };
3229
3230
3231 /*
3232 * Dell Precision T3400
3233 */
3234 static struct hda_input_mux ad1984_dell_desktop_capture_source = {
3235 .num_items = 3,
3236 .items = {
3237 { "Front Mic", 0x0 },
3238 { "Line-In", 0x1 },
3239 { "Mix", 0x3 },
3240 },
3241 };
3242
3243
3244 static struct snd_kcontrol_new ad1984_thinkpad_mixers[] = {
3245 HDA_CODEC_VOLUME("PCM Playback Volume", 0x04, 0x0, HDA_OUTPUT),
3246 /* HDA_CODEC_VOLUME_IDX("PCM Playback Volume", 1, 0x03, 0x0, HDA_OUTPUT), */
3247 HDA_CODEC_MUTE("Headphone Playback Switch", 0x11, 0x0, HDA_OUTPUT),
3248 HDA_CODEC_MUTE("Speaker Playback Switch", 0x12, 0x0, HDA_OUTPUT),
3249 HDA_CODEC_VOLUME("Mic Playback Volume", 0x20, 0x00, HDA_INPUT),
3250 HDA_CODEC_MUTE("Mic Playback Switch", 0x20, 0x00, HDA_INPUT),
3251 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x20, 0x01, HDA_INPUT),
3252 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x20, 0x01, HDA_INPUT),
3253 HDA_CODEC_VOLUME("Docking Mic Playback Volume", 0x20, 0x04, HDA_INPUT),
3254 HDA_CODEC_MUTE("Docking Mic Playback Switch", 0x20, 0x04, HDA_INPUT),
3255 HDA_CODEC_VOLUME("Mic Boost", 0x14, 0x0, HDA_INPUT),
3256 HDA_CODEC_VOLUME("Internal Mic Boost", 0x15, 0x0, HDA_INPUT),
3257 HDA_CODEC_VOLUME("Docking Mic Boost", 0x25, 0x0, HDA_OUTPUT),
3258 HDA_CODEC_VOLUME("Beep Playback Volume", 0x20, 0x03, HDA_INPUT),
3259 HDA_CODEC_MUTE("Beep Playback Switch", 0x20, 0x03, HDA_INPUT),
3260 HDA_CODEC_VOLUME("Capture Volume", 0x0c, 0x0, HDA_OUTPUT),
3261 HDA_CODEC_MUTE("Capture Switch", 0x0c, 0x0, HDA_OUTPUT),
3262 HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x0d, 0x0, HDA_OUTPUT),
3263 HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x0d, 0x0, HDA_OUTPUT),
3264 {
3265 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
3266 /* The multiple "Capture Source" controls confuse alsamixer
3267 * So call somewhat different..
3268 */
3269 /* .name = "Capture Source", */
3270 .name = "Input Source",
3271 .count = 2,
3272 .info = ad198x_mux_enum_info,
3273 .get = ad198x_mux_enum_get,
3274 .put = ad198x_mux_enum_put,
3275 },
3276 /* SPDIF controls */
3277 HDA_CODEC_VOLUME("IEC958 Playback Volume", 0x1b, 0x0, HDA_OUTPUT),
3278 {
3279 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
3280 .name = SNDRV_CTL_NAME_IEC958("",PLAYBACK,NONE) "Source",
3281 /* identical with ad1983 */
3282 .info = ad1983_spdif_route_info,
3283 .get = ad1983_spdif_route_get,
3284 .put = ad1983_spdif_route_put,
3285 },
3286 { } /* end */
3287 };
3288
3289 /* additional verbs */
3290 static struct hda_verb ad1984_thinkpad_init_verbs[] = {
3291 /* Port-E (docking station mic) pin */
3292 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3293 {0x1c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3294 /* docking mic boost */
3295 {0x25, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3296 /* Analog mixer - docking mic; mute as default */
3297 {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
3298 /* enable EAPD bit */
3299 {0x12, AC_VERB_SET_EAPD_BTLENABLE, 0x02},
3300 { } /* end */
3301 };
3302
3303 /*
3304 * Dell Precision T3400
3305 */
3306 static struct snd_kcontrol_new ad1984_dell_desktop_mixers[] = {
3307 HDA_CODEC_VOLUME("PCM Playback Volume", 0x04, 0x0, HDA_OUTPUT),
3308 HDA_CODEC_MUTE("Headphone Playback Switch", 0x11, 0x0, HDA_OUTPUT),
3309 HDA_CODEC_MUTE("Speaker Playback Switch", 0x12, 0x0, HDA_OUTPUT),
3310 HDA_CODEC_VOLUME_MONO("Mono Playback Volume", 0x13, 1, 0x0, HDA_OUTPUT),
3311 HDA_CODEC_MUTE_MONO("Mono Playback Switch", 0x13, 1, 0x0, HDA_OUTPUT),
3312 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x20, 0x00, HDA_INPUT),
3313 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x20, 0x00, HDA_INPUT),
3314 HDA_CODEC_VOLUME("Line-In Playback Volume", 0x20, 0x01, HDA_INPUT),
3315 HDA_CODEC_MUTE("Line-In Playback Switch", 0x20, 0x01, HDA_INPUT),
3316 /*
3317 HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x20, 0x03, HDA_INPUT),
3318 HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x20, 0x03, HDA_INPUT),
3319 */
3320 HDA_CODEC_VOLUME("Line-In Boost", 0x15, 0x0, HDA_INPUT),
3321 HDA_CODEC_VOLUME("Front Mic Boost", 0x14, 0x0, HDA_INPUT),
3322 HDA_CODEC_VOLUME("Capture Volume", 0x0c, 0x0, HDA_OUTPUT),
3323 HDA_CODEC_MUTE("Capture Switch", 0x0c, 0x0, HDA_OUTPUT),
3324 HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x0d, 0x0, HDA_OUTPUT),
3325 HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x0d, 0x0, HDA_OUTPUT),
3326 {
3327 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
3328 /* The multiple "Capture Source" controls confuse alsamixer
3329 * So call somewhat different..
3330 */
3331 /* .name = "Capture Source", */
3332 .name = "Input Source",
3333 .count = 2,
3334 .info = ad198x_mux_enum_info,
3335 .get = ad198x_mux_enum_get,
3336 .put = ad198x_mux_enum_put,
3337 },
3338 { } /* end */
3339 };
3340
3341 /* Digial MIC ADC NID 0x05 + 0x06 */
3342 static int ad1984_pcm_dmic_prepare(struct hda_pcm_stream *hinfo,
3343 struct hda_codec *codec,
3344 unsigned int stream_tag,
3345 unsigned int format,
3346 struct snd_pcm_substream *substream)
3347 {
3348 snd_hda_codec_setup_stream(codec, 0x05 + substream->number,
3349 stream_tag, 0, format);
3350 return 0;
3351 }
3352
3353 static int ad1984_pcm_dmic_cleanup(struct hda_pcm_stream *hinfo,
3354 struct hda_codec *codec,
3355 struct snd_pcm_substream *substream)
3356 {
3357 snd_hda_codec_cleanup_stream(codec, 0x05 + substream->number);
3358 return 0;
3359 }
3360
3361 static struct hda_pcm_stream ad1984_pcm_dmic_capture = {
3362 .substreams = 2,
3363 .channels_min = 2,
3364 .channels_max = 2,
3365 .nid = 0x05,
3366 .ops = {
3367 .prepare = ad1984_pcm_dmic_prepare,
3368 .cleanup = ad1984_pcm_dmic_cleanup
3369 },
3370 };
3371
3372 static int ad1984_build_pcms(struct hda_codec *codec)
3373 {
3374 struct ad198x_spec *spec = codec->spec;
3375 struct hda_pcm *info;
3376 int err;
3377
3378 err = ad198x_build_pcms(codec);
3379 if (err < 0)
3380 return err;
3381
3382 info = spec->pcm_rec + codec->num_pcms;
3383 codec->num_pcms++;
3384 info->name = "AD1984 Digital Mic";
3385 info->stream[SNDRV_PCM_STREAM_CAPTURE] = ad1984_pcm_dmic_capture;
3386 return 0;
3387 }
3388
3389 /* models */
3390 enum {
3391 AD1984_BASIC,
3392 AD1984_THINKPAD,
3393 AD1984_DELL_DESKTOP,
3394 AD1984_MODELS
3395 };
3396
3397 static const char *ad1984_models[AD1984_MODELS] = {
3398 [AD1984_BASIC] = "basic",
3399 [AD1984_THINKPAD] = "thinkpad",
3400 [AD1984_DELL_DESKTOP] = "dell_desktop",
3401 };
3402
3403 static struct snd_pci_quirk ad1984_cfg_tbl[] = {
3404 /* Lenovo Thinkpad T61/X61 */
3405 SND_PCI_QUIRK(0x17aa, 0, "Lenovo Thinkpad", AD1984_THINKPAD),
3406 SND_PCI_QUIRK(0x1028, 0x0214, "Dell T3400", AD1984_DELL_DESKTOP),
3407 {}
3408 };
3409
3410 static int patch_ad1984(struct hda_codec *codec)
3411 {
3412 struct ad198x_spec *spec;
3413 int board_config, err;
3414
3415 err = patch_ad1884(codec);
3416 if (err < 0)
3417 return err;
3418 spec = codec->spec;
3419 board_config = snd_hda_check_board_config(codec, AD1984_MODELS,
3420 ad1984_models, ad1984_cfg_tbl);
3421 switch (board_config) {
3422 case AD1984_BASIC:
3423 /* additional digital mics */
3424 spec->mixers[spec->num_mixers++] = ad1984_dmic_mixers;
3425 codec->patch_ops.build_pcms = ad1984_build_pcms;
3426 break;
3427 case AD1984_THINKPAD:
3428 spec->multiout.dig_out_nid = AD1884_SPDIF_OUT;
3429 spec->input_mux = &ad1984_thinkpad_capture_source;
3430 spec->mixers[0] = ad1984_thinkpad_mixers;
3431 spec->init_verbs[spec->num_init_verbs++] = ad1984_thinkpad_init_verbs;
3432 break;
3433 case AD1984_DELL_DESKTOP:
3434 spec->multiout.dig_out_nid = 0;
3435 spec->input_mux = &ad1984_dell_desktop_capture_source;
3436 spec->mixers[0] = ad1984_dell_desktop_mixers;
3437 break;
3438 }
3439 return 0;
3440 }
3441
3442
3443 /*
3444 * AD1883 / AD1884A / AD1984A / AD1984B
3445 *
3446 * port-B (0x14) - front mic-in
3447 * port-E (0x1c) - rear mic-in
3448 * port-F (0x16) - CD / ext out
3449 * port-C (0x15) - rear line-in
3450 * port-D (0x12) - rear line-out
3451 * port-A (0x11) - front hp-out
3452 *
3453 * AD1984A = AD1884A + digital-mic
3454 * AD1883 = equivalent with AD1984A
3455 * AD1984B = AD1984A + extra SPDIF-out
3456 *
3457 * FIXME:
3458 * We share the single DAC for both HP and line-outs (see AD1884/1984).
3459 */
3460
3461 static hda_nid_t ad1884a_dac_nids[1] = {
3462 0x03,
3463 };
3464
3465 #define ad1884a_adc_nids ad1884_adc_nids
3466 #define ad1884a_capsrc_nids ad1884_capsrc_nids
3467
3468 #define AD1884A_SPDIF_OUT 0x02
3469
3470 static struct hda_input_mux ad1884a_capture_source = {
3471 .num_items = 5,
3472 .items = {
3473 { "Front Mic", 0x0 },
3474 { "Mic", 0x4 },
3475 { "Line", 0x1 },
3476 { "CD", 0x2 },
3477 { "Mix", 0x3 },
3478 },
3479 };
3480
3481 static struct snd_kcontrol_new ad1884a_base_mixers[] = {
3482 HDA_CODEC_VOLUME("Master Playback Volume", 0x21, 0x0, HDA_OUTPUT),
3483 HDA_CODEC_MUTE("Master Playback Switch", 0x21, 0x0, HDA_OUTPUT),
3484 HDA_CODEC_MUTE("Headphone Playback Switch", 0x11, 0x0, HDA_OUTPUT),
3485 HDA_CODEC_MUTE("Front Playback Switch", 0x12, 0x0, HDA_OUTPUT),
3486 HDA_CODEC_VOLUME_MONO("Mono Playback Volume", 0x13, 1, 0x0, HDA_OUTPUT),
3487 HDA_CODEC_MUTE_MONO("Mono Playback Switch", 0x13, 1, 0x0, HDA_OUTPUT),
3488 HDA_CODEC_VOLUME("PCM Playback Volume", 0x20, 0x5, HDA_INPUT),
3489 HDA_CODEC_MUTE("PCM Playback Switch", 0x20, 0x5, HDA_INPUT),
3490 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x20, 0x00, HDA_INPUT),
3491 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x20, 0x00, HDA_INPUT),
3492 HDA_CODEC_VOLUME("Line Playback Volume", 0x20, 0x01, HDA_INPUT),
3493 HDA_CODEC_MUTE("Line Playback Switch", 0x20, 0x01, HDA_INPUT),
3494 HDA_CODEC_VOLUME("Mic Playback Volume", 0x20, 0x04, HDA_INPUT),
3495 HDA_CODEC_MUTE("Mic Playback Switch", 0x20, 0x04, HDA_INPUT),
3496 HDA_CODEC_VOLUME("CD Playback Volume", 0x20, 0x02, HDA_INPUT),
3497 HDA_CODEC_MUTE("CD Playback Switch", 0x20, 0x02, HDA_INPUT),
3498 HDA_CODEC_VOLUME("Beep Playback Volume", 0x20, 0x03, HDA_INPUT),
3499 HDA_CODEC_MUTE("Beep Playback Switch", 0x20, 0x03, HDA_INPUT),
3500 HDA_CODEC_VOLUME("Front Mic Boost", 0x14, 0x0, HDA_INPUT),
3501 HDA_CODEC_VOLUME("Line Boost", 0x15, 0x0, HDA_INPUT),
3502 HDA_CODEC_VOLUME("Mic Boost", 0x25, 0x0, HDA_OUTPUT),
3503 HDA_CODEC_VOLUME("Capture Volume", 0x0c, 0x0, HDA_OUTPUT),
3504 HDA_CODEC_MUTE("Capture Switch", 0x0c, 0x0, HDA_OUTPUT),
3505 HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x0d, 0x0, HDA_OUTPUT),
3506 HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x0d, 0x0, HDA_OUTPUT),
3507 {
3508 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
3509 /* The multiple "Capture Source" controls confuse alsamixer
3510 * So call somewhat different..
3511 */
3512 /* .name = "Capture Source", */
3513 .name = "Input Source",
3514 .count = 2,
3515 .info = ad198x_mux_enum_info,
3516 .get = ad198x_mux_enum_get,
3517 .put = ad198x_mux_enum_put,
3518 },
3519 /* SPDIF controls */
3520 HDA_CODEC_VOLUME("IEC958 Playback Volume", 0x1b, 0x0, HDA_OUTPUT),
3521 {
3522 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
3523 .name = SNDRV_CTL_NAME_IEC958("",PLAYBACK,NONE) "Source",
3524 /* identical with ad1983 */
3525 .info = ad1983_spdif_route_info,
3526 .get = ad1983_spdif_route_get,
3527 .put = ad1983_spdif_route_put,
3528 },
3529 { } /* end */
3530 };
3531
3532 /*
3533 * initialization verbs
3534 */
3535 static struct hda_verb ad1884a_init_verbs[] = {
3536 /* DACs; unmute as default */
3537 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, 0x27}, /* 0dB */
3538 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, 0x27}, /* 0dB */
3539 /* Port-A (HP) mixer - route only from analog mixer */
3540 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
3541 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
3542 /* Port-A pin */
3543 {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
3544 {0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3545 /* Port-D (Line-out) mixer - route only from analog mixer */
3546 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
3547 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
3548 /* Port-D pin */
3549 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
3550 {0x12, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3551 /* Mono-out mixer - route only from analog mixer */
3552 {0x1e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
3553 {0x1e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
3554 /* Mono-out pin */
3555 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
3556 {0x13, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3557 /* Port-B (front mic) pin */
3558 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3559 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3560 /* Port-C (rear line-in) pin */
3561 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
3562 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3563 /* Port-E (rear mic) pin */
3564 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3565 {0x1c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3566 {0x25, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, /* no boost */
3567 /* Port-F (CD) pin */
3568 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
3569 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3570 /* Analog mixer; mute as default */
3571 {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
3572 {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
3573 {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
3574 {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
3575 {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(4)}, /* aux */
3576 {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)},
3577 /* Analog Mix output amp */
3578 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3579 /* capture sources */
3580 {0x0c, AC_VERB_SET_CONNECT_SEL, 0x0},
3581 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3582 {0x0d, AC_VERB_SET_CONNECT_SEL, 0x0},
3583 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3584 /* SPDIF output amp */
3585 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE | 0x27}, /* 0dB */
3586 { } /* end */
3587 };
3588
3589 #ifdef CONFIG_SND_HDA_POWER_SAVE
3590 static struct hda_amp_list ad1884a_loopbacks[] = {
3591 { 0x20, HDA_INPUT, 0 }, /* Front Mic */
3592 { 0x20, HDA_INPUT, 1 }, /* Mic */
3593 { 0x20, HDA_INPUT, 2 }, /* CD */
3594 { 0x20, HDA_INPUT, 4 }, /* Docking */
3595 { } /* end */
3596 };
3597 #endif
3598
3599 /*
3600 * Laptop model
3601 *
3602 * Port A: Headphone jack
3603 * Port B: MIC jack
3604 * Port C: Internal MIC
3605 * Port D: Dock Line Out (if enabled)
3606 * Port E: Dock Line In (if enabled)
3607 * Port F: Internal speakers
3608 */
3609
3610 static struct hda_input_mux ad1884a_laptop_capture_source = {
3611 .num_items = 4,
3612 .items = {
3613 { "Mic", 0x0 }, /* port-B */
3614 { "Internal Mic", 0x1 }, /* port-C */
3615 { "Dock Mic", 0x4 }, /* port-E */
3616 { "Mix", 0x3 },
3617 },
3618 };
3619
3620 static struct snd_kcontrol_new ad1884a_laptop_mixers[] = {
3621 HDA_CODEC_VOLUME("Master Playback Volume", 0x21, 0x0, HDA_OUTPUT),
3622 HDA_CODEC_MUTE("Master Playback Switch", 0x21, 0x0, HDA_OUTPUT),
3623 HDA_CODEC_MUTE("Dock Playback Switch", 0x12, 0x0, HDA_OUTPUT),
3624 HDA_CODEC_VOLUME("PCM Playback Volume", 0x20, 0x5, HDA_INPUT),
3625 HDA_CODEC_MUTE("PCM Playback Switch", 0x20, 0x5, HDA_INPUT),
3626 HDA_CODEC_VOLUME("Mic Playback Volume", 0x20, 0x00, HDA_INPUT),
3627 HDA_CODEC_MUTE("Mic Playback Switch", 0x20, 0x00, HDA_INPUT),
3628 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x20, 0x01, HDA_INPUT),
3629 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x20, 0x01, HDA_INPUT),
3630 HDA_CODEC_VOLUME("Dock Mic Playback Volume", 0x20, 0x04, HDA_INPUT),
3631 HDA_CODEC_MUTE("Dock Mic Playback Switch", 0x20, 0x04, HDA_INPUT),
3632 HDA_CODEC_VOLUME("Beep Playback Volume", 0x20, 0x03, HDA_INPUT),
3633 HDA_CODEC_MUTE("Beep Playback Switch", 0x20, 0x03, HDA_INPUT),
3634 HDA_CODEC_VOLUME("Mic Boost", 0x14, 0x0, HDA_INPUT),
3635 HDA_CODEC_VOLUME("Internal Mic Boost", 0x15, 0x0, HDA_INPUT),
3636 HDA_CODEC_VOLUME("Dock Mic Boost", 0x25, 0x0, HDA_OUTPUT),
3637 HDA_CODEC_VOLUME("Capture Volume", 0x0c, 0x0, HDA_OUTPUT),
3638 HDA_CODEC_MUTE("Capture Switch", 0x0c, 0x0, HDA_OUTPUT),
3639 HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x0d, 0x0, HDA_OUTPUT),
3640 HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x0d, 0x0, HDA_OUTPUT),
3641 {
3642 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
3643 /* The multiple "Capture Source" controls confuse alsamixer
3644 * So call somewhat different..
3645 */
3646 /* .name = "Capture Source", */
3647 .name = "Input Source",
3648 .count = 2,
3649 .info = ad198x_mux_enum_info,
3650 .get = ad198x_mux_enum_get,
3651 .put = ad198x_mux_enum_put,
3652 },
3653 { } /* end */
3654 };
3655
3656 static struct snd_kcontrol_new ad1884a_mobile_mixers[] = {
3657 HDA_CODEC_VOLUME("Master Playback Volume", 0x21, 0x0, HDA_OUTPUT),
3658 HDA_CODEC_MUTE("Master Playback Switch", 0x21, 0x0, HDA_OUTPUT),
3659 HDA_CODEC_VOLUME("PCM Playback Volume", 0x20, 0x5, HDA_INPUT),
3660 HDA_CODEC_MUTE("PCM Playback Switch", 0x20, 0x5, HDA_INPUT),
3661 HDA_CODEC_VOLUME("Beep Playback Volume", 0x20, 0x03, HDA_INPUT),
3662 HDA_CODEC_MUTE("Beep Playback Switch", 0x20, 0x03, HDA_INPUT),
3663 HDA_CODEC_VOLUME("Mic Capture Volume", 0x14, 0x0, HDA_INPUT),
3664 HDA_CODEC_VOLUME("Internal Mic Capture Volume", 0x15, 0x0, HDA_INPUT),
3665 HDA_CODEC_VOLUME("Capture Volume", 0x0c, 0x0, HDA_OUTPUT),
3666 HDA_CODEC_MUTE("Capture Switch", 0x0c, 0x0, HDA_OUTPUT),
3667 { } /* end */
3668 };
3669
3670 /* mute internal speaker if HP is plugged */
3671 static void ad1884a_hp_automute(struct hda_codec *codec)
3672 {
3673 unsigned int present;
3674
3675 present = snd_hda_codec_read(codec, 0x11, 0,
3676 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
3677 snd_hda_codec_amp_stereo(codec, 0x16, HDA_OUTPUT, 0,
3678 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
3679 snd_hda_codec_write(codec, 0x16, 0, AC_VERB_SET_EAPD_BTLENABLE,
3680 present ? 0x00 : 0x02);
3681 }
3682
3683 /* switch to external mic if plugged */
3684 static void ad1884a_hp_automic(struct hda_codec *codec)
3685 {
3686 unsigned int present;
3687