Merge tag 'asoc-v4.9' of git://git.kernel.org/pub/scm/linux/kernel/git/broonie/sound...
[cascardo/linux.git] / sound / usb / line6 / driver.h
index 7da643e..7e3a3aa 100644 (file)
 #ifndef DRIVER_H
 #define DRIVER_H
 
-#include <linux/spinlock.h>
 #include <linux/usb.h>
+#include <linux/mutex.h>
+#include <linux/kfifo.h>
 #include <sound/core.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 */
 #define LINE6_FALLBACK_INTERVAL 10
 #define LINE6_FALLBACK_MAXPACKETSIZE 16
 
 #define LINE6_TIMEOUT 1
-#define LINE6_BUFSIZE_LISTEN 32
-#define LINE6_MESSAGE_MAXLEN 256
+#define LINE6_BUFSIZE_LISTEN 64
+#define LINE6_MIDI_MESSAGE_MAXLEN 256
+
+#define LINE6_RAW_MESSAGES_MAXCOUNT_ORDER 7
+/* 4k packets are common, BUFSIZE * MAXCOUNT should be bigger... */
+#define LINE6_RAW_MESSAGES_MAXCOUNT (1 << LINE6_RAW_MESSAGES_MAXCOUNT_ORDER)
+
+
+#if LINE6_BUFSIZE_LISTEN > 65535
+#error "Use dynamic fifo instead"
+#endif
 
 /*
        Line 6 MIDI control commands
@@ -94,8 +110,12 @@ enum {
        LINE6_CAP_CONTROL =     1 << 0,
        /* device supports PCM input/output via USB */
        LINE6_CAP_PCM =         1 << 1,
-       /* device support hardware monitoring */
+       /* device supports hardware monitoring */
        LINE6_CAP_HWMON =       1 << 2,
+       /* device requires output data when input is read */
+       LINE6_CAP_IN_NEEDS_OUT = 1 << 3,
+       /* device uses raw MIDI via USB (data endpoints) */
+       LINE6_CAP_CONTROL_MIDI = 1 << 4,
 };
 
 /*
@@ -109,10 +129,15 @@ struct usb_line6 {
        /* Properties */
        const struct line6_properties *properties;
 
-       /* Interval (ms) */
+       /* Interval for data USB packets */
        int interval;
+       /* ...for isochronous transfers framing */
+       int intervals_per_second;
+
+       /* Number of isochronous URBs used for frame transfers */
+       int iso_buffers;
 
-       /* Maximum size of USB packet */
+       /* Maximum size of data USB packet */
        int max_packet_size;
 
        /* Device representing the USB interface */
@@ -129,18 +154,30 @@ struct usb_line6 {
        /* Line 6 MIDI device data structure */
        struct snd_line6_midi *line6midi;
 
-       /* URB for listening to PODxt Pro control endpoint */
+       /* URB for listening to POD data endpoint */
        struct urb *urb_listen;
 
-       /* Buffer for listening to PODxt Pro control endpoint */
+       /* Buffer for incoming data from POD data endpoint */
        unsigned char *buffer_listen;
 
-       /* Buffer for message to be processed */
+       /* Buffer for message to be processed, generated from MIDI layer */
        unsigned char *buffer_message;
 
-       /* Length of message to be processed */
+       /* Length of message to be processed, generated from MIDI layer  */
        int message_length;
 
+       /* Circular buffer for non-MIDI control messages */
+       struct {
+               struct mutex read_lock;
+               wait_queue_head_t wait_queue;
+               unsigned int active:1;
+               STRUCT_KFIFO_REC_2(LINE6_BUFSIZE_LISTEN * LINE6_RAW_MESSAGES_MAXCOUNT)
+                       fifo;
+       } messages;
+
+       /* If MIDI is supported, buffer_message contains the pre-processed data;
+        * otherwise the data is only in urb_listen (buffer_incoming).
+        */
        void (*process_message)(struct usb_line6 *);
        void (*disconnect)(struct usb_line6 *line6);
 };