ALSA: line6: Split to each driver
authorTakashi Iwai <tiwai@suse.de>
Thu, 15 Jan 2015 07:22:31 +0000 (08:22 +0100)
committerTakashi Iwai <tiwai@suse.de>
Tue, 20 Jan 2015 07:14:17 +0000 (08:14 +0100)
Split to each individual driver for POD, PODHD, TonePort and Variax
with a core LINE6 helper module.  The new modules follow the standard
ALSA naming rule with snd prefix: snd-usb-pod, snd-usb-podhd,
snd-usb-toneport and snd-usb-variax, together with the corresponding
CONFIG_SND_USB_* Kconfig items.

Tested-by: Chris Rorvick <chris@rorvick.com>
Signed-off-by: Takashi Iwai <tiwai@suse.de>
18 files changed:
sound/usb/Makefile
sound/usb/line6/Kconfig
sound/usb/line6/Makefile
sound/usb/line6/audio.c
sound/usb/line6/capture.c
sound/usb/line6/driver.c
sound/usb/line6/driver.h
sound/usb/line6/midi.c
sound/usb/line6/pcm.c
sound/usb/line6/playback.c
sound/usb/line6/pod.c
sound/usb/line6/pod.h [deleted file]
sound/usb/line6/podhd.c
sound/usb/line6/podhd.h [deleted file]
sound/usb/line6/toneport.c
sound/usb/line6/toneport.h [deleted file]
sound/usb/line6/variax.c
sound/usb/line6/variax.h [deleted file]

index 54045b745d11eec4d021a74303ca935e7446a90d..2d2d122b069f37974b7353d781023cf99cbe11ef 100644 (file)
@@ -25,4 +25,4 @@ obj-$(CONFIG_SND_USB_USX2Y) += snd-usbmidi-lib.o
 obj-$(CONFIG_SND_USB_US122L) += snd-usbmidi-lib.o
 
 obj-$(CONFIG_SND) += misc/ usx2y/ caiaq/ 6fire/ hiface/ bcd2000/
-obj-$(CONFIG_LINE6_USB)                += line6/
+obj-$(CONFIG_SND_USB_LINE6)    += line6/
index 4f1219b4c692f65bf725c2c243ca2906297e9315..33deb419dde893f94addb84806cda4aec2712302 100644 (file)
@@ -1,12 +1,14 @@
-menuconfig LINE6_USB
-       tristate "Line6 USB support"
-       depends on USB && SND
+config SND_USB_LINE6
+       tristate
        select SND_RAWMIDI
        select SND_PCM
+
+config SND_USB_POD
+       tristate "Line6 POD USB support"
+       select SND_USB_LINE6
        help
-         This is a driver for the guitar amp, cab, and effects modeller
-         PODxt Pro by Line6 (and similar devices), supporting the
-         following features:
+         This is a driver for PODxt and other similar devices,
+         supporting the following features:
            * Reading/writing individual parameters
            * Reading/writing complete channel, effects setup, and amp
              setup data
@@ -18,14 +20,27 @@ menuconfig LINE6_USB
            * Signal routing (record clean/processed guitar signal,
              re-amping)
 
-         Preliminary support for the Variax Workbench and TonePort
-         devices is included.
+config SND_USB_PODHD
+       tristate "Line6 POD HD300/400/500 USB support"
+       select SND_USB_LINE6
+       help
+         This is a driver for POD HD300, 400 and 500 devices.
 
-if LINE6_USB
+config SND_USB_TONEPORT
+       tristate "TonePort GX, UX1 and UX2 USB support"
+       select SND_USB_LINE6
+       help
+         This is a driver for TonePort GX, UX1 and UX2 devices.
+
+config SND_USB_VARIAX
+       tristate "Variax Workbench USB support"
+       select SND_USB_LINE6
+       help
+         This is a driver for Variax Workbench device.
 
 config LINE6_USB_IMPULSE_RESPONSE
        bool "measure impulse response"
-       default n
+       depends on SND_USB_LINE6
        help
          Say Y here to add code to measure the impulse response of a Line6
          device. This is more accurate than user-space methods since it
@@ -35,4 +50,3 @@ config LINE6_USB_IMPULSE_RESPONSE
 
          If unsure, say N.
 
-endif # LINE6_USB
index ae5c374b0f87510665217c6de0607a4821363b40..fa3a78dac09790b5f82e7f2b404a3ffdabf28ab0 100644 (file)
@@ -1,14 +1,19 @@
-obj-$(CONFIG_LINE6_USB)                += line6usb.o
-
-line6usb-y :=          \
+snd-usb-line6-y :=             \
                audio.o         \
                capture.o       \
                driver.o        \
                midi.o          \
                midibuf.o       \
                pcm.o           \
-               playback.o      \
-               pod.o           \
-               toneport.o      \
-               variax.o        \
-               podhd.o
+               playback.o
+
+snd-usb-pod-y := pod.o
+snd-usb-podhd-y := podhd.o
+snd-usb-toneport-y := toneport.o
+snd-usb-variax-y := variax.o
+
+obj-$(CONFIG_SND_USB_LINE6)    += snd-usb-line6.o
+obj-$(CONFIG_SND_USB_POD)      += snd-usb-pod.o
+obj-$(CONFIG_SND_USB_PODHD)    += snd-usb-podhd.o
+obj-$(CONFIG_SND_USB_TONEPORT) += snd-usb-toneport.o
+obj-$(CONFIG_SND_USB_VARIAX)   += snd-usb-variax.o
index 171d80c1b02071fdadc2e7111e34b0cde49565a6..95686e5af4bdefadb52f7d1bcd17a8d6410d06b7 100644 (file)
@@ -40,6 +40,7 @@ int line6_init_audio(struct usb_line6 *line6)
                dev_name(line6->ifcdev));
        return 0;
 }
+EXPORT_SYMBOL_GPL(line6_init_audio);
 
 /*
        Register the Line6 USB audio system.
@@ -54,6 +55,7 @@ int line6_register_audio(struct usb_line6 *line6)
 
        return 0;
 }
+EXPORT_SYMBOL_GPL(line6_register_audio);
 
 /*
        Cleanup the Line6 USB audio system.
@@ -69,3 +71,4 @@ void line6_cleanup_audio(struct usb_line6 *line6)
        snd_card_free(card);
        line6->card = NULL;
 }
+EXPORT_SYMBOL_GPL(line6_cleanup_audio);
index f24c7c5e0a3ef613c4600edc2fc8b37751f9eed5..da4ab013ea8e942d4108b484639475437bb2cbf1 100644 (file)
@@ -18,7 +18,6 @@
 #include "capture.h"
 #include "driver.h"
 #include "pcm.h"
-#include "pod.h"
 
 /*
        Find a free URB and submit it.
index 19904d677114920e42529758248b070744a69696..149c393c73024be21163cc530579b7398e3a3b30 100644 (file)
@@ -11,6 +11,7 @@
 
 #include <linux/kernel.h>
 #include <linux/module.h>
+#include <linux/export.h>
 #include <linux/slab.h>
 #include <linux/usb.h>
 
 #include "driver.h"
 #include "midi.h"
 #include "playback.h"
-#include "pod.h"
-#include "podhd.h"
 #include "revision.h"
-#include "toneport.h"
 #include "usbdefs.h"
-#include "variax.h"
 
 #define DRIVER_AUTHOR  "Markus Grabner <grabner@icg.tugraz.at>"
 #define DRIVER_DESC    "Line6 USB Driver"
 #define DRIVER_VERSION "0.9.1beta" DRIVER_REVISION
 
-#define LINE6_DEVICE(prod) USB_DEVICE(0x0e41, prod)
-#define LINE6_IF_NUM(prod, n) USB_DEVICE_INTERFACE_NUMBER(0x0e41, prod, n)
-
-/* table of devices that work with this driver */
-static const struct usb_device_id line6_id_table[] = {
-       { LINE6_DEVICE(0x4250),    .driver_info = LINE6_BASSPODXT },
-       { LINE6_DEVICE(0x4642),    .driver_info = LINE6_BASSPODXTLIVE },
-       { LINE6_DEVICE(0x4252),    .driver_info = LINE6_BASSPODXTPRO },
-       { LINE6_DEVICE(0x4750),    .driver_info = LINE6_GUITARPORT },
-       { LINE6_IF_NUM(0x5051, 1), .driver_info = LINE6_POCKETPOD },
-       { LINE6_DEVICE(0x5057),    .driver_info = LINE6_PODHD300 },
-       { LINE6_DEVICE(0x5058),    .driver_info = LINE6_PODHD400 },
-       { LINE6_IF_NUM(0x414D, 0), .driver_info = LINE6_PODHD500_0 },
-       { LINE6_IF_NUM(0x414D, 1), .driver_info = LINE6_PODHD500_1 },
-       { LINE6_DEVICE(0x4153),    .driver_info = LINE6_PODSTUDIO_GX },
-       { LINE6_DEVICE(0x4150),    .driver_info = LINE6_PODSTUDIO_UX1 },
-       { LINE6_IF_NUM(0x4151, 0), .driver_info = LINE6_PODSTUDIO_UX2 },
-       { LINE6_DEVICE(0x5044),    .driver_info = LINE6_PODXT },
-       { LINE6_IF_NUM(0x4650, 0), .driver_info = LINE6_PODXTLIVE_POD },
-       { LINE6_IF_NUM(0x4650, 1), .driver_info = LINE6_PODXTLIVE_VARIAX },
-       { LINE6_DEVICE(0x5050),    .driver_info = LINE6_PODXTPRO },
-       { LINE6_DEVICE(0x4147),    .driver_info = LINE6_TONEPORT_GX },
-       { LINE6_DEVICE(0x4141),    .driver_info = LINE6_TONEPORT_UX1 },
-       { LINE6_IF_NUM(0x4142, 0), .driver_info = LINE6_TONEPORT_UX2 },
-       { LINE6_DEVICE(0x534d),    .driver_info = LINE6_VARIAX },
-       {}
-};
-
-MODULE_DEVICE_TABLE(usb, line6_id_table);
-
-static const struct line6_properties line6_properties_table[] = {
-       [LINE6_BASSPODXT] = {
-               .id = "BassPODxt",
-               .name = "BassPODxt",
-               .capabilities   = LINE6_CAP_CONTROL
-                               | LINE6_CAP_PCM
-                               | LINE6_CAP_HWMON,
-               .altsetting = 5,
-               .ep_ctrl_r = 0x84,
-               .ep_ctrl_w = 0x03,
-               .ep_audio_r = 0x82,
-               .ep_audio_w = 0x01,
-       },
-       [LINE6_BASSPODXTLIVE] = {
-               .id = "BassPODxtLive",
-               .name = "BassPODxt Live",
-               .capabilities   = LINE6_CAP_CONTROL
-                               | LINE6_CAP_PCM
-                               | LINE6_CAP_HWMON,
-               .altsetting = 1,
-               .ep_ctrl_r = 0x84,
-               .ep_ctrl_w = 0x03,
-               .ep_audio_r = 0x82,
-               .ep_audio_w = 0x01,
-       },
-       [LINE6_BASSPODXTPRO] = {
-               .id = "BassPODxtPro",
-               .name = "BassPODxt Pro",
-               .capabilities   = LINE6_CAP_CONTROL
-                               | LINE6_CAP_PCM
-                               | LINE6_CAP_HWMON,
-               .altsetting = 5,
-               .ep_ctrl_r = 0x84,
-               .ep_ctrl_w = 0x03,
-               .ep_audio_r = 0x82,
-               .ep_audio_w = 0x01,
-       },
-       [LINE6_GUITARPORT] = {
-               .id = "GuitarPort",
-               .name = "GuitarPort",
-               .capabilities   = LINE6_CAP_PCM,
-               .altsetting = 2,  /* 1..4 seem to be ok */
-               /* no control channel */
-               .ep_audio_r = 0x82,
-               .ep_audio_w = 0x01,
-       },
-       [LINE6_POCKETPOD] = {
-               .id = "PocketPOD",
-               .name = "Pocket POD",
-               .capabilities   = LINE6_CAP_CONTROL,
-               .altsetting = 0,
-               .ep_ctrl_r = 0x82,
-               .ep_ctrl_w = 0x02,
-               /* no audio channel */
-       },
-       [LINE6_PODHD300] = {
-               .id = "PODHD300",
-               .name = "POD HD300",
-               .capabilities   = LINE6_CAP_CONTROL
-                               | LINE6_CAP_PCM
-                               | LINE6_CAP_HWMON,
-               .altsetting = 5,
-               .ep_ctrl_r = 0x84,
-               .ep_ctrl_w = 0x03,
-               .ep_audio_r = 0x82,
-               .ep_audio_w = 0x01,
-       },
-       [LINE6_PODHD400] = {
-               .id = "PODHD400",
-               .name = "POD HD400",
-               .capabilities   = LINE6_CAP_CONTROL
-                               | LINE6_CAP_PCM
-                               | LINE6_CAP_HWMON,
-               .altsetting = 5,
-               .ep_ctrl_r = 0x84,
-               .ep_ctrl_w = 0x03,
-               .ep_audio_r = 0x82,
-               .ep_audio_w = 0x01,
-       },
-       [LINE6_PODHD500_0] = {
-               .id = "PODHD500",
-               .name = "POD HD500",
-               .capabilities   = LINE6_CAP_CONTROL
-                               | LINE6_CAP_PCM
-                               | LINE6_CAP_HWMON,
-               .altsetting = 1,
-               .ep_ctrl_r = 0x81,
-               .ep_ctrl_w = 0x01,
-               .ep_audio_r = 0x86,
-               .ep_audio_w = 0x02,
-       },
-       [LINE6_PODHD500_1] = {
-               .id = "PODHD500",
-               .name = "POD HD500",
-               .capabilities   = LINE6_CAP_CONTROL
-                               | LINE6_CAP_PCM
-                               | LINE6_CAP_HWMON,
-               .altsetting = 1,
-               .ep_ctrl_r = 0x81,
-               .ep_ctrl_w = 0x01,
-               .ep_audio_r = 0x86,
-               .ep_audio_w = 0x02,
-       },
-       [LINE6_PODSTUDIO_GX] = {
-               .id = "PODStudioGX",
-               .name = "POD Studio GX",
-               .capabilities   = LINE6_CAP_PCM,
-               .altsetting = 2,  /* 1..4 seem to be ok */
-               /* no control channel */
-               .ep_audio_r = 0x82,
-               .ep_audio_w = 0x01,
-       },
-       [LINE6_PODSTUDIO_UX1] = {
-               .id = "PODStudioUX1",
-               .name = "POD Studio UX1",
-               .capabilities   = LINE6_CAP_PCM,
-               .altsetting = 2,  /* 1..4 seem to be ok */
-               /* no control channel */
-               .ep_audio_r = 0x82,
-               .ep_audio_w = 0x01,
-       },
-       [LINE6_PODSTUDIO_UX2] = {
-               .id = "PODStudioUX2",
-               .name = "POD Studio UX2",
-               .capabilities   = LINE6_CAP_PCM,
-               .altsetting = 2,  /* defaults to 44.1kHz, 16-bit */
-               /* no control channel */
-               .ep_audio_r = 0x82,
-               .ep_audio_w = 0x01,
-       },
-       [LINE6_PODXT] = {
-               .id = "PODxt",
-               .name = "PODxt",
-               .capabilities   = LINE6_CAP_CONTROL
-                               | LINE6_CAP_PCM
-                               | LINE6_CAP_HWMON,
-               .altsetting = 5,
-               .ep_ctrl_r = 0x84,
-               .ep_ctrl_w = 0x03,
-               .ep_audio_r = 0x82,
-               .ep_audio_w = 0x01,
-       },
-       [LINE6_PODXTLIVE_POD] = {
-               .id = "PODxtLive",
-               .name = "PODxt Live",
-               .capabilities   = LINE6_CAP_CONTROL
-                               | LINE6_CAP_PCM
-                               | LINE6_CAP_HWMON,
-               .altsetting = 1,
-               .ep_ctrl_r = 0x84,
-               .ep_ctrl_w = 0x03,
-               .ep_audio_r = 0x82,
-               .ep_audio_w = 0x01,
-       },
-       [LINE6_PODXTLIVE_VARIAX] = {
-               .id = "PODxtLive",
-               .name = "PODxt Live",
-               .capabilities   = LINE6_CAP_CONTROL
-                               | LINE6_CAP_PCM
-                               | LINE6_CAP_HWMON,
-               .altsetting = 1,
-               .ep_ctrl_r = 0x86,
-               .ep_ctrl_w = 0x05,
-               .ep_audio_r = 0x82,
-               .ep_audio_w = 0x01,
-       },
-       [LINE6_PODXTPRO] = {
-               .id = "PODxtPro",
-               .name = "PODxt Pro",
-               .capabilities   = LINE6_CAP_CONTROL
-                               | LINE6_CAP_PCM
-                               | LINE6_CAP_HWMON,
-               .altsetting = 5,
-               .ep_ctrl_r = 0x84,
-               .ep_ctrl_w = 0x03,
-               .ep_audio_r = 0x82,
-               .ep_audio_w = 0x01,
-       },
-       [LINE6_TONEPORT_GX] = {
-               .id = "TonePortGX",
-               .name = "TonePort GX",
-               .capabilities   = LINE6_CAP_PCM,
-               .altsetting = 2,  /* 1..4 seem to be ok */
-               /* no control channel */
-               .ep_audio_r = 0x82,
-               .ep_audio_w = 0x01,
-       },
-       [LINE6_TONEPORT_UX1] = {
-               .id = "TonePortUX1",
-               .name = "TonePort UX1",
-               .capabilities   = LINE6_CAP_PCM,
-               .altsetting = 2,  /* 1..4 seem to be ok */
-               /* no control channel */
-               .ep_audio_r = 0x82,
-               .ep_audio_w = 0x01,
-       },
-       [LINE6_TONEPORT_UX2] = {
-               .id = "TonePortUX2",
-               .name = "TonePort UX2",
-               .capabilities   = LINE6_CAP_PCM,
-               .altsetting = 2,  /* defaults to 44.1kHz, 16-bit */
-               /* no control channel */
-               .ep_audio_r = 0x82,
-               .ep_audio_w = 0x01,
-       },
-       [LINE6_VARIAX] = {
-               .id = "Variax",
-               .name = "Variax Workbench",
-               .capabilities   = LINE6_CAP_CONTROL,
-               .altsetting = 1,
-               .ep_ctrl_r = 0x82,
-               .ep_ctrl_w = 0x01,
-               /* no audio channel */
-       }
-};
-
 /*
        This is Line6's MIDI manufacturer ID.
 */
 const unsigned char line6_midi_id[] = {
        0x00, 0x01, 0x0c
 };
+EXPORT_SYMBOL_GPL(line6_midi_id);
 
 /*
        Code to request version of POD, Variax interface
@@ -417,6 +169,7 @@ void line6_start_timer(struct timer_list *timer, unsigned int msecs,
        setup_timer(timer, function, data);
        mod_timer(timer, jiffies + msecs * HZ / 1000);
 }
+EXPORT_SYMBOL_GPL(line6_start_timer);
 
 /*
        Asynchronously send raw message.
@@ -450,6 +203,7 @@ int line6_send_raw_message_async(struct usb_line6 *line6, const char *buffer,
        /* start sending: */
        return line6_send_raw_message_async_part(msg, urb);
 }
+EXPORT_SYMBOL_GPL(line6_send_raw_message_async);
 
 /*
        Send asynchronous device version request.
@@ -471,6 +225,7 @@ int line6_version_request_async(struct usb_line6 *line6)
        kfree(buffer);
        return retval;
 }
+EXPORT_SYMBOL_GPL(line6_version_request_async);
 
 /*
        Send sysex message in pieces of wMaxPacketSize bytes.
@@ -482,6 +237,7 @@ int line6_send_sysex_message(struct usb_line6 *line6, const char *buffer,
                                      size + SYSEX_EXTRA_SIZE) -
            SYSEX_EXTRA_SIZE;
 }
+EXPORT_SYMBOL_GPL(line6_send_sysex_message);
 
 /*
        Allocate buffer for sysex message and prepare header.
@@ -503,6 +259,7 @@ char *line6_alloc_sysex_buffer(struct usb_line6 *line6, int code1, int code2,
        buffer[sizeof(line6_midi_id) + 3 + size] = LINE6_SYSEX_END;
        return buffer;
 }
+EXPORT_SYMBOL_GPL(line6_alloc_sysex_buffer);
 
 /*
        Notification of data received from the Line6 device.
@@ -658,6 +415,7 @@ int line6_read_data(struct usb_line6 *line6, int address, void *data,
 
        return 0;
 }
+EXPORT_SYMBOL_GPL(line6_read_data);
 
 /*
        Write data to device.
@@ -702,6 +460,7 @@ int line6_write_data(struct usb_line6 *line6, int address, void *data,
 
        return 0;
 }
+EXPORT_SYMBOL_GPL(line6_write_data);
 
 /*
        Read Line6 device serial number.
@@ -712,6 +471,7 @@ int line6_read_serial_number(struct usb_line6 *line6, int *serial_number)
        return line6_read_data(line6, 0x80d0, serial_number,
                               sizeof(*serial_number));
 }
+EXPORT_SYMBOL_GPL(line6_read_serial_number);
 
 /*
        No operation (i.e., unsupported).
@@ -721,6 +481,7 @@ ssize_t line6_nop_read(struct device *dev, struct device_attribute *attr,
 {
        return 0;
 }
+EXPORT_SYMBOL_GPL(line6_nop_read);
 
 /*
        Generic destructor.
@@ -744,30 +505,29 @@ static void line6_destruct(struct usb_interface *interface)
 
        /* make sure the device isn't destructed twice: */
        usb_set_intfdata(interface, NULL);
-
-       /* free interface data: */
-       kfree(line6);
 }
 
 /*
        Probe USB device.
 */
-static int line6_probe(struct usb_interface *interface,
-                      const struct usb_device_id *id)
+int line6_probe(struct usb_interface *interface,
+               struct usb_line6 *line6,
+               const struct line6_properties *properties,
+               int (*private_init)(struct usb_interface *, struct usb_line6 *))
 {
-       enum line6_device_type devtype;
        struct usb_device *usbdev;
-       struct usb_line6 *line6;
-       const struct line6_properties *properties;
        int interface_number;
-       int size = 0;
        int ret;
 
-       if (interface == NULL)
-               return -ENODEV;
+       if (!interface) {
+               ret = -ENODEV;
+               goto err_put;
+       }
        usbdev = interface_to_usbdev(interface);
-       if (usbdev == NULL)
-               return -ENODEV;
+       if (!usbdev) {
+               ret = -ENODEV;
+               goto err_put;
+       }
 
        /* we don't handle multiple configurations */
        if (usbdev->descriptor.bNumConfigurations != 1) {
@@ -775,10 +535,7 @@ static int line6_probe(struct usb_interface *interface,
                goto err_put;
        }
 
-       devtype = id->driver_info;
-
        /* initialize device info: */
-       properties = &line6_properties_table[devtype];
        dev_info(&interface->dev, "Line6 %s found\n", properties->name);
 
        /* query interface number */
@@ -791,76 +548,10 @@ static int line6_probe(struct usb_interface *interface,
                goto err_put;
        }
 
-       /* initialize device data based on device: */
-       switch (devtype) {
-       case LINE6_BASSPODXT:
-       case LINE6_BASSPODXTLIVE:
-       case LINE6_BASSPODXTPRO:
-       case LINE6_PODXT:
-       case LINE6_PODXTPRO:
-               size = sizeof(struct usb_line6_pod);
-               break;
-
-       case LINE6_PODHD300:
-       case LINE6_PODHD400:
-               size = sizeof(struct usb_line6_podhd);
-               break;
-
-       case LINE6_PODHD500_0:
-       case LINE6_PODHD500_1:
-               size = sizeof(struct usb_line6_podhd);
-               break;
-
-       case LINE6_POCKETPOD:
-               size = sizeof(struct usb_line6_pod);
-               break;
-
-       case LINE6_PODSTUDIO_GX:
-       case LINE6_PODSTUDIO_UX1:
-       case LINE6_PODSTUDIO_UX2:
-       case LINE6_TONEPORT_GX:
-       case LINE6_TONEPORT_UX1:
-       case LINE6_TONEPORT_UX2:
-       case LINE6_GUITARPORT:
-               size = sizeof(struct usb_line6_toneport);
-               break;
-
-       case LINE6_PODXTLIVE_POD:
-               size = sizeof(struct usb_line6_pod);
-               break;
-
-       case LINE6_PODXTLIVE_VARIAX:
-               size = sizeof(struct usb_line6_variax);
-               break;
-
-       case LINE6_VARIAX:
-               size = sizeof(struct usb_line6_variax);
-               break;
-
-       default:
-               MISSING_CASE;
-               ret = -ENODEV;
-               goto err_put;
-       }
-
-       if (size == 0) {
-               dev_err(&interface->dev,
-                       "driver bug: interface data size not set\n");
-               ret = -ENODEV;
-               goto err_put;
-       }
-
-       line6 = kzalloc(size, GFP_KERNEL);
-       if (line6 == NULL) {
-               ret = -ENODEV;
-               goto err_put;
-       }
-
        /* store basic data: */
        line6->properties = properties;
        line6->usbdev = usbdev;
        line6->ifcdev = &interface->dev;
-       line6->type = devtype;
 
        /* get data from endpoint descriptor (see usb_maxpacket): */
        {
@@ -903,7 +594,6 @@ static int line6_probe(struct usb_interface *interface,
 
                if (line6->urb_listen == NULL) {
                        dev_err(&interface->dev, "Out of memory\n");
-                       line6_destruct(interface);
                        ret = -ENOMEM;
                        goto err_destruct;
                }
@@ -917,50 +607,7 @@ static int line6_probe(struct usb_interface *interface,
        }
 
        /* initialize device data based on device: */
-       switch (devtype) {
-       case LINE6_BASSPODXT:
-       case LINE6_BASSPODXTLIVE:
-       case LINE6_BASSPODXTPRO:
-       case LINE6_POCKETPOD:
-       case LINE6_PODXT:
-       case LINE6_PODXTPRO:
-               ret = line6_pod_init(interface, line6);
-               break;
-
-       case LINE6_PODHD300:
-       case LINE6_PODHD400:
-       case LINE6_PODHD500_0:
-       case LINE6_PODHD500_1:
-               ret = line6_podhd_init(interface, line6);
-               break;
-
-       case LINE6_PODXTLIVE_POD:
-               ret = line6_pod_init(interface, line6);
-               break;
-
-       case LINE6_PODXTLIVE_VARIAX:
-               ret = line6_variax_init(interface, line6);
-               break;
-
-       case LINE6_VARIAX:
-               ret = line6_variax_init(interface, line6);
-               break;
-
-       case LINE6_PODSTUDIO_GX:
-       case LINE6_PODSTUDIO_UX1:
-       case LINE6_PODSTUDIO_UX2:
-       case LINE6_TONEPORT_GX:
-       case LINE6_TONEPORT_UX1:
-       case LINE6_TONEPORT_UX2:
-       case LINE6_GUITARPORT:
-               ret = line6_toneport_init(interface, line6);
-               break;
-
-       default:
-               MISSING_CASE;
-               ret = -ENODEV;
-       }
-
+       ret = private_init(interface, line6);
        if (ret < 0)
                goto err_destruct;
 
@@ -985,11 +632,12 @@ err_destruct:
 err_put:
        return ret;
 }
+EXPORT_SYMBOL_GPL(line6_probe);
 
 /*
        Line6 device disconnected.
 */
-static void line6_disconnect(struct usb_interface *interface)
+void line6_disconnect(struct usb_interface *interface)
 {
        struct usb_line6 *line6;
        struct usb_device *usbdev;
@@ -1024,17 +672,21 @@ static void line6_disconnect(struct usb_interface *interface)
 
        line6_destruct(interface);
 
+       /* free interface data: */
+       kfree(line6);
+
        /* decrement reference counters: */
        usb_put_intf(interface);
        usb_put_dev(usbdev);
 }
+EXPORT_SYMBOL_GPL(line6_disconnect);
 
 #ifdef CONFIG_PM
 
 /*
        Suspend Line6 device.
 */
-static int line6_suspend(struct usb_interface *interface, pm_message_t message)
+int line6_suspend(struct usb_interface *interface, pm_message_t message)
 {
        struct usb_line6 *line6 = usb_get_intfdata(interface);
        struct snd_line6_pcm *line6pcm = line6->line6pcm;
@@ -1052,11 +704,12 @@ static int line6_suspend(struct usb_interface *interface, pm_message_t message)
 
        return 0;
 }
+EXPORT_SYMBOL_GPL(line6_suspend);
 
 /*
        Resume Line6 device.
 */
-static int line6_resume(struct usb_interface *interface)
+int line6_resume(struct usb_interface *interface)
 {
        struct usb_line6 *line6 = usb_get_intfdata(interface);
 
@@ -1066,47 +719,10 @@ static int line6_resume(struct usb_interface *interface)
        snd_power_change_state(line6->card, SNDRV_CTL_POWER_D0);
        return 0;
 }
-
-/*
-       Resume Line6 device after reset.
-*/
-static int line6_reset_resume(struct usb_interface *interface)
-{
-       struct usb_line6 *line6 = usb_get_intfdata(interface);
-
-       switch (line6->type) {
-       case LINE6_PODSTUDIO_GX:
-       case LINE6_PODSTUDIO_UX1:
-       case LINE6_PODSTUDIO_UX2:
-       case LINE6_TONEPORT_GX:
-       case LINE6_TONEPORT_UX1:
-       case LINE6_TONEPORT_UX2:
-       case LINE6_GUITARPORT:
-               line6_toneport_reset_resume((struct usb_line6_toneport *)line6);
-
-       default:
-               break;
-       }
-
-       return line6_resume(interface);
-}
+EXPORT_SYMBOL_GPL(line6_resume);
 
 #endif /* CONFIG_PM */
 
-static struct usb_driver line6_driver = {
-       .name = DRIVER_NAME,
-       .probe = line6_probe,
-       .disconnect = line6_disconnect,
-#ifdef CONFIG_PM
-       .suspend = line6_suspend,
-       .resume = line6_resume,
-       .reset_resume = line6_reset_resume,
-#endif
-       .id_table = line6_id_table,
-};
-
-module_usb_driver(line6_driver);
-
 MODULE_AUTHOR(DRIVER_AUTHOR);
 MODULE_DESCRIPTION(DRIVER_DESC);
 MODULE_LICENSE("GPL");
index ad203f197e80569ae434307b2a4a1cbbcaf9ec70..31cd318369e900641af911ff0838cf21b43a6d50 100644 (file)
 
 #define DRIVER_NAME "line6usb"
 
-enum line6_device_type {
-       LINE6_BASSPODXT,
-       LINE6_BASSPODXTLIVE,
-       LINE6_BASSPODXTPRO,
-       LINE6_GUITARPORT,
-       LINE6_POCKETPOD,
-       LINE6_PODHD300,
-       LINE6_PODHD400,
-       LINE6_PODHD500_0,
-       LINE6_PODHD500_1,
-       LINE6_PODSTUDIO_GX,
-       LINE6_PODSTUDIO_UX1,
-       LINE6_PODSTUDIO_UX2,
-       LINE6_PODXT,
-       LINE6_PODXTLIVE_POD,
-       LINE6_PODXTLIVE_VARIAX,
-       LINE6_PODXTPRO,
-       LINE6_TONEPORT_GX,
-       LINE6_TONEPORT_UX1,
-       LINE6_TONEPORT_UX2,
-       LINE6_VARIAX
-};
-
 #define LINE6_TIMEOUT 1
 #define LINE6_BUFSIZE_LISTEN 32
 #define LINE6_MESSAGE_MAXLEN 256
@@ -134,11 +111,6 @@ struct usb_line6 {
        */
        struct usb_device *usbdev;
 
-       /**
-                Device type.
-       */
-       enum line6_device_type type;
-
        /**
                 Properties.
        */
@@ -225,4 +197,15 @@ extern int line6_version_request_async(struct usb_line6 *line6);
 extern int line6_write_data(struct usb_line6 *line6, int address, void *data,
                            size_t datalen);
 
+int line6_probe(struct usb_interface *interface,
+               struct usb_line6 *line6,
+               const struct line6_properties *properties,
+               int (*private_init)(struct usb_interface *, struct usb_line6 *));
+void line6_disconnect(struct usb_interface *interface);
+
+#ifdef CONFIG_PM
+int line6_suspend(struct usb_interface *interface, pm_message_t message);
+int line6_resume(struct usb_interface *interface);
+#endif
+
 #endif
index c9d725ae85a0b8669b38cd54b37ab28004482318..2a42d533f49c0bfb7a3e9899f30f4e6504a65bc6 100644 (file)
 
 #include <linux/slab.h>
 #include <linux/usb.h>
+#include <linux/export.h>
 #include <sound/core.h>
 #include <sound/rawmidi.h>
 
 #include "audio.h"
 #include "driver.h"
 #include "midi.h"
-#include "pod.h"
 #include "usbdefs.h"
 
 #define line6_rawmidi_substream_midi(substream) \
@@ -319,3 +319,4 @@ int line6_init_midi(struct usb_line6 *line6)
        spin_lock_init(&line6midi->midi_transmit_lock);
        return 0;
 }
+EXPORT_SYMBOL_GPL(line6_init_midi);
index 6d4e5cd0482c6b8b9e57bee2af52ea9a356bc969..b7348b031bf7aff65aa6bea92d2326de6d4e30cd 100644 (file)
@@ -10,6 +10,7 @@
  */
 
 #include <linux/slab.h>
+#include <linux/export.h>
 #include <sound/core.h>
 #include <sound/control.h>
 #include <sound/pcm.h>
@@ -19,7 +20,6 @@
 #include "capture.h"
 #include "driver.h"
 #include "playback.h"
-#include "pod.h"
 
 #ifdef CONFIG_LINE6_USB_IMPULSE_RESPONSE
 
@@ -195,6 +195,7 @@ pcm_acquire_error:
        line6_pcm_release(line6pcm, flags_final & channels);
        return err;
 }
+EXPORT_SYMBOL_GPL(line6_pcm_acquire);
 
 int line6_pcm_release(struct snd_line6_pcm *line6pcm, int channels)
 {
@@ -223,6 +224,7 @@ int line6_pcm_release(struct snd_line6_pcm *line6pcm, int channels)
 
        return 0;
 }
+EXPORT_SYMBOL_GPL(line6_pcm_release);
 
 /* trigger callback */
 int snd_line6_trigger(struct snd_pcm_substream *substream, int cmd)
@@ -408,6 +410,7 @@ void line6_pcm_disconnect(struct snd_line6_pcm *line6pcm)
        line6_unlink_wait_clear_audio_out_urbs(line6pcm);
        line6_unlink_wait_clear_audio_in_urbs(line6pcm);
 }
+EXPORT_SYMBOL_GPL(line6_pcm_disconnect);
 
 /*
        Create and register the PCM device and mixer entries.
@@ -490,6 +493,7 @@ int line6_init_pcm(struct usb_line6 *line6,
 
        return 0;
 }
+EXPORT_SYMBOL_GPL(line6_init_pcm);
 
 /* prepare pcm callback */
 int snd_line6_prepare(struct snd_pcm_substream *substream)
index da2e3b8876b8e3cb9f480091e2044be8a670b35c..0a874105ccefc36b1f0d9f84008ec67ca656444b 100644 (file)
@@ -18,7 +18,6 @@
 #include "capture.h"
 #include "driver.h"
 #include "pcm.h"
-#include "pod.h"
 #include "playback.h"
 
 /*
index 85a43631996e351e3cb0c7da2ce1240d1b5a3ce1..dde9c2b8ad0fed3694e497c9f02c69c9f20a458d 100644 (file)
 
 #include <linux/slab.h>
 #include <linux/wait.h>
+#include <linux/interrupt.h>
+#include <linux/module.h>
+#include <linux/usb.h>
+
+#include <sound/core.h>
 #include <sound/control.h>
 
 #include "audio.h"
 #include "capture.h"
 #include "driver.h"
 #include "playback.h"
-#include "pod.h"
+#include "usbdefs.h"
+
+/*
+       Locate name in binary program dump
+*/
+#define        POD_NAME_OFFSET 0
+#define        POD_NAME_LENGTH 16
+
+/*
+       Other constants
+*/
+#define POD_CONTROL_SIZE 0x80
+#define POD_BUFSIZE_DUMPREQ 7
+#define POD_STARTUP_DELAY 1000
+
+/*
+       Stages of POD startup procedure
+*/
+enum {
+       POD_STARTUP_INIT = 1,
+       POD_STARTUP_VERSIONREQ,
+       POD_STARTUP_WORKQUEUE,
+       POD_STARTUP_SETUP,
+       POD_STARTUP_LAST = POD_STARTUP_SETUP - 1
+};
+
+enum {
+       LINE6_BASSPODXT,
+       LINE6_BASSPODXTLIVE,
+       LINE6_BASSPODXTPRO,
+       LINE6_POCKETPOD,
+       LINE6_PODXT,
+       LINE6_PODXTLIVE_POD,
+       LINE6_PODXTPRO,
+};
+
+struct usb_line6_pod {
+       /**
+               Generic Line6 USB data.
+       */
+       struct usb_line6 line6;
+
+       /**
+               Instrument monitor level.
+       */
+       int monitor_level;
+
+       /**
+               Timer for device initializaton.
+       */
+       struct timer_list startup_timer;
+
+       /**
+               Work handler for device initializaton.
+       */
+       struct work_struct startup_work;
+
+       /**
+               Current progress in startup procedure.
+       */
+       int startup_progress;
+
+       /**
+               Serial number of device.
+       */
+       int serial_number;
+
+       /**
+               Firmware version (x 100).
+       */
+       int firmware_version;
+
+       /**
+               Device ID.
+       */
+       int device_id;
+};
 
 #define POD_SYSEX_CODE 3
 #define POD_BYTES_PER_FRAME 6  /* 24bit audio (stereo) */
@@ -442,7 +523,8 @@ static int pod_try_init(struct usb_interface *interface,
 /*
         Init POD device (and clean up in case of failure).
 */
-int line6_pod_init(struct usb_interface *interface, struct usb_line6 *line6)
+static int pod_init(struct usb_interface *interface,
+                   struct usb_line6 *line6)
 {
        int err = pod_try_init(interface, line6);
 
@@ -451,3 +533,141 @@ int line6_pod_init(struct usb_interface *interface, struct usb_line6 *line6)
 
        return err;
 }
+
+#define LINE6_DEVICE(prod) USB_DEVICE(0x0e41, prod)
+#define LINE6_IF_NUM(prod, n) USB_DEVICE_INTERFACE_NUMBER(0x0e41, prod, n)
+
+/* table of devices that work with this driver */
+static const struct usb_device_id pod_id_table[] = {
+       { LINE6_DEVICE(0x4250),    .driver_info = LINE6_BASSPODXT },
+       { LINE6_DEVICE(0x4642),    .driver_info = LINE6_BASSPODXTLIVE },
+       { LINE6_DEVICE(0x4252),    .driver_info = LINE6_BASSPODXTPRO },
+       { LINE6_IF_NUM(0x5051, 1), .driver_info = LINE6_POCKETPOD },
+       { LINE6_DEVICE(0x5044),    .driver_info = LINE6_PODXT },
+       { LINE6_IF_NUM(0x4650, 0), .driver_info = LINE6_PODXTLIVE_POD },
+       { LINE6_DEVICE(0x5050),    .driver_info = LINE6_PODXTPRO },
+       {}
+};
+
+MODULE_DEVICE_TABLE(usb, pod_id_table);
+
+static const struct line6_properties pod_properties_table[] = {
+       [LINE6_BASSPODXT] = {
+               .id = "BassPODxt",
+               .name = "BassPODxt",
+               .capabilities   = LINE6_CAP_CONTROL
+                               | LINE6_CAP_PCM
+                               | LINE6_CAP_HWMON,
+               .altsetting = 5,
+               .ep_ctrl_r = 0x84,
+               .ep_ctrl_w = 0x03,
+               .ep_audio_r = 0x82,
+               .ep_audio_w = 0x01,
+       },
+       [LINE6_BASSPODXTLIVE] = {
+               .id = "BassPODxtLive",
+               .name = "BassPODxt Live",
+               .capabilities   = LINE6_CAP_CONTROL
+                               | LINE6_CAP_PCM
+                               | LINE6_CAP_HWMON,
+               .altsetting = 1,
+               .ep_ctrl_r = 0x84,
+               .ep_ctrl_w = 0x03,
+               .ep_audio_r = 0x82,
+               .ep_audio_w = 0x01,
+       },
+       [LINE6_BASSPODXTPRO] = {
+               .id = "BassPODxtPro",
+               .name = "BassPODxt Pro",
+               .capabilities   = LINE6_CAP_CONTROL
+                               | LINE6_CAP_PCM
+                               | LINE6_CAP_HWMON,
+               .altsetting = 5,
+               .ep_ctrl_r = 0x84,
+               .ep_ctrl_w = 0x03,
+               .ep_audio_r = 0x82,
+               .ep_audio_w = 0x01,
+       },
+       [LINE6_POCKETPOD] = {
+               .id = "PocketPOD",
+               .name = "Pocket POD",
+               .capabilities   = LINE6_CAP_CONTROL,
+               .altsetting = 0,
+               .ep_ctrl_r = 0x82,
+               .ep_ctrl_w = 0x02,
+               /* no audio channel */
+       },
+       [LINE6_PODXT] = {
+               .id = "PODxt",
+               .name = "PODxt",
+               .capabilities   = LINE6_CAP_CONTROL
+                               | LINE6_CAP_PCM
+                               | LINE6_CAP_HWMON,
+               .altsetting = 5,
+               .ep_ctrl_r = 0x84,
+               .ep_ctrl_w = 0x03,
+               .ep_audio_r = 0x82,
+               .ep_audio_w = 0x01,
+       },
+       [LINE6_PODXTLIVE_POD] = {
+               .id = "PODxtLive",
+               .name = "PODxt Live",
+               .capabilities   = LINE6_CAP_CONTROL
+                               | LINE6_CAP_PCM
+                               | LINE6_CAP_HWMON,
+               .altsetting = 1,
+               .ep_ctrl_r = 0x84,
+               .ep_ctrl_w = 0x03,
+               .ep_audio_r = 0x82,
+               .ep_audio_w = 0x01,
+       },
+       [LINE6_PODXTPRO] = {
+               .id = "PODxtPro",
+               .name = "PODxt Pro",
+               .capabilities   = LINE6_CAP_CONTROL
+                               | LINE6_CAP_PCM
+                               | LINE6_CAP_HWMON,
+               .altsetting = 5,
+               .ep_ctrl_r = 0x84,
+               .ep_ctrl_w = 0x03,
+               .ep_audio_r = 0x82,
+               .ep_audio_w = 0x01,
+       },
+};
+
+/*
+       Probe USB device.
+*/
+static int pod_probe(struct usb_interface *interface,
+                    const struct usb_device_id *id)
+{
+       struct usb_line6_pod *pod;
+       int err;
+
+       pod = kzalloc(sizeof(*pod), GFP_KERNEL);
+       if (!pod)
+               return -ENODEV;
+       err = line6_probe(interface, &pod->line6,
+                         &pod_properties_table[id->driver_info],
+                         pod_init);
+       if (err < 0)
+               kfree(pod);
+       return err;
+}
+
+static struct usb_driver pod_driver = {
+       .name = KBUILD_MODNAME,
+       .probe = pod_probe,
+       .disconnect = line6_disconnect,
+#ifdef CONFIG_PM
+       .suspend = line6_suspend,
+       .resume = line6_resume,
+       .reset_resume = line6_resume,
+#endif
+       .id_table = pod_id_table,
+};
+
+module_usb_driver(pod_driver);
+
+MODULE_DESCRIPTION("Line6 POD USB driver");
+MODULE_LICENSE("GPL");
diff --git a/sound/usb/line6/pod.h b/sound/usb/line6/pod.h
deleted file mode 100644 (file)
index 87a8f0f..0000000
+++ /dev/null
@@ -1,92 +0,0 @@
-/*
- * Line6 Linux USB driver - 0.9.1beta
- *
- * Copyright (C) 2004-2010 Markus Grabner (grabner@icg.tugraz.at)
- *
- *     This program is free software; you can redistribute it and/or
- *     modify it under the terms of the GNU General Public License as
- *     published by the Free Software Foundation, version 2.
- *
- */
-
-#ifndef POD_H
-#define POD_H
-
-#include <linux/interrupt.h>
-#include <linux/spinlock.h>
-#include <linux/usb.h>
-
-#include <sound/core.h>
-
-#include "driver.h"
-
-/*
-       Locate name in binary program dump
-*/
-#define        POD_NAME_OFFSET 0
-#define        POD_NAME_LENGTH 16
-
-/*
-       Other constants
-*/
-#define POD_CONTROL_SIZE 0x80
-#define POD_BUFSIZE_DUMPREQ 7
-#define POD_STARTUP_DELAY 1000
-
-/*
-       Stages of POD startup procedure
-*/
-enum {
-       POD_STARTUP_INIT = 1,
-       POD_STARTUP_VERSIONREQ,
-       POD_STARTUP_WORKQUEUE,
-       POD_STARTUP_SETUP,
-       POD_STARTUP_LAST = POD_STARTUP_SETUP - 1
-};
-
-struct usb_line6_pod {
-       /**
-               Generic Line6 USB data.
-       */
-       struct usb_line6 line6;
-
-       /**
-               Instrument monitor level.
-       */
-       int monitor_level;
-
-       /**
-               Timer for device initializaton.
-       */
-       struct timer_list startup_timer;
-
-       /**
-               Work handler for device initializaton.
-       */
-       struct work_struct startup_work;
-
-       /**
-               Current progress in startup procedure.
-       */
-       int startup_progress;
-
-       /**
-               Serial number of device.
-       */
-       int serial_number;
-
-       /**
-               Firmware version (x 100).
-       */
-       int firmware_version;
-
-       /**
-               Device ID.
-       */
-       int device_id;
-};
-
-extern int line6_pod_init(struct usb_interface *interface,
-                         struct usb_line6 *line6);
-
-#endif
index 27c5402cece80acf37f0795e1e914d88436aa1ae..84096326694cd8dc597e21cf6e563e70d9e22582 100644 (file)
@@ -9,13 +9,30 @@
  *
  */
 
+#include <linux/usb.h>
+#include <linux/slab.h>
+#include <linux/module.h>
 #include <sound/core.h>
 #include <sound/pcm.h>
 
 #include "audio.h"
 #include "driver.h"
 #include "pcm.h"
-#include "podhd.h"
+#include "usbdefs.h"
+
+enum {
+       LINE6_PODHD300,
+       LINE6_PODHD400,
+       LINE6_PODHD500_0,
+       LINE6_PODHD500_1,
+};
+
+struct usb_line6_podhd {
+       /**
+               Generic Line6 USB data.
+       */
+       struct usb_line6 line6;
+};
 
 #define PODHD_BYTES_PER_FRAME 6        /* 24bit audio (stereo) */
 
@@ -141,10 +158,76 @@ static int podhd_try_init(struct usb_interface *interface,
        return err;
 }
 
+#define LINE6_DEVICE(prod) USB_DEVICE(0x0e41, prod)
+#define LINE6_IF_NUM(prod, n) USB_DEVICE_INTERFACE_NUMBER(0x0e41, prod, n)
+
+/* table of devices that work with this driver */
+static const struct usb_device_id podhd_id_table[] = {
+       { LINE6_DEVICE(0x5057),    .driver_info = LINE6_PODHD300 },
+       { LINE6_DEVICE(0x5058),    .driver_info = LINE6_PODHD400 },
+       { LINE6_IF_NUM(0x414D, 0), .driver_info = LINE6_PODHD500_0 },
+       { LINE6_IF_NUM(0x414D, 1), .driver_info = LINE6_PODHD500_1 },
+       {}
+};
+
+MODULE_DEVICE_TABLE(usb, podhd_id_table);
+
+static const struct line6_properties podhd_properties_table[] = {
+       [LINE6_PODHD300] = {
+               .id = "PODHD300",
+               .name = "POD HD300",
+               .capabilities   = LINE6_CAP_CONTROL
+                               | LINE6_CAP_PCM
+                               | LINE6_CAP_HWMON,
+               .altsetting = 5,
+               .ep_ctrl_r = 0x84,
+               .ep_ctrl_w = 0x03,
+               .ep_audio_r = 0x82,
+               .ep_audio_w = 0x01,
+       },
+       [LINE6_PODHD400] = {
+               .id = "PODHD400",
+               .name = "POD HD400",
+               .capabilities   = LINE6_CAP_CONTROL
+                               | LINE6_CAP_PCM
+                               | LINE6_CAP_HWMON,
+               .altsetting = 5,
+               .ep_ctrl_r = 0x84,
+               .ep_ctrl_w = 0x03,
+               .ep_audio_r = 0x82,
+               .ep_audio_w = 0x01,
+       },
+       [LINE6_PODHD500_0] = {
+               .id = "PODHD500",
+               .name = "POD HD500",
+               .capabilities   = LINE6_CAP_CONTROL
+                               | LINE6_CAP_PCM
+                               | LINE6_CAP_HWMON,
+               .altsetting = 1,
+               .ep_ctrl_r = 0x81,
+               .ep_ctrl_w = 0x01,
+               .ep_audio_r = 0x86,
+               .ep_audio_w = 0x02,
+       },
+       [LINE6_PODHD500_1] = {
+               .id = "PODHD500",
+               .name = "POD HD500",
+               .capabilities   = LINE6_CAP_CONTROL
+                               | LINE6_CAP_PCM
+                               | LINE6_CAP_HWMON,
+               .altsetting = 1,
+               .ep_ctrl_r = 0x81,
+               .ep_ctrl_w = 0x01,
+               .ep_audio_r = 0x86,
+               .ep_audio_w = 0x02,
+       },
+};
+
 /*
        Init POD HD device (and clean up in case of failure).
 */
-int line6_podhd_init(struct usb_interface *interface, struct usb_line6 *line6)
+static int podhd_init(struct usb_interface *interface,
+                     struct usb_line6 *line6)
 {
        struct usb_line6_podhd *podhd = (struct usb_line6_podhd *) line6;
        int err = podhd_try_init(interface, podhd);
@@ -154,3 +237,40 @@ int line6_podhd_init(struct usb_interface *interface, struct usb_line6 *line6)
 
        return err;
 }
+
+/*
+       Probe USB device.
+*/
+static int podhd_probe(struct usb_interface *interface,
+                      const struct usb_device_id *id)
+{
+       struct usb_line6_podhd *podhd;
+       int err;
+
+       podhd = kzalloc(sizeof(*podhd), GFP_KERNEL);
+       if (!podhd)
+               return -ENODEV;
+       err = line6_probe(interface, &podhd->line6,
+                         &podhd_properties_table[id->driver_info],
+                         podhd_init);
+       if (err < 0)
+               kfree(podhd);
+       return err;
+}
+
+static struct usb_driver podhd_driver = {
+       .name = KBUILD_MODNAME,
+       .probe = podhd_probe,
+       .disconnect = line6_disconnect,
+#ifdef CONFIG_PM
+       .suspend = line6_suspend,
+       .resume = line6_resume,
+       .reset_resume = line6_resume,
+#endif
+       .id_table = podhd_id_table,
+};
+
+module_usb_driver(podhd_driver);
+
+MODULE_DESCRIPTION("Line6 PODHD USB driver");
+MODULE_LICENSE("GPL");
diff --git a/sound/usb/line6/podhd.h b/sound/usb/line6/podhd.h
deleted file mode 100644 (file)
index a14f711..0000000
+++ /dev/null
@@ -1,29 +0,0 @@
-/*
- * Line6 Pod HD
- *
- * Copyright (C) 2011 Stefan Hajnoczi <stefanha@gmail.com>
- *
- *     This program is free software; you can redistribute it and/or
- *     modify it under the terms of the GNU General Public License as
- *     published by the Free Software Foundation, version 2.
- *
- */
-
-#ifndef PODHD_H
-#define PODHD_H
-
-#include <linux/usb.h>
-
-#include "driver.h"
-
-struct usb_line6_podhd {
-       /**
-               Generic Line6 USB data.
-       */
-       struct usb_line6 line6;
-};
-
-extern int line6_podhd_init(struct usb_interface *interface,
-                           struct usb_line6 *line6);
-
-#endif /* PODHD_H */
index 7f97f4a812a7a39401ed7e5ab5b58717e519de05..4f07643e47f251a7dd0c473a538e7b54d4e79c3b 100644 (file)
  */
 
 #include <linux/wait.h>
+#include <linux/usb.h>
+#include <linux/slab.h>
+#include <linux/module.h>
+#include <sound/core.h>
 #include <sound/control.h>
 
 #include "audio.h"
 #include "capture.h"
 #include "driver.h"
 #include "playback.h"
-#include "toneport.h"
+#include "usbdefs.h"
+
+enum line6_device_type {
+       LINE6_GUITARPORT,
+       LINE6_PODSTUDIO_GX,
+       LINE6_PODSTUDIO_UX1,
+       LINE6_PODSTUDIO_UX2,
+       LINE6_TONEPORT_GX,
+       LINE6_TONEPORT_UX1,
+       LINE6_TONEPORT_UX2,
+};
+
+struct usb_line6_toneport {
+       /**
+               Generic Line6 USB data.
+       */
+       struct usb_line6 line6;
+
+       /**
+               Source selector.
+       */
+       int source;
+
+       /**
+               Serial number of device.
+       */
+       int serial_number;
+
+       /**
+               Firmware version (x 100).
+       */
+       int firmware_version;
+
+       /**
+                Timer for delayed PCM startup.
+       */
+       struct timer_list timer;
+
+       /**
+                Device type.
+       */
+       enum line6_device_type type;
+};
 
 static int toneport_send_cmd(struct usb_device *usbdev, int cmd1, int cmd2);
 
@@ -319,7 +365,7 @@ static void toneport_setup(struct usb_line6_toneport *toneport)
        toneport_send_cmd(usbdev, 0x0301, 0x0000);
 
        /* initialize source select: */
-       switch (line6->type) {
+       switch (toneport->type) {
        case LINE6_TONEPORT_UX1:
        case LINE6_TONEPORT_UX2:
        case LINE6_PODSTUDIO_UX1:
@@ -331,7 +377,7 @@ static void toneport_setup(struct usb_line6_toneport *toneport)
                break;
        }
 
-       if (toneport_has_led(line6->type))
+       if (toneport_has_led(toneport->type))
                toneport_update_led(&usbdev->dev);
 }
 
@@ -400,7 +446,7 @@ static int toneport_try_init(struct usb_interface *interface,
                return err;
 
        /* register source select control: */
-       switch (line6->type) {
+       switch (toneport->type) {
        case LINE6_TONEPORT_UX1:
        case LINE6_TONEPORT_UX2:
        case LINE6_PODSTUDIO_UX1:
@@ -424,7 +470,7 @@ static int toneport_try_init(struct usb_interface *interface,
        line6_read_serial_number(line6, &toneport->serial_number);
        line6_read_data(line6, 0x80c2, &toneport->firmware_version, 1);
 
-       if (toneport_has_led(line6->type)) {
+       if (toneport_has_led(toneport->type)) {
                CHECK_RETURN(device_create_file
                             (&interface->dev, &dev_attr_led_red));
                CHECK_RETURN(device_create_file
@@ -443,8 +489,8 @@ static int toneport_try_init(struct usb_interface *interface,
 /*
         Init Toneport device (and clean up in case of failure).
 */
-int line6_toneport_init(struct usb_interface *interface,
-                       struct usb_line6 *line6)
+static int toneport_init(struct usb_interface *interface,
+                        struct usb_line6 *line6)
 {
        int err = toneport_try_init(interface, line6);
 
@@ -454,10 +500,134 @@ int line6_toneport_init(struct usb_interface *interface,
        return err;
 }
 
+#ifdef CONFIG_PM
 /*
        Resume Toneport device after reset.
 */
-void line6_toneport_reset_resume(struct usb_line6_toneport *toneport)
+static int toneport_reset_resume(struct usb_interface *interface)
 {
-       toneport_setup(toneport);
+       toneport_setup(usb_get_intfdata(interface));
+       return line6_resume(interface);
 }
+#endif
+
+#define LINE6_DEVICE(prod) USB_DEVICE(0x0e41, prod)
+#define LINE6_IF_NUM(prod, n) USB_DEVICE_INTERFACE_NUMBER(0x0e41, prod, n)
+
+/* table of devices that work with this driver */
+static const struct usb_device_id toneport_id_table[] = {
+       { LINE6_DEVICE(0x4750),    .driver_info = LINE6_GUITARPORT },
+       { LINE6_DEVICE(0x4153),    .driver_info = LINE6_PODSTUDIO_GX },
+       { LINE6_DEVICE(0x4150),    .driver_info = LINE6_PODSTUDIO_UX1 },
+       { LINE6_IF_NUM(0x4151, 0), .driver_info = LINE6_PODSTUDIO_UX2 },
+       { LINE6_DEVICE(0x4147),    .driver_info = LINE6_TONEPORT_GX },
+       { LINE6_DEVICE(0x4141),    .driver_info = LINE6_TONEPORT_UX1 },
+       { LINE6_IF_NUM(0x4142, 0), .driver_info = LINE6_TONEPORT_UX2 },
+       {}
+};
+
+MODULE_DEVICE_TABLE(usb, toneport_id_table);
+
+static const struct line6_properties toneport_properties_table[] = {
+       [LINE6_GUITARPORT] = {
+               .id = "GuitarPort",
+               .name = "GuitarPort",
+               .capabilities   = LINE6_CAP_PCM,
+               .altsetting = 2,  /* 1..4 seem to be ok */
+               /* no control channel */
+               .ep_audio_r = 0x82,
+               .ep_audio_w = 0x01,
+       },
+       [LINE6_PODSTUDIO_GX] = {
+               .id = "PODStudioGX",
+               .name = "POD Studio GX",
+               .capabilities   = LINE6_CAP_PCM,
+               .altsetting = 2,  /* 1..4 seem to be ok */
+               /* no control channel */
+               .ep_audio_r = 0x82,
+               .ep_audio_w = 0x01,
+       },
+       [LINE6_PODSTUDIO_UX1] = {
+               .id = "PODStudioUX1",
+               .name = "POD Studio UX1",
+               .capabilities   = LINE6_CAP_PCM,
+               .altsetting = 2,  /* 1..4 seem to be ok */
+               /* no control channel */
+               .ep_audio_r = 0x82,
+               .ep_audio_w = 0x01,
+       },
+       [LINE6_PODSTUDIO_UX2] = {
+               .id = "PODStudioUX2",
+               .name = "POD Studio UX2",
+               .capabilities   = LINE6_CAP_PCM,
+               .altsetting = 2,  /* defaults to 44.1kHz, 16-bit */
+               /* no control channel */
+               .ep_audio_r = 0x82,
+               .ep_audio_w = 0x01,
+       },
+       [LINE6_TONEPORT_GX] = {
+               .id = "TonePortGX",
+               .name = "TonePort GX",
+               .capabilities   = LINE6_CAP_PCM,
+               .altsetting = 2,  /* 1..4 seem to be ok */
+               /* no control channel */
+               .ep_audio_r = 0x82,
+               .ep_audio_w = 0x01,
+       },
+       [LINE6_TONEPORT_UX1] = {
+               .id = "TonePortUX1",
+               .name = "TonePort UX1",
+               .capabilities   = LINE6_CAP_PCM,
+               .altsetting = 2,  /* 1..4 seem to be ok */
+               /* no control channel */
+               .ep_audio_r = 0x82,
+               .ep_audio_w = 0x01,
+       },
+       [LINE6_TONEPORT_UX2] = {
+               .id = "TonePortUX2",
+               .name = "TonePort UX2",
+               .capabilities   = LINE6_CAP_PCM,
+               .altsetting = 2,  /* defaults to 44.1kHz, 16-bit */
+               /* no control channel */
+               .ep_audio_r = 0x82,
+               .ep_audio_w = 0x01,
+       },
+};
+
+/*
+       Probe USB device.
+*/
+static int toneport_probe(struct usb_interface *interface,
+                         const struct usb_device_id *id)
+{
+       struct usb_line6_toneport *toneport;
+       int err;
+
+       toneport = kzalloc(sizeof(*toneport), GFP_KERNEL);
+       if (!toneport)
+               return -ENODEV;
+       toneport->type = id->driver_info;
+       err = line6_probe(interface, &toneport->line6,
+                         &toneport_properties_table[id->driver_info],
+                         toneport_init);
+       if (err < 0)
+               kfree(toneport);
+       return err;
+}
+
+static struct usb_driver toneport_driver = {
+       .name = KBUILD_MODNAME,
+       .probe = toneport_probe,
+       .disconnect = line6_disconnect,
+#ifdef CONFIG_PM
+       .suspend = line6_suspend,
+       .resume = line6_resume,
+       .reset_resume = toneport_reset_resume,
+#endif
+       .id_table = toneport_id_table,
+};
+
+module_usb_driver(toneport_driver);
+
+MODULE_DESCRIPTION("TonePort USB driver");
+MODULE_LICENSE("GPL");
diff --git a/sound/usb/line6/toneport.h b/sound/usb/line6/toneport.h
deleted file mode 100644 (file)
index 8cb1442..0000000
+++ /dev/null
@@ -1,51 +0,0 @@
-/*
- * Line6 Linux USB driver - 0.9.1beta
- *
- * Copyright (C) 2004-2010 Markus Grabner (grabner@icg.tugraz.at)
- *
- *     This program is free software; you can redistribute it and/or
- *     modify it under the terms of the GNU General Public License as
- *     published by the Free Software Foundation, version 2.
- *
- */
-
-#ifndef TONEPORT_H
-#define TONEPORT_H
-
-#include <linux/usb.h>
-#include <sound/core.h>
-
-#include "driver.h"
-
-struct usb_line6_toneport {
-       /**
-               Generic Line6 USB data.
-       */
-       struct usb_line6 line6;
-
-       /**
-               Source selector.
-       */
-       int source;
-
-       /**
-               Serial number of device.
-       */
-       int serial_number;
-
-       /**
-               Firmware version (x 100).
-       */
-       int firmware_version;
-
-       /**
-                Timer for delayed PCM startup.
-       */
-       struct timer_list timer;
-};
-
-extern int line6_toneport_init(struct usb_interface *interface,
-                              struct usb_line6 *line6);
-extern void line6_toneport_reset_resume(struct usb_line6_toneport *toneport);
-
-#endif
index b4a41b0ad0eaf064203988a33d29646d815ca83b..0c852bb1e76c5c3e2d84fa614accb760dcb9c894 100644 (file)
  */
 
 #include <linux/slab.h>
+#include <linux/spinlock.h>
+#include <linux/usb.h>
+#include <linux/wait.h>
+#include <linux/module.h>
+#include <sound/core.h>
 
 #include "audio.h"
 #include "driver.h"
-#include "variax.h"
+#include "usbdefs.h"
+
+#define VARIAX_STARTUP_DELAY1 1000
+#define VARIAX_STARTUP_DELAY3 100
+#define VARIAX_STARTUP_DELAY4 100
+
+/*
+       Stages of Variax startup procedure
+*/
+enum {
+       VARIAX_STARTUP_INIT = 1,
+       VARIAX_STARTUP_VERSIONREQ,
+       VARIAX_STARTUP_WAIT,
+       VARIAX_STARTUP_ACTIVATE,
+       VARIAX_STARTUP_WORKQUEUE,
+       VARIAX_STARTUP_SETUP,
+       VARIAX_STARTUP_LAST = VARIAX_STARTUP_SETUP - 1
+};
+
+enum {
+       LINE6_PODXTLIVE_VARIAX,
+       LINE6_VARIAX
+};
+
+struct usb_line6_variax {
+       /**
+               Generic Line6 USB data.
+       */
+       struct usb_line6 line6;
+
+       /**
+               Buffer for activation code.
+       */
+       unsigned char *buffer_activate;
+
+       /**
+               Handler for device initializaton.
+       */
+       struct work_struct startup_work;
+
+       /**
+               Timers for device initializaton.
+       */
+       struct timer_list startup_timer1;
+       struct timer_list startup_timer2;
+
+       /**
+               Current progress in startup procedure.
+       */
+       int startup_progress;
+};
 
 #define VARIAX_OFFSET_ACTIVATE 7
 
@@ -228,7 +283,8 @@ static int variax_try_init(struct usb_interface *interface,
 /*
         Init workbench device (and clean up in case of failure).
 */
-int line6_variax_init(struct usb_interface *interface, struct usb_line6 *line6)
+static int variax_init(struct usb_interface *interface,
+                      struct usb_line6 *line6)
 {
        int err = variax_try_init(interface, line6);
 
@@ -237,3 +293,76 @@ int line6_variax_init(struct usb_interface *interface, struct usb_line6 *line6)
 
        return err;
 }
+
+#define LINE6_DEVICE(prod) USB_DEVICE(0x0e41, prod)
+#define LINE6_IF_NUM(prod, n) USB_DEVICE_INTERFACE_NUMBER(0x0e41, prod, n)
+
+/* table of devices that work with this driver */
+static const struct usb_device_id variax_id_table[] = {
+       { LINE6_IF_NUM(0x4650, 1), .driver_info = LINE6_PODXTLIVE_VARIAX },
+       { LINE6_DEVICE(0x534d),    .driver_info = LINE6_VARIAX },
+       {}
+};
+
+MODULE_DEVICE_TABLE(usb, variax_id_table);
+
+static const struct line6_properties variax_properties_table[] = {
+       [LINE6_PODXTLIVE_VARIAX] = {
+               .id = "PODxtLive",
+               .name = "PODxt Live",
+               .capabilities   = LINE6_CAP_CONTROL
+                               | LINE6_CAP_PCM
+                               | LINE6_CAP_HWMON,
+               .altsetting = 1,
+               .ep_ctrl_r = 0x86,
+               .ep_ctrl_w = 0x05,
+               .ep_audio_r = 0x82,
+               .ep_audio_w = 0x01,
+       },
+       [LINE6_VARIAX] = {
+               .id = "Variax",
+               .name = "Variax Workbench",
+               .capabilities   = LINE6_CAP_CONTROL,
+               .altsetting = 1,
+               .ep_ctrl_r = 0x82,
+               .ep_ctrl_w = 0x01,
+               /* no audio channel */
+       }
+};
+
+/*
+       Probe USB device.
+*/
+static int variax_probe(struct usb_interface *interface,
+                       const struct usb_device_id *id)
+{
+       struct usb_line6_variax *variax;
+       int err;
+
+       variax = kzalloc(sizeof(*variax), GFP_KERNEL);
+       if (!variax)
+               return -ENODEV;
+       err = line6_probe(interface, &variax->line6,
+                         &variax_properties_table[id->driver_info],
+                         variax_init);
+       if (err < 0)
+               kfree(variax);
+       return err;
+}
+
+static struct usb_driver variax_driver = {
+       .name = KBUILD_MODNAME,
+       .probe = variax_probe,
+       .disconnect = line6_disconnect,
+#ifdef CONFIG_PM
+       .suspend = line6_suspend,
+       .resume = line6_resume,
+       .reset_resume = line6_resume,
+#endif
+       .id_table = variax_id_table,
+};
+
+module_usb_driver(variax_driver);
+
+MODULE_DESCRIPTION("Vairax Workbench USB driver");
+MODULE_LICENSE("GPL");
diff --git a/sound/usb/line6/variax.h b/sound/usb/line6/variax.h
deleted file mode 100644 (file)
index dfb94e5..0000000
+++ /dev/null
@@ -1,70 +0,0 @@
-/*
- * Line6 Linux USB driver - 0.9.1beta
- *
- * Copyright (C) 2004-2010 Markus Grabner (grabner@icg.tugraz.at)
- *
- *     This program is free software; you can redistribute it and/or
- *     modify it under the terms of the GNU General Public License as
- *     published by the Free Software Foundation, version 2.
- *
- */
-
-#ifndef VARIAX_H
-#define VARIAX_H
-
-#include <linux/spinlock.h>
-#include <linux/usb.h>
-#include <linux/wait.h>
-#include <sound/core.h>
-
-#include "driver.h"
-
-#define VARIAX_STARTUP_DELAY1 1000
-#define VARIAX_STARTUP_DELAY3 100
-#define VARIAX_STARTUP_DELAY4 100
-
-/*
-       Stages of Variax startup procedure
-*/
-enum {
-       VARIAX_STARTUP_INIT = 1,
-       VARIAX_STARTUP_VERSIONREQ,
-       VARIAX_STARTUP_WAIT,
-       VARIAX_STARTUP_ACTIVATE,
-       VARIAX_STARTUP_WORKQUEUE,
-       VARIAX_STARTUP_SETUP,
-       VARIAX_STARTUP_LAST = VARIAX_STARTUP_SETUP - 1
-};
-
-struct usb_line6_variax {
-       /**
-               Generic Line6 USB data.
-       */
-       struct usb_line6 line6;
-
-       /**
-               Buffer for activation code.
-       */
-       unsigned char *buffer_activate;
-
-       /**
-               Handler for device initializaton.
-       */
-       struct work_struct startup_work;
-
-       /**
-               Timers for device initializaton.
-       */
-       struct timer_list startup_timer1;
-       struct timer_list startup_timer2;
-
-       /**
-               Current progress in startup procedure.
-       */
-       int startup_progress;
-};
-
-extern int line6_variax_init(struct usb_interface *interface,
-                            struct usb_line6 *line6);
-
-#endif