diff options
-rw-r--r-- | include/sound/sof/topology.h | 2 | ||||
-rw-r--r-- | sound/soc/sof/core.c | 6 | ||||
-rw-r--r-- | sound/soc/sof/imx/imx8.c | 2 | ||||
-rw-r--r-- | sound/soc/sof/imx/imx8m.c | 8 | ||||
-rw-r--r-- | sound/soc/sof/intel/hda.c | 10 | ||||
-rw-r--r-- | sound/soc/sof/pm.c | 19 | ||||
-rw-r--r-- | sound/soc/sof/sof-priv.h | 1 | ||||
-rw-r--r-- | sound/soc/sof/topology.c | 1 |
8 files changed, 44 insertions, 5 deletions
diff --git a/include/sound/sof/topology.h b/include/sound/sof/topology.h index 872de52b3144..f56e80d09b32 100644 --- a/include/sound/sof/topology.h +++ b/include/sound/sof/topology.h @@ -38,6 +38,7 @@ enum sof_comp_type { SOF_COMP_DEMUX, SOF_COMP_ASRC, /**< Asynchronous sample rate converter */ SOF_COMP_DCBLOCK, + SOF_COMP_SMART_AMP, /**< smart amplifier component */ /* keep FILEREAD/FILEWRITE as the last ones */ SOF_COMP_FILEREAD = 10000, /**< host test based file IO */ SOF_COMP_FILEWRITE = 10001, /**< host test based file IO */ @@ -220,6 +221,7 @@ enum sof_ipc_process_type { SOF_PROCESS_MUX, SOF_PROCESS_DEMUX, SOF_PROCESS_DCBLOCK, + SOF_PROCESS_SMART_AMP, /**< Smart Amplifier */ }; /* generic "effect", "codec" or proprietary processing component */ diff --git a/sound/soc/sof/core.c b/sound/soc/sof/core.c index ef9be4f45e27..339c4930b0c0 100644 --- a/sound/soc/sof/core.c +++ b/sound/soc/sof/core.c @@ -343,6 +343,12 @@ int snd_sof_device_remove(struct device *dev) { struct snd_sof_dev *sdev = dev_get_drvdata(dev); struct snd_sof_pdata *pdata = sdev->pdata; + int ret; + + ret = snd_sof_dsp_power_down_notify(sdev); + if (ret < 0) + dev_warn(dev, "error: %d failed to prepare DSP for device removal", + ret); if (IS_ENABLED(CONFIG_SND_SOC_SOF_PROBE_WORK_QUEUE)) cancel_work_sync(&sdev->probe_work); diff --git a/sound/soc/sof/imx/imx8.c b/sound/soc/sof/imx/imx8.c index 68b2edccd791..63f9c20a1bac 100644 --- a/sound/soc/sof/imx/imx8.c +++ b/sound/soc/sof/imx/imx8.c @@ -119,7 +119,7 @@ static void imx8_dsp_handle_request(struct imx_dsp_ipc *ipc) snd_sof_ipc_msgs_rx(priv->sdev); } -struct imx_dsp_ops dsp_ops = { +static struct imx_dsp_ops dsp_ops = { .handle_reply = imx8_dsp_handle_reply, .handle_request = imx8_dsp_handle_request, }; diff --git a/sound/soc/sof/imx/imx8m.c b/sound/soc/sof/imx/imx8m.c index 3ac0444dca93..fa86a9e2990f 100644 --- a/sound/soc/sof/imx/imx8m.c +++ b/sound/soc/sof/imx/imx8m.c @@ -92,7 +92,7 @@ static void imx8m_dsp_handle_request(struct imx_dsp_ipc *ipc) snd_sof_ipc_msgs_rx(priv->sdev); } -struct imx_dsp_ops imx8m_dsp_ops = { +static struct imx_dsp_ops imx8m_dsp_ops = { .handle_reply = imx8m_dsp_handle_reply, .handle_request = imx8m_dsp_handle_request, }; @@ -273,6 +273,12 @@ struct snd_sof_dsp_ops sof_imx8m_ops = { /* DAI drivers */ .drv = imx8m_dai, .num_drv = 1, /* we have only 1 SAI interface on i.MX8M */ + + .hw_info = SNDRV_PCM_INFO_MMAP | + SNDRV_PCM_INFO_MMAP_VALID | + SNDRV_PCM_INFO_INTERLEAVED | + SNDRV_PCM_INFO_PAUSE | + SNDRV_PCM_INFO_NO_PERIOD_WAKEUP, }; EXPORT_SYMBOL(sof_imx8m_ops); diff --git a/sound/soc/sof/intel/hda.c b/sound/soc/sof/intel/hda.c index 578ac7b036b0..63ca920c8e6e 100644 --- a/sound/soc/sof/intel/hda.c +++ b/sound/soc/sof/intel/hda.c @@ -1107,7 +1107,15 @@ static int hda_sdw_machine_select(struct snd_sof_dev *sdev) if (link_mask && !pdata->machine) { for (mach = pdata->desc->alt_machines; mach && mach->link_mask; mach++) { - if (mach->link_mask != link_mask) + /* + * On some platforms such as Up Extreme all links + * are enabled but only one link can be used by + * external codec. Instead of exact match of two masks, + * first check whether link_mask of mach is subset of + * link_mask supported by hw and then go on searching + * link_adr + */ + if (~link_mask & mach->link_mask) continue; /* No need to match adr if there is no links defined */ diff --git a/sound/soc/sof/pm.c b/sound/soc/sof/pm.c index 1f8f7e33979d..5e804a7728f5 100644 --- a/sound/soc/sof/pm.c +++ b/sound/soc/sof/pm.c @@ -90,7 +90,10 @@ static int sof_resume(struct device *dev, bool runtime_resume) int ret; /* do nothing if dsp resume callbacks are not set */ - if (!sof_ops(sdev)->resume || !sof_ops(sdev)->runtime_resume) + if (!runtime_resume && !sof_ops(sdev)->resume) + return 0; + + if (runtime_resume && !sof_ops(sdev)->runtime_resume) return 0; /* DSP was never successfully started, nothing to resume */ @@ -175,7 +178,10 @@ static int sof_suspend(struct device *dev, bool runtime_suspend) int ret; /* do nothing if dsp suspend callback is not set */ - if (!sof_ops(sdev)->suspend) + if (!runtime_suspend && !sof_ops(sdev)->suspend) + return 0; + + if (runtime_suspend && !sof_ops(sdev)->runtime_suspend) return 0; if (sdev->fw_state != SOF_FW_BOOT_COMPLETE) @@ -250,6 +256,15 @@ suspend: return ret; } +int snd_sof_dsp_power_down_notify(struct snd_sof_dev *sdev) +{ + /* Notify DSP of upcoming power down */ + if (sof_ops(sdev)->remove) + return sof_send_pm_ctx_ipc(sdev, SOF_IPC_PM_CTX_SAVE); + + return 0; +} + int snd_sof_runtime_suspend(struct device *dev) { return sof_suspend(dev, true); diff --git a/sound/soc/sof/sof-priv.h b/sound/soc/sof/sof-priv.h index a34dbae9f971..3ed39b887214 100644 --- a/sound/soc/sof/sof-priv.h +++ b/sound/soc/sof/sof-priv.h @@ -453,6 +453,7 @@ int snd_sof_runtime_resume(struct device *dev); int snd_sof_runtime_idle(struct device *dev); int snd_sof_resume(struct device *dev); int snd_sof_suspend(struct device *dev); +int snd_sof_dsp_power_down_notify(struct snd_sof_dev *sdev); int snd_sof_prepare(struct device *dev); void snd_sof_complete(struct device *dev); diff --git a/sound/soc/sof/topology.c b/sound/soc/sof/topology.c index 0259537d3740..6a9703e5ff60 100644 --- a/sound/soc/sof/topology.c +++ b/sound/soc/sof/topology.c @@ -431,6 +431,7 @@ static const struct sof_process_types sof_process[] = { {"MUX", SOF_PROCESS_MUX, SOF_COMP_MUX}, {"DEMUX", SOF_PROCESS_DEMUX, SOF_COMP_DEMUX}, {"DCBLOCK", SOF_PROCESS_DCBLOCK, SOF_COMP_DCBLOCK}, + {"SMART_AMP", SOF_PROCESS_SMART_AMP, SOF_COMP_SMART_AMP}, }; static enum sof_ipc_process_type find_process(const char *name) |