2 * Line6 Linux USB driver - 0.8.0
4 * Copyright (C) 2004-2009 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.
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 static const char variax_activate
[] = {
28 0xf0, 0x00, 0x01, 0x0c, 0x07, 0x00, 0x2a, 0x01,
31 static const char variax_request_bank
[] = {
32 0xf0, 0x00, 0x01, 0x0c, 0x07, 0x00, 0x6d, 0xf7
34 static const char variax_request_model1
[] = {
35 0xf0, 0x00, 0x01, 0x0c, 0x07, 0x00, 0x3c, 0x00,
36 0x02, 0x00, 0x00, 0x00, 0x00, 0x03, 0x05, 0x03,
37 0x00, 0x00, 0x00, 0xf7
39 static const char variax_request_model2
[] = {
40 0xf0, 0x00, 0x01, 0x0c, 0x07, 0x00, 0x3c, 0x00,
41 0x02, 0x00, 0x00, 0x00, 0x00, 0x03, 0x07, 0x03,
42 0x00, 0x00, 0x00, 0xf7
47 Decode data transmitted by workbench.
49 static void variax_decode(const unsigned char *raw_data
, unsigned char *data
,
52 for (; raw_size
> 0; raw_size
-= 6) {
53 data
[2] = raw_data
[0] | (raw_data
[1] << 4);
54 data
[1] = raw_data
[2] | (raw_data
[3] << 4);
55 data
[0] = raw_data
[4] | (raw_data
[5] << 4);
61 static void variax_activate_timeout(unsigned long arg
)
63 struct usb_line6_variax
*variax
= (struct usb_line6_variax
*)arg
;
64 variax
->buffer_activate
[VARIAX_OFFSET_ACTIVATE
] = 1;
65 line6_send_raw_message_async(&variax
->line6
, variax
->buffer_activate
,
66 sizeof(variax_activate
));
70 Send an asynchronous activation request after a given interval.
72 static void variax_activate_delayed(struct usb_line6_variax
*variax
,
75 variax
->activate_timer
.expires
= jiffies
+ seconds
* HZ
;
76 variax
->activate_timer
.function
= variax_activate_timeout
;
77 variax
->activate_timer
.data
= (unsigned long)variax
;
78 add_timer(&variax
->activate_timer
);
81 static void variax_startup_timeout(unsigned long arg
)
83 struct usb_line6_variax
*variax
= (struct usb_line6_variax
*)arg
;
85 if (variax
->dumpreq
.ok
)
88 line6_dump_request_async(&variax
->dumpreq
, &variax
->line6
, 0);
89 line6_startup_delayed(&variax
->dumpreq
, 1, variax_startup_timeout
,
94 Process a completely received message.
96 void variax_process_message(struct usb_line6_variax
*variax
)
98 const unsigned char *buf
= variax
->line6
.buffer_message
;
101 case LINE6_PARAM_CHANGE
| LINE6_CHANNEL_HOST
:
103 case VARIAXMIDI_volume
:
104 variax
->volume
= buf
[2];
107 case VARIAXMIDI_tone
:
108 variax
->tone
= buf
[2];
113 case LINE6_PROGRAM_CHANGE
| LINE6_CHANNEL_DEVICE
:
114 case LINE6_PROGRAM_CHANGE
| LINE6_CHANNEL_HOST
:
115 variax
->model
= buf
[1];
116 line6_dump_request_async(&variax
->dumpreq
, &variax
->line6
, 0);
120 dev_info(variax
->line6
.ifcdev
, "VARIAX reset\n");
121 variax_activate_delayed(variax
, VARIAX_ACTIVATE_DELAY
);
124 case LINE6_SYSEX_BEGIN
:
125 if (memcmp(buf
+ 1, variax_request_model1
+ 1,
126 VARIAX_MODEL_HEADER_LENGTH
- 1) == 0) {
127 if (variax
->line6
.message_length
==
128 VARIAX_MODEL_MESSAGE_LENGTH
) {
129 switch (variax
->dumpreq
.in_progress
) {
130 case VARIAX_DUMP_PASS1
:
131 variax_decode(buf
+ VARIAX_MODEL_HEADER_LENGTH
, (unsigned char *)&variax
->model_data
,
132 (sizeof(variax
->model_data
.name
) + sizeof(variax
->model_data
.control
) / 2) * 2);
133 line6_dump_request_async(&variax
->dumpreq
, &variax
->line6
, 1);
134 line6_dump_started(&variax
->dumpreq
, VARIAX_DUMP_PASS2
);
137 case VARIAX_DUMP_PASS2
:
138 /* model name is transmitted twice, so skip it here: */
139 variax_decode(buf
+ VARIAX_MODEL_HEADER_LENGTH
,
140 (unsigned char *)&variax
->model_data
.control
+ sizeof(variax
->model_data
.control
) / 2,
141 sizeof(variax
->model_data
.control
) / 2 * 2);
142 variax
->dumpreq
.ok
= 1;
143 line6_dump_request_async(&variax
->dumpreq
, &variax
->line6
, 2);
144 line6_dump_started(&variax
->dumpreq
, VARIAX_DUMP_PASS3
);
147 DEBUG_MESSAGES(dev_err(variax
->line6
.ifcdev
, "illegal length %d of model data\n", variax
->line6
.message_length
));
148 line6_dump_finished(&variax
->dumpreq
);
150 } else if (memcmp(buf
+ 1, variax_request_bank
+ 1,
151 sizeof(variax_request_bank
) - 2) == 0) {
153 buf
+ sizeof(variax_request_bank
) - 1,
154 sizeof(variax
->bank
));
155 variax
->dumpreq
.ok
= 1;
156 line6_dump_finished(&variax
->dumpreq
);
161 case LINE6_SYSEX_END
:
165 DEBUG_MESSAGES(dev_err(variax
->line6
.ifcdev
, "Variax: unknown message %02X\n", buf
[0]));
170 "read" request on "volume" special file.
172 static ssize_t
variax_get_volume(struct device
*dev
,
173 struct device_attribute
*attr
, char *buf
)
175 struct usb_line6_variax
*variax
= usb_get_intfdata(to_usb_interface(dev
));
176 return sprintf(buf
, "%d\n", variax
->volume
);
180 "write" request on "volume" special file.
182 static ssize_t
variax_set_volume(struct device
*dev
,
183 struct device_attribute
*attr
,
184 const char *buf
, size_t count
)
186 struct usb_line6_variax
*variax
= usb_get_intfdata(to_usb_interface(dev
));
190 ret
= strict_strtoul(buf
, 10, &value
);
194 if (line6_transmit_parameter(&variax
->line6
, VARIAXMIDI_volume
,
196 variax
->volume
= value
;
202 "read" request on "model" special file.
204 static ssize_t
variax_get_model(struct device
*dev
,
205 struct device_attribute
*attr
, char *buf
)
207 struct usb_line6_variax
*variax
= usb_get_intfdata(to_usb_interface(dev
));
208 return sprintf(buf
, "%d\n", variax
->model
);
212 "write" request on "model" special file.
214 static ssize_t
variax_set_model(struct device
*dev
,
215 struct device_attribute
*attr
,
216 const char *buf
, size_t count
)
218 struct usb_line6_variax
*variax
= usb_get_intfdata(to_usb_interface(dev
));
222 ret
= strict_strtoul(buf
, 10, &value
);
226 if (line6_send_program(&variax
->line6
, value
) == 0)
227 variax
->model
= value
;
233 "read" request on "active" special file.
235 static ssize_t
variax_get_active(struct device
*dev
,
236 struct device_attribute
*attr
, char *buf
)
238 struct usb_line6_variax
*variax
= usb_get_intfdata(to_usb_interface(dev
));
239 return sprintf(buf
, "%d\n", variax
->buffer_activate
[VARIAX_OFFSET_ACTIVATE
]);
243 "write" request on "active" special file.
245 static ssize_t
variax_set_active(struct device
*dev
,
246 struct device_attribute
*attr
,
247 const char *buf
, size_t count
)
249 struct usb_line6_variax
*variax
= usb_get_intfdata(to_usb_interface(dev
));
253 ret
= strict_strtoul(buf
, 10, &value
);
257 variax
->buffer_activate
[VARIAX_OFFSET_ACTIVATE
] = value
? 1 : 0;
258 line6_send_raw_message_async(&variax
->line6
, variax
->buffer_activate
,
259 sizeof(variax_activate
));
264 "read" request on "tone" special file.
266 static ssize_t
variax_get_tone(struct device
*dev
,
267 struct device_attribute
*attr
, char *buf
)
269 struct usb_line6_variax
*variax
= usb_get_intfdata(to_usb_interface(dev
));
270 return sprintf(buf
, "%d\n", variax
->tone
);
274 "write" request on "tone" special file.
276 static ssize_t
variax_set_tone(struct device
*dev
,
277 struct device_attribute
*attr
,
278 const char *buf
, size_t count
)
280 struct usb_line6_variax
*variax
= usb_get_intfdata(to_usb_interface(dev
));
284 ret
= strict_strtoul(buf
, 10, &value
);
288 if (line6_transmit_parameter(&variax
->line6
, VARIAXMIDI_tone
,
290 variax
->tone
= value
;
295 static ssize_t
get_string(char *buf
, const char *data
, int length
)
298 memcpy(buf
, data
, length
);
300 for (i
= length
; i
--;) {
303 if ((c
!= 0) && (c
!= ' '))
312 "read" request on "name" special file.
314 static ssize_t
variax_get_name(struct device
*dev
,
315 struct device_attribute
*attr
, char *buf
)
317 struct usb_line6_variax
*variax
= usb_get_intfdata(to_usb_interface(dev
));
318 line6_wait_dump(&variax
->dumpreq
, 0);
319 return get_string(buf
, variax
->model_data
.name
,
320 sizeof(variax
->model_data
.name
));
324 "read" request on "bank" special file.
326 static ssize_t
variax_get_bank(struct device
*dev
,
327 struct device_attribute
*attr
, char *buf
)
329 struct usb_line6_variax
*variax
= usb_get_intfdata(to_usb_interface(dev
));
330 line6_wait_dump(&variax
->dumpreq
, 0);
331 return get_string(buf
, variax
->bank
, sizeof(variax
->bank
));
335 "read" request on "dump" special file.
337 static ssize_t
variax_get_dump(struct device
*dev
,
338 struct device_attribute
*attr
, char *buf
)
340 struct usb_line6_variax
*variax
= usb_get_intfdata(to_usb_interface(dev
));
342 retval
= line6_wait_dump(&variax
->dumpreq
, 0);
345 memcpy(buf
, &variax
->model_data
.control
,
346 sizeof(variax
->model_data
.control
));
347 return sizeof(variax
->model_data
.control
);
353 "write" request on "raw" special file.
355 static ssize_t
variax_set_raw2(struct device
*dev
,
356 struct device_attribute
*attr
,
357 const char *buf
, size_t count
)
359 struct usb_line6_variax
*variax
= usb_get_intfdata(to_usb_interface(dev
));
366 sysex
= variax_alloc_sysex_buffer(variax
, VARIAX_SYSEX_PARAM
, size
);
371 for (i
= 0; i
< count
; i
+= 3) {
372 const unsigned char *p1
= buf
+ i
;
373 char *p2
= sysex
+ SYSEX_DATA_OFS
+ i
* 2;
374 p2
[0] = p1
[2] & 0x0f;
376 p2
[2] = p1
[1] & 0x0f;
378 p2
[4] = p1
[0] & 0x0f;
382 line6_send_sysex_message(&variax
->line6
, sysex
, size
);
389 /* Variax workbench special files: */
390 static DEVICE_ATTR(model
, S_IWUGO
| S_IRUGO
, variax_get_model
, variax_set_model
);
391 static DEVICE_ATTR(volume
, S_IWUGO
| S_IRUGO
, variax_get_volume
, variax_set_volume
);
392 static DEVICE_ATTR(tone
, S_IWUGO
| S_IRUGO
, variax_get_tone
, variax_set_tone
);
393 static DEVICE_ATTR(name
, S_IRUGO
, variax_get_name
, line6_nop_write
);
394 static DEVICE_ATTR(bank
, S_IRUGO
, variax_get_bank
, line6_nop_write
);
395 static DEVICE_ATTR(dump
, S_IRUGO
, variax_get_dump
, line6_nop_write
);
396 static DEVICE_ATTR(active
, S_IWUGO
| S_IRUGO
, variax_get_active
, variax_set_active
);
399 static DEVICE_ATTR(raw
, S_IWUGO
, line6_nop_read
, line6_set_raw
);
400 static DEVICE_ATTR(raw2
, S_IWUGO
, line6_nop_read
, variax_set_raw2
);
407 static void variax_destruct(struct usb_interface
*interface
)
409 struct usb_line6_variax
*variax
= usb_get_intfdata(interface
);
410 struct usb_line6
*line6
;
414 line6
= &variax
->line6
;
417 line6_cleanup_audio(line6
);
419 /* free dump request data: */
420 line6_dumpreq_destructbuf(&variax
->dumpreq
, 2);
421 line6_dumpreq_destructbuf(&variax
->dumpreq
, 1);
422 line6_dumpreq_destruct(&variax
->dumpreq
);
424 kfree(variax
->buffer_activate
);
425 del_timer_sync(&variax
->activate_timer
);
429 Create sysfs entries.
431 static int variax_create_files2(struct device
*dev
)
434 CHECK_RETURN(device_create_file(dev
, &dev_attr_model
));
435 CHECK_RETURN(device_create_file(dev
, &dev_attr_volume
));
436 CHECK_RETURN(device_create_file(dev
, &dev_attr_tone
));
437 CHECK_RETURN(device_create_file(dev
, &dev_attr_name
));
438 CHECK_RETURN(device_create_file(dev
, &dev_attr_bank
));
439 CHECK_RETURN(device_create_file(dev
, &dev_attr_dump
));
440 CHECK_RETURN(device_create_file(dev
, &dev_attr_active
));
442 CHECK_RETURN(device_create_file(dev
, &dev_attr_raw
));
443 CHECK_RETURN(device_create_file(dev
, &dev_attr_raw2
));
449 Init workbench device.
451 int variax_init(struct usb_interface
*interface
,
452 struct usb_line6_variax
*variax
)
456 if ((interface
== NULL
) || (variax
== NULL
))
459 /* initialize USB buffers: */
460 err
= line6_dumpreq_init(&variax
->dumpreq
, variax_request_model1
,
461 sizeof(variax_request_model1
));
464 dev_err(&interface
->dev
, "Out of memory\n");
465 variax_destruct(interface
);
469 err
= line6_dumpreq_initbuf(&variax
->dumpreq
, variax_request_model2
,
470 sizeof(variax_request_model2
), 1);
473 dev_err(&interface
->dev
, "Out of memory\n");
474 variax_destruct(interface
);
478 err
= line6_dumpreq_initbuf(&variax
->dumpreq
, variax_request_bank
,
479 sizeof(variax_request_bank
), 2);
482 dev_err(&interface
->dev
, "Out of memory\n");
483 variax_destruct(interface
);
487 variax
->buffer_activate
= kmalloc(sizeof(variax_activate
), GFP_KERNEL
);
489 if (variax
->buffer_activate
== NULL
) {
490 dev_err(&interface
->dev
, "Out of memory\n");
491 variax_destruct(interface
);
495 memcpy(variax
->buffer_activate
, variax_activate
,
496 sizeof(variax_activate
));
497 init_timer(&variax
->activate_timer
);
499 /* create sysfs entries: */
500 err
= variax_create_files(0, 0, &interface
->dev
);
502 variax_destruct(interface
);
506 err
= variax_create_files2(&interface
->dev
);
508 variax_destruct(interface
);
512 /* initialize audio system: */
513 err
= line6_init_audio(&variax
->line6
);
515 variax_destruct(interface
);
519 /* initialize MIDI subsystem: */
520 err
= line6_init_midi(&variax
->line6
);
522 variax_destruct(interface
);
526 /* register audio system: */
527 err
= line6_register_audio(&variax
->line6
);
529 variax_destruct(interface
);
533 variax_activate_delayed(variax
, VARIAX_ACTIVATE_DELAY
);
534 line6_startup_delayed(&variax
->dumpreq
, VARIAX_STARTUP_DELAY
,
535 variax_startup_timeout
, variax
);
540 Workbench device disconnected.
542 void variax_disconnect(struct usb_interface
*interface
)
546 if (interface
== NULL
)
548 dev
= &interface
->dev
;
551 /* remove sysfs entries: */
552 variax_remove_files(0, 0, dev
);
553 device_remove_file(dev
, &dev_attr_model
);
554 device_remove_file(dev
, &dev_attr_volume
);
555 device_remove_file(dev
, &dev_attr_tone
);
556 device_remove_file(dev
, &dev_attr_name
);
557 device_remove_file(dev
, &dev_attr_bank
);
558 device_remove_file(dev
, &dev_attr_dump
);
559 device_remove_file(dev
, &dev_attr_active
);
561 device_remove_file(dev
, &dev_attr_raw
);
562 device_remove_file(dev
, &dev_attr_raw2
);
566 variax_destruct(interface
);