Skip to content

Commit 1c82679

Browse files
puleglottiwai
authored andcommitted
ALSA: usb-audio: Filter out unsupported sample rates on Focusrite devices
Many Focusrite devices supports a limited set of sample rates per altsetting. These includes audio interfaces with ADAT ports: - Scarlett 18i6, 18i8 1st gen, 18i20 1st gen; - Scarlett 18i8 2nd gen, 18i20 2nd gen; - Scarlett 18i8 3rd gen, 18i20 3rd gen; - Clarett 2Pre USB, 4Pre USB, 8Pre USB. Maximum rate is exposed in the last 4 bytes of Format Type descriptor which has a non-standard bLength = 10. Tested-by: Alexey Skobkin <[email protected]> Signed-off-by: Alexander Tsoy <[email protected]> Cc: <[email protected]> Link: https://lore.kernel.org/r/[email protected] Signed-off-by: Takashi Iwai <[email protected]>
1 parent b392350 commit 1c82679

File tree

1 file changed

+51
-0
lines changed

1 file changed

+51
-0
lines changed

sound/usb/format.c

Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -277,6 +277,52 @@ static bool s1810c_valid_sample_rate(struct audioformat *fp,
277277
return false;
278278
}
279279

280+
/*
281+
* Many Focusrite devices supports a limited set of sampling rates per
282+
* altsetting. Maximum rate is exposed in the last 4 bytes of Format Type
283+
* descriptor which has a non-standard bLength = 10.
284+
*/
285+
static bool focusrite_valid_sample_rate(struct snd_usb_audio *chip,
286+
struct audioformat *fp,
287+
unsigned int rate)
288+
{
289+
struct usb_interface *iface;
290+
struct usb_host_interface *alts;
291+
unsigned char *fmt;
292+
unsigned int max_rate;
293+
294+
iface = usb_ifnum_to_if(chip->dev, fp->iface);
295+
if (!iface)
296+
return true;
297+
298+
alts = &iface->altsetting[fp->altset_idx];
299+
fmt = snd_usb_find_csint_desc(alts->extra, alts->extralen,
300+
NULL, UAC_FORMAT_TYPE);
301+
if (!fmt)
302+
return true;
303+
304+
if (fmt[0] == 10) { /* bLength */
305+
max_rate = combine_quad(&fmt[6]);
306+
307+
/* Validate max rate */
308+
if (max_rate != 48000 &&
309+
max_rate != 96000 &&
310+
max_rate != 192000 &&
311+
max_rate != 384000) {
312+
313+
usb_audio_info(chip,
314+
"%u:%d : unexpected max rate: %u\n",
315+
fp->iface, fp->altsetting, max_rate);
316+
317+
return true;
318+
}
319+
320+
return rate <= max_rate;
321+
}
322+
323+
return true;
324+
}
325+
280326
/*
281327
* Helper function to walk the array of sample rate triplets reported by
282328
* the device. The problem is that we need to parse whole array first to
@@ -319,6 +365,11 @@ static int parse_uac2_sample_rate_range(struct snd_usb_audio *chip,
319365
!s1810c_valid_sample_rate(fp, rate))
320366
goto skip_rate;
321367

368+
/* Filter out invalid rates on Focusrite devices */
369+
if (USB_ID_VENDOR(chip->usb_id) == 0x1235 &&
370+
!focusrite_valid_sample_rate(chip, fp, rate))
371+
goto skip_rate;
372+
322373
if (fp->rate_table)
323374
fp->rate_table[nr_rates] = rate;
324375
if (!fp->rate_min || rate < fp->rate_min)

0 commit comments

Comments
 (0)