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

+234 -56
+1
Documentation/devicetree/bindings/sound/ti,tlv320aic3x.yaml
··· 46 properties: 47 compatible: 48 enum: 49 - ti,tlv320aic3x 50 - ti,tlv320aic33 51 - ti,tlv320aic3007
··· 46 properties: 47 compatible: 48 enum: 49 + - ti,tlv320aic23 50 - ti,tlv320aic3x 51 - ti,tlv320aic33 52 - ti,tlv320aic3007
+37
drivers/firmware/cirrus/cs_dsp.c
··· 9 * Cirrus Logic International Semiconductor Ltd. 10 */ 11 12 #include <linux/cleanup.h> 13 #include <linux/ctype.h> 14 #include <linux/debugfs.h> ··· 25 #include <linux/firmware/cirrus/cs_dsp.h> 26 #include <linux/firmware/cirrus/wmfw.h> 27 28 #define cs_dsp_err(_dsp, fmt, ...) \ 29 dev_err(_dsp->dev, "%s: " fmt, _dsp->name, ##__VA_ARGS__) 30 #define cs_dsp_warn(_dsp, fmt, ...) \ ··· 68 dev_info(_dsp->dev, "%s: " fmt, _dsp->name, ##__VA_ARGS__) 69 #define cs_dsp_dbg(_dsp, fmt, ...) \ 70 dev_dbg(_dsp->dev, "%s: " fmt, _dsp->name, ##__VA_ARGS__) 71 72 #define ADSP1_CONTROL_1 0x00 73 #define ADSP1_CONTROL_2 0x02
··· 9 * Cirrus Logic International Semiconductor Ltd. 10 */ 11 12 + #include <kunit/visibility.h> 13 #include <linux/cleanup.h> 14 #include <linux/ctype.h> 15 #include <linux/debugfs.h> ··· 24 #include <linux/firmware/cirrus/cs_dsp.h> 25 #include <linux/firmware/cirrus/wmfw.h> 26 27 + #include "cs_dsp.h" 28 + 29 + /* 30 + * When the KUnit test is running the error-case tests will cause a lot 31 + * of messages. Rate-limit to prevent overflowing the kernel log buffer 32 + * during KUnit test runs. 33 + */ 34 + #if IS_ENABLED(CONFIG_FW_CS_DSP_KUNIT_TEST) 35 + bool cs_dsp_suppress_err_messages; 36 + EXPORT_SYMBOL_IF_KUNIT(cs_dsp_suppress_err_messages); 37 + 38 + bool cs_dsp_suppress_warn_messages; 39 + EXPORT_SYMBOL_IF_KUNIT(cs_dsp_suppress_warn_messages); 40 + 41 + bool cs_dsp_suppress_info_messages; 42 + EXPORT_SYMBOL_IF_KUNIT(cs_dsp_suppress_info_messages); 43 + 44 + #define cs_dsp_err(_dsp, fmt, ...) \ 45 + do { \ 46 + if (!cs_dsp_suppress_err_messages) \ 47 + dev_err_ratelimited(_dsp->dev, "%s: " fmt, _dsp->name, ##__VA_ARGS__); \ 48 + } while (false) 49 + #define cs_dsp_warn(_dsp, fmt, ...) \ 50 + do { \ 51 + if (!cs_dsp_suppress_warn_messages) \ 52 + dev_warn_ratelimited(_dsp->dev, "%s: " fmt, _dsp->name, ##__VA_ARGS__); \ 53 + } while (false) 54 + #define cs_dsp_info(_dsp, fmt, ...) \ 55 + do { \ 56 + if (!cs_dsp_suppress_info_messages) \ 57 + dev_info_ratelimited(_dsp->dev, "%s: " fmt, _dsp->name, ##__VA_ARGS__); \ 58 + } while (false) 59 + #define cs_dsp_dbg(_dsp, fmt, ...) \ 60 + dev_dbg_ratelimited(_dsp->dev, "%s: " fmt, _dsp->name, ##__VA_ARGS__) 61 + #else 62 #define cs_dsp_err(_dsp, fmt, ...) \ 63 dev_err(_dsp->dev, "%s: " fmt, _dsp->name, ##__VA_ARGS__) 64 #define cs_dsp_warn(_dsp, fmt, ...) \ ··· 32 dev_info(_dsp->dev, "%s: " fmt, _dsp->name, ##__VA_ARGS__) 33 #define cs_dsp_dbg(_dsp, fmt, ...) \ 34 dev_dbg(_dsp->dev, "%s: " fmt, _dsp->name, ##__VA_ARGS__) 35 + #endif 36 37 #define ADSP1_CONTROL_1 0x00 38 #define ADSP1_CONTROL_2 0x02
+18
drivers/firmware/cirrus/cs_dsp.h
···
··· 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 */
+21 -1
drivers/firmware/cirrus/test/cs_dsp_test_bin.c
··· 17 #include <linux/random.h> 18 #include <linux/regmap.h> 19 20 /* 21 * Test method is: 22 * ··· 2226 return ret; 2227 2228 /* Automatically call cs_dsp_remove() when test case ends */ 2229 - return kunit_add_action_or_reset(priv->test, _cs_dsp_remove_wrapper, dsp); 2230 } 2231 2232 static int cs_dsp_bin_test_halo_init(struct kunit *test) ··· 2553 static struct kunit_suite cs_dsp_bin_test_halo = { 2554 .name = "cs_dsp_bin_halo", 2555 .init = cs_dsp_bin_test_halo_init, 2556 .test_cases = cs_dsp_bin_test_cases_halo, 2557 }; 2558 2559 static struct kunit_suite cs_dsp_bin_test_adsp2_32bit = { 2560 .name = "cs_dsp_bin_adsp2_32bit", 2561 .init = cs_dsp_bin_test_adsp2_32bit_init, 2562 .test_cases = cs_dsp_bin_test_cases_adsp2, 2563 }; 2564 2565 static struct kunit_suite cs_dsp_bin_test_adsp2_16bit = { 2566 .name = "cs_dsp_bin_adsp2_16bit", 2567 .init = cs_dsp_bin_test_adsp2_16bit_init, 2568 .test_cases = cs_dsp_bin_test_cases_adsp2, 2569 }; 2570
··· 17 #include <linux/random.h> 18 #include <linux/regmap.h> 19 20 + #include "../cs_dsp.h" 21 + 22 /* 23 * Test method is: 24 * ··· 2224 return ret; 2225 2226 /* Automatically call cs_dsp_remove() when test case ends */ 2227 + ret = kunit_add_action_or_reset(priv->test, _cs_dsp_remove_wrapper, dsp); 2228 + if (ret) 2229 + return ret; 2230 + 2231 + /* 2232 + * The large number of test cases will cause an unusually large amount 2233 + * of dev_info() messages from cs_dsp, so suppress these. 2234 + */ 2235 + cs_dsp_suppress_info_messages = true; 2236 + 2237 + return 0; 2238 + } 2239 + 2240 + static void cs_dsp_bin_test_exit(struct kunit *test) 2241 + { 2242 + cs_dsp_suppress_info_messages = false; 2243 } 2244 2245 static int cs_dsp_bin_test_halo_init(struct kunit *test) ··· 2536 static struct kunit_suite cs_dsp_bin_test_halo = { 2537 .name = "cs_dsp_bin_halo", 2538 .init = cs_dsp_bin_test_halo_init, 2539 + .exit = cs_dsp_bin_test_exit, 2540 .test_cases = cs_dsp_bin_test_cases_halo, 2541 }; 2542 2543 static struct kunit_suite cs_dsp_bin_test_adsp2_32bit = { 2544 .name = "cs_dsp_bin_adsp2_32bit", 2545 .init = cs_dsp_bin_test_adsp2_32bit_init, 2546 + .exit = cs_dsp_bin_test_exit, 2547 .test_cases = cs_dsp_bin_test_cases_adsp2, 2548 }; 2549 2550 static struct kunit_suite cs_dsp_bin_test_adsp2_16bit = { 2551 .name = "cs_dsp_bin_adsp2_16bit", 2552 .init = cs_dsp_bin_test_adsp2_16bit_init, 2553 + .exit = cs_dsp_bin_test_exit, 2554 .test_cases = cs_dsp_bin_test_cases_adsp2, 2555 }; 2556
+18 -6
drivers/firmware/cirrus/test/cs_dsp_test_bin_error.c
··· 18 #include <linux/string.h> 19 #include <linux/vmalloc.h> 20 21 KUNIT_DEFINE_ACTION_WRAPPER(_put_device_wrapper, put_device, struct device *); 22 KUNIT_DEFINE_ACTION_WRAPPER(_cs_dsp_remove_wrapper, cs_dsp_remove, struct cs_dsp *); 23 ··· 382 383 static void cs_dsp_bin_err_test_exit(struct kunit *test) 384 { 385 - /* 386 - * Testing error conditions can produce a lot of log output 387 - * from cs_dsp error messages, so rate limit the test cases. 388 - */ 389 - usleep_range(200, 500); 390 } 391 392 static int cs_dsp_bin_err_test_common_init(struct kunit *test, struct cs_dsp *dsp, ··· 474 return ret; 475 476 /* Automatically call cs_dsp_remove() when test case ends */ 477 - return kunit_add_action_or_reset(priv->test, _cs_dsp_remove_wrapper, dsp); 478 } 479 480 static int cs_dsp_bin_err_test_halo_init(struct kunit *test)
··· 18 #include <linux/string.h> 19 #include <linux/vmalloc.h> 20 21 + #include "../cs_dsp.h" 22 + 23 KUNIT_DEFINE_ACTION_WRAPPER(_put_device_wrapper, put_device, struct device *); 24 KUNIT_DEFINE_ACTION_WRAPPER(_cs_dsp_remove_wrapper, cs_dsp_remove, struct cs_dsp *); 25 ··· 380 381 static void cs_dsp_bin_err_test_exit(struct kunit *test) 382 { 383 + cs_dsp_suppress_err_messages = false; 384 + cs_dsp_suppress_warn_messages = false; 385 + cs_dsp_suppress_info_messages = false; 386 } 387 388 static int cs_dsp_bin_err_test_common_init(struct kunit *test, struct cs_dsp *dsp, ··· 474 return ret; 475 476 /* Automatically call cs_dsp_remove() when test case ends */ 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; 490 } 491 492 static int cs_dsp_bin_err_test_halo_init(struct kunit *test)
+25 -1
drivers/firmware/cirrus/test/cs_dsp_test_wmfw.c
··· 18 #include <linux/string.h> 19 #include <linux/vmalloc.h> 20 21 /* 22 * Test method is: 23 * ··· 1855 return ret; 1856 1857 /* Automatically call cs_dsp_remove() when test case ends */ 1858 - return kunit_add_action_or_reset(priv->test, _cs_dsp_remove_wrapper, dsp); 1859 } 1860 1861 static int cs_dsp_wmfw_test_halo_init(struct kunit *test) ··· 2180 static struct kunit_suite cs_dsp_wmfw_test_halo = { 2181 .name = "cs_dsp_wmfwV3_halo", 2182 .init = cs_dsp_wmfw_test_halo_init, 2183 .test_cases = cs_dsp_wmfw_test_cases_halo, 2184 }; 2185 2186 static struct kunit_suite cs_dsp_wmfw_test_adsp2_32bit_wmfw0 = { 2187 .name = "cs_dsp_wmfwV0_adsp2_32bit", 2188 .init = cs_dsp_wmfw_test_adsp2_32bit_wmfw0_init, 2189 .test_cases = cs_dsp_wmfw_test_cases_adsp2, 2190 }; 2191 2192 static struct kunit_suite cs_dsp_wmfw_test_adsp2_32bit_wmfw1 = { 2193 .name = "cs_dsp_wmfwV1_adsp2_32bit", 2194 .init = cs_dsp_wmfw_test_adsp2_32bit_wmfw1_init, 2195 .test_cases = cs_dsp_wmfw_test_cases_adsp2, 2196 }; 2197 2198 static struct kunit_suite cs_dsp_wmfw_test_adsp2_32bit_wmfw2 = { 2199 .name = "cs_dsp_wmfwV2_adsp2_32bit", 2200 .init = cs_dsp_wmfw_test_adsp2_32bit_wmfw2_init, 2201 .test_cases = cs_dsp_wmfw_test_cases_adsp2, 2202 }; 2203 2204 static struct kunit_suite cs_dsp_wmfw_test_adsp2_16bit_wmfw0 = { 2205 .name = "cs_dsp_wmfwV0_adsp2_16bit", 2206 .init = cs_dsp_wmfw_test_adsp2_16bit_wmfw0_init, 2207 .test_cases = cs_dsp_wmfw_test_cases_adsp2, 2208 }; 2209 2210 static struct kunit_suite cs_dsp_wmfw_test_adsp2_16bit_wmfw1 = { 2211 .name = "cs_dsp_wmfwV1_adsp2_16bit", 2212 .init = cs_dsp_wmfw_test_adsp2_16bit_wmfw1_init, 2213 .test_cases = cs_dsp_wmfw_test_cases_adsp2, 2214 }; 2215 2216 static struct kunit_suite cs_dsp_wmfw_test_adsp2_16bit_wmfw2 = { 2217 .name = "cs_dsp_wmfwV2_adsp2_16bit", 2218 .init = cs_dsp_wmfw_test_adsp2_16bit_wmfw2_init, 2219 .test_cases = cs_dsp_wmfw_test_cases_adsp2, 2220 }; 2221
··· 18 #include <linux/string.h> 19 #include <linux/vmalloc.h> 20 21 + #include "../cs_dsp.h" 22 + 23 /* 24 * Test method is: 25 * ··· 1853 return ret; 1854 1855 /* Automatically call cs_dsp_remove() when test case ends */ 1856 + ret = kunit_add_action_or_reset(priv->test, _cs_dsp_remove_wrapper, dsp); 1857 + if (ret) 1858 + return ret; 1859 + 1860 + /* 1861 + * The large number of test cases will cause an unusually large amount 1862 + * of dev_info() messages from cs_dsp, so suppress these. 1863 + */ 1864 + cs_dsp_suppress_info_messages = true; 1865 + 1866 + return 0; 1867 + } 1868 + 1869 + static void cs_dsp_wmfw_test_exit(struct kunit *test) 1870 + { 1871 + cs_dsp_suppress_info_messages = false; 1872 } 1873 1874 static int cs_dsp_wmfw_test_halo_init(struct kunit *test) ··· 2163 static struct kunit_suite cs_dsp_wmfw_test_halo = { 2164 .name = "cs_dsp_wmfwV3_halo", 2165 .init = cs_dsp_wmfw_test_halo_init, 2166 + .exit = cs_dsp_wmfw_test_exit, 2167 .test_cases = cs_dsp_wmfw_test_cases_halo, 2168 }; 2169 2170 static struct kunit_suite cs_dsp_wmfw_test_adsp2_32bit_wmfw0 = { 2171 .name = "cs_dsp_wmfwV0_adsp2_32bit", 2172 .init = cs_dsp_wmfw_test_adsp2_32bit_wmfw0_init, 2173 + .exit = cs_dsp_wmfw_test_exit, 2174 .test_cases = cs_dsp_wmfw_test_cases_adsp2, 2175 }; 2176 2177 static struct kunit_suite cs_dsp_wmfw_test_adsp2_32bit_wmfw1 = { 2178 .name = "cs_dsp_wmfwV1_adsp2_32bit", 2179 .init = cs_dsp_wmfw_test_adsp2_32bit_wmfw1_init, 2180 + .exit = cs_dsp_wmfw_test_exit, 2181 .test_cases = cs_dsp_wmfw_test_cases_adsp2, 2182 }; 2183 2184 static struct kunit_suite cs_dsp_wmfw_test_adsp2_32bit_wmfw2 = { 2185 .name = "cs_dsp_wmfwV2_adsp2_32bit", 2186 .init = cs_dsp_wmfw_test_adsp2_32bit_wmfw2_init, 2187 + .exit = cs_dsp_wmfw_test_exit, 2188 .test_cases = cs_dsp_wmfw_test_cases_adsp2, 2189 }; 2190 2191 static struct kunit_suite cs_dsp_wmfw_test_adsp2_16bit_wmfw0 = { 2192 .name = "cs_dsp_wmfwV0_adsp2_16bit", 2193 .init = cs_dsp_wmfw_test_adsp2_16bit_wmfw0_init, 2194 + .exit = cs_dsp_wmfw_test_exit, 2195 .test_cases = cs_dsp_wmfw_test_cases_adsp2, 2196 }; 2197 2198 static struct kunit_suite cs_dsp_wmfw_test_adsp2_16bit_wmfw1 = { 2199 .name = "cs_dsp_wmfwV1_adsp2_16bit", 2200 .init = cs_dsp_wmfw_test_adsp2_16bit_wmfw1_init, 2201 + .exit = cs_dsp_wmfw_test_exit, 2202 .test_cases = cs_dsp_wmfw_test_cases_adsp2, 2203 }; 2204 2205 static struct kunit_suite cs_dsp_wmfw_test_adsp2_16bit_wmfw2 = { 2206 .name = "cs_dsp_wmfwV2_adsp2_16bit", 2207 .init = cs_dsp_wmfw_test_adsp2_16bit_wmfw2_init, 2208 + .exit = cs_dsp_wmfw_test_exit, 2209 .test_cases = cs_dsp_wmfw_test_cases_adsp2, 2210 }; 2211
+18 -6
drivers/firmware/cirrus/test/cs_dsp_test_wmfw_error.c
··· 18 #include <linux/string.h> 19 #include <linux/vmalloc.h> 20 21 KUNIT_DEFINE_ACTION_WRAPPER(_put_device_wrapper, put_device, struct device *); 22 KUNIT_DEFINE_ACTION_WRAPPER(_cs_dsp_remove_wrapper, cs_dsp_remove, struct cs_dsp *); 23 ··· 991 992 static void cs_dsp_wmfw_err_test_exit(struct kunit *test) 993 { 994 - /* 995 - * Testing error conditions can produce a lot of log output 996 - * from cs_dsp error messages, so rate limit the test cases. 997 - */ 998 - usleep_range(200, 500); 999 } 1000 1001 static int cs_dsp_wmfw_err_test_common_init(struct kunit *test, struct cs_dsp *dsp, ··· 1072 return ret; 1073 1074 /* Automatically call cs_dsp_remove() when test case ends */ 1075 - return kunit_add_action_or_reset(priv->test, _cs_dsp_remove_wrapper, dsp); 1076 } 1077 1078 static int cs_dsp_wmfw_err_test_halo_init(struct kunit *test)
··· 18 #include <linux/string.h> 19 #include <linux/vmalloc.h> 20 21 + #include "../cs_dsp.h" 22 + 23 KUNIT_DEFINE_ACTION_WRAPPER(_put_device_wrapper, put_device, struct device *); 24 KUNIT_DEFINE_ACTION_WRAPPER(_cs_dsp_remove_wrapper, cs_dsp_remove, struct cs_dsp *); 25 ··· 989 990 static void cs_dsp_wmfw_err_test_exit(struct kunit *test) 991 { 992 + cs_dsp_suppress_err_messages = false; 993 + cs_dsp_suppress_warn_messages = false; 994 + cs_dsp_suppress_info_messages = false; 995 } 996 997 static int cs_dsp_wmfw_err_test_common_init(struct kunit *test, struct cs_dsp *dsp, ··· 1072 return ret; 1073 1074 /* Automatically call cs_dsp_remove() when test case ends */ 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; 1088 } 1089 1090 static int cs_dsp_wmfw_err_test_halo_init(struct kunit *test)
+1
drivers/firmware/cirrus/test/cs_dsp_tests.c
··· 12 MODULE_LICENSE("GPL"); 13 MODULE_IMPORT_NS("FW_CS_DSP"); 14 MODULE_IMPORT_NS("FW_CS_DSP_KUNIT_TEST_UTILS");
··· 12 MODULE_LICENSE("GPL"); 13 MODULE_IMPORT_NS("FW_CS_DSP"); 14 MODULE_IMPORT_NS("FW_CS_DSP_KUNIT_TEST_UTILS"); 15 + MODULE_IMPORT_NS("EXPORTED_FOR_KUNIT_TESTING");
+36 -26
sound/drivers/aloop.c
··· 336 337 static int loopback_check_format(struct loopback_cable *cable, int stream) 338 { 339 struct snd_pcm_runtime *runtime, *cruntime; 340 struct loopback_setup *setup; 341 struct snd_card *card; 342 int check; 343 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; 370 if (setup->format != runtime->format) { 371 snd_ctl_notify(card, SNDRV_CTL_EVENT_MASK_VALUE, 372 &setup->format_id); ··· 395 setup->access = runtime->access; 396 } 397 } 398 return 0; 399 } 400
··· 336 337 static int loopback_check_format(struct loopback_cable *cable, int stream) 338 { 339 + struct loopback_pcm *dpcm_play, *dpcm_capt; 340 struct snd_pcm_runtime *runtime, *cruntime; 341 struct loopback_setup *setup; 342 struct snd_card *card; 343 + bool stop_capture = false; 344 int check; 345 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; 376 if (setup->format != runtime->format) { 377 snd_ctl_notify(card, SNDRV_CTL_EVENT_MASK_VALUE, 378 &setup->format_id); ··· 389 setup->access = runtime->access; 390 } 391 } 392 + 393 + if (stop_capture) 394 + snd_pcm_stop(dpcm_capt->substream, SNDRV_PCM_STATE_DRAINING); 395 + 396 return 0; 397 } 398
+1
sound/hda/codecs/realtek/alc269.c
··· 6353 SND_PCI_QUIRK(0x1025, 0x1430, "Acer TravelMate B311R-31", ALC256_FIXUP_ACER_MIC_NO_PRESENCE), 6354 SND_PCI_QUIRK(0x1025, 0x1466, "Acer Aspire A515-56", ALC255_FIXUP_ACER_HEADPHONE_AND_MIC), 6355 SND_PCI_QUIRK(0x1025, 0x1534, "Acer Predator PH315-54", ALC255_FIXUP_ACER_MIC_NO_PRESENCE), 6356 SND_PCI_QUIRK(0x1025, 0x159c, "Acer Nitro 5 AN515-58", ALC2XX_FIXUP_HEADSET_MIC), 6357 SND_PCI_QUIRK(0x1025, 0x1597, "Acer Nitro 5 AN517-55", ALC2XX_FIXUP_HEADSET_MIC), 6358 SND_PCI_QUIRK(0x1025, 0x169a, "Acer Swift SFG16", ALC256_FIXUP_ACER_SFG16_MICMUTE_LED),
··· 6353 SND_PCI_QUIRK(0x1025, 0x1430, "Acer TravelMate B311R-31", ALC256_FIXUP_ACER_MIC_NO_PRESENCE), 6354 SND_PCI_QUIRK(0x1025, 0x1466, "Acer Aspire A515-56", ALC255_FIXUP_ACER_HEADPHONE_AND_MIC), 6355 SND_PCI_QUIRK(0x1025, 0x1534, "Acer Predator PH315-54", ALC255_FIXUP_ACER_MIC_NO_PRESENCE), 6356 + SND_PCI_QUIRK(0x1025, 0x1539, "Acer Nitro 5 AN515-57", ALC2XX_FIXUP_HEADSET_MIC), 6357 SND_PCI_QUIRK(0x1025, 0x159c, "Acer Nitro 5 AN515-58", ALC2XX_FIXUP_HEADSET_MIC), 6358 SND_PCI_QUIRK(0x1025, 0x1597, "Acer Nitro 5 AN517-55", ALC2XX_FIXUP_HEADSET_MIC), 6359 SND_PCI_QUIRK(0x1025, 0x169a, "Acer Swift SFG16", ALC256_FIXUP_ACER_SFG16_MICMUTE_LED),
+2
sound/soc/amd/renoir/acp3x-pdm-dma.c
··· 301 struct snd_pcm_substream *substream) 302 { 303 struct pdm_dev_data *adata = dev_get_drvdata(component->dev); 304 305 disable_pdm_interrupts(adata->acp_base); 306 adata->capture_stream = NULL; 307 return 0; 308 } 309
··· 301 struct snd_pcm_substream *substream) 302 { 303 struct pdm_dev_data *adata = dev_get_drvdata(component->dev); 304 + struct pdm_stream_instance *rtd = substream->runtime->private_data; 305 306 disable_pdm_interrupts(adata->acp_base); 307 adata->capture_stream = NULL; 308 + kfree(rtd); 309 return 0; 310 } 311
+7
sound/soc/amd/yc/acp6x-mach.c
··· 643 { 644 .driver_data = &acp6x_card, 645 .matches = { 646 DMI_MATCH(DMI_BOARD_VENDOR, "MECHREVO"), 647 DMI_MATCH(DMI_BOARD_NAME, "MRID6"), 648 }
··· 643 { 644 .driver_data = &acp6x_card, 645 .matches = { 646 + DMI_MATCH(DMI_BOARD_VENDOR, "HP"), 647 + DMI_MATCH(DMI_BOARD_NAME, "8EE4"), 648 + } 649 + }, 650 + { 651 + .driver_data = &acp6x_card, 652 + .matches = { 653 DMI_MATCH(DMI_BOARD_VENDOR, "MECHREVO"), 654 DMI_MATCH(DMI_BOARD_NAME, "MRID6"), 655 }
+31 -6
sound/soc/codecs/cs42l43-jack.c
··· 496 pm_runtime_put_autosuspend(priv->dev); 497 } 498 499 - static void cs42l43_start_load_detect(struct cs42l43_codec *priv) 500 { 501 struct cs42l43 *cs42l43 = priv->core; 502 ··· 535 if (!time_left) 536 dev_err(priv->dev, "Load detect HP power down timed out\n"); 537 } 538 539 regmap_update_bits(cs42l43->regmap, CS42L43_BLOCK_EN3, 540 CS42L43_ADC1_EN_MASK | CS42L43_ADC2_EN_MASK, 0); ··· 623 624 reinit_completion(&priv->load_detect); 625 626 - cs42l43_start_load_detect(priv); 627 time_left = wait_for_completion_timeout(&priv->load_detect, 628 msecs_to_jiffies(CS42L43_LOAD_TIMEOUT_MS)); 629 cs42l43_stop_load_detect(priv); ··· 647 } 648 649 switch (val & CS42L43_AMP3_RES_DET_MASK) { 650 - case 0x0: // low impedance 651 - case 0x1: // high impedance 652 return CS42L43_JACK_HEADPHONE; 653 - case 0x2: // lineout 654 - case 0x3: // Open circuit 655 return CS42L43_JACK_LINEOUT; 656 default: 657 return -EINVAL;
··· 496 pm_runtime_put_autosuspend(priv->dev); 497 } 498 499 + static const struct reg_sequence cs42l43_3pole_patch[] = { 500 + { 0x4000, 0x00000055 }, 501 + { 0x4000, 0x000000AA }, 502 + { 0x17420, 0x8500F300 }, 503 + { 0x17424, 0x36003E00 }, 504 + { 0x4000, 0x00000000 }, 505 + }; 506 + 507 + static const struct reg_sequence cs42l43_4pole_patch[] = { 508 + { 0x4000, 0x00000055 }, 509 + { 0x4000, 0x000000AA }, 510 + { 0x17420, 0x7800E600 }, 511 + { 0x17424, 0x36003800 }, 512 + { 0x4000, 0x00000000 }, 513 + }; 514 + 515 + static void cs42l43_start_load_detect(struct cs42l43_codec *priv, bool mic) 516 { 517 struct cs42l43 *cs42l43 = priv->core; 518 ··· 519 if (!time_left) 520 dev_err(priv->dev, "Load detect HP power down timed out\n"); 521 } 522 + 523 + if (mic) 524 + regmap_multi_reg_write_bypassed(cs42l43->regmap, 525 + cs42l43_4pole_patch, 526 + ARRAY_SIZE(cs42l43_4pole_patch)); 527 + else 528 + regmap_multi_reg_write_bypassed(cs42l43->regmap, 529 + cs42l43_3pole_patch, 530 + ARRAY_SIZE(cs42l43_3pole_patch)); 531 532 regmap_update_bits(cs42l43->regmap, CS42L43_BLOCK_EN3, 533 CS42L43_ADC1_EN_MASK | CS42L43_ADC2_EN_MASK, 0); ··· 598 599 reinit_completion(&priv->load_detect); 600 601 + cs42l43_start_load_detect(priv, mic); 602 time_left = wait_for_completion_timeout(&priv->load_detect, 603 msecs_to_jiffies(CS42L43_LOAD_TIMEOUT_MS)); 604 cs42l43_stop_load_detect(priv); ··· 622 } 623 624 switch (val & CS42L43_AMP3_RES_DET_MASK) { 625 + case 0x0: // < 22 Ohm impedance 626 + case 0x1: // < 150 Ohm impedance 627 + case 0x2: // < 1000 Ohm impedance 628 return CS42L43_JACK_HEADPHONE; 629 + case 0x3: // > 1000 Ohm impedance 630 return CS42L43_JACK_LINEOUT; 631 default: 632 return -EINVAL;
+2
sound/soc/codecs/rt1320-sdw.c
··· 203 { 0x3fc2bfc2, 0x00 }, 204 { 0x3fc2bfc1, 0x00 }, 205 { 0x3fc2bfc0, 0x07 }, 206 { 0x0000d486, 0x43 }, 207 { SDW_SDCA_CTL(FUNC_NUM_AMP, RT1320_SDCA_ENT_PDE23, RT1320_SDCA_CTL_REQ_POWER_STATE, 0), 0x00 }, 208 { 0x1000db00, 0x07 }, ··· 355 { 0x0000d73d, 0xd7 }, 356 { 0x0000d73e, 0x00 }, 357 { 0x0000d73f, 0x10 }, 358 { 0x3fc2dfc3, 0x00 }, 359 { 0x3fc2dfc2, 0x00 }, 360 { 0x3fc2dfc1, 0x00 },
··· 203 { 0x3fc2bfc2, 0x00 }, 204 { 0x3fc2bfc1, 0x00 }, 205 { 0x3fc2bfc0, 0x07 }, 206 + { 0x1000cc46, 0x00 }, 207 { 0x0000d486, 0x43 }, 208 { SDW_SDCA_CTL(FUNC_NUM_AMP, RT1320_SDCA_ENT_PDE23, RT1320_SDCA_CTL_REQ_POWER_STATE, 0), 0x00 }, 209 { 0x1000db00, 0x07 }, ··· 354 { 0x0000d73d, 0xd7 }, 355 { 0x0000d73e, 0x00 }, 356 { 0x0000d73f, 0x10 }, 357 + { 0x1000cd56, 0x00 }, 358 { 0x3fc2dfc3, 0x00 }, 359 { 0x3fc2dfc2, 0x00 }, 360 { 0x3fc2dfc1, 0x00 },
+3
sound/soc/fsl/fsl_xcvr.c
··· 223 224 xcvr->mode = snd_soc_enum_item_to_val(e, item[0]); 225 226 fsl_xcvr_activate_ctl(dai, fsl_xcvr_arc_mode_kctl.name, 227 (xcvr->mode == FSL_XCVR_MODE_ARC)); 228 fsl_xcvr_activate_ctl(dai, fsl_xcvr_earc_capds_kctl.name, 229 (xcvr->mode == FSL_XCVR_MODE_EARC)); 230 /* Allow playback for SPDIF only */ 231 rtd = snd_soc_get_pcm_runtime(card, card->dai_link); 232 rtd->pcm->streams[SNDRV_PCM_STREAM_PLAYBACK].substream_count =
··· 223 224 xcvr->mode = snd_soc_enum_item_to_val(e, item[0]); 225 226 + down_read(&card->snd_card->controls_rwsem); 227 fsl_xcvr_activate_ctl(dai, fsl_xcvr_arc_mode_kctl.name, 228 (xcvr->mode == FSL_XCVR_MODE_ARC)); 229 fsl_xcvr_activate_ctl(dai, fsl_xcvr_earc_capds_kctl.name, 230 (xcvr->mode == FSL_XCVR_MODE_EARC)); 231 + up_read(&card->snd_card->controls_rwsem); 232 + 233 /* Allow playback for SPDIF only */ 234 rtd = snd_soc_get_pcm_runtime(card, card->dai_link); 235 rtd->pcm->streams[SNDRV_PCM_STREAM_PLAYBACK].substream_count =
+9
sound/soc/intel/boards/sof_es8336.c
··· 337 { 338 .callback = sof_es8336_quirk_cb, 339 .matches = { 340 DMI_MATCH(DMI_SYS_VENDOR, "IP3 tech"), 341 DMI_MATCH(DMI_BOARD_NAME, "WN1"), 342 },
··· 337 { 338 .callback = sof_es8336_quirk_cb, 339 .matches = { 340 + DMI_MATCH(DMI_SYS_VENDOR, "HUAWEI"), 341 + DMI_MATCH(DMI_PRODUCT_NAME, "BOD-WXX9"), 342 + }, 343 + .driver_data = (void *)(SOF_ES8336_HEADPHONE_GPIO | 344 + SOF_ES8336_ENABLE_DMIC) 345 + }, 346 + { 347 + .callback = sof_es8336_quirk_cb, 348 + .matches = { 349 DMI_MATCH(DMI_SYS_VENDOR, "IP3 tech"), 350 DMI_MATCH(DMI_BOARD_NAME, "WN1"), 351 },
+2 -3
sound/soc/sof/intel/hda.c
··· 1304 int i; 1305 1306 hdev = pdata->hw_pdata; 1307 - link_mask = hdev->info.link_mask; 1308 1309 - if (!link_mask) { 1310 dev_info(sdev->dev, "SoundWire links not enabled\n"); 1311 return NULL; 1312 } ··· 1336 * link_mask supported by hw and then go on searching 1337 * link_adr 1338 */ 1339 - if (~link_mask & mach->link_mask) 1340 continue; 1341 1342 /* No need to match adr if there is no links defined */
··· 1304 int i; 1305 1306 hdev = pdata->hw_pdata; 1307 1308 + if (!hdev->info.link_mask) { 1309 dev_info(sdev->dev, "SoundWire links not enabled\n"); 1310 return NULL; 1311 } ··· 1337 * link_mask supported by hw and then go on searching 1338 * link_adr 1339 */ 1340 + if (~hdev->info.link_mask & mach->link_mask) 1341 continue; 1342 1343 /* No need to match adr if there is no links defined */
+2 -7
sound/usb/mixer_quirks.c
··· 311 if (pm.err < 0) 312 return pm.err; 313 314 - if (chip->usb_id == USB_ID(0x041e, 0x3042)) 315 - err = snd_usb_ctl_msg(chip->dev, 316 - usb_sndctrlpipe(chip->dev, 0), 0x24, 317 - USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_OTHER, 318 - !value, 0, NULL, 0); 319 - /* USB X-Fi S51 Pro */ 320 - if (chip->usb_id == USB_ID(0x041e, 0x30df)) 321 err = snd_usb_ctl_msg(chip->dev, 322 usb_sndctrlpipe(chip->dev, 0), 0x24, 323 USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_OTHER,
··· 311 if (pm.err < 0) 312 return pm.err; 313 314 + if (chip->usb_id == USB_ID(0x041e, 0x3042) || /* USB X-Fi S51 */ 315 + chip->usb_id == USB_ID(0x041e, 0x30df)) /* USB X-Fi S51 Pro */ 316 err = snd_usb_ctl_msg(chip->dev, 317 usb_sndctrlpipe(chip->dev, 0), 0x24, 318 USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_OTHER,