Linux Kernel  3.7.1
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Groups Pages
variax.c
Go to the documentation of this file.
1 /*
2  * Line6 Linux USB driver - 0.9.1beta
3  *
4  * Copyright (C) 2004-2010 Markus Grabner ([email protected])
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 {
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 {
110 
111  /* delay startup procedure: */
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 
127  variax_startup2, (unsigned long)variax);
128 
129  /* request firmware version: */
131 }
132 
133 static void variax_startup3(struct usb_line6_variax *variax)
134 {
136 
137  /* delay startup procedure: */
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;
147 
148  /* activate device: */
149  variax_activate_async(variax, 1);
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;
159 
160  /* current model dump: */
161  line6_dump_request_async(&variax->dumpreq, &variax->line6, 0,
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 {
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 =
179  struct usb_line6 *line6 = &variax->line6;
180 
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 */
195 {
196  const unsigned char *buf = variax->line6.buffer_message;
197 
198  switch (buf[0]) {
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 
213  variax->model = buf[1];
214  line6_dump_request_async(&variax->dumpreq, &variax->line6, 0,
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 ==
227  switch (variax->dumpreq.in_progress) {
228  case VARIAX_DUMP_PASS1:
229  variax_decode(buf +
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);
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 +
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);
259  (&variax->dumpreq, &variax->line6,
260  2, VARIAX_DUMP_PASS3);
261  }
262  } else {
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:
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  u8 value;
323  int ret;
324 
325  ret = kstrtou8(buf, 10, &value);
326  if (ret)
327  return ret;
328 
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",
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 
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));
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));
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
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);
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 }