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