aboutsummaryrefslogtreecommitdiffstats
path: root/sound/pci/hda
diff options
context:
space:
mode:
Diffstat (limited to 'sound/pci/hda')
-rw-r--r--sound/pci/hda/patch_realtek.c99
-rw-r--r--sound/pci/hda/patch_sigmatel.c2
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
2789static 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
2811static 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
2834static 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 */
2783static struct hda_codec_ops alc_patch_ops = { 2848static 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
4998static int alc260_add_playback_controls(struct alc_spec *spec, hda_nid_t nid, 5067static 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;