summaryrefslogtreecommitdiffstats
path: root/sound/usb/quirks.c
diff options
context:
space:
mode:
authorDaniel Mack <zonque@gmail.com>2012-09-04 10:23:07 +0200
committerTakashi Iwai <tiwai@suse.de>2012-09-04 11:31:14 +0200
commit2b58fd5b3193fd3af3d15114d95706087d25a7fe (patch)
tree929c51bd48ee1637f963fa520bf31eee04927861 /sound/usb/quirks.c
parentc05fce586d4da2dfe0309bef3795a8586e967bc3 (diff)
downloadlinux-2b58fd5b3193fd3af3d15114d95706087d25a7fe.tar.bz2
ALSA: snd-usb: Add quirks for Playback Designs devices
Playback Designs' USB devices have some hardware limitations on their USB interface. In particular: - They need a 20ms delay after each class compliant request as the hardware ACKs the USB packets before the device is actually ready for the next command. Sending data immediately will result in buffer overflows in the hardware. - The devices send bogus feedback data at the start of each stream which confuse the feedback format auto-detection. This patch introduces a new quirks hook that is called after each control packet and which adds a delay for all devices that match Playback Designs' USB VID for now. In addition, it adds a counter to snd_usb_endpoint to drop received packets on the floor. Another new quirks function that is called once an endpoint is started initializes that counter for these devices on their sync endpoint. Signed-off-by: Daniel Mack <zonque@gmail.com> Reported-and-tested-by: Andreas Koch <andreas@akdesigninc.com> Supported-by: Demian Martin <demianm_1@yahoo.com> Signed-off-by: Takashi Iwai <tiwai@suse.de>
Diffstat (limited to 'sound/usb/quirks.c')
-rw-r--r--sound/usb/quirks.c24
1 files changed, 24 insertions, 0 deletions
diff --git a/sound/usb/quirks.c b/sound/usb/quirks.c
index 27817266867a..0f58b4b6d702 100644
--- a/sound/usb/quirks.c
+++ b/sound/usb/quirks.c
@@ -761,3 +761,27 @@ void snd_usb_set_format_quirk(struct snd_usb_substream *subs,
}
}
+void snd_usb_endpoint_start_quirk(struct snd_usb_endpoint *ep)
+{
+ /*
+ * "Playback Design" products send bogus feedback data at the start
+ * of the stream. Ignore them.
+ */
+ if ((le16_to_cpu(ep->chip->dev->descriptor.idVendor) == 0x23ba) &&
+ ep->type == SND_USB_ENDPOINT_TYPE_SYNC)
+ ep->skip_packets = 4;
+}
+
+void snd_usb_ctl_msg_quirk(struct usb_device *dev, unsigned int pipe,
+ __u8 request, __u8 requesttype, __u16 value,
+ __u16 index, void *data, __u16 size)
+{
+ /*
+ * "Playback Design" products need a 20ms delay after each
+ * class compliant request
+ */
+ if ((le16_to_cpu(dev->descriptor.idVendor) == 0x23ba) &&
+ (requesttype & USB_TYPE_MASK) == USB_TYPE_CLASS)
+ mdelay(20);
+}
+