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
38 /* dumps entire internal memory of PODxt Pro */
39 /* POD_SYSEX_DUMPMEM2 = 0x76 */
43 POD_MONITOR_LEVEL = 0x04,
44 POD_SYSTEM_INVALID = 0x10000
61 static struct snd_ratden pod_ratden = {
68 static struct line6_pcm_properties pod_pcm_properties = {
69 .snd_line6_playback_hw = {
70 .info = (SNDRV_PCM_INFO_MMAP |
71 SNDRV_PCM_INFO_INTERLEAVED |
72 SNDRV_PCM_INFO_BLOCK_TRANSFER |
73 SNDRV_PCM_INFO_MMAP_VALID |
74 SNDRV_PCM_INFO_PAUSE |
76 SNDRV_PCM_INFO_RESUME |
78 SNDRV_PCM_INFO_SYNC_START),
79 .formats = SNDRV_PCM_FMTBIT_S24_3LE,
80 .rates = SNDRV_PCM_RATE_KNOT,
85 .buffer_bytes_max = 60000,
86 .period_bytes_min = 64,
87 .period_bytes_max = 8192,
90 .snd_line6_capture_hw = {
91 .info = (SNDRV_PCM_INFO_MMAP |
92 SNDRV_PCM_INFO_INTERLEAVED |
93 SNDRV_PCM_INFO_BLOCK_TRANSFER |
94 SNDRV_PCM_INFO_MMAP_VALID |
96 SNDRV_PCM_INFO_RESUME |
98 SNDRV_PCM_INFO_SYNC_START),
99 .formats = SNDRV_PCM_FMTBIT_S24_3LE,
100 .rates = SNDRV_PCM_RATE_KNOT,
105 .buffer_bytes_max = 60000,
106 .period_bytes_min = 64,
107 .period_bytes_max = 8192,
109 .periods_max = 1024},
112 .rats = &pod_ratden},
113 .bytes_per_frame = POD_BYTES_PER_FRAME
116 static const char pod_version_header[] = {
117 0xf2, 0x7e, 0x7f, 0x06, 0x02
120 /* forward declarations: */
121 static void pod_startup2(unsigned long data);
122 static void pod_startup3(struct usb_line6_pod *pod);
124 static char *pod_alloc_sysex_buffer(struct usb_line6_pod *pod, int code,
127 return line6_alloc_sysex_buffer(&pod->line6, POD_SYSEX_CODE, code,
132 Process a completely received message.
134 void line6_pod_process_message(struct usb_line6_pod *pod)
136 const unsigned char *buf = pod->line6.buffer_message;
138 /* filter messages by type */
139 switch (buf[0] & 0xf0) {
140 case LINE6_PARAM_CHANGE:
141 case LINE6_PROGRAM_CHANGE:
142 case LINE6_SYSEX_BEGIN:
143 break; /* handle these further down */
146 return; /* ignore all others */
149 /* process all remaining messages */
151 case LINE6_PARAM_CHANGE | LINE6_CHANNEL_DEVICE:
152 case LINE6_PARAM_CHANGE | LINE6_CHANNEL_HOST:
155 case LINE6_PROGRAM_CHANGE | LINE6_CHANNEL_DEVICE:
156 case LINE6_PROGRAM_CHANGE | LINE6_CHANNEL_HOST:
159 case LINE6_SYSEX_BEGIN | LINE6_CHANNEL_DEVICE:
160 case LINE6_SYSEX_BEGIN | LINE6_CHANNEL_UNKNOWN:
161 if (memcmp(buf + 1, line6_midi_id,
162 sizeof(line6_midi_id)) == 0) {
167 case POD_SYSEX_SYSTEM:{
169 ((int)buf[7] << 12) | ((int)buf[8]
171 ((int)buf[9] << 4) | (int)buf[10];
173 if (buf[6] == POD_MONITOR_LEVEL)
174 pod->monitor_level = value;
178 case POD_SYSEX_FINISH:
179 /* do we need to respond to this? */
185 case POD_SYSEX_STORE:
186 dev_dbg(pod->line6.ifcdev,
187 "message %02X not yet implemented\n",
192 dev_dbg(pod->line6.ifcdev,
193 "unknown sysex message %02X\n",
198 (buf, pod_version_header,
199 sizeof(pod_version_header)) == 0) {
200 pod->firmware_version =
201 buf[13] * 100 + buf[14] * 10 + buf[15];
203 ((int)buf[8] << 16) | ((int)buf[9] << 8) | (int)
207 dev_dbg(pod->line6.ifcdev, "unknown sysex header\n");
211 case LINE6_SYSEX_END:
215 dev_dbg(pod->line6.ifcdev, "POD: unknown message %02X\n",
221 Transmit PODxt Pro control parameter.
223 void line6_pod_transmit_parameter(struct usb_line6_pod *pod, int param,
226 line6_transmit_parameter(&pod->line6, param, value);
230 Send system parameter (from integer).
232 static int pod_set_system_param_int(struct usb_line6_pod *pod, int value,
236 static const int size = 5;
238 sysex = pod_alloc_sysex_buffer(pod, POD_SYSEX_SYSTEM, size);
241 sysex[SYSEX_DATA_OFS] = code;
242 sysex[SYSEX_DATA_OFS + 1] = (value >> 12) & 0x0f;
243 sysex[SYSEX_DATA_OFS + 2] = (value >> 8) & 0x0f;
244 sysex[SYSEX_DATA_OFS + 3] = (value >> 4) & 0x0f;
245 sysex[SYSEX_DATA_OFS + 4] = (value) & 0x0f;
246 line6_send_sysex_message(&pod->line6, sysex, size);
252 "read" request on "serial_number" special file.
254 static ssize_t pod_get_serial_number(struct device *dev,
255 struct device_attribute *attr, char *buf)
257 struct usb_interface *interface = to_usb_interface(dev);
258 struct usb_line6_pod *pod = usb_get_intfdata(interface);
259 return sprintf(buf, "%d\n", pod->serial_number);
263 "read" request on "firmware_version" special file.
265 static ssize_t pod_get_firmware_version(struct device *dev,
266 struct device_attribute *attr,
269 struct usb_interface *interface = to_usb_interface(dev);
270 struct usb_line6_pod *pod = usb_get_intfdata(interface);
271 return sprintf(buf, "%d.%02d\n", pod->firmware_version / 100,
272 pod->firmware_version % 100);
276 "read" request on "device_id" special file.
278 static ssize_t pod_get_device_id(struct device *dev,
279 struct device_attribute *attr, char *buf)
281 struct usb_interface *interface = to_usb_interface(dev);
282 struct usb_line6_pod *pod = usb_get_intfdata(interface);
283 return sprintf(buf, "%d\n", pod->device_id);
287 POD startup procedure.
288 This is a sequence of functions with special requirements (e.g., must
289 not run immediately after initialization, must not run in interrupt
290 context). After the last one has finished, the device is ready to use.
293 static void pod_startup1(struct usb_line6_pod *pod)
295 CHECK_STARTUP_PROGRESS(pod->startup_progress, POD_STARTUP_INIT);
297 /* delay startup procedure: */
298 line6_start_timer(&pod->startup_timer, POD_STARTUP_DELAY, pod_startup2,
302 static void pod_startup2(unsigned long data)
304 struct usb_line6_pod *pod = (struct usb_line6_pod *)data;
305 struct usb_line6 *line6 = &pod->line6;
306 CHECK_STARTUP_PROGRESS(pod->startup_progress, POD_STARTUP_VERSIONREQ);
308 /* request firmware version: */
309 line6_version_request_async(line6);
312 static void pod_startup3(struct usb_line6_pod *pod)
314 CHECK_STARTUP_PROGRESS(pod->startup_progress, POD_STARTUP_WORKQUEUE);
316 /* schedule work for global work queue: */
317 schedule_work(&pod->startup_work);
320 static void pod_startup4(struct work_struct *work)
322 struct usb_line6_pod *pod =
323 container_of(work, struct usb_line6_pod, startup_work);
324 struct usb_line6 *line6 = &pod->line6;
326 CHECK_STARTUP_PROGRESS(pod->startup_progress, POD_STARTUP_SETUP);
329 line6_read_serial_number(&pod->line6, &pod->serial_number);
331 /* ALSA audio interface: */
332 line6_register_audio(line6);
335 /* POD special files: */
336 static DEVICE_ATTR(device_id, S_IRUGO, pod_get_device_id, line6_nop_write);
337 static DEVICE_ATTR(firmware_version, S_IRUGO, pod_get_firmware_version,
339 static DEVICE_ATTR(serial_number, S_IRUGO, pod_get_serial_number,
342 /* control info callback */
343 static int snd_pod_control_monitor_info(struct snd_kcontrol *kcontrol,
344 struct snd_ctl_elem_info *uinfo)
346 uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
348 uinfo->value.integer.min = 0;
349 uinfo->value.integer.max = 65535;
353 /* control get callback */
354 static int snd_pod_control_monitor_get(struct snd_kcontrol *kcontrol,
355 struct snd_ctl_elem_value *ucontrol)
357 struct snd_line6_pcm *line6pcm = snd_kcontrol_chip(kcontrol);
358 struct usb_line6_pod *pod = (struct usb_line6_pod *)line6pcm->line6;
359 ucontrol->value.integer.value[0] = pod->monitor_level;
363 /* control put callback */
364 static int snd_pod_control_monitor_put(struct snd_kcontrol *kcontrol,
365 struct snd_ctl_elem_value *ucontrol)
367 struct snd_line6_pcm *line6pcm = snd_kcontrol_chip(kcontrol);
368 struct usb_line6_pod *pod = (struct usb_line6_pod *)line6pcm->line6;
370 if (ucontrol->value.integer.value[0] == pod->monitor_level)
373 pod->monitor_level = ucontrol->value.integer.value[0];
374 pod_set_system_param_int(pod, ucontrol->value.integer.value[0],
379 /* control definition */
380 static struct snd_kcontrol_new pod_control_monitor = {
381 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
382 .name = "Monitor Playback Volume",
384 .access = SNDRV_CTL_ELEM_ACCESS_READWRITE,
385 .info = snd_pod_control_monitor_info,
386 .get = snd_pod_control_monitor_get,
387 .put = snd_pod_control_monitor_put
393 static void pod_destruct(struct usb_interface *interface)
395 struct usb_line6_pod *pod = usb_get_intfdata(interface);
399 line6_cleanup_audio(&pod->line6);
401 del_timer(&pod->startup_timer);
402 cancel_work_sync(&pod->startup_work);
406 Create sysfs entries.
408 static int pod_create_files2(struct device *dev)
412 CHECK_RETURN(device_create_file(dev, &dev_attr_device_id));
413 CHECK_RETURN(device_create_file(dev, &dev_attr_firmware_version));
414 CHECK_RETURN(device_create_file(dev, &dev_attr_serial_number));
419 Try to init POD device.
421 static int pod_try_init(struct usb_interface *interface,
422 struct usb_line6_pod *pod)
425 struct usb_line6 *line6 = &pod->line6;
427 init_timer(&pod->startup_timer);
428 INIT_WORK(&pod->startup_work, pod_startup4);
430 if ((interface == NULL) || (pod == NULL))
433 /* create sysfs entries: */
434 err = pod_create_files2(&interface->dev);
438 /* initialize audio system: */
439 err = line6_init_audio(line6);
443 /* initialize MIDI subsystem: */
444 err = line6_init_midi(line6);
448 /* initialize PCM subsystem: */
449 err = line6_init_pcm(line6, &pod_pcm_properties);
453 /* register monitor control: */
454 err = snd_ctl_add(line6->card,
455 snd_ctl_new1(&pod_control_monitor, line6->line6pcm));
460 When the sound card is registered at this point, the PODxt Live
461 displays "Invalid Code Error 07", so we do it later in the event
465 if (pod->line6.properties->capabilities & LINE6_BIT_CONTROL) {
466 pod->monitor_level = POD_SYSTEM_INVALID;
468 /* initiate startup procedure: */
476 Init POD device (and clean up in case of failure).
478 int line6_pod_init(struct usb_interface *interface, struct usb_line6_pod *pod)
480 int err = pod_try_init(interface, pod);
483 pod_destruct(interface);
489 POD device disconnected.
491 void line6_pod_disconnect(struct usb_interface *interface)
493 struct usb_line6_pod *pod;
495 if (interface == NULL)
497 pod = usb_get_intfdata(interface);
500 struct snd_line6_pcm *line6pcm = pod->line6.line6pcm;
501 struct device *dev = &interface->dev;
503 if (line6pcm != NULL)
504 line6_pcm_disconnect(line6pcm);
507 /* remove sysfs entries: */
508 device_remove_file(dev, &dev_attr_device_id);
509 device_remove_file(dev, &dev_attr_firmware_version);
510 device_remove_file(dev, &dev_attr_serial_number);
514 pod_destruct(interface);