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(struct timer_list *t);
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}
291
292static void pod_startup2(struct timer_list *t)
293{
294 struct usb_line6_pod *pod = from_timer(pod, t, startup_timer);
295 struct usb_line6 *line6 = &pod->line6;
296
297 CHECK_STARTUP_PROGRESS(pod->startup_progress, POD_STARTUP_VERSIONREQ);
298
299
300 line6_version_request_async(line6);
301}
302
303static void pod_startup3(struct usb_line6_pod *pod)
304{
305 CHECK_STARTUP_PROGRESS(pod->startup_progress, POD_STARTUP_WORKQUEUE);
306
307
308 schedule_work(&pod->startup_work);
309}
310
311static void pod_startup4(struct work_struct *work)
312{
313 struct usb_line6_pod *pod =
314 container_of(work, struct usb_line6_pod, startup_work);
315 struct usb_line6 *line6 = &pod->line6;
316
317 CHECK_STARTUP_PROGRESS(pod->startup_progress, POD_STARTUP_SETUP);
318
319
320 line6_read_serial_number(&pod->line6, &pod->serial_number);
321
322
323 snd_card_register(line6->card);
324}
325
326
327static DEVICE_ATTR_RO(device_id);
328static DEVICE_ATTR_RO(firmware_version);
329static DEVICE_ATTR_RO(serial_number);
330
331static struct attribute *pod_dev_attrs[] = {
332 &dev_attr_device_id.attr,
333 &dev_attr_firmware_version.attr,
334 &dev_attr_serial_number.attr,
335 NULL
336};
337
338static const struct attribute_group pod_dev_attr_group = {
339 .name = "pod",
340 .attrs = pod_dev_attrs,
341};
342
343
344static int snd_pod_control_monitor_info(struct snd_kcontrol *kcontrol,
345 struct snd_ctl_elem_info *uinfo)
346{
347 uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
348 uinfo->count = 1;
349 uinfo->value.integer.min = 0;
350 uinfo->value.integer.max = 65535;
351 return 0;
352}
353
354
355static int snd_pod_control_monitor_get(struct snd_kcontrol *kcontrol,
356 struct snd_ctl_elem_value *ucontrol)
357{
358 struct snd_line6_pcm *line6pcm = snd_kcontrol_chip(kcontrol);
359 struct usb_line6_pod *pod = (struct usb_line6_pod *)line6pcm->line6;
360
361 ucontrol->value.integer.value[0] = pod->monitor_level;
362 return 0;
363}
364
365
366static int snd_pod_control_monitor_put(struct snd_kcontrol *kcontrol,
367 struct snd_ctl_elem_value *ucontrol)
368{
369 struct snd_line6_pcm *line6pcm = snd_kcontrol_chip(kcontrol);
370 struct usb_line6_pod *pod = (struct usb_line6_pod *)line6pcm->line6;
371
372 if (ucontrol->value.integer.value[0] == pod->monitor_level)
373 return 0;
374
375 pod->monitor_level = ucontrol->value.integer.value[0];
376 pod_set_system_param_int(pod, ucontrol->value.integer.value[0],
377 POD_MONITOR_LEVEL);
378 return 1;
379}
380
381
382static const struct snd_kcontrol_new pod_control_monitor = {
383 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
384 .name = "Monitor Playback Volume",
385 .index = 0,
386 .access = SNDRV_CTL_ELEM_ACCESS_READWRITE,
387 .info = snd_pod_control_monitor_info,
388 .get = snd_pod_control_monitor_get,
389 .put = snd_pod_control_monitor_put
390};
391
392
393
394
395static void line6_pod_disconnect(struct usb_line6 *line6)
396{
397 struct usb_line6_pod *pod = (struct usb_line6_pod *)line6;
398
399 del_timer_sync(&pod->startup_timer);
400 cancel_work_sync(&pod->startup_work);
401}
402
403
404
405
406static int pod_init(struct usb_line6 *line6,
407 const struct usb_device_id *id)
408{
409 int err;
410 struct usb_line6_pod *pod = (struct usb_line6_pod *) line6;
411
412 line6->process_message = line6_pod_process_message;
413 line6->disconnect = line6_pod_disconnect;
414
415 timer_setup(&pod->startup_timer, NULL, 0);
416 INIT_WORK(&pod->startup_work, pod_startup4);
417
418
419 err = snd_card_add_dev_attr(line6->card, &pod_dev_attr_group);
420 if (err < 0)
421 return err;
422
423
424 err = line6_init_midi(line6);
425 if (err < 0)
426 return err;
427
428
429 err = line6_init_pcm(line6, &pod_pcm_properties);
430 if (err < 0)
431 return err;
432
433
434 err = snd_ctl_add(line6->card,
435 snd_ctl_new1(&pod_control_monitor, line6->line6pcm));
436 if (err < 0)
437 return err;
438
439
440
441
442
443
444
445 if (pod->line6.properties->capabilities & LINE6_CAP_CONTROL) {
446 pod->monitor_level = POD_SYSTEM_INVALID;
447
448
449 pod_startup1(pod);
450 }
451
452 return 0;
453}
454
455#define LINE6_DEVICE(prod) USB_DEVICE(0x0e41, prod)
456#define LINE6_IF_NUM(prod, n) USB_DEVICE_INTERFACE_NUMBER(0x0e41, prod, n)
457
458
459static const struct usb_device_id pod_id_table[] = {
460 { LINE6_DEVICE(0x4250), .driver_info = LINE6_BASSPODXT },
461 { LINE6_DEVICE(0x4642), .driver_info = LINE6_BASSPODXTLIVE },
462 { LINE6_DEVICE(0x4252), .driver_info = LINE6_BASSPODXTPRO },
463 { LINE6_IF_NUM(0x5051, 1), .driver_info = LINE6_POCKETPOD },
464 { LINE6_DEVICE(0x5044), .driver_info = LINE6_PODXT },
465 { LINE6_IF_NUM(0x4650, 0), .driver_info = LINE6_PODXTLIVE_POD },
466 { LINE6_DEVICE(0x5050), .driver_info = LINE6_PODXTPRO },
467 {}
468};
469
470MODULE_DEVICE_TABLE(usb, pod_id_table);
471
472static const struct line6_properties pod_properties_table[] = {
473 [LINE6_BASSPODXT] = {
474 .id = "BassPODxt",
475 .name = "BassPODxt",
476 .capabilities = LINE6_CAP_CONTROL
477 | LINE6_CAP_CONTROL_MIDI
478 | LINE6_CAP_PCM
479 | LINE6_CAP_HWMON,
480 .altsetting = 5,
481 .ep_ctrl_r = 0x84,
482 .ep_ctrl_w = 0x03,
483 .ep_audio_r = 0x82,
484 .ep_audio_w = 0x01,
485 },
486 [LINE6_BASSPODXTLIVE] = {
487 .id = "BassPODxtLive",
488 .name = "BassPODxt Live",
489 .capabilities = LINE6_CAP_CONTROL
490 | LINE6_CAP_CONTROL_MIDI
491 | LINE6_CAP_PCM
492 | LINE6_CAP_HWMON,
493 .altsetting = 1,
494 .ep_ctrl_r = 0x84,
495 .ep_ctrl_w = 0x03,
496 .ep_audio_r = 0x82,
497 .ep_audio_w = 0x01,
498 },
499 [LINE6_BASSPODXTPRO] = {
500 .id = "BassPODxtPro",
501 .name = "BassPODxt Pro",
502 .capabilities = LINE6_CAP_CONTROL
503 | LINE6_CAP_CONTROL_MIDI
504 | LINE6_CAP_PCM
505 | LINE6_CAP_HWMON,
506 .altsetting = 5,
507 .ep_ctrl_r = 0x84,
508 .ep_ctrl_w = 0x03,
509 .ep_audio_r = 0x82,
510 .ep_audio_w = 0x01,
511 },
512 [LINE6_POCKETPOD] = {
513 .id = "PocketPOD",
514 .name = "Pocket POD",
515 .capabilities = LINE6_CAP_CONTROL
516 | LINE6_CAP_CONTROL_MIDI,
517 .altsetting = 0,
518 .ep_ctrl_r = 0x82,
519 .ep_ctrl_w = 0x02,
520
521 },
522 [LINE6_PODXT] = {
523 .id = "PODxt",
524 .name = "PODxt",
525 .capabilities = LINE6_CAP_CONTROL
526 | LINE6_CAP_CONTROL_MIDI
527 | LINE6_CAP_PCM
528 | LINE6_CAP_HWMON,
529 .altsetting = 5,
530 .ep_ctrl_r = 0x84,
531 .ep_ctrl_w = 0x03,
532 .ep_audio_r = 0x82,
533 .ep_audio_w = 0x01,
534 },
535 [LINE6_PODXTLIVE_POD] = {
536 .id = "PODxtLive",
537 .name = "PODxt Live",
538 .capabilities = LINE6_CAP_CONTROL
539 | LINE6_CAP_CONTROL_MIDI
540 | LINE6_CAP_PCM
541 | LINE6_CAP_HWMON,
542 .altsetting = 1,
543 .ep_ctrl_r = 0x84,
544 .ep_ctrl_w = 0x03,
545 .ep_audio_r = 0x82,
546 .ep_audio_w = 0x01,
547 },
548 [LINE6_PODXTPRO] = {
549 .id = "PODxtPro",
550 .name = "PODxt Pro",
551 .capabilities = LINE6_CAP_CONTROL
552 | LINE6_CAP_CONTROL_MIDI
553 | LINE6_CAP_PCM
554 | LINE6_CAP_HWMON,
555 .altsetting = 5,
556 .ep_ctrl_r = 0x84,
557 .ep_ctrl_w = 0x03,
558 .ep_audio_r = 0x82,
559 .ep_audio_w = 0x01,
560 },
561};
562
563
564
565
566static int pod_probe(struct usb_interface *interface,
567 const struct usb_device_id *id)
568{
569 return line6_probe(interface, id, "Line6-POD",
570 &pod_properties_table[id->driver_info],
571 pod_init, sizeof(struct usb_line6_pod));
572}
573
574static struct usb_driver pod_driver = {
575 .name = KBUILD_MODNAME,
576 .probe = pod_probe,
577 .disconnect = line6_disconnect,
578#ifdef CONFIG_PM
579 .suspend = line6_suspend,
580 .resume = line6_resume,
581 .reset_resume = line6_resume,
582#endif
583 .id_table = pod_id_table,
584};
585
586module_usb_driver(pod_driver);
587
588MODULE_DESCRIPTION("Line 6 POD USB driver");
589MODULE_LICENSE("GPL");
590