All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH 0/4] More aggressive PM for HD-audio
@ 2015-03-18  8:50 Takashi Iwai
  2015-03-18  8:50 ` [PATCH 1/4] ALSA: hda - Simplify PCM setup overrides Takashi Iwai
                   ` (5 more replies)
  0 siblings, 6 replies; 21+ messages in thread
From: Takashi Iwai @ 2015-03-18  8:50 UTC (permalink / raw)
  To: alsa-devel; +Cc: David Henningsson

Hi,

here is a patchset for supporting more aggressive PM for HD-audio.
This allows to change the power state of each widget more dynamically
with jack and stream states.  It's activated only when the codec
driver (or via sysfs or f/w patch) sets codec->power_mgmt flag.

In theory, this should work for the recent Realtek codecs, but
currently I have no machine for test.

David, could you or your team check whether this works for ALC282 or
such?  Just add like:

--- a/sound/pci/hda/patch_realtek.c
+++ b/sound/pci/hda/patch_realtek.c
@@ -5415,6 +5415,7 @@ static int patch_alc269(struct hda_codec *codec)
 
 	spec = codec->spec;
 	spec->gen.shared_mic_vref_pin = 0x18;
+	codec->power_mgmt = 1;
 
 	snd_hda_pick_fixup(codec, alc269_fixup_models,
 		       alc269_fixup_tbl, alc269_fixups);


The patchset is for for-next branch of sound git tree, but they might
be applicable to 4.0-rc (or even older), too.  The current patches are
found in topic/hda-power branch.


thanks,

Takashi

===

Takashi Iwai (4):
  ALSA: hda - Simplify PCM setup overrides
  ALSA: hda - Support advanced power state controls
  ALSA: hda - Use the new power control for VIA codecs
  ALSA: hda - Adjust power of beep widget and outputs

 sound/pci/hda/hda_beep.c       |  29 +-
 sound/pci/hda/hda_beep.h       |   1 +
 sound/pci/hda/hda_codec.c      |   4 +
 sound/pci/hda/hda_codec.h      |   2 +
 sound/pci/hda/hda_generic.c    | 480 ++++++++++++++++++++++++------
 sound/pci/hda/hda_generic.h    |   5 +-
 sound/pci/hda/patch_realtek.c  |  41 ---
 sound/pci/hda/patch_sigmatel.c |   5 +
 sound/pci/hda/patch_via.c      | 662 +----------------------------------------
 9 files changed, 427 insertions(+), 802 deletions(-)

-- 
2.3.3

^ permalink raw reply	[flat|nested] 21+ messages in thread

* [PATCH 1/4] ALSA: hda - Simplify PCM setup overrides
  2015-03-18  8:50 [PATCH 0/4] More aggressive PM for HD-audio Takashi Iwai
@ 2015-03-18  8:50 ` Takashi Iwai
  2015-03-18  8:50 ` [PATCH 2/4] ALSA: hda - Support advanced power state controls Takashi Iwai
                   ` (4 subsequent siblings)
  5 siblings, 0 replies; 21+ messages in thread
From: Takashi Iwai @ 2015-03-18  8:50 UTC (permalink / raw)
  To: alsa-devel; +Cc: David Henningsson

This patch does two things:
- code refactoring with a local helper function,
- allow codec drivers to provide the specific PCM stream info pointers
  only for overriding the non-NULL entries, instead of copying the
  whole.

This simplifies the codec driver side (currently the only user is
alc269's 44kHz fixed rate).

Signed-off-by: Takashi Iwai <tiwai@suse.de>
---
 sound/pci/hda/hda_generic.c   | 110 +++++++++++++++++++++++-------------------
 sound/pci/hda/patch_realtek.c |  41 ----------------
 2 files changed, 60 insertions(+), 91 deletions(-)

diff --git a/sound/pci/hda/hda_generic.c b/sound/pci/hda/hda_generic.c
index ebdbc023583d..27ce54701f0f 100644
--- a/sound/pci/hda/hda_generic.c
+++ b/sound/pci/hda/hda_generic.c
@@ -5137,6 +5137,33 @@ static void fill_pcm_stream_name(char *str, size_t len, const char *sfx,
 	strlcat(str, sfx, len);
 }
 
+/* copy PCM stream info from @default_str, and override non-NULL entries
+ * from @spec_str and @nid
+ */
+static void setup_pcm_stream(struct hda_pcm_stream *str,
+			     const struct hda_pcm_stream *default_str,
+			     const struct hda_pcm_stream *spec_str,
+			     hda_nid_t nid)
+{
+	*str = *default_str;
+	if (nid)
+		str->nid = nid;
+	if (spec_str) {
+		if (spec_str->substreams)
+			str->substreams = spec_str->substreams;
+		if (spec_str->channels_min)
+			str->channels_min = spec_str->channels_min;
+		if (spec_str->channels_max)
+			str->channels_max = spec_str->channels_max;
+		if (spec_str->rates)
+			str->rates = spec_str->rates;
+		if (spec_str->formats)
+			str->formats = spec_str->formats;
+		if (spec_str->maxbps)
+			str->maxbps = spec_str->maxbps;
+	}
+}
+
 /**
  * snd_hda_gen_build_pcms - build PCM streams based on the parsed results
  * @codec: the HDA codec
@@ -5147,7 +5174,6 @@ int snd_hda_gen_build_pcms(struct hda_codec *codec)
 {
 	struct hda_gen_spec *spec = codec->spec;
 	struct hda_pcm *info;
-	const struct hda_pcm_stream *p;
 	bool have_multi_adcs;
 
 	if (spec->no_analog)
@@ -5162,11 +5188,10 @@ int snd_hda_gen_build_pcms(struct hda_codec *codec)
 	spec->pcm_rec[0] = info;
 
 	if (spec->multiout.num_dacs > 0) {
-		p = spec->stream_analog_playback;
-		if (!p)
-			p = &pcm_analog_playback;
-		info->stream[SNDRV_PCM_STREAM_PLAYBACK] = *p;
-		info->stream[SNDRV_PCM_STREAM_PLAYBACK].nid = spec->multiout.dac_nids[0];
+		setup_pcm_stream(&info->stream[SNDRV_PCM_STREAM_PLAYBACK],
+				 &pcm_analog_playback,
+				 spec->stream_analog_playback,
+				 spec->multiout.dac_nids[0]);
 		info->stream[SNDRV_PCM_STREAM_PLAYBACK].channels_max =
 			spec->multiout.max_channels;
 		if (spec->autocfg.line_out_type == AUTO_PIN_SPEAKER_OUT &&
@@ -5175,15 +5200,11 @@ int snd_hda_gen_build_pcms(struct hda_codec *codec)
 				snd_pcm_2_1_chmaps;
 	}
 	if (spec->num_adc_nids) {
-		p = spec->stream_analog_capture;
-		if (!p) {
-			if (spec->dyn_adc_switch)
-				p = &dyn_adc_pcm_analog_capture;
-			else
-				p = &pcm_analog_capture;
-		}
-		info->stream[SNDRV_PCM_STREAM_CAPTURE] = *p;
-		info->stream[SNDRV_PCM_STREAM_CAPTURE].nid = spec->adc_nids[0];
+		setup_pcm_stream(&info->stream[SNDRV_PCM_STREAM_CAPTURE],
+				 (spec->dyn_adc_switch ?
+				  &dyn_adc_pcm_analog_capture : &pcm_analog_capture),
+				 spec->stream_analog_capture,
+				 spec->adc_nids[0]);
 	}
 
  skip_analog:
@@ -5202,20 +5223,16 @@ int snd_hda_gen_build_pcms(struct hda_codec *codec)
 			info->pcm_type = spec->dig_out_type;
 		else
 			info->pcm_type = HDA_PCM_TYPE_SPDIF;
-		if (spec->multiout.dig_out_nid) {
-			p = spec->stream_digital_playback;
-			if (!p)
-				p = &pcm_digital_playback;
-			info->stream[SNDRV_PCM_STREAM_PLAYBACK] = *p;
-			info->stream[SNDRV_PCM_STREAM_PLAYBACK].nid = spec->multiout.dig_out_nid;
-		}
-		if (spec->dig_in_nid) {
-			p = spec->stream_digital_capture;
-			if (!p)
-				p = &pcm_digital_capture;
-			info->stream[SNDRV_PCM_STREAM_CAPTURE] = *p;
-			info->stream[SNDRV_PCM_STREAM_CAPTURE].nid = spec->dig_in_nid;
-		}
+		if (spec->multiout.dig_out_nid)
+			setup_pcm_stream(&info->stream[SNDRV_PCM_STREAM_PLAYBACK],
+					 &pcm_digital_playback,
+					 spec->stream_digital_playback,
+					 spec->multiout.dig_out_nid);
+		if (spec->dig_in_nid)
+			setup_pcm_stream(&info->stream[SNDRV_PCM_STREAM_CAPTURE],
+					 &pcm_digital_capture,
+					 spec->stream_digital_capture,
+					 spec->dig_in_nid);
 	}
 
 	if (spec->no_analog)
@@ -5236,31 +5253,24 @@ int snd_hda_gen_build_pcms(struct hda_codec *codec)
 		if (!info)
 			return -ENOMEM;
 		spec->pcm_rec[2] = info;
-		if (spec->alt_dac_nid) {
-			p = spec->stream_analog_alt_playback;
-			if (!p)
-				p = &pcm_analog_alt_playback;
-			info->stream[SNDRV_PCM_STREAM_PLAYBACK] = *p;
-			info->stream[SNDRV_PCM_STREAM_PLAYBACK].nid =
-				spec->alt_dac_nid;
-		} else {
-			info->stream[SNDRV_PCM_STREAM_PLAYBACK] =
-				pcm_null_stream;
-			info->stream[SNDRV_PCM_STREAM_PLAYBACK].nid = 0;
-		}
+		if (spec->alt_dac_nid)
+			setup_pcm_stream(&info->stream[SNDRV_PCM_STREAM_PLAYBACK],
+					 &pcm_analog_alt_playback,
+					 spec->stream_analog_alt_playback,
+					 spec->alt_dac_nid);
+		else
+			setup_pcm_stream(&info->stream[SNDRV_PCM_STREAM_PLAYBACK],
+					 &pcm_null_stream, NULL, 0);
 		if (have_multi_adcs) {
-			p = spec->stream_analog_alt_capture;
-			if (!p)
-				p = &pcm_analog_alt_capture;
-			info->stream[SNDRV_PCM_STREAM_CAPTURE] = *p;
-			info->stream[SNDRV_PCM_STREAM_CAPTURE].nid =
-				spec->adc_nids[1];
+			setup_pcm_stream(&info->stream[SNDRV_PCM_STREAM_CAPTURE],
+					 &pcm_analog_alt_capture,
+					 spec->stream_analog_alt_capture,
+					 spec->adc_nids[1]);
 			info->stream[SNDRV_PCM_STREAM_CAPTURE].substreams =
 				spec->num_adc_nids - 1;
 		} else {
-			info->stream[SNDRV_PCM_STREAM_CAPTURE] =
-				pcm_null_stream;
-			info->stream[SNDRV_PCM_STREAM_CAPTURE].nid = 0;
+			setup_pcm_stream(&info->stream[SNDRV_PCM_STREAM_CAPTURE],
+					 &pcm_null_stream, NULL, 0);
 		}
 	}
 
diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c
index 2a61bda8115d..124eacf67fc4 100644
--- a/sound/pci/hda/patch_realtek.c
+++ b/sound/pci/hda/patch_realtek.c
@@ -2602,53 +2602,12 @@ static int patch_alc268(struct hda_codec *codec)
  * ALC269
  */
 
-static int playback_pcm_open(struct hda_pcm_stream *hinfo,
-			     struct hda_codec *codec,
-			     struct snd_pcm_substream *substream)
-{
-	struct hda_gen_spec *spec = codec->spec;
-	return snd_hda_multi_out_analog_open(codec, &spec->multiout, substream,
-					     hinfo);
-}
-
-static int playback_pcm_prepare(struct hda_pcm_stream *hinfo,
-				struct hda_codec *codec,
-				unsigned int stream_tag,
-				unsigned int format,
-				struct snd_pcm_substream *substream)
-{
-	struct hda_gen_spec *spec = codec->spec;
-	return snd_hda_multi_out_analog_prepare(codec, &spec->multiout,
-						stream_tag, format, substream);
-}
-
-static int playback_pcm_cleanup(struct hda_pcm_stream *hinfo,
-				struct hda_codec *codec,
-				struct snd_pcm_substream *substream)
-{
-	struct hda_gen_spec *spec = codec->spec;
-	return snd_hda_multi_out_analog_cleanup(codec, &spec->multiout);
-}
-
 static const struct hda_pcm_stream alc269_44k_pcm_analog_playback = {
-	.substreams = 1,
-	.channels_min = 2,
-	.channels_max = 8,
 	.rates = SNDRV_PCM_RATE_44100, /* fixed rate */
-	/* NID is set in alc_build_pcms */
-	.ops = {
-		.open = playback_pcm_open,
-		.prepare = playback_pcm_prepare,
-		.cleanup = playback_pcm_cleanup
-	},
 };
 
 static const struct hda_pcm_stream alc269_44k_pcm_analog_capture = {
-	.substreams = 1,
-	.channels_min = 2,
-	.channels_max = 2,
 	.rates = SNDRV_PCM_RATE_44100, /* fixed rate */
-	/* NID is set in alc_build_pcms */
 };
 
 /* different alc269-variants */
-- 
2.3.3

^ permalink raw reply related	[flat|nested] 21+ messages in thread

* [PATCH 2/4] ALSA: hda - Support advanced power state controls
  2015-03-18  8:50 [PATCH 0/4] More aggressive PM for HD-audio Takashi Iwai
  2015-03-18  8:50 ` [PATCH 1/4] ALSA: hda - Simplify PCM setup overrides Takashi Iwai
@ 2015-03-18  8:50 ` Takashi Iwai
  2015-03-18  8:50 ` [PATCH 3/4] ALSA: hda - Use the new power control for VIA codecs Takashi Iwai
                   ` (3 subsequent siblings)
  5 siblings, 0 replies; 21+ messages in thread
From: Takashi Iwai @ 2015-03-18  8:50 UTC (permalink / raw)
  To: alsa-devel; +Cc: David Henningsson

This patch enables the finer power state control of each widget
depending on the jack plug state and streaming state in addition to
the existing power_down_unused power optimization.  The new feature is
enabled only when codec->power_mgmt flag is set.

Two new flags, pin_enabled and stream_enabled, are introduced in
nid_path struct for marking the two individual power states: the pin
plug/unplug and DAC/ADC stream, respectively.  They can be set
statically in case they are static routes (e.g. some mixer paths),
too.

The power up and down events for each pin are triggered via the
standard hda_jack table.  The call order is hard-coded, relying on the
current implementation of jack event chain (a la FILO/stack order).

One point to be dealt carefully is that DAC/ADC cannot be powered
on/off while streaming.  They are pinned as long as the stream is
running.  For controlling the power of DAC/ADC, a new patch_ops is
added.  The generic parser provides the default callback for that.

As of this patch, only IDT/Sigmatel codec driver enables the flag.
The support on other codecs will follow.

An assumption we made in this code is that the widget state (e.g. amp,
pinctl, connections) remains after the widget power transition (not
about FG power transition).  This is true for IDT codecs, at least.
But if the widget state is lost at widget power transition, we'd need
to implement additional code to sync the cached amp/verbs for the
specific NID.

Signed-off-by: Takashi Iwai <tiwai@suse.de>
---
 sound/pci/hda/hda_codec.c      |   4 +
 sound/pci/hda/hda_codec.h      |   2 +
 sound/pci/hda/hda_generic.c    | 301 ++++++++++++++++++++++++++++++++++-------
 sound/pci/hda/hda_generic.h    |   5 +-
 sound/pci/hda/patch_sigmatel.c |   5 +
 5 files changed, 269 insertions(+), 48 deletions(-)

diff --git a/sound/pci/hda/hda_codec.c b/sound/pci/hda/hda_codec.c
index 3e4fb7a8fdcb..7e38d6f7314b 100644
--- a/sound/pci/hda/hda_codec.c
+++ b/sound/pci/hda/hda_codec.c
@@ -1502,6 +1502,8 @@ void snd_hda_codec_setup_stream(struct hda_codec *codec, hda_nid_t nid,
 	if (!p)
 		return;
 
+	if (codec->patch_ops.stream_pm)
+		codec->patch_ops.stream_pm(codec, nid, true);
 	if (codec->pcm_format_first)
 		update_pcm_format(codec, p, nid, format);
 	update_pcm_stream_id(codec, p, nid, stream_tag, channel_id);
@@ -1570,6 +1572,8 @@ static void really_cleanup_stream(struct hda_codec *codec,
 );
 	memset(q, 0, sizeof(*q));
 	q->nid = nid;
+	if (codec->patch_ops.stream_pm)
+		codec->patch_ops.stream_pm(codec, nid, false);
 }
 
 /* clean up the all conflicting obsolete streams */
diff --git a/sound/pci/hda/hda_codec.h b/sound/pci/hda/hda_codec.h
index 70851e6d5f10..148e84ce61cf 100644
--- a/sound/pci/hda/hda_codec.h
+++ b/sound/pci/hda/hda_codec.h
@@ -200,6 +200,7 @@ struct hda_codec_ops {
 	int (*check_power_status)(struct hda_codec *codec, hda_nid_t nid);
 #endif
 	void (*reboot_notify)(struct hda_codec *codec);
+	void (*stream_pm)(struct hda_codec *codec, hda_nid_t nid, bool on);
 };
 
 /* record for amp information cache */
@@ -370,6 +371,7 @@ struct hda_codec {
 	unsigned int cached_write:1;	/* write only to caches */
 	unsigned int dp_mst:1; /* support DP1.2 Multi-stream transport */
 	unsigned int dump_coef:1; /* dump processing coefs in codec proc file */
+	unsigned int power_mgmt:1; /* advanced PM for each widget */
 #ifdef CONFIG_PM
 	unsigned int d3_stop_clk:1;	/* support D3 operation without BCLK */
 	atomic_t in_pm;		/* suspend/resume being performed */
diff --git a/sound/pci/hda/hda_generic.c b/sound/pci/hda/hda_generic.c
index 27ce54701f0f..8a5055d296f5 100644
--- a/sound/pci/hda/hda_generic.c
+++ b/sound/pci/hda/hda_generic.c
@@ -140,6 +140,9 @@ static void parse_user_hints(struct hda_codec *codec)
 	val = snd_hda_get_bool_hint(codec, "single_adc_amp");
 	if (val >= 0)
 		codec->single_adc_amp = !!val;
+	val = snd_hda_get_bool_hint(codec, "power_mgmt");
+	if (val >= 0)
+		codec->power_mgmt = !!val;
 
 	val = snd_hda_get_bool_hint(codec, "auto_mute");
 	if (val >= 0)
@@ -648,12 +651,21 @@ static bool is_active_nid(struct hda_codec *codec, hda_nid_t nid,
 			  unsigned int dir, unsigned int idx)
 {
 	struct hda_gen_spec *spec = codec->spec;
+	int type = get_wcaps_type(get_wcaps(codec, nid));
 	int i, n;
 
 	for (n = 0; n < spec->paths.used; n++) {
 		struct nid_path *path = snd_array_elem(&spec->paths, n);
 		if (!path->active)
 			continue;
+		if (codec->power_mgmt) {
+			if (!path->stream_enabled)
+				continue;
+			/* ignore unplugged paths except for DAC/ADC */
+			if (!path->pin_enabled &&
+			    type != AC_WID_AUD_OUT && type != AC_WID_AUD_IN)
+				continue;
+		}
 		for (i = 0; i < path->depth; i++) {
 			if (path->path[i] == nid) {
 				if (dir == HDA_OUTPUT || path->idx[i] == idx)
@@ -807,6 +819,42 @@ static void activate_amp_in(struct hda_codec *codec, struct nid_path *path,
 	}
 }
 
+/* sync power of each widget in the the given path */
+static hda_nid_t path_power_update(struct hda_codec *codec,
+				   struct nid_path *path,
+				   bool allow_powerdown)
+{
+	hda_nid_t nid, changed = 0;
+	int i, state;
+
+	for (i = 0; i < path->depth; i++) {
+		nid = path->path[i];
+		if (!allow_powerdown || is_active_nid_for_any(codec, nid))
+			state = AC_PWRST_D0;
+		else
+			state = AC_PWRST_D3;
+		if (!snd_hda_check_power_state(codec, nid, state)) {
+			snd_hda_codec_write(codec, nid, 0,
+					    AC_VERB_SET_POWER_STATE, state);
+			changed = nid;
+			/* here we assume that widget attributes (e.g. amp,
+			 * pinctl connection) don't change with local power
+			 * state change.  If not, need to sync the cache.
+			 */
+		}
+	}
+	return changed;
+}
+
+/* do sync with the last power state change */
+static void sync_power_state_change(struct hda_codec *codec, hda_nid_t nid)
+{
+	if (nid) {
+		msleep(10);
+		snd_hda_codec_read(codec, nid, 0, AC_VERB_GET_POWER_STATE, 0);
+	}
+}
+
 /**
  * snd_hda_activate_path - activate or deactivate the given path
  * @codec: the HDA codec
@@ -825,15 +873,13 @@ void snd_hda_activate_path(struct hda_codec *codec, struct nid_path *path,
 	if (!enable)
 		path->active = false;
 
+	/* make sure the widget is powered up */
+	if (enable && (spec->power_down_unused || codec->power_mgmt))
+		path_power_update(codec, path, codec->power_mgmt);
+
 	for (i = path->depth - 1; i >= 0; i--) {
 		hda_nid_t nid = path->path[i];
-		if (enable && spec->power_down_unused) {
-			/* make sure the widget is powered up */
-			if (!snd_hda_check_power_state(codec, nid, AC_PWRST_D0))
-				snd_hda_codec_write(codec, nid, 0,
-						    AC_VERB_SET_POWER_STATE,
-						    AC_PWRST_D0);
-		}
+
 		if (enable && path->multi[i])
 			snd_hda_codec_update_cache(codec, nid, 0,
 					    AC_VERB_SET_CONNECT_SEL,
@@ -853,28 +899,10 @@ EXPORT_SYMBOL_GPL(snd_hda_activate_path);
 static void path_power_down_sync(struct hda_codec *codec, struct nid_path *path)
 {
 	struct hda_gen_spec *spec = codec->spec;
-	bool changed = false;
-	int i;
 
-	if (!spec->power_down_unused || path->active)
+	if (!(spec->power_down_unused || codec->power_mgmt) || path->active)
 		return;
-
-	for (i = 0; i < path->depth; i++) {
-		hda_nid_t nid = path->path[i];
-		if (!snd_hda_check_power_state(codec, nid, AC_PWRST_D3) &&
-		    !is_active_nid_for_any(codec, nid)) {
-			snd_hda_codec_write(codec, nid, 0,
-					    AC_VERB_SET_POWER_STATE,
-					    AC_PWRST_D3);
-			changed = true;
-		}
-	}
-
-	if (changed) {
-		msleep(10);
-		snd_hda_codec_read(codec, path->path[0], 0,
-				   AC_VERB_GET_POWER_STATE, 0);
-	}
+	sync_power_state_change(codec, path_power_update(codec, path, true));
 }
 
 /* turn on/off EAPD on the given pin */
@@ -1574,6 +1602,7 @@ static int check_aamix_out_path(struct hda_codec *codec, int path_idx)
 		return 0;
 	/* print_nid_path(codec, "output-aamix", path); */
 	path->active = false; /* unused as default */
+	path->pin_enabled = true; /* static route */
 	return snd_hda_get_path_idx(codec, path);
 }
 
@@ -2998,6 +3027,7 @@ static int new_analog_input(struct hda_codec *codec, int input_idx,
 	}
 
 	path->active = true;
+	path->stream_enabled = true; /* no DAC/ADC involved */
 	err = add_loopback_list(spec, mix_nid, idx);
 	if (err < 0)
 		return err;
@@ -3009,6 +3039,8 @@ static int new_analog_input(struct hda_codec *codec, int input_idx,
 		if (path) {
 			print_nid_path(codec, "loopback-merge", path);
 			path->active = true;
+			path->pin_enabled = true; /* static route */
+			path->stream_enabled = true; /* no DAC/ADC involved */
 			spec->loopback_merge_path =
 				snd_hda_get_path_idx(codec, path);
 		}
@@ -3810,6 +3842,7 @@ static void parse_digital(struct hda_codec *codec)
 			continue;
 		print_nid_path(codec, "digout", path);
 		path->active = true;
+		path->pin_enabled = true; /* no jack detection */
 		spec->digout_paths[i] = snd_hda_get_path_idx(codec, path);
 		set_pin_target(codec, pin, PIN_OUT, false);
 		if (!nums) {
@@ -3837,6 +3870,7 @@ static void parse_digital(struct hda_codec *codec)
 			if (path) {
 				print_nid_path(codec, "digin", path);
 				path->active = true;
+				path->pin_enabled = true; /* no jack */
 				spec->dig_in_nid = dig_nid;
 				spec->digin_path = snd_hda_get_path_idx(codec, path);
 				set_pin_target(codec, pin, PIN_IN, false);
@@ -3896,6 +3930,148 @@ static int mux_select(struct hda_codec *codec, unsigned int adc_idx,
 	return 1;
 }
 
+/* power up/down widgets in the all paths that match with the given NID
+ * as terminals (either start- or endpoint)
+ *
+ * returns the last changed NID, or zero if unchanged.
+ */
+static hda_nid_t set_path_power(struct hda_codec *codec, hda_nid_t nid,
+				int pin_state, int stream_state)
+{
+	struct hda_gen_spec *spec = codec->spec;
+	hda_nid_t last, changed = 0;
+	struct nid_path *path;
+	int n;
+
+	for (n = 0; n < spec->paths.used; n++) {
+		path = snd_array_elem(&spec->paths, n);
+		if (path->path[0] == nid ||
+		    path->path[path->depth - 1] == nid) {
+			bool pin_old = path->pin_enabled;
+			bool stream_old = path->stream_enabled;
+
+			if (pin_state >= 0)
+				path->pin_enabled = pin_state;
+			if (stream_state >= 0)
+				path->stream_enabled = stream_state;
+			if (path->pin_enabled != pin_old ||
+			    path->stream_enabled != stream_old) {
+				last = path_power_update(codec, path, true);
+				if (last)
+					changed = last;
+			}
+		}
+	}
+	return changed;
+}
+
+/* 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
+ *
+ * returns the last changed NID, or zero if unchanged.
+ */
+static hda_nid_t set_pin_power_jack(struct hda_codec *codec, hda_nid_t pin,
+				    int power)
+{
+	bool on;
+
+	if (!codec->power_mgmt)
+		return 0;
+
+	on = snd_hda_jack_detect_state(codec, pin) != HDA_JACK_NOT_PRESENT;
+	if (power >= 0 && on != power)
+		return 0;
+	return set_path_power(codec, pin, on, -1);
+}
+
+static void pin_power_callback(struct hda_codec *codec,
+			       struct hda_jack_callback *jack,
+			       bool on)
+{
+	if (jack && jack->tbl->nid)
+		sync_power_state_change(codec,
+					set_pin_power_jack(codec, jack->tbl->nid, on));
+}
+
+/* callback only doing power up -- called at first */
+static void pin_power_up_callback(struct hda_codec *codec,
+				  struct hda_jack_callback *jack)
+{
+	pin_power_callback(codec, jack, true);
+}
+
+/* callback only doing power down -- called at last */
+static void pin_power_down_callback(struct hda_codec *codec,
+				    struct hda_jack_callback *jack)
+{
+	pin_power_callback(codec, jack, false);
+}
+
+/* set up the power up/down callbacks */
+static void add_pin_power_ctls(struct hda_codec *codec, int num_pins,
+			       const hda_nid_t *pins, bool on)
+{
+	int i;
+	hda_jack_callback_fn cb =
+		on ? pin_power_up_callback : pin_power_down_callback;
+
+	for (i = 0; i < num_pins && pins[i]; i++) {
+		if (is_jack_detectable(codec, pins[i]))
+			snd_hda_jack_detect_enable_callback(codec, pins[i], cb);
+		else
+			set_path_power(codec, pins[i], true, -1);
+	}
+}
+
+/* enabled power callback to each available I/O pin with jack detections;
+ * the digital I/O pins are excluded because of the unreliable detectsion
+ */
+static void add_all_pin_power_ctls(struct hda_codec *codec, bool on)
+{
+	struct hda_gen_spec *spec = codec->spec;
+	struct auto_pin_cfg *cfg = &spec->autocfg;
+	int i;
+
+	if (!codec->power_mgmt)
+		return;
+	add_pin_power_ctls(codec, cfg->line_outs, cfg->line_out_pins, on);
+	if (cfg->line_out_type != AUTO_PIN_HP_OUT)
+		add_pin_power_ctls(codec, cfg->hp_outs, cfg->hp_pins, on);
+	if (cfg->line_out_type != AUTO_PIN_SPEAKER_OUT)
+		add_pin_power_ctls(codec, cfg->speaker_outs, cfg->speaker_pins, on);
+	for (i = 0; i < cfg->num_inputs; i++)
+		add_pin_power_ctls(codec, 1, &cfg->inputs[i].pin, on);
+}
+
+/* sync path power up/down with the jack states of given pins */
+static void sync_pin_power_ctls(struct hda_codec *codec, int num_pins,
+				const hda_nid_t *pins)
+{
+	int i;
+
+	for (i = 0; i < num_pins && pins[i]; i++)
+		if (is_jack_detectable(codec, pins[i]))
+			set_pin_power_jack(codec, pins[i], -1);
+}
+
+/* sync path power up/down with pins; called at init and resume */
+static void sync_all_pin_power_ctls(struct hda_codec *codec)
+{
+	struct hda_gen_spec *spec = codec->spec;
+	struct auto_pin_cfg *cfg = &spec->autocfg;
+	int i;
+
+	if (!codec->power_mgmt)
+		return;
+	sync_pin_power_ctls(codec, cfg->line_outs, cfg->line_out_pins);
+	if (cfg->line_out_type != AUTO_PIN_HP_OUT)
+		sync_pin_power_ctls(codec, cfg->hp_outs, cfg->hp_pins);
+	if (cfg->line_out_type != AUTO_PIN_SPEAKER_OUT)
+		sync_pin_power_ctls(codec, cfg->speaker_outs, cfg->speaker_pins);
+	for (i = 0; i < cfg->num_inputs; i++)
+		sync_pin_power_ctls(codec, 1, &cfg->inputs[i].pin);
+}
 
 /*
  * Jack detections for HP auto-mute and mic-switch
@@ -3933,6 +4109,10 @@ static void do_automute(struct hda_codec *codec, int num_pins, hda_nid_t *pins,
 		if (!nid)
 			break;
 
+		oldval = snd_hda_codec_get_pin_target(codec, nid);
+		if (oldval & PIN_IN)
+			continue; /* no mute for inputs */
+
 		if (spec->auto_mute_via_amp) {
 			struct nid_path *path;
 			hda_nid_t mute_nid;
@@ -3947,29 +4127,33 @@ static void do_automute(struct hda_codec *codec, int num_pins, hda_nid_t *pins,
 				spec->mute_bits |= (1ULL << mute_nid);
 			else
 				spec->mute_bits &= ~(1ULL << mute_nid);
-			set_pin_eapd(codec, nid, !mute);
 			continue;
+		} else {
+			/* don't reset VREF value in case it's controlling
+			 * the amp (see alc861_fixup_asus_amp_vref_0f())
+			 */
+			if (spec->keep_vref_in_automute)
+				val = oldval & ~PIN_HP;
+			else
+				val = 0;
+			if (!mute)
+				val |= oldval;
+			/* here we call update_pin_ctl() so that the pinctl is
+			 * changed without changing the pinctl target value;
+			 * the original target value will be still referred at
+			 * the init / resume again
+			 */
+			update_pin_ctl(codec, nid, val);
 		}
 
-		oldval = snd_hda_codec_get_pin_target(codec, nid);
-		if (oldval & PIN_IN)
-			continue; /* no mute for inputs */
-		/* don't reset VREF value in case it's controlling
-		 * the amp (see alc861_fixup_asus_amp_vref_0f())
-		 */
-		if (spec->keep_vref_in_automute)
-			val = oldval & ~PIN_HP;
-		else
-			val = 0;
-		if (!mute)
-			val |= oldval;
-		/* here we call update_pin_ctl() so that the pinctl is changed
-		 * without changing the pinctl target value;
-		 * the original target value will be still referred at the
-		 * init / resume again
-		 */
-		update_pin_ctl(codec, nid, val);
 		set_pin_eapd(codec, nid, !mute);
+		if (codec->power_mgmt) {
+			bool on = !mute;
+			if (on)
+				on = snd_hda_jack_detect_state(codec, nid)
+					!= HDA_JACK_NOT_PRESENT;
+			set_path_power(codec, nid, on, -1);
+		}
 	}
 }
 
@@ -4466,6 +4650,21 @@ static void mute_all_mixer_nid(struct hda_codec *codec, hda_nid_t mix)
 }
 
 /**
+ * snd_hda_gen_stream_pm - Stream power management callback
+ * @codec: the HDA codec
+ * @nid: audio widget
+ * @on: power on/off flag
+ *
+ * Set this in patch_ops.stream_pm.  Only valid with power_mgmt flag.
+ */
+void snd_hda_gen_stream_pm(struct hda_codec *codec, hda_nid_t nid, bool on)
+{
+	if (codec->power_mgmt)
+		set_path_power(codec, nid, -1, on);
+}
+EXPORT_SYMBOL_GPL(snd_hda_gen_stream_pm);
+
+/**
  * snd_hda_gen_parse_auto_config - Parse the given BIOS configuration and
  * set up the hda_gen_spec
  * @codec: the HDA codec
@@ -4549,6 +4748,9 @@ int snd_hda_gen_parse_auto_config(struct hda_codec *codec,
 	if (err < 0)
 		return err;
 
+	/* add power-down pin callbacks at first */
+	add_all_pin_power_ctls(codec, false);
+
 	spec->const_channel_count = spec->ext_channel_count;
 	/* check the multiple speaker and headphone pins */
 	if (cfg->line_out_type != AUTO_PIN_SPEAKER_OUT)
@@ -4618,6 +4820,9 @@ int snd_hda_gen_parse_auto_config(struct hda_codec *codec,
 		}
 	}
 
+	/* add power-up pin callbacks at last */
+	add_all_pin_power_ctls(codec, true);
+
 	/* mute all aamix input initially */
 	if (spec->mixer_nid)
 		mute_all_mixer_nid(codec, spec->mixer_nid);
@@ -4625,7 +4830,7 @@ int snd_hda_gen_parse_auto_config(struct hda_codec *codec,
  dig_only:
 	parse_digital(codec);
 
-	if (spec->power_down_unused)
+	if (spec->power_down_unused || codec->power_mgmt)
 		codec->power_filter = snd_hda_gen_path_power_filter;
 
 	if (!spec->no_analog && spec->beep_nid) {
@@ -5478,6 +5683,8 @@ int snd_hda_gen_init(struct hda_codec *codec)
 
 	clear_unsol_on_unused_pins(codec);
 
+	sync_all_pin_power_ctls(codec);
+
 	/* call init functions of standard auto-mute helpers */
 	update_automute_all(codec);
 
diff --git a/sound/pci/hda/hda_generic.h b/sound/pci/hda/hda_generic.h
index b211f889b335..54659b51fe16 100644
--- a/sound/pci/hda/hda_generic.h
+++ b/sound/pci/hda/hda_generic.h
@@ -46,7 +46,9 @@ struct nid_path {
 	unsigned char idx[MAX_NID_PATH_DEPTH];
 	unsigned char multi[MAX_NID_PATH_DEPTH];
 	unsigned int ctls[NID_PATH_NUM_CTLS]; /* NID_PATH_XXX_CTL */
-	bool active;
+	bool active:1;		/* activated by driver */
+	bool pin_enabled:1;	/* pins are enabled */
+	bool stream_enabled:1;	/* stream is active */
 };
 
 /* mic/line-in auto switching entry */
@@ -340,5 +342,6 @@ int snd_hda_gen_check_power_status(struct hda_codec *codec, hda_nid_t nid);
 unsigned int snd_hda_gen_path_power_filter(struct hda_codec *codec,
 					   hda_nid_t nid,
 					   unsigned int power_state);
+void snd_hda_gen_stream_pm(struct hda_codec *codec, hda_nid_t nid, bool on);
 
 #endif /* __SOUND_HDA_GENERIC_H */
diff --git a/sound/pci/hda/patch_sigmatel.c b/sound/pci/hda/patch_sigmatel.c
index 2956a6ba6bf0..86b944a6b0ed 100644
--- a/sound/pci/hda/patch_sigmatel.c
+++ b/sound/pci/hda/patch_sigmatel.c
@@ -4394,6 +4394,7 @@ static const struct hda_codec_ops stac_patch_ops = {
 #ifdef CONFIG_PM
 	.suspend = stac_suspend,
 #endif
+	.stream_pm = snd_hda_gen_stream_pm,
 	.reboot_notify = stac_shutup,
 };
 
@@ -4487,6 +4488,7 @@ static int patch_stac92hd73xx(struct hda_codec *codec)
 		return err;
 
 	spec = codec->spec;
+	codec->power_mgmt = 1;
 	spec->linear_tone_beep = 0;
 	spec->gen.mixer_nid = 0x1d;
 	spec->have_spdif_mux = 1;
@@ -4592,6 +4594,7 @@ static int patch_stac92hd83xxx(struct hda_codec *codec)
 	codec->epss = 0; /* longer delay needed for D3 */
 
 	spec = codec->spec;
+	codec->power_mgmt = 1;
 	spec->linear_tone_beep = 0;
 	spec->gen.own_eapd_ctl = 1;
 	spec->gen.power_down_unused = 1;
@@ -4641,6 +4644,7 @@ static int patch_stac92hd95(struct hda_codec *codec)
 	codec->epss = 0; /* longer delay needed for D3 */
 
 	spec = codec->spec;
+	codec->power_mgmt = 1;
 	spec->linear_tone_beep = 0;
 	spec->gen.own_eapd_ctl = 1;
 	spec->gen.power_down_unused = 1;
@@ -4682,6 +4686,7 @@ static int patch_stac92hd71bxx(struct hda_codec *codec)
 		return err;
 
 	spec = codec->spec;
+	codec->power_mgmt = 1;
 	spec->linear_tone_beep = 0;
 	spec->gen.own_eapd_ctl = 1;
 	spec->gen.power_down_unused = 1;
-- 
2.3.3

^ permalink raw reply related	[flat|nested] 21+ messages in thread

* [PATCH 3/4] ALSA: hda - Use the new power control for VIA codecs
  2015-03-18  8:50 [PATCH 0/4] More aggressive PM for HD-audio Takashi Iwai
  2015-03-18  8:50 ` [PATCH 1/4] ALSA: hda - Simplify PCM setup overrides Takashi Iwai
  2015-03-18  8:50 ` [PATCH 2/4] ALSA: hda - Support advanced power state controls Takashi Iwai
@ 2015-03-18  8:50 ` Takashi Iwai
  2015-03-18  8:50 ` [PATCH 4/4] ALSA: hda - Adjust power of beep widget and outputs Takashi Iwai
                   ` (2 subsequent siblings)
  5 siblings, 0 replies; 21+ messages in thread
From: Takashi Iwai @ 2015-03-18  8:50 UTC (permalink / raw)
  To: alsa-devel; +Cc: David Henningsson

VIA codecs used to have the own power controls but they were disabled
at transition to the generic parser due to the coding assuming the
fixed routes.  Now we get the proper support of equivalently fine
power management in the generic parser, and the old kludges can be
replaced with it.  This results in the reduction of lots of dead
codes.

The advanced PM feature is disabled as default like before for keeping
the compatible behavior.  It's enabled via "Dynamic Power-Control"
mixer element.

Signed-off-by: Takashi Iwai <tiwai@suse.de>
---
 sound/pci/hda/patch_via.c | 662 +---------------------------------------------
 1 file changed, 12 insertions(+), 650 deletions(-)

diff --git a/sound/pci/hda/patch_via.c b/sound/pci/hda/patch_via.c
index 2112fbe9e577..d5d1dca4f11b 100644
--- a/sound/pci/hda/patch_via.c
+++ b/sound/pci/hda/patch_via.c
@@ -99,7 +99,6 @@ struct via_spec {
 
 	/* HP mode source */
 	unsigned int dmic_enabled;
-	unsigned int no_pin_power_ctl;
 	enum VIA_HDA_CODEC codec_type;
 
 	/* analog low-power control */
@@ -108,9 +107,6 @@ struct via_spec {
 	/* work to check hp jack state */
 	int hp_work_active;
 	int vt1708_jack_detect;
-
-	void (*set_widgets_power_state)(struct hda_codec *codec);
-	unsigned int dac_stream_tag[4];
 };
 
 static enum VIA_HDA_CODEC get_codec_type(struct hda_codec *codec);
@@ -133,11 +129,12 @@ static struct via_spec *via_new_spec(struct hda_codec *codec)
 	/* VT1708BCE & VT1708S are almost same */
 	if (spec->codec_type == VT1708BCE)
 		spec->codec_type = VT1708S;
-	spec->no_pin_power_ctl = 1;
 	spec->gen.indep_hp = 1;
 	spec->gen.keep_eapd_on = 1;
 	spec->gen.pcm_playback_hook = via_playback_pcm_hook;
 	spec->gen.add_stereo_mix_input = HDA_HINT_STEREO_MIX_AUTO;
+	codec->power_mgmt = 1;
+	spec->gen.power_down_unused = 1;
 	return spec;
 }
 
@@ -229,90 +226,6 @@ static void vt1708_update_hp_work(struct hda_codec *codec)
 		vt1708_stop_hp_work(codec);
 }
 
-static void set_widgets_power_state(struct hda_codec *codec)
-{
-#if 0 /* FIXME: the assumed connections don't match always with the
-       * actual routes by the generic parser, so better to disable
-       * the control for safety.
-       */
-	struct via_spec *spec = codec->spec;
-	if (spec->set_widgets_power_state)
-		spec->set_widgets_power_state(codec);
-#endif
-}
-
-static void update_power_state(struct hda_codec *codec, hda_nid_t nid,
-			       unsigned int parm)
-{
-	if (snd_hda_check_power_state(codec, nid, parm))
-		return;
-	snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_POWER_STATE, parm);
-}
-
-static void update_conv_power_state(struct hda_codec *codec, hda_nid_t nid,
-			       unsigned int parm, unsigned int index)
-{
-	struct via_spec *spec = codec->spec;
-	unsigned int format;
-
-	if (snd_hda_check_power_state(codec, nid, parm))
-		return;
-	format = snd_hda_codec_read(codec, nid, 0, AC_VERB_GET_CONV, 0);
-	if (format && (spec->dac_stream_tag[index] != format))
-		spec->dac_stream_tag[index] = format;
-
-	snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_POWER_STATE, parm);
-	if (parm == AC_PWRST_D0) {
-		format = snd_hda_codec_read(codec, nid, 0, AC_VERB_GET_CONV, 0);
-		if (!format && (spec->dac_stream_tag[index] != format))
-			snd_hda_codec_write(codec, nid, 0,
-						  AC_VERB_SET_CHANNEL_STREAMID,
-						  spec->dac_stream_tag[index]);
-	}
-}
-
-static bool smart51_enabled(struct hda_codec *codec)
-{
-	struct via_spec *spec = codec->spec;
-	return spec->gen.ext_channel_count > 2;
-}
-
-static bool is_smart51_pins(struct hda_codec *codec, hda_nid_t pin)
-{
-	struct via_spec *spec = codec->spec;
-	int i;
-
-	for (i = 0; i < spec->gen.multi_ios; i++)
-		if (spec->gen.multi_io[i].pin == pin)
-			return true;
-	return false;
-}
-
-static void set_pin_power_state(struct hda_codec *codec, hda_nid_t nid,
-				unsigned int *affected_parm)
-{
-	unsigned parm;
-	unsigned def_conf = snd_hda_codec_get_pincfg(codec, nid);
-	unsigned no_presence = (def_conf & AC_DEFCFG_MISC)
-		>> AC_DEFCFG_MISC_SHIFT
-		& AC_DEFCFG_MISC_NO_PRESENCE; /* do not support pin sense */
-	struct via_spec *spec = codec->spec;
-	unsigned present = 0;
-
-	no_presence |= spec->no_pin_power_ctl;
-	if (!no_presence)
-		present = snd_hda_jack_detect(codec, nid);
-	if ((smart51_enabled(codec) && is_smart51_pins(codec, nid))
-	    || ((no_presence || present)
-		&& get_defcfg_connect(def_conf) != AC_JACK_PORT_NONE)) {
-		*affected_parm = AC_PWRST_D0; /* if it's connected */
-		parm = AC_PWRST_D0;
-	} else
-		parm = AC_PWRST_D3;
-
-	update_power_state(codec, nid, parm);
-}
-
 static int via_pin_power_ctl_info(struct snd_kcontrol *kcontrol,
 				  struct snd_ctl_elem_info *uinfo)
 {
@@ -323,8 +236,7 @@ static int via_pin_power_ctl_get(struct snd_kcontrol *kcontrol,
 				 struct snd_ctl_elem_value *ucontrol)
 {
 	struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
-	struct via_spec *spec = codec->spec;
-	ucontrol->value.enumerated.item[0] = !spec->no_pin_power_ctl;
+	ucontrol->value.enumerated.item[0] = codec->power_mgmt;
 	return 0;
 }
 
@@ -333,12 +245,12 @@ static int via_pin_power_ctl_put(struct snd_kcontrol *kcontrol,
 {
 	struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
 	struct via_spec *spec = codec->spec;
-	unsigned int val = !ucontrol->value.enumerated.item[0];
+	bool val = !!ucontrol->value.enumerated.item[0];
 
-	if (val == spec->no_pin_power_ctl)
+	if (val == codec->power_mgmt)
 		return 0;
-	spec->no_pin_power_ctl = val;
-	set_widgets_power_state(codec);
+	codec->power_mgmt = val;
+	spec->gen.power_down_unused = val;
 	analog_low_current_mode(codec);
 	return 1;
 }
@@ -383,7 +295,7 @@ static void __analog_low_current_mode(struct hda_codec *codec, bool force)
 	bool enable;
 	unsigned int verb, parm;
 
-	if (spec->no_pin_power_ctl)
+	if (!codec->power_mgmt)
 		enable = false;
 	else
 		enable = is_aa_path_mute(codec) && !spec->gen.active_streams;
@@ -440,8 +352,7 @@ static int via_build_controls(struct hda_codec *codec)
 	if (err < 0)
 		return err;
 
-	if (spec->set_widgets_power_state)
-		spec->mixers[spec->num_mixers++] = via_pin_power_ctl_enum;
+	spec->mixers[spec->num_mixers++] = via_pin_power_ctl_enum;
 
 	for (i = 0; i < spec->num_mixers; i++) {
 		err = snd_hda_add_new_ctls(codec, spec->mixers[i]);
@@ -485,7 +396,6 @@ static int via_suspend(struct hda_codec *codec)
 static int via_check_power_status(struct hda_codec *codec, hda_nid_t nid)
 {
 	struct via_spec *spec = codec->spec;
-	set_widgets_power_state(codec);
 	analog_low_current_mode(codec);
 	vt1708_update_hp_work(codec);
 	return snd_hda_check_amp_list_power(codec, &spec->gen.loopback, nid);
@@ -573,34 +483,6 @@ static const struct snd_kcontrol_new vt1708_jack_detect_ctl[] = {
 	{} /* terminator */
 };
 
-static void via_jack_powerstate_event(struct hda_codec *codec,
-				      struct hda_jack_callback *tbl)
-{
-	set_widgets_power_state(codec);
-}
-
-static void via_set_jack_unsol_events(struct hda_codec *codec)
-{
-	struct via_spec *spec = codec->spec;
-	struct auto_pin_cfg *cfg = &spec->gen.autocfg;
-	hda_nid_t pin;
-	int i;
-
-	for (i = 0; i < cfg->line_outs; i++) {
-		pin = cfg->line_out_pins[i];
-		if (pin && is_jack_detectable(codec, pin))
-			snd_hda_jack_detect_enable_callback(codec, pin,
-							    via_jack_powerstate_event);
-	}
-
-	for (i = 0; i < cfg->num_inputs; i++) {
-		pin = cfg->line_out_pins[i];
-		if (pin && is_jack_detectable(codec, pin))
-			snd_hda_jack_detect_enable_callback(codec, pin,
-							    via_jack_powerstate_event);
-	}
-}
-
 static const struct badness_table via_main_out_badness = {
 	.no_primary_dac = 0x10000,
 	.no_dac = 0x4000,
@@ -634,7 +516,9 @@ static int via_parse_auto_config(struct hda_codec *codec)
 	if (err < 0)
 		return err;
 
-	via_set_jack_unsol_events(codec);
+	/* disable widget PM at start for compatibility */
+	codec->power_mgmt = 0;
+	spec->gen.power_down_unused = 0;
 	return 0;
 }
 
@@ -647,7 +531,6 @@ static int via_init(struct hda_codec *codec)
 		snd_hda_sequence_write(codec, spec->init_verbs[i]);
 
 	/* init power states */
-	set_widgets_power_state(codec);
 	__analog_low_current_mode(codec, true);
 
 	snd_hda_gen_init(codec);
@@ -767,78 +650,6 @@ static int patch_vt1709(struct hda_codec *codec)
 	return 0;
 }
 
-static void set_widgets_power_state_vt1708B(struct hda_codec *codec)
-{
-	struct via_spec *spec = codec->spec;
-	int imux_is_smixer;
-	unsigned int parm;
-	int is_8ch = 0;
-	if ((spec->codec_type != VT1708B_4CH) &&
-	    (codec->vendor_id != 0x11064397))
-		is_8ch = 1;
-
-	/* SW0 (17h) = stereo mixer */
-	imux_is_smixer =
-	(snd_hda_codec_read(codec, 0x17, 0, AC_VERB_GET_CONNECT_SEL, 0x00)
-	 == ((spec->codec_type == VT1708S) ? 5 : 0));
-	/* inputs */
-	/* PW 1/2/5 (1ah/1bh/1eh) */
-	parm = AC_PWRST_D3;
-	set_pin_power_state(codec, 0x1a, &parm);
-	set_pin_power_state(codec, 0x1b, &parm);
-	set_pin_power_state(codec, 0x1e, &parm);
-	if (imux_is_smixer)
-		parm = AC_PWRST_D0;
-	/* SW0 (17h), AIW 0/1 (13h/14h) */
-	update_power_state(codec, 0x17, parm);
-	update_power_state(codec, 0x13, parm);
-	update_power_state(codec, 0x14, parm);
-
-	/* outputs */
-	/* PW0 (19h), SW1 (18h), AOW1 (11h) */
-	parm = AC_PWRST_D3;
-	set_pin_power_state(codec, 0x19, &parm);
-	if (smart51_enabled(codec))
-		set_pin_power_state(codec, 0x1b, &parm);
-	update_power_state(codec, 0x18, parm);
-	update_power_state(codec, 0x11, parm);
-
-	/* PW6 (22h), SW2 (26h), AOW2 (24h) */
-	if (is_8ch) {
-		parm = AC_PWRST_D3;
-		set_pin_power_state(codec, 0x22, &parm);
-		if (smart51_enabled(codec))
-			set_pin_power_state(codec, 0x1a, &parm);
-		update_power_state(codec, 0x26, parm);
-		update_power_state(codec, 0x24, parm);
-	} else if (codec->vendor_id == 0x11064397) {
-		/* PW7(23h), SW2(27h), AOW2(25h) */
-		parm = AC_PWRST_D3;
-		set_pin_power_state(codec, 0x23, &parm);
-		if (smart51_enabled(codec))
-			set_pin_power_state(codec, 0x1a, &parm);
-		update_power_state(codec, 0x27, parm);
-		update_power_state(codec, 0x25, parm);
-	}
-
-	/* PW 3/4/7 (1ch/1dh/23h) */
-	parm = AC_PWRST_D3;
-	/* force to D0 for internal Speaker */
-	set_pin_power_state(codec, 0x1c, &parm);
-	set_pin_power_state(codec, 0x1d, &parm);
-	if (is_8ch)
-		set_pin_power_state(codec, 0x23, &parm);
-
-	/* MW0 (16h), Sw3 (27h), AOW 0/3 (10h/25h) */
-	update_power_state(codec, 0x16, imux_is_smixer ? AC_PWRST_D0 : parm);
-	update_power_state(codec, 0x10, parm);
-	if (is_8ch) {
-		update_power_state(codec, 0x25, parm);
-		update_power_state(codec, 0x27, parm);
-	} else if (codec->vendor_id == 0x11064397 && spec->gen.indep_hp_enabled)
-		update_power_state(codec, 0x25, parm);
-}
-
 static int patch_vt1708S(struct hda_codec *codec);
 static int patch_vt1708B(struct hda_codec *codec)
 {
@@ -863,9 +674,6 @@ static int patch_vt1708B(struct hda_codec *codec)
 	}
 
 	codec->patch_ops = via_patch_ops;
-
-	spec->set_widgets_power_state =  set_widgets_power_state_vt1708B;
-
 	return 0;
 }
 
@@ -931,8 +739,6 @@ static int patch_vt1708S(struct hda_codec *codec)
 	spec->init_verbs[spec->num_iverbs++] = vt1708S_init_verbs;
 
 	codec->patch_ops = via_patch_ops;
-
-	spec->set_widgets_power_state =  set_widgets_power_state_vt1708B;
 	return 0;
 }
 
@@ -946,36 +752,6 @@ static const struct hda_verb vt1702_init_verbs[] = {
 	{ }
 };
 
-static void set_widgets_power_state_vt1702(struct hda_codec *codec)
-{
-	int imux_is_smixer =
-	snd_hda_codec_read(codec, 0x13, 0, AC_VERB_GET_CONNECT_SEL, 0x00) == 3;
-	unsigned int parm;
-	/* inputs */
-	/* PW 1/2/5 (14h/15h/18h) */
-	parm = AC_PWRST_D3;
-	set_pin_power_state(codec, 0x14, &parm);
-	set_pin_power_state(codec, 0x15, &parm);
-	set_pin_power_state(codec, 0x18, &parm);
-	if (imux_is_smixer)
-		parm = AC_PWRST_D0; /* SW0 (13h) = stereo mixer (idx 3) */
-	/* SW0 (13h), AIW 0/1/2 (12h/1fh/20h) */
-	update_power_state(codec, 0x13, parm);
-	update_power_state(codec, 0x12, parm);
-	update_power_state(codec, 0x1f, parm);
-	update_power_state(codec, 0x20, parm);
-
-	/* outputs */
-	/* PW 3/4 (16h/17h) */
-	parm = AC_PWRST_D3;
-	set_pin_power_state(codec, 0x17, &parm);
-	set_pin_power_state(codec, 0x16, &parm);
-	/* MW0 (1ah), AOW 0/1 (10h/1dh) */
-	update_power_state(codec, 0x1a, imux_is_smixer ? AC_PWRST_D0 : parm);
-	update_power_state(codec, 0x10, parm);
-	update_power_state(codec, 0x1d, parm);
-}
-
 static int patch_vt1702(struct hda_codec *codec)
 {
 	struct via_spec *spec;
@@ -1005,8 +781,6 @@ static int patch_vt1702(struct hda_codec *codec)
 	spec->init_verbs[spec->num_iverbs++] = vt1702_init_verbs;
 
 	codec->patch_ops = via_patch_ops;
-
-	spec->set_widgets_power_state =  set_widgets_power_state_vt1702;
 	return 0;
 }
 
@@ -1021,71 +795,6 @@ static const struct hda_verb vt1718S_init_verbs[] = {
 	{ }
 };
 
-static void set_widgets_power_state_vt1718S(struct hda_codec *codec)
-{
-	struct via_spec *spec = codec->spec;
-	int imux_is_smixer;
-	unsigned int parm, parm2;
-	/* MUX6 (1eh) = stereo mixer */
-	imux_is_smixer =
-	snd_hda_codec_read(codec, 0x1e, 0, AC_VERB_GET_CONNECT_SEL, 0x00) == 5;
-	/* inputs */
-	/* PW 5/6/7 (29h/2ah/2bh) */
-	parm = AC_PWRST_D3;
-	set_pin_power_state(codec, 0x29, &parm);
-	set_pin_power_state(codec, 0x2a, &parm);
-	set_pin_power_state(codec, 0x2b, &parm);
-	if (imux_is_smixer)
-		parm = AC_PWRST_D0;
-	/* MUX6/7 (1eh/1fh), AIW 0/1 (10h/11h) */
-	update_power_state(codec, 0x1e, parm);
-	update_power_state(codec, 0x1f, parm);
-	update_power_state(codec, 0x10, parm);
-	update_power_state(codec, 0x11, parm);
-
-	/* outputs */
-	/* PW3 (27h), MW2 (1ah), AOW3 (bh) */
-	parm = AC_PWRST_D3;
-	set_pin_power_state(codec, 0x27, &parm);
-	update_power_state(codec, 0x1a, parm);
-	parm2 = parm; /* for pin 0x0b */
-
-	/* PW2 (26h), AOW2 (ah) */
-	parm = AC_PWRST_D3;
-	set_pin_power_state(codec, 0x26, &parm);
-	if (smart51_enabled(codec))
-		set_pin_power_state(codec, 0x2b, &parm);
-	update_power_state(codec, 0xa, parm);
-
-	/* PW0 (24h), AOW0 (8h) */
-	parm = AC_PWRST_D3;
-	set_pin_power_state(codec, 0x24, &parm);
-	if (!spec->gen.indep_hp_enabled) /* check for redirected HP */
-		set_pin_power_state(codec, 0x28, &parm);
-	update_power_state(codec, 0x8, parm);
-	if (!spec->gen.indep_hp_enabled && parm2 != AC_PWRST_D3)
-		parm = parm2;
-	update_power_state(codec, 0xb, parm);
-	/* MW9 (21h), Mw2 (1ah), AOW0 (8h) */
-	update_power_state(codec, 0x21, imux_is_smixer ? AC_PWRST_D0 : parm);
-
-	/* PW1 (25h), AOW1 (9h) */
-	parm = AC_PWRST_D3;
-	set_pin_power_state(codec, 0x25, &parm);
-	if (smart51_enabled(codec))
-		set_pin_power_state(codec, 0x2a, &parm);
-	update_power_state(codec, 0x9, parm);
-
-	if (spec->gen.indep_hp_enabled) {
-		/* PW4 (28h), MW3 (1bh), MUX1(34h), AOW4 (ch) */
-		parm = AC_PWRST_D3;
-		set_pin_power_state(codec, 0x28, &parm);
-		update_power_state(codec, 0x1b, parm);
-		update_power_state(codec, 0x34, parm);
-		update_power_state(codec, 0xc, parm);
-	}
-}
-
 /* Add a connection to the primary DAC from AA-mixer for some codecs
  * This isn't listed from the raw info, but the chip has a secret connection.
  */
@@ -1146,9 +855,6 @@ static int patch_vt1718S(struct hda_codec *codec)
 	spec->init_verbs[spec->num_iverbs++] = vt1718S_init_verbs;
 
 	codec->patch_ops = via_patch_ops;
-
-	spec->set_widgets_power_state =  set_widgets_power_state_vt1718S;
-
 	return 0;
 }
 
@@ -1188,7 +894,6 @@ static int vt1716s_dmic_put(struct snd_kcontrol *kcontrol,
 	snd_hda_codec_write(codec, 0x26, 0,
 					       AC_VERB_SET_CONNECT_SEL, index);
 	spec->dmic_enabled = index;
-	set_widgets_power_state(codec);
 	return 1;
 }
 
@@ -1223,95 +928,6 @@ static const struct hda_verb vt1716S_init_verbs[] = {
 	{ }
 };
 
-static void set_widgets_power_state_vt1716S(struct hda_codec *codec)
-{
-	struct via_spec *spec = codec->spec;
-	int imux_is_smixer;
-	unsigned int parm;
-	unsigned int mono_out, present;
-	/* SW0 (17h) = stereo mixer */
-	imux_is_smixer =
-	(snd_hda_codec_read(codec, 0x17, 0,
-			    AC_VERB_GET_CONNECT_SEL, 0x00) ==  5);
-	/* inputs */
-	/* PW 1/2/5 (1ah/1bh/1eh) */
-	parm = AC_PWRST_D3;
-	set_pin_power_state(codec, 0x1a, &parm);
-	set_pin_power_state(codec, 0x1b, &parm);
-	set_pin_power_state(codec, 0x1e, &parm);
-	if (imux_is_smixer)
-		parm = AC_PWRST_D0;
-	/* SW0 (17h), AIW0(13h) */
-	update_power_state(codec, 0x17, parm);
-	update_power_state(codec, 0x13, parm);
-
-	parm = AC_PWRST_D3;
-	set_pin_power_state(codec, 0x1e, &parm);
-	/* PW11 (22h) */
-	if (spec->dmic_enabled)
-		set_pin_power_state(codec, 0x22, &parm);
-	else
-		update_power_state(codec, 0x22, AC_PWRST_D3);
-
-	/* SW2(26h), AIW1(14h) */
-	update_power_state(codec, 0x26, parm);
-	update_power_state(codec, 0x14, parm);
-
-	/* outputs */
-	/* PW0 (19h), SW1 (18h), AOW1 (11h) */
-	parm = AC_PWRST_D3;
-	set_pin_power_state(codec, 0x19, &parm);
-	/* Smart 5.1 PW2(1bh) */
-	if (smart51_enabled(codec))
-		set_pin_power_state(codec, 0x1b, &parm);
-	update_power_state(codec, 0x18, parm);
-	update_power_state(codec, 0x11, parm);
-
-	/* PW7 (23h), SW3 (27h), AOW3 (25h) */
-	parm = AC_PWRST_D3;
-	set_pin_power_state(codec, 0x23, &parm);
-	/* Smart 5.1 PW1(1ah) */
-	if (smart51_enabled(codec))
-		set_pin_power_state(codec, 0x1a, &parm);
-	update_power_state(codec, 0x27, parm);
-
-	/* Smart 5.1 PW5(1eh) */
-	if (smart51_enabled(codec))
-		set_pin_power_state(codec, 0x1e, &parm);
-	update_power_state(codec, 0x25, parm);
-
-	/* Mono out */
-	/* SW4(28h)->MW1(29h)-> PW12 (2ah)*/
-	present = snd_hda_jack_detect(codec, 0x1c);
-
-	if (present)
-		mono_out = 0;
-	else {
-		present = snd_hda_jack_detect(codec, 0x1d);
-		if (!spec->gen.indep_hp_enabled && present)
-			mono_out = 0;
-		else
-			mono_out = 1;
-	}
-	parm = mono_out ? AC_PWRST_D0 : AC_PWRST_D3;
-	update_power_state(codec, 0x28, parm);
-	update_power_state(codec, 0x29, parm);
-	update_power_state(codec, 0x2a, parm);
-
-	/* PW 3/4 (1ch/1dh) */
-	parm = AC_PWRST_D3;
-	set_pin_power_state(codec, 0x1c, &parm);
-	set_pin_power_state(codec, 0x1d, &parm);
-	/* HP Independent Mode, power on AOW3 */
-	if (spec->gen.indep_hp_enabled)
-		update_power_state(codec, 0x25, parm);
-
-	/* force to D0 for internal Speaker */
-	/* MW0 (16h), AOW0 (10h) */
-	update_power_state(codec, 0x16, imux_is_smixer ? AC_PWRST_D0 : parm);
-	update_power_state(codec, 0x10, mono_out ? AC_PWRST_D0 : parm);
-}
-
 static int patch_vt1716S(struct hda_codec *codec)
 {
 	struct via_spec *spec;
@@ -1339,8 +955,6 @@ static int patch_vt1716S(struct hda_codec *codec)
 	spec->mixers[spec->num_mixers++] = vt1716S_mono_out_mixer;
 
 	codec->patch_ops = via_patch_ops;
-
-	spec->set_widgets_power_state = set_widgets_power_state_vt1716S;
 	return 0;
 }
 
@@ -1366,98 +980,6 @@ static const struct hda_verb vt1802_init_verbs[] = {
 	{ }
 };
 
-static void set_widgets_power_state_vt2002P(struct hda_codec *codec)
-{
-	struct via_spec *spec = codec->spec;
-	int imux_is_smixer;
-	unsigned int parm;
-	unsigned int present;
-	/* MUX9 (1eh) = stereo mixer */
-	imux_is_smixer =
-	snd_hda_codec_read(codec, 0x1e, 0, AC_VERB_GET_CONNECT_SEL, 0x00) == 3;
-	/* inputs */
-	/* PW 5/6/7 (29h/2ah/2bh) */
-	parm = AC_PWRST_D3;
-	set_pin_power_state(codec, 0x29, &parm);
-	set_pin_power_state(codec, 0x2a, &parm);
-	set_pin_power_state(codec, 0x2b, &parm);
-	parm = AC_PWRST_D0;
-	/* MUX9/10 (1eh/1fh), AIW 0/1 (10h/11h) */
-	update_power_state(codec, 0x1e, parm);
-	update_power_state(codec, 0x1f, parm);
-	update_power_state(codec, 0x10, parm);
-	update_power_state(codec, 0x11, parm);
-
-	/* outputs */
-	/* AOW0 (8h)*/
-	update_power_state(codec, 0x8, parm);
-
-	if (spec->codec_type == VT1802) {
-		/* PW4 (28h), MW4 (18h), MUX4(38h) */
-		parm = AC_PWRST_D3;
-		set_pin_power_state(codec, 0x28, &parm);
-		update_power_state(codec, 0x18, parm);
-		update_power_state(codec, 0x38, parm);
-	} else {
-		/* PW4 (26h), MW4 (1ch), MUX4(37h) */
-		parm = AC_PWRST_D3;
-		set_pin_power_state(codec, 0x26, &parm);
-		update_power_state(codec, 0x1c, parm);
-		update_power_state(codec, 0x37, parm);
-	}
-
-	if (spec->codec_type == VT1802) {
-		/* PW1 (25h), MW1 (15h), MUX1(35h), AOW1 (9h) */
-		parm = AC_PWRST_D3;
-		set_pin_power_state(codec, 0x25, &parm);
-		update_power_state(codec, 0x15, parm);
-		update_power_state(codec, 0x35, parm);
-	} else {
-		/* PW1 (25h), MW1 (19h), MUX1(35h), AOW1 (9h) */
-		parm = AC_PWRST_D3;
-		set_pin_power_state(codec, 0x25, &parm);
-		update_power_state(codec, 0x19, parm);
-		update_power_state(codec, 0x35, parm);
-	}
-
-	if (spec->gen.indep_hp_enabled)
-		update_power_state(codec, 0x9, AC_PWRST_D0);
-
-	/* Class-D */
-	/* PW0 (24h), MW0(18h/14h), MUX0(34h) */
-	present = snd_hda_jack_detect(codec, 0x25);
-
-	parm = AC_PWRST_D3;
-	set_pin_power_state(codec, 0x24, &parm);
-	parm = present ? AC_PWRST_D3 : AC_PWRST_D0;
-	if (spec->codec_type == VT1802)
-		update_power_state(codec, 0x14, parm);
-	else
-		update_power_state(codec, 0x18, parm);
-	update_power_state(codec, 0x34, parm);
-
-	/* Mono Out */
-	present = snd_hda_jack_detect(codec, 0x26);
-
-	parm = present ? AC_PWRST_D3 : AC_PWRST_D0;
-	if (spec->codec_type == VT1802) {
-		/* PW15 (33h), MW8(1ch), MUX8(3ch) */
-		update_power_state(codec, 0x33, parm);
-		update_power_state(codec, 0x1c, parm);
-		update_power_state(codec, 0x3c, parm);
-	} else {
-		/* PW15 (31h), MW8(17h), MUX8(3bh) */
-		update_power_state(codec, 0x31, parm);
-		update_power_state(codec, 0x17, parm);
-		update_power_state(codec, 0x3b, parm);
-	}
-	/* MW9 (21h) */
-	if (imux_is_smixer || !is_aa_path_mute(codec))
-		update_power_state(codec, 0x21, AC_PWRST_D0);
-	else
-		update_power_state(codec, 0x21, AC_PWRST_D3);
-}
-
 /*
  * pin fix-up
  */
@@ -1541,8 +1063,6 @@ static int patch_vt2002P(struct hda_codec *codec)
 		spec->init_verbs[spec->num_iverbs++] = vt2002P_init_verbs;
 
 	codec->patch_ops = via_patch_ops;
-
-	spec->set_widgets_power_state =  set_widgets_power_state_vt2002P;
 	return 0;
 }
 
@@ -1556,81 +1076,6 @@ static const struct hda_verb vt1812_init_verbs[] = {
 	{ }
 };
 
-static void set_widgets_power_state_vt1812(struct hda_codec *codec)
-{
-	struct via_spec *spec = codec->spec;
-	unsigned int parm;
-	unsigned int present;
-	/* inputs */
-	/* PW 5/6/7 (29h/2ah/2bh) */
-	parm = AC_PWRST_D3;
-	set_pin_power_state(codec, 0x29, &parm);
-	set_pin_power_state(codec, 0x2a, &parm);
-	set_pin_power_state(codec, 0x2b, &parm);
-	parm = AC_PWRST_D0;
-	/* MUX10/11 (1eh/1fh), AIW 0/1 (10h/11h) */
-	update_power_state(codec, 0x1e, parm);
-	update_power_state(codec, 0x1f, parm);
-	update_power_state(codec, 0x10, parm);
-	update_power_state(codec, 0x11, parm);
-
-	/* outputs */
-	/* AOW0 (8h)*/
-	update_power_state(codec, 0x8, AC_PWRST_D0);
-
-	/* PW4 (28h), MW4 (18h), MUX4(38h) */
-	parm = AC_PWRST_D3;
-	set_pin_power_state(codec, 0x28, &parm);
-	update_power_state(codec, 0x18, parm);
-	update_power_state(codec, 0x38, parm);
-
-	/* PW1 (25h), MW1 (15h), MUX1(35h), AOW1 (9h) */
-	parm = AC_PWRST_D3;
-	set_pin_power_state(codec, 0x25, &parm);
-	update_power_state(codec, 0x15, parm);
-	update_power_state(codec, 0x35, parm);
-	if (spec->gen.indep_hp_enabled)
-		update_power_state(codec, 0x9, AC_PWRST_D0);
-
-	/* Internal Speaker */
-	/* PW0 (24h), MW0(14h), MUX0(34h) */
-	present = snd_hda_jack_detect(codec, 0x25);
-
-	parm = AC_PWRST_D3;
-	set_pin_power_state(codec, 0x24, &parm);
-	if (present) {
-		update_power_state(codec, 0x14, AC_PWRST_D3);
-		update_power_state(codec, 0x34, AC_PWRST_D3);
-	} else {
-		update_power_state(codec, 0x14, AC_PWRST_D0);
-		update_power_state(codec, 0x34, AC_PWRST_D0);
-	}
-
-
-	/* Mono Out */
-	/* PW13 (31h), MW13(1ch), MUX13(3ch), MW14(3eh) */
-	present = snd_hda_jack_detect(codec, 0x28);
-
-	parm = AC_PWRST_D3;
-	set_pin_power_state(codec, 0x31, &parm);
-	if (present) {
-		update_power_state(codec, 0x1c, AC_PWRST_D3);
-		update_power_state(codec, 0x3c, AC_PWRST_D3);
-		update_power_state(codec, 0x3e, AC_PWRST_D3);
-	} else {
-		update_power_state(codec, 0x1c, AC_PWRST_D0);
-		update_power_state(codec, 0x3c, AC_PWRST_D0);
-		update_power_state(codec, 0x3e, AC_PWRST_D0);
-	}
-
-	/* PW15 (33h), MW15 (1dh), MUX15(3dh) */
-	parm = AC_PWRST_D3;
-	set_pin_power_state(codec, 0x33, &parm);
-	update_power_state(codec, 0x1d, parm);
-	update_power_state(codec, 0x3d, parm);
-
-}
-
 /* patch for vt1812 */
 static int patch_vt1812(struct hda_codec *codec)
 {
@@ -1657,8 +1102,6 @@ static int patch_vt1812(struct hda_codec *codec)
 	spec->init_verbs[spec->num_iverbs++]  = vt1812_init_verbs;
 
 	codec->patch_ops = via_patch_ops;
-
-	spec->set_widgets_power_state =  set_widgets_power_state_vt1812;
 	return 0;
 }
 
@@ -1674,84 +1117,6 @@ static const struct hda_verb vt3476_init_verbs[] = {
 	{ }
 };
 
-static void set_widgets_power_state_vt3476(struct hda_codec *codec)
-{
-	struct via_spec *spec = codec->spec;
-	int imux_is_smixer;
-	unsigned int parm, parm2;
-	/* MUX10 (1eh) = stereo mixer */
-	imux_is_smixer =
-	snd_hda_codec_read(codec, 0x1e, 0, AC_VERB_GET_CONNECT_SEL, 0x00) == 4;
-	/* inputs */
-	/* PW 5/6/7 (29h/2ah/2bh) */
-	parm = AC_PWRST_D3;
-	set_pin_power_state(codec, 0x29, &parm);
-	set_pin_power_state(codec, 0x2a, &parm);
-	set_pin_power_state(codec, 0x2b, &parm);
-	if (imux_is_smixer)
-		parm = AC_PWRST_D0;
-	/* MUX10/11 (1eh/1fh), AIW 0/1 (10h/11h) */
-	update_power_state(codec, 0x1e, parm);
-	update_power_state(codec, 0x1f, parm);
-	update_power_state(codec, 0x10, parm);
-	update_power_state(codec, 0x11, parm);
-
-	/* outputs */
-	/* PW3 (27h), MW3(37h), AOW3 (bh) */
-	if (spec->codec_type == VT1705CF) {
-		parm = AC_PWRST_D3;
-		update_power_state(codec, 0x27, parm);
-		update_power_state(codec, 0x37, parm);
-	}	else {
-		parm = AC_PWRST_D3;
-		set_pin_power_state(codec, 0x27, &parm);
-		update_power_state(codec, 0x37, parm);
-	}
-
-	/* PW2 (26h), MW2(36h), AOW2 (ah) */
-	parm = AC_PWRST_D3;
-	set_pin_power_state(codec, 0x26, &parm);
-	update_power_state(codec, 0x36, parm);
-	if (smart51_enabled(codec)) {
-		/* PW7(2bh), MW7(3bh), MUX7(1Bh) */
-		set_pin_power_state(codec, 0x2b, &parm);
-		update_power_state(codec, 0x3b, parm);
-		update_power_state(codec, 0x1b, parm);
-	}
-	update_conv_power_state(codec, 0xa, parm, 2);
-
-	/* PW1 (25h), MW1(35h), AOW1 (9h) */
-	parm = AC_PWRST_D3;
-	set_pin_power_state(codec, 0x25, &parm);
-	update_power_state(codec, 0x35, parm);
-	if (smart51_enabled(codec)) {
-		/* PW6(2ah), MW6(3ah), MUX6(1ah) */
-		set_pin_power_state(codec, 0x2a, &parm);
-		update_power_state(codec, 0x3a, parm);
-		update_power_state(codec, 0x1a, parm);
-	}
-	update_conv_power_state(codec, 0x9, parm, 1);
-
-	/* PW4 (28h), MW4 (38h), MUX4(18h), AOW3(bh)/AOW0(8h) */
-	parm = AC_PWRST_D3;
-	set_pin_power_state(codec, 0x28, &parm);
-	update_power_state(codec, 0x38, parm);
-	update_power_state(codec, 0x18, parm);
-	if (spec->gen.indep_hp_enabled)
-		update_conv_power_state(codec, 0xb, parm, 3);
-	parm2 = parm; /* for pin 0x0b */
-
-	/* PW0 (24h), MW0(34h), MW9(3fh), AOW0 (8h) */
-	parm = AC_PWRST_D3;
-	set_pin_power_state(codec, 0x24, &parm);
-	update_power_state(codec, 0x34, parm);
-	if (!spec->gen.indep_hp_enabled && parm2 != AC_PWRST_D3)
-		parm = parm2;
-	update_conv_power_state(codec, 0x8, parm, 0);
-	/* MW9 (21h), Mw2 (1ah), AOW0 (8h) */
-	update_power_state(codec, 0x3f, imux_is_smixer ? AC_PWRST_D0 : parm);
-}
-
 static int patch_vt3476(struct hda_codec *codec)
 {
 	struct via_spec *spec;
@@ -1775,9 +1140,6 @@ static int patch_vt3476(struct hda_codec *codec)
 	spec->init_verbs[spec->num_iverbs++] = vt3476_init_verbs;
 
 	codec->patch_ops = via_patch_ops;
-
-	spec->set_widgets_power_state = set_widgets_power_state_vt3476;
-
 	return 0;
 }
 
-- 
2.3.3

^ permalink raw reply related	[flat|nested] 21+ messages in thread

* [PATCH 4/4] ALSA: hda - Adjust power of beep widget and outputs
  2015-03-18  8:50 [PATCH 0/4] More aggressive PM for HD-audio Takashi Iwai
                   ` (2 preceding siblings ...)
  2015-03-18  8:50 ` [PATCH 3/4] ALSA: hda - Use the new power control for VIA codecs Takashi Iwai
@ 2015-03-18  8:50 ` Takashi Iwai
  2015-03-18 19:34 ` [PATCH 0/4] More aggressive PM for HD-audio David Henningsson
  2015-03-20 16:20 ` David Henningsson
  5 siblings, 0 replies; 21+ messages in thread
From: Takashi Iwai @ 2015-03-18  8:50 UTC (permalink / raw)
  To: alsa-devel; +Cc: David Henningsson

As the widget PM may turn off the pins, this might lead to the silent
output for beep when no explicit paths are given.  This patch adds
fake output paths for the beep widget so that the output pins are
dynamically powered upon beep on/off.

Signed-off-by: Takashi Iwai <tiwai@suse.de>
---
 sound/pci/hda/hda_beep.c    | 29 ++++++++++---------
 sound/pci/hda/hda_beep.h    |  1 +
 sound/pci/hda/hda_generic.c | 69 +++++++++++++++++++++++++++++++++++++++++++++
 3 files changed, 86 insertions(+), 13 deletions(-)

diff --git a/sound/pci/hda/hda_beep.c b/sound/pci/hda/hda_beep.c
index 581b7fdef0e3..4cdac3a71cae 100644
--- a/sound/pci/hda/hda_beep.c
+++ b/sound/pci/hda/hda_beep.c
@@ -33,30 +33,36 @@ enum {
 	DIGBEEP_HZ_MAX = 12000000,	/* 12 KHz */
 };
 
-static void snd_hda_generate_beep(struct work_struct *work)
+/* generate or stop tone */
+static void generate_tone(struct hda_beep *beep, int tone)
 {
-	struct hda_beep *beep =
-		container_of(work, struct hda_beep, beep_work);
 	struct hda_codec *codec = beep->codec;
-	int tone;
 
-	if (!beep->enabled)
-		return;
-
-	tone = beep->tone;
 	if (tone && !beep->playing) {
 		snd_hda_power_up(codec);
+		if (beep->power_hook)
+			beep->power_hook(beep, true);
 		beep->playing = 1;
 	}
-	/* generate tone */
 	snd_hda_codec_write(codec, beep->nid, 0,
 			    AC_VERB_SET_BEEP_CONTROL, tone);
 	if (!tone && beep->playing) {
 		beep->playing = 0;
+		if (beep->power_hook)
+			beep->power_hook(beep, false);
 		snd_hda_power_down(codec);
 	}
 }
 
+static void snd_hda_generate_beep(struct work_struct *work)
+{
+	struct hda_beep *beep =
+		container_of(work, struct hda_beep, beep_work);
+
+	if (beep->enabled)
+		generate_tone(beep, beep->tone);
+}
+
 /* (non-standard) Linear beep tone calculation for IDT/STAC codecs 
  *
  * The tone frequency of beep generator on IDT/STAC codecs is
@@ -130,10 +136,7 @@ static void turn_off_beep(struct hda_beep *beep)
 	cancel_work_sync(&beep->beep_work);
 	if (beep->playing) {
 		/* turn off beep */
-		snd_hda_codec_write(beep->codec, beep->nid, 0,
-				    AC_VERB_SET_BEEP_CONTROL, 0);
-		beep->playing = 0;
-		snd_hda_power_down(beep->codec);
+		generate_tone(beep, 0);
 	}
 }
 
diff --git a/sound/pci/hda/hda_beep.h b/sound/pci/hda/hda_beep.h
index a63b5e077332..46524ff7e79e 100644
--- a/sound/pci/hda/hda_beep.h
+++ b/sound/pci/hda/hda_beep.h
@@ -40,6 +40,7 @@ struct hda_beep {
 	unsigned int playing:1;
 	struct work_struct beep_work; /* scheduled task for beep event */
 	struct mutex mutex;
+	void (*power_hook)(struct hda_beep *beep, bool on);
 };
 
 #ifdef CONFIG_SND_HDA_INPUT_BEEP
diff --git a/sound/pci/hda/hda_generic.c b/sound/pci/hda/hda_generic.c
index 8a5055d296f5..d7ca388651da 100644
--- a/sound/pci/hda/hda_generic.c
+++ b/sound/pci/hda/hda_generic.c
@@ -654,6 +654,9 @@ static bool is_active_nid(struct hda_codec *codec, hda_nid_t nid,
 	int type = get_wcaps_type(get_wcaps(codec, nid));
 	int i, n;
 
+	if (nid == codec->afg)
+		return true;
+
 	for (n = 0; n < spec->paths.used; n++) {
 		struct nid_path *path = snd_array_elem(&spec->paths, n);
 		if (!path->active)
@@ -829,6 +832,8 @@ static hda_nid_t path_power_update(struct hda_codec *codec,
 
 	for (i = 0; i < path->depth; i++) {
 		nid = path->path[i];
+		if (nid == codec->afg)
+			continue;
 		if (!allow_powerdown || is_active_nid_for_any(codec, nid))
 			state = AC_PWRST_D0;
 		else
@@ -4073,6 +4078,64 @@ static void sync_all_pin_power_ctls(struct hda_codec *codec)
 		sync_pin_power_ctls(codec, 1, &cfg->inputs[i].pin);
 }
 
+/* add fake paths if not present yet */
+static int add_fake_paths(struct hda_codec *codec, hda_nid_t nid,
+			   int num_pins, const hda_nid_t *pins)
+{
+	struct hda_gen_spec *spec = codec->spec;
+	struct nid_path *path;
+	int i;
+
+	for (i = 0; i < num_pins; i++) {
+		if (!pins[i])
+			break;
+		if (get_nid_path(codec, nid, pins[i], 0))
+			continue;
+		path = snd_array_new(&spec->paths);
+		if (!path)
+			return -ENOMEM;
+		memset(path, 0, sizeof(*path));
+		path->depth = 2;
+		path->path[0] = nid;
+		path->path[1] = pins[i];
+		path->active = true;
+	}
+	return 0;
+}
+
+/* create fake paths to all outputs from beep */
+static int add_fake_beep_paths(struct hda_codec *codec)
+{
+	struct hda_gen_spec *spec = codec->spec;
+	struct auto_pin_cfg *cfg = &spec->autocfg;
+	hda_nid_t nid = spec->beep_nid;
+	int err;
+
+	if (!codec->power_mgmt || !nid)
+		return 0;
+	err = add_fake_paths(codec, nid, cfg->line_outs, cfg->line_out_pins);
+	if (err < 0)
+		return err;
+	if (cfg->line_out_type != AUTO_PIN_HP_OUT) {
+		err = add_fake_paths(codec, nid, cfg->hp_outs, cfg->hp_pins);
+		if (err < 0)
+			return err;
+	}
+	if (cfg->line_out_type != AUTO_PIN_SPEAKER_OUT) {
+		err = add_fake_paths(codec, nid, cfg->speaker_outs,
+				     cfg->speaker_pins);
+		if (err < 0)
+			return err;
+	}
+	return 0;
+}
+
+/* power up/down beep widget and its output paths */
+static void beep_power_hook(struct hda_beep *beep, bool on)
+{
+	set_path_power(beep->codec, beep->nid, -1, on);
+}
+
 /*
  * Jack detections for HP auto-mute and mic-switch
  */
@@ -4837,6 +4900,12 @@ int snd_hda_gen_parse_auto_config(struct hda_codec *codec,
 		err = snd_hda_attach_beep_device(codec, spec->beep_nid);
 		if (err < 0)
 			return err;
+		if (codec->beep && codec->power_mgmt) {
+			err = add_fake_beep_paths(codec);
+			if (err < 0)
+				return err;
+			codec->beep->power_hook = beep_power_hook;
+		}
 	}
 
 	return 1;
-- 
2.3.3

^ permalink raw reply related	[flat|nested] 21+ messages in thread

* Re: [PATCH 0/4] More aggressive PM for HD-audio
  2015-03-18  8:50 [PATCH 0/4] More aggressive PM for HD-audio Takashi Iwai
                   ` (3 preceding siblings ...)
  2015-03-18  8:50 ` [PATCH 4/4] ALSA: hda - Adjust power of beep widget and outputs Takashi Iwai
@ 2015-03-18 19:34 ` David Henningsson
  2015-03-18 20:02   ` Takashi Iwai
  2015-03-20 16:20 ` David Henningsson
  5 siblings, 1 reply; 21+ messages in thread
From: David Henningsson @ 2015-03-18 19:34 UTC (permalink / raw)
  To: Takashi Iwai, alsa-devel



On 2015-03-18 09:50, Takashi Iwai wrote:
> Hi,
>
> here is a patchset for supporting more aggressive PM for HD-audio.
> This allows to change the power state of each widget more dynamically
> with jack and stream states.  It's activated only when the codec
> driver (or via sysfs or f/w patch) sets codec->power_mgmt flag.

Cool. Could you elaborate on how the power_mgmt flag interacts with the 
power_save module parameter (which, on Ubuntu, is set dynamically based 
on AC power or not)? I e, does it make sense to test this both with and 
without power_save enabled?

Also I assume power_save_controller should not matter, right?

>
> In theory, this should work for the recent Realtek codecs, but
> currently I have no machine for test.
>
> David, could you or your team check whether this works for ALC282 or
> such?  Just add like:
>
> --- a/sound/pci/hda/patch_realtek.c
> +++ b/sound/pci/hda/patch_realtek.c
> @@ -5415,6 +5415,7 @@ static int patch_alc269(struct hda_codec *codec)
>   
>   	spec = codec->spec;
>   	spec->gen.shared_mic_vref_pin = 0x18;
> +	codec->power_mgmt = 1;
>   
>   	snd_hda_pick_fixup(codec, alc269_fixup_models,
>   		       alc269_fixup_tbl, alc269_fixups);
>
>
> The patchset is for for-next branch of sound git tree, but they might
> be applicable to 4.0-rc (or even older), too.  The current patches are
> found in topic/hda-power branch.
>
>
> thanks,
>
> Takashi
>
> ===
>
> Takashi Iwai (4):
>    ALSA: hda - Simplify PCM setup overrides
>    ALSA: hda - Support advanced power state controls
>    ALSA: hda - Use the new power control for VIA codecs
>    ALSA: hda - Adjust power of beep widget and outputs
>
>   sound/pci/hda/hda_beep.c       |  29 +-
>   sound/pci/hda/hda_beep.h       |   1 +
>   sound/pci/hda/hda_codec.c      |   4 +
>   sound/pci/hda/hda_codec.h      |   2 +
>   sound/pci/hda/hda_generic.c    | 480 ++++++++++++++++++++++++------
>   sound/pci/hda/hda_generic.h    |   5 +-
>   sound/pci/hda/patch_realtek.c  |  41 ---
>   sound/pci/hda/patch_sigmatel.c |   5 +
>   sound/pci/hda/patch_via.c      | 662 +----------------------------------------
>   9 files changed, 427 insertions(+), 802 deletions(-)
>

^ permalink raw reply	[flat|nested] 21+ messages in thread

* Re: [PATCH 0/4] More aggressive PM for HD-audio
  2015-03-18 19:34 ` [PATCH 0/4] More aggressive PM for HD-audio David Henningsson
@ 2015-03-18 20:02   ` Takashi Iwai
  0 siblings, 0 replies; 21+ messages in thread
From: Takashi Iwai @ 2015-03-18 20:02 UTC (permalink / raw)
  To: David Henningsson; +Cc: alsa-devel

At Wed, 18 Mar 2015 20:34:34 +0100,
David Henningsson wrote:
> 
> 
> 
> On 2015-03-18 09:50, Takashi Iwai wrote:
> > Hi,
> >
> > here is a patchset for supporting more aggressive PM for HD-audio.
> > This allows to change the power state of each widget more dynamically
> > with jack and stream states.  It's activated only when the codec
> > driver (or via sysfs or f/w patch) sets codec->power_mgmt flag.
> 
> Cool. Could you elaborate on how the power_mgmt flag interacts with the 
> power_save module parameter (which, on Ubuntu, is set dynamically based 
> on AC power or not)? I e, does it make sense to test this both with and 
> without power_save enabled?
> 
> Also I assume power_save_controller should not matter, right?

The new stuff basically works independently from traditional
power_save and power_save_controller options.  But, you can think it's
on top of power_save stuff, i.e. trying to power on/off of each widget
in the codec while the codec itself is powered on by power_save.

Hierarchy is something like:
  power_mgmt  (managing D0/D3 of each codec widget)
    --> power_save  (managing D0/D3 of FG node of the codec)
      --> power_save_controller  (managing D0/D3 of HDA controller)


Takashi

^ permalink raw reply	[flat|nested] 21+ messages in thread

* Re: [PATCH 0/4] More aggressive PM for HD-audio
  2015-03-18  8:50 [PATCH 0/4] More aggressive PM for HD-audio Takashi Iwai
                   ` (4 preceding siblings ...)
  2015-03-18 19:34 ` [PATCH 0/4] More aggressive PM for HD-audio David Henningsson
@ 2015-03-20 16:20 ` David Henningsson
  2015-03-20 16:28   ` Takashi Iwai
  2015-03-21  6:38   ` Hui Wang
  5 siblings, 2 replies; 21+ messages in thread
From: David Henningsson @ 2015-03-20 16:20 UTC (permalink / raw)
  To: Takashi Iwai, alsa-devel, Hui Wang


On 2015-03-18 09:50, Takashi Iwai wrote:
> Hi,
>
> here is a patchset for supporting more aggressive PM for HD-audio.
> This allows to change the power state of each widget more dynamically
> with jack and stream states.  It's activated only when the codec
> driver (or via sysfs or f/w patch) sets codec->power_mgmt flag.
>
> In theory, this should work for the recent Realtek codecs, but
> currently I have no machine for test.
>
> David, could you or your team check whether this works for ALC282 or
> such?  Just add like:
>
> --- a/sound/pci/hda/patch_realtek.c
> +++ b/sound/pci/hda/patch_realtek.c
> @@ -5415,6 +5415,7 @@ static int patch_alc269(struct hda_codec *codec)
>
>   	spec = codec->spec;
>   	spec->gen.shared_mic_vref_pin = 0x18;
> +	codec->power_mgmt = 1;
>
>   	snd_hda_pick_fixup(codec, alc269_fixup_models,
>   		       alc269_fixup_tbl, alc269_fixups);
>
>
> The patchset is for for-next branch of sound git tree, but they might
> be applicable to 4.0-rc (or even older), too.  The current patches are
> found in topic/hda-power branch.

So I hoped to be able to look at this today, but it turns out the 
machine I was thinking of using for testing has an ALC262 codec, which 
hardly counts as "new".

Hui, is this something you feel like taking on? Otherwise I'll try to 
talk to someone in Taipei.

Anyhow, after reading through the code, I have a question about LEDs. It 
could be that if vref is used for controlling a LED, maybe that pin 
needs to stay in D0 for the LED to stay lit. Is this correctly handled? 
I couldn't find any code specific to that issue, but maybe I just missed it.

Also, I find the power_mgmt name easy to confuse with the existing 
power_save parameter, perhaps power_save_pin, power_save_node or 
power_save_widget is better?

>
>
> thanks,
>
> Takashi
>
> ===
>
> Takashi Iwai (4):
>    ALSA: hda - Simplify PCM setup overrides
>    ALSA: hda - Support advanced power state controls
>    ALSA: hda - Use the new power control for VIA codecs
>    ALSA: hda - Adjust power of beep widget and outputs
>
>   sound/pci/hda/hda_beep.c       |  29 +-
>   sound/pci/hda/hda_beep.h       |   1 +
>   sound/pci/hda/hda_codec.c      |   4 +
>   sound/pci/hda/hda_codec.h      |   2 +
>   sound/pci/hda/hda_generic.c    | 480 ++++++++++++++++++++++++------
>   sound/pci/hda/hda_generic.h    |   5 +-
>   sound/pci/hda/patch_realtek.c  |  41 ---
>   sound/pci/hda/patch_sigmatel.c |   5 +
>   sound/pci/hda/patch_via.c      | 662 +----------------------------------------
>   9 files changed, 427 insertions(+), 802 deletions(-)
>

-- 
David Henningsson, Canonical Ltd.
https://launchpad.net/~diwic

^ permalink raw reply	[flat|nested] 21+ messages in thread

* Re: [PATCH 0/4] More aggressive PM for HD-audio
  2015-03-20 16:20 ` David Henningsson
@ 2015-03-20 16:28   ` Takashi Iwai
  2015-03-20 17:18     ` Takashi Iwai
  2015-03-21  6:38   ` Hui Wang
  1 sibling, 1 reply; 21+ messages in thread
From: Takashi Iwai @ 2015-03-20 16:28 UTC (permalink / raw)
  To: David Henningsson; +Cc: Hui Wang, alsa-devel

At Fri, 20 Mar 2015 17:20:59 +0100,
David Henningsson wrote:
> 
> Anyhow, after reading through the code, I have a question about LEDs. It 
> could be that if vref is used for controlling a LED, maybe that pin 
> needs to stay in D0 for the LED to stay lit. Is this correctly handled? 
> I couldn't find any code specific to that issue, but maybe I just missed it.

Good point.  As far as I know, IDT codecs keep pinctl value no matter
whether the widget power state is.  So, it should be OK, judging only
from the spec.  But we need testing with the actual machine.  Maybe
it's really need a power up.

The VREF pins have to be constantly powered on, the fix shouldn't be
too difficult.

> Also, I find the power_mgmt name easy to confuse with the existing 
> power_save parameter, perhaps power_save_pin, power_save_node or 
> power_save_widget is better?

I don't mind renaming.  power_save_pin isn't appropriate because it's
not only about pins but all paths in general.  power_save_node might
sound generic enough.


thanks,

Takashi

^ permalink raw reply	[flat|nested] 21+ messages in thread

* Re: [PATCH 0/4] More aggressive PM for HD-audio
  2015-03-20 16:28   ` Takashi Iwai
@ 2015-03-20 17:18     ` Takashi Iwai
  2015-03-20 17:33       ` Takashi Iwai
  0 siblings, 1 reply; 21+ messages in thread
From: Takashi Iwai @ 2015-03-20 17:18 UTC (permalink / raw)
  To: David Henningsson; +Cc: Hui Wang, alsa-devel

At Fri, 20 Mar 2015 17:28:11 +0100,
Takashi Iwai wrote:
> 
> At Fri, 20 Mar 2015 17:20:59 +0100,
> David Henningsson wrote:
> > 
> > Anyhow, after reading through the code, I have a question about LEDs. It 
> > could be that if vref is used for controlling a LED, maybe that pin 
> > needs to stay in D0 for the LED to stay lit. Is this correctly handled? 
> > I couldn't find any code specific to that issue, but maybe I just missed it.
> 
> Good point.  As far as I know, IDT codecs keep pinctl value no matter
> whether the widget power state is.  So, it should be OK, judging only
> from the spec.  But we need testing with the actual machine.  Maybe
> it's really need a power up.
> 
> The VREF pins have to be constantly powered on, the fix shouldn't be
> too difficult.

I'm convinced that it's safer to power them up, so added the patch
below.  For some HP laptops with Realtek need the similar call.

Also, I'm going to rename codec->power_mgmt with
codec->power_save_node, too.


thanks,

Takashi

-- 8< --
From: Takashi Iwai <tiwai@suse.de>
Subject: [PATCH] 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>
---
 sound/pci/hda/hda_generic.c    | 38 ++++++++++++++++++++++++++++++--------
 sound/pci/hda/hda_generic.h    |  2 ++
 sound/pci/hda/patch_sigmatel.c |  6 ++++++
 3 files changed, 38 insertions(+), 8 deletions(-)

diff --git a/sound/pci/hda/hda_generic.c b/sound/pci/hda/hda_generic.c
index d7ca388651da..94c7f43ad182 100644
--- a/sound/pci/hda/hda_generic.c
+++ b/sound/pci/hda/hda_generic.c
@@ -662,10 +662,10 @@ static bool is_active_nid(struct hda_codec *codec, hda_nid_t nid,
 		if (!path->active)
 			continue;
 		if (codec->power_mgmt) {
-			if (!path->stream_enabled)
+			if (!path->stream_enabled && !path->pin_fixed)
 				continue;
 			/* ignore unplugged paths except for DAC/ADC */
-			if (!path->pin_enabled &&
+			if (!(path->pin_enabled || path->pin_fixed) &&
 			    type != AC_WID_AUD_OUT && type != AC_WID_AUD_IN)
 				continue;
 		}
@@ -1607,7 +1607,7 @@ static int check_aamix_out_path(struct hda_codec *codec, int path_idx)
 		return 0;
 	/* print_nid_path(codec, "output-aamix", path); */
 	path->active = false; /* unused as default */
-	path->pin_enabled = true; /* static route */
+	path->pin_fixed = true; /* static route */
 	return snd_hda_get_path_idx(codec, path);
 }
 
@@ -3044,7 +3044,7 @@ static int new_analog_input(struct hda_codec *codec, int input_idx,
 		if (path) {
 			print_nid_path(codec, "loopback-merge", path);
 			path->active = true;
-			path->pin_enabled = true; /* static route */
+			path->pin_fixed = true; /* static route */
 			path->stream_enabled = true; /* no DAC/ADC involved */
 			spec->loopback_merge_path =
 				snd_hda_get_path_idx(codec, path);
@@ -3847,7 +3847,7 @@ static void parse_digital(struct hda_codec *codec)
 			continue;
 		print_nid_path(codec, "digout", path);
 		path->active = true;
-		path->pin_enabled = true; /* no jack detection */
+		path->pin_fixed = true; /* no jack detection */
 		spec->digout_paths[i] = snd_hda_get_path_idx(codec, path);
 		set_pin_target(codec, pin, PIN_OUT, false);
 		if (!nums) {
@@ -3875,7 +3875,7 @@ static void parse_digital(struct hda_codec *codec)
 			if (path) {
 				print_nid_path(codec, "digin", path);
 				path->active = true;
-				path->pin_enabled = true; /* no jack */
+				path->pin_fixed = true; /* no jack */
 				spec->dig_in_nid = dig_nid;
 				spec->digin_path = snd_hda_get_path_idx(codec, path);
 				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,
 				path->pin_enabled = pin_state;
 			if (stream_state >= 0)
 				path->stream_enabled = stream_state;
-			if (path->pin_enabled != pin_old ||
-			    path->stream_enabled != stream_old) {
+			if ((!path->pin_fixed && path->pin_enabled != pin_old)
+			    || path->stream_enabled != stream_old) {
 				last = path_power_update(codec, path, true);
 				if (last)
 					changed = last;
@@ -4136,6 +4136,28 @@ static void beep_power_hook(struct hda_beep *beep, bool on)
 	set_path_power(beep->codec, beep->nid, -1, on);
 }
 
+/**
+ * snd_hda_gen_fix_pin_power - Fix the power of the given pin widget to D0
+ * @codec: the HDA codec
+ * @pin: NID of pin to fix
+ */
+int snd_hda_gen_fix_pin_power(struct hda_codec *codec, hda_nid_t pin)
+{
+	struct hda_gen_spec *spec = codec->spec;
+	struct nid_path *path;
+
+	path = snd_array_new(&spec->paths);
+	if (!path)
+		return -ENOMEM;
+	memset(path, 0, sizeof(*path));
+	path->depth = 1;
+	path->path[0] = pin;
+	path->active = true;
+	path->pin_fixed = true;
+	return 0;
+}
+EXPORT_SYMBOL_GPL(snd_hda_gen_fix_pin_power);
+
 /*
  * Jack detections for HP auto-mute and mic-switch
  */
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 {
 	unsigned int ctls[NID_PATH_NUM_CTLS]; /* NID_PATH_XXX_CTL */
 	bool active:1;		/* activated by driver */
 	bool pin_enabled:1;	/* pins are enabled */
+	bool pin_fixed:1;	/* path with fixed pin */
 	bool stream_enabled:1;	/* stream is active */
 };
 
@@ -343,5 +344,6 @@ unsigned int snd_hda_gen_path_power_filter(struct hda_codec *codec,
 					   hda_nid_t nid,
 					   unsigned int power_state);
 void snd_hda_gen_stream_pm(struct hda_codec *codec, hda_nid_t nid, bool on);
+int snd_hda_gen_fix_pin_power(struct hda_codec *codec, hda_nid_t pin);
 
 #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)
 	if (err < 0)
 		return err;
 
+	if (spec->vref_mute_led_nid) {
+		err = snd_hda_gen_fix_pin_power(codec, spec->vref_mute_led_nid);
+		if (err < 0)
+			return err;
+	}
+
 	/* setup analog beep controls */
 	if (spec->anabeep_nid > 0) {
 		err = stac_auto_create_beep_ctls(codec,
-- 
2.3.3

^ permalink raw reply related	[flat|nested] 21+ messages in thread

* Re: [PATCH 0/4] More aggressive PM for HD-audio
  2015-03-20 17:18     ` Takashi Iwai
@ 2015-03-20 17:33       ` Takashi Iwai
  0 siblings, 0 replies; 21+ messages in thread
From: Takashi Iwai @ 2015-03-20 17:33 UTC (permalink / raw)
  To: David Henningsson; +Cc: Hui Wang, alsa-devel

At Fri, 20 Mar 2015 18:18:08 +0100,
Takashi Iwai wrote:
> 
> At Fri, 20 Mar 2015 17:28:11 +0100,
> Takashi Iwai wrote:
> > 
> > At Fri, 20 Mar 2015 17:20:59 +0100,
> > David Henningsson wrote:
> > > 
> > > Anyhow, after reading through the code, I have a question about LEDs. It 
> > > could be that if vref is used for controlling a LED, maybe that pin 
> > > needs to stay in D0 for the LED to stay lit. Is this correctly handled? 
> > > I couldn't find any code specific to that issue, but maybe I just missed it.
> > 
> > Good point.  As far as I know, IDT codecs keep pinctl value no matter
> > whether the widget power state is.  So, it should be OK, judging only
> > from the spec.  But we need testing with the actual machine.  Maybe
> > it's really need a power up.
> > 
> > The VREF pins have to be constantly powered on, the fix shouldn't be
> > too difficult.
> 
> I'm convinced that it's safer to power them up, so added the patch
> below.  For some HP laptops with Realtek need the similar call.

There was a minor issue in the previous patch, some digital I/O paths
are powered up unnecessarily.  The revised patch is below.

The latest patches are found in topic/hda-power branch.


thanks,

Takashi

-- 8< --
From: Takashi Iwai <tiwai@suse.de>
Subject: [PATCH v2] 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>
---
 sound/pci/hda/hda_generic.c    | 37 ++++++++++++++++++++++++++++++-------
 sound/pci/hda/hda_generic.h    |  2 ++
 sound/pci/hda/patch_sigmatel.c |  6 ++++++
 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,
 			if (!path->stream_enabled)
 				continue;
 			/* ignore unplugged paths except for DAC/ADC */
-			if (!path->pin_enabled &&
+			if (!(path->pin_enabled || path->pin_fixed) &&
 			    type != AC_WID_AUD_OUT && type != AC_WID_AUD_IN)
 				continue;
 		}
@@ -1607,7 +1607,7 @@ static int check_aamix_out_path(struct hda_codec *codec, int path_idx)
 		return 0;
 	/* print_nid_path(codec, "output-aamix", path); */
 	path->active = false; /* unused as default */
-	path->pin_enabled = true; /* static route */
+	path->pin_fixed = true; /* static route */
 	return snd_hda_get_path_idx(codec, path);
 }
 
@@ -3044,7 +3044,7 @@ static int new_analog_input(struct hda_codec *codec, int input_idx,
 		if (path) {
 			print_nid_path(codec, "loopback-merge", path);
 			path->active = true;
-			path->pin_enabled = true; /* static route */
+			path->pin_fixed = true; /* static route */
 			path->stream_enabled = true; /* no DAC/ADC involved */
 			spec->loopback_merge_path =
 				snd_hda_get_path_idx(codec, path);
@@ -3847,7 +3847,7 @@ static void parse_digital(struct hda_codec *codec)
 			continue;
 		print_nid_path(codec, "digout", path);
 		path->active = true;
-		path->pin_enabled = true; /* no jack detection */
+		path->pin_fixed = true; /* no jack detection */
 		spec->digout_paths[i] = snd_hda_get_path_idx(codec, path);
 		set_pin_target(codec, pin, PIN_OUT, false);
 		if (!nums) {
@@ -3875,7 +3875,7 @@ static void parse_digital(struct hda_codec *codec)
 			if (path) {
 				print_nid_path(codec, "digin", path);
 				path->active = true;
-				path->pin_enabled = true; /* no jack */
+				path->pin_fixed = true; /* no jack */
 				spec->dig_in_nid = dig_nid;
 				spec->digin_path = snd_hda_get_path_idx(codec, path);
 				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,
 				path->pin_enabled = pin_state;
 			if (stream_state >= 0)
 				path->stream_enabled = stream_state;
-			if (path->pin_enabled != pin_old ||
-			    path->stream_enabled != stream_old) {
+			if ((!path->pin_fixed && path->pin_enabled != pin_old)
+			    || path->stream_enabled != stream_old) {
 				last = path_power_update(codec, path, true);
 				if (last)
 					changed = last;
@@ -4136,6 +4136,29 @@ static void beep_power_hook(struct hda_beep *beep, bool on)
 	set_path_power(beep->codec, beep->nid, -1, on);
 }
 
+/**
+ * snd_hda_gen_fix_pin_power - Fix the power of the given pin widget to D0
+ * @codec: the HDA codec
+ * @pin: NID of pin to fix
+ */
+int snd_hda_gen_fix_pin_power(struct hda_codec *codec, hda_nid_t pin)
+{
+	struct hda_gen_spec *spec = codec->spec;
+	struct nid_path *path;
+
+	path = snd_array_new(&spec->paths);
+	if (!path)
+		return -ENOMEM;
+	memset(path, 0, sizeof(*path));
+	path->depth = 1;
+	path->path[0] = pin;
+	path->active = true;
+	path->pin_fixed = true;
+	path->stream_enabled = true;
+	return 0;
+}
+EXPORT_SYMBOL_GPL(snd_hda_gen_fix_pin_power);
+
 /*
  * Jack detections for HP auto-mute and mic-switch
  */
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 {
 	unsigned int ctls[NID_PATH_NUM_CTLS]; /* NID_PATH_XXX_CTL */
 	bool active:1;		/* activated by driver */
 	bool pin_enabled:1;	/* pins are enabled */
+	bool pin_fixed:1;	/* path with fixed pin */
 	bool stream_enabled:1;	/* stream is active */
 };
 
@@ -343,5 +344,6 @@ unsigned int snd_hda_gen_path_power_filter(struct hda_codec *codec,
 					   hda_nid_t nid,
 					   unsigned int power_state);
 void snd_hda_gen_stream_pm(struct hda_codec *codec, hda_nid_t nid, bool on);
+int snd_hda_gen_fix_pin_power(struct hda_codec *codec, hda_nid_t pin);
 
 #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)
 	if (err < 0)
 		return err;
 
+	if (spec->vref_mute_led_nid) {
+		err = snd_hda_gen_fix_pin_power(codec, spec->vref_mute_led_nid);
+		if (err < 0)
+			return err;
+	}
+
 	/* setup analog beep controls */
 	if (spec->anabeep_nid > 0) {
 		err = stac_auto_create_beep_ctls(codec,
-- 
2.3.3

^ permalink raw reply related	[flat|nested] 21+ messages in thread

* Re: [PATCH 0/4] More aggressive PM for HD-audio
  2015-03-20 16:20 ` David Henningsson
  2015-03-20 16:28   ` Takashi Iwai
@ 2015-03-21  6:38   ` Hui Wang
       [not found]     ` <5513FA8B.402@canonical.com>
  1 sibling, 1 reply; 21+ messages in thread
From: Hui Wang @ 2015-03-21  6:38 UTC (permalink / raw)
  To: David Henningsson, Takashi Iwai, alsa-devel

On 03/21/2015 12:20 AM, David Henningsson wrote:
>
> On 2015-03-18 09:50, Takashi Iwai wrote:
>> Hi,
>>
>> here is a patchset for supporting more aggressive PM for HD-audio.
>> This allows to change the power state of each widget more dynamically
>> with jack and stream states.  It's activated only when the codec
>> driver (or via sysfs or f/w patch) sets codec->power_mgmt flag.
>>
>> In theory, this should work for the recent Realtek codecs, but
>> currently I have no machine for test.
>>
>> David, could you or your team check whether this works for ALC282 or
>> such?  Just add like:
>>
>> --- a/sound/pci/hda/patch_realtek.c
>> +++ b/sound/pci/hda/patch_realtek.c
>> @@ -5415,6 +5415,7 @@ static int patch_alc269(struct hda_codec *codec)
>>
>>       spec = codec->spec;
>>       spec->gen.shared_mic_vref_pin = 0x18;
>> +    codec->power_mgmt = 1;
>>
>>       snd_hda_pick_fixup(codec, alc269_fixup_models,
>>                  alc269_fixup_tbl, alc269_fixups);
>>
>>
>> The patchset is for for-next branch of sound git tree, but they might
>> be applicable to 4.0-rc (or even older), too.  The current patches are
>> found in topic/hda-power branch.
>
> So I hoped to be able to look at this today, but it turns out the 
> machine I was thinking of using for testing has an ALC262 codec, which 
> hardly counts as "new".
>
> Hui, is this something you feel like taking on? Otherwise I'll try to 
> talk to someone in Taipei.
>
OK, I will look for the machine to do the test next week.

Regards,
Hui.

> Anyhow, after reading through the code, I have a question about LEDs. 
> It could be that if vref is used for controlling a LED, maybe that pin 
> needs to stay in D0 for the LED to stay lit. Is this correctly 
> handled? I couldn't find any code specific to that issue, but maybe I 
> just missed it.
>
> Also, I find the power_mgmt name easy to confuse with the existing 
> power_save parameter, perhaps power_save_pin, power_save_node or 
> power_save_widget is better?
>
>>
>>
>> thanks,
>>
>> Takashi
>>
>> ===
>>
>> Takashi Iwai (4):
>>    ALSA: hda - Simplify PCM setup overrides
>>    ALSA: hda - Support advanced power state controls
>>    ALSA: hda - Use the new power control for VIA codecs
>>    ALSA: hda - Adjust power of beep widget and outputs
>>
>>   sound/pci/hda/hda_beep.c       |  29 +-
>>   sound/pci/hda/hda_beep.h       |   1 +
>>   sound/pci/hda/hda_codec.c      |   4 +
>>   sound/pci/hda/hda_codec.h      |   2 +
>>   sound/pci/hda/hda_generic.c    | 480 ++++++++++++++++++++++++------
>>   sound/pci/hda/hda_generic.h    |   5 +-
>>   sound/pci/hda/patch_realtek.c  |  41 ---
>>   sound/pci/hda/patch_sigmatel.c |   5 +
>>   sound/pci/hda/patch_via.c      | 662 
>> +----------------------------------------
>>   9 files changed, 427 insertions(+), 802 deletions(-)
>>
>

_______________________________________________
Alsa-devel mailing list
Alsa-devel@alsa-project.org
http://mailman.alsa-project.org/mailman/listinfo/alsa-devel

^ permalink raw reply	[flat|nested] 21+ messages in thread

* Re: [PATCH 0/4] More aggressive PM for HD-audio
       [not found]     ` <5513FA8B.402@canonical.com>
@ 2015-03-26 13:10       ` Takashi Iwai
  2015-03-26 13:52         ` Takashi Iwai
  0 siblings, 1 reply; 21+ messages in thread
From: Takashi Iwai @ 2015-03-26 13:10 UTC (permalink / raw)
  To: Hui Wang; +Cc: alsa-devel, David Henningsson

At Thu, 26 Mar 2015 20:24:43 +0800,
Hui Wang wrote:
> 
> [1  <text/plain; utf-8 (8bit)>]
> On 03/21/2015 02:38 PM, Hui Wang wrote:
> > On 03/21/2015 12:20 AM, David Henningsson wrote:
> >>
> >> On 2015-03-18 09:50, Takashi Iwai wrote:
> >>> Hi,
> >>>
> >>> here is a patchset for supporting more aggressive PM for HD-audio.
> >>> This allows to change the power state of each widget more dynamically
> >>> with jack and stream states.  It's activated only when the codec
> >>> driver (or via sysfs or f/w patch) sets codec->power_mgmt flag.
> >>>
> >>> In theory, this should work for the recent Realtek codecs, but
> >>> currently I have no machine for test.
> >>>
> >>> David, could you or your team check whether this works for ALC282 or
> >>> such?  Just add like:
> >>>
> >>> --- a/sound/pci/hda/patch_realtek.c
> >>> +++ b/sound/pci/hda/patch_realtek.c
> >>> @@ -5415,6 +5415,7 @@ static int patch_alc269(struct hda_codec *codec)
> >>>
> >>>       spec = codec->spec;
> >>>       spec->gen.shared_mic_vref_pin = 0x18;
> >>> +    codec->power_mgmt = 1;
> >>>
> >>>       snd_hda_pick_fixup(codec, alc269_fixup_models,
> >>>                  alc269_fixup_tbl, alc269_fixups);
> >>>
> >>>
> >>> The patchset is for for-next branch of sound git tree, but they might
> >>> be applicable to 4.0-rc (or even older), too.  The current patches are
> >>> found in topic/hda-power branch.
> >>
> >> So I hoped to be able to look at this today, but it turns out the 
> >> machine I was thinking of using for testing has an ALC262 codec, 
> >> which hardly counts as "new".
> >>
> >> Hui, is this something you feel like taking on? Otherwise I'll try to 
> >> talk to someone in Taipei.
> >>
> > OK, I will look for the machine to do the test next week.
> >
> > Regards,
> > Hui.
> >
> Sorry for late response, today is my first day in the office back from 
> vacation, I checked all machines in the Beijing office, none of them has 
> the ALC282 codec, I will continue to look for the machine from other office.
> 
> And I did the test on the machines with the alc283, alc255, alc292 and 
> alc269, the testing result were same, there were no sound output from 
> internal speaker or headphone, and the internal mic or external mic 
> can't record any sound. The test steps as below:
> 
> 1. power_save_node = 0
> checkout the hda-power branch, build the kernel based on this branch.
> Install the kernel to the above machines and boot into the desktop
> test internal speaker and internal mic, works very well, plug a headset, 
> test headphone and external mic, works very well.
> run pm_suspend, wait 5 seconds, wakeup the system, redo the above test, 
> everything works very well.

OK, this is expected.  The patch shouldn't touch this case.

> 2. power_save_node = 1
> enable the power_save_node as below:
> @@ -5426,6 +5426,8 @@ static int patch_alc269(struct hda_codec *codec)
> 
>          alc_auto_parse_customize_define(codec);
> 
> +       codec->power_save_node = 1;
> +
>          if (has_cdefine_beep(codec))
>                  spec->gen.beep_nid = 0x01;
> rebuild the kernel, install the kernel to the above machines and boot 
> into the desktop
> test internal speaker and internal mic, we can play sound to internal 
> speaker without any errors, but I can't hear any sound from the speaker; 
> I can use the internal mic to record without errors, but recorded file 
> did not include any sound pcm (maybe all 0x00 or 0xff)
> I plug a headset into the headset jack, the detection works very well, 
> but I can't hear sound from headphone when play a sound, and I can't use 
> headset mic to record any sound as well.
> 
> 
> And I attached 2 alsa-info.txt, one is the power_save_node=0, the other 
> is the power_save_node=1

Thanks.  The alsa-info.sh outputs show no difference but the power
state, so the widget attributes seem kept with the power state change,
as it seems.

Could you give alsa-info.sh output *during* playing with
power_save_node=1?


Takashi
_______________________________________________
Alsa-devel mailing list
Alsa-devel@alsa-project.org
http://mailman.alsa-project.org/mailman/listinfo/alsa-devel

^ permalink raw reply	[flat|nested] 21+ messages in thread

* Re: [PATCH 0/4] More aggressive PM for HD-audio
  2015-03-26 13:10       ` Takashi Iwai
@ 2015-03-26 13:52         ` Takashi Iwai
  2015-03-27  0:11           ` Hui Wang
  0 siblings, 1 reply; 21+ messages in thread
From: Takashi Iwai @ 2015-03-26 13:52 UTC (permalink / raw)
  To: Hui Wang; +Cc: alsa-devel, David Henningsson

At Thu, 26 Mar 2015 14:10:17 +0100,
Takashi Iwai wrote:
> 
> At Thu, 26 Mar 2015 20:24:43 +0800,
> Hui Wang wrote:
> > 
> > On 03/21/2015 02:38 PM, Hui Wang wrote:
> > > On 03/21/2015 12:20 AM, David Henningsson wrote:
> > >>
> > >> On 2015-03-18 09:50, Takashi Iwai wrote:
> > >>> Hi,
> > >>>
> > >>> here is a patchset for supporting more aggressive PM for HD-audio.
> > >>> This allows to change the power state of each widget more dynamically
> > >>> with jack and stream states.  It's activated only when the codec
> > >>> driver (or via sysfs or f/w patch) sets codec->power_mgmt flag.
> > >>>
> > >>> In theory, this should work for the recent Realtek codecs, but
> > >>> currently I have no machine for test.
> > >>>
> > >>> David, could you or your team check whether this works for ALC282 or
> > >>> such?  Just add like:
> > >>>
> > >>> --- a/sound/pci/hda/patch_realtek.c
> > >>> +++ b/sound/pci/hda/patch_realtek.c
> > >>> @@ -5415,6 +5415,7 @@ static int patch_alc269(struct hda_codec *codec)
> > >>>
> > >>>       spec = codec->spec;
> > >>>       spec->gen.shared_mic_vref_pin = 0x18;
> > >>> +    codec->power_mgmt = 1;
> > >>>
> > >>>       snd_hda_pick_fixup(codec, alc269_fixup_models,
> > >>>                  alc269_fixup_tbl, alc269_fixups);
> > >>>
> > >>>
> > >>> The patchset is for for-next branch of sound git tree, but they might
> > >>> be applicable to 4.0-rc (or even older), too.  The current patches are
> > >>> found in topic/hda-power branch.
> > >>
> > >> So I hoped to be able to look at this today, but it turns out the 
> > >> machine I was thinking of using for testing has an ALC262 codec, 
> > >> which hardly counts as "new".
> > >>
> > >> Hui, is this something you feel like taking on? Otherwise I'll try to 
> > >> talk to someone in Taipei.
> > >>
> > > OK, I will look for the machine to do the test next week.
> > >
> > > Regards,
> > > Hui.
> > >
> > Sorry for late response, today is my first day in the office back from 
> > vacation, I checked all machines in the Beijing office, none of them has 
> > the ALC282 codec, I will continue to look for the machine from other office.
> > 
> > And I did the test on the machines with the alc283, alc255, alc292 and 
> > alc269, the testing result were same, there were no sound output from 
> > internal speaker or headphone, and the internal mic or external mic 
> > can't record any sound. The test steps as below:
> > 
> > 1. power_save_node = 0
> > checkout the hda-power branch, build the kernel based on this branch.
> > Install the kernel to the above machines and boot into the desktop
> > test internal speaker and internal mic, works very well, plug a headset, 
> > test headphone and external mic, works very well.
> > run pm_suspend, wait 5 seconds, wakeup the system, redo the above test, 
> > everything works very well.
> 
> OK, this is expected.  The patch shouldn't touch this case.
> 
> > 2. power_save_node = 1
> > enable the power_save_node as below:
> > @@ -5426,6 +5426,8 @@ static int patch_alc269(struct hda_codec *codec)
> > 
> >          alc_auto_parse_customize_define(codec);
> > 
> > +       codec->power_save_node = 1;
> > +
> >          if (has_cdefine_beep(codec))
> >                  spec->gen.beep_nid = 0x01;
> > rebuild the kernel, install the kernel to the above machines and boot 
> > into the desktop
> > test internal speaker and internal mic, we can play sound to internal 
> > speaker without any errors, but I can't hear any sound from the speaker; 
> > I can use the internal mic to record without errors, but recorded file 
> > did not include any sound pcm (maybe all 0x00 or 0xff)
> > I plug a headset into the headset jack, the detection works very well, 
> > but I can't hear sound from headphone when play a sound, and I can't use 
> > headset mic to record any sound as well.
> > 
> > 
> > And I attached 2 alsa-info.txt, one is the power_save_node=0, the other 
> > is the power_save_node=1
> 
> Thanks.  The alsa-info.sh outputs show no difference but the power
> state, so the widget attributes seem kept with the power state change,
> as it seems.
> 
> Could you give alsa-info.sh output *during* playing with
> power_save_node=1?

Also, try to pull topic/hda-regmap branch in addition, and apply the
patch below.  This implements the partial sync for the widget path.
Note that the patch is totally untested.


thanks,

Takashi

diff --git a/include/sound/hda_regmap.h b/include/sound/hda_regmap.h
index 76648ccfbbf8..727a5801e298 100644
--- a/include/sound/hda_regmap.h
+++ b/include/sound/hda_regmap.h
@@ -202,4 +202,16 @@ snd_hdac_regmap_update_amp_stereo(struct hdac_device *codec, hda_nid_t nid,
 	return snd_hdac_regmap_update_raw(codec, cmd, mask, val);
 }
 
+/**
+ * snd_hdac_regmap_sync_node - sync the widget node attributes
+ * @codec: HD-audio codec
+ * @nid: NID to sync
+ */
+static inline void
+snd_hdac_regmap_sync_node(struct hdac_device *codec, hda_nid_t nid)
+{
+	regcache_mark_dirty(codec->regmap);
+	regcache_sync_region(codec->regmap, nid << 20, ((nid + 1) << 20) -1);
+}
+
 #endif /* __SOUND_HDA_REGMAP_H */
diff --git a/sound/pci/hda/hda_generic.c b/sound/pci/hda/hda_generic.c
index f7ccef5559de..1f2ca7be1468 100644
--- a/sound/pci/hda/hda_generic.c
+++ b/sound/pci/hda/hda_generic.c
@@ -842,10 +842,8 @@ static hda_nid_t path_power_update(struct hda_codec *codec,
 			snd_hda_codec_write(codec, nid, 0,
 					    AC_VERB_SET_POWER_STATE, state);
 			changed = nid;
-			/* here we assume that widget attributes (e.g. amp,
-			 * pinctl connection) don't change with local power
-			 * state change.  If not, need to sync the cache.
-			 */
+			if (state == AC_PWRST_D0)
+				snd_hdac_regmap_sync_node(&codec->core, nid);
 		}
 	}
 	return changed;
_______________________________________________
Alsa-devel mailing list
Alsa-devel@alsa-project.org
http://mailman.alsa-project.org/mailman/listinfo/alsa-devel

^ permalink raw reply related	[flat|nested] 21+ messages in thread

* Re: [PATCH 0/4] More aggressive PM for HD-audio
  2015-03-26 13:52         ` Takashi Iwai
@ 2015-03-27  0:11           ` Hui Wang
  2015-03-30  6:53             ` hwang4
  0 siblings, 1 reply; 21+ messages in thread
From: Hui Wang @ 2015-03-27  0:11 UTC (permalink / raw)
  To: Takashi Iwai; +Cc: alsa-devel, David Henningsson

On 03/26/2015 09:52 PM, Takashi Iwai wrote:
> At Thu, 26 Mar 2015 14:10:17 +0100,
> Takashi Iwai wrote:
>> At Thu, 26 Mar 2015 20:24:43 +0800,
>> Hui Wang wrote:
>>> On 03/21/2015 02:38 PM, Hui Wang wrote:
>>>> On 03/21/2015 12:20 AM, David Henningsson wrote:
>>>>> On 2015-03-18 09:50, Takashi Iwai wrote:
>>>>>> Hi,
>>>>>>
>>>>>> here is a patchset for supporting more aggressive PM for HD-audio.
>>>>>> This allows to change the power state of each widget more dynamically
>>>>>> with jack and stream states.  It's activated only when the codec
>>>>>> driver (or via sysfs or f/w patch) sets codec->power_mgmt flag.
>>>>>>
>>>>>> In theory, this should work for the recent Realtek codecs, but
>>>>>> currently I have no machine for test.
>>>>>>
>>>>>> David, could you or your team check whether this works for ALC282 or
>>>>>> such?  Just add like:
>>>>>>
>>>>>> --- a/sound/pci/hda/patch_realtek.c
>>>>>> +++ b/sound/pci/hda/patch_realtek.c
>>>>>> @@ -5415,6 +5415,7 @@ static int patch_alc269(struct hda_codec *codec)
>>>>>>
>>>>>>        spec = codec->spec;
>>>>>>        spec->gen.shared_mic_vref_pin = 0x18;
>>>>>> +    codec->power_mgmt = 1;
>>>>>>
>>>>>>        snd_hda_pick_fixup(codec, alc269_fixup_models,
>>>>>>                   alc269_fixup_tbl, alc269_fixups);
>>>>>>
>>>>>>
>>>>>> The patchset is for for-next branch of sound git tree, but they might
>>>>>> be applicable to 4.0-rc (or even older), too.  The current patches are
>>>>>> found in topic/hda-power branch.
>>>>> So I hoped to be able to look at this today, but it turns out the
>>>>> machine I was thinking of using for testing has an ALC262 codec,
>>>>> which hardly counts as "new".
>>>>>
>>>>> Hui, is this something you feel like taking on? Otherwise I'll try to
>>>>> talk to someone in Taipei.
>>>>>
>>>> OK, I will look for the machine to do the test next week.
>>>>
>>>> Regards,
>>>> Hui.
>>>>
>>> Sorry for late response, today is my first day in the office back from
>>> vacation, I checked all machines in the Beijing office, none of them has
>>> the ALC282 codec, I will continue to look for the machine from other office.
>>>
>>> And I did the test on the machines with the alc283, alc255, alc292 and
>>> alc269, the testing result were same, there were no sound output from
>>> internal speaker or headphone, and the internal mic or external mic
>>> can't record any sound. The test steps as below:
>>>
>>> 1. power_save_node = 0
>>> checkout the hda-power branch, build the kernel based on this branch.
>>> Install the kernel to the above machines and boot into the desktop
>>> test internal speaker and internal mic, works very well, plug a headset,
>>> test headphone and external mic, works very well.
>>> run pm_suspend, wait 5 seconds, wakeup the system, redo the above test,
>>> everything works very well.
>> OK, this is expected.  The patch shouldn't touch this case.
>>
>>> 2. power_save_node = 1
>>> enable the power_save_node as below:
>>> @@ -5426,6 +5426,8 @@ static int patch_alc269(struct hda_codec *codec)
>>>
>>>           alc_auto_parse_customize_define(codec);
>>>
>>> +       codec->power_save_node = 1;
>>> +
>>>           if (has_cdefine_beep(codec))
>>>                   spec->gen.beep_nid = 0x01;
>>> rebuild the kernel, install the kernel to the above machines and boot
>>> into the desktop
>>> test internal speaker and internal mic, we can play sound to internal
>>> speaker without any errors, but I can't hear any sound from the speaker;
>>> I can use the internal mic to record without errors, but recorded file
>>> did not include any sound pcm (maybe all 0x00 or 0xff)
>>> I plug a headset into the headset jack, the detection works very well,
>>> but I can't hear sound from headphone when play a sound, and I can't use
>>> headset mic to record any sound as well.
>>>
>>>
>>> And I attached 2 alsa-info.txt, one is the power_save_node=0, the other
>>> is the power_save_node=1
>> Thanks.  The alsa-info.sh outputs show no difference but the power
>> state, so the widget attributes seem kept with the power state change,
>> as it seems.
>>
>> Could you give alsa-info.sh output *during* playing with
>> power_save_node=1?
> Also, try to pull topic/hda-regmap branch in addition, and apply the
> patch below.  This implements the partial sync for the widget path.
> Note that the patch is totally untested.
Got it, I will do the test next Monday, since I can't access those 
machines until next Monday.

Regards,
Hui.
>
> thanks,
>
> Takashi
>
> diff --git a/include/sound/hda_regmap.h b/include/sound/hda_regmap.h
> index 76648ccfbbf8..727a5801e298 100644
> --- a/include/sound/hda_regmap.h
> +++ b/include/sound/hda_regmap.h
> @@ -202,4 +202,16 @@ snd_hdac_regmap_update_amp_stereo(struct hdac_device *codec, hda_nid_t nid,
>   	return snd_hdac_regmap_update_raw(codec, cmd, mask, val);
>   }
>   
> +/**
> + * snd_hdac_regmap_sync_node - sync the widget node attributes
> + * @codec: HD-audio codec
> + * @nid: NID to sync
> + */
> +static inline void
> +snd_hdac_regmap_sync_node(struct hdac_device *codec, hda_nid_t nid)
> +{
> +	regcache_mark_dirty(codec->regmap);
> +	regcache_sync_region(codec->regmap, nid << 20, ((nid + 1) << 20) -1);
> +}
> +
>   #endif /* __SOUND_HDA_REGMAP_H */
> diff --git a/sound/pci/hda/hda_generic.c b/sound/pci/hda/hda_generic.c
> index f7ccef5559de..1f2ca7be1468 100644
> --- a/sound/pci/hda/hda_generic.c
> +++ b/sound/pci/hda/hda_generic.c
> @@ -842,10 +842,8 @@ static hda_nid_t path_power_update(struct hda_codec *codec,
>   			snd_hda_codec_write(codec, nid, 0,
>   					    AC_VERB_SET_POWER_STATE, state);
>   			changed = nid;
> -			/* here we assume that widget attributes (e.g. amp,
> -			 * pinctl connection) don't change with local power
> -			 * state change.  If not, need to sync the cache.
> -			 */
> +			if (state == AC_PWRST_D0)
> +				snd_hdac_regmap_sync_node(&codec->core, nid);
>   		}
>   	}
>   	return changed;
>

_______________________________________________
Alsa-devel mailing list
Alsa-devel@alsa-project.org
http://mailman.alsa-project.org/mailman/listinfo/alsa-devel

^ permalink raw reply	[flat|nested] 21+ messages in thread

* Re: [PATCH 0/4] More aggressive PM for HD-audio
  2015-03-27  0:11           ` Hui Wang
@ 2015-03-30  6:53             ` hwang4
  2015-04-04 10:31               ` Takashi Iwai
  2015-04-09  6:54               ` hwang4
  0 siblings, 2 replies; 21+ messages in thread
From: hwang4 @ 2015-03-30  6:53 UTC (permalink / raw)
  To: Takashi Iwai; +Cc: alsa-devel, David Henningsson

[-- Attachment #1: Type: text/plain, Size: 6983 bytes --]



On 2015年03月27日 08:11, Hui Wang wrote:
> On 03/26/2015 09:52 PM, Takashi Iwai wrote:
>> At Thu, 26 Mar 2015 14:10:17 +0100,
>> Takashi Iwai wrote:
>>> At Thu, 26 Mar 2015 20:24:43 +0800,
>>> Hui Wang wrote:
>>>> On 03/21/2015 02:38 PM, Hui Wang wrote:
>>>>> On 03/21/2015 12:20 AM, David Henningsson wrote:
>>>>>> On 2015-03-18 09:50, Takashi Iwai wrote:
>>>>>>> Hi,
>>>>>>>
>>>>>>> here is a patchset for supporting more aggressive PM for HD-audio.
>>>>>>> This allows to change the power state of each widget more 
>>>>>>> dynamically
>>>>>>> with jack and stream states.  It's activated only when the codec
>>>>>>> driver (or via sysfs or f/w patch) sets codec->power_mgmt flag.
>>>>>>>
>>>>>>> In theory, this should work for the recent Realtek codecs, but
>>>>>>> currently I have no machine for test.
>>>>>>>
>>>>>>> David, could you or your team check whether this works for 
>>>>>>> ALC282 or
>>>>>>> such?  Just add like:
>>>>>>>
>>>>>>> --- a/sound/pci/hda/patch_realtek.c
>>>>>>> +++ b/sound/pci/hda/patch_realtek.c
>>>>>>> @@ -5415,6 +5415,7 @@ static int patch_alc269(struct hda_codec 
>>>>>>> *codec)
>>>>>>>
>>>>>>>        spec = codec->spec;
>>>>>>>        spec->gen.shared_mic_vref_pin = 0x18;
>>>>>>> +    codec->power_mgmt = 1;
>>>>>>>
>>>>>>>        snd_hda_pick_fixup(codec, alc269_fixup_models,
>>>>>>>                   alc269_fixup_tbl, alc269_fixups);
>>>>>>>
>>>>>>>
>>>>>>> The patchset is for for-next branch of sound git tree, but they 
>>>>>>> might
>>>>>>> be applicable to 4.0-rc (or even older), too.  The current 
>>>>>>> patches are
>>>>>>> found in topic/hda-power branch.
>>>>>> So I hoped to be able to look at this today, but it turns out the
>>>>>> machine I was thinking of using for testing has an ALC262 codec,
>>>>>> which hardly counts as "new".
>>>>>>
>>>>>> Hui, is this something you feel like taking on? Otherwise I'll 
>>>>>> try to
>>>>>> talk to someone in Taipei.
>>>>>>
>>>>> OK, I will look for the machine to do the test next week.
>>>>>
>>>>> Regards,
>>>>> Hui.
>>>>>
>>>> Sorry for late response, today is my first day in the office back from
>>>> vacation, I checked all machines in the Beijing office, none of 
>>>> them has
>>>> the ALC282 codec, I will continue to look for the machine from 
>>>> other office.
>>>>
>>>> And I did the test on the machines with the alc283, alc255, alc292 and
>>>> alc269, the testing result were same, there were no sound output from
>>>> internal speaker or headphone, and the internal mic or external mic
>>>> can't record any sound. The test steps as below:
>>>>
>>>> 1. power_save_node = 0
>>>> checkout the hda-power branch, build the kernel based on this branch.
>>>> Install the kernel to the above machines and boot into the desktop
>>>> test internal speaker and internal mic, works very well, plug a 
>>>> headset,
>>>> test headphone and external mic, works very well.
>>>> run pm_suspend, wait 5 seconds, wakeup the system, redo the above 
>>>> test,
>>>> everything works very well.
>>> OK, this is expected.  The patch shouldn't touch this case.
>>>
>>>> 2. power_save_node = 1
>>>> enable the power_save_node as below:
>>>> @@ -5426,6 +5426,8 @@ static int patch_alc269(struct hda_codec *codec)
>>>>
>>>>           alc_auto_parse_customize_define(codec);
>>>>
>>>> +       codec->power_save_node = 1;
>>>> +
>>>>           if (has_cdefine_beep(codec))
>>>>                   spec->gen.beep_nid = 0x01;
>>>> rebuild the kernel, install the kernel to the above machines and boot
>>>> into the desktop
>>>> test internal speaker and internal mic, we can play sound to internal
>>>> speaker without any errors, but I can't hear any sound from the 
>>>> speaker;
>>>> I can use the internal mic to record without errors, but recorded file
>>>> did not include any sound pcm (maybe all 0x00 or 0xff)
>>>> I plug a headset into the headset jack, the detection works very well,
>>>> but I can't hear sound from headphone when play a sound, and I 
>>>> can't use
>>>> headset mic to record any sound as well.
>>>>
>>>>
>>>> And I attached 2 alsa-info.txt, one is the power_save_node=0, the 
>>>> other
>>>> is the power_save_node=1
>>> Thanks.  The alsa-info.sh outputs show no difference but the power
>>> state, so the widget attributes seem kept with the power state change,
>>> as it seems.
>>>
>>> Could you give alsa-info.sh output *during* playing with
>>> power_save_node=1?
>> Also, try to pull topic/hda-regmap branch in addition, and apply the
>> patch below.  This implements the partial sync for the widget path.
>> Note that the patch is totally untested.
> Got it, I will do the test next Monday, since I can't access those 
> machines until next Monday.
>
> Regards,
> Hui.

The attached alsa-info.txt was generated when the aplay was playing a 
song, it seems the widget power state did not change even the output 
device was working.


And I also checkout the hda-regmap branch and applied the patch below, 
rebuilt the kernel and used the kernel to do the test of playing and 
recording, both internal devices and external devices worked very well, 
I didn't see any obvious problems when using hda-regmap branch doing the 
test.

Regards,
Hui.

>>
>> thanks,
>>
>> Takashi
>>
>> diff --git a/include/sound/hda_regmap.h b/include/sound/hda_regmap.h
>> index 76648ccfbbf8..727a5801e298 100644
>> --- a/include/sound/hda_regmap.h
>> +++ b/include/sound/hda_regmap.h
>> @@ -202,4 +202,16 @@ snd_hdac_regmap_update_amp_stereo(struct 
>> hdac_device *codec, hda_nid_t nid,
>>       return snd_hdac_regmap_update_raw(codec, cmd, mask, val);
>>   }
>>   +/**
>> + * snd_hdac_regmap_sync_node - sync the widget node attributes
>> + * @codec: HD-audio codec
>> + * @nid: NID to sync
>> + */
>> +static inline void
>> +snd_hdac_regmap_sync_node(struct hdac_device *codec, hda_nid_t nid)
>> +{
>> +    regcache_mark_dirty(codec->regmap);
>> +    regcache_sync_region(codec->regmap, nid << 20, ((nid + 1) << 20) 
>> -1);
>> +}
>> +
>>   #endif /* __SOUND_HDA_REGMAP_H */
>> diff --git a/sound/pci/hda/hda_generic.c b/sound/pci/hda/hda_generic.c
>> index f7ccef5559de..1f2ca7be1468 100644
>> --- a/sound/pci/hda/hda_generic.c
>> +++ b/sound/pci/hda/hda_generic.c
>> @@ -842,10 +842,8 @@ static hda_nid_t path_power_update(struct 
>> hda_codec *codec,
>>               snd_hda_codec_write(codec, nid, 0,
>>                           AC_VERB_SET_POWER_STATE, state);
>>               changed = nid;
>> -            /* here we assume that widget attributes (e.g. amp,
>> -             * pinctl connection) don't change with local power
>> -             * state change.  If not, need to sync the cache.
>> -             */
>> +            if (state == AC_PWRST_D0)
>> +                snd_hdac_regmap_sync_node(&codec->core, nid);
>>           }
>>       }
>>       return changed;
>>
>


[-- Attachment #2: alsa-info.txt-power-save-node=1-playing --]
[-- Type: text/plain, Size: 38025 bytes --]

upload=true&script=true&cardinfo=
!!################################
!!ALSA Information Script v 0.4.64
!!################################

!!Script ran on: Mon Mar 30 04:19:13 UTC 2015


!!Linux Distribution
!!------------------

Ubuntu Vivid Vervet (development branch) \n \l DISTRIB_ID=Ubuntu DISTRIB_DESCRIPTION="Ubuntu Vivid Vervet (development branch)" NAME="Ubuntu" ID=ubuntu ID_LIKE=debian PRETTY_NAME="Ubuntu Vivid Vervet (development branch)" HOME_URL="http://www.ubuntu.com/" SUPPORT_URL="http://help.ubuntu.com/" BUG_REPORT_URL="http://bugs.launchpad.net/ubuntu/"


!!DMI Information
!!---------------

Manufacturer:      Dell Inc.
Product Name:      Inspiron 7447
Product Version:   Not Specified
Firmware Version:  X18


!!Kernel Information
!!------------------

Kernel release:    4.0.0-rc4+
Operating System:  GNU/Linux
Architecture:      x86_64
Processor:         x86_64
SMP Enabled:       Yes


!!ALSA Version
!!------------

Driver version:     k4.0.0-rc4+
Library version:    1.0.28
Utilities version:  1.0.28


!!Loaded ALSA modules
!!-------------------



!!Sound Servers on this system
!!----------------------------

Pulseaudio:
      Installed - Yes (/usr/bin/pulseaudio)
      Running - Yes


!!Soundcards recognised by ALSA
!!-----------------------------

 0 [HDMI           ]: HDA-Intel - HDA Intel HDMI
                      HDA Intel HDMI at 0xf7a1c000 irq 32
 1 [PCH            ]: HDA-Intel - HDA Intel PCH
                      HDA Intel PCH at 0xf7a18000 irq 31


!!PCI Soundcards installed in the system
!!--------------------------------------

00:03.0 Audio device: Intel Corporation Xeon E3-1200 v3/4th Gen Core Processor HD Audio Controller (rev 06)
00:1b.0 Audio device: Intel Corporation 8 Series/C220 Series Chipset High Definition Audio Controller (rev 05)


!!Advanced information - PCI Vendor/Device/Subsystem ID's
!!-------------------------------------------------------

00:03.0 0403: 8086:0c0c (rev 06)
	Subsystem: 1028:0680
--
00:1b.0 0403: 8086:8c20 (rev 05)
	Subsystem: 1028:0680


!!Modprobe options (Sound related)
!!--------------------------------

snd_atiixp_modem: index=-2
snd_intel8x0m: index=-2
snd_via82xx_modem: index=-2
snd_usb_audio: index=-2
snd_usb_caiaq: index=-2
snd_usb_ua101: index=-2
snd_usb_us122l: index=-2
snd_usb_usx2y: index=-2
snd_cmipci: mpu_port=0x330 fm_port=0x388
snd_pcsp: index=-2
snd_usb_audio: index=-2


!!Loaded sound module options
!!---------------------------


!!HDA-Intel Codec information
!!---------------------------
--startcollapse--

Codec: Intel Haswell HDMI
Address: 0
AFG Function Id: 0x1 (unsol 0)
Vendor Id: 0x80862807
Subsystem Id: 0x80860101
Revision Id: 0x100000
No Modem Function Group found
Default PCM:
    rates [0x0]:
    bits [0x0]:
    formats [0x0]:
Default Amp-In caps: N/A
Default Amp-Out caps: N/A
State of AFG node 0x01:
  Power states:  D0 D3 CLKSTOP EPSS
  Power: setting=D0, actual=D0, Clock-stop-OK
GPIO: io=0, o=0, i=0, unsolicited=0, wake=0
Node 0x02 [Audio Output] wcaps 0x6611: 8-Channels Digital
  Converter: stream=1, channel=0
  Digital: Enabled KAE
  Digital category: 0x0
  IEC Coding Type: 0x0
  PCM:
    rates [0x7f0]: 32000 44100 48000 88200 96000 176400 192000
    bits [0x1e]: 16 20 24 32
    formats [0x5]: PCM AC3
  Power states:  D0 D3 EPSS
  Power: setting=D0, actual=D0
Node 0x03 [Audio Output] wcaps 0x6611: 8-Channels Digital
  Converter: stream=0, channel=0
  Digital: Enabled KAE
  Digital category: 0x0
  IEC Coding Type: 0x0
  PCM:
    rates [0x7f0]: 32000 44100 48000 88200 96000 176400 192000
    bits [0x1e]: 16 20 24 32
    formats [0x5]: PCM AC3
  Power states:  D0 D3 EPSS
  Power: setting=D0, actual=D0
Node 0x04 [Audio Output] wcaps 0x6611: 8-Channels Digital
  Converter: stream=0, channel=0
  Digital: Enabled KAE
  Digital category: 0x0
  IEC Coding Type: 0x0
  PCM:
    rates [0x7f0]: 32000 44100 48000 88200 96000 176400 192000
    bits [0x1e]: 16 20 24 32
    formats [0x5]: PCM AC3
  Power states:  D0 D3 EPSS
  Power: setting=D0, actual=D0
Node 0x05 [Pin Complex] wcaps 0x40778d: 8-Channels Digital Amp-Out CP
  Control: name="HDMI/DP,pcm=3 Jack", index=0, device=0
  Control: name="IEC958 Playback Con Mask", index=0, device=0
  Control: name="IEC958 Playback Pro Mask", index=0, device=0
  Control: name="IEC958 Playback Default", index=0, device=0
  Control: name="IEC958 Playback Switch", index=0, device=0
  Control: name="ELD", index=0, device=3
  Amp-Out caps: ofs=0x00, nsteps=0x00, stepsize=0x00, mute=1
  Amp-Out vals:  [0x00 0x00]
  Pincap 0x0b000094: OUT Detect HBR HDMI DP
  Pin Default 0x18560010: [Jack] Digital Out at Int HDMI
    Conn = Digital, Color = Unknown
    DefAssociation = 0x1, Sequence = 0x0
  Pin-ctls: 0x00:
  Unsolicited: tag=01, enabled=1
  Power states:  D0 D3 EPSS
  Power: setting=D0, actual=D0
  Devices: 0
  Connection: 0
  In-driver Connection: 3
     0x02 0x03 0x04
Node 0x06 [Pin Complex] wcaps 0x40778d: 8-Channels Digital Amp-Out CP
  Control: name="HDMI/DP,pcm=7 Jack", index=0, device=0
  Control: name="IEC958 Playback Con Mask", index=1, device=0
  Control: name="IEC958 Playback Pro Mask", index=1, device=0
  Control: name="IEC958 Playback Default", index=1, device=0
  Control: name="IEC958 Playback Switch", index=1, device=0
  Control: name="ELD", index=0, device=7
  Amp-Out caps: ofs=0x00, nsteps=0x00, stepsize=0x00, mute=1
  Amp-Out vals:  [0x00 0x00]
  Pincap 0x0b000094: OUT Detect HBR HDMI DP
  Pin Default 0x18560020: [Jack] Digital Out at Int HDMI
    Conn = Digital, Color = Unknown
    DefAssociation = 0x2, Sequence = 0x0
  Pin-ctls: 0x00:
  Unsolicited: tag=02, enabled=1
  Power states:  D0 D3 EPSS
  Power: setting=D0, actual=D0
  Devices: 0
  Connection: 0
  In-driver Connection: 3
     0x02 0x03 0x04
Node 0x07 [Pin Complex] wcaps 0x40778d: 8-Channels Digital Amp-Out CP
  Control: name="HDMI/DP,pcm=8 Jack", index=0, device=0
  Control: name="IEC958 Playback Con Mask", index=2, device=0
  Control: name="IEC958 Playback Pro Mask", index=2, device=0
  Control: name="IEC958 Playback Default", index=2, device=0
  Control: name="IEC958 Playback Switch", index=2, device=0
  Control: name="ELD", index=0, device=8
  Amp-Out caps: ofs=0x00, nsteps=0x00, stepsize=0x00, mute=1
  Amp-Out vals:  [0x00 0x00]
  Pincap 0x0b000094: OUT Detect HBR HDMI DP
  Pin Default 0x18560030: [Jack] Digital Out at Int HDMI
    Conn = Digital, Color = Unknown
    DefAssociation = 0x3, Sequence = 0x0
  Pin-ctls: 0x00:
  Unsolicited: tag=03, enabled=1
  Power states:  D0 D3 EPSS
  Power: setting=D0, actual=D0
  Devices: 0
  Connection: 0
  In-driver Connection: 3
     0x02 0x03 0x04
Node 0x08 [Vendor Defined Widget] wcaps 0xf00000: Mono
Codec: Realtek ALC3234
Address: 0
AFG Function Id: 0x1 (unsol 1)
Vendor Id: 0x10ec0255
Subsystem Id: 0x10280680
Revision Id: 0x100002
No Modem Function Group found
Default PCM:
    rates [0x560]: 44100 48000 96000 192000
    bits [0xe]: 16 20 24
    formats [0x1]: PCM
Default Amp-In caps: N/A
Default Amp-Out caps: N/A
State of AFG node 0x01:
  Power states:  D0 D1 D2 D3 D3cold CLKSTOP EPSS
  Power: setting=D0, actual=D0
GPIO: io=3, o=0, i=0, unsolicited=1, wake=0
  IO[0]: enable=0, dir=0, wake=0, sticky=0, data=0, unsol=0
  IO[1]: enable=0, dir=0, wake=0, sticky=0, data=0, unsol=0
  IO[2]: enable=0, dir=0, wake=0, sticky=0, data=0, unsol=0
Node 0x02 [Audio Output] wcaps 0x41d: Stereo Amp-Out
  Control: name="Front Playback Volume", index=0, device=0
    ControlAmp: chs=3, dir=Out, idx=0, ofs=0
  Device: name="ALC3234 Analog", type="Audio", device=0
  Amp-Out caps: ofs=0x57, nsteps=0x57, stepsize=0x02, mute=0
  Amp-Out vals:  [0x46 0x46]
  Converter: stream=8, channel=0
  PCM:
    rates [0x60]: 44100 48000
    bits [0xe]: 16 20 24
    formats [0x1]: PCM
  Power states:  D0 D1 D2 D3 EPSS
  Power: setting=D3, actual=D3
Node 0x03 [Audio Output] wcaps 0x41d: Stereo Amp-Out
  Control: name="Bass Speaker Playback Volume", index=0, device=0
    ControlAmp: chs=3, dir=Out, idx=0, ofs=0
  Amp-Out caps: ofs=0x57, nsteps=0x57, stepsize=0x02, mute=0
  Amp-Out vals:  [0x46 0x46]
  Converter: stream=8, channel=2
  PCM:
    rates [0x60]: 44100 48000
    bits [0xe]: 16 20 24
    formats [0x1]: PCM
  Power states:  D0 D1 D2 D3 EPSS
  Power: setting=D3, actual=D3
Node 0x04 [Vendor Defined Widget] wcaps 0xf00000: Mono
Node 0x05 [Vendor Defined Widget] wcaps 0xf00000: Mono
Node 0x06 [Audio Output] wcaps 0x611: Stereo Digital
  Converter: stream=0, channel=0
  Digital:
  Digital category: 0x0
  IEC Coding Type: 0x0
  PCM:
    rates [0x5e0]: 44100 48000 88200 96000 192000
    bits [0xe]: 16 20 24
    formats [0x1]: PCM
  Power states:  D0 D1 D2 D3 EPSS
  Power: setting=D3, actual=D3
Node 0x07 [Vendor Defined Widget] wcaps 0xf00000: Mono
Node 0x08 [Audio Input] wcaps 0x10051b: Stereo Amp-In
  Control: name="Capture Volume", index=0, device=0
    ControlAmp: chs=3, dir=In, idx=0, ofs=0
  Control: name="Capture Switch", index=0, device=0
    ControlAmp: chs=3, dir=In, idx=0, ofs=0
  Device: name="ALC3234 Analog", type="Audio", device=0
  Amp-In caps: ofs=0x17, nsteps=0x3f, stepsize=0x02, mute=1
  Amp-In vals:  [0x26 0x26]
  Converter: stream=4, channel=0
  SDI-Select: 0
  PCM:
    rates [0x560]: 44100 48000 96000 192000
    bits [0xe]: 16 20 24
    formats [0x1]: PCM
  Power states:  D0 D1 D2 D3 EPSS
  Power: setting=D3, actual=D3
  Connection: 1
     0x23
Node 0x09 [Audio Input] wcaps 0x10051b: Stereo Amp-In
  Amp-In caps: ofs=0x17, nsteps=0x3f, stepsize=0x02, mute=1
  Amp-In vals:  [0x97 0x97]
  Converter: stream=0, channel=0
  SDI-Select: 0
  PCM:
    rates [0x560]: 44100 48000 96000 192000
    bits [0xe]: 16 20 24
    formats [0x1]: PCM
  Power states:  D0 D1 D2 D3 EPSS
  Power: setting=D3, actual=D3
  Connection: 1
     0x22
Node 0x0a [Vendor Defined Widget] wcaps 0xf00000: Mono
Node 0x0b [Audio Mixer] wcaps 0x20010b: Stereo Amp-In
  Control: name="Headset Mic Playback Volume", index=0, device=0
    ControlAmp: chs=3, dir=In, idx=1, ofs=0
  Control: name="Headset Mic Playback Switch", index=0, device=0
    ControlAmp: chs=3, dir=In, idx=1, ofs=0
  Control: name="Headphone Mic Playback Volume", index=0, device=0
    ControlAmp: chs=3, dir=In, idx=2, ofs=0
  Control: name="Headphone Mic Playback Switch", index=0, device=0
    ControlAmp: chs=3, dir=In, idx=2, ofs=0
  Control: name="Beep Playback Volume", index=0, device=0
    ControlAmp: chs=3, dir=In, idx=4, ofs=0
  Control: name="Beep Playback Switch", index=0, device=0
    ControlAmp: chs=3, dir=In, idx=4, ofs=0
  Amp-In caps: ofs=0x17, nsteps=0x1f, stepsize=0x05, mute=1
  Amp-In vals:  [0x80 0x80] [0x80 0x80] [0x80 0x80] [0x80 0x80] [0x80 0x80]
  Connection: 5
     0x18 0x19 0x1a 0x1b 0x1d
Node 0x0c [Audio Mixer] wcaps 0x20010b: Stereo Amp-In
  Amp-In caps: ofs=0x00, nsteps=0x00, stepsize=0x00, mute=1
  Amp-In vals:  [0x00 0x00] [0x00 0x00]
  Connection: 2
     0x02 0x0b
Node 0x0d [Audio Mixer] wcaps 0x20010b: Stereo Amp-In
  Amp-In caps: ofs=0x00, nsteps=0x00, stepsize=0x00, mute=1
  Amp-In vals:  [0x00 0x00] [0x00 0x00]
  Connection: 2
     0x03 0x0b
Node 0x0e [Vendor Defined Widget] wcaps 0xf00000: Mono
Node 0x0f [Audio Mixer] wcaps 0x20010a: Mono Amp-In
  Amp-In caps: ofs=0x00, nsteps=0x00, stepsize=0x00, mute=1
  Amp-In vals:  [0x00 0x00]
  Connection: 1
     0x0d
Node 0x10 [Vendor Defined Widget] wcaps 0xf00000: Mono
Node 0x11 [Vendor Defined Widget] wcaps 0xf00000: Mono
Node 0x12 [Pin Complex] wcaps 0x40040b: Stereo Amp-In
  Control: name="Internal Mic Boost Volume", index=0, device=0
    ControlAmp: chs=3, dir=In, idx=0, ofs=0
  Control: name="Internal Mic Phantom Jack", index=0, device=0
  Amp-In caps: ofs=0x00, nsteps=0x03, stepsize=0x27, mute=0
  Amp-In vals:  [0x00 0x00]
  Pincap 0x00000020: IN
  Pin Default 0x90a60160: [Fixed] Mic at Int N/A
    Conn = Digital, Color = Unknown
    DefAssociation = 0x6, Sequence = 0x0
    Misc = NO_PRESENCE
  Pin-ctls: 0x20: IN
  Power states:  D0 D1 D2 D3 EPSS
  Power: setting=D3, actual=D3
Node 0x13 [Vendor Defined Widget] wcaps 0xf00000: Mono
Node 0x14 [Pin Complex] wcaps 0x40058d: Stereo Amp-Out
  Control: name="Speaker Playback Switch", index=0, device=0
    ControlAmp: chs=3, dir=Out, idx=0, ofs=0
  Control: name="Speaker Front Phantom Jack", index=0, device=0
  Amp-Out caps: ofs=0x00, nsteps=0x00, stepsize=0x00, mute=1
  Amp-Out vals:  [0x00 0x00]
  Pincap 0x00010014: OUT EAPD Detect
  EAPD 0x2: EAPD
  Pin Default 0x90170120: [Fixed] Speaker at Int N/A
    Conn = Analog, Color = Unknown
    DefAssociation = 0x2, Sequence = 0x0
    Misc = NO_PRESENCE
  Pin-ctls: 0x40: OUT
  Unsolicited: tag=00, enabled=0
  Power states:  D0 D1 D2 D3 EPSS
  Power: setting=D3, actual=D3
  Connection: 1
     0x0c
Node 0x15 [Vendor Defined Widget] wcaps 0xf00000: Mono
Node 0x16 [Vendor Defined Widget] wcaps 0xf00000: Mono
Node 0x17 [Pin Complex] wcaps 0x40050c: Mono Amp-Out
  Control: name="Bass Speaker Playback Switch", index=0, device=0
    ControlAmp: chs=1, dir=Out, idx=0, ofs=0
  Control: name="Speaker Surround Phantom Jack", index=0, device=0
  Amp-Out caps: ofs=0x00, nsteps=0x00, stepsize=0x00, mute=1
  Amp-Out vals:  [0x00]
  Pincap 0x00000010: OUT
  Pin Default 0x90170140: [Fixed] Speaker at Int N/A
    Conn = Analog, Color = Unknown
    DefAssociation = 0x4, Sequence = 0x0
    Misc = NO_PRESENCE
  Pin-ctls: 0x40: OUT
  Power states:  D0 D1 D2 D3 EPSS
  Power: setting=D3, actual=D3
  Connection: 1
     0x0f
Node 0x18 [Pin Complex] wcaps 0x40048b: Stereo Amp-In
  Amp-In caps: ofs=0x00, nsteps=0x03, stepsize=0x27, mute=0
  Amp-In vals:  [0x00 0x00]
  Pincap 0x00003724: IN Detect
    Vref caps: HIZ 50 GRD 80 100
  Pin Default 0x40000000: [N/A] Line Out at Ext N/A
    Conn = Unknown, Color = Unknown
    DefAssociation = 0x0, Sequence = 0x0
  Pin-ctls: 0x20: IN VREF_HIZ
  Unsolicited: tag=00, enabled=0
  Power states:  D0 D1 D2 D3 EPSS
  Power: setting=D3, actual=D3
Node 0x19 [Pin Complex] wcaps 0x40048b: Stereo Amp-In
  Control: name="Headset Mic Boost Volume", index=0, device=0
    ControlAmp: chs=3, dir=In, idx=0, ofs=0
  Control: name="Headset Mic Phantom Jack", index=0, device=0
  Amp-In caps: ofs=0x00, nsteps=0x03, stepsize=0x27, mute=0
  Amp-In vals:  [0x00 0x00]
  Pincap 0x00003724: IN Detect
    Vref caps: HIZ 50 GRD 80 100
  Pin Default 0x411111f0: [N/A] Speaker at Ext Rear
    Conn = 1/8, Color = Black
    DefAssociation = 0xf, Sequence = 0x0
    Misc = NO_PRESENCE
  Pin-ctls: 0x24: IN VREF_80
  Unsolicited: tag=00, enabled=0
  Power states:  D0 D1 D2 D3 EPSS
  Power: setting=D0, actual=D0
Node 0x1a [Pin Complex] wcaps 0x40048b: Stereo Amp-In
  Control: name="Headphone Mic Boost Volume", index=0, device=0
    ControlAmp: chs=3, dir=In, idx=0, ofs=0
  Amp-In caps: ofs=0x00, nsteps=0x03, stepsize=0x27, mute=0
  Amp-In vals:  [0x00 0x00]
  Pincap 0x00003724: IN Detect
    Vref caps: HIZ 50 GRD 80 100
  Pin Default 0x411111f0: [N/A] Speaker at Ext Rear
    Conn = 1/8, Color = Black
    DefAssociation = 0xf, Sequence = 0x0
    Misc = NO_PRESENCE
  Pin-ctls: 0x20: IN VREF_HIZ
  Unsolicited: tag=00, enabled=0
  Power states:  D0 D1 D2 D3 EPSS
  Power: setting=D0, actual=D0
Node 0x1b [Pin Complex] wcaps 0x40058f: Stereo Amp-In Amp-Out
  Amp-In caps: ofs=0x00, nsteps=0x03, stepsize=0x27, mute=0
  Amp-In vals:  [0x00 0x00]
  Amp-Out caps: ofs=0x00, nsteps=0x00, stepsize=0x00, mute=1
  Amp-Out vals:  [0x80 0x80]
  Pincap 0x0001373c: IN OUT HP EAPD Detect
    Vref caps: HIZ 50 GRD 80 100
  EAPD 0x2: EAPD
  Pin Default 0x411111f0: [N/A] Speaker at Ext Rear
    Conn = 1/8, Color = Black
    DefAssociation = 0xf, Sequence = 0x0
    Misc = NO_PRESENCE
  Pin-ctls: 0x20: IN VREF_HIZ
  Unsolicited: tag=00, enabled=0
  Power states:  D0 D1 D2 D3 EPSS
  Power: setting=D3, actual=D3
  Connection: 2
     0x0c* 0x0d
Node 0x1c [Vendor Defined Widget] wcaps 0xf00000: Mono
Node 0x1d [Pin Complex] wcaps 0x400400: Mono
  Pincap 0x00000020: IN
  Pin Default 0x41163b05: [N/A] Speaker at Ext Rear
    Conn = Digital, Color = Blue
    DefAssociation = 0x0, Sequence = 0x5
    Misc = NO_PRESENCE
  Pin-ctls: 0x20: IN
  Power states:  D0 D1 D2 D3 EPSS
  Power: setting=D3, actual=D3
Node 0x1e [Pin Complex] wcaps 0x400781: Stereo Digital
  Pincap 0x00000014: OUT Detect
  Pin Default 0x411111f0: [N/A] Speaker at Ext Rear
    Conn = 1/8, Color = Black
    DefAssociation = 0xf, Sequence = 0x0
    Misc = NO_PRESENCE
  Pin-ctls: 0x40: OUT
  Unsolicited: tag=00, enabled=0
  Power states:  D0 D1 D2 D3 EPSS
  Power: setting=D3, actual=D3
  Connection: 1
     0x06
Node 0x1f [Vendor Defined Widget] wcaps 0xf00000: Mono
Node 0x20 [Vendor Defined Widget] wcaps 0xf00040: Mono
  Processing caps: benign=0, ncoeff=76
Node 0x21 [Pin Complex] wcaps 0x40058d: Stereo Amp-Out
  Control: name="Headphone Playback Switch", index=0, device=0
    ControlAmp: chs=3, dir=Out, idx=0, ofs=0
  Control: name="Headphone Mic Jack", index=0, device=0
  Amp-Out caps: ofs=0x00, nsteps=0x00, stepsize=0x00, mute=1
  Amp-Out vals:  [0x80 0x80]
  Pincap 0x0001001c: OUT HP EAPD Detect
  EAPD 0x2: EAPD
  Pin Default 0x0321102f: [Jack] HP Out at Ext Left
    Conn = 1/8, Color = Black
    DefAssociation = 0x2, Sequence = 0xf
  Pin-ctls: 0xc0: OUT HP
  Unsolicited: tag=01, enabled=1
  Power states:  D0 D1 D2 D3 EPSS
  Power: setting=D3, actual=D3
  Connection: 2
     0x0c* 0x0d
Node 0x22 [Audio Mixer] wcaps 0x20010b: Stereo Amp-In
  Amp-In caps: ofs=0x00, nsteps=0x00, stepsize=0x00, mute=1
  Amp-In vals:  [0x80 0x80] [0x80 0x80] [0x80 0x80] [0x80 0x80] [0x80 0x80] [0x80 0x80]
  Connection: 6
     0x18 0x19 0x1a 0x1b 0x1d 0x0b
Node 0x23 [Audio Mixer] wcaps 0x20010b: Stereo Amp-In
  Amp-In caps: ofs=0x00, nsteps=0x00, stepsize=0x00, mute=1
  Amp-In vals:  [0x80 0x80] [0x80 0x80] [0x80 0x80] [0x80 0x80] [0x80 0x80] [0x80 0x80] [0x00 0x00]
  Connection: 7
     0x18 0x19 0x1a 0x1b 0x1d 0x0b 0x12
--endcollapse--


!!ALSA Device nodes
!!-----------------

crw-rw----+ 1 root audio 116,  2 Mar 30 12:17 /dev/snd/controlC0
crw-rw----+ 1 root audio 116,  7 Mar 30 12:17 /dev/snd/controlC1
crw-rw----+ 1 root audio 116,  6 Mar 30 12:17 /dev/snd/hwC0D0
crw-rw----+ 1 root audio 116, 10 Mar 30 12:17 /dev/snd/hwC1D0
crw-rw----+ 1 root audio 116,  3 Mar 30 12:17 /dev/snd/pcmC0D3p
crw-rw----+ 1 root audio 116,  4 Mar 30 12:17 /dev/snd/pcmC0D7p
crw-rw----+ 1 root audio 116,  5 Mar 30 12:17 /dev/snd/pcmC0D8p
crw-rw----+ 1 root audio 116,  9 Mar 30 12:17 /dev/snd/pcmC1D0c
crw-rw----+ 1 root audio 116,  8 Mar 30 12:19 /dev/snd/pcmC1D0p
crw-rw----+ 1 root audio 116, 33 Mar 30 12:17 /dev/snd/timer

/dev/snd/by-path:
total 0
drwxr-xr-x 2 root root  80 Mar 30 12:17 .
drwxr-xr-x 3 root root 260 Mar 30 12:17 ..
lrwxrwxrwx 1 root root  12 Mar 30 12:17 pci-0000:00:03.0 -> ../controlC0
lrwxrwxrwx 1 root root  12 Mar 30 12:17 pci-0000:00:1b.0 -> ../controlC1


!!Aplay/Arecord output
!!--------------------

APLAY

**** List of PLAYBACK Hardware Devices ****
card 0: HDMI [HDA Intel HDMI], device 3: HDMI 0 [HDMI 0]
  Subdevices: 1/1
  Subdevice #0: subdevice #0
card 0: HDMI [HDA Intel HDMI], device 7: HDMI 1 [HDMI 1]
  Subdevices: 1/1
  Subdevice #0: subdevice #0
card 0: HDMI [HDA Intel HDMI], device 8: HDMI 2 [HDMI 2]
  Subdevices: 1/1
  Subdevice #0: subdevice #0
card 1: PCH [HDA Intel PCH], device 0: ALC3234 Analog [ALC3234 Analog]
  Subdevices: 0/1
  Subdevice #0: subdevice #0

ARECORD

**** List of CAPTURE Hardware Devices ****
card 1: PCH [HDA Intel PCH], device 0: ALC3234 Analog [ALC3234 Analog]
  Subdevices: 1/1
  Subdevice #0: subdevice #0

!!Amixer output
!!-------------

!!-------Mixer controls for card 0 [HDMI]

Card hw:0 'HDMI'/'HDA Intel HDMI at 0xf7a1c000 irq 32'
  Mixer name	: 'Intel Haswell HDMI'
  Components	: 'HDA:80862807,80860101,00100000'
  Controls      : 21
  Simple ctrls  : 3
Simple mixer control 'IEC958',0
  Capabilities: pswitch pswitch-joined
  Playback channels: Mono
  Mono: Playback [on]
Simple mixer control 'IEC958',1
  Capabilities: pswitch pswitch-joined
  Playback channels: Mono
  Mono: Playback [on]
Simple mixer control 'IEC958',2
  Capabilities: pswitch pswitch-joined
  Playback channels: Mono
  Mono: Playback [on]

!!-------Mixer controls for card 1 [PCH]

Card hw:1 'PCH'/'HDA Intel PCH at 0xf7a18000 irq 31'
  Mixer name	: 'Realtek ALC3234'
  Components	: 'HDA:10ec0255,10280680,00100002'
  Controls      : 28
  Simple ctrls  : 15
Simple mixer control 'Master',0
  Capabilities: pvolume pvolume-joined pswitch pswitch-joined
  Playback channels: Mono
  Limits: Playback 0 - 87
  Mono: Playback 70 [80%] [-12.75dB] [on]
Simple mixer control 'Headphone',0
  Capabilities: pswitch
  Playback channels: Front Left - Front Right
  Mono:
  Front Left: Playback [off]
  Front Right: Playback [off]
Simple mixer control 'Headphone Mic',0
  Capabilities: pvolume pswitch cswitch cswitch-joined cswitch-exclusive
  Capture exclusive group: 0
  Playback channels: Front Left - Front Right
  Capture channels: Mono
  Limits: Playback 0 - 31
  Mono: Capture [off]
  Front Left: Playback 0 [0%] [-34.50dB] [off]
  Front Right: Playback 0 [0%] [-34.50dB] [off]
Simple mixer control 'Headphone Mic Boost',0
  Capabilities: volume
  Playback channels: Front Left - Front Right
  Capture channels: Front Left - Front Right
  Limits: 0 - 3
  Front Left: 0 [0%] [0.00dB]
  Front Right: 0 [0%] [0.00dB]
Simple mixer control 'Speaker',0
  Capabilities: pswitch
  Playback channels: Front Left - Front Right
  Mono:
  Front Left: Playback [on]
  Front Right: Playback [on]
Simple mixer control 'Bass Speaker',0
  Capabilities: pvolume pswitch pswitch-joined
  Playback channels: Front Left - Front Right
  Limits: Playback 0 - 87
  Mono:
  Front Left: Playback 87 [100%] [0.00dB] [on]
  Front Right: Playback 87 [100%] [0.00dB] [on]
Simple mixer control 'PCM',0
  Capabilities: pvolume
  Playback channels: Front Left - Front Right
  Limits: Playback 0 - 255
  Mono:
  Front Left: Playback 254 [100%] [-0.20dB]
  Front Right: Playback 254 [100%] [-0.20dB]
Simple mixer control 'Front',0
  Capabilities: pvolume
  Playback channels: Front Left - Front Right
  Limits: Playback 0 - 87
  Mono:
  Front Left: Playback 87 [100%] [0.00dB]
  Front Right: Playback 87 [100%] [0.00dB]
Simple mixer control 'Beep',0
  Capabilities: pvolume pswitch
  Playback channels: Front Left - Front Right
  Limits: Playback 0 - 31
  Mono:
  Front Left: Playback 0 [0%] [-34.50dB] [off]
  Front Right: Playback 0 [0%] [-34.50dB] [off]
Simple mixer control 'Capture',0
  Capabilities: cvolume cswitch
  Capture channels: Front Left - Front Right
  Limits: Capture 0 - 63
  Front Left: Capture 38 [60%] [11.25dB] [on]
  Front Right: Capture 38 [60%] [11.25dB] [on]
Simple mixer control 'Auto-Mute Mode',0
  Capabilities: enum
  Items: 'Disabled' 'Enabled'
  Item0: 'Disabled'
Simple mixer control 'Headset Mic',0
  Capabilities: pvolume pswitch cswitch cswitch-joined cswitch-exclusive
  Capture exclusive group: 0
  Playback channels: Front Left - Front Right
  Capture channels: Mono
  Limits: Playback 0 - 31
  Mono: Capture [off]
  Front Left: Playback 0 [0%] [-34.50dB] [off]
  Front Right: Playback 0 [0%] [-34.50dB] [off]
Simple mixer control 'Headset Mic Boost',0
  Capabilities: volume
  Playback channels: Front Left - Front Right
  Capture channels: Front Left - Front Right
  Limits: 0 - 3
  Front Left: 0 [0%] [0.00dB]
  Front Right: 0 [0%] [0.00dB]
Simple mixer control 'Internal Mic',0
  Capabilities: cswitch cswitch-joined cswitch-exclusive
  Capture exclusive group: 0
  Capture channels: Mono
  Mono: Capture [on]
Simple mixer control 'Internal Mic Boost',0
  Capabilities: volume
  Playback channels: Front Left - Front Right
  Capture channels: Front Left - Front Right
  Limits: 0 - 3
  Front Left: 0 [0%] [0.00dB]
  Front Right: 0 [0%] [0.00dB]


!!Alsactl output
!!--------------

--startcollapse--
state.HDMI {
	control.1 {
		iface CARD
		name 'HDMI/DP,pcm=3 Jack'
		value false
		comment {
			access read
			type BOOLEAN
			count 1
		}
	}
	control.2 {
		iface MIXER
		name 'IEC958 Playback Con Mask'
		value '0fff000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000'
		comment {
			access read
			type IEC958
			count 1
		}
	}
	control.3 {
		iface MIXER
		name 'IEC958 Playback Pro Mask'
		value '0f00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000'
		comment {
			access read
			type IEC958
			count 1
		}
	}
	control.4 {
		iface MIXER
		name 'IEC958 Playback Default'
		value '0400000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000'
		comment {
			access 'read write'
			type IEC958
			count 1
		}
	}
	control.5 {
		iface MIXER
		name 'IEC958 Playback Switch'
		value true
		comment {
			access 'read write'
			type BOOLEAN
			count 1
		}
	}
	control.6 {
		iface PCM
		device 3
		name ELD
		value ''
		comment {
			access 'read volatile'
			type BYTES
			count 0
		}
	}
	control.7 {
		iface CARD
		name 'HDMI/DP,pcm=7 Jack'
		value false
		comment {
			access read
			type BOOLEAN
			count 1
		}
	}
	control.8 {
		iface MIXER
		name 'IEC958 Playback Con Mask'
		index 1
		value '0fff000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000'
		comment {
			access read
			type IEC958
			count 1
		}
	}
	control.9 {
		iface MIXER
		name 'IEC958 Playback Pro Mask'
		index 1
		value '0f00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000'
		comment {
			access read
			type IEC958
			count 1
		}
	}
	control.10 {
		iface MIXER
		name 'IEC958 Playback Default'
		index 1
		value '0400000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000'
		comment {
			access 'read write'
			type IEC958
			count 1
		}
	}
	control.11 {
		iface MIXER
		name 'IEC958 Playback Switch'
		index 1
		value true
		comment {
			access 'read write'
			type BOOLEAN
			count 1
		}
	}
	control.12 {
		iface PCM
		device 7
		name ELD
		value ''
		comment {
			access 'read volatile'
			type BYTES
			count 0
		}
	}
	control.13 {
		iface CARD
		name 'HDMI/DP,pcm=8 Jack'
		value false
		comment {
			access read
			type BOOLEAN
			count 1
		}
	}
	control.14 {
		iface MIXER
		name 'IEC958 Playback Con Mask'
		index 2
		value '0fff000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000'
		comment {
			access read
			type IEC958
			count 1
		}
	}
	control.15 {
		iface MIXER
		name 'IEC958 Playback Pro Mask'
		index 2
		value '0f00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000'
		comment {
			access read
			type IEC958
			count 1
		}
	}
	control.16 {
		iface MIXER
		name 'IEC958 Playback Default'
		index 2
		value '0400000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000'
		comment {
			access 'read write'
			type IEC958
			count 1
		}
	}
	control.17 {
		iface MIXER
		name 'IEC958 Playback Switch'
		index 2
		value true
		comment {
			access 'read write'
			type BOOLEAN
			count 1
		}
	}
	control.18 {
		iface PCM
		device 8
		name ELD
		value ''
		comment {
			access 'read volatile'
			type BYTES
			count 0
		}
	}
	control.19 {
		iface PCM
		device 3
		name 'Playback Channel Map'
		value.0 0
		value.1 0
		value.2 0
		value.3 0
		value.4 0
		value.5 0
		value.6 0
		value.7 0
		comment {
			access 'read write'
			type INTEGER
			count 8
			range '0 - 36'
		}
	}
	control.20 {
		iface PCM
		device 7
		name 'Playback Channel Map'
		value.0 0
		value.1 0
		value.2 0
		value.3 0
		value.4 0
		value.5 0
		value.6 0
		value.7 0
		comment {
			access 'read write'
			type INTEGER
			count 8
			range '0 - 36'
		}
	}
	control.21 {
		iface PCM
		device 8
		name 'Playback Channel Map'
		value.0 0
		value.1 0
		value.2 0
		value.3 0
		value.4 0
		value.5 0
		value.6 0
		value.7 0
		comment {
			access 'read write'
			type INTEGER
			count 8
			range '0 - 36'
		}
	}
}
state.PCH {
	control.1 {
		iface MIXER
		name 'Front Playback Volume'
		value.0 87
		value.1 87
		comment {
			access 'read write'
			type INTEGER
			count 2
			range '0 - 87'
			dbmin -6525
			dbmax 0
			dbvalue.0 0
			dbvalue.1 0
		}
	}
	control.2 {
		iface MIXER
		name 'Speaker Playback Switch'
		value.0 true
		value.1 true
		comment {
			access 'read write'
			type BOOLEAN
			count 2
		}
	}
	control.3 {
		iface MIXER
		name 'Bass Speaker Playback Volume'
		value.0 87
		value.1 87
		comment {
			access 'read write'
			type INTEGER
			count 2
			range '0 - 87'
			dbmin -6525
			dbmax 0
			dbvalue.0 0
			dbvalue.1 0
		}
	}
	control.4 {
		iface MIXER
		name 'Bass Speaker Playback Switch'
		value true
		comment {
			access 'read write'
			type BOOLEAN
			count 1
		}
	}
	control.5 {
		iface MIXER
		name 'Headphone Playback Switch'
		value.0 false
		value.1 false
		comment {
			access 'read write'
			type BOOLEAN
			count 2
		}
	}
	control.6 {
		iface MIXER
		name 'Headset Mic Playback Volume'
		value.0 0
		value.1 0
		comment {
			access 'read write'
			type INTEGER
			count 2
			range '0 - 31'
			dbmin -3450
			dbmax 1200
			dbvalue.0 -3450
			dbvalue.1 -3450
		}
	}
	control.7 {
		iface MIXER
		name 'Headset Mic Playback Switch'
		value.0 false
		value.1 false
		comment {
			access 'read write'
			type BOOLEAN
			count 2
		}
	}
	control.8 {
		iface MIXER
		name 'Headphone Mic Playback Volume'
		value.0 0
		value.1 0
		comment {
			access 'read write'
			type INTEGER
			count 2
			range '0 - 31'
			dbmin -3450
			dbmax 1200
			dbvalue.0 -3450
			dbvalue.1 -3450
		}
	}
	control.9 {
		iface MIXER
		name 'Headphone Mic Playback Switch'
		value.0 false
		value.1 false
		comment {
			access 'read write'
			type BOOLEAN
			count 2
		}
	}
	control.10 {
		iface MIXER
		name 'Auto-Mute Mode'
		value Disabled
		comment {
			access 'read write'
			type ENUMERATED
			count 1
			item.0 Disabled
			item.1 Enabled
		}
	}
	control.11 {
		iface MIXER
		name 'Capture Source'
		value 'Internal Mic'
		comment {
			access 'read write'
			type ENUMERATED
			count 1
			item.0 'Headset Mic'
			item.1 'Headphone Mic'
			item.2 'Internal Mic'
		}
	}
	control.12 {
		iface MIXER
		name 'Capture Volume'
		value.0 38
		value.1 38
		comment {
			access 'read write'
			type INTEGER
			count 2
			range '0 - 63'
			dbmin -1725
			dbmax 3000
			dbvalue.0 1125
			dbvalue.1 1125
		}
	}
	control.13 {
		iface MIXER
		name 'Capture Switch'
		value.0 true
		value.1 true
		comment {
			access 'read write'
			type BOOLEAN
			count 2
		}
	}
	control.14 {
		iface MIXER
		name 'Headset Mic Boost Volume'
		value.0 0
		value.1 0
		comment {
			access 'read write'
			type INTEGER
			count 2
			range '0 - 3'
			dbmin 0
			dbmax 3000
			dbvalue.0 0
			dbvalue.1 0
		}
	}
	control.15 {
		iface MIXER
		name 'Headphone Mic Boost Volume'
		value.0 0
		value.1 0
		comment {
			access 'read write'
			type INTEGER
			count 2
			range '0 - 3'
			dbmin 0
			dbmax 3000
			dbvalue.0 0
			dbvalue.1 0
		}
	}
	control.16 {
		iface MIXER
		name 'Internal Mic Boost Volume'
		value.0 0
		value.1 0
		comment {
			access 'read write'
			type INTEGER
			count 2
			range '0 - 3'
			dbmin 0
			dbmax 3000
			dbvalue.0 0
			dbvalue.1 0
		}
	}
	control.17 {
		iface MIXER
		name 'Master Playback Volume'
		value 70
		comment {
			access 'read write'
			type INTEGER
			count 1
			range '0 - 87'
			dbmin -6525
			dbmax 0
			dbvalue.0 -1275
		}
	}
	control.18 {
		iface MIXER
		name 'Master Playback Switch'
		value true
		comment {
			access 'read write'
			type BOOLEAN
			count 1
		}
	}
	control.19 {
		iface CARD
		name 'Headset Mic Phantom Jack'
		value true
		comment {
			access read
			type BOOLEAN
			count 1
		}
	}
	control.20 {
		iface CARD
		name 'Headphone Mic Jack'
		value false
		comment {
			access read
			type BOOLEAN
			count 1
		}
	}
	control.21 {
		iface CARD
		name 'Internal Mic Phantom Jack'
		value true
		comment {
			access read
			type BOOLEAN
			count 1
		}
	}
	control.22 {
		iface CARD
		name 'Speaker Front Phantom Jack'
		value true
		comment {
			access read
			type BOOLEAN
			count 1
		}
	}
	control.23 {
		iface CARD
		name 'Speaker Surround Phantom Jack'
		value true
		comment {
			access read
			type BOOLEAN
			count 1
		}
	}
	control.24 {
		iface MIXER
		name 'Beep Playback Volume'
		value.0 0
		value.1 0
		comment {
			access 'read write'
			type INTEGER
			count 2
			range '0 - 31'
			dbmin -3450
			dbmax 1200
			dbvalue.0 -3450
			dbvalue.1 -3450
		}
	}
	control.25 {
		iface MIXER
		name 'Beep Playback Switch'
		value.0 false
		value.1 false
		comment {
			access 'read write'
			type BOOLEAN
			count 2
		}
	}
	control.26 {
		iface PCM
		name 'Playback Channel Map'
		value.0 3
		value.1 4
		value.2 8
		value.3 8
		comment {
			access read
			type INTEGER
			count 4
			range '0 - 36'
		}
	}
	control.27 {
		iface PCM
		name 'Capture Channel Map'
		value.0 0
		value.1 0
		comment {
			access read
			type INTEGER
			count 2
			range '0 - 36'
		}
	}
	control.28 {
		iface MIXER
		name 'PCM Playback Volume'
		value.0 254
		value.1 254
		comment {
			access 'read write user'
			type INTEGER
			count 2
			range '0 - 255'
			tlv '0000000100000008ffffec1400000014'
			dbmin -5100
			dbmax 0
			dbvalue.0 -20
			dbvalue.1 -20
		}
	}
}
--endcollapse--


!!All Loaded Modules
!!------------------

Module


!!Sysfs Files
!!-----------

/sys/class/sound/hwC0D0/init_pin_configs:
0x05 0x18560010
0x06 0x18560020
0x07 0x18560030

/sys/class/sound/hwC0D0/driver_pin_configs:

/sys/class/sound/hwC0D0/user_pin_configs:

/sys/class/sound/hwC0D0/init_verbs:

/sys/class/sound/hwC0D0/hints:

/sys/class/sound/hwC1D0/init_pin_configs:
0x12 0x90a60160
0x14 0x90170120
0x17 0x90170140
0x18 0x40000000
0x19 0x411111f0
0x1a 0x411111f0
0x1b 0x411111f0
0x1d 0x41163b05
0x1e 0x411111f0
0x21 0x0321102f

/sys/class/sound/hwC1D0/driver_pin_configs:
0x19 0x01a1913c
0x1a 0x01a1913d

/sys/class/sound/hwC1D0/user_pin_configs:

/sys/class/sound/hwC1D0/init_verbs:

/sys/class/sound/hwC1D0/hints:


!!ALSA/HDA dmesg
!!--------------

[    0.892364] usbhid: USB HID core driver
[    0.892529] snd_hda_intel 0000:00:03.0: enabling device (0000 -> 0002)
[    0.892605] snd_hda_intel 0000:00:03.0: bound 0000:00:02.0 (ops i915_audio_component_bind_ops)
[    0.892618] snd_hda_intel 0000:00:1b.0: enabling device (0000 -> 0002)
[    0.892818] TCP: cubic registered
--
[    0.898597] PM: Hibernation image not present or could not be loaded.
[    0.898604] ALSA device list:
[    0.898605]   No soundcards found.
[    0.903878] input: HDA Intel HDMI HDMI/DP,pcm=3 as /devices/pci0000:00/0000:00:03.0/sound/card0/input9
[    0.903942] input: HDA Intel HDMI HDMI/DP,pcm=7 as /devices/pci0000:00/0000:00:03.0/sound/card0/input10
[    0.904002] input: HDA Intel HDMI HDMI/DP,pcm=8 as /devices/pci0000:00/0000:00:03.0/sound/card0/input11
[    0.906403] [drm] GMBUS [i915 gmbus vga] timed out, falling back to bit banging on pin 2
[    0.923152] fbcon: inteldrmfb (fb0) is primary device
[    0.938905] snd_hda_codec_realtek hdaudioC1D0: autoconfig for ALC3234: line_outs=2 (0x14/0x17/0x0/0x0/0x0) type:speaker
[    0.938907] snd_hda_codec_realtek hdaudioC1D0:    speaker_outs=0 (0x0/0x0/0x0/0x0/0x0)
[    0.938908] snd_hda_codec_realtek hdaudioC1D0:    hp_outs=1 (0x21/0x0/0x0/0x0/0x0)
[    0.938908] snd_hda_codec_realtek hdaudioC1D0:    mono: mono_out=0x0
[    0.938909] snd_hda_codec_realtek hdaudioC1D0:    inputs:
[    0.938910] snd_hda_codec_realtek hdaudioC1D0:      Headset Mic=0x19
[    0.938911] snd_hda_codec_realtek hdaudioC1D0:      Headphone Mic=0x1a
[    0.938912] snd_hda_codec_realtek hdaudioC1D0:      Internal Mic=0x12
[    0.943084] snd_hda_codec_realtek hdaudioC1D0: Failed to find dell wmi symbol dell_app_wmi_led_set
[    0.949620] input: HDA Intel PCH Headphone Mic as /devices/pci0000:00/0000:00:1b.0/sound/card1/input12
[    1.162780] usb 1-5: new high-speed USB device number 2 using xhci_hcd



[-- Attachment #3: Type: text/plain, Size: 0 bytes --]



^ permalink raw reply	[flat|nested] 21+ messages in thread

* Re: [PATCH 0/4] More aggressive PM for HD-audio
  2015-03-30  6:53             ` hwang4
@ 2015-04-04 10:31               ` Takashi Iwai
  2015-04-09  6:54               ` hwang4
  1 sibling, 0 replies; 21+ messages in thread
From: Takashi Iwai @ 2015-04-04 10:31 UTC (permalink / raw)
  To: hwang4; +Cc: alsa-devel, David Henningsson

Hi,

sorry for the late reply, now I'm back from vacation.

At Mon, 30 Mar 2015 14:53:37 +0800,
hwang4 wrote:
> 
> 
> 
> On 2015年03月27日 08:11, Hui Wang wrote:
> > On 03/26/2015 09:52 PM, Takashi Iwai wrote:
> >> At Thu, 26 Mar 2015 14:10:17 +0100,
> >> Takashi Iwai wrote:
> >>> At Thu, 26 Mar 2015 20:24:43 +0800,
> >>> Hui Wang wrote:
> >>>> On 03/21/2015 02:38 PM, Hui Wang wrote:
> >>>>> On 03/21/2015 12:20 AM, David Henningsson wrote:
> >>>>>> On 2015-03-18 09:50, Takashi Iwai wrote:
> >>>>>>> Hi,
> >>>>>>>
> >>>>>>> here is a patchset for supporting more aggressive PM for HD-audio.
> >>>>>>> This allows to change the power state of each widget more 
> >>>>>>> dynamically
> >>>>>>> with jack and stream states.  It's activated only when the codec
> >>>>>>> driver (or via sysfs or f/w patch) sets codec->power_mgmt flag.
> >>>>>>>
> >>>>>>> In theory, this should work for the recent Realtek codecs, but
> >>>>>>> currently I have no machine for test.
> >>>>>>>
> >>>>>>> David, could you or your team check whether this works for 
> >>>>>>> ALC282 or
> >>>>>>> such?  Just add like:
> >>>>>>>
> >>>>>>> --- a/sound/pci/hda/patch_realtek.c
> >>>>>>> +++ b/sound/pci/hda/patch_realtek.c
> >>>>>>> @@ -5415,6 +5415,7 @@ static int patch_alc269(struct hda_codec 
> >>>>>>> *codec)
> >>>>>>>
> >>>>>>>        spec = codec->spec;
> >>>>>>>        spec->gen.shared_mic_vref_pin = 0x18;
> >>>>>>> +    codec->power_mgmt = 1;
> >>>>>>>
> >>>>>>>        snd_hda_pick_fixup(codec, alc269_fixup_models,
> >>>>>>>                   alc269_fixup_tbl, alc269_fixups);
> >>>>>>>
> >>>>>>>
> >>>>>>> The patchset is for for-next branch of sound git tree, but they 
> >>>>>>> might
> >>>>>>> be applicable to 4.0-rc (or even older), too.  The current 
> >>>>>>> patches are
> >>>>>>> found in topic/hda-power branch.
> >>>>>> So I hoped to be able to look at this today, but it turns out the
> >>>>>> machine I was thinking of using for testing has an ALC262 codec,
> >>>>>> which hardly counts as "new".
> >>>>>>
> >>>>>> Hui, is this something you feel like taking on? Otherwise I'll 
> >>>>>> try to
> >>>>>> talk to someone in Taipei.
> >>>>>>
> >>>>> OK, I will look for the machine to do the test next week.
> >>>>>
> >>>>> Regards,
> >>>>> Hui.
> >>>>>
> >>>> Sorry for late response, today is my first day in the office back from
> >>>> vacation, I checked all machines in the Beijing office, none of 
> >>>> them has
> >>>> the ALC282 codec, I will continue to look for the machine from 
> >>>> other office.
> >>>>
> >>>> And I did the test on the machines with the alc283, alc255, alc292 and
> >>>> alc269, the testing result were same, there were no sound output from
> >>>> internal speaker or headphone, and the internal mic or external mic
> >>>> can't record any sound. The test steps as below:
> >>>>
> >>>> 1. power_save_node = 0
> >>>> checkout the hda-power branch, build the kernel based on this branch.
> >>>> Install the kernel to the above machines and boot into the desktop
> >>>> test internal speaker and internal mic, works very well, plug a 
> >>>> headset,
> >>>> test headphone and external mic, works very well.
> >>>> run pm_suspend, wait 5 seconds, wakeup the system, redo the above 
> >>>> test,
> >>>> everything works very well.
> >>> OK, this is expected.  The patch shouldn't touch this case.
> >>>
> >>>> 2. power_save_node = 1
> >>>> enable the power_save_node as below:
> >>>> @@ -5426,6 +5426,8 @@ static int patch_alc269(struct hda_codec *codec)
> >>>>
> >>>>           alc_auto_parse_customize_define(codec);
> >>>>
> >>>> +       codec->power_save_node = 1;
> >>>> +
> >>>>           if (has_cdefine_beep(codec))
> >>>>                   spec->gen.beep_nid = 0x01;
> >>>> rebuild the kernel, install the kernel to the above machines and boot
> >>>> into the desktop
> >>>> test internal speaker and internal mic, we can play sound to internal
> >>>> speaker without any errors, but I can't hear any sound from the 
> >>>> speaker;
> >>>> I can use the internal mic to record without errors, but recorded file
> >>>> did not include any sound pcm (maybe all 0x00 or 0xff)
> >>>> I plug a headset into the headset jack, the detection works very well,
> >>>> but I can't hear sound from headphone when play a sound, and I 
> >>>> can't use
> >>>> headset mic to record any sound as well.
> >>>>
> >>>>
> >>>> And I attached 2 alsa-info.txt, one is the power_save_node=0, the 
> >>>> other
> >>>> is the power_save_node=1
> >>> Thanks.  The alsa-info.sh outputs show no difference but the power
> >>> state, so the widget attributes seem kept with the power state change,
> >>> as it seems.
> >>>
> >>> Could you give alsa-info.sh output *during* playing with
> >>> power_save_node=1?
> >> Also, try to pull topic/hda-regmap branch in addition, and apply the
> >> patch below.  This implements the partial sync for the widget path.
> >> Note that the patch is totally untested.
> > Got it, I will do the test next Monday, since I can't access those 
> > machines until next Monday.
> >
> > Regards,
> > Hui.
> 
> The attached alsa-info.txt was generated when the aplay was playing a 
> song, it seems the widget power state did not change even the output 
> device was working.
> 
> 
> And I also checkout the hda-regmap branch and applied the patch below, 
> rebuilt the kernel and used the kernel to do the test of playing and 
> recording, both internal devices and external devices worked very well, 
> I didn't see any obvious problems when using hda-regmap branch doing the 
> test.

Great!  I merged the branch now and enabled the widget power saving
for Realtek codecs.


Takashi
_______________________________________________
Alsa-devel mailing list
Alsa-devel@alsa-project.org
http://mailman.alsa-project.org/mailman/listinfo/alsa-devel

^ permalink raw reply	[flat|nested] 21+ messages in thread

* Re: [PATCH 0/4] More aggressive PM for HD-audio
  2015-03-30  6:53             ` hwang4
  2015-04-04 10:31               ` Takashi Iwai
@ 2015-04-09  6:54               ` hwang4
  2015-04-09  6:56                 ` Takashi Iwai
  1 sibling, 1 reply; 21+ messages in thread
From: hwang4 @ 2015-04-09  6:54 UTC (permalink / raw)
  To: Takashi Iwai; +Cc: alsa-devel, David Henningsson



On 2015年03月30日 14:53, hwang4 wrote:
>
>
> On 2015年03月27日 08:11, Hui Wang wrote:
>> On 03/26/2015 09:52 PM, Takashi Iwai wrote:
>>> At Thu, 26 Mar 2015 14:10:17 +0100,
>>> Takashi Iwai wrote:
>>>> At Thu, 26 Mar 2015 20:24:43 +0800,
>>>> Hui Wang wrote:
>>>>> On 03/21/2015 02:38 PM, Hui Wang wrote:
>>>>>> On 03/21/2015 12:20 AM, David Henningsson wrote:
>>>>>>> On 2015-03-18 09:50, Takashi Iwai wrote:
>>>>>>>> Hi,
>>>>>>>>
>>>>>>>> here is a patchset for supporting more aggressive PM for HD-audio.
>>>>>>>> This allows to change the power state of each widget more 
>>>>>>>> dynamically
>>>>>>>> with jack and stream states.  It's activated only when the codec
>>>>>>>> driver (or via sysfs or f/w patch) sets codec->power_mgmt flag.
>>>>>>>>
>>>>>>>> In theory, this should work for the recent Realtek codecs, but
>>>>>>>> currently I have no machine for test.
>>>>>>>>
>>>>>>>> David, could you or your team check whether this works for 
>>>>>>>> ALC282 or
>>>>>>>> such?  Just add like:
>>>>>>>>
>>>>>>>> --- a/sound/pci/hda/patch_realtek.c
>>>>>>>> +++ b/sound/pci/hda/patch_realtek.c
>>>>>>>> @@ -5415,6 +5415,7 @@ static int patch_alc269(struct hda_codec 
>>>>>>>> *codec)
>>>>>>>>
>>>>>>>>        spec = codec->spec;
>>>>>>>>        spec->gen.shared_mic_vref_pin = 0x18;
>>>>>>>> +    codec->power_mgmt = 1;
>>>>>>>>
>>>>>>>>        snd_hda_pick_fixup(codec, alc269_fixup_models,
>>>>>>>>                   alc269_fixup_tbl, alc269_fixups);
>>>>>>>>
>>>>>>>>
>>>>>>>> The patchset is for for-next branch of sound git tree, but they 
>>>>>>>> might
>>>>>>>> be applicable to 4.0-rc (or even older), too.  The current 
>>>>>>>> patches are
>>>>>>>> found in topic/hda-power branch.
>>>>>>> So I hoped to be able to look at this today, but it turns out the
>>>>>>> machine I was thinking of using for testing has an ALC262 codec,
>>>>>>> which hardly counts as "new".
>>>>>>>
>>>>>>> Hui, is this something you feel like taking on? Otherwise I'll 
>>>>>>> try to
>>>>>>> talk to someone in Taipei.
>>>>>>>
>>>>>> OK, I will look for the machine to do the test next week.
>>>>>>
>>>>>> Regards,
>>>>>> Hui.
>>>>>>
>>>>> Sorry for late response, today is my first day in the office back 
>>>>> from
>>>>> vacation, I checked all machines in the Beijing office, none of 
>>>>> them has
>>>>> the ALC282 codec, I will continue to look for the machine from 
>>>>> other office.
>>>>>
>>>>> And I did the test on the machines with the alc283, alc255, alc292 
>>>>> and
>>>>> alc269, the testing result were same, there were no sound output from
>>>>> internal speaker or headphone, and the internal mic or external mic
>>>>> can't record any sound. The test steps as below:
>>>>>
>>>>> 1. power_save_node = 0
>>>>> checkout the hda-power branch, build the kernel based on this branch.
>>>>> Install the kernel to the above machines and boot into the desktop
>>>>> test internal speaker and internal mic, works very well, plug a 
>>>>> headset,
>>>>> test headphone and external mic, works very well.
>>>>> run pm_suspend, wait 5 seconds, wakeup the system, redo the above 
>>>>> test,
>>>>> everything works very well.
>>>> OK, this is expected.  The patch shouldn't touch this case.
>>>>
>>>>> 2. power_save_node = 1
>>>>> enable the power_save_node as below:
>>>>> @@ -5426,6 +5426,8 @@ static int patch_alc269(struct hda_codec 
>>>>> *codec)
>>>>>
>>>>>           alc_auto_parse_customize_define(codec);
>>>>>
>>>>> +       codec->power_save_node = 1;
>>>>> +
>>>>>           if (has_cdefine_beep(codec))
>>>>>                   spec->gen.beep_nid = 0x01;
>>>>> rebuild the kernel, install the kernel to the above machines and boot
>>>>> into the desktop
>>>>> test internal speaker and internal mic, we can play sound to internal
>>>>> speaker without any errors, but I can't hear any sound from the 
>>>>> speaker;
>>>>> I can use the internal mic to record without errors, but recorded 
>>>>> file
>>>>> did not include any sound pcm (maybe all 0x00 or 0xff)
>>>>> I plug a headset into the headset jack, the detection works very 
>>>>> well,
>>>>> but I can't hear sound from headphone when play a sound, and I 
>>>>> can't use
>>>>> headset mic to record any sound as well.
>>>>>
>>>>>
>>>>> And I attached 2 alsa-info.txt, one is the power_save_node=0, the 
>>>>> other
>>>>> is the power_save_node=1
>>>> Thanks.  The alsa-info.sh outputs show no difference but the power
>>>> state, so the widget attributes seem kept with the power state change,
>>>> as it seems.
>>>>
>>>> Could you give alsa-info.sh output *during* playing with
>>>> power_save_node=1?
>>> Also, try to pull topic/hda-regmap branch in addition, and apply the
>>> patch below.  This implements the partial sync for the widget path.
>>> Note that the patch is totally untested.
>> Got it, I will do the test next Monday, since I can't access those 
>> machines until next Monday.
>>
>> Regards,
>> Hui.
>
> The attached alsa-info.txt was generated when the aplay was playing a 
> song, it seems the widget power state did not change even the output 
> device was working.
>
>
> And I also checkout the hda-regmap branch and applied the patch below, 
> rebuilt the kernel and used the kernel to do the test of playing and 
> recording, both internal devices and external devices worked very 
> well, I didn't see any obvious problems when using hda-regmap branch 
> doing the test.
>
> Regards,
> Hui.
>
Hi Takashi,

Probably I didn't express correctly, sorry to make you mis-understand.  
I wanted to express that I tested hda-power and hda-regmap two branches 
respectively, the hda-regmap branch with your patch worked very well, 
but the hda-power branch didn't work on the machines with realtek codec, 
the nodes kept in the D3 power state no matter playing or not.

It seems you enabled the power_save_node for realtek codec several days 
ago, it makes the HDA drivers fail to work on all machines with realtek 
codec.

Regards,
Hui.

_______________________________________________
Alsa-devel mailing list
Alsa-devel@alsa-project.org
http://mailman.alsa-project.org/mailman/listinfo/alsa-devel

^ permalink raw reply	[flat|nested] 21+ messages in thread

* Re: [PATCH 0/4] More aggressive PM for HD-audio
  2015-04-09  6:54               ` hwang4
@ 2015-04-09  6:56                 ` Takashi Iwai
  2015-04-09  6:59                   ` David Henningsson
  0 siblings, 1 reply; 21+ messages in thread
From: Takashi Iwai @ 2015-04-09  6:56 UTC (permalink / raw)
  To: hwang4; +Cc: alsa-devel, David Henningsson

At Thu, 09 Apr 2015 14:54:17 +0800,
hwang4 wrote:
> 
> 
> 
> On 2015年03月30日 14:53, hwang4 wrote:
> >
> >
> > On 2015年03月27日 08:11, Hui Wang wrote:
> >> On 03/26/2015 09:52 PM, Takashi Iwai wrote:
> >>> At Thu, 26 Mar 2015 14:10:17 +0100,
> >>> Takashi Iwai wrote:
> >>>> At Thu, 26 Mar 2015 20:24:43 +0800,
> >>>> Hui Wang wrote:
> >>>>> On 03/21/2015 02:38 PM, Hui Wang wrote:
> >>>>>> On 03/21/2015 12:20 AM, David Henningsson wrote:
> >>>>>>> On 2015-03-18 09:50, Takashi Iwai wrote:
> >>>>>>>> Hi,
> >>>>>>>>
> >>>>>>>> here is a patchset for supporting more aggressive PM for HD-audio.
> >>>>>>>> This allows to change the power state of each widget more 
> >>>>>>>> dynamically
> >>>>>>>> with jack and stream states.  It's activated only when the codec
> >>>>>>>> driver (or via sysfs or f/w patch) sets codec->power_mgmt flag.
> >>>>>>>>
> >>>>>>>> In theory, this should work for the recent Realtek codecs, but
> >>>>>>>> currently I have no machine for test.
> >>>>>>>>
> >>>>>>>> David, could you or your team check whether this works for 
> >>>>>>>> ALC282 or
> >>>>>>>> such?  Just add like:
> >>>>>>>>
> >>>>>>>> --- a/sound/pci/hda/patch_realtek.c
> >>>>>>>> +++ b/sound/pci/hda/patch_realtek.c
> >>>>>>>> @@ -5415,6 +5415,7 @@ static int patch_alc269(struct hda_codec 
> >>>>>>>> *codec)
> >>>>>>>>
> >>>>>>>>        spec = codec->spec;
> >>>>>>>>        spec->gen.shared_mic_vref_pin = 0x18;
> >>>>>>>> +    codec->power_mgmt = 1;
> >>>>>>>>
> >>>>>>>>        snd_hda_pick_fixup(codec, alc269_fixup_models,
> >>>>>>>>                   alc269_fixup_tbl, alc269_fixups);
> >>>>>>>>
> >>>>>>>>
> >>>>>>>> The patchset is for for-next branch of sound git tree, but they 
> >>>>>>>> might
> >>>>>>>> be applicable to 4.0-rc (or even older), too.  The current 
> >>>>>>>> patches are
> >>>>>>>> found in topic/hda-power branch.
> >>>>>>> So I hoped to be able to look at this today, but it turns out the
> >>>>>>> machine I was thinking of using for testing has an ALC262 codec,
> >>>>>>> which hardly counts as "new".
> >>>>>>>
> >>>>>>> Hui, is this something you feel like taking on? Otherwise I'll 
> >>>>>>> try to
> >>>>>>> talk to someone in Taipei.
> >>>>>>>
> >>>>>> OK, I will look for the machine to do the test next week.
> >>>>>>
> >>>>>> Regards,
> >>>>>> Hui.
> >>>>>>
> >>>>> Sorry for late response, today is my first day in the office back 
> >>>>> from
> >>>>> vacation, I checked all machines in the Beijing office, none of 
> >>>>> them has
> >>>>> the ALC282 codec, I will continue to look for the machine from 
> >>>>> other office.
> >>>>>
> >>>>> And I did the test on the machines with the alc283, alc255, alc292 
> >>>>> and
> >>>>> alc269, the testing result were same, there were no sound output from
> >>>>> internal speaker or headphone, and the internal mic or external mic
> >>>>> can't record any sound. The test steps as below:
> >>>>>
> >>>>> 1. power_save_node = 0
> >>>>> checkout the hda-power branch, build the kernel based on this branch.
> >>>>> Install the kernel to the above machines and boot into the desktop
> >>>>> test internal speaker and internal mic, works very well, plug a 
> >>>>> headset,
> >>>>> test headphone and external mic, works very well.
> >>>>> run pm_suspend, wait 5 seconds, wakeup the system, redo the above 
> >>>>> test,
> >>>>> everything works very well.
> >>>> OK, this is expected.  The patch shouldn't touch this case.
> >>>>
> >>>>> 2. power_save_node = 1
> >>>>> enable the power_save_node as below:
> >>>>> @@ -5426,6 +5426,8 @@ static int patch_alc269(struct hda_codec 
> >>>>> *codec)
> >>>>>
> >>>>>           alc_auto_parse_customize_define(codec);
> >>>>>
> >>>>> +       codec->power_save_node = 1;
> >>>>> +
> >>>>>           if (has_cdefine_beep(codec))
> >>>>>                   spec->gen.beep_nid = 0x01;
> >>>>> rebuild the kernel, install the kernel to the above machines and boot
> >>>>> into the desktop
> >>>>> test internal speaker and internal mic, we can play sound to internal
> >>>>> speaker without any errors, but I can't hear any sound from the 
> >>>>> speaker;
> >>>>> I can use the internal mic to record without errors, but recorded 
> >>>>> file
> >>>>> did not include any sound pcm (maybe all 0x00 or 0xff)
> >>>>> I plug a headset into the headset jack, the detection works very 
> >>>>> well,
> >>>>> but I can't hear sound from headphone when play a sound, and I 
> >>>>> can't use
> >>>>> headset mic to record any sound as well.
> >>>>>
> >>>>>
> >>>>> And I attached 2 alsa-info.txt, one is the power_save_node=0, the 
> >>>>> other
> >>>>> is the power_save_node=1
> >>>> Thanks.  The alsa-info.sh outputs show no difference but the power
> >>>> state, so the widget attributes seem kept with the power state change,
> >>>> as it seems.
> >>>>
> >>>> Could you give alsa-info.sh output *during* playing with
> >>>> power_save_node=1?
> >>> Also, try to pull topic/hda-regmap branch in addition, and apply the
> >>> patch below.  This implements the partial sync for the widget path.
> >>> Note that the patch is totally untested.
> >> Got it, I will do the test next Monday, since I can't access those 
> >> machines until next Monday.
> >>
> >> Regards,
> >> Hui.
> >
> > The attached alsa-info.txt was generated when the aplay was playing a 
> > song, it seems the widget power state did not change even the output 
> > device was working.
> >
> >
> > And I also checkout the hda-regmap branch and applied the patch below, 
> > rebuilt the kernel and used the kernel to do the test of playing and 
> > recording, both internal devices and external devices worked very 
> > well, I didn't see any obvious problems when using hda-regmap branch 
> > doing the test.
> >
> > Regards,
> > Hui.
> >
> Hi Takashi,
> 
> Probably I didn't express correctly, sorry to make you mis-understand.  
> I wanted to express that I tested hda-power and hda-regmap two branches 
> respectively, the hda-regmap branch with your patch worked very well, 
> but the hda-power branch didn't work on the machines with realtek codec, 
> the nodes kept in the D3 power state no matter playing or not.
>
> It seems you enabled the power_save_node for realtek codec several days 
> ago, it makes the HDA drivers fail to work on all machines with realtek 
> codec.

Ah, OK.  Then we should revert the commit later.

But let's continue debugging a bit.  Could you give alsa-info.sh
outputs on both working and non-working states?


Takashi
_______________________________________________
Alsa-devel mailing list
Alsa-devel@alsa-project.org
http://mailman.alsa-project.org/mailman/listinfo/alsa-devel

^ permalink raw reply	[flat|nested] 21+ messages in thread

* Re: [PATCH 0/4] More aggressive PM for HD-audio
  2015-04-09  6:56                 ` Takashi Iwai
@ 2015-04-09  6:59                   ` David Henningsson
  2015-04-09  8:35                     ` Takashi Iwai
  0 siblings, 1 reply; 21+ messages in thread
From: David Henningsson @ 2015-04-09  6:59 UTC (permalink / raw)
  To: Takashi Iwai, hwang4; +Cc: alsa-devel



On 2015-04-09 08:56, Takashi Iwai wrote:
> Ah, OK.  Then we should revert the commit later.
>
> But let's continue debugging a bit.  Could you give alsa-info.sh
> outputs on both working and non-working states?

Just running hda-emu with a realtek codec, e g 
codecs/canonical/alc292-dell-latitude-e5440-ccert-201307-13941 turns all 
nodes, including the internal speaker, into D3. And running a playback 
test does not switch things into D0 - even the DAC node remains in D3 
even though you try to stream to it, which seems a bit strange.

Could you explain how this is supposed to work?

-- 
David Henningsson, Canonical Ltd.
https://launchpad.net/~diwic

^ permalink raw reply	[flat|nested] 21+ messages in thread

* Re: [PATCH 0/4] More aggressive PM for HD-audio
  2015-04-09  6:59                   ` David Henningsson
@ 2015-04-09  8:35                     ` Takashi Iwai
  0 siblings, 0 replies; 21+ messages in thread
From: Takashi Iwai @ 2015-04-09  8:35 UTC (permalink / raw)
  To: David Henningsson; +Cc: hwang4, alsa-devel

At Thu, 09 Apr 2015 08:59:17 +0200,
David Henningsson wrote:
> 
> 
> 
> On 2015-04-09 08:56, Takashi Iwai wrote:
> > Ah, OK.  Then we should revert the commit later.
> >
> > But let's continue debugging a bit.  Could you give alsa-info.sh
> > outputs on both working and non-working states?
> 
> Just running hda-emu with a realtek codec, e g 
> codecs/canonical/alc292-dell-latitude-e5440-ccert-201307-13941 turns all 
> nodes, including the internal speaker, into D3. And running a playback 
> test does not switch things into D0 - even the DAC node remains in D3 
> even though you try to stream to it, which seems a bit strange.
> 
> Could you explain how this is supposed to work?

Doh, it was the missing stream_pm ops setup.  Also I found a few
other minor issues.  I'm going to submit a fix patch series now.


thanks

Takashi

^ permalink raw reply	[flat|nested] 21+ messages in thread

end of thread, other threads:[~2015-04-09  8:35 UTC | newest]

Thread overview: 21+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2015-03-18  8:50 [PATCH 0/4] More aggressive PM for HD-audio Takashi Iwai
2015-03-18  8:50 ` [PATCH 1/4] ALSA: hda - Simplify PCM setup overrides Takashi Iwai
2015-03-18  8:50 ` [PATCH 2/4] ALSA: hda - Support advanced power state controls Takashi Iwai
2015-03-18  8:50 ` [PATCH 3/4] ALSA: hda - Use the new power control for VIA codecs Takashi Iwai
2015-03-18  8:50 ` [PATCH 4/4] ALSA: hda - Adjust power of beep widget and outputs Takashi Iwai
2015-03-18 19:34 ` [PATCH 0/4] More aggressive PM for HD-audio David Henningsson
2015-03-18 20:02   ` Takashi Iwai
2015-03-20 16:20 ` David Henningsson
2015-03-20 16:28   ` Takashi Iwai
2015-03-20 17:18     ` Takashi Iwai
2015-03-20 17:33       ` Takashi Iwai
2015-03-21  6:38   ` Hui Wang
     [not found]     ` <5513FA8B.402@canonical.com>
2015-03-26 13:10       ` Takashi Iwai
2015-03-26 13:52         ` Takashi Iwai
2015-03-27  0:11           ` Hui Wang
2015-03-30  6:53             ` hwang4
2015-04-04 10:31               ` Takashi Iwai
2015-04-09  6:54               ` hwang4
2015-04-09  6:56                 ` Takashi Iwai
2015-04-09  6:59                   ` David Henningsson
2015-04-09  8:35                     ` Takashi Iwai

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.