xref: /openbmc/linux/sound/usb/line6/playback.c (revision 6cbbfe1c)
1 /*
2  * Line 6 Linux USB driver
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 
12 #include <linux/slab.h>
13 #include <sound/core.h>
14 #include <sound/pcm.h>
15 #include <sound/pcm_params.h>
16 
17 #include "capture.h"
18 #include "driver.h"
19 #include "pcm.h"
20 #include "playback.h"
21 
22 /*
23 	Software stereo volume control.
24 */
25 static void change_volume(struct urb *urb_out, int volume[],
26 			  int bytes_per_frame)
27 {
28 	int chn = 0;
29 
30 	if (volume[0] == 256 && volume[1] == 256)
31 		return;		/* maximum volume - no change */
32 
33 	if (bytes_per_frame == 4) {
34 		short *p, *buf_end;
35 
36 		p = (short *)urb_out->transfer_buffer;
37 		buf_end = p + urb_out->transfer_buffer_length / sizeof(*p);
38 
39 		for (; p < buf_end; ++p) {
40 			int val = (*p * volume[chn & 1]) >> 8;
41 			*p = clamp(val, 0x7fff, -0x8000);
42 			++chn;
43 		}
44 	} else if (bytes_per_frame == 6) {
45 		unsigned char *p, *buf_end;
46 
47 		p = (unsigned char *)urb_out->transfer_buffer;
48 		buf_end = p + urb_out->transfer_buffer_length;
49 
50 		for (; p < buf_end; p += 3) {
51 			int val;
52 
53 			val = p[0] + (p[1] << 8) + ((signed char)p[2] << 16);
54 			val = (val * volume[chn & 1]) >> 8;
55 			val = clamp(val, 0x7fffff, -0x800000);
56 			p[0] = val;
57 			p[1] = val >> 8;
58 			p[2] = val >> 16;
59 			++chn;
60 		}
61 	}
62 }
63 
64 /*
65 	Create signal for impulse response test.
66 */
67 static void create_impulse_test_signal(struct snd_line6_pcm *line6pcm,
68 				       struct urb *urb_out, int bytes_per_frame)
69 {
70 	int frames = urb_out->transfer_buffer_length / bytes_per_frame;
71 
72 	if (bytes_per_frame == 4) {
73 		int i;
74 		short *pi = (short *)line6pcm->prev_fbuf;
75 		short *po = (short *)urb_out->transfer_buffer;
76 
77 		for (i = 0; i < frames; ++i) {
78 			po[0] = pi[0];
79 			po[1] = 0;
80 			pi += 2;
81 			po += 2;
82 		}
83 	} else if (bytes_per_frame == 6) {
84 		int i, j;
85 		unsigned char *pi = line6pcm->prev_fbuf;
86 		unsigned char *po = urb_out->transfer_buffer;
87 
88 		for (i = 0; i < frames; ++i) {
89 			for (j = 0; j < bytes_per_frame / 2; ++j)
90 				po[j] = pi[j];
91 
92 			for (; j < bytes_per_frame; ++j)
93 				po[j] = 0;
94 
95 			pi += bytes_per_frame;
96 			po += bytes_per_frame;
97 		}
98 	}
99 	if (--line6pcm->impulse_count <= 0) {
100 		((unsigned char *)(urb_out->transfer_buffer))[bytes_per_frame -
101 							      1] =
102 		    line6pcm->impulse_volume;
103 		line6pcm->impulse_count = line6pcm->impulse_period;
104 	}
105 }
106 
107 /*
108 	Add signal to buffer for software monitoring.
109 */
110 static void add_monitor_signal(struct urb *urb_out, unsigned char *signal,
111 			       int volume, int bytes_per_frame)
112 {
113 	if (volume == 0)
114 		return;		/* zero volume - no change */
115 
116 	if (bytes_per_frame == 4) {
117 		short *pi, *po, *buf_end;
118 
119 		pi = (short *)signal;
120 		po = (short *)urb_out->transfer_buffer;
121 		buf_end = po + urb_out->transfer_buffer_length / sizeof(*po);
122 
123 		for (; po < buf_end; ++pi, ++po) {
124 			int val = *po + ((*pi * volume) >> 8);
125 			*po = clamp(val, 0x7fff, -0x8000);
126 		}
127 	}
128 
129 	/*
130 	   We don't need to handle devices with 6 bytes per frame here
131 	   since they all support hardware monitoring.
132 	 */
133 }
134 
135 /*
136 	Find a free URB, prepare audio data, and submit URB.
137 	must be called in line6pcm->out.lock context
138 */
139 static int submit_audio_out_urb(struct snd_line6_pcm *line6pcm)
140 {
141 	int index;
142 	int i, urb_size, urb_frames;
143 	int ret;
144 	const int bytes_per_frame = line6pcm->properties->bytes_per_frame;
145 	const int frame_increment =
146 	    line6pcm->properties->snd_line6_rates.rats[0].num_min;
147 	const int frame_factor =
148 	    line6pcm->properties->snd_line6_rates.rats[0].den *
149 	    (USB_INTERVALS_PER_SECOND / LINE6_ISO_INTERVAL);
150 	struct urb *urb_out;
151 
152 	index =
153 	    find_first_zero_bit(&line6pcm->out.active_urbs, LINE6_ISO_BUFFERS);
154 
155 	if (index < 0 || index >= LINE6_ISO_BUFFERS) {
156 		dev_err(line6pcm->line6->ifcdev, "no free URB found\n");
157 		return -EINVAL;
158 	}
159 
160 	urb_out = line6pcm->out.urbs[index];
161 	urb_size = 0;
162 
163 	for (i = 0; i < LINE6_ISO_PACKETS; ++i) {
164 		/* compute frame size for given sampling rate */
165 		int fsize = 0;
166 		struct usb_iso_packet_descriptor *fout =
167 		    &urb_out->iso_frame_desc[i];
168 
169 		fsize = line6pcm->prev_fsize;
170 		if (fsize == 0) {
171 			int n;
172 
173 			line6pcm->out.count += frame_increment;
174 			n = line6pcm->out.count / frame_factor;
175 			line6pcm->out.count -= n * frame_factor;
176 			fsize = n * bytes_per_frame;
177 		}
178 
179 		fout->offset = urb_size;
180 		fout->length = fsize;
181 		urb_size += fsize;
182 	}
183 
184 	if (urb_size == 0) {
185 		/* can't determine URB size */
186 		dev_err(line6pcm->line6->ifcdev, "driver bug: urb_size = 0\n");
187 		return -EINVAL;
188 	}
189 
190 	urb_frames = urb_size / bytes_per_frame;
191 	urb_out->transfer_buffer =
192 	    line6pcm->out.buffer +
193 	    index * LINE6_ISO_PACKETS * line6pcm->max_packet_size;
194 	urb_out->transfer_buffer_length = urb_size;
195 	urb_out->context = line6pcm;
196 
197 	if (test_bit(LINE6_STREAM_PCM, &line6pcm->out.running) &&
198 	    !test_bit(LINE6_FLAG_PAUSE_PLAYBACK, &line6pcm->flags)) {
199 		struct snd_pcm_runtime *runtime =
200 		    get_substream(line6pcm, SNDRV_PCM_STREAM_PLAYBACK)->runtime;
201 
202 		if (line6pcm->out.pos + urb_frames > runtime->buffer_size) {
203 			/*
204 			   The transferred area goes over buffer boundary,
205 			   copy the data to the temp buffer.
206 			 */
207 			int len;
208 
209 			len = runtime->buffer_size - line6pcm->out.pos;
210 
211 			if (len > 0) {
212 				memcpy(urb_out->transfer_buffer,
213 				       runtime->dma_area +
214 				       line6pcm->out.pos * bytes_per_frame,
215 				       len * bytes_per_frame);
216 				memcpy(urb_out->transfer_buffer +
217 				       len * bytes_per_frame, runtime->dma_area,
218 				       (urb_frames - len) * bytes_per_frame);
219 			} else
220 				dev_err(line6pcm->line6->ifcdev, "driver bug: len = %d\n",
221 					len);
222 		} else {
223 			memcpy(urb_out->transfer_buffer,
224 			       runtime->dma_area +
225 			       line6pcm->out.pos * bytes_per_frame,
226 			       urb_out->transfer_buffer_length);
227 		}
228 
229 		line6pcm->out.pos += urb_frames;
230 		if (line6pcm->out.pos >= runtime->buffer_size)
231 			line6pcm->out.pos -= runtime->buffer_size;
232 
233 		change_volume(urb_out, line6pcm->volume_playback,
234 			      bytes_per_frame);
235 	} else {
236 		memset(urb_out->transfer_buffer, 0,
237 		       urb_out->transfer_buffer_length);
238 	}
239 
240 	spin_lock_nested(&line6pcm->in.lock, SINGLE_DEPTH_NESTING);
241 	if (line6pcm->prev_fbuf) {
242 		if (test_bit(LINE6_STREAM_IMPULSE, &line6pcm->out.running)) {
243 			create_impulse_test_signal(line6pcm, urb_out,
244 						   bytes_per_frame);
245 			if (test_bit(LINE6_STREAM_PCM, &line6pcm->in.running)) {
246 				line6_capture_copy(line6pcm,
247 						   urb_out->transfer_buffer,
248 						   urb_out->
249 						   transfer_buffer_length);
250 				line6_capture_check_period(line6pcm,
251 					urb_out->transfer_buffer_length);
252 			}
253 		} else {
254 			if (!(line6pcm->line6->properties->capabilities & LINE6_CAP_HWMON)
255 			    && line6pcm->out.running && line6pcm->in.running)
256 				add_monitor_signal(urb_out, line6pcm->prev_fbuf,
257 						   line6pcm->volume_monitor,
258 						   bytes_per_frame);
259 		}
260 		line6pcm->prev_fbuf = NULL;
261 		line6pcm->prev_fsize = 0;
262 	}
263 	spin_unlock(&line6pcm->in.lock);
264 
265 	ret = usb_submit_urb(urb_out, GFP_ATOMIC);
266 
267 	if (ret == 0)
268 		set_bit(index, &line6pcm->out.active_urbs);
269 	else
270 		dev_err(line6pcm->line6->ifcdev,
271 			"URB out #%d submission failed (%d)\n", index, ret);
272 
273 	return 0;
274 }
275 
276 /*
277 	Submit all currently available playback URBs.
278 	must be called in line6pcm->out.lock context
279  */
280 int line6_submit_audio_out_all_urbs(struct snd_line6_pcm *line6pcm)
281 {
282 	int ret = 0, i;
283 
284 	for (i = 0; i < LINE6_ISO_BUFFERS; ++i) {
285 		ret = submit_audio_out_urb(line6pcm);
286 		if (ret < 0)
287 			break;
288 	}
289 
290 	return ret;
291 }
292 
293 /*
294 	Callback for completed playback URB.
295 */
296 static void audio_out_callback(struct urb *urb)
297 {
298 	int i, index, length = 0, shutdown = 0;
299 	unsigned long flags;
300 	struct snd_line6_pcm *line6pcm = (struct snd_line6_pcm *)urb->context;
301 	struct snd_pcm_substream *substream =
302 	    get_substream(line6pcm, SNDRV_PCM_STREAM_PLAYBACK);
303 
304 #if USE_CLEAR_BUFFER_WORKAROUND
305 	memset(urb->transfer_buffer, 0, urb->transfer_buffer_length);
306 #endif
307 
308 	line6pcm->out.last_frame = urb->start_frame;
309 
310 	/* find index of URB */
311 	for (index = 0; index < LINE6_ISO_BUFFERS; index++)
312 		if (urb == line6pcm->out.urbs[index])
313 			break;
314 
315 	if (index >= LINE6_ISO_BUFFERS)
316 		return;		/* URB has been unlinked asynchronously */
317 
318 	for (i = 0; i < LINE6_ISO_PACKETS; i++)
319 		length += urb->iso_frame_desc[i].length;
320 
321 	spin_lock_irqsave(&line6pcm->out.lock, flags);
322 
323 	if (test_bit(LINE6_STREAM_PCM, &line6pcm->out.running)) {
324 		struct snd_pcm_runtime *runtime = substream->runtime;
325 
326 		line6pcm->out.pos_done +=
327 		    length / line6pcm->properties->bytes_per_frame;
328 
329 		if (line6pcm->out.pos_done >= runtime->buffer_size)
330 			line6pcm->out.pos_done -= runtime->buffer_size;
331 	}
332 
333 	clear_bit(index, &line6pcm->out.active_urbs);
334 
335 	for (i = 0; i < LINE6_ISO_PACKETS; i++)
336 		if (urb->iso_frame_desc[i].status == -EXDEV) {
337 			shutdown = 1;
338 			break;
339 		}
340 
341 	if (test_and_clear_bit(index, &line6pcm->out.unlink_urbs))
342 		shutdown = 1;
343 
344 	if (!shutdown) {
345 		submit_audio_out_urb(line6pcm);
346 
347 		if (test_bit(LINE6_STREAM_PCM, &line6pcm->out.running)) {
348 			line6pcm->out.bytes += length;
349 			if (line6pcm->out.bytes >= line6pcm->out.period) {
350 				line6pcm->out.bytes %= line6pcm->out.period;
351 				spin_unlock(&line6pcm->out.lock);
352 				snd_pcm_period_elapsed(substream);
353 				spin_lock(&line6pcm->out.lock);
354 			}
355 		}
356 	}
357 	spin_unlock_irqrestore(&line6pcm->out.lock, flags);
358 }
359 
360 /* open playback callback */
361 static int snd_line6_playback_open(struct snd_pcm_substream *substream)
362 {
363 	int err;
364 	struct snd_pcm_runtime *runtime = substream->runtime;
365 	struct snd_line6_pcm *line6pcm = snd_pcm_substream_chip(substream);
366 
367 	err = snd_pcm_hw_constraint_ratdens(runtime, 0, SNDRV_PCM_HW_PARAM_RATE,
368 					    (&line6pcm->
369 					     properties->snd_line6_rates));
370 	if (err < 0)
371 		return err;
372 
373 	runtime->hw = line6pcm->properties->snd_line6_playback_hw;
374 	return 0;
375 }
376 
377 /* close playback callback */
378 static int snd_line6_playback_close(struct snd_pcm_substream *substream)
379 {
380 	return 0;
381 }
382 
383 /* playback operators */
384 struct snd_pcm_ops snd_line6_playback_ops = {
385 	.open = snd_line6_playback_open,
386 	.close = snd_line6_playback_close,
387 	.ioctl = snd_pcm_lib_ioctl,
388 	.hw_params = snd_line6_hw_params,
389 	.hw_free = snd_line6_hw_free,
390 	.prepare = snd_line6_prepare,
391 	.trigger = snd_line6_trigger,
392 	.pointer = snd_line6_pointer,
393 };
394 
395 int line6_create_audio_out_urbs(struct snd_line6_pcm *line6pcm)
396 {
397 	struct usb_line6 *line6 = line6pcm->line6;
398 	int i;
399 
400 	/* create audio URBs and fill in constant values: */
401 	for (i = 0; i < LINE6_ISO_BUFFERS; ++i) {
402 		struct urb *urb;
403 
404 		/* URB for audio out: */
405 		urb = line6pcm->out.urbs[i] =
406 		    usb_alloc_urb(LINE6_ISO_PACKETS, GFP_KERNEL);
407 
408 		if (urb == NULL)
409 			return -ENOMEM;
410 
411 		urb->dev = line6->usbdev;
412 		urb->pipe =
413 		    usb_sndisocpipe(line6->usbdev,
414 				    line6->properties->ep_audio_w &
415 				    USB_ENDPOINT_NUMBER_MASK);
416 		urb->transfer_flags = URB_ISO_ASAP;
417 		urb->start_frame = -1;
418 		urb->number_of_packets = LINE6_ISO_PACKETS;
419 		urb->interval = LINE6_ISO_INTERVAL;
420 		urb->error_count = 0;
421 		urb->complete = audio_out_callback;
422 	}
423 
424 	return 0;
425 }
426