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>
19 #define VARIAX_SYSEX_CODE 7
20 #define VARIAX_SYSEX_PARAM 0x3b
21 #define VARIAX_SYSEX_ACTIVATE 0x2a
22 #define VARIAX_MODEL_HEADER_LENGTH 7
23 #define VARIAX_MODEL_MESSAGE_LENGTH 199
24 #define VARIAX_OFFSET_ACTIVATE 7
27 This message is sent by the device during initialization and identifies
28 the connected guitar model.
30 static const char variax_init_model[] = {
31 0xf0, 0x00, 0x01, 0x0c, 0x07, 0x00, 0x69, 0x02,
36 This message is sent by the device during initialization and identifies
37 the connected guitar version.
39 static const char variax_init_version[] = {
40 0xf0, 0x7e, 0x7f, 0x06, 0x02, 0x00, 0x01, 0x0c,
41 0x07, 0x00, 0x00, 0x00
45 This message is the last one sent by the device during initialization.
47 static const char variax_init_done[] = {
48 0xf0, 0x00, 0x01, 0x0c, 0x07, 0x00, 0x6b
51 static const char variax_activate[] = {
52 0xf0, 0x00, 0x01, 0x0c, 0x07, 0x00, 0x2a, 0x01,
56 static const char variax_request_bank[] = {
57 0xf0, 0x00, 0x01, 0x0c, 0x07, 0x00, 0x6d, 0xf7
60 static const char variax_request_model1[] = {
61 0xf0, 0x00, 0x01, 0x0c, 0x07, 0x00, 0x3c, 0x00,
62 0x02, 0x00, 0x00, 0x00, 0x00, 0x03, 0x05, 0x03,
63 0x00, 0x00, 0x00, 0xf7
66 static const char variax_request_model2[] = {
67 0xf0, 0x00, 0x01, 0x0c, 0x07, 0x00, 0x3c, 0x00,
68 0x02, 0x00, 0x00, 0x00, 0x00, 0x03, 0x07, 0x03,
69 0x00, 0x00, 0x00, 0xf7
72 /* forward declarations: */
73 static int variax_create_files2(struct device *dev);
74 static void variax_startup2(unsigned long data);
75 static void variax_startup4(unsigned long data);
76 static void variax_startup5(unsigned long data);
79 Decode data transmitted by workbench.
81 static void variax_decode(const unsigned char *raw_data, unsigned char *data,
84 for (; raw_size > 0; raw_size -= 6) {
85 data[2] = raw_data[0] | (raw_data[1] << 4);
86 data[1] = raw_data[2] | (raw_data[3] << 4);
87 data[0] = raw_data[4] | (raw_data[5] << 4);
93 static void variax_activate_async(struct usb_line6_variax *variax, int a)
95 variax->buffer_activate[VARIAX_OFFSET_ACTIVATE] = a;
96 line6_send_raw_message_async(&variax->line6, variax->buffer_activate,
97 sizeof(variax_activate));
101 Variax startup procedure.
102 This is a sequence of functions with special requirements (e.g., must
103 not run immediately after initialization, must not run in interrupt
104 context). After the last one has finished, the device is ready to use.
107 static void variax_startup1(struct usb_line6_variax *variax)
109 CHECK_STARTUP_PROGRESS(variax->startup_progress, VARIAX_STARTUP_INIT);
111 /* delay startup procedure: */
112 line6_start_timer(&variax->startup_timer1, VARIAX_STARTUP_DELAY1,
113 variax_startup2, (unsigned long)variax);
116 static void variax_startup2(unsigned long data)
118 struct usb_line6_variax *variax = (struct usb_line6_variax *)data;
119 struct usb_line6 *line6 = &variax->line6;
121 /* schedule another startup procedure until startup is complete: */
122 if (variax->startup_progress >= VARIAX_STARTUP_LAST)
125 variax->startup_progress = VARIAX_STARTUP_VERSIONREQ;
126 line6_start_timer(&variax->startup_timer1, VARIAX_STARTUP_DELAY1,
127 variax_startup2, (unsigned long)variax);
129 /* request firmware version: */
130 line6_version_request_async(line6);
133 static void variax_startup3(struct usb_line6_variax *variax)
135 CHECK_STARTUP_PROGRESS(variax->startup_progress, VARIAX_STARTUP_WAIT);
137 /* delay startup procedure: */
138 line6_start_timer(&variax->startup_timer2, VARIAX_STARTUP_DELAY3,
139 variax_startup4, (unsigned long)variax);
142 static void variax_startup4(unsigned long data)
144 struct usb_line6_variax *variax = (struct usb_line6_variax *)data;
145 CHECK_STARTUP_PROGRESS(variax->startup_progress,
146 VARIAX_STARTUP_ACTIVATE);
148 /* activate device: */
149 variax_activate_async(variax, 1);
150 line6_start_timer(&variax->startup_timer2, VARIAX_STARTUP_DELAY4,
151 variax_startup5, (unsigned long)variax);
154 static void variax_startup5(unsigned long data)
156 struct usb_line6_variax *variax = (struct usb_line6_variax *)data;
157 CHECK_STARTUP_PROGRESS(variax->startup_progress,
158 VARIAX_STARTUP_DUMPREQ);
160 /* current model dump: */
161 line6_dump_request_async(&variax->dumpreq, &variax->line6, 0,
163 /* passes 2 and 3 are performed implicitly before entering
168 static void variax_startup6(struct usb_line6_variax *variax)
170 CHECK_STARTUP_PROGRESS(variax->startup_progress,
171 VARIAX_STARTUP_WORKQUEUE);
173 /* schedule work for global work queue: */
174 schedule_work(&variax->startup_work);
177 static void variax_startup7(struct work_struct *work)
179 struct usb_line6_variax *variax =
180 container_of(work, struct usb_line6_variax, startup_work);
181 struct usb_line6 *line6 = &variax->line6;
183 CHECK_STARTUP_PROGRESS(variax->startup_progress, VARIAX_STARTUP_SETUP);
185 /* ALSA audio interface: */
186 line6_register_audio(&variax->line6);
189 line6_variax_create_files(0, 0, line6->ifcdev);
190 variax_create_files2(line6->ifcdev);
194 Process a completely received message.
196 void line6_variax_process_message(struct usb_line6_variax *variax)
198 const unsigned char *buf = variax->line6.buffer_message;
201 case LINE6_PARAM_CHANGE | LINE6_CHANNEL_HOST:
203 case VARIAXMIDI_tone:
204 variax->tone = buf[2];
209 case LINE6_PROGRAM_CHANGE | LINE6_CHANNEL_DEVICE:
210 case LINE6_PROGRAM_CHANGE | LINE6_CHANNEL_HOST:
211 line6_dump_request_async(&variax->dumpreq, &variax->line6, 0,
216 dev_info(variax->line6.ifcdev, "VARIAX reset\n");
219 case LINE6_SYSEX_BEGIN:
220 if (memcmp(buf + 1, variax_request_model1 + 1,
221 VARIAX_MODEL_HEADER_LENGTH - 1) == 0) {
222 if (variax->line6.message_length ==
223 VARIAX_MODEL_MESSAGE_LENGTH) {
224 switch (variax->dumpreq.in_progress) {
225 case VARIAX_DUMP_PASS1:
227 VARIAX_MODEL_HEADER_LENGTH,
237 line6_dump_request_async
238 (&variax->dumpreq, &variax->line6,
239 1, VARIAX_DUMP_PASS2);
242 case VARIAX_DUMP_PASS2:
243 /* model name is transmitted twice, so skip it here: */
245 VARIAX_MODEL_HEADER_LENGTH,
249 sizeof(variax->model_data.
252 sizeof(variax->model_data.
255 line6_dump_request_async
256 (&variax->dumpreq, &variax->line6,
257 2, VARIAX_DUMP_PASS3);
260 dev_dbg(variax->line6.ifcdev,
261 "illegal length %d of model data\n",
262 variax->line6.message_length);
263 line6_dump_finished(&variax->dumpreq);
265 } else if (memcmp(buf + 1, variax_request_bank + 1,
266 sizeof(variax_request_bank) - 2) == 0) {
268 buf + sizeof(variax_request_bank) - 1,
269 sizeof(variax->bank));
270 line6_dump_finished(&variax->dumpreq);
271 variax_startup6(variax);
272 } else if (memcmp(buf + 1, variax_init_model + 1,
273 sizeof(variax_init_model) - 1) == 0) {
274 memcpy(variax->guitar,
275 buf + sizeof(variax_init_model),
276 sizeof(variax->guitar));
277 } else if (memcmp(buf + 1, variax_init_version + 1,
278 sizeof(variax_init_version) - 1) == 0) {
279 variax_startup3(variax);
280 } else if (memcmp(buf + 1, variax_init_done + 1,
281 sizeof(variax_init_done) - 1) == 0) {
282 /* notify of complete initialization: */
283 variax_startup4((unsigned long)variax);
288 case LINE6_SYSEX_END:
292 dev_dbg(variax->line6.ifcdev,
293 "Variax: unknown message %02X\n", buf[0]);
298 "read" request on "active" special file.
300 static ssize_t variax_get_active(struct device *dev,
301 struct device_attribute *attr, char *buf)
303 struct usb_line6_variax *variax =
304 usb_get_intfdata(to_usb_interface(dev));
305 return sprintf(buf, "%d\n",
306 variax->buffer_activate[VARIAX_OFFSET_ACTIVATE]);
310 "write" request on "active" special file.
312 static ssize_t variax_set_active(struct device *dev,
313 struct device_attribute *attr,
314 const char *buf, size_t count)
316 struct usb_line6_variax *variax =
317 usb_get_intfdata(to_usb_interface(dev));
321 ret = kstrtou8(buf, 10, &value);
325 variax_activate_async(variax, value ? 1 : 0);
330 "read" request on "tone" special file.
332 static ssize_t variax_get_tone(struct device *dev,
333 struct device_attribute *attr, char *buf)
335 struct usb_line6_variax *variax =
336 usb_get_intfdata(to_usb_interface(dev));
337 return sprintf(buf, "%d\n", variax->tone);
341 "write" request on "tone" special file.
343 static ssize_t variax_set_tone(struct device *dev,
344 struct device_attribute *attr,
345 const char *buf, size_t count)
347 struct usb_line6_variax *variax =
348 usb_get_intfdata(to_usb_interface(dev));
352 ret = kstrtou8(buf, 10, &value);
356 if (line6_transmit_parameter(&variax->line6, VARIAXMIDI_tone,
358 variax->tone = value;
363 static ssize_t get_string(char *buf, const char *data, int length)
366 memcpy(buf, data, length);
368 for (i = length; i--;) {
371 if ((c != 0) && (c != ' '))
380 "read" request on "name" special file.
382 static ssize_t variax_get_name(struct device *dev,
383 struct device_attribute *attr, char *buf)
385 struct usb_line6_variax *variax =
386 usb_get_intfdata(to_usb_interface(dev));
387 line6_dump_wait_interruptible(&variax->dumpreq);
388 return get_string(buf, variax->model_data.name,
389 sizeof(variax->model_data.name));
393 "read" request on "bank" special file.
395 static ssize_t variax_get_bank(struct device *dev,
396 struct device_attribute *attr, char *buf)
398 struct usb_line6_variax *variax =
399 usb_get_intfdata(to_usb_interface(dev));
400 line6_dump_wait_interruptible(&variax->dumpreq);
401 return get_string(buf, variax->bank, sizeof(variax->bank));
405 "read" request on "dump" special file.
407 static ssize_t variax_get_dump(struct device *dev,
408 struct device_attribute *attr, char *buf)
410 struct usb_line6_variax *variax =
411 usb_get_intfdata(to_usb_interface(dev));
413 retval = line6_dump_wait_interruptible(&variax->dumpreq);
416 memcpy(buf, &variax->model_data.control,
417 sizeof(variax->model_data.control));
418 return sizeof(variax->model_data.control);
422 "read" request on "guitar" special file.
424 static ssize_t variax_get_guitar(struct device *dev,
425 struct device_attribute *attr, char *buf)
427 struct usb_line6_variax *variax =
428 usb_get_intfdata(to_usb_interface(dev));
429 return sprintf(buf, "%s\n", variax->guitar);
432 #ifdef CONFIG_LINE6_USB_RAW
434 static char *variax_alloc_sysex_buffer(struct usb_line6_variax *variax,
437 return line6_alloc_sysex_buffer(&variax->line6, VARIAX_SYSEX_CODE, code,
442 "write" request on "raw" special file.
444 static ssize_t variax_set_raw2(struct device *dev,
445 struct device_attribute *attr,
446 const char *buf, size_t count)
448 struct usb_line6_variax *variax =
449 usb_get_intfdata(to_usb_interface(dev));
456 sysex = variax_alloc_sysex_buffer(variax, VARIAX_SYSEX_PARAM, size);
461 for (i = 0; i < count; i += 3) {
462 const unsigned char *p1 = buf + i;
463 char *p2 = sysex + SYSEX_DATA_OFS + i * 2;
464 p2[0] = p1[2] & 0x0f;
466 p2[2] = p1[1] & 0x0f;
468 p2[4] = p1[0] & 0x0f;
472 line6_send_sysex_message(&variax->line6, sysex, size);
479 /* Variax workbench special files: */
480 static DEVICE_ATTR(tone, S_IWUSR | S_IRUGO, variax_get_tone, variax_set_tone);
481 static DEVICE_ATTR(name, S_IRUGO, variax_get_name, line6_nop_write);
482 static DEVICE_ATTR(bank, S_IRUGO, variax_get_bank, line6_nop_write);
483 static DEVICE_ATTR(dump, S_IRUGO, variax_get_dump, line6_nop_write);
484 static DEVICE_ATTR(active, S_IWUSR | S_IRUGO, variax_get_active,
486 static DEVICE_ATTR(guitar, S_IRUGO, variax_get_guitar, line6_nop_write);
488 #ifdef CONFIG_LINE6_USB_RAW
489 static DEVICE_ATTR(raw, S_IWUSR, line6_nop_read, line6_set_raw);
490 static DEVICE_ATTR(raw2, S_IWUSR, line6_nop_read, variax_set_raw2);
496 static void variax_destruct(struct usb_interface *interface)
498 struct usb_line6_variax *variax = usb_get_intfdata(interface);
502 line6_cleanup_audio(&variax->line6);
504 del_timer(&variax->startup_timer1);
505 del_timer(&variax->startup_timer2);
506 cancel_work_sync(&variax->startup_work);
508 /* free dump request data: */
509 line6_dumpreq_destructbuf(&variax->dumpreq, 2);
510 line6_dumpreq_destructbuf(&variax->dumpreq, 1);
511 line6_dumpreq_destruct(&variax->dumpreq);
513 kfree(variax->buffer_activate);
517 Create sysfs entries.
519 static int variax_create_files2(struct device *dev)
522 CHECK_RETURN(device_create_file(dev, &dev_attr_tone));
523 CHECK_RETURN(device_create_file(dev, &dev_attr_name));
524 CHECK_RETURN(device_create_file(dev, &dev_attr_bank));
525 CHECK_RETURN(device_create_file(dev, &dev_attr_dump));
526 CHECK_RETURN(device_create_file(dev, &dev_attr_active));
527 CHECK_RETURN(device_create_file(dev, &dev_attr_guitar));
528 #ifdef CONFIG_LINE6_USB_RAW
529 CHECK_RETURN(device_create_file(dev, &dev_attr_raw));
530 CHECK_RETURN(device_create_file(dev, &dev_attr_raw2));
536 Try to init workbench device.
538 static int variax_try_init(struct usb_interface *interface,
539 struct usb_line6_variax *variax)
543 init_timer(&variax->startup_timer1);
544 init_timer(&variax->startup_timer2);
545 INIT_WORK(&variax->startup_work, variax_startup7);
547 if ((interface == NULL) || (variax == NULL))
550 /* initialize USB buffers: */
551 err = line6_dumpreq_init(&variax->dumpreq, variax_request_model1,
552 sizeof(variax_request_model1));
555 dev_err(&interface->dev, "Out of memory\n");
559 err = line6_dumpreq_initbuf(&variax->dumpreq, variax_request_model2,
560 sizeof(variax_request_model2), 1);
563 dev_err(&interface->dev, "Out of memory\n");
567 err = line6_dumpreq_initbuf(&variax->dumpreq, variax_request_bank,
568 sizeof(variax_request_bank), 2);
571 dev_err(&interface->dev, "Out of memory\n");
575 variax->buffer_activate = kmemdup(variax_activate,
576 sizeof(variax_activate), GFP_KERNEL);
578 if (variax->buffer_activate == NULL) {
579 dev_err(&interface->dev, "Out of memory\n");
583 /* initialize audio system: */
584 err = line6_init_audio(&variax->line6);
588 /* initialize MIDI subsystem: */
589 err = line6_init_midi(&variax->line6);
593 /* initiate startup procedure: */
594 variax_startup1(variax);
599 Init workbench device (and clean up in case of failure).
601 int line6_variax_init(struct usb_interface *interface,
602 struct usb_line6_variax *variax)
604 int err = variax_try_init(interface, variax);
607 variax_destruct(interface);
613 Workbench device disconnected.
615 void line6_variax_disconnect(struct usb_interface *interface)
619 if (interface == NULL)
621 dev = &interface->dev;
624 /* remove sysfs entries: */
625 line6_variax_remove_files(0, 0, dev);
626 device_remove_file(dev, &dev_attr_tone);
627 device_remove_file(dev, &dev_attr_name);
628 device_remove_file(dev, &dev_attr_bank);
629 device_remove_file(dev, &dev_attr_dump);
630 device_remove_file(dev, &dev_attr_active);
631 device_remove_file(dev, &dev_attr_guitar);
632 #ifdef CONFIG_LINE6_USB_RAW
633 device_remove_file(dev, &dev_attr_raw);
634 device_remove_file(dev, &dev_attr_raw2);
638 variax_destruct(interface);