xref: /linux/tools/testing/selftests/alsa/mixer-test.c (revision 34f7c6e7d4396090692a09789db231e12cb4762b)
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 6
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 show_mismatch(struct ctl_data *ctl, int index,
460 			  snd_ctl_elem_value_t *read_val,
461 			  snd_ctl_elem_value_t *expected_val)
462 {
463 	long long expected_int, read_int;
464 
465 	/*
466 	 * We factor out the code to compare values representable as
467 	 * integers, ensure that check doesn't log otherwise.
468 	 */
469 	expected_int = 0;
470 	read_int = 0;
471 
472 	switch (snd_ctl_elem_info_get_type(ctl->info)) {
473 	case SND_CTL_ELEM_TYPE_BOOLEAN:
474 		expected_int = snd_ctl_elem_value_get_boolean(expected_val,
475 							      index);
476 		read_int = snd_ctl_elem_value_get_boolean(read_val, index);
477 		break;
478 
479 	case SND_CTL_ELEM_TYPE_INTEGER:
480 		expected_int = snd_ctl_elem_value_get_integer(expected_val,
481 							      index);
482 		read_int = snd_ctl_elem_value_get_integer(read_val, index);
483 		break;
484 
485 	case SND_CTL_ELEM_TYPE_INTEGER64:
486 		expected_int = snd_ctl_elem_value_get_integer64(expected_val,
487 								index);
488 		read_int = snd_ctl_elem_value_get_integer64(read_val,
489 							    index);
490 		break;
491 
492 	case SND_CTL_ELEM_TYPE_ENUMERATED:
493 		expected_int = snd_ctl_elem_value_get_enumerated(expected_val,
494 								 index);
495 		read_int = snd_ctl_elem_value_get_enumerated(read_val,
496 							     index);
497 		break;
498 
499 	default:
500 		break;
501 	}
502 
503 	if (expected_int != read_int) {
504 		/*
505 		 * NOTE: The volatile attribute means that the hardware
506 		 * can voluntarily change the state of control element
507 		 * independent of any operation by software.
508 		 */
509 		bool is_volatile = snd_ctl_elem_info_is_volatile(ctl->info);
510 		ksft_print_msg("%s.%d expected %lld but read %lld, is_volatile %d\n",
511 			       ctl->name, index, expected_int, read_int, is_volatile);
512 		return !is_volatile;
513 	} else {
514 		return false;
515 	}
516 }
517 
518 /*
519  * Write a value then if possible verify that we get the expected
520  * result.  An optional expected value can be provided if we expect
521  * the write to fail, for verifying that invalid writes don't corrupt
522  * anything.
523  */
524 static int write_and_verify(struct ctl_data *ctl,
525 			    snd_ctl_elem_value_t *write_val,
526 			    snd_ctl_elem_value_t *expected_val)
527 {
528 	int err, i;
529 	bool error_expected, mismatch_shown;
530 	snd_ctl_elem_value_t *initial_val, *read_val, *w_val;
531 	snd_ctl_elem_value_alloca(&initial_val);
532 	snd_ctl_elem_value_alloca(&read_val);
533 	snd_ctl_elem_value_alloca(&w_val);
534 
535 	/*
536 	 * We need to copy the write value since writing can modify
537 	 * the value which causes surprises, and allocate an expected
538 	 * value if we expect to read back what we wrote.
539 	 */
540 	snd_ctl_elem_value_copy(w_val, write_val);
541 	if (expected_val) {
542 		error_expected = true;
543 	} else {
544 		error_expected = false;
545 		snd_ctl_elem_value_alloca(&expected_val);
546 		snd_ctl_elem_value_copy(expected_val, write_val);
547 	}
548 
549 	/* Store the value before we write */
550 	if (snd_ctl_elem_info_is_readable(ctl->info)) {
551 		snd_ctl_elem_value_set_id(initial_val, ctl->id);
552 
553 		err = snd_ctl_elem_read(ctl->card->handle, initial_val);
554 		if (err < 0) {
555 			ksft_print_msg("snd_ctl_elem_read() failed: %s\n",
556 				       snd_strerror(err));
557 			return err;
558 		}
559 	}
560 
561 	/*
562 	 * Do the write, if we have an expected value ignore the error
563 	 * and carry on to validate the expected value.
564 	 */
565 	err = snd_ctl_elem_write(ctl->card->handle, w_val);
566 	if (err < 0 && !error_expected) {
567 		ksft_print_msg("snd_ctl_elem_write() failed: %s\n",
568 			       snd_strerror(err));
569 		return err;
570 	}
571 
572 	/* Can we do the verification part? */
573 	if (!snd_ctl_elem_info_is_readable(ctl->info))
574 		return err;
575 
576 	snd_ctl_elem_value_set_id(read_val, ctl->id);
577 
578 	err = snd_ctl_elem_read(ctl->card->handle, read_val);
579 	if (err < 0) {
580 		ksft_print_msg("snd_ctl_elem_read() failed: %s\n",
581 			       snd_strerror(err));
582 		return err;
583 	}
584 
585 	/*
586 	 * Check for an event if the value changed, or confirm that
587 	 * there was none if it didn't.  We rely on the kernel
588 	 * generating the notification before it returns from the
589 	 * write, this is currently true, should that ever change this
590 	 * will most likely break and need updating.
591 	 */
592 	if (!snd_ctl_elem_info_is_volatile(ctl->info)) {
593 		err = wait_for_event(ctl, 0);
594 		if (snd_ctl_elem_value_compare(initial_val, read_val)) {
595 			if (err < 1) {
596 				ksft_print_msg("No event generated for %s\n",
597 					       ctl->name);
598 				ctl->event_missing++;
599 			}
600 		} else {
601 			if (err != 0) {
602 				ksft_print_msg("Spurious event generated for %s\n",
603 					       ctl->name);
604 				ctl->event_spurious++;
605 			}
606 		}
607 	}
608 
609 	/*
610 	 * Use the libray to compare values, if there's a mismatch
611 	 * carry on and try to provide a more useful diagnostic than
612 	 * just "mismatch".
613 	 */
614 	if (!snd_ctl_elem_value_compare(expected_val, read_val))
615 		return 0;
616 
617 	mismatch_shown = false;
618 	for (i = 0; i < snd_ctl_elem_info_get_count(ctl->info); i++)
619 		if (show_mismatch(ctl, i, read_val, expected_val))
620 			mismatch_shown = true;
621 
622 	if (!mismatch_shown)
623 		ksft_print_msg("%s read and written values differ\n",
624 			       ctl->name);
625 
626 	return -1;
627 }
628 
629 /*
630  * Make sure we can write the default value back to the control, this
631  * should validate that at least some write works.
632  */
633 static void test_ctl_write_default(struct ctl_data *ctl)
634 {
635 	int err;
636 
637 	/* If the control is turned off let's be polite */
638 	if (snd_ctl_elem_info_is_inactive(ctl->info)) {
639 		ksft_print_msg("%s is inactive\n", ctl->name);
640 		ksft_test_result_skip("write_default.%d.%d\n",
641 				      ctl->card->card, ctl->elem);
642 		return;
643 	}
644 
645 	if (!snd_ctl_elem_info_is_writable(ctl->info)) {
646 		ksft_print_msg("%s is not writeable\n", ctl->name);
647 		ksft_test_result_skip("write_default.%d.%d\n",
648 				      ctl->card->card, ctl->elem);
649 		return;
650 	}
651 
652 	/* No idea what the default was for unreadable controls */
653 	if (!snd_ctl_elem_info_is_readable(ctl->info)) {
654 		ksft_print_msg("%s couldn't read default\n", ctl->name);
655 		ksft_test_result_skip("write_default.%d.%d\n",
656 				      ctl->card->card, ctl->elem);
657 		return;
658 	}
659 
660 	err = write_and_verify(ctl, ctl->def_val, NULL);
661 
662 	ksft_test_result(err >= 0, "write_default.%d.%d\n",
663 			 ctl->card->card, ctl->elem);
664 }
665 
666 static bool test_ctl_write_valid_boolean(struct ctl_data *ctl)
667 {
668 	int err, i, j;
669 	bool fail = false;
670 	snd_ctl_elem_value_t *val;
671 	snd_ctl_elem_value_alloca(&val);
672 
673 	snd_ctl_elem_value_set_id(val, ctl->id);
674 
675 	for (i = 0; i < snd_ctl_elem_info_get_count(ctl->info); i++) {
676 		for (j = 0; j < 2; j++) {
677 			snd_ctl_elem_value_set_boolean(val, i, j);
678 			err = write_and_verify(ctl, val, NULL);
679 			if (err != 0)
680 				fail = true;
681 		}
682 	}
683 
684 	return !fail;
685 }
686 
687 static bool test_ctl_write_valid_integer(struct ctl_data *ctl)
688 {
689 	int err;
690 	int i;
691 	long j, step;
692 	bool fail = false;
693 	snd_ctl_elem_value_t *val;
694 	snd_ctl_elem_value_alloca(&val);
695 
696 	snd_ctl_elem_value_set_id(val, ctl->id);
697 
698 	step = snd_ctl_elem_info_get_step(ctl->info);
699 	if (!step)
700 		step = 1;
701 
702 	for (i = 0; i < snd_ctl_elem_info_get_count(ctl->info); i++) {
703 		for (j = snd_ctl_elem_info_get_min(ctl->info);
704 		     j <= snd_ctl_elem_info_get_max(ctl->info); j += step) {
705 
706 			snd_ctl_elem_value_set_integer(val, i, j);
707 			err = write_and_verify(ctl, val, NULL);
708 			if (err != 0)
709 				fail = true;
710 		}
711 	}
712 
713 
714 	return !fail;
715 }
716 
717 static bool test_ctl_write_valid_integer64(struct ctl_data *ctl)
718 {
719 	int err, i;
720 	long long j, step;
721 	bool fail = false;
722 	snd_ctl_elem_value_t *val;
723 	snd_ctl_elem_value_alloca(&val);
724 
725 	snd_ctl_elem_value_set_id(val, ctl->id);
726 
727 	step = snd_ctl_elem_info_get_step64(ctl->info);
728 	if (!step)
729 		step = 1;
730 
731 	for (i = 0; i < snd_ctl_elem_info_get_count(ctl->info); i++) {
732 		for (j = snd_ctl_elem_info_get_min64(ctl->info);
733 		     j <= snd_ctl_elem_info_get_max64(ctl->info); j += step) {
734 
735 			snd_ctl_elem_value_set_integer64(val, i, j);
736 			err = write_and_verify(ctl, val, NULL);
737 			if (err != 0)
738 				fail = true;
739 		}
740 	}
741 
742 	return !fail;
743 }
744 
745 static bool test_ctl_write_valid_enumerated(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 < snd_ctl_elem_info_get_items(ctl->info); j++) {
756 			snd_ctl_elem_value_set_enumerated(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 void test_ctl_write_valid(struct ctl_data *ctl)
767 {
768 	bool pass;
769 	int err;
770 
771 	/* If the control is turned off let's be polite */
772 	if (snd_ctl_elem_info_is_inactive(ctl->info)) {
773 		ksft_print_msg("%s is inactive\n", ctl->name);
774 		ksft_test_result_skip("write_valid.%d.%d\n",
775 				      ctl->card->card, ctl->elem);
776 		return;
777 	}
778 
779 	if (!snd_ctl_elem_info_is_writable(ctl->info)) {
780 		ksft_print_msg("%s is not writeable\n", ctl->name);
781 		ksft_test_result_skip("write_valid.%d.%d\n",
782 				      ctl->card->card, ctl->elem);
783 		return;
784 	}
785 
786 	switch (snd_ctl_elem_info_get_type(ctl->info)) {
787 	case SND_CTL_ELEM_TYPE_BOOLEAN:
788 		pass = test_ctl_write_valid_boolean(ctl);
789 		break;
790 
791 	case SND_CTL_ELEM_TYPE_INTEGER:
792 		pass = test_ctl_write_valid_integer(ctl);
793 		break;
794 
795 	case SND_CTL_ELEM_TYPE_INTEGER64:
796 		pass = test_ctl_write_valid_integer64(ctl);
797 		break;
798 
799 	case SND_CTL_ELEM_TYPE_ENUMERATED:
800 		pass = test_ctl_write_valid_enumerated(ctl);
801 		break;
802 
803 	default:
804 		/* No tests for this yet */
805 		ksft_test_result_skip("write_valid.%d.%d\n",
806 				      ctl->card->card, ctl->elem);
807 		return;
808 	}
809 
810 	/* Restore the default value to minimise disruption */
811 	err = write_and_verify(ctl, ctl->def_val, NULL);
812 	if (err < 0)
813 		pass = false;
814 
815 	ksft_test_result(pass, "write_valid.%d.%d\n",
816 			 ctl->card->card, ctl->elem);
817 }
818 
819 static bool test_ctl_write_invalid_value(struct ctl_data *ctl,
820 					 snd_ctl_elem_value_t *val)
821 {
822 	int err;
823 	long val_read;
824 
825 	/* Ideally this will fail... */
826 	err = snd_ctl_elem_write(ctl->card->handle, val);
827 	if (err < 0)
828 		return false;
829 
830 	/* ...but some devices will clamp to an in range value */
831 	err = snd_ctl_elem_read(ctl->card->handle, val);
832 	if (err < 0) {
833 		ksft_print_msg("%s failed to read: %s\n",
834 			       ctl->name, snd_strerror(err));
835 		return true;
836 	}
837 
838 	return !ctl_value_valid(ctl, val);
839 }
840 
841 static bool test_ctl_write_invalid_boolean(struct ctl_data *ctl)
842 {
843 	int err, i;
844 	long val_read;
845 	bool fail = false;
846 	snd_ctl_elem_value_t *val;
847 	snd_ctl_elem_value_alloca(&val);
848 
849 	for (i = 0; i < snd_ctl_elem_info_get_count(ctl->info); i++) {
850 		snd_ctl_elem_value_copy(val, ctl->def_val);
851 		snd_ctl_elem_value_set_boolean(val, i, 2);
852 
853 		if (test_ctl_write_invalid_value(ctl, val))
854 			fail = true;
855 	}
856 
857 	return !fail;
858 }
859 
860 static bool test_ctl_write_invalid_integer(struct ctl_data *ctl)
861 {
862 	int i;
863 	bool fail = false;
864 	snd_ctl_elem_value_t *val;
865 	snd_ctl_elem_value_alloca(&val);
866 
867 	for (i = 0; i < snd_ctl_elem_info_get_count(ctl->info); i++) {
868 		if (snd_ctl_elem_info_get_min(ctl->info) != LONG_MIN) {
869 			/* Just under range */
870 			snd_ctl_elem_value_copy(val, ctl->def_val);
871 			snd_ctl_elem_value_set_integer(val, i,
872 			       snd_ctl_elem_info_get_min(ctl->info) - 1);
873 
874 			if (test_ctl_write_invalid_value(ctl, val))
875 				fail = true;
876 
877 			/* Minimum representable value */
878 			snd_ctl_elem_value_copy(val, ctl->def_val);
879 			snd_ctl_elem_value_set_integer(val, i, LONG_MIN);
880 
881 			if (test_ctl_write_invalid_value(ctl, val))
882 				fail = true;
883 		}
884 
885 		if (snd_ctl_elem_info_get_max(ctl->info) != LONG_MAX) {
886 			/* Just over range */
887 			snd_ctl_elem_value_copy(val, ctl->def_val);
888 			snd_ctl_elem_value_set_integer(val, i,
889 			       snd_ctl_elem_info_get_max(ctl->info) + 1);
890 
891 			if (test_ctl_write_invalid_value(ctl, val))
892 				fail = true;
893 
894 			/* Maximum representable value */
895 			snd_ctl_elem_value_copy(val, ctl->def_val);
896 			snd_ctl_elem_value_set_integer(val, i, LONG_MAX);
897 
898 			if (test_ctl_write_invalid_value(ctl, val))
899 				fail = true;
900 		}
901 	}
902 
903 	return !fail;
904 }
905 
906 static bool test_ctl_write_invalid_integer64(struct ctl_data *ctl)
907 {
908 	int i;
909 	bool fail = false;
910 	snd_ctl_elem_value_t *val;
911 	snd_ctl_elem_value_alloca(&val);
912 
913 	for (i = 0; i < snd_ctl_elem_info_get_count(ctl->info); i++) {
914 		if (snd_ctl_elem_info_get_min64(ctl->info) != LLONG_MIN) {
915 			/* Just under range */
916 			snd_ctl_elem_value_copy(val, ctl->def_val);
917 			snd_ctl_elem_value_set_integer64(val, i,
918 				snd_ctl_elem_info_get_min64(ctl->info) - 1);
919 
920 			if (test_ctl_write_invalid_value(ctl, val))
921 				fail = true;
922 
923 			/* Minimum representable value */
924 			snd_ctl_elem_value_copy(val, ctl->def_val);
925 			snd_ctl_elem_value_set_integer64(val, i, LLONG_MIN);
926 
927 			if (test_ctl_write_invalid_value(ctl, val))
928 				fail = true;
929 		}
930 
931 		if (snd_ctl_elem_info_get_max64(ctl->info) != LLONG_MAX) {
932 			/* Just over range */
933 			snd_ctl_elem_value_copy(val, ctl->def_val);
934 			snd_ctl_elem_value_set_integer64(val, i,
935 				snd_ctl_elem_info_get_max64(ctl->info) + 1);
936 
937 			if (test_ctl_write_invalid_value(ctl, val))
938 				fail = true;
939 
940 			/* Maximum representable value */
941 			snd_ctl_elem_value_copy(val, ctl->def_val);
942 			snd_ctl_elem_value_set_integer64(val, i, LLONG_MAX);
943 
944 			if (test_ctl_write_invalid_value(ctl, val))
945 				fail = true;
946 		}
947 	}
948 
949 	return !fail;
950 }
951 
952 static bool test_ctl_write_invalid_enumerated(struct ctl_data *ctl)
953 {
954 	int err, i;
955 	unsigned int val_read;
956 	bool fail = false;
957 	snd_ctl_elem_value_t *val;
958 	snd_ctl_elem_value_alloca(&val);
959 
960 	snd_ctl_elem_value_set_id(val, ctl->id);
961 
962 	for (i = 0; i < snd_ctl_elem_info_get_count(ctl->info); i++) {
963 		/* One beyond maximum */
964 		snd_ctl_elem_value_copy(val, ctl->def_val);
965 		snd_ctl_elem_value_set_enumerated(val, i,
966 				  snd_ctl_elem_info_get_items(ctl->info));
967 
968 		if (test_ctl_write_invalid_value(ctl, val))
969 			fail = true;
970 
971 		/* Maximum representable value */
972 		snd_ctl_elem_value_copy(val, ctl->def_val);
973 		snd_ctl_elem_value_set_enumerated(val, i, UINT_MAX);
974 
975 		if (test_ctl_write_invalid_value(ctl, val))
976 			fail = true;
977 
978 	}
979 
980 	return !fail;
981 }
982 
983 
984 static void test_ctl_write_invalid(struct ctl_data *ctl)
985 {
986 	bool pass;
987 	int err;
988 
989 	/* If the control is turned off let's be polite */
990 	if (snd_ctl_elem_info_is_inactive(ctl->info)) {
991 		ksft_print_msg("%s is inactive\n", ctl->name);
992 		ksft_test_result_skip("write_invalid.%d.%d\n",
993 				      ctl->card->card, ctl->elem);
994 		return;
995 	}
996 
997 	if (!snd_ctl_elem_info_is_writable(ctl->info)) {
998 		ksft_print_msg("%s is not writeable\n", ctl->name);
999 		ksft_test_result_skip("write_invalid.%d.%d\n",
1000 				      ctl->card->card, ctl->elem);
1001 		return;
1002 	}
1003 
1004 	switch (snd_ctl_elem_info_get_type(ctl->info)) {
1005 	case SND_CTL_ELEM_TYPE_BOOLEAN:
1006 		pass = test_ctl_write_invalid_boolean(ctl);
1007 		break;
1008 
1009 	case SND_CTL_ELEM_TYPE_INTEGER:
1010 		pass = test_ctl_write_invalid_integer(ctl);
1011 		break;
1012 
1013 	case SND_CTL_ELEM_TYPE_INTEGER64:
1014 		pass = test_ctl_write_invalid_integer64(ctl);
1015 		break;
1016 
1017 	case SND_CTL_ELEM_TYPE_ENUMERATED:
1018 		pass = test_ctl_write_invalid_enumerated(ctl);
1019 		break;
1020 
1021 	default:
1022 		/* No tests for this yet */
1023 		ksft_test_result_skip("write_invalid.%d.%d\n",
1024 				      ctl->card->card, ctl->elem);
1025 		return;
1026 	}
1027 
1028 	/* Restore the default value to minimise disruption */
1029 	err = write_and_verify(ctl, ctl->def_val, NULL);
1030 	if (err < 0)
1031 		pass = false;
1032 
1033 	ksft_test_result(pass, "write_invalid.%d.%d\n",
1034 			 ctl->card->card, ctl->elem);
1035 }
1036 
1037 static void test_ctl_event_missing(struct ctl_data *ctl)
1038 {
1039 	ksft_test_result(!ctl->event_missing, "event_missing.%d.%d\n",
1040 			 ctl->card->card, ctl->elem);
1041 }
1042 
1043 static void test_ctl_event_spurious(struct ctl_data *ctl)
1044 {
1045 	ksft_test_result(!ctl->event_spurious, "event_spurious.%d.%d\n",
1046 			 ctl->card->card, ctl->elem);
1047 }
1048 
1049 int main(void)
1050 {
1051 	struct ctl_data *ctl;
1052 
1053 	ksft_print_header();
1054 
1055 	find_controls();
1056 
1057 	ksft_set_plan(num_controls * TESTS_PER_CONTROL);
1058 
1059 	for (ctl = ctl_list; ctl != NULL; ctl = ctl->next) {
1060 		/*
1061 		 * Must test get_value() before we write anything, the
1062 		 * test stores the default value for later cleanup.
1063 		 */
1064 		test_ctl_get_value(ctl);
1065 		test_ctl_write_default(ctl);
1066 		test_ctl_write_valid(ctl);
1067 		test_ctl_write_invalid(ctl);
1068 		test_ctl_event_missing(ctl);
1069 		test_ctl_event_spurious(ctl);
1070 	}
1071 
1072 	ksft_exit_pass();
1073 
1074 	return 0;
1075 }
1076