1 // SPDX-License-Identifier: GPL-2.0-only 2 /* 3 * Line 6 Pod HD 4 * 5 * Copyright (C) 2011 Stefan Hajnoczi <stefanha@gmail.com> 6 * Copyright (C) 2015 Andrej Krutak <dev@andree.sk> 7 * Copyright (C) 2017 Hans P. Moller <hmoller@uc.cl> 8 */ 9 10 #include <linux/usb.h> 11 #include <linux/slab.h> 12 #include <linux/module.h> 13 #include <sound/core.h> 14 #include <sound/control.h> 15 #include <sound/pcm.h> 16 17 #include "driver.h" 18 #include "pcm.h" 19 20 #define PODHD_STARTUP_DELAY 500 21 22 enum { 23 LINE6_PODHD300, 24 LINE6_PODHD400, 25 LINE6_PODHD500, 26 LINE6_PODX3, 27 LINE6_PODX3LIVE, 28 LINE6_PODHD500X, 29 LINE6_PODHDDESKTOP 30 }; 31 32 struct usb_line6_podhd { 33 /* Generic Line 6 USB data */ 34 struct usb_line6 line6; 35 36 /* Serial number of device */ 37 u32 serial_number; 38 39 /* Firmware version */ 40 int firmware_version; 41 42 /* Monitor level */ 43 int monitor_level; 44 }; 45 46 #define line6_to_podhd(x) container_of(x, struct usb_line6_podhd, line6) 47 48 static const struct snd_ratden podhd_ratden = { 49 .num_min = 48000, 50 .num_max = 48000, 51 .num_step = 1, 52 .den = 1, 53 }; 54 55 static struct line6_pcm_properties podhd_pcm_properties = { 56 .playback_hw = { 57 .info = (SNDRV_PCM_INFO_MMAP | 58 SNDRV_PCM_INFO_INTERLEAVED | 59 SNDRV_PCM_INFO_BLOCK_TRANSFER | 60 SNDRV_PCM_INFO_MMAP_VALID | 61 SNDRV_PCM_INFO_PAUSE | 62 SNDRV_PCM_INFO_SYNC_START), 63 .formats = SNDRV_PCM_FMTBIT_S24_3LE, 64 .rates = SNDRV_PCM_RATE_48000, 65 .rate_min = 48000, 66 .rate_max = 48000, 67 .channels_min = 2, 68 .channels_max = 2, 69 .buffer_bytes_max = 60000, 70 .period_bytes_min = 64, 71 .period_bytes_max = 8192, 72 .periods_min = 1, 73 .periods_max = 1024}, 74 .capture_hw = { 75 .info = (SNDRV_PCM_INFO_MMAP | 76 SNDRV_PCM_INFO_INTERLEAVED | 77 SNDRV_PCM_INFO_BLOCK_TRANSFER | 78 SNDRV_PCM_INFO_MMAP_VALID | 79 SNDRV_PCM_INFO_SYNC_START), 80 .formats = SNDRV_PCM_FMTBIT_S24_3LE, 81 .rates = SNDRV_PCM_RATE_48000, 82 .rate_min = 48000, 83 .rate_max = 48000, 84 .channels_min = 2, 85 .channels_max = 2, 86 .buffer_bytes_max = 60000, 87 .period_bytes_min = 64, 88 .period_bytes_max = 8192, 89 .periods_min = 1, 90 .periods_max = 1024}, 91 .rates = { 92 .nrats = 1, 93 .rats = &podhd_ratden}, 94 .bytes_per_channel = 3 /* SNDRV_PCM_FMTBIT_S24_3LE */ 95 }; 96 97 static struct line6_pcm_properties podx3_pcm_properties = { 98 .playback_hw = { 99 .info = (SNDRV_PCM_INFO_MMAP | 100 SNDRV_PCM_INFO_INTERLEAVED | 101 SNDRV_PCM_INFO_BLOCK_TRANSFER | 102 SNDRV_PCM_INFO_MMAP_VALID | 103 SNDRV_PCM_INFO_PAUSE | 104 SNDRV_PCM_INFO_SYNC_START), 105 .formats = SNDRV_PCM_FMTBIT_S24_3LE, 106 .rates = SNDRV_PCM_RATE_48000, 107 .rate_min = 48000, 108 .rate_max = 48000, 109 .channels_min = 2, 110 .channels_max = 2, 111 .buffer_bytes_max = 60000, 112 .period_bytes_min = 64, 113 .period_bytes_max = 8192, 114 .periods_min = 1, 115 .periods_max = 1024}, 116 .capture_hw = { 117 .info = (SNDRV_PCM_INFO_MMAP | 118 SNDRV_PCM_INFO_INTERLEAVED | 119 SNDRV_PCM_INFO_BLOCK_TRANSFER | 120 SNDRV_PCM_INFO_MMAP_VALID | 121 SNDRV_PCM_INFO_SYNC_START), 122 .formats = SNDRV_PCM_FMTBIT_S24_3LE, 123 .rates = SNDRV_PCM_RATE_48000, 124 .rate_min = 48000, 125 .rate_max = 48000, 126 /* 1+2: Main signal (out), 3+4: Tone 1, 127 * 5+6: Tone 2, 7+8: raw 128 */ 129 .channels_min = 8, 130 .channels_max = 8, 131 .buffer_bytes_max = 60000, 132 .period_bytes_min = 64, 133 .period_bytes_max = 8192, 134 .periods_min = 1, 135 .periods_max = 1024}, 136 .rates = { 137 .nrats = 1, 138 .rats = &podhd_ratden}, 139 .bytes_per_channel = 3 /* SNDRV_PCM_FMTBIT_S24_3LE */ 140 }; 141 static struct usb_driver podhd_driver; 142 143 static ssize_t serial_number_show(struct device *dev, 144 struct device_attribute *attr, char *buf) 145 { 146 struct snd_card *card = dev_to_snd_card(dev); 147 struct usb_line6_podhd *pod = card->private_data; 148 149 return sprintf(buf, "%u\n", pod->serial_number); 150 } 151 152 static ssize_t firmware_version_show(struct device *dev, 153 struct device_attribute *attr, char *buf) 154 { 155 struct snd_card *card = dev_to_snd_card(dev); 156 struct usb_line6_podhd *pod = card->private_data; 157 158 return sprintf(buf, "%06x\n", pod->firmware_version); 159 } 160 161 static DEVICE_ATTR_RO(firmware_version); 162 static DEVICE_ATTR_RO(serial_number); 163 164 static struct attribute *podhd_dev_attrs[] = { 165 &dev_attr_firmware_version.attr, 166 &dev_attr_serial_number.attr, 167 NULL 168 }; 169 170 static const struct attribute_group podhd_dev_attr_group = { 171 .name = "podhd", 172 .attrs = podhd_dev_attrs, 173 }; 174 175 /* 176 * POD X3 startup procedure. 177 * 178 * May be compatible with other POD HD's, since it's also similar to the 179 * previous POD setup. In any case, it doesn't seem to be required for the 180 * audio nor bulk interfaces to work. 181 */ 182 183 static int podhd_dev_start(struct usb_line6_podhd *pod) 184 { 185 int ret; 186 u8 *init_bytes; 187 int i; 188 struct usb_device *usbdev = pod->line6.usbdev; 189 190 init_bytes = kmalloc(8, GFP_KERNEL); 191 if (!init_bytes) 192 return -ENOMEM; 193 194 ret = usb_control_msg(usbdev, usb_sndctrlpipe(usbdev, 0), 195 0x67, USB_TYPE_VENDOR | USB_RECIP_DEVICE | USB_DIR_OUT, 196 0x11, 0, 197 NULL, 0, LINE6_TIMEOUT * HZ); 198 if (ret < 0) { 199 dev_err(pod->line6.ifcdev, "read request failed (error %d)\n", ret); 200 goto exit; 201 } 202 203 /* NOTE: looks like some kind of ping message */ 204 ret = usb_control_msg(usbdev, usb_rcvctrlpipe(usbdev, 0), 0x67, 205 USB_TYPE_VENDOR | USB_RECIP_DEVICE | USB_DIR_IN, 206 0x11, 0x0, 207 init_bytes, 3, LINE6_TIMEOUT * HZ); 208 if (ret < 0) { 209 dev_err(pod->line6.ifcdev, 210 "receive length failed (error %d)\n", ret); 211 goto exit; 212 } 213 214 pod->firmware_version = 215 (init_bytes[0] << 16) | (init_bytes[1] << 8) | (init_bytes[2] << 0); 216 217 for (i = 0; i <= 16; i++) { 218 ret = line6_read_data(&pod->line6, 0xf000 + 0x08 * i, init_bytes, 8); 219 if (ret < 0) 220 goto exit; 221 } 222 223 ret = usb_control_msg(usbdev, usb_sndctrlpipe(usbdev, 0), 224 USB_REQ_SET_FEATURE, 225 USB_TYPE_STANDARD | USB_RECIP_DEVICE | USB_DIR_OUT, 226 1, 0, 227 NULL, 0, LINE6_TIMEOUT * HZ); 228 exit: 229 kfree(init_bytes); 230 return ret; 231 } 232 233 static void podhd_startup(struct usb_line6 *line6) 234 { 235 struct usb_line6_podhd *pod = line6_to_podhd(line6); 236 237 podhd_dev_start(pod); 238 line6_read_serial_number(&pod->line6, &pod->serial_number); 239 if (snd_card_register(line6->card)) 240 dev_err(line6->ifcdev, "Failed to register POD HD card.\n"); 241 } 242 243 static void podhd_disconnect(struct usb_line6 *line6) 244 { 245 struct usb_line6_podhd *pod = line6_to_podhd(line6); 246 247 if (pod->line6.properties->capabilities & LINE6_CAP_CONTROL_INFO) { 248 struct usb_interface *intf; 249 250 intf = usb_ifnum_to_if(line6->usbdev, 251 pod->line6.properties->ctrl_if); 252 if (intf) 253 usb_driver_release_interface(&podhd_driver, intf); 254 } 255 } 256 257 static const unsigned int float_zero_to_one_lookup[] = { 258 0x00000000, 0x3c23d70a, 0x3ca3d70a, 0x3cf5c28f, 0x3d23d70a, 0x3d4ccccd, 259 0x3d75c28f, 0x3d8f5c29, 0x3da3d70a, 0x3db851ec, 0x3dcccccd, 0x3de147ae, 260 0x3df5c28f, 0x3e051eb8, 0x3e0f5c29, 0x3e19999a, 0x3e23d70a, 0x3e2e147b, 261 0x3e3851ec, 0x3e428f5c, 0x3e4ccccd, 0x3e570a3d, 0x3e6147ae, 0x3e6b851f, 262 0x3e75c28f, 0x3e800000, 0x3e851eb8, 0x3e8a3d71, 0x3e8f5c29, 0x3e947ae1, 263 0x3e99999a, 0x3e9eb852, 0x3ea3d70a, 0x3ea8f5c3, 0x3eae147b, 0x3eb33333, 264 0x3eb851ec, 0x3ebd70a4, 0x3ec28f5c, 0x3ec7ae14, 0x3ecccccd, 0x3ed1eb85, 265 0x3ed70a3d, 0x3edc28f6, 0x3ee147ae, 0x3ee66666, 0x3eeb851f, 0x3ef0a3d7, 266 0x3ef5c28f, 0x3efae148, 0x3f000000, 0x3f028f5c, 0x3f051eb8, 0x3f07ae14, 267 0x3f0a3d71, 0x3f0ccccd, 0x3f0f5c29, 0x3f11eb85, 0x3f147ae1, 0x3f170a3d, 268 0x3f19999a, 0x3f1c28f6, 0x3f1eb852, 0x3f2147ae, 0x3f23d70a, 0x3f266666, 269 0x3f28f5c3, 0x3f2b851f, 0x3f2e147b, 0x3f30a3d7, 0x3f333333, 0x3f35c28f, 270 0x3f3851ec, 0x3f3ae148, 0x3f3d70a4, 0x3f400000, 0x3f428f5c, 0x3f451eb8, 271 0x3f47ae14, 0x3f4a3d71, 0x3f4ccccd, 0x3f4f5c29, 0x3f51eb85, 0x3f547ae1, 272 0x3f570a3d, 0x3f59999a, 0x3f5c28f6, 0x3f5eb852, 0x3f6147ae, 0x3f63d70a, 273 0x3f666666, 0x3f68f5c3, 0x3f6b851f, 0x3f6e147b, 0x3f70a3d7, 0x3f733333, 274 0x3f75c28f, 0x3f7851ec, 0x3f7ae148, 0x3f7d70a4, 0x3f800000 275 }; 276 277 static void podhd_set_monitor_level(struct usb_line6_podhd *podhd, int value) 278 { 279 unsigned int fl; 280 static const unsigned char msg[16] = { 281 /* Chunk is 0xc bytes (without first word) */ 282 0x0c, 0x00, 283 /* First chunk in the message */ 284 0x01, 0x00, 285 /* Message size is 2 4-byte words */ 286 0x02, 0x00, 287 /* Unknown */ 288 0x04, 0x41, 289 /* Unknown */ 290 0x04, 0x00, 0x13, 0x00, 291 /* Volume, LE float32, 0.0 - 1.0 */ 292 0x00, 0x00, 0x00, 0x00 293 }; 294 unsigned char *buf; 295 296 buf = kmemdup(msg, sizeof(msg), GFP_KERNEL); 297 if (!buf) 298 return; 299 300 if (value < 0) 301 value = 0; 302 303 if (value >= ARRAY_SIZE(float_zero_to_one_lookup)) 304 value = ARRAY_SIZE(float_zero_to_one_lookup) - 1; 305 306 fl = float_zero_to_one_lookup[value]; 307 308 buf[12] = (fl >> 0) & 0xff; 309 buf[13] = (fl >> 8) & 0xff; 310 buf[14] = (fl >> 16) & 0xff; 311 buf[15] = (fl >> 24) & 0xff; 312 313 line6_send_raw_message(&podhd->line6, buf, sizeof(msg)); 314 kfree(buf); 315 316 podhd->monitor_level = value; 317 } 318 319 /* control info callback */ 320 static int snd_podhd_control_monitor_info(struct snd_kcontrol *kcontrol, 321 struct snd_ctl_elem_info *uinfo) 322 { 323 uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER; 324 uinfo->count = 1; 325 uinfo->value.integer.min = 0; 326 uinfo->value.integer.max = 100; 327 uinfo->value.integer.step = 1; 328 return 0; 329 } 330 331 /* control get callback */ 332 static int snd_podhd_control_monitor_get(struct snd_kcontrol *kcontrol, 333 struct snd_ctl_elem_value *ucontrol) 334 { 335 struct snd_line6_pcm *line6pcm = snd_kcontrol_chip(kcontrol); 336 struct usb_line6_podhd *podhd = line6_to_podhd(line6pcm->line6); 337 338 ucontrol->value.integer.value[0] = podhd->monitor_level; 339 return 0; 340 } 341 342 /* control put callback */ 343 static int snd_podhd_control_monitor_put(struct snd_kcontrol *kcontrol, 344 struct snd_ctl_elem_value *ucontrol) 345 { 346 struct snd_line6_pcm *line6pcm = snd_kcontrol_chip(kcontrol); 347 struct usb_line6_podhd *podhd = line6_to_podhd(line6pcm->line6); 348 349 if (ucontrol->value.integer.value[0] == podhd->monitor_level) 350 return 0; 351 352 podhd_set_monitor_level(podhd, ucontrol->value.integer.value[0]); 353 return 1; 354 } 355 356 /* control definition */ 357 static const struct snd_kcontrol_new podhd_control_monitor = { 358 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 359 .name = "Monitor Playback Volume", 360 .index = 0, 361 .access = SNDRV_CTL_ELEM_ACCESS_READWRITE, 362 .info = snd_podhd_control_monitor_info, 363 .get = snd_podhd_control_monitor_get, 364 .put = snd_podhd_control_monitor_put 365 }; 366 367 /* 368 Try to init POD HD device. 369 */ 370 static int podhd_init(struct usb_line6 *line6, 371 const struct usb_device_id *id) 372 { 373 int err; 374 struct usb_line6_podhd *pod = line6_to_podhd(line6); 375 struct usb_interface *intf; 376 377 line6->disconnect = podhd_disconnect; 378 line6->startup = podhd_startup; 379 380 if (pod->line6.properties->capabilities & LINE6_CAP_CONTROL) { 381 /* claim the data interface */ 382 intf = usb_ifnum_to_if(line6->usbdev, 383 pod->line6.properties->ctrl_if); 384 if (!intf) { 385 dev_err(pod->line6.ifcdev, "interface %d not found\n", 386 pod->line6.properties->ctrl_if); 387 return -ENODEV; 388 } 389 390 err = usb_driver_claim_interface(&podhd_driver, intf, NULL); 391 if (err != 0) { 392 dev_err(pod->line6.ifcdev, "can't claim interface %d, error %d\n", 393 pod->line6.properties->ctrl_if, err); 394 return err; 395 } 396 } 397 398 if (pod->line6.properties->capabilities & LINE6_CAP_CONTROL_INFO) { 399 /* create sysfs entries: */ 400 err = snd_card_add_dev_attr(line6->card, &podhd_dev_attr_group); 401 if (err < 0) 402 return err; 403 } 404 405 if (pod->line6.properties->capabilities & LINE6_CAP_PCM) { 406 /* initialize PCM subsystem: */ 407 err = line6_init_pcm(line6, 408 (id->driver_info == LINE6_PODX3 || 409 id->driver_info == LINE6_PODX3LIVE) ? &podx3_pcm_properties : 410 &podhd_pcm_properties); 411 if (err < 0) 412 return err; 413 } 414 415 if (pod->line6.properties->capabilities & LINE6_CAP_HWMON_CTL) { 416 podhd_set_monitor_level(pod, 100); 417 err = snd_ctl_add(line6->card, 418 snd_ctl_new1(&podhd_control_monitor, 419 line6->line6pcm)); 420 if (err < 0) 421 return err; 422 } 423 424 if (!(pod->line6.properties->capabilities & LINE6_CAP_CONTROL_INFO)) { 425 /* register USB audio system directly */ 426 return snd_card_register(line6->card); 427 } 428 429 /* init device and delay registering */ 430 schedule_delayed_work(&line6->startup_work, 431 msecs_to_jiffies(PODHD_STARTUP_DELAY)); 432 return 0; 433 } 434 435 #define LINE6_DEVICE(prod) USB_DEVICE(0x0e41, prod) 436 #define LINE6_IF_NUM(prod, n) USB_DEVICE_INTERFACE_NUMBER(0x0e41, prod, n) 437 438 /* table of devices that work with this driver */ 439 static const struct usb_device_id podhd_id_table[] = { 440 /* TODO: no need to alloc data interfaces when only audio is used */ 441 { LINE6_DEVICE(0x5057), .driver_info = LINE6_PODHD300 }, 442 { LINE6_DEVICE(0x5058), .driver_info = LINE6_PODHD400 }, 443 { LINE6_IF_NUM(0x414D, 0), .driver_info = LINE6_PODHD500 }, 444 { LINE6_IF_NUM(0x414A, 0), .driver_info = LINE6_PODX3 }, 445 { LINE6_IF_NUM(0x414B, 0), .driver_info = LINE6_PODX3LIVE }, 446 { LINE6_IF_NUM(0x4159, 0), .driver_info = LINE6_PODHD500X }, 447 { LINE6_IF_NUM(0x4156, 0), .driver_info = LINE6_PODHDDESKTOP }, 448 {} 449 }; 450 451 MODULE_DEVICE_TABLE(usb, podhd_id_table); 452 453 static const struct line6_properties podhd_properties_table[] = { 454 [LINE6_PODHD300] = { 455 .id = "PODHD300", 456 .name = "POD HD300", 457 .capabilities = LINE6_CAP_PCM 458 | LINE6_CAP_HWMON, 459 .altsetting = 5, 460 .ep_ctrl_r = 0x84, 461 .ep_ctrl_w = 0x03, 462 .ep_audio_r = 0x82, 463 .ep_audio_w = 0x01, 464 }, 465 [LINE6_PODHD400] = { 466 .id = "PODHD400", 467 .name = "POD HD400", 468 .capabilities = LINE6_CAP_PCM 469 | LINE6_CAP_HWMON, 470 .altsetting = 5, 471 .ep_ctrl_r = 0x84, 472 .ep_ctrl_w = 0x03, 473 .ep_audio_r = 0x82, 474 .ep_audio_w = 0x01, 475 }, 476 [LINE6_PODHD500] = { 477 .id = "PODHD500", 478 .name = "POD HD500", 479 .capabilities = LINE6_CAP_PCM | LINE6_CAP_CONTROL 480 | LINE6_CAP_HWMON | LINE6_CAP_HWMON_CTL, 481 .altsetting = 1, 482 .ctrl_if = 1, 483 .ep_ctrl_r = 0x81, 484 .ep_ctrl_w = 0x01, 485 .ep_audio_r = 0x86, 486 .ep_audio_w = 0x02, 487 }, 488 [LINE6_PODX3] = { 489 .id = "PODX3", 490 .name = "POD X3", 491 .capabilities = LINE6_CAP_CONTROL | LINE6_CAP_CONTROL_INFO 492 | LINE6_CAP_PCM | LINE6_CAP_HWMON | LINE6_CAP_IN_NEEDS_OUT, 493 .altsetting = 1, 494 .ep_ctrl_r = 0x81, 495 .ep_ctrl_w = 0x01, 496 .ctrl_if = 1, 497 .ep_audio_r = 0x86, 498 .ep_audio_w = 0x02, 499 }, 500 [LINE6_PODX3LIVE] = { 501 .id = "PODX3LIVE", 502 .name = "POD X3 LIVE", 503 .capabilities = LINE6_CAP_CONTROL | LINE6_CAP_CONTROL_INFO 504 | LINE6_CAP_PCM | LINE6_CAP_HWMON | LINE6_CAP_IN_NEEDS_OUT, 505 .altsetting = 1, 506 .ep_ctrl_r = 0x81, 507 .ep_ctrl_w = 0x01, 508 .ctrl_if = 1, 509 .ep_audio_r = 0x86, 510 .ep_audio_w = 0x02, 511 }, 512 [LINE6_PODHD500X] = { 513 .id = "PODHD500X", 514 .name = "POD HD500X", 515 .capabilities = LINE6_CAP_CONTROL 516 | LINE6_CAP_PCM | LINE6_CAP_HWMON, 517 .altsetting = 1, 518 .ep_ctrl_r = 0x81, 519 .ep_ctrl_w = 0x01, 520 .ctrl_if = 1, 521 .ep_audio_r = 0x86, 522 .ep_audio_w = 0x02, 523 }, 524 [LINE6_PODHDDESKTOP] = { 525 .id = "PODHDDESKTOP", 526 .name = "POD HDDESKTOP", 527 .capabilities = LINE6_CAP_CONTROL 528 | LINE6_CAP_PCM | LINE6_CAP_HWMON, 529 .altsetting = 1, 530 .ep_ctrl_r = 0x81, 531 .ep_ctrl_w = 0x01, 532 .ctrl_if = 1, 533 .ep_audio_r = 0x86, 534 .ep_audio_w = 0x02, 535 }, 536 }; 537 538 /* 539 Probe USB device. 540 */ 541 static int podhd_probe(struct usb_interface *interface, 542 const struct usb_device_id *id) 543 { 544 return line6_probe(interface, id, "Line6-PODHD", 545 &podhd_properties_table[id->driver_info], 546 podhd_init, sizeof(struct usb_line6_podhd)); 547 } 548 549 static struct usb_driver podhd_driver = { 550 .name = KBUILD_MODNAME, 551 .probe = podhd_probe, 552 .disconnect = line6_disconnect, 553 #ifdef CONFIG_PM 554 .suspend = line6_suspend, 555 .resume = line6_resume, 556 .reset_resume = line6_resume, 557 #endif 558 .id_table = podhd_id_table, 559 }; 560 561 module_usb_driver(podhd_driver); 562 563 MODULE_DESCRIPTION("Line 6 PODHD USB driver"); 564 MODULE_LICENSE("GPL"); 565