* [PATCH 0/4] ASoC: cs35l56: More KUnit tests for speaker ID
@ 2026-03-04 16:23 Richard Fitzgerald
2026-03-04 16:23 ` [PATCH 1/4] ASoC: cs35l56: KUnit tests for setting dsp.system_name Richard Fitzgerald
` (4 more replies)
0 siblings, 5 replies; 6+ messages in thread
From: Richard Fitzgerald @ 2026-03-04 16:23 UTC (permalink / raw)
To: broonie, brendan.higgins, davidgow, raemoar63
Cc: linux-sound, linux-kselftest, kunit-dev, linux-kernel, patches
The first 3 patches in this series add some more KUnit testing for
fetching speaker ID and combining it with the system name to create
part of the qualifier for a firmware filename.
Patch #4 enables GPIOLIB in KUnit 'alltests' builds. This can be taken
separately from the first 3 patches.
The GPIO tests will skip if GPIOLIB is not enabled, but obviously it
would be ideal for 'kunit.py --alltests' runs to include these new
test cases.
Richard Fitzgerald (4):
ASoC: cs35l56: KUnit tests for setting dsp.system_name
ASoC: cs35l56: Some KUnit testing of cs35l56_get_speaker_id()
ASoC: cs35l56: KUnit tests for reading speaker ID from host GPIOs
kunit: config: all_tests: Select CONFIG_GPIOLIB
sound/soc/codecs/cs-amp-lib.c | 2 +
sound/soc/codecs/cs35l56-shared-test.c | 240 +++++++++++++++++++
sound/soc/codecs/cs35l56-test.c | 80 +++++++
sound/soc/codecs/cs35l56.c | 3 +-
sound/soc/codecs/cs35l56.h | 1 +
tools/testing/kunit/configs/all_tests.config | 2 +
6 files changed, 327 insertions(+), 1 deletion(-)
--
2.47.3
^ permalink raw reply [flat|nested] 6+ messages in thread
* [PATCH 1/4] ASoC: cs35l56: KUnit tests for setting dsp.system_name
2026-03-04 16:23 [PATCH 0/4] ASoC: cs35l56: More KUnit tests for speaker ID Richard Fitzgerald
@ 2026-03-04 16:23 ` Richard Fitzgerald
2026-03-04 16:24 ` [PATCH 2/4] ASoC: cs35l56: Some KUnit testing of cs35l56_get_speaker_id() Richard Fitzgerald
` (3 subsequent siblings)
4 siblings, 0 replies; 6+ messages in thread
From: Richard Fitzgerald @ 2026-03-04 16:23 UTC (permalink / raw)
To: broonie, brendan.higgins, davidgow, raemoar63
Cc: linux-sound, linux-kselftest, kunit-dev, linux-kernel, patches
Add KUnit tests for setting the dsp.system_name string.
There are two sources of the string:
1. PCI SSID from struct snd_soc_card.
2. "cirrus,firmware-uid" property.
Either of these can then be qualified by a speaker ID integer.
Signed-off-by: Richard Fitzgerald <rf@opensource.cirrus.com>
---
sound/soc/codecs/cs35l56-test.c | 80 +++++++++++++++++++++++++++++++++
sound/soc/codecs/cs35l56.c | 3 +-
sound/soc/codecs/cs35l56.h | 1 +
3 files changed, 83 insertions(+), 1 deletion(-)
diff --git a/sound/soc/codecs/cs35l56-test.c b/sound/soc/codecs/cs35l56-test.c
index decedf76847d..ac3f34bf8adc 100644
--- a/sound/soc/codecs/cs35l56-test.c
+++ b/sound/soc/codecs/cs35l56-test.c
@@ -74,6 +74,78 @@ static const char *cs35l56_test_devm_get_vendor_specific_variant_id_none(struct
return ERR_PTR(-ENOENT);
}
+static void cs35l56_test_system_name_from_ssid(struct kunit *test)
+{
+ struct cs35l56_test_priv *priv = test->priv;
+ struct cs35l56_private *cs35l56 = priv->cs35l56_priv;
+
+ cs35l56->speaker_id = -1;
+ snd_soc_card_set_pci_ssid(cs35l56->component->card, 0x12b4, 0xa7c8);
+
+ KUNIT_EXPECT_EQ(test, cs35l56_get_firmware_uid(cs35l56), 0);
+ KUNIT_EXPECT_EQ(test, cs35l56_set_fw_name(cs35l56->component), 0);
+ KUNIT_EXPECT_STREQ(test, cs35l56->dsp.system_name, "12b4a7c8");
+}
+
+static void cs35l56_test_system_name_from_ssid_and_spkid(struct kunit *test)
+{
+ struct cs35l56_test_priv *priv = test->priv;
+ struct cs35l56_private *cs35l56 = priv->cs35l56_priv;
+
+ cs35l56->speaker_id = 1;
+ snd_soc_card_set_pci_ssid(cs35l56->component->card, 0x12b4, 0xa7c8);
+
+ KUNIT_EXPECT_EQ(test, cs35l56_get_firmware_uid(cs35l56), 0);
+ KUNIT_EXPECT_EQ(test, cs35l56_set_fw_name(cs35l56->component), 0);
+ KUNIT_EXPECT_STREQ(test, cs35l56->dsp.system_name, "12b4a7c8-spkid1");
+}
+
+static void cs35l56_test_system_name_from_property(struct kunit *test)
+{
+ struct cs35l56_test_priv *priv = test->priv;
+ struct cs35l56_private *cs35l56 = priv->cs35l56_priv;
+ const struct property_entry dev_props[] = {
+ PROPERTY_ENTRY_STRING("cirrus,firmware-uid", "acme"),
+ { }
+ };
+ const struct software_node dev_node = SOFTWARE_NODE("SPK1", dev_props, NULL);
+
+ cs35l56->speaker_id = -1;
+
+ KUNIT_ASSERT_EQ(test, device_add_software_node(cs35l56->base.dev, &dev_node), 0);
+ KUNIT_ASSERT_EQ(test, 0,
+ kunit_add_action_or_reset(test,
+ device_remove_software_node_wrapper,
+ cs35l56->base.dev));
+
+ KUNIT_EXPECT_EQ(test, cs35l56_get_firmware_uid(cs35l56), 0);
+ KUNIT_EXPECT_EQ(test, cs35l56_set_fw_name(cs35l56->component), 0);
+ KUNIT_EXPECT_STREQ(test, cs35l56->dsp.system_name, "acme");
+}
+
+static void cs35l56_test_system_name_from_property_and_spkid(struct kunit *test)
+{
+ struct cs35l56_test_priv *priv = test->priv;
+ struct cs35l56_private *cs35l56 = priv->cs35l56_priv;
+ const struct property_entry dev_props[] = {
+ PROPERTY_ENTRY_STRING("cirrus,firmware-uid", "acme"),
+ { }
+ };
+ const struct software_node dev_node = SOFTWARE_NODE("SPK1", dev_props, NULL);
+
+ cs35l56->speaker_id = 1;
+
+ KUNIT_ASSERT_EQ(test, device_add_software_node(cs35l56->base.dev, &dev_node), 0);
+ KUNIT_ASSERT_EQ(test, 0,
+ kunit_add_action_or_reset(test,
+ device_remove_software_node_wrapper,
+ cs35l56->base.dev));
+
+ KUNIT_EXPECT_EQ(test, cs35l56_get_firmware_uid(cs35l56), 0);
+ KUNIT_EXPECT_EQ(test, cs35l56_set_fw_name(cs35l56->component), 0);
+ KUNIT_EXPECT_STREQ(test, cs35l56->dsp.system_name, "acme-spkid1");
+}
+
static void cs35l56_test_l56_b0_suffix_sdw(struct kunit *test)
{
struct cs35l56_test_priv *priv = test->priv;
@@ -596,6 +668,10 @@ KUNIT_ARRAY_PARAM(cs35l56_test_type_rev_all, cs35l56_test_type_rev_all_param_cas
cs35l56_test_type_rev_param_desc);
static struct kunit_case cs35l56_test_cases_soundwire[] = {
+ KUNIT_CASE(cs35l56_test_system_name_from_ssid),
+ KUNIT_CASE(cs35l56_test_system_name_from_ssid_and_spkid),
+ KUNIT_CASE(cs35l56_test_system_name_from_property),
+ KUNIT_CASE(cs35l56_test_system_name_from_property_and_spkid),
KUNIT_CASE(cs35l56_test_l56_b0_suffix_sdw),
KUNIT_CASE_PARAM(cs35l56_test_suffix_sdw, cs35l56_test_type_rev_ex_b0_gen_params),
KUNIT_CASE_PARAM(cs35l56_test_ssidexv2_suffix_sdw,
@@ -613,6 +689,10 @@ static struct kunit_case cs35l56_test_cases_soundwire[] = {
};
static struct kunit_case cs35l56_test_cases_not_soundwire[] = {
+ KUNIT_CASE(cs35l56_test_system_name_from_ssid),
+ KUNIT_CASE(cs35l56_test_system_name_from_ssid_and_spkid),
+ KUNIT_CASE(cs35l56_test_system_name_from_property),
+ KUNIT_CASE(cs35l56_test_system_name_from_property_and_spkid),
KUNIT_CASE_PARAM(cs35l56_test_suffix_i2cspi, cs35l56_test_type_rev_all_gen_params),
KUNIT_CASE_PARAM(cs35l56_test_ssidexv2_suffix_i2cspi,
cs35l56_test_type_rev_all_gen_params),
diff --git a/sound/soc/codecs/cs35l56.c b/sound/soc/codecs/cs35l56.c
index 37909a319f88..9d35797e000a 100644
--- a/sound/soc/codecs/cs35l56.c
+++ b/sound/soc/codecs/cs35l56.c
@@ -1669,7 +1669,7 @@ VISIBLE_IF_KUNIT int cs35l56_process_xu_properties(struct cs35l56_private *cs35l
}
EXPORT_SYMBOL_IF_KUNIT(cs35l56_process_xu_properties);
-static int cs35l56_get_firmware_uid(struct cs35l56_private *cs35l56)
+VISIBLE_IF_KUNIT int cs35l56_get_firmware_uid(struct cs35l56_private *cs35l56)
{
struct device *dev = cs35l56->base.dev;
const char *prop;
@@ -1694,6 +1694,7 @@ static int cs35l56_get_firmware_uid(struct cs35l56_private *cs35l56)
return 0;
}
+EXPORT_SYMBOL_IF_KUNIT(cs35l56_get_firmware_uid);
/*
* Some SoundWire laptops have a spk-id-gpios property but it points to
diff --git a/sound/soc/codecs/cs35l56.h b/sound/soc/codecs/cs35l56.h
index 691f857d0bd8..747529be3e2e 100644
--- a/sound/soc/codecs/cs35l56.h
+++ b/sound/soc/codecs/cs35l56.h
@@ -78,6 +78,7 @@ void cs35l56_remove(struct cs35l56_private *cs35l56);
int cs35l56_set_fw_suffix(struct cs35l56_private *cs35l56);
int cs35l56_set_fw_name(struct snd_soc_component *component);
int cs35l56_process_xu_properties(struct cs35l56_private *cs35l56);
+int cs35l56_get_firmware_uid(struct cs35l56_private *cs35l56);
#endif
#endif /* ifndef CS35L56_H */
--
2.47.3
^ permalink raw reply related [flat|nested] 6+ messages in thread
* [PATCH 2/4] ASoC: cs35l56: Some KUnit testing of cs35l56_get_speaker_id()
2026-03-04 16:23 [PATCH 0/4] ASoC: cs35l56: More KUnit tests for speaker ID Richard Fitzgerald
2026-03-04 16:23 ` [PATCH 1/4] ASoC: cs35l56: KUnit tests for setting dsp.system_name Richard Fitzgerald
@ 2026-03-04 16:24 ` Richard Fitzgerald
2026-03-04 16:24 ` [PATCH 3/4] ASoC: cs35l56: KUnit tests for reading speaker ID from host GPIOs Richard Fitzgerald
` (2 subsequent siblings)
4 siblings, 0 replies; 6+ messages in thread
From: Richard Fitzgerald @ 2026-03-04 16:24 UTC (permalink / raw)
To: broonie, brendan.higgins, davidgow, raemoar63
Cc: linux-sound, linux-kselftest, kunit-dev, linux-kernel, patches
Add some KUnit tests for cs35l56_get_speaker_id().
These only test the simpler cases of reading the speaker ID from
cs_amp_get_vendor_spkid() or the "cirrus,speaker-id" property.
The untested case is reading it from GPIOs, which would require
a dummy implementation of a GPIO driver.
Signed-off-by: Richard Fitzgerald <rf@opensource.cirrus.com>
---
sound/soc/codecs/cs-amp-lib.c | 2 ++
sound/soc/codecs/cs35l56-shared-test.c | 43 ++++++++++++++++++++++++++
2 files changed, 45 insertions(+)
diff --git a/sound/soc/codecs/cs-amp-lib.c b/sound/soc/codecs/cs-amp-lib.c
index 8b131975143d..b34b1f5f121f 100644
--- a/sound/soc/codecs/cs-amp-lib.c
+++ b/sound/soc/codecs/cs-amp-lib.c
@@ -716,6 +716,8 @@ int cs_amp_get_vendor_spkid(struct device *dev)
{
int i, ret;
+ KUNIT_STATIC_STUB_REDIRECT(cs_amp_get_vendor_spkid, dev);
+
if (!efi_rt_services_supported(EFI_RT_SUPPORTED_GET_VARIABLE) &&
!IS_ENABLED(CONFIG_SND_SOC_CS_AMP_LIB_TEST_HOOKS))
return -ENOENT;
diff --git a/sound/soc/codecs/cs35l56-shared-test.c b/sound/soc/codecs/cs35l56-shared-test.c
index 94db02aef7dc..d510893dcd44 100644
--- a/sound/soc/codecs/cs35l56-shared-test.c
+++ b/sound/soc/codecs/cs35l56-shared-test.c
@@ -37,6 +37,10 @@ KUNIT_DEFINE_ACTION_WRAPPER(faux_device_destroy_wrapper, faux_device_destroy,
KUNIT_DEFINE_ACTION_WRAPPER(regmap_exit_wrapper, regmap_exit, struct regmap *)
+KUNIT_DEFINE_ACTION_WRAPPER(device_remove_software_node_wrapper,
+ device_remove_software_node,
+ struct device *)
+
static const struct regmap_config cs35l56_shared_test_mock_registers_regmap = {
.reg_bits = 32,
.val_bits = 32,
@@ -410,6 +414,41 @@ static void cs35l56_shared_test_onchip_speaker_id_not_defined(struct kunit *test
KUNIT_EXPECT_EQ(test, cs35l56_read_onchip_spkid(cs35l56_base), -ENOENT);
}
+/* simulate cs_amp_get_vendor_spkid() reading a vendor-specific ID of 1 */
+static int cs35l56_shared_test_get_vendor_spkid_1(struct device *dev)
+{
+ return 1;
+}
+
+static void cs35l56_shared_test_get_speaker_id_vendor(struct kunit *test)
+{
+ struct cs35l56_shared_test_priv *priv = test->priv;
+
+ /* Hook cs_amp_get_vendor_spkid() to return an ID of 1 */
+ kunit_activate_static_stub(test, cs_amp_get_vendor_spkid,
+ cs35l56_shared_test_get_vendor_spkid_1);
+
+ KUNIT_EXPECT_EQ(test, cs35l56_get_speaker_id(priv->cs35l56_base), 1);
+}
+
+static void cs35l56_shared_test_get_speaker_id_property(struct kunit *test)
+{
+ struct cs35l56_shared_test_priv *priv = test->priv;
+ const struct property_entry dev_props[] = {
+ PROPERTY_ENTRY_U32("cirrus,speaker-id", 2),
+ { }
+ };
+ const struct software_node dev_node = SOFTWARE_NODE("SPK1", dev_props, NULL);
+
+ KUNIT_ASSERT_EQ(test, device_add_software_node(priv->cs35l56_base->dev, &dev_node), 0);
+ KUNIT_ASSERT_EQ(test, 0,
+ kunit_add_action_or_reset(test,
+ device_remove_software_node_wrapper,
+ priv->cs35l56_base->dev));
+
+ KUNIT_EXPECT_EQ(test, cs35l56_get_speaker_id(priv->cs35l56_base), 2);
+}
+
static int cs35l56_shared_test_case_regmap_init(struct kunit *test,
const struct regmap_config *regmap_config)
{
@@ -616,6 +655,10 @@ static struct kunit_case cs35l56_shared_test_cases[] = {
cs35l56_shared_test_onchip_spkid_pull_gen_params),
KUNIT_CASE(cs35l56_shared_test_stash_onchip_spkid_pins_reject_invalid),
KUNIT_CASE(cs35l56_shared_test_onchip_speaker_id_not_defined),
+
+ KUNIT_CASE(cs35l56_shared_test_get_speaker_id_vendor),
+ KUNIT_CASE(cs35l56_shared_test_get_speaker_id_property),
+
{ }
};
--
2.47.3
^ permalink raw reply related [flat|nested] 6+ messages in thread
* [PATCH 3/4] ASoC: cs35l56: KUnit tests for reading speaker ID from host GPIOs
2026-03-04 16:23 [PATCH 0/4] ASoC: cs35l56: More KUnit tests for speaker ID Richard Fitzgerald
2026-03-04 16:23 ` [PATCH 1/4] ASoC: cs35l56: KUnit tests for setting dsp.system_name Richard Fitzgerald
2026-03-04 16:24 ` [PATCH 2/4] ASoC: cs35l56: Some KUnit testing of cs35l56_get_speaker_id() Richard Fitzgerald
@ 2026-03-04 16:24 ` Richard Fitzgerald
2026-03-04 16:24 ` [PATCH 4/4] kunit: config: all_tests: Select CONFIG_GPIOLIB Richard Fitzgerald
2026-03-05 22:49 ` (subset) [PATCH 0/4] ASoC: cs35l56: More KUnit tests for speaker ID Mark Brown
4 siblings, 0 replies; 6+ messages in thread
From: Richard Fitzgerald @ 2026-03-04 16:24 UTC (permalink / raw)
To: broonie, brendan.higgins, davidgow, raemoar63
Cc: linux-sound, linux-kselftest, kunit-dev, linux-kernel, patches
Add test cases for the spk-id-gpios property used to read an integer
speaker ID value from a set of GPIO inputs.
There is a single parameterized test function,
cs35l56_shared_test_get_speaker_id_from_host_gpio() that does
the following:
- Create a mock GPIO driver to simulate real GPIO inputs.
- Create an array of struct software_node_ref_args to provide the
content of the spk-id-gpios property. Each entry is a reference to
a GPIO on the mock GPIO driver. The GPIO indexes are taken from test
case parameterization.
- Create a software node containing the spk-id-gpios property and set
this as the node of the pseudo codec driver device.
- Call cs35l56_get_speaker_id() and assert that the returned value
matches the expected value defined in the test case parameterization.
Signed-off-by: Richard Fitzgerald <rf@opensource.cirrus.com>
---
sound/soc/codecs/cs35l56-shared-test.c | 197 +++++++++++++++++++++++++
1 file changed, 197 insertions(+)
diff --git a/sound/soc/codecs/cs35l56-shared-test.c b/sound/soc/codecs/cs35l56-shared-test.c
index d510893dcd44..cfe7938065f9 100644
--- a/sound/soc/codecs/cs35l56-shared-test.c
+++ b/sound/soc/codecs/cs35l56-shared-test.c
@@ -11,15 +11,23 @@
#include <linux/bitfield.h>
#include <linux/bitops.h>
#include <linux/device/faux.h>
+#include <linux/gpio/driver.h>
#include <linux/module.h>
#include <linux/random.h>
#include <linux/regmap.h>
#include <linux/seq_buf.h>
#include <sound/cs35l56.h>
+struct cs35l56_shared_test_mock_gpio {
+ unsigned int pin_state;
+ struct gpio_chip chip;
+};
+
struct cs35l56_shared_test_priv {
struct kunit *test;
struct faux_device *amp_dev;
+ struct faux_device *gpio_dev;
+ struct cs35l56_shared_test_mock_gpio *gpio_priv;
struct regmap *registers;
struct cs35l56_base *cs35l56_base;
u8 applied_pad_pull_state[CS35L56_MAX_GPIO];
@@ -41,6 +49,90 @@ KUNIT_DEFINE_ACTION_WRAPPER(device_remove_software_node_wrapper,
device_remove_software_node,
struct device *)
+static int cs35l56_shared_test_mock_gpio_get_direction(struct gpio_chip *chip,
+ unsigned int offset)
+{
+ return GPIO_LINE_DIRECTION_IN;
+}
+
+static int cs35l56_shared_test_mock_gpio_direction_in(struct gpio_chip *chip,
+ unsigned int offset)
+{
+ return 0;
+}
+
+static int cs35l56_shared_test_mock_gpio_get(struct gpio_chip *chip, unsigned int offset)
+{
+ struct cs35l56_shared_test_mock_gpio *gpio_priv = gpiochip_get_data(chip);
+
+ return !!(gpio_priv->pin_state & BIT(offset));
+}
+
+static const struct gpio_chip cs35l56_shared_test_mock_gpio_chip = {
+ .label = "cs35l56_shared_test_mock_gpio",
+ .owner = THIS_MODULE,
+ .get_direction = cs35l56_shared_test_mock_gpio_get_direction,
+ .direction_input = cs35l56_shared_test_mock_gpio_direction_in,
+ .get = cs35l56_shared_test_mock_gpio_get,
+ .base = -1,
+ .ngpio = 32,
+};
+
+/* software_node referencing the gpio driver */
+static const struct software_node cs35l56_shared_test_mock_gpio_swnode = {
+ .name = "cs35l56_shared_test_mock_gpio",
+};
+
+static int cs35l56_shared_test_mock_gpio_probe(struct faux_device *fdev)
+{
+ struct cs35l56_shared_test_mock_gpio *gpio_priv;
+ struct device *dev = &fdev->dev;
+ int ret;
+
+ gpio_priv = devm_kzalloc(dev, sizeof(*gpio_priv), GFP_KERNEL);
+ if (!gpio_priv)
+ return -ENOMEM;
+
+ ret = device_add_software_node(dev, &cs35l56_shared_test_mock_gpio_swnode);
+ if (ret)
+ return ret;
+
+ ret = devm_add_action_or_reset(dev, device_remove_software_node_wrapper, dev);
+ if (ret)
+ return ret;
+
+ /* GPIO core modifies our struct gpio_chip so use a copy */
+ gpio_priv->chip = cs35l56_shared_test_mock_gpio_chip;
+ gpio_priv->chip.parent = dev;
+ ret = devm_gpiochip_add_data(dev, &gpio_priv->chip, gpio_priv);
+ if (ret)
+ return dev_err_probe(dev, ret, "Failed to add gpiochip\n");
+
+ dev_set_drvdata(dev, gpio_priv);
+
+ return 0;
+}
+
+static struct faux_device_ops cs35l56_shared_test_mock_gpio_drv = {
+ .probe = cs35l56_shared_test_mock_gpio_probe,
+};
+
+static void _cs35l56_shared_test_create_dummy_gpio(struct kunit *test)
+{
+ struct cs35l56_shared_test_priv *priv = test->priv;
+
+ priv->gpio_dev = faux_device_create("cs35l56_shared_test_mock_gpio", NULL,
+ &cs35l56_shared_test_mock_gpio_drv);
+ KUNIT_ASSERT_NOT_NULL(test, priv->gpio_dev);
+ KUNIT_ASSERT_EQ(test, 0,
+ kunit_add_action_or_reset(test,
+ faux_device_destroy_wrapper,
+ priv->gpio_dev));
+
+ priv->gpio_priv = dev_get_drvdata(&priv->gpio_dev->dev);
+ KUNIT_ASSERT_NOT_NULL(test, priv->gpio_priv);
+}
+
static const struct regmap_config cs35l56_shared_test_mock_registers_regmap = {
.reg_bits = 32,
.val_bits = 32,
@@ -449,6 +541,74 @@ static void cs35l56_shared_test_get_speaker_id_property(struct kunit *test)
KUNIT_EXPECT_EQ(test, cs35l56_get_speaker_id(priv->cs35l56_base), 2);
}
+/*
+ * Create software nodes equivalent to ACPI structure
+ *
+ * Device(GSPK) {
+ * Name(_DSD, ...) {
+ * Package() {
+ * cs-gpios {
+ * GPIO, n, 0,
+ * ...
+ * }
+ * }
+ */
+static void _cs35l56_shared_test_create_spkid_swnode(struct kunit *test,
+ struct device *dev,
+ const struct software_node_ref_args *args,
+ int num_args)
+{
+ struct cs35l56_shared_test_priv *priv = test->priv;
+ const struct property_entry props_template[] = {
+ PROPERTY_ENTRY_REF_ARRAY_LEN("spk-id-gpios", args, num_args),
+ { }
+ };
+ struct property_entry *props;
+ struct software_node *node;
+
+ props = kunit_kzalloc(test, sizeof(props_template), GFP_KERNEL);
+ KUNIT_ASSERT_NOT_NULL(test, props);
+ memcpy(props, props_template, sizeof(props_template));
+
+ node = kunit_kzalloc(test, sizeof(*node), GFP_KERNEL);
+ KUNIT_ASSERT_NOT_NULL(test, node);
+ *node = SOFTWARE_NODE("GSPK", props, NULL);
+
+ KUNIT_ASSERT_EQ(test, device_add_software_node(dev, node), 0);
+ KUNIT_ASSERT_EQ(test, 0,
+ kunit_add_action_or_reset(test,
+ device_remove_software_node_wrapper,
+ priv->cs35l56_base->dev));
+}
+
+static void cs35l56_shared_test_get_speaker_id_from_host_gpio(struct kunit *test)
+{
+ const struct cs35l56_shared_test_param *param = test->param_value;
+ struct cs35l56_shared_test_priv *priv = test->priv;
+ struct cs35l56_base *cs35l56_base = priv->cs35l56_base;
+ struct software_node_ref_args *ref;
+ int i;
+
+ if (!IS_REACHABLE(CONFIG_GPIOLIB)) {
+ kunit_skip(test, "Requires CONFIG_GPIOLIB");
+ return;
+ }
+
+ _cs35l56_shared_test_create_dummy_gpio(test);
+
+ ref = kunit_kcalloc(test, ARRAY_SIZE(param->spkid_gpios), sizeof(*ref), GFP_KERNEL);
+ KUNIT_ASSERT_NOT_NULL(test, ref);
+
+ for (i = 0; param->spkid_gpios[i] >= 0; i++) {
+ ref[i] = SOFTWARE_NODE_REFERENCE(&cs35l56_shared_test_mock_gpio_swnode,
+ param->spkid_gpios[i], 0);
+ }
+ _cs35l56_shared_test_create_spkid_swnode(test, cs35l56_base->dev, ref, i);
+
+ priv->gpio_priv->pin_state = param->gpio_status;
+ KUNIT_EXPECT_EQ(test, cs35l56_get_speaker_id(priv->cs35l56_base), param->spkid);
+}
+
static int cs35l56_shared_test_case_regmap_init(struct kunit *test,
const struct regmap_config *regmap_config)
{
@@ -641,6 +801,40 @@ KUNIT_ARRAY_PARAM(cs35l56_shared_test_onchip_spkid_pull,
cs35l56_shared_test_onchip_spkid_pull_cases,
cs35l56_shared_test_gpio_param_desc);
+/* Note: spk-id-gpios property bit order is LSbit...MSbit */
+static const struct cs35l56_shared_test_param cs35l56_shared_test_host_gpio_spkid_cases[] = {
+ { .spkid_gpios = { 0, -1 }, .gpio_status = 0, .spkid = 0 },
+ { .spkid_gpios = { 0, -1 }, .gpio_status = ~BIT(0), .spkid = 0 },
+ { .spkid_gpios = { 0, -1 }, .gpio_status = BIT(0), .spkid = 1 },
+
+ { .spkid_gpios = { 6, -1 }, .gpio_status = 0, .spkid = 0 },
+ { .spkid_gpios = { 6, -1 }, .gpio_status = ~BIT(6), .spkid = 0 },
+ { .spkid_gpios = { 6, -1 }, .gpio_status = BIT(6), .spkid = 1 },
+
+ { .spkid_gpios = { 6, 0, -1 }, .gpio_status = 0, .spkid = 0 },
+ { .spkid_gpios = { 6, 0, -1 }, .gpio_status = ~(BIT(0) | BIT(6)), .spkid = 0 },
+ { .spkid_gpios = { 6, 0, -1 }, .gpio_status = BIT(6), .spkid = 1 },
+ { .spkid_gpios = { 6, 0, -1 }, .gpio_status = BIT(0), .spkid = 2 },
+ { .spkid_gpios = { 6, 0, -1 }, .gpio_status = BIT(6) | BIT(0), .spkid = 3 },
+
+ { .spkid_gpios = { 0, 6, -1 }, .gpio_status = 0, .spkid = 0 },
+ { .spkid_gpios = { 0, 6, -1 }, .gpio_status = ~(BIT(6) | BIT(0)), .spkid = 0 },
+ { .spkid_gpios = { 0, 6, -1 }, .gpio_status = BIT(0), .spkid = 1 },
+ { .spkid_gpios = { 0, 6, -1 }, .gpio_status = BIT(6), .spkid = 2 },
+ { .spkid_gpios = { 0, 6, -1 }, .gpio_status = BIT(6) | BIT(0), .spkid = 3 },
+
+ { .spkid_gpios = { 0, 6, 2, -1 }, .gpio_status = 0, .spkid = 0 },
+ { .spkid_gpios = { 0, 6, 2, -1 }, .gpio_status = BIT(0), .spkid = 1 },
+ { .spkid_gpios = { 0, 6, 2, -1 }, .gpio_status = BIT(6), .spkid = 2 },
+ { .spkid_gpios = { 0, 6, 2, -1 }, .gpio_status = BIT(6) | BIT(0), .spkid = 3 },
+ { .spkid_gpios = { 0, 6, 2, -1 }, .gpio_status = BIT(2), .spkid = 4 },
+ { .spkid_gpios = { 0, 6, 2, -1 }, .gpio_status = BIT(2) | BIT(0), .spkid = 5 },
+ { .spkid_gpios = { 0, 6, 2, -1 }, .gpio_status = BIT(2) | BIT(6), .spkid = 6 },
+ { .spkid_gpios = { 0, 6, 2, -1 }, .gpio_status = BIT(2) | BIT(6) | BIT(0), .spkid = 7 },
+};
+KUNIT_ARRAY_PARAM(cs35l56_shared_test_host_gpio_spkid, cs35l56_shared_test_host_gpio_spkid_cases,
+ cs35l56_shared_test_gpio_param_desc);
+
static struct kunit_case cs35l56_shared_test_cases[] = {
/* Tests for speaker id */
KUNIT_CASE_PARAM(cs35l56_shared_test_mock_gpio_status_selftest,
@@ -658,6 +852,9 @@ static struct kunit_case cs35l56_shared_test_cases[] = {
KUNIT_CASE(cs35l56_shared_test_get_speaker_id_vendor),
KUNIT_CASE(cs35l56_shared_test_get_speaker_id_property),
+ KUNIT_CASE_PARAM_ATTR(cs35l56_shared_test_get_speaker_id_from_host_gpio,
+ cs35l56_shared_test_host_gpio_spkid_gen_params,
+ { KUNIT_SPEED_SLOW }),
{ }
};
--
2.47.3
^ permalink raw reply related [flat|nested] 6+ messages in thread
* [PATCH 4/4] kunit: config: all_tests: Select CONFIG_GPIOLIB
2026-03-04 16:23 [PATCH 0/4] ASoC: cs35l56: More KUnit tests for speaker ID Richard Fitzgerald
` (2 preceding siblings ...)
2026-03-04 16:24 ` [PATCH 3/4] ASoC: cs35l56: KUnit tests for reading speaker ID from host GPIOs Richard Fitzgerald
@ 2026-03-04 16:24 ` Richard Fitzgerald
2026-03-05 22:49 ` (subset) [PATCH 0/4] ASoC: cs35l56: More KUnit tests for speaker ID Mark Brown
4 siblings, 0 replies; 6+ messages in thread
From: Richard Fitzgerald @ 2026-03-04 16:24 UTC (permalink / raw)
To: broonie, brendan.higgins, davidgow, raemoar63
Cc: linux-sound, linux-kselftest, kunit-dev, linux-kernel, patches
Add CONFIG_GPIOLIB to the all_tests config so that it can run test
cases that create dummy GPIO drivers.
Some tests for the Cirrus Logic cs35l56 ASoC codec driver and
cirrus_scodec HDA driver create a dummy GPIO driver so they can
test driver functions that read from the GPIOs. These tests will be
skipped if CONFIG_GPIOLIB is not set. Ideally we would like them to
be run when selecting --alltests.
CONFIG_GPIOLIB does not have any dependencies and only enables
generic library code.
Signed-off-by: Richard Fitzgerald <rf@opensource.cirrus.com>
---
tools/testing/kunit/configs/all_tests.config | 2 ++
1 file changed, 2 insertions(+)
diff --git a/tools/testing/kunit/configs/all_tests.config b/tools/testing/kunit/configs/all_tests.config
index 422e186cf3cf..e21239dc6fae 100644
--- a/tools/testing/kunit/configs/all_tests.config
+++ b/tools/testing/kunit/configs/all_tests.config
@@ -40,6 +40,8 @@ CONFIG_DAMON=y
CONFIG_DAMON_VADDR=y
CONFIG_DAMON_PADDR=y
+CONFIG_GPIOLIB=y
+
CONFIG_REGMAP_BUILD=y
CONFIG_AUDIT=y
--
2.47.3
^ permalink raw reply related [flat|nested] 6+ messages in thread
* Re: (subset) [PATCH 0/4] ASoC: cs35l56: More KUnit tests for speaker ID
2026-03-04 16:23 [PATCH 0/4] ASoC: cs35l56: More KUnit tests for speaker ID Richard Fitzgerald
` (3 preceding siblings ...)
2026-03-04 16:24 ` [PATCH 4/4] kunit: config: all_tests: Select CONFIG_GPIOLIB Richard Fitzgerald
@ 2026-03-05 22:49 ` Mark Brown
4 siblings, 0 replies; 6+ messages in thread
From: Mark Brown @ 2026-03-05 22:49 UTC (permalink / raw)
To: brendan.higgins, davidgow, raemoar63, Richard Fitzgerald
Cc: linux-sound, linux-kselftest, kunit-dev, linux-kernel, patches
On Wed, 04 Mar 2026 16:23:58 +0000, Richard Fitzgerald wrote:
> The first 3 patches in this series add some more KUnit testing for
> fetching speaker ID and combining it with the system name to create
> part of the qualifier for a firmware filename.
>
> Patch #4 enables GPIOLIB in KUnit 'alltests' builds. This can be taken
> separately from the first 3 patches.
>
> [...]
Applied to
https://git.kernel.org/pub/scm/linux/kernel/git/broonie/sound.git for-next
Thanks!
[1/4] ASoC: cs35l56: KUnit tests for setting dsp.system_name
commit: bae6668c526018af45b70e7825b61e6edb528f41
[2/4] ASoC: cs35l56: Some KUnit testing of cs35l56_get_speaker_id()
commit: 72e1c4704844766c46725d6b043ba04559054d02
[3/4] ASoC: cs35l56: KUnit tests for reading speaker ID from host GPIOs
commit: ef0b4783afc211a4b120e72b5a57f3d0340a9981
All being well this means that it will be integrated into the linux-next
tree (usually sometime in the next 24 hours) and sent to Linus during
the next merge window (or sooner if it is a bug fix), however if
problems are discovered then the patch may be dropped or reverted.
You may get further e-mails resulting from automated or manual testing
and review of the tree, please engage with people reporting problems and
send followup patches addressing any issues that are reported if needed.
If any updates are required or you are submitting further changes they
should be sent as incremental updates against current git, existing
patches will not be replaced.
Please add any relevant lists and maintainers to the CCs when replying
to this mail.
Thanks,
Mark
^ permalink raw reply [flat|nested] 6+ messages in thread
end of thread, other threads:[~2026-03-05 22:49 UTC | newest]
Thread overview: 6+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-03-04 16:23 [PATCH 0/4] ASoC: cs35l56: More KUnit tests for speaker ID Richard Fitzgerald
2026-03-04 16:23 ` [PATCH 1/4] ASoC: cs35l56: KUnit tests for setting dsp.system_name Richard Fitzgerald
2026-03-04 16:24 ` [PATCH 2/4] ASoC: cs35l56: Some KUnit testing of cs35l56_get_speaker_id() Richard Fitzgerald
2026-03-04 16:24 ` [PATCH 3/4] ASoC: cs35l56: KUnit tests for reading speaker ID from host GPIOs Richard Fitzgerald
2026-03-04 16:24 ` [PATCH 4/4] kunit: config: all_tests: Select CONFIG_GPIOLIB Richard Fitzgerald
2026-03-05 22:49 ` (subset) [PATCH 0/4] ASoC: cs35l56: More KUnit tests for speaker ID Mark Brown
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox