diff options
author | Nick Kossifidis <mickflemm@gmail.com> | 2020-02-15 03:23:35 +0200 |
---|---|---|
committer | Takashi Iwai <tiwai@suse.de> | 2020-02-15 09:46:16 +0100 |
commit | 8dc5efe3d17cd572328ac4f1ebde629c83317f54 (patch) | |
tree | d60a6e26a042aa9641d197fba3c051adb90d469b /sound/usb/format.c | |
parent | 146f66975bafbcfab349901c9f9c9f521ac96cbb (diff) | |
download | lwn-8dc5efe3d17cd572328ac4f1ebde629c83317f54.tar.gz lwn-8dc5efe3d17cd572328ac4f1ebde629c83317f54.zip |
ALSA: usb-audio: Add support for Presonus Studio 1810c
This patch adds support for Presonus Studio 1810c, a usb interface
that's UAC2 compliant with a few quirks and a few extra hw-specific
controls. I've tested all 3 altsettings and the added switch
controls and they work as expected.
More infos on the card:
https://www.presonus.com/products/Studio-1810c
Note that this work is based on packet inspection with
usbmon. I just wanted to get this card to work for using
it on our open-source radio station:
https://github.com/UoC-Radio
v2 address issues reported by Takashi:
* Properly get/set enum type controls
* Prevent race condition on switch_get/set
* Various control naming changes
* Various coding style fixes
v3 improve readability of sample rate filtering
and some other minor changes.
Signed-off-by: Nick Kossifidis <mickflemm@gmail.com>
Link: https://lore.kernel.org/r/5e47481a.1c69fb81.befb3.8dac@mx.google.com
Signed-off-by: Takashi Iwai <tiwai@suse.de>
Diffstat (limited to 'sound/usb/format.c')
-rw-r--r-- | sound/usb/format.c | 37 |
1 files changed, 37 insertions, 0 deletions
diff --git a/sound/usb/format.c b/sound/usb/format.c index 9260136e4c9b..51e9fca1f3dc 100644 --- a/sound/usb/format.c +++ b/sound/usb/format.c @@ -226,6 +226,36 @@ static int parse_audio_format_rates_v1(struct snd_usb_audio *chip, struct audiof return 0; } + +/* + * Presonus Studio 1810c supports a limited set of sampling + * rates per altsetting but reports the full set each time. + * If we don't filter out the unsupported rates and attempt + * to configure the card, it will hang refusing to do any + * further audio I/O until a hard reset is performed. + * + * The list of supported rates per altsetting (set of available + * I/O channels) is described in the owner's manual, section 2.2. + */ +static bool s1810c_valid_sample_rate(struct audioformat *fp, + unsigned int rate) +{ + switch (fp->altsetting) { + case 1: + /* All ADAT ports available */ + return rate <= 48000; + case 2: + /* Half of ADAT ports available */ + return (rate == 88200 || rate == 96000); + case 3: + /* Analog I/O only (no S/PDIF nor ADAT) */ + return rate >= 176400; + default: + return false; + } + return false; +} + /* * Helper function to walk the array of sample rate triplets reported by * the device. The problem is that we need to parse whole array first to @@ -262,6 +292,12 @@ static int parse_uac2_sample_rate_range(struct snd_usb_audio *chip, } for (rate = min; rate <= max; rate += res) { + + /* Filter out invalid rates on Presonus Studio 1810c */ + if (chip->usb_id == USB_ID(0x0194f, 0x010c) && + !s1810c_valid_sample_rate(fp, rate)) + goto skip_rate; + if (fp->rate_table) fp->rate_table[nr_rates] = rate; if (!fp->rate_min || rate < fp->rate_min) @@ -276,6 +312,7 @@ static int parse_uac2_sample_rate_range(struct snd_usb_audio *chip, break; } +skip_rate: /* avoid endless loop */ if (res == 0) break; |