[alsa-devel] [PATCH v8 2/2] ASoC: hdac_hdmi: Add PM support

Takashi Iwai tiwai at suse.de
Sun Feb 21 09:18:46 CET 2016


On Sun, 21 Feb 2016 07:00:44 +0100,
Subhransu S. Prusty wrote:
> 
> From: Jeeja KP <jeeja.kp at intel.com>
> 
> The codec registers are reset during S3. So need to reconfigure
> all pins and DP1.2 feature again after resume from S3. Also
> reprogram the required registers if the S3 was triggered during
> playback.
> 
> In suspended state ELD notify callback is not processed, So add
> ELD check for all pins as well.
> 
> Also turn the codec power domain OFF which is kept ON during
> controller resequencing and codec reenumeration.
> 
> Signed-off-by: Jeeja KP <jeeja.kp at intel.com>
> Signed-off-by: Subhransu S. Prusty <subhransu.s.prusty at intel.com>
> Signed-off-by: Vinod Koul <vinod.koul at intel.com>
> ---
>  sound/soc/codecs/hdac_hdmi.c | 61 ++++++++++++++++++++++++++++++++++++++++++++
>  1 file changed, 61 insertions(+)
> 
> diff --git a/sound/soc/codecs/hdac_hdmi.c b/sound/soc/codecs/hdac_hdmi.c
> index aa953a5..ab75b4b 100644
> --- a/sound/soc/codecs/hdac_hdmi.c
> +++ b/sound/soc/codecs/hdac_hdmi.c
> @@ -601,6 +601,26 @@ static int hdac_hdmi_pcm_open(struct snd_pcm_substream *substream,
>  				pin->eld.eld_buffer);
>  }
>  
> +static int hdac_hdmi_trigger(struct snd_pcm_substream *substream, int cmd,
> +		struct snd_soc_dai *dai)
> +{
> +	struct hdac_hdmi_dai_pin_map *dai_map;
> +	struct hdac_ext_device *hdac = snd_soc_dai_get_drvdata(dai);
> +	struct hdac_hdmi_priv *hdmi = hdac->private_data;
> +	int ret;
> +
> +	dai_map = &hdmi->dai_map[dai->id];
> +	if (cmd == SNDRV_PCM_TRIGGER_RESUME) {
> +		ret = hdac_hdmi_enable_pin(hdac, dai_map);
> +		if (ret < 0)
> +			return ret;
> +
> +		return hdac_hdmi_playback_prepare(substream, dai);
> +	}
> +
> +	return 0;
> +}
> +
>  static void hdac_hdmi_pcm_close(struct snd_pcm_substream *substream,
>  		struct snd_soc_dai *dai)
>  {
> @@ -1154,6 +1174,7 @@ static struct snd_soc_dai_ops hdmi_dai_ops = {
>  	.shutdown = hdac_hdmi_pcm_close,
>  	.hw_params = hdac_hdmi_set_hw_params,
>  	.prepare = hdac_hdmi_playback_prepare,
> +	.trigger = hdac_hdmi_trigger,
>  	.hw_free = hdac_hdmi_playback_cleanup,
>  };
>  
> @@ -1399,9 +1420,49 @@ static int hdmi_codec_remove(struct snd_soc_codec *codec)
>  	return 0;
>  }
>  
> +#ifdef CONFIG_PM
> +static int hdmi_codec_resume(struct snd_soc_codec *codec)
> +{
> +	struct hdac_ext_device *edev = snd_soc_codec_get_drvdata(codec);
> +	struct hdac_hdmi_priv *hdmi = edev->private_data;
> +	struct hdac_hdmi_pin *pin;
> +	struct hdac_device *hdac = &edev->hdac;
> +	struct hdac_bus *bus = hdac->bus;
> +	int err;
> +
> +	hdac_hdmi_skl_enable_all_pins(&edev->hdac);
> +	hdac_hdmi_skl_enable_dp12(&edev->hdac);
> +
> +	/* Power up afg */
> +	if (!snd_hdac_check_power_state(hdac, hdac->afg, AC_PWRST_D0))
> +		snd_hdac_codec_write(hdac, hdac->afg, 0,
> +			AC_VERB_SET_POWER_STATE, AC_PWRST_D0);

You don't have to wait for D0 power up unlike runtime resume?

> +	/*
> +	 * As the ELD notify callback request is not entertained while the
> +	 * device is in suspend state. Need to manually check detection of
> +	 * all pins here.
> +	 */
> +	list_for_each_entry(pin, &hdmi->pin_list, head)
> +		hdac_hdmi_present_sense(pin, 1);
> +
> +	/* Codec power is turned ON during controller resume */
> +	err = snd_hdac_display_power(bus, false);
> +	if (err < 0) {
> +		dev_err(bus->dev, "Cannot turn on display power on i915\n");

Make clear whether you're turning on or off...


Takashi


More information about the Alsa-devel mailing list