1 /* 2 * Line 6 Linux USB driver 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 #include <linux/wait.h> 14 #include <linux/interrupt.h> 15 #include <linux/module.h> 16 #include <linux/usb.h> 17 18 #include <sound/core.h> 19 #include <sound/control.h> 20 21 #include "capture.h" 22 #include "driver.h" 23 #include "playback.h" 24 25 /* 26 Locate name in binary program dump 27 */ 28 #define POD_NAME_OFFSET 0 29 #define POD_NAME_LENGTH 16 30 31 /* 32 Other constants 33 */ 34 #define POD_CONTROL_SIZE 0x80 35 #define POD_BUFSIZE_DUMPREQ 7 36 #define POD_STARTUP_DELAY 1000 37 38 /* 39 Stages of POD startup procedure 40 */ 41 enum { 42 POD_STARTUP_VERSIONREQ, 43 POD_STARTUP_SETUP, 44 POD_STARTUP_DONE, 45 }; 46 47 enum { 48 LINE6_BASSPODXT, 49 LINE6_BASSPODXTLIVE, 50 LINE6_BASSPODXTPRO, 51 LINE6_POCKETPOD, 52 LINE6_PODXT, 53 LINE6_PODXTLIVE_POD, 54 LINE6_PODXTPRO, 55 }; 56 57 struct usb_line6_pod { 58 /* Generic Line 6 USB data */ 59 struct usb_line6 line6; 60 61 /* Instrument monitor level */ 62 int monitor_level; 63 64 /* Current progress in startup procedure */ 65 int startup_progress; 66 67 /* Serial number of device */ 68 u32 serial_number; 69 70 /* Firmware version (x 100) */ 71 int firmware_version; 72 73 /* Device ID */ 74 int device_id; 75 }; 76 77 #define POD_SYSEX_CODE 3 78 79 /* *INDENT-OFF* */ 80 81 enum { 82 POD_SYSEX_SAVE = 0x24, 83 POD_SYSEX_SYSTEM = 0x56, 84 POD_SYSEX_SYSTEMREQ = 0x57, 85 /* POD_SYSEX_UPDATE = 0x6c, */ /* software update! */ 86 POD_SYSEX_STORE = 0x71, 87 POD_SYSEX_FINISH = 0x72, 88 POD_SYSEX_DUMPMEM = 0x73, 89 POD_SYSEX_DUMP = 0x74, 90 POD_SYSEX_DUMPREQ = 0x75 91 92 /* dumps entire internal memory of PODxt Pro */ 93 /* POD_SYSEX_DUMPMEM2 = 0x76 */ 94 }; 95 96 enum { 97 POD_MONITOR_LEVEL = 0x04, 98 POD_SYSTEM_INVALID = 0x10000 99 }; 100 101 /* *INDENT-ON* */ 102 103 enum { 104 POD_DUMP_MEMORY = 2 105 }; 106 107 enum { 108 POD_BUSY_READ, 109 POD_BUSY_WRITE, 110 POD_CHANNEL_DIRTY, 111 POD_SAVE_PRESSED, 112 POD_BUSY_MIDISEND 113 }; 114 115 static struct snd_ratden pod_ratden = { 116 .num_min = 78125, 117 .num_max = 78125, 118 .num_step = 1, 119 .den = 2 120 }; 121 122 static struct line6_pcm_properties pod_pcm_properties = { 123 .playback_hw = { 124 .info = (SNDRV_PCM_INFO_MMAP | 125 SNDRV_PCM_INFO_INTERLEAVED | 126 SNDRV_PCM_INFO_BLOCK_TRANSFER | 127 SNDRV_PCM_INFO_MMAP_VALID | 128 SNDRV_PCM_INFO_PAUSE | 129 SNDRV_PCM_INFO_SYNC_START), 130 .formats = SNDRV_PCM_FMTBIT_S24_3LE, 131 .rates = SNDRV_PCM_RATE_KNOT, 132 .rate_min = 39062, 133 .rate_max = 39063, 134 .channels_min = 2, 135 .channels_max = 2, 136 .buffer_bytes_max = 60000, 137 .period_bytes_min = 64, 138 .period_bytes_max = 8192, 139 .periods_min = 1, 140 .periods_max = 1024}, 141 .capture_hw = { 142 .info = (SNDRV_PCM_INFO_MMAP | 143 SNDRV_PCM_INFO_INTERLEAVED | 144 SNDRV_PCM_INFO_BLOCK_TRANSFER | 145 SNDRV_PCM_INFO_MMAP_VALID | 146 SNDRV_PCM_INFO_SYNC_START), 147 .formats = SNDRV_PCM_FMTBIT_S24_3LE, 148 .rates = SNDRV_PCM_RATE_KNOT, 149 .rate_min = 39062, 150 .rate_max = 39063, 151 .channels_min = 2, 152 .channels_max = 2, 153 .buffer_bytes_max = 60000, 154 .period_bytes_min = 64, 155 .period_bytes_max = 8192, 156 .periods_min = 1, 157 .periods_max = 1024}, 158 .rates = { 159 .nrats = 1, 160 .rats = &pod_ratden}, 161 .bytes_per_channel = 3 /* SNDRV_PCM_FMTBIT_S24_3LE */ 162 }; 163 164 static const char pod_version_header[] = { 165 0xf2, 0x7e, 0x7f, 0x06, 0x02 166 }; 167 168 static char *pod_alloc_sysex_buffer(struct usb_line6_pod *pod, int code, 169 int size) 170 { 171 return line6_alloc_sysex_buffer(&pod->line6, POD_SYSEX_CODE, code, 172 size); 173 } 174 175 /* 176 Process a completely received message. 177 */ 178 static void line6_pod_process_message(struct usb_line6 *line6) 179 { 180 struct usb_line6_pod *pod = (struct usb_line6_pod *) line6; 181 const unsigned char *buf = pod->line6.buffer_message; 182 183 if (memcmp(buf, pod_version_header, sizeof(pod_version_header)) == 0) { 184 pod->firmware_version = buf[13] * 100 + buf[14] * 10 + buf[15]; 185 pod->device_id = ((int)buf[8] << 16) | ((int)buf[9] << 8) | 186 (int) buf[10]; 187 if (pod->startup_progress == POD_STARTUP_VERSIONREQ) { 188 pod->startup_progress = POD_STARTUP_SETUP; 189 schedule_delayed_work(&line6->startup_work, 0); 190 } 191 return; 192 } 193 194 /* Only look for sysex messages from this device */ 195 if (buf[0] != (LINE6_SYSEX_BEGIN | LINE6_CHANNEL_DEVICE) && 196 buf[0] != (LINE6_SYSEX_BEGIN | LINE6_CHANNEL_UNKNOWN)) { 197 return; 198 } 199 if (memcmp(buf + 1, line6_midi_id, sizeof(line6_midi_id)) != 0) 200 return; 201 202 if (buf[5] == POD_SYSEX_SYSTEM && buf[6] == POD_MONITOR_LEVEL) { 203 short value = ((int)buf[7] << 12) | ((int)buf[8] << 8) | 204 ((int)buf[9] << 4) | (int)buf[10]; 205 pod->monitor_level = value; 206 } 207 } 208 209 /* 210 Send system parameter (from integer). 211 */ 212 static int pod_set_system_param_int(struct usb_line6_pod *pod, int value, 213 int code) 214 { 215 char *sysex; 216 static const int size = 5; 217 218 sysex = pod_alloc_sysex_buffer(pod, POD_SYSEX_SYSTEM, size); 219 if (!sysex) 220 return -ENOMEM; 221 sysex[SYSEX_DATA_OFS] = code; 222 sysex[SYSEX_DATA_OFS + 1] = (value >> 12) & 0x0f; 223 sysex[SYSEX_DATA_OFS + 2] = (value >> 8) & 0x0f; 224 sysex[SYSEX_DATA_OFS + 3] = (value >> 4) & 0x0f; 225 sysex[SYSEX_DATA_OFS + 4] = (value) & 0x0f; 226 line6_send_sysex_message(&pod->line6, sysex, size); 227 kfree(sysex); 228 return 0; 229 } 230 231 /* 232 "read" request on "serial_number" special file. 233 */ 234 static ssize_t serial_number_show(struct device *dev, 235 struct device_attribute *attr, char *buf) 236 { 237 struct snd_card *card = dev_to_snd_card(dev); 238 struct usb_line6_pod *pod = card->private_data; 239 240 return sprintf(buf, "%u\n", pod->serial_number); 241 } 242 243 /* 244 "read" request on "firmware_version" special file. 245 */ 246 static ssize_t firmware_version_show(struct device *dev, 247 struct device_attribute *attr, char *buf) 248 { 249 struct snd_card *card = dev_to_snd_card(dev); 250 struct usb_line6_pod *pod = card->private_data; 251 252 return sprintf(buf, "%d.%02d\n", pod->firmware_version / 100, 253 pod->firmware_version % 100); 254 } 255 256 /* 257 "read" request on "device_id" special file. 258 */ 259 static ssize_t device_id_show(struct device *dev, 260 struct device_attribute *attr, char *buf) 261 { 262 struct snd_card *card = dev_to_snd_card(dev); 263 struct usb_line6_pod *pod = card->private_data; 264 265 return sprintf(buf, "%d\n", pod->device_id); 266 } 267 268 /* 269 POD startup procedure. 270 This is a sequence of functions with special requirements (e.g., must 271 not run immediately after initialization, must not run in interrupt 272 context). After the last one has finished, the device is ready to use. 273 */ 274 275 static void pod_startup(struct usb_line6 *line6) 276 { 277 struct usb_line6_pod *pod = (struct usb_line6_pod *) line6; 278 279 switch (pod->startup_progress) { 280 case POD_STARTUP_VERSIONREQ: 281 /* request firmware version: */ 282 line6_version_request_async(line6); 283 break; 284 case POD_STARTUP_SETUP: 285 /* serial number: */ 286 line6_read_serial_number(&pod->line6, &pod->serial_number); 287 288 /* ALSA audio interface: */ 289 if (snd_card_register(line6->card)) 290 dev_err(line6->ifcdev, "Failed to register POD card.\n"); 291 pod->startup_progress = POD_STARTUP_DONE; 292 break; 293 default: 294 break; 295 } 296 } 297 298 /* POD special files: */ 299 static DEVICE_ATTR_RO(device_id); 300 static DEVICE_ATTR_RO(firmware_version); 301 static DEVICE_ATTR_RO(serial_number); 302 303 static struct attribute *pod_dev_attrs[] = { 304 &dev_attr_device_id.attr, 305 &dev_attr_firmware_version.attr, 306 &dev_attr_serial_number.attr, 307 NULL 308 }; 309 310 static const struct attribute_group pod_dev_attr_group = { 311 .name = "pod", 312 .attrs = pod_dev_attrs, 313 }; 314 315 /* control info callback */ 316 static int snd_pod_control_monitor_info(struct snd_kcontrol *kcontrol, 317 struct snd_ctl_elem_info *uinfo) 318 { 319 uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER; 320 uinfo->count = 1; 321 uinfo->value.integer.min = 0; 322 uinfo->value.integer.max = 65535; 323 return 0; 324 } 325 326 /* control get callback */ 327 static int snd_pod_control_monitor_get(struct snd_kcontrol *kcontrol, 328 struct snd_ctl_elem_value *ucontrol) 329 { 330 struct snd_line6_pcm *line6pcm = snd_kcontrol_chip(kcontrol); 331 struct usb_line6_pod *pod = (struct usb_line6_pod *)line6pcm->line6; 332 333 ucontrol->value.integer.value[0] = pod->monitor_level; 334 return 0; 335 } 336 337 /* control put callback */ 338 static int snd_pod_control_monitor_put(struct snd_kcontrol *kcontrol, 339 struct snd_ctl_elem_value *ucontrol) 340 { 341 struct snd_line6_pcm *line6pcm = snd_kcontrol_chip(kcontrol); 342 struct usb_line6_pod *pod = (struct usb_line6_pod *)line6pcm->line6; 343 344 if (ucontrol->value.integer.value[0] == pod->monitor_level) 345 return 0; 346 347 pod->monitor_level = ucontrol->value.integer.value[0]; 348 pod_set_system_param_int(pod, ucontrol->value.integer.value[0], 349 POD_MONITOR_LEVEL); 350 return 1; 351 } 352 353 /* control definition */ 354 static const struct snd_kcontrol_new pod_control_monitor = { 355 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 356 .name = "Monitor Playback Volume", 357 .index = 0, 358 .access = SNDRV_CTL_ELEM_ACCESS_READWRITE, 359 .info = snd_pod_control_monitor_info, 360 .get = snd_pod_control_monitor_get, 361 .put = snd_pod_control_monitor_put 362 }; 363 364 /* 365 Try to init POD device. 366 */ 367 static int pod_init(struct usb_line6 *line6, 368 const struct usb_device_id *id) 369 { 370 int err; 371 struct usb_line6_pod *pod = (struct usb_line6_pod *) line6; 372 373 line6->process_message = line6_pod_process_message; 374 line6->startup = pod_startup; 375 376 /* create sysfs entries: */ 377 err = snd_card_add_dev_attr(line6->card, &pod_dev_attr_group); 378 if (err < 0) 379 return err; 380 381 /* initialize MIDI subsystem: */ 382 err = line6_init_midi(line6); 383 if (err < 0) 384 return err; 385 386 /* initialize PCM subsystem: */ 387 err = line6_init_pcm(line6, &pod_pcm_properties); 388 if (err < 0) 389 return err; 390 391 /* register monitor control: */ 392 err = snd_ctl_add(line6->card, 393 snd_ctl_new1(&pod_control_monitor, line6->line6pcm)); 394 if (err < 0) 395 return err; 396 397 /* 398 When the sound card is registered at this point, the PODxt Live 399 displays "Invalid Code Error 07", so we do it later in the event 400 handler. 401 */ 402 403 if (pod->line6.properties->capabilities & LINE6_CAP_CONTROL) { 404 pod->monitor_level = POD_SYSTEM_INVALID; 405 406 /* initiate startup procedure: */ 407 schedule_delayed_work(&line6->startup_work, 408 msecs_to_jiffies(POD_STARTUP_DELAY)); 409 } 410 411 return 0; 412 } 413 414 #define LINE6_DEVICE(prod) USB_DEVICE(0x0e41, prod) 415 #define LINE6_IF_NUM(prod, n) USB_DEVICE_INTERFACE_NUMBER(0x0e41, prod, n) 416 417 /* table of devices that work with this driver */ 418 static const struct usb_device_id pod_id_table[] = { 419 { LINE6_DEVICE(0x4250), .driver_info = LINE6_BASSPODXT }, 420 { LINE6_DEVICE(0x4642), .driver_info = LINE6_BASSPODXTLIVE }, 421 { LINE6_DEVICE(0x4252), .driver_info = LINE6_BASSPODXTPRO }, 422 { LINE6_IF_NUM(0x5051, 1), .driver_info = LINE6_POCKETPOD }, 423 { LINE6_DEVICE(0x5044), .driver_info = LINE6_PODXT }, 424 { LINE6_IF_NUM(0x4650, 0), .driver_info = LINE6_PODXTLIVE_POD }, 425 { LINE6_DEVICE(0x5050), .driver_info = LINE6_PODXTPRO }, 426 {} 427 }; 428 429 MODULE_DEVICE_TABLE(usb, pod_id_table); 430 431 static const struct line6_properties pod_properties_table[] = { 432 [LINE6_BASSPODXT] = { 433 .id = "BassPODxt", 434 .name = "BassPODxt", 435 .capabilities = LINE6_CAP_CONTROL 436 | LINE6_CAP_CONTROL_MIDI 437 | LINE6_CAP_PCM 438 | LINE6_CAP_HWMON, 439 .altsetting = 5, 440 .ep_ctrl_r = 0x84, 441 .ep_ctrl_w = 0x03, 442 .ep_audio_r = 0x82, 443 .ep_audio_w = 0x01, 444 }, 445 [LINE6_BASSPODXTLIVE] = { 446 .id = "BassPODxtLive", 447 .name = "BassPODxt Live", 448 .capabilities = LINE6_CAP_CONTROL 449 | LINE6_CAP_CONTROL_MIDI 450 | LINE6_CAP_PCM 451 | LINE6_CAP_HWMON, 452 .altsetting = 1, 453 .ep_ctrl_r = 0x84, 454 .ep_ctrl_w = 0x03, 455 .ep_audio_r = 0x82, 456 .ep_audio_w = 0x01, 457 }, 458 [LINE6_BASSPODXTPRO] = { 459 .id = "BassPODxtPro", 460 .name = "BassPODxt Pro", 461 .capabilities = LINE6_CAP_CONTROL 462 | LINE6_CAP_CONTROL_MIDI 463 | LINE6_CAP_PCM 464 | LINE6_CAP_HWMON, 465 .altsetting = 5, 466 .ep_ctrl_r = 0x84, 467 .ep_ctrl_w = 0x03, 468 .ep_audio_r = 0x82, 469 .ep_audio_w = 0x01, 470 }, 471 [LINE6_POCKETPOD] = { 472 .id = "PocketPOD", 473 .name = "Pocket POD", 474 .capabilities = LINE6_CAP_CONTROL 475 | LINE6_CAP_CONTROL_MIDI, 476 .altsetting = 0, 477 .ep_ctrl_r = 0x82, 478 .ep_ctrl_w = 0x02, 479 /* no audio channel */ 480 }, 481 [LINE6_PODXT] = { 482 .id = "PODxt", 483 .name = "PODxt", 484 .capabilities = LINE6_CAP_CONTROL 485 | LINE6_CAP_CONTROL_MIDI 486 | LINE6_CAP_PCM 487 | LINE6_CAP_HWMON, 488 .altsetting = 5, 489 .ep_ctrl_r = 0x84, 490 .ep_ctrl_w = 0x03, 491 .ep_audio_r = 0x82, 492 .ep_audio_w = 0x01, 493 }, 494 [LINE6_PODXTLIVE_POD] = { 495 .id = "PODxtLive", 496 .name = "PODxt Live", 497 .capabilities = LINE6_CAP_CONTROL 498 | LINE6_CAP_CONTROL_MIDI 499 | LINE6_CAP_PCM 500 | LINE6_CAP_HWMON, 501 .altsetting = 1, 502 .ep_ctrl_r = 0x84, 503 .ep_ctrl_w = 0x03, 504 .ep_audio_r = 0x82, 505 .ep_audio_w = 0x01, 506 }, 507 [LINE6_PODXTPRO] = { 508 .id = "PODxtPro", 509 .name = "PODxt Pro", 510 .capabilities = LINE6_CAP_CONTROL 511 | LINE6_CAP_CONTROL_MIDI 512 | LINE6_CAP_PCM 513 | LINE6_CAP_HWMON, 514 .altsetting = 5, 515 .ep_ctrl_r = 0x84, 516 .ep_ctrl_w = 0x03, 517 .ep_audio_r = 0x82, 518 .ep_audio_w = 0x01, 519 }, 520 }; 521 522 /* 523 Probe USB device. 524 */ 525 static int pod_probe(struct usb_interface *interface, 526 const struct usb_device_id *id) 527 { 528 return line6_probe(interface, id, "Line6-POD", 529 &pod_properties_table[id->driver_info], 530 pod_init, sizeof(struct usb_line6_pod)); 531 } 532 533 static struct usb_driver pod_driver = { 534 .name = KBUILD_MODNAME, 535 .probe = pod_probe, 536 .disconnect = line6_disconnect, 537 #ifdef CONFIG_PM 538 .suspend = line6_suspend, 539 .resume = line6_resume, 540 .reset_resume = line6_resume, 541 #endif 542 .id_table = pod_id_table, 543 }; 544 545 module_usb_driver(pod_driver); 546 547 MODULE_DESCRIPTION("Line 6 POD USB driver"); 548 MODULE_LICENSE("GPL"); 549