capture.c 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432
  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 <sound/core.h>
  13. #include <sound/pcm.h>
  14. #include <sound/pcm_params.h>
  15. #include "audio.h"
  16. #include "capture.h"
  17. #include "driver.h"
  18. #include "pcm.h"
  19. #include "pod.h"
  20. /*
  21. Find a free URB and submit it.
  22. */
  23. static int submit_audio_in_urb(struct snd_line6_pcm *line6pcm)
  24. {
  25. int index;
  26. unsigned long flags;
  27. int i, urb_size;
  28. int ret;
  29. struct urb *urb_in;
  30. spin_lock_irqsave(&line6pcm->lock_audio_in, flags);
  31. index =
  32. find_first_zero_bit(&line6pcm->active_urb_in, LINE6_ISO_BUFFERS);
  33. if (index < 0 || index >= LINE6_ISO_BUFFERS) {
  34. spin_unlock_irqrestore(&line6pcm->lock_audio_in, flags);
  35. dev_err(line6pcm->line6->ifcdev, "no free URB found\n");
  36. return -EINVAL;
  37. }
  38. urb_in = line6pcm->urb_audio_in[index];
  39. urb_size = 0;
  40. for (i = 0; i < LINE6_ISO_PACKETS; ++i) {
  41. struct usb_iso_packet_descriptor *fin =
  42. &urb_in->iso_frame_desc[i];
  43. fin->offset = urb_size;
  44. fin->length = line6pcm->max_packet_size;
  45. urb_size += line6pcm->max_packet_size;
  46. }
  47. urb_in->transfer_buffer =
  48. line6pcm->buffer_in +
  49. index * LINE6_ISO_PACKETS * line6pcm->max_packet_size;
  50. urb_in->transfer_buffer_length = urb_size;
  51. urb_in->context = line6pcm;
  52. ret = usb_submit_urb(urb_in, GFP_ATOMIC);
  53. if (ret == 0)
  54. set_bit(index, &line6pcm->active_urb_in);
  55. else
  56. dev_err(line6pcm->line6->ifcdev,
  57. "URB in #%d submission failed (%d)\n", index, ret);
  58. spin_unlock_irqrestore(&line6pcm->lock_audio_in, flags);
  59. return 0;
  60. }
  61. /*
  62. Submit all currently available capture URBs.
  63. */
  64. int line6_submit_audio_in_all_urbs(struct snd_line6_pcm *line6pcm)
  65. {
  66. int ret, i;
  67. for (i = 0; i < LINE6_ISO_BUFFERS; ++i) {
  68. ret = submit_audio_in_urb(line6pcm);
  69. if (ret < 0)
  70. return ret;
  71. }
  72. return 0;
  73. }
  74. /*
  75. Unlink all currently active capture URBs.
  76. */
  77. void line6_unlink_audio_in_urbs(struct snd_line6_pcm *line6pcm)
  78. {
  79. unsigned int i;
  80. for (i = LINE6_ISO_BUFFERS; i--;) {
  81. if (test_bit(i, &line6pcm->active_urb_in)) {
  82. if (!test_and_set_bit(i, &line6pcm->unlink_urb_in)) {
  83. struct urb *u = line6pcm->urb_audio_in[i];
  84. usb_unlink_urb(u);
  85. }
  86. }
  87. }
  88. }
  89. /*
  90. Wait until unlinking of all currently active capture URBs has been
  91. finished.
  92. */
  93. void line6_wait_clear_audio_in_urbs(struct snd_line6_pcm *line6pcm)
  94. {
  95. int timeout = HZ;
  96. unsigned int i;
  97. int alive;
  98. do {
  99. alive = 0;
  100. for (i = LINE6_ISO_BUFFERS; i--;) {
  101. if (test_bit(i, &line6pcm->active_urb_in))
  102. alive++;
  103. }
  104. if (!alive)
  105. break;
  106. set_current_state(TASK_UNINTERRUPTIBLE);
  107. schedule_timeout(1);
  108. } while (--timeout > 0);
  109. if (alive)
  110. snd_printk(KERN_ERR "timeout: still %d active urbs..\n", alive);
  111. }
  112. /*
  113. Unlink all currently active capture URBs, and wait for finishing.
  114. */
  115. void line6_unlink_wait_clear_audio_in_urbs(struct snd_line6_pcm *line6pcm)
  116. {
  117. line6_unlink_audio_in_urbs(line6pcm);
  118. line6_wait_clear_audio_in_urbs(line6pcm);
  119. }
  120. /*
  121. Copy data into ALSA capture buffer.
  122. */
  123. void line6_capture_copy(struct snd_line6_pcm *line6pcm, char *fbuf, int fsize)
  124. {
  125. struct snd_pcm_substream *substream =
  126. get_substream(line6pcm, SNDRV_PCM_STREAM_CAPTURE);
  127. struct snd_pcm_runtime *runtime = substream->runtime;
  128. const int bytes_per_frame = line6pcm->properties->bytes_per_frame;
  129. int frames = fsize / bytes_per_frame;
  130. if (runtime == NULL)
  131. return;
  132. if (line6pcm->pos_in_done + frames > runtime->buffer_size) {
  133. /*
  134. The transferred area goes over buffer boundary,
  135. copy two separate chunks.
  136. */
  137. int len;
  138. len = runtime->buffer_size - line6pcm->pos_in_done;
  139. if (len > 0) {
  140. memcpy(runtime->dma_area +
  141. line6pcm->pos_in_done * bytes_per_frame, fbuf,
  142. len * bytes_per_frame);
  143. memcpy(runtime->dma_area, fbuf + len * bytes_per_frame,
  144. (frames - len) * bytes_per_frame);
  145. } else {
  146. /* this is somewhat paranoid */
  147. dev_err(line6pcm->line6->ifcdev,
  148. "driver bug: len = %d\n", len);
  149. }
  150. } else {
  151. /* copy single chunk */
  152. memcpy(runtime->dma_area +
  153. line6pcm->pos_in_done * bytes_per_frame, fbuf, fsize);
  154. }
  155. line6pcm->pos_in_done += frames;
  156. if (line6pcm->pos_in_done >= runtime->buffer_size)
  157. line6pcm->pos_in_done -= runtime->buffer_size;
  158. }
  159. void line6_capture_check_period(struct snd_line6_pcm *line6pcm, int length)
  160. {
  161. struct snd_pcm_substream *substream =
  162. get_substream(line6pcm, SNDRV_PCM_STREAM_CAPTURE);
  163. line6pcm->bytes_in += length;
  164. if (line6pcm->bytes_in >= line6pcm->period_in) {
  165. line6pcm->bytes_in %= line6pcm->period_in;
  166. snd_pcm_period_elapsed(substream);
  167. }
  168. }
  169. void line6_free_capture_buffer(struct snd_line6_pcm *line6pcm)
  170. {
  171. kfree(line6pcm->buffer_in);
  172. line6pcm->buffer_in = NULL;
  173. }
  174. /*
  175. * Callback for completed capture URB.
  176. */
  177. static void audio_in_callback(struct urb *urb)
  178. {
  179. int i, index, length = 0, shutdown = 0;
  180. unsigned long flags;
  181. struct snd_line6_pcm *line6pcm = (struct snd_line6_pcm *)urb->context;
  182. line6pcm->last_frame_in = urb->start_frame;
  183. /* find index of URB */
  184. for (index = 0; index < LINE6_ISO_BUFFERS; ++index)
  185. if (urb == line6pcm->urb_audio_in[index])
  186. break;
  187. spin_lock_irqsave(&line6pcm->lock_audio_in, flags);
  188. for (i = 0; i < LINE6_ISO_PACKETS; ++i) {
  189. char *fbuf;
  190. int fsize;
  191. struct usb_iso_packet_descriptor *fin = &urb->iso_frame_desc[i];
  192. if (fin->status == -EXDEV) {
  193. shutdown = 1;
  194. break;
  195. }
  196. fbuf = urb->transfer_buffer + fin->offset;
  197. fsize = fin->actual_length;
  198. if (fsize > line6pcm->max_packet_size) {
  199. dev_err(line6pcm->line6->ifcdev,
  200. "driver and/or device bug: packet too large (%d > %d)\n",
  201. fsize, line6pcm->max_packet_size);
  202. }
  203. length += fsize;
  204. /* the following assumes LINE6_ISO_PACKETS == 1: */
  205. line6pcm->prev_fbuf = fbuf;
  206. line6pcm->prev_fsize = fsize;
  207. #ifdef CONFIG_LINE6_USB_IMPULSE_RESPONSE
  208. if (!(line6pcm->flags & LINE6_BITS_PCM_IMPULSE))
  209. #endif
  210. if (test_bit(LINE6_INDEX_PCM_ALSA_CAPTURE_STREAM,
  211. &line6pcm->flags) && (fsize > 0))
  212. line6_capture_copy(line6pcm, fbuf, fsize);
  213. }
  214. clear_bit(index, &line6pcm->active_urb_in);
  215. if (test_and_clear_bit(index, &line6pcm->unlink_urb_in))
  216. shutdown = 1;
  217. spin_unlock_irqrestore(&line6pcm->lock_audio_in, flags);
  218. if (!shutdown) {
  219. submit_audio_in_urb(line6pcm);
  220. #ifdef CONFIG_LINE6_USB_IMPULSE_RESPONSE
  221. if (!(line6pcm->flags & LINE6_BITS_PCM_IMPULSE))
  222. #endif
  223. if (test_bit(LINE6_INDEX_PCM_ALSA_CAPTURE_STREAM,
  224. &line6pcm->flags))
  225. line6_capture_check_period(line6pcm, length);
  226. }
  227. }
  228. /* open capture callback */
  229. static int snd_line6_capture_open(struct snd_pcm_substream *substream)
  230. {
  231. int err;
  232. struct snd_pcm_runtime *runtime = substream->runtime;
  233. struct snd_line6_pcm *line6pcm = snd_pcm_substream_chip(substream);
  234. err = snd_pcm_hw_constraint_ratdens(runtime, 0,
  235. SNDRV_PCM_HW_PARAM_RATE,
  236. (&line6pcm->
  237. properties->snd_line6_rates));
  238. if (err < 0)
  239. return err;
  240. runtime->hw = line6pcm->properties->snd_line6_capture_hw;
  241. return 0;
  242. }
  243. /* close capture callback */
  244. static int snd_line6_capture_close(struct snd_pcm_substream *substream)
  245. {
  246. return 0;
  247. }
  248. /* hw_params capture callback */
  249. static int snd_line6_capture_hw_params(struct snd_pcm_substream *substream,
  250. struct snd_pcm_hw_params *hw_params)
  251. {
  252. int ret;
  253. struct snd_line6_pcm *line6pcm = snd_pcm_substream_chip(substream);
  254. /* -- Florian Demski [FD] */
  255. /* don't ask me why, but this fixes the bug on my machine */
  256. if (line6pcm == NULL) {
  257. if (substream->pcm == NULL)
  258. return -ENOMEM;
  259. if (substream->pcm->private_data == NULL)
  260. return -ENOMEM;
  261. substream->private_data = substream->pcm->private_data;
  262. line6pcm = snd_pcm_substream_chip(substream);
  263. }
  264. /* -- [FD] end */
  265. ret = line6_pcm_acquire(line6pcm, LINE6_BIT_PCM_ALSA_CAPTURE_BUFFER);
  266. if (ret < 0)
  267. return ret;
  268. ret = snd_pcm_lib_malloc_pages(substream,
  269. params_buffer_bytes(hw_params));
  270. if (ret < 0) {
  271. line6_pcm_release(line6pcm, LINE6_BIT_PCM_ALSA_CAPTURE_BUFFER);
  272. return ret;
  273. }
  274. line6pcm->period_in = params_period_bytes(hw_params);
  275. return 0;
  276. }
  277. /* hw_free capture callback */
  278. static int snd_line6_capture_hw_free(struct snd_pcm_substream *substream)
  279. {
  280. struct snd_line6_pcm *line6pcm = snd_pcm_substream_chip(substream);
  281. line6_pcm_release(line6pcm, LINE6_BIT_PCM_ALSA_CAPTURE_BUFFER);
  282. return snd_pcm_lib_free_pages(substream);
  283. }
  284. /* trigger callback */
  285. int snd_line6_capture_trigger(struct snd_line6_pcm *line6pcm, int cmd)
  286. {
  287. int err;
  288. switch (cmd) {
  289. case SNDRV_PCM_TRIGGER_START:
  290. #ifdef CONFIG_PM
  291. case SNDRV_PCM_TRIGGER_RESUME:
  292. #endif
  293. err = line6_pcm_acquire(line6pcm,
  294. LINE6_BIT_PCM_ALSA_CAPTURE_STREAM);
  295. if (err < 0)
  296. return err;
  297. break;
  298. case SNDRV_PCM_TRIGGER_STOP:
  299. #ifdef CONFIG_PM
  300. case SNDRV_PCM_TRIGGER_SUSPEND:
  301. #endif
  302. err = line6_pcm_release(line6pcm,
  303. LINE6_BIT_PCM_ALSA_CAPTURE_STREAM);
  304. if (err < 0)
  305. return err;
  306. break;
  307. default:
  308. return -EINVAL;
  309. }
  310. return 0;
  311. }
  312. /* capture pointer callback */
  313. static snd_pcm_uframes_t
  314. snd_line6_capture_pointer(struct snd_pcm_substream *substream)
  315. {
  316. struct snd_line6_pcm *line6pcm = snd_pcm_substream_chip(substream);
  317. return line6pcm->pos_in_done;
  318. }
  319. /* capture operators */
  320. struct snd_pcm_ops snd_line6_capture_ops = {
  321. .open = snd_line6_capture_open,
  322. .close = snd_line6_capture_close,
  323. .ioctl = snd_pcm_lib_ioctl,
  324. .hw_params = snd_line6_capture_hw_params,
  325. .hw_free = snd_line6_capture_hw_free,
  326. .prepare = snd_line6_prepare,
  327. .trigger = snd_line6_trigger,
  328. .pointer = snd_line6_capture_pointer,
  329. };
  330. int line6_create_audio_in_urbs(struct snd_line6_pcm *line6pcm)
  331. {
  332. int i;
  333. /* create audio URBs and fill in constant values: */
  334. for (i = 0; i < LINE6_ISO_BUFFERS; ++i) {
  335. struct urb *urb;
  336. /* URB for audio in: */
  337. urb = line6pcm->urb_audio_in[i] =
  338. usb_alloc_urb(LINE6_ISO_PACKETS, GFP_KERNEL);
  339. if (urb == NULL) {
  340. dev_err(line6pcm->line6->ifcdev, "Out of memory\n");
  341. return -ENOMEM;
  342. }
  343. urb->dev = line6pcm->line6->usbdev;
  344. urb->pipe =
  345. usb_rcvisocpipe(line6pcm->line6->usbdev,
  346. line6pcm->ep_audio_read &
  347. USB_ENDPOINT_NUMBER_MASK);
  348. urb->transfer_flags = URB_ISO_ASAP;
  349. urb->start_frame = -1;
  350. urb->number_of_packets = LINE6_ISO_PACKETS;
  351. urb->interval = LINE6_ISO_INTERVAL;
  352. urb->error_count = 0;
  353. urb->complete = audio_in_callback;
  354. }
  355. return 0;
  356. }