All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH 00/17] More line6 driver code reorg and cleanups
@ 2015-01-19 15:54 Takashi Iwai
  2015-01-19 15:54 ` [PATCH 01/17] ALSA: line6: Split to each driver Takashi Iwai
                   ` (17 more replies)
  0 siblings, 18 replies; 25+ messages in thread
From: Takashi Iwai @ 2015-01-19 15:54 UTC (permalink / raw)
  To: alsa-devel; +Cc: Stefan Hajnoczi, Chris Rorvick

Hi,

here is a series of patches I hacked quickly after merging line6
stuff into sound git tree.  There are two significant changes:

- Split to each driver and renames: now there are 4 card modules,
  snd-usb-pod, snd-usb-podhd, snd-usb-toneport and snd-usb-variax,
  while snd-usb-line6 serves as a common helper module.

- Many codes restrucruring, especially cleanup of the resource
  management; the destructor is solely called from card's private_free
  now

The current merged code is found in topic/line6 branch of sound.git
tree while this development code is found in test/line6 branch.
The devel branch hasn't been merged to linux-next yet, I'm waiting
for any good/bad test results.  So, give me any feedback.  Thanks!

(BTW, the next step would be to straighten the init code in pod.c,
 etc instead of (ab)using the system timer.  Instead, it should be
 a flat function with wait_event() of such.) 


Takashi

^ permalink raw reply	[flat|nested] 25+ messages in thread

* [PATCH 01/17] ALSA: line6: Split to each driver
  2015-01-19 15:54 [PATCH 00/17] More line6 driver code reorg and cleanups Takashi Iwai
@ 2015-01-19 15:54 ` Takashi Iwai
  2015-01-19 18:00   ` Chris Rorvick
  2015-01-19 15:54 ` [PATCH 02/17] ALSA: line6: Handle impulse response via control API Takashi Iwai
                   ` (16 subsequent siblings)
  17 siblings, 1 reply; 25+ messages in thread
From: Takashi Iwai @ 2015-01-19 15:54 UTC (permalink / raw)
  To: alsa-devel; +Cc: Stefan Hajnoczi, Chris Rorvick

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.

Signed-off-by: Takashi Iwai <tiwai@suse.de>
---
 sound/usb/Makefile         |   2 +-
 sound/usb/line6/Kconfig    |  36 ++--
 sound/usb/line6/Makefile   |  21 ++-
 sound/usb/line6/audio.c    |   3 +
 sound/usb/line6/capture.c  |   1 -
 sound/usb/line6/driver.c   | 452 ++++-----------------------------------------
 sound/usb/line6/driver.h   |  39 ++--
 sound/usb/line6/midi.c     |   3 +-
 sound/usb/line6/pcm.c      |   6 +-
 sound/usb/line6/playback.c |   1 -
 sound/usb/line6/pod.c      | 224 +++++++++++++++++++++-
 sound/usb/line6/pod.h      |  92 ---------
 sound/usb/line6/podhd.c    | 124 ++++++++++++-
 sound/usb/line6/podhd.h    |  29 ---
 sound/usb/line6/toneport.c | 188 ++++++++++++++++++-
 sound/usb/line6/toneport.h |  51 -----
 sound/usb/line6/variax.c   | 133 ++++++++++++-
 sound/usb/line6/variax.h   |  70 -------
 18 files changed, 748 insertions(+), 727 deletions(-)
 delete mode 100644 sound/usb/line6/pod.h
 delete mode 100644 sound/usb/line6/podhd.h
 delete mode 100644 sound/usb/line6/toneport.h
 delete mode 100644 sound/usb/line6/variax.h

diff --git a/sound/usb/Makefile b/sound/usb/Makefile
index 54045b745d11..2d2d122b069f 100644
--- a/sound/usb/Makefile
+++ b/sound/usb/Makefile
@@ -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/
diff --git a/sound/usb/line6/Kconfig b/sound/usb/line6/Kconfig
index 4f1219b4c692..33deb419dde8 100644
--- a/sound/usb/line6/Kconfig
+++ b/sound/usb/line6/Kconfig
@@ -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
diff --git a/sound/usb/line6/Makefile b/sound/usb/line6/Makefile
index ae5c374b0f87..fa3a78dac097 100644
--- a/sound/usb/line6/Makefile
+++ b/sound/usb/line6/Makefile
@@ -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
diff --git a/sound/usb/line6/audio.c b/sound/usb/line6/audio.c
index 171d80c1b020..95686e5af4bd 100644
--- a/sound/usb/line6/audio.c
+++ b/sound/usb/line6/audio.c
@@ -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);
diff --git a/sound/usb/line6/capture.c b/sound/usb/line6/capture.c
index f24c7c5e0a3e..da4ab013ea8e 100644
--- a/sound/usb/line6/capture.c
+++ b/sound/usb/line6/capture.c
@@ -18,7 +18,6 @@
 #include "capture.h"
 #include "driver.h"
 #include "pcm.h"
-#include "pod.h"
 
 /*
 	Find a free URB and submit it.
diff --git a/sound/usb/line6/driver.c b/sound/usb/line6/driver.c
index 19904d677114..149c393c7302 100644
--- a/sound/usb/line6/driver.c
+++ b/sound/usb/line6/driver.c
@@ -11,6 +11,7 @@
 
 #include <linux/kernel.h>
 #include <linux/module.h>
+#include <linux/export.h>
 #include <linux/slab.h>
 #include <linux/usb.h>
 
@@ -19,269 +20,20 @@
 #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");
diff --git a/sound/usb/line6/driver.h b/sound/usb/line6/driver.h
index ad203f197e80..31cd318369e9 100644
--- a/sound/usb/line6/driver.h
+++ b/sound/usb/line6/driver.h
@@ -20,29 +20,6 @@
 
 #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
@@ -135,11 +112,6 @@ struct usb_line6 {
 	struct usb_device *usbdev;
 
 	/**
-		 Device type.
-	*/
-	enum line6_device_type type;
-
-	/**
 		 Properties.
 	*/
 	const struct line6_properties *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
diff --git a/sound/usb/line6/midi.c b/sound/usb/line6/midi.c
index c9d725ae85a0..2a42d533f49c 100644
--- a/sound/usb/line6/midi.c
+++ b/sound/usb/line6/midi.c
@@ -11,13 +11,13 @@
 
 #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);
diff --git a/sound/usb/line6/pcm.c b/sound/usb/line6/pcm.c
index 6d4e5cd0482c..b7348b031bf7 100644
--- a/sound/usb/line6/pcm.c
+++ b/sound/usb/line6/pcm.c
@@ -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)
diff --git a/sound/usb/line6/playback.c b/sound/usb/line6/playback.c
index da2e3b8876b8..0a874105ccef 100644
--- a/sound/usb/line6/playback.c
+++ b/sound/usb/line6/playback.c
@@ -18,7 +18,6 @@
 #include "capture.h"
 #include "driver.h"
 #include "pcm.h"
-#include "pod.h"
 #include "playback.h"
 
 /*
diff --git a/sound/usb/line6/pod.c b/sound/usb/line6/pod.c
index 85a43631996e..dde9c2b8ad0f 100644
--- a/sound/usb/line6/pod.c
+++ b/sound/usb/line6/pod.c
@@ -11,13 +11,94 @@
 
 #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
index 87a8f0fa9cba..000000000000
--- a/sound/usb/line6/pod.h
+++ /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
diff --git a/sound/usb/line6/podhd.c b/sound/usb/line6/podhd.c
index 27c5402cece8..84096326694c 100644
--- a/sound/usb/line6/podhd.c
+++ b/sound/usb/line6/podhd.c
@@ -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
index a14f711f9725..000000000000
--- a/sound/usb/line6/podhd.h
+++ /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 */
diff --git a/sound/usb/line6/toneport.c b/sound/usb/line6/toneport.c
index 7f97f4a812a7..4f07643e47f2 100644
--- a/sound/usb/line6/toneport.c
+++ b/sound/usb/line6/toneport.c
@@ -11,13 +11,59 @@
  */
 
 #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
index 8cb14426f6ae..000000000000
--- a/sound/usb/line6/toneport.h
+++ /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
diff --git a/sound/usb/line6/variax.c b/sound/usb/line6/variax.c
index b4a41b0ad0ea..0c852bb1e76c 100644
--- a/sound/usb/line6/variax.c
+++ b/sound/usb/line6/variax.c
@@ -10,10 +10,65 @@
  */
 
 #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
index dfb94e574cc4..000000000000
--- a/sound/usb/line6/variax.h
+++ /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
-- 
2.2.1

^ permalink raw reply related	[flat|nested] 25+ messages in thread

* [PATCH 02/17] ALSA: line6: Handle impulse response via control API
  2015-01-19 15:54 [PATCH 00/17] More line6 driver code reorg and cleanups Takashi Iwai
  2015-01-19 15:54 ` [PATCH 01/17] ALSA: line6: Split to each driver Takashi Iwai
@ 2015-01-19 15:54 ` Takashi Iwai
  2015-01-19 15:54 ` [PATCH 03/17] ALSA: line6: Drop superfluous snd_device for PCM Takashi Iwai
                   ` (15 subsequent siblings)
  17 siblings, 0 replies; 25+ messages in thread
From: Takashi Iwai @ 2015-01-19 15:54 UTC (permalink / raw)
  To: alsa-devel; +Cc: Stefan Hajnoczi, Chris Rorvick

Instead of sysfs and the conditional build with Kconfig, implement the
handling of the impulse response controls via control API, and always
enable the build.  Two new controls, "Impulse Response Volume" and
"Impulse Response Period" are added as a replacement for the former
sysfs files.

Signed-off-by: Takashi Iwai <tiwai@suse.de>
---
 sound/usb/line6/Kconfig    |  12 ----
 sound/usb/line6/capture.c  |   4 --
 sound/usb/line6/pcm.c      | 157 ++++++++++++++++++++++-----------------------
 sound/usb/line6/pcm.h      |  18 ------
 sound/usb/line6/playback.c |   8 ---
 5 files changed, 75 insertions(+), 124 deletions(-)

diff --git a/sound/usb/line6/Kconfig b/sound/usb/line6/Kconfig
index 33deb419dde8..8287ae6a2c26 100644
--- a/sound/usb/line6/Kconfig
+++ b/sound/usb/line6/Kconfig
@@ -38,15 +38,3 @@ config SND_USB_VARIAX
 	help
 	  This is a driver for Variax Workbench device.
 
-config LINE6_USB_IMPULSE_RESPONSE
-	bool "measure impulse response"
-	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
-	  bypasses any PCM data buffering (e.g., by ALSA or jack). This is
-	  useful for assessing the performance of new devices, but is not
-	  required for normal operation.
-
-	  If unsure, say N.
-
diff --git a/sound/usb/line6/capture.c b/sound/usb/line6/capture.c
index da4ab013ea8e..4cf6fa0541f1 100644
--- a/sound/usb/line6/capture.c
+++ b/sound/usb/line6/capture.c
@@ -244,9 +244,7 @@ static void audio_in_callback(struct urb *urb)
 		line6pcm->prev_fbuf = fbuf;
 		line6pcm->prev_fsize = fsize;
 
-#ifdef CONFIG_LINE6_USB_IMPULSE_RESPONSE
 		if (!(line6pcm->flags & LINE6_BITS_PCM_IMPULSE))
-#endif
 			if (test_bit(LINE6_INDEX_PCM_ALSA_CAPTURE_STREAM,
 				     &line6pcm->flags) && (fsize > 0))
 				line6_capture_copy(line6pcm, fbuf, fsize);
@@ -262,9 +260,7 @@ static void audio_in_callback(struct urb *urb)
 	if (!shutdown) {
 		submit_audio_in_urb(line6pcm);
 
-#ifdef CONFIG_LINE6_USB_IMPULSE_RESPONSE
 		if (!(line6pcm->flags & LINE6_BITS_PCM_IMPULSE))
-#endif
 			if (test_bit(LINE6_INDEX_PCM_ALSA_CAPTURE_STREAM,
 				     &line6pcm->flags))
 				line6_capture_check_period(line6pcm, length);
diff --git a/sound/usb/line6/pcm.c b/sound/usb/line6/pcm.c
index b7348b031bf7..626b6c158023 100644
--- a/sound/usb/line6/pcm.c
+++ b/sound/usb/line6/pcm.c
@@ -21,80 +21,75 @@
 #include "driver.h"
 #include "playback.h"
 
-#ifdef CONFIG_LINE6_USB_IMPULSE_RESPONSE
-
-static struct snd_line6_pcm *dev2pcm(struct device *dev)
+/* impulse response volume controls */
+static int snd_line6_impulse_volume_info(struct snd_kcontrol *kcontrol,
+					 struct snd_ctl_elem_info *uinfo)
 {
-	struct usb_interface *interface = to_usb_interface(dev);
-	struct usb_line6 *line6 = usb_get_intfdata(interface);
-	struct snd_line6_pcm *line6pcm = line6->line6pcm;
-	return line6pcm;
+	uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
+	uinfo->count = 1;
+	uinfo->value.integer.min = 0;
+	uinfo->value.integer.max = 255;
+	return 0;
 }
 
-/*
-	"read" request on "impulse_volume" special file.
-*/
-static ssize_t impulse_volume_show(struct device *dev,
-				   struct device_attribute *attr, char *buf)
+static int snd_line6_impulse_volume_get(struct snd_kcontrol *kcontrol,
+					struct snd_ctl_elem_value *ucontrol)
 {
-	return sprintf(buf, "%d\n", dev2pcm(dev)->impulse_volume);
+	struct snd_line6_pcm *line6pcm = snd_kcontrol_chip(kcontrol);
+
+	ucontrol->value.integer.value[0] = line6pcm->impulse_volume;
+	return 0;
 }
 
-/*
-	"write" request on "impulse_volume" special file.
-*/
-static ssize_t impulse_volume_store(struct device *dev,
-				    struct device_attribute *attr,
-				    const char *buf, size_t count)
+static int snd_line6_impulse_volume_put(struct snd_kcontrol *kcontrol,
+					struct snd_ctl_elem_value *ucontrol)
 {
-	struct snd_line6_pcm *line6pcm = dev2pcm(dev);
-	int value;
-	int ret;
+	struct snd_line6_pcm *line6pcm = snd_kcontrol_chip(kcontrol);
+	int value = ucontrol->value.integer.value[0];
 
-	ret = kstrtoint(buf, 10, &value);
-	if (ret < 0)
-		return ret;
+	if (line6pcm->impulse_volume == value)
+		return 0;
 
 	line6pcm->impulse_volume = value;
-
 	if (value > 0)
 		line6_pcm_acquire(line6pcm, LINE6_BITS_PCM_IMPULSE);
 	else
 		line6_pcm_release(line6pcm, LINE6_BITS_PCM_IMPULSE);
+	return 1;
+}
 
-	return count;
+/* impulse response period controls */
+static int snd_line6_impulse_period_info(struct snd_kcontrol *kcontrol,
+					 struct snd_ctl_elem_info *uinfo)
+{
+	uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
+	uinfo->count = 1;
+	uinfo->value.integer.min = 0;
+	uinfo->value.integer.max = 2000;
+	return 0;
 }
-static DEVICE_ATTR_RW(impulse_volume);
 
-/*
-	"read" request on "impulse_period" special file.
-*/
-static ssize_t impulse_period_show(struct device *dev,
-				   struct device_attribute *attr, char *buf)
+static int snd_line6_impulse_period_get(struct snd_kcontrol *kcontrol,
+					struct snd_ctl_elem_value *ucontrol)
 {
-	return sprintf(buf, "%d\n", dev2pcm(dev)->impulse_period);
+	struct snd_line6_pcm *line6pcm = snd_kcontrol_chip(kcontrol);
+
+	ucontrol->value.integer.value[0] = line6pcm->impulse_period;
+	return 0;
 }
 
-/*
-	"write" request on "impulse_period" special file.
-*/
-static ssize_t impulse_period_store(struct device *dev,
-				    struct device_attribute *attr,
-				    const char *buf, size_t count)
+static int snd_line6_impulse_period_put(struct snd_kcontrol *kcontrol,
+					struct snd_ctl_elem_value *ucontrol)
 {
-	int value;
-	int ret;
+	struct snd_line6_pcm *line6pcm = snd_kcontrol_chip(kcontrol);
+	int value = ucontrol->value.integer.value[0];
 
-	ret = kstrtoint(buf, 10, &value);
-	if (ret < 0)
-		return ret;
+	if (line6pcm->impulse_period == value)
+		return 0;
 
-	dev2pcm(dev)->impulse_period = value;
-	return count;
+	line6pcm->impulse_period = value;
+	return 1;
 }
-static DEVICE_ATTR_RW(impulse_period);
-
-#endif
 
 static bool test_flags(unsigned long flags0, unsigned long flags1,
 		       unsigned long mask)
@@ -314,14 +309,28 @@ static int snd_line6_control_playback_put(struct snd_kcontrol *kcontrol,
 }
 
 /* control definition */
-static struct snd_kcontrol_new line6_control_playback = {
-	.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
-	.name = "PCM Playback Volume",
-	.index = 0,
-	.access = SNDRV_CTL_ELEM_ACCESS_READWRITE,
-	.info = snd_line6_control_playback_info,
-	.get = snd_line6_control_playback_get,
-	.put = snd_line6_control_playback_put
+static struct snd_kcontrol_new line6_controls[] = {
+	{
+		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
+		.name = "PCM Playback Volume",
+		.info = snd_line6_control_playback_info,
+		.get = snd_line6_control_playback_get,
+		.put = snd_line6_control_playback_put
+	},
+	{
+		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
+		.name = "Impulse Response Volume",
+		.info = snd_line6_impulse_volume_info,
+		.get = snd_line6_impulse_volume_get,
+		.put = snd_line6_impulse_volume_put
+	},
+	{
+		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
+		.name = "Impulse Response Period",
+		.info = snd_line6_impulse_period_info,
+		.get = snd_line6_impulse_period_get,
+		.put = snd_line6_impulse_period_put
+	},
 };
 
 /*
@@ -332,11 +341,6 @@ static void line6_cleanup_pcm(struct snd_pcm *pcm)
 	int i;
 	struct snd_line6_pcm *line6pcm = snd_pcm_chip(pcm);
 
-#ifdef CONFIG_LINE6_USB_IMPULSE_RESPONSE
-	device_remove_file(line6pcm->line6->ifcdev, &dev_attr_impulse_volume);
-	device_remove_file(line6pcm->line6->ifcdev, &dev_attr_impulse_period);
-#endif
-
 	for (i = LINE6_ISO_BUFFERS; i--;) {
 		if (line6pcm->urb_audio_out[i]) {
 			usb_kill_urb(line6pcm->urb_audio_out[i]);
@@ -423,7 +427,7 @@ int line6_init_pcm(struct usb_line6 *line6,
 		.dev_free = snd_line6_pcm_free,
 	};
 
-	int err;
+	int i, err;
 	unsigned ep_read = line6->properties->ep_audio_r;
 	unsigned ep_write = line6->properties->ep_audio_w;
 	struct snd_line6_pcm *line6pcm;
@@ -462,6 +466,7 @@ int line6_init_pcm(struct usb_line6 *line6,
 	spin_lock_init(&line6pcm->lock_audio_out);
 	spin_lock_init(&line6pcm->lock_audio_in);
 	spin_lock_init(&line6pcm->lock_trigger);
+	line6pcm->impulse_period = LINE6_IMPULSE_DEFAULT_PERIOD;
 
 	err = line6_create_audio_out_urbs(line6pcm);
 	if (err < 0)
@@ -472,24 +477,12 @@ int line6_init_pcm(struct usb_line6 *line6,
 		return err;
 
 	/* mixer: */
-	err =
-	    snd_ctl_add(line6->card,
-			snd_ctl_new1(&line6_control_playback, line6pcm));
-	if (err < 0)
-		return err;
-
-#ifdef CONFIG_LINE6_USB_IMPULSE_RESPONSE
-	/* impulse response test: */
-	err = device_create_file(line6->ifcdev, &dev_attr_impulse_volume);
-	if (err < 0)
-		return err;
-
-	err = device_create_file(line6->ifcdev, &dev_attr_impulse_period);
-	if (err < 0)
-		return err;
-
-	line6pcm->impulse_period = LINE6_IMPULSE_DEFAULT_PERIOD;
-#endif
+	for (i = 0; i < ARRAY_SIZE(line6_controls); i++) {
+		err = snd_ctl_add(line6->card,
+				  snd_ctl_new1(&line6_controls[i], line6pcm));
+		if (err < 0)
+			return err;
+	}
 
 	return 0;
 }
diff --git a/sound/usb/line6/pcm.h b/sound/usb/line6/pcm.h
index 7315e8131184..9328e6ffb191 100644
--- a/sound/usb/line6/pcm.h
+++ b/sound/usb/line6/pcm.h
@@ -35,9 +35,7 @@
 /* in a "full speed" device (such as the PODxt Pro) this means 1ms */
 #define LINE6_ISO_INTERVAL	1
 
-#ifdef CONFIG_LINE6_USB_IMPULSE_RESPONSE
 #define LINE6_IMPULSE_DEFAULT_PERIOD 100
-#endif
 
 /*
 	Get substream from Line6 PCM data structure
@@ -89,12 +87,10 @@ enum {
 	LINE6_INDEX_PCM_MONITOR_PLAYBACK_STREAM,
 	LINE6_INDEX_PCM_MONITOR_CAPTURE_BUFFER,
 	LINE6_INDEX_PCM_MONITOR_CAPTURE_STREAM,
-#ifdef CONFIG_LINE6_USB_IMPULSE_RESPONSE
 	LINE6_INDEX_PCM_IMPULSE_PLAYBACK_BUFFER,
 	LINE6_INDEX_PCM_IMPULSE_PLAYBACK_STREAM,
 	LINE6_INDEX_PCM_IMPULSE_CAPTURE_BUFFER,
 	LINE6_INDEX_PCM_IMPULSE_CAPTURE_STREAM,
-#endif
 	LINE6_INDEX_PAUSE_PLAYBACK,
 	LINE6_INDEX_PREPARED,
 
@@ -109,12 +105,10 @@ enum {
 	LINE6_BIT(PCM_MONITOR_PLAYBACK_STREAM),
 	LINE6_BIT(PCM_MONITOR_CAPTURE_BUFFER),
 	LINE6_BIT(PCM_MONITOR_CAPTURE_STREAM),
-#ifdef CONFIG_LINE6_USB_IMPULSE_RESPONSE
 	LINE6_BIT(PCM_IMPULSE_PLAYBACK_BUFFER),
 	LINE6_BIT(PCM_IMPULSE_PLAYBACK_STREAM),
 	LINE6_BIT(PCM_IMPULSE_CAPTURE_BUFFER),
 	LINE6_BIT(PCM_IMPULSE_CAPTURE_STREAM),
-#endif
 	LINE6_BIT(PAUSE_PLAYBACK),
 	LINE6_BIT(PREPARED),
 
@@ -133,40 +127,30 @@ enum {
 	    LINE6_BIT_PCM_MONITOR_CAPTURE_BUFFER |
 	    LINE6_BIT_PCM_MONITOR_CAPTURE_STREAM,
 
-#ifdef CONFIG_LINE6_USB_IMPULSE_RESPONSE
 	LINE6_BITS_PCM_IMPULSE =
 	    LINE6_BIT_PCM_IMPULSE_PLAYBACK_BUFFER |
 	    LINE6_BIT_PCM_IMPULSE_PLAYBACK_STREAM |
 	    LINE6_BIT_PCM_IMPULSE_CAPTURE_BUFFER |
 	    LINE6_BIT_PCM_IMPULSE_CAPTURE_STREAM,
-#endif
 
 	/* combined bit masks (by direction): */
 	LINE6_BITS_PLAYBACK_BUFFER =
-#ifdef CONFIG_LINE6_USB_IMPULSE_RESPONSE
 	    LINE6_BIT_PCM_IMPULSE_PLAYBACK_BUFFER |
-#endif
 	    LINE6_BIT_PCM_ALSA_PLAYBACK_BUFFER |
 	    LINE6_BIT_PCM_MONITOR_PLAYBACK_BUFFER,
 
 	LINE6_BITS_PLAYBACK_STREAM =
-#ifdef CONFIG_LINE6_USB_IMPULSE_RESPONSE
 	    LINE6_BIT_PCM_IMPULSE_PLAYBACK_STREAM |
-#endif
 	    LINE6_BIT_PCM_ALSA_PLAYBACK_STREAM |
 	    LINE6_BIT_PCM_MONITOR_PLAYBACK_STREAM,
 
 	LINE6_BITS_CAPTURE_BUFFER =
-#ifdef CONFIG_LINE6_USB_IMPULSE_RESPONSE
 	    LINE6_BIT_PCM_IMPULSE_CAPTURE_BUFFER |
-#endif
 	    LINE6_BIT_PCM_ALSA_CAPTURE_BUFFER |
 	    LINE6_BIT_PCM_MONITOR_CAPTURE_BUFFER,
 
 	LINE6_BITS_CAPTURE_STREAM =
-#ifdef CONFIG_LINE6_USB_IMPULSE_RESPONSE
 	    LINE6_BIT_PCM_IMPULSE_CAPTURE_STREAM |
-#endif
 	    LINE6_BIT_PCM_ALSA_CAPTURE_STREAM |
 	    LINE6_BIT_PCM_MONITOR_CAPTURE_STREAM,
 
@@ -338,7 +322,6 @@ struct snd_line6_pcm {
 	*/
 	int volume_monitor;
 
-#ifdef CONFIG_LINE6_USB_IMPULSE_RESPONSE
 	/**
 		 Volume of impulse response test signal (if zero, test is disabled).
 	*/
@@ -353,7 +336,6 @@ struct snd_line6_pcm {
 		 Counter for impulse response test signal.
 	*/
 	int impulse_count;
-#endif
 
 	/**
 		 Several status bits (see LINE6_BIT_*).
diff --git a/sound/usb/line6/playback.c b/sound/usb/line6/playback.c
index 0a874105ccef..258147eadf37 100644
--- a/sound/usb/line6/playback.c
+++ b/sound/usb/line6/playback.c
@@ -60,8 +60,6 @@ static void change_volume(struct urb *urb_out, int volume[],
 	}
 }
 
-#ifdef CONFIG_LINE6_USB_IMPULSE_RESPONSE
-
 /*
 	Create signal for impulse response test.
 */
@@ -105,8 +103,6 @@ static void create_impulse_test_signal(struct snd_line6_pcm *line6pcm,
 	}
 }
 
-#endif
-
 /*
 	Add signal to buffer for software monitoring.
 */
@@ -243,7 +239,6 @@ static int submit_audio_out_urb(struct snd_line6_pcm *line6pcm)
 	change_volume(urb_out, line6pcm->volume_playback, bytes_per_frame);
 
 	if (line6pcm->prev_fbuf != NULL) {
-#ifdef CONFIG_LINE6_USB_IMPULSE_RESPONSE
 		if (line6pcm->flags & LINE6_BITS_PCM_IMPULSE) {
 			create_impulse_test_signal(line6pcm, urb_out,
 						   bytes_per_frame);
@@ -257,7 +252,6 @@ static int submit_audio_out_urb(struct snd_line6_pcm *line6pcm)
 					urb_out->transfer_buffer_length);
 			}
 		} else {
-#endif
 			if (!
 			    (line6pcm->line6->
 			     properties->capabilities & LINE6_CAP_HWMON)
@@ -266,9 +260,7 @@ static int submit_audio_out_urb(struct snd_line6_pcm *line6pcm)
 				add_monitor_signal(urb_out, line6pcm->prev_fbuf,
 						   line6pcm->volume_monitor,
 						   bytes_per_frame);
-#ifdef CONFIG_LINE6_USB_IMPULSE_RESPONSE
 		}
-#endif
 	}
 
 	ret = usb_submit_urb(urb_out, GFP_ATOMIC);
-- 
2.2.1

^ permalink raw reply related	[flat|nested] 25+ messages in thread

* [PATCH 03/17] ALSA: line6: Drop superfluous snd_device for PCM
  2015-01-19 15:54 [PATCH 00/17] More line6 driver code reorg and cleanups Takashi Iwai
  2015-01-19 15:54 ` [PATCH 01/17] ALSA: line6: Split to each driver Takashi Iwai
  2015-01-19 15:54 ` [PATCH 02/17] ALSA: line6: Handle impulse response via control API Takashi Iwai
@ 2015-01-19 15:54 ` Takashi Iwai
  2015-01-19 15:54 ` [PATCH 04/17] ALSA: line6: Drop superfluous snd_device for rawmidi Takashi Iwai
                   ` (14 subsequent siblings)
  17 siblings, 0 replies; 25+ messages in thread
From: Takashi Iwai @ 2015-01-19 15:54 UTC (permalink / raw)
  To: alsa-devel; +Cc: Stefan Hajnoczi, Chris Rorvick

Instead of handling the card-specific resource in snd_device, attach
it into pcm->private_data and release it directly in private_free.
This simplifies the code and structure.

Signed-off-by: Takashi Iwai <tiwai@suse.de>
---
 sound/usb/line6/pcm.c | 53 ++++++++++++++++++---------------------------------
 1 file changed, 19 insertions(+), 34 deletions(-)

diff --git a/sound/usb/line6/pcm.c b/sound/usb/line6/pcm.c
index 626b6c158023..520cf540e83c 100644
--- a/sound/usb/line6/pcm.c
+++ b/sound/usb/line6/pcm.c
@@ -351,24 +351,21 @@ static void line6_cleanup_pcm(struct snd_pcm *pcm)
 			usb_free_urb(line6pcm->urb_audio_in[i]);
 		}
 	}
+	kfree(line6pcm);
 }
 
 /* create a PCM device */
-static int snd_line6_new_pcm(struct snd_line6_pcm *line6pcm)
+static int snd_line6_new_pcm(struct usb_line6 *line6, struct snd_pcm **pcm_ret)
 {
 	struct snd_pcm *pcm;
 	int err;
 
-	err = snd_pcm_new(line6pcm->line6->card,
-			  (char *)line6pcm->line6->properties->name,
-			  0, 1, 1, &pcm);
+	err = snd_pcm_new(line6->card, (char *)line6->properties->name,
+			  0, 1, 1, pcm_ret);
 	if (err < 0)
 		return err;
-
-	pcm->private_data = line6pcm;
-	pcm->private_free = line6_cleanup_pcm;
-	line6pcm->pcm = pcm;
-	strcpy(pcm->name, line6pcm->line6->properties->name);
+	pcm = *pcm_ret;
+	strcpy(pcm->name, line6->properties->name);
 
 	/* set operators */
 	snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK,
@@ -380,13 +377,6 @@ static int snd_line6_new_pcm(struct snd_line6_pcm *line6pcm)
 					      snd_dma_continuous_data
 					      (GFP_KERNEL), 64 * 1024,
 					      128 * 1024);
-
-	return 0;
-}
-
-/* PCM device destructor */
-static int snd_line6_pcm_free(struct snd_device *device)
-{
 	return 0;
 }
 
@@ -423,23 +413,25 @@ EXPORT_SYMBOL_GPL(line6_pcm_disconnect);
 int line6_init_pcm(struct usb_line6 *line6,
 		   struct line6_pcm_properties *properties)
 {
-	static struct snd_device_ops pcm_ops = {
-		.dev_free = snd_line6_pcm_free,
-	};
-
 	int i, err;
 	unsigned ep_read = line6->properties->ep_audio_r;
 	unsigned ep_write = line6->properties->ep_audio_w;
+	struct snd_pcm *pcm;
 	struct snd_line6_pcm *line6pcm;
 
 	if (!(line6->properties->capabilities & LINE6_CAP_PCM))
 		return 0;	/* skip PCM initialization and report success */
 
-	line6pcm = kzalloc(sizeof(*line6pcm), GFP_KERNEL);
+	err = snd_line6_new_pcm(line6, &pcm);
+	if (err < 0)
+		return err;
 
-	if (line6pcm == NULL)
+	line6pcm = kzalloc(sizeof(*line6pcm), GFP_KERNEL);
+	if (!line6pcm)
 		return -ENOMEM;
 
+	line6pcm->pcm = pcm;
+	line6pcm->properties = properties;
 	line6pcm->volume_playback[0] = line6pcm->volume_playback[1] = 255;
 	line6pcm->volume_monitor = 255;
 	line6pcm->line6 = line6;
@@ -451,23 +443,16 @@ int line6_init_pcm(struct usb_line6 *line6,
 			usb_maxpacket(line6->usbdev,
 				usb_sndisocpipe(line6->usbdev, ep_write), 1));
 
-	line6pcm->properties = properties;
-	line6->line6pcm = line6pcm;
-
-	/* PCM device: */
-	err = snd_device_new(line6->card, SNDRV_DEV_PCM, line6, &pcm_ops);
-	if (err < 0)
-		return err;
-
-	err = snd_line6_new_pcm(line6pcm);
-	if (err < 0)
-		return err;
-
 	spin_lock_init(&line6pcm->lock_audio_out);
 	spin_lock_init(&line6pcm->lock_audio_in);
 	spin_lock_init(&line6pcm->lock_trigger);
 	line6pcm->impulse_period = LINE6_IMPULSE_DEFAULT_PERIOD;
 
+	line6->line6pcm = line6pcm;
+
+	pcm->private_data = line6pcm;
+	pcm->private_free = line6_cleanup_pcm;
+
 	err = line6_create_audio_out_urbs(line6pcm);
 	if (err < 0)
 		return err;
-- 
2.2.1

^ permalink raw reply related	[flat|nested] 25+ messages in thread

* [PATCH 04/17] ALSA: line6: Drop superfluous snd_device for rawmidi
  2015-01-19 15:54 [PATCH 00/17] More line6 driver code reorg and cleanups Takashi Iwai
                   ` (2 preceding siblings ...)
  2015-01-19 15:54 ` [PATCH 03/17] ALSA: line6: Drop superfluous snd_device for PCM Takashi Iwai
@ 2015-01-19 15:54 ` Takashi Iwai
  2015-01-19 15:54 ` [PATCH 05/17] ALSA: line6: Drop invalid SNDRV_PCM_INFO_RESUME flag Takashi Iwai
                   ` (13 subsequent siblings)
  17 siblings, 0 replies; 25+ messages in thread
From: Takashi Iwai @ 2015-01-19 15:54 UTC (permalink / raw)
  To: alsa-devel; +Cc: Stefan Hajnoczi, Chris Rorvick

Like the previous fix for PCM, attach the card-specific resource into
rawmidi->private_data instead of handling in a snd_device object.
This simplifies the code and structure.

Signed-off-by: Takashi Iwai <tiwai@suse.de>
---
 sound/usb/line6/midi.c | 65 ++++++++++++++++++--------------------------------
 1 file changed, 23 insertions(+), 42 deletions(-)

diff --git a/sound/usb/line6/midi.c b/sound/usb/line6/midi.c
index 2a42d533f49c..ebca5ebcfecc 100644
--- a/sound/usb/line6/midi.c
+++ b/sound/usb/line6/midi.c
@@ -223,28 +223,20 @@ static struct snd_rawmidi_ops line6_midi_input_ops = {
 	.trigger = line6_midi_input_trigger,
 };
 
-/*
-	Cleanup the Line6 MIDI device.
-*/
-static void line6_cleanup_midi(struct snd_rawmidi *rmidi)
-{
-}
-
 /* Create a MIDI device */
-static int snd_line6_new_midi(struct snd_line6_midi *line6midi)
+static int snd_line6_new_midi(struct usb_line6 *line6,
+			      struct snd_rawmidi **rmidi_ret)
 {
 	struct snd_rawmidi *rmidi;
 	int err;
 
-	err = snd_rawmidi_new(line6midi->line6->card, "Line6 MIDI", 0, 1, 1,
-			      &rmidi);
+	err = snd_rawmidi_new(line6->card, "Line6 MIDI", 0, 1, 1, rmidi_ret);
 	if (err < 0)
 		return err;
 
-	rmidi->private_data = line6midi;
-	rmidi->private_free = line6_cleanup_midi;
-	strcpy(rmidi->id, line6midi->line6->properties->id);
-	strcpy(rmidi->name, line6midi->line6->properties->name);
+	rmidi = *rmidi_ret;
+	strcpy(rmidi->id, line6->properties->id);
+	strcpy(rmidi->name, line6->properties->name);
 
 	rmidi->info_flags =
 	    SNDRV_RAWMIDI_INFO_OUTPUT |
@@ -258,13 +250,13 @@ static int snd_line6_new_midi(struct snd_line6_midi *line6midi)
 }
 
 /* MIDI device destructor */
-static int snd_line6_midi_free(struct snd_device *device)
+static void snd_line6_midi_free(struct snd_rawmidi *rmidi)
 {
-	struct snd_line6_midi *line6midi = device->device_data;
+	struct snd_line6_midi *line6midi = rmidi->private_data;
 
 	line6_midibuf_destroy(&line6midi->midibuf_in);
 	line6_midibuf_destroy(&line6midi->midibuf_out);
-	return 0;
+	kfree(line6midi);
 }
 
 /*
@@ -272,11 +264,8 @@ static int snd_line6_midi_free(struct snd_device *device)
 */
 int line6_init_midi(struct usb_line6 *line6)
 {
-	static struct snd_device_ops midi_ops = {
-		.dev_free = snd_line6_midi_free,
-	};
-
 	int err;
+	struct snd_rawmidi *rmidi;
 	struct snd_line6_midi *line6midi;
 
 	if (!(line6->properties->capabilities & LINE6_CAP_CONTROL)) {
@@ -284,39 +273,31 @@ int line6_init_midi(struct usb_line6 *line6)
 		return 0;
 	}
 
-	line6midi = kzalloc(sizeof(struct snd_line6_midi), GFP_KERNEL);
+	err = snd_line6_new_midi(line6, &rmidi);
+	if (err < 0)
+		return err;
 
-	if (line6midi == NULL)
+	line6midi = kzalloc(sizeof(struct snd_line6_midi), GFP_KERNEL);
+	if (!line6midi)
 		return -ENOMEM;
 
-	err = line6_midibuf_init(&line6midi->midibuf_in, MIDI_BUFFER_SIZE, 0);
-	if (err < 0) {
-		kfree(line6midi);
-		return err;
-	}
-
-	err = line6_midibuf_init(&line6midi->midibuf_out, MIDI_BUFFER_SIZE, 1);
-	if (err < 0) {
-		kfree(line6midi->midibuf_in.buf);
-		kfree(line6midi);
-		return err;
-	}
+	rmidi->private_data = line6midi;
+	rmidi->private_free = snd_line6_midi_free;
 
+	init_waitqueue_head(&line6midi->send_wait);
+	spin_lock_init(&line6midi->send_urb_lock);
+	spin_lock_init(&line6midi->midi_transmit_lock);
 	line6midi->line6 = line6;
-	line6->line6midi = line6midi;
 
-	err = snd_device_new(line6->card, SNDRV_DEV_RAWMIDI, line6midi,
-			     &midi_ops);
+	err = line6_midibuf_init(&line6midi->midibuf_in, MIDI_BUFFER_SIZE, 0);
 	if (err < 0)
 		return err;
 
-	err = snd_line6_new_midi(line6midi);
+	err = line6_midibuf_init(&line6midi->midibuf_out, MIDI_BUFFER_SIZE, 1);
 	if (err < 0)
 		return err;
 
-	init_waitqueue_head(&line6midi->send_wait);
-	spin_lock_init(&line6midi->send_urb_lock);
-	spin_lock_init(&line6midi->midi_transmit_lock);
+	line6->line6midi = line6midi;
 	return 0;
 }
 EXPORT_SYMBOL_GPL(line6_init_midi);
-- 
2.2.1

^ permalink raw reply related	[flat|nested] 25+ messages in thread

* [PATCH 05/17] ALSA: line6: Drop invalid SNDRV_PCM_INFO_RESUME flag
  2015-01-19 15:54 [PATCH 00/17] More line6 driver code reorg and cleanups Takashi Iwai
                   ` (3 preceding siblings ...)
  2015-01-19 15:54 ` [PATCH 04/17] ALSA: line6: Drop superfluous snd_device for rawmidi Takashi Iwai
@ 2015-01-19 15:54 ` Takashi Iwai
  2015-01-19 15:54 ` [PATCH 06/17] ALSA: line6: Drop usb_device sysfs symlink Takashi Iwai
                   ` (12 subsequent siblings)
  17 siblings, 0 replies; 25+ messages in thread
From: Takashi Iwai @ 2015-01-19 15:54 UTC (permalink / raw)
  To: alsa-devel; +Cc: Stefan Hajnoczi, Chris Rorvick

The line6 drivers don't support the full resume although they set
SNDRV_PCM_INFO_RESUME.  These flags have to be dropped to inform
properly to the user-space.

Also, drop the CONFIG_PM in trigger callbacks, too, which are rather
superfluous.

Signed-off-by: Takashi Iwai <tiwai@suse.de>
---
 sound/usb/line6/capture.c  | 4 ----
 sound/usb/line6/playback.c | 4 ----
 sound/usb/line6/pod.c      | 6 ------
 sound/usb/line6/podhd.c    | 6 ------
 sound/usb/line6/toneport.c | 6 ------
 5 files changed, 26 deletions(-)

diff --git a/sound/usb/line6/capture.c b/sound/usb/line6/capture.c
index 4cf6fa0541f1..1970ab57cb6f 100644
--- a/sound/usb/line6/capture.c
+++ b/sound/usb/line6/capture.c
@@ -342,9 +342,7 @@ int snd_line6_capture_trigger(struct snd_line6_pcm *line6pcm, int cmd)
 
 	switch (cmd) {
 	case SNDRV_PCM_TRIGGER_START:
-#ifdef CONFIG_PM
 	case SNDRV_PCM_TRIGGER_RESUME:
-#endif
 		err = line6_pcm_acquire(line6pcm,
 					LINE6_BIT_PCM_ALSA_CAPTURE_STREAM);
 
@@ -354,9 +352,7 @@ int snd_line6_capture_trigger(struct snd_line6_pcm *line6pcm, int cmd)
 		break;
 
 	case SNDRV_PCM_TRIGGER_STOP:
-#ifdef CONFIG_PM
 	case SNDRV_PCM_TRIGGER_SUSPEND:
-#endif
 		err = line6_pcm_release(line6pcm,
 					LINE6_BIT_PCM_ALSA_CAPTURE_STREAM);
 
diff --git a/sound/usb/line6/playback.c b/sound/usb/line6/playback.c
index 258147eadf37..8fc2dedbeb52 100644
--- a/sound/usb/line6/playback.c
+++ b/sound/usb/line6/playback.c
@@ -490,9 +490,7 @@ int snd_line6_playback_trigger(struct snd_line6_pcm *line6pcm, int cmd)
 
 	switch (cmd) {
 	case SNDRV_PCM_TRIGGER_START:
-#ifdef CONFIG_PM
 	case SNDRV_PCM_TRIGGER_RESUME:
-#endif
 		err = line6_pcm_acquire(line6pcm,
 					LINE6_BIT_PCM_ALSA_PLAYBACK_STREAM);
 
@@ -502,9 +500,7 @@ int snd_line6_playback_trigger(struct snd_line6_pcm *line6pcm, int cmd)
 		break;
 
 	case SNDRV_PCM_TRIGGER_STOP:
-#ifdef CONFIG_PM
 	case SNDRV_PCM_TRIGGER_SUSPEND:
-#endif
 		err = line6_pcm_release(line6pcm,
 					LINE6_BIT_PCM_ALSA_PLAYBACK_STREAM);
 
diff --git a/sound/usb/line6/pod.c b/sound/usb/line6/pod.c
index dde9c2b8ad0f..d6bc5a1ab7f4 100644
--- a/sound/usb/line6/pod.c
+++ b/sound/usb/line6/pod.c
@@ -153,9 +153,6 @@ static struct line6_pcm_properties pod_pcm_properties = {
 					   SNDRV_PCM_INFO_BLOCK_TRANSFER |
 					   SNDRV_PCM_INFO_MMAP_VALID |
 					   SNDRV_PCM_INFO_PAUSE |
-#ifdef CONFIG_PM
-					   SNDRV_PCM_INFO_RESUME |
-#endif
 					   SNDRV_PCM_INFO_SYNC_START),
 				  .formats = SNDRV_PCM_FMTBIT_S24_3LE,
 				  .rates = SNDRV_PCM_RATE_KNOT,
@@ -173,9 +170,6 @@ static struct line6_pcm_properties pod_pcm_properties = {
 					  SNDRV_PCM_INFO_INTERLEAVED |
 					  SNDRV_PCM_INFO_BLOCK_TRANSFER |
 					  SNDRV_PCM_INFO_MMAP_VALID |
-#ifdef CONFIG_PM
-					  SNDRV_PCM_INFO_RESUME |
-#endif
 					  SNDRV_PCM_INFO_SYNC_START),
 				 .formats = SNDRV_PCM_FMTBIT_S24_3LE,
 				 .rates = SNDRV_PCM_RATE_KNOT,
diff --git a/sound/usb/line6/podhd.c b/sound/usb/line6/podhd.c
index 84096326694c..8f4ca1d20b62 100644
--- a/sound/usb/line6/podhd.c
+++ b/sound/usb/line6/podhd.c
@@ -50,9 +50,6 @@ static struct line6_pcm_properties podhd_pcm_properties = {
 					   SNDRV_PCM_INFO_BLOCK_TRANSFER |
 					   SNDRV_PCM_INFO_MMAP_VALID |
 					   SNDRV_PCM_INFO_PAUSE |
-#ifdef CONFIG_PM
-					   SNDRV_PCM_INFO_RESUME |
-#endif
 					   SNDRV_PCM_INFO_SYNC_START),
 				  .formats = SNDRV_PCM_FMTBIT_S24_3LE,
 				  .rates = SNDRV_PCM_RATE_48000,
@@ -70,9 +67,6 @@ static struct line6_pcm_properties podhd_pcm_properties = {
 					  SNDRV_PCM_INFO_INTERLEAVED |
 					  SNDRV_PCM_INFO_BLOCK_TRANSFER |
 					  SNDRV_PCM_INFO_MMAP_VALID |
-#ifdef CONFIG_PM
-					  SNDRV_PCM_INFO_RESUME |
-#endif
 					  SNDRV_PCM_INFO_SYNC_START),
 				 .formats = SNDRV_PCM_FMTBIT_S24_3LE,
 				 .rates = SNDRV_PCM_RATE_48000,
diff --git a/sound/usb/line6/toneport.c b/sound/usb/line6/toneport.c
index 4f07643e47f2..6ec3268a6153 100644
--- a/sound/usb/line6/toneport.c
+++ b/sound/usb/line6/toneport.c
@@ -83,9 +83,6 @@ static struct line6_pcm_properties toneport_pcm_properties = {
 					   SNDRV_PCM_INFO_BLOCK_TRANSFER |
 					   SNDRV_PCM_INFO_MMAP_VALID |
 					   SNDRV_PCM_INFO_PAUSE |
-#ifdef CONFIG_PM
-					   SNDRV_PCM_INFO_RESUME |
-#endif
 					   SNDRV_PCM_INFO_SYNC_START),
 				  .formats = SNDRV_PCM_FMTBIT_S16_LE,
 				  .rates = SNDRV_PCM_RATE_KNOT,
@@ -103,9 +100,6 @@ static struct line6_pcm_properties toneport_pcm_properties = {
 					  SNDRV_PCM_INFO_INTERLEAVED |
 					  SNDRV_PCM_INFO_BLOCK_TRANSFER |
 					  SNDRV_PCM_INFO_MMAP_VALID |
-#ifdef CONFIG_PM
-					  SNDRV_PCM_INFO_RESUME |
-#endif
 					  SNDRV_PCM_INFO_SYNC_START),
 				 .formats = SNDRV_PCM_FMTBIT_S16_LE,
 				 .rates = SNDRV_PCM_RATE_KNOT,
-- 
2.2.1

^ permalink raw reply related	[flat|nested] 25+ messages in thread

* [PATCH 06/17] ALSA: line6: Drop usb_device sysfs symlink
  2015-01-19 15:54 [PATCH 00/17] More line6 driver code reorg and cleanups Takashi Iwai
                   ` (4 preceding siblings ...)
  2015-01-19 15:54 ` [PATCH 05/17] ALSA: line6: Drop invalid SNDRV_PCM_INFO_RESUME flag Takashi Iwai
@ 2015-01-19 15:54 ` Takashi Iwai
  2015-01-19 15:54 ` [PATCH 07/17] ALSA: line6: Remove superfluous out-of-memory error messages Takashi Iwai
                   ` (11 subsequent siblings)
  17 siblings, 0 replies; 25+ messages in thread
From: Takashi Iwai @ 2015-01-19 15:54 UTC (permalink / raw)
  To: alsa-devel; +Cc: Stefan Hajnoczi, Chris Rorvick

It's non-standard and rather superfluous.

Signed-off-by: Takashi Iwai <tiwai@suse.de>
---
 sound/usb/line6/driver.c | 9 ---------
 1 file changed, 9 deletions(-)

diff --git a/sound/usb/line6/driver.c b/sound/usb/line6/driver.c
index 149c393c7302..23d504f4b6bc 100644
--- a/sound/usb/line6/driver.c
+++ b/sound/usb/line6/driver.c
@@ -611,11 +611,6 @@ int line6_probe(struct usb_interface *interface,
 	if (ret < 0)
 		goto err_destruct;
 
-	ret = sysfs_create_link(&interface->dev.kobj, &usbdev->dev.kobj,
-				"usb_device");
-	if (ret < 0)
-		goto err_destruct;
-
 	/* creation of additional special files should go here */
 
 	dev_info(&interface->dev, "Line6 %s now attached\n",
@@ -649,10 +644,6 @@ void line6_disconnect(struct usb_interface *interface)
 	if (usbdev == NULL)
 		return;
 
-	/* removal of additional special files should go here */
-
-	sysfs_remove_link(&interface->dev.kobj, "usb_device");
-
 	interface_number = interface->cur_altsetting->desc.bInterfaceNumber;
 	line6 = usb_get_intfdata(interface);
 
-- 
2.2.1

^ permalink raw reply related	[flat|nested] 25+ messages in thread

* [PATCH 07/17] ALSA: line6: Remove superfluous out-of-memory error messages
  2015-01-19 15:54 [PATCH 00/17] More line6 driver code reorg and cleanups Takashi Iwai
                   ` (5 preceding siblings ...)
  2015-01-19 15:54 ` [PATCH 06/17] ALSA: line6: Drop usb_device sysfs symlink Takashi Iwai
@ 2015-01-19 15:54 ` Takashi Iwai
  2015-01-19 15:54 ` [PATCH 08/17] ALSA: line6: Don't handle PCM trigger for other cards Takashi Iwai
                   ` (10 subsequent siblings)
  17 siblings, 0 replies; 25+ messages in thread
From: Takashi Iwai @ 2015-01-19 15:54 UTC (permalink / raw)
  To: alsa-devel; +Cc: Stefan Hajnoczi, Chris Rorvick

Kernel already shows the error in the common path.

Signed-off-by: Takashi Iwai <tiwai@suse.de>
---
 sound/usb/line6/capture.c  | 4 +---
 sound/usb/line6/driver.c   | 6 +-----
 sound/usb/line6/midi.c     | 5 +----
 sound/usb/line6/playback.c | 4 +---
 sound/usb/line6/variax.c   | 4 +---
 5 files changed, 5 insertions(+), 18 deletions(-)

diff --git a/sound/usb/line6/capture.c b/sound/usb/line6/capture.c
index 1970ab57cb6f..727b31876d48 100644
--- a/sound/usb/line6/capture.c
+++ b/sound/usb/line6/capture.c
@@ -402,10 +402,8 @@ int line6_create_audio_in_urbs(struct snd_line6_pcm *line6pcm)
 		urb = line6pcm->urb_audio_in[i] =
 		    usb_alloc_urb(LINE6_ISO_PACKETS, GFP_KERNEL);
 
-		if (urb == NULL) {
-			dev_err(line6->ifcdev, "Out of memory\n");
+		if (urb == NULL)
 			return -ENOMEM;
-		}
 
 		urb->dev = line6->usbdev;
 		urb->pipe =
diff --git a/sound/usb/line6/driver.c b/sound/usb/line6/driver.c
index 23d504f4b6bc..b8f5134dcec2 100644
--- a/sound/usb/line6/driver.c
+++ b/sound/usb/line6/driver.c
@@ -190,7 +190,6 @@ int line6_send_raw_message_async(struct usb_line6 *line6, const char *buffer,
 
 	if (urb == NULL) {
 		kfree(msg);
-		dev_err(line6->ifcdev, "Out of memory\n");
 		return -ENOMEM;
 	}
 
@@ -215,10 +214,8 @@ int line6_version_request_async(struct usb_line6 *line6)
 
 	buffer = kmemdup(line6_request_version,
 			sizeof(line6_request_version), GFP_ATOMIC);
-	if (buffer == NULL) {
-		dev_err(line6->ifcdev, "Out of memory");
+	if (buffer == NULL)
 		return -ENOMEM;
-	}
 
 	retval = line6_send_raw_message_async(line6, buffer,
 					      sizeof(line6_request_version));
@@ -593,7 +590,6 @@ int line6_probe(struct usb_interface *interface,
 		line6->urb_listen = usb_alloc_urb(0, GFP_KERNEL);
 
 		if (line6->urb_listen == NULL) {
-			dev_err(&interface->dev, "Out of memory\n");
 			ret = -ENOMEM;
 			goto err_destruct;
 		}
diff --git a/sound/usb/line6/midi.c b/sound/usb/line6/midi.c
index ebca5ebcfecc..f333cef5d2d7 100644
--- a/sound/usb/line6/midi.c
+++ b/sound/usb/line6/midi.c
@@ -121,16 +121,13 @@ static int send_midi_async(struct usb_line6 *line6, unsigned char *data,
 
 	urb = usb_alloc_urb(0, GFP_ATOMIC);
 
-	if (urb == NULL) {
-		dev_err(line6->ifcdev, "Out of memory\n");
+	if (urb == NULL)
 		return -ENOMEM;
-	}
 
 	transfer_buffer = kmemdup(data, length, GFP_ATOMIC);
 
 	if (transfer_buffer == NULL) {
 		usb_free_urb(urb);
-		dev_err(line6->ifcdev, "Out of memory\n");
 		return -ENOMEM;
 	}
 
diff --git a/sound/usb/line6/playback.c b/sound/usb/line6/playback.c
index 8fc2dedbeb52..5a7fe409a3b9 100644
--- a/sound/usb/line6/playback.c
+++ b/sound/usb/line6/playback.c
@@ -558,10 +558,8 @@ int line6_create_audio_out_urbs(struct snd_line6_pcm *line6pcm)
 		urb = line6pcm->urb_audio_out[i] =
 		    usb_alloc_urb(LINE6_ISO_PACKETS, GFP_KERNEL);
 
-		if (urb == NULL) {
-			dev_err(line6->ifcdev, "Out of memory\n");
+		if (urb == NULL)
 			return -ENOMEM;
-		}
 
 		urb->dev = line6->usbdev;
 		urb->pipe =
diff --git a/sound/usb/line6/variax.c b/sound/usb/line6/variax.c
index 0c852bb1e76c..9a9c7e48e24f 100644
--- a/sound/usb/line6/variax.c
+++ b/sound/usb/line6/variax.c
@@ -260,10 +260,8 @@ static int variax_try_init(struct usb_interface *interface,
 	variax->buffer_activate = kmemdup(variax_activate,
 					  sizeof(variax_activate), GFP_KERNEL);
 
-	if (variax->buffer_activate == NULL) {
-		dev_err(&interface->dev, "Out of memory\n");
+	if (variax->buffer_activate == NULL)
 		return -ENOMEM;
-	}
 
 	/* initialize audio system: */
 	err = line6_init_audio(&variax->line6);
-- 
2.2.1

^ permalink raw reply related	[flat|nested] 25+ messages in thread

* [PATCH 08/17] ALSA: line6: Don't handle PCM trigger for other cards
  2015-01-19 15:54 [PATCH 00/17] More line6 driver code reorg and cleanups Takashi Iwai
                   ` (6 preceding siblings ...)
  2015-01-19 15:54 ` [PATCH 07/17] ALSA: line6: Remove superfluous out-of-memory error messages Takashi Iwai
@ 2015-01-19 15:54 ` Takashi Iwai
  2015-01-19 15:54 ` [PATCH 09/17] ALSA: line6: Drop superfluous irqsave/irqrestore in PCM trigger callback Takashi Iwai
                   ` (9 subsequent siblings)
  17 siblings, 0 replies; 25+ messages in thread
From: Takashi Iwai @ 2015-01-19 15:54 UTC (permalink / raw)
  To: alsa-devel; +Cc: Stefan Hajnoczi, Chris Rorvick

Otherwise it oopses.

Signed-off-by: Takashi Iwai <tiwai@suse.de>
---
 sound/usb/line6/pcm.c | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/sound/usb/line6/pcm.c b/sound/usb/line6/pcm.c
index 520cf540e83c..932cc7e194e2 100644
--- a/sound/usb/line6/pcm.c
+++ b/sound/usb/line6/pcm.c
@@ -233,6 +233,8 @@ int snd_line6_trigger(struct snd_pcm_substream *substream, int cmd)
 	clear_bit(LINE6_INDEX_PREPARED, &line6pcm->flags);
 
 	snd_pcm_group_for_each_entry(s, substream) {
+		if (s->pcm->card != substream->pcm->card)
+			continue;
 		switch (s->stream) {
 		case SNDRV_PCM_STREAM_PLAYBACK:
 			err = snd_line6_playback_trigger(line6pcm, cmd);
-- 
2.2.1

^ permalink raw reply related	[flat|nested] 25+ messages in thread

* [PATCH 09/17] ALSA: line6: Drop superfluous irqsave/irqrestore in PCM trigger callback
  2015-01-19 15:54 [PATCH 00/17] More line6 driver code reorg and cleanups Takashi Iwai
                   ` (7 preceding siblings ...)
  2015-01-19 15:54 ` [PATCH 08/17] ALSA: line6: Don't handle PCM trigger for other cards Takashi Iwai
@ 2015-01-19 15:54 ` Takashi Iwai
  2015-01-19 15:54 ` [PATCH 10/17] ALSA: line6: Reorganize card resource handling Takashi Iwai
                   ` (8 subsequent siblings)
  17 siblings, 0 replies; 25+ messages in thread
From: Takashi Iwai @ 2015-01-19 15:54 UTC (permalink / raw)
  To: alsa-devel; +Cc: Stefan Hajnoczi, Chris Rorvick

Signed-off-by: Takashi Iwai <tiwai@suse.de>
---
 sound/usb/line6/pcm.c | 11 ++++-------
 1 file changed, 4 insertions(+), 7 deletions(-)

diff --git a/sound/usb/line6/pcm.c b/sound/usb/line6/pcm.c
index 932cc7e194e2..edab3cd7c048 100644
--- a/sound/usb/line6/pcm.c
+++ b/sound/usb/line6/pcm.c
@@ -227,9 +227,8 @@ int snd_line6_trigger(struct snd_pcm_substream *substream, int cmd)
 	struct snd_line6_pcm *line6pcm = snd_pcm_substream_chip(substream);
 	struct snd_pcm_substream *s;
 	int err;
-	unsigned long flags;
 
-	spin_lock_irqsave(&line6pcm->lock_trigger, flags);
+	spin_lock(&line6pcm->lock_trigger);
 	clear_bit(LINE6_INDEX_PREPARED, &line6pcm->flags);
 
 	snd_pcm_group_for_each_entry(s, substream) {
@@ -240,8 +239,7 @@ int snd_line6_trigger(struct snd_pcm_substream *substream, int cmd)
 			err = snd_line6_playback_trigger(line6pcm, cmd);
 
 			if (err < 0) {
-				spin_unlock_irqrestore(&line6pcm->lock_trigger,
-						       flags);
+				spin_unlock(&line6pcm->lock_trigger);
 				return err;
 			}
 
@@ -251,8 +249,7 @@ int snd_line6_trigger(struct snd_pcm_substream *substream, int cmd)
 			err = snd_line6_capture_trigger(line6pcm, cmd);
 
 			if (err < 0) {
-				spin_unlock_irqrestore(&line6pcm->lock_trigger,
-						       flags);
+				spin_unlock(&line6pcm->lock_trigger);
 				return err;
 			}
 
@@ -264,7 +261,7 @@ int snd_line6_trigger(struct snd_pcm_substream *substream, int cmd)
 		}
 	}
 
-	spin_unlock_irqrestore(&line6pcm->lock_trigger, flags);
+	spin_unlock(&line6pcm->lock_trigger);
 	return 0;
 }
 
-- 
2.2.1

^ permalink raw reply related	[flat|nested] 25+ messages in thread

* [PATCH 10/17] ALSA: line6: Reorganize card resource handling
  2015-01-19 15:54 [PATCH 00/17] More line6 driver code reorg and cleanups Takashi Iwai
                   ` (8 preceding siblings ...)
  2015-01-19 15:54 ` [PATCH 09/17] ALSA: line6: Drop superfluous irqsave/irqrestore in PCM trigger callback Takashi Iwai
@ 2015-01-19 15:54 ` Takashi Iwai
  2015-01-20  6:14   ` Chris Rorvick
  2015-01-19 15:54 ` [PATCH 11/17] ALSA: line6: Remove driver version string Takashi Iwai
                   ` (7 subsequent siblings)
  17 siblings, 1 reply; 25+ messages in thread
From: Takashi Iwai @ 2015-01-19 15:54 UTC (permalink / raw)
  To: alsa-devel; +Cc: Stefan Hajnoczi, Chris Rorvick

This is a fairly big rewrite regarding the card resource management in
line6 drivers:

- The card creation is moved into line6_probe().  This adds the global
  destructor to private_free, so that each driver doesn't have to call
  it any longer.

- The USB disconnect callback handles the card release, thus each
  driver needs to concentrate on only its own resources.  No need to
  snd_card_*() call in the destructor.

- Fix the potential stall in disconnection by removing
  snd_card_free().   It's replaced with snd_card_free_when_closed()
  for asynchronous release.

- The only remaining operation for the card in each driver is the call
  of snd_card_register().  All the rest are dealt in the common module
  by itself.

- These ended up with removal of audio.[ch] as a result of a reduction
  of one layer.  Each driver just needs to call line6_probe().

Signed-off-by: Takashi Iwai <tiwai@suse.de>
---
 sound/usb/line6/Makefile   |  1 -
 sound/usb/line6/audio.c    | 74 -----------------------------------------
 sound/usb/line6/audio.h    | 21 ------------
 sound/usb/line6/capture.c  |  1 -
 sound/usb/line6/driver.c   | 82 +++++++++++++++++++++++++++-------------------
 sound/usb/line6/midi.c     |  1 -
 sound/usb/line6/pcm.c      |  1 -
 sound/usb/line6/playback.c |  1 -
 sound/usb/line6/pod.c      | 60 +++++----------------------------
 sound/usb/line6/podhd.c    | 75 ++++--------------------------------------
 sound/usb/line6/toneport.c | 65 ++++--------------------------------
 sound/usb/line6/variax.c   | 58 ++++++++------------------------
 12 files changed, 85 insertions(+), 355 deletions(-)
 delete mode 100644 sound/usb/line6/audio.c
 delete mode 100644 sound/usb/line6/audio.h

diff --git a/sound/usb/line6/Makefile b/sound/usb/line6/Makefile
index fa3a78dac097..b8b3b2a543d8 100644
--- a/sound/usb/line6/Makefile
+++ b/sound/usb/line6/Makefile
@@ -1,5 +1,4 @@
 snd-usb-line6-y := 		\
-		audio.o		\
 		capture.o	\
 		driver.o	\
 		midi.o		\
diff --git a/sound/usb/line6/audio.c b/sound/usb/line6/audio.c
deleted file mode 100644
index 95686e5af4bd..000000000000
--- a/sound/usb/line6/audio.c
+++ /dev/null
@@ -1,74 +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.
- *
- */
-
-#include <sound/core.h>
-#include <sound/initval.h>
-#include <linux/export.h>
-
-#include "driver.h"
-#include "audio.h"
-
-/*
-	Initialize the Line6 USB audio system.
-*/
-int line6_init_audio(struct usb_line6 *line6)
-{
-	struct snd_card *card;
-	int err;
-
-	err = snd_card_new(line6->ifcdev,
-			   SNDRV_DEFAULT_IDX1, SNDRV_DEFAULT_STR1,
-			   THIS_MODULE, 0, &card);
-	if (err < 0)
-		return err;
-
-	line6->card = card;
-
-	strcpy(card->id, line6->properties->id);
-	strcpy(card->driver, DRIVER_NAME);
-	strcpy(card->shortname, line6->properties->name);
-	/* longname is 80 chars - see asound.h */
-	sprintf(card->longname, "Line6 %s at USB %s", line6->properties->name,
-		dev_name(line6->ifcdev));
-	return 0;
-}
-EXPORT_SYMBOL_GPL(line6_init_audio);
-
-/*
-	Register the Line6 USB audio system.
-*/
-int line6_register_audio(struct usb_line6 *line6)
-{
-	int err;
-
-	err = snd_card_register(line6->card);
-	if (err < 0)
-		return err;
-
-	return 0;
-}
-EXPORT_SYMBOL_GPL(line6_register_audio);
-
-/*
-	Cleanup the Line6 USB audio system.
-*/
-void line6_cleanup_audio(struct usb_line6 *line6)
-{
-	struct snd_card *card = line6->card;
-
-	if (card == NULL)
-		return;
-
-	snd_card_disconnect(card);
-	snd_card_free(card);
-	line6->card = NULL;
-}
-EXPORT_SYMBOL_GPL(line6_cleanup_audio);
diff --git a/sound/usb/line6/audio.h b/sound/usb/line6/audio.h
deleted file mode 100644
index 5f8a09a0fa95..000000000000
--- a/sound/usb/line6/audio.h
+++ /dev/null
@@ -1,21 +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 AUDIO_H
-#define AUDIO_H
-
-#include "driver.h"
-
-extern void line6_cleanup_audio(struct usb_line6 *);
-extern int line6_init_audio(struct usb_line6 *);
-extern int line6_register_audio(struct usb_line6 *);
-
-#endif
diff --git a/sound/usb/line6/capture.c b/sound/usb/line6/capture.c
index 727b31876d48..e8c54ede9227 100644
--- a/sound/usb/line6/capture.c
+++ b/sound/usb/line6/capture.c
@@ -14,7 +14,6 @@
 #include <sound/pcm.h>
 #include <sound/pcm_params.h>
 
-#include "audio.h"
 #include "capture.h"
 #include "driver.h"
 #include "pcm.h"
diff --git a/sound/usb/line6/driver.c b/sound/usb/line6/driver.c
index b8f5134dcec2..8b6a658a8a58 100644
--- a/sound/usb/line6/driver.c
+++ b/sound/usb/line6/driver.c
@@ -15,7 +15,9 @@
 #include <linux/slab.h>
 #include <linux/usb.h>
 
-#include "audio.h"
+#include <sound/core.h>
+#include <sound/initval.h>
+
 #include "capture.h"
 #include "driver.h"
 #include "midi.h"
@@ -481,17 +483,16 @@ ssize_t line6_nop_read(struct device *dev, struct device_attribute *attr,
 EXPORT_SYMBOL_GPL(line6_nop_read);
 
 /*
-	Generic destructor.
+	Card destructor.
 */
-static void line6_destruct(struct usb_interface *interface)
+static void line6_destruct(struct snd_card *card)
 {
-	struct usb_line6 *line6;
+	struct usb_line6 *line6 = card->private_data;
+	struct usb_device *usbdev;
 
-	if (interface == NULL)
-		return;
-	line6 = usb_get_intfdata(interface);
-	if (line6 == NULL)
+	if (!line6)
 		return;
+	usbdev = line6->usbdev;
 
 	/* free buffer memory first: */
 	kfree(line6->buffer_message);
@@ -500,8 +501,11 @@ static void line6_destruct(struct usb_interface *interface)
 	/* then free URBs: */
 	usb_free_urb(line6->urb_listen);
 
-	/* make sure the device isn't destructed twice: */
-	usb_set_intfdata(interface, NULL);
+	/* free interface data: */
+	kfree(line6);
+
+	/* decrement reference counters: */
+	usb_put_dev(usbdev);
 }
 
 /*
@@ -513,6 +517,7 @@ int line6_probe(struct usb_interface *interface,
 		int (*private_init)(struct usb_interface *, struct usb_line6 *))
 {
 	struct usb_device *usbdev;
+	struct snd_card *card;
 	int interface_number;
 	int ret;
 
@@ -569,8 +574,26 @@ int line6_probe(struct usb_interface *interface,
 		}
 	}
 
+	ret = snd_card_new(line6->ifcdev,
+			   SNDRV_DEFAULT_IDX1, SNDRV_DEFAULT_STR1,
+			   THIS_MODULE, 0, &card);
+	if (ret < 0)
+		goto err_put;
+
+	line6->card = card;
+	strcpy(card->id, line6->properties->id);
+	strcpy(card->driver, DRIVER_NAME);
+	strcpy(card->shortname, line6->properties->name);
+	sprintf(card->longname, "Line6 %s at USB %s", line6->properties->name,
+		dev_name(line6->ifcdev));
+	card->private_data = line6;
+	card->private_free = line6_destruct;
+
 	usb_set_intfdata(interface, line6);
 
+	/* increment reference counters: */
+	usb_get_dev(usbdev);
+
 	if (properties->capabilities & LINE6_CAP_CONTROL) {
 		/* initialize USB buffers: */
 		line6->buffer_listen =
@@ -612,15 +635,11 @@ int line6_probe(struct usb_interface *interface,
 	dev_info(&interface->dev, "Line6 %s now attached\n",
 		 line6->properties->name);
 
-	/* increment reference counters: */
-	usb_get_intf(interface);
-	usb_get_dev(usbdev);
-
 	return 0;
 
-err_destruct:
-	line6_destruct(interface);
-err_put:
+ err_destruct:
+	snd_card_free(card);
+ err_put:
 	return ret;
 }
 EXPORT_SYMBOL_GPL(line6_probe);
@@ -642,29 +661,26 @@ void line6_disconnect(struct usb_interface *interface)
 
 	interface_number = interface->cur_altsetting->desc.bInterfaceNumber;
 	line6 = usb_get_intfdata(interface);
+	if (!line6)
+		return;
 
-	if (line6 != NULL) {
-		if (line6->urb_listen != NULL)
-			line6_stop_listen(line6);
+	if (line6->urb_listen != NULL)
+		line6_stop_listen(line6);
 
-		if (usbdev != line6->usbdev)
-			dev_err(line6->ifcdev,
-				"driver bug: inconsistent usb device\n");
+	if (usbdev != line6->usbdev)
+		dev_err(line6->ifcdev, "driver bug: inconsistent usb device\n");
 
+	snd_card_disconnect(line6->card);
+	if (line6->disconnect)
 		line6->disconnect(interface);
 
-		dev_info(&interface->dev, "Line6 %s now disconnected\n",
-			 line6->properties->name);
-	}
-
-	line6_destruct(interface);
+	dev_info(&interface->dev, "Line6 %s now disconnected\n",
+		 line6->properties->name);
 
-	/* free interface data: */
-	kfree(line6);
+	/* make sure the device isn't destructed twice: */
+	usb_set_intfdata(interface, NULL);
 
-	/* decrement reference counters: */
-	usb_put_intf(interface);
-	usb_put_dev(usbdev);
+	snd_card_free_when_closed(line6->card);
 }
 EXPORT_SYMBOL_GPL(line6_disconnect);
 
diff --git a/sound/usb/line6/midi.c b/sound/usb/line6/midi.c
index f333cef5d2d7..68793cc5dc1e 100644
--- a/sound/usb/line6/midi.c
+++ b/sound/usb/line6/midi.c
@@ -15,7 +15,6 @@
 #include <sound/core.h>
 #include <sound/rawmidi.h>
 
-#include "audio.h"
 #include "driver.h"
 #include "midi.h"
 #include "usbdefs.h"
diff --git a/sound/usb/line6/pcm.c b/sound/usb/line6/pcm.c
index edab3cd7c048..1e77d0d9da17 100644
--- a/sound/usb/line6/pcm.c
+++ b/sound/usb/line6/pcm.c
@@ -16,7 +16,6 @@
 #include <sound/pcm.h>
 #include <sound/pcm_params.h>
 
-#include "audio.h"
 #include "capture.h"
 #include "driver.h"
 #include "playback.h"
diff --git a/sound/usb/line6/playback.c b/sound/usb/line6/playback.c
index 5a7fe409a3b9..ec2384c875a7 100644
--- a/sound/usb/line6/playback.c
+++ b/sound/usb/line6/playback.c
@@ -14,7 +14,6 @@
 #include <sound/pcm.h>
 #include <sound/pcm_params.h>
 
-#include "audio.h"
 #include "capture.h"
 #include "driver.h"
 #include "pcm.h"
diff --git a/sound/usb/line6/pod.c b/sound/usb/line6/pod.c
index d6bc5a1ab7f4..6b30deb6b157 100644
--- a/sound/usb/line6/pod.c
+++ b/sound/usb/line6/pod.c
@@ -18,7 +18,6 @@
 #include <sound/core.h>
 #include <sound/control.h>
 
-#include "audio.h"
 #include "capture.h"
 #include "driver.h"
 #include "playback.h"
@@ -340,7 +339,7 @@ static void pod_startup4(struct work_struct *work)
 	line6_read_serial_number(&pod->line6, &pod->serial_number);
 
 	/* ALSA audio interface: */
-	line6_register_audio(line6);
+	snd_card_register(line6->card);
 }
 
 /* POD special files: */
@@ -398,21 +397,6 @@ static struct snd_kcontrol_new pod_control_monitor = {
 };
 
 /*
-	POD destructor.
-*/
-static void pod_destruct(struct usb_interface *interface)
-{
-	struct usb_line6_pod *pod = usb_get_intfdata(interface);
-
-	if (pod == NULL)
-		return;
-	line6_cleanup_audio(&pod->line6);
-
-	del_timer(&pod->startup_timer);
-	cancel_work_sync(&pod->startup_work);
-}
-
-/*
 	POD device disconnected.
 */
 static void line6_pod_disconnect(struct usb_interface *interface)
@@ -424,21 +408,18 @@ static void line6_pod_disconnect(struct usb_interface *interface)
 	pod = usb_get_intfdata(interface);
 
 	if (pod != NULL) {
-		struct snd_line6_pcm *line6pcm = pod->line6.line6pcm;
 		struct device *dev = &interface->dev;
 
-		if (line6pcm != NULL)
-			line6_pcm_disconnect(line6pcm);
-
 		if (dev != NULL) {
 			/* remove sysfs entries: */
 			device_remove_file(dev, &dev_attr_device_id);
 			device_remove_file(dev, &dev_attr_firmware_version);
 			device_remove_file(dev, &dev_attr_serial_number);
 		}
-	}
 
-	pod_destruct(interface);
+		del_timer_sync(&pod->startup_timer);
+		cancel_work_sync(&pod->startup_work);
+	}
 }
 
 /*
@@ -457,8 +438,8 @@ static int pod_create_files2(struct device *dev)
 /*
 	 Try to init POD device.
 */
-static int pod_try_init(struct usb_interface *interface,
-			struct usb_line6 *line6)
+static int pod_init(struct usb_interface *interface,
+		    struct usb_line6 *line6)
 {
 	int err;
 	struct usb_line6_pod *pod = (struct usb_line6_pod *) line6;
@@ -477,11 +458,6 @@ static int pod_try_init(struct usb_interface *interface,
 	if (err < 0)
 		return err;
 
-	/* initialize audio system: */
-	err = line6_init_audio(line6);
-	if (err < 0)
-		return err;
-
 	/* initialize MIDI subsystem: */
 	err = line6_init_midi(line6);
 	if (err < 0)
@@ -514,20 +490,6 @@ static int pod_try_init(struct usb_interface *interface,
 	return 0;
 }
 
-/*
-	 Init POD device (and clean up in case of failure).
-*/
-static int pod_init(struct usb_interface *interface,
-		    struct usb_line6 *line6)
-{
-	int err = pod_try_init(interface, line6);
-
-	if (err < 0)
-		pod_destruct(interface);
-
-	return err;
-}
-
 #define LINE6_DEVICE(prod) USB_DEVICE(0x0e41, prod)
 #define LINE6_IF_NUM(prod, n) USB_DEVICE_INTERFACE_NUMBER(0x0e41, prod, n)
 
@@ -636,17 +598,13 @@ 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;
+	return line6_probe(interface, &pod->line6,
+			   &pod_properties_table[id->driver_info],
+			   pod_init);
 }
 
 static struct usb_driver pod_driver = {
diff --git a/sound/usb/line6/podhd.c b/sound/usb/line6/podhd.c
index 8f4ca1d20b62..1d11185780e3 100644
--- a/sound/usb/line6/podhd.c
+++ b/sound/usb/line6/podhd.c
@@ -15,7 +15,6 @@
 #include <sound/core.h>
 #include <sound/pcm.h>
 
-#include "audio.h"
 #include "driver.h"
 #include "pcm.h"
 #include "usbdefs.h"
@@ -86,57 +85,17 @@ static struct line6_pcm_properties podhd_pcm_properties = {
 };
 
 /*
-	POD HD destructor.
-*/
-static void podhd_destruct(struct usb_interface *interface)
-{
-	struct usb_line6_podhd *podhd = usb_get_intfdata(interface);
-
-	if (podhd == NULL)
-		return;
-	line6_cleanup_audio(&podhd->line6);
-}
-
-/*
-	POD HD device disconnected.
-*/
-static void line6_podhd_disconnect(struct usb_interface *interface)
-{
-	struct usb_line6_podhd *podhd;
-
-	if (interface == NULL)
-		return;
-	podhd = usb_get_intfdata(interface);
-
-	if (podhd != NULL) {
-		struct snd_line6_pcm *line6pcm = podhd->line6.line6pcm;
-
-		if (line6pcm != NULL)
-			line6_pcm_disconnect(line6pcm);
-	}
-
-	podhd_destruct(interface);
-}
-
-/*
 	Try to init POD HD device.
 */
-static int podhd_try_init(struct usb_interface *interface,
-			  struct usb_line6_podhd *podhd)
+static int podhd_init(struct usb_interface *interface,
+		      struct usb_line6 *line6)
 {
+	struct usb_line6_podhd *podhd = (struct usb_line6_podhd *) line6;
 	int err;
-	struct usb_line6 *line6 = &podhd->line6;
 
 	if ((interface == NULL) || (podhd == NULL))
 		return -ENODEV;
 
-	line6->disconnect = line6_podhd_disconnect;
-
-	/* initialize audio system: */
-	err = line6_init_audio(line6);
-	if (err < 0)
-		return err;
-
 	/* initialize MIDI subsystem: */
 	err = line6_init_midi(line6);
 	if (err < 0)
@@ -148,8 +107,7 @@ static int podhd_try_init(struct usb_interface *interface,
 		return err;
 
 	/* register USB audio system: */
-	err = line6_register_audio(line6);
-	return err;
+	return snd_card_register(line6->card);
 }
 
 #define LINE6_DEVICE(prod) USB_DEVICE(0x0e41, prod)
@@ -218,38 +176,19 @@ static const struct line6_properties podhd_properties_table[] = {
 };
 
 /*
-	Init POD HD device (and clean up in case of failure).
-*/
-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);
-
-	if (err < 0)
-		podhd_destruct(interface);
-
-	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;
+	return line6_probe(interface, &podhd->line6,
+			   &podhd_properties_table[id->driver_info],
+			   podhd_init);
 }
 
 static struct usb_driver podhd_driver = {
diff --git a/sound/usb/line6/toneport.c b/sound/usb/line6/toneport.c
index 6ec3268a6153..3097a75a9bec 100644
--- a/sound/usb/line6/toneport.c
+++ b/sound/usb/line6/toneport.c
@@ -17,7 +17,6 @@
 #include <sound/core.h>
 #include <sound/control.h>
 
-#include "audio.h"
 #include "capture.h"
 #include "driver.h"
 #include "playback.h"
@@ -331,18 +330,6 @@ static struct snd_kcontrol_new toneport_control_source = {
 };
 
 /*
-	Toneport destructor.
-*/
-static void toneport_destruct(struct usb_interface *interface)
-{
-	struct usb_line6_toneport *toneport = usb_get_intfdata(interface);
-
-	if (toneport == NULL)
-		return;
-	line6_cleanup_audio(&toneport->line6);
-}
-
-/*
 	Setup Toneport device.
 */
 static void toneport_setup(struct usb_line6_toneport *toneport)
@@ -394,25 +381,14 @@ static void line6_toneport_disconnect(struct usb_interface *interface)
 		device_remove_file(&interface->dev, &dev_attr_led_red);
 		device_remove_file(&interface->dev, &dev_attr_led_green);
 	}
-
-	if (toneport != NULL) {
-		struct snd_line6_pcm *line6pcm = toneport->line6.line6pcm;
-
-		if (line6pcm != NULL) {
-			line6_pcm_release(line6pcm, LINE6_BITS_PCM_MONITOR);
-			line6_pcm_disconnect(line6pcm);
-		}
-	}
-
-	toneport_destruct(interface);
 }
 
 
 /*
 	 Try to init Toneport device.
 */
-static int toneport_try_init(struct usb_interface *interface,
-			     struct usb_line6 *line6)
+static int toneport_init(struct usb_interface *interface,
+			 struct usb_line6 *line6)
 {
 	int err;
 	struct usb_line6_toneport *toneport =  (struct usb_line6_toneport *) line6;
@@ -422,11 +398,6 @@ static int toneport_try_init(struct usb_interface *interface,
 
 	line6->disconnect = line6_toneport_disconnect;
 
-	/* initialize audio system: */
-	err = line6_init_audio(line6);
-	if (err < 0)
-		return err;
-
 	/* initialize PCM subsystem: */
 	err = line6_init_pcm(line6, &toneport_pcm_properties);
 	if (err < 0)
@@ -456,11 +427,6 @@ static int toneport_try_init(struct usb_interface *interface,
 		break;
 	}
 
-	/* register audio system: */
-	err = line6_register_audio(line6);
-	if (err < 0)
-		return err;
-
 	line6_read_serial_number(line6, &toneport->serial_number);
 	line6_read_data(line6, 0x80c2, &toneport->firmware_version, 1);
 
@@ -477,21 +443,8 @@ static int toneport_try_init(struct usb_interface *interface,
 		    (unsigned long)toneport);
 	mod_timer(&toneport->timer, jiffies + TONEPORT_PCM_DELAY * HZ);
 
-	return 0;
-}
-
-/*
-	 Init Toneport device (and clean up in case of failure).
-*/
-static int toneport_init(struct usb_interface *interface,
-			 struct usb_line6 *line6)
-{
-	int err = toneport_try_init(interface, line6);
-
-	if (err < 0)
-		toneport_destruct(interface);
-
-	return err;
+	/* register audio system: */
+	return snd_card_register(line6->card);
 }
 
 #ifdef CONFIG_PM
@@ -595,18 +548,14 @@ 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;
+	return line6_probe(interface, &toneport->line6,
+			   &toneport_properties_table[id->driver_info],
+			   toneport_init);
 }
 
 static struct usb_driver toneport_driver = {
diff --git a/sound/usb/line6/variax.c b/sound/usb/line6/variax.c
index 9a9c7e48e24f..a591c2c5794f 100644
--- a/sound/usb/line6/variax.c
+++ b/sound/usb/line6/variax.c
@@ -16,7 +16,6 @@
 #include <linux/module.h>
 #include <sound/core.h>
 
-#include "audio.h"
 #include "driver.h"
 #include "usbdefs.h"
 
@@ -179,7 +178,7 @@ static void variax_startup6(struct work_struct *work)
 	CHECK_STARTUP_PROGRESS(variax->startup_progress, VARIAX_STARTUP_SETUP);
 
 	/* ALSA audio interface: */
-	line6_register_audio(&variax->line6);
+	snd_card_register(variax->line6.card);
 }
 
 /*
@@ -211,13 +210,16 @@ static void line6_variax_process_message(struct usb_line6 *line6)
 /*
 	Variax destructor.
 */
-static void variax_destruct(struct usb_interface *interface)
+static void line6_variax_disconnect(struct usb_interface *interface)
 {
-	struct usb_line6_variax *variax = usb_get_intfdata(interface);
+	struct usb_line6_variax *variax;
+
+	if (!interface)
+		return;
 
-	if (variax == NULL)
+	variax = usb_get_intfdata(interface);
+	if (!variax)
 		return;
-	line6_cleanup_audio(&variax->line6);
 
 	del_timer(&variax->startup_timer1);
 	del_timer(&variax->startup_timer2);
@@ -227,21 +229,10 @@ static void variax_destruct(struct usb_interface *interface)
 }
 
 /*
-	Workbench device disconnected.
-*/
-static void line6_variax_disconnect(struct usb_interface *interface)
-{
-	if (interface == NULL)
-		return;
-
-	variax_destruct(interface);
-}
-
-/*
 	 Try to init workbench device.
 */
-static int variax_try_init(struct usb_interface *interface,
-			   struct usb_line6 *line6)
+static int variax_init(struct usb_interface *interface,
+		       struct usb_line6 *line6)
 {
 	struct usb_line6_variax *variax = (struct usb_line6_variax *) line6;
 	int err;
@@ -263,11 +254,6 @@ static int variax_try_init(struct usb_interface *interface,
 	if (variax->buffer_activate == NULL)
 		return -ENOMEM;
 
-	/* initialize audio system: */
-	err = line6_init_audio(&variax->line6);
-	if (err < 0)
-		return err;
-
 	/* initialize MIDI subsystem: */
 	err = line6_init_midi(&variax->line6);
 	if (err < 0)
@@ -278,20 +264,6 @@ static int variax_try_init(struct usb_interface *interface,
 	return 0;
 }
 
-/*
-	 Init workbench device (and clean up in case of failure).
-*/
-static int variax_init(struct usb_interface *interface,
-		       struct usb_line6 *line6)
-{
-	int err = variax_try_init(interface, line6);
-
-	if (err < 0)
-		variax_destruct(interface);
-
-	return err;
-}
-
 #define LINE6_DEVICE(prod) USB_DEVICE(0x0e41, prod)
 #define LINE6_IF_NUM(prod, n) USB_DEVICE_INTERFACE_NUMBER(0x0e41, prod, n)
 
@@ -335,17 +307,13 @@ 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;
+	return line6_probe(interface, &variax->line6,
+			   &variax_properties_table[id->driver_info],
+			   variax_init);
 }
 
 static struct usb_driver variax_driver = {
-- 
2.2.1

^ permalink raw reply related	[flat|nested] 25+ messages in thread

* [PATCH 11/17] ALSA: line6: Remove driver version string
  2015-01-19 15:54 [PATCH 00/17] More line6 driver code reorg and cleanups Takashi Iwai
                   ` (9 preceding siblings ...)
  2015-01-19 15:54 ` [PATCH 10/17] ALSA: line6: Reorganize card resource handling Takashi Iwai
@ 2015-01-19 15:54 ` Takashi Iwai
  2015-01-19 15:54 ` [PATCH 12/17] ALSA: line6: Drop MISSING_CASE macro Takashi Iwai
                   ` (6 subsequent siblings)
  17 siblings, 0 replies; 25+ messages in thread
From: Takashi Iwai @ 2015-01-19 15:54 UTC (permalink / raw)
  To: alsa-devel; +Cc: Stefan Hajnoczi, Chris Rorvick

This is rather useless for a driver that has been already merged into
the official tree.

Signed-off-by: Takashi Iwai <tiwai@suse.de>
---
 sound/usb/line6/driver.c | 2 --
 1 file changed, 2 deletions(-)

diff --git a/sound/usb/line6/driver.c b/sound/usb/line6/driver.c
index 8b6a658a8a58..6a3ec07d869f 100644
--- a/sound/usb/line6/driver.c
+++ b/sound/usb/line6/driver.c
@@ -27,7 +27,6 @@
 
 #define DRIVER_AUTHOR  "Markus Grabner <grabner@icg.tugraz.at>"
 #define DRIVER_DESC    "Line6 USB Driver"
-#define DRIVER_VERSION "0.9.1beta" DRIVER_REVISION
 
 /*
 	This is Line6's MIDI manufacturer ID.
@@ -729,4 +728,3 @@ EXPORT_SYMBOL_GPL(line6_resume);
 MODULE_AUTHOR(DRIVER_AUTHOR);
 MODULE_DESCRIPTION(DRIVER_DESC);
 MODULE_LICENSE("GPL");
-MODULE_VERSION(DRIVER_VERSION);
-- 
2.2.1

^ permalink raw reply related	[flat|nested] 25+ messages in thread

* [PATCH 12/17] ALSA: line6: Drop MISSING_CASE macro
  2015-01-19 15:54 [PATCH 00/17] More line6 driver code reorg and cleanups Takashi Iwai
                   ` (10 preceding siblings ...)
  2015-01-19 15:54 ` [PATCH 11/17] ALSA: line6: Remove driver version string Takashi Iwai
@ 2015-01-19 15:54 ` Takashi Iwai
  2015-01-19 15:54 ` [PATCH 13/17] ALSA: line6: Remove CHECK_RETURN macro Takashi Iwai
                   ` (5 subsequent siblings)
  17 siblings, 0 replies; 25+ messages in thread
From: Takashi Iwai @ 2015-01-19 15:54 UTC (permalink / raw)
  To: alsa-devel; +Cc: Stefan Hajnoczi, Chris Rorvick

Such a debug is needed in the core code, not in each lowlevel driver.

Signed-off-by: Takashi Iwai <tiwai@suse.de>
---
 sound/usb/line6/driver.h | 4 ----
 sound/usb/line6/pcm.c    | 3 ---
 2 files changed, 7 deletions(-)

diff --git a/sound/usb/line6/driver.h b/sound/usb/line6/driver.h
index 31cd318369e9..8e4d946a130c 100644
--- a/sound/usb/line6/driver.h
+++ b/sound/usb/line6/driver.h
@@ -48,10 +48,6 @@
 
 #define LINE6_CHANNEL_MASK 0x0f
 
-#define MISSING_CASE	\
-	pr_err("line6usb driver bug: missing case in %s:%d\n", \
-		__FILE__, __LINE__)
-
 #define CHECK_RETURN(x)		\
 do {				\
 	err = x;		\
diff --git a/sound/usb/line6/pcm.c b/sound/usb/line6/pcm.c
index 1e77d0d9da17..39034c7681da 100644
--- a/sound/usb/line6/pcm.c
+++ b/sound/usb/line6/pcm.c
@@ -488,9 +488,6 @@ int snd_line6_prepare(struct snd_pcm_substream *substream)
 			line6_unlink_wait_clear_audio_in_urbs(line6pcm);
 
 		break;
-
-	default:
-		MISSING_CASE;
 	}
 
 	if (!test_and_set_bit(LINE6_INDEX_PREPARED, &line6pcm->flags)) {
-- 
2.2.1

^ permalink raw reply related	[flat|nested] 25+ messages in thread

* [PATCH 13/17] ALSA: line6: Remove CHECK_RETURN macro
  2015-01-19 15:54 [PATCH 00/17] More line6 driver code reorg and cleanups Takashi Iwai
                   ` (11 preceding siblings ...)
  2015-01-19 15:54 ` [PATCH 12/17] ALSA: line6: Drop MISSING_CASE macro Takashi Iwai
@ 2015-01-19 15:54 ` Takashi Iwai
  2015-01-19 15:54 ` [PATCH 14/17] ALSA: line6: Remove superfluous disconnect call in suspend handler Takashi Iwai
                   ` (4 subsequent siblings)
  17 siblings, 0 replies; 25+ messages in thread
From: Takashi Iwai @ 2015-01-19 15:54 UTC (permalink / raw)
  To: alsa-devel; +Cc: Stefan Hajnoczi, Chris Rorvick

Such a macro doesn't improve readability.

Signed-off-by: Takashi Iwai <tiwai@suse.de>
---
 sound/usb/line6/driver.h   |  7 -------
 sound/usb/line6/pod.c      | 12 +++++++++---
 sound/usb/line6/toneport.c | 10 ++++++----
 3 files changed, 15 insertions(+), 14 deletions(-)

diff --git a/sound/usb/line6/driver.h b/sound/usb/line6/driver.h
index 8e4d946a130c..f484aa09840b 100644
--- a/sound/usb/line6/driver.h
+++ b/sound/usb/line6/driver.h
@@ -48,13 +48,6 @@
 
 #define LINE6_CHANNEL_MASK 0x0f
 
-#define CHECK_RETURN(x)		\
-do {				\
-	err = x;		\
-	if (err < 0)		\
-		return err;	\
-} while (0)
-
 #define CHECK_STARTUP_PROGRESS(x, n)	\
 do {					\
 	if ((x) >= (n))			\
diff --git a/sound/usb/line6/pod.c b/sound/usb/line6/pod.c
index 6b30deb6b157..6f4b09982589 100644
--- a/sound/usb/line6/pod.c
+++ b/sound/usb/line6/pod.c
@@ -429,9 +429,15 @@ static int pod_create_files2(struct device *dev)
 {
 	int err;
 
-	CHECK_RETURN(device_create_file(dev, &dev_attr_device_id));
-	CHECK_RETURN(device_create_file(dev, &dev_attr_firmware_version));
-	CHECK_RETURN(device_create_file(dev, &dev_attr_serial_number));
+	err = device_create_file(dev, &dev_attr_device_id);
+	if (err < 0)
+		return err;
+	err = device_create_file(dev, &dev_attr_firmware_version);
+	if (err < 0)
+		return err;
+	err = device_create_file(dev, &dev_attr_serial_number);
+	if (err < 0)
+		return err;
 	return 0;
 }
 
diff --git a/sound/usb/line6/toneport.c b/sound/usb/line6/toneport.c
index 3097a75a9bec..24544b7ab476 100644
--- a/sound/usb/line6/toneport.c
+++ b/sound/usb/line6/toneport.c
@@ -431,10 +431,12 @@ static int toneport_init(struct usb_interface *interface,
 	line6_read_data(line6, 0x80c2, &toneport->firmware_version, 1);
 
 	if (toneport_has_led(toneport->type)) {
-		CHECK_RETURN(device_create_file
-			     (&interface->dev, &dev_attr_led_red));
-		CHECK_RETURN(device_create_file
-			     (&interface->dev, &dev_attr_led_green));
+		err = device_create_file(&interface->dev, &dev_attr_led_red);
+		if (err < 0)
+			return err;
+		err = device_create_file(&interface->dev, &dev_attr_led_green);
+		if (err < 0)
+			return err;
 	}
 
 	toneport_setup(toneport);
-- 
2.2.1

^ permalink raw reply related	[flat|nested] 25+ messages in thread

* [PATCH 14/17] ALSA: line6: Remove superfluous disconnect call in suspend handler
  2015-01-19 15:54 [PATCH 00/17] More line6 driver code reorg and cleanups Takashi Iwai
                   ` (12 preceding siblings ...)
  2015-01-19 15:54 ` [PATCH 13/17] ALSA: line6: Remove CHECK_RETURN macro Takashi Iwai
@ 2015-01-19 15:54 ` Takashi Iwai
  2015-01-19 15:54 ` [PATCH 15/17] ALSA: line6: Sync PCM stop at disconnect Takashi Iwai
                   ` (3 subsequent siblings)
  17 siblings, 0 replies; 25+ messages in thread
From: Takashi Iwai @ 2015-01-19 15:54 UTC (permalink / raw)
  To: alsa-devel; +Cc: Stefan Hajnoczi, Chris Rorvick

Calling line6_pcm_disconnect() at suspend callback is superfluous and
rather confusing.  Let's get rid of it.

Signed-off-by: Takashi Iwai <tiwai@suse.de>
---
 sound/usb/line6/driver.c | 1 -
 1 file changed, 1 deletion(-)

diff --git a/sound/usb/line6/driver.c b/sound/usb/line6/driver.c
index 6a3ec07d869f..f222d9ffeca5 100644
--- a/sound/usb/line6/driver.c
+++ b/sound/usb/line6/driver.c
@@ -700,7 +700,6 @@ int line6_suspend(struct usb_interface *interface, pm_message_t message)
 
 	if (line6pcm != NULL) {
 		snd_pcm_suspend_all(line6pcm->pcm);
-		line6_pcm_disconnect(line6pcm);
 		line6pcm->flags = 0;
 	}
 
-- 
2.2.1

^ permalink raw reply related	[flat|nested] 25+ messages in thread

* [PATCH 15/17] ALSA: line6: Sync PCM stop at disconnect
  2015-01-19 15:54 [PATCH 00/17] More line6 driver code reorg and cleanups Takashi Iwai
                   ` (13 preceding siblings ...)
  2015-01-19 15:54 ` [PATCH 14/17] ALSA: line6: Remove superfluous disconnect call in suspend handler Takashi Iwai
@ 2015-01-19 15:54 ` Takashi Iwai
  2015-01-19 15:54 ` [PATCH 16/17] ALSA: line6: Make line6_send_raw_message() static Takashi Iwai
                   ` (2 subsequent siblings)
  17 siblings, 0 replies; 25+ messages in thread
From: Takashi Iwai @ 2015-01-19 15:54 UTC (permalink / raw)
  To: alsa-devel; +Cc: Stefan Hajnoczi, Chris Rorvick

Call line6_pcm_disconnect() at disconnect to make sure that all URBs
are cleared.  Also reduce the superfluous snd_pcm_stop() calls from
the function (and remove the unused function) since the streams are
guaranteed to be stopped at this point via snd_card_disconnect().

Signed-off-by: Takashi Iwai <tiwai@suse.de>
---
 sound/usb/line6/driver.c |  2 ++
 sound/usb/line6/pcm.c    | 19 +------------------
 2 files changed, 3 insertions(+), 18 deletions(-)

diff --git a/sound/usb/line6/driver.c b/sound/usb/line6/driver.c
index f222d9ffeca5..1193d16396a0 100644
--- a/sound/usb/line6/driver.c
+++ b/sound/usb/line6/driver.c
@@ -670,6 +670,8 @@ void line6_disconnect(struct usb_interface *interface)
 		dev_err(line6->ifcdev, "driver bug: inconsistent usb device\n");
 
 	snd_card_disconnect(line6->card);
+	if (line6->line6pcm)
+		line6_pcm_disconnect(line6->line6pcm);
 	if (line6->disconnect)
 		line6->disconnect(interface);
 
diff --git a/sound/usb/line6/pcm.c b/sound/usb/line6/pcm.c
index 39034c7681da..08fa9753a680 100644
--- a/sound/usb/line6/pcm.c
+++ b/sound/usb/line6/pcm.c
@@ -379,30 +379,13 @@ static int snd_line6_new_pcm(struct usb_line6 *line6, struct snd_pcm **pcm_ret)
 }
 
 /*
-	Stop substream if still running.
-*/
-static void pcm_disconnect_substream(struct snd_pcm_substream *substream)
-{
-	if (substream->runtime && snd_pcm_running(substream)) {
-		snd_pcm_stream_lock_irq(substream);
-		snd_pcm_stop(substream, SNDRV_PCM_STATE_DISCONNECTED);
-		snd_pcm_stream_unlock_irq(substream);
-	}
-}
-
-/*
-	Stop PCM stream.
+	Sync with PCM stream stops.
 */
 void line6_pcm_disconnect(struct snd_line6_pcm *line6pcm)
 {
-	pcm_disconnect_substream(get_substream
-				 (line6pcm, SNDRV_PCM_STREAM_CAPTURE));
-	pcm_disconnect_substream(get_substream
-				 (line6pcm, SNDRV_PCM_STREAM_PLAYBACK));
 	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.
-- 
2.2.1

^ permalink raw reply related	[flat|nested] 25+ messages in thread

* [PATCH 16/17] ALSA: line6: Make line6_send_raw_message() static
  2015-01-19 15:54 [PATCH 00/17] More line6 driver code reorg and cleanups Takashi Iwai
                   ` (14 preceding siblings ...)
  2015-01-19 15:54 ` [PATCH 15/17] ALSA: line6: Sync PCM stop at disconnect Takashi Iwai
@ 2015-01-19 15:54 ` Takashi Iwai
  2015-01-19 15:54 ` [PATCH 17/17] ALSA: line6: Drop line6_send_program() and line6_transmit_parameter() Takashi Iwai
  2015-01-20  6:24 ` [PATCH 00/17] More line6 driver code reorg and cleanups Chris Rorvick
  17 siblings, 0 replies; 25+ messages in thread
From: Takashi Iwai @ 2015-01-19 15:54 UTC (permalink / raw)
  To: alsa-devel; +Cc: Stefan Hajnoczi, Chris Rorvick

It's used only locally.

Signed-off-by: Takashi Iwai <tiwai@suse.de>
---
 sound/usb/line6/driver.c | 4 ++--
 sound/usb/line6/driver.h | 2 --
 2 files changed, 2 insertions(+), 4 deletions(-)

diff --git a/sound/usb/line6/driver.c b/sound/usb/line6/driver.c
index 1193d16396a0..a2f72cc2bf96 100644
--- a/sound/usb/line6/driver.c
+++ b/sound/usb/line6/driver.c
@@ -88,8 +88,8 @@ static void line6_stop_listen(struct usb_line6 *line6)
 /*
 	Send raw message in pieces of wMaxPacketSize bytes.
 */
-int line6_send_raw_message(struct usb_line6 *line6, const char *buffer,
-			   int size)
+static int line6_send_raw_message(struct usb_line6 *line6, const char *buffer,
+				  int size)
 {
 	int i, done = 0;
 
diff --git a/sound/usb/line6/driver.h b/sound/usb/line6/driver.h
index f484aa09840b..8fd65f2e1f06 100644
--- a/sound/usb/line6/driver.h
+++ b/sound/usb/line6/driver.h
@@ -169,8 +169,6 @@ extern int line6_read_data(struct usb_line6 *line6, int address, void *data,
 extern int line6_read_serial_number(struct usb_line6 *line6,
 				    int *serial_number);
 extern int line6_send_program(struct usb_line6 *line6, u8 value);
-extern int line6_send_raw_message(struct usb_line6 *line6, const char *buffer,
-				  int size);
 extern int line6_send_raw_message_async(struct usb_line6 *line6,
 					const char *buffer, int size);
 extern int line6_send_sysex_message(struct usb_line6 *line6,
-- 
2.2.1

^ permalink raw reply related	[flat|nested] 25+ messages in thread

* [PATCH 17/17] ALSA: line6: Drop line6_send_program() and line6_transmit_parameter()
  2015-01-19 15:54 [PATCH 00/17] More line6 driver code reorg and cleanups Takashi Iwai
                   ` (15 preceding siblings ...)
  2015-01-19 15:54 ` [PATCH 16/17] ALSA: line6: Make line6_send_raw_message() static Takashi Iwai
@ 2015-01-19 15:54 ` Takashi Iwai
  2015-01-20  6:24 ` [PATCH 00/17] More line6 driver code reorg and cleanups Chris Rorvick
  17 siblings, 0 replies; 25+ messages in thread
From: Takashi Iwai @ 2015-01-19 15:54 UTC (permalink / raw)
  To: alsa-devel; +Cc: Stefan Hajnoczi, Chris Rorvick

Both functions are used nowhere.

Signed-off-by: Takashi Iwai <tiwai@suse.de>
---
 sound/usb/line6/driver.c | 59 ------------------------------------------------
 sound/usb/line6/driver.h |  3 ---
 2 files changed, 62 deletions(-)

diff --git a/sound/usb/line6/driver.c b/sound/usb/line6/driver.c
index a2f72cc2bf96..a3da18b876d1 100644
--- a/sound/usb/line6/driver.c
+++ b/sound/usb/line6/driver.c
@@ -299,65 +299,6 @@ static void line6_data_received(struct urb *urb)
 }
 
 /*
-	Send channel number (i.e., switch to a different sound).
-*/
-int line6_send_program(struct usb_line6 *line6, u8 value)
-{
-	int retval;
-	unsigned char *buffer;
-	int partial;
-
-	buffer = kmalloc(2, GFP_KERNEL);
-	if (!buffer)
-		return -ENOMEM;
-
-	buffer[0] = LINE6_PROGRAM_CHANGE | LINE6_CHANNEL_HOST;
-	buffer[1] = value;
-
-	retval = usb_interrupt_msg(line6->usbdev,
-				   usb_sndintpipe(line6->usbdev,
-						  line6->properties->ep_ctrl_w),
-				   buffer, 2, &partial, LINE6_TIMEOUT * HZ);
-
-	if (retval)
-		dev_err(line6->ifcdev, "usb_interrupt_msg failed (%d)\n",
-			retval);
-
-	kfree(buffer);
-	return retval;
-}
-
-/*
-	Transmit Line6 control parameter.
-*/
-int line6_transmit_parameter(struct usb_line6 *line6, int param, u8 value)
-{
-	int retval;
-	unsigned char *buffer;
-	int partial;
-
-	buffer = kmalloc(3, GFP_KERNEL);
-	if (!buffer)
-		return -ENOMEM;
-
-	buffer[0] = LINE6_PARAM_CHANGE | LINE6_CHANNEL_HOST;
-	buffer[1] = param;
-	buffer[2] = value;
-
-	retval = usb_interrupt_msg(line6->usbdev,
-				   usb_sndintpipe(line6->usbdev,
-						  line6->properties->ep_ctrl_w),
-				   buffer, 3, &partial, LINE6_TIMEOUT * HZ);
-
-	if (retval)
-		dev_err(line6->ifcdev, "usb_interrupt_msg failed (%d)\n",
-			retval);
-
-	kfree(buffer);
-	return retval;
-}
-
-/*
 	Read data from device.
 */
 int line6_read_data(struct usb_line6 *line6, int address, void *data,
diff --git a/sound/usb/line6/driver.h b/sound/usb/line6/driver.h
index 8fd65f2e1f06..d539c11d333d 100644
--- a/sound/usb/line6/driver.h
+++ b/sound/usb/line6/driver.h
@@ -168,7 +168,6 @@ extern int line6_read_data(struct usb_line6 *line6, int address, void *data,
 			   size_t datalen);
 extern int line6_read_serial_number(struct usb_line6 *line6,
 				    int *serial_number);
-extern int line6_send_program(struct usb_line6 *line6, u8 value);
 extern int line6_send_raw_message_async(struct usb_line6 *line6,
 					const char *buffer, int size);
 extern int line6_send_sysex_message(struct usb_line6 *line6,
@@ -178,8 +177,6 @@ extern ssize_t line6_set_raw(struct device *dev, struct device_attribute *attr,
 extern void line6_start_timer(struct timer_list *timer, unsigned int msecs,
 			      void (*function)(unsigned long),
 			      unsigned long data);
-extern int line6_transmit_parameter(struct usb_line6 *line6, int param,
-				    u8 value);
 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);
-- 
2.2.1

^ permalink raw reply related	[flat|nested] 25+ messages in thread

* Re: [PATCH 01/17] ALSA: line6: Split to each driver
  2015-01-19 15:54 ` [PATCH 01/17] ALSA: line6: Split to each driver Takashi Iwai
@ 2015-01-19 18:00   ` Chris Rorvick
  2015-01-19 19:37     ` Takashi Iwai
  0 siblings, 1 reply; 25+ messages in thread
From: Chris Rorvick @ 2015-01-19 18:00 UTC (permalink / raw)
  To: Takashi Iwai; +Cc: Stefan Hajnoczi, alsa-devel

On Mon, Jan 19, 2015 at 9:54 AM, Takashi Iwai <tiwai@suse.de> wrote:
> -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;
> +       }

These NULL checks are unnecessary, right?  We could just assign `usbdev'
at declaration and be done with it.  But maybe that should be another
patch.

Chris

^ permalink raw reply	[flat|nested] 25+ messages in thread

* Re: [PATCH 01/17] ALSA: line6: Split to each driver
  2015-01-19 18:00   ` Chris Rorvick
@ 2015-01-19 19:37     ` Takashi Iwai
  2015-01-20  5:59       ` Chris Rorvick
  0 siblings, 1 reply; 25+ messages in thread
From: Takashi Iwai @ 2015-01-19 19:37 UTC (permalink / raw)
  To: Chris Rorvick; +Cc: Stefan Hajnoczi, alsa-devel

At Mon, 19 Jan 2015 12:00:01 -0600,
Chris Rorvick wrote:
> 
> On Mon, Jan 19, 2015 at 9:54 AM, Takashi Iwai <tiwai@suse.de> wrote:
> > -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;
> > +       }
> 
> These NULL checks are unnecessary, right?  We could just assign `usbdev'
> at declaration and be done with it.  But maybe that should be another
> patch.

Right, the cleanup can be done later, as this patch is merely a
transition.


Takashi

^ permalink raw reply	[flat|nested] 25+ messages in thread

* Re: [PATCH 01/17] ALSA: line6: Split to each driver
  2015-01-19 19:37     ` Takashi Iwai
@ 2015-01-20  5:59       ` Chris Rorvick
  0 siblings, 0 replies; 25+ messages in thread
From: Chris Rorvick @ 2015-01-20  5:59 UTC (permalink / raw)
  To: Takashi Iwai; +Cc: Stefan Hajnoczi, alsa-devel

Sounds good.  I like the approach.  I was futzing around with how to do
this, though I didn't spend too much time on it because I was antici-
pating more patches from you that would be difficult to merge.  Using
the private_init callback is a nice idea and makes a necessarily large
change pretty easy to understand.

Chris

On Mon, Jan 19, 2015 at 1:37 PM, Takashi Iwai <tiwai@suse.de> wrote:
> At Mon, 19 Jan 2015 12:00:01 -0600,
> Chris Rorvick wrote:
>>
>> On Mon, Jan 19, 2015 at 9:54 AM, Takashi Iwai <tiwai@suse.de> wrote:
>> > -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;
>> > +       }
>>
>> These NULL checks are unnecessary, right?  We could just assign `usbdev'
>> at declaration and be done with it.  But maybe that should be another
>> patch.
>
> Right, the cleanup can be done later, as this patch is merely a
> transition.
>
>
> Takashi

^ permalink raw reply	[flat|nested] 25+ messages in thread

* Re: [PATCH 10/17] ALSA: line6: Reorganize card resource handling
  2015-01-19 15:54 ` [PATCH 10/17] ALSA: line6: Reorganize card resource handling Takashi Iwai
@ 2015-01-20  6:14   ` Chris Rorvick
  2015-01-20  7:11     ` Takashi Iwai
  0 siblings, 1 reply; 25+ messages in thread
From: Chris Rorvick @ 2015-01-20  6:14 UTC (permalink / raw)
  To: Takashi Iwai; +Cc: Stefan Hajnoczi, alsa-devel

On Mon, Jan 19, 2015 at 9:54 AM, Takashi Iwai <tiwai@suse.de> wrote:
> This is a fairly big rewrite regarding the card resource management in
> line6 drivers:
>
> - The card creation is moved into line6_probe().  This adds the global
>   destructor to private_free, so that each driver doesn't have to call
>   it any longer.
>
> - The USB disconnect callback handles the card release, thus each
>   driver needs to concentrate on only its own resources.  No need to
>   snd_card_*() call in the destructor.
>
> - Fix the potential stall in disconnection by removing
>   snd_card_free().   It's replaced with snd_card_free_when_closed()
>   for asynchronous release.
>
> - The only remaining operation for the card in each driver is the call
>   of snd_card_register().  All the rest are dealt in the common module
>   by itself.
>
> - These ended up with removal of audio.[ch] as a result of a reduction
>   of one layer.  Each driver just needs to call line6_probe().

Nice looking diff --stat.  :-)

Seems like this could be nicely split up into a few patches to make it
a bit easier to review.  I'd be happy to take a stab at that if you
thought it was worth it.  Otherwise, looks good to me.

Chris

^ permalink raw reply	[flat|nested] 25+ messages in thread

* Re: [PATCH 00/17] More line6 driver code reorg and cleanups
  2015-01-19 15:54 [PATCH 00/17] More line6 driver code reorg and cleanups Takashi Iwai
                   ` (16 preceding siblings ...)
  2015-01-19 15:54 ` [PATCH 17/17] ALSA: line6: Drop line6_send_program() and line6_transmit_parameter() Takashi Iwai
@ 2015-01-20  6:24 ` Chris Rorvick
  2015-01-20  7:19   ` Takashi Iwai
  17 siblings, 1 reply; 25+ messages in thread
From: Chris Rorvick @ 2015-01-20  6:24 UTC (permalink / raw)
  To: Takashi Iwai; +Cc: Stefan Hajnoczi, alsa-devel

On Mon, Jan 19, 2015 at 9:54 AM, Takashi Iwai <tiwai@suse.de> wrote:
> The current merged code is found in topic/line6 branch of sound.git
> tree while this development code is found in test/line6 branch.
> The devel branch hasn't been merged to linux-next yet, I'm waiting
> for any good/bad test results.  So, give me any feedback.  Thanks!

Looks good to me.  I tried it out briefly with a TonePort UX2 without
issue.

Tested-by: Chris Rorvick <chris@rorvick.com>

> (BTW, the next step would be to straighten the init code in pod.c,
>  etc instead of (ab)using the system timer.  Instead, it should be
>  a flat function with wait_event() of such.)

Are you planning on doing this?  Otherwise I can probably poke at it
this week.

Thanks!

Chris

^ permalink raw reply	[flat|nested] 25+ messages in thread

* Re: [PATCH 10/17] ALSA: line6: Reorganize card resource handling
  2015-01-20  6:14   ` Chris Rorvick
@ 2015-01-20  7:11     ` Takashi Iwai
  0 siblings, 0 replies; 25+ messages in thread
From: Takashi Iwai @ 2015-01-20  7:11 UTC (permalink / raw)
  To: Chris Rorvick; +Cc: Stefan Hajnoczi, alsa-devel

At Tue, 20 Jan 2015 00:14:08 -0600,
Chris Rorvick wrote:
> 
> On Mon, Jan 19, 2015 at 9:54 AM, Takashi Iwai <tiwai@suse.de> wrote:
> > This is a fairly big rewrite regarding the card resource management in
> > line6 drivers:
> >
> > - The card creation is moved into line6_probe().  This adds the global
> >   destructor to private_free, so that each driver doesn't have to call
> >   it any longer.
> >
> > - The USB disconnect callback handles the card release, thus each
> >   driver needs to concentrate on only its own resources.  No need to
> >   snd_card_*() call in the destructor.
> >
> > - Fix the potential stall in disconnection by removing
> >   snd_card_free().   It's replaced with snd_card_free_when_closed()
> >   for asynchronous release.
> >
> > - The only remaining operation for the card in each driver is the call
> >   of snd_card_register().  All the rest are dealt in the common module
> >   by itself.
> >
> > - These ended up with removal of audio.[ch] as a result of a reduction
> >   of one layer.  Each driver just needs to call line6_probe().
> 
> Nice looking diff --stat.  :-)
> 
> Seems like this could be nicely split up into a few patches to make it
> a bit easier to review.  I'd be happy to take a stab at that if you
> thought it was worth it.  Otherwise, looks good to me.

It's not trivial to split, unfortunately, because all the above are
related tightly together and the code has been already split to
individual drivers.

Despite the code reduction, what the patch is doing is fairly
straightforward if you know of the standard snd_card creation and
destruction procedure.


Takashi

^ permalink raw reply	[flat|nested] 25+ messages in thread

* Re: [PATCH 00/17] More line6 driver code reorg and cleanups
  2015-01-20  6:24 ` [PATCH 00/17] More line6 driver code reorg and cleanups Chris Rorvick
@ 2015-01-20  7:19   ` Takashi Iwai
  0 siblings, 0 replies; 25+ messages in thread
From: Takashi Iwai @ 2015-01-20  7:19 UTC (permalink / raw)
  To: Chris Rorvick; +Cc: Stefan Hajnoczi, alsa-devel

At Tue, 20 Jan 2015 00:24:24 -0600,
Chris Rorvick wrote:
> 
> On Mon, Jan 19, 2015 at 9:54 AM, Takashi Iwai <tiwai@suse.de> wrote:
> > The current merged code is found in topic/line6 branch of sound.git
> > tree while this development code is found in test/line6 branch.
> > The devel branch hasn't been merged to linux-next yet, I'm waiting
> > for any good/bad test results.  So, give me any feedback.  Thanks!
> 
> Looks good to me.  I tried it out briefly with a TonePort UX2 without
> issue.
> 
> Tested-by: Chris Rorvick <chris@rorvick.com>

Added your tag now.

> > (BTW, the next step would be to straighten the init code in pod.c,
> >  etc instead of (ab)using the system timer.  Instead, it should be
> >  a flat function with wait_event() of such.)
> 
> Are you planning on doing this?  Otherwise I can probably poke at it
> this week.

I'd like to leave to you since such a change is more sensitive wrt
timing and needs definitely the real hardware testing.


thanks,

Takashi

^ permalink raw reply	[flat|nested] 25+ messages in thread

end of thread, other threads:[~2015-01-20  7:19 UTC | newest]

Thread overview: 25+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2015-01-19 15:54 [PATCH 00/17] More line6 driver code reorg and cleanups Takashi Iwai
2015-01-19 15:54 ` [PATCH 01/17] ALSA: line6: Split to each driver Takashi Iwai
2015-01-19 18:00   ` Chris Rorvick
2015-01-19 19:37     ` Takashi Iwai
2015-01-20  5:59       ` Chris Rorvick
2015-01-19 15:54 ` [PATCH 02/17] ALSA: line6: Handle impulse response via control API Takashi Iwai
2015-01-19 15:54 ` [PATCH 03/17] ALSA: line6: Drop superfluous snd_device for PCM Takashi Iwai
2015-01-19 15:54 ` [PATCH 04/17] ALSA: line6: Drop superfluous snd_device for rawmidi Takashi Iwai
2015-01-19 15:54 ` [PATCH 05/17] ALSA: line6: Drop invalid SNDRV_PCM_INFO_RESUME flag Takashi Iwai
2015-01-19 15:54 ` [PATCH 06/17] ALSA: line6: Drop usb_device sysfs symlink Takashi Iwai
2015-01-19 15:54 ` [PATCH 07/17] ALSA: line6: Remove superfluous out-of-memory error messages Takashi Iwai
2015-01-19 15:54 ` [PATCH 08/17] ALSA: line6: Don't handle PCM trigger for other cards Takashi Iwai
2015-01-19 15:54 ` [PATCH 09/17] ALSA: line6: Drop superfluous irqsave/irqrestore in PCM trigger callback Takashi Iwai
2015-01-19 15:54 ` [PATCH 10/17] ALSA: line6: Reorganize card resource handling Takashi Iwai
2015-01-20  6:14   ` Chris Rorvick
2015-01-20  7:11     ` Takashi Iwai
2015-01-19 15:54 ` [PATCH 11/17] ALSA: line6: Remove driver version string Takashi Iwai
2015-01-19 15:54 ` [PATCH 12/17] ALSA: line6: Drop MISSING_CASE macro Takashi Iwai
2015-01-19 15:54 ` [PATCH 13/17] ALSA: line6: Remove CHECK_RETURN macro Takashi Iwai
2015-01-19 15:54 ` [PATCH 14/17] ALSA: line6: Remove superfluous disconnect call in suspend handler Takashi Iwai
2015-01-19 15:54 ` [PATCH 15/17] ALSA: line6: Sync PCM stop at disconnect Takashi Iwai
2015-01-19 15:54 ` [PATCH 16/17] ALSA: line6: Make line6_send_raw_message() static Takashi Iwai
2015-01-19 15:54 ` [PATCH 17/17] ALSA: line6: Drop line6_send_program() and line6_transmit_parameter() Takashi Iwai
2015-01-20  6:24 ` [PATCH 00/17] More line6 driver code reorg and cleanups Chris Rorvick
2015-01-20  7:19   ` Takashi Iwai

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.