chip.c 7.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297
  1. /*
  2. * Linux driver for M2Tech hiFace compatible devices
  3. *
  4. * Copyright 2012-2013 (C) M2TECH S.r.l and Amarula Solutions B.V.
  5. *
  6. * Authors: Michael Trimarchi <michael@amarulasolutions.com>
  7. * Antonio Ospite <ao2@amarulasolutions.com>
  8. *
  9. * The driver is based on the work done in TerraTec DMX 6Fire USB
  10. *
  11. * This program is free software; you can redistribute it and/or modify
  12. * it under the terms of the GNU General Public License as published by
  13. * the Free Software Foundation; either version 2 of the License, or
  14. * (at your option) any later version.
  15. */
  16. #include <linux/module.h>
  17. #include <linux/slab.h>
  18. #include <sound/initval.h>
  19. #include "chip.h"
  20. #include "pcm.h"
  21. MODULE_AUTHOR("Michael Trimarchi <michael@amarulasolutions.com>");
  22. MODULE_AUTHOR("Antonio Ospite <ao2@amarulasolutions.com>");
  23. MODULE_DESCRIPTION("M2Tech hiFace USB-SPDIF audio driver");
  24. MODULE_LICENSE("GPL v2");
  25. MODULE_SUPPORTED_DEVICE("{{M2Tech,Young},"
  26. "{M2Tech,hiFace},"
  27. "{M2Tech,North Star},"
  28. "{M2Tech,W4S Young},"
  29. "{M2Tech,Corrson},"
  30. "{M2Tech,AUDIA},"
  31. "{M2Tech,SL Audio},"
  32. "{M2Tech,Empirical},"
  33. "{M2Tech,Rockna},"
  34. "{M2Tech,Pathos},"
  35. "{M2Tech,Metronome},"
  36. "{M2Tech,CAD},"
  37. "{M2Tech,Audio Esclusive},"
  38. "{M2Tech,Rotel},"
  39. "{M2Tech,Eeaudio},"
  40. "{The Chord Company,CHORD},"
  41. "{AVA Group A/S,Vitus}}");
  42. static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX; /* Index 0-max */
  43. static char *id[SNDRV_CARDS] = SNDRV_DEFAULT_STR; /* Id for card */
  44. static bool enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE_PNP; /* Enable this card */
  45. #define DRIVER_NAME "snd-usb-hiface"
  46. #define CARD_NAME "hiFace"
  47. module_param_array(index, int, NULL, 0444);
  48. MODULE_PARM_DESC(index, "Index value for " CARD_NAME " soundcard.");
  49. module_param_array(id, charp, NULL, 0444);
  50. MODULE_PARM_DESC(id, "ID string for " CARD_NAME " soundcard.");
  51. module_param_array(enable, bool, NULL, 0444);
  52. MODULE_PARM_DESC(enable, "Enable " CARD_NAME " soundcard.");
  53. static DEFINE_MUTEX(register_mutex);
  54. struct hiface_vendor_quirk {
  55. const char *device_name;
  56. u8 extra_freq;
  57. };
  58. static int hiface_chip_create(struct usb_interface *intf,
  59. struct usb_device *device, int idx,
  60. const struct hiface_vendor_quirk *quirk,
  61. struct hiface_chip **rchip)
  62. {
  63. struct snd_card *card = NULL;
  64. struct hiface_chip *chip;
  65. int ret;
  66. int len;
  67. *rchip = NULL;
  68. /* if we are here, card can be registered in alsa. */
  69. ret = snd_card_new(&intf->dev, index[idx], id[idx], THIS_MODULE,
  70. sizeof(*chip), &card);
  71. if (ret < 0) {
  72. dev_err(&device->dev, "cannot create alsa card.\n");
  73. return ret;
  74. }
  75. strlcpy(card->driver, DRIVER_NAME, sizeof(card->driver));
  76. if (quirk && quirk->device_name)
  77. strlcpy(card->shortname, quirk->device_name, sizeof(card->shortname));
  78. else
  79. strlcpy(card->shortname, "M2Tech generic audio", sizeof(card->shortname));
  80. strlcat(card->longname, card->shortname, sizeof(card->longname));
  81. len = strlcat(card->longname, " at ", sizeof(card->longname));
  82. if (len < sizeof(card->longname))
  83. usb_make_path(device, card->longname + len,
  84. sizeof(card->longname) - len);
  85. chip = card->private_data;
  86. chip->dev = device;
  87. chip->card = card;
  88. *rchip = chip;
  89. return 0;
  90. }
  91. static int hiface_chip_probe(struct usb_interface *intf,
  92. const struct usb_device_id *usb_id)
  93. {
  94. const struct hiface_vendor_quirk *quirk = (struct hiface_vendor_quirk *)usb_id->driver_info;
  95. int ret;
  96. int i;
  97. struct hiface_chip *chip;
  98. struct usb_device *device = interface_to_usbdev(intf);
  99. ret = usb_set_interface(device, 0, 0);
  100. if (ret != 0) {
  101. dev_err(&device->dev, "can't set first interface for " CARD_NAME " device.\n");
  102. return -EIO;
  103. }
  104. /* check whether the card is already registered */
  105. chip = NULL;
  106. mutex_lock(&register_mutex);
  107. for (i = 0; i < SNDRV_CARDS; i++)
  108. if (enable[i])
  109. break;
  110. if (i >= SNDRV_CARDS) {
  111. dev_err(&device->dev, "no available " CARD_NAME " audio device\n");
  112. ret = -ENODEV;
  113. goto err;
  114. }
  115. ret = hiface_chip_create(intf, device, i, quirk, &chip);
  116. if (ret < 0)
  117. goto err;
  118. ret = hiface_pcm_init(chip, quirk ? quirk->extra_freq : 0);
  119. if (ret < 0)
  120. goto err_chip_destroy;
  121. ret = snd_card_register(chip->card);
  122. if (ret < 0) {
  123. dev_err(&device->dev, "cannot register " CARD_NAME " card\n");
  124. goto err_chip_destroy;
  125. }
  126. mutex_unlock(&register_mutex);
  127. usb_set_intfdata(intf, chip);
  128. return 0;
  129. err_chip_destroy:
  130. snd_card_free(chip->card);
  131. err:
  132. mutex_unlock(&register_mutex);
  133. return ret;
  134. }
  135. static void hiface_chip_disconnect(struct usb_interface *intf)
  136. {
  137. struct hiface_chip *chip;
  138. struct snd_card *card;
  139. chip = usb_get_intfdata(intf);
  140. if (!chip)
  141. return;
  142. card = chip->card;
  143. /* Make sure that the userspace cannot create new request */
  144. snd_card_disconnect(card);
  145. hiface_pcm_abort(chip);
  146. snd_card_free_when_closed(card);
  147. }
  148. static const struct usb_device_id device_table[] = {
  149. {
  150. USB_DEVICE(0x04b4, 0x0384),
  151. .driver_info = (unsigned long)&(const struct hiface_vendor_quirk) {
  152. .device_name = "Young",
  153. .extra_freq = 1,
  154. }
  155. },
  156. {
  157. USB_DEVICE(0x04b4, 0x930b),
  158. .driver_info = (unsigned long)&(const struct hiface_vendor_quirk) {
  159. .device_name = "hiFace",
  160. }
  161. },
  162. {
  163. USB_DEVICE(0x04b4, 0x931b),
  164. .driver_info = (unsigned long)&(const struct hiface_vendor_quirk) {
  165. .device_name = "North Star",
  166. }
  167. },
  168. {
  169. USB_DEVICE(0x04b4, 0x931c),
  170. .driver_info = (unsigned long)&(const struct hiface_vendor_quirk) {
  171. .device_name = "W4S Young",
  172. }
  173. },
  174. {
  175. USB_DEVICE(0x04b4, 0x931d),
  176. .driver_info = (unsigned long)&(const struct hiface_vendor_quirk) {
  177. .device_name = "Corrson",
  178. }
  179. },
  180. {
  181. USB_DEVICE(0x04b4, 0x931e),
  182. .driver_info = (unsigned long)&(const struct hiface_vendor_quirk) {
  183. .device_name = "AUDIA",
  184. }
  185. },
  186. {
  187. USB_DEVICE(0x04b4, 0x931f),
  188. .driver_info = (unsigned long)&(const struct hiface_vendor_quirk) {
  189. .device_name = "SL Audio",
  190. }
  191. },
  192. {
  193. USB_DEVICE(0x04b4, 0x9320),
  194. .driver_info = (unsigned long)&(const struct hiface_vendor_quirk) {
  195. .device_name = "Empirical",
  196. }
  197. },
  198. {
  199. USB_DEVICE(0x04b4, 0x9321),
  200. .driver_info = (unsigned long)&(const struct hiface_vendor_quirk) {
  201. .device_name = "Rockna",
  202. }
  203. },
  204. {
  205. USB_DEVICE(0x249c, 0x9001),
  206. .driver_info = (unsigned long)&(const struct hiface_vendor_quirk) {
  207. .device_name = "Pathos",
  208. }
  209. },
  210. {
  211. USB_DEVICE(0x249c, 0x9002),
  212. .driver_info = (unsigned long)&(const struct hiface_vendor_quirk) {
  213. .device_name = "Metronome",
  214. }
  215. },
  216. {
  217. USB_DEVICE(0x249c, 0x9006),
  218. .driver_info = (unsigned long)&(const struct hiface_vendor_quirk) {
  219. .device_name = "CAD",
  220. }
  221. },
  222. {
  223. USB_DEVICE(0x249c, 0x9008),
  224. .driver_info = (unsigned long)&(const struct hiface_vendor_quirk) {
  225. .device_name = "Audio Esclusive",
  226. }
  227. },
  228. {
  229. USB_DEVICE(0x249c, 0x931c),
  230. .driver_info = (unsigned long)&(const struct hiface_vendor_quirk) {
  231. .device_name = "Rotel",
  232. }
  233. },
  234. {
  235. USB_DEVICE(0x249c, 0x932c),
  236. .driver_info = (unsigned long)&(const struct hiface_vendor_quirk) {
  237. .device_name = "Eeaudio",
  238. }
  239. },
  240. {
  241. USB_DEVICE(0x245f, 0x931c),
  242. .driver_info = (unsigned long)&(const struct hiface_vendor_quirk) {
  243. .device_name = "CHORD",
  244. }
  245. },
  246. {
  247. USB_DEVICE(0x25c6, 0x9002),
  248. .driver_info = (unsigned long)&(const struct hiface_vendor_quirk) {
  249. .device_name = "Vitus",
  250. }
  251. },
  252. {}
  253. };
  254. MODULE_DEVICE_TABLE(usb, device_table);
  255. static struct usb_driver hiface_usb_driver = {
  256. .name = DRIVER_NAME,
  257. .probe = hiface_chip_probe,
  258. .disconnect = hiface_chip_disconnect,
  259. .id_table = device_table,
  260. };
  261. module_usb_driver(hiface_usb_driver);