aboutsummaryrefslogtreecommitdiffstats
path: root/sound/pci/hda/patch_analog.c
diff options
context:
space:
mode:
Diffstat (limited to 'sound/pci/hda/patch_analog.c')
-rw-r--r--sound/pci/hda/patch_analog.c524
1 files changed, 307 insertions, 217 deletions
diff --git a/sound/pci/hda/patch_analog.c b/sound/pci/hda/patch_analog.c
index 4d7f8d11ad75..54cfd4526d20 100644
--- a/sound/pci/hda/patch_analog.c
+++ b/sound/pci/hda/patch_analog.c
@@ -73,6 +73,12 @@ struct ad198x_spec {
73 struct snd_kcontrol_new *kctl_alloc; 73 struct snd_kcontrol_new *kctl_alloc;
74 struct hda_input_mux private_imux; 74 struct hda_input_mux private_imux;
75 hda_nid_t private_dac_nids[4]; 75 hda_nid_t private_dac_nids[4];
76
77 unsigned int jack_present :1;
78
79#ifdef CONFIG_SND_HDA_POWER_SAVE
80 struct hda_loopback_check loopback;
81#endif
76}; 82};
77 83
78/* 84/*
@@ -144,6 +150,14 @@ static int ad198x_build_controls(struct hda_codec *codec)
144 return 0; 150 return 0;
145} 151}
146 152
153#ifdef CONFIG_SND_HDA_POWER_SAVE
154static int ad198x_check_power_status(struct hda_codec *codec, hda_nid_t nid)
155{
156 struct ad198x_spec *spec = codec->spec;
157 return snd_hda_check_amp_list_power(codec, &spec->loopback, nid);
158}
159#endif
160
147/* 161/*
148 * Analog playback callbacks 162 * Analog playback callbacks
149 */ 163 */
@@ -318,30 +332,13 @@ static void ad198x_free(struct hda_codec *codec)
318 kfree(codec->spec); 332 kfree(codec->spec);
319} 333}
320 334
321#ifdef CONFIG_PM
322static int ad198x_resume(struct hda_codec *codec)
323{
324 struct ad198x_spec *spec = codec->spec;
325 int i;
326
327 codec->patch_ops.init(codec);
328 for (i = 0; i < spec->num_mixers; i++)
329 snd_hda_resume_ctls(codec, spec->mixers[i]);
330 if (spec->multiout.dig_out_nid)
331 snd_hda_resume_spdif_out(codec);
332 if (spec->dig_in_nid)
333 snd_hda_resume_spdif_in(codec);
334 return 0;
335}
336#endif
337
338static struct hda_codec_ops ad198x_patch_ops = { 335static struct hda_codec_ops ad198x_patch_ops = {
339 .build_controls = ad198x_build_controls, 336 .build_controls = ad198x_build_controls,
340 .build_pcms = ad198x_build_pcms, 337 .build_pcms = ad198x_build_pcms,
341 .init = ad198x_init, 338 .init = ad198x_init,
342 .free = ad198x_free, 339 .free = ad198x_free,
343#ifdef CONFIG_PM 340#ifdef CONFIG_SND_HDA_POWER_SAVE
344 .resume = ad198x_resume, 341 .check_power_status = ad198x_check_power_status,
345#endif 342#endif
346}; 343};
347 344
@@ -350,15 +347,7 @@ static struct hda_codec_ops ad198x_patch_ops = {
350 * EAPD control 347 * EAPD control
351 * the private value = nid | (invert << 8) 348 * the private value = nid | (invert << 8)
352 */ 349 */
353static int ad198x_eapd_info(struct snd_kcontrol *kcontrol, 350#define ad198x_eapd_info snd_ctl_boolean_mono_info
354 struct snd_ctl_elem_info *uinfo)
355{
356 uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN;
357 uinfo->count = 1;
358 uinfo->value.integer.min = 0;
359 uinfo->value.integer.max = 1;
360 return 0;
361}
362 351
363static int ad198x_eapd_get(struct snd_kcontrol *kcontrol, 352static int ad198x_eapd_get(struct snd_kcontrol *kcontrol,
364 struct snd_ctl_elem_value *ucontrol) 353 struct snd_ctl_elem_value *ucontrol)
@@ -384,12 +373,12 @@ static int ad198x_eapd_put(struct snd_kcontrol *kcontrol,
384 eapd = ucontrol->value.integer.value[0]; 373 eapd = ucontrol->value.integer.value[0];
385 if (invert) 374 if (invert)
386 eapd = !eapd; 375 eapd = !eapd;
387 if (eapd == spec->cur_eapd && ! codec->in_resume) 376 if (eapd == spec->cur_eapd)
388 return 0; 377 return 0;
389 spec->cur_eapd = eapd; 378 spec->cur_eapd = eapd;
390 snd_hda_codec_write(codec, nid, 379 snd_hda_codec_write_cache(codec, nid,
391 0, AC_VERB_SET_EAPD_BTLENABLE, 380 0, AC_VERB_SET_EAPD_BTLENABLE,
392 eapd ? 0x02 : 0x00); 381 eapd ? 0x02 : 0x00);
393 return 1; 382 return 1;
394} 383}
395 384
@@ -430,94 +419,36 @@ static struct hda_input_mux ad1986a_capture_source = {
430 }, 419 },
431}; 420};
432 421
433/*
434 * PCM control
435 *
436 * bind volumes/mutes of 3 DACs as a single PCM control for simplicity
437 */
438
439#define ad1986a_pcm_amp_vol_info snd_hda_mixer_amp_volume_info
440
441static int ad1986a_pcm_amp_vol_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
442{
443 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
444 struct ad198x_spec *ad = codec->spec;
445
446 mutex_lock(&ad->amp_mutex);
447 snd_hda_mixer_amp_volume_get(kcontrol, ucontrol);
448 mutex_unlock(&ad->amp_mutex);
449 return 0;
450}
451
452static int ad1986a_pcm_amp_vol_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
453{
454 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
455 struct ad198x_spec *ad = codec->spec;
456 int i, change = 0;
457
458 mutex_lock(&ad->amp_mutex);
459 for (i = 0; i < ARRAY_SIZE(ad1986a_dac_nids); i++) {
460 kcontrol->private_value = HDA_COMPOSE_AMP_VAL(ad1986a_dac_nids[i], 3, 0, HDA_OUTPUT);
461 change |= snd_hda_mixer_amp_volume_put(kcontrol, ucontrol);
462 }
463 kcontrol->private_value = HDA_COMPOSE_AMP_VAL(AD1986A_FRONT_DAC, 3, 0, HDA_OUTPUT);
464 mutex_unlock(&ad->amp_mutex);
465 return change;
466}
467
468#define ad1986a_pcm_amp_sw_info snd_hda_mixer_amp_switch_info
469 422
470static int ad1986a_pcm_amp_sw_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) 423static struct hda_bind_ctls ad1986a_bind_pcm_vol = {
471{ 424 .ops = &snd_hda_bind_vol,
472 struct hda_codec *codec = snd_kcontrol_chip(kcontrol); 425 .values = {
473 struct ad198x_spec *ad = codec->spec; 426 HDA_COMPOSE_AMP_VAL(AD1986A_FRONT_DAC, 3, 0, HDA_OUTPUT),
474 427 HDA_COMPOSE_AMP_VAL(AD1986A_SURR_DAC, 3, 0, HDA_OUTPUT),
475 mutex_lock(&ad->amp_mutex); 428 HDA_COMPOSE_AMP_VAL(AD1986A_CLFE_DAC, 3, 0, HDA_OUTPUT),
476 snd_hda_mixer_amp_switch_get(kcontrol, ucontrol); 429 0
477 mutex_unlock(&ad->amp_mutex); 430 },
478 return 0; 431};
479}
480
481static int ad1986a_pcm_amp_sw_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
482{
483 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
484 struct ad198x_spec *ad = codec->spec;
485 int i, change = 0;
486 432
487 mutex_lock(&ad->amp_mutex); 433static struct hda_bind_ctls ad1986a_bind_pcm_sw = {
488 for (i = 0; i < ARRAY_SIZE(ad1986a_dac_nids); i++) { 434 .ops = &snd_hda_bind_sw,
489 kcontrol->private_value = HDA_COMPOSE_AMP_VAL(ad1986a_dac_nids[i], 3, 0, HDA_OUTPUT); 435 .values = {
490 change |= snd_hda_mixer_amp_switch_put(kcontrol, ucontrol); 436 HDA_COMPOSE_AMP_VAL(AD1986A_FRONT_DAC, 3, 0, HDA_OUTPUT),
491 } 437 HDA_COMPOSE_AMP_VAL(AD1986A_SURR_DAC, 3, 0, HDA_OUTPUT),
492 kcontrol->private_value = HDA_COMPOSE_AMP_VAL(AD1986A_FRONT_DAC, 3, 0, HDA_OUTPUT); 438 HDA_COMPOSE_AMP_VAL(AD1986A_CLFE_DAC, 3, 0, HDA_OUTPUT),
493 mutex_unlock(&ad->amp_mutex); 439 0
494 return change; 440 },
495} 441};
496 442
497/* 443/*
498 * mixers 444 * mixers
499 */ 445 */
500static struct snd_kcontrol_new ad1986a_mixers[] = { 446static struct snd_kcontrol_new ad1986a_mixers[] = {
501 { 447 /*
502 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 448 * bind volumes/mutes of 3 DACs as a single PCM control for simplicity
503 .name = "PCM Playback Volume", 449 */
504 .access = SNDRV_CTL_ELEM_ACCESS_READWRITE | 450 HDA_BIND_VOL("PCM Playback Volume", &ad1986a_bind_pcm_vol),
505 SNDRV_CTL_ELEM_ACCESS_TLV_READ | 451 HDA_BIND_SW("PCM Playback Switch", &ad1986a_bind_pcm_sw),
506 SNDRV_CTL_ELEM_ACCESS_TLV_CALLBACK,
507 .info = ad1986a_pcm_amp_vol_info,
508 .get = ad1986a_pcm_amp_vol_get,
509 .put = ad1986a_pcm_amp_vol_put,
510 .tlv = { .c = snd_hda_mixer_amp_tlv },
511 .private_value = HDA_COMPOSE_AMP_VAL(AD1986A_FRONT_DAC, 3, 0, HDA_OUTPUT)
512 },
513 {
514 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
515 .name = "PCM Playback Switch",
516 .info = ad1986a_pcm_amp_sw_info,
517 .get = ad1986a_pcm_amp_sw_get,
518 .put = ad1986a_pcm_amp_sw_put,
519 .private_value = HDA_COMPOSE_AMP_VAL(AD1986A_FRONT_DAC, 3, 0, HDA_OUTPUT)
520 },
521 HDA_CODEC_VOLUME("Front Playback Volume", 0x1b, 0x0, HDA_OUTPUT), 452 HDA_CODEC_VOLUME("Front Playback Volume", 0x1b, 0x0, HDA_OUTPUT),
522 HDA_CODEC_MUTE("Front Playback Switch", 0x1b, 0x0, HDA_OUTPUT), 453 HDA_CODEC_MUTE("Front Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
523 HDA_CODEC_VOLUME("Surround Playback Volume", 0x1c, 0x0, HDA_OUTPUT), 454 HDA_CODEC_VOLUME("Surround Playback Volume", 0x1c, 0x0, HDA_OUTPUT),
@@ -569,13 +500,30 @@ static struct snd_kcontrol_new ad1986a_3st_mixers[] = {
569/* laptop model - 2ch only */ 500/* laptop model - 2ch only */
570static hda_nid_t ad1986a_laptop_dac_nids[1] = { AD1986A_FRONT_DAC }; 501static hda_nid_t ad1986a_laptop_dac_nids[1] = { AD1986A_FRONT_DAC };
571 502
503/* master controls both pins 0x1a and 0x1b */
504static struct hda_bind_ctls ad1986a_laptop_master_vol = {
505 .ops = &snd_hda_bind_vol,
506 .values = {
507 HDA_COMPOSE_AMP_VAL(0x1a, 3, 0, HDA_OUTPUT),
508 HDA_COMPOSE_AMP_VAL(0x1b, 3, 0, HDA_OUTPUT),
509 0,
510 },
511};
512
513static struct hda_bind_ctls ad1986a_laptop_master_sw = {
514 .ops = &snd_hda_bind_sw,
515 .values = {
516 HDA_COMPOSE_AMP_VAL(0x1a, 3, 0, HDA_OUTPUT),
517 HDA_COMPOSE_AMP_VAL(0x1b, 3, 0, HDA_OUTPUT),
518 0,
519 },
520};
521
572static struct snd_kcontrol_new ad1986a_laptop_mixers[] = { 522static struct snd_kcontrol_new ad1986a_laptop_mixers[] = {
573 HDA_CODEC_VOLUME("PCM Playback Volume", 0x03, 0x0, HDA_OUTPUT), 523 HDA_CODEC_VOLUME("PCM Playback Volume", 0x03, 0x0, HDA_OUTPUT),
574 HDA_CODEC_MUTE("PCM Playback Switch", 0x03, 0x0, HDA_OUTPUT), 524 HDA_CODEC_MUTE("PCM Playback Switch", 0x03, 0x0, HDA_OUTPUT),
575 HDA_CODEC_VOLUME("Master Playback Volume", 0x1b, 0x0, HDA_OUTPUT), 525 HDA_BIND_VOL("Master Playback Volume", &ad1986a_laptop_master_vol),
576 HDA_CODEC_MUTE("Master Playback Switch", 0x1b, 0x0, HDA_OUTPUT), 526 HDA_BIND_SW("Master Playback Switch", &ad1986a_laptop_master_sw),
577 /* HDA_CODEC_VOLUME("Headphone Playback Volume", 0x1a, 0x0, HDA_OUTPUT),
578 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1a, 0x0, HDA_OUTPUT), */
579 HDA_CODEC_VOLUME("CD Playback Volume", 0x15, 0x0, HDA_OUTPUT), 527 HDA_CODEC_VOLUME("CD Playback Volume", 0x15, 0x0, HDA_OUTPUT),
580 HDA_CODEC_MUTE("CD Playback Switch", 0x15, 0x0, HDA_OUTPUT), 528 HDA_CODEC_MUTE("CD Playback Switch", 0x15, 0x0, HDA_OUTPUT),
581 HDA_CODEC_VOLUME("Line Playback Volume", 0x17, 0x0, HDA_OUTPUT), 529 HDA_CODEC_VOLUME("Line Playback Volume", 0x17, 0x0, HDA_OUTPUT),
@@ -603,68 +551,114 @@ static struct snd_kcontrol_new ad1986a_laptop_mixers[] = {
603 551
604/* laptop-eapd model - 2ch only */ 552/* laptop-eapd model - 2ch only */
605 553
606/* master controls both pins 0x1a and 0x1b */ 554static struct hda_input_mux ad1986a_laptop_eapd_capture_source = {
607static int ad1986a_laptop_master_vol_put(struct snd_kcontrol *kcontrol, 555 .num_items = 3,
608 struct snd_ctl_elem_value *ucontrol) 556 .items = {
557 { "Mic", 0x0 },
558 { "Internal Mic", 0x4 },
559 { "Mix", 0x5 },
560 },
561};
562
563static struct snd_kcontrol_new ad1986a_laptop_eapd_mixers[] = {
564 HDA_BIND_VOL("Master Playback Volume", &ad1986a_laptop_master_vol),
565 HDA_BIND_SW("Master Playback Switch", &ad1986a_laptop_master_sw),
566 HDA_CODEC_VOLUME("PCM Playback Volume", 0x03, 0x0, HDA_OUTPUT),
567 HDA_CODEC_MUTE("PCM Playback Switch", 0x03, 0x0, HDA_OUTPUT),
568 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x17, 0x0, HDA_OUTPUT),
569 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x17, 0x0, HDA_OUTPUT),
570 HDA_CODEC_VOLUME("Mic Playback Volume", 0x13, 0x0, HDA_OUTPUT),
571 HDA_CODEC_MUTE("Mic Playback Switch", 0x13, 0x0, HDA_OUTPUT),
572 HDA_CODEC_VOLUME("Mic Boost", 0x0f, 0x0, HDA_OUTPUT),
573 HDA_CODEC_VOLUME("Capture Volume", 0x12, 0x0, HDA_OUTPUT),
574 HDA_CODEC_MUTE("Capture Switch", 0x12, 0x0, HDA_OUTPUT),
575 {
576 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
577 .name = "Capture Source",
578 .info = ad198x_mux_enum_info,
579 .get = ad198x_mux_enum_get,
580 .put = ad198x_mux_enum_put,
581 },
582 {
583 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
584 .name = "External Amplifier",
585 .info = ad198x_eapd_info,
586 .get = ad198x_eapd_get,
587 .put = ad198x_eapd_put,
588 .private_value = 0x1b | (1 << 8), /* port-D, inversed */
589 },
590 { } /* end */
591};
592
593/* laptop-automute - 2ch only */
594
595static void ad1986a_update_hp(struct hda_codec *codec)
609{ 596{
610 struct hda_codec *codec = snd_kcontrol_chip(kcontrol); 597 struct ad198x_spec *spec = codec->spec;
611 long *valp = ucontrol->value.integer.value; 598 unsigned int mute;
612 int change;
613 599
614 change = snd_hda_codec_amp_update(codec, 0x1a, 0, HDA_OUTPUT, 0, 600 if (spec->jack_present)
615 0x7f, valp[0] & 0x7f); 601 mute = HDA_AMP_MUTE; /* mute internal speaker */
616 change |= snd_hda_codec_amp_update(codec, 0x1a, 1, HDA_OUTPUT, 0, 602 else
617 0x7f, valp[1] & 0x7f); 603 /* unmute internal speaker if necessary */
618 snd_hda_codec_amp_update(codec, 0x1b, 0, HDA_OUTPUT, 0, 604 mute = snd_hda_codec_amp_read(codec, 0x1a, 0, HDA_OUTPUT, 0);
619 0x7f, valp[0] & 0x7f); 605 snd_hda_codec_amp_stereo(codec, 0x1b, HDA_OUTPUT, 0,
620 snd_hda_codec_amp_update(codec, 0x1b, 1, HDA_OUTPUT, 0, 606 HDA_AMP_MUTE, mute);
621 0x7f, valp[1] & 0x7f);
622 return change;
623} 607}
624 608
625static int ad1986a_laptop_master_sw_put(struct snd_kcontrol *kcontrol, 609static void ad1986a_hp_automute(struct hda_codec *codec)
626 struct snd_ctl_elem_value *ucontrol) 610{
611 struct ad198x_spec *spec = codec->spec;
612 unsigned int present;
613
614 present = snd_hda_codec_read(codec, 0x1a, 0, AC_VERB_GET_PIN_SENSE, 0);
615 spec->jack_present = (present & 0x80000000) != 0;
616 ad1986a_update_hp(codec);
617}
618
619#define AD1986A_HP_EVENT 0x37
620
621static void ad1986a_hp_unsol_event(struct hda_codec *codec, unsigned int res)
622{
623 if ((res >> 26) != AD1986A_HP_EVENT)
624 return;
625 ad1986a_hp_automute(codec);
626}
627
628static int ad1986a_hp_init(struct hda_codec *codec)
629{
630 ad198x_init(codec);
631 ad1986a_hp_automute(codec);
632 return 0;
633}
634
635/* bind hp and internal speaker mute (with plug check) */
636static int ad1986a_hp_master_sw_put(struct snd_kcontrol *kcontrol,
637 struct snd_ctl_elem_value *ucontrol)
627{ 638{
628 struct hda_codec *codec = snd_kcontrol_chip(kcontrol); 639 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
629 long *valp = ucontrol->value.integer.value; 640 long *valp = ucontrol->value.integer.value;
630 int change; 641 int change;
631 642
632 change = snd_hda_codec_amp_update(codec, 0x1a, 0, HDA_OUTPUT, 0, 643 change = snd_hda_codec_amp_update(codec, 0x1a, 0, HDA_OUTPUT, 0,
633 0x80, valp[0] ? 0 : 0x80); 644 HDA_AMP_MUTE,
645 valp[0] ? 0 : HDA_AMP_MUTE);
634 change |= snd_hda_codec_amp_update(codec, 0x1a, 1, HDA_OUTPUT, 0, 646 change |= snd_hda_codec_amp_update(codec, 0x1a, 1, HDA_OUTPUT, 0,
635 0x80, valp[1] ? 0 : 0x80); 647 HDA_AMP_MUTE,
636 snd_hda_codec_amp_update(codec, 0x1b, 0, HDA_OUTPUT, 0, 648 valp[1] ? 0 : HDA_AMP_MUTE);
637 0x80, valp[0] ? 0 : 0x80); 649 if (change)
638 snd_hda_codec_amp_update(codec, 0x1b, 1, HDA_OUTPUT, 0, 650 ad1986a_update_hp(codec);
639 0x80, valp[1] ? 0 : 0x80);
640 return change; 651 return change;
641} 652}
642 653
643static struct hda_input_mux ad1986a_laptop_eapd_capture_source = { 654static struct snd_kcontrol_new ad1986a_laptop_automute_mixers[] = {
644 .num_items = 3, 655 HDA_BIND_VOL("Master Playback Volume", &ad1986a_laptop_master_vol),
645 .items = {
646 { "Mic", 0x0 },
647 { "Internal Mic", 0x4 },
648 { "Mix", 0x5 },
649 },
650};
651
652static struct snd_kcontrol_new ad1986a_laptop_eapd_mixers[] = {
653 {
654 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
655 .name = "Master Playback Volume",
656 .info = snd_hda_mixer_amp_volume_info,
657 .get = snd_hda_mixer_amp_volume_get,
658 .put = ad1986a_laptop_master_vol_put,
659 .tlv = { .c = snd_hda_mixer_amp_tlv },
660 .private_value = HDA_COMPOSE_AMP_VAL(0x1a, 3, 0, HDA_OUTPUT),
661 },
662 { 656 {
663 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 657 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
664 .name = "Master Playback Switch", 658 .name = "Master Playback Switch",
665 .info = snd_hda_mixer_amp_switch_info, 659 .info = snd_hda_mixer_amp_switch_info,
666 .get = snd_hda_mixer_amp_switch_get, 660 .get = snd_hda_mixer_amp_switch_get,
667 .put = ad1986a_laptop_master_sw_put, 661 .put = ad1986a_hp_master_sw_put,
668 .private_value = HDA_COMPOSE_AMP_VAL(0x1a, 3, 0, HDA_OUTPUT), 662 .private_value = HDA_COMPOSE_AMP_VAL(0x1a, 3, 0, HDA_OUTPUT),
669 }, 663 },
670 HDA_CODEC_VOLUME("PCM Playback Volume", 0x03, 0x0, HDA_OUTPUT), 664 HDA_CODEC_VOLUME("PCM Playback Volume", 0x03, 0x0, HDA_OUTPUT),
@@ -674,6 +668,8 @@ static struct snd_kcontrol_new ad1986a_laptop_eapd_mixers[] = {
674 HDA_CODEC_VOLUME("Mic Playback Volume", 0x13, 0x0, HDA_OUTPUT), 668 HDA_CODEC_VOLUME("Mic Playback Volume", 0x13, 0x0, HDA_OUTPUT),
675 HDA_CODEC_MUTE("Mic Playback Switch", 0x13, 0x0, HDA_OUTPUT), 669 HDA_CODEC_MUTE("Mic Playback Switch", 0x13, 0x0, HDA_OUTPUT),
676 HDA_CODEC_VOLUME("Mic Boost", 0x0f, 0x0, HDA_OUTPUT), 670 HDA_CODEC_VOLUME("Mic Boost", 0x0f, 0x0, HDA_OUTPUT),
671 HDA_CODEC_VOLUME("Beep Playback Volume", 0x18, 0x0, HDA_OUTPUT),
672 HDA_CODEC_MUTE("Beep Playback Switch", 0x18, 0x0, HDA_OUTPUT),
677 HDA_CODEC_VOLUME("Capture Volume", 0x12, 0x0, HDA_OUTPUT), 673 HDA_CODEC_VOLUME("Capture Volume", 0x12, 0x0, HDA_OUTPUT),
678 HDA_CODEC_MUTE("Capture Switch", 0x12, 0x0, HDA_OUTPUT), 674 HDA_CODEC_MUTE("Capture Switch", 0x12, 0x0, HDA_OUTPUT),
679 { 675 {
@@ -807,12 +803,20 @@ static struct hda_verb ad1986a_ultra_init[] = {
807 { } /* end */ 803 { } /* end */
808}; 804};
809 805
806/* pin sensing on HP jack */
807static struct hda_verb ad1986a_hp_init_verbs[] = {
808 {0x1a, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | AD1986A_HP_EVENT},
809 {}
810};
811
812
810/* models */ 813/* models */
811enum { 814enum {
812 AD1986A_6STACK, 815 AD1986A_6STACK,
813 AD1986A_3STACK, 816 AD1986A_3STACK,
814 AD1986A_LAPTOP, 817 AD1986A_LAPTOP,
815 AD1986A_LAPTOP_EAPD, 818 AD1986A_LAPTOP_EAPD,
819 AD1986A_LAPTOP_AUTOMUTE,
816 AD1986A_ULTRA, 820 AD1986A_ULTRA,
817 AD1986A_MODELS 821 AD1986A_MODELS
818}; 822};
@@ -822,6 +826,7 @@ static const char *ad1986a_models[AD1986A_MODELS] = {
822 [AD1986A_3STACK] = "3stack", 826 [AD1986A_3STACK] = "3stack",
823 [AD1986A_LAPTOP] = "laptop", 827 [AD1986A_LAPTOP] = "laptop",
824 [AD1986A_LAPTOP_EAPD] = "laptop-eapd", 828 [AD1986A_LAPTOP_EAPD] = "laptop-eapd",
829 [AD1986A_LAPTOP_AUTOMUTE] = "laptop-automute",
825 [AD1986A_ULTRA] = "ultra", 830 [AD1986A_ULTRA] = "ultra",
826}; 831};
827 832
@@ -850,11 +855,22 @@ static struct snd_pci_quirk ad1986a_cfg_tbl[] = {
850 SND_PCI_QUIRK(0x144d, 0xc027, "Samsung Q1", AD1986A_ULTRA), 855 SND_PCI_QUIRK(0x144d, 0xc027, "Samsung Q1", AD1986A_ULTRA),
851 SND_PCI_QUIRK(0x17aa, 0x1011, "Lenovo M55", AD1986A_LAPTOP), 856 SND_PCI_QUIRK(0x17aa, 0x1011, "Lenovo M55", AD1986A_LAPTOP),
852 SND_PCI_QUIRK(0x17aa, 0x1017, "Lenovo A60", AD1986A_3STACK), 857 SND_PCI_QUIRK(0x17aa, 0x1017, "Lenovo A60", AD1986A_3STACK),
853 SND_PCI_QUIRK(0x17aa, 0x2066, "Lenovo N100", AD1986A_LAPTOP_EAPD), 858 SND_PCI_QUIRK(0x17aa, 0x2066, "Lenovo N100", AD1986A_LAPTOP_AUTOMUTE),
854 SND_PCI_QUIRK(0x17c0, 0x2017, "Samsung M50", AD1986A_LAPTOP), 859 SND_PCI_QUIRK(0x17c0, 0x2017, "Samsung M50", AD1986A_LAPTOP),
855 {} 860 {}
856}; 861};
857 862
863#ifdef CONFIG_SND_HDA_POWER_SAVE
864static struct hda_amp_list ad1986a_loopbacks[] = {
865 { 0x13, HDA_OUTPUT, 0 }, /* Mic */
866 { 0x14, HDA_OUTPUT, 0 }, /* Phone */
867 { 0x15, HDA_OUTPUT, 0 }, /* CD */
868 { 0x16, HDA_OUTPUT, 0 }, /* Aux */
869 { 0x17, HDA_OUTPUT, 0 }, /* Line */
870 { } /* end */
871};
872#endif
873
858static int patch_ad1986a(struct hda_codec *codec) 874static int patch_ad1986a(struct hda_codec *codec)
859{ 875{
860 struct ad198x_spec *spec; 876 struct ad198x_spec *spec;
@@ -864,7 +880,6 @@ static int patch_ad1986a(struct hda_codec *codec)
864 if (spec == NULL) 880 if (spec == NULL)
865 return -ENOMEM; 881 return -ENOMEM;
866 882
867 mutex_init(&spec->amp_mutex);
868 codec->spec = spec; 883 codec->spec = spec;
869 884
870 spec->multiout.max_channels = 6; 885 spec->multiout.max_channels = 6;
@@ -879,6 +894,9 @@ static int patch_ad1986a(struct hda_codec *codec)
879 spec->mixers[0] = ad1986a_mixers; 894 spec->mixers[0] = ad1986a_mixers;
880 spec->num_init_verbs = 1; 895 spec->num_init_verbs = 1;
881 spec->init_verbs[0] = ad1986a_init_verbs; 896 spec->init_verbs[0] = ad1986a_init_verbs;
897#ifdef CONFIG_SND_HDA_POWER_SAVE
898 spec->loopback.amplist = ad1986a_loopbacks;
899#endif
882 900
883 codec->patch_ops = ad198x_patch_ops; 901 codec->patch_ops = ad198x_patch_ops;
884 902
@@ -914,6 +932,19 @@ static int patch_ad1986a(struct hda_codec *codec)
914 spec->multiout.dig_out_nid = 0; 932 spec->multiout.dig_out_nid = 0;
915 spec->input_mux = &ad1986a_laptop_eapd_capture_source; 933 spec->input_mux = &ad1986a_laptop_eapd_capture_source;
916 break; 934 break;
935 case AD1986A_LAPTOP_AUTOMUTE:
936 spec->mixers[0] = ad1986a_laptop_automute_mixers;
937 spec->num_init_verbs = 3;
938 spec->init_verbs[1] = ad1986a_eapd_init_verbs;
939 spec->init_verbs[2] = ad1986a_hp_init_verbs;
940 spec->multiout.max_channels = 2;
941 spec->multiout.num_dacs = 1;
942 spec->multiout.dac_nids = ad1986a_laptop_dac_nids;
943 spec->multiout.dig_out_nid = 0;
944 spec->input_mux = &ad1986a_laptop_eapd_capture_source;
945 codec->patch_ops.unsol_event = ad1986a_hp_unsol_event;
946 codec->patch_ops.init = ad1986a_hp_init;
947 break;
917 case AD1986A_ULTRA: 948 case AD1986A_ULTRA:
918 spec->mixers[0] = ad1986a_laptop_eapd_mixers; 949 spec->mixers[0] = ad1986a_laptop_eapd_mixers;
919 spec->num_init_verbs = 2; 950 spec->num_init_verbs = 2;
@@ -982,8 +1013,9 @@ static int ad1983_spdif_route_put(struct snd_kcontrol *kcontrol, struct snd_ctl_
982 1013
983 if (spec->spdif_route != ucontrol->value.enumerated.item[0]) { 1014 if (spec->spdif_route != ucontrol->value.enumerated.item[0]) {
984 spec->spdif_route = ucontrol->value.enumerated.item[0]; 1015 spec->spdif_route = ucontrol->value.enumerated.item[0];
985 snd_hda_codec_write(codec, spec->multiout.dig_out_nid, 0, 1016 snd_hda_codec_write_cache(codec, spec->multiout.dig_out_nid, 0,
986 AC_VERB_SET_CONNECT_SEL, spec->spdif_route); 1017 AC_VERB_SET_CONNECT_SEL,
1018 spec->spdif_route);
987 return 1; 1019 return 1;
988 } 1020 }
989 return 0; 1021 return 0;
@@ -1063,6 +1095,13 @@ static struct hda_verb ad1983_init_verbs[] = {
1063 { } /* end */ 1095 { } /* end */
1064}; 1096};
1065 1097
1098#ifdef CONFIG_SND_HDA_POWER_SAVE
1099static struct hda_amp_list ad1983_loopbacks[] = {
1100 { 0x12, HDA_OUTPUT, 0 }, /* Mic */
1101 { 0x13, HDA_OUTPUT, 0 }, /* Line */
1102 { } /* end */
1103};
1104#endif
1066 1105
1067static int patch_ad1983(struct hda_codec *codec) 1106static int patch_ad1983(struct hda_codec *codec)
1068{ 1107{
@@ -1072,7 +1111,6 @@ static int patch_ad1983(struct hda_codec *codec)
1072 if (spec == NULL) 1111 if (spec == NULL)
1073 return -ENOMEM; 1112 return -ENOMEM;
1074 1113
1075 mutex_init(&spec->amp_mutex);
1076 codec->spec = spec; 1114 codec->spec = spec;
1077 1115
1078 spec->multiout.max_channels = 2; 1116 spec->multiout.max_channels = 2;
@@ -1088,6 +1126,9 @@ static int patch_ad1983(struct hda_codec *codec)
1088 spec->num_init_verbs = 1; 1126 spec->num_init_verbs = 1;
1089 spec->init_verbs[0] = ad1983_init_verbs; 1127 spec->init_verbs[0] = ad1983_init_verbs;
1090 spec->spdif_route = 0; 1128 spec->spdif_route = 0;
1129#ifdef CONFIG_SND_HDA_POWER_SAVE
1130 spec->loopback.amplist = ad1983_loopbacks;
1131#endif
1091 1132
1092 codec->patch_ops = ad198x_patch_ops; 1133 codec->patch_ops = ad198x_patch_ops;
1093 1134
@@ -1211,6 +1252,17 @@ static struct hda_verb ad1981_init_verbs[] = {
1211 { } /* end */ 1252 { } /* end */
1212}; 1253};
1213 1254
1255#ifdef CONFIG_SND_HDA_POWER_SAVE
1256static struct hda_amp_list ad1981_loopbacks[] = {
1257 { 0x12, HDA_OUTPUT, 0 }, /* Front Mic */
1258 { 0x13, HDA_OUTPUT, 0 }, /* Line */
1259 { 0x1b, HDA_OUTPUT, 0 }, /* Aux */
1260 { 0x1c, HDA_OUTPUT, 0 }, /* Mic */
1261 { 0x1d, HDA_OUTPUT, 0 }, /* CD */
1262 { } /* end */
1263};
1264#endif
1265
1214/* 1266/*
1215 * Patch for HP nx6320 1267 * Patch for HP nx6320
1216 * 1268 *
@@ -1240,31 +1292,21 @@ static int ad1981_hp_master_sw_put(struct snd_kcontrol *kcontrol,
1240 return 0; 1292 return 0;
1241 1293
1242 /* toggle HP mute appropriately */ 1294 /* toggle HP mute appropriately */
1243 snd_hda_codec_amp_update(codec, 0x06, 0, HDA_OUTPUT, 0, 1295 snd_hda_codec_amp_stereo(codec, 0x06, HDA_OUTPUT, 0,
1244 0x80, spec->cur_eapd ? 0 : 0x80); 1296 HDA_AMP_MUTE,
1245 snd_hda_codec_amp_update(codec, 0x06, 1, HDA_OUTPUT, 0, 1297 spec->cur_eapd ? 0 : HDA_AMP_MUTE);
1246 0x80, spec->cur_eapd ? 0 : 0x80);
1247 return 1; 1298 return 1;
1248} 1299}
1249 1300
1250/* bind volumes of both NID 0x05 and 0x06 */ 1301/* bind volumes of both NID 0x05 and 0x06 */
1251static int ad1981_hp_master_vol_put(struct snd_kcontrol *kcontrol, 1302static struct hda_bind_ctls ad1981_hp_bind_master_vol = {
1252 struct snd_ctl_elem_value *ucontrol) 1303 .ops = &snd_hda_bind_vol,
1253{ 1304 .values = {
1254 struct hda_codec *codec = snd_kcontrol_chip(kcontrol); 1305 HDA_COMPOSE_AMP_VAL(0x05, 3, 0, HDA_OUTPUT),
1255 long *valp = ucontrol->value.integer.value; 1306 HDA_COMPOSE_AMP_VAL(0x06, 3, 0, HDA_OUTPUT),
1256 int change; 1307 0
1257 1308 },
1258 change = snd_hda_codec_amp_update(codec, 0x05, 0, HDA_OUTPUT, 0, 1309};
1259 0x7f, valp[0] & 0x7f);
1260 change |= snd_hda_codec_amp_update(codec, 0x05, 1, HDA_OUTPUT, 0,
1261 0x7f, valp[1] & 0x7f);
1262 snd_hda_codec_amp_update(codec, 0x06, 0, HDA_OUTPUT, 0,
1263 0x7f, valp[0] & 0x7f);
1264 snd_hda_codec_amp_update(codec, 0x06, 1, HDA_OUTPUT, 0,
1265 0x7f, valp[1] & 0x7f);
1266 return change;
1267}
1268 1310
1269/* mute internal speaker if HP is plugged */ 1311/* mute internal speaker if HP is plugged */
1270static void ad1981_hp_automute(struct hda_codec *codec) 1312static void ad1981_hp_automute(struct hda_codec *codec)
@@ -1273,10 +1315,8 @@ static void ad1981_hp_automute(struct hda_codec *codec)
1273 1315
1274 present = snd_hda_codec_read(codec, 0x06, 0, 1316 present = snd_hda_codec_read(codec, 0x06, 0,
1275 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000; 1317 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
1276 snd_hda_codec_amp_update(codec, 0x05, 0, HDA_OUTPUT, 0, 1318 snd_hda_codec_amp_stereo(codec, 0x05, HDA_OUTPUT, 0,
1277 0x80, present ? 0x80 : 0); 1319 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
1278 snd_hda_codec_amp_update(codec, 0x05, 1, HDA_OUTPUT, 0,
1279 0x80, present ? 0x80 : 0);
1280} 1320}
1281 1321
1282/* toggle input of built-in and mic jack appropriately */ 1322/* toggle input of built-in and mic jack appropriately */
@@ -1327,14 +1367,7 @@ static struct hda_input_mux ad1981_hp_capture_source = {
1327}; 1367};
1328 1368
1329static struct snd_kcontrol_new ad1981_hp_mixers[] = { 1369static struct snd_kcontrol_new ad1981_hp_mixers[] = {
1330 { 1370 HDA_BIND_VOL("Master Playback Volume", &ad1981_hp_bind_master_vol),
1331 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1332 .name = "Master Playback Volume",
1333 .info = snd_hda_mixer_amp_volume_info,
1334 .get = snd_hda_mixer_amp_volume_get,
1335 .put = ad1981_hp_master_vol_put,
1336 .private_value = HDA_COMPOSE_AMP_VAL(0x05, 3, 0, HDA_OUTPUT),
1337 },
1338 { 1371 {
1339 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 1372 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1340 .name = "Master Playback Switch", 1373 .name = "Master Playback Switch",
@@ -1474,7 +1507,6 @@ static int patch_ad1981(struct hda_codec *codec)
1474 if (spec == NULL) 1507 if (spec == NULL)
1475 return -ENOMEM; 1508 return -ENOMEM;
1476 1509
1477 mutex_init(&spec->amp_mutex);
1478 codec->spec = spec; 1510 codec->spec = spec;
1479 1511
1480 spec->multiout.max_channels = 2; 1512 spec->multiout.max_channels = 2;
@@ -1490,6 +1522,9 @@ static int patch_ad1981(struct hda_codec *codec)
1490 spec->num_init_verbs = 1; 1522 spec->num_init_verbs = 1;
1491 spec->init_verbs[0] = ad1981_init_verbs; 1523 spec->init_verbs[0] = ad1981_init_verbs;
1492 spec->spdif_route = 0; 1524 spec->spdif_route = 0;
1525#ifdef CONFIG_SND_HDA_POWER_SAVE
1526 spec->loopback.amplist = ad1981_loopbacks;
1527#endif
1493 1528
1494 codec->patch_ops = ad198x_patch_ops; 1529 codec->patch_ops = ad198x_patch_ops;
1495 1530
@@ -1897,16 +1932,19 @@ static int ad1988_spdif_playback_source_get(struct snd_kcontrol *kcontrol,
1897 struct hda_codec *codec = snd_kcontrol_chip(kcontrol); 1932 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
1898 unsigned int sel; 1933 unsigned int sel;
1899 1934
1900 sel = snd_hda_codec_read(codec, 0x02, 0, AC_VERB_GET_CONNECT_SEL, 0); 1935 sel = snd_hda_codec_read(codec, 0x1d, 0, AC_VERB_GET_AMP_GAIN_MUTE,
1901 if (sel > 0) { 1936 AC_AMP_GET_INPUT);
1937 if (!(sel & 0x80))
1938 ucontrol->value.enumerated.item[0] = 0;
1939 else {
1902 sel = snd_hda_codec_read(codec, 0x0b, 0, 1940 sel = snd_hda_codec_read(codec, 0x0b, 0,
1903 AC_VERB_GET_CONNECT_SEL, 0); 1941 AC_VERB_GET_CONNECT_SEL, 0);
1904 if (sel < 3) 1942 if (sel < 3)
1905 sel++; 1943 sel++;
1906 else 1944 else
1907 sel = 0; 1945 sel = 0;
1946 ucontrol->value.enumerated.item[0] = sel;
1908 } 1947 }
1909 ucontrol->value.enumerated.item[0] = sel;
1910 return 0; 1948 return 0;
1911} 1949}
1912 1950
@@ -1918,23 +1956,39 @@ static int ad1988_spdif_playback_source_put(struct snd_kcontrol *kcontrol,
1918 int change; 1956 int change;
1919 1957
1920 val = ucontrol->value.enumerated.item[0]; 1958 val = ucontrol->value.enumerated.item[0];
1921 sel = snd_hda_codec_read(codec, 0x02, 0, AC_VERB_GET_CONNECT_SEL, 0);
1922 if (!val) { 1959 if (!val) {
1923 change = sel != 0; 1960 sel = snd_hda_codec_read(codec, 0x1d, 0,
1924 if (change || codec->in_resume) 1961 AC_VERB_GET_AMP_GAIN_MUTE,
1925 snd_hda_codec_write(codec, 0x02, 0, 1962 AC_AMP_GET_INPUT);
1926 AC_VERB_SET_CONNECT_SEL, 0); 1963 change = sel & 0x80;
1964 if (change) {
1965 snd_hda_codec_write_cache(codec, 0x1d, 0,
1966 AC_VERB_SET_AMP_GAIN_MUTE,
1967 AMP_IN_UNMUTE(0));
1968 snd_hda_codec_write_cache(codec, 0x1d, 0,
1969 AC_VERB_SET_AMP_GAIN_MUTE,
1970 AMP_IN_MUTE(1));
1971 }
1927 } else { 1972 } else {
1928 change = sel == 0; 1973 sel = snd_hda_codec_read(codec, 0x1d, 0,
1929 if (change || codec->in_resume) 1974 AC_VERB_GET_AMP_GAIN_MUTE,
1930 snd_hda_codec_write(codec, 0x02, 0, 1975 AC_AMP_GET_INPUT | 0x01);
1931 AC_VERB_SET_CONNECT_SEL, 1); 1976 change = sel & 0x80;
1977 if (change) {
1978 snd_hda_codec_write_cache(codec, 0x1d, 0,
1979 AC_VERB_SET_AMP_GAIN_MUTE,
1980 AMP_IN_MUTE(0));
1981 snd_hda_codec_write_cache(codec, 0x1d, 0,
1982 AC_VERB_SET_AMP_GAIN_MUTE,
1983 AMP_IN_UNMUTE(1));
1984 }
1932 sel = snd_hda_codec_read(codec, 0x0b, 0, 1985 sel = snd_hda_codec_read(codec, 0x0b, 0,
1933 AC_VERB_GET_CONNECT_SEL, 0) + 1; 1986 AC_VERB_GET_CONNECT_SEL, 0) + 1;
1934 change |= sel != val; 1987 change |= sel != val;
1935 if (change || codec->in_resume) 1988 if (change)
1936 snd_hda_codec_write(codec, 0x0b, 0, 1989 snd_hda_codec_write_cache(codec, 0x0b, 0,
1937 AC_VERB_SET_CONNECT_SEL, val - 1); 1990 AC_VERB_SET_CONNECT_SEL,
1991 val - 1);
1938 } 1992 }
1939 return change; 1993 return change;
1940} 1994}
@@ -2047,10 +2101,9 @@ static struct hda_verb ad1988_spdif_init_verbs[] = {
2047 {0x02, AC_VERB_SET_CONNECT_SEL, 0x0}, /* PCM */ 2101 {0x02, AC_VERB_SET_CONNECT_SEL, 0x0}, /* PCM */
2048 {0x0b, AC_VERB_SET_CONNECT_SEL, 0x0}, /* ADC1 */ 2102 {0x0b, AC_VERB_SET_CONNECT_SEL, 0x0}, /* ADC1 */
2049 {0x1d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 2103 {0x1d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
2050 {0x1d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 2104 {0x1d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
2051 /* SPDIF out pin */ 2105 /* SPDIF out pin */
2052 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE | 0x27}, /* 0dB */ 2106 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE | 0x27}, /* 0dB */
2053 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0) | 0x17}, /* 0dB */
2054 2107
2055 { } 2108 { }
2056}; 2109};
@@ -2225,6 +2278,15 @@ static void ad1988_laptop_unsol_event(struct hda_codec *codec, unsigned int res)
2225 snd_hda_sequence_write(codec, ad1988_laptop_hp_off); 2278 snd_hda_sequence_write(codec, ad1988_laptop_hp_off);
2226} 2279}
2227 2280
2281#ifdef CONFIG_SND_HDA_POWER_SAVE
2282static struct hda_amp_list ad1988_loopbacks[] = {
2283 { 0x20, HDA_INPUT, 0 }, /* Front Mic */
2284 { 0x20, HDA_INPUT, 1 }, /* Line */
2285 { 0x20, HDA_INPUT, 4 }, /* Mic */
2286 { 0x20, HDA_INPUT, 6 }, /* CD */
2287 { } /* end */
2288};
2289#endif
2228 2290
2229/* 2291/*
2230 * Automatic parse of I/O pins from the BIOS configuration 2292 * Automatic parse of I/O pins from the BIOS configuration
@@ -2663,7 +2725,6 @@ static int patch_ad1988(struct hda_codec *codec)
2663 if (spec == NULL) 2725 if (spec == NULL)
2664 return -ENOMEM; 2726 return -ENOMEM;
2665 2727
2666 mutex_init(&spec->amp_mutex);
2667 codec->spec = spec; 2728 codec->spec = spec;
2668 2729
2669 if (is_rev2(codec)) 2730 if (is_rev2(codec))
@@ -2770,6 +2831,9 @@ static int patch_ad1988(struct hda_codec *codec)
2770 codec->patch_ops.unsol_event = ad1988_laptop_unsol_event; 2831 codec->patch_ops.unsol_event = ad1988_laptop_unsol_event;
2771 break; 2832 break;
2772 } 2833 }
2834#ifdef CONFIG_SND_HDA_POWER_SAVE
2835 spec->loopback.amplist = ad1988_loopbacks;
2836#endif
2773 2837
2774 return 0; 2838 return 0;
2775} 2839}
@@ -2926,6 +2990,16 @@ static struct hda_verb ad1884_init_verbs[] = {
2926 { } /* end */ 2990 { } /* end */
2927}; 2991};
2928 2992
2993#ifdef CONFIG_SND_HDA_POWER_SAVE
2994static struct hda_amp_list ad1884_loopbacks[] = {
2995 { 0x20, HDA_INPUT, 0 }, /* Front Mic */
2996 { 0x20, HDA_INPUT, 1 }, /* Mic */
2997 { 0x20, HDA_INPUT, 2 }, /* CD */
2998 { 0x20, HDA_INPUT, 4 }, /* Docking */
2999 { } /* end */
3000};
3001#endif
3002
2929static int patch_ad1884(struct hda_codec *codec) 3003static int patch_ad1884(struct hda_codec *codec)
2930{ 3004{
2931 struct ad198x_spec *spec; 3005 struct ad198x_spec *spec;
@@ -2950,6 +3024,9 @@ static int patch_ad1884(struct hda_codec *codec)
2950 spec->num_init_verbs = 1; 3024 spec->num_init_verbs = 1;
2951 spec->init_verbs[0] = ad1884_init_verbs; 3025 spec->init_verbs[0] = ad1884_init_verbs;
2952 spec->spdif_route = 0; 3026 spec->spdif_route = 0;
3027#ifdef CONFIG_SND_HDA_POWER_SAVE
3028 spec->loopback.amplist = ad1884_loopbacks;
3029#endif
2953 3030
2954 codec->patch_ops = ad198x_patch_ops; 3031 codec->patch_ops = ad198x_patch_ops;
2955 3032
@@ -3331,6 +3408,16 @@ static struct hda_verb ad1882_init_verbs[] = {
3331 { } /* end */ 3408 { } /* end */
3332}; 3409};
3333 3410
3411#ifdef CONFIG_SND_HDA_POWER_SAVE
3412static struct hda_amp_list ad1882_loopbacks[] = {
3413 { 0x20, HDA_INPUT, 0 }, /* Front Mic */
3414 { 0x20, HDA_INPUT, 1 }, /* Mic */
3415 { 0x20, HDA_INPUT, 4 }, /* Line */
3416 { 0x20, HDA_INPUT, 6 }, /* CD */
3417 { } /* end */
3418};
3419#endif
3420
3334/* models */ 3421/* models */
3335enum { 3422enum {
3336 AD1882_3STACK, 3423 AD1882_3STACK,
@@ -3369,6 +3456,9 @@ static int patch_ad1882(struct hda_codec *codec)
3369 spec->num_init_verbs = 1; 3456 spec->num_init_verbs = 1;
3370 spec->init_verbs[0] = ad1882_init_verbs; 3457 spec->init_verbs[0] = ad1882_init_verbs;
3371 spec->spdif_route = 0; 3458 spec->spdif_route = 0;
3459#ifdef CONFIG_SND_HDA_POWER_SAVE
3460 spec->loopback.amplist = ad1882_loopbacks;
3461#endif
3372 3462
3373 codec->patch_ops = ad198x_patch_ops; 3463 codec->patch_ops = ad198x_patch_ops;
3374 3464