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 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 <string.h> 17 #include <getopt.h> 18 #include <stdarg.h> 19 #include <ctype.h> 20 #include <math.h> 21 #include <errno.h> 22 #include <assert.h> 23 #include <alsa/asoundlib.h> 24 #include <poll.h> 25 #include <stdint.h> 26 27 #include "../kselftest.h" 28 29 #define TESTS_PER_CONTROL 3 30 31 struct card_data { 32 snd_ctl_t *handle; 33 int card; 34 int num_ctls; 35 snd_ctl_elem_list_t *ctls; 36 struct card_data *next; 37 }; 38 39 struct ctl_data { 40 const char *name; 41 snd_ctl_elem_id_t *id; 42 snd_ctl_elem_info_t *info; 43 snd_ctl_elem_value_t *def_val; 44 int elem; 45 struct card_data *card; 46 struct ctl_data *next; 47 }; 48 49 static const char *alsa_config = 50 "ctl.hw {\n" 51 " @args [ CARD ]\n" 52 " @args.CARD.type string\n" 53 " type hw\n" 54 " card $CARD\n" 55 "}\n" 56 ; 57 58 int num_cards = 0; 59 int num_controls = 0; 60 struct card_data *card_list = NULL; 61 struct ctl_data *ctl_list = NULL; 62 63 #ifdef SND_LIB_VER 64 #if SND_LIB_VERSION >= SND_LIB_VER(1, 2, 6) 65 #define LIB_HAS_LOAD_STRING 66 #endif 67 #endif 68 69 #ifndef LIB_HAS_LOAD_STRING 70 int snd_config_load_string(snd_config_t **config, const char *s, size_t size) 71 { 72 snd_input_t *input; 73 snd_config_t *dst; 74 int err; 75 76 assert(config && s); 77 if (size == 0) 78 size = strlen(s); 79 err = snd_input_buffer_open(&input, s, size); 80 if (err < 0) 81 return err; 82 err = snd_config_top(&dst); 83 if (err < 0) { 84 snd_input_close(input); 85 return err; 86 } 87 err = snd_config_load(dst, input); 88 snd_input_close(input); 89 if (err < 0) { 90 snd_config_delete(dst); 91 return err; 92 } 93 *config = dst; 94 return 0; 95 } 96 #endif 97 98 void find_controls(void) 99 { 100 char name[32]; 101 int card, ctl, err; 102 struct card_data *card_data; 103 struct ctl_data *ctl_data; 104 snd_config_t *config; 105 106 card = -1; 107 if (snd_card_next(&card) < 0 || card < 0) 108 return; 109 110 err = snd_config_load_string(&config, alsa_config, strlen(alsa_config)); 111 if (err < 0) { 112 ksft_print_msg("Unable to parse custom alsa-lib configuration: %s\n", 113 snd_strerror(err)); 114 ksft_exit_fail(); 115 } 116 117 while (card >= 0) { 118 sprintf(name, "hw:%d", card); 119 120 card_data = malloc(sizeof(*card_data)); 121 if (!card_data) 122 ksft_exit_fail_msg("Out of memory\n"); 123 124 err = snd_ctl_open_lconf(&card_data->handle, name, 0, config); 125 if (err < 0) { 126 ksft_print_msg("Failed to get hctl for card %d: %s\n", 127 card, snd_strerror(err)); 128 goto next_card; 129 } 130 131 /* Count controls */ 132 snd_ctl_elem_list_malloc(&card_data->ctls); 133 snd_ctl_elem_list(card_data->handle, card_data->ctls); 134 card_data->num_ctls = snd_ctl_elem_list_get_count(card_data->ctls); 135 136 /* Enumerate control information */ 137 snd_ctl_elem_list_alloc_space(card_data->ctls, card_data->num_ctls); 138 snd_ctl_elem_list(card_data->handle, card_data->ctls); 139 140 card_data->card = num_cards++; 141 card_data->next = card_list; 142 card_list = card_data; 143 144 num_controls += card_data->num_ctls; 145 146 for (ctl = 0; ctl < card_data->num_ctls; ctl++) { 147 ctl_data = malloc(sizeof(*ctl_data)); 148 if (!ctl_data) 149 ksft_exit_fail_msg("Out of memory\n"); 150 151 ctl_data->card = card_data; 152 ctl_data->elem = ctl; 153 ctl_data->name = snd_ctl_elem_list_get_name(card_data->ctls, 154 ctl); 155 156 err = snd_ctl_elem_id_malloc(&ctl_data->id); 157 if (err < 0) 158 ksft_exit_fail_msg("Out of memory\n"); 159 160 err = snd_ctl_elem_info_malloc(&ctl_data->info); 161 if (err < 0) 162 ksft_exit_fail_msg("Out of memory\n"); 163 164 err = snd_ctl_elem_value_malloc(&ctl_data->def_val); 165 if (err < 0) 166 ksft_exit_fail_msg("Out of memory\n"); 167 168 snd_ctl_elem_list_get_id(card_data->ctls, ctl, 169 ctl_data->id); 170 snd_ctl_elem_info_set_id(ctl_data->info, ctl_data->id); 171 err = snd_ctl_elem_info(card_data->handle, 172 ctl_data->info); 173 if (err < 0) { 174 ksft_print_msg("%s getting info for %d\n", 175 snd_strerror(err), 176 ctl_data->name); 177 } 178 179 snd_ctl_elem_value_set_id(ctl_data->def_val, 180 ctl_data->id); 181 182 ctl_data->next = ctl_list; 183 ctl_list = ctl_data; 184 } 185 186 next_card: 187 if (snd_card_next(&card) < 0) { 188 ksft_print_msg("snd_card_next"); 189 break; 190 } 191 } 192 193 snd_config_delete(config); 194 } 195 196 bool ctl_value_index_valid(struct ctl_data *ctl, snd_ctl_elem_value_t *val, 197 int index) 198 { 199 long int_val; 200 long long int64_val; 201 202 switch (snd_ctl_elem_info_get_type(ctl->info)) { 203 case SND_CTL_ELEM_TYPE_NONE: 204 ksft_print_msg("%s.%d Invalid control type NONE\n", 205 ctl->name, index); 206 return false; 207 208 case SND_CTL_ELEM_TYPE_BOOLEAN: 209 int_val = snd_ctl_elem_value_get_boolean(val, index); 210 switch (int_val) { 211 case 0: 212 case 1: 213 break; 214 default: 215 ksft_print_msg("%s.%d Invalid boolean value %ld\n", 216 ctl->name, index, int_val); 217 return false; 218 } 219 break; 220 221 case SND_CTL_ELEM_TYPE_INTEGER: 222 int_val = snd_ctl_elem_value_get_integer(val, index); 223 224 if (int_val < snd_ctl_elem_info_get_min(ctl->info)) { 225 ksft_print_msg("%s.%d value %ld less than minimum %ld\n", 226 ctl->name, index, int_val, 227 snd_ctl_elem_info_get_min(ctl->info)); 228 return false; 229 } 230 231 if (int_val > snd_ctl_elem_info_get_max(ctl->info)) { 232 ksft_print_msg("%s.%d value %ld more than maximum %ld\n", 233 ctl->name, index, int_val, 234 snd_ctl_elem_info_get_max(ctl->info)); 235 return false; 236 } 237 238 /* Only check step size if there is one and we're in bounds */ 239 if (snd_ctl_elem_info_get_step(ctl->info) && 240 (int_val - snd_ctl_elem_info_get_min(ctl->info) % 241 snd_ctl_elem_info_get_step(ctl->info))) { 242 ksft_print_msg("%s.%d value %ld invalid for step %ld minimum %ld\n", 243 ctl->name, index, int_val, 244 snd_ctl_elem_info_get_step(ctl->info), 245 snd_ctl_elem_info_get_min(ctl->info)); 246 return false; 247 } 248 break; 249 250 case SND_CTL_ELEM_TYPE_INTEGER64: 251 int64_val = snd_ctl_elem_value_get_integer64(val, index); 252 253 if (int64_val < snd_ctl_elem_info_get_min64(ctl->info)) { 254 ksft_print_msg("%s.%d value %lld less than minimum %lld\n", 255 ctl->name, index, int64_val, 256 snd_ctl_elem_info_get_min64(ctl->info)); 257 return false; 258 } 259 260 if (int64_val > snd_ctl_elem_info_get_max64(ctl->info)) { 261 ksft_print_msg("%s.%d value %lld more than maximum %lld\n", 262 ctl->name, index, int64_val, 263 snd_ctl_elem_info_get_max(ctl->info)); 264 return false; 265 } 266 267 /* Only check step size if there is one and we're in bounds */ 268 if (snd_ctl_elem_info_get_step64(ctl->info) && 269 (int64_val - snd_ctl_elem_info_get_min64(ctl->info)) % 270 snd_ctl_elem_info_get_step64(ctl->info)) { 271 ksft_print_msg("%s.%d value %lld invalid for step %lld minimum %lld\n", 272 ctl->name, index, int64_val, 273 snd_ctl_elem_info_get_step64(ctl->info), 274 snd_ctl_elem_info_get_min64(ctl->info)); 275 return false; 276 } 277 break; 278 279 case SND_CTL_ELEM_TYPE_ENUMERATED: 280 int_val = snd_ctl_elem_value_get_enumerated(val, index); 281 282 if (int_val < 0) { 283 ksft_print_msg("%s.%d negative value %ld for enumeration\n", 284 ctl->name, index, int_val); 285 return false; 286 } 287 288 if (int_val >= snd_ctl_elem_info_get_items(ctl->info)) { 289 ksft_print_msg("%s.%d value %ld more than item count %ld\n", 290 ctl->name, index, int_val, 291 snd_ctl_elem_info_get_items(ctl->info)); 292 return false; 293 } 294 break; 295 296 default: 297 /* No tests for other types */ 298 break; 299 } 300 301 return true; 302 } 303 304 /* 305 * Check that the provided value meets the constraints for the 306 * provided control. 307 */ 308 bool ctl_value_valid(struct ctl_data *ctl, snd_ctl_elem_value_t *val) 309 { 310 int i; 311 bool valid = true; 312 313 for (i = 0; i < snd_ctl_elem_info_get_count(ctl->info); i++) 314 if (!ctl_value_index_valid(ctl, val, i)) 315 valid = false; 316 317 return valid; 318 } 319 320 /* 321 * Check that we can read the default value and it is valid. Write 322 * tests use the read value to restore the default. 323 */ 324 void test_ctl_get_value(struct ctl_data *ctl) 325 { 326 int err; 327 328 /* If the control is turned off let's be polite */ 329 if (snd_ctl_elem_info_is_inactive(ctl->info)) { 330 ksft_print_msg("%s is inactive\n", ctl->name); 331 ksft_test_result_skip("get_value.%d.%d\n", 332 ctl->card->card, ctl->elem); 333 return; 334 } 335 336 /* Can't test reading on an unreadable control */ 337 if (!snd_ctl_elem_info_is_readable(ctl->info)) { 338 ksft_print_msg("%s is not readable\n", ctl->name); 339 ksft_test_result_skip("get_value.%d.%d\n", 340 ctl->card->card, ctl->elem); 341 return; 342 } 343 344 err = snd_ctl_elem_read(ctl->card->handle, ctl->def_val); 345 if (err < 0) { 346 ksft_print_msg("snd_ctl_elem_read() failed: %s\n", 347 snd_strerror(err)); 348 goto out; 349 } 350 351 if (!ctl_value_valid(ctl, ctl->def_val)) 352 err = -EINVAL; 353 354 out: 355 ksft_test_result(err >= 0, "get_value.%d.%d\n", 356 ctl->card->card, ctl->elem); 357 } 358 359 bool show_mismatch(struct ctl_data *ctl, int index, 360 snd_ctl_elem_value_t *read_val, 361 snd_ctl_elem_value_t *expected_val) 362 { 363 long long expected_int, read_int; 364 365 /* 366 * We factor out the code to compare values representable as 367 * integers, ensure that check doesn't log otherwise. 368 */ 369 expected_int = 0; 370 read_int = 0; 371 372 switch (snd_ctl_elem_info_get_type(ctl->info)) { 373 case SND_CTL_ELEM_TYPE_BOOLEAN: 374 expected_int = snd_ctl_elem_value_get_boolean(expected_val, 375 index); 376 read_int = snd_ctl_elem_value_get_boolean(read_val, index); 377 break; 378 379 case SND_CTL_ELEM_TYPE_INTEGER: 380 expected_int = snd_ctl_elem_value_get_integer(expected_val, 381 index); 382 read_int = snd_ctl_elem_value_get_integer(read_val, index); 383 break; 384 385 case SND_CTL_ELEM_TYPE_INTEGER64: 386 expected_int = snd_ctl_elem_value_get_integer64(expected_val, 387 index); 388 read_int = snd_ctl_elem_value_get_integer64(read_val, 389 index); 390 break; 391 392 case SND_CTL_ELEM_TYPE_ENUMERATED: 393 expected_int = snd_ctl_elem_value_get_enumerated(expected_val, 394 index); 395 read_int = snd_ctl_elem_value_get_enumerated(read_val, 396 index); 397 break; 398 399 default: 400 break; 401 } 402 403 if (expected_int != read_int) { 404 /* 405 * NOTE: The volatile attribute means that the hardware 406 * can voluntarily change the state of control element 407 * independent of any operation by software. 408 */ 409 bool is_volatile = snd_ctl_elem_info_is_volatile(ctl->info); 410 ksft_print_msg("%s.%d expected %lld but read %lld, is_volatile %d\n", 411 ctl->name, index, expected_int, read_int, is_volatile); 412 return !is_volatile; 413 } else { 414 return false; 415 } 416 } 417 418 /* 419 * Write a value then if possible verify that we get the expected 420 * result. An optional expected value can be provided if we expect 421 * the write to fail, for verifying that invalid writes don't corrupt 422 * anything. 423 */ 424 int write_and_verify(struct ctl_data *ctl, 425 snd_ctl_elem_value_t *write_val, 426 snd_ctl_elem_value_t *expected_val) 427 { 428 int err, i; 429 bool error_expected, mismatch_shown; 430 snd_ctl_elem_value_t *read_val, *w_val; 431 snd_ctl_elem_value_alloca(&read_val); 432 snd_ctl_elem_value_alloca(&w_val); 433 434 /* 435 * We need to copy the write value since writing can modify 436 * the value which causes surprises, and allocate an expected 437 * value if we expect to read back what we wrote. 438 */ 439 snd_ctl_elem_value_copy(w_val, write_val); 440 if (expected_val) { 441 error_expected = true; 442 } else { 443 error_expected = false; 444 snd_ctl_elem_value_alloca(&expected_val); 445 snd_ctl_elem_value_copy(expected_val, write_val); 446 } 447 448 /* 449 * Do the write, if we have an expected value ignore the error 450 * and carry on to validate the expected value. 451 */ 452 err = snd_ctl_elem_write(ctl->card->handle, w_val); 453 if (err < 0 && !error_expected) { 454 ksft_print_msg("snd_ctl_elem_write() failed: %s\n", 455 snd_strerror(err)); 456 return err; 457 } 458 459 /* Can we do the verification part? */ 460 if (!snd_ctl_elem_info_is_readable(ctl->info)) 461 return err; 462 463 snd_ctl_elem_value_set_id(read_val, ctl->id); 464 465 err = snd_ctl_elem_read(ctl->card->handle, read_val); 466 if (err < 0) { 467 ksft_print_msg("snd_ctl_elem_read() failed: %s\n", 468 snd_strerror(err)); 469 return err; 470 } 471 472 /* 473 * Use the libray to compare values, if there's a mismatch 474 * carry on and try to provide a more useful diagnostic than 475 * just "mismatch". 476 */ 477 if (!snd_ctl_elem_value_compare(expected_val, read_val)) 478 return 0; 479 480 mismatch_shown = false; 481 for (i = 0; i < snd_ctl_elem_info_get_count(ctl->info); i++) 482 if (show_mismatch(ctl, i, read_val, expected_val)) 483 mismatch_shown = true; 484 485 if (!mismatch_shown) 486 ksft_print_msg("%s read and written values differ\n", 487 ctl->name); 488 489 return -1; 490 } 491 492 /* 493 * Make sure we can write the default value back to the control, this 494 * should validate that at least some write works. 495 */ 496 void test_ctl_write_default(struct ctl_data *ctl) 497 { 498 int err; 499 500 /* If the control is turned off let's be polite */ 501 if (snd_ctl_elem_info_is_inactive(ctl->info)) { 502 ksft_print_msg("%s is inactive\n", ctl->name); 503 ksft_test_result_skip("write_default.%d.%d\n", 504 ctl->card->card, ctl->elem); 505 return; 506 } 507 508 if (!snd_ctl_elem_info_is_writable(ctl->info)) { 509 ksft_print_msg("%s is not writeable\n", ctl->name); 510 ksft_test_result_skip("write_default.%d.%d\n", 511 ctl->card->card, ctl->elem); 512 return; 513 } 514 515 /* No idea what the default was for unreadable controls */ 516 if (!snd_ctl_elem_info_is_readable(ctl->info)) { 517 ksft_print_msg("%s couldn't read default\n", ctl->name); 518 ksft_test_result_skip("write_default.%d.%d\n", 519 ctl->card->card, ctl->elem); 520 return; 521 } 522 523 err = write_and_verify(ctl, ctl->def_val, NULL); 524 525 ksft_test_result(err >= 0, "write_default.%d.%d\n", 526 ctl->card->card, ctl->elem); 527 } 528 529 bool test_ctl_write_valid_boolean(struct ctl_data *ctl) 530 { 531 int err, i, j; 532 bool fail = false; 533 snd_ctl_elem_value_t *val; 534 snd_ctl_elem_value_alloca(&val); 535 536 snd_ctl_elem_value_set_id(val, ctl->id); 537 538 for (i = 0; i < snd_ctl_elem_info_get_count(ctl->info); i++) { 539 for (j = 0; j < 2; j++) { 540 snd_ctl_elem_value_set_boolean(val, i, j); 541 err = write_and_verify(ctl, val, NULL); 542 if (err != 0) 543 fail = true; 544 } 545 } 546 547 return !fail; 548 } 549 550 bool test_ctl_write_valid_integer(struct ctl_data *ctl) 551 { 552 int err; 553 int i; 554 long j, step; 555 bool fail = false; 556 snd_ctl_elem_value_t *val; 557 snd_ctl_elem_value_alloca(&val); 558 559 snd_ctl_elem_value_set_id(val, ctl->id); 560 561 step = snd_ctl_elem_info_get_step(ctl->info); 562 if (!step) 563 step = 1; 564 565 for (i = 0; i < snd_ctl_elem_info_get_count(ctl->info); i++) { 566 for (j = snd_ctl_elem_info_get_min(ctl->info); 567 j <= snd_ctl_elem_info_get_max(ctl->info); j += step) { 568 569 snd_ctl_elem_value_set_integer(val, i, j); 570 err = write_and_verify(ctl, val, NULL); 571 if (err != 0) 572 fail = true; 573 } 574 } 575 576 577 return !fail; 578 } 579 580 bool test_ctl_write_valid_integer64(struct ctl_data *ctl) 581 { 582 int err, i; 583 long long j, step; 584 bool fail = false; 585 snd_ctl_elem_value_t *val; 586 snd_ctl_elem_value_alloca(&val); 587 588 snd_ctl_elem_value_set_id(val, ctl->id); 589 590 step = snd_ctl_elem_info_get_step64(ctl->info); 591 if (!step) 592 step = 1; 593 594 for (i = 0; i < snd_ctl_elem_info_get_count(ctl->info); i++) { 595 for (j = snd_ctl_elem_info_get_min64(ctl->info); 596 j <= snd_ctl_elem_info_get_max64(ctl->info); j += step) { 597 598 snd_ctl_elem_value_set_integer64(val, i, j); 599 err = write_and_verify(ctl, val, NULL); 600 if (err != 0) 601 fail = true; 602 } 603 } 604 605 return !fail; 606 } 607 608 bool test_ctl_write_valid_enumerated(struct ctl_data *ctl) 609 { 610 int err, i, j; 611 bool fail = false; 612 snd_ctl_elem_value_t *val; 613 snd_ctl_elem_value_alloca(&val); 614 615 snd_ctl_elem_value_set_id(val, ctl->id); 616 617 for (i = 0; i < snd_ctl_elem_info_get_count(ctl->info); i++) { 618 for (j = 0; j < snd_ctl_elem_info_get_items(ctl->info); j++) { 619 snd_ctl_elem_value_set_enumerated(val, i, j); 620 err = write_and_verify(ctl, val, NULL); 621 if (err != 0) 622 fail = true; 623 } 624 } 625 626 return !fail; 627 } 628 629 void test_ctl_write_valid(struct ctl_data *ctl) 630 { 631 bool pass; 632 int err; 633 634 /* If the control is turned off let's be polite */ 635 if (snd_ctl_elem_info_is_inactive(ctl->info)) { 636 ksft_print_msg("%s is inactive\n", ctl->name); 637 ksft_test_result_skip("write_valid.%d.%d\n", 638 ctl->card->card, ctl->elem); 639 return; 640 } 641 642 if (!snd_ctl_elem_info_is_writable(ctl->info)) { 643 ksft_print_msg("%s is not writeable\n", ctl->name); 644 ksft_test_result_skip("write_valid.%d.%d\n", 645 ctl->card->card, ctl->elem); 646 return; 647 } 648 649 switch (snd_ctl_elem_info_get_type(ctl->info)) { 650 case SND_CTL_ELEM_TYPE_BOOLEAN: 651 pass = test_ctl_write_valid_boolean(ctl); 652 break; 653 654 case SND_CTL_ELEM_TYPE_INTEGER: 655 pass = test_ctl_write_valid_integer(ctl); 656 break; 657 658 case SND_CTL_ELEM_TYPE_INTEGER64: 659 pass = test_ctl_write_valid_integer64(ctl); 660 break; 661 662 case SND_CTL_ELEM_TYPE_ENUMERATED: 663 pass = test_ctl_write_valid_enumerated(ctl); 664 break; 665 666 default: 667 /* No tests for this yet */ 668 ksft_test_result_skip("write_valid.%d.%d\n", 669 ctl->card->card, ctl->elem); 670 return; 671 } 672 673 /* Restore the default value to minimise disruption */ 674 err = write_and_verify(ctl, ctl->def_val, NULL); 675 if (err < 0) 676 pass = false; 677 678 ksft_test_result(pass, "write_valid.%d.%d\n", 679 ctl->card->card, ctl->elem); 680 } 681 682 int main(void) 683 { 684 struct ctl_data *ctl; 685 686 ksft_print_header(); 687 688 find_controls(); 689 690 ksft_set_plan(num_controls * TESTS_PER_CONTROL); 691 692 for (ctl = ctl_list; ctl != NULL; ctl = ctl->next) { 693 /* 694 * Must test get_value() before we write anything, the 695 * test stores the default value for later cleanup. 696 */ 697 test_ctl_get_value(ctl); 698 test_ctl_write_default(ctl); 699 test_ctl_write_valid(ctl); 700 } 701 702 ksft_exit_pass(); 703 704 return 0; 705 } 706