aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/staging
diff options
context:
space:
mode:
authorMarkus Grabner <grabner@icg.tugraz.at>2009-02-27 22:43:04 -0500
committerGreg Kroah-Hartman <gregkh@suse.de>2009-04-03 17:54:24 -0400
commit705ececd1c60d0f5d6ef2a719008847883516970 (patch)
treee2a96ac85e15850919e493181fe47f7fdd471af1 /drivers/staging
parente642f09951f7cbb69983781b07bb9cd881546ac4 (diff)
Staging: add line6 usb driver
This is an experimental Linux 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) Moreover, preliminary support for the Variax Workbench is included. From: Markus Grabner <grabner@icg.tugraz.at> Cc: Mariusz Kozlowski <m.kozlowski@tuxland.pl> Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
Diffstat (limited to 'drivers/staging')
-rw-r--r--drivers/staging/line6/Kconfig20
-rw-r--r--drivers/staging/line6/Makefile15
-rw-r--r--drivers/staging/line6/audio.c69
-rw-r--r--drivers/staging/line6/audio.h24
-rw-r--r--drivers/staging/line6/capture.c370
-rw-r--r--drivers/staging/line6/capture.h31
-rw-r--r--drivers/staging/line6/config.h73
-rw-r--r--drivers/staging/line6/control.c702
-rw-r--r--drivers/staging/line6/control.h187
-rw-r--r--drivers/staging/line6/driver.c1050
-rw-r--r--drivers/staging/line6/driver.h190
-rw-r--r--drivers/staging/line6/dumprequest.c143
-rw-r--r--drivers/staging/line6/dumprequest.h87
-rw-r--r--drivers/staging/line6/midi.c398
-rw-r--r--drivers/staging/line6/midi.h87
-rw-r--r--drivers/staging/line6/midibuf.c268
-rw-r--r--drivers/staging/line6/midibuf.h39
-rw-r--r--drivers/staging/line6/pcm.c289
-rw-r--r--drivers/staging/line6/pcm.h210
-rw-r--r--drivers/staging/line6/playback.c428
-rw-r--r--drivers/staging/line6/playback.h29
-rw-r--r--drivers/staging/line6/pod.c1100
-rw-r--r--drivers/staging/line6/pod.h203
-rw-r--r--drivers/staging/line6/revision.h4
-rw-r--r--drivers/staging/line6/toneport.c219
-rw-r--r--drivers/staging/line6/toneport.h44
-rw-r--r--drivers/staging/line6/usbdefs.h75
-rw-r--r--drivers/staging/line6/variax.c501
-rw-r--r--drivers/staging/line6/variax.h107
29 files changed, 6962 insertions, 0 deletions
diff --git a/drivers/staging/line6/Kconfig b/drivers/staging/line6/Kconfig
new file mode 100644
index 000000000000..3c1ffcb8cb12
--- /dev/null
+++ b/drivers/staging/line6/Kconfig
@@ -0,0 +1,20 @@
1config LINE6_USB
2 tristate "Line6 USB support"
3 depends on USB
4 help
5 This is a driver for the guitar amp, cab, and effects modeller
6 PODxt Pro by Line6 (and similar devices), supporting the
7 following features:
8 * Reading/writing individual parameters
9 * Reading/writing complete channel, effects setup, and amp
10 setup data
11 * Channel switching
12 * Virtual MIDI interface
13 * Tuner access
14 * Playback/capture/mixer device for any ALSA-compatible PCM
15 audio application
16 * Signal routing (record clean/processed guitar signal,
17 re-amping)
18
19 Preliminary support for the Variax Workbench is included.
20
diff --git a/drivers/staging/line6/Makefile b/drivers/staging/line6/Makefile
new file mode 100644
index 000000000000..a1c93edc6b1d
--- /dev/null
+++ b/drivers/staging/line6/Makefile
@@ -0,0 +1,15 @@
1obj-$(CONFIG_LINE6_USB) += line6usb.o
2
3line6usb-objs := \
4 audio.o \
5 capture.o \
6 control.o \
7 driver.o \
8 dumprequest.o \
9 midi.o \
10 midibuf.o \
11 pcm.o \
12 playback.o \
13 pod.o \
14 toneport.o \
15 variax.o
diff --git a/drivers/staging/line6/audio.c b/drivers/staging/line6/audio.c
new file mode 100644
index 000000000000..e15fa1f6ee48
--- /dev/null
+++ b/drivers/staging/line6/audio.c
@@ -0,0 +1,69 @@
1/*
2 * Line6 Linux USB driver - 0.8.0
3 *
4 * Copyright (C) 2004-2009 Markus Grabner (grabner@icg.tugraz.at)
5 *
6 * This program is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU General Public License as
8 * published by the Free Software Foundation, version 2.
9 *
10 */
11
12#include "driver.h"
13
14#include <sound/core.h>
15#include <sound/initval.h>
16
17
18static int line6_index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX;
19static char *line6_id[SNDRV_CARDS] = SNDRV_DEFAULT_STR;
20
21
22/*
23 Initialize the Line6 USB audio system.
24*/
25int line6_init_audio(struct usb_line6 *line6)
26{
27 static int dev = 0;
28 struct snd_card *card;
29
30 card = snd_card_new(line6_index[dev], line6_id[dev], THIS_MODULE, 0);
31
32 if(card == NULL)
33 return -ENOMEM;
34
35 line6->card = card;
36
37 strcpy(card->driver, DRIVER_NAME);
38 strcpy(card->shortname, "Line6-USB");
39 sprintf(card->longname, "Line6 %s at USB %s", line6->properties->name, line6->ifcdev->bus_id); /* 80 chars - see asound.h */
40 return 0;
41}
42
43/*
44 Register the Line6 USB audio system.
45*/
46int line6_register_audio(struct usb_line6 *line6)
47{
48 int err;
49
50 if((err = snd_card_register(line6->card)) < 0)
51 return err;
52
53 return 0;
54}
55
56/*
57 Cleanup the Line6 USB audio system.
58*/
59void line6_cleanup_audio(struct usb_line6 *line6)
60{
61 struct snd_card *card = line6->card;
62
63 if(card == 0)
64 return;
65
66 snd_card_disconnect(card);
67 snd_card_free(card);
68 line6->card = 0;
69}
diff --git a/drivers/staging/line6/audio.h b/drivers/staging/line6/audio.h
new file mode 100644
index 000000000000..cc0245adbcd9
--- /dev/null
+++ b/drivers/staging/line6/audio.h
@@ -0,0 +1,24 @@
1/*
2 * Line6 Linux USB driver - 0.8.0
3 *
4 * Copyright (C) 2004-2009 Markus Grabner (grabner@icg.tugraz.at)
5 *
6 * This program is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU General Public License as
8 * published by the Free Software Foundation, version 2.
9 *
10 */
11
12#ifndef AUDIO_H
13#define AUDIO_H
14
15
16#include "driver.h"
17
18
19extern void line6_cleanup_audio(struct usb_line6 *);
20extern int line6_init_audio(struct usb_line6 *);
21extern int line6_register_audio(struct usb_line6 *);
22
23
24#endif
diff --git a/drivers/staging/line6/capture.c b/drivers/staging/line6/capture.c
new file mode 100644
index 000000000000..5dec3bfff04d
--- /dev/null
+++ b/drivers/staging/line6/capture.c
@@ -0,0 +1,370 @@
1/*
2 * Line6 Linux USB driver - 0.8.0
3 *
4 * Copyright (C) 2004-2009 Markus Grabner (grabner@icg.tugraz.at)
5 *
6 * This program is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU General Public License as
8 * published by the Free Software Foundation, version 2.
9 *
10 */
11
12#include "driver.h"
13
14#include <sound/core.h>
15#include <sound/pcm.h>
16#include <sound/pcm_params.h>
17
18#include "audio.h"
19#include "pcm.h"
20#include "pod.h"
21
22
23/*
24 Find a free URB and submit it.
25*/
26static int submit_audio_in_urb(struct snd_pcm_substream *substream)
27{
28 int index;
29 unsigned long flags;
30 struct snd_line6_pcm *line6pcm = snd_pcm_substream_chip(substream);
31 int i, urb_size;
32 struct urb *urb_in;
33
34 spin_lock_irqsave(&line6pcm->lock_audio_in, flags);
35 index = find_first_zero_bit(&line6pcm->active_urb_in, LINE6_ISO_BUFFERS);
36
37 if(index < 0 || index >= LINE6_ISO_BUFFERS) {
38 spin_unlock_irqrestore(&line6pcm->lock_audio_in, flags);
39 dev_err(s2m(substream), "no free URB found\n");
40 return -EINVAL;
41 }
42
43 urb_in = line6pcm->urb_audio_in[index];
44 urb_size = 0;
45
46 for(i = 0; i < LINE6_ISO_PACKETS; ++i) {
47 struct usb_iso_packet_descriptor *fin = &urb_in->iso_frame_desc[i];
48 fin->offset = urb_size;
49 fin->length = line6pcm->max_packet_size;
50 urb_size += line6pcm->max_packet_size;
51 }
52
53 urb_in->transfer_buffer = line6pcm->buffer_in + index * LINE6_ISO_PACKETS * line6pcm->max_packet_size;
54 urb_in->transfer_buffer_length = urb_size;
55 urb_in->context = substream;
56
57 if(usb_submit_urb(urb_in, GFP_ATOMIC) == 0)
58 set_bit(index, &line6pcm->active_urb_in);
59 else
60 dev_err(s2m(substream), "URB in #%d submission failed\n", index);
61
62 spin_unlock_irqrestore(&line6pcm->lock_audio_in, flags);
63 return 0;
64}
65
66/*
67 Submit all currently available capture URBs.
68*/
69static int submit_audio_in_all_urbs(struct snd_pcm_substream *substream)
70{
71 int ret, i;
72
73 for(i = 0; i < LINE6_ISO_BUFFERS; ++i)
74 if((ret = submit_audio_in_urb(substream)) < 0)
75 return ret;
76
77 return 0;
78}
79
80/*
81 Unlink all currently active capture URBs.
82*/
83static void unlink_audio_in_urbs(struct snd_line6_pcm *line6pcm)
84{
85 unsigned int i;
86
87 for(i = LINE6_ISO_BUFFERS; i--;) {
88 if(test_bit(i, &line6pcm->active_urb_in)) {
89 if(!test_and_set_bit(i, &line6pcm->unlink_urb_in)) {
90 struct urb *u = line6pcm->urb_audio_in[i];
91#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 14)
92 u->transfer_flags |= URB_ASYNC_UNLINK;
93#endif
94 usb_unlink_urb(u);
95 }
96 }
97 }
98}
99
100/*
101 Wait until unlinking of all currently active capture URBs has been finished.
102*/
103static void wait_clear_audio_in_urbs(struct snd_line6_pcm *line6pcm)
104{
105 int timeout = HZ;
106 unsigned int i;
107 int alive;
108
109 do {
110 alive = 0;
111 for (i = LINE6_ISO_BUFFERS; i--;) {
112 if (test_bit(i, &line6pcm->active_urb_in))
113 alive++;
114 }
115 if (! alive)
116 break;
117 set_current_state(TASK_UNINTERRUPTIBLE);
118 schedule_timeout(1);
119 } while (--timeout > 0);
120 if (alive)
121 snd_printk(KERN_ERR "timeout: still %d active urbs..\n", alive);
122
123 line6pcm->active_urb_in = 0;
124 line6pcm->unlink_urb_in = 0;
125}
126
127/*
128 Unlink all currently active capture URBs, and wait for finishing.
129*/
130void unlink_wait_clear_audio_in_urbs(struct snd_line6_pcm *line6pcm)
131{
132 unlink_audio_in_urbs(line6pcm);
133 wait_clear_audio_in_urbs(line6pcm);
134}
135
136/*
137 Callback for completed capture URB.
138*/
139static void audio_in_callback(struct urb *urb PT_REGS)
140{
141 int i, index, length = 0, shutdown = 0;
142 int frames;
143 unsigned long flags;
144
145 struct snd_pcm_substream *substream = (struct snd_pcm_substream *)urb->context;
146 struct snd_line6_pcm *line6pcm = snd_pcm_substream_chip(substream);
147 const int bytes_per_frame = line6pcm->properties->bytes_per_frame;
148 struct snd_pcm_runtime *runtime = substream->runtime;
149
150 /* find index of URB */
151 for(index = 0; index < LINE6_ISO_BUFFERS; ++index)
152 if(urb == line6pcm->urb_audio_in[index])
153 break;
154
155#if DO_DUMP_PCM_RECEIVE
156 for(i = 0; i < LINE6_ISO_PACKETS; ++i) {
157 struct usb_iso_packet_descriptor *fout = &urb->iso_frame_desc[i];
158 line6_write_hexdump(line6pcm->line6, 'C', urb->transfer_buffer + fout->offset, fout->length);
159 }
160#endif
161
162 spin_lock_irqsave(&line6pcm->lock_audio_in, flags);
163
164 for(i = 0; i < LINE6_ISO_PACKETS; ++i) {
165 char *fbuf;
166 int fsize;
167 struct usb_iso_packet_descriptor *fin = &urb->iso_frame_desc[i];
168
169 if(fin->status == -18) {
170 shutdown = 1;
171 break;
172 }
173
174 fbuf = urb->transfer_buffer + fin->offset;
175 fsize = fin->actual_length;
176 length += fsize;
177
178 if(fsize > 0) {
179 frames = fsize / bytes_per_frame;
180
181 if(line6pcm->pos_in_done + frames > runtime->buffer_size) {
182 /*
183 The transferred area goes over buffer boundary,
184 copy two separate chunks.
185 */
186 int len;
187 len = runtime->buffer_size - line6pcm->pos_in_done;
188
189 if(len > 0) {
190 memcpy(runtime->dma_area + line6pcm->pos_in_done * bytes_per_frame, fbuf, len * bytes_per_frame);
191 memcpy(runtime->dma_area, fbuf + len * bytes_per_frame, (frames - len) * bytes_per_frame);
192 }
193 else
194 dev_err(s2m(substream), "driver bug: len = %d\n", len); /* this is somewhat paranoid */
195 }
196 else {
197 /* copy single chunk */
198 memcpy(runtime->dma_area + line6pcm->pos_in_done * bytes_per_frame, fbuf, fsize * bytes_per_frame);
199 }
200
201 if((line6pcm->pos_in_done += frames) >= runtime->buffer_size)
202 line6pcm->pos_in_done -= runtime->buffer_size;
203 }
204 }
205
206 clear_bit(index, &line6pcm->active_urb_in);
207
208 if(test_bit(index, &line6pcm->unlink_urb_in))
209 shutdown = 1;
210
211 spin_unlock_irqrestore(&line6pcm->lock_audio_in, flags);
212
213 if(!shutdown) {
214 submit_audio_in_urb(substream);
215
216 if((line6pcm->bytes_in += length) >= line6pcm->period_in) {
217 line6pcm->bytes_in -= line6pcm->period_in;
218 snd_pcm_period_elapsed(substream);
219 }
220 }
221}
222
223/* open capture callback */
224static int snd_line6_capture_open(struct snd_pcm_substream *substream)
225{
226 int err;
227 struct snd_pcm_runtime *runtime = substream->runtime;
228 struct snd_line6_pcm *line6pcm = snd_pcm_substream_chip(substream);
229
230 if((err = snd_pcm_hw_constraint_ratdens(runtime, 0, SNDRV_PCM_HW_PARAM_RATE,
231 (&line6pcm->properties->snd_line6_rates))) < 0)
232 return err;
233
234 runtime->hw = line6pcm->properties->snd_line6_capture_hw;
235 return 0;
236}
237
238/* close capture callback */
239static int snd_line6_capture_close(struct snd_pcm_substream *substream)
240{
241 return 0;
242}
243
244/* hw_params capture callback */
245static int snd_line6_capture_hw_params(struct snd_pcm_substream *substream, struct snd_pcm_hw_params *hw_params)
246{
247 int ret;
248 struct snd_line6_pcm *line6pcm = snd_pcm_substream_chip(substream);
249
250 /* -- Florian Demski [FD] */
251 /* don't ask me why, but this fixes the bug on my machine */
252 if ( line6pcm == NULL ) {
253 if ( substream->pcm == NULL )
254 return -ENOMEM;
255 if ( substream->pcm->private_data == NULL )
256 return -ENOMEM;
257 substream->private_data = substream->pcm->private_data;
258 line6pcm = snd_pcm_substream_chip( substream );
259 }
260 /* -- [FD] end */
261
262 if((ret = snd_pcm_lib_malloc_pages(substream, params_buffer_bytes(hw_params))) < 0)
263 return ret;
264
265 line6pcm->period_in = params_period_bytes(hw_params);
266 line6pcm->buffer_in = kmalloc(LINE6_ISO_BUFFERS * LINE6_ISO_PACKETS * LINE6_ISO_PACKET_SIZE_MAX, GFP_KERNEL);
267
268 if(!line6pcm->buffer_in) {
269 dev_err(s2m(substream), "cannot malloc buffer_in\n");
270 return -ENOMEM;
271 }
272
273 return 0;
274}
275
276/* hw_free capture callback */
277static int snd_line6_capture_hw_free(struct snd_pcm_substream *substream)
278{
279 struct snd_line6_pcm *line6pcm = snd_pcm_substream_chip(substream);
280 unlink_wait_clear_audio_in_urbs(line6pcm);
281
282 if(line6pcm->buffer_in) {
283 kfree(line6pcm->buffer_in);
284 line6pcm->buffer_in = 0;
285 }
286
287 return snd_pcm_lib_free_pages(substream);
288}
289
290/* trigger callback */
291int snd_line6_capture_trigger(struct snd_pcm_substream *substream, int cmd)
292{
293 struct snd_line6_pcm *line6pcm = snd_pcm_substream_chip(substream);
294 int err;
295 line6pcm->count_in = 0;
296
297 switch(cmd) {
298 case SNDRV_PCM_TRIGGER_START:
299 if(!test_and_set_bit(BIT_RUNNING_CAPTURE, &line6pcm->flags)) {
300 err = submit_audio_in_all_urbs(substream);
301
302 if(err < 0) {
303 clear_bit(BIT_RUNNING_CAPTURE, &line6pcm->flags);
304 return err;
305 }
306 }
307
308 break;
309
310 case SNDRV_PCM_TRIGGER_STOP:
311 if(test_and_clear_bit(BIT_RUNNING_CAPTURE, &line6pcm->flags))
312 unlink_audio_in_urbs(line6pcm);
313
314 break;
315
316 default:
317 return -EINVAL;
318 }
319
320 return 0;
321}
322
323/* capture pointer callback */
324static snd_pcm_uframes_t
325snd_line6_capture_pointer(struct snd_pcm_substream *substream)
326{
327 struct snd_line6_pcm *line6pcm = snd_pcm_substream_chip(substream);
328 return line6pcm->pos_in_done;
329}
330
331/* capture operators */
332struct snd_pcm_ops snd_line6_capture_ops = {
333 .open = snd_line6_capture_open,
334 .close = snd_line6_capture_close,
335 .ioctl = snd_pcm_lib_ioctl,
336 .hw_params = snd_line6_capture_hw_params,
337 .hw_free = snd_line6_capture_hw_free,
338 .prepare = snd_line6_prepare,
339 .trigger = snd_line6_trigger,
340 .pointer = snd_line6_capture_pointer,
341};
342
343int create_audio_in_urbs(struct snd_line6_pcm *line6pcm)
344{
345 int i;
346
347 /* create audio URBs and fill in constant values: */
348 for(i = 0; i < LINE6_ISO_BUFFERS; ++i) {
349 struct urb *urb;
350
351 /* URB for audio in: */
352 urb = line6pcm->urb_audio_in[i] = usb_alloc_urb(LINE6_ISO_PACKETS, GFP_KERNEL);
353
354 if(urb == NULL) {
355 dev_err(line6pcm->line6->ifcdev, "Out of memory\n");
356 return -ENOMEM;
357 }
358
359 urb->dev = line6pcm->line6->usbdev;
360 urb->pipe = usb_rcvisocpipe(line6pcm->line6->usbdev, line6pcm->ep_audio_read & USB_ENDPOINT_NUMBER_MASK);
361 urb->transfer_flags = URB_ISO_ASAP;
362 urb->start_frame = -1;
363 urb->number_of_packets = LINE6_ISO_PACKETS;
364 urb->interval = LINE6_ISO_INTERVAL;
365 urb->error_count = 0;
366 urb->complete = audio_in_callback;
367 }
368
369 return 0;
370}
diff --git a/drivers/staging/line6/capture.h b/drivers/staging/line6/capture.h
new file mode 100644
index 000000000000..7b92e4de3927
--- /dev/null
+++ b/drivers/staging/line6/capture.h
@@ -0,0 +1,31 @@
1/*
2 * Line6 Linux USB driver - 0.8.0
3 *
4 * Copyright (C) 2004-2009 Markus Grabner (grabner@icg.tugraz.at)
5 *
6 * This program is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU General Public License as
8 * published by the Free Software Foundation, version 2.
9 *
10 */
11
12#ifndef CAPTURE_H
13#define CAPTURE_H
14
15
16#include "driver.h"
17
18#include <sound/pcm.h>
19
20#include "pcm.h"
21
22
23extern struct snd_pcm_ops snd_line6_capture_ops;
24
25
26extern int create_audio_in_urbs(struct snd_line6_pcm *line6pcm);
27extern int snd_line6_capture_trigger(struct snd_pcm_substream *substream, int cmd);
28extern void unlink_wait_clear_audio_in_urbs(struct snd_line6_pcm *line6pcm);
29
30
31#endif
diff --git a/drivers/staging/line6/config.h b/drivers/staging/line6/config.h
new file mode 100644
index 000000000000..d5ed1a740b0d
--- /dev/null
+++ b/drivers/staging/line6/config.h
@@ -0,0 +1,73 @@
1/*
2 * Line6 Linux USB driver - 0.8.0
3 *
4 * Copyright (C) 2004-2009 Markus Grabner (grabner@icg.tugraz.at)
5 *
6 * This program is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU General Public License as
8 * published by the Free Software Foundation, version 2.
9 *
10 */
11
12#ifndef CONFIG_H
13#define CONFIG_H
14
15
16#include <linux/version.h>
17
18#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 19)
19#include <linux/config.h>
20#endif
21
22#ifdef CONFIG_USB_DEBUG
23#define DEBUG 1
24#endif
25
26
27/**
28 Development tools.
29*/
30#define DO_DEBUG_MESSAGES 0
31#define DO_DUMP_URB_SEND DO_DEBUG_MESSAGES
32#define DO_DUMP_URB_RECEIVE DO_DEBUG_MESSAGES
33#define DO_DUMP_PCM_SEND 0
34#define DO_DUMP_PCM_RECEIVE 0
35#define DO_DUMP_MIDI_SEND DO_DEBUG_MESSAGES
36#define DO_DUMP_MIDI_RECEIVE DO_DEBUG_MESSAGES
37#define DO_DUMP_ANY (DO_DUMP_URB_SEND || DO_DUMP_URB_RECEIVE || \
38 DO_DUMP_PCM_SEND || DO_DUMP_PCM_RECEIVE || \
39 DO_DUMP_MIDI_SEND || DO_DUMP_MIDI_RECEIVE)
40#define CREATE_RAW_FILE 0
41
42#if DO_DEBUG_MESSAGES
43#define CHECKPOINT printk("line6usb: %s (%s:%d)\n", __FUNCTION__, __FILE__, __LINE__)
44#endif
45
46/**
47 In Linux 2.6.13 and later, the device_attribute is passed to the sysfs
48 get/set functions (see /usr/src/linux/include/linux/device.h).
49*/
50#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 13)
51#define DEVICE_ATTRIBUTE struct device_attribute *attr,
52#else
53#define DEVICE_ATTRIBUTE
54#endif
55
56/**
57 In Linux 2.6.20 and later, the pt_regs is no longer passed to USB callback
58 functions.
59*/
60#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 20)
61#define PT_REGS
62#else
63#define PT_REGS , struct pt_regs *regs
64#endif
65
66#if DO_DEBUG_MESSAGES
67#define DEBUG_MESSAGES(x) (x)
68#else
69#define DEBUG_MESSAGES(x)
70#endif
71
72
73#endif
diff --git a/drivers/staging/line6/control.c b/drivers/staging/line6/control.c
new file mode 100644
index 000000000000..d44d06d7b136
--- /dev/null
+++ b/drivers/staging/line6/control.c
@@ -0,0 +1,702 @@
1/*
2 * Line6 Linux USB driver - 0.8.0
3 *
4 * Copyright (C) 2004-2009 Markus Grabner (grabner@icg.tugraz.at)
5 *
6 * This program is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU General Public License as
8 * published by the Free Software Foundation, version 2.
9 *
10 */
11
12#include "driver.h"
13
14#include <linux/usb.h>
15
16#include "control.h"
17#include "pod.h"
18#include "usbdefs.h"
19#include "variax.h"
20
21#define DEVICE_ATTR2(_name1,_name2,_mode,_show,_store) \
22struct device_attribute dev_attr_##_name1 = __ATTR(_name2,_mode,_show,_store)
23
24#define LINE6_PARAM_R(PREFIX, prefix, type, param) \
25static ssize_t prefix ## _get_ ## param(struct device *dev, DEVICE_ATTRIBUTE char *buf) \
26{ \
27 return prefix ## _get_param_ ## type(dev, buf, PREFIX ## _ ## param); \
28}
29
30#define LINE6_PARAM_RW(PREFIX, prefix, type, param) \
31LINE6_PARAM_R(PREFIX, prefix, type, param); \
32static ssize_t prefix ## _set_ ## param(struct device *dev, DEVICE_ATTRIBUTE const char *buf, size_t count) \
33{ \
34 return prefix ## _set_param_ ## type(dev, buf, count, PREFIX ## _ ## param); \
35}
36
37#define POD_PARAM_R(type, param) LINE6_PARAM_R(POD, pod, type, param)
38#define POD_PARAM_RW(type, param) LINE6_PARAM_RW(POD, pod, type, param)
39#define VARIAX_PARAM_R(type, param) LINE6_PARAM_R(VARIAX, variax, type, param)
40#define VARIAX_PARAM_RW(type, param) LINE6_PARAM_RW(VARIAX, variax, type, param)
41
42
43static ssize_t pod_get_param_int(struct device *dev, char *buf, int param)
44{
45 struct usb_interface *interface = to_usb_interface(dev);
46 struct usb_line6_pod *pod = usb_get_intfdata(interface);
47 int retval = line6_wait_dump(&pod->dumpreq, 0);
48 if(retval < 0) return retval;
49 return sprintf(buf, "%d\n", pod->prog_data.control[param]);
50}
51
52static ssize_t pod_set_param_int(struct device *dev, const char *buf, size_t count, int param)
53{
54 struct usb_interface *interface = to_usb_interface(dev);
55 struct usb_line6_pod *pod = usb_get_intfdata(interface);
56 int value = simple_strtoul(buf, NULL, 10);
57 pod_transmit_parameter(pod, param, value);
58 return count;
59}
60
61static ssize_t variax_get_param_int(struct device *dev, char *buf, int param)
62{
63 struct usb_interface *interface = to_usb_interface(dev);
64 struct usb_line6_variax *variax = usb_get_intfdata(interface);
65 int retval = line6_wait_dump(&variax->dumpreq, 0);
66 if(retval < 0) return retval;
67 return sprintf(buf, "%d\n", variax->model_data.control[param]);
68}
69
70static ssize_t variax_get_param_float(struct device *dev, char *buf, int param)
71{
72 /*
73 We do our own floating point handling here since floats in the kernel are
74 problematic for at least two reasons:
75 - many distros are still shipped with binary kernels optimized for the
76 ancient 80386 without FPU
77 - there isn't a printf("%f")
78 (see http://www.kernelthread.com/publications/faq/335.html)
79 */
80
81 static const int BIAS = 0x7f;
82 static const int OFFSET = 0xf;
83 static const int PRECISION = 1000;
84
85 int len = 0;
86 unsigned part_int, part_frac;
87 struct usb_interface *interface = to_usb_interface(dev);
88 struct usb_line6_variax *variax = usb_get_intfdata(interface);
89 const unsigned char *p = variax->model_data.control + param;
90 int retval = line6_wait_dump(&variax->dumpreq, 0);
91 if(retval < 0) return retval;
92
93 if((p[0] == 0) && (p[1] == 0) && (p[2] == 0))
94 part_int = part_frac = 0;
95 else {
96 int exponent = (((p[0] & 0x7f) << 1) | (p[1] >> 7)) - BIAS;
97 unsigned mantissa = (p[1] << 8) | p[2] | 0x8000;
98 exponent -= OFFSET;
99
100 if(exponent >= 0) {
101 part_int = mantissa << exponent;
102 part_frac = 0;
103 }
104 else {
105 part_int = mantissa >> -exponent;
106 part_frac = (mantissa << (32 + exponent)) & 0xffffffff;
107 }
108
109 part_frac = (part_frac / ((1UL << 31) / (PRECISION / 2 * 10)) + 5) / 10;
110 }
111
112 len += sprintf(buf + len, "%s%d.%03d\n", ((p[0] & 0x80) ? "-" : ""), part_int, part_frac);
113 return len;
114}
115
116POD_PARAM_RW(int, tweak);
117POD_PARAM_RW(int, wah_position);
118POD_PARAM_RW(int, compression_gain);
119POD_PARAM_RW(int, vol_pedal_position);
120POD_PARAM_RW(int, compression_threshold);
121POD_PARAM_RW(int, pan);
122POD_PARAM_RW(int, amp_model_setup);
123POD_PARAM_RW(int, amp_model);
124POD_PARAM_RW(int, drive);
125POD_PARAM_RW(int, bass);
126POD_PARAM_RW(int, mid);
127POD_PARAM_RW(int, lowmid);
128POD_PARAM_RW(int, treble);
129POD_PARAM_RW(int, highmid);
130POD_PARAM_RW(int, chan_vol);
131POD_PARAM_RW(int, reverb_mix);
132POD_PARAM_RW(int, effect_setup);
133POD_PARAM_RW(int, band_1_frequency);
134POD_PARAM_RW(int, presence);
135POD_PARAM_RW(int, treble__bass);
136POD_PARAM_RW(int, noise_gate_enable);
137POD_PARAM_RW(int, gate_threshold);
138POD_PARAM_RW(int, gate_decay_time);
139POD_PARAM_RW(int, stomp_enable);
140POD_PARAM_RW(int, comp_enable);
141POD_PARAM_RW(int, stomp_time);
142POD_PARAM_RW(int, delay_enable);
143POD_PARAM_RW(int, mod_param_1);
144POD_PARAM_RW(int, delay_param_1);
145POD_PARAM_RW(int, delay_param_1_note_value);
146POD_PARAM_RW(int, band_2_frequency__bass);
147POD_PARAM_RW(int, delay_param_2);
148POD_PARAM_RW(int, delay_volume_mix);
149POD_PARAM_RW(int, delay_param_3);
150POD_PARAM_RW(int, reverb_enable);
151POD_PARAM_RW(int, reverb_type);
152POD_PARAM_RW(int, reverb_decay);
153POD_PARAM_RW(int, reverb_tone);
154POD_PARAM_RW(int, reverb_pre_delay);
155POD_PARAM_RW(int, reverb_pre_post);
156POD_PARAM_RW(int, band_2_frequency);
157POD_PARAM_RW(int, band_3_frequency__bass);
158POD_PARAM_RW(int, wah_enable);
159POD_PARAM_RW(int, modulation_lo_cut);
160POD_PARAM_RW(int, delay_reverb_lo_cut);
161POD_PARAM_RW(int, volume_pedal_minimum);
162POD_PARAM_RW(int, eq_pre_post);
163POD_PARAM_RW(int, volume_pre_post);
164POD_PARAM_RW(int, di_model);
165POD_PARAM_RW(int, di_delay);
166POD_PARAM_RW(int, mod_enable);
167POD_PARAM_RW(int, mod_param_1_note_value);
168POD_PARAM_RW(int, mod_param_2);
169POD_PARAM_RW(int, mod_param_3);
170POD_PARAM_RW(int, mod_param_4);
171POD_PARAM_RW(int, mod_param_5);
172POD_PARAM_RW(int, mod_volume_mix);
173POD_PARAM_RW(int, mod_pre_post);
174POD_PARAM_RW(int, modulation_model);
175POD_PARAM_RW(int, band_3_frequency);
176POD_PARAM_RW(int, band_4_frequency__bass);
177POD_PARAM_RW(int, mod_param_1_double_precision);
178POD_PARAM_RW(int, delay_param_1_double_precision);
179POD_PARAM_RW(int, eq_enable);
180POD_PARAM_RW(int, tap);
181POD_PARAM_RW(int, volume_tweak_pedal_assign);
182POD_PARAM_RW(int, band_5_frequency);
183POD_PARAM_RW(int, tuner);
184POD_PARAM_RW(int, mic_selection);
185POD_PARAM_RW(int, cabinet_model);
186POD_PARAM_RW(int, stomp_model);
187POD_PARAM_RW(int, roomlevel);
188POD_PARAM_RW(int, band_4_frequency);
189POD_PARAM_RW(int, band_6_frequency);
190POD_PARAM_RW(int, stomp_param_1_note_value);
191POD_PARAM_RW(int, stomp_param_2);
192POD_PARAM_RW(int, stomp_param_3);
193POD_PARAM_RW(int, stomp_param_4);
194POD_PARAM_RW(int, stomp_param_5);
195POD_PARAM_RW(int, stomp_param_6);
196POD_PARAM_RW(int, amp_switch_select);
197POD_PARAM_RW(int, delay_param_4);
198POD_PARAM_RW(int, delay_param_5);
199POD_PARAM_RW(int, delay_pre_post);
200POD_PARAM_RW(int, delay_model);
201POD_PARAM_RW(int, delay_verb_model);
202POD_PARAM_RW(int, tempo_msb);
203POD_PARAM_RW(int, tempo_lsb);
204POD_PARAM_RW(int, wah_model);
205POD_PARAM_RW(int, bypass_volume);
206POD_PARAM_RW(int, fx_loop_on_off);
207POD_PARAM_RW(int, tweak_param_select);
208POD_PARAM_RW(int, amp1_engage);
209POD_PARAM_RW(int, band_1_gain);
210POD_PARAM_RW(int, band_2_gain__bass);
211POD_PARAM_RW(int, band_2_gain);
212POD_PARAM_RW(int, band_3_gain__bass);
213POD_PARAM_RW(int, band_3_gain);
214POD_PARAM_RW(int, band_4_gain__bass);
215POD_PARAM_RW(int, band_5_gain__bass);
216POD_PARAM_RW(int, band_4_gain);
217POD_PARAM_RW(int, band_6_gain__bass);
218VARIAX_PARAM_R(int, body);
219VARIAX_PARAM_R(int, pickup1_enable);
220VARIAX_PARAM_R(int, pickup1_type);
221VARIAX_PARAM_R(float, pickup1_position);
222VARIAX_PARAM_R(float, pickup1_angle);
223VARIAX_PARAM_R(float, pickup1_level);
224VARIAX_PARAM_R(int, pickup2_enable);
225VARIAX_PARAM_R(int, pickup2_type);
226VARIAX_PARAM_R(float, pickup2_position);
227VARIAX_PARAM_R(float, pickup2_angle);
228VARIAX_PARAM_R(float, pickup2_level);
229VARIAX_PARAM_R(int, pickup_phase);
230VARIAX_PARAM_R(float, capacitance);
231VARIAX_PARAM_R(float, tone_resistance);
232VARIAX_PARAM_R(float, volume_resistance);
233VARIAX_PARAM_R(int, taper);
234VARIAX_PARAM_R(float, tone_dump);
235VARIAX_PARAM_R(int, save_tone);
236VARIAX_PARAM_R(float, volume_dump);
237VARIAX_PARAM_R(int, tuning_enable);
238VARIAX_PARAM_R(int, tuning6);
239VARIAX_PARAM_R(int, tuning5);
240VARIAX_PARAM_R(int, tuning4);
241VARIAX_PARAM_R(int, tuning3);
242VARIAX_PARAM_R(int, tuning2);
243VARIAX_PARAM_R(int, tuning1);
244VARIAX_PARAM_R(float, detune6);
245VARIAX_PARAM_R(float, detune5);
246VARIAX_PARAM_R(float, detune4);
247VARIAX_PARAM_R(float, detune3);
248VARIAX_PARAM_R(float, detune2);
249VARIAX_PARAM_R(float, detune1);
250VARIAX_PARAM_R(float, mix6);
251VARIAX_PARAM_R(float, mix5);
252VARIAX_PARAM_R(float, mix4);
253VARIAX_PARAM_R(float, mix3);
254VARIAX_PARAM_R(float, mix2);
255VARIAX_PARAM_R(float, mix1);
256VARIAX_PARAM_R(int, pickup_wiring);
257
258static DEVICE_ATTR(tweak, S_IWUGO | S_IRUGO, pod_get_tweak, pod_set_tweak);
259static DEVICE_ATTR(wah_position, S_IWUGO | S_IRUGO, pod_get_wah_position, pod_set_wah_position);
260static DEVICE_ATTR(compression_gain, S_IWUGO | S_IRUGO, pod_get_compression_gain, pod_set_compression_gain);
261static DEVICE_ATTR(vol_pedal_position, S_IWUGO | S_IRUGO, pod_get_vol_pedal_position, pod_set_vol_pedal_position);
262static DEVICE_ATTR(compression_threshold, S_IWUGO | S_IRUGO, pod_get_compression_threshold, pod_set_compression_threshold);
263static DEVICE_ATTR(pan, S_IWUGO | S_IRUGO, pod_get_pan, pod_set_pan);
264static DEVICE_ATTR(amp_model_setup, S_IWUGO | S_IRUGO, pod_get_amp_model_setup, pod_set_amp_model_setup);
265static DEVICE_ATTR(amp_model, S_IWUGO | S_IRUGO, pod_get_amp_model, pod_set_amp_model);
266static DEVICE_ATTR(drive, S_IWUGO | S_IRUGO, pod_get_drive, pod_set_drive);
267static DEVICE_ATTR(bass, S_IWUGO | S_IRUGO, pod_get_bass, pod_set_bass);
268static DEVICE_ATTR(mid, S_IWUGO | S_IRUGO, pod_get_mid, pod_set_mid);
269static DEVICE_ATTR(lowmid, S_IWUGO | S_IRUGO, pod_get_lowmid, pod_set_lowmid);
270static DEVICE_ATTR(treble, S_IWUGO | S_IRUGO, pod_get_treble, pod_set_treble);
271static DEVICE_ATTR(highmid, S_IWUGO | S_IRUGO, pod_get_highmid, pod_set_highmid);
272static DEVICE_ATTR(chan_vol, S_IWUGO | S_IRUGO, pod_get_chan_vol, pod_set_chan_vol);
273static DEVICE_ATTR(reverb_mix, S_IWUGO | S_IRUGO, pod_get_reverb_mix, pod_set_reverb_mix);
274static DEVICE_ATTR(effect_setup, S_IWUGO | S_IRUGO, pod_get_effect_setup, pod_set_effect_setup);
275static DEVICE_ATTR(band_1_frequency, S_IWUGO | S_IRUGO, pod_get_band_1_frequency, pod_set_band_1_frequency);
276static DEVICE_ATTR(presence, S_IWUGO | S_IRUGO, pod_get_presence, pod_set_presence);
277static DEVICE_ATTR2(treble__bass, treble, S_IWUGO | S_IRUGO, pod_get_treble__bass, pod_set_treble__bass);
278static DEVICE_ATTR(noise_gate_enable, S_IWUGO | S_IRUGO, pod_get_noise_gate_enable, pod_set_noise_gate_enable);
279static DEVICE_ATTR(gate_threshold, S_IWUGO | S_IRUGO, pod_get_gate_threshold, pod_set_gate_threshold);
280static DEVICE_ATTR(gate_decay_time, S_IWUGO | S_IRUGO, pod_get_gate_decay_time, pod_set_gate_decay_time);
281static DEVICE_ATTR(stomp_enable, S_IWUGO | S_IRUGO, pod_get_stomp_enable, pod_set_stomp_enable);
282static DEVICE_ATTR(comp_enable, S_IWUGO | S_IRUGO, pod_get_comp_enable, pod_set_comp_enable);
283static DEVICE_ATTR(stomp_time, S_IWUGO | S_IRUGO, pod_get_stomp_time, pod_set_stomp_time);
284static DEVICE_ATTR(delay_enable, S_IWUGO | S_IRUGO, pod_get_delay_enable, pod_set_delay_enable);
285static DEVICE_ATTR(mod_param_1, S_IWUGO | S_IRUGO, pod_get_mod_param_1, pod_set_mod_param_1);
286static DEVICE_ATTR(delay_param_1, S_IWUGO | S_IRUGO, pod_get_delay_param_1, pod_set_delay_param_1);
287static DEVICE_ATTR(delay_param_1_note_value, S_IWUGO | S_IRUGO, pod_get_delay_param_1_note_value, pod_set_delay_param_1_note_value);
288static DEVICE_ATTR2(band_2_frequency__bass, band_2_frequency, S_IWUGO | S_IRUGO, pod_get_band_2_frequency__bass, pod_set_band_2_frequency__bass);
289static DEVICE_ATTR(delay_param_2, S_IWUGO | S_IRUGO, pod_get_delay_param_2, pod_set_delay_param_2);
290static DEVICE_ATTR(delay_volume_mix, S_IWUGO | S_IRUGO, pod_get_delay_volume_mix, pod_set_delay_volume_mix);
291static DEVICE_ATTR(delay_param_3, S_IWUGO | S_IRUGO, pod_get_delay_param_3, pod_set_delay_param_3);
292static DEVICE_ATTR(reverb_enable, S_IWUGO | S_IRUGO, pod_get_reverb_enable, pod_set_reverb_enable);
293static DEVICE_ATTR(reverb_type, S_IWUGO | S_IRUGO, pod_get_reverb_type, pod_set_reverb_type);
294static DEVICE_ATTR(reverb_decay, S_IWUGO | S_IRUGO, pod_get_reverb_decay, pod_set_reverb_decay);
295static DEVICE_ATTR(reverb_tone, S_IWUGO | S_IRUGO, pod_get_reverb_tone, pod_set_reverb_tone);
296static DEVICE_ATTR(reverb_pre_delay, S_IWUGO | S_IRUGO, pod_get_reverb_pre_delay, pod_set_reverb_pre_delay);
297static DEVICE_ATTR(reverb_pre_post, S_IWUGO | S_IRUGO, pod_get_reverb_pre_post, pod_set_reverb_pre_post);
298static DEVICE_ATTR(band_2_frequency, S_IWUGO | S_IRUGO, pod_get_band_2_frequency, pod_set_band_2_frequency);
299static DEVICE_ATTR2(band_3_frequency__bass, band_3_frequency, S_IWUGO | S_IRUGO, pod_get_band_3_frequency__bass, pod_set_band_3_frequency__bass);
300static DEVICE_ATTR(wah_enable, S_IWUGO | S_IRUGO, pod_get_wah_enable, pod_set_wah_enable);
301static DEVICE_ATTR(modulation_lo_cut, S_IWUGO | S_IRUGO, pod_get_modulation_lo_cut, pod_set_modulation_lo_cut);
302static DEVICE_ATTR(delay_reverb_lo_cut, S_IWUGO | S_IRUGO, pod_get_delay_reverb_lo_cut, pod_set_delay_reverb_lo_cut);
303static DEVICE_ATTR(volume_pedal_minimum, S_IWUGO | S_IRUGO, pod_get_volume_pedal_minimum, pod_set_volume_pedal_minimum);
304static DEVICE_ATTR(eq_pre_post, S_IWUGO | S_IRUGO, pod_get_eq_pre_post, pod_set_eq_pre_post);
305static DEVICE_ATTR(volume_pre_post, S_IWUGO | S_IRUGO, pod_get_volume_pre_post, pod_set_volume_pre_post);
306static DEVICE_ATTR(di_model, S_IWUGO | S_IRUGO, pod_get_di_model, pod_set_di_model);
307static DEVICE_ATTR(di_delay, S_IWUGO | S_IRUGO, pod_get_di_delay, pod_set_di_delay);
308static DEVICE_ATTR(mod_enable, S_IWUGO | S_IRUGO, pod_get_mod_enable, pod_set_mod_enable);
309static DEVICE_ATTR(mod_param_1_note_value, S_IWUGO | S_IRUGO, pod_get_mod_param_1_note_value, pod_set_mod_param_1_note_value);
310static DEVICE_ATTR(mod_param_2, S_IWUGO | S_IRUGO, pod_get_mod_param_2, pod_set_mod_param_2);
311static DEVICE_ATTR(mod_param_3, S_IWUGO | S_IRUGO, pod_get_mod_param_3, pod_set_mod_param_3);
312static DEVICE_ATTR(mod_param_4, S_IWUGO | S_IRUGO, pod_get_mod_param_4, pod_set_mod_param_4);
313static DEVICE_ATTR(mod_param_5, S_IWUGO | S_IRUGO, pod_get_mod_param_5, pod_set_mod_param_5);
314static DEVICE_ATTR(mod_volume_mix, S_IWUGO | S_IRUGO, pod_get_mod_volume_mix, pod_set_mod_volume_mix);
315static DEVICE_ATTR(mod_pre_post, S_IWUGO | S_IRUGO, pod_get_mod_pre_post, pod_set_mod_pre_post);
316static DEVICE_ATTR(modulation_model, S_IWUGO | S_IRUGO, pod_get_modulation_model, pod_set_modulation_model);
317static DEVICE_ATTR(band_3_frequency, S_IWUGO | S_IRUGO, pod_get_band_3_frequency, pod_set_band_3_frequency);
318static DEVICE_ATTR2(band_4_frequency__bass, band_4_frequency, S_IWUGO | S_IRUGO, pod_get_band_4_frequency__bass, pod_set_band_4_frequency__bass);
319static DEVICE_ATTR(mod_param_1_double_precision, S_IWUGO | S_IRUGO, pod_get_mod_param_1_double_precision, pod_set_mod_param_1_double_precision);
320static DEVICE_ATTR(delay_param_1_double_precision, S_IWUGO | S_IRUGO, pod_get_delay_param_1_double_precision, pod_set_delay_param_1_double_precision);
321static DEVICE_ATTR(eq_enable, S_IWUGO | S_IRUGO, pod_get_eq_enable, pod_set_eq_enable);
322static DEVICE_ATTR(tap, S_IWUGO | S_IRUGO, pod_get_tap, pod_set_tap);
323static DEVICE_ATTR(volume_tweak_pedal_assign, S_IWUGO | S_IRUGO, pod_get_volume_tweak_pedal_assign, pod_set_volume_tweak_pedal_assign);
324static DEVICE_ATTR(band_5_frequency, S_IWUGO | S_IRUGO, pod_get_band_5_frequency, pod_set_band_5_frequency);
325static DEVICE_ATTR(tuner, S_IWUGO | S_IRUGO, pod_get_tuner, pod_set_tuner);
326static DEVICE_ATTR(mic_selection, S_IWUGO | S_IRUGO, pod_get_mic_selection, pod_set_mic_selection);
327static DEVICE_ATTR(cabinet_model, S_IWUGO | S_IRUGO, pod_get_cabinet_model, pod_set_cabinet_model);
328static DEVICE_ATTR(stomp_model, S_IWUGO | S_IRUGO, pod_get_stomp_model, pod_set_stomp_model);
329static DEVICE_ATTR(roomlevel, S_IWUGO | S_IRUGO, pod_get_roomlevel, pod_set_roomlevel);
330static DEVICE_ATTR(band_4_frequency, S_IWUGO | S_IRUGO, pod_get_band_4_frequency, pod_set_band_4_frequency);
331static DEVICE_ATTR(band_6_frequency, S_IWUGO | S_IRUGO, pod_get_band_6_frequency, pod_set_band_6_frequency);
332static DEVICE_ATTR(stomp_param_1_note_value, S_IWUGO | S_IRUGO, pod_get_stomp_param_1_note_value, pod_set_stomp_param_1_note_value);
333static DEVICE_ATTR(stomp_param_2, S_IWUGO | S_IRUGO, pod_get_stomp_param_2, pod_set_stomp_param_2);
334static DEVICE_ATTR(stomp_param_3, S_IWUGO | S_IRUGO, pod_get_stomp_param_3, pod_set_stomp_param_3);
335static DEVICE_ATTR(stomp_param_4, S_IWUGO | S_IRUGO, pod_get_stomp_param_4, pod_set_stomp_param_4);
336static DEVICE_ATTR(stomp_param_5, S_IWUGO | S_IRUGO, pod_get_stomp_param_5, pod_set_stomp_param_5);
337static DEVICE_ATTR(stomp_param_6, S_IWUGO | S_IRUGO, pod_get_stomp_param_6, pod_set_stomp_param_6);
338static DEVICE_ATTR(amp_switch_select, S_IWUGO | S_IRUGO, pod_get_amp_switch_select, pod_set_amp_switch_select);
339static DEVICE_ATTR(delay_param_4, S_IWUGO | S_IRUGO, pod_get_delay_param_4, pod_set_delay_param_4);
340static DEVICE_ATTR(delay_param_5, S_IWUGO | S_IRUGO, pod_get_delay_param_5, pod_set_delay_param_5);
341static DEVICE_ATTR(delay_pre_post, S_IWUGO | S_IRUGO, pod_get_delay_pre_post, pod_set_delay_pre_post);
342static DEVICE_ATTR(delay_model, S_IWUGO | S_IRUGO, pod_get_delay_model, pod_set_delay_model);
343static DEVICE_ATTR(delay_verb_model, S_IWUGO | S_IRUGO, pod_get_delay_verb_model, pod_set_delay_verb_model);
344static DEVICE_ATTR(tempo_msb, S_IWUGO | S_IRUGO, pod_get_tempo_msb, pod_set_tempo_msb);
345static DEVICE_ATTR(tempo_lsb, S_IWUGO | S_IRUGO, pod_get_tempo_lsb, pod_set_tempo_lsb);
346static DEVICE_ATTR(wah_model, S_IWUGO | S_IRUGO, pod_get_wah_model, pod_set_wah_model);
347static DEVICE_ATTR(bypass_volume, S_IWUGO | S_IRUGO, pod_get_bypass_volume, pod_set_bypass_volume);
348static DEVICE_ATTR(fx_loop_on_off, S_IWUGO | S_IRUGO, pod_get_fx_loop_on_off, pod_set_fx_loop_on_off);
349static DEVICE_ATTR(tweak_param_select, S_IWUGO | S_IRUGO, pod_get_tweak_param_select, pod_set_tweak_param_select);
350static DEVICE_ATTR(amp1_engage, S_IWUGO | S_IRUGO, pod_get_amp1_engage, pod_set_amp1_engage);
351static DEVICE_ATTR(band_1_gain, S_IWUGO | S_IRUGO, pod_get_band_1_gain, pod_set_band_1_gain);
352static DEVICE_ATTR2(band_2_gain__bass, band_2_gain, S_IWUGO | S_IRUGO, pod_get_band_2_gain__bass, pod_set_band_2_gain__bass);
353static DEVICE_ATTR(band_2_gain, S_IWUGO | S_IRUGO, pod_get_band_2_gain, pod_set_band_2_gain);
354static DEVICE_ATTR2(band_3_gain__bass, band_3_gain, S_IWUGO | S_IRUGO, pod_get_band_3_gain__bass, pod_set_band_3_gain__bass);
355static DEVICE_ATTR(band_3_gain, S_IWUGO | S_IRUGO, pod_get_band_3_gain, pod_set_band_3_gain);
356static DEVICE_ATTR2(band_4_gain__bass, band_4_gain, S_IWUGO | S_IRUGO, pod_get_band_4_gain__bass, pod_set_band_4_gain__bass);
357static DEVICE_ATTR2(band_5_gain__bass, band_5_gain, S_IWUGO | S_IRUGO, pod_get_band_5_gain__bass, pod_set_band_5_gain__bass);
358static DEVICE_ATTR(band_4_gain, S_IWUGO | S_IRUGO, pod_get_band_4_gain, pod_set_band_4_gain);
359static DEVICE_ATTR2(band_6_gain__bass, band_6_gain, S_IWUGO | S_IRUGO, pod_get_band_6_gain__bass, pod_set_band_6_gain__bass);
360static DEVICE_ATTR(body, S_IRUGO, variax_get_body, line6_nop_write);
361static DEVICE_ATTR(pickup1_enable, S_IRUGO, variax_get_pickup1_enable, line6_nop_write);
362static DEVICE_ATTR(pickup1_type, S_IRUGO, variax_get_pickup1_type, line6_nop_write);
363static DEVICE_ATTR(pickup1_position, S_IRUGO, variax_get_pickup1_position, line6_nop_write);
364static DEVICE_ATTR(pickup1_angle, S_IRUGO, variax_get_pickup1_angle, line6_nop_write);
365static DEVICE_ATTR(pickup1_level, S_IRUGO, variax_get_pickup1_level, line6_nop_write);
366static DEVICE_ATTR(pickup2_enable, S_IRUGO, variax_get_pickup2_enable, line6_nop_write);
367static DEVICE_ATTR(pickup2_type, S_IRUGO, variax_get_pickup2_type, line6_nop_write);
368static DEVICE_ATTR(pickup2_position, S_IRUGO, variax_get_pickup2_position, line6_nop_write);
369static DEVICE_ATTR(pickup2_angle, S_IRUGO, variax_get_pickup2_angle, line6_nop_write);
370static DEVICE_ATTR(pickup2_level, S_IRUGO, variax_get_pickup2_level, line6_nop_write);
371static DEVICE_ATTR(pickup_phase, S_IRUGO, variax_get_pickup_phase, line6_nop_write);
372static DEVICE_ATTR(capacitance, S_IRUGO, variax_get_capacitance, line6_nop_write);
373static DEVICE_ATTR(tone_resistance, S_IRUGO, variax_get_tone_resistance, line6_nop_write);
374static DEVICE_ATTR(volume_resistance, S_IRUGO, variax_get_volume_resistance, line6_nop_write);
375static DEVICE_ATTR(taper, S_IRUGO, variax_get_taper, line6_nop_write);
376static DEVICE_ATTR(tone_dump, S_IRUGO, variax_get_tone_dump, line6_nop_write);
377static DEVICE_ATTR(save_tone, S_IRUGO, variax_get_save_tone, line6_nop_write);
378static DEVICE_ATTR(volume_dump, S_IRUGO, variax_get_volume_dump, line6_nop_write);
379static DEVICE_ATTR(tuning_enable, S_IRUGO, variax_get_tuning_enable, line6_nop_write);
380static DEVICE_ATTR(tuning6, S_IRUGO, variax_get_tuning6, line6_nop_write);
381static DEVICE_ATTR(tuning5, S_IRUGO, variax_get_tuning5, line6_nop_write);
382static DEVICE_ATTR(tuning4, S_IRUGO, variax_get_tuning4, line6_nop_write);
383static DEVICE_ATTR(tuning3, S_IRUGO, variax_get_tuning3, line6_nop_write);
384static DEVICE_ATTR(tuning2, S_IRUGO, variax_get_tuning2, line6_nop_write);
385static DEVICE_ATTR(tuning1, S_IRUGO, variax_get_tuning1, line6_nop_write);
386static DEVICE_ATTR(detune6, S_IRUGO, variax_get_detune6, line6_nop_write);
387static DEVICE_ATTR(detune5, S_IRUGO, variax_get_detune5, line6_nop_write);
388static DEVICE_ATTR(detune4, S_IRUGO, variax_get_detune4, line6_nop_write);
389static DEVICE_ATTR(detune3, S_IRUGO, variax_get_detune3, line6_nop_write);
390static DEVICE_ATTR(detune2, S_IRUGO, variax_get_detune2, line6_nop_write);
391static DEVICE_ATTR(detune1, S_IRUGO, variax_get_detune1, line6_nop_write);
392static DEVICE_ATTR(mix6, S_IRUGO, variax_get_mix6, line6_nop_write);
393static DEVICE_ATTR(mix5, S_IRUGO, variax_get_mix5, line6_nop_write);
394static DEVICE_ATTR(mix4, S_IRUGO, variax_get_mix4, line6_nop_write);
395static DEVICE_ATTR(mix3, S_IRUGO, variax_get_mix3, line6_nop_write);
396static DEVICE_ATTR(mix2, S_IRUGO, variax_get_mix2, line6_nop_write);
397static DEVICE_ATTR(mix1, S_IRUGO, variax_get_mix1, line6_nop_write);
398static DEVICE_ATTR(pickup_wiring, S_IRUGO, variax_get_pickup_wiring, line6_nop_write);
399
400int pod_create_files(int firmware, int type, struct device *dev) {
401 int err;
402 CHECK_RETURN(device_create_file(dev, &dev_attr_tweak));
403 CHECK_RETURN(device_create_file(dev, &dev_attr_wah_position));
404 if((type & (LINE6_BITS_PODXTALL)) != 0) CHECK_RETURN(device_create_file(dev, &dev_attr_compression_gain));
405 CHECK_RETURN(device_create_file(dev, &dev_attr_vol_pedal_position));
406 CHECK_RETURN(device_create_file(dev, &dev_attr_compression_threshold));
407 CHECK_RETURN(device_create_file(dev, &dev_attr_pan));
408 CHECK_RETURN(device_create_file(dev, &dev_attr_amp_model_setup));
409 if(firmware >= 200) CHECK_RETURN(device_create_file(dev, &dev_attr_amp_model));
410 CHECK_RETURN(device_create_file(dev, &dev_attr_drive));
411 CHECK_RETURN(device_create_file(dev, &dev_attr_bass));
412 if((type & (LINE6_BITS_PODXTALL)) != 0) CHECK_RETURN(device_create_file(dev, &dev_attr_mid));
413 if((type & (LINE6_BITS_BASSPODXTALL)) != 0) CHECK_RETURN(device_create_file(dev, &dev_attr_lowmid));
414 if((type & (LINE6_BITS_PODXTALL)) != 0) CHECK_RETURN(device_create_file(dev, &dev_attr_treble));
415 if((type & (LINE6_BITS_BASSPODXTALL)) != 0) CHECK_RETURN(device_create_file(dev, &dev_attr_highmid));
416 CHECK_RETURN(device_create_file(dev, &dev_attr_chan_vol));
417 if((type & (LINE6_BITS_PODXTALL)) != 0) CHECK_RETURN(device_create_file(dev, &dev_attr_reverb_mix));
418 CHECK_RETURN(device_create_file(dev, &dev_attr_effect_setup));
419 if(firmware >= 200) CHECK_RETURN(device_create_file(dev, &dev_attr_band_1_frequency));
420 if((type & (LINE6_BITS_PODXTALL)) != 0) CHECK_RETURN(device_create_file(dev, &dev_attr_presence));
421 if((type & (LINE6_BITS_BASSPODXTALL)) != 0) CHECK_RETURN(device_create_file(dev, &dev_attr_treble__bass));
422 CHECK_RETURN(device_create_file(dev, &dev_attr_noise_gate_enable));
423 CHECK_RETURN(device_create_file(dev, &dev_attr_gate_threshold));
424 CHECK_RETURN(device_create_file(dev, &dev_attr_gate_decay_time));
425 CHECK_RETURN(device_create_file(dev, &dev_attr_stomp_enable));
426 CHECK_RETURN(device_create_file(dev, &dev_attr_comp_enable));
427 CHECK_RETURN(device_create_file(dev, &dev_attr_stomp_time));
428 CHECK_RETURN(device_create_file(dev, &dev_attr_delay_enable));
429 CHECK_RETURN(device_create_file(dev, &dev_attr_mod_param_1));
430 CHECK_RETURN(device_create_file(dev, &dev_attr_delay_param_1));
431 CHECK_RETURN(device_create_file(dev, &dev_attr_delay_param_1_note_value));
432 if((type & (LINE6_BITS_BASSPODXTALL)) != 0) if(firmware >= 200) CHECK_RETURN(device_create_file(dev, &dev_attr_band_2_frequency__bass));
433 CHECK_RETURN(device_create_file(dev, &dev_attr_delay_param_2));
434 CHECK_RETURN(device_create_file(dev, &dev_attr_delay_volume_mix));
435 CHECK_RETURN(device_create_file(dev, &dev_attr_delay_param_3));
436 if((type & (LINE6_BITS_PODXTALL)) != 0) CHECK_RETURN(device_create_file(dev, &dev_attr_reverb_enable));
437 if((type & (LINE6_BITS_PODXTALL)) != 0) CHECK_RETURN(device_create_file(dev, &dev_attr_reverb_type));
438 if((type & (LINE6_BITS_PODXTALL)) != 0) CHECK_RETURN(device_create_file(dev, &dev_attr_reverb_decay));
439 if((type & (LINE6_BITS_PODXTALL)) != 0) CHECK_RETURN(device_create_file(dev, &dev_attr_reverb_tone));
440 if((type & (LINE6_BITS_PODXTALL)) != 0) CHECK_RETURN(device_create_file(dev, &dev_attr_reverb_pre_delay));
441 if((type & (LINE6_BITS_PODXTALL)) != 0) CHECK_RETURN(device_create_file(dev, &dev_attr_reverb_pre_post));
442 if((type & (LINE6_BITS_PODXTALL)) != 0) if(firmware >= 200) CHECK_RETURN(device_create_file(dev, &dev_attr_band_2_frequency));
443 if((type & (LINE6_BITS_BASSPODXTALL)) != 0) if(firmware >= 200) CHECK_RETURN(device_create_file(dev, &dev_attr_band_3_frequency__bass));
444 CHECK_RETURN(device_create_file(dev, &dev_attr_wah_enable));
445 if((type & (LINE6_BITS_BASSPODXTALL)) != 0) CHECK_RETURN(device_create_file(dev, &dev_attr_modulation_lo_cut));
446 if((type & (LINE6_BITS_BASSPODXTALL)) != 0) CHECK_RETURN(device_create_file(dev, &dev_attr_delay_reverb_lo_cut));
447 if((type & (LINE6_BITS_PODXTALL)) != 0) if(firmware >= 200) CHECK_RETURN(device_create_file(dev, &dev_attr_volume_pedal_minimum));
448 if((type & (LINE6_BITS_BASSPODXTALL)) != 0) if(firmware >= 200) CHECK_RETURN(device_create_file(dev, &dev_attr_eq_pre_post));
449 CHECK_RETURN(device_create_file(dev, &dev_attr_volume_pre_post));
450 if((type & (LINE6_BITS_BASSPODXTALL)) != 0) CHECK_RETURN(device_create_file(dev, &dev_attr_di_model));
451 if((type & (LINE6_BITS_BASSPODXTALL)) != 0) CHECK_RETURN(device_create_file(dev, &dev_attr_di_delay));
452 CHECK_RETURN(device_create_file(dev, &dev_attr_mod_enable));
453 CHECK_RETURN(device_create_file(dev, &dev_attr_mod_param_1_note_value));
454 CHECK_RETURN(device_create_file(dev, &dev_attr_mod_param_2));
455 CHECK_RETURN(device_create_file(dev, &dev_attr_mod_param_3));
456 CHECK_RETURN(device_create_file(dev, &dev_attr_mod_param_4));
457 if((type & (LINE6_BITS_BASSPODXTALL)) != 0) CHECK_RETURN(device_create_file(dev, &dev_attr_mod_param_5));
458 CHECK_RETURN(device_create_file(dev, &dev_attr_mod_volume_mix));
459 CHECK_RETURN(device_create_file(dev, &dev_attr_mod_pre_post));
460 CHECK_RETURN(device_create_file(dev, &dev_attr_modulation_model));
461 if((type & (LINE6_BITS_PODXTALL)) != 0) if(firmware >= 200) CHECK_RETURN(device_create_file(dev, &dev_attr_band_3_frequency));
462 if((type & (LINE6_BITS_BASSPODXTALL)) != 0) if(firmware >= 200) CHECK_RETURN(device_create_file(dev, &dev_attr_band_4_frequency__bass));
463 CHECK_RETURN(device_create_file(dev, &dev_attr_mod_param_1_double_precision));
464 CHECK_RETURN(device_create_file(dev, &dev_attr_delay_param_1_double_precision));
465 if(firmware >= 200) CHECK_RETURN(device_create_file(dev, &dev_attr_eq_enable));
466 CHECK_RETURN(device_create_file(dev, &dev_attr_tap));
467 CHECK_RETURN(device_create_file(dev, &dev_attr_volume_tweak_pedal_assign));
468 if((type & (LINE6_BITS_BASSPODXTALL)) != 0) if(firmware >= 200) CHECK_RETURN(device_create_file(dev, &dev_attr_band_5_frequency));
469 CHECK_RETURN(device_create_file(dev, &dev_attr_tuner));
470 CHECK_RETURN(device_create_file(dev, &dev_attr_mic_selection));
471 CHECK_RETURN(device_create_file(dev, &dev_attr_cabinet_model));
472 CHECK_RETURN(device_create_file(dev, &dev_attr_stomp_model));
473 CHECK_RETURN(device_create_file(dev, &dev_attr_roomlevel));
474 if((type & (LINE6_BITS_PODXTALL)) != 0) if(firmware >= 200) CHECK_RETURN(device_create_file(dev, &dev_attr_band_4_frequency));
475 if((type & (LINE6_BITS_BASSPODXTALL)) != 0) if(firmware >= 200) CHECK_RETURN(device_create_file(dev, &dev_attr_band_6_frequency));
476 CHECK_RETURN(device_create_file(dev, &dev_attr_stomp_param_1_note_value));
477 CHECK_RETURN(device_create_file(dev, &dev_attr_stomp_param_2));
478 CHECK_RETURN(device_create_file(dev, &dev_attr_stomp_param_3));
479 CHECK_RETURN(device_create_file(dev, &dev_attr_stomp_param_4));
480 CHECK_RETURN(device_create_file(dev, &dev_attr_stomp_param_5));
481 CHECK_RETURN(device_create_file(dev, &dev_attr_stomp_param_6));
482 if((type & (LINE6_BITS_LIVE)) != 0) CHECK_RETURN(device_create_file(dev, &dev_attr_amp_switch_select));
483 CHECK_RETURN(device_create_file(dev, &dev_attr_delay_param_4));
484 CHECK_RETURN(device_create_file(dev, &dev_attr_delay_param_5));
485 CHECK_RETURN(device_create_file(dev, &dev_attr_delay_pre_post));
486 if((type & (LINE6_BITS_PODXTALL)) != 0) CHECK_RETURN(device_create_file(dev, &dev_attr_delay_model));
487 if((type & (LINE6_BITS_BASSPODXTALL)) != 0) CHECK_RETURN(device_create_file(dev, &dev_attr_delay_verb_model));
488 CHECK_RETURN(device_create_file(dev, &dev_attr_tempo_msb));
489 CHECK_RETURN(device_create_file(dev, &dev_attr_tempo_lsb));
490 if(firmware >= 300) CHECK_RETURN(device_create_file(dev, &dev_attr_wah_model));
491 if(firmware >= 214) CHECK_RETURN(device_create_file(dev, &dev_attr_bypass_volume));
492 if((type & (LINE6_BITS_PRO)) != 0) CHECK_RETURN(device_create_file(dev, &dev_attr_fx_loop_on_off));
493 CHECK_RETURN(device_create_file(dev, &dev_attr_tweak_param_select));
494 CHECK_RETURN(device_create_file(dev, &dev_attr_amp1_engage));
495 if(firmware >= 200) CHECK_RETURN(device_create_file(dev, &dev_attr_band_1_gain));
496 if((type & (LINE6_BITS_BASSPODXTALL)) != 0) if(firmware >= 200) CHECK_RETURN(device_create_file(dev, &dev_attr_band_2_gain__bass));
497 if((type & (LINE6_BITS_PODXTALL)) != 0) if(firmware >= 200) CHECK_RETURN(device_create_file(dev, &dev_attr_band_2_gain));
498 if((type & (LINE6_BITS_BASSPODXTALL)) != 0) if(firmware >= 200) CHECK_RETURN(device_create_file(dev, &dev_attr_band_3_gain__bass));
499 if((type & (LINE6_BITS_PODXTALL)) != 0) if(firmware >= 200) CHECK_RETURN(device_create_file(dev, &dev_attr_band_3_gain));
500 if((type & (LINE6_BITS_BASSPODXTALL)) != 0) if(firmware >= 200) CHECK_RETURN(device_create_file(dev, &dev_attr_band_4_gain__bass));
501 if((type & (LINE6_BITS_BASSPODXTALL)) != 0) if(firmware >= 200) CHECK_RETURN(device_create_file(dev, &dev_attr_band_5_gain__bass));
502 if((type & (LINE6_BITS_PODXTALL)) != 0) if(firmware >= 200) CHECK_RETURN(device_create_file(dev, &dev_attr_band_4_gain));
503 if((type & (LINE6_BITS_BASSPODXTALL)) != 0) if(firmware >= 200) CHECK_RETURN(device_create_file(dev, &dev_attr_band_6_gain__bass));
504 return 0;
505}
506
507void pod_remove_files(int firmware, int type, struct device *dev) {
508 device_remove_file(dev, &dev_attr_tweak);
509 device_remove_file(dev, &dev_attr_wah_position);
510 if((type & (LINE6_BITS_PODXTALL)) != 0) device_remove_file(dev, &dev_attr_compression_gain);
511 device_remove_file(dev, &dev_attr_vol_pedal_position);
512 device_remove_file(dev, &dev_attr_compression_threshold);
513 device_remove_file(dev, &dev_attr_pan);
514 device_remove_file(dev, &dev_attr_amp_model_setup);
515 if(firmware >= 200) device_remove_file(dev, &dev_attr_amp_model);
516 device_remove_file(dev, &dev_attr_drive);
517 device_remove_file(dev, &dev_attr_bass);
518 if((type & (LINE6_BITS_PODXTALL)) != 0) device_remove_file(dev, &dev_attr_mid);
519 if((type & (LINE6_BITS_BASSPODXTALL)) != 0) device_remove_file(dev, &dev_attr_lowmid);
520 if((type & (LINE6_BITS_PODXTALL)) != 0) device_remove_file(dev, &dev_attr_treble);
521 if((type & (LINE6_BITS_BASSPODXTALL)) != 0) device_remove_file(dev, &dev_attr_highmid);
522 device_remove_file(dev, &dev_attr_chan_vol);
523 if((type & (LINE6_BITS_PODXTALL)) != 0) device_remove_file(dev, &dev_attr_reverb_mix);
524 device_remove_file(dev, &dev_attr_effect_setup);
525 if(firmware >= 200) device_remove_file(dev, &dev_attr_band_1_frequency);
526 if((type & (LINE6_BITS_PODXTALL)) != 0) device_remove_file(dev, &dev_attr_presence);
527 if((type & (LINE6_BITS_BASSPODXTALL)) != 0) device_remove_file(dev, &dev_attr_treble__bass);
528 device_remove_file(dev, &dev_attr_noise_gate_enable);
529 device_remove_file(dev, &dev_attr_gate_threshold);
530 device_remove_file(dev, &dev_attr_gate_decay_time);
531 device_remove_file(dev, &dev_attr_stomp_enable);
532 device_remove_file(dev, &dev_attr_comp_enable);
533 device_remove_file(dev, &dev_attr_stomp_time);
534 device_remove_file(dev, &dev_attr_delay_enable);
535 device_remove_file(dev, &dev_attr_mod_param_1);
536 device_remove_file(dev, &dev_attr_delay_param_1);
537 device_remove_file(dev, &dev_attr_delay_param_1_note_value);
538 if((type & (LINE6_BITS_BASSPODXTALL)) != 0) if(firmware >= 200) device_remove_file(dev, &dev_attr_band_2_frequency__bass);
539 device_remove_file(dev, &dev_attr_delay_param_2);
540 device_remove_file(dev, &dev_attr_delay_volume_mix);
541 device_remove_file(dev, &dev_attr_delay_param_3);
542 if((type & (LINE6_BITS_PODXTALL)) != 0) device_remove_file(dev, &dev_attr_reverb_enable);
543 if((type & (LINE6_BITS_PODXTALL)) != 0) device_remove_file(dev, &dev_attr_reverb_type);
544 if((type & (LINE6_BITS_PODXTALL)) != 0) device_remove_file(dev, &dev_attr_reverb_decay);
545 if((type & (LINE6_BITS_PODXTALL)) != 0) device_remove_file(dev, &dev_attr_reverb_tone);
546 if((type & (LINE6_BITS_PODXTALL)) != 0) device_remove_file(dev, &dev_attr_reverb_pre_delay);
547 if((type & (LINE6_BITS_PODXTALL)) != 0) device_remove_file(dev, &dev_attr_reverb_pre_post);
548 if((type & (LINE6_BITS_PODXTALL)) != 0) if(firmware >= 200) device_remove_file(dev, &dev_attr_band_2_frequency);
549 if((type & (LINE6_BITS_BASSPODXTALL)) != 0) if(firmware >= 200) device_remove_file(dev, &dev_attr_band_3_frequency__bass);
550 device_remove_file(dev, &dev_attr_wah_enable);
551 if((type & (LINE6_BITS_BASSPODXTALL)) != 0) device_remove_file(dev, &dev_attr_modulation_lo_cut);
552 if((type & (LINE6_BITS_BASSPODXTALL)) != 0) device_remove_file(dev, &dev_attr_delay_reverb_lo_cut);
553 if((type & (LINE6_BITS_PODXTALL)) != 0) if(firmware >= 200) device_remove_file(dev, &dev_attr_volume_pedal_minimum);
554 if((type & (LINE6_BITS_BASSPODXTALL)) != 0) if(firmware >= 200) device_remove_file(dev, &dev_attr_eq_pre_post);
555 device_remove_file(dev, &dev_attr_volume_pre_post);
556 if((type & (LINE6_BITS_BASSPODXTALL)) != 0) device_remove_file(dev, &dev_attr_di_model);
557 if((type & (LINE6_BITS_BASSPODXTALL)) != 0) device_remove_file(dev, &dev_attr_di_delay);
558 device_remove_file(dev, &dev_attr_mod_enable);
559 device_remove_file(dev, &dev_attr_mod_param_1_note_value);
560 device_remove_file(dev, &dev_attr_mod_param_2);
561 device_remove_file(dev, &dev_attr_mod_param_3);
562 device_remove_file(dev, &dev_attr_mod_param_4);
563 if((type & (LINE6_BITS_BASSPODXTALL)) != 0) device_remove_file(dev, &dev_attr_mod_param_5);
564 device_remove_file(dev, &dev_attr_mod_volume_mix);
565 device_remove_file(dev, &dev_attr_mod_pre_post);
566 device_remove_file(dev, &dev_attr_modulation_model);
567 if((type & (LINE6_BITS_PODXTALL)) != 0) if(firmware >= 200) device_remove_file(dev, &dev_attr_band_3_frequency);
568 if((type & (LINE6_BITS_BASSPODXTALL)) != 0) if(firmware >= 200) device_remove_file(dev, &dev_attr_band_4_frequency__bass);
569 device_remove_file(dev, &dev_attr_mod_param_1_double_precision);
570 device_remove_file(dev, &dev_attr_delay_param_1_double_precision);
571 if(firmware >= 200) device_remove_file(dev, &dev_attr_eq_enable);
572 device_remove_file(dev, &dev_attr_tap);
573 device_remove_file(dev, &dev_attr_volume_tweak_pedal_assign);
574 if((type & (LINE6_BITS_BASSPODXTALL)) != 0) if(firmware >= 200) device_remove_file(dev, &dev_attr_band_5_frequency);
575 device_remove_file(dev, &dev_attr_tuner);
576 device_remove_file(dev, &dev_attr_mic_selection);
577 device_remove_file(dev, &dev_attr_cabinet_model);
578 device_remove_file(dev, &dev_attr_stomp_model);
579 device_remove_file(dev, &dev_attr_roomlevel);
580 if((type & (LINE6_BITS_PODXTALL)) != 0) if(firmware >= 200) device_remove_file(dev, &dev_attr_band_4_frequency);
581 if((type & (LINE6_BITS_BASSPODXTALL)) != 0) if(firmware >= 200) device_remove_file(dev, &dev_attr_band_6_frequency);
582 device_remove_file(dev, &dev_attr_stomp_param_1_note_value);
583 device_remove_file(dev, &dev_attr_stomp_param_2);
584 device_remove_file(dev, &dev_attr_stomp_param_3);
585 device_remove_file(dev, &dev_attr_stomp_param_4);
586 device_remove_file(dev, &dev_attr_stomp_param_5);
587 device_remove_file(dev, &dev_attr_stomp_param_6);
588 if((type & (LINE6_BITS_LIVE)) != 0) device_remove_file(dev, &dev_attr_amp_switch_select);
589 device_remove_file(dev, &dev_attr_delay_param_4);
590 device_remove_file(dev, &dev_attr_delay_param_5);
591 device_remove_file(dev, &dev_attr_delay_pre_post);
592 if((type & (LINE6_BITS_PODXTALL)) != 0) device_remove_file(dev, &dev_attr_delay_model);
593 if((type & (LINE6_BITS_BASSPODXTALL)) != 0) device_remove_file(dev, &dev_attr_delay_verb_model);
594 device_remove_file(dev, &dev_attr_tempo_msb);
595 device_remove_file(dev, &dev_attr_tempo_lsb);
596 if(firmware >= 300) device_remove_file(dev, &dev_attr_wah_model);
597 if(firmware >= 214) device_remove_file(dev, &dev_attr_bypass_volume);
598 if((type & (LINE6_BITS_PRO)) != 0) device_remove_file(dev, &dev_attr_fx_loop_on_off);
599 device_remove_file(dev, &dev_attr_tweak_param_select);
600 device_remove_file(dev, &dev_attr_amp1_engage);
601 if(firmware >= 200) device_remove_file(dev, &dev_attr_band_1_gain);
602 if((type & (LINE6_BITS_BASSPODXTALL)) != 0) if(firmware >= 200) device_remove_file(dev, &dev_attr_band_2_gain__bass);
603 if((type & (LINE6_BITS_PODXTALL)) != 0) if(firmware >= 200) device_remove_file(dev, &dev_attr_band_2_gain);
604 if((type & (LINE6_BITS_BASSPODXTALL)) != 0) if(firmware >= 200) device_remove_file(dev, &dev_attr_band_3_gain__bass);
605 if((type & (LINE6_BITS_PODXTALL)) != 0) if(firmware >= 200) device_remove_file(dev, &dev_attr_band_3_gain);
606 if((type & (LINE6_BITS_BASSPODXTALL)) != 0) if(firmware >= 200) device_remove_file(dev, &dev_attr_band_4_gain__bass);
607 if((type & (LINE6_BITS_BASSPODXTALL)) != 0) if(firmware >= 200) device_remove_file(dev, &dev_attr_band_5_gain__bass);
608 if((type & (LINE6_BITS_PODXTALL)) != 0) if(firmware >= 200) device_remove_file(dev, &dev_attr_band_4_gain);
609 if((type & (LINE6_BITS_BASSPODXTALL)) != 0) if(firmware >= 200) device_remove_file(dev, &dev_attr_band_6_gain__bass);
610}
611
612EXPORT_SYMBOL(pod_create_files);
613EXPORT_SYMBOL(pod_remove_files);
614
615int variax_create_files(int firmware, int type, struct device *dev) {
616 int err;
617 CHECK_RETURN(device_create_file(dev, &dev_attr_body));
618 CHECK_RETURN(device_create_file(dev, &dev_attr_pickup1_enable));
619 CHECK_RETURN(device_create_file(dev, &dev_attr_pickup1_type));
620 CHECK_RETURN(device_create_file(dev, &dev_attr_pickup1_position));
621 CHECK_RETURN(device_create_file(dev, &dev_attr_pickup1_angle));
622 CHECK_RETURN(device_create_file(dev, &dev_attr_pickup1_level));
623 CHECK_RETURN(device_create_file(dev, &dev_attr_pickup2_enable));
624 CHECK_RETURN(device_create_file(dev, &dev_attr_pickup2_type));
625 CHECK_RETURN(device_create_file(dev, &dev_attr_pickup2_position));
626 CHECK_RETURN(device_create_file(dev, &dev_attr_pickup2_angle));
627 CHECK_RETURN(device_create_file(dev, &dev_attr_pickup2_level));
628 CHECK_RETURN(device_create_file(dev, &dev_attr_pickup_phase));
629 CHECK_RETURN(device_create_file(dev, &dev_attr_capacitance));
630 CHECK_RETURN(device_create_file(dev, &dev_attr_tone_resistance));
631 CHECK_RETURN(device_create_file(dev, &dev_attr_volume_resistance));
632 CHECK_RETURN(device_create_file(dev, &dev_attr_taper));
633 CHECK_RETURN(device_create_file(dev, &dev_attr_tone_dump));
634 CHECK_RETURN(device_create_file(dev, &dev_attr_save_tone));
635 CHECK_RETURN(device_create_file(dev, &dev_attr_volume_dump));
636 CHECK_RETURN(device_create_file(dev, &dev_attr_tuning_enable));
637 CHECK_RETURN(device_create_file(dev, &dev_attr_tuning6));
638 CHECK_RETURN(device_create_file(dev, &dev_attr_tuning5));
639 CHECK_RETURN(device_create_file(dev, &dev_attr_tuning4));
640 CHECK_RETURN(device_create_file(dev, &dev_attr_tuning3));
641 CHECK_RETURN(device_create_file(dev, &dev_attr_tuning2));
642 CHECK_RETURN(device_create_file(dev, &dev_attr_tuning1));
643 CHECK_RETURN(device_create_file(dev, &dev_attr_detune6));
644 CHECK_RETURN(device_create_file(dev, &dev_attr_detune5));
645 CHECK_RETURN(device_create_file(dev, &dev_attr_detune4));
646 CHECK_RETURN(device_create_file(dev, &dev_attr_detune3));
647 CHECK_RETURN(device_create_file(dev, &dev_attr_detune2));
648 CHECK_RETURN(device_create_file(dev, &dev_attr_detune1));
649 CHECK_RETURN(device_create_file(dev, &dev_attr_mix6));
650 CHECK_RETURN(device_create_file(dev, &dev_attr_mix5));
651 CHECK_RETURN(device_create_file(dev, &dev_attr_mix4));
652 CHECK_RETURN(device_create_file(dev, &dev_attr_mix3));
653 CHECK_RETURN(device_create_file(dev, &dev_attr_mix2));
654 CHECK_RETURN(device_create_file(dev, &dev_attr_mix1));
655 CHECK_RETURN(device_create_file(dev, &dev_attr_pickup_wiring));
656 return 0;
657}
658
659void variax_remove_files(int firmware, int type, struct device *dev) {
660 device_remove_file(dev, &dev_attr_body);
661 device_remove_file(dev, &dev_attr_pickup1_enable);
662 device_remove_file(dev, &dev_attr_pickup1_type);
663 device_remove_file(dev, &dev_attr_pickup1_position);
664 device_remove_file(dev, &dev_attr_pickup1_angle);
665 device_remove_file(dev, &dev_attr_pickup1_level);
666 device_remove_file(dev, &dev_attr_pickup2_enable);
667 device_remove_file(dev, &dev_attr_pickup2_type);
668 device_remove_file(dev, &dev_attr_pickup2_position);
669 device_remove_file(dev, &dev_attr_pickup2_angle);
670 device_remove_file(dev, &dev_attr_pickup2_level);
671 device_remove_file(dev, &dev_attr_pickup_phase);
672 device_remove_file(dev, &dev_attr_capacitance);
673 device_remove_file(dev, &dev_attr_tone_resistance);
674 device_remove_file(dev, &dev_attr_volume_resistance);
675 device_remove_file(dev, &dev_attr_taper);
676 device_remove_file(dev, &dev_attr_tone_dump);
677 device_remove_file(dev, &dev_attr_save_tone);
678 device_remove_file(dev, &dev_attr_volume_dump);
679 device_remove_file(dev, &dev_attr_tuning_enable);
680 device_remove_file(dev, &dev_attr_tuning6);
681 device_remove_file(dev, &dev_attr_tuning5);
682 device_remove_file(dev, &dev_attr_tuning4);
683 device_remove_file(dev, &dev_attr_tuning3);
684 device_remove_file(dev, &dev_attr_tuning2);
685 device_remove_file(dev, &dev_attr_tuning1);
686 device_remove_file(dev, &dev_attr_detune6);
687 device_remove_file(dev, &dev_attr_detune5);
688 device_remove_file(dev, &dev_attr_detune4);
689 device_remove_file(dev, &dev_attr_detune3);
690 device_remove_file(dev, &dev_attr_detune2);
691 device_remove_file(dev, &dev_attr_detune1);
692 device_remove_file(dev, &dev_attr_mix6);
693 device_remove_file(dev, &dev_attr_mix5);
694 device_remove_file(dev, &dev_attr_mix4);
695 device_remove_file(dev, &dev_attr_mix3);
696 device_remove_file(dev, &dev_attr_mix2);
697 device_remove_file(dev, &dev_attr_mix1);
698 device_remove_file(dev, &dev_attr_pickup_wiring);
699}
700
701EXPORT_SYMBOL(variax_create_files);
702EXPORT_SYMBOL(variax_remove_files);
diff --git a/drivers/staging/line6/control.h b/drivers/staging/line6/control.h
new file mode 100644
index 000000000000..2f19665d95a9
--- /dev/null
+++ b/drivers/staging/line6/control.h
@@ -0,0 +1,187 @@
1/*
2 * Line6 Linux USB driver - 0.8.0
3 *
4 * Copyright (C) 2004-2009 Markus Grabner (grabner@icg.tugraz.at)
5 *
6 * This program is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU General Public License as
8 * published by the Free Software Foundation, version 2.
9 *
10 */
11
12#ifndef LINE6_CONTROL_H
13#define LINE6_CONTROL_H
14
15
16/**
17 List of PODxt Pro controls.
18 See Appendix C of the "PODxt (Pro) Pilot's Handbook" by Line6.
19 Comments after the number refer to the PODxt Pro firmware version required
20 for this feature.
21*/
22enum {
23 POD_tweak = 1,
24 POD_wah_position = 4,
25 POD_compression_gain = 5, /* device: LINE6_BITS_PODXTALL */
26 POD_vol_pedal_position = 7,
27 POD_compression_threshold = 9,
28 POD_pan = 10,
29 POD_amp_model_setup = 11,
30 POD_amp_model = 12, /* firmware: 2.0 */
31 POD_drive = 13,
32 POD_bass = 14,
33 POD_mid = 15, /* device: LINE6_BITS_PODXTALL */
34 POD_lowmid = 15, /* device: LINE6_BITS_BASSPODXTALL */
35 POD_treble = 16, /* device: LINE6_BITS_PODXTALL */
36 POD_highmid = 16, /* device: LINE6_BITS_BASSPODXTALL */
37 POD_chan_vol = 17,
38 POD_reverb_mix = 18, /* device: LINE6_BITS_PODXTALL */
39 POD_effect_setup = 19,
40 POD_band_1_frequency = 20, /* firmware: 2.0 */
41 POD_presence = 21, /* device: LINE6_BITS_PODXTALL */
42 POD_treble__bass = 21, /* device: LINE6_BITS_BASSPODXTALL */
43 POD_noise_gate_enable = 22,
44 POD_gate_threshold = 23,
45 POD_gate_decay_time = 24,
46 POD_stomp_enable = 25,
47 POD_comp_enable = 26,
48 POD_stomp_time = 27,
49 POD_delay_enable = 28,
50 POD_mod_param_1 = 29,
51 POD_delay_param_1 = 30,
52 POD_delay_param_1_note_value = 31,
53 POD_band_2_frequency__bass = 32, /* device: LINE6_BITS_BASSPODXTALL */ /* firmware: 2.0 */
54 POD_delay_param_2 = 33,
55 POD_delay_volume_mix = 34,
56 POD_delay_param_3 = 35,
57 POD_reverb_enable = 36, /* device: LINE6_BITS_PODXTALL */
58 POD_reverb_type = 37, /* device: LINE6_BITS_PODXTALL */
59 POD_reverb_decay = 38, /* device: LINE6_BITS_PODXTALL */
60 POD_reverb_tone = 39, /* device: LINE6_BITS_PODXTALL */
61 POD_reverb_pre_delay = 40, /* device: LINE6_BITS_PODXTALL */
62 POD_reverb_pre_post = 41, /* device: LINE6_BITS_PODXTALL */
63 POD_band_2_frequency = 42, /* device: LINE6_BITS_PODXTALL */ /* firmware: 2.0 */
64 POD_band_3_frequency__bass = 42, /* device: LINE6_BITS_BASSPODXTALL */ /* firmware: 2.0 */
65 POD_wah_enable = 43,
66 POD_modulation_lo_cut = 44, /* device: LINE6_BITS_BASSPODXTALL */
67 POD_delay_reverb_lo_cut = 45, /* device: LINE6_BITS_BASSPODXTALL */
68 POD_volume_pedal_minimum = 46, /* device: LINE6_BITS_PODXTALL */ /* firmware: 2.0 */
69 POD_eq_pre_post = 46, /* device: LINE6_BITS_BASSPODXTALL */ /* firmware: 2.0 */
70 POD_volume_pre_post = 47,
71 POD_di_model = 48, /* device: LINE6_BITS_BASSPODXTALL */
72 POD_di_delay = 49, /* device: LINE6_BITS_BASSPODXTALL */
73 POD_mod_enable = 50,
74 POD_mod_param_1_note_value = 51,
75 POD_mod_param_2 = 52,
76 POD_mod_param_3 = 53,
77 POD_mod_param_4 = 54,
78 POD_mod_param_5 = 55, /* device: LINE6_BITS_BASSPODXTALL */
79 POD_mod_volume_mix = 56,
80 POD_mod_pre_post = 57,
81 POD_modulation_model = 58,
82 POD_band_3_frequency = 60, /* device: LINE6_BITS_PODXTALL */ /* firmware: 2.0 */
83 POD_band_4_frequency__bass = 60, /* device: LINE6_BITS_BASSPODXTALL */ /* firmware: 2.0 */
84 POD_mod_param_1_double_precision = 61,
85 POD_delay_param_1_double_precision = 62,
86 POD_eq_enable = 63, /* firmware: 2.0 */
87 POD_tap = 64,
88 POD_volume_tweak_pedal_assign = 65,
89 POD_band_5_frequency = 68, /* device: LINE6_BITS_BASSPODXTALL */ /* firmware: 2.0 */
90 POD_tuner = 69,
91 POD_mic_selection = 70,
92 POD_cabinet_model = 71,
93 POD_stomp_model = 75,
94 POD_roomlevel = 76,
95 POD_band_4_frequency = 77, /* device: LINE6_BITS_PODXTALL */ /* firmware: 2.0 */
96 POD_band_6_frequency = 77, /* device: LINE6_BITS_BASSPODXTALL */ /* firmware: 2.0 */
97 POD_stomp_param_1_note_value = 78,
98 POD_stomp_param_2 = 79,
99 POD_stomp_param_3 = 80,
100 POD_stomp_param_4 = 81,
101 POD_stomp_param_5 = 82,
102 POD_stomp_param_6 = 83,
103 POD_amp_switch_select = 84, /* device: LINE6_BITS_LIVE */
104 POD_delay_param_4 = 85,
105 POD_delay_param_5 = 86,
106 POD_delay_pre_post = 87,
107 POD_delay_model = 88, /* device: LINE6_BITS_PODXTALL */
108 POD_delay_verb_model = 88, /* device: LINE6_BITS_BASSPODXTALL */
109 POD_tempo_msb = 89,
110 POD_tempo_lsb = 90,
111 POD_wah_model = 91, /* firmware: 3.0 */
112 POD_bypass_volume = 105, /* firmware: 2.14 */
113 POD_fx_loop_on_off = 107, /* device: LINE6_BITS_PRO */
114 POD_tweak_param_select = 108,
115 POD_amp1_engage = 111,
116 POD_band_1_gain = 114, /* firmware: 2.0 */
117 POD_band_2_gain__bass = 115, /* device: LINE6_BITS_BASSPODXTALL */ /* firmware: 2.0 */
118 POD_band_2_gain = 116, /* device: LINE6_BITS_PODXTALL */ /* firmware: 2.0 */
119 POD_band_3_gain__bass = 116, /* device: LINE6_BITS_BASSPODXTALL */ /* firmware: 2.0 */
120 POD_band_3_gain = 117, /* device: LINE6_BITS_PODXTALL */ /* firmware: 2.0 */
121 POD_band_4_gain__bass = 117, /* device: LINE6_BITS_BASSPODXTALL */ /* firmware: 2.0 */
122 POD_band_5_gain__bass = 118, /* device: LINE6_BITS_BASSPODXTALL */ /* firmware: 2.0 */
123 POD_band_4_gain = 119, /* device: LINE6_BITS_PODXTALL */ /* firmware: 2.0 */
124 POD_band_6_gain__bass = 119 /* device: LINE6_BITS_BASSPODXTALL */ /* firmware: 2.0 */
125};
126
127/**
128 List of Variax workbench controls (dump).
129*/
130enum {
131 VARIAX_body = 3,
132 VARIAX_pickup1_enable = 4, /* 0: enabled, 1: disabled */
133 VARIAX_pickup1_type = 8,
134 VARIAX_pickup1_position = 9, /* type: 24 bit float */
135 VARIAX_pickup1_angle = 12, /* type: 24 bit float */
136 VARIAX_pickup1_level = 15, /* type: 24 bit float */
137 VARIAX_pickup2_enable = 18, /* 0: enabled, 1: disabled */
138 VARIAX_pickup2_type = 22,
139 VARIAX_pickup2_position = 23, /* type: 24 bit float */
140 VARIAX_pickup2_angle = 26, /* type: 24 bit float */
141 VARIAX_pickup2_level = 29, /* type: 24 bit float */
142 VARIAX_pickup_phase = 32, /* 0: in phase, 1: out of phase */
143 VARIAX_capacitance = 33, /* type: 24 bit float */
144 VARIAX_tone_resistance = 36, /* type: 24 bit float */
145 VARIAX_volume_resistance = 39, /* type: 24 bit float */
146 VARIAX_taper = 42, /* 0: Linear, 1: Audio */
147 VARIAX_tone_dump = 43, /* type: 24 bit float */
148 VARIAX_save_tone = 46,
149 VARIAX_volume_dump = 47, /* type: 24 bit float */
150 VARIAX_tuning_enable = 50,
151 VARIAX_tuning6 = 51,
152 VARIAX_tuning5 = 52,
153 VARIAX_tuning4 = 53,
154 VARIAX_tuning3 = 54,
155 VARIAX_tuning2 = 55,
156 VARIAX_tuning1 = 56,
157 VARIAX_detune6 = 57, /* type: 24 bit float */
158 VARIAX_detune5 = 60, /* type: 24 bit float */
159 VARIAX_detune4 = 63, /* type: 24 bit float */
160 VARIAX_detune3 = 66, /* type: 24 bit float */
161 VARIAX_detune2 = 69, /* type: 24 bit float */
162 VARIAX_detune1 = 72, /* type: 24 bit float */
163 VARIAX_mix6 = 75, /* type: 24 bit float */
164 VARIAX_mix5 = 78, /* type: 24 bit float */
165 VARIAX_mix4 = 81, /* type: 24 bit float */
166 VARIAX_mix3 = 84, /* type: 24 bit float */
167 VARIAX_mix2 = 87, /* type: 24 bit float */
168 VARIAX_mix1 = 90, /* type: 24 bit float */
169 VARIAX_pickup_wiring = 96 /* 0: parallel, 1: series */
170};
171
172/**
173 List of Variax workbench controls (MIDI).
174*/
175enum {
176 VARIAXMIDI_volume = 7,
177 VARIAXMIDI_tone = 79,
178};
179
180
181extern int pod_create_files(int firmware, int type, struct device *dev);
182extern void pod_remove_files(int firmware, int type, struct device *dev);
183extern int variax_create_files(int firmware, int type, struct device *dev);
184extern void variax_remove_files(int firmware, int type, struct device *dev);
185
186
187#endif
diff --git a/drivers/staging/line6/driver.c b/drivers/staging/line6/driver.c
new file mode 100644
index 000000000000..f20efa583691
--- /dev/null
+++ b/drivers/staging/line6/driver.c
@@ -0,0 +1,1050 @@
1/*
2 * Line6 Linux USB driver - 0.8.0
3 *
4 * Copyright (C) 2004-2009 Markus Grabner (grabner@icg.tugraz.at)
5 *
6 * This program is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU General Public License as
8 * published by the Free Software Foundation, version 2.
9 *
10 */
11
12#include "driver.h"
13
14#include <linux/kernel.h>
15#include <linux/module.h>
16#include <linux/usb.h>
17
18#include "audio.h"
19#include "capture.h"
20#include "control.h"
21#include "midi.h"
22#include "playback.h"
23#include "pod.h"
24#include "revision.h"
25#include "toneport.h"
26#include "usbdefs.h"
27#include "variax.h"
28
29
30#define DRIVER_AUTHOR "Markus Grabner <grabner@icg.tugraz.at>"
31#define DRIVER_DESC "Line6 USB Driver"
32#define DRIVER_VERSION "0.8.0"
33
34
35/* table of devices that work with this driver */
36static struct usb_device_id line6_id_table[] = {
37 { USB_DEVICE(LINE6_VENDOR_ID, LINE6_DEVID_BASSPODXT) },
38 { USB_DEVICE(LINE6_VENDOR_ID, LINE6_DEVID_BASSPODXTLIVE) },
39 { USB_DEVICE(LINE6_VENDOR_ID, LINE6_DEVID_BASSPODXTPRO) },
40 { USB_DEVICE(LINE6_VENDOR_ID, LINE6_DEVID_GUITARPORT) },
41 { USB_DEVICE(LINE6_VENDOR_ID, LINE6_DEVID_POCKETPOD) },
42 { USB_DEVICE(LINE6_VENDOR_ID, LINE6_DEVID_PODX3) },
43 { USB_DEVICE(LINE6_VENDOR_ID, LINE6_DEVID_PODX3LIVE) },
44 { USB_DEVICE(LINE6_VENDOR_ID, LINE6_DEVID_PODXT) },
45 { USB_DEVICE(LINE6_VENDOR_ID, LINE6_DEVID_PODXTLIVE) },
46 { USB_DEVICE(LINE6_VENDOR_ID, LINE6_DEVID_PODXTPRO) },
47 { USB_DEVICE(LINE6_VENDOR_ID, LINE6_DEVID_TONEPORT_GX) },
48 { USB_DEVICE(LINE6_VENDOR_ID, LINE6_DEVID_TONEPORT_UX1) },
49 { USB_DEVICE(LINE6_VENDOR_ID, LINE6_DEVID_TONEPORT_UX2) },
50 { USB_DEVICE(LINE6_VENDOR_ID, LINE6_DEVID_VARIAX) },
51 { },
52};
53MODULE_DEVICE_TABLE (usb, line6_id_table);
54
55static struct line6_properties line6_properties_table[] = {
56 { "BassPODxt", LINE6_BIT_BASSPODXT, LINE6_BIT_CONTROL_PCM },
57 { "BassPODxt Live", LINE6_BIT_BASSPODXTLIVE, LINE6_BIT_CONTROL_PCM },
58 { "BassPODxt Pro", LINE6_BIT_BASSPODXTPRO, LINE6_BIT_CONTROL_PCM },
59 { "GuitarPort", LINE6_BIT_GUITARPORT, LINE6_BIT_PCM },
60 { "Pocket POD", LINE6_BIT_POCKETPOD, LINE6_BIT_CONTROL_PCM },
61 { "POD X3", LINE6_BIT_PODX3, LINE6_BIT_PCM },
62 { "POD X3 Live", LINE6_BIT_PODX3LIVE, LINE6_BIT_PCM },
63 { "PODxt", LINE6_BIT_PODXT, LINE6_BIT_CONTROL_PCM },
64 { "PODxt Live", LINE6_BIT_PODXTLIVE, LINE6_BIT_CONTROL_PCM },
65 { "PODxt Pro", LINE6_BIT_PODXTPRO, LINE6_BIT_CONTROL_PCM },
66 { "TonePort GX", LINE6_BIT_TONEPORT_GX, LINE6_BIT_PCM },
67 { "TonePort UX1", LINE6_BIT_TONEPORT_UX1, LINE6_BIT_PCM },
68 { "TonePort UX2", LINE6_BIT_TONEPORT_UX2, LINE6_BIT_PCM },
69 { "Variax Workbench", LINE6_BIT_VARIAX, LINE6_BIT_CONTROL }
70};
71
72
73/*
74 This is Line6's MIDI manufacturer ID.
75*/
76const unsigned char line6_midi_id[] = { 0x00, 0x01, 0x0c };
77
78struct usb_line6 *line6_devices[LINE6_MAX_DEVICES];
79struct workqueue_struct *line6_workqueue;
80
81
82/**
83 Class for asynchronous messages.
84*/
85struct message
86{
87 struct usb_line6 *line6;
88 const char *buffer;
89 int size;
90 int done;
91};
92
93
94/*
95 Forward declarations.
96*/
97static void line6_data_received(struct urb *urb PT_REGS);
98static int line6_send_raw_message_async_part(struct message *msg, struct urb *urb);
99
100
101/*
102 Start to listen on endpoint.
103*/
104static int line6_start_listen(struct usb_line6 *line6)
105{
106 usb_fill_int_urb(line6->urb_listen,
107 line6->usbdev,
108 usb_rcvintpipe(line6->usbdev, line6->ep_control_read),
109 line6->buffer_listen, LINE6_BUFSIZE_LISTEN,
110 line6_data_received,
111 line6,
112 line6->interval);
113 line6->urb_listen->actual_length = 0;
114 return usb_submit_urb(line6->urb_listen, GFP_KERNEL);
115}
116
117#if DO_DUMP_ANY
118/*
119 Write hexdump to syslog.
120*/
121void line6_write_hexdump(struct usb_line6 *line6, char dir, const unsigned char *buffer, int size)
122{
123 static const int BYTES_PER_LINE = 8;
124 char hexdump[100];
125 char asc[BYTES_PER_LINE + 1];
126 int i, j;
127
128 for(i = 0; i < size; i += BYTES_PER_LINE) {
129 int hexdumpsize = sizeof(hexdump);
130 char *p = hexdump;
131 int n = min(size - i, BYTES_PER_LINE);
132 asc[n] = 0;
133
134 for(j = 0; j < BYTES_PER_LINE; ++j) {
135 int bytes;
136
137 if(j < n) {
138 unsigned char val = buffer[i + j];
139 bytes = snprintf(p, hexdumpsize, " %02X", val);
140 asc[j] = ((val >= 0x20) && (val < 0x7f)) ? val : '.';
141 }
142 else
143 bytes = snprintf(p, hexdumpsize, " ");
144
145 if(bytes > hexdumpsize)
146 break; /* buffer overflow */
147
148 p += bytes;
149 hexdumpsize -= bytes;
150 }
151
152 dev_info(line6->ifcdev, "%c%04X:%s %s\n", dir, i, hexdump, asc);
153 }
154}
155#endif
156
157#if DO_DUMP_URB_RECEIVE
158/*
159 Dump URB data to syslog.
160*/
161static void line6_dump_urb(struct urb *urb)
162{
163 struct usb_line6 *line6 = (struct usb_line6 *)urb->context;
164
165 if(urb->status < 0)
166 return;
167
168 line6_write_hexdump(line6, 'R', (unsigned char *)urb->transfer_buffer, urb->actual_length);
169}
170#endif
171
172/*
173 Send raw message in pieces of wMaxPacketSize bytes.
174*/
175int line6_send_raw_message(struct usb_line6 *line6, const char *buffer, int size)
176{
177 int i, done = 0;
178
179#if DO_DUMP_URB_SEND
180 line6_write_hexdump(line6, 'S', buffer, size);
181#endif
182
183 for(i = 0; i < size; i += line6->max_packet_size) {
184 int partial;
185 const char *frag_buf = buffer + i;
186 int frag_size = min(line6->max_packet_size, size - i);
187 int retval = usb_interrupt_msg(line6->usbdev,
188 usb_sndintpipe(line6->usbdev, line6->ep_control_write),
189 (char *)frag_buf, frag_size, &partial, LINE6_TIMEOUT * HZ);
190
191 if(retval) {
192 dev_err(line6->ifcdev, "usb_interrupt_msg failed (%d)\n", retval);
193 break;
194 }
195
196 done += frag_size;
197 }
198
199 return done;
200}
201
202/*
203 Notification of completion of asynchronous request transmission.
204*/
205static void line6_async_request_sent(struct urb *urb PT_REGS)
206{
207 struct message *msg = (struct message *)urb->context;
208
209 if(msg->done >= msg->size) {
210 usb_free_urb(urb);
211 kfree(msg);
212 }
213 else
214 line6_send_raw_message_async_part(msg, urb);
215}
216
217/*
218 Asynchronously send part of a raw message.
219*/
220static int line6_send_raw_message_async_part(struct message *msg, struct urb *urb)
221{
222 int retval;
223 struct usb_line6 *line6 = msg->line6;
224 int done = msg->done;
225 int bytes = min(msg->size - done, line6->max_packet_size);
226
227 usb_fill_int_urb(urb,
228 line6->usbdev,
229 usb_sndintpipe(line6->usbdev, line6->ep_control_write),
230 (char *)msg->buffer + done, bytes,
231 line6_async_request_sent, msg, line6->interval);
232
233#if DO_DUMP_URB_SEND
234 line6_write_hexdump(line6, 'S', (char *)msg->buffer + done, bytes);
235#endif
236
237 msg->done += bytes;
238 retval = usb_submit_urb(urb, GFP_ATOMIC);
239
240 if(retval < 0) {
241 dev_err(line6->ifcdev, "line6_send_raw_message_async: usb_submit_urb failed (%d)\n", retval);
242 usb_free_urb(urb);
243 kfree(msg);
244 return -EINVAL;
245 }
246
247 return 0;
248}
249
250/*
251 Asynchronously send raw message.
252*/
253int line6_send_raw_message_async(struct usb_line6 *line6, const char *buffer, int size)
254{
255 struct message *msg;
256 struct urb *urb;
257
258 /* create message: */
259 msg = kmalloc(sizeof(struct message), GFP_ATOMIC);
260
261 if(msg == NULL) {
262 dev_err(line6->ifcdev, "Out of memory\n");
263 return -ENOMEM;
264 }
265
266 /* create URB: */
267 urb = usb_alloc_urb(0, GFP_ATOMIC);
268
269 if(urb == NULL) {
270 kfree(msg);
271 dev_err(line6->ifcdev, "Out of memory\n");
272 return -ENOMEM;
273 }
274
275 /* set message data: */
276 msg->line6 = line6;
277 msg->buffer = buffer;
278 msg->size = size;
279 msg->done = 0;
280
281 /* start sending: */
282 return line6_send_raw_message_async_part(msg, urb);
283}
284
285/*
286 Send sysex message in pieces of wMaxPacketSize bytes.
287*/
288int line6_send_sysex_message(struct usb_line6 *line6, const char *buffer, int size)
289{
290 return line6_send_raw_message(line6, buffer, size + SYSEX_EXTRA_SIZE) - SYSEX_EXTRA_SIZE;
291}
292
293/*
294 Allocate buffer for sysex message and prepare header.
295 @param code sysex message code
296 @param size number of bytes between code and sysex end
297*/
298char *line6_alloc_sysex_buffer(struct usb_line6 *line6, int code1, int code2, int size)
299{
300 char *buffer = kmalloc(size + SYSEX_EXTRA_SIZE, GFP_KERNEL);
301
302 if(!buffer) {
303 dev_err(line6->ifcdev, "out of memory\n");
304 return 0;
305 }
306
307 buffer[0] = LINE6_SYSEX_BEGIN;
308 memcpy(buffer + 1, line6_midi_id, sizeof(line6_midi_id));
309 buffer[sizeof(line6_midi_id) + 1] = code1;
310 buffer[sizeof(line6_midi_id) + 2] = code2;
311 buffer[sizeof(line6_midi_id) + 3 + size] = LINE6_SYSEX_END;
312 return buffer;
313}
314
315/*
316 Notification of data received from the Line6 device.
317*/
318static void line6_data_received(struct urb *urb PT_REGS)
319{
320 struct usb_line6 *line6 = (struct usb_line6 *)urb->context;
321 struct MidiBuffer *mb = &line6->line6midi->midibuf_in;
322 int done;
323
324 if(urb->status == -ESHUTDOWN)
325 return;
326
327#if DO_DUMP_URB_RECEIVE
328 line6_dump_urb(urb);
329#endif
330
331 done = midibuf_write(mb, urb->transfer_buffer, urb->actual_length);
332
333 if(done < urb->actual_length) {
334 midibuf_ignore(mb, done);
335 DEBUG_MESSAGES(dev_err(line6->ifcdev, "%d %d buffer overflow - message skipped\n", done, urb->actual_length));
336 }
337
338 for(;;) {
339 done = midibuf_read(mb, line6->buffer_message, LINE6_MESSAGE_MAXLEN);
340
341 if(done == 0)
342 break;
343
344 /* MIDI input filter */
345 if(midibuf_skip_message(mb, line6->line6midi->midi_mask_receive))
346 continue;
347
348 line6->message_length = done;
349#if DO_DUMP_MIDI_RECEIVE
350 line6_write_hexdump(line6, 'r', line6->buffer_message, done);
351#endif
352 line6_midi_receive(line6, line6->buffer_message, done);
353
354 switch(line6->usbdev->descriptor.idProduct) {
355 case LINE6_DEVID_BASSPODXT:
356 case LINE6_DEVID_BASSPODXTLIVE:
357 case LINE6_DEVID_BASSPODXTPRO:
358 case LINE6_DEVID_PODXT:
359 case LINE6_DEVID_PODXTPRO:
360 case LINE6_DEVID_POCKETPOD:
361 pod_process_message((struct usb_line6_pod *)line6);
362 break;
363
364 case LINE6_DEVID_PODXTLIVE:
365 switch(line6->interface_number) {
366 case PODXTLIVE_INTERFACE_POD:
367 pod_process_message((struct usb_line6_pod *)line6);
368 break;
369
370 case PODXTLIVE_INTERFACE_VARIAX:
371 variax_process_message((struct usb_line6_variax *)line6);
372 break;
373
374 default:
375 dev_err(line6->ifcdev, "PODxt Live interface %d not supported\n", line6->interface_number);
376 }
377 break;
378
379 case LINE6_DEVID_VARIAX:
380 variax_process_message((struct usb_line6_variax *)line6);
381 break;
382
383 default:
384 MISSING_CASE;
385 }
386 }
387
388 line6_start_listen(line6);
389}
390
391/*
392 Send channel number (i.e., switch to a different sound).
393*/
394int line6_send_program(struct usb_line6 *line6, int value)
395{
396 int retval;
397 unsigned char *buffer;
398 unsigned int partial;
399
400 buffer = kmalloc(2, GFP_KERNEL);
401
402 if(!buffer) {
403 dev_err(line6->ifcdev, "out of memory\n");
404 return -ENOMEM;
405 }
406
407 buffer[0] = LINE6_PROGRAM_CHANGE | LINE6_CHANNEL_HOST;
408 buffer[1] = value;
409
410#if DO_DUMP_URB_SEND
411 line6_write_hexdump(line6, 'S', buffer, 2);
412#endif
413
414 retval = usb_interrupt_msg(line6->usbdev,
415 usb_sndintpipe(line6->usbdev, line6->ep_control_write),
416 buffer, 2, &partial, LINE6_TIMEOUT * HZ);
417
418 if(retval)
419 dev_err(line6->ifcdev, "usb_interrupt_msg failed (%d)\n", retval);
420
421 kfree(buffer);
422 return retval;
423}
424
425/*
426 Transmit Line6 control parameter.
427*/
428int line6_transmit_parameter(struct usb_line6 *line6, int param, int value)
429{
430 int retval;
431 unsigned char *buffer;
432 unsigned int partial;
433
434 buffer = kmalloc(3, GFP_KERNEL);
435
436 if(!buffer) {
437 dev_err(line6->ifcdev, "out of memory\n");
438 return -ENOMEM;
439 }
440
441 buffer[0] = LINE6_PARAM_CHANGE | LINE6_CHANNEL_HOST;
442 buffer[1] = param;
443 buffer[2] = value;
444
445#if DO_DUMP_URB_SEND
446 line6_write_hexdump(line6, 'S', buffer, 3);
447#endif
448
449 retval = usb_interrupt_msg(line6->usbdev,
450 usb_sndintpipe(line6->usbdev, line6->ep_control_write),
451 buffer, 3, &partial, LINE6_TIMEOUT * HZ);
452
453 if(retval)
454 dev_err(line6->ifcdev, "usb_interrupt_msg failed (%d)\n", retval);
455
456 kfree(buffer);
457 return retval;
458}
459
460/*
461 Read data from device.
462*/
463int line6_read_data(struct usb_line6 *line6, int address, void *data, size_t datalen)
464{
465 struct usb_device *usbdev = line6->usbdev;
466 int ret;
467 unsigned char len;
468
469 /* query the serial number: */
470 ret = usb_control_msg(usbdev, usb_sndctrlpipe(usbdev, 0), 0x67,
471 USB_TYPE_VENDOR | USB_RECIP_DEVICE | USB_DIR_OUT,
472 (datalen << 8) | 0x21, address, 0, 0, LINE6_TIMEOUT * HZ);
473
474 if(ret < 0) {
475 dev_err(line6->ifcdev, "read request failed (error %d)\n", ret);
476 return ret;
477 }
478
479 /* Wait for data length. We'll get a couple of 0xff until length arrives. */
480 do {
481 ret = usb_control_msg(usbdev, usb_rcvctrlpipe(usbdev, 0), 0x67,
482 USB_TYPE_VENDOR | USB_RECIP_DEVICE | USB_DIR_IN,
483 0x0012, 0x0000, &len, 1, LINE6_TIMEOUT * HZ);
484 if(ret < 0) {
485 dev_err(line6->ifcdev, "receive length failed (error %d)\n", ret);
486 return ret;
487 }
488 }
489 while(len == 0xff);
490
491 if(len != datalen) { /* should be equal or something went wrong */
492 dev_err(line6->ifcdev, "length mismatch (expected %d, got %d)\n", (int)datalen, (int)len);
493 return -EINVAL;
494 }
495
496 /* receive the result: */
497 ret = usb_control_msg(usbdev, usb_rcvctrlpipe(usbdev, 0), 0x67,
498 USB_TYPE_VENDOR | USB_RECIP_DEVICE | USB_DIR_IN,
499 0x0013, 0x0000, data, datalen, LINE6_TIMEOUT * HZ);
500
501 if(ret < 0) {
502 dev_err(line6->ifcdev, "read failed (error %d)\n", ret);
503 return ret;
504 }
505
506 return 0;
507}
508
509/*
510 Write data to device.
511*/
512int line6_write_data(struct usb_line6 *line6, int address, void *data, size_t datalen)
513{
514 struct usb_device *usbdev = line6->usbdev;
515 int ret;
516 unsigned char status;
517
518 ret = usb_control_msg(usbdev, usb_sndctrlpipe(usbdev,0), 0x67,
519 USB_TYPE_VENDOR | USB_RECIP_DEVICE | USB_DIR_OUT,
520 0x0022, address, data, datalen, LINE6_TIMEOUT * HZ);
521
522 if(ret < 0) {
523 dev_err(line6->ifcdev, "write request failed (error %d)\n", ret);
524 return ret;
525 }
526
527 do {
528 ret = usb_control_msg(usbdev, usb_rcvctrlpipe(usbdev,0), 0x67,
529 USB_TYPE_VENDOR | USB_RECIP_DEVICE | USB_DIR_IN,
530 0x0012, 0x0000, &status, 1, LINE6_TIMEOUT * HZ);
531
532 if(ret < 0) {
533 dev_err(line6->ifcdev, "receiving status failed (error %d)\n", ret);
534 return ret;
535 }
536 }
537 while(status == 0xff);
538
539 if(status != 0) {
540 dev_err(line6->ifcdev, "write failed (error %d)\n", ret);
541 return -EINVAL;
542 }
543
544 return 0;
545}
546
547/*
548 Read Line6 device serial number.
549 (POD, TonePort, GuitarPort)
550*/
551int line6_read_serial_number(struct usb_line6 *line6, int *serial_number)
552{
553 return line6_read_data(line6, 0x80d0, serial_number, sizeof(*serial_number));
554}
555
556/*
557 No operation (i.e., unsupported).
558*/
559ssize_t line6_nop_read(struct device *dev, DEVICE_ATTRIBUTE char *buf)
560{
561 return 0;
562}
563
564/*
565 No operation (i.e., unsupported).
566*/
567ssize_t line6_nop_write(struct device *dev, DEVICE_ATTRIBUTE const char *buf, size_t count)
568{
569 return count;
570}
571
572/*
573 "write" request on "raw" special file.
574*/
575#if CREATE_RAW_FILE
576ssize_t line6_set_raw(struct device *dev, DEVICE_ATTRIBUTE const char *buf, size_t count)
577{
578 struct usb_interface *interface = to_usb_interface(dev);
579 struct usb_line6 *line6 = usb_get_intfdata(interface);
580 line6_send_raw_message(line6, buf, count);
581 return count;
582}
583#endif
584
585/*
586 Generic destructor.
587*/
588static void line6_destruct(struct usb_interface *interface)
589{
590 struct usb_line6 *line6;
591 if(interface == NULL) return;
592 line6 = usb_get_intfdata(interface);
593 if(line6 == NULL) return;
594
595 /* free buffer memory first: */
596 if(line6->buffer_message != NULL) kfree(line6->buffer_message);
597 if(line6->buffer_listen != NULL) kfree(line6->buffer_listen);
598
599 /* then free URBs: */
600 if(line6->urb_listen != NULL) usb_free_urb(line6->urb_listen);
601
602 /* make sure the device isn't destructed twice: */
603 usb_set_intfdata(interface, NULL);
604
605 /* free interface data: */
606 kfree(line6);
607}
608
609static void line6_list_devices(void)
610{
611 int i;
612
613 for(i = 0; i < LINE6_MAX_DEVICES; ++i) {
614 struct usb_line6 *dev = line6_devices[i];
615 printk(KERN_INFO "Line6 device %d: ", i);
616
617 if(dev == NULL)
618 printk("(not used)\n");
619 else
620 printk("%s:%d\n", dev->properties->name, dev->interface_number);
621 }
622}
623
624/*
625 Probe USB device.
626*/
627static int line6_probe(struct usb_interface *interface, const struct usb_device_id *id)
628{
629 int devtype;
630 struct usb_device *usbdev = 0;
631 struct usb_line6 *line6 = 0;
632 const struct line6_properties *properties;
633 int devnum;
634 int interface_number, alternate = 0;
635 int product;
636 int size = 0;
637 int ep_read = 0, ep_write = 0;
638 int ret;
639
640 if(interface == NULL) return -ENODEV;
641 usbdev = interface_to_usbdev(interface);
642 if(usbdev == NULL) return -ENODEV;
643
644 /* increment reference counters: */
645 usb_get_intf(interface);
646 usb_get_dev(usbdev);
647
648 /* we don't handle multiple configurations */
649 if(usbdev->descriptor.bNumConfigurations != 1)
650 return -ENODEV;
651
652 /* check vendor and product id */
653 for(devtype = sizeof(line6_id_table) / sizeof(line6_id_table[0]) - 1; devtype--;)
654 if((le16_to_cpu(usbdev->descriptor.idVendor) == line6_id_table[devtype].idVendor) &&
655 (le16_to_cpu(usbdev->descriptor.idProduct) == line6_id_table[devtype].idProduct))
656 break;
657
658 if(devtype < 0)
659 return -ENODEV;
660
661 /* find free slot in device table: */
662 for(devnum = 0; devnum < LINE6_MAX_DEVICES; ++devnum)
663 if(line6_devices[devnum] == NULL)
664 break;
665
666 if(devnum == LINE6_MAX_DEVICES)
667 return -ENODEV;
668
669 /* initialize device info: */
670 properties = &line6_properties_table[devtype];
671 dev_info(&interface->dev, "Line6 %s found\n", properties->name);
672 product = le16_to_cpu(usbdev->descriptor.idProduct);
673
674 /* query interface number */
675 interface_number = interface->cur_altsetting->desc.bInterfaceNumber;
676
677 switch(product) {
678 case LINE6_DEVID_BASSPODXTLIVE:
679 case LINE6_DEVID_POCKETPOD:
680 case LINE6_DEVID_PODXTLIVE:
681 case LINE6_DEVID_VARIAX:
682 alternate = 1;
683 break;
684
685 case LINE6_DEVID_PODX3:
686 case LINE6_DEVID_PODX3LIVE:
687 switch(interface_number) {
688 case 0: alternate = 1; break;
689 case 1: alternate = 0; break;
690 default: MISSING_CASE;
691 }
692 break;
693
694 case LINE6_DEVID_BASSPODXT:
695 case LINE6_DEVID_BASSPODXTPRO:
696 case LINE6_DEVID_PODXT:
697 case LINE6_DEVID_PODXTPRO:
698 alternate = 5;
699 break;
700
701 case LINE6_DEVID_TONEPORT_GX:
702 case LINE6_DEVID_GUITARPORT:
703 alternate = 2; // 1..4 seem to be ok
704 break;
705
706 case LINE6_DEVID_TONEPORT_UX1:
707 case LINE6_DEVID_TONEPORT_UX2:
708 switch(interface_number) {
709 case 0: alternate = 2; break; /* defaults to 44.1kHz, 16-bit */
710 case 1: alternate = 0; break;
711 default: MISSING_CASE;
712 }
713 break;
714
715 default:
716 MISSING_CASE;
717 return -ENODEV;
718 }
719
720 if((ret = usb_set_interface(usbdev, interface_number, alternate)) < 0) {
721 dev_err(&interface->dev, "set_interface failed\n");
722 return ret;
723 }
724
725 /* initialize device data based on product id: */
726 switch(product) {
727 case LINE6_DEVID_BASSPODXT:
728 case LINE6_DEVID_BASSPODXTLIVE:
729 case LINE6_DEVID_BASSPODXTPRO:
730 case LINE6_DEVID_POCKETPOD:
731 case LINE6_DEVID_PODXT:
732 case LINE6_DEVID_PODXTPRO:
733 size = sizeof(struct usb_line6_pod);
734 ep_read = 0x84;
735 ep_write = 0x03;
736 break;
737
738 case LINE6_DEVID_PODX3:
739 case LINE6_DEVID_PODX3LIVE:
740 /* currently unused! */
741 size = sizeof(struct usb_line6_pod);
742 ep_read = 0x81;
743 ep_write = 0x01;
744 break;
745
746 case LINE6_DEVID_TONEPORT_GX:
747 case LINE6_DEVID_TONEPORT_UX1:
748 case LINE6_DEVID_TONEPORT_UX2:
749 case LINE6_DEVID_GUITARPORT:
750 size = sizeof(struct usb_line6_toneport);
751 /* these don't have a control channel */
752 break;
753
754 case LINE6_DEVID_PODXTLIVE:
755 switch(interface_number) {
756 case PODXTLIVE_INTERFACE_POD:
757 size = sizeof(struct usb_line6_pod);
758 ep_read = 0x84;
759 ep_write = 0x03;
760 break;
761
762 case PODXTLIVE_INTERFACE_VARIAX:
763 size = sizeof(struct usb_line6_variax);
764 ep_read = 0x86;
765 ep_write = 0x05;
766 break;
767
768 default:
769 return -ENODEV;
770 }
771 break;
772
773 case LINE6_DEVID_VARIAX:
774 size = sizeof(struct usb_line6_variax);
775 ep_read = 0x82;
776 ep_write = 0x01;
777 break;
778
779 default:
780 MISSING_CASE;
781 return -ENODEV;
782 }
783
784 if(size == 0) {
785 dev_err(line6->ifcdev, "driver bug: interface data size not set\n");
786 return -ENODEV;
787 }
788
789 line6 = kzalloc(size, GFP_KERNEL);
790
791 if(line6 == NULL) {
792 dev_err(&interface->dev, "Out of memory\n");
793 return -ENOMEM;
794 }
795
796 /* store basic data: */
797 line6->interface_number = interface_number;
798 line6->properties = properties;
799 line6->usbdev = usbdev;
800 line6->ifcdev = &interface->dev;
801 line6->ep_control_read = ep_read;
802 line6->ep_control_write = ep_write;
803 line6->product = product;
804
805 /* get data from endpoint descriptor (see usb_maxpacket): */
806 {
807 struct usb_host_endpoint *ep;
808 unsigned epnum = usb_pipeendpoint(usb_rcvintpipe(usbdev, ep_read));
809 ep = usbdev->ep_in[epnum];
810
811 if(ep != NULL) {
812 line6->interval = ep->desc.bInterval;
813 line6->max_packet_size = le16_to_cpu(ep->desc.wMaxPacketSize);
814 }
815 else {
816 line6->interval = LINE6_FALLBACK_INTERVAL;
817 line6->max_packet_size = LINE6_FALLBACK_MAXPACKETSIZE;
818 dev_err(line6->ifcdev, "endpoint not available, using fallback values");
819 }
820 }
821
822 usb_set_intfdata(interface, line6);
823
824 if(properties->capabilities & LINE6_BIT_CONTROL) {
825 /* initialize USB buffers: */
826 line6->buffer_listen = kmalloc(LINE6_BUFSIZE_LISTEN, GFP_KERNEL);
827
828 if(line6->buffer_listen == NULL) {
829 dev_err(&interface->dev, "Out of memory\n");
830 line6_destruct(interface);
831 return -ENOMEM;
832 }
833
834 line6->buffer_message = kmalloc(LINE6_MESSAGE_MAXLEN, GFP_KERNEL);
835
836 if(line6->buffer_message == NULL) {
837 dev_err(&interface->dev, "Out of memory\n");
838 line6_destruct(interface);
839 return -ENOMEM;
840 }
841
842 line6->urb_listen = usb_alloc_urb(0, GFP_KERNEL);
843
844 if(line6->urb_listen == NULL) {
845 dev_err(&interface->dev, "Out of memory\n");
846 line6_destruct(interface);
847 return -ENOMEM;
848 }
849
850 if((ret = line6_start_listen(line6)) < 0) {
851 dev_err(&interface->dev, " line6_probe: usb_submit_urb failed\n");
852 line6_destruct(interface);
853 return ret;
854 }
855 }
856
857 /* initialize device data based on product id: */
858 switch(product) {
859 case LINE6_DEVID_BASSPODXT:
860 case LINE6_DEVID_BASSPODXTLIVE:
861 case LINE6_DEVID_BASSPODXTPRO:
862 case LINE6_DEVID_POCKETPOD:
863 case LINE6_DEVID_PODX3:
864 case LINE6_DEVID_PODX3LIVE:
865 case LINE6_DEVID_PODXT:
866 case LINE6_DEVID_PODXTPRO:
867 ret = pod_init(interface, (struct usb_line6_pod *)line6);
868 break;
869
870 case LINE6_DEVID_PODXTLIVE:
871 switch(interface_number) {
872 case PODXTLIVE_INTERFACE_POD:
873 ret = pod_init(interface, (struct usb_line6_pod *)line6);
874 break;
875
876 case PODXTLIVE_INTERFACE_VARIAX:
877 ret = variax_init(interface, (struct usb_line6_variax *)line6);
878 break;
879
880 default:
881 dev_err(&interface->dev, "PODxt Live interface %d not supported\n", interface_number);
882 ret = -ENODEV;
883 }
884
885 break;
886
887 case LINE6_DEVID_VARIAX:
888 ret = variax_init(interface, (struct usb_line6_variax *)line6);
889 break;
890
891 case LINE6_DEVID_TONEPORT_GX:
892 case LINE6_DEVID_TONEPORT_UX1:
893 case LINE6_DEVID_TONEPORT_UX2:
894 case LINE6_DEVID_GUITARPORT:
895 ret = toneport_init(interface, (struct usb_line6_toneport *)line6);
896 break;
897
898 default:
899 MISSING_CASE;
900 ret = -ENODEV;
901 }
902
903 if(ret < 0) {
904 line6_destruct(interface);
905 return ret;
906 }
907
908 if((ret = sysfs_create_link(&interface->dev.kobj, &usbdev->dev.kobj, "usb_device")) < 0) {
909 line6_destruct(interface);
910 return ret;
911 }
912
913 dev_info(&interface->dev, "Line6 %s now attached\n", line6->properties->name);
914 line6_devices[devnum] = line6;
915 line6_list_devices();
916 return ret;
917}
918
919/*
920 Line6 device disconnected.
921*/
922static void line6_disconnect(struct usb_interface *interface)
923{
924 struct usb_line6 *line6;
925 struct usb_device *usbdev;
926 int interface_number, i;
927
928 if(interface == NULL) return;
929 usbdev = interface_to_usbdev(interface);
930 if(usbdev == NULL) return;
931
932 sysfs_remove_link(&interface->dev.kobj, "usb_device");
933
934 interface_number = interface->cur_altsetting->desc.bInterfaceNumber;
935 line6 = usb_get_intfdata(interface);
936
937 if(line6 != NULL) {
938 if(line6->urb_listen != NULL) usb_kill_urb(line6->urb_listen);
939
940 if(usbdev != line6->usbdev)
941 dev_err(line6->ifcdev, "driver bug: inconsistent usb device\n");
942
943 switch(line6->usbdev->descriptor.idProduct) {
944 case LINE6_DEVID_BASSPODXT:
945 case LINE6_DEVID_BASSPODXTLIVE:
946 case LINE6_DEVID_BASSPODXTPRO:
947 case LINE6_DEVID_POCKETPOD:
948 case LINE6_DEVID_PODX3:
949 case LINE6_DEVID_PODX3LIVE:
950 case LINE6_DEVID_PODXT:
951 case LINE6_DEVID_PODXTPRO:
952 pod_disconnect(interface);
953 break;
954
955 case LINE6_DEVID_PODXTLIVE:
956 switch(interface_number) {
957 case PODXTLIVE_INTERFACE_POD:
958 pod_disconnect(interface);
959 break;
960
961 case PODXTLIVE_INTERFACE_VARIAX:
962 variax_disconnect(interface);
963 break;
964 }
965
966 break;
967
968 case LINE6_DEVID_VARIAX:
969 variax_disconnect(interface);
970 break;
971
972 case LINE6_DEVID_TONEPORT_GX:
973 case LINE6_DEVID_TONEPORT_UX1:
974 case LINE6_DEVID_TONEPORT_UX2:
975 case LINE6_DEVID_GUITARPORT:
976 toneport_disconnect(interface);
977 break;
978
979 default:
980 MISSING_CASE;
981 }
982
983 dev_info(&interface->dev, "Line6 %s now disconnected\n", line6->properties->name);
984
985 for(i = LINE6_MAX_DEVICES; i--;)
986 if(line6_devices[i] == line6)
987 line6_devices[i] = 0;
988 }
989
990 line6_destruct(interface);
991
992 /* decrement reference counters: */
993 usb_put_intf(interface);
994 usb_put_dev(usbdev);
995
996 line6_list_devices();
997}
998
999static struct usb_driver line6_driver = {
1000#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 16)
1001 .owner = THIS_MODULE,
1002#endif
1003 .name = DRIVER_NAME,
1004 .probe = line6_probe,
1005 .disconnect = line6_disconnect,
1006 .id_table = line6_id_table,
1007};
1008
1009/*
1010 Module initialization.
1011*/
1012static int __init line6_init(void)
1013{
1014 int i, retval;
1015
1016 printk("%s driver version %s%s\n", DRIVER_NAME, DRIVER_VERSION, DRIVER_REVISION);
1017 line6_workqueue = create_workqueue(DRIVER_NAME);
1018
1019 if(line6_workqueue == 0) {
1020 err("couldn't create workqueue");
1021 return -EINVAL;
1022 }
1023
1024 for(i = LINE6_MAX_DEVICES; i--;)
1025 line6_devices[i] = 0;
1026
1027 retval = usb_register(&line6_driver);
1028
1029 if(retval)
1030 err("usb_register failed. Error number %d", retval);
1031
1032 return retval;
1033}
1034
1035/*
1036 Module cleanup.
1037*/
1038static void __exit line6_exit(void)
1039{
1040 destroy_workqueue(line6_workqueue);
1041 usb_deregister(&line6_driver);
1042}
1043
1044module_init(line6_init);
1045module_exit(line6_exit);
1046
1047MODULE_AUTHOR(DRIVER_AUTHOR);
1048MODULE_DESCRIPTION(DRIVER_DESC);
1049MODULE_LICENSE("GPL");
1050MODULE_VERSION(DRIVER_VERSION);
diff --git a/drivers/staging/line6/driver.h b/drivers/staging/line6/driver.h
new file mode 100644
index 000000000000..e5179d99b9f6
--- /dev/null
+++ b/drivers/staging/line6/driver.h
@@ -0,0 +1,190 @@
1/*
2 * Line6 Linux USB driver - 0.8.0
3 *
4 * Copyright (C) 2004-2009 Markus Grabner (grabner@icg.tugraz.at)
5 *
6 * This program is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU General Public License as
8 * published by the Free Software Foundation, version 2.
9 *
10 */
11
12#ifndef DRIVER_H
13#define DRIVER_H
14
15
16#include "config.h"
17
18#include <linux/spinlock.h>
19#include <linux/usb.h>
20#include <linux/wait.h>
21
22#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 25)
23#include <sound/driver.h>
24#endif
25
26#include <sound/core.h>
27
28#include "midi.h"
29
30
31#define DRIVER_NAME "line6usb"
32
33#define LINE6_TIMEOUT 1
34#define LINE6_MAX_DEVICES 8
35#define LINE6_BUFSIZE_LISTEN 32
36#define LINE6_MESSAGE_MAXLEN 256
37
38
39/*
40 Line6 MIDI control commands
41*/
42#define LINE6_PARAM_CHANGE 0xb0
43#define LINE6_PROGRAM_CHANGE 0xc0
44#define LINE6_SYSEX_BEGIN 0xf0
45#define LINE6_SYSEX_END 0xf7
46#define LINE6_RESET 0xff
47
48/*
49 MIDI channel for messages initiated by the host
50 (and eventually echoed back by the device)
51*/
52#define LINE6_CHANNEL_HOST 0x00
53
54/*
55 MIDI channel for messages initiated by the device
56*/
57#define LINE6_CHANNEL_DEVICE 0x02
58
59#define LINE6_CHANNEL_UNKNOWN 5 /* don't know yet what this is good for */
60
61#define LINE6_CHANNEL_MASK 0x0f
62
63
64#define MISSING_CASE printk("line6usb driver bug: missing case in %s:%d\n", __FILE__, __LINE__)
65
66
67#define CHECK_RETURN(x) if((err = x) < 0) return err
68
69
70extern const unsigned char line6_midi_id[3];
71extern struct usb_line6 *line6_devices[LINE6_MAX_DEVICES];
72extern struct workqueue_struct *line6_workqueue;
73
74static const int SYSEX_DATA_OFS = sizeof(line6_midi_id) + 3;
75static const int SYSEX_EXTRA_SIZE = sizeof(line6_midi_id) + 4;
76
77
78/**
79 Common properties of Line6 devices.
80*/
81struct line6_properties {
82 const char *name;
83 int device_bit;
84 int capabilities;
85};
86
87/**
88 Common data shared by all Line6 devices.
89 Corresponds to a pair of USB endpoints.
90*/
91struct usb_line6 {
92 /**
93 USB device.
94 */
95 struct usb_device *usbdev;
96
97 /**
98 Product id.
99 */
100 int product;
101
102 /**
103 Properties.
104 */
105 const struct line6_properties *properties;
106
107 /**
108 Interface number.
109 */
110 int interface_number;
111
112 /**
113 Interval (ms).
114 */
115 int interval;
116
117 /**
118 Maximum size of USB packet.
119 */
120 int max_packet_size;
121
122 /**
123 Device representing the USB interface.
124 */
125 struct device *ifcdev;
126
127 /**
128 Line6 sound card data structure.
129 Each device has at least MIDI or PCM.
130 */
131 struct snd_card *card;
132
133 /**
134 Line6 PCM device data structure.
135 */
136 struct snd_line6_pcm *line6pcm;
137
138 /**
139 Line6 MIDI device data structure.
140 */
141 struct snd_line6_midi *line6midi;
142
143 /**
144 USB endpoint for listening to control commands.
145 */
146 int ep_control_read;
147
148 /**
149 USB endpoint for writing control commands.
150 */
151 int ep_control_write;
152
153 /**
154 URB for listening to PODxt Pro control endpoint.
155 */
156 struct urb *urb_listen;
157
158 /**
159 Buffer for listening to PODxt Pro control endpoint.
160 */
161 unsigned char *buffer_listen;
162
163 /**
164 Buffer for message to be processed.
165 */
166 unsigned char *buffer_message;
167
168 /**
169 Length of message to be processed.
170 */
171 int message_length;
172};
173
174
175extern char *line6_alloc_sysex_buffer(struct usb_line6 *line6, int code1, int code2, int size);
176extern ssize_t line6_nop_read(struct device *dev, DEVICE_ATTRIBUTE char *buf);
177extern ssize_t line6_nop_write(struct device *dev, DEVICE_ATTRIBUTE const char *buf, size_t count);
178extern int line6_read_data(struct usb_line6 *line6, int address, void *data, size_t datalen);
179extern int line6_read_serial_number(struct usb_line6 *line6, int *serial_number);
180extern int line6_send_program(struct usb_line6 *line6, int value);
181extern int line6_send_raw_message(struct usb_line6 *line6, const char *buffer, int size);
182extern int line6_send_raw_message_async(struct usb_line6 *line6, const char *buffer, int size);
183extern int line6_send_sysex_message(struct usb_line6 *line6, const char *buffer, int size);
184extern ssize_t line6_set_raw(struct device *dev, DEVICE_ATTRIBUTE const char *buf, size_t count);
185extern int line6_transmit_parameter(struct usb_line6 *line6, int param, int value);
186extern int line6_write_data(struct usb_line6 *line6, int address, void *data, size_t datalen);
187extern void line6_write_hexdump(struct usb_line6 *line6, char dir, const unsigned char *buffer, int size);
188
189
190#endif
diff --git a/drivers/staging/line6/dumprequest.c b/drivers/staging/line6/dumprequest.c
new file mode 100644
index 000000000000..89bc0994d07b
--- /dev/null
+++ b/drivers/staging/line6/dumprequest.c
@@ -0,0 +1,143 @@
1/*
2 * Line6 Linux USB driver - 0.8.0
3 *
4 * Copyright (C) 2004-2009 Markus Grabner (grabner@icg.tugraz.at)
5 *
6 * This program is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU General Public License as
8 * published by the Free Software Foundation, version 2.
9 *
10 */
11
12#include "driver.h"
13#include "dumprequest.h"
14
15
16/*
17 Set "dump in progress" flag.
18*/
19void line6_dump_started(struct line6_dump_request *l6dr, int dest)
20{
21 l6dr->in_progress = dest;
22}
23
24/*
25 Invalidate current channel, i.e., set "dump in progress" flag.
26 Reading from the "dump" special file blocks until dump is completed.
27*/
28void line6_invalidate_current(struct line6_dump_request *l6dr)
29{
30 line6_dump_started(l6dr, LINE6_DUMP_CURRENT);
31}
32
33/*
34 Clear "dump in progress" flag and notify waiting processes.
35*/
36void line6_dump_finished(struct line6_dump_request *l6dr)
37{
38 l6dr->in_progress = LINE6_DUMP_NONE;
39 wake_up_interruptible(&l6dr->wait);
40}
41
42/*
43 Send an asynchronous channel dump request.
44*/
45int line6_dump_request_async(struct line6_dump_request *l6dr, struct usb_line6 *line6, int num)
46{
47 int ret;
48 line6_invalidate_current(l6dr);
49 ret = line6_send_raw_message_async(line6, l6dr->reqbufs[num].buffer, l6dr->reqbufs[num].length);
50
51 if(ret < 0)
52 line6_dump_finished(l6dr);
53
54 return ret;
55}
56
57/*
58 Send an asynchronous dump request after a given interval.
59*/
60void line6_startup_delayed(struct line6_dump_request *l6dr, int seconds,
61 void (*function)(unsigned long), void *data)
62{
63 l6dr->timer.expires = jiffies + seconds * HZ;
64 l6dr->timer.function = function;
65 l6dr->timer.data = (unsigned long)data;
66 add_timer(&l6dr->timer);
67}
68
69/*
70 Wait for completion.
71*/
72int line6_wait_dump(struct line6_dump_request *l6dr, int nonblock)
73{
74 int retval = 0;
75 DECLARE_WAITQUEUE(wait, current);
76 add_wait_queue(&l6dr->wait, &wait);
77 current->state = TASK_INTERRUPTIBLE;
78
79 while(l6dr->in_progress) {
80 if(nonblock) {
81 retval = -EAGAIN;
82 break;
83 }
84
85 if(signal_pending(current)) {
86 retval = -ERESTARTSYS;
87 break;
88 }
89 else
90 schedule();
91 }
92
93 current->state = TASK_RUNNING;
94 remove_wait_queue(&l6dr->wait, &wait);
95 return retval;
96}
97
98/*
99 Initialize dump request buffer.
100*/
101int line6_dumpreq_initbuf(struct line6_dump_request *l6dr, const void *buf, size_t len, int num)
102{
103 l6dr->reqbufs[num].buffer = kmalloc(len, GFP_KERNEL);
104 if(l6dr->reqbufs[num].buffer == NULL) return -ENOMEM;
105 memcpy(l6dr->reqbufs[num].buffer, buf, len);
106 l6dr->reqbufs[num].length = len;
107 return 0;
108}
109
110/*
111 Initialize dump request data structure (including one buffer).
112*/
113int line6_dumpreq_init(struct line6_dump_request *l6dr, const void *buf, size_t len)
114{
115 int ret;
116 ret = line6_dumpreq_initbuf(l6dr, buf, len, 0);
117 if(ret < 0) return ret;
118 init_waitqueue_head(&l6dr->wait);
119 init_timer(&l6dr->timer);
120 return 0;
121}
122
123/*
124 Destruct dump request data structure.
125*/
126void line6_dumpreq_destructbuf(struct line6_dump_request *l6dr, int num)
127{
128 if(l6dr == NULL) return;
129 if(l6dr->reqbufs[num].buffer == NULL) return;
130 kfree(l6dr->reqbufs[num].buffer);
131 l6dr->reqbufs[num].buffer = NULL;
132}
133
134/*
135 Destruct dump request data structure.
136*/
137void line6_dumpreq_destruct(struct line6_dump_request *l6dr)
138{
139 if(l6dr->reqbufs[0].buffer == NULL) return;
140 line6_dumpreq_destructbuf(l6dr, 0);
141 l6dr->ok = 1;
142 del_timer_sync(&l6dr->timer);
143}
diff --git a/drivers/staging/line6/dumprequest.h b/drivers/staging/line6/dumprequest.h
new file mode 100644
index 000000000000..e0b38bbc1ad2
--- /dev/null
+++ b/drivers/staging/line6/dumprequest.h
@@ -0,0 +1,87 @@
1/*
2 * Line6 Linux USB driver - 0.8.0
3 *
4 * Copyright (C) 2004-2009 Markus Grabner (grabner@icg.tugraz.at)
5 *
6 * This program is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU General Public License as
8 * published by the Free Software Foundation, version 2.
9 *
10 */
11
12#ifndef DUMPREQUEST_H
13#define DUMPREQUEST_H
14
15
16#include <linux/usb.h>
17#include <linux/wait.h>
18
19#include <sound/core.h>
20
21
22enum {
23 LINE6_DUMP_NONE,
24 LINE6_DUMP_CURRENT
25};
26
27
28struct line6_dump_reqbuf {
29 /**
30 Buffer for dump requests.
31 */
32 unsigned char *buffer;
33
34 /**
35 Size of dump request.
36 */
37 size_t length;
38};
39
40/**
41 Provides the functionality to request channel/model/... dump data from a
42 Line6 device.
43*/
44struct line6_dump_request {
45 /**
46 Wait queue for access to program dump data.
47 */
48 wait_queue_head_t wait;
49
50 /**
51 Indicates an unfinished program dump request.
52 0: no dump
53 1: dump current settings
54 Other device-specific values are also allowed.
55 */
56 int in_progress;
57
58 /**
59 Timer for delayed dump request.
60 */
61 struct timer_list timer;
62
63 /**
64 Flag if initial dump request has been successful.
65 */
66 char ok;
67
68 /**
69 Dump request buffers
70 */
71 struct line6_dump_reqbuf reqbufs[1];
72};
73
74extern void line6_dump_finished(struct line6_dump_request *l6dr);
75extern int line6_dump_request_async(struct line6_dump_request *l6dr, struct usb_line6 *line6, int num);
76extern void line6_dump_started(struct line6_dump_request *l6dr, int dest);
77extern void line6_dumpreq_destruct(struct line6_dump_request *l6dr);
78extern void line6_dumpreq_destructbuf(struct line6_dump_request *l6dr, int num);
79extern int line6_dumpreq_init(struct line6_dump_request *l6dr, const void *buf, size_t len);
80extern int line6_dumpreq_initbuf(struct line6_dump_request *l6dr, const void *buf, size_t len, int num);
81extern void line6_invalidate_current(struct line6_dump_request *l6dr);
82extern void line6_startup_delayed(struct line6_dump_request *l6dr, int seconds,
83 void (*function)(unsigned long), void *data);
84extern int line6_wait_dump(struct line6_dump_request *l6dr, int nonblock);
85
86
87#endif
diff --git a/drivers/staging/line6/midi.c b/drivers/staging/line6/midi.c
new file mode 100644
index 000000000000..74489ee77bff
--- /dev/null
+++ b/drivers/staging/line6/midi.c
@@ -0,0 +1,398 @@
1/*
2 * Line6 Linux USB driver - 0.8.0
3 *
4 * Copyright (C) 2004-2009 Markus Grabner (grabner@icg.tugraz.at)
5 *
6 * This program is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU General Public License as
8 * published by the Free Software Foundation, version 2.
9 *
10 */
11
12#include "driver.h"
13
14#include <linux/usb.h>
15
16#include <sound/core.h>
17#include <sound/rawmidi.h>
18
19#include "audio.h"
20#include "midi.h"
21#include "pod.h"
22#include "usbdefs.h"
23
24
25#define USE_MIDIBUF 1
26#define OUTPUT_DUMP_ONLY 0
27
28
29#define line6_rawmidi_substream_midi(substream) ((struct snd_line6_midi *)((substream)->rmidi->private_data))
30
31
32static int send_midi_async(struct usb_line6 *line6, unsigned char *data, int length);
33
34
35/*
36 Pass data received via USB to MIDI.
37*/
38void line6_midi_receive(struct usb_line6 *line6, unsigned char *data, int length)
39{
40 if(line6->line6midi->substream_receive)
41 snd_rawmidi_receive(line6->line6midi->substream_receive, data, length);
42}
43
44/*
45 Read data from MIDI buffer and transmit them via USB.
46*/
47static void line6_midi_transmit(struct snd_rawmidi_substream *substream)
48{
49 struct usb_line6 *line6 = line6_rawmidi_substream_midi(substream)->line6;
50 struct snd_line6_midi *line6midi = line6->line6midi;
51 struct MidiBuffer *mb = &line6midi->midibuf_out;
52 unsigned long flags;
53 unsigned char chunk[line6->max_packet_size];
54 int req, done;
55
56 spin_lock_irqsave(&line6->line6midi->midi_transmit_lock, flags);
57
58 for(;;) {
59 req = min(midibuf_bytes_free(mb), line6->max_packet_size);
60 done = snd_rawmidi_transmit_peek(substream, chunk, req);
61
62 if(done == 0)
63 break;
64
65#if DO_DUMP_MIDI_SEND
66 line6_write_hexdump(line6, 's', chunk, done);
67#endif
68 midibuf_write(mb, chunk, done);
69 snd_rawmidi_transmit_ack(substream, done);
70 }
71
72 for(;;) {
73 done = midibuf_read(mb, chunk, line6->max_packet_size);
74
75 if(done == 0)
76 break;
77
78 if(midibuf_skip_message(mb, line6midi->midi_mask_transmit))
79 continue;
80
81 send_midi_async(line6, chunk, done);
82 }
83
84 spin_unlock_irqrestore(&line6->line6midi->midi_transmit_lock, flags);
85}
86
87/*
88 Notification of completion of MIDI transmission.
89*/
90static void midi_sent(struct urb *urb PT_REGS)
91{
92 unsigned long flags;
93 int status;
94 int num;
95 struct usb_line6 *line6 = (struct usb_line6 *)urb->context;
96
97 status = urb->status;
98 kfree(urb->transfer_buffer);
99 usb_free_urb(urb);
100
101 if(status == -ESHUTDOWN)
102 return;
103
104 spin_lock_irqsave(&line6->line6midi->send_urb_lock, flags);
105 num = --line6->line6midi->num_active_send_urbs;
106
107 if(num == 0) {
108 line6_midi_transmit(line6->line6midi->substream_transmit);
109 num = line6->line6midi->num_active_send_urbs;
110 }
111
112 if(num == 0)
113 wake_up_interruptible(&line6->line6midi->send_wait);
114
115 spin_unlock_irqrestore(&line6->line6midi->send_urb_lock, flags);
116}
117
118/*
119 Send an asynchronous MIDI message.
120 Assumes that line6->line6midi->send_urb_lock is held
121 (i.e., this function is serialized).
122*/
123static int send_midi_async(struct usb_line6 *line6, unsigned char *data, int length)
124{
125 struct urb *urb;
126 int retval;
127 unsigned char *transfer_buffer;
128
129 urb = usb_alloc_urb(0, GFP_ATOMIC);
130
131 if(urb == 0) {
132 dev_err(line6->ifcdev, "Out of memory\n");
133 return -ENOMEM;
134 }
135
136#if DO_DUMP_URB_SEND
137 line6_write_hexdump(line6, 'S', data, length);
138#endif
139
140 transfer_buffer = (unsigned char *)kmalloc(length, GFP_ATOMIC);
141
142 if(transfer_buffer == 0) {
143 usb_free_urb(urb);
144 dev_err(line6->ifcdev, "Out of memory\n");
145 return -ENOMEM;
146 }
147
148 memcpy(transfer_buffer, data, length);
149 usb_fill_int_urb(urb,
150 line6->usbdev,
151 usb_sndbulkpipe(line6->usbdev, line6->ep_control_write),
152 transfer_buffer, length, midi_sent, line6, line6->interval);
153 urb->actual_length = 0;
154 retval = usb_submit_urb(urb, GFP_ATOMIC);
155
156 if(retval < 0) {
157 dev_err(line6->ifcdev, "usb_submit_urb failed\n");
158 usb_free_urb(urb);
159 return -EINVAL;
160 }
161
162 ++line6->line6midi->num_active_send_urbs;
163
164 switch(line6->usbdev->descriptor.idProduct) {
165 case LINE6_DEVID_BASSPODXT:
166 case LINE6_DEVID_BASSPODXTLIVE:
167 case LINE6_DEVID_BASSPODXTPRO:
168 case LINE6_DEVID_PODXT:
169 case LINE6_DEVID_PODXTLIVE:
170 case LINE6_DEVID_PODXTPRO:
171 case LINE6_DEVID_POCKETPOD:
172 pod_midi_postprocess((struct usb_line6_pod *)line6, data, length);
173 break;
174
175 default:
176 MISSING_CASE;
177 }
178
179 return 0;
180}
181
182static int line6_midi_output_open(struct snd_rawmidi_substream *substream)
183{
184 return 0;
185}
186
187static int line6_midi_output_close(struct snd_rawmidi_substream *substream)
188{
189 return 0;
190}
191
192static void line6_midi_output_trigger(struct snd_rawmidi_substream *substream, int up)
193{
194 unsigned long flags;
195 struct usb_line6 *line6 = line6_rawmidi_substream_midi(substream)->line6;
196
197 line6->line6midi->substream_transmit = substream;
198 spin_lock_irqsave(&line6->line6midi->send_urb_lock, flags);
199
200 if(line6->line6midi->num_active_send_urbs == 0)
201 line6_midi_transmit(substream);
202
203 spin_unlock_irqrestore(&line6->line6midi->send_urb_lock, flags);
204}
205
206static void line6_midi_output_drain(struct snd_rawmidi_substream *substream)
207{
208 struct usb_line6 *line6 = line6_rawmidi_substream_midi(substream)->line6;
209 wait_queue_head_t *head = &line6->line6midi->send_wait;
210 DECLARE_WAITQUEUE(wait, current);
211 add_wait_queue(head, &wait);
212 current->state = TASK_INTERRUPTIBLE;
213
214 while(line6->line6midi->num_active_send_urbs > 0)
215 if(signal_pending(current))
216 break;
217 else
218 schedule();
219
220 current->state = TASK_RUNNING;
221 remove_wait_queue(head, &wait);
222}
223
224static int line6_midi_input_open(struct snd_rawmidi_substream *substream)
225{
226 return 0;
227}
228
229static int line6_midi_input_close(struct snd_rawmidi_substream *substream)
230{
231 return 0;
232}
233
234static void line6_midi_input_trigger(struct snd_rawmidi_substream *substream, int up)
235{
236 struct usb_line6 *line6 = line6_rawmidi_substream_midi(substream)->line6;
237
238 if(up)
239 line6->line6midi->substream_receive = substream;
240 else
241 line6->line6midi->substream_receive = 0;
242}
243
244static struct snd_rawmidi_ops line6_midi_output_ops = {
245 .open = line6_midi_output_open,
246 .close = line6_midi_output_close,
247 .trigger = line6_midi_output_trigger,
248 .drain = line6_midi_output_drain,
249};
250
251static struct snd_rawmidi_ops line6_midi_input_ops = {
252 .open = line6_midi_input_open,
253 .close = line6_midi_input_close,
254 .trigger = line6_midi_input_trigger,
255};
256
257/*
258 Cleanup the Line6 MIDI device.
259*/
260static void line6_cleanup_midi(struct snd_rawmidi *rmidi)
261{
262}
263
264/* Create a MIDI device */
265static int snd_line6_new_midi(struct snd_line6_midi *line6midi)
266{
267 struct snd_rawmidi *rmidi;
268 int err;
269
270 if((err = snd_rawmidi_new(line6midi->line6->card, "Line6 MIDI", 0, 1, 1, &rmidi)) < 0)
271 return err;
272
273 rmidi->private_data = line6midi;
274 rmidi->private_free = line6_cleanup_midi;
275 strcpy(rmidi->name, line6midi->line6->properties->name);
276
277 rmidi->info_flags =
278 SNDRV_RAWMIDI_INFO_OUTPUT |
279 SNDRV_RAWMIDI_INFO_INPUT |
280 SNDRV_RAWMIDI_INFO_DUPLEX;
281
282 snd_rawmidi_set_ops(rmidi, SNDRV_RAWMIDI_STREAM_OUTPUT, &line6_midi_output_ops);
283 snd_rawmidi_set_ops(rmidi, SNDRV_RAWMIDI_STREAM_INPUT, &line6_midi_input_ops);
284 return 0;
285}
286
287/*
288 "read" request on "midi_mask_transmit" special file.
289*/
290static ssize_t midi_get_midi_mask_transmit(struct device *dev, DEVICE_ATTRIBUTE char *buf)
291{
292 struct usb_interface *interface = to_usb_interface(dev);
293 struct usb_line6 *line6 = usb_get_intfdata(interface);
294 return sprintf(buf, "%d\n", line6->line6midi->midi_mask_transmit);
295}
296
297/*
298 "write" request on "midi_mask" special file.
299*/
300static ssize_t midi_set_midi_mask_transmit(struct device *dev, DEVICE_ATTRIBUTE const char *buf, size_t count)
301{
302 struct usb_interface *interface = to_usb_interface(dev);
303 struct usb_line6 *line6 = usb_get_intfdata(interface);
304 int value = simple_strtoul(buf, NULL, 10);
305 line6->line6midi->midi_mask_transmit = value;
306 return count;
307}
308
309/*
310 "read" request on "midi_mask_receive" special file.
311*/
312static ssize_t midi_get_midi_mask_receive(struct device *dev, DEVICE_ATTRIBUTE char *buf)
313{
314 struct usb_interface *interface = to_usb_interface(dev);
315 struct usb_line6 *line6 = usb_get_intfdata(interface);
316 return sprintf(buf, "%d\n", line6->line6midi->midi_mask_receive);
317}
318
319/*
320 "write" request on "midi_mask" special file.
321*/
322static ssize_t midi_set_midi_mask_receive(struct device *dev, DEVICE_ATTRIBUTE const char *buf, size_t count)
323{
324 struct usb_interface *interface = to_usb_interface(dev);
325 struct usb_line6 *line6 = usb_get_intfdata(interface);
326 int value = simple_strtoul(buf, NULL, 10);
327 line6->line6midi->midi_mask_receive = value;
328 return count;
329}
330
331static DEVICE_ATTR(midi_mask_transmit, S_IWUGO | S_IRUGO, midi_get_midi_mask_transmit, midi_set_midi_mask_transmit);
332static DEVICE_ATTR(midi_mask_receive, S_IWUGO | S_IRUGO, midi_get_midi_mask_receive, midi_set_midi_mask_receive);
333
334/* MIDI device destructor */
335static int snd_line6_midi_free(struct snd_device *device)
336{
337 struct snd_line6_midi *line6midi = device->device_data;
338 device_remove_file(line6midi->line6->ifcdev, &dev_attr_midi_mask_transmit);
339 device_remove_file(line6midi->line6->ifcdev, &dev_attr_midi_mask_receive);
340 midibuf_destroy(&line6midi->midibuf_in);
341 midibuf_destroy(&line6midi->midibuf_out);
342 return 0;
343}
344
345/*
346 Initialize the Line6 MIDI subsystem.
347*/
348int line6_init_midi(struct usb_line6 *line6)
349{
350 static struct snd_device_ops midi_ops = {
351 .dev_free = snd_line6_midi_free,
352 };
353
354 int err;
355 struct snd_line6_midi *line6midi;
356
357 if(!(line6->properties->capabilities & LINE6_BIT_CONTROL))
358 return 0; /* skip MIDI initialization and report success */
359
360 line6midi = kzalloc(sizeof(struct snd_line6_midi), GFP_KERNEL);
361
362 if(line6midi == NULL)
363 return -ENOMEM;
364
365 err = midibuf_init(&line6midi->midibuf_in, MIDI_BUFFER_SIZE, 0);
366
367 if(err < 0)
368 return err;
369
370 err = midibuf_init(&line6midi->midibuf_out, MIDI_BUFFER_SIZE, 1);
371
372 if(err < 0)
373 return err;
374
375 line6midi->line6 = line6;
376 line6midi->midi_mask_transmit = 1;
377 line6midi->midi_mask_receive = 4;
378 line6->line6midi = line6midi;
379
380 if((err = snd_device_new(line6->card, SNDRV_DEV_RAWMIDI, line6midi, &midi_ops)) < 0)
381 return err;
382
383 snd_card_set_dev(line6->card, line6->ifcdev);
384
385 if((err = snd_line6_new_midi(line6midi)) < 0)
386 return err;
387
388 if((err = device_create_file(line6->ifcdev, &dev_attr_midi_mask_transmit)) < 0)
389 return err;
390
391 if((err = device_create_file(line6->ifcdev, &dev_attr_midi_mask_receive)) < 0)
392 return err;
393
394 init_waitqueue_head(&line6midi->send_wait);
395 spin_lock_init(&line6midi->send_urb_lock);
396 spin_lock_init(&line6midi->midi_transmit_lock);
397 return 0;
398}
diff --git a/drivers/staging/line6/midi.h b/drivers/staging/line6/midi.h
new file mode 100644
index 000000000000..be05a54205c4
--- /dev/null
+++ b/drivers/staging/line6/midi.h
@@ -0,0 +1,87 @@
1/*
2 * Line6 Linux USB driver - 0.8.0
3 *
4 * Copyright (C) 2004-2009 Markus Grabner (grabner@icg.tugraz.at)
5 *
6 * This program is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU General Public License as
8 * published by the Free Software Foundation, version 2.
9 *
10 */
11
12#ifndef MIDI_H
13#define MIDI_H
14
15
16#include <sound/rawmidi.h>
17
18#include "midibuf.h"
19
20
21#define MIDI_BUFFER_SIZE 1024
22
23
24struct snd_line6_midi
25{
26 /**
27 Pointer back to the Line6 driver data structure.
28 */
29 struct usb_line6 *line6;
30
31 /**
32 MIDI substream for receiving (or NULL if not active).
33 */
34 struct snd_rawmidi_substream *substream_receive;
35
36 /**
37 MIDI substream for transmitting (or NULL if not active).
38 */
39 struct snd_rawmidi_substream *substream_transmit;
40
41 /**
42 Number of currently active MIDI send URBs.
43 */
44 int num_active_send_urbs;
45
46 /**
47 Spin lock to protect updates of send_urb.
48 */
49 spinlock_t send_urb_lock;
50
51 /**
52 Spin lock to protect MIDI buffer handling.
53 */
54 spinlock_t midi_transmit_lock;
55
56 /**
57 Wait queue for MIDI transmission.
58 */
59 wait_queue_head_t send_wait;
60
61 /**
62 Bit mask for output MIDI channels.
63 */
64 int midi_mask_transmit;
65
66 /**
67 Bit mask for input MIDI channels.
68 */
69 int midi_mask_receive;
70
71 /**
72 Buffer for incoming MIDI stream.
73 */
74 struct MidiBuffer midibuf_in;
75
76 /**
77 Buffer for outgoing MIDI stream.
78 */
79 struct MidiBuffer midibuf_out;
80};
81
82
83extern int line6_init_midi(struct usb_line6 *line6);
84extern void line6_midi_receive(struct usb_line6 *line6, unsigned char *data, int length);
85
86
87#endif
diff --git a/drivers/staging/line6/midibuf.c b/drivers/staging/line6/midibuf.c
new file mode 100644
index 000000000000..2f86c6692516
--- /dev/null
+++ b/drivers/staging/line6/midibuf.c
@@ -0,0 +1,268 @@
1/*
2 * Line6 Linux USB driver - 0.8.0
3 *
4 * Copyright (C) 2004-2009 Markus Grabner (grabner@icg.tugraz.at)
5 *
6 * This program is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU General Public License as
8 * published by the Free Software Foundation, version 2.
9 *
10 */
11
12#include "config.h"
13
14#include <linux/slab.h>
15
16#include "midibuf.h"
17
18
19int midibuf_message_length(unsigned char code)
20{
21 if(code < 0x80)
22 return -1;
23 else if(code < 0xf0) {
24 static const int length[] = { 3, 3, 3, 3, 2, 2, 3 };
25 return length[(code >> 4) - 8];
26 }
27 else {
28 /*
29 Note that according to the MIDI specification 0xf2 is the "Song Position
30 Pointer", but this is used by Line6 to send sysex messages to the host.
31 */
32 static const int length[] = { -1, 2, -1, 2, -1, -1, 1, 1, 1, 1, 1, 1, 1, -1, 1, 1 };
33 return length[code & 0x0f];
34 }
35}
36
37void midibuf_reset(struct MidiBuffer *this)
38{
39 this->pos_read = this->pos_write = this->full = 0;
40 this->command_prev = -1;
41}
42
43int midibuf_init(struct MidiBuffer *this, int size, int split)
44{
45 this->buf = (unsigned char *)kmalloc(size, GFP_KERNEL);
46
47 if(this->buf == 0)
48 return -ENOMEM;
49
50 this->size = size;
51 this->split = split;
52 midibuf_reset(this);
53 return 0;
54}
55
56void midibuf_status(struct MidiBuffer *this)
57{
58 printk("midibuf size=%d split=%d pos_read=%d pos_write=%d full=%d command_prev=%02x\n",
59 this->size, this->split, this->pos_read, this->pos_write, this->full, this->command_prev);
60}
61
62int midibuf_is_empty(struct MidiBuffer *this)
63{
64 return (this->pos_read == this->pos_write) && !this->full;
65}
66
67int midibuf_is_full(struct MidiBuffer *this)
68{
69 return this->full;
70}
71
72int midibuf_bytes_free(struct MidiBuffer *this)
73{
74 return
75 midibuf_is_full(this) ?
76 0 :
77 (this->pos_read - this->pos_write + this->size - 1) % this->size + 1;
78}
79
80int midibuf_bytes_used(struct MidiBuffer *this)
81{
82 return
83 midibuf_is_empty(this) ?
84 0 :
85 (this->pos_write - this->pos_read + this->size - 1) % this->size + 1;
86}
87
88int midibuf_write(struct MidiBuffer *this, unsigned char *data, int length)
89{
90 int bytes_free;
91 int length1, length2;
92 int skip_active_sense = 0;
93
94 if(midibuf_is_full(this) || (length <= 0))
95 return 0;
96
97 /* skip trailing active sense */
98 if(data[length - 1] == 0xfe) {
99 --length;
100 skip_active_sense = 1;
101 }
102
103 bytes_free = midibuf_bytes_free(this);
104
105 if(length > bytes_free)
106 length = bytes_free;
107
108 if(length > 0) {
109 length1 = this->size - this->pos_write;
110
111 if(length < length1) {
112 /* no buffer wraparound */
113 memcpy(this->buf + this->pos_write, data, length);
114 this->pos_write += length;
115 }
116 else {
117 /* buffer wraparound */
118 length2 = length - length1;
119 memcpy(this->buf + this->pos_write, data, length1);
120 memcpy(this->buf, data + length1, length2);
121 this->pos_write = length2;
122 }
123
124 if(this->pos_write == this->pos_read)
125 this->full = 1;
126 }
127
128 return length + skip_active_sense;
129}
130
131int midibuf_read(struct MidiBuffer *this, unsigned char *data, int length)
132{
133 int bytes_used;
134 int length1, length2;
135 int command;
136 int midi_length;
137 int repeat = 0;
138 int i;
139
140 if(length < 3)
141 return -EINVAL; /* we need to be able to store at least a 3 byte MIDI message */
142
143 if(midibuf_is_empty(this))
144 return 0;
145
146 bytes_used = midibuf_bytes_used(this);
147
148 if(length > bytes_used)
149 length = bytes_used;
150
151 length1 = this->size - this->pos_read;
152
153 /* check MIDI command length */
154 command = this->buf[this->pos_read];
155
156 if(command & 0x80) {
157 midi_length = midibuf_message_length(command);
158 this->command_prev = command;
159 }
160 else {
161 if(this->command_prev > 0) {
162 int midi_length_prev = midibuf_message_length(this->command_prev);
163
164 if(midi_length_prev > 0) {
165 midi_length = midi_length_prev - 1;
166 repeat = 1;
167 }
168 else
169 midi_length = -1;
170 }
171 else
172 midi_length = -1;
173 }
174
175 if(midi_length < 0) {
176 /* search for end of message */
177 if(length < length1) {
178 /* no buffer wraparound */
179 for(i = 1; i < length; ++i)
180 if(this->buf[this->pos_read + i] & 0x80)
181 break;
182
183 midi_length = i;
184 }
185 else {
186 /* buffer wraparound */
187 length2 = length - length1;
188
189 for(i = 1; i < length1; ++i)
190 if(this->buf[this->pos_read + i] & 0x80)
191 break;
192
193 if(i < length1)
194 midi_length = i;
195 else {
196 for(i = 0; i < length2; ++i)
197 if(this->buf[i] & 0x80)
198 break;
199
200 midi_length = length1 + i;
201 }
202 }
203
204 if(midi_length == length)
205 midi_length = -1; /* end of message not found */
206 }
207
208 if(midi_length < 0) {
209 if(!this->split)
210 return 0; /* command is not yet complete */
211 }
212 else {
213 if(length < midi_length)
214 return 0; /* command is not yet complete */
215
216 length = midi_length;
217 }
218
219 if(length < length1) {
220 /* no buffer wraparound */
221 memcpy(data + repeat, this->buf + this->pos_read, length);
222 this->pos_read += length;
223 }
224 else {
225 /* buffer wraparound */
226 length2 = length - length1;
227 memcpy(data + repeat, this->buf + this->pos_read, length1);
228 memcpy(data + repeat + length1, this->buf, length2);
229 this->pos_read = length2;
230 }
231
232 if(repeat)
233 data[0] = this->command_prev;
234
235 this->full = 0;
236 return length + repeat;
237}
238
239int midibuf_ignore(struct MidiBuffer *this, int length)
240{
241 int bytes_used = midibuf_bytes_used(this);
242
243 if(length > bytes_used)
244 length = bytes_used;
245
246 this->pos_read = (this->pos_read + length) % this->size;
247 this->full = 0;
248 return length;
249}
250
251int midibuf_skip_message(struct MidiBuffer *this, unsigned short mask)
252{
253 int cmd = this->command_prev;
254
255 if((cmd >= 0x80) && (cmd < 0xf0))
256 if((mask & (1 << (cmd & 0x0f))) == 0)
257 return 1;
258
259 return 0;
260}
261
262void midibuf_destroy(struct MidiBuffer *this)
263{
264 if(this->buf != 0) {
265 kfree(this->buf);
266 this->buf = 0;
267 }
268}
diff --git a/drivers/staging/line6/midibuf.h b/drivers/staging/line6/midibuf.h
new file mode 100644
index 000000000000..0e7762c677c4
--- /dev/null
+++ b/drivers/staging/line6/midibuf.h
@@ -0,0 +1,39 @@
1/*
2 * Line6 Linux USB driver - 0.8.0
3 *
4 * Copyright (C) 2004-2009 Markus Grabner (grabner@icg.tugraz.at)
5 *
6 * This program is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU General Public License as
8 * published by the Free Software Foundation, version 2.
9 *
10 */
11
12#ifndef MIDIBUF_H
13#define MIDIBUF_H
14
15
16struct MidiBuffer
17{
18 unsigned char *buf;
19 int size;
20 int split;
21 int pos_read, pos_write;
22 int full;
23 int command_prev;
24};
25
26
27extern int midibuf_bytes_used(struct MidiBuffer *mb);
28extern int midibuf_bytes_free(struct MidiBuffer *mb);
29extern void midibuf_destroy(struct MidiBuffer *mb);
30extern int midibuf_ignore(struct MidiBuffer *mb, int length);
31extern int midibuf_init(struct MidiBuffer *mb, int size, int split);
32extern int midibuf_read(struct MidiBuffer *mb, unsigned char *data, int length);
33extern void midibuf_reset(struct MidiBuffer *mb);
34extern int midibuf_skip_message(struct MidiBuffer *mb, unsigned short mask);
35extern void midibuf_status(struct MidiBuffer *mb);
36extern int midibuf_write(struct MidiBuffer *mb, unsigned char *data, int length);
37
38
39#endif
diff --git a/drivers/staging/line6/pcm.c b/drivers/staging/line6/pcm.c
new file mode 100644
index 000000000000..725184b2f308
--- /dev/null
+++ b/drivers/staging/line6/pcm.c
@@ -0,0 +1,289 @@
1/*
2 * Line6 Linux USB driver - 0.8.0
3 *
4 * Copyright (C) 2004-2009 Markus Grabner (grabner@icg.tugraz.at)
5 *
6 * This program is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU General Public License as
8 * published by the Free Software Foundation, version 2.
9 *
10 */
11
12#include "driver.h"
13
14#include <sound/core.h>
15#include <sound/control.h>
16#include <sound/pcm.h>
17#include <sound/pcm_params.h>
18
19#include "audio.h"
20#include "capture.h"
21#include "playback.h"
22#include "pod.h"
23
24
25/* trigger callback */
26int snd_line6_trigger(struct snd_pcm_substream *substream, int cmd)
27{
28 struct snd_line6_pcm *line6pcm = snd_pcm_substream_chip(substream);
29#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 22)
30 struct list_head *pos;
31#endif
32 struct snd_pcm_substream *s;
33 int err;
34 unsigned long flags;
35
36 spin_lock_irqsave(&line6pcm->lock_trigger, flags);
37 clear_bit(BIT_PREPARED, &line6pcm->flags);
38
39#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 22)
40 snd_pcm_group_for_each(pos, substream) {
41 s = snd_pcm_group_substream_entry(pos);
42#else
43 snd_pcm_group_for_each_entry(s, substream) {
44#endif
45 switch(s->stream) {
46 case SNDRV_PCM_STREAM_PLAYBACK:
47 err = snd_line6_playback_trigger(s, cmd);
48
49 if(err < 0) {
50 spin_unlock_irqrestore(&line6pcm->lock_trigger, flags);
51 return err;
52 }
53
54 break;
55
56 case SNDRV_PCM_STREAM_CAPTURE:
57 err = snd_line6_capture_trigger(s, cmd);
58
59 if(err < 0) {
60 spin_unlock_irqrestore(&line6pcm->lock_trigger, flags);
61 return err;
62 }
63
64 break;
65
66 default:
67 dev_err(s2m(substream), "Unknown stream direction %d\n", s->stream);
68 }
69 }
70
71 spin_unlock_irqrestore(&line6pcm->lock_trigger, flags);
72 return 0;
73}
74
75/* control info callback */
76static int snd_line6_control_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo) {
77 uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
78 uinfo->count = 2;
79 uinfo->value.integer.min = 0;
80 uinfo->value.integer.max = 256;
81 return 0;
82}
83
84/* control get callback */
85static int snd_line6_control_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) {
86 int i;
87 struct snd_line6_pcm *line6pcm = snd_kcontrol_chip(kcontrol);
88
89 for(i = 2; i--;)
90 ucontrol->value.integer.value[i] = line6pcm->volume[i];
91
92 return 0;
93}
94
95/* control put callback */
96static int snd_line6_control_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) {
97 int i, changed = 0;
98 struct snd_line6_pcm *line6pcm = snd_kcontrol_chip(kcontrol);
99
100 for(i = 2; i--;)
101 if(line6pcm->volume[i] != ucontrol->value.integer.value[i]) {
102 line6pcm->volume[i] = ucontrol->value.integer.value[i];
103 changed = 1;
104 }
105
106 return changed;
107}
108
109/* control definition */
110static struct snd_kcontrol_new line6_control = {
111 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
112 .name = "PCM Playback Volume",
113 .index = 0,
114 .access = SNDRV_CTL_ELEM_ACCESS_READWRITE,
115 .info = snd_line6_control_info,
116 .get = snd_line6_control_get,
117 .put = snd_line6_control_put
118};
119
120/*
121 Cleanup the PCM device.
122*/
123static void line6_cleanup_pcm(struct snd_pcm *pcm)
124{
125 int i;
126 struct snd_line6_pcm *line6pcm = snd_pcm_chip(pcm);
127
128 for(i = LINE6_ISO_BUFFERS; i--;) {
129 if(line6pcm->urb_audio_out[i]) {
130 usb_kill_urb(line6pcm->urb_audio_out[i]);
131 usb_free_urb(line6pcm->urb_audio_out[i]);
132 }
133 if(line6pcm->urb_audio_in[i]) {
134 usb_kill_urb(line6pcm->urb_audio_in[i]);
135 usb_free_urb(line6pcm->urb_audio_in[i]);
136 }
137 }
138}
139
140/* create a PCM device */
141static int snd_line6_new_pcm(struct snd_line6_pcm *line6pcm)
142{
143 struct snd_pcm *pcm;
144 int err;
145
146 if((err = snd_pcm_new(line6pcm->line6->card, (char *)line6pcm->line6->properties->name, 0, 1, 1, &pcm)) < 0)
147 return err;
148
149 pcm->private_data = line6pcm;
150 pcm->private_free = line6_cleanup_pcm;
151 line6pcm->pcm = pcm;
152 strcpy(pcm->name, line6pcm->line6->properties->name);
153
154 /* set operators */
155 snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK, &snd_line6_playback_ops);
156 snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_CAPTURE, &snd_line6_capture_ops);
157
158 /* pre-allocation of buffers */
159 snd_pcm_lib_preallocate_pages_for_all(pcm,
160 SNDRV_DMA_TYPE_CONTINUOUS,
161 snd_dma_continuous_data(GFP_KERNEL),
162 64 * 1024, 128 * 1024);
163
164 return 0;
165}
166
167/* PCM device destructor */
168static int snd_line6_pcm_free(struct snd_device *device)
169{
170 return 0;
171}
172
173/*
174 Create and register the PCM device and mixer entries.
175 Create URBs for playback and capture.
176*/
177int line6_init_pcm(struct usb_line6 *line6, struct line6_pcm_properties *properties)
178{
179 static struct snd_device_ops pcm_ops = {
180 .dev_free = snd_line6_pcm_free,
181 };
182
183 int err;
184 int ep_read = 0, ep_write = 0;
185 struct snd_line6_pcm *line6pcm;
186
187 if(!(line6->properties->capabilities & LINE6_BIT_PCM))
188 return 0; /* skip PCM initialization and report success */
189
190 /* initialize PCM subsystem based on product id: */
191 switch(line6->product) {
192 case LINE6_DEVID_BASSPODXT:
193 case LINE6_DEVID_BASSPODXTLIVE:
194 case LINE6_DEVID_BASSPODXTPRO:
195 case LINE6_DEVID_PODXT:
196 case LINE6_DEVID_PODXTLIVE:
197 case LINE6_DEVID_PODXTPRO:
198 ep_read = 0x82;
199 ep_write = 0x01;
200 break;
201
202 case LINE6_DEVID_PODX3:
203 case LINE6_DEVID_PODX3LIVE:
204 ep_read = 0x86;
205 ep_write = 0x02;
206 break;
207
208 case LINE6_DEVID_POCKETPOD:
209 ep_read = 0x82;
210 ep_write = 0x02;
211 break;
212
213 case LINE6_DEVID_GUITARPORT:
214 case LINE6_DEVID_TONEPORT_GX:
215 ep_read = 0x82;
216 ep_write = 0x01;
217 break;
218
219 case LINE6_DEVID_TONEPORT_UX1:
220 ep_read = 0x00;
221 ep_write = 0x00;
222 break;
223
224 case LINE6_DEVID_TONEPORT_UX2:
225 ep_read = 0x87;
226 ep_write = 0x00;
227 break;
228
229 default:
230 MISSING_CASE;
231 }
232
233 line6pcm = kzalloc(sizeof(struct snd_line6_pcm), GFP_KERNEL);
234
235 if(line6pcm == NULL)
236 return -ENOMEM;
237
238 line6pcm->volume[0] = line6pcm->volume[1] = 128;
239 line6pcm->line6 = line6;
240 line6pcm->ep_audio_read = ep_read;
241 line6pcm->ep_audio_write = ep_write;
242 line6pcm->max_packet_size = usb_maxpacket(line6->usbdev, usb_rcvintpipe(line6->usbdev, ep_read), 0);
243 line6pcm->properties = properties;
244 line6->line6pcm = line6pcm;
245
246 /* PCM device: */
247 if((err = snd_device_new(line6->card, SNDRV_DEV_PCM, line6, &pcm_ops)) < 0)
248 return err;
249
250 snd_card_set_dev(line6->card, line6->ifcdev);
251
252 if((err = snd_line6_new_pcm(line6pcm)) < 0)
253 return err;
254
255 spin_lock_init(&line6pcm->lock_audio_out);
256 spin_lock_init(&line6pcm->lock_audio_in);
257 spin_lock_init(&line6pcm->lock_trigger);
258
259 if((err = create_audio_out_urbs(line6pcm)) < 0)
260 return err;
261
262 if((err = create_audio_in_urbs(line6pcm)) < 0)
263 return err;
264
265 /* mixer: */
266 if((err = snd_ctl_add(line6->card, snd_ctl_new1(&line6_control, line6pcm))) < 0)
267 return err;
268
269 return 0;
270}
271
272/* prepare pcm callback */
273int snd_line6_prepare(struct snd_pcm_substream *substream)
274{
275 struct snd_line6_pcm *line6pcm = snd_pcm_substream_chip(substream);
276
277 if(!test_and_set_bit(BIT_PREPARED, &line6pcm->flags)) {
278 unlink_wait_clear_audio_out_urbs(line6pcm);
279 line6pcm->pos_out = 0;
280 line6pcm->pos_out_done = 0;
281
282 unlink_wait_clear_audio_in_urbs(line6pcm);
283 line6pcm->bytes_out = 0;
284 line6pcm->pos_in_done = 0;
285 line6pcm->bytes_in = 0;
286 }
287
288 return 0;
289}
diff --git a/drivers/staging/line6/pcm.h b/drivers/staging/line6/pcm.h
new file mode 100644
index 000000000000..90f8bb9816d5
--- /dev/null
+++ b/drivers/staging/line6/pcm.h
@@ -0,0 +1,210 @@
1/*
2 * Line6 Linux USB driver - 0.8.0
3 *
4 * Copyright (C) 2004-2009 Markus Grabner (grabner@icg.tugraz.at)
5 *
6 * This program is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU General Public License as
8 * published by the Free Software Foundation, version 2.
9 *
10 */
11
12/*
13 PCM interface to POD series devices.
14*/
15
16#ifndef PCM_H
17#define PCM_H
18
19
20#include <sound/pcm.h>
21
22#include "driver.h"
23#include "usbdefs.h"
24
25
26#define LINE6_ISO_BUFFERS 8 /* number of URBs */
27#define LINE6_ISO_PACKETS 2 /* number of USB frames per URB */
28#define LINE6_ISO_INTERVAL 1 /* in a "full speed" device (such as the PODxt Pro) this means 1ms */
29#define LINE6_ISO_PACKET_SIZE_MAX 252 /* this should be queried dynamically from the USB interface! */
30
31
32/*
33 Extract the messaging device from the substream instance
34*/
35#define s2m(s) (((struct snd_line6_pcm *)snd_pcm_substream_chip(s))->line6->ifcdev)
36
37
38enum {
39 BIT_RUNNING_PLAYBACK,
40 BIT_RUNNING_CAPTURE,
41 BIT_PAUSE_PLAYBACK,
42 BIT_PREPARED
43};
44
45struct line6_pcm_properties {
46 struct snd_pcm_hardware snd_line6_playback_hw, snd_line6_capture_hw;
47 struct snd_pcm_hw_constraint_ratdens snd_line6_rates;
48 int bytes_per_frame;
49};
50
51struct snd_line6_pcm
52{
53 /**
54 Pointer back to the Line6 driver data structure.
55 */
56 struct usb_line6 *line6;
57
58 /**
59 Properties.
60 */
61 struct line6_pcm_properties *properties;
62
63 /**
64 ALSA pcm stream
65 */
66 struct snd_pcm *pcm;
67
68 /**
69 URBs for audio playback.
70 */
71 struct urb *urb_audio_out[LINE6_ISO_BUFFERS];
72
73 /**
74 URBs for audio capture.
75 */
76 struct urb *urb_audio_in[LINE6_ISO_BUFFERS];
77
78 /**
79 Temporary buffer to hold data when playback buffer wraps.
80 */
81 unsigned char *wrap_out;
82
83 /**
84 Temporary buffer for capture.
85 Since the packet size is not known in advance, this buffer is large enough
86 to store maximum size packets.
87 */
88 unsigned char *buffer_in;
89
90 /**
91 Free frame position in the playback buffer.
92 */
93 snd_pcm_uframes_t pos_out;
94
95 /**
96 Count processed bytes for playback.
97 This is modulo period size (to determine when a period is finished).
98 */
99 unsigned bytes_out;
100
101 /**
102 Counter to create desired playback sample rate.
103 */
104 unsigned count_out;
105
106 /**
107 Playback period size in bytes
108 */
109 unsigned period_out;
110
111 /**
112 Processed frame position in the playback buffer.
113 The contents of the output ring buffer have been consumed by the USB
114 subsystem (i.e., sent to the USB device) up to this position.
115 */
116 snd_pcm_uframes_t pos_out_done;
117
118 /**
119 Count processed bytes for capture.
120 This is modulo period size (to determine when a period is finished).
121 */
122 unsigned bytes_in;
123
124 /**
125 Counter to create desired capture sample rate.
126 */
127 unsigned count_in;
128
129 /**
130 Capture period size in bytes
131 */
132 unsigned period_in;
133
134 /**
135 Processed frame position in the capture buffer.
136 The contents of the output ring buffer have been consumed by the USB
137 subsystem (i.e., sent to the USB device) up to this position.
138 */
139 snd_pcm_uframes_t pos_in_done;
140
141 /**
142 Bit mask of active playback URBs.
143 */
144 unsigned long active_urb_out;
145
146 /**
147 Maximum size of USB packet.
148 */
149 int max_packet_size;
150
151 /**
152 USB endpoint for listening to audio data.
153 */
154 int ep_audio_read;
155
156 /**
157 USB endpoint for writing audio data.
158 */
159 int ep_audio_write;
160
161 /**
162 Bit mask of active capture URBs.
163 */
164 unsigned long active_urb_in;
165
166 /**
167 Bit mask of playback URBs currently being unlinked.
168 */
169 unsigned long unlink_urb_out;
170
171 /**
172 Bit mask of capture URBs currently being unlinked.
173 */
174 unsigned long unlink_urb_in;
175
176 /**
177 Spin lock to protect updates of the playback buffer positions (not
178 contents!)
179 */
180 spinlock_t lock_audio_out;
181
182 /**
183 Spin lock to protect updates of the capture buffer positions (not
184 contents!)
185 */
186 spinlock_t lock_audio_in;
187
188 /**
189 Spin lock to protect trigger.
190 */
191 spinlock_t lock_trigger;
192
193 /**
194 PCM playback volume (left and right).
195 */
196 int volume[2];
197
198 /**
199 Several status bits (see BIT_*).
200 */
201 unsigned long flags;
202};
203
204
205extern int line6_init_pcm(struct usb_line6 *line6, struct line6_pcm_properties *properties);
206extern int snd_line6_trigger(struct snd_pcm_substream *substream, int cmd);
207extern int snd_line6_prepare(struct snd_pcm_substream *substream);
208
209
210#endif
diff --git a/drivers/staging/line6/playback.c b/drivers/staging/line6/playback.c
new file mode 100644
index 000000000000..f6503c23bd08
--- /dev/null
+++ b/drivers/staging/line6/playback.c
@@ -0,0 +1,428 @@
1/*
2 * Line6 Linux USB driver - 0.8.0
3 *
4 * Copyright (C) 2004-2009 Markus Grabner (grabner@icg.tugraz.at)
5 *
6 * This program is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU General Public License as
8 * published by the Free Software Foundation, version 2.
9 *
10 */
11
12#include "driver.h"
13
14#include <sound/core.h>
15#include <sound/pcm.h>
16#include <sound/pcm_params.h>
17
18#include "audio.h"
19#include "pcm.h"
20#include "pod.h"
21
22
23/*
24 Software stereo volume control.
25*/
26static void change_volume(struct urb *urb_out, int volume[], int bytes_per_frame)
27{
28 int chn = 0;
29
30 if(volume[0] == 256 && volume[1] == 256)
31 return; /* maximum volume - no change */
32
33 if(bytes_per_frame == 4) {
34 short *p, *buf_end;
35 p = (short *)urb_out->transfer_buffer;
36 buf_end = p + urb_out->transfer_buffer_length / sizeof(*p);
37
38 for(; p < buf_end; ++p) {
39 *p = (*p * volume[chn & 1]) >> 8;
40 ++chn;
41 }
42 }
43 else if(bytes_per_frame == 6) {
44 unsigned char *p, *buf_end;
45 p = (unsigned char *)urb_out->transfer_buffer;
46 buf_end = p + urb_out->transfer_buffer_length;
47
48 for(; p < buf_end; p += 3) {
49 int val = p[0] + (p[1] << 8) + ((signed char)p[2] << 16);
50 val = (val * volume[chn & 1]) >> 8;
51 p[0] = val;
52 p[1] = val >> 8;
53 p[2] = val >> 16;
54 ++chn;
55 }
56 }
57}
58
59/*
60 Find a free URB, prepare audio data, and submit URB.
61*/
62static int submit_audio_out_urb(struct snd_pcm_substream *substream)
63{
64 int index;
65 unsigned long flags;
66 int i, urb_size, urb_frames;
67 struct snd_line6_pcm *line6pcm = snd_pcm_substream_chip(substream);
68 const int bytes_per_frame = line6pcm->properties->bytes_per_frame;
69 const int frame_increment = line6pcm->properties->snd_line6_rates.rats[0].num_min;
70 const int frame_factor = line6pcm->properties->snd_line6_rates.rats[0].den * (USB_INTERVALS_PER_SECOND / LINE6_ISO_INTERVAL);
71 struct snd_pcm_runtime *runtime = substream->runtime;
72 struct urb *urb_out;
73
74 spin_lock_irqsave(&line6pcm->lock_audio_out, flags);
75 index = find_first_zero_bit(&line6pcm->active_urb_out, LINE6_ISO_BUFFERS);
76
77 if(index < 0 || index >= LINE6_ISO_BUFFERS) {
78 spin_unlock_irqrestore(&line6pcm->lock_audio_out, flags);
79 dev_err(s2m(substream), "no free URB found\n");
80 return -EINVAL;
81 }
82
83 urb_out = line6pcm->urb_audio_out[index];
84 urb_size = 0;
85
86 for(i = 0; i < LINE6_ISO_PACKETS; ++i) {
87 /* compute frame size for given sampling rate */
88 int n, fs;
89 struct usb_iso_packet_descriptor *fout = &urb_out->iso_frame_desc[i];
90 line6pcm->count_out += frame_increment;
91 n = line6pcm->count_out / frame_factor;
92 line6pcm->count_out -= n * frame_factor;
93 fs = n * bytes_per_frame;
94 fout->offset = urb_size;
95 fout->length = fs;
96 urb_size += fs;
97 }
98
99 urb_frames = urb_size / bytes_per_frame;
100
101 if(test_bit(BIT_PAUSE_PLAYBACK, &line6pcm->flags)) {
102 urb_out->transfer_buffer = line6pcm->wrap_out;
103 memset(line6pcm->wrap_out, 0, urb_size);
104 }
105 else {
106 if(line6pcm->pos_out + urb_frames > runtime->buffer_size) {
107 /*
108 The transferred area goes over buffer boundary,
109 copy the data to the temp buffer.
110 */
111 int len;
112 len = runtime->buffer_size - line6pcm->pos_out;
113 urb_out->transfer_buffer = line6pcm->wrap_out;
114
115 if(len > 0) {
116 memcpy(line6pcm->wrap_out, runtime->dma_area + line6pcm->pos_out * bytes_per_frame, len * bytes_per_frame);
117 memcpy(line6pcm->wrap_out + len * bytes_per_frame, runtime->dma_area, (urb_frames - len) * bytes_per_frame);
118 }
119 else
120 dev_err(s2m(substream), "driver bug: len = %d\n", len); /* this is somewhat paranoid */
121 }
122 else {
123 /* set the buffer pointer */
124 urb_out->transfer_buffer = runtime->dma_area + line6pcm->pos_out * bytes_per_frame;
125 }
126 }
127
128 if((line6pcm->pos_out += urb_frames) >= runtime->buffer_size)
129 line6pcm->pos_out -= runtime->buffer_size;
130
131 urb_out->transfer_buffer_length = urb_size;
132 urb_out->context = substream;
133 change_volume(urb_out, line6pcm->volume, bytes_per_frame);
134
135#if DO_DUMP_PCM_SEND
136 for(i = 0; i < LINE6_ISO_PACKETS; ++i) {
137 struct usb_iso_packet_descriptor *fout = &urb_out->iso_frame_desc[i];
138 line6_write_hexdump(line6pcm->line6, 'P', urb_out->transfer_buffer + fout->offset, fout->length);
139 }
140#endif
141
142 if(usb_submit_urb(urb_out, GFP_ATOMIC) == 0)
143 set_bit(index, &line6pcm->active_urb_out);
144 else
145 dev_err(s2m(substream), "URB out #%d submission failed\n", index);
146
147 spin_unlock_irqrestore(&line6pcm->lock_audio_out, flags);
148 return 0;
149}
150
151/*
152 Submit all currently available playback URBs.
153*/
154static int submit_audio_out_all_urbs(struct snd_pcm_substream *substream)
155{
156 int ret, i;
157
158 for(i = 0; i < LINE6_ISO_BUFFERS; ++i)
159 if((ret = submit_audio_out_urb(substream)) < 0)
160 return ret;
161
162 return 0;
163}
164
165/*
166 Unlink all currently active playback URBs.
167*/
168static void unlink_audio_out_urbs(struct snd_line6_pcm *line6pcm)
169{
170 unsigned int i;
171
172 for(i = LINE6_ISO_BUFFERS; i--;) {
173 if(test_bit(i, &line6pcm->active_urb_out)) {
174 if(!test_and_set_bit(i, &line6pcm->unlink_urb_out)) {
175 struct urb *u = line6pcm->urb_audio_out[i];
176#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 14)
177 u->transfer_flags |= URB_ASYNC_UNLINK;
178#endif
179 usb_unlink_urb(u);
180 }
181 }
182 }
183}
184
185/*
186 Wait until unlinking of all currently active playback URBs has been finished.
187*/
188static void wait_clear_audio_out_urbs(struct snd_line6_pcm *line6pcm)
189{
190 int timeout = HZ;
191 unsigned int i;
192 int alive;
193
194 do {
195 alive = 0;
196 for (i = LINE6_ISO_BUFFERS; i--;) {
197 if (test_bit(i, &line6pcm->active_urb_out))
198 alive++;
199 }
200 if (! alive)
201 break;
202 set_current_state(TASK_UNINTERRUPTIBLE);
203 schedule_timeout(1);
204 } while (--timeout > 0);
205 if (alive)
206 snd_printk(KERN_ERR "timeout: still %d active urbs..\n", alive);
207
208 line6pcm->active_urb_out = 0;
209 line6pcm->unlink_urb_out = 0;
210}
211
212/*
213 Unlink all currently active playback URBs, and wait for finishing.
214*/
215void unlink_wait_clear_audio_out_urbs(struct snd_line6_pcm *line6pcm)
216{
217 unlink_audio_out_urbs(line6pcm);
218 wait_clear_audio_out_urbs(line6pcm);
219}
220
221/*
222 Callback for completed playback URB.
223*/
224static void audio_out_callback(struct urb *urb PT_REGS)
225{
226 int i, index, length = 0, shutdown = 0;
227 unsigned long flags;
228
229 struct snd_pcm_substream *substream = (struct snd_pcm_substream *)urb->context;
230 struct snd_line6_pcm *line6pcm = snd_pcm_substream_chip(substream);
231 struct snd_pcm_runtime *runtime = substream->runtime;
232
233 /* find index of URB */
234 for(index = LINE6_ISO_BUFFERS; index--;)
235 if(urb == line6pcm->urb_audio_out[index])
236 break;
237
238 if(index < 0)
239 return; /* URB has been unlinked asynchronously */
240
241 for(i = LINE6_ISO_PACKETS; i--;)
242 length += urb->iso_frame_desc[i].length;
243
244 spin_lock_irqsave(&line6pcm->lock_audio_out, flags);
245 line6pcm->pos_out_done += length / line6pcm->properties->bytes_per_frame;
246
247 if(line6pcm->pos_out_done >= runtime->buffer_size)
248 line6pcm->pos_out_done -= runtime->buffer_size;
249
250 clear_bit(index, &line6pcm->active_urb_out);
251
252 for(i = LINE6_ISO_PACKETS; i--;)
253 if(urb->iso_frame_desc[i].status == -ESHUTDOWN) {
254 shutdown = 1;
255 break;
256 }
257
258 if(test_bit(index, &line6pcm->unlink_urb_out))
259 shutdown = 1;
260
261 spin_unlock_irqrestore(&line6pcm->lock_audio_out, flags);
262
263 if(!shutdown) {
264 submit_audio_out_urb(substream);
265
266 if((line6pcm->bytes_out += length) >= line6pcm->period_out) {
267 line6pcm->bytes_out -= line6pcm->period_out;
268 snd_pcm_period_elapsed(substream);
269 }
270 }
271}
272
273/* open playback callback */
274static int snd_line6_playback_open(struct snd_pcm_substream *substream)
275{
276 int err;
277 struct snd_pcm_runtime *runtime = substream->runtime;
278 struct snd_line6_pcm *line6pcm = snd_pcm_substream_chip(substream);
279
280 if((err = snd_pcm_hw_constraint_ratdens(runtime, 0, SNDRV_PCM_HW_PARAM_RATE,
281 (&line6pcm->properties->snd_line6_rates))) < 0)
282 return err;
283
284 runtime->hw = line6pcm->properties->snd_line6_playback_hw;
285 return 0;
286}
287
288/* close playback callback */
289static int snd_line6_playback_close(struct snd_pcm_substream *substream)
290{
291 return 0;
292}
293
294/* hw_params playback callback */
295static int snd_line6_playback_hw_params(struct snd_pcm_substream *substream, struct snd_pcm_hw_params *hw_params)
296{
297 int ret;
298 struct snd_line6_pcm *line6pcm = snd_pcm_substream_chip(substream);
299
300 /* -- Florian Demski [FD] */
301 /* don't ask me why, but this fixes the bug on my machine */
302 if ( line6pcm == NULL ) {
303 if ( substream->pcm == NULL )
304 return -ENOMEM;
305 if ( substream->pcm->private_data == NULL )
306 return -ENOMEM;
307 substream->private_data = substream->pcm->private_data;
308 line6pcm = snd_pcm_substream_chip( substream );
309 }
310 /* -- [FD] end */
311
312 if((ret = snd_pcm_lib_malloc_pages(substream, params_buffer_bytes(hw_params))) < 0)
313 return ret;
314
315 line6pcm->period_out = params_period_bytes(hw_params);
316 line6pcm->wrap_out = kmalloc(2 * LINE6_ISO_PACKET_SIZE_MAX, GFP_KERNEL);
317
318 if(!line6pcm->wrap_out) {
319 dev_err(s2m(substream), "cannot malloc wrap_out\n");
320 return -ENOMEM;
321 }
322
323 return 0;
324}
325
326/* hw_free playback callback */
327static int snd_line6_playback_hw_free(struct snd_pcm_substream *substream)
328{
329 struct snd_line6_pcm *line6pcm = snd_pcm_substream_chip(substream);
330 unlink_wait_clear_audio_out_urbs(line6pcm);
331
332 if(line6pcm->wrap_out) {
333 kfree(line6pcm->wrap_out);
334 line6pcm->wrap_out = 0;
335 }
336
337 return snd_pcm_lib_free_pages(substream);
338}
339
340/* trigger playback callback */
341int snd_line6_playback_trigger(struct snd_pcm_substream *substream, int cmd)
342{
343 struct snd_line6_pcm *line6pcm = snd_pcm_substream_chip(substream);
344 int err;
345 line6pcm->count_out = 0;
346
347 switch(cmd) {
348 case SNDRV_PCM_TRIGGER_START:
349 if(!test_and_set_bit(BIT_RUNNING_PLAYBACK, &line6pcm->flags)) {
350 err = submit_audio_out_all_urbs(substream);
351
352 if(err < 0) {
353 clear_bit(BIT_RUNNING_PLAYBACK, &line6pcm->flags);
354 return err;
355 }
356 }
357
358 break;
359
360 case SNDRV_PCM_TRIGGER_STOP:
361 if(test_and_clear_bit(BIT_RUNNING_PLAYBACK, &line6pcm->flags))
362 unlink_audio_out_urbs(line6pcm);
363
364 break;
365
366 case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
367 set_bit(BIT_PAUSE_PLAYBACK, &line6pcm->flags);
368 break;
369
370 case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
371 clear_bit(BIT_PAUSE_PLAYBACK, &line6pcm->flags);
372 break;
373
374 default:
375 return -EINVAL;
376 }
377
378 return 0;
379}
380
381/* playback pointer callback */
382static snd_pcm_uframes_t
383snd_line6_playback_pointer(struct snd_pcm_substream *substream)
384{
385 struct snd_line6_pcm *line6pcm = snd_pcm_substream_chip(substream);
386 return line6pcm->pos_out_done;
387}
388
389/* playback operators */
390struct snd_pcm_ops snd_line6_playback_ops = {
391 .open = snd_line6_playback_open,
392 .close = snd_line6_playback_close,
393 .ioctl = snd_pcm_lib_ioctl,
394 .hw_params = snd_line6_playback_hw_params,
395 .hw_free = snd_line6_playback_hw_free,
396 .prepare = snd_line6_prepare,
397 .trigger = snd_line6_trigger,
398 .pointer = snd_line6_playback_pointer,
399};
400
401int create_audio_out_urbs(struct snd_line6_pcm *line6pcm)
402{
403 int i;
404
405 /* create audio URBs and fill in constant values: */
406 for(i = 0; i < LINE6_ISO_BUFFERS; ++i) {
407 struct urb *urb;
408
409 /* URB for audio out: */
410 urb = line6pcm->urb_audio_out[i] = usb_alloc_urb(LINE6_ISO_PACKETS, GFP_KERNEL);
411
412 if(urb == NULL) {
413 dev_err(line6pcm->line6->ifcdev, "Out of memory\n");
414 return -ENOMEM;
415 }
416
417 urb->dev = line6pcm->line6->usbdev;
418 urb->pipe = usb_sndisocpipe(line6pcm->line6->usbdev, line6pcm->ep_audio_write & USB_ENDPOINT_NUMBER_MASK);
419 urb->transfer_flags = URB_ISO_ASAP;
420 urb->start_frame = -1;
421 urb->number_of_packets = LINE6_ISO_PACKETS;
422 urb->interval = LINE6_ISO_INTERVAL;
423 urb->error_count = 0;
424 urb->complete = audio_out_callback;
425 }
426
427 return 0;
428}
diff --git a/drivers/staging/line6/playback.h b/drivers/staging/line6/playback.h
new file mode 100644
index 000000000000..019c40f2cdb4
--- /dev/null
+++ b/drivers/staging/line6/playback.h
@@ -0,0 +1,29 @@
1/*
2 * Line6 Linux USB driver - 0.8.0
3 *
4 * Copyright (C) 2004-2009 Markus Grabner (grabner@icg.tugraz.at)
5 *
6 * This program is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU General Public License as
8 * published by the Free Software Foundation, version 2.
9 *
10 */
11
12#ifndef PLAYBACK_H
13#define PLAYBACK_H
14
15
16#include "driver.h"
17
18#include <sound/pcm.h>
19
20
21extern struct snd_pcm_ops snd_line6_playback_ops;
22
23
24extern int create_audio_out_urbs(struct snd_line6_pcm *line6pcm);
25extern int snd_line6_playback_trigger(struct snd_pcm_substream *substream, int cmd);
26extern void unlink_wait_clear_audio_out_urbs(struct snd_line6_pcm *line6pcm);
27
28
29#endif
diff --git a/drivers/staging/line6/pod.c b/drivers/staging/line6/pod.c
new file mode 100644
index 000000000000..154985aeb698
--- /dev/null
+++ b/drivers/staging/line6/pod.c
@@ -0,0 +1,1100 @@
1/*
2 * Line6 Linux USB driver - 0.8.0
3 *
4 * Copyright (C) 2004-2009 Markus Grabner (grabner@icg.tugraz.at)
5 *
6 * This program is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU General Public License as
8 * published by the Free Software Foundation, version 2.
9 *
10 */
11
12#include "driver.h"
13
14#include "audio.h"
15#include "capture.h"
16#include "control.h"
17#include "playback.h"
18#include "pod.h"
19
20
21#define POD_SYSEX_CODE 3
22#define POD_BYTES_PER_FRAME 6 /* 24bit audio (stereo) */
23
24
25enum {
26 POD_SYSEX_CLIP = 0x0f,
27 POD_SYSEX_SAVE = 0x24,
28 POD_SYSEX_SYSTEM = 0x56,
29 POD_SYSEX_SYSTEMREQ = 0x57,
30 /* POD_SYSEX_UPDATE = 0x6c, */ /* software update! */
31 POD_SYSEX_STORE = 0x71,
32 POD_SYSEX_FINISH = 0x72,
33 POD_SYSEX_DUMPMEM = 0x73,
34 POD_SYSEX_DUMP = 0x74,
35 POD_SYSEX_DUMPREQ = 0x75
36 /* POD_SYSEX_DUMPMEM2 = 0x76 */ /* dumps entire internal memory of PODxt Pro */
37};
38
39enum {
40 POD_monitor_level = 0x04,
41 POD_routing = 0x05,
42 POD_tuner_mute = 0x13,
43 POD_tuner_freq = 0x15,
44 POD_tuner_note = 0x16,
45 POD_tuner_pitch = 0x17,
46 POD_system_invalid = 0x7fff
47};
48
49enum {
50 POD_DUMP_MEMORY = 2
51};
52
53enum {
54 POD_BUSY_READ,
55 POD_BUSY_WRITE,
56 POD_CHANNEL_DIRTY,
57 POD_SAVE_PRESSED,
58 POD_BUSY_MIDISEND
59};
60
61
62static struct snd_ratden pod_ratden = {
63 .num_min = 78125,
64 .num_max = 78125,
65 .num_step = 1,
66 .den = 2
67};
68
69static struct line6_pcm_properties pod_pcm_properties = {
70 .snd_line6_playback_hw = {
71 .info = (SNDRV_PCM_INFO_MMAP |
72 SNDRV_PCM_INFO_INTERLEAVED |
73 SNDRV_PCM_INFO_BLOCK_TRANSFER |
74 SNDRV_PCM_INFO_MMAP_VALID |
75 SNDRV_PCM_INFO_PAUSE |
76 SNDRV_PCM_INFO_SYNC_START),
77 .formats = SNDRV_PCM_FMTBIT_S24_3LE,
78 .rates = SNDRV_PCM_RATE_KNOT,
79 .rate_min = 39062,
80 .rate_max = 39063,
81 .channels_min = 2,
82 .channels_max = 2,
83 .buffer_bytes_max = 60000,
84 .period_bytes_min = LINE6_ISO_PACKET_SIZE_MAX * POD_BYTES_PER_FRAME, /* at least one URB must fit into one period */
85 .period_bytes_max = 8192,
86 .periods_min = 1,
87 .periods_max = 1024
88 },
89 .snd_line6_capture_hw = {
90 .info = (SNDRV_PCM_INFO_MMAP |
91 SNDRV_PCM_INFO_INTERLEAVED |
92 SNDRV_PCM_INFO_BLOCK_TRANSFER |
93 SNDRV_PCM_INFO_MMAP_VALID |
94 SNDRV_PCM_INFO_SYNC_START),
95 .formats = SNDRV_PCM_FMTBIT_S24_3LE,
96 .rates = SNDRV_PCM_RATE_KNOT,
97 .rate_min = 39062,
98 .rate_max = 39063,
99 .channels_min = 2,
100 .channels_max = 2,
101 .buffer_bytes_max = 60000,
102 .period_bytes_min = LINE6_ISO_PACKET_SIZE_MAX * POD_BYTES_PER_FRAME, /* at least one URB must fit into one period */
103 .period_bytes_max = 8192,
104 .periods_min = 1,
105 .periods_max = 1024
106 },
107 .snd_line6_rates = {
108 .nrats = 1,
109 .rats = &pod_ratden
110 },
111 .bytes_per_frame = POD_BYTES_PER_FRAME
112};
113
114static const char pod_request_version[] = { 0xf0, 0x7e, 0x7f, 0x06, 0x01, 0xf7 };
115static const char pod_request_channel[] = { 0xf0, 0x00, 0x01, 0x0c, 0x03, 0x75, 0xf7 };
116static const char pod_version_header [] = { 0xf2, 0x7e, 0x7f, 0x06, 0x02 };
117
118
119/*
120 Mark all parameters as dirty and notify waiting processes.
121*/
122static void pod_mark_batch_all_dirty(struct usb_line6_pod *pod)
123{
124 int i;
125
126 for(i = POD_CONTROL_SIZE; i--;)
127 set_bit(i, pod->param_dirty);
128}
129
130/*
131 Send an asynchronous request for the POD firmware version and device ID.
132*/
133static int pod_version_request_async(struct usb_line6_pod *pod)
134{
135 return line6_send_raw_message_async(&pod->line6, pod->buffer_versionreq, sizeof(pod_request_version));
136}
137
138#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 20)
139static void pod_create_files_work(struct work_struct *work)
140{
141 struct usb_line6_pod *pod = container_of(work, struct usb_line6_pod, create_files_work);
142#else
143static void pod_create_files_work(void *work)
144{
145 struct usb_line6_pod *pod = (struct usb_line6_pod *)work;
146#endif
147
148 pod_create_files(pod->firmware_version, pod->line6.properties->device_bit, pod->line6.ifcdev);
149}
150
151static void pod_startup_timeout(unsigned long arg)
152{
153 enum {
154 REQUEST_NONE,
155 REQUEST_DUMP,
156 REQUEST_VERSION
157 };
158
159 int request = REQUEST_NONE;
160 struct usb_line6_pod *pod = (struct usb_line6_pod *)arg;
161
162 if(pod->dumpreq.ok) {
163 if(!pod->versionreq_ok)
164 request = REQUEST_VERSION;
165 }
166 else {
167 if(pod->versionreq_ok)
168 request = REQUEST_DUMP;
169 else if(pod->startup_count++ & 1)
170 request = REQUEST_DUMP;
171 else
172 request = REQUEST_VERSION;
173 }
174
175 switch(request) {
176 case REQUEST_DUMP:
177 line6_dump_request_async(&pod->dumpreq, &pod->line6, 0);
178 break;
179
180 case REQUEST_VERSION:
181 pod_version_request_async(pod);
182 break;
183
184 default:
185 return;
186 }
187
188 line6_startup_delayed(&pod->dumpreq, 1, pod_startup_timeout, pod);
189}
190
191static char *pod_alloc_sysex_buffer(struct usb_line6_pod *pod, int code, int size)
192{
193 return line6_alloc_sysex_buffer(&pod->line6, POD_SYSEX_CODE, code, size);
194}
195
196/*
197 Send channel dump data to the PODxt Pro.
198*/
199static void pod_dump(struct usb_line6_pod *pod, const unsigned char *data)
200{
201 int size = 1 + sizeof(pod->prog_data);
202 char *sysex = pod_alloc_sysex_buffer(pod, POD_SYSEX_DUMP, size);
203 if(!sysex) return;
204 sysex[SYSEX_DATA_OFS] = 5; /* Don't know what this is good for, but PODxt Pro transmits it, so we also do... */
205 memcpy(sysex + SYSEX_DATA_OFS + 1, data, sizeof(pod->prog_data));
206 line6_send_sysex_message(&pod->line6, sysex, size);
207 memcpy(&pod->prog_data, data, sizeof(pod->prog_data));
208 pod_mark_batch_all_dirty(pod);
209 kfree(sysex);
210}
211
212/*
213 Store parameter value in driver memory and mark it as dirty.
214*/
215static void pod_store_parameter(struct usb_line6_pod *pod, int param, int value)
216{
217 pod->prog_data.control[param] = value;
218 set_bit(param, pod->param_dirty);
219 pod->dirty = 1;
220}
221
222/*
223 Handle SAVE button
224*/
225static void pod_save_button_pressed(struct usb_line6_pod *pod, int type, int index)
226{
227 pod->dirty = 0;
228 set_bit(POD_SAVE_PRESSED, &pod->atomic_flags);
229}
230
231/*
232 Process a completely received message.
233*/
234void pod_process_message(struct usb_line6_pod *pod)
235{
236 const unsigned char *buf = pod->line6.buffer_message;
237
238 /* filter messages by type */
239 switch(buf[0] & 0xf0) {
240 case LINE6_PARAM_CHANGE:
241 case LINE6_PROGRAM_CHANGE:
242 case LINE6_SYSEX_BEGIN:
243 break; /* handle these further down */
244
245 default:
246 return; /* ignore all others */
247 }
248
249 /* process all remaining messages */
250 switch(buf[0]) {
251 case LINE6_PARAM_CHANGE | LINE6_CHANNEL_DEVICE:
252 pod_store_parameter(pod, buf[1], buf[2]);
253 /* intentionally no break here! */
254
255 case LINE6_PARAM_CHANGE | LINE6_CHANNEL_HOST:
256 if((buf[1] == POD_amp_model_setup) || (buf[1] == POD_effect_setup)) /* these also affect other settings */
257 line6_dump_request_async(&pod->dumpreq, &pod->line6, 0);
258
259 break;
260
261 case LINE6_PROGRAM_CHANGE | LINE6_CHANNEL_DEVICE:
262 case LINE6_PROGRAM_CHANGE | LINE6_CHANNEL_HOST:
263 pod->channel_num = buf[1];
264 pod->dirty = 0;
265 set_bit(POD_CHANNEL_DIRTY, &pod->atomic_flags);
266 line6_dump_request_async(&pod->dumpreq, &pod->line6, 0);
267 break;
268
269 case LINE6_SYSEX_BEGIN | LINE6_CHANNEL_DEVICE:
270 case LINE6_SYSEX_BEGIN | LINE6_CHANNEL_UNKNOWN:
271 if(memcmp(buf + 1, line6_midi_id, sizeof(line6_midi_id)) == 0) {
272 switch(buf[5]) {
273 case POD_SYSEX_DUMP:
274 if(pod->line6.message_length == sizeof(pod->prog_data) + 7) {
275 switch(pod->dumpreq.in_progress) {
276 case LINE6_DUMP_CURRENT:
277 memcpy(&pod->prog_data, buf + 7, sizeof(pod->prog_data));
278 pod_mark_batch_all_dirty(pod);
279 pod->dumpreq.ok = 1;
280 break;
281
282 case POD_DUMP_MEMORY:
283 memcpy(&pod->prog_data_buf, buf + 7, sizeof(pod->prog_data_buf));
284 break;
285
286 default:
287 DEBUG_MESSAGES(dev_err(pod->line6.ifcdev, "unknown dump code %02X\n", pod->dumpreq.in_progress));
288 }
289
290 line6_dump_finished(&pod->dumpreq);
291 }
292 else
293 DEBUG_MESSAGES(dev_err(pod->line6.ifcdev, "wrong size of channel dump message (%d instead of %d)\n",
294 pod->line6.message_length, (int)sizeof(pod->prog_data) + 7));
295
296 break;
297
298 case POD_SYSEX_SYSTEM: {
299 short value = ((int)buf[7] << 12) | ((int)buf[8] << 8) | ((int)buf[9] << 4) | (int)buf[10];
300
301#define PROCESS_SYSTEM_PARAM(x) \
302 case POD_ ## x: \
303 pod->x.value = value; \
304 wake_up_interruptible(&pod->x.wait); \
305 break;
306
307 switch(buf[6]) {
308 PROCESS_SYSTEM_PARAM(monitor_level);
309 PROCESS_SYSTEM_PARAM(routing);
310 PROCESS_SYSTEM_PARAM(tuner_mute);
311 PROCESS_SYSTEM_PARAM(tuner_freq);
312 PROCESS_SYSTEM_PARAM(tuner_note);
313 PROCESS_SYSTEM_PARAM(tuner_pitch);
314
315#undef PROCESS_SYSTEM_PARAM
316
317 default:
318 DEBUG_MESSAGES(dev_err(pod->line6.ifcdev, "unknown tuner/system response %02X\n", buf[6]));
319 }
320
321 break;
322 }
323
324 case POD_SYSEX_FINISH:
325 /* do we need to respond to this? */
326 break;
327
328 case POD_SYSEX_SAVE:
329 pod_save_button_pressed(pod, buf[6], buf[7]);
330 break;
331
332 case POD_SYSEX_CLIP:
333 DEBUG_MESSAGES(dev_err(pod->line6.ifcdev, "audio clipped\n"));
334 pod->clipping.value = 1;
335 wake_up_interruptible(&pod->clipping.wait);
336 break;
337
338 case POD_SYSEX_STORE:
339 DEBUG_MESSAGES(dev_err(pod->line6.ifcdev, "message %02X not yet implemented\n", buf[5]));
340 break;
341
342 default:
343 DEBUG_MESSAGES(dev_err(pod->line6.ifcdev, "unknown sysex message %02X\n", buf[5]));
344 }
345 }
346 else if(memcmp(buf, pod_version_header, sizeof(pod_version_header)) == 0) {
347 if(pod->versionreq_ok == 0) {
348 pod->firmware_version = buf[13] * 100 + buf[14] * 10 + buf[15];
349 pod->device_id = ((int)buf[8] << 16) | ((int)buf[9] << 8) | (int)buf[10];
350 pod->versionreq_ok = 1;
351
352 /* Now we know the firmware version, so we schedule a bottom half
353 handler to create the special files: */
354#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 20)
355 INIT_WORK(&pod->create_files_work, pod_create_files_work);
356#else
357 INIT_WORK(&pod->create_files_work, pod_create_files_work, pod);
358#endif
359 queue_work(line6_workqueue, &pod->create_files_work);
360 }
361 else
362 DEBUG_MESSAGES(dev_err(pod->line6.ifcdev, "multiple firmware version message\n"));
363 }
364 else
365 DEBUG_MESSAGES(dev_err(pod->line6.ifcdev, "unknown sysex header\n"));
366
367 break;
368
369 case LINE6_SYSEX_END:
370 break;
371
372 default:
373 DEBUG_MESSAGES(dev_err(pod->line6.ifcdev, "POD: unknown message %02X\n", buf[0]));
374 }
375}
376
377/*
378 Detect some cases that require a channel dump after sending a command to the
379 device. Important notes:
380 *) The actual dump request can not be sent here since we are not allowed to
381 wait for the completion of the first message in this context, and sending
382 the dump request before completion of the previous message leaves the POD
383 in an undefined state. The dump request will be sent when the echoed
384 commands are received.
385 *) This method fails if a param change message is "chopped" after the first
386 byte.
387*/
388void pod_midi_postprocess(struct usb_line6_pod *pod, unsigned char *data, int length)
389{
390 int i;
391
392 if(!pod->midi_postprocess)
393 return;
394
395 for(i = 0; i < length; ++i) {
396 if(data[i] == (LINE6_PROGRAM_CHANGE | LINE6_CHANNEL_HOST)) {
397 line6_invalidate_current(&pod->dumpreq);
398 break;
399 }
400 else if((data[i] == (LINE6_PARAM_CHANGE | LINE6_CHANNEL_HOST)) && (i < length - 1))
401 if((data[i + 1] == POD_amp_model_setup) || (data[i + 1] == POD_effect_setup)) {
402 line6_invalidate_current(&pod->dumpreq);
403 break;
404 }
405 }
406}
407
408/*
409 Send channel number (i.e., switch to a different sound).
410*/
411void pod_send_channel(struct usb_line6_pod *pod, int value)
412{
413 line6_invalidate_current(&pod->dumpreq);
414
415 if(line6_send_program(&pod->line6, value) == 0)
416 pod->channel_num = value;
417 else
418 line6_dump_finished(&pod->dumpreq);
419}
420
421/*
422 Transmit PODxt Pro control parameter.
423*/
424void pod_transmit_parameter(struct usb_line6_pod *pod, int param, int value)
425{
426 if(line6_transmit_parameter(&pod->line6, param, value) == 0)
427 pod_store_parameter(pod, param, value);
428
429 if((param == POD_amp_model_setup) || (param == POD_effect_setup)) /* these also affect other settings */
430 line6_invalidate_current(&pod->dumpreq);
431}
432
433/*
434 Resolve value to memory location.
435*/
436static void pod_resolve(const char *buf, short block0, short block1, unsigned char *location)
437{
438 int value = simple_strtoul(buf, NULL, 10);
439 short block = (value < 0x40) ? block0 : block1;
440 value &= 0x3f;
441 location[0] = block >> 7;
442 location[1] = value | (block & 0x7f);
443}
444
445/*
446 Send command to store channel/effects setup/amp setup to PODxt Pro.
447*/
448static ssize_t pod_send_store_command(struct device *dev, const char *buf, size_t count, short block0, short block1)
449{
450 struct usb_interface *interface = to_usb_interface(dev);
451 struct usb_line6_pod *pod = usb_get_intfdata(interface);
452
453 int size = 3 + sizeof(pod->prog_data_buf);
454 char *sysex = pod_alloc_sysex_buffer(pod, POD_SYSEX_STORE, size);
455 if(!sysex) return 0;
456
457 sysex[SYSEX_DATA_OFS] = 5; /* see pod_dump() */
458 pod_resolve(buf, block0, block1, sysex + SYSEX_DATA_OFS + 1);
459 memcpy(sysex + SYSEX_DATA_OFS + 3, &pod->prog_data_buf, sizeof(pod->prog_data_buf));
460
461 line6_send_sysex_message(&pod->line6, sysex, size);
462 kfree(sysex);
463 /* needs some delay here on AMD64 platform */
464 return count;
465}
466
467/*
468 Send command to retrieve channel/effects setup/amp setup to PODxt Pro.
469*/
470static ssize_t pod_send_retrieve_command(struct device *dev, const char *buf, size_t count, short block0, short block1)
471{
472 struct usb_interface *interface = to_usb_interface(dev);
473 struct usb_line6_pod *pod = usb_get_intfdata(interface);
474
475 int size = 4;
476 char *sysex = pod_alloc_sysex_buffer(pod, POD_SYSEX_DUMPMEM, size);
477 if(!sysex) return 0;
478
479 pod_resolve(buf, block0, block1, sysex + SYSEX_DATA_OFS);
480 sysex[SYSEX_DATA_OFS + 2] = 0;
481 sysex[SYSEX_DATA_OFS + 3] = 0;
482 line6_dump_started(&pod->dumpreq, POD_DUMP_MEMORY);
483
484 if(line6_send_sysex_message(&pod->line6, sysex, size) < size)
485 line6_dump_finished(&pod->dumpreq);
486
487 kfree(sysex);
488 /* needs some delay here on AMD64 platform */
489 return count;
490}
491
492/*
493 Generic get name function.
494*/
495static ssize_t get_name_generic(struct usb_line6_pod *pod, const char *str, char *buf)
496{
497 int length = 0;
498 const char *p1;
499 char *p2;
500 char *last_non_space = buf;
501
502 int retval = line6_wait_dump(&pod->dumpreq, 0);
503 if(retval < 0) return retval;
504
505 for(p1 = str, p2 = buf; *p1; ++p1, ++p2) {
506 *p2 = *p1;
507 if(*p2 != ' ') last_non_space = p2;
508 if(++length == POD_NAME_LENGTH) break;
509 }
510
511 *(last_non_space + 1) = '\n';
512 return last_non_space - buf + 2;
513}
514
515/*
516 "read" request on "channel" special file.
517*/
518static ssize_t pod_get_channel(struct device *dev, DEVICE_ATTRIBUTE char *buf)
519{
520 struct usb_interface *interface = to_usb_interface(dev);
521 struct usb_line6_pod *pod = usb_get_intfdata(interface);
522 return sprintf(buf, "%d\n", pod->channel_num);
523}
524
525/*
526 "write" request on "channel" special file.
527*/
528static ssize_t pod_set_channel(struct device *dev, DEVICE_ATTRIBUTE const char *buf, size_t count)
529{
530 struct usb_interface *interface = to_usb_interface(dev);
531 struct usb_line6_pod *pod = usb_get_intfdata(interface);
532 int value = simple_strtoul(buf, NULL, 10);
533 pod_send_channel(pod, value);
534 return count;
535}
536
537/*
538 "read" request on "name" special file.
539*/
540static ssize_t pod_get_name(struct device *dev, DEVICE_ATTRIBUTE char *buf)
541{
542 struct usb_interface *interface = to_usb_interface(dev);
543 struct usb_line6_pod *pod = usb_get_intfdata(interface);
544 return get_name_generic(pod, pod->prog_data.header + POD_NAME_OFFSET, buf);
545}
546
547/*
548 "read" request on "name" special file.
549*/
550static ssize_t pod_get_name_buf(struct device *dev, DEVICE_ATTRIBUTE char *buf)
551{
552 struct usb_interface *interface = to_usb_interface(dev);
553 struct usb_line6_pod *pod = usb_get_intfdata(interface);
554 return get_name_generic(pod, pod->prog_data_buf.header + POD_NAME_OFFSET, buf);
555}
556
557/*
558 "read" request on "dump" special file.
559*/
560static ssize_t pod_get_dump(struct device *dev, DEVICE_ATTRIBUTE char *buf)
561{
562 struct usb_interface *interface = to_usb_interface(dev);
563 struct usb_line6_pod *pod = usb_get_intfdata(interface);
564 int retval = line6_wait_dump(&pod->dumpreq, 0);
565 if(retval < 0) return retval;
566 memcpy(buf, &pod->prog_data, sizeof(pod->prog_data));
567 return sizeof(pod->prog_data);
568}
569
570/*
571 "write" request on "dump" special file.
572*/
573static ssize_t pod_set_dump(struct device *dev, DEVICE_ATTRIBUTE const char *buf, size_t count)
574{
575 struct usb_interface *interface = to_usb_interface(dev);
576 struct usb_line6_pod *pod = usb_get_intfdata(interface);
577
578 if(count != sizeof(pod->prog_data)) {
579 dev_err(pod->line6.ifcdev,
580 "data block must be exactly %d bytes\n",
581 (int)sizeof(pod->prog_data));
582 return -EINVAL;
583 }
584
585 pod_dump(pod, buf);
586 return sizeof(pod->prog_data);
587}
588
589/*
590 Request system parameter.
591 @param tuner non-zero, if code refers to a tuner parameter
592*/
593static ssize_t pod_get_system_param(struct usb_line6_pod *pod, char *buf, int code, struct ValueWait *param, int tuner, int sign)
594{
595 char *sysex;
596 int value;
597 static const int size = 1;
598 int retval = 0;
599 DECLARE_WAITQUEUE(wait, current);
600
601 if(((pod->prog_data.control[POD_tuner] & 0x40) == 0) && tuner)
602 return -ENODEV;
603
604 /* send value request to tuner: */
605 param->value = POD_system_invalid;
606 sysex = pod_alloc_sysex_buffer(pod, POD_SYSEX_SYSTEMREQ, size);
607 if(!sysex) return 0;
608 sysex[SYSEX_DATA_OFS] = code;
609 line6_send_sysex_message(&pod->line6, sysex, size);
610 kfree(sysex);
611
612 /* wait for tuner to respond: */
613 add_wait_queue(&param->wait, &wait);
614 current->state = TASK_INTERRUPTIBLE;
615
616 while(param->value == POD_system_invalid) {
617 if(signal_pending(current)) {
618 retval = -ERESTARTSYS;
619 break;
620 }
621 else
622 schedule();
623 }
624
625 current->state = TASK_RUNNING;
626 remove_wait_queue(&param->wait, &wait);
627
628 if(retval < 0)
629 return retval;
630
631 value = sign ? (int)(signed short)param->value : (int)(unsigned short)param->value;
632 return sprintf(buf, "%d\n", value);
633}
634
635/*
636 Send system parameter.
637 @param tuner non-zero, if code refers to a tuner parameter
638*/
639static ssize_t pod_set_system_param(struct usb_line6_pod *pod, const char *buf, int count, int code, unsigned short mask, int tuner)
640{
641 char *sysex;
642 static const int size = 5;
643 unsigned short value;
644
645 if(((pod->prog_data.control[POD_tuner] & 0x40) == 0) && tuner)
646 return -EINVAL;
647
648 /* send value to tuner: */
649 sysex = pod_alloc_sysex_buffer(pod, POD_SYSEX_SYSTEM, size);
650 if(!sysex) return 0;
651 value = simple_strtoul(buf, NULL, 10) & mask;
652 sysex[SYSEX_DATA_OFS] = code;
653 sysex[SYSEX_DATA_OFS + 1] = (value >> 12) & 0x0f;
654 sysex[SYSEX_DATA_OFS + 2] = (value >> 8) & 0x0f;
655 sysex[SYSEX_DATA_OFS + 3] = (value >> 4) & 0x0f;
656 sysex[SYSEX_DATA_OFS + 4] = (value ) & 0x0f;
657 line6_send_sysex_message(&pod->line6, sysex, size);
658 kfree(sysex);
659 return count;
660}
661
662/*
663 "read" request on "dump_buf" special file.
664*/
665static ssize_t pod_get_dump_buf(struct device *dev, DEVICE_ATTRIBUTE char *buf)
666{
667 struct usb_interface *interface = to_usb_interface(dev);
668 struct usb_line6_pod *pod = usb_get_intfdata(interface);
669 int retval = line6_wait_dump(&pod->dumpreq, 0);
670 if(retval < 0) return retval;
671 memcpy(buf, &pod->prog_data_buf, sizeof(pod->prog_data_buf));
672 return sizeof(pod->prog_data_buf);
673}
674
675/*
676 "write" request on "dump_buf" special file.
677*/
678static ssize_t pod_set_dump_buf(struct device *dev, DEVICE_ATTRIBUTE const char *buf, size_t count)
679{
680 struct usb_interface *interface = to_usb_interface(dev);
681 struct usb_line6_pod *pod = usb_get_intfdata(interface);
682
683 if(count != sizeof(pod->prog_data)) {
684 dev_err(pod->line6.ifcdev,
685 "data block must be exactly %d bytes\n",
686 (int)sizeof(pod->prog_data));
687 return -EINVAL;
688 }
689
690 memcpy(&pod->prog_data_buf, buf, sizeof(pod->prog_data));
691 return sizeof(pod->prog_data);
692}
693
694/*
695 "write" request on "finish" special file.
696*/
697static ssize_t pod_set_finish(struct device *dev, DEVICE_ATTRIBUTE const char *buf, size_t count)
698{
699 struct usb_interface *interface = to_usb_interface(dev);
700 struct usb_line6_pod *pod = usb_get_intfdata(interface);
701 int size = 0;
702 char *sysex = pod_alloc_sysex_buffer(pod, POD_SYSEX_FINISH, size);
703 if(!sysex) return 0;
704 line6_send_sysex_message(&pod->line6, sysex, size);
705 kfree(sysex);
706 return count;
707}
708
709/*
710 "write" request on "store_channel" special file.
711*/
712static ssize_t pod_set_store_channel(struct device *dev, DEVICE_ATTRIBUTE const char *buf, size_t count)
713{
714 return pod_send_store_command(dev, buf, count, 0x0000, 0x00c0);
715}
716
717/*
718 "write" request on "store_effects_setup" special file.
719*/
720static ssize_t pod_set_store_effects_setup(struct device *dev, DEVICE_ATTRIBUTE const char *buf, size_t count)
721{
722 return pod_send_store_command(dev, buf, count, 0x0080, 0x0080);
723}
724
725/*
726 "write" request on "store_amp_setup" special file.
727*/
728static ssize_t pod_set_store_amp_setup(struct device *dev, DEVICE_ATTRIBUTE const char *buf, size_t count)
729{
730 return pod_send_store_command(dev, buf, count, 0x0040, 0x0100);
731}
732
733/*
734 "write" request on "retrieve_channel" special file.
735*/
736static ssize_t pod_set_retrieve_channel(struct device *dev, DEVICE_ATTRIBUTE const char *buf, size_t count)
737{
738 return pod_send_retrieve_command(dev, buf, count, 0x0000, 0x00c0);
739}
740
741/*
742 "write" request on "retrieve_effects_setup" special file.
743*/
744static ssize_t pod_set_retrieve_effects_setup(struct device *dev, DEVICE_ATTRIBUTE const char *buf, size_t count)
745{
746 return pod_send_retrieve_command(dev, buf, count, 0x0080, 0x0080);
747}
748
749/*
750 "write" request on "retrieve_amp_setup" special file.
751*/
752static ssize_t pod_set_retrieve_amp_setup(struct device *dev, DEVICE_ATTRIBUTE const char *buf, size_t count)
753{
754 return pod_send_retrieve_command(dev, buf, count, 0x0040, 0x0100);
755}
756
757/*
758 "read" request on "dirty" special file.
759*/
760static ssize_t pod_get_dirty(struct device *dev, DEVICE_ATTRIBUTE char *buf)
761{
762 struct usb_interface *interface = to_usb_interface(dev);
763 struct usb_line6_pod *pod = usb_get_intfdata(interface);
764 buf[0] = pod->dirty ? '1' : '0';
765 buf[1] = '\n';
766 return 2;
767}
768
769/*
770 "read" request on "midi_postprocess" special file.
771*/
772static ssize_t pod_get_midi_postprocess(struct device *dev, DEVICE_ATTRIBUTE char *buf)
773{
774 struct usb_interface *interface = to_usb_interface(dev);
775 struct usb_line6_pod *pod = usb_get_intfdata(interface);
776 return sprintf(buf, "%d\n", pod->midi_postprocess);
777}
778
779/*
780 "write" request on "midi_postprocess" special file.
781*/
782static ssize_t pod_set_midi_postprocess(struct device *dev, DEVICE_ATTRIBUTE const char *buf, size_t count)
783{
784 struct usb_interface *interface = to_usb_interface(dev);
785 struct usb_line6_pod *pod = usb_get_intfdata(interface);
786 int value = simple_strtoul(buf, NULL, 10);
787 pod->midi_postprocess = value ? 1 : 0;
788 return count;
789}
790
791/*
792 "read" request on "serial_number" special file.
793*/
794static ssize_t pod_get_serial_number(struct device *dev, DEVICE_ATTRIBUTE char *buf)
795{
796 struct usb_interface *interface = to_usb_interface(dev);
797 struct usb_line6_pod *pod = usb_get_intfdata(interface);
798 return sprintf(buf, "%d\n", pod->serial_number);
799}
800
801/*
802 "read" request on "firmware_version" special file.
803*/
804static ssize_t pod_get_firmware_version(struct device *dev, DEVICE_ATTRIBUTE char *buf)
805{
806 struct usb_interface *interface = to_usb_interface(dev);
807 struct usb_line6_pod *pod = usb_get_intfdata(interface);
808 return sprintf(buf, "%d.%02d\n", pod->firmware_version / 100, pod->firmware_version % 100);
809}
810
811/*
812 "read" request on "device_id" special file.
813*/
814static ssize_t pod_get_device_id(struct device *dev, DEVICE_ATTRIBUTE char *buf)
815{
816 struct usb_interface *interface = to_usb_interface(dev);
817 struct usb_line6_pod *pod = usb_get_intfdata(interface);
818 return sprintf(buf, "%d\n", pod->device_id);
819}
820
821/*
822 "read" request on "clip" special file.
823*/
824static ssize_t pod_wait_for_clip(struct device *dev, DEVICE_ATTRIBUTE char *buf)
825{
826 struct usb_interface *interface = to_usb_interface(dev);
827 struct usb_line6_pod *pod = usb_get_intfdata(interface);
828 int err = 0;
829 DECLARE_WAITQUEUE(wait, current);
830 pod->clipping.value = 0;
831 add_wait_queue(&pod->clipping.wait, &wait);
832 current->state = TASK_INTERRUPTIBLE;
833
834 while(pod->clipping.value == 0) {
835 if(signal_pending(current)) {
836 err = -ERESTARTSYS;
837 break;
838 }
839 else
840 schedule();
841 }
842
843 current->state = TASK_RUNNING;
844 remove_wait_queue(&pod->clipping.wait, &wait);
845 return err;
846}
847
848#define POD_GET_SYSTEM_PARAM(code, tuner, sign) \
849static ssize_t pod_get_ ## code(struct device *dev, DEVICE_ATTRIBUTE char *buf) \
850{ \
851 struct usb_interface *interface = to_usb_interface(dev); \
852 struct usb_line6_pod *pod = usb_get_intfdata(interface); \
853 return pod_get_system_param(pod, buf, POD_ ## code, &pod->code, tuner, sign); \
854}
855
856#define POD_GET_SET_SYSTEM_PARAM(code, mask, tuner, sign) \
857POD_GET_SYSTEM_PARAM(code, tuner, sign) \
858static ssize_t pod_set_ ## code(struct device *dev, DEVICE_ATTRIBUTE const char *buf, size_t count) \
859{ \
860 struct usb_interface *interface = to_usb_interface(dev); \
861 struct usb_line6_pod *pod = usb_get_intfdata(interface); \
862 return pod_set_system_param(pod, buf, count, POD_ ## code, mask, tuner); \
863}
864
865POD_GET_SET_SYSTEM_PARAM(monitor_level, 0xffff, 0, 0);
866POD_GET_SET_SYSTEM_PARAM(routing, 0x0003, 0, 0);
867POD_GET_SET_SYSTEM_PARAM(tuner_mute, 0x0001, 1, 0);
868POD_GET_SET_SYSTEM_PARAM(tuner_freq, 0xffff, 1, 0);
869POD_GET_SYSTEM_PARAM(tuner_note, 1, 1);
870POD_GET_SYSTEM_PARAM(tuner_pitch, 1, 1);
871
872#undef GET_SET_SYSTEM_PARAM
873#undef GET_SYSTEM_PARAM
874
875/* POD special files: */
876static DEVICE_ATTR(channel, S_IWUGO | S_IRUGO, pod_get_channel, pod_set_channel);
877static DEVICE_ATTR(clip, S_IRUGO, pod_wait_for_clip, line6_nop_write);
878static DEVICE_ATTR(device_id, S_IRUGO, pod_get_device_id, line6_nop_write);
879static DEVICE_ATTR(dirty, S_IRUGO, pod_get_dirty, line6_nop_write);
880static DEVICE_ATTR(dump, S_IWUGO | S_IRUGO, pod_get_dump, pod_set_dump);
881static DEVICE_ATTR(dump_buf, S_IWUGO | S_IRUGO, pod_get_dump_buf, pod_set_dump_buf);
882static DEVICE_ATTR(finish, S_IWUGO, line6_nop_read, pod_set_finish);
883static DEVICE_ATTR(firmware_version, S_IRUGO, pod_get_firmware_version, line6_nop_write);
884static DEVICE_ATTR(midi_postprocess, S_IWUGO | S_IRUGO, pod_get_midi_postprocess, pod_set_midi_postprocess);
885static DEVICE_ATTR(monitor_level, S_IWUGO | S_IRUGO, pod_get_monitor_level, pod_set_monitor_level);
886static DEVICE_ATTR(name, S_IRUGO, pod_get_name, line6_nop_write);
887static DEVICE_ATTR(name_buf, S_IRUGO, pod_get_name_buf, line6_nop_write);
888static DEVICE_ATTR(retrieve_amp_setup, S_IWUGO, line6_nop_read, pod_set_retrieve_amp_setup);
889static DEVICE_ATTR(retrieve_channel, S_IWUGO, line6_nop_read, pod_set_retrieve_channel);
890static DEVICE_ATTR(retrieve_effects_setup, S_IWUGO, line6_nop_read, pod_set_retrieve_effects_setup);
891static DEVICE_ATTR(routing, S_IWUGO | S_IRUGO, pod_get_routing, pod_set_routing);
892static DEVICE_ATTR(serial_number, S_IRUGO, pod_get_serial_number, line6_nop_write);
893static DEVICE_ATTR(store_amp_setup, S_IWUGO, line6_nop_read, pod_set_store_amp_setup);
894static DEVICE_ATTR(store_channel, S_IWUGO, line6_nop_read, pod_set_store_channel);
895static DEVICE_ATTR(store_effects_setup, S_IWUGO, line6_nop_read, pod_set_store_effects_setup);
896static DEVICE_ATTR(tuner_freq, S_IWUGO | S_IRUGO, pod_get_tuner_freq, pod_set_tuner_freq);
897static DEVICE_ATTR(tuner_mute, S_IWUGO | S_IRUGO, pod_get_tuner_mute, pod_set_tuner_mute);
898static DEVICE_ATTR(tuner_note, S_IRUGO, pod_get_tuner_note, line6_nop_write);
899static DEVICE_ATTR(tuner_pitch, S_IRUGO, pod_get_tuner_pitch, line6_nop_write);
900
901#if CREATE_RAW_FILE
902static DEVICE_ATTR(raw, S_IWUGO, line6_nop_read, line6_set_raw);
903#endif
904
905/*
906 POD destructor.
907*/
908static void pod_destruct(struct usb_interface *interface)
909{
910 struct usb_line6_pod *pod = usb_get_intfdata(interface);
911 struct usb_line6 *line6;
912
913 if(pod == NULL) return;
914 line6 = &pod->line6;
915 if(line6 == NULL) return;
916 line6_cleanup_audio(line6);
917
918 /* free dump request data: */
919 line6_dumpreq_destruct(&pod->dumpreq);
920
921 if(pod->buffer_versionreq) kfree(pod->buffer_versionreq);
922}
923
924/*
925 Create sysfs entries.
926*/
927int pod_create_files2(struct device *dev)
928{
929 int err;
930
931 CHECK_RETURN(device_create_file(dev, &dev_attr_channel));
932 CHECK_RETURN(device_create_file(dev, &dev_attr_clip));
933 CHECK_RETURN(device_create_file(dev, &dev_attr_device_id));
934 CHECK_RETURN(device_create_file(dev, &dev_attr_dirty));
935 CHECK_RETURN(device_create_file(dev, &dev_attr_dump));
936 CHECK_RETURN(device_create_file(dev, &dev_attr_dump_buf));
937 CHECK_RETURN(device_create_file(dev, &dev_attr_finish));
938 CHECK_RETURN(device_create_file(dev, &dev_attr_firmware_version));
939 CHECK_RETURN(device_create_file(dev, &dev_attr_midi_postprocess));
940 CHECK_RETURN(device_create_file(dev, &dev_attr_monitor_level));
941 CHECK_RETURN(device_create_file(dev, &dev_attr_name));
942 CHECK_RETURN(device_create_file(dev, &dev_attr_name_buf));
943 CHECK_RETURN(device_create_file(dev, &dev_attr_retrieve_amp_setup));
944 CHECK_RETURN(device_create_file(dev, &dev_attr_retrieve_channel));
945 CHECK_RETURN(device_create_file(dev, &dev_attr_retrieve_effects_setup));
946 CHECK_RETURN(device_create_file(dev, &dev_attr_routing));
947 CHECK_RETURN(device_create_file(dev, &dev_attr_serial_number));
948 CHECK_RETURN(device_create_file(dev, &dev_attr_store_amp_setup));
949 CHECK_RETURN(device_create_file(dev, &dev_attr_store_channel));
950 CHECK_RETURN(device_create_file(dev, &dev_attr_store_effects_setup));
951 CHECK_RETURN(device_create_file(dev, &dev_attr_tuner_freq));
952 CHECK_RETURN(device_create_file(dev, &dev_attr_tuner_mute));
953 CHECK_RETURN(device_create_file(dev, &dev_attr_tuner_note));
954 CHECK_RETURN(device_create_file(dev, &dev_attr_tuner_pitch));
955
956#if CREATE_RAW_FILE
957 CHECK_RETURN(device_create_file(dev, &dev_attr_raw));
958#endif
959
960 return 0;
961}
962
963/*
964 Init POD device.
965*/
966int pod_init(struct usb_interface *interface, struct usb_line6_pod *pod)
967{
968 int err;
969 struct usb_line6 *line6 = &pod->line6;
970
971 if((interface == NULL) || (pod == NULL)) return -ENODEV;
972
973 pod->channel_num = 255;
974
975 /* initialize wait queues: */
976 init_waitqueue_head(&pod->monitor_level.wait);
977 init_waitqueue_head(&pod->routing.wait);
978 init_waitqueue_head(&pod->tuner_mute.wait);
979 init_waitqueue_head(&pod->tuner_freq.wait);
980 init_waitqueue_head(&pod->tuner_note.wait);
981 init_waitqueue_head(&pod->tuner_pitch.wait);
982 init_waitqueue_head(&pod->clipping.wait);
983
984 memset(pod->param_dirty, 0xff, sizeof(pod->param_dirty));
985
986 /* initialize USB buffers: */
987 err = line6_dumpreq_init(&pod->dumpreq, pod_request_channel, sizeof(pod_request_channel));
988
989 if(err < 0) {
990 dev_err(&interface->dev, "Out of memory\n");
991 pod_destruct(interface);
992 return -ENOMEM;
993 }
994
995 pod->buffer_versionreq = kmalloc(sizeof(pod_request_version), GFP_KERNEL);
996
997 if(pod->buffer_versionreq == NULL) {
998 dev_err(&interface->dev, "Out of memory\n");
999 pod_destruct(interface);
1000 return -ENOMEM;
1001 }
1002
1003 memcpy(pod->buffer_versionreq, pod_request_version, sizeof(pod_request_version));
1004
1005 /* create sysfs entries: */
1006 if((err = pod_create_files2(&interface->dev)) < 0) {
1007 pod_destruct(interface);
1008 return err;
1009 }
1010
1011 /* initialize audio system: */
1012 if((err = line6_init_audio(line6)) < 0) {
1013 pod_destruct(interface);
1014 return err;
1015 }
1016
1017 /* initialize MIDI subsystem: */
1018 if((err = line6_init_midi(line6)) < 0) {
1019 pod_destruct(interface);
1020 return err;
1021 }
1022
1023 /* initialize PCM subsystem: */
1024 if((err = line6_init_pcm(line6, &pod_pcm_properties)) < 0) {
1025 pod_destruct(interface);
1026 return err;
1027 }
1028
1029 /* register audio system: */
1030 if((err = line6_register_audio(line6)) < 0) {
1031 pod_destruct(interface);
1032 return err;
1033 }
1034
1035 if(pod->line6.properties->capabilities & LINE6_BIT_CONTROL) {
1036 /* query some data: */
1037 line6_startup_delayed(&pod->dumpreq, POD_STARTUP_DELAY, pod_startup_timeout, pod);
1038 line6_read_serial_number(&pod->line6, &pod->serial_number);
1039 }
1040
1041 return 0;
1042}
1043
1044/*
1045 POD device disconnected.
1046*/
1047void pod_disconnect(struct usb_interface *interface)
1048{
1049 struct usb_line6_pod *pod;
1050
1051 if(interface == NULL) return;
1052 pod = usb_get_intfdata(interface);
1053
1054 if(pod != NULL) {
1055 struct snd_line6_pcm *line6pcm = pod->line6.line6pcm;
1056 struct device *dev = &interface->dev;
1057
1058 if(line6pcm != NULL) {
1059 unlink_wait_clear_audio_out_urbs(line6pcm);
1060 unlink_wait_clear_audio_in_urbs(line6pcm);
1061 }
1062
1063 if(dev != NULL) {
1064 /* remove sysfs entries: */
1065 if(pod->versionreq_ok)
1066 pod_remove_files(pod->firmware_version, pod->line6.properties->device_bit, dev);
1067
1068 device_remove_file(dev, &dev_attr_channel);
1069 device_remove_file(dev, &dev_attr_clip);
1070 device_remove_file(dev, &dev_attr_device_id);
1071 device_remove_file(dev, &dev_attr_dirty);
1072 device_remove_file(dev, &dev_attr_dump);
1073 device_remove_file(dev, &dev_attr_dump_buf);
1074 device_remove_file(dev, &dev_attr_finish);
1075 device_remove_file(dev, &dev_attr_firmware_version);
1076 device_remove_file(dev, &dev_attr_midi_postprocess);
1077 device_remove_file(dev, &dev_attr_monitor_level);
1078 device_remove_file(dev, &dev_attr_name);
1079 device_remove_file(dev, &dev_attr_name_buf);
1080 device_remove_file(dev, &dev_attr_retrieve_amp_setup);
1081 device_remove_file(dev, &dev_attr_retrieve_channel);
1082 device_remove_file(dev, &dev_attr_retrieve_effects_setup);
1083 device_remove_file(dev, &dev_attr_routing);
1084 device_remove_file(dev, &dev_attr_serial_number);
1085 device_remove_file(dev, &dev_attr_store_amp_setup);
1086 device_remove_file(dev, &dev_attr_store_channel);
1087 device_remove_file(dev, &dev_attr_store_effects_setup);
1088 device_remove_file(dev, &dev_attr_tuner_freq);
1089 device_remove_file(dev, &dev_attr_tuner_mute);
1090 device_remove_file(dev, &dev_attr_tuner_note);
1091 device_remove_file(dev, &dev_attr_tuner_pitch);
1092
1093#if CREATE_RAW_FILE
1094 device_remove_file(dev, &dev_attr_raw);
1095#endif
1096 }
1097 }
1098
1099 pod_destruct(interface);
1100}
diff --git a/drivers/staging/line6/pod.h b/drivers/staging/line6/pod.h
new file mode 100644
index 000000000000..0db59484c4ba
--- /dev/null
+++ b/drivers/staging/line6/pod.h
@@ -0,0 +1,203 @@
1/*
2 * Line6 Linux USB driver - 0.8.0
3 *
4 * Copyright (C) 2004-2009 Markus Grabner (grabner@icg.tugraz.at)
5 *
6 * This program is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU General Public License as
8 * published by the Free Software Foundation, version 2.
9 *
10 */
11
12#ifndef POD_H
13#define POD_H
14
15
16#include "driver.h"
17
18#include <linux/spinlock.h>
19#include <linux/usb.h>
20#include <linux/wait.h>
21#include <linux/workqueue.h>
22
23#include <sound/core.h>
24
25#include "dumprequest.h"
26
27
28/*
29 PODxt Live interfaces
30*/
31#define PODXTLIVE_INTERFACE_POD 0
32#define PODXTLIVE_INTERFACE_VARIAX 1
33
34/*
35 Locate name in binary program dump
36*/
37#define POD_NAME_OFFSET 0
38#define POD_NAME_LENGTH 16
39
40/*
41 Other constants
42*/
43#define POD_CONTROL_SIZE 0x80
44#define POD_BUFSIZE_DUMPREQ 7
45#define POD_STARTUP_DELAY 3
46
47
48/**
49 Data structure for values that need to be requested explicitly.
50 This is the case for system and tuner settings.
51*/
52struct ValueWait
53{
54 unsigned short value;
55 wait_queue_head_t wait;
56};
57
58/**
59 Binary PodXT Pro program dump
60*/
61struct pod_program {
62 /**
63 Header information (including program name).
64 */
65 unsigned char header[0x20];
66
67 /**
68 Program parameters.
69 */
70 unsigned char control[POD_CONTROL_SIZE];
71};
72
73struct usb_line6_pod {
74 /**
75 Generic Line6 USB data.
76 */
77 struct usb_line6 line6;
78
79 /**
80 Dump request structure.
81 */
82 struct line6_dump_request dumpreq;
83
84 /**
85 Current program number.
86 */
87 unsigned char channel_num;
88
89 /**
90 Current program settings.
91 */
92 struct pod_program prog_data;
93
94 /**
95 Buffer for data retrieved from or to be stored on PODxt Pro.
96 */
97 struct pod_program prog_data_buf;
98
99 /**
100 Buffer for requesting version number.
101 */
102 unsigned char *buffer_versionreq;
103
104 /**
105 Tuner mute mode.
106 */
107 struct ValueWait tuner_mute;
108
109 /**
110 Tuner base frequency (typically 440Hz).
111 */
112 struct ValueWait tuner_freq;
113
114 /**
115 Note received from tuner.
116 */
117 struct ValueWait tuner_note;
118
119 /**
120 Pitch value received from tuner.
121 */
122 struct ValueWait tuner_pitch;
123
124 /**
125 Instrument monitor level.
126 */
127 struct ValueWait monitor_level;
128
129 /**
130 Audio routing mode.
131 0: send processed guitar
132 1: send clean guitar
133 2: send clean guitar re-amp playback
134 3: send re-amp playback
135 */
136 struct ValueWait routing;
137
138 /**
139 Wait for audio clipping event.
140 */
141 struct ValueWait clipping;
142
143 /**
144 Bottom-half for creation of sysfs special files.
145 */
146 struct work_struct create_files_work;
147
148 /**
149 Dirty flags for access to parameter data.
150 */
151 unsigned long param_dirty[POD_CONTROL_SIZE / sizeof(unsigned long)];
152
153 /**
154 Some atomic flags.
155 */
156 unsigned long atomic_flags;
157
158 /**
159 Counter for startup process.
160 */
161 int startup_count;
162
163 /**
164 Serial number of device.
165 */
166 int serial_number;
167
168 /**
169 Firmware version (x 100).
170 */
171 int firmware_version;
172
173 /**
174 Device ID.
175 */
176 int device_id;
177
178 /**
179 Flag to indicate modification of current program settings.
180 */
181 char dirty;
182
183 /**
184 Flag if initial firmware version request has been successful.
185 */
186 char versionreq_ok;
187
188 /**
189 Flag to enable MIDI postprocessing.
190 */
191 char midi_postprocess;
192};
193
194
195extern void pod_disconnect(struct usb_interface *interface);
196extern int pod_init(struct usb_interface *interface, struct usb_line6_pod *pod);
197extern void pod_midi_postprocess(struct usb_line6_pod *pod, unsigned char *data, int length);
198extern void pod_process_message(struct usb_line6_pod *pod);
199extern void pod_receive_parameter(struct usb_line6_pod *pod, int param);
200extern void pod_transmit_parameter(struct usb_line6_pod *pod, int param, int value);
201
202
203#endif
diff --git a/drivers/staging/line6/revision.h b/drivers/staging/line6/revision.h
new file mode 100644
index 000000000000..b2a0a85efe69
--- /dev/null
+++ b/drivers/staging/line6/revision.h
@@ -0,0 +1,4 @@
1#ifndef DRIVER_REVISION
2/* current subversion revision */
3#define DRIVER_REVISION " (revision 529)"
4#endif
diff --git a/drivers/staging/line6/toneport.c b/drivers/staging/line6/toneport.c
new file mode 100644
index 000000000000..c9fe07feab69
--- /dev/null
+++ b/drivers/staging/line6/toneport.c
@@ -0,0 +1,219 @@
1/*
2 * Line6 Linux USB driver - 0.8.0
3 *
4 * Copyright (C) 2004-2009 Markus Grabner (grabner@icg.tugraz.at)
5 * Emil Myhrman (emil.myhrman@gmail.com)
6 *
7 * This program is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU General Public License as
9 * published by the Free Software Foundation, version 2.
10 *
11 */
12
13#include "driver.h"
14
15#include "audio.h"
16#include "capture.h"
17#include "playback.h"
18#include "toneport.h"
19
20
21static int toneport_send_cmd(struct usb_device *usbdev, int cmd1, int cmd2);
22
23
24static struct snd_ratden toneport_ratden = {
25 .num_min = 44100,
26 .num_max = 44100,
27 .num_step = 1,
28 .den = 1
29};
30
31static struct line6_pcm_properties toneport_pcm_properties = {
32 .snd_line6_playback_hw = {
33 .info = (SNDRV_PCM_INFO_MMAP |
34 SNDRV_PCM_INFO_INTERLEAVED |
35 SNDRV_PCM_INFO_BLOCK_TRANSFER |
36 SNDRV_PCM_INFO_MMAP_VALID |
37 SNDRV_PCM_INFO_PAUSE |
38 SNDRV_PCM_INFO_SYNC_START),
39 .formats = SNDRV_PCM_FMTBIT_S16_LE,
40 .rates = SNDRV_PCM_RATE_KNOT,
41 .rate_min = 44100,
42 .rate_max = 44100,
43 .channels_min = 2,
44 .channels_max = 2,
45 .buffer_bytes_max = 60000,
46 .period_bytes_min = 180 * 4,
47 .period_bytes_max = 8192,
48 .periods_min = 1,
49 .periods_max = 1024
50 },
51 .snd_line6_capture_hw = {
52 .info = (SNDRV_PCM_INFO_MMAP |
53 SNDRV_PCM_INFO_INTERLEAVED |
54 SNDRV_PCM_INFO_BLOCK_TRANSFER |
55 SNDRV_PCM_INFO_MMAP_VALID |
56 SNDRV_PCM_INFO_SYNC_START),
57 .formats = SNDRV_PCM_FMTBIT_S16_LE,
58 .rates = SNDRV_PCM_RATE_KNOT,
59 .rate_min = 44100,
60 .rate_max = 44100,
61 .channels_min = 2,
62 .channels_max = 2,
63 .buffer_bytes_max = 60000,
64 .period_bytes_min = 188 * 4,
65 .period_bytes_max = 8192,
66 .periods_min = 1,
67 .periods_max = 1024
68 },
69 .snd_line6_rates = {
70 .nrats = 1,
71 .rats = &toneport_ratden
72 },
73 .bytes_per_frame = 4
74};
75
76/*
77 For the led on Guitarport.
78 Brightness goes from 0x00 to 0x26. Set a value above this to have led blink.
79 (void cmd_0x02(byte red, byte green)
80*/
81static int led_red = 0x00;
82static int led_green = 0x26;
83
84static void toneport_update_led(struct device *dev) {
85 struct usb_interface *interface;
86 struct usb_line6_toneport *tp;
87 struct usb_line6* line6;
88
89 if ((interface = to_usb_interface(dev)) &&
90 (tp = usb_get_intfdata(interface)) &&
91 (line6 = &tp->line6))
92 toneport_send_cmd(line6->usbdev, (led_red<<8)|0x0002, led_green); // for setting the LED on Guitarport
93}
94static ssize_t toneport_set_led_red(struct device *dev, DEVICE_ATTRIBUTE const char *buf, size_t count) {
95 char* c;
96 led_red = simple_strtol(buf, &c, 10);
97 toneport_update_led(dev);
98 return count;
99}
100static ssize_t toneport_set_led_green(struct device *dev, DEVICE_ATTRIBUTE const char *buf, size_t count) {
101 char* c;
102 led_green = simple_strtol(buf, &c, 10);
103 toneport_update_led(dev);
104 return count;
105}
106
107static DEVICE_ATTR(led_red, S_IWUGO | S_IRUGO, line6_nop_read, toneport_set_led_red);
108static DEVICE_ATTR(led_green, S_IWUGO | S_IRUGO, line6_nop_read, toneport_set_led_green);
109
110
111static int toneport_send_cmd(struct usb_device *usbdev, int cmd1, int cmd2)
112{
113 int ret;
114 ret = usb_control_msg(usbdev, usb_sndctrlpipe(usbdev,0), 0x67,
115 USB_TYPE_VENDOR | USB_RECIP_DEVICE | USB_DIR_OUT,
116 cmd1, cmd2, 0, 0, LINE6_TIMEOUT * HZ);
117
118 if(ret < 0) {
119 err("send failed (error %d)\n", ret);
120 return ret;
121 }
122
123 return 0;
124}
125
126/*
127 Toneport destructor.
128*/
129static void toneport_destruct(struct usb_interface *interface)
130{
131 struct usb_line6_toneport *toneport = usb_get_intfdata(interface);
132 struct usb_line6 *line6;
133
134 if(toneport == NULL) return;
135 line6 = &toneport->line6;
136 if(line6 == NULL) return;
137 line6_cleanup_audio(line6);
138}
139
140/*
141 Init Toneport device.
142*/
143int toneport_init(struct usb_interface *interface, struct usb_line6_toneport *toneport)
144{
145 int err, ticks;
146 struct usb_line6 *line6 = &toneport->line6;
147 struct usb_device *usbdev;
148
149 if((interface == NULL) || (toneport == NULL))
150 return -ENODEV;
151
152 /* initialize audio system: */
153 if((err = line6_init_audio(line6)) < 0) {
154 toneport_destruct(interface);
155 return err;
156 }
157
158 /* initialize PCM subsystem: */
159 if((err = line6_init_pcm(line6, &toneport_pcm_properties)) < 0) {
160 toneport_destruct(interface);
161 return err;
162 }
163
164 /* register audio system: */
165 if((err = line6_register_audio(line6)) < 0) {
166 toneport_destruct(interface);
167 return err;
168 }
169
170 usbdev = line6->usbdev;
171 line6_read_serial_number(line6, &toneport->serial_number);
172 line6_read_data(line6, 0x80c2, &toneport->firmware_version, 1);
173
174 /* sync time on device with host: */
175 ticks = (int)get_seconds();
176 line6_write_data(line6, 0x80c6, &ticks, 4);
177
178 /*
179 seems to work without the first two...
180 */
181 //toneport_send_cmd(usbdev, 0x0201, 0x0002); // ..
182 //toneport_send_cmd(usbdev, 0x0801, 0x0000); // ..
183 toneport_send_cmd(usbdev, 0x0301, 0x0000); // only one that works for me; on GP, TP might be different?
184
185 if (usbdev->descriptor.idProduct!=LINE6_DEVID_GUITARPORT) {
186 CHECK_RETURN(device_create_file(&interface->dev, &dev_attr_led_red));
187 CHECK_RETURN(device_create_file(&interface->dev, &dev_attr_led_green));
188 toneport_update_led(&usbdev->dev);
189 }
190
191 return 0;
192}
193
194/*
195 Toneport device disconnected.
196*/
197void toneport_disconnect(struct usb_interface *interface)
198{
199 struct usb_line6_toneport *toneport;
200
201 if(interface == NULL) return;
202 toneport = usb_get_intfdata(interface);
203
204 if (toneport->line6.usbdev->descriptor.idProduct != LINE6_DEVID_GUITARPORT) {
205 device_remove_file(&interface->dev, &dev_attr_led_red);
206 device_remove_file(&interface->dev, &dev_attr_led_green);
207 }
208
209 if(toneport != NULL) {
210 struct snd_line6_pcm *line6pcm = toneport->line6.line6pcm;
211
212 if(line6pcm != NULL) {
213 unlink_wait_clear_audio_out_urbs(line6pcm);
214 unlink_wait_clear_audio_in_urbs(line6pcm);
215 }
216 }
217
218 toneport_destruct(interface);
219}
diff --git a/drivers/staging/line6/toneport.h b/drivers/staging/line6/toneport.h
new file mode 100644
index 000000000000..cd0b19fe7c84
--- /dev/null
+++ b/drivers/staging/line6/toneport.h
@@ -0,0 +1,44 @@
1/*
2 * Line6 Linux USB driver - 0.8.0
3 *
4 * Copyright (C) 2004-2009 Markus Grabner (grabner@icg.tugraz.at)
5 *
6 * This program is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU General Public License as
8 * published by the Free Software Foundation, version 2.
9 *
10 */
11
12#ifndef TONEPORT_H
13#define TONEPORT_H
14
15
16#include "driver.h"
17
18#include <linux/usb.h>
19#include <sound/core.h>
20
21
22struct usb_line6_toneport {
23 /**
24 Generic Line6 USB data.
25 */
26 struct usb_line6 line6;
27
28 /**
29 Serial number of device.
30 */
31 int serial_number;
32
33 /**
34 Firmware version (x 100).
35 */
36 int firmware_version;
37};
38
39
40extern void toneport_disconnect(struct usb_interface *interface);
41extern int toneport_init(struct usb_interface *interface, struct usb_line6_toneport *toneport);
42
43
44#endif
diff --git a/drivers/staging/line6/usbdefs.h b/drivers/staging/line6/usbdefs.h
new file mode 100644
index 000000000000..cbf5d0d62a1f
--- /dev/null
+++ b/drivers/staging/line6/usbdefs.h
@@ -0,0 +1,75 @@
1/*
2 * Line6 Linux USB driver - 0.8.0
3 *
4 * Copyright (C) 2005-2008 Markus Grabner (grabner@icg.tugraz.at)
5 *
6 * This program is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU General Public License as
8 * published by the Free Software Foundation, version 2.
9 *
10 */
11
12#ifndef USBDEFS_H
13#define USBDEFS_H
14
15
16#include <linux/version.h>
17
18
19#define LINE6_VENDOR_ID 0x0e41
20
21#define USB_INTERVALS_PER_SECOND 1000
22
23/*
24 Device ids.
25*/
26#define LINE6_DEVID_BASSPODXT 0x4250
27#define LINE6_DEVID_BASSPODXTLIVE 0x4642
28#define LINE6_DEVID_BASSPODXTPRO 0x4252
29#define LINE6_DEVID_GUITARPORT 0x4750
30#define LINE6_DEVID_POCKETPOD 0x5051
31#define LINE6_DEVID_PODX3 0x414a
32#define LINE6_DEVID_PODX3LIVE 0x414b
33#define LINE6_DEVID_PODXT 0x5044
34#define LINE6_DEVID_PODXTLIVE 0x4650
35#define LINE6_DEVID_PODXTPRO 0x5050
36#define LINE6_DEVID_TONEPORT_GX 0x4147
37#define LINE6_DEVID_TONEPORT_UX1 0x4141
38#define LINE6_DEVID_TONEPORT_UX2 0x4142
39#define LINE6_DEVID_VARIAX 0x534d
40
41#define LINE6_BIT_BASSPODXT (1 << 0)
42#define LINE6_BIT_BASSPODXTLIVE (1 << 1)
43#define LINE6_BIT_BASSPODXTPRO (1 << 2)
44#define LINE6_BIT_GUITARPORT (1 << 3)
45#define LINE6_BIT_POCKETPOD (1 << 4)
46#define LINE6_BIT_PODX3 (1 << 5)
47#define LINE6_BIT_PODX3LIVE (1 << 6)
48#define LINE6_BIT_PODXT (1 << 7)
49#define LINE6_BIT_PODXTLIVE (1 << 8)
50#define LINE6_BIT_PODXTPRO (1 << 9)
51#define LINE6_BIT_TONEPORT_GX (1 << 10)
52#define LINE6_BIT_TONEPORT_UX1 (1 << 11)
53#define LINE6_BIT_TONEPORT_UX2 (1 << 12)
54#define LINE6_BIT_VARIAX (1 << 13)
55
56#define LINE6_BITS_PRO (LINE6_BIT_BASSPODXTPRO | LINE6_BIT_PODXTPRO)
57#define LINE6_BITS_LIVE (LINE6_BIT_BASSPODXTLIVE | LINE6_BIT_PODXTLIVE | LINE6_BIT_PODX3LIVE)
58#define LINE6_BITS_PODXTALL (LINE6_BIT_PODXT | LINE6_BIT_PODXTLIVE | LINE6_BIT_PODXTPRO)
59#define LINE6_BITS_BASSPODXTALL (LINE6_BIT_BASSPODXT | LINE6_BIT_BASSPODXTLIVE | LINE6_BIT_BASSPODXTPRO)
60
61#define LINE6_BIT_CONTROL (1 << 0) /* device supports settings parameter via USB */
62#define LINE6_BIT_PCM (1 << 1) /* device supports PCM input/output via USB */
63#define LINE6_BIT_CONTROL_PCM (LINE6_BIT_CONTROL | LINE6_BIT_PCM)
64
65#define LINE6_FALLBACK_INTERVAL 10
66#define LINE6_FALLBACK_MAXPACKETSIZE 16
67
68
69#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 18)
70#define usb_interrupt_msg(usb_dev, pipe, data, len, actual_length, timeout) \
71usb_bulk_msg(usb_dev, pipe, data, len, actual_length, timeout)
72#endif
73
74
75#endif
diff --git a/drivers/staging/line6/variax.c b/drivers/staging/line6/variax.c
new file mode 100644
index 000000000000..edb02a39d820
--- /dev/null
+++ b/drivers/staging/line6/variax.c
@@ -0,0 +1,501 @@
1/*
2 * Line6 Linux USB driver - 0.8.0
3 *
4 * Copyright (C) 2004-2009 Markus Grabner (grabner@icg.tugraz.at)
5 *
6 * This program is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU General Public License as
8 * published by the Free Software Foundation, version 2.
9 *
10 */
11
12#include "driver.h"
13
14#include "audio.h"
15#include "control.h"
16#include "variax.h"
17
18
19#define VARIAX_SYSEX_CODE 7
20#define VARIAX_SYSEX_PARAM 0x3b
21#define VARIAX_SYSEX_ACTIVATE 0x2a
22#define VARIAX_MODEL_HEADER_LENGTH 7
23#define VARIAX_MODEL_MESSAGE_LENGTH 199
24#define VARIAX_OFFSET_ACTIVATE 7
25
26
27static const char variax_activate[] = {
28 0xf0, 0x00, 0x01, 0x0c, 0x07, 0x00, 0x2a, 0x01,
29 0xf7
30};
31static const char variax_request_bank[] = {
32 0xf0, 0x00, 0x01, 0x0c, 0x07, 0x00, 0x6d, 0xf7
33};
34static const char variax_request_model1[] = {
35 0xf0, 0x00, 0x01, 0x0c, 0x07, 0x00, 0x3c, 0x00,
36 0x02, 0x00, 0x00, 0x00, 0x00, 0x03, 0x05, 0x03,
37 0x00, 0x00, 0x00, 0xf7
38};
39static const char variax_request_model2[] = {
40 0xf0, 0x00, 0x01, 0x0c, 0x07, 0x00, 0x3c, 0x00,
41 0x02, 0x00, 0x00, 0x00, 0x00, 0x03, 0x07, 0x03,
42 0x00, 0x00, 0x00, 0xf7
43};
44
45
46/*
47 Decode data transmitted by workbench.
48*/
49static void variax_decode(const unsigned char *raw_data, unsigned char *data, int raw_size)
50{
51 for(; raw_size > 0; raw_size -= 6) {
52 data[2] = raw_data[0] | (raw_data[1] << 4);
53 data[1] = raw_data[2] | (raw_data[3] << 4);
54 data[0] = raw_data[4] | (raw_data[5] << 4);
55 raw_data += 6;
56 data += 3;
57 }
58}
59
60static void variax_activate_timeout(unsigned long arg)
61{
62 struct usb_line6_variax *variax = (struct usb_line6_variax *)arg;
63 variax->buffer_activate[VARIAX_OFFSET_ACTIVATE] = 1;
64 line6_send_raw_message_async(&variax->line6, variax->buffer_activate, sizeof(variax_activate));
65}
66
67/*
68 Send an asynchronous activation request after a given interval.
69*/
70static void variax_activate_delayed(struct usb_line6_variax *variax, int seconds)
71{
72 variax->activate_timer.expires = jiffies + seconds * HZ;
73 variax->activate_timer.function = variax_activate_timeout;
74 variax->activate_timer.data = (unsigned long)variax;
75 add_timer(&variax->activate_timer);
76}
77
78static void variax_startup_timeout(unsigned long arg)
79{
80 struct usb_line6_variax *variax = (struct usb_line6_variax *)arg;
81
82 if(variax->dumpreq.ok)
83 return;
84
85 line6_dump_request_async(&variax->dumpreq, &variax->line6, 0);
86 line6_startup_delayed(&variax->dumpreq, 1, variax_startup_timeout, variax);
87}
88
89/*
90 Process a completely received message.
91*/
92void variax_process_message(struct usb_line6_variax *variax)
93{
94 const unsigned char *buf = variax->line6.buffer_message;
95
96 switch(buf[0]) {
97 case LINE6_PARAM_CHANGE | LINE6_CHANNEL_HOST:
98 switch(buf[1]) {
99 case VARIAXMIDI_volume:
100 variax->volume = buf[2];
101 break;
102
103 case VARIAXMIDI_tone:
104 variax->tone = buf[2];
105 }
106
107 break;
108
109 case LINE6_PROGRAM_CHANGE | LINE6_CHANNEL_DEVICE:
110 case LINE6_PROGRAM_CHANGE | LINE6_CHANNEL_HOST:
111 variax->model = buf[1];
112 line6_dump_request_async(&variax->dumpreq, &variax->line6, 0);
113 break;
114
115 case LINE6_RESET:
116 dev_info(variax->line6.ifcdev, "VARIAX reset\n");
117 variax_activate_delayed(variax, VARIAX_ACTIVATE_DELAY);
118 break;
119
120 case LINE6_SYSEX_BEGIN:
121 if(memcmp(buf + 1, variax_request_model1 + 1, VARIAX_MODEL_HEADER_LENGTH - 1) == 0) {
122 if(variax->line6.message_length == VARIAX_MODEL_MESSAGE_LENGTH) {
123 switch(variax->dumpreq.in_progress) {
124 case VARIAX_DUMP_PASS1:
125 variax_decode(buf + VARIAX_MODEL_HEADER_LENGTH, (unsigned char *)&variax->model_data,
126 (sizeof(variax->model_data.name) + sizeof(variax->model_data.control) / 2) * 2);
127 line6_dump_request_async(&variax->dumpreq, &variax->line6, 1);
128 line6_dump_started(&variax->dumpreq, VARIAX_DUMP_PASS2);
129 break;
130
131 case VARIAX_DUMP_PASS2:
132 /* model name is transmitted twice, so skip it here: */
133 variax_decode(buf + VARIAX_MODEL_HEADER_LENGTH,
134 (unsigned char *)&variax->model_data.control + sizeof(variax->model_data.control) / 2,
135 sizeof(variax->model_data.control) / 2 * 2);
136 variax->dumpreq.ok = 1;
137 line6_dump_request_async(&variax->dumpreq, &variax->line6, 2);
138 line6_dump_started(&variax->dumpreq, VARIAX_DUMP_PASS3);
139 }
140 }
141 else {
142 DEBUG_MESSAGES(dev_err(variax->line6.ifcdev, "illegal length %d of model data\n", variax->line6.message_length));
143 line6_dump_finished(&variax->dumpreq);
144 }
145 }
146 else if(memcmp(buf + 1, variax_request_bank + 1, sizeof(variax_request_bank) - 2) == 0) {
147 memcpy(variax->bank, buf + sizeof(variax_request_bank) - 1, sizeof(variax->bank));
148 variax->dumpreq.ok = 1;
149 line6_dump_finished(&variax->dumpreq);
150 }
151
152 break;
153
154 case LINE6_SYSEX_END:
155 break;
156
157 default:
158 DEBUG_MESSAGES(dev_err(variax->line6.ifcdev, "Variax: unknown message %02X\n", buf[0]));
159 }
160}
161
162/*
163 "read" request on "volume" special file.
164*/
165static ssize_t variax_get_volume(struct device *dev, DEVICE_ATTRIBUTE char *buf)
166{
167 struct usb_line6_variax *variax = usb_get_intfdata(to_usb_interface(dev));
168 return sprintf(buf, "%d\n", variax->volume);
169}
170
171/*
172 "write" request on "volume" special file.
173*/
174static ssize_t variax_set_volume(struct device *dev, DEVICE_ATTRIBUTE const char *buf, size_t count)
175{
176 struct usb_line6_variax *variax = usb_get_intfdata(to_usb_interface(dev));
177 int value = simple_strtoul(buf, NULL, 10);
178
179 if(line6_transmit_parameter(&variax->line6, VARIAXMIDI_volume, value) == 0)
180 variax->volume = value;
181
182 return count;
183}
184
185/*
186 "read" request on "model" special file.
187*/
188static ssize_t variax_get_model(struct device *dev, DEVICE_ATTRIBUTE char *buf)
189{
190 struct usb_line6_variax *variax = usb_get_intfdata(to_usb_interface(dev));
191 return sprintf(buf, "%d\n", variax->model);
192}
193
194/*
195 "write" request on "model" special file.
196*/
197static ssize_t variax_set_model(struct device *dev, DEVICE_ATTRIBUTE const char *buf, size_t count)
198{
199 struct usb_line6_variax *variax = usb_get_intfdata( to_usb_interface(dev));
200 int value = simple_strtoul(buf, NULL, 10);
201
202 if(line6_send_program(&variax->line6, value) == 0)
203 variax->model = value;
204
205 return count;
206}
207
208/*
209 "read" request on "active" special file.
210*/
211static ssize_t variax_get_active(struct device *dev, DEVICE_ATTRIBUTE char *buf)
212{
213 struct usb_line6_variax *variax = usb_get_intfdata(to_usb_interface(dev));
214 return sprintf(buf, "%d\n", variax->buffer_activate[VARIAX_OFFSET_ACTIVATE]);
215}
216
217/*
218 "write" request on "active" special file.
219*/
220static ssize_t variax_set_active(struct device *dev, DEVICE_ATTRIBUTE const char *buf, size_t count)
221{
222 struct usb_line6_variax *variax = usb_get_intfdata(to_usb_interface(dev));
223 int value = simple_strtoul(buf, NULL, 10) ? 1 : 0;
224 variax->buffer_activate[VARIAX_OFFSET_ACTIVATE] = value;
225 line6_send_raw_message_async(&variax->line6, variax->buffer_activate, sizeof(variax_activate));
226 return count;
227}
228
229/*
230 "read" request on "tone" special file.
231*/
232static ssize_t variax_get_tone(struct device *dev, DEVICE_ATTRIBUTE char *buf)
233{
234 struct usb_line6_variax *variax = usb_get_intfdata(to_usb_interface(dev));
235 return sprintf(buf, "%d\n", variax->tone);
236}
237
238/*
239 "write" request on "tone" special file.
240*/
241static ssize_t variax_set_tone(struct device *dev, DEVICE_ATTRIBUTE const char *buf, size_t count)
242{
243 struct usb_line6_variax *variax = usb_get_intfdata(to_usb_interface(dev));
244 int value = simple_strtoul(buf, NULL, 10);
245
246 if(line6_transmit_parameter(&variax->line6, VARIAXMIDI_tone, value) == 0)
247 variax->tone = value;
248
249 return count;
250}
251
252static ssize_t get_string(char *buf, const char *data, int length)
253{
254 int i;
255 memcpy(buf, data, length);
256
257 for(i = length; i--;) {
258 char c = buf[i];
259
260 if((c != 0) && (c != ' '))
261 break;
262 }
263
264 buf[i + 1] = '\n';
265 return i + 2;
266}
267
268/*
269 "read" request on "name" special file.
270*/
271static ssize_t variax_get_name(struct device *dev, DEVICE_ATTRIBUTE char *buf)
272{
273 struct usb_line6_variax *variax = usb_get_intfdata(to_usb_interface(dev));
274 line6_wait_dump(&variax->dumpreq, 0);
275 return get_string(buf, variax->model_data.name, sizeof(variax->model_data.name));
276}
277
278/*
279 "read" request on "bank" special file.
280*/
281static ssize_t variax_get_bank(struct device *dev, DEVICE_ATTRIBUTE char *buf)
282{
283 struct usb_line6_variax *variax = usb_get_intfdata(to_usb_interface(dev));
284 line6_wait_dump(&variax->dumpreq, 0);
285 return get_string(buf, variax->bank, sizeof(variax->bank));
286}
287
288/*
289 "read" request on "dump" special file.
290*/
291static ssize_t variax_get_dump(struct device *dev, DEVICE_ATTRIBUTE char *buf)
292{
293 struct usb_line6_variax *variax = usb_get_intfdata(to_usb_interface(dev));
294 int retval;
295 retval = line6_wait_dump(&variax->dumpreq, 0);
296 if(retval < 0) return retval;
297 memcpy(buf, &variax->model_data.control, sizeof(variax->model_data.control));
298 return sizeof(variax->model_data.control);
299}
300
301#if CREATE_RAW_FILE
302
303/*
304 "write" request on "raw" special file.
305*/
306static ssize_t variax_set_raw2(struct device *dev, DEVICE_ATTRIBUTE const char *buf, size_t count)
307{
308 struct usb_line6_variax *variax = usb_get_intfdata(to_usb_interface(dev));
309 int size;
310 int i;
311 char *sysex;
312
313 count -= count % 3;
314 size = count * 2;
315 sysex = variax_alloc_sysex_buffer(variax, VARIAX_SYSEX_PARAM, size);
316
317 if(!sysex)
318 return 0;
319
320 for(i = 0; i < count; i += 3) {
321 const unsigned char *p1 = buf + i;
322 char *p2 = sysex + SYSEX_DATA_OFS + i * 2;
323 p2[0] = p1[2] & 0x0f;
324 p2[1] = p1[2] >> 4;
325 p2[2] = p1[1] & 0x0f;
326 p2[3] = p1[1] >> 4;
327 p2[4] = p1[0] & 0x0f;
328 p2[5] = p1[0] >> 4;
329 }
330
331 line6_send_sysex_message(&variax->line6, sysex, size);
332 kfree(sysex);
333 return count;
334}
335
336#endif
337
338/* Variax workbench special files: */
339static DEVICE_ATTR(model, S_IWUGO | S_IRUGO, variax_get_model, variax_set_model);
340static DEVICE_ATTR(volume, S_IWUGO | S_IRUGO, variax_get_volume, variax_set_volume);
341static DEVICE_ATTR(tone, S_IWUGO | S_IRUGO, variax_get_tone, variax_set_tone);
342static DEVICE_ATTR(name, S_IRUGO, variax_get_name, line6_nop_write);
343static DEVICE_ATTR(bank, S_IRUGO, variax_get_bank, line6_nop_write);
344static DEVICE_ATTR(dump, S_IRUGO, variax_get_dump, line6_nop_write);
345static DEVICE_ATTR(active, S_IWUGO | S_IRUGO, variax_get_active, variax_set_active);
346
347#if CREATE_RAW_FILE
348static DEVICE_ATTR(raw, S_IWUGO, line6_nop_read, line6_set_raw);
349static DEVICE_ATTR(raw2, S_IWUGO, line6_nop_read, variax_set_raw2);
350#endif
351
352
353/*
354 Variax destructor.
355*/
356static void variax_destruct(struct usb_interface *interface)
357{
358 struct usb_line6_variax *variax = usb_get_intfdata(interface);
359 struct usb_line6 *line6;
360
361 if(variax == NULL) return;
362 line6 = &variax->line6;
363 if(line6 == NULL) return;
364 line6_cleanup_audio(line6);
365
366 /* free dump request data: */
367 line6_dumpreq_destructbuf(&variax->dumpreq, 2);
368 line6_dumpreq_destructbuf(&variax->dumpreq, 1);
369 line6_dumpreq_destruct(&variax->dumpreq);
370
371 if(variax->buffer_activate) kfree(variax->buffer_activate);
372 del_timer_sync(&variax->activate_timer);
373}
374
375/*
376 Create sysfs entries.
377*/
378int variax_create_files2(struct device *dev)
379{
380 int err;
381 CHECK_RETURN(device_create_file(dev, &dev_attr_model));
382 CHECK_RETURN(device_create_file(dev, &dev_attr_volume));
383 CHECK_RETURN(device_create_file(dev, &dev_attr_tone));
384 CHECK_RETURN(device_create_file(dev, &dev_attr_name));
385 CHECK_RETURN(device_create_file(dev, &dev_attr_bank));
386 CHECK_RETURN(device_create_file(dev, &dev_attr_dump));
387 CHECK_RETURN(device_create_file(dev, &dev_attr_active));
388#if CREATE_RAW_FILE
389 CHECK_RETURN(device_create_file(dev, &dev_attr_raw));
390 CHECK_RETURN(device_create_file(dev, &dev_attr_raw2));
391#endif
392 return 0;
393}
394
395/*
396 Init workbench device.
397*/
398int variax_init(struct usb_interface *interface, struct usb_line6_variax *variax)
399{
400 int err;
401
402 if((interface == NULL) || (variax == NULL)) return -ENODEV;
403
404 /* initialize USB buffers: */
405 err = line6_dumpreq_init(&variax->dumpreq, variax_request_model1, sizeof(variax_request_model1));
406
407 if(err < 0) {
408 dev_err(&interface->dev, "Out of memory\n");
409 variax_destruct(interface);
410 return err;
411 }
412
413 err = line6_dumpreq_initbuf(&variax->dumpreq, variax_request_model2, sizeof(variax_request_model2), 1);
414
415 if(err < 0) {
416 dev_err(&interface->dev, "Out of memory\n");
417 variax_destruct(interface);
418 return err;
419 }
420
421 err = line6_dumpreq_initbuf(&variax->dumpreq, variax_request_bank, sizeof(variax_request_bank), 2);
422
423 if(err < 0) {
424 dev_err(&interface->dev, "Out of memory\n");
425 variax_destruct(interface);
426 return err;
427 }
428
429 variax->buffer_activate = kmalloc(sizeof(variax_activate), GFP_KERNEL);
430
431 if(variax->buffer_activate == NULL) {
432 dev_err(&interface->dev, "Out of memory\n");
433 variax_destruct(interface);
434 return -ENOMEM;
435 }
436
437 memcpy(variax->buffer_activate, variax_activate, sizeof(variax_activate));
438 init_timer(&variax->activate_timer);
439
440 /* create sysfs entries: */
441 if((err = variax_create_files(0, 0, &interface->dev)) < 0) {
442 variax_destruct(interface);
443 return err;
444 }
445
446 if((err = variax_create_files2(&interface->dev)) < 0) {
447 variax_destruct(interface);
448 return err;
449 }
450
451 /* initialize audio system: */
452 if((err = line6_init_audio(&variax->line6)) < 0) {
453 variax_destruct(interface);
454 return err;
455 }
456
457 /* initialize MIDI subsystem: */
458 if((err = line6_init_midi(&variax->line6)) < 0) {
459 variax_destruct(interface);
460 return err;
461 }
462
463 /* register audio system: */
464 if((err = line6_register_audio(&variax->line6)) < 0) {
465 variax_destruct(interface);
466 return err;
467 }
468
469 variax_activate_delayed(variax, VARIAX_ACTIVATE_DELAY);
470 line6_startup_delayed(&variax->dumpreq, VARIAX_STARTUP_DELAY, variax_startup_timeout, variax);
471 return 0;
472}
473
474/*
475 Workbench device disconnected.
476*/
477void variax_disconnect(struct usb_interface *interface)
478{
479 struct device *dev;
480
481 if(interface == NULL) return;
482 dev = &interface->dev;
483
484 if(dev != NULL) {
485 /* remove sysfs entries: */
486 variax_remove_files(0, 0, dev);
487 device_remove_file(dev, &dev_attr_model);
488 device_remove_file(dev, &dev_attr_volume);
489 device_remove_file(dev, &dev_attr_tone);
490 device_remove_file(dev, &dev_attr_name);
491 device_remove_file(dev, &dev_attr_bank);
492 device_remove_file(dev, &dev_attr_dump);
493 device_remove_file(dev, &dev_attr_active);
494#if CREATE_RAW_FILE
495 device_remove_file(dev, &dev_attr_raw);
496 device_remove_file(dev, &dev_attr_raw2);
497#endif
498 }
499
500 variax_destruct(interface);
501}
diff --git a/drivers/staging/line6/variax.h b/drivers/staging/line6/variax.h
new file mode 100644
index 000000000000..286df248c816
--- /dev/null
+++ b/drivers/staging/line6/variax.h
@@ -0,0 +1,107 @@
1/*
2 * Line6 Linux USB driver - 0.8.0
3 *
4 * Copyright (C) 2004-2009 Markus Grabner (grabner@icg.tugraz.at)
5 *
6 * This program is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU General Public License as
8 * published by the Free Software Foundation, version 2.
9 *
10 */
11
12#ifndef VARIAX_H
13#define VARIAX_H
14
15
16#include "driver.h"
17
18#include <linux/spinlock.h>
19#include <linux/usb.h>
20#include <linux/wait.h>
21
22#include <sound/core.h>
23
24#include "dumprequest.h"
25
26
27#define VARIAX_ACTIVATE_DELAY 10
28#define VARIAX_STARTUP_DELAY 3
29
30
31enum {
32 VARIAX_DUMP_PASS1 = LINE6_DUMP_CURRENT,
33 VARIAX_DUMP_PASS2,
34 VARIAX_DUMP_PASS3
35};
36
37
38/**
39 Binary Variax model dump
40*/
41struct variax_model {
42 /**
43 Header information (including program name).
44 */
45 unsigned char name[18];
46
47 /**
48 Model parameters.
49 */
50 unsigned char control[78 * 2];
51};
52
53struct usb_line6_variax {
54 /**
55 Generic Line6 USB data.
56 */
57 struct usb_line6 line6;
58
59 /**
60 Dump request structure.
61 Append two extra buffers for 3-pass data query.
62 */
63 struct line6_dump_request dumpreq; struct line6_dump_reqbuf extrabuf[2];
64
65 /**
66 Buffer for activation code.
67 */
68 unsigned char *buffer_activate;
69
70 /**
71 Model number.
72 */
73 int model;
74
75 /**
76 Current model settings.
77 */
78 struct variax_model model_data;
79
80 /**
81 Name of current model bank.
82 */
83 unsigned char bank[18];
84
85 /**
86 Position of volume dial.
87 */
88 int volume;
89
90 /**
91 Position of tone control dial.
92 */
93 int tone;
94
95 /**
96 Timer for delayed activation request.
97 */
98 struct timer_list activate_timer;
99};
100
101
102extern void variax_disconnect(struct usb_interface *interface);
103extern int variax_init(struct usb_interface *interface, struct usb_line6_variax *variax);
104extern void variax_process_message(struct usb_line6_variax *variax);
105
106
107#endif