diff options
Diffstat (limited to 'drivers/staging/line6')
29 files changed, 868 insertions, 3867 deletions
diff --git a/drivers/staging/line6/Kconfig b/drivers/staging/line6/Kconfig index 43120ff2ab7..4f1219b4c69 100644 --- a/drivers/staging/line6/Kconfig +++ b/drivers/staging/line6/Kconfig @@ -23,53 +23,6 @@ menuconfig LINE6_USB  if LINE6_USB -config LINE6_USB_DEBUG -	bool "print debug messages" -	default n -	help -	  Say Y here to write debug messages to the syslog. - -	  If unsure, say N. - -config LINE6_USB_DUMP_CTRL -	bool "dump control messages" -	default n -	help -	  Say Y here to write control messages sent to and received from -	  Line6 devices to the syslog. - -	  If unsure, say N. - -config LINE6_USB_DUMP_MIDI -	bool "dump MIDI messages" -	default n -	help -	  Say Y here to write MIDI messages sent to and received from -	  Line6 devices to the syslog. - -	  If unsure, say N. - -config LINE6_USB_DUMP_PCM -	bool "dump PCM data" -	default n -	help -	  Say Y here to write PCM data sent to and received from Line6 -	  devices to the syslog. This will produce a huge amount of -	  syslog data during playback and capture. - -	  If unsure, say N. - -config LINE6_USB_RAW -	bool "raw data communication" -	default n -	help -	  Say Y here to create special files which allow to send raw data -	  to the device. This bypasses any sanity checks, so if you discover -	  the code to erase the firmware, feel free to render your device -	  useless, but only after reading the GPL section "NO WARRANTY". - -	  If unsure, say N. -  config LINE6_USB_IMPULSE_RESPONSE  	bool "measure impulse response"  	default n diff --git a/drivers/staging/line6/Makefile b/drivers/staging/line6/Makefile index de6bd12e973..ae5c374b0f8 100644 --- a/drivers/staging/line6/Makefile +++ b/drivers/staging/line6/Makefile @@ -3,13 +3,12 @@ obj-$(CONFIG_LINE6_USB)		+= line6usb.o  line6usb-y := 		\  		audio.o		\  		capture.o	\ -		control.o	\  		driver.o	\ -		dumprequest.o	\  		midi.o		\  		midibuf.o	\  		pcm.o		\  		playback.o	\  		pod.o		\  		toneport.o	\ -		variax.o +		variax.o	\ +		podhd.o diff --git a/drivers/staging/line6/audio.c b/drivers/staging/line6/audio.c index 61db1f99b0c..171d80c1b02 100644 --- a/drivers/staging/line6/audio.c +++ b/drivers/staging/line6/audio.c @@ -11,24 +11,22 @@  #include <sound/core.h>  #include <sound/initval.h> +#include <linux/export.h>  #include "driver.h"  #include "audio.h" -static int line6_index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX; -static char *line6_id[SNDRV_CARDS] = SNDRV_DEFAULT_STR; -  /*  	Initialize the Line6 USB audio system.  */  int line6_init_audio(struct usb_line6 *line6)  { -	static int dev;  	struct snd_card *card;  	int err; -	err = snd_card_create(line6_index[dev], line6_id[dev], THIS_MODULE, 0, -			      &card); +	err = snd_card_new(line6->ifcdev, +			   SNDRV_DEFAULT_IDX1, SNDRV_DEFAULT_STR1, +			   THIS_MODULE, 0, &card);  	if (err < 0)  		return err; diff --git a/drivers/staging/line6/capture.c b/drivers/staging/line6/capture.c index 1e3bb140633..e6ca631e3f7 100644 --- a/drivers/staging/line6/capture.c +++ b/drivers/staging/line6/capture.c @@ -9,6 +9,7 @@   *   */ +#include <linux/slab.h>  #include <sound/core.h>  #include <sound/pcm.h>  #include <sound/pcm_params.h> @@ -96,6 +97,7 @@ void line6_unlink_audio_in_urbs(struct snd_line6_pcm *line6pcm)  		if (test_bit(i, &line6pcm->active_urb_in)) {  			if (!test_and_set_bit(i, &line6pcm->unlink_urb_in)) {  				struct urb *u = line6pcm->urb_audio_in[i]; +  				usb_unlink_urb(u);  			}  		} @@ -106,7 +108,7 @@ void line6_unlink_audio_in_urbs(struct snd_line6_pcm *line6pcm)  	Wait until unlinking of all currently active capture URBs has been  	finished.  */ -static void wait_clear_audio_in_urbs(struct snd_line6_pcm *line6pcm) +void line6_wait_clear_audio_in_urbs(struct snd_line6_pcm *line6pcm)  {  	int timeout = HZ;  	unsigned int i; @@ -133,7 +135,7 @@ static void wait_clear_audio_in_urbs(struct snd_line6_pcm *line6pcm)  void line6_unlink_wait_clear_audio_in_urbs(struct snd_line6_pcm *line6pcm)  {  	line6_unlink_audio_in_urbs(line6pcm); -	wait_clear_audio_in_urbs(line6pcm); +	line6_wait_clear_audio_in_urbs(line6pcm);  }  /* @@ -147,7 +149,7 @@ void line6_capture_copy(struct snd_line6_pcm *line6pcm, char *fbuf, int fsize)  	const int bytes_per_frame = line6pcm->properties->bytes_per_frame;  	int frames = fsize / bytes_per_frame; -	if (runtime == 0) +	if (runtime == NULL)  		return;  	if (line6pcm->pos_in_done + frames > runtime->buffer_size) { @@ -156,6 +158,7 @@ void line6_capture_copy(struct snd_line6_pcm *line6pcm, char *fbuf, int fsize)  		   copy two separate chunks.  		 */  		int len; +  		len = runtime->buffer_size - line6pcm->pos_in_done;  		if (len > 0) { @@ -192,6 +195,12 @@ void line6_capture_check_period(struct snd_line6_pcm *line6pcm, int length)  	}  } +void line6_free_capture_buffer(struct snd_line6_pcm *line6pcm) +{ +	kfree(line6pcm->buffer_in); +	line6pcm->buffer_in = NULL; +} +  /*   * Callback for completed capture URB.   */ @@ -209,16 +218,6 @@ static void audio_in_callback(struct urb *urb)  		if (urb == line6pcm->urb_audio_in[index])  			break; -#ifdef CONFIG_LINE6_USB_DUMP_PCM -	for (i = 0; i < LINE6_ISO_PACKETS; ++i) { -		struct usb_iso_packet_descriptor *fout = -		    &urb->iso_frame_desc[i]; -		line6_write_hexdump(line6pcm->line6, 'C', -				    urb->transfer_buffer + fout->offset, -				    fout->length); -	} -#endif -  	spin_lock_irqsave(&line6pcm->lock_audio_in, flags);  	for (i = 0; i < LINE6_ISO_PACKETS; ++i) { @@ -243,18 +242,14 @@ static void audio_in_callback(struct urb *urb)  		length += fsize;  		/* the following assumes LINE6_ISO_PACKETS == 1: */ -#if LINE6_BACKUP_MONITOR_SIGNAL -		memcpy(line6pcm->prev_fbuf, fbuf, fsize); -#else  		line6pcm->prev_fbuf = fbuf; -#endif  		line6pcm->prev_fsize = fsize;  #ifdef CONFIG_LINE6_USB_IMPULSE_RESPONSE -		if (!(line6pcm->flags & MASK_PCM_IMPULSE)) +		if (!(line6pcm->flags & LINE6_BITS_PCM_IMPULSE))  #endif -			if (test_bit(BIT_PCM_ALSA_CAPTURE, &line6pcm->flags) -			    && (fsize > 0)) +			if (test_bit(LINE6_INDEX_PCM_ALSA_CAPTURE_STREAM, +				     &line6pcm->flags) && (fsize > 0))  				line6_capture_copy(line6pcm, fbuf, fsize);  	} @@ -269,9 +264,10 @@ static void audio_in_callback(struct urb *urb)  		submit_audio_in_urb(line6pcm);  #ifdef CONFIG_LINE6_USB_IMPULSE_RESPONSE -		if (!(line6pcm->flags & MASK_PCM_IMPULSE)) +		if (!(line6pcm->flags & LINE6_BITS_PCM_IMPULSE))  #endif -			if (test_bit(BIT_PCM_ALSA_CAPTURE, &line6pcm->flags)) +			if (test_bit(LINE6_INDEX_PCM_ALSA_CAPTURE_STREAM, +				     &line6pcm->flags))  				line6_capture_check_period(line6pcm, length);  	}  } @@ -319,10 +315,17 @@ static int snd_line6_capture_hw_params(struct snd_pcm_substream *substream,  	}  	/* -- [FD] end */ +	ret = line6_pcm_acquire(line6pcm, LINE6_BIT_PCM_ALSA_CAPTURE_BUFFER); + +	if (ret < 0) +		return ret; +  	ret = snd_pcm_lib_malloc_pages(substream,  				       params_buffer_bytes(hw_params)); -	if (ret < 0) +	if (ret < 0) { +		line6_pcm_release(line6pcm, LINE6_BIT_PCM_ALSA_CAPTURE_BUFFER);  		return ret; +	}  	line6pcm->period_in = params_period_bytes(hw_params);  	return 0; @@ -331,6 +334,9 @@ static int snd_line6_capture_hw_params(struct snd_pcm_substream *substream,  /* hw_free capture callback */  static int snd_line6_capture_hw_free(struct snd_pcm_substream *substream)  { +	struct snd_line6_pcm *line6pcm = snd_pcm_substream_chip(substream); + +	line6_pcm_release(line6pcm, LINE6_BIT_PCM_ALSA_CAPTURE_BUFFER);  	return snd_pcm_lib_free_pages(substream);  } @@ -344,7 +350,8 @@ int snd_line6_capture_trigger(struct snd_line6_pcm *line6pcm, int cmd)  #ifdef CONFIG_PM  	case SNDRV_PCM_TRIGGER_RESUME:  #endif -		err = line6_pcm_start(line6pcm, MASK_PCM_ALSA_CAPTURE); +		err = line6_pcm_acquire(line6pcm, +					LINE6_BIT_PCM_ALSA_CAPTURE_STREAM);  		if (err < 0)  			return err; @@ -355,7 +362,8 @@ int snd_line6_capture_trigger(struct snd_line6_pcm *line6pcm, int cmd)  #ifdef CONFIG_PM  	case SNDRV_PCM_TRIGGER_SUSPEND:  #endif -		err = line6_pcm_stop(line6pcm, MASK_PCM_ALSA_CAPTURE); +		err = line6_pcm_release(line6pcm, +					LINE6_BIT_PCM_ALSA_CAPTURE_STREAM);  		if (err < 0)  			return err; @@ -374,6 +382,7 @@ static snd_pcm_uframes_t  snd_line6_capture_pointer(struct snd_pcm_substream *substream)  {  	struct snd_line6_pcm *line6pcm = snd_pcm_substream_chip(substream); +  	return line6pcm->pos_in_done;  } diff --git a/drivers/staging/line6/capture.h b/drivers/staging/line6/capture.h index a7509fbbb95..4157bcb598a 100644 --- a/drivers/staging/line6/capture.h +++ b/drivers/staging/line6/capture.h @@ -24,10 +24,12 @@ extern void line6_capture_copy(struct snd_line6_pcm *line6pcm, char *fbuf,  extern void line6_capture_check_period(struct snd_line6_pcm *line6pcm,  				       int length);  extern int line6_create_audio_in_urbs(struct snd_line6_pcm *line6pcm); +extern void line6_free_capture_buffer(struct snd_line6_pcm *line6pcm);  extern int line6_submit_audio_in_all_urbs(struct snd_line6_pcm *line6pcm);  extern void line6_unlink_audio_in_urbs(struct snd_line6_pcm *line6pcm);  extern void line6_unlink_wait_clear_audio_in_urbs(struct snd_line6_pcm  						  *line6pcm); +extern void line6_wait_clear_audio_in_urbs(struct snd_line6_pcm *line6pcm);  extern int snd_line6_capture_trigger(struct snd_line6_pcm *line6pcm, int cmd);  #endif diff --git a/drivers/staging/line6/config.h b/drivers/staging/line6/config.h deleted file mode 100644 index f8a5149e3da..00000000000 --- a/drivers/staging/line6/config.h +++ /dev/null @@ -1,48 +0,0 @@ -/* - * Line6 Linux USB driver - 0.8.0 - * - * Copyright (C) 2004-2009 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 CONFIG_H -#define CONFIG_H - - -#ifdef CONFIG_USB_DEBUG -#define DEBUG 1 -#endif - - -/* - * Development tools. - */ -#define DO_DEBUG_MESSAGES    0 -#define DO_DUMP_URB_SEND     DO_DEBUG_MESSAGES -#define DO_DUMP_URB_RECEIVE  DO_DEBUG_MESSAGES -#define DO_DUMP_PCM_SEND     0 -#define DO_DUMP_PCM_RECEIVE  0 -#define DO_DUMP_MIDI_SEND    DO_DEBUG_MESSAGES -#define DO_DUMP_MIDI_RECEIVE DO_DEBUG_MESSAGES -#define DO_DUMP_ANY          (DO_DUMP_URB_SEND || DO_DUMP_URB_RECEIVE || \ -			      DO_DUMP_PCM_SEND || DO_DUMP_PCM_RECEIVE || \ -			      DO_DUMP_MIDI_SEND || DO_DUMP_MIDI_RECEIVE) -#define CREATE_RAW_FILE      0 - -#if DO_DEBUG_MESSAGES -#define CHECKPOINT printk(KERN_INFO "line6usb: %s (%s:%d)\n", \ -			  __func__, __FILE__, __LINE__) -#endif - -#if DO_DEBUG_MESSAGES -#define DEBUG_MESSAGES(x) (x) -#else -#define DEBUG_MESSAGES(x) -#endif - - -#endif diff --git a/drivers/staging/line6/control.c b/drivers/staging/line6/control.c deleted file mode 100644 index 040e25ca6d3..00000000000 --- a/drivers/staging/line6/control.c +++ /dev/null @@ -1,995 +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 <linux/usb.h> - -#include "control.h" -#include "driver.h" -#include "pod.h" -#include "usbdefs.h" -#include "variax.h" - -#define DEVICE_ATTR2(_name1, _name2, _mode, _show, _store) \ -struct device_attribute dev_attr_##_name1 = __ATTR(_name2, _mode, _show, _store) - -#define LINE6_PARAM_R(PREFIX, prefix, type, param) \ -static ssize_t prefix##_get_##param(struct device *dev, \ -			struct device_attribute *attr, char *buf) \ -{ \ -	return prefix##_get_param_##type(dev, buf, PREFIX##_##param); \ -} - -#define LINE6_PARAM_RW(PREFIX, prefix, type, param) \ -LINE6_PARAM_R(PREFIX, prefix, type, param); \ -static ssize_t prefix##_set_##param(struct device *dev, \ -		struct device_attribute *attr, const char *buf, size_t count) \ -{ \ -	return prefix##_set_param_##type(dev, buf, count, PREFIX##_##param); \ -} - -#define POD_PARAM_R(type, param) LINE6_PARAM_R(POD, pod, type, param) -#define POD_PARAM_RW(type, param) LINE6_PARAM_RW(POD, pod, type, param) -#define VARIAX_PARAM_R(type, param) LINE6_PARAM_R(VARIAX, variax, type, param) -#define VARIAX_PARAM_RW(type, param) LINE6_PARAM_RW(VARIAX, variax, type, param) - -static ssize_t pod_get_param_int(struct device *dev, char *buf, int param) -{ -	struct usb_interface *interface = to_usb_interface(dev); -	struct usb_line6_pod *pod = usb_get_intfdata(interface); -	int retval = line6_dump_wait_interruptible(&pod->dumpreq); -	if (retval < 0) -		return retval; -	return sprintf(buf, "%d\n", pod->prog_data.control[param]); -} - -static ssize_t pod_set_param_int(struct device *dev, const char *buf, -				 size_t count, int param) -{ -	struct usb_interface *interface = to_usb_interface(dev); -	struct usb_line6_pod *pod = usb_get_intfdata(interface); -	unsigned long value; -	int retval; - -	retval = strict_strtoul(buf, 10, &value); -	if (retval) -		return retval; - -	line6_pod_transmit_parameter(pod, param, value); -	return count; -} - -static ssize_t variax_get_param_int(struct device *dev, char *buf, int param) -{ -	struct usb_interface *interface = to_usb_interface(dev); -	struct usb_line6_variax *variax = usb_get_intfdata(interface); -	int retval = line6_dump_wait_interruptible(&variax->dumpreq); -	if (retval < 0) -		return retval; -	return sprintf(buf, "%d\n", variax->model_data.control[param]); -} - -static ssize_t variax_get_param_float(struct device *dev, char *buf, int param) -{ -	/* -	   We do our own floating point handling here since at the time -	   this code was written (Jan 2006) it was highly discouraged to -	   use floating point arithmetic in the kernel. If you think that -	   this no longer applies, feel free to replace this by generic -	   floating point code. -	 */ - -	static const int BIAS = 0x7f; -	static const int OFFSET = 0xf; -	static const int PRECISION = 1000; - -	int len = 0; -	unsigned part_int, part_frac; -	struct usb_interface *interface = to_usb_interface(dev); -	struct usb_line6_variax *variax = usb_get_intfdata(interface); -	const unsigned char *p = variax->model_data.control + param; -	int retval = line6_dump_wait_interruptible(&variax->dumpreq); -	if (retval < 0) -		return retval; - -	if ((p[0] == 0) && (p[1] == 0) && (p[2] == 0)) -		part_int = part_frac = 0; -	else { -		int exponent = (((p[0] & 0x7f) << 1) | (p[1] >> 7)) - BIAS; -		unsigned mantissa = (p[1] << 8) | p[2] | 0x8000; -		exponent -= OFFSET; - -		if (exponent >= 0) { -			part_int = mantissa << exponent; -			part_frac = 0; -		} else { -			part_int = mantissa >> -exponent; -			part_frac = (mantissa << (32 + exponent)) & 0xffffffff; -		} - -		part_frac = -		    (part_frac / ((1UL << 31) / (PRECISION / 2 * 10)) + 5) / 10; -	} - -	len += -	    sprintf(buf + len, "%s%d.%03d\n", ((p[0] & 0x80) ? "-" : ""), -		    part_int, part_frac); -	return len; -} - -POD_PARAM_RW(int, tweak); -POD_PARAM_RW(int, wah_position); -POD_PARAM_RW(int, compression_gain); -POD_PARAM_RW(int, vol_pedal_position); -POD_PARAM_RW(int, compression_threshold); -POD_PARAM_RW(int, pan); -POD_PARAM_RW(int, amp_model_setup); -POD_PARAM_RW(int, amp_model); -POD_PARAM_RW(int, drive); -POD_PARAM_RW(int, bass); -POD_PARAM_RW(int, mid); -POD_PARAM_RW(int, lowmid); -POD_PARAM_RW(int, treble); -POD_PARAM_RW(int, highmid); -POD_PARAM_RW(int, chan_vol); -POD_PARAM_RW(int, reverb_mix); -POD_PARAM_RW(int, effect_setup); -POD_PARAM_RW(int, band_1_frequency); -POD_PARAM_RW(int, presence); -POD_PARAM_RW(int, treble__bass); -POD_PARAM_RW(int, noise_gate_enable); -POD_PARAM_RW(int, gate_threshold); -POD_PARAM_RW(int, gate_decay_time); -POD_PARAM_RW(int, stomp_enable); -POD_PARAM_RW(int, comp_enable); -POD_PARAM_RW(int, stomp_time); -POD_PARAM_RW(int, delay_enable); -POD_PARAM_RW(int, mod_param_1); -POD_PARAM_RW(int, delay_param_1); -POD_PARAM_RW(int, delay_param_1_note_value); -POD_PARAM_RW(int, band_2_frequency__bass); -POD_PARAM_RW(int, delay_param_2); -POD_PARAM_RW(int, delay_volume_mix); -POD_PARAM_RW(int, delay_param_3); -POD_PARAM_RW(int, reverb_enable); -POD_PARAM_RW(int, reverb_type); -POD_PARAM_RW(int, reverb_decay); -POD_PARAM_RW(int, reverb_tone); -POD_PARAM_RW(int, reverb_pre_delay); -POD_PARAM_RW(int, reverb_pre_post); -POD_PARAM_RW(int, band_2_frequency); -POD_PARAM_RW(int, band_3_frequency__bass); -POD_PARAM_RW(int, wah_enable); -POD_PARAM_RW(int, modulation_lo_cut); -POD_PARAM_RW(int, delay_reverb_lo_cut); -POD_PARAM_RW(int, volume_pedal_minimum); -POD_PARAM_RW(int, eq_pre_post); -POD_PARAM_RW(int, volume_pre_post); -POD_PARAM_RW(int, di_model); -POD_PARAM_RW(int, di_delay); -POD_PARAM_RW(int, mod_enable); -POD_PARAM_RW(int, mod_param_1_note_value); -POD_PARAM_RW(int, mod_param_2); -POD_PARAM_RW(int, mod_param_3); -POD_PARAM_RW(int, mod_param_4); -POD_PARAM_RW(int, mod_param_5); -POD_PARAM_RW(int, mod_volume_mix); -POD_PARAM_RW(int, mod_pre_post); -POD_PARAM_RW(int, modulation_model); -POD_PARAM_RW(int, band_3_frequency); -POD_PARAM_RW(int, band_4_frequency__bass); -POD_PARAM_RW(int, mod_param_1_double_precision); -POD_PARAM_RW(int, delay_param_1_double_precision); -POD_PARAM_RW(int, eq_enable); -POD_PARAM_RW(int, tap); -POD_PARAM_RW(int, volume_tweak_pedal_assign); -POD_PARAM_RW(int, band_5_frequency); -POD_PARAM_RW(int, tuner); -POD_PARAM_RW(int, mic_selection); -POD_PARAM_RW(int, cabinet_model); -POD_PARAM_RW(int, stomp_model); -POD_PARAM_RW(int, roomlevel); -POD_PARAM_RW(int, band_4_frequency); -POD_PARAM_RW(int, band_6_frequency); -POD_PARAM_RW(int, stomp_param_1_note_value); -POD_PARAM_RW(int, stomp_param_2); -POD_PARAM_RW(int, stomp_param_3); -POD_PARAM_RW(int, stomp_param_4); -POD_PARAM_RW(int, stomp_param_5); -POD_PARAM_RW(int, stomp_param_6); -POD_PARAM_RW(int, amp_switch_select); -POD_PARAM_RW(int, delay_param_4); -POD_PARAM_RW(int, delay_param_5); -POD_PARAM_RW(int, delay_pre_post); -POD_PARAM_RW(int, delay_model); -POD_PARAM_RW(int, delay_verb_model); -POD_PARAM_RW(int, tempo_msb); -POD_PARAM_RW(int, tempo_lsb); -POD_PARAM_RW(int, wah_model); -POD_PARAM_RW(int, bypass_volume); -POD_PARAM_RW(int, fx_loop_on_off); -POD_PARAM_RW(int, tweak_param_select); -POD_PARAM_RW(int, amp1_engage); -POD_PARAM_RW(int, band_1_gain); -POD_PARAM_RW(int, band_2_gain__bass); -POD_PARAM_RW(int, band_2_gain); -POD_PARAM_RW(int, band_3_gain__bass); -POD_PARAM_RW(int, band_3_gain); -POD_PARAM_RW(int, band_4_gain__bass); -POD_PARAM_RW(int, band_5_gain__bass); -POD_PARAM_RW(int, band_4_gain); -POD_PARAM_RW(int, band_6_gain__bass); -VARIAX_PARAM_R(int, body); -VARIAX_PARAM_R(int, pickup1_enable); -VARIAX_PARAM_R(int, pickup1_type); -VARIAX_PARAM_R(float, pickup1_position); -VARIAX_PARAM_R(float, pickup1_angle); -VARIAX_PARAM_R(float, pickup1_level); -VARIAX_PARAM_R(int, pickup2_enable); -VARIAX_PARAM_R(int, pickup2_type); -VARIAX_PARAM_R(float, pickup2_position); -VARIAX_PARAM_R(float, pickup2_angle); -VARIAX_PARAM_R(float, pickup2_level); -VARIAX_PARAM_R(int, pickup_phase); -VARIAX_PARAM_R(float, capacitance); -VARIAX_PARAM_R(float, tone_resistance); -VARIAX_PARAM_R(float, volume_resistance); -VARIAX_PARAM_R(int, taper); -VARIAX_PARAM_R(float, tone_dump); -VARIAX_PARAM_R(int, save_tone); -VARIAX_PARAM_R(float, volume_dump); -VARIAX_PARAM_R(int, tuning_enable); -VARIAX_PARAM_R(int, tuning6); -VARIAX_PARAM_R(int, tuning5); -VARIAX_PARAM_R(int, tuning4); -VARIAX_PARAM_R(int, tuning3); -VARIAX_PARAM_R(int, tuning2); -VARIAX_PARAM_R(int, tuning1); -VARIAX_PARAM_R(float, detune6); -VARIAX_PARAM_R(float, detune5); -VARIAX_PARAM_R(float, detune4); -VARIAX_PARAM_R(float, detune3); -VARIAX_PARAM_R(float, detune2); -VARIAX_PARAM_R(float, detune1); -VARIAX_PARAM_R(float, mix6); -VARIAX_PARAM_R(float, mix5); -VARIAX_PARAM_R(float, mix4); -VARIAX_PARAM_R(float, mix3); -VARIAX_PARAM_R(float, mix2); -VARIAX_PARAM_R(float, mix1); -VARIAX_PARAM_R(int, pickup_wiring); - -static DEVICE_ATTR(tweak, S_IWUGO | S_IRUGO, pod_get_tweak, pod_set_tweak); -static DEVICE_ATTR(wah_position, S_IWUGO | S_IRUGO, pod_get_wah_position, -		   pod_set_wah_position); -static DEVICE_ATTR(compression_gain, S_IWUGO | S_IRUGO, -		   pod_get_compression_gain, pod_set_compression_gain); -static DEVICE_ATTR(vol_pedal_position, S_IWUGO | S_IRUGO, -		   pod_get_vol_pedal_position, pod_set_vol_pedal_position); -static DEVICE_ATTR(compression_threshold, S_IWUGO | S_IRUGO, -		   pod_get_compression_threshold, -		   pod_set_compression_threshold); -static DEVICE_ATTR(pan, S_IWUGO | S_IRUGO, pod_get_pan, pod_set_pan); -static DEVICE_ATTR(amp_model_setup, S_IWUGO | S_IRUGO, pod_get_amp_model_setup, -		   pod_set_amp_model_setup); -static DEVICE_ATTR(amp_model, S_IWUGO | S_IRUGO, pod_get_amp_model, -		   pod_set_amp_model); -static DEVICE_ATTR(drive, S_IWUGO | S_IRUGO, pod_get_drive, pod_set_drive); -static DEVICE_ATTR(bass, S_IWUGO | S_IRUGO, pod_get_bass, pod_set_bass); -static DEVICE_ATTR(mid, S_IWUGO | S_IRUGO, pod_get_mid, pod_set_mid); -static DEVICE_ATTR(lowmid, S_IWUGO | S_IRUGO, pod_get_lowmid, pod_set_lowmid); -static DEVICE_ATTR(treble, S_IWUGO | S_IRUGO, pod_get_treble, pod_set_treble); -static DEVICE_ATTR(highmid, S_IWUGO | S_IRUGO, pod_get_highmid, -		   pod_set_highmid); -static DEVICE_ATTR(chan_vol, S_IWUGO | S_IRUGO, pod_get_chan_vol, -		   pod_set_chan_vol); -static DEVICE_ATTR(reverb_mix, S_IWUGO | S_IRUGO, pod_get_reverb_mix, -		   pod_set_reverb_mix); -static DEVICE_ATTR(effect_setup, S_IWUGO | S_IRUGO, pod_get_effect_setup, -		   pod_set_effect_setup); -static DEVICE_ATTR(band_1_frequency, S_IWUGO | S_IRUGO, -		   pod_get_band_1_frequency, pod_set_band_1_frequency); -static DEVICE_ATTR(presence, S_IWUGO | S_IRUGO, pod_get_presence, -		   pod_set_presence); -static DEVICE_ATTR2(treble__bass, treble, S_IWUGO | S_IRUGO, -		    pod_get_treble__bass, pod_set_treble__bass); -static DEVICE_ATTR(noise_gate_enable, S_IWUGO | S_IRUGO, -		   pod_get_noise_gate_enable, pod_set_noise_gate_enable); -static DEVICE_ATTR(gate_threshold, S_IWUGO | S_IRUGO, pod_get_gate_threshold, -		   pod_set_gate_threshold); -static DEVICE_ATTR(gate_decay_time, S_IWUGO | S_IRUGO, pod_get_gate_decay_time, -		   pod_set_gate_decay_time); -static DEVICE_ATTR(stomp_enable, S_IWUGO | S_IRUGO, pod_get_stomp_enable, -		   pod_set_stomp_enable); -static DEVICE_ATTR(comp_enable, S_IWUGO | S_IRUGO, pod_get_comp_enable, -		   pod_set_comp_enable); -static DEVICE_ATTR(stomp_time, S_IWUGO | S_IRUGO, pod_get_stomp_time, -		   pod_set_stomp_time); -static DEVICE_ATTR(delay_enable, S_IWUGO | S_IRUGO, pod_get_delay_enable, -		   pod_set_delay_enable); -static DEVICE_ATTR(mod_param_1, S_IWUGO | S_IRUGO, pod_get_mod_param_1, -		   pod_set_mod_param_1); -static DEVICE_ATTR(delay_param_1, S_IWUGO | S_IRUGO, pod_get_delay_param_1, -		   pod_set_delay_param_1); -static DEVICE_ATTR(delay_param_1_note_value, S_IWUGO | S_IRUGO, -		   pod_get_delay_param_1_note_value, -		   pod_set_delay_param_1_note_value); -static DEVICE_ATTR2(band_2_frequency__bass, band_2_frequency, S_IWUGO | S_IRUGO, -		    pod_get_band_2_frequency__bass, -		    pod_set_band_2_frequency__bass); -static DEVICE_ATTR(delay_param_2, S_IWUGO | S_IRUGO, pod_get_delay_param_2, -		   pod_set_delay_param_2); -static DEVICE_ATTR(delay_volume_mix, S_IWUGO | S_IRUGO, -		   pod_get_delay_volume_mix, pod_set_delay_volume_mix); -static DEVICE_ATTR(delay_param_3, S_IWUGO | S_IRUGO, pod_get_delay_param_3, -		   pod_set_delay_param_3); -static DEVICE_ATTR(reverb_enable, S_IWUGO | S_IRUGO, pod_get_reverb_enable, -		   pod_set_reverb_enable); -static DEVICE_ATTR(reverb_type, S_IWUGO | S_IRUGO, pod_get_reverb_type, -		   pod_set_reverb_type); -static DEVICE_ATTR(reverb_decay, S_IWUGO | S_IRUGO, pod_get_reverb_decay, -		   pod_set_reverb_decay); -static DEVICE_ATTR(reverb_tone, S_IWUGO | S_IRUGO, pod_get_reverb_tone, -		   pod_set_reverb_tone); -static DEVICE_ATTR(reverb_pre_delay, S_IWUGO | S_IRUGO, -		   pod_get_reverb_pre_delay, pod_set_reverb_pre_delay); -static DEVICE_ATTR(reverb_pre_post, S_IWUGO | S_IRUGO, pod_get_reverb_pre_post, -		   pod_set_reverb_pre_post); -static DEVICE_ATTR(band_2_frequency, S_IWUGO | S_IRUGO, -		   pod_get_band_2_frequency, pod_set_band_2_frequency); -static DEVICE_ATTR2(band_3_frequency__bass, band_3_frequency, S_IWUGO | S_IRUGO, -		    pod_get_band_3_frequency__bass, -		    pod_set_band_3_frequency__bass); -static DEVICE_ATTR(wah_enable, S_IWUGO | S_IRUGO, pod_get_wah_enable, -		   pod_set_wah_enable); -static DEVICE_ATTR(modulation_lo_cut, S_IWUGO | S_IRUGO, -		   pod_get_modulation_lo_cut, pod_set_modulation_lo_cut); -static DEVICE_ATTR(delay_reverb_lo_cut, S_IWUGO | S_IRUGO, -		   pod_get_delay_reverb_lo_cut, pod_set_delay_reverb_lo_cut); -static DEVICE_ATTR(volume_pedal_minimum, S_IWUGO | S_IRUGO, -		   pod_get_volume_pedal_minimum, pod_set_volume_pedal_minimum); -static DEVICE_ATTR(eq_pre_post, S_IWUGO | S_IRUGO, pod_get_eq_pre_post, -		   pod_set_eq_pre_post); -static DEVICE_ATTR(volume_pre_post, S_IWUGO | S_IRUGO, pod_get_volume_pre_post, -		   pod_set_volume_pre_post); -static DEVICE_ATTR(di_model, S_IWUGO | S_IRUGO, pod_get_di_model, -		   pod_set_di_model); -static DEVICE_ATTR(di_delay, S_IWUGO | S_IRUGO, pod_get_di_delay, -		   pod_set_di_delay); -static DEVICE_ATTR(mod_enable, S_IWUGO | S_IRUGO, pod_get_mod_enable, -		   pod_set_mod_enable); -static DEVICE_ATTR(mod_param_1_note_value, S_IWUGO | S_IRUGO, -		   pod_get_mod_param_1_note_value, -		   pod_set_mod_param_1_note_value); -static DEVICE_ATTR(mod_param_2, S_IWUGO | S_IRUGO, pod_get_mod_param_2, -		   pod_set_mod_param_2); -static DEVICE_ATTR(mod_param_3, S_IWUGO | S_IRUGO, pod_get_mod_param_3, -		   pod_set_mod_param_3); -static DEVICE_ATTR(mod_param_4, S_IWUGO | S_IRUGO, pod_get_mod_param_4, -		   pod_set_mod_param_4); -static DEVICE_ATTR(mod_param_5, S_IWUGO | S_IRUGO, pod_get_mod_param_5, -		   pod_set_mod_param_5); -static DEVICE_ATTR(mod_volume_mix, S_IWUGO | S_IRUGO, pod_get_mod_volume_mix, -		   pod_set_mod_volume_mix); -static DEVICE_ATTR(mod_pre_post, S_IWUGO | S_IRUGO, pod_get_mod_pre_post, -		   pod_set_mod_pre_post); -static DEVICE_ATTR(modulation_model, S_IWUGO | S_IRUGO, -		   pod_get_modulation_model, pod_set_modulation_model); -static DEVICE_ATTR(band_3_frequency, S_IWUGO | S_IRUGO, -		   pod_get_band_3_frequency, pod_set_band_3_frequency); -static DEVICE_ATTR2(band_4_frequency__bass, band_4_frequency, S_IWUGO | S_IRUGO, -		    pod_get_band_4_frequency__bass, -		    pod_set_band_4_frequency__bass); -static DEVICE_ATTR(mod_param_1_double_precision, S_IWUGO | S_IRUGO, -		   pod_get_mod_param_1_double_precision, -		   pod_set_mod_param_1_double_precision); -static DEVICE_ATTR(delay_param_1_double_precision, S_IWUGO | S_IRUGO, -		   pod_get_delay_param_1_double_precision, -		   pod_set_delay_param_1_double_precision); -static DEVICE_ATTR(eq_enable, S_IWUGO | S_IRUGO, pod_get_eq_enable, -		   pod_set_eq_enable); -static DEVICE_ATTR(tap, S_IWUGO | S_IRUGO, pod_get_tap, pod_set_tap); -static DEVICE_ATTR(volume_tweak_pedal_assign, S_IWUGO | S_IRUGO, -		   pod_get_volume_tweak_pedal_assign, -		   pod_set_volume_tweak_pedal_assign); -static DEVICE_ATTR(band_5_frequency, S_IWUGO | S_IRUGO, -		   pod_get_band_5_frequency, pod_set_band_5_frequency); -static DEVICE_ATTR(tuner, S_IWUGO | S_IRUGO, pod_get_tuner, pod_set_tuner); -static DEVICE_ATTR(mic_selection, S_IWUGO | S_IRUGO, pod_get_mic_selection, -		   pod_set_mic_selection); -static DEVICE_ATTR(cabinet_model, S_IWUGO | S_IRUGO, pod_get_cabinet_model, -		   pod_set_cabinet_model); -static DEVICE_ATTR(stomp_model, S_IWUGO | S_IRUGO, pod_get_stomp_model, -		   pod_set_stomp_model); -static DEVICE_ATTR(roomlevel, S_IWUGO | S_IRUGO, pod_get_roomlevel, -		   pod_set_roomlevel); -static DEVICE_ATTR(band_4_frequency, S_IWUGO | S_IRUGO, -		   pod_get_band_4_frequency, pod_set_band_4_frequency); -static DEVICE_ATTR(band_6_frequency, S_IWUGO | S_IRUGO, -		   pod_get_band_6_frequency, pod_set_band_6_frequency); -static DEVICE_ATTR(stomp_param_1_note_value, S_IWUGO | S_IRUGO, -		   pod_get_stomp_param_1_note_value, -		   pod_set_stomp_param_1_note_value); -static DEVICE_ATTR(stomp_param_2, S_IWUGO | S_IRUGO, pod_get_stomp_param_2, -		   pod_set_stomp_param_2); -static DEVICE_ATTR(stomp_param_3, S_IWUGO | S_IRUGO, pod_get_stomp_param_3, -		   pod_set_stomp_param_3); -static DEVICE_ATTR(stomp_param_4, S_IWUGO | S_IRUGO, pod_get_stomp_param_4, -		   pod_set_stomp_param_4); -static DEVICE_ATTR(stomp_param_5, S_IWUGO | S_IRUGO, pod_get_stomp_param_5, -		   pod_set_stomp_param_5); -static DEVICE_ATTR(stomp_param_6, S_IWUGO | S_IRUGO, pod_get_stomp_param_6, -		   pod_set_stomp_param_6); -static DEVICE_ATTR(amp_switch_select, S_IWUGO | S_IRUGO, -		   pod_get_amp_switch_select, pod_set_amp_switch_select); -static DEVICE_ATTR(delay_param_4, S_IWUGO | S_IRUGO, pod_get_delay_param_4, -		   pod_set_delay_param_4); -static DEVICE_ATTR(delay_param_5, S_IWUGO | S_IRUGO, pod_get_delay_param_5, -		   pod_set_delay_param_5); -static DEVICE_ATTR(delay_pre_post, S_IWUGO | S_IRUGO, pod_get_delay_pre_post, -		   pod_set_delay_pre_post); -static DEVICE_ATTR(delay_model, S_IWUGO | S_IRUGO, pod_get_delay_model, -		   pod_set_delay_model); -static DEVICE_ATTR(delay_verb_model, S_IWUGO | S_IRUGO, -		   pod_get_delay_verb_model, pod_set_delay_verb_model); -static DEVICE_ATTR(tempo_msb, S_IWUGO | S_IRUGO, pod_get_tempo_msb, -		   pod_set_tempo_msb); -static DEVICE_ATTR(tempo_lsb, S_IWUGO | S_IRUGO, pod_get_tempo_lsb, -		   pod_set_tempo_lsb); -static DEVICE_ATTR(wah_model, S_IWUGO | S_IRUGO, pod_get_wah_model, -		   pod_set_wah_model); -static DEVICE_ATTR(bypass_volume, S_IWUGO | S_IRUGO, pod_get_bypass_volume, -		   pod_set_bypass_volume); -static DEVICE_ATTR(fx_loop_on_off, S_IWUGO | S_IRUGO, pod_get_fx_loop_on_off, -		   pod_set_fx_loop_on_off); -static DEVICE_ATTR(tweak_param_select, S_IWUGO | S_IRUGO, -		   pod_get_tweak_param_select, pod_set_tweak_param_select); -static DEVICE_ATTR(amp1_engage, S_IWUGO | S_IRUGO, pod_get_amp1_engage, -		   pod_set_amp1_engage); -static DEVICE_ATTR(band_1_gain, S_IWUGO | S_IRUGO, pod_get_band_1_gain, -		   pod_set_band_1_gain); -static DEVICE_ATTR2(band_2_gain__bass, band_2_gain, S_IWUGO | S_IRUGO, -		    pod_get_band_2_gain__bass, pod_set_band_2_gain__bass); -static DEVICE_ATTR(band_2_gain, S_IWUGO | S_IRUGO, pod_get_band_2_gain, -		   pod_set_band_2_gain); -static DEVICE_ATTR2(band_3_gain__bass, band_3_gain, S_IWUGO | S_IRUGO, -		    pod_get_band_3_gain__bass, pod_set_band_3_gain__bass); -static DEVICE_ATTR(band_3_gain, S_IWUGO | S_IRUGO, pod_get_band_3_gain, -		   pod_set_band_3_gain); -static DEVICE_ATTR2(band_4_gain__bass, band_4_gain, S_IWUGO | S_IRUGO, -		    pod_get_band_4_gain__bass, pod_set_band_4_gain__bass); -static DEVICE_ATTR2(band_5_gain__bass, band_5_gain, S_IWUGO | S_IRUGO, -		    pod_get_band_5_gain__bass, pod_set_band_5_gain__bass); -static DEVICE_ATTR(band_4_gain, S_IWUGO | S_IRUGO, pod_get_band_4_gain, -		   pod_set_band_4_gain); -static DEVICE_ATTR2(band_6_gain__bass, band_6_gain, S_IWUGO | S_IRUGO, -		    pod_get_band_6_gain__bass, pod_set_band_6_gain__bass); -static DEVICE_ATTR(body, S_IRUGO, variax_get_body, line6_nop_write); -static DEVICE_ATTR(pickup1_enable, S_IRUGO, variax_get_pickup1_enable, -		   line6_nop_write); -static DEVICE_ATTR(pickup1_type, S_IRUGO, variax_get_pickup1_type, -		   line6_nop_write); -static DEVICE_ATTR(pickup1_position, S_IRUGO, variax_get_pickup1_position, -		   line6_nop_write); -static DEVICE_ATTR(pickup1_angle, S_IRUGO, variax_get_pickup1_angle, -		   line6_nop_write); -static DEVICE_ATTR(pickup1_level, S_IRUGO, variax_get_pickup1_level, -		   line6_nop_write); -static DEVICE_ATTR(pickup2_enable, S_IRUGO, variax_get_pickup2_enable, -		   line6_nop_write); -static DEVICE_ATTR(pickup2_type, S_IRUGO, variax_get_pickup2_type, -		   line6_nop_write); -static DEVICE_ATTR(pickup2_position, S_IRUGO, variax_get_pickup2_position, -		   line6_nop_write); -static DEVICE_ATTR(pickup2_angle, S_IRUGO, variax_get_pickup2_angle, -		   line6_nop_write); -static DEVICE_ATTR(pickup2_level, S_IRUGO, variax_get_pickup2_level, -		   line6_nop_write); -static DEVICE_ATTR(pickup_phase, S_IRUGO, variax_get_pickup_phase, -		   line6_nop_write); -static DEVICE_ATTR(capacitance, S_IRUGO, variax_get_capacitance, -		   line6_nop_write); -static DEVICE_ATTR(tone_resistance, S_IRUGO, variax_get_tone_resistance, -		   line6_nop_write); -static DEVICE_ATTR(volume_resistance, S_IRUGO, variax_get_volume_resistance, -		   line6_nop_write); -static DEVICE_ATTR(taper, S_IRUGO, variax_get_taper, line6_nop_write); -static DEVICE_ATTR(tone_dump, S_IRUGO, variax_get_tone_dump, line6_nop_write); -static DEVICE_ATTR(save_tone, S_IRUGO, variax_get_save_tone, line6_nop_write); -static DEVICE_ATTR(volume_dump, S_IRUGO, variax_get_volume_dump, -		   line6_nop_write); -static DEVICE_ATTR(tuning_enable, S_IRUGO, variax_get_tuning_enable, -		   line6_nop_write); -static DEVICE_ATTR(tuning6, S_IRUGO, variax_get_tuning6, line6_nop_write); -static DEVICE_ATTR(tuning5, S_IRUGO, variax_get_tuning5, line6_nop_write); -static DEVICE_ATTR(tuning4, S_IRUGO, variax_get_tuning4, line6_nop_write); -static DEVICE_ATTR(tuning3, S_IRUGO, variax_get_tuning3, line6_nop_write); -static DEVICE_ATTR(tuning2, S_IRUGO, variax_get_tuning2, line6_nop_write); -static DEVICE_ATTR(tuning1, S_IRUGO, variax_get_tuning1, line6_nop_write); -static DEVICE_ATTR(detune6, S_IRUGO, variax_get_detune6, line6_nop_write); -static DEVICE_ATTR(detune5, S_IRUGO, variax_get_detune5, line6_nop_write); -static DEVICE_ATTR(detune4, S_IRUGO, variax_get_detune4, line6_nop_write); -static DEVICE_ATTR(detune3, S_IRUGO, variax_get_detune3, line6_nop_write); -static DEVICE_ATTR(detune2, S_IRUGO, variax_get_detune2, line6_nop_write); -static DEVICE_ATTR(detune1, S_IRUGO, variax_get_detune1, line6_nop_write); -static DEVICE_ATTR(mix6, S_IRUGO, variax_get_mix6, line6_nop_write); -static DEVICE_ATTR(mix5, S_IRUGO, variax_get_mix5, line6_nop_write); -static DEVICE_ATTR(mix4, S_IRUGO, variax_get_mix4, line6_nop_write); -static DEVICE_ATTR(mix3, S_IRUGO, variax_get_mix3, line6_nop_write); -static DEVICE_ATTR(mix2, S_IRUGO, variax_get_mix2, line6_nop_write); -static DEVICE_ATTR(mix1, S_IRUGO, variax_get_mix1, line6_nop_write); -static DEVICE_ATTR(pickup_wiring, S_IRUGO, variax_get_pickup_wiring, -		   line6_nop_write); - -int line6_pod_create_files(int firmware, int type, struct device *dev) -{ -	int err; -	CHECK_RETURN(device_create_file(dev, &dev_attr_tweak)); -	CHECK_RETURN(device_create_file(dev, &dev_attr_wah_position)); -	if ((type & (LINE6_BITS_PODXTALL)) != 0) -		CHECK_RETURN(device_create_file -			     (dev, &dev_attr_compression_gain)); -	CHECK_RETURN(device_create_file(dev, &dev_attr_vol_pedal_position)); -	CHECK_RETURN(device_create_file(dev, &dev_attr_compression_threshold)); -	CHECK_RETURN(device_create_file(dev, &dev_attr_pan)); -	CHECK_RETURN(device_create_file(dev, &dev_attr_amp_model_setup)); -	if (firmware >= 200) -		CHECK_RETURN(device_create_file(dev, &dev_attr_amp_model)); -	CHECK_RETURN(device_create_file(dev, &dev_attr_drive)); -	CHECK_RETURN(device_create_file(dev, &dev_attr_bass)); -	if ((type & (LINE6_BITS_PODXTALL)) != 0) -		CHECK_RETURN(device_create_file(dev, &dev_attr_mid)); -	if ((type & (LINE6_BITS_BASSPODXTALL)) != 0) -		CHECK_RETURN(device_create_file(dev, &dev_attr_lowmid)); -	if ((type & (LINE6_BITS_PODXTALL)) != 0) -		CHECK_RETURN(device_create_file(dev, &dev_attr_treble)); -	if ((type & (LINE6_BITS_BASSPODXTALL)) != 0) -		CHECK_RETURN(device_create_file(dev, &dev_attr_highmid)); -	CHECK_RETURN(device_create_file(dev, &dev_attr_chan_vol)); -	if ((type & (LINE6_BITS_PODXTALL)) != 0) -		CHECK_RETURN(device_create_file(dev, &dev_attr_reverb_mix)); -	CHECK_RETURN(device_create_file(dev, &dev_attr_effect_setup)); -	if (firmware >= 200) -		CHECK_RETURN(device_create_file -			     (dev, &dev_attr_band_1_frequency)); -	if ((type & (LINE6_BITS_PODXTALL)) != 0) -		CHECK_RETURN(device_create_file(dev, &dev_attr_presence)); -	if ((type & (LINE6_BITS_BASSPODXTALL)) != 0) -		CHECK_RETURN(device_create_file(dev, &dev_attr_treble__bass)); -	CHECK_RETURN(device_create_file(dev, &dev_attr_noise_gate_enable)); -	CHECK_RETURN(device_create_file(dev, &dev_attr_gate_threshold)); -	CHECK_RETURN(device_create_file(dev, &dev_attr_gate_decay_time)); -	CHECK_RETURN(device_create_file(dev, &dev_attr_stomp_enable)); -	CHECK_RETURN(device_create_file(dev, &dev_attr_comp_enable)); -	CHECK_RETURN(device_create_file(dev, &dev_attr_stomp_time)); -	CHECK_RETURN(device_create_file(dev, &dev_attr_delay_enable)); -	CHECK_RETURN(device_create_file(dev, &dev_attr_mod_param_1)); -	CHECK_RETURN(device_create_file(dev, &dev_attr_delay_param_1)); -	CHECK_RETURN(device_create_file -		     (dev, &dev_attr_delay_param_1_note_value)); -	if ((type & (LINE6_BITS_BASSPODXTALL)) != 0) -		if (firmware >= 200) -			CHECK_RETURN(device_create_file -				     (dev, &dev_attr_band_2_frequency__bass)); -	CHECK_RETURN(device_create_file(dev, &dev_attr_delay_param_2)); -	CHECK_RETURN(device_create_file(dev, &dev_attr_delay_volume_mix)); -	CHECK_RETURN(device_create_file(dev, &dev_attr_delay_param_3)); -	if ((type & (LINE6_BITS_PODXTALL)) != 0) -		CHECK_RETURN(device_create_file(dev, &dev_attr_reverb_enable)); -	if ((type & (LINE6_BITS_PODXTALL)) != 0) -		CHECK_RETURN(device_create_file(dev, &dev_attr_reverb_type)); -	if ((type & (LINE6_BITS_PODXTALL)) != 0) -		CHECK_RETURN(device_create_file(dev, &dev_attr_reverb_decay)); -	if ((type & (LINE6_BITS_PODXTALL)) != 0) -		CHECK_RETURN(device_create_file(dev, &dev_attr_reverb_tone)); -	if ((type & (LINE6_BITS_PODXTALL)) != 0) -		CHECK_RETURN(device_create_file -			     (dev, &dev_attr_reverb_pre_delay)); -	if ((type & (LINE6_BITS_PODXTALL)) != 0) -		CHECK_RETURN(device_create_file -			     (dev, &dev_attr_reverb_pre_post)); -	if ((type & (LINE6_BITS_PODXTALL)) != 0) -		if (firmware >= 200) -			CHECK_RETURN(device_create_file -				     (dev, &dev_attr_band_2_frequency)); -	if ((type & (LINE6_BITS_BASSPODXTALL)) != 0) -		if (firmware >= 200) -			CHECK_RETURN(device_create_file -				     (dev, &dev_attr_band_3_frequency__bass)); -	CHECK_RETURN(device_create_file(dev, &dev_attr_wah_enable)); -	if ((type & (LINE6_BITS_BASSPODXTALL)) != 0) -		CHECK_RETURN(device_create_file -			     (dev, &dev_attr_modulation_lo_cut)); -	if ((type & (LINE6_BITS_BASSPODXTALL)) != 0) -		CHECK_RETURN(device_create_file -			     (dev, &dev_attr_delay_reverb_lo_cut)); -	if ((type & (LINE6_BITS_PODXTALL)) != 0) -		if (firmware >= 200) -			CHECK_RETURN(device_create_file -				     (dev, &dev_attr_volume_pedal_minimum)); -	if ((type & (LINE6_BITS_BASSPODXTALL)) != 0) -		if (firmware >= 200) -			CHECK_RETURN(device_create_file -				     (dev, &dev_attr_eq_pre_post)); -	CHECK_RETURN(device_create_file(dev, &dev_attr_volume_pre_post)); -	if ((type & (LINE6_BITS_BASSPODXTALL)) != 0) -		CHECK_RETURN(device_create_file(dev, &dev_attr_di_model)); -	if ((type & (LINE6_BITS_BASSPODXTALL)) != 0) -		CHECK_RETURN(device_create_file(dev, &dev_attr_di_delay)); -	CHECK_RETURN(device_create_file(dev, &dev_attr_mod_enable)); -	CHECK_RETURN(device_create_file(dev, &dev_attr_mod_param_1_note_value)); -	CHECK_RETURN(device_create_file(dev, &dev_attr_mod_param_2)); -	CHECK_RETURN(device_create_file(dev, &dev_attr_mod_param_3)); -	CHECK_RETURN(device_create_file(dev, &dev_attr_mod_param_4)); -	if ((type & (LINE6_BITS_BASSPODXTALL)) != 0) -		CHECK_RETURN(device_create_file(dev, &dev_attr_mod_param_5)); -	CHECK_RETURN(device_create_file(dev, &dev_attr_mod_volume_mix)); -	CHECK_RETURN(device_create_file(dev, &dev_attr_mod_pre_post)); -	CHECK_RETURN(device_create_file(dev, &dev_attr_modulation_model)); -	if ((type & (LINE6_BITS_PODXTALL)) != 0) -		if (firmware >= 200) -			CHECK_RETURN(device_create_file -				     (dev, &dev_attr_band_3_frequency)); -	if ((type & (LINE6_BITS_BASSPODXTALL)) != 0) -		if (firmware >= 200) -			CHECK_RETURN(device_create_file -				     (dev, &dev_attr_band_4_frequency__bass)); -	CHECK_RETURN(device_create_file -		     (dev, &dev_attr_mod_param_1_double_precision)); -	CHECK_RETURN(device_create_file -		     (dev, &dev_attr_delay_param_1_double_precision)); -	if (firmware >= 200) -		CHECK_RETURN(device_create_file(dev, &dev_attr_eq_enable)); -	CHECK_RETURN(device_create_file(dev, &dev_attr_tap)); -	CHECK_RETURN(device_create_file -		     (dev, &dev_attr_volume_tweak_pedal_assign)); -	if ((type & (LINE6_BITS_BASSPODXTALL)) != 0) -		if (firmware >= 200) -			CHECK_RETURN(device_create_file -				     (dev, &dev_attr_band_5_frequency)); -	CHECK_RETURN(device_create_file(dev, &dev_attr_tuner)); -	CHECK_RETURN(device_create_file(dev, &dev_attr_mic_selection)); -	CHECK_RETURN(device_create_file(dev, &dev_attr_cabinet_model)); -	CHECK_RETURN(device_create_file(dev, &dev_attr_stomp_model)); -	CHECK_RETURN(device_create_file(dev, &dev_attr_roomlevel)); -	if ((type & (LINE6_BITS_PODXTALL)) != 0) -		if (firmware >= 200) -			CHECK_RETURN(device_create_file -				     (dev, &dev_attr_band_4_frequency)); -	if ((type & (LINE6_BITS_BASSPODXTALL)) != 0) -		if (firmware >= 200) -			CHECK_RETURN(device_create_file -				     (dev, &dev_attr_band_6_frequency)); -	CHECK_RETURN(device_create_file -		     (dev, &dev_attr_stomp_param_1_note_value)); -	CHECK_RETURN(device_create_file(dev, &dev_attr_stomp_param_2)); -	CHECK_RETURN(device_create_file(dev, &dev_attr_stomp_param_3)); -	CHECK_RETURN(device_create_file(dev, &dev_attr_stomp_param_4)); -	CHECK_RETURN(device_create_file(dev, &dev_attr_stomp_param_5)); -	CHECK_RETURN(device_create_file(dev, &dev_attr_stomp_param_6)); -	if ((type & (LINE6_BITS_LIVE)) != 0) -		CHECK_RETURN(device_create_file -			     (dev, &dev_attr_amp_switch_select)); -	CHECK_RETURN(device_create_file(dev, &dev_attr_delay_param_4)); -	CHECK_RETURN(device_create_file(dev, &dev_attr_delay_param_5)); -	CHECK_RETURN(device_create_file(dev, &dev_attr_delay_pre_post)); -	if ((type & (LINE6_BITS_PODXTALL)) != 0) -		CHECK_RETURN(device_create_file(dev, &dev_attr_delay_model)); -	if ((type & (LINE6_BITS_BASSPODXTALL)) != 0) -		CHECK_RETURN(device_create_file -			     (dev, &dev_attr_delay_verb_model)); -	CHECK_RETURN(device_create_file(dev, &dev_attr_tempo_msb)); -	CHECK_RETURN(device_create_file(dev, &dev_attr_tempo_lsb)); -	if (firmware >= 300) -		CHECK_RETURN(device_create_file(dev, &dev_attr_wah_model)); -	if (firmware >= 214) -		CHECK_RETURN(device_create_file(dev, &dev_attr_bypass_volume)); -	if ((type & (LINE6_BITS_PRO)) != 0) -		CHECK_RETURN(device_create_file(dev, &dev_attr_fx_loop_on_off)); -	CHECK_RETURN(device_create_file(dev, &dev_attr_tweak_param_select)); -	CHECK_RETURN(device_create_file(dev, &dev_attr_amp1_engage)); -	if (firmware >= 200) -		CHECK_RETURN(device_create_file(dev, &dev_attr_band_1_gain)); -	if ((type & (LINE6_BITS_BASSPODXTALL)) != 0) -		if (firmware >= 200) -			CHECK_RETURN(device_create_file -				     (dev, &dev_attr_band_2_gain__bass)); -	if ((type & (LINE6_BITS_PODXTALL)) != 0) -		if (firmware >= 200) -			CHECK_RETURN(device_create_file -				     (dev, &dev_attr_band_2_gain)); -	if ((type & (LINE6_BITS_BASSPODXTALL)) != 0) -		if (firmware >= 200) -			CHECK_RETURN(device_create_file -				     (dev, &dev_attr_band_3_gain__bass)); -	if ((type & (LINE6_BITS_PODXTALL)) != 0) -		if (firmware >= 200) -			CHECK_RETURN(device_create_file -				     (dev, &dev_attr_band_3_gain)); -	if ((type & (LINE6_BITS_BASSPODXTALL)) != 0) -		if (firmware >= 200) -			CHECK_RETURN(device_create_file -				     (dev, &dev_attr_band_4_gain__bass)); -	if ((type & (LINE6_BITS_BASSPODXTALL)) != 0) -		if (firmware >= 200) -			CHECK_RETURN(device_create_file -				     (dev, &dev_attr_band_5_gain__bass)); -	if ((type & (LINE6_BITS_PODXTALL)) != 0) -		if (firmware >= 200) -			CHECK_RETURN(device_create_file -				     (dev, &dev_attr_band_4_gain)); -	if ((type & (LINE6_BITS_BASSPODXTALL)) != 0) -		if (firmware >= 200) -			CHECK_RETURN(device_create_file -				     (dev, &dev_attr_band_6_gain__bass)); -	return 0; -} - -void line6_pod_remove_files(int firmware, int type, struct device *dev) -{ -	device_remove_file(dev, &dev_attr_tweak); -	device_remove_file(dev, &dev_attr_wah_position); -	if ((type & (LINE6_BITS_PODXTALL)) != 0) -		device_remove_file(dev, &dev_attr_compression_gain); -	device_remove_file(dev, &dev_attr_vol_pedal_position); -	device_remove_file(dev, &dev_attr_compression_threshold); -	device_remove_file(dev, &dev_attr_pan); -	device_remove_file(dev, &dev_attr_amp_model_setup); -	if (firmware >= 200) -		device_remove_file(dev, &dev_attr_amp_model); -	device_remove_file(dev, &dev_attr_drive); -	device_remove_file(dev, &dev_attr_bass); -	if ((type & (LINE6_BITS_PODXTALL)) != 0) -		device_remove_file(dev, &dev_attr_mid); -	if ((type & (LINE6_BITS_BASSPODXTALL)) != 0) -		device_remove_file(dev, &dev_attr_lowmid); -	if ((type & (LINE6_BITS_PODXTALL)) != 0) -		device_remove_file(dev, &dev_attr_treble); -	if ((type & (LINE6_BITS_BASSPODXTALL)) != 0) -		device_remove_file(dev, &dev_attr_highmid); -	device_remove_file(dev, &dev_attr_chan_vol); -	if ((type & (LINE6_BITS_PODXTALL)) != 0) -		device_remove_file(dev, &dev_attr_reverb_mix); -	device_remove_file(dev, &dev_attr_effect_setup); -	if (firmware >= 200) -		device_remove_file(dev, &dev_attr_band_1_frequency); -	if ((type & (LINE6_BITS_PODXTALL)) != 0) -		device_remove_file(dev, &dev_attr_presence); -	if ((type & (LINE6_BITS_BASSPODXTALL)) != 0) -		device_remove_file(dev, &dev_attr_treble__bass); -	device_remove_file(dev, &dev_attr_noise_gate_enable); -	device_remove_file(dev, &dev_attr_gate_threshold); -	device_remove_file(dev, &dev_attr_gate_decay_time); -	device_remove_file(dev, &dev_attr_stomp_enable); -	device_remove_file(dev, &dev_attr_comp_enable); -	device_remove_file(dev, &dev_attr_stomp_time); -	device_remove_file(dev, &dev_attr_delay_enable); -	device_remove_file(dev, &dev_attr_mod_param_1); -	device_remove_file(dev, &dev_attr_delay_param_1); -	device_remove_file(dev, &dev_attr_delay_param_1_note_value); -	if ((type & (LINE6_BITS_BASSPODXTALL)) != 0) -		if (firmware >= 200) -			device_remove_file(dev, -					   &dev_attr_band_2_frequency__bass); -	device_remove_file(dev, &dev_attr_delay_param_2); -	device_remove_file(dev, &dev_attr_delay_volume_mix); -	device_remove_file(dev, &dev_attr_delay_param_3); -	if ((type & (LINE6_BITS_PODXTALL)) != 0) -		device_remove_file(dev, &dev_attr_reverb_enable); -	if ((type & (LINE6_BITS_PODXTALL)) != 0) -		device_remove_file(dev, &dev_attr_reverb_type); -	if ((type & (LINE6_BITS_PODXTALL)) != 0) -		device_remove_file(dev, &dev_attr_reverb_decay); -	if ((type & (LINE6_BITS_PODXTALL)) != 0) -		device_remove_file(dev, &dev_attr_reverb_tone); -	if ((type & (LINE6_BITS_PODXTALL)) != 0) -		device_remove_file(dev, &dev_attr_reverb_pre_delay); -	if ((type & (LINE6_BITS_PODXTALL)) != 0) -		device_remove_file(dev, &dev_attr_reverb_pre_post); -	if ((type & (LINE6_BITS_PODXTALL)) != 0) -		if (firmware >= 200) -			device_remove_file(dev, &dev_attr_band_2_frequency); -	if ((type & (LINE6_BITS_BASSPODXTALL)) != 0) -		if (firmware >= 200) -			device_remove_file(dev, -					   &dev_attr_band_3_frequency__bass); -	device_remove_file(dev, &dev_attr_wah_enable); -	if ((type & (LINE6_BITS_BASSPODXTALL)) != 0) -		device_remove_file(dev, &dev_attr_modulation_lo_cut); -	if ((type & (LINE6_BITS_BASSPODXTALL)) != 0) -		device_remove_file(dev, &dev_attr_delay_reverb_lo_cut); -	if ((type & (LINE6_BITS_PODXTALL)) != 0) -		if (firmware >= 200) -			device_remove_file(dev, &dev_attr_volume_pedal_minimum); -	if ((type & (LINE6_BITS_BASSPODXTALL)) != 0) -		if (firmware >= 200) -			device_remove_file(dev, &dev_attr_eq_pre_post); -	device_remove_file(dev, &dev_attr_volume_pre_post); -	if ((type & (LINE6_BITS_BASSPODXTALL)) != 0) -		device_remove_file(dev, &dev_attr_di_model); -	if ((type & (LINE6_BITS_BASSPODXTALL)) != 0) -		device_remove_file(dev, &dev_attr_di_delay); -	device_remove_file(dev, &dev_attr_mod_enable); -	device_remove_file(dev, &dev_attr_mod_param_1_note_value); -	device_remove_file(dev, &dev_attr_mod_param_2); -	device_remove_file(dev, &dev_attr_mod_param_3); -	device_remove_file(dev, &dev_attr_mod_param_4); -	if ((type & (LINE6_BITS_BASSPODXTALL)) != 0) -		device_remove_file(dev, &dev_attr_mod_param_5); -	device_remove_file(dev, &dev_attr_mod_volume_mix); -	device_remove_file(dev, &dev_attr_mod_pre_post); -	device_remove_file(dev, &dev_attr_modulation_model); -	if ((type & (LINE6_BITS_PODXTALL)) != 0) -		if (firmware >= 200) -			device_remove_file(dev, &dev_attr_band_3_frequency); -	if ((type & (LINE6_BITS_BASSPODXTALL)) != 0) -		if (firmware >= 200) -			device_remove_file(dev, -					   &dev_attr_band_4_frequency__bass); -	device_remove_file(dev, &dev_attr_mod_param_1_double_precision); -	device_remove_file(dev, &dev_attr_delay_param_1_double_precision); -	if (firmware >= 200) -		device_remove_file(dev, &dev_attr_eq_enable); -	device_remove_file(dev, &dev_attr_tap); -	device_remove_file(dev, &dev_attr_volume_tweak_pedal_assign); -	if ((type & (LINE6_BITS_BASSPODXTALL)) != 0) -		if (firmware >= 200) -			device_remove_file(dev, &dev_attr_band_5_frequency); -	device_remove_file(dev, &dev_attr_tuner); -	device_remove_file(dev, &dev_attr_mic_selection); -	device_remove_file(dev, &dev_attr_cabinet_model); -	device_remove_file(dev, &dev_attr_stomp_model); -	device_remove_file(dev, &dev_attr_roomlevel); -	if ((type & (LINE6_BITS_PODXTALL)) != 0) -		if (firmware >= 200) -			device_remove_file(dev, &dev_attr_band_4_frequency); -	if ((type & (LINE6_BITS_BASSPODXTALL)) != 0) -		if (firmware >= 200) -			device_remove_file(dev, &dev_attr_band_6_frequency); -	device_remove_file(dev, &dev_attr_stomp_param_1_note_value); -	device_remove_file(dev, &dev_attr_stomp_param_2); -	device_remove_file(dev, &dev_attr_stomp_param_3); -	device_remove_file(dev, &dev_attr_stomp_param_4); -	device_remove_file(dev, &dev_attr_stomp_param_5); -	device_remove_file(dev, &dev_attr_stomp_param_6); -	if ((type & (LINE6_BITS_LIVE)) != 0) -		device_remove_file(dev, &dev_attr_amp_switch_select); -	device_remove_file(dev, &dev_attr_delay_param_4); -	device_remove_file(dev, &dev_attr_delay_param_5); -	device_remove_file(dev, &dev_attr_delay_pre_post); -	if ((type & (LINE6_BITS_PODXTALL)) != 0) -		device_remove_file(dev, &dev_attr_delay_model); -	if ((type & (LINE6_BITS_BASSPODXTALL)) != 0) -		device_remove_file(dev, &dev_attr_delay_verb_model); -	device_remove_file(dev, &dev_attr_tempo_msb); -	device_remove_file(dev, &dev_attr_tempo_lsb); -	if (firmware >= 300) -		device_remove_file(dev, &dev_attr_wah_model); -	if (firmware >= 214) -		device_remove_file(dev, &dev_attr_bypass_volume); -	if ((type & (LINE6_BITS_PRO)) != 0) -		device_remove_file(dev, &dev_attr_fx_loop_on_off); -	device_remove_file(dev, &dev_attr_tweak_param_select); -	device_remove_file(dev, &dev_attr_amp1_engage); -	if (firmware >= 200) -		device_remove_file(dev, &dev_attr_band_1_gain); -	if ((type & (LINE6_BITS_BASSPODXTALL)) != 0) -		if (firmware >= 200) -			device_remove_file(dev, &dev_attr_band_2_gain__bass); -	if ((type & (LINE6_BITS_PODXTALL)) != 0) -		if (firmware >= 200) -			device_remove_file(dev, &dev_attr_band_2_gain); -	if ((type & (LINE6_BITS_BASSPODXTALL)) != 0) -		if (firmware >= 200) -			device_remove_file(dev, &dev_attr_band_3_gain__bass); -	if ((type & (LINE6_BITS_PODXTALL)) != 0) -		if (firmware >= 200) -			device_remove_file(dev, &dev_attr_band_3_gain); -	if ((type & (LINE6_BITS_BASSPODXTALL)) != 0) -		if (firmware >= 200) -			device_remove_file(dev, &dev_attr_band_4_gain__bass); -	if ((type & (LINE6_BITS_BASSPODXTALL)) != 0) -		if (firmware >= 200) -			device_remove_file(dev, &dev_attr_band_5_gain__bass); -	if ((type & (LINE6_BITS_PODXTALL)) != 0) -		if (firmware >= 200) -			device_remove_file(dev, &dev_attr_band_4_gain); -	if ((type & (LINE6_BITS_BASSPODXTALL)) != 0) -		if (firmware >= 200) -			device_remove_file(dev, &dev_attr_band_6_gain__bass); -} - -int line6_variax_create_files(int firmware, int type, struct device *dev) -{ -	int err; -	CHECK_RETURN(device_create_file(dev, &dev_attr_body)); -	CHECK_RETURN(device_create_file(dev, &dev_attr_pickup1_enable)); -	CHECK_RETURN(device_create_file(dev, &dev_attr_pickup1_type)); -	CHECK_RETURN(device_create_file(dev, &dev_attr_pickup1_position)); -	CHECK_RETURN(device_create_file(dev, &dev_attr_pickup1_angle)); -	CHECK_RETURN(device_create_file(dev, &dev_attr_pickup1_level)); -	CHECK_RETURN(device_create_file(dev, &dev_attr_pickup2_enable)); -	CHECK_RETURN(device_create_file(dev, &dev_attr_pickup2_type)); -	CHECK_RETURN(device_create_file(dev, &dev_attr_pickup2_position)); -	CHECK_RETURN(device_create_file(dev, &dev_attr_pickup2_angle)); -	CHECK_RETURN(device_create_file(dev, &dev_attr_pickup2_level)); -	CHECK_RETURN(device_create_file(dev, &dev_attr_pickup_phase)); -	CHECK_RETURN(device_create_file(dev, &dev_attr_capacitance)); -	CHECK_RETURN(device_create_file(dev, &dev_attr_tone_resistance)); -	CHECK_RETURN(device_create_file(dev, &dev_attr_volume_resistance)); -	CHECK_RETURN(device_create_file(dev, &dev_attr_taper)); -	CHECK_RETURN(device_create_file(dev, &dev_attr_tone_dump)); -	CHECK_RETURN(device_create_file(dev, &dev_attr_save_tone)); -	CHECK_RETURN(device_create_file(dev, &dev_attr_volume_dump)); -	CHECK_RETURN(device_create_file(dev, &dev_attr_tuning_enable)); -	CHECK_RETURN(device_create_file(dev, &dev_attr_tuning6)); -	CHECK_RETURN(device_create_file(dev, &dev_attr_tuning5)); -	CHECK_RETURN(device_create_file(dev, &dev_attr_tuning4)); -	CHECK_RETURN(device_create_file(dev, &dev_attr_tuning3)); -	CHECK_RETURN(device_create_file(dev, &dev_attr_tuning2)); -	CHECK_RETURN(device_create_file(dev, &dev_attr_tuning1)); -	CHECK_RETURN(device_create_file(dev, &dev_attr_detune6)); -	CHECK_RETURN(device_create_file(dev, &dev_attr_detune5)); -	CHECK_RETURN(device_create_file(dev, &dev_attr_detune4)); -	CHECK_RETURN(device_create_file(dev, &dev_attr_detune3)); -	CHECK_RETURN(device_create_file(dev, &dev_attr_detune2)); -	CHECK_RETURN(device_create_file(dev, &dev_attr_detune1)); -	CHECK_RETURN(device_create_file(dev, &dev_attr_mix6)); -	CHECK_RETURN(device_create_file(dev, &dev_attr_mix5)); -	CHECK_RETURN(device_create_file(dev, &dev_attr_mix4)); -	CHECK_RETURN(device_create_file(dev, &dev_attr_mix3)); -	CHECK_RETURN(device_create_file(dev, &dev_attr_mix2)); -	CHECK_RETURN(device_create_file(dev, &dev_attr_mix1)); -	CHECK_RETURN(device_create_file(dev, &dev_attr_pickup_wiring)); -	return 0; -} - -void line6_variax_remove_files(int firmware, int type, struct device *dev) -{ -	device_remove_file(dev, &dev_attr_body); -	device_remove_file(dev, &dev_attr_pickup1_enable); -	device_remove_file(dev, &dev_attr_pickup1_type); -	device_remove_file(dev, &dev_attr_pickup1_position); -	device_remove_file(dev, &dev_attr_pickup1_angle); -	device_remove_file(dev, &dev_attr_pickup1_level); -	device_remove_file(dev, &dev_attr_pickup2_enable); -	device_remove_file(dev, &dev_attr_pickup2_type); -	device_remove_file(dev, &dev_attr_pickup2_position); -	device_remove_file(dev, &dev_attr_pickup2_angle); -	device_remove_file(dev, &dev_attr_pickup2_level); -	device_remove_file(dev, &dev_attr_pickup_phase); -	device_remove_file(dev, &dev_attr_capacitance); -	device_remove_file(dev, &dev_attr_tone_resistance); -	device_remove_file(dev, &dev_attr_volume_resistance); -	device_remove_file(dev, &dev_attr_taper); -	device_remove_file(dev, &dev_attr_tone_dump); -	device_remove_file(dev, &dev_attr_save_tone); -	device_remove_file(dev, &dev_attr_volume_dump); -	device_remove_file(dev, &dev_attr_tuning_enable); -	device_remove_file(dev, &dev_attr_tuning6); -	device_remove_file(dev, &dev_attr_tuning5); -	device_remove_file(dev, &dev_attr_tuning4); -	device_remove_file(dev, &dev_attr_tuning3); -	device_remove_file(dev, &dev_attr_tuning2); -	device_remove_file(dev, &dev_attr_tuning1); -	device_remove_file(dev, &dev_attr_detune6); -	device_remove_file(dev, &dev_attr_detune5); -	device_remove_file(dev, &dev_attr_detune4); -	device_remove_file(dev, &dev_attr_detune3); -	device_remove_file(dev, &dev_attr_detune2); -	device_remove_file(dev, &dev_attr_detune1); -	device_remove_file(dev, &dev_attr_mix6); -	device_remove_file(dev, &dev_attr_mix5); -	device_remove_file(dev, &dev_attr_mix4); -	device_remove_file(dev, &dev_attr_mix3); -	device_remove_file(dev, &dev_attr_mix2); -	device_remove_file(dev, &dev_attr_mix1); -	device_remove_file(dev, &dev_attr_pickup_wiring); -} diff --git a/drivers/staging/line6/control.h b/drivers/staging/line6/control.h deleted file mode 100644 index e4c5d2ce2aa..00000000000 --- a/drivers/staging/line6/control.h +++ /dev/null @@ -1,195 +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 LINE6_CONTROL_H -#define LINE6_CONTROL_H - -/** -   List of PODxt Pro controls. -   See Appendix C of the "PODxt (Pro) Pilot's Handbook" by Line6. -   Comments after the number refer to the PODxt Pro firmware version required -   for this feature. - -   Please *don't* reformat this file since "control.c" is created automatically -   from "control.h", and this process depends on the exact formatting of the -   code and the comments below! -*/ - -/* *INDENT-OFF* */ - -enum { -	POD_tweak                          =   1, -	POD_wah_position                   =   4, -	POD_compression_gain               =   5,  /* device: LINE6_BITS_PODXTALL */ -	POD_vol_pedal_position             =   7, -	POD_compression_threshold          =   9, -	POD_pan                            =  10, -	POD_amp_model_setup                =  11, -	POD_amp_model                      =  12,  /* firmware: 2.0 */ -	POD_drive                          =  13, -	POD_bass                           =  14, -	POD_mid                            =  15,  /* device: LINE6_BITS_PODXTALL */ -	POD_lowmid                         =  15,  /* device: LINE6_BITS_BASSPODXTALL */ -	POD_treble                         =  16,  /* device: LINE6_BITS_PODXTALL */ -	POD_highmid                        =  16,  /* device: LINE6_BITS_BASSPODXTALL */ -	POD_chan_vol                       =  17, -	POD_reverb_mix                     =  18,  /* device: LINE6_BITS_PODXTALL */ -	POD_effect_setup                   =  19, -	POD_band_1_frequency               =  20,  /* firmware: 2.0 */ -	POD_presence                       =  21,  /* device: LINE6_BITS_PODXTALL */ -	POD_treble__bass                   =  21,  /* device: LINE6_BITS_BASSPODXTALL */ -	POD_noise_gate_enable              =  22, -	POD_gate_threshold                 =  23, -	POD_gate_decay_time                =  24, -	POD_stomp_enable                   =  25, -	POD_comp_enable                    =  26, -	POD_stomp_time                     =  27, -	POD_delay_enable                   =  28, -	POD_mod_param_1                    =  29, -	POD_delay_param_1                  =  30, -	POD_delay_param_1_note_value       =  31, -	POD_band_2_frequency__bass         =  32,  /* device: LINE6_BITS_BASSPODXTALL */ /* firmware: 2.0 */ -	POD_delay_param_2                  =  33, -	POD_delay_volume_mix               =  34, -	POD_delay_param_3                  =  35, -	POD_reverb_enable                  =  36,  /* device: LINE6_BITS_PODXTALL */ -	POD_reverb_type                    =  37,  /* device: LINE6_BITS_PODXTALL */ -	POD_reverb_decay                   =  38,  /* device: LINE6_BITS_PODXTALL */ -	POD_reverb_tone                    =  39,  /* device: LINE6_BITS_PODXTALL */ -	POD_reverb_pre_delay               =  40,  /* device: LINE6_BITS_PODXTALL */ -	POD_reverb_pre_post                =  41,  /* device: LINE6_BITS_PODXTALL */ -	POD_band_2_frequency               =  42,  /* device: LINE6_BITS_PODXTALL */     /* firmware: 2.0 */ -	POD_band_3_frequency__bass         =  42,  /* device: LINE6_BITS_BASSPODXTALL */ /* firmware: 2.0 */ -	POD_wah_enable                     =  43, -	POD_modulation_lo_cut              =  44,  /* device: LINE6_BITS_BASSPODXTALL */ -	POD_delay_reverb_lo_cut            =  45,  /* device: LINE6_BITS_BASSPODXTALL */ -	POD_volume_pedal_minimum           =  46,  /* device: LINE6_BITS_PODXTALL */     /* firmware: 2.0 */ -	POD_eq_pre_post                    =  46,  /* device: LINE6_BITS_BASSPODXTALL */ /* firmware: 2.0 */ -	POD_volume_pre_post                =  47, -	POD_di_model                       =  48,  /* device: LINE6_BITS_BASSPODXTALL */ -	POD_di_delay                       =  49,  /* device: LINE6_BITS_BASSPODXTALL */ -	POD_mod_enable                     =  50, -	POD_mod_param_1_note_value         =  51, -	POD_mod_param_2                    =  52, -	POD_mod_param_3                    =  53, -	POD_mod_param_4                    =  54, -	POD_mod_param_5                    =  55,  /* device: LINE6_BITS_BASSPODXTALL */ -	POD_mod_volume_mix                 =  56, -	POD_mod_pre_post                   =  57, -	POD_modulation_model               =  58, -	POD_band_3_frequency               =  60,  /* device: LINE6_BITS_PODXTALL */     /* firmware: 2.0 */ -	POD_band_4_frequency__bass         =  60,  /* device: LINE6_BITS_BASSPODXTALL */ /* firmware: 2.0 */ -	POD_mod_param_1_double_precision   =  61, -	POD_delay_param_1_double_precision =  62, -	POD_eq_enable                      =  63,  /* firmware: 2.0 */ -	POD_tap                            =  64, -	POD_volume_tweak_pedal_assign      =  65, -	POD_band_5_frequency               =  68,  /* device: LINE6_BITS_BASSPODXTALL */ /* firmware: 2.0 */ -	POD_tuner                          =  69, -	POD_mic_selection                  =  70, -	POD_cabinet_model                  =  71, -	POD_stomp_model                    =  75, -	POD_roomlevel                      =  76, -	POD_band_4_frequency               =  77,  /* device: LINE6_BITS_PODXTALL */     /* firmware: 2.0 */ -	POD_band_6_frequency               =  77,  /* device: LINE6_BITS_BASSPODXTALL */ /* firmware: 2.0 */ -	POD_stomp_param_1_note_value       =  78, -	POD_stomp_param_2                  =  79, -	POD_stomp_param_3                  =  80, -	POD_stomp_param_4                  =  81, -	POD_stomp_param_5                  =  82, -	POD_stomp_param_6                  =  83, -	POD_amp_switch_select              =  84,  /* device: LINE6_BITS_LIVE */ -	POD_delay_param_4                  =  85, -	POD_delay_param_5                  =  86, -	POD_delay_pre_post                 =  87, -	POD_delay_model                    =  88,  /* device: LINE6_BITS_PODXTALL */ -	POD_delay_verb_model               =  88,  /* device: LINE6_BITS_BASSPODXTALL */ -	POD_tempo_msb                      =  89, -	POD_tempo_lsb                      =  90, -	POD_wah_model                      =  91,  /* firmware: 3.0 */ -	POD_bypass_volume                  = 105,  /* firmware: 2.14 */ -	POD_fx_loop_on_off                 = 107,  /* device: LINE6_BITS_PRO */ -	POD_tweak_param_select             = 108, -	POD_amp1_engage                    = 111, -	POD_band_1_gain                    = 114,  /* firmware: 2.0 */ -	POD_band_2_gain__bass              = 115,  /* device: LINE6_BITS_BASSPODXTALL */ /* firmware: 2.0 */ -	POD_band_2_gain                    = 116,  /* device: LINE6_BITS_PODXTALL */     /* firmware: 2.0 */ -	POD_band_3_gain__bass              = 116,  /* device: LINE6_BITS_BASSPODXTALL */ /* firmware: 2.0 */ -	POD_band_3_gain                    = 117,  /* device: LINE6_BITS_PODXTALL */     /* firmware: 2.0 */ -	POD_band_4_gain__bass              = 117,  /* device: LINE6_BITS_BASSPODXTALL */ /* firmware: 2.0 */ -	POD_band_5_gain__bass              = 118,  /* device: LINE6_BITS_BASSPODXTALL */ /* firmware: 2.0 */ -	POD_band_4_gain                    = 119,  /* device: LINE6_BITS_PODXTALL */     /* firmware: 2.0 */ -	POD_band_6_gain__bass              = 119   /* device: LINE6_BITS_BASSPODXTALL */ /* firmware: 2.0 */ -}; - -/** -   List of Variax workbench controls (dump). -*/ -enum { -	VARIAX_body                        =   3, -	VARIAX_pickup1_enable              =   4,  /* 0: enabled, 1: disabled */ -	VARIAX_pickup1_type                =   8, -	VARIAX_pickup1_position            =   9,  /* type: 24 bit float */ -	VARIAX_pickup1_angle               =  12,  /* type: 24 bit float */ -	VARIAX_pickup1_level               =  15,  /* type: 24 bit float */ -	VARIAX_pickup2_enable              =  18,  /* 0: enabled, 1: disabled */ -	VARIAX_pickup2_type                =  22, -	VARIAX_pickup2_position            =  23,  /* type: 24 bit float */ -	VARIAX_pickup2_angle               =  26,  /* type: 24 bit float */ -	VARIAX_pickup2_level               =  29,  /* type: 24 bit float */ -	VARIAX_pickup_phase                =  32,  /* 0: in phase, 1: out of phase */ -	VARIAX_capacitance                 =  33,  /* type: 24 bit float */ -	VARIAX_tone_resistance             =  36,  /* type: 24 bit float */ -	VARIAX_volume_resistance           =  39,  /* type: 24 bit float */ -	VARIAX_taper                       =  42,  /* 0: Linear, 1: Audio */ -	VARIAX_tone_dump                   =  43,  /* type: 24 bit float */ -	VARIAX_save_tone                   =  46, -	VARIAX_volume_dump                 =  47,  /* type: 24 bit float */ -	VARIAX_tuning_enable               =  50, -	VARIAX_tuning6                     =  51, -	VARIAX_tuning5                     =  52, -	VARIAX_tuning4                     =  53, -	VARIAX_tuning3                     =  54, -	VARIAX_tuning2                     =  55, -	VARIAX_tuning1                     =  56, -	VARIAX_detune6                     =  57,  /* type: 24 bit float */ -	VARIAX_detune5                     =  60,  /* type: 24 bit float */ -	VARIAX_detune4                     =  63,  /* type: 24 bit float */ -	VARIAX_detune3                     =  66,  /* type: 24 bit float */ -	VARIAX_detune2                     =  69,  /* type: 24 bit float */ -	VARIAX_detune1                     =  72,  /* type: 24 bit float */ -	VARIAX_mix6                        =  75,  /* type: 24 bit float */ -	VARIAX_mix5                        =  78,  /* type: 24 bit float */ -	VARIAX_mix4                        =  81,  /* type: 24 bit float */ -	VARIAX_mix3                        =  84,  /* type: 24 bit float */ -	VARIAX_mix2                        =  87,  /* type: 24 bit float */ -	VARIAX_mix1                        =  90,  /* type: 24 bit float */ -	VARIAX_pickup_wiring               =  96   /* 0: parallel, 1: series */ -}; - -/** -   List of Variax workbench controls (MIDI). -*/ -enum { -	VARIAXMIDI_volume                  =   7, -	VARIAXMIDI_tone                    =  79, -}; - -/* *INDENT-ON* */ - -extern int line6_pod_create_files(int firmware, int type, struct device *dev); -extern void line6_pod_remove_files(int firmware, int type, struct device *dev); -extern int line6_variax_create_files(int firmware, int type, -				     struct device *dev); -extern void line6_variax_remove_files(int firmware, int type, -				      struct device *dev); - -#endif diff --git a/drivers/staging/line6/driver.c b/drivers/staging/line6/driver.c index ea9209d9ceb..ef511c76a6e 100644 --- a/drivers/staging/line6/driver.c +++ b/drivers/staging/line6/driver.c @@ -16,11 +16,11 @@  #include "audio.h"  #include "capture.h" -#include "control.h"  #include "driver.h"  #include "midi.h"  #include "playback.h"  #include "pod.h" +#include "podhd.h"  #include "revision.h"  #include "toneport.h"  #include "usbdefs.h" @@ -37,6 +37,9 @@ static const struct usb_device_id line6_id_table[] = {  	{USB_DEVICE(LINE6_VENDOR_ID, LINE6_DEVID_BASSPODXTPRO)},  	{USB_DEVICE(LINE6_VENDOR_ID, LINE6_DEVID_GUITARPORT)},  	{USB_DEVICE(LINE6_VENDOR_ID, LINE6_DEVID_POCKETPOD)}, +	{USB_DEVICE(LINE6_VENDOR_ID, LINE6_DEVID_PODHD300)}, +	{USB_DEVICE(LINE6_VENDOR_ID, LINE6_DEVID_PODHD400)}, +	{USB_DEVICE(LINE6_VENDOR_ID, LINE6_DEVID_PODHD500)},  	{USB_DEVICE(LINE6_VENDOR_ID, LINE6_DEVID_PODSTUDIO_GX)},  	{USB_DEVICE(LINE6_VENDOR_ID, LINE6_DEVID_PODSTUDIO_UX1)},  	{USB_DEVICE(LINE6_VENDOR_ID, LINE6_DEVID_PODSTUDIO_UX2)}, @@ -54,25 +57,32 @@ static const struct usb_device_id line6_id_table[] = {  MODULE_DEVICE_TABLE(usb, line6_id_table); +#define L6PROP(dev_bit, dev_id, dev_name, dev_cap)\ +	{.device_bit = LINE6_BIT_##dev_bit, .id = dev_id,\ +	 .name = dev_name, .capabilities = LINE6_BIT_##dev_cap} +  /* *INDENT-OFF* */ -static struct line6_properties line6_properties_table[] = { -	{ "BassPODxt",     "BassPODxt",        LINE6_BIT_BASSPODXT,     LINE6_BIT_CONTROL_PCM_HWMON }, -	{ "BassPODxtLive", "BassPODxt Live",   LINE6_BIT_BASSPODXTLIVE, LINE6_BIT_CONTROL_PCM_HWMON }, -	{ "BassPODxtPro",  "BassPODxt Pro",    LINE6_BIT_BASSPODXTPRO,  LINE6_BIT_CONTROL_PCM_HWMON }, -	{ "GuitarPort",    "GuitarPort",       LINE6_BIT_GUITARPORT,    LINE6_BIT_PCM               }, -	{ "PocketPOD",     "Pocket POD",       LINE6_BIT_POCKETPOD,     LINE6_BIT_CONTROL           }, -	{ "PODStudioGX",   "POD Studio GX",    LINE6_BIT_PODSTUDIO_GX,  LINE6_BIT_PCM               }, -	{ "PODStudioUX1",  "POD Studio UX1",   LINE6_BIT_PODSTUDIO_UX1, LINE6_BIT_PCM               }, -	{ "PODStudioUX2",  "POD Studio UX2",   LINE6_BIT_PODSTUDIO_UX2, LINE6_BIT_PCM               }, -	{ "PODX3",         "POD X3",           LINE6_BIT_PODX3,         LINE6_BIT_PCM               }, -	{ "PODX3Live",     "POD X3 Live",      LINE6_BIT_PODX3LIVE,     LINE6_BIT_PCM               }, -	{ "PODxt",         "PODxt",            LINE6_BIT_PODXT,         LINE6_BIT_CONTROL_PCM_HWMON }, -	{ "PODxtLive",     "PODxt Live",       LINE6_BIT_PODXTLIVE,     LINE6_BIT_CONTROL_PCM_HWMON }, -	{ "PODxtPro",      "PODxt Pro",        LINE6_BIT_PODXTPRO,      LINE6_BIT_CONTROL_PCM_HWMON }, -	{ "TonePortGX",    "TonePort GX",      LINE6_BIT_TONEPORT_GX,   LINE6_BIT_PCM               }, -	{ "TonePortUX1",   "TonePort UX1",     LINE6_BIT_TONEPORT_UX1,  LINE6_BIT_PCM               }, -	{ "TonePortUX2",   "TonePort UX2",     LINE6_BIT_TONEPORT_UX2,  LINE6_BIT_PCM               }, -	{ "Variax",        "Variax Workbench", LINE6_BIT_VARIAX,        LINE6_BIT_CONTROL           } +static const struct line6_properties line6_properties_table[] = { +	L6PROP(BASSPODXT,     "BassPODxt",     "BassPODxt",        CTRL_PCM_HW), +	L6PROP(BASSPODXTLIVE, "BassPODxtLive", "BassPODxt Live",   CTRL_PCM_HW), +	L6PROP(BASSPODXTPRO,  "BassPODxtPro",  "BassPODxt Pro",    CTRL_PCM_HW), +	L6PROP(GUITARPORT,    "GuitarPort",    "GuitarPort",       PCM), +	L6PROP(POCKETPOD,     "PocketPOD",     "Pocket POD",       CONTROL), +	L6PROP(PODHD300,      "PODHD300",      "POD HD300",        CTRL_PCM_HW), +	L6PROP(PODHD400,      "PODHD400",      "POD HD400",        CTRL_PCM_HW), +	L6PROP(PODHD500,      "PODHD500",      "POD HD500",        CTRL_PCM_HW), +	L6PROP(PODSTUDIO_GX,  "PODStudioGX",   "POD Studio GX",    PCM), +	L6PROP(PODSTUDIO_UX1, "PODStudioUX1",  "POD Studio UX1",   PCM), +	L6PROP(PODSTUDIO_UX2, "PODStudioUX2",  "POD Studio UX2",   PCM), +	L6PROP(PODX3,         "PODX3",         "POD X3",           PCM), +	L6PROP(PODX3LIVE,     "PODX3Live",     "POD X3 Live",      PCM), +	L6PROP(PODXT,         "PODxt",         "PODxt",            CTRL_PCM_HW), +	L6PROP(PODXTLIVE,     "PODxtLive",     "PODxt Live",       CTRL_PCM_HW), +	L6PROP(PODXTPRO,      "PODxtPro",      "PODxt Pro",        CTRL_PCM_HW), +	L6PROP(TONEPORT_GX,   "TonePortGX",    "TonePort GX",      PCM), +	L6PROP(TONEPORT_UX1,  "TonePortUX1",   "TonePort UX1",     PCM), +	L6PROP(TONEPORT_UX2,  "TonePortUX2",   "TonePort UX2",     PCM), +	L6PROP(VARIAX,        "Variax",        "Variax Workbench", CONTROL),  };  /* *INDENT-ON* */ @@ -87,17 +97,10 @@ const unsigned char line6_midi_id[] = {  	Code to request version of POD, Variax interface  	(and maybe other devices).  */ -static const char line6_request_version0[] = { +static const char line6_request_version[] = {  	0xf0, 0x7e, 0x7f, 0x06, 0x01, 0xf7  }; -/* -	Copy of version request code with GFP_KERNEL flag for use in URB. -*/ -static const char *line6_request_version; - -struct usb_line6 *line6_devices[LINE6_MAX_DEVICES]; -  /**  	 Class for asynchronous messages.  */ @@ -121,6 +124,7 @@ static int line6_send_raw_message_async_part(struct message *msg,  static int line6_start_listen(struct usb_line6 *line6)  {  	int err; +  	usb_fill_int_urb(line6->urb_listen, line6->usbdev,  			 usb_rcvintpipe(line6->usbdev, line6->ep_control_read),  			 line6->buffer_listen, LINE6_BUFSIZE_LISTEN, @@ -138,63 +142,6 @@ static void line6_stop_listen(struct usb_line6 *line6)  	usb_kill_urb(line6->urb_listen);  } -#ifdef CONFIG_LINE6_USB_DUMP_ANY -/* -	Write hexdump to syslog. -*/ -void line6_write_hexdump(struct usb_line6 *line6, char dir, -			 const unsigned char *buffer, int size) -{ -	static const int BYTES_PER_LINE = 8; -	char hexdump[100]; -	char asc[BYTES_PER_LINE + 1]; -	int i, j; - -	for (i = 0; i < size; i += BYTES_PER_LINE) { -		int hexdumpsize = sizeof(hexdump); -		char *p = hexdump; -		int n = min(size - i, BYTES_PER_LINE); -		asc[n] = 0; - -		for (j = 0; j < BYTES_PER_LINE; ++j) { -			int bytes; - -			if (j < n) { -				unsigned char val = buffer[i + j]; -				bytes = snprintf(p, hexdumpsize, " %02X", val); -				asc[j] = ((val >= 0x20) -					  && (val < 0x7f)) ? val : '.'; -			} else -				bytes = snprintf(p, hexdumpsize, "   "); - -			if (bytes > hexdumpsize) -				break;	/* buffer overflow */ - -			p += bytes; -			hexdumpsize -= bytes; -		} - -		dev_info(line6->ifcdev, "%c%04X:%s %s\n", dir, i, hexdump, asc); -	} -} -#endif - -#ifdef CONFIG_LINE6_USB_DUMP_CTRL -/* -	Dump URB data to syslog. -*/ -static void line6_dump_urb(struct urb *urb) -{ -	struct usb_line6 *line6 = (struct usb_line6 *)urb->context; - -	if (urb->status < 0) -		return; - -	line6_write_hexdump(line6, 'R', (unsigned char *)urb->transfer_buffer, -			    urb->actual_length); -} -#endif -  /*  	Send raw message in pieces of wMaxPacketSize bytes.  */ @@ -203,10 +150,6 @@ int line6_send_raw_message(struct usb_line6 *line6, const char *buffer,  {  	int i, done = 0; -#ifdef CONFIG_LINE6_USB_DUMP_CTRL -	line6_write_hexdump(line6, 'S', buffer, size); -#endif -  	for (i = 0; i < size; i += line6->max_packet_size) {  		int partial;  		const char *frag_buf = buffer + i; @@ -214,10 +157,10 @@ int line6_send_raw_message(struct usb_line6 *line6, const char *buffer,  		int retval;  		retval = usb_interrupt_msg(line6->usbdev, -					   usb_sndintpipe(line6->usbdev, -							  line6->ep_control_write), -					   (char *)frag_buf, frag_size, -					   &partial, LINE6_TIMEOUT * HZ); +					usb_sndintpipe(line6->usbdev, +						line6->ep_control_write), +					(char *)frag_buf, frag_size, +					&partial, LINE6_TIMEOUT * HZ);  		if (retval) {  			dev_err(line6->ifcdev, @@ -261,10 +204,6 @@ static int line6_send_raw_message_async_part(struct message *msg,  			 (char *)msg->buffer + done, bytes,  			 line6_async_request_sent, msg, line6->interval); -#ifdef CONFIG_LINE6_USB_DUMP_CTRL -	line6_write_hexdump(line6, 'S', (char *)msg->buffer + done, bytes); -#endif -  	msg->done += bytes;  	retval = usb_submit_urb(urb, GFP_ATOMIC); @@ -273,7 +212,7 @@ static int line6_send_raw_message_async_part(struct message *msg,  			__func__, retval);  		usb_free_urb(urb);  		kfree(msg); -		return -EINVAL; +		return retval;  	}  	return 0; @@ -283,7 +222,7 @@ static int line6_send_raw_message_async_part(struct message *msg,  	Setup and start timer.  */  void line6_start_timer(struct timer_list *timer, unsigned int msecs, -		       void (*function) (unsigned long), unsigned long data) +		       void (*function)(unsigned long), unsigned long data)  {  	setup_timer(timer, function, data);  	timer->expires = jiffies + msecs * HZ / 1000; @@ -301,11 +240,8 @@ int line6_send_raw_message_async(struct usb_line6 *line6, const char *buffer,  	/* create message: */  	msg = kmalloc(sizeof(struct message), GFP_ATOMIC); - -	if (msg == NULL) { -		dev_err(line6->ifcdev, "Out of memory\n"); +	if (msg == NULL)  		return -ENOMEM; -	}  	/* create URB: */  	urb = usb_alloc_urb(0, GFP_ATOMIC); @@ -331,8 +267,20 @@ int line6_send_raw_message_async(struct usb_line6 *line6, const char *buffer,  */  int line6_version_request_async(struct usb_line6 *line6)  { -	return line6_send_raw_message_async(line6, line6_request_version, -					    sizeof(line6_request_version0)); +	char *buffer; +	int retval; + +	buffer = kmemdup(line6_request_version, +			sizeof(line6_request_version), GFP_ATOMIC); +	if (buffer == NULL) { +		dev_err(line6->ifcdev, "Out of memory"); +		return -ENOMEM; +	} + +	retval = line6_send_raw_message_async(line6, buffer, +					      sizeof(line6_request_version)); +	kfree(buffer); +	return retval;  }  /* @@ -347,17 +295,6 @@ int line6_send_sysex_message(struct usb_line6 *line6, const char *buffer,  }  /* -	Send sysex message in pieces of wMaxPacketSize bytes. -*/ -int line6_send_sysex_message_async(struct usb_line6 *line6, const char *buffer, -				   int size) -{ -	return line6_send_raw_message_async(line6, buffer, -					    size + SYSEX_EXTRA_SIZE) - -	    SYSEX_EXTRA_SIZE; -} - -/*  	Allocate buffer for sysex message and prepare header.  	@param code sysex message code  	@param size number of bytes between code and sysex end @@ -367,10 +304,8 @@ char *line6_alloc_sysex_buffer(struct usb_line6 *line6, int code1, int code2,  {  	char *buffer = kmalloc(size + SYSEX_EXTRA_SIZE, GFP_ATOMIC); -	if (!buffer) { -		dev_err(line6->ifcdev, "out of memory\n"); +	if (!buffer)  		return NULL; -	}  	buffer[0] = LINE6_SYSEX_BEGIN;  	memcpy(buffer + 1, line6_midi_id, sizeof(line6_midi_id)); @@ -386,25 +321,19 @@ char *line6_alloc_sysex_buffer(struct usb_line6 *line6, int code1, int code2,  static void line6_data_received(struct urb *urb)  {  	struct usb_line6 *line6 = (struct usb_line6 *)urb->context; -	struct MidiBuffer *mb = &line6->line6midi->midibuf_in; +	struct midi_buffer *mb = &line6->line6midi->midibuf_in;  	int done;  	if (urb->status == -ESHUTDOWN)  		return; -#ifdef CONFIG_LINE6_USB_DUMP_CTRL -	line6_dump_urb(urb); -#endif -  	done =  	    line6_midibuf_write(mb, urb->transfer_buffer, urb->actual_length);  	if (done < urb->actual_length) {  		line6_midibuf_ignore(mb, done); -		DEBUG_MESSAGES(dev_err -			       (line6->ifcdev, -				"%d %d buffer overflow - message skipped\n", -				done, urb->actual_length)); +		dev_dbg(line6->ifcdev, "%d %d buffer overflow - message skipped\n", +			done, urb->actual_length);  	}  	for (;;) { @@ -415,18 +344,10 @@ static void line6_data_received(struct urb *urb)  		if (done == 0)  			break; -		/* MIDI input filter */ -		if (line6_midibuf_skip_message -		    (mb, line6->line6midi->midi_mask_receive)) -			continue; -  		line6->message_length = done; -#ifdef CONFIG_LINE6_USB_DUMP_MIDI -		line6_write_hexdump(line6, 'r', line6->buffer_message, done); -#endif  		line6_midi_receive(line6, line6->buffer_message, done); -		switch (line6->usbdev->descriptor.idProduct) { +		switch (le16_to_cpu(line6->usbdev->descriptor.idProduct)) {  		case LINE6_DEVID_BASSPODXT:  		case LINE6_DEVID_BASSPODXTLIVE:  		case LINE6_DEVID_BASSPODXTPRO: @@ -437,6 +358,11 @@ static void line6_data_received(struct urb *urb)  						  line6);  			break; +		case LINE6_DEVID_PODHD300: +		case LINE6_DEVID_PODHD400: +		case LINE6_DEVID_PODHD500: +			break; /* let userspace handle MIDI */ +  		case LINE6_DEVID_PODXTLIVE:  			switch (line6->interface_number) {  			case PODXTLIVE_INTERFACE_POD: @@ -473,26 +399,19 @@ 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, int value) +int line6_send_program(struct usb_line6 *line6, u8 value)  {  	int retval;  	unsigned char *buffer;  	int partial;  	buffer = kmalloc(2, GFP_KERNEL); - -	if (!buffer) { -		dev_err(line6->ifcdev, "out of memory\n"); +	if (!buffer)  		return -ENOMEM; -	}  	buffer[0] = LINE6_PROGRAM_CHANGE | LINE6_CHANNEL_HOST;  	buffer[1] = value; -#ifdef CONFIG_LINE6_USB_DUMP_CTRL -	line6_write_hexdump(line6, 'S', buffer, 2); -#endif -  	retval = usb_interrupt_msg(line6->usbdev,  				   usb_sndintpipe(line6->usbdev,  						  line6->ep_control_write), @@ -509,27 +428,20 @@ int line6_send_program(struct usb_line6 *line6, int value)  /*  	Transmit Line6 control parameter.  */ -int line6_transmit_parameter(struct usb_line6 *line6, int param, int value) +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) { -		dev_err(line6->ifcdev, "out of memory\n"); +	if (!buffer)  		return -ENOMEM; -	}  	buffer[0] = LINE6_PARAM_CHANGE | LINE6_CHANNEL_HOST;  	buffer[1] = param;  	buffer[2] = value; -#ifdef CONFIG_LINE6_USB_DUMP_CTRL -	line6_write_hexdump(line6, 'S', buffer, 3); -#endif -  	retval = usb_interrupt_msg(line6->usbdev,  				   usb_sndintpipe(line6->usbdev,  						  line6->ep_control_write), @@ -564,7 +476,7 @@ int line6_read_data(struct usb_line6 *line6, int address, void *data,  		return ret;  	} -	/* Wait for data length. We'll get a couple of 0xff until length arrives. */ +	/* Wait for data length. We'll get 0xff until length arrives. */  	do {  		ret = usb_control_msg(usbdev, usb_rcvctrlpipe(usbdev, 0), 0x67,  				      USB_TYPE_VENDOR | USB_RECIP_DEVICE | @@ -664,29 +576,6 @@ ssize_t line6_nop_read(struct device *dev, struct device_attribute *attr,  }  /* -	No operation (i.e., unsupported). -*/ -ssize_t line6_nop_write(struct device *dev, struct device_attribute *attr, -			const char *buf, size_t count) -{ -	return count; -} - -/* -	"write" request on "raw" special file. -*/ -#ifdef CONFIG_LINE6_USB_RAW -ssize_t line6_set_raw(struct device *dev, struct device_attribute *attr, -		      const char *buf, size_t count) -{ -	struct usb_interface *interface = to_usb_interface(dev); -	struct usb_line6 *line6 = usb_get_intfdata(interface); -	line6_send_raw_message(line6, buf, count); -	return count; -} -#endif - -/*  	Generic destructor.  */  static void line6_destruct(struct usb_interface *interface) @@ -720,10 +609,9 @@ static int line6_probe(struct usb_interface *interface,  		       const struct usb_device_id *id)  {  	int devtype; -	struct usb_device *usbdev = NULL; -	struct usb_line6 *line6 = NULL; +	struct usb_device *usbdev; +	struct usb_line6 *line6;  	const struct line6_properties *properties; -	int devnum;  	int interface_number, alternate = 0;  	int product;  	int size = 0; @@ -757,16 +645,6 @@ static int line6_probe(struct usb_interface *interface,  		goto err_put;  	} -	/* find free slot in device table: */ -	for (devnum = 0; devnum < LINE6_MAX_DEVICES; ++devnum) -		if (line6_devices[devnum] == NULL) -			break; - -	if (devnum == LINE6_MAX_DEVICES) { -		ret = -ENODEV; -		goto err_put; -	} -  	/* initialize device info: */  	properties = &line6_properties_table[devtype];  	dev_info(&interface->dev, "Line6 %s found\n", properties->name); @@ -794,6 +672,7 @@ static int line6_probe(struct usb_interface *interface,  		}  		break; +	case LINE6_DEVID_PODHD500:  	case LINE6_DEVID_PODX3:  	case LINE6_DEVID_PODX3LIVE:  		switch (interface_number) { @@ -812,6 +691,8 @@ static int line6_probe(struct usb_interface *interface,  	case LINE6_DEVID_BASSPODXTPRO:  	case LINE6_DEVID_PODXT:  	case LINE6_DEVID_PODXTPRO: +	case LINE6_DEVID_PODHD300: +	case LINE6_DEVID_PODHD400:  		alternate = 5;  		break; @@ -865,6 +746,19 @@ static int line6_probe(struct usb_interface *interface,  		ep_write = 0x03;  		break; +	case LINE6_DEVID_PODHD300: +	case LINE6_DEVID_PODHD400: +		size = sizeof(struct usb_line6_podhd); +		ep_read = 0x84; +		ep_write = 0x03; +		break; + +	case LINE6_DEVID_PODHD500: +		size = sizeof(struct usb_line6_podhd); +		ep_read = 0x81; +		ep_write = 0x01; +		break; +  	case LINE6_DEVID_POCKETPOD:  		size = sizeof(struct usb_line6_pod);  		ep_read = 0x82; @@ -923,16 +817,14 @@ static int line6_probe(struct usb_interface *interface,  	}  	if (size == 0) { -		dev_err(line6->ifcdev, +		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) { -		dev_err(&interface->dev, "Out of memory\n");  		ret = -ENODEV;  		goto err_put;  	} @@ -971,18 +863,14 @@ static int line6_probe(struct usb_interface *interface,  		/* initialize USB buffers: */  		line6->buffer_listen =  		    kmalloc(LINE6_BUFSIZE_LISTEN, GFP_KERNEL); -  		if (line6->buffer_listen == NULL) { -			dev_err(&interface->dev, "Out of memory\n");  			ret = -ENOMEM;  			goto err_destruct;  		}  		line6->buffer_message =  		    kmalloc(LINE6_MESSAGE_MAXLEN, GFP_KERNEL); -  		if (line6->buffer_message == NULL) { -			dev_err(&interface->dev, "Out of memory\n");  			ret = -ENOMEM;  			goto err_destruct;  		} @@ -1017,6 +905,13 @@ static int line6_probe(struct usb_interface *interface,  		ret = line6_pod_init(interface, (struct usb_line6_pod *)line6);  		break; +	case LINE6_DEVID_PODHD300: +	case LINE6_DEVID_PODHD400: +	case LINE6_DEVID_PODHD500: +		ret = line6_podhd_init(interface, +				       (struct usb_line6_podhd *)line6); +		break; +  	case LINE6_DEVID_PODXTLIVE:  		switch (interface_number) {  		case PODXTLIVE_INTERFACE_POD: @@ -1075,7 +970,6 @@ static int line6_probe(struct usb_interface *interface,  	dev_info(&interface->dev, "Line6 %s now attached\n",  		 line6->properties->name); -	line6_devices[devnum] = line6;  	switch (product) {  	case LINE6_DEVID_PODX3: @@ -1094,8 +988,6 @@ static int line6_probe(struct usb_interface *interface,  err_destruct:  	line6_destruct(interface);  err_put: -	usb_put_intf(interface); -	usb_put_dev(usbdev);  	return ret;  } @@ -1106,7 +998,7 @@ static void line6_disconnect(struct usb_interface *interface)  {  	struct usb_line6 *line6;  	struct usb_device *usbdev; -	int interface_number, i; +	int interface_number;  	if (interface == NULL)  		return; @@ -1129,7 +1021,7 @@ static void line6_disconnect(struct usb_interface *interface)  			dev_err(line6->ifcdev,  				"driver bug: inconsistent usb device\n"); -		switch (line6->usbdev->descriptor.idProduct) { +		switch (le16_to_cpu(line6->usbdev->descriptor.idProduct)) {  		case LINE6_DEVID_BASSPODXT:  		case LINE6_DEVID_BASSPODXTLIVE:  		case LINE6_DEVID_BASSPODXTPRO: @@ -1141,6 +1033,12 @@ static void line6_disconnect(struct usb_interface *interface)  			line6_pod_disconnect(interface);  			break; +		case LINE6_DEVID_PODHD300: +		case LINE6_DEVID_PODHD400: +		case LINE6_DEVID_PODHD500: +			line6_podhd_disconnect(interface); +			break; +  		case LINE6_DEVID_PODXTLIVE:  			switch (interface_number) {  			case PODXTLIVE_INTERFACE_POD: @@ -1174,10 +1072,6 @@ static void line6_disconnect(struct usb_interface *interface)  		dev_info(&interface->dev, "Line6 %s now disconnected\n",  			 line6->properties->name); - -		for (i = LINE6_MAX_DEVICES; i--;) -			if (line6_devices[i] == line6) -				line6_devices[i] = NULL;  	}  	line6_destruct(interface); @@ -1232,7 +1126,7 @@ static int line6_reset_resume(struct usb_interface *interface)  {  	struct usb_line6 *line6 = usb_get_intfdata(interface); -	switch (line6->usbdev->descriptor.idProduct) { +	switch (le16_to_cpu(line6->usbdev->descriptor.idProduct)) {  	case LINE6_DEVID_PODSTUDIO_GX:  	case LINE6_DEVID_PODSTUDIO_UX1:  	case LINE6_DEVID_PODSTUDIO_UX2: @@ -1260,69 +1154,7 @@ static struct usb_driver line6_driver = {  	.id_table = line6_id_table,  }; -/* -	Module initialization. -*/ -static int __init line6_init(void) -{ -	int i, retval; - -	printk(KERN_INFO "%s driver version %s\n", DRIVER_NAME, DRIVER_VERSION); - -	for (i = LINE6_MAX_DEVICES; i--;) -		line6_devices[i] = NULL; - -	retval = usb_register(&line6_driver); - -	if (retval) { -		err("usb_register failed. Error number %d", retval); -		return retval; -	} - -	line6_request_version = kmalloc(sizeof(line6_request_version0), -					GFP_KERNEL); - -	if (line6_request_version == NULL) { -		err("Out of memory"); -		return -ENOMEM; -	} - -	memcpy((char *)line6_request_version, line6_request_version0, -	       sizeof(line6_request_version0)); - -	return retval; -} - -/* -	Module cleanup. -*/ -static void __exit line6_exit(void) -{ -	int i; -	struct usb_line6 *line6; -	struct snd_line6_pcm *line6pcm; - -	/* stop all PCM channels */ -	for (i = LINE6_MAX_DEVICES; i--;) { -		line6 = line6_devices[i]; - -		if (line6 == NULL) -			continue; - -		line6pcm = line6->line6pcm; - -		if (line6pcm == NULL) -			continue; - -		line6_pcm_stop(line6pcm, ~0); -	} - -	usb_deregister(&line6_driver); -	kfree(line6_request_version); -} - -module_init(line6_init); -module_exit(line6_exit); +module_usb_driver(line6_driver);  MODULE_AUTHOR(DRIVER_AUTHOR);  MODULE_DESCRIPTION(DRIVER_DESC); diff --git a/drivers/staging/line6/driver.h b/drivers/staging/line6/driver.h index 553192f4931..16e3fc2f1f1 100644 --- a/drivers/staging/line6/driver.h +++ b/drivers/staging/line6/driver.h @@ -20,12 +20,7 @@  #define DRIVER_NAME "line6usb" -#if defined(CONFIG_LINE6_USB_DUMP_CTRL) || defined(CONFIG_LINE6_USB_DUMP_MIDI) || defined(CONFIG_LINE6_USB_DUMP_PCM) -#define CONFIG_LINE6_USB_DUMP_ANY -#endif -  #define LINE6_TIMEOUT 1 -#define LINE6_MAX_DEVICES 8  #define LINE6_BUFSIZE_LISTEN 32  #define LINE6_MESSAGE_MAXLEN 256 @@ -53,14 +48,8 @@  #define LINE6_CHANNEL_MASK 0x0f -#ifdef CONFIG_LINE6_USB_DEBUG -#define DEBUG_MESSAGES(x) (x) -#else -#define DEBUG_MESSAGES(x) -#endif -  #define MISSING_CASE	\ -	printk(KERN_ERR "line6usb driver bug: missing case in %s:%d\n", \ +	pr_err("line6usb driver bug: missing case in %s:%d\n", \  		__FILE__, __LINE__)  #define CHECK_RETURN(x)		\ @@ -78,7 +67,6 @@ do {					\  } while (0)  extern const unsigned char line6_midi_id[3]; -extern struct usb_line6 *line6_devices[LINE6_MAX_DEVICES];  static const int SYSEX_DATA_OFS = sizeof(line6_midi_id) + 3;  static const int SYSEX_EXTRA_SIZE = sizeof(line6_midi_id) + 4; @@ -88,6 +76,11 @@ static const int SYSEX_EXTRA_SIZE = sizeof(line6_midi_id) + 4;  */  struct line6_properties {  	/** +		 Bit identifying this device in the line6usb driver. +	*/ +	int device_bit; + +	/**  		 Card id string (maximum 16 characters).  		 This can be used to address the device in ALSA programs as  		 "default:CARD=<id>" @@ -100,11 +93,6 @@ struct line6_properties {  	const char *name;  	/** -		 Bit identifying this device in the line6usb driver. -	*/ -	int device_bit; - -	/**  		 Bit vector defining this device's capabilities in the  		 line6usb driver.  	*/ @@ -202,36 +190,26 @@ extern char *line6_alloc_sysex_buffer(struct usb_line6 *line6, int code1,  				      int code2, int size);  extern ssize_t line6_nop_read(struct device *dev,  			      struct device_attribute *attr, char *buf); -extern ssize_t line6_nop_write(struct device *dev, -			       struct device_attribute *attr, -			       const char *buf, size_t count);  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, int value); +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,  				    const char *buffer, int size); -extern int line6_send_sysex_message_async(struct usb_line6 *line6, -					  const char *buffer, int size);  extern ssize_t line6_set_raw(struct device *dev, struct device_attribute *attr,  			     const char *buf, size_t count);  extern void line6_start_timer(struct timer_list *timer, unsigned int msecs, -			      void (*function) (unsigned long), +			      void (*function)(unsigned long),  			      unsigned long data);  extern int line6_transmit_parameter(struct usb_line6 *line6, int param, -				    int value); +				    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); -#ifdef CONFIG_LINE6_USB_DUMP_ANY -extern void line6_write_hexdump(struct usb_line6 *line6, char dir, -				const unsigned char *buffer, int size); -#endif -  #endif diff --git a/drivers/staging/line6/dumprequest.c b/drivers/staging/line6/dumprequest.c deleted file mode 100644 index 60c7bae3ad3..00000000000 --- a/drivers/staging/line6/dumprequest.c +++ /dev/null @@ -1,135 +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 <linux/slab.h> - -#include "driver.h" -#include "dumprequest.h" - -/* -	Set "dump in progress" flag. -*/ -void line6_dump_started(struct line6_dump_request *l6dr, int dest) -{ -	l6dr->in_progress = dest; -} - -/* -	Invalidate current channel, i.e., set "dump in progress" flag. -	Reading from the "dump" special file blocks until dump is completed. -*/ -void line6_invalidate_current(struct line6_dump_request *l6dr) -{ -	line6_dump_started(l6dr, LINE6_DUMP_CURRENT); -} - -/* -	Clear "dump in progress" flag and notify waiting processes. -*/ -void line6_dump_finished(struct line6_dump_request *l6dr) -{ -	l6dr->in_progress = LINE6_DUMP_NONE; -	wake_up(&l6dr->wait); -} - -/* -	Send an asynchronous channel dump request. -*/ -int line6_dump_request_async(struct line6_dump_request *l6dr, -			     struct usb_line6 *line6, int num, int dest) -{ -	int ret; -	line6_dump_started(l6dr, dest); -	ret = line6_send_raw_message_async(line6, l6dr->reqbufs[num].buffer, -					   l6dr->reqbufs[num].length); - -	if (ret < 0) -		line6_dump_finished(l6dr); - -	return ret; -} - -/* -	Wait for completion (interruptible). -*/ -int line6_dump_wait_interruptible(struct line6_dump_request *l6dr) -{ -	return wait_event_interruptible(l6dr->wait, -					l6dr->in_progress == LINE6_DUMP_NONE); -} - -/* -	Wait for completion. -*/ -void line6_dump_wait(struct line6_dump_request *l6dr) -{ -	wait_event(l6dr->wait, l6dr->in_progress == LINE6_DUMP_NONE); -} - -/* -	Wait for completion (with timeout). -*/ -int line6_dump_wait_timeout(struct line6_dump_request *l6dr, long timeout) -{ -	return wait_event_timeout(l6dr->wait, -				  l6dr->in_progress == LINE6_DUMP_NONE, -				  timeout); -} - -/* -	Initialize dump request buffer. -*/ -int line6_dumpreq_initbuf(struct line6_dump_request *l6dr, const void *buf, -			  size_t len, int num) -{ -	l6dr->reqbufs[num].buffer = kmemdup(buf, len, GFP_KERNEL); -	if (l6dr->reqbufs[num].buffer == NULL) -		return -ENOMEM; -	l6dr->reqbufs[num].length = len; -	return 0; -} - -/* -	Initialize dump request data structure (including one buffer). -*/ -int line6_dumpreq_init(struct line6_dump_request *l6dr, const void *buf, -		       size_t len) -{ -	int ret; -	ret = line6_dumpreq_initbuf(l6dr, buf, len, 0); -	if (ret < 0) -		return ret; -	init_waitqueue_head(&l6dr->wait); -	return 0; -} - -/* -	Destruct dump request data structure. -*/ -void line6_dumpreq_destructbuf(struct line6_dump_request *l6dr, int num) -{ -	if (l6dr == NULL) -		return; -	if (l6dr->reqbufs[num].buffer == NULL) -		return; -	kfree(l6dr->reqbufs[num].buffer); -	l6dr->reqbufs[num].buffer = NULL; -} - -/* -	Destruct dump request data structure. -*/ -void line6_dumpreq_destruct(struct line6_dump_request *l6dr) -{ -	if (l6dr->reqbufs[0].buffer == NULL) -		return; -	line6_dumpreq_destructbuf(l6dr, 0); -} diff --git a/drivers/staging/line6/dumprequest.h b/drivers/staging/line6/dumprequest.h deleted file mode 100644 index c17a262fad2..00000000000 --- a/drivers/staging/line6/dumprequest.h +++ /dev/null @@ -1,76 +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 DUMPREQUEST_H -#define DUMPREQUEST_H - -#include <linux/usb.h> -#include <linux/wait.h> -#include <sound/core.h> - -enum { -	LINE6_DUMP_NONE, -	LINE6_DUMP_CURRENT -}; - -struct line6_dump_reqbuf { -	/** -		 Buffer for dump requests. -	*/ -	unsigned char *buffer; - -	/** -		 Size of dump request. -	*/ -	size_t length; -}; - -/** -	 Provides the functionality to request channel/model/... dump data from a -	 Line6 device. -*/ -struct line6_dump_request { -	/** -		 Wait queue for access to program dump data. -	*/ -	wait_queue_head_t wait; - -	/** -		 Indicates an unfinished program dump request. -		 0: no dump -		 1: dump current settings -		 Other device-specific values are also allowed. -	*/ -	int in_progress; - -	/** -		 Dump request buffers -	*/ -	struct line6_dump_reqbuf reqbufs[1]; -}; - -extern void line6_dump_finished(struct line6_dump_request *l6dr); -extern int line6_dump_request_async(struct line6_dump_request *l6dr, -				    struct usb_line6 *line6, int num, int dest); -extern void line6_dump_started(struct line6_dump_request *l6dr, int dest); -extern void line6_dumpreq_destruct(struct line6_dump_request *l6dr); -extern void line6_dumpreq_destructbuf(struct line6_dump_request *l6dr, int num); -extern int line6_dumpreq_init(struct line6_dump_request *l6dr, const void *buf, -			      size_t len); -extern int line6_dumpreq_initbuf(struct line6_dump_request *l6dr, -				 const void *buf, size_t len, int num); -extern void line6_invalidate_current(struct line6_dump_request *l6dr); -extern void line6_dump_wait(struct line6_dump_request *l6dr); -extern int line6_dump_wait_interruptible(struct line6_dump_request *l6dr); -extern int line6_dump_wait_timeout(struct line6_dump_request *l6dr, -				   long timeout); - -#endif diff --git a/drivers/staging/line6/midi.c b/drivers/staging/line6/midi.c index 4304dfe6c16..1ac343b649c 100644 --- a/drivers/staging/line6/midi.c +++ b/drivers/staging/line6/midi.c @@ -45,9 +45,9 @@ static void line6_midi_transmit(struct snd_rawmidi_substream *substream)  	struct usb_line6 *line6 =  	    line6_rawmidi_substream_midi(substream)->line6;  	struct snd_line6_midi *line6midi = line6->line6midi; -	struct MidiBuffer *mb = &line6midi->midibuf_out; +	struct midi_buffer *mb = &line6midi->midibuf_out;  	unsigned long flags; -	unsigned char chunk[line6->max_packet_size]; +	unsigned char chunk[LINE6_FALLBACK_MAXPACKETSIZE];  	int req, done;  	spin_lock_irqsave(&line6->line6midi->midi_transmit_lock, flags); @@ -59,23 +59,17 @@ static void line6_midi_transmit(struct snd_rawmidi_substream *substream)  		if (done == 0)  			break; -#ifdef CONFIG_LINE6_USB_DUMP_MIDI -		line6_write_hexdump(line6, 's', chunk, done); -#endif  		line6_midibuf_write(mb, chunk, done);  		snd_rawmidi_transmit_ack(substream, done);  	}  	for (;;) { -		done = line6_midibuf_read(mb, chunk, line6->max_packet_size); +		done = line6_midibuf_read(mb, chunk, +					  LINE6_FALLBACK_MAXPACKETSIZE);  		if (done == 0)  			break; -		if (line6_midibuf_skip_message -		    (mb, line6midi->midi_mask_transmit)) -			continue; -  		send_midi_async(line6, chunk, done);  	} @@ -127,23 +121,19 @@ static int send_midi_async(struct usb_line6 *line6, unsigned char *data,  	urb = usb_alloc_urb(0, GFP_ATOMIC); -	if (urb == 0) { +	if (urb == NULL) {  		dev_err(line6->ifcdev, "Out of memory\n");  		return -ENOMEM;  	} -#ifdef CONFIG_LINE6_USB_DUMP_CTRL -	line6_write_hexdump(line6, 'S', data, length); -#endif -	transfer_buffer = kmalloc(length, GFP_ATOMIC); +	transfer_buffer = kmemdup(data, length, GFP_ATOMIC); -	if (transfer_buffer == 0) { +	if (transfer_buffer == NULL) {  		usb_free_urb(urb);  		dev_err(line6->ifcdev, "Out of memory\n");  		return -ENOMEM;  	} -	memcpy(transfer_buffer, data, length);  	usb_fill_int_urb(urb, line6->usbdev,  			 usb_sndbulkpipe(line6->usbdev,  					 line6->ep_control_write), @@ -155,30 +145,10 @@ static int send_midi_async(struct usb_line6 *line6, unsigned char *data,  	if (retval < 0) {  		dev_err(line6->ifcdev, "usb_submit_urb failed\n");  		usb_free_urb(urb); -		return -EINVAL; +		return retval;  	}  	++line6->line6midi->num_active_send_urbs; - -	switch (line6->usbdev->descriptor.idProduct) { -	case LINE6_DEVID_BASSPODXT: -	case LINE6_DEVID_BASSPODXTLIVE: -	case LINE6_DEVID_BASSPODXTPRO: -	case LINE6_DEVID_PODXT: -	case LINE6_DEVID_PODXTLIVE: -	case LINE6_DEVID_PODXTPRO: -	case LINE6_DEVID_POCKETPOD: -		line6_pod_midi_postprocess((struct usb_line6_pod *)line6, data, -					   length); -		break; - -	case LINE6_DEVID_VARIAX: -		break; - -	default: -		MISSING_CASE; -	} -  	return 0;  } @@ -213,6 +183,7 @@ static void line6_midi_output_drain(struct snd_rawmidi_substream *substream)  	struct usb_line6 *line6 =  	    line6_rawmidi_substream_midi(substream)->line6;  	struct snd_line6_midi *midi = line6->line6midi; +  	wait_event_interruptible(midi->send_wait,  				 midi->num_active_send_urbs == 0);  } @@ -236,7 +207,7 @@ static void line6_midi_input_trigger(struct snd_rawmidi_substream *substream,  	if (up)  		line6->line6midi->substream_receive = substream;  	else -		line6->line6midi->substream_receive = 0; +		line6->line6midi->substream_receive = NULL;  }  static struct snd_rawmidi_ops line6_midi_output_ops = { @@ -286,83 +257,11 @@ static int snd_line6_new_midi(struct snd_line6_midi *line6midi)  	return 0;  } -/* -	"read" request on "midi_mask_transmit" special file. -*/ -static ssize_t midi_get_midi_mask_transmit(struct device *dev, -					   struct device_attribute *attr, -					   char *buf) -{ -	struct usb_interface *interface = to_usb_interface(dev); -	struct usb_line6 *line6 = usb_get_intfdata(interface); -	return sprintf(buf, "%d\n", line6->line6midi->midi_mask_transmit); -} - -/* -	"write" request on "midi_mask" special file. -*/ -static ssize_t midi_set_midi_mask_transmit(struct device *dev, -					   struct device_attribute *attr, -					   const char *buf, size_t count) -{ -	struct usb_interface *interface = to_usb_interface(dev); -	struct usb_line6 *line6 = usb_get_intfdata(interface); -	unsigned long value; -	int ret; - -	ret = strict_strtoul(buf, 10, &value); -	if (ret) -		return ret; - -	line6->line6midi->midi_mask_transmit = value; -	return count; -} - -/* -	"read" request on "midi_mask_receive" special file. -*/ -static ssize_t midi_get_midi_mask_receive(struct device *dev, -					  struct device_attribute *attr, -					  char *buf) -{ -	struct usb_interface *interface = to_usb_interface(dev); -	struct usb_line6 *line6 = usb_get_intfdata(interface); -	return sprintf(buf, "%d\n", line6->line6midi->midi_mask_receive); -} - -/* -	"write" request on "midi_mask" special file. -*/ -static ssize_t midi_set_midi_mask_receive(struct device *dev, -					  struct device_attribute *attr, -					  const char *buf, size_t count) -{ -	struct usb_interface *interface = to_usb_interface(dev); -	struct usb_line6 *line6 = usb_get_intfdata(interface); -	unsigned long value; -	int ret; - -	ret = strict_strtoul(buf, 10, &value); -	if (ret) -		return ret; - -	line6->line6midi->midi_mask_receive = value; -	return count; -} - -static DEVICE_ATTR(midi_mask_transmit, S_IWUGO | S_IRUGO, -		   midi_get_midi_mask_transmit, midi_set_midi_mask_transmit); -static DEVICE_ATTR(midi_mask_receive, S_IWUGO | S_IRUGO, -		   midi_get_midi_mask_receive, midi_set_midi_mask_receive); -  /* MIDI device destructor */  static int snd_line6_midi_free(struct snd_device *device)  {  	struct snd_line6_midi *line6midi = device->device_data; -	device_remove_file(line6midi->line6->ifcdev, -			   &dev_attr_midi_mask_transmit); -	device_remove_file(line6midi->line6->ifcdev, -			   &dev_attr_midi_mask_receive); +  	line6_midibuf_destroy(&line6midi->midibuf_in);  	line6_midibuf_destroy(&line6midi->midibuf_out);  	return 0; @@ -391,16 +290,19 @@ int line6_init_midi(struct usb_line6 *line6)  		return -ENOMEM;  	err = line6_midibuf_init(&line6midi->midibuf_in, MIDI_BUFFER_SIZE, 0); -	if (err < 0) +	if (err < 0) { +		kfree(line6midi);  		return err; +	}  	err = line6_midibuf_init(&line6midi->midibuf_out, MIDI_BUFFER_SIZE, 1); -	if (err < 0) +	if (err < 0) { +		kfree(line6midi->midibuf_in.buf); +		kfree(line6midi);  		return err; +	}  	line6midi->line6 = line6; -	line6midi->midi_mask_transmit = 1; -	line6midi->midi_mask_receive = 4;  	line6->line6midi = line6midi;  	err = snd_device_new(line6->card, SNDRV_DEV_RAWMIDI, line6midi, @@ -408,20 +310,10 @@ int line6_init_midi(struct usb_line6 *line6)  	if (err < 0)  		return err; -	snd_card_set_dev(line6->card, line6->ifcdev); -  	err = snd_line6_new_midi(line6midi);  	if (err < 0)  		return err; -	err = device_create_file(line6->ifcdev, &dev_attr_midi_mask_transmit); -	if (err < 0) -		return err; - -	err = device_create_file(line6->ifcdev, &dev_attr_midi_mask_receive); -	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); diff --git a/drivers/staging/line6/midi.h b/drivers/staging/line6/midi.h index b73a025d8be..78f903fb4d4 100644 --- a/drivers/staging/line6/midi.h +++ b/drivers/staging/line6/midi.h @@ -55,24 +55,14 @@ struct snd_line6_midi {  	wait_queue_head_t send_wait;  	/** -		 Bit mask for output MIDI channels. -	*/ -	int midi_mask_transmit; - -	/** -		 Bit mask for input MIDI channels. -	*/ -	int midi_mask_receive; - -	/**  		 Buffer for incoming MIDI stream.  	*/ -	struct MidiBuffer midibuf_in; +	struct midi_buffer midibuf_in;  	/**  		 Buffer for outgoing MIDI stream.  	*/ -	struct MidiBuffer midibuf_out; +	struct midi_buffer midibuf_out;  };  extern int line6_init_midi(struct usb_line6 *line6); diff --git a/drivers/staging/line6/midibuf.c b/drivers/staging/line6/midibuf.c index 7b532e5ce8b..f0adb7baa60 100644 --- a/drivers/staging/line6/midibuf.c +++ b/drivers/staging/line6/midibuf.c @@ -33,23 +33,23 @@ static int midibuf_message_length(unsigned char code)  	}  } -static int midibuf_is_empty(struct MidiBuffer *this) +static int midibuf_is_empty(struct midi_buffer *this)  {  	return (this->pos_read == this->pos_write) && !this->full;  } -static int midibuf_is_full(struct MidiBuffer *this) +static int midibuf_is_full(struct midi_buffer *this)  {  	return this->full;  } -void line6_midibuf_reset(struct MidiBuffer *this) +void line6_midibuf_reset(struct midi_buffer *this)  {  	this->pos_read = this->pos_write = this->full = 0;  	this->command_prev = -1;  } -int line6_midibuf_init(struct MidiBuffer *this, int size, int split) +int line6_midibuf_init(struct midi_buffer *this, int size, int split)  {  	this->buf = kmalloc(size, GFP_KERNEL); @@ -62,14 +62,14 @@ int line6_midibuf_init(struct MidiBuffer *this, int size, int split)  	return 0;  } -void line6_midibuf_status(struct MidiBuffer *this) +void line6_midibuf_status(struct midi_buffer *this)  { -	printk(KERN_DEBUG "midibuf size=%d split=%d pos_read=%d pos_write=%d " -	       "full=%d command_prev=%02x\n", this->size, this->split, -	       this->pos_read, this->pos_write, this->full, this->command_prev); +	pr_debug("midibuf size=%d split=%d pos_read=%d pos_write=%d full=%d command_prev=%02x\n", +		 this->size, this->split, this->pos_read, this->pos_write, +		 this->full, this->command_prev);  } -int line6_midibuf_bytes_free(struct MidiBuffer *this) +int line6_midibuf_bytes_free(struct midi_buffer *this)  {  	return  	    midibuf_is_full(this) ? @@ -78,7 +78,7 @@ int line6_midibuf_bytes_free(struct MidiBuffer *this)  	    1;  } -int line6_midibuf_bytes_used(struct MidiBuffer *this) +int line6_midibuf_bytes_used(struct midi_buffer *this)  {  	return  	    midibuf_is_empty(this) ? @@ -87,7 +87,7 @@ int line6_midibuf_bytes_used(struct MidiBuffer *this)  	    1;  } -int line6_midibuf_write(struct MidiBuffer *this, unsigned char *data, +int line6_midibuf_write(struct midi_buffer *this, unsigned char *data,  			int length)  {  	int bytes_free; @@ -130,7 +130,8 @@ int line6_midibuf_write(struct MidiBuffer *this, unsigned char *data,  	return length + skip_active_sense;  } -int line6_midibuf_read(struct MidiBuffer *this, unsigned char *data, int length) +int line6_midibuf_read(struct midi_buffer *this, unsigned char *data, +		       int length)  {  	int bytes_used;  	int length1, length2; @@ -234,7 +235,7 @@ int line6_midibuf_read(struct MidiBuffer *this, unsigned char *data, int length)  	return length + repeat;  } -int line6_midibuf_ignore(struct MidiBuffer *this, int length) +int line6_midibuf_ignore(struct midi_buffer *this, int length)  {  	int bytes_used = line6_midibuf_bytes_used(this); @@ -246,7 +247,7 @@ int line6_midibuf_ignore(struct MidiBuffer *this, int length)  	return length;  } -int line6_midibuf_skip_message(struct MidiBuffer *this, unsigned short mask) +int line6_midibuf_skip_message(struct midi_buffer *this, unsigned short mask)  {  	int cmd = this->command_prev; @@ -257,7 +258,7 @@ int line6_midibuf_skip_message(struct MidiBuffer *this, unsigned short mask)  	return 0;  } -void line6_midibuf_destroy(struct MidiBuffer *this) +void line6_midibuf_destroy(struct midi_buffer *this)  {  	kfree(this->buf);  	this->buf = NULL; diff --git a/drivers/staging/line6/midibuf.h b/drivers/staging/line6/midibuf.h index 444cb3a12d7..707482b940e 100644 --- a/drivers/staging/line6/midibuf.h +++ b/drivers/staging/line6/midibuf.h @@ -12,7 +12,7 @@  #ifndef MIDIBUF_H  #define MIDIBUF_H -struct MidiBuffer { +struct midi_buffer {  	unsigned char *buf;  	int size;  	int split; @@ -21,18 +21,18 @@ struct MidiBuffer {  	int command_prev;  }; -extern int line6_midibuf_bytes_used(struct MidiBuffer *mb); -extern int line6_midibuf_bytes_free(struct MidiBuffer *mb); -extern void line6_midibuf_destroy(struct MidiBuffer *mb); -extern int line6_midibuf_ignore(struct MidiBuffer *mb, int length); -extern int line6_midibuf_init(struct MidiBuffer *mb, int size, int split); -extern int line6_midibuf_read(struct MidiBuffer *mb, unsigned char *data, +extern int line6_midibuf_bytes_used(struct midi_buffer *mb); +extern int line6_midibuf_bytes_free(struct midi_buffer *mb); +extern void line6_midibuf_destroy(struct midi_buffer *mb); +extern int line6_midibuf_ignore(struct midi_buffer *mb, int length); +extern int line6_midibuf_init(struct midi_buffer *mb, int size, int split); +extern int line6_midibuf_read(struct midi_buffer *mb, unsigned char *data,  			      int length); -extern void line6_midibuf_reset(struct MidiBuffer *mb); -extern int line6_midibuf_skip_message(struct MidiBuffer *mb, +extern void line6_midibuf_reset(struct midi_buffer *mb); +extern int line6_midibuf_skip_message(struct midi_buffer *mb,  				      unsigned short mask); -extern void line6_midibuf_status(struct MidiBuffer *mb); -extern int line6_midibuf_write(struct MidiBuffer *mb, unsigned char *data, +extern void line6_midibuf_status(struct midi_buffer *mb); +extern int line6_midibuf_write(struct midi_buffer *mb, unsigned char *data,  			       int length);  #endif diff --git a/drivers/staging/line6/pcm.c b/drivers/staging/line6/pcm.c index e54770e34d2..a3136b189ee 100644 --- a/drivers/staging/line6/pcm.c +++ b/drivers/staging/line6/pcm.c @@ -34,8 +34,8 @@ static struct snd_line6_pcm *dev2pcm(struct device *dev)  /*  	"read" request on "impulse_volume" special file.  */ -static ssize_t pcm_get_impulse_volume(struct device *dev, -				      struct device_attribute *attr, char *buf) +static ssize_t impulse_volume_show(struct device *dev, +				   struct device_attribute *attr, char *buf)  {  	return sprintf(buf, "%d\n", dev2pcm(dev)->impulse_volume);  } @@ -43,27 +43,34 @@ static ssize_t pcm_get_impulse_volume(struct device *dev,  /*  	"write" request on "impulse_volume" special file.  */ -static ssize_t pcm_set_impulse_volume(struct device *dev, -				      struct device_attribute *attr, -				      const char *buf, size_t count) +static ssize_t impulse_volume_store(struct device *dev, +				    struct device_attribute *attr, +				    const char *buf, size_t count)  {  	struct snd_line6_pcm *line6pcm = dev2pcm(dev); -	int value = simple_strtoul(buf, NULL, 10); +	int value; +	int ret; + +	ret = kstrtoint(buf, 10, &value); +	if (ret < 0) +		return ret; +  	line6pcm->impulse_volume = value;  	if (value > 0) -		line6_pcm_start(line6pcm, MASK_PCM_IMPULSE); +		line6_pcm_acquire(line6pcm, LINE6_BITS_PCM_IMPULSE);  	else -		line6_pcm_stop(line6pcm, MASK_PCM_IMPULSE); +		line6_pcm_release(line6pcm, LINE6_BITS_PCM_IMPULSE);  	return count;  } +static DEVICE_ATTR_RW(impulse_volume);  /*  	"read" request on "impulse_period" special file.  */ -static ssize_t pcm_get_impulse_period(struct device *dev, -				      struct device_attribute *attr, char *buf) +static ssize_t impulse_period_show(struct device *dev, +				   struct device_attribute *attr, char *buf)  {  	return sprintf(buf, "%d\n", dev2pcm(dev)->impulse_period);  } @@ -71,127 +78,148 @@ static ssize_t pcm_get_impulse_period(struct device *dev,  /*  	"write" request on "impulse_period" special file.  */ -static ssize_t pcm_set_impulse_period(struct device *dev, -				      struct device_attribute *attr, -				      const char *buf, size_t count) +static ssize_t impulse_period_store(struct device *dev, +				    struct device_attribute *attr, +				    const char *buf, size_t count)  { -	dev2pcm(dev)->impulse_period = simple_strtoul(buf, NULL, 10); +	int value; +	int ret; + +	ret = kstrtoint(buf, 10, &value); +	if (ret < 0) +		return ret; + +	dev2pcm(dev)->impulse_period = value;  	return count;  } - -static DEVICE_ATTR(impulse_volume, S_IWUGO | S_IRUGO, pcm_get_impulse_volume, -		   pcm_set_impulse_volume); -static DEVICE_ATTR(impulse_period, S_IWUGO | S_IRUGO, pcm_get_impulse_period, -		   pcm_set_impulse_period); +static DEVICE_ATTR_RW(impulse_period);  #endif -int line6_pcm_start(struct snd_line6_pcm *line6pcm, int channels) +static bool test_flags(unsigned long flags0, unsigned long flags1, +		       unsigned long mask)  { -	unsigned long flags_old = -	    __sync_fetch_and_or(&line6pcm->flags, channels); -	unsigned long flags_new = flags_old | channels; -	int err = 0; - -#if LINE6_BACKUP_MONITOR_SIGNAL -	if (!(line6pcm->line6->properties->capabilities & LINE6_BIT_HWMON)) { -		line6pcm->prev_fbuf = -		    kmalloc(LINE6_ISO_PACKETS * line6pcm->max_packet_size, -			    GFP_KERNEL); - -		if (!line6pcm->prev_fbuf) { -			dev_err(line6pcm->line6->ifcdev, -				"cannot malloc monitor buffer\n"); -			return -ENOMEM; +	return ((flags0 & mask) == 0) && ((flags1 & mask) != 0); +} + +int line6_pcm_acquire(struct snd_line6_pcm *line6pcm, int channels) +{ +	unsigned long flags_old, flags_new, flags_final; +	int err; + +	do { +		flags_old = ACCESS_ONCE(line6pcm->flags); +		flags_new = flags_old | channels; +	} while (cmpxchg(&line6pcm->flags, flags_old, flags_new) != flags_old); + +	flags_final = flags_old; + +	line6pcm->prev_fbuf = NULL; + +	if (test_flags(flags_old, flags_new, LINE6_BITS_CAPTURE_BUFFER)) { +		/* Invoked multiple times in a row so allocate once only */ +		if (!line6pcm->buffer_in) { +			line6pcm->buffer_in = +				kmalloc(LINE6_ISO_BUFFERS * LINE6_ISO_PACKETS * +					line6pcm->max_packet_size, GFP_KERNEL); +			if (!line6pcm->buffer_in) { +				err = -ENOMEM; +				goto pcm_acquire_error; +			} + +			flags_final |= channels & LINE6_BITS_CAPTURE_BUFFER;  		}  	} -#else -	line6pcm->prev_fbuf = NULL; -#endif -	if (((flags_old & MASK_CAPTURE) == 0) && -	    ((flags_new & MASK_CAPTURE) != 0)) { +	if (test_flags(flags_old, flags_new, LINE6_BITS_CAPTURE_STREAM)) {  		/*  		   Waiting for completion of active URBs in the stop handler is  		   a bug, we therefore report an error if capturing is restarted  		   too soon.  		 */ -		if (line6pcm->active_urb_in | line6pcm->unlink_urb_in) +		if (line6pcm->active_urb_in | line6pcm->unlink_urb_in) { +			dev_err(line6pcm->line6->ifcdev, "Device not yet ready\n");  			return -EBUSY; - -		line6pcm->buffer_in = -		    kmalloc(LINE6_ISO_BUFFERS * LINE6_ISO_PACKETS * -			    line6pcm->max_packet_size, GFP_KERNEL); - -		if (!line6pcm->buffer_in) { -			dev_err(line6pcm->line6->ifcdev, -				"cannot malloc capture buffer\n"); -			return -ENOMEM;  		}  		line6pcm->count_in = 0;  		line6pcm->prev_fsize = 0;  		err = line6_submit_audio_in_all_urbs(line6pcm); -		if (err < 0) { -			__sync_fetch_and_and(&line6pcm->flags, ~channels); -			return err; +		if (err < 0) +			goto pcm_acquire_error; + +		flags_final |= channels & LINE6_BITS_CAPTURE_STREAM; +	} + +	if (test_flags(flags_old, flags_new, LINE6_BITS_PLAYBACK_BUFFER)) { +		/* Invoked multiple times in a row so allocate once only */ +		if (!line6pcm->buffer_out) { +			line6pcm->buffer_out = +				kmalloc(LINE6_ISO_BUFFERS * LINE6_ISO_PACKETS * +					line6pcm->max_packet_size, GFP_KERNEL); +			if (!line6pcm->buffer_out) { +				err = -ENOMEM; +				goto pcm_acquire_error; +			} + +			flags_final |= channels & LINE6_BITS_PLAYBACK_BUFFER;  		}  	} -	if (((flags_old & MASK_PLAYBACK) == 0) && -	    ((flags_new & MASK_PLAYBACK) != 0)) { +	if (test_flags(flags_old, flags_new, LINE6_BITS_PLAYBACK_STREAM)) {  		/* -		   See comment above regarding PCM restart. -		 */ -		if (line6pcm->active_urb_out | line6pcm->unlink_urb_out) +		  See comment above regarding PCM restart. +		*/ +		if (line6pcm->active_urb_out | line6pcm->unlink_urb_out) { +			dev_err(line6pcm->line6->ifcdev, "Device not yet ready\n");  			return -EBUSY; - -		line6pcm->buffer_out = -		    kmalloc(LINE6_ISO_BUFFERS * LINE6_ISO_PACKETS * -			    line6pcm->max_packet_size, GFP_KERNEL); - -		if (!line6pcm->buffer_out) { -			dev_err(line6pcm->line6->ifcdev, -				"cannot malloc playback buffer\n"); -			return -ENOMEM;  		}  		line6pcm->count_out = 0;  		err = line6_submit_audio_out_all_urbs(line6pcm); -		if (err < 0) { -			__sync_fetch_and_and(&line6pcm->flags, ~channels); -			return err; -		} +		if (err < 0) +			goto pcm_acquire_error; + +		flags_final |= channels & LINE6_BITS_PLAYBACK_STREAM;  	}  	return 0; + +pcm_acquire_error: +	/* +	   If not all requested resources/streams could be obtained, release +	   those which were successfully obtained (if any). +	*/ +	line6_pcm_release(line6pcm, flags_final & channels); +	return err;  } -int line6_pcm_stop(struct snd_line6_pcm *line6pcm, int channels) +int line6_pcm_release(struct snd_line6_pcm *line6pcm, int channels)  { -	unsigned long flags_old = -	    __sync_fetch_and_and(&line6pcm->flags, ~channels); -	unsigned long flags_new = flags_old & ~channels; +	unsigned long flags_old, flags_new; -	if (((flags_old & MASK_CAPTURE) != 0) && -	    ((flags_new & MASK_CAPTURE) == 0)) { +	do { +		flags_old = ACCESS_ONCE(line6pcm->flags); +		flags_new = flags_old & ~channels; +	} while (cmpxchg(&line6pcm->flags, flags_old, flags_new) != flags_old); + +	if (test_flags(flags_new, flags_old, LINE6_BITS_CAPTURE_STREAM))  		line6_unlink_audio_in_urbs(line6pcm); -		kfree(line6pcm->buffer_in); -		line6pcm->buffer_in = NULL; + +	if (test_flags(flags_new, flags_old, LINE6_BITS_CAPTURE_BUFFER)) { +		line6_wait_clear_audio_in_urbs(line6pcm); +		line6_free_capture_buffer(line6pcm);  	} -	if (((flags_old & MASK_PLAYBACK) != 0) && -	    ((flags_new & MASK_PLAYBACK) == 0)) { +	if (test_flags(flags_new, flags_old, LINE6_BITS_PLAYBACK_STREAM))  		line6_unlink_audio_out_urbs(line6pcm); -		kfree(line6pcm->buffer_out); -		line6pcm->buffer_out = NULL; + +	if (test_flags(flags_new, flags_old, LINE6_BITS_PLAYBACK_BUFFER)) { +		line6_wait_clear_audio_out_urbs(line6pcm); +		line6_free_playback_buffer(line6pcm);  	} -#if LINE6_BACKUP_MONITOR_SIGNAL -	if (line6pcm->prev_fbuf != NULL) -		kfree(line6pcm->prev_fbuf); -#endif  	return 0;  } @@ -205,7 +233,7 @@ int snd_line6_trigger(struct snd_pcm_substream *substream, int cmd)  	unsigned long flags;  	spin_lock_irqsave(&line6pcm->lock_trigger, flags); -	clear_bit(BIT_PREPARED, &line6pcm->flags); +	clear_bit(LINE6_INDEX_PREPARED, &line6pcm->flags);  	snd_pcm_group_for_each_entry(s, substream) {  		switch (s->stream) { @@ -361,8 +389,11 @@ static int snd_line6_pcm_free(struct snd_device *device)  */  static void pcm_disconnect_substream(struct snd_pcm_substream *substream)  { -	if (substream->runtime && snd_pcm_running(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); +	}  }  /* @@ -404,10 +435,13 @@ int line6_init_pcm(struct usb_line6 *line6,  	case LINE6_DEVID_PODXT:  	case LINE6_DEVID_PODXTLIVE:  	case LINE6_DEVID_PODXTPRO: +	case LINE6_DEVID_PODHD300: +	case LINE6_DEVID_PODHD400:  		ep_read = 0x82;  		ep_write = 0x01;  		break; +	case LINE6_DEVID_PODHD500:  	case LINE6_DEVID_PODX3:  	case LINE6_DEVID_PODX3LIVE:  		ep_read = 0x86; @@ -430,19 +464,18 @@ int line6_init_pcm(struct usb_line6 *line6,  		ep_write = 0x01;  		break; -		/* this is for interface_number == 1: -		   case LINE6_DEVID_TONEPORT_UX2: -		   case LINE6_DEVID_PODSTUDIO_UX2: -		   ep_read  = 0x87; -		   ep_write = 0x00; -		   break; -		 */ +	/* this is for interface_number == 1: +	case LINE6_DEVID_TONEPORT_UX2: +	case LINE6_DEVID_PODSTUDIO_UX2: +		ep_read  = 0x87; +		ep_write = 0x00; +		break; */  	default:  		MISSING_CASE;  	} -	line6pcm = kzalloc(sizeof(struct snd_line6_pcm), GFP_KERNEL); +	line6pcm = kzalloc(sizeof(*line6pcm), GFP_KERNEL);  	if (line6pcm == NULL)  		return -ENOMEM; @@ -452,9 +485,14 @@ int line6_init_pcm(struct usb_line6 *line6,  	line6pcm->line6 = line6;  	line6pcm->ep_audio_read = ep_read;  	line6pcm->ep_audio_write = ep_write; -	line6pcm->max_packet_size = usb_maxpacket(line6->usbdev, -						  usb_rcvintpipe(line6->usbdev, -								 ep_read), 0); + +	/* Read and write buffers are sized identically, so choose minimum */ +	line6pcm->max_packet_size = min( +			usb_maxpacket(line6->usbdev, +				usb_rcvisocpipe(line6->usbdev, ep_read), 0), +			usb_maxpacket(line6->usbdev, +				usb_sndisocpipe(line6->usbdev, ep_write), 1)); +  	line6pcm->properties = properties;  	line6->line6pcm = line6pcm; @@ -463,8 +501,6 @@ int line6_init_pcm(struct usb_line6 *line6,  	if (err < 0)  		return err; -	snd_card_set_dev(line6->card, line6->ifcdev); -  	err = snd_line6_new_pcm(line6pcm);  	if (err < 0)  		return err; @@ -509,7 +545,24 @@ int snd_line6_prepare(struct snd_pcm_substream *substream)  {  	struct snd_line6_pcm *line6pcm = snd_pcm_substream_chip(substream); -	if (!test_and_set_bit(BIT_PREPARED, &line6pcm->flags)) { +	switch (substream->stream) { +	case SNDRV_PCM_STREAM_PLAYBACK: +		if ((line6pcm->flags & LINE6_BITS_PLAYBACK_STREAM) == 0) +			line6_unlink_wait_clear_audio_out_urbs(line6pcm); + +		break; + +	case SNDRV_PCM_STREAM_CAPTURE: +		if ((line6pcm->flags & LINE6_BITS_CAPTURE_STREAM) == 0) +			line6_unlink_wait_clear_audio_in_urbs(line6pcm); + +		break; + +	default: +		MISSING_CASE; +	} + +	if (!test_and_set_bit(LINE6_INDEX_PREPARED, &line6pcm->flags)) {  		line6pcm->count_out = 0;  		line6pcm->pos_out = 0;  		line6pcm->pos_out_done = 0; diff --git a/drivers/staging/line6/pcm.h b/drivers/staging/line6/pcm.h index 77055b3724a..6aa0d46a289 100644 --- a/drivers/staging/line6/pcm.h +++ b/drivers/staging/line6/pcm.h @@ -39,9 +39,6 @@  #define LINE6_IMPULSE_DEFAULT_PERIOD 100  #endif -#define LINE6_BACKUP_MONITOR_SIGNAL 0 -#define LINE6_REUSE_DMA_AREA_FOR_PLAYBACK 0 -  /*  	Get substream from Line6 PCM data structure  */ @@ -49,57 +46,131 @@  		(line6pcm->pcm->streams[stream].substream)  /* -	PCM mode bits and masks. -	"ALSA": operations triggered by applications via ALSA -	"MONITOR": software monitoring -	"IMPULSE": optional impulse response operation +	PCM mode bits. + +	There are several features of the Line6 USB driver which require PCM +	data to be exchanged with the device: +	*) PCM playback and capture via ALSA +	*) software monitoring (for devices without hardware monitoring) +	*) optional impulse response measurement +	However, from the device's point of view, there is just a single +	capture and playback stream, which must be shared between these +	subsystems. It is therefore necessary to maintain the state of the +	subsystems with respect to PCM usage. We define several constants of +	the form LINE6_BIT_PCM_<subsystem>_<direction>_<resource> with the +	following meanings: +	*) <subsystem> is one of +	-) ALSA: PCM playback and capture via ALSA +	-) MONITOR: software monitoring +	-) IMPULSE: optional impulse response measurement +	*) <direction> is one of +	-) PLAYBACK: audio output (from host to device) +	-) CAPTURE: audio input (from device to host) +	*) <resource> is one of +	-) BUFFER: buffer required by PCM data stream +	-) STREAM: actual PCM data stream + +	The subsystems call line6_pcm_acquire() to acquire the (shared) +	resources needed for a particular operation (e.g., allocate the buffer +	for ALSA playback or start the capture stream for software monitoring). +	When a resource is no longer needed, it is released by calling +	line6_pcm_release(). Buffer allocation and stream startup are handled +	separately to allow the ALSA kernel driver to perform them at +	appropriate places (since the callback which starts a PCM stream is not +	allowed to sleep).  */  enum { -	/* individual bits: */ -	BIT_PCM_ALSA_PLAYBACK, -	BIT_PCM_ALSA_CAPTURE, -	BIT_PCM_MONITOR_PLAYBACK, -	BIT_PCM_MONITOR_CAPTURE, +	/* individual bit indices: */ +	LINE6_INDEX_PCM_ALSA_PLAYBACK_BUFFER, +	LINE6_INDEX_PCM_ALSA_PLAYBACK_STREAM, +	LINE6_INDEX_PCM_ALSA_CAPTURE_BUFFER, +	LINE6_INDEX_PCM_ALSA_CAPTURE_STREAM, +	LINE6_INDEX_PCM_MONITOR_PLAYBACK_BUFFER, +	LINE6_INDEX_PCM_MONITOR_PLAYBACK_STREAM, +	LINE6_INDEX_PCM_MONITOR_CAPTURE_BUFFER, +	LINE6_INDEX_PCM_MONITOR_CAPTURE_STREAM,  #ifdef CONFIG_LINE6_USB_IMPULSE_RESPONSE -	BIT_PCM_IMPULSE_PLAYBACK, -	BIT_PCM_IMPULSE_CAPTURE, +	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 -	BIT_PAUSE_PLAYBACK, -	BIT_PREPARED, - -	/* individual masks: */ -/* *INDENT-OFF* */ -	MASK_PCM_ALSA_PLAYBACK    = 1 << BIT_PCM_ALSA_PLAYBACK, -	MASK_PCM_ALSA_CAPTURE     = 1 << BIT_PCM_ALSA_CAPTURE, -	MASK_PCM_MONITOR_PLAYBACK = 1 << BIT_PCM_MONITOR_PLAYBACK, -	MASK_PCM_MONITOR_CAPTURE  = 1 << BIT_PCM_MONITOR_CAPTURE, +	LINE6_INDEX_PAUSE_PLAYBACK, +	LINE6_INDEX_PREPARED, + +	/* individual bit masks: */ +	LINE6_BIT(PCM_ALSA_PLAYBACK_BUFFER), +	LINE6_BIT(PCM_ALSA_PLAYBACK_STREAM), +	LINE6_BIT(PCM_ALSA_CAPTURE_BUFFER), +	LINE6_BIT(PCM_ALSA_CAPTURE_STREAM), +	LINE6_BIT(PCM_MONITOR_PLAYBACK_BUFFER), +	LINE6_BIT(PCM_MONITOR_PLAYBACK_STREAM), +	LINE6_BIT(PCM_MONITOR_CAPTURE_BUFFER), +	LINE6_BIT(PCM_MONITOR_CAPTURE_STREAM),  #ifdef CONFIG_LINE6_USB_IMPULSE_RESPONSE -	MASK_PCM_IMPULSE_PLAYBACK = 1 << BIT_PCM_IMPULSE_PLAYBACK, -	MASK_PCM_IMPULSE_CAPTURE  = 1 << BIT_PCM_IMPULSE_CAPTURE, +	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 -	MASK_PAUSE_PLAYBACK       = 1 << BIT_PAUSE_PLAYBACK, -	MASK_PREPARED             = 1 << BIT_PREPARED, -/* *INDENT-ON* */ +	LINE6_BIT(PAUSE_PLAYBACK), +	LINE6_BIT(PREPARED), + +	/* combined bit masks (by operation): */ +	LINE6_BITS_PCM_ALSA_BUFFER = +	    LINE6_BIT_PCM_ALSA_PLAYBACK_BUFFER | +	    LINE6_BIT_PCM_ALSA_CAPTURE_BUFFER, + +	LINE6_BITS_PCM_ALSA_STREAM = +	    LINE6_BIT_PCM_ALSA_PLAYBACK_STREAM | +	    LINE6_BIT_PCM_ALSA_CAPTURE_STREAM, + +	LINE6_BITS_PCM_MONITOR = +	    LINE6_BIT_PCM_MONITOR_PLAYBACK_BUFFER | +	    LINE6_BIT_PCM_MONITOR_PLAYBACK_STREAM | +	    LINE6_BIT_PCM_MONITOR_CAPTURE_BUFFER | +	    LINE6_BIT_PCM_MONITOR_CAPTURE_STREAM, -	/* combined masks (by operation): */ -	MASK_PCM_ALSA = MASK_PCM_ALSA_PLAYBACK | MASK_PCM_ALSA_CAPTURE, -	MASK_PCM_MONITOR = MASK_PCM_MONITOR_PLAYBACK | MASK_PCM_MONITOR_CAPTURE,  #ifdef CONFIG_LINE6_USB_IMPULSE_RESPONSE -	MASK_PCM_IMPULSE = MASK_PCM_IMPULSE_PLAYBACK | MASK_PCM_IMPULSE_CAPTURE, +	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 masks (by direction): */ +	/* combined bit masks (by direction): */ +	LINE6_BITS_PLAYBACK_BUFFER =  #ifdef CONFIG_LINE6_USB_IMPULSE_RESPONSE -	MASK_PLAYBACK = -	    MASK_PCM_ALSA_PLAYBACK | MASK_PCM_MONITOR_PLAYBACK | -	    MASK_PCM_IMPULSE_PLAYBACK, -	MASK_CAPTURE = -	    MASK_PCM_ALSA_CAPTURE | MASK_PCM_MONITOR_CAPTURE | -	    MASK_PCM_IMPULSE_CAPTURE -#else -	MASK_PLAYBACK = MASK_PCM_ALSA_PLAYBACK | MASK_PCM_MONITOR_PLAYBACK, -	MASK_CAPTURE = MASK_PCM_ALSA_CAPTURE | MASK_PCM_MONITOR_CAPTURE +	    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, + +	LINE6_BITS_STREAM = +	    LINE6_BITS_PLAYBACK_STREAM | +	    LINE6_BITS_CAPTURE_STREAM  };  struct line6_pcm_properties { @@ -149,11 +220,6 @@ struct snd_line6_pcm {  	unsigned char *buffer_in;  	/** -		 Temporary buffer index for playback. -	*/ -	int index_out; - -	/**  		 Previously captured frame (for software monitoring).  	*/  	unsigned char *prev_fbuf; @@ -298,7 +364,7 @@ struct snd_line6_pcm {  #endif  	/** -		 Several status bits (see BIT_*). +		 Several status bits (see LINE6_BIT_*).  	*/  	unsigned long flags; @@ -310,16 +376,7 @@ extern int line6_init_pcm(struct usb_line6 *line6,  extern int snd_line6_trigger(struct snd_pcm_substream *substream, int cmd);  extern int snd_line6_prepare(struct snd_pcm_substream *substream);  extern void line6_pcm_disconnect(struct snd_line6_pcm *line6pcm); -extern int line6_pcm_start(struct snd_line6_pcm *line6pcm, int channels); -extern int line6_pcm_stop(struct snd_line6_pcm *line6pcm, int channels); - -#define PRINT_FRAME_DIFF(op) {						\ -	static int diff_prev = 1000;					\ -	int diff = line6pcm->last_frame_out - line6pcm->last_frame_in;	\ -	if ((diff != diff_prev) && (abs(diff) < 100)) {			\ -		printk(KERN_INFO "%s frame diff = %d\n", op, diff);	\ -		diff_prev = diff;					\ -	}								\ -} +extern int line6_pcm_acquire(struct snd_line6_pcm *line6pcm, int channels); +extern int line6_pcm_release(struct snd_line6_pcm *line6pcm, int channels);  #endif diff --git a/drivers/staging/line6/playback.c b/drivers/staging/line6/playback.c index 29940fd1671..2ca8900e68c 100644 --- a/drivers/staging/line6/playback.c +++ b/drivers/staging/line6/playback.c @@ -9,6 +9,7 @@   *   */ +#include <linux/slab.h>  #include <sound/core.h>  #include <sound/pcm.h>  #include <sound/pcm_params.h> @@ -33,6 +34,7 @@ static void change_volume(struct urb *urb_out, int volume[],  	if (bytes_per_frame == 4) {  		short *p, *buf_end; +  		p = (short *)urb_out->transfer_buffer;  		buf_end = p + urb_out->transfer_buffer_length / sizeof(*p); @@ -42,11 +44,13 @@ static void change_volume(struct urb *urb_out, int volume[],  		}  	} else if (bytes_per_frame == 6) {  		unsigned char *p, *buf_end; +  		p = (unsigned char *)urb_out->transfer_buffer;  		buf_end = p + urb_out->transfer_buffer_length;  		for (; p < buf_end; p += 3) {  			int val; +  			val = p[0] + (p[1] << 8) + ((signed char)p[2] << 16);  			val = (val * volume[chn & 1]) >> 8;  			p[0] = val; @@ -115,6 +119,7 @@ static void add_monitor_signal(struct urb *urb_out, unsigned char *signal,  	if (bytes_per_frame == 4) {  		short *pi, *po, *buf_end; +  		pi = (short *)signal;  		po = (short *)urb_out->transfer_buffer;  		buf_end = po + urb_out->transfer_buffer_length / sizeof(*po); @@ -165,11 +170,12 @@ static int submit_audio_out_urb(struct snd_line6_pcm *line6pcm)  		struct usb_iso_packet_descriptor *fout =  		    &urb_out->iso_frame_desc[i]; -		if (line6pcm->flags & MASK_CAPTURE) +		if (line6pcm->flags & LINE6_BITS_CAPTURE_STREAM)  			fsize = line6pcm->prev_fsize;  		if (fsize == 0) {  			int n; +  			line6pcm->count_out += frame_increment;  			n = line6pcm->count_out / frame_factor;  			line6pcm->count_out -= n * frame_factor; @@ -184,22 +190,19 @@ static int submit_audio_out_urb(struct snd_line6_pcm *line6pcm)  	if (urb_size == 0) {  		/* can't determine URB size */  		spin_unlock_irqrestore(&line6pcm->lock_audio_out, flags); -		dev_err(line6pcm->line6->ifcdev, "driver bug: urb_size = 0\n");	/* this is somewhat paranoid */ +		dev_err(line6pcm->line6->ifcdev, "driver bug: urb_size = 0\n");  		return -EINVAL;  	}  	urb_frames = urb_size / bytes_per_frame;  	urb_out->transfer_buffer =  	    line6pcm->buffer_out + -	    line6pcm->max_packet_size * line6pcm->index_out; +	    index * LINE6_ISO_PACKETS * line6pcm->max_packet_size;  	urb_out->transfer_buffer_length = urb_size;  	urb_out->context = line6pcm; -	if (++line6pcm->index_out == LINE6_ISO_BUFFERS) -		line6pcm->index_out = 0; - -	if (test_bit(BIT_PCM_ALSA_PLAYBACK, &line6pcm->flags) && -	    !test_bit(BIT_PAUSE_PLAYBACK, &line6pcm->flags)) { +	if (test_bit(LINE6_INDEX_PCM_ALSA_PLAYBACK_STREAM, &line6pcm->flags) && +	    !test_bit(LINE6_INDEX_PAUSE_PLAYBACK, &line6pcm->flags)) {  		struct snd_pcm_runtime *runtime =  		    get_substream(line6pcm, SNDRV_PCM_STREAM_PLAYBACK)->runtime; @@ -209,6 +212,7 @@ static int submit_audio_out_urb(struct snd_line6_pcm *line6pcm)  			   copy the data to the temp buffer.  			 */  			int len; +  			len = runtime->buffer_size - line6pcm->pos_out;  			if (len > 0) { @@ -220,20 +224,13 @@ static int submit_audio_out_urb(struct snd_line6_pcm *line6pcm)  				       len * bytes_per_frame, runtime->dma_area,  				       (urb_frames - len) * bytes_per_frame);  			} else -				dev_err(line6pcm->line6->ifcdev, "driver bug: len = %d\n", len);	/* this is somewhat paranoid */ +				dev_err(line6pcm->line6->ifcdev, "driver bug: len = %d\n", +					len);  		} else { -#if LINE6_REUSE_DMA_AREA_FOR_PLAYBACK -			/* set the buffer pointer */ -			urb_out->transfer_buffer = -			    runtime->dma_area + -			    line6pcm->pos_out * bytes_per_frame; -#else -			/* copy data */  			memcpy(urb_out->transfer_buffer,  			       runtime->dma_area +  			       line6pcm->pos_out * bytes_per_frame,  			       urb_out->transfer_buffer_length); -#endif  		}  		line6pcm->pos_out += urb_frames; @@ -246,26 +243,27 @@ 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 != 0) { +	if (line6pcm->prev_fbuf != NULL) {  #ifdef CONFIG_LINE6_USB_IMPULSE_RESPONSE -		if (line6pcm->flags & MASK_PCM_IMPULSE) { +		if (line6pcm->flags & LINE6_BITS_PCM_IMPULSE) {  			create_impulse_test_signal(line6pcm, urb_out,  						   bytes_per_frame); -			if (line6pcm->flags & MASK_PCM_ALSA_CAPTURE) { +			if (line6pcm->flags & +			    LINE6_BIT_PCM_ALSA_CAPTURE_STREAM) {  				line6_capture_copy(line6pcm,  						   urb_out->transfer_buffer,  						   urb_out->  						   transfer_buffer_length);  				line6_capture_check_period(line6pcm, -							   urb_out->transfer_buffer_length); +					urb_out->transfer_buffer_length);  			}  		} else {  #endif  			if (!  			    (line6pcm->line6->  			     properties->capabilities & LINE6_BIT_HWMON) -&& (line6pcm->flags & MASK_PLAYBACK) -&& (line6pcm->flags & MASK_CAPTURE)) +			    && (line6pcm->flags & LINE6_BITS_PLAYBACK_STREAM) +			    && (line6pcm->flags & LINE6_BITS_CAPTURE_STREAM))  				add_monitor_signal(urb_out, line6pcm->prev_fbuf,  						   line6pcm->volume_monitor,  						   bytes_per_frame); @@ -273,15 +271,6 @@ static int submit_audio_out_urb(struct snd_line6_pcm *line6pcm)  		}  #endif  	} -#ifdef CONFIG_LINE6_USB_DUMP_PCM -	for (i = 0; i < LINE6_ISO_PACKETS; ++i) { -		struct usb_iso_packet_descriptor *fout = -		    &urb_out->iso_frame_desc[i]; -		line6_write_hexdump(line6pcm->line6, 'P', -				    urb_out->transfer_buffer + fout->offset, -				    fout->length); -	} -#endif  	ret = usb_submit_urb(urb_out, GFP_ATOMIC); @@ -322,6 +311,7 @@ void line6_unlink_audio_out_urbs(struct snd_line6_pcm *line6pcm)  		if (test_bit(i, &line6pcm->active_urb_out)) {  			if (!test_and_set_bit(i, &line6pcm->unlink_urb_out)) {  				struct urb *u = line6pcm->urb_audio_out[i]; +  				usb_unlink_urb(u);  			}  		} @@ -329,9 +319,10 @@ void line6_unlink_audio_out_urbs(struct snd_line6_pcm *line6pcm)  }  /* -	Wait until unlinking of all currently active playback URBs has been finished. +	Wait until unlinking of all currently active playback URBs has been +	finished.  */ -static void wait_clear_audio_out_urbs(struct snd_line6_pcm *line6pcm) +void line6_wait_clear_audio_out_urbs(struct snd_line6_pcm *line6pcm)  {  	int timeout = HZ;  	unsigned int i; @@ -358,7 +349,13 @@ static void wait_clear_audio_out_urbs(struct snd_line6_pcm *line6pcm)  void line6_unlink_wait_clear_audio_out_urbs(struct snd_line6_pcm *line6pcm)  {  	line6_unlink_audio_out_urbs(line6pcm); -	wait_clear_audio_out_urbs(line6pcm); +	line6_wait_clear_audio_out_urbs(line6pcm); +} + +void line6_free_playback_buffer(struct snd_line6_pcm *line6pcm) +{ +	kfree(line6pcm->buffer_out); +	line6pcm->buffer_out = NULL;  }  /* @@ -368,7 +365,6 @@ static void audio_out_callback(struct urb *urb)  {  	int i, index, length = 0, shutdown = 0;  	unsigned long flags; -  	struct snd_line6_pcm *line6pcm = (struct snd_line6_pcm *)urb->context;  	struct snd_pcm_substream *substream =  	    get_substream(line6pcm, SNDRV_PCM_STREAM_PLAYBACK); @@ -392,8 +388,9 @@ static void audio_out_callback(struct urb *urb)  	spin_lock_irqsave(&line6pcm->lock_audio_out, flags); -	if (test_bit(BIT_PCM_ALSA_PLAYBACK, &line6pcm->flags)) { +	if (test_bit(LINE6_INDEX_PCM_ALSA_PLAYBACK_STREAM, &line6pcm->flags)) {  		struct snd_pcm_runtime *runtime = substream->runtime; +  		line6pcm->pos_out_done +=  		    length / line6pcm->properties->bytes_per_frame; @@ -417,7 +414,8 @@ static void audio_out_callback(struct urb *urb)  	if (!shutdown) {  		submit_audio_out_urb(line6pcm); -		if (test_bit(BIT_PCM_ALSA_PLAYBACK, &line6pcm->flags)) { +		if (test_bit(LINE6_INDEX_PCM_ALSA_PLAYBACK_STREAM, +			     &line6pcm->flags)) {  			line6pcm->bytes_out += length;  			if (line6pcm->bytes_out >= line6pcm->period_out) {  				line6pcm->bytes_out %= line6pcm->period_out; @@ -469,10 +467,17 @@ static int snd_line6_playback_hw_params(struct snd_pcm_substream *substream,  	}  	/* -- [FD] end */ +	ret = line6_pcm_acquire(line6pcm, LINE6_BIT_PCM_ALSA_PLAYBACK_BUFFER); + +	if (ret < 0) +		return ret; +  	ret = snd_pcm_lib_malloc_pages(substream,  				       params_buffer_bytes(hw_params)); -	if (ret < 0) +	if (ret < 0) { +		line6_pcm_release(line6pcm, LINE6_BIT_PCM_ALSA_PLAYBACK_BUFFER);  		return ret; +	}  	line6pcm->period_out = params_period_bytes(hw_params);  	return 0; @@ -481,6 +486,9 @@ static int snd_line6_playback_hw_params(struct snd_pcm_substream *substream,  /* hw_free playback callback */  static int snd_line6_playback_hw_free(struct snd_pcm_substream *substream)  { +	struct snd_line6_pcm *line6pcm = snd_pcm_substream_chip(substream); + +	line6_pcm_release(line6pcm, LINE6_BIT_PCM_ALSA_PLAYBACK_BUFFER);  	return snd_pcm_lib_free_pages(substream);  } @@ -494,7 +502,8 @@ int snd_line6_playback_trigger(struct snd_line6_pcm *line6pcm, int cmd)  #ifdef CONFIG_PM  	case SNDRV_PCM_TRIGGER_RESUME:  #endif -		err = line6_pcm_start(line6pcm, MASK_PCM_ALSA_PLAYBACK); +		err = line6_pcm_acquire(line6pcm, +					LINE6_BIT_PCM_ALSA_PLAYBACK_STREAM);  		if (err < 0)  			return err; @@ -505,7 +514,8 @@ int snd_line6_playback_trigger(struct snd_line6_pcm *line6pcm, int cmd)  #ifdef CONFIG_PM  	case SNDRV_PCM_TRIGGER_SUSPEND:  #endif -		err = line6_pcm_stop(line6pcm, MASK_PCM_ALSA_PLAYBACK); +		err = line6_pcm_release(line6pcm, +					LINE6_BIT_PCM_ALSA_PLAYBACK_STREAM);  		if (err < 0)  			return err; @@ -513,11 +523,11 @@ int snd_line6_playback_trigger(struct snd_line6_pcm *line6pcm, int cmd)  		break;  	case SNDRV_PCM_TRIGGER_PAUSE_PUSH: -		set_bit(BIT_PAUSE_PLAYBACK, &line6pcm->flags); +		set_bit(LINE6_INDEX_PAUSE_PLAYBACK, &line6pcm->flags);  		break;  	case SNDRV_PCM_TRIGGER_PAUSE_RELEASE: -		clear_bit(BIT_PAUSE_PLAYBACK, &line6pcm->flags); +		clear_bit(LINE6_INDEX_PAUSE_PLAYBACK, &line6pcm->flags);  		break;  	default: @@ -532,6 +542,7 @@ static snd_pcm_uframes_t  snd_line6_playback_pointer(struct snd_pcm_substream *substream)  {  	struct snd_line6_pcm *line6pcm = snd_pcm_substream_chip(substream); +  	return line6pcm->pos_out_done;  } diff --git a/drivers/staging/line6/playback.h b/drivers/staging/line6/playback.h index f2fc8c0526e..743bd6f74c5 100644 --- a/drivers/staging/line6/playback.h +++ b/drivers/staging/line6/playback.h @@ -30,10 +30,12 @@  extern struct snd_pcm_ops snd_line6_playback_ops;  extern int line6_create_audio_out_urbs(struct snd_line6_pcm *line6pcm); +extern void line6_free_playback_buffer(struct snd_line6_pcm *line6pcm);  extern int line6_submit_audio_out_all_urbs(struct snd_line6_pcm *line6pcm);  extern void line6_unlink_audio_out_urbs(struct snd_line6_pcm *line6pcm);  extern void line6_unlink_wait_clear_audio_out_urbs(struct snd_line6_pcm  						   *line6pcm); +extern void line6_wait_clear_audio_out_urbs(struct snd_line6_pcm *line6pcm);  extern int snd_line6_playback_trigger(struct snd_line6_pcm *line6pcm, int cmd);  #endif diff --git a/drivers/staging/line6/pod.c b/drivers/staging/line6/pod.c index 22e2cedcacf..44f4b2f9857 100644 --- a/drivers/staging/line6/pod.c +++ b/drivers/staging/line6/pod.c @@ -15,7 +15,6 @@  #include "audio.h"  #include "capture.h" -#include "control.h"  #include "driver.h"  #include "playback.h"  #include "pod.h" @@ -26,7 +25,6 @@  /* *INDENT-OFF* */  enum { -	POD_SYSEX_CLIP      = 0x0f,  	POD_SYSEX_SAVE      = 0x24,  	POD_SYSEX_SYSTEM    = 0x56,  	POD_SYSEX_SYSTEMREQ = 0x57, @@ -36,17 +34,14 @@ enum {  	POD_SYSEX_DUMPMEM   = 0x73,  	POD_SYSEX_DUMP      = 0x74,  	POD_SYSEX_DUMPREQ   = 0x75 -	/* POD_SYSEX_DUMPMEM2  = 0x76 */   /* dumps entire internal memory of PODxt Pro */ + +	/* dumps entire internal memory of PODxt Pro */ +	/* POD_SYSEX_DUMPMEM2  = 0x76 */  };  enum { -	POD_monitor_level  = 0x04, -	POD_routing        = 0x05, -	POD_tuner_mute     = 0x13, -	POD_tuner_freq     = 0x15, -	POD_tuner_note     = 0x16, -	POD_tuner_pitch    = 0x17, -	POD_system_invalid = 0x10000 +	POD_MONITOR_LEVEL  = 0x04, +	POD_SYSTEM_INVALID = 0x10000  };  /* *INDENT-ON* */ @@ -118,10 +113,6 @@ static struct line6_pcm_properties pod_pcm_properties = {  	.bytes_per_frame = POD_BYTES_PER_FRAME  }; -static const char pod_request_channel[] = { -	0xf0, 0x00, 0x01, 0x0c, 0x03, 0x75, 0xf7 -}; -  static const char pod_version_header[] = {  	0xf2, 0x7e, 0x7f, 0x06, 0x02  }; @@ -129,18 +120,6 @@ static const char pod_version_header[] = {  /* forward declarations: */  static void pod_startup2(unsigned long data);  static void pod_startup3(struct usb_line6_pod *pod); -static void pod_startup4(struct usb_line6_pod *pod); - -/* -	Mark all parameters as dirty and notify waiting processes. -*/ -static void pod_mark_batch_all_dirty(struct usb_line6_pod *pod) -{ -	int i; - -	for (i = 0; i < POD_CONTROL_SIZE; i++) -		set_bit(i, pod->param_dirty); -}  static char *pod_alloc_sysex_buffer(struct usb_line6_pod *pod, int code,  				    int size) @@ -150,561 +129,46 @@ static char *pod_alloc_sysex_buffer(struct usb_line6_pod *pod, int code,  }  /* -	Send channel dump data to the PODxt Pro. -*/ -static void pod_dump(struct usb_line6_pod *pod, const unsigned char *data) -{ -	int size = 1 + sizeof(pod->prog_data); -	char *sysex = pod_alloc_sysex_buffer(pod, POD_SYSEX_DUMP, size); -	if (!sysex) -		return; -	/* Don't know what this is good for, but PODxt Pro transmits it, so we -	 * also do... */ -	sysex[SYSEX_DATA_OFS] = 5; -	memcpy(sysex + SYSEX_DATA_OFS + 1, data, sizeof(pod->prog_data)); -	line6_send_sysex_message(&pod->line6, sysex, size); -	memcpy(&pod->prog_data, data, sizeof(pod->prog_data)); -	pod_mark_batch_all_dirty(pod); -	kfree(sysex); -} - -/* -	Store parameter value in driver memory and mark it as dirty. -*/ -static void pod_store_parameter(struct usb_line6_pod *pod, int param, int value) -{ -	pod->prog_data.control[param] = value; -	set_bit(param, pod->param_dirty); -	pod->dirty = 1; -} - -/* -	Handle SAVE button. -*/ -static void pod_save_button_pressed(struct usb_line6_pod *pod, int type, -				    int index) -{ -	pod->dirty = 0; -	set_bit(POD_SAVE_PRESSED, &pod->atomic_flags); -} - -/*  	Process a completely received message.  */  void line6_pod_process_message(struct usb_line6_pod *pod)  {  	const unsigned char *buf = pod->line6.buffer_message; -	/* filter messages by type */ -	switch (buf[0] & 0xf0) { -	case LINE6_PARAM_CHANGE: -	case LINE6_PROGRAM_CHANGE: -	case LINE6_SYSEX_BEGIN: -		break;		/* handle these further down */ - -	default: -		return;		/* ignore all others */ +	if (memcmp(buf, pod_version_header, sizeof(pod_version_header)) == 0) { +		pod->firmware_version = buf[13] * 100 + buf[14] * 10 + buf[15]; +		pod->device_id = ((int)buf[8] << 16) | ((int)buf[9] << 8) | +				 (int) buf[10]; +		pod_startup3(pod); +		return;  	} -	/* process all remaining messages */ -	switch (buf[0]) { -	case LINE6_PARAM_CHANGE | LINE6_CHANNEL_DEVICE: -		pod_store_parameter(pod, buf[1], buf[2]); -		/* intentionally no break here! */ - -	case LINE6_PARAM_CHANGE | LINE6_CHANNEL_HOST: -		if ((buf[1] == POD_amp_model_setup) || -		    (buf[1] == POD_effect_setup)) -			/* these also affect other settings */ -			line6_dump_request_async(&pod->dumpreq, &pod->line6, 0, -						 LINE6_DUMP_CURRENT); - -		break; - -	case LINE6_PROGRAM_CHANGE | LINE6_CHANNEL_DEVICE: -	case LINE6_PROGRAM_CHANGE | LINE6_CHANNEL_HOST: -		pod->channel_num = buf[1]; -		pod->dirty = 0; -		set_bit(POD_CHANNEL_DIRTY, &pod->atomic_flags); -		line6_dump_request_async(&pod->dumpreq, &pod->line6, 0, -					 LINE6_DUMP_CURRENT); -		break; - -	case LINE6_SYSEX_BEGIN | LINE6_CHANNEL_DEVICE: -	case LINE6_SYSEX_BEGIN | LINE6_CHANNEL_UNKNOWN: -		if (memcmp(buf + 1, line6_midi_id, sizeof(line6_midi_id)) == 0) { -			switch (buf[5]) { -			case POD_SYSEX_DUMP: -				if (pod->line6.message_length == -				    sizeof(pod->prog_data) + 7) { -					switch (pod->dumpreq.in_progress) { -					case LINE6_DUMP_CURRENT: -						memcpy(&pod->prog_data, buf + 7, -						       sizeof(pod->prog_data)); -						pod_mark_batch_all_dirty(pod); -						break; - -					case POD_DUMP_MEMORY: -						memcpy(&pod->prog_data_buf, -						       buf + 7, -						       sizeof -						       (pod->prog_data_buf)); -						break; - -					default: -						DEBUG_MESSAGES(dev_err -							       (pod-> -								line6.ifcdev, -								"unknown dump code %02X\n", -								pod-> -								dumpreq.in_progress)); -					} - -					line6_dump_finished(&pod->dumpreq); -					pod_startup3(pod); -				} else -					DEBUG_MESSAGES(dev_err -						       (pod->line6.ifcdev, -							"wrong size of channel dump message (%d instead of %d)\n", -							pod-> -							line6.message_length, -							(int) -							sizeof(pod->prog_data) + -							7)); - -				break; - -			case POD_SYSEX_SYSTEM:{ -					short value = -					    ((int)buf[7] << 12) | ((int)buf[8] -								   << 8) | -					    ((int)buf[9] << 4) | (int)buf[10]; - -#define PROCESS_SYSTEM_PARAM(x) \ -					case POD_ ## x: \ -						pod->x.value = value; \ -						wake_up(&pod->x.wait); \ -						break; - -					switch (buf[6]) { -						PROCESS_SYSTEM_PARAM -						    (monitor_level); -						PROCESS_SYSTEM_PARAM(routing); -						PROCESS_SYSTEM_PARAM -						    (tuner_mute); -						PROCESS_SYSTEM_PARAM -						    (tuner_freq); -						PROCESS_SYSTEM_PARAM -						    (tuner_note); -						PROCESS_SYSTEM_PARAM -						    (tuner_pitch); - -#undef PROCESS_SYSTEM_PARAM - -					default: -						DEBUG_MESSAGES(dev_err -							       (pod-> -								line6.ifcdev, -								"unknown tuner/system response %02X\n", -								buf[6])); -					} - -					break; -				} - -			case POD_SYSEX_FINISH: -				/* do we need to respond to this? */ -				break; - -			case POD_SYSEX_SAVE: -				pod_save_button_pressed(pod, buf[6], buf[7]); -				break; - -			case POD_SYSEX_CLIP: -				DEBUG_MESSAGES(dev_err -					       (pod->line6.ifcdev, -						"audio clipped\n")); -				pod->clipping.value = 1; -				wake_up(&pod->clipping.wait); -				break; - -			case POD_SYSEX_STORE: -				DEBUG_MESSAGES(dev_err -					       (pod->line6.ifcdev, -						"message %02X not yet implemented\n", -						buf[5])); -				break; - -			default: -				DEBUG_MESSAGES(dev_err -					       (pod->line6.ifcdev, -						"unknown sysex message %02X\n", -						buf[5])); -			} -		} else -		    if (memcmp -			(buf, pod_version_header, -			 sizeof(pod_version_header)) == 0) { -			pod->firmware_version = -			    buf[13] * 100 + buf[14] * 10 + buf[15]; -			pod->device_id = -			    ((int)buf[8] << 16) | ((int)buf[9] << 8) | (int) -			    buf[10]; -			pod_startup4(pod); -		} else -			DEBUG_MESSAGES(dev_err -				       (pod->line6.ifcdev, -					"unknown sysex header\n")); - -		break; - -	case LINE6_SYSEX_END: -		break; - -	default: -		DEBUG_MESSAGES(dev_err -			       (pod->line6.ifcdev, -				"POD: unknown message %02X\n", buf[0])); +	/* Only look for sysex messages from this device */ +	if (buf[0] != (LINE6_SYSEX_BEGIN | LINE6_CHANNEL_DEVICE) && +	    buf[0] != (LINE6_SYSEX_BEGIN | LINE6_CHANNEL_UNKNOWN)) { +		return;  	} -} - -/* -	Detect some cases that require a channel dump after sending a command to the -	device. Important notes: -	*) The actual dump request can not be sent here since we are not allowed to -	wait for the completion of the first message in this context, and sending -	the dump request before completion of the previous message leaves the POD -	in an undefined state. The dump request will be sent when the echoed -	commands are received. -	*) This method fails if a param change message is "chopped" after the first -	byte. -*/ -void line6_pod_midi_postprocess(struct usb_line6_pod *pod, unsigned char *data, -				int length) -{ -	int i; - -	if (!pod->midi_postprocess) +	if (memcmp(buf + 1, line6_midi_id, sizeof(line6_midi_id)) != 0)  		return; -	for (i = 0; i < length; ++i) { -		if (data[i] == (LINE6_PROGRAM_CHANGE | LINE6_CHANNEL_HOST)) { -			line6_invalidate_current(&pod->dumpreq); -			break; -		} else -		    if ((data[i] == (LINE6_PARAM_CHANGE | LINE6_CHANNEL_HOST)) -			&& (i < length - 1)) -			if ((data[i + 1] == POD_amp_model_setup) -			    || (data[i + 1] == POD_effect_setup)) { -				line6_invalidate_current(&pod->dumpreq); -				break; -			} +	if (buf[5] == POD_SYSEX_SYSTEM && buf[6] == POD_MONITOR_LEVEL) { +		short value = ((int)buf[7] << 12) | ((int)buf[8] << 8) | +			      ((int)buf[9] << 4) | (int)buf[10]; +		pod->monitor_level = value;  	}  }  /* -	Send channel number (i.e., switch to a different sound). -*/ -static void pod_send_channel(struct usb_line6_pod *pod, int value) -{ -	line6_invalidate_current(&pod->dumpreq); - -	if (line6_send_program(&pod->line6, value) == 0) -		pod->channel_num = value; -	else -		line6_dump_finished(&pod->dumpreq); -} - -/*  	Transmit PODxt Pro control parameter.  */  void line6_pod_transmit_parameter(struct usb_line6_pod *pod, int param, -				  int value) +				  u8 value)  { -	if (line6_transmit_parameter(&pod->line6, param, value) == 0) -		pod_store_parameter(pod, param, value); - -	if ((param == POD_amp_model_setup) || (param == POD_effect_setup))	/* these also affect other settings */ -		line6_invalidate_current(&pod->dumpreq); -} - -/* -	Resolve value to memory location. -*/ -static int pod_resolve(const char *buf, short block0, short block1, -		       unsigned char *location) -{ -	unsigned long value; -	short block; -	int ret; - -	ret = strict_strtoul(buf, 10, &value); -	if (ret) -		return ret; - -	block = (value < 0x40) ? block0 : block1; -	value &= 0x3f; -	location[0] = block >> 7; -	location[1] = value | (block & 0x7f); -	return 0; -} - -/* -	Send command to store channel/effects setup/amp setup to PODxt Pro. -*/ -static ssize_t pod_send_store_command(struct device *dev, const char *buf, -				      size_t count, short block0, short block1) -{ -	struct usb_interface *interface = to_usb_interface(dev); -	struct usb_line6_pod *pod = usb_get_intfdata(interface); -	int ret; -	int size = 3 + sizeof(pod->prog_data_buf); -	char *sysex = pod_alloc_sysex_buffer(pod, POD_SYSEX_STORE, size); - -	if (!sysex) -		return 0; - -	sysex[SYSEX_DATA_OFS] = 5;	/* see pod_dump() */ -	ret = pod_resolve(buf, block0, block1, sysex + SYSEX_DATA_OFS + 1); -	if (ret) { -		kfree(sysex); -		return ret; -	} - -	memcpy(sysex + SYSEX_DATA_OFS + 3, &pod->prog_data_buf, -	       sizeof(pod->prog_data_buf)); - -	line6_send_sysex_message(&pod->line6, sysex, size); -	kfree(sysex); -	/* needs some delay here on AMD64 platform */ -	return count; -} - -/* -	Send command to retrieve channel/effects setup/amp setup to PODxt Pro. -*/ -static ssize_t pod_send_retrieve_command(struct device *dev, const char *buf, -					 size_t count, short block0, -					 short block1) -{ -	struct usb_interface *interface = to_usb_interface(dev); -	struct usb_line6_pod *pod = usb_get_intfdata(interface); -	int ret; -	int size = 4; -	char *sysex = pod_alloc_sysex_buffer(pod, POD_SYSEX_DUMPMEM, size); - -	if (!sysex) -		return 0; - -	ret = pod_resolve(buf, block0, block1, sysex + SYSEX_DATA_OFS); -	if (ret) { -		kfree(sysex); -		return ret; -	} -	sysex[SYSEX_DATA_OFS + 2] = 0; -	sysex[SYSEX_DATA_OFS + 3] = 0; -	line6_dump_started(&pod->dumpreq, POD_DUMP_MEMORY); - -	if (line6_send_sysex_message(&pod->line6, sysex, size) < size) -		line6_dump_finished(&pod->dumpreq); - -	kfree(sysex); -	/* needs some delay here on AMD64 platform */ -	return count; -} - -/* -	Generic get name function. -*/ -static ssize_t get_name_generic(struct usb_line6_pod *pod, const char *str, -				char *buf) -{ -	int length = 0; -	const char *p1; -	char *p2; -	char *last_non_space = buf; - -	int retval = line6_dump_wait_interruptible(&pod->dumpreq); -	if (retval < 0) -		return retval; - -	for (p1 = str, p2 = buf; *p1; ++p1, ++p2) { -		*p2 = *p1; -		if (*p2 != ' ') -			last_non_space = p2; -		if (++length == POD_NAME_LENGTH) -			break; -	} - -	*(last_non_space + 1) = '\n'; -	return last_non_space - buf + 2; -} - -/* -	"read" request on "channel" special file. -*/ -static ssize_t pod_get_channel(struct device *dev, -			       struct device_attribute *attr, char *buf) -{ -	struct usb_interface *interface = to_usb_interface(dev); -	struct usb_line6_pod *pod = usb_get_intfdata(interface); -	return sprintf(buf, "%d\n", pod->channel_num); -} - -/* -	"write" request on "channel" special file. -*/ -static ssize_t pod_set_channel(struct device *dev, -			       struct device_attribute *attr, -			       const char *buf, size_t count) -{ -	struct usb_interface *interface = to_usb_interface(dev); -	struct usb_line6_pod *pod = usb_get_intfdata(interface); -	unsigned long value; -	int ret; - -	ret = strict_strtoul(buf, 10, &value); -	if (ret) -		return ret; - -	pod_send_channel(pod, value); -	return count; -} - -/* -	"read" request on "name" special file. -*/ -static ssize_t pod_get_name(struct device *dev, struct device_attribute *attr, -			    char *buf) -{ -	struct usb_interface *interface = to_usb_interface(dev); -	struct usb_line6_pod *pod = usb_get_intfdata(interface); -	return get_name_generic(pod, pod->prog_data.header + POD_NAME_OFFSET, -				buf); -} - -/* -	"read" request on "name" special file. -*/ -static ssize_t pod_get_name_buf(struct device *dev, -				struct device_attribute *attr, char *buf) -{ -	struct usb_interface *interface = to_usb_interface(dev); -	struct usb_line6_pod *pod = usb_get_intfdata(interface); -	return get_name_generic(pod, -				pod->prog_data_buf.header + POD_NAME_OFFSET, -				buf); -} - -/* -	"read" request on "dump" special file. -*/ -static ssize_t pod_get_dump(struct device *dev, struct device_attribute *attr, -			    char *buf) -{ -	struct usb_interface *interface = to_usb_interface(dev); -	struct usb_line6_pod *pod = usb_get_intfdata(interface); -	int retval = line6_dump_wait_interruptible(&pod->dumpreq); -	if (retval < 0) -		return retval; -	memcpy(buf, &pod->prog_data, sizeof(pod->prog_data)); -	return sizeof(pod->prog_data); -} - -/* -	"write" request on "dump" special file. -*/ -static ssize_t pod_set_dump(struct device *dev, struct device_attribute *attr, -			    const char *buf, size_t count) -{ -	struct usb_interface *interface = to_usb_interface(dev); -	struct usb_line6_pod *pod = usb_get_intfdata(interface); - -	if (count != sizeof(pod->prog_data)) { -		dev_err(pod->line6.ifcdev, -			"data block must be exactly %d bytes\n", -			(int)sizeof(pod->prog_data)); -		return -EINVAL; -	} - -	pod_dump(pod, buf); -	return sizeof(pod->prog_data); -} - -/* -	Identify system parameters related to the tuner. -*/ -static bool pod_is_tuner(int code) -{ -	return -	    (code == POD_tuner_mute) || -	    (code == POD_tuner_freq) || -	    (code == POD_tuner_note) || (code == POD_tuner_pitch); -} - -/* -	Get system parameter (as integer). -	@param tuner non-zero, if code refers to a tuner parameter -*/ -static int pod_get_system_param_int(struct usb_line6_pod *pod, int *value, -				    int code, struct ValueWait *param, int sign) -{ -	char *sysex; -	static const int size = 1; -	int retval = 0; - -	if (((pod->prog_data.control[POD_tuner] & 0x40) == 0) -	    && pod_is_tuner(code)) -		return -ENODEV; - -	/* send value request to device: */ -	param->value = POD_system_invalid; -	sysex = pod_alloc_sysex_buffer(pod, POD_SYSEX_SYSTEMREQ, size); - -	if (!sysex) -		return -ENOMEM; - -	sysex[SYSEX_DATA_OFS] = code; -	line6_send_sysex_message(&pod->line6, sysex, size); -	kfree(sysex); - -	/* wait for device to respond: */ -	retval = -	    wait_event_interruptible(param->wait, -				     param->value != POD_system_invalid); - -	if (retval < 0) -		return retval; - -	*value = sign ? (int)(signed short)param->value : (int)(unsigned short) -	    param->value; - -	if (*value == POD_system_invalid) -		*value = 0;	/* don't report uninitialized values */ - -	return 0; -} - -/* -	Get system parameter (as string). -	@param tuner non-zero, if code refers to a tuner parameter -*/ -static ssize_t pod_get_system_param_string(struct usb_line6_pod *pod, char *buf, -					   int code, struct ValueWait *param, -					   int sign) -{ -	int retval, value = 0; -	retval = pod_get_system_param_int(pod, &value, code, param, sign); - -	if (retval < 0) -		return retval; - -	return sprintf(buf, "%d\n", value); +	line6_transmit_parameter(&pod->line6, param, value);  }  /*  	Send system parameter (from integer). -	@param tuner non-zero, if code refers to a tuner parameter  */  static int pod_set_system_param_int(struct usb_line6_pod *pod, int value,  				    int code) @@ -712,11 +176,6 @@ static int pod_set_system_param_int(struct usb_line6_pod *pod, int value,  	char *sysex;  	static const int size = 5; -	if (((pod->prog_data.control[POD_tuner] & 0x40) == 0) -	    && pod_is_tuner(code)) -		return -EINVAL; - -	/* send value to tuner: */  	sysex = pod_alloc_sysex_buffer(pod, POD_SYSEX_SYSTEM, size);  	if (!sysex)  		return -ENOMEM; @@ -731,198 +190,26 @@ static int pod_set_system_param_int(struct usb_line6_pod *pod, int value,  }  /* -	Send system parameter (from string). -	@param tuner non-zero, if code refers to a tuner parameter -*/ -static ssize_t pod_set_system_param_string(struct usb_line6_pod *pod, -					   const char *buf, int count, int code, -					   unsigned short mask) -{ -	int retval; -	unsigned short value = simple_strtoul(buf, NULL, 10) & mask; -	retval = pod_set_system_param_int(pod, value, code); -	return (retval < 0) ? retval : count; -} - -/* -	"read" request on "dump_buf" special file. -*/ -static ssize_t pod_get_dump_buf(struct device *dev, -				struct device_attribute *attr, char *buf) -{ -	struct usb_interface *interface = to_usb_interface(dev); -	struct usb_line6_pod *pod = usb_get_intfdata(interface); -	int retval = line6_dump_wait_interruptible(&pod->dumpreq); -	if (retval < 0) -		return retval; -	memcpy(buf, &pod->prog_data_buf, sizeof(pod->prog_data_buf)); -	return sizeof(pod->prog_data_buf); -} - -/* -	"write" request on "dump_buf" special file. -*/ -static ssize_t pod_set_dump_buf(struct device *dev, -				struct device_attribute *attr, -				const char *buf, size_t count) -{ -	struct usb_interface *interface = to_usb_interface(dev); -	struct usb_line6_pod *pod = usb_get_intfdata(interface); - -	if (count != sizeof(pod->prog_data)) { -		dev_err(pod->line6.ifcdev, -			"data block must be exactly %d bytes\n", -			(int)sizeof(pod->prog_data)); -		return -EINVAL; -	} - -	memcpy(&pod->prog_data_buf, buf, sizeof(pod->prog_data)); -	return sizeof(pod->prog_data); -} - -/* -	"write" request on "finish" special file. -*/ -static ssize_t pod_set_finish(struct device *dev, -			      struct device_attribute *attr, -			      const char *buf, size_t count) -{ -	struct usb_interface *interface = to_usb_interface(dev); -	struct usb_line6_pod *pod = usb_get_intfdata(interface); -	int size = 0; -	char *sysex = pod_alloc_sysex_buffer(pod, POD_SYSEX_FINISH, size); -	if (!sysex) -		return 0; -	line6_send_sysex_message(&pod->line6, sysex, size); -	kfree(sysex); -	return count; -} - -/* -	"write" request on "store_channel" special file. -*/ -static ssize_t pod_set_store_channel(struct device *dev, -				     struct device_attribute *attr, -				     const char *buf, size_t count) -{ -	return pod_send_store_command(dev, buf, count, 0x0000, 0x00c0); -} - -/* -	"write" request on "store_effects_setup" special file. -*/ -static ssize_t pod_set_store_effects_setup(struct device *dev, -					   struct device_attribute *attr, -					   const char *buf, size_t count) -{ -	return pod_send_store_command(dev, buf, count, 0x0080, 0x0080); -} - -/* -	"write" request on "store_amp_setup" special file. -*/ -static ssize_t pod_set_store_amp_setup(struct device *dev, -				       struct device_attribute *attr, -				       const char *buf, size_t count) -{ -	return pod_send_store_command(dev, buf, count, 0x0040, 0x0100); -} - -/* -	"write" request on "retrieve_channel" special file. -*/ -static ssize_t pod_set_retrieve_channel(struct device *dev, -					struct device_attribute *attr, -					const char *buf, size_t count) -{ -	return pod_send_retrieve_command(dev, buf, count, 0x0000, 0x00c0); -} - -/* -	"write" request on "retrieve_effects_setup" special file. -*/ -static ssize_t pod_set_retrieve_effects_setup(struct device *dev, -					      struct device_attribute *attr, -					      const char *buf, size_t count) -{ -	return pod_send_retrieve_command(dev, buf, count, 0x0080, 0x0080); -} - -/* -	"write" request on "retrieve_amp_setup" special file. -*/ -static ssize_t pod_set_retrieve_amp_setup(struct device *dev, -					  struct device_attribute *attr, -					  const char *buf, size_t count) -{ -	return pod_send_retrieve_command(dev, buf, count, 0x0040, 0x0100); -} - -/* -	"read" request on "dirty" special file. -*/ -static ssize_t pod_get_dirty(struct device *dev, struct device_attribute *attr, -			     char *buf) -{ -	struct usb_interface *interface = to_usb_interface(dev); -	struct usb_line6_pod *pod = usb_get_intfdata(interface); -	buf[0] = pod->dirty ? '1' : '0'; -	buf[1] = '\n'; -	return 2; -} - -/* -	"read" request on "midi_postprocess" special file. -*/ -static ssize_t pod_get_midi_postprocess(struct device *dev, -					struct device_attribute *attr, -					char *buf) -{ -	struct usb_interface *interface = to_usb_interface(dev); -	struct usb_line6_pod *pod = usb_get_intfdata(interface); -	return sprintf(buf, "%d\n", pod->midi_postprocess); -} - -/* -	"write" request on "midi_postprocess" special file. -*/ -static ssize_t pod_set_midi_postprocess(struct device *dev, -					struct device_attribute *attr, -					const char *buf, size_t count) -{ -	struct usb_interface *interface = to_usb_interface(dev); -	struct usb_line6_pod *pod = usb_get_intfdata(interface); -	unsigned long value; -	int ret; - -	ret = strict_strtoul(buf, 10, &value); -	if (ret) -		return ret; - -	pod->midi_postprocess = value ? 1 : 0; -	return count; -} - -/*  	"read" request on "serial_number" special file.  */ -static ssize_t pod_get_serial_number(struct device *dev, -				     struct device_attribute *attr, char *buf) +static ssize_t serial_number_show(struct device *dev, +				  struct device_attribute *attr, char *buf)  {  	struct usb_interface *interface = to_usb_interface(dev);  	struct usb_line6_pod *pod = usb_get_intfdata(interface); +  	return sprintf(buf, "%d\n", pod->serial_number);  }  /*  	"read" request on "firmware_version" special file.  */ -static ssize_t pod_get_firmware_version(struct device *dev, -					struct device_attribute *attr, -					char *buf) +static ssize_t firmware_version_show(struct device *dev, +				     struct device_attribute *attr, char *buf)  {  	struct usb_interface *interface = to_usb_interface(dev);  	struct usb_line6_pod *pod = usb_get_intfdata(interface); +  	return sprintf(buf, "%d.%02d\n", pod->firmware_version / 100,  		       pod->firmware_version % 100);  } @@ -930,24 +217,13 @@ static ssize_t pod_get_firmware_version(struct device *dev,  /*  	"read" request on "device_id" special file.  */ -static ssize_t pod_get_device_id(struct device *dev, -				 struct device_attribute *attr, char *buf) +static ssize_t device_id_show(struct device *dev, +			      struct device_attribute *attr, char *buf)  {  	struct usb_interface *interface = to_usb_interface(dev);  	struct usb_line6_pod *pod = usb_get_intfdata(interface); -	return sprintf(buf, "%d\n", pod->device_id); -} -/* -	"read" request on "clip" special file. -*/ -static ssize_t pod_wait_for_clip(struct device *dev, -				 struct device_attribute *attr, char *buf) -{ -	struct usb_interface *interface = to_usb_interface(dev); -	struct usb_line6_pod *pod = usb_get_intfdata(interface); -	return wait_event_interruptible(pod->clipping.wait, -					pod->clipping.value != 0); +	return sprintf(buf, "%d\n", pod->device_id);  }  /* @@ -969,30 +245,15 @@ static void pod_startup1(struct usb_line6_pod *pod)  static void pod_startup2(unsigned long data)  {  	struct usb_line6_pod *pod = (struct usb_line6_pod *)data; - -	/* schedule another startup procedure until startup is complete: */ -	if (pod->startup_progress >= POD_STARTUP_LAST) -		return; - -	pod->startup_progress = POD_STARTUP_DUMPREQ; -	line6_start_timer(&pod->startup_timer, POD_STARTUP_DELAY, pod_startup2, -			  (unsigned long)pod); - -	/* current channel dump: */ -	line6_dump_request_async(&pod->dumpreq, &pod->line6, 0, -				 LINE6_DUMP_CURRENT); -} - -static void pod_startup3(struct usb_line6_pod *pod) -{  	struct usb_line6 *line6 = &pod->line6; +  	CHECK_STARTUP_PROGRESS(pod->startup_progress, POD_STARTUP_VERSIONREQ);  	/* request firmware version: */  	line6_version_request_async(line6);  } -static void pod_startup4(struct usb_line6_pod *pod) +static void pod_startup3(struct usb_line6_pod *pod)  {  	CHECK_STARTUP_PROGRESS(pod->startup_progress, POD_STARTUP_WORKQUEUE); @@ -1000,7 +261,7 @@ static void pod_startup4(struct usb_line6_pod *pod)  	schedule_work(&pod->startup_work);  } -static void pod_startup5(struct work_struct *work) +static void pod_startup4(struct work_struct *work)  {  	struct usb_line6_pod *pod =  	    container_of(work, struct usb_line6_pod, startup_work); @@ -1013,87 +274,12 @@ static void pod_startup5(struct work_struct *work)  	/* ALSA audio interface: */  	line6_register_audio(line6); - -	/* device files: */ -	line6_pod_create_files(pod->firmware_version, -			       line6->properties->device_bit, line6->ifcdev); -} - -#define POD_GET_SYSTEM_PARAM(code, sign) \ -static ssize_t pod_get_ ## code(struct device *dev, \ -				struct device_attribute *attr, char *buf) \ -{ \ -	struct usb_interface *interface = to_usb_interface(dev); \ -	struct usb_line6_pod *pod = usb_get_intfdata(interface); \ -	return pod_get_system_param_string(pod, buf, POD_ ## code,	\ -					   &pod->code, sign);		\  } -#define POD_GET_SET_SYSTEM_PARAM(code, mask, sign) \ -POD_GET_SYSTEM_PARAM(code, sign) \ -static ssize_t pod_set_ ## code(struct device *dev, \ -				struct device_attribute *attr, \ -				const char *buf, size_t count) \ -{ \ -	struct usb_interface *interface = to_usb_interface(dev); \ -	struct usb_line6_pod *pod = usb_get_intfdata(interface); \ -	return pod_set_system_param_string(pod, buf, count, POD_ ## code, mask); \ -} - -POD_GET_SET_SYSTEM_PARAM(monitor_level, 0xffff, 0); -POD_GET_SET_SYSTEM_PARAM(routing, 0x0003, 0); -POD_GET_SET_SYSTEM_PARAM(tuner_mute, 0x0001, 0); -POD_GET_SET_SYSTEM_PARAM(tuner_freq, 0xffff, 0); -POD_GET_SYSTEM_PARAM(tuner_note, 1); -POD_GET_SYSTEM_PARAM(tuner_pitch, 1); - -#undef GET_SET_SYSTEM_PARAM -#undef GET_SYSTEM_PARAM -  /* POD special files: */ -static DEVICE_ATTR(channel, S_IWUGO | S_IRUGO, pod_get_channel, -		   pod_set_channel); -static DEVICE_ATTR(clip, S_IRUGO, pod_wait_for_clip, line6_nop_write); -static DEVICE_ATTR(device_id, S_IRUGO, pod_get_device_id, line6_nop_write); -static DEVICE_ATTR(dirty, S_IRUGO, pod_get_dirty, line6_nop_write); -static DEVICE_ATTR(dump, S_IWUGO | S_IRUGO, pod_get_dump, pod_set_dump); -static DEVICE_ATTR(dump_buf, S_IWUGO | S_IRUGO, pod_get_dump_buf, -		   pod_set_dump_buf); -static DEVICE_ATTR(finish, S_IWUGO, line6_nop_read, pod_set_finish); -static DEVICE_ATTR(firmware_version, S_IRUGO, pod_get_firmware_version, -		   line6_nop_write); -static DEVICE_ATTR(midi_postprocess, S_IWUGO | S_IRUGO, -		   pod_get_midi_postprocess, pod_set_midi_postprocess); -static DEVICE_ATTR(monitor_level, S_IWUGO | S_IRUGO, pod_get_monitor_level, -		   pod_set_monitor_level); -static DEVICE_ATTR(name, S_IRUGO, pod_get_name, line6_nop_write); -static DEVICE_ATTR(name_buf, S_IRUGO, pod_get_name_buf, line6_nop_write); -static DEVICE_ATTR(retrieve_amp_setup, S_IWUGO, line6_nop_read, -		   pod_set_retrieve_amp_setup); -static DEVICE_ATTR(retrieve_channel, S_IWUGO, line6_nop_read, -		   pod_set_retrieve_channel); -static DEVICE_ATTR(retrieve_effects_setup, S_IWUGO, line6_nop_read, -		   pod_set_retrieve_effects_setup); -static DEVICE_ATTR(routing, S_IWUGO | S_IRUGO, pod_get_routing, -		   pod_set_routing); -static DEVICE_ATTR(serial_number, S_IRUGO, pod_get_serial_number, -		   line6_nop_write); -static DEVICE_ATTR(store_amp_setup, S_IWUGO, line6_nop_read, -		   pod_set_store_amp_setup); -static DEVICE_ATTR(store_channel, S_IWUGO, line6_nop_read, -		   pod_set_store_channel); -static DEVICE_ATTR(store_effects_setup, S_IWUGO, line6_nop_read, -		   pod_set_store_effects_setup); -static DEVICE_ATTR(tuner_freq, S_IWUGO | S_IRUGO, pod_get_tuner_freq, -		   pod_set_tuner_freq); -static DEVICE_ATTR(tuner_mute, S_IWUGO | S_IRUGO, pod_get_tuner_mute, -		   pod_set_tuner_mute); -static DEVICE_ATTR(tuner_note, S_IRUGO, pod_get_tuner_note, line6_nop_write); -static DEVICE_ATTR(tuner_pitch, S_IRUGO, pod_get_tuner_pitch, line6_nop_write); - -#ifdef CONFIG_LINE6_USB_RAW -static DEVICE_ATTR(raw, S_IWUGO, line6_nop_read, line6_set_raw); -#endif +static DEVICE_ATTR_RO(device_id); +static DEVICE_ATTR_RO(firmware_version); +static DEVICE_ATTR_RO(serial_number);  /* control info callback */  static int snd_pod_control_monitor_info(struct snd_kcontrol *kcontrol, @@ -1112,7 +298,8 @@ static int snd_pod_control_monitor_get(struct snd_kcontrol *kcontrol,  {  	struct snd_line6_pcm *line6pcm = snd_kcontrol_chip(kcontrol);  	struct usb_line6_pod *pod = (struct usb_line6_pod *)line6pcm->line6; -	ucontrol->value.integer.value[0] = pod->monitor_level.value; + +	ucontrol->value.integer.value[0] = pod->monitor_level;  	return 0;  } @@ -1123,12 +310,12 @@ static int snd_pod_control_monitor_put(struct snd_kcontrol *kcontrol,  	struct snd_line6_pcm *line6pcm = snd_kcontrol_chip(kcontrol);  	struct usb_line6_pod *pod = (struct usb_line6_pod *)line6pcm->line6; -	if (ucontrol->value.integer.value[0] == pod->monitor_level.value) +	if (ucontrol->value.integer.value[0] == pod->monitor_level)  		return 0; -	pod->monitor_level.value = ucontrol->value.integer.value[0]; +	pod->monitor_level = ucontrol->value.integer.value[0];  	pod_set_system_param_int(pod, ucontrol->value.integer.value[0], -				 POD_monitor_level); +				 POD_MONITOR_LEVEL);  	return 1;  } @@ -1149,20 +336,13 @@ static struct snd_kcontrol_new pod_control_monitor = {  static void pod_destruct(struct usb_interface *interface)  {  	struct usb_line6_pod *pod = usb_get_intfdata(interface); -	struct usb_line6 *line6;  	if (pod == NULL)  		return; -	line6 = &pod->line6; -	if (line6 == NULL) -		return; -	line6_cleanup_audio(line6); +	line6_cleanup_audio(&pod->line6);  	del_timer(&pod->startup_timer);  	cancel_work_sync(&pod->startup_work); - -	/* free dump request data: */ -	line6_dumpreq_destruct(&pod->dumpreq);  }  /* @@ -1172,35 +352,9 @@ static int pod_create_files2(struct device *dev)  {  	int err; -	CHECK_RETURN(device_create_file(dev, &dev_attr_channel)); -	CHECK_RETURN(device_create_file(dev, &dev_attr_clip));  	CHECK_RETURN(device_create_file(dev, &dev_attr_device_id)); -	CHECK_RETURN(device_create_file(dev, &dev_attr_dirty)); -	CHECK_RETURN(device_create_file(dev, &dev_attr_dump)); -	CHECK_RETURN(device_create_file(dev, &dev_attr_dump_buf)); -	CHECK_RETURN(device_create_file(dev, &dev_attr_finish));  	CHECK_RETURN(device_create_file(dev, &dev_attr_firmware_version)); -	CHECK_RETURN(device_create_file(dev, &dev_attr_midi_postprocess)); -	CHECK_RETURN(device_create_file(dev, &dev_attr_monitor_level)); -	CHECK_RETURN(device_create_file(dev, &dev_attr_name)); -	CHECK_RETURN(device_create_file(dev, &dev_attr_name_buf)); -	CHECK_RETURN(device_create_file(dev, &dev_attr_retrieve_amp_setup)); -	CHECK_RETURN(device_create_file(dev, &dev_attr_retrieve_channel)); -	CHECK_RETURN(device_create_file(dev, &dev_attr_retrieve_effects_setup)); -	CHECK_RETURN(device_create_file(dev, &dev_attr_routing));  	CHECK_RETURN(device_create_file(dev, &dev_attr_serial_number)); -	CHECK_RETURN(device_create_file(dev, &dev_attr_store_amp_setup)); -	CHECK_RETURN(device_create_file(dev, &dev_attr_store_channel)); -	CHECK_RETURN(device_create_file(dev, &dev_attr_store_effects_setup)); -	CHECK_RETURN(device_create_file(dev, &dev_attr_tuner_freq)); -	CHECK_RETURN(device_create_file(dev, &dev_attr_tuner_mute)); -	CHECK_RETURN(device_create_file(dev, &dev_attr_tuner_note)); -	CHECK_RETURN(device_create_file(dev, &dev_attr_tuner_pitch)); - -#ifdef CONFIG_LINE6_USB_RAW -	CHECK_RETURN(device_create_file(dev, &dev_attr_raw)); -#endif -  	return 0;  } @@ -1214,32 +368,11 @@ static int pod_try_init(struct usb_interface *interface,  	struct usb_line6 *line6 = &pod->line6;  	init_timer(&pod->startup_timer); -	INIT_WORK(&pod->startup_work, pod_startup5); +	INIT_WORK(&pod->startup_work, pod_startup4);  	if ((interface == NULL) || (pod == NULL))  		return -ENODEV; -	pod->channel_num = 255; - -	/* initialize wait queues: */ -	init_waitqueue_head(&pod->monitor_level.wait); -	init_waitqueue_head(&pod->routing.wait); -	init_waitqueue_head(&pod->tuner_mute.wait); -	init_waitqueue_head(&pod->tuner_freq.wait); -	init_waitqueue_head(&pod->tuner_note.wait); -	init_waitqueue_head(&pod->tuner_pitch.wait); -	init_waitqueue_head(&pod->clipping.wait); - -	memset(pod->param_dirty, 0xff, sizeof(pod->param_dirty)); - -	/* initialize USB buffers: */ -	err = line6_dumpreq_init(&pod->dumpreq, pod_request_channel, -				 sizeof(pod_request_channel)); -	if (err < 0) { -		dev_err(&interface->dev, "Out of memory\n"); -		return -ENOMEM; -	} -  	/* create sysfs entries: */  	err = pod_create_files2(&interface->dev);  	if (err < 0) @@ -1273,7 +406,7 @@ static int pod_try_init(struct usb_interface *interface,  	 */  	if (pod->line6.properties->capabilities & LINE6_BIT_CONTROL) { -		pod->monitor_level.value = POD_system_invalid; +		pod->monitor_level = POD_SYSTEM_INVALID;  		/* initiate startup procedure: */  		pod_startup1(pod); @@ -1315,39 +448,9 @@ void line6_pod_disconnect(struct usb_interface *interface)  		if (dev != NULL) {  			/* remove sysfs entries: */ -			line6_pod_remove_files(pod->firmware_version, -					       pod->line6. -					       properties->device_bit, dev); - -			device_remove_file(dev, &dev_attr_channel); -			device_remove_file(dev, &dev_attr_clip);  			device_remove_file(dev, &dev_attr_device_id); -			device_remove_file(dev, &dev_attr_dirty); -			device_remove_file(dev, &dev_attr_dump); -			device_remove_file(dev, &dev_attr_dump_buf); -			device_remove_file(dev, &dev_attr_finish);  			device_remove_file(dev, &dev_attr_firmware_version); -			device_remove_file(dev, &dev_attr_midi_postprocess); -			device_remove_file(dev, &dev_attr_monitor_level); -			device_remove_file(dev, &dev_attr_name); -			device_remove_file(dev, &dev_attr_name_buf); -			device_remove_file(dev, &dev_attr_retrieve_amp_setup); -			device_remove_file(dev, &dev_attr_retrieve_channel); -			device_remove_file(dev, -					   &dev_attr_retrieve_effects_setup); -			device_remove_file(dev, &dev_attr_routing);  			device_remove_file(dev, &dev_attr_serial_number); -			device_remove_file(dev, &dev_attr_store_amp_setup); -			device_remove_file(dev, &dev_attr_store_channel); -			device_remove_file(dev, &dev_attr_store_effects_setup); -			device_remove_file(dev, &dev_attr_tuner_freq); -			device_remove_file(dev, &dev_attr_tuner_mute); -			device_remove_file(dev, &dev_attr_tuner_note); -			device_remove_file(dev, &dev_attr_tuner_pitch); - -#ifdef CONFIG_LINE6_USB_RAW -			device_remove_file(dev, &dev_attr_raw); -#endif  		}  	} diff --git a/drivers/staging/line6/pod.h b/drivers/staging/line6/pod.h index 18b9d08c328..3e3f1671337 100644 --- a/drivers/staging/line6/pod.h +++ b/drivers/staging/line6/pod.h @@ -15,12 +15,10 @@  #include <linux/interrupt.h>  #include <linux/spinlock.h>  #include <linux/usb.h> -#include <linux/wait.h>  #include <sound/core.h>  #include "driver.h" -#include "dumprequest.h"  /*  	PODxt Live interfaces @@ -46,37 +44,12 @@  */  enum {  	POD_STARTUP_INIT = 1, -	POD_STARTUP_DUMPREQ,  	POD_STARTUP_VERSIONREQ,  	POD_STARTUP_WORKQUEUE,  	POD_STARTUP_SETUP,  	POD_STARTUP_LAST = POD_STARTUP_SETUP - 1  }; -/** -	Data structure for values that need to be requested explicitly. -	This is the case for system and tuner settings. -*/ -struct ValueWait { -	int value; -	wait_queue_head_t wait; -}; - -/** -	Binary PODxt Pro program dump -*/ -struct pod_program { -	/** -		Header information (including program name). -	*/ -	unsigned char header[0x20]; - -	/** -		Program parameters. -	*/ -	unsigned char control[POD_CONTROL_SIZE]; -}; -  struct usb_line6_pod {  	/**  		Generic Line6 USB data. @@ -84,63 +57,9 @@ struct usb_line6_pod {  	struct usb_line6 line6;  	/** -		Dump request structure. -	*/ -	struct line6_dump_request dumpreq; - -	/** -		Current program number. -	*/ -	unsigned char channel_num; - -	/** -		Current program settings. -	*/ -	struct pod_program prog_data; - -	/** -		Buffer for data retrieved from or to be stored on PODxt Pro. -	*/ -	struct pod_program prog_data_buf; - -	/** -		Tuner mute mode. -	*/ -	struct ValueWait tuner_mute; - -	/** -		Tuner base frequency (typically 440Hz). -	*/ -	struct ValueWait tuner_freq; - -	/** -		Note received from tuner. -	*/ -	struct ValueWait tuner_note; - -	/** -		Pitch value received from tuner. -	*/ -	struct ValueWait tuner_pitch; - -	/**  		Instrument monitor level.  	*/ -	struct ValueWait monitor_level; - -	/** -		Audio routing mode. -		0: send processed guitar -		1: send clean guitar -		2: send clean guitar re-amp playback -		3: send re-amp playback -	*/ -	struct ValueWait routing; - -	/** -		Wait for audio clipping event. -	*/ -	struct ValueWait clipping; +	int monitor_level;  	/**  		Timer for device initializaton. @@ -158,16 +77,6 @@ struct usb_line6_pod {  	int startup_progress;  	/** -		Dirty flags for access to parameter data. -	*/ -	unsigned long param_dirty[POD_CONTROL_SIZE / sizeof(unsigned long)]; - -	/** -		Some atomic flags. -	*/ -	unsigned long atomic_flags; - -	/**  		Serial number of device.  	*/  	int serial_number; @@ -181,25 +90,13 @@ struct usb_line6_pod {  		Device ID.  	*/  	int device_id; - -	/** -		Flag to indicate modification of current program settings. -	*/ -	char dirty; - -	/** -		Flag to enable MIDI postprocessing. -	*/ -	char midi_postprocess;  };  extern void line6_pod_disconnect(struct usb_interface *interface);  extern int line6_pod_init(struct usb_interface *interface,  			  struct usb_line6_pod *pod); -extern void line6_pod_midi_postprocess(struct usb_line6_pod *pod, -				       unsigned char *data, int length);  extern void line6_pod_process_message(struct usb_line6_pod *pod);  extern void line6_pod_transmit_parameter(struct usb_line6_pod *pod, int param, -					 int value); +					 u8 value);  #endif diff --git a/drivers/staging/line6/podhd.c b/drivers/staging/line6/podhd.c new file mode 100644 index 00000000000..7ef45437b4f --- /dev/null +++ b/drivers/staging/line6/podhd.c @@ -0,0 +1,154 @@ +/* + * 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. + * + */ + +#include <sound/core.h> +#include <sound/pcm.h> + +#include "audio.h" +#include "driver.h" +#include "pcm.h" +#include "podhd.h" + +#define PODHD_BYTES_PER_FRAME 6	/* 24bit audio (stereo) */ + +static struct snd_ratden podhd_ratden = { +	.num_min = 48000, +	.num_max = 48000, +	.num_step = 1, +	.den = 1, +}; + +static struct line6_pcm_properties podhd_pcm_properties = { +	.snd_line6_playback_hw = { +				  .info = (SNDRV_PCM_INFO_MMAP | +					   SNDRV_PCM_INFO_INTERLEAVED | +					   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, +				  .rate_min = 48000, +				  .rate_max = 48000, +				  .channels_min = 2, +				  .channels_max = 2, +				  .buffer_bytes_max = 60000, +				  .period_bytes_min = 64, +				  .period_bytes_max = 8192, +				  .periods_min = 1, +				  .periods_max = 1024}, +	.snd_line6_capture_hw = { +				 .info = (SNDRV_PCM_INFO_MMAP | +					  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, +				 .rate_min = 48000, +				 .rate_max = 48000, +				 .channels_min = 2, +				 .channels_max = 2, +				 .buffer_bytes_max = 60000, +				 .period_bytes_min = 64, +				 .period_bytes_max = 8192, +				 .periods_min = 1, +				 .periods_max = 1024}, +	.snd_line6_rates = { +			    .nrats = 1, +			    .rats = &podhd_ratden}, +	.bytes_per_frame = PODHD_BYTES_PER_FRAME +}; + +/* +	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); +} + +/* +	Try to init POD HD device. +*/ +static int podhd_try_init(struct usb_interface *interface, +			  struct usb_line6_podhd *podhd) +{ +	int err; +	struct usb_line6 *line6 = &podhd->line6; + +	if ((interface == NULL) || (podhd == NULL)) +		return -ENODEV; + +	/* initialize audio system: */ +	err = line6_init_audio(line6); +	if (err < 0) +		return err; + +	/* initialize MIDI subsystem: */ +	err = line6_init_midi(line6); +	if (err < 0) +		return err; + +	/* initialize PCM subsystem: */ +	err = line6_init_pcm(line6, &podhd_pcm_properties); +	if (err < 0) +		return err; + +	/* register USB audio system: */ +	err = line6_register_audio(line6); +	return err; +} + +/* +	Init POD HD device (and clean up in case of failure). +*/ +int line6_podhd_init(struct usb_interface *interface, +		     struct usb_line6_podhd *podhd) +{ +	int err = podhd_try_init(interface, podhd); + +	if (err < 0) +		podhd_destruct(interface); + +	return err; +} + +/* +	POD HD device disconnected. +*/ +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); +} diff --git a/drivers/staging/line6/podhd.h b/drivers/staging/line6/podhd.h new file mode 100644 index 00000000000..652f74056bb --- /dev/null +++ b/drivers/staging/line6/podhd.h @@ -0,0 +1,30 @@ +/* + * 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 void line6_podhd_disconnect(struct usb_interface *interface); +extern int line6_podhd_init(struct usb_interface *interface, +			    struct usb_line6_podhd *podhd); + +#endif /* PODHD_H */ diff --git a/drivers/staging/line6/revision.h b/drivers/staging/line6/revision.h index 350d0dfff8f..b4eee2b7383 100644 --- a/drivers/staging/line6/revision.h +++ b/drivers/staging/line6/revision.h @@ -1,4 +1,4 @@  #ifndef DRIVER_REVISION  /* current subversion revision */ -#define DRIVER_REVISION " (revision 690)" +#define DRIVER_REVISION " (904)"  #endif diff --git a/drivers/staging/line6/toneport.c b/drivers/staging/line6/toneport.c index 6a10b0f9749..69437158d38 100644 --- a/drivers/staging/line6/toneport.c +++ b/drivers/staging/line6/toneport.c @@ -87,12 +87,10 @@ static struct line6_pcm_properties toneport_pcm_properties = {  static int led_red = 0x00;  static int led_green = 0x26; -struct ToneportSourceInfo { +static const struct {  	const char *name;  	int code; -}; - -static const struct ToneportSourceInfo toneport_source_info[] = { +} toneport_source_info[] = {  	{"Microphone", 0x0a01},  	{"Line", 0x0801},  	{"Instrument", 0x0b01}, @@ -127,13 +125,11 @@ static ssize_t toneport_set_led_red(struct device *dev,  				    const char *buf, size_t count)  {  	int retval; -	long value; -	retval = strict_strtol(buf, 10, &value); +	retval = kstrtoint(buf, 10, &led_red);  	if (retval)  		return retval; -	led_red = value;  	toneport_update_led(dev);  	return count;  } @@ -143,20 +139,18 @@ static ssize_t toneport_set_led_green(struct device *dev,  				      const char *buf, size_t count)  {  	int retval; -	long value; -	retval = strict_strtol(buf, 10, &value); +	retval = kstrtoint(buf, 10, &led_green);  	if (retval)  		return retval; -	led_green = value;  	toneport_update_led(dev);  	return count;  } -static DEVICE_ATTR(led_red, S_IWUGO | S_IRUGO, line6_nop_read, +static DEVICE_ATTR(led_red, S_IWUSR | S_IRUGO, line6_nop_read,  		   toneport_set_led_red); -static DEVICE_ATTR(led_green, S_IWUGO | S_IRUGO, line6_nop_read, +static DEVICE_ATTR(led_green, S_IWUSR | S_IRUGO, line6_nop_read,  		   toneport_set_led_green);  static int toneport_send_cmd(struct usb_device *usbdev, int cmd1, int cmd2) @@ -168,7 +162,7 @@ static int toneport_send_cmd(struct usb_device *usbdev, int cmd1, int cmd2)  			      cmd1, cmd2, NULL, 0, LINE6_TIMEOUT * HZ);  	if (ret < 0) { -		err("send failed (error %d)\n", ret); +		dev_err(&usbdev->dev, "send failed (error %d)\n", ret);  		return ret;  	} @@ -191,6 +185,7 @@ static int snd_toneport_monitor_get(struct snd_kcontrol *kcontrol,  				    struct snd_ctl_elem_value *ucontrol)  {  	struct snd_line6_pcm *line6pcm = snd_kcontrol_chip(kcontrol); +  	ucontrol->value.integer.value[0] = line6pcm->volume_monitor;  	return 0;  } @@ -207,9 +202,9 @@ static int snd_toneport_monitor_put(struct snd_kcontrol *kcontrol,  	line6pcm->volume_monitor = ucontrol->value.integer.value[0];  	if (line6pcm->volume_monitor > 0) -		line6_pcm_start(line6pcm, MASK_PCM_MONITOR); +		line6_pcm_acquire(line6pcm, LINE6_BITS_PCM_MONITOR);  	else -		line6_pcm_stop(line6pcm, MASK_PCM_MONITOR); +		line6_pcm_release(line6pcm, LINE6_BITS_PCM_MONITOR);  	return 1;  } @@ -219,6 +214,7 @@ static int snd_toneport_source_info(struct snd_kcontrol *kcontrol,  				    struct snd_ctl_elem_info *uinfo)  {  	const int size = ARRAY_SIZE(toneport_source_info); +  	uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;  	uinfo->count = 1;  	uinfo->value.enumerated.items = size; @@ -250,13 +246,17 @@ static int snd_toneport_source_put(struct snd_kcontrol *kcontrol,  	struct snd_line6_pcm *line6pcm = snd_kcontrol_chip(kcontrol);  	struct usb_line6_toneport *toneport =  	    (struct usb_line6_toneport *)line6pcm->line6; +	unsigned int source; -	if (ucontrol->value.enumerated.item[0] == toneport->source) +	source = ucontrol->value.enumerated.item[0]; +	if (source >= ARRAY_SIZE(toneport_source_info)) +		return -EINVAL; +	if (source == toneport->source)  		return 0; -	toneport->source = ucontrol->value.enumerated.item[0]; +	toneport->source = source;  	toneport_send_cmd(toneport->line6.usbdev, -			  toneport_source_info[toneport->source].code, 0x0000); +			  toneport_source_info[source].code, 0x0000);  	return 1;  } @@ -264,7 +264,8 @@ static void toneport_start_pcm(unsigned long arg)  {  	struct usb_line6_toneport *toneport = (struct usb_line6_toneport *)arg;  	struct usb_line6 *line6 = &toneport->line6; -	line6_pcm_start(line6->line6pcm, MASK_PCM_MONITOR); + +	line6_pcm_acquire(line6->line6pcm, LINE6_BITS_PCM_MONITOR);  }  /* control definition */ @@ -295,14 +296,10 @@ static struct snd_kcontrol_new toneport_control_source = {  static void toneport_destruct(struct usb_interface *interface)  {  	struct usb_line6_toneport *toneport = usb_get_intfdata(interface); -	struct usb_line6 *line6;  	if (toneport == NULL)  		return; -	line6 = &toneport->line6; -	if (line6 == NULL) -		return; -	line6_cleanup_audio(line6); +	line6_cleanup_audio(&toneport->line6);  }  /* @@ -313,6 +310,7 @@ static void toneport_setup(struct usb_line6_toneport *toneport)  	int ticks;  	struct usb_line6 *line6 = &toneport->line6;  	struct usb_device *usbdev = line6->usbdev; +	u16 idProduct = le16_to_cpu(usbdev->descriptor.idProduct);  	/* sync time on device with host: */  	ticks = (int)get_seconds(); @@ -322,15 +320,17 @@ static void toneport_setup(struct usb_line6_toneport *toneport)  	toneport_send_cmd(usbdev, 0x0301, 0x0000);  	/* initialize source select: */ -	switch (usbdev->descriptor.idProduct) { +	switch (le16_to_cpu(usbdev->descriptor.idProduct)) {  	case LINE6_DEVID_TONEPORT_UX1: +	case LINE6_DEVID_TONEPORT_UX2:  	case LINE6_DEVID_PODSTUDIO_UX1: +	case LINE6_DEVID_PODSTUDIO_UX2:  		toneport_send_cmd(usbdev,  				  toneport_source_info[toneport->source].code,  				  0x0000);  	} -	if (toneport_has_led(usbdev->descriptor.idProduct)) +	if (toneport_has_led(idProduct))  		toneport_update_led(&usbdev->dev);  } @@ -343,6 +343,7 @@ static int toneport_try_init(struct usb_interface *interface,  	int err;  	struct usb_line6 *line6 = &toneport->line6;  	struct usb_device *usbdev = line6->usbdev; +	u16 idProduct = le16_to_cpu(usbdev->descriptor.idProduct);  	if ((interface == NULL) || (toneport == NULL))  		return -ENODEV; @@ -365,9 +366,11 @@ static int toneport_try_init(struct usb_interface *interface,  		return err;  	/* register source select control: */ -	switch (usbdev->descriptor.idProduct) { +	switch (le16_to_cpu(usbdev->descriptor.idProduct)) {  	case LINE6_DEVID_TONEPORT_UX1: +	case LINE6_DEVID_TONEPORT_UX2:  	case LINE6_DEVID_PODSTUDIO_UX1: +	case LINE6_DEVID_PODSTUDIO_UX2:  		err =  		    snd_ctl_add(line6->card,  				snd_ctl_new1(&toneport_control_source, @@ -384,7 +387,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(usbdev->descriptor.idProduct)) { +	if (toneport_has_led(idProduct)) {  		CHECK_RETURN(device_create_file  			     (&interface->dev, &dev_attr_led_red));  		CHECK_RETURN(device_create_file @@ -430,14 +433,16 @@ void line6_toneport_reset_resume(struct usb_line6_toneport *toneport)  void line6_toneport_disconnect(struct usb_interface *interface)  {  	struct usb_line6_toneport *toneport; +	u16 idProduct;  	if (interface == NULL)  		return;  	toneport = usb_get_intfdata(interface);  	del_timer_sync(&toneport->timer); +	idProduct = le16_to_cpu(toneport->line6.usbdev->descriptor.idProduct); -	if (toneport_has_led(toneport->line6.usbdev->descriptor.idProduct)) { +	if (toneport_has_led(idProduct)) {  		device_remove_file(&interface->dev, &dev_attr_led_red);  		device_remove_file(&interface->dev, &dev_attr_led_green);  	} @@ -446,7 +451,7 @@ void line6_toneport_disconnect(struct usb_interface *interface)  		struct snd_line6_pcm *line6pcm = toneport->line6.line6pcm;  		if (line6pcm != NULL) { -			line6_pcm_stop(line6pcm, MASK_PCM_MONITOR); +			line6_pcm_release(line6pcm, LINE6_BITS_PCM_MONITOR);  			line6_pcm_disconnect(line6pcm);  		}  	} diff --git a/drivers/staging/line6/usbdefs.h b/drivers/staging/line6/usbdefs.h index c6dffe6bc1a..2d1cc472bea 100644 --- a/drivers/staging/line6/usbdefs.h +++ b/drivers/staging/line6/usbdefs.h @@ -24,6 +24,9 @@  #define LINE6_DEVID_BASSPODXTPRO  0x4252  #define LINE6_DEVID_GUITARPORT    0x4750  #define LINE6_DEVID_POCKETPOD     0x5051 +#define LINE6_DEVID_PODHD300      0x5057 +#define LINE6_DEVID_PODHD400      0x5058 +#define LINE6_DEVID_PODHD500      0x414D  #define LINE6_DEVID_PODSTUDIO_GX  0x4153  #define LINE6_DEVID_PODSTUDIO_UX1 0x4150  #define LINE6_DEVID_PODSTUDIO_UX2 0x4151 @@ -37,48 +40,77 @@  #define LINE6_DEVID_TONEPORT_UX2  0x4142  #define LINE6_DEVID_VARIAX        0x534d -#define LINE6_BIT_BASSPODXT       (1 <<  0) -#define LINE6_BIT_BASSPODXTLIVE   (1 <<  1) -#define LINE6_BIT_BASSPODXTPRO    (1 <<  2) -#define LINE6_BIT_GUITARPORT      (1 <<  3) -#define LINE6_BIT_POCKETPOD       (1 <<  4) -#define LINE6_BIT_PODSTUDIO_GX    (1 <<  5) -#define LINE6_BIT_PODSTUDIO_UX1   (1 <<  6) -#define LINE6_BIT_PODSTUDIO_UX2   (1 <<  7) -#define LINE6_BIT_PODX3           (1 <<  8) -#define LINE6_BIT_PODX3LIVE       (1 <<  9) -#define LINE6_BIT_PODXT           (1 << 10) -#define LINE6_BIT_PODXTLIVE       (1 << 11) -#define LINE6_BIT_PODXTPRO        (1 << 12) -#define LINE6_BIT_TONEPORT_GX     (1 << 13) -#define LINE6_BIT_TONEPORT_UX1    (1 << 14) -#define LINE6_BIT_TONEPORT_UX2    (1 << 15) -#define LINE6_BIT_VARIAX          (1 << 16) +#define LINE6_BIT(x) LINE6_BIT_ ## x = 1 << LINE6_INDEX_ ## x -#define LINE6_BITS_PRO		(LINE6_BIT_BASSPODXTPRO | \ -				 LINE6_BIT_PODXTPRO) -#define LINE6_BITS_LIVE		(LINE6_BIT_BASSPODXTLIVE | \ -				 LINE6_BIT_PODXTLIVE | \ -				 LINE6_BIT_PODX3LIVE) -#define LINE6_BITS_PODXTALL	(LINE6_BIT_PODXT | \ -				 LINE6_BIT_PODXTLIVE | \ -				 LINE6_BIT_PODXTPRO) -#define LINE6_BITS_BASSPODXTALL	(LINE6_BIT_BASSPODXT | \ -				 LINE6_BIT_BASSPODXTLIVE | \ -				 LINE6_BIT_BASSPODXTPRO) +enum { +	LINE6_INDEX_BASSPODXT, +	LINE6_INDEX_BASSPODXTLIVE, +	LINE6_INDEX_BASSPODXTPRO, +	LINE6_INDEX_GUITARPORT, +	LINE6_INDEX_POCKETPOD, +	LINE6_INDEX_PODHD300, +	LINE6_INDEX_PODHD400, +	LINE6_INDEX_PODHD500, +	LINE6_INDEX_PODSTUDIO_GX, +	LINE6_INDEX_PODSTUDIO_UX1, +	LINE6_INDEX_PODSTUDIO_UX2, +	LINE6_INDEX_PODX3, +	LINE6_INDEX_PODX3LIVE, +	LINE6_INDEX_PODXT, +	LINE6_INDEX_PODXTLIVE, +	LINE6_INDEX_PODXTPRO, +	LINE6_INDEX_TONEPORT_GX, +	LINE6_INDEX_TONEPORT_UX1, +	LINE6_INDEX_TONEPORT_UX2, +	LINE6_INDEX_VARIAX, + +	LINE6_BIT(BASSPODXT), +	LINE6_BIT(BASSPODXTLIVE), +	LINE6_BIT(BASSPODXTPRO), +	LINE6_BIT(GUITARPORT), +	LINE6_BIT(POCKETPOD), +	LINE6_BIT(PODHD300), +	LINE6_BIT(PODHD400), +	LINE6_BIT(PODHD500), +	LINE6_BIT(PODSTUDIO_GX), +	LINE6_BIT(PODSTUDIO_UX1), +	LINE6_BIT(PODSTUDIO_UX2), +	LINE6_BIT(PODX3), +	LINE6_BIT(PODX3LIVE), +	LINE6_BIT(PODXT), +	LINE6_BIT(PODXTLIVE), +	LINE6_BIT(PODXTPRO), +	LINE6_BIT(TONEPORT_GX), +	LINE6_BIT(TONEPORT_UX1), +	LINE6_BIT(TONEPORT_UX2), +	LINE6_BIT(VARIAX), + +	LINE6_BITS_PRO = LINE6_BIT_BASSPODXTPRO | LINE6_BIT_PODXTPRO, +	LINE6_BITS_LIVE = LINE6_BIT_BASSPODXTLIVE | LINE6_BIT_PODXTLIVE | +			  LINE6_BIT_PODX3LIVE, +	LINE6_BITS_PODXTALL = LINE6_BIT_PODXT | LINE6_BIT_PODXTLIVE | +			      LINE6_BIT_PODXTPRO, +	LINE6_BITS_PODX3ALL = LINE6_BIT_PODX3 | LINE6_BIT_PODX3LIVE, +	LINE6_BITS_PODHDALL = LINE6_BIT_PODHD300 | +			      LINE6_BIT_PODHD400 | +			      LINE6_BIT_PODHD500, +	LINE6_BITS_BASSPODXTALL	= LINE6_BIT_BASSPODXT | +				  LINE6_BIT_BASSPODXTLIVE | +				  LINE6_BIT_BASSPODXTPRO +};  /* device supports settings parameter via USB */ -#define LINE6_BIT_CONTROL	(1 << 0) +#define LINE6_BIT_CONTROL (1 << 0)  /* device supports PCM input/output via USB */ -#define LINE6_BIT_PCM		(1 << 1) +#define LINE6_BIT_PCM (1 << 1)  /* device support hardware monitoring */ -#define LINE6_BIT_HWMON		(1 << 2) +#define LINE6_BIT_HWMON (1 << 2) -#define LINE6_BIT_CONTROL_PCM_HWMON	(LINE6_BIT_CONTROL |	\ +#define LINE6_BIT_CTRL_PCM_HW	(LINE6_BIT_CONTROL |	\  					 LINE6_BIT_PCM |	\  					 LINE6_BIT_HWMON) -#define LINE6_FALLBACK_INTERVAL		10 -#define LINE6_FALLBACK_MAXPACKETSIZE	16 +#define LINE6_FALLBACK_INTERVAL 10 +#define LINE6_FALLBACK_MAXPACKETSIZE 16  #endif diff --git a/drivers/staging/line6/variax.c b/drivers/staging/line6/variax.c index 894eee7f231..ae2be99f9a9 100644 --- a/drivers/staging/line6/variax.c +++ b/drivers/staging/line6/variax.c @@ -12,28 +12,13 @@  #include <linux/slab.h>  #include "audio.h" -#include "control.h"  #include "driver.h"  #include "variax.h" -#define VARIAX_SYSEX_CODE 7 -#define VARIAX_SYSEX_PARAM 0x3b -#define VARIAX_SYSEX_ACTIVATE 0x2a -#define VARIAX_MODEL_HEADER_LENGTH 7 -#define VARIAX_MODEL_MESSAGE_LENGTH 199  #define VARIAX_OFFSET_ACTIVATE 7  /*  	This message is sent by the device during initialization and identifies -	the connected guitar model. -*/ -static const char variax_init_model[] = { -	0xf0, 0x00, 0x01, 0x0c, 0x07, 0x00, 0x69, 0x02, -	0x00 -}; - -/* -	This message is sent by the device during initialization and identifies  	the connected guitar version.  */  static const char variax_init_version[] = { @@ -53,43 +38,11 @@ static const char variax_activate[] = {  	0xf7  }; -static const char variax_request_bank[] = { -	0xf0, 0x00, 0x01, 0x0c, 0x07, 0x00, 0x6d, 0xf7 -}; - -static const char variax_request_model1[] = { -	0xf0, 0x00, 0x01, 0x0c, 0x07, 0x00, 0x3c, 0x00, -	0x02, 0x00, 0x00, 0x00, 0x00, 0x03, 0x05, 0x03, -	0x00, 0x00, 0x00, 0xf7 -}; - -static const char variax_request_model2[] = { -	0xf0, 0x00, 0x01, 0x0c, 0x07, 0x00, 0x3c, 0x00, -	0x02, 0x00, 0x00, 0x00, 0x00, 0x03, 0x07, 0x03, -	0x00, 0x00, 0x00, 0xf7 -}; -  /* forward declarations: */ -static int variax_create_files2(struct device *dev);  static void variax_startup2(unsigned long data);  static void variax_startup4(unsigned long data);  static void variax_startup5(unsigned long data); -/* -	Decode data transmitted by workbench. -*/ -static void variax_decode(const unsigned char *raw_data, unsigned char *data, -			  int raw_size) -{ -	for (; raw_size > 0; raw_size -= 6) { -		data[2] = raw_data[0] | (raw_data[1] << 4); -		data[1] = raw_data[2] | (raw_data[3] << 4); -		data[0] = raw_data[4] | (raw_data[5] << 4); -		raw_data += 6; -		data += 3; -	} -} -  static void variax_activate_async(struct usb_line6_variax *variax, int a)  {  	variax->buffer_activate[VARIAX_OFFSET_ACTIVATE] = a; @@ -142,6 +95,7 @@ static void variax_startup3(struct usb_line6_variax *variax)  static void variax_startup4(unsigned long data)  {  	struct usb_line6_variax *variax = (struct usb_line6_variax *)data; +  	CHECK_STARTUP_PROGRESS(variax->startup_progress,  			       VARIAX_STARTUP_ACTIVATE); @@ -154,17 +108,7 @@ static void variax_startup4(unsigned long data)  static void variax_startup5(unsigned long data)  {  	struct usb_line6_variax *variax = (struct usb_line6_variax *)data; -	CHECK_STARTUP_PROGRESS(variax->startup_progress, -			       VARIAX_STARTUP_DUMPREQ); - -	/* current model dump: */ -	line6_dump_request_async(&variax->dumpreq, &variax->line6, 0, -				 VARIAX_DUMP_PASS1); -	/* passes 2 and 3 are performed implicitly before entering variax_startup6 */ -} -static void variax_startup6(struct usb_line6_variax *variax) -{  	CHECK_STARTUP_PROGRESS(variax->startup_progress,  			       VARIAX_STARTUP_WORKQUEUE); @@ -172,20 +116,15 @@ static void variax_startup6(struct usb_line6_variax *variax)  	schedule_work(&variax->startup_work);  } -static void variax_startup7(struct work_struct *work) +static void variax_startup6(struct work_struct *work)  {  	struct usb_line6_variax *variax =  	    container_of(work, struct usb_line6_variax, startup_work); -	struct usb_line6 *line6 = &variax->line6;  	CHECK_STARTUP_PROGRESS(variax->startup_progress, VARIAX_STARTUP_SETUP);  	/* ALSA audio interface: */  	line6_register_audio(&variax->line6); - -	/* device files: */ -	line6_variax_create_files(0, 0, line6->ifcdev); -	variax_create_files2(line6->ifcdev);  }  /* @@ -196,425 +135,42 @@ void line6_variax_process_message(struct usb_line6_variax *variax)  	const unsigned char *buf = variax->line6.buffer_message;  	switch (buf[0]) { -	case LINE6_PARAM_CHANGE | LINE6_CHANNEL_HOST: -		switch (buf[1]) { -		case VARIAXMIDI_volume: -			variax->volume = buf[2]; -			break; - -		case VARIAXMIDI_tone: -			variax->tone = buf[2]; -		} - -		break; - -	case LINE6_PROGRAM_CHANGE | LINE6_CHANNEL_DEVICE: -	case LINE6_PROGRAM_CHANGE | LINE6_CHANNEL_HOST: -		variax->model = buf[1]; -		line6_dump_request_async(&variax->dumpreq, &variax->line6, 0, -					 VARIAX_DUMP_PASS1); -		break; -  	case LINE6_RESET:  		dev_info(variax->line6.ifcdev, "VARIAX reset\n");  		break;  	case LINE6_SYSEX_BEGIN: -		if (memcmp(buf + 1, variax_request_model1 + 1, -			   VARIAX_MODEL_HEADER_LENGTH - 1) == 0) { -			if (variax->line6.message_length == -			    VARIAX_MODEL_MESSAGE_LENGTH) { -				switch (variax->dumpreq.in_progress) { -				case VARIAX_DUMP_PASS1: -					variax_decode(buf + -						      VARIAX_MODEL_HEADER_LENGTH, -						      (unsigned char *) -						      &variax->model_data, -						      (sizeof -						       (variax->model_data. -							name) + -						       sizeof(variax-> -							      model_data. -							      control) -						       / 2) * 2); -					line6_dump_request_async -					    (&variax->dumpreq, &variax->line6, -					     1, VARIAX_DUMP_PASS2); -					break; - -				case VARIAX_DUMP_PASS2: -					/* model name is transmitted twice, so skip it here: */ -					variax_decode(buf + -						      VARIAX_MODEL_HEADER_LENGTH, -						      (unsigned char *) -						      &variax-> -						      model_data.control + -						      sizeof(variax->model_data. -							     control) -						      / 2, -						      sizeof(variax->model_data. -							     control) -						      / 2 * 2); -					line6_dump_request_async -					    (&variax->dumpreq, &variax->line6, -					     2, VARIAX_DUMP_PASS3); -				} -			} else { -				DEBUG_MESSAGES(dev_err -					       (variax->line6.ifcdev, -						"illegal length %d of model data\n", -						variax->line6.message_length)); -				line6_dump_finished(&variax->dumpreq); -			} -		} else if (memcmp(buf + 1, variax_request_bank + 1, -				  sizeof(variax_request_bank) - 2) == 0) { -			memcpy(variax->bank, -			       buf + sizeof(variax_request_bank) - 1, -			       sizeof(variax->bank)); -			line6_dump_finished(&variax->dumpreq); -			variax_startup6(variax); -		} else if (memcmp(buf + 1, variax_init_model + 1, -				  sizeof(variax_init_model) - 1) == 0) { -			memcpy(variax->guitar, -			       buf + sizeof(variax_init_model), -			       sizeof(variax->guitar)); -		} else if (memcmp(buf + 1, variax_init_version + 1, -				  sizeof(variax_init_version) - 1) == 0) { +		if (memcmp(buf + 1, variax_init_version + 1, +			   sizeof(variax_init_version) - 1) == 0) {  			variax_startup3(variax);  		} else if (memcmp(buf + 1, variax_init_done + 1,  				  sizeof(variax_init_done) - 1) == 0) {  			/* notify of complete initialization: */  			variax_startup4((unsigned long)variax);  		} -  		break; - -	case LINE6_SYSEX_END: -		break; - -	default: -		DEBUG_MESSAGES(dev_err -			       (variax->line6.ifcdev, -				"Variax: unknown message %02X\n", buf[0]));  	}  }  /* -	"read" request on "volume" special file. -*/ -static ssize_t variax_get_volume(struct device *dev, -				 struct device_attribute *attr, char *buf) -{ -	struct usb_line6_variax *variax = -	    usb_get_intfdata(to_usb_interface(dev)); -	return sprintf(buf, "%d\n", variax->volume); -} - -/* -	"write" request on "volume" special file. -*/ -static ssize_t variax_set_volume(struct device *dev, -				 struct device_attribute *attr, -				 const char *buf, size_t count) -{ -	struct usb_line6_variax *variax = -	    usb_get_intfdata(to_usb_interface(dev)); -	unsigned long value; -	int ret; - -	ret = strict_strtoul(buf, 10, &value); -	if (ret) -		return ret; - -	if (line6_transmit_parameter(&variax->line6, VARIAXMIDI_volume, -				     value) == 0) -		variax->volume = value; - -	return count; -} - -/* -	"read" request on "model" special file. -*/ -static ssize_t variax_get_model(struct device *dev, -				struct device_attribute *attr, char *buf) -{ -	struct usb_line6_variax *variax = -	    usb_get_intfdata(to_usb_interface(dev)); -	return sprintf(buf, "%d\n", variax->model); -} - -/* -	"write" request on "model" special file. -*/ -static ssize_t variax_set_model(struct device *dev, -				struct device_attribute *attr, -				const char *buf, size_t count) -{ -	struct usb_line6_variax *variax = -	    usb_get_intfdata(to_usb_interface(dev)); -	unsigned long value; -	int ret; - -	ret = strict_strtoul(buf, 10, &value); -	if (ret) -		return ret; - -	if (line6_send_program(&variax->line6, value) == 0) -		variax->model = value; - -	return count; -} - -/* -	"read" request on "active" special file. -*/ -static ssize_t variax_get_active(struct device *dev, -				 struct device_attribute *attr, char *buf) -{ -	struct usb_line6_variax *variax = -	    usb_get_intfdata(to_usb_interface(dev)); -	return sprintf(buf, "%d\n", -		       variax->buffer_activate[VARIAX_OFFSET_ACTIVATE]); -} - -/* -	"write" request on "active" special file. -*/ -static ssize_t variax_set_active(struct device *dev, -				 struct device_attribute *attr, -				 const char *buf, size_t count) -{ -	struct usb_line6_variax *variax = -	    usb_get_intfdata(to_usb_interface(dev)); -	unsigned long value; -	int ret; - -	ret = strict_strtoul(buf, 10, &value); -	if (ret) -		return ret; - -	variax_activate_async(variax, value ? 1 : 0); -	return count; -} - -/* -	"read" request on "tone" special file. -*/ -static ssize_t variax_get_tone(struct device *dev, -			       struct device_attribute *attr, char *buf) -{ -	struct usb_line6_variax *variax = -	    usb_get_intfdata(to_usb_interface(dev)); -	return sprintf(buf, "%d\n", variax->tone); -} - -/* -	"write" request on "tone" special file. -*/ -static ssize_t variax_set_tone(struct device *dev, -			       struct device_attribute *attr, -			       const char *buf, size_t count) -{ -	struct usb_line6_variax *variax = -	    usb_get_intfdata(to_usb_interface(dev)); -	unsigned long value; -	int ret; - -	ret = strict_strtoul(buf, 10, &value); -	if (ret) -		return ret; - -	if (line6_transmit_parameter(&variax->line6, VARIAXMIDI_tone, -				     value) == 0) -		variax->tone = value; - -	return count; -} - -static ssize_t get_string(char *buf, const char *data, int length) -{ -	int i; -	memcpy(buf, data, length); - -	for (i = length; i--;) { -		char c = buf[i]; - -		if ((c != 0) && (c != ' ')) -			break; -	} - -	buf[i + 1] = '\n'; -	return i + 2; -} - -/* -	"read" request on "name" special file. -*/ -static ssize_t variax_get_name(struct device *dev, -			       struct device_attribute *attr, char *buf) -{ -	struct usb_line6_variax *variax = -	    usb_get_intfdata(to_usb_interface(dev)); -	line6_dump_wait_interruptible(&variax->dumpreq); -	return get_string(buf, variax->model_data.name, -			  sizeof(variax->model_data.name)); -} - -/* -	"read" request on "bank" special file. -*/ -static ssize_t variax_get_bank(struct device *dev, -			       struct device_attribute *attr, char *buf) -{ -	struct usb_line6_variax *variax = -	    usb_get_intfdata(to_usb_interface(dev)); -	line6_dump_wait_interruptible(&variax->dumpreq); -	return get_string(buf, variax->bank, sizeof(variax->bank)); -} - -/* -	"read" request on "dump" special file. -*/ -static ssize_t variax_get_dump(struct device *dev, -			       struct device_attribute *attr, char *buf) -{ -	struct usb_line6_variax *variax = -	    usb_get_intfdata(to_usb_interface(dev)); -	int retval; -	retval = line6_dump_wait_interruptible(&variax->dumpreq); -	if (retval < 0) -		return retval; -	memcpy(buf, &variax->model_data.control, -	       sizeof(variax->model_data.control)); -	return sizeof(variax->model_data.control); -} - -/* -	"read" request on "guitar" special file. -*/ -static ssize_t variax_get_guitar(struct device *dev, -				 struct device_attribute *attr, char *buf) -{ -	struct usb_line6_variax *variax = -	    usb_get_intfdata(to_usb_interface(dev)); -	return sprintf(buf, "%s\n", variax->guitar); -} - -#ifdef CONFIG_LINE6_USB_RAW - -static char *variax_alloc_sysex_buffer(struct usb_line6_variax *variax, -				       int code, int size) -{ -	return line6_alloc_sysex_buffer(&variax->line6, VARIAX_SYSEX_CODE, code, -					size); -} - -/* -	"write" request on "raw" special file. -*/ -static ssize_t variax_set_raw2(struct device *dev, -			       struct device_attribute *attr, -			       const char *buf, size_t count) -{ -	struct usb_line6_variax *variax = -	    usb_get_intfdata(to_usb_interface(dev)); -	int size; -	int i; -	char *sysex; - -	count -= count % 3; -	size = count * 2; -	sysex = variax_alloc_sysex_buffer(variax, VARIAX_SYSEX_PARAM, size); - -	if (!sysex) -		return 0; - -	for (i = 0; i < count; i += 3) { -		const unsigned char *p1 = buf + i; -		char *p2 = sysex + SYSEX_DATA_OFS + i * 2; -		p2[0] = p1[2] & 0x0f; -		p2[1] = p1[2] >> 4; -		p2[2] = p1[1] & 0x0f; -		p2[3] = p1[1] >> 4; -		p2[4] = p1[0] & 0x0f; -		p2[5] = p1[0] >> 4; -	} - -	line6_send_sysex_message(&variax->line6, sysex, size); -	kfree(sysex); -	return count; -} - -#endif - -/* Variax workbench special files: */ -static DEVICE_ATTR(model, S_IWUGO | S_IRUGO, variax_get_model, -		   variax_set_model); -static DEVICE_ATTR(volume, S_IWUGO | S_IRUGO, variax_get_volume, -		   variax_set_volume); -static DEVICE_ATTR(tone, S_IWUGO | S_IRUGO, variax_get_tone, variax_set_tone); -static DEVICE_ATTR(name, S_IRUGO, variax_get_name, line6_nop_write); -static DEVICE_ATTR(bank, S_IRUGO, variax_get_bank, line6_nop_write); -static DEVICE_ATTR(dump, S_IRUGO, variax_get_dump, line6_nop_write); -static DEVICE_ATTR(active, S_IWUGO | S_IRUGO, variax_get_active, -		   variax_set_active); -static DEVICE_ATTR(guitar, S_IRUGO, variax_get_guitar, line6_nop_write); - -#ifdef CONFIG_LINE6_USB_RAW -static DEVICE_ATTR(raw, S_IWUGO, line6_nop_read, line6_set_raw); -static DEVICE_ATTR(raw2, S_IWUGO, line6_nop_read, variax_set_raw2); -#endif - -/*  	Variax destructor.  */  static void variax_destruct(struct usb_interface *interface)  {  	struct usb_line6_variax *variax = usb_get_intfdata(interface); -	struct usb_line6 *line6;  	if (variax == NULL)  		return; -	line6 = &variax->line6; -	if (line6 == NULL) -		return; -	line6_cleanup_audio(line6); +	line6_cleanup_audio(&variax->line6);  	del_timer(&variax->startup_timer1);  	del_timer(&variax->startup_timer2);  	cancel_work_sync(&variax->startup_work); -	/* free dump request data: */ -	line6_dumpreq_destructbuf(&variax->dumpreq, 2); -	line6_dumpreq_destructbuf(&variax->dumpreq, 1); -	line6_dumpreq_destruct(&variax->dumpreq); -  	kfree(variax->buffer_activate);  }  /* -	Create sysfs entries. -*/ -static int variax_create_files2(struct device *dev) -{ -	int err; -	CHECK_RETURN(device_create_file(dev, &dev_attr_model)); -	CHECK_RETURN(device_create_file(dev, &dev_attr_volume)); -	CHECK_RETURN(device_create_file(dev, &dev_attr_tone)); -	CHECK_RETURN(device_create_file(dev, &dev_attr_name)); -	CHECK_RETURN(device_create_file(dev, &dev_attr_bank)); -	CHECK_RETURN(device_create_file(dev, &dev_attr_dump)); -	CHECK_RETURN(device_create_file(dev, &dev_attr_active)); -	CHECK_RETURN(device_create_file(dev, &dev_attr_guitar)); -#ifdef CONFIG_LINE6_USB_RAW -	CHECK_RETURN(device_create_file(dev, &dev_attr_raw)); -	CHECK_RETURN(device_create_file(dev, &dev_attr_raw2)); -#endif -	return 0; -} - -/*  	 Try to init workbench device.  */  static int variax_try_init(struct usb_interface *interface, @@ -624,36 +180,12 @@ static int variax_try_init(struct usb_interface *interface,  	init_timer(&variax->startup_timer1);  	init_timer(&variax->startup_timer2); -	INIT_WORK(&variax->startup_work, variax_startup7); +	INIT_WORK(&variax->startup_work, variax_startup6);  	if ((interface == NULL) || (variax == NULL))  		return -ENODEV;  	/* initialize USB buffers: */ -	err = line6_dumpreq_init(&variax->dumpreq, variax_request_model1, -				 sizeof(variax_request_model1)); - -	if (err < 0) { -		dev_err(&interface->dev, "Out of memory\n"); -		return err; -	} - -	err = line6_dumpreq_initbuf(&variax->dumpreq, variax_request_model2, -				    sizeof(variax_request_model2), 1); - -	if (err < 0) { -		dev_err(&interface->dev, "Out of memory\n"); -		return err; -	} - -	err = line6_dumpreq_initbuf(&variax->dumpreq, variax_request_bank, -				    sizeof(variax_request_bank), 2); - -	if (err < 0) { -		dev_err(&interface->dev, "Out of memory\n"); -		return err; -	} -  	variax->buffer_activate = kmemdup(variax_activate,  					  sizeof(variax_activate), GFP_KERNEL); @@ -696,28 +228,8 @@ int line6_variax_init(struct usb_interface *interface,  */  void line6_variax_disconnect(struct usb_interface *interface)  { -	struct device *dev; -  	if (interface == NULL)  		return; -	dev = &interface->dev; - -	if (dev != NULL) { -		/* remove sysfs entries: */ -		line6_variax_remove_files(0, 0, dev); -		device_remove_file(dev, &dev_attr_model); -		device_remove_file(dev, &dev_attr_volume); -		device_remove_file(dev, &dev_attr_tone); -		device_remove_file(dev, &dev_attr_name); -		device_remove_file(dev, &dev_attr_bank); -		device_remove_file(dev, &dev_attr_dump); -		device_remove_file(dev, &dev_attr_active); -		device_remove_file(dev, &dev_attr_guitar); -#ifdef CONFIG_LINE6_USB_RAW -		device_remove_file(dev, &dev_attr_raw); -		device_remove_file(dev, &dev_attr_raw2); -#endif -	}  	variax_destruct(interface);  } diff --git a/drivers/staging/line6/variax.h b/drivers/staging/line6/variax.h index e2999ab41b0..24de79620d8 100644 --- a/drivers/staging/line6/variax.h +++ b/drivers/staging/line6/variax.h @@ -18,7 +18,6 @@  #include <sound/core.h>  #include "driver.h" -#include "dumprequest.h"  #define VARIAX_STARTUP_DELAY1 1000  #define VARIAX_STARTUP_DELAY3 100 @@ -32,33 +31,11 @@ enum {  	VARIAX_STARTUP_VERSIONREQ,  	VARIAX_STARTUP_WAIT,  	VARIAX_STARTUP_ACTIVATE, -	VARIAX_STARTUP_DUMPREQ,  	VARIAX_STARTUP_WORKQUEUE,  	VARIAX_STARTUP_SETUP,  	VARIAX_STARTUP_LAST = VARIAX_STARTUP_SETUP - 1  }; -enum { -	VARIAX_DUMP_PASS1 = LINE6_DUMP_CURRENT, -	VARIAX_DUMP_PASS2, -	VARIAX_DUMP_PASS3 -}; - -/** -	Binary Variax model dump -*/ -struct variax_model { -	/** -		Header information (including program name). -	*/ -	unsigned char name[18]; - -	/** -		Model parameters. -	*/ -	unsigned char control[78 * 2]; -}; -  struct usb_line6_variax {  	/**  		Generic Line6 USB data. @@ -66,48 +43,11 @@ struct usb_line6_variax {  	struct usb_line6 line6;  	/** -		Dump request structure. -		Append two extra buffers for 3-pass data query. -	*/ -	struct line6_dump_request dumpreq; -	struct line6_dump_reqbuf extrabuf[2]; - -	/**  		Buffer for activation code.  	*/  	unsigned char *buffer_activate;  	/** -		Model number. -	*/ -	int model; - -	/** -		Current model settings. -	*/ -	struct variax_model model_data; - -	/** -		Name of connected guitar. -	*/ -	unsigned char guitar[18]; - -	/** -		Name of current model bank. -	*/ -	unsigned char bank[18]; - -	/** -		Position of volume dial. -	*/ -	int volume; - -	/** -		Position of tone control dial. -	*/ -	int tone; - -	/**  		Handler for device initializaton.  	*/  	struct work_struct startup_work;  | 
