pcm.c 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509
  1. /*
  2. * Line6 Linux USB driver - 0.9.1beta
  3. *
  4. * Copyright (C) 2004-2010 Markus Grabner (grabner@icg.tugraz.at)
  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/slab.h>
  12. #include <linux/export.h>
  13. #include <sound/core.h>
  14. #include <sound/control.h>
  15. #include <sound/pcm.h>
  16. #include <sound/pcm_params.h>
  17. #include "audio.h"
  18. #include "capture.h"
  19. #include "driver.h"
  20. #include "playback.h"
  21. /* impulse response volume controls */
  22. static int snd_line6_impulse_volume_info(struct snd_kcontrol *kcontrol,
  23. struct snd_ctl_elem_info *uinfo)
  24. {
  25. uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
  26. uinfo->count = 1;
  27. uinfo->value.integer.min = 0;
  28. uinfo->value.integer.max = 255;
  29. return 0;
  30. }
  31. static int snd_line6_impulse_volume_get(struct snd_kcontrol *kcontrol,
  32. struct snd_ctl_elem_value *ucontrol)
  33. {
  34. struct snd_line6_pcm *line6pcm = snd_kcontrol_chip(kcontrol);
  35. ucontrol->value.integer.value[0] = line6pcm->impulse_volume;
  36. return 0;
  37. }
  38. static int snd_line6_impulse_volume_put(struct snd_kcontrol *kcontrol,
  39. struct snd_ctl_elem_value *ucontrol)
  40. {
  41. struct snd_line6_pcm *line6pcm = snd_kcontrol_chip(kcontrol);
  42. int value = ucontrol->value.integer.value[0];
  43. if (line6pcm->impulse_volume == value)
  44. return 0;
  45. line6pcm->impulse_volume = value;
  46. if (value > 0)
  47. line6_pcm_acquire(line6pcm, LINE6_BITS_PCM_IMPULSE);
  48. else
  49. line6_pcm_release(line6pcm, LINE6_BITS_PCM_IMPULSE);
  50. return 1;
  51. }
  52. /* impulse response period controls */
  53. static int snd_line6_impulse_period_info(struct snd_kcontrol *kcontrol,
  54. struct snd_ctl_elem_info *uinfo)
  55. {
  56. uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
  57. uinfo->count = 1;
  58. uinfo->value.integer.min = 0;
  59. uinfo->value.integer.max = 2000;
  60. return 0;
  61. }
  62. static int snd_line6_impulse_period_get(struct snd_kcontrol *kcontrol,
  63. struct snd_ctl_elem_value *ucontrol)
  64. {
  65. struct snd_line6_pcm *line6pcm = snd_kcontrol_chip(kcontrol);
  66. ucontrol->value.integer.value[0] = line6pcm->impulse_period;
  67. return 0;
  68. }
  69. static int snd_line6_impulse_period_put(struct snd_kcontrol *kcontrol,
  70. struct snd_ctl_elem_value *ucontrol)
  71. {
  72. struct snd_line6_pcm *line6pcm = snd_kcontrol_chip(kcontrol);
  73. int value = ucontrol->value.integer.value[0];
  74. if (line6pcm->impulse_period == value)
  75. return 0;
  76. line6pcm->impulse_period = value;
  77. return 1;
  78. }
  79. static bool test_flags(unsigned long flags0, unsigned long flags1,
  80. unsigned long mask)
  81. {
  82. return ((flags0 & mask) == 0) && ((flags1 & mask) != 0);
  83. }
  84. int line6_pcm_acquire(struct snd_line6_pcm *line6pcm, int channels)
  85. {
  86. unsigned long flags_old, flags_new, flags_final;
  87. int err;
  88. do {
  89. flags_old = ACCESS_ONCE(line6pcm->flags);
  90. flags_new = flags_old | channels;
  91. } while (cmpxchg(&line6pcm->flags, flags_old, flags_new) != flags_old);
  92. flags_final = flags_old;
  93. line6pcm->prev_fbuf = NULL;
  94. if (test_flags(flags_old, flags_new, LINE6_BITS_CAPTURE_BUFFER)) {
  95. /* Invoked multiple times in a row so allocate once only */
  96. if (!line6pcm->buffer_in) {
  97. line6pcm->buffer_in =
  98. kmalloc(LINE6_ISO_BUFFERS * LINE6_ISO_PACKETS *
  99. line6pcm->max_packet_size, GFP_KERNEL);
  100. if (!line6pcm->buffer_in) {
  101. err = -ENOMEM;
  102. goto pcm_acquire_error;
  103. }
  104. flags_final |= channels & LINE6_BITS_CAPTURE_BUFFER;
  105. }
  106. }
  107. if (test_flags(flags_old, flags_new, LINE6_BITS_CAPTURE_STREAM)) {
  108. /*
  109. Waiting for completion of active URBs in the stop handler is
  110. a bug, we therefore report an error if capturing is restarted
  111. too soon.
  112. */
  113. if (line6pcm->active_urb_in | line6pcm->unlink_urb_in) {
  114. dev_err(line6pcm->line6->ifcdev, "Device not yet ready\n");
  115. return -EBUSY;
  116. }
  117. line6pcm->count_in = 0;
  118. line6pcm->prev_fsize = 0;
  119. err = line6_submit_audio_in_all_urbs(line6pcm);
  120. if (err < 0)
  121. goto pcm_acquire_error;
  122. flags_final |= channels & LINE6_BITS_CAPTURE_STREAM;
  123. }
  124. if (test_flags(flags_old, flags_new, LINE6_BITS_PLAYBACK_BUFFER)) {
  125. /* Invoked multiple times in a row so allocate once only */
  126. if (!line6pcm->buffer_out) {
  127. line6pcm->buffer_out =
  128. kmalloc(LINE6_ISO_BUFFERS * LINE6_ISO_PACKETS *
  129. line6pcm->max_packet_size, GFP_KERNEL);
  130. if (!line6pcm->buffer_out) {
  131. err = -ENOMEM;
  132. goto pcm_acquire_error;
  133. }
  134. flags_final |= channels & LINE6_BITS_PLAYBACK_BUFFER;
  135. }
  136. }
  137. if (test_flags(flags_old, flags_new, LINE6_BITS_PLAYBACK_STREAM)) {
  138. /*
  139. See comment above regarding PCM restart.
  140. */
  141. if (line6pcm->active_urb_out | line6pcm->unlink_urb_out) {
  142. dev_err(line6pcm->line6->ifcdev, "Device not yet ready\n");
  143. return -EBUSY;
  144. }
  145. line6pcm->count_out = 0;
  146. err = line6_submit_audio_out_all_urbs(line6pcm);
  147. if (err < 0)
  148. goto pcm_acquire_error;
  149. flags_final |= channels & LINE6_BITS_PLAYBACK_STREAM;
  150. }
  151. return 0;
  152. pcm_acquire_error:
  153. /*
  154. If not all requested resources/streams could be obtained, release
  155. those which were successfully obtained (if any).
  156. */
  157. line6_pcm_release(line6pcm, flags_final & channels);
  158. return err;
  159. }
  160. EXPORT_SYMBOL_GPL(line6_pcm_acquire);
  161. int line6_pcm_release(struct snd_line6_pcm *line6pcm, int channels)
  162. {
  163. unsigned long flags_old, flags_new;
  164. do {
  165. flags_old = ACCESS_ONCE(line6pcm->flags);
  166. flags_new = flags_old & ~channels;
  167. } while (cmpxchg(&line6pcm->flags, flags_old, flags_new) != flags_old);
  168. if (test_flags(flags_new, flags_old, LINE6_BITS_CAPTURE_STREAM))
  169. line6_unlink_audio_in_urbs(line6pcm);
  170. if (test_flags(flags_new, flags_old, LINE6_BITS_CAPTURE_BUFFER)) {
  171. line6_wait_clear_audio_in_urbs(line6pcm);
  172. line6_free_capture_buffer(line6pcm);
  173. }
  174. if (test_flags(flags_new, flags_old, LINE6_BITS_PLAYBACK_STREAM))
  175. line6_unlink_audio_out_urbs(line6pcm);
  176. if (test_flags(flags_new, flags_old, LINE6_BITS_PLAYBACK_BUFFER)) {
  177. line6_wait_clear_audio_out_urbs(line6pcm);
  178. line6_free_playback_buffer(line6pcm);
  179. }
  180. return 0;
  181. }
  182. EXPORT_SYMBOL_GPL(line6_pcm_release);
  183. /* trigger callback */
  184. int snd_line6_trigger(struct snd_pcm_substream *substream, int cmd)
  185. {
  186. struct snd_line6_pcm *line6pcm = snd_pcm_substream_chip(substream);
  187. struct snd_pcm_substream *s;
  188. int err;
  189. unsigned long flags;
  190. spin_lock_irqsave(&line6pcm->lock_trigger, flags);
  191. clear_bit(LINE6_INDEX_PREPARED, &line6pcm->flags);
  192. snd_pcm_group_for_each_entry(s, substream) {
  193. switch (s->stream) {
  194. case SNDRV_PCM_STREAM_PLAYBACK:
  195. err = snd_line6_playback_trigger(line6pcm, cmd);
  196. if (err < 0) {
  197. spin_unlock_irqrestore(&line6pcm->lock_trigger,
  198. flags);
  199. return err;
  200. }
  201. break;
  202. case SNDRV_PCM_STREAM_CAPTURE:
  203. err = snd_line6_capture_trigger(line6pcm, cmd);
  204. if (err < 0) {
  205. spin_unlock_irqrestore(&line6pcm->lock_trigger,
  206. flags);
  207. return err;
  208. }
  209. break;
  210. default:
  211. dev_err(line6pcm->line6->ifcdev,
  212. "Unknown stream direction %d\n", s->stream);
  213. }
  214. }
  215. spin_unlock_irqrestore(&line6pcm->lock_trigger, flags);
  216. return 0;
  217. }
  218. /* control info callback */
  219. static int snd_line6_control_playback_info(struct snd_kcontrol *kcontrol,
  220. struct snd_ctl_elem_info *uinfo)
  221. {
  222. uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
  223. uinfo->count = 2;
  224. uinfo->value.integer.min = 0;
  225. uinfo->value.integer.max = 256;
  226. return 0;
  227. }
  228. /* control get callback */
  229. static int snd_line6_control_playback_get(struct snd_kcontrol *kcontrol,
  230. struct snd_ctl_elem_value *ucontrol)
  231. {
  232. int i;
  233. struct snd_line6_pcm *line6pcm = snd_kcontrol_chip(kcontrol);
  234. for (i = 2; i--;)
  235. ucontrol->value.integer.value[i] = line6pcm->volume_playback[i];
  236. return 0;
  237. }
  238. /* control put callback */
  239. static int snd_line6_control_playback_put(struct snd_kcontrol *kcontrol,
  240. struct snd_ctl_elem_value *ucontrol)
  241. {
  242. int i, changed = 0;
  243. struct snd_line6_pcm *line6pcm = snd_kcontrol_chip(kcontrol);
  244. for (i = 2; i--;)
  245. if (line6pcm->volume_playback[i] !=
  246. ucontrol->value.integer.value[i]) {
  247. line6pcm->volume_playback[i] =
  248. ucontrol->value.integer.value[i];
  249. changed = 1;
  250. }
  251. return changed;
  252. }
  253. /* control definition */
  254. static struct snd_kcontrol_new line6_controls[] = {
  255. {
  256. .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
  257. .name = "PCM Playback Volume",
  258. .info = snd_line6_control_playback_info,
  259. .get = snd_line6_control_playback_get,
  260. .put = snd_line6_control_playback_put
  261. },
  262. {
  263. .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
  264. .name = "Impulse Response Volume",
  265. .info = snd_line6_impulse_volume_info,
  266. .get = snd_line6_impulse_volume_get,
  267. .put = snd_line6_impulse_volume_put
  268. },
  269. {
  270. .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
  271. .name = "Impulse Response Period",
  272. .info = snd_line6_impulse_period_info,
  273. .get = snd_line6_impulse_period_get,
  274. .put = snd_line6_impulse_period_put
  275. },
  276. };
  277. /*
  278. Cleanup the PCM device.
  279. */
  280. static void line6_cleanup_pcm(struct snd_pcm *pcm)
  281. {
  282. int i;
  283. struct snd_line6_pcm *line6pcm = snd_pcm_chip(pcm);
  284. for (i = LINE6_ISO_BUFFERS; i--;) {
  285. if (line6pcm->urb_audio_out[i]) {
  286. usb_kill_urb(line6pcm->urb_audio_out[i]);
  287. usb_free_urb(line6pcm->urb_audio_out[i]);
  288. }
  289. if (line6pcm->urb_audio_in[i]) {
  290. usb_kill_urb(line6pcm->urb_audio_in[i]);
  291. usb_free_urb(line6pcm->urb_audio_in[i]);
  292. }
  293. }
  294. kfree(line6pcm);
  295. }
  296. /* create a PCM device */
  297. static int snd_line6_new_pcm(struct usb_line6 *line6, struct snd_pcm **pcm_ret)
  298. {
  299. struct snd_pcm *pcm;
  300. int err;
  301. err = snd_pcm_new(line6->card, (char *)line6->properties->name,
  302. 0, 1, 1, pcm_ret);
  303. if (err < 0)
  304. return err;
  305. pcm = *pcm_ret;
  306. strcpy(pcm->name, line6->properties->name);
  307. /* set operators */
  308. snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK,
  309. &snd_line6_playback_ops);
  310. snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_CAPTURE, &snd_line6_capture_ops);
  311. /* pre-allocation of buffers */
  312. snd_pcm_lib_preallocate_pages_for_all(pcm, SNDRV_DMA_TYPE_CONTINUOUS,
  313. snd_dma_continuous_data
  314. (GFP_KERNEL), 64 * 1024,
  315. 128 * 1024);
  316. return 0;
  317. }
  318. /*
  319. Stop substream if still running.
  320. */
  321. static void pcm_disconnect_substream(struct snd_pcm_substream *substream)
  322. {
  323. if (substream->runtime && snd_pcm_running(substream)) {
  324. snd_pcm_stream_lock_irq(substream);
  325. snd_pcm_stop(substream, SNDRV_PCM_STATE_DISCONNECTED);
  326. snd_pcm_stream_unlock_irq(substream);
  327. }
  328. }
  329. /*
  330. Stop PCM stream.
  331. */
  332. void line6_pcm_disconnect(struct snd_line6_pcm *line6pcm)
  333. {
  334. pcm_disconnect_substream(get_substream
  335. (line6pcm, SNDRV_PCM_STREAM_CAPTURE));
  336. pcm_disconnect_substream(get_substream
  337. (line6pcm, SNDRV_PCM_STREAM_PLAYBACK));
  338. line6_unlink_wait_clear_audio_out_urbs(line6pcm);
  339. line6_unlink_wait_clear_audio_in_urbs(line6pcm);
  340. }
  341. EXPORT_SYMBOL_GPL(line6_pcm_disconnect);
  342. /*
  343. Create and register the PCM device and mixer entries.
  344. Create URBs for playback and capture.
  345. */
  346. int line6_init_pcm(struct usb_line6 *line6,
  347. struct line6_pcm_properties *properties)
  348. {
  349. int i, err;
  350. unsigned ep_read = line6->properties->ep_audio_r;
  351. unsigned ep_write = line6->properties->ep_audio_w;
  352. struct snd_pcm *pcm;
  353. struct snd_line6_pcm *line6pcm;
  354. if (!(line6->properties->capabilities & LINE6_CAP_PCM))
  355. return 0; /* skip PCM initialization and report success */
  356. err = snd_line6_new_pcm(line6, &pcm);
  357. if (err < 0)
  358. return err;
  359. line6pcm = kzalloc(sizeof(*line6pcm), GFP_KERNEL);
  360. if (!line6pcm)
  361. return -ENOMEM;
  362. line6pcm->pcm = pcm;
  363. line6pcm->properties = properties;
  364. line6pcm->volume_playback[0] = line6pcm->volume_playback[1] = 255;
  365. line6pcm->volume_monitor = 255;
  366. line6pcm->line6 = line6;
  367. /* Read and write buffers are sized identically, so choose minimum */
  368. line6pcm->max_packet_size = min(
  369. usb_maxpacket(line6->usbdev,
  370. usb_rcvisocpipe(line6->usbdev, ep_read), 0),
  371. usb_maxpacket(line6->usbdev,
  372. usb_sndisocpipe(line6->usbdev, ep_write), 1));
  373. spin_lock_init(&line6pcm->lock_audio_out);
  374. spin_lock_init(&line6pcm->lock_audio_in);
  375. spin_lock_init(&line6pcm->lock_trigger);
  376. line6pcm->impulse_period = LINE6_IMPULSE_DEFAULT_PERIOD;
  377. line6->line6pcm = line6pcm;
  378. pcm->private_data = line6pcm;
  379. pcm->private_free = line6_cleanup_pcm;
  380. err = line6_create_audio_out_urbs(line6pcm);
  381. if (err < 0)
  382. return err;
  383. err = line6_create_audio_in_urbs(line6pcm);
  384. if (err < 0)
  385. return err;
  386. /* mixer: */
  387. for (i = 0; i < ARRAY_SIZE(line6_controls); i++) {
  388. err = snd_ctl_add(line6->card,
  389. snd_ctl_new1(&line6_controls[i], line6pcm));
  390. if (err < 0)
  391. return err;
  392. }
  393. return 0;
  394. }
  395. EXPORT_SYMBOL_GPL(line6_init_pcm);
  396. /* prepare pcm callback */
  397. int snd_line6_prepare(struct snd_pcm_substream *substream)
  398. {
  399. struct snd_line6_pcm *line6pcm = snd_pcm_substream_chip(substream);
  400. switch (substream->stream) {
  401. case SNDRV_PCM_STREAM_PLAYBACK:
  402. if ((line6pcm->flags & LINE6_BITS_PLAYBACK_STREAM) == 0)
  403. line6_unlink_wait_clear_audio_out_urbs(line6pcm);
  404. break;
  405. case SNDRV_PCM_STREAM_CAPTURE:
  406. if ((line6pcm->flags & LINE6_BITS_CAPTURE_STREAM) == 0)
  407. line6_unlink_wait_clear_audio_in_urbs(line6pcm);
  408. break;
  409. default:
  410. MISSING_CASE;
  411. }
  412. if (!test_and_set_bit(LINE6_INDEX_PREPARED, &line6pcm->flags)) {
  413. line6pcm->count_out = 0;
  414. line6pcm->pos_out = 0;
  415. line6pcm->pos_out_done = 0;
  416. line6pcm->bytes_out = 0;
  417. line6pcm->count_in = 0;
  418. line6pcm->pos_in_done = 0;
  419. line6pcm->bytes_in = 0;
  420. }
  421. return 0;
  422. }