1 // SPDX-License-Identifier: GPL-2.0-only
3 * Line 6 Linux USB driver
5 * Copyright (C) 2004-2010 Markus Grabner (grabner@icg.tugraz.at)
8 #include <linux/slab.h>
9 #include <sound/core.h>
10 #include <sound/pcm.h>
11 #include <sound/pcm_params.h>
18 Find a free URB and submit it.
19 must be called in line6pcm->in.lock context
21 static int submit_audio_in_urb(struct snd_line6_pcm
*line6pcm
)
28 index
= find_first_zero_bit(&line6pcm
->in
.active_urbs
,
29 line6pcm
->line6
->iso_buffers
);
31 if (index
< 0 || index
>= line6pcm
->line6
->iso_buffers
) {
32 dev_err(line6pcm
->line6
->ifcdev
, "no free URB found\n");
36 urb_in
= line6pcm
->in
.urbs
[index
];
39 for (i
= 0; i
< LINE6_ISO_PACKETS
; ++i
) {
40 struct usb_iso_packet_descriptor
*fin
=
41 &urb_in
->iso_frame_desc
[i
];
42 fin
->offset
= urb_size
;
43 fin
->length
= line6pcm
->max_packet_size_in
;
44 urb_size
+= line6pcm
->max_packet_size_in
;
47 urb_in
->transfer_buffer
=
49 index
* LINE6_ISO_PACKETS
* line6pcm
->max_packet_size_in
;
50 urb_in
->transfer_buffer_length
= urb_size
;
51 urb_in
->context
= line6pcm
;
53 ret
= usb_submit_urb(urb_in
, GFP_ATOMIC
);
56 set_bit(index
, &line6pcm
->in
.active_urbs
);
58 dev_err(line6pcm
->line6
->ifcdev
,
59 "URB in #%d submission failed (%d)\n", index
, ret
);
65 Submit all currently available capture URBs.
66 must be called in line6pcm->in.lock context
68 int line6_submit_audio_in_all_urbs(struct snd_line6_pcm
*line6pcm
)
72 for (i
= 0; i
< line6pcm
->line6
->iso_buffers
; ++i
) {
73 ret
= submit_audio_in_urb(line6pcm
);
82 Copy data into ALSA capture buffer.
84 void line6_capture_copy(struct snd_line6_pcm
*line6pcm
, char *fbuf
, int fsize
)
86 struct snd_pcm_substream
*substream
=
87 get_substream(line6pcm
, SNDRV_PCM_STREAM_CAPTURE
);
88 struct snd_pcm_runtime
*runtime
= substream
->runtime
;
89 const int bytes_per_frame
=
90 line6pcm
->properties
->bytes_per_channel
*
91 line6pcm
->properties
->capture_hw
.channels_max
;
92 int frames
= fsize
/ bytes_per_frame
;
97 if (line6pcm
->in
.pos_done
+ frames
> runtime
->buffer_size
) {
99 The transferred area goes over buffer boundary,
100 copy two separate chunks.
104 len
= runtime
->buffer_size
- line6pcm
->in
.pos_done
;
107 memcpy(runtime
->dma_area
+
108 line6pcm
->in
.pos_done
* bytes_per_frame
, fbuf
,
109 len
* bytes_per_frame
);
110 memcpy(runtime
->dma_area
, fbuf
+ len
* bytes_per_frame
,
111 (frames
- len
) * bytes_per_frame
);
113 /* this is somewhat paranoid */
114 dev_err(line6pcm
->line6
->ifcdev
,
115 "driver bug: len = %d\n", len
);
118 /* copy single chunk */
119 memcpy(runtime
->dma_area
+
120 line6pcm
->in
.pos_done
* bytes_per_frame
, fbuf
, fsize
);
123 line6pcm
->in
.pos_done
+= frames
;
124 if (line6pcm
->in
.pos_done
>= runtime
->buffer_size
)
125 line6pcm
->in
.pos_done
-= runtime
->buffer_size
;
128 void line6_capture_check_period(struct snd_line6_pcm
*line6pcm
, int length
)
130 struct snd_pcm_substream
*substream
=
131 get_substream(line6pcm
, SNDRV_PCM_STREAM_CAPTURE
);
133 line6pcm
->in
.bytes
+= length
;
134 if (line6pcm
->in
.bytes
>= line6pcm
->in
.period
) {
135 line6pcm
->in
.bytes
%= line6pcm
->in
.period
;
136 spin_unlock(&line6pcm
->in
.lock
);
137 snd_pcm_period_elapsed(substream
);
138 spin_lock(&line6pcm
->in
.lock
);
143 * Callback for completed capture URB.
145 static void audio_in_callback(struct urb
*urb
)
147 int i
, index
, length
= 0, shutdown
= 0;
150 struct snd_line6_pcm
*line6pcm
= (struct snd_line6_pcm
*)urb
->context
;
152 line6pcm
->in
.last_frame
= urb
->start_frame
;
154 /* find index of URB */
155 for (index
= 0; index
< line6pcm
->line6
->iso_buffers
; ++index
)
156 if (urb
== line6pcm
->in
.urbs
[index
])
159 spin_lock_irqsave(&line6pcm
->in
.lock
, flags
);
161 for (i
= 0; i
< LINE6_ISO_PACKETS
; ++i
) {
164 struct usb_iso_packet_descriptor
*fin
= &urb
->iso_frame_desc
[i
];
166 if (fin
->status
== -EXDEV
) {
171 fbuf
= urb
->transfer_buffer
+ fin
->offset
;
172 fsize
= fin
->actual_length
;
174 if (fsize
> line6pcm
->max_packet_size_in
) {
175 dev_err(line6pcm
->line6
->ifcdev
,
176 "driver and/or device bug: packet too large (%d > %d)\n",
177 fsize
, line6pcm
->max_packet_size_in
);
182 BUILD_BUG_ON_MSG(LINE6_ISO_PACKETS
!= 1,
183 "The following code assumes LINE6_ISO_PACKETS == 1");
185 * Also, if iso_buffers != 2, the prev frame is almost random at
187 * This needs to be redesigned. It should be "stable", but we may
188 * experience sync problems on such high-speed configs.
191 line6pcm
->prev_fbuf
= fbuf
;
192 line6pcm
->prev_fsize
= fsize
/
193 (line6pcm
->properties
->bytes_per_channel
*
194 line6pcm
->properties
->capture_hw
.channels_max
);
196 if (!test_bit(LINE6_STREAM_IMPULSE
, &line6pcm
->in
.running
) &&
197 test_bit(LINE6_STREAM_PCM
, &line6pcm
->in
.running
) &&
199 line6_capture_copy(line6pcm
, fbuf
, fsize
);
202 clear_bit(index
, &line6pcm
->in
.active_urbs
);
204 if (test_and_clear_bit(index
, &line6pcm
->in
.unlink_urbs
))
208 submit_audio_in_urb(line6pcm
);
210 if (!test_bit(LINE6_STREAM_IMPULSE
, &line6pcm
->in
.running
) &&
211 test_bit(LINE6_STREAM_PCM
, &line6pcm
->in
.running
))
212 line6_capture_check_period(line6pcm
, length
);
215 spin_unlock_irqrestore(&line6pcm
->in
.lock
, flags
);
218 /* open capture callback */
219 static int snd_line6_capture_open(struct snd_pcm_substream
*substream
)
222 struct snd_pcm_runtime
*runtime
= substream
->runtime
;
223 struct snd_line6_pcm
*line6pcm
= snd_pcm_substream_chip(substream
);
225 err
= snd_pcm_hw_constraint_ratdens(runtime
, 0,
226 SNDRV_PCM_HW_PARAM_RATE
,
227 &line6pcm
->properties
->rates
);
231 line6_pcm_acquire(line6pcm
, LINE6_STREAM_CAPTURE_HELPER
, false);
233 runtime
->hw
= line6pcm
->properties
->capture_hw
;
237 /* close capture callback */
238 static int snd_line6_capture_close(struct snd_pcm_substream
*substream
)
240 struct snd_line6_pcm
*line6pcm
= snd_pcm_substream_chip(substream
);
242 line6_pcm_release(line6pcm
, LINE6_STREAM_CAPTURE_HELPER
);
246 /* capture operators */
247 const struct snd_pcm_ops snd_line6_capture_ops
= {
248 .open
= snd_line6_capture_open
,
249 .close
= snd_line6_capture_close
,
250 .hw_params
= snd_line6_hw_params
,
251 .hw_free
= snd_line6_hw_free
,
252 .prepare
= snd_line6_prepare
,
253 .trigger
= snd_line6_trigger
,
254 .pointer
= snd_line6_pointer
,
257 int line6_create_audio_in_urbs(struct snd_line6_pcm
*line6pcm
)
259 struct usb_line6
*line6
= line6pcm
->line6
;
262 line6pcm
->in
.urbs
= kcalloc(line6
->iso_buffers
, sizeof(struct urb
*),
264 if (line6pcm
->in
.urbs
== NULL
)
267 /* create audio URBs and fill in constant values: */
268 for (i
= 0; i
< line6
->iso_buffers
; ++i
) {
271 /* URB for audio in: */
272 urb
= line6pcm
->in
.urbs
[i
] =
273 usb_alloc_urb(LINE6_ISO_PACKETS
, GFP_KERNEL
);
278 urb
->dev
= line6
->usbdev
;
280 usb_rcvisocpipe(line6
->usbdev
,
281 line6
->properties
->ep_audio_r
&
282 USB_ENDPOINT_NUMBER_MASK
);
283 urb
->transfer_flags
= URB_ISO_ASAP
;
284 urb
->start_frame
= -1;
285 urb
->number_of_packets
= LINE6_ISO_PACKETS
;
286 urb
->interval
= LINE6_ISO_INTERVAL
;
287 urb
->error_count
= 0;
288 urb
->complete
= audio_in_callback
;
289 if (usb_urb_ep_type_check(urb
))