aboutsummaryrefslogtreecommitdiffstats
path: root/sound/pci
diff options
context:
space:
mode:
authorTakashi Iwai <tiwai@suse.de>2015-03-20 13:11:05 -0400
committerTakashi Iwai <tiwai@suse.de>2015-03-20 13:30:48 -0400
commit6b275b140094b701f7ad15272f0597e9d954e5e4 (patch)
tree7275155df0eb7b0783521830fcbba083a6171cb1 /sound/pci
parentfc0daafeb4acf70839db5baf8ec4b861fff3efef (diff)
ALSA: hda - Fix power of pins used for mute LED with vrefs
Some pins are used for controlling the LED with the VREF value. This patch changes the power behavior of such pins to be constantly up. A new state, pin_fixed, is introduced to nid_path to indicate that the path contains the fixed pin. This improves also the readability a bit for other static routes, too. Then a helper function snd_hda_gen_fix_pin_power() is called from the codec driver for such fixed pins, and it will create fake paths containing only these pins with pin_fixed=1 flag. Reported-by: David Henningsson <david.henningsson@canonical.com> Signed-off-by: Takashi Iwai <tiwai@suse.de>
Diffstat (limited to 'sound/pci')
-rw-r--r--sound/pci/hda/hda_generic.c37
-rw-r--r--sound/pci/hda/hda_generic.h2
-rw-r--r--sound/pci/hda/patch_sigmatel.c6
3 files changed, 38 insertions, 7 deletions
diff --git a/sound/pci/hda/hda_generic.c b/sound/pci/hda/hda_generic.c
index d7ca388651da..1cafcbb9d391 100644
--- a/sound/pci/hda/hda_generic.c
+++ b/sound/pci/hda/hda_generic.c
@@ -665,7 +665,7 @@ static bool is_active_nid(struct hda_codec *codec, hda_nid_t nid,
665 if (!path->stream_enabled) 665 if (!path->stream_enabled)
666 continue; 666 continue;
667 /* ignore unplugged paths except for DAC/ADC */ 667 /* ignore unplugged paths except for DAC/ADC */
668 if (!path->pin_enabled && 668 if (!(path->pin_enabled || path->pin_fixed) &&
669 type != AC_WID_AUD_OUT && type != AC_WID_AUD_IN) 669 type != AC_WID_AUD_OUT && type != AC_WID_AUD_IN)
670 continue; 670 continue;
671 } 671 }
@@ -1607,7 +1607,7 @@ static int check_aamix_out_path(struct hda_codec *codec, int path_idx)
1607 return 0; 1607 return 0;
1608 /* print_nid_path(codec, "output-aamix", path); */ 1608 /* print_nid_path(codec, "output-aamix", path); */
1609 path->active = false; /* unused as default */ 1609 path->active = false; /* unused as default */
1610 path->pin_enabled = true; /* static route */ 1610 path->pin_fixed = true; /* static route */
1611 return snd_hda_get_path_idx(codec, path); 1611 return snd_hda_get_path_idx(codec, path);
1612} 1612}
1613 1613
@@ -3044,7 +3044,7 @@ static int new_analog_input(struct hda_codec *codec, int input_idx,
3044 if (path) { 3044 if (path) {
3045 print_nid_path(codec, "loopback-merge", path); 3045 print_nid_path(codec, "loopback-merge", path);
3046 path->active = true; 3046 path->active = true;
3047 path->pin_enabled = true; /* static route */ 3047 path->pin_fixed = true; /* static route */
3048 path->stream_enabled = true; /* no DAC/ADC involved */ 3048 path->stream_enabled = true; /* no DAC/ADC involved */
3049 spec->loopback_merge_path = 3049 spec->loopback_merge_path =
3050 snd_hda_get_path_idx(codec, path); 3050 snd_hda_get_path_idx(codec, path);
@@ -3847,7 +3847,7 @@ static void parse_digital(struct hda_codec *codec)
3847 continue; 3847 continue;
3848 print_nid_path(codec, "digout", path); 3848 print_nid_path(codec, "digout", path);
3849 path->active = true; 3849 path->active = true;
3850 path->pin_enabled = true; /* no jack detection */ 3850 path->pin_fixed = true; /* no jack detection */
3851 spec->digout_paths[i] = snd_hda_get_path_idx(codec, path); 3851 spec->digout_paths[i] = snd_hda_get_path_idx(codec, path);
3852 set_pin_target(codec, pin, PIN_OUT, false); 3852 set_pin_target(codec, pin, PIN_OUT, false);
3853 if (!nums) { 3853 if (!nums) {
@@ -3875,7 +3875,7 @@ static void parse_digital(struct hda_codec *codec)
3875 if (path) { 3875 if (path) {
3876 print_nid_path(codec, "digin", path); 3876 print_nid_path(codec, "digin", path);
3877 path->active = true; 3877 path->active = true;
3878 path->pin_enabled = true; /* no jack */ 3878 path->pin_fixed = true; /* no jack */
3879 spec->dig_in_nid = dig_nid; 3879 spec->dig_in_nid = dig_nid;
3880 spec->digin_path = snd_hda_get_path_idx(codec, path); 3880 spec->digin_path = snd_hda_get_path_idx(codec, path);
3881 set_pin_target(codec, pin, PIN_IN, false); 3881 set_pin_target(codec, pin, PIN_IN, false);
@@ -3959,8 +3959,8 @@ static hda_nid_t set_path_power(struct hda_codec *codec, hda_nid_t nid,
3959 path->pin_enabled = pin_state; 3959 path->pin_enabled = pin_state;
3960 if (stream_state >= 0) 3960 if (stream_state >= 0)
3961 path->stream_enabled = stream_state; 3961 path->stream_enabled = stream_state;
3962 if (path->pin_enabled != pin_old || 3962 if ((!path->pin_fixed && path->pin_enabled != pin_old)
3963 path->stream_enabled != stream_old) { 3963 || path->stream_enabled != stream_old) {
3964 last = path_power_update(codec, path, true); 3964 last = path_power_update(codec, path, true);
3965 if (last) 3965 if (last)
3966 changed = last; 3966 changed = last;
@@ -4136,6 +4136,29 @@ static void beep_power_hook(struct hda_beep *beep, bool on)
4136 set_path_power(beep->codec, beep->nid, -1, on); 4136 set_path_power(beep->codec, beep->nid, -1, on);
4137} 4137}
4138 4138
4139/**
4140 * snd_hda_gen_fix_pin_power - Fix the power of the given pin widget to D0
4141 * @codec: the HDA codec
4142 * @pin: NID of pin to fix
4143 */
4144int snd_hda_gen_fix_pin_power(struct hda_codec *codec, hda_nid_t pin)
4145{
4146 struct hda_gen_spec *spec = codec->spec;
4147 struct nid_path *path;
4148
4149 path = snd_array_new(&spec->paths);
4150 if (!path)
4151 return -ENOMEM;
4152 memset(path, 0, sizeof(*path));
4153 path->depth = 1;
4154 path->path[0] = pin;
4155 path->active = true;
4156 path->pin_fixed = true;
4157 path->stream_enabled = true;
4158 return 0;
4159}
4160EXPORT_SYMBOL_GPL(snd_hda_gen_fix_pin_power);
4161
4139/* 4162/*
4140 * Jack detections for HP auto-mute and mic-switch 4163 * Jack detections for HP auto-mute and mic-switch
4141 */ 4164 */
diff --git a/sound/pci/hda/hda_generic.h b/sound/pci/hda/hda_generic.h
index 54659b51fe16..56e4139b9032 100644
--- a/sound/pci/hda/hda_generic.h
+++ b/sound/pci/hda/hda_generic.h
@@ -48,6 +48,7 @@ struct nid_path {
48 unsigned int ctls[NID_PATH_NUM_CTLS]; /* NID_PATH_XXX_CTL */ 48 unsigned int ctls[NID_PATH_NUM_CTLS]; /* NID_PATH_XXX_CTL */
49 bool active:1; /* activated by driver */ 49 bool active:1; /* activated by driver */
50 bool pin_enabled:1; /* pins are enabled */ 50 bool pin_enabled:1; /* pins are enabled */
51 bool pin_fixed:1; /* path with fixed pin */
51 bool stream_enabled:1; /* stream is active */ 52 bool stream_enabled:1; /* stream is active */
52}; 53};
53 54
@@ -343,5 +344,6 @@ unsigned int snd_hda_gen_path_power_filter(struct hda_codec *codec,
343 hda_nid_t nid, 344 hda_nid_t nid,
344 unsigned int power_state); 345 unsigned int power_state);
345void snd_hda_gen_stream_pm(struct hda_codec *codec, hda_nid_t nid, bool on); 346void snd_hda_gen_stream_pm(struct hda_codec *codec, hda_nid_t nid, bool on);
347int snd_hda_gen_fix_pin_power(struct hda_codec *codec, hda_nid_t pin);
346 348
347#endif /* __SOUND_HDA_GENERIC_H */ 349#endif /* __SOUND_HDA_GENERIC_H */
diff --git a/sound/pci/hda/patch_sigmatel.c b/sound/pci/hda/patch_sigmatel.c
index 86b944a6b0ed..7e531d5cde51 100644
--- a/sound/pci/hda/patch_sigmatel.c
+++ b/sound/pci/hda/patch_sigmatel.c
@@ -4225,6 +4225,12 @@ static int stac_parse_auto_config(struct hda_codec *codec)
4225 if (err < 0) 4225 if (err < 0)
4226 return err; 4226 return err;
4227 4227
4228 if (spec->vref_mute_led_nid) {
4229 err = snd_hda_gen_fix_pin_power(codec, spec->vref_mute_led_nid);
4230 if (err < 0)
4231 return err;
4232 }
4233
4228 /* setup analog beep controls */ 4234 /* setup analog beep controls */
4229 if (spec->anabeep_nid > 0) { 4235 if (spec->anabeep_nid > 0) {
4230 err = stac_auto_create_beep_ctls(codec, 4236 err = stac_auto_create_beep_ctls(codec,