podhd.c 13 KB

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