staging: line6: Pass *_process_message() `usb_line6' pointers
[deliverable/linux.git] / drivers / staging / line6 / driver.c
CommitLineData
705ececd 1/*
e1a164d7 2 * Line6 Linux USB driver - 0.9.1beta
705ececd 3 *
1027f476 4 * Copyright (C) 2004-2010 Markus Grabner (grabner@icg.tugraz.at)
705ececd
MG
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
705ececd
MG
12#include <linux/kernel.h>
13#include <linux/module.h>
5a0e3ad6 14#include <linux/slab.h>
705ececd
MG
15#include <linux/usb.h>
16
17#include "audio.h"
18#include "capture.h"
1027f476 19#include "driver.h"
705ececd
MG
20#include "midi.h"
21#include "playback.h"
22#include "pod.h"
16dc1040 23#include "podhd.h"
705ececd
MG
24#include "revision.h"
25#include "toneport.h"
26#include "usbdefs.h"
27#include "variax.h"
28
705ececd
MG
29#define DRIVER_AUTHOR "Markus Grabner <grabner@icg.tugraz.at>"
30#define DRIVER_DESC "Line6 USB Driver"
e1a164d7 31#define DRIVER_VERSION "0.9.1beta" DRIVER_REVISION
705ececd 32
f45be7dc 33#define LINE6_DEVICE(prod) USB_DEVICE(0x0e41, prod)
7ad07310 34#define LINE6_IF_NUM(prod, n) USB_DEVICE_INTERFACE_NUMBER(0x0e41, prod, n)
daf54a59 35
705ececd 36/* table of devices that work with this driver */
a457732b 37static const struct usb_device_id line6_id_table[] = {
f45be7dc
CR
38 { LINE6_DEVICE(0x4250), .driver_info = LINE6_BASSPODXT },
39 { LINE6_DEVICE(0x4642), .driver_info = LINE6_BASSPODXTLIVE },
40 { LINE6_DEVICE(0x4252), .driver_info = LINE6_BASSPODXTPRO },
41 { LINE6_DEVICE(0x4750), .driver_info = LINE6_GUITARPORT },
3a3eae6c 42 { LINE6_IF_NUM(0x5051, 1), .driver_info = LINE6_POCKETPOD },
f45be7dc
CR
43 { LINE6_DEVICE(0x5057), .driver_info = LINE6_PODHD300 },
44 { LINE6_DEVICE(0x5058), .driver_info = LINE6_PODHD400 },
951dd316
CR
45 { LINE6_IF_NUM(0x414D, 0), .driver_info = LINE6_PODHD500_0 },
46 { LINE6_IF_NUM(0x414D, 1), .driver_info = LINE6_PODHD500_1 },
f45be7dc
CR
47 { LINE6_DEVICE(0x4153), .driver_info = LINE6_PODSTUDIO_GX },
48 { LINE6_DEVICE(0x4150), .driver_info = LINE6_PODSTUDIO_UX1 },
b98a8115 49 { LINE6_IF_NUM(0x4151, 0), .driver_info = LINE6_PODSTUDIO_UX2 },
f45be7dc 50 { LINE6_DEVICE(0x5044), .driver_info = LINE6_PODXT },
7ad07310
CR
51 { LINE6_IF_NUM(0x4650, 0), .driver_info = LINE6_PODXTLIVE_POD },
52 { LINE6_IF_NUM(0x4650, 1), .driver_info = LINE6_PODXTLIVE_VARIAX },
f45be7dc
CR
53 { LINE6_DEVICE(0x5050), .driver_info = LINE6_PODXTPRO },
54 { LINE6_DEVICE(0x4147), .driver_info = LINE6_TONEPORT_GX },
55 { LINE6_DEVICE(0x4141), .driver_info = LINE6_TONEPORT_UX1 },
b98a8115 56 { LINE6_IF_NUM(0x4142, 0), .driver_info = LINE6_TONEPORT_UX2 },
f45be7dc 57 { LINE6_DEVICE(0x534d), .driver_info = LINE6_VARIAX },
daf54a59 58 {}
705ececd 59};
e1a164d7 60
36445bc1 61MODULE_DEVICE_TABLE(usb, line6_id_table);
705ececd 62
ba79e52b 63static const struct line6_properties line6_properties_table[] = {
4d947546
CR
64 [LINE6_BASSPODXT] = {
65 .id = "BassPODxt",
66 .name = "BassPODxt",
7b3e4d47
CR
67 .capabilities = LINE6_CAP_CONTROL
68 | LINE6_CAP_PCM
69 | LINE6_CAP_HWMON,
7b9584fa 70 .altsetting = 5,
9e165be7
CR
71 .ep_ctrl_r = 0x84,
72 .ep_ctrl_w = 0x03,
16d603d3
CR
73 .ep_audio_r = 0x82,
74 .ep_audio_w = 0x01,
4d947546
CR
75 },
76 [LINE6_BASSPODXTLIVE] = {
77 .id = "BassPODxtLive",
78 .name = "BassPODxt Live",
7b3e4d47
CR
79 .capabilities = LINE6_CAP_CONTROL
80 | LINE6_CAP_PCM
81 | LINE6_CAP_HWMON,
7b9584fa 82 .altsetting = 1,
9e165be7
CR
83 .ep_ctrl_r = 0x84,
84 .ep_ctrl_w = 0x03,
16d603d3
CR
85 .ep_audio_r = 0x82,
86 .ep_audio_w = 0x01,
4d947546
CR
87 },
88 [LINE6_BASSPODXTPRO] = {
89 .id = "BassPODxtPro",
90 .name = "BassPODxt Pro",
7b3e4d47
CR
91 .capabilities = LINE6_CAP_CONTROL
92 | LINE6_CAP_PCM
93 | LINE6_CAP_HWMON,
7b9584fa 94 .altsetting = 5,
9e165be7
CR
95 .ep_ctrl_r = 0x84,
96 .ep_ctrl_w = 0x03,
16d603d3
CR
97 .ep_audio_r = 0x82,
98 .ep_audio_w = 0x01,
4d947546
CR
99 },
100 [LINE6_GUITARPORT] = {
101 .id = "GuitarPort",
102 .name = "GuitarPort",
7b3e4d47 103 .capabilities = LINE6_CAP_PCM,
7b9584fa 104 .altsetting = 2, /* 1..4 seem to be ok */
9e165be7 105 /* no control channel */
16d603d3
CR
106 .ep_audio_r = 0x82,
107 .ep_audio_w = 0x01,
4d947546
CR
108 },
109 [LINE6_POCKETPOD] = {
110 .id = "PocketPOD",
111 .name = "Pocket POD",
7b3e4d47 112 .capabilities = LINE6_CAP_CONTROL,
7b9584fa 113 .altsetting = 0,
9e165be7
CR
114 .ep_ctrl_r = 0x82,
115 .ep_ctrl_w = 0x02,
16d603d3 116 /* no audio channel */
4d947546
CR
117 },
118 [LINE6_PODHD300] = {
119 .id = "PODHD300",
120 .name = "POD HD300",
7b3e4d47
CR
121 .capabilities = LINE6_CAP_CONTROL
122 | LINE6_CAP_PCM
123 | LINE6_CAP_HWMON,
7b9584fa 124 .altsetting = 5,
9e165be7
CR
125 .ep_ctrl_r = 0x84,
126 .ep_ctrl_w = 0x03,
16d603d3
CR
127 .ep_audio_r = 0x82,
128 .ep_audio_w = 0x01,
4d947546
CR
129 },
130 [LINE6_PODHD400] = {
131 .id = "PODHD400",
132 .name = "POD HD400",
7b3e4d47
CR
133 .capabilities = LINE6_CAP_CONTROL
134 | LINE6_CAP_PCM
135 | LINE6_CAP_HWMON,
7b9584fa 136 .altsetting = 5,
9e165be7
CR
137 .ep_ctrl_r = 0x84,
138 .ep_ctrl_w = 0x03,
16d603d3
CR
139 .ep_audio_r = 0x82,
140 .ep_audio_w = 0x01,
4d947546 141 },
951dd316
CR
142 [LINE6_PODHD500_0] = {
143 .id = "PODHD500",
144 .name = "POD HD500",
145 .capabilities = LINE6_CAP_CONTROL
146 | LINE6_CAP_PCM
147 | LINE6_CAP_HWMON,
7b9584fa 148 .altsetting = 1,
9e165be7
CR
149 .ep_ctrl_r = 0x81,
150 .ep_ctrl_w = 0x01,
16d603d3
CR
151 .ep_audio_r = 0x86,
152 .ep_audio_w = 0x02,
951dd316
CR
153 },
154 [LINE6_PODHD500_1] = {
4d947546
CR
155 .id = "PODHD500",
156 .name = "POD HD500",
7b3e4d47
CR
157 .capabilities = LINE6_CAP_CONTROL
158 | LINE6_CAP_PCM
159 | LINE6_CAP_HWMON,
7b9584fa 160 .altsetting = 1,
9e165be7
CR
161 .ep_ctrl_r = 0x81,
162 .ep_ctrl_w = 0x01,
16d603d3
CR
163 .ep_audio_r = 0x86,
164 .ep_audio_w = 0x02,
4d947546
CR
165 },
166 [LINE6_PODSTUDIO_GX] = {
167 .id = "PODStudioGX",
168 .name = "POD Studio GX",
7b3e4d47 169 .capabilities = LINE6_CAP_PCM,
7b9584fa 170 .altsetting = 2, /* 1..4 seem to be ok */
9e165be7 171 /* no control channel */
16d603d3
CR
172 .ep_audio_r = 0x82,
173 .ep_audio_w = 0x01,
4d947546
CR
174 },
175 [LINE6_PODSTUDIO_UX1] = {
176 .id = "PODStudioUX1",
177 .name = "POD Studio UX1",
7b3e4d47 178 .capabilities = LINE6_CAP_PCM,
7b9584fa 179 .altsetting = 2, /* 1..4 seem to be ok */
9e165be7 180 /* no control channel */
16d603d3
CR
181 .ep_audio_r = 0x82,
182 .ep_audio_w = 0x01,
4d947546
CR
183 },
184 [LINE6_PODSTUDIO_UX2] = {
185 .id = "PODStudioUX2",
186 .name = "POD Studio UX2",
7b3e4d47 187 .capabilities = LINE6_CAP_PCM,
7b9584fa 188 .altsetting = 2, /* defaults to 44.1kHz, 16-bit */
9e165be7 189 /* no control channel */
16d603d3
CR
190 .ep_audio_r = 0x82,
191 .ep_audio_w = 0x01,
4d947546
CR
192 },
193 [LINE6_PODXT] = {
194 .id = "PODxt",
195 .name = "PODxt",
7b3e4d47
CR
196 .capabilities = LINE6_CAP_CONTROL
197 | LINE6_CAP_PCM
198 | LINE6_CAP_HWMON,
7b9584fa 199 .altsetting = 5,
9e165be7
CR
200 .ep_ctrl_r = 0x84,
201 .ep_ctrl_w = 0x03,
16d603d3
CR
202 .ep_audio_r = 0x82,
203 .ep_audio_w = 0x01,
4d947546 204 },
7ad07310
CR
205 [LINE6_PODXTLIVE_POD] = {
206 .id = "PODxtLive",
207 .name = "PODxt Live",
208 .capabilities = LINE6_CAP_CONTROL
209 | LINE6_CAP_PCM
210 | LINE6_CAP_HWMON,
7b9584fa 211 .altsetting = 1,
9e165be7
CR
212 .ep_ctrl_r = 0x84,
213 .ep_ctrl_w = 0x03,
16d603d3
CR
214 .ep_audio_r = 0x82,
215 .ep_audio_w = 0x01,
7ad07310
CR
216 },
217 [LINE6_PODXTLIVE_VARIAX] = {
4d947546
CR
218 .id = "PODxtLive",
219 .name = "PODxt Live",
7b3e4d47
CR
220 .capabilities = LINE6_CAP_CONTROL
221 | LINE6_CAP_PCM
222 | LINE6_CAP_HWMON,
7b9584fa 223 .altsetting = 1,
9e165be7
CR
224 .ep_ctrl_r = 0x86,
225 .ep_ctrl_w = 0x05,
16d603d3
CR
226 .ep_audio_r = 0x82,
227 .ep_audio_w = 0x01,
4d947546
CR
228 },
229 [LINE6_PODXTPRO] = {
230 .id = "PODxtPro",
231 .name = "PODxt Pro",
7b3e4d47
CR
232 .capabilities = LINE6_CAP_CONTROL
233 | LINE6_CAP_PCM
234 | LINE6_CAP_HWMON,
7b9584fa 235 .altsetting = 5,
9e165be7
CR
236 .ep_ctrl_r = 0x84,
237 .ep_ctrl_w = 0x03,
16d603d3
CR
238 .ep_audio_r = 0x82,
239 .ep_audio_w = 0x01,
4d947546
CR
240 },
241 [LINE6_TONEPORT_GX] = {
242 .id = "TonePortGX",
243 .name = "TonePort GX",
7b3e4d47 244 .capabilities = LINE6_CAP_PCM,
7b9584fa 245 .altsetting = 2, /* 1..4 seem to be ok */
9e165be7 246 /* no control channel */
16d603d3
CR
247 .ep_audio_r = 0x82,
248 .ep_audio_w = 0x01,
4d947546
CR
249 },
250 [LINE6_TONEPORT_UX1] = {
251 .id = "TonePortUX1",
252 .name = "TonePort UX1",
7b3e4d47 253 .capabilities = LINE6_CAP_PCM,
7b9584fa 254 .altsetting = 2, /* 1..4 seem to be ok */
9e165be7 255 /* no control channel */
16d603d3
CR
256 .ep_audio_r = 0x82,
257 .ep_audio_w = 0x01,
4d947546
CR
258 },
259 [LINE6_TONEPORT_UX2] = {
260 .id = "TonePortUX2",
261 .name = "TonePort UX2",
7b3e4d47 262 .capabilities = LINE6_CAP_PCM,
7b9584fa 263 .altsetting = 2, /* defaults to 44.1kHz, 16-bit */
9e165be7 264 /* no control channel */
16d603d3
CR
265 .ep_audio_r = 0x82,
266 .ep_audio_w = 0x01,
4d947546
CR
267 },
268 [LINE6_VARIAX] = {
269 .id = "Variax",
270 .name = "Variax Workbench",
7b3e4d47 271 .capabilities = LINE6_CAP_CONTROL,
7b9584fa 272 .altsetting = 1,
9e165be7
CR
273 .ep_ctrl_r = 0x82,
274 .ep_ctrl_w = 0x01,
16d603d3 275 /* no audio channel */
4d947546 276 }
705ececd 277};
705ececd
MG
278
279/*
280 This is Line6's MIDI manufacturer ID.
281*/
1027f476
MG
282const unsigned char line6_midi_id[] = {
283 0x00, 0x01, 0x0c
284};
285
286/*
287 Code to request version of POD, Variax interface
288 (and maybe other devices).
289*/
c46b8a65 290static const char line6_request_version[] = {
1027f476
MG
291 0xf0, 0x7e, 0x7f, 0x06, 0x01, 0xf7
292};
293
705ececd
MG
294/**
295 Class for asynchronous messages.
296*/
36445bc1 297struct message {
705ececd
MG
298 struct usb_line6 *line6;
299 const char *buffer;
300 int size;
301 int done;
302};
303
705ececd
MG
304/*
305 Forward declarations.
306*/
0c7ab158 307static void line6_data_received(struct urb *urb);
36445bc1
GKH
308static int line6_send_raw_message_async_part(struct message *msg,
309 struct urb *urb);
705ececd 310
705ececd
MG
311/*
312 Start to listen on endpoint.
313*/
314static int line6_start_listen(struct usb_line6 *line6)
315{
1027f476 316 int err;
a6b4699d 317
36445bc1 318 usb_fill_int_urb(line6->urb_listen, line6->usbdev,
9e165be7
CR
319 usb_rcvintpipe(line6->usbdev, line6->properties->ep_ctrl_r),
320 line6->buffer_listen, LINE6_BUFSIZE_LISTEN,
321 line6_data_received, line6, line6->interval);
705ececd 322 line6->urb_listen->actual_length = 0;
e1a164d7 323 err = usb_submit_urb(line6->urb_listen, GFP_ATOMIC);
1027f476
MG
324 return err;
325}
326
327/*
328 Stop listening on endpoint.
329*/
330static void line6_stop_listen(struct usb_line6 *line6)
331{
332 usb_kill_urb(line6->urb_listen);
705ececd
MG
333}
334
705ececd 335/*
1027f476 336 Send raw message in pieces of wMaxPacketSize bytes.
705ececd 337*/
36445bc1
GKH
338int line6_send_raw_message(struct usb_line6 *line6, const char *buffer,
339 int size)
705ececd
MG
340{
341 int i, done = 0;
342
1027f476
MG
343 for (i = 0; i < size; i += line6->max_packet_size) {
344 int partial;
705ececd
MG
345 const char *frag_buf = buffer + i;
346 int frag_size = min(line6->max_packet_size, size - i);
36445bc1
GKH
347 int retval;
348
349 retval = usb_interrupt_msg(line6->usbdev,
ba79e52b 350 usb_sndintpipe(line6->usbdev,
9e165be7 351 line6->properties->ep_ctrl_w),
ba79e52b
DB
352 (char *)frag_buf, frag_size,
353 &partial, LINE6_TIMEOUT * HZ);
705ececd 354
36445bc1
GKH
355 if (retval) {
356 dev_err(line6->ifcdev,
357 "usb_interrupt_msg failed (%d)\n", retval);
705ececd
MG
358 break;
359 }
360
1027f476 361 done += frag_size;
705ececd
MG
362 }
363
364 return done;
365}
366
367/*
368 Notification of completion of asynchronous request transmission.
369*/
0c7ab158 370static void line6_async_request_sent(struct urb *urb)
705ececd
MG
371{
372 struct message *msg = (struct message *)urb->context;
373
36445bc1 374 if (msg->done >= msg->size) {
705ececd
MG
375 usb_free_urb(urb);
376 kfree(msg);
36445bc1 377 } else
705ececd
MG
378 line6_send_raw_message_async_part(msg, urb);
379}
380
381/*
382 Asynchronously send part of a raw message.
383*/
36445bc1
GKH
384static int line6_send_raw_message_async_part(struct message *msg,
385 struct urb *urb)
705ececd
MG
386{
387 int retval;
388 struct usb_line6 *line6 = msg->line6;
389 int done = msg->done;
390 int bytes = min(msg->size - done, line6->max_packet_size);
391
36445bc1 392 usb_fill_int_urb(urb, line6->usbdev,
9e165be7
CR
393 usb_sndintpipe(line6->usbdev, line6->properties->ep_ctrl_w),
394 (char *)msg->buffer + done, bytes,
395 line6_async_request_sent, msg, line6->interval);
705ececd 396
705ececd
MG
397 msg->done += bytes;
398 retval = usb_submit_urb(urb, GFP_ATOMIC);
399
36445bc1
GKH
400 if (retval < 0) {
401 dev_err(line6->ifcdev, "%s: usb_submit_urb failed (%d)\n",
402 __func__, retval);
705ececd
MG
403 usb_free_urb(urb);
404 kfree(msg);
056e0af2 405 return retval;
705ececd
MG
406 }
407
408 return 0;
409}
410
1027f476
MG
411/*
412 Setup and start timer.
413*/
414void line6_start_timer(struct timer_list *timer, unsigned int msecs,
1cad608e 415 void (*function)(unsigned long), unsigned long data)
1027f476
MG
416{
417 setup_timer(timer, function, data);
418 timer->expires = jiffies + msecs * HZ / 1000;
419 add_timer(timer);
420}
421
705ececd
MG
422/*
423 Asynchronously send raw message.
424*/
36445bc1
GKH
425int line6_send_raw_message_async(struct usb_line6 *line6, const char *buffer,
426 int size)
705ececd
MG
427{
428 struct message *msg;
429 struct urb *urb;
430
431 /* create message: */
432 msg = kmalloc(sizeof(struct message), GFP_ATOMIC);
78110bb8 433 if (msg == NULL)
705ececd 434 return -ENOMEM;
705ececd
MG
435
436 /* create URB: */
437 urb = usb_alloc_urb(0, GFP_ATOMIC);
438
36445bc1 439 if (urb == NULL) {
705ececd
MG
440 kfree(msg);
441 dev_err(line6->ifcdev, "Out of memory\n");
442 return -ENOMEM;
443 }
444
445 /* set message data: */
446 msg->line6 = line6;
447 msg->buffer = buffer;
448 msg->size = size;
449 msg->done = 0;
450
451 /* start sending: */
452 return line6_send_raw_message_async_part(msg, urb);
453}
454
1027f476
MG
455/*
456 Send asynchronous device version request.
457*/
458int line6_version_request_async(struct usb_line6 *line6)
459{
c46b8a65
GKH
460 char *buffer;
461 int retval;
462
77ecb6fe
LN
463 buffer = kmemdup(line6_request_version,
464 sizeof(line6_request_version), GFP_ATOMIC);
c46b8a65
GKH
465 if (buffer == NULL) {
466 dev_err(line6->ifcdev, "Out of memory");
467 return -ENOMEM;
468 }
469
c46b8a65
GKH
470 retval = line6_send_raw_message_async(line6, buffer,
471 sizeof(line6_request_version));
472 kfree(buffer);
473 return retval;
1027f476
MG
474}
475
705ececd
MG
476/*
477 Send sysex message in pieces of wMaxPacketSize bytes.
478*/
36445bc1
GKH
479int line6_send_sysex_message(struct usb_line6 *line6, const char *buffer,
480 int size)
705ececd 481{
e1a164d7
MG
482 return line6_send_raw_message(line6, buffer,
483 size + SYSEX_EXTRA_SIZE) -
484 SYSEX_EXTRA_SIZE;
705ececd
MG
485}
486
487/*
488 Allocate buffer for sysex message and prepare header.
489 @param code sysex message code
490 @param size number of bytes between code and sysex end
491*/
36445bc1
GKH
492char *line6_alloc_sysex_buffer(struct usb_line6 *line6, int code1, int code2,
493 int size)
705ececd 494{
1027f476 495 char *buffer = kmalloc(size + SYSEX_EXTRA_SIZE, GFP_ATOMIC);
705ececd 496
78110bb8 497 if (!buffer)
536165d8 498 return NULL;
705ececd
MG
499
500 buffer[0] = LINE6_SYSEX_BEGIN;
501 memcpy(buffer + 1, line6_midi_id, sizeof(line6_midi_id));
502 buffer[sizeof(line6_midi_id) + 1] = code1;
503 buffer[sizeof(line6_midi_id) + 2] = code2;
504 buffer[sizeof(line6_midi_id) + 3 + size] = LINE6_SYSEX_END;
505 return buffer;
506}
507
508/*
509 Notification of data received from the Line6 device.
510*/
0c7ab158 511static void line6_data_received(struct urb *urb)
705ececd
MG
512{
513 struct usb_line6 *line6 = (struct usb_line6 *)urb->context;
269edc8e 514 struct midi_buffer *mb = &line6->line6midi->midibuf_in;
705ececd
MG
515 int done;
516
36445bc1 517 if (urb->status == -ESHUTDOWN)
705ececd
MG
518 return;
519
e1a164d7
MG
520 done =
521 line6_midibuf_write(mb, urb->transfer_buffer, urb->actual_length);
705ececd 522
36445bc1 523 if (done < urb->actual_length) {
1027f476 524 line6_midibuf_ignore(mb, done);
e00d33cb
SH
525 dev_dbg(line6->ifcdev, "%d %d buffer overflow - message skipped\n",
526 done, urb->actual_length);
705ececd
MG
527 }
528
36445bc1 529 for (;;) {
e1a164d7
MG
530 done =
531 line6_midibuf_read(mb, line6->buffer_message,
532 LINE6_MESSAGE_MAXLEN);
705ececd 533
36445bc1 534 if (done == 0)
705ececd
MG
535 break;
536
705ececd 537 line6->message_length = done;
705ececd
MG
538 line6_midi_receive(line6, line6->buffer_message, done);
539
a23a8bff
CR
540 switch (line6->type) {
541 case LINE6_BASSPODXT:
542 case LINE6_BASSPODXTLIVE:
543 case LINE6_BASSPODXTPRO:
544 case LINE6_PODXT:
545 case LINE6_PODXTPRO:
546 case LINE6_POCKETPOD:
1cad3e8d 547 line6_pod_process_message(line6);
705ececd
MG
548 break;
549
a23a8bff
CR
550 case LINE6_PODHD300:
551 case LINE6_PODHD400:
951dd316
CR
552 case LINE6_PODHD500_0:
553 case LINE6_PODHD500_1:
16dc1040
SH
554 break; /* let userspace handle MIDI */
555
7ad07310 556 case LINE6_PODXTLIVE_POD:
1cad3e8d 557 line6_pod_process_message(line6);
7ad07310
CR
558 break;
559
560 case LINE6_PODXTLIVE_VARIAX:
1cad3e8d 561 line6_variax_process_message(line6);
705ececd
MG
562 break;
563
a23a8bff 564 case LINE6_VARIAX:
1cad3e8d 565 line6_variax_process_message(line6);
705ececd
MG
566 break;
567
568 default:
569 MISSING_CASE;
570 }
571 }
572
573 line6_start_listen(line6);
574}
575
576/*
577 Send channel number (i.e., switch to a different sound).
578*/
317e188b 579int line6_send_program(struct usb_line6 *line6, u8 value)
705ececd 580{
1027f476 581 int retval;
705ececd 582 unsigned char *buffer;
1027f476
MG
583 int partial;
584
585 buffer = kmalloc(2, GFP_KERNEL);
78110bb8 586 if (!buffer)
705ececd 587 return -ENOMEM;
705ececd
MG
588
589 buffer[0] = LINE6_PROGRAM_CHANGE | LINE6_CHANNEL_HOST;
590 buffer[1] = value;
591
1027f476
MG
592 retval = usb_interrupt_msg(line6->usbdev,
593 usb_sndintpipe(line6->usbdev,
9e165be7 594 line6->properties->ep_ctrl_w),
1027f476
MG
595 buffer, 2, &partial, LINE6_TIMEOUT * HZ);
596
597 if (retval)
e1a164d7
MG
598 dev_err(line6->ifcdev, "usb_interrupt_msg failed (%d)\n",
599 retval);
1027f476
MG
600
601 kfree(buffer);
602 return retval;
705ececd
MG
603}
604
605/*
606 Transmit Line6 control parameter.
607*/
2471c093 608int line6_transmit_parameter(struct usb_line6 *line6, int param, u8 value)
705ececd 609{
1027f476 610 int retval;
705ececd 611 unsigned char *buffer;
1027f476
MG
612 int partial;
613
614 buffer = kmalloc(3, GFP_KERNEL);
78110bb8 615 if (!buffer)
705ececd 616 return -ENOMEM;
705ececd
MG
617
618 buffer[0] = LINE6_PARAM_CHANGE | LINE6_CHANNEL_HOST;
619 buffer[1] = param;
620 buffer[2] = value;
621
1027f476 622 retval = usb_interrupt_msg(line6->usbdev,
e1a164d7 623 usb_sndintpipe(line6->usbdev,
9e165be7 624 line6->properties->ep_ctrl_w),
1027f476
MG
625 buffer, 3, &partial, LINE6_TIMEOUT * HZ);
626
627 if (retval)
e1a164d7
MG
628 dev_err(line6->ifcdev, "usb_interrupt_msg failed (%d)\n",
629 retval);
1027f476
MG
630
631 kfree(buffer);
632 return retval;
705ececd
MG
633}
634
635/*
636 Read data from device.
637*/
e1a164d7
MG
638int line6_read_data(struct usb_line6 *line6, int address, void *data,
639 size_t datalen)
705ececd
MG
640{
641 struct usb_device *usbdev = line6->usbdev;
642 int ret;
643 unsigned char len;
644
645 /* query the serial number: */
646 ret = usb_control_msg(usbdev, usb_sndctrlpipe(usbdev, 0), 0x67,
1027f476
MG
647 USB_TYPE_VENDOR | USB_RECIP_DEVICE | USB_DIR_OUT,
648 (datalen << 8) | 0x21, address,
649 NULL, 0, LINE6_TIMEOUT * HZ);
705ececd 650
36445bc1 651 if (ret < 0) {
705ececd
MG
652 dev_err(line6->ifcdev, "read request failed (error %d)\n", ret);
653 return ret;
654 }
655
bc776f27 656 /* Wait for data length. We'll get 0xff until length arrives. */
705ececd
MG
657 do {
658 ret = usb_control_msg(usbdev, usb_rcvctrlpipe(usbdev, 0), 0x67,
36445bc1
GKH
659 USB_TYPE_VENDOR | USB_RECIP_DEVICE |
660 USB_DIR_IN,
661 0x0012, 0x0000, &len, 1,
662 LINE6_TIMEOUT * HZ);
663 if (ret < 0) {
664 dev_err(line6->ifcdev,
665 "receive length failed (error %d)\n", ret);
705ececd
MG
666 return ret;
667 }
d722a510 668 } while (len == 0xff);
36445bc1
GKH
669
670 if (len != datalen) {
671 /* should be equal or something went wrong */
672 dev_err(line6->ifcdev,
673 "length mismatch (expected %d, got %d)\n",
674 (int)datalen, (int)len);
705ececd
MG
675 return -EINVAL;
676 }
677
678 /* receive the result: */
679 ret = usb_control_msg(usbdev, usb_rcvctrlpipe(usbdev, 0), 0x67,
36445bc1
GKH
680 USB_TYPE_VENDOR | USB_RECIP_DEVICE | USB_DIR_IN,
681 0x0013, 0x0000, data, datalen,
682 LINE6_TIMEOUT * HZ);
705ececd 683
36445bc1 684 if (ret < 0) {
705ececd
MG
685 dev_err(line6->ifcdev, "read failed (error %d)\n", ret);
686 return ret;
687 }
688
689 return 0;
690}
691
692/*
693 Write data to device.
694*/
36445bc1
GKH
695int line6_write_data(struct usb_line6 *line6, int address, void *data,
696 size_t datalen)
705ececd
MG
697{
698 struct usb_device *usbdev = line6->usbdev;
699 int ret;
700 unsigned char status;
701
36445bc1
GKH
702 ret = usb_control_msg(usbdev, usb_sndctrlpipe(usbdev, 0), 0x67,
703 USB_TYPE_VENDOR | USB_RECIP_DEVICE | USB_DIR_OUT,
704 0x0022, address, data, datalen,
705 LINE6_TIMEOUT * HZ);
705ececd 706
36445bc1
GKH
707 if (ret < 0) {
708 dev_err(line6->ifcdev,
709 "write request failed (error %d)\n", ret);
705ececd
MG
710 return ret;
711 }
712
713 do {
36445bc1
GKH
714 ret = usb_control_msg(usbdev, usb_rcvctrlpipe(usbdev, 0),
715 0x67,
716 USB_TYPE_VENDOR | USB_RECIP_DEVICE |
717 USB_DIR_IN,
718 0x0012, 0x0000,
719 &status, 1, LINE6_TIMEOUT * HZ);
720
721 if (ret < 0) {
722 dev_err(line6->ifcdev,
723 "receiving status failed (error %d)\n", ret);
705ececd
MG
724 return ret;
725 }
027360c5 726 } while (status == 0xff);
705ececd 727
36445bc1 728 if (status != 0) {
705ececd
MG
729 dev_err(line6->ifcdev, "write failed (error %d)\n", ret);
730 return -EINVAL;
731 }
732
733 return 0;
734}
735
736/*
737 Read Line6 device serial number.
738 (POD, TonePort, GuitarPort)
739*/
740int line6_read_serial_number(struct usb_line6 *line6, int *serial_number)
741{
e1a164d7
MG
742 return line6_read_data(line6, 0x80d0, serial_number,
743 sizeof(*serial_number));
705ececd
MG
744}
745
746/*
747 No operation (i.e., unsupported).
748*/
77491e52
GKH
749ssize_t line6_nop_read(struct device *dev, struct device_attribute *attr,
750 char *buf)
705ececd
MG
751{
752 return 0;
753}
754
705ececd
MG
755/*
756 Generic destructor.
757*/
758static void line6_destruct(struct usb_interface *interface)
759{
760 struct usb_line6 *line6;
36445bc1
GKH
761
762 if (interface == NULL)
763 return;
705ececd 764 line6 = usb_get_intfdata(interface);
36445bc1
GKH
765 if (line6 == NULL)
766 return;
705ececd
MG
767
768 /* free buffer memory first: */
36445bc1
GKH
769 kfree(line6->buffer_message);
770 kfree(line6->buffer_listen);
705ececd
MG
771
772 /* then free URBs: */
36445bc1 773 usb_free_urb(line6->urb_listen);
705ececd
MG
774
775 /* make sure the device isn't destructed twice: */
776 usb_set_intfdata(interface, NULL);
777
778 /* free interface data: */
779 kfree(line6);
780}
781
705ececd
MG
782/*
783 Probe USB device.
784*/
e1a164d7
MG
785static int line6_probe(struct usb_interface *interface,
786 const struct usb_device_id *id)
705ececd 787{
c33a20b7 788 enum line6_device_type devtype;
4bd8b4de
DC
789 struct usb_device *usbdev;
790 struct usb_line6 *line6;
705ececd 791 const struct line6_properties *properties;
7b9584fa 792 int interface_number;
705ececd 793 int size = 0;
705ececd
MG
794 int ret;
795
36445bc1
GKH
796 if (interface == NULL)
797 return -ENODEV;
705ececd 798 usbdev = interface_to_usbdev(interface);
36445bc1
GKH
799 if (usbdev == NULL)
800 return -ENODEV;
705ececd 801
705ececd 802 /* we don't handle multiple configurations */
ab366c1a
KV
803 if (usbdev->descriptor.bNumConfigurations != 1) {
804 ret = -ENODEV;
805 goto err_put;
806 }
705ececd 807
c33a20b7 808 devtype = id->driver_info;
705ececd 809
705ececd
MG
810 /* initialize device info: */
811 properties = &line6_properties_table[devtype];
812 dev_info(&interface->dev, "Line6 %s found\n", properties->name);
705ececd
MG
813
814 /* query interface number */
815 interface_number = interface->cur_altsetting->desc.bInterfaceNumber;
816
7b9584fa
CR
817 ret = usb_set_interface(usbdev, interface_number,
818 properties->altsetting);
36445bc1 819 if (ret < 0) {
705ececd 820 dev_err(&interface->dev, "set_interface failed\n");
ab366c1a 821 goto err_put;
705ececd
MG
822 }
823
a23a8bff
CR
824 /* initialize device data based on device: */
825 switch (devtype) {
826 case LINE6_BASSPODXT:
827 case LINE6_BASSPODXTLIVE:
828 case LINE6_BASSPODXTPRO:
829 case LINE6_PODXT:
830 case LINE6_PODXTPRO:
705ececd 831 size = sizeof(struct usb_line6_pod);
705ececd
MG
832 break;
833
a23a8bff
CR
834 case LINE6_PODHD300:
835 case LINE6_PODHD400:
16dc1040 836 size = sizeof(struct usb_line6_podhd);
16dc1040
SH
837 break;
838
951dd316
CR
839 case LINE6_PODHD500_0:
840 case LINE6_PODHD500_1:
4c6fb5fc 841 size = sizeof(struct usb_line6_podhd);
4c6fb5fc
MG
842 break;
843
a23a8bff 844 case LINE6_POCKETPOD:
1027f476 845 size = sizeof(struct usb_line6_pod);
1027f476
MG
846 break;
847
a23a8bff
CR
848 case LINE6_PODSTUDIO_GX:
849 case LINE6_PODSTUDIO_UX1:
850 case LINE6_PODSTUDIO_UX2:
851 case LINE6_TONEPORT_GX:
852 case LINE6_TONEPORT_UX1:
853 case LINE6_TONEPORT_UX2:
854 case LINE6_GUITARPORT:
705ececd 855 size = sizeof(struct usb_line6_toneport);
705ececd
MG
856 break;
857
7ad07310
CR
858 case LINE6_PODXTLIVE_POD:
859 size = sizeof(struct usb_line6_pod);
7ad07310 860 break;
705ececd 861
7ad07310
CR
862 case LINE6_PODXTLIVE_VARIAX:
863 size = sizeof(struct usb_line6_variax);
705ececd
MG
864 break;
865
a23a8bff 866 case LINE6_VARIAX:
705ececd 867 size = sizeof(struct usb_line6_variax);
705ececd
MG
868 break;
869
870 default:
871 MISSING_CASE;
ab366c1a
KV
872 ret = -ENODEV;
873 goto err_put;
705ececd
MG
874 }
875
36445bc1 876 if (size == 0) {
4bd8b4de 877 dev_err(&interface->dev,
e1a164d7 878 "driver bug: interface data size not set\n");
ab366c1a
KV
879 ret = -ENODEV;
880 goto err_put;
705ececd
MG
881 }
882
883 line6 = kzalloc(size, GFP_KERNEL);
36445bc1 884 if (line6 == NULL) {
ab366c1a
KV
885 ret = -ENODEV;
886 goto err_put;
705ececd
MG
887 }
888
889 /* store basic data: */
705ececd
MG
890 line6->properties = properties;
891 line6->usbdev = usbdev;
892 line6->ifcdev = &interface->dev;
a23a8bff 893 line6->type = devtype;
705ececd
MG
894
895 /* get data from endpoint descriptor (see usb_maxpacket): */
896 {
897 struct usb_host_endpoint *ep;
9e165be7
CR
898 unsigned pipe = usb_rcvintpipe(usbdev, properties->ep_ctrl_r);
899 unsigned epnum = usb_pipeendpoint(pipe);
705ececd
MG
900 ep = usbdev->ep_in[epnum];
901
36445bc1 902 if (ep != NULL) {
705ececd 903 line6->interval = ep->desc.bInterval;
e1a164d7
MG
904 line6->max_packet_size =
905 le16_to_cpu(ep->desc.wMaxPacketSize);
36445bc1 906 } else {
705ececd
MG
907 line6->interval = LINE6_FALLBACK_INTERVAL;
908 line6->max_packet_size = LINE6_FALLBACK_MAXPACKETSIZE;
e1a164d7
MG
909 dev_err(line6->ifcdev,
910 "endpoint not available, using fallback values");
705ececd
MG
911 }
912 }
913
914 usb_set_intfdata(interface, line6);
915
4cb1a4ae 916 if (properties->capabilities & LINE6_CAP_CONTROL) {
705ececd 917 /* initialize USB buffers: */
e1a164d7
MG
918 line6->buffer_listen =
919 kmalloc(LINE6_BUFSIZE_LISTEN, GFP_KERNEL);
36445bc1 920 if (line6->buffer_listen == NULL) {
ab366c1a
KV
921 ret = -ENOMEM;
922 goto err_destruct;
705ececd
MG
923 }
924
e1a164d7
MG
925 line6->buffer_message =
926 kmalloc(LINE6_MESSAGE_MAXLEN, GFP_KERNEL);
36445bc1 927 if (line6->buffer_message == NULL) {
ab366c1a
KV
928 ret = -ENOMEM;
929 goto err_destruct;
705ececd
MG
930 }
931
932 line6->urb_listen = usb_alloc_urb(0, GFP_KERNEL);
933
36445bc1 934 if (line6->urb_listen == NULL) {
705ececd
MG
935 dev_err(&interface->dev, "Out of memory\n");
936 line6_destruct(interface);
ab366c1a
KV
937 ret = -ENOMEM;
938 goto err_destruct;
705ececd
MG
939 }
940
36445bc1
GKH
941 ret = line6_start_listen(line6);
942 if (ret < 0) {
943 dev_err(&interface->dev, "%s: usb_submit_urb failed\n",
944 __func__);
ab366c1a 945 goto err_destruct;
705ececd
MG
946 }
947 }
948
a23a8bff
CR
949 /* initialize device data based on device: */
950 switch (devtype) {
951 case LINE6_BASSPODXT:
952 case LINE6_BASSPODXTLIVE:
953 case LINE6_BASSPODXTPRO:
954 case LINE6_POCKETPOD:
955 case LINE6_PODXT:
956 case LINE6_PODXTPRO:
a221dd45 957 ret = line6_pod_init(interface, line6);
705ececd
MG
958 break;
959
a23a8bff
CR
960 case LINE6_PODHD300:
961 case LINE6_PODHD400:
951dd316
CR
962 case LINE6_PODHD500_0:
963 case LINE6_PODHD500_1:
a221dd45 964 ret = line6_podhd_init(interface, line6);
16dc1040
SH
965 break;
966
7ad07310 967 case LINE6_PODXTLIVE_POD:
a221dd45 968 ret = line6_pod_init(interface, line6);
7ad07310 969 break;
705ececd 970
7ad07310 971 case LINE6_PODXTLIVE_VARIAX:
a221dd45 972 ret = line6_variax_init(interface, line6);
705ececd
MG
973 break;
974
a23a8bff 975 case LINE6_VARIAX:
a221dd45 976 ret = line6_variax_init(interface, line6);
705ececd
MG
977 break;
978
a23a8bff
CR
979 case LINE6_PODSTUDIO_GX:
980 case LINE6_PODSTUDIO_UX1:
981 case LINE6_PODSTUDIO_UX2:
982 case LINE6_TONEPORT_GX:
983 case LINE6_TONEPORT_UX1:
984 case LINE6_TONEPORT_UX2:
985 case LINE6_GUITARPORT:
a221dd45 986 ret = line6_toneport_init(interface, line6);
705ececd
MG
987 break;
988
989 default:
990 MISSING_CASE;
991 ret = -ENODEV;
992 }
993
ab366c1a
KV
994 if (ret < 0)
995 goto err_destruct;
705ececd 996
36445bc1
GKH
997 ret = sysfs_create_link(&interface->dev.kobj, &usbdev->dev.kobj,
998 "usb_device");
ab366c1a
KV
999 if (ret < 0)
1000 goto err_destruct;
705ececd 1001
1027f476
MG
1002 /* creation of additional special files should go here */
1003
36445bc1
GKH
1004 dev_info(&interface->dev, "Line6 %s now attached\n",
1005 line6->properties->name);
1027f476 1006
1027f476
MG
1007 /* increment reference counters: */
1008 usb_get_intf(interface);
1009 usb_get_dev(usbdev);
1010
ab366c1a
KV
1011 return 0;
1012
1013err_destruct:
1014 line6_destruct(interface);
1015err_put:
705ececd
MG
1016 return ret;
1017}
1018
1019/*
1020 Line6 device disconnected.
1021*/
1022static void line6_disconnect(struct usb_interface *interface)
1023{
1024 struct usb_line6 *line6;
1025 struct usb_device *usbdev;
b430b3db 1026 int interface_number;
705ececd 1027
36445bc1
GKH
1028 if (interface == NULL)
1029 return;
705ececd 1030 usbdev = interface_to_usbdev(interface);
36445bc1
GKH
1031 if (usbdev == NULL)
1032 return;
705ececd 1033
1027f476
MG
1034 /* removal of additional special files should go here */
1035
705ececd
MG
1036 sysfs_remove_link(&interface->dev.kobj, "usb_device");
1037
1038 interface_number = interface->cur_altsetting->desc.bInterfaceNumber;
1039 line6 = usb_get_intfdata(interface);
1040
36445bc1
GKH
1041 if (line6 != NULL) {
1042 if (line6->urb_listen != NULL)
1027f476 1043 line6_stop_listen(line6);
705ececd 1044
36445bc1
GKH
1045 if (usbdev != line6->usbdev)
1046 dev_err(line6->ifcdev,
1047 "driver bug: inconsistent usb device\n");
705ececd 1048
a23a8bff
CR
1049 switch (line6->type) {
1050 case LINE6_BASSPODXT:
1051 case LINE6_BASSPODXTLIVE:
1052 case LINE6_BASSPODXTPRO:
1053 case LINE6_POCKETPOD:
1054 case LINE6_PODXT:
1055 case LINE6_PODXTPRO:
1027f476 1056 line6_pod_disconnect(interface);
705ececd
MG
1057 break;
1058
a23a8bff
CR
1059 case LINE6_PODHD300:
1060 case LINE6_PODHD400:
951dd316
CR
1061 case LINE6_PODHD500_0:
1062 case LINE6_PODHD500_1:
16dc1040
SH
1063 line6_podhd_disconnect(interface);
1064 break;
1065
7ad07310
CR
1066 case LINE6_PODXTLIVE_POD:
1067 line6_pod_disconnect(interface);
1068 break;
705ececd 1069
7ad07310
CR
1070 case LINE6_PODXTLIVE_VARIAX:
1071 line6_variax_disconnect(interface);
705ececd
MG
1072 break;
1073
a23a8bff 1074 case LINE6_VARIAX:
1027f476 1075 line6_variax_disconnect(interface);
705ececd
MG
1076 break;
1077
a23a8bff
CR
1078 case LINE6_PODSTUDIO_GX:
1079 case LINE6_PODSTUDIO_UX1:
1080 case LINE6_PODSTUDIO_UX2:
1081 case LINE6_TONEPORT_GX:
1082 case LINE6_TONEPORT_UX1:
1083 case LINE6_TONEPORT_UX2:
1084 case LINE6_GUITARPORT:
1027f476 1085 line6_toneport_disconnect(interface);
705ececd
MG
1086 break;
1087
1088 default:
1089 MISSING_CASE;
1090 }
1091
e1a164d7
MG
1092 dev_info(&interface->dev, "Line6 %s now disconnected\n",
1093 line6->properties->name);
705ececd
MG
1094 }
1095
1096 line6_destruct(interface);
1097
1098 /* decrement reference counters: */
1099 usb_put_intf(interface);
1100 usb_put_dev(usbdev);
1027f476
MG
1101}
1102
1103#ifdef CONFIG_PM
1104
1105/*
1106 Suspend Line6 device.
1107*/
1108static int line6_suspend(struct usb_interface *interface, pm_message_t message)
1109{
1110 struct usb_line6 *line6 = usb_get_intfdata(interface);
1111 struct snd_line6_pcm *line6pcm = line6->line6pcm;
1112
1113 snd_power_change_state(line6->card, SNDRV_CTL_POWER_D3hot);
1114
4cb1a4ae 1115 if (line6->properties->capabilities & LINE6_CAP_CONTROL)
1027f476
MG
1116 line6_stop_listen(line6);
1117
1118 if (line6pcm != NULL) {
1119 snd_pcm_suspend_all(line6pcm->pcm);
1120 line6_pcm_disconnect(line6pcm);
1121 line6pcm->flags = 0;
1122 }
1123
1124 return 0;
1125}
1126
1127/*
1128 Resume Line6 device.
1129*/
1130static int line6_resume(struct usb_interface *interface)
1131{
1132 struct usb_line6 *line6 = usb_get_intfdata(interface);
1133
4cb1a4ae 1134 if (line6->properties->capabilities & LINE6_CAP_CONTROL)
1027f476
MG
1135 line6_start_listen(line6);
1136
1137 snd_power_change_state(line6->card, SNDRV_CTL_POWER_D0);
1138 return 0;
1139}
1140
1141/*
1142 Resume Line6 device after reset.
1143*/
1144static int line6_reset_resume(struct usb_interface *interface)
1145{
1146 struct usb_line6 *line6 = usb_get_intfdata(interface);
705ececd 1147
a23a8bff
CR
1148 switch (line6->type) {
1149 case LINE6_PODSTUDIO_GX:
1150 case LINE6_PODSTUDIO_UX1:
1151 case LINE6_PODSTUDIO_UX2:
1152 case LINE6_TONEPORT_GX:
1153 case LINE6_TONEPORT_UX1:
1154 case LINE6_TONEPORT_UX2:
1155 case LINE6_GUITARPORT:
1027f476 1156 line6_toneport_reset_resume((struct usb_line6_toneport *)line6);
a23a8bff
CR
1157
1158 default:
1159 break;
1027f476
MG
1160 }
1161
1162 return line6_resume(interface);
705ececd
MG
1163}
1164
e1a164d7 1165#endif /* CONFIG_PM */
1027f476 1166
705ececd 1167static struct usb_driver line6_driver = {
705ececd
MG
1168 .name = DRIVER_NAME,
1169 .probe = line6_probe,
1170 .disconnect = line6_disconnect,
1027f476
MG
1171#ifdef CONFIG_PM
1172 .suspend = line6_suspend,
1173 .resume = line6_resume,
1174 .reset_resume = line6_reset_resume,
1175#endif
705ececd
MG
1176 .id_table = line6_id_table,
1177};
1178
4a631364 1179module_usb_driver(line6_driver);
705ececd
MG
1180
1181MODULE_AUTHOR(DRIVER_AUTHOR);
1182MODULE_DESCRIPTION(DRIVER_DESC);
1183MODULE_LICENSE("GPL");
1184MODULE_VERSION(DRIVER_VERSION);
This page took 0.685342 seconds and 5 git commands to generate.