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_volume:
204 variax->volume = buf[2];
207 case VARIAXMIDI_tone:
208 variax->tone = buf[2];
213 case LINE6_PROGRAM_CHANGE | LINE6_CHANNEL_DEVICE:
214 case LINE6_PROGRAM_CHANGE | LINE6_CHANNEL_HOST:
215 line6_dump_request_async(&variax->dumpreq, &variax->line6, 0,
220 dev_info(variax->line6.ifcdev, "VARIAX reset\n");
223 case LINE6_SYSEX_BEGIN:
224 if (memcmp(buf + 1, variax_request_model1 + 1,
225 VARIAX_MODEL_HEADER_LENGTH - 1) == 0) {
226 if (variax->line6.message_length ==
227 VARIAX_MODEL_MESSAGE_LENGTH) {
228 switch (variax->dumpreq.in_progress) {
229 case VARIAX_DUMP_PASS1:
231 VARIAX_MODEL_HEADER_LENGTH,
241 line6_dump_request_async
242 (&variax->dumpreq, &variax->line6,
243 1, VARIAX_DUMP_PASS2);
246 case VARIAX_DUMP_PASS2:
247 /* model name is transmitted twice, so skip it here: */
249 VARIAX_MODEL_HEADER_LENGTH,
253 sizeof(variax->model_data.
256 sizeof(variax->model_data.
259 line6_dump_request_async
260 (&variax->dumpreq, &variax->line6,
261 2, VARIAX_DUMP_PASS3);
264 dev_dbg(variax->line6.ifcdev,
265 "illegal length %d of model data\n",
266 variax->line6.message_length);
267 line6_dump_finished(&variax->dumpreq);
269 } else if (memcmp(buf + 1, variax_request_bank + 1,
270 sizeof(variax_request_bank) - 2) == 0) {
272 buf + sizeof(variax_request_bank) - 1,
273 sizeof(variax->bank));
274 line6_dump_finished(&variax->dumpreq);
275 variax_startup6(variax);
276 } else if (memcmp(buf + 1, variax_init_model + 1,
277 sizeof(variax_init_model) - 1) == 0) {
278 memcpy(variax->guitar,
279 buf + sizeof(variax_init_model),
280 sizeof(variax->guitar));
281 } else if (memcmp(buf + 1, variax_init_version + 1,
282 sizeof(variax_init_version) - 1) == 0) {
283 variax_startup3(variax);
284 } else if (memcmp(buf + 1, variax_init_done + 1,
285 sizeof(variax_init_done) - 1) == 0) {
286 /* notify of complete initialization: */
287 variax_startup4((unsigned long)variax);
292 case LINE6_SYSEX_END:
296 dev_dbg(variax->line6.ifcdev,
297 "Variax: unknown message %02X\n", buf[0]);
302 "read" request on "volume" special file.
304 static ssize_t variax_get_volume(struct device *dev,
305 struct device_attribute *attr, char *buf)
307 struct usb_line6_variax *variax =
308 usb_get_intfdata(to_usb_interface(dev));
309 return sprintf(buf, "%d\n", variax->volume);
313 "write" request on "volume" special file.
315 static ssize_t variax_set_volume(struct device *dev,
316 struct device_attribute *attr,
317 const char *buf, size_t count)
319 struct usb_line6_variax *variax =
320 usb_get_intfdata(to_usb_interface(dev));
324 ret = kstrtou8(buf, 10, &value);
328 if (line6_transmit_parameter(&variax->line6, VARIAXMIDI_volume,
330 variax->volume = value;
336 "read" request on "active" special file.
338 static ssize_t variax_get_active(struct device *dev,
339 struct device_attribute *attr, char *buf)
341 struct usb_line6_variax *variax =
342 usb_get_intfdata(to_usb_interface(dev));
343 return sprintf(buf, "%d\n",
344 variax->buffer_activate[VARIAX_OFFSET_ACTIVATE]);
348 "write" request on "active" special file.
350 static ssize_t variax_set_active(struct device *dev,
351 struct device_attribute *attr,
352 const char *buf, size_t count)
354 struct usb_line6_variax *variax =
355 usb_get_intfdata(to_usb_interface(dev));
359 ret = kstrtou8(buf, 10, &value);
363 variax_activate_async(variax, value ? 1 : 0);
368 "read" request on "tone" special file.
370 static ssize_t variax_get_tone(struct device *dev,
371 struct device_attribute *attr, char *buf)
373 struct usb_line6_variax *variax =
374 usb_get_intfdata(to_usb_interface(dev));
375 return sprintf(buf, "%d\n", variax->tone);
379 "write" request on "tone" special file.
381 static ssize_t variax_set_tone(struct device *dev,
382 struct device_attribute *attr,
383 const char *buf, size_t count)
385 struct usb_line6_variax *variax =
386 usb_get_intfdata(to_usb_interface(dev));
390 ret = kstrtou8(buf, 10, &value);
394 if (line6_transmit_parameter(&variax->line6, VARIAXMIDI_tone,
396 variax->tone = value;
401 static ssize_t get_string(char *buf, const char *data, int length)
404 memcpy(buf, data, length);
406 for (i = length; i--;) {
409 if ((c != 0) && (c != ' '))
418 "read" request on "name" special file.
420 static ssize_t variax_get_name(struct device *dev,
421 struct device_attribute *attr, char *buf)
423 struct usb_line6_variax *variax =
424 usb_get_intfdata(to_usb_interface(dev));
425 line6_dump_wait_interruptible(&variax->dumpreq);
426 return get_string(buf, variax->model_data.name,
427 sizeof(variax->model_data.name));
431 "read" request on "bank" special file.
433 static ssize_t variax_get_bank(struct device *dev,
434 struct device_attribute *attr, char *buf)
436 struct usb_line6_variax *variax =
437 usb_get_intfdata(to_usb_interface(dev));
438 line6_dump_wait_interruptible(&variax->dumpreq);
439 return get_string(buf, variax->bank, sizeof(variax->bank));
443 "read" request on "dump" special file.
445 static ssize_t variax_get_dump(struct device *dev,
446 struct device_attribute *attr, char *buf)
448 struct usb_line6_variax *variax =
449 usb_get_intfdata(to_usb_interface(dev));
451 retval = line6_dump_wait_interruptible(&variax->dumpreq);
454 memcpy(buf, &variax->model_data.control,
455 sizeof(variax->model_data.control));
456 return sizeof(variax->model_data.control);
460 "read" request on "guitar" special file.
462 static ssize_t variax_get_guitar(struct device *dev,
463 struct device_attribute *attr, char *buf)
465 struct usb_line6_variax *variax =
466 usb_get_intfdata(to_usb_interface(dev));
467 return sprintf(buf, "%s\n", variax->guitar);
470 #ifdef CONFIG_LINE6_USB_RAW
472 static char *variax_alloc_sysex_buffer(struct usb_line6_variax *variax,
475 return line6_alloc_sysex_buffer(&variax->line6, VARIAX_SYSEX_CODE, code,
480 "write" request on "raw" special file.
482 static ssize_t variax_set_raw2(struct device *dev,
483 struct device_attribute *attr,
484 const char *buf, size_t count)
486 struct usb_line6_variax *variax =
487 usb_get_intfdata(to_usb_interface(dev));
494 sysex = variax_alloc_sysex_buffer(variax, VARIAX_SYSEX_PARAM, size);
499 for (i = 0; i < count; i += 3) {
500 const unsigned char *p1 = buf + i;
501 char *p2 = sysex + SYSEX_DATA_OFS + i * 2;
502 p2[0] = p1[2] & 0x0f;
504 p2[2] = p1[1] & 0x0f;
506 p2[4] = p1[0] & 0x0f;
510 line6_send_sysex_message(&variax->line6, sysex, size);
517 /* Variax workbench special files: */
518 static DEVICE_ATTR(volume, S_IWUSR | S_IRUGO, variax_get_volume,
520 static DEVICE_ATTR(tone, S_IWUSR | S_IRUGO, variax_get_tone, variax_set_tone);
521 static DEVICE_ATTR(name, S_IRUGO, variax_get_name, line6_nop_write);
522 static DEVICE_ATTR(bank, S_IRUGO, variax_get_bank, line6_nop_write);
523 static DEVICE_ATTR(dump, S_IRUGO, variax_get_dump, line6_nop_write);
524 static DEVICE_ATTR(active, S_IWUSR | S_IRUGO, variax_get_active,
526 static DEVICE_ATTR(guitar, S_IRUGO, variax_get_guitar, line6_nop_write);
528 #ifdef CONFIG_LINE6_USB_RAW
529 static DEVICE_ATTR(raw, S_IWUSR, line6_nop_read, line6_set_raw);
530 static DEVICE_ATTR(raw2, S_IWUSR, line6_nop_read, variax_set_raw2);
536 static void variax_destruct(struct usb_interface *interface)
538 struct usb_line6_variax *variax = usb_get_intfdata(interface);
542 line6_cleanup_audio(&variax->line6);
544 del_timer(&variax->startup_timer1);
545 del_timer(&variax->startup_timer2);
546 cancel_work_sync(&variax->startup_work);
548 /* free dump request data: */
549 line6_dumpreq_destructbuf(&variax->dumpreq, 2);
550 line6_dumpreq_destructbuf(&variax->dumpreq, 1);
551 line6_dumpreq_destruct(&variax->dumpreq);
553 kfree(variax->buffer_activate);
557 Create sysfs entries.
559 static int variax_create_files2(struct device *dev)
562 CHECK_RETURN(device_create_file(dev, &dev_attr_volume));
563 CHECK_RETURN(device_create_file(dev, &dev_attr_tone));
564 CHECK_RETURN(device_create_file(dev, &dev_attr_name));
565 CHECK_RETURN(device_create_file(dev, &dev_attr_bank));
566 CHECK_RETURN(device_create_file(dev, &dev_attr_dump));
567 CHECK_RETURN(device_create_file(dev, &dev_attr_active));
568 CHECK_RETURN(device_create_file(dev, &dev_attr_guitar));
569 #ifdef CONFIG_LINE6_USB_RAW
570 CHECK_RETURN(device_create_file(dev, &dev_attr_raw));
571 CHECK_RETURN(device_create_file(dev, &dev_attr_raw2));
577 Try to init workbench device.
579 static int variax_try_init(struct usb_interface *interface,
580 struct usb_line6_variax *variax)
584 init_timer(&variax->startup_timer1);
585 init_timer(&variax->startup_timer2);
586 INIT_WORK(&variax->startup_work, variax_startup7);
588 if ((interface == NULL) || (variax == NULL))
591 /* initialize USB buffers: */
592 err = line6_dumpreq_init(&variax->dumpreq, variax_request_model1,
593 sizeof(variax_request_model1));
596 dev_err(&interface->dev, "Out of memory\n");
600 err = line6_dumpreq_initbuf(&variax->dumpreq, variax_request_model2,
601 sizeof(variax_request_model2), 1);
604 dev_err(&interface->dev, "Out of memory\n");
608 err = line6_dumpreq_initbuf(&variax->dumpreq, variax_request_bank,
609 sizeof(variax_request_bank), 2);
612 dev_err(&interface->dev, "Out of memory\n");
616 variax->buffer_activate = kmemdup(variax_activate,
617 sizeof(variax_activate), GFP_KERNEL);
619 if (variax->buffer_activate == NULL) {
620 dev_err(&interface->dev, "Out of memory\n");
624 /* initialize audio system: */
625 err = line6_init_audio(&variax->line6);
629 /* initialize MIDI subsystem: */
630 err = line6_init_midi(&variax->line6);
634 /* initiate startup procedure: */
635 variax_startup1(variax);
640 Init workbench device (and clean up in case of failure).
642 int line6_variax_init(struct usb_interface *interface,
643 struct usb_line6_variax *variax)
645 int err = variax_try_init(interface, variax);
648 variax_destruct(interface);
654 Workbench device disconnected.
656 void line6_variax_disconnect(struct usb_interface *interface)
660 if (interface == NULL)
662 dev = &interface->dev;
665 /* remove sysfs entries: */
666 line6_variax_remove_files(0, 0, dev);
667 device_remove_file(dev, &dev_attr_volume);
668 device_remove_file(dev, &dev_attr_tone);
669 device_remove_file(dev, &dev_attr_name);
670 device_remove_file(dev, &dev_attr_bank);
671 device_remove_file(dev, &dev_attr_dump);
672 device_remove_file(dev, &dev_attr_active);
673 device_remove_file(dev, &dev_attr_guitar);
674 #ifdef CONFIG_LINE6_USB_RAW
675 device_remove_file(dev, &dev_attr_raw);
676 device_remove_file(dev, &dev_attr_raw2);
680 variax_destruct(interface);