summaryrefslogtreecommitdiff
path: root/sound/soc
diff options
context:
space:
mode:
Diffstat (limited to 'sound/soc')
-rw-r--r--sound/soc/amd/acp/acp-mach-common.c18
-rw-r--r--sound/soc/amd/acp/amd-acp63-acpi-match.c413
-rw-r--r--sound/soc/amd/acp3x-rt5682-max9836.c9
-rw-r--r--sound/soc/amd/yc/acp6x-mach.c14
-rw-r--r--sound/soc/codecs/cs35l56-shared.c16
-rw-r--r--sound/soc/codecs/cs35l56.c12
-rw-r--r--sound/soc/codecs/cs42l43-jack.c1
-rw-r--r--sound/soc/codecs/rt1011.c2
-rw-r--r--sound/soc/codecs/rt1320-sdw.c5
-rw-r--r--sound/soc/codecs/tas2781-fmwlib.c94
-rw-r--r--sound/soc/fsl/fsl_easrc.c14
-rw-r--r--sound/soc/generic/simple-card-utils.c12
-rw-r--r--sound/soc/intel/boards/sof_sdw.c8
-rw-r--r--sound/soc/qcom/qdsp6/q6apm-dai.c1
-rw-r--r--sound/soc/qcom/qdsp6/q6apm-lpass-dais.c1
-rw-r--r--sound/soc/qcom/qdsp6/q6apm.c1
-rw-r--r--sound/soc/sdca/sdca_functions.c5
-rw-r--r--sound/soc/sdca/sdca_interrupts.c4
-rw-r--r--sound/soc/soc-core.c11
-rw-r--r--sound/soc/tegra/tegra_audio_graph_card.c11
20 files changed, 626 insertions, 26 deletions
diff --git a/sound/soc/amd/acp/acp-mach-common.c b/sound/soc/amd/acp/acp-mach-common.c
index 4d99472c75ba..09f6c9a2c041 100644
--- a/sound/soc/amd/acp/acp-mach-common.c
+++ b/sound/soc/amd/acp/acp-mach-common.c
@@ -127,8 +127,13 @@ static int acp_card_rt5682_init(struct snd_soc_pcm_runtime *rtd)
if (drvdata->hs_codec_id != RT5682)
return -EINVAL;
- drvdata->wclk = clk_get(component->dev, "rt5682-dai-wclk");
- drvdata->bclk = clk_get(component->dev, "rt5682-dai-bclk");
+ drvdata->wclk = devm_clk_get(component->dev, "rt5682-dai-wclk");
+ if (IS_ERR(drvdata->wclk))
+ return PTR_ERR(drvdata->wclk);
+
+ drvdata->bclk = devm_clk_get(component->dev, "rt5682-dai-bclk");
+ if (IS_ERR(drvdata->bclk))
+ return PTR_ERR(drvdata->bclk);
ret = snd_soc_dapm_new_controls(dapm, rt5682_widgets,
ARRAY_SIZE(rt5682_widgets));
@@ -370,8 +375,13 @@ static int acp_card_rt5682s_init(struct snd_soc_pcm_runtime *rtd)
return -EINVAL;
if (!drvdata->soc_mclk) {
- drvdata->wclk = clk_get(component->dev, "rt5682-dai-wclk");
- drvdata->bclk = clk_get(component->dev, "rt5682-dai-bclk");
+ drvdata->wclk = devm_clk_get(component->dev, "rt5682-dai-wclk");
+ if (IS_ERR(drvdata->wclk))
+ return PTR_ERR(drvdata->wclk);
+
+ drvdata->bclk = devm_clk_get(component->dev, "rt5682-dai-bclk");
+ if (IS_ERR(drvdata->bclk))
+ return PTR_ERR(drvdata->bclk);
}
ret = snd_soc_dapm_new_controls(dapm, rt5682s_widgets,
diff --git a/sound/soc/amd/acp/amd-acp63-acpi-match.c b/sound/soc/amd/acp/amd-acp63-acpi-match.c
index 9b6a49c051cd..1dbbaba3c75b 100644
--- a/sound/soc/amd/acp/amd-acp63-acpi-match.c
+++ b/sound/soc/amd/acp/amd-acp63-acpi-match.c
@@ -30,6 +30,20 @@ static const struct snd_soc_acpi_endpoint spk_r_endpoint = {
.group_id = 1
};
+static const struct snd_soc_acpi_endpoint spk_2_endpoint = {
+ .num = 0,
+ .aggregated = 1,
+ .group_position = 2,
+ .group_id = 1
+};
+
+static const struct snd_soc_acpi_endpoint spk_3_endpoint = {
+ .num = 0,
+ .aggregated = 1,
+ .group_position = 3,
+ .group_id = 1
+};
+
static const struct snd_soc_acpi_adr_device rt711_rt1316_group_adr[] = {
{
.adr = 0x000030025D071101ull,
@@ -103,6 +117,345 @@ static const struct snd_soc_acpi_adr_device rt722_0_single_adr[] = {
}
};
+static const struct snd_soc_acpi_endpoint cs42l43_endpoints[] = {
+ { /* Jack Playback Endpoint */
+ .num = 0,
+ .aggregated = 0,
+ .group_position = 0,
+ .group_id = 0,
+ },
+ { /* DMIC Capture Endpoint */
+ .num = 1,
+ .aggregated = 0,
+ .group_position = 0,
+ .group_id = 0,
+ },
+ { /* Jack Capture Endpoint */
+ .num = 2,
+ .aggregated = 0,
+ .group_position = 0,
+ .group_id = 0,
+ },
+ { /* Speaker Playback Endpoint */
+ .num = 3,
+ .aggregated = 0,
+ .group_position = 0,
+ .group_id = 0,
+ },
+};
+
+static const struct snd_soc_acpi_adr_device cs35l56x4_l1u3210_adr[] = {
+ {
+ .adr = 0x00013301FA355601ull,
+ .num_endpoints = 1,
+ .endpoints = &spk_l_endpoint,
+ .name_prefix = "AMP1"
+ },
+ {
+ .adr = 0x00013201FA355601ull,
+ .num_endpoints = 1,
+ .endpoints = &spk_r_endpoint,
+ .name_prefix = "AMP2"
+ },
+ {
+ .adr = 0x00013101FA355601ull,
+ .num_endpoints = 1,
+ .endpoints = &spk_2_endpoint,
+ .name_prefix = "AMP3"
+ },
+ {
+ .adr = 0x00013001FA355601ull,
+ .num_endpoints = 1,
+ .endpoints = &spk_3_endpoint,
+ .name_prefix = "AMP4"
+ },
+};
+
+static const struct snd_soc_acpi_adr_device cs35l63x2_l0u01_adr[] = {
+ {
+ .adr = 0x00003001FA356301ull,
+ .num_endpoints = 1,
+ .endpoints = &spk_l_endpoint,
+ .name_prefix = "AMP1"
+ },
+ {
+ .adr = 0x00003101FA356301ull,
+ .num_endpoints = 1,
+ .endpoints = &spk_r_endpoint,
+ .name_prefix = "AMP2"
+ },
+};
+
+static const struct snd_soc_acpi_adr_device cs35l63x2_l1u01_adr[] = {
+ {
+ .adr = 0x00013001FA356301ull,
+ .num_endpoints = 1,
+ .endpoints = &spk_l_endpoint,
+ .name_prefix = "AMP1"
+ },
+ {
+ .adr = 0x00013101FA356301ull,
+ .num_endpoints = 1,
+ .endpoints = &spk_r_endpoint,
+ .name_prefix = "AMP2"
+ },
+};
+
+static const struct snd_soc_acpi_adr_device cs35l63x2_l1u13_adr[] = {
+ {
+ .adr = 0x00013101FA356301ull,
+ .num_endpoints = 1,
+ .endpoints = &spk_l_endpoint,
+ .name_prefix = "AMP1"
+ },
+ {
+ .adr = 0x00013301FA356301ull,
+ .num_endpoints = 1,
+ .endpoints = &spk_r_endpoint,
+ .name_prefix = "AMP2"
+ },
+};
+
+static const struct snd_soc_acpi_adr_device cs35l63x4_l0u0246_adr[] = {
+ {
+ .adr = 0x00003001FA356301ull,
+ .num_endpoints = 1,
+ .endpoints = &spk_l_endpoint,
+ .name_prefix = "AMP1"
+ },
+ {
+ .adr = 0x00003201FA356301ull,
+ .num_endpoints = 1,
+ .endpoints = &spk_r_endpoint,
+ .name_prefix = "AMP2"
+ },
+ {
+ .adr = 0x00003401FA356301ull,
+ .num_endpoints = 1,
+ .endpoints = &spk_2_endpoint,
+ .name_prefix = "AMP3"
+ },
+ {
+ .adr = 0x00003601FA356301ull,
+ .num_endpoints = 1,
+ .endpoints = &spk_3_endpoint,
+ .name_prefix = "AMP4"
+ },
+};
+
+static const struct snd_soc_acpi_adr_device cs42l43_l0u0_adr[] = {
+ {
+ .adr = 0x00003001FA424301ull,
+ .num_endpoints = ARRAY_SIZE(cs42l43_endpoints),
+ .endpoints = cs42l43_endpoints,
+ .name_prefix = "cs42l43"
+ }
+};
+
+static const struct snd_soc_acpi_adr_device cs42l43_l0u1_adr[] = {
+ {
+ .adr = 0x00003101FA424301ull,
+ .num_endpoints = ARRAY_SIZE(cs42l43_endpoints),
+ .endpoints = cs42l43_endpoints,
+ .name_prefix = "cs42l43"
+ }
+};
+
+static const struct snd_soc_acpi_adr_device cs42l43b_l0u1_adr[] = {
+ {
+ .adr = 0x00003101FA2A3B01ull,
+ .num_endpoints = ARRAY_SIZE(cs42l43_endpoints),
+ .endpoints = cs42l43_endpoints,
+ .name_prefix = "cs42l43"
+ }
+};
+
+static const struct snd_soc_acpi_adr_device cs42l43_l1u0_cs35l56x4_l1u0123_adr[] = {
+ {
+ .adr = 0x00013001FA424301ull,
+ .num_endpoints = ARRAY_SIZE(cs42l43_endpoints),
+ .endpoints = cs42l43_endpoints,
+ .name_prefix = "cs42l43"
+ },
+ {
+ .adr = 0x00013001FA355601ull,
+ .num_endpoints = 1,
+ .endpoints = &spk_l_endpoint,
+ .name_prefix = "AMP1"
+ },
+ {
+ .adr = 0x00013101FA355601ull,
+ .num_endpoints = 1,
+ .endpoints = &spk_r_endpoint,
+ .name_prefix = "AMP2"
+ },
+ {
+ .adr = 0x00013201FA355601ull,
+ .num_endpoints = 1,
+ .endpoints = &spk_2_endpoint,
+ .name_prefix = "AMP3"
+ },
+ {
+ .adr = 0x00013301FA355601ull,
+ .num_endpoints = 1,
+ .endpoints = &spk_3_endpoint,
+ .name_prefix = "AMP4"
+ },
+};
+
+static const struct snd_soc_acpi_adr_device cs42l45_l0u0_adr[] = {
+ {
+ .adr = 0x00003001FA424501ull,
+ /* Re-use endpoints, but cs42l45 has no speaker */
+ .num_endpoints = ARRAY_SIZE(cs42l43_endpoints) - 1,
+ .endpoints = cs42l43_endpoints,
+ .name_prefix = "cs42l45"
+ }
+};
+
+static const struct snd_soc_acpi_adr_device cs42l45_l1u0_adr[] = {
+ {
+ .adr = 0x00013001FA424501ull,
+ /* Re-use endpoints, but cs42l45 has no speaker */
+ .num_endpoints = ARRAY_SIZE(cs42l43_endpoints) - 1,
+ .endpoints = cs42l43_endpoints,
+ .name_prefix = "cs42l45"
+ }
+};
+
+static const struct snd_soc_acpi_link_adr acp63_cs35l56x4_l1u3210[] = {
+ {
+ .mask = BIT(1),
+ .num_adr = ARRAY_SIZE(cs35l56x4_l1u3210_adr),
+ .adr_d = cs35l56x4_l1u3210_adr,
+ },
+ {}
+};
+
+static const struct snd_soc_acpi_link_adr acp63_cs35l63x4_l0u0246[] = {
+ {
+ .mask = BIT(0),
+ .num_adr = ARRAY_SIZE(cs35l63x4_l0u0246_adr),
+ .adr_d = cs35l63x4_l0u0246_adr,
+ },
+ {}
+};
+
+static const struct snd_soc_acpi_link_adr acp63_cs42l43_l0u1[] = {
+ {
+ .mask = BIT(0),
+ .num_adr = ARRAY_SIZE(cs42l43_l0u1_adr),
+ .adr_d = cs42l43_l0u1_adr,
+ },
+ {}
+};
+
+static const struct snd_soc_acpi_link_adr acp63_cs42l43b_l0u1[] = {
+ {
+ .mask = BIT(0),
+ .num_adr = ARRAY_SIZE(cs42l43b_l0u1_adr),
+ .adr_d = cs42l43b_l0u1_adr,
+ },
+ {}
+};
+
+static const struct snd_soc_acpi_link_adr acp63_cs42l43_l0u0_cs35l56x4_l1u3210[] = {
+ {
+ .mask = BIT(0),
+ .num_adr = ARRAY_SIZE(cs42l43_l0u0_adr),
+ .adr_d = cs42l43_l0u0_adr,
+ },
+ {
+ .mask = BIT(1),
+ .num_adr = ARRAY_SIZE(cs35l56x4_l1u3210_adr),
+ .adr_d = cs35l56x4_l1u3210_adr,
+ },
+ {}
+};
+
+static const struct snd_soc_acpi_link_adr acp63_cs42l43_l1u0_cs35l56x4_l1u0123[] = {
+ {
+ .mask = BIT(1),
+ .num_adr = ARRAY_SIZE(cs42l43_l1u0_cs35l56x4_l1u0123_adr),
+ .adr_d = cs42l43_l1u0_cs35l56x4_l1u0123_adr,
+ },
+ {}
+};
+
+static const struct snd_soc_acpi_link_adr acp63_cs42l45_l0u0[] = {
+ {
+ .mask = BIT(0),
+ .num_adr = ARRAY_SIZE(cs42l45_l0u0_adr),
+ .adr_d = cs42l45_l0u0_adr,
+ },
+ {}
+};
+
+static const struct snd_soc_acpi_link_adr acp63_cs42l45_l0u0_cs35l63x2_l1u01[] = {
+ {
+ .mask = BIT(0),
+ .num_adr = ARRAY_SIZE(cs42l45_l0u0_adr),
+ .adr_d = cs42l45_l0u0_adr,
+ },
+ {
+ .mask = BIT(1),
+ .num_adr = ARRAY_SIZE(cs35l63x2_l1u01_adr),
+ .adr_d = cs35l63x2_l1u01_adr,
+ },
+ {}
+};
+
+static const struct snd_soc_acpi_link_adr acp63_cs42l45_l0u0_cs35l63x2_l1u13[] = {
+ {
+ .mask = BIT(0),
+ .num_adr = ARRAY_SIZE(cs42l45_l0u0_adr),
+ .adr_d = cs42l45_l0u0_adr,
+ },
+ {
+ .mask = BIT(1),
+ .num_adr = ARRAY_SIZE(cs35l63x2_l1u13_adr),
+ .adr_d = cs35l63x2_l1u13_adr,
+ },
+ {}
+};
+
+static const struct snd_soc_acpi_link_adr acp63_cs42l45_l1u0[] = {
+ {
+ .mask = BIT(1),
+ .num_adr = ARRAY_SIZE(cs42l45_l1u0_adr),
+ .adr_d = cs42l45_l1u0_adr,
+ },
+ {}
+};
+
+static const struct snd_soc_acpi_link_adr acp63_cs42l45_l1u0_cs35l63x2_l0u01[] = {
+ {
+ .mask = BIT(1),
+ .num_adr = ARRAY_SIZE(cs42l45_l1u0_adr),
+ .adr_d = cs42l45_l1u0_adr,
+ },
+ {
+ .mask = BIT(0),
+ .num_adr = ARRAY_SIZE(cs35l63x2_l0u01_adr),
+ .adr_d = cs35l63x2_l0u01_adr,
+ },
+ {}
+};
+
+static const struct snd_soc_acpi_link_adr acp63_cs42l45_l1u0_cs35l63x4_l0u0246[] = {
+ {
+ .mask = BIT(1),
+ .num_adr = ARRAY_SIZE(cs42l45_l1u0_adr),
+ .adr_d = cs42l45_l1u0_adr,
+ },
+ {
+ .mask = BIT(0),
+ .num_adr = ARRAY_SIZE(cs35l63x4_l0u0246_adr),
+ .adr_d = cs35l63x4_l0u0246_adr,
+ },
+ {}
+};
+
static const struct snd_soc_acpi_link_adr acp63_rt722_only[] = {
{
.mask = BIT(0),
@@ -135,6 +488,66 @@ struct snd_soc_acpi_mach snd_soc_acpi_amd_acp63_sdw_machines[] = {
.links = acp63_4_in_1_sdca,
.drv_name = "amd_sdw",
},
+ {
+ .link_mask = BIT(0) | BIT(1),
+ .links = acp63_cs42l43_l0u0_cs35l56x4_l1u3210,
+ .drv_name = "amd_sdw",
+ },
+ {
+ .link_mask = BIT(0) | BIT(1),
+ .links = acp63_cs42l45_l1u0_cs35l63x4_l0u0246,
+ .drv_name = "amd_sdw",
+ },
+ {
+ .link_mask = BIT(0) | BIT(1),
+ .links = acp63_cs42l45_l0u0_cs35l63x2_l1u01,
+ .drv_name = "amd_sdw",
+ },
+ {
+ .link_mask = BIT(0) | BIT(1),
+ .links = acp63_cs42l45_l0u0_cs35l63x2_l1u13,
+ .drv_name = "amd_sdw",
+ },
+ {
+ .link_mask = BIT(0) | BIT(1),
+ .links = acp63_cs42l45_l1u0_cs35l63x2_l0u01,
+ .drv_name = "amd_sdw",
+ },
+ {
+ .link_mask = BIT(1),
+ .links = acp63_cs42l43_l1u0_cs35l56x4_l1u0123,
+ .drv_name = "amd_sdw",
+ },
+ {
+ .link_mask = BIT(1),
+ .links = acp63_cs35l56x4_l1u3210,
+ .drv_name = "amd_sdw",
+ },
+ {
+ .link_mask = BIT(0),
+ .links = acp63_cs35l63x4_l0u0246,
+ .drv_name = "amd_sdw",
+ },
+ {
+ .link_mask = BIT(0),
+ .links = acp63_cs42l43_l0u1,
+ .drv_name = "amd_sdw",
+ },
+ {
+ .link_mask = BIT(0),
+ .links = acp63_cs42l43b_l0u1,
+ .drv_name = "amd_sdw",
+ },
+ {
+ .link_mask = BIT(0),
+ .links = acp63_cs42l45_l0u0,
+ .drv_name = "amd_sdw",
+ },
+ {
+ .link_mask = BIT(1),
+ .links = acp63_cs42l45_l1u0,
+ .drv_name = "amd_sdw",
+ },
{},
};
EXPORT_SYMBOL(snd_soc_acpi_amd_acp63_sdw_machines);
diff --git a/sound/soc/amd/acp3x-rt5682-max9836.c b/sound/soc/amd/acp3x-rt5682-max9836.c
index 4ca1978020a9..d1eb6f12a183 100644
--- a/sound/soc/amd/acp3x-rt5682-max9836.c
+++ b/sound/soc/amd/acp3x-rt5682-max9836.c
@@ -94,8 +94,13 @@ static int acp3x_5682_init(struct snd_soc_pcm_runtime *rtd)
return ret;
}
- rt5682_dai_wclk = clk_get(component->dev, "rt5682-dai-wclk");
- rt5682_dai_bclk = clk_get(component->dev, "rt5682-dai-bclk");
+ rt5682_dai_wclk = devm_clk_get(component->dev, "rt5682-dai-wclk");
+ if (IS_ERR(rt5682_dai_wclk))
+ return PTR_ERR(rt5682_dai_wclk);
+
+ rt5682_dai_bclk = devm_clk_get(component->dev, "rt5682-dai-bclk");
+ if (IS_ERR(rt5682_dai_bclk))
+ return PTR_ERR(rt5682_dai_bclk);
ret = snd_soc_card_jack_new_pins(card, "Headset Jack",
SND_JACK_HEADSET |
diff --git a/sound/soc/amd/yc/acp6x-mach.c b/sound/soc/amd/yc/acp6x-mach.c
index f1a63475100d..1324543b42d7 100644
--- a/sound/soc/amd/yc/acp6x-mach.c
+++ b/sound/soc/amd/yc/acp6x-mach.c
@@ -703,6 +703,20 @@ static const struct dmi_system_id yc_acp_quirk_table[] = {
DMI_MATCH(DMI_PRODUCT_NAME, "Vivobook_ASUSLaptop M6501RR_M6501RR"),
}
},
+ {
+ .driver_data = &acp6x_card,
+ .matches = {
+ DMI_MATCH(DMI_BOARD_VENDOR, "ASUSTeK COMPUTER INC."),
+ DMI_MATCH(DMI_PRODUCT_NAME, "ASUS EXPERTBOOK BM1503CDA"),
+ }
+ },
+ {
+ .driver_data = &acp6x_card,
+ .matches = {
+ DMI_MATCH(DMI_BOARD_VENDOR, "ASUSTeK COMPUTER INC."),
+ DMI_MATCH(DMI_BOARD_NAME, "PM1503CDA"),
+ }
+ },
{}
};
diff --git a/sound/soc/codecs/cs35l56-shared.c b/sound/soc/codecs/cs35l56-shared.c
index 4707f28bfca2..af87ebae98cb 100644
--- a/sound/soc/codecs/cs35l56-shared.c
+++ b/sound/soc/codecs/cs35l56-shared.c
@@ -26,7 +26,7 @@
#include "cs35l56.h"
-static const struct reg_sequence cs35l56_patch[] = {
+static const struct reg_sequence cs35l56_asp_patch[] = {
/*
* Firmware can change these to non-defaults to satisfy SDCA.
* Ensure that they are at known defaults.
@@ -43,6 +43,20 @@ static const struct reg_sequence cs35l56_patch[] = {
{ CS35L56_ASP1TX2_INPUT, 0x00000000 },
{ CS35L56_ASP1TX3_INPUT, 0x00000000 },
{ CS35L56_ASP1TX4_INPUT, 0x00000000 },
+};
+
+int cs35l56_set_asp_patch(struct cs35l56_base *cs35l56_base)
+{
+ return regmap_register_patch(cs35l56_base->regmap, cs35l56_asp_patch,
+ ARRAY_SIZE(cs35l56_asp_patch));
+}
+EXPORT_SYMBOL_NS_GPL(cs35l56_set_asp_patch, "SND_SOC_CS35L56_SHARED");
+
+static const struct reg_sequence cs35l56_patch[] = {
+ /*
+ * Firmware can change these to non-defaults to satisfy SDCA.
+ * Ensure that they are at known defaults.
+ */
{ CS35L56_SWIRE_DP3_CH1_INPUT, 0x00000018 },
{ CS35L56_SWIRE_DP3_CH2_INPUT, 0x00000019 },
{ CS35L56_SWIRE_DP3_CH3_INPUT, 0x00000029 },
diff --git a/sound/soc/codecs/cs35l56.c b/sound/soc/codecs/cs35l56.c
index 2ff8b172b76e..37909a319f88 100644
--- a/sound/soc/codecs/cs35l56.c
+++ b/sound/soc/codecs/cs35l56.c
@@ -348,6 +348,13 @@ static int cs35l56_dsp_event(struct snd_soc_dapm_widget *w,
return wm_adsp_event(w, kcontrol, event);
}
+static int cs35l56_asp_dai_probe(struct snd_soc_dai *codec_dai)
+{
+ struct cs35l56_private *cs35l56 = snd_soc_component_get_drvdata(codec_dai->component);
+
+ return cs35l56_set_asp_patch(&cs35l56->base);
+}
+
static int cs35l56_asp_dai_set_fmt(struct snd_soc_dai *codec_dai, unsigned int fmt)
{
struct cs35l56_private *cs35l56 = snd_soc_component_get_drvdata(codec_dai->component);
@@ -552,6 +559,7 @@ static int cs35l56_asp_dai_set_sysclk(struct snd_soc_dai *dai,
}
static const struct snd_soc_dai_ops cs35l56_ops = {
+ .probe = cs35l56_asp_dai_probe,
.set_fmt = cs35l56_asp_dai_set_fmt,
.set_tdm_slot = cs35l56_asp_dai_set_tdm_slot,
.hw_params = cs35l56_asp_dai_hw_params,
@@ -1617,9 +1625,9 @@ static int cs35l56_process_xu_onchip_speaker_id(struct cs35l56_private *cs35l56,
if (num_pulls < 0)
return num_pulls;
- if (num_pulls != num_gpios) {
+ if (num_pulls && (num_pulls != num_gpios)) {
dev_warn(cs35l56->base.dev, "%s count(%d) != %s count(%d)\n",
- pull_name, num_pulls, gpio_name, num_gpios);
+ pull_name, num_pulls, gpio_name, num_gpios);
}
ret = cs35l56_check_and_save_onchip_spkid_gpios(&cs35l56->base,
diff --git a/sound/soc/codecs/cs42l43-jack.c b/sound/soc/codecs/cs42l43-jack.c
index b83bc4de1301..3e04e6897b14 100644
--- a/sound/soc/codecs/cs42l43-jack.c
+++ b/sound/soc/codecs/cs42l43-jack.c
@@ -699,6 +699,7 @@ static int cs42l43_run_type_detect(struct cs42l43_codec *priv)
switch (type & CS42L43_HSDET_TYPE_STS_MASK) {
case 0x0: // CTIA
case 0x1: // OMTP
+ case 0x4:
return cs42l43_run_load_detect(priv, true);
case 0x2: // 3-pole
return cs42l43_run_load_detect(priv, false);
diff --git a/sound/soc/codecs/rt1011.c b/sound/soc/codecs/rt1011.c
index 9f34a6a35487..03f31d9d916e 100644
--- a/sound/soc/codecs/rt1011.c
+++ b/sound/soc/codecs/rt1011.c
@@ -1047,7 +1047,7 @@ static int rt1011_recv_spk_mode_put(struct snd_kcontrol *kcontrol,
struct snd_ctl_elem_value *ucontrol)
{
struct snd_soc_component *component = snd_kcontrol_chip(kcontrol);
- struct snd_soc_dapm_context *dapm = snd_soc_dapm_kcontrol_to_dapm(kcontrol);
+ struct snd_soc_dapm_context *dapm = snd_soc_component_to_dapm(component);
struct rt1011_priv *rt1011 =
snd_soc_component_get_drvdata(component);
diff --git a/sound/soc/codecs/rt1320-sdw.c b/sound/soc/codecs/rt1320-sdw.c
index 50f65662e143..8bb7e8497c72 100644
--- a/sound/soc/codecs/rt1320-sdw.c
+++ b/sound/soc/codecs/rt1320-sdw.c
@@ -2629,7 +2629,7 @@ static int rt1320_sdw_hw_params(struct snd_pcm_substream *substream,
struct sdw_port_config port_config;
struct sdw_port_config dmic_port_config[2];
struct sdw_stream_runtime *sdw_stream;
- int retval;
+ int retval, num_channels;
unsigned int sampling_rate;
dev_dbg(dai->dev, "%s %s", __func__, dai->name);
@@ -2661,7 +2661,8 @@ static int rt1320_sdw_hw_params(struct snd_pcm_substream *substream,
dmic_port_config[1].num = 10;
break;
case RT1321_DEV_ID:
- dmic_port_config[0].ch_mask = BIT(0) | BIT(1);
+ num_channels = params_channels(params);
+ dmic_port_config[0].ch_mask = GENMASK(num_channels - 1, 0);
dmic_port_config[0].num = 8;
break;
default:
diff --git a/sound/soc/codecs/tas2781-fmwlib.c b/sound/soc/codecs/tas2781-fmwlib.c
index c969eb38704e..5798d518d94c 100644
--- a/sound/soc/codecs/tas2781-fmwlib.c
+++ b/sound/soc/codecs/tas2781-fmwlib.c
@@ -32,6 +32,10 @@
#define TAS2781_YRAM1_PAGE 42
#define TAS2781_YRAM1_START_REG 88
+#define TAS2781_PG_REG TASDEVICE_REG(0x00, 0x00, 0x7c)
+#define TAS2781_PG_1_0 0xA0
+#define TAS2781_PG_2_0 0xA8
+
#define TAS2781_YRAM2_START_PAGE 43
#define TAS2781_YRAM2_END_PAGE 49
#define TAS2781_YRAM2_START_REG 8
@@ -98,6 +102,12 @@ struct blktyp_devidx_map {
unsigned char dev_idx;
};
+struct tas2781_cali_specific {
+ unsigned char sin_gni[4];
+ int sin_gni_reg;
+ bool is_sin_gn_flush;
+};
+
static const char deviceNumber[TASDEVICE_DSP_TAS_MAX_DEVICE] = {
1, 2, 1, 2, 1, 1, 0, 2, 4, 3, 1, 2, 3, 4, 1, 2
};
@@ -2454,6 +2464,84 @@ static int tasdevice_load_data(struct tasdevice_priv *tas_priv,
return ret;
}
+static int tas2781_cali_preproc(struct tasdevice_priv *priv, int i)
+{
+ struct tas2781_cali_specific *spec = priv->tasdevice[i].cali_specific;
+ struct calidata *cali_data = &priv->cali_data;
+ struct cali_reg *p = &cali_data->cali_reg_array;
+ unsigned char *data = cali_data->data;
+ int rc;
+
+ /*
+ * On TAS2781, if the Speaker calibrated impedance is lower than
+ * default value hard-coded inside the TAS2781, it will cuase vol
+ * lower than normal. In order to fix this issue, the parameter of
+ * SineGainI need updating.
+ */
+ if (spec == NULL) {
+ int k = i * (cali_data->cali_dat_sz_per_dev + 1);
+ int re_org, re_cal, corrected_sin_gn, pg_id;
+ unsigned char r0_deflt[4];
+
+ spec = devm_kzalloc(priv->dev, sizeof(*spec), GFP_KERNEL);
+ if (spec == NULL)
+ return -ENOMEM;
+ priv->tasdevice[i].cali_specific = spec;
+ rc = tasdevice_dev_bulk_read(priv, i, p->r0_reg, r0_deflt, 4);
+ if (rc < 0) {
+ dev_err(priv->dev, "invalid RE from %d = %d\n", i, rc);
+ return rc;
+ }
+ /*
+ * SineGainI need to be re-calculated, calculate the high 16
+ * bits.
+ */
+ re_org = r0_deflt[0] << 8 | r0_deflt[1];
+ re_cal = data[k + 1] << 8 | data[k + 2];
+ if (re_org > re_cal) {
+ rc = tasdevice_dev_read(priv, i, TAS2781_PG_REG,
+ &pg_id);
+ if (rc < 0) {
+ dev_err(priv->dev, "invalid PG id %d = %d\n",
+ i, rc);
+ return rc;
+ }
+
+ spec->sin_gni_reg = (pg_id == TAS2781_PG_1_0) ?
+ TASDEVICE_REG(0, 0x1b, 0x34) :
+ TASDEVICE_REG(0, 0x18, 0x1c);
+
+ rc = tasdevice_dev_bulk_read(priv, i,
+ spec->sin_gni_reg,
+ spec->sin_gni, 4);
+ if (rc < 0) {
+ dev_err(priv->dev, "wrong sinegaini %d = %d\n",
+ i, rc);
+ return rc;
+ }
+ corrected_sin_gn = re_org * ((spec->sin_gni[0] << 8) +
+ spec->sin_gni[1]);
+ corrected_sin_gn /= re_cal;
+ spec->sin_gni[0] = corrected_sin_gn >> 8;
+ spec->sin_gni[1] = corrected_sin_gn & 0xff;
+
+ spec->is_sin_gn_flush = true;
+ }
+ }
+
+ if (spec->is_sin_gn_flush) {
+ rc = tasdevice_dev_bulk_write(priv, i, spec->sin_gni_reg,
+ spec->sin_gni, 4);
+ if (rc < 0) {
+ dev_err(priv->dev, "update failed %d = %d\n",
+ i, rc);
+ return rc;
+ }
+ }
+
+ return 0;
+}
+
static void tasdev_load_calibrated_data(struct tasdevice_priv *priv, int i)
{
struct calidata *cali_data = &priv->cali_data;
@@ -2469,6 +2557,12 @@ static void tasdev_load_calibrated_data(struct tasdevice_priv *priv, int i)
}
k++;
+ if (priv->chip_id == TAS2781) {
+ rc = tas2781_cali_preproc(priv, i);
+ if (rc < 0)
+ return;
+ }
+
rc = tasdevice_dev_bulk_write(priv, i, p->r0_reg, &(data[k]), 4);
if (rc < 0) {
dev_err(priv->dev, "chn %d r0_reg bulk_wr err = %d\n", i, rc);
diff --git a/sound/soc/fsl/fsl_easrc.c b/sound/soc/fsl/fsl_easrc.c
index e64a0d97afd0..6c56134c60cc 100644
--- a/sound/soc/fsl/fsl_easrc.c
+++ b/sound/soc/fsl/fsl_easrc.c
@@ -52,10 +52,13 @@ static int fsl_easrc_iec958_put_bits(struct snd_kcontrol *kcontrol,
struct soc_mreg_control *mc =
(struct soc_mreg_control *)kcontrol->private_value;
unsigned int regval = ucontrol->value.integer.value[0];
+ int ret;
+
+ ret = (easrc_priv->bps_iec958[mc->regbase] != regval);
easrc_priv->bps_iec958[mc->regbase] = regval;
- return 0;
+ return ret;
}
static int fsl_easrc_iec958_get_bits(struct snd_kcontrol *kcontrol,
@@ -93,14 +96,17 @@ static int fsl_easrc_set_reg(struct snd_kcontrol *kcontrol,
struct snd_soc_component *component = snd_kcontrol_chip(kcontrol);
struct soc_mreg_control *mc =
(struct soc_mreg_control *)kcontrol->private_value;
+ struct fsl_asrc *easrc = snd_soc_component_get_drvdata(component);
unsigned int regval = ucontrol->value.integer.value[0];
+ bool changed;
int ret;
- ret = snd_soc_component_write(component, mc->regbase, regval);
- if (ret < 0)
+ ret = regmap_update_bits_check(easrc->regmap, mc->regbase,
+ GENMASK(31, 0), regval, &changed);
+ if (ret != 0)
return ret;
- return 0;
+ return changed;
}
#define SOC_SINGLE_REG_RW(xname, xreg) \
diff --git a/sound/soc/generic/simple-card-utils.c b/sound/soc/generic/simple-card-utils.c
index bdc02e85b089..9e5be0eaa77f 100644
--- a/sound/soc/generic/simple-card-utils.c
+++ b/sound/soc/generic/simple-card-utils.c
@@ -1038,11 +1038,15 @@ int graph_util_is_ports0(struct device_node *np)
else
port = np;
- struct device_node *ports __free(device_node) = of_get_parent(port);
- struct device_node *top __free(device_node) = of_get_parent(ports);
- struct device_node *ports0 __free(device_node) = of_get_child_by_name(top, "ports");
+ struct device_node *ports __free(device_node) = of_get_parent(port);
+ const char *at = strchr(kbasename(ports->full_name), '@');
- return ports0 == ports;
+ /*
+ * Since child iteration order may differ
+ * between a base DT and DT overlays,
+ * string match "ports" or "ports@0" in the node name instead.
+ */
+ return !at || !strcmp(at, "@0");
}
EXPORT_SYMBOL_GPL(graph_util_is_ports0);
diff --git a/sound/soc/intel/boards/sof_sdw.c b/sound/soc/intel/boards/sof_sdw.c
index f230991f5f8e..c18ec607e029 100644
--- a/sound/soc/intel/boards/sof_sdw.c
+++ b/sound/soc/intel/boards/sof_sdw.c
@@ -763,6 +763,14 @@ static const struct dmi_system_id sof_sdw_quirk_table[] = {
},
.driver_data = (void *)(SOC_SDW_CODEC_SPKR),
},
+ {
+ .callback = sof_sdw_quirk_cb,
+ .matches = {
+ DMI_MATCH(DMI_SYS_VENDOR, "Alienware"),
+ DMI_EXACT_MATCH(DMI_PRODUCT_SKU, "0CCD")
+ },
+ .driver_data = (void *)(SOC_SDW_CODEC_SPKR),
+ },
/* Pantherlake devices*/
{
.callback = sof_sdw_quirk_cb,
diff --git a/sound/soc/qcom/qdsp6/q6apm-dai.c b/sound/soc/qcom/qdsp6/q6apm-dai.c
index de3bdac3e791..168c166c960d 100644
--- a/sound/soc/qcom/qdsp6/q6apm-dai.c
+++ b/sound/soc/qcom/qdsp6/q6apm-dai.c
@@ -838,6 +838,7 @@ static const struct snd_soc_component_driver q6apm_fe_dai_component = {
.ack = q6apm_dai_ack,
.compress_ops = &q6apm_dai_compress_ops,
.use_dai_pcm_id = true,
+ .remove_order = SND_SOC_COMP_ORDER_EARLY,
};
static int q6apm_dai_probe(struct platform_device *pdev)
diff --git a/sound/soc/qcom/qdsp6/q6apm-lpass-dais.c b/sound/soc/qcom/qdsp6/q6apm-lpass-dais.c
index 528756f1332b..5be37eeea329 100644
--- a/sound/soc/qcom/qdsp6/q6apm-lpass-dais.c
+++ b/sound/soc/qcom/qdsp6/q6apm-lpass-dais.c
@@ -278,6 +278,7 @@ static const struct snd_soc_component_driver q6apm_lpass_dai_component = {
.of_xlate_dai_name = q6dsp_audio_ports_of_xlate_dai_name,
.be_pcm_base = AUDIOREACH_BE_PCM_BASE,
.use_dai_pcm_id = true,
+ .remove_order = SND_SOC_COMP_ORDER_FIRST,
};
static int q6apm_lpass_dai_dev_probe(struct platform_device *pdev)
diff --git a/sound/soc/qcom/qdsp6/q6apm.c b/sound/soc/qcom/qdsp6/q6apm.c
index 44841fde3856..970b08c89bb3 100644
--- a/sound/soc/qcom/qdsp6/q6apm.c
+++ b/sound/soc/qcom/qdsp6/q6apm.c
@@ -715,6 +715,7 @@ static const struct snd_soc_component_driver q6apm_audio_component = {
.name = APM_AUDIO_DRV_NAME,
.probe = q6apm_audio_probe,
.remove = q6apm_audio_remove,
+ .remove_order = SND_SOC_COMP_ORDER_LAST,
};
static int apm_probe(gpr_device_t *gdev)
diff --git a/sound/soc/sdca/sdca_functions.c b/sound/soc/sdca/sdca_functions.c
index 95b67bb904c3..e0ed593697ba 100644
--- a/sound/soc/sdca/sdca_functions.c
+++ b/sound/soc/sdca/sdca_functions.c
@@ -1156,9 +1156,12 @@ static int find_sdca_entity_iot(struct device *dev,
if (!terminal->is_dataport) {
const char *type_name = sdca_find_terminal_name(terminal->type);
- if (type_name)
+ if (type_name) {
entity->label = devm_kasprintf(dev, GFP_KERNEL, "%s %s",
entity->label, type_name);
+ if (!entity->label)
+ return -ENOMEM;
+ }
}
ret = fwnode_property_read_u32(entity_node,
diff --git a/sound/soc/sdca/sdca_interrupts.c b/sound/soc/sdca/sdca_interrupts.c
index d9e22cf40f77..95b1ab4ba1b0 100644
--- a/sound/soc/sdca/sdca_interrupts.c
+++ b/sound/soc/sdca/sdca_interrupts.c
@@ -265,9 +265,9 @@ static int sdca_irq_request_locked(struct device *dev,
}
/**
- * sdca_request_irq - request an individual SDCA interrupt
+ * sdca_irq_request - request an individual SDCA interrupt
* @dev: Pointer to the struct device against which things should be allocated.
- * @interrupt_info: Pointer to the interrupt information structure.
+ * @info: Pointer to the interrupt information structure.
* @sdca_irq: SDCA interrupt position.
* @name: Name to be given to the IRQ.
* @handler: A callback thread function to be called for the IRQ.
diff --git a/sound/soc/soc-core.c b/sound/soc/soc-core.c
index d0fffef65daf..573693e21780 100644
--- a/sound/soc/soc-core.c
+++ b/sound/soc/soc-core.c
@@ -462,8 +462,7 @@ static void soc_free_pcm_runtime(struct snd_soc_pcm_runtime *rtd)
list_del(&rtd->list);
- if (delayed_work_pending(&rtd->delayed_work))
- flush_delayed_work(&rtd->delayed_work);
+ flush_delayed_work(&rtd->delayed_work);
snd_soc_pcm_component_free(rtd);
/*
@@ -1864,12 +1863,15 @@ static void cleanup_dmi_name(char *name)
/*
* Check if a DMI field is valid, i.e. not containing any string
- * in the black list.
+ * in the black list and not the empty string.
*/
static int is_dmi_valid(const char *field)
{
int i = 0;
+ if (!field[0])
+ return 0;
+
while (dmi_blacklist[i]) {
if (strstr(field, dmi_blacklist[i]))
return 0;
@@ -2122,6 +2124,9 @@ static void soc_cleanup_card_resources(struct snd_soc_card *card)
for_each_card_rtds(card, rtd)
if (rtd->initialized)
snd_soc_link_exit(rtd);
+ /* flush delayed work before removing DAIs and DAPM widgets */
+ snd_soc_flush_all_delayed_work(card);
+
/* remove and free each DAI */
soc_remove_link_dais(card);
soc_remove_link_components(card);
diff --git a/sound/soc/tegra/tegra_audio_graph_card.c b/sound/soc/tegra/tegra_audio_graph_card.c
index 94b5ab77649b..ea10e6e8a9fe 100644
--- a/sound/soc/tegra/tegra_audio_graph_card.c
+++ b/sound/soc/tegra/tegra_audio_graph_card.c
@@ -231,6 +231,15 @@ static const struct tegra_audio_cdata tegra186_data = {
.plla_out0_rates[x11_RATE] = 45158400,
};
+static const struct tegra_audio_cdata tegra238_data = {
+ /* PLLA */
+ .plla_rates[x8_RATE] = 1277952000,
+ .plla_rates[x11_RATE] = 1264435200,
+ /* PLLA_OUT0 */
+ .plla_out0_rates[x8_RATE] = 49152000,
+ .plla_out0_rates[x11_RATE] = 45158400,
+};
+
static const struct tegra_audio_cdata tegra264_data = {
/* PLLA1 */
.plla_rates[x8_RATE] = 983040000,
@@ -245,6 +254,8 @@ static const struct of_device_id graph_of_tegra_match[] = {
.data = &tegra210_data },
{ .compatible = "nvidia,tegra186-audio-graph-card",
.data = &tegra186_data },
+ { .compatible = "nvidia,tegra238-audio-graph-card",
+ .data = &tegra238_data },
{ .compatible = "nvidia,tegra264-audio-graph-card",
.data = &tegra264_data },
{},