This source file includes following definitions.
- variax_activate_async
- variax_startup
- line6_variax_process_message
- line6_variax_disconnect
- variax_init
- variax_probe
   1 
   2 
   3 
   4 
   5 
   6 
   7 
   8 #include <linux/slab.h>
   9 #include <linux/spinlock.h>
  10 #include <linux/usb.h>
  11 #include <linux/wait.h>
  12 #include <linux/module.h>
  13 #include <sound/core.h>
  14 
  15 #include "driver.h"
  16 
  17 #define VARIAX_STARTUP_DELAY1 1000
  18 #define VARIAX_STARTUP_DELAY3 100
  19 #define VARIAX_STARTUP_DELAY4 100
  20 
  21 
  22 
  23 
  24 enum {
  25         VARIAX_STARTUP_VERSIONREQ,
  26         VARIAX_STARTUP_ACTIVATE,
  27         VARIAX_STARTUP_SETUP,
  28 };
  29 
  30 enum {
  31         LINE6_PODXTLIVE_VARIAX,
  32         LINE6_VARIAX
  33 };
  34 
  35 struct usb_line6_variax {
  36         
  37         struct usb_line6 line6;
  38 
  39         
  40         unsigned char *buffer_activate;
  41 
  42         
  43         int startup_progress;
  44 };
  45 
  46 #define line6_to_variax(x)      container_of(x, struct usb_line6_variax, line6)
  47 
  48 #define VARIAX_OFFSET_ACTIVATE 7
  49 
  50 
  51 
  52 
  53 
  54 static const char variax_init_version[] = {
  55         0xf0, 0x7e, 0x7f, 0x06, 0x02, 0x00, 0x01, 0x0c,
  56         0x07, 0x00, 0x00, 0x00
  57 };
  58 
  59 
  60 
  61 
  62 static const char variax_init_done[] = {
  63         0xf0, 0x00, 0x01, 0x0c, 0x07, 0x00, 0x6b
  64 };
  65 
  66 static const char variax_activate[] = {
  67         0xf0, 0x00, 0x01, 0x0c, 0x07, 0x00, 0x2a, 0x01,
  68         0xf7
  69 };
  70 
  71 static void variax_activate_async(struct usb_line6_variax *variax, int a)
  72 {
  73         variax->buffer_activate[VARIAX_OFFSET_ACTIVATE] = a;
  74         line6_send_raw_message_async(&variax->line6, variax->buffer_activate,
  75                                      sizeof(variax_activate));
  76 }
  77 
  78 
  79 
  80 
  81 
  82 
  83 
  84 
  85 static void variax_startup(struct usb_line6 *line6)
  86 {
  87         struct usb_line6_variax *variax = line6_to_variax(line6);
  88 
  89         switch (variax->startup_progress) {
  90         case VARIAX_STARTUP_VERSIONREQ:
  91                 
  92                 schedule_delayed_work(&line6->startup_work,
  93                                       msecs_to_jiffies(VARIAX_STARTUP_DELAY1));
  94                 
  95                 line6_version_request_async(line6);
  96                 break;
  97         case VARIAX_STARTUP_ACTIVATE:
  98                 
  99                 variax_activate_async(variax, 1);
 100                 variax->startup_progress = VARIAX_STARTUP_SETUP;
 101                 schedule_delayed_work(&line6->startup_work,
 102                                       msecs_to_jiffies(VARIAX_STARTUP_DELAY4));
 103                 break;
 104         case VARIAX_STARTUP_SETUP:
 105                 
 106                 snd_card_register(variax->line6.card);
 107                 break;
 108         }
 109 }
 110 
 111 
 112 
 113 
 114 static void line6_variax_process_message(struct usb_line6 *line6)
 115 {
 116         struct usb_line6_variax *variax = line6_to_variax(line6);
 117         const unsigned char *buf = variax->line6.buffer_message;
 118 
 119         switch (buf[0]) {
 120         case LINE6_RESET:
 121                 dev_info(variax->line6.ifcdev, "VARIAX reset\n");
 122                 break;
 123 
 124         case LINE6_SYSEX_BEGIN:
 125                 if (memcmp(buf + 1, variax_init_version + 1,
 126                            sizeof(variax_init_version) - 1) == 0) {
 127                         if (variax->startup_progress >= VARIAX_STARTUP_ACTIVATE)
 128                                 break;
 129                         variax->startup_progress = VARIAX_STARTUP_ACTIVATE;
 130                         cancel_delayed_work(&line6->startup_work);
 131                         schedule_delayed_work(&line6->startup_work,
 132                                               msecs_to_jiffies(VARIAX_STARTUP_DELAY3));
 133                 } else if (memcmp(buf + 1, variax_init_done + 1,
 134                                   sizeof(variax_init_done) - 1) == 0) {
 135                         
 136                         if (variax->startup_progress >= VARIAX_STARTUP_SETUP)
 137                                 break;
 138                         cancel_delayed_work(&line6->startup_work);
 139                         schedule_delayed_work(&line6->startup_work, 0);
 140                 }
 141                 break;
 142         }
 143 }
 144 
 145 
 146 
 147 
 148 static void line6_variax_disconnect(struct usb_line6 *line6)
 149 {
 150         struct usb_line6_variax *variax = line6_to_variax(line6);
 151 
 152         kfree(variax->buffer_activate);
 153 }
 154 
 155 
 156 
 157 
 158 static int variax_init(struct usb_line6 *line6,
 159                        const struct usb_device_id *id)
 160 {
 161         struct usb_line6_variax *variax = line6_to_variax(line6);
 162         int err;
 163 
 164         line6->process_message = line6_variax_process_message;
 165         line6->disconnect = line6_variax_disconnect;
 166         line6->startup = variax_startup;
 167 
 168         
 169         variax->buffer_activate = kmemdup(variax_activate,
 170                                           sizeof(variax_activate), GFP_KERNEL);
 171 
 172         if (variax->buffer_activate == NULL)
 173                 return -ENOMEM;
 174 
 175         
 176         err = line6_init_midi(&variax->line6);
 177         if (err < 0)
 178                 return err;
 179 
 180         
 181         schedule_delayed_work(&line6->startup_work,
 182                               msecs_to_jiffies(VARIAX_STARTUP_DELAY1));
 183         return 0;
 184 }
 185 
 186 #define LINE6_DEVICE(prod) USB_DEVICE(0x0e41, prod)
 187 #define LINE6_IF_NUM(prod, n) USB_DEVICE_INTERFACE_NUMBER(0x0e41, prod, n)
 188 
 189 
 190 static const struct usb_device_id variax_id_table[] = {
 191         { LINE6_IF_NUM(0x4650, 1), .driver_info = LINE6_PODXTLIVE_VARIAX },
 192         { LINE6_DEVICE(0x534d),    .driver_info = LINE6_VARIAX },
 193         {}
 194 };
 195 
 196 MODULE_DEVICE_TABLE(usb, variax_id_table);
 197 
 198 static const struct line6_properties variax_properties_table[] = {
 199         [LINE6_PODXTLIVE_VARIAX] = {
 200                 .id = "PODxtLive",
 201                 .name = "PODxt Live",
 202                 .capabilities   = LINE6_CAP_CONTROL
 203                                 | LINE6_CAP_CONTROL_MIDI,
 204                 .altsetting = 1,
 205                 .ep_ctrl_r = 0x86,
 206                 .ep_ctrl_w = 0x05,
 207                 .ep_audio_r = 0x82,
 208                 .ep_audio_w = 0x01,
 209         },
 210         [LINE6_VARIAX] = {
 211                 .id = "Variax",
 212                 .name = "Variax Workbench",
 213                 .capabilities   = LINE6_CAP_CONTROL
 214                                 | LINE6_CAP_CONTROL_MIDI,
 215                 .altsetting = 1,
 216                 .ep_ctrl_r = 0x82,
 217                 .ep_ctrl_w = 0x01,
 218                 
 219         }
 220 };
 221 
 222 
 223 
 224 
 225 static int variax_probe(struct usb_interface *interface,
 226                         const struct usb_device_id *id)
 227 {
 228         return line6_probe(interface, id, "Line6-Variax",
 229                            &variax_properties_table[id->driver_info],
 230                            variax_init, sizeof(struct usb_line6_variax));
 231 }
 232 
 233 static struct usb_driver variax_driver = {
 234         .name = KBUILD_MODNAME,
 235         .probe = variax_probe,
 236         .disconnect = line6_disconnect,
 237 #ifdef CONFIG_PM
 238         .suspend = line6_suspend,
 239         .resume = line6_resume,
 240         .reset_resume = line6_resume,
 241 #endif
 242         .id_table = variax_id_table,
 243 };
 244 
 245 module_usb_driver(variax_driver);
 246 
 247 MODULE_DESCRIPTION("Variax Workbench USB driver");
 248 MODULE_LICENSE("GPL");