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 if (memcmp(buf, pod_version_header, sizeof(pod_version_header)) == 0) {
139 pod->firmware_version = buf[13] * 100 + buf[14] * 10 + buf[15];
140 pod->device_id = ((int)buf[8] << 16) | ((int)buf[9] << 8) |
146 /* Only look for sysex messages from this device */
147 if (buf[0] != (LINE6_SYSEX_BEGIN | LINE6_CHANNEL_DEVICE) &&
148 buf[0] != (LINE6_SYSEX_BEGIN | LINE6_CHANNEL_UNKNOWN)) {
151 if (memcmp(buf + 1, line6_midi_id, sizeof(line6_midi_id)) != 0) {
155 if (buf[5] == POD_SYSEX_SYSTEM && buf[6] == POD_MONITOR_LEVEL) {
156 short value = ((int)buf[7] << 12) | ((int)buf[8] << 8) |
157 ((int)buf[9] << 4) | (int)buf[10];
158 pod->monitor_level = value;
163 Transmit PODxt Pro control parameter.
165 void line6_pod_transmit_parameter(struct usb_line6_pod *pod, int param,
168 line6_transmit_parameter(&pod->line6, param, value);
172 Send system parameter (from integer).
174 static int pod_set_system_param_int(struct usb_line6_pod *pod, int value,
178 static const int size = 5;
180 sysex = pod_alloc_sysex_buffer(pod, POD_SYSEX_SYSTEM, size);
183 sysex[SYSEX_DATA_OFS] = code;
184 sysex[SYSEX_DATA_OFS + 1] = (value >> 12) & 0x0f;
185 sysex[SYSEX_DATA_OFS + 2] = (value >> 8) & 0x0f;
186 sysex[SYSEX_DATA_OFS + 3] = (value >> 4) & 0x0f;
187 sysex[SYSEX_DATA_OFS + 4] = (value) & 0x0f;
188 line6_send_sysex_message(&pod->line6, sysex, size);
194 "read" request on "serial_number" special file.
196 static ssize_t pod_get_serial_number(struct device *dev,
197 struct device_attribute *attr, char *buf)
199 struct usb_interface *interface = to_usb_interface(dev);
200 struct usb_line6_pod *pod = usb_get_intfdata(interface);
201 return sprintf(buf, "%d\n", pod->serial_number);
205 "read" request on "firmware_version" special file.
207 static ssize_t pod_get_firmware_version(struct device *dev,
208 struct device_attribute *attr,
211 struct usb_interface *interface = to_usb_interface(dev);
212 struct usb_line6_pod *pod = usb_get_intfdata(interface);
213 return sprintf(buf, "%d.%02d\n", pod->firmware_version / 100,
214 pod->firmware_version % 100);
218 "read" request on "device_id" special file.
220 static ssize_t pod_get_device_id(struct device *dev,
221 struct device_attribute *attr, char *buf)
223 struct usb_interface *interface = to_usb_interface(dev);
224 struct usb_line6_pod *pod = usb_get_intfdata(interface);
225 return sprintf(buf, "%d\n", pod->device_id);
229 POD startup procedure.
230 This is a sequence of functions with special requirements (e.g., must
231 not run immediately after initialization, must not run in interrupt
232 context). After the last one has finished, the device is ready to use.
235 static void pod_startup1(struct usb_line6_pod *pod)
237 CHECK_STARTUP_PROGRESS(pod->startup_progress, POD_STARTUP_INIT);
239 /* delay startup procedure: */
240 line6_start_timer(&pod->startup_timer, POD_STARTUP_DELAY, pod_startup2,
244 static void pod_startup2(unsigned long data)
246 struct usb_line6_pod *pod = (struct usb_line6_pod *)data;
247 struct usb_line6 *line6 = &pod->line6;
248 CHECK_STARTUP_PROGRESS(pod->startup_progress, POD_STARTUP_VERSIONREQ);
250 /* request firmware version: */
251 line6_version_request_async(line6);
254 static void pod_startup3(struct usb_line6_pod *pod)
256 CHECK_STARTUP_PROGRESS(pod->startup_progress, POD_STARTUP_WORKQUEUE);
258 /* schedule work for global work queue: */
259 schedule_work(&pod->startup_work);
262 static void pod_startup4(struct work_struct *work)
264 struct usb_line6_pod *pod =
265 container_of(work, struct usb_line6_pod, startup_work);
266 struct usb_line6 *line6 = &pod->line6;
268 CHECK_STARTUP_PROGRESS(pod->startup_progress, POD_STARTUP_SETUP);
271 line6_read_serial_number(&pod->line6, &pod->serial_number);
273 /* ALSA audio interface: */
274 line6_register_audio(line6);
277 /* POD special files: */
278 static DEVICE_ATTR(device_id, S_IRUGO, pod_get_device_id, line6_nop_write);
279 static DEVICE_ATTR(firmware_version, S_IRUGO, pod_get_firmware_version,
281 static DEVICE_ATTR(serial_number, S_IRUGO, pod_get_serial_number,
284 /* control info callback */
285 static int snd_pod_control_monitor_info(struct snd_kcontrol *kcontrol,
286 struct snd_ctl_elem_info *uinfo)
288 uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
290 uinfo->value.integer.min = 0;
291 uinfo->value.integer.max = 65535;
295 /* control get callback */
296 static int snd_pod_control_monitor_get(struct snd_kcontrol *kcontrol,
297 struct snd_ctl_elem_value *ucontrol)
299 struct snd_line6_pcm *line6pcm = snd_kcontrol_chip(kcontrol);
300 struct usb_line6_pod *pod = (struct usb_line6_pod *)line6pcm->line6;
301 ucontrol->value.integer.value[0] = pod->monitor_level;
305 /* control put callback */
306 static int snd_pod_control_monitor_put(struct snd_kcontrol *kcontrol,
307 struct snd_ctl_elem_value *ucontrol)
309 struct snd_line6_pcm *line6pcm = snd_kcontrol_chip(kcontrol);
310 struct usb_line6_pod *pod = (struct usb_line6_pod *)line6pcm->line6;
312 if (ucontrol->value.integer.value[0] == pod->monitor_level)
315 pod->monitor_level = ucontrol->value.integer.value[0];
316 pod_set_system_param_int(pod, ucontrol->value.integer.value[0],
321 /* control definition */
322 static struct snd_kcontrol_new pod_control_monitor = {
323 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
324 .name = "Monitor Playback Volume",
326 .access = SNDRV_CTL_ELEM_ACCESS_READWRITE,
327 .info = snd_pod_control_monitor_info,
328 .get = snd_pod_control_monitor_get,
329 .put = snd_pod_control_monitor_put
335 static void pod_destruct(struct usb_interface *interface)
337 struct usb_line6_pod *pod = usb_get_intfdata(interface);
341 line6_cleanup_audio(&pod->line6);
343 del_timer(&pod->startup_timer);
344 cancel_work_sync(&pod->startup_work);
348 Create sysfs entries.
350 static int pod_create_files2(struct device *dev)
354 CHECK_RETURN(device_create_file(dev, &dev_attr_device_id));
355 CHECK_RETURN(device_create_file(dev, &dev_attr_firmware_version));
356 CHECK_RETURN(device_create_file(dev, &dev_attr_serial_number));
361 Try to init POD device.
363 static int pod_try_init(struct usb_interface *interface,
364 struct usb_line6_pod *pod)
367 struct usb_line6 *line6 = &pod->line6;
369 init_timer(&pod->startup_timer);
370 INIT_WORK(&pod->startup_work, pod_startup4);
372 if ((interface == NULL) || (pod == NULL))
375 /* create sysfs entries: */
376 err = pod_create_files2(&interface->dev);
380 /* initialize audio system: */
381 err = line6_init_audio(line6);
385 /* initialize MIDI subsystem: */
386 err = line6_init_midi(line6);
390 /* initialize PCM subsystem: */
391 err = line6_init_pcm(line6, &pod_pcm_properties);
395 /* register monitor control: */
396 err = snd_ctl_add(line6->card,
397 snd_ctl_new1(&pod_control_monitor, line6->line6pcm));
402 When the sound card is registered at this point, the PODxt Live
403 displays "Invalid Code Error 07", so we do it later in the event
407 if (pod->line6.properties->capabilities & LINE6_BIT_CONTROL) {
408 pod->monitor_level = POD_SYSTEM_INVALID;
410 /* initiate startup procedure: */
418 Init POD device (and clean up in case of failure).
420 int line6_pod_init(struct usb_interface *interface, struct usb_line6_pod *pod)
422 int err = pod_try_init(interface, pod);
425 pod_destruct(interface);
431 POD device disconnected.
433 void line6_pod_disconnect(struct usb_interface *interface)
435 struct usb_line6_pod *pod;
437 if (interface == NULL)
439 pod = usb_get_intfdata(interface);
442 struct snd_line6_pcm *line6pcm = pod->line6.line6pcm;
443 struct device *dev = &interface->dev;
445 if (line6pcm != NULL)
446 line6_pcm_disconnect(line6pcm);
449 /* remove sysfs entries: */
450 device_remove_file(dev, &dev_attr_device_id);
451 device_remove_file(dev, &dev_attr_firmware_version);
452 device_remove_file(dev, &dev_attr_serial_number);
456 pod_destruct(interface);