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