diff options
Diffstat (limited to 'sound/pci/hda')
-rw-r--r-- | sound/pci/hda/patch_realtek.c | 99 | ||||
-rw-r--r-- | sound/pci/hda/patch_sigmatel.c | 2 |
2 files changed, 92 insertions, 9 deletions
diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c index e72707cb60a3..4eceab9bd109 100644 --- a/sound/pci/hda/patch_realtek.c +++ b/sound/pci/hda/patch_realtek.c | |||
@@ -307,6 +307,13 @@ struct alc_spec { | |||
307 | /* for PLL fix */ | 307 | /* for PLL fix */ |
308 | hda_nid_t pll_nid; | 308 | hda_nid_t pll_nid; |
309 | unsigned int pll_coef_idx, pll_coef_bit; | 309 | unsigned int pll_coef_idx, pll_coef_bit; |
310 | |||
311 | #ifdef SND_HDA_NEEDS_RESUME | ||
312 | #define ALC_MAX_PINS 16 | ||
313 | unsigned int num_pins; | ||
314 | hda_nid_t pin_nids[ALC_MAX_PINS]; | ||
315 | unsigned int pin_cfgs[ALC_MAX_PINS]; | ||
316 | #endif | ||
310 | }; | 317 | }; |
311 | 318 | ||
312 | /* | 319 | /* |
@@ -2778,6 +2785,64 @@ static void alc_free(struct hda_codec *codec) | |||
2778 | codec->spec = NULL; /* to be sure */ | 2785 | codec->spec = NULL; /* to be sure */ |
2779 | } | 2786 | } |
2780 | 2787 | ||
2788 | #ifdef SND_HDA_NEEDS_RESUME | ||
2789 | static void store_pin_configs(struct hda_codec *codec) | ||
2790 | { | ||
2791 | struct alc_spec *spec = codec->spec; | ||
2792 | hda_nid_t nid, end_nid; | ||
2793 | |||
2794 | end_nid = codec->start_nid + codec->num_nodes; | ||
2795 | for (nid = codec->start_nid; nid < end_nid; nid++) { | ||
2796 | unsigned int wid_caps = get_wcaps(codec, nid); | ||
2797 | unsigned int wid_type = | ||
2798 | (wid_caps & AC_WCAP_TYPE) >> AC_WCAP_TYPE_SHIFT; | ||
2799 | if (wid_type != AC_WID_PIN) | ||
2800 | continue; | ||
2801 | if (spec->num_pins >= ARRAY_SIZE(spec->pin_nids)) | ||
2802 | break; | ||
2803 | spec->pin_nids[spec->num_pins] = nid; | ||
2804 | spec->pin_cfgs[spec->num_pins] = | ||
2805 | snd_hda_codec_read(codec, nid, 0, | ||
2806 | AC_VERB_GET_CONFIG_DEFAULT, 0); | ||
2807 | spec->num_pins++; | ||
2808 | } | ||
2809 | } | ||
2810 | |||
2811 | static void resume_pin_configs(struct hda_codec *codec) | ||
2812 | { | ||
2813 | struct alc_spec *spec = codec->spec; | ||
2814 | int i; | ||
2815 | |||
2816 | for (i = 0; i < spec->num_pins; i++) { | ||
2817 | hda_nid_t pin_nid = spec->pin_nids[i]; | ||
2818 | unsigned int pin_config = spec->pin_cfgs[i]; | ||
2819 | snd_hda_codec_write(codec, pin_nid, 0, | ||
2820 | AC_VERB_SET_CONFIG_DEFAULT_BYTES_0, | ||
2821 | pin_config & 0x000000ff); | ||
2822 | snd_hda_codec_write(codec, pin_nid, 0, | ||
2823 | AC_VERB_SET_CONFIG_DEFAULT_BYTES_1, | ||
2824 | (pin_config & 0x0000ff00) >> 8); | ||
2825 | snd_hda_codec_write(codec, pin_nid, 0, | ||
2826 | AC_VERB_SET_CONFIG_DEFAULT_BYTES_2, | ||
2827 | (pin_config & 0x00ff0000) >> 16); | ||
2828 | snd_hda_codec_write(codec, pin_nid, 0, | ||
2829 | AC_VERB_SET_CONFIG_DEFAULT_BYTES_3, | ||
2830 | pin_config >> 24); | ||
2831 | } | ||
2832 | } | ||
2833 | |||
2834 | static int alc_resume(struct hda_codec *codec) | ||
2835 | { | ||
2836 | resume_pin_configs(codec); | ||
2837 | codec->patch_ops.init(codec); | ||
2838 | snd_hda_codec_resume_amp(codec); | ||
2839 | snd_hda_codec_resume_cache(codec); | ||
2840 | return 0; | ||
2841 | } | ||
2842 | #else | ||
2843 | #define store_pin_configs(codec) | ||
2844 | #endif | ||
2845 | |||
2781 | /* | 2846 | /* |
2782 | */ | 2847 | */ |
2783 | static struct hda_codec_ops alc_patch_ops = { | 2848 | static struct hda_codec_ops alc_patch_ops = { |
@@ -2786,6 +2851,9 @@ static struct hda_codec_ops alc_patch_ops = { | |||
2786 | .init = alc_init, | 2851 | .init = alc_init, |
2787 | .free = alc_free, | 2852 | .free = alc_free, |
2788 | .unsol_event = alc_unsol_event, | 2853 | .unsol_event = alc_unsol_event, |
2854 | #ifdef SND_HDA_NEEDS_RESUME | ||
2855 | .resume = alc_resume, | ||
2856 | #endif | ||
2789 | #ifdef CONFIG_SND_HDA_POWER_SAVE | 2857 | #ifdef CONFIG_SND_HDA_POWER_SAVE |
2790 | .check_power_status = alc_check_power_status, | 2858 | .check_power_status = alc_check_power_status, |
2791 | #endif | 2859 | #endif |
@@ -3832,6 +3900,7 @@ static int alc880_parse_auto_config(struct hda_codec *codec) | |||
3832 | spec->num_mux_defs = 1; | 3900 | spec->num_mux_defs = 1; |
3833 | spec->input_mux = &spec->private_imux; | 3901 | spec->input_mux = &spec->private_imux; |
3834 | 3902 | ||
3903 | store_pin_configs(codec); | ||
3835 | return 1; | 3904 | return 1; |
3836 | } | 3905 | } |
3837 | 3906 | ||
@@ -4996,7 +5065,7 @@ static struct hda_verb alc260_test_init_verbs[] = { | |||
4996 | */ | 5065 | */ |
4997 | 5066 | ||
4998 | static int alc260_add_playback_controls(struct alc_spec *spec, hda_nid_t nid, | 5067 | static int alc260_add_playback_controls(struct alc_spec *spec, hda_nid_t nid, |
4999 | const char *pfx) | 5068 | const char *pfx, int *vol_bits) |
5000 | { | 5069 | { |
5001 | hda_nid_t nid_vol; | 5070 | hda_nid_t nid_vol; |
5002 | unsigned long vol_val, sw_val; | 5071 | unsigned long vol_val, sw_val; |
@@ -5018,10 +5087,14 @@ static int alc260_add_playback_controls(struct alc_spec *spec, hda_nid_t nid, | |||
5018 | } else | 5087 | } else |
5019 | return 0; /* N/A */ | 5088 | return 0; /* N/A */ |
5020 | 5089 | ||
5021 | snprintf(name, sizeof(name), "%s Playback Volume", pfx); | 5090 | if (!(*vol_bits & (1 << nid_vol))) { |
5022 | err = add_control(spec, ALC_CTL_WIDGET_VOL, name, vol_val); | 5091 | /* first control for the volume widget */ |
5023 | if (err < 0) | 5092 | snprintf(name, sizeof(name), "%s Playback Volume", pfx); |
5024 | return err; | 5093 | err = add_control(spec, ALC_CTL_WIDGET_VOL, name, vol_val); |
5094 | if (err < 0) | ||
5095 | return err; | ||
5096 | *vol_bits |= (1 << nid_vol); | ||
5097 | } | ||
5025 | snprintf(name, sizeof(name), "%s Playback Switch", pfx); | 5098 | snprintf(name, sizeof(name), "%s Playback Switch", pfx); |
5026 | err = add_control(spec, ALC_CTL_WIDGET_MUTE, name, sw_val); | 5099 | err = add_control(spec, ALC_CTL_WIDGET_MUTE, name, sw_val); |
5027 | if (err < 0) | 5100 | if (err < 0) |
@@ -5035,6 +5108,7 @@ static int alc260_auto_create_multi_out_ctls(struct alc_spec *spec, | |||
5035 | { | 5108 | { |
5036 | hda_nid_t nid; | 5109 | hda_nid_t nid; |
5037 | int err; | 5110 | int err; |
5111 | int vols = 0; | ||
5038 | 5112 | ||
5039 | spec->multiout.num_dacs = 1; | 5113 | spec->multiout.num_dacs = 1; |
5040 | spec->multiout.dac_nids = spec->private_dac_nids; | 5114 | spec->multiout.dac_nids = spec->private_dac_nids; |
@@ -5042,21 +5116,22 @@ static int alc260_auto_create_multi_out_ctls(struct alc_spec *spec, | |||
5042 | 5116 | ||
5043 | nid = cfg->line_out_pins[0]; | 5117 | nid = cfg->line_out_pins[0]; |
5044 | if (nid) { | 5118 | if (nid) { |
5045 | err = alc260_add_playback_controls(spec, nid, "Front"); | 5119 | err = alc260_add_playback_controls(spec, nid, "Front", &vols); |
5046 | if (err < 0) | 5120 | if (err < 0) |
5047 | return err; | 5121 | return err; |
5048 | } | 5122 | } |
5049 | 5123 | ||
5050 | nid = cfg->speaker_pins[0]; | 5124 | nid = cfg->speaker_pins[0]; |
5051 | if (nid) { | 5125 | if (nid) { |
5052 | err = alc260_add_playback_controls(spec, nid, "Speaker"); | 5126 | err = alc260_add_playback_controls(spec, nid, "Speaker", &vols); |
5053 | if (err < 0) | 5127 | if (err < 0) |
5054 | return err; | 5128 | return err; |
5055 | } | 5129 | } |
5056 | 5130 | ||
5057 | nid = cfg->hp_pins[0]; | 5131 | nid = cfg->hp_pins[0]; |
5058 | if (nid) { | 5132 | if (nid) { |
5059 | err = alc260_add_playback_controls(spec, nid, "Headphone"); | 5133 | err = alc260_add_playback_controls(spec, nid, "Headphone", |
5134 | &vols); | ||
5060 | if (err < 0) | 5135 | if (err < 0) |
5061 | return err; | 5136 | return err; |
5062 | } | 5137 | } |
@@ -5244,6 +5319,7 @@ static int alc260_parse_auto_config(struct hda_codec *codec) | |||
5244 | } | 5319 | } |
5245 | spec->num_mixers++; | 5320 | spec->num_mixers++; |
5246 | 5321 | ||
5322 | store_pin_configs(codec); | ||
5247 | return 1; | 5323 | return 1; |
5248 | } | 5324 | } |
5249 | 5325 | ||
@@ -10307,6 +10383,7 @@ static int alc262_parse_auto_config(struct hda_codec *codec) | |||
10307 | if (err < 0) | 10383 | if (err < 0) |
10308 | return err; | 10384 | return err; |
10309 | 10385 | ||
10386 | store_pin_configs(codec); | ||
10310 | return 1; | 10387 | return 1; |
10311 | } | 10388 | } |
10312 | 10389 | ||
@@ -11441,6 +11518,7 @@ static int alc268_parse_auto_config(struct hda_codec *codec) | |||
11441 | if (err < 0) | 11518 | if (err < 0) |
11442 | return err; | 11519 | return err; |
11443 | 11520 | ||
11521 | store_pin_configs(codec); | ||
11444 | return 1; | 11522 | return 1; |
11445 | } | 11523 | } |
11446 | 11524 | ||
@@ -12224,6 +12302,7 @@ static int alc269_parse_auto_config(struct hda_codec *codec) | |||
12224 | spec->mixers[spec->num_mixers] = alc269_capture_mixer; | 12302 | spec->mixers[spec->num_mixers] = alc269_capture_mixer; |
12225 | spec->num_mixers++; | 12303 | spec->num_mixers++; |
12226 | 12304 | ||
12305 | store_pin_configs(codec); | ||
12227 | return 1; | 12306 | return 1; |
12228 | } | 12307 | } |
12229 | 12308 | ||
@@ -13310,6 +13389,7 @@ static int alc861_parse_auto_config(struct hda_codec *codec) | |||
13310 | spec->mixers[spec->num_mixers] = alc861_capture_mixer; | 13389 | spec->mixers[spec->num_mixers] = alc861_capture_mixer; |
13311 | spec->num_mixers++; | 13390 | spec->num_mixers++; |
13312 | 13391 | ||
13392 | store_pin_configs(codec); | ||
13313 | return 1; | 13393 | return 1; |
13314 | } | 13394 | } |
13315 | 13395 | ||
@@ -14421,6 +14501,7 @@ static int alc861vd_parse_auto_config(struct hda_codec *codec) | |||
14421 | if (err < 0) | 14501 | if (err < 0) |
14422 | return err; | 14502 | return err; |
14423 | 14503 | ||
14504 | store_pin_configs(codec); | ||
14424 | return 1; | 14505 | return 1; |
14425 | } | 14506 | } |
14426 | 14507 | ||
@@ -16252,6 +16333,8 @@ static int alc662_parse_auto_config(struct hda_codec *codec) | |||
16252 | 16333 | ||
16253 | spec->mixers[spec->num_mixers] = alc662_capture_mixer; | 16334 | spec->mixers[spec->num_mixers] = alc662_capture_mixer; |
16254 | spec->num_mixers++; | 16335 | spec->num_mixers++; |
16336 | |||
16337 | store_pin_configs(codec); | ||
16255 | return 1; | 16338 | return 1; |
16256 | } | 16339 | } |
16257 | 16340 | ||
diff --git a/sound/pci/hda/patch_sigmatel.c b/sound/pci/hda/patch_sigmatel.c index a2ac7205d45d..788fdc6f3264 100644 --- a/sound/pci/hda/patch_sigmatel.c +++ b/sound/pci/hda/patch_sigmatel.c | |||
@@ -1282,7 +1282,7 @@ static int stac92xx_build_controls(struct hda_codec *codec) | |||
1282 | return err; | 1282 | return err; |
1283 | spec->multiout.share_spdif = 1; | 1283 | spec->multiout.share_spdif = 1; |
1284 | } | 1284 | } |
1285 | if (spec->dig_in_nid && (!spec->gpio_dir & 0x01)) { | 1285 | if (spec->dig_in_nid && !(spec->gpio_dir & 0x01)) { |
1286 | err = snd_hda_create_spdif_in_ctls(codec, spec->dig_in_nid); | 1286 | err = snd_hda_create_spdif_in_ctls(codec, spec->dig_in_nid); |
1287 | if (err < 0) | 1287 | if (err < 0) |
1288 | return err; | 1288 | return err; |