]> Pileus Git - ~andy/linux/blob - drivers/staging/line6/variax.c
staging: line6: drop retrieve_channel sysfs attr
[~andy/linux] / drivers / staging / line6 / variax.c
1 /*
2  * Line6 Linux USB driver - 0.9.1beta
3  *
4  * Copyright (C) 2004-2010 Markus Grabner (grabner@icg.tugraz.at)
5  *
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.
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         This message is sent by the device during initialization and identifies
28         the connected guitar model.
29 */
30 static const char variax_init_model[] = {
31         0xf0, 0x00, 0x01, 0x0c, 0x07, 0x00, 0x69, 0x02,
32         0x00
33 };
34
35 /*
36         This message is sent by the device during initialization and identifies
37         the connected guitar version.
38 */
39 static const char variax_init_version[] = {
40         0xf0, 0x7e, 0x7f, 0x06, 0x02, 0x00, 0x01, 0x0c,
41         0x07, 0x00, 0x00, 0x00
42 };
43
44 /*
45         This message is the last one sent by the device during initialization.
46 */
47 static const char variax_init_done[] = {
48         0xf0, 0x00, 0x01, 0x0c, 0x07, 0x00, 0x6b
49 };
50
51 static const char variax_activate[] = {
52         0xf0, 0x00, 0x01, 0x0c, 0x07, 0x00, 0x2a, 0x01,
53         0xf7
54 };
55
56 static const char variax_request_bank[] = {
57         0xf0, 0x00, 0x01, 0x0c, 0x07, 0x00, 0x6d, 0xf7
58 };
59
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
64 };
65
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
70 };
71
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);
77
78 /*
79         Decode data transmitted by workbench.
80 */
81 static 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
93 static 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         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.
105 */
106
107 static void variax_startup1(struct usb_line6_variax *variax)
108 {
109         CHECK_STARTUP_PROGRESS(variax->startup_progress, VARIAX_STARTUP_INIT);
110
111         /* delay startup procedure: */
112         line6_start_timer(&variax->startup_timer1, VARIAX_STARTUP_DELAY1,
113                           variax_startup2, (unsigned long)variax);
114 }
115
116 static 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         /* schedule another startup procedure until startup is complete: */
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         /* request firmware version: */
130         line6_version_request_async(line6);
131 }
132
133 static void variax_startup3(struct usb_line6_variax *variax)
134 {
135         CHECK_STARTUP_PROGRESS(variax->startup_progress, VARIAX_STARTUP_WAIT);
136
137         /* delay startup procedure: */
138         line6_start_timer(&variax->startup_timer2, VARIAX_STARTUP_DELAY3,
139                           variax_startup4, (unsigned long)variax);
140 }
141
142 static 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         /* activate device: */
149         variax_activate_async(variax, 1);
150         line6_start_timer(&variax->startup_timer2, VARIAX_STARTUP_DELAY4,
151                           variax_startup5, (unsigned long)variax);
152 }
153
154 static 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         /* current model dump: */
161         line6_dump_request_async(&variax->dumpreq, &variax->line6, 0,
162                                  VARIAX_DUMP_PASS1);
163         /* passes 2 and 3 are performed implicitly before entering
164          * variax_startup6.
165          */
166 }
167
168 static void variax_startup6(struct usb_line6_variax *variax)
169 {
170         CHECK_STARTUP_PROGRESS(variax->startup_progress,
171                                VARIAX_STARTUP_WORKQUEUE);
172
173         /* schedule work for global work queue: */
174         schedule_work(&variax->startup_work);
175 }
176
177 static void variax_startup7(struct work_struct *work)
178 {
179         struct usb_line6_variax *variax =
180             container_of(work, struct usb_line6_variax, startup_work);
181         struct usb_line6 *line6 = &variax->line6;
182
183         CHECK_STARTUP_PROGRESS(variax->startup_progress, VARIAX_STARTUP_SETUP);
184
185         /* ALSA audio interface: */
186         line6_register_audio(&variax->line6);
187
188         /* device files: */
189         line6_variax_create_files(0, 0, line6->ifcdev);
190         variax_create_files2(line6->ifcdev);
191 }
192
193 /*
194         Process a completely received message.
195 */
196 void line6_variax_process_message(struct usb_line6_variax *variax)
197 {
198         const unsigned char *buf = variax->line6.buffer_message;
199
200         switch (buf[0]) {
201         case LINE6_PARAM_CHANGE | LINE6_CHANNEL_HOST:
202                 switch (buf[1]) {
203                 case VARIAXMIDI_volume:
204                         variax->volume = buf[2];
205                         break;
206
207                 case VARIAXMIDI_tone:
208                         variax->tone = buf[2];
209                 }
210
211                 break;
212
213         case LINE6_PROGRAM_CHANGE | LINE6_CHANNEL_DEVICE:
214         case LINE6_PROGRAM_CHANGE | LINE6_CHANNEL_HOST:
215                 variax->model = buf[1];
216                 line6_dump_request_async(&variax->dumpreq, &variax->line6, 0,
217                                          VARIAX_DUMP_PASS1);
218                 break;
219
220         case LINE6_RESET:
221                 dev_info(variax->line6.ifcdev, "VARIAX reset\n");
222                 break;
223
224         case LINE6_SYSEX_BEGIN:
225                 if (memcmp(buf + 1, variax_request_model1 + 1,
226                            VARIAX_MODEL_HEADER_LENGTH - 1) == 0) {
227                         if (variax->line6.message_length ==
228                             VARIAX_MODEL_MESSAGE_LENGTH) {
229                                 switch (variax->dumpreq.in_progress) {
230                                 case VARIAX_DUMP_PASS1:
231                                         variax_decode(buf +
232                                                       VARIAX_MODEL_HEADER_LENGTH,
233                                                       (unsigned char *)
234                                                       &variax->model_data,
235                                                       (sizeof
236                                                        (variax->model_data.
237                                                         name) +
238                                                        sizeof(variax->
239                                                               model_data.
240                                                               control)
241                                                        / 2) * 2);
242                                         line6_dump_request_async
243                                             (&variax->dumpreq, &variax->line6,
244                                              1, VARIAX_DUMP_PASS2);
245                                         break;
246
247                                 case VARIAX_DUMP_PASS2:
248                                         /* model name is transmitted twice, so skip it here: */
249                                         variax_decode(buf +
250                                                       VARIAX_MODEL_HEADER_LENGTH,
251                                                       (unsigned char *)
252                                                       &variax->
253                                                       model_data.control +
254                                                       sizeof(variax->model_data.
255                                                              control)
256                                                       / 2,
257                                                       sizeof(variax->model_data.
258                                                              control)
259                                                       / 2 * 2);
260                                         line6_dump_request_async
261                                             (&variax->dumpreq, &variax->line6,
262                                              2, VARIAX_DUMP_PASS3);
263                                 }
264                         } else {
265                                 dev_dbg(variax->line6.ifcdev,
266                                         "illegal length %d of model data\n",
267                                         variax->line6.message_length);
268                                 line6_dump_finished(&variax->dumpreq);
269                         }
270                 } else if (memcmp(buf + 1, variax_request_bank + 1,
271                                   sizeof(variax_request_bank) - 2) == 0) {
272                         memcpy(variax->bank,
273                                buf + sizeof(variax_request_bank) - 1,
274                                sizeof(variax->bank));
275                         line6_dump_finished(&variax->dumpreq);
276                         variax_startup6(variax);
277                 } else if (memcmp(buf + 1, variax_init_model + 1,
278                                   sizeof(variax_init_model) - 1) == 0) {
279                         memcpy(variax->guitar,
280                                buf + sizeof(variax_init_model),
281                                sizeof(variax->guitar));
282                 } else if (memcmp(buf + 1, variax_init_version + 1,
283                                   sizeof(variax_init_version) - 1) == 0) {
284                         variax_startup3(variax);
285                 } else if (memcmp(buf + 1, variax_init_done + 1,
286                                   sizeof(variax_init_done) - 1) == 0) {
287                         /* notify of complete initialization: */
288                         variax_startup4((unsigned long)variax);
289                 }
290
291                 break;
292
293         case LINE6_SYSEX_END:
294                 break;
295
296         default:
297                 dev_dbg(variax->line6.ifcdev,
298                         "Variax: unknown message %02X\n", buf[0]);
299         }
300 }
301
302 /*
303         "read" request on "volume" special file.
304 */
305 static 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         "write" request on "volume" special file.
315 */
316 static 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         u8 value;
323         int ret;
324
325         ret = kstrtou8(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         "read" request on "model" special file.
338 */
339 static 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         "write" request on "model" special file.
349 */
350 static 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         u8 value;
357         int ret;
358
359         ret = kstrtou8(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         "read" request on "active" special file.
371 */
372 static 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         "write" request on "active" special file.
383 */
384 static 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         u8 value;
391         int ret;
392
393         ret = kstrtou8(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         "read" request on "tone" special file.
403 */
404 static 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         "write" request on "tone" special file.
414 */
415 static 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         u8 value;
422         int ret;
423
424         ret = kstrtou8(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
435 static 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         "read" request on "name" special file.
453 */
454 static 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         "read" request on "bank" special file.
466 */
467 static 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         "read" request on "dump" special file.
478 */
479 static 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         "read" request on "guitar" special file.
495 */
496 static 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
506 static 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         "write" request on "raw" special file.
515 */
516 static 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 /* Variax workbench special files: */
552 static DEVICE_ATTR(model, S_IWUSR | S_IRUGO, variax_get_model,
553                    variax_set_model);
554 static DEVICE_ATTR(volume, S_IWUSR | S_IRUGO, variax_get_volume,
555                    variax_set_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,
561                    variax_set_active);
562 static DEVICE_ATTR(guitar, S_IRUGO, variax_get_guitar, line6_nop_write);
563
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);
567 #endif
568
569 /*
570         Variax destructor.
571 */
572 static 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         /* free dump request data: */
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         Create sysfs entries.
594 */
595 static 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          Try to init workbench device.
615 */
616 static 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         /* initialize USB buffers: */
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         /* initialize audio system: */
662         err = line6_init_audio(&variax->line6);
663         if (err < 0)
664                 return err;
665
666         /* initialize MIDI subsystem: */
667         err = line6_init_midi(&variax->line6);
668         if (err < 0)
669                 return err;
670
671         /* initiate startup procedure: */
672         variax_startup1(variax);
673         return 0;
674 }
675
676 /*
677          Init workbench device (and clean up in case of failure).
678 */
679 int 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         Workbench device disconnected.
692 */
693 void 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                 /* 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);
715 #endif
716         }
717
718         variax_destruct(interface);
719 }