ALSA: line6: Add high-speed USB support
This has two parts: * intervals_per_second setup (high speed needs 8000, instead of 1000) * iso_buffers setup (count of iso buffers depends on USB speed, 2 is not enough for high speed) Signed-off-by: Andrej Krutak <dev@andree.sk> Signed-off-by: Takashi Iwai <tiwai@suse.de>
This commit is contained in:
parent
b2233d97a0
commit
79faa2b048
|
@ -181,7 +181,15 @@ static void audio_in_callback(struct urb *urb)
|
||||||
|
|
||||||
length += fsize;
|
length += fsize;
|
||||||
|
|
||||||
/* the following assumes LINE6_ISO_PACKETS == 1: */
|
BUILD_BUG_ON_MSG(LINE6_ISO_PACKETS != 1,
|
||||||
|
"The following code assumes LINE6_ISO_PACKETS == 1");
|
||||||
|
/* TODO:
|
||||||
|
* Also, if iso_buffers != 2, the prev frame is almost random at
|
||||||
|
* playback side.
|
||||||
|
* This needs to be redesigned. It should be "stable", but we may
|
||||||
|
* experience sync problems on such high-speed configs.
|
||||||
|
*/
|
||||||
|
|
||||||
line6pcm->prev_fbuf = fbuf;
|
line6pcm->prev_fbuf = fbuf;
|
||||||
line6pcm->prev_fsize = fsize;
|
line6pcm->prev_fsize = fsize;
|
||||||
|
|
||||||
|
|
|
@ -462,14 +462,18 @@ static void line6_destruct(struct snd_card *card)
|
||||||
static void line6_get_interval(struct usb_line6 *line6)
|
static void line6_get_interval(struct usb_line6 *line6)
|
||||||
{
|
{
|
||||||
struct usb_device *usbdev = line6->usbdev;
|
struct usb_device *usbdev = line6->usbdev;
|
||||||
struct usb_host_endpoint *ep;
|
struct usb_host_endpoint *ep = usbdev->ep_in[line6->properties->ep_ctrl_r];
|
||||||
unsigned pipe = usb_rcvintpipe(usbdev, line6->properties->ep_ctrl_r);
|
|
||||||
unsigned epnum = usb_pipeendpoint(pipe);
|
|
||||||
|
|
||||||
ep = usbdev->ep_in[epnum];
|
|
||||||
line6->iso_buffers = LINE6_ISO_BUFFERS;
|
|
||||||
if (ep) {
|
if (ep) {
|
||||||
line6->interval = ep->desc.bInterval;
|
line6->interval = ep->desc.bInterval;
|
||||||
|
if (usbdev->speed == USB_SPEED_LOW) {
|
||||||
|
line6->intervals_per_second = USB_LOW_INTERVALS_PER_SECOND;
|
||||||
|
line6->iso_buffers = USB_LOW_ISO_BUFFERS;
|
||||||
|
} else {
|
||||||
|
line6->intervals_per_second = USB_HIGH_INTERVALS_PER_SECOND;
|
||||||
|
line6->iso_buffers = USB_HIGH_ISO_BUFFERS;
|
||||||
|
}
|
||||||
|
|
||||||
line6->max_packet_size = le16_to_cpu(ep->desc.wMaxPacketSize);
|
line6->max_packet_size = le16_to_cpu(ep->desc.wMaxPacketSize);
|
||||||
} else {
|
} else {
|
||||||
dev_err(line6->ifcdev,
|
dev_err(line6->ifcdev,
|
||||||
|
@ -559,6 +563,7 @@ int line6_probe(struct usb_interface *interface,
|
||||||
/* query interface number */
|
/* query interface number */
|
||||||
interface_number = interface->cur_altsetting->desc.bInterfaceNumber;
|
interface_number = interface->cur_altsetting->desc.bInterfaceNumber;
|
||||||
|
|
||||||
|
/* TODO reserves the bus bandwidth even without actual transfer */
|
||||||
ret = usb_set_interface(usbdev, interface_number,
|
ret = usb_set_interface(usbdev, interface_number,
|
||||||
properties->altsetting);
|
properties->altsetting);
|
||||||
if (ret < 0) {
|
if (ret < 0) {
|
||||||
|
|
|
@ -18,7 +18,13 @@
|
||||||
|
|
||||||
#include "midi.h"
|
#include "midi.h"
|
||||||
|
|
||||||
#define USB_INTERVALS_PER_SECOND 1000
|
/* USB 1.1 speed configuration */
|
||||||
|
#define USB_LOW_INTERVALS_PER_SECOND 1000
|
||||||
|
#define USB_LOW_ISO_BUFFERS 2
|
||||||
|
|
||||||
|
/* USB 2.0+ speed configuration */
|
||||||
|
#define USB_HIGH_INTERVALS_PER_SECOND 8000
|
||||||
|
#define USB_HIGH_ISO_BUFFERS 16
|
||||||
|
|
||||||
/* Fallback USB interval and max packet size values */
|
/* Fallback USB interval and max packet size values */
|
||||||
#define LINE6_FALLBACK_INTERVAL 10
|
#define LINE6_FALLBACK_INTERVAL 10
|
||||||
|
@ -109,12 +115,15 @@ struct usb_line6 {
|
||||||
/* Properties */
|
/* Properties */
|
||||||
const struct line6_properties *properties;
|
const struct line6_properties *properties;
|
||||||
|
|
||||||
/* Interval (ms) */
|
/* Interval for data USB packets */
|
||||||
int interval;
|
int interval;
|
||||||
|
/* ...for isochronous transfers framing */
|
||||||
|
int intervals_per_second;
|
||||||
|
|
||||||
/* Number of isochronous URBs used for frame transfers */
|
/* Number of isochronous URBs used for frame transfers */
|
||||||
int iso_buffers;
|
int iso_buffers;
|
||||||
|
|
||||||
/* Maximum size of USB packet */
|
/* Maximum size of data USB packet */
|
||||||
int max_packet_size;
|
int max_packet_size;
|
||||||
|
|
||||||
/* Device representing the USB interface */
|
/* Device representing the USB interface */
|
||||||
|
|
|
@ -20,9 +20,6 @@
|
||||||
|
|
||||||
#include "driver.h"
|
#include "driver.h"
|
||||||
|
|
||||||
/* number of URBs */
|
|
||||||
#define LINE6_ISO_BUFFERS 2
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
number of USB frames per URB
|
number of USB frames per URB
|
||||||
The Line 6 Windows driver always transmits two frames per packet, but
|
The Line 6 Windows driver always transmits two frames per packet, but
|
||||||
|
@ -31,7 +28,9 @@
|
||||||
*/
|
*/
|
||||||
#define LINE6_ISO_PACKETS 1
|
#define LINE6_ISO_PACKETS 1
|
||||||
|
|
||||||
/* in a "full speed" device (such as the PODxt Pro) this means 1ms */
|
/* in a "full speed" device (such as the PODxt Pro) this means 1ms,
|
||||||
|
* for "high speed" it's 1/8ms
|
||||||
|
*/
|
||||||
#define LINE6_ISO_INTERVAL 1
|
#define LINE6_ISO_INTERVAL 1
|
||||||
|
|
||||||
#define LINE6_IMPULSE_DEFAULT_PERIOD 100
|
#define LINE6_IMPULSE_DEFAULT_PERIOD 100
|
||||||
|
|
|
@ -151,7 +151,7 @@ static int submit_audio_out_urb(struct snd_line6_pcm *line6pcm)
|
||||||
line6pcm->properties->rates.rats[0].num_min;
|
line6pcm->properties->rates.rats[0].num_min;
|
||||||
const int frame_factor =
|
const int frame_factor =
|
||||||
line6pcm->properties->rates.rats[0].den *
|
line6pcm->properties->rates.rats[0].den *
|
||||||
(USB_INTERVALS_PER_SECOND / LINE6_ISO_INTERVAL);
|
(line6pcm->line6->intervals_per_second / LINE6_ISO_INTERVAL);
|
||||||
struct urb *urb_out;
|
struct urb *urb_out;
|
||||||
|
|
||||||
index = find_first_zero_bit(&line6pcm->out.active_urbs,
|
index = find_first_zero_bit(&line6pcm->out.active_urbs,
|
||||||
|
|
Loading…
Reference in a new issue