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.
14 #include <linux/slab.h>
21 #define VARIAX_SYSEX_CODE 7
22 #define VARIAX_SYSEX_PARAM 0x3b
23 #define VARIAX_SYSEX_ACTIVATE 0x2a
24 #define VARIAX_MODEL_HEADER_LENGTH 7
25 #define VARIAX_MODEL_MESSAGE_LENGTH 199
26 #define VARIAX_OFFSET_ACTIVATE 7
29 static const char variax_activate
[] = {
30 0xf0, 0x00, 0x01, 0x0c, 0x07, 0x00, 0x2a, 0x01,
33 static const char variax_request_bank
[] = {
34 0xf0, 0x00, 0x01, 0x0c, 0x07, 0x00, 0x6d, 0xf7
36 static const char variax_request_model1
[] = {
37 0xf0, 0x00, 0x01, 0x0c, 0x07, 0x00, 0x3c, 0x00,
38 0x02, 0x00, 0x00, 0x00, 0x00, 0x03, 0x05, 0x03,
39 0x00, 0x00, 0x00, 0xf7
41 static const char variax_request_model2
[] = {
42 0xf0, 0x00, 0x01, 0x0c, 0x07, 0x00, 0x3c, 0x00,
43 0x02, 0x00, 0x00, 0x00, 0x00, 0x03, 0x07, 0x03,
44 0x00, 0x00, 0x00, 0xf7
49 Decode data transmitted by workbench.
51 static void variax_decode(const unsigned char *raw_data
, unsigned char *data
,
54 for (; raw_size
> 0; raw_size
-= 6) {
55 data
[2] = raw_data
[0] | (raw_data
[1] << 4);
56 data
[1] = raw_data
[2] | (raw_data
[3] << 4);
57 data
[0] = raw_data
[4] | (raw_data
[5] << 4);
63 static void variax_activate_timeout(unsigned long arg
)
65 struct usb_line6_variax
*variax
= (struct usb_line6_variax
*)arg
;
66 variax
->buffer_activate
[VARIAX_OFFSET_ACTIVATE
] = 1;
67 line6_send_raw_message_async(&variax
->line6
, variax
->buffer_activate
,
68 sizeof(variax_activate
));
72 Send an asynchronous activation request after a given interval.
74 static void variax_activate_delayed(struct usb_line6_variax
*variax
,
77 variax
->activate_timer
.expires
= jiffies
+ seconds
* HZ
;
78 variax
->activate_timer
.function
= variax_activate_timeout
;
79 variax
->activate_timer
.data
= (unsigned long)variax
;
80 add_timer(&variax
->activate_timer
);
83 static void variax_startup_timeout(unsigned long arg
)
85 struct usb_line6_variax
*variax
= (struct usb_line6_variax
*)arg
;
87 if (variax
->dumpreq
.ok
)
90 line6_dump_request_async(&variax
->dumpreq
, &variax
->line6
, 0);
91 line6_startup_delayed(&variax
->dumpreq
, 1, variax_startup_timeout
,
96 Process a completely received message.
98 void variax_process_message(struct usb_line6_variax
*variax
)
100 const unsigned char *buf
= variax
->line6
.buffer_message
;
103 case LINE6_PARAM_CHANGE
| LINE6_CHANNEL_HOST
:
105 case VARIAXMIDI_volume
:
106 variax
->volume
= buf
[2];
109 case VARIAXMIDI_tone
:
110 variax
->tone
= buf
[2];
115 case LINE6_PROGRAM_CHANGE
| LINE6_CHANNEL_DEVICE
:
116 case LINE6_PROGRAM_CHANGE
| LINE6_CHANNEL_HOST
:
117 variax
->model
= buf
[1];
118 line6_dump_request_async(&variax
->dumpreq
, &variax
->line6
, 0);
122 dev_info(variax
->line6
.ifcdev
, "VARIAX reset\n");
123 variax_activate_delayed(variax
, VARIAX_ACTIVATE_DELAY
);
126 case LINE6_SYSEX_BEGIN
:
127 if (memcmp(buf
+ 1, variax_request_model1
+ 1,
128 VARIAX_MODEL_HEADER_LENGTH
- 1) == 0) {
129 if (variax
->line6
.message_length
==
130 VARIAX_MODEL_MESSAGE_LENGTH
) {
131 switch (variax
->dumpreq
.in_progress
) {
132 case VARIAX_DUMP_PASS1
:
133 variax_decode(buf
+ VARIAX_MODEL_HEADER_LENGTH
, (unsigned char *)&variax
->model_data
,
134 (sizeof(variax
->model_data
.name
) + sizeof(variax
->model_data
.control
) / 2) * 2);
135 line6_dump_request_async(&variax
->dumpreq
, &variax
->line6
, 1);
136 line6_dump_started(&variax
->dumpreq
, VARIAX_DUMP_PASS2
);
139 case VARIAX_DUMP_PASS2
:
140 /* model name is transmitted twice, so skip it here: */
141 variax_decode(buf
+ VARIAX_MODEL_HEADER_LENGTH
,
142 (unsigned char *)&variax
->model_data
.control
+ sizeof(variax
->model_data
.control
) / 2,
143 sizeof(variax
->model_data
.control
) / 2 * 2);
144 variax
->dumpreq
.ok
= 1;
145 line6_dump_request_async(&variax
->dumpreq
, &variax
->line6
, 2);
146 line6_dump_started(&variax
->dumpreq
, VARIAX_DUMP_PASS3
);
149 DEBUG_MESSAGES(dev_err(variax
->line6
.ifcdev
, "illegal length %d of model data\n", variax
->line6
.message_length
));
150 line6_dump_finished(&variax
->dumpreq
);
152 } else if (memcmp(buf
+ 1, variax_request_bank
+ 1,
153 sizeof(variax_request_bank
) - 2) == 0) {
155 buf
+ sizeof(variax_request_bank
) - 1,
156 sizeof(variax
->bank
));
157 variax
->dumpreq
.ok
= 1;
158 line6_dump_finished(&variax
->dumpreq
);
163 case LINE6_SYSEX_END
:
167 DEBUG_MESSAGES(dev_err(variax
->line6
.ifcdev
, "Variax: unknown message %02X\n", buf
[0]));
172 "read" request on "volume" special file.
174 static ssize_t
variax_get_volume(struct device
*dev
,
175 struct device_attribute
*attr
, char *buf
)
177 struct usb_line6_variax
*variax
= usb_get_intfdata(to_usb_interface(dev
));
178 return sprintf(buf
, "%d\n", variax
->volume
);
182 "write" request on "volume" special file.
184 static ssize_t
variax_set_volume(struct device
*dev
,
185 struct device_attribute
*attr
,
186 const char *buf
, size_t count
)
188 struct usb_line6_variax
*variax
= usb_get_intfdata(to_usb_interface(dev
));
192 ret
= strict_strtoul(buf
, 10, &value
);
196 if (line6_transmit_parameter(&variax
->line6
, VARIAXMIDI_volume
,
198 variax
->volume
= value
;
204 "read" request on "model" special file.
206 static ssize_t
variax_get_model(struct device
*dev
,
207 struct device_attribute
*attr
, char *buf
)
209 struct usb_line6_variax
*variax
= usb_get_intfdata(to_usb_interface(dev
));
210 return sprintf(buf
, "%d\n", variax
->model
);
214 "write" request on "model" special file.
216 static ssize_t
variax_set_model(struct device
*dev
,
217 struct device_attribute
*attr
,
218 const char *buf
, size_t count
)
220 struct usb_line6_variax
*variax
= usb_get_intfdata(to_usb_interface(dev
));
224 ret
= strict_strtoul(buf
, 10, &value
);
228 if (line6_send_program(&variax
->line6
, value
) == 0)
229 variax
->model
= value
;
235 "read" request on "active" special file.
237 static ssize_t
variax_get_active(struct device
*dev
,
238 struct device_attribute
*attr
, char *buf
)
240 struct usb_line6_variax
*variax
= usb_get_intfdata(to_usb_interface(dev
));
241 return sprintf(buf
, "%d\n", variax
->buffer_activate
[VARIAX_OFFSET_ACTIVATE
]);
245 "write" request on "active" special file.
247 static ssize_t
variax_set_active(struct device
*dev
,
248 struct device_attribute
*attr
,
249 const char *buf
, size_t count
)
251 struct usb_line6_variax
*variax
= usb_get_intfdata(to_usb_interface(dev
));
255 ret
= strict_strtoul(buf
, 10, &value
);
259 variax
->buffer_activate
[VARIAX_OFFSET_ACTIVATE
] = value
? 1 : 0;
260 line6_send_raw_message_async(&variax
->line6
, variax
->buffer_activate
,
261 sizeof(variax_activate
));
266 "read" request on "tone" special file.
268 static ssize_t
variax_get_tone(struct device
*dev
,
269 struct device_attribute
*attr
, char *buf
)
271 struct usb_line6_variax
*variax
= usb_get_intfdata(to_usb_interface(dev
));
272 return sprintf(buf
, "%d\n", variax
->tone
);
276 "write" request on "tone" special file.
278 static ssize_t
variax_set_tone(struct device
*dev
,
279 struct device_attribute
*attr
,
280 const char *buf
, size_t count
)
282 struct usb_line6_variax
*variax
= usb_get_intfdata(to_usb_interface(dev
));
286 ret
= strict_strtoul(buf
, 10, &value
);
290 if (line6_transmit_parameter(&variax
->line6
, VARIAXMIDI_tone
,
292 variax
->tone
= value
;
297 static ssize_t
get_string(char *buf
, const char *data
, int length
)
300 memcpy(buf
, data
, length
);
302 for (i
= length
; i
--;) {
305 if ((c
!= 0) && (c
!= ' '))
314 "read" request on "name" special file.
316 static ssize_t
variax_get_name(struct device
*dev
,
317 struct device_attribute
*attr
, char *buf
)
319 struct usb_line6_variax
*variax
= usb_get_intfdata(to_usb_interface(dev
));
320 line6_wait_dump(&variax
->dumpreq
, 0);
321 return get_string(buf
, variax
->model_data
.name
,
322 sizeof(variax
->model_data
.name
));
326 "read" request on "bank" special file.
328 static ssize_t
variax_get_bank(struct device
*dev
,
329 struct device_attribute
*attr
, char *buf
)
331 struct usb_line6_variax
*variax
= usb_get_intfdata(to_usb_interface(dev
));
332 line6_wait_dump(&variax
->dumpreq
, 0);
333 return get_string(buf
, variax
->bank
, sizeof(variax
->bank
));
337 "read" request on "dump" special file.
339 static ssize_t
variax_get_dump(struct device
*dev
,
340 struct device_attribute
*attr
, char *buf
)
342 struct usb_line6_variax
*variax
= usb_get_intfdata(to_usb_interface(dev
));
344 retval
= line6_wait_dump(&variax
->dumpreq
, 0);
347 memcpy(buf
, &variax
->model_data
.control
,
348 sizeof(variax
->model_data
.control
));
349 return sizeof(variax
->model_data
.control
);
355 "write" request on "raw" special file.
357 static ssize_t
variax_set_raw2(struct device
*dev
,
358 struct device_attribute
*attr
,
359 const char *buf
, size_t count
)
361 struct usb_line6_variax
*variax
= usb_get_intfdata(to_usb_interface(dev
));
368 sysex
= variax_alloc_sysex_buffer(variax
, VARIAX_SYSEX_PARAM
, size
);
373 for (i
= 0; i
< count
; i
+= 3) {
374 const unsigned char *p1
= buf
+ i
;
375 char *p2
= sysex
+ SYSEX_DATA_OFS
+ i
* 2;
376 p2
[0] = p1
[2] & 0x0f;
378 p2
[2] = p1
[1] & 0x0f;
380 p2
[4] = p1
[0] & 0x0f;
384 line6_send_sysex_message(&variax
->line6
, sysex
, size
);
391 /* Variax workbench special files: */
392 static DEVICE_ATTR(model
, S_IWUGO
| S_IRUGO
, variax_get_model
, variax_set_model
);
393 static DEVICE_ATTR(volume
, S_IWUGO
| S_IRUGO
, variax_get_volume
, variax_set_volume
);
394 static DEVICE_ATTR(tone
, S_IWUGO
| S_IRUGO
, variax_get_tone
, variax_set_tone
);
395 static DEVICE_ATTR(name
, S_IRUGO
, variax_get_name
, line6_nop_write
);
396 static DEVICE_ATTR(bank
, S_IRUGO
, variax_get_bank
, line6_nop_write
);
397 static DEVICE_ATTR(dump
, S_IRUGO
, variax_get_dump
, line6_nop_write
);
398 static DEVICE_ATTR(active
, S_IWUGO
| S_IRUGO
, variax_get_active
, variax_set_active
);
401 static DEVICE_ATTR(raw
, S_IWUGO
, line6_nop_read
, line6_set_raw
);
402 static DEVICE_ATTR(raw2
, S_IWUGO
, line6_nop_read
, variax_set_raw2
);
409 static void variax_destruct(struct usb_interface
*interface
)
411 struct usb_line6_variax
*variax
= usb_get_intfdata(interface
);
412 struct usb_line6
*line6
;
416 line6
= &variax
->line6
;
419 line6_cleanup_audio(line6
);
421 /* free dump request data: */
422 line6_dumpreq_destructbuf(&variax
->dumpreq
, 2);
423 line6_dumpreq_destructbuf(&variax
->dumpreq
, 1);
424 line6_dumpreq_destruct(&variax
->dumpreq
);
426 kfree(variax
->buffer_activate
);
427 del_timer_sync(&variax
->activate_timer
);
431 Create sysfs entries.
433 static int variax_create_files2(struct device
*dev
)
436 CHECK_RETURN(device_create_file(dev
, &dev_attr_model
));
437 CHECK_RETURN(device_create_file(dev
, &dev_attr_volume
));
438 CHECK_RETURN(device_create_file(dev
, &dev_attr_tone
));
439 CHECK_RETURN(device_create_file(dev
, &dev_attr_name
));
440 CHECK_RETURN(device_create_file(dev
, &dev_attr_bank
));
441 CHECK_RETURN(device_create_file(dev
, &dev_attr_dump
));
442 CHECK_RETURN(device_create_file(dev
, &dev_attr_active
));
444 CHECK_RETURN(device_create_file(dev
, &dev_attr_raw
));
445 CHECK_RETURN(device_create_file(dev
, &dev_attr_raw2
));
451 Init workbench device.
453 int variax_init(struct usb_interface
*interface
,
454 struct usb_line6_variax
*variax
)
458 if ((interface
== NULL
) || (variax
== NULL
))
461 /* initialize USB buffers: */
462 err
= line6_dumpreq_init(&variax
->dumpreq
, variax_request_model1
,
463 sizeof(variax_request_model1
));
466 dev_err(&interface
->dev
, "Out of memory\n");
467 variax_destruct(interface
);
471 err
= line6_dumpreq_initbuf(&variax
->dumpreq
, variax_request_model2
,
472 sizeof(variax_request_model2
), 1);
475 dev_err(&interface
->dev
, "Out of memory\n");
476 variax_destruct(interface
);
480 err
= line6_dumpreq_initbuf(&variax
->dumpreq
, variax_request_bank
,
481 sizeof(variax_request_bank
), 2);
484 dev_err(&interface
->dev
, "Out of memory\n");
485 variax_destruct(interface
);
489 variax
->buffer_activate
= kmemdup(variax_activate
,
490 sizeof(variax_activate
), GFP_KERNEL
);
492 if (variax
->buffer_activate
== NULL
) {
493 dev_err(&interface
->dev
, "Out of memory\n");
494 variax_destruct(interface
);
498 init_timer(&variax
->activate_timer
);
500 /* create sysfs entries: */
501 err
= variax_create_files(0, 0, &interface
->dev
);
503 variax_destruct(interface
);
507 err
= variax_create_files2(&interface
->dev
);
509 variax_destruct(interface
);
513 /* initialize audio system: */
514 err
= line6_init_audio(&variax
->line6
);
516 variax_destruct(interface
);
520 /* initialize MIDI subsystem: */
521 err
= line6_init_midi(&variax
->line6
);
523 variax_destruct(interface
);
527 /* register audio system: */
528 err
= line6_register_audio(&variax
->line6
);
530 variax_destruct(interface
);
534 variax_activate_delayed(variax
, VARIAX_ACTIVATE_DELAY
);
535 line6_startup_delayed(&variax
->dumpreq
, VARIAX_STARTUP_DELAY
,
536 variax_startup_timeout
, variax
);
541 Workbench device disconnected.
543 void variax_disconnect(struct usb_interface
*interface
)
547 if (interface
== NULL
)
549 dev
= &interface
->dev
;
552 /* remove sysfs entries: */
553 variax_remove_files(0, 0, dev
);
554 device_remove_file(dev
, &dev_attr_model
);
555 device_remove_file(dev
, &dev_attr_volume
);
556 device_remove_file(dev
, &dev_attr_tone
);
557 device_remove_file(dev
, &dev_attr_name
);
558 device_remove_file(dev
, &dev_attr_bank
);
559 device_remove_file(dev
, &dev_attr_dump
);
560 device_remove_file(dev
, &dev_attr_active
);
562 device_remove_file(dev
, &dev_attr_raw
);
563 device_remove_file(dev
, &dev_attr_raw2
);
567 variax_destruct(interface
);