From 5610921a4435ef45c33702073e64f835f3dca7f1 Mon Sep 17 00:00:00 2001 From: Mateusz Gorski Date: Wed, 22 Jul 2020 19:35:24 +0200 Subject: ASoC: Intel: skl_hda_dsp_generic: Fix NULLptr dereference in autosuspend delay Different modules for HDMI codec are used depending on the "hda_codec_use_common_hdmi" option being enabled or not. Driver private context for both of them is different. This leads to null-pointer dereference error when driver tries to set autosuspend delay for HDMI codec while the option is off (hdac_hdmi module is used for HDMI). Change the string in conditional statement to "ehdaudio0D0" to ensure that only the HDAudio codec is handled by this function. Fixes: 5bf73b1b1dec ("ASoC: intel/skl/hda - fix oops on systems without i915 audio codec") Signed-off-by: Mateusz Gorski Reviewed-by: Kai Vehmanen Link: https://lore.kernel.org/r/20200722173524.30161-1-mateusz.gorski@linux.intel.com Signed-off-by: Mark Brown --- sound/soc/intel/boards/skl_hda_dsp_generic.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'sound') diff --git a/sound/soc/intel/boards/skl_hda_dsp_generic.c b/sound/soc/intel/boards/skl_hda_dsp_generic.c index ca4900036ead..bc50eda297ab 100644 --- a/sound/soc/intel/boards/skl_hda_dsp_generic.c +++ b/sound/soc/intel/boards/skl_hda_dsp_generic.c @@ -181,7 +181,7 @@ static void skl_set_hda_codec_autosuspend_delay(struct snd_soc_card *card) struct snd_soc_dai *dai; for_each_card_rtds(card, rtd) { - if (!strstr(rtd->dai_link->codecs->name, "ehdaudio")) + if (!strstr(rtd->dai_link->codecs->name, "ehdaudio0D0")) continue; dai = asoc_rtd_to_codec(rtd, 0); hda_pvt = snd_soc_component_get_drvdata(dai->component); -- cgit From 5e7820e369248f880767c4c4079b414529bc2125 Mon Sep 17 00:00:00 2001 From: Brent Lu Date: Fri, 31 Jul 2020 20:26:04 +0800 Subject: ASoC: intel: atom: Add period size constraint Use constraint to make sure the period size could always be multiple of 1ms to align with the fundamental design/limitation of firmware. Signed-off-by: Brent Lu Link: https://lore.kernel.org/r/1596198365-10105-2-git-send-email-brent.lu@intel.com Signed-off-by: Mark Brown --- sound/soc/intel/atom/sst-mfld-platform-pcm.c | 11 +++++++++++ 1 file changed, 11 insertions(+) (limited to 'sound') diff --git a/sound/soc/intel/atom/sst-mfld-platform-pcm.c b/sound/soc/intel/atom/sst-mfld-platform-pcm.c index b1cac7abdc0a..fba2c795ce0d 100644 --- a/sound/soc/intel/atom/sst-mfld-platform-pcm.c +++ b/sound/soc/intel/atom/sst-mfld-platform-pcm.c @@ -333,6 +333,17 @@ static int sst_media_open(struct snd_pcm_substream *substream, if (ret_val < 0) goto out_power_up; + /* + * Make sure the period to be multiple of 1ms to align the + * design of firmware. Apply same rule to buffer size to make + * sure alsa could always find a value for period size + * regardless the buffer size given by user space. + */ + snd_pcm_hw_constraint_step(substream->runtime, 0, + SNDRV_PCM_HW_PARAM_PERIOD_SIZE, 48); + snd_pcm_hw_constraint_step(substream->runtime, 0, + SNDRV_PCM_HW_PARAM_BUFFER_SIZE, 48); + /* Make sure, that the period size is always even */ snd_pcm_hw_constraint_step(substream->runtime, 0, SNDRV_PCM_HW_PARAM_PERIODS, 2); -- cgit From 3c27ea23ffb43262da6c64964163895951aaed4e Mon Sep 17 00:00:00 2001 From: Stephan Gerhold Date: Thu, 20 Aug 2020 17:45:11 +0200 Subject: ASoC: qcom: Set card->owner to avoid warnings On Linux 5.9-rc1 I get the following warning with apq8016-sbc: WARNING: CPU: 2 PID: 69 at sound/core/init.c:207 snd_card_new+0x36c/0x3b0 [snd] CPU: 2 PID: 69 Comm: kworker/2:1 Not tainted 5.9.0-rc1 #1 Workqueue: events deferred_probe_work_func pc : snd_card_new+0x36c/0x3b0 [snd] lr : snd_card_new+0xf4/0x3b0 [snd] Call trace: snd_card_new+0x36c/0x3b0 [snd] snd_soc_bind_card+0x340/0x9a0 [snd_soc_core] snd_soc_register_card+0xf4/0x110 [snd_soc_core] devm_snd_soc_register_card+0x44/0xa0 [snd_soc_core] apq8016_sbc_platform_probe+0x11c/0x140 [snd_soc_apq8016_sbc] This warning was introduced in commit 81033c6b584b ("ALSA: core: Warn on empty module"). It looks like we are supposed to set card->owner to THIS_MODULE. Fix this for all the qcom ASoC drivers. Cc: Srinivas Kandagatla Fixes: 79119c798649 ("ASoC: qcom: Add Storm machine driver") Fixes: bdb052e81f62 ("ASoC: qcom: add apq8016 sound card support") Fixes: a6f933f63f2f ("ASoC: qcom: apq8096: Add db820c machine driver") Fixes: 6b1687bf76ef ("ASoC: qcom: add sdm845 sound card support") Signed-off-by: Stephan Gerhold Link: https://lore.kernel.org/r/20200820154511.203072-1-stephan@gerhold.net Signed-off-by: Mark Brown --- sound/soc/qcom/apq8016_sbc.c | 1 + sound/soc/qcom/apq8096.c | 1 + sound/soc/qcom/sdm845.c | 1 + sound/soc/qcom/storm.c | 1 + 4 files changed, 4 insertions(+) (limited to 'sound') diff --git a/sound/soc/qcom/apq8016_sbc.c b/sound/soc/qcom/apq8016_sbc.c index 083413abc2f6..575e2aefefe3 100644 --- a/sound/soc/qcom/apq8016_sbc.c +++ b/sound/soc/qcom/apq8016_sbc.c @@ -143,6 +143,7 @@ static int apq8016_sbc_platform_probe(struct platform_device *pdev) card = &data->card; card->dev = dev; + card->owner = THIS_MODULE; card->dapm_widgets = apq8016_sbc_dapm_widgets; card->num_dapm_widgets = ARRAY_SIZE(apq8016_sbc_dapm_widgets); diff --git a/sound/soc/qcom/apq8096.c b/sound/soc/qcom/apq8096.c index 253549600c5a..1a69baefc5ce 100644 --- a/sound/soc/qcom/apq8096.c +++ b/sound/soc/qcom/apq8096.c @@ -114,6 +114,7 @@ static int apq8096_platform_probe(struct platform_device *pdev) return -ENOMEM; card->dev = dev; + card->owner = THIS_MODULE; dev_set_drvdata(dev, card); ret = qcom_snd_parse_of(card); if (ret) diff --git a/sound/soc/qcom/sdm845.c b/sound/soc/qcom/sdm845.c index 0d10fba53945..ab1bf23c21a6 100644 --- a/sound/soc/qcom/sdm845.c +++ b/sound/soc/qcom/sdm845.c @@ -555,6 +555,7 @@ static int sdm845_snd_platform_probe(struct platform_device *pdev) card->dapm_widgets = sdm845_snd_widgets; card->num_dapm_widgets = ARRAY_SIZE(sdm845_snd_widgets); card->dev = dev; + card->owner = THIS_MODULE; dev_set_drvdata(dev, card); ret = qcom_snd_parse_of(card); if (ret) diff --git a/sound/soc/qcom/storm.c b/sound/soc/qcom/storm.c index c0c388d4db82..80c9cf2f254a 100644 --- a/sound/soc/qcom/storm.c +++ b/sound/soc/qcom/storm.c @@ -96,6 +96,7 @@ static int storm_platform_probe(struct platform_device *pdev) return -ENOMEM; card->dev = &pdev->dev; + card->owner = THIS_MODULE; ret = snd_soc_of_parse_card_name(card, "qcom,model"); if (ret) { -- cgit From 0235bc04627d02a08f7ad9d226a8fe78e6c4a1c3 Mon Sep 17 00:00:00 2001 From: Rander Wang Date: Fri, 21 Aug 2020 14:55:53 -0500 Subject: ASoC: Intel: tgl_max98373: fix a runtime pm issue in multi-thread case When the playback & capture streams are stopped simultaneously, the SOF PCI device will remain pm_runtime active. The root-cause is a race condition with two threads reaching the trigger function at the same time. They see another stream is active so the dapm pin is not disabled, so the codec remains active as well as the parent PCI device. For max98373, the capture stream provides feedback when playback is working and it is unused when playback is stopped. So the dapm pin should be set only when playback is active. Fixes: 94d2d08974746 ('ASoC: Intel: Boards: tgl_max98373: add dai_trigger function') Reviewed-by: Ranjani Sridharan Signed-off-by: Rander Wang Signed-off-by: Pierre-Louis Bossart Link: https://lore.kernel.org/r/20200821195603.215535-7-pierre-louis.bossart@linux.intel.com Signed-off-by: Mark Brown --- sound/soc/intel/boards/sof_maxim_common.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) (limited to 'sound') diff --git a/sound/soc/intel/boards/sof_maxim_common.c b/sound/soc/intel/boards/sof_maxim_common.c index 1a6961592029..b6e63ea13d64 100644 --- a/sound/soc/intel/boards/sof_maxim_common.c +++ b/sound/soc/intel/boards/sof_maxim_common.c @@ -66,6 +66,10 @@ int max98373_trigger(struct snd_pcm_substream *substream, int cmd) int j; int ret = 0; + /* set spk pin by playback only */ + if (substream->stream == SNDRV_PCM_STREAM_CAPTURE) + return 0; + for_each_rtd_codec_dais(rtd, j, codec_dai) { struct snd_soc_component *component = codec_dai->component; struct snd_soc_dapm_context *dapm = @@ -86,9 +90,6 @@ int max98373_trigger(struct snd_pcm_substream *substream, int cmd) case SNDRV_PCM_TRIGGER_STOP: case SNDRV_PCM_TRIGGER_SUSPEND: case SNDRV_PCM_TRIGGER_PAUSE_PUSH: - /* Make sure no streams are active before disable pin */ - if (snd_soc_dai_active(codec_dai) != 1) - break; ret = snd_soc_dapm_disable_pin(dapm, pin_name); if (!ret) snd_soc_dapm_sync(dapm); -- cgit From 7ad26d6671db758c959d7e1d100b138a38483612 Mon Sep 17 00:00:00 2001 From: Kuninori Morimoto Date: Tue, 25 Aug 2020 08:39:24 +0900 Subject: ASoC: pcm3168a: ignore 0 Hz settings Some sound card try to set 0 Hz as reset, but it is impossible. This patch ignores it to avoid error return. Signed-off-by: Kuninori Morimoto Link: https://lore.kernel.org/r/87a6yjy5sy.wl-kuninori.morimoto.gx@renesas.com Signed-off-by: Mark Brown --- sound/soc/codecs/pcm3168a.c | 7 +++++++ 1 file changed, 7 insertions(+) (limited to 'sound') diff --git a/sound/soc/codecs/pcm3168a.c b/sound/soc/codecs/pcm3168a.c index 5e445fee4ef5..821e7395f90f 100644 --- a/sound/soc/codecs/pcm3168a.c +++ b/sound/soc/codecs/pcm3168a.c @@ -306,6 +306,13 @@ static int pcm3168a_set_dai_sysclk(struct snd_soc_dai *dai, struct pcm3168a_priv *pcm3168a = snd_soc_component_get_drvdata(dai->component); int ret; + /* + * Some sound card sets 0 Hz as reset, + * but it is impossible to set. Ignore it here + */ + if (freq == 0) + return 0; + if (freq > PCM3168A_MAX_SYSCLK) return -EINVAL; -- cgit From d062085d61b1c2015845d1d9c475266381cce785 Mon Sep 17 00:00:00 2001 From: Kuninori Morimoto Date: Tue, 25 Aug 2020 08:38:54 +0900 Subject: ASoC: ti: fixup ams_delta_mute() function name commit 059374fe9ea5d ("ASoC: ti: merge .digital_mute() into .mute_stream()") merged .digital_mute() into .mute_stream(). But it didn't rename ams_delta_digital_mute() to ams_delta_mute(). This patch fixup it. Signed-off-by: Kuninori Morimoto Reported-by: kernel test robot Link: https://lore.kernel.org/r/87blizy5ts.wl-kuninori.morimoto.gx@renesas.com Signed-off-by: Mark Brown --- sound/soc/ti/ams-delta.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'sound') diff --git a/sound/soc/ti/ams-delta.c b/sound/soc/ti/ams-delta.c index 5c47de96c529..57feb473a579 100644 --- a/sound/soc/ti/ams-delta.c +++ b/sound/soc/ti/ams-delta.c @@ -446,12 +446,12 @@ static const struct snd_soc_dai_ops ams_delta_dai_ops = { /* Will be used if the codec ever has its own digital_mute function */ static int ams_delta_startup(struct snd_pcm_substream *substream) { - return ams_delta_digital_mute(NULL, 0, substream->stream); + return ams_delta_mute(NULL, 0, substream->stream); } static void ams_delta_shutdown(struct snd_pcm_substream *substream) { - ams_delta_digital_mute(NULL, 1, substream->stream); + ams_delta_mute(NULL, 1, substream->stream); } -- cgit From 6e0c9b5f90978287b5a3d38ee83203d295f375f1 Mon Sep 17 00:00:00 2001 From: Vinod Koul Date: Wed, 26 Aug 2020 22:03:36 +0530 Subject: ASoC: max98373: Fix return check for devm_regmap_init_sdw() devm_regmap_init_sdw() returns a valid pointer on success or ERR_PTR on failure which should be checked with IS_ERR. Also use PTR_ERR for returning error codes. Reported-by: Takashi Iwai Fixes: 56a5b7910e96 ("ASoC: codecs: max98373: add SoundWire support") Signed-off-by: Vinod Koul Reviewed-by: Pierre-Louis Bossart Link: https://lore.kernel.org/r/20200826163340.3249608-2-vkoul@kernel.org Signed-off-by: Mark Brown --- sound/soc/codecs/max98373-sdw.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'sound') diff --git a/sound/soc/codecs/max98373-sdw.c b/sound/soc/codecs/max98373-sdw.c index 5fe724728e84..e4675cfff7b2 100644 --- a/sound/soc/codecs/max98373-sdw.c +++ b/sound/soc/codecs/max98373-sdw.c @@ -838,8 +838,8 @@ static int max98373_sdw_probe(struct sdw_slave *slave, /* Regmap Initialization */ regmap = devm_regmap_init_sdw(slave, &max98373_sdw_regmap); - if (!regmap) - return -EINVAL; + if (IS_ERR(regmap)) + return PTR_ERR(regmap); return max98373_init(slave, regmap); } -- cgit From 344850d93c098e1b17e6f89d5e436893e9762ef3 Mon Sep 17 00:00:00 2001 From: Vinod Koul Date: Wed, 26 Aug 2020 22:03:37 +0530 Subject: ASoC: rt1308-sdw: Fix return check for devm_regmap_init_sdw() devm_regmap_init_sdw() returns a valid pointer on success or ERR_PTR on failure which should be checked with IS_ERR. Also use PTR_ERR for returning error codes. Reported-by: Takashi Iwai Fixes: a87a6653a28c ("ASoC: rt1308-sdw: add rt1308 SdW amplifier driver") Signed-off-by: Vinod Koul Reviewed-by: Pierre-Louis Bossart Link: https://lore.kernel.org/r/20200826163340.3249608-3-vkoul@kernel.org Signed-off-by: Mark Brown --- sound/soc/codecs/rt1308-sdw.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'sound') diff --git a/sound/soc/codecs/rt1308-sdw.c b/sound/soc/codecs/rt1308-sdw.c index b0ba0d2acbdd..56e952a904a3 100644 --- a/sound/soc/codecs/rt1308-sdw.c +++ b/sound/soc/codecs/rt1308-sdw.c @@ -684,8 +684,8 @@ static int rt1308_sdw_probe(struct sdw_slave *slave, /* Regmap Initialization */ regmap = devm_regmap_init_sdw(slave, &rt1308_sdw_regmap); - if (!regmap) - return -EINVAL; + if (IS_ERR(regmap)) + return PTR_ERR(regmap); rt1308_sdw_init(&slave->dev, regmap, slave); -- cgit From be1a4b2c56db860a220c6f74d461188e5733264a Mon Sep 17 00:00:00 2001 From: Vinod Koul Date: Wed, 26 Aug 2020 22:03:38 +0530 Subject: ASoC: rt711: Fix return check for devm_regmap_init_sdw() devm_regmap_init_sdw() returns a valid pointer on success or ERR_PTR on failure which should be checked with IS_ERR. Also use PTR_ERR for returning error codes. Reported-by: Takashi Iwai Fixes: 320b8b0d13b8 ("ASoC: rt711: add rt711 codec driver") Signed-off-by: Vinod Koul Reviewed-by: Pierre-Louis Bossart Link: https://lore.kernel.org/r/20200826163340.3249608-4-vkoul@kernel.org Signed-off-by: Mark Brown --- sound/soc/codecs/rt711-sdw.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'sound') diff --git a/sound/soc/codecs/rt711-sdw.c b/sound/soc/codecs/rt711-sdw.c index 45b928954b58..7efff130a638 100644 --- a/sound/soc/codecs/rt711-sdw.c +++ b/sound/soc/codecs/rt711-sdw.c @@ -452,8 +452,8 @@ static int rt711_sdw_probe(struct sdw_slave *slave, /* Regmap Initialization */ sdw_regmap = devm_regmap_init_sdw(slave, &rt711_sdw_regmap); - if (!sdw_regmap) - return -EINVAL; + if (IS_ERR(sdw_regmap)) + return PTR_ERR(sdw_regmap); regmap = devm_regmap_init(&slave->dev, NULL, &slave->dev, &rt711_regmap); -- cgit From 282eb0b52e3f0399ee48a4cad0d9ffec840b0164 Mon Sep 17 00:00:00 2001 From: Vinod Koul Date: Wed, 26 Aug 2020 22:03:39 +0530 Subject: ASoC: rt715: Fix return check for devm_regmap_init_sdw() devm_regmap_init_sdw() returns a valid pointer on success or ERR_PTR on failure which should be checked with IS_ERR. Also use PTR_ERR for returning error codes. Reported-by: Takashi Iwai Fixes: d1ede0641b05 ("ASoC: rt715: add RT715 codec driver") Signed-off-by: Vinod Koul Reviewed-by: Pierre-Louis Bossart Link: https://lore.kernel.org/r/20200826163340.3249608-5-vkoul@kernel.org Signed-off-by: Mark Brown --- sound/soc/codecs/rt715-sdw.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'sound') diff --git a/sound/soc/codecs/rt715-sdw.c b/sound/soc/codecs/rt715-sdw.c index d11b23d6b240..68a36739f1b0 100644 --- a/sound/soc/codecs/rt715-sdw.c +++ b/sound/soc/codecs/rt715-sdw.c @@ -527,8 +527,8 @@ static int rt715_sdw_probe(struct sdw_slave *slave, /* Regmap Initialization */ sdw_regmap = devm_regmap_init_sdw(slave, &rt715_sdw_regmap); - if (!sdw_regmap) - return -EINVAL; + if (IS_ERR(sdw_regmap)) + return PTR_ERR(sdw_regmap); regmap = devm_regmap_init(&slave->dev, NULL, &slave->dev, &rt715_regmap); -- cgit From db1a4250aef53775ec0094b81454213319cc8c74 Mon Sep 17 00:00:00 2001 From: Vinod Koul Date: Wed, 26 Aug 2020 22:03:40 +0530 Subject: ASoC: rt700: Fix return check for devm_regmap_init_sdw() devm_regmap_init_sdw() returns a valid pointer on success or ERR_PTR on failure which should be checked with IS_ERR. Also use PTR_ERR for returning error codes. Reported-by: Takashi Iwai Fixes: 7d2a5f9ae41e ("ASoC: rt700: add rt700 codec driver") Signed-off-by: Vinod Koul Reviewed-by: Pierre-Louis Bossart Link: https://lore.kernel.org/r/20200826163340.3249608-6-vkoul@kernel.org Signed-off-by: Mark Brown --- sound/soc/codecs/rt700-sdw.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'sound') diff --git a/sound/soc/codecs/rt700-sdw.c b/sound/soc/codecs/rt700-sdw.c index 4d14048d1197..1d24bf040718 100644 --- a/sound/soc/codecs/rt700-sdw.c +++ b/sound/soc/codecs/rt700-sdw.c @@ -452,8 +452,8 @@ static int rt700_sdw_probe(struct sdw_slave *slave, /* Regmap Initialization */ sdw_regmap = devm_regmap_init_sdw(slave, &rt700_sdw_regmap); - if (!sdw_regmap) - return -EINVAL; + if (IS_ERR(sdw_regmap)) + return PTR_ERR(sdw_regmap); regmap = devm_regmap_init(&slave->dev, NULL, &slave->dev, &rt700_regmap); -- cgit From c1e6414cdc371f9ed82cefebba7538499a3059f9 Mon Sep 17 00:00:00 2001 From: Dinghao Liu Date: Thu, 20 Aug 2020 12:28:27 +0800 Subject: ASoC: qcom: common: Fix refcount imbalance on error for_each_child_of_node returns a node pointer np with refcount incremented. So when devm_kzalloc fails, a pairing refcount decrement is needed to keep np's refcount balanced. Fixes: 16395ceee11f8 ("ASoC: qcom: common: Fix NULL pointer in of parser") Signed-off-by: Dinghao Liu Link: https://lore.kernel.org/r/20200820042828.10308-1-dinghao.liu@zju.edu.cn Signed-off-by: Mark Brown --- sound/soc/qcom/common.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) (limited to 'sound') diff --git a/sound/soc/qcom/common.c b/sound/soc/qcom/common.c index 5194d90ddb96..fd69cf8b1f23 100644 --- a/sound/soc/qcom/common.c +++ b/sound/soc/qcom/common.c @@ -52,8 +52,10 @@ int qcom_snd_parse_of(struct snd_soc_card *card) for_each_child_of_node(dev->of_node, np) { dlc = devm_kzalloc(dev, 2 * sizeof(*dlc), GFP_KERNEL); - if (!dlc) - return -ENOMEM; + if (!dlc) { + ret = -ENOMEM; + goto err; + } link->cpus = &dlc[0]; link->platforms = &dlc[1]; -- cgit From 20d9fdee72dfaa1fa7588c7a846283bd740e7157 Mon Sep 17 00:00:00 2001 From: Kuninori Morimoto Date: Thu, 27 Aug 2020 08:55:39 +0900 Subject: ASoC: soc-core: add snd_soc_find_dai_with_mutex() commit 25612477d20b52 ("ASoC: soc-dai: set dai_link dpcm_ flags with a helper") added snd_soc_dai_link_set_capabilities(). But it is using snd_soc_find_dai() (A) which is required client_mutex (B). And client_mutex is soc-core.c local. struct snd_soc_dai *snd_soc_find_dai(xxx) { ... (B) lockdep_assert_held(&client_mutex); ... } void snd_soc_dai_link_set_capabilities(xxx) { ... for_each_pcm_streams(direction) { ... for_each_link_cpus(dai_link, i, cpu) { (A) dai = snd_soc_find_dai(cpu); ... } ... for_each_link_codecs(dai_link, i, codec) { (A) dai = snd_soc_find_dai(codec); ... } } ... } Because of these background, we will get WARNING if .config has CONFIG_LOCKDEP. WARNING: CPU: 2 PID: 53 at sound/soc/soc-core.c:814 snd_soc_find_dai+0xf8/0x100 CPU: 2 PID: 53 Comm: kworker/2:1 Not tainted 5.7.0-rc1+ #328 Hardware name: Renesas H3ULCB Kingfisher board based on r8a77951 (DT) Workqueue: events deferred_probe_work_func pstate: 60000005 (nZCv daif -PAN -UAO) pc : snd_soc_find_dai+0xf8/0x100 lr : snd_soc_find_dai+0xf4/0x100 ... Call trace: snd_soc_find_dai+0xf8/0x100 snd_soc_dai_link_set_capabilities+0xa0/0x16c graph_dai_link_of_dpcm+0x390/0x3c0 graph_for_each_link+0x134/0x200 graph_probe+0x144/0x230 platform_drv_probe+0x5c/0xb0 really_probe+0xe4/0x430 driver_probe_device+0x60/0xf4 snd_soc_find_dai() will be used from (X) CPU/Codec/Platform driver with mutex lock, and (Y) Card driver without mutex lock. This snd_soc_dai_link_set_capabilities() is for Card driver, this means called without mutex. This patch adds snd_soc_find_dai_with_mutex() to solve it. Fixes: 25612477d20b52 ("ASoC: soc-dai: set dai_link dpcm_ flags with a helper") Signed-off-by: Kuninori Morimoto Link: https://lore.kernel.org/r/87blixvuab.wl-kuninori.morimoto.gx@renesas.com Signed-off-by: Mark Brown --- sound/soc/soc-core.c | 13 +++++++++++++ sound/soc/soc-dai.c | 4 ++-- 2 files changed, 15 insertions(+), 2 deletions(-) (limited to 'sound') diff --git a/sound/soc/soc-core.c b/sound/soc/soc-core.c index 2fe1b2ec7c8f..fe11856d7a63 100644 --- a/sound/soc/soc-core.c +++ b/sound/soc/soc-core.c @@ -834,6 +834,19 @@ struct snd_soc_dai *snd_soc_find_dai( } EXPORT_SYMBOL_GPL(snd_soc_find_dai); +struct snd_soc_dai *snd_soc_find_dai_with_mutex( + const struct snd_soc_dai_link_component *dlc) +{ + struct snd_soc_dai *dai; + + mutex_lock(&client_mutex); + dai = snd_soc_find_dai(dlc); + mutex_unlock(&client_mutex); + + return dai; +} +EXPORT_SYMBOL_GPL(snd_soc_find_dai_with_mutex); + static int soc_dai_link_sanity_check(struct snd_soc_card *card, struct snd_soc_dai_link *link) { diff --git a/sound/soc/soc-dai.c b/sound/soc/soc-dai.c index 91a2551e4cef..0dbd312aad08 100644 --- a/sound/soc/soc-dai.c +++ b/sound/soc/soc-dai.c @@ -412,14 +412,14 @@ void snd_soc_dai_link_set_capabilities(struct snd_soc_dai_link *dai_link) supported_codec = false; for_each_link_cpus(dai_link, i, cpu) { - dai = snd_soc_find_dai(cpu); + dai = snd_soc_find_dai_with_mutex(cpu); if (dai && snd_soc_dai_stream_valid(dai, direction)) { supported_cpu = true; break; } } for_each_link_codecs(dai_link, i, codec) { - dai = snd_soc_find_dai(codec); + dai = snd_soc_find_dai_with_mutex(codec); if (dai && snd_soc_dai_stream_valid(dai, direction)) { supported_codec = true; break; -- cgit From 9c4b205a20f483d8a5d1208cfec33e339347d4bd Mon Sep 17 00:00:00 2001 From: Jerome Brunet Date: Fri, 28 Aug 2020 17:14:38 +0200 Subject: ASoC: meson: axg-toddr: fix channel order on g12 platforms On g12 and following platforms, The first channel of record with more than 2 channels ends being placed randomly on an even channel of the output. On these SoCs, a bit was added to force the first channel to be placed at the beginning of the output. Apparently the behavior if the bit is not set is not easily predictable. According to the documentation, this bit is not present on the axg series. Set the bit on g12 and fix the problem. Fixes: a3c23a8ad4dc ("ASoC: meson: axg-toddr: add g12a support") Reported-by: Nicolas Belin Signed-off-by: Jerome Brunet Link: https://lore.kernel.org/r/20200828151438.350974-1-jbrunet@baylibre.com Signed-off-by: Mark Brown --- sound/soc/meson/axg-toddr.c | 24 +++++++++++++++++++++++- 1 file changed, 23 insertions(+), 1 deletion(-) (limited to 'sound') diff --git a/sound/soc/meson/axg-toddr.c b/sound/soc/meson/axg-toddr.c index e711abcf8c12..d6adf7edea41 100644 --- a/sound/soc/meson/axg-toddr.c +++ b/sound/soc/meson/axg-toddr.c @@ -18,6 +18,7 @@ #define CTRL0_TODDR_SEL_RESAMPLE BIT(30) #define CTRL0_TODDR_EXT_SIGNED BIT(29) #define CTRL0_TODDR_PP_MODE BIT(28) +#define CTRL0_TODDR_SYNC_CH BIT(27) #define CTRL0_TODDR_TYPE_MASK GENMASK(15, 13) #define CTRL0_TODDR_TYPE(x) ((x) << 13) #define CTRL0_TODDR_MSB_POS_MASK GENMASK(12, 8) @@ -189,10 +190,31 @@ static const struct axg_fifo_match_data axg_toddr_match_data = { .dai_drv = &axg_toddr_dai_drv }; +static int g12a_toddr_dai_startup(struct snd_pcm_substream *substream, + struct snd_soc_dai *dai) +{ + struct axg_fifo *fifo = snd_soc_dai_get_drvdata(dai); + int ret; + + ret = axg_toddr_dai_startup(substream, dai); + if (ret) + return ret; + + /* + * Make sure the first channel ends up in the at beginning of the output + * As weird as it looks, without this the first channel may be misplaced + * in memory, with a random shift of 2 channels. + */ + regmap_update_bits(fifo->map, FIFO_CTRL0, CTRL0_TODDR_SYNC_CH, + CTRL0_TODDR_SYNC_CH); + + return 0; +} + static const struct snd_soc_dai_ops g12a_toddr_ops = { .prepare = g12a_toddr_dai_prepare, .hw_params = axg_toddr_dai_hw_params, - .startup = axg_toddr_dai_startup, + .startup = g12a_toddr_dai_startup, .shutdown = axg_toddr_dai_shutdown, }; -- cgit From 811c5494436789e7149487c06e0602b507ce274b Mon Sep 17 00:00:00 2001 From: Sylwester Nawrocki Date: Thu, 27 Aug 2020 19:33:56 +0200 Subject: ASoC: wm8994: Skip setting of the WM8994_MICBIAS register for WM1811 The WM8994_MICBIAS register is not available in the WM1811 CODEC so skip initialization of that register for that device. This suppresses an error during boot: "wm8994-codec: ASoC: error at snd_soc_component_update_bits on wm8994-codec" Signed-off-by: Sylwester Nawrocki Acked-by: Krzysztof Kozlowski Acked-by: Charles Keepax Link: https://lore.kernel.org/r/20200827173357.31891-1-s.nawrocki@samsung.com Signed-off-by: Mark Brown --- sound/soc/codecs/wm8994.c | 2 ++ sound/soc/codecs/wm_hubs.c | 3 +++ sound/soc/codecs/wm_hubs.h | 1 + 3 files changed, 6 insertions(+) (limited to 'sound') diff --git a/sound/soc/codecs/wm8994.c b/sound/soc/codecs/wm8994.c index 038be667c1a6..b3ba0536736e 100644 --- a/sound/soc/codecs/wm8994.c +++ b/sound/soc/codecs/wm8994.c @@ -4193,11 +4193,13 @@ static int wm8994_component_probe(struct snd_soc_component *component) wm8994->hubs.dcs_readback_mode = 2; break; } + wm8994->hubs.micd_scthr = true; break; case WM8958: wm8994->hubs.dcs_readback_mode = 1; wm8994->hubs.hp_startup_mode = 1; + wm8994->hubs.micd_scthr = true; switch (control->revision) { case 0: diff --git a/sound/soc/codecs/wm_hubs.c b/sound/soc/codecs/wm_hubs.c index 891effe220fe..0c881846f485 100644 --- a/sound/soc/codecs/wm_hubs.c +++ b/sound/soc/codecs/wm_hubs.c @@ -1223,6 +1223,9 @@ int wm_hubs_handle_analogue_pdata(struct snd_soc_component *component, snd_soc_component_update_bits(component, WM8993_ADDITIONAL_CONTROL, WM8993_LINEOUT2_FB, WM8993_LINEOUT2_FB); + if (!hubs->micd_scthr) + return 0; + snd_soc_component_update_bits(component, WM8993_MICBIAS, WM8993_JD_SCTHR_MASK | WM8993_JD_THR_MASK | WM8993_MICB1_LVL | WM8993_MICB2_LVL, diff --git a/sound/soc/codecs/wm_hubs.h b/sound/soc/codecs/wm_hubs.h index 4b8e5f0d6e32..988b29e63060 100644 --- a/sound/soc/codecs/wm_hubs.h +++ b/sound/soc/codecs/wm_hubs.h @@ -27,6 +27,7 @@ struct wm_hubs_data { int hp_startup_mode; int series_startup; int no_series_update; + bool micd_scthr; bool no_cache_dac_hp_direct; struct list_head dcs_cache; -- cgit From f5a2cda4f1db89776b64c4f0f2c2ac609527ac70 Mon Sep 17 00:00:00 2001 From: Sylwester Nawrocki Date: Thu, 27 Aug 2020 19:33:57 +0200 Subject: ASoC: wm8994: Ensure the device is resumed in wm89xx_mic_detect functions When the wm8958_mic_detect, wm8994_mic_detect functions get called from the machine driver, e.g. from the card's late_probe() callback, the CODEC device may be PM runtime suspended and any regmap writes have no effect. Add PM runtime calls to these functions to ensure the device registers are updated as expected. This suppresses an error during boot "wm8994-codec: ASoC: error at snd_soc_component_update_bits on wm8994-codec" caused by the regmap access error due to the cache_only flag being set. Signed-off-by: Sylwester Nawrocki Acked-by: Krzysztof Kozlowski Acked-by: Charles Keepax Link: https://lore.kernel.org/r/20200827173357.31891-2-s.nawrocki@samsung.com Signed-off-by: Mark Brown --- sound/soc/codecs/wm8994.c | 8 ++++++++ 1 file changed, 8 insertions(+) (limited to 'sound') diff --git a/sound/soc/codecs/wm8994.c b/sound/soc/codecs/wm8994.c index b3ba0536736e..fc9ea198ac79 100644 --- a/sound/soc/codecs/wm8994.c +++ b/sound/soc/codecs/wm8994.c @@ -3514,6 +3514,8 @@ int wm8994_mic_detect(struct snd_soc_component *component, struct snd_soc_jack * return -EINVAL; } + pm_runtime_get_sync(component->dev); + switch (micbias) { case 1: micdet = &wm8994->micdet[0]; @@ -3561,6 +3563,8 @@ int wm8994_mic_detect(struct snd_soc_component *component, struct snd_soc_jack * snd_soc_dapm_sync(dapm); + pm_runtime_put(component->dev); + return 0; } EXPORT_SYMBOL_GPL(wm8994_mic_detect); @@ -3932,6 +3936,8 @@ int wm8958_mic_detect(struct snd_soc_component *component, struct snd_soc_jack * return -EINVAL; } + pm_runtime_get_sync(component->dev); + if (jack) { snd_soc_dapm_force_enable_pin(dapm, "CLK_SYS"); snd_soc_dapm_sync(dapm); @@ -4000,6 +4006,8 @@ int wm8958_mic_detect(struct snd_soc_component *component, struct snd_soc_jack * snd_soc_dapm_sync(dapm); } + pm_runtime_put(component->dev); + return 0; } EXPORT_SYMBOL_GPL(wm8958_mic_detect); -- cgit From 2569231d71dff82cfd6e82ab3871776f72ec53b6 Mon Sep 17 00:00:00 2001 From: Camel Guo Date: Tue, 1 Sep 2020 15:57:35 +0200 Subject: ASoC: tlv320adcx140: Fix accessing uninitialized adcx140->dev In adcx140_i2c_probe, adcx140->dev is accessed before its initialization. This commit fixes this bug. Fixes: 689c7655b50c ("ASoC: tlv320adcx140: Add the tlv320adcx140 codec driver family") Acked-by: Dan Murphy Signed-off-by: Camel Guo Link: https://lore.kernel.org/r/20200901135736.32036-1-camel.guo@axis.com Signed-off-by: Mark Brown --- sound/soc/codecs/tlv320adcx140.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'sound') diff --git a/sound/soc/codecs/tlv320adcx140.c b/sound/soc/codecs/tlv320adcx140.c index 5cd50d841177..7ae6ec374be3 100644 --- a/sound/soc/codecs/tlv320adcx140.c +++ b/sound/soc/codecs/tlv320adcx140.c @@ -980,6 +980,8 @@ static int adcx140_i2c_probe(struct i2c_client *i2c, if (!adcx140) return -ENOMEM; + adcx140->dev = &i2c->dev; + adcx140->gpio_reset = devm_gpiod_get_optional(adcx140->dev, "reset", GPIOD_OUT_LOW); if (IS_ERR(adcx140->gpio_reset)) @@ -1007,7 +1009,7 @@ static int adcx140_i2c_probe(struct i2c_client *i2c, ret); return ret; } - adcx140->dev = &i2c->dev; + i2c_set_clientdata(i2c, adcx140); return devm_snd_soc_register_component(&i2c->dev, -- cgit From 154549558a622b31702fcaa01ccd85e6e34073de Mon Sep 17 00:00:00 2001 From: Cezary Rojewski Date: Tue, 1 Sep 2020 17:30:41 +0200 Subject: ASoC: Intel: haswell: Fix power transition refactor While addressing existing power-cycle limitations for sound/soc/intel/haswell solution, change brings regression for standard audio userspace flows e.g.: when using PulseAudio. Occasional sound-card initialization fail is still better than permanent audio distortions, so revert the change. Fixes: 8ec7d6043263 ("ASoC: Intel: haswell: Power transition refactor") Reported-by: Christian Bundy Signed-off-by: Cezary Rojewski Reviewed-by: Pierre-Louis Bossart Link: https://lore.kernel.org/r/20200901153041.14771-1-cezary.rojewski@intel.com Signed-off-by: Mark Brown --- sound/soc/intel/haswell/sst-haswell-dsp.c | 185 +++++++++++++----------------- 1 file changed, 81 insertions(+), 104 deletions(-) (limited to 'sound') diff --git a/sound/soc/intel/haswell/sst-haswell-dsp.c b/sound/soc/intel/haswell/sst-haswell-dsp.c index de80e19454c1..88c3f63bded9 100644 --- a/sound/soc/intel/haswell/sst-haswell-dsp.c +++ b/sound/soc/intel/haswell/sst-haswell-dsp.c @@ -243,92 +243,45 @@ static irqreturn_t hsw_irq(int irq, void *context) return ret; } -#define CSR_DEFAULT_VALUE 0x8480040E -#define ISC_DEFAULT_VALUE 0x0 -#define ISD_DEFAULT_VALUE 0x0 -#define IMC_DEFAULT_VALUE 0x7FFF0003 -#define IMD_DEFAULT_VALUE 0x7FFF0003 -#define IPCC_DEFAULT_VALUE 0x0 -#define IPCD_DEFAULT_VALUE 0x0 -#define CLKCTL_DEFAULT_VALUE 0x7FF -#define CSR2_DEFAULT_VALUE 0x0 -#define LTR_CTRL_DEFAULT_VALUE 0x0 -#define HMD_CTRL_DEFAULT_VALUE 0x0 - -static void hsw_set_shim_defaults(struct sst_dsp *sst) -{ - sst_dsp_shim_write_unlocked(sst, SST_CSR, CSR_DEFAULT_VALUE); - sst_dsp_shim_write_unlocked(sst, SST_ISRX, ISC_DEFAULT_VALUE); - sst_dsp_shim_write_unlocked(sst, SST_ISRD, ISD_DEFAULT_VALUE); - sst_dsp_shim_write_unlocked(sst, SST_IMRX, IMC_DEFAULT_VALUE); - sst_dsp_shim_write_unlocked(sst, SST_IMRD, IMD_DEFAULT_VALUE); - sst_dsp_shim_write_unlocked(sst, SST_IPCX, IPCC_DEFAULT_VALUE); - sst_dsp_shim_write_unlocked(sst, SST_IPCD, IPCD_DEFAULT_VALUE); - sst_dsp_shim_write_unlocked(sst, SST_CLKCTL, CLKCTL_DEFAULT_VALUE); - sst_dsp_shim_write_unlocked(sst, SST_CSR2, CSR2_DEFAULT_VALUE); - sst_dsp_shim_write_unlocked(sst, SST_LTRC, LTR_CTRL_DEFAULT_VALUE); - sst_dsp_shim_write_unlocked(sst, SST_HMDC, HMD_CTRL_DEFAULT_VALUE); -} - -/* all clock-gating minus DCLCGE and DTCGE */ -#define SST_VDRTCL2_CG_OTHER 0xB7D - static void hsw_set_dsp_D3(struct sst_dsp *sst) { + u32 val; u32 reg; - /* disable clock core gating */ + /* Disable core clock gating (VDRTCTL2.DCLCGE = 0) */ reg = readl(sst->addr.pci_cfg + SST_VDRTCTL2); - reg &= ~(SST_VDRTCL2_DCLCGE); + reg &= ~(SST_VDRTCL2_DCLCGE | SST_VDRTCL2_DTCGE); writel(reg, sst->addr.pci_cfg + SST_VDRTCTL2); - /* stall, reset and set 24MHz XOSC */ - sst_dsp_shim_update_bits_unlocked(sst, SST_CSR, - SST_CSR_24MHZ_LPCS | SST_CSR_STALL | SST_CSR_RST, - SST_CSR_24MHZ_LPCS | SST_CSR_STALL | SST_CSR_RST); - - /* DRAM power gating all */ - reg = readl(sst->addr.pci_cfg + SST_VDRTCTL0); - reg |= SST_VDRTCL0_ISRAMPGE_MASK | - SST_VDRTCL0_DSRAMPGE_MASK; - reg &= ~(SST_VDRTCL0_D3SRAMPGD); - reg |= SST_VDRTCL0_D3PGD; - writel(reg, sst->addr.pci_cfg + SST_VDRTCTL0); - udelay(50); + /* enable power gating and switch off DRAM & IRAM blocks */ + val = readl(sst->addr.pci_cfg + SST_VDRTCTL0); + val |= SST_VDRTCL0_DSRAMPGE_MASK | + SST_VDRTCL0_ISRAMPGE_MASK; + val &= ~(SST_VDRTCL0_D3PGD | SST_VDRTCL0_D3SRAMPGD); + writel(val, sst->addr.pci_cfg + SST_VDRTCTL0); - /* PLL shutdown enable */ - reg = readl(sst->addr.pci_cfg + SST_VDRTCTL2); - reg |= SST_VDRTCL2_APLLSE_MASK; - writel(reg, sst->addr.pci_cfg + SST_VDRTCTL2); + /* switch off audio PLL */ + val = readl(sst->addr.pci_cfg + SST_VDRTCTL2); + val |= SST_VDRTCL2_APLLSE_MASK; + writel(val, sst->addr.pci_cfg + SST_VDRTCTL2); - /* disable MCLK */ + /* disable MCLK(clkctl.smos = 0) */ sst_dsp_shim_update_bits_unlocked(sst, SST_CLKCTL, - SST_CLKCTL_MASK, 0); - - /* switch clock gating */ - reg = readl(sst->addr.pci_cfg + SST_VDRTCTL2); - reg |= SST_VDRTCL2_CG_OTHER; - reg &= ~(SST_VDRTCL2_DTCGE); - writel(reg, sst->addr.pci_cfg + SST_VDRTCTL2); - /* enable DTCGE separatelly */ - reg = readl(sst->addr.pci_cfg + SST_VDRTCTL2); - reg |= SST_VDRTCL2_DTCGE; - writel(reg, sst->addr.pci_cfg + SST_VDRTCTL2); + SST_CLKCTL_MASK, 0); - /* set shim defaults */ - hsw_set_shim_defaults(sst); - - /* set D3 */ - reg = readl(sst->addr.pci_cfg + SST_PMCS); - reg |= SST_PMCS_PS_MASK; - writel(reg, sst->addr.pci_cfg + SST_PMCS); + /* Set D3 state, delay 50 us */ + val = readl(sst->addr.pci_cfg + SST_PMCS); + val |= SST_PMCS_PS_MASK; + writel(val, sst->addr.pci_cfg + SST_PMCS); udelay(50); - /* enable clock core gating */ + /* Enable core clock gating (VDRTCTL2.DCLCGE = 1), delay 50 us */ reg = readl(sst->addr.pci_cfg + SST_VDRTCTL2); - reg |= SST_VDRTCL2_DCLCGE; + reg |= SST_VDRTCL2_DCLCGE | SST_VDRTCL2_DTCGE; writel(reg, sst->addr.pci_cfg + SST_VDRTCTL2); + udelay(50); + } static void hsw_reset(struct sst_dsp *sst) @@ -346,62 +299,75 @@ static void hsw_reset(struct sst_dsp *sst) SST_CSR_RST | SST_CSR_STALL, SST_CSR_STALL); } -/* recommended CSR state for power-up */ -#define SST_CSR_D0_MASK (0x18A09C0C | SST_CSR_DCS_MASK) - static int hsw_set_dsp_D0(struct sst_dsp *sst) { - u32 reg; + int tries = 10; + u32 reg, fw_dump_bit; - /* disable clock core gating */ + /* Disable core clock gating (VDRTCTL2.DCLCGE = 0) */ reg = readl(sst->addr.pci_cfg + SST_VDRTCTL2); - reg &= ~(SST_VDRTCL2_DCLCGE); + reg &= ~(SST_VDRTCL2_DCLCGE | SST_VDRTCL2_DTCGE); writel(reg, sst->addr.pci_cfg + SST_VDRTCTL2); - /* switch clock gating */ - reg = readl(sst->addr.pci_cfg + SST_VDRTCTL2); - reg |= SST_VDRTCL2_CG_OTHER; - reg &= ~(SST_VDRTCL2_DTCGE); - writel(reg, sst->addr.pci_cfg + SST_VDRTCTL2); + /* Disable D3PG (VDRTCTL0.D3PGD = 1) */ + reg = readl(sst->addr.pci_cfg + SST_VDRTCTL0); + reg |= SST_VDRTCL0_D3PGD; + writel(reg, sst->addr.pci_cfg + SST_VDRTCTL0); - /* set D0 */ + /* Set D0 state */ reg = readl(sst->addr.pci_cfg + SST_PMCS); - reg &= ~(SST_PMCS_PS_MASK); + reg &= ~SST_PMCS_PS_MASK; writel(reg, sst->addr.pci_cfg + SST_PMCS); - /* DRAM power gating none */ - reg = readl(sst->addr.pci_cfg + SST_VDRTCTL0); - reg &= ~(SST_VDRTCL0_ISRAMPGE_MASK | - SST_VDRTCL0_DSRAMPGE_MASK); - reg |= SST_VDRTCL0_D3SRAMPGD; - reg |= SST_VDRTCL0_D3PGD; - writel(reg, sst->addr.pci_cfg + SST_VDRTCTL0); - mdelay(10); + /* check that ADSP shim is enabled */ + while (tries--) { + reg = readl(sst->addr.pci_cfg + SST_PMCS) & SST_PMCS_PS_MASK; + if (reg == 0) + goto finish; + + msleep(1); + } + + return -ENODEV; - /* set shim defaults */ - hsw_set_shim_defaults(sst); +finish: + /* select SSP1 19.2MHz base clock, SSP clock 0, turn off Low Power Clock */ + sst_dsp_shim_update_bits_unlocked(sst, SST_CSR, + SST_CSR_S1IOCS | SST_CSR_SBCS1 | SST_CSR_LPCS, 0x0); + + /* stall DSP core, set clk to 192/96Mhz */ + sst_dsp_shim_update_bits_unlocked(sst, + SST_CSR, SST_CSR_STALL | SST_CSR_DCS_MASK, + SST_CSR_STALL | SST_CSR_DCS(4)); - /* restore MCLK */ + /* Set 24MHz MCLK, prevent local clock gating, enable SSP0 clock */ sst_dsp_shim_update_bits_unlocked(sst, SST_CLKCTL, - SST_CLKCTL_MASK, SST_CLKCTL_MASK); + SST_CLKCTL_MASK | SST_CLKCTL_DCPLCG | SST_CLKCTL_SCOE0, + SST_CLKCTL_MASK | SST_CLKCTL_DCPLCG | SST_CLKCTL_SCOE0); - /* PLL shutdown disable */ + /* Stall and reset core, set CSR */ + hsw_reset(sst); + + /* Enable core clock gating (VDRTCTL2.DCLCGE = 1), delay 50 us */ reg = readl(sst->addr.pci_cfg + SST_VDRTCTL2); - reg &= ~(SST_VDRTCL2_APLLSE_MASK); + reg |= SST_VDRTCL2_DCLCGE | SST_VDRTCL2_DTCGE; writel(reg, sst->addr.pci_cfg + SST_VDRTCTL2); - sst_dsp_shim_update_bits_unlocked(sst, SST_CSR, - SST_CSR_D0_MASK, SST_CSR_SBCS0 | SST_CSR_SBCS1 | - SST_CSR_STALL | SST_CSR_DCS(4)); udelay(50); - /* enable clock core gating */ + /* switch on audio PLL */ reg = readl(sst->addr.pci_cfg + SST_VDRTCTL2); - reg |= SST_VDRTCL2_DCLCGE; + reg &= ~SST_VDRTCL2_APLLSE_MASK; writel(reg, sst->addr.pci_cfg + SST_VDRTCTL2); - /* clear reset */ - sst_dsp_shim_update_bits_unlocked(sst, SST_CSR, SST_CSR_RST, 0); + /* set default power gating control, enable power gating control for all blocks. that is, + can't be accessed, please enable each block before accessing. */ + reg = readl(sst->addr.pci_cfg + SST_VDRTCTL0); + reg |= SST_VDRTCL0_DSRAMPGE_MASK | SST_VDRTCL0_ISRAMPGE_MASK; + /* for D0, always enable the block(DSRAM[0]) used for FW dump */ + fw_dump_bit = 1 << SST_VDRTCL0_DSRAMPGE_SHIFT; + writel(reg & ~fw_dump_bit, sst->addr.pci_cfg + SST_VDRTCTL0); + /* disable DMA finish function for SSP0 & SSP1 */ sst_dsp_shim_update_bits_unlocked(sst, SST_CSR2, SST_CSR2_SDFD_SSP1, @@ -418,6 +384,12 @@ static int hsw_set_dsp_D0(struct sst_dsp *sst) sst_dsp_shim_update_bits(sst, SST_IMRD, (SST_IMRD_DONE | SST_IMRD_BUSY | SST_IMRD_SSP0 | SST_IMRD_DMAC), 0x0); + /* clear IPC registers */ + sst_dsp_shim_write(sst, SST_IPCX, 0x0); + sst_dsp_shim_write(sst, SST_IPCD, 0x0); + sst_dsp_shim_write(sst, 0x80, 0x6); + sst_dsp_shim_write(sst, 0xe0, 0x300a); + return 0; } @@ -443,6 +415,11 @@ static void hsw_sleep(struct sst_dsp *sst) { dev_dbg(sst->dev, "HSW_PM dsp runtime suspend\n"); + /* put DSP into reset and stall */ + sst_dsp_shim_update_bits(sst, SST_CSR, + SST_CSR_24MHZ_LPCS | SST_CSR_RST | SST_CSR_STALL, + SST_CSR_RST | SST_CSR_STALL | SST_CSR_24MHZ_LPCS); + hsw_set_dsp_D3(sst); dev_dbg(sst->dev, "HSW_PM dsp runtime suspend exit\n"); } -- cgit From 6a0137101f47301fff2da6ba4b9048383d569909 Mon Sep 17 00:00:00 2001 From: Hans de Goede Date: Tue, 1 Sep 2020 10:06:23 +0200 Subject: ASoC: Intel: bytcr_rt5640: Add quirk for MPMAN Converter9 2-in-1 The MPMAN Converter9 2-in-1 almost fully works with out default settings. The only problem is that it has only 1 speaker so any sounds only playing on the right channel get lost. Add a quirk for this model using the default settings + MONO_SPEAKER. Signed-off-by: Hans de Goede Acked-by: Pierre-Louis Bossart Link: https://lore.kernel.org/r/20200901080623.4987-1-hdegoede@redhat.com Signed-off-by: Mark Brown --- sound/soc/intel/boards/bytcr_rt5640.c | 10 ++++++++++ 1 file changed, 10 insertions(+) (limited to 'sound') diff --git a/sound/soc/intel/boards/bytcr_rt5640.c b/sound/soc/intel/boards/bytcr_rt5640.c index 479992f4e97a..fc202747ba83 100644 --- a/sound/soc/intel/boards/bytcr_rt5640.c +++ b/sound/soc/intel/boards/bytcr_rt5640.c @@ -591,6 +591,16 @@ static const struct dmi_system_id byt_rt5640_quirk_table[] = { BYT_RT5640_SSP0_AIF1 | BYT_RT5640_MCLK_EN), }, + { /* MPMAN Converter 9, similar hw as the I.T.Works TW891 2-in-1 */ + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, "MPMAN"), + DMI_MATCH(DMI_PRODUCT_NAME, "Converter9"), + }, + .driver_data = (void *)(BYTCR_INPUT_DEFAULTS | + BYT_RT5640_MONO_SPEAKER | + BYT_RT5640_SSP0_AIF1 | + BYT_RT5640_MCLK_EN), + }, { /* MPMAN MPWIN895CL */ .matches = { -- cgit From 20244b2a8a8728c63233d33146e007dcacbcc5c4 Mon Sep 17 00:00:00 2001 From: Cezary Rojewski Date: Mon, 7 Sep 2020 13:19:39 +0200 Subject: ASoC: core: Do not cleanup uninitialized dais on soc_pcm_open failure Introduce for_each_rtd_dais_rollback macro which behaves exactly like for_each_codec_dais_rollback and its cpu_dais equivalent but for all dais instead. Use newly added macro to fix soc_pcm_open error path and prevent uninitialized dais from being cleaned-up. Signed-off-by: Cezary Rojewski Fixes: 5d9fa03e6c35 ("ASoC: soc-pcm: tidyup soc_pcm_open() order") Acked-by: Liam Girdwood Acked-by: Kuninori Morimoto Link: https://lore.kernel.org/r/20200907111939.16169-1-cezary.rojewski@intel.com Signed-off-by: Mark Brown --- sound/soc/soc-pcm.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'sound') diff --git a/sound/soc/soc-pcm.c b/sound/soc/soc-pcm.c index 00ac1cbf6f88..4c9d4cd8cf0b 100644 --- a/sound/soc/soc-pcm.c +++ b/sound/soc/soc-pcm.c @@ -812,7 +812,7 @@ dynamic: return 0; config_err: - for_each_rtd_dais(rtd, i, dai) + for_each_rtd_dais_rollback(rtd, i, dai) snd_soc_dai_shutdown(dai, substream); snd_soc_link_shutdown(substream); -- cgit From 1a5ce48fd667128e369fdc7fb87e21539aed21b5 Mon Sep 17 00:00:00 2001 From: Camel Guo Date: Tue, 8 Sep 2020 10:35:21 +0200 Subject: ASoC: tlv320adcx140: Wake up codec before accessing register According to its datasheet, after reset this codec goes into sleep mode. In this mode, any register accessing should be avoided except for exiting sleep mode. Hence this commit moves SLEEP_CFG access before any register accessing. Signed-off-by: Camel Guo Acked-by: Dan Murphy Link: https://lore.kernel.org/r/20200908083521.14105-2-camel.guo@axis.com Signed-off-by: Mark Brown --- sound/soc/codecs/tlv320adcx140.c | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) (limited to 'sound') diff --git a/sound/soc/codecs/tlv320adcx140.c b/sound/soc/codecs/tlv320adcx140.c index 7ae6ec374be3..8efe20605f9b 100644 --- a/sound/soc/codecs/tlv320adcx140.c +++ b/sound/soc/codecs/tlv320adcx140.c @@ -842,6 +842,18 @@ static int adcx140_codec_probe(struct snd_soc_component *component) if (ret) goto out; + if (adcx140->supply_areg == NULL) + sleep_cfg_val |= ADCX140_AREG_INTERNAL; + + ret = regmap_write(adcx140->regmap, ADCX140_SLEEP_CFG, sleep_cfg_val); + if (ret) { + dev_err(adcx140->dev, "setting sleep config failed %d\n", ret); + goto out; + } + + /* 8.4.3: Wait >= 1ms after entering active mode. */ + usleep_range(1000, 100000); + pdm_count = device_property_count_u32(adcx140->dev, "ti,pdm-edge-select"); if (pdm_count <= ADCX140_NUM_PDM_EDGES && pdm_count > 0) { @@ -889,18 +901,6 @@ static int adcx140_codec_probe(struct snd_soc_component *component) if (ret) goto out; - if (adcx140->supply_areg == NULL) - sleep_cfg_val |= ADCX140_AREG_INTERNAL; - - ret = regmap_write(adcx140->regmap, ADCX140_SLEEP_CFG, sleep_cfg_val); - if (ret) { - dev_err(adcx140->dev, "setting sleep config failed %d\n", ret); - goto out; - } - - /* 8.4.3: Wait >= 1ms after entering active mode. */ - usleep_range(1000, 100000); - ret = regmap_update_bits(adcx140->regmap, ADCX140_BIAS_CFG, ADCX140_MIC_BIAS_VAL_MSK | ADCX140_MIC_BIAS_VREF_MSK, bias_cfg); -- cgit