1 // SPDX-License-Identifier: GPL-2.0-only 2 // 3 // KUnit test for the Cirrus Logic cs35l56 driver. 4 // 5 // Copyright (C) 2026 Cirrus Logic, Inc. and 6 // Cirrus Logic International Semiconductor Ltd. 7 8 #include <kunit/resource.h> 9 #include <kunit/test.h> 10 #include <kunit/static_stub.h> 11 #include <linux/efi.h> 12 #include <linux/device/faux.h> 13 #include <linux/firmware/cirrus/cs_dsp.h> 14 #include <linux/firmware/cirrus/wmfw.h> 15 #include <linux/module.h> 16 #include <linux/overflow.h> 17 #include <linux/pci_ids.h> 18 #include <linux/property.h> 19 #include <linux/seq_buf.h> 20 #include <linux/soundwire/sdw.h> 21 #include <sound/cs35l56.h> 22 #include <sound/cs-amp-lib.h> 23 #include "cs35l56.h" 24 25 KUNIT_DEFINE_ACTION_WRAPPER(faux_device_destroy_wrapper, faux_device_destroy, 26 struct faux_device *) 27 28 KUNIT_DEFINE_ACTION_WRAPPER(software_node_unregister_node_group_wrapper, 29 software_node_unregister_node_group, 30 const struct software_node * const *) 31 32 KUNIT_DEFINE_ACTION_WRAPPER(software_node_unregister_wrapper, 33 software_node_unregister, 34 const struct software_node *) 35 36 KUNIT_DEFINE_ACTION_WRAPPER(device_remove_software_node_wrapper, 37 device_remove_software_node, 38 struct device *) 39 40 struct cs35l56_test_priv { 41 struct faux_device *amp_dev; 42 struct cs35l56_private *cs35l56_priv; 43 44 const char *ssidexv2; 45 46 bool read_onchip_spkid_called; 47 bool configure_onchip_spkid_pads_called; 48 }; 49 50 struct cs35l56_test_param { 51 u8 type; 52 u8 rev; 53 54 s32 spkid_gpios[4]; 55 s32 spkid_pulls[4]; 56 }; 57 58 static const struct software_node cs35l56_test_dev_sw_node = 59 SOFTWARE_NODE("SWD1", NULL, NULL); 60 61 static const struct software_node cs35l56_test_af01_sw_node = 62 SOFTWARE_NODE("AF01", NULL, &cs35l56_test_dev_sw_node); 63 64 static const struct software_node *cs35l56_test_dev_and_af01_node_group[] = { 65 &cs35l56_test_dev_sw_node, 66 &cs35l56_test_af01_sw_node, 67 NULL 68 }; 69 70 static const char *cs35l56_test_devm_get_vendor_specific_variant_id_none(struct device *dev, 71 int ssid_vendor, 72 int ssid_device) 73 { 74 return ERR_PTR(-ENOENT); 75 } 76 77 static void cs35l56_test_l56_b0_suffix_sdw(struct kunit *test) 78 { 79 struct cs35l56_test_priv *priv = test->priv; 80 struct cs35l56_private *cs35l56 = priv->cs35l56_priv; 81 82 /* Set device type info */ 83 cs35l56->base.type = 0x56; 84 cs35l56->base.rev = 0xb0; 85 86 /* Set the ALSA name prefix */ 87 cs35l56->component->name_prefix = "AMP1"; 88 89 /* Set SoundWire link and UID number */ 90 cs35l56->sdw_link_num = 1; 91 cs35l56->sdw_unique_id = 5; 92 93 kunit_activate_static_stub(test, 94 cs35l56_test_devm_get_vendor_specific_variant_id_none, 95 cs_amp_devm_get_vendor_specific_variant_id); 96 97 KUNIT_EXPECT_EQ(test, 0, cs35l56_set_fw_suffix(cs35l56)); 98 99 /* Priority suffix should be the legacy ALSA prefix */ 100 KUNIT_EXPECT_STREQ(test, cs35l56->dsp.fwf_suffix, "AMP1"); 101 102 /* Fallback suffix should be the new SoundWire ID */ 103 KUNIT_EXPECT_STREQ(test, cs35l56->fallback_fw_suffix, "l1u5"); 104 } 105 106 static void cs35l56_test_suffix_sdw(struct kunit *test) 107 { 108 struct cs35l56_test_priv *priv = test->priv; 109 struct cs35l56_private *cs35l56 = priv->cs35l56_priv; 110 111 /* Set the ALSA name prefix */ 112 cs35l56->component->name_prefix = "AMP1"; 113 114 /* Set SoundWire link and UID number */ 115 cs35l56->sdw_link_num = 1; 116 cs35l56->sdw_unique_id = 5; 117 118 kunit_activate_static_stub(test, 119 cs35l56_test_devm_get_vendor_specific_variant_id_none, 120 cs_amp_devm_get_vendor_specific_variant_id); 121 122 KUNIT_EXPECT_EQ(test, 0, cs35l56_set_fw_suffix(cs35l56)); 123 124 /* Suffix should be the SoundWire ID without a fallback */ 125 KUNIT_EXPECT_STREQ(test, cs35l56->dsp.fwf_suffix, "l1u5"); 126 KUNIT_EXPECT_NULL(test, cs35l56->fallback_fw_suffix); 127 } 128 129 static void cs35l56_test_suffix_i2cspi(struct kunit *test) 130 { 131 struct cs35l56_test_priv *priv = test->priv; 132 struct cs35l56_private *cs35l56 = priv->cs35l56_priv; 133 134 /* Set the ALSA name prefix */ 135 cs35l56->component->name_prefix = "AMP1"; 136 137 kunit_activate_static_stub(test, 138 cs35l56_test_devm_get_vendor_specific_variant_id_none, 139 cs_amp_devm_get_vendor_specific_variant_id); 140 141 KUNIT_EXPECT_EQ(test, 0, cs35l56_set_fw_suffix(cs35l56)); 142 143 /* Suffix strings should not be set: use default wm_adsp suffixing */ 144 KUNIT_EXPECT_NULL(test, cs35l56->dsp.fwf_suffix); 145 KUNIT_EXPECT_NULL(test, cs35l56->fallback_fw_suffix); 146 } 147 148 static efi_status_t cs35l56_test_get_efi_ssidexv2(efi_char16_t *name, 149 efi_guid_t *guid, 150 u32 *returned_attr, 151 unsigned long *size, 152 void *buf) 153 { 154 struct kunit *test = kunit_get_current_test(); 155 struct cs35l56_test_priv *priv = test->priv; 156 unsigned int len; 157 158 KUNIT_ASSERT_NOT_NULL(test, priv->ssidexv2); 159 len = strlen(priv->ssidexv2); 160 161 if (*size < len) { 162 *size = len; 163 return EFI_BUFFER_TOO_SMALL; 164 } 165 166 KUNIT_ASSERT_NOT_NULL(test, buf); 167 memcpy(buf, priv->ssidexv2, len); 168 169 return EFI_SUCCESS; 170 } 171 172 static void cs35l56_test_ssidexv2_suffix_sdw(struct kunit *test) 173 { 174 struct cs35l56_test_priv *priv = test->priv; 175 struct cs35l56_private *cs35l56 = priv->cs35l56_priv; 176 177 /* Set the ALSA name prefix */ 178 cs35l56->component->name_prefix = "AMP1"; 179 180 /* Set SoundWire link and UID number */ 181 cs35l56->sdw_link_num = 1; 182 cs35l56->sdw_unique_id = 5; 183 184 /* Set a SSID to enable lookup of SSIDExV2 */ 185 snd_soc_card_set_pci_ssid(cs35l56->component->card, PCI_VENDOR_ID_DELL, 0x1234); 186 187 priv->ssidexv2 = "10281234_01_BB_CC"; 188 189 kunit_activate_static_stub(test, 190 cs_amp_test_hooks->get_efi_variable, 191 cs35l56_test_get_efi_ssidexv2); 192 193 KUNIT_EXPECT_EQ(test, 0, cs35l56_set_fw_suffix(cs35l56)); 194 195 /* Priority suffix should be the SSIDExV2 string with SoundWire ID */ 196 KUNIT_EXPECT_STREQ(test, cs35l56->dsp.fwf_suffix, "01-l1u5"); 197 198 /* Fallback suffix should be the SoundWireID */ 199 KUNIT_EXPECT_STREQ(test, cs35l56->fallback_fw_suffix, "l1u5"); 200 } 201 202 static void cs35l56_test_ssidexv2_suffix_i2cspi(struct kunit *test) 203 { 204 struct cs35l56_test_priv *priv = test->priv; 205 struct cs35l56_private *cs35l56 = priv->cs35l56_priv; 206 207 /* Set the ALSA name prefix */ 208 cs35l56->component->name_prefix = "AMP1"; 209 210 /* Set a SSID to enable lookup of SSIDExV2 */ 211 snd_soc_card_set_pci_ssid(cs35l56->component->card, PCI_VENDOR_ID_DELL, 0x1234); 212 213 priv->ssidexv2 = "10281234_01_BB_CC"; 214 215 kunit_activate_static_stub(test, 216 cs_amp_test_hooks->get_efi_variable, 217 cs35l56_test_get_efi_ssidexv2); 218 219 KUNIT_EXPECT_EQ(test, 0, cs35l56_set_fw_suffix(cs35l56)); 220 221 /* Priority suffix should be the SSIDExV2 string with ALSA name prefix */ 222 KUNIT_EXPECT_STREQ(test, cs35l56->dsp.fwf_suffix, "01-AMP1"); 223 224 /* Fallback suffix should be the ALSA name prefix */ 225 KUNIT_EXPECT_STREQ(test, cs35l56->fallback_fw_suffix, "AMP1"); 226 } 227 228 /* 229 * CS35L56 B0 SoundWire should ignore any SSIDExV2 suffix. It isn't needed 230 * on any products with B0 silicon and would interfere with the fallback 231 * to legacy naming convention for early B0-based laptops. 232 */ 233 static void cs35l56_test_l56_b0_ssidexv2_ignored_suffix_sdw(struct kunit *test) 234 { 235 struct cs35l56_test_priv *priv = test->priv; 236 struct cs35l56_private *cs35l56 = priv->cs35l56_priv; 237 238 /* Set device type info */ 239 cs35l56->base.type = 0x56; 240 cs35l56->base.rev = 0xb0; 241 242 /* Set the ALSA name prefix */ 243 cs35l56->component->name_prefix = "AMP1"; 244 245 /* Set SoundWire link and UID number */ 246 cs35l56->sdw_link_num = 1; 247 cs35l56->sdw_unique_id = 5; 248 249 /* Set a SSID to enable lookup of SSIDExV2 */ 250 snd_soc_card_set_pci_ssid(cs35l56->component->card, PCI_VENDOR_ID_DELL, 0x1234); 251 252 priv->ssidexv2 = "10281234_01_BB_CC"; 253 254 kunit_activate_static_stub(test, 255 cs_amp_test_hooks->get_efi_variable, 256 cs35l56_test_get_efi_ssidexv2); 257 258 KUNIT_EXPECT_EQ(test, 0, cs35l56_set_fw_suffix(cs35l56)); 259 260 /* Priority suffix should be the legacy ALSA prefix */ 261 KUNIT_EXPECT_STREQ(test, cs35l56->dsp.fwf_suffix, "AMP1"); 262 263 /* Fallback suffix should be the new SoundWire ID */ 264 KUNIT_EXPECT_STREQ(test, cs35l56->fallback_fw_suffix, "l1u5"); 265 } 266 267 /* 268 * Test that cs35l56_process_xu_properties() correctly parses the GPIO and 269 * pull values from properties into the arrays in struct cs35l56_base. 270 * 271 * This test creates the node tree: 272 * 273 * Node("SWD1") { // top-level device node 274 * Node("AF01") { 275 * Node("mipi-sdca-function-expansion-subproperties") { 276 * property: "01fa-spk-id-gpios-onchip" 277 * property: 01fa-spk-id-gpios-onchip-pull 278 * } 279 * } 280 * } 281 * 282 * Note that in ACPI "mipi-sdca-function-expansion-subproperties" is 283 * a special _DSD property that points to a Device(EXT0) node but behaves 284 * as an alias of the EXT0 node. The equivalent in software nodes is to 285 * create a Node named "mipi-sdca-function-expansion-subproperties" with 286 * the properties. 287 * 288 */ 289 static void cs35l56_test_parse_xu_onchip_spkid(struct kunit *test) 290 { 291 const struct cs35l56_test_param *param = test->param_value; 292 struct cs35l56_test_priv *priv = test->priv; 293 struct cs35l56_private *cs35l56 = priv->cs35l56_priv; 294 struct software_node *ext0_node; 295 int num_gpios = 0; 296 int num_pulls = 0; 297 int i; 298 299 for (i = 0; i < ARRAY_SIZE(param->spkid_gpios); i++, num_gpios++) { 300 if (param->spkid_gpios[i] < 0) 301 break; 302 } 303 KUNIT_ASSERT_LE(test, num_gpios, ARRAY_SIZE(cs35l56->base.onchip_spkid_gpios)); 304 305 for (i = 0; i < ARRAY_SIZE(param->spkid_pulls); i++, num_pulls++) { 306 if (param->spkid_pulls[i] < 0) 307 break; 308 } 309 KUNIT_ASSERT_LE(test, num_pulls, ARRAY_SIZE(cs35l56->base.onchip_spkid_pulls)); 310 311 const struct property_entry ext0_props[] = { 312 PROPERTY_ENTRY_U32_ARRAY_LEN("01fa-spk-id-gpios-onchip", 313 param->spkid_gpios, num_gpios), 314 PROPERTY_ENTRY_U32_ARRAY_LEN("01fa-spk-id-gpios-onchip-pull", 315 param->spkid_pulls, num_pulls), 316 { } 317 }; 318 319 KUNIT_ASSERT_EQ(test, 320 software_node_register_node_group(cs35l56_test_dev_and_af01_node_group), 321 0); 322 KUNIT_ASSERT_EQ(test, 323 kunit_add_action_or_reset(test, 324 software_node_unregister_node_group_wrapper, 325 cs35l56_test_dev_and_af01_node_group), 326 0); 327 328 ext0_node = kunit_kzalloc(test, sizeof(*ext0_node), GFP_KERNEL); 329 KUNIT_ASSERT_NOT_NULL(test, ext0_node); 330 *ext0_node = SOFTWARE_NODE("mipi-sdca-function-expansion-subproperties", 331 ext0_props, &cs35l56_test_af01_sw_node); 332 333 KUNIT_ASSERT_EQ(test, software_node_register(ext0_node), 0); 334 KUNIT_ASSERT_EQ(test, 335 kunit_add_action_or_reset(test, 336 software_node_unregister_wrapper, 337 ext0_node), 338 0); 339 340 KUNIT_ASSERT_EQ(test, 341 device_add_software_node(cs35l56->base.dev, &cs35l56_test_dev_sw_node), 0); 342 KUNIT_ASSERT_EQ(test, 0, 343 kunit_add_action_or_reset(test, 344 device_remove_software_node_wrapper, 345 cs35l56->base.dev)); 346 347 KUNIT_EXPECT_EQ(test, cs35l56_process_xu_properties(cs35l56), 0); 348 349 KUNIT_EXPECT_EQ(test, cs35l56->base.num_onchip_spkid_gpios, num_gpios); 350 KUNIT_EXPECT_EQ(test, cs35l56->base.num_onchip_spkid_pulls, num_pulls); 351 352 for (i = 0; i < ARRAY_SIZE(param->spkid_gpios); i++) { 353 if (param->spkid_gpios[i] < 0) 354 break; 355 356 /* 357 * cs35l56_process_xu_properties() stores the GPIO numbers 358 * zero-based, which is one less than the value in the property. 359 */ 360 KUNIT_EXPECT_EQ_MSG(test, cs35l56->base.onchip_spkid_gpios[i], 361 param->spkid_gpios[i] - 1, 362 "i=%d", i); 363 } 364 365 for (i = 0; i < ARRAY_SIZE(param->spkid_pulls); i++) { 366 if (param->spkid_pulls[i] < 0) 367 break; 368 369 KUNIT_EXPECT_EQ_MSG(test, cs35l56->base.onchip_spkid_pulls[i], 370 param->spkid_pulls[i], "i=%d", i); 371 } 372 } 373 374 static int cs35l56_test_dummy_read_onchip_spkid(struct cs35l56_base *cs35l56_base) 375 { 376 struct kunit *test = kunit_get_current_test(); 377 struct cs35l56_test_priv *priv = test->priv; 378 379 priv->read_onchip_spkid_called = true; 380 381 return 4; 382 } 383 384 static int cs35l56_test_dummy_configure_onchip_spkid_pads(struct cs35l56_base *cs35l56_base) 385 { 386 struct kunit *test = kunit_get_current_test(); 387 struct cs35l56_test_priv *priv = test->priv; 388 389 priv->configure_onchip_spkid_pads_called = true; 390 391 return 0; 392 } 393 394 static void cs35l56_test_set_fw_name_reads_onchip_spkid(struct kunit *test) 395 { 396 struct cs35l56_test_priv *priv = test->priv; 397 struct cs35l56_private *cs35l56 = priv->cs35l56_priv; 398 399 /* Provide some on-chip GPIOs for spkid */ 400 cs35l56->base.onchip_spkid_gpios[0] = 1; 401 cs35l56->base.num_onchip_spkid_gpios = 1; 402 403 cs35l56->speaker_id = -ENOENT; 404 405 kunit_activate_static_stub(test, 406 cs35l56_configure_onchip_spkid_pads, 407 cs35l56_test_dummy_configure_onchip_spkid_pads); 408 kunit_activate_static_stub(test, 409 cs35l56_read_onchip_spkid, 410 cs35l56_test_dummy_read_onchip_spkid); 411 412 priv->configure_onchip_spkid_pads_called = false; 413 priv->read_onchip_spkid_called = false; 414 KUNIT_EXPECT_EQ(test, cs35l56_set_fw_name(cs35l56->component), 0); 415 KUNIT_EXPECT_TRUE(test, priv->configure_onchip_spkid_pads_called); 416 KUNIT_EXPECT_TRUE(test, priv->read_onchip_spkid_called); 417 KUNIT_EXPECT_EQ(test, cs35l56->speaker_id, 418 cs35l56_test_dummy_read_onchip_spkid(&cs35l56->base)); 419 } 420 421 static void cs35l56_test_set_fw_name_preserves_spkid_with_onchip_gpios(struct kunit *test) 422 { 423 struct cs35l56_test_priv *priv = test->priv; 424 struct cs35l56_private *cs35l56 = priv->cs35l56_priv; 425 426 /* Provide some on-chip GPIOs for spkid */ 427 cs35l56->base.onchip_spkid_gpios[0] = 1; 428 cs35l56->base.num_onchip_spkid_gpios = 1; 429 430 /* Simulate that the driver already got a spkid from somewhere */ 431 cs35l56->speaker_id = 15; 432 433 KUNIT_EXPECT_EQ(test, cs35l56_set_fw_name(cs35l56->component), 0); 434 KUNIT_EXPECT_EQ(test, cs35l56->speaker_id, 15); 435 } 436 437 static void cs35l56_test_set_fw_name_preserves_spkid_without_onchip_gpios(struct kunit *test) 438 { 439 struct cs35l56_test_priv *priv = test->priv; 440 struct cs35l56_private *cs35l56 = priv->cs35l56_priv; 441 442 cs35l56->base.num_onchip_spkid_gpios = 0; 443 444 /* Simulate that the driver already got a spkid from somewhere */ 445 cs35l56->speaker_id = 15; 446 447 KUNIT_EXPECT_EQ(test, cs35l56_set_fw_name(cs35l56->component), 0); 448 KUNIT_EXPECT_EQ(test, cs35l56->speaker_id, 15); 449 } 450 451 static int cs35l56_test_case_init_common(struct kunit *test) 452 { 453 struct cs35l56_test_priv *priv; 454 const struct cs35l56_test_param *param = test->param_value; 455 struct cs35l56_private *cs35l56; 456 457 KUNIT_ASSERT_NOT_NULL(test, cs_amp_test_hooks); 458 459 priv = kunit_kzalloc(test, sizeof(*priv), GFP_KERNEL); 460 if (!priv) 461 return -ENOMEM; 462 463 test->priv = priv; 464 465 /* Create dummy amp driver dev */ 466 priv->amp_dev = faux_device_create("cs35l56_test_drv", NULL, NULL); 467 KUNIT_ASSERT_NOT_NULL(test, priv->amp_dev); 468 KUNIT_ASSERT_EQ(test, 0, 469 kunit_add_action_or_reset(test, 470 faux_device_destroy_wrapper, 471 priv->amp_dev)); 472 473 /* Construct minimal set of driver structs */ 474 priv->cs35l56_priv = kunit_kzalloc(test, sizeof(*priv->cs35l56_priv), GFP_KERNEL); 475 KUNIT_ASSERT_NOT_NULL(test, priv->cs35l56_priv); 476 cs35l56 = priv->cs35l56_priv; 477 cs35l56->base.dev = &priv->amp_dev->dev; 478 479 cs35l56->component = kunit_kzalloc(test, sizeof(*cs35l56->component), GFP_KERNEL); 480 KUNIT_ASSERT_NOT_NULL(test, cs35l56->component); 481 cs35l56->component->dev = cs35l56->base.dev; 482 snd_soc_component_set_drvdata(cs35l56->component, cs35l56); 483 484 cs35l56->component->card = kunit_kzalloc(test, sizeof(*cs35l56->component->card), 485 GFP_KERNEL); 486 KUNIT_ASSERT_NOT_NULL(test, cs35l56->component->card); 487 488 if (param) { 489 cs35l56->base.type = param->type; 490 cs35l56->base.rev = param->rev; 491 } 492 493 return 0; 494 } 495 496 static int cs35l56_test_case_init_soundwire(struct kunit *test) 497 { 498 struct cs35l56_test_priv *priv; 499 struct cs35l56_private *cs35l56; 500 int ret; 501 502 ret = cs35l56_test_case_init_common(test); 503 if (ret) 504 return ret; 505 506 priv = test->priv; 507 cs35l56 = priv->cs35l56_priv; 508 509 /* Dummy to indicate this is Soundwire */ 510 cs35l56->sdw_peripheral = kunit_kzalloc(test, sizeof(*cs35l56->sdw_peripheral), 511 GFP_KERNEL); 512 if (!cs35l56->sdw_peripheral) 513 return -ENOMEM; 514 515 516 return 0; 517 } 518 519 static void cs35l56_test_gpio_param_desc(const struct cs35l56_test_param *param, char *desc) 520 { 521 DECLARE_SEQ_BUF(gpios, 1 + (2 * ARRAY_SIZE(param->spkid_gpios))); 522 DECLARE_SEQ_BUF(pulls, 1 + (2 * ARRAY_SIZE(param->spkid_pulls))); 523 int i; 524 525 for (i = 0; i < ARRAY_SIZE(param->spkid_gpios); i++) { 526 if (param->spkid_gpios[i] < 0) 527 break; 528 529 seq_buf_printf(&gpios, "%s%d", (i == 0) ? "" : ",", param->spkid_gpios[i]); 530 } 531 532 for (i = 0; i < ARRAY_SIZE(param->spkid_pulls); i++) { 533 if (param->spkid_pulls[i] < 0) 534 break; 535 536 seq_buf_printf(&pulls, "%s%d", (i == 0) ? "" : ",", param->spkid_pulls[i]); 537 } 538 539 snprintf(desc, KUNIT_PARAM_DESC_SIZE, "gpios:{%s} pulls:{%s}", 540 seq_buf_str(&gpios), seq_buf_str(&pulls)); 541 } 542 543 static const struct cs35l56_test_param cs35l56_test_onchip_spkid_cases[] = { 544 { .spkid_gpios = { 1, -1 }, .spkid_pulls = { 1, -1 }, }, 545 { .spkid_gpios = { 1, -1 }, .spkid_pulls = { 2, -1 }, }, 546 547 { .spkid_gpios = { 7, -1 }, .spkid_pulls = { 1, -1 }, }, 548 { .spkid_gpios = { 7, -1 }, .spkid_pulls = { 2, -1 }, }, 549 550 { .spkid_gpios = { 1, 7, -1 }, .spkid_pulls = { 1, 1, -1 }, }, 551 { .spkid_gpios = { 1, 7, -1 }, .spkid_pulls = { 2, 2, -1 }, }, 552 553 { .spkid_gpios = { 7, 1, -1 }, .spkid_pulls = { 1, 1, -1 }, }, 554 { .spkid_gpios = { 7, 1, -1 }, .spkid_pulls = { 2, 2, -1 }, }, 555 556 { .spkid_gpios = { 3, 7, 1, -1 }, .spkid_pulls = { 1, 1, 1, -1 }, }, 557 { .spkid_gpios = { 3, 7, 1, -1 }, .spkid_pulls = { 2, 2, 2, -1 }, }, 558 }; 559 KUNIT_ARRAY_PARAM(cs35l56_test_onchip_spkid, 560 cs35l56_test_onchip_spkid_cases, 561 cs35l56_test_gpio_param_desc); 562 563 static void cs35l56_test_type_rev_param_desc(const struct cs35l56_test_param *param, 564 char *desc) 565 { 566 snprintf(desc, KUNIT_PARAM_DESC_SIZE, "type: %02x rev: %02x", 567 param->type, param->rev); 568 } 569 570 static const struct cs35l56_test_param cs35l56_test_type_rev_ex_b0_param_cases[] = { 571 { .type = 0x56, .rev = 0xb2 }, 572 { .type = 0x57, .rev = 0xb2 }, 573 { .type = 0x63, .rev = 0xa1 }, 574 }; 575 KUNIT_ARRAY_PARAM(cs35l56_test_type_rev_ex_b0, cs35l56_test_type_rev_ex_b0_param_cases, 576 cs35l56_test_type_rev_param_desc); 577 578 579 static const struct cs35l56_test_param cs35l56_test_type_rev_all_param_cases[] = { 580 { .type = 0x56, .rev = 0xb0 }, 581 { .type = 0x56, .rev = 0xb2 }, 582 { .type = 0x57, .rev = 0xb2 }, 583 { .type = 0x63, .rev = 0xa1 }, 584 }; 585 KUNIT_ARRAY_PARAM(cs35l56_test_type_rev_all, cs35l56_test_type_rev_all_param_cases, 586 cs35l56_test_type_rev_param_desc); 587 588 static struct kunit_case cs35l56_test_cases_soundwire[] = { 589 KUNIT_CASE(cs35l56_test_l56_b0_suffix_sdw), 590 KUNIT_CASE_PARAM(cs35l56_test_suffix_sdw, cs35l56_test_type_rev_ex_b0_gen_params), 591 KUNIT_CASE_PARAM(cs35l56_test_ssidexv2_suffix_sdw, 592 cs35l56_test_type_rev_ex_b0_gen_params), 593 KUNIT_CASE(cs35l56_test_l56_b0_ssidexv2_ignored_suffix_sdw), 594 595 KUNIT_CASE_PARAM(cs35l56_test_parse_xu_onchip_spkid, 596 cs35l56_test_onchip_spkid_gen_params), 597 598 KUNIT_CASE(cs35l56_test_set_fw_name_reads_onchip_spkid), 599 KUNIT_CASE(cs35l56_test_set_fw_name_preserves_spkid_with_onchip_gpios), 600 KUNIT_CASE(cs35l56_test_set_fw_name_preserves_spkid_without_onchip_gpios), 601 602 { } /* terminator */ 603 }; 604 605 static struct kunit_case cs35l56_test_cases_not_soundwire[] = { 606 KUNIT_CASE_PARAM(cs35l56_test_suffix_i2cspi, cs35l56_test_type_rev_all_gen_params), 607 KUNIT_CASE_PARAM(cs35l56_test_ssidexv2_suffix_i2cspi, 608 cs35l56_test_type_rev_all_gen_params), 609 610 KUNIT_CASE(cs35l56_test_set_fw_name_reads_onchip_spkid), 611 KUNIT_CASE(cs35l56_test_set_fw_name_preserves_spkid_with_onchip_gpios), 612 KUNIT_CASE(cs35l56_test_set_fw_name_preserves_spkid_without_onchip_gpios), 613 614 { } /* terminator */ 615 }; 616 617 static struct kunit_suite cs35l56_test_suite_soundwire = { 618 .name = "snd-soc-cs35l56-test-soundwire", 619 .init = cs35l56_test_case_init_soundwire, 620 .test_cases = cs35l56_test_cases_soundwire, 621 }; 622 623 static struct kunit_suite cs35l56_test_suite_not_soundwire = { 624 .name = "snd-soc-cs35l56-test-not-soundwire", 625 .init = cs35l56_test_case_init_common, 626 .test_cases = cs35l56_test_cases_not_soundwire, 627 }; 628 629 kunit_test_suites( 630 &cs35l56_test_suite_soundwire, 631 &cs35l56_test_suite_not_soundwire, 632 ); 633 634 MODULE_IMPORT_NS("SND_SOC_CS_AMP_LIB"); 635 MODULE_IMPORT_NS("SND_SOC_CS35L56_SHARED"); 636 MODULE_IMPORT_NS("EXPORTED_FOR_KUNIT_TESTING"); 637 MODULE_DESCRIPTION("KUnit test for Cirrus Logic cs35l56 codec driver"); 638 MODULE_AUTHOR("Richard Fitzgerald <rf@opensource.cirrus.com>"); 639 MODULE_LICENSE("GPL"); 640