Skip to content

Commit 8770bd8

Browse files
committed
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 cs42l43
2 parents 5ca98c2 + 51db052 commit 8770bd8

18 files changed

Lines changed: 234 additions & 56 deletions

File tree

Documentation/devicetree/bindings/sound/ti,tlv320aic3x.yaml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,7 @@ maintainers:
4646
properties:
4747
compatible:
4848
enum:
49+
- ti,tlv320aic23
4950
- ti,tlv320aic3x
5051
- ti,tlv320aic33
5152
- ti,tlv320aic3007

drivers/firmware/cirrus/cs_dsp.c

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
* Cirrus Logic International Semiconductor Ltd.
1010
*/
1111

12+
#include <kunit/visibility.h>
1213
#include <linux/cleanup.h>
1314
#include <linux/ctype.h>
1415
#include <linux/debugfs.h>
@@ -24,6 +25,41 @@
2425
#include <linux/firmware/cirrus/cs_dsp.h>
2526
#include <linux/firmware/cirrus/wmfw.h>
2627

28+
#include "cs_dsp.h"
29+
30+
/*
31+
* When the KUnit test is running the error-case tests will cause a lot
32+
* of messages. Rate-limit to prevent overflowing the kernel log buffer
33+
* during KUnit test runs.
34+
*/
35+
#if IS_ENABLED(CONFIG_FW_CS_DSP_KUNIT_TEST)
36+
bool cs_dsp_suppress_err_messages;
37+
EXPORT_SYMBOL_IF_KUNIT(cs_dsp_suppress_err_messages);
38+
39+
bool cs_dsp_suppress_warn_messages;
40+
EXPORT_SYMBOL_IF_KUNIT(cs_dsp_suppress_warn_messages);
41+
42+
bool cs_dsp_suppress_info_messages;
43+
EXPORT_SYMBOL_IF_KUNIT(cs_dsp_suppress_info_messages);
44+
45+
#define cs_dsp_err(_dsp, fmt, ...) \
46+
do { \
47+
if (!cs_dsp_suppress_err_messages) \
48+
dev_err_ratelimited(_dsp->dev, "%s: " fmt, _dsp->name, ##__VA_ARGS__); \
49+
} while (false)
50+
#define cs_dsp_warn(_dsp, fmt, ...) \
51+
do { \
52+
if (!cs_dsp_suppress_warn_messages) \
53+
dev_warn_ratelimited(_dsp->dev, "%s: " fmt, _dsp->name, ##__VA_ARGS__); \
54+
} while (false)
55+
#define cs_dsp_info(_dsp, fmt, ...) \
56+
do { \
57+
if (!cs_dsp_suppress_info_messages) \
58+
dev_info_ratelimited(_dsp->dev, "%s: " fmt, _dsp->name, ##__VA_ARGS__); \
59+
} while (false)
60+
#define cs_dsp_dbg(_dsp, fmt, ...) \
61+
dev_dbg_ratelimited(_dsp->dev, "%s: " fmt, _dsp->name, ##__VA_ARGS__)
62+
#else
2763
#define cs_dsp_err(_dsp, fmt, ...) \
2864
dev_err(_dsp->dev, "%s: " fmt, _dsp->name, ##__VA_ARGS__)
2965
#define cs_dsp_warn(_dsp, fmt, ...) \
@@ -32,6 +68,7 @@
3268
dev_info(_dsp->dev, "%s: " fmt, _dsp->name, ##__VA_ARGS__)
3369
#define cs_dsp_dbg(_dsp, fmt, ...) \
3470
dev_dbg(_dsp->dev, "%s: " fmt, _dsp->name, ##__VA_ARGS__)
71+
#endif
3572

3673
#define ADSP1_CONTROL_1 0x00
3774
#define ADSP1_CONTROL_2 0x02

drivers/firmware/cirrus/cs_dsp.h

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
/* SPDX-License-Identifier: GPL-2.0-only */
2+
/*
3+
* cs_dsp.h -- Private header for cs_dsp driver.
4+
*
5+
* Copyright (C) 2026 Cirrus Logic, Inc. and
6+
* Cirrus Logic International Semiconductor Ltd.
7+
*/
8+
9+
#ifndef FW_CS_DSP_H
10+
#define FW_CS_DSP_H
11+
12+
#if IS_ENABLED(CONFIG_KUNIT)
13+
extern bool cs_dsp_suppress_err_messages;
14+
extern bool cs_dsp_suppress_warn_messages;
15+
extern bool cs_dsp_suppress_info_messages;
16+
#endif
17+
18+
#endif /* ifndef FW_CS_DSP_H */

drivers/firmware/cirrus/test/cs_dsp_test_bin.c

Lines changed: 21 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,8 @@
1717
#include <linux/random.h>
1818
#include <linux/regmap.h>
1919

20+
#include "../cs_dsp.h"
21+
2022
/*
2123
* Test method is:
2224
*
@@ -2224,7 +2226,22 @@ static int cs_dsp_bin_test_common_init(struct kunit *test, struct cs_dsp *dsp)
22242226
return ret;
22252227

22262228
/* Automatically call cs_dsp_remove() when test case ends */
2227-
return kunit_add_action_or_reset(priv->test, _cs_dsp_remove_wrapper, dsp);
2229+
ret = kunit_add_action_or_reset(priv->test, _cs_dsp_remove_wrapper, dsp);
2230+
if (ret)
2231+
return ret;
2232+
2233+
/*
2234+
* The large number of test cases will cause an unusually large amount
2235+
* of dev_info() messages from cs_dsp, so suppress these.
2236+
*/
2237+
cs_dsp_suppress_info_messages = true;
2238+
2239+
return 0;
2240+
}
2241+
2242+
static void cs_dsp_bin_test_exit(struct kunit *test)
2243+
{
2244+
cs_dsp_suppress_info_messages = false;
22282245
}
22292246

22302247
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[] = {
25362553
static struct kunit_suite cs_dsp_bin_test_halo = {
25372554
.name = "cs_dsp_bin_halo",
25382555
.init = cs_dsp_bin_test_halo_init,
2556+
.exit = cs_dsp_bin_test_exit,
25392557
.test_cases = cs_dsp_bin_test_cases_halo,
25402558
};
25412559

25422560
static struct kunit_suite cs_dsp_bin_test_adsp2_32bit = {
25432561
.name = "cs_dsp_bin_adsp2_32bit",
25442562
.init = cs_dsp_bin_test_adsp2_32bit_init,
2563+
.exit = cs_dsp_bin_test_exit,
25452564
.test_cases = cs_dsp_bin_test_cases_adsp2,
25462565
};
25472566

25482567
static struct kunit_suite cs_dsp_bin_test_adsp2_16bit = {
25492568
.name = "cs_dsp_bin_adsp2_16bit",
25502569
.init = cs_dsp_bin_test_adsp2_16bit_init,
2570+
.exit = cs_dsp_bin_test_exit,
25512571
.test_cases = cs_dsp_bin_test_cases_adsp2,
25522572
};
25532573

drivers/firmware/cirrus/test/cs_dsp_test_bin_error.c

Lines changed: 18 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,8 @@
1818
#include <linux/string.h>
1919
#include <linux/vmalloc.h>
2020

21+
#include "../cs_dsp.h"
22+
2123
KUNIT_DEFINE_ACTION_WRAPPER(_put_device_wrapper, put_device, struct device *);
2224
KUNIT_DEFINE_ACTION_WRAPPER(_cs_dsp_remove_wrapper, cs_dsp_remove, struct cs_dsp *);
2325

@@ -380,11 +382,9 @@ static void bin_block_payload_len_garbage(struct kunit *test)
380382

381383
static void cs_dsp_bin_err_test_exit(struct kunit *test)
382384
{
383-
/*
384-
* Testing error conditions can produce a lot of log output
385-
* from cs_dsp error messages, so rate limit the test cases.
386-
*/
387-
usleep_range(200, 500);
385+
cs_dsp_suppress_err_messages = false;
386+
cs_dsp_suppress_warn_messages = false;
387+
cs_dsp_suppress_info_messages = false;
388388
}
389389

390390
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
474474
return ret;
475475

476476
/* Automatically call cs_dsp_remove() when test case ends */
477-
return kunit_add_action_or_reset(priv->test, _cs_dsp_remove_wrapper, dsp);
477+
ret = kunit_add_action_or_reset(priv->test, _cs_dsp_remove_wrapper, dsp);
478+
if (ret)
479+
return ret;
480+
481+
/*
482+
* Testing error conditions can produce a lot of log output
483+
* from cs_dsp error messages, so suppress messages.
484+
*/
485+
cs_dsp_suppress_err_messages = true;
486+
cs_dsp_suppress_warn_messages = true;
487+
cs_dsp_suppress_info_messages = true;
488+
489+
return 0;
478490
}
479491

480492
static int cs_dsp_bin_err_test_halo_init(struct kunit *test)

drivers/firmware/cirrus/test/cs_dsp_test_wmfw.c

Lines changed: 25 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,8 @@
1818
#include <linux/string.h>
1919
#include <linux/vmalloc.h>
2020

21+
#include "../cs_dsp.h"
22+
2123
/*
2224
* Test method is:
2325
*
@@ -1853,7 +1855,22 @@ static int cs_dsp_wmfw_test_common_init(struct kunit *test, struct cs_dsp *dsp,
18531855
return ret;
18541856

18551857
/* Automatically call cs_dsp_remove() when test case ends */
1856-
return kunit_add_action_or_reset(priv->test, _cs_dsp_remove_wrapper, dsp);
1858+
ret = kunit_add_action_or_reset(priv->test, _cs_dsp_remove_wrapper, dsp);
1859+
if (ret)
1860+
return ret;
1861+
1862+
/*
1863+
* The large number of test cases will cause an unusually large amount
1864+
* of dev_info() messages from cs_dsp, so suppress these.
1865+
*/
1866+
cs_dsp_suppress_info_messages = true;
1867+
1868+
return 0;
1869+
}
1870+
1871+
static void cs_dsp_wmfw_test_exit(struct kunit *test)
1872+
{
1873+
cs_dsp_suppress_info_messages = false;
18571874
}
18581875

18591876
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[] = {
21632180
static struct kunit_suite cs_dsp_wmfw_test_halo = {
21642181
.name = "cs_dsp_wmfwV3_halo",
21652182
.init = cs_dsp_wmfw_test_halo_init,
2183+
.exit = cs_dsp_wmfw_test_exit,
21662184
.test_cases = cs_dsp_wmfw_test_cases_halo,
21672185
};
21682186

21692187
static struct kunit_suite cs_dsp_wmfw_test_adsp2_32bit_wmfw0 = {
21702188
.name = "cs_dsp_wmfwV0_adsp2_32bit",
21712189
.init = cs_dsp_wmfw_test_adsp2_32bit_wmfw0_init,
2190+
.exit = cs_dsp_wmfw_test_exit,
21722191
.test_cases = cs_dsp_wmfw_test_cases_adsp2,
21732192
};
21742193

21752194
static struct kunit_suite cs_dsp_wmfw_test_adsp2_32bit_wmfw1 = {
21762195
.name = "cs_dsp_wmfwV1_adsp2_32bit",
21772196
.init = cs_dsp_wmfw_test_adsp2_32bit_wmfw1_init,
2197+
.exit = cs_dsp_wmfw_test_exit,
21782198
.test_cases = cs_dsp_wmfw_test_cases_adsp2,
21792199
};
21802200

21812201
static struct kunit_suite cs_dsp_wmfw_test_adsp2_32bit_wmfw2 = {
21822202
.name = "cs_dsp_wmfwV2_adsp2_32bit",
21832203
.init = cs_dsp_wmfw_test_adsp2_32bit_wmfw2_init,
2204+
.exit = cs_dsp_wmfw_test_exit,
21842205
.test_cases = cs_dsp_wmfw_test_cases_adsp2,
21852206
};
21862207

21872208
static struct kunit_suite cs_dsp_wmfw_test_adsp2_16bit_wmfw0 = {
21882209
.name = "cs_dsp_wmfwV0_adsp2_16bit",
21892210
.init = cs_dsp_wmfw_test_adsp2_16bit_wmfw0_init,
2211+
.exit = cs_dsp_wmfw_test_exit,
21902212
.test_cases = cs_dsp_wmfw_test_cases_adsp2,
21912213
};
21922214

21932215
static struct kunit_suite cs_dsp_wmfw_test_adsp2_16bit_wmfw1 = {
21942216
.name = "cs_dsp_wmfwV1_adsp2_16bit",
21952217
.init = cs_dsp_wmfw_test_adsp2_16bit_wmfw1_init,
2218+
.exit = cs_dsp_wmfw_test_exit,
21962219
.test_cases = cs_dsp_wmfw_test_cases_adsp2,
21972220
};
21982221

21992222
static struct kunit_suite cs_dsp_wmfw_test_adsp2_16bit_wmfw2 = {
22002223
.name = "cs_dsp_wmfwV2_adsp2_16bit",
22012224
.init = cs_dsp_wmfw_test_adsp2_16bit_wmfw2_init,
2225+
.exit = cs_dsp_wmfw_test_exit,
22022226
.test_cases = cs_dsp_wmfw_test_cases_adsp2,
22032227
};
22042228

drivers/firmware/cirrus/test/cs_dsp_test_wmfw_error.c

Lines changed: 18 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,8 @@
1818
#include <linux/string.h>
1919
#include <linux/vmalloc.h>
2020

21+
#include "../cs_dsp.h"
22+
2123
KUNIT_DEFINE_ACTION_WRAPPER(_put_device_wrapper, put_device, struct device *);
2224
KUNIT_DEFINE_ACTION_WRAPPER(_cs_dsp_remove_wrapper, cs_dsp_remove, struct cs_dsp *);
2325

@@ -989,11 +991,9 @@ static void wmfw_v2_coeff_description_exceeds_block(struct kunit *test)
989991

990992
static void cs_dsp_wmfw_err_test_exit(struct kunit *test)
991993
{
992-
/*
993-
* Testing error conditions can produce a lot of log output
994-
* from cs_dsp error messages, so rate limit the test cases.
995-
*/
996-
usleep_range(200, 500);
994+
cs_dsp_suppress_err_messages = false;
995+
cs_dsp_suppress_warn_messages = false;
996+
cs_dsp_suppress_info_messages = false;
997997
}
998998

999999
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
10721072
return ret;
10731073

10741074
/* Automatically call cs_dsp_remove() when test case ends */
1075-
return kunit_add_action_or_reset(priv->test, _cs_dsp_remove_wrapper, dsp);
1075+
ret = kunit_add_action_or_reset(priv->test, _cs_dsp_remove_wrapper, dsp);
1076+
if (ret)
1077+
return ret;
1078+
1079+
/*
1080+
* Testing error conditions can produce a lot of log output
1081+
* from cs_dsp error messages, so suppress messages.
1082+
*/
1083+
cs_dsp_suppress_err_messages = true;
1084+
cs_dsp_suppress_warn_messages = true;
1085+
cs_dsp_suppress_info_messages = true;
1086+
1087+
return 0;
10761088
}
10771089

10781090
static int cs_dsp_wmfw_err_test_halo_init(struct kunit *test)

drivers/firmware/cirrus/test/cs_dsp_tests.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,3 +12,4 @@ MODULE_AUTHOR("Richard Fitzgerald <[email protected]>");
1212
MODULE_LICENSE("GPL");
1313
MODULE_IMPORT_NS("FW_CS_DSP");
1414
MODULE_IMPORT_NS("FW_CS_DSP_KUNIT_TEST_UTILS");
15+
MODULE_IMPORT_NS("EXPORTED_FOR_KUNIT_TESTING");

sound/drivers/aloop.c

Lines changed: 36 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -336,37 +336,43 @@ static bool is_access_interleaved(snd_pcm_access_t access)
336336

337337
static int loopback_check_format(struct loopback_cable *cable, int stream)
338338
{
339+
struct loopback_pcm *dpcm_play, *dpcm_capt;
339340
struct snd_pcm_runtime *runtime, *cruntime;
340341
struct loopback_setup *setup;
341342
struct snd_card *card;
343+
bool stop_capture = false;
342344
int check;
343345

344-
if (cable->valid != CABLE_VALID_BOTH) {
345-
if (stream == SNDRV_PCM_STREAM_PLAYBACK)
346-
goto __notify;
347-
return 0;
348-
}
349-
runtime = cable->streams[SNDRV_PCM_STREAM_PLAYBACK]->
350-
substream->runtime;
351-
cruntime = cable->streams[SNDRV_PCM_STREAM_CAPTURE]->
352-
substream->runtime;
353-
check = runtime->format != cruntime->format ||
354-
runtime->rate != cruntime->rate ||
355-
runtime->channels != cruntime->channels ||
356-
is_access_interleaved(runtime->access) !=
357-
is_access_interleaved(cruntime->access);
358-
if (!check)
359-
return 0;
360-
if (stream == SNDRV_PCM_STREAM_CAPTURE) {
361-
return -EIO;
362-
} else {
363-
snd_pcm_stop(cable->streams[SNDRV_PCM_STREAM_CAPTURE]->
364-
substream, SNDRV_PCM_STATE_DRAINING);
365-
__notify:
366-
runtime = cable->streams[SNDRV_PCM_STREAM_PLAYBACK]->
367-
substream->runtime;
368-
setup = get_setup(cable->streams[SNDRV_PCM_STREAM_PLAYBACK]);
369-
card = cable->streams[SNDRV_PCM_STREAM_PLAYBACK]->loopback->card;
346+
scoped_guard(spinlock_irqsave, &cable->lock) {
347+
dpcm_play = cable->streams[SNDRV_PCM_STREAM_PLAYBACK];
348+
dpcm_capt = cable->streams[SNDRV_PCM_STREAM_CAPTURE];
349+
350+
if (cable->valid != CABLE_VALID_BOTH) {
351+
if (stream == SNDRV_PCM_STREAM_CAPTURE || !dpcm_play)
352+
return 0;
353+
} else {
354+
if (!dpcm_play || !dpcm_capt)
355+
return -EIO;
356+
runtime = dpcm_play->substream->runtime;
357+
cruntime = dpcm_capt->substream->runtime;
358+
if (!runtime || !cruntime)
359+
return -EIO;
360+
check = runtime->format != cruntime->format ||
361+
runtime->rate != cruntime->rate ||
362+
runtime->channels != cruntime->channels ||
363+
is_access_interleaved(runtime->access) !=
364+
is_access_interleaved(cruntime->access);
365+
if (!check)
366+
return 0;
367+
if (stream == SNDRV_PCM_STREAM_CAPTURE)
368+
return -EIO;
369+
else if (cruntime->state == SNDRV_PCM_STATE_RUNNING)
370+
stop_capture = true;
371+
}
372+
373+
setup = get_setup(dpcm_play);
374+
card = dpcm_play->loopback->card;
375+
runtime = dpcm_play->substream->runtime;
370376
if (setup->format != runtime->format) {
371377
snd_ctl_notify(card, SNDRV_CTL_EVENT_MASK_VALUE,
372378
&setup->format_id);
@@ -389,6 +395,10 @@ static int loopback_check_format(struct loopback_cable *cable, int stream)
389395
setup->access = runtime->access;
390396
}
391397
}
398+
399+
if (stop_capture)
400+
snd_pcm_stop(dpcm_capt->substream, SNDRV_PCM_STATE_DRAINING);
401+
392402
return 0;
393403
}
394404

0 commit comments

Comments
 (0)