aboutsummaryrefslogtreecommitdiffstats
path: root/sound/pci/hda/patch_realtek.c
diff options
context:
space:
mode:
Diffstat (limited to 'sound/pci/hda/patch_realtek.c')
-rw-r--r--sound/pci/hda/patch_realtek.c125
1 files changed, 120 insertions, 5 deletions
diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c
index c7465053d6bb..aeb23ef6afe5 100644
--- a/sound/pci/hda/patch_realtek.c
+++ b/sound/pci/hda/patch_realtek.c
@@ -633,6 +633,7 @@ static int alc_pin_mode_put(struct snd_kcontrol *kcontrol,
633 633
634#define ALC_PIN_MODE(xname, nid, dir) \ 634#define ALC_PIN_MODE(xname, nid, dir) \
635 { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = 0, \ 635 { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = 0, \
636 .subdevice = HDA_SUBDEV_NID_FLAG | nid, \
636 .info = alc_pin_mode_info, \ 637 .info = alc_pin_mode_info, \
637 .get = alc_pin_mode_get, \ 638 .get = alc_pin_mode_get, \
638 .put = alc_pin_mode_put, \ 639 .put = alc_pin_mode_put, \
@@ -684,6 +685,7 @@ static int alc_gpio_data_put(struct snd_kcontrol *kcontrol,
684} 685}
685#define ALC_GPIO_DATA_SWITCH(xname, nid, mask) \ 686#define ALC_GPIO_DATA_SWITCH(xname, nid, mask) \
686 { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = 0, \ 687 { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = 0, \
688 .subdevice = HDA_SUBDEV_NID_FLAG | nid, \
687 .info = alc_gpio_data_info, \ 689 .info = alc_gpio_data_info, \
688 .get = alc_gpio_data_get, \ 690 .get = alc_gpio_data_get, \
689 .put = alc_gpio_data_put, \ 691 .put = alc_gpio_data_put, \
@@ -738,6 +740,7 @@ static int alc_spdif_ctrl_put(struct snd_kcontrol *kcontrol,
738} 740}
739#define ALC_SPDIF_CTRL_SWITCH(xname, nid, mask) \ 741#define ALC_SPDIF_CTRL_SWITCH(xname, nid, mask) \
740 { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = 0, \ 742 { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = 0, \
743 .subdevice = HDA_SUBDEV_NID_FLAG | nid, \
741 .info = alc_spdif_ctrl_info, \ 744 .info = alc_spdif_ctrl_info, \
742 .get = alc_spdif_ctrl_get, \ 745 .get = alc_spdif_ctrl_get, \
743 .put = alc_spdif_ctrl_put, \ 746 .put = alc_spdif_ctrl_put, \
@@ -791,6 +794,7 @@ static int alc_eapd_ctrl_put(struct snd_kcontrol *kcontrol,
791 794
792#define ALC_EAPD_CTRL_SWITCH(xname, nid, mask) \ 795#define ALC_EAPD_CTRL_SWITCH(xname, nid, mask) \
793 { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = 0, \ 796 { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = 0, \
797 .subdevice = HDA_SUBDEV_NID_FLAG | nid, \
794 .info = alc_eapd_ctrl_info, \ 798 .info = alc_eapd_ctrl_info, \
795 .get = alc_eapd_ctrl_get, \ 799 .get = alc_eapd_ctrl_get, \
796 .put = alc_eapd_ctrl_put, \ 800 .put = alc_eapd_ctrl_put, \
@@ -2443,6 +2447,15 @@ static const char *alc_slave_sws[] = {
2443 * build control elements 2447 * build control elements
2444 */ 2448 */
2445 2449
2450#define NID_MAPPING (-1)
2451
2452#define SUBDEV_SPEAKER_ (0 << 6)
2453#define SUBDEV_HP_ (1 << 6)
2454#define SUBDEV_LINE_ (2 << 6)
2455#define SUBDEV_SPEAKER(x) (SUBDEV_SPEAKER_ | ((x) & 0x3f))
2456#define SUBDEV_HP(x) (SUBDEV_HP_ | ((x) & 0x3f))
2457#define SUBDEV_LINE(x) (SUBDEV_LINE_ | ((x) & 0x3f))
2458
2446static void alc_free_kctls(struct hda_codec *codec); 2459static void alc_free_kctls(struct hda_codec *codec);
2447 2460
2448#ifdef CONFIG_SND_HDA_INPUT_BEEP 2461#ifdef CONFIG_SND_HDA_INPUT_BEEP
@@ -2457,8 +2470,11 @@ static struct snd_kcontrol_new alc_beep_mixer[] = {
2457static int alc_build_controls(struct hda_codec *codec) 2470static int alc_build_controls(struct hda_codec *codec)
2458{ 2471{
2459 struct alc_spec *spec = codec->spec; 2472 struct alc_spec *spec = codec->spec;
2460 int err; 2473 struct snd_kcontrol *kctl;
2461 int i; 2474 struct snd_kcontrol_new *knew;
2475 int i, j, err;
2476 unsigned int u;
2477 hda_nid_t nid;
2462 2478
2463 for (i = 0; i < spec->num_mixers; i++) { 2479 for (i = 0; i < spec->num_mixers; i++) {
2464 err = snd_hda_add_new_ctls(codec, spec->mixers[i]); 2480 err = snd_hda_add_new_ctls(codec, spec->mixers[i]);
@@ -2499,8 +2515,7 @@ static int alc_build_controls(struct hda_codec *codec)
2499 if (!kctl) 2515 if (!kctl)
2500 return -ENOMEM; 2516 return -ENOMEM;
2501 kctl->private_value = spec->beep_amp; 2517 kctl->private_value = spec->beep_amp;
2502 err = snd_hda_ctl_add(codec, 2518 err = snd_hda_ctl_add(codec, 0, kctl);
2503 get_amp_nid_(spec->beep_amp), kctl);
2504 if (err < 0) 2519 if (err < 0)
2505 return err; 2520 return err;
2506 } 2521 }
@@ -2527,6 +2542,73 @@ static int alc_build_controls(struct hda_codec *codec)
2527 } 2542 }
2528 2543
2529 alc_free_kctls(codec); /* no longer needed */ 2544 alc_free_kctls(codec); /* no longer needed */
2545
2546 /* assign Capture Source enums to NID */
2547 kctl = snd_hda_find_mixer_ctl(codec, "Capture Source");
2548 if (!kctl)
2549 kctl = snd_hda_find_mixer_ctl(codec, "Input Source");
2550 for (i = 0; kctl && i < kctl->count; i++) {
2551 err = snd_hda_add_nids(codec, kctl, i, spec->capsrc_nids,
2552 spec->input_mux->num_items);
2553 if (err < 0)
2554 return err;
2555 }
2556 if (spec->cap_mixer) {
2557 const char *kname = kctl ? kctl->id.name : NULL;
2558 for (knew = spec->cap_mixer; knew->name; knew++) {
2559 if (kname && strcmp(knew->name, kname) == 0)
2560 continue;
2561 kctl = snd_hda_find_mixer_ctl(codec, knew->name);
2562 for (i = 0; kctl && i < kctl->count; i++) {
2563 err = snd_hda_add_nid(codec, kctl, i,
2564 spec->adc_nids[i]);
2565 if (err < 0)
2566 return err;
2567 }
2568 }
2569 }
2570
2571 /* other nid->control mapping */
2572 for (i = 0; i < spec->num_mixers; i++) {
2573 for (knew = spec->mixers[i]; knew->name; knew++) {
2574 if (knew->iface != NID_MAPPING)
2575 continue;
2576 kctl = snd_hda_find_mixer_ctl(codec, knew->name);
2577 if (kctl == NULL)
2578 continue;
2579 u = knew->subdevice;
2580 for (j = 0; j < 4; j++, u >>= 8) {
2581 nid = u & 0x3f;
2582 if (nid == 0)
2583 continue;
2584 switch (u & 0xc0) {
2585 case SUBDEV_SPEAKER_:
2586 nid = spec->autocfg.speaker_pins[nid];
2587 break;
2588 case SUBDEV_LINE_:
2589 nid = spec->autocfg.line_out_pins[nid];
2590 break;
2591 case SUBDEV_HP_:
2592 nid = spec->autocfg.hp_pins[nid];
2593 break;
2594 default:
2595 continue;
2596 }
2597 err = snd_hda_add_nid(codec, kctl, 0, nid);
2598 if (err < 0)
2599 return err;
2600 }
2601 u = knew->private_value;
2602 for (j = 0; j < 4; j++, u >>= 8) {
2603 nid = u & 0xff;
2604 if (nid == 0)
2605 continue;
2606 err = snd_hda_add_nid(codec, kctl, 0, nid);
2607 if (err < 0)
2608 return err;
2609 }
2610 }
2611 }
2530 return 0; 2612 return 0;
2531} 2613}
2532 2614
@@ -3832,6 +3914,7 @@ static int alc_test_pin_src_put(struct snd_kcontrol *kcontrol,
3832#define PIN_CTL_TEST(xname,nid) { \ 3914#define PIN_CTL_TEST(xname,nid) { \
3833 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \ 3915 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
3834 .name = xname, \ 3916 .name = xname, \
3917 .subdevice = HDA_SUBDEV_NID_FLAG | nid, \
3835 .info = alc_test_pin_ctl_info, \ 3918 .info = alc_test_pin_ctl_info, \
3836 .get = alc_test_pin_ctl_get, \ 3919 .get = alc_test_pin_ctl_get, \
3837 .put = alc_test_pin_ctl_put, \ 3920 .put = alc_test_pin_ctl_put, \
@@ -3841,6 +3924,7 @@ static int alc_test_pin_src_put(struct snd_kcontrol *kcontrol,
3841#define PIN_SRC_TEST(xname,nid) { \ 3924#define PIN_SRC_TEST(xname,nid) { \
3842 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \ 3925 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
3843 .name = xname, \ 3926 .name = xname, \
3927 .subdevice = HDA_SUBDEV_NID_FLAG | nid, \
3844 .info = alc_test_pin_src_info, \ 3928 .info = alc_test_pin_src_info, \
3845 .get = alc_test_pin_src_get, \ 3929 .get = alc_test_pin_src_get, \
3846 .put = alc_test_pin_src_put, \ 3930 .put = alc_test_pin_src_put, \
@@ -4380,7 +4464,7 @@ static int add_control(struct alc_spec *spec, int type, const char *name,
4380 if (!knew->name) 4464 if (!knew->name)
4381 return -ENOMEM; 4465 return -ENOMEM;
4382 if (get_amp_nid_(val)) 4466 if (get_amp_nid_(val))
4383 knew->subdevice = HDA_SUBDEV_NID_FLAG | get_amp_nid_(val); 4467 knew->subdevice = HDA_SUBDEV_AMP_FLAG;
4384 knew->private_value = val; 4468 knew->private_value = val;
4385 return 0; 4469 return 0;
4386} 4470}
@@ -5131,6 +5215,7 @@ static struct snd_kcontrol_new alc260_hp_output_mixer[] = {
5131 { 5215 {
5132 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 5216 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
5133 .name = "Master Playback Switch", 5217 .name = "Master Playback Switch",
5218 .subdevice = HDA_SUBDEV_NID_FLAG | 0x11,
5134 .info = snd_ctl_boolean_mono_info, 5219 .info = snd_ctl_boolean_mono_info,
5135 .get = alc260_hp_master_sw_get, 5220 .get = alc260_hp_master_sw_get,
5136 .put = alc260_hp_master_sw_put, 5221 .put = alc260_hp_master_sw_put,
@@ -5169,6 +5254,7 @@ static struct snd_kcontrol_new alc260_hp_3013_mixer[] = {
5169 { 5254 {
5170 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 5255 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
5171 .name = "Master Playback Switch", 5256 .name = "Master Playback Switch",
5257 .subdevice = HDA_SUBDEV_NID_FLAG | 0x11,
5172 .info = snd_ctl_boolean_mono_info, 5258 .info = snd_ctl_boolean_mono_info,
5173 .get = alc260_hp_master_sw_get, 5259 .get = alc260_hp_master_sw_get,
5174 .put = alc260_hp_master_sw_put, 5260 .put = alc260_hp_master_sw_put,
@@ -10248,8 +10334,14 @@ static int alc262_hp_master_sw_put(struct snd_kcontrol *kcontrol,
10248 .info = snd_ctl_boolean_mono_info, \ 10334 .info = snd_ctl_boolean_mono_info, \
10249 .get = alc262_hp_master_sw_get, \ 10335 .get = alc262_hp_master_sw_get, \
10250 .put = alc262_hp_master_sw_put, \ 10336 .put = alc262_hp_master_sw_put, \
10337 }, \
10338 { \
10339 .iface = NID_MAPPING, \
10340 .name = "Master Playback Switch", \
10341 .private_value = 0x15 | (0x16 << 8) | (0x1b << 16), \
10251 } 10342 }
10252 10343
10344
10253static struct snd_kcontrol_new alc262_HP_BPC_mixer[] = { 10345static struct snd_kcontrol_new alc262_HP_BPC_mixer[] = {
10254 ALC262_HP_MASTER_SWITCH, 10346 ALC262_HP_MASTER_SWITCH,
10255 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT), 10347 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
@@ -10407,6 +10499,12 @@ static int alc262_hippo_master_sw_put(struct snd_kcontrol *kcontrol,
10407 .info = snd_ctl_boolean_mono_info, \ 10499 .info = snd_ctl_boolean_mono_info, \
10408 .get = alc262_hippo_master_sw_get, \ 10500 .get = alc262_hippo_master_sw_get, \
10409 .put = alc262_hippo_master_sw_put, \ 10501 .put = alc262_hippo_master_sw_put, \
10502 }, \
10503 { \
10504 .iface = NID_MAPPING, \
10505 .name = "Master Playback Switch", \
10506 .subdevice = SUBDEV_HP(0) | (SUBDEV_LINE(0) << 8) | \
10507 (SUBDEV_SPEAKER(0) << 16), \
10410 } 10508 }
10411 10509
10412static struct snd_kcontrol_new alc262_hippo_mixer[] = { 10510static struct snd_kcontrol_new alc262_hippo_mixer[] = {
@@ -10887,11 +10985,17 @@ static struct snd_kcontrol_new alc262_fujitsu_mixer[] = {
10887 { 10985 {
10888 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 10986 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
10889 .name = "Master Playback Switch", 10987 .name = "Master Playback Switch",
10988 .subdevice = HDA_SUBDEV_AMP_FLAG,
10890 .info = snd_hda_mixer_amp_switch_info, 10989 .info = snd_hda_mixer_amp_switch_info,
10891 .get = snd_hda_mixer_amp_switch_get, 10990 .get = snd_hda_mixer_amp_switch_get,
10892 .put = alc262_fujitsu_master_sw_put, 10991 .put = alc262_fujitsu_master_sw_put,
10893 .private_value = HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT), 10992 .private_value = HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
10894 }, 10993 },
10994 {
10995 .iface = NID_MAPPING,
10996 .name = "Master Playback Switch",
10997 .private_value = 0x1b,
10998 },
10895 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT), 10999 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
10896 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT), 11000 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
10897 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT), 11001 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
@@ -10922,6 +11026,7 @@ static struct snd_kcontrol_new alc262_lenovo_3000_mixer[] = {
10922 { 11026 {
10923 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 11027 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
10924 .name = "Master Playback Switch", 11028 .name = "Master Playback Switch",
11029 .subdevice = HDA_SUBDEV_AMP_FLAG,
10925 .info = snd_hda_mixer_amp_switch_info, 11030 .info = snd_hda_mixer_amp_switch_info,
10926 .get = snd_hda_mixer_amp_switch_get, 11031 .get = snd_hda_mixer_amp_switch_get,
10927 .put = alc262_lenovo_3000_master_sw_put, 11032 .put = alc262_lenovo_3000_master_sw_put,
@@ -11076,6 +11181,11 @@ static struct snd_kcontrol_new alc262_ultra_capture_mixer[] = {
11076 .get = alc_mux_enum_get, 11181 .get = alc_mux_enum_get,
11077 .put = alc262_ultra_mux_enum_put, 11182 .put = alc262_ultra_mux_enum_put,
11078 }, 11183 },
11184 {
11185 .iface = NID_MAPPING,
11186 .name = "Capture Source",
11187 .private_value = 0x15,
11188 },
11079 { } /* end */ 11189 { } /* end */
11080}; 11190};
11081 11191
@@ -12094,6 +12204,7 @@ static struct snd_kcontrol_new alc268_acer_aspire_one_mixer[] = {
12094 { 12204 {
12095 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 12205 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
12096 .name = "Master Playback Switch", 12206 .name = "Master Playback Switch",
12207 .subdevice = HDA_SUBDEV_AMP_FLAG,
12097 .info = snd_hda_mixer_amp_switch_info, 12208 .info = snd_hda_mixer_amp_switch_info,
12098 .get = snd_hda_mixer_amp_switch_get, 12209 .get = snd_hda_mixer_amp_switch_get,
12099 .put = alc268_acer_master_sw_put, 12210 .put = alc268_acer_master_sw_put,
@@ -12109,6 +12220,7 @@ static struct snd_kcontrol_new alc268_acer_mixer[] = {
12109 { 12220 {
12110 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 12221 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
12111 .name = "Master Playback Switch", 12222 .name = "Master Playback Switch",
12223 .subdevice = HDA_SUBDEV_AMP_FLAG,
12112 .info = snd_hda_mixer_amp_switch_info, 12224 .info = snd_hda_mixer_amp_switch_info,
12113 .get = snd_hda_mixer_amp_switch_get, 12225 .get = snd_hda_mixer_amp_switch_get,
12114 .put = alc268_acer_master_sw_put, 12226 .put = alc268_acer_master_sw_put,
@@ -12126,6 +12238,7 @@ static struct snd_kcontrol_new alc268_acer_dmic_mixer[] = {
12126 { 12238 {
12127 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 12239 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
12128 .name = "Master Playback Switch", 12240 .name = "Master Playback Switch",
12241 .subdevice = HDA_SUBDEV_AMP_FLAG,
12129 .info = snd_hda_mixer_amp_switch_info, 12242 .info = snd_hda_mixer_amp_switch_info,
12130 .get = snd_hda_mixer_amp_switch_get, 12243 .get = snd_hda_mixer_amp_switch_get,
12131 .put = alc268_acer_master_sw_put, 12244 .put = alc268_acer_master_sw_put,
@@ -13078,6 +13191,7 @@ static struct snd_kcontrol_new alc269_quanta_fl1_mixer[] = {
13078 { 13191 {
13079 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 13192 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
13080 .name = "Master Playback Switch", 13193 .name = "Master Playback Switch",
13194 .subdevice = HDA_SUBDEV_AMP_FLAG,
13081 .info = snd_hda_mixer_amp_switch_info, 13195 .info = snd_hda_mixer_amp_switch_info,
13082 .get = snd_hda_mixer_amp_switch_get, 13196 .get = snd_hda_mixer_amp_switch_get,
13083 .put = alc268_acer_master_sw_put, 13197 .put = alc268_acer_master_sw_put,
@@ -13098,6 +13212,7 @@ static struct snd_kcontrol_new alc269_lifebook_mixer[] = {
13098 { 13212 {
13099 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 13213 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
13100 .name = "Master Playback Switch", 13214 .name = "Master Playback Switch",
13215 .subdevice = HDA_SUBDEV_AMP_FLAG,
13101 .info = snd_hda_mixer_amp_switch_info, 13216 .info = snd_hda_mixer_amp_switch_info,
13102 .get = snd_hda_mixer_amp_switch_get, 13217 .get = snd_hda_mixer_amp_switch_get,
13103 .put = alc268_acer_master_sw_put, 13218 .put = alc268_acer_master_sw_put,