From 8e55ea19125b65cffe42747359af99d545e85f2f Mon Sep 17 00:00:00 2001 From: Olivier Moysan Date: Fri, 10 Jan 2020 14:11:31 +0100 Subject: ASoC: stm32: dfsdm: fix 16 bits record In stm32_afsdm_pcm_cb function, the transfer size is provided in bytes. However, samples are copied as 16 bits words from iio buffer. Divide by two the transfer size, to copy the right number of samples. Fixes: 1e7f6e1c69f0 ("ASoC: stm32: dfsdm: add 16 bits audio record support") Signed-off-by: Olivier Moysan Link: https://lore.kernel.org/r/20200110131131.3191-1-olivier.moysan@st.com Signed-off-by: Mark Brown --- sound/soc/stm/stm32_adfsdm.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/sound/soc/stm/stm32_adfsdm.c b/sound/soc/stm/stm32_adfsdm.c index 81c407da15c5..08696a4adb69 100644 --- a/sound/soc/stm/stm32_adfsdm.c +++ b/sound/soc/stm/stm32_adfsdm.c @@ -153,13 +153,13 @@ static const struct snd_soc_component_driver stm32_adfsdm_dai_component = { .name = "stm32_dfsdm_audio", }; -static void memcpy_32to16(void *dest, const void *src, size_t n) +static void stm32_memcpy_32to16(void *dest, const void *src, size_t n) { unsigned int i = 0; u16 *d = (u16 *)dest, *s = (u16 *)src; s++; - for (i = n; i > 0; i--) { + for (i = n >> 1; i > 0; i--) { *d++ = *s++; s++; } @@ -186,8 +186,8 @@ static int stm32_afsdm_pcm_cb(const void *data, size_t size, void *private) if ((priv->pos + src_size) > buff_size) { if (format == SNDRV_PCM_FORMAT_S16_LE) - memcpy_32to16(&pcm_buff[priv->pos], src_buff, - buff_size - priv->pos); + stm32_memcpy_32to16(&pcm_buff[priv->pos], src_buff, + buff_size - priv->pos); else memcpy(&pcm_buff[priv->pos], src_buff, buff_size - priv->pos); @@ -196,8 +196,8 @@ static int stm32_afsdm_pcm_cb(const void *data, size_t size, void *private) } if (format == SNDRV_PCM_FORMAT_S16_LE) - memcpy_32to16(&pcm_buff[priv->pos], - &src_buff[src_size - cur_size], cur_size); + stm32_memcpy_32to16(&pcm_buff[priv->pos], + &src_buff[src_size - cur_size], cur_size); else memcpy(&pcm_buff[priv->pos], &src_buff[src_size - cur_size], cur_size); -- cgit v1.2.3-58-ga151 From ceca2197b2f1af4cb6e3f32bb7bd2879943406ef Mon Sep 17 00:00:00 2001 From: Bard liao Date: Fri, 10 Jan 2020 17:57:48 -0600 Subject: ASoC: SOF: Intel: lower print level to dbg if we will reinit DSP We will reinit DSP in a loop when it fails to initialize the first time, as recommended. So, it is not an error before we finally give up. And reorder the trace to make it more readable. Signed-off-by: Bard liao Signed-off-by: Pierre-Louis Bossart Link: https://lore.kernel.org/r/20200110235751.3404-6-pierre-louis.bossart@linux.intel.com Signed-off-by: Mark Brown --- sound/soc/sof/intel/hda-loader.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/sound/soc/sof/intel/hda-loader.c b/sound/soc/sof/intel/hda-loader.c index b1783360fe10..bae7ac3581e5 100644 --- a/sound/soc/sof/intel/hda-loader.c +++ b/sound/soc/sof/intel/hda-loader.c @@ -329,13 +329,13 @@ int hda_dsp_cl_boot_firmware(struct snd_sof_dev *sdev) if (!ret) break; - dev_err(sdev->dev, "error: Error code=0x%x: FW status=0x%x\n", + dev_dbg(sdev->dev, "iteration %d of Core En/ROM load failed: %d\n", + i, ret); + dev_dbg(sdev->dev, "Error code=0x%x: FW status=0x%x\n", snd_sof_dsp_read(sdev, HDA_DSP_BAR, HDA_DSP_SRAM_REG_ROM_ERROR), snd_sof_dsp_read(sdev, HDA_DSP_BAR, HDA_DSP_SRAM_REG_ROM_STATUS)); - dev_err(sdev->dev, "error: iteration %d of Core En/ROM load failed: %d\n", - i, ret); } if (i == HDA_FW_BOOT_ATTEMPTS) { -- cgit v1.2.3-58-ga151 From 2c63bea714780f8e1fc9cb7bc10deda26fada25b Mon Sep 17 00:00:00 2001 From: Kai Vehmanen Date: Fri, 10 Jan 2020 17:57:50 -0600 Subject: ASoC: SOF: Intel: fix HDA codec driver probe with multiple controllers In case system has multiple HDA controllers, it can happen that same HDA codec driver is used for codecs of multiple controllers. In this case, SOF may fail to probe the HDA driver and SOF initialization fails. SOF HDA code currently relies that a call to request_module() will also run device matching logic to attach driver to the codec instance. However if driver for another HDA controller was already loaded and it already loaded the HDA codec driver, this breaks current logic in SOF. In this case the request_module() SOF does becomes a no-op and HDA Codec driver is not attached to the codec instance sitting on the HDA bus SOF is controlling. Typical scenario would be a system with both external and internal GPUs, with driver of the external GPU loaded first. Fix this by adding similar logic as is used in legacy HDA driver where an explicit device_attach() call is done after request_module(). Also add logic to propagate errors reported by device_attach() back to caller. This also works in the case where drivers are not built as modules. Signed-off-by: Kai Vehmanen Signed-off-by: Pierre-Louis Bossart Link: https://lore.kernel.org/r/20200110235751.3404-8-pierre-louis.bossart@linux.intel.com Signed-off-by: Mark Brown --- sound/soc/sof/intel/hda-codec.c | 19 ++++++++++++------- 1 file changed, 12 insertions(+), 7 deletions(-) diff --git a/sound/soc/sof/intel/hda-codec.c b/sound/soc/sof/intel/hda-codec.c index 827f84a0722e..fbfa225d1c5a 100644 --- a/sound/soc/sof/intel/hda-codec.c +++ b/sound/soc/sof/intel/hda-codec.c @@ -24,19 +24,18 @@ #define IDISP_VID_INTEL 0x80860000 /* load the legacy HDA codec driver */ -#ifdef MODULE -static void hda_codec_load_module(struct hda_codec *codec) +static int hda_codec_load_module(struct hda_codec *codec) { +#ifdef MODULE char alias[MODULE_NAME_LEN]; const char *module = alias; snd_hdac_codec_modalias(&codec->core, alias, sizeof(alias)); dev_dbg(&codec->core.dev, "loading codec module: %s\n", module); request_module(module); -} -#else -static void hda_codec_load_module(struct hda_codec *codec) {} #endif + return device_attach(hda_codec_dev(codec)); +} /* enable controller wake up event for all codecs with jack connectors */ void hda_codec_jack_wake_enable(struct snd_sof_dev *sdev) @@ -129,10 +128,16 @@ static int hda_codec_probe(struct snd_sof_dev *sdev, int address) if ((mach_params && mach_params->common_hdmi_codec_drv) || (resp & 0xFFFF0000) != IDISP_VID_INTEL) { hdev->type = HDA_DEV_LEGACY; - hda_codec_load_module(&hda_priv->codec); + ret = hda_codec_load_module(&hda_priv->codec); + /* + * handle ret==0 (no driver bound) as an error, but pass + * other return codes without modification + */ + if (ret == 0) + ret = -ENOENT; } - return 0; + return ret; #else hdev = devm_kzalloc(sdev->dev, sizeof(*hdev), GFP_KERNEL); if (!hdev) -- cgit v1.2.3-58-ga151 From 552b1a85da9f63856e7e341b81c16e0e078204f1 Mon Sep 17 00:00:00 2001 From: Kai Vehmanen Date: Fri, 10 Jan 2020 17:57:51 -0600 Subject: ASoC: hdac_hda: Fix error in driver removal after failed probe In case system has multiple HDA codecs, and codec probe fails for at least one but not all codecs, driver will end up cancelling a non-initialized timer context upon driver removal. Call trace of typical case: [ 60.593646] WARNING: CPU: 1 PID: 1147 at kernel/workqueue.c:3032 __flush_work+0x18b/0x1a0 [...] [ 60.593670] __cancel_work_timer+0x11f/0x1a0 [ 60.593673] hdac_hda_dev_remove+0x25/0x30 [snd_soc_hdac_hda] [ 60.593674] device_release_driver_internal+0xe0/0x1c0 [ 60.593675] bus_remove_device+0xd6/0x140 [ 60.593677] device_del+0x175/0x3e0 [ 60.593679] ? widget_tree_free.isra.7+0x90/0xb0 [snd_hda_core] [ 60.593680] snd_hdac_device_unregister+0x34/0x50 [snd_hda_core] [ 60.593682] snd_hdac_ext_bus_device_remove+0x2a/0x60 [snd_hda_ext_core] [ 60.593684] hda_dsp_remove+0x26/0x100 [snd_sof_intel_hda_common] [ 60.593686] snd_sof_device_remove+0x84/0xa0 [snd_sof] [ 60.593687] sof_pci_remove+0x10/0x30 [snd_sof_pci] [ 60.593689] pci_device_remove+0x36/0xb0 Signed-off-by: Kai Vehmanen Signed-off-by: Pierre-Louis Bossart Link: https://lore.kernel.org/r/20200110235751.3404-9-pierre-louis.bossart@linux.intel.com Signed-off-by: Mark Brown --- sound/soc/codecs/hdac_hda.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/sound/soc/codecs/hdac_hda.c b/sound/soc/codecs/hdac_hda.c index 6803d39e09a5..43110151e928 100644 --- a/sound/soc/codecs/hdac_hda.c +++ b/sound/soc/codecs/hdac_hda.c @@ -588,7 +588,9 @@ static int hdac_hda_dev_remove(struct hdac_device *hdev) struct hdac_hda_priv *hda_pvt; hda_pvt = dev_get_drvdata(&hdev->dev); - cancel_delayed_work_sync(&hda_pvt->codec.jackpoll_work); + if (hda_pvt && hda_pvt->codec.registered) + cancel_delayed_work_sync(&hda_pvt->codec.jackpoll_work); + return 0; } -- cgit v1.2.3-58-ga151 From e0beec88397b163c7c4ea6fcfb67e8e07a2671dc Mon Sep 17 00:00:00 2001 From: Stephan Gerhold Date: Sat, 11 Jan 2020 17:40:03 +0100 Subject: ASoC: msm8916-wcd-analog: Fix selected events for MIC BIAS External1 MIC BIAS External1 sets pm8916_wcd_analog_enable_micbias_ext1() as event handler, which ends up in pm8916_wcd_analog_enable_micbias_ext(). But pm8916_wcd_analog_enable_micbias_ext() only handles the POST_PMU event, which is not specified in the event flags for MIC BIAS External1. This means that the code in the event handler is never actually run. Set SND_SOC_DAPM_POST_PMU as the only event for the handler to fix this. Fixes: 585e881e5b9e ("ASoC: codecs: Add msm8916-wcd analog codec") Cc: Srinivas Kandagatla Signed-off-by: Stephan Gerhold Link: https://lore.kernel.org/r/20200111164006.43074-2-stephan@gerhold.net Signed-off-by: Mark Brown --- sound/soc/codecs/msm8916-wcd-analog.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/sound/soc/codecs/msm8916-wcd-analog.c b/sound/soc/codecs/msm8916-wcd-analog.c index f53235be77d9..30b19f12fabc 100644 --- a/sound/soc/codecs/msm8916-wcd-analog.c +++ b/sound/soc/codecs/msm8916-wcd-analog.c @@ -938,10 +938,10 @@ static const struct snd_soc_dapm_widget pm8916_wcd_analog_dapm_widgets[] = { SND_SOC_DAPM_SUPPLY("MIC BIAS External1", CDC_A_MICB_1_EN, 7, 0, pm8916_wcd_analog_enable_micbias_ext1, - SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD), + SND_SOC_DAPM_POST_PMU), SND_SOC_DAPM_SUPPLY("MIC BIAS External2", CDC_A_MICB_2_EN, 7, 0, pm8916_wcd_analog_enable_micbias_ext2, - SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD), + SND_SOC_DAPM_POST_PMU), SND_SOC_DAPM_ADC_E("ADC1", NULL, CDC_A_TX_1_EN, 7, 0, pm8916_wcd_analog_enable_adc, -- cgit v1.2.3-58-ga151 From ce780a47c3c01e1e179d0792df6b853a913928f1 Mon Sep 17 00:00:00 2001 From: Arnaud Pouliquen Date: Mon, 13 Jan 2020 11:04:00 +0100 Subject: ASoC: sti: fix possible sleep-in-atomic Change mutex and spinlock management to avoid sleep in atomic issue. Signed-off-by: Arnaud Pouliquen Link: https://lore.kernel.org/r/20200113100400.30472-1-arnaud.pouliquen@st.com Signed-off-by: Mark Brown --- sound/soc/sti/uniperif_player.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/sound/soc/sti/uniperif_player.c b/sound/soc/sti/uniperif_player.c index 48ea915b24ba..2ed92c990b97 100644 --- a/sound/soc/sti/uniperif_player.c +++ b/sound/soc/sti/uniperif_player.c @@ -226,7 +226,6 @@ static void uni_player_set_channel_status(struct uniperif *player, * sampling frequency. If no sample rate is already specified, then * set one. */ - mutex_lock(&player->ctrl_lock); if (runtime) { switch (runtime->rate) { case 22050: @@ -303,7 +302,6 @@ static void uni_player_set_channel_status(struct uniperif *player, player->stream_settings.iec958.status[3 + (n * 4)] << 24; SET_UNIPERIF_CHANNEL_STA_REGN(player, n, status); } - mutex_unlock(&player->ctrl_lock); /* Update the channel status */ if (player->ver < SND_ST_UNIPERIF_VERSION_UNI_PLR_TOP_1_0) @@ -365,8 +363,10 @@ static int uni_player_prepare_iec958(struct uniperif *player, SET_UNIPERIF_CTRL_ZERO_STUFF_HW(player); + mutex_lock(&player->ctrl_lock); /* Update the channel status */ uni_player_set_channel_status(player, runtime); + mutex_unlock(&player->ctrl_lock); /* Clear the user validity user bits */ SET_UNIPERIF_USER_VALIDITY_VALIDITY_LR(player, 0); @@ -598,7 +598,6 @@ static int uni_player_ctl_iec958_put(struct snd_kcontrol *kcontrol, iec958->status[1] = ucontrol->value.iec958.status[1]; iec958->status[2] = ucontrol->value.iec958.status[2]; iec958->status[3] = ucontrol->value.iec958.status[3]; - mutex_unlock(&player->ctrl_lock); spin_lock_irqsave(&player->irq_lock, flags); if (player->substream && player->substream->runtime) @@ -608,6 +607,8 @@ static int uni_player_ctl_iec958_put(struct snd_kcontrol *kcontrol, uni_player_set_channel_status(player, NULL); spin_unlock_irqrestore(&player->irq_lock, flags); + mutex_unlock(&player->ctrl_lock); + return 0; } -- cgit v1.2.3-58-ga151 From 877167ef343de2a9be3d31cdd5c41122e61190dd Mon Sep 17 00:00:00 2001 From: Yu-Hsuan Hsu Date: Sun, 12 Jan 2020 13:49:00 +0800 Subject: ASoC: cros_ec_codec: Make the device acpi compatible Add ACPI entry for cros_ec_codec. Signed-off-by: Yu-Hsuan Hsu Link: https://lore.kernel.org/r/20200112054900.236576-1-yuhsuan@chromium.org Signed-off-by: Mark Brown --- sound/soc/codecs/cros_ec_codec.c | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/sound/soc/codecs/cros_ec_codec.c b/sound/soc/codecs/cros_ec_codec.c index dd14caf9091a..bc31e5a9a2a7 100644 --- a/sound/soc/codecs/cros_ec_codec.c +++ b/sound/soc/codecs/cros_ec_codec.c @@ -10,6 +10,7 @@ #include #include +#include #include #include #include @@ -1047,10 +1048,17 @@ static const struct of_device_id cros_ec_codec_of_match[] = { MODULE_DEVICE_TABLE(of, cros_ec_codec_of_match); #endif +static const struct acpi_device_id cros_ec_codec_acpi_id[] = { + { "GOOG0013", 0 }, + { } +}; +MODULE_DEVICE_TABLE(acpi, cros_ec_codec_acpi_id); + static struct platform_driver cros_ec_codec_platform_driver = { .driver = { .name = "cros-ec-codec", .of_match_table = of_match_ptr(cros_ec_codec_of_match), + .acpi_match_table = ACPI_PTR(cros_ec_codec_acpi_id), }, .probe = cros_ec_codec_platform_probe, }; -- cgit v1.2.3-58-ga151 From 057efcf9faea4769cf1020677d93d040db9b23f3 Mon Sep 17 00:00:00 2001 From: Stephan Gerhold Date: Sat, 11 Jan 2020 17:40:04 +0100 Subject: ASoC: msm8916-wcd-analog: Fix MIC BIAS Internal1 MIC BIAS Internal1 is broken at the moment because we always enable the internal rbias resistor to the TX2 line (connected to the headset microphone), rather than enabling the resistor connected to TX1. Move the RBIAS code to pm8916_wcd_analog_enable_micbias_int1/2() to fix this. Fixes: 585e881e5b9e ("ASoC: codecs: Add msm8916-wcd analog codec") Cc: Srinivas Kandagatla Signed-off-by: Stephan Gerhold Link: https://lore.kernel.org/r/20200111164006.43074-3-stephan@gerhold.net Signed-off-by: Mark Brown --- sound/soc/codecs/msm8916-wcd-analog.c | 16 +++++++++++++--- 1 file changed, 13 insertions(+), 3 deletions(-) diff --git a/sound/soc/codecs/msm8916-wcd-analog.c b/sound/soc/codecs/msm8916-wcd-analog.c index 30b19f12fabc..1f7964beb20c 100644 --- a/sound/soc/codecs/msm8916-wcd-analog.c +++ b/sound/soc/codecs/msm8916-wcd-analog.c @@ -396,9 +396,6 @@ static int pm8916_wcd_analog_enable_micbias_int(struct snd_soc_component switch (event) { case SND_SOC_DAPM_PRE_PMU: - snd_soc_component_update_bits(component, CDC_A_MICB_1_INT_RBIAS, - MICB_1_INT_TX2_INT_RBIAS_EN_MASK, - MICB_1_INT_TX2_INT_RBIAS_EN_ENABLE); snd_soc_component_update_bits(component, reg, MICB_1_EN_PULL_DOWN_EN_MASK, 0); snd_soc_component_update_bits(component, CDC_A_MICB_1_EN, MICB_1_EN_OPA_STG2_TAIL_CURR_MASK, @@ -448,6 +445,14 @@ static int pm8916_wcd_analog_enable_micbias_int1(struct struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm); struct pm8916_wcd_analog_priv *wcd = snd_soc_component_get_drvdata(component); + switch (event) { + case SND_SOC_DAPM_PRE_PMU: + snd_soc_component_update_bits(component, CDC_A_MICB_1_INT_RBIAS, + MICB_1_INT_TX1_INT_RBIAS_EN_MASK, + MICB_1_INT_TX1_INT_RBIAS_EN_ENABLE); + break; + } + return pm8916_wcd_analog_enable_micbias_int(component, event, w->reg, wcd->micbias1_cap_mode); } @@ -558,6 +563,11 @@ static int pm8916_wcd_analog_enable_micbias_int2(struct struct pm8916_wcd_analog_priv *wcd = snd_soc_component_get_drvdata(component); switch (event) { + case SND_SOC_DAPM_PRE_PMU: + snd_soc_component_update_bits(component, CDC_A_MICB_1_INT_RBIAS, + MICB_1_INT_TX2_INT_RBIAS_EN_MASK, + MICB_1_INT_TX2_INT_RBIAS_EN_ENABLE); + break; case SND_SOC_DAPM_POST_PMU: pm8916_mbhc_configure_bias(wcd, true); break; -- cgit v1.2.3-58-ga151 From 85578bbd642f65065039b1765ebe1a867d5435b0 Mon Sep 17 00:00:00 2001 From: Stephan Gerhold Date: Sun, 5 Jan 2020 11:27:53 +0100 Subject: ASoC: msm8916-wcd-digital: Reset RX interpolation path after use For some reason, attempting to route audio through QDSP6 on MSM8916 causes the RX interpolation path to get "stuck" after playing audio a few times. In this situation, the analog codec part is still working, but the RX path in the digital codec stops working, so you only hear the analog parts powering up. After a reboot everything works again. So far I was not able to reproduce the problem when using lpass-cpu. The downstream kernel driver avoids this by resetting the RX interpolation path after use. In mainline we do something similar for the TX decimator (LPASS_CDC_CLK_TX_RESET_B1_CTL), but the interpolator reset (LPASS_CDC_CLK_RX_RESET_CTL) got lost when the msm8916-wcd driver was split into analog and digital. Fix this problem by adding the reset to msm8916_wcd_digital_enable_interpolator(). Fixes: 150db8c5afa1 ("ASoC: codecs: Add msm8916-wcd digital codec") Cc: Srinivas Kandagatla Signed-off-by: Stephan Gerhold Link: https://lore.kernel.org/r/20200105102753.83108-1-stephan@gerhold.net Signed-off-by: Mark Brown --- sound/soc/codecs/msm8916-wcd-digital.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/sound/soc/codecs/msm8916-wcd-digital.c b/sound/soc/codecs/msm8916-wcd-digital.c index 58b2468fb2a7..09fccacadd6b 100644 --- a/sound/soc/codecs/msm8916-wcd-digital.c +++ b/sound/soc/codecs/msm8916-wcd-digital.c @@ -586,6 +586,12 @@ static int msm8916_wcd_digital_enable_interpolator( snd_soc_component_write(component, rx_gain_reg[w->shift], snd_soc_component_read32(component, rx_gain_reg[w->shift])); break; + case SND_SOC_DAPM_POST_PMD: + snd_soc_component_update_bits(component, LPASS_CDC_CLK_RX_RESET_CTL, + 1 << w->shift, 1 << w->shift); + snd_soc_component_update_bits(component, LPASS_CDC_CLK_RX_RESET_CTL, + 1 << w->shift, 0x0); + break; } return 0; } -- cgit v1.2.3-58-ga151