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