summaryrefslogtreecommitdiff
path: root/sound/usb
diff options
context:
space:
mode:
Diffstat (limited to 'sound/usb')
-rw-r--r--sound/usb/caiaq/input.c1
-rw-r--r--sound/usb/card.c1
-rw-r--r--sound/usb/endpoint.c43
-rw-r--r--sound/usb/endpoint.h4
-rw-r--r--sound/usb/format.c8
-rw-r--r--sound/usb/helper.c1
-rw-r--r--sound/usb/pcm.c2
-rw-r--r--sound/usb/quirks-table.h58
-rw-r--r--sound/usb/usbaudio.h2
9 files changed, 88 insertions, 32 deletions
diff --git a/sound/usb/caiaq/input.c b/sound/usb/caiaq/input.c
index 1e2cf2f08eec..84f26dce7f5d 100644
--- a/sound/usb/caiaq/input.c
+++ b/sound/usb/caiaq/input.c
@@ -804,6 +804,7 @@ int snd_usb_caiaq_input_init(struct snd_usb_caiaqdev *cdev)
default:
/* no input methods supported on this device */
+ ret = -EINVAL;
goto exit_free_idev;
}
diff --git a/sound/usb/card.c b/sound/usb/card.c
index 26268ffb8274..f6e99ced8068 100644
--- a/sound/usb/card.c
+++ b/sound/usb/card.c
@@ -609,7 +609,6 @@ static int snd_usb_audio_create(struct usb_interface *intf,
case USB_SPEED_LOW:
case USB_SPEED_FULL:
case USB_SPEED_HIGH:
- case USB_SPEED_WIRELESS:
case USB_SPEED_SUPER:
case USB_SPEED_SUPER_PLUS:
break;
diff --git a/sound/usb/endpoint.c b/sound/usb/endpoint.c
index 419302e2057e..a385e85c4650 100644
--- a/sound/usb/endpoint.c
+++ b/sound/usb/endpoint.c
@@ -455,8 +455,8 @@ static void push_back_to_ready_list(struct snd_usb_endpoint *ep,
* This function is used both for implicit feedback endpoints and in low-
* latency playback mode.
*/
-void snd_usb_queue_pending_output_urbs(struct snd_usb_endpoint *ep,
- bool in_stream_lock)
+int snd_usb_queue_pending_output_urbs(struct snd_usb_endpoint *ep,
+ bool in_stream_lock)
{
bool implicit_fb = snd_usb_endpoint_implicit_feedback_sink(ep);
@@ -480,7 +480,7 @@ void snd_usb_queue_pending_output_urbs(struct snd_usb_endpoint *ep,
spin_unlock_irqrestore(&ep->lock, flags);
if (ctx == NULL)
- return;
+ break;
/* copy over the length information */
if (implicit_fb) {
@@ -495,11 +495,14 @@ void snd_usb_queue_pending_output_urbs(struct snd_usb_endpoint *ep,
break;
if (err < 0) {
/* push back to ready list again for -EAGAIN */
- if (err == -EAGAIN)
+ if (err == -EAGAIN) {
push_back_to_ready_list(ep, ctx);
- else
+ break;
+ }
+
+ if (!in_stream_lock)
notify_xrun(ep);
- return;
+ return -EPIPE;
}
err = usb_submit_urb(ctx->urb, GFP_ATOMIC);
@@ -507,13 +510,16 @@ void snd_usb_queue_pending_output_urbs(struct snd_usb_endpoint *ep,
usb_audio_err(ep->chip,
"Unable to submit urb #%d: %d at %s\n",
ctx->index, err, __func__);
- notify_xrun(ep);
- return;
+ if (!in_stream_lock)
+ notify_xrun(ep);
+ return -EPIPE;
}
set_bit(ctx->index, &ep->active_mask);
atomic_inc(&ep->submitted_urbs);
}
+
+ return 0;
}
/*
@@ -910,8 +916,9 @@ static int endpoint_set_interface(struct snd_usb_audio *chip,
ep->iface, altset, ep->ep_num);
err = usb_set_interface(chip->dev, ep->iface, altset);
if (err < 0) {
- usb_audio_err(chip, "%d:%d: usb_set_interface failed (%d)\n",
- ep->iface, altset, err);
+ usb_audio_err_ratelimited(
+ chip, "%d:%d: usb_set_interface failed (%d)\n",
+ ep->iface, altset, err);
return err;
}
@@ -1173,22 +1180,8 @@ static int data_ep_set_params(struct snd_usb_endpoint *ep)
*/
if (usb_pipein(ep->pipe) || ep->implicit_fb_sync) {
- urb_packs = packs_per_ms;
- /*
- * Wireless devices can poll at a max rate of once per 4ms.
- * For dataintervals less than 5, increase the packet count to
- * allow the host controller to use bursting to fill in the
- * gaps.
- */
- if (snd_usb_get_speed(chip->dev) == USB_SPEED_WIRELESS) {
- int interval = ep->datainterval;
- while (interval < 5) {
- urb_packs <<= 1;
- ++interval;
- }
- }
/* make capture URBs <= 1 ms and smaller than a period */
- urb_packs = min(max_packs_per_urb, urb_packs);
+ urb_packs = min(max_packs_per_urb, packs_per_ms);
while (urb_packs > 1 && urb_packs * maxsize >= ep->cur_period_bytes)
urb_packs >>= 1;
ep->nurbs = MAX_URBS;
diff --git a/sound/usb/endpoint.h b/sound/usb/endpoint.h
index 924f4351588c..c09f68ce08b1 100644
--- a/sound/usb/endpoint.h
+++ b/sound/usb/endpoint.h
@@ -52,7 +52,7 @@ int snd_usb_endpoint_implicit_feedback_sink(struct snd_usb_endpoint *ep);
int snd_usb_endpoint_next_packet_size(struct snd_usb_endpoint *ep,
struct snd_urb_ctx *ctx, int idx,
unsigned int avail);
-void snd_usb_queue_pending_output_urbs(struct snd_usb_endpoint *ep,
- bool in_stream_lock);
+int snd_usb_queue_pending_output_urbs(struct snd_usb_endpoint *ep,
+ bool in_stream_lock);
#endif /* __USBAUDIO_ENDPOINT_H */
diff --git a/sound/usb/format.c b/sound/usb/format.c
index 405dc0bf6678..4b1c5ba121f3 100644
--- a/sound/usb/format.c
+++ b/sound/usb/format.c
@@ -39,8 +39,12 @@ static u64 parse_audio_format_i_type(struct snd_usb_audio *chip,
case UAC_VERSION_1:
default: {
struct uac_format_type_i_discrete_descriptor *fmt = _fmt;
- if (format >= 64)
- return 0; /* invalid format */
+ 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;
diff --git a/sound/usb/helper.c b/sound/usb/helper.c
index a4410267bf70..bf80e55d013a 100644
--- a/sound/usb/helper.c
+++ b/sound/usb/helper.c
@@ -108,7 +108,6 @@ unsigned char snd_usb_parse_datainterval(struct snd_usb_audio *chip,
{
switch (snd_usb_get_speed(chip->dev)) {
case USB_SPEED_HIGH:
- case USB_SPEED_WIRELESS:
case USB_SPEED_SUPER:
case USB_SPEED_SUPER_PLUS:
if (get_endpoint(alts, 0)->bInterval >= 1 &&
diff --git a/sound/usb/pcm.c b/sound/usb/pcm.c
index d959da7a1afb..eec5232f9fb2 100644
--- a/sound/usb/pcm.c
+++ b/sound/usb/pcm.c
@@ -1639,7 +1639,7 @@ static int snd_usb_pcm_playback_ack(struct snd_pcm_substream *substream)
* outputs here
*/
if (!ep->active_mask)
- snd_usb_queue_pending_output_urbs(ep, true);
+ return snd_usb_queue_pending_output_urbs(ep, true);
return 0;
}
diff --git a/sound/usb/quirks-table.h b/sound/usb/quirks-table.h
index 271884e35003..efb4a3311cc5 100644
--- a/sound/usb/quirks-table.h
+++ b/sound/usb/quirks-table.h
@@ -3884,6 +3884,64 @@ YAMAHA_DEVICE(0x7010, "UB99"),
}
},
+{
+ /*
+ * PIONEER DJ DDJ-800
+ * PCM is 6 channels out, 6 channels in @ 44.1 fixed
+ * The Feedback for the output is the input
+ */
+ USB_DEVICE_VENDOR_SPEC(0x2b73, 0x0029),
+ .driver_info = (unsigned long) &(const struct snd_usb_audio_quirk) {
+ .ifnum = QUIRK_ANY_INTERFACE,
+ .type = QUIRK_COMPOSITE,
+ .data = (const struct snd_usb_audio_quirk[]) {
+ {
+ .ifnum = 0,
+ .type = QUIRK_AUDIO_FIXED_ENDPOINT,
+ .data = &(const struct audioformat) {
+ .formats = SNDRV_PCM_FMTBIT_S24_3LE,
+ .channels = 6,
+ .iface = 0,
+ .altsetting = 1,
+ .altset_idx = 1,
+ .endpoint = 0x01,
+ .ep_attr = USB_ENDPOINT_XFER_ISOC|
+ USB_ENDPOINT_SYNC_ASYNC,
+ .rates = SNDRV_PCM_RATE_44100,
+ .rate_min = 44100,
+ .rate_max = 44100,
+ .nr_rates = 1,
+ .rate_table = (unsigned int[]) { 44100 }
+ }
+ },
+ {
+ .ifnum = 0,
+ .type = QUIRK_AUDIO_FIXED_ENDPOINT,
+ .data = &(const struct audioformat) {
+ .formats = SNDRV_PCM_FMTBIT_S24_3LE,
+ .channels = 6,
+ .iface = 0,
+ .altsetting = 1,
+ .altset_idx = 1,
+ .endpoint = 0x82,
+ .ep_idx = 1,
+ .ep_attr = USB_ENDPOINT_XFER_ISOC|
+ USB_ENDPOINT_SYNC_ASYNC|
+ USB_ENDPOINT_USAGE_IMPLICIT_FB,
+ .rates = SNDRV_PCM_RATE_44100,
+ .rate_min = 44100,
+ .rate_max = 44100,
+ .nr_rates = 1,
+ .rate_table = (unsigned int[]) { 44100 }
+ }
+ },
+ {
+ .ifnum = -1
+ }
+ }
+ }
+},
+
/*
* MacroSilicon MS2100/MS2106 based AV capture cards
*
diff --git a/sound/usb/usbaudio.h b/sound/usb/usbaudio.h
index f5a8dca66457..38a85b2c9a73 100644
--- a/sound/usb/usbaudio.h
+++ b/sound/usb/usbaudio.h
@@ -67,6 +67,8 @@ struct snd_usb_audio {
#define usb_audio_err(chip, fmt, args...) \
dev_err(&(chip)->dev->dev, fmt, ##args)
+#define usb_audio_err_ratelimited(chip, fmt, args...) \
+ dev_err_ratelimited(&(chip)->dev->dev, fmt, ##args)
#define usb_audio_warn(chip, fmt, args...) \
dev_warn(&(chip)->dev->dev, fmt, ##args)
#define usb_audio_info(chip, fmt, args...) \