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)
154 if (buf[5] == POD_SYSEX_SYSTEM && buf[6] == POD_MONITOR_LEVEL) {
155 short value = ((int)buf[7] << 12) | ((int)buf[8] << 8) |
156 ((int)buf[9] << 4) | (int)buf[10];
157 pod->monitor_level = value;
162 Transmit PODxt Pro control parameter.
164 void line6_pod_transmit_parameter(struct usb_line6_pod *pod, int param,
167 line6_transmit_parameter(&pod->line6, param, value);
171 Send system parameter (from integer).
173 static int pod_set_system_param_int(struct usb_line6_pod *pod, int value,
177 static const int size = 5;
179 sysex = pod_alloc_sysex_buffer(pod, POD_SYSEX_SYSTEM, size);
182 sysex[SYSEX_DATA_OFS] = code;
183 sysex[SYSEX_DATA_OFS + 1] = (value >> 12) & 0x0f;
184 sysex[SYSEX_DATA_OFS + 2] = (value >> 8) & 0x0f;
185 sysex[SYSEX_DATA_OFS + 3] = (value >> 4) & 0x0f;
186 sysex[SYSEX_DATA_OFS + 4] = (value) & 0x0f;
187 line6_send_sysex_message(&pod->line6, sysex, size);
193 "read" request on "serial_number" special file.
195 static ssize_t pod_get_serial_number(struct device *dev,
196 struct device_attribute *attr, char *buf)
198 struct usb_interface *interface = to_usb_interface(dev);
199 struct usb_line6_pod *pod = usb_get_intfdata(interface);
200 return sprintf(buf, "%d\n", pod->serial_number);
204 "read" request on "firmware_version" special file.
206 static ssize_t pod_get_firmware_version(struct device *dev,
207 struct device_attribute *attr,
210 struct usb_interface *interface = to_usb_interface(dev);
211 struct usb_line6_pod *pod = usb_get_intfdata(interface);
212 return sprintf(buf, "%d.%02d\n", pod->firmware_version / 100,
213 pod->firmware_version % 100);
217 "read" request on "device_id" special file.
219 static ssize_t pod_get_device_id(struct device *dev,
220 struct device_attribute *attr, char *buf)
222 struct usb_interface *interface = to_usb_interface(dev);
223 struct usb_line6_pod *pod = usb_get_intfdata(interface);
224 return sprintf(buf, "%d\n", pod->device_id);
228 POD startup procedure.
229 This is a sequence of functions with special requirements (e.g., must
230 not run immediately after initialization, must not run in interrupt
231 context). After the last one has finished, the device is ready to use.
234 static void pod_startup1(struct usb_line6_pod *pod)
236 CHECK_STARTUP_PROGRESS(pod->startup_progress, POD_STARTUP_INIT);
238 /* delay startup procedure: */
239 line6_start_timer(&pod->startup_timer, POD_STARTUP_DELAY, pod_startup2,
243 static void pod_startup2(unsigned long data)
245 struct usb_line6_pod *pod = (struct usb_line6_pod *)data;
246 struct usb_line6 *line6 = &pod->line6;
247 CHECK_STARTUP_PROGRESS(pod->startup_progress, POD_STARTUP_VERSIONREQ);
249 /* request firmware version: */
250 line6_version_request_async(line6);
253 static void pod_startup3(struct usb_line6_pod *pod)
255 CHECK_STARTUP_PROGRESS(pod->startup_progress, POD_STARTUP_WORKQUEUE);
257 /* schedule work for global work queue: */
258 schedule_work(&pod->startup_work);
261 static void pod_startup4(struct work_struct *work)
263 struct usb_line6_pod *pod =
264 container_of(work, struct usb_line6_pod, startup_work);
265 struct usb_line6 *line6 = &pod->line6;
267 CHECK_STARTUP_PROGRESS(pod->startup_progress, POD_STARTUP_SETUP);
270 line6_read_serial_number(&pod->line6, &pod->serial_number);
272 /* ALSA audio interface: */
273 line6_register_audio(line6);
276 /* POD special files: */
277 static DEVICE_ATTR(device_id, S_IRUGO, pod_get_device_id, line6_nop_write);
278 static DEVICE_ATTR(firmware_version, S_IRUGO, pod_get_firmware_version,
280 static DEVICE_ATTR(serial_number, S_IRUGO, pod_get_serial_number,
283 /* control info callback */
284 static int snd_pod_control_monitor_info(struct snd_kcontrol *kcontrol,
285 struct snd_ctl_elem_info *uinfo)
287 uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
289 uinfo->value.integer.min = 0;
290 uinfo->value.integer.max = 65535;
294 /* control get callback */
295 static int snd_pod_control_monitor_get(struct snd_kcontrol *kcontrol,
296 struct snd_ctl_elem_value *ucontrol)
298 struct snd_line6_pcm *line6pcm = snd_kcontrol_chip(kcontrol);
299 struct usb_line6_pod *pod = (struct usb_line6_pod *)line6pcm->line6;
300 ucontrol->value.integer.value[0] = pod->monitor_level;
304 /* control put callback */
305 static int snd_pod_control_monitor_put(struct snd_kcontrol *kcontrol,
306 struct snd_ctl_elem_value *ucontrol)
308 struct snd_line6_pcm *line6pcm = snd_kcontrol_chip(kcontrol);
309 struct usb_line6_pod *pod = (struct usb_line6_pod *)line6pcm->line6;
311 if (ucontrol->value.integer.value[0] == pod->monitor_level)
314 pod->monitor_level = ucontrol->value.integer.value[0];
315 pod_set_system_param_int(pod, ucontrol->value.integer.value[0],
320 /* control definition */
321 static struct snd_kcontrol_new pod_control_monitor = {
322 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
323 .name = "Monitor Playback Volume",
325 .access = SNDRV_CTL_ELEM_ACCESS_READWRITE,
326 .info = snd_pod_control_monitor_info,
327 .get = snd_pod_control_monitor_get,
328 .put = snd_pod_control_monitor_put
334 static void pod_destruct(struct usb_interface *interface)
336 struct usb_line6_pod *pod = usb_get_intfdata(interface);
340 line6_cleanup_audio(&pod->line6);
342 del_timer(&pod->startup_timer);
343 cancel_work_sync(&pod->startup_work);
347 Create sysfs entries.
349 static int pod_create_files2(struct device *dev)
353 CHECK_RETURN(device_create_file(dev, &dev_attr_device_id));
354 CHECK_RETURN(device_create_file(dev, &dev_attr_firmware_version));
355 CHECK_RETURN(device_create_file(dev, &dev_attr_serial_number));
360 Try to init POD device.
362 static int pod_try_init(struct usb_interface *interface,
363 struct usb_line6_pod *pod)
366 struct usb_line6 *line6 = &pod->line6;
368 init_timer(&pod->startup_timer);
369 INIT_WORK(&pod->startup_work, pod_startup4);
371 if ((interface == NULL) || (pod == NULL))
374 /* create sysfs entries: */
375 err = pod_create_files2(&interface->dev);
379 /* initialize audio system: */
380 err = line6_init_audio(line6);
384 /* initialize MIDI subsystem: */
385 err = line6_init_midi(line6);
389 /* initialize PCM subsystem: */
390 err = line6_init_pcm(line6, &pod_pcm_properties);
394 /* register monitor control: */
395 err = snd_ctl_add(line6->card,
396 snd_ctl_new1(&pod_control_monitor, line6->line6pcm));
401 When the sound card is registered at this point, the PODxt Live
402 displays "Invalid Code Error 07", so we do it later in the event
406 if (pod->line6.properties->capabilities & LINE6_BIT_CONTROL) {
407 pod->monitor_level = POD_SYSTEM_INVALID;
409 /* initiate startup procedure: */
417 Init POD device (and clean up in case of failure).
419 int line6_pod_init(struct usb_interface *interface, struct usb_line6_pod *pod)
421 int err = pod_try_init(interface, pod);
424 pod_destruct(interface);
430 POD device disconnected.
432 void line6_pod_disconnect(struct usb_interface *interface)
434 struct usb_line6_pod *pod;
436 if (interface == NULL)
438 pod = usb_get_intfdata(interface);
441 struct snd_line6_pcm *line6pcm = pod->line6.line6pcm;
442 struct device *dev = &interface->dev;
444 if (line6pcm != NULL)
445 line6_pcm_disconnect(line6pcm);
448 /* remove sysfs entries: */
449 device_remove_file(dev, &dev_attr_device_id);
450 device_remove_file(dev, &dev_attr_firmware_version);
451 device_remove_file(dev, &dev_attr_serial_number);
455 pod_destruct(interface);