diff options
-rw-r--r-- | sound/soc/codecs/lochnagar-sc.c | 2 | ||||
-rw-r--r-- | sound/soc/codecs/rt5670.c | 2 | ||||
-rw-r--r-- | sound/soc/codecs/wm8994.c | 5 | ||||
-rw-r--r-- | sound/soc/intel/boards/bytcr_rt5640.c | 25 | ||||
-rw-r--r-- | sound/soc/intel/common/soc-acpi-intel-rpl-match.c | 2 | ||||
-rw-r--r-- | sound/soc/mediatek/mt8195/mt8195-mt6359.c | 30 | ||||
-rw-r--r-- | sound/soc/rockchip/rockchip_spdif.c | 1 | ||||
-rw-r--r-- | sound/soc/sof/core.c | 9 | ||||
-rw-r--r-- | sound/soc/sof/intel/hda-dsp.c | 72 | ||||
-rw-r--r-- | sound/soc/sof/intel/hda.h | 1 | ||||
-rw-r--r-- | sound/soc/sof/intel/tgl.c | 2 | ||||
-rw-r--r-- | sound/soc/sof/mediatek/mtk-adsp-common.c | 2 |
12 files changed, 138 insertions, 15 deletions
diff --git a/sound/soc/codecs/lochnagar-sc.c b/sound/soc/codecs/lochnagar-sc.c index 13fbd8830b09..5e0bd0d24ed3 100644 --- a/sound/soc/codecs/lochnagar-sc.c +++ b/sound/soc/codecs/lochnagar-sc.c @@ -253,7 +253,7 @@ MODULE_DEVICE_TABLE(of, lochnagar_of_match); static struct platform_driver lochnagar_sc_codec_driver = { .driver = { .name = "lochnagar-soundcard", - .of_match_table = of_match_ptr(lochnagar_of_match), + .of_match_table = lochnagar_of_match, }, .probe = lochnagar_sc_probe, diff --git a/sound/soc/codecs/rt5670.c b/sound/soc/codecs/rt5670.c index ebac6caeb40a..a230f441559a 100644 --- a/sound/soc/codecs/rt5670.c +++ b/sound/soc/codecs/rt5670.c @@ -3311,8 +3311,6 @@ static int rt5670_i2c_probe(struct i2c_client *i2c) if (ret < 0) goto err; - pm_runtime_put(&i2c->dev); - return 0; err: pm_runtime_disable(&i2c->dev); diff --git a/sound/soc/codecs/wm8994.c b/sound/soc/codecs/wm8994.c index d3cfd3788f2a..8fe9a75d1235 100644 --- a/sound/soc/codecs/wm8994.c +++ b/sound/soc/codecs/wm8994.c @@ -3853,7 +3853,12 @@ static irqreturn_t wm1811_jackdet_irq(int irq, void *data) } else { dev_dbg(component->dev, "Jack not detected\n"); + /* Release wm8994->accdet_lock to avoid deadlock: + * cancel_delayed_work_sync() takes wm8994->mic_work internal + * lock and wm1811_mic_work takes wm8994->accdet_lock */ + mutex_unlock(&wm8994->accdet_lock); cancel_delayed_work_sync(&wm8994->mic_work); + mutex_lock(&wm8994->accdet_lock); snd_soc_component_update_bits(component, WM8958_MICBIAS2, WM8958_MICB2_DISCH, WM8958_MICB2_DISCH); diff --git a/sound/soc/intel/boards/bytcr_rt5640.c b/sound/soc/intel/boards/bytcr_rt5640.c index 6db07b2417ca..4699ca79f3ea 100644 --- a/sound/soc/intel/boards/bytcr_rt5640.c +++ b/sound/soc/intel/boards/bytcr_rt5640.c @@ -571,6 +571,21 @@ static const struct dmi_system_id byt_rt5640_quirk_table[] = { BYT_RT5640_MCLK_EN), }, { + /* Advantech MICA-071 */ + .matches = { + DMI_EXACT_MATCH(DMI_SYS_VENDOR, "Advantech"), + DMI_EXACT_MATCH(DMI_PRODUCT_NAME, "MICA-071"), + }, + /* OVCD Th = 1500uA to reliable detect head-phones vs -set */ + .driver_data = (void *)(BYT_RT5640_IN3_MAP | + BYT_RT5640_JD_SRC_JD2_IN4N | + BYT_RT5640_OVCD_TH_1500UA | + BYT_RT5640_OVCD_SF_0P75 | + BYT_RT5640_MONO_SPEAKER | + BYT_RT5640_DIFF_MIC | + BYT_RT5640_MCLK_EN), + }, + { .matches = { DMI_EXACT_MATCH(DMI_SYS_VENDOR, "ARCHOS"), DMI_EXACT_MATCH(DMI_PRODUCT_NAME, "ARCHOS 80 Cesium"), @@ -796,6 +811,16 @@ static const struct dmi_system_id byt_rt5640_quirk_table[] = { BYT_RT5640_SSP0_AIF1 | BYT_RT5640_MCLK_EN), }, + { /* HP Stream 8 */ + .matches = { + DMI_EXACT_MATCH(DMI_SYS_VENDOR, "Hewlett-Packard"), + DMI_EXACT_MATCH(DMI_PRODUCT_NAME, "HP Stream 8 Tablet"), + }, + .driver_data = (void *)(BYTCR_INPUT_DEFAULTS | + BYT_RT5640_JD_NOT_INV | + BYT_RT5640_SSP0_AIF1 | + BYT_RT5640_MCLK_EN), + }, { /* I.T.Works TW891 */ .matches = { DMI_EXACT_MATCH(DMI_SYS_VENDOR, "To be filled by O.E.M."), diff --git a/sound/soc/intel/common/soc-acpi-intel-rpl-match.c b/sound/soc/intel/common/soc-acpi-intel-rpl-match.c index 3c5229f41bb0..31b43116e3d8 100644 --- a/sound/soc/intel/common/soc-acpi-intel-rpl-match.c +++ b/sound/soc/intel/common/soc-acpi-intel-rpl-match.c @@ -112,7 +112,7 @@ static const struct snd_soc_acpi_adr_device rt1316_1_group2_adr[] = { static const struct snd_soc_acpi_adr_device rt1318_1_group1_adr[] = { { - .adr = 0x000131025D131801ull, + .adr = 0x000132025D131801ull, .num_endpoints = 1, .endpoints = &spk_l_endpoint, .name_prefix = "rt1318-1" diff --git a/sound/soc/mediatek/mt8195/mt8195-mt6359.c b/sound/soc/mediatek/mt8195/mt8195-mt6359.c index 61be66f47723..4682748d82be 100644 --- a/sound/soc/mediatek/mt8195/mt8195-mt6359.c +++ b/sound/soc/mediatek/mt8195/mt8195-mt6359.c @@ -633,6 +633,32 @@ static const struct snd_soc_ops mt8195_rt1011_etdm_ops = { .hw_params = mt8195_rt1011_etdm_hw_params, }; +static int mt8195_sof_be_hw_params(struct snd_pcm_substream *substream, + struct snd_pcm_hw_params *params) +{ + struct snd_soc_pcm_runtime *rtd = asoc_substream_to_rtd(substream); + struct snd_soc_component *cmpnt_afe = NULL; + struct snd_soc_pcm_runtime *runtime; + + /* find afe component */ + for_each_card_rtds(rtd->card, runtime) { + cmpnt_afe = snd_soc_rtdcom_lookup(runtime, AFE_PCM_NAME); + if (cmpnt_afe) + break; + } + + if (cmpnt_afe && !pm_runtime_active(cmpnt_afe->dev)) { + dev_err(rtd->dev, "afe pm runtime is not active!!\n"); + return -EINVAL; + } + + return 0; +} + +static const struct snd_soc_ops mt8195_sof_be_ops = { + .hw_params = mt8195_sof_be_hw_params, +}; + static int mt8195_rt1011_init(struct snd_soc_pcm_runtime *rtd) { struct snd_soc_card *card = rtd->card; @@ -1272,24 +1298,28 @@ static struct snd_soc_dai_link mt8195_mt6359_dai_links[] = { .name = "AFE_SOF_DL2", .no_pcm = 1, .dpcm_playback = 1, + .ops = &mt8195_sof_be_ops, SND_SOC_DAILINK_REG(AFE_SOF_DL2), }, [DAI_LINK_SOF_DL3_BE] = { .name = "AFE_SOF_DL3", .no_pcm = 1, .dpcm_playback = 1, + .ops = &mt8195_sof_be_ops, SND_SOC_DAILINK_REG(AFE_SOF_DL3), }, [DAI_LINK_SOF_UL4_BE] = { .name = "AFE_SOF_UL4", .no_pcm = 1, .dpcm_capture = 1, + .ops = &mt8195_sof_be_ops, SND_SOC_DAILINK_REG(AFE_SOF_UL4), }, [DAI_LINK_SOF_UL5_BE] = { .name = "AFE_SOF_UL5", .no_pcm = 1, .dpcm_capture = 1, + .ops = &mt8195_sof_be_ops, SND_SOC_DAILINK_REG(AFE_SOF_UL5), }, }; diff --git a/sound/soc/rockchip/rockchip_spdif.c b/sound/soc/rockchip/rockchip_spdif.c index 8bef572d3cbc..5b4f00457587 100644 --- a/sound/soc/rockchip/rockchip_spdif.c +++ b/sound/soc/rockchip/rockchip_spdif.c @@ -88,6 +88,7 @@ static int __maybe_unused rk_spdif_runtime_resume(struct device *dev) ret = clk_prepare_enable(spdif->hclk); if (ret) { + clk_disable_unprepare(spdif->mclk); dev_err(spdif->dev, "hclk clock enable failed %d\n", ret); return ret; } diff --git a/sound/soc/sof/core.c b/sound/soc/sof/core.c index 3e6141d03770..625977a29d8a 100644 --- a/sound/soc/sof/core.c +++ b/sound/soc/sof/core.c @@ -475,19 +475,10 @@ EXPORT_SYMBOL(snd_sof_device_remove); int snd_sof_device_shutdown(struct device *dev) { struct snd_sof_dev *sdev = dev_get_drvdata(dev); - struct snd_sof_pdata *pdata = sdev->pdata; if (IS_ENABLED(CONFIG_SND_SOC_SOF_PROBE_WORK_QUEUE)) cancel_work_sync(&sdev->probe_work); - /* - * make sure clients and machine driver(s) are unregistered to force - * all userspace devices to be closed prior to the DSP shutdown sequence - */ - sof_unregister_clients(sdev); - - snd_sof_machine_unregister(sdev, pdata); - if (sdev->fw_state == SOF_FW_BOOT_COMPLETE) return snd_sof_shutdown(sdev); diff --git a/sound/soc/sof/intel/hda-dsp.c b/sound/soc/sof/intel/hda-dsp.c index 5fa29df54b42..b4eacae8564c 100644 --- a/sound/soc/sof/intel/hda-dsp.c +++ b/sound/soc/sof/intel/hda-dsp.c @@ -878,6 +878,78 @@ int hda_dsp_suspend(struct snd_sof_dev *sdev, u32 target_state) return snd_sof_dsp_set_power_state(sdev, &target_dsp_state); } +static unsigned int hda_dsp_check_for_dma_streams(struct snd_sof_dev *sdev) +{ + struct hdac_bus *bus = sof_to_bus(sdev); + struct hdac_stream *s; + unsigned int active_streams = 0; + int sd_offset; + u32 val; + + list_for_each_entry(s, &bus->stream_list, list) { + sd_offset = SOF_STREAM_SD_OFFSET(s); + val = snd_sof_dsp_read(sdev, HDA_DSP_HDA_BAR, + sd_offset); + if (val & SOF_HDA_SD_CTL_DMA_START) + active_streams |= BIT(s->index); + } + + return active_streams; +} + +static int hda_dsp_s5_quirk(struct snd_sof_dev *sdev) +{ + int ret; + + /* + * Do not assume a certain timing between the prior + * suspend flow, and running of this quirk function. + * This is needed if the controller was just put + * to reset before calling this function. + */ + usleep_range(500, 1000); + + /* + * Take controller out of reset to flush DMA + * transactions. + */ + ret = hda_dsp_ctrl_link_reset(sdev, false); + if (ret < 0) + return ret; + + usleep_range(500, 1000); + + /* Restore state for shutdown, back to reset */ + ret = hda_dsp_ctrl_link_reset(sdev, true); + if (ret < 0) + return ret; + + return ret; +} + +int hda_dsp_shutdown_dma_flush(struct snd_sof_dev *sdev) +{ + unsigned int active_streams; + int ret, ret2; + + /* check if DMA cleanup has been successful */ + active_streams = hda_dsp_check_for_dma_streams(sdev); + + sdev->system_suspend_target = SOF_SUSPEND_S3; + ret = snd_sof_suspend(sdev->dev); + + if (active_streams) { + dev_warn(sdev->dev, + "There were active DSP streams (%#x) at shutdown, trying to recover\n", + active_streams); + ret2 = hda_dsp_s5_quirk(sdev); + if (ret2 < 0) + dev_err(sdev->dev, "shutdown recovery failed (%d)\n", ret2); + } + + return ret; +} + int hda_dsp_shutdown(struct snd_sof_dev *sdev) { sdev->system_suspend_target = SOF_SUSPEND_S3; diff --git a/sound/soc/sof/intel/hda.h b/sound/soc/sof/intel/hda.h index 022ce80968dd..caccaf8fba9c 100644 --- a/sound/soc/sof/intel/hda.h +++ b/sound/soc/sof/intel/hda.h @@ -592,6 +592,7 @@ int hda_dsp_resume(struct snd_sof_dev *sdev); int hda_dsp_runtime_suspend(struct snd_sof_dev *sdev); int hda_dsp_runtime_resume(struct snd_sof_dev *sdev); int hda_dsp_runtime_idle(struct snd_sof_dev *sdev); +int hda_dsp_shutdown_dma_flush(struct snd_sof_dev *sdev); int hda_dsp_shutdown(struct snd_sof_dev *sdev); int hda_dsp_set_hw_params_upon_resume(struct snd_sof_dev *sdev); void hda_dsp_dump(struct snd_sof_dev *sdev, u32 flags); diff --git a/sound/soc/sof/intel/tgl.c b/sound/soc/sof/intel/tgl.c index 30f2f49ee149..58ac3a46e6a7 100644 --- a/sound/soc/sof/intel/tgl.c +++ b/sound/soc/sof/intel/tgl.c @@ -60,7 +60,7 @@ int sof_tgl_ops_init(struct snd_sof_dev *sdev) memcpy(&sof_tgl_ops, &sof_hda_common_ops, sizeof(struct snd_sof_dsp_ops)); /* probe/remove/shutdown */ - sof_tgl_ops.shutdown = hda_dsp_shutdown; + sof_tgl_ops.shutdown = hda_dsp_shutdown_dma_flush; if (sdev->pdata->ipc_type == SOF_IPC) { /* doorbell */ diff --git a/sound/soc/sof/mediatek/mtk-adsp-common.c b/sound/soc/sof/mediatek/mtk-adsp-common.c index 1e0769c668a7..de8dbe27cd0d 100644 --- a/sound/soc/sof/mediatek/mtk-adsp-common.c +++ b/sound/soc/sof/mediatek/mtk-adsp-common.c @@ -60,7 +60,7 @@ void mtk_adsp_dump(struct snd_sof_dev *sdev, u32 flags) { char *level = (flags & SOF_DBG_DUMP_OPTIONAL) ? KERN_DEBUG : KERN_ERR; struct sof_ipc_dsp_oops_xtensa xoops; - struct sof_ipc_panic_info panic_info; + struct sof_ipc_panic_info panic_info = {}; u32 stack[MTK_ADSP_STACK_DUMP_SIZE]; u32 status; |