]> rtime.felk.cvut.cz Git - mcf548x/linux.git/blob - drivers/staging/line6/variax.c
Initial 2.6.37
[mcf548x/linux.git] / 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 variax_startup6 */
164 }
165
166 static void variax_startup6(struct usb_line6_variax *variax)
167 {
168         CHECK_STARTUP_PROGRESS(variax->startup_progress,
169                                VARIAX_STARTUP_WORKQUEUE);
170
171         /* schedule work for global work queue: */
172         schedule_work(&variax->startup_work);
173 }
174
175 static 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         /* ALSA audio interface: */
184         line6_register_audio(&variax->line6);
185
186         /* device files: */
187         line6_variax_create_files(0, 0, line6->ifcdev);
188         variax_create_files2(line6->ifcdev);
189 }
190
191 /*
192         Process a completely received message.
193 */
194 void 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                                         /* model name is transmitted twice, so skip it here: */
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                         /* notify of complete initialization: */
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         "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         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         "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         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         "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         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         "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         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
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         struct usb_line6 *line6;
576
577         if (variax == NULL)
578                 return;
579         line6 = &variax->line6;
580         if (line6 == NULL)
581                 return;
582         line6_cleanup_audio(line6);
583
584         del_timer(&variax->startup_timer1);
585         del_timer(&variax->startup_timer2);
586         cancel_work_sync(&variax->startup_work);
587
588         /* free dump request data: */
589         line6_dumpreq_destructbuf(&variax->dumpreq, 2);
590         line6_dumpreq_destructbuf(&variax->dumpreq, 1);
591         line6_dumpreq_destruct(&variax->dumpreq);
592
593         kfree(variax->buffer_activate);
594 }
595
596 /*
597         Create sysfs entries.
598 */
599 static int variax_create_files2(struct device *dev)
600 {
601         int err;
602         CHECK_RETURN(device_create_file(dev, &dev_attr_model));
603         CHECK_RETURN(device_create_file(dev, &dev_attr_volume));
604         CHECK_RETURN(device_create_file(dev, &dev_attr_tone));
605         CHECK_RETURN(device_create_file(dev, &dev_attr_name));
606         CHECK_RETURN(device_create_file(dev, &dev_attr_bank));
607         CHECK_RETURN(device_create_file(dev, &dev_attr_dump));
608         CHECK_RETURN(device_create_file(dev, &dev_attr_active));
609         CHECK_RETURN(device_create_file(dev, &dev_attr_guitar));
610 #ifdef CONFIG_LINE6_USB_RAW
611         CHECK_RETURN(device_create_file(dev, &dev_attr_raw));
612         CHECK_RETURN(device_create_file(dev, &dev_attr_raw2));
613 #endif
614         return 0;
615 }
616
617 /*
618          Try to init workbench device.
619 */
620 static int variax_try_init(struct usb_interface *interface,
621                            struct usb_line6_variax *variax)
622 {
623         int err;
624
625         init_timer(&variax->startup_timer1);
626         init_timer(&variax->startup_timer2);
627         INIT_WORK(&variax->startup_work, variax_startup7);
628
629         if ((interface == NULL) || (variax == NULL))
630                 return -ENODEV;
631
632         /* initialize USB buffers: */
633         err = line6_dumpreq_init(&variax->dumpreq, variax_request_model1,
634                                  sizeof(variax_request_model1));
635
636         if (err < 0) {
637                 dev_err(&interface->dev, "Out of memory\n");
638                 return err;
639         }
640
641         err = line6_dumpreq_initbuf(&variax->dumpreq, variax_request_model2,
642                                     sizeof(variax_request_model2), 1);
643
644         if (err < 0) {
645                 dev_err(&interface->dev, "Out of memory\n");
646                 return err;
647         }
648
649         err = line6_dumpreq_initbuf(&variax->dumpreq, variax_request_bank,
650                                     sizeof(variax_request_bank), 2);
651
652         if (err < 0) {
653                 dev_err(&interface->dev, "Out of memory\n");
654                 return err;
655         }
656
657         variax->buffer_activate = kmemdup(variax_activate,
658                                           sizeof(variax_activate), GFP_KERNEL);
659
660         if (variax->buffer_activate == NULL) {
661                 dev_err(&interface->dev, "Out of memory\n");
662                 return -ENOMEM;
663         }
664
665         /* initialize audio system: */
666         err = line6_init_audio(&variax->line6);
667         if (err < 0)
668                 return err;
669
670         /* initialize MIDI subsystem: */
671         err = line6_init_midi(&variax->line6);
672         if (err < 0)
673                 return err;
674
675         /* initiate startup procedure: */
676         variax_startup1(variax);
677         return 0;
678 }
679
680 /*
681          Init workbench device (and clean up in case of failure).
682 */
683 int line6_variax_init(struct usb_interface *interface,
684                       struct usb_line6_variax *variax)
685 {
686         int err = variax_try_init(interface, variax);
687
688         if (err < 0)
689                 variax_destruct(interface);
690
691         return err;
692 }
693
694 /*
695         Workbench device disconnected.
696 */
697 void line6_variax_disconnect(struct usb_interface *interface)
698 {
699         struct device *dev;
700
701         if (interface == NULL)
702                 return;
703         dev = &interface->dev;
704
705         if (dev != NULL) {
706                 /* remove sysfs entries: */
707                 line6_variax_remove_files(0, 0, dev);
708                 device_remove_file(dev, &dev_attr_model);
709                 device_remove_file(dev, &dev_attr_volume);
710                 device_remove_file(dev, &dev_attr_tone);
711                 device_remove_file(dev, &dev_attr_name);
712                 device_remove_file(dev, &dev_attr_bank);
713                 device_remove_file(dev, &dev_attr_dump);
714                 device_remove_file(dev, &dev_attr_active);
715                 device_remove_file(dev, &dev_attr_guitar);
716 #ifdef CONFIG_LINE6_USB_RAW
717                 device_remove_file(dev, &dev_attr_raw);
718                 device_remove_file(dev, &dev_attr_raw2);
719 #endif
720         }
721
722         variax_destruct(interface);
723 }