1 /* 2 * Line 6 Pod HD 3 * 4 * Copyright (C) 2011 Stefan Hajnoczi <stefanha@gmail.com> 5 * Copyright (C) 2015 Andrej Krutak <dev@andree.sk> 6 * 7 * This program is free software; you can redistribute it and/or 8 * modify it under the terms of the GNU General Public License as 9 * published by the Free Software Foundation, version 2. 10 * 11 */ 12 13 #include <linux/usb.h> 14 #include <linux/slab.h> 15 #include <linux/module.h> 16 #include <sound/core.h> 17 #include <sound/pcm.h> 18 19 #include "driver.h" 20 #include "pcm.h" 21 22 #define PODHD_STARTUP_DELAY 500 23 24 /* 25 * Stages of POD startup procedure 26 */ 27 enum { 28 PODHD_STARTUP_INIT = 1, 29 PODHD_STARTUP_SCHEDULE_WORKQUEUE, 30 PODHD_STARTUP_SETUP, 31 PODHD_STARTUP_LAST = PODHD_STARTUP_SETUP - 1 32 }; 33 34 enum { 35 LINE6_PODHD300, 36 LINE6_PODHD400, 37 LINE6_PODHD500_0, 38 LINE6_PODHD500_1, 39 LINE6_PODX3, 40 LINE6_PODX3LIVE 41 }; 42 43 struct usb_line6_podhd { 44 /* Generic Line 6 USB data */ 45 struct usb_line6 line6; 46 47 /* Timer for device initialization */ 48 struct timer_list startup_timer; 49 50 /* Work handler for device initialization */ 51 struct work_struct startup_work; 52 53 /* Current progress in startup procedure */ 54 int startup_progress; 55 56 /* Serial number of device */ 57 u32 serial_number; 58 59 /* Firmware version */ 60 int firmware_version; 61 }; 62 63 static struct snd_ratden podhd_ratden = { 64 .num_min = 48000, 65 .num_max = 48000, 66 .num_step = 1, 67 .den = 1, 68 }; 69 70 static struct line6_pcm_properties podhd_pcm_properties = { 71 .playback_hw = { 72 .info = (SNDRV_PCM_INFO_MMAP | 73 SNDRV_PCM_INFO_INTERLEAVED | 74 SNDRV_PCM_INFO_BLOCK_TRANSFER | 75 SNDRV_PCM_INFO_MMAP_VALID | 76 SNDRV_PCM_INFO_PAUSE | 77 SNDRV_PCM_INFO_SYNC_START), 78 .formats = SNDRV_PCM_FMTBIT_S24_3LE, 79 .rates = SNDRV_PCM_RATE_48000, 80 .rate_min = 48000, 81 .rate_max = 48000, 82 .channels_min = 2, 83 .channels_max = 2, 84 .buffer_bytes_max = 60000, 85 .period_bytes_min = 64, 86 .period_bytes_max = 8192, 87 .periods_min = 1, 88 .periods_max = 1024}, 89 .capture_hw = { 90 .info = (SNDRV_PCM_INFO_MMAP | 91 SNDRV_PCM_INFO_INTERLEAVED | 92 SNDRV_PCM_INFO_BLOCK_TRANSFER | 93 SNDRV_PCM_INFO_MMAP_VALID | 94 SNDRV_PCM_INFO_SYNC_START), 95 .formats = SNDRV_PCM_FMTBIT_S24_3LE, 96 .rates = SNDRV_PCM_RATE_48000, 97 .rate_min = 48000, 98 .rate_max = 48000, 99 .channels_min = 2, 100 .channels_max = 2, 101 .buffer_bytes_max = 60000, 102 .period_bytes_min = 64, 103 .period_bytes_max = 8192, 104 .periods_min = 1, 105 .periods_max = 1024}, 106 .rates = { 107 .nrats = 1, 108 .rats = &podhd_ratden}, 109 .bytes_per_channel = 3 /* SNDRV_PCM_FMTBIT_S24_3LE */ 110 }; 111 112 static struct line6_pcm_properties podx3_pcm_properties = { 113 .playback_hw = { 114 .info = (SNDRV_PCM_INFO_MMAP | 115 SNDRV_PCM_INFO_INTERLEAVED | 116 SNDRV_PCM_INFO_BLOCK_TRANSFER | 117 SNDRV_PCM_INFO_MMAP_VALID | 118 SNDRV_PCM_INFO_PAUSE | 119 SNDRV_PCM_INFO_SYNC_START), 120 .formats = SNDRV_PCM_FMTBIT_S24_3LE, 121 .rates = SNDRV_PCM_RATE_48000, 122 .rate_min = 48000, 123 .rate_max = 48000, 124 .channels_min = 2, 125 .channels_max = 2, 126 .buffer_bytes_max = 60000, 127 .period_bytes_min = 64, 128 .period_bytes_max = 8192, 129 .periods_min = 1, 130 .periods_max = 1024}, 131 .capture_hw = { 132 .info = (SNDRV_PCM_INFO_MMAP | 133 SNDRV_PCM_INFO_INTERLEAVED | 134 SNDRV_PCM_INFO_BLOCK_TRANSFER | 135 SNDRV_PCM_INFO_MMAP_VALID | 136 SNDRV_PCM_INFO_SYNC_START), 137 .formats = SNDRV_PCM_FMTBIT_S24_3LE, 138 .rates = SNDRV_PCM_RATE_48000, 139 .rate_min = 48000, 140 .rate_max = 48000, 141 /* 1+2: Main signal (out), 3+4: Tone 1, 142 * 5+6: Tone 2, 7+8: raw 143 */ 144 .channels_min = 8, 145 .channels_max = 8, 146 .buffer_bytes_max = 60000, 147 .period_bytes_min = 64, 148 .period_bytes_max = 8192, 149 .periods_min = 1, 150 .periods_max = 1024}, 151 .rates = { 152 .nrats = 1, 153 .rats = &podhd_ratden}, 154 .bytes_per_channel = 3 /* SNDRV_PCM_FMTBIT_S24_3LE */ 155 }; 156 static struct usb_driver podhd_driver; 157 158 static void podhd_startup_start_workqueue(unsigned long data); 159 static void podhd_startup_workqueue(struct work_struct *work); 160 static int podhd_startup_finalize(struct usb_line6_podhd *pod); 161 162 static ssize_t serial_number_show(struct device *dev, 163 struct device_attribute *attr, char *buf) 164 { 165 struct snd_card *card = dev_to_snd_card(dev); 166 struct usb_line6_podhd *pod = card->private_data; 167 168 return sprintf(buf, "%u\n", pod->serial_number); 169 } 170 171 static ssize_t firmware_version_show(struct device *dev, 172 struct device_attribute *attr, char *buf) 173 { 174 struct snd_card *card = dev_to_snd_card(dev); 175 struct usb_line6_podhd *pod = card->private_data; 176 177 return sprintf(buf, "%06x\n", pod->firmware_version); 178 } 179 180 static DEVICE_ATTR_RO(firmware_version); 181 static DEVICE_ATTR_RO(serial_number); 182 183 static struct attribute *podhd_dev_attrs[] = { 184 &dev_attr_firmware_version.attr, 185 &dev_attr_serial_number.attr, 186 NULL 187 }; 188 189 static const struct attribute_group podhd_dev_attr_group = { 190 .name = "podhd", 191 .attrs = podhd_dev_attrs, 192 }; 193 194 /* 195 * POD X3 startup procedure. 196 * 197 * May be compatible with other POD HD's, since it's also similar to the 198 * previous POD setup. In any case, it doesn't seem to be required for the 199 * audio nor bulk interfaces to work. 200 */ 201 202 static void podhd_startup(struct usb_line6_podhd *pod) 203 { 204 CHECK_STARTUP_PROGRESS(pod->startup_progress, PODHD_STARTUP_INIT); 205 206 /* delay startup procedure: */ 207 line6_start_timer(&pod->startup_timer, PODHD_STARTUP_DELAY, 208 podhd_startup_start_workqueue, (unsigned long)pod); 209 } 210 211 static void podhd_startup_start_workqueue(unsigned long data) 212 { 213 struct usb_line6_podhd *pod = (struct usb_line6_podhd *)data; 214 215 CHECK_STARTUP_PROGRESS(pod->startup_progress, 216 PODHD_STARTUP_SCHEDULE_WORKQUEUE); 217 218 /* schedule work for global work queue: */ 219 schedule_work(&pod->startup_work); 220 } 221 222 static int podhd_dev_start(struct usb_line6_podhd *pod) 223 { 224 int ret; 225 u8 init_bytes[8]; 226 int i; 227 struct usb_device *usbdev = pod->line6.usbdev; 228 229 ret = usb_control_msg(usbdev, usb_sndctrlpipe(usbdev, 0), 230 0x67, USB_TYPE_VENDOR | USB_RECIP_DEVICE | USB_DIR_OUT, 231 0x11, 0, 232 NULL, 0, LINE6_TIMEOUT * HZ); 233 if (ret < 0) { 234 dev_err(pod->line6.ifcdev, "read request failed (error %d)\n", ret); 235 return ret; 236 } 237 238 /* NOTE: looks like some kind of ping message */ 239 ret = usb_control_msg(usbdev, usb_rcvctrlpipe(usbdev, 0), 0x67, 240 USB_TYPE_VENDOR | USB_RECIP_DEVICE | USB_DIR_IN, 241 0x11, 0x0, 242 &init_bytes, 3, LINE6_TIMEOUT * HZ); 243 if (ret < 0) { 244 dev_err(pod->line6.ifcdev, 245 "receive length failed (error %d)\n", ret); 246 return ret; 247 } 248 249 pod->firmware_version = 250 (init_bytes[0] << 16) | (init_bytes[1] << 8) | (init_bytes[2] << 0); 251 252 for (i = 0; i <= 16; i++) { 253 ret = line6_read_data(&pod->line6, 0xf000 + 0x08 * i, init_bytes, 8); 254 if (ret < 0) 255 return ret; 256 } 257 258 ret = usb_control_msg(usbdev, usb_sndctrlpipe(usbdev, 0), 259 USB_REQ_SET_FEATURE, 260 USB_TYPE_STANDARD | USB_RECIP_DEVICE | USB_DIR_OUT, 261 1, 0, 262 NULL, 0, LINE6_TIMEOUT * HZ); 263 if (ret < 0) 264 return ret; 265 266 return 0; 267 } 268 269 static void podhd_startup_workqueue(struct work_struct *work) 270 { 271 struct usb_line6_podhd *pod = 272 container_of(work, struct usb_line6_podhd, startup_work); 273 274 CHECK_STARTUP_PROGRESS(pod->startup_progress, PODHD_STARTUP_SETUP); 275 276 podhd_dev_start(pod); 277 line6_read_serial_number(&pod->line6, &pod->serial_number); 278 279 podhd_startup_finalize(pod); 280 } 281 282 static int podhd_startup_finalize(struct usb_line6_podhd *pod) 283 { 284 struct usb_line6 *line6 = &pod->line6; 285 286 /* ALSA audio interface: */ 287 return snd_card_register(line6->card); 288 } 289 290 static void podhd_disconnect(struct usb_line6 *line6) 291 { 292 struct usb_line6_podhd *pod = (struct usb_line6_podhd *)line6; 293 294 if (pod->line6.properties->capabilities & LINE6_CAP_CONTROL) { 295 struct usb_interface *intf; 296 297 del_timer_sync(&pod->startup_timer); 298 cancel_work_sync(&pod->startup_work); 299 300 intf = usb_ifnum_to_if(line6->usbdev, 301 pod->line6.properties->ctrl_if); 302 usb_driver_release_interface(&podhd_driver, intf); 303 } 304 } 305 306 /* 307 Try to init POD HD device. 308 */ 309 static int podhd_init(struct usb_line6 *line6, 310 const struct usb_device_id *id) 311 { 312 int err; 313 struct usb_line6_podhd *pod = (struct usb_line6_podhd *) line6; 314 struct usb_interface *intf; 315 316 line6->disconnect = podhd_disconnect; 317 318 if (pod->line6.properties->capabilities & LINE6_CAP_CONTROL) { 319 /* claim the data interface */ 320 intf = usb_ifnum_to_if(line6->usbdev, 321 pod->line6.properties->ctrl_if); 322 if (!intf) { 323 dev_err(pod->line6.ifcdev, "interface %d not found\n", 324 pod->line6.properties->ctrl_if); 325 return -ENODEV; 326 } 327 328 err = usb_driver_claim_interface(&podhd_driver, intf, NULL); 329 if (err != 0) { 330 dev_err(pod->line6.ifcdev, "can't claim interface %d, error %d\n", 331 pod->line6.properties->ctrl_if, err); 332 return err; 333 } 334 335 /* create sysfs entries: */ 336 err = snd_card_add_dev_attr(line6->card, &podhd_dev_attr_group); 337 if (err < 0) 338 return err; 339 } 340 341 if (pod->line6.properties->capabilities & LINE6_CAP_PCM) { 342 /* initialize PCM subsystem: */ 343 err = line6_init_pcm(line6, 344 (id->driver_info == LINE6_PODX3 || 345 id->driver_info == LINE6_PODX3LIVE) ? &podx3_pcm_properties : 346 &podhd_pcm_properties); 347 if (err < 0) 348 return err; 349 } 350 351 if (!(pod->line6.properties->capabilities & LINE6_CAP_CONTROL)) { 352 /* register USB audio system directly */ 353 return podhd_startup_finalize(pod); 354 } 355 356 /* init device and delay registering */ 357 init_timer(&pod->startup_timer); 358 INIT_WORK(&pod->startup_work, podhd_startup_workqueue); 359 podhd_startup(pod); 360 return 0; 361 } 362 363 #define LINE6_DEVICE(prod) USB_DEVICE(0x0e41, prod) 364 #define LINE6_IF_NUM(prod, n) USB_DEVICE_INTERFACE_NUMBER(0x0e41, prod, n) 365 366 /* table of devices that work with this driver */ 367 static const struct usb_device_id podhd_id_table[] = { 368 /* TODO: no need to alloc data interfaces when only audio is used */ 369 { LINE6_DEVICE(0x5057), .driver_info = LINE6_PODHD300 }, 370 { LINE6_DEVICE(0x5058), .driver_info = LINE6_PODHD400 }, 371 { LINE6_IF_NUM(0x414D, 0), .driver_info = LINE6_PODHD500_0 }, 372 { LINE6_IF_NUM(0x414D, 1), .driver_info = LINE6_PODHD500_1 }, 373 { LINE6_IF_NUM(0x414A, 0), .driver_info = LINE6_PODX3 }, 374 { LINE6_IF_NUM(0x414B, 0), .driver_info = LINE6_PODX3LIVE }, 375 {} 376 }; 377 378 MODULE_DEVICE_TABLE(usb, podhd_id_table); 379 380 static const struct line6_properties podhd_properties_table[] = { 381 [LINE6_PODHD300] = { 382 .id = "PODHD300", 383 .name = "POD HD300", 384 .capabilities = LINE6_CAP_PCM 385 | LINE6_CAP_HWMON, 386 .altsetting = 5, 387 .ep_ctrl_r = 0x84, 388 .ep_ctrl_w = 0x03, 389 .ep_audio_r = 0x82, 390 .ep_audio_w = 0x01, 391 }, 392 [LINE6_PODHD400] = { 393 .id = "PODHD400", 394 .name = "POD HD400", 395 .capabilities = LINE6_CAP_PCM 396 | LINE6_CAP_HWMON, 397 .altsetting = 5, 398 .ep_ctrl_r = 0x84, 399 .ep_ctrl_w = 0x03, 400 .ep_audio_r = 0x82, 401 .ep_audio_w = 0x01, 402 }, 403 [LINE6_PODHD500_0] = { 404 .id = "PODHD500", 405 .name = "POD HD500", 406 .capabilities = LINE6_CAP_PCM 407 | LINE6_CAP_HWMON, 408 .altsetting = 1, 409 .ep_ctrl_r = 0x81, 410 .ep_ctrl_w = 0x01, 411 .ep_audio_r = 0x86, 412 .ep_audio_w = 0x02, 413 }, 414 [LINE6_PODHD500_1] = { 415 .id = "PODHD500", 416 .name = "POD HD500", 417 .capabilities = LINE6_CAP_PCM 418 | LINE6_CAP_HWMON, 419 .altsetting = 1, 420 .ep_ctrl_r = 0x81, 421 .ep_ctrl_w = 0x01, 422 .ep_audio_r = 0x86, 423 .ep_audio_w = 0x02, 424 }, 425 [LINE6_PODX3] = { 426 .id = "PODX3", 427 .name = "POD X3", 428 .capabilities = LINE6_CAP_CONTROL 429 | LINE6_CAP_PCM | LINE6_CAP_HWMON | LINE6_CAP_IN_NEEDS_OUT, 430 .altsetting = 1, 431 .ep_ctrl_r = 0x81, 432 .ep_ctrl_w = 0x01, 433 .ctrl_if = 1, 434 .ep_audio_r = 0x86, 435 .ep_audio_w = 0x02, 436 }, 437 [LINE6_PODX3LIVE] = { 438 .id = "PODX3LIVE", 439 .name = "POD X3 LIVE", 440 .capabilities = LINE6_CAP_CONTROL 441 | LINE6_CAP_PCM | LINE6_CAP_HWMON | LINE6_CAP_IN_NEEDS_OUT, 442 .altsetting = 1, 443 .ep_ctrl_r = 0x81, 444 .ep_ctrl_w = 0x01, 445 .ctrl_if = 1, 446 .ep_audio_r = 0x86, 447 .ep_audio_w = 0x02, 448 }, 449 }; 450 451 /* 452 Probe USB device. 453 */ 454 static int podhd_probe(struct usb_interface *interface, 455 const struct usb_device_id *id) 456 { 457 return line6_probe(interface, id, "Line6-PODHD", 458 &podhd_properties_table[id->driver_info], 459 podhd_init, sizeof(struct usb_line6_podhd)); 460 } 461 462 static struct usb_driver podhd_driver = { 463 .name = KBUILD_MODNAME, 464 .probe = podhd_probe, 465 .disconnect = line6_disconnect, 466 #ifdef CONFIG_PM 467 .suspend = line6_suspend, 468 .resume = line6_resume, 469 .reset_resume = line6_resume, 470 #endif 471 .id_table = podhd_id_table, 472 }; 473 474 module_usb_driver(podhd_driver); 475 476 MODULE_DESCRIPTION("Line 6 PODHD USB driver"); 477 MODULE_LICENSE("GPL"); 478