xref: /linux/tools/testing/selftests/alsa/mixer-test.c (revision 26ba30221c03364d6ed9910be8da4c1fd871b07b)
1 // SPDX-License-Identifier: GPL-2.0
2 //
3 // kselftest for the ALSA mixer API
4 //
5 // Original author: Mark Brown <broonie@kernel.org>
6 // Copyright (c) 2021-2 Arm Limited
7 
8 // This test will iterate over all cards detected in the system, exercising
9 // every mixer control it can find.  This may conflict with other system
10 // software if there is audio activity so is best run on a system with a
11 // minimal active userspace.
12 
13 #include <stdio.h>
14 #include <stdlib.h>
15 #include <stdbool.h>
16 #include <limits.h>
17 #include <string.h>
18 #include <getopt.h>
19 #include <stdarg.h>
20 #include <ctype.h>
21 #include <math.h>
22 #include <errno.h>
23 #include <assert.h>
24 #include <alsa/asoundlib.h>
25 #include <poll.h>
26 #include <stdint.h>
27 
28 #include "kselftest.h"
29 #include "alsa-local.h"
30 
31 #define TESTS_PER_CONTROL 7
32 
33 struct card_data {
34 	snd_ctl_t *handle;
35 	int card;
36 	snd_ctl_card_info_t *info;
37 	const char *card_name;
38 	struct pollfd pollfd;
39 	int num_ctls;
40 	snd_ctl_elem_list_t *ctls;
41 	struct card_data *next;
42 };
43 
44 struct ctl_data {
45 	const char *name;
46 	snd_ctl_elem_id_t *id;
47 	snd_ctl_elem_info_t *info;
48 	snd_ctl_elem_value_t *def_val;
49 	int elem;
50 	int event_missing;
51 	int event_spurious;
52 	struct card_data *card;
53 	struct ctl_data *next;
54 };
55 
56 int num_cards;
57 int num_controls;
58 struct card_data *card_list;
59 struct ctl_data *ctl_list;
60 
61 static void find_controls(void)
62 {
63 	char name[32];
64 	int card, ctl, err;
65 	struct card_data *card_data;
66 	struct ctl_data *ctl_data;
67 	snd_config_t *config;
68 	char *card_name, *card_longname;
69 
70 	card = -1;
71 	if (snd_card_next(&card) < 0 || card < 0)
72 		return;
73 
74 	config = get_alsalib_config();
75 
76 	while (card >= 0) {
77 		sprintf(name, "hw:%d", card);
78 
79 		card_data = malloc(sizeof(*card_data));
80 		if (!card_data)
81 			ksft_exit_fail_msg("Out of memory\n");
82 
83 		err = snd_ctl_open_lconf(&card_data->handle, name, 0, config);
84 		if (err < 0) {
85 			ksft_print_msg("Failed to get hctl for card %d: %s\n",
86 				       card, snd_strerror(err));
87 			free(card_data);
88 			goto next_card;
89 		}
90 
91 		err = snd_card_get_name(card, &card_name);
92 		if (err != 0)
93 			card_name = "Unknown";
94 		err = snd_card_get_longname(card, &card_longname);
95 		if (err != 0)
96 			card_longname = "Unknown";
97 
98 		err = snd_ctl_card_info_malloc(&card_data->info);
99 		if (err != 0)
100 			ksft_exit_fail_msg("Failed to allocate card info: %d\n",
101 				err);
102 
103 		err = snd_ctl_card_info(card_data->handle, card_data->info);
104 		if (err == 0) {
105 			card_data->card_name = snd_ctl_card_info_get_id(card_data->info);
106 			if (!card_data->card_name)
107 				ksft_print_msg("Failed to get card ID\n");
108 		} else {
109 			ksft_print_msg("Failed to get card info: %d\n", err);
110 		}
111 
112 		if (!card_data->card_name)
113 			card_data->card_name = "Unknown";
114 
115 		ksft_print_msg("Card %d/%s - %s (%s)\n", card,
116 			       card_data->card_name, card_name, card_longname);
117 
118 		/* Count controls */
119 		snd_ctl_elem_list_malloc(&card_data->ctls);
120 		snd_ctl_elem_list(card_data->handle, card_data->ctls);
121 		card_data->num_ctls = snd_ctl_elem_list_get_count(card_data->ctls);
122 
123 		/* Enumerate control information */
124 		snd_ctl_elem_list_alloc_space(card_data->ctls, card_data->num_ctls);
125 		snd_ctl_elem_list(card_data->handle, card_data->ctls);
126 
127 		card_data->card = num_cards++;
128 		card_data->next = card_list;
129 		card_list = card_data;
130 
131 		num_controls += card_data->num_ctls;
132 
133 		for (ctl = 0; ctl < card_data->num_ctls; ctl++) {
134 			ctl_data = malloc(sizeof(*ctl_data));
135 			if (!ctl_data)
136 				ksft_exit_fail_msg("Out of memory\n");
137 
138 			memset(ctl_data, 0, sizeof(*ctl_data));
139 			ctl_data->card = card_data;
140 			ctl_data->elem = ctl;
141 			ctl_data->name = snd_ctl_elem_list_get_name(card_data->ctls,
142 								    ctl);
143 
144 			err = snd_ctl_elem_id_malloc(&ctl_data->id);
145 			if (err < 0)
146 				ksft_exit_fail_msg("Out of memory\n");
147 
148 			err = snd_ctl_elem_info_malloc(&ctl_data->info);
149 			if (err < 0)
150 				ksft_exit_fail_msg("Out of memory\n");
151 
152 			err = snd_ctl_elem_value_malloc(&ctl_data->def_val);
153 			if (err < 0)
154 				ksft_exit_fail_msg("Out of memory\n");
155 
156 			snd_ctl_elem_list_get_id(card_data->ctls, ctl,
157 						 ctl_data->id);
158 			snd_ctl_elem_info_set_id(ctl_data->info, ctl_data->id);
159 			err = snd_ctl_elem_info(card_data->handle,
160 						ctl_data->info);
161 			if (err < 0) {
162 				ksft_print_msg("%s getting info for %s\n",
163 					       snd_strerror(err),
164 					       ctl_data->name);
165 			}
166 
167 			snd_ctl_elem_value_set_id(ctl_data->def_val,
168 						  ctl_data->id);
169 
170 			ctl_data->next = ctl_list;
171 			ctl_list = ctl_data;
172 		}
173 
174 		/* Set up for events */
175 		err = snd_ctl_subscribe_events(card_data->handle, true);
176 		if (err < 0) {
177 			ksft_exit_fail_msg("snd_ctl_subscribe_events() failed for card %d: %d\n",
178 					   card, err);
179 		}
180 
181 		err = snd_ctl_poll_descriptors_count(card_data->handle);
182 		if (err != 1) {
183 			ksft_exit_fail_msg("Unexpected descriptor count %d for card %d\n",
184 					   err, card);
185 		}
186 
187 		err = snd_ctl_poll_descriptors(card_data->handle,
188 					       &card_data->pollfd, 1);
189 		if (err != 1) {
190 			ksft_exit_fail_msg("snd_ctl_poll_descriptors() failed for card %d: %d\n",
191 				       card, err);
192 		}
193 
194 	next_card:
195 		if (snd_card_next(&card) < 0) {
196 			ksft_print_msg("snd_card_next");
197 			break;
198 		}
199 	}
200 
201 	snd_config_delete(config);
202 }
203 
204 /*
205  * Block for up to timeout ms for an event, returns a negative value
206  * on error, 0 for no event and 1 for an event.
207  */
208 static int wait_for_event(struct ctl_data *ctl, int timeout)
209 {
210 	unsigned short revents;
211 	snd_ctl_event_t *event;
212 	int err;
213 	unsigned int mask = 0;
214 	unsigned int ev_id;
215 
216 	snd_ctl_event_alloca(&event);
217 
218 	do {
219 		err = poll(&(ctl->card->pollfd), 1, timeout);
220 		if (err < 0) {
221 			ksft_print_msg("poll() failed for %s: %s (%d)\n",
222 				       ctl->name, strerror(errno), errno);
223 			return -1;
224 		}
225 		/* Timeout */
226 		if (err == 0)
227 			return 0;
228 
229 		err = snd_ctl_poll_descriptors_revents(ctl->card->handle,
230 						       &(ctl->card->pollfd),
231 						       1, &revents);
232 		if (err < 0) {
233 			ksft_print_msg("snd_ctl_poll_descriptors_revents() failed for %s: %d\n",
234 				       ctl->name, err);
235 			return err;
236 		}
237 		if (revents & POLLERR) {
238 			ksft_print_msg("snd_ctl_poll_descriptors_revents() reported POLLERR for %s\n",
239 				       ctl->name);
240 			return -1;
241 		}
242 		/* No read events */
243 		if (!(revents & POLLIN)) {
244 			ksft_print_msg("No POLLIN\n");
245 			continue;
246 		}
247 
248 		err = snd_ctl_read(ctl->card->handle, event);
249 		if (err < 0) {
250 			ksft_print_msg("snd_ctl_read() failed for %s: %d\n",
251 			       ctl->name, err);
252 			return err;
253 		}
254 
255 		if (snd_ctl_event_get_type(event) != SND_CTL_EVENT_ELEM)
256 			continue;
257 
258 		/* The ID returned from the event is 1 less than numid */
259 		mask = snd_ctl_event_elem_get_mask(event);
260 		ev_id = snd_ctl_event_elem_get_numid(event);
261 		if (ev_id != snd_ctl_elem_info_get_numid(ctl->info)) {
262 			ksft_print_msg("Event for unexpected ctl %s\n",
263 				       snd_ctl_event_elem_get_name(event));
264 			continue;
265 		}
266 
267 		if ((mask & SND_CTL_EVENT_MASK_REMOVE) == SND_CTL_EVENT_MASK_REMOVE) {
268 			ksft_print_msg("Removal event for %s\n",
269 				       ctl->name);
270 			return -1;
271 		}
272 	} while ((mask & SND_CTL_EVENT_MASK_VALUE) != SND_CTL_EVENT_MASK_VALUE);
273 
274 	return 1;
275 }
276 
277 static bool ctl_value_index_valid(struct ctl_data *ctl,
278 				  snd_ctl_elem_value_t *val,
279 				  int index)
280 {
281 	long int_val;
282 	long long int64_val;
283 
284 	switch (snd_ctl_elem_info_get_type(ctl->info)) {
285 	case SND_CTL_ELEM_TYPE_NONE:
286 		ksft_print_msg("%s.%d Invalid control type NONE\n",
287 			       ctl->name, index);
288 		return false;
289 
290 	case SND_CTL_ELEM_TYPE_BOOLEAN:
291 		int_val = snd_ctl_elem_value_get_boolean(val, index);
292 		switch (int_val) {
293 		case 0:
294 		case 1:
295 			break;
296 		default:
297 			ksft_print_msg("%s.%d Invalid boolean value %ld\n",
298 				       ctl->name, index, int_val);
299 			return false;
300 		}
301 		break;
302 
303 	case SND_CTL_ELEM_TYPE_INTEGER:
304 		int_val = snd_ctl_elem_value_get_integer(val, index);
305 
306 		if (int_val < snd_ctl_elem_info_get_min(ctl->info)) {
307 			ksft_print_msg("%s.%d value %ld less than minimum %ld\n",
308 				       ctl->name, index, int_val,
309 				       snd_ctl_elem_info_get_min(ctl->info));
310 			return false;
311 		}
312 
313 		if (int_val > snd_ctl_elem_info_get_max(ctl->info)) {
314 			ksft_print_msg("%s.%d value %ld more than maximum %ld\n",
315 				       ctl->name, index, int_val,
316 				       snd_ctl_elem_info_get_max(ctl->info));
317 			return false;
318 		}
319 
320 		/* Only check step size if there is one and we're in bounds */
321 		if (snd_ctl_elem_info_get_step(ctl->info) &&
322 		    (int_val - snd_ctl_elem_info_get_min(ctl->info) %
323 		     snd_ctl_elem_info_get_step(ctl->info))) {
324 			ksft_print_msg("%s.%d value %ld invalid for step %ld minimum %ld\n",
325 				       ctl->name, index, int_val,
326 				       snd_ctl_elem_info_get_step(ctl->info),
327 				       snd_ctl_elem_info_get_min(ctl->info));
328 			return false;
329 		}
330 		break;
331 
332 	case SND_CTL_ELEM_TYPE_INTEGER64:
333 		int64_val = snd_ctl_elem_value_get_integer64(val, index);
334 
335 		if (int64_val < snd_ctl_elem_info_get_min64(ctl->info)) {
336 			ksft_print_msg("%s.%d value %lld less than minimum %lld\n",
337 				       ctl->name, index, int64_val,
338 				       snd_ctl_elem_info_get_min64(ctl->info));
339 			return false;
340 		}
341 
342 		if (int64_val > snd_ctl_elem_info_get_max64(ctl->info)) {
343 			ksft_print_msg("%s.%d value %lld more than maximum %lld\n",
344 				       ctl->name, index, int64_val,
345 				       snd_ctl_elem_info_get_max64(ctl->info));
346 			return false;
347 		}
348 
349 		/* Only check step size if there is one and we're in bounds */
350 		if (snd_ctl_elem_info_get_step64(ctl->info) &&
351 		    (int64_val - snd_ctl_elem_info_get_min64(ctl->info)) %
352 		    snd_ctl_elem_info_get_step64(ctl->info)) {
353 			ksft_print_msg("%s.%d value %lld invalid for step %lld minimum %lld\n",
354 				       ctl->name, index, int64_val,
355 				       snd_ctl_elem_info_get_step64(ctl->info),
356 				       snd_ctl_elem_info_get_min64(ctl->info));
357 			return false;
358 		}
359 		break;
360 
361 	case SND_CTL_ELEM_TYPE_ENUMERATED:
362 		int_val = snd_ctl_elem_value_get_enumerated(val, index);
363 
364 		if (int_val < 0) {
365 			ksft_print_msg("%s.%d negative value %ld for enumeration\n",
366 				       ctl->name, index, int_val);
367 			return false;
368 		}
369 
370 		if (int_val >= snd_ctl_elem_info_get_items(ctl->info)) {
371 			ksft_print_msg("%s.%d value %ld more than item count %u\n",
372 				       ctl->name, index, int_val,
373 				       snd_ctl_elem_info_get_items(ctl->info));
374 			return false;
375 		}
376 		break;
377 
378 	default:
379 		/* No tests for other types */
380 		break;
381 	}
382 
383 	return true;
384 }
385 
386 /*
387  * Check that the provided value meets the constraints for the
388  * provided control.
389  */
390 static bool ctl_value_valid(struct ctl_data *ctl, snd_ctl_elem_value_t *val)
391 {
392 	int i;
393 	bool valid = true;
394 
395 	for (i = 0; i < snd_ctl_elem_info_get_count(ctl->info); i++)
396 		if (!ctl_value_index_valid(ctl, val, i))
397 			valid = false;
398 
399 	return valid;
400 }
401 
402 /*
403  * Check that we can read the default value and it is valid. Write
404  * tests use the read value to restore the default.
405  */
406 static void test_ctl_get_value(struct ctl_data *ctl)
407 {
408 	int err;
409 
410 	/* If the control is turned off let's be polite */
411 	if (snd_ctl_elem_info_is_inactive(ctl->info)) {
412 		ksft_print_msg("%s is inactive\n", ctl->name);
413 		ksft_test_result_skip("get_value.%s.%d\n",
414 				      ctl->card->card_name, ctl->elem);
415 		return;
416 	}
417 
418 	/* Can't test reading on an unreadable control */
419 	if (!snd_ctl_elem_info_is_readable(ctl->info)) {
420 		ksft_print_msg("%s is not readable\n", ctl->name);
421 		ksft_test_result_skip("get_value.%s.%d\n",
422 				      ctl->card->card_name, ctl->elem);
423 		return;
424 	}
425 
426 	err = snd_ctl_elem_read(ctl->card->handle, ctl->def_val);
427 	if (err < 0) {
428 		ksft_print_msg("snd_ctl_elem_read() failed: %s\n",
429 			       snd_strerror(err));
430 		goto out;
431 	}
432 
433 	if (!ctl_value_valid(ctl, ctl->def_val))
434 		err = -EINVAL;
435 
436 out:
437 	ksft_test_result(err >= 0, "get_value.%s.%d\n",
438 			 ctl->card->card_name, ctl->elem);
439 }
440 
441 static bool strend(const char *haystack, const char *needle)
442 {
443 	size_t haystack_len = strlen(haystack);
444 	size_t needle_len = strlen(needle);
445 
446 	if (needle_len > haystack_len)
447 		return false;
448 	return strcmp(haystack + haystack_len - needle_len, needle) == 0;
449 }
450 
451 static void test_ctl_name(struct ctl_data *ctl)
452 {
453 	bool name_ok = true;
454 
455 	ksft_print_msg("%s.%d %s\n", ctl->card->card_name, ctl->elem,
456 		       ctl->name);
457 
458 	/* Only boolean controls should end in Switch */
459 	if (strend(ctl->name, " Switch")) {
460 		if (snd_ctl_elem_info_get_type(ctl->info) != SND_CTL_ELEM_TYPE_BOOLEAN) {
461 			ksft_print_msg("%d.%d %s ends in Switch but is not boolean\n",
462 				       ctl->card->card, ctl->elem, ctl->name);
463 			name_ok = false;
464 		}
465 	}
466 
467 	/* Writeable boolean controls should end in Switch */
468 	if (snd_ctl_elem_info_get_type(ctl->info) == SND_CTL_ELEM_TYPE_BOOLEAN &&
469 	    snd_ctl_elem_info_is_writable(ctl->info)) {
470 		if (!strend(ctl->name, " Switch")) {
471 			ksft_print_msg("%d.%d %s is a writeable boolean but not a Switch\n",
472 				       ctl->card->card, ctl->elem, ctl->name);
473 			name_ok = false;
474 		}
475 	}
476 
477 	ksft_test_result(name_ok, "name.%s.%d\n",
478 			 ctl->card->card_name, ctl->elem);
479 }
480 
481 static void show_values(struct ctl_data *ctl, snd_ctl_elem_value_t *orig_val,
482 			snd_ctl_elem_value_t *read_val)
483 {
484 	long long orig_int, read_int;
485 	int i;
486 
487 	for (i = 0; i < snd_ctl_elem_info_get_count(ctl->info); i++) {
488 		switch (snd_ctl_elem_info_get_type(ctl->info)) {
489 		case SND_CTL_ELEM_TYPE_BOOLEAN:
490 			orig_int = snd_ctl_elem_value_get_boolean(orig_val, i);
491 			read_int = snd_ctl_elem_value_get_boolean(read_val, i);
492 			break;
493 
494 		case SND_CTL_ELEM_TYPE_INTEGER:
495 			orig_int = snd_ctl_elem_value_get_integer(orig_val, i);
496 			read_int = snd_ctl_elem_value_get_integer(read_val, i);
497 			break;
498 
499 		case SND_CTL_ELEM_TYPE_INTEGER64:
500 			orig_int = snd_ctl_elem_value_get_integer64(orig_val,
501 								    i);
502 			read_int = snd_ctl_elem_value_get_integer64(read_val,
503 								    i);
504 			break;
505 
506 		case SND_CTL_ELEM_TYPE_ENUMERATED:
507 			orig_int = snd_ctl_elem_value_get_enumerated(orig_val,
508 								     i);
509 			read_int = snd_ctl_elem_value_get_enumerated(read_val,
510 								     i);
511 			break;
512 
513 		default:
514 			return;
515 		}
516 
517 		ksft_print_msg("%s.%d orig %lld read %lld, is_volatile %d\n",
518 			       ctl->name, i, orig_int, read_int,
519 			       snd_ctl_elem_info_is_volatile(ctl->info));
520 	}
521 }
522 
523 static bool show_mismatch(struct ctl_data *ctl, int index,
524 			  snd_ctl_elem_value_t *read_val,
525 			  snd_ctl_elem_value_t *expected_val)
526 {
527 	long long expected_int, read_int;
528 
529 	/*
530 	 * We factor out the code to compare values representable as
531 	 * integers, ensure that check doesn't log otherwise.
532 	 */
533 	expected_int = 0;
534 	read_int = 0;
535 
536 	switch (snd_ctl_elem_info_get_type(ctl->info)) {
537 	case SND_CTL_ELEM_TYPE_BOOLEAN:
538 		expected_int = snd_ctl_elem_value_get_boolean(expected_val,
539 							      index);
540 		read_int = snd_ctl_elem_value_get_boolean(read_val, index);
541 		break;
542 
543 	case SND_CTL_ELEM_TYPE_INTEGER:
544 		expected_int = snd_ctl_elem_value_get_integer(expected_val,
545 							      index);
546 		read_int = snd_ctl_elem_value_get_integer(read_val, index);
547 		break;
548 
549 	case SND_CTL_ELEM_TYPE_INTEGER64:
550 		expected_int = snd_ctl_elem_value_get_integer64(expected_val,
551 								index);
552 		read_int = snd_ctl_elem_value_get_integer64(read_val,
553 							    index);
554 		break;
555 
556 	case SND_CTL_ELEM_TYPE_ENUMERATED:
557 		expected_int = snd_ctl_elem_value_get_enumerated(expected_val,
558 								 index);
559 		read_int = snd_ctl_elem_value_get_enumerated(read_val,
560 							     index);
561 		break;
562 
563 	default:
564 		break;
565 	}
566 
567 	if (expected_int != read_int) {
568 		/*
569 		 * NOTE: The volatile attribute means that the hardware
570 		 * can voluntarily change the state of control element
571 		 * independent of any operation by software.
572 		 */
573 		bool is_volatile = snd_ctl_elem_info_is_volatile(ctl->info);
574 		ksft_print_msg("%s.%d expected %lld but read %lld, is_volatile %d\n",
575 			       ctl->name, index, expected_int, read_int, is_volatile);
576 		return !is_volatile;
577 	} else {
578 		return false;
579 	}
580 }
581 
582 /*
583  * Write a value then if possible verify that we get the expected
584  * result.  An optional expected value can be provided if we expect
585  * the write to fail, for verifying that invalid writes don't corrupt
586  * anything.
587  */
588 static int write_and_verify(struct ctl_data *ctl,
589 			    snd_ctl_elem_value_t *write_val,
590 			    snd_ctl_elem_value_t *expected_val)
591 {
592 	int err, i;
593 	bool error_expected, mismatch_shown;
594 	snd_ctl_elem_value_t *initial_val, *read_val, *w_val;
595 	snd_ctl_elem_value_alloca(&initial_val);
596 	snd_ctl_elem_value_alloca(&read_val);
597 	snd_ctl_elem_value_alloca(&w_val);
598 
599 	/*
600 	 * We need to copy the write value since writing can modify
601 	 * the value which causes surprises, and allocate an expected
602 	 * value if we expect to read back what we wrote.
603 	 */
604 	snd_ctl_elem_value_copy(w_val, write_val);
605 	if (expected_val) {
606 		error_expected = true;
607 	} else {
608 		error_expected = false;
609 		snd_ctl_elem_value_alloca(&expected_val);
610 		snd_ctl_elem_value_copy(expected_val, write_val);
611 	}
612 
613 	/* Store the value before we write */
614 	if (snd_ctl_elem_info_is_readable(ctl->info)) {
615 		snd_ctl_elem_value_set_id(initial_val, ctl->id);
616 
617 		err = snd_ctl_elem_read(ctl->card->handle, initial_val);
618 		if (err < 0) {
619 			ksft_print_msg("snd_ctl_elem_read() failed: %s\n",
620 				       snd_strerror(err));
621 			return err;
622 		}
623 	}
624 
625 	/*
626 	 * Do the write, if we have an expected value ignore the error
627 	 * and carry on to validate the expected value.
628 	 */
629 	err = snd_ctl_elem_write(ctl->card->handle, w_val);
630 	if (err < 0 && !error_expected) {
631 		ksft_print_msg("snd_ctl_elem_write() failed: %s\n",
632 			       snd_strerror(err));
633 		return err;
634 	}
635 
636 	/* Can we do the verification part? */
637 	if (!snd_ctl_elem_info_is_readable(ctl->info))
638 		return err;
639 
640 	snd_ctl_elem_value_set_id(read_val, ctl->id);
641 
642 	err = snd_ctl_elem_read(ctl->card->handle, read_val);
643 	if (err < 0) {
644 		ksft_print_msg("snd_ctl_elem_read() failed: %s\n",
645 			       snd_strerror(err));
646 		return err;
647 	}
648 
649 	/*
650 	 * We can't verify any specific value for volatile controls
651 	 * but we should still check that whatever we read is a valid
652 	 * vale for the control.
653 	 */
654 	if (snd_ctl_elem_info_is_volatile(ctl->info)) {
655 		if (!ctl_value_valid(ctl, read_val)) {
656 			ksft_print_msg("Volatile control %s has invalid value\n",
657 				       ctl->name);
658 			return -EINVAL;
659 		}
660 
661 		return 0;
662 	}
663 
664 	/*
665 	 * Check for an event if the value changed, or confirm that
666 	 * there was none if it didn't.  We rely on the kernel
667 	 * generating the notification before it returns from the
668 	 * write, this is currently true, should that ever change this
669 	 * will most likely break and need updating.
670 	 */
671 	err = wait_for_event(ctl, 0);
672 	if (snd_ctl_elem_value_compare(initial_val, read_val)) {
673 		if (err < 1) {
674 			ksft_print_msg("No event generated for %s\n",
675 				       ctl->name);
676 			show_values(ctl, initial_val, read_val);
677 			ctl->event_missing++;
678 		}
679 	} else {
680 		if (err != 0) {
681 			ksft_print_msg("Spurious event generated for %s\n",
682 				       ctl->name);
683 			show_values(ctl, initial_val, read_val);
684 			ctl->event_spurious++;
685 		}
686 	}
687 
688 	/*
689 	 * Use the libray to compare values, if there's a mismatch
690 	 * carry on and try to provide a more useful diagnostic than
691 	 * just "mismatch".
692 	 */
693 	if (!snd_ctl_elem_value_compare(expected_val, read_val))
694 		return 0;
695 
696 	mismatch_shown = false;
697 	for (i = 0; i < snd_ctl_elem_info_get_count(ctl->info); i++)
698 		if (show_mismatch(ctl, i, read_val, expected_val))
699 			mismatch_shown = true;
700 
701 	if (!mismatch_shown)
702 		ksft_print_msg("%s read and written values differ\n",
703 			       ctl->name);
704 
705 	return -1;
706 }
707 
708 /*
709  * Make sure we can write the default value back to the control, this
710  * should validate that at least some write works.
711  */
712 static void test_ctl_write_default(struct ctl_data *ctl)
713 {
714 	int err;
715 
716 	/* If the control is turned off let's be polite */
717 	if (snd_ctl_elem_info_is_inactive(ctl->info)) {
718 		ksft_print_msg("%s is inactive\n", ctl->name);
719 		ksft_test_result_skip("write_default.%s.%d\n",
720 				      ctl->card->card_name, ctl->elem);
721 		return;
722 	}
723 
724 	if (!snd_ctl_elem_info_is_writable(ctl->info)) {
725 		ksft_print_msg("%s is not writeable\n", ctl->name);
726 		ksft_test_result_skip("write_default.%s.%d\n",
727 				      ctl->card->card_name, ctl->elem);
728 		return;
729 	}
730 
731 	/* No idea what the default was for unreadable controls */
732 	if (!snd_ctl_elem_info_is_readable(ctl->info)) {
733 		ksft_print_msg("%s couldn't read default\n", ctl->name);
734 		ksft_test_result_skip("write_default.%s.%d\n",
735 				      ctl->card->card_name, ctl->elem);
736 		return;
737 	}
738 
739 	err = write_and_verify(ctl, ctl->def_val, NULL);
740 
741 	ksft_test_result(err >= 0, "write_default.%s.%d\n",
742 			 ctl->card->card_name, ctl->elem);
743 }
744 
745 static bool test_ctl_write_valid_boolean(struct ctl_data *ctl)
746 {
747 	int err, i, j;
748 	bool fail = false;
749 	snd_ctl_elem_value_t *val;
750 	snd_ctl_elem_value_alloca(&val);
751 
752 	snd_ctl_elem_value_set_id(val, ctl->id);
753 
754 	for (i = 0; i < snd_ctl_elem_info_get_count(ctl->info); i++) {
755 		for (j = 0; j < 2; j++) {
756 			snd_ctl_elem_value_set_boolean(val, i, j);
757 			err = write_and_verify(ctl, val, NULL);
758 			if (err != 0)
759 				fail = true;
760 		}
761 	}
762 
763 	return !fail;
764 }
765 
766 static bool test_ctl_write_valid_integer(struct ctl_data *ctl)
767 {
768 	int err;
769 	int i;
770 	long j, step;
771 	bool fail = false;
772 	snd_ctl_elem_value_t *val;
773 	snd_ctl_elem_value_alloca(&val);
774 
775 	snd_ctl_elem_value_set_id(val, ctl->id);
776 
777 	step = snd_ctl_elem_info_get_step(ctl->info);
778 	if (!step)
779 		step = 1;
780 
781 	for (i = 0; i < snd_ctl_elem_info_get_count(ctl->info); i++) {
782 		for (j = snd_ctl_elem_info_get_min(ctl->info);
783 		     j <= snd_ctl_elem_info_get_max(ctl->info); j += step) {
784 
785 			snd_ctl_elem_value_set_integer(val, i, j);
786 			err = write_and_verify(ctl, val, NULL);
787 			if (err != 0)
788 				fail = true;
789 		}
790 	}
791 
792 
793 	return !fail;
794 }
795 
796 static bool test_ctl_write_valid_integer64(struct ctl_data *ctl)
797 {
798 	int err, i;
799 	long long j, step;
800 	bool fail = false;
801 	snd_ctl_elem_value_t *val;
802 	snd_ctl_elem_value_alloca(&val);
803 
804 	snd_ctl_elem_value_set_id(val, ctl->id);
805 
806 	step = snd_ctl_elem_info_get_step64(ctl->info);
807 	if (!step)
808 		step = 1;
809 
810 	for (i = 0; i < snd_ctl_elem_info_get_count(ctl->info); i++) {
811 		for (j = snd_ctl_elem_info_get_min64(ctl->info);
812 		     j <= snd_ctl_elem_info_get_max64(ctl->info); j += step) {
813 
814 			snd_ctl_elem_value_set_integer64(val, i, j);
815 			err = write_and_verify(ctl, val, NULL);
816 			if (err != 0)
817 				fail = true;
818 		}
819 	}
820 
821 	return !fail;
822 }
823 
824 static bool test_ctl_write_valid_enumerated(struct ctl_data *ctl)
825 {
826 	int err, i, j;
827 	bool fail = false;
828 	snd_ctl_elem_value_t *val;
829 	snd_ctl_elem_value_alloca(&val);
830 
831 	snd_ctl_elem_value_set_id(val, ctl->id);
832 
833 	for (i = 0; i < snd_ctl_elem_info_get_count(ctl->info); i++) {
834 		for (j = 0; j < snd_ctl_elem_info_get_items(ctl->info); j++) {
835 			snd_ctl_elem_value_set_enumerated(val, i, j);
836 			err = write_and_verify(ctl, val, NULL);
837 			if (err != 0)
838 				fail = true;
839 		}
840 	}
841 
842 	return !fail;
843 }
844 
845 static void test_ctl_write_valid(struct ctl_data *ctl)
846 {
847 	bool pass;
848 
849 	/* If the control is turned off let's be polite */
850 	if (snd_ctl_elem_info_is_inactive(ctl->info)) {
851 		ksft_print_msg("%s is inactive\n", ctl->name);
852 		ksft_test_result_skip("write_valid.%s.%d\n",
853 				      ctl->card->card_name, ctl->elem);
854 		return;
855 	}
856 
857 	if (!snd_ctl_elem_info_is_writable(ctl->info)) {
858 		ksft_print_msg("%s is not writeable\n", ctl->name);
859 		ksft_test_result_skip("write_valid.%s.%d\n",
860 				      ctl->card->card_name, ctl->elem);
861 		return;
862 	}
863 
864 	switch (snd_ctl_elem_info_get_type(ctl->info)) {
865 	case SND_CTL_ELEM_TYPE_BOOLEAN:
866 		pass = test_ctl_write_valid_boolean(ctl);
867 		break;
868 
869 	case SND_CTL_ELEM_TYPE_INTEGER:
870 		pass = test_ctl_write_valid_integer(ctl);
871 		break;
872 
873 	case SND_CTL_ELEM_TYPE_INTEGER64:
874 		pass = test_ctl_write_valid_integer64(ctl);
875 		break;
876 
877 	case SND_CTL_ELEM_TYPE_ENUMERATED:
878 		pass = test_ctl_write_valid_enumerated(ctl);
879 		break;
880 
881 	default:
882 		/* No tests for this yet */
883 		ksft_test_result_skip("write_valid.%s.%d\n",
884 				      ctl->card->card_name, ctl->elem);
885 		return;
886 	}
887 
888 	/* Restore the default value to minimise disruption */
889 	write_and_verify(ctl, ctl->def_val, NULL);
890 
891 	ksft_test_result(pass, "write_valid.%s.%d\n",
892 			 ctl->card->card_name, ctl->elem);
893 }
894 
895 static bool test_ctl_write_invalid_value(struct ctl_data *ctl,
896 					 snd_ctl_elem_value_t *val)
897 {
898 	int err;
899 
900 	/* Ideally this will fail... */
901 	err = snd_ctl_elem_write(ctl->card->handle, val);
902 	if (err < 0)
903 		return false;
904 
905 	/* ...but some devices will clamp to an in range value */
906 	err = snd_ctl_elem_read(ctl->card->handle, val);
907 	if (err < 0) {
908 		ksft_print_msg("%s failed to read: %s\n",
909 			       ctl->name, snd_strerror(err));
910 		return true;
911 	}
912 
913 	return !ctl_value_valid(ctl, val);
914 }
915 
916 static bool test_ctl_write_invalid_boolean(struct ctl_data *ctl)
917 {
918 	int i;
919 	bool fail = false;
920 	snd_ctl_elem_value_t *val;
921 	snd_ctl_elem_value_alloca(&val);
922 
923 	for (i = 0; i < snd_ctl_elem_info_get_count(ctl->info); i++) {
924 		snd_ctl_elem_value_copy(val, ctl->def_val);
925 		snd_ctl_elem_value_set_boolean(val, i, 2);
926 
927 		if (test_ctl_write_invalid_value(ctl, val))
928 			fail = true;
929 	}
930 
931 	return !fail;
932 }
933 
934 static bool test_ctl_write_invalid_integer(struct ctl_data *ctl)
935 {
936 	int i;
937 	bool fail = false;
938 	snd_ctl_elem_value_t *val;
939 	snd_ctl_elem_value_alloca(&val);
940 
941 	for (i = 0; i < snd_ctl_elem_info_get_count(ctl->info); i++) {
942 		if (snd_ctl_elem_info_get_min(ctl->info) != LONG_MIN) {
943 			/* Just under range */
944 			snd_ctl_elem_value_copy(val, ctl->def_val);
945 			snd_ctl_elem_value_set_integer(val, i,
946 			       snd_ctl_elem_info_get_min(ctl->info) - 1);
947 
948 			if (test_ctl_write_invalid_value(ctl, val))
949 				fail = true;
950 
951 			/* Minimum representable value */
952 			snd_ctl_elem_value_copy(val, ctl->def_val);
953 			snd_ctl_elem_value_set_integer(val, i, LONG_MIN);
954 
955 			if (test_ctl_write_invalid_value(ctl, val))
956 				fail = true;
957 		}
958 
959 		if (snd_ctl_elem_info_get_max(ctl->info) != LONG_MAX) {
960 			/* Just over range */
961 			snd_ctl_elem_value_copy(val, ctl->def_val);
962 			snd_ctl_elem_value_set_integer(val, i,
963 			       snd_ctl_elem_info_get_max(ctl->info) + 1);
964 
965 			if (test_ctl_write_invalid_value(ctl, val))
966 				fail = true;
967 
968 			/* Maximum representable value */
969 			snd_ctl_elem_value_copy(val, ctl->def_val);
970 			snd_ctl_elem_value_set_integer(val, i, LONG_MAX);
971 
972 			if (test_ctl_write_invalid_value(ctl, val))
973 				fail = true;
974 		}
975 	}
976 
977 	return !fail;
978 }
979 
980 static bool test_ctl_write_invalid_integer64(struct ctl_data *ctl)
981 {
982 	int i;
983 	bool fail = false;
984 	snd_ctl_elem_value_t *val;
985 	snd_ctl_elem_value_alloca(&val);
986 
987 	for (i = 0; i < snd_ctl_elem_info_get_count(ctl->info); i++) {
988 		if (snd_ctl_elem_info_get_min64(ctl->info) != LLONG_MIN) {
989 			/* Just under range */
990 			snd_ctl_elem_value_copy(val, ctl->def_val);
991 			snd_ctl_elem_value_set_integer64(val, i,
992 				snd_ctl_elem_info_get_min64(ctl->info) - 1);
993 
994 			if (test_ctl_write_invalid_value(ctl, val))
995 				fail = true;
996 
997 			/* Minimum representable value */
998 			snd_ctl_elem_value_copy(val, ctl->def_val);
999 			snd_ctl_elem_value_set_integer64(val, i, LLONG_MIN);
1000 
1001 			if (test_ctl_write_invalid_value(ctl, val))
1002 				fail = true;
1003 		}
1004 
1005 		if (snd_ctl_elem_info_get_max64(ctl->info) != LLONG_MAX) {
1006 			/* Just over range */
1007 			snd_ctl_elem_value_copy(val, ctl->def_val);
1008 			snd_ctl_elem_value_set_integer64(val, i,
1009 				snd_ctl_elem_info_get_max64(ctl->info) + 1);
1010 
1011 			if (test_ctl_write_invalid_value(ctl, val))
1012 				fail = true;
1013 
1014 			/* Maximum representable value */
1015 			snd_ctl_elem_value_copy(val, ctl->def_val);
1016 			snd_ctl_elem_value_set_integer64(val, i, LLONG_MAX);
1017 
1018 			if (test_ctl_write_invalid_value(ctl, val))
1019 				fail = true;
1020 		}
1021 	}
1022 
1023 	return !fail;
1024 }
1025 
1026 static bool test_ctl_write_invalid_enumerated(struct ctl_data *ctl)
1027 {
1028 	int i;
1029 	bool fail = false;
1030 	snd_ctl_elem_value_t *val;
1031 	snd_ctl_elem_value_alloca(&val);
1032 
1033 	snd_ctl_elem_value_set_id(val, ctl->id);
1034 
1035 	for (i = 0; i < snd_ctl_elem_info_get_count(ctl->info); i++) {
1036 		/* One beyond maximum */
1037 		snd_ctl_elem_value_copy(val, ctl->def_val);
1038 		snd_ctl_elem_value_set_enumerated(val, i,
1039 				  snd_ctl_elem_info_get_items(ctl->info));
1040 
1041 		if (test_ctl_write_invalid_value(ctl, val))
1042 			fail = true;
1043 
1044 		/* Maximum representable value */
1045 		snd_ctl_elem_value_copy(val, ctl->def_val);
1046 		snd_ctl_elem_value_set_enumerated(val, i, UINT_MAX);
1047 
1048 		if (test_ctl_write_invalid_value(ctl, val))
1049 			fail = true;
1050 
1051 	}
1052 
1053 	return !fail;
1054 }
1055 
1056 
1057 static void test_ctl_write_invalid(struct ctl_data *ctl)
1058 {
1059 	bool pass;
1060 
1061 	/* If the control is turned off let's be polite */
1062 	if (snd_ctl_elem_info_is_inactive(ctl->info)) {
1063 		ksft_print_msg("%s is inactive\n", ctl->name);
1064 		ksft_test_result_skip("write_invalid.%s.%d\n",
1065 				      ctl->card->card_name, ctl->elem);
1066 		return;
1067 	}
1068 
1069 	if (!snd_ctl_elem_info_is_writable(ctl->info)) {
1070 		ksft_print_msg("%s is not writeable\n", ctl->name);
1071 		ksft_test_result_skip("write_invalid.%s.%d\n",
1072 				      ctl->card->card_name, ctl->elem);
1073 		return;
1074 	}
1075 
1076 	switch (snd_ctl_elem_info_get_type(ctl->info)) {
1077 	case SND_CTL_ELEM_TYPE_BOOLEAN:
1078 		pass = test_ctl_write_invalid_boolean(ctl);
1079 		break;
1080 
1081 	case SND_CTL_ELEM_TYPE_INTEGER:
1082 		pass = test_ctl_write_invalid_integer(ctl);
1083 		break;
1084 
1085 	case SND_CTL_ELEM_TYPE_INTEGER64:
1086 		pass = test_ctl_write_invalid_integer64(ctl);
1087 		break;
1088 
1089 	case SND_CTL_ELEM_TYPE_ENUMERATED:
1090 		pass = test_ctl_write_invalid_enumerated(ctl);
1091 		break;
1092 
1093 	default:
1094 		/* No tests for this yet */
1095 		ksft_test_result_skip("write_invalid.%s.%d\n",
1096 				      ctl->card->card_name, ctl->elem);
1097 		return;
1098 	}
1099 
1100 	/* Restore the default value to minimise disruption */
1101 	write_and_verify(ctl, ctl->def_val, NULL);
1102 
1103 	ksft_test_result(pass, "write_invalid.%s.%d\n",
1104 			 ctl->card->card_name, ctl->elem);
1105 }
1106 
1107 static void test_ctl_event_missing(struct ctl_data *ctl)
1108 {
1109 	ksft_test_result(!ctl->event_missing, "event_missing.%s.%d\n",
1110 			 ctl->card->card_name, ctl->elem);
1111 }
1112 
1113 static void test_ctl_event_spurious(struct ctl_data *ctl)
1114 {
1115 	ksft_test_result(!ctl->event_spurious, "event_spurious.%s.%d\n",
1116 			 ctl->card->card_name, ctl->elem);
1117 }
1118 
1119 int main(void)
1120 {
1121 	struct ctl_data *ctl;
1122 
1123 	ksft_print_header();
1124 
1125 	find_controls();
1126 
1127 	ksft_set_plan(num_controls * TESTS_PER_CONTROL);
1128 
1129 	for (ctl = ctl_list; ctl != NULL; ctl = ctl->next) {
1130 		/*
1131 		 * Must test get_value() before we write anything, the
1132 		 * test stores the default value for later cleanup.
1133 		 */
1134 		test_ctl_get_value(ctl);
1135 		test_ctl_name(ctl);
1136 		test_ctl_write_default(ctl);
1137 		test_ctl_write_valid(ctl);
1138 		test_ctl_write_invalid(ctl);
1139 		test_ctl_event_missing(ctl);
1140 		test_ctl_event_spurious(ctl);
1141 	}
1142 
1143 	ksft_exit_pass();
1144 
1145 	return 0;
1146 }
1147