From 409fa67a7f4a68f6990955849c22eaca589f18c0 Mon Sep 17 00:00:00 2001 From: kbuild test robot Date: Tue, 23 Oct 2018 20:20:22 +0800 Subject: ASoC: stm32: sai: fix noderef.cocci warnings sound/soc/stm/stm32_sai_sub.c:393:26-32: ERROR: application of sizeof to pointer sizeof when applied to a pointer typed expression gives the size of the pointer Generated by: scripts/coccinelle/misc/noderef.cocci Fixes: 8307b2afd386 ("ASoC: stm32: sai: set sai as mclk clock provider") CC: Olivier Moysan Signed-off-by: kbuild test robot Signed-off-by: Mark Brown --- sound/soc/stm/stm32_sai_sub.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sound/soc/stm/stm32_sai_sub.c b/sound/soc/stm/stm32_sai_sub.c index ea05cc91aa05..211589b0b2ef 100644 --- a/sound/soc/stm/stm32_sai_sub.c +++ b/sound/soc/stm/stm32_sai_sub.c @@ -390,7 +390,7 @@ static int stm32_sai_add_mclk_provider(struct stm32_sai_sub_data *sai) char *mclk_name, *p, *s = (char *)pname; int ret, i = 0; - mclk = devm_kzalloc(dev, sizeof(mclk), GFP_KERNEL); + mclk = devm_kzalloc(dev, sizeof(*mclk), GFP_KERNEL); if (!mclk) return -ENOMEM; -- cgit v1.2.3-59-g8ed1b From 23cb2d04db54535df65edbbebbca89f2590f08bd Mon Sep 17 00:00:00 2001 From: Pierre-Louis Bossart Date: Fri, 26 Oct 2018 16:54:43 -0500 Subject: ASoC: fix oops w/ for_each_rtd_codec_dai_rollback() macro A kernel oops happens on an error case (usual missing BE mixer configuration required by Intel SST driver). Git bisect points to this macro and an operator precedence issue. for (; ((i--) >= 0) && ((dai) = rtd->codec_dais[i]);) The initial code replaced by this macro was while (--i >= 0) { codec_dai = rtd->codec_dais[i]; Fix the C operator precedence difference by reverting to pre-decrement Fixes: 0b7990e3897 ('ASoC: add for_each_rtd_codec_dai() macro') Cc: Kuninori Morimoto Signed-off-by: Pierre-Louis Bossart Signed-off-by: Mark Brown --- include/sound/soc.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/sound/soc.h b/include/sound/soc.h index f1dab1f4b194..70c10a8f3e90 100644 --- a/include/sound/soc.h +++ b/include/sound/soc.h @@ -1192,7 +1192,7 @@ struct snd_soc_pcm_runtime { ((i) < rtd->num_codecs) && ((dai) = rtd->codec_dais[i]); \ (i)++) #define for_each_rtd_codec_dai_rollback(rtd, i, dai) \ - for (; ((i--) >= 0) && ((dai) = rtd->codec_dais[i]);) + for (; ((--i) >= 0) && ((dai) = rtd->codec_dais[i]);) /* mixer control */ -- cgit v1.2.3-59-g8ed1b From 3ee9a76a8c5a10e1bfb04b81db767c6d562ddaf3 Mon Sep 17 00:00:00 2001 From: Kuninori Morimoto Date: Wed, 31 Oct 2018 00:48:12 +0000 Subject: ASoC: rsnd: fixup clock start checker commit 4d230d12710646 ("ASoC: rsnd: fixup not to call clk_get/set under non-atomic") fixuped clock start timing. But it exchanged clock start checker from ssi->usrcnt to ssi->rate. Current rsnd_ssi_master_clk_start() is called from .prepare, but some player (for example GStreamer) might calls it many times. In such case, the checker might returns error even though it was not error. It should check ssi->usrcnt instead of ssi->rate. This patch fixup it. Without this patch, GStreamer can't switch 48kHz / 44.1kHz. Reported-by: Yusuke Goda Signed-off-by: Kuninori Morimoto Tested-by: Yusuke Goda Signed-off-by: Mark Brown --- sound/soc/sh/rcar/ssi.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sound/soc/sh/rcar/ssi.c b/sound/soc/sh/rcar/ssi.c index fcb4df23248c..6ec78f3096dd 100644 --- a/sound/soc/sh/rcar/ssi.c +++ b/sound/soc/sh/rcar/ssi.c @@ -306,7 +306,7 @@ static int rsnd_ssi_master_clk_start(struct rsnd_mod *mod, if (rsnd_ssi_is_multi_slave(mod, io)) return 0; - if (ssi->rate) { + if (ssi->usrcnt > 1) { if (ssi->rate != rate) { dev_err(dev, "SSI parent/child should use same rate\n"); return -EINVAL; -- cgit v1.2.3-59-g8ed1b From 2f5d94123ce3c12a1e15802e6d5ee98f304ccb71 Mon Sep 17 00:00:00 2001 From: Vasily Khoruzhick Date: Fri, 2 Nov 2018 21:26:51 -0700 Subject: ASoC: sunxi: rename SND_SUNXI_ADDA_PR_REGMAP to SND_SUN8I_ADDA_PR_REGMAP SND_SUN50I_CODEC_ANALOG selects SND_SUNXI_ADDA_PR_REGMAP which is leftover of renaming SND_SUNXI_ADDA_PR_REGMAP to SND_SUN8I_ADDA_PR_REGMAP. Replace it with SND_SUN8I_ADDA_PR_REGMAP to fix possible link errors for some configurations: sound/soc/sunxi/sun50i-codec-analog.o: In function `sun50i_codec_analog_probe': sun50i-codec-analog.c:(.text+0x62): undefined reference to `sun8i_adda_pr_regmap_init' Fixes: 42371f327df0 ("ASoC: sunxi: Add new driver for Allwinner A64 codec's analog path controls") Signed-off-by: Vasily Khoruzhick Reviewed-by: Andre Przywara Signed-off-by: Mark Brown --- sound/soc/sunxi/Kconfig | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sound/soc/sunxi/Kconfig b/sound/soc/sunxi/Kconfig index 66aad0d3f9c7..8134c3c94229 100644 --- a/sound/soc/sunxi/Kconfig +++ b/sound/soc/sunxi/Kconfig @@ -31,7 +31,7 @@ config SND_SUN8I_CODEC_ANALOG config SND_SUN50I_CODEC_ANALOG tristate "Allwinner sun50i Codec Analog Controls Support" depends on (ARM64 && ARCH_SUNXI) || COMPILE_TEST - select SND_SUNXI_ADDA_PR_REGMAP + select SND_SUN8I_ADDA_PR_REGMAP help Say Y or M if you want to add support for the analog controls for the codec embedded in Allwinner A64 SoC. -- cgit v1.2.3-59-g8ed1b From a182ecd3809c8d5a2da80c520f3602e301c5317e Mon Sep 17 00:00:00 2001 From: Hans de Goede Date: Wed, 31 Oct 2018 15:22:25 +0100 Subject: ASoC: intel: cht_bsw_max98090_ti: Add quirk for boards using pmc_plt_clk_0 Some boards such as the Swanky model Chromebooks use pmc_plt_clk_0 for the mclk instead of pmc_plt_clk_3. This commit adds a DMI based quirk for this. This fixing audio no longer working on these devices after commit 648e921888ad ("clk: x86: Stop marking clocks as CLK_IS_CRITICAL") that commit fixes us unnecessary keeping unused clocks on, but in case of the Swanky that was breaking audio support since we were not using the right clock in the cht_bsw_max98090_ti machine driver. Cc: stable@vger.kernel.org Fixes: 648e921888ad ("clk: x86: Stop marking clocks as CLK_IS_CRITICAL") Reported-and-tested-by: Dean Wallace Signed-off-by: Hans de Goede Signed-off-by: Mark Brown --- sound/soc/intel/boards/cht_bsw_max98090_ti.c | 32 +++++++++++++++++++++++++--- 1 file changed, 29 insertions(+), 3 deletions(-) diff --git a/sound/soc/intel/boards/cht_bsw_max98090_ti.c b/sound/soc/intel/boards/cht_bsw_max98090_ti.c index db6976f4ddaa..9d9f6e41d81c 100644 --- a/sound/soc/intel/boards/cht_bsw_max98090_ti.c +++ b/sound/soc/intel/boards/cht_bsw_max98090_ti.c @@ -19,6 +19,7 @@ * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */ +#include #include #include #include @@ -35,6 +36,8 @@ #define CHT_PLAT_CLK_3_HZ 19200000 #define CHT_CODEC_DAI "HiFi" +#define QUIRK_PMC_PLT_CLK_0 0x01 + struct cht_mc_private { struct clk *mclk; struct snd_soc_jack jack; @@ -385,11 +388,29 @@ static struct snd_soc_card snd_soc_card_cht = { .num_controls = ARRAY_SIZE(cht_mc_controls), }; +static const struct dmi_system_id cht_max98090_quirk_table[] = { + { + /* Swanky model Chromebook (Toshiba Chromebook 2) */ + .matches = { + DMI_MATCH(DMI_PRODUCT_NAME, "Swanky"), + }, + .driver_data = (void *)QUIRK_PMC_PLT_CLK_0, + }, + {} +}; + static int snd_cht_mc_probe(struct platform_device *pdev) { + const struct dmi_system_id *dmi_id; struct device *dev = &pdev->dev; int ret_val = 0; struct cht_mc_private *drv; + const char *mclk_name; + int quirks = 0; + + dmi_id = dmi_first_match(cht_max98090_quirk_table); + if (dmi_id) + quirks = (unsigned long)dmi_id->driver_data; drv = devm_kzalloc(&pdev->dev, sizeof(*drv), GFP_KERNEL); if (!drv) @@ -411,11 +432,16 @@ static int snd_cht_mc_probe(struct platform_device *pdev) snd_soc_card_cht.dev = &pdev->dev; snd_soc_card_set_drvdata(&snd_soc_card_cht, drv); - drv->mclk = devm_clk_get(&pdev->dev, "pmc_plt_clk_3"); + if (quirks & QUIRK_PMC_PLT_CLK_0) + mclk_name = "pmc_plt_clk_0"; + else + mclk_name = "pmc_plt_clk_3"; + + drv->mclk = devm_clk_get(&pdev->dev, mclk_name); if (IS_ERR(drv->mclk)) { dev_err(&pdev->dev, - "Failed to get MCLK from pmc_plt_clk_3: %ld\n", - PTR_ERR(drv->mclk)); + "Failed to get MCLK from %s: %ld\n", + mclk_name, PTR_ERR(drv->mclk)); return PTR_ERR(drv->mclk); } -- cgit v1.2.3-59-g8ed1b From 112b57fa737445b2361be332ce8cc0fd3e2b994e Mon Sep 17 00:00:00 2001 From: Rohit kumar Date: Thu, 1 Nov 2018 17:21:07 +0530 Subject: ASoC: qdsp6: q6afe: Fix wrong MI2S SD line mask SD line mask for MI2S starts from BIT 0 instead of BIT 1. Fix all bit mask for MI2S SD lines. Signed-off-by: Rohit kumar Signed-off-by: Mark Brown --- sound/soc/qcom/qdsp6/q6afe.c | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/sound/soc/qcom/qdsp6/q6afe.c b/sound/soc/qcom/qdsp6/q6afe.c index 000775b4bba8..829b5e987b2a 100644 --- a/sound/soc/qcom/qdsp6/q6afe.c +++ b/sound/soc/qcom/qdsp6/q6afe.c @@ -49,14 +49,14 @@ #define AFE_PORT_I2S_SD1 0x2 #define AFE_PORT_I2S_SD2 0x3 #define AFE_PORT_I2S_SD3 0x4 -#define AFE_PORT_I2S_SD0_MASK BIT(0x1) -#define AFE_PORT_I2S_SD1_MASK BIT(0x2) -#define AFE_PORT_I2S_SD2_MASK BIT(0x3) -#define AFE_PORT_I2S_SD3_MASK BIT(0x4) -#define AFE_PORT_I2S_SD0_1_MASK GENMASK(2, 1) -#define AFE_PORT_I2S_SD2_3_MASK GENMASK(4, 3) -#define AFE_PORT_I2S_SD0_1_2_MASK GENMASK(3, 1) -#define AFE_PORT_I2S_SD0_1_2_3_MASK GENMASK(4, 1) +#define AFE_PORT_I2S_SD0_MASK BIT(0x0) +#define AFE_PORT_I2S_SD1_MASK BIT(0x1) +#define AFE_PORT_I2S_SD2_MASK BIT(0x2) +#define AFE_PORT_I2S_SD3_MASK BIT(0x3) +#define AFE_PORT_I2S_SD0_1_MASK GENMASK(1, 0) +#define AFE_PORT_I2S_SD2_3_MASK GENMASK(3, 2) +#define AFE_PORT_I2S_SD0_1_2_MASK GENMASK(2, 0) +#define AFE_PORT_I2S_SD0_1_2_3_MASK GENMASK(3, 0) #define AFE_PORT_I2S_QUAD01 0x5 #define AFE_PORT_I2S_QUAD23 0x6 #define AFE_PORT_I2S_6CHS 0x7 -- cgit v1.2.3-59-g8ed1b From 9de57ff1566fd36a664c1b04a641e26fed472a9c Mon Sep 17 00:00:00 2001 From: Srinivas Kandagatla Date: Tue, 6 Nov 2018 11:38:56 +0000 Subject: ASoC: qdsp6: q6asm-dai: Only add routing once. q6asm routing gets added multiple times as part of dai probe. Move this to q6routing routes which has those widgets defined, this also fixes the issue where these are added each time at dai probe. Signed-off-by: Srinivas Kandagatla Signed-off-by: Mark Brown --- sound/soc/qcom/qdsp6/q6asm-dai.c | 33 --------------------------------- sound/soc/qcom/qdsp6/q6routing.c | 19 +++++++++++++++++++ 2 files changed, 19 insertions(+), 33 deletions(-) diff --git a/sound/soc/qcom/qdsp6/q6asm-dai.c b/sound/soc/qcom/qdsp6/q6asm-dai.c index a16c71c03058..86115de5c1b2 100644 --- a/sound/soc/qcom/qdsp6/q6asm-dai.c +++ b/sound/soc/qcom/qdsp6/q6asm-dai.c @@ -122,7 +122,6 @@ static struct snd_pcm_hardware q6asm_dai_hardware_playback = { .rate_max = 48000, \ }, \ .name = "MultiMedia"#num, \ - .probe = fe_dai_probe, \ .id = MSM_FRONTEND_DAI_MULTIMEDIA##num, \ } @@ -511,38 +510,6 @@ static void q6asm_dai_pcm_free(struct snd_pcm *pcm) } } -static const struct snd_soc_dapm_route afe_pcm_routes[] = { - {"MM_DL1", NULL, "MultiMedia1 Playback" }, - {"MM_DL2", NULL, "MultiMedia2 Playback" }, - {"MM_DL3", NULL, "MultiMedia3 Playback" }, - {"MM_DL4", NULL, "MultiMedia4 Playback" }, - {"MM_DL5", NULL, "MultiMedia5 Playback" }, - {"MM_DL6", NULL, "MultiMedia6 Playback" }, - {"MM_DL7", NULL, "MultiMedia7 Playback" }, - {"MM_DL7", NULL, "MultiMedia8 Playback" }, - {"MultiMedia1 Capture", NULL, "MM_UL1"}, - {"MultiMedia2 Capture", NULL, "MM_UL2"}, - {"MultiMedia3 Capture", NULL, "MM_UL3"}, - {"MultiMedia4 Capture", NULL, "MM_UL4"}, - {"MultiMedia5 Capture", NULL, "MM_UL5"}, - {"MultiMedia6 Capture", NULL, "MM_UL6"}, - {"MultiMedia7 Capture", NULL, "MM_UL7"}, - {"MultiMedia8 Capture", NULL, "MM_UL8"}, - -}; - -static int fe_dai_probe(struct snd_soc_dai *dai) -{ - struct snd_soc_dapm_context *dapm; - - dapm = snd_soc_component_get_dapm(dai->component); - snd_soc_dapm_add_routes(dapm, afe_pcm_routes, - ARRAY_SIZE(afe_pcm_routes)); - - return 0; -} - - static const struct snd_soc_component_driver q6asm_fe_dai_component = { .name = DRV_NAME, .ops = &q6asm_dai_ops, diff --git a/sound/soc/qcom/qdsp6/q6routing.c b/sound/soc/qcom/qdsp6/q6routing.c index c6b51571be94..d61b8404f7da 100644 --- a/sound/soc/qcom/qdsp6/q6routing.c +++ b/sound/soc/qcom/qdsp6/q6routing.c @@ -909,6 +909,25 @@ static const struct snd_soc_dapm_route intercon[] = { {"MM_UL6", NULL, "MultiMedia6 Mixer"}, {"MM_UL7", NULL, "MultiMedia7 Mixer"}, {"MM_UL8", NULL, "MultiMedia8 Mixer"}, + + {"MM_DL1", NULL, "MultiMedia1 Playback" }, + {"MM_DL2", NULL, "MultiMedia2 Playback" }, + {"MM_DL3", NULL, "MultiMedia3 Playback" }, + {"MM_DL4", NULL, "MultiMedia4 Playback" }, + {"MM_DL5", NULL, "MultiMedia5 Playback" }, + {"MM_DL6", NULL, "MultiMedia6 Playback" }, + {"MM_DL7", NULL, "MultiMedia7 Playback" }, + {"MM_DL8", NULL, "MultiMedia8 Playback" }, + + {"MultiMedia1 Capture", NULL, "MM_UL1"}, + {"MultiMedia2 Capture", NULL, "MM_UL2"}, + {"MultiMedia3 Capture", NULL, "MM_UL3"}, + {"MultiMedia4 Capture", NULL, "MM_UL4"}, + {"MultiMedia5 Capture", NULL, "MM_UL5"}, + {"MultiMedia6 Capture", NULL, "MM_UL6"}, + {"MultiMedia7 Capture", NULL, "MM_UL7"}, + {"MultiMedia8 Capture", NULL, "MM_UL8"}, + }; static int routing_hw_params(struct snd_pcm_substream *substream, -- cgit v1.2.3-59-g8ed1b From e14856f6cfbb1b96aa45a68f188b147b5bde76b4 Mon Sep 17 00:00:00 2001 From: Srinivas Kandagatla Date: Tue, 6 Nov 2018 11:38:57 +0000 Subject: ASoC: qdsp6: q6afe-dai: Fix the dai widgets For some reason the dapm widgets are incorrectly defined from the start, Not sure how we ended up with such thing. Fix them now! Without this fix the backend dais are always powered up even if there is no active stream. Reported-by: Jimmy Cheng-Yi Chiang Reported-by: Rohit kumar Signed-off-by: Srinivas Kandagatla Signed-off-by: Mark Brown --- sound/soc/qcom/qdsp6/q6afe-dai.c | 208 +++++++++++++++++++-------------------- 1 file changed, 104 insertions(+), 104 deletions(-) diff --git a/sound/soc/qcom/qdsp6/q6afe-dai.c b/sound/soc/qcom/qdsp6/q6afe-dai.c index 60ff4a2d3577..8f6c8fc073a9 100644 --- a/sound/soc/qcom/qdsp6/q6afe-dai.c +++ b/sound/soc/qcom/qdsp6/q6afe-dai.c @@ -1112,204 +1112,204 @@ static int q6afe_of_xlate_dai_name(struct snd_soc_component *component, } static const struct snd_soc_dapm_widget q6afe_dai_widgets[] = { - SND_SOC_DAPM_AIF_OUT("HDMI_RX", "HDMI Playback", 0, 0, 0, 0), - SND_SOC_DAPM_AIF_OUT("SLIMBUS_0_RX", "Slimbus Playback", 0, 0, 0, 0), - SND_SOC_DAPM_AIF_OUT("SLIMBUS_1_RX", "Slimbus1 Playback", 0, 0, 0, 0), - SND_SOC_DAPM_AIF_OUT("SLIMBUS_2_RX", "Slimbus2 Playback", 0, 0, 0, 0), - SND_SOC_DAPM_AIF_OUT("SLIMBUS_3_RX", "Slimbus3 Playback", 0, 0, 0, 0), - SND_SOC_DAPM_AIF_OUT("SLIMBUS_4_RX", "Slimbus4 Playback", 0, 0, 0, 0), - SND_SOC_DAPM_AIF_OUT("SLIMBUS_5_RX", "Slimbus5 Playback", 0, 0, 0, 0), - SND_SOC_DAPM_AIF_OUT("SLIMBUS_6_RX", "Slimbus6 Playback", 0, 0, 0, 0), - SND_SOC_DAPM_AIF_IN("SLIMBUS_0_TX", "Slimbus Capture", 0, 0, 0, 0), - SND_SOC_DAPM_AIF_IN("SLIMBUS_1_TX", "Slimbus1 Capture", 0, 0, 0, 0), - SND_SOC_DAPM_AIF_IN("SLIMBUS_2_TX", "Slimbus2 Capture", 0, 0, 0, 0), - SND_SOC_DAPM_AIF_IN("SLIMBUS_3_TX", "Slimbus3 Capture", 0, 0, 0, 0), - SND_SOC_DAPM_AIF_IN("SLIMBUS_4_TX", "Slimbus4 Capture", 0, 0, 0, 0), - SND_SOC_DAPM_AIF_IN("SLIMBUS_5_TX", "Slimbus5 Capture", 0, 0, 0, 0), - SND_SOC_DAPM_AIF_IN("SLIMBUS_6_TX", "Slimbus6 Capture", 0, 0, 0, 0), - SND_SOC_DAPM_AIF_OUT("QUAT_MI2S_RX", "Quaternary MI2S Playback", + SND_SOC_DAPM_AIF_IN("HDMI_RX", NULL, 0, 0, 0, 0), + SND_SOC_DAPM_AIF_IN("SLIMBUS_0_RX", NULL, 0, 0, 0, 0), + SND_SOC_DAPM_AIF_IN("SLIMBUS_1_RX", NULL, 0, 0, 0, 0), + SND_SOC_DAPM_AIF_IN("SLIMBUS_2_RX", NULL, 0, 0, 0, 0), + SND_SOC_DAPM_AIF_IN("SLIMBUS_3_RX", NULL, 0, 0, 0, 0), + SND_SOC_DAPM_AIF_IN("SLIMBUS_4_RX", NULL, 0, 0, 0, 0), + SND_SOC_DAPM_AIF_IN("SLIMBUS_5_RX", NULL, 0, 0, 0, 0), + SND_SOC_DAPM_AIF_IN("SLIMBUS_6_RX", NULL, 0, 0, 0, 0), + SND_SOC_DAPM_AIF_OUT("SLIMBUS_0_TX", NULL, 0, 0, 0, 0), + SND_SOC_DAPM_AIF_OUT("SLIMBUS_1_TX", NULL, 0, 0, 0, 0), + SND_SOC_DAPM_AIF_OUT("SLIMBUS_2_TX", NULL, 0, 0, 0, 0), + SND_SOC_DAPM_AIF_OUT("SLIMBUS_3_TX", NULL, 0, 0, 0, 0), + SND_SOC_DAPM_AIF_OUT("SLIMBUS_4_TX", NULL, 0, 0, 0, 0), + SND_SOC_DAPM_AIF_OUT("SLIMBUS_5_TX", NULL, 0, 0, 0, 0), + SND_SOC_DAPM_AIF_OUT("SLIMBUS_6_TX", NULL, 0, 0, 0, 0), + SND_SOC_DAPM_AIF_IN("QUAT_MI2S_RX", NULL, 0, 0, 0, 0), - SND_SOC_DAPM_AIF_IN("QUAT_MI2S_TX", "Quaternary MI2S Capture", + SND_SOC_DAPM_AIF_OUT("QUAT_MI2S_TX", NULL, 0, 0, 0, 0), - SND_SOC_DAPM_AIF_OUT("TERT_MI2S_RX", "Tertiary MI2S Playback", + SND_SOC_DAPM_AIF_IN("TERT_MI2S_RX", NULL, 0, 0, 0, 0), - SND_SOC_DAPM_AIF_IN("TERT_MI2S_TX", "Tertiary MI2S Capture", + SND_SOC_DAPM_AIF_OUT("TERT_MI2S_TX", NULL, 0, 0, 0, 0), - SND_SOC_DAPM_AIF_OUT("SEC_MI2S_RX", "Secondary MI2S Playback", + SND_SOC_DAPM_AIF_IN("SEC_MI2S_RX", NULL, 0, 0, 0, 0), - SND_SOC_DAPM_AIF_IN("SEC_MI2S_TX", "Secondary MI2S Capture", + SND_SOC_DAPM_AIF_OUT("SEC_MI2S_TX", NULL, 0, 0, 0, 0), - SND_SOC_DAPM_AIF_OUT("SEC_MI2S_RX_SD1", + SND_SOC_DAPM_AIF_IN("SEC_MI2S_RX_SD1", "Secondary MI2S Playback SD1", 0, 0, 0, 0), - SND_SOC_DAPM_AIF_OUT("PRI_MI2S_RX", "Primary MI2S Playback", + SND_SOC_DAPM_AIF_IN("PRI_MI2S_RX", NULL, 0, 0, 0, 0), - SND_SOC_DAPM_AIF_IN("PRI_MI2S_TX", "Primary MI2S Capture", + SND_SOC_DAPM_AIF_OUT("PRI_MI2S_TX", NULL, 0, 0, 0, 0), - SND_SOC_DAPM_AIF_OUT("PRIMARY_TDM_RX_0", "Primary TDM0 Playback", + SND_SOC_DAPM_AIF_IN("PRIMARY_TDM_RX_0", NULL, 0, 0, 0, 0), - SND_SOC_DAPM_AIF_OUT("PRIMARY_TDM_RX_1", "Primary TDM1 Playback", + SND_SOC_DAPM_AIF_IN("PRIMARY_TDM_RX_1", NULL, 0, 0, 0, 0), - SND_SOC_DAPM_AIF_OUT("PRIMARY_TDM_RX_2", "Primary TDM2 Playback", + SND_SOC_DAPM_AIF_IN("PRIMARY_TDM_RX_2", NULL, 0, 0, 0, 0), - SND_SOC_DAPM_AIF_OUT("PRIMARY_TDM_RX_3", "Primary TDM3 Playback", + SND_SOC_DAPM_AIF_IN("PRIMARY_TDM_RX_3", NULL, 0, 0, 0, 0), - SND_SOC_DAPM_AIF_OUT("PRIMARY_TDM_RX_4", "Primary TDM4 Playback", + SND_SOC_DAPM_AIF_IN("PRIMARY_TDM_RX_4", NULL, 0, 0, 0, 0), - SND_SOC_DAPM_AIF_OUT("PRIMARY_TDM_RX_5", "Primary TDM5 Playback", + SND_SOC_DAPM_AIF_IN("PRIMARY_TDM_RX_5", NULL, 0, 0, 0, 0), - SND_SOC_DAPM_AIF_OUT("PRIMARY_TDM_RX_6", "Primary TDM6 Playback", + SND_SOC_DAPM_AIF_IN("PRIMARY_TDM_RX_6", NULL, 0, 0, 0, 0), - SND_SOC_DAPM_AIF_OUT("PRIMARY_TDM_RX_7", "Primary TDM7 Playback", + SND_SOC_DAPM_AIF_IN("PRIMARY_TDM_RX_7", NULL, 0, 0, 0, 0), - SND_SOC_DAPM_AIF_IN("PRIMARY_TDM_TX_0", "Primary TDM0 Capture", + SND_SOC_DAPM_AIF_OUT("PRIMARY_TDM_TX_0", NULL, 0, 0, 0, 0), - SND_SOC_DAPM_AIF_IN("PRIMARY_TDM_TX_1", "Primary TDM1 Capture", + SND_SOC_DAPM_AIF_OUT("PRIMARY_TDM_TX_1", NULL, 0, 0, 0, 0), - SND_SOC_DAPM_AIF_IN("PRIMARY_TDM_TX_2", "Primary TDM2 Capture", + SND_SOC_DAPM_AIF_OUT("PRIMARY_TDM_TX_2", NULL, 0, 0, 0, 0), - SND_SOC_DAPM_AIF_IN("PRIMARY_TDM_TX_3", "Primary TDM3 Capture", + SND_SOC_DAPM_AIF_OUT("PRIMARY_TDM_TX_3", NULL, 0, 0, 0, 0), - SND_SOC_DAPM_AIF_IN("PRIMARY_TDM_TX_4", "Primary TDM4 Capture", + SND_SOC_DAPM_AIF_OUT("PRIMARY_TDM_TX_4", NULL, 0, 0, 0, 0), - SND_SOC_DAPM_AIF_IN("PRIMARY_TDM_TX_5", "Primary TDM5 Capture", + SND_SOC_DAPM_AIF_OUT("PRIMARY_TDM_TX_5", NULL, 0, 0, 0, 0), - SND_SOC_DAPM_AIF_IN("PRIMARY_TDM_TX_6", "Primary TDM6 Capture", + SND_SOC_DAPM_AIF_OUT("PRIMARY_TDM_TX_6", NULL, 0, 0, 0, 0), - SND_SOC_DAPM_AIF_IN("PRIMARY_TDM_TX_7", "Primary TDM7 Capture", + SND_SOC_DAPM_AIF_OUT("PRIMARY_TDM_TX_7", NULL, 0, 0, 0, 0), - SND_SOC_DAPM_AIF_OUT("SEC_TDM_RX_0", "Secondary TDM0 Playback", + SND_SOC_DAPM_AIF_IN("SEC_TDM_RX_0", NULL, 0, 0, 0, 0), - SND_SOC_DAPM_AIF_OUT("SEC_TDM_RX_1", "Secondary TDM1 Playback", + SND_SOC_DAPM_AIF_IN("SEC_TDM_RX_1", NULL, 0, 0, 0, 0), - SND_SOC_DAPM_AIF_OUT("SEC_TDM_RX_2", "Secondary TDM2 Playback", + SND_SOC_DAPM_AIF_IN("SEC_TDM_RX_2", NULL, 0, 0, 0, 0), - SND_SOC_DAPM_AIF_OUT("SEC_TDM_RX_3", "Secondary TDM3 Playback", + SND_SOC_DAPM_AIF_IN("SEC_TDM_RX_3", NULL, 0, 0, 0, 0), - SND_SOC_DAPM_AIF_OUT("SEC_TDM_RX_4", "Secondary TDM4 Playback", + SND_SOC_DAPM_AIF_IN("SEC_TDM_RX_4", NULL, 0, 0, 0, 0), - SND_SOC_DAPM_AIF_OUT("SEC_TDM_RX_5", "Secondary TDM5 Playback", + SND_SOC_DAPM_AIF_IN("SEC_TDM_RX_5", NULL, 0, 0, 0, 0), - SND_SOC_DAPM_AIF_OUT("SEC_TDM_RX_6", "Secondary TDM6 Playback", + SND_SOC_DAPM_AIF_IN("SEC_TDM_RX_6", NULL, 0, 0, 0, 0), - SND_SOC_DAPM_AIF_OUT("SEC_TDM_RX_7", "Secondary TDM7 Playback", + SND_SOC_DAPM_AIF_IN("SEC_TDM_RX_7", NULL, 0, 0, 0, 0), - SND_SOC_DAPM_AIF_IN("SEC_TDM_TX_0", "Secondary TDM0 Capture", + SND_SOC_DAPM_AIF_OUT("SEC_TDM_TX_0", NULL, 0, 0, 0, 0), - SND_SOC_DAPM_AIF_IN("SEC_TDM_TX_1", "Secondary TDM1 Capture", + SND_SOC_DAPM_AIF_OUT("SEC_TDM_TX_1", NULL, 0, 0, 0, 0), - SND_SOC_DAPM_AIF_IN("SEC_TDM_TX_2", "Secondary TDM2 Capture", + SND_SOC_DAPM_AIF_OUT("SEC_TDM_TX_2", NULL, 0, 0, 0, 0), - SND_SOC_DAPM_AIF_IN("SEC_TDM_TX_3", "Secondary TDM3 Capture", + SND_SOC_DAPM_AIF_OUT("SEC_TDM_TX_3", NULL, 0, 0, 0, 0), - SND_SOC_DAPM_AIF_IN("SEC_TDM_TX_4", "Secondary TDM4 Capture", + SND_SOC_DAPM_AIF_OUT("SEC_TDM_TX_4", NULL, 0, 0, 0, 0), - SND_SOC_DAPM_AIF_IN("SEC_TDM_TX_5", "Secondary TDM5 Capture", + SND_SOC_DAPM_AIF_OUT("SEC_TDM_TX_5", NULL, 0, 0, 0, 0), - SND_SOC_DAPM_AIF_IN("SEC_TDM_TX_6", "Secondary TDM6 Capture", + SND_SOC_DAPM_AIF_OUT("SEC_TDM_TX_6", NULL, 0, 0, 0, 0), - SND_SOC_DAPM_AIF_IN("SEC_TDM_TX_7", "Secondary TDM7 Capture", + SND_SOC_DAPM_AIF_OUT("SEC_TDM_TX_7", NULL, 0, 0, 0, 0), - SND_SOC_DAPM_AIF_OUT("TERT_TDM_RX_0", "Tertiary TDM0 Playback", + SND_SOC_DAPM_AIF_IN("TERT_TDM_RX_0", NULL, 0, 0, 0, 0), - SND_SOC_DAPM_AIF_OUT("TERT_TDM_RX_1", "Tertiary TDM1 Playback", + SND_SOC_DAPM_AIF_IN("TERT_TDM_RX_1", NULL, 0, 0, 0, 0), - SND_SOC_DAPM_AIF_OUT("TERT_TDM_RX_2", "Tertiary TDM2 Playback", + SND_SOC_DAPM_AIF_IN("TERT_TDM_RX_2", NULL, 0, 0, 0, 0), - SND_SOC_DAPM_AIF_OUT("TERT_TDM_RX_3", "Tertiary TDM3 Playback", + SND_SOC_DAPM_AIF_IN("TERT_TDM_RX_3", NULL, 0, 0, 0, 0), - SND_SOC_DAPM_AIF_OUT("TERT_TDM_RX_4", "Tertiary TDM4 Playback", + SND_SOC_DAPM_AIF_IN("TERT_TDM_RX_4", NULL, 0, 0, 0, 0), - SND_SOC_DAPM_AIF_OUT("TERT_TDM_RX_5", "Tertiary TDM5 Playback", + SND_SOC_DAPM_AIF_IN("TERT_TDM_RX_5", NULL, 0, 0, 0, 0), - SND_SOC_DAPM_AIF_OUT("TERT_TDM_RX_6", "Tertiary TDM6 Playback", + SND_SOC_DAPM_AIF_IN("TERT_TDM_RX_6", NULL, 0, 0, 0, 0), - SND_SOC_DAPM_AIF_OUT("TERT_TDM_RX_7", "Tertiary TDM7 Playback", + SND_SOC_DAPM_AIF_IN("TERT_TDM_RX_7", NULL, 0, 0, 0, 0), - SND_SOC_DAPM_AIF_IN("TERT_TDM_TX_0", "Tertiary TDM0 Capture", + SND_SOC_DAPM_AIF_OUT("TERT_TDM_TX_0", NULL, 0, 0, 0, 0), - SND_SOC_DAPM_AIF_IN("TERT_TDM_TX_1", "Tertiary TDM1 Capture", + SND_SOC_DAPM_AIF_OUT("TERT_TDM_TX_1", NULL, 0, 0, 0, 0), - SND_SOC_DAPM_AIF_IN("TERT_TDM_TX_2", "Tertiary TDM2 Capture", + SND_SOC_DAPM_AIF_OUT("TERT_TDM_TX_2", NULL, 0, 0, 0, 0), - SND_SOC_DAPM_AIF_IN("TERT_TDM_TX_3", "Tertiary TDM3 Capture", + SND_SOC_DAPM_AIF_OUT("TERT_TDM_TX_3", NULL, 0, 0, 0, 0), - SND_SOC_DAPM_AIF_IN("TERT_TDM_TX_4", "Tertiary TDM4 Capture", + SND_SOC_DAPM_AIF_OUT("TERT_TDM_TX_4", NULL, 0, 0, 0, 0), - SND_SOC_DAPM_AIF_IN("TERT_TDM_TX_5", "Tertiary TDM5 Capture", + SND_SOC_DAPM_AIF_OUT("TERT_TDM_TX_5", NULL, 0, 0, 0, 0), - SND_SOC_DAPM_AIF_IN("TERT_TDM_TX_6", "Tertiary TDM6 Capture", + SND_SOC_DAPM_AIF_OUT("TERT_TDM_TX_6", NULL, 0, 0, 0, 0), - SND_SOC_DAPM_AIF_IN("TERT_TDM_TX_7", "Tertiary TDM7 Capture", + SND_SOC_DAPM_AIF_OUT("TERT_TDM_TX_7", NULL, 0, 0, 0, 0), - SND_SOC_DAPM_AIF_OUT("QUAT_TDM_RX_0", "Quaternary TDM0 Playback", + SND_SOC_DAPM_AIF_IN("QUAT_TDM_RX_0", NULL, 0, 0, 0, 0), - SND_SOC_DAPM_AIF_OUT("QUAT_TDM_RX_1", "Quaternary TDM1 Playback", + SND_SOC_DAPM_AIF_IN("QUAT_TDM_RX_1", NULL, 0, 0, 0, 0), - SND_SOC_DAPM_AIF_OUT("QUAT_TDM_RX_2", "Quaternary TDM2 Playback", + SND_SOC_DAPM_AIF_IN("QUAT_TDM_RX_2", NULL, 0, 0, 0, 0), - SND_SOC_DAPM_AIF_OUT("QUAT_TDM_RX_3", "Quaternary TDM3 Playback", + SND_SOC_DAPM_AIF_IN("QUAT_TDM_RX_3", NULL, 0, 0, 0, 0), - SND_SOC_DAPM_AIF_OUT("QUAT_TDM_RX_4", "Quaternary TDM4 Playback", + SND_SOC_DAPM_AIF_IN("QUAT_TDM_RX_4", NULL, 0, 0, 0, 0), - SND_SOC_DAPM_AIF_OUT("QUAT_TDM_RX_5", "Quaternary TDM5 Playback", + SND_SOC_DAPM_AIF_IN("QUAT_TDM_RX_5", NULL, 0, 0, 0, 0), - SND_SOC_DAPM_AIF_OUT("QUAT_TDM_RX_6", "Quaternary TDM6 Playback", + SND_SOC_DAPM_AIF_IN("QUAT_TDM_RX_6", NULL, 0, 0, 0, 0), - SND_SOC_DAPM_AIF_OUT("QUAT_TDM_RX_7", "Quaternary TDM7 Playback", + SND_SOC_DAPM_AIF_IN("QUAT_TDM_RX_7", NULL, 0, 0, 0, 0), - SND_SOC_DAPM_AIF_IN("QUAT_TDM_TX_0", "Quaternary TDM0 Capture", + SND_SOC_DAPM_AIF_OUT("QUAT_TDM_TX_0", NULL, 0, 0, 0, 0), - SND_SOC_DAPM_AIF_IN("QUAT_TDM_TX_1", "Quaternary TDM1 Capture", + SND_SOC_DAPM_AIF_OUT("QUAT_TDM_TX_1", NULL, 0, 0, 0, 0), - SND_SOC_DAPM_AIF_IN("QUAT_TDM_TX_2", "Quaternary TDM2 Capture", + SND_SOC_DAPM_AIF_OUT("QUAT_TDM_TX_2", NULL, 0, 0, 0, 0), - SND_SOC_DAPM_AIF_IN("QUAT_TDM_TX_3", "Quaternary TDM3 Capture", + SND_SOC_DAPM_AIF_OUT("QUAT_TDM_TX_3", NULL, 0, 0, 0, 0), - SND_SOC_DAPM_AIF_IN("QUAT_TDM_TX_4", "Quaternary TDM4 Capture", + SND_SOC_DAPM_AIF_OUT("QUAT_TDM_TX_4", NULL, 0, 0, 0, 0), - SND_SOC_DAPM_AIF_IN("QUAT_TDM_TX_5", "Quaternary TDM5 Capture", + SND_SOC_DAPM_AIF_OUT("QUAT_TDM_TX_5", NULL, 0, 0, 0, 0), - SND_SOC_DAPM_AIF_IN("QUAT_TDM_TX_6", "Quaternary TDM6 Capture", + SND_SOC_DAPM_AIF_OUT("QUAT_TDM_TX_6", NULL, 0, 0, 0, 0), - SND_SOC_DAPM_AIF_IN("QUAT_TDM_TX_7", "Quaternary TDM7 Capture", + SND_SOC_DAPM_AIF_OUT("QUAT_TDM_TX_7", NULL, 0, 0, 0, 0), - SND_SOC_DAPM_AIF_OUT("QUIN_TDM_RX_0", "Quinary TDM0 Playback", + SND_SOC_DAPM_AIF_IN("QUIN_TDM_RX_0", NULL, 0, 0, 0, 0), - SND_SOC_DAPM_AIF_OUT("QUIN_TDM_RX_1", "Quinary TDM1 Playback", + SND_SOC_DAPM_AIF_IN("QUIN_TDM_RX_1", NULL, 0, 0, 0, 0), - SND_SOC_DAPM_AIF_OUT("QUIN_TDM_RX_2", "Quinary TDM2 Playback", + SND_SOC_DAPM_AIF_IN("QUIN_TDM_RX_2", NULL, 0, 0, 0, 0), - SND_SOC_DAPM_AIF_OUT("QUIN_TDM_RX_3", "Quinary TDM3 Playback", + SND_SOC_DAPM_AIF_IN("QUIN_TDM_RX_3", NULL, 0, 0, 0, 0), - SND_SOC_DAPM_AIF_OUT("QUIN_TDM_RX_4", "Quinary TDM4 Playback", + SND_SOC_DAPM_AIF_IN("QUIN_TDM_RX_4", NULL, 0, 0, 0, 0), - SND_SOC_DAPM_AIF_OUT("QUIN_TDM_RX_5", "Quinary TDM5 Playback", + SND_SOC_DAPM_AIF_IN("QUIN_TDM_RX_5", NULL, 0, 0, 0, 0), - SND_SOC_DAPM_AIF_OUT("QUIN_TDM_RX_6", "Quinary TDM6 Playback", + SND_SOC_DAPM_AIF_IN("QUIN_TDM_RX_6", NULL, 0, 0, 0, 0), - SND_SOC_DAPM_AIF_OUT("QUIN_TDM_RX_7", "Quinary TDM7 Playback", + SND_SOC_DAPM_AIF_IN("QUIN_TDM_RX_7", NULL, 0, 0, 0, 0), - SND_SOC_DAPM_AIF_IN("QUIN_TDM_TX_0", "Quinary TDM0 Capture", + SND_SOC_DAPM_AIF_OUT("QUIN_TDM_TX_0", NULL, 0, 0, 0, 0), - SND_SOC_DAPM_AIF_IN("QUIN_TDM_TX_1", "Quinary TDM1 Capture", + SND_SOC_DAPM_AIF_OUT("QUIN_TDM_TX_1", NULL, 0, 0, 0, 0), - SND_SOC_DAPM_AIF_IN("QUIN_TDM_TX_2", "Quinary TDM2 Capture", + SND_SOC_DAPM_AIF_OUT("QUIN_TDM_TX_2", NULL, 0, 0, 0, 0), - SND_SOC_DAPM_AIF_IN("QUIN_TDM_TX_3", "Quinary TDM3 Capture", + SND_SOC_DAPM_AIF_OUT("QUIN_TDM_TX_3", NULL, 0, 0, 0, 0), - SND_SOC_DAPM_AIF_IN("QUIN_TDM_TX_4", "Quinary TDM4 Capture", + SND_SOC_DAPM_AIF_OUT("QUIN_TDM_TX_4", NULL, 0, 0, 0, 0), - SND_SOC_DAPM_AIF_IN("QUIN_TDM_TX_5", "Quinary TDM5 Capture", + SND_SOC_DAPM_AIF_OUT("QUIN_TDM_TX_5", NULL, 0, 0, 0, 0), - SND_SOC_DAPM_AIF_IN("QUIN_TDM_TX_6", "Quinary TDM6 Capture", + SND_SOC_DAPM_AIF_OUT("QUIN_TDM_TX_6", NULL, 0, 0, 0, 0), - SND_SOC_DAPM_AIF_IN("QUIN_TDM_TX_7", "Quinary TDM7 Capture", + SND_SOC_DAPM_AIF_OUT("QUIN_TDM_TX_7", NULL, 0, 0, 0, 0), }; -- cgit v1.2.3-59-g8ed1b From 278df5e5527b633f4882f1680ad58b62a7c07bfe Mon Sep 17 00:00:00 2001 From: Vasily Khoruzhick Date: Thu, 8 Nov 2018 20:31:35 -0800 Subject: ASoC: sun8i-codec: fix crash on module removal drvdata is actually sun8i_codec, not snd_soc_card, so it crashes when calling snd_soc_card_get_drvdata(). Drop card and scodec vars anyway since we don't need to disable/unprepare clocks - it's already done by calling runtime_suspend() Drop clk_disable_unprepare() calls for the same reason. Fixes: 36c684936fae7 ("ASoC: Add sun8i digital audio codec") Signed-off-by: Vasily Khoruzhick Acked-by: Maxime Ripard Signed-off-by: Mark Brown --- sound/soc/sunxi/sun8i-codec.c | 6 ------ 1 file changed, 6 deletions(-) diff --git a/sound/soc/sunxi/sun8i-codec.c b/sound/soc/sunxi/sun8i-codec.c index 522a72fde78d..c4196d4e5915 100644 --- a/sound/soc/sunxi/sun8i-codec.c +++ b/sound/soc/sunxi/sun8i-codec.c @@ -605,16 +605,10 @@ err_pm_disable: static int sun8i_codec_remove(struct platform_device *pdev) { - struct snd_soc_card *card = platform_get_drvdata(pdev); - struct sun8i_codec *scodec = snd_soc_card_get_drvdata(card); - pm_runtime_disable(&pdev->dev); if (!pm_runtime_status_suspended(&pdev->dev)) sun8i_codec_runtime_suspend(&pdev->dev); - clk_disable_unprepare(scodec->clk_module); - clk_disable_unprepare(scodec->clk_bus); - return 0; } -- cgit v1.2.3-59-g8ed1b From 16a8ee4c80b45984b6de1f90a49edcf336b7c621 Mon Sep 17 00:00:00 2001 From: Katsuhiro Suzuki Date: Sun, 11 Nov 2018 00:18:44 +0900 Subject: ASoC: rockchip: add missing slave_config setting for I2S This patch adds missing prepare_sleve_config that is needed for setup the DMA slave channel for I2S. Signed-off-by: Katsuhiro Suzuki Signed-off-by: Mark Brown --- sound/soc/rockchip/rockchip_pcm.c | 1 + 1 file changed, 1 insertion(+) diff --git a/sound/soc/rockchip/rockchip_pcm.c b/sound/soc/rockchip/rockchip_pcm.c index 9e7b5fa4cf59..4ac78d7a4b2d 100644 --- a/sound/soc/rockchip/rockchip_pcm.c +++ b/sound/soc/rockchip/rockchip_pcm.c @@ -33,6 +33,7 @@ static const struct snd_pcm_hardware snd_rockchip_hardware = { static const struct snd_dmaengine_pcm_config rk_dmaengine_pcm_config = { .pcm_hardware = &snd_rockchip_hardware, + .prepare_slave_config = snd_dmaengine_pcm_prepare_slave_config, .prealloc_buffer_size = 32 * 1024, }; -- cgit v1.2.3-59-g8ed1b From 20e00db2f59bdddf8a8e241473ef8be94631d3ae Mon Sep 17 00:00:00 2001 From: Richard Fitzgerald Date: Mon, 12 Nov 2018 13:36:38 +0000 Subject: ASoC: wm_adsp: Fix dma-unsafe read of scratch registers Stack memory isn't DMA-safe so it isn't safe to use either regmap_raw_read or regmap_bulk_read to read into stack memory. The two functions to read the scratch registers were using stack memory and regmap_raw_read. It's not worth allocating memory just for this trivial read, and it isn't time-critical. A simple regmap_read for each register is sufficient. Signed-off-by: Richard Fitzgerald Signed-off-by: Mark Brown --- sound/soc/codecs/wm_adsp.c | 37 ++++++++++++++++++++----------------- 1 file changed, 20 insertions(+), 17 deletions(-) diff --git a/sound/soc/codecs/wm_adsp.c b/sound/soc/codecs/wm_adsp.c index a53dc174bbf0..66501b8dc46f 100644 --- a/sound/soc/codecs/wm_adsp.c +++ b/sound/soc/codecs/wm_adsp.c @@ -765,38 +765,41 @@ static unsigned int wm_adsp_region_to_reg(struct wm_adsp_region const *mem, static void wm_adsp2_show_fw_status(struct wm_adsp *dsp) { - u16 scratch[4]; + unsigned int scratch[4]; + unsigned int addr = dsp->base + ADSP2_SCRATCH0; + unsigned int i; int ret; - ret = regmap_raw_read(dsp->regmap, dsp->base + ADSP2_SCRATCH0, - scratch, sizeof(scratch)); - if (ret) { - adsp_err(dsp, "Failed to read SCRATCH regs: %d\n", ret); - return; + for (i = 0; i < ARRAY_SIZE(scratch); ++i) { + ret = regmap_read(dsp->regmap, addr + i, &scratch[i]); + if (ret) { + adsp_err(dsp, "Failed to read SCRATCH%u: %d\n", i, ret); + return; + } } adsp_dbg(dsp, "FW SCRATCH 0:0x%x 1:0x%x 2:0x%x 3:0x%x\n", - be16_to_cpu(scratch[0]), - be16_to_cpu(scratch[1]), - be16_to_cpu(scratch[2]), - be16_to_cpu(scratch[3])); + scratch[0], scratch[1], scratch[2], scratch[3]); } static void wm_adsp2v2_show_fw_status(struct wm_adsp *dsp) { - u32 scratch[2]; + unsigned int scratch[2]; int ret; - ret = regmap_raw_read(dsp->regmap, dsp->base + ADSP2V2_SCRATCH0_1, - scratch, sizeof(scratch)); - + ret = regmap_read(dsp->regmap, dsp->base + ADSP2V2_SCRATCH0_1, + &scratch[0]); if (ret) { - adsp_err(dsp, "Failed to read SCRATCH regs: %d\n", ret); + adsp_err(dsp, "Failed to read SCRATCH0_1: %d\n", ret); return; } - scratch[0] = be32_to_cpu(scratch[0]); - scratch[1] = be32_to_cpu(scratch[1]); + ret = regmap_read(dsp->regmap, dsp->base + ADSP2V2_SCRATCH2_3, + &scratch[1]); + if (ret) { + adsp_err(dsp, "Failed to read SCRATCH2_3: %d\n", ret); + return; + } adsp_dbg(dsp, "FW SCRATCH 0:0x%x 1:0x%x 2:0x%x 3:0x%x\n", scratch[0] & 0xFFFF, -- cgit v1.2.3-59-g8ed1b From 4c10473d6ddf12ec124c9ff71a5d23bb5388478b Mon Sep 17 00:00:00 2001 From: Pierre-Louis Bossart Date: Fri, 9 Nov 2018 13:39:23 -0600 Subject: ASoC: Intel: Power down links before turning off display audio power On certain platforms, Display HDMI HDA codec was not going to sleep state after the use when links are powered down after turning off the display power. As per the HW recommendation, links are powered down before turning off the display power to ensure that the codec goes to sleep state. This patch was updated from an earlier version submitted upstream [1] which conflicted with the changes merged for HDaudio codec support with the Intel DSP. [1] https://patchwork.kernel.org/patch/10540213/ Signed-off-by: Sriram Periyasamy Signed-off-by: Sanyog Kale Signed-off-by: Pierre-Louis Bossart Signed-off-by: Mark Brown --- sound/soc/codecs/hdac_hdmi.c | 11 +++++------ sound/soc/intel/skylake/skl.c | 12 ++++++------ 2 files changed, 11 insertions(+), 12 deletions(-) diff --git a/sound/soc/codecs/hdac_hdmi.c b/sound/soc/codecs/hdac_hdmi.c index 4e9854889a95..e63d6e33df48 100644 --- a/sound/soc/codecs/hdac_hdmi.c +++ b/sound/soc/codecs/hdac_hdmi.c @@ -2187,11 +2187,6 @@ static int hdac_hdmi_runtime_suspend(struct device *dev) */ snd_hdac_codec_read(hdev, hdev->afg, 0, AC_VERB_SET_POWER_STATE, AC_PWRST_D3); - err = snd_hdac_display_power(bus, false); - if (err < 0) { - dev_err(dev, "Cannot turn on display power on i915\n"); - return err; - } hlink = snd_hdac_ext_bus_get_link(bus, dev_name(dev)); if (!hlink) { @@ -2201,7 +2196,11 @@ static int hdac_hdmi_runtime_suspend(struct device *dev) snd_hdac_ext_bus_link_put(bus, hlink); - return 0; + err = snd_hdac_display_power(bus, false); + if (err < 0) + dev_err(dev, "Cannot turn off display power on i915\n"); + + return err; } static int hdac_hdmi_runtime_resume(struct device *dev) diff --git a/sound/soc/intel/skylake/skl.c b/sound/soc/intel/skylake/skl.c index 29225623b4b4..1586c97d9450 100644 --- a/sound/soc/intel/skylake/skl.c +++ b/sound/soc/intel/skylake/skl.c @@ -815,6 +815,12 @@ static void skl_probe_work(struct work_struct *work) } } + /* + * we are done probing so decrement link counts + */ + list_for_each_entry(hlink, &bus->hlink_list, list) + snd_hdac_ext_bus_link_put(bus, hlink); + if (IS_ENABLED(CONFIG_SND_SOC_HDAC_HDMI)) { err = snd_hdac_display_power(bus, false); if (err < 0) { @@ -824,12 +830,6 @@ static void skl_probe_work(struct work_struct *work) } } - /* - * we are done probing so decrement link counts - */ - list_for_each_entry(hlink, &bus->hlink_list, list) - snd_hdac_ext_bus_link_put(bus, hlink); - /* configure PM */ pm_runtime_put_noidle(bus->dev); pm_runtime_allow(bus->dev); -- cgit v1.2.3-59-g8ed1b From 9ee325d029c4abb75716851ce38863845911d605 Mon Sep 17 00:00:00 2001 From: Vasily Khoruzhick Date: Thu, 8 Nov 2018 20:24:19 -0800 Subject: ASoC: sun8i-codec: add missing route for ADC sun8i-codec misses a route from ADC to AIF1 Slot 0 ADC. Add it to the driver to avoid adding it to every dts. Fixes: eda85d1fee05d ("ASoC: sun8i-codec: Add ADC support for a33") Signed-off-by: Vasily Khoruzhick Signed-off-by: Mark Brown --- sound/soc/sunxi/sun8i-codec.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/sound/soc/sunxi/sun8i-codec.c b/sound/soc/sunxi/sun8i-codec.c index c4196d4e5915..92c5de026c43 100644 --- a/sound/soc/sunxi/sun8i-codec.c +++ b/sound/soc/sunxi/sun8i-codec.c @@ -481,7 +481,11 @@ static const struct snd_soc_dapm_route sun8i_codec_dapm_routes[] = { { "Right Digital DAC Mixer", "AIF1 Slot 0 Digital DAC Playback Switch", "AIF1 Slot 0 Right"}, - /* ADC routes */ + /* ADC Routes */ + { "AIF1 Slot 0 Right ADC", NULL, "ADC" }, + { "AIF1 Slot 0 Left ADC", NULL, "ADC" }, + + /* ADC Mixer Routes */ { "Left Digital ADC Mixer", "AIF1 Data Digital ADC Capture Switch", "AIF1 Slot 0 Left ADC" }, { "Right Digital ADC Mixer", "AIF1 Data Digital ADC Capture Switch", -- cgit v1.2.3-59-g8ed1b From 67fd1437d11620de8768b22fe20942e752ed52e9 Mon Sep 17 00:00:00 2001 From: Rohit kumar Date: Thu, 8 Nov 2018 19:11:40 +0530 Subject: ASoC: qcom: Set dai_link id to each dai_link Frontend dai_link id is used for closing ADM sessions. During concurrent usecase when one session is closed, it closes other ADM session associated with other usecase too. Dai_link->id should always point to Frontend dai id. Set cpu_dai id as dai_link id to fix the issue. Signed-off-by: Rohit kumar Acked-by: Srinivas Kandagatla Signed-off-by: Mark Brown --- sound/soc/qcom/common.c | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/sound/soc/qcom/common.c b/sound/soc/qcom/common.c index eb1b9da05dd4..4715527054e5 100644 --- a/sound/soc/qcom/common.c +++ b/sound/soc/qcom/common.c @@ -13,6 +13,7 @@ int qcom_snd_parse_of(struct snd_soc_card *card) struct device_node *cpu = NULL; struct device *dev = card->dev; struct snd_soc_dai_link *link; + struct of_phandle_args args; int ret, num_links; ret = snd_soc_of_parse_card_name(card, "model"); @@ -47,12 +48,14 @@ int qcom_snd_parse_of(struct snd_soc_card *card) goto err; } - link->cpu_of_node = of_parse_phandle(cpu, "sound-dai", 0); - if (!link->cpu_of_node) { + ret = of_parse_phandle_with_args(cpu, "sound-dai", + "#sound-dai-cells", 0, &args); + if (ret) { dev_err(card->dev, "error getting cpu phandle\n"); - ret = -EINVAL; goto err; } + link->cpu_of_node = args.np; + link->id = args.args[0]; ret = snd_soc_of_get_dai_name(cpu, &link->cpu_dai_name); if (ret) { -- cgit v1.2.3-59-g8ed1b From 933a95496e48bde40e366a79e6dd9f9740905573 Mon Sep 17 00:00:00 2001 From: Kirill Marinushkin Date: Mon, 12 Nov 2018 08:08:34 +0100 Subject: ASoC: pcm3060: Rename output widgets In the initial commit [1], I added differential output of the codec as separate `+` and `-` widgets: OUTL+ OUTR+ OUTL- OUTR- Later, in the commit [2], I added a device tree property to configure the output as single-ended or differential. Having this property, the `+` and `-` separation in widgets seems for me confusing. There are no functional benefits in such separation, so I find reasonable to get rid of it: OUTL OUTR The new naming is more friendly for sound cards, and is better aligned with other codec drivers in kernel. Renaming the output widgets now should not be a problem from the backwards- compatibility perspective, as the driver for PCM3060 is added into the mainline very recently, and did not yet appear in any releases. [1] commit 6ee47d4a8dac ("ASoC: pcm3060: Add codec driver") [2] commit a78c62de00d5 ("ASoC: pcm3060: Add DT property for single-ended output") Signed-off-by: Kirill Marinushkin Signed-off-by: Mark Brown --- sound/soc/codecs/pcm3060.c | 12 ++++-------- 1 file changed, 4 insertions(+), 8 deletions(-) diff --git a/sound/soc/codecs/pcm3060.c b/sound/soc/codecs/pcm3060.c index 494d9d662be8..771b46e1974b 100644 --- a/sound/soc/codecs/pcm3060.c +++ b/sound/soc/codecs/pcm3060.c @@ -198,20 +198,16 @@ static const struct snd_kcontrol_new pcm3060_dapm_controls[] = { }; static const struct snd_soc_dapm_widget pcm3060_dapm_widgets[] = { - SND_SOC_DAPM_OUTPUT("OUTL+"), - SND_SOC_DAPM_OUTPUT("OUTR+"), - SND_SOC_DAPM_OUTPUT("OUTL-"), - SND_SOC_DAPM_OUTPUT("OUTR-"), + SND_SOC_DAPM_OUTPUT("OUTL"), + SND_SOC_DAPM_OUTPUT("OUTR"), SND_SOC_DAPM_INPUT("INL"), SND_SOC_DAPM_INPUT("INR"), }; static const struct snd_soc_dapm_route pcm3060_dapm_map[] = { - { "OUTL+", NULL, "Playback" }, - { "OUTR+", NULL, "Playback" }, - { "OUTL-", NULL, "Playback" }, - { "OUTR-", NULL, "Playback" }, + { "OUTL", NULL, "Playback" }, + { "OUTR", NULL, "Playback" }, { "Capture", NULL, "INL" }, { "Capture", NULL, "INR" }, -- cgit v1.2.3-59-g8ed1b From 76836fd354922ebe4798a64fda01f8dc6a8b0984 Mon Sep 17 00:00:00 2001 From: Peter Ujfalusi Date: Wed, 14 Nov 2018 14:58:20 +0200 Subject: ASoC: omap-abe-twl6040: Fix missing audio card caused by deferred probing The machine driver fails to probe in next-20181113 with: [ 2.539093] omap-abe-twl6040 sound: ASoC: CODEC DAI twl6040-legacy not registered [ 2.546630] omap-abe-twl6040 sound: devm_snd_soc_register_card() failed: -517 ... [ 3.693206] omap-abe-twl6040 sound: ASoC: Both platform name/of_node are set for TWL6040 [ 3.701446] omap-abe-twl6040 sound: ASoC: failed to init link TWL6040 [ 3.708007] omap-abe-twl6040 sound: devm_snd_soc_register_card() failed: -22 [ 3.715148] omap-abe-twl6040: probe of sound failed with error -22 Bisect pointed to a merge commit: first bad commit: [0f688ab20a540aafa984c5dbd68a71debebf4d7f] Merge remote-tracking branch 'net-next/master' and a diff between a working kernel does not reveal anything which would explain the change in behavior. Further investigation showed that on the second try of loading fails because the dai_link->platform is no longer NULL and it might be pointing to uninitialized memory. The fix is to move the snd_soc_dai_link and snd_soc_card inside of the abe_twl6040 struct, which is dynamically allocated every time the driver probes. Signed-off-by: Peter Ujfalusi Signed-off-by: Mark Brown --- sound/soc/omap/omap-abe-twl6040.c | 67 +++++++++++++++++---------------------- 1 file changed, 29 insertions(+), 38 deletions(-) diff --git a/sound/soc/omap/omap-abe-twl6040.c b/sound/soc/omap/omap-abe-twl6040.c index d5ae9eb8c756..fed45b41f9d3 100644 --- a/sound/soc/omap/omap-abe-twl6040.c +++ b/sound/soc/omap/omap-abe-twl6040.c @@ -36,6 +36,8 @@ #include "../codecs/twl6040.h" struct abe_twl6040 { + struct snd_soc_card card; + struct snd_soc_dai_link dai_links[2]; int jack_detection; /* board can detect jack events */ int mclk_freq; /* MCLK frequency speed for twl6040 */ }; @@ -208,40 +210,10 @@ static int omap_abe_dmic_init(struct snd_soc_pcm_runtime *rtd) ARRAY_SIZE(dmic_audio_map)); } -/* Digital audio interface glue - connects codec <--> CPU */ -static struct snd_soc_dai_link abe_twl6040_dai_links[] = { - { - .name = "TWL6040", - .stream_name = "TWL6040", - .codec_dai_name = "twl6040-legacy", - .codec_name = "twl6040-codec", - .init = omap_abe_twl6040_init, - .ops = &omap_abe_ops, - }, - { - .name = "DMIC", - .stream_name = "DMIC Capture", - .codec_dai_name = "dmic-hifi", - .codec_name = "dmic-codec", - .init = omap_abe_dmic_init, - .ops = &omap_abe_dmic_ops, - }, -}; - -/* Audio machine driver */ -static struct snd_soc_card omap_abe_card = { - .owner = THIS_MODULE, - - .dapm_widgets = twl6040_dapm_widgets, - .num_dapm_widgets = ARRAY_SIZE(twl6040_dapm_widgets), - .dapm_routes = audio_map, - .num_dapm_routes = ARRAY_SIZE(audio_map), -}; - static int omap_abe_probe(struct platform_device *pdev) { struct device_node *node = pdev->dev.of_node; - struct snd_soc_card *card = &omap_abe_card; + struct snd_soc_card *card; struct device_node *dai_node; struct abe_twl6040 *priv; int num_links = 0; @@ -252,12 +224,18 @@ static int omap_abe_probe(struct platform_device *pdev) return -ENODEV; } - card->dev = &pdev->dev; - priv = devm_kzalloc(&pdev->dev, sizeof(struct abe_twl6040), GFP_KERNEL); if (priv == NULL) return -ENOMEM; + card = &priv->card; + card->dev = &pdev->dev; + card->owner = THIS_MODULE; + card->dapm_widgets = twl6040_dapm_widgets; + card->num_dapm_widgets = ARRAY_SIZE(twl6040_dapm_widgets); + card->dapm_routes = audio_map; + card->num_dapm_routes = ARRAY_SIZE(audio_map); + if (snd_soc_of_parse_card_name(card, "ti,model")) { dev_err(&pdev->dev, "Card name is not provided\n"); return -ENODEV; @@ -274,14 +252,27 @@ static int omap_abe_probe(struct platform_device *pdev) dev_err(&pdev->dev, "McPDM node is not provided\n"); return -EINVAL; } - abe_twl6040_dai_links[0].cpu_of_node = dai_node; - abe_twl6040_dai_links[0].platform_of_node = dai_node; + + priv->dai_links[0].name = "DMIC"; + priv->dai_links[0].stream_name = "TWL6040"; + priv->dai_links[0].cpu_of_node = dai_node; + priv->dai_links[0].platform_of_node = dai_node; + priv->dai_links[0].codec_dai_name = "twl6040-legacy"; + priv->dai_links[0].codec_name = "twl6040-codec"; + priv->dai_links[0].init = omap_abe_twl6040_init; + priv->dai_links[0].ops = &omap_abe_ops; dai_node = of_parse_phandle(node, "ti,dmic", 0); if (dai_node) { num_links = 2; - abe_twl6040_dai_links[1].cpu_of_node = dai_node; - abe_twl6040_dai_links[1].platform_of_node = dai_node; + priv->dai_links[1].name = "TWL6040"; + priv->dai_links[1].stream_name = "DMIC Capture"; + priv->dai_links[1].cpu_of_node = dai_node; + priv->dai_links[1].platform_of_node = dai_node; + priv->dai_links[1].codec_dai_name = "dmic-hifi"; + priv->dai_links[1].codec_name = "dmic-codec"; + priv->dai_links[1].init = omap_abe_dmic_init; + priv->dai_links[1].ops = &omap_abe_dmic_ops; } else { num_links = 1; } @@ -300,7 +291,7 @@ static int omap_abe_probe(struct platform_device *pdev) return -ENODEV; } - card->dai_link = abe_twl6040_dai_links; + card->dai_link = priv->dai_links; card->num_links = num_links; snd_soc_card_set_drvdata(card, priv); -- cgit v1.2.3-59-g8ed1b From 882eab6c28d23a970ae73b7eb831b169a672d456 Mon Sep 17 00:00:00 2001 From: Tzung-Bi Shih Date: Wed, 14 Nov 2018 17:06:13 +0800 Subject: ASoC: dapm: Recalculate audio map forcely when card instantiated Audio map are possible in wrong state before card->instantiated has been set to true. Imaging the following examples: time 1: at the beginning in:-1 in:-1 in:-1 in:-1 out:-1 out:-1 out:-1 out:-1 SIGGEN A B Spk time 2: after someone called snd_soc_dapm_new_widgets() (e.g. create_fill_widget_route_map() in sound/soc/codecs/hdac_hdmi.c) in:1 in:0 in:0 in:0 out:0 out:0 out:0 out:1 SIGGEN A B Spk time 3: routes added in:1 in:0 in:0 in:0 out:0 out:0 out:0 out:1 SIGGEN -----> A -----> B ---> Spk In the end, the path should be powered on but it did not. At time 3, "in" of SIGGEN and "out" of Spk did not propagate to their neighbors because snd_soc_dapm_add_path() will not invalidate the paths if the card has not instantiated (i.e. card->instantiated is false). To correct the state of audio map, recalculate the whole map forcely. Signed-off-by: Tzung-Bi Shih Signed-off-by: Mark Brown --- sound/soc/soc-core.c | 1 + 1 file changed, 1 insertion(+) diff --git a/sound/soc/soc-core.c b/sound/soc/soc-core.c index 6ddcf12bc030..b29d0f65611e 100644 --- a/sound/soc/soc-core.c +++ b/sound/soc/soc-core.c @@ -2131,6 +2131,7 @@ static int snd_soc_instantiate_card(struct snd_soc_card *card) } card->instantiated = 1; + dapm_mark_endpoints_dirty(card); snd_soc_dapm_sync(&card->dapm); mutex_unlock(&card->mutex); mutex_unlock(&client_mutex); -- cgit v1.2.3-59-g8ed1b From 5277715639ff6f75c729e657690751a831112c4b Mon Sep 17 00:00:00 2001 From: Andreas Dannenberg Date: Thu, 15 Nov 2018 11:01:31 -0600 Subject: ASoC: pcm186x: Fix device reset-registers trigger value According to the current device datasheet (TI Lit # SLAS831D, revised March 2018) the value written to the device's PAGE register to trigger a complete register reset should be 0xfe, not 0xff. So go ahead and update to the correct value. Reported-by: Stephane Le Provost Tested-by: Stephane Le Provost Signed-off-by: Andreas Dannenberg Acked-by: Andrew F. Davis Signed-off-by: Mark Brown Cc: stable@vger.kernel.org --- sound/soc/codecs/pcm186x.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sound/soc/codecs/pcm186x.h b/sound/soc/codecs/pcm186x.h index 2c6ba55bf394..bb3f0c42a1cd 100644 --- a/sound/soc/codecs/pcm186x.h +++ b/sound/soc/codecs/pcm186x.h @@ -139,7 +139,7 @@ enum pcm186x_type { #define PCM186X_MAX_REGISTER PCM186X_CURR_TRIM_CTRL /* PCM186X_PAGE */ -#define PCM186X_RESET 0xff +#define PCM186X_RESET 0xfe /* PCM186X_ADCX_INPUT_SEL_X */ #define PCM186X_ADC_INPUT_SEL_POL BIT(7) -- cgit v1.2.3-59-g8ed1b From 5bb9b84b0796336b18c8b8651628009eace70202 Mon Sep 17 00:00:00 2001 From: Clément Péron Date: Sat, 17 Nov 2018 13:14:52 +0100 Subject: MAINTAINERS: add ASoC maintainers for sound dt-bindings MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Sound dt-bindings are applied by ASoC maintainers and should be submit to ASoC list in addition to the devicetree list. Hence, add this information into the MAINTAINERS file. Signed-off-by: Clément Péron Signed-off-by: Mark Brown --- MAINTAINERS | 1 + 1 file changed, 1 insertion(+) diff --git a/MAINTAINERS b/MAINTAINERS index d3814c46d60a..79640cffe658 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -13592,6 +13592,7 @@ S: Supported F: Documentation/devicetree/bindings/sound/ F: Documentation/sound/soc/ F: sound/soc/ +F: include/dt-bindings/sound/ F: include/sound/soc* SOUNDWIRE SUBSYSTEM -- cgit v1.2.3-59-g8ed1b From 8c4e7c2ee8096b5ca8214418f287b3878d578cc0 Mon Sep 17 00:00:00 2001 From: Pierre-Louis Bossart Date: Sun, 18 Nov 2018 16:38:09 -0600 Subject: ASoC: Intel: Skylake: fix Kconfigs, make HDaudio codec optional The Skylake driver currently has a set of problems supporting load/unload modules. We need to make the HDaudio codec support optional to help narrow down the issues. Support for HDaudio codecs also leads to a Kconfig issue. We want the hdac_hda codec to be compilable independently of Skylake (e.g. with ALL_CODECS) but when Skylake is selected as built-in the hdac_hda codec needs to use the same option due a a code dependency Solve both problems by adding a user-selectable boolean Kconfig, select HDAC_HDA as needed and make the HDaudio codec support in the Skylake driver optional. Tests on a Chell Chromebook device without HDaudio show no regression for speaker and HDMI playback. This is submitted as an RFC to allow for comments and more validation. Signed-off-by: Pierre-Louis Bossart Signed-off-by: Mark Brown --- sound/soc/intel/Kconfig | 26 +++++++++++++++++++++++--- sound/soc/intel/boards/Kconfig | 24 ++++++++++++++---------- sound/soc/intel/skylake/skl.c | 20 ++++++++++++++++++-- 3 files changed, 55 insertions(+), 15 deletions(-) diff --git a/sound/soc/intel/Kconfig b/sound/soc/intel/Kconfig index 0caa1f4eb94d..18e717703685 100644 --- a/sound/soc/intel/Kconfig +++ b/sound/soc/intel/Kconfig @@ -101,22 +101,42 @@ config SND_SST_ATOM_HIFI2_PLATFORM_ACPI codec, then enable this option by saying Y or m. This is a recommended option -config SND_SOC_INTEL_SKYLAKE_SSP_CLK - tristate - config SND_SOC_INTEL_SKYLAKE tristate "SKL/BXT/KBL/GLK/CNL... Platforms" depends on PCI && ACPI + select SND_SOC_INTEL_SKYLAKE_COMMON + help + If you have a Intel Skylake/Broxton/ApolloLake/KabyLake/ + GeminiLake or CannonLake platform with the DSP enabled in the BIOS + then enable this option by saying Y or m. + +if SND_SOC_INTEL_SKYLAKE + +config SND_SOC_INTEL_SKYLAKE_SSP_CLK + tristate + +config SND_SOC_INTEL_SKYLAKE_HDAUDIO_CODEC + bool "HDAudio codec support" + help + If you have a Intel Skylake/Broxton/ApolloLake/KabyLake/ + GeminiLake or CannonLake platform with an HDaudio codec + then enable this option by saying Y + +config SND_SOC_INTEL_SKYLAKE_COMMON + tristate select SND_HDA_EXT_CORE select SND_HDA_DSP_LOADER select SND_SOC_TOPOLOGY select SND_SOC_INTEL_SST + select SND_SOC_HDAC_HDA if SND_SOC_INTEL_SKYLAKE_HDAUDIO_CODEC select SND_SOC_ACPI_INTEL_MATCH help If you have a Intel Skylake/Broxton/ApolloLake/KabyLake/ GeminiLake or CannonLake platform with the DSP enabled in the BIOS then enable this option by saying Y or m. +endif ## SND_SOC_INTEL_SKYLAKE + config SND_SOC_ACPI_INTEL_MATCH tristate select SND_SOC_ACPI if ACPI diff --git a/sound/soc/intel/boards/Kconfig b/sound/soc/intel/boards/Kconfig index 73ca1350aa31..b177db2a0dbb 100644 --- a/sound/soc/intel/boards/Kconfig +++ b/sound/soc/intel/boards/Kconfig @@ -293,16 +293,6 @@ config SND_SOC_INTEL_KBL_DA7219_MAX98927_MACH Say Y if you have such a device. If unsure select "N". -config SND_SOC_INTEL_SKL_HDA_DSP_GENERIC_MACH - tristate "SKL/KBL/BXT/APL with HDA Codecs" - select SND_SOC_HDAC_HDMI - select SND_SOC_HDAC_HDA - help - This adds support for ASoC machine driver for Intel platforms - SKL/KBL/BXT/APL with iDisp, HDA audio codecs. - Say Y or m if you have such a device. This is a recommended option. - If unsure select "N". - config SND_SOC_INTEL_GLK_RT5682_MAX98357A_MACH tristate "GLK with RT5682 and MAX98357A in I2S Mode" depends on MFD_INTEL_LPSS && I2C && ACPI @@ -319,4 +309,18 @@ config SND_SOC_INTEL_GLK_RT5682_MAX98357A_MACH endif ## SND_SOC_INTEL_SKYLAKE +if SND_SOC_INTEL_SKYLAKE_HDAUDIO_CODEC + +config SND_SOC_INTEL_SKL_HDA_DSP_GENERIC_MACH + tristate "SKL/KBL/BXT/APL with HDA Codecs" + select SND_SOC_HDAC_HDMI + # SND_SOC_HDAC_HDA is already selected + help + This adds support for ASoC machine driver for Intel platforms + SKL/KBL/BXT/APL with iDisp, HDA audio codecs. + Say Y or m if you have such a device. This is a recommended option. + If unsure select "N". + +endif ## SND_SOC_INTEL_SKYLAKE_HDAUDIO_CODEC + endif ## SND_SOC_INTEL_MACH diff --git a/sound/soc/intel/skylake/skl.c b/sound/soc/intel/skylake/skl.c index 1586c97d9450..7487f388e65d 100644 --- a/sound/soc/intel/skylake/skl.c +++ b/sound/soc/intel/skylake/skl.c @@ -37,7 +37,9 @@ #include "skl.h" #include "skl-sst-dsp.h" #include "skl-sst-ipc.h" +#if IS_ENABLED(CONFIG_SND_SOC_INTEL_SKYLAKE_HDAUDIO_CODEC) #include "../../../soc/codecs/hdac_hda.h" +#endif /* * initialize the PCI registers @@ -658,6 +660,8 @@ static void skl_clock_device_unregister(struct skl *skl) platform_device_unregister(skl->clk_dev); } +#if IS_ENABLED(CONFIG_SND_SOC_INTEL_SKYLAKE_HDAUDIO_CODEC) + #define IDISP_INTEL_VENDOR_ID 0x80860000 /* @@ -676,6 +680,8 @@ static void load_codec_module(struct hda_codec *codec) #endif } +#endif /* CONFIG_SND_SOC_INTEL_SKYLAKE_HDAUDIO_CODEC */ + /* * Probe the given codec address */ @@ -685,9 +691,11 @@ static int probe_codec(struct hdac_bus *bus, int addr) (AC_VERB_PARAMETERS << 8) | AC_PAR_VENDOR_ID; unsigned int res = -1; struct skl *skl = bus_to_skl(bus); +#if IS_ENABLED(CONFIG_SND_SOC_INTEL_SKYLAKE_HDAUDIO_CODEC) struct hdac_hda_priv *hda_codec; - struct hdac_device *hdev; int err; +#endif + struct hdac_device *hdev; mutex_lock(&bus->cmd_mutex); snd_hdac_bus_send_cmd(bus, cmd); @@ -697,6 +705,7 @@ static int probe_codec(struct hdac_bus *bus, int addr) return -EIO; dev_dbg(bus->dev, "codec #%d probed OK: %x\n", addr, res); +#if IS_ENABLED(CONFIG_SND_SOC_INTEL_SKYLAKE_HDAUDIO_CODEC) hda_codec = devm_kzalloc(&skl->pci->dev, sizeof(*hda_codec), GFP_KERNEL); if (!hda_codec) @@ -715,6 +724,13 @@ static int probe_codec(struct hdac_bus *bus, int addr) load_codec_module(&hda_codec->codec); } return 0; +#else + hdev = devm_kzalloc(&skl->pci->dev, sizeof(*hdev), GFP_KERNEL); + if (!hdev) + return -ENOMEM; + + return snd_hdac_ext_bus_device_init(bus, addr, hdev); +#endif /* CONFIG_SND_SOC_INTEL_SKYLAKE_HDAUDIO_CODEC */ } /* Codec initialization */ @@ -870,7 +886,7 @@ static int skl_create(struct pci_dev *pci, hbus = skl_to_hbus(skl); bus = skl_to_bus(skl); -#if IS_ENABLED(CONFIG_SND_SOC_HDAC_HDA) +#if IS_ENABLED(CONFIG_SND_SOC_INTEL_SKYLAKE_HDAUDIO_CODEC) ext_ops = snd_soc_hdac_hda_get_ops(); #endif snd_hdac_ext_bus_init(bus, &pci->dev, &bus_core_ops, io_ops, ext_ops); -- cgit v1.2.3-59-g8ed1b From a3e620f8422832afd832ad5e20aa97d0c72bada8 Mon Sep 17 00:00:00 2001 From: Keyon Jie Date: Fri, 16 Nov 2018 18:47:04 -0600 Subject: ASoC: acpi: fix: continue searching when machine is ignored The machine_quirk may return NULL which means the acpi entries should be skipped and search for next matched entry is needed, here add return check here and continue for NULL case. Signed-off-by: Keyon Jie Signed-off-by: Pierre-Louis Bossart Signed-off-by: Mark Brown --- sound/soc/soc-acpi.c | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/sound/soc/soc-acpi.c b/sound/soc/soc-acpi.c index b8e72b52db30..4fb29f0e561e 100644 --- a/sound/soc/soc-acpi.c +++ b/sound/soc/soc-acpi.c @@ -10,11 +10,17 @@ struct snd_soc_acpi_mach * snd_soc_acpi_find_machine(struct snd_soc_acpi_mach *machines) { struct snd_soc_acpi_mach *mach; + struct snd_soc_acpi_mach *mach_alt; for (mach = machines; mach->id[0]; mach++) { if (acpi_dev_present(mach->id, NULL, -1)) { - if (mach->machine_quirk) - mach = mach->machine_quirk(mach); + if (mach->machine_quirk) { + mach_alt = mach->machine_quirk(mach); + if (!mach_alt) + continue; /* not full match, ignore */ + mach = mach_alt; + } + return mach; } } -- cgit v1.2.3-59-g8ed1b From dd2f52d8991af9fe0928d59ec502ba52be7bc38d Mon Sep 17 00:00:00 2001 From: Peter Ujfalusi Date: Wed, 14 Nov 2018 13:06:21 +0200 Subject: ASoC: omap-mcbsp: Fix latency value calculation for pm_qos The latency number is in usec for the pm_qos. Correct the calculation to give us the time in usec Signed-off-by: Peter Ujfalusi Acked-by: Jarkko Nikula Signed-off-by: Mark Brown --- sound/soc/omap/omap-mcbsp.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/sound/soc/omap/omap-mcbsp.c b/sound/soc/omap/omap-mcbsp.c index d0ebb6b9bfac..2d6decbfc99e 100644 --- a/sound/soc/omap/omap-mcbsp.c +++ b/sound/soc/omap/omap-mcbsp.c @@ -308,9 +308,9 @@ static int omap_mcbsp_dai_hw_params(struct snd_pcm_substream *substream, pkt_size = channels; } - latency = ((((buffer_size - pkt_size) / channels) * 1000) - / (params->rate_num / params->rate_den)); - + latency = (buffer_size - pkt_size) / channels; + latency = latency * USEC_PER_SEC / + (params->rate_num / params->rate_den); mcbsp->latency[substream->stream] = latency; omap_mcbsp_set_threshold(substream, pkt_size); -- cgit v1.2.3-59-g8ed1b From 373a500e34aea97971c9d71e45edad458d3da98f Mon Sep 17 00:00:00 2001 From: Peter Ujfalusi Date: Wed, 14 Nov 2018 13:06:22 +0200 Subject: ASoC: omap-mcpdm: Add pm_qos handling to avoid under/overruns with CPU_IDLE We need to block sleep states which would require longer time to leave than the time the DMA must react to the DMA request in order to keep the FIFO serviced without under of overrun. Signed-off-by: Peter Ujfalusi Acked-by: Jarkko Nikula Signed-off-by: Mark Brown --- sound/soc/omap/omap-mcpdm.c | 43 ++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 42 insertions(+), 1 deletion(-) diff --git a/sound/soc/omap/omap-mcpdm.c b/sound/soc/omap/omap-mcpdm.c index 4c1be36c2207..7d5bdc5a2890 100644 --- a/sound/soc/omap/omap-mcpdm.c +++ b/sound/soc/omap/omap-mcpdm.c @@ -54,6 +54,8 @@ struct omap_mcpdm { unsigned long phys_base; void __iomem *io_base; int irq; + struct pm_qos_request pm_qos_req; + int latency[2]; struct mutex mutex; @@ -277,6 +279,9 @@ static void omap_mcpdm_dai_shutdown(struct snd_pcm_substream *substream, struct snd_soc_dai *dai) { struct omap_mcpdm *mcpdm = snd_soc_dai_get_drvdata(dai); + int tx = (substream->stream == SNDRV_PCM_STREAM_PLAYBACK); + int stream1 = tx ? SNDRV_PCM_STREAM_PLAYBACK : SNDRV_PCM_STREAM_CAPTURE; + int stream2 = tx ? SNDRV_PCM_STREAM_CAPTURE : SNDRV_PCM_STREAM_PLAYBACK; mutex_lock(&mcpdm->mutex); @@ -289,6 +294,14 @@ static void omap_mcpdm_dai_shutdown(struct snd_pcm_substream *substream, } } + if (mcpdm->latency[stream2]) + pm_qos_update_request(&mcpdm->pm_qos_req, + mcpdm->latency[stream2]); + else if (mcpdm->latency[stream1]) + pm_qos_remove_request(&mcpdm->pm_qos_req); + + mcpdm->latency[stream1] = 0; + mutex_unlock(&mcpdm->mutex); } @@ -300,7 +313,7 @@ static int omap_mcpdm_dai_hw_params(struct snd_pcm_substream *substream, int stream = substream->stream; struct snd_dmaengine_dai_dma_data *dma_data; u32 threshold; - int channels; + int channels, latency; int link_mask = 0; channels = params_channels(params); @@ -344,14 +357,25 @@ static int omap_mcpdm_dai_hw_params(struct snd_pcm_substream *substream, dma_data->maxburst = (MCPDM_DN_THRES_MAX - threshold) * channels; + latency = threshold; } else { /* If playback is not running assume a stereo stream to come */ if (!mcpdm->config[!stream].link_mask) mcpdm->config[!stream].link_mask = (0x3 << 3); dma_data->maxburst = threshold * channels; + latency = (MCPDM_DN_THRES_MAX - threshold); } + /* + * The DMA must act to a DMA request within latency time (usec) to avoid + * under/overflow + */ + mcpdm->latency[stream] = latency * USEC_PER_SEC / params_rate(params); + + if (!mcpdm->latency[stream]) + mcpdm->latency[stream] = 10; + /* Check if we need to restart McPDM with this stream */ if (mcpdm->config[stream].link_mask && mcpdm->config[stream].link_mask != link_mask) @@ -366,6 +390,20 @@ static int omap_mcpdm_prepare(struct snd_pcm_substream *substream, struct snd_soc_dai *dai) { struct omap_mcpdm *mcpdm = snd_soc_dai_get_drvdata(dai); + struct pm_qos_request *pm_qos_req = &mcpdm->pm_qos_req; + int tx = (substream->stream == SNDRV_PCM_STREAM_PLAYBACK); + int stream1 = tx ? SNDRV_PCM_STREAM_PLAYBACK : SNDRV_PCM_STREAM_CAPTURE; + int stream2 = tx ? SNDRV_PCM_STREAM_CAPTURE : SNDRV_PCM_STREAM_PLAYBACK; + int latency = mcpdm->latency[stream2]; + + /* Prevent omap hardware from hitting off between FIFO fills */ + if (!latency || mcpdm->latency[stream1] < latency) + latency = mcpdm->latency[stream1]; + + if (pm_qos_request_active(pm_qos_req)) + pm_qos_update_request(pm_qos_req, latency); + else if (latency) + pm_qos_add_request(pm_qos_req, PM_QOS_CPU_DMA_LATENCY, latency); if (!omap_mcpdm_active(mcpdm)) { omap_mcpdm_start(mcpdm); @@ -427,6 +465,9 @@ static int omap_mcpdm_remove(struct snd_soc_dai *dai) free_irq(mcpdm->irq, (void *)mcpdm); pm_runtime_disable(mcpdm->dev); + if (pm_qos_request_active(&mcpdm->pm_qos_req)) + pm_qos_remove_request(&mcpdm->pm_qos_req); + return 0; } -- cgit v1.2.3-59-g8ed1b From ffdcc3638c58d55a6fa68b6e5dfd4fb4109652eb Mon Sep 17 00:00:00 2001 From: Peter Ujfalusi Date: Wed, 14 Nov 2018 13:06:23 +0200 Subject: ASoC: omap-dmic: Add pm_qos handling to avoid overruns with CPU_IDLE We need to block sleep states which would require longer time to leave than the time the DMA must react to the DMA request in order to keep the FIFO serviced without overrun. Signed-off-by: Peter Ujfalusi Acked-by: Jarkko Nikula Signed-off-by: Mark Brown --- sound/soc/omap/omap-dmic.c | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/sound/soc/omap/omap-dmic.c b/sound/soc/omap/omap-dmic.c index fe966272bd0c..cba9645b6487 100644 --- a/sound/soc/omap/omap-dmic.c +++ b/sound/soc/omap/omap-dmic.c @@ -48,6 +48,8 @@ struct omap_dmic { struct device *dev; void __iomem *io_base; struct clk *fclk; + struct pm_qos_request pm_qos_req; + int latency; int fclk_freq; int out_freq; int clk_div; @@ -124,6 +126,8 @@ static void omap_dmic_dai_shutdown(struct snd_pcm_substream *substream, mutex_lock(&dmic->mutex); + pm_qos_remove_request(&dmic->pm_qos_req); + if (!dai->active) dmic->active = 0; @@ -228,6 +232,8 @@ static int omap_dmic_dai_hw_params(struct snd_pcm_substream *substream, /* packet size is threshold * channels */ dma_data = snd_soc_dai_get_dma_data(dai, substream); dma_data->maxburst = dmic->threshold * channels; + dmic->latency = (OMAP_DMIC_THRES_MAX - dmic->threshold) * USEC_PER_SEC / + params_rate(params); return 0; } @@ -238,6 +244,9 @@ static int omap_dmic_dai_prepare(struct snd_pcm_substream *substream, struct omap_dmic *dmic = snd_soc_dai_get_drvdata(dai); u32 ctrl; + if (pm_qos_request_active(&dmic->pm_qos_req)) + pm_qos_update_request(&dmic->pm_qos_req, dmic->latency); + /* Configure uplink threshold */ omap_dmic_write(dmic, OMAP_DMIC_FIFO_CTRL_REG, dmic->threshold); -- cgit v1.2.3-59-g8ed1b From 7194eda1ba0872d917faf3b322540b4f57f11ba5 Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Fri, 23 Nov 2018 15:44:00 +0100 Subject: ALSA: ac97: Fix incorrect bit shift at AC97-SPSA control write The function snd_ac97_put_spsa() gets the bit shift value from the associated private_value, but it extracts too much; the current code extracts 8 bit values in bits 8-15, but this is a combination of two nibbles (bits 8-11 and bits 12-15) for left and right shifts. Due to the incorrect bits extraction, the actual shift may go beyond the 32bit value, as spotted recently by UBSAN check: UBSAN: Undefined behaviour in sound/pci/ac97/ac97_codec.c:836:7 shift exponent 68 is too large for 32-bit type 'int' This patch fixes the shift value extraction by masking the properly with 0x0f instead of 0xff. Reported-and-tested-by: Meelis Roos Cc: Signed-off-by: Takashi Iwai --- sound/pci/ac97/ac97_codec.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sound/pci/ac97/ac97_codec.c b/sound/pci/ac97/ac97_codec.c index f4459d1a9d67..27b468f057dd 100644 --- a/sound/pci/ac97/ac97_codec.c +++ b/sound/pci/ac97/ac97_codec.c @@ -824,7 +824,7 @@ static int snd_ac97_put_spsa(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_ { struct snd_ac97 *ac97 = snd_kcontrol_chip(kcontrol); int reg = kcontrol->private_value & 0xff; - int shift = (kcontrol->private_value >> 8) & 0xff; + int shift = (kcontrol->private_value >> 8) & 0x0f; int mask = (kcontrol->private_value >> 16) & 0xff; // int invert = (kcontrol->private_value >> 24) & 0xff; unsigned short value, old, new; -- cgit v1.2.3-59-g8ed1b From 39070a98d668db8fbaa2a6a6752f732cbcbb14b1 Mon Sep 17 00:00:00 2001 From: Hans de Goede Date: Thu, 22 Nov 2018 12:38:12 +0100 Subject: ALSA: hda: Add ASRock N68C-S UCC the power_save blacklist Power-saving is causing plops on audio start/stop on the built-in audio of the nForce 430 based ASRock N68C-S UCC motherboard, add this model to the power_save blacklist. BugLink: https://bugzilla.redhat.com/show_bug.cgi?id=1525104 Cc: Signed-off-by: Hans de Goede Signed-off-by: Takashi Iwai --- sound/pci/hda/hda_intel.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/sound/pci/hda/hda_intel.c b/sound/pci/hda/hda_intel.c index d8eb2b5f51ae..0bbdf1a01e76 100644 --- a/sound/pci/hda/hda_intel.c +++ b/sound/pci/hda/hda_intel.c @@ -2169,6 +2169,8 @@ static struct snd_pci_quirk power_save_blacklist[] = { /* https://bugzilla.redhat.com/show_bug.cgi?id=1525104 */ SND_PCI_QUIRK(0x1849, 0xc892, "Asrock B85M-ITX", 0), /* https://bugzilla.redhat.com/show_bug.cgi?id=1525104 */ + SND_PCI_QUIRK(0x1849, 0x0397, "Asrock N68C-S UCC", 0), + /* https://bugzilla.redhat.com/show_bug.cgi?id=1525104 */ SND_PCI_QUIRK(0x1849, 0x7662, "Asrock H81M-HDS", 0), /* https://bugzilla.redhat.com/show_bug.cgi?id=1525104 */ SND_PCI_QUIRK(0x1043, 0x8733, "Asus Prime X370-Pro", 0), -- cgit v1.2.3-59-g8ed1b From 8cd65271f8e545ddeed10ecc2e417936bdff168e Mon Sep 17 00:00:00 2001 From: Anisse Astier Date: Fri, 23 Nov 2018 17:59:11 +0100 Subject: ALSA: hda/realtek - fix headset mic detection for MSI MS-B171 MSI Cubi N 8GL (MS-B171) needs the same fixup as its older model, the MS-B120, in order for the headset mic to be properly detected. They both use a single 3-way jack for both mic and headset with an ALC283 codec, with the same pins used. Cc: stable@vger.kernel.org Signed-off-by: Anisse Astier Signed-off-by: Takashi Iwai --- sound/pci/hda/patch_realtek.c | 1 + 1 file changed, 1 insertion(+) diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c index 970bc44a378b..1118fd1bbf1a 100644 --- a/sound/pci/hda/patch_realtek.c +++ b/sound/pci/hda/patch_realtek.c @@ -6532,6 +6532,7 @@ static const struct snd_pci_quirk alc269_fixup_tbl[] = { SND_PCI_QUIRK(0x144d, 0xc740, "Samsung Ativ book 8 (NP870Z5G)", ALC269_FIXUP_ATIV_BOOK_8), SND_PCI_QUIRK(0x1458, 0xfa53, "Gigabyte BXBT-2807", ALC283_FIXUP_HEADSET_MIC), SND_PCI_QUIRK(0x1462, 0xb120, "MSI Cubi MS-B120", ALC283_FIXUP_HEADSET_MIC), + SND_PCI_QUIRK(0x1462, 0xb171, "Cubi N 8GL (MS-B171)", ALC283_FIXUP_HEADSET_MIC), SND_PCI_QUIRK(0x17aa, 0x1036, "Lenovo P520", ALC233_FIXUP_LENOVO_MULTI_CODECS), SND_PCI_QUIRK(0x17aa, 0x20f2, "Thinkpad SL410/510", ALC269_FIXUP_SKU_IGNORE), SND_PCI_QUIRK(0x17aa, 0x215e, "Thinkpad L512", ALC269_FIXUP_SKU_IGNORE), -- cgit v1.2.3-59-g8ed1b From 7b69154171b407844c273ab4c10b5f0ddcd6aa29 Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Fri, 23 Nov 2018 18:16:33 +0100 Subject: ALSA: wss: Fix invalid snd_free_pages() at error path Some spurious calls of snd_free_pages() have been overlooked and remain in the error paths of wss driver code. Since runtime->dma_area is managed by the PCM core helper, we shouldn't release manually. Drop the superfluous calls. Reviewed-by: Takashi Sakamoto Cc: Signed-off-by: Takashi Iwai --- sound/isa/wss/wss_lib.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/sound/isa/wss/wss_lib.c b/sound/isa/wss/wss_lib.c index 32453f81b95a..3a5008837576 100644 --- a/sound/isa/wss/wss_lib.c +++ b/sound/isa/wss/wss_lib.c @@ -1531,7 +1531,6 @@ static int snd_wss_playback_open(struct snd_pcm_substream *substream) if (err < 0) { if (chip->release_dma) chip->release_dma(chip, chip->dma_private_data, chip->dma1); - snd_free_pages(runtime->dma_area, runtime->dma_bytes); return err; } chip->playback_substream = substream; @@ -1572,7 +1571,6 @@ static int snd_wss_capture_open(struct snd_pcm_substream *substream) if (err < 0) { if (chip->release_dma) chip->release_dma(chip, chip->dma_private_data, chip->dma2); - snd_free_pages(runtime->dma_area, runtime->dma_bytes); return err; } chip->capture_substream = substream; -- cgit v1.2.3-59-g8ed1b From 9a20332ab373b1f8f947e0a9c923652b32dab031 Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Fri, 23 Nov 2018 18:18:30 +0100 Subject: ALSA: sparc: Fix invalid snd_free_pages() at error path Some spurious calls of snd_free_pages() have been overlooked and remain in the error paths of sparc cs4231 driver code. Since runtime->dma_area is managed by the PCM core helper, we shouldn't release manually. Drop the superfluous calls. Reviewed-by: Takashi Sakamoto Cc: Signed-off-by: Takashi Iwai --- sound/sparc/cs4231.c | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/sound/sparc/cs4231.c b/sound/sparc/cs4231.c index e73c962590eb..079063d8038d 100644 --- a/sound/sparc/cs4231.c +++ b/sound/sparc/cs4231.c @@ -1146,10 +1146,8 @@ static int snd_cs4231_playback_open(struct snd_pcm_substream *substream) runtime->hw = snd_cs4231_playback; err = snd_cs4231_open(chip, CS4231_MODE_PLAY); - if (err < 0) { - snd_free_pages(runtime->dma_area, runtime->dma_bytes); + if (err < 0) return err; - } chip->playback_substream = substream; chip->p_periods_sent = 0; snd_pcm_set_sync(substream); @@ -1167,10 +1165,8 @@ static int snd_cs4231_capture_open(struct snd_pcm_substream *substream) runtime->hw = snd_cs4231_capture; err = snd_cs4231_open(chip, CS4231_MODE_RECORD); - if (err < 0) { - snd_free_pages(runtime->dma_area, runtime->dma_bytes); + if (err < 0) return err; - } chip->capture_substream = substream; chip->c_periods_sent = 0; snd_pcm_set_sync(substream); -- cgit v1.2.3-59-g8ed1b From e1a7bfe3807974e66f971f2589d4e0197ec0fced Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Thu, 22 Nov 2018 14:36:17 +0100 Subject: ALSA: control: Fix race between adding and removing a user element The procedure for adding a user control element has some window opened for race against the concurrent removal of a user element. This was caught by syzkaller, hitting a KASAN use-after-free error. This patch addresses the bug by wrapping the whole procedure to add a user control element with the card->controls_rwsem, instead of only around the increment of card->user_ctl_count. This required a slight code refactoring, too. The function snd_ctl_add() is split to two parts: a core function to add the control element and a part calling it. The former is called from the function for adding a user control element inside the controls_rwsem. One change to be noted is that snd_ctl_notify() for adding a control element gets called inside the controls_rwsem as well while it was called outside the rwsem. But this should be OK, as snd_ctl_notify() takes another (finer) rwlock instead of rwsem, and the call of snd_ctl_notify() inside rwsem is already done in another code path. Reported-by: syzbot+dc09047bce3820621ba2@syzkaller.appspotmail.com Cc: Signed-off-by: Takashi Iwai --- sound/core/control.c | 80 +++++++++++++++++++++++++++++----------------------- 1 file changed, 45 insertions(+), 35 deletions(-) diff --git a/sound/core/control.c b/sound/core/control.c index 9aa15bfc7936..649d3217590e 100644 --- a/sound/core/control.c +++ b/sound/core/control.c @@ -348,6 +348,40 @@ static int snd_ctl_find_hole(struct snd_card *card, unsigned int count) return 0; } +/* add a new kcontrol object; call with card->controls_rwsem locked */ +static int __snd_ctl_add(struct snd_card *card, struct snd_kcontrol *kcontrol) +{ + struct snd_ctl_elem_id id; + unsigned int idx; + unsigned int count; + + id = kcontrol->id; + if (id.index > UINT_MAX - kcontrol->count) + return -EINVAL; + + if (snd_ctl_find_id(card, &id)) { + dev_err(card->dev, + "control %i:%i:%i:%s:%i is already present\n", + id.iface, id.device, id.subdevice, id.name, id.index); + return -EBUSY; + } + + if (snd_ctl_find_hole(card, kcontrol->count) < 0) + return -ENOMEM; + + list_add_tail(&kcontrol->list, &card->controls); + card->controls_count += kcontrol->count; + kcontrol->id.numid = card->last_numid + 1; + card->last_numid += kcontrol->count; + + id = kcontrol->id; + count = kcontrol->count; + for (idx = 0; idx < count; idx++, id.index++, id.numid++) + snd_ctl_notify(card, SNDRV_CTL_EVENT_MASK_ADD, &id); + + return 0; +} + /** * snd_ctl_add - add the control instance to the card * @card: the card instance @@ -364,45 +398,18 @@ static int snd_ctl_find_hole(struct snd_card *card, unsigned int count) */ int snd_ctl_add(struct snd_card *card, struct snd_kcontrol *kcontrol) { - struct snd_ctl_elem_id id; - unsigned int idx; - unsigned int count; int err = -EINVAL; if (! kcontrol) return err; if (snd_BUG_ON(!card || !kcontrol->info)) goto error; - id = kcontrol->id; - if (id.index > UINT_MAX - kcontrol->count) - goto error; down_write(&card->controls_rwsem); - if (snd_ctl_find_id(card, &id)) { - up_write(&card->controls_rwsem); - dev_err(card->dev, "control %i:%i:%i:%s:%i is already present\n", - id.iface, - id.device, - id.subdevice, - id.name, - id.index); - err = -EBUSY; - goto error; - } - if (snd_ctl_find_hole(card, kcontrol->count) < 0) { - up_write(&card->controls_rwsem); - err = -ENOMEM; - goto error; - } - list_add_tail(&kcontrol->list, &card->controls); - card->controls_count += kcontrol->count; - kcontrol->id.numid = card->last_numid + 1; - card->last_numid += kcontrol->count; - id = kcontrol->id; - count = kcontrol->count; + err = __snd_ctl_add(card, kcontrol); up_write(&card->controls_rwsem); - for (idx = 0; idx < count; idx++, id.index++, id.numid++) - snd_ctl_notify(card, SNDRV_CTL_EVENT_MASK_ADD, &id); + if (err < 0) + goto error; return 0; error: @@ -1361,9 +1368,12 @@ static int snd_ctl_elem_add(struct snd_ctl_file *file, kctl->tlv.c = snd_ctl_elem_user_tlv; /* This function manage to free the instance on failure. */ - err = snd_ctl_add(card, kctl); - if (err < 0) - return err; + down_write(&card->controls_rwsem); + err = __snd_ctl_add(card, kctl); + if (err < 0) { + snd_ctl_free_one(kctl); + goto unlock; + } offset = snd_ctl_get_ioff(kctl, &info->id); snd_ctl_build_ioff(&info->id, kctl, offset); /* @@ -1374,10 +1384,10 @@ static int snd_ctl_elem_add(struct snd_ctl_file *file, * which locks the element. */ - down_write(&card->controls_rwsem); card->user_ctl_count++; - up_write(&card->controls_rwsem); + unlock: + up_write(&card->controls_rwsem); return 0; } -- cgit v1.2.3-59-g8ed1b From c4cfcf6f4297c9256b53790bacbbbd6901fef468 Mon Sep 17 00:00:00 2001 From: Hui Wang Date: Mon, 26 Nov 2018 14:17:16 +0800 Subject: ALSA: hda/realtek - fix the pop noise on headphone for lenovo laptops We have several Lenovo laptops with the codec alc285, when playing sound via headphone, we can hear click/pop noise in the headphone, if we let the headphone share the DAC of NID 0x2 with the speaker, the noise disappears. The Lenovo laptops here include P52, P72, X1 yoda2 and X1 carbon. I have tried to set preferred_dacs and override_conn, but neither of them worked. Thanks for Kailang, he told me to invalidate the NID 0x3 through override_wcaps. BugLink: https://bugs.launchpad.net/bugs/1805079 Cc: Signed-off-by: Kailang Yang Signed-off-by: Hui Wang Signed-off-by: Takashi Iwai --- sound/pci/hda/patch_realtek.c | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c index 1118fd1bbf1a..e66da22272fd 100644 --- a/sound/pci/hda/patch_realtek.c +++ b/sound/pci/hda/patch_realtek.c @@ -5358,6 +5358,16 @@ static void alc274_fixup_bind_dacs(struct hda_codec *codec, spec->gen.preferred_dacs = preferred_pairs; } +/* The DAC of NID 0x3 will introduce click/pop noise on headphones, so invalidate it */ +static void alc285_fixup_invalidate_dacs(struct hda_codec *codec, + const struct hda_fixup *fix, int action) +{ + if (action != HDA_FIXUP_ACT_PRE_PROBE) + return; + + snd_hda_override_wcaps(codec, 0x03, 0); +} + /* for hda_fixup_thinkpad_acpi() */ #include "thinkpad_helper.c" @@ -5495,6 +5505,7 @@ enum { ALC255_FIXUP_DELL_HEADSET_MIC, ALC295_FIXUP_HP_X360, ALC221_FIXUP_HP_HEADSET_MIC, + ALC285_FIXUP_LENOVO_HEADPHONE_NOISE, }; static const struct hda_fixup alc269_fixups[] = { @@ -6362,6 +6373,10 @@ static const struct hda_fixup alc269_fixups[] = { .chained = true, .chain_id = ALC269_FIXUP_HEADSET_MIC }, + [ALC285_FIXUP_LENOVO_HEADPHONE_NOISE] = { + .type = HDA_FIXUP_FUNC, + .v.func = alc285_fixup_invalidate_dacs, + }, }; static const struct snd_pci_quirk alc269_fixup_tbl[] = { @@ -7035,6 +7050,11 @@ static const struct snd_hda_pin_quirk alc269_pin_fixup_tbl[] = { {0x12, 0x90a60130}, {0x19, 0x03a11020}, {0x21, 0x0321101f}), + SND_HDA_PIN_QUIRK(0x10ec0285, 0x17aa, "Lenovo", ALC285_FIXUP_LENOVO_HEADPHONE_NOISE, + {0x12, 0x90a60130}, + {0x14, 0x90170110}, + {0x19, 0x04a11040}, + {0x21, 0x04211020}), SND_HDA_PIN_QUIRK(0x10ec0288, 0x1028, "Dell", ALC288_FIXUP_DELL1_MIC_NO_PRESENCE, {0x12, 0x90a60120}, {0x14, 0x90170110}, -- cgit v1.2.3-59-g8ed1b From e8ed64b08eddc05043e556832616a478bbe4bb00 Mon Sep 17 00:00:00 2001 From: Girija Kumar Kasinadhuni Date: Mon, 26 Nov 2018 13:40:46 -0500 Subject: ALSA: hda/realtek - Add auto-mute quirk for HP Spectre x360 laptop This device makes a loud buzzing sound when a headphone is inserted while playing audio at full volume through the speaker. Fixes: bbf8ff6b1d2a ("ALSA: hda/realtek - Fixup for HP x360 laptops with B&O speakers") Signed-off-by: Girija Kumar Kasinadhuni Cc: Signed-off-by: Takashi Iwai --- sound/pci/hda/patch_realtek.c | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c index e66da22272fd..7d16dbb18e41 100644 --- a/sound/pci/hda/patch_realtek.c +++ b/sound/pci/hda/patch_realtek.c @@ -5506,6 +5506,7 @@ enum { ALC295_FIXUP_HP_X360, ALC221_FIXUP_HP_HEADSET_MIC, ALC285_FIXUP_LENOVO_HEADPHONE_NOISE, + ALC295_FIXUP_HP_AUTO_MUTE, }; static const struct hda_fixup alc269_fixups[] = { @@ -5670,6 +5671,8 @@ static const struct hda_fixup alc269_fixups[] = { [ALC269_FIXUP_HP_MUTE_LED_MIC3] = { .type = HDA_FIXUP_FUNC, .v.func = alc269_fixup_hp_mute_led_mic3, + .chained = true, + .chain_id = ALC295_FIXUP_HP_AUTO_MUTE }, [ALC269_FIXUP_HP_GPIO_LED] = { .type = HDA_FIXUP_FUNC, @@ -6377,6 +6380,10 @@ static const struct hda_fixup alc269_fixups[] = { .type = HDA_FIXUP_FUNC, .v.func = alc285_fixup_invalidate_dacs, }, + [ALC295_FIXUP_HP_AUTO_MUTE] = { + .type = HDA_FIXUP_FUNC, + .v.func = alc_fixup_auto_mute_via_amp, + }, }; static const struct snd_pci_quirk alc269_fixup_tbl[] = { -- cgit v1.2.3-59-g8ed1b From 1078bef0cd9291355a20369b21cd823026ab8eaa Mon Sep 17 00:00:00 2001 From: Kailang Yang Date: Thu, 8 Nov 2018 16:36:15 +0800 Subject: ALSA: hda/realtek - Support ALC300 This patch will enable ALC300. [ It's almost equivalent with other ALC269-compatible ones, and apparently has no loopback mixer -- tiwai ] Signed-off-by: Kailang Yang Cc: Signed-off-by: Takashi Iwai --- sound/pci/hda/patch_realtek.c | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c index 7d16dbb18e41..06f93032d0cc 100644 --- a/sound/pci/hda/patch_realtek.c +++ b/sound/pci/hda/patch_realtek.c @@ -388,6 +388,7 @@ static void alc_fill_eapd_coef(struct hda_codec *codec) case 0x10ec0285: case 0x10ec0298: case 0x10ec0289: + case 0x10ec0300: alc_update_coef_idx(codec, 0x10, 1<<9, 0); break; case 0x10ec0275: @@ -2830,6 +2831,7 @@ enum { ALC269_TYPE_ALC215, ALC269_TYPE_ALC225, ALC269_TYPE_ALC294, + ALC269_TYPE_ALC300, ALC269_TYPE_ALC700, }; @@ -2864,6 +2866,7 @@ static int alc269_parse_auto_config(struct hda_codec *codec) case ALC269_TYPE_ALC215: case ALC269_TYPE_ALC225: case ALC269_TYPE_ALC294: + case ALC269_TYPE_ALC300: case ALC269_TYPE_ALC700: ssids = alc269_ssids; break; @@ -7323,6 +7326,10 @@ static int patch_alc269(struct hda_codec *codec) spec->gen.mixer_nid = 0; /* ALC2x4 does not have any loopback mixer path */ alc_update_coef_idx(codec, 0x6b, 0x0018, (1<<4) | (1<<3)); /* UAJ MIC Vref control by verb */ break; + case 0x10ec0300: + spec->codec_variant = ALC269_TYPE_ALC300; + spec->gen.mixer_nid = 0; /* no loopback on ALC300 */ + break; case 0x10ec0700: case 0x10ec0701: case 0x10ec0703: @@ -8433,6 +8440,7 @@ static const struct hda_device_id snd_hda_id_realtek[] = { HDA_CODEC_ENTRY(0x10ec0295, "ALC295", patch_alc269), HDA_CODEC_ENTRY(0x10ec0298, "ALC298", patch_alc269), HDA_CODEC_ENTRY(0x10ec0299, "ALC299", patch_alc269), + HDA_CODEC_ENTRY(0x10ec0300, "ALC300", patch_alc269), HDA_CODEC_REV_ENTRY(0x10ec0861, 0x100340, "ALC660", patch_alc861), HDA_CODEC_ENTRY(0x10ec0660, "ALC660-VD", patch_alc861vd), HDA_CODEC_ENTRY(0x10ec0861, "ALC861", patch_alc861), -- cgit v1.2.3-59-g8ed1b From 8159a6a4a7d2a092d5375f695ecfca22b4562b5f Mon Sep 17 00:00:00 2001 From: Hui Wang Date: Wed, 28 Nov 2018 17:11:26 +0800 Subject: ALSA: usb-audio: Add vendor and product name for Dell WD19 Dock Like the Dell WD15 Dock, the WD19 Dock (0bda:402e) doens't provide useful string for the vendor and product names too. In order to share the UCM with WD15, here we keep the profile_name same as the WD15. Signed-off-by: Hui Wang Signed-off-by: Takashi Iwai --- sound/usb/quirks-table.h | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/sound/usb/quirks-table.h b/sound/usb/quirks-table.h index 849953e5775c..37fc0447c071 100644 --- a/sound/usb/quirks-table.h +++ b/sound/usb/quirks-table.h @@ -3382,5 +3382,15 @@ AU0828_DEVICE(0x2040, 0x7270, "Hauppauge", "HVR-950Q"), .ifnum = QUIRK_NO_INTERFACE } }, +/* Dell WD19 Dock */ +{ + USB_DEVICE(0x0bda, 0x402e), + .driver_info = (unsigned long) & (const struct snd_usb_audio_quirk) { + .vendor_name = "Dell", + .product_name = "WD19 Dock", + .profile_name = "Dell-WD15-Dock", + .ifnum = QUIRK_NO_INTERFACE + } +}, #undef USB_DEVICE_VENDOR_SPEC -- cgit v1.2.3-59-g8ed1b