summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Documentation/devicetree/bindings/sound/ti,tlv320aic3x.yaml1
-rw-r--r--drivers/firmware/cirrus/cs_dsp.c37
-rw-r--r--drivers/firmware/cirrus/cs_dsp.h18
-rw-r--r--drivers/firmware/cirrus/test/cs_dsp_test_bin.c22
-rw-r--r--drivers/firmware/cirrus/test/cs_dsp_test_bin_error.c24
-rw-r--r--drivers/firmware/cirrus/test/cs_dsp_test_wmfw.c26
-rw-r--r--drivers/firmware/cirrus/test/cs_dsp_test_wmfw_error.c24
-rw-r--r--drivers/firmware/cirrus/test/cs_dsp_tests.c1
-rw-r--r--sound/drivers/aloop.c62
-rw-r--r--sound/hda/codecs/realtek/alc269.c1
-rw-r--r--sound/soc/amd/renoir/acp3x-pdm-dma.c2
-rw-r--r--sound/soc/amd/yc/acp6x-mach.c7
-rw-r--r--sound/soc/codecs/cs42l43-jack.c37
-rw-r--r--sound/soc/codecs/rt1320-sdw.c2
-rw-r--r--sound/soc/fsl/fsl_xcvr.c3
-rw-r--r--sound/soc/intel/boards/sof_es8336.c9
-rw-r--r--sound/soc/sof/intel/hda.c5
-rw-r--r--sound/usb/mixer_quirks.c9
18 files changed, 234 insertions, 56 deletions
diff --git a/Documentation/devicetree/bindings/sound/ti,tlv320aic3x.yaml b/Documentation/devicetree/bindings/sound/ti,tlv320aic3x.yaml
index 206f6d61e362..50088698adac 100644
--- a/Documentation/devicetree/bindings/sound/ti,tlv320aic3x.yaml
+++ b/Documentation/devicetree/bindings/sound/ti,tlv320aic3x.yaml
@@ -46,6 +46,7 @@ maintainers:
properties:
compatible:
enum:
+ - ti,tlv320aic23
- ti,tlv320aic3x
- ti,tlv320aic33
- ti,tlv320aic3007
diff --git a/drivers/firmware/cirrus/cs_dsp.c b/drivers/firmware/cirrus/cs_dsp.c
index 525ac0f0a75d..73d201e7d992 100644
--- a/drivers/firmware/cirrus/cs_dsp.c
+++ b/drivers/firmware/cirrus/cs_dsp.c
@@ -9,6 +9,7 @@
* Cirrus Logic International Semiconductor Ltd.
*/
+#include <kunit/visibility.h>
#include <linux/cleanup.h>
#include <linux/ctype.h>
#include <linux/debugfs.h>
@@ -24,6 +25,41 @@
#include <linux/firmware/cirrus/cs_dsp.h>
#include <linux/firmware/cirrus/wmfw.h>
+#include "cs_dsp.h"
+
+/*
+ * When the KUnit test is running the error-case tests will cause a lot
+ * of messages. Rate-limit to prevent overflowing the kernel log buffer
+ * during KUnit test runs.
+ */
+#if IS_ENABLED(CONFIG_FW_CS_DSP_KUNIT_TEST)
+bool cs_dsp_suppress_err_messages;
+EXPORT_SYMBOL_IF_KUNIT(cs_dsp_suppress_err_messages);
+
+bool cs_dsp_suppress_warn_messages;
+EXPORT_SYMBOL_IF_KUNIT(cs_dsp_suppress_warn_messages);
+
+bool cs_dsp_suppress_info_messages;
+EXPORT_SYMBOL_IF_KUNIT(cs_dsp_suppress_info_messages);
+
+#define cs_dsp_err(_dsp, fmt, ...) \
+ do { \
+ if (!cs_dsp_suppress_err_messages) \
+ dev_err_ratelimited(_dsp->dev, "%s: " fmt, _dsp->name, ##__VA_ARGS__); \
+ } while (false)
+#define cs_dsp_warn(_dsp, fmt, ...) \
+ do { \
+ if (!cs_dsp_suppress_warn_messages) \
+ dev_warn_ratelimited(_dsp->dev, "%s: " fmt, _dsp->name, ##__VA_ARGS__); \
+ } while (false)
+#define cs_dsp_info(_dsp, fmt, ...) \
+ do { \
+ if (!cs_dsp_suppress_info_messages) \
+ dev_info_ratelimited(_dsp->dev, "%s: " fmt, _dsp->name, ##__VA_ARGS__); \
+ } while (false)
+#define cs_dsp_dbg(_dsp, fmt, ...) \
+ dev_dbg_ratelimited(_dsp->dev, "%s: " fmt, _dsp->name, ##__VA_ARGS__)
+#else
#define cs_dsp_err(_dsp, fmt, ...) \
dev_err(_dsp->dev, "%s: " fmt, _dsp->name, ##__VA_ARGS__)
#define cs_dsp_warn(_dsp, fmt, ...) \
@@ -32,6 +68,7 @@
dev_info(_dsp->dev, "%s: " fmt, _dsp->name, ##__VA_ARGS__)
#define cs_dsp_dbg(_dsp, fmt, ...) \
dev_dbg(_dsp->dev, "%s: " fmt, _dsp->name, ##__VA_ARGS__)
+#endif
#define ADSP1_CONTROL_1 0x00
#define ADSP1_CONTROL_2 0x02
diff --git a/drivers/firmware/cirrus/cs_dsp.h b/drivers/firmware/cirrus/cs_dsp.h
new file mode 100644
index 000000000000..adf543004aea
--- /dev/null
+++ b/drivers/firmware/cirrus/cs_dsp.h
@@ -0,0 +1,18 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+/*
+ * cs_dsp.h -- Private header for cs_dsp driver.
+ *
+ * Copyright (C) 2026 Cirrus Logic, Inc. and
+ * Cirrus Logic International Semiconductor Ltd.
+ */
+
+#ifndef FW_CS_DSP_H
+#define FW_CS_DSP_H
+
+#if IS_ENABLED(CONFIG_KUNIT)
+extern bool cs_dsp_suppress_err_messages;
+extern bool cs_dsp_suppress_warn_messages;
+extern bool cs_dsp_suppress_info_messages;
+#endif
+
+#endif /* ifndef FW_CS_DSP_H */
diff --git a/drivers/firmware/cirrus/test/cs_dsp_test_bin.c b/drivers/firmware/cirrus/test/cs_dsp_test_bin.c
index 163b7faecff4..2c6486fa9575 100644
--- a/drivers/firmware/cirrus/test/cs_dsp_test_bin.c
+++ b/drivers/firmware/cirrus/test/cs_dsp_test_bin.c
@@ -17,6 +17,8 @@
#include <linux/random.h>
#include <linux/regmap.h>
+#include "../cs_dsp.h"
+
/*
* Test method is:
*
@@ -2224,7 +2226,22 @@ static int cs_dsp_bin_test_common_init(struct kunit *test, struct cs_dsp *dsp)
return ret;
/* Automatically call cs_dsp_remove() when test case ends */
- return kunit_add_action_or_reset(priv->test, _cs_dsp_remove_wrapper, dsp);
+ ret = kunit_add_action_or_reset(priv->test, _cs_dsp_remove_wrapper, dsp);
+ if (ret)
+ return ret;
+
+ /*
+ * The large number of test cases will cause an unusually large amount
+ * of dev_info() messages from cs_dsp, so suppress these.
+ */
+ cs_dsp_suppress_info_messages = true;
+
+ return 0;
+}
+
+static void cs_dsp_bin_test_exit(struct kunit *test)
+{
+ cs_dsp_suppress_info_messages = false;
}
static int cs_dsp_bin_test_halo_init(struct kunit *test)
@@ -2536,18 +2553,21 @@ static struct kunit_case cs_dsp_bin_test_cases_adsp2[] = {
static struct kunit_suite cs_dsp_bin_test_halo = {
.name = "cs_dsp_bin_halo",
.init = cs_dsp_bin_test_halo_init,
+ .exit = cs_dsp_bin_test_exit,
.test_cases = cs_dsp_bin_test_cases_halo,
};
static struct kunit_suite cs_dsp_bin_test_adsp2_32bit = {
.name = "cs_dsp_bin_adsp2_32bit",
.init = cs_dsp_bin_test_adsp2_32bit_init,
+ .exit = cs_dsp_bin_test_exit,
.test_cases = cs_dsp_bin_test_cases_adsp2,
};
static struct kunit_suite cs_dsp_bin_test_adsp2_16bit = {
.name = "cs_dsp_bin_adsp2_16bit",
.init = cs_dsp_bin_test_adsp2_16bit_init,
+ .exit = cs_dsp_bin_test_exit,
.test_cases = cs_dsp_bin_test_cases_adsp2,
};
diff --git a/drivers/firmware/cirrus/test/cs_dsp_test_bin_error.c b/drivers/firmware/cirrus/test/cs_dsp_test_bin_error.c
index a7ec956d2724..631b9cb9eb25 100644
--- a/drivers/firmware/cirrus/test/cs_dsp_test_bin_error.c
+++ b/drivers/firmware/cirrus/test/cs_dsp_test_bin_error.c
@@ -18,6 +18,8 @@
#include <linux/string.h>
#include <linux/vmalloc.h>
+#include "../cs_dsp.h"
+
KUNIT_DEFINE_ACTION_WRAPPER(_put_device_wrapper, put_device, struct device *);
KUNIT_DEFINE_ACTION_WRAPPER(_cs_dsp_remove_wrapper, cs_dsp_remove, struct cs_dsp *);
@@ -380,11 +382,9 @@ static void bin_block_payload_len_garbage(struct kunit *test)
static void cs_dsp_bin_err_test_exit(struct kunit *test)
{
- /*
- * Testing error conditions can produce a lot of log output
- * from cs_dsp error messages, so rate limit the test cases.
- */
- usleep_range(200, 500);
+ cs_dsp_suppress_err_messages = false;
+ cs_dsp_suppress_warn_messages = false;
+ cs_dsp_suppress_info_messages = false;
}
static int cs_dsp_bin_err_test_common_init(struct kunit *test, struct cs_dsp *dsp,
@@ -474,7 +474,19 @@ static int cs_dsp_bin_err_test_common_init(struct kunit *test, struct cs_dsp *ds
return ret;
/* Automatically call cs_dsp_remove() when test case ends */
- return kunit_add_action_or_reset(priv->test, _cs_dsp_remove_wrapper, dsp);
+ ret = kunit_add_action_or_reset(priv->test, _cs_dsp_remove_wrapper, dsp);
+ if (ret)
+ return ret;
+
+ /*
+ * Testing error conditions can produce a lot of log output
+ * from cs_dsp error messages, so suppress messages.
+ */
+ cs_dsp_suppress_err_messages = true;
+ cs_dsp_suppress_warn_messages = true;
+ cs_dsp_suppress_info_messages = true;
+
+ return 0;
}
static int cs_dsp_bin_err_test_halo_init(struct kunit *test)
diff --git a/drivers/firmware/cirrus/test/cs_dsp_test_wmfw.c b/drivers/firmware/cirrus/test/cs_dsp_test_wmfw.c
index 9e997c4ee2d6..f02cb6cf7638 100644
--- a/drivers/firmware/cirrus/test/cs_dsp_test_wmfw.c
+++ b/drivers/firmware/cirrus/test/cs_dsp_test_wmfw.c
@@ -18,6 +18,8 @@
#include <linux/string.h>
#include <linux/vmalloc.h>
+#include "../cs_dsp.h"
+
/*
* Test method is:
*
@@ -1853,7 +1855,22 @@ static int cs_dsp_wmfw_test_common_init(struct kunit *test, struct cs_dsp *dsp,
return ret;
/* Automatically call cs_dsp_remove() when test case ends */
- return kunit_add_action_or_reset(priv->test, _cs_dsp_remove_wrapper, dsp);
+ ret = kunit_add_action_or_reset(priv->test, _cs_dsp_remove_wrapper, dsp);
+ if (ret)
+ return ret;
+
+ /*
+ * The large number of test cases will cause an unusually large amount
+ * of dev_info() messages from cs_dsp, so suppress these.
+ */
+ cs_dsp_suppress_info_messages = true;
+
+ return 0;
+}
+
+static void cs_dsp_wmfw_test_exit(struct kunit *test)
+{
+ cs_dsp_suppress_info_messages = false;
}
static int cs_dsp_wmfw_test_halo_init(struct kunit *test)
@@ -2163,42 +2180,49 @@ static struct kunit_case cs_dsp_wmfw_test_cases_adsp2[] = {
static struct kunit_suite cs_dsp_wmfw_test_halo = {
.name = "cs_dsp_wmfwV3_halo",
.init = cs_dsp_wmfw_test_halo_init,
+ .exit = cs_dsp_wmfw_test_exit,
.test_cases = cs_dsp_wmfw_test_cases_halo,
};
static struct kunit_suite cs_dsp_wmfw_test_adsp2_32bit_wmfw0 = {
.name = "cs_dsp_wmfwV0_adsp2_32bit",
.init = cs_dsp_wmfw_test_adsp2_32bit_wmfw0_init,
+ .exit = cs_dsp_wmfw_test_exit,
.test_cases = cs_dsp_wmfw_test_cases_adsp2,
};
static struct kunit_suite cs_dsp_wmfw_test_adsp2_32bit_wmfw1 = {
.name = "cs_dsp_wmfwV1_adsp2_32bit",
.init = cs_dsp_wmfw_test_adsp2_32bit_wmfw1_init,
+ .exit = cs_dsp_wmfw_test_exit,
.test_cases = cs_dsp_wmfw_test_cases_adsp2,
};
static struct kunit_suite cs_dsp_wmfw_test_adsp2_32bit_wmfw2 = {
.name = "cs_dsp_wmfwV2_adsp2_32bit",
.init = cs_dsp_wmfw_test_adsp2_32bit_wmfw2_init,
+ .exit = cs_dsp_wmfw_test_exit,
.test_cases = cs_dsp_wmfw_test_cases_adsp2,
};
static struct kunit_suite cs_dsp_wmfw_test_adsp2_16bit_wmfw0 = {
.name = "cs_dsp_wmfwV0_adsp2_16bit",
.init = cs_dsp_wmfw_test_adsp2_16bit_wmfw0_init,
+ .exit = cs_dsp_wmfw_test_exit,
.test_cases = cs_dsp_wmfw_test_cases_adsp2,
};
static struct kunit_suite cs_dsp_wmfw_test_adsp2_16bit_wmfw1 = {
.name = "cs_dsp_wmfwV1_adsp2_16bit",
.init = cs_dsp_wmfw_test_adsp2_16bit_wmfw1_init,
+ .exit = cs_dsp_wmfw_test_exit,
.test_cases = cs_dsp_wmfw_test_cases_adsp2,
};
static struct kunit_suite cs_dsp_wmfw_test_adsp2_16bit_wmfw2 = {
.name = "cs_dsp_wmfwV2_adsp2_16bit",
.init = cs_dsp_wmfw_test_adsp2_16bit_wmfw2_init,
+ .exit = cs_dsp_wmfw_test_exit,
.test_cases = cs_dsp_wmfw_test_cases_adsp2,
};
diff --git a/drivers/firmware/cirrus/test/cs_dsp_test_wmfw_error.c b/drivers/firmware/cirrus/test/cs_dsp_test_wmfw_error.c
index c309843261d7..37162d12e2fa 100644
--- a/drivers/firmware/cirrus/test/cs_dsp_test_wmfw_error.c
+++ b/drivers/firmware/cirrus/test/cs_dsp_test_wmfw_error.c
@@ -18,6 +18,8 @@
#include <linux/string.h>
#include <linux/vmalloc.h>
+#include "../cs_dsp.h"
+
KUNIT_DEFINE_ACTION_WRAPPER(_put_device_wrapper, put_device, struct device *);
KUNIT_DEFINE_ACTION_WRAPPER(_cs_dsp_remove_wrapper, cs_dsp_remove, struct cs_dsp *);
@@ -989,11 +991,9 @@ static void wmfw_v2_coeff_description_exceeds_block(struct kunit *test)
static void cs_dsp_wmfw_err_test_exit(struct kunit *test)
{
- /*
- * Testing error conditions can produce a lot of log output
- * from cs_dsp error messages, so rate limit the test cases.
- */
- usleep_range(200, 500);
+ cs_dsp_suppress_err_messages = false;
+ cs_dsp_suppress_warn_messages = false;
+ cs_dsp_suppress_info_messages = false;
}
static int cs_dsp_wmfw_err_test_common_init(struct kunit *test, struct cs_dsp *dsp,
@@ -1072,7 +1072,19 @@ static int cs_dsp_wmfw_err_test_common_init(struct kunit *test, struct cs_dsp *d
return ret;
/* Automatically call cs_dsp_remove() when test case ends */
- return kunit_add_action_or_reset(priv->test, _cs_dsp_remove_wrapper, dsp);
+ ret = kunit_add_action_or_reset(priv->test, _cs_dsp_remove_wrapper, dsp);
+ if (ret)
+ return ret;
+
+ /*
+ * Testing error conditions can produce a lot of log output
+ * from cs_dsp error messages, so suppress messages.
+ */
+ cs_dsp_suppress_err_messages = true;
+ cs_dsp_suppress_warn_messages = true;
+ cs_dsp_suppress_info_messages = true;
+
+ return 0;
}
static int cs_dsp_wmfw_err_test_halo_init(struct kunit *test)
diff --git a/drivers/firmware/cirrus/test/cs_dsp_tests.c b/drivers/firmware/cirrus/test/cs_dsp_tests.c
index 7b829a03ca52..288675fdbdc5 100644
--- a/drivers/firmware/cirrus/test/cs_dsp_tests.c
+++ b/drivers/firmware/cirrus/test/cs_dsp_tests.c
@@ -12,3 +12,4 @@ MODULE_AUTHOR("Richard Fitzgerald <rf@opensource.cirrus.com>");
MODULE_LICENSE("GPL");
MODULE_IMPORT_NS("FW_CS_DSP");
MODULE_IMPORT_NS("FW_CS_DSP_KUNIT_TEST_UTILS");
+MODULE_IMPORT_NS("EXPORTED_FOR_KUNIT_TESTING");
diff --git a/sound/drivers/aloop.c b/sound/drivers/aloop.c
index 64ef03b2d579..aa0d2fcb1a18 100644
--- a/sound/drivers/aloop.c
+++ b/sound/drivers/aloop.c
@@ -336,37 +336,43 @@ static bool is_access_interleaved(snd_pcm_access_t access)
static int loopback_check_format(struct loopback_cable *cable, int stream)
{
+ struct loopback_pcm *dpcm_play, *dpcm_capt;
struct snd_pcm_runtime *runtime, *cruntime;
struct loopback_setup *setup;
struct snd_card *card;
+ bool stop_capture = false;
int check;
- if (cable->valid != CABLE_VALID_BOTH) {
- if (stream == SNDRV_PCM_STREAM_PLAYBACK)
- goto __notify;
- return 0;
- }
- runtime = cable->streams[SNDRV_PCM_STREAM_PLAYBACK]->
- substream->runtime;
- cruntime = cable->streams[SNDRV_PCM_STREAM_CAPTURE]->
- substream->runtime;
- check = runtime->format != cruntime->format ||
- runtime->rate != cruntime->rate ||
- runtime->channels != cruntime->channels ||
- is_access_interleaved(runtime->access) !=
- is_access_interleaved(cruntime->access);
- if (!check)
- return 0;
- if (stream == SNDRV_PCM_STREAM_CAPTURE) {
- return -EIO;
- } else {
- snd_pcm_stop(cable->streams[SNDRV_PCM_STREAM_CAPTURE]->
- substream, SNDRV_PCM_STATE_DRAINING);
- __notify:
- runtime = cable->streams[SNDRV_PCM_STREAM_PLAYBACK]->
- substream->runtime;
- setup = get_setup(cable->streams[SNDRV_PCM_STREAM_PLAYBACK]);
- card = cable->streams[SNDRV_PCM_STREAM_PLAYBACK]->loopback->card;
+ scoped_guard(spinlock_irqsave, &cable->lock) {
+ dpcm_play = cable->streams[SNDRV_PCM_STREAM_PLAYBACK];
+ dpcm_capt = cable->streams[SNDRV_PCM_STREAM_CAPTURE];
+
+ if (cable->valid != CABLE_VALID_BOTH) {
+ if (stream == SNDRV_PCM_STREAM_CAPTURE || !dpcm_play)
+ return 0;
+ } else {
+ if (!dpcm_play || !dpcm_capt)
+ return -EIO;
+ runtime = dpcm_play->substream->runtime;
+ cruntime = dpcm_capt->substream->runtime;
+ if (!runtime || !cruntime)
+ return -EIO;
+ check = runtime->format != cruntime->format ||
+ runtime->rate != cruntime->rate ||
+ runtime->channels != cruntime->channels ||
+ is_access_interleaved(runtime->access) !=
+ is_access_interleaved(cruntime->access);
+ if (!check)
+ return 0;
+ if (stream == SNDRV_PCM_STREAM_CAPTURE)
+ return -EIO;
+ else if (cruntime->state == SNDRV_PCM_STATE_RUNNING)
+ stop_capture = true;
+ }
+
+ setup = get_setup(dpcm_play);
+ card = dpcm_play->loopback->card;
+ runtime = dpcm_play->substream->runtime;
if (setup->format != runtime->format) {
snd_ctl_notify(card, SNDRV_CTL_EVENT_MASK_VALUE,
&setup->format_id);
@@ -389,6 +395,10 @@ static int loopback_check_format(struct loopback_cable *cable, int stream)
setup->access = runtime->access;
}
}
+
+ if (stop_capture)
+ snd_pcm_stop(dpcm_capt->substream, SNDRV_PCM_STATE_DRAINING);
+
return 0;
}
diff --git a/sound/hda/codecs/realtek/alc269.c b/sound/hda/codecs/realtek/alc269.c
index 0a0496deb9c8..b66965a52107 100644
--- a/sound/hda/codecs/realtek/alc269.c
+++ b/sound/hda/codecs/realtek/alc269.c
@@ -6353,6 +6353,7 @@ static const struct hda_quirk alc269_fixup_tbl[] = {
SND_PCI_QUIRK(0x1025, 0x1430, "Acer TravelMate B311R-31", ALC256_FIXUP_ACER_MIC_NO_PRESENCE),
SND_PCI_QUIRK(0x1025, 0x1466, "Acer Aspire A515-56", ALC255_FIXUP_ACER_HEADPHONE_AND_MIC),
SND_PCI_QUIRK(0x1025, 0x1534, "Acer Predator PH315-54", ALC255_FIXUP_ACER_MIC_NO_PRESENCE),
+ SND_PCI_QUIRK(0x1025, 0x1539, "Acer Nitro 5 AN515-57", ALC2XX_FIXUP_HEADSET_MIC),
SND_PCI_QUIRK(0x1025, 0x159c, "Acer Nitro 5 AN515-58", ALC2XX_FIXUP_HEADSET_MIC),
SND_PCI_QUIRK(0x1025, 0x1597, "Acer Nitro 5 AN517-55", ALC2XX_FIXUP_HEADSET_MIC),
SND_PCI_QUIRK(0x1025, 0x169a, "Acer Swift SFG16", ALC256_FIXUP_ACER_SFG16_MICMUTE_LED),
diff --git a/sound/soc/amd/renoir/acp3x-pdm-dma.c b/sound/soc/amd/renoir/acp3x-pdm-dma.c
index 95ac8c680037..a560d06097d5 100644
--- a/sound/soc/amd/renoir/acp3x-pdm-dma.c
+++ b/sound/soc/amd/renoir/acp3x-pdm-dma.c
@@ -301,9 +301,11 @@ static int acp_pdm_dma_close(struct snd_soc_component *component,
struct snd_pcm_substream *substream)
{
struct pdm_dev_data *adata = dev_get_drvdata(component->dev);
+ struct pdm_stream_instance *rtd = substream->runtime->private_data;
disable_pdm_interrupts(adata->acp_base);
adata->capture_stream = NULL;
+ kfree(rtd);
return 0;
}
diff --git a/sound/soc/amd/yc/acp6x-mach.c b/sound/soc/amd/yc/acp6x-mach.c
index c18da0915baa..67f2fee19398 100644
--- a/sound/soc/amd/yc/acp6x-mach.c
+++ b/sound/soc/amd/yc/acp6x-mach.c
@@ -643,6 +643,13 @@ static const struct dmi_system_id yc_acp_quirk_table[] = {
{
.driver_data = &acp6x_card,
.matches = {
+ DMI_MATCH(DMI_BOARD_VENDOR, "HP"),
+ DMI_MATCH(DMI_BOARD_NAME, "8EE4"),
+ }
+ },
+ {
+ .driver_data = &acp6x_card,
+ .matches = {
DMI_MATCH(DMI_BOARD_VENDOR, "MECHREVO"),
DMI_MATCH(DMI_BOARD_NAME, "MRID6"),
}
diff --git a/sound/soc/codecs/cs42l43-jack.c b/sound/soc/codecs/cs42l43-jack.c
index b719d62635a0..b83bc4de1301 100644
--- a/sound/soc/codecs/cs42l43-jack.c
+++ b/sound/soc/codecs/cs42l43-jack.c
@@ -496,7 +496,23 @@ void cs42l43_bias_sense_timeout(struct work_struct *work)
pm_runtime_put_autosuspend(priv->dev);
}
-static void cs42l43_start_load_detect(struct cs42l43_codec *priv)
+static const struct reg_sequence cs42l43_3pole_patch[] = {
+ { 0x4000, 0x00000055 },
+ { 0x4000, 0x000000AA },
+ { 0x17420, 0x8500F300 },
+ { 0x17424, 0x36003E00 },
+ { 0x4000, 0x00000000 },
+};
+
+static const struct reg_sequence cs42l43_4pole_patch[] = {
+ { 0x4000, 0x00000055 },
+ { 0x4000, 0x000000AA },
+ { 0x17420, 0x7800E600 },
+ { 0x17424, 0x36003800 },
+ { 0x4000, 0x00000000 },
+};
+
+static void cs42l43_start_load_detect(struct cs42l43_codec *priv, bool mic)
{
struct cs42l43 *cs42l43 = priv->core;
@@ -520,6 +536,15 @@ static void cs42l43_start_load_detect(struct cs42l43_codec *priv)
dev_err(priv->dev, "Load detect HP power down timed out\n");
}
+ if (mic)
+ regmap_multi_reg_write_bypassed(cs42l43->regmap,
+ cs42l43_4pole_patch,
+ ARRAY_SIZE(cs42l43_4pole_patch));
+ else
+ regmap_multi_reg_write_bypassed(cs42l43->regmap,
+ cs42l43_3pole_patch,
+ ARRAY_SIZE(cs42l43_3pole_patch));
+
regmap_update_bits(cs42l43->regmap, CS42L43_BLOCK_EN3,
CS42L43_ADC1_EN_MASK | CS42L43_ADC2_EN_MASK, 0);
regmap_update_bits(cs42l43->regmap, CS42L43_DACCNFG2, CS42L43_HP_HPF_EN_MASK, 0);
@@ -598,7 +623,7 @@ static int cs42l43_run_load_detect(struct cs42l43_codec *priv, bool mic)
reinit_completion(&priv->load_detect);
- cs42l43_start_load_detect(priv);
+ cs42l43_start_load_detect(priv, mic);
time_left = wait_for_completion_timeout(&priv->load_detect,
msecs_to_jiffies(CS42L43_LOAD_TIMEOUT_MS));
cs42l43_stop_load_detect(priv);
@@ -622,11 +647,11 @@ static int cs42l43_run_load_detect(struct cs42l43_codec *priv, bool mic)
}
switch (val & CS42L43_AMP3_RES_DET_MASK) {
- case 0x0: // low impedance
- case 0x1: // high impedance
+ case 0x0: // < 22 Ohm impedance
+ case 0x1: // < 150 Ohm impedance
+ case 0x2: // < 1000 Ohm impedance
return CS42L43_JACK_HEADPHONE;
- case 0x2: // lineout
- case 0x3: // Open circuit
+ case 0x3: // > 1000 Ohm impedance
return CS42L43_JACK_LINEOUT;
default:
return -EINVAL;
diff --git a/sound/soc/codecs/rt1320-sdw.c b/sound/soc/codecs/rt1320-sdw.c
index feecef258b65..e6142645b903 100644
--- a/sound/soc/codecs/rt1320-sdw.c
+++ b/sound/soc/codecs/rt1320-sdw.c
@@ -203,6 +203,7 @@ static const struct reg_sequence rt1320_vc_blind_write[] = {
{ 0x3fc2bfc2, 0x00 },
{ 0x3fc2bfc1, 0x00 },
{ 0x3fc2bfc0, 0x07 },
+ { 0x1000cc46, 0x00 },
{ 0x0000d486, 0x43 },
{ SDW_SDCA_CTL(FUNC_NUM_AMP, RT1320_SDCA_ENT_PDE23, RT1320_SDCA_CTL_REQ_POWER_STATE, 0), 0x00 },
{ 0x1000db00, 0x07 },
@@ -354,6 +355,7 @@ static const struct reg_sequence rt1321_blind_write[] = {
{ 0x0000d73d, 0xd7 },
{ 0x0000d73e, 0x00 },
{ 0x0000d73f, 0x10 },
+ { 0x1000cd56, 0x00 },
{ 0x3fc2dfc3, 0x00 },
{ 0x3fc2dfc2, 0x00 },
{ 0x3fc2dfc1, 0x00 },
diff --git a/sound/soc/fsl/fsl_xcvr.c b/sound/soc/fsl/fsl_xcvr.c
index a268fb81a2f8..5de93f458b56 100644
--- a/sound/soc/fsl/fsl_xcvr.c
+++ b/sound/soc/fsl/fsl_xcvr.c
@@ -223,10 +223,13 @@ static int fsl_xcvr_mode_put(struct snd_kcontrol *kcontrol,
xcvr->mode = snd_soc_enum_item_to_val(e, item[0]);
+ down_read(&card->snd_card->controls_rwsem);
fsl_xcvr_activate_ctl(dai, fsl_xcvr_arc_mode_kctl.name,
(xcvr->mode == FSL_XCVR_MODE_ARC));
fsl_xcvr_activate_ctl(dai, fsl_xcvr_earc_capds_kctl.name,
(xcvr->mode == FSL_XCVR_MODE_EARC));
+ up_read(&card->snd_card->controls_rwsem);
+
/* Allow playback for SPDIF only */
rtd = snd_soc_get_pcm_runtime(card, card->dai_link);
rtd->pcm->streams[SNDRV_PCM_STREAM_PLAYBACK].substream_count =
diff --git a/sound/soc/intel/boards/sof_es8336.c b/sound/soc/intel/boards/sof_es8336.c
index fce50fd9f093..e9ee752d5ec3 100644
--- a/sound/soc/intel/boards/sof_es8336.c
+++ b/sound/soc/intel/boards/sof_es8336.c
@@ -337,6 +337,15 @@ static const struct dmi_system_id sof_es8336_quirk_table[] = {
{
.callback = sof_es8336_quirk_cb,
.matches = {
+ DMI_MATCH(DMI_SYS_VENDOR, "HUAWEI"),
+ DMI_MATCH(DMI_PRODUCT_NAME, "BOD-WXX9"),
+ },
+ .driver_data = (void *)(SOF_ES8336_HEADPHONE_GPIO |
+ SOF_ES8336_ENABLE_DMIC)
+ },
+ {
+ .callback = sof_es8336_quirk_cb,
+ .matches = {
DMI_MATCH(DMI_SYS_VENDOR, "IP3 tech"),
DMI_MATCH(DMI_BOARD_NAME, "WN1"),
},
diff --git a/sound/soc/sof/intel/hda.c b/sound/soc/sof/intel/hda.c
index 0bb85f92e106..686ecc040867 100644
--- a/sound/soc/sof/intel/hda.c
+++ b/sound/soc/sof/intel/hda.c
@@ -1304,9 +1304,8 @@ static struct snd_soc_acpi_mach *hda_sdw_machine_select(struct snd_sof_dev *sdev
int i;
hdev = pdata->hw_pdata;
- link_mask = hdev->info.link_mask;
- if (!link_mask) {
+ if (!hdev->info.link_mask) {
dev_info(sdev->dev, "SoundWire links not enabled\n");
return NULL;
}
@@ -1337,7 +1336,7 @@ static struct snd_soc_acpi_mach *hda_sdw_machine_select(struct snd_sof_dev *sdev
* link_mask supported by hw and then go on searching
* link_adr
*/
- if (~link_mask & mach->link_mask)
+ if (~hdev->info.link_mask & mach->link_mask)
continue;
/* No need to match adr if there is no links defined */
diff --git a/sound/usb/mixer_quirks.c b/sound/usb/mixer_quirks.c
index f8eccb1c58da..cf4ccf467cb6 100644
--- a/sound/usb/mixer_quirks.c
+++ b/sound/usb/mixer_quirks.c
@@ -311,13 +311,8 @@ static int snd_audigy2nx_led_update(struct usb_mixer_interface *mixer,
if (pm.err < 0)
return pm.err;
- if (chip->usb_id == USB_ID(0x041e, 0x3042))
- err = snd_usb_ctl_msg(chip->dev,
- usb_sndctrlpipe(chip->dev, 0), 0x24,
- USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_OTHER,
- !value, 0, NULL, 0);
- /* USB X-Fi S51 Pro */
- if (chip->usb_id == USB_ID(0x041e, 0x30df))
+ if (chip->usb_id == USB_ID(0x041e, 0x3042) || /* USB X-Fi S51 */
+ chip->usb_id == USB_ID(0x041e, 0x30df)) /* USB X-Fi S51 Pro */
err = snd_usb_ctl_msg(chip->dev,
usb_sndctrlpipe(chip->dev, 0), 0x24,
USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_OTHER,