2 * Line6 Linux USB driver - 0.8.0
4 * Copyright (C) 2004-2009 Markus Grabner (grabner@icg.tugraz.at)
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.
14 #include <linux/slab.h>
16 #include <sound/core.h>
17 #include <sound/pcm.h>
18 #include <sound/pcm_params.h>
26 Find a free URB and submit it.
28 static int submit_audio_in_urb(struct snd_pcm_substream
*substream
)
32 struct snd_line6_pcm
*line6pcm
= snd_pcm_substream_chip(substream
);
36 spin_lock_irqsave(&line6pcm
->lock_audio_in
, flags
);
38 find_first_zero_bit(&line6pcm
->active_urb_in
, LINE6_ISO_BUFFERS
);
40 if (index
>= LINE6_ISO_BUFFERS
) {
41 spin_unlock_irqrestore(&line6pcm
->lock_audio_in
, flags
);
42 dev_err(s2m(substream
), "no free URB found\n");
46 urb_in
= line6pcm
->urb_audio_in
[index
];
49 for (i
= 0; i
< LINE6_ISO_PACKETS
; ++i
) {
50 struct usb_iso_packet_descriptor
*fin
=
51 &urb_in
->iso_frame_desc
[i
];
52 fin
->offset
= urb_size
;
53 fin
->length
= line6pcm
->max_packet_size
;
54 urb_size
+= line6pcm
->max_packet_size
;
57 urb_in
->transfer_buffer
=
59 index
* LINE6_ISO_PACKETS
* line6pcm
->max_packet_size
;
60 urb_in
->transfer_buffer_length
= urb_size
;
61 urb_in
->context
= substream
;
63 if (usb_submit_urb(urb_in
, GFP_ATOMIC
) == 0)
64 set_bit(index
, &line6pcm
->active_urb_in
);
66 dev_err(s2m(substream
), "URB in #%d submission failed\n",
69 spin_unlock_irqrestore(&line6pcm
->lock_audio_in
, flags
);
74 Submit all currently available capture URBs.
76 static int submit_audio_in_all_urbs(struct snd_pcm_substream
*substream
)
80 for (i
= 0; i
< LINE6_ISO_BUFFERS
; ++i
) {
81 ret
= submit_audio_in_urb(substream
);
90 Unlink all currently active capture URBs.
92 static void unlink_audio_in_urbs(struct snd_line6_pcm
*line6pcm
)
96 for (i
= LINE6_ISO_BUFFERS
; i
--;) {
97 if (test_bit(i
, &line6pcm
->active_urb_in
)) {
98 if (!test_and_set_bit(i
, &line6pcm
->unlink_urb_in
)) {
99 struct urb
*u
= line6pcm
->urb_audio_in
[i
];
107 Wait until unlinking of all currently active capture URBs has been
110 static void wait_clear_audio_in_urbs(struct snd_line6_pcm
*line6pcm
)
118 for (i
= LINE6_ISO_BUFFERS
; i
--;) {
119 if (test_bit(i
, &line6pcm
->active_urb_in
))
124 set_current_state(TASK_UNINTERRUPTIBLE
);
126 } while (--timeout
> 0);
128 snd_printk(KERN_ERR
"timeout: still %d active urbs..\n", alive
);
130 line6pcm
->active_urb_in
= 0;
131 line6pcm
->unlink_urb_in
= 0;
135 Unlink all currently active capture URBs, and wait for finishing.
137 void unlink_wait_clear_audio_in_urbs(struct snd_line6_pcm
*line6pcm
)
139 unlink_audio_in_urbs(line6pcm
);
140 wait_clear_audio_in_urbs(line6pcm
);
144 Callback for completed capture URB.
146 static void audio_in_callback(struct urb
*urb
)
148 int i
, index
, length
= 0, shutdown
= 0;
152 struct snd_pcm_substream
*substream
=
153 (struct snd_pcm_substream
*)urb
->context
;
154 struct snd_line6_pcm
*line6pcm
= snd_pcm_substream_chip(substream
);
155 const int bytes_per_frame
= line6pcm
->properties
->bytes_per_frame
;
156 struct snd_pcm_runtime
*runtime
= substream
->runtime
;
158 /* find index of URB */
159 for (index
= 0; index
< LINE6_ISO_BUFFERS
; ++index
)
160 if (urb
== line6pcm
->urb_audio_in
[index
])
163 #if DO_DUMP_PCM_RECEIVE
164 for (i
= 0; i
< LINE6_ISO_PACKETS
; ++i
) {
165 struct usb_iso_packet_descriptor
*fout
=
166 &urb
->iso_frame_desc
[i
];
167 line6_write_hexdump(line6pcm
->line6
, 'C',
168 urb
->transfer_buffer
+ fout
->offset
,
173 spin_lock_irqsave(&line6pcm
->lock_audio_in
, flags
);
175 for (i
= 0; i
< LINE6_ISO_PACKETS
; ++i
) {
178 struct usb_iso_packet_descriptor
*fin
= &urb
->iso_frame_desc
[i
];
180 if (fin
->status
== -18) {
185 fbuf
= urb
->transfer_buffer
+ fin
->offset
;
186 fsize
= fin
->actual_length
;
190 frames
= fsize
/ bytes_per_frame
;
192 if (line6pcm
->pos_in_done
+ frames
>
193 runtime
->buffer_size
) {
195 The transferred area goes over buffer
196 boundary, copy two separate chunks.
200 runtime
->buffer_size
-
201 line6pcm
->pos_in_done
;
204 memcpy(runtime
->dma_area
+
205 line6pcm
->pos_in_done
*
206 bytes_per_frame
, fbuf
,
207 len
* bytes_per_frame
);
208 memcpy(runtime
->dma_area
,
209 fbuf
+ len
* bytes_per_frame
,
211 len
) * bytes_per_frame
);
213 /* this is somewhat paranoid */
214 dev_err(s2m(substream
),
215 "driver bug: len = %d\n", len
);
218 /* copy single chunk */
219 memcpy(runtime
->dma_area
+
220 line6pcm
->pos_in_done
* bytes_per_frame
,
221 fbuf
, fsize
* bytes_per_frame
);
224 line6pcm
->pos_in_done
+= frames
;
225 if (line6pcm
->pos_in_done
>= runtime
->buffer_size
)
226 line6pcm
->pos_in_done
-= runtime
->buffer_size
;
230 clear_bit(index
, &line6pcm
->active_urb_in
);
232 if (test_bit(index
, &line6pcm
->unlink_urb_in
))
235 spin_unlock_irqrestore(&line6pcm
->lock_audio_in
, flags
);
238 submit_audio_in_urb(substream
);
240 line6pcm
->bytes_in
+= length
;
241 if (line6pcm
->bytes_in
>= line6pcm
->period_in
) {
242 line6pcm
->bytes_in
-= line6pcm
->period_in
;
243 snd_pcm_period_elapsed(substream
);
248 /* open capture callback */
249 static int snd_line6_capture_open(struct snd_pcm_substream
*substream
)
252 struct snd_pcm_runtime
*runtime
= substream
->runtime
;
253 struct snd_line6_pcm
*line6pcm
= snd_pcm_substream_chip(substream
);
255 err
= snd_pcm_hw_constraint_ratdens(runtime
, 0,
256 SNDRV_PCM_HW_PARAM_RATE
,
257 (&line6pcm
->properties
->
262 runtime
->hw
= line6pcm
->properties
->snd_line6_capture_hw
;
266 /* close capture callback */
267 static int snd_line6_capture_close(struct snd_pcm_substream
*substream
)
272 /* hw_params capture callback */
273 static int snd_line6_capture_hw_params(struct snd_pcm_substream
*substream
,
274 struct snd_pcm_hw_params
*hw_params
)
277 struct snd_line6_pcm
*line6pcm
= snd_pcm_substream_chip(substream
);
279 /* -- Florian Demski [FD] */
280 /* don't ask me why, but this fixes the bug on my machine */
281 if (line6pcm
== NULL
) {
282 if (substream
->pcm
== NULL
)
284 if (substream
->pcm
->private_data
== NULL
)
286 substream
->private_data
= substream
->pcm
->private_data
;
287 line6pcm
= snd_pcm_substream_chip(substream
);
291 ret
= snd_pcm_lib_malloc_pages(substream
,
292 params_buffer_bytes(hw_params
));
296 line6pcm
->period_in
= params_period_bytes(hw_params
);
297 line6pcm
->buffer_in
=
298 kmalloc(LINE6_ISO_BUFFERS
* LINE6_ISO_PACKETS
*
299 LINE6_ISO_PACKET_SIZE_MAX
, GFP_KERNEL
);
301 if (!line6pcm
->buffer_in
) {
302 dev_err(s2m(substream
), "cannot malloc buffer_in\n");
309 /* hw_free capture callback */
310 static int snd_line6_capture_hw_free(struct snd_pcm_substream
*substream
)
312 struct snd_line6_pcm
*line6pcm
= snd_pcm_substream_chip(substream
);
313 unlink_wait_clear_audio_in_urbs(line6pcm
);
315 kfree(line6pcm
->buffer_in
);
316 line6pcm
->buffer_in
= NULL
;
318 return snd_pcm_lib_free_pages(substream
);
321 /* trigger callback */
322 int snd_line6_capture_trigger(struct snd_pcm_substream
*substream
, int cmd
)
324 struct snd_line6_pcm
*line6pcm
= snd_pcm_substream_chip(substream
);
326 line6pcm
->count_in
= 0;
329 case SNDRV_PCM_TRIGGER_START
:
330 if (!test_and_set_bit(BIT_RUNNING_CAPTURE
, &line6pcm
->flags
)) {
331 err
= submit_audio_in_all_urbs(substream
);
334 clear_bit(BIT_RUNNING_CAPTURE
,
342 case SNDRV_PCM_TRIGGER_STOP
:
343 if (test_and_clear_bit(BIT_RUNNING_CAPTURE
, &line6pcm
->flags
))
344 unlink_audio_in_urbs(line6pcm
);
355 /* capture pointer callback */
356 static snd_pcm_uframes_t
357 snd_line6_capture_pointer(struct snd_pcm_substream
*substream
)
359 struct snd_line6_pcm
*line6pcm
= snd_pcm_substream_chip(substream
);
360 return line6pcm
->pos_in_done
;
363 /* capture operators */
364 struct snd_pcm_ops snd_line6_capture_ops
= {
365 .open
= snd_line6_capture_open
,
366 .close
= snd_line6_capture_close
,
367 .ioctl
= snd_pcm_lib_ioctl
,
368 .hw_params
= snd_line6_capture_hw_params
,
369 .hw_free
= snd_line6_capture_hw_free
,
370 .prepare
= snd_line6_prepare
,
371 .trigger
= snd_line6_trigger
,
372 .pointer
= snd_line6_capture_pointer
,
375 int create_audio_in_urbs(struct snd_line6_pcm
*line6pcm
)
379 /* create audio URBs and fill in constant values: */
380 for (i
= 0; i
< LINE6_ISO_BUFFERS
; ++i
) {
383 /* URB for audio in: */
384 urb
= line6pcm
->urb_audio_in
[i
] =
385 usb_alloc_urb(LINE6_ISO_PACKETS
, GFP_KERNEL
);
388 dev_err(line6pcm
->line6
->ifcdev
, "Out of memory\n");
392 urb
->dev
= line6pcm
->line6
->usbdev
;
394 usb_rcvisocpipe(line6pcm
->line6
->usbdev
,
396 ep_audio_read
& USB_ENDPOINT_NUMBER_MASK
);
397 urb
->transfer_flags
= URB_ISO_ASAP
;
398 urb
->start_frame
= -1;
399 urb
->number_of_packets
= LINE6_ISO_PACKETS
;
400 urb
->interval
= LINE6_ISO_INTERVAL
;
401 urb
->error_count
= 0;
402 urb
->complete
= audio_in_callback
;