Linux Audio

Check our new training course

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