2 * Line6 Linux USB driver - 0.9.0
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>
20 #define VARIAX_SYSEX_CODE 7
21 #define VARIAX_SYSEX_PARAM 0x3b
22 #define VARIAX_SYSEX_ACTIVATE 0x2a
23 #define VARIAX_MODEL_HEADER_LENGTH 7
24 #define VARIAX_MODEL_MESSAGE_LENGTH 199
25 #define VARIAX_OFFSET_ACTIVATE 7
29 This message is sent by the device during initialization and identifies
30 the connected guitar model.
32 static const char variax_init_model[] = {
33 0xf0, 0x00, 0x01, 0x0c, 0x07, 0x00, 0x69, 0x02,
38 This message is sent by the device during initialization and identifies
39 the connected guitar version.
41 static const char variax_init_version[] = {
42 0xf0, 0x7e, 0x7f, 0x06, 0x02, 0x00, 0x01, 0x0c,
43 0x07, 0x00, 0x00, 0x00
47 This message is the last one sent by the device during initialization.
49 static const char variax_init_done[] = {
50 0xf0, 0x00, 0x01, 0x0c, 0x07, 0x00, 0x6b
53 static const char variax_activate[] = {
54 0xf0, 0x00, 0x01, 0x0c, 0x07, 0x00, 0x2a, 0x01,
58 static const char variax_request_bank[] = {
59 0xf0, 0x00, 0x01, 0x0c, 0x07, 0x00, 0x6d, 0xf7
62 static const char variax_request_model1[] = {
63 0xf0, 0x00, 0x01, 0x0c, 0x07, 0x00, 0x3c, 0x00,
64 0x02, 0x00, 0x00, 0x00, 0x00, 0x03, 0x05, 0x03,
65 0x00, 0x00, 0x00, 0xf7
68 static const char variax_request_model2[] = {
69 0xf0, 0x00, 0x01, 0x0c, 0x07, 0x00, 0x3c, 0x00,
70 0x02, 0x00, 0x00, 0x00, 0x00, 0x03, 0x07, 0x03,
71 0x00, 0x00, 0x00, 0xf7
75 /* forward declarations: */
76 static int variax_create_files2(struct device *dev);
77 static void variax_startup2(unsigned long data);
78 static void variax_startup4(unsigned long data);
79 static void variax_startup5(unsigned long data);
83 Decode data transmitted by workbench.
85 static void variax_decode(const unsigned char *raw_data, unsigned char *data,
88 for (; raw_size > 0; raw_size -= 6) {
89 data[2] = raw_data[0] | (raw_data[1] << 4);
90 data[1] = raw_data[2] | (raw_data[3] << 4);
91 data[0] = raw_data[4] | (raw_data[5] << 4);
97 static void variax_activate_async(struct usb_line6_variax *variax, int a)
99 variax->buffer_activate[VARIAX_OFFSET_ACTIVATE] = a;
100 line6_send_raw_message_async(&variax->line6, variax->buffer_activate,
101 sizeof(variax_activate));
105 Variax startup procedure.
106 This is a sequence of functions with special requirements (e.g., must
107 not run immediately after initialization, must not run in interrupt
108 context). After the last one has finished, the device is ready to use.
111 static void variax_startup1(struct usb_line6_variax *variax)
113 CHECK_STARTUP_PROGRESS(variax->startup_progress, 1);
115 /* delay startup procedure: */
116 line6_start_timer(&variax->startup_timer, VARIAX_STARTUP_DELAY1, variax_startup2, (unsigned long)variax);
119 static void variax_startup2(unsigned long data)
121 struct usb_line6_variax *variax = (struct usb_line6_variax *)data;
122 struct usb_line6 *line6 = &variax->line6;
123 CHECK_STARTUP_PROGRESS(variax->startup_progress, 2);
125 /* request firmware version: */
126 line6_version_request_async(line6);
129 static void variax_startup3(struct usb_line6_variax *variax)
131 CHECK_STARTUP_PROGRESS(variax->startup_progress, 3);
133 /* delay startup procedure: */
134 line6_start_timer(&variax->startup_timer, VARIAX_STARTUP_DELAY3, variax_startup4, (unsigned long)variax);
137 static void variax_startup4(unsigned long data)
139 struct usb_line6_variax *variax = (struct usb_line6_variax *)data;
140 CHECK_STARTUP_PROGRESS(variax->startup_progress, 4);
142 /* activate device: */
143 variax_activate_async(variax, 1);
144 line6_start_timer(&variax->startup_timer, VARIAX_STARTUP_DELAY4, variax_startup5, (unsigned long)variax);
147 static void variax_startup5(unsigned long data)
149 struct usb_line6_variax *variax = (struct usb_line6_variax *)data;
150 CHECK_STARTUP_PROGRESS(variax->startup_progress, 5);
152 /* current model dump: */
153 line6_dump_request_async(&variax->dumpreq, &variax->line6, 0, VARIAX_DUMP_PASS1);
154 /* passes 2 and 3 are performed implicitly before entering variax_startup6 */
157 static void variax_startup6(struct usb_line6_variax *variax)
159 CHECK_STARTUP_PROGRESS(variax->startup_progress, 6);
161 /* schedule work for global work queue: */
162 schedule_work(&variax->startup_work);
165 static void variax_startup7(struct work_struct *work)
167 struct usb_line6_variax *variax = container_of(work, struct usb_line6_variax, startup_work);
168 struct usb_line6 *line6 = &variax->line6;
170 CHECK_STARTUP_PROGRESS(variax->startup_progress, 7);
172 /* ALSA audio interface: */
173 line6_register_audio(&variax->line6);
176 line6_variax_create_files(0, 0, line6->ifcdev);
177 variax_create_files2(line6->ifcdev);
181 Process a completely received message.
183 void line6_variax_process_message(struct usb_line6_variax *variax)
185 const unsigned char *buf = variax->line6.buffer_message;
188 case LINE6_PARAM_CHANGE | LINE6_CHANNEL_HOST:
190 case VARIAXMIDI_volume:
191 variax->volume = buf[2];
194 case VARIAXMIDI_tone:
195 variax->tone = buf[2];
200 case LINE6_PROGRAM_CHANGE | LINE6_CHANNEL_DEVICE:
201 case LINE6_PROGRAM_CHANGE | LINE6_CHANNEL_HOST:
202 variax->model = buf[1];
203 line6_dump_request_async(&variax->dumpreq, &variax->line6, 0, VARIAX_DUMP_PASS1);
207 dev_info(variax->line6.ifcdev, "VARIAX reset\n");
210 case LINE6_SYSEX_BEGIN:
211 if (memcmp(buf + 1, variax_request_model1 + 1,
212 VARIAX_MODEL_HEADER_LENGTH - 1) == 0) {
213 if (variax->line6.message_length ==
214 VARIAX_MODEL_MESSAGE_LENGTH) {
215 switch (variax->dumpreq.in_progress) {
216 case VARIAX_DUMP_PASS1:
217 variax_decode(buf + VARIAX_MODEL_HEADER_LENGTH, (unsigned char *)&variax->model_data,
218 (sizeof(variax->model_data.name) + sizeof(variax->model_data.control) / 2) * 2);
219 line6_dump_request_async(&variax->dumpreq, &variax->line6, 1, VARIAX_DUMP_PASS2);
222 case VARIAX_DUMP_PASS2:
223 /* model name is transmitted twice, so skip it here: */
224 variax_decode(buf + VARIAX_MODEL_HEADER_LENGTH,
225 (unsigned char *)&variax->model_data.control + sizeof(variax->model_data.control) / 2,
226 sizeof(variax->model_data.control) / 2 * 2);
227 line6_dump_request_async(&variax->dumpreq, &variax->line6, 2, VARIAX_DUMP_PASS3);
230 DEBUG_MESSAGES(dev_err(variax->line6.ifcdev, "illegal length %d of model data\n", variax->line6.message_length));
231 line6_dump_finished(&variax->dumpreq);
233 } else if (memcmp(buf + 1, variax_request_bank + 1,
234 sizeof(variax_request_bank) - 2) == 0) {
236 buf + sizeof(variax_request_bank) - 1,
237 sizeof(variax->bank));
238 line6_dump_finished(&variax->dumpreq);
239 variax_startup6(variax);
240 } else if (memcmp(buf + 1, variax_init_model + 1,
241 sizeof(variax_init_model) - 1) == 0) {
242 memcpy(variax->guitar,
243 buf + sizeof(variax_init_model),
244 sizeof(variax->guitar));
245 } else if (memcmp(buf + 1, variax_init_version + 1,
246 sizeof(variax_init_version) - 1) == 0) {
247 variax_startup3(variax);
248 } else if (memcmp(buf + 1, variax_init_done + 1,
249 sizeof(variax_init_done) - 1) == 0) {
250 /* notify of complete initialization: */
251 variax_startup4((unsigned long)variax);
256 case LINE6_SYSEX_END:
260 DEBUG_MESSAGES(dev_err(variax->line6.ifcdev, "Variax: unknown message %02X\n", buf[0]));
265 "read" request on "volume" special file.
267 static ssize_t variax_get_volume(struct device *dev,
268 struct device_attribute *attr, char *buf)
270 struct usb_line6_variax *variax = usb_get_intfdata(to_usb_interface(dev));
271 return sprintf(buf, "%d\n", variax->volume);
275 "write" request on "volume" special file.
277 static ssize_t variax_set_volume(struct device *dev,
278 struct device_attribute *attr,
279 const char *buf, size_t count)
281 struct usb_line6_variax *variax = usb_get_intfdata(to_usb_interface(dev));
285 ret = strict_strtoul(buf, 10, &value);
289 if (line6_transmit_parameter(&variax->line6, VARIAXMIDI_volume,
291 variax->volume = value;
297 "read" request on "model" special file.
299 static ssize_t variax_get_model(struct device *dev,
300 struct device_attribute *attr, char *buf)
302 struct usb_line6_variax *variax = usb_get_intfdata(to_usb_interface(dev));
303 return sprintf(buf, "%d\n", variax->model);
307 "write" request on "model" special file.
309 static ssize_t variax_set_model(struct device *dev,
310 struct device_attribute *attr,
311 const char *buf, size_t count)
313 struct usb_line6_variax *variax = usb_get_intfdata(to_usb_interface(dev));
317 ret = strict_strtoul(buf, 10, &value);
321 if (line6_send_program(&variax->line6, value) == 0)
322 variax->model = value;
328 "read" request on "active" special file.
330 static ssize_t variax_get_active(struct device *dev,
331 struct device_attribute *attr, char *buf)
333 struct usb_line6_variax *variax = usb_get_intfdata(to_usb_interface(dev));
334 return sprintf(buf, "%d\n", variax->buffer_activate[VARIAX_OFFSET_ACTIVATE]);
338 "write" request on "active" special file.
340 static ssize_t variax_set_active(struct device *dev,
341 struct device_attribute *attr,
342 const char *buf, size_t count)
344 struct usb_line6_variax *variax = usb_get_intfdata(to_usb_interface(dev));
348 ret = strict_strtoul(buf, 10, &value);
352 variax_activate_async(variax, value ? 1 : 0);
357 "read" request on "tone" special file.
359 static ssize_t variax_get_tone(struct device *dev,
360 struct device_attribute *attr, char *buf)
362 struct usb_line6_variax *variax = usb_get_intfdata(to_usb_interface(dev));
363 return sprintf(buf, "%d\n", variax->tone);
367 "write" request on "tone" special file.
369 static ssize_t variax_set_tone(struct device *dev,
370 struct device_attribute *attr,
371 const char *buf, size_t count)
373 struct usb_line6_variax *variax = usb_get_intfdata(to_usb_interface(dev));
377 ret = strict_strtoul(buf, 10, &value);
381 if (line6_transmit_parameter(&variax->line6, VARIAXMIDI_tone,
383 variax->tone = value;
388 static ssize_t get_string(char *buf, const char *data, int length)
391 memcpy(buf, data, length);
393 for (i = length; i--;) {
396 if ((c != 0) && (c != ' '))
405 "read" request on "name" special file.
407 static ssize_t variax_get_name(struct device *dev,
408 struct device_attribute *attr, char *buf)
410 struct usb_line6_variax *variax = usb_get_intfdata(to_usb_interface(dev));
411 line6_dump_wait_interruptible(&variax->dumpreq);
412 return get_string(buf, variax->model_data.name,
413 sizeof(variax->model_data.name));
417 "read" request on "bank" special file.
419 static ssize_t variax_get_bank(struct device *dev,
420 struct device_attribute *attr, char *buf)
422 struct usb_line6_variax *variax = usb_get_intfdata(to_usb_interface(dev));
423 line6_dump_wait_interruptible(&variax->dumpreq);
424 return get_string(buf, variax->bank, sizeof(variax->bank));
428 "read" request on "dump" special file.
430 static ssize_t variax_get_dump(struct device *dev,
431 struct device_attribute *attr, char *buf)
433 struct usb_line6_variax *variax = usb_get_intfdata(to_usb_interface(dev));
435 retval = line6_dump_wait_interruptible(&variax->dumpreq);
438 memcpy(buf, &variax->model_data.control,
439 sizeof(variax->model_data.control));
440 return sizeof(variax->model_data.control);
444 "read" request on "guitar" special file.
446 static ssize_t variax_get_guitar(struct device *dev,
447 struct device_attribute *attr, char *buf)
449 struct usb_line6_variax *variax = usb_get_intfdata(to_usb_interface(dev));
450 return sprintf(buf, "%s\n", variax->guitar);
453 #ifdef CONFIG_LINE6_USB_RAW
455 static char *variax_alloc_sysex_buffer(struct usb_line6_variax *variax, int code, int size)
457 return line6_alloc_sysex_buffer(&variax->line6, VARIAX_SYSEX_CODE, code, size);
461 "write" request on "raw" special file.
463 static ssize_t variax_set_raw2(struct device *dev,
464 struct device_attribute *attr,
465 const char *buf, size_t count)
467 struct usb_line6_variax *variax = usb_get_intfdata(to_usb_interface(dev));
474 sysex = variax_alloc_sysex_buffer(variax, VARIAX_SYSEX_PARAM, size);
479 for (i = 0; i < count; i += 3) {
480 const unsigned char *p1 = buf + i;
481 char *p2 = sysex + SYSEX_DATA_OFS + i * 2;
482 p2[0] = p1[2] & 0x0f;
484 p2[2] = p1[1] & 0x0f;
486 p2[4] = p1[0] & 0x0f;
490 line6_send_sysex_message(&variax->line6, sysex, size);
497 /* Variax workbench special files: */
498 static DEVICE_ATTR(model, S_IWUGO | S_IRUGO, variax_get_model, variax_set_model);
499 static DEVICE_ATTR(volume, S_IWUGO | S_IRUGO, variax_get_volume, variax_set_volume);
500 static DEVICE_ATTR(tone, S_IWUGO | S_IRUGO, variax_get_tone, variax_set_tone);
501 static DEVICE_ATTR(name, S_IRUGO, variax_get_name, line6_nop_write);
502 static DEVICE_ATTR(bank, S_IRUGO, variax_get_bank, line6_nop_write);
503 static DEVICE_ATTR(dump, S_IRUGO, variax_get_dump, line6_nop_write);
504 static DEVICE_ATTR(active, S_IWUGO | S_IRUGO, variax_get_active, variax_set_active);
505 static DEVICE_ATTR(guitar, S_IRUGO, variax_get_guitar, line6_nop_write);
507 #ifdef CONFIG_LINE6_USB_RAW
508 static DEVICE_ATTR(raw, S_IWUGO, line6_nop_read, line6_set_raw);
509 static DEVICE_ATTR(raw2, S_IWUGO, line6_nop_read, variax_set_raw2);
516 static void variax_destruct(struct usb_interface *interface)
518 struct usb_line6_variax *variax = usb_get_intfdata(interface);
519 struct usb_line6 *line6;
523 line6 = &variax->line6;
526 line6_cleanup_audio(line6);
528 /* free dump request data: */
529 line6_dumpreq_destructbuf(&variax->dumpreq, 2);
530 line6_dumpreq_destructbuf(&variax->dumpreq, 1);
531 line6_dumpreq_destruct(&variax->dumpreq);
533 kfree(variax->buffer_activate);
537 Create sysfs entries.
539 static int variax_create_files2(struct device *dev)
542 CHECK_RETURN(device_create_file(dev, &dev_attr_model));
543 CHECK_RETURN(device_create_file(dev, &dev_attr_volume));
544 CHECK_RETURN(device_create_file(dev, &dev_attr_tone));
545 CHECK_RETURN(device_create_file(dev, &dev_attr_name));
546 CHECK_RETURN(device_create_file(dev, &dev_attr_bank));
547 CHECK_RETURN(device_create_file(dev, &dev_attr_dump));
548 CHECK_RETURN(device_create_file(dev, &dev_attr_active));
549 CHECK_RETURN(device_create_file(dev, &dev_attr_guitar));
550 #ifdef CONFIG_LINE6_USB_RAW
551 CHECK_RETURN(device_create_file(dev, &dev_attr_raw));
552 CHECK_RETURN(device_create_file(dev, &dev_attr_raw2));
558 Try to init workbench device.
560 static int variax_try_init(struct usb_interface *interface,
561 struct usb_line6_variax *variax)
565 if ((interface == NULL) || (variax == NULL))
568 init_timer(&variax->startup_timer);
569 INIT_WORK(&variax->startup_work, variax_startup7);
571 /* initialize USB buffers: */
572 err = line6_dumpreq_init(&variax->dumpreq, variax_request_model1,
573 sizeof(variax_request_model1));
576 dev_err(&interface->dev, "Out of memory\n");
580 err = line6_dumpreq_initbuf(&variax->dumpreq, variax_request_model2,
581 sizeof(variax_request_model2), 1);
584 dev_err(&interface->dev, "Out of memory\n");
588 err = line6_dumpreq_initbuf(&variax->dumpreq, variax_request_bank,
589 sizeof(variax_request_bank), 2);
592 dev_err(&interface->dev, "Out of memory\n");
596 variax->buffer_activate = kmemdup(variax_activate,
597 sizeof(variax_activate), GFP_KERNEL);
599 if (variax->buffer_activate == NULL) {
600 dev_err(&interface->dev, "Out of memory\n");
604 /* initialize audio system: */
605 err = line6_init_audio(&variax->line6);
610 /* initialize MIDI subsystem: */
611 err = line6_init_midi(&variax->line6);
616 /* initiate startup procedure: */
617 variax_startup1(variax);
622 Init workbench device (and clean up in case of failure).
624 int line6_variax_init(struct usb_interface *interface,
625 struct usb_line6_variax *variax)
627 int err = variax_try_init(interface, variax);
630 variax_destruct(interface);
637 Workbench device disconnected.
639 void line6_variax_disconnect(struct usb_interface *interface)
643 if (interface == NULL)
645 dev = &interface->dev;
648 /* remove sysfs entries: */
649 line6_variax_remove_files(0, 0, dev);
650 device_remove_file(dev, &dev_attr_model);
651 device_remove_file(dev, &dev_attr_volume);
652 device_remove_file(dev, &dev_attr_tone);
653 device_remove_file(dev, &dev_attr_name);
654 device_remove_file(dev, &dev_attr_bank);
655 device_remove_file(dev, &dev_attr_dump);
656 device_remove_file(dev, &dev_attr_active);
657 device_remove_file(dev, &dev_attr_guitar);
658 #ifdef CONFIG_LINE6_USB_RAW
659 device_remove_file(dev, &dev_attr_raw);
660 device_remove_file(dev, &dev_attr_raw2);
664 variax_destruct(interface);