1
2
3
4
5
6
7
8
9
10
11
12#include <linux/slab.h>
13
14#include "audio.h"
15#include "control.h"
16#include "driver.h"
17#include "variax.h"
18
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
25
26
27
28
29
30static const char variax_init_model[] = {
31 0xf0, 0x00, 0x01, 0x0c, 0x07, 0x00, 0x69, 0x02,
32 0x00
33};
34
35
36
37
38
39static const char variax_init_version[] = {
40 0xf0, 0x7e, 0x7f, 0x06, 0x02, 0x00, 0x01, 0x0c,
41 0x07, 0x00, 0x00, 0x00
42};
43
44
45
46
47static const char variax_init_done[] = {
48 0xf0, 0x00, 0x01, 0x0c, 0x07, 0x00, 0x6b
49};
50
51static const char variax_activate[] = {
52 0xf0, 0x00, 0x01, 0x0c, 0x07, 0x00, 0x2a, 0x01,
53 0xf7
54};
55
56static const char variax_request_bank[] = {
57 0xf0, 0x00, 0x01, 0x0c, 0x07, 0x00, 0x6d, 0xf7
58};
59
60static 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
64};
65
66static 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
70};
71
72
73static int variax_create_files2(struct device *dev);
74static void variax_startup2(unsigned long data);
75static void variax_startup4(unsigned long data);
76static void variax_startup5(unsigned long data);
77
78
79
80
81static void variax_decode(const unsigned char *raw_data, unsigned char *data,
82 int raw_size)
83{
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);
88 raw_data += 6;
89 data += 3;
90 }
91}
92
93static void variax_activate_async(struct usb_line6_variax *variax, int a)
94{
95 variax->buffer_activate[VARIAX_OFFSET_ACTIVATE] = a;
96 line6_send_raw_message_async(&variax->line6, variax->buffer_activate,
97 sizeof(variax_activate));
98}
99
100
101
102
103
104
105
106
107static void variax_startup1(struct usb_line6_variax *variax)
108{
109 CHECK_STARTUP_PROGRESS(variax->startup_progress, VARIAX_STARTUP_INIT);
110
111
112 line6_start_timer(&variax->startup_timer1, VARIAX_STARTUP_DELAY1,
113 variax_startup2, (unsigned long)variax);
114}
115
116static void variax_startup2(unsigned long data)
117{
118 struct usb_line6_variax *variax = (struct usb_line6_variax *)data;
119 struct usb_line6 *line6 = &variax->line6;
120
121
122 if (variax->startup_progress >= VARIAX_STARTUP_LAST)
123 return;
124
125 variax->startup_progress = VARIAX_STARTUP_VERSIONREQ;
126 line6_start_timer(&variax->startup_timer1, VARIAX_STARTUP_DELAY1,
127 variax_startup2, (unsigned long)variax);
128
129
130 line6_version_request_async(line6);
131}
132
133static void variax_startup3(struct usb_line6_variax *variax)
134{
135 CHECK_STARTUP_PROGRESS(variax->startup_progress, VARIAX_STARTUP_WAIT);
136
137
138 line6_start_timer(&variax->startup_timer2, VARIAX_STARTUP_DELAY3,
139 variax_startup4, (unsigned long)variax);
140}
141
142static void variax_startup4(unsigned long data)
143{
144 struct usb_line6_variax *variax = (struct usb_line6_variax *)data;
145 CHECK_STARTUP_PROGRESS(variax->startup_progress,
146 VARIAX_STARTUP_ACTIVATE);
147
148
149 variax_activate_async(variax, 1);
150 line6_start_timer(&variax->startup_timer2, VARIAX_STARTUP_DELAY4,
151 variax_startup5, (unsigned long)variax);
152}
153
154static void variax_startup5(unsigned long data)
155{
156 struct usb_line6_variax *variax = (struct usb_line6_variax *)data;
157 CHECK_STARTUP_PROGRESS(variax->startup_progress,
158 VARIAX_STARTUP_DUMPREQ);
159
160
161 line6_dump_request_async(&variax->dumpreq, &variax->line6, 0,
162 VARIAX_DUMP_PASS1);
163
164}
165
166static void variax_startup6(struct usb_line6_variax *variax)
167{
168 CHECK_STARTUP_PROGRESS(variax->startup_progress,
169 VARIAX_STARTUP_WORKQUEUE);
170
171
172 schedule_work(&variax->startup_work);
173}
174
175static void variax_startup7(struct work_struct *work)
176{
177 struct usb_line6_variax *variax =
178 container_of(work, struct usb_line6_variax, startup_work);
179 struct usb_line6 *line6 = &variax->line6;
180
181 CHECK_STARTUP_PROGRESS(variax->startup_progress, VARIAX_STARTUP_SETUP);
182
183
184 line6_register_audio(&variax->line6);
185
186
187 line6_variax_create_files(0, 0, line6->ifcdev);
188 variax_create_files2(line6->ifcdev);
189}
190
191
192
193
194void line6_variax_process_message(struct usb_line6_variax *variax)
195{
196 const unsigned char *buf = variax->line6.buffer_message;
197
198 switch (buf[0]) {
199 case LINE6_PARAM_CHANGE | LINE6_CHANNEL_HOST:
200 switch (buf[1]) {
201 case VARIAXMIDI_volume:
202 variax->volume = buf[2];
203 break;
204
205 case VARIAXMIDI_tone:
206 variax->tone = buf[2];
207 }
208
209 break;
210
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,
215 VARIAX_DUMP_PASS1);
216 break;
217
218 case LINE6_RESET:
219 dev_info(variax->line6.ifcdev, "VARIAX reset\n");
220 break;
221
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:
229 variax_decode(buf +
230 VARIAX_MODEL_HEADER_LENGTH,
231 (unsigned char *)
232 &variax->model_data,
233 (sizeof
234 (variax->model_data.
235 name) +
236 sizeof(variax->
237 model_data.
238 control)
239 / 2) * 2);
240 line6_dump_request_async
241 (&variax->dumpreq, &variax->line6,
242 1, VARIAX_DUMP_PASS2);
243 break;
244
245 case VARIAX_DUMP_PASS2:
246
247 variax_decode(buf +
248 VARIAX_MODEL_HEADER_LENGTH,
249 (unsigned char *)
250 &variax->
251 model_data.control +
252 sizeof(variax->model_data.
253 control)
254 / 2,
255 sizeof(variax->model_data.
256 control)
257 / 2 * 2);
258 line6_dump_request_async
259 (&variax->dumpreq, &variax->line6,
260 2, VARIAX_DUMP_PASS3);
261 }
262 } else {
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);
268 }
269 } else if (memcmp(buf + 1, variax_request_bank + 1,
270 sizeof(variax_request_bank) - 2) == 0) {
271 memcpy(variax->bank,
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
287 variax_startup4((unsigned long)variax);
288 }
289
290 break;
291
292 case LINE6_SYSEX_END:
293 break;
294
295 default:
296 DEBUG_MESSAGES(dev_err
297 (variax->line6.ifcdev,
298 "Variax: unknown message %02X\n", buf[0]));
299 }
300}
301
302
303
304
305static ssize_t variax_get_volume(struct device *dev,
306 struct device_attribute *attr, char *buf)
307{
308 struct usb_line6_variax *variax =
309 usb_get_intfdata(to_usb_interface(dev));
310 return sprintf(buf, "%d\n", variax->volume);
311}
312
313
314
315
316static ssize_t variax_set_volume(struct device *dev,
317 struct device_attribute *attr,
318 const char *buf, size_t count)
319{
320 struct usb_line6_variax *variax =
321 usb_get_intfdata(to_usb_interface(dev));
322 unsigned long value;
323 int ret;
324
325 ret = strict_strtoul(buf, 10, &value);
326 if (ret)
327 return ret;
328
329 if (line6_transmit_parameter(&variax->line6, VARIAXMIDI_volume,
330 value) == 0)
331 variax->volume = value;
332
333 return count;
334}
335
336
337
338
339static ssize_t variax_get_model(struct device *dev,
340 struct device_attribute *attr, char *buf)
341{
342 struct usb_line6_variax *variax =
343 usb_get_intfdata(to_usb_interface(dev));
344 return sprintf(buf, "%d\n", variax->model);
345}
346
347
348
349
350static ssize_t variax_set_model(struct device *dev,
351 struct device_attribute *attr,
352 const char *buf, size_t count)
353{
354 struct usb_line6_variax *variax =
355 usb_get_intfdata(to_usb_interface(dev));
356 unsigned long value;
357 int ret;
358
359 ret = strict_strtoul(buf, 10, &value);
360 if (ret)
361 return ret;
362
363 if (line6_send_program(&variax->line6, value) == 0)
364 variax->model = value;
365
366 return count;
367}
368
369
370
371
372static ssize_t variax_get_active(struct device *dev,
373 struct device_attribute *attr, char *buf)
374{
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]);
379}
380
381
382
383
384static ssize_t variax_set_active(struct device *dev,
385 struct device_attribute *attr,
386 const char *buf, size_t count)
387{
388 struct usb_line6_variax *variax =
389 usb_get_intfdata(to_usb_interface(dev));
390 unsigned long value;
391 int ret;
392
393 ret = strict_strtoul(buf, 10, &value);
394 if (ret)
395 return ret;
396
397 variax_activate_async(variax, value ? 1 : 0);
398 return count;
399}
400
401
402
403
404static ssize_t variax_get_tone(struct device *dev,
405 struct device_attribute *attr, char *buf)
406{
407 struct usb_line6_variax *variax =
408 usb_get_intfdata(to_usb_interface(dev));
409 return sprintf(buf, "%d\n", variax->tone);
410}
411
412
413
414
415static ssize_t variax_set_tone(struct device *dev,
416 struct device_attribute *attr,
417 const char *buf, size_t count)
418{
419 struct usb_line6_variax *variax =
420 usb_get_intfdata(to_usb_interface(dev));
421 unsigned long value;
422 int ret;
423
424 ret = strict_strtoul(buf, 10, &value);
425 if (ret)
426 return ret;
427
428 if (line6_transmit_parameter(&variax->line6, VARIAXMIDI_tone,
429 value) == 0)
430 variax->tone = value;
431
432 return count;
433}
434
435static ssize_t get_string(char *buf, const char *data, int length)
436{
437 int i;
438 memcpy(buf, data, length);
439
440 for (i = length; i--;) {
441 char c = buf[i];
442
443 if ((c != 0) && (c != ' '))
444 break;
445 }
446
447 buf[i + 1] = '\n';
448 return i + 2;
449}
450
451
452
453
454static ssize_t variax_get_name(struct device *dev,
455 struct device_attribute *attr, char *buf)
456{
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));
462}
463
464
465
466
467static ssize_t variax_get_bank(struct device *dev,
468 struct device_attribute *attr, char *buf)
469{
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));
474}
475
476
477
478
479static ssize_t variax_get_dump(struct device *dev,
480 struct device_attribute *attr, char *buf)
481{
482 struct usb_line6_variax *variax =
483 usb_get_intfdata(to_usb_interface(dev));
484 int retval;
485 retval = line6_dump_wait_interruptible(&variax->dumpreq);
486 if (retval < 0)
487 return retval;
488 memcpy(buf, &variax->model_data.control,
489 sizeof(variax->model_data.control));
490 return sizeof(variax->model_data.control);
491}
492
493
494
495
496static ssize_t variax_get_guitar(struct device *dev,
497 struct device_attribute *attr, char *buf)
498{
499 struct usb_line6_variax *variax =
500 usb_get_intfdata(to_usb_interface(dev));
501 return sprintf(buf, "%s\n", variax->guitar);
502}
503
504#ifdef CONFIG_LINE6_USB_RAW
505
506static char *variax_alloc_sysex_buffer(struct usb_line6_variax *variax,
507 int code, int size)
508{
509 return line6_alloc_sysex_buffer(&variax->line6, VARIAX_SYSEX_CODE, code,
510 size);
511}
512
513
514
515
516static ssize_t variax_set_raw2(struct device *dev,
517 struct device_attribute *attr,
518 const char *buf, size_t count)
519{
520 struct usb_line6_variax *variax =
521 usb_get_intfdata(to_usb_interface(dev));
522 int size;
523 int i;
524 char *sysex;
525
526 count -= count % 3;
527 size = count * 2;
528 sysex = variax_alloc_sysex_buffer(variax, VARIAX_SYSEX_PARAM, size);
529
530 if (!sysex)
531 return 0;
532
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;
537 p2[1] = p1[2] >> 4;
538 p2[2] = p1[1] & 0x0f;
539 p2[3] = p1[1] >> 4;
540 p2[4] = p1[0] & 0x0f;
541 p2[5] = p1[0] >> 4;
542 }
543
544 line6_send_sysex_message(&variax->line6, sysex, size);
545 kfree(sysex);
546 return count;
547}
548
549#endif
550
551
552static DEVICE_ATTR(model, S_IWUSR | S_IRUGO, variax_get_model,
553 variax_set_model);
554static DEVICE_ATTR(volume, S_IWUSR | S_IRUGO, variax_get_volume,
555 variax_set_volume);
556static DEVICE_ATTR(tone, S_IWUSR | S_IRUGO, variax_get_tone, variax_set_tone);
557static DEVICE_ATTR(name, S_IRUGO, variax_get_name, line6_nop_write);
558static DEVICE_ATTR(bank, S_IRUGO, variax_get_bank, line6_nop_write);
559static DEVICE_ATTR(dump, S_IRUGO, variax_get_dump, line6_nop_write);
560static DEVICE_ATTR(active, S_IWUSR | S_IRUGO, variax_get_active,
561 variax_set_active);
562static DEVICE_ATTR(guitar, S_IRUGO, variax_get_guitar, line6_nop_write);
563
564#ifdef CONFIG_LINE6_USB_RAW
565static DEVICE_ATTR(raw, S_IWUSR, line6_nop_read, line6_set_raw);
566static DEVICE_ATTR(raw2, S_IWUSR, line6_nop_read, variax_set_raw2);
567#endif
568
569
570
571
572static void variax_destruct(struct usb_interface *interface)
573{
574 struct usb_line6_variax *variax = usb_get_intfdata(interface);
575
576 if (variax == NULL)
577 return;
578 line6_cleanup_audio(&variax->line6);
579
580 del_timer(&variax->startup_timer1);
581 del_timer(&variax->startup_timer2);
582 cancel_work_sync(&variax->startup_work);
583
584
585 line6_dumpreq_destructbuf(&variax->dumpreq, 2);
586 line6_dumpreq_destructbuf(&variax->dumpreq, 1);
587 line6_dumpreq_destruct(&variax->dumpreq);
588
589 kfree(variax->buffer_activate);
590}
591
592
593
594
595static int variax_create_files2(struct device *dev)
596{
597 int err;
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));
609#endif
610 return 0;
611}
612
613
614
615
616static int variax_try_init(struct usb_interface *interface,
617 struct usb_line6_variax *variax)
618{
619 int err;
620
621 init_timer(&variax->startup_timer1);
622 init_timer(&variax->startup_timer2);
623 INIT_WORK(&variax->startup_work, variax_startup7);
624
625 if ((interface == NULL) || (variax == NULL))
626 return -ENODEV;
627
628
629 err = line6_dumpreq_init(&variax->dumpreq, variax_request_model1,
630 sizeof(variax_request_model1));
631
632 if (err < 0) {
633 dev_err(&interface->dev, "Out of memory\n");
634 return err;
635 }
636
637 err = line6_dumpreq_initbuf(&variax->dumpreq, variax_request_model2,
638 sizeof(variax_request_model2), 1);
639
640 if (err < 0) {
641 dev_err(&interface->dev, "Out of memory\n");
642 return err;
643 }
644
645 err = line6_dumpreq_initbuf(&variax->dumpreq, variax_request_bank,
646 sizeof(variax_request_bank), 2);
647
648 if (err < 0) {
649 dev_err(&interface->dev, "Out of memory\n");
650 return err;
651 }
652
653 variax->buffer_activate = kmemdup(variax_activate,
654 sizeof(variax_activate), GFP_KERNEL);
655
656 if (variax->buffer_activate == NULL) {
657 dev_err(&interface->dev, "Out of memory\n");
658 return -ENOMEM;
659 }
660
661
662 err = line6_init_audio(&variax->line6);
663 if (err < 0)
664 return err;
665
666
667 err = line6_init_midi(&variax->line6);
668 if (err < 0)
669 return err;
670
671
672 variax_startup1(variax);
673 return 0;
674}
675
676
677
678
679int line6_variax_init(struct usb_interface *interface,
680 struct usb_line6_variax *variax)
681{
682 int err = variax_try_init(interface, variax);
683
684 if (err < 0)
685 variax_destruct(interface);
686
687 return err;
688}
689
690
691
692
693void line6_variax_disconnect(struct usb_interface *interface)
694{
695 struct device *dev;
696
697 if (interface == NULL)
698 return;
699 dev = &interface->dev;
700
701 if (dev != NULL) {
702
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);
715#endif
716 }
717
718 variax_destruct(interface);
719}
720