* [PATCH 1/2] ASoC: cs35l56: Use Disco FEID and FEV to qualify firmware filenames
2026-11-10 16:48 [PATCH 0/2] ASoC: cs35l56: Consider SDCA FunctionExtension ID/Version for firmware name Richard Fitzgerald
@ 2026-11-10 16:48 ` Richard Fitzgerald
2026-11-10 16:48 ` [PATCH 2/2] ASoC: cs35l56: Add KUnit tests for FEID and FEV firmware names Richard Fitzgerald
1 sibling, 0 replies; 3+ messages in thread
From: Richard Fitzgerald @ 2026-11-10 16:48 UTC (permalink / raw)
To: broonie; +Cc: linux-sound, linux-kernel, patches
Include the FunctionExtensionID (FEID) and FunctionExtensionVersion (FEV)
values from Disco as qualifiers on firmware names. This mechanism is
required to support new products that use CS35L56/57/62/63.
Some manufacturers are starting to re-use SSIDs, and the time between
re-use is decreasing. The SSID is therefore no longer providing the
unique hardware identifier intended by the PCI spec.
To ensure that the audio hardware can be uniquely identified, the FEID
and FEV will be included in the Disco for new products and must be
used to qualify the firmware filename (unless FEID==0). For products that
require an SSID match, the combination of SSID, FEID, FEV will be unique.
The implementation is backward-compatible. All existing SKUs either don't
have FEID in Disco, or it has a value of 0. For compatibility with Windows
behaviour the value of 0 means "ignore".
Behaviour is:
FEID missing: Legacy behaviour, SSID qualified firmware name.
Firmware system name only created if SSID available.
FEID == 0: Legacy behaviour, SSID qualified firmware name.
Firmware system name only created if SSID available.
FEID > 0 and < 0x8000: Firmware name qualified with SSID, FEID and FEV.
If SSID is missing the system_name is left NULL to
preserve the existing fallback behaviour.
FEID >= 0x8000: Firmware name qualified with FEID and FEV only,
SSID not used.
Signed-off-by: Richard Fitzgerald <rf@opensource.cirrus.com>
---
sound/soc/codecs/cs35l56.c | 163 ++++++++++++++++++++++++++++++++-----
sound/soc/codecs/cs35l56.h | 3 +
2 files changed, 145 insertions(+), 21 deletions(-)
diff --git a/sound/soc/codecs/cs35l56.c b/sound/soc/codecs/cs35l56.c
index a4d25c287941..b44964a13111 100644
--- a/sound/soc/codecs/cs35l56.c
+++ b/sound/soc/codecs/cs35l56.c
@@ -9,6 +9,7 @@
#include <kunit/visibility.h>
#include <linux/acpi.h>
#include <linux/array_size.h>
+#include <linux/cleanup.h>
#include <linux/completion.h>
#include <linux/debugfs.h>
#include <linux/delay.h>
@@ -19,6 +20,7 @@
#include <linux/math.h>
#include <linux/module.h>
#include <linux/mutex.h>
+#include <linux/overflow.h>
#include <linux/pm.h>
#include <linux/pm_runtime.h>
#include <linux/property.h>
@@ -32,6 +34,7 @@
#include <sound/cs-amp-lib.h>
#include <sound/pcm.h>
#include <sound/pcm_params.h>
+#include <sound/sdca_function.h>
#include <sound/sdw.h>
#include <sound/soc.h>
#include <sound/soc-dapm.h>
@@ -1387,6 +1390,9 @@ VISIBLE_IF_KUNIT int cs35l56_set_fw_name(struct snd_soc_component *component)
{
struct cs35l56_private *cs35l56 = snd_soc_component_get_drvdata(component);
unsigned short vendor, device;
+ char ssid[9] = "";
+ char fe[10] = "";
+ const char *separator = "";
int ret;
if ((cs35l56->speaker_id < 0) && cs35l56->base.num_onchip_spkid_gpios) {
@@ -1406,20 +1412,38 @@ VISIBLE_IF_KUNIT int cs35l56_set_fw_name(struct snd_soc_component *component)
cs35l56->speaker_id = ret;
}
- if (!cs35l56->dsp.system_name &&
- (snd_soc_card_get_pci_ssid(component->card, &vendor, &device) == 0)) {
+ if (!cs35l56->dsp.system_name) {
+ if (cs35l56->feid < 0x8000) {
+ if (snd_soc_card_get_pci_ssid(component->card, &vendor, &device) == 0) {
+ snprintf(ssid, sizeof(ssid), "%04x%04x", vendor, device);
+ separator = "-";
+ } else if (cs35l56->feid) {
+ dev_err(cs35l56->base.dev, "SSID required but not available\n");
+
+ /* Don't return error: allow falling back to default firmware */
+ return 0;
+ } else {
+ return 0;
+ }
+ }
+
+ if (cs35l56->feid) {
+ snprintf(fe, sizeof(fe), "%sf%xv%x", separator,
+ cs35l56->feid, cs35l56->fev);
+ }
+
/* Append a speaker qualifier if there is a speaker ID */
if (cs35l56->speaker_id >= 0) {
cs35l56->dsp.system_name = devm_kasprintf(cs35l56->base.dev,
GFP_KERNEL,
- "%04x%04x-spkid%d",
- vendor, device,
+ "%s%s-spkid%d",
+ ssid, fe,
cs35l56->speaker_id);
} else {
cs35l56->dsp.system_name = devm_kasprintf(cs35l56->base.dev,
GFP_KERNEL,
- "%04x%04x",
- vendor, device);
+ "%s%s",
+ ssid, fe);
}
if (!cs35l56->dsp.system_name)
return -ENOMEM;
@@ -1868,31 +1892,128 @@ static int cs35l56_process_xu_onchip_speaker_id(struct cs35l56_private *cs35l56,
return 0;
}
+static int cs35l56_read_subproperty_control_dc(struct cs35l56_private *cs35l56,
+ struct fwnode_handle *node,
+ const char *subname,
+ int width)
+{
+ static const char * const control_dc_value_prop_name = "mipi-sdca-control-dc-value";
+ u8 val8 = 0;
+ u16 val16 = 0;
+ u32 val32;
+ int ret;
+
+ struct fwnode_handle *subnode __free(fwnode_handle) =
+ fwnode_get_named_child_node(node, subname);
+ if (!subnode)
+ return -EINVAL;
+
+ switch (width) {
+ case 8:
+ ret = fwnode_property_read_u8(subnode, control_dc_value_prop_name, &val8);
+ val32 = val8;
+ break;
+ case 16:
+ ret = fwnode_property_read_u16(subnode, control_dc_value_prop_name, &val16);
+ val32 = val16;
+ break;
+ default:
+ ret = fwnode_property_read_u32(subnode, control_dc_value_prop_name, &val32);
+ break;
+ }
+
+ if (ret == -EINVAL)
+ return ret;
+
+ if (ret < 0) {
+ dev_warn(cs35l56->base.dev, "Failed to get dc-value for %s: %d\n",
+ subname, ret);
+ return ret;
+ }
+
+ /* None of the values we need are this big */
+ if (overflows_type(val32, int))
+ return -EINVAL;
+
+ return (int)val32;
+}
+
+static int cs35l56_process_feid_fev(struct cs35l56_private *cs35l56,
+ struct fwnode_handle *node)
+{
+ int ret;
+
+ /* Either property overrides default of 0. This matches Windows behavior */
+ ret = cs35l56_read_subproperty_control_dc(cs35l56, node,
+ "mipi-sdca-control-0x9-subproperties",
+ 16);
+ if (ret >= 0) {
+ cs35l56->feid = (u16)ret;
+ dev_dbg(cs35l56->base.dev, "FEID=%#x\n", cs35l56->feid);
+ } else if (ret != -EINVAL) {
+ return ret;
+ }
+
+ ret = cs35l56_read_subproperty_control_dc(cs35l56, node,
+ "mipi-sdca-control-0xA-subproperties",
+ 8);
+ if (ret >= 0) {
+ cs35l56->fev = (u8)ret;
+ dev_dbg(cs35l56->base.dev, "FEV=%#x\n", cs35l56->fev);
+ } else if (ret != -EINVAL) {
+ return ret;
+ }
+
+ return 0;
+}
+
+static int cs35l56_process_disco_control5(struct cs35l56_private *cs35l56,
+ struct fwnode_handle *node)
+{
+ int ret;
+
+ /*
+ * Don't fail probe because of a malformed property.
+ * It might be a property we are not interested in anyway.
+ */
+ ret = cs35l56_read_subproperty_control_dc(cs35l56, node,
+ "mipi-sdca-control-0x5-subproperties",
+ 32);
+ if (ret < 0)
+ return 0;
+
+ if (ret != SDCA_FUNCTION_TYPE_SMART_AMP)
+ return 0;
+
+ return cs35l56_process_feid_fev(cs35l56, node);
+}
+
VISIBLE_IF_KUNIT int cs35l56_process_xu_properties(struct cs35l56_private *cs35l56)
{
- struct fwnode_handle *ext_node = NULL;
- struct fwnode_handle *link;
int ret;
if (!cs35l56->sdw_peripheral)
return 0;
- fwnode_for_each_child_node(dev_fwnode(cs35l56->base.dev), link) {
- ext_node = fwnode_get_named_child_node(link,
- "mipi-sdca-function-expansion-subproperties");
- if (ext_node) {
- fwnode_handle_put(link);
- break;
+ fwnode_for_each_child_node_scoped(dev_fwnode(cs35l56->base.dev), link) {
+ ret = cs35l56_process_disco_control5(cs35l56, link);
+ if (ret)
+ return ret;
+
+ if (!cs35l56->base.num_onchip_spkid_gpios) {
+ struct fwnode_handle *ext_node __free(fwnode_handle) =
+ fwnode_get_named_child_node(link,
+ "mipi-sdca-function-expansion-subproperties");
+
+ if (ext_node) {
+ ret = cs35l56_process_xu_onchip_speaker_id(cs35l56, ext_node);
+ if (ret)
+ return ret;
+ }
}
}
- if (!ext_node)
- return 0;
-
- ret = cs35l56_process_xu_onchip_speaker_id(cs35l56, ext_node);
- fwnode_handle_put(ext_node);
-
- return ret;
+ return 0;
}
EXPORT_SYMBOL_IF_KUNIT(cs35l56_process_xu_properties);
diff --git a/sound/soc/codecs/cs35l56.h b/sound/soc/codecs/cs35l56.h
index b46f410f0e09..f55dab899f9d 100644
--- a/sound/soc/codecs/cs35l56.h
+++ b/sound/soc/codecs/cs35l56.h
@@ -56,6 +56,9 @@ struct cs35l56_private {
u8 sdw_link_num;
u8 sdw_unique_id;
+ u16 feid;
+ u8 fev;
+
u8 ambient_ctl_value;
};
--
2.47.3
^ permalink raw reply [flat|nested] 3+ messages in thread* [PATCH 2/2] ASoC: cs35l56: Add KUnit tests for FEID and FEV firmware names
2026-11-10 16:48 [PATCH 0/2] ASoC: cs35l56: Consider SDCA FunctionExtension ID/Version for firmware name Richard Fitzgerald
2026-11-10 16:48 ` [PATCH 1/2] ASoC: cs35l56: Use Disco FEID and FEV to qualify firmware filenames Richard Fitzgerald
@ 2026-11-10 16:48 ` Richard Fitzgerald
1 sibling, 0 replies; 3+ messages in thread
From: Richard Fitzgerald @ 2026-11-10 16:48 UTC (permalink / raw)
To: broonie; +Cc: linux-sound, linux-kernel, patches
Add parameterized tests for firmware system names qualified by Disco
FunctionExtensionId (FEID) and FunctionExtensionVersion (FEV). As these
are Disco values they only need to be tested for SoundWire.
Expected behaviour is:
FEID == 0
Previous behaviour unchanged. If SSID is present it is included in
system_name, else system_name is NULL. Value of FEV is ignored.
FEID > 1 and < 0x8000
SSID is mandatory. SSID, FEID and FEV are included in system name in
the format fFvV where F is FEID in hex and V is FEV in hex.
FEID >= 0x8000
SSID is ignored. FEID and FEV are included in system name in the
format fFvV where F is FEID in hex and V is FEV in hex.
In all cases speaker ID is appended to system name if a speaker ID value
is available.
Signed-off-by: Richard Fitzgerald <rf@opensource.cirrus.com>
---
sound/soc/codecs/cs35l56-test.c | 229 +++++++++++++++++++++++++++++++-
1 file changed, 225 insertions(+), 4 deletions(-)
diff --git a/sound/soc/codecs/cs35l56-test.c b/sound/soc/codecs/cs35l56-test.c
index 124fe5e75500..b58df099bf72 100644
--- a/sound/soc/codecs/cs35l56-test.c
+++ b/sound/soc/codecs/cs35l56-test.c
@@ -5,6 +5,7 @@
// Copyright (C) 2026 Cirrus Logic, Inc. and
// Cirrus Logic International Semiconductor Ltd.
+#include <kunit/fwnode.h>
#include <kunit/resource.h>
#include <kunit/test.h>
#include <kunit/static_stub.h>
@@ -20,6 +21,7 @@
#include <linux/soundwire/sdw.h>
#include <sound/cs35l56.h>
#include <sound/cs-amp-lib.h>
+#include <sound/sdca_function.h>
#include "cs35l56.h"
KUNIT_DEFINE_ACTION_WRAPPER(faux_device_destroy_wrapper, faux_device_destroy,
@@ -51,6 +53,16 @@ struct cs35l56_test_param {
u8 type;
u8 rev;
+ u16 feid;
+ u8 fev;
+ u32 function_type;
+ bool omit_feid;
+ bool omit_fev;
+ bool has_ssid;
+ int speaker_id;
+ const char *system_name;
+ int ret;
+
s32 spkid_gpios[4];
s32 spkid_pulls[4];
};
@@ -100,6 +112,24 @@ static void cs35l56_test_system_name_from_ssid_and_spkid(struct kunit *test)
KUNIT_EXPECT_STREQ(test, cs35l56->dsp.system_name, "12b4a7c8-spkid1");
}
+static void cs35l56_test_system_name_with_feid_fev(struct kunit *test)
+{
+ const struct cs35l56_test_param *param = test->param_value;
+ struct cs35l56_test_priv *priv = test->priv;
+ struct cs35l56_private *cs35l56 = priv->cs35l56_priv;
+
+ cs35l56->speaker_id = param->speaker_id;
+ if (param->has_ssid)
+ 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), param->ret);
+ if (param->system_name)
+ KUNIT_EXPECT_STREQ(test, cs35l56->dsp.system_name, param->system_name);
+ else
+ KUNIT_EXPECT_NULL(test, cs35l56->dsp.system_name);
+}
+
static void cs35l56_test_system_name_from_property(struct kunit *test)
{
struct cs35l56_test_priv *priv = test->priv;
@@ -442,6 +472,68 @@ static void cs35l56_test_parse_xu_onchip_spkid(struct kunit *test)
}
}
+static void cs35l56_test_parse_disco_feid_fev(struct kunit *test)
+{
+ static const char * const control_names[] = {
+ "mipi-sdca-control-0x5-subproperties",
+ "mipi-sdca-control-0x9-subproperties",
+ "mipi-sdca-control-0xA-subproperties",
+ };
+ const struct cs35l56_test_param *param = test->param_value;
+ struct cs35l56_test_priv *priv = test->priv;
+ struct cs35l56_private *cs35l56 = priv->cs35l56_priv;
+ struct {
+ struct software_node nodes[ARRAY_SIZE(control_names)];
+ struct property_entry props[ARRAY_SIZE(control_names)][2];
+ } *disco;
+ int ret;
+
+ disco = kunit_kzalloc(test, sizeof(*disco), GFP_KERNEL);
+ KUNIT_ASSERT_NOT_NULL(test, disco);
+
+ disco->props[0][0] = PROPERTY_ENTRY_U32("mipi-sdca-control-dc-value",
+ param->function_type);
+ disco->props[1][0] = PROPERTY_ENTRY_U16("mipi-sdca-control-dc-value", param->feid);
+ disco->props[2][0] = PROPERTY_ENTRY_U8("mipi-sdca-control-dc-value", param->fev);
+ ret = kunit_software_node_register_node_group(test,
+ cs35l56_test_dev_and_af01_node_group);
+ KUNIT_ASSERT_EQ(test, ret, 0);
+
+ disco->nodes[0] = SOFTWARE_NODE(control_names[0], disco->props[0],
+ &cs35l56_test_af01_sw_node);
+ KUNIT_ASSERT_NOT_ERR_OR_NULL(test,
+ kunit_software_node_register(test, &disco->nodes[0]));
+
+ if (!param->omit_feid) {
+ disco->nodes[1] = SOFTWARE_NODE(control_names[1], disco->props[1],
+ &cs35l56_test_af01_sw_node);
+ KUNIT_ASSERT_NOT_ERR_OR_NULL(test,
+ kunit_software_node_register(test, &disco->nodes[1]));
+ }
+
+ if (!param->omit_fev) {
+ disco->nodes[2] = SOFTWARE_NODE(control_names[2], disco->props[2],
+ &cs35l56_test_af01_sw_node);
+ KUNIT_ASSERT_NOT_ERR_OR_NULL(test,
+ kunit_software_node_register(test, &disco->nodes[2]));
+ }
+
+ KUNIT_ASSERT_EQ(test,
+ kunit_device_add_software_node(test, cs35l56->base.dev,
+ &cs35l56_test_dev_sw_node),
+ 0);
+
+ cs35l56->feid = 0;
+ cs35l56->fev = 0;
+
+ KUNIT_EXPECT_EQ(test, cs35l56_process_xu_properties(cs35l56), 0);
+
+ KUNIT_EXPECT_EQ(test, cs35l56->feid,
+ param->function_type == SDCA_FUNCTION_TYPE_SMART_AMP ? param->feid : 0);
+ KUNIT_EXPECT_EQ(test, cs35l56->fev,
+ param->function_type == SDCA_FUNCTION_TYPE_SMART_AMP ? param->fev : 0);
+}
+
static int cs35l56_test_dummy_read_onchip_spkid(struct cs35l56_base *cs35l56_base)
{
struct kunit *test = kunit_get_current_test();
@@ -559,6 +651,8 @@ static int cs35l56_test_case_init_common(struct kunit *test)
if (param) {
cs35l56->base.type = param->type;
cs35l56->base.rev = param->rev;
+ cs35l56->feid = param->feid;
+ cs35l56->fev = param->fev;
}
return 0;
@@ -587,6 +681,125 @@ static int cs35l56_test_case_init_soundwire(struct kunit *test)
return 0;
}
+static void cs35l56_test_system_name_param_desc(const struct cs35l56_test_param *param,
+ char *desc)
+{
+ snprintf(desc, KUNIT_PARAM_DESC_SIZE, "feid: %04x fev: %02x ssid: %d spkid: %d",
+ param->feid, param->fev, param->has_ssid, param->speaker_id);
+}
+
+static const struct cs35l56_test_param cs35l56_test_system_name_feid_fev_cases[] = {
+ /* FEID == 0 retains legacy naming and ignores FEV */
+ { .feid = 0, .fev = 0, .speaker_id = -1, },
+ { .feid = 0, .fev = 0, .speaker_id = 1, },
+ { .feid = 0, .fev = 0xff, .has_ssid = true, .speaker_id = -1,
+ .system_name = "12b4a7c8", },
+ { .feid = 0, .fev = 0xff, .has_ssid = true, .speaker_id = 1,
+ .system_name = "12b4a7c8-spkid1", },
+ { .feid = 0, .fev = 0xff, .speaker_id = -1, },
+ { .feid = 0, .fev = 0xff, .speaker_id = 1, },
+
+ /* Nonzero FEID < 0x8000 includes SSID and FEV */
+ { .feid = 1, .fev = 0, .has_ssid = true, .speaker_id = -1,
+ .system_name = "12b4a7c8-f1v0", },
+ { .feid = 1, .fev = 0, .has_ssid = true, .speaker_id = 1,
+ .system_name = "12b4a7c8-f1v0-spkid1", },
+ { .feid = 0x1234, .fev = 0xab, .has_ssid = true, .speaker_id = -1,
+ .system_name = "12b4a7c8-f1234vab", },
+ { .feid = 0x1234, .fev = 0xab, .has_ssid = true, .speaker_id = 1,
+ .system_name = "12b4a7c8-f1234vab-spkid1", },
+ { .feid = 0x7fff, .fev = 0xff, .has_ssid = true, .speaker_id = -1,
+ .system_name = "12b4a7c8-f7fffvff", },
+ { .feid = 0x7fff, .fev = 0xff, .has_ssid = true, .speaker_id = 1,
+ .system_name = "12b4a7c8-f7fffvff-spkid1", },
+
+ /* Nonzero FEID < 0x8000 missing SSID should not return error (fallback is allowed) */
+ { .feid = 1, .fev = 0, .speaker_id = -1, .ret = 0, },
+ { .feid = 1, .fev = 0, .speaker_id = 1, .ret = 0, },
+ { .feid = 0x1234, .fev = 0xab, .speaker_id = -1, .ret = 0, },
+ { .feid = 0x1234, .fev = 0xab, .speaker_id = 1, .ret = 0, },
+ { .feid = 0x7fff, .fev = 0xff, .speaker_id = -1, .ret = 0, },
+ { .feid = 0x7fff, .fev = 0xff, .speaker_id = 1, .ret = 0, },
+
+ /* FEID >= 0x8000 does not use an SSID */
+ { .feid = 0x8000, .fev = 0, .speaker_id = -1,
+ .system_name = "f8000v0", },
+ { .feid = 0x8000, .fev = 0, .speaker_id = 1,
+ .system_name = "f8000v0-spkid1", },
+ { .feid = 0x8000, .fev = 0, .has_ssid = true, .speaker_id = -1,
+ .system_name = "f8000v0", },
+ { .feid = 0x8000, .fev = 0, .has_ssid = true, .speaker_id = 1,
+ .system_name = "f8000v0-spkid1", },
+ { .feid = 0xabcd, .fev = 0xab, .speaker_id = -1,
+ .system_name = "fabcdvab", },
+ { .feid = 0xabcd, .fev = 0xab, .speaker_id = 1,
+ .system_name = "fabcdvab-spkid1", },
+ { .feid = 0xabcd, .fev = 0xab, .has_ssid = true, .speaker_id = -1,
+ .system_name = "fabcdvab", },
+ { .feid = 0xabcd, .fev = 0xab, .has_ssid = true, .speaker_id = 1,
+ .system_name = "fabcdvab-spkid1", },
+ { .feid = 0xffff, .fev = 0xff, .speaker_id = -1,
+ .system_name = "fffffvff", },
+ { .feid = 0xffff, .fev = 0xff, .speaker_id = 1,
+ .system_name = "fffffvff-spkid1", },
+ { .feid = 0xffff, .fev = 0xff, .has_ssid = true, .speaker_id = -1,
+ .system_name = "fffffvff", },
+ { .feid = 0xffff, .fev = 0xff, .has_ssid = true, .speaker_id = 1,
+ .system_name = "fffffvff-spkid1", },
+};
+KUNIT_ARRAY_PARAM(cs35l56_test_system_name_feid_fev,
+ cs35l56_test_system_name_feid_fev_cases,
+ cs35l56_test_system_name_param_desc);
+
+static void cs35l56_test_feid_fev_param_desc(const struct cs35l56_test_param *param,
+ char *desc)
+{
+ snprintf(desc, KUNIT_PARAM_DESC_SIZE, "feid: %04x fev: %02x",
+ param->feid, param->fev);
+}
+
+static const struct cs35l56_test_param cs35l56_test_property_feid_fev_cases[] = {
+ { .feid = 0, .fev = 0, },
+ { .feid = 0, .fev = 0xff, },
+ { .feid = 1, .fev = 0, },
+ { .feid = 0x7fff, .fev = 0xff, },
+ { .feid = 0x8000, .fev = 0, },
+ { .feid = 0xffff, .fev = 0xff, },
+};
+KUNIT_ARRAY_PARAM(cs35l56_test_property_feid_fev,
+ cs35l56_test_property_feid_fev_cases,
+ cs35l56_test_feid_fev_param_desc);
+
+static void cs35l56_test_disco_feid_fev_param_desc(const struct cs35l56_test_param *param,
+ char *desc)
+{
+ snprintf(desc, KUNIT_PARAM_DESC_SIZE, "function_type: %#x feid: %#x%s fev: %#x%s",
+ param->function_type, param->feid, param->omit_feid ? "(omitted)" : "",
+ param->fev, param->omit_fev ? "(omitted)" : "");
+}
+
+static const struct cs35l56_test_param cs35l56_test_disco_feid_fev_cases[] = {
+ { .function_type = SDCA_FUNCTION_TYPE_SMART_AMP, .feid = 0, .fev = 0, },
+ { .function_type = SDCA_FUNCTION_TYPE_SMART_AMP, .feid = 0, .fev = 0xff, },
+ { .function_type = SDCA_FUNCTION_TYPE_SMART_AMP, .feid = 1, .fev = 0, },
+ { .function_type = SDCA_FUNCTION_TYPE_SMART_AMP, .feid = 0x1234, .fev = 0xab, },
+ { .function_type = SDCA_FUNCTION_TYPE_SMART_AMP, .feid = 0x7fff, .fev = 0xff, },
+ { .function_type = SDCA_FUNCTION_TYPE_SMART_AMP, .feid = 0x8000, .fev = 0, },
+ { .function_type = SDCA_FUNCTION_TYPE_SMART_AMP, .feid = 0xffff, .fev = 0xff, },
+
+ /* Either or both can be absent*/
+ { .function_type = SDCA_FUNCTION_TYPE_SMART_AMP, .omit_feid = true, .fev = 0xab, },
+ { .function_type = SDCA_FUNCTION_TYPE_SMART_AMP, .feid = 0x1234, .omit_fev = true, },
+ { .function_type = SDCA_FUNCTION_TYPE_SMART_AMP, .omit_feid = true, .omit_fev = true, },
+
+ /* Other types of node are ignored */
+ { .function_type = SDCA_FUNCTION_TYPE_SMART_MIC, .feid = 0xffff, .fev = 0xff, },
+};
+
+KUNIT_ARRAY_PARAM(cs35l56_test_disco_feid_fev,
+ cs35l56_test_disco_feid_fev_cases,
+ cs35l56_test_disco_feid_fev_param_desc);
+
static void cs35l56_test_gpio_param_desc(const struct cs35l56_test_param *param, char *desc)
{
DECLARE_SEQ_BUF(gpios, 1 + (2 * ARRAY_SIZE(param->spkid_gpios)));
@@ -669,8 +882,12 @@ KUNIT_ARRAY_PARAM(cs35l56_test_type_rev_all, cs35l56_test_type_rev_all_param_cas
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_PARAM(cs35l56_test_system_name_with_feid_fev,
+ cs35l56_test_system_name_feid_fev_gen_params),
+ KUNIT_CASE_PARAM(cs35l56_test_system_name_from_property,
+ cs35l56_test_property_feid_fev_gen_params),
+ KUNIT_CASE_PARAM(cs35l56_test_system_name_from_property_and_spkid,
+ cs35l56_test_property_feid_fev_gen_params),
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,
@@ -679,6 +896,8 @@ static struct kunit_case cs35l56_test_cases_soundwire[] = {
KUNIT_CASE_PARAM(cs35l56_test_parse_xu_onchip_spkid,
cs35l56_test_onchip_spkid_gen_params),
+ KUNIT_CASE_PARAM(cs35l56_test_parse_disco_feid_fev,
+ cs35l56_test_disco_feid_fev_gen_params),
KUNIT_CASE(cs35l56_test_set_fw_name_reads_onchip_spkid),
KUNIT_CASE(cs35l56_test_set_fw_name_preserves_spkid_with_onchip_gpios),
@@ -690,8 +909,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_system_name_from_property,
+ cs35l56_test_property_feid_fev_gen_params),
+ KUNIT_CASE_PARAM(cs35l56_test_system_name_from_property_and_spkid,
+ cs35l56_test_property_feid_fev_gen_params),
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),
--
2.47.3
^ permalink raw reply [flat|nested] 3+ messages in thread