/* * V1 controls do not have names, the name field in the coefficient entry * should be ignored.
*/ staticvoid cs_dsp_ctl_parse_v1_name(struct kunit *test)
{ struct cs_dsp_test *priv = test->priv; struct cs_dsp_test_local *local = priv->local; struct cs_dsp_mock_coeff_def def = mock_coeff_template; struct cs_dsp_coeff_ctl *ctl; struct firmware *wmfw;
/* * V1 controls do not have names, the name field in the coefficient entry * should be ignored. Test with a zero-length name string.
*/ staticvoid cs_dsp_ctl_parse_empty_v1_name(struct kunit *test)
{ struct cs_dsp_test *priv = test->priv; struct cs_dsp_test_local *local = priv->local; struct cs_dsp_mock_coeff_def def = mock_coeff_template; struct cs_dsp_coeff_ctl *ctl; struct firmware *wmfw;
/* * V1 controls do not have names, the name field in the coefficient entry * should be ignored. Test with a maximum length name string.
*/ staticvoid cs_dsp_ctl_parse_max_v1_name(struct kunit *test)
{ struct cs_dsp_test *priv = test->priv; struct cs_dsp_test_local *local = priv->local; struct cs_dsp_mock_coeff_def def = mock_coeff_template; struct cs_dsp_coeff_ctl *ctl; struct firmware *wmfw;
/* Short name from coeff descriptor should be used as control name. */ staticvoid cs_dsp_ctl_parse_short_name(struct kunit *test)
{ struct cs_dsp_test *priv = test->priv; struct cs_dsp_test_local *local = priv->local; struct cs_dsp_mock_coeff_def def = mock_coeff_template; struct cs_dsp_coeff_ctl *ctl; struct firmware *wmfw;
/* * Short name from coeff descriptor should be used as control name. * Test with a short name that is a single character.
*/ staticvoid cs_dsp_ctl_parse_min_short_name(struct kunit *test)
{ struct cs_dsp_test *priv = test->priv; struct cs_dsp_test_local *local = priv->local; struct cs_dsp_mock_coeff_def def = mock_coeff_template; struct cs_dsp_coeff_ctl *ctl; struct firmware *wmfw;
/* * Short name from coeff descriptor should be used as control name. * Test with a maximum length name.
*/ staticvoid cs_dsp_ctl_parse_max_short_name(struct kunit *test)
{ struct cs_dsp_test *priv = test->priv; struct cs_dsp_test_local *local = priv->local; struct cs_dsp_mock_coeff_def def = mock_coeff_template; struct cs_dsp_coeff_ctl *ctl; struct firmware *wmfw;
/* * Full name from coeff descriptor should be ignored. It is a variable * length field so affects the position of subsequent fields. * Test with a 1-character full name.
*/ staticvoid cs_dsp_ctl_parse_with_min_fullname(struct kunit *test)
{ struct cs_dsp_test *priv = test->priv; struct cs_dsp_test_local *local = priv->local; struct cs_dsp_mock_coeff_def def = mock_coeff_template; struct cs_dsp_coeff_ctl *ctl; struct firmware *wmfw;
/* * Full name from coeff descriptor should be ignored. It is a variable * length field so affects the position of subsequent fields. * Test with a maximum length full name.
*/ staticvoid cs_dsp_ctl_parse_with_max_fullname(struct kunit *test)
{ struct cs_dsp_test *priv = test->priv; struct cs_dsp_test_local *local = priv->local; struct cs_dsp_mock_coeff_def def = mock_coeff_template; struct cs_dsp_coeff_ctl *ctl; struct firmware *wmfw;
/* * Description from coeff descriptor should be ignored. It is a variable * length field so affects the position of subsequent fields. * Test with a 1-character description
*/ staticvoid cs_dsp_ctl_parse_with_min_description(struct kunit *test)
{ struct cs_dsp_test *priv = test->priv; struct cs_dsp_test_local *local = priv->local; struct cs_dsp_mock_coeff_def def = mock_coeff_template; struct cs_dsp_coeff_ctl *ctl; struct firmware *wmfw;
/* * Description from coeff descriptor should be ignored. It is a variable * length field so affects the position of subsequent fields. * Test with a maximum length description
*/ staticvoid cs_dsp_ctl_parse_with_max_description(struct kunit *test)
{ struct cs_dsp_test *priv = test->priv; struct cs_dsp_test_local *local = priv->local; struct cs_dsp_mock_coeff_def def = mock_coeff_template; struct cs_dsp_coeff_ctl *ctl; struct firmware *wmfw;
/* * Full name and description from coeff descriptor are variable length * fields so affects the position of subsequent fields. * Test with a maximum length full name and description
*/ staticvoid cs_dsp_ctl_parse_with_max_fullname_and_description(struct kunit *test)
{ struct cs_dsp_test *priv = test->priv; struct cs_dsp_test_local *local = priv->local; struct cs_dsp_mock_coeff_def def = mock_coeff_template; struct cs_dsp_coeff_ctl *ctl; struct firmware *wmfw;
/* * Variable-length string fields are padded to a multiple of 4-bytes. * Test this with various lengths of short name.
*/ staticvoid cs_dsp_ctl_shortname_alignment(struct kunit *test)
{ struct cs_dsp_test *priv = test->priv; struct cs_dsp_test_local *local = priv->local; struct cs_dsp_mock_coeff_def def = mock_coeff_template; struct cs_dsp_coeff_ctl *ctl; struct firmware *wmfw; int i;
for (i = 0; i < ARRAY_SIZE(cs_dsp_ctl_alignment_test_names); i++) {
def.shortname = cs_dsp_ctl_alignment_test_names[i];
cs_dsp_mock_wmfw_add_coeff_desc(local->wmfw_builder, &def);
}
for (i = 0; i < ARRAY_SIZE(cs_dsp_ctl_alignment_test_names); i++) {
mutex_lock(&priv->dsp->pwr_lock);
ctl = cs_dsp_get_ctl(priv->dsp, cs_dsp_ctl_alignment_test_names[i],
def.mem_type, cs_dsp_ctl_parse_test_algs[0].id);
mutex_unlock(&priv->dsp->pwr_lock);
KUNIT_ASSERT_NOT_NULL(test, ctl);
KUNIT_EXPECT_EQ(test, ctl->subname_len, i + 1);
KUNIT_EXPECT_MEMEQ(test, ctl->subname, cs_dsp_ctl_alignment_test_names[i],
ctl->subname_len); /* Test fields that are parsed after the variable-length fields */
KUNIT_EXPECT_EQ(test, ctl->flags, def.flags);
KUNIT_EXPECT_EQ(test, ctl->type, def.type);
KUNIT_EXPECT_EQ(test, ctl->len, def.length_bytes);
}
}
/* * Variable-length string fields are padded to a multiple of 4-bytes. * Test this with various lengths of full name.
*/ staticvoid cs_dsp_ctl_fullname_alignment(struct kunit *test)
{ struct cs_dsp_test *priv = test->priv; struct cs_dsp_test_local *local = priv->local; struct cs_dsp_mock_coeff_def def = mock_coeff_template; struct cs_dsp_coeff_ctl *ctl; char ctl_name[4]; struct firmware *wmfw; int i;
for (i = 0; i < ARRAY_SIZE(cs_dsp_ctl_alignment_test_names); i++) { /* * Create a unique control name of 3 characters so that * the shortname field is exactly 4 bytes long including * the length byte.
*/
snprintf(ctl_name, sizeof(ctl_name), "%03d", i);
KUNIT_ASSERT_EQ(test, strlen(ctl_name), 3);
def.shortname = ctl_name;
for (i = 0; i < ARRAY_SIZE(cs_dsp_ctl_alignment_test_names); i++) { /* * Create a unique control name of 3 characters so that * the shortname field is exactly 4 bytes long including * the length byte.
*/
snprintf(ctl_name, sizeof(ctl_name), "%03d", i);
KUNIT_ASSERT_EQ(test, strlen(ctl_name), 3);
def.shortname = ctl_name;
/* * cs_dsp_get_ctl() searches for the control in the currently loaded * firmware, so create identical controls in multiple firmware and * test that the correct one is found.
*/ staticvoid cs_dsp_get_ctl_test_multiple_wmfw(struct kunit *test)
{ struct cs_dsp_test *priv = test->priv; struct cs_dsp_test_local *local = priv->local; struct cs_dsp_mock_coeff_def def = mock_coeff_template; struct cs_dsp_coeff_ctl *ctl; struct cs_dsp_mock_wmfw_builder *builder2; struct firmware *wmfw;
def.shortname = "_A_CONTROL";
/* Create a second mock wmfw builder */
builder2 = cs_dsp_mock_wmfw_init(priv,
cs_dsp_mock_wmfw_format_version(local->wmfw_builder));
KUNIT_ASSERT_NOT_ERR_OR_NULL(test, builder2);
cs_dsp_mock_wmfw_add_data_block(builder2,
WMFW_ADSP2_XM, 0,
local->xm_header->blob_data,
local->xm_header->blob_size_bytes);
/* Load a 'misc' firmware with a control */
def.offset_dsp_words = 1;
cs_dsp_mock_wmfw_start_alg_info_block(local->wmfw_builder,
cs_dsp_ctl_parse_test_algs[0].id, "dummyalg", NULL);
cs_dsp_mock_wmfw_add_coeff_desc(local->wmfw_builder, &def);
cs_dsp_mock_wmfw_end_alg_info_block(local->wmfw_builder);
wmfw = cs_dsp_mock_wmfw_get_firmware(priv->local->wmfw_builder);
KUNIT_ASSERT_EQ(test, cs_dsp_power_up(priv->dsp, wmfw, "mock_fw", NULL, NULL, "misc"), 0);
cs_dsp_power_down(priv->dsp);
/* Load a 'mbc/vss' firmware with a control of the same name */
def.offset_dsp_words = 2;
cs_dsp_mock_wmfw_start_alg_info_block(builder2,
cs_dsp_ctl_parse_test_algs[0].id, "dummyalg", NULL);
cs_dsp_mock_wmfw_add_coeff_desc(builder2, &def);
cs_dsp_mock_wmfw_end_alg_info_block(builder2);
wmfw = cs_dsp_mock_wmfw_get_firmware(builder2);
KUNIT_ASSERT_EQ(test,
cs_dsp_power_up(priv->dsp, wmfw, "mock_fw2", NULL, NULL, "mbc/vss"), 0);
/* A lookup should return the control for the current firmware */
mutex_lock(&priv->dsp->pwr_lock);
ctl = cs_dsp_get_ctl(priv->dsp, def.shortname,
def.mem_type, cs_dsp_ctl_parse_test_algs[0].id);
mutex_unlock(&priv->dsp->pwr_lock);
KUNIT_ASSERT_NOT_NULL(test, ctl);
KUNIT_EXPECT_EQ(test, ctl->offset, 2);
/* Re-load the 'misc' firmware and a lookup should return its control */
cs_dsp_power_down(priv->dsp);
wmfw = cs_dsp_mock_wmfw_get_firmware(priv->local->wmfw_builder);
KUNIT_ASSERT_EQ(test, cs_dsp_power_up(priv->dsp, wmfw, "mock_fw", NULL, NULL, "misc"), 0);
/* Test that the value of the memory type field is parsed correctly. */ staticvoid cs_dsp_ctl_parse_memory_type(struct kunit *test)
{ conststruct cs_dsp_ctl_parse_test_param *param = test->param_value; struct cs_dsp_test *priv = test->priv; struct cs_dsp_test_local *local = priv->local; struct cs_dsp_mock_coeff_def def = mock_coeff_template; struct cs_dsp_coeff_ctl *ctl; struct firmware *wmfw;
/* kunit_skip() marks the test skipped forever, so just return */ if ((param->mem_type == WMFW_ADSP2_ZM) && !cs_dsp_mock_has_zm(priv)) return;
/* * Test that the values of (alg id, memory type) tuple is parsed correctly. * The alg id is parsed from the alg-info block, but the memory type is * parsed from the coefficient info descriptor.
*/ staticvoid cs_dsp_ctl_parse_alg_mem(struct kunit *test)
{ conststruct cs_dsp_ctl_parse_test_param *param = test->param_value; struct cs_dsp_test *priv = test->priv; struct cs_dsp_test_local *local = priv->local; struct cs_dsp_mock_coeff_def def = mock_coeff_template; struct cs_dsp_coeff_ctl *ctl; struct firmware *wmfw;
/* kunit_skip() marks the test skipped forever, so just return */ if ((param->mem_type == WMFW_ADSP2_ZM) && !cs_dsp_mock_has_zm(priv)) return;
/* Test that the value of the control type field is parsed correctly. */ staticvoid cs_dsp_ctl_parse_ctl_type(struct kunit *test)
{ conststruct cs_dsp_ctl_parse_test_param *param = test->param_value; struct cs_dsp_test *priv = test->priv; struct cs_dsp_test_local *local = priv->local; struct cs_dsp_mock_coeff_def def = mock_coeff_template; struct cs_dsp_coeff_ctl *ctl; struct firmware *wmfw;
/* Test that the value of the flags field is parsed correctly. */ staticvoid cs_dsp_ctl_parse_flags(struct kunit *test)
{ conststruct cs_dsp_ctl_parse_test_param *param = test->param_value; struct cs_dsp_test *priv = test->priv; struct cs_dsp_test_local *local = priv->local; struct cs_dsp_mock_coeff_def def = mock_coeff_template; struct cs_dsp_coeff_ctl *ctl; struct firmware *wmfw;
u32 reg_val;
/* * Non volatile controls will be read to initialize the cache * so the regmap cache must contain something to read.
*/
reg_val = 0xf11100;
regmap_raw_write(priv->dsp->regmap,
cs_dsp_mock_base_addr_for_mem(priv, WMFW_ADSP2_YM),
®_val, sizeof(reg_val));
/* * Non volatile controls will be read to initialize the cache * so the regmap cache must contain something to read.
*/
reg_val = 0xf11100;
regmap_raw_write(priv->dsp->regmap,
cs_dsp_mock_base_addr_for_mem(priv, WMFW_ADSP2_YM),
®_val, sizeof(reg_val));
/* Controls are unique if the algorithm ID is different */ staticvoid cs_dsp_ctl_alg_id_uniqueness(struct kunit *test)
{ struct cs_dsp_test *priv = test->priv; struct cs_dsp_test_local *local = priv->local; struct cs_dsp_mock_coeff_def def = mock_coeff_template; struct cs_dsp_coeff_ctl *ctl1, *ctl2; struct firmware *wmfw;
/* Create an algorithm containing the control */
cs_dsp_mock_wmfw_start_alg_info_block(local->wmfw_builder,
cs_dsp_ctl_parse_test_algs[0].id, "dummyalg", NULL);
cs_dsp_mock_wmfw_add_coeff_desc(local->wmfw_builder, &def);
cs_dsp_mock_wmfw_end_alg_info_block(local->wmfw_builder);
/* Create a different algorithm containing an identical control */
cs_dsp_mock_wmfw_start_alg_info_block(local->wmfw_builder,
cs_dsp_ctl_parse_test_algs[1].id, "dummyalg", NULL);
cs_dsp_mock_wmfw_add_coeff_desc(local->wmfw_builder, &def);
cs_dsp_mock_wmfw_end_alg_info_block(local->wmfw_builder);
/* Both controls should be in the list */
KUNIT_EXPECT_EQ(test, list_count_nodes(&priv->dsp->ctl_list), 2);
ctl1 = list_first_entry_or_null(&priv->dsp->ctl_list, struct cs_dsp_coeff_ctl, list);
ctl2 = list_next_entry(ctl1, list);
KUNIT_EXPECT_NOT_NULL(test, ctl1);
KUNIT_EXPECT_NOT_NULL(test, ctl2);
KUNIT_EXPECT_EQ(test, ctl1->alg_region.alg, ctl2->alg_region.alg);
KUNIT_EXPECT_NE(test, ctl1->alg_region.type, ctl2->alg_region.type);
KUNIT_EXPECT_EQ(test, ctl1->offset, ctl2->offset);
KUNIT_EXPECT_EQ(test, ctl1->type, ctl2->type);
KUNIT_EXPECT_EQ(test, ctl1->flags, ctl2->flags);
KUNIT_EXPECT_EQ(test, ctl1->len, ctl2->len);
KUNIT_EXPECT_STREQ(test, ctl1->fw_name, ctl2->fw_name);
KUNIT_EXPECT_EQ(test, ctl1->subname_len, ctl2->subname_len); if (ctl1->subname_len)
KUNIT_EXPECT_MEMEQ(test, ctl1->subname, ctl2->subname, ctl1->subname_len);
}
/* Controls are unique if they are in different firmware */ staticvoid cs_dsp_ctl_fw_uniqueness(struct kunit *test)
{ struct cs_dsp_test *priv = test->priv; struct cs_dsp_test_local *local = priv->local; struct cs_dsp_mock_coeff_def def = mock_coeff_template; struct cs_dsp_coeff_ctl *ctl1, *ctl2; struct cs_dsp_mock_wmfw_builder *builder2; struct firmware *wmfw;
/* Create a second mock wmfw builder */
builder2 = cs_dsp_mock_wmfw_init(priv,
cs_dsp_mock_wmfw_format_version(local->wmfw_builder));
KUNIT_ASSERT_NOT_ERR_OR_NULL(test, builder2);
cs_dsp_mock_wmfw_add_data_block(builder2,
WMFW_ADSP2_XM, 0,
local->xm_header->blob_data,
local->xm_header->blob_size_bytes);
/* Load a 'misc' firmware with a control */
cs_dsp_mock_wmfw_start_alg_info_block(local->wmfw_builder,
cs_dsp_ctl_parse_test_algs[0].id, "dummyalg", NULL);
cs_dsp_mock_wmfw_add_coeff_desc(local->wmfw_builder, &def);
cs_dsp_mock_wmfw_end_alg_info_block(local->wmfw_builder);
wmfw = cs_dsp_mock_wmfw_get_firmware(priv->local->wmfw_builder);
KUNIT_ASSERT_EQ(test, cs_dsp_power_up(priv->dsp, wmfw, "mock_fw", NULL, NULL, "misc"), 0);
cs_dsp_power_down(priv->dsp);
/* Load a 'mbc/vss' firmware with the same control */
cs_dsp_mock_wmfw_start_alg_info_block(builder2,
cs_dsp_ctl_parse_test_algs[0].id, "dummyalg", NULL);
cs_dsp_mock_wmfw_add_coeff_desc(builder2, &def);
cs_dsp_mock_wmfw_end_alg_info_block(builder2);
wmfw = cs_dsp_mock_wmfw_get_firmware(builder2);
KUNIT_ASSERT_EQ(test, cs_dsp_power_up(priv->dsp, wmfw, "mock_fw2",
NULL, NULL, "mbc/vss"), 0);
cs_dsp_power_down(priv->dsp);
/* Both controls should be in the list */
KUNIT_EXPECT_EQ(test, list_count_nodes(&priv->dsp->ctl_list), 2);
ctl1 = list_first_entry_or_null(&priv->dsp->ctl_list, struct cs_dsp_coeff_ctl, list);
ctl2 = list_next_entry(ctl1, list);
KUNIT_EXPECT_NOT_NULL(test, ctl1);
KUNIT_EXPECT_NOT_NULL(test, ctl2);
KUNIT_EXPECT_EQ(test, ctl1->alg_region.alg, ctl2->alg_region.alg);
KUNIT_EXPECT_EQ(test, ctl1->alg_region.type, ctl2->alg_region.type);
KUNIT_EXPECT_EQ(test, ctl1->offset, ctl2->offset);
KUNIT_EXPECT_EQ(test, ctl1->type, ctl2->type);
KUNIT_EXPECT_EQ(test, ctl1->flags, ctl2->flags);
KUNIT_EXPECT_EQ(test, ctl1->len, ctl2->len);
KUNIT_EXPECT_STRNEQ(test, ctl1->fw_name, ctl2->fw_name);
KUNIT_EXPECT_EQ(test, ctl1->subname_len, ctl2->subname_len); if (ctl1->subname_len)
KUNIT_EXPECT_MEMEQ(test, ctl1->subname, ctl2->subname, ctl1->subname_len);
}
/* * Controls from a wmfw are only added to the list once. If the same * wmfw is reloaded the controls are not added again. * This creates multiple algorithms with one control each, which will * work on both V1 format and >=V2 format controls.
*/ staticvoid cs_dsp_ctl_squash_reloaded_controls(struct kunit *test)
{ struct cs_dsp_test *priv = test->priv; struct cs_dsp_test_local *local = priv->local; struct cs_dsp_mock_coeff_def def = mock_coeff_template; struct cs_dsp_coeff_ctl *ctls[ARRAY_SIZE(cs_dsp_ctl_parse_test_algs)]; struct cs_dsp_coeff_ctl *walkctl; struct firmware *wmfw; int i;
/* Create some algorithms with a control */ for (i = 0; i < ARRAY_SIZE(cs_dsp_ctl_parse_test_algs); i++) {
cs_dsp_mock_wmfw_start_alg_info_block(local->wmfw_builder,
cs_dsp_ctl_parse_test_algs[i].id, "dummyalg", NULL);
def.mem_type = WMFW_ADSP2_YM;
cs_dsp_mock_wmfw_add_coeff_desc(local->wmfw_builder, &def);
cs_dsp_mock_wmfw_end_alg_info_block(local->wmfw_builder);
}
/* All controls should be in the list */
KUNIT_EXPECT_EQ(test, list_count_nodes(&priv->dsp->ctl_list),
ARRAY_SIZE(cs_dsp_ctl_parse_test_algs));
/* Take a copy of the pointers to controls to compare against. */
i = 0;
list_for_each_entry(walkctl, &priv->dsp->ctl_list, list) {
KUNIT_ASSERT_LT(test, i, ARRAY_SIZE(ctls));
ctls[i++] = walkctl;
}
/* Load the wmfw again */
KUNIT_ASSERT_EQ(test, cs_dsp_power_up(priv->dsp, wmfw, "mock_fw", NULL, NULL, "misc"), 0);
cs_dsp_power_down(priv->dsp);
/* The number of controls should be the same */
KUNIT_EXPECT_EQ(test, list_count_nodes(&priv->dsp->ctl_list),
ARRAY_SIZE(cs_dsp_ctl_parse_test_algs));
/* And they should be the same objects */
i = 0;
list_for_each_entry(walkctl, &priv->dsp->ctl_list, list) {
KUNIT_ASSERT_LT(test, i, ARRAY_SIZE(ctls));
KUNIT_ASSERT_PTR_EQ(test, walkctl, ctls[i++]);
}
}
/* * Controls from a wmfw are only added to the list once. If the same * wmfw is reloaded the controls are not added again. * This tests >=V2 firmware that can have multiple named controls in * the same algorithm.
*/ staticvoid cs_dsp_ctl_v2_squash_reloaded_controls(struct kunit *test)
{ struct cs_dsp_test *priv = test->priv; struct cs_dsp_test_local *local = priv->local; struct cs_dsp_mock_coeff_def def = mock_coeff_template; struct cs_dsp_coeff_ctl *ctls[ARRAY_SIZE(cs_dsp_get_ctl_test_names)]; struct cs_dsp_coeff_ctl *walkctl; struct firmware *wmfw; int i;
/* All controls should be in the list */
KUNIT_EXPECT_EQ(test, list_count_nodes(&priv->dsp->ctl_list),
ARRAY_SIZE(cs_dsp_get_ctl_test_names));
/* Take a copy of the pointers to controls to compare against. */
i = 0;
list_for_each_entry(walkctl, &priv->dsp->ctl_list, list) {
KUNIT_ASSERT_LT(test, i, ARRAY_SIZE(ctls));
ctls[i++] = walkctl;
}
/* Load the wmfw again */
KUNIT_ASSERT_EQ(test, cs_dsp_power_up(priv->dsp, wmfw, "mock_fw", NULL, NULL, "misc"), 0);
cs_dsp_power_down(priv->dsp);
/* The number of controls should be the same */
KUNIT_EXPECT_EQ(test, list_count_nodes(&priv->dsp->ctl_list),
ARRAY_SIZE(cs_dsp_get_ctl_test_names));
/* And they should be the same objects */
i = 0;
list_for_each_entry(walkctl, &priv->dsp->ctl_list, list) {
KUNIT_ASSERT_LT(test, i, ARRAY_SIZE(ctls));
KUNIT_ASSERT_PTR_EQ(test, walkctl, ctls[i++]);
}
}
/* * When comparing shortnames the full length of both strings is * considered, not only the characters in of the shortest string. * So that "LEFT" is not the same as "LEFT2". * This is specifically to test for the bug that was fixed by commit: * 7ac1102b227b ("firmware: cs_dsp: Fix new control name check")
*/ staticvoid cs_dsp_ctl_v2_compare_len(struct kunit *test)
{ struct cs_dsp_test *priv = test->priv; struct cs_dsp_test_local *local = priv->local; struct cs_dsp_mock_coeff_def def = mock_coeff_template; struct cs_dsp_coeff_ctl *ctl; struct firmware *wmfw; int i;
for (i = 0; i < ARRAY_SIZE(cs_dsp_ctl_v2_compare_len_names); i++) {
def.shortname = cs_dsp_ctl_v2_compare_len_names[i];
cs_dsp_mock_wmfw_add_coeff_desc(local->wmfw_builder, &def);
}
dsp->dev = get_device(test_dev); if (!dsp->dev) return -ENODEV;
ret = kunit_add_action_or_reset(test, _put_device_wrapper, dsp->dev); if (ret) return ret;
dev_set_drvdata(dsp->dev, priv);
/* Allocate regmap */
ret = cs_dsp_mock_regmap_init(priv); if (ret) return ret;
/* * There must always be a XM header with at least 1 algorithm, so create * a dummy one that tests can use and extract it to a data blob.
*/
local->xm_header = cs_dsp_create_mock_xm_header(priv,
cs_dsp_ctl_parse_test_algs,
ARRAY_SIZE(cs_dsp_ctl_parse_test_algs));
KUNIT_ASSERT_NOT_ERR_OR_NULL(test, local->xm_header);
switch (dsp->type) { case WMFW_ADSP2:
ret = cs_dsp_adsp2_init(dsp); break; case WMFW_HALO:
ret = cs_dsp_halo_init(dsp); break; default:
KUNIT_FAIL(test, "Untested DSP type %d\n", dsp->type); return -EINVAL;
}
if (ret) return ret;
/* Automatically call cs_dsp_remove() when test case ends */ return kunit_add_action_or_reset(priv->test, _cs_dsp_remove_wrapper, dsp);
}
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.