diff mbox

[2/5] ALSA: hda/generic - Fix wrong initial power state for fixed pins

Message ID 1428568838-21550-3-git-send-email-tiwai@suse.de (mailing list archive)
State Accepted
Commit d5ac0100a9027bdf488cf20247b1041f26f796f3
Headers show

Commit Message

Takashi Iwai April 9, 2015, 8:40 a.m. UTC
When the widget power-saving is enabled, the first automute hook
invocation checks through the whole pins and it also tries to
synchronize the power state.  However, this results in a wrong state
because it calls unconditionally snd_hda_jack_detect_state().
This patch adds a check of jack detectability before the actual jack
detection call.

Signed-off-by: Takashi Iwai <tiwai@suse.de>
---
 sound/pci/hda/hda_generic.c | 14 +++++++++++---
 1 file changed, 11 insertions(+), 3 deletions(-)

Comments

Raymond Yau April 10, 2015, 8:51 a.m. UTC | #1
>
> When the widget power-saving is enabled, the first automute hook
> invocation checks through the whole pins and it also tries to
> synchronize the power state.  However, this results in a wrong state
> because it calls unconditionally snd_hda_jack_detect_state().
> This patch adds a check of jack detectability before the actual jack
> detection call.

What happen when the computer has no headphone jack ?

No mic jack and internal mic

Those  thin mini itx motherboard use firmware to disable mixer and remove
all input pins

# Prevent the AA-loopback from being enabled which can pull in white noise
(ACI#380)
[hint]
mixer_nid = 0

Will the driver still power down the audio mixer and audio inputs ?

Seem driver still create capture device when there is no input pins

https://bugs.freedesktop.org/show_bug.cgi?id=54881#c16

https://bugs.freedesktop.org/show_bug.cgi?id=54881#c16
Takashi Iwai April 10, 2015, 9:36 a.m. UTC | #2
At Fri, 10 Apr 2015 16:51:58 +0800,
Raymond Yau wrote:
> 
> >
> > When the widget power-saving is enabled, the first automute hook
> > invocation checks through the whole pins and it also tries to
> > synchronize the power state.  However, this results in a wrong state
> > because it calls unconditionally snd_hda_jack_detect_state().
> > This patch adds a check of jack detectability before the actual jack
> > detection call.
> 
> What happen when the computer has no headphone jack ?

Nothing wrong happens.  The logic of widget power saving is to power
down unused paths.  It includes the paths with pins that aren't
plugged and paths with the DAC/ADCs that aren't enabled (no stream
running).  Fixed pins are handled as always plugged.


Takashi

> 
> No mic jack and internal mic
> 
> Those  thin mini itx motherboard use firmware to disable mixer and remove
> all input pins
> 
> # Prevent the AA-loopback from being enabled which can pull in white noise
> (ACI#380)
> [hint]
> mixer_nid = 0
> 
> Will the driver still power down the audio mixer and audio inputs ?
> 
> Seem driver still create capture device when there is no input pins
> 
> https://bugs.freedesktop.org/show_bug.cgi?id=54881#c16
> 
> https://bugs.freedesktop.org/show_bug.cgi?id=54881#c16
diff mbox

Patch

diff --git a/sound/pci/hda/hda_generic.c b/sound/pci/hda/hda_generic.c
index afc6b1b0898c..46b559832d2c 100644
--- a/sound/pci/hda/hda_generic.c
+++ b/sound/pci/hda/hda_generic.c
@@ -3959,6 +3959,14 @@  static hda_nid_t set_path_power(struct hda_codec *codec, hda_nid_t nid,
 	return changed;
 }
 
+/* check the jack status for power control */
+static bool detect_pin_state(struct hda_codec *codec, hda_nid_t pin)
+{
+	if (!is_jack_detectable(codec, pin))
+		return true;
+	return snd_hda_jack_detect_state(codec, pin) != HDA_JACK_NOT_PRESENT;
+}
+
 /* power up/down the paths of the given pin according to the jack state;
  * power = 0/1 : only power up/down if it matches with the jack state,
  *       < 0   : force power up/down to follow the jack sate
@@ -3973,7 +3981,8 @@  static hda_nid_t set_pin_power_jack(struct hda_codec *codec, hda_nid_t pin,
 	if (!codec->power_save_node)
 		return 0;
 
-	on = snd_hda_jack_detect_state(codec, pin) != HDA_JACK_NOT_PRESENT;
+	on = detect_pin_state(codec, pin);
+
 	if (power >= 0 && on != power)
 		return 0;
 	return set_path_power(codec, pin, on, -1);
@@ -4225,8 +4234,7 @@  static void do_automute(struct hda_codec *codec, int num_pins, hda_nid_t *pins,
 		if (codec->power_save_node) {
 			bool on = !mute;
 			if (on)
-				on = snd_hda_jack_detect_state(codec, nid)
-					!= HDA_JACK_NOT_PRESENT;
+				on = detect_pin_state(codec, nid);
 			set_path_power(codec, nid, on, -1);
 		}
 	}