diff --git a/sound/soc/sof/intel/hda-codec.c b/sound/soc/sof/intel/hda-codec.c index 5882f1bfd906ca..3ca6795a89ba3a 100644 --- a/sound/soc/sof/intel/hda-codec.c +++ b/sound/soc/sof/intel/hda-codec.c @@ -38,55 +38,55 @@ static void hda_codec_load_module(struct hda_codec *codec) static void hda_codec_load_module(struct hda_codec *codec) {} #endif +/* enable controller wake up event for all codecs with jack connectors */ +void hda_codec_jack_wake_enable(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; + unsigned int mask = 0; + + list_for_each_codec(codec, hbus) + 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, int status) +void hda_codec_jack_check(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; + + /* disable controller Wake Up event*/ + snd_hdac_chip_updatew(bus, WAKEEN, STATESTS_INT_MASK, 0); list_for_each_codec(codec, hbus) - if (mask & BIT(codec->core.addr)) + /* + * 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); - - /* disable controller Wake Up event*/ - snd_hdac_chip_writew(bus, WAKEEN, - snd_hdac_chip_readw(bus, WAKEEN) & - ~hda->hda_codec_mask); } #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; @@ -116,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 fe143bb000e373..938b4f99218837 100644 --- a/sound/soc/sof/intel/hda-dsp.c +++ b/sound/soc/sof/intel/hda-dsp.c @@ -295,11 +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_writew(bus, WAKEEN, - snd_hdac_chip_readw(bus, WAKEEN) | - 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); @@ -340,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; @@ -350,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) { @@ -366,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 */