sound fixes for 6.19
A collection of small fixes. It became a bit larger than wished, but all of them are device-specific small fixes, and it should be still fairly safe to take at the last minute. Included are a few quirks and fixes for Intel, AMD, HD-audio, and USB-audio, as well as a race fix in aloop driver and corrections of Cirrus firmware kunit test -----BEGIN PGP SIGNATURE----- iQJCBAABCAAsFiEEIXTw5fNLNI7mMiVaLtJE4w1nLE8FAmmFtrEOHHRpd2FpQHN1 c2UuZGUACgkQLtJE4w1nLE+5qw//ZMzL++FkmAkZV+EHF6XqAaGd1PlA14s13Nzm +lDV8XqM1N5W3LIhUpANEf+DZB+9P/uy2IJqz7rCMAe5JiTdiovUplKg6VIwq1Y7 vemglGR1Y/nzxgAYtjI8H6F30mx/tufFRP3UXv4eKu20CwX5wK/AJwS71WKdjiXI YSeTtjhnkzVHiqvloDupZj7TI+jXD/1aHI0HebWs9NQmBHoZwLsDRY81ajUGEqvJ 0YWzCu08k3D7M4BB6W5gGDjuR2sSl6mIMU2g9erRu9Gbg4g82q5FCs1VKnmrDtCz UW3TRfdFI7/h9G2uJE7Go15LjgxzmotAEJNzgmy8cDzRhagqYjB1K3eBoQ9cEkv9 ZDl4buQSUIRnR+Bko5kg1t0XOyBzSFRHx8slgZNKwFVOHbLm78Gj0nvgjQqSHc/r S1vqZdPDk9zL0fIg9PoLYiVDFUO9RcT6ueaI1tbyWXRVAxvxdH/A2mfE+RwTufvR tDNV3IG53+JGayTu4f4tnQZxMzt4lVk9DR829+JIGkcGAHHURWXJmqwCbwnvJSVv /iLLzYxtBN0mFDmhIYDgIuJWiz9y7pFVXuUu82RzqzxzBFe0XgLhG3e23G0WzAmT DAUbXoXhZcEOdj3Cj5Dl//RAtWtv8v6o2VHcDLtUkIrwuCc2jgcrzEdQZbxxMbav rlksaV8= =wefJ -----END PGP SIGNATURE----- Merge tag 'sound-6.19' of git://git.kernel.org/pub/scm/linux/kernel/git/tiwai/sound Pull sound fixes from Takashi Iwai: "A collection of small fixes. It became a bit larger than wished, but all of them are device-specific small fixes, and it should be still fairly safe to take at the last minute. Included are a few quirks and fixes for Intel, AMD, HD-audio, and USB-audio, as well as a race fix in aloop driver and corrections of Cirrus firmware kunit test" * tag 'sound-6.19' of git://git.kernel.org/pub/scm/linux/kernel/git/tiwai/sound: ALSA: hda/realtek: Enable headset mic for Acer Nitro 5 ASoC: fsl_xcvr: fix missing lock in fsl_xcvr_mode_put() ASoC: dt-bindings: ti,tlv320aic3x: Add compatible string ti,tlv320aic23 ASoC: amd: fix memory leak in acp3x pdm dma ops ALSA: usb-audio: fix broken logic in snd_audigy2nx_led_update() ALSA: aloop: Fix racy access at PCM trigger ASoC: rt1320: fix intermittent no-sound issue ASoC: SOF: Intel: use hdev->info.link_mask directly firmware: cs_dsp: rate-limit log messages in KUnit builds ASoC: amd: yc: Add quirk for HP 200 G2a 16 ASoC: cs42l43: Correct handling of 3-pole jack load detection ASoC: Intel: sof_es8336: Add DMI quirk for Huawei BOD-WXX9 ASoC: sof_sdw: Add a quirk for Lenovo laptop using sidecar amps with cs42l43master
commit
8770bd8f91
|
|
@ -46,6 +46,7 @@ maintainers:
|
|||
properties:
|
||||
compatible:
|
||||
enum:
|
||||
- ti,tlv320aic23
|
||||
- ti,tlv320aic3x
|
||||
- ti,tlv320aic33
|
||||
- ti,tlv320aic3007
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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 */
|
||||
|
|
@ -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,
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
|
|
|||
|
|
@ -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,
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
|
|
|||
|
|
@ -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");
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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),
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -640,6 +640,13 @@ static const struct dmi_system_id yc_acp_quirk_table[] = {
|
|||
DMI_MATCH(DMI_BOARD_NAME, "8BD6"),
|
||||
}
|
||||
},
|
||||
{
|
||||
.driver_data = &acp6x_card,
|
||||
.matches = {
|
||||
DMI_MATCH(DMI_BOARD_VENDOR, "HP"),
|
||||
DMI_MATCH(DMI_BOARD_NAME, "8EE4"),
|
||||
}
|
||||
},
|
||||
{
|
||||
.driver_data = &acp6x_card,
|
||||
.matches = {
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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 },
|
||||
|
|
|
|||
|
|
@ -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 =
|
||||
|
|
|
|||
|
|
@ -334,6 +334,15 @@ static int sof_es8336_quirk_cb(const struct dmi_system_id *id)
|
|||
* if the topology file is modified as well.
|
||||
*/
|
||||
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 = {
|
||||
|
|
|
|||
|
|
@ -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 */
|
||||
|
|
|
|||
|
|
@ -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,
|
||||
|
|
|
|||
Loading…
Reference in New Issue