From d360ab8b6996dc0db436723f1ae96e2a784d5295 Mon Sep 17 00:00:00 2001 From: Guennadi Liakhovetski Date: Mon, 1 Jul 2019 16:25:47 +0200 Subject: [PATCH 1/2] ASoC: SOF: Intel: use snd_hdac_chip_updatew() for WAKEEN Use snd_hdac_chip_updatew() to update WAKEEN instead of open-coding. Signed-off-by: Guennadi Liakhovetski --- sound/soc/sof/intel/hda-codec.c | 4 +--- sound/soc/sof/intel/hda-dsp.c | 5 ++--- 2 files changed, 3 insertions(+), 6 deletions(-) diff --git a/sound/soc/sof/intel/hda-codec.c b/sound/soc/sof/intel/hda-codec.c index 5882f1bfd906ca..95e8bab8f8bf60 100644 --- a/sound/soc/sof/intel/hda-codec.c +++ b/sound/soc/sof/intel/hda-codec.c @@ -68,9 +68,7 @@ void hda_codec_jack_check(struct snd_sof_dev *sdev, int status) codec->jackpoll_interval); /* disable controller Wake Up event*/ - snd_hdac_chip_writew(bus, WAKEEN, - snd_hdac_chip_readw(bus, WAKEEN) & - ~hda->hda_codec_mask); + snd_hdac_chip_updatew(bus, WAKEEN, STATESTS_INT_MASK, 0); } #else void hda_codec_jack_check(struct snd_sof_dev *sdev, int status) {} diff --git a/sound/soc/sof/intel/hda-dsp.c b/sound/soc/sof/intel/hda-dsp.c index fe143bb000e373..6ce4f3dd74d146 100644 --- a/sound/soc/sof/intel/hda-dsp.c +++ b/sound/soc/sof/intel/hda-dsp.c @@ -297,9 +297,8 @@ static int hda_suspend(struct snd_sof_dev *sdev, bool runtime_suspend) #if IS_ENABLED(CONFIG_SND_SOC_SOF_HDA) if (IS_ENABLED(CONFIG_SND_SOC_SOF_HDA_AUDIO_CODEC) && runtime_suspend) /* enable controller wake up event */ - snd_hdac_chip_writew(bus, WAKEEN, - snd_hdac_chip_readw(bus, WAKEEN) | - hda->hda_codec_mask); + snd_hdac_chip_updatew(bus, WAKEEN, STATESTS_INT_MASK, + hda->hda_codec_mask); /* power down all hda link */ snd_hdac_ext_bus_link_power_down_all(bus); From 863fff83847f8f981d77614d14ea82283faf0984 Mon Sep 17 00:00:00 2001 From: Guennadi Liakhovetski Date: Wed, 12 Jun 2019 12:34:53 +0200 Subject: [PATCH 2/2] ASoC: SOF: Intel: optimise jack detection 1. The additional HDA codec mask isn't needed, just check the codec jack table. 2. Remove the "status" parameter. Signed-off-by: Guennadi Liakhovetski --- sound/soc/sof/intel/hda-codec.c | 53 +++++++++++++++++---------------- sound/soc/sof/intel/hda-dsp.c | 18 +++-------- sound/soc/sof/intel/hda.h | 6 ++-- 3 files changed, 33 insertions(+), 44 deletions(-) diff --git a/sound/soc/sof/intel/hda-codec.c b/sound/soc/sof/intel/hda-codec.c index 95e8bab8f8bf60..3ca6795a89ba3a 100644 --- a/sound/soc/sof/intel/hda-codec.c +++ b/sound/soc/sof/intel/hda-codec.c @@ -38,53 +38,55 @@ static void hda_codec_load_module(struct hda_codec *codec) static void hda_codec_load_module(struct hda_codec *codec) {} #endif -/* check jack status after resuming from suspend mode */ -void hda_codec_jack_check(struct snd_sof_dev *sdev, int status) +/* enable controller wake up event for all codecs with jack connectors */ +void hda_codec_jack_wake_enable(struct snd_sof_dev *sdev) { - struct sof_intel_hda_dev *hda = sdev->pdata->hw_pdata; struct hda_bus *hbus = sof_to_hbus(sdev); struct hdac_bus *bus = sof_to_bus(sdev); struct hda_codec *codec; - int mask; - - /* - * there are two reasons for runtime resume - * (1) waken up by interrupt triggered by WAKEEN feature - * (2) waken up by pm get functions for some audio operations - * For case (1), the bits in status mean which codec triggers - * the interrupt and jacks will be checked on these codecs. - * For case (2), we need to check all the non-hdmi codecs for some - * cases like playback with HDMI or capture with DMIC. In these - * cases, only controller is active and codecs are suspended, so - * codecs can't send unsolicited event to controller. The jack polling - * operation will activate codecs and unsolicited event can work - * even codecs become suspended later. - */ - mask = status ? status : hda->hda_codec_mask; + unsigned int mask = 0; list_for_each_codec(codec, hbus) - if (mask & BIT(codec->core.addr)) - schedule_delayed_work(&codec->jackpoll_work, - codec->jackpoll_interval); + if (codec->jacktbl.used) + mask |= BIT(codec->core.addr); + + snd_hdac_chip_updatew(bus, WAKEEN, STATESTS_INT_MASK, mask); +} + +/* check jack status after resuming from suspend mode */ +void hda_codec_jack_check(struct snd_sof_dev *sdev) +{ + struct hda_bus *hbus = sof_to_hbus(sdev); + struct hdac_bus *bus = sof_to_bus(sdev); + struct hda_codec *codec; /* disable controller Wake Up event*/ snd_hdac_chip_updatew(bus, WAKEEN, STATESTS_INT_MASK, 0); + + list_for_each_codec(codec, hbus) + /* + * Wake up all jack-detecting codecs regardless whether an event + * has been recorded in STATESTS + */ + if (codec->jacktbl.used) + schedule_delayed_work(&codec->jackpoll_work, + codec->jackpoll_interval); } #else -void hda_codec_jack_check(struct snd_sof_dev *sdev, int status) {} +void hda_codec_jack_wake_enable(struct snd_sof_dev *sdev) {} +void hda_codec_jack_check(struct snd_sof_dev *sdev) {} #endif /* CONFIG_SND_SOC_SOF_HDA_AUDIO_CODEC */ +EXPORT_SYMBOL(hda_codec_jack_wake_enable); EXPORT_SYMBOL(hda_codec_jack_check); /* probe individual codec */ static int hda_codec_probe(struct snd_sof_dev *sdev, int address) { #if IS_ENABLED(CONFIG_SND_SOC_SOF_HDA_AUDIO_CODEC) - struct sof_intel_hda_dev *hda = sdev->pdata->hw_pdata; struct hdac_hda_priv *hda_priv; #endif struct hda_bus *hbus = sof_to_hbus(sdev); struct hdac_device *hdev; - u32 hda_cmd = (address << 28) | (AC_NODE_ROOT << 20) | (AC_VERB_PARAMETERS << 8) | AC_PAR_VENDOR_ID; u32 resp = -1; @@ -114,7 +116,6 @@ static int hda_codec_probe(struct snd_sof_dev *sdev, int address) /* use legacy bus only for HDA codecs, idisp uses ext bus */ if ((resp & 0xFFFF0000) != IDISP_VID_INTEL) { hdev->type = HDA_DEV_LEGACY; - hda->hda_codec_mask |= BIT(address); hda_codec_load_module(&hda_priv->codec); } diff --git a/sound/soc/sof/intel/hda-dsp.c b/sound/soc/sof/intel/hda-dsp.c index 6ce4f3dd74d146..938b4f99218837 100644 --- a/sound/soc/sof/intel/hda-dsp.c +++ b/sound/soc/sof/intel/hda-dsp.c @@ -295,10 +295,8 @@ static int hda_suspend(struct snd_sof_dev *sdev, bool runtime_suspend) hda_dsp_ipc_int_disable(sdev); #if IS_ENABLED(CONFIG_SND_SOC_SOF_HDA) - if (IS_ENABLED(CONFIG_SND_SOC_SOF_HDA_AUDIO_CODEC) && runtime_suspend) - /* enable controller wake up event */ - snd_hdac_chip_updatew(bus, WAKEEN, STATESTS_INT_MASK, - hda->hda_codec_mask); + if (runtime_suspend) + hda_codec_jack_wake_enable(sdev); /* power down all hda link */ snd_hdac_ext_bus_link_power_down_all(bus); @@ -339,7 +337,6 @@ static int hda_resume(struct snd_sof_dev *sdev, bool runtime_resume) #if IS_ENABLED(CONFIG_SND_SOC_SOF_HDA) struct hdac_bus *bus = sof_to_bus(sdev); struct hdac_ext_link *hlink = NULL; - int status; #endif int ret; @@ -349,13 +346,6 @@ static int hda_resume(struct snd_sof_dev *sdev, bool runtime_resume) */ snd_sof_pci_update_bits(sdev, PCI_TCSEL, 0x07, 0); -#if IS_ENABLED(CONFIG_SND_SOC_SOF_HDA) - if (runtime_resume) { - /* read STATESTS before controller reset */ - status = snd_hdac_chip_readw(bus, STATESTS); - } -#endif - /* reset and start hda controller */ ret = hda_dsp_ctrl_init_chip(sdev, true); if (ret < 0) { @@ -365,9 +355,9 @@ static int hda_resume(struct snd_sof_dev *sdev, bool runtime_resume) } #if IS_ENABLED(CONFIG_SND_SOC_SOF_HDA) - /* check jack status based on controller status */ + /* check jack status */ if (runtime_resume) - hda_codec_jack_check(sdev, status); + hda_codec_jack_check(sdev); /* turn off the links that were off before suspend */ list_for_each_entry(hlink, &bus->hlink_list, list) { diff --git a/sound/soc/sof/intel/hda.h b/sound/soc/sof/intel/hda.h index 3df15012279b19..aa11df4ff7f72a 100644 --- a/sound/soc/sof/intel/hda.h +++ b/sound/soc/sof/intel/hda.h @@ -398,9 +398,6 @@ struct sof_intel_hda_dev { /* DMIC device */ struct platform_device *dmic_dev; - - /* hda codec mask excluding hdmi */ - u32 hda_codec_mask; }; static inline struct hdac_bus *sof_to_bus(struct snd_sof_dev *s) @@ -558,7 +555,8 @@ void sof_hda_bus_init(struct hdac_bus *bus, struct device *dev, * HDA Codec operations. */ int hda_codec_probe_bus(struct snd_sof_dev *sdev); -void hda_codec_jack_check(struct snd_sof_dev *sdev, int status); +void hda_codec_jack_wake_enable(struct snd_sof_dev *sdev); +void hda_codec_jack_check(struct snd_sof_dev *sdev); #endif /* CONFIG_SND_SOC_SOF_HDA */