summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTakashi Iwai <tiwai@suse.de>2026-04-29 08:46:33 +0300
committerTakashi Iwai <tiwai@suse.de>2026-04-29 08:46:33 +0300
commita7b75a11c6f16c049a2ea17cf9d1aaaa57201cf3 (patch)
treea156862cf2a94e17ab55ee8c17658c8f3b2b942f
parent6e7247d8f5fefeceb0bb9cc80a5388a636b219cd (diff)
parent03dcb5b68a96b51157ec2d17042fa2f0106828ae (diff)
downloadlinux-a7b75a11c6f16c049a2ea17cf9d1aaaa57201cf3.tar.xz
Merge tag 'asoc-fix-v7.1-rc1' of https://git.kernel.org/pub/scm/linux/kernel/git/broonie/sound into for-linus
ASoC: Fixes for v7.1 We've had quite a lot of fixes come in this past week, all driver stuff rather than any broad systematic issue. All quite routine stuff.
-rw-r--r--sound/soc/amd/acp/acp-legacy-mach.c2
-rw-r--r--sound/soc/amd/acp/acp-mach-common.c22
-rw-r--r--sound/soc/amd/acp/acp-mach.h4
-rw-r--r--sound/soc/amd/acp/acp-sof-mach.c2
-rw-r--r--sound/soc/codecs/ab8500-codec.c6
-rw-r--r--sound/soc/codecs/aw88395/aw88395.c9
-rw-r--r--sound/soc/codecs/cs35l56-shared.c7
-rw-r--r--sound/soc/codecs/es8389.c2
-rw-r--r--sound/soc/codecs/tas2764.c1
-rw-r--r--sound/soc/codecs/tas2770.c4
-rw-r--r--sound/soc/codecs/wcd937x.c26
-rw-r--r--sound/soc/intel/boards/bytcr_wm5102.c1
-rw-r--r--sound/soc/sof/intel/hda.c3
-rw-r--r--sound/soc/spacemit/k1_i2s.c49
-rw-r--r--sound/soc/tegra/Makefile1
15 files changed, 101 insertions, 38 deletions
diff --git a/sound/soc/amd/acp/acp-legacy-mach.c b/sound/soc/amd/acp/acp-legacy-mach.c
index a7a551366a40..235d6cc83fa9 100644
--- a/sound/soc/amd/acp/acp-legacy-mach.c
+++ b/sound/soc/amd/acp/acp-legacy-mach.c
@@ -174,7 +174,7 @@ static int acp_asoc_probe(struct platform_device *pdev)
acp_card_drvdata->acp_rev = mach->mach_params.subsystem_rev;
dmi_id = dmi_first_match(acp_quirk_table);
- if (dmi_id && dmi_id->driver_data)
+ if (dmi_id && dmi_id->driver_data == (void *)QUIRK_TDM_MODE_ENABLE)
acp_card_drvdata->tdm_mode = dmi_id->driver_data;
ret = acp_legacy_dai_links_create(card);
diff --git a/sound/soc/amd/acp/acp-mach-common.c b/sound/soc/amd/acp/acp-mach-common.c
index 09f6c9a2c041..ef784cca13f2 100644
--- a/sound/soc/amd/acp/acp-mach-common.c
+++ b/sound/soc/amd/acp/acp-mach-common.c
@@ -20,6 +20,7 @@
#include <sound/soc.h>
#include <linux/input.h>
#include <linux/module.h>
+#include <linux/dmi.h>
#include "../../codecs/rt5682.h"
#include "../../codecs/rt1019.h"
@@ -37,15 +38,21 @@
#define NAU8821_FREQ_OUT 12288000
#define MAX98388_CODEC_DAI "max98388-aif1"
-#define TDM_MODE_ENABLE 1
-
const struct dmi_system_id acp_quirk_table[] = {
{
/* Google skyrim proto-0 */
.matches = {
DMI_EXACT_MATCH(DMI_PRODUCT_FAMILY, "Google_Skyrim"),
},
- .driver_data = (void *)TDM_MODE_ENABLE,
+ .driver_data = (void *)QUIRK_TDM_MODE_ENABLE,
+ },
+ {
+ /* Valve Steam Deck OLED */
+ .matches = {
+ DMI_MATCH(DMI_SYS_VENDOR, "Valve"),
+ DMI_MATCH(DMI_PRODUCT_NAME, "Galileo"),
+ },
+ .driver_data = (void *)QUIRK_REMAP_DMIC_BT,
},
{}
};
@@ -1401,6 +1408,7 @@ int acp_sofdsp_dai_links_create(struct snd_soc_card *card)
struct snd_soc_dai_link *links;
struct device *dev = card->dev;
struct acp_card_drvdata *drv_data = card->drvdata;
+ const struct dmi_system_id *dmi_id = dmi_first_match(acp_quirk_table);
int i = 0, num_links = 0;
if (drv_data->hs_cpu_id)
@@ -1572,6 +1580,9 @@ int acp_sofdsp_dai_links_create(struct snd_soc_card *card)
links[i].codecs = &snd_soc_dummy_dlc;
links[i].num_codecs = 1;
}
+
+ if (dmi_id && dmi_id->driver_data == (void *)QUIRK_REMAP_DMIC_BT)
+ links[i].id = DMIC_BE_ID;
i++;
}
@@ -1587,6 +1598,11 @@ int acp_sofdsp_dai_links_create(struct snd_soc_card *card)
links[i].capture_only = 1;
links[i].nonatomic = true;
links[i].no_pcm = 1;
+
+ if (dmi_id && dmi_id->driver_data == (void *)QUIRK_REMAP_DMIC_BT) {
+ links[i].id = BT_BE_ID;
+ dev_dbg(dev, "quirk REMAP_DMIC_BT enabled\n");
+ }
}
card->dai_link = links;
diff --git a/sound/soc/amd/acp/acp-mach.h b/sound/soc/amd/acp/acp-mach.h
index f94c30c20f20..7177d3fd9619 100644
--- a/sound/soc/amd/acp/acp-mach.h
+++ b/sound/soc/amd/acp/acp-mach.h
@@ -26,6 +26,10 @@
#define acp_get_drvdata(card) ((struct acp_card_drvdata *)(card)->drvdata)
+/* List of DMI quirks - check acp-mach-common.c for usage. */
+#define QUIRK_TDM_MODE_ENABLE 1
+#define QUIRK_REMAP_DMIC_BT 2
+
enum be_id {
HEADSET_BE_ID = 0,
AMP_BE_ID,
diff --git a/sound/soc/amd/acp/acp-sof-mach.c b/sound/soc/amd/acp/acp-sof-mach.c
index 6215e31ecedd..36ecef7013b9 100644
--- a/sound/soc/amd/acp/acp-sof-mach.c
+++ b/sound/soc/amd/acp/acp-sof-mach.c
@@ -110,7 +110,7 @@ static int acp_sof_probe(struct platform_device *pdev)
acp_card_drvdata = card->drvdata;
dmi_id = dmi_first_match(acp_quirk_table);
- if (dmi_id && dmi_id->driver_data)
+ if (dmi_id && dmi_id->driver_data == (void *)QUIRK_TDM_MODE_ENABLE)
acp_card_drvdata->tdm_mode = dmi_id->driver_data;
acp_card_drvdata->acp_rev = mach->mach_params.subsystem_rev;
diff --git a/sound/soc/codecs/ab8500-codec.c b/sound/soc/codecs/ab8500-codec.c
index fdda1b747bf7..8ab2e60f80b4 100644
--- a/sound/soc/codecs/ab8500-codec.c
+++ b/sound/soc/codecs/ab8500-codec.c
@@ -2496,13 +2496,13 @@ static int ab8500_codec_probe(struct snd_soc_component *component)
return status;
}
fc = (struct filter_control *)
- &ab8500_filter_controls[AB8500_FILTER_ANC_FIR].private_value;
+ ab8500_filter_controls[AB8500_FILTER_ANC_FIR].private_value;
drvdata->anc_fir_values = (long *)fc->value;
fc = (struct filter_control *)
- &ab8500_filter_controls[AB8500_FILTER_ANC_IIR].private_value;
+ ab8500_filter_controls[AB8500_FILTER_ANC_IIR].private_value;
drvdata->anc_iir_values = (long *)fc->value;
fc = (struct filter_control *)
- &ab8500_filter_controls[AB8500_FILTER_SID_FIR].private_value;
+ ab8500_filter_controls[AB8500_FILTER_SID_FIR].private_value;
drvdata->sid_fir_values = (long *)fc->value;
snd_soc_dapm_disable_pin(dapm, "ANC Configure Input");
diff --git a/sound/soc/codecs/aw88395/aw88395.c b/sound/soc/codecs/aw88395/aw88395.c
index 3602b5b9f7d7..dd09bac652f7 100644
--- a/sound/soc/codecs/aw88395/aw88395.c
+++ b/sound/soc/codecs/aw88395/aw88395.c
@@ -456,8 +456,6 @@ static void aw88395_hw_reset(struct aw88395 *aw88395)
usleep_range(AW88395_1000_US, AW88395_1000_US + 10);
gpiod_set_value_cansleep(aw88395->reset_gpio, 1);
usleep_range(AW88395_1000_US, AW88395_1000_US + 10);
- } else {
- dev_err(aw88395->aw_pa->dev, "%s failed", __func__);
}
}
@@ -522,9 +520,10 @@ static int aw88395_i2c_probe(struct i2c_client *i2c)
i2c_set_clientdata(i2c, aw88395);
aw88395->reset_gpio = devm_gpiod_get_optional(&i2c->dev, "reset", GPIOD_OUT_LOW);
- if (IS_ERR(aw88395->reset_gpio))
- dev_info(&i2c->dev, "reset gpio not defined\n");
-
+ if (IS_ERR(aw88395->reset_gpio)) {
+ return dev_err_probe(&i2c->dev, PTR_ERR(aw88395->reset_gpio),
+ "failed to get reset gpio\n");
+ }
/* hardware reset */
aw88395_hw_reset(aw88395);
diff --git a/sound/soc/codecs/cs35l56-shared.c b/sound/soc/codecs/cs35l56-shared.c
index e05d975ba794..033e56d5e9db 100644
--- a/sound/soc/codecs/cs35l56-shared.c
+++ b/sound/soc/codecs/cs35l56-shared.c
@@ -108,8 +108,6 @@ int cs35l56_set_patch(struct cs35l56_base *cs35l56_base)
EXPORT_SYMBOL_NS_GPL(cs35l56_set_patch, "SND_SOC_CS35L56_SHARED");
static const struct reg_default cs35l56_reg_defaults[] = {
- /* no defaults for OTP_MEM - first read populates cache */
-
{ CS35L56_ASP1_ENABLES1, 0x00000000 },
{ CS35L56_ASP1_CONTROL1, 0x00000028 },
{ CS35L56_ASP1_CONTROL2, 0x18180200 },
@@ -138,8 +136,6 @@ static const struct reg_default cs35l56_reg_defaults[] = {
};
static const struct reg_default cs35l63_reg_defaults[] = {
- /* no defaults for OTP_MEM - first read populates cache */
-
{ CS35L56_ASP1_ENABLES1, 0x00000000 },
{ CS35L56_ASP1_CONTROL1, 0x00000028 },
{ CS35L56_ASP1_CONTROL2, 0x18180200 },
@@ -282,6 +278,9 @@ static bool cs35l56_common_volatile_reg(unsigned int reg)
case CS35L56_GLOBAL_ENABLES: /* owned by firmware */
case CS35L56_BLOCK_ENABLES: /* owned by firmware */
case CS35L56_BLOCK_ENABLES2: /* owned by firmware */
+ case CS35L56_OTP_MEM_53:
+ case CS35L56_OTP_MEM_54:
+ case CS35L56_OTP_MEM_55:
case CS35L56_SYNC_GPIO1_CFG ... CS35L56_ASP2_DIO_GPIO13_CFG:
case CS35L56_UPDATE_REGS:
case CS35L56_REFCLK_INPUT: /* owned by firmware */
diff --git a/sound/soc/codecs/es8389.c b/sound/soc/codecs/es8389.c
index 8d418cae371a..449d9574b03a 100644
--- a/sound/soc/codecs/es8389.c
+++ b/sound/soc/codecs/es8389.c
@@ -892,7 +892,7 @@ static int es8389_probe(struct snd_soc_component *component)
return ret;
}
- es8389->mclk = devm_clk_get(component->dev, "mclk");
+ es8389->mclk = devm_clk_get_optional(component->dev, "mclk");
if (IS_ERR(es8389->mclk))
return dev_err_probe(component->dev, PTR_ERR(es8389->mclk),
"ES8389 is unable to get mclk\n");
diff --git a/sound/soc/codecs/tas2764.c b/sound/soc/codecs/tas2764.c
index 423b7073b302..6aab6d2b7419 100644
--- a/sound/soc/codecs/tas2764.c
+++ b/sound/soc/codecs/tas2764.c
@@ -904,6 +904,7 @@ static bool tas2764_volatile_register(struct device *dev, unsigned int reg)
{
switch (reg) {
case TAS2764_SW_RST:
+ case TAS2764_TEMP:
case TAS2764_INT_LTCH0 ... TAS2764_INT_LTCH4:
case TAS2764_INT_CLK_CFG:
return true;
diff --git a/sound/soc/codecs/tas2770.c b/sound/soc/codecs/tas2770.c
index d4d7d056141b..50501bcbe916 100644
--- a/sound/soc/codecs/tas2770.c
+++ b/sound/soc/codecs/tas2770.c
@@ -624,7 +624,7 @@ static int tas2770_read_die_temp(struct tas2770_priv *tas2770, long *result)
/*
* As per datasheet: divide register by 16 and subtract 93 to get
* degrees Celsius. hwmon requires millidegrees. Let's avoid rounding
- * errors by subtracting 93 * 16 then multiplying by 1000 / 16.
+ * errors by subtracting 93 * 16 and scaling before dividing.
*
* NOTE: The ADC registers are initialised to 0 on reset. This means
* that the temperature will read -93 *C until the chip is brought out
@@ -633,7 +633,7 @@ static int tas2770_read_die_temp(struct tas2770_priv *tas2770, long *result)
* value read back from its registers will be the last value sampled
* before entering software shutdown.
*/
- *result = (reading - (93 * 16)) * (1000 / 16);
+ *result = (reading - (93 * 16)) * 1000 / 16;
return 0;
}
diff --git a/sound/soc/codecs/wcd937x.c b/sound/soc/codecs/wcd937x.c
index 10a2d598caa7..72a53f95d688 100644
--- a/sound/soc/codecs/wcd937x.c
+++ b/sound/soc/codecs/wcd937x.c
@@ -547,6 +547,9 @@ static int wcd937x_codec_aux_dac_event(struct snd_soc_dapm_widget *w,
WCD937X_DIGITAL_CDC_ANA_CLK_CTL,
BIT(2), BIT(2));
snd_soc_component_update_bits(component,
+ WCD937X_AUX_AUXPA,
+ BIT(4), BIT(4));
+ snd_soc_component_update_bits(component,
WCD937X_DIGITAL_CDC_DIG_CLK_CTL,
BIT(2), BIT(2));
snd_soc_component_update_bits(component,
@@ -562,6 +565,9 @@ static int wcd937x_codec_aux_dac_event(struct snd_soc_dapm_widget *w,
snd_soc_component_update_bits(component,
WCD937X_DIGITAL_CDC_ANA_CLK_CTL,
BIT(2), 0x00);
+ snd_soc_component_update_bits(component,
+ WCD937X_AUX_AUXPA,
+ BIT(4), 0x00);
break;
}
@@ -730,10 +736,23 @@ static int wcd937x_codec_enable_aux_pa(struct snd_soc_dapm_widget *w,
snd_soc_component_update_bits(component,
WCD937X_ANA_RX_SUPPLIES,
BIT(1), BIT(1));
+ /* Enable AUX PA related RX supplies */
+ snd_soc_component_update_bits(component,
+ WCD937X_ANA_RX_SUPPLIES,
+ BIT(6), BIT(6));
+ snd_soc_component_update_bits(component,
+ WCD937X_ANA_RX_SUPPLIES,
+ BIT(7), BIT(7));
enable_irq(wcd937x->aux_pdm_wd_int);
break;
case SND_SOC_DAPM_PRE_PMD:
disable_irq_nosync(wcd937x->aux_pdm_wd_int);
+ snd_soc_component_update_bits(component,
+ WCD937X_ANA_RX_SUPPLIES,
+ BIT(6), 0x00);
+ snd_soc_component_update_bits(component,
+ WCD937X_ANA_RX_SUPPLIES,
+ BIT(7), 0x00);
break;
case SND_SOC_DAPM_POST_PMD:
usleep_range(2000, 2010);
@@ -2051,7 +2070,12 @@ static const struct snd_kcontrol_new wcd937x_snd_controls[] = {
wcd937x_get_swr_port, wcd937x_set_swr_port),
SOC_SINGLE_EXT("LO Switch", WCD937X_LO, 0, 1, 0,
wcd937x_get_swr_port, wcd937x_set_swr_port),
-
+ SOC_SINGLE_EXT("CLSH PA Switch", WCD937X_CLSH, 0, 1, 0,
+ wcd937x_get_swr_port, wcd937x_set_swr_port),
+ SOC_SINGLE_EXT("DSD_L Switch", WCD937X_DSD_L, 0, 1, 0,
+ wcd937x_get_swr_port, wcd937x_set_swr_port),
+ SOC_SINGLE_EXT("DSD_R Switch", WCD937X_DSD_R, 0, 1, 0,
+ wcd937x_get_swr_port, wcd937x_set_swr_port),
SOC_SINGLE_EXT("ADC1 Switch", WCD937X_ADC1, 1, 1, 0,
wcd937x_get_swr_port, wcd937x_set_swr_port),
SOC_SINGLE_EXT("ADC2 Switch", WCD937X_ADC2, 1, 1, 0,
diff --git a/sound/soc/intel/boards/bytcr_wm5102.c b/sound/soc/intel/boards/bytcr_wm5102.c
index 4879f79aef29..4aa0cf49b033 100644
--- a/sound/soc/intel/boards/bytcr_wm5102.c
+++ b/sound/soc/intel/boards/bytcr_wm5102.c
@@ -170,6 +170,7 @@ static int platform_clock_control(struct snd_soc_dapm_widget *w,
ret = byt_wm5102_prepare_and_enable_pll1(codec_dai, 48000);
if (ret) {
dev_err(card->dev, "Error setting codec sysclk: %d\n", ret);
+ clk_disable_unprepare(priv->mclk);
return ret;
}
} else {
diff --git a/sound/soc/sof/intel/hda.c b/sound/soc/sof/intel/hda.c
index b3d61d973ce4..8662b422eb80 100644
--- a/sound/soc/sof/intel/hda.c
+++ b/sound/soc/sof/intel/hda.c
@@ -1412,7 +1412,8 @@ static struct snd_soc_acpi_mach *hda_sdw_machine_select(struct snd_sof_dev *sdev
link_mask |= BIT(peripherals->array[i]->bus->link_id);
link_num = hweight32(link_mask);
- links = devm_kcalloc(sdev->dev, link_num, sizeof(*links), GFP_KERNEL);
+ /* An empty adr_link is needed to terminate the adr_link loop */
+ links = devm_kcalloc(sdev->dev, link_num + 1, sizeof(*links), GFP_KERNEL);
if (!links)
return NULL;
diff --git a/sound/soc/spacemit/k1_i2s.c b/sound/soc/spacemit/k1_i2s.c
index 1cb99f1abc7c..43481f387c44 100644
--- a/sound/soc/spacemit/k1_i2s.c
+++ b/sound/soc/spacemit/k1_i2s.c
@@ -93,8 +93,8 @@ static void spacemit_i2s_init(struct spacemit_i2s_dev *i2s)
u32 sscr_val, sspsp_val, ssfcr_val, ssrwt_val;
sscr_val = SSCR_TRAIL | SSCR_FRF_PSP;
- ssfcr_val = FIELD_PREP(SSFCR_FIELD_TFT, 5) |
- FIELD_PREP(SSFCR_FIELD_RFT, 5) |
+ ssfcr_val = FIELD_PREP(SSFCR_FIELD_TFT, 0xF) |
+ FIELD_PREP(SSFCR_FIELD_RFT, 0xF) |
SSFCR_RSRE | SSFCR_TSRE;
ssrwt_val = SSRWT_RWOT;
sspsp_val = SSPSP_SFRMP;
@@ -106,6 +106,37 @@ static void spacemit_i2s_init(struct spacemit_i2s_dev *i2s)
writel(0, i2s->base + SSINTEN);
}
+static int spacemit_i2s_startup(struct snd_pcm_substream *substream,
+ struct snd_soc_dai *dai)
+{
+ struct spacemit_i2s_dev *i2s = snd_soc_dai_get_drvdata(dai);
+
+ switch (i2s->dai_fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
+ case SND_SOC_DAIFMT_I2S:
+ snd_pcm_hw_constraint_minmax(substream->runtime,
+ SNDRV_PCM_HW_PARAM_CHANNELS,
+ 2, 2);
+ snd_pcm_hw_constraint_mask64(substream->runtime,
+ SNDRV_PCM_HW_PARAM_FORMAT,
+ SNDRV_PCM_FMTBIT_S16_LE);
+ break;
+ case SND_SOC_DAIFMT_DSP_A:
+ case SND_SOC_DAIFMT_DSP_B:
+ snd_pcm_hw_constraint_minmax(substream->runtime,
+ SNDRV_PCM_HW_PARAM_CHANNELS,
+ 1, 1);
+ snd_pcm_hw_constraint_mask64(substream->runtime,
+ SNDRV_PCM_HW_PARAM_FORMAT,
+ SNDRV_PCM_FMTBIT_S32_LE);
+ break;
+ default:
+ dev_dbg(i2s->dev, "unexpected format type");
+ return -EINVAL;
+ }
+
+ return 0;
+}
+
static int spacemit_i2s_hw_params(struct snd_pcm_substream *substream,
struct snd_pcm_hw_params *params,
struct snd_soc_dai *dai)
@@ -157,22 +188,9 @@ static int spacemit_i2s_hw_params(struct snd_pcm_substream *substream,
dma_data->maxburst = 32;
dma_data->addr_width = DMA_SLAVE_BUSWIDTH_4_BYTES;
}
-
- snd_pcm_hw_constraint_minmax(substream->runtime,
- SNDRV_PCM_HW_PARAM_CHANNELS,
- 1, 2);
- snd_pcm_hw_constraint_mask64(substream->runtime,
- SNDRV_PCM_HW_PARAM_FORMAT,
- SNDRV_PCM_FMTBIT_S16_LE);
break;
case SND_SOC_DAIFMT_DSP_A:
case SND_SOC_DAIFMT_DSP_B:
- snd_pcm_hw_constraint_minmax(substream->runtime,
- SNDRV_PCM_HW_PARAM_CHANNELS,
- 1, 1);
- snd_pcm_hw_constraint_mask64(substream->runtime,
- SNDRV_PCM_HW_PARAM_FORMAT,
- SNDRV_PCM_FMTBIT_S32_LE);
break;
default:
dev_dbg(i2s->dev, "unexpected format type");
@@ -303,6 +321,7 @@ static int spacemit_i2s_dai_remove(struct snd_soc_dai *dai)
static const struct snd_soc_dai_ops spacemit_i2s_dai_ops = {
.probe = spacemit_i2s_dai_probe,
.remove = spacemit_i2s_dai_remove,
+ .startup = spacemit_i2s_startup,
.hw_params = spacemit_i2s_hw_params,
.set_sysclk = spacemit_i2s_set_sysclk,
.set_fmt = spacemit_i2s_set_fmt,
diff --git a/sound/soc/tegra/Makefile b/sound/soc/tegra/Makefile
index 3f396c87802e..1c18ef6971c0 100644
--- a/sound/soc/tegra/Makefile
+++ b/sound/soc/tegra/Makefile
@@ -1,7 +1,6 @@
# SPDX-License-Identifier: GPL-2.0
# Tegra platform Support
snd-soc-tegra-pcm-y := tegra_pcm.o
-snd-soc-tegra-utils-y += tegra_asoc_utils.o
snd-soc-tegra20-ac97-y := tegra20_ac97.o
snd-soc-tegra20-das-y := tegra20_das.o
snd-soc-tegra20-i2s-y := tegra20_i2s.o