]> git.proxmox.com Git - mirror_ubuntu-zesty-kernel.git/blame - sound/usb/line6/pod.c
Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/viro/vfs
[mirror_ubuntu-zesty-kernel.git] / sound / usb / line6 / pod.c
CommitLineData
705ececd 1/*
c078a4aa 2 * Line 6 Linux USB driver
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
5a0e3ad6 12#include <linux/slab.h>
1027f476 13#include <linux/wait.h>
ccddbe4a
TI
14#include <linux/interrupt.h>
15#include <linux/module.h>
16#include <linux/usb.h>
17
18#include <sound/core.h>
1027f476 19#include <sound/control.h>
5a0e3ad6 20
705ececd 21#include "capture.h"
1027f476 22#include "driver.h"
705ececd 23#include "playback.h"
ccddbe4a
TI
24
25/*
26 Locate name in binary program dump
27*/
28#define POD_NAME_OFFSET 0
29#define POD_NAME_LENGTH 16
30
31/*
32 Other constants
33*/
34#define POD_CONTROL_SIZE 0x80
35#define POD_BUFSIZE_DUMPREQ 7
36#define POD_STARTUP_DELAY 1000
37
38/*
39 Stages of POD startup procedure
40*/
41enum {
42 POD_STARTUP_INIT = 1,
43 POD_STARTUP_VERSIONREQ,
44 POD_STARTUP_WORKQUEUE,
45 POD_STARTUP_SETUP,
46 POD_STARTUP_LAST = POD_STARTUP_SETUP - 1
47};
48
49enum {
50 LINE6_BASSPODXT,
51 LINE6_BASSPODXTLIVE,
52 LINE6_BASSPODXTPRO,
53 LINE6_POCKETPOD,
54 LINE6_PODXT,
55 LINE6_PODXTLIVE_POD,
56 LINE6_PODXTPRO,
57};
58
59struct usb_line6_pod {
cddbd4f1 60 /* Generic Line 6 USB data */
ccddbe4a
TI
61 struct usb_line6 line6;
62
cddbd4f1 63 /* Instrument monitor level */
ccddbe4a
TI
64 int monitor_level;
65
cddbd4f1 66 /* Timer for device initialization */
ccddbe4a
TI
67 struct timer_list startup_timer;
68
cddbd4f1 69 /* Work handler for device initialization */
ccddbe4a
TI
70 struct work_struct startup_work;
71
cddbd4f1 72 /* Current progress in startup procedure */
ccddbe4a
TI
73 int startup_progress;
74
cddbd4f1 75 /* Serial number of device */
12b00157 76 u32 serial_number;
ccddbe4a 77
cddbd4f1 78 /* Firmware version (x 100) */
ccddbe4a
TI
79 int firmware_version;
80
cddbd4f1 81 /* Device ID */
ccddbe4a
TI
82 int device_id;
83};
705ececd 84
705ececd 85#define POD_SYSEX_CODE 3
705ececd 86
e1a164d7 87/* *INDENT-OFF* */
705ececd
MG
88
89enum {
705ececd
MG
90 POD_SYSEX_SAVE = 0x24,
91 POD_SYSEX_SYSTEM = 0x56,
92 POD_SYSEX_SYSTEMREQ = 0x57,
93 /* POD_SYSEX_UPDATE = 0x6c, */ /* software update! */
94 POD_SYSEX_STORE = 0x71,
95 POD_SYSEX_FINISH = 0x72,
96 POD_SYSEX_DUMPMEM = 0x73,
97 POD_SYSEX_DUMP = 0x74,
98 POD_SYSEX_DUMPREQ = 0x75
0a1eb4e8
SH
99
100 /* dumps entire internal memory of PODxt Pro */
101 /* POD_SYSEX_DUMPMEM2 = 0x76 */
705ececd
MG
102};
103
104enum {
7936095f
SH
105 POD_MONITOR_LEVEL = 0x04,
106 POD_SYSTEM_INVALID = 0x10000
705ececd
MG
107};
108
e1a164d7
MG
109/* *INDENT-ON* */
110
705ececd
MG
111enum {
112 POD_DUMP_MEMORY = 2
113};
114
115enum {
116 POD_BUSY_READ,
117 POD_BUSY_WRITE,
118 POD_CHANNEL_DIRTY,
119 POD_SAVE_PRESSED,
120 POD_BUSY_MIDISEND
121};
122
705ececd
MG
123static struct snd_ratden pod_ratden = {
124 .num_min = 78125,
125 .num_max = 78125,
126 .num_step = 1,
127 .den = 2
128};
129
130static struct line6_pcm_properties pod_pcm_properties = {
1263f611 131 .playback_hw = {
e1a164d7
MG
132 .info = (SNDRV_PCM_INFO_MMAP |
133 SNDRV_PCM_INFO_INTERLEAVED |
134 SNDRV_PCM_INFO_BLOCK_TRANSFER |
135 SNDRV_PCM_INFO_MMAP_VALID |
136 SNDRV_PCM_INFO_PAUSE |
e1a164d7
MG
137 SNDRV_PCM_INFO_SYNC_START),
138 .formats = SNDRV_PCM_FMTBIT_S24_3LE,
139 .rates = SNDRV_PCM_RATE_KNOT,
140 .rate_min = 39062,
141 .rate_max = 39063,
142 .channels_min = 2,
143 .channels_max = 2,
144 .buffer_bytes_max = 60000,
145 .period_bytes_min = 64,
146 .period_bytes_max = 8192,
147 .periods_min = 1,
148 .periods_max = 1024},
1263f611 149 .capture_hw = {
e1a164d7
MG
150 .info = (SNDRV_PCM_INFO_MMAP |
151 SNDRV_PCM_INFO_INTERLEAVED |
152 SNDRV_PCM_INFO_BLOCK_TRANSFER |
153 SNDRV_PCM_INFO_MMAP_VALID |
e1a164d7
MG
154 SNDRV_PCM_INFO_SYNC_START),
155 .formats = SNDRV_PCM_FMTBIT_S24_3LE,
156 .rates = SNDRV_PCM_RATE_KNOT,
157 .rate_min = 39062,
158 .rate_max = 39063,
159 .channels_min = 2,
160 .channels_max = 2,
161 .buffer_bytes_max = 60000,
162 .period_bytes_min = 64,
163 .period_bytes_max = 8192,
164 .periods_min = 1,
165 .periods_max = 1024},
1263f611 166 .rates = {
e1a164d7
MG
167 .nrats = 1,
168 .rats = &pod_ratden},
97d78acf 169 .bytes_per_channel = 3 /* SNDRV_PCM_FMTBIT_S24_3LE */
705ececd
MG
170};
171
e1a164d7 172static const char pod_version_header[] = {
1027f476
MG
173 0xf2, 0x7e, 0x7f, 0x06, 0x02
174};
175
1027f476
MG
176/* forward declarations: */
177static void pod_startup2(unsigned long data);
178static void pod_startup3(struct usb_line6_pod *pod);
705ececd 179
e1a164d7
MG
180static char *pod_alloc_sysex_buffer(struct usb_line6_pod *pod, int code,
181 int size)
705ececd 182{
e1a164d7
MG
183 return line6_alloc_sysex_buffer(&pod->line6, POD_SYSEX_CODE, code,
184 size);
705ececd
MG
185}
186
705ececd
MG
187/*
188 Process a completely received message.
189*/
01f6b2bc 190static void line6_pod_process_message(struct usb_line6 *line6)
705ececd 191{
1cad3e8d 192 struct usb_line6_pod *pod = (struct usb_line6_pod *) line6;
705ececd
MG
193 const unsigned char *buf = pod->line6.buffer_message;
194
4e6a8ffb
SH
195 if (memcmp(buf, pod_version_header, sizeof(pod_version_header)) == 0) {
196 pod->firmware_version = buf[13] * 100 + buf[14] * 10 + buf[15];
197 pod->device_id = ((int)buf[8] << 16) | ((int)buf[9] << 8) |
198 (int) buf[10];
199 pod_startup3(pod);
200 return;
705ececd
MG
201 }
202
4e6a8ffb
SH
203 /* Only look for sysex messages from this device */
204 if (buf[0] != (LINE6_SYSEX_BEGIN | LINE6_CHANNEL_DEVICE) &&
205 buf[0] != (LINE6_SYSEX_BEGIN | LINE6_CHANNEL_UNKNOWN)) {
206 return;
207 }
c19e9461 208 if (memcmp(buf + 1, line6_midi_id, sizeof(line6_midi_id)) != 0)
4e6a8ffb 209 return;
4e6a8ffb
SH
210
211 if (buf[5] == POD_SYSEX_SYSTEM && buf[6] == POD_MONITOR_LEVEL) {
212 short value = ((int)buf[7] << 12) | ((int)buf[8] << 8) |
213 ((int)buf[9] << 4) | (int)buf[10];
214 pod->monitor_level = value;
705ececd
MG
215 }
216}
217
705ececd 218/*
1027f476 219 Send system parameter (from integer).
705ececd 220*/
e1a164d7
MG
221static int pod_set_system_param_int(struct usb_line6_pod *pod, int value,
222 int code)
705ececd
MG
223{
224 char *sysex;
225 static const int size = 5;
705ececd 226
705ececd 227 sysex = pod_alloc_sysex_buffer(pod, POD_SYSEX_SYSTEM, size);
0fdef36a 228 if (!sysex)
1027f476 229 return -ENOMEM;
705ececd
MG
230 sysex[SYSEX_DATA_OFS] = code;
231 sysex[SYSEX_DATA_OFS + 1] = (value >> 12) & 0x0f;
e1a164d7
MG
232 sysex[SYSEX_DATA_OFS + 2] = (value >> 8) & 0x0f;
233 sysex[SYSEX_DATA_OFS + 3] = (value >> 4) & 0x0f;
234 sysex[SYSEX_DATA_OFS + 4] = (value) & 0x0f;
705ececd
MG
235 line6_send_sysex_message(&pod->line6, sysex, size);
236 kfree(sysex);
1027f476
MG
237 return 0;
238}
239
705ececd
MG
240/*
241 "read" request on "serial_number" special file.
242*/
e7c8a7e3
GKH
243static ssize_t serial_number_show(struct device *dev,
244 struct device_attribute *attr, char *buf)
705ececd 245{
b027d112
AK
246 struct snd_card *card = dev_to_snd_card(dev);
247 struct usb_line6_pod *pod = card->private_data;
f3c5261e 248
12b00157 249 return sprintf(buf, "%u\n", pod->serial_number);
705ececd
MG
250}
251
252/*
253 "read" request on "firmware_version" special file.
254*/
e7c8a7e3
GKH
255static ssize_t firmware_version_show(struct device *dev,
256 struct device_attribute *attr, char *buf)
705ececd 257{
b027d112
AK
258 struct snd_card *card = dev_to_snd_card(dev);
259 struct usb_line6_pod *pod = card->private_data;
f3c5261e 260
0fdef36a
GKH
261 return sprintf(buf, "%d.%02d\n", pod->firmware_version / 100,
262 pod->firmware_version % 100);
705ececd
MG
263}
264
265/*
266 "read" request on "device_id" special file.
267*/
e7c8a7e3
GKH
268static ssize_t device_id_show(struct device *dev,
269 struct device_attribute *attr, char *buf)
705ececd 270{
b027d112
AK
271 struct snd_card *card = dev_to_snd_card(dev);
272 struct usb_line6_pod *pod = card->private_data;
f3c5261e 273
705ececd
MG
274 return sprintf(buf, "%d\n", pod->device_id);
275}
276
1027f476
MG
277/*
278 POD startup procedure.
279 This is a sequence of functions with special requirements (e.g., must
280 not run immediately after initialization, must not run in interrupt
281 context). After the last one has finished, the device is ready to use.
282*/
283
284static void pod_startup1(struct usb_line6_pod *pod)
285{
e1a164d7 286 CHECK_STARTUP_PROGRESS(pod->startup_progress, POD_STARTUP_INIT);
1027f476
MG
287
288 /* delay startup procedure: */
e1a164d7
MG
289 line6_start_timer(&pod->startup_timer, POD_STARTUP_DELAY, pod_startup2,
290 (unsigned long)pod);
1027f476
MG
291}
292
293static void pod_startup2(unsigned long data)
294{
295 struct usb_line6_pod *pod = (struct usb_line6_pod *)data;
1027f476 296 struct usb_line6 *line6 = &pod->line6;
f3c5261e 297
e1a164d7 298 CHECK_STARTUP_PROGRESS(pod->startup_progress, POD_STARTUP_VERSIONREQ);
1027f476
MG
299
300 /* request firmware version: */
301 line6_version_request_async(line6);
705ececd
MG
302}
303
09fda10a 304static void pod_startup3(struct usb_line6_pod *pod)
1027f476 305{
e1a164d7 306 CHECK_STARTUP_PROGRESS(pod->startup_progress, POD_STARTUP_WORKQUEUE);
1027f476
MG
307
308 /* schedule work for global work queue: */
309 schedule_work(&pod->startup_work);
310}
311
09fda10a 312static void pod_startup4(struct work_struct *work)
1027f476 313{
e1a164d7
MG
314 struct usb_line6_pod *pod =
315 container_of(work, struct usb_line6_pod, startup_work);
1027f476
MG
316 struct usb_line6 *line6 = &pod->line6;
317
e1a164d7 318 CHECK_STARTUP_PROGRESS(pod->startup_progress, POD_STARTUP_SETUP);
1027f476
MG
319
320 /* serial number: */
321 line6_read_serial_number(&pod->line6, &pod->serial_number);
322
323 /* ALSA audio interface: */
85a9339b 324 snd_card_register(line6->card);
1027f476
MG
325}
326
705ececd 327/* POD special files: */
e7c8a7e3
GKH
328static DEVICE_ATTR_RO(device_id);
329static DEVICE_ATTR_RO(firmware_version);
330static DEVICE_ATTR_RO(serial_number);
705ececd 331
02fc76f6
TI
332static struct attribute *pod_dev_attrs[] = {
333 &dev_attr_device_id.attr,
334 &dev_attr_firmware_version.attr,
335 &dev_attr_serial_number.attr,
336 NULL
337};
338
339static const struct attribute_group pod_dev_attr_group = {
340 .name = "pod",
341 .attrs = pod_dev_attrs,
342};
343
1027f476
MG
344/* control info callback */
345static int snd_pod_control_monitor_info(struct snd_kcontrol *kcontrol,
346 struct snd_ctl_elem_info *uinfo)
347{
348 uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
349 uinfo->count = 1;
350 uinfo->value.integer.min = 0;
351 uinfo->value.integer.max = 65535;
352 return 0;
353}
354
355/* control get callback */
356static int snd_pod_control_monitor_get(struct snd_kcontrol *kcontrol,
357 struct snd_ctl_elem_value *ucontrol)
358{
359 struct snd_line6_pcm *line6pcm = snd_kcontrol_chip(kcontrol);
360 struct usb_line6_pod *pod = (struct usb_line6_pod *)line6pcm->line6;
f3c5261e 361
2c35dc21 362 ucontrol->value.integer.value[0] = pod->monitor_level;
1027f476
MG
363 return 0;
364}
365
366/* control put callback */
367static int snd_pod_control_monitor_put(struct snd_kcontrol *kcontrol,
368 struct snd_ctl_elem_value *ucontrol)
369{
370 struct snd_line6_pcm *line6pcm = snd_kcontrol_chip(kcontrol);
371 struct usb_line6_pod *pod = (struct usb_line6_pod *)line6pcm->line6;
372
2c35dc21 373 if (ucontrol->value.integer.value[0] == pod->monitor_level)
1027f476
MG
374 return 0;
375
2c35dc21 376 pod->monitor_level = ucontrol->value.integer.value[0];
e1a164d7 377 pod_set_system_param_int(pod, ucontrol->value.integer.value[0],
7936095f 378 POD_MONITOR_LEVEL);
1027f476
MG
379 return 1;
380}
381
382/* control definition */
383static struct snd_kcontrol_new pod_control_monitor = {
384 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
385 .name = "Monitor Playback Volume",
386 .index = 0,
387 .access = SNDRV_CTL_ELEM_ACCESS_READWRITE,
388 .info = snd_pod_control_monitor_info,
389 .get = snd_pod_control_monitor_get,
390 .put = snd_pod_control_monitor_put
391};
392
d29b854f
CR
393/*
394 POD device disconnected.
395*/
f66fd990 396static void line6_pod_disconnect(struct usb_line6 *line6)
d29b854f 397{
f66fd990 398 struct usb_line6_pod *pod = (struct usb_line6_pod *)line6;
d29b854f 399
8a3b7c08
TI
400 del_timer_sync(&pod->startup_timer);
401 cancel_work_sync(&pod->startup_work);
d29b854f
CR
402}
403
705ececd 404/*
1027f476 405 Try to init POD device.
705ececd 406*/
f66fd990
TI
407static int pod_init(struct usb_line6 *line6,
408 const struct usb_device_id *id)
705ececd
MG
409{
410 int err;
a221dd45 411 struct usb_line6_pod *pod = (struct usb_line6_pod *) line6;
705ececd 412
01f6b2bc 413 line6->process_message = line6_pod_process_message;
a46c4672 414 line6->disconnect = line6_pod_disconnect;
01f6b2bc 415
e1a164d7 416 init_timer(&pod->startup_timer);
09fda10a 417 INIT_WORK(&pod->startup_work, pod_startup4);
e1a164d7 418
705ececd 419 /* create sysfs entries: */
02fc76f6 420 err = snd_card_add_dev_attr(line6->card, &pod_dev_attr_group);
027360c5 421 if (err < 0)
705ececd 422 return err;
705ececd 423
705ececd 424 /* initialize MIDI subsystem: */
0fdef36a 425 err = line6_init_midi(line6);
027360c5 426 if (err < 0)
705ececd 427 return err;
705ececd
MG
428
429 /* initialize PCM subsystem: */
0fdef36a 430 err = line6_init_pcm(line6, &pod_pcm_properties);
027360c5 431 if (err < 0)
705ececd 432 return err;
705ececd 433
1027f476 434 /* register monitor control: */
027360c5
GKH
435 err = snd_ctl_add(line6->card,
436 snd_ctl_new1(&pod_control_monitor, line6->line6pcm));
437 if (err < 0)
705ececd 438 return err;
705ececd 439
1027f476 440 /*
e1a164d7
MG
441 When the sound card is registered at this point, the PODxt Live
442 displays "Invalid Code Error 07", so we do it later in the event
443 handler.
444 */
1027f476 445
4cb1a4ae 446 if (pod->line6.properties->capabilities & LINE6_CAP_CONTROL) {
7936095f 447 pod->monitor_level = POD_SYSTEM_INVALID;
1027f476
MG
448
449 /* initiate startup procedure: */
450 pod_startup1(pod);
705ececd
MG
451 }
452
453 return 0;
454}
455
ccddbe4a
TI
456#define LINE6_DEVICE(prod) USB_DEVICE(0x0e41, prod)
457#define LINE6_IF_NUM(prod, n) USB_DEVICE_INTERFACE_NUMBER(0x0e41, prod, n)
458
459/* table of devices that work with this driver */
460static const struct usb_device_id pod_id_table[] = {
461 { LINE6_DEVICE(0x4250), .driver_info = LINE6_BASSPODXT },
462 { LINE6_DEVICE(0x4642), .driver_info = LINE6_BASSPODXTLIVE },
463 { LINE6_DEVICE(0x4252), .driver_info = LINE6_BASSPODXTPRO },
464 { LINE6_IF_NUM(0x5051, 1), .driver_info = LINE6_POCKETPOD },
465 { LINE6_DEVICE(0x5044), .driver_info = LINE6_PODXT },
466 { LINE6_IF_NUM(0x4650, 0), .driver_info = LINE6_PODXTLIVE_POD },
467 { LINE6_DEVICE(0x5050), .driver_info = LINE6_PODXTPRO },
468 {}
469};
470
471MODULE_DEVICE_TABLE(usb, pod_id_table);
472
473static const struct line6_properties pod_properties_table[] = {
474 [LINE6_BASSPODXT] = {
475 .id = "BassPODxt",
476 .name = "BassPODxt",
477 .capabilities = LINE6_CAP_CONTROL
174e1fc0 478 | LINE6_CAP_CONTROL_MIDI
ccddbe4a
TI
479 | LINE6_CAP_PCM
480 | LINE6_CAP_HWMON,
481 .altsetting = 5,
482 .ep_ctrl_r = 0x84,
483 .ep_ctrl_w = 0x03,
484 .ep_audio_r = 0x82,
485 .ep_audio_w = 0x01,
486 },
487 [LINE6_BASSPODXTLIVE] = {
488 .id = "BassPODxtLive",
489 .name = "BassPODxt Live",
490 .capabilities = LINE6_CAP_CONTROL
174e1fc0 491 | LINE6_CAP_CONTROL_MIDI
ccddbe4a
TI
492 | LINE6_CAP_PCM
493 | LINE6_CAP_HWMON,
494 .altsetting = 1,
495 .ep_ctrl_r = 0x84,
496 .ep_ctrl_w = 0x03,
497 .ep_audio_r = 0x82,
498 .ep_audio_w = 0x01,
499 },
500 [LINE6_BASSPODXTPRO] = {
501 .id = "BassPODxtPro",
502 .name = "BassPODxt Pro",
503 .capabilities = LINE6_CAP_CONTROL
174e1fc0 504 | LINE6_CAP_CONTROL_MIDI
ccddbe4a
TI
505 | LINE6_CAP_PCM
506 | LINE6_CAP_HWMON,
507 .altsetting = 5,
508 .ep_ctrl_r = 0x84,
509 .ep_ctrl_w = 0x03,
510 .ep_audio_r = 0x82,
511 .ep_audio_w = 0x01,
512 },
513 [LINE6_POCKETPOD] = {
514 .id = "PocketPOD",
515 .name = "Pocket POD",
174e1fc0
AK
516 .capabilities = LINE6_CAP_CONTROL
517 | LINE6_CAP_CONTROL_MIDI,
ccddbe4a
TI
518 .altsetting = 0,
519 .ep_ctrl_r = 0x82,
520 .ep_ctrl_w = 0x02,
521 /* no audio channel */
522 },
523 [LINE6_PODXT] = {
524 .id = "PODxt",
525 .name = "PODxt",
526 .capabilities = LINE6_CAP_CONTROL
174e1fc0 527 | LINE6_CAP_CONTROL_MIDI
ccddbe4a
TI
528 | LINE6_CAP_PCM
529 | LINE6_CAP_HWMON,
530 .altsetting = 5,
531 .ep_ctrl_r = 0x84,
532 .ep_ctrl_w = 0x03,
533 .ep_audio_r = 0x82,
534 .ep_audio_w = 0x01,
535 },
536 [LINE6_PODXTLIVE_POD] = {
537 .id = "PODxtLive",
538 .name = "PODxt Live",
539 .capabilities = LINE6_CAP_CONTROL
174e1fc0 540 | LINE6_CAP_CONTROL_MIDI
ccddbe4a
TI
541 | LINE6_CAP_PCM
542 | LINE6_CAP_HWMON,
543 .altsetting = 1,
544 .ep_ctrl_r = 0x84,
545 .ep_ctrl_w = 0x03,
546 .ep_audio_r = 0x82,
547 .ep_audio_w = 0x01,
548 },
549 [LINE6_PODXTPRO] = {
550 .id = "PODxtPro",
551 .name = "PODxt Pro",
552 .capabilities = LINE6_CAP_CONTROL
174e1fc0 553 | LINE6_CAP_CONTROL_MIDI
ccddbe4a
TI
554 | LINE6_CAP_PCM
555 | LINE6_CAP_HWMON,
556 .altsetting = 5,
557 .ep_ctrl_r = 0x84,
558 .ep_ctrl_w = 0x03,
559 .ep_audio_r = 0x82,
560 .ep_audio_w = 0x01,
561 },
562};
563
564/*
565 Probe USB device.
566*/
567static int pod_probe(struct usb_interface *interface,
568 const struct usb_device_id *id)
569{
12865cac 570 return line6_probe(interface, id, "Line6-POD",
85a9339b 571 &pod_properties_table[id->driver_info],
aca514b8 572 pod_init, sizeof(struct usb_line6_pod));
ccddbe4a
TI
573}
574
575static struct usb_driver pod_driver = {
576 .name = KBUILD_MODNAME,
577 .probe = pod_probe,
578 .disconnect = line6_disconnect,
579#ifdef CONFIG_PM
580 .suspend = line6_suspend,
581 .resume = line6_resume,
582 .reset_resume = line6_resume,
583#endif
584 .id_table = pod_id_table,
585};
586
587module_usb_driver(pod_driver);
588
c6fffce9 589MODULE_DESCRIPTION("Line 6 POD USB driver");
ccddbe4a 590MODULE_LICENSE("GPL");