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 variax_startup6 */
166 static void variax_startup6(struct usb_line6_variax
*variax
)
168 CHECK_STARTUP_PROGRESS(variax
->startup_progress
,
169 VARIAX_STARTUP_WORKQUEUE
);
171 /* schedule work for global work queue: */
172 schedule_work(&variax
->startup_work
);
175 static void variax_startup7(struct work_struct
*work
)
177 struct usb_line6_variax
*variax
=
178 container_of(work
, struct usb_line6_variax
, startup_work
);
179 struct usb_line6
*line6
= &variax
->line6
;
181 CHECK_STARTUP_PROGRESS(variax
->startup_progress
, VARIAX_STARTUP_SETUP
);
183 /* ALSA audio interface: */
184 line6_register_audio(&variax
->line6
);
187 line6_variax_create_files(0, 0, line6
->ifcdev
);
188 variax_create_files2(line6
->ifcdev
);
192 Process a completely received message.
194 void line6_variax_process_message(struct usb_line6_variax
*variax
)
196 const unsigned char *buf
= variax
->line6
.buffer_message
;
199 case LINE6_PARAM_CHANGE
| LINE6_CHANNEL_HOST
:
201 case VARIAXMIDI_volume
:
202 variax
->volume
= buf
[2];
205 case VARIAXMIDI_tone
:
206 variax
->tone
= buf
[2];
211 case LINE6_PROGRAM_CHANGE
| LINE6_CHANNEL_DEVICE
:
212 case LINE6_PROGRAM_CHANGE
| LINE6_CHANNEL_HOST
:
213 variax
->model
= buf
[1];
214 line6_dump_request_async(&variax
->dumpreq
, &variax
->line6
, 0,
219 dev_info(variax
->line6
.ifcdev
, "VARIAX reset\n");
222 case LINE6_SYSEX_BEGIN
:
223 if (memcmp(buf
+ 1, variax_request_model1
+ 1,
224 VARIAX_MODEL_HEADER_LENGTH
- 1) == 0) {
225 if (variax
->line6
.message_length
==
226 VARIAX_MODEL_MESSAGE_LENGTH
) {
227 switch (variax
->dumpreq
.in_progress
) {
228 case VARIAX_DUMP_PASS1
:
230 VARIAX_MODEL_HEADER_LENGTH
,
240 line6_dump_request_async
241 (&variax
->dumpreq
, &variax
->line6
,
242 1, VARIAX_DUMP_PASS2
);
245 case VARIAX_DUMP_PASS2
:
246 /* model name is transmitted twice, so skip it here: */
248 VARIAX_MODEL_HEADER_LENGTH
,
252 sizeof(variax
->model_data
.
255 sizeof(variax
->model_data
.
258 line6_dump_request_async
259 (&variax
->dumpreq
, &variax
->line6
,
260 2, VARIAX_DUMP_PASS3
);
263 DEBUG_MESSAGES(dev_err
264 (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 DEBUG_MESSAGES(dev_err
297 (variax
->line6
.ifcdev
,
298 "Variax: unknown message %02X\n", buf
[0]));
303 "read" request on "volume" special file.
305 static ssize_t
variax_get_volume(struct device
*dev
,
306 struct device_attribute
*attr
, char *buf
)
308 struct usb_line6_variax
*variax
=
309 usb_get_intfdata(to_usb_interface(dev
));
310 return sprintf(buf
, "%d\n", variax
->volume
);
314 "write" request on "volume" special file.
316 static ssize_t
variax_set_volume(struct device
*dev
,
317 struct device_attribute
*attr
,
318 const char *buf
, size_t count
)
320 struct usb_line6_variax
*variax
=
321 usb_get_intfdata(to_usb_interface(dev
));
325 ret
= strict_strtoul(buf
, 10, &value
);
329 if (line6_transmit_parameter(&variax
->line6
, VARIAXMIDI_volume
,
331 variax
->volume
= value
;
337 "read" request on "model" special file.
339 static ssize_t
variax_get_model(struct device
*dev
,
340 struct device_attribute
*attr
, char *buf
)
342 struct usb_line6_variax
*variax
=
343 usb_get_intfdata(to_usb_interface(dev
));
344 return sprintf(buf
, "%d\n", variax
->model
);
348 "write" request on "model" special file.
350 static ssize_t
variax_set_model(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
= strict_strtoul(buf
, 10, &value
);
363 if (line6_send_program(&variax
->line6
, value
) == 0)
364 variax
->model
= value
;
370 "read" request on "active" special file.
372 static ssize_t
variax_get_active(struct device
*dev
,
373 struct device_attribute
*attr
, char *buf
)
375 struct usb_line6_variax
*variax
=
376 usb_get_intfdata(to_usb_interface(dev
));
377 return sprintf(buf
, "%d\n",
378 variax
->buffer_activate
[VARIAX_OFFSET_ACTIVATE
]);
382 "write" request on "active" special file.
384 static ssize_t
variax_set_active(struct device
*dev
,
385 struct device_attribute
*attr
,
386 const char *buf
, size_t count
)
388 struct usb_line6_variax
*variax
=
389 usb_get_intfdata(to_usb_interface(dev
));
393 ret
= strict_strtoul(buf
, 10, &value
);
397 variax_activate_async(variax
, value
? 1 : 0);
402 "read" request on "tone" special file.
404 static ssize_t
variax_get_tone(struct device
*dev
,
405 struct device_attribute
*attr
, char *buf
)
407 struct usb_line6_variax
*variax
=
408 usb_get_intfdata(to_usb_interface(dev
));
409 return sprintf(buf
, "%d\n", variax
->tone
);
413 "write" request on "tone" special file.
415 static ssize_t
variax_set_tone(struct device
*dev
,
416 struct device_attribute
*attr
,
417 const char *buf
, size_t count
)
419 struct usb_line6_variax
*variax
=
420 usb_get_intfdata(to_usb_interface(dev
));
424 ret
= strict_strtoul(buf
, 10, &value
);
428 if (line6_transmit_parameter(&variax
->line6
, VARIAXMIDI_tone
,
430 variax
->tone
= value
;
435 static ssize_t
get_string(char *buf
, const char *data
, int length
)
438 memcpy(buf
, data
, length
);
440 for (i
= length
; i
--;) {
443 if ((c
!= 0) && (c
!= ' '))
452 "read" request on "name" special file.
454 static ssize_t
variax_get_name(struct device
*dev
,
455 struct device_attribute
*attr
, char *buf
)
457 struct usb_line6_variax
*variax
=
458 usb_get_intfdata(to_usb_interface(dev
));
459 line6_dump_wait_interruptible(&variax
->dumpreq
);
460 return get_string(buf
, variax
->model_data
.name
,
461 sizeof(variax
->model_data
.name
));
465 "read" request on "bank" special file.
467 static ssize_t
variax_get_bank(struct device
*dev
,
468 struct device_attribute
*attr
, char *buf
)
470 struct usb_line6_variax
*variax
=
471 usb_get_intfdata(to_usb_interface(dev
));
472 line6_dump_wait_interruptible(&variax
->dumpreq
);
473 return get_string(buf
, variax
->bank
, sizeof(variax
->bank
));
477 "read" request on "dump" special file.
479 static ssize_t
variax_get_dump(struct device
*dev
,
480 struct device_attribute
*attr
, char *buf
)
482 struct usb_line6_variax
*variax
=
483 usb_get_intfdata(to_usb_interface(dev
));
485 retval
= line6_dump_wait_interruptible(&variax
->dumpreq
);
488 memcpy(buf
, &variax
->model_data
.control
,
489 sizeof(variax
->model_data
.control
));
490 return sizeof(variax
->model_data
.control
);
494 "read" request on "guitar" special file.
496 static ssize_t
variax_get_guitar(struct device
*dev
,
497 struct device_attribute
*attr
, char *buf
)
499 struct usb_line6_variax
*variax
=
500 usb_get_intfdata(to_usb_interface(dev
));
501 return sprintf(buf
, "%s\n", variax
->guitar
);
504 #ifdef CONFIG_LINE6_USB_RAW
506 static char *variax_alloc_sysex_buffer(struct usb_line6_variax
*variax
,
509 return line6_alloc_sysex_buffer(&variax
->line6
, VARIAX_SYSEX_CODE
, code
,
514 "write" request on "raw" special file.
516 static ssize_t
variax_set_raw2(struct device
*dev
,
517 struct device_attribute
*attr
,
518 const char *buf
, size_t count
)
520 struct usb_line6_variax
*variax
=
521 usb_get_intfdata(to_usb_interface(dev
));
528 sysex
= variax_alloc_sysex_buffer(variax
, VARIAX_SYSEX_PARAM
, size
);
533 for (i
= 0; i
< count
; i
+= 3) {
534 const unsigned char *p1
= buf
+ i
;
535 char *p2
= sysex
+ SYSEX_DATA_OFS
+ i
* 2;
536 p2
[0] = p1
[2] & 0x0f;
538 p2
[2] = p1
[1] & 0x0f;
540 p2
[4] = p1
[0] & 0x0f;
544 line6_send_sysex_message(&variax
->line6
, sysex
, size
);
551 /* Variax workbench special files: */
552 static DEVICE_ATTR(model
, S_IWUSR
| S_IRUGO
, variax_get_model
,
554 static DEVICE_ATTR(volume
, S_IWUSR
| S_IRUGO
, variax_get_volume
,
556 static DEVICE_ATTR(tone
, S_IWUSR
| S_IRUGO
, variax_get_tone
, variax_set_tone
);
557 static DEVICE_ATTR(name
, S_IRUGO
, variax_get_name
, line6_nop_write
);
558 static DEVICE_ATTR(bank
, S_IRUGO
, variax_get_bank
, line6_nop_write
);
559 static DEVICE_ATTR(dump
, S_IRUGO
, variax_get_dump
, line6_nop_write
);
560 static DEVICE_ATTR(active
, S_IWUSR
| S_IRUGO
, variax_get_active
,
562 static DEVICE_ATTR(guitar
, S_IRUGO
, variax_get_guitar
, line6_nop_write
);
564 #ifdef CONFIG_LINE6_USB_RAW
565 static DEVICE_ATTR(raw
, S_IWUSR
, line6_nop_read
, line6_set_raw
);
566 static DEVICE_ATTR(raw2
, S_IWUSR
, line6_nop_read
, variax_set_raw2
);
572 static void variax_destruct(struct usb_interface
*interface
)
574 struct usb_line6_variax
*variax
= usb_get_intfdata(interface
);
578 line6_cleanup_audio(&variax
->line6
);
580 del_timer(&variax
->startup_timer1
);
581 del_timer(&variax
->startup_timer2
);
582 cancel_work_sync(&variax
->startup_work
);
584 /* free dump request data: */
585 line6_dumpreq_destructbuf(&variax
->dumpreq
, 2);
586 line6_dumpreq_destructbuf(&variax
->dumpreq
, 1);
587 line6_dumpreq_destruct(&variax
->dumpreq
);
589 kfree(variax
->buffer_activate
);
593 Create sysfs entries.
595 static int variax_create_files2(struct device
*dev
)
598 CHECK_RETURN(device_create_file(dev
, &dev_attr_model
));
599 CHECK_RETURN(device_create_file(dev
, &dev_attr_volume
));
600 CHECK_RETURN(device_create_file(dev
, &dev_attr_tone
));
601 CHECK_RETURN(device_create_file(dev
, &dev_attr_name
));
602 CHECK_RETURN(device_create_file(dev
, &dev_attr_bank
));
603 CHECK_RETURN(device_create_file(dev
, &dev_attr_dump
));
604 CHECK_RETURN(device_create_file(dev
, &dev_attr_active
));
605 CHECK_RETURN(device_create_file(dev
, &dev_attr_guitar
));
606 #ifdef CONFIG_LINE6_USB_RAW
607 CHECK_RETURN(device_create_file(dev
, &dev_attr_raw
));
608 CHECK_RETURN(device_create_file(dev
, &dev_attr_raw2
));
614 Try to init workbench device.
616 static int variax_try_init(struct usb_interface
*interface
,
617 struct usb_line6_variax
*variax
)
621 init_timer(&variax
->startup_timer1
);
622 init_timer(&variax
->startup_timer2
);
623 INIT_WORK(&variax
->startup_work
, variax_startup7
);
625 if ((interface
== NULL
) || (variax
== NULL
))
628 /* initialize USB buffers: */
629 err
= line6_dumpreq_init(&variax
->dumpreq
, variax_request_model1
,
630 sizeof(variax_request_model1
));
633 dev_err(&interface
->dev
, "Out of memory\n");
637 err
= line6_dumpreq_initbuf(&variax
->dumpreq
, variax_request_model2
,
638 sizeof(variax_request_model2
), 1);
641 dev_err(&interface
->dev
, "Out of memory\n");
645 err
= line6_dumpreq_initbuf(&variax
->dumpreq
, variax_request_bank
,
646 sizeof(variax_request_bank
), 2);
649 dev_err(&interface
->dev
, "Out of memory\n");
653 variax
->buffer_activate
= kmemdup(variax_activate
,
654 sizeof(variax_activate
), GFP_KERNEL
);
656 if (variax
->buffer_activate
== NULL
) {
657 dev_err(&interface
->dev
, "Out of memory\n");
661 /* initialize audio system: */
662 err
= line6_init_audio(&variax
->line6
);
666 /* initialize MIDI subsystem: */
667 err
= line6_init_midi(&variax
->line6
);
671 /* initiate startup procedure: */
672 variax_startup1(variax
);
677 Init workbench device (and clean up in case of failure).
679 int line6_variax_init(struct usb_interface
*interface
,
680 struct usb_line6_variax
*variax
)
682 int err
= variax_try_init(interface
, variax
);
685 variax_destruct(interface
);
691 Workbench device disconnected.
693 void line6_variax_disconnect(struct usb_interface
*interface
)
697 if (interface
== NULL
)
699 dev
= &interface
->dev
;
702 /* remove sysfs entries: */
703 line6_variax_remove_files(0, 0, dev
);
704 device_remove_file(dev
, &dev_attr_model
);
705 device_remove_file(dev
, &dev_attr_volume
);
706 device_remove_file(dev
, &dev_attr_tone
);
707 device_remove_file(dev
, &dev_attr_name
);
708 device_remove_file(dev
, &dev_attr_bank
);
709 device_remove_file(dev
, &dev_attr_dump
);
710 device_remove_file(dev
, &dev_attr_active
);
711 device_remove_file(dev
, &dev_attr_guitar
);
712 #ifdef CONFIG_LINE6_USB_RAW
713 device_remove_file(dev
, &dev_attr_raw
);
714 device_remove_file(dev
, &dev_attr_raw2
);
718 variax_destruct(interface
);