summaryrefslogtreecommitdiffstats
path: root/sound/soc/sof/intel/hda-dsp.c
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2019-09-17 17:43:33 -0700
committerLinus Torvalds <torvalds@linux-foundation.org>2019-09-17 17:43:33 -0700
commit6ab8ad31601f29470eb895fd95e5c963e125aa1b (patch)
tree73327fe9fc2ee62e7815fa0a666fdf46aaab7322 /sound/soc/sof/intel/hda-dsp.c
parentea982ba7f79141d86eb7a440fcba6796ed718b9b (diff)
parent9bf9bf5440b99edfba496388c90b52ebcd9df715 (diff)
downloadlinux-6ab8ad31601f29470eb895fd95e5c963e125aa1b.tar.bz2
Merge tag 'sound-5.4-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/tiwai/sound
Pull sound updates from Takashi Iwai: "As shown in diffstat and logs, it was again a busy development cycle at this time, too. The most significant changes are still on-going refactoring / modernization works for ASoC core and drivers, but there are lots of other changes as well. Here we go, some highlights below: ASoC: - Quite a lot of cleanup / refactoring of ASoC core and APIs; most of them are systematic, but also including cleanups and modernization - A bulk of updates for some ASoC platforms, Freescale, sunxi and Intel SST/SOF - Initial support for Sound Open Firmware on i.MX8 - Removal of deprecated w90x900 and nuc900 drivers - New support for Cirrus Logic CS47L15 and CS47L92, Freescale i.MX 7ULP and 8MQ, Meson G12A and NXP UDA1334 USB-audio: - More validations of descriptor units for hardening against bugs reported by fuzzers - PCM device assignment workaround for a past call-order change - Scarlett Gen2 mixer interface, a few more more quirks HD-audio: - Support for audio component with AMD/ATI and Nvidia HDMI codecs - Clean up HD-audio core and remove indirect access ops for Intel SOF - DMIC detection at probe; it would make systems automatically falling back to SST/SOF driver on devices that need DMIC handling. Needs a new Kconfig to set, and beware that it's still new and a bit experimental FireWire: - Lots of code refactoring and cleanups" * tag 'sound-5.4-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/tiwai/sound: (521 commits) ASoC: sdm845: remove unneeded semicolon ASoC: fsl_sai: Implement set_bclk_ratio ASoC: dmaengine: Replace strncpy() with strscpy_pad() for pcm->name ASoC: wcd9335: remove redundant use of ret variable ALSA: firewire-tascam: check intermediate state of clock status and retry ALSA: firewire-tascam: handle error code when getting current source of clock ASoC: hdmi-codec: Add an op to set callback function for plug event ASoC: rt5677: keep analog power register at SND_SOC_BIAS_OFF ASoC: rt5677: Remove magic number register writes ASoC: soc-core: self contained soc_unbind_aux_dev() ASoC: soc-core: add soc_unbind_aux_dev() ASoC: soc-core: self contained soc_bind_aux_dev() ASoC: soc-core: move soc_probe_link_dais() next to soc_remove_link_dais() ASoC: soc-core: self contained soc_probe_link_dais() ASoC: soc-core: add new soc_link_init() ASoC: soc-core: move soc_probe_dai() next to soc_remove_dai() ASoC: soc-core: self contained soc_remove_link_dais() ASoC: soc-core: self contained soc_remove_link_components() ASoC: soc-core: self contained soc_probe_link_components() ASoC: rt1308: make array pd static const, makes object smaller ...
Diffstat (limited to 'sound/soc/sof/intel/hda-dsp.c')
-rw-r--r--sound/soc/sof/intel/hda-dsp.c100
1 files changed, 35 insertions, 65 deletions
diff --git a/sound/soc/sof/intel/hda-dsp.c b/sound/soc/sof/intel/hda-dsp.c
index 91de4785b6a3..fb55a3c5afd0 100644
--- a/sound/soc/sof/intel/hda-dsp.c
+++ b/sound/soc/sof/intel/hda-dsp.c
@@ -282,7 +282,7 @@ void hda_dsp_ipc_int_disable(struct snd_sof_dev *sdev)
HDA_DSP_REG_HIPCCTL_BUSY | HDA_DSP_REG_HIPCCTL_DONE, 0);
}
-static int hda_suspend(struct snd_sof_dev *sdev, int state)
+static int hda_suspend(struct snd_sof_dev *sdev, bool runtime_suspend)
{
struct sof_intel_hda_dev *hda = sdev->pdata->hw_pdata;
const struct sof_intel_dsp_desc *chip = hda->desc;
@@ -295,6 +295,9 @@ static int hda_suspend(struct snd_sof_dev *sdev, int state)
hda_dsp_ipc_int_disable(sdev);
#if IS_ENABLED(CONFIG_SND_SOC_SOF_HDA)
+ if (runtime_suspend)
+ hda_codec_jack_wake_enable(sdev);
+
/* power down all hda link */
snd_hdac_ext_bus_link_power_down_all(bus);
#endif
@@ -329,7 +332,7 @@ static int hda_suspend(struct snd_sof_dev *sdev, int state)
return 0;
}
-static int hda_resume(struct snd_sof_dev *sdev)
+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);
@@ -343,7 +346,6 @@ static int hda_resume(struct snd_sof_dev *sdev)
*/
snd_sof_pci_update_bits(sdev, PCI_TCSEL, 0x07, 0);
-#if IS_ENABLED(CONFIG_SND_SOC_SOF_HDA)
/* reset and start hda controller */
ret = hda_dsp_ctrl_init_chip(sdev, true);
if (ret < 0) {
@@ -352,46 +354,11 @@ static int hda_resume(struct snd_sof_dev *sdev)
return ret;
}
- hda_dsp_ctrl_misc_clock_gating(sdev, false);
-
- /* Reset stream-to-link mapping */
- list_for_each_entry(hlink, &bus->hlink_list, list)
- bus->io_ops->reg_writel(0, hlink->ml_addr + AZX_REG_ML_LOSIDV);
-
- hda_dsp_ctrl_misc_clock_gating(sdev, true);
-#else
-
- hda_dsp_ctrl_misc_clock_gating(sdev, false);
-
- /* reset controller */
- ret = hda_dsp_ctrl_link_reset(sdev, true);
- if (ret < 0) {
- dev_err(sdev->dev,
- "error: failed to reset controller during resume\n");
- return ret;
- }
-
- /* take controller out of reset */
- ret = hda_dsp_ctrl_link_reset(sdev, false);
- if (ret < 0) {
- dev_err(sdev->dev,
- "error: failed to ready controller during resume\n");
- return ret;
- }
-
- /* enable hda bus irq */
- snd_sof_dsp_update_bits(sdev, HDA_DSP_HDA_BAR, SOF_HDA_INTCTL,
- SOF_HDA_INT_CTRL_EN | SOF_HDA_INT_GLOBAL_EN,
- SOF_HDA_INT_CTRL_EN | SOF_HDA_INT_GLOBAL_EN);
-
- hda_dsp_ctrl_misc_clock_gating(sdev, true);
-#endif
-
- /* enable ppcap interrupt */
- hda_dsp_ctrl_ppcap_enable(sdev, true);
- hda_dsp_ctrl_ppcap_int_enable(sdev, true);
-
#if IS_ENABLED(CONFIG_SND_SOC_SOF_HDA)
+ /* check jack status */
+ if (runtime_resume)
+ hda_codec_jack_check(sdev);
+
/* turn off the links that were off before suspend */
list_for_each_entry(hlink, &bus->hlink_list, list) {
if (!hlink->ref_count)
@@ -403,19 +370,23 @@ static int hda_resume(struct snd_sof_dev *sdev)
snd_hdac_bus_stop_cmd_io(bus);
#endif
+ /* enable ppcap interrupt */
+ hda_dsp_ctrl_ppcap_enable(sdev, true);
+ hda_dsp_ctrl_ppcap_int_enable(sdev, true);
+
return 0;
}
int hda_dsp_resume(struct snd_sof_dev *sdev)
{
/* init hda controller. DSP cores will be powered up during fw boot */
- return hda_resume(sdev);
+ return hda_resume(sdev, false);
}
int hda_dsp_runtime_resume(struct snd_sof_dev *sdev)
{
/* init hda controller. DSP cores will be powered up during fw boot */
- return hda_resume(sdev);
+ return hda_resume(sdev, true);
}
int hda_dsp_runtime_idle(struct snd_sof_dev *sdev)
@@ -431,19 +402,19 @@ int hda_dsp_runtime_idle(struct snd_sof_dev *sdev)
return 0;
}
-int hda_dsp_runtime_suspend(struct snd_sof_dev *sdev, int state)
+int hda_dsp_runtime_suspend(struct snd_sof_dev *sdev)
{
/* stop hda controller and power dsp off */
- return hda_suspend(sdev, state);
+ return hda_suspend(sdev, true);
}
-int hda_dsp_suspend(struct snd_sof_dev *sdev, int state)
+int hda_dsp_suspend(struct snd_sof_dev *sdev)
{
struct hdac_bus *bus = sof_to_bus(sdev);
int ret;
/* stop hda controller and power dsp off */
- ret = hda_suspend(sdev, state);
+ ret = hda_suspend(sdev, false);
if (ret < 0) {
dev_err(bus->dev, "error: suspending dsp\n");
return ret;
@@ -454,30 +425,24 @@ int hda_dsp_suspend(struct snd_sof_dev *sdev, int state)
int hda_dsp_set_hw_params_upon_resume(struct snd_sof_dev *sdev)
{
- struct hdac_bus *bus = sof_to_bus(sdev);
- struct sof_intel_hda_stream *hda_stream;
- struct hdac_ext_stream *stream;
- struct hdac_stream *s;
-
#if IS_ENABLED(CONFIG_SND_SOC_SOF_HDA)
+ struct hdac_bus *bus = sof_to_bus(sdev);
struct snd_soc_pcm_runtime *rtd;
+ struct hdac_ext_stream *stream;
struct hdac_ext_link *link;
+ struct hdac_stream *s;
const char *name;
int stream_tag;
-#endif
/* set internal flag for BE */
list_for_each_entry(s, &bus->stream_list, list) {
stream = stream_to_hdac_ext_stream(s);
- hda_stream = container_of(stream, struct sof_intel_hda_stream,
- hda_stream);
- hda_stream->hw_params_upon_resume = 1;
-#if IS_ENABLED(CONFIG_SND_SOC_SOF_HDA)
+
/*
- * clear and release stream. This should already be taken care
- * for running streams when the SUSPEND trigger is called.
- * But paused streams do not get suspended, so this needs to be
- * done explicitly during suspend.
+ * clear stream. This should already be taken care for running
+ * streams when the SUSPEND trigger is called. But paused
+ * streams do not get suspended, so this needs to be done
+ * explicitly during suspend.
*/
if (stream->link_substream) {
rtd = snd_pcm_substream_chip(stream->link_substream);
@@ -485,12 +450,17 @@ int hda_dsp_set_hw_params_upon_resume(struct snd_sof_dev *sdev)
link = snd_hdac_ext_bus_get_link(bus, name);
if (!link)
return -EINVAL;
+
+ stream->link_prepared = 0;
+
+ if (hdac_stream(stream)->direction ==
+ SNDRV_PCM_STREAM_CAPTURE)
+ continue;
+
stream_tag = hdac_stream(stream)->stream_tag;
snd_hdac_ext_link_clear_stream_id(link, stream_tag);
- snd_hdac_ext_stream_release(stream,
- HDAC_EXT_STREAM_TYPE_LINK);
}
-#endif
}
+#endif
return 0;
}