ALSA: line6: move staging driver to sound/usb/
PATCH 1/1 ALSA: line6: move staging driver to sound/usb/
The line6 driver supports devices from the Line6 PODxt, POD HD, TonePort, and Variax product families. This USB sound driver has been in staging since 2009 and is ready for wider review and users.
These devices provide both PCM and MIDI. Depending on the model the PCM supports capture and playback - there may be multiple capture sources. MIDI is used to control the device including changing effect or amplifier model settings, dumping presets, and changing between patches.
There are userspace tools and a manual available at:
http://www.tanzband-scream.at/line6/
http://line6linux.sourceforge.net/
---
This patch is based on linux-next.git/master.
Markus is busy but has given me the green light to do the work needed to get the line6 driver out of staging:
http://permalink.gmane.org/gmane.comp.audio.line6linux.devel/49
drivers/staging/Kconfig | 2 - drivers/staging/Makefile | 1 - drivers/staging/line6/Kconfig | 85 --- drivers/staging/line6/Makefile | 16 - drivers/staging/line6/audio.c | 70 -- drivers/staging/line6/audio.h | 21 - drivers/staging/line6/capture.c | 435 ----------- drivers/staging/line6/capture.h | 35 - drivers/staging/line6/control.c | 995 -------------------------- drivers/staging/line6/control.h | 195 ----- drivers/staging/line6/driver.c | 1290 --------------------------------- drivers/staging/line6/driver.h | 235 ------ drivers/staging/line6/dumprequest.c | 135 ---- drivers/staging/line6/dumprequest.h | 76 -- drivers/staging/line6/midi.c | 446 ------------ drivers/staging/line6/midi.h | 82 --- drivers/staging/line6/midibuf.c | 264 ------- drivers/staging/line6/midibuf.h | 38 - drivers/staging/line6/pcm.c | 570 --------------- drivers/staging/line6/pcm.h | 382 ---------- drivers/staging/line6/playback.c | 586 --------------- drivers/staging/line6/playback.h | 41 -- drivers/staging/line6/pod.c | 1351 ----------------------------------- drivers/staging/line6/pod.h | 205 ------ drivers/staging/line6/podhd.c | 154 ---- drivers/staging/line6/podhd.h | 30 - drivers/staging/line6/revision.h | 4 - drivers/staging/line6/toneport.c | 455 ------------ drivers/staging/line6/toneport.h | 52 -- drivers/staging/line6/usbdefs.h | 107 --- drivers/staging/line6/variax.c | 719 ------------------- drivers/staging/line6/variax.h | 132 ---- sound/usb/Kconfig | 2 + sound/usb/Makefile | 2 +- sound/usb/line6/Kconfig | 85 +++ sound/usb/line6/Makefile | 16 + sound/usb/line6/audio.c | 70 ++ sound/usb/line6/audio.h | 21 + sound/usb/line6/capture.c | 435 +++++++++++ sound/usb/line6/capture.h | 35 + sound/usb/line6/control.c | 995 ++++++++++++++++++++++++++ sound/usb/line6/control.h | 195 +++++ sound/usb/line6/driver.c | 1290 +++++++++++++++++++++++++++++++++ sound/usb/line6/driver.h | 235 ++++++ sound/usb/line6/dumprequest.c | 135 ++++ sound/usb/line6/dumprequest.h | 76 ++ sound/usb/line6/midi.c | 446 ++++++++++++ sound/usb/line6/midi.h | 82 +++ sound/usb/line6/midibuf.c | 264 +++++++ sound/usb/line6/midibuf.h | 38 + sound/usb/line6/pcm.c | 570 +++++++++++++++ sound/usb/line6/pcm.h | 382 ++++++++++ sound/usb/line6/playback.c | 586 +++++++++++++++ sound/usb/line6/playback.h | 41 ++ sound/usb/line6/pod.c | 1351 +++++++++++++++++++++++++++++++++++ sound/usb/line6/pod.h | 205 ++++++ sound/usb/line6/podhd.c | 154 ++++ sound/usb/line6/podhd.h | 30 + sound/usb/line6/revision.h | 4 + sound/usb/line6/toneport.c | 455 ++++++++++++ sound/usb/line6/toneport.h | 52 ++ sound/usb/line6/usbdefs.h | 107 +++ sound/usb/line6/variax.c | 719 +++++++++++++++++++ sound/usb/line6/variax.h | 132 ++++ 64 files changed, 9209 insertions(+), 9210 deletions(-) delete mode 100644 drivers/staging/line6/Kconfig delete mode 100644 drivers/staging/line6/Makefile delete mode 100644 drivers/staging/line6/audio.c delete mode 100644 drivers/staging/line6/audio.h delete mode 100644 drivers/staging/line6/capture.c delete mode 100644 drivers/staging/line6/capture.h delete mode 100644 drivers/staging/line6/control.c delete mode 100644 drivers/staging/line6/control.h delete mode 100644 drivers/staging/line6/driver.c delete mode 100644 drivers/staging/line6/driver.h delete mode 100644 drivers/staging/line6/dumprequest.c delete mode 100644 drivers/staging/line6/dumprequest.h delete mode 100644 drivers/staging/line6/midi.c delete mode 100644 drivers/staging/line6/midi.h delete mode 100644 drivers/staging/line6/midibuf.c delete mode 100644 drivers/staging/line6/midibuf.h delete mode 100644 drivers/staging/line6/pcm.c delete mode 100644 drivers/staging/line6/pcm.h delete mode 100644 drivers/staging/line6/playback.c delete mode 100644 drivers/staging/line6/playback.h delete mode 100644 drivers/staging/line6/pod.c delete mode 100644 drivers/staging/line6/pod.h delete mode 100644 drivers/staging/line6/podhd.c delete mode 100644 drivers/staging/line6/podhd.h delete mode 100644 drivers/staging/line6/revision.h delete mode 100644 drivers/staging/line6/toneport.c delete mode 100644 drivers/staging/line6/toneport.h delete mode 100644 drivers/staging/line6/usbdefs.h delete mode 100644 drivers/staging/line6/variax.c delete mode 100644 drivers/staging/line6/variax.h create mode 100644 sound/usb/line6/Kconfig create mode 100644 sound/usb/line6/Makefile create mode 100644 sound/usb/line6/audio.c create mode 100644 sound/usb/line6/audio.h create mode 100644 sound/usb/line6/capture.c create mode 100644 sound/usb/line6/capture.h create mode 100644 sound/usb/line6/control.c create mode 100644 sound/usb/line6/control.h create mode 100644 sound/usb/line6/driver.c create mode 100644 sound/usb/line6/driver.h create mode 100644 sound/usb/line6/dumprequest.c create mode 100644 sound/usb/line6/dumprequest.h create mode 100644 sound/usb/line6/midi.c create mode 100644 sound/usb/line6/midi.h create mode 100644 sound/usb/line6/midibuf.c create mode 100644 sound/usb/line6/midibuf.h create mode 100644 sound/usb/line6/pcm.c create mode 100644 sound/usb/line6/pcm.h create mode 100644 sound/usb/line6/playback.c create mode 100644 sound/usb/line6/playback.h create mode 100644 sound/usb/line6/pod.c create mode 100644 sound/usb/line6/pod.h create mode 100644 sound/usb/line6/podhd.c create mode 100644 sound/usb/line6/podhd.h create mode 100644 sound/usb/line6/revision.h create mode 100644 sound/usb/line6/toneport.c create mode 100644 sound/usb/line6/toneport.h create mode 100644 sound/usb/line6/usbdefs.h create mode 100644 sound/usb/line6/variax.c create mode 100644 sound/usb/line6/variax.h
drivers/staging/Kconfig +0 -2
@@ -58,8 +58,6 @@ source "drivers/staging/frontier/Kconfig" source "drivers/staging/phison/Kconfig" -source "drivers/staging/line6/Kconfig" - source "drivers/staging/octeon/Kconfig" source "drivers/staging/serqt_usb2/Kconfig"
drivers/staging/Makefile +0 -1
@@ -22,7 +22,6 @@ obj-$(CONFIG_R8712U) += rtl8712/ obj-$(CONFIG_RTS5139) += rts5139/ obj-$(CONFIG_TRANZPORT) += frontier/ obj-$(CONFIG_IDE_PHISON) += phison/ -obj-$(CONFIG_LINE6_USB) += line6/ obj-$(CONFIG_USB_SERIAL_QUATECH2) += serqt_usb2/ obj-$(CONFIG_OCTEON_ETHERNET) += octeon/ obj-$(CONFIG_VT6655) += vt6655/
drivers/staging/line6/Kconfig deleted +0 -85
85 lines not on this page · raw message
drivers/staging/line6/Makefile deleted +0 -16
@@ -1,16 +0,0 @@ -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 \ - podhd.o
drivers/staging/line6/audio.c deleted +0 -70
70 lines not on this page · raw message
drivers/staging/line6/audio.h deleted +0 -21
@@ -1,21 +0,0 @@ -/* -* Line6 Linux USB driver - 0.9.1beta -* -* Copyright (C) 2004-2010 Markus Grabner ([email protected]) -* -* This program is free software; you can redistribute it and/or -* modify it under the terms of the GNU General Public License as -* published by the Free Software Foundation, version 2. -* -*/ - -#ifndef AUDIO_H -#define AUDIO_H - -#include "driver.h" - -extern void line6_cleanup_audio (struct usb_line6 *); -extern int line6_init_audio (struct usb_line6 *); -extern int line6_register_audio (struct usb_line6 *); - -#endif
drivers/staging/line6/capture.c deleted +0 -435
435 lines not on this page · raw message
drivers/staging/line6/capture.h deleted +0 -35
@@ -1,35 +0,0 @@ -/* -* Line6 Linux USB driver - 0.9.1beta -* -* Copyright (C) 2004-2010 Markus Grabner ([email protected]) -* -* 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 CAPTURE_H -#define CAPTURE_H - -#include <sound/pcm.h> - -#include "driver.h" -#include "pcm.h" - -extern struct snd_pcm_ops snd_line6_capture_ops; - -extern void line6_capture_copy (struct snd_line6_pcm *line6pcm,char *fbuf, -int fsize); -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
drivers/staging/line6/control.c deleted +0 -995
995 lines not on this page · raw message
drivers/staging/line6/control.h deleted +0 -195
195 lines not on this page · raw message
drivers/staging/line6/driver.c deleted +0 -1290
1,133 lines not on this page · raw message
drivers/staging/line6/driver.h deleted +0 -235
235 lines not on this page · raw message
drivers/staging/line6/dumprequest.c deleted +0 -135
135 lines not on this page · raw message
drivers/staging/line6/dumprequest.h deleted +0 -76
76 lines not on this page · raw message
drivers/staging/line6/midi.c deleted +0 -446
446 lines not on this page · raw message
drivers/staging/line6/midi.h deleted +0 -82
82 lines not on this page · raw message
drivers/staging/line6/midibuf.c deleted +0 -264
264 lines not on this page · raw message
drivers/staging/line6/midibuf.h deleted +0 -38
Lines of this file are not shown. View the raw message.
drivers/staging/line6/pcm.c deleted +0 -570
570 lines not on this page · raw message
drivers/staging/line6/pcm.h deleted +0 -382
382 lines not on this page · raw message
drivers/staging/line6/playback.c deleted +0 -586
586 lines not on this page · raw message
drivers/staging/line6/playback.h deleted +0 -41
41 lines not on this page · raw message
drivers/staging/line6/pod.c deleted +0 -1351
1,351 lines not on this page · raw message
drivers/staging/line6/pod.h deleted +0 -205
205 lines not on this page · raw message
drivers/staging/line6/podhd.c deleted +0 -154
154 lines not on this page · raw message
drivers/staging/line6/revision.h deleted +0 -4
Lines of this file are not shown. View the raw message.
drivers/staging/line6/toneport.c deleted +0 -455
455 lines not on this page · raw message
drivers/staging/line6/toneport.h deleted +0 -52
52 lines not on this page · raw message
drivers/staging/line6/usbdefs.h deleted +0 -107
107 lines not on this page · raw message
drivers/staging/line6/variax.c deleted +0 -719
719 lines not on this page · raw message
drivers/staging/line6/variax.h deleted +0 -132
132 lines not on this page · raw message
sound/usb/line6/Kconfig new file +85 -0
85 lines not on this page · raw message
sound/usb/line6/audio.c new file +70 -0
70 lines not on this page · raw message
sound/usb/line6/capture.c new file +435 -0
435 lines not on this page · raw message
sound/usb/line6/control.c new file +995 -0
995 lines not on this page · raw message
sound/usb/line6/control.h new file +195 -0
195 lines not on this page · raw message
sound/usb/line6/driver.c new file +1290 -0
1,290 lines not on this page · raw message
sound/usb/line6/driver.h new file +235 -0
235 lines not on this page · raw message
sound/usb/line6/dumprequest.c new file +135 -0
135 lines not on this page · raw message
sound/usb/line6/dumprequest.h new file +76 -0
76 lines not on this page · raw message
sound/usb/line6/midi.c new file +446 -0
446 lines not on this page · raw message
sound/usb/line6/midi.h new file +82 -0
82 lines not on this page · raw message
sound/usb/line6/midibuf.c new file +264 -0
264 lines not on this page · raw message
sound/usb/line6/pcm.c new file +570 -0
570 lines not on this page · raw message
sound/usb/line6/pcm.h new file +382 -0
382 lines not on this page · raw message
sound/usb/line6/playback.c new file +586 -0
586 lines not on this page · raw message
sound/usb/line6/playback.h new file +41 -0
41 lines not on this page · raw message
sound/usb/line6/pod.c new file +1351 -0
1,351 lines not on this page · raw message
sound/usb/line6/pod.h new file +205 -0
205 lines not on this page · raw message
sound/usb/line6/podhd.c new file +154 -0
154 lines not on this page · raw message
sound/usb/line6/toneport.c new file +455 -0
455 lines not on this page · raw message
sound/usb/line6/toneport.h new file +52 -0
52 lines not on this page · raw message
sound/usb/line6/usbdefs.h new file +107 -0
107 lines not on this page · raw message
sound/usb/line6/variax.c new file +719 -0
719 lines not on this page · raw message
sound/usb/line6/variax.h new file +132 -0
132 lines not on this page · raw message
The rest of this diff is not shown. View the raw message.
Signature · 1 line
1.7.12.1
Part of the diff is not shown here. View the raw message.
Hi,
Quoted 3 lines · Stefan Hajnoczi
The line6 driver supports devices from the Line6 PODxt, POD HD, TonePort, and Variax product families. This USB sound driver has been in staging since 2009 and is ready for wider review and users.
Thanks a lot for working on this! However, just moving over the current code does not seem sufficient.
Alone, script/checkpatch.pl gives me
total: 9234 errors, 158 warnings, 9233 lines checked
including DOS line feeds, broken indentation and other style issues. I think at least most of them need to be fixed.
Apart from that, I picked some random places to comment on below, but they by far don't address all issues that need attention.
Many of the comments above also apply to other files in that patch with similar problems.
Also, I wonder whether the patch could be easier reviewed when split up into mupltiple, smaller ones ...
Quoted 70 lines
These devices provide both PCM and MIDI. Depending on the model the PCM supports capture and playback - there may be multiple capture sources. MIDI is used to control the device including changing effect or amplifier model settings, dumping presets, and changing between patches.
There are userspace tools and a manual available at:
http://www.tanzband-scream.at/line6/
http://line6linux.sourceforge.net/Cc Markus Grabner <[email protected]>Signed-off-by Stefan Hajnoczi <[email protected]>---
sound/usb/line6/Kconfig new file +50
-0@@ -0,0 +1,85 @@ +menuconfig LINE6_USB + tristate "Line6 USB support" + depends on USB && SND + select SND_RAWMIDI + select SND_PCM + help + This is a driver for the guitar amp, cab, and effects modeller + PODxt Pro by Line6 (and similar devices), supporting the + following features: + * Reading/writing individual parameters + * Reading/writing complete channel, effects setup, and amp + setup data + * Channel switching + * Virtual MIDI interface + * Tuner access + * Playback/capture/mixer device for any ALSA-compatible PCM + audio application + * Signal routing (record clean/processed guitar signal, + re-amping) + + Preliminary support for the Variax Workbench and TonePort + devices is included. + +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.
sound/usb/line6/Kconfig line 60
Quoted 10 lines
sound/usb/line6/Kconfig new file +10
-0+ +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.
I think all such debug things should be realized with dynamic kernel debugging features (see Documentation/dynamic-debug-howto.txt).
Quoted 1,815 lines
sound/usb/line6/Kconfig new file +25
-0+ +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 + help + Say Y here to add code to measure the impulse response of a Line6 + device. This is more accurate than user-space methods since it + bypasses any PCM data buffering (e.g., by ALSA or jack). This is + useful for assessing the performance of new devices, but is not + required for normal operation. + + If unsure, say N. + +endif # LINE6_USBsound/usb/line6/Makefile new file +16
-0@@ -0,0 +1,16 @@ +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 \ + podhd.osound/usb/line6/audio.c new file +70
-0@@ -0,0 +1,70 @@ +/* +* Line6 Linux USB driver - 0.9.1beta +* +* Copyright (C) 2004-2010 Markus Grabner ([email protected]) +* +* This program is free software; you can redistribute it and/or +* modify it under the terms of the GNU General Public License as +* published by the Free Software Foundation, version 2. +* +*/ + +#include <sound/core.h> +#include <sound/initval.h> +#include <linux/export.h> + +#include "driver.h" +#include "audio.h" + +/* +Initialize the Line6 USB audio system. +*/ +int line6_init_audio (struct usb_line6 *line6) +{ +struct snd_card *card; +int err; + + err =snd_card_create (SNDRV_DEFAULT_IDX1 ,SNDRV_DEFAULT_STR1 , +THIS_MODULE ,0 , &card); +if (err <0 ) +return err; + + line6->card = card; + +strcpy (card->id, line6->properties->id); +strcpy (card->driver,DRIVER_NAME ); +strcpy (card->shortname, line6->properties->name); +/* longname is 80 chars - see asound.h */ +sprintf (card->longname,"Line6 %s at USB %s" , line6->properties->name, +dev_name (line6->ifcdev)); +return 0 ; +} + +/* +Register the Line6 USB audio system. +*/ +int line6_register_audio (struct usb_line6 *line6) +{ +int err; + + err =snd_card_register (line6->card); +if (err <0 ) +return err; + +return 0 ; +} + +/* +Cleanup the Line6 USB audio system. +*/ +void line6_cleanup_audio (struct usb_line6 *line6) +{ +struct snd_card *card = line6->card; + +if (card ==NULL ) +return ; + +snd_card_disconnect (card); +snd_card_free (card); + line6->card =NULL ; +}sound/usb/line6/audio.h new file +21
-0@@ -0,0 +1,21 @@ +/* +* Line6 Linux USB driver - 0.9.1beta +* +* Copyright (C) 2004-2010 Markus Grabner ([email protected]) +* +* This program is free software; you can redistribute it and/or +* modify it under the terms of the GNU General Public License as +* published by the Free Software Foundation, version 2. +* +*/ + +#ifndef AUDIO_H +#define AUDIO_H + +#include "driver.h" + +extern void line6_cleanup_audio (struct usb_line6 *); +extern int line6_init_audio (struct usb_line6 *); +extern int line6_register_audio (struct usb_line6 *); + +#endif sound/usb/line6/capture.c new file +435
-0@@ -0,0 +1,435 @@ +/* +* Line6 Linux USB driver - 0.9.1beta +* +* Copyright (C) 2004-2010 Markus Grabner ([email protected]) +* +* 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 <sound/core.h> +#include <sound/pcm.h> +#include <sound/pcm_params.h> + +#include "audio.h" +#include "capture.h" +#include "driver.h" +#include "pcm.h" +#include "pod.h" + +/* +Find a free URB and submit it. +*/ +static int submit_audio_in_urb (struct snd_line6_pcm *line6pcm) +{ +int index; +unsigned long flags; +int i, urb_size; +int ret; +struct urb *urb_in; + +spin_lock_irqsave (&line6pcm->lock_audio_in, flags); + index = +find_first_zero_bit (&line6pcm->active_urb_in,LINE6_ISO_BUFFERS ); + +if (index <0 || index >=LINE6_ISO_BUFFERS ) { +spin_unlock_irqrestore (&line6pcm->lock_audio_in, flags); +dev_err (line6pcm->line6->ifcdev,"no free URB found\n" ); +return -EINVAL ; + } + + urb_in = line6pcm->urb_audio_in[index]; + urb_size =0 ; + +for (i =0 ; i <LINE6_ISO_PACKETS ; ++i) { +struct usb_iso_packet_descriptor *fin = + &urb_in->iso_frame_desc[i]; + fin->offset = urb_size; + fin->length = line6pcm->max_packet_size; + urb_size += line6pcm->max_packet_size; + } + + urb_in->transfer_buffer = + line6pcm->buffer_in + + index *LINE6_ISO_PACKETS * line6pcm->max_packet_size; + urb_in->transfer_buffer_length = urb_size; + urb_in->context = line6pcm; + + ret =usb_submit_urb (urb_in,GFP_ATOMIC ); + +if (ret ==0 ) +set_bit (index, &line6pcm->active_urb_in); +else +dev_err (line6pcm->line6->ifcdev, +"URB in #%d submission failed (%d)\n" , index, ret); + +spin_unlock_irqrestore (&line6pcm->lock_audio_in, flags); +return 0 ; +} + +/* +Submit all currently available capture URBs. +*/ +int line6_submit_audio_in_all_urbs (struct snd_line6_pcm *line6pcm) +{ +int ret, i; + +for (i =0 ; i <LINE6_ISO_BUFFERS ; ++i) { + ret =submit_audio_in_urb (line6pcm); +if (ret <0 ) +return ret; + } + +return 0 ; +} + +/* +Unlink all currently active capture URBs. +*/ +void line6_unlink_audio_in_urbs (struct snd_line6_pcm *line6pcm) +{ +unsigned int i; + +for (i =LINE6_ISO_BUFFERS ; i--;) { +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); + } + } + } +} + +/* +Wait until unlinking of all currently active capture URBs has been +finished. +*/ +void line6_wait_clear_audio_in_urbs (struct snd_line6_pcm *line6pcm) +{ +int timeout =HZ ; +unsigned int i; +int alive; + +do { + alive =0 ; +for (i =LINE6_ISO_BUFFERS ; i--;) { +if (test_bit (i, &line6pcm->active_urb_in)) + alive++; + } +if (!alive) +break ; +set_current_state (TASK_UNINTERRUPTIBLE ); +schedule_timeout (1 ); + }while (--timeout >0 ); +if (alive) +snd_printk (KERN_ERR "timeout: still %d active urbs..\n" , alive); +} + +/* +Unlink all currently active capture URBs, and wait for finishing. +*/ +void line6_unlink_wait_clear_audio_in_urbs (struct snd_line6_pcm *line6pcm) +{ +line6_unlink_audio_in_urbs (line6pcm); +line6_wait_clear_audio_in_urbs (line6pcm); +} + +/* +Copy data into ALSA capture buffer. +*/ +void line6_capture_copy (struct snd_line6_pcm *line6pcm,char *fbuf,int fsize) +{ +struct snd_pcm_substream *substream = +get_substream (line6pcm,SNDRV_PCM_STREAM_CAPTURE ); +struct snd_pcm_runtime *runtime = substream->runtime; +const int bytes_per_frame = line6pcm->properties->bytes_per_frame; +int frames = fsize / bytes_per_frame; + +if (runtime ==NULL ) +return ; + +if (line6pcm->pos_in_done + frames > runtime->buffer_size) { +/* +The transferred area goes over buffer boundary, +copy two separate chunks. +*/ +int len; + len = runtime->buffer_size - line6pcm->pos_in_done; + +if (len >0 ) { +memcpy (runtime->dma_area + + line6pcm->pos_in_done * bytes_per_frame, fbuf, + len * bytes_per_frame); +memcpy (runtime->dma_area, fbuf + len * bytes_per_frame, + (frames - len) * bytes_per_frame); + }else { +/* this is somewhat paranoid */ +dev_err (line6pcm->line6->ifcdev, +"driver bug: len = %d\n" , len); + } + }else { +/* copy single chunk */ +memcpy (runtime->dma_area + + line6pcm->pos_in_done * bytes_per_frame, fbuf, fsize); + } + + line6pcm->pos_in_done += frames; +if (line6pcm->pos_in_done >= runtime->buffer_size) + line6pcm->pos_in_done -= runtime->buffer_size; +} + +void line6_capture_check_period (struct snd_line6_pcm *line6pcm,int length) +{ +struct snd_pcm_substream *substream = +get_substream (line6pcm,SNDRV_PCM_STREAM_CAPTURE ); + + line6pcm->bytes_in += length; +if (line6pcm->bytes_in >= line6pcm->period_in) { + line6pcm->bytes_in %= line6pcm->period_in; +snd_pcm_period_elapsed (substream); + } +} + +void line6_free_capture_buffer (struct snd_line6_pcm *line6pcm) +{ +kfree (line6pcm->buffer_in); + line6pcm->buffer_in =NULL ; +} + +/* +* Callback for completed capture URB. +*/ +static void audio_in_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; + + line6pcm->last_frame_in = urb->start_frame; + +/* find index of URB */ +for (index =0 ; index <LINE6_ISO_BUFFERS ; ++index) +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) { +char *fbuf; +int fsize; +struct usb_iso_packet_descriptor *fin = &urb->iso_frame_desc[i]; + +if (fin->status == -EXDEV ) { + shutdown =1 ; +break ; + } + + fbuf = urb->transfer_buffer + fin->offset; + fsize = fin->actual_length; + +if (fsize > line6pcm->max_packet_size) { +dev_err (line6pcm->line6->ifcdev, +"driver and/or device bug: packet too large (%d > %d)\n" , + fsize, line6pcm->max_packet_size); + } + + length += fsize; + +/* the following assumes LINE6_ISO_PACKETS == 1: */ + line6pcm->prev_fbuf = fbuf; + line6pcm->prev_fsize = fsize; + +#ifdef CONFIG_LINE6_USB_IMPULSE_RESPONSE + if (!(line6pcm->flags & LINE6_BITS_PCM_IMPULSE)) +#endif +if (test_bit (LINE6_INDEX_PCM_ALSA_CAPTURE_STREAM , &line6pcm->flags) + && (fsize >0 )) +line6_capture_copy (line6pcm, fbuf, fsize); + } + +clear_bit (index, &line6pcm->active_urb_in); + +if (test_and_clear_bit (index, &line6pcm->unlink_urb_in)) + shutdown =1 ; + +spin_unlock_irqrestore (&line6pcm->lock_audio_in, flags); + +if (!shutdown) { +submit_audio_in_urb (line6pcm); + +#ifdef CONFIG_LINE6_USB_IMPULSE_RESPONSE + if (!(line6pcm->flags & LINE6_BITS_PCM_IMPULSE)) +#endif +if (test_bit (LINE6_INDEX_PCM_ALSA_CAPTURE_STREAM , &line6pcm->flags)) +line6_capture_check_period (line6pcm, length); + } +} + +/* open capture callback */ +static int snd_line6_capture_open (struct snd_pcm_substream *substream) +{ +int err; +struct snd_pcm_runtime *runtime = substream->runtime; +struct snd_line6_pcm *line6pcm =snd_pcm_substream_chip (substream); + + err =snd_pcm_hw_constraint_ratdens (runtime,0 , +SNDRV_PCM_HW_PARAM_RATE , + (&line6pcm-> + properties->snd_line6_rates)); +if (err <0 ) +return err; + + runtime->hw = line6pcm->properties->snd_line6_capture_hw; +return 0 ; +} + +/* close capture callback */ +static int snd_line6_capture_close (struct snd_pcm_substream *substream) +{ +return 0 ; +} + +/* hw_params capture callback */ +static int snd_line6_capture_hw_params (struct snd_pcm_substream *substream, +struct snd_pcm_hw_params *hw_params) +{ +int ret; +struct snd_line6_pcm *line6pcm =snd_pcm_substream_chip (substream); + +/* -- Florian Demski [FD] */ +/* don't ask me why, but this fixes the bug on my machine */ +if (line6pcm ==NULL ) { +if (substream->pcm ==NULL ) +return -ENOMEM ; +if (substream->pcm->private_data ==NULL ) +return -ENOMEM ; + substream->private_data = substream->pcm->private_data; + line6pcm =snd_pcm_substream_chip (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 ) { +line6_pcm_release (line6pcm,LINE6_BIT_PCM_ALSA_CAPTURE_BUFFER ); +return ret; + } + + line6pcm->period_in =params_period_bytes (hw_params); +return 0 ; +} + +/* 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); +} + +/* trigger callback */ +int snd_line6_capture_trigger (struct snd_line6_pcm *line6pcm,int cmd) +{ +int err; + +switch (cmd) { +case SNDRV_PCM_TRIGGER_START : +#ifdef CONFIG_PM +case SNDRV_PCM_TRIGGER_RESUME : +#endif + err =line6_pcm_acquire (line6pcm,LINE6_BIT_PCM_ALSA_CAPTURE_STREAM ); + +if (err <0 ) +return err; + +break ; + +case SNDRV_PCM_TRIGGER_STOP : +#ifdef CONFIG_PM +case SNDRV_PCM_TRIGGER_SUSPEND : +#endif + err =line6_pcm_release (line6pcm,LINE6_BIT_PCM_ALSA_CAPTURE_STREAM ); + +if (err <0 ) +return err; + +break ; + +default : +return -EINVAL ; + } + +return 0 ; +} + +/* capture pointer callback */ +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; +} + +/* capture operators */ +struct snd_pcm_ops snd_line6_capture_ops = { + .open = snd_line6_capture_open, + .close = snd_line6_capture_close, + .ioctl = snd_pcm_lib_ioctl, + .hw_params = snd_line6_capture_hw_params, + .hw_free = snd_line6_capture_hw_free, + .prepare = snd_line6_prepare, + .trigger = snd_line6_trigger, + .pointer = snd_line6_capture_pointer, +}; + +int line6_create_audio_in_urbs (struct snd_line6_pcm *line6pcm) +{ +int i; + +/* create audio URBs and fill in constant values: */ +for (i =0 ; i <LINE6_ISO_BUFFERS ; ++i) { +struct urb *urb; + +/* URB for audio in: */ + urb = line6pcm->urb_audio_in[i] = +usb_alloc_urb (LINE6_ISO_PACKETS ,GFP_KERNEL ); + +if (urb ==NULL ) { +dev_err (line6pcm->line6->ifcdev,"Out of memory\n" ); +return -ENOMEM ; + } + + urb->dev = line6pcm->line6->usbdev; + urb->pipe = +usb_rcvisocpipe (line6pcm->line6->usbdev, + line6pcm->ep_audio_read & +USB_ENDPOINT_NUMBER_MASK ); + urb->transfer_flags =URB_ISO_ASAP ; + urb->start_frame =-1 ; + urb->number_of_packets =LINE6_ISO_PACKETS ; + urb->interval =LINE6_ISO_INTERVAL ; + urb->error_count =0 ; + urb->complete = audio_in_callback; + } + +return 0 ; +}sound/usb/line6/capture.h new file +35
-0@@ -0,0 +1,35 @@ +/* +* Line6 Linux USB driver - 0.9.1beta +* +* Copyright (C) 2004-2010 Markus Grabner ([email protected]) +* +* 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 CAPTURE_H +#define CAPTURE_H + +#include <sound/pcm.h> + +#include "driver.h" +#include "pcm.h" + +extern struct snd_pcm_ops snd_line6_capture_ops; + +extern void line6_capture_copy (struct snd_line6_pcm *line6pcm,char *fbuf, +int fsize); +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 sound/usb/line6/control.c new file +995
-0@@ -0,0 +1,995 @@ +/* +* Line6 Linux USB driver - 0.9.1beta +* +* Copyright (C) 2004-2010 Markus Grabner ([email protected]) +* +* 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); +u8 value; +int retval; + + retval =kstrtou8 (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_IWUSR | S_IRUGO, pod_get_tweak, pod_set_tweak); +static DEVICE_ATTR(wah_position, S_IWUSR | S_IRUGO, pod_get_wah_position, + pod_set_wah_position); +static DEVICE_ATTR(compression_gain, S_IWUSR | S_IRUGO, + pod_get_compression_gain, pod_set_compression_gain); +static DEVICE_ATTR(vol_pedal_position, S_IWUSR | S_IRUGO, + pod_get_vol_pedal_position, pod_set_vol_pedal_position); +static DEVICE_ATTR(compression_threshold, S_IWUSR | S_IRUGO, + pod_get_compression_threshold, + pod_set_compression_threshold); +static DEVICE_ATTR(pan, S_IWUSR | S_IRUGO, pod_get_pan, pod_set_pan); +static DEVICE_ATTR(amp_model_setup, S_IWUSR | S_IRUGO, pod_get_amp_model_setup, + pod_set_amp_model_setup); +static DEVICE_ATTR(amp_model, S_IWUSR | S_IRUGO, pod_get_amp_model, + pod_set_amp_model); +static DEVICE_ATTR(drive, S_IWUSR | S_IRUGO, pod_get_drive, pod_set_drive); +static DEVICE_ATTR(bass, S_IWUSR | S_IRUGO, pod_get_bass, pod_set_bass); +static DEVICE_ATTR(mid, S_IWUSR | S_IRUGO, pod_get_mid, pod_set_mid); +static DEVICE_ATTR(lowmid, S_IWUSR | S_IRUGO, pod_get_lowmid, pod_set_lowmid); +static DEVICE_ATTR(treble, S_IWUSR | S_IRUGO, pod_get_treble, pod_set_treble); +static DEVICE_ATTR(highmid, S_IWUSR | S_IRUGO, pod_get_highmid, + pod_set_highmid); +static DEVICE_ATTR(chan_vol, S_IWUSR | S_IRUGO, pod_get_chan_vol, + pod_set_chan_vol); +static DEVICE_ATTR(reverb_mix, S_IWUSR | S_IRUGO, pod_get_reverb_mix, + pod_set_reverb_mix); +static DEVICE_ATTR(effect_setup, S_IWUSR | S_IRUGO, pod_get_effect_setup, + pod_set_effect_setup); +static DEVICE_ATTR(band_1_frequency, S_IWUSR | S_IRUGO, + pod_get_band_1_frequency, pod_set_band_1_frequency); +static DEVICE_ATTR(presence, S_IWUSR | S_IRUGO, pod_get_presence, + pod_set_presence); +static DEVICE_ATTR2(treble__bass, treble, S_IWUSR | S_IRUGO, + pod_get_treble__bass, pod_set_treble__bass); +static DEVICE_ATTR(noise_gate_enable, S_IWUSR | S_IRUGO, + pod_get_noise_gate_enable, pod_set_noise_gate_enable); +static DEVICE_ATTR(gate_threshold, S_IWUSR | S_IRUGO, pod_get_gate_threshold, + pod_set_gate_threshold); +static DEVICE_ATTR(gate_decay_time, S_IWUSR | S_IRUGO, pod_get_gate_decay_time, + pod_set_gate_decay_time); +static DEVICE_ATTR(stomp_enable, S_IWUSR | S_IRUGO, pod_get_stomp_enable, + pod_set_stomp_enable); +static DEVICE_ATTR(comp_enable, S_IWUSR | S_IRUGO, pod_get_comp_enable, + pod_set_comp_enable); +static DEVICE_ATTR(stomp_time, S_IWUSR | S_IRUGO, pod_get_stomp_time, + pod_set_stomp_time); +static DEVICE_ATTR(delay_enable, S_IWUSR | S_IRUGO, pod_get_delay_enable, + pod_set_delay_enable); +static DEVICE_ATTR(mod_param_1, S_IWUSR | S_IRUGO, pod_get_mod_param_1, + pod_set_mod_param_1); +static DEVICE_ATTR(delay_param_1, S_IWUSR | S_IRUGO, pod_get_delay_param_1, + pod_set_delay_param_1); +static DEVICE_ATTR(delay_param_1_note_value, S_IWUSR | 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_IWUSR | S_IRUGO, + pod_get_band_2_frequency__bass, + pod_set_band_2_frequency__bass); +static DEVICE_ATTR(delay_param_2, S_IWUSR | S_IRUGO, pod_get_delay_param_2, + pod_set_delay_param_2); +static DEVICE_ATTR(delay_volume_mix, S_IWUSR | S_IRUGO, + pod_get_delay_volume_mix, pod_set_delay_volume_mix); +static DEVICE_ATTR(delay_param_3, S_IWUSR | S_IRUGO, pod_get_delay_param_3, + pod_set_delay_param_3); +static DEVICE_ATTR(reverb_enable, S_IWUSR | S_IRUGO, pod_get_reverb_enable, + pod_set_reverb_enable); +static DEVICE_ATTR(reverb_type, S_IWUSR | S_IRUGO, pod_get_reverb_type, + pod_set_reverb_type); +static DEVICE_ATTR(reverb_decay, S_IWUSR | S_IRUGO, pod_get_reverb_decay, + pod_set_reverb_decay); +static DEVICE_ATTR(reverb_tone, S_IWUSR | S_IRUGO, pod_get_reverb_tone, + pod_set_reverb_tone); +static DEVICE_ATTR(reverb_pre_delay, S_IWUSR | S_IRUGO, + pod_get_reverb_pre_delay, pod_set_reverb_pre_delay); +static DEVICE_ATTR(reverb_pre_post, S_IWUSR | S_IRUGO, pod_get_reverb_pre_post, + pod_set_reverb_pre_post); +static DEVICE_ATTR(band_2_frequency, S_IWUSR | S_IRUGO, + pod_get_band_2_frequency, pod_set_band_2_frequency); +static DEVICE_ATTR2(band_3_frequency__bass, band_3_frequency, S_IWUSR | S_IRUGO, + pod_get_band_3_frequency__bass, + pod_set_band_3_frequency__bass); +static DEVICE_ATTR(wah_enable, S_IWUSR | S_IRUGO, pod_get_wah_enable, + pod_set_wah_enable); +static DEVICE_ATTR(modulation_lo_cut, S_IWUSR | S_IRUGO, + pod_get_modulation_lo_cut, pod_set_modulation_lo_cut); +static DEVICE_ATTR(delay_reverb_lo_cut, S_IWUSR | S_IRUGO, + pod_get_delay_reverb_lo_cut, pod_set_delay_reverb_lo_cut); +static DEVICE_ATTR(volume_pedal_minimum, S_IWUSR | S_IRUGO, + pod_get_volume_pedal_minimum, pod_set_volume_pedal_minimum); +static DEVICE_ATTR(eq_pre_post, S_IWUSR | S_IRUGO, pod_get_eq_pre_post, + pod_set_eq_pre_post); +static DEVICE_ATTR(volume_pre_post, S_IWUSR | S_IRUGO, pod_get_volume_pre_post, + pod_set_volume_pre_post); +static DEVICE_ATTR(di_model, S_IWUSR | S_IRUGO, pod_get_di_model, + pod_set_di_model); +static DEVICE_ATTR(di_delay, S_IWUSR | S_IRUGO, pod_get_di_delay, + pod_set_di_delay); +static DEVICE_ATTR(mod_enable, S_IWUSR | S_IRUGO, pod_get_mod_enable, + pod_set_mod_enable); +static DEVICE_ATTR(mod_param_1_note_value, S_IWUSR | S_IRUGO, + pod_get_mod_param_1_note_value, + pod_set_mod_param_1_note_value); +static DEVICE_ATTR(mod_param_2, S_IWUSR | S_IRUGO, pod_get_mod_param_2, + pod_set_mod_param_2); +static DEVICE_ATTR(mod_param_3, S_IWUSR | S_IRUGO, pod_get_mod_param_3, + pod_set_mod_param_3); +static DEVICE_ATTR(mod_param_4, S_IWUSR | S_IRUGO, pod_get_mod_param_4, + pod_set_mod_param_4); +static DEVICE_ATTR(mod_param_5, S_IWUSR | S_IRUGO, pod_get_mod_param_5, + pod_set_mod_param_5); +static DEVICE_ATTR(mod_volume_mix, S_IWUSR | S_IRUGO, pod_get_mod_volume_mix, + pod_set_mod_volume_mix); +static DEVICE_ATTR(mod_pre_post, S_IWUSR | S_IRUGO, pod_get_mod_pre_post, + pod_set_mod_pre_post); +static DEVICE_ATTR(modulation_model, S_IWUSR | S_IRUGO, + pod_get_modulation_model, pod_set_modulation_model); +static DEVICE_ATTR(band_3_frequency, S_IWUSR | S_IRUGO, + pod_get_band_3_frequency, pod_set_band_3_frequency); +static DEVICE_ATTR2(band_4_frequency__bass, band_4_frequency, S_IWUSR | S_IRUGO, + pod_get_band_4_frequency__bass, + pod_set_band_4_frequency__bass); +static DEVICE_ATTR(mod_param_1_double_precision, S_IWUSR | 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_IWUSR | S_IRUGO, + pod_get_delay_param_1_double_precision, + pod_set_delay_param_1_double_precision); +static DEVICE_ATTR(eq_enable, S_IWUSR | S_IRUGO, pod_get_eq_enable, + pod_set_eq_enable); +static DEVICE_ATTR(tap, S_IWUSR | S_IRUGO, pod_get_tap, pod_set_tap); +static DEVICE_ATTR(volume_tweak_pedal_assign, S_IWUSR | S_IRUGO, + pod_get_volume_tweak_pedal_assign, + pod_set_volume_tweak_pedal_assign); +static DEVICE_ATTR(band_5_frequency, S_IWUSR | S_IRUGO, + pod_get_band_5_frequency, pod_set_band_5_frequency); +static DEVICE_ATTR(tuner, S_IWUSR | S_IRUGO, pod_get_tuner, pod_set_tuner); +static DEVICE_ATTR(mic_selection, S_IWUSR | S_IRUGO, pod_get_mic_selection, + pod_set_mic_selection); +static DEVICE_ATTR(cabinet_model, S_IWUSR | S_IRUGO, pod_get_cabinet_model, + pod_set_cabinet_model); +static DEVICE_ATTR(stomp_model, S_IWUSR | S_IRUGO, pod_get_stomp_model, + pod_set_stomp_model); +static DEVICE_ATTR(roomlevel, S_IWUSR | S_IRUGO, pod_get_roomlevel, + pod_set_roomlevel); +static DEVICE_ATTR(band_4_frequency, S_IWUSR | S_IRUGO, + pod_get_band_4_frequency, pod_set_band_4_frequency); +static DEVICE_ATTR(band_6_frequency, S_IWUSR | S_IRUGO, + pod_get_band_6_frequency, pod_set_band_6_frequency); +static DEVICE_ATTR(stomp_param_1_note_value, S_IWUSR | S_IRUGO, + pod_get_stomp_param_1_note_value, + pod_set_stomp_param_1_note_value); +static DEVICE_ATTR(stomp_param_2, S_IWUSR | S_IRUGO, pod_get_stomp_param_2, + pod_set_stomp_param_2); +static DEVICE_ATTR(stomp_param_3, S_IWUSR | S_IRUGO, pod_get_stomp_param_3, + pod_set_stomp_param_3); +static DEVICE_ATTR(stomp_param_4, S_IWUSR | S_IRUGO, pod_get_stomp_param_4, + pod_set_stomp_param_4); +static DEVICE_ATTR(stomp_param_5, S_IWUSR | S_IRUGO, pod_get_stomp_param_5, + pod_set_stomp_param_5); +static DEVICE_ATTR(stomp_param_6, S_IWUSR | S_IRUGO, pod_get_stomp_param_6, + pod_set_stomp_param_6); +static DEVICE_ATTR(amp_switch_select, S_IWUSR | S_IRUGO, + pod_get_amp_switch_select, pod_set_amp_switch_select); +static DEVICE_ATTR(delay_param_4, S_IWUSR | S_IRUGO, pod_get_delay_param_4, + pod_set_delay_param_4); +static DEVICE_ATTR(delay_param_5, S_IWUSR | S_IRUGO, pod_get_delay_param_5, + pod_set_delay_param_5); +static DEVICE_ATTR(delay_pre_post, S_IWUSR | S_IRUGO, pod_get_delay_pre_post, + pod_set_delay_pre_post); +static DEVICE_ATTR(delay_model, S_IWUSR | S_IRUGO, pod_get_delay_model, + pod_set_delay_model); +static DEVICE_ATTR(delay_verb_model, S_IWUSR | S_IRUGO, + pod_get_delay_verb_model, pod_set_delay_verb_model); +static DEVICE_ATTR(tempo_msb, S_IWUSR | S_IRUGO, pod_get_tempo_msb, + pod_set_tempo_msb); +static DEVICE_ATTR(tempo_lsb, S_IWUSR | S_IRUGO, pod_get_tempo_lsb, + pod_set_tempo_lsb); +static DEVICE_ATTR(wah_model, S_IWUSR | S_IRUGO, pod_get_wah_model, + pod_set_wah_model); +static DEVICE_ATTR(bypass_volume, S_IWUSR | S_IRUGO, pod_get_bypass_volume, + pod_set_bypass_volume); +static DEVICE_ATTR(fx_loop_on_off, S_IWUSR | S_IRUGO, pod_get_fx_loop_on_off, + pod_set_fx_loop_on_off); +static DEVICE_ATTR(tweak_param_select, S_IWUSR | S_IRUGO, + pod_get_tweak_param_select, pod_set_tweak_param_select); +static DEVICE_ATTR(amp1_engage, S_IWUSR | S_IRUGO, pod_get_amp1_engage, + pod_set_amp1_engage); +static DEVICE_ATTR(band_1_gain, S_IWUSR | S_IRUGO, pod_get_band_1_gain, + pod_set_band_1_gain); +static DEVICE_ATTR2(band_2_gain__bass, band_2_gain, S_IWUSR | S_IRUGO, + pod_get_band_2_gain__bass, pod_set_band_2_gain__bass); +static DEVICE_ATTR(band_2_gain, S_IWUSR | S_IRUGO, pod_get_band_2_gain, + pod_set_band_2_gain); +static DEVICE_ATTR2(band_3_gain__bass, band_3_gain, S_IWUSR | S_IRUGO, + pod_get_band_3_gain__bass, pod_set_band_3_gain__bass); +static DEVICE_ATTR(band_3_gain, S_IWUSR | S_IRUGO, pod_get_band_3_gain, + pod_set_band_3_gain); +static DEVICE_ATTR2(band_4_gain__bass, band_4_gain, S_IWUSR | 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_IWUSR | S_IRUGO, + pod_get_band_5_gain__bass, pod_set_band_5_gain__bass); +static DEVICE_ATTR(band_4_gain, S_IWUSR | S_IRUGO, pod_get_band_4_gain, + pod_set_band_4_gain); +static DEVICE_ATTR2(band_6_gain__bass, band_6_gain, S_IWUSR | 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); +}sound/usb/line6/control.h new file +176
-0@@ -0,0 +1,195 @@ +/* +* Line6 Linux USB driver - 0.9.1beta +* +* Copyright (C) 2004-2010 Markus Grabner ([email protected]) +* +* 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 */ +};
sound/usb/line6/control.h line 186
Quoted 10 lines
sound/usb/line6/control.h new file +10
-0+ +/** +List of Variax workbench controls (MIDI). +*/ +enum { + VARIAXMIDI_volume =7 , + VARIAXMIDI_tone =79 , +}; + +/* *INDENT-ON* */
That looks like a editor command?
sound/usb/line6/playback.c
Quoted 3,965 lines
sound/usb/line6/control.h new file +9
-0+ +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 sound/usb/line6/driver.c new file +1290
-0@@ -0,0 +1,1290 @@ +/* +* Line6 Linux USB driver - 0.9.1beta +* +* Copyright (C) 2004-2010 Markus Grabner ([email protected]) +* +* 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/kernel.h> +#include <linux/module.h> +#include <linux/slab.h> +#include <linux/usb.h> + +#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" +#include "variax.h" + +#define DRIVER_AUTHOR "Markus Grabner <[email protected]>" +#define DRIVER_DESC "Line6 USB Driver" +#define DRIVER_VERSION "0.9.1beta" DRIVER_REVISION + +/* table of devices that work with this driver */ +static const struct usb_device_id line6_id_table[] = { + {USB_DEVICE (LINE6_VENDOR_ID ,LINE6_DEVID_BASSPODXT )}, + {USB_DEVICE (LINE6_VENDOR_ID ,LINE6_DEVID_BASSPODXTLIVE )}, + {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_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 )}, + {USB_DEVICE (LINE6_VENDOR_ID ,LINE6_DEVID_PODX3 )}, + {USB_DEVICE (LINE6_VENDOR_ID ,LINE6_DEVID_PODX3LIVE )}, + {USB_DEVICE (LINE6_VENDOR_ID ,LINE6_DEVID_PODXT )}, + {USB_DEVICE (LINE6_VENDOR_ID ,LINE6_DEVID_PODXTLIVE )}, + {USB_DEVICE (LINE6_VENDOR_ID ,LINE6_DEVID_PODXTPRO )}, + {USB_DEVICE (LINE6_VENDOR_ID ,LINE6_DEVID_TONEPORT_GX )}, + {USB_DEVICE (LINE6_VENDOR_ID ,LINE6_DEVID_TONEPORT_UX1 )}, + {USB_DEVICE (LINE6_VENDOR_ID ,LINE6_DEVID_TONEPORT_UX2 )}, + {USB_DEVICE (LINE6_VENDOR_ID ,LINE6_DEVID_VARIAX )}, + {}, +}; + +MODULE_DEVICE_TABLE (usb, line6_id_table); + +/* *INDENT-OFF* */ +static struct line6_properties line6_properties_table[] = { + {LINE6_BIT_BASSPODXT ,"BassPODxt" ,"BassPODxt" ,LINE6_BIT_CONTROL_PCM_HWMON }, + {LINE6_BIT_BASSPODXTLIVE ,"BassPODxtLive" ,"BassPODxt Live" ,LINE6_BIT_CONTROL_PCM_HWMON }, + {LINE6_BIT_BASSPODXTPRO ,"BassPODxtPro" ,"BassPODxt Pro" ,LINE6_BIT_CONTROL_PCM_HWMON }, + {LINE6_BIT_GUITARPORT ,"GuitarPort" ,"GuitarPort" ,LINE6_BIT_PCM }, + {LINE6_BIT_POCKETPOD ,"PocketPOD" ,"Pocket POD" ,LINE6_BIT_CONTROL }, + {LINE6_BIT_PODHD300 ,"PODHD300" ,"POD HD300" ,LINE6_BIT_CONTROL_PCM_HWMON }, + {LINE6_BIT_PODHD500 ,"PODHD500" ,"POD HD500" ,LINE6_BIT_CONTROL_PCM_HWMON }, + {LINE6_BIT_PODSTUDIO_GX ,"PODStudioGX" ,"POD Studio GX" ,LINE6_BIT_PCM }, + {LINE6_BIT_PODSTUDIO_UX1 ,"PODStudioUX1" ,"POD Studio UX1" ,LINE6_BIT_PCM }, + {LINE6_BIT_PODSTUDIO_UX2 ,"PODStudioUX2" ,"POD Studio UX2" ,LINE6_BIT_PCM }, + {LINE6_BIT_PODX3 ,"PODX3" ,"POD X3" ,LINE6_BIT_PCM }, + {LINE6_BIT_PODX3LIVE ,"PODX3Live" ,"POD X3 Live" ,LINE6_BIT_PCM }, + {LINE6_BIT_PODXT ,"PODxt" ,"PODxt" ,LINE6_BIT_CONTROL_PCM_HWMON }, + {LINE6_BIT_PODXTLIVE ,"PODxtLive" ,"PODxt Live" ,LINE6_BIT_CONTROL_PCM_HWMON }, + {LINE6_BIT_PODXTPRO ,"PODxtPro" ,"PODxt Pro" ,LINE6_BIT_CONTROL_PCM_HWMON }, + {LINE6_BIT_TONEPORT_GX ,"TonePortGX" ,"TonePort GX" ,LINE6_BIT_PCM }, + {LINE6_BIT_TONEPORT_UX1 ,"TonePortUX1" ,"TonePort UX1" ,LINE6_BIT_PCM }, + {LINE6_BIT_TONEPORT_UX2 ,"TonePortUX2" ,"TonePort UX2" ,LINE6_BIT_PCM }, + {LINE6_BIT_VARIAX ,"Variax" ,"Variax Workbench" ,LINE6_BIT_CONTROL }, +}; +/* *INDENT-ON* */ + +/* +This is Line6's MIDI manufacturer ID. +*/ +const unsigned char line6_midi_id[] = { +0x00 ,0x01 ,0x0c +}; + +/* +Code to request version of POD, Variax interface +(and maybe other devices). +*/ +static const char line6_request_version[] = { +0xf0 ,0x7e ,0x7f ,0x06 ,0x01 ,0xf7 +}; + +/** +Class for asynchronous messages. +*/ +struct message { +struct usb_line6 *line6; +const char *buffer; +int size; +int done; +}; + +/* +Forward declarations. +*/ +static void line6_data_received (struct urb *urb); +static int line6_send_raw_message_async_part (struct message *msg, +struct urb *urb); + +/* +Start to listen on endpoint. +*/ +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 , + line6_data_received, line6, line6->interval); + line6->urb_listen->actual_length =0 ; + err =usb_submit_urb (line6->urb_listen,GFP_ATOMIC ); +return err; +} + +/* +Stop listening on endpoint. +*/ +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. +*/ +int line6_send_raw_message (struct usb_line6 *line6,const char *buffer, +int size) +{ +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; +int frag_size =min (line6->max_packet_size, size - i); +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 ); + +if (retval) { +dev_err (line6->ifcdev, +"usb_interrupt_msg failed (%d)\n" , retval); +break ; + } + + done += frag_size; + } + +return done; +} + +/* +Notification of completion of asynchronous request transmission. +*/ +static void line6_async_request_sent (struct urb *urb) +{ +struct message *msg = (struct message *)urb->context; + +if (msg->done >= msg->size) { +usb_free_urb (urb); +kfree (msg); + }else +line6_send_raw_message_async_part (msg, urb); +} + +/* +Asynchronously send part of a raw message. +*/ +static int line6_send_raw_message_async_part (struct message *msg, +struct urb *urb) +{ +int retval; +struct usb_line6 *line6 = msg->line6; +int done = msg->done; +int bytes =min (msg->size - done, line6->max_packet_size); + +usb_fill_int_urb (urb, line6->usbdev, +usb_sndintpipe (line6->usbdev, line6->ep_control_write), + (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 ); + +if (retval <0 ) { +dev_err (line6->ifcdev,"%s: usb_submit_urb failed (%d)\n" , + __func__, retval); +usb_free_urb (urb); +kfree (msg); +return -EINVAL ; + } + +return 0 ; +} + +/* +Setup and start timer. +*/ +void line6_start_timer (struct timer_list *timer,unsigned int msecs, +void (*function) (unsigned long ),unsigned long data) +{ +setup_timer (timer, function, data); + timer->expires = jiffies + msecs *HZ /1000 ; +add_timer (timer); +} + +/* +Asynchronously send raw message. +*/ +int line6_send_raw_message_async (struct usb_line6 *line6,const char *buffer, +int size) +{ +struct message *msg; +struct urb *urb; + +/* create message: */ + msg =kmalloc (sizeof (struct message ),GFP_ATOMIC ); + +if (msg ==NULL ) { +dev_err (line6->ifcdev,"Out of memory\n" ); +return -ENOMEM ; + } + +/* create URB: */ + urb =usb_alloc_urb (0 ,GFP_ATOMIC ); + +if (urb ==NULL ) { +kfree (msg); +dev_err (line6->ifcdev,"Out of memory\n" ); +return -ENOMEM ; + } + +/* set message data: */ + msg->line6 = line6; + msg->buffer = buffer; + msg->size = size; + msg->done =0 ; + +/* start sending: */ +return line6_send_raw_message_async_part (msg, urb); +} + +/* +Send asynchronous device version request. +*/ +int line6_version_request_async (struct usb_line6 *line6) +{ +char *buffer; +int retval; + + buffer =kmalloc (sizeof (line6_request_version),GFP_ATOMIC ); +if (buffer ==NULL ) { +dev_err (line6->ifcdev,"Out of memory" ); +return -ENOMEM ; + } + +memcpy (buffer, line6_request_version,sizeof (line6_request_version)); + + retval =line6_send_raw_message_async (line6, buffer, +sizeof (line6_request_version)); +kfree (buffer); +return retval; +} + +/* +Send sysex message in pieces of wMaxPacketSize bytes. +*/ +int line6_send_sysex_message (struct usb_line6 *line6,const char *buffer, +int size) +{ +return line6_send_raw_message (line6, buffer, + size +SYSEX_EXTRA_SIZE ) - +SYSEX_EXTRA_SIZE ; +} + +/* +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 +*/ +char *line6_alloc_sysex_buffer (struct usb_line6 *line6,int code1,int code2, +int size) +{ +char *buffer =kmalloc (size +SYSEX_EXTRA_SIZE ,GFP_ATOMIC ); + +if (!buffer) { +dev_err (line6->ifcdev,"out of memory\n" ); +return NULL ; + } + + buffer[0 ] =LINE6_SYSEX_BEGIN ; +memcpy (buffer +1 , line6_midi_id,sizeof (line6_midi_id)); + buffer[sizeof (line6_midi_id) +1 ] = code1; + buffer[sizeof (line6_midi_id) +2 ] = code2; + buffer[sizeof (line6_midi_id) +3 + size] =LINE6_SYSEX_END ; +return buffer; +} + +/* +Notification of data received from the Line6 device. +*/ +static void line6_data_received (struct urb *urb) +{ +struct usb_line6 *line6 = (struct usb_line6 *)urb->context; +struct MidiBuffer *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)); + } + +for (;;) { + done = +line6_midibuf_read (mb, line6->buffer_message, +LINE6_MESSAGE_MAXLEN ); + +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) { +case LINE6_DEVID_BASSPODXT : +case LINE6_DEVID_BASSPODXTLIVE : +case LINE6_DEVID_BASSPODXTPRO : +case LINE6_DEVID_PODXT : +case LINE6_DEVID_PODXTPRO : +case LINE6_DEVID_POCKETPOD : +line6_pod_process_message ((struct usb_line6_pod *) + line6); +break ; + +case LINE6_DEVID_PODHD300 : +case LINE6_DEVID_PODHD500 : +break ;/* let userspace handle MIDI */ + +case LINE6_DEVID_PODXTLIVE : +switch (line6->interface_number) { +case PODXTLIVE_INTERFACE_POD : +line6_pod_process_message ((struct usb_line6_pod + *)line6); +break ; + +case PODXTLIVE_INTERFACE_VARIAX : +line6_variax_process_message ((struct +usb_line6_variax + *)line6); +break ; + +default : +dev_err (line6->ifcdev, +"PODxt Live interface %d not supported\n" , + line6->interface_number); + } +break ; + +case LINE6_DEVID_VARIAX : +line6_variax_process_message ((struct usb_line6_variax *) + line6); +break ; + +default : +MISSING_CASE ; + } + } + +line6_start_listen (line6); +} + +/* +Send channel number (i.e., switch to a different sound). +*/ +int line6_send_program (struct usb_line6 *line6,u8 value) +{ +int retval; +unsigned char *buffer; +int partial; + + buffer =kmalloc (2 ,GFP_KERNEL ); + +if (!buffer) { +dev_err (line6->ifcdev,"out of memory\n" ); +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), + buffer,2 , &partial,LINE6_TIMEOUT *HZ ); + +if (retval) +dev_err (line6->ifcdev,"usb_interrupt_msg failed (%d)\n" , + retval); + +kfree (buffer); +return retval; +} + +/* +Transmit Line6 control parameter. +*/ +int line6_transmit_parameter (struct usb_line6 *line6,int param,u8 value) +{ +int retval; +unsigned char *buffer; +int partial; + + buffer =kmalloc (3 ,GFP_KERNEL ); + +if (!buffer) { +dev_err (line6->ifcdev,"out of memory\n" ); +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), + buffer,3 , &partial,LINE6_TIMEOUT *HZ ); + +if (retval) +dev_err (line6->ifcdev,"usb_interrupt_msg failed (%d)\n" , + retval); + +kfree (buffer); +return retval; +} + +/* +Read data from device. +*/ +int line6_read_data (struct usb_line6 *line6,int address,void *data, +size_t datalen) +{ +struct usb_device *usbdev = line6->usbdev; +int ret; +unsigned char len; + +/* query the serial number: */ + ret =usb_control_msg (usbdev,usb_sndctrlpipe (usbdev,0 ),0x67 , +USB_TYPE_VENDOR |USB_RECIP_DEVICE |USB_DIR_OUT , + (datalen <<8 ) |0x21 , address, +NULL ,0 ,LINE6_TIMEOUT *HZ ); + +if (ret <0 ) { +dev_err (line6->ifcdev,"read request failed (error %d)\n" , ret); +return ret; + } + +/* Wait for data length. We'll get a couple of 0xff until length arrives. */ +do { + ret =usb_control_msg (usbdev,usb_rcvctrlpipe (usbdev,0 ),0x67 , +USB_TYPE_VENDOR |USB_RECIP_DEVICE | +USB_DIR_IN , +0x0012 ,0x0000 , &len,1 , +LINE6_TIMEOUT *HZ ); +if (ret <0 ) { +dev_err (line6->ifcdev, +"receive length failed (error %d)\n" , ret); +return ret; + } + }while (len ==0xff ); + +if (len != datalen) { +/* should be equal or something went wrong */ +dev_err (line6->ifcdev, +"length mismatch (expected %d, got %d)\n" , + (int )datalen, (int )len); +return -EINVAL ; + } + +/* receive the result: */ + ret =usb_control_msg (usbdev,usb_rcvctrlpipe (usbdev,0 ),0x67 , +USB_TYPE_VENDOR |USB_RECIP_DEVICE |USB_DIR_IN , +0x0013 ,0x0000 , data, datalen, +LINE6_TIMEOUT *HZ ); + +if (ret <0 ) { +dev_err (line6->ifcdev,"read failed (error %d)\n" , ret); +return ret; + } + +return 0 ; +} + +/* +Write data to device. +*/ +int line6_write_data (struct usb_line6 *line6,int address,void *data, +size_t datalen) +{ +struct usb_device *usbdev = line6->usbdev; +int ret; +unsigned char status; + + ret =usb_control_msg (usbdev,usb_sndctrlpipe (usbdev,0 ),0x67 , +USB_TYPE_VENDOR |USB_RECIP_DEVICE |USB_DIR_OUT , +0x0022 , address, data, datalen, +LINE6_TIMEOUT *HZ ); + +if (ret <0 ) { +dev_err (line6->ifcdev, +"write request failed (error %d)\n" , ret); +return ret; + } + +do { + ret =usb_control_msg (usbdev,usb_rcvctrlpipe (usbdev,0 ), +0x67 , +USB_TYPE_VENDOR |USB_RECIP_DEVICE | +USB_DIR_IN , +0x0012 ,0x0000 , + &status,1 ,LINE6_TIMEOUT *HZ ); + +if (ret <0 ) { +dev_err (line6->ifcdev, +"receiving status failed (error %d)\n" , ret); +return ret; + } + }while (status ==0xff ); + +if (status !=0 ) { +dev_err (line6->ifcdev,"write failed (error %d)\n" , ret); +return -EINVAL ; + } + +return 0 ; +} + +/* +Read Line6 device serial number. +(POD, TonePort, GuitarPort) +*/ +int line6_read_serial_number (struct usb_line6 *line6,int *serial_number) +{ +return line6_read_data (line6,0x80d0 , serial_number, +sizeof (*serial_number)); +} + +/* +No operation (i.e., unsupported). +*/ +ssize_t line6_nop_read (struct device *dev,struct device_attribute *attr, +char *buf) +{ +return 0 ; +} + +/* +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) +{ +struct usb_line6 *line6; + +if (interface ==NULL ) +return ; + line6 =usb_get_intfdata (interface); +if (line6 ==NULL ) +return ; + +/* free buffer memory first: */ +kfree (line6->buffer_message); +kfree (line6->buffer_listen); + +/* then free URBs: */ +usb_free_urb (line6->urb_listen); + +/* make sure the device isn't destructed twice: */ +usb_set_intfdata (interface,NULL ); + +/* free interface data: */ +kfree (line6); +} + +/* +Probe USB device. +*/ +static int line6_probe (struct usb_interface *interface, +const struct usb_device_id *id) +{ +int devtype; +struct usb_device *usbdev; +struct usb_line6 *line6; +const struct line6_properties *properties; +int interface_number, alternate =0 ; +int product; +int size =0 ; +int ep_read =0 , ep_write =0 ; +int ret; + +if (interface ==NULL ) +return -ENODEV ; + usbdev =interface_to_usbdev (interface); +if (usbdev ==NULL ) +return -ENODEV ; + +/* we don't handle multiple configurations */ +if (usbdev->descriptor.bNumConfigurations !=1 ) { + ret = -ENODEV ; + goto err_put; + } + +/* check vendor and product id */ +for (devtype =ARRAY_SIZE (line6_id_table) -1 ; devtype--;) { +u16 idVendor =le16_to_cpu (usbdev->descriptor.idVendor); +u16 idProduct =le16_to_cpu (usbdev->descriptor.idProduct); + +if (idVendor == line6_id_table[devtype].idVendor && + idProduct == line6_id_table[devtype].idProduct) +break ; + } + +if (devtype <0 ) { + ret = -ENODEV ; + goto err_put; + } + +/* initialize device info: */ + properties = &line6_properties_table[devtype]; +dev_info (&interface->dev,"Line6 %s found\n" , properties->name); + product =le16_to_cpu (usbdev->descriptor.idProduct); + +/* query interface number */ + interface_number = interface->cur_altsetting->desc.bInterfaceNumber; + +switch (product) { +case LINE6_DEVID_BASSPODXTLIVE : +case LINE6_DEVID_PODXTLIVE : +case LINE6_DEVID_VARIAX : + alternate =1 ; +break ; + +case LINE6_DEVID_POCKETPOD : +switch (interface_number) { +case 0 : +return 0 ;/* this interface has no endpoints */ +case 1 : + alternate =0 ; +break ; +default : +MISSING_CASE ; + } +break ; + +case LINE6_DEVID_PODHD500 : +case LINE6_DEVID_PODX3 : +case LINE6_DEVID_PODX3LIVE : +switch (interface_number) { +case 0 : + alternate =1 ; +break ; +case 1 : + alternate =0 ; +break ; +default : +MISSING_CASE ; + } +break ; + +case LINE6_DEVID_BASSPODXT : +case LINE6_DEVID_BASSPODXTPRO : +case LINE6_DEVID_PODXT : +case LINE6_DEVID_PODXTPRO : +case LINE6_DEVID_PODHD300 : + alternate =5 ; +break ; + +case LINE6_DEVID_GUITARPORT : +case LINE6_DEVID_PODSTUDIO_GX : +case LINE6_DEVID_PODSTUDIO_UX1 : +case LINE6_DEVID_TONEPORT_GX : +case LINE6_DEVID_TONEPORT_UX1 : + alternate =2 ;/* 1..4 seem to be ok */ +break ; + +case LINE6_DEVID_TONEPORT_UX2 : +case LINE6_DEVID_PODSTUDIO_UX2 : +switch (interface_number) { +case 0 : +/* defaults to 44.1kHz, 16-bit */ + alternate =2 ; +break ; +case 1 : +/* don't know yet what this is ... +alternate = 1; +break; +*/ +return -ENODEV ; +default : +MISSING_CASE ; + } +break ; + +default : +MISSING_CASE ; + ret = -ENODEV ; + goto err_put; + } + + ret =usb_set_interface (usbdev, interface_number, alternate); +if (ret <0 ) { +dev_err (&interface->dev,"set_interface failed\n" ); + goto err_put; + } + +/* initialize device data based on product id: */ +switch (product) { +case LINE6_DEVID_BASSPODXT : +case LINE6_DEVID_BASSPODXTLIVE : +case LINE6_DEVID_BASSPODXTPRO : +case LINE6_DEVID_PODXT : +case LINE6_DEVID_PODXTPRO : + size =sizeof (struct usb_line6_pod ); + ep_read =0x84 ; + ep_write =0x03 ; +break ; + +case LINE6_DEVID_PODHD300 : + 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 ; + ep_write =0x02 ; +break ; + +case LINE6_DEVID_PODX3 : +case LINE6_DEVID_PODX3LIVE : +/* currently unused! */ + size =sizeof (struct usb_line6_pod ); + ep_read =0x81 ; + ep_write =0x01 ; +break ; + +case LINE6_DEVID_PODSTUDIO_GX : +case LINE6_DEVID_PODSTUDIO_UX1 : +case LINE6_DEVID_PODSTUDIO_UX2 : +case LINE6_DEVID_TONEPORT_GX : +case LINE6_DEVID_TONEPORT_UX1 : +case LINE6_DEVID_TONEPORT_UX2 : +case LINE6_DEVID_GUITARPORT : + size =sizeof (struct usb_line6_toneport ); +/* these don't have a control channel */ +break ; + +case LINE6_DEVID_PODXTLIVE : +switch (interface_number) { +case PODXTLIVE_INTERFACE_POD : + size =sizeof (struct usb_line6_pod ); + ep_read =0x84 ; + ep_write =0x03 ; +break ; + +case PODXTLIVE_INTERFACE_VARIAX : + size =sizeof (struct usb_line6_variax ); + ep_read =0x86 ; + ep_write =0x05 ; +break ; + +default : + ret = -ENODEV ; + goto err_put; + } +break ; + +case LINE6_DEVID_VARIAX : + size =sizeof (struct usb_line6_variax ); + ep_read =0x82 ; + ep_write =0x01 ; +break ; + +default : +MISSING_CASE ; + ret = -ENODEV ; + goto err_put; + } + +if (size ==0 ) { +dev_err (&interface->dev, +"driver bug: interface data size not set\n" ); + ret = -ENODEV ; + goto err_put; + } + + line6 =kzalloc (size,GFP_KERNEL ); + +if (line6 ==NULL ) { +dev_err (&interface->dev,"Out of memory\n" ); + ret = -ENODEV ; + goto err_put; + } + +/* store basic data: */ + line6->interface_number = interface_number; + line6->properties = properties; + line6->usbdev = usbdev; + line6->ifcdev = &interface->dev; + line6->ep_control_read = ep_read; + line6->ep_control_write = ep_write; + line6->product = product; + +/* get data from endpoint descriptor (see usb_maxpacket): */ + { +struct usb_host_endpoint *ep; +unsigned epnum = +usb_pipeendpoint (usb_rcvintpipe (usbdev, ep_read)); + ep = usbdev->ep_in[epnum]; + +if (ep !=NULL ) { + line6->interval = ep->desc.bInterval; + line6->max_packet_size = +le16_to_cpu (ep->desc.wMaxPacketSize); + }else { + line6->interval =LINE6_FALLBACK_INTERVAL ; + line6->max_packet_size =LINE6_FALLBACK_MAXPACKETSIZE ; +dev_err (line6->ifcdev, +"endpoint not available, using fallback values" ); + } + } + +usb_set_intfdata (interface, line6); + +if (properties->capabilities &LINE6_BIT_CONTROL ) { +/* 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; + } + + line6->urb_listen =usb_alloc_urb (0 ,GFP_KERNEL ); + +if (line6->urb_listen ==NULL ) { +dev_err (&interface->dev,"Out of memory\n" ); +line6_destruct (interface); + ret = -ENOMEM ; + goto err_destruct; + } + + ret =line6_start_listen (line6); +if (ret <0 ) { +dev_err (&interface->dev,"%s: usb_submit_urb failed\n" , + __func__); + goto err_destruct; + } + } + +/* initialize device data based on product id: */ +switch (product) { +case LINE6_DEVID_BASSPODXT : +case LINE6_DEVID_BASSPODXTLIVE : +case LINE6_DEVID_BASSPODXTPRO : +case LINE6_DEVID_POCKETPOD : +case LINE6_DEVID_PODX3 : +case LINE6_DEVID_PODX3LIVE : +case LINE6_DEVID_PODXT : +case LINE6_DEVID_PODXTPRO : + ret =line6_pod_init (interface, (struct usb_line6_pod *)line6); +break ; + +case LINE6_DEVID_PODHD300 : +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 : + ret = +line6_pod_init (interface, + (struct usb_line6_pod *)line6); +break ; + +case PODXTLIVE_INTERFACE_VARIAX : + ret = +line6_variax_init (interface, + (struct usb_line6_variax *)line6); +break ; + +default : +dev_err (&interface->dev, +"PODxt Live interface %d not supported\n" , + interface_number); + ret = -ENODEV ; + } + +break ; + +case LINE6_DEVID_VARIAX : + ret = +line6_variax_init (interface, + (struct usb_line6_variax *)line6); +break ; + +case LINE6_DEVID_PODSTUDIO_GX : +case LINE6_DEVID_PODSTUDIO_UX1 : +case LINE6_DEVID_PODSTUDIO_UX2 : +case LINE6_DEVID_TONEPORT_GX : +case LINE6_DEVID_TONEPORT_UX1 : +case LINE6_DEVID_TONEPORT_UX2 : +case LINE6_DEVID_GUITARPORT : + ret = +line6_toneport_init (interface, + (struct usb_line6_toneport *)line6); +break ; + +default : +MISSING_CASE ; + ret = -ENODEV ; + } + +if (ret <0 ) + goto err_destruct; + + ret =sysfs_create_link (&interface->dev.kobj, &usbdev->dev.kobj, +"usb_device" ); +if (ret <0 ) + goto err_destruct; + +/* creation of additional special files should go here */ + +dev_info (&interface->dev,"Line6 %s now attached\n" , + line6->properties->name); + +switch (product) { +case LINE6_DEVID_PODX3 : +case LINE6_DEVID_PODX3LIVE : +dev_info (&interface->dev, +"NOTE: the Line6 %s is detected, but not yet supported\n" , + line6->properties->name); + } + +/* increment reference counters: */ +usb_get_intf (interface); +usb_get_dev (usbdev); + +return 0 ; + +err_destruct: +line6_destruct (interface); +err_put: +return ret; +} + +/* +Line6 device disconnected. +*/ +static void line6_disconnect (struct usb_interface *interface) +{ +struct usb_line6 *line6; +struct usb_device *usbdev; +int interface_number; + +if (interface ==NULL ) +return ; + usbdev =interface_to_usbdev (interface); +if (usbdev ==NULL ) +return ; + +/* removal of additional special files should go here */ + +sysfs_remove_link (&interface->dev.kobj,"usb_device" ); + + interface_number = interface->cur_altsetting->desc.bInterfaceNumber; + line6 =usb_get_intfdata (interface); + +if (line6 !=NULL ) { +if (line6->urb_listen !=NULL ) +line6_stop_listen (line6); +Lines of this file are not shown. View the raw message.
sound/usb/line6/dumprequest.c new file +135
-0Lines of this file are not shown. View the raw message.
sound/usb/line6/dumprequest.h new file +76
-0Lines of this file are not shown. View the raw message.
The rest of this diff is not shown. View the raw message.
That should be either a runtime condition or the #ifdef should be removed.
sound/usb/line6/playback.c
Quoted 129 lines
sound/usb/line6/playback.c new file +129
-0Lines of this file are not shown. View the raw message.
The rest of this diff is not shown. View the raw message.
This condition is not needed.
sound/usb/line6/playback.c
Quoted 11 lines
sound/usb/line6/playback.c new file +11
-0Lines of this file are not shown. View the raw message.
The rest of this diff is not shown. View the raw message.
Dito.
sound/usb/line6/pod.c
Quoted 177 lines
sound/usb/line6/playback.c new file +74
-0Lines of this file are not shown. View the raw message.
The rest of this diff is not shown. View the raw message.
Please make them consisten in naming.
sound/usb/line6/pod.c
Quoted 32 lines
sound/usb/line6/pod.c new file +32
-0Lines of this file are not shown. View the raw message.
The rest of this diff is not shown. View the raw message.
No need to do this conditionally.
sound/usb/line6/pod.c
Quoted 20 lines
sound/usb/line6/pod.c new file +20
-0Lines of this file are not shown. View the raw message.
The rest of this diff is not shown. View the raw message.
Dito.
sound/usb/line6/pod.c
Quoted 30 lines
sound/usb/line6/pod.c new file +30
-0Lines of this file are not shown. View the raw message.
The rest of this diff is not shown. View the raw message.
Can't they be avoided by changing the function order?
sound/usb/line6/pod.c
Quoted 960 lines
sound/usb/line6/pod.c new file +960
-0Lines of this file are not shown. View the raw message.
The rest of this diff is not shown. View the raw message.
Why aren't most of these just exported as mixer controls? No other USB audio device exports such functionality via sysfs, and given that the structure here is not anything that is standardized, we should really avoid that.
Thanks,
Daniel
Part of the diff is not shown here. View the raw message.
Quoted 10 lines · Daniel Mack
Hi,
Quoted 3 lines · Stefan Hajnoczi
The line6 driver supports devices from the Line6 PODxt, POD HD, TonePort, and Variax product families. This USB sound driver has been in staging since 2009 and is ready for wider review and users.
Thanks a lot for working on this! However, just moving over the current code does not seem sufficient.
Quoted 6 lines
Alone,
script/checkpatch.plgives metotal: 9234 errors, 158 warnings, 9233 lines checked
including DOS line feeds, broken indentation and other style issues. I think at least most of them need to be fixed.
Thanks for the response and sorry I forgot to check this.
Stefan
Greg Kroah-Hartman
maintainerQuoted 9 lines · Stefan Hajnoczi
The line6 driver supports devices from the Line6 PODxt, POD HD, TonePort, and Variax product families. This USB sound driver has been in staging since 2009 and is ready for wider review and users.
These devices provide both PCM and MIDI. Depending on the model the PCM supports capture and playback - there may be multiple capture sources. MIDI is used to control the device including changing effect or amplifier model settings, dumping presets, and changing between patches.
Quoted 7 lines
There are userspace tools and a manual available at:
http://www.tanzband-scream.at/line6/
http://line6linux.sourceforge.net/Cc Markus Grabner <[email protected]>Signed-off-by Stefan Hajnoczi <[email protected]>
Please fix all of the coding style issues, and the huge number of undocumented sysfs files before asking to move this out of staging.
thanks,
greg k-h