This source file includes following definitions.
- pod_alloc_sysex_buffer
- line6_pod_process_message
- pod_set_system_param_int
- serial_number_show
- firmware_version_show
- device_id_show
- pod_startup
- snd_pod_control_monitor_info
- snd_pod_control_monitor_get
- snd_pod_control_monitor_put
- pod_init
- pod_probe
1
2
3
4
5
6
7
8 #include <linux/slab.h>
9 #include <linux/wait.h>
10 #include <linux/interrupt.h>
11 #include <linux/module.h>
12 #include <linux/usb.h>
13
14 #include <sound/core.h>
15 #include <sound/control.h>
16
17 #include "capture.h"
18 #include "driver.h"
19 #include "playback.h"
20
21
22
23
24 #define POD_NAME_OFFSET 0
25 #define POD_NAME_LENGTH 16
26
27
28
29
30 #define POD_CONTROL_SIZE 0x80
31 #define POD_BUFSIZE_DUMPREQ 7
32 #define POD_STARTUP_DELAY 1000
33
34
35
36
37 enum {
38 POD_STARTUP_VERSIONREQ,
39 POD_STARTUP_SETUP,
40 POD_STARTUP_DONE,
41 };
42
43 enum {
44 LINE6_BASSPODXT,
45 LINE6_BASSPODXTLIVE,
46 LINE6_BASSPODXTPRO,
47 LINE6_POCKETPOD,
48 LINE6_PODXT,
49 LINE6_PODXTLIVE_POD,
50 LINE6_PODXTPRO,
51 };
52
53 struct usb_line6_pod {
54
55 struct usb_line6 line6;
56
57
58 int monitor_level;
59
60
61 int startup_progress;
62
63
64 u32 serial_number;
65
66
67 int firmware_version;
68
69
70 int device_id;
71 };
72
73 #define line6_to_pod(x) container_of(x, struct usb_line6_pod, line6)
74
75 #define POD_SYSEX_CODE 3
76
77
78
79 enum {
80 POD_SYSEX_SAVE = 0x24,
81 POD_SYSEX_SYSTEM = 0x56,
82 POD_SYSEX_SYSTEMREQ = 0x57,
83
84 POD_SYSEX_STORE = 0x71,
85 POD_SYSEX_FINISH = 0x72,
86 POD_SYSEX_DUMPMEM = 0x73,
87 POD_SYSEX_DUMP = 0x74,
88 POD_SYSEX_DUMPREQ = 0x75
89
90
91
92 };
93
94 enum {
95 POD_MONITOR_LEVEL = 0x04,
96 POD_SYSTEM_INVALID = 0x10000
97 };
98
99
100
101 enum {
102 POD_DUMP_MEMORY = 2
103 };
104
105 enum {
106 POD_BUSY_READ,
107 POD_BUSY_WRITE,
108 POD_CHANNEL_DIRTY,
109 POD_SAVE_PRESSED,
110 POD_BUSY_MIDISEND
111 };
112
113 static struct snd_ratden pod_ratden = {
114 .num_min = 78125,
115 .num_max = 78125,
116 .num_step = 1,
117 .den = 2
118 };
119
120 static struct line6_pcm_properties pod_pcm_properties = {
121 .playback_hw = {
122 .info = (SNDRV_PCM_INFO_MMAP |
123 SNDRV_PCM_INFO_INTERLEAVED |
124 SNDRV_PCM_INFO_BLOCK_TRANSFER |
125 SNDRV_PCM_INFO_MMAP_VALID |
126 SNDRV_PCM_INFO_PAUSE |
127 SNDRV_PCM_INFO_SYNC_START),
128 .formats = SNDRV_PCM_FMTBIT_S24_3LE,
129 .rates = SNDRV_PCM_RATE_KNOT,
130 .rate_min = 39062,
131 .rate_max = 39063,
132 .channels_min = 2,
133 .channels_max = 2,
134 .buffer_bytes_max = 60000,
135 .period_bytes_min = 64,
136 .period_bytes_max = 8192,
137 .periods_min = 1,
138 .periods_max = 1024},
139 .capture_hw = {
140 .info = (SNDRV_PCM_INFO_MMAP |
141 SNDRV_PCM_INFO_INTERLEAVED |
142 SNDRV_PCM_INFO_BLOCK_TRANSFER |
143 SNDRV_PCM_INFO_MMAP_VALID |
144 SNDRV_PCM_INFO_SYNC_START),
145 .formats = SNDRV_PCM_FMTBIT_S24_3LE,
146 .rates = SNDRV_PCM_RATE_KNOT,
147 .rate_min = 39062,
148 .rate_max = 39063,
149 .channels_min = 2,
150 .channels_max = 2,
151 .buffer_bytes_max = 60000,
152 .period_bytes_min = 64,
153 .period_bytes_max = 8192,
154 .periods_min = 1,
155 .periods_max = 1024},
156 .rates = {
157 .nrats = 1,
158 .rats = &pod_ratden},
159 .bytes_per_channel = 3
160 };
161
162 static const char pod_version_header[] = {
163 0xf2, 0x7e, 0x7f, 0x06, 0x02
164 };
165
166 static char *pod_alloc_sysex_buffer(struct usb_line6_pod *pod, int code,
167 int size)
168 {
169 return line6_alloc_sysex_buffer(&pod->line6, POD_SYSEX_CODE, code,
170 size);
171 }
172
173
174
175
176 static void line6_pod_process_message(struct usb_line6 *line6)
177 {
178 struct usb_line6_pod *pod = line6_to_pod(line6);
179 const unsigned char *buf = pod->line6.buffer_message;
180
181 if (memcmp(buf, pod_version_header, sizeof(pod_version_header)) == 0) {
182 pod->firmware_version = buf[13] * 100 + buf[14] * 10 + buf[15];
183 pod->device_id = ((int)buf[8] << 16) | ((int)buf[9] << 8) |
184 (int) buf[10];
185 if (pod->startup_progress == POD_STARTUP_VERSIONREQ) {
186 pod->startup_progress = POD_STARTUP_SETUP;
187 schedule_delayed_work(&line6->startup_work, 0);
188 }
189 return;
190 }
191
192
193 if (buf[0] != (LINE6_SYSEX_BEGIN | LINE6_CHANNEL_DEVICE) &&
194 buf[0] != (LINE6_SYSEX_BEGIN | LINE6_CHANNEL_UNKNOWN)) {
195 return;
196 }
197 if (memcmp(buf + 1, line6_midi_id, sizeof(line6_midi_id)) != 0)
198 return;
199
200 if (buf[5] == POD_SYSEX_SYSTEM && buf[6] == POD_MONITOR_LEVEL) {
201 short value = ((int)buf[7] << 12) | ((int)buf[8] << 8) |
202 ((int)buf[9] << 4) | (int)buf[10];
203 pod->monitor_level = value;
204 }
205 }
206
207
208
209
210 static int pod_set_system_param_int(struct usb_line6_pod *pod, int value,
211 int code)
212 {
213 char *sysex;
214 static const int size = 5;
215
216 sysex = pod_alloc_sysex_buffer(pod, POD_SYSEX_SYSTEM, size);
217 if (!sysex)
218 return -ENOMEM;
219 sysex[SYSEX_DATA_OFS] = code;
220 sysex[SYSEX_DATA_OFS + 1] = (value >> 12) & 0x0f;
221 sysex[SYSEX_DATA_OFS + 2] = (value >> 8) & 0x0f;
222 sysex[SYSEX_DATA_OFS + 3] = (value >> 4) & 0x0f;
223 sysex[SYSEX_DATA_OFS + 4] = (value) & 0x0f;
224 line6_send_sysex_message(&pod->line6, sysex, size);
225 kfree(sysex);
226 return 0;
227 }
228
229
230
231
232 static ssize_t serial_number_show(struct device *dev,
233 struct device_attribute *attr, char *buf)
234 {
235 struct snd_card *card = dev_to_snd_card(dev);
236 struct usb_line6_pod *pod = card->private_data;
237
238 return sprintf(buf, "%u\n", pod->serial_number);
239 }
240
241
242
243
244 static ssize_t firmware_version_show(struct device *dev,
245 struct device_attribute *attr, char *buf)
246 {
247 struct snd_card *card = dev_to_snd_card(dev);
248 struct usb_line6_pod *pod = card->private_data;
249
250 return sprintf(buf, "%d.%02d\n", pod->firmware_version / 100,
251 pod->firmware_version % 100);
252 }
253
254
255
256
257 static ssize_t device_id_show(struct device *dev,
258 struct device_attribute *attr, char *buf)
259 {
260 struct snd_card *card = dev_to_snd_card(dev);
261 struct usb_line6_pod *pod = card->private_data;
262
263 return sprintf(buf, "%d\n", pod->device_id);
264 }
265
266
267
268
269
270
271
272
273 static void pod_startup(struct usb_line6 *line6)
274 {
275 struct usb_line6_pod *pod = line6_to_pod(line6);
276
277 switch (pod->startup_progress) {
278 case POD_STARTUP_VERSIONREQ:
279
280 line6_version_request_async(line6);
281 break;
282 case POD_STARTUP_SETUP:
283
284 line6_read_serial_number(&pod->line6, &pod->serial_number);
285
286
287 if (snd_card_register(line6->card))
288 dev_err(line6->ifcdev, "Failed to register POD card.\n");
289 pod->startup_progress = POD_STARTUP_DONE;
290 break;
291 default:
292 break;
293 }
294 }
295
296
297 static DEVICE_ATTR_RO(device_id);
298 static DEVICE_ATTR_RO(firmware_version);
299 static DEVICE_ATTR_RO(serial_number);
300
301 static struct attribute *pod_dev_attrs[] = {
302 &dev_attr_device_id.attr,
303 &dev_attr_firmware_version.attr,
304 &dev_attr_serial_number.attr,
305 NULL
306 };
307
308 static const struct attribute_group pod_dev_attr_group = {
309 .name = "pod",
310 .attrs = pod_dev_attrs,
311 };
312
313
314 static int snd_pod_control_monitor_info(struct snd_kcontrol *kcontrol,
315 struct snd_ctl_elem_info *uinfo)
316 {
317 uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
318 uinfo->count = 1;
319 uinfo->value.integer.min = 0;
320 uinfo->value.integer.max = 65535;
321 return 0;
322 }
323
324
325 static int snd_pod_control_monitor_get(struct snd_kcontrol *kcontrol,
326 struct snd_ctl_elem_value *ucontrol)
327 {
328 struct snd_line6_pcm *line6pcm = snd_kcontrol_chip(kcontrol);
329 struct usb_line6_pod *pod = line6_to_pod(line6pcm->line6);
330
331 ucontrol->value.integer.value[0] = pod->monitor_level;
332 return 0;
333 }
334
335
336 static int snd_pod_control_monitor_put(struct snd_kcontrol *kcontrol,
337 struct snd_ctl_elem_value *ucontrol)
338 {
339 struct snd_line6_pcm *line6pcm = snd_kcontrol_chip(kcontrol);
340 struct usb_line6_pod *pod = line6_to_pod(line6pcm->line6);
341
342 if (ucontrol->value.integer.value[0] == pod->monitor_level)
343 return 0;
344
345 pod->monitor_level = ucontrol->value.integer.value[0];
346 pod_set_system_param_int(pod, ucontrol->value.integer.value[0],
347 POD_MONITOR_LEVEL);
348 return 1;
349 }
350
351
352 static const struct snd_kcontrol_new pod_control_monitor = {
353 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
354 .name = "Monitor Playback Volume",
355 .index = 0,
356 .access = SNDRV_CTL_ELEM_ACCESS_READWRITE,
357 .info = snd_pod_control_monitor_info,
358 .get = snd_pod_control_monitor_get,
359 .put = snd_pod_control_monitor_put
360 };
361
362
363
364
365 static int pod_init(struct usb_line6 *line6,
366 const struct usb_device_id *id)
367 {
368 int err;
369 struct usb_line6_pod *pod = line6_to_pod(line6);
370
371 line6->process_message = line6_pod_process_message;
372 line6->startup = pod_startup;
373
374
375 err = snd_card_add_dev_attr(line6->card, &pod_dev_attr_group);
376 if (err < 0)
377 return err;
378
379
380 err = line6_init_midi(line6);
381 if (err < 0)
382 return err;
383
384
385 err = line6_init_pcm(line6, &pod_pcm_properties);
386 if (err < 0)
387 return err;
388
389
390 err = snd_ctl_add(line6->card,
391 snd_ctl_new1(&pod_control_monitor, line6->line6pcm));
392 if (err < 0)
393 return err;
394
395
396
397
398
399
400
401 if (pod->line6.properties->capabilities & LINE6_CAP_CONTROL) {
402 pod->monitor_level = POD_SYSTEM_INVALID;
403
404
405 schedule_delayed_work(&line6->startup_work,
406 msecs_to_jiffies(POD_STARTUP_DELAY));
407 }
408
409 return 0;
410 }
411
412 #define LINE6_DEVICE(prod) USB_DEVICE(0x0e41, prod)
413 #define LINE6_IF_NUM(prod, n) USB_DEVICE_INTERFACE_NUMBER(0x0e41, prod, n)
414
415
416 static const struct usb_device_id pod_id_table[] = {
417 { LINE6_DEVICE(0x4250), .driver_info = LINE6_BASSPODXT },
418 { LINE6_DEVICE(0x4642), .driver_info = LINE6_BASSPODXTLIVE },
419 { LINE6_DEVICE(0x4252), .driver_info = LINE6_BASSPODXTPRO },
420 { LINE6_IF_NUM(0x5051, 1), .driver_info = LINE6_POCKETPOD },
421 { LINE6_DEVICE(0x5044), .driver_info = LINE6_PODXT },
422 { LINE6_IF_NUM(0x4650, 0), .driver_info = LINE6_PODXTLIVE_POD },
423 { LINE6_DEVICE(0x5050), .driver_info = LINE6_PODXTPRO },
424 {}
425 };
426
427 MODULE_DEVICE_TABLE(usb, pod_id_table);
428
429 static const struct line6_properties pod_properties_table[] = {
430 [LINE6_BASSPODXT] = {
431 .id = "BassPODxt",
432 .name = "BassPODxt",
433 .capabilities = LINE6_CAP_CONTROL
434 | LINE6_CAP_CONTROL_MIDI
435 | LINE6_CAP_PCM
436 | LINE6_CAP_HWMON,
437 .altsetting = 5,
438 .ep_ctrl_r = 0x84,
439 .ep_ctrl_w = 0x03,
440 .ep_audio_r = 0x82,
441 .ep_audio_w = 0x01,
442 },
443 [LINE6_BASSPODXTLIVE] = {
444 .id = "BassPODxtLive",
445 .name = "BassPODxt Live",
446 .capabilities = LINE6_CAP_CONTROL
447 | LINE6_CAP_CONTROL_MIDI
448 | LINE6_CAP_PCM
449 | LINE6_CAP_HWMON,
450 .altsetting = 1,
451 .ep_ctrl_r = 0x84,
452 .ep_ctrl_w = 0x03,
453 .ep_audio_r = 0x82,
454 .ep_audio_w = 0x01,
455 },
456 [LINE6_BASSPODXTPRO] = {
457 .id = "BassPODxtPro",
458 .name = "BassPODxt Pro",
459 .capabilities = LINE6_CAP_CONTROL
460 | LINE6_CAP_CONTROL_MIDI
461 | LINE6_CAP_PCM
462 | LINE6_CAP_HWMON,
463 .altsetting = 5,
464 .ep_ctrl_r = 0x84,
465 .ep_ctrl_w = 0x03,
466 .ep_audio_r = 0x82,
467 .ep_audio_w = 0x01,
468 },
469 [LINE6_POCKETPOD] = {
470 .id = "PocketPOD",
471 .name = "Pocket POD",
472 .capabilities = LINE6_CAP_CONTROL
473 | LINE6_CAP_CONTROL_MIDI,
474 .altsetting = 0,
475 .ep_ctrl_r = 0x82,
476 .ep_ctrl_w = 0x02,
477
478 },
479 [LINE6_PODXT] = {
480 .id = "PODxt",
481 .name = "PODxt",
482 .capabilities = LINE6_CAP_CONTROL
483 | LINE6_CAP_CONTROL_MIDI
484 | LINE6_CAP_PCM
485 | LINE6_CAP_HWMON,
486 .altsetting = 5,
487 .ep_ctrl_r = 0x84,
488 .ep_ctrl_w = 0x03,
489 .ep_audio_r = 0x82,
490 .ep_audio_w = 0x01,
491 },
492 [LINE6_PODXTLIVE_POD] = {
493 .id = "PODxtLive",
494 .name = "PODxt Live",
495 .capabilities = LINE6_CAP_CONTROL
496 | LINE6_CAP_CONTROL_MIDI
497 | LINE6_CAP_PCM
498 | LINE6_CAP_HWMON,
499 .altsetting = 1,
500 .ep_ctrl_r = 0x84,
501 .ep_ctrl_w = 0x03,
502 .ep_audio_r = 0x82,
503 .ep_audio_w = 0x01,
504 },
505 [LINE6_PODXTPRO] = {
506 .id = "PODxtPro",
507 .name = "PODxt Pro",
508 .capabilities = LINE6_CAP_CONTROL
509 | LINE6_CAP_CONTROL_MIDI
510 | LINE6_CAP_PCM
511 | LINE6_CAP_HWMON,
512 .altsetting = 5,
513 .ep_ctrl_r = 0x84,
514 .ep_ctrl_w = 0x03,
515 .ep_audio_r = 0x82,
516 .ep_audio_w = 0x01,
517 },
518 };
519
520
521
522
523 static int pod_probe(struct usb_interface *interface,
524 const struct usb_device_id *id)
525 {
526 return line6_probe(interface, id, "Line6-POD",
527 &pod_properties_table[id->driver_info],
528 pod_init, sizeof(struct usb_line6_pod));
529 }
530
531 static struct usb_driver pod_driver = {
532 .name = KBUILD_MODNAME,
533 .probe = pod_probe,
534 .disconnect = line6_disconnect,
535 #ifdef CONFIG_PM
536 .suspend = line6_suspend,
537 .resume = line6_resume,
538 .reset_resume = line6_resume,
539 #endif
540 .id_table = pod_id_table,
541 };
542
543 module_usb_driver(pod_driver);
544
545 MODULE_DESCRIPTION("Line 6 POD USB driver");
546 MODULE_LICENSE("GPL");