1 // SPDX-License-Identifier: GPL-2.0-only
2 //
3 // Test cases for wm_adsp library.
4 //
5 // Copyright (C) 2025 Cirrus Logic, Inc. and
6 // Cirrus Logic International Semiconductor Ltd.
7
8 #include <kunit/device.h>
9 #include <kunit/static_stub.h>
10 #include <kunit/test.h>
11 #include <linux/slab.h>
12 #include "wm_adsp.h"
13
14 KUNIT_DEFINE_ACTION_WRAPPER(_put_device_wrapper, put_device, struct device *);
15
16 struct wm_adsp_fw_find_test {
17 struct wm_adsp dsp;
18
19 struct wm_adsp_fw_files found_fw;
20 char searched_fw_files[768];
21 };
22
23 struct wm_adsp_fw_find_test_params {
24 const char *part;
25 const char *dsp_name;
26 const char *fwf_name;
27 const char *system_name;
28 const char *alsa_name;
29 bool wmfw_optional;
30 bool bin_mandatory;
31
32 /* If non-NULL this file should be returned as "found" */
33 const char *expect_wmfw;
34
35 /* If non-NULL this file should be returned as "found" */
36 const char *expect_bin;
37
38 /* Space-separated list of filenames in expected order of searching */
39 const char *expected_searches;
40
41 /* NULL-terminated array of pointers to filenames to simulate directory content */
42 const char * const *dir_files;
43 };
44
45 /* Dummy struct firmware to return from wm_adsp_request_firmware_files */
46 static const struct firmware wm_adsp_find_test_dummy_firmware;
47
wm_adsp_fw_find_test_release_firmware_files_stub(struct wm_adsp_fw_files * fw)48 static void wm_adsp_fw_find_test_release_firmware_files_stub(struct wm_adsp_fw_files *fw)
49 {
50 /*
51 * fw->wmfw.firmware and fw->coeff.firmware allocated by this KUnit
52 * test are dummies not allocated by the real request_firmware() call
53 * so they must not be passed to release_firmware().
54 * This function replaces wm_adsp_release_firmware_files().
55 */
56
57 if (!fw)
58 return;
59
60 kfree(fw->wmfw.filename);
61 kfree(fw->coeff.filename);
62
63 fw->wmfw.firmware = NULL;
64 fw->coeff.firmware = NULL;
65 fw->wmfw.filename = NULL;
66 fw->coeff.filename = NULL;
67 }
68
wm_adsp_free_found_fw(struct kunit * test)69 static void wm_adsp_free_found_fw(struct kunit *test)
70 {
71 struct wm_adsp_fw_find_test *priv = test->priv;
72
73 wm_adsp_fw_find_test_release_firmware_files_stub(&priv->found_fw);
74 }
75
76 /* Simple lookup of a filename in a list of names */
wm_adsp_fw_find_test_firmware_request_simple_stub(const struct firmware ** firmware,const char * filename,struct device * dev)77 static int wm_adsp_fw_find_test_firmware_request_simple_stub(const struct firmware **firmware,
78 const char *filename,
79 struct device *dev)
80 {
81 struct kunit *test = kunit_get_current_test();
82 const struct wm_adsp_fw_find_test_params *params = test->param_value;
83 int i;
84
85 /* Non-parameterized test? */
86 if (!params)
87 return -ENOENT;
88
89 if (!params->dir_files)
90 return -ENOENT;
91
92 for (i = 0; params->dir_files[i]; i++) {
93 if (strcmp(params->dir_files[i], filename) == 0) {
94 *firmware = &wm_adsp_find_test_dummy_firmware;
95 return 0;
96 }
97 }
98
99 return -ENOENT;
100 }
101
wm_adsp_fw_find_test_pick_file(struct kunit * test)102 static void wm_adsp_fw_find_test_pick_file(struct kunit *test)
103 {
104 struct wm_adsp_fw_find_test *priv = test->priv;
105 const struct wm_adsp_fw_find_test_params *params = test->param_value;
106 struct wm_adsp *dsp = &priv->dsp;
107 int i, ret;
108
109 /* Concatenate string of dir content for error messages */
110 for (i = 0; params->dir_files[i]; i++) {
111 strlcat(priv->searched_fw_files, params->dir_files[i],
112 sizeof(priv->searched_fw_files));
113 strlcat(priv->searched_fw_files, ";",
114 sizeof(priv->searched_fw_files));
115 }
116
117 dsp->cs_dsp.name = params->dsp_name;
118 dsp->part = params->part;
119 dsp->fwf_name = params->fwf_name;
120 dsp->system_name = params->system_name;
121 dsp->component->name_prefix = params->alsa_name;
122 dsp->wmfw_optional = params->wmfw_optional;
123 dsp->bin_mandatory = params->bin_mandatory;
124
125 kunit_activate_static_stub(test,
126 wm_adsp_firmware_request,
127 wm_adsp_fw_find_test_firmware_request_simple_stub);
128 kunit_activate_static_stub(test,
129 wm_adsp_release_firmware_files,
130 wm_adsp_fw_find_test_release_firmware_files_stub);
131
132 ret = wm_adsp_request_firmware_files(dsp, &priv->found_fw);
133 kunit_deactivate_static_stub(test, wm_adsp_firmware_request);
134 kunit_deactivate_static_stub(test, wm_adsp_release_firmware_files);
135
136 KUNIT_EXPECT_EQ_MSG(test, ret,
137 (params->expect_wmfw || params->expect_bin) ? 0 : -ENOENT,
138 "%s\n", priv->searched_fw_files);
139
140 KUNIT_EXPECT_EQ_MSG(test, !!priv->found_fw.wmfw.filename, !!params->expect_wmfw,
141 "%s\n", priv->searched_fw_files);
142 KUNIT_EXPECT_EQ_MSG(test, !!priv->found_fw.coeff.filename, !!params->expect_bin,
143 "%s\n", priv->searched_fw_files);
144
145 if (params->expect_wmfw) {
146 KUNIT_EXPECT_STREQ_MSG(test, priv->found_fw.wmfw.filename, params->expect_wmfw,
147 "%s\n", priv->searched_fw_files);
148 }
149
150 if (params->expect_bin) {
151 KUNIT_EXPECT_STREQ_MSG(test, priv->found_fw.coeff.filename, params->expect_bin,
152 "%s\n", priv->searched_fw_files);
153 }
154 }
155
wm_adsp_fw_find_test_firmware_request_stub(const struct firmware ** firmware,const char * filename,struct device * dev)156 static int wm_adsp_fw_find_test_firmware_request_stub(const struct firmware **firmware,
157 const char *filename,
158 struct device *dev)
159 {
160 struct kunit *test = kunit_get_current_test();
161 const struct wm_adsp_fw_find_test_params *params = test->param_value;
162 struct wm_adsp_fw_find_test *priv = test->priv;
163
164 /*
165 * Searches are accumulated as a single string of space-separated names.
166 * The list of expected searches are stored the same way in
167 * struct wm_adsp_fw_find_test_params. This allows for comparision using
168 * a simple KUNIT_EXPECT_STREQ(), which avoids the risk of bugs in a
169 * more complex custom comparison.
170 */
171 if (priv->searched_fw_files[0] != '\0')
172 strlcat(priv->searched_fw_files, " ", sizeof(priv->searched_fw_files));
173
174 strlcat(priv->searched_fw_files, filename, sizeof(priv->searched_fw_files));
175
176 /* Non-parameterized test? */
177 if (!params)
178 return -ENOENT;
179
180 if (params->expect_wmfw && (strcmp(filename, params->expect_wmfw) == 0)) {
181 *firmware = &wm_adsp_find_test_dummy_firmware;
182 return 0;
183 }
184
185 if (params->expect_bin && (strcmp(filename, params->expect_bin) == 0)) {
186 *firmware = &wm_adsp_find_test_dummy_firmware;
187 return 0;
188 }
189
190 return -ENOENT;
191 }
192
wm_adsp_fw_find_test_search_order(struct kunit * test)193 static void wm_adsp_fw_find_test_search_order(struct kunit *test)
194 {
195 struct wm_adsp_fw_find_test *priv = test->priv;
196 const struct wm_adsp_fw_find_test_params *params = test->param_value;
197 struct wm_adsp *dsp = &priv->dsp;
198
199 dsp->cs_dsp.name = params->dsp_name;
200 dsp->part = params->part;
201 dsp->fwf_name = params->fwf_name;
202 dsp->system_name = params->system_name;
203 dsp->component->name_prefix = params->alsa_name;
204 dsp->wmfw_optional = params->wmfw_optional;
205
206 kunit_activate_static_stub(test,
207 wm_adsp_firmware_request,
208 wm_adsp_fw_find_test_firmware_request_stub);
209 kunit_activate_static_stub(test,
210 wm_adsp_release_firmware_files,
211 wm_adsp_fw_find_test_release_firmware_files_stub);
212
213 wm_adsp_request_firmware_files(dsp, &priv->found_fw);
214 kunit_deactivate_static_stub(test, wm_adsp_firmware_request);
215 kunit_deactivate_static_stub(test, wm_adsp_release_firmware_files);
216
217 KUNIT_EXPECT_STREQ(test, priv->searched_fw_files, params->expected_searches);
218
219 KUNIT_EXPECT_EQ(test, !!priv->found_fw.wmfw.filename, !!params->expect_wmfw);
220 if (params->expect_wmfw)
221 KUNIT_EXPECT_STREQ(test, priv->found_fw.wmfw.filename, params->expect_wmfw);
222
223 KUNIT_EXPECT_EQ(test, !!priv->found_fw.coeff.filename, !!params->expect_bin);
224 if (params->expect_bin)
225 KUNIT_EXPECT_STREQ(test, priv->found_fw.coeff.filename, params->expect_bin);
226
227 /* Either we get a filename and firmware, or neither */
228 KUNIT_EXPECT_EQ(test, !!priv->found_fw.wmfw.filename, !!priv->found_fw.wmfw.firmware);
229 KUNIT_EXPECT_EQ(test, !!priv->found_fw.coeff.filename, !!priv->found_fw.coeff.firmware);
230 }
231
wm_adsp_fw_find_test_find_firmware_byindex(struct kunit * test)232 static void wm_adsp_fw_find_test_find_firmware_byindex(struct kunit *test)
233 {
234 struct wm_adsp_fw_find_test *priv = test->priv;
235 struct wm_adsp *dsp = &priv->dsp;
236 const char *fw_name;
237
238 dsp->cs_dsp.name = "cs1234";
239 dsp->part = "dsp1";
240
241 for (dsp->fw = 0;; dsp->fw++) {
242 fw_name = wm_adsp_get_fwf_name_by_index(dsp->fw);
243 if (!fw_name)
244 break;
245
246 kunit_activate_static_stub(test,
247 wm_adsp_firmware_request,
248 wm_adsp_fw_find_test_firmware_request_stub);
249 kunit_activate_static_stub(test,
250 wm_adsp_release_firmware_files,
251 wm_adsp_fw_find_test_release_firmware_files_stub);
252
253 wm_adsp_request_firmware_files(dsp, &priv->found_fw);
254
255 kunit_deactivate_static_stub(test, wm_adsp_firmware_request);
256 kunit_deactivate_static_stub(test, wm_adsp_release_firmware_files);
257
258 KUNIT_EXPECT_NOT_NULL_MSG(test,
259 strstr(priv->searched_fw_files, fw_name),
260 "fw#%d Did not find '%s' in '%s'\n",
261 dsp->fw, fw_name, priv->searched_fw_files);
262
263 wm_adsp_free_found_fw(test);
264 memset(priv->searched_fw_files, 0, sizeof(priv->searched_fw_files));
265 }
266 }
267
wm_adsp_fw_find_test_case_init(struct kunit * test)268 static int wm_adsp_fw_find_test_case_init(struct kunit *test)
269 {
270 struct wm_adsp_fw_find_test *priv;
271 struct device *test_dev;
272 int ret;
273
274 priv = kunit_kzalloc(test, sizeof(*priv), GFP_KERNEL);
275 if (!priv)
276 return -ENOMEM;
277
278 /* Require dummy struct snd_soc_component for the alsa name prefix string */
279 priv->dsp.component = kunit_kzalloc(test, sizeof(*priv->dsp.component), GFP_KERNEL);
280 if (!priv->dsp.component)
281 return -ENOMEM;
282
283 test->priv = priv;
284
285 /* Create dummy amp device */
286 test_dev = kunit_device_register(test, "wm_adsp_test_drv");
287 if (IS_ERR(test_dev))
288 return PTR_ERR(test_dev);
289
290 priv->dsp.cs_dsp.dev = get_device(test_dev);
291 if (!priv->dsp.cs_dsp.dev)
292 return -ENODEV;
293
294 ret = kunit_add_action_or_reset(test, _put_device_wrapper, priv->dsp.cs_dsp.dev);
295 if (ret)
296 return ret;
297
298 return 0;
299 }
300
wm_adsp_fw_find_test_case_exit(struct kunit * test)301 static void wm_adsp_fw_find_test_case_exit(struct kunit *test)
302 {
303 wm_adsp_free_found_fw(test);
304 }
305
wm_adsp_fw_find_test_param_desc(const struct wm_adsp_fw_find_test_params * param,char * desc)306 static void wm_adsp_fw_find_test_param_desc(const struct wm_adsp_fw_find_test_params *param,
307 char *desc)
308 {
309 snprintf(desc, KUNIT_PARAM_DESC_SIZE,
310 "%s %s fwf_name:%s system:%s alsa_name:%s %s expects:(%s %s)",
311 param->part, param->dsp_name,
312 param->fwf_name ? param->fwf_name : "",
313 param->system_name ? param->system_name : "",
314 param->alsa_name ? param->alsa_name : "",
315 param->wmfw_optional ? "wmfw_optional" : "",
316 param->expect_wmfw ? param->expect_wmfw : "",
317 param->expect_bin ? param->expect_bin : "");
318 }
319
320 /* Cases where firmware file not found. Tests full search sequence. */
321 static const struct wm_adsp_fw_find_test_params wm_adsp_fw_find_full_search_cases[] = {
322 { /* system name and alsa prefix, wmfw mandatory. */
323 .part = "cs1234", .dsp_name = "dsp1", .system_name = "ABC123",
324 .alsa_name = "amp1",
325 .expected_searches =
326 "cirrus/cs1234-dsp1-mbc-vss-abc123-amp1.wmfw "
327 "cirrus/cs1234-dsp1-mbc-vss-abc123.wmfw "
328 "cs1234-dsp1-mbc-vss.wmfw "
329 "cirrus/cs1234-dsp1-mbc-vss.wmfw",
330 },
331 { /* system name and alsa prefix, wmfw optional. */
332 .part = "cs1234", .dsp_name = "dsp1", .system_name = "ABC123",
333 .alsa_name = "amp1", .wmfw_optional = true,
334 .expected_searches =
335 "cirrus/cs1234-dsp1-mbc-vss-abc123-amp1.wmfw "
336 "cirrus/cs1234-dsp1-mbc-vss-abc123.wmfw "
337 "cirrus/cs1234-dsp1-mbc-vss-abc123-amp1.bin "
338 "cirrus/cs1234-dsp1-mbc-vss-abc123.bin "
339 "cs1234-dsp1-mbc-vss.wmfw "
340 "cirrus/cs1234-dsp1-mbc-vss.wmfw "
341 "cirrus/cs1234-dsp1-mbc-vss.bin",
342 },
343 { /* system name only, wmfw mandatory. */
344 .part = "cs1234", .dsp_name = "dsp1", .system_name = "ABC123",
345 .expected_searches =
346 "cirrus/cs1234-dsp1-mbc-vss-abc123.wmfw "
347 "cs1234-dsp1-mbc-vss.wmfw "
348 "cirrus/cs1234-dsp1-mbc-vss.wmfw",
349 },
350 { /* system name only, wmfw optional. */
351 .part = "cs1234", .dsp_name = "dsp1", .system_name = "ABC123",
352 .wmfw_optional = true,
353 .expected_searches =
354 "cirrus/cs1234-dsp1-mbc-vss-abc123.wmfw "
355 "cirrus/cs1234-dsp1-mbc-vss-abc123.bin "
356 "cs1234-dsp1-mbc-vss.wmfw "
357 "cirrus/cs1234-dsp1-mbc-vss.wmfw "
358 "cirrus/cs1234-dsp1-mbc-vss.bin",
359 },
360
361 /*
362 * TODO: Is this a bug? Device-specific bin is only allowed when there
363 * is a system_name. But if there isn't any meaningful system name on
364 * a product, why can't it load firmware files qualified by alsa prefix?
365 */
366
367 { /* Alsa prefix, wmfw mandatory. No system name so generic files only. */
368 .part = "cs1234", .dsp_name = "dsp1", .alsa_name = "amp1",
369 .expected_searches =
370 "cs1234-dsp1-mbc-vss.wmfw "
371 "cirrus/cs1234-dsp1-mbc-vss.wmfw",
372 },
373 { /* Alsa prefix, wmfw optional. No system name so generic files only. */
374 .part = "cs1234", .dsp_name = "dsp1", .alsa_name = "amp1",
375 .wmfw_optional = true,
376 .expected_searches =
377 "cs1234-dsp1-mbc-vss.wmfw "
378 "cirrus/cs1234-dsp1-mbc-vss.wmfw "
379 "cirrus/cs1234-dsp1-mbc-vss.bin",
380 },
381
382 { /* fwf_name, system name and alsa prefix, wmfw mandatory. */
383 .part = "cs1234", .dsp_name = "dsp1", .system_name = "ABC123",
384 .alsa_name = "amp1", .fwf_name = "ao",
385 .expected_searches =
386 "cirrus/cs1234-ao-mbc-vss-abc123-amp1.wmfw "
387 "cirrus/cs1234-ao-mbc-vss-abc123.wmfw "
388 "cs1234-ao-mbc-vss.wmfw "
389 "cirrus/cs1234-ao-mbc-vss.wmfw",
390 },
391 { /* fwf_name, system name and alsa prefix, wmfw optional. */
392 .part = "cs1234", .dsp_name = "dsp1", .system_name = "ABC123",
393 .alsa_name = "amp1", .fwf_name = "ao",
394 .wmfw_optional = true,
395 .expected_searches =
396 "cirrus/cs1234-ao-mbc-vss-abc123-amp1.wmfw "
397 "cirrus/cs1234-ao-mbc-vss-abc123.wmfw "
398 "cirrus/cs1234-ao-mbc-vss-abc123-amp1.bin "
399 "cirrus/cs1234-ao-mbc-vss-abc123.bin "
400 "cs1234-ao-mbc-vss.wmfw "
401 "cirrus/cs1234-ao-mbc-vss.wmfw "
402 "cirrus/cs1234-ao-mbc-vss.bin",
403 },
404 };
405 KUNIT_ARRAY_PARAM(wm_adsp_fw_find_full_search,
406 wm_adsp_fw_find_full_search_cases,
407 wm_adsp_fw_find_test_param_desc);
408
409 /* Cases with system name and alsa prefix both given. */
410 static const struct wm_adsp_fw_find_test_params wm_adsp_fw_find_system_alsaname_cases[] = {
411 { /* Fully-qualified wmfw exists. No bin */
412 .part = "cs1234", .dsp_name = "dsp1", .system_name = "ABC123",
413 .alsa_name = "amp1",
414 .expect_wmfw = "cirrus/cs1234-dsp1-mbc-vss-abc123-amp1.wmfw",
415 .expected_searches =
416 "cirrus/cs1234-dsp1-mbc-vss-abc123-amp1.wmfw "
417 "cirrus/cs1234-dsp1-mbc-vss-abc123-amp1.bin",
418 },
419 { /* Optional fully-qualified wmfw exists. No bin */
420 .part = "cs1234", .dsp_name = "dsp1", .system_name = "ABC123",
421 .alsa_name = "amp1", .wmfw_optional = true,
422 .expect_wmfw = "cirrus/cs1234-dsp1-mbc-vss-abc123-amp1.wmfw",
423 .expected_searches =
424 "cirrus/cs1234-dsp1-mbc-vss-abc123-amp1.wmfw "
425 "cirrus/cs1234-dsp1-mbc-vss-abc123-amp1.bin",
426 },
427 { /* Fully-qualified wmfw and bin exist. */
428 .part = "cs1234", .dsp_name = "dsp1", .system_name = "ABC123",
429 .alsa_name = "amp1",
430 .expect_wmfw = "cirrus/cs1234-dsp1-mbc-vss-abc123-amp1.wmfw",
431 .expect_bin = "cirrus/cs1234-dsp1-mbc-vss-abc123-amp1.bin",
432 .expected_searches =
433 "cirrus/cs1234-dsp1-mbc-vss-abc123-amp1.wmfw "
434 "cirrus/cs1234-dsp1-mbc-vss-abc123-amp1.bin",
435 },
436 { /* Optional fully-qualified wmfw and fully-qualified bin exist. */
437 .part = "cs1234", .dsp_name = "dsp1", .system_name = "ABC123",
438 .alsa_name = "amp1", .wmfw_optional = true,
439 .expect_wmfw = "cirrus/cs1234-dsp1-mbc-vss-abc123-amp1.wmfw",
440 .expect_bin = "cirrus/cs1234-dsp1-mbc-vss-abc123-amp1.bin",
441 .expected_searches =
442 "cirrus/cs1234-dsp1-mbc-vss-abc123-amp1.wmfw "
443 "cirrus/cs1234-dsp1-mbc-vss-abc123-amp1.bin",
444 },
445 { /* wmfw matches system name only. No bin */
446 .part = "cs1234", .dsp_name = "dsp1", .system_name = "ABC123",
447 .alsa_name = "amp1",
448 .expect_wmfw = "cirrus/cs1234-dsp1-mbc-vss-abc123.wmfw",
449 .expected_searches =
450 "cirrus/cs1234-dsp1-mbc-vss-abc123-amp1.wmfw "
451 "cirrus/cs1234-dsp1-mbc-vss-abc123.wmfw "
452 "cirrus/cs1234-dsp1-mbc-vss-abc123-amp1.bin "
453 "cirrus/cs1234-dsp1-mbc-vss-abc123.bin",
454 },
455 { /* Optional wmfw matches system name only. No bin */
456 .part = "cs1234", .dsp_name = "dsp1", .system_name = "ABC123",
457 .alsa_name = "amp1", .wmfw_optional = true,
458 .expect_wmfw = "cirrus/cs1234-dsp1-mbc-vss-abc123.wmfw",
459 .expected_searches =
460 "cirrus/cs1234-dsp1-mbc-vss-abc123-amp1.wmfw "
461 "cirrus/cs1234-dsp1-mbc-vss-abc123.wmfw "
462 "cirrus/cs1234-dsp1-mbc-vss-abc123-amp1.bin "
463 "cirrus/cs1234-dsp1-mbc-vss-abc123.bin",
464 },
465 { /* wmfw matches system name only. Fully-qualified bin. */
466 .part = "cs1234", .dsp_name = "dsp1", .system_name = "ABC123",
467 .alsa_name = "amp1",
468 .expect_wmfw = "cirrus/cs1234-dsp1-mbc-vss-abc123.wmfw",
469 .expect_bin = "cirrus/cs1234-dsp1-mbc-vss-abc123-amp1.bin",
470 .expected_searches =
471 "cirrus/cs1234-dsp1-mbc-vss-abc123-amp1.wmfw "
472 "cirrus/cs1234-dsp1-mbc-vss-abc123.wmfw "
473 "cirrus/cs1234-dsp1-mbc-vss-abc123-amp1.bin",
474 },
475 { /* Optional wmfw matches system name only. Fully-qualified bin. */
476 .part = "cs1234", .dsp_name = "dsp1", .system_name = "ABC123",
477 .alsa_name = "amp1", .wmfw_optional = true,
478 .expect_wmfw = "cirrus/cs1234-dsp1-mbc-vss-abc123.wmfw",
479 .expect_bin = "cirrus/cs1234-dsp1-mbc-vss-abc123-amp1.bin",
480 .expected_searches =
481 "cirrus/cs1234-dsp1-mbc-vss-abc123-amp1.wmfw "
482 "cirrus/cs1234-dsp1-mbc-vss-abc123.wmfw "
483 "cirrus/cs1234-dsp1-mbc-vss-abc123-amp1.bin",
484 },
485 { /* wmfw and bin match system name only. */
486 .part = "cs1234", .dsp_name = "dsp1", .system_name = "ABC123",
487 .alsa_name = "amp1",
488 .expect_wmfw = "cirrus/cs1234-dsp1-mbc-vss-abc123.wmfw",
489 .expect_bin = "cirrus/cs1234-dsp1-mbc-vss-abc123.bin",
490 .expected_searches =
491 "cirrus/cs1234-dsp1-mbc-vss-abc123-amp1.wmfw "
492 "cirrus/cs1234-dsp1-mbc-vss-abc123.wmfw "
493 "cirrus/cs1234-dsp1-mbc-vss-abc123-amp1.bin "
494 "cirrus/cs1234-dsp1-mbc-vss-abc123.bin",
495 },
496 { /* Optional wmfw and bin match system name only. */
497 .part = "cs1234", .dsp_name = "dsp1", .system_name = "ABC123",
498 .alsa_name = "amp1", .wmfw_optional = true,
499 .expect_wmfw = "cirrus/cs1234-dsp1-mbc-vss-abc123.wmfw",
500 .expect_bin = "cirrus/cs1234-dsp1-mbc-vss-abc123.bin",
501 .expected_searches =
502 "cirrus/cs1234-dsp1-mbc-vss-abc123-amp1.wmfw "
503 "cirrus/cs1234-dsp1-mbc-vss-abc123.wmfw "
504 "cirrus/cs1234-dsp1-mbc-vss-abc123-amp1.bin "
505 "cirrus/cs1234-dsp1-mbc-vss-abc123.bin",
506 },
507 { /* Optional wmfw not found. bin matches fully-qualified name. */
508 .part = "cs1234", .dsp_name = "dsp1", .system_name = "ABC123",
509 .alsa_name = "amp1", .wmfw_optional = true,
510 .expect_bin = "cirrus/cs1234-dsp1-mbc-vss-abc123-amp1.bin",
511 .expected_searches =
512 "cirrus/cs1234-dsp1-mbc-vss-abc123-amp1.wmfw "
513 "cirrus/cs1234-dsp1-mbc-vss-abc123.wmfw "
514 "cirrus/cs1234-dsp1-mbc-vss-abc123-amp1.bin",
515 },
516 { /* Optional wmfw not found. bin matches system name only. */
517 .part = "cs1234", .dsp_name = "dsp1", .system_name = "ABC123",
518 .alsa_name = "amp1", .wmfw_optional = true,
519 .expect_bin = "cirrus/cs1234-dsp1-mbc-vss-abc123.bin",
520 .expected_searches =
521 "cirrus/cs1234-dsp1-mbc-vss-abc123-amp1.wmfw "
522 "cirrus/cs1234-dsp1-mbc-vss-abc123.wmfw "
523 "cirrus/cs1234-dsp1-mbc-vss-abc123-amp1.bin "
524 "cirrus/cs1234-dsp1-mbc-vss-abc123.bin",
525 },
526 { /* No qualified wmfw. Legacy generic wmfw found. No bin. */
527 .part = "cs1234", .dsp_name = "dsp1", .system_name = "ABC123",
528 .alsa_name = "amp1",
529 .expect_wmfw = "cs1234-dsp1-mbc-vss.wmfw",
530 .expected_searches =
531 "cirrus/cs1234-dsp1-mbc-vss-abc123-amp1.wmfw "
532 "cirrus/cs1234-dsp1-mbc-vss-abc123.wmfw "
533 "cs1234-dsp1-mbc-vss.wmfw "
534 "cs1234-dsp1-mbc-vss.bin",
535 },
536 { /* No qualified optional wmfw. Legacy generic wmfw found. No bin. */
537 .part = "cs1234", .dsp_name = "dsp1", .system_name = "ABC123",
538 .alsa_name = "amp1", .wmfw_optional = true,
539 .expect_wmfw = "cs1234-dsp1-mbc-vss.wmfw",
540 .expected_searches =
541 "cirrus/cs1234-dsp1-mbc-vss-abc123-amp1.wmfw "
542 "cirrus/cs1234-dsp1-mbc-vss-abc123.wmfw "
543 "cirrus/cs1234-dsp1-mbc-vss-abc123-amp1.bin "
544 "cirrus/cs1234-dsp1-mbc-vss-abc123.bin "
545 "cs1234-dsp1-mbc-vss.wmfw "
546 "cs1234-dsp1-mbc-vss.bin",
547 },
548 { /* No qualified wmfw. Legacy generic wmfw and bin found. */
549 .part = "cs1234", .dsp_name = "dsp1", .system_name = "ABC123",
550 .alsa_name = "amp1",
551 .expect_wmfw = "cs1234-dsp1-mbc-vss.wmfw",
552 .expect_bin = "cs1234-dsp1-mbc-vss.bin",
553 .expected_searches =
554 "cirrus/cs1234-dsp1-mbc-vss-abc123-amp1.wmfw "
555 "cirrus/cs1234-dsp1-mbc-vss-abc123.wmfw "
556 "cs1234-dsp1-mbc-vss.wmfw "
557 "cs1234-dsp1-mbc-vss.bin",
558 },
559 { /* No qualified optional wmfw. Legacy generic wmfw and bin found. */
560 .part = "cs1234", .dsp_name = "dsp1", .system_name = "ABC123",
561 .alsa_name = "amp1", .wmfw_optional = true,
562 .expect_wmfw = "cs1234-dsp1-mbc-vss.wmfw",
563 .expect_bin = "cs1234-dsp1-mbc-vss.bin",
564 .expected_searches =
565 "cirrus/cs1234-dsp1-mbc-vss-abc123-amp1.wmfw "
566 "cirrus/cs1234-dsp1-mbc-vss-abc123.wmfw "
567 "cirrus/cs1234-dsp1-mbc-vss-abc123-amp1.bin "
568 "cirrus/cs1234-dsp1-mbc-vss-abc123.bin "
569 "cs1234-dsp1-mbc-vss.wmfw "
570 "cs1234-dsp1-mbc-vss.bin",
571 },
572 { /* No qualified or legacy wmfw. Generic wmfw found. No bin. */
573 .part = "cs1234", .dsp_name = "dsp1", .system_name = "ABC123",
574 .alsa_name = "amp1",
575 .expect_wmfw = "cirrus/cs1234-dsp1-mbc-vss.wmfw",
576 .expected_searches =
577 "cirrus/cs1234-dsp1-mbc-vss-abc123-amp1.wmfw "
578 "cirrus/cs1234-dsp1-mbc-vss-abc123.wmfw "
579 "cs1234-dsp1-mbc-vss.wmfw "
580 "cirrus/cs1234-dsp1-mbc-vss.wmfw "
581 "cirrus/cs1234-dsp1-mbc-vss.bin",
582 },
583 { /* No optional qualified or legacy wmfw. Generic wmfw found. No bin. */
584 .part = "cs1234", .dsp_name = "dsp1", .system_name = "ABC123",
585 .alsa_name = "amp1", .wmfw_optional = true,
586 .expect_wmfw = "cirrus/cs1234-dsp1-mbc-vss.wmfw",
587 .expected_searches =
588 "cirrus/cs1234-dsp1-mbc-vss-abc123-amp1.wmfw "
589 "cirrus/cs1234-dsp1-mbc-vss-abc123.wmfw "
590 "cirrus/cs1234-dsp1-mbc-vss-abc123-amp1.bin "
591 "cirrus/cs1234-dsp1-mbc-vss-abc123.bin "
592 "cs1234-dsp1-mbc-vss.wmfw "
593 "cirrus/cs1234-dsp1-mbc-vss.wmfw "
594 "cirrus/cs1234-dsp1-mbc-vss.bin",
595 },
596 { /* No qualified or legacy wmfw. Generic wmfw and bin found. */
597 .part = "cs1234", .dsp_name = "dsp1", .system_name = "ABC123",
598 .alsa_name = "amp1",
599 .expect_wmfw = "cirrus/cs1234-dsp1-mbc-vss.wmfw",
600 .expect_bin = "cirrus/cs1234-dsp1-mbc-vss.bin",
601 .expected_searches =
602 "cirrus/cs1234-dsp1-mbc-vss-abc123-amp1.wmfw "
603 "cirrus/cs1234-dsp1-mbc-vss-abc123.wmfw "
604 "cs1234-dsp1-mbc-vss.wmfw "
605 "cirrus/cs1234-dsp1-mbc-vss.wmfw "
606 "cirrus/cs1234-dsp1-mbc-vss.bin",
607 },
608 { /* No optional qualified or legacy wmfw. Generic wmfw and bin found. */
609 .part = "cs1234", .dsp_name = "dsp1", .system_name = "ABC123",
610 .alsa_name = "amp1", .wmfw_optional = true,
611 .expect_wmfw = "cirrus/cs1234-dsp1-mbc-vss.wmfw",
612 .expect_bin = "cirrus/cs1234-dsp1-mbc-vss.bin",
613 .expected_searches =
614 "cirrus/cs1234-dsp1-mbc-vss-abc123-amp1.wmfw "
615 "cirrus/cs1234-dsp1-mbc-vss-abc123.wmfw "
616 "cirrus/cs1234-dsp1-mbc-vss-abc123-amp1.bin "
617 "cirrus/cs1234-dsp1-mbc-vss-abc123.bin "
618 "cs1234-dsp1-mbc-vss.wmfw "
619 "cirrus/cs1234-dsp1-mbc-vss.wmfw "
620 "cirrus/cs1234-dsp1-mbc-vss.bin",
621 },
622 { /* No optional qualified or generic wmfw. Generic bin found. */
623 .part = "cs1234", .dsp_name = "dsp1", .system_name = "ABC123",
624 .alsa_name = "amp1", .wmfw_optional = true,
625 .expect_bin = "cirrus/cs1234-dsp1-mbc-vss.bin",
626 .expected_searches =
627 "cirrus/cs1234-dsp1-mbc-vss-abc123-amp1.wmfw "
628 "cirrus/cs1234-dsp1-mbc-vss-abc123.wmfw "
629 "cirrus/cs1234-dsp1-mbc-vss-abc123-amp1.bin "
630 "cirrus/cs1234-dsp1-mbc-vss-abc123.bin "
631 "cs1234-dsp1-mbc-vss.wmfw "
632 "cirrus/cs1234-dsp1-mbc-vss.wmfw "
633 "cirrus/cs1234-dsp1-mbc-vss.bin",
634 },
635 };
636 KUNIT_ARRAY_PARAM(wm_adsp_fw_find_system_alsaname,
637 wm_adsp_fw_find_system_alsaname_cases,
638 wm_adsp_fw_find_test_param_desc);
639
640 /* Cases with system name but without alsa name prefix. */
641 static const struct wm_adsp_fw_find_test_params wm_adsp_fw_find_system_cases[] = {
642 { /* Qualified wmfw found. No bin */
643 .part = "cs1234", .dsp_name = "dsp1", .system_name = "ABC123",
644 .expect_wmfw = "cirrus/cs1234-dsp1-mbc-vss-abc123.wmfw",
645 .expected_searches =
646 "cirrus/cs1234-dsp1-mbc-vss-abc123.wmfw "
647 "cirrus/cs1234-dsp1-mbc-vss-abc123.bin",
648 },
649 { /* Optional qualified wmfw found. No bin */
650 .part = "cs1234", .dsp_name = "dsp1", .system_name = "ABC123",
651 .wmfw_optional = true,
652 .expect_wmfw = "cirrus/cs1234-dsp1-mbc-vss-abc123.wmfw",
653 .expected_searches =
654 "cirrus/cs1234-dsp1-mbc-vss-abc123.wmfw "
655 "cirrus/cs1234-dsp1-mbc-vss-abc123.bin",
656 },
657 { /* Qualified wmfw found. Qualified bin found. */
658 .part = "cs1234", .dsp_name = "dsp1", .system_name = "ABC123",
659 .expect_wmfw = "cirrus/cs1234-dsp1-mbc-vss-abc123.wmfw",
660 .expect_bin = "cirrus/cs1234-dsp1-mbc-vss-abc123.bin",
661 .expected_searches =
662 "cirrus/cs1234-dsp1-mbc-vss-abc123.wmfw "
663 "cirrus/cs1234-dsp1-mbc-vss-abc123.bin",
664 },
665 { /* Optional qualified wmfw found. Qualified bin found. */
666 .part = "cs1234", .dsp_name = "dsp1", .system_name = "ABC123",
667 .wmfw_optional = true,
668 .expect_wmfw = "cirrus/cs1234-dsp1-mbc-vss-abc123.wmfw",
669 .expect_bin = "cirrus/cs1234-dsp1-mbc-vss-abc123.bin",
670 .expected_searches =
671 "cirrus/cs1234-dsp1-mbc-vss-abc123.wmfw "
672 "cirrus/cs1234-dsp1-mbc-vss-abc123.bin",
673 },
674 { /* Optional wmfw not found. Qualified bin found. */
675 .part = "cs1234", .dsp_name = "dsp1", .system_name = "ABC123",
676 .wmfw_optional = true,
677 .expect_bin = "cirrus/cs1234-dsp1-mbc-vss-abc123.bin",
678 .expected_searches =
679 "cirrus/cs1234-dsp1-mbc-vss-abc123.wmfw "
680 "cirrus/cs1234-dsp1-mbc-vss-abc123.bin",
681 },
682 { /* No qualified wmfw. Legacy generic wmfw found. No bin. */
683 .part = "cs1234", .dsp_name = "dsp1", .system_name = "ABC123",
684 .expect_wmfw = "cs1234-dsp1-mbc-vss.wmfw",
685 .expected_searches =
686 "cirrus/cs1234-dsp1-mbc-vss-abc123.wmfw "
687 "cs1234-dsp1-mbc-vss.wmfw "
688 "cs1234-dsp1-mbc-vss.bin",
689 },
690 { /* No qualified optional wmfw. Legacy generic wmfw found. No bin. */
691 .part = "cs1234", .dsp_name = "dsp1", .system_name = "ABC123",
692 .wmfw_optional = true,
693 .expect_wmfw = "cs1234-dsp1-mbc-vss.wmfw",
694 .expected_searches =
695 "cirrus/cs1234-dsp1-mbc-vss-abc123.wmfw "
696 "cirrus/cs1234-dsp1-mbc-vss-abc123.bin "
697 "cs1234-dsp1-mbc-vss.wmfw "
698 "cs1234-dsp1-mbc-vss.bin",
699 },
700 { /* No qualified wmfw. Legacy generic wmfw and bin found. */
701 .part = "cs1234", .dsp_name = "dsp1", .system_name = "ABC123",
702 .expect_wmfw = "cs1234-dsp1-mbc-vss.wmfw",
703 .expect_bin = "cs1234-dsp1-mbc-vss.bin",
704 .expected_searches =
705 "cirrus/cs1234-dsp1-mbc-vss-abc123.wmfw "
706 "cs1234-dsp1-mbc-vss.wmfw "
707 "cs1234-dsp1-mbc-vss.bin",
708 },
709 { /* No qualified optional wmfw. Legacy generic wmfw and bin found. */
710 .part = "cs1234", .dsp_name = "dsp1", .system_name = "ABC123",
711 .wmfw_optional = true,
712 .expect_wmfw = "cs1234-dsp1-mbc-vss.wmfw",
713 .expect_bin = "cs1234-dsp1-mbc-vss.bin",
714 .expected_searches =
715 "cirrus/cs1234-dsp1-mbc-vss-abc123.wmfw "
716 "cirrus/cs1234-dsp1-mbc-vss-abc123.bin "
717 "cs1234-dsp1-mbc-vss.wmfw "
718 "cs1234-dsp1-mbc-vss.bin",
719 },
720 { /* No qualified or legacy wmfw. Generic wmfw found. No bin. */
721 .part = "cs1234", .dsp_name = "dsp1", .system_name = "ABC123",
722 .expect_wmfw = "cirrus/cs1234-dsp1-mbc-vss.wmfw",
723 .expected_searches =
724 "cirrus/cs1234-dsp1-mbc-vss-abc123.wmfw "
725 "cs1234-dsp1-mbc-vss.wmfw "
726 "cirrus/cs1234-dsp1-mbc-vss.wmfw "
727 "cirrus/cs1234-dsp1-mbc-vss.bin",
728 },
729 { /* No optional qualified or legacy wmfw. Generic wmfw found. No bin. */
730 .part = "cs1234", .dsp_name = "dsp1", .system_name = "ABC123",
731 .wmfw_optional = true,
732 .expect_wmfw = "cirrus/cs1234-dsp1-mbc-vss.wmfw",
733 .expected_searches =
734 "cirrus/cs1234-dsp1-mbc-vss-abc123.wmfw "
735 "cirrus/cs1234-dsp1-mbc-vss-abc123.bin "
736 "cs1234-dsp1-mbc-vss.wmfw "
737 "cirrus/cs1234-dsp1-mbc-vss.wmfw "
738 "cirrus/cs1234-dsp1-mbc-vss.bin",
739 },
740 { /* No qualified or legacy wmfw. Generic wmfw and bin found. */
741 .part = "cs1234", .dsp_name = "dsp1", .system_name = "ABC123",
742 .expect_wmfw = "cirrus/cs1234-dsp1-mbc-vss.wmfw",
743 .expect_bin = "cirrus/cs1234-dsp1-mbc-vss.bin",
744 .expected_searches =
745 "cirrus/cs1234-dsp1-mbc-vss-abc123.wmfw "
746 "cs1234-dsp1-mbc-vss.wmfw "
747 "cirrus/cs1234-dsp1-mbc-vss.wmfw "
748 "cirrus/cs1234-dsp1-mbc-vss.bin",
749 },
750 { /* No optional qualified or legacy wmfw. Generic wmfw and bin found. */
751 .part = "cs1234", .dsp_name = "dsp1", .system_name = "ABC123",
752 .wmfw_optional = true,
753 .expect_wmfw = "cirrus/cs1234-dsp1-mbc-vss.wmfw",
754 .expect_bin = "cirrus/cs1234-dsp1-mbc-vss.bin",
755 .expected_searches =
756 "cirrus/cs1234-dsp1-mbc-vss-abc123.wmfw "
757 "cirrus/cs1234-dsp1-mbc-vss-abc123.bin "
758 "cs1234-dsp1-mbc-vss.wmfw "
759 "cirrus/cs1234-dsp1-mbc-vss.wmfw "
760 "cirrus/cs1234-dsp1-mbc-vss.bin",
761 },
762 { /* No optional qualified or generic wmfw. Generic bin found. */
763 .part = "cs1234", .dsp_name = "dsp1", .system_name = "ABC123",
764 .wmfw_optional = true,
765 .expect_bin = "cirrus/cs1234-dsp1-mbc-vss.bin",
766 .expected_searches =
767 "cirrus/cs1234-dsp1-mbc-vss-abc123.wmfw "
768 "cirrus/cs1234-dsp1-mbc-vss-abc123.bin "
769 "cs1234-dsp1-mbc-vss.wmfw "
770 "cirrus/cs1234-dsp1-mbc-vss.wmfw "
771 "cirrus/cs1234-dsp1-mbc-vss.bin",
772 },
773 };
774 KUNIT_ARRAY_PARAM(wm_adsp_fw_find_system,
775 wm_adsp_fw_find_system_cases,
776 wm_adsp_fw_find_test_param_desc);
777
778 /* Cases without system name but with alsa name prefix. */
779 static const struct wm_adsp_fw_find_test_params wm_adsp_fw_find_alsaname_cases[] = {
780 { /* Legacy generic wmfw found. No bin. */
781 .part = "cs1234", .dsp_name = "dsp1", .alsa_name = "amp1",
782 .expect_wmfw = "cs1234-dsp1-mbc-vss.wmfw",
783 .expected_searches =
784 "cs1234-dsp1-mbc-vss.wmfw "
785 "cs1234-dsp1-mbc-vss.bin",
786 },
787 { /* wmfw optional. Legacy generic wmfw found. No bin. */
788 .part = "cs1234", .dsp_name = "dsp1", .alsa_name = "amp1",
789 .wmfw_optional = true,
790 .expect_wmfw = "cs1234-dsp1-mbc-vss.wmfw",
791 .expected_searches =
792 "cs1234-dsp1-mbc-vss.wmfw "
793 "cs1234-dsp1-mbc-vss.bin",
794 },
795 { /* Legacy generic wmfw and bin found. */
796 .part = "cs1234", .dsp_name = "dsp1", .alsa_name = "amp1",
797 .expect_wmfw = "cs1234-dsp1-mbc-vss.wmfw",
798 .expect_bin = "cs1234-dsp1-mbc-vss.bin",
799 .expected_searches =
800 "cs1234-dsp1-mbc-vss.wmfw "
801 "cs1234-dsp1-mbc-vss.bin",
802 },
803 { /* wmfw optional. Legacy generic wmfw and bin found. */
804 .part = "cs1234", .dsp_name = "dsp1", .alsa_name = "amp1",
805 .wmfw_optional = true,
806 .expect_wmfw = "cs1234-dsp1-mbc-vss.wmfw",
807 .expect_bin = "cs1234-dsp1-mbc-vss.bin",
808 .expected_searches =
809 "cs1234-dsp1-mbc-vss.wmfw "
810 "cs1234-dsp1-mbc-vss.bin",
811 },
812 { /* No legacy wmfw. Generic wmfw found. No bin. */
813 .part = "cs1234", .dsp_name = "dsp1", .alsa_name = "amp1",
814 .expect_wmfw = "cirrus/cs1234-dsp1-mbc-vss.wmfw",
815 .expected_searches =
816 "cs1234-dsp1-mbc-vss.wmfw "
817 "cirrus/cs1234-dsp1-mbc-vss.wmfw "
818 "cirrus/cs1234-dsp1-mbc-vss.bin",
819 },
820 { /* No legacy wmfw. Optional generic wmfw found. No bin. */
821 .part = "cs1234", .dsp_name = "dsp1", .alsa_name = "amp1",
822 .wmfw_optional = true,
823 .expect_wmfw = "cirrus/cs1234-dsp1-mbc-vss.wmfw",
824 .expected_searches =
825 "cs1234-dsp1-mbc-vss.wmfw "
826 "cirrus/cs1234-dsp1-mbc-vss.wmfw "
827 "cirrus/cs1234-dsp1-mbc-vss.bin",
828 },
829 { /* No legacy wmfw. Generic wmfw and bin found. */
830 .part = "cs1234", .dsp_name = "dsp1", .alsa_name = "amp1",
831 .expect_wmfw = "cirrus/cs1234-dsp1-mbc-vss.wmfw",
832 .expect_bin = "cirrus/cs1234-dsp1-mbc-vss.bin",
833 .expected_searches =
834 "cs1234-dsp1-mbc-vss.wmfw "
835 "cirrus/cs1234-dsp1-mbc-vss.wmfw "
836 "cirrus/cs1234-dsp1-mbc-vss.bin",
837 },
838 { /* No legacy wmfw. Optional generic wmfw and bin found. */
839 .part = "cs1234", .dsp_name = "dsp1", .alsa_name = "amp1",
840 .wmfw_optional = true,
841 .expect_wmfw = "cirrus/cs1234-dsp1-mbc-vss.wmfw",
842 .expect_bin = "cirrus/cs1234-dsp1-mbc-vss.bin",
843 .expected_searches =
844 "cs1234-dsp1-mbc-vss.wmfw "
845 "cirrus/cs1234-dsp1-mbc-vss.wmfw "
846 "cirrus/cs1234-dsp1-mbc-vss.bin",
847 },
848 { /* No legacy or generic wmfw. Generic bin found. */
849 .part = "cs1234", .dsp_name = "dsp1", .alsa_name = "amp1",
850 .wmfw_optional = true,
851 .expect_bin = "cirrus/cs1234-dsp1-mbc-vss.bin",
852 .expected_searches =
853 "cs1234-dsp1-mbc-vss.wmfw "
854 "cirrus/cs1234-dsp1-mbc-vss.wmfw "
855 "cirrus/cs1234-dsp1-mbc-vss.bin",
856 },
857 };
858 KUNIT_ARRAY_PARAM(wm_adsp_fw_find_alsaname,
859 wm_adsp_fw_find_alsaname_cases,
860 wm_adsp_fw_find_test_param_desc);
861
862 /* Cases without system name or alsa name prefix. */
863 static const struct wm_adsp_fw_find_test_params wm_adsp_fw_find_noqual_cases[] = {
864 { /* Legacy generic wmfw found. No bin. */
865 .part = "cs1234", .dsp_name = "dsp1",
866 .expect_wmfw = "cs1234-dsp1-mbc-vss.wmfw",
867 .expected_searches =
868 "cs1234-dsp1-mbc-vss.wmfw "
869 "cs1234-dsp1-mbc-vss.bin",
870 },
871 { /* wmfw optional. Legacy generic wmfw found. No bin. */
872 .part = "cs1234", .dsp_name = "dsp1",
873 .wmfw_optional = true,
874 .expect_wmfw = "cs1234-dsp1-mbc-vss.wmfw",
875 .expected_searches =
876 "cs1234-dsp1-mbc-vss.wmfw "
877 "cs1234-dsp1-mbc-vss.bin",
878 },
879 { /* Legacy generic wmfw and bin found. */
880 .part = "cs1234", .dsp_name = "dsp1",
881 .expect_wmfw = "cs1234-dsp1-mbc-vss.wmfw",
882 .expect_bin = "cs1234-dsp1-mbc-vss.bin",
883 .expected_searches =
884 "cs1234-dsp1-mbc-vss.wmfw "
885 "cs1234-dsp1-mbc-vss.bin",
886 },
887 { /* wmfw optional. Legacy generic wmfw and bin found. */
888 .part = "cs1234", .dsp_name = "dsp1",
889 .wmfw_optional = true,
890 .expect_wmfw = "cs1234-dsp1-mbc-vss.wmfw",
891 .expect_bin = "cs1234-dsp1-mbc-vss.bin",
892 .expected_searches =
893 "cs1234-dsp1-mbc-vss.wmfw "
894 "cs1234-dsp1-mbc-vss.bin",
895 },
896 { /* No legacy wmfw. Generic wmfw found. No bin. */
897 .part = "cs1234", .dsp_name = "dsp1",
898 .expect_wmfw = "cirrus/cs1234-dsp1-mbc-vss.wmfw",
899 .expected_searches =
900 "cs1234-dsp1-mbc-vss.wmfw "
901 "cirrus/cs1234-dsp1-mbc-vss.wmfw "
902 "cirrus/cs1234-dsp1-mbc-vss.bin",
903 },
904 { /* No legacy wmfw. Optional generic wmfw found. No bin. */
905 .part = "cs1234", .dsp_name = "dsp1",
906 .wmfw_optional = true,
907 .expect_wmfw = "cirrus/cs1234-dsp1-mbc-vss.wmfw",
908 .expected_searches =
909 "cs1234-dsp1-mbc-vss.wmfw "
910 "cirrus/cs1234-dsp1-mbc-vss.wmfw "
911 "cirrus/cs1234-dsp1-mbc-vss.bin",
912 },
913 { /* No legacy wmfw. Generic wmfw and bin found. */
914 .part = "cs1234", .dsp_name = "dsp1",
915 .expect_wmfw = "cirrus/cs1234-dsp1-mbc-vss.wmfw",
916 .expect_bin = "cirrus/cs1234-dsp1-mbc-vss.bin",
917 .expected_searches =
918 "cs1234-dsp1-mbc-vss.wmfw "
919 "cirrus/cs1234-dsp1-mbc-vss.wmfw "
920 "cirrus/cs1234-dsp1-mbc-vss.bin",
921 },
922 { /* No legacy wmfw. Optional generic wmfw and bin found. */
923 .part = "cs1234", .dsp_name = "dsp1",
924 .wmfw_optional = true,
925 .expect_wmfw = "cirrus/cs1234-dsp1-mbc-vss.wmfw",
926 .expect_bin = "cirrus/cs1234-dsp1-mbc-vss.bin",
927 .expected_searches =
928 "cs1234-dsp1-mbc-vss.wmfw "
929 "cirrus/cs1234-dsp1-mbc-vss.wmfw "
930 "cirrus/cs1234-dsp1-mbc-vss.bin",
931 },
932 { /* No legacy or generic wmfw. Generic bin found. */
933 .part = "cs1234", .dsp_name = "dsp1",
934 .wmfw_optional = true,
935 .expect_bin = "cirrus/cs1234-dsp1-mbc-vss.bin",
936 .expected_searches =
937 "cs1234-dsp1-mbc-vss.wmfw "
938 "cirrus/cs1234-dsp1-mbc-vss.wmfw "
939 "cirrus/cs1234-dsp1-mbc-vss.bin",
940 },
941 };
942 KUNIT_ARRAY_PARAM(wm_adsp_fw_find_noqual,
943 wm_adsp_fw_find_noqual_cases,
944 wm_adsp_fw_find_test_param_desc);
945
946 /*
947 * Tests for filename normalization. The system name and alsa prefix strings
948 * should be converted to lower-case and delimiters are converted to '-', except
949 * for '.' which is preserved.
950 */
951 static const struct wm_adsp_fw_find_test_params wm_adsp_fw_find_normalization_cases[] = {
952 {
953 .part = "cs1234", .dsp_name = "dsp1", .system_name = "Vendor",
954 .expect_wmfw = "cirrus/cs1234-dsp1-mbc-vss-vendor.wmfw",
955 .expected_searches =
956 "cirrus/cs1234-dsp1-mbc-vss-vendor.wmfw "
957 "cirrus/cs1234-dsp1-mbc-vss-vendor.bin",
958 },
959 {
960 .part = "cs1234", .dsp_name = "dsp1", .system_name = "Vendor Device",
961 .expect_wmfw = "cirrus/cs1234-dsp1-mbc-vss-vendor-device.wmfw",
962 .expected_searches =
963 "cirrus/cs1234-dsp1-mbc-vss-vendor-device.wmfw "
964 "cirrus/cs1234-dsp1-mbc-vss-vendor-device.bin",
965 },
966 {
967 .part = "cs1234", .dsp_name = "dsp1", .system_name = "Vendor_Device",
968 .expect_wmfw = "cirrus/cs1234-dsp1-mbc-vss-vendor-device.wmfw",
969 .expected_searches =
970 "cirrus/cs1234-dsp1-mbc-vss-vendor-device.wmfw "
971 "cirrus/cs1234-dsp1-mbc-vss-vendor-device.bin",
972 },
973 {
974 .part = "cs1234", .dsp_name = "dsp1", .system_name = "Vendor/Device",
975 .expect_wmfw = "cirrus/cs1234-dsp1-mbc-vss-vendor-device.wmfw",
976 .expected_searches =
977 "cirrus/cs1234-dsp1-mbc-vss-vendor-device.wmfw "
978 "cirrus/cs1234-dsp1-mbc-vss-vendor-device.bin",
979 },
980 {
981 .part = "cs1234", .dsp_name = "dsp1", .system_name = "1234:56AB",
982 .expect_wmfw = "cirrus/cs1234-dsp1-mbc-vss-1234-56ab.wmfw",
983 .expected_searches =
984 "cirrus/cs1234-dsp1-mbc-vss-1234-56ab.wmfw "
985 "cirrus/cs1234-dsp1-mbc-vss-1234-56ab.bin",
986 },
987
988 {
989 .part = "cs1234", .dsp_name = "dsp1", .system_name = "abc",
990 .alsa_name = "LEFT",
991 .expect_wmfw = "cirrus/cs1234-dsp1-mbc-vss-abc-left.wmfw",
992 .expected_searches =
993 "cirrus/cs1234-dsp1-mbc-vss-abc-left.wmfw "
994 "cirrus/cs1234-dsp1-mbc-vss-abc-left.bin",
995 },
996 {
997 .part = "cs1234", .dsp_name = "dsp1", .system_name = "abc",
998 .alsa_name = "LEFT AMP",
999 .expect_wmfw = "cirrus/cs1234-dsp1-mbc-vss-abc-left-amp.wmfw",
1000 .expected_searches =
1001 "cirrus/cs1234-dsp1-mbc-vss-abc-left-amp.wmfw "
1002 "cirrus/cs1234-dsp1-mbc-vss-abc-left-amp.bin",
1003 },
1004 {
1005 .part = "cs1234", .dsp_name = "dsp1", .system_name = "abc",
1006 .alsa_name = "Left Amp",
1007 .expect_wmfw = "cirrus/cs1234-dsp1-mbc-vss-abc-left-amp.wmfw",
1008 .expected_searches =
1009 "cirrus/cs1234-dsp1-mbc-vss-abc-left-amp.wmfw "
1010 "cirrus/cs1234-dsp1-mbc-vss-abc-left-amp.bin",
1011 },
1012 {
1013 .part = "cs1234", .dsp_name = "dsp1", .system_name = "abc",
1014 .alsa_name = "Amp_1",
1015 .expect_wmfw = "cirrus/cs1234-dsp1-mbc-vss-abc-amp-1.wmfw",
1016 .expected_searches =
1017 "cirrus/cs1234-dsp1-mbc-vss-abc-amp-1.wmfw "
1018 "cirrus/cs1234-dsp1-mbc-vss-abc-amp-1.bin",
1019 },
1020 {
1021 .part = "cs1234", .dsp_name = "dsp1", .system_name = "abc",
1022 .alsa_name = "cs1234.1",
1023 .expect_wmfw = "cirrus/cs1234-dsp1-mbc-vss-abc-cs1234.1.wmfw",
1024 .expected_searches =
1025 "cirrus/cs1234-dsp1-mbc-vss-abc-cs1234.1.wmfw "
1026 "cirrus/cs1234-dsp1-mbc-vss-abc-cs1234.1.bin",
1027 },
1028 {
1029 .part = "cs1234", .dsp_name = "dsp1", .system_name = "abc",
1030 .alsa_name = "Spk/Jack",
1031 .expect_wmfw = "cirrus/cs1234-dsp1-mbc-vss-abc-spk-jack.wmfw",
1032 .expected_searches =
1033 "cirrus/cs1234-dsp1-mbc-vss-abc-spk-jack.wmfw "
1034 "cirrus/cs1234-dsp1-mbc-vss-abc-spk-jack.bin",
1035 },
1036 };
1037 KUNIT_ARRAY_PARAM(wm_adsp_fw_find_normalization,
1038 wm_adsp_fw_find_normalization_cases,
1039 wm_adsp_fw_find_test_param_desc);
1040
1041 /*
1042 * Dummy directory content for regression tests.
1043 * DSP part name and system name are used to select different available
1044 * files.
1045 *
1046 * System:
1047 * WFBF1111 = wmfw and bin fully-qualified
1048 * WSBF1111 = wmfw system-qualified, bin fully-qualified
1049 * WSBS1111 = wmfw and bin system-qualified
1050 * WFXX1111 = wmfw fully-qualified, bin not present
1051 * XXBF1111 = wmfw not present, bin fully-qualified
1052 *
1053 * Part:
1054 * cs1234 = for testing fully-qualified configurations
1055 * cs1234nobin = generic wmfw without a bin available
1056 * wm1234 = legacy wmfw and bin
1057 * wm1234nobin = legacy wmfw without bin
1058 */
1059 static const char * const wm_adsp_fw_find_test_dir_all_files[] = {
1060 "cirrus/cs1234-dsp1-mbc-vss-wfbf1111-amp1.wmfw",
1061 "cirrus/cs1234-dsp1-mbc-vss-wfbf1111-l1u2.wmfw",
1062 "cirrus/cs1234-dsp1-mbc-vss-wfbf1111.wmfw",
1063 "cirrus/cs1234-dsp1-mbc-vss-wsbf1111.wmfw",
1064 "cirrus/cs1234-dsp1-mbc-vss-wsbs1111.wmfw",
1065 "cirrus/cs1234-dsp1-mbc-vss-wfxx1111.wmfw",
1066 "cirrus/cs1234-dsp1-mbc-vss.wmfw",
1067 "cirrus/cs1234nobin-dsp1-mbc-vss.wmfw",
1068 "cirrus/wm1234-dsp1-mbc-vss.wmfw",
1069 "cirrus/wm1234nobin-dsp1-mbc-vss.wmfw",
1070 "wm1234-dsp1-mbc-vss.wmfw",
1071 "wm1234nobin-dsp1-mbc-vss.wmfw",
1072 "cirrus/cs1234-dsp1-mbc-vss-wfbf1111-amp1.bin",
1073 "cirrus/cs1234-dsp1-mbc-vss-wfbf1111-l1u2.bin",
1074 "cirrus/cs1234-dsp1-mbc-vss-wsbf1111-amp1.bin",
1075 "cirrus/cs1234-dsp1-mbc-vss-wsbf1111-l1u2.bin",
1076 "cirrus/cs1234-dsp1-mbc-vss-wsbs1111.bin",
1077 "cirrus/cs1234-dsp1-mbc-vss-xxbf1111-amp1.bin",
1078 "cirrus/cs1234-dsp1-mbc-vss.bin",
1079 "cirrus/wm1234-dsp1-mbc-vss.bin",
1080 "wm1234-dsp1-mbc-vss.bin",
1081 NULL /* terminator */
1082 };
1083
1084 /*
1085 * Regression testing that a change in the search algorithm doesn't change
1086 * which file is picked. This doesn't cover every possible combination, only
1087 * those that are already in use and typical cases.
1088 *
1089 * It wouldn't be efficent to fully prove the algorithm this way (too many
1090 * directory content combinations would be needed, and it only infers what the
1091 * algorithm searched for, it doesn't prove exactly what searches were made).
1092 * So the main testing is done by checking for the expected file searches.
1093 * This regression test is independent of the search algorithm.
1094 *
1095 * The main tests already prove that the algorithm only searches for files
1096 * with the correct qualifiers so we can assume that files with the wrong
1097 * qualifiers would not be picked and there's no need to test for that here.
1098 */
1099 static const struct wm_adsp_fw_find_test_params wm_adsp_fw_find_pick_cases[] = {
1100 /*
1101 * Amps
1102 */
1103 { /* Full info, wmfw and bin fully-qualified */
1104 .part = "cs1234", .dsp_name = "dsp1", .system_name = "WFBF1111",
1105 .alsa_name = "amp1",
1106 .expect_wmfw = "cirrus/cs1234-dsp1-mbc-vss-wfbf1111-amp1.wmfw",
1107 .expect_bin = "cirrus/cs1234-dsp1-mbc-vss-wfbf1111-amp1.bin",
1108 .dir_files = wm_adsp_fw_find_test_dir_all_files,
1109 },
1110 { /* Full info, wmfw and bin fully-qualified */
1111 .part = "cs1234", .dsp_name = "dsp1", .system_name = "WFBF1111",
1112 .alsa_name = "l1u2",
1113 .expect_wmfw = "cirrus/cs1234-dsp1-mbc-vss-wfbf1111-l1u2.wmfw",
1114 .expect_bin = "cirrus/cs1234-dsp1-mbc-vss-wfbf1111-l1u2.bin",
1115 .dir_files = wm_adsp_fw_find_test_dir_all_files,
1116 },
1117 { /* Full info, wmfw only system-qualified, bin fully-qualified */
1118 .part = "cs1234", .dsp_name = "dsp1", .system_name = "WSBF1111",
1119 .alsa_name = "amp1",
1120 .expect_wmfw = "cirrus/cs1234-dsp1-mbc-vss-wsbf1111.wmfw",
1121 .expect_bin = "cirrus/cs1234-dsp1-mbc-vss-wsbf1111-amp1.bin",
1122 .dir_files = wm_adsp_fw_find_test_dir_all_files,
1123 },
1124 { /* Full info, wmfw only system-qualified, bin fully-qualified */
1125 .part = "cs1234", .dsp_name = "dsp1", .system_name = "WSBF1111",
1126 .alsa_name = "l1u2",
1127 .expect_wmfw = "cirrus/cs1234-dsp1-mbc-vss-wsbf1111.wmfw",
1128 .expect_bin = "cirrus/cs1234-dsp1-mbc-vss-wsbf1111-l1u2.bin",
1129 .dir_files = wm_adsp_fw_find_test_dir_all_files,
1130 },
1131 { /* Full info, wmfw optional but present, and bin fully-qualified */
1132 .part = "cs1234", .dsp_name = "dsp1", .system_name = "WFBF1111",
1133 .alsa_name = "amp1", .wmfw_optional = true,
1134 .expect_wmfw = "cirrus/cs1234-dsp1-mbc-vss-wfbf1111-amp1.wmfw",
1135 .expect_bin = "cirrus/cs1234-dsp1-mbc-vss-wfbf1111-amp1.bin",
1136 .dir_files = wm_adsp_fw_find_test_dir_all_files,
1137 },
1138 { /* Full info, wmfw and bin only system-qualified */
1139 .part = "cs1234", .dsp_name = "dsp1", .system_name = "WSBS1111",
1140 .alsa_name = "amp1",
1141 .expect_wmfw = "cirrus/cs1234-dsp1-mbc-vss-wsbs1111.wmfw",
1142 .expect_bin = "cirrus/cs1234-dsp1-mbc-vss-wsbs1111.bin",
1143 .dir_files = wm_adsp_fw_find_test_dir_all_files,
1144 },
1145 { /* Full info, wmfw optional but system-qualified wmfm present, bin fully-qualified */
1146 .part = "cs1234", .dsp_name = "dsp1", .system_name = "WSBF1111",
1147 .alsa_name = "amp1", .wmfw_optional = true,
1148 .expect_wmfw = "cirrus/cs1234-dsp1-mbc-vss-wsbf1111.wmfw",
1149 .expect_bin = "cirrus/cs1234-dsp1-mbc-vss-wsbf1111-amp1.bin",
1150 .dir_files = wm_adsp_fw_find_test_dir_all_files,
1151 },
1152 { /* Full info, wmfw optional not present, and bin fully-qualified */
1153 .part = "cs1234", .dsp_name = "dsp1", .system_name = "XXBF1111",
1154 .alsa_name = "amp1", .wmfw_optional = true,
1155 .expect_bin = "cirrus/cs1234-dsp1-mbc-vss-xxbf1111-amp1.bin",
1156 .dir_files = wm_adsp_fw_find_test_dir_all_files,
1157 },
1158 { /* Full info, wmfw and bin fully-qualified, bin mandatory and present */
1159 .part = "cs1234", .dsp_name = "dsp1", .system_name = "WFBF1111",
1160 .alsa_name = "amp1", .bin_mandatory = true,
1161 .expect_wmfw = "cirrus/cs1234-dsp1-mbc-vss-wfbf1111-amp1.wmfw",
1162 .expect_bin = "cirrus/cs1234-dsp1-mbc-vss-wfbf1111-amp1.bin",
1163 .dir_files = wm_adsp_fw_find_test_dir_all_files,
1164 },
1165 { /* Full info, wmfw and bin fully-qualified, bin mandatory but not present */
1166 .part = "cs1234", .dsp_name = "dsp1", .system_name = "WFXX1111",
1167 .alsa_name = "amp1", .bin_mandatory = true,
1168 .expect_wmfw = "cirrus/cs1234-dsp1-mbc-vss-wfxx1111.wmfw",
1169 .dir_files = wm_adsp_fw_find_test_dir_all_files,
1170 },
1171 { /* Full info, wmfw optional but present, bin mandatory but not present */
1172 .part = "cs1234", .dsp_name = "dsp1", .system_name = "WFXX1111",
1173 .alsa_name = "amp1", .wmfw_optional = true, .bin_mandatory = true,
1174 .expect_wmfw = "cirrus/cs1234-dsp1-mbc-vss-wfxx1111.wmfw",
1175 .dir_files = wm_adsp_fw_find_test_dir_all_files,
1176 },
1177 { /* Full info, wmfw and bin not present, generic fallbacks are present */
1178 .part = "cs1234", .dsp_name = "dsp1", .system_name = "XXXX1111",
1179 .alsa_name = "amp1",
1180 .expect_wmfw = "cirrus/cs1234-dsp1-mbc-vss.wmfw",
1181 .expect_bin = "cirrus/cs1234-dsp1-mbc-vss.bin",
1182 .dir_files = wm_adsp_fw_find_test_dir_all_files,
1183 },
1184 { /* Full info, wmfw and bin not present, generic wmfw present */
1185 .part = "cs1234nobin", .dsp_name = "dsp1", .system_name = "XXXX1111",
1186 .alsa_name = "amp1",
1187 .expect_wmfw = "cirrus/cs1234nobin-dsp1-mbc-vss.wmfw",
1188 .dir_files = wm_adsp_fw_find_test_dir_all_files,
1189 },
1190
1191 /*
1192 * Codecs
1193 */
1194 { /* No qualifiers. Generic wmfws exist, legacy should be chosen. */
1195 .part = "wm1234nobin", .dsp_name = "dsp1",
1196 .expect_wmfw = "wm1234nobin-dsp1-mbc-vss.wmfw",
1197 .dir_files = wm_adsp_fw_find_test_dir_all_files,
1198 },
1199 { /* No qualifiers. Generic wmfw and bin exist, legacy should be chosen */
1200 .part = "wm1234", .dsp_name = "dsp1",
1201 .expect_wmfw = "wm1234-dsp1-mbc-vss.wmfw",
1202 .expect_bin = "wm1234-dsp1-mbc-vss.bin",
1203 .dir_files = wm_adsp_fw_find_test_dir_all_files,
1204 },
1205 { /* No qualifiers. New generic wmfw exists, no legacy files. */
1206 .part = "cs1234nobin", .dsp_name = "dsp1",
1207 .expect_wmfw = "cirrus/cs1234nobin-dsp1-mbc-vss.wmfw",
1208 .dir_files = wm_adsp_fw_find_test_dir_all_files,
1209 },
1210 { /* No qualifiers. New generic wmfw and bin exist, no legacy files. */
1211 .part = "cs1234", .dsp_name = "dsp1",
1212 .expect_wmfw = "cirrus/cs1234-dsp1-mbc-vss.wmfw",
1213 .expect_bin = "cirrus/cs1234-dsp1-mbc-vss.bin",
1214 .dir_files = wm_adsp_fw_find_test_dir_all_files,
1215 },
1216 };
1217 KUNIT_ARRAY_PARAM(wm_adsp_fw_find_pick,
1218 wm_adsp_fw_find_pick_cases,
1219 wm_adsp_fw_find_test_param_desc);
1220
1221 static struct kunit_case wm_adsp_fw_find_test_cases[] = {
1222 KUNIT_CASE_PARAM(wm_adsp_fw_find_test_search_order,
1223 wm_adsp_fw_find_full_search_gen_params),
1224
1225 KUNIT_CASE_PARAM(wm_adsp_fw_find_test_search_order,
1226 wm_adsp_fw_find_system_alsaname_gen_params),
1227
1228 KUNIT_CASE_PARAM(wm_adsp_fw_find_test_search_order,
1229 wm_adsp_fw_find_system_gen_params),
1230
1231 KUNIT_CASE_PARAM(wm_adsp_fw_find_test_search_order,
1232 wm_adsp_fw_find_alsaname_gen_params),
1233
1234 KUNIT_CASE_PARAM(wm_adsp_fw_find_test_search_order,
1235 wm_adsp_fw_find_noqual_gen_params),
1236
1237 KUNIT_CASE_PARAM(wm_adsp_fw_find_test_search_order,
1238 wm_adsp_fw_find_normalization_gen_params),
1239
1240 KUNIT_CASE_PARAM(wm_adsp_fw_find_test_pick_file,
1241 wm_adsp_fw_find_pick_gen_params),
1242
1243 KUNIT_CASE(wm_adsp_fw_find_test_find_firmware_byindex),
1244
1245 { } /* terminator */
1246 };
1247
1248 static struct kunit_suite wm_adsp_fw_find_test_suite = {
1249 .name = "wm-adsp-fw-find",
1250 .init = wm_adsp_fw_find_test_case_init,
1251 .exit = wm_adsp_fw_find_test_case_exit,
1252 .test_cases = wm_adsp_fw_find_test_cases,
1253 };
1254
1255 kunit_test_suite(wm_adsp_fw_find_test_suite);
1256
1257 MODULE_DESCRIPTION("KUnit test for Cirrus Logic wm_adsp driver");
1258 MODULE_AUTHOR("Richard Fitzgerald <rf@opensource.cirrus.com>");
1259 MODULE_LICENSE("GPL");
1260 MODULE_IMPORT_NS("EXPORTED_FOR_KUNIT_TESTING");
1261