162306a36Sopenharmony_ci// SPDX-License-Identifier: GPL-2.0-or-later 262306a36Sopenharmony_ci/* 362306a36Sopenharmony_ci */ 462306a36Sopenharmony_ci 562306a36Sopenharmony_ci#include <linux/init.h> 662306a36Sopenharmony_ci#include <linux/slab.h> 762306a36Sopenharmony_ci#include <linux/usb.h> 862306a36Sopenharmony_ci#include <linux/usb/audio.h> 962306a36Sopenharmony_ci#include <linux/usb/audio-v2.h> 1062306a36Sopenharmony_ci#include <linux/usb/audio-v3.h> 1162306a36Sopenharmony_ci 1262306a36Sopenharmony_ci#include <sound/core.h> 1362306a36Sopenharmony_ci#include <sound/pcm.h> 1462306a36Sopenharmony_ci 1562306a36Sopenharmony_ci#include "usbaudio.h" 1662306a36Sopenharmony_ci#include "card.h" 1762306a36Sopenharmony_ci#include "quirks.h" 1862306a36Sopenharmony_ci#include "helper.h" 1962306a36Sopenharmony_ci#include "clock.h" 2062306a36Sopenharmony_ci#include "format.h" 2162306a36Sopenharmony_ci 2262306a36Sopenharmony_ci/* 2362306a36Sopenharmony_ci * parse the audio format type I descriptor 2462306a36Sopenharmony_ci * and returns the corresponding pcm format 2562306a36Sopenharmony_ci * 2662306a36Sopenharmony_ci * @dev: usb device 2762306a36Sopenharmony_ci * @fp: audioformat record 2862306a36Sopenharmony_ci * @format: the format tag (wFormatTag) 2962306a36Sopenharmony_ci * @fmt: the format type descriptor (v1/v2) or AudioStreaming descriptor (v3) 3062306a36Sopenharmony_ci */ 3162306a36Sopenharmony_cistatic u64 parse_audio_format_i_type(struct snd_usb_audio *chip, 3262306a36Sopenharmony_ci struct audioformat *fp, 3362306a36Sopenharmony_ci u64 format, void *_fmt) 3462306a36Sopenharmony_ci{ 3562306a36Sopenharmony_ci int sample_width, sample_bytes; 3662306a36Sopenharmony_ci u64 pcm_formats = 0; 3762306a36Sopenharmony_ci 3862306a36Sopenharmony_ci switch (fp->protocol) { 3962306a36Sopenharmony_ci case UAC_VERSION_1: 4062306a36Sopenharmony_ci default: { 4162306a36Sopenharmony_ci struct uac_format_type_i_discrete_descriptor *fmt = _fmt; 4262306a36Sopenharmony_ci if (format >= 64) { 4362306a36Sopenharmony_ci usb_audio_info(chip, 4462306a36Sopenharmony_ci "%u:%d: invalid format type 0x%llx is detected, processed as PCM\n", 4562306a36Sopenharmony_ci fp->iface, fp->altsetting, format); 4662306a36Sopenharmony_ci format = UAC_FORMAT_TYPE_I_PCM; 4762306a36Sopenharmony_ci } 4862306a36Sopenharmony_ci sample_width = fmt->bBitResolution; 4962306a36Sopenharmony_ci sample_bytes = fmt->bSubframeSize; 5062306a36Sopenharmony_ci format = 1ULL << format; 5162306a36Sopenharmony_ci break; 5262306a36Sopenharmony_ci } 5362306a36Sopenharmony_ci 5462306a36Sopenharmony_ci case UAC_VERSION_2: { 5562306a36Sopenharmony_ci struct uac_format_type_i_ext_descriptor *fmt = _fmt; 5662306a36Sopenharmony_ci sample_width = fmt->bBitResolution; 5762306a36Sopenharmony_ci sample_bytes = fmt->bSubslotSize; 5862306a36Sopenharmony_ci 5962306a36Sopenharmony_ci if (format & UAC2_FORMAT_TYPE_I_RAW_DATA) { 6062306a36Sopenharmony_ci pcm_formats |= SNDRV_PCM_FMTBIT_SPECIAL; 6162306a36Sopenharmony_ci /* flag potentially raw DSD capable altsettings */ 6262306a36Sopenharmony_ci fp->dsd_raw = true; 6362306a36Sopenharmony_ci } 6462306a36Sopenharmony_ci 6562306a36Sopenharmony_ci format <<= 1; 6662306a36Sopenharmony_ci break; 6762306a36Sopenharmony_ci } 6862306a36Sopenharmony_ci case UAC_VERSION_3: { 6962306a36Sopenharmony_ci struct uac3_as_header_descriptor *as = _fmt; 7062306a36Sopenharmony_ci 7162306a36Sopenharmony_ci sample_width = as->bBitResolution; 7262306a36Sopenharmony_ci sample_bytes = as->bSubslotSize; 7362306a36Sopenharmony_ci 7462306a36Sopenharmony_ci if (format & UAC3_FORMAT_TYPE_I_RAW_DATA) 7562306a36Sopenharmony_ci pcm_formats |= SNDRV_PCM_FMTBIT_SPECIAL; 7662306a36Sopenharmony_ci 7762306a36Sopenharmony_ci format <<= 1; 7862306a36Sopenharmony_ci break; 7962306a36Sopenharmony_ci } 8062306a36Sopenharmony_ci } 8162306a36Sopenharmony_ci 8262306a36Sopenharmony_ci fp->fmt_bits = sample_width; 8362306a36Sopenharmony_ci 8462306a36Sopenharmony_ci if ((pcm_formats == 0) && 8562306a36Sopenharmony_ci (format == 0 || format == (1 << UAC_FORMAT_TYPE_I_UNDEFINED))) { 8662306a36Sopenharmony_ci /* some devices don't define this correctly... */ 8762306a36Sopenharmony_ci usb_audio_info(chip, "%u:%d : format type 0 is detected, processed as PCM\n", 8862306a36Sopenharmony_ci fp->iface, fp->altsetting); 8962306a36Sopenharmony_ci format = 1 << UAC_FORMAT_TYPE_I_PCM; 9062306a36Sopenharmony_ci } 9162306a36Sopenharmony_ci if (format & (1 << UAC_FORMAT_TYPE_I_PCM)) { 9262306a36Sopenharmony_ci if (((chip->usb_id == USB_ID(0x0582, 0x0016)) || 9362306a36Sopenharmony_ci /* Edirol SD-90 */ 9462306a36Sopenharmony_ci (chip->usb_id == USB_ID(0x0582, 0x000c))) && 9562306a36Sopenharmony_ci /* Roland SC-D70 */ 9662306a36Sopenharmony_ci sample_width == 24 && sample_bytes == 2) 9762306a36Sopenharmony_ci sample_bytes = 3; 9862306a36Sopenharmony_ci else if (sample_width > sample_bytes * 8) { 9962306a36Sopenharmony_ci usb_audio_info(chip, "%u:%d : sample bitwidth %d in over sample bytes %d\n", 10062306a36Sopenharmony_ci fp->iface, fp->altsetting, 10162306a36Sopenharmony_ci sample_width, sample_bytes); 10262306a36Sopenharmony_ci } 10362306a36Sopenharmony_ci /* check the format byte size */ 10462306a36Sopenharmony_ci switch (sample_bytes) { 10562306a36Sopenharmony_ci case 1: 10662306a36Sopenharmony_ci pcm_formats |= SNDRV_PCM_FMTBIT_S8; 10762306a36Sopenharmony_ci break; 10862306a36Sopenharmony_ci case 2: 10962306a36Sopenharmony_ci if (snd_usb_is_big_endian_format(chip, fp)) 11062306a36Sopenharmony_ci pcm_formats |= SNDRV_PCM_FMTBIT_S16_BE; /* grrr, big endian!! */ 11162306a36Sopenharmony_ci else 11262306a36Sopenharmony_ci pcm_formats |= SNDRV_PCM_FMTBIT_S16_LE; 11362306a36Sopenharmony_ci break; 11462306a36Sopenharmony_ci case 3: 11562306a36Sopenharmony_ci if (snd_usb_is_big_endian_format(chip, fp)) 11662306a36Sopenharmony_ci pcm_formats |= SNDRV_PCM_FMTBIT_S24_3BE; /* grrr, big endian!! */ 11762306a36Sopenharmony_ci else 11862306a36Sopenharmony_ci pcm_formats |= SNDRV_PCM_FMTBIT_S24_3LE; 11962306a36Sopenharmony_ci break; 12062306a36Sopenharmony_ci case 4: 12162306a36Sopenharmony_ci pcm_formats |= SNDRV_PCM_FMTBIT_S32_LE; 12262306a36Sopenharmony_ci break; 12362306a36Sopenharmony_ci default: 12462306a36Sopenharmony_ci usb_audio_info(chip, 12562306a36Sopenharmony_ci "%u:%d : unsupported sample bitwidth %d in %d bytes\n", 12662306a36Sopenharmony_ci fp->iface, fp->altsetting, 12762306a36Sopenharmony_ci sample_width, sample_bytes); 12862306a36Sopenharmony_ci break; 12962306a36Sopenharmony_ci } 13062306a36Sopenharmony_ci } 13162306a36Sopenharmony_ci if (format & (1 << UAC_FORMAT_TYPE_I_PCM8)) { 13262306a36Sopenharmony_ci /* Dallas DS4201 workaround: it advertises U8 format, but really 13362306a36Sopenharmony_ci supports S8. */ 13462306a36Sopenharmony_ci if (chip->usb_id == USB_ID(0x04fa, 0x4201)) 13562306a36Sopenharmony_ci pcm_formats |= SNDRV_PCM_FMTBIT_S8; 13662306a36Sopenharmony_ci else 13762306a36Sopenharmony_ci pcm_formats |= SNDRV_PCM_FMTBIT_U8; 13862306a36Sopenharmony_ci } 13962306a36Sopenharmony_ci if (format & (1 << UAC_FORMAT_TYPE_I_IEEE_FLOAT)) { 14062306a36Sopenharmony_ci pcm_formats |= SNDRV_PCM_FMTBIT_FLOAT_LE; 14162306a36Sopenharmony_ci } 14262306a36Sopenharmony_ci if (format & (1 << UAC_FORMAT_TYPE_I_ALAW)) { 14362306a36Sopenharmony_ci pcm_formats |= SNDRV_PCM_FMTBIT_A_LAW; 14462306a36Sopenharmony_ci } 14562306a36Sopenharmony_ci if (format & (1 << UAC_FORMAT_TYPE_I_MULAW)) { 14662306a36Sopenharmony_ci pcm_formats |= SNDRV_PCM_FMTBIT_MU_LAW; 14762306a36Sopenharmony_ci } 14862306a36Sopenharmony_ci if (format & ~0x3f) { 14962306a36Sopenharmony_ci usb_audio_info(chip, 15062306a36Sopenharmony_ci "%u:%d : unsupported format bits %#llx\n", 15162306a36Sopenharmony_ci fp->iface, fp->altsetting, format); 15262306a36Sopenharmony_ci } 15362306a36Sopenharmony_ci 15462306a36Sopenharmony_ci pcm_formats |= snd_usb_interface_dsd_format_quirks(chip, fp, sample_bytes); 15562306a36Sopenharmony_ci 15662306a36Sopenharmony_ci return pcm_formats; 15762306a36Sopenharmony_ci} 15862306a36Sopenharmony_ci 15962306a36Sopenharmony_cistatic int set_fixed_rate(struct audioformat *fp, int rate, int rate_bits) 16062306a36Sopenharmony_ci{ 16162306a36Sopenharmony_ci kfree(fp->rate_table); 16262306a36Sopenharmony_ci fp->rate_table = kmalloc(sizeof(int), GFP_KERNEL); 16362306a36Sopenharmony_ci if (!fp->rate_table) 16462306a36Sopenharmony_ci return -ENOMEM; 16562306a36Sopenharmony_ci fp->nr_rates = 1; 16662306a36Sopenharmony_ci fp->rate_min = rate; 16762306a36Sopenharmony_ci fp->rate_max = rate; 16862306a36Sopenharmony_ci fp->rates = rate_bits; 16962306a36Sopenharmony_ci fp->rate_table[0] = rate; 17062306a36Sopenharmony_ci return 0; 17162306a36Sopenharmony_ci} 17262306a36Sopenharmony_ci 17362306a36Sopenharmony_ci/* set up rate_min, rate_max and rates from the rate table */ 17462306a36Sopenharmony_cistatic void set_rate_table_min_max(struct audioformat *fp) 17562306a36Sopenharmony_ci{ 17662306a36Sopenharmony_ci unsigned int rate; 17762306a36Sopenharmony_ci int i; 17862306a36Sopenharmony_ci 17962306a36Sopenharmony_ci fp->rate_min = INT_MAX; 18062306a36Sopenharmony_ci fp->rate_max = 0; 18162306a36Sopenharmony_ci fp->rates = 0; 18262306a36Sopenharmony_ci for (i = 0; i < fp->nr_rates; i++) { 18362306a36Sopenharmony_ci rate = fp->rate_table[i]; 18462306a36Sopenharmony_ci fp->rate_min = min(fp->rate_min, rate); 18562306a36Sopenharmony_ci fp->rate_max = max(fp->rate_max, rate); 18662306a36Sopenharmony_ci fp->rates |= snd_pcm_rate_to_rate_bit(rate); 18762306a36Sopenharmony_ci } 18862306a36Sopenharmony_ci} 18962306a36Sopenharmony_ci 19062306a36Sopenharmony_ci/* 19162306a36Sopenharmony_ci * parse the format descriptor and stores the possible sample rates 19262306a36Sopenharmony_ci * on the audioformat table (audio class v1). 19362306a36Sopenharmony_ci * 19462306a36Sopenharmony_ci * @dev: usb device 19562306a36Sopenharmony_ci * @fp: audioformat record 19662306a36Sopenharmony_ci * @fmt: the format descriptor 19762306a36Sopenharmony_ci * @offset: the start offset of descriptor pointing the rate type 19862306a36Sopenharmony_ci * (7 for type I and II, 8 for type II) 19962306a36Sopenharmony_ci */ 20062306a36Sopenharmony_cistatic int parse_audio_format_rates_v1(struct snd_usb_audio *chip, struct audioformat *fp, 20162306a36Sopenharmony_ci unsigned char *fmt, int offset) 20262306a36Sopenharmony_ci{ 20362306a36Sopenharmony_ci int nr_rates = fmt[offset]; 20462306a36Sopenharmony_ci 20562306a36Sopenharmony_ci if (fmt[0] < offset + 1 + 3 * (nr_rates ? nr_rates : 2)) { 20662306a36Sopenharmony_ci usb_audio_err(chip, 20762306a36Sopenharmony_ci "%u:%d : invalid UAC_FORMAT_TYPE desc\n", 20862306a36Sopenharmony_ci fp->iface, fp->altsetting); 20962306a36Sopenharmony_ci return -EINVAL; 21062306a36Sopenharmony_ci } 21162306a36Sopenharmony_ci 21262306a36Sopenharmony_ci if (nr_rates) { 21362306a36Sopenharmony_ci /* 21462306a36Sopenharmony_ci * build the rate table and bitmap flags 21562306a36Sopenharmony_ci */ 21662306a36Sopenharmony_ci int r, idx; 21762306a36Sopenharmony_ci 21862306a36Sopenharmony_ci fp->rate_table = kmalloc_array(nr_rates, sizeof(int), 21962306a36Sopenharmony_ci GFP_KERNEL); 22062306a36Sopenharmony_ci if (fp->rate_table == NULL) 22162306a36Sopenharmony_ci return -ENOMEM; 22262306a36Sopenharmony_ci 22362306a36Sopenharmony_ci fp->nr_rates = 0; 22462306a36Sopenharmony_ci for (r = 0, idx = offset + 1; r < nr_rates; r++, idx += 3) { 22562306a36Sopenharmony_ci unsigned int rate = combine_triple(&fmt[idx]); 22662306a36Sopenharmony_ci if (!rate) 22762306a36Sopenharmony_ci continue; 22862306a36Sopenharmony_ci /* C-Media CM6501 mislabels its 96 kHz altsetting */ 22962306a36Sopenharmony_ci /* Terratec Aureon 7.1 USB C-Media 6206, too */ 23062306a36Sopenharmony_ci /* Ozone Z90 USB C-Media, too */ 23162306a36Sopenharmony_ci if (rate == 48000 && nr_rates == 1 && 23262306a36Sopenharmony_ci (chip->usb_id == USB_ID(0x0d8c, 0x0201) || 23362306a36Sopenharmony_ci chip->usb_id == USB_ID(0x0d8c, 0x0102) || 23462306a36Sopenharmony_ci chip->usb_id == USB_ID(0x0d8c, 0x0078) || 23562306a36Sopenharmony_ci chip->usb_id == USB_ID(0x0ccd, 0x00b1)) && 23662306a36Sopenharmony_ci fp->altsetting == 5 && fp->maxpacksize == 392) 23762306a36Sopenharmony_ci rate = 96000; 23862306a36Sopenharmony_ci /* Creative VF0420/VF0470 Live Cams report 16 kHz instead of 8kHz */ 23962306a36Sopenharmony_ci if (rate == 16000 && 24062306a36Sopenharmony_ci (chip->usb_id == USB_ID(0x041e, 0x4064) || 24162306a36Sopenharmony_ci chip->usb_id == USB_ID(0x041e, 0x4068))) 24262306a36Sopenharmony_ci rate = 8000; 24362306a36Sopenharmony_ci 24462306a36Sopenharmony_ci fp->rate_table[fp->nr_rates++] = rate; 24562306a36Sopenharmony_ci } 24662306a36Sopenharmony_ci if (!fp->nr_rates) { 24762306a36Sopenharmony_ci usb_audio_info(chip, 24862306a36Sopenharmony_ci "%u:%d: All rates were zero\n", 24962306a36Sopenharmony_ci fp->iface, fp->altsetting); 25062306a36Sopenharmony_ci return -EINVAL; 25162306a36Sopenharmony_ci } 25262306a36Sopenharmony_ci set_rate_table_min_max(fp); 25362306a36Sopenharmony_ci } else { 25462306a36Sopenharmony_ci /* continuous rates */ 25562306a36Sopenharmony_ci fp->rates = SNDRV_PCM_RATE_CONTINUOUS; 25662306a36Sopenharmony_ci fp->rate_min = combine_triple(&fmt[offset + 1]); 25762306a36Sopenharmony_ci fp->rate_max = combine_triple(&fmt[offset + 4]); 25862306a36Sopenharmony_ci } 25962306a36Sopenharmony_ci 26062306a36Sopenharmony_ci /* Jabra Evolve 65 headset */ 26162306a36Sopenharmony_ci if (chip->usb_id == USB_ID(0x0b0e, 0x030b)) { 26262306a36Sopenharmony_ci /* only 48kHz for playback while keeping 16kHz for capture */ 26362306a36Sopenharmony_ci if (fp->nr_rates != 1) 26462306a36Sopenharmony_ci return set_fixed_rate(fp, 48000, SNDRV_PCM_RATE_48000); 26562306a36Sopenharmony_ci } 26662306a36Sopenharmony_ci 26762306a36Sopenharmony_ci return 0; 26862306a36Sopenharmony_ci} 26962306a36Sopenharmony_ci 27062306a36Sopenharmony_ci 27162306a36Sopenharmony_ci/* 27262306a36Sopenharmony_ci * Presonus Studio 1810c supports a limited set of sampling 27362306a36Sopenharmony_ci * rates per altsetting but reports the full set each time. 27462306a36Sopenharmony_ci * If we don't filter out the unsupported rates and attempt 27562306a36Sopenharmony_ci * to configure the card, it will hang refusing to do any 27662306a36Sopenharmony_ci * further audio I/O until a hard reset is performed. 27762306a36Sopenharmony_ci * 27862306a36Sopenharmony_ci * The list of supported rates per altsetting (set of available 27962306a36Sopenharmony_ci * I/O channels) is described in the owner's manual, section 2.2. 28062306a36Sopenharmony_ci */ 28162306a36Sopenharmony_cistatic bool s1810c_valid_sample_rate(struct audioformat *fp, 28262306a36Sopenharmony_ci unsigned int rate) 28362306a36Sopenharmony_ci{ 28462306a36Sopenharmony_ci switch (fp->altsetting) { 28562306a36Sopenharmony_ci case 1: 28662306a36Sopenharmony_ci /* All ADAT ports available */ 28762306a36Sopenharmony_ci return rate <= 48000; 28862306a36Sopenharmony_ci case 2: 28962306a36Sopenharmony_ci /* Half of ADAT ports available */ 29062306a36Sopenharmony_ci return (rate == 88200 || rate == 96000); 29162306a36Sopenharmony_ci case 3: 29262306a36Sopenharmony_ci /* Analog I/O only (no S/PDIF nor ADAT) */ 29362306a36Sopenharmony_ci return rate >= 176400; 29462306a36Sopenharmony_ci default: 29562306a36Sopenharmony_ci return false; 29662306a36Sopenharmony_ci } 29762306a36Sopenharmony_ci return false; 29862306a36Sopenharmony_ci} 29962306a36Sopenharmony_ci 30062306a36Sopenharmony_ci/* 30162306a36Sopenharmony_ci * Many Focusrite devices supports a limited set of sampling rates per 30262306a36Sopenharmony_ci * altsetting. Maximum rate is exposed in the last 4 bytes of Format Type 30362306a36Sopenharmony_ci * descriptor which has a non-standard bLength = 10. 30462306a36Sopenharmony_ci */ 30562306a36Sopenharmony_cistatic bool focusrite_valid_sample_rate(struct snd_usb_audio *chip, 30662306a36Sopenharmony_ci struct audioformat *fp, 30762306a36Sopenharmony_ci unsigned int rate) 30862306a36Sopenharmony_ci{ 30962306a36Sopenharmony_ci struct usb_interface *iface; 31062306a36Sopenharmony_ci struct usb_host_interface *alts; 31162306a36Sopenharmony_ci unsigned char *fmt; 31262306a36Sopenharmony_ci unsigned int max_rate; 31362306a36Sopenharmony_ci 31462306a36Sopenharmony_ci iface = usb_ifnum_to_if(chip->dev, fp->iface); 31562306a36Sopenharmony_ci if (!iface) 31662306a36Sopenharmony_ci return true; 31762306a36Sopenharmony_ci 31862306a36Sopenharmony_ci alts = &iface->altsetting[fp->altset_idx]; 31962306a36Sopenharmony_ci fmt = snd_usb_find_csint_desc(alts->extra, alts->extralen, 32062306a36Sopenharmony_ci NULL, UAC_FORMAT_TYPE); 32162306a36Sopenharmony_ci if (!fmt) 32262306a36Sopenharmony_ci return true; 32362306a36Sopenharmony_ci 32462306a36Sopenharmony_ci if (fmt[0] == 10) { /* bLength */ 32562306a36Sopenharmony_ci max_rate = combine_quad(&fmt[6]); 32662306a36Sopenharmony_ci 32762306a36Sopenharmony_ci /* Validate max rate */ 32862306a36Sopenharmony_ci if (max_rate != 48000 && 32962306a36Sopenharmony_ci max_rate != 96000 && 33062306a36Sopenharmony_ci max_rate != 192000 && 33162306a36Sopenharmony_ci max_rate != 384000) { 33262306a36Sopenharmony_ci 33362306a36Sopenharmony_ci usb_audio_info(chip, 33462306a36Sopenharmony_ci "%u:%d : unexpected max rate: %u\n", 33562306a36Sopenharmony_ci fp->iface, fp->altsetting, max_rate); 33662306a36Sopenharmony_ci 33762306a36Sopenharmony_ci return true; 33862306a36Sopenharmony_ci } 33962306a36Sopenharmony_ci 34062306a36Sopenharmony_ci return rate <= max_rate; 34162306a36Sopenharmony_ci } 34262306a36Sopenharmony_ci 34362306a36Sopenharmony_ci return true; 34462306a36Sopenharmony_ci} 34562306a36Sopenharmony_ci 34662306a36Sopenharmony_ci/* 34762306a36Sopenharmony_ci * Helper function to walk the array of sample rate triplets reported by 34862306a36Sopenharmony_ci * the device. The problem is that we need to parse whole array first to 34962306a36Sopenharmony_ci * get to know how many sample rates we have to expect. 35062306a36Sopenharmony_ci * Then fp->rate_table can be allocated and filled. 35162306a36Sopenharmony_ci */ 35262306a36Sopenharmony_cistatic int parse_uac2_sample_rate_range(struct snd_usb_audio *chip, 35362306a36Sopenharmony_ci struct audioformat *fp, int nr_triplets, 35462306a36Sopenharmony_ci const unsigned char *data) 35562306a36Sopenharmony_ci{ 35662306a36Sopenharmony_ci int i, nr_rates = 0; 35762306a36Sopenharmony_ci 35862306a36Sopenharmony_ci for (i = 0; i < nr_triplets; i++) { 35962306a36Sopenharmony_ci int min = combine_quad(&data[2 + 12 * i]); 36062306a36Sopenharmony_ci int max = combine_quad(&data[6 + 12 * i]); 36162306a36Sopenharmony_ci int res = combine_quad(&data[10 + 12 * i]); 36262306a36Sopenharmony_ci unsigned int rate; 36362306a36Sopenharmony_ci 36462306a36Sopenharmony_ci if ((max < 0) || (min < 0) || (res < 0) || (max < min)) 36562306a36Sopenharmony_ci continue; 36662306a36Sopenharmony_ci 36762306a36Sopenharmony_ci /* 36862306a36Sopenharmony_ci * for ranges with res == 1, we announce a continuous sample 36962306a36Sopenharmony_ci * rate range, and this function should return 0 for no further 37062306a36Sopenharmony_ci * parsing. 37162306a36Sopenharmony_ci */ 37262306a36Sopenharmony_ci if (res == 1) { 37362306a36Sopenharmony_ci fp->rate_min = min; 37462306a36Sopenharmony_ci fp->rate_max = max; 37562306a36Sopenharmony_ci fp->rates = SNDRV_PCM_RATE_CONTINUOUS; 37662306a36Sopenharmony_ci return 0; 37762306a36Sopenharmony_ci } 37862306a36Sopenharmony_ci 37962306a36Sopenharmony_ci for (rate = min; rate <= max; rate += res) { 38062306a36Sopenharmony_ci 38162306a36Sopenharmony_ci /* Filter out invalid rates on Presonus Studio 1810c */ 38262306a36Sopenharmony_ci if (chip->usb_id == USB_ID(0x194f, 0x010c) && 38362306a36Sopenharmony_ci !s1810c_valid_sample_rate(fp, rate)) 38462306a36Sopenharmony_ci goto skip_rate; 38562306a36Sopenharmony_ci 38662306a36Sopenharmony_ci /* Filter out invalid rates on Focusrite devices */ 38762306a36Sopenharmony_ci if (USB_ID_VENDOR(chip->usb_id) == 0x1235 && 38862306a36Sopenharmony_ci !focusrite_valid_sample_rate(chip, fp, rate)) 38962306a36Sopenharmony_ci goto skip_rate; 39062306a36Sopenharmony_ci 39162306a36Sopenharmony_ci if (fp->rate_table) 39262306a36Sopenharmony_ci fp->rate_table[nr_rates] = rate; 39362306a36Sopenharmony_ci nr_rates++; 39462306a36Sopenharmony_ci if (nr_rates >= MAX_NR_RATES) { 39562306a36Sopenharmony_ci usb_audio_err(chip, "invalid uac2 rates\n"); 39662306a36Sopenharmony_ci break; 39762306a36Sopenharmony_ci } 39862306a36Sopenharmony_ci 39962306a36Sopenharmony_ciskip_rate: 40062306a36Sopenharmony_ci /* avoid endless loop */ 40162306a36Sopenharmony_ci if (res == 0) 40262306a36Sopenharmony_ci break; 40362306a36Sopenharmony_ci } 40462306a36Sopenharmony_ci } 40562306a36Sopenharmony_ci 40662306a36Sopenharmony_ci return nr_rates; 40762306a36Sopenharmony_ci} 40862306a36Sopenharmony_ci 40962306a36Sopenharmony_ci/* Line6 Helix series and the Rode Rodecaster Pro don't support the 41062306a36Sopenharmony_ci * UAC2_CS_RANGE usb function call. Return a static table of known 41162306a36Sopenharmony_ci * clock rates. 41262306a36Sopenharmony_ci */ 41362306a36Sopenharmony_cistatic int line6_parse_audio_format_rates_quirk(struct snd_usb_audio *chip, 41462306a36Sopenharmony_ci struct audioformat *fp) 41562306a36Sopenharmony_ci{ 41662306a36Sopenharmony_ci switch (chip->usb_id) { 41762306a36Sopenharmony_ci case USB_ID(0x0e41, 0x4241): /* Line6 Helix */ 41862306a36Sopenharmony_ci case USB_ID(0x0e41, 0x4242): /* Line6 Helix Rack */ 41962306a36Sopenharmony_ci case USB_ID(0x0e41, 0x4244): /* Line6 Helix LT */ 42062306a36Sopenharmony_ci case USB_ID(0x0e41, 0x4246): /* Line6 HX-Stomp */ 42162306a36Sopenharmony_ci case USB_ID(0x0e41, 0x4253): /* Line6 HX-Stomp XL */ 42262306a36Sopenharmony_ci case USB_ID(0x0e41, 0x4247): /* Line6 Pod Go */ 42362306a36Sopenharmony_ci case USB_ID(0x0e41, 0x4248): /* Line6 Helix >= fw 2.82 */ 42462306a36Sopenharmony_ci case USB_ID(0x0e41, 0x4249): /* Line6 Helix Rack >= fw 2.82 */ 42562306a36Sopenharmony_ci case USB_ID(0x0e41, 0x424a): /* Line6 Helix LT >= fw 2.82 */ 42662306a36Sopenharmony_ci case USB_ID(0x0e41, 0x424b): /* Line6 Pod Go */ 42762306a36Sopenharmony_ci case USB_ID(0x19f7, 0x0011): /* Rode Rodecaster Pro */ 42862306a36Sopenharmony_ci return set_fixed_rate(fp, 48000, SNDRV_PCM_RATE_48000); 42962306a36Sopenharmony_ci } 43062306a36Sopenharmony_ci 43162306a36Sopenharmony_ci return -ENODEV; 43262306a36Sopenharmony_ci} 43362306a36Sopenharmony_ci 43462306a36Sopenharmony_ci/* check whether the given altsetting is supported for the already set rate */ 43562306a36Sopenharmony_cistatic bool check_valid_altsetting_v2v3(struct snd_usb_audio *chip, int iface, 43662306a36Sopenharmony_ci int altsetting) 43762306a36Sopenharmony_ci{ 43862306a36Sopenharmony_ci struct usb_device *dev = chip->dev; 43962306a36Sopenharmony_ci __le64 raw_data = 0; 44062306a36Sopenharmony_ci u64 data; 44162306a36Sopenharmony_ci int err; 44262306a36Sopenharmony_ci 44362306a36Sopenharmony_ci /* we assume 64bit is enough for any altsettings */ 44462306a36Sopenharmony_ci if (snd_BUG_ON(altsetting >= 64 - 8)) 44562306a36Sopenharmony_ci return false; 44662306a36Sopenharmony_ci 44762306a36Sopenharmony_ci err = snd_usb_ctl_msg(dev, usb_rcvctrlpipe(dev, 0), UAC2_CS_CUR, 44862306a36Sopenharmony_ci USB_TYPE_CLASS | USB_RECIP_INTERFACE | USB_DIR_IN, 44962306a36Sopenharmony_ci UAC2_AS_VAL_ALT_SETTINGS << 8, 45062306a36Sopenharmony_ci iface, &raw_data, sizeof(raw_data)); 45162306a36Sopenharmony_ci if (err < 0) 45262306a36Sopenharmony_ci return false; 45362306a36Sopenharmony_ci 45462306a36Sopenharmony_ci data = le64_to_cpu(raw_data); 45562306a36Sopenharmony_ci /* first byte contains the bitmap size */ 45662306a36Sopenharmony_ci if ((data & 0xff) * 8 < altsetting) 45762306a36Sopenharmony_ci return false; 45862306a36Sopenharmony_ci if (data & (1ULL << (altsetting + 8))) 45962306a36Sopenharmony_ci return true; 46062306a36Sopenharmony_ci 46162306a36Sopenharmony_ci return false; 46262306a36Sopenharmony_ci} 46362306a36Sopenharmony_ci 46462306a36Sopenharmony_ci/* 46562306a36Sopenharmony_ci * Validate each sample rate with the altsetting 46662306a36Sopenharmony_ci * Rebuild the rate table if only partial values are valid 46762306a36Sopenharmony_ci */ 46862306a36Sopenharmony_cistatic int validate_sample_rate_table_v2v3(struct snd_usb_audio *chip, 46962306a36Sopenharmony_ci struct audioformat *fp, 47062306a36Sopenharmony_ci int clock) 47162306a36Sopenharmony_ci{ 47262306a36Sopenharmony_ci struct usb_device *dev = chip->dev; 47362306a36Sopenharmony_ci struct usb_host_interface *alts; 47462306a36Sopenharmony_ci unsigned int *table; 47562306a36Sopenharmony_ci unsigned int nr_rates; 47662306a36Sopenharmony_ci int i, err; 47762306a36Sopenharmony_ci u32 bmControls; 47862306a36Sopenharmony_ci 47962306a36Sopenharmony_ci /* performing the rate verification may lead to unexpected USB bus 48062306a36Sopenharmony_ci * behavior afterwards by some unknown reason. Do this only for the 48162306a36Sopenharmony_ci * known devices. 48262306a36Sopenharmony_ci */ 48362306a36Sopenharmony_ci if (!(chip->quirk_flags & QUIRK_FLAG_VALIDATE_RATES)) 48462306a36Sopenharmony_ci return 0; /* don't perform the validation as default */ 48562306a36Sopenharmony_ci 48662306a36Sopenharmony_ci alts = snd_usb_get_host_interface(chip, fp->iface, fp->altsetting); 48762306a36Sopenharmony_ci if (!alts) 48862306a36Sopenharmony_ci return 0; 48962306a36Sopenharmony_ci 49062306a36Sopenharmony_ci if (fp->protocol == UAC_VERSION_3) { 49162306a36Sopenharmony_ci struct uac3_as_header_descriptor *as = snd_usb_find_csint_desc( 49262306a36Sopenharmony_ci alts->extra, alts->extralen, NULL, UAC_AS_GENERAL); 49362306a36Sopenharmony_ci bmControls = le32_to_cpu(as->bmControls); 49462306a36Sopenharmony_ci } else { 49562306a36Sopenharmony_ci struct uac2_as_header_descriptor *as = snd_usb_find_csint_desc( 49662306a36Sopenharmony_ci alts->extra, alts->extralen, NULL, UAC_AS_GENERAL); 49762306a36Sopenharmony_ci bmControls = as->bmControls; 49862306a36Sopenharmony_ci } 49962306a36Sopenharmony_ci 50062306a36Sopenharmony_ci if (!uac_v2v3_control_is_readable(bmControls, 50162306a36Sopenharmony_ci UAC2_AS_VAL_ALT_SETTINGS)) 50262306a36Sopenharmony_ci return 0; 50362306a36Sopenharmony_ci 50462306a36Sopenharmony_ci table = kcalloc(fp->nr_rates, sizeof(*table), GFP_KERNEL); 50562306a36Sopenharmony_ci if (!table) 50662306a36Sopenharmony_ci return -ENOMEM; 50762306a36Sopenharmony_ci 50862306a36Sopenharmony_ci /* clear the interface altsetting at first */ 50962306a36Sopenharmony_ci usb_set_interface(dev, fp->iface, 0); 51062306a36Sopenharmony_ci 51162306a36Sopenharmony_ci nr_rates = 0; 51262306a36Sopenharmony_ci for (i = 0; i < fp->nr_rates; i++) { 51362306a36Sopenharmony_ci err = snd_usb_set_sample_rate_v2v3(chip, fp, clock, 51462306a36Sopenharmony_ci fp->rate_table[i]); 51562306a36Sopenharmony_ci if (err < 0) 51662306a36Sopenharmony_ci continue; 51762306a36Sopenharmony_ci 51862306a36Sopenharmony_ci if (check_valid_altsetting_v2v3(chip, fp->iface, fp->altsetting)) 51962306a36Sopenharmony_ci table[nr_rates++] = fp->rate_table[i]; 52062306a36Sopenharmony_ci } 52162306a36Sopenharmony_ci 52262306a36Sopenharmony_ci if (!nr_rates) { 52362306a36Sopenharmony_ci usb_audio_dbg(chip, 52462306a36Sopenharmony_ci "No valid sample rate available for %d:%d, assuming a firmware bug\n", 52562306a36Sopenharmony_ci fp->iface, fp->altsetting); 52662306a36Sopenharmony_ci nr_rates = fp->nr_rates; /* continue as is */ 52762306a36Sopenharmony_ci } 52862306a36Sopenharmony_ci 52962306a36Sopenharmony_ci if (fp->nr_rates == nr_rates) { 53062306a36Sopenharmony_ci kfree(table); 53162306a36Sopenharmony_ci return 0; 53262306a36Sopenharmony_ci } 53362306a36Sopenharmony_ci 53462306a36Sopenharmony_ci kfree(fp->rate_table); 53562306a36Sopenharmony_ci fp->rate_table = table; 53662306a36Sopenharmony_ci fp->nr_rates = nr_rates; 53762306a36Sopenharmony_ci return 0; 53862306a36Sopenharmony_ci} 53962306a36Sopenharmony_ci 54062306a36Sopenharmony_ci/* 54162306a36Sopenharmony_ci * parse the format descriptor and stores the possible sample rates 54262306a36Sopenharmony_ci * on the audioformat table (audio class v2 and v3). 54362306a36Sopenharmony_ci */ 54462306a36Sopenharmony_cistatic int parse_audio_format_rates_v2v3(struct snd_usb_audio *chip, 54562306a36Sopenharmony_ci struct audioformat *fp) 54662306a36Sopenharmony_ci{ 54762306a36Sopenharmony_ci struct usb_device *dev = chip->dev; 54862306a36Sopenharmony_ci unsigned char tmp[2], *data; 54962306a36Sopenharmony_ci int nr_triplets, data_size, ret = 0, ret_l6; 55062306a36Sopenharmony_ci int clock = snd_usb_clock_find_source(chip, fp, false); 55162306a36Sopenharmony_ci 55262306a36Sopenharmony_ci if (clock < 0) { 55362306a36Sopenharmony_ci dev_err(&dev->dev, 55462306a36Sopenharmony_ci "%s(): unable to find clock source (clock %d)\n", 55562306a36Sopenharmony_ci __func__, clock); 55662306a36Sopenharmony_ci goto err; 55762306a36Sopenharmony_ci } 55862306a36Sopenharmony_ci 55962306a36Sopenharmony_ci /* get the number of sample rates first by only fetching 2 bytes */ 56062306a36Sopenharmony_ci ret = snd_usb_ctl_msg(dev, usb_rcvctrlpipe(dev, 0), UAC2_CS_RANGE, 56162306a36Sopenharmony_ci USB_TYPE_CLASS | USB_RECIP_INTERFACE | USB_DIR_IN, 56262306a36Sopenharmony_ci UAC2_CS_CONTROL_SAM_FREQ << 8, 56362306a36Sopenharmony_ci snd_usb_ctrl_intf(chip) | (clock << 8), 56462306a36Sopenharmony_ci tmp, sizeof(tmp)); 56562306a36Sopenharmony_ci 56662306a36Sopenharmony_ci if (ret < 0) { 56762306a36Sopenharmony_ci /* line6 helix devices don't support UAC2_CS_CONTROL_SAM_FREQ call */ 56862306a36Sopenharmony_ci ret_l6 = line6_parse_audio_format_rates_quirk(chip, fp); 56962306a36Sopenharmony_ci if (ret_l6 == -ENODEV) { 57062306a36Sopenharmony_ci /* no line6 device found continue showing the error */ 57162306a36Sopenharmony_ci dev_err(&dev->dev, 57262306a36Sopenharmony_ci "%s(): unable to retrieve number of sample rates (clock %d)\n", 57362306a36Sopenharmony_ci __func__, clock); 57462306a36Sopenharmony_ci goto err; 57562306a36Sopenharmony_ci } 57662306a36Sopenharmony_ci if (ret_l6 == 0) { 57762306a36Sopenharmony_ci dev_info(&dev->dev, 57862306a36Sopenharmony_ci "%s(): unable to retrieve number of sample rates: set it to a predefined value (clock %d).\n", 57962306a36Sopenharmony_ci __func__, clock); 58062306a36Sopenharmony_ci return 0; 58162306a36Sopenharmony_ci } 58262306a36Sopenharmony_ci ret = ret_l6; 58362306a36Sopenharmony_ci goto err; 58462306a36Sopenharmony_ci } 58562306a36Sopenharmony_ci 58662306a36Sopenharmony_ci nr_triplets = (tmp[1] << 8) | tmp[0]; 58762306a36Sopenharmony_ci data_size = 2 + 12 * nr_triplets; 58862306a36Sopenharmony_ci data = kzalloc(data_size, GFP_KERNEL); 58962306a36Sopenharmony_ci if (!data) { 59062306a36Sopenharmony_ci ret = -ENOMEM; 59162306a36Sopenharmony_ci goto err; 59262306a36Sopenharmony_ci } 59362306a36Sopenharmony_ci 59462306a36Sopenharmony_ci /* now get the full information */ 59562306a36Sopenharmony_ci ret = snd_usb_ctl_msg(dev, usb_rcvctrlpipe(dev, 0), UAC2_CS_RANGE, 59662306a36Sopenharmony_ci USB_TYPE_CLASS | USB_RECIP_INTERFACE | USB_DIR_IN, 59762306a36Sopenharmony_ci UAC2_CS_CONTROL_SAM_FREQ << 8, 59862306a36Sopenharmony_ci snd_usb_ctrl_intf(chip) | (clock << 8), 59962306a36Sopenharmony_ci data, data_size); 60062306a36Sopenharmony_ci 60162306a36Sopenharmony_ci if (ret < 0) { 60262306a36Sopenharmony_ci dev_err(&dev->dev, 60362306a36Sopenharmony_ci "%s(): unable to retrieve sample rate range (clock %d)\n", 60462306a36Sopenharmony_ci __func__, clock); 60562306a36Sopenharmony_ci ret = -EINVAL; 60662306a36Sopenharmony_ci goto err_free; 60762306a36Sopenharmony_ci } 60862306a36Sopenharmony_ci 60962306a36Sopenharmony_ci /* Call the triplet parser, and make sure fp->rate_table is NULL. 61062306a36Sopenharmony_ci * We just use the return value to know how many sample rates we 61162306a36Sopenharmony_ci * will have to deal with. */ 61262306a36Sopenharmony_ci kfree(fp->rate_table); 61362306a36Sopenharmony_ci fp->rate_table = NULL; 61462306a36Sopenharmony_ci fp->nr_rates = parse_uac2_sample_rate_range(chip, fp, nr_triplets, data); 61562306a36Sopenharmony_ci 61662306a36Sopenharmony_ci if (fp->nr_rates == 0) { 61762306a36Sopenharmony_ci /* SNDRV_PCM_RATE_CONTINUOUS */ 61862306a36Sopenharmony_ci ret = 0; 61962306a36Sopenharmony_ci goto err_free; 62062306a36Sopenharmony_ci } 62162306a36Sopenharmony_ci 62262306a36Sopenharmony_ci fp->rate_table = kmalloc_array(fp->nr_rates, sizeof(int), GFP_KERNEL); 62362306a36Sopenharmony_ci if (!fp->rate_table) { 62462306a36Sopenharmony_ci ret = -ENOMEM; 62562306a36Sopenharmony_ci goto err_free; 62662306a36Sopenharmony_ci } 62762306a36Sopenharmony_ci 62862306a36Sopenharmony_ci /* Call the triplet parser again, but this time, fp->rate_table is 62962306a36Sopenharmony_ci * allocated, so the rates will be stored */ 63062306a36Sopenharmony_ci parse_uac2_sample_rate_range(chip, fp, nr_triplets, data); 63162306a36Sopenharmony_ci 63262306a36Sopenharmony_ci ret = validate_sample_rate_table_v2v3(chip, fp, clock); 63362306a36Sopenharmony_ci if (ret < 0) 63462306a36Sopenharmony_ci goto err_free; 63562306a36Sopenharmony_ci 63662306a36Sopenharmony_ci set_rate_table_min_max(fp); 63762306a36Sopenharmony_ci 63862306a36Sopenharmony_cierr_free: 63962306a36Sopenharmony_ci kfree(data); 64062306a36Sopenharmony_cierr: 64162306a36Sopenharmony_ci return ret; 64262306a36Sopenharmony_ci} 64362306a36Sopenharmony_ci 64462306a36Sopenharmony_ci/* 64562306a36Sopenharmony_ci * parse the format type I and III descriptors 64662306a36Sopenharmony_ci */ 64762306a36Sopenharmony_cistatic int parse_audio_format_i(struct snd_usb_audio *chip, 64862306a36Sopenharmony_ci struct audioformat *fp, u64 format, 64962306a36Sopenharmony_ci void *_fmt) 65062306a36Sopenharmony_ci{ 65162306a36Sopenharmony_ci snd_pcm_format_t pcm_format; 65262306a36Sopenharmony_ci unsigned int fmt_type; 65362306a36Sopenharmony_ci int ret; 65462306a36Sopenharmony_ci 65562306a36Sopenharmony_ci switch (fp->protocol) { 65662306a36Sopenharmony_ci default: 65762306a36Sopenharmony_ci case UAC_VERSION_1: 65862306a36Sopenharmony_ci case UAC_VERSION_2: { 65962306a36Sopenharmony_ci struct uac_format_type_i_continuous_descriptor *fmt = _fmt; 66062306a36Sopenharmony_ci 66162306a36Sopenharmony_ci fmt_type = fmt->bFormatType; 66262306a36Sopenharmony_ci break; 66362306a36Sopenharmony_ci } 66462306a36Sopenharmony_ci case UAC_VERSION_3: { 66562306a36Sopenharmony_ci /* fp->fmt_type is already set in this case */ 66662306a36Sopenharmony_ci fmt_type = fp->fmt_type; 66762306a36Sopenharmony_ci break; 66862306a36Sopenharmony_ci } 66962306a36Sopenharmony_ci } 67062306a36Sopenharmony_ci 67162306a36Sopenharmony_ci if (fmt_type == UAC_FORMAT_TYPE_III) { 67262306a36Sopenharmony_ci /* FIXME: the format type is really IECxxx 67362306a36Sopenharmony_ci * but we give normal PCM format to get the existing 67462306a36Sopenharmony_ci * apps working... 67562306a36Sopenharmony_ci */ 67662306a36Sopenharmony_ci switch (chip->usb_id) { 67762306a36Sopenharmony_ci 67862306a36Sopenharmony_ci case USB_ID(0x0763, 0x2003): /* M-Audio Audiophile USB */ 67962306a36Sopenharmony_ci if (chip->setup == 0x00 && 68062306a36Sopenharmony_ci fp->altsetting == 6) 68162306a36Sopenharmony_ci pcm_format = SNDRV_PCM_FORMAT_S16_BE; 68262306a36Sopenharmony_ci else 68362306a36Sopenharmony_ci pcm_format = SNDRV_PCM_FORMAT_S16_LE; 68462306a36Sopenharmony_ci break; 68562306a36Sopenharmony_ci default: 68662306a36Sopenharmony_ci pcm_format = SNDRV_PCM_FORMAT_S16_LE; 68762306a36Sopenharmony_ci } 68862306a36Sopenharmony_ci fp->formats = pcm_format_to_bits(pcm_format); 68962306a36Sopenharmony_ci } else { 69062306a36Sopenharmony_ci fp->formats = parse_audio_format_i_type(chip, fp, format, _fmt); 69162306a36Sopenharmony_ci if (!fp->formats) 69262306a36Sopenharmony_ci return -EINVAL; 69362306a36Sopenharmony_ci } 69462306a36Sopenharmony_ci 69562306a36Sopenharmony_ci /* gather possible sample rates */ 69662306a36Sopenharmony_ci /* audio class v1 reports possible sample rates as part of the 69762306a36Sopenharmony_ci * proprietary class specific descriptor. 69862306a36Sopenharmony_ci * audio class v2 uses class specific EP0 range requests for that. 69962306a36Sopenharmony_ci */ 70062306a36Sopenharmony_ci switch (fp->protocol) { 70162306a36Sopenharmony_ci default: 70262306a36Sopenharmony_ci case UAC_VERSION_1: { 70362306a36Sopenharmony_ci struct uac_format_type_i_continuous_descriptor *fmt = _fmt; 70462306a36Sopenharmony_ci 70562306a36Sopenharmony_ci fp->channels = fmt->bNrChannels; 70662306a36Sopenharmony_ci ret = parse_audio_format_rates_v1(chip, fp, (unsigned char *) fmt, 7); 70762306a36Sopenharmony_ci break; 70862306a36Sopenharmony_ci } 70962306a36Sopenharmony_ci case UAC_VERSION_2: 71062306a36Sopenharmony_ci case UAC_VERSION_3: { 71162306a36Sopenharmony_ci /* fp->channels is already set in this case */ 71262306a36Sopenharmony_ci ret = parse_audio_format_rates_v2v3(chip, fp); 71362306a36Sopenharmony_ci break; 71462306a36Sopenharmony_ci } 71562306a36Sopenharmony_ci } 71662306a36Sopenharmony_ci 71762306a36Sopenharmony_ci if (fp->channels < 1) { 71862306a36Sopenharmony_ci usb_audio_err(chip, 71962306a36Sopenharmony_ci "%u:%d : invalid channels %d\n", 72062306a36Sopenharmony_ci fp->iface, fp->altsetting, fp->channels); 72162306a36Sopenharmony_ci return -EINVAL; 72262306a36Sopenharmony_ci } 72362306a36Sopenharmony_ci 72462306a36Sopenharmony_ci return ret; 72562306a36Sopenharmony_ci} 72662306a36Sopenharmony_ci 72762306a36Sopenharmony_ci/* 72862306a36Sopenharmony_ci * parse the format type II descriptor 72962306a36Sopenharmony_ci */ 73062306a36Sopenharmony_cistatic int parse_audio_format_ii(struct snd_usb_audio *chip, 73162306a36Sopenharmony_ci struct audioformat *fp, 73262306a36Sopenharmony_ci u64 format, void *_fmt) 73362306a36Sopenharmony_ci{ 73462306a36Sopenharmony_ci int brate, framesize, ret; 73562306a36Sopenharmony_ci 73662306a36Sopenharmony_ci switch (format) { 73762306a36Sopenharmony_ci case UAC_FORMAT_TYPE_II_AC3: 73862306a36Sopenharmony_ci /* FIXME: there is no AC3 format defined yet */ 73962306a36Sopenharmony_ci // fp->formats = SNDRV_PCM_FMTBIT_AC3; 74062306a36Sopenharmony_ci fp->formats = SNDRV_PCM_FMTBIT_U8; /* temporary hack to receive byte streams */ 74162306a36Sopenharmony_ci break; 74262306a36Sopenharmony_ci case UAC_FORMAT_TYPE_II_MPEG: 74362306a36Sopenharmony_ci fp->formats = SNDRV_PCM_FMTBIT_MPEG; 74462306a36Sopenharmony_ci break; 74562306a36Sopenharmony_ci default: 74662306a36Sopenharmony_ci usb_audio_info(chip, 74762306a36Sopenharmony_ci "%u:%d : unknown format tag %#llx is detected. processed as MPEG.\n", 74862306a36Sopenharmony_ci fp->iface, fp->altsetting, format); 74962306a36Sopenharmony_ci fp->formats = SNDRV_PCM_FMTBIT_MPEG; 75062306a36Sopenharmony_ci break; 75162306a36Sopenharmony_ci } 75262306a36Sopenharmony_ci 75362306a36Sopenharmony_ci fp->channels = 1; 75462306a36Sopenharmony_ci 75562306a36Sopenharmony_ci switch (fp->protocol) { 75662306a36Sopenharmony_ci default: 75762306a36Sopenharmony_ci case UAC_VERSION_1: { 75862306a36Sopenharmony_ci struct uac_format_type_ii_discrete_descriptor *fmt = _fmt; 75962306a36Sopenharmony_ci brate = le16_to_cpu(fmt->wMaxBitRate); 76062306a36Sopenharmony_ci framesize = le16_to_cpu(fmt->wSamplesPerFrame); 76162306a36Sopenharmony_ci usb_audio_info(chip, "found format II with max.bitrate = %d, frame size=%d\n", brate, framesize); 76262306a36Sopenharmony_ci fp->frame_size = framesize; 76362306a36Sopenharmony_ci ret = parse_audio_format_rates_v1(chip, fp, _fmt, 8); /* fmt[8..] sample rates */ 76462306a36Sopenharmony_ci break; 76562306a36Sopenharmony_ci } 76662306a36Sopenharmony_ci case UAC_VERSION_2: { 76762306a36Sopenharmony_ci struct uac_format_type_ii_ext_descriptor *fmt = _fmt; 76862306a36Sopenharmony_ci brate = le16_to_cpu(fmt->wMaxBitRate); 76962306a36Sopenharmony_ci framesize = le16_to_cpu(fmt->wSamplesPerFrame); 77062306a36Sopenharmony_ci usb_audio_info(chip, "found format II with max.bitrate = %d, frame size=%d\n", brate, framesize); 77162306a36Sopenharmony_ci fp->frame_size = framesize; 77262306a36Sopenharmony_ci ret = parse_audio_format_rates_v2v3(chip, fp); 77362306a36Sopenharmony_ci break; 77462306a36Sopenharmony_ci } 77562306a36Sopenharmony_ci } 77662306a36Sopenharmony_ci 77762306a36Sopenharmony_ci return ret; 77862306a36Sopenharmony_ci} 77962306a36Sopenharmony_ci 78062306a36Sopenharmony_ciint snd_usb_parse_audio_format(struct snd_usb_audio *chip, 78162306a36Sopenharmony_ci struct audioformat *fp, u64 format, 78262306a36Sopenharmony_ci struct uac_format_type_i_continuous_descriptor *fmt, 78362306a36Sopenharmony_ci int stream) 78462306a36Sopenharmony_ci{ 78562306a36Sopenharmony_ci int err; 78662306a36Sopenharmony_ci 78762306a36Sopenharmony_ci switch (fmt->bFormatType) { 78862306a36Sopenharmony_ci case UAC_FORMAT_TYPE_I: 78962306a36Sopenharmony_ci case UAC_FORMAT_TYPE_III: 79062306a36Sopenharmony_ci err = parse_audio_format_i(chip, fp, format, fmt); 79162306a36Sopenharmony_ci break; 79262306a36Sopenharmony_ci case UAC_FORMAT_TYPE_II: 79362306a36Sopenharmony_ci err = parse_audio_format_ii(chip, fp, format, fmt); 79462306a36Sopenharmony_ci break; 79562306a36Sopenharmony_ci default: 79662306a36Sopenharmony_ci usb_audio_info(chip, 79762306a36Sopenharmony_ci "%u:%d : format type %d is not supported yet\n", 79862306a36Sopenharmony_ci fp->iface, fp->altsetting, 79962306a36Sopenharmony_ci fmt->bFormatType); 80062306a36Sopenharmony_ci return -ENOTSUPP; 80162306a36Sopenharmony_ci } 80262306a36Sopenharmony_ci fp->fmt_type = fmt->bFormatType; 80362306a36Sopenharmony_ci if (err < 0) 80462306a36Sopenharmony_ci return err; 80562306a36Sopenharmony_ci#if 1 80662306a36Sopenharmony_ci /* FIXME: temporary hack for extigy/audigy 2 nx/zs */ 80762306a36Sopenharmony_ci /* extigy apparently supports sample rates other than 48k 80862306a36Sopenharmony_ci * but not in ordinary way. so we enable only 48k atm. 80962306a36Sopenharmony_ci */ 81062306a36Sopenharmony_ci if (chip->usb_id == USB_ID(0x041e, 0x3000) || 81162306a36Sopenharmony_ci chip->usb_id == USB_ID(0x041e, 0x3020) || 81262306a36Sopenharmony_ci chip->usb_id == USB_ID(0x041e, 0x3061)) { 81362306a36Sopenharmony_ci if (fmt->bFormatType == UAC_FORMAT_TYPE_I && 81462306a36Sopenharmony_ci fp->rates != SNDRV_PCM_RATE_48000 && 81562306a36Sopenharmony_ci fp->rates != SNDRV_PCM_RATE_96000) 81662306a36Sopenharmony_ci return -ENOTSUPP; 81762306a36Sopenharmony_ci } 81862306a36Sopenharmony_ci#endif 81962306a36Sopenharmony_ci return 0; 82062306a36Sopenharmony_ci} 82162306a36Sopenharmony_ci 82262306a36Sopenharmony_ciint snd_usb_parse_audio_format_v3(struct snd_usb_audio *chip, 82362306a36Sopenharmony_ci struct audioformat *fp, 82462306a36Sopenharmony_ci struct uac3_as_header_descriptor *as, 82562306a36Sopenharmony_ci int stream) 82662306a36Sopenharmony_ci{ 82762306a36Sopenharmony_ci u64 format = le64_to_cpu(as->bmFormats); 82862306a36Sopenharmony_ci int err; 82962306a36Sopenharmony_ci 83062306a36Sopenharmony_ci /* 83162306a36Sopenharmony_ci * Type I format bits are D0..D6 83262306a36Sopenharmony_ci * This test works because type IV is not supported 83362306a36Sopenharmony_ci */ 83462306a36Sopenharmony_ci if (format & 0x7f) 83562306a36Sopenharmony_ci fp->fmt_type = UAC_FORMAT_TYPE_I; 83662306a36Sopenharmony_ci else 83762306a36Sopenharmony_ci fp->fmt_type = UAC_FORMAT_TYPE_III; 83862306a36Sopenharmony_ci 83962306a36Sopenharmony_ci err = parse_audio_format_i(chip, fp, format, as); 84062306a36Sopenharmony_ci if (err < 0) 84162306a36Sopenharmony_ci return err; 84262306a36Sopenharmony_ci 84362306a36Sopenharmony_ci return 0; 84462306a36Sopenharmony_ci} 845