Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

Merge tag 'asoc-fix-v6.19-rc8' of https://git.kernel.org/pub/scm/linux/kernel/git/broonie/sound into for-linus

ASoC: Fixes for v6.19

A bunch more small fixes here, plus some more of the constant stream of
quirks. The most notable change here is Richard's change to the cs_dsp
code for the KUnit tests which is relatively large, mostly due to
boilerplate. The tests were triggering large numbers of error messages
as part of verifying that problems with input data are appropriately
detected which in turn caused runtime issues for the framework due to
the performance impact of pushing the logging out, while the logging is
valuable in normal operation it's basically useless while doing tests
designed to trigger it so rate limiting is an appropriate fix.

+195 -23
+1
Documentation/devicetree/bindings/sound/ti,tlv320aic3x.yaml
··· 46 46 properties: 47 47 compatible: 48 48 enum: 49 + - ti,tlv320aic23 49 50 - ti,tlv320aic3x 50 51 - ti,tlv320aic33 51 52 - ti,tlv320aic3007
+37
drivers/firmware/cirrus/cs_dsp.c
··· 9 9 * Cirrus Logic International Semiconductor Ltd. 10 10 */ 11 11 12 + #include <kunit/visibility.h> 12 13 #include <linux/cleanup.h> 13 14 #include <linux/ctype.h> 14 15 #include <linux/debugfs.h> ··· 25 24 #include <linux/firmware/cirrus/cs_dsp.h> 26 25 #include <linux/firmware/cirrus/wmfw.h> 27 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 28 62 #define cs_dsp_err(_dsp, fmt, ...) \ 29 63 dev_err(_dsp->dev, "%s: " fmt, _dsp->name, ##__VA_ARGS__) 30 64 #define cs_dsp_warn(_dsp, fmt, ...) \ ··· 68 32 dev_info(_dsp->dev, "%s: " fmt, _dsp->name, ##__VA_ARGS__) 69 33 #define cs_dsp_dbg(_dsp, fmt, ...) \ 70 34 dev_dbg(_dsp->dev, "%s: " fmt, _dsp->name, ##__VA_ARGS__) 35 + #endif 71 36 72 37 #define ADSP1_CONTROL_1 0x00 73 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 17 #include <linux/random.h> 18 18 #include <linux/regmap.h> 19 19 20 + #include "../cs_dsp.h" 21 + 20 22 /* 21 23 * Test method is: 22 24 * ··· 2226 2224 return ret; 2227 2225 2228 2226 /* Automatically call cs_dsp_remove() when test case ends */ 2229 - return kunit_add_action_or_reset(priv->test, _cs_dsp_remove_wrapper, dsp); 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; 2230 2243 } 2231 2244 2232 2245 static int cs_dsp_bin_test_halo_init(struct kunit *test) ··· 2553 2536 static struct kunit_suite cs_dsp_bin_test_halo = { 2554 2537 .name = "cs_dsp_bin_halo", 2555 2538 .init = cs_dsp_bin_test_halo_init, 2539 + .exit = cs_dsp_bin_test_exit, 2556 2540 .test_cases = cs_dsp_bin_test_cases_halo, 2557 2541 }; 2558 2542 2559 2543 static struct kunit_suite cs_dsp_bin_test_adsp2_32bit = { 2560 2544 .name = "cs_dsp_bin_adsp2_32bit", 2561 2545 .init = cs_dsp_bin_test_adsp2_32bit_init, 2546 + .exit = cs_dsp_bin_test_exit, 2562 2547 .test_cases = cs_dsp_bin_test_cases_adsp2, 2563 2548 }; 2564 2549 2565 2550 static struct kunit_suite cs_dsp_bin_test_adsp2_16bit = { 2566 2551 .name = "cs_dsp_bin_adsp2_16bit", 2567 2552 .init = cs_dsp_bin_test_adsp2_16bit_init, 2553 + .exit = cs_dsp_bin_test_exit, 2568 2554 .test_cases = cs_dsp_bin_test_cases_adsp2, 2569 2555 }; 2570 2556
+18 -6
drivers/firmware/cirrus/test/cs_dsp_test_bin_error.c
··· 18 18 #include <linux/string.h> 19 19 #include <linux/vmalloc.h> 20 20 21 + #include "../cs_dsp.h" 22 + 21 23 KUNIT_DEFINE_ACTION_WRAPPER(_put_device_wrapper, put_device, struct device *); 22 24 KUNIT_DEFINE_ACTION_WRAPPER(_cs_dsp_remove_wrapper, cs_dsp_remove, struct cs_dsp *); 23 25 ··· 382 380 383 381 static void cs_dsp_bin_err_test_exit(struct kunit *test) 384 382 { 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); 383 + cs_dsp_suppress_err_messages = false; 384 + cs_dsp_suppress_warn_messages = false; 385 + cs_dsp_suppress_info_messages = false; 390 386 } 391 387 392 388 static int cs_dsp_bin_err_test_common_init(struct kunit *test, struct cs_dsp *dsp, ··· 474 474 return ret; 475 475 476 476 /* 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; 478 490 } 479 491 480 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 18 #include <linux/string.h> 19 19 #include <linux/vmalloc.h> 20 20 21 + #include "../cs_dsp.h" 22 + 21 23 /* 22 24 * Test method is: 23 25 * ··· 1855 1853 return ret; 1856 1854 1857 1855 /* Automatically call cs_dsp_remove() when test case ends */ 1858 - return kunit_add_action_or_reset(priv->test, _cs_dsp_remove_wrapper, dsp); 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; 1859 1872 } 1860 1873 1861 1874 static int cs_dsp_wmfw_test_halo_init(struct kunit *test) ··· 2180 2163 static struct kunit_suite cs_dsp_wmfw_test_halo = { 2181 2164 .name = "cs_dsp_wmfwV3_halo", 2182 2165 .init = cs_dsp_wmfw_test_halo_init, 2166 + .exit = cs_dsp_wmfw_test_exit, 2183 2167 .test_cases = cs_dsp_wmfw_test_cases_halo, 2184 2168 }; 2185 2169 2186 2170 static struct kunit_suite cs_dsp_wmfw_test_adsp2_32bit_wmfw0 = { 2187 2171 .name = "cs_dsp_wmfwV0_adsp2_32bit", 2188 2172 .init = cs_dsp_wmfw_test_adsp2_32bit_wmfw0_init, 2173 + .exit = cs_dsp_wmfw_test_exit, 2189 2174 .test_cases = cs_dsp_wmfw_test_cases_adsp2, 2190 2175 }; 2191 2176 2192 2177 static struct kunit_suite cs_dsp_wmfw_test_adsp2_32bit_wmfw1 = { 2193 2178 .name = "cs_dsp_wmfwV1_adsp2_32bit", 2194 2179 .init = cs_dsp_wmfw_test_adsp2_32bit_wmfw1_init, 2180 + .exit = cs_dsp_wmfw_test_exit, 2195 2181 .test_cases = cs_dsp_wmfw_test_cases_adsp2, 2196 2182 }; 2197 2183 2198 2184 static struct kunit_suite cs_dsp_wmfw_test_adsp2_32bit_wmfw2 = { 2199 2185 .name = "cs_dsp_wmfwV2_adsp2_32bit", 2200 2186 .init = cs_dsp_wmfw_test_adsp2_32bit_wmfw2_init, 2187 + .exit = cs_dsp_wmfw_test_exit, 2201 2188 .test_cases = cs_dsp_wmfw_test_cases_adsp2, 2202 2189 }; 2203 2190 2204 2191 static struct kunit_suite cs_dsp_wmfw_test_adsp2_16bit_wmfw0 = { 2205 2192 .name = "cs_dsp_wmfwV0_adsp2_16bit", 2206 2193 .init = cs_dsp_wmfw_test_adsp2_16bit_wmfw0_init, 2194 + .exit = cs_dsp_wmfw_test_exit, 2207 2195 .test_cases = cs_dsp_wmfw_test_cases_adsp2, 2208 2196 }; 2209 2197 2210 2198 static struct kunit_suite cs_dsp_wmfw_test_adsp2_16bit_wmfw1 = { 2211 2199 .name = "cs_dsp_wmfwV1_adsp2_16bit", 2212 2200 .init = cs_dsp_wmfw_test_adsp2_16bit_wmfw1_init, 2201 + .exit = cs_dsp_wmfw_test_exit, 2213 2202 .test_cases = cs_dsp_wmfw_test_cases_adsp2, 2214 2203 }; 2215 2204 2216 2205 static struct kunit_suite cs_dsp_wmfw_test_adsp2_16bit_wmfw2 = { 2217 2206 .name = "cs_dsp_wmfwV2_adsp2_16bit", 2218 2207 .init = cs_dsp_wmfw_test_adsp2_16bit_wmfw2_init, 2208 + .exit = cs_dsp_wmfw_test_exit, 2219 2209 .test_cases = cs_dsp_wmfw_test_cases_adsp2, 2220 2210 }; 2221 2211
+18 -6
drivers/firmware/cirrus/test/cs_dsp_test_wmfw_error.c
··· 18 18 #include <linux/string.h> 19 19 #include <linux/vmalloc.h> 20 20 21 + #include "../cs_dsp.h" 22 + 21 23 KUNIT_DEFINE_ACTION_WRAPPER(_put_device_wrapper, put_device, struct device *); 22 24 KUNIT_DEFINE_ACTION_WRAPPER(_cs_dsp_remove_wrapper, cs_dsp_remove, struct cs_dsp *); 23 25 ··· 991 989 992 990 static void cs_dsp_wmfw_err_test_exit(struct kunit *test) 993 991 { 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); 992 + cs_dsp_suppress_err_messages = false; 993 + cs_dsp_suppress_warn_messages = false; 994 + cs_dsp_suppress_info_messages = false; 999 995 } 1000 996 1001 997 static int cs_dsp_wmfw_err_test_common_init(struct kunit *test, struct cs_dsp *dsp, ··· 1072 1072 return ret; 1073 1073 1074 1074 /* 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; 1076 1088 } 1077 1089 1078 1090 static int cs_dsp_wmfw_err_test_halo_init(struct kunit *test)
+1
drivers/firmware/cirrus/test/cs_dsp_tests.c
··· 12 12 MODULE_LICENSE("GPL"); 13 13 MODULE_IMPORT_NS("FW_CS_DSP"); 14 14 MODULE_IMPORT_NS("FW_CS_DSP_KUNIT_TEST_UTILS"); 15 + MODULE_IMPORT_NS("EXPORTED_FOR_KUNIT_TESTING");
+2
sound/soc/amd/renoir/acp3x-pdm-dma.c
··· 301 301 struct snd_pcm_substream *substream) 302 302 { 303 303 struct pdm_dev_data *adata = dev_get_drvdata(component->dev); 304 + struct pdm_stream_instance *rtd = substream->runtime->private_data; 304 305 305 306 disable_pdm_interrupts(adata->acp_base); 306 307 adata->capture_stream = NULL; 308 + kfree(rtd); 307 309 return 0; 308 310 } 309 311
+7
sound/soc/amd/yc/acp6x-mach.c
··· 643 643 { 644 644 .driver_data = &acp6x_card, 645 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 = { 646 653 DMI_MATCH(DMI_BOARD_VENDOR, "MECHREVO"), 647 654 DMI_MATCH(DMI_BOARD_NAME, "MRID6"), 648 655 }
+31 -6
sound/soc/codecs/cs42l43-jack.c
··· 496 496 pm_runtime_put_autosuspend(priv->dev); 497 497 } 498 498 499 - static void cs42l43_start_load_detect(struct cs42l43_codec *priv) 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) 500 516 { 501 517 struct cs42l43 *cs42l43 = priv->core; 502 518 ··· 535 519 if (!time_left) 536 520 dev_err(priv->dev, "Load detect HP power down timed out\n"); 537 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)); 538 531 539 532 regmap_update_bits(cs42l43->regmap, CS42L43_BLOCK_EN3, 540 533 CS42L43_ADC1_EN_MASK | CS42L43_ADC2_EN_MASK, 0); ··· 623 598 624 599 reinit_completion(&priv->load_detect); 625 600 626 - cs42l43_start_load_detect(priv); 601 + cs42l43_start_load_detect(priv, mic); 627 602 time_left = wait_for_completion_timeout(&priv->load_detect, 628 603 msecs_to_jiffies(CS42L43_LOAD_TIMEOUT_MS)); 629 604 cs42l43_stop_load_detect(priv); ··· 647 622 } 648 623 649 624 switch (val & CS42L43_AMP3_RES_DET_MASK) { 650 - case 0x0: // low impedance 651 - case 0x1: // high impedance 625 + case 0x0: // < 22 Ohm impedance 626 + case 0x1: // < 150 Ohm impedance 627 + case 0x2: // < 1000 Ohm impedance 652 628 return CS42L43_JACK_HEADPHONE; 653 - case 0x2: // lineout 654 - case 0x3: // Open circuit 629 + case 0x3: // > 1000 Ohm impedance 655 630 return CS42L43_JACK_LINEOUT; 656 631 default: 657 632 return -EINVAL;
+2
sound/soc/codecs/rt1320-sdw.c
··· 203 203 { 0x3fc2bfc2, 0x00 }, 204 204 { 0x3fc2bfc1, 0x00 }, 205 205 { 0x3fc2bfc0, 0x07 }, 206 + { 0x1000cc46, 0x00 }, 206 207 { 0x0000d486, 0x43 }, 207 208 { SDW_SDCA_CTL(FUNC_NUM_AMP, RT1320_SDCA_ENT_PDE23, RT1320_SDCA_CTL_REQ_POWER_STATE, 0), 0x00 }, 208 209 { 0x1000db00, 0x07 }, ··· 355 354 { 0x0000d73d, 0xd7 }, 356 355 { 0x0000d73e, 0x00 }, 357 356 { 0x0000d73f, 0x10 }, 357 + { 0x1000cd56, 0x00 }, 358 358 { 0x3fc2dfc3, 0x00 }, 359 359 { 0x3fc2dfc2, 0x00 }, 360 360 { 0x3fc2dfc1, 0x00 },
+3
sound/soc/fsl/fsl_xcvr.c
··· 223 223 224 224 xcvr->mode = snd_soc_enum_item_to_val(e, item[0]); 225 225 226 + down_read(&card->snd_card->controls_rwsem); 226 227 fsl_xcvr_activate_ctl(dai, fsl_xcvr_arc_mode_kctl.name, 227 228 (xcvr->mode == FSL_XCVR_MODE_ARC)); 228 229 fsl_xcvr_activate_ctl(dai, fsl_xcvr_earc_capds_kctl.name, 229 230 (xcvr->mode == FSL_XCVR_MODE_EARC)); 231 + up_read(&card->snd_card->controls_rwsem); 232 + 230 233 /* Allow playback for SPDIF only */ 231 234 rtd = snd_soc_get_pcm_runtime(card, card->dai_link); 232 235 rtd->pcm->streams[SNDRV_PCM_STREAM_PLAYBACK].substream_count =
+9
sound/soc/intel/boards/sof_es8336.c
··· 337 337 { 338 338 .callback = sof_es8336_quirk_cb, 339 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 = { 340 349 DMI_MATCH(DMI_SYS_VENDOR, "IP3 tech"), 341 350 DMI_MATCH(DMI_BOARD_NAME, "WN1"), 342 351 },
+2 -3
sound/soc/sof/intel/hda.c
··· 1304 1304 int i; 1305 1305 1306 1306 hdev = pdata->hw_pdata; 1307 - link_mask = hdev->info.link_mask; 1308 1307 1309 - if (!link_mask) { 1308 + if (!hdev->info.link_mask) { 1310 1309 dev_info(sdev->dev, "SoundWire links not enabled\n"); 1311 1310 return NULL; 1312 1311 } ··· 1336 1337 * link_mask supported by hw and then go on searching 1337 1338 * link_adr 1338 1339 */ 1339 - if (~link_mask & mach->link_mask) 1340 + if (~hdev->info.link_mask & mach->link_mask) 1340 1341 continue; 1341 1342 1342 1343 /* No need to match adr if there is no links defined */