kselftest: alsa: Declare most functions static
[linux-2.6-microblaze.git] / tools / testing / selftests / alsa / mixer-test.c
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 desciptor 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_desciptors_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_desciptors_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 }