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
));
187 int value
= simple_strtoul(buf
, NULL
, 10);
189 if (line6_transmit_parameter(&variax
->line6
, VARIAXMIDI_volume
,
191 variax
->volume
= value
;
197 "read" request on "model" special file.
199 static ssize_t
variax_get_model(struct device
*dev
,
200 struct device_attribute
*attr
, char *buf
)
202 struct usb_line6_variax
*variax
= usb_get_intfdata(to_usb_interface(dev
));
203 return sprintf(buf
, "%d\n", variax
->model
);
207 "write" request on "model" special file.
209 static ssize_t
variax_set_model(struct device
*dev
,
210 struct device_attribute
*attr
,
211 const char *buf
, size_t count
)
213 struct usb_line6_variax
*variax
= usb_get_intfdata(to_usb_interface(dev
));
214 int value
= simple_strtoul(buf
, NULL
, 10);
216 if (line6_send_program(&variax
->line6
, value
) == 0)
217 variax
->model
= value
;
223 "read" request on "active" special file.
225 static ssize_t
variax_get_active(struct device
*dev
,
226 struct device_attribute
*attr
, char *buf
)
228 struct usb_line6_variax
*variax
= usb_get_intfdata(to_usb_interface(dev
));
229 return sprintf(buf
, "%d\n", variax
->buffer_activate
[VARIAX_OFFSET_ACTIVATE
]);
233 "write" request on "active" special file.
235 static ssize_t
variax_set_active(struct device
*dev
,
236 struct device_attribute
*attr
,
237 const char *buf
, size_t count
)
239 struct usb_line6_variax
*variax
= usb_get_intfdata(to_usb_interface(dev
));
240 int value
= simple_strtoul(buf
, NULL
, 10) ? 1 : 0;
241 variax
->buffer_activate
[VARIAX_OFFSET_ACTIVATE
] = value
;
242 line6_send_raw_message_async(&variax
->line6
, variax
->buffer_activate
,
243 sizeof(variax_activate
));
248 "read" request on "tone" special file.
250 static ssize_t
variax_get_tone(struct device
*dev
,
251 struct device_attribute
*attr
, char *buf
)
253 struct usb_line6_variax
*variax
= usb_get_intfdata(to_usb_interface(dev
));
254 return sprintf(buf
, "%d\n", variax
->tone
);
258 "write" request on "tone" special file.
260 static ssize_t
variax_set_tone(struct device
*dev
,
261 struct device_attribute
*attr
,
262 const char *buf
, size_t count
)
264 struct usb_line6_variax
*variax
= usb_get_intfdata(to_usb_interface(dev
));
265 int value
= simple_strtoul(buf
, NULL
, 10);
267 if (line6_transmit_parameter(&variax
->line6
, VARIAXMIDI_tone
,
269 variax
->tone
= value
;
274 static ssize_t
get_string(char *buf
, const char *data
, int length
)
277 memcpy(buf
, data
, length
);
279 for (i
= length
; i
--;) {
282 if ((c
!= 0) && (c
!= ' '))
291 "read" request on "name" special file.
293 static ssize_t
variax_get_name(struct device
*dev
,
294 struct device_attribute
*attr
, char *buf
)
296 struct usb_line6_variax
*variax
= usb_get_intfdata(to_usb_interface(dev
));
297 line6_wait_dump(&variax
->dumpreq
, 0);
298 return get_string(buf
, variax
->model_data
.name
,
299 sizeof(variax
->model_data
.name
));
303 "read" request on "bank" special file.
305 static ssize_t
variax_get_bank(struct device
*dev
,
306 struct device_attribute
*attr
, char *buf
)
308 struct usb_line6_variax
*variax
= usb_get_intfdata(to_usb_interface(dev
));
309 line6_wait_dump(&variax
->dumpreq
, 0);
310 return get_string(buf
, variax
->bank
, sizeof(variax
->bank
));
314 "read" request on "dump" special file.
316 static ssize_t
variax_get_dump(struct device
*dev
,
317 struct device_attribute
*attr
, char *buf
)
319 struct usb_line6_variax
*variax
= usb_get_intfdata(to_usb_interface(dev
));
321 retval
= line6_wait_dump(&variax
->dumpreq
, 0);
324 memcpy(buf
, &variax
->model_data
.control
,
325 sizeof(variax
->model_data
.control
));
326 return sizeof(variax
->model_data
.control
);
332 "write" request on "raw" special file.
334 static ssize_t
variax_set_raw2(struct device
*dev
,
335 struct device_attribute
*attr
,
336 const char *buf
, size_t count
)
338 struct usb_line6_variax
*variax
= usb_get_intfdata(to_usb_interface(dev
));
345 sysex
= variax_alloc_sysex_buffer(variax
, VARIAX_SYSEX_PARAM
, size
);
350 for (i
= 0; i
< count
; i
+= 3) {
351 const unsigned char *p1
= buf
+ i
;
352 char *p2
= sysex
+ SYSEX_DATA_OFS
+ i
* 2;
353 p2
[0] = p1
[2] & 0x0f;
355 p2
[2] = p1
[1] & 0x0f;
357 p2
[4] = p1
[0] & 0x0f;
361 line6_send_sysex_message(&variax
->line6
, sysex
, size
);
368 /* Variax workbench special files: */
369 static DEVICE_ATTR(model
, S_IWUGO
| S_IRUGO
, variax_get_model
, variax_set_model
);
370 static DEVICE_ATTR(volume
, S_IWUGO
| S_IRUGO
, variax_get_volume
, variax_set_volume
);
371 static DEVICE_ATTR(tone
, S_IWUGO
| S_IRUGO
, variax_get_tone
, variax_set_tone
);
372 static DEVICE_ATTR(name
, S_IRUGO
, variax_get_name
, line6_nop_write
);
373 static DEVICE_ATTR(bank
, S_IRUGO
, variax_get_bank
, line6_nop_write
);
374 static DEVICE_ATTR(dump
, S_IRUGO
, variax_get_dump
, line6_nop_write
);
375 static DEVICE_ATTR(active
, S_IWUGO
| S_IRUGO
, variax_get_active
, variax_set_active
);
378 static DEVICE_ATTR(raw
, S_IWUGO
, line6_nop_read
, line6_set_raw
);
379 static DEVICE_ATTR(raw2
, S_IWUGO
, line6_nop_read
, variax_set_raw2
);
386 static void variax_destruct(struct usb_interface
*interface
)
388 struct usb_line6_variax
*variax
= usb_get_intfdata(interface
);
389 struct usb_line6
*line6
;
393 line6
= &variax
->line6
;
396 line6_cleanup_audio(line6
);
398 /* free dump request data: */
399 line6_dumpreq_destructbuf(&variax
->dumpreq
, 2);
400 line6_dumpreq_destructbuf(&variax
->dumpreq
, 1);
401 line6_dumpreq_destruct(&variax
->dumpreq
);
403 kfree(variax
->buffer_activate
);
404 del_timer_sync(&variax
->activate_timer
);
408 Create sysfs entries.
410 static int variax_create_files2(struct device
*dev
)
413 CHECK_RETURN(device_create_file(dev
, &dev_attr_model
));
414 CHECK_RETURN(device_create_file(dev
, &dev_attr_volume
));
415 CHECK_RETURN(device_create_file(dev
, &dev_attr_tone
));
416 CHECK_RETURN(device_create_file(dev
, &dev_attr_name
));
417 CHECK_RETURN(device_create_file(dev
, &dev_attr_bank
));
418 CHECK_RETURN(device_create_file(dev
, &dev_attr_dump
));
419 CHECK_RETURN(device_create_file(dev
, &dev_attr_active
));
421 CHECK_RETURN(device_create_file(dev
, &dev_attr_raw
));
422 CHECK_RETURN(device_create_file(dev
, &dev_attr_raw2
));
428 Init workbench device.
430 int variax_init(struct usb_interface
*interface
,
431 struct usb_line6_variax
*variax
)
435 if ((interface
== NULL
) || (variax
== NULL
))
438 /* initialize USB buffers: */
439 err
= line6_dumpreq_init(&variax
->dumpreq
, variax_request_model1
,
440 sizeof(variax_request_model1
));
443 dev_err(&interface
->dev
, "Out of memory\n");
444 variax_destruct(interface
);
448 err
= line6_dumpreq_initbuf(&variax
->dumpreq
, variax_request_model2
,
449 sizeof(variax_request_model2
), 1);
452 dev_err(&interface
->dev
, "Out of memory\n");
453 variax_destruct(interface
);
457 err
= line6_dumpreq_initbuf(&variax
->dumpreq
, variax_request_bank
,
458 sizeof(variax_request_bank
), 2);
461 dev_err(&interface
->dev
, "Out of memory\n");
462 variax_destruct(interface
);
466 variax
->buffer_activate
= kmalloc(sizeof(variax_activate
), GFP_KERNEL
);
468 if (variax
->buffer_activate
== NULL
) {
469 dev_err(&interface
->dev
, "Out of memory\n");
470 variax_destruct(interface
);
474 memcpy(variax
->buffer_activate
, variax_activate
,
475 sizeof(variax_activate
));
476 init_timer(&variax
->activate_timer
);
478 /* create sysfs entries: */
479 err
= variax_create_files(0, 0, &interface
->dev
);
481 variax_destruct(interface
);
485 err
= variax_create_files2(&interface
->dev
);
487 variax_destruct(interface
);
491 /* initialize audio system: */
492 err
= line6_init_audio(&variax
->line6
);
494 variax_destruct(interface
);
498 /* initialize MIDI subsystem: */
499 err
= line6_init_midi(&variax
->line6
);
501 variax_destruct(interface
);
505 /* register audio system: */
506 err
= line6_register_audio(&variax
->line6
);
508 variax_destruct(interface
);
512 variax_activate_delayed(variax
, VARIAX_ACTIVATE_DELAY
);
513 line6_startup_delayed(&variax
->dumpreq
, VARIAX_STARTUP_DELAY
,
514 variax_startup_timeout
, variax
);
519 Workbench device disconnected.
521 void variax_disconnect(struct usb_interface
*interface
)
525 if (interface
== NULL
)
527 dev
= &interface
->dev
;
530 /* remove sysfs entries: */
531 variax_remove_files(0, 0, dev
);
532 device_remove_file(dev
, &dev_attr_model
);
533 device_remove_file(dev
, &dev_attr_volume
);
534 device_remove_file(dev
, &dev_attr_tone
);
535 device_remove_file(dev
, &dev_attr_name
);
536 device_remove_file(dev
, &dev_attr_bank
);
537 device_remove_file(dev
, &dev_attr_dump
);
538 device_remove_file(dev
, &dev_attr_active
);
540 device_remove_file(dev
, &dev_attr_raw
);
541 device_remove_file(dev
, &dev_attr_raw2
);
545 variax_destruct(interface
);