podhd.c 4.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193
  1. /*
  2. * Line 6 Pod HD
  3. *
  4. * Copyright (C) 2011 Stefan Hajnoczi <stefanha@gmail.com>
  5. *
  6. * This program is free software; you can redistribute it and/or
  7. * modify it under the terms of the GNU General Public License as
  8. * published by the Free Software Foundation, version 2.
  9. *
  10. */
  11. #include <linux/usb.h>
  12. #include <linux/slab.h>
  13. #include <linux/module.h>
  14. #include <sound/core.h>
  15. #include <sound/pcm.h>
  16. #include "driver.h"
  17. #include "pcm.h"
  18. enum {
  19. LINE6_PODHD300,
  20. LINE6_PODHD400,
  21. LINE6_PODHD500_0,
  22. LINE6_PODHD500_1,
  23. };
  24. #define PODHD_BYTES_PER_FRAME 6 /* 24bit audio (stereo) */
  25. static struct snd_ratden podhd_ratden = {
  26. .num_min = 48000,
  27. .num_max = 48000,
  28. .num_step = 1,
  29. .den = 1,
  30. };
  31. static struct line6_pcm_properties podhd_pcm_properties = {
  32. .playback_hw = {
  33. .info = (SNDRV_PCM_INFO_MMAP |
  34. SNDRV_PCM_INFO_INTERLEAVED |
  35. SNDRV_PCM_INFO_BLOCK_TRANSFER |
  36. SNDRV_PCM_INFO_MMAP_VALID |
  37. SNDRV_PCM_INFO_PAUSE |
  38. SNDRV_PCM_INFO_SYNC_START),
  39. .formats = SNDRV_PCM_FMTBIT_S24_3LE,
  40. .rates = SNDRV_PCM_RATE_48000,
  41. .rate_min = 48000,
  42. .rate_max = 48000,
  43. .channels_min = 2,
  44. .channels_max = 2,
  45. .buffer_bytes_max = 60000,
  46. .period_bytes_min = 64,
  47. .period_bytes_max = 8192,
  48. .periods_min = 1,
  49. .periods_max = 1024},
  50. .capture_hw = {
  51. .info = (SNDRV_PCM_INFO_MMAP |
  52. SNDRV_PCM_INFO_INTERLEAVED |
  53. SNDRV_PCM_INFO_BLOCK_TRANSFER |
  54. SNDRV_PCM_INFO_MMAP_VALID |
  55. SNDRV_PCM_INFO_SYNC_START),
  56. .formats = SNDRV_PCM_FMTBIT_S24_3LE,
  57. .rates = SNDRV_PCM_RATE_48000,
  58. .rate_min = 48000,
  59. .rate_max = 48000,
  60. .channels_min = 2,
  61. .channels_max = 2,
  62. .buffer_bytes_max = 60000,
  63. .period_bytes_min = 64,
  64. .period_bytes_max = 8192,
  65. .periods_min = 1,
  66. .periods_max = 1024},
  67. .rates = {
  68. .nrats = 1,
  69. .rats = &podhd_ratden},
  70. .bytes_per_frame = PODHD_BYTES_PER_FRAME
  71. };
  72. /*
  73. Try to init POD HD device.
  74. */
  75. static int podhd_init(struct usb_line6 *line6,
  76. const struct usb_device_id *id)
  77. {
  78. int err;
  79. /* initialize MIDI subsystem: */
  80. err = line6_init_midi(line6);
  81. if (err < 0)
  82. return err;
  83. /* initialize PCM subsystem: */
  84. err = line6_init_pcm(line6, &podhd_pcm_properties);
  85. if (err < 0)
  86. return err;
  87. /* register USB audio system: */
  88. return snd_card_register(line6->card);
  89. }
  90. #define LINE6_DEVICE(prod) USB_DEVICE(0x0e41, prod)
  91. #define LINE6_IF_NUM(prod, n) USB_DEVICE_INTERFACE_NUMBER(0x0e41, prod, n)
  92. /* table of devices that work with this driver */
  93. static const struct usb_device_id podhd_id_table[] = {
  94. { LINE6_DEVICE(0x5057), .driver_info = LINE6_PODHD300 },
  95. { LINE6_DEVICE(0x5058), .driver_info = LINE6_PODHD400 },
  96. { LINE6_IF_NUM(0x414D, 0), .driver_info = LINE6_PODHD500_0 },
  97. { LINE6_IF_NUM(0x414D, 1), .driver_info = LINE6_PODHD500_1 },
  98. {}
  99. };
  100. MODULE_DEVICE_TABLE(usb, podhd_id_table);
  101. static const struct line6_properties podhd_properties_table[] = {
  102. [LINE6_PODHD300] = {
  103. .id = "PODHD300",
  104. .name = "POD HD300",
  105. .capabilities = LINE6_CAP_CONTROL
  106. | LINE6_CAP_PCM
  107. | LINE6_CAP_HWMON,
  108. .altsetting = 5,
  109. .ep_ctrl_r = 0x84,
  110. .ep_ctrl_w = 0x03,
  111. .ep_audio_r = 0x82,
  112. .ep_audio_w = 0x01,
  113. },
  114. [LINE6_PODHD400] = {
  115. .id = "PODHD400",
  116. .name = "POD HD400",
  117. .capabilities = LINE6_CAP_CONTROL
  118. | LINE6_CAP_PCM
  119. | LINE6_CAP_HWMON,
  120. .altsetting = 5,
  121. .ep_ctrl_r = 0x84,
  122. .ep_ctrl_w = 0x03,
  123. .ep_audio_r = 0x82,
  124. .ep_audio_w = 0x01,
  125. },
  126. [LINE6_PODHD500_0] = {
  127. .id = "PODHD500",
  128. .name = "POD HD500",
  129. .capabilities = LINE6_CAP_CONTROL
  130. | LINE6_CAP_PCM
  131. | LINE6_CAP_HWMON,
  132. .altsetting = 1,
  133. .ep_ctrl_r = 0x81,
  134. .ep_ctrl_w = 0x01,
  135. .ep_audio_r = 0x86,
  136. .ep_audio_w = 0x02,
  137. },
  138. [LINE6_PODHD500_1] = {
  139. .id = "PODHD500",
  140. .name = "POD HD500",
  141. .capabilities = LINE6_CAP_CONTROL
  142. | LINE6_CAP_PCM
  143. | LINE6_CAP_HWMON,
  144. .altsetting = 1,
  145. .ep_ctrl_r = 0x81,
  146. .ep_ctrl_w = 0x01,
  147. .ep_audio_r = 0x86,
  148. .ep_audio_w = 0x02,
  149. },
  150. };
  151. /*
  152. Probe USB device.
  153. */
  154. static int podhd_probe(struct usb_interface *interface,
  155. const struct usb_device_id *id)
  156. {
  157. return line6_probe(interface, id, "Line6-PODHD",
  158. &podhd_properties_table[id->driver_info],
  159. podhd_init, sizeof(struct usb_line6));
  160. }
  161. static struct usb_driver podhd_driver = {
  162. .name = KBUILD_MODNAME,
  163. .probe = podhd_probe,
  164. .disconnect = line6_disconnect,
  165. #ifdef CONFIG_PM
  166. .suspend = line6_suspend,
  167. .resume = line6_resume,
  168. .reset_resume = line6_resume,
  169. #endif
  170. .id_table = podhd_id_table,
  171. };
  172. module_usb_driver(podhd_driver);
  173. MODULE_DESCRIPTION("Line 6 PODHD USB driver");
  174. MODULE_LICENSE("GPL");