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 serial_number_show(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);
201 return sprintf(buf, "%d\n", pod->serial_number);
205 "read" request on "firmware_version" special file.
207 static ssize_t firmware_version_show(struct device *dev,
208 struct device_attribute *attr, char *buf)
210 struct usb_interface *interface = to_usb_interface(dev);
211 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 device_id_show(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);
226 return sprintf(buf, "%d\n", pod->device_id);
230 POD startup procedure.
231 This is a sequence of functions with special requirements (e.g., must
232 not run immediately after initialization, must not run in interrupt
233 context). After the last one has finished, the device is ready to use.
236 static void pod_startup1(struct usb_line6_pod *pod)
238 CHECK_STARTUP_PROGRESS(pod->startup_progress, POD_STARTUP_INIT);
240 /* delay startup procedure: */
241 line6_start_timer(&pod->startup_timer, POD_STARTUP_DELAY, pod_startup2,
245 static void pod_startup2(unsigned long data)
247 struct usb_line6_pod *pod = (struct usb_line6_pod *)data;
248 struct usb_line6 *line6 = &pod->line6;
250 CHECK_STARTUP_PROGRESS(pod->startup_progress, POD_STARTUP_VERSIONREQ);
252 /* request firmware version: */
253 line6_version_request_async(line6);
256 static void pod_startup3(struct usb_line6_pod *pod)
258 CHECK_STARTUP_PROGRESS(pod->startup_progress, POD_STARTUP_WORKQUEUE);
260 /* schedule work for global work queue: */
261 schedule_work(&pod->startup_work);
264 static void pod_startup4(struct work_struct *work)
266 struct usb_line6_pod *pod =
267 container_of(work, struct usb_line6_pod, startup_work);
268 struct usb_line6 *line6 = &pod->line6;
270 CHECK_STARTUP_PROGRESS(pod->startup_progress, POD_STARTUP_SETUP);
273 line6_read_serial_number(&pod->line6, &pod->serial_number);
275 /* ALSA audio interface: */
276 line6_register_audio(line6);
279 /* POD special files: */
280 static DEVICE_ATTR_RO(device_id);
281 static DEVICE_ATTR_RO(firmware_version);
282 static DEVICE_ATTR_RO(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;
302 ucontrol->value.integer.value[0] = pod->monitor_level;
306 /* control put callback */
307 static int snd_pod_control_monitor_put(struct snd_kcontrol *kcontrol,
308 struct snd_ctl_elem_value *ucontrol)
310 struct snd_line6_pcm *line6pcm = snd_kcontrol_chip(kcontrol);
311 struct usb_line6_pod *pod = (struct usb_line6_pod *)line6pcm->line6;
313 if (ucontrol->value.integer.value[0] == pod->monitor_level)
316 pod->monitor_level = ucontrol->value.integer.value[0];
317 pod_set_system_param_int(pod, ucontrol->value.integer.value[0],
322 /* control definition */
323 static struct snd_kcontrol_new pod_control_monitor = {
324 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
325 .name = "Monitor Playback Volume",
327 .access = SNDRV_CTL_ELEM_ACCESS_READWRITE,
328 .info = snd_pod_control_monitor_info,
329 .get = snd_pod_control_monitor_get,
330 .put = snd_pod_control_monitor_put
336 static void pod_destruct(struct usb_interface *interface)
338 struct usb_line6_pod *pod = usb_get_intfdata(interface);
342 line6_cleanup_audio(&pod->line6);
344 del_timer(&pod->startup_timer);
345 cancel_work_sync(&pod->startup_work);
349 Create sysfs entries.
351 static int pod_create_files2(struct device *dev)
355 CHECK_RETURN(device_create_file(dev, &dev_attr_device_id));
356 CHECK_RETURN(device_create_file(dev, &dev_attr_firmware_version));
357 CHECK_RETURN(device_create_file(dev, &dev_attr_serial_number));
362 Try to init POD device.
364 static int pod_try_init(struct usb_interface *interface,
365 struct usb_line6_pod *pod)
368 struct usb_line6 *line6 = &pod->line6;
370 init_timer(&pod->startup_timer);
371 INIT_WORK(&pod->startup_work, pod_startup4);
373 if ((interface == NULL) || (pod == NULL))
376 /* create sysfs entries: */
377 err = pod_create_files2(&interface->dev);
381 /* initialize audio system: */
382 err = line6_init_audio(line6);
386 /* initialize MIDI subsystem: */
387 err = line6_init_midi(line6);
391 /* initialize PCM subsystem: */
392 err = line6_init_pcm(line6, &pod_pcm_properties);
396 /* register monitor control: */
397 err = snd_ctl_add(line6->card,
398 snd_ctl_new1(&pod_control_monitor, line6->line6pcm));
403 When the sound card is registered at this point, the PODxt Live
404 displays "Invalid Code Error 07", so we do it later in the event
408 if (pod->line6.properties->capabilities & LINE6_BIT_CONTROL) {
409 pod->monitor_level = POD_SYSTEM_INVALID;
411 /* initiate startup procedure: */
419 Init POD device (and clean up in case of failure).
421 int line6_pod_init(struct usb_interface *interface, struct usb_line6_pod *pod)
423 int err = pod_try_init(interface, pod);
426 pod_destruct(interface);
432 POD device disconnected.
434 void line6_pod_disconnect(struct usb_interface *interface)
436 struct usb_line6_pod *pod;
438 if (interface == NULL)
440 pod = usb_get_intfdata(interface);
443 struct snd_line6_pcm *line6pcm = pod->line6.line6pcm;
444 struct device *dev = &interface->dev;
446 if (line6pcm != NULL)
447 line6_pcm_disconnect(line6pcm);
450 /* remove sysfs entries: */
451 device_remove_file(dev, &dev_attr_device_id);
452 device_remove_file(dev, &dev_attr_firmware_version);
453 device_remove_file(dev, &dev_attr_serial_number);
457 pod_destruct(interface);