1
2
3
4
5
6
7
8
9
10
11
12#include <linux/slab.h>
13#include <linux/wait.h>
14#include <linux/interrupt.h>
15#include <linux/module.h>
16#include <linux/usb.h>
17
18#include <sound/core.h>
19#include <sound/control.h>
20
21#include "capture.h"
22#include "driver.h"
23#include "playback.h"
24
25
26
27
28#define POD_NAME_OFFSET 0
29#define POD_NAME_LENGTH 16
30
31
32
33
34#define POD_CONTROL_SIZE 0x80
35#define POD_BUFSIZE_DUMPREQ 7
36#define POD_STARTUP_DELAY 1000
37
38
39
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 {
60
61 struct usb_line6 line6;
62
63
64 int monitor_level;
65
66
67 struct timer_list startup_timer;
68
69
70 struct work_struct startup_work;
71
72
73 int startup_progress;
74
75
76 u32 serial_number;
77
78
79 int firmware_version;
80
81
82 int device_id;
83};
84
85#define POD_SYSEX_CODE 3
86
87
88
89enum {
90 POD_SYSEX_SAVE = 0x24,
91 POD_SYSEX_SYSTEM = 0x56,
92 POD_SYSEX_SYSTEMREQ = 0x57,
93
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
99
100
101
102};
103
104enum {
105 POD_MONITOR_LEVEL = 0x04,
106 POD_SYSTEM_INVALID = 0x10000
107};
108
109
110
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
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 = {
131 .playback_hw = {
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 |
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},
149 .capture_hw = {
150 .info = (SNDRV_PCM_INFO_MMAP |
151 SNDRV_PCM_INFO_INTERLEAVED |
152 SNDRV_PCM_INFO_BLOCK_TRANSFER |
153 SNDRV_PCM_INFO_MMAP_VALID |
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},
166 .rates = {
167 .nrats = 1,
168 .rats = &pod_ratden},
169 .bytes_per_channel = 3
170};
171
172static const char pod_version_header[] = {
173 0xf2, 0x7e, 0x7f, 0x06, 0x02
174};
175
176
177static void pod_startup2(unsigned long data);
178static void pod_startup3(struct usb_line6_pod *pod);
179
180static char *pod_alloc_sysex_buffer(struct usb_line6_pod *pod, int code,
181 int size)
182{
183 return line6_alloc_sysex_buffer(&pod->line6, POD_SYSEX_CODE, code,
184 size);
185}
186
187
188
189
190static void line6_pod_process_message(struct usb_line6 *line6)
191{
192 struct usb_line6_pod *pod = (struct usb_line6_pod *) line6;
193 const unsigned char *buf = pod->line6.buffer_message;
194
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;
201 }
202
203
204 if (buf[0] != (LINE6_SYSEX_BEGIN | LINE6_CHANNEL_DEVICE) &&
205 buf[0] != (LINE6_SYSEX_BEGIN | LINE6_CHANNEL_UNKNOWN)) {
206 return;
207 }
208 if (memcmp(buf + 1, line6_midi_id, sizeof(line6_midi_id)) != 0)
209 return;
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;
215 }
216}
217
218
219
220
221static int pod_set_system_param_int(struct usb_line6_pod *pod, int value,
222 int code)
223{
224 char *sysex;
225 static const int size = 5;
226
227 sysex = pod_alloc_sysex_buffer(pod, POD_SYSEX_SYSTEM, size);
228 if (!sysex)
229 return -ENOMEM;
230 sysex[SYSEX_DATA_OFS] = code;
231 sysex[SYSEX_DATA_OFS + 1] = (value >> 12) & 0x0f;
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;
235 line6_send_sysex_message(&pod->line6, sysex, size);
236 kfree(sysex);
237 return 0;
238}
239
240
241
242
243static ssize_t serial_number_show(struct device *dev,
244 struct device_attribute *attr, char *buf)
245{
246 struct snd_card *card = dev_to_snd_card(dev);
247 struct usb_line6_pod *pod = card->private_data;
248
249 return sprintf(buf, "%u\n", pod->serial_number);
250}
251
252
253
254
255static ssize_t firmware_version_show(struct device *dev,
256 struct device_attribute *attr, char *buf)
257{
258 struct snd_card *card = dev_to_snd_card(dev);
259 struct usb_line6_pod *pod = card->private_data;
260
261 return sprintf(buf, "%d.%02d\n", pod->firmware_version / 100,
262 pod->firmware_version % 100);
263}
264
265
266
267
268static ssize_t device_id_show(struct device *dev,
269 struct device_attribute *attr, char *buf)
270{
271 struct snd_card *card = dev_to_snd_card(dev);
272 struct usb_line6_pod *pod = card->private_data;
273
274 return sprintf(buf, "%d\n", pod->device_id);
275}
276
277
278
279
280
281
282
283
284static void pod_startup1(struct usb_line6_pod *pod)
285{
286 CHECK_STARTUP_PROGRESS(pod->startup_progress, POD_STARTUP_INIT);
287
288
289 line6_start_timer(&pod->startup_timer, POD_STARTUP_DELAY, pod_startup2,
290 (unsigned long)pod);
291}
292
293static void pod_startup2(unsigned long data)
294{
295 struct usb_line6_pod *pod = (struct usb_line6_pod *)data;
296 struct usb_line6 *line6 = &pod->line6;
297
298 CHECK_STARTUP_PROGRESS(pod->startup_progress, POD_STARTUP_VERSIONREQ);
299
300
301 line6_version_request_async(line6);
302}
303
304static void pod_startup3(struct usb_line6_pod *pod)
305{
306 CHECK_STARTUP_PROGRESS(pod->startup_progress, POD_STARTUP_WORKQUEUE);
307
308
309 schedule_work(&pod->startup_work);
310}
311
312static void pod_startup4(struct work_struct *work)
313{
314 struct usb_line6_pod *pod =
315 container_of(work, struct usb_line6_pod, startup_work);
316 struct usb_line6 *line6 = &pod->line6;
317
318 CHECK_STARTUP_PROGRESS(pod->startup_progress, POD_STARTUP_SETUP);
319
320
321 line6_read_serial_number(&pod->line6, &pod->serial_number);
322
323
324 snd_card_register(line6->card);
325}
326
327
328static DEVICE_ATTR_RO(device_id);
329static DEVICE_ATTR_RO(firmware_version);
330static DEVICE_ATTR_RO(serial_number);
331
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
344
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
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;
361
362 ucontrol->value.integer.value[0] = pod->monitor_level;
363 return 0;
364}
365
366
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
373 if (ucontrol->value.integer.value[0] == pod->monitor_level)
374 return 0;
375
376 pod->monitor_level = ucontrol->value.integer.value[0];
377 pod_set_system_param_int(pod, ucontrol->value.integer.value[0],
378 POD_MONITOR_LEVEL);
379 return 1;
380}
381
382
383static const 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
393
394
395
396static void line6_pod_disconnect(struct usb_line6 *line6)
397{
398 struct usb_line6_pod *pod = (struct usb_line6_pod *)line6;
399
400 del_timer_sync(&pod->startup_timer);
401 cancel_work_sync(&pod->startup_work);
402}
403
404
405
406
407static int pod_init(struct usb_line6 *line6,
408 const struct usb_device_id *id)
409{
410 int err;
411 struct usb_line6_pod *pod = (struct usb_line6_pod *) line6;
412
413 line6->process_message = line6_pod_process_message;
414 line6->disconnect = line6_pod_disconnect;
415
416 init_timer(&pod->startup_timer);
417 INIT_WORK(&pod->startup_work, pod_startup4);
418
419
420 err = snd_card_add_dev_attr(line6->card, &pod_dev_attr_group);
421 if (err < 0)
422 return err;
423
424
425 err = line6_init_midi(line6);
426 if (err < 0)
427 return err;
428
429
430 err = line6_init_pcm(line6, &pod_pcm_properties);
431 if (err < 0)
432 return err;
433
434
435 err = snd_ctl_add(line6->card,
436 snd_ctl_new1(&pod_control_monitor, line6->line6pcm));
437 if (err < 0)
438 return err;
439
440
441
442
443
444
445
446 if (pod->line6.properties->capabilities & LINE6_CAP_CONTROL) {
447 pod->monitor_level = POD_SYSTEM_INVALID;
448
449
450 pod_startup1(pod);
451 }
452
453 return 0;
454}
455
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
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
478 | LINE6_CAP_CONTROL_MIDI
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
491 | LINE6_CAP_CONTROL_MIDI
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
504 | LINE6_CAP_CONTROL_MIDI
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",
516 .capabilities = LINE6_CAP_CONTROL
517 | LINE6_CAP_CONTROL_MIDI,
518 .altsetting = 0,
519 .ep_ctrl_r = 0x82,
520 .ep_ctrl_w = 0x02,
521
522 },
523 [LINE6_PODXT] = {
524 .id = "PODxt",
525 .name = "PODxt",
526 .capabilities = LINE6_CAP_CONTROL
527 | LINE6_CAP_CONTROL_MIDI
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
540 | LINE6_CAP_CONTROL_MIDI
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
553 | LINE6_CAP_CONTROL_MIDI
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
566
567static int pod_probe(struct usb_interface *interface,
568 const struct usb_device_id *id)
569{
570 return line6_probe(interface, id, "Line6-POD",
571 &pod_properties_table[id->driver_info],
572 pod_init, sizeof(struct usb_line6_pod));
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
589MODULE_DESCRIPTION("Line 6 POD USB driver");
590MODULE_LICENSE("GPL");
591