summaryrefslogtreecommitdiffstats
path: root/sound/usb/format.c
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2026-08-30 09:22:00 -0700
committerLinus Torvalds <torvalds@linux-foundation.org>2026-08-30 09:22:00 -0700
commit034dd340b08be1f2f0477ad16131d609f9dbd53c (patch)
tree2536f4b2d7893ccd916b5abdf3c454ad6edc03c2 /sound/usb/format.c
downloadlinux-stable-034dd340b08be1f2f0477ad16131d609f9dbd53c.tar.gz
linux-stable-034dd340b08be1f2f0477ad16131d609f9dbd53c.zip
Merge tag 'trace-v7.3-2' of git://git.kernel.org/pub/scm/linux/kernel/git/trace/linux-tracegrafted
Pull tracing fixes from Steven Rostedt: - Fix error output of boot instance creation failure Currently if a boot instance creation fails, instead of printing out the name of the instance that failed, it prints "(null)". That is because it prints "cur_str" that had already been processed by strsep(). Print the saved name instead. While at it, print the error code of the failure. - Fix use-after-free for same named historgrams Histograms can be named so that they can be used in multiple events. But if the named histogram has a variable attached, the second event that uses the named histogram which duplicates it and needs to free the original after duplication leaves the old variable in place and still visible. If another histogram uses than variable, it will use the stale one which will try to reference the freed duplicate histogram and crash the kernel. Free the duplicate variables along with the duplicated histogram data. - Check return value of kthread_run() in event self test The events self tests uses a kthread for testing but does not check if it succeeded in creating a kthread. If the kthread creation were to fail, the code will still try to call kthread_stop() on the error returned. - Fix race between reading trace_pipe and updating subbuffer size If a user is reading the trace_pipe file at the same time they update the ring buffer sub-buffer size, can cause the trace_pipe read to read stale data. Add trace_access_lock() around updating the ring buffer sub-buffer size. - Fix eventfs_inode on failure path in creation of the events directory In the creation of the "events" directory, if after allocating the eventfs_inode a failure is detected, it calls cleanup_ei() which calls free_ei(). The free_ei() will test if eventfs_inode being freed has no children. It is a bug if it does. But on the failure case of the creation of the "events" directory, the children lists have not yet been initialized and the free will trigger a warning because list_empty() on an uninitialized list returns false. Move the initialization into init_ei() where it makes more sense and makes sure that a created eventfs_inode has its lists initialized upon creation. - Check return value of kthread_run() in ftrace direct sample code The sample code that shows how to use the ftrace direct calls does not test the return of kthread_run() to see if it succeeds. Return a failure if the kthread_run() doesn't succeed. - Clear user events state on fork in case of alloc failure On fork, the child gets a pointer to the parent's user events state. It makes a copy of it then updates the child's pointer to it. But if the allocation fails, the duplication function leaves the child with a pointer to its parent's descriptor. When the child cleans up its data, it will free the parent's descriptor while the parent is still using it. In the duplication function, set the child's user_event_mm to NULL before testing if the allocation succeeded, and when it exits it will not free the parent's descriptor. - Fix retry exhaustion in simple ring buffer reader swap simple_ring_buffer_swap_reader_page() starts with retry set to 8 and post-decrements it only after a failed link replacement. On the final attempt, a successful replacement leaves retry at zero, while a failed replacement leaves it at -1. But the check for success expects the retry value to be non-zero and exits with an error on zero. This is the opposite result. Fix it. - Fail nicely when the remote swap_reader_page() returns an error Currently, if the swap_reader_page() of a remote buffer fails, it triggers a WARN_ON_ONCE() and continues normally. Instead, have it exit with an error and a pr_warn() print instead of a full WARNING. * tag 'trace-v7.3-2' of git://git.kernel.org/pub/scm/linux/kernel/git/trace/linux-trace: ring-buffer: Stop remote reader update when page swap fails tracing: Fix retry exhaustion in simple ring buffer reader swap tracing/user_events: Clear copied tracing state before fork duplication samples/ftrace: Fix kthread_stop() on ERR_PTR in ftrace-direct-multi-modify samples/ftrace: Fix kthread_stop() on ERR_PTR in ftrace-direct-modify eventfs: Initialize ei->children and ei->list in init_ei() tracing: Fix use-after-free in trace_pipe read on sub-buffer order change tracing: Fix crash passing ERR_PTR to kthread_stop() tracing: Fix use-after-free with same-name named triggers tracing: Fix logged instance name on creation failure
Diffstat (limited to 'sound/usb/format.c')
-rw-r--r--sound/usb/format.c923
1 files changed, 923 insertions, 0 deletions
diff --git a/sound/usb/format.c b/sound/usb/format.c
new file mode 100644
index 000000000..4830f9f93
--- /dev/null
+++ b/sound/usb/format.c
@@ -0,0 +1,923 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+/*
+ */
+
+#include <linux/init.h>
+#include <linux/slab.h>
+#include <linux/usb.h>
+#include <linux/usb/audio.h>
+#include <linux/usb/audio-v2.h>
+#include <linux/usb/audio-v3.h>
+
+#include <sound/core.h>
+#include <sound/pcm.h>
+
+#include "usbaudio.h"
+#include "card.h"
+#include "quirks.h"
+#include "helper.h"
+#include "clock.h"
+#include "format.h"
+
+/*
+ * parse the audio format type I descriptor
+ * and returns the corresponding pcm format
+ *
+ * @dev: usb device
+ * @fp: audioformat record
+ * @format: the format tag (wFormatTag)
+ * @fmt: the format type descriptor (v1/v2) or AudioStreaming descriptor (v3)
+ */
+static u64 parse_audio_format_i_type(struct snd_usb_audio *chip,
+ struct audioformat *fp,
+ u64 format, void *_fmt)
+{
+ int sample_width, sample_bytes;
+ u64 pcm_formats = 0;
+ u64 dsd_formats = 0;
+
+ switch (fp->protocol) {
+ case UAC_VERSION_1:
+ default: {
+ struct uac_format_type_i_discrete_descriptor *fmt = _fmt;
+ if (format >= 64) {
+ usb_audio_info(chip,
+ "%u:%d: invalid format type 0x%llx is detected, processed as PCM\n",
+ fp->iface, fp->altsetting, format);
+ format = UAC_FORMAT_TYPE_I_PCM;
+ }
+ sample_width = fmt->bBitResolution;
+ sample_bytes = fmt->bSubframeSize;
+ format = 1ULL << format;
+ break;
+ }
+
+ case UAC_VERSION_2: {
+ struct uac_format_type_i_ext_descriptor *fmt = _fmt;
+ sample_width = fmt->bBitResolution;
+ sample_bytes = fmt->bSubslotSize;
+
+ if (format & UAC2_FORMAT_TYPE_I_RAW_DATA) {
+ pcm_formats |= SNDRV_PCM_FMTBIT_SPECIAL;
+ /* flag potentially raw DSD capable altsettings */
+ fp->dsd_raw = true;
+ /* clear special format bit to avoid "unsupported format" msg below */
+ format &= ~UAC2_FORMAT_TYPE_I_RAW_DATA;
+ }
+
+ format <<= 1;
+ break;
+ }
+ case UAC_VERSION_3: {
+ struct uac3_as_header_descriptor *as = _fmt;
+
+ sample_width = as->bBitResolution;
+ sample_bytes = as->bSubslotSize;
+
+ if (format & UAC3_FORMAT_TYPE_I_RAW_DATA) {
+ pcm_formats |= SNDRV_PCM_FMTBIT_SPECIAL;
+ /* clear special format bit to avoid "unsupported format" msg below */
+ format &= ~UAC3_FORMAT_TYPE_I_RAW_DATA;
+ }
+
+ format <<= 1;
+ break;
+ }
+ }
+
+ fp->fmt_bits = sample_width;
+ fp->fmt_sz = sample_bytes;
+
+ if ((pcm_formats == 0) &&
+ (format == 0 || format == BIT(UAC_FORMAT_TYPE_I_UNDEFINED))) {
+ /* some devices don't define this correctly... */
+ usb_audio_info(chip, "%u:%d : format type 0 is detected, processed as PCM\n",
+ fp->iface, fp->altsetting);
+ format = BIT(UAC_FORMAT_TYPE_I_PCM);
+ }
+ if (format & BIT(UAC_FORMAT_TYPE_I_PCM)) {
+ if (((chip->usb_id == USB_ID(0x0582, 0x0016)) ||
+ /* Edirol SD-90 */
+ (chip->usb_id == USB_ID(0x0582, 0x000c))) &&
+ /* Roland SC-D70 */
+ sample_width == 24 && sample_bytes == 2)
+ sample_bytes = 3;
+ else if (sample_width > sample_bytes * 8) {
+ usb_audio_info(chip, "%u:%d : sample bitwidth %d in over sample bytes %d\n",
+ fp->iface, fp->altsetting,
+ sample_width, sample_bytes);
+ }
+ /* check the format byte size */
+ switch (sample_bytes) {
+ case 1:
+ pcm_formats |= SNDRV_PCM_FMTBIT_S8;
+ break;
+ case 2:
+ if (snd_usb_is_big_endian_format(chip, fp))
+ pcm_formats |= SNDRV_PCM_FMTBIT_S16_BE; /* grrr, big endian!! */
+ else
+ pcm_formats |= SNDRV_PCM_FMTBIT_S16_LE;
+ break;
+ case 3:
+ if (snd_usb_is_big_endian_format(chip, fp))
+ pcm_formats |= SNDRV_PCM_FMTBIT_S24_3BE; /* grrr, big endian!! */
+ else
+ pcm_formats |= SNDRV_PCM_FMTBIT_S24_3LE;
+ break;
+ case 4:
+ pcm_formats |= SNDRV_PCM_FMTBIT_S32_LE;
+ break;
+ default:
+ usb_audio_info(chip,
+ "%u:%d : unsupported sample bitwidth %d in %d bytes\n",
+ fp->iface, fp->altsetting,
+ sample_width, sample_bytes);
+ break;
+ }
+ }
+ if (format & BIT(UAC_FORMAT_TYPE_I_PCM8)) {
+ /* Dallas DS4201 workaround: it advertises U8 format, but really
+ supports S8. */
+ if (chip->usb_id == USB_ID(0x04fa, 0x4201))
+ pcm_formats |= SNDRV_PCM_FMTBIT_S8;
+ else
+ pcm_formats |= SNDRV_PCM_FMTBIT_U8;
+ }
+ if (format & BIT(UAC_FORMAT_TYPE_I_IEEE_FLOAT))
+ pcm_formats |= SNDRV_PCM_FMTBIT_FLOAT_LE;
+ if (format & BIT(UAC_FORMAT_TYPE_I_ALAW))
+ pcm_formats |= SNDRV_PCM_FMTBIT_A_LAW;
+ if (format & BIT(UAC_FORMAT_TYPE_I_MULAW))
+ pcm_formats |= SNDRV_PCM_FMTBIT_MU_LAW;
+ if (format & ~0x3f) {
+ usb_audio_info(chip,
+ "%u:%d : unsupported format bits %#llx\n",
+ fp->iface, fp->altsetting, format);
+ }
+
+ dsd_formats |= snd_usb_interface_dsd_format_quirks(chip, fp, sample_bytes);
+ if (dsd_formats && !fp->dsd_dop)
+ pcm_formats = dsd_formats;
+
+ return pcm_formats;
+}
+
+static int set_fixed_rate(struct audioformat *fp, int rate, int rate_bits)
+{
+ kfree(fp->rate_table);
+ fp->rate_table = kmalloc(sizeof(int), GFP_KERNEL);
+ if (!fp->rate_table)
+ return -ENOMEM;
+ fp->nr_rates = 1;
+ fp->rate_min = rate;
+ fp->rate_max = rate;
+ fp->rates = rate_bits;
+ fp->rate_table[0] = rate;
+ return 0;
+}
+
+/* set up rate_min, rate_max and rates from the rate table */
+static void set_rate_table_min_max(struct audioformat *fp)
+{
+ unsigned int rate;
+ int i;
+
+ fp->rate_min = INT_MAX;
+ fp->rate_max = 0;
+ fp->rates = 0;
+ for (i = 0; i < fp->nr_rates; i++) {
+ rate = fp->rate_table[i];
+ fp->rate_min = min(fp->rate_min, rate);
+ fp->rate_max = max(fp->rate_max, rate);
+ fp->rates |= snd_pcm_rate_to_rate_bit(rate);
+ }
+}
+
+/*
+ * parse the format descriptor and stores the possible sample rates
+ * on the audioformat table (audio class v1).
+ *
+ * @dev: usb device
+ * @fp: audioformat record
+ * @fmt: the format descriptor
+ * @offset: the start offset of descriptor pointing the rate type
+ * (7 for type I and II, 8 for type II)
+ */
+static int parse_audio_format_rates_v1(struct snd_usb_audio *chip, struct audioformat *fp,
+ unsigned char *fmt, int offset)
+{
+ int nr_rates = fmt[offset];
+
+ if (fmt[0] < offset + 1 + 3 * (nr_rates ? nr_rates : 2)) {
+ usb_audio_err(chip,
+ "%u:%d : invalid UAC_FORMAT_TYPE desc\n",
+ fp->iface, fp->altsetting);
+ return -EINVAL;
+ }
+
+ if (nr_rates) {
+ /*
+ * build the rate table and bitmap flags
+ */
+ int r, idx;
+
+ fp->rate_table = kmalloc_array(nr_rates, sizeof(int),
+ GFP_KERNEL);
+ if (fp->rate_table == NULL)
+ return -ENOMEM;
+
+ fp->nr_rates = 0;
+ for (r = 0, idx = offset + 1; r < nr_rates; r++, idx += 3) {
+ unsigned int rate = combine_triple(&fmt[idx]);
+ if (!rate)
+ continue;
+ /* C-Media CM6501 mislabels its 96 kHz altsetting */
+ /* Terratec Aureon 7.1 USB C-Media 6206, too */
+ /* Ozone Z90 USB C-Media, too */
+ if (rate == 48000 && nr_rates == 1 &&
+ (chip->usb_id == USB_ID(0x0d8c, 0x0201) ||
+ chip->usb_id == USB_ID(0x0d8c, 0x0102) ||
+ chip->usb_id == USB_ID(0x0d8c, 0x0078) ||
+ chip->usb_id == USB_ID(0x0ccd, 0x00b1)) &&
+ fp->altsetting == 5 && fp->maxpacksize == 392)
+ rate = 96000;
+ /* Creative VF0420/VF0470 Live Cams report 16 kHz instead of 8kHz */
+ if (rate == 16000 &&
+ (chip->usb_id == USB_ID(0x041e, 0x4064) ||
+ chip->usb_id == USB_ID(0x041e, 0x4068)))
+ rate = 8000;
+
+ fp->rate_table[fp->nr_rates++] = rate;
+ }
+ if (!fp->nr_rates) {
+ usb_audio_info(chip,
+ "%u:%d: All rates were zero\n",
+ fp->iface, fp->altsetting);
+ return -EINVAL;
+ }
+ set_rate_table_min_max(fp);
+ } else {
+ /* continuous rates */
+ fp->rates = SNDRV_PCM_RATE_CONTINUOUS;
+ fp->rate_min = combine_triple(&fmt[offset + 1]);
+ fp->rate_max = combine_triple(&fmt[offset + 4]);
+ }
+
+ /* Jabra Evolve 65 headset */
+ if (chip->usb_id == USB_ID(0x0b0e, 0x030b) ||
+ chip->usb_id == USB_ID(0x0b0e, 0x030c)) {
+ /* only 48kHz for playback while keeping 16kHz for capture */
+ if (fp->nr_rates != 1)
+ return set_fixed_rate(fp, 48000, SNDRV_PCM_RATE_48000);
+ }
+
+ 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;
+}
+
+/*
+ * Focusrite devices use rate pairs: 44100/48000, 88200/96000, and
+ * 176400/192000. Return true if rate is in the pair for max_rate.
+ */
+static bool focusrite_rate_pair(unsigned int rate,
+ unsigned int max_rate)
+{
+ switch (max_rate) {
+ case 48000: return rate == 44100 || rate == 48000;
+ case 96000: return rate == 88200 || rate == 96000;
+ case 192000: return rate == 176400 || rate == 192000;
+ default: return true;
+ }
+}
+
+/*
+ * Focusrite devices report all supported rates in a single clock
+ * source but only a subset is valid per altsetting.
+ *
+ * Detection uses two descriptor features:
+ *
+ * 1. Format Type descriptor bLength == 10: non-standard extension
+ * with max sample rate in bytes 6..9.
+ *
+ * 2. bmControls VAL_ALT_SETTINGS readable bit: when set, the device
+ * only supports the highest rate pair for that altsetting, and when
+ * clear, all rates up to max_rate are valid.
+ *
+ * For devices without the bLength == 10 extension but with
+ * VAL_ALT_SETTINGS readable and multiple altsettings (only seen in
+ * Scarlett 18i8 3rd Gen playback), fall back to the Focusrite
+ * convention: alt 1 = 48kHz, alt 2 = 96kHz, alt 3 = 192kHz.
+ */
+static bool focusrite_valid_sample_rate(struct snd_usb_audio *chip,
+ struct audioformat *fp,
+ unsigned int rate)
+{
+ struct usb_interface *iface;
+ struct usb_host_interface *alts;
+ struct uac2_as_header_descriptor *as;
+ unsigned char *fmt;
+ unsigned int max_rate;
+ bool val_alt;
+
+ alts = snd_usb_get_host_interface(chip, fp->iface, fp->altsetting);
+ if (!alts)
+ return true;
+
+ fmt = snd_usb_find_csint_desc(alts->extra, alts->extralen,
+ NULL, UAC_FORMAT_TYPE);
+ if (!fmt)
+ return true;
+
+ as = snd_usb_find_csint_desc(alts->extra, alts->extralen,
+ NULL, UAC_AS_GENERAL);
+ if (!as)
+ return true;
+
+ val_alt = uac_v2v3_control_is_readable(as->bmControls,
+ UAC2_AS_VAL_ALT_SETTINGS);
+
+ if (fmt[0] == 10) { /* bLength */
+ max_rate = combine_quad(&fmt[6]);
+
+ if (val_alt)
+ return focusrite_rate_pair(rate, max_rate);
+
+ /* No val_alt: rates fall through from higher */
+ switch (max_rate) {
+ case 192000:
+ if (rate == 176400 || rate == 192000)
+ return true;
+ fallthrough;
+ case 96000:
+ if (rate == 88200 || rate == 96000)
+ return true;
+ fallthrough;
+ case 48000:
+ return (rate == 44100 || rate == 48000);
+ default:
+ usb_audio_info(chip,
+ "%u:%d : unexpected max rate: %u\n",
+ fp->iface, fp->altsetting, max_rate);
+ return true;
+ }
+ }
+
+ if (!val_alt)
+ return true;
+
+ /* Multi-altsetting device with val_alt but no max_rate
+ * in the format descriptor. Use Focusrite convention:
+ * alt 1 = 48kHz, alt 2 = 96kHz, alt 3 = 192kHz.
+ */
+ iface = usb_ifnum_to_if(chip->dev, fp->iface);
+ if (!iface || iface->num_altsetting <= 2)
+ return true;
+
+ switch (fp->altsetting) {
+ case 1: max_rate = 48000; break;
+ case 2: max_rate = 96000; break;
+ case 3: max_rate = 192000; break;
+ default: return true;
+ }
+
+ return focusrite_rate_pair(rate, max_rate);
+}
+
+/*
+ * 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
+ * get to know how many sample rates we have to expect.
+ * Then fp->rate_table can be allocated and filled.
+ */
+static int parse_uac2_sample_rate_range(struct snd_usb_audio *chip,
+ struct audioformat *fp, int nr_triplets,
+ const unsigned char *data)
+{
+ int i, nr_rates = 0;
+
+ for (i = 0; i < nr_triplets; i++) {
+ int min = combine_quad(&data[2 + 12 * i]);
+ int max = combine_quad(&data[6 + 12 * i]);
+ int res = combine_quad(&data[10 + 12 * i]);
+ unsigned int rate;
+
+ if ((max < 0) || (min < 0) || (res < 0) || (max < min))
+ continue;
+
+ /*
+ * for ranges with res == 1, we announce a continuous sample
+ * rate range, and this function should return 0 for no further
+ * parsing.
+ */
+ if (res == 1) {
+ fp->rate_min = min;
+ fp->rate_max = max;
+ fp->rates = SNDRV_PCM_RATE_CONTINUOUS;
+ return 0;
+ }
+
+ for (rate = min; rate <= max; rate += res) {
+
+ /* Filter out invalid rates on Presonus Studio 1810c */
+ if (chip->usb_id == USB_ID(0x194f, 0x010c) &&
+ !s1810c_valid_sample_rate(fp, rate))
+ goto skip_rate;
+ /* Filter out invalid rates on Presonus Studio 1824c */
+ if (chip->usb_id == USB_ID(0x194f, 0x010d) &&
+ !s1810c_valid_sample_rate(fp, rate))
+ goto skip_rate;
+ /* Filter out invalid rates on Presonus Studio 1824 */
+ if (chip->usb_id == USB_ID(0x194f, 0x0107) &&
+ !s1810c_valid_sample_rate(fp, rate))
+ goto skip_rate;
+
+ /* Filter out invalid rates on Focusrite devices */
+ if (USB_ID_VENDOR(chip->usb_id) == 0x1235 &&
+ !focusrite_valid_sample_rate(chip, fp, rate))
+ goto skip_rate;
+
+ if (fp->rate_table)
+ fp->rate_table[nr_rates] = rate;
+ nr_rates++;
+ if (nr_rates >= MAX_NR_RATES) {
+ usb_audio_err(chip, "invalid uac2 rates\n");
+ return nr_rates;
+ }
+
+skip_rate:
+ /* avoid endless loop */
+ if (res == 0)
+ break;
+ }
+ }
+
+ return nr_rates;
+}
+
+/* Line6 Helix series and the Rode Rodecaster Pro don't support the
+ * UAC2_CS_RANGE usb function call. Return a static table of known
+ * clock rates.
+ */
+static int line6_parse_audio_format_rates_quirk(struct snd_usb_audio *chip,
+ struct audioformat *fp)
+{
+ switch (chip->usb_id) {
+ case USB_ID(0x0e41, 0x4241): /* Line6 Helix */
+ case USB_ID(0x0e41, 0x4242): /* Line6 Helix Rack */
+ case USB_ID(0x0e41, 0x4244): /* Line6 Helix LT */
+ case USB_ID(0x0e41, 0x4246): /* Line6 HX-Stomp */
+ case USB_ID(0x0e41, 0x4253): /* Line6 HX-Stomp XL */
+ case USB_ID(0x0e41, 0x4247): /* Line6 Pod Go */
+ case USB_ID(0x0e41, 0x4248): /* Line6 Helix >= fw 2.82 */
+ case USB_ID(0x0e41, 0x4249): /* Line6 Helix Rack >= fw 2.82 */
+ case USB_ID(0x0e41, 0x424a): /* Line6 Helix LT >= fw 2.82 */
+ case USB_ID(0x0e41, 0x424b): /* Line6 Pod Go */
+ case USB_ID(0x19f7, 0x0011): /* Rode Rodecaster Pro */
+ return set_fixed_rate(fp, 48000, SNDRV_PCM_RATE_48000);
+ }
+
+ return -ENODEV;
+}
+
+/* check whether the given altsetting is supported for the already set rate */
+static bool check_valid_altsetting_v2v3(struct snd_usb_audio *chip, int iface,
+ int altsetting)
+{
+ struct usb_device *dev = chip->dev;
+ __le64 raw_data = 0;
+ u64 data;
+ int err;
+
+ /* we assume 64bit is enough for any altsettings */
+ if (snd_BUG_ON(altsetting >= 64 - 8))
+ return false;
+
+ err = snd_usb_ctl_msg(dev, usb_rcvctrlpipe(dev, 0), UAC2_CS_CUR,
+ USB_TYPE_CLASS | USB_RECIP_INTERFACE | USB_DIR_IN,
+ UAC2_AS_VAL_ALT_SETTINGS << 8,
+ iface, &raw_data, sizeof(raw_data));
+ if (err < 0)
+ return false;
+
+ data = le64_to_cpu(raw_data);
+ /* first byte contains the bitmap size */
+ if ((data & 0xff) * 8 < altsetting)
+ return false;
+ if (data & (1ULL << (altsetting + 8)))
+ return true;
+
+ return false;
+}
+
+/*
+ * Validate each sample rate with the altsetting
+ * Rebuild the rate table if only partial values are valid
+ */
+static int validate_sample_rate_table_v2v3(struct snd_usb_audio *chip,
+ struct audioformat *fp,
+ int clock)
+{
+ struct usb_device *dev = chip->dev;
+ struct usb_host_interface *alts;
+ unsigned int *table;
+ unsigned int nr_rates;
+ int i, err;
+ u32 bmControls;
+
+ /* performing the rate verification may lead to unexpected USB bus
+ * behavior afterwards by some unknown reason. Do this only for the
+ * known devices.
+ */
+ if (!(chip->quirk_flags & QUIRK_FLAG_VALIDATE_RATES))
+ return 0; /* don't perform the validation as default */
+
+ alts = snd_usb_get_host_interface(chip, fp->iface, fp->altsetting);
+ if (!alts)
+ return 0;
+
+ if (fp->protocol == UAC_VERSION_3) {
+ struct uac3_as_header_descriptor *as = snd_usb_find_csint_desc(
+ alts->extra, alts->extralen, NULL, UAC_AS_GENERAL);
+ bmControls = le32_to_cpu(as->bmControls);
+ } else {
+ struct uac2_as_header_descriptor *as = snd_usb_find_csint_desc(
+ alts->extra, alts->extralen, NULL, UAC_AS_GENERAL);
+ bmControls = as->bmControls;
+ }
+
+ if (!uac_v2v3_control_is_readable(bmControls,
+ UAC2_AS_VAL_ALT_SETTINGS))
+ return 0;
+
+ table = kcalloc(fp->nr_rates, sizeof(*table), GFP_KERNEL);
+ if (!table)
+ return -ENOMEM;
+
+ /* clear the interface altsetting at first */
+ usb_set_interface(dev, fp->iface, 0);
+
+ nr_rates = 0;
+ for (i = 0; i < fp->nr_rates; i++) {
+ err = snd_usb_set_sample_rate_v2v3(chip, fp, clock,
+ fp->rate_table[i]);
+ if (err < 0)
+ continue;
+
+ if (check_valid_altsetting_v2v3(chip, fp->iface, fp->altsetting))
+ table[nr_rates++] = fp->rate_table[i];
+ }
+
+ if (!nr_rates) {
+ usb_audio_dbg(chip,
+ "No valid sample rate available for %d:%d, assuming a firmware bug\n",
+ fp->iface, fp->altsetting);
+ nr_rates = fp->nr_rates; /* continue as is */
+ }
+
+ if (fp->nr_rates == nr_rates) {
+ kfree(table);
+ return 0;
+ }
+
+ kfree(fp->rate_table);
+ fp->rate_table = table;
+ fp->nr_rates = nr_rates;
+ return 0;
+}
+
+/*
+ * parse the format descriptor and stores the possible sample rates
+ * on the audioformat table (audio class v2 and v3).
+ */
+static int parse_audio_format_rates_v2v3(struct snd_usb_audio *chip,
+ struct audioformat *fp)
+{
+ struct usb_device *dev = chip->dev;
+ unsigned char tmp[2], *data;
+ int nr_triplets, data_size, ret = 0, ret_l6;
+ int clock = snd_usb_clock_find_source(chip, fp, false);
+ struct usb_host_interface *ctrl_intf;
+
+ ctrl_intf = snd_usb_find_ctrl_interface(chip, fp->iface);
+ if (clock < 0) {
+ dev_err(&dev->dev,
+ "%s(): unable to find clock source (clock %d)\n",
+ __func__, clock);
+ goto err;
+ }
+
+ /* get the number of sample rates first by only fetching 2 bytes */
+ ret = snd_usb_ctl_msg(dev, usb_rcvctrlpipe(dev, 0), UAC2_CS_RANGE,
+ USB_TYPE_CLASS | USB_RECIP_INTERFACE | USB_DIR_IN,
+ UAC2_CS_CONTROL_SAM_FREQ << 8,
+ snd_usb_ctrl_intf(ctrl_intf) | (clock << 8),
+ tmp, sizeof(tmp));
+
+ if (ret < 0) {
+ /* line6 helix devices don't support UAC2_CS_CONTROL_SAM_FREQ call */
+ ret_l6 = line6_parse_audio_format_rates_quirk(chip, fp);
+ if (ret_l6 == -ENODEV) {
+ /* no line6 device found continue showing the error */
+ dev_err(&dev->dev,
+ "%s(): unable to retrieve number of sample rates (clock %d)\n",
+ __func__, clock);
+ goto err;
+ }
+ if (ret_l6 == 0) {
+ dev_info(&dev->dev,
+ "%s(): unable to retrieve number of sample rates: set it to a predefined value (clock %d).\n",
+ __func__, clock);
+ return 0;
+ }
+ ret = ret_l6;
+ goto err;
+ }
+
+ nr_triplets = (tmp[1] << 8) | tmp[0];
+ data_size = 2 + 12 * nr_triplets;
+ data = kzalloc(data_size, GFP_KERNEL);
+ if (!data) {
+ ret = -ENOMEM;
+ goto err;
+ }
+
+ /* now get the full information */
+ ret = snd_usb_ctl_msg(dev, usb_rcvctrlpipe(dev, 0), UAC2_CS_RANGE,
+ USB_TYPE_CLASS | USB_RECIP_INTERFACE | USB_DIR_IN,
+ UAC2_CS_CONTROL_SAM_FREQ << 8,
+ snd_usb_ctrl_intf(ctrl_intf) | (clock << 8),
+ data, data_size);
+
+ if (ret < 0) {
+ dev_err(&dev->dev,
+ "%s(): unable to retrieve sample rate range (clock %d)\n",
+ __func__, clock);
+ ret = -EINVAL;
+ goto err_free;
+ }
+
+ /* Call the triplet parser, and make sure fp->rate_table is NULL.
+ * We just use the return value to know how many sample rates we
+ * will have to deal with. */
+ kfree(fp->rate_table);
+ fp->rate_table = NULL;
+ fp->nr_rates = parse_uac2_sample_rate_range(chip, fp, nr_triplets, data);
+
+ if (fp->nr_rates == 0) {
+ /* SNDRV_PCM_RATE_CONTINUOUS */
+ ret = 0;
+ goto err_free;
+ }
+
+ fp->rate_table = kmalloc_array(fp->nr_rates, sizeof(int), GFP_KERNEL);
+ if (!fp->rate_table) {
+ ret = -ENOMEM;
+ goto err_free;
+ }
+
+ /* Call the triplet parser again, but this time, fp->rate_table is
+ * allocated, so the rates will be stored */
+ parse_uac2_sample_rate_range(chip, fp, nr_triplets, data);
+
+ ret = validate_sample_rate_table_v2v3(chip, fp, clock);
+ if (ret < 0)
+ goto err_free;
+
+ set_rate_table_min_max(fp);
+
+err_free:
+ kfree(data);
+err:
+ return ret;
+}
+
+/*
+ * parse the format type I and III descriptors
+ */
+static int parse_audio_format_i(struct snd_usb_audio *chip,
+ struct audioformat *fp, u64 format,
+ void *_fmt)
+{
+ snd_pcm_format_t pcm_format;
+ unsigned int fmt_type;
+ int ret;
+
+ switch (fp->protocol) {
+ default:
+ case UAC_VERSION_1:
+ case UAC_VERSION_2: {
+ struct uac_format_type_i_continuous_descriptor *fmt = _fmt;
+
+ fmt_type = fmt->bFormatType;
+ break;
+ }
+ case UAC_VERSION_3: {
+ /* fp->fmt_type is already set in this case */
+ fmt_type = fp->fmt_type;
+ break;
+ }
+ }
+
+ if (fmt_type == UAC_FORMAT_TYPE_III) {
+ /* FIXME: the format type is really IECxxx
+ * but we give normal PCM format to get the existing
+ * apps working...
+ */
+ switch (chip->usb_id) {
+
+ case USB_ID(0x0763, 0x2003): /* M-Audio Audiophile USB */
+ if (chip->setup == 0x00 &&
+ fp->altsetting == 6)
+ pcm_format = SNDRV_PCM_FORMAT_S16_BE;
+ else
+ pcm_format = SNDRV_PCM_FORMAT_S16_LE;
+ break;
+ default:
+ pcm_format = SNDRV_PCM_FORMAT_S16_LE;
+ }
+ fp->formats = pcm_format_to_bits(pcm_format);
+ } else {
+ fp->formats = parse_audio_format_i_type(chip, fp, format, _fmt);
+ if (!fp->formats)
+ return -EINVAL;
+ }
+
+ /* gather possible sample rates */
+ /* audio class v1 reports possible sample rates as part of the
+ * proprietary class specific descriptor.
+ * audio class v2 uses class specific EP0 range requests for that.
+ */
+ switch (fp->protocol) {
+ default:
+ case UAC_VERSION_1: {
+ struct uac_format_type_i_continuous_descriptor *fmt = _fmt;
+
+ fp->channels = fmt->bNrChannels;
+ ret = parse_audio_format_rates_v1(chip, fp, (unsigned char *) fmt, 7);
+ break;
+ }
+ case UAC_VERSION_2:
+ case UAC_VERSION_3: {
+ /* fp->channels is already set in this case */
+ ret = parse_audio_format_rates_v2v3(chip, fp);
+ break;
+ }
+ }
+
+ if (fp->channels < 1) {
+ usb_audio_err(chip,
+ "%u:%d : invalid channels %d\n",
+ fp->iface, fp->altsetting, fp->channels);
+ return -EINVAL;
+ }
+
+ return ret;
+}
+
+/*
+ * parse the format type II descriptor
+ */
+static int parse_audio_format_ii(struct snd_usb_audio *chip,
+ struct audioformat *fp,
+ u64 format, void *_fmt)
+{
+ int brate, framesize, ret;
+
+ switch (format) {
+ case UAC_FORMAT_TYPE_II_AC3:
+ /* FIXME: there is no AC3 format defined yet */
+ // fp->formats = SNDRV_PCM_FMTBIT_AC3;
+ fp->formats = SNDRV_PCM_FMTBIT_U8; /* temporary hack to receive byte streams */
+ break;
+ case UAC_FORMAT_TYPE_II_MPEG:
+ fp->formats = SNDRV_PCM_FMTBIT_MPEG;
+ break;
+ default:
+ usb_audio_info(chip,
+ "%u:%d : unknown format tag %#llx is detected. processed as MPEG.\n",
+ fp->iface, fp->altsetting, format);
+ fp->formats = SNDRV_PCM_FMTBIT_MPEG;
+ break;
+ }
+
+ fp->channels = 1;
+
+ switch (fp->protocol) {
+ default:
+ case UAC_VERSION_1: {
+ struct uac_format_type_ii_discrete_descriptor *fmt = _fmt;
+ brate = le16_to_cpu(fmt->wMaxBitRate);
+ framesize = le16_to_cpu(fmt->wSamplesPerFrame);
+ usb_audio_info(chip, "found format II with max.bitrate = %d, frame size=%d\n", brate, framesize);
+ fp->frame_size = framesize;
+ ret = parse_audio_format_rates_v1(chip, fp, _fmt, 8); /* fmt[8..] sample rates */
+ break;
+ }
+ case UAC_VERSION_2: {
+ struct uac_format_type_ii_ext_descriptor *fmt = _fmt;
+ brate = le16_to_cpu(fmt->wMaxBitRate);
+ framesize = le16_to_cpu(fmt->wSamplesPerFrame);
+ usb_audio_info(chip, "found format II with max.bitrate = %d, frame size=%d\n", brate, framesize);
+ fp->frame_size = framesize;
+ ret = parse_audio_format_rates_v2v3(chip, fp);
+ break;
+ }
+ }
+
+ return ret;
+}
+
+int snd_usb_parse_audio_format(struct snd_usb_audio *chip,
+ struct audioformat *fp, u64 format,
+ struct uac_format_type_i_continuous_descriptor *fmt,
+ int stream)
+{
+ int err;
+
+ switch (fmt->bFormatType) {
+ case UAC_FORMAT_TYPE_I:
+ case UAC_FORMAT_TYPE_III:
+ err = parse_audio_format_i(chip, fp, format, fmt);
+ break;
+ case UAC_FORMAT_TYPE_II:
+ err = parse_audio_format_ii(chip, fp, format, fmt);
+ break;
+ default:
+ usb_audio_info(chip,
+ "%u:%d : format type %d is not supported yet\n",
+ fp->iface, fp->altsetting,
+ fmt->bFormatType);
+ return -ENOTSUPP;
+ }
+ fp->fmt_type = fmt->bFormatType;
+ if (err < 0)
+ return err;
+#if 1
+ /* FIXME: temporary hack for extigy/audigy 2 nx/zs */
+ /* extigy apparently supports sample rates other than 48k
+ * but not in ordinary way. so we enable only 48k atm.
+ */
+ if (chip->usb_id == USB_ID(0x041e, 0x3000) ||
+ chip->usb_id == USB_ID(0x041e, 0x3020) ||
+ chip->usb_id == USB_ID(0x041e, 0x3061)) {
+ if (fmt->bFormatType == UAC_FORMAT_TYPE_I &&
+ fp->rates != SNDRV_PCM_RATE_48000 &&
+ fp->rates != SNDRV_PCM_RATE_96000)
+ return -ENOTSUPP;
+ }
+#endif
+ return 0;
+}
+
+int snd_usb_parse_audio_format_v3(struct snd_usb_audio *chip,
+ struct audioformat *fp,
+ struct uac3_as_header_descriptor *as,
+ int stream)
+{
+ u64 format = le64_to_cpu(as->bmFormats);
+ int err;
+
+ /*
+ * Type I format bits are D0..D6
+ * This test works because type IV is not supported
+ */
+ if (format & 0x7f)
+ fp->fmt_type = UAC_FORMAT_TYPE_I;
+ else
+ fp->fmt_type = UAC_FORMAT_TYPE_III;
+
+ err = parse_audio_format_i(chip, fp, format, as);
+ if (err < 0)
+ return err;
+
+ return 0;
+}