2 * Line 6 Linux USB driver
4 * Copyright (C) 2004-2010 Markus Grabner (grabner@icg.tugraz.at)
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.
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>
18 #include <sound/core.h>
19 #include <sound/control.h>
27 Locate name in binary program dump
29 #define POD_NAME_OFFSET 0
30 #define POD_NAME_LENGTH 16
35 #define POD_CONTROL_SIZE 0x80
36 #define POD_BUFSIZE_DUMPREQ 7
37 #define POD_STARTUP_DELAY 1000
40 Stages of POD startup procedure
44 POD_STARTUP_VERSIONREQ,
45 POD_STARTUP_WORKQUEUE,
47 POD_STARTUP_LAST = POD_STARTUP_SETUP - 1
60 struct usb_line6_pod {
62 Generic Line 6 USB data.
64 struct usb_line6 line6;
67 Instrument monitor level.
72 Timer for device initializaton.
74 struct timer_list startup_timer;
77 Work handler for device initializaton.
79 struct work_struct startup_work;
82 Current progress in startup procedure.
87 Serial number of device.
92 Firmware version (x 100).
102 #define POD_SYSEX_CODE 3
103 #define POD_BYTES_PER_FRAME 6 /* 24bit audio (stereo) */
108 POD_SYSEX_SAVE = 0x24,
109 POD_SYSEX_SYSTEM = 0x56,
110 POD_SYSEX_SYSTEMREQ = 0x57,
111 /* POD_SYSEX_UPDATE = 0x6c, */ /* software update! */
112 POD_SYSEX_STORE = 0x71,
113 POD_SYSEX_FINISH = 0x72,
114 POD_SYSEX_DUMPMEM = 0x73,
115 POD_SYSEX_DUMP = 0x74,
116 POD_SYSEX_DUMPREQ = 0x75
118 /* dumps entire internal memory of PODxt Pro */
119 /* POD_SYSEX_DUMPMEM2 = 0x76 */
123 POD_MONITOR_LEVEL = 0x04,
124 POD_SYSTEM_INVALID = 0x10000
141 static struct snd_ratden pod_ratden = {
148 static struct line6_pcm_properties pod_pcm_properties = {
149 .snd_line6_playback_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_PAUSE |
155 SNDRV_PCM_INFO_SYNC_START),
156 .formats = SNDRV_PCM_FMTBIT_S24_3LE,
157 .rates = SNDRV_PCM_RATE_KNOT,
162 .buffer_bytes_max = 60000,
163 .period_bytes_min = 64,
164 .period_bytes_max = 8192,
166 .periods_max = 1024},
167 .snd_line6_capture_hw = {
168 .info = (SNDRV_PCM_INFO_MMAP |
169 SNDRV_PCM_INFO_INTERLEAVED |
170 SNDRV_PCM_INFO_BLOCK_TRANSFER |
171 SNDRV_PCM_INFO_MMAP_VALID |
172 SNDRV_PCM_INFO_SYNC_START),
173 .formats = SNDRV_PCM_FMTBIT_S24_3LE,
174 .rates = SNDRV_PCM_RATE_KNOT,
179 .buffer_bytes_max = 60000,
180 .period_bytes_min = 64,
181 .period_bytes_max = 8192,
183 .periods_max = 1024},
186 .rats = &pod_ratden},
187 .bytes_per_frame = POD_BYTES_PER_FRAME
190 static const char pod_version_header[] = {
191 0xf2, 0x7e, 0x7f, 0x06, 0x02
194 /* forward declarations: */
195 static void pod_startup2(unsigned long data);
196 static void pod_startup3(struct usb_line6_pod *pod);
198 static char *pod_alloc_sysex_buffer(struct usb_line6_pod *pod, int code,
201 return line6_alloc_sysex_buffer(&pod->line6, POD_SYSEX_CODE, code,
206 Process a completely received message.
208 static void line6_pod_process_message(struct usb_line6 *line6)
210 struct usb_line6_pod *pod = (struct usb_line6_pod *) line6;
211 const unsigned char *buf = pod->line6.buffer_message;
213 if (memcmp(buf, pod_version_header, sizeof(pod_version_header)) == 0) {
214 pod->firmware_version = buf[13] * 100 + buf[14] * 10 + buf[15];
215 pod->device_id = ((int)buf[8] << 16) | ((int)buf[9] << 8) |
221 /* Only look for sysex messages from this device */
222 if (buf[0] != (LINE6_SYSEX_BEGIN | LINE6_CHANNEL_DEVICE) &&
223 buf[0] != (LINE6_SYSEX_BEGIN | LINE6_CHANNEL_UNKNOWN)) {
226 if (memcmp(buf + 1, line6_midi_id, sizeof(line6_midi_id)) != 0)
229 if (buf[5] == POD_SYSEX_SYSTEM && buf[6] == POD_MONITOR_LEVEL) {
230 short value = ((int)buf[7] << 12) | ((int)buf[8] << 8) |
231 ((int)buf[9] << 4) | (int)buf[10];
232 pod->monitor_level = value;
237 Send system parameter (from integer).
239 static int pod_set_system_param_int(struct usb_line6_pod *pod, int value,
243 static const int size = 5;
245 sysex = pod_alloc_sysex_buffer(pod, POD_SYSEX_SYSTEM, size);
248 sysex[SYSEX_DATA_OFS] = code;
249 sysex[SYSEX_DATA_OFS + 1] = (value >> 12) & 0x0f;
250 sysex[SYSEX_DATA_OFS + 2] = (value >> 8) & 0x0f;
251 sysex[SYSEX_DATA_OFS + 3] = (value >> 4) & 0x0f;
252 sysex[SYSEX_DATA_OFS + 4] = (value) & 0x0f;
253 line6_send_sysex_message(&pod->line6, sysex, size);
259 "read" request on "serial_number" special file.
261 static ssize_t serial_number_show(struct device *dev,
262 struct device_attribute *attr, char *buf)
264 struct usb_interface *interface = to_usb_interface(dev);
265 struct usb_line6_pod *pod = usb_get_intfdata(interface);
267 return sprintf(buf, "%d\n", pod->serial_number);
271 "read" request on "firmware_version" special file.
273 static ssize_t firmware_version_show(struct device *dev,
274 struct device_attribute *attr, char *buf)
276 struct usb_interface *interface = to_usb_interface(dev);
277 struct usb_line6_pod *pod = usb_get_intfdata(interface);
279 return sprintf(buf, "%d.%02d\n", pod->firmware_version / 100,
280 pod->firmware_version % 100);
284 "read" request on "device_id" special file.
286 static ssize_t device_id_show(struct device *dev,
287 struct device_attribute *attr, char *buf)
289 struct usb_interface *interface = to_usb_interface(dev);
290 struct usb_line6_pod *pod = usb_get_intfdata(interface);
292 return sprintf(buf, "%d\n", pod->device_id);
296 POD startup procedure.
297 This is a sequence of functions with special requirements (e.g., must
298 not run immediately after initialization, must not run in interrupt
299 context). After the last one has finished, the device is ready to use.
302 static void pod_startup1(struct usb_line6_pod *pod)
304 CHECK_STARTUP_PROGRESS(pod->startup_progress, POD_STARTUP_INIT);
306 /* delay startup procedure: */
307 line6_start_timer(&pod->startup_timer, POD_STARTUP_DELAY, pod_startup2,
311 static void pod_startup2(unsigned long data)
313 struct usb_line6_pod *pod = (struct usb_line6_pod *)data;
314 struct usb_line6 *line6 = &pod->line6;
316 CHECK_STARTUP_PROGRESS(pod->startup_progress, POD_STARTUP_VERSIONREQ);
318 /* request firmware version: */
319 line6_version_request_async(line6);
322 static void pod_startup3(struct usb_line6_pod *pod)
324 CHECK_STARTUP_PROGRESS(pod->startup_progress, POD_STARTUP_WORKQUEUE);
326 /* schedule work for global work queue: */
327 schedule_work(&pod->startup_work);
330 static void pod_startup4(struct work_struct *work)
332 struct usb_line6_pod *pod =
333 container_of(work, struct usb_line6_pod, startup_work);
334 struct usb_line6 *line6 = &pod->line6;
336 CHECK_STARTUP_PROGRESS(pod->startup_progress, POD_STARTUP_SETUP);
339 line6_read_serial_number(&pod->line6, &pod->serial_number);
341 /* ALSA audio interface: */
342 snd_card_register(line6->card);
345 /* POD special files: */
346 static DEVICE_ATTR_RO(device_id);
347 static DEVICE_ATTR_RO(firmware_version);
348 static DEVICE_ATTR_RO(serial_number);
350 /* control info callback */
351 static int snd_pod_control_monitor_info(struct snd_kcontrol *kcontrol,
352 struct snd_ctl_elem_info *uinfo)
354 uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
356 uinfo->value.integer.min = 0;
357 uinfo->value.integer.max = 65535;
361 /* control get callback */
362 static int snd_pod_control_monitor_get(struct snd_kcontrol *kcontrol,
363 struct snd_ctl_elem_value *ucontrol)
365 struct snd_line6_pcm *line6pcm = snd_kcontrol_chip(kcontrol);
366 struct usb_line6_pod *pod = (struct usb_line6_pod *)line6pcm->line6;
368 ucontrol->value.integer.value[0] = pod->monitor_level;
372 /* control put callback */
373 static int snd_pod_control_monitor_put(struct snd_kcontrol *kcontrol,
374 struct snd_ctl_elem_value *ucontrol)
376 struct snd_line6_pcm *line6pcm = snd_kcontrol_chip(kcontrol);
377 struct usb_line6_pod *pod = (struct usb_line6_pod *)line6pcm->line6;
379 if (ucontrol->value.integer.value[0] == pod->monitor_level)
382 pod->monitor_level = ucontrol->value.integer.value[0];
383 pod_set_system_param_int(pod, ucontrol->value.integer.value[0],
388 /* control definition */
389 static struct snd_kcontrol_new pod_control_monitor = {
390 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
391 .name = "Monitor Playback Volume",
393 .access = SNDRV_CTL_ELEM_ACCESS_READWRITE,
394 .info = snd_pod_control_monitor_info,
395 .get = snd_pod_control_monitor_get,
396 .put = snd_pod_control_monitor_put
400 POD device disconnected.
402 static void line6_pod_disconnect(struct usb_line6 *line6)
404 struct usb_line6_pod *pod = (struct usb_line6_pod *)line6;
405 struct device *dev = line6->ifcdev;
407 /* remove sysfs entries: */
408 device_remove_file(dev, &dev_attr_device_id);
409 device_remove_file(dev, &dev_attr_firmware_version);
410 device_remove_file(dev, &dev_attr_serial_number);
412 del_timer_sync(&pod->startup_timer);
413 cancel_work_sync(&pod->startup_work);
417 Create sysfs entries.
419 static int pod_create_files2(struct device *dev)
423 err = device_create_file(dev, &dev_attr_device_id);
426 err = device_create_file(dev, &dev_attr_firmware_version);
429 err = device_create_file(dev, &dev_attr_serial_number);
436 Try to init POD device.
438 static int pod_init(struct usb_line6 *line6,
439 const struct usb_device_id *id)
442 struct usb_line6_pod *pod = (struct usb_line6_pod *) line6;
444 line6->process_message = line6_pod_process_message;
445 line6->disconnect = line6_pod_disconnect;
447 init_timer(&pod->startup_timer);
448 INIT_WORK(&pod->startup_work, pod_startup4);
450 /* create sysfs entries: */
451 err = pod_create_files2(line6->ifcdev);
455 /* initialize MIDI subsystem: */
456 err = line6_init_midi(line6);
460 /* initialize PCM subsystem: */
461 err = line6_init_pcm(line6, &pod_pcm_properties);
465 /* register monitor control: */
466 err = snd_ctl_add(line6->card,
467 snd_ctl_new1(&pod_control_monitor, line6->line6pcm));
472 When the sound card is registered at this point, the PODxt Live
473 displays "Invalid Code Error 07", so we do it later in the event
477 if (pod->line6.properties->capabilities & LINE6_CAP_CONTROL) {
478 pod->monitor_level = POD_SYSTEM_INVALID;
480 /* initiate startup procedure: */
487 #define LINE6_DEVICE(prod) USB_DEVICE(0x0e41, prod)
488 #define LINE6_IF_NUM(prod, n) USB_DEVICE_INTERFACE_NUMBER(0x0e41, prod, n)
490 /* table of devices that work with this driver */
491 static const struct usb_device_id pod_id_table[] = {
492 { LINE6_DEVICE(0x4250), .driver_info = LINE6_BASSPODXT },
493 { LINE6_DEVICE(0x4642), .driver_info = LINE6_BASSPODXTLIVE },
494 { LINE6_DEVICE(0x4252), .driver_info = LINE6_BASSPODXTPRO },
495 { LINE6_IF_NUM(0x5051, 1), .driver_info = LINE6_POCKETPOD },
496 { LINE6_DEVICE(0x5044), .driver_info = LINE6_PODXT },
497 { LINE6_IF_NUM(0x4650, 0), .driver_info = LINE6_PODXTLIVE_POD },
498 { LINE6_DEVICE(0x5050), .driver_info = LINE6_PODXTPRO },
502 MODULE_DEVICE_TABLE(usb, pod_id_table);
504 static const struct line6_properties pod_properties_table[] = {
505 [LINE6_BASSPODXT] = {
508 .capabilities = LINE6_CAP_CONTROL
517 [LINE6_BASSPODXTLIVE] = {
518 .id = "BassPODxtLive",
519 .name = "BassPODxt Live",
520 .capabilities = LINE6_CAP_CONTROL
529 [LINE6_BASSPODXTPRO] = {
530 .id = "BassPODxtPro",
531 .name = "BassPODxt Pro",
532 .capabilities = LINE6_CAP_CONTROL
541 [LINE6_POCKETPOD] = {
543 .name = "Pocket POD",
544 .capabilities = LINE6_CAP_CONTROL,
548 /* no audio channel */
553 .capabilities = LINE6_CAP_CONTROL
562 [LINE6_PODXTLIVE_POD] = {
564 .name = "PODxt Live",
565 .capabilities = LINE6_CAP_CONTROL
577 .capabilities = LINE6_CAP_CONTROL
591 static int pod_probe(struct usb_interface *interface,
592 const struct usb_device_id *id)
594 struct usb_line6_pod *pod;
596 pod = kzalloc(sizeof(*pod), GFP_KERNEL);
599 return line6_probe(interface, id, &pod->line6,
600 &pod_properties_table[id->driver_info],
604 static struct usb_driver pod_driver = {
605 .name = KBUILD_MODNAME,
607 .disconnect = line6_disconnect,
609 .suspend = line6_suspend,
610 .resume = line6_resume,
611 .reset_resume = line6_resume,
613 .id_table = pod_id_table,
616 module_usb_driver(pod_driver);
618 MODULE_DESCRIPTION("Line 6 POD USB driver");
619 MODULE_LICENSE("GPL");