podhd.c 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510
  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[8];
  200. int i;
  201. struct usb_device *usbdev = pod->line6.usbdev;
  202. ret = usb_control_msg(usbdev, usb_sndctrlpipe(usbdev, 0),
  203. 0x67, USB_TYPE_VENDOR | USB_RECIP_DEVICE | USB_DIR_OUT,
  204. 0x11, 0,
  205. NULL, 0, LINE6_TIMEOUT * HZ);
  206. if (ret < 0) {
  207. dev_err(pod->line6.ifcdev, "read request failed (error %d)\n", ret);
  208. return ret;
  209. }
  210. /* NOTE: looks like some kind of ping message */
  211. ret = usb_control_msg(usbdev, usb_rcvctrlpipe(usbdev, 0), 0x67,
  212. USB_TYPE_VENDOR | USB_RECIP_DEVICE | USB_DIR_IN,
  213. 0x11, 0x0,
  214. &init_bytes, 3, LINE6_TIMEOUT * HZ);
  215. if (ret < 0) {
  216. dev_err(pod->line6.ifcdev,
  217. "receive length failed (error %d)\n", ret);
  218. return ret;
  219. }
  220. pod->firmware_version =
  221. (init_bytes[0] << 16) | (init_bytes[1] << 8) | (init_bytes[2] << 0);
  222. for (i = 0; i <= 16; i++) {
  223. ret = line6_read_data(&pod->line6, 0xf000 + 0x08 * i, init_bytes, 8);
  224. if (ret < 0)
  225. return ret;
  226. }
  227. ret = usb_control_msg(usbdev, usb_sndctrlpipe(usbdev, 0),
  228. USB_REQ_SET_FEATURE,
  229. USB_TYPE_STANDARD | USB_RECIP_DEVICE | USB_DIR_OUT,
  230. 1, 0,
  231. NULL, 0, LINE6_TIMEOUT * HZ);
  232. if (ret < 0)
  233. return ret;
  234. return 0;
  235. }
  236. static void podhd_startup_workqueue(struct work_struct *work)
  237. {
  238. struct usb_line6_podhd *pod =
  239. container_of(work, struct usb_line6_podhd, startup_work);
  240. CHECK_STARTUP_PROGRESS(pod->startup_progress, PODHD_STARTUP_SETUP);
  241. podhd_dev_start(pod);
  242. line6_read_serial_number(&pod->line6, &pod->serial_number);
  243. podhd_startup_finalize(pod);
  244. }
  245. static int podhd_startup_finalize(struct usb_line6_podhd *pod)
  246. {
  247. struct usb_line6 *line6 = &pod->line6;
  248. /* ALSA audio interface: */
  249. return snd_card_register(line6->card);
  250. }
  251. static void podhd_disconnect(struct usb_line6 *line6)
  252. {
  253. struct usb_line6_podhd *pod = (struct usb_line6_podhd *)line6;
  254. if (pod->line6.properties->capabilities & LINE6_CAP_CONTROL_INFO) {
  255. struct usb_interface *intf;
  256. del_timer_sync(&pod->startup_timer);
  257. cancel_work_sync(&pod->startup_work);
  258. intf = usb_ifnum_to_if(line6->usbdev,
  259. pod->line6.properties->ctrl_if);
  260. if (intf)
  261. usb_driver_release_interface(&podhd_driver, intf);
  262. }
  263. }
  264. /*
  265. Try to init POD HD device.
  266. */
  267. static int podhd_init(struct usb_line6 *line6,
  268. const struct usb_device_id *id)
  269. {
  270. int err;
  271. struct usb_line6_podhd *pod = (struct usb_line6_podhd *) line6;
  272. struct usb_interface *intf;
  273. line6->disconnect = podhd_disconnect;
  274. timer_setup(&pod->startup_timer, NULL, 0);
  275. INIT_WORK(&pod->startup_work, podhd_startup_workqueue);
  276. if (pod->line6.properties->capabilities & LINE6_CAP_CONTROL) {
  277. /* claim the data interface */
  278. intf = usb_ifnum_to_if(line6->usbdev,
  279. pod->line6.properties->ctrl_if);
  280. if (!intf) {
  281. dev_err(pod->line6.ifcdev, "interface %d not found\n",
  282. pod->line6.properties->ctrl_if);
  283. return -ENODEV;
  284. }
  285. err = usb_driver_claim_interface(&podhd_driver, intf, NULL);
  286. if (err != 0) {
  287. dev_err(pod->line6.ifcdev, "can't claim interface %d, error %d\n",
  288. pod->line6.properties->ctrl_if, err);
  289. return err;
  290. }
  291. }
  292. if (pod->line6.properties->capabilities & LINE6_CAP_CONTROL_INFO) {
  293. /* create sysfs entries: */
  294. err = snd_card_add_dev_attr(line6->card, &podhd_dev_attr_group);
  295. if (err < 0)
  296. return err;
  297. }
  298. if (pod->line6.properties->capabilities & LINE6_CAP_PCM) {
  299. /* initialize PCM subsystem: */
  300. err = line6_init_pcm(line6,
  301. (id->driver_info == LINE6_PODX3 ||
  302. id->driver_info == LINE6_PODX3LIVE) ? &podx3_pcm_properties :
  303. &podhd_pcm_properties);
  304. if (err < 0)
  305. return err;
  306. }
  307. if (!(pod->line6.properties->capabilities & LINE6_CAP_CONTROL_INFO)) {
  308. /* register USB audio system directly */
  309. return podhd_startup_finalize(pod);
  310. }
  311. /* init device and delay registering */
  312. podhd_startup(pod);
  313. return 0;
  314. }
  315. #define LINE6_DEVICE(prod) USB_DEVICE(0x0e41, prod)
  316. #define LINE6_IF_NUM(prod, n) USB_DEVICE_INTERFACE_NUMBER(0x0e41, prod, n)
  317. /* table of devices that work with this driver */
  318. static const struct usb_device_id podhd_id_table[] = {
  319. /* TODO: no need to alloc data interfaces when only audio is used */
  320. { LINE6_DEVICE(0x5057), .driver_info = LINE6_PODHD300 },
  321. { LINE6_DEVICE(0x5058), .driver_info = LINE6_PODHD400 },
  322. { LINE6_IF_NUM(0x414D, 0), .driver_info = LINE6_PODHD500_0 },
  323. { LINE6_IF_NUM(0x414D, 1), .driver_info = LINE6_PODHD500_1 },
  324. { LINE6_IF_NUM(0x414A, 0), .driver_info = LINE6_PODX3 },
  325. { LINE6_IF_NUM(0x414B, 0), .driver_info = LINE6_PODX3LIVE },
  326. { LINE6_IF_NUM(0x4159, 0), .driver_info = LINE6_PODHD500X },
  327. { LINE6_IF_NUM(0x4156, 0), .driver_info = LINE6_PODHDDESKTOP },
  328. {}
  329. };
  330. MODULE_DEVICE_TABLE(usb, podhd_id_table);
  331. static const struct line6_properties podhd_properties_table[] = {
  332. [LINE6_PODHD300] = {
  333. .id = "PODHD300",
  334. .name = "POD HD300",
  335. .capabilities = LINE6_CAP_PCM
  336. | LINE6_CAP_HWMON,
  337. .altsetting = 5,
  338. .ep_ctrl_r = 0x84,
  339. .ep_ctrl_w = 0x03,
  340. .ep_audio_r = 0x82,
  341. .ep_audio_w = 0x01,
  342. },
  343. [LINE6_PODHD400] = {
  344. .id = "PODHD400",
  345. .name = "POD HD400",
  346. .capabilities = LINE6_CAP_PCM
  347. | LINE6_CAP_HWMON,
  348. .altsetting = 5,
  349. .ep_ctrl_r = 0x84,
  350. .ep_ctrl_w = 0x03,
  351. .ep_audio_r = 0x82,
  352. .ep_audio_w = 0x01,
  353. },
  354. [LINE6_PODHD500_0] = {
  355. .id = "PODHD500",
  356. .name = "POD HD500",
  357. .capabilities = LINE6_CAP_PCM
  358. | LINE6_CAP_HWMON,
  359. .altsetting = 1,
  360. .ep_ctrl_r = 0x81,
  361. .ep_ctrl_w = 0x01,
  362. .ep_audio_r = 0x86,
  363. .ep_audio_w = 0x02,
  364. },
  365. [LINE6_PODHD500_1] = {
  366. .id = "PODHD500",
  367. .name = "POD HD500",
  368. .capabilities = LINE6_CAP_PCM
  369. | LINE6_CAP_HWMON,
  370. .altsetting = 1,
  371. .ep_ctrl_r = 0x81,
  372. .ep_ctrl_w = 0x01,
  373. .ep_audio_r = 0x86,
  374. .ep_audio_w = 0x02,
  375. },
  376. [LINE6_PODX3] = {
  377. .id = "PODX3",
  378. .name = "POD X3",
  379. .capabilities = LINE6_CAP_CONTROL | LINE6_CAP_CONTROL_INFO
  380. | LINE6_CAP_PCM | LINE6_CAP_HWMON | LINE6_CAP_IN_NEEDS_OUT,
  381. .altsetting = 1,
  382. .ep_ctrl_r = 0x81,
  383. .ep_ctrl_w = 0x01,
  384. .ctrl_if = 1,
  385. .ep_audio_r = 0x86,
  386. .ep_audio_w = 0x02,
  387. },
  388. [LINE6_PODX3LIVE] = {
  389. .id = "PODX3LIVE",
  390. .name = "POD X3 LIVE",
  391. .capabilities = LINE6_CAP_CONTROL | LINE6_CAP_CONTROL_INFO
  392. | LINE6_CAP_PCM | LINE6_CAP_HWMON | LINE6_CAP_IN_NEEDS_OUT,
  393. .altsetting = 1,
  394. .ep_ctrl_r = 0x81,
  395. .ep_ctrl_w = 0x01,
  396. .ctrl_if = 1,
  397. .ep_audio_r = 0x86,
  398. .ep_audio_w = 0x02,
  399. },
  400. [LINE6_PODHD500X] = {
  401. .id = "PODHD500X",
  402. .name = "POD HD500X",
  403. .capabilities = LINE6_CAP_CONTROL
  404. | LINE6_CAP_PCM | LINE6_CAP_HWMON,
  405. .altsetting = 1,
  406. .ep_ctrl_r = 0x81,
  407. .ep_ctrl_w = 0x01,
  408. .ctrl_if = 1,
  409. .ep_audio_r = 0x86,
  410. .ep_audio_w = 0x02,
  411. },
  412. [LINE6_PODHDDESKTOP] = {
  413. .id = "PODHDDESKTOP",
  414. .name = "POD HDDESKTOP",
  415. .capabilities = LINE6_CAP_CONTROL
  416. | LINE6_CAP_PCM | LINE6_CAP_HWMON,
  417. .altsetting = 1,
  418. .ep_ctrl_r = 0x81,
  419. .ep_ctrl_w = 0x01,
  420. .ctrl_if = 1,
  421. .ep_audio_r = 0x86,
  422. .ep_audio_w = 0x02,
  423. },
  424. };
  425. /*
  426. Probe USB device.
  427. */
  428. static int podhd_probe(struct usb_interface *interface,
  429. const struct usb_device_id *id)
  430. {
  431. return line6_probe(interface, id, "Line6-PODHD",
  432. &podhd_properties_table[id->driver_info],
  433. podhd_init, sizeof(struct usb_line6_podhd));
  434. }
  435. static struct usb_driver podhd_driver = {
  436. .name = KBUILD_MODNAME,
  437. .probe = podhd_probe,
  438. .disconnect = line6_disconnect,
  439. #ifdef CONFIG_PM
  440. .suspend = line6_suspend,
  441. .resume = line6_resume,
  442. .reset_resume = line6_resume,
  443. #endif
  444. .id_table = podhd_id_table,
  445. };
  446. module_usb_driver(podhd_driver);
  447. MODULE_DESCRIPTION("Line 6 PODHD USB driver");
  448. MODULE_LICENSE("GPL");