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