2 * Line6 Linux USB driver - 0.9.1beta
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 <sound/control.h>
22 #define POD_SYSEX_CODE 3
23 #define POD_BYTES_PER_FRAME 6 /* 24bit audio (stereo) */
28 POD_SYSEX_SAVE = 0x24,
29 POD_SYSEX_SYSTEM = 0x56,
30 POD_SYSEX_SYSTEMREQ = 0x57,
31 /* POD_SYSEX_UPDATE = 0x6c, */ /* software update! */
32 POD_SYSEX_STORE = 0x71,
33 POD_SYSEX_FINISH = 0x72,
34 POD_SYSEX_DUMPMEM = 0x73,
35 POD_SYSEX_DUMP = 0x74,
36 POD_SYSEX_DUMPREQ = 0x75
37 /* POD_SYSEX_DUMPMEM2 = 0x76 */ /* dumps entire internal memory of PODxt Pro */
41 POD_monitor_level = 0x04,
42 POD_system_invalid = 0x10000
59 static struct snd_ratden pod_ratden = {
66 static struct line6_pcm_properties pod_pcm_properties = {
67 .snd_line6_playback_hw = {
68 .info = (SNDRV_PCM_INFO_MMAP |
69 SNDRV_PCM_INFO_INTERLEAVED |
70 SNDRV_PCM_INFO_BLOCK_TRANSFER |
71 SNDRV_PCM_INFO_MMAP_VALID |
72 SNDRV_PCM_INFO_PAUSE |
74 SNDRV_PCM_INFO_RESUME |
76 SNDRV_PCM_INFO_SYNC_START),
77 .formats = SNDRV_PCM_FMTBIT_S24_3LE,
78 .rates = SNDRV_PCM_RATE_KNOT,
83 .buffer_bytes_max = 60000,
84 .period_bytes_min = 64,
85 .period_bytes_max = 8192,
88 .snd_line6_capture_hw = {
89 .info = (SNDRV_PCM_INFO_MMAP |
90 SNDRV_PCM_INFO_INTERLEAVED |
91 SNDRV_PCM_INFO_BLOCK_TRANSFER |
92 SNDRV_PCM_INFO_MMAP_VALID |
94 SNDRV_PCM_INFO_RESUME |
96 SNDRV_PCM_INFO_SYNC_START),
97 .formats = SNDRV_PCM_FMTBIT_S24_3LE,
98 .rates = SNDRV_PCM_RATE_KNOT,
103 .buffer_bytes_max = 60000,
104 .period_bytes_min = 64,
105 .period_bytes_max = 8192,
107 .periods_max = 1024},
110 .rats = &pod_ratden},
111 .bytes_per_frame = POD_BYTES_PER_FRAME
114 static const char pod_version_header[] = {
115 0xf2, 0x7e, 0x7f, 0x06, 0x02
118 /* forward declarations: */
119 static void pod_startup2(unsigned long data);
120 static void pod_startup3(struct usb_line6_pod *pod);
122 static char *pod_alloc_sysex_buffer(struct usb_line6_pod *pod, int code,
125 return line6_alloc_sysex_buffer(&pod->line6, POD_SYSEX_CODE, code,
130 Process a completely received message.
132 void line6_pod_process_message(struct usb_line6_pod *pod)
134 const unsigned char *buf = pod->line6.buffer_message;
136 /* filter messages by type */
137 switch (buf[0] & 0xf0) {
138 case LINE6_PARAM_CHANGE:
139 case LINE6_PROGRAM_CHANGE:
140 case LINE6_SYSEX_BEGIN:
141 break; /* handle these further down */
144 return; /* ignore all others */
147 /* process all remaining messages */
149 case LINE6_PARAM_CHANGE | LINE6_CHANNEL_DEVICE:
150 case LINE6_PARAM_CHANGE | LINE6_CHANNEL_HOST:
153 case LINE6_PROGRAM_CHANGE | LINE6_CHANNEL_DEVICE:
154 case LINE6_PROGRAM_CHANGE | LINE6_CHANNEL_HOST:
157 case LINE6_SYSEX_BEGIN | LINE6_CHANNEL_DEVICE:
158 case LINE6_SYSEX_BEGIN | LINE6_CHANNEL_UNKNOWN:
159 if (memcmp(buf + 1, line6_midi_id, sizeof(line6_midi_id)) == 0) {
164 case POD_SYSEX_SYSTEM:{
166 ((int)buf[7] << 12) | ((int)buf[8]
168 ((int)buf[9] << 4) | (int)buf[10];
170 if (buf[6] == POD_monitor_level)
171 pod->monitor_level = value;
175 case POD_SYSEX_FINISH:
176 /* do we need to respond to this? */
182 case POD_SYSEX_STORE:
183 dev_dbg(pod->line6.ifcdev,
184 "message %02X not yet implemented\n",
189 dev_dbg(pod->line6.ifcdev,
190 "unknown sysex message %02X\n",
195 (buf, pod_version_header,
196 sizeof(pod_version_header)) == 0) {
197 pod->firmware_version =
198 buf[13] * 100 + buf[14] * 10 + buf[15];
200 ((int)buf[8] << 16) | ((int)buf[9] << 8) | (int)
204 dev_dbg(pod->line6.ifcdev, "unknown sysex header\n");
208 case LINE6_SYSEX_END:
212 dev_dbg(pod->line6.ifcdev, "POD: unknown message %02X\n",
218 Transmit PODxt Pro control parameter.
220 void line6_pod_transmit_parameter(struct usb_line6_pod *pod, int param,
223 line6_transmit_parameter(&pod->line6, param, value);
227 Send system parameter (from integer).
229 static int pod_set_system_param_int(struct usb_line6_pod *pod, int value,
233 static const int size = 5;
235 sysex = pod_alloc_sysex_buffer(pod, POD_SYSEX_SYSTEM, size);
238 sysex[SYSEX_DATA_OFS] = code;
239 sysex[SYSEX_DATA_OFS + 1] = (value >> 12) & 0x0f;
240 sysex[SYSEX_DATA_OFS + 2] = (value >> 8) & 0x0f;
241 sysex[SYSEX_DATA_OFS + 3] = (value >> 4) & 0x0f;
242 sysex[SYSEX_DATA_OFS + 4] = (value) & 0x0f;
243 line6_send_sysex_message(&pod->line6, sysex, size);
249 "read" request on "serial_number" special file.
251 static ssize_t pod_get_serial_number(struct device *dev,
252 struct device_attribute *attr, char *buf)
254 struct usb_interface *interface = to_usb_interface(dev);
255 struct usb_line6_pod *pod = usb_get_intfdata(interface);
256 return sprintf(buf, "%d\n", pod->serial_number);
260 "read" request on "firmware_version" special file.
262 static ssize_t pod_get_firmware_version(struct device *dev,
263 struct device_attribute *attr,
266 struct usb_interface *interface = to_usb_interface(dev);
267 struct usb_line6_pod *pod = usb_get_intfdata(interface);
268 return sprintf(buf, "%d.%02d\n", pod->firmware_version / 100,
269 pod->firmware_version % 100);
273 "read" request on "device_id" special file.
275 static ssize_t pod_get_device_id(struct device *dev,
276 struct device_attribute *attr, char *buf)
278 struct usb_interface *interface = to_usb_interface(dev);
279 struct usb_line6_pod *pod = usb_get_intfdata(interface);
280 return sprintf(buf, "%d\n", pod->device_id);
284 POD startup procedure.
285 This is a sequence of functions with special requirements (e.g., must
286 not run immediately after initialization, must not run in interrupt
287 context). After the last one has finished, the device is ready to use.
290 static void pod_startup1(struct usb_line6_pod *pod)
292 CHECK_STARTUP_PROGRESS(pod->startup_progress, POD_STARTUP_INIT);
294 /* delay startup procedure: */
295 line6_start_timer(&pod->startup_timer, POD_STARTUP_DELAY, pod_startup2,
299 static void pod_startup2(unsigned long data)
301 struct usb_line6_pod *pod = (struct usb_line6_pod *)data;
302 struct usb_line6 *line6 = &pod->line6;
303 CHECK_STARTUP_PROGRESS(pod->startup_progress, POD_STARTUP_VERSIONREQ);
305 /* request firmware version: */
306 line6_version_request_async(line6);
309 static void pod_startup3(struct usb_line6_pod *pod)
311 CHECK_STARTUP_PROGRESS(pod->startup_progress, POD_STARTUP_WORKQUEUE);
313 /* schedule work for global work queue: */
314 schedule_work(&pod->startup_work);
317 static void pod_startup4(struct work_struct *work)
319 struct usb_line6_pod *pod =
320 container_of(work, struct usb_line6_pod, startup_work);
321 struct usb_line6 *line6 = &pod->line6;
323 CHECK_STARTUP_PROGRESS(pod->startup_progress, POD_STARTUP_SETUP);
326 line6_read_serial_number(&pod->line6, &pod->serial_number);
328 /* ALSA audio interface: */
329 line6_register_audio(line6);
332 /* POD special files: */
333 static DEVICE_ATTR(device_id, S_IRUGO, pod_get_device_id, line6_nop_write);
334 static DEVICE_ATTR(firmware_version, S_IRUGO, pod_get_firmware_version,
336 static DEVICE_ATTR(serial_number, S_IRUGO, pod_get_serial_number,
339 /* control info callback */
340 static int snd_pod_control_monitor_info(struct snd_kcontrol *kcontrol,
341 struct snd_ctl_elem_info *uinfo)
343 uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
345 uinfo->value.integer.min = 0;
346 uinfo->value.integer.max = 65535;
350 /* control get callback */
351 static int snd_pod_control_monitor_get(struct snd_kcontrol *kcontrol,
352 struct snd_ctl_elem_value *ucontrol)
354 struct snd_line6_pcm *line6pcm = snd_kcontrol_chip(kcontrol);
355 struct usb_line6_pod *pod = (struct usb_line6_pod *)line6pcm->line6;
356 ucontrol->value.integer.value[0] = pod->monitor_level;
360 /* control put callback */
361 static int snd_pod_control_monitor_put(struct snd_kcontrol *kcontrol,
362 struct snd_ctl_elem_value *ucontrol)
364 struct snd_line6_pcm *line6pcm = snd_kcontrol_chip(kcontrol);
365 struct usb_line6_pod *pod = (struct usb_line6_pod *)line6pcm->line6;
367 if (ucontrol->value.integer.value[0] == pod->monitor_level)
370 pod->monitor_level = ucontrol->value.integer.value[0];
371 pod_set_system_param_int(pod, ucontrol->value.integer.value[0],
376 /* control definition */
377 static struct snd_kcontrol_new pod_control_monitor = {
378 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
379 .name = "Monitor Playback Volume",
381 .access = SNDRV_CTL_ELEM_ACCESS_READWRITE,
382 .info = snd_pod_control_monitor_info,
383 .get = snd_pod_control_monitor_get,
384 .put = snd_pod_control_monitor_put
390 static void pod_destruct(struct usb_interface *interface)
392 struct usb_line6_pod *pod = usb_get_intfdata(interface);
396 line6_cleanup_audio(&pod->line6);
398 del_timer(&pod->startup_timer);
399 cancel_work_sync(&pod->startup_work);
403 Create sysfs entries.
405 static int pod_create_files2(struct device *dev)
409 CHECK_RETURN(device_create_file(dev, &dev_attr_device_id));
410 CHECK_RETURN(device_create_file(dev, &dev_attr_firmware_version));
411 CHECK_RETURN(device_create_file(dev, &dev_attr_serial_number));
416 Try to init POD device.
418 static int pod_try_init(struct usb_interface *interface,
419 struct usb_line6_pod *pod)
422 struct usb_line6 *line6 = &pod->line6;
424 init_timer(&pod->startup_timer);
425 INIT_WORK(&pod->startup_work, pod_startup4);
427 if ((interface == NULL) || (pod == NULL))
430 /* create sysfs entries: */
431 err = pod_create_files2(&interface->dev);
435 /* initialize audio system: */
436 err = line6_init_audio(line6);
440 /* initialize MIDI subsystem: */
441 err = line6_init_midi(line6);
445 /* initialize PCM subsystem: */
446 err = line6_init_pcm(line6, &pod_pcm_properties);
450 /* register monitor control: */
451 err = snd_ctl_add(line6->card,
452 snd_ctl_new1(&pod_control_monitor, line6->line6pcm));
457 When the sound card is registered at this point, the PODxt Live
458 displays "Invalid Code Error 07", so we do it later in the event
462 if (pod->line6.properties->capabilities & LINE6_BIT_CONTROL) {
463 pod->monitor_level = POD_system_invalid;
465 /* initiate startup procedure: */
473 Init POD device (and clean up in case of failure).
475 int line6_pod_init(struct usb_interface *interface, struct usb_line6_pod *pod)
477 int err = pod_try_init(interface, pod);
480 pod_destruct(interface);
486 POD device disconnected.
488 void line6_pod_disconnect(struct usb_interface *interface)
490 struct usb_line6_pod *pod;
492 if (interface == NULL)
494 pod = usb_get_intfdata(interface);
497 struct snd_line6_pcm *line6pcm = pod->line6.line6pcm;
498 struct device *dev = &interface->dev;
500 if (line6pcm != NULL)
501 line6_pcm_disconnect(line6pcm);
504 /* remove sysfs entries: */
505 device_remove_file(dev, &dev_attr_device_id);
506 device_remove_file(dev, &dev_attr_firmware_version);
507 device_remove_file(dev, &dev_attr_serial_number);
511 pod_destruct(interface);