GNU Linux-libre 4.19.263-gnu1
[releases.git] / sound / usb / clock.c
1 /*
2  *   Clock domain and sample rate management functions
3  *
4  *   This program is free software; you can redistribute it and/or modify
5  *   it under the terms of the GNU General Public License as published by
6  *   the Free Software Foundation; either version 2 of the License, or
7  *   (at your option) any later version.
8  *
9  *   This program is distributed in the hope that it will be useful,
10  *   but WITHOUT ANY WARRANTY; without even the implied warranty of
11  *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12  *   GNU General Public License for more details.
13  *
14  *   You should have received a copy of the GNU General Public License
15  *   along with this program; if not, write to the Free Software
16  *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
17  *
18  */
19
20 #include <linux/bitops.h>
21 #include <linux/init.h>
22 #include <linux/string.h>
23 #include <linux/usb.h>
24 #include <linux/usb/audio.h>
25 #include <linux/usb/audio-v2.h>
26 #include <linux/usb/audio-v3.h>
27
28 #include <sound/core.h>
29 #include <sound/info.h>
30 #include <sound/pcm.h>
31
32 #include "usbaudio.h"
33 #include "card.h"
34 #include "helper.h"
35 #include "clock.h"
36 #include "quirks.h"
37
38 static void *find_uac_clock_desc(struct usb_host_interface *iface, int id,
39                                  bool (*validator)(void *, int), u8 type)
40 {
41         void *cs = NULL;
42
43         while ((cs = snd_usb_find_csint_desc(iface->extra, iface->extralen,
44                                              cs, type))) {
45                 if (validator(cs, id))
46                         return cs;
47         }
48
49         return NULL;
50 }
51
52 static bool validate_clock_source_v2(void *p, int id)
53 {
54         struct uac_clock_source_descriptor *cs = p;
55         return cs->bClockID == id;
56 }
57
58 static bool validate_clock_source_v3(void *p, int id)
59 {
60         struct uac3_clock_source_descriptor *cs = p;
61         return cs->bClockID == id;
62 }
63
64 static bool validate_clock_selector_v2(void *p, int id)
65 {
66         struct uac_clock_selector_descriptor *cs = p;
67         return cs->bClockID == id;
68 }
69
70 static bool validate_clock_selector_v3(void *p, int id)
71 {
72         struct uac3_clock_selector_descriptor *cs = p;
73         return cs->bClockID == id;
74 }
75
76 static bool validate_clock_multiplier_v2(void *p, int id)
77 {
78         struct uac_clock_multiplier_descriptor *cs = p;
79         return cs->bClockID == id;
80 }
81
82 static bool validate_clock_multiplier_v3(void *p, int id)
83 {
84         struct uac3_clock_multiplier_descriptor *cs = p;
85         return cs->bClockID == id;
86 }
87
88 #define DEFINE_FIND_HELPER(name, obj, validator, type)          \
89 static obj *name(struct usb_host_interface *iface, int id)      \
90 {                                                               \
91         return find_uac_clock_desc(iface, id, validator, type); \
92 }
93
94 DEFINE_FIND_HELPER(snd_usb_find_clock_source,
95                    struct uac_clock_source_descriptor,
96                    validate_clock_source_v2, UAC2_CLOCK_SOURCE);
97 DEFINE_FIND_HELPER(snd_usb_find_clock_source_v3,
98                    struct uac3_clock_source_descriptor,
99                    validate_clock_source_v3, UAC3_CLOCK_SOURCE);
100
101 DEFINE_FIND_HELPER(snd_usb_find_clock_selector,
102                    struct uac_clock_selector_descriptor,
103                    validate_clock_selector_v2, UAC2_CLOCK_SELECTOR);
104 DEFINE_FIND_HELPER(snd_usb_find_clock_selector_v3,
105                    struct uac3_clock_selector_descriptor,
106                    validate_clock_selector_v3, UAC3_CLOCK_SELECTOR);
107
108 DEFINE_FIND_HELPER(snd_usb_find_clock_multiplier,
109                    struct uac_clock_multiplier_descriptor,
110                    validate_clock_multiplier_v2, UAC2_CLOCK_MULTIPLIER);
111 DEFINE_FIND_HELPER(snd_usb_find_clock_multiplier_v3,
112                    struct uac3_clock_multiplier_descriptor,
113                    validate_clock_multiplier_v3, UAC3_CLOCK_MULTIPLIER);
114
115 static int uac_clock_selector_get_val(struct snd_usb_audio *chip, int selector_id)
116 {
117         unsigned char buf;
118         int ret;
119
120         ret = snd_usb_ctl_msg(chip->dev, usb_rcvctrlpipe(chip->dev, 0),
121                               UAC2_CS_CUR,
122                               USB_RECIP_INTERFACE | USB_TYPE_CLASS | USB_DIR_IN,
123                               UAC2_CX_CLOCK_SELECTOR << 8,
124                               snd_usb_ctrl_intf(chip) | (selector_id << 8),
125                               &buf, sizeof(buf));
126
127         if (ret < 0)
128                 return ret;
129
130         return buf;
131 }
132
133 static int uac_clock_selector_set_val(struct snd_usb_audio *chip, int selector_id,
134                                         unsigned char pin)
135 {
136         int ret;
137
138         ret = snd_usb_ctl_msg(chip->dev, usb_sndctrlpipe(chip->dev, 0),
139                               UAC2_CS_CUR,
140                               USB_RECIP_INTERFACE | USB_TYPE_CLASS | USB_DIR_OUT,
141                               UAC2_CX_CLOCK_SELECTOR << 8,
142                               snd_usb_ctrl_intf(chip) | (selector_id << 8),
143                               &pin, sizeof(pin));
144         if (ret < 0)
145                 return ret;
146
147         if (ret != sizeof(pin)) {
148                 usb_audio_err(chip,
149                         "setting selector (id %d) unexpected length %d\n",
150                         selector_id, ret);
151                 return -EINVAL;
152         }
153
154         ret = uac_clock_selector_get_val(chip, selector_id);
155         if (ret < 0)
156                 return ret;
157
158         if (ret != pin) {
159                 usb_audio_err(chip,
160                         "setting selector (id %d) to %x failed (current: %d)\n",
161                         selector_id, pin, ret);
162                 return -EINVAL;
163         }
164
165         return ret;
166 }
167
168 /*
169  * Assume the clock is valid if clock source supports only one single sample
170  * rate, the terminal is connected directly to it (there is no clock selector)
171  * and clock type is internal. This is to deal with some Denon DJ controllers
172  * that always reports that clock is invalid.
173  */
174 static bool uac_clock_source_is_valid_quirk(struct snd_usb_audio *chip,
175                                             struct audioformat *fmt,
176                                             int source_id)
177 {
178         if (fmt->protocol == UAC_VERSION_2) {
179                 struct uac_clock_source_descriptor *cs_desc =
180                         snd_usb_find_clock_source(chip->ctrl_intf, source_id);
181
182                 if (!cs_desc)
183                         return false;
184
185                 return (fmt->nr_rates == 1 &&
186                         (fmt->clock & 0xff) == cs_desc->bClockID &&
187                         (cs_desc->bmAttributes & 0x3) !=
188                                 UAC_CLOCK_SOURCE_TYPE_EXT);
189         }
190
191         return false;
192 }
193
194 static bool uac_clock_source_is_valid(struct snd_usb_audio *chip,
195                                       struct audioformat *fmt,
196                                       int source_id)
197 {
198         int err;
199         unsigned char data;
200         struct usb_device *dev = chip->dev;
201         u32 bmControls;
202
203         if (fmt->protocol == UAC_VERSION_3) {
204                 struct uac3_clock_source_descriptor *cs_desc =
205                         snd_usb_find_clock_source_v3(chip->ctrl_intf, source_id);
206
207                 if (!cs_desc)
208                         return false;
209                 bmControls = le32_to_cpu(cs_desc->bmControls);
210         } else { /* UAC_VERSION_1/2 */
211                 struct uac_clock_source_descriptor *cs_desc =
212                         snd_usb_find_clock_source(chip->ctrl_intf, source_id);
213
214                 if (!cs_desc)
215                         return false;
216                 bmControls = cs_desc->bmControls;
217         }
218
219         /* If a clock source can't tell us whether it's valid, we assume it is */
220         if (!uac_v2v3_control_is_readable(bmControls,
221                                       UAC2_CS_CONTROL_CLOCK_VALID))
222                 return true;
223
224         err = snd_usb_ctl_msg(dev, usb_rcvctrlpipe(dev, 0), UAC2_CS_CUR,
225                               USB_TYPE_CLASS | USB_RECIP_INTERFACE | USB_DIR_IN,
226                               UAC2_CS_CONTROL_CLOCK_VALID << 8,
227                               snd_usb_ctrl_intf(chip) | (source_id << 8),
228                               &data, sizeof(data));
229
230         if (err < 0) {
231                 dev_warn(&dev->dev,
232                          "%s(): cannot get clock validity for id %d\n",
233                            __func__, source_id);
234                 return false;
235         }
236
237         if (data)
238                 return true;
239         else
240                 return uac_clock_source_is_valid_quirk(chip, fmt, source_id);
241 }
242
243 static int __uac_clock_find_source(struct snd_usb_audio *chip,
244                                    struct audioformat *fmt, int entity_id,
245                                    unsigned long *visited, bool validate)
246 {
247         struct uac_clock_source_descriptor *source;
248         struct uac_clock_selector_descriptor *selector;
249         struct uac_clock_multiplier_descriptor *multiplier;
250
251         entity_id &= 0xff;
252
253         if (test_and_set_bit(entity_id, visited)) {
254                 usb_audio_warn(chip,
255                          "%s(): recursive clock topology detected, id %d.\n",
256                          __func__, entity_id);
257                 return -EINVAL;
258         }
259
260         /* first, see if the ID we're looking for is a clock source already */
261         source = snd_usb_find_clock_source(chip->ctrl_intf, entity_id);
262         if (source) {
263                 entity_id = source->bClockID;
264                 if (validate && !uac_clock_source_is_valid(chip, fmt,
265                                                                 entity_id)) {
266                         usb_audio_err(chip,
267                                 "clock source %d is not valid, cannot use\n",
268                                 entity_id);
269                         return -ENXIO;
270                 }
271                 return entity_id;
272         }
273
274         selector = snd_usb_find_clock_selector(chip->ctrl_intf, entity_id);
275         if (selector) {
276                 int ret, i, cur, err;
277
278                 /* the entity ID we are looking for is a selector.
279                  * find out what it currently selects */
280                 ret = uac_clock_selector_get_val(chip, selector->bClockID);
281                 if (ret < 0)
282                         return ret;
283
284                 /* Selector values are one-based */
285
286                 if (ret > selector->bNrInPins || ret < 1) {
287                         usb_audio_err(chip,
288                                 "%s(): selector reported illegal value, id %d, ret %d\n",
289                                 __func__, selector->bClockID, ret);
290
291                         return -EINVAL;
292                 }
293
294                 cur = ret;
295                 ret = __uac_clock_find_source(chip, fmt,
296                                               selector->baCSourceID[ret - 1],
297                                               visited, validate);
298                 if (ret > 0) {
299                         /*
300                          * For Samsung USBC Headset (AKG), setting clock selector again
301                          * will result in incorrect default clock setting problems
302                          */
303                         if (chip->usb_id == USB_ID(0x04e8, 0xa051))
304                                 return ret;
305                         err = uac_clock_selector_set_val(chip, entity_id, cur);
306                         if (err < 0)
307                                 return err;
308                 }
309
310                 if (!validate || ret > 0 || !chip->autoclock)
311                         return ret;
312
313                 /* The current clock source is invalid, try others. */
314                 for (i = 1; i <= selector->bNrInPins; i++) {
315                         if (i == cur)
316                                 continue;
317
318                         ret = __uac_clock_find_source(chip, fmt,
319                                                       selector->baCSourceID[i - 1],
320                                                       visited, true);
321                         if (ret < 0)
322                                 continue;
323
324                         err = uac_clock_selector_set_val(chip, entity_id, i);
325                         if (err < 0)
326                                 continue;
327
328                         usb_audio_info(chip,
329                                  "found and selected valid clock source %d\n",
330                                  ret);
331                         return ret;
332                 }
333
334                 return -ENXIO;
335         }
336
337         /* FIXME: multipliers only act as pass-thru element for now */
338         multiplier = snd_usb_find_clock_multiplier(chip->ctrl_intf, entity_id);
339         if (multiplier)
340                 return __uac_clock_find_source(chip, fmt,
341                                                multiplier->bCSourceID,
342                                                visited, validate);
343
344         return -EINVAL;
345 }
346
347 static int __uac3_clock_find_source(struct snd_usb_audio *chip,
348                                     struct audioformat *fmt, int entity_id,
349                                     unsigned long *visited, bool validate)
350 {
351         struct uac3_clock_source_descriptor *source;
352         struct uac3_clock_selector_descriptor *selector;
353         struct uac3_clock_multiplier_descriptor *multiplier;
354
355         entity_id &= 0xff;
356
357         if (test_and_set_bit(entity_id, visited)) {
358                 usb_audio_warn(chip,
359                          "%s(): recursive clock topology detected, id %d.\n",
360                          __func__, entity_id);
361                 return -EINVAL;
362         }
363
364         /* first, see if the ID we're looking for is a clock source already */
365         source = snd_usb_find_clock_source_v3(chip->ctrl_intf, entity_id);
366         if (source) {
367                 entity_id = source->bClockID;
368                 if (validate && !uac_clock_source_is_valid(chip, fmt,
369                                                                 entity_id)) {
370                         usb_audio_err(chip,
371                                 "clock source %d is not valid, cannot use\n",
372                                 entity_id);
373                         return -ENXIO;
374                 }
375                 return entity_id;
376         }
377
378         selector = snd_usb_find_clock_selector_v3(chip->ctrl_intf, entity_id);
379         if (selector) {
380                 int ret, i, cur, err;
381
382                 /* the entity ID we are looking for is a selector.
383                  * find out what it currently selects */
384                 ret = uac_clock_selector_get_val(chip, selector->bClockID);
385                 if (ret < 0)
386                         return ret;
387
388                 /* Selector values are one-based */
389
390                 if (ret > selector->bNrInPins || ret < 1) {
391                         usb_audio_err(chip,
392                                 "%s(): selector reported illegal value, id %d, ret %d\n",
393                                 __func__, selector->bClockID, ret);
394
395                         return -EINVAL;
396                 }
397
398                 cur = ret;
399                 ret = __uac3_clock_find_source(chip, fmt,
400                                                selector->baCSourceID[ret - 1],
401                                                visited, validate);
402                 if (ret > 0) {
403                         err = uac_clock_selector_set_val(chip, entity_id, cur);
404                         if (err < 0)
405                                 return err;
406                 }
407
408                 if (!validate || ret > 0 || !chip->autoclock)
409                         return ret;
410
411                 /* The current clock source is invalid, try others. */
412                 for (i = 1; i <= selector->bNrInPins; i++) {
413                         int err;
414
415                         if (i == cur)
416                                 continue;
417
418                         ret = __uac3_clock_find_source(chip, fmt,
419                                                        selector->baCSourceID[i - 1],
420                                                        visited, true);
421                         if (ret < 0)
422                                 continue;
423
424                         err = uac_clock_selector_set_val(chip, entity_id, i);
425                         if (err < 0)
426                                 continue;
427
428                         usb_audio_info(chip,
429                                  "found and selected valid clock source %d\n",
430                                  ret);
431                         return ret;
432                 }
433
434                 return -ENXIO;
435         }
436
437         /* FIXME: multipliers only act as pass-thru element for now */
438         multiplier = snd_usb_find_clock_multiplier_v3(chip->ctrl_intf,
439                                                       entity_id);
440         if (multiplier)
441                 return __uac3_clock_find_source(chip, fmt,
442                                                 multiplier->bCSourceID,
443                                                 visited, validate);
444
445         return -EINVAL;
446 }
447
448 /*
449  * For all kinds of sample rate settings and other device queries,
450  * the clock source (end-leaf) must be used. However, clock selectors,
451  * clock multipliers and sample rate converters may be specified as
452  * clock source input to terminal. This functions walks the clock path
453  * to its end and tries to find the source.
454  *
455  * The 'visited' bitfield is used internally to detect recursive loops.
456  *
457  * Returns the clock source UnitID (>=0) on success, or an error.
458  */
459 int snd_usb_clock_find_source(struct snd_usb_audio *chip,
460                               struct audioformat *fmt, bool validate)
461 {
462         DECLARE_BITMAP(visited, 256);
463         memset(visited, 0, sizeof(visited));
464
465         switch (fmt->protocol) {
466         case UAC_VERSION_2:
467                 return __uac_clock_find_source(chip, fmt, fmt->clock, visited,
468                                                validate);
469         case UAC_VERSION_3:
470                 return __uac3_clock_find_source(chip, fmt, fmt->clock, visited,
471                                                validate);
472         default:
473                 return -EINVAL;
474         }
475 }
476
477 static int set_sample_rate_v1(struct snd_usb_audio *chip, int iface,
478                               struct usb_host_interface *alts,
479                               struct audioformat *fmt, int rate)
480 {
481         struct usb_device *dev = chip->dev;
482         unsigned int ep;
483         unsigned char data[3];
484         int err, crate;
485
486         if (get_iface_desc(alts)->bNumEndpoints < 1)
487                 return -EINVAL;
488         ep = get_endpoint(alts, 0)->bEndpointAddress;
489
490         /* if endpoint doesn't have sampling rate control, bail out */
491         if (!(fmt->attributes & UAC_EP_CS_ATTR_SAMPLE_RATE))
492                 return 0;
493
494         data[0] = rate;
495         data[1] = rate >> 8;
496         data[2] = rate >> 16;
497         err = snd_usb_ctl_msg(dev, usb_sndctrlpipe(dev, 0), UAC_SET_CUR,
498                               USB_TYPE_CLASS | USB_RECIP_ENDPOINT | USB_DIR_OUT,
499                               UAC_EP_CS_ATTR_SAMPLE_RATE << 8, ep,
500                               data, sizeof(data));
501         if (err < 0) {
502                 dev_err(&dev->dev, "%d:%d: cannot set freq %d to ep %#x\n",
503                         iface, fmt->altsetting, rate, ep);
504                 return err;
505         }
506
507         /* Don't check the sample rate for devices which we know don't
508          * support reading */
509         if (snd_usb_get_sample_rate_quirk(chip))
510                 return 0;
511         /* the firmware is likely buggy, don't repeat to fail too many times */
512         if (chip->sample_rate_read_error > 2)
513                 return 0;
514
515         err = snd_usb_ctl_msg(dev, usb_rcvctrlpipe(dev, 0), UAC_GET_CUR,
516                               USB_TYPE_CLASS | USB_RECIP_ENDPOINT | USB_DIR_IN,
517                               UAC_EP_CS_ATTR_SAMPLE_RATE << 8, ep,
518                               data, sizeof(data));
519         if (err < 0) {
520                 dev_err(&dev->dev, "%d:%d: cannot get freq at ep %#x\n",
521                         iface, fmt->altsetting, ep);
522                 chip->sample_rate_read_error++;
523                 return 0; /* some devices don't support reading */
524         }
525
526         crate = data[0] | (data[1] << 8) | (data[2] << 16);
527         if (!crate) {
528                 dev_info(&dev->dev, "failed to read current rate; disabling the check\n");
529                 chip->sample_rate_read_error = 3; /* three strikes, see above */
530                 return 0;
531         }
532
533         if (crate != rate) {
534                 dev_warn(&dev->dev, "current rate %d is different from the runtime rate %d\n", crate, rate);
535                 // runtime->rate = crate;
536         }
537
538         return 0;
539 }
540
541 static int get_sample_rate_v2v3(struct snd_usb_audio *chip, int iface,
542                               int altsetting, int clock)
543 {
544         struct usb_device *dev = chip->dev;
545         __le32 data;
546         int err;
547
548         err = snd_usb_ctl_msg(dev, usb_rcvctrlpipe(dev, 0), UAC2_CS_CUR,
549                               USB_TYPE_CLASS | USB_RECIP_INTERFACE | USB_DIR_IN,
550                               UAC2_CS_CONTROL_SAM_FREQ << 8,
551                               snd_usb_ctrl_intf(chip) | (clock << 8),
552                               &data, sizeof(data));
553         if (err < 0) {
554                 dev_warn(&dev->dev, "%d:%d: cannot get freq (v2/v3): err %d\n",
555                          iface, altsetting, err);
556                 return 0;
557         }
558
559         return le32_to_cpu(data);
560 }
561
562 static int set_sample_rate_v2v3(struct snd_usb_audio *chip, int iface,
563                               struct usb_host_interface *alts,
564                               struct audioformat *fmt, int rate)
565 {
566         struct usb_device *dev = chip->dev;
567         __le32 data;
568         int err, cur_rate, prev_rate;
569         int clock;
570         bool writeable;
571         u32 bmControls;
572
573         /* First, try to find a valid clock. This may trigger
574          * automatic clock selection if the current clock is not
575          * valid.
576          */
577         clock = snd_usb_clock_find_source(chip, fmt, true);
578         if (clock < 0) {
579                 /* We did not find a valid clock, but that might be
580                  * because the current sample rate does not match an
581                  * external clock source. Try again without validation
582                  * and we will do another validation after setting the
583                  * rate.
584                  */
585                 clock = snd_usb_clock_find_source(chip, fmt, false);
586                 if (clock < 0)
587                         return clock;
588         }
589
590         prev_rate = get_sample_rate_v2v3(chip, iface, fmt->altsetting, clock);
591         if (prev_rate == rate)
592                 goto validation;
593
594         if (fmt->protocol == UAC_VERSION_3) {
595                 struct uac3_clock_source_descriptor *cs_desc;
596
597                 cs_desc = snd_usb_find_clock_source_v3(chip->ctrl_intf, clock);
598                 bmControls = le32_to_cpu(cs_desc->bmControls);
599         } else {
600                 struct uac_clock_source_descriptor *cs_desc;
601
602                 cs_desc = snd_usb_find_clock_source(chip->ctrl_intf, clock);
603                 bmControls = cs_desc->bmControls;
604         }
605
606         writeable = uac_v2v3_control_is_writeable(bmControls,
607                                                   UAC2_CS_CONTROL_SAM_FREQ);
608         if (writeable) {
609                 data = cpu_to_le32(rate);
610                 err = snd_usb_ctl_msg(dev, usb_sndctrlpipe(dev, 0), UAC2_CS_CUR,
611                                       USB_TYPE_CLASS | USB_RECIP_INTERFACE | USB_DIR_OUT,
612                                       UAC2_CS_CONTROL_SAM_FREQ << 8,
613                                       snd_usb_ctrl_intf(chip) | (clock << 8),
614                                       &data, sizeof(data));
615                 if (err < 0) {
616                         usb_audio_err(chip,
617                                 "%d:%d: cannot set freq %d (v2/v3): err %d\n",
618                                 iface, fmt->altsetting, rate, err);
619                         return err;
620                 }
621
622                 cur_rate = get_sample_rate_v2v3(chip, iface,
623                                                 fmt->altsetting, clock);
624         } else {
625                 cur_rate = prev_rate;
626         }
627
628         if (cur_rate != rate) {
629                 if (!writeable) {
630                         usb_audio_warn(chip,
631                                  "%d:%d: freq mismatch (RO clock): req %d, clock runs @%d\n",
632                                  iface, fmt->altsetting, rate, cur_rate);
633                         return -ENXIO;
634                 }
635                 usb_audio_dbg(chip,
636                         "current rate %d is different from the runtime rate %d\n",
637                         cur_rate, rate);
638         }
639
640         /* Some devices doesn't respond to sample rate changes while the
641          * interface is active. */
642         if (rate != prev_rate) {
643                 usb_set_interface(dev, iface, 0);
644                 snd_usb_set_interface_quirk(dev);
645                 usb_set_interface(dev, iface, fmt->altsetting);
646                 snd_usb_set_interface_quirk(dev);
647         }
648
649 validation:
650         /* validate clock after rate change */
651         if (!uac_clock_source_is_valid(chip, fmt, clock))
652                 return -ENXIO;
653         return 0;
654 }
655
656 int snd_usb_init_sample_rate(struct snd_usb_audio *chip, int iface,
657                              struct usb_host_interface *alts,
658                              struct audioformat *fmt, int rate)
659 {
660         switch (fmt->protocol) {
661         case UAC_VERSION_1:
662         default:
663                 return set_sample_rate_v1(chip, iface, alts, fmt, rate);
664
665         case UAC_VERSION_3:
666                 if (chip->badd_profile >= UAC3_FUNCTION_SUBCLASS_GENERIC_IO) {
667                         if (rate != UAC3_BADD_SAMPLING_RATE)
668                                 return -ENXIO;
669                         else
670                                 return 0;
671                 }
672         /* fall through */
673         case UAC_VERSION_2:
674                 return set_sample_rate_v2v3(chip, iface, alts, fmt, rate);
675         }
676 }
677