aboutsummaryrefslogtreecommitdiffstats
path: root/sound
diff options
context:
space:
mode:
authorJaroslav Kysela <perex@perex.cz>2010-08-09 08:21:11 -0400
committerJaroslav Kysela <perex@perex.cz>2010-08-09 08:21:11 -0400
commit597603d615d2b19a9e451d8cfac24372856a522d (patch)
treecb7ccddec2ccf274ce3dbb57068f4143b3172716 /sound
parent9fe6206f400646a2322096b56c59891d530e8d51 (diff)
ALSA: introduce the snd-aloop module for the PCM loopback
The snd-aloop module allows redirecting of the PCM playback in the kernel back to the user space using the standard ALSA PCM capture API. The module also allows time synchronization with another timing source and notifications of playback stream parameter changes. Signed-off-by: Jaroslav Kysela <perex@perex.cz>
Diffstat (limited to 'sound')
-rw-r--r--sound/drivers/Kconfig19
-rw-r--r--sound/drivers/Makefile2
-rw-r--r--sound/drivers/aloop.c1055
3 files changed, 1076 insertions, 0 deletions
diff --git a/sound/drivers/Kconfig b/sound/drivers/Kconfig
index 84714a65e5c8..b6ae76285255 100644
--- a/sound/drivers/Kconfig
+++ b/sound/drivers/Kconfig
@@ -74,6 +74,25 @@ config SND_DUMMY
74 To compile this driver as a module, choose M here: the module 74 To compile this driver as a module, choose M here: the module
75 will be called snd-dummy. 75 will be called snd-dummy.
76 76
77config SND_ALOOP
78 tristate "Generic loopback driver (PCM)"
79 select SND_PCM
80 help
81 Say 'Y' or 'M' to include support for the PCM loopback device.
82 This module returns played samples back to the user space using
83 the standard ALSA PCM device. The devices are routed 0->1 and
84 1->0, where first number is the playback PCM device and second
85 number is the capture device. Module creates two PCM devices and
86 configured number of substreams (see the pcm_substreams module
87 parameter).
88
89 The looback device allow time sychronization with an external
90 timing source using the time shift universal control (+-20%
91 of system time).
92
93 To compile this driver as a module, choose M here: the module
94 will be called snd-aloop.
95
77config SND_VIRMIDI 96config SND_VIRMIDI
78 tristate "Virtual MIDI soundcard" 97 tristate "Virtual MIDI soundcard"
79 depends on SND_SEQUENCER 98 depends on SND_SEQUENCER
diff --git a/sound/drivers/Makefile b/sound/drivers/Makefile
index d4a07f9ff2c7..1a8440c8b138 100644
--- a/sound/drivers/Makefile
+++ b/sound/drivers/Makefile
@@ -4,6 +4,7 @@
4# 4#
5 5
6snd-dummy-objs := dummy.o 6snd-dummy-objs := dummy.o
7snd-aloop-objs := aloop.o
7snd-mtpav-objs := mtpav.o 8snd-mtpav-objs := mtpav.o
8snd-mts64-objs := mts64.o 9snd-mts64-objs := mts64.o
9snd-portman2x4-objs := portman2x4.o 10snd-portman2x4-objs := portman2x4.o
@@ -13,6 +14,7 @@ snd-ml403-ac97cr-objs := ml403-ac97cr.o pcm-indirect2.o
13 14
14# Toplevel Module Dependency 15# Toplevel Module Dependency
15obj-$(CONFIG_SND_DUMMY) += snd-dummy.o 16obj-$(CONFIG_SND_DUMMY) += snd-dummy.o
17obj-$(CONFIG_SND_ALOOP) += snd-aloop.o
16obj-$(CONFIG_SND_VIRMIDI) += snd-virmidi.o 18obj-$(CONFIG_SND_VIRMIDI) += snd-virmidi.o
17obj-$(CONFIG_SND_SERIAL_U16550) += snd-serial-u16550.o 19obj-$(CONFIG_SND_SERIAL_U16550) += snd-serial-u16550.o
18obj-$(CONFIG_SND_MTPAV) += snd-mtpav.o 20obj-$(CONFIG_SND_MTPAV) += snd-mtpav.o
diff --git a/sound/drivers/aloop.c b/sound/drivers/aloop.c
new file mode 100644
index 000000000000..3123a15d23f6
--- /dev/null
+++ b/sound/drivers/aloop.c
@@ -0,0 +1,1055 @@
1/*
2 * Loopback soundcard
3 *
4 * Original code:
5 * Copyright (c) by Jaroslav Kysela <perex@perex.cz>
6 *
7 * More accurate positioning and full-duplex support:
8 * Copyright (c) Ahmet İnan <ainan at mathematik.uni-freiburg.de>
9 *
10 * Major (almost complete) rewrite:
11 * Copyright (c) by Takashi Iwai <tiwai@suse.de>
12 *
13 * A next major update in 2010 (separate timers for playback and capture):
14 * Copyright (c) Jaroslav Kysela <perex@perex.cz>
15 *
16 * This program is free software; you can redistribute it and/or modify
17 * it under the terms of the GNU General Public License as published by
18 * the Free Software Foundation; either version 2 of the License, or
19 * (at your option) any later version.
20 *
21 * This program is distributed in the hope that it will be useful,
22 * but WITHOUT ANY WARRANTY; without even the implied warranty of
23 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
24 * GNU General Public License for more details.
25 *
26 * You should have received a copy of the GNU General Public License
27 * along with this program; if not, write to the Free Software
28 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
29 *
30 */
31
32#include <linux/init.h>
33#include <linux/jiffies.h>
34#include <linux/slab.h>
35#include <linux/time.h>
36#include <linux/wait.h>
37#include <linux/moduleparam.h>
38#include <linux/platform_device.h>
39#include <sound/core.h>
40#include <sound/control.h>
41#include <sound/pcm.h>
42#include <sound/initval.h>
43
44MODULE_AUTHOR("Jaroslav Kysela <perex@perex.cz>");
45MODULE_DESCRIPTION("A loopback soundcard");
46MODULE_LICENSE("GPL");
47MODULE_SUPPORTED_DEVICE("{{ALSA,Loopback soundcard}}");
48
49#define MAX_PCM_SUBSTREAMS 8
50
51static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX; /* Index 0-MAX */
52static char *id[SNDRV_CARDS] = SNDRV_DEFAULT_STR; /* ID for this card */
53static int enable[SNDRV_CARDS] = {1, [1 ... (SNDRV_CARDS - 1)] = 0};
54static int pcm_substreams[SNDRV_CARDS] = {[0 ... (SNDRV_CARDS - 1)] = 8};
55static int pcm_notify[SNDRV_CARDS];
56
57module_param_array(index, int, NULL, 0444);
58MODULE_PARM_DESC(index, "Index value for loopback soundcard.");
59module_param_array(id, charp, NULL, 0444);
60MODULE_PARM_DESC(id, "ID string for loopback soundcard.");
61module_param_array(enable, bool, NULL, 0444);
62MODULE_PARM_DESC(enable, "Enable this loopback soundcard.");
63module_param_array(pcm_substreams, int, NULL, 0444);
64MODULE_PARM_DESC(pcm_substreams, "PCM substreams # (1-8) for loopback driver.");
65module_param_array(pcm_notify, int, NULL, 0444);
66MODULE_PARM_DESC(pcm_notify, "Break capture when PCM format/rate/channels changes.");
67
68#define NO_PITCH 100000
69
70struct loopback_pcm;
71
72struct loopback_cable {
73 spinlock_t lock;
74 struct loopback_pcm *streams[2];
75 struct snd_pcm_hardware hw;
76 /* flags */
77 unsigned int valid;
78 unsigned int running;
79};
80
81struct loopback_setup {
82 unsigned int notify: 1;
83 unsigned int rate_shift;
84 unsigned int format;
85 unsigned int rate;
86 unsigned int channels;
87 struct snd_ctl_elem_id active_id;
88 struct snd_ctl_elem_id format_id;
89 struct snd_ctl_elem_id rate_id;
90 struct snd_ctl_elem_id channels_id;
91};
92
93struct loopback {
94 struct snd_card *card;
95 struct mutex cable_lock;
96 struct loopback_cable *cables[MAX_PCM_SUBSTREAMS][2];
97 struct snd_pcm *pcm[2];
98 struct loopback_setup setup[MAX_PCM_SUBSTREAMS][2];
99};
100
101struct loopback_pcm {
102 struct loopback *loopback;
103 struct snd_pcm_substream *substream;
104 struct loopback_cable *cable;
105 unsigned int pcm_buffer_size;
106 unsigned int buf_pos; /* position in buffer */
107 unsigned int silent_size;
108 /* PCM parameters */
109 unsigned int pcm_period_size;
110 unsigned int pcm_bps; /* bytes per second */
111 unsigned int pcm_salign; /* bytes per sample * channels */
112 unsigned int pcm_rate_shift; /* rate shift value */
113 /* flags */
114 unsigned int period_update_pending :1;
115 /* timer stuff */
116 unsigned int irq_pos; /* fractional IRQ position */
117 unsigned int period_size_frac;
118 unsigned long last_jiffies;
119 struct timer_list timer;
120};
121
122static struct platform_device *devices[SNDRV_CARDS];
123
124static inline unsigned int byte_pos(struct loopback_pcm *dpcm, unsigned int x)
125{
126 if (dpcm->pcm_rate_shift == NO_PITCH) {
127 x /= HZ;
128 } else {
129 x = div_u64(NO_PITCH * (unsigned long long)x,
130 HZ * (unsigned long long)dpcm->pcm_rate_shift);
131 }
132 return x - (x % dpcm->pcm_salign);
133}
134
135static inline unsigned int frac_pos(struct loopback_pcm *dpcm, unsigned int x)
136{
137 if (dpcm->pcm_rate_shift == NO_PITCH) { /* no pitch */
138 return x * HZ;
139 } else {
140 x = div_u64(dpcm->pcm_rate_shift * (unsigned long long)x * HZ,
141 NO_PITCH);
142 }
143 return x;
144}
145
146static inline struct loopback_setup *get_setup(struct loopback_pcm *dpcm)
147{
148 int device = dpcm->substream->pstr->pcm->device;
149
150 if (dpcm->substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
151 device ^= 1;
152 return &dpcm->loopback->setup[dpcm->substream->number][device];
153}
154
155static inline unsigned int get_notify(struct loopback_pcm *dpcm)
156{
157 return get_setup(dpcm)->notify;
158}
159
160static inline unsigned int get_rate_shift(struct loopback_pcm *dpcm)
161{
162 return get_setup(dpcm)->rate_shift;
163}
164
165static void loopback_timer_start(struct loopback_pcm *dpcm)
166{
167 unsigned long tick;
168 unsigned int rate_shift = get_rate_shift(dpcm);
169
170 if (rate_shift != dpcm->pcm_rate_shift) {
171 dpcm->pcm_rate_shift = rate_shift;
172 dpcm->period_size_frac = frac_pos(dpcm, dpcm->pcm_period_size);
173 }
174 tick = dpcm->period_size_frac - dpcm->irq_pos;
175 tick = (tick + dpcm->pcm_bps - 1) / dpcm->pcm_bps;
176 dpcm->timer.expires = jiffies + tick;
177 add_timer(&dpcm->timer);
178}
179
180static inline void loopback_timer_stop(struct loopback_pcm *dpcm)
181{
182 del_timer(&dpcm->timer);
183}
184
185#define CABLE_VALID_PLAYBACK (1 << SNDRV_PCM_STREAM_PLAYBACK)
186#define CABLE_VALID_CAPTURE (1 << SNDRV_PCM_STREAM_CAPTURE)
187#define CABLE_VALID_BOTH (CABLE_VALID_PLAYBACK|CABLE_VALID_CAPTURE)
188
189static int loopback_check_format(struct loopback_cable *cable, int stream)
190{
191 struct snd_pcm_runtime *runtime;
192 struct loopback_setup *setup;
193 struct snd_card *card;
194 int check;
195
196 if (cable->valid != CABLE_VALID_BOTH) {
197 if (stream == SNDRV_PCM_STREAM_PLAYBACK)
198 goto __notify;
199 return 0;
200 }
201 runtime = cable->streams[SNDRV_PCM_STREAM_PLAYBACK]->
202 substream->runtime;
203 check = cable->hw.formats != (1ULL << runtime->format) ||
204 cable->hw.rate_min != runtime->rate ||
205 cable->hw.rate_max != runtime->rate ||
206 cable->hw.channels_min != runtime->channels ||
207 cable->hw.channels_max != runtime->channels;
208 if (!check)
209 return 0;
210 if (stream == SNDRV_PCM_STREAM_CAPTURE) {
211 return -EIO;
212 } else {
213 snd_pcm_stop(cable->streams[SNDRV_PCM_STREAM_CAPTURE]->
214 substream, SNDRV_PCM_STATE_DRAINING);
215 __notify:
216 runtime = cable->streams[SNDRV_PCM_STREAM_PLAYBACK]->
217 substream->runtime;
218 setup = get_setup(cable->streams[SNDRV_PCM_STREAM_PLAYBACK]);
219 card = cable->streams[SNDRV_PCM_STREAM_PLAYBACK]->loopback->card;
220 if (setup->format != runtime->format) {
221 snd_ctl_notify(card, SNDRV_CTL_EVENT_MASK_VALUE,
222 &setup->format_id);
223 setup->format = runtime->format;
224 }
225 if (setup->rate != runtime->rate) {
226 snd_ctl_notify(card, SNDRV_CTL_EVENT_MASK_VALUE,
227 &setup->rate_id);
228 setup->rate = runtime->rate;
229 }
230 if (setup->channels != runtime->channels) {
231 snd_ctl_notify(card, SNDRV_CTL_EVENT_MASK_VALUE,
232 &setup->channels_id);
233 setup->channels = runtime->channels;
234 }
235 }
236 return 0;
237}
238
239static void loopback_active_notify(struct loopback_pcm *dpcm)
240{
241 snd_ctl_notify(dpcm->loopback->card,
242 SNDRV_CTL_EVENT_MASK_VALUE,
243 &get_setup(dpcm)->active_id);
244}
245
246static int loopback_trigger(struct snd_pcm_substream *substream, int cmd)
247{
248 struct snd_pcm_runtime *runtime = substream->runtime;
249 struct loopback_pcm *dpcm = runtime->private_data;
250 struct loopback_cable *cable = dpcm->cable;
251 int err;
252
253 switch (cmd) {
254 case SNDRV_PCM_TRIGGER_START:
255 err = loopback_check_format(cable, substream->stream);
256 if (err < 0)
257 return err;
258 dpcm->last_jiffies = jiffies;
259 dpcm->pcm_rate_shift = 0;
260 loopback_timer_start(dpcm);
261 cable->running |= (1 << substream->stream);
262 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
263 loopback_active_notify(dpcm);
264 break;
265 case SNDRV_PCM_TRIGGER_STOP:
266 cable->running &= ~(1 << substream->stream);
267 loopback_timer_stop(dpcm);
268 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
269 loopback_active_notify(dpcm);
270 break;
271 default:
272 return -EINVAL;
273 }
274 return 0;
275}
276
277static int loopback_prepare(struct snd_pcm_substream *substream)
278{
279 struct snd_pcm_runtime *runtime = substream->runtime;
280 struct loopback_pcm *dpcm = runtime->private_data;
281 struct loopback_cable *cable = dpcm->cable;
282 unsigned int bps, salign;
283
284 salign = (snd_pcm_format_width(runtime->format) *
285 runtime->channels) / 8;
286 bps = salign * runtime->rate;
287 if (bps <= 0 || salign <= 0)
288 return -EINVAL;
289
290 dpcm->buf_pos = 0;
291 dpcm->pcm_buffer_size = frames_to_bytes(runtime, runtime->buffer_size);
292 if (substream->stream == SNDRV_PCM_STREAM_CAPTURE) {
293 /* clear capture buffer */
294 dpcm->silent_size = dpcm->pcm_buffer_size;
295 snd_pcm_format_set_silence(runtime->format, runtime->dma_area,
296 runtime->buffer_size * runtime->channels);
297 }
298
299 dpcm->irq_pos = 0;
300 dpcm->period_update_pending = 0;
301 dpcm->pcm_bps = bps;
302 dpcm->pcm_salign = salign;
303 dpcm->pcm_period_size = frames_to_bytes(runtime, runtime->period_size);
304
305 mutex_lock(&dpcm->loopback->cable_lock);
306 if (!(cable->valid & ~(1 << substream->stream))) {
307 cable->hw.formats = (1ULL << runtime->format);
308 cable->hw.rate_min = runtime->rate;
309 cable->hw.rate_max = runtime->rate;
310 cable->hw.channels_min = runtime->channels;
311 cable->hw.channels_max = runtime->channels;
312 }
313 cable->valid |= 1 << substream->stream;
314 mutex_unlock(&dpcm->loopback->cable_lock);
315
316 return 0;
317}
318
319static void clear_capture_buf(struct loopback_pcm *dpcm, unsigned int bytes)
320{
321 struct snd_pcm_runtime *runtime = dpcm->substream->runtime;
322 char *dst = runtime->dma_area;
323 unsigned int dst_off = dpcm->buf_pos;
324
325 if (dpcm->silent_size >= dpcm->pcm_buffer_size)
326 return;
327 if (dpcm->silent_size + bytes > dpcm->pcm_buffer_size)
328 bytes = dpcm->pcm_buffer_size - dpcm->silent_size;
329
330 for (;;) {
331 unsigned int size = bytes;
332 if (dst_off + size > dpcm->pcm_buffer_size)
333 size = dpcm->pcm_buffer_size - dst_off;
334 snd_pcm_format_set_silence(runtime->format, dst + dst_off,
335 bytes_to_frames(runtime, size) *
336 runtime->channels);
337 dpcm->silent_size += size;
338 bytes -= size;
339 if (!bytes)
340 break;
341 dst_off = 0;
342 }
343}
344
345static void copy_play_buf(struct loopback_pcm *play,
346 struct loopback_pcm *capt,
347 unsigned int bytes)
348{
349 struct snd_pcm_runtime *runtime = play->substream->runtime;
350 char *src = play->substream->runtime->dma_area;
351 char *dst = capt->substream->runtime->dma_area;
352 unsigned int src_off = play->buf_pos;
353 unsigned int dst_off = capt->buf_pos;
354 unsigned int clear_bytes = 0;
355
356 /* check if playback is draining, trim the capture copy size
357 * when our pointer is at the end of playback ring buffer */
358 if (runtime->status->state == SNDRV_PCM_STATE_DRAINING &&
359 snd_pcm_playback_hw_avail(runtime) < runtime->buffer_size) {
360 snd_pcm_uframes_t appl_ptr, appl_ptr1, diff;
361 appl_ptr = appl_ptr1 = runtime->control->appl_ptr;
362 appl_ptr1 -= appl_ptr1 % runtime->buffer_size;
363 appl_ptr1 += play->buf_pos / play->pcm_salign;
364 if (appl_ptr < appl_ptr1)
365 appl_ptr1 -= runtime->buffer_size;
366 diff = (appl_ptr - appl_ptr1) * play->pcm_salign;
367 if (diff < bytes) {
368 clear_bytes = bytes - diff;
369 bytes = diff;
370 }
371 }
372
373 for (;;) {
374 unsigned int size = bytes;
375 if (src_off + size > play->pcm_buffer_size)
376 size = play->pcm_buffer_size - src_off;
377 if (dst_off + size > capt->pcm_buffer_size)
378 size = capt->pcm_buffer_size - dst_off;
379 memcpy(dst + dst_off, src + src_off, size);
380 capt->silent_size = 0;
381 bytes -= size;
382 if (!bytes)
383 break;
384 src_off = (src_off + size) % play->pcm_buffer_size;
385 dst_off = (dst_off + size) % capt->pcm_buffer_size;
386 }
387
388 if (clear_bytes > 0)
389 clear_capture_buf(capt, clear_bytes);
390}
391
392#define BYTEPOS_UPDATE_POSONLY 0
393#define BYTEPOS_UPDATE_CLEAR 1
394#define BYTEPOS_UPDATE_COPY 2
395
396static void loopback_bytepos_update(struct loopback_pcm *dpcm,
397 unsigned int delta,
398 unsigned int cmd)
399{
400 unsigned int count;
401 unsigned long last_pos;
402
403 last_pos = byte_pos(dpcm, dpcm->irq_pos);
404 dpcm->irq_pos += delta * dpcm->pcm_bps;
405 count = byte_pos(dpcm, dpcm->irq_pos) - last_pos;
406 if (!count)
407 return;
408 if (cmd == BYTEPOS_UPDATE_CLEAR)
409 clear_capture_buf(dpcm, count);
410 else if (cmd == BYTEPOS_UPDATE_COPY)
411 copy_play_buf(dpcm->cable->streams[SNDRV_PCM_STREAM_PLAYBACK],
412 dpcm->cable->streams[SNDRV_PCM_STREAM_CAPTURE],
413 count);
414 dpcm->buf_pos += count;
415 dpcm->buf_pos %= dpcm->pcm_buffer_size;
416 if (dpcm->irq_pos >= dpcm->period_size_frac) {
417 dpcm->irq_pos %= dpcm->period_size_frac;
418 dpcm->period_update_pending = 1;
419 }
420}
421
422static void loopback_pos_update(struct loopback_cable *cable)
423{
424 struct loopback_pcm *dpcm_play =
425 cable->streams[SNDRV_PCM_STREAM_PLAYBACK];
426 struct loopback_pcm *dpcm_capt =
427 cable->streams[SNDRV_PCM_STREAM_CAPTURE];
428 unsigned long delta_play = 0, delta_capt = 0;
429
430 spin_lock(&cable->lock);
431 if (cable->running & (1 << SNDRV_PCM_STREAM_PLAYBACK)) {
432 delta_play = jiffies - dpcm_play->last_jiffies;
433 dpcm_play->last_jiffies += delta_play;
434 }
435
436 if (cable->running & (1 << SNDRV_PCM_STREAM_CAPTURE)) {
437 delta_capt = jiffies - dpcm_capt->last_jiffies;
438 dpcm_capt->last_jiffies += delta_capt;
439 }
440
441 if (delta_play == 0 && delta_capt == 0) {
442 spin_unlock(&cable->lock);
443 return;
444 }
445
446 if (delta_play > delta_capt) {
447 loopback_bytepos_update(dpcm_play, delta_play - delta_capt,
448 BYTEPOS_UPDATE_POSONLY);
449 delta_play = delta_capt;
450 } else if (delta_play < delta_capt) {
451 loopback_bytepos_update(dpcm_capt, delta_capt - delta_play,
452 BYTEPOS_UPDATE_CLEAR);
453 delta_capt = delta_play;
454 }
455
456 if (delta_play == 0 && delta_capt == 0) {
457 spin_unlock(&cable->lock);
458 return;
459 }
460 /* note delta_capt == delta_play at this moment */
461 loopback_bytepos_update(dpcm_capt, delta_capt, BYTEPOS_UPDATE_COPY);
462 loopback_bytepos_update(dpcm_play, delta_play, BYTEPOS_UPDATE_POSONLY);
463 spin_unlock(&cable->lock);
464}
465
466static void loopback_timer_function(unsigned long data)
467{
468 struct loopback_pcm *dpcm = (struct loopback_pcm *)data;
469 int stream;
470
471 loopback_pos_update(dpcm->cable);
472 stream = dpcm->substream->stream;
473 if (dpcm->cable->running & (1 << stream))
474 loopback_timer_start(dpcm);
475 if (dpcm->period_update_pending) {
476 dpcm->period_update_pending = 0;
477 if (dpcm->cable->running & (1 << stream))
478 snd_pcm_period_elapsed(dpcm->substream);
479 }
480}
481
482static snd_pcm_uframes_t loopback_pointer(struct snd_pcm_substream *substream)
483{
484 struct snd_pcm_runtime *runtime = substream->runtime;
485 struct loopback_pcm *dpcm = runtime->private_data;
486
487 loopback_pos_update(dpcm->cable);
488 return bytes_to_frames(runtime, dpcm->buf_pos);
489}
490
491static struct snd_pcm_hardware loopback_pcm_hardware =
492{
493 .info = (SNDRV_PCM_INFO_INTERLEAVED | SNDRV_PCM_INFO_MMAP |
494 SNDRV_PCM_INFO_MMAP_VALID),
495 .formats = (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S16_BE |
496 SNDRV_PCM_FMTBIT_S32_LE | SNDRV_PCM_FMTBIT_S32_BE |
497 SNDRV_PCM_FMTBIT_FLOAT_LE | SNDRV_PCM_FMTBIT_FLOAT_BE),
498 .rates = SNDRV_PCM_RATE_CONTINUOUS | SNDRV_PCM_RATE_8000_192000,
499 .rate_min = 8000,
500 .rate_max = 192000,
501 .channels_min = 1,
502 .channels_max = 32,
503 .buffer_bytes_max = 2 * 1024 * 1024,
504 .period_bytes_min = 64,
505 .period_bytes_max = 2 * 1024 * 1024,
506 .periods_min = 1,
507 .periods_max = 1024,
508 .fifo_size = 0,
509};
510
511static void loopback_runtime_free(struct snd_pcm_runtime *runtime)
512{
513 struct loopback_pcm *dpcm = runtime->private_data;
514 kfree(dpcm);
515}
516
517static int loopback_hw_params(struct snd_pcm_substream *substream,
518 struct snd_pcm_hw_params *params)
519{
520 return snd_pcm_lib_malloc_pages(substream, params_buffer_bytes(params));
521}
522
523static int loopback_hw_free(struct snd_pcm_substream *substream)
524{
525 struct snd_pcm_runtime *runtime = substream->runtime;
526 struct loopback_pcm *dpcm = runtime->private_data;
527 struct loopback_cable *cable = dpcm->cable;
528
529 mutex_lock(&dpcm->loopback->cable_lock);
530 cable->valid &= ~(1 << substream->stream);
531 mutex_unlock(&dpcm->loopback->cable_lock);
532 return snd_pcm_lib_free_pages(substream);
533}
534
535static unsigned int get_cable_index(struct snd_pcm_substream *substream)
536{
537 if (!substream->pcm->device)
538 return substream->stream;
539 else
540 return !substream->stream;
541}
542
543static int loopback_open(struct snd_pcm_substream *substream)
544{
545 struct snd_pcm_runtime *runtime = substream->runtime;
546 struct loopback *loopback = substream->private_data;
547 struct loopback_pcm *dpcm;
548 struct loopback_cable *cable;
549 int err = 0;
550 int dev = get_cable_index(substream);
551
552 mutex_lock(&loopback->cable_lock);
553 dpcm = kzalloc(sizeof(*dpcm), GFP_KERNEL);
554 if (!dpcm) {
555 err = -ENOMEM;
556 goto unlock;
557 }
558 dpcm->loopback = loopback;
559 dpcm->substream = substream;
560 setup_timer(&dpcm->timer, loopback_timer_function,
561 (unsigned long)dpcm);
562
563 cable = loopback->cables[substream->number][dev];
564 if (!cable) {
565 cable = kzalloc(sizeof(*cable), GFP_KERNEL);
566 if (!cable) {
567 kfree(dpcm);
568 err = -ENOMEM;
569 goto unlock;
570 }
571 spin_lock_init(&cable->lock);
572 cable->hw = loopback_pcm_hardware;
573 loopback->cables[substream->number][dev] = cable;
574 }
575 dpcm->cable = cable;
576 cable->streams[substream->stream] = dpcm;
577
578 snd_pcm_hw_constraint_integer(runtime, SNDRV_PCM_HW_PARAM_PERIODS);
579
580 runtime->private_data = dpcm;
581 runtime->private_free = loopback_runtime_free;
582 if (get_notify(dpcm) &&
583 substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
584 runtime->hw = loopback_pcm_hardware;
585 } else {
586 runtime->hw = cable->hw;
587 }
588 unlock:
589 mutex_unlock(&loopback->cable_lock);
590 return err;
591}
592
593static int loopback_close(struct snd_pcm_substream *substream)
594{
595 struct loopback *loopback = substream->private_data;
596 struct loopback_pcm *dpcm = substream->runtime->private_data;
597 struct loopback_cable *cable;
598 int dev = get_cable_index(substream);
599
600 loopback_timer_stop(dpcm);
601 mutex_lock(&loopback->cable_lock);
602 cable = loopback->cables[substream->number][dev];
603 if (cable->streams[!substream->stream]) {
604 /* other stream is still alive */
605 cable->streams[substream->stream] = NULL;
606 } else {
607 /* free the cable */
608 loopback->cables[substream->number][dev] = NULL;
609 kfree(cable);
610 }
611 mutex_unlock(&loopback->cable_lock);
612 return 0;
613}
614
615static struct snd_pcm_ops loopback_playback_ops = {
616 .open = loopback_open,
617 .close = loopback_close,
618 .ioctl = snd_pcm_lib_ioctl,
619 .hw_params = loopback_hw_params,
620 .hw_free = loopback_hw_free,
621 .prepare = loopback_prepare,
622 .trigger = loopback_trigger,
623 .pointer = loopback_pointer,
624};
625
626static struct snd_pcm_ops loopback_capture_ops = {
627 .open = loopback_open,
628 .close = loopback_close,
629 .ioctl = snd_pcm_lib_ioctl,
630 .hw_params = loopback_hw_params,
631 .hw_free = loopback_hw_free,
632 .prepare = loopback_prepare,
633 .trigger = loopback_trigger,
634 .pointer = loopback_pointer,
635};
636
637static int __devinit loopback_pcm_new(struct loopback *loopback,
638 int device, int substreams)
639{
640 struct snd_pcm *pcm;
641 int err;
642
643 err = snd_pcm_new(loopback->card, "Loopback PCM", device,
644 substreams, substreams, &pcm);
645 if (err < 0)
646 return err;
647 snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK, &loopback_playback_ops);
648 snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_CAPTURE, &loopback_capture_ops);
649
650 pcm->private_data = loopback;
651 pcm->info_flags = 0;
652 strcpy(pcm->name, "Loopback PCM");
653
654 loopback->pcm[device] = pcm;
655
656 snd_pcm_lib_preallocate_pages_for_all(pcm, SNDRV_DMA_TYPE_CONTINUOUS,
657 snd_dma_continuous_data(GFP_KERNEL),
658 0, 2 * 1024 * 1024);
659 return 0;
660}
661
662static int loopback_rate_shift_info(struct snd_kcontrol *kcontrol,
663 struct snd_ctl_elem_info *uinfo)
664{
665 uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
666 uinfo->count = 1;
667 uinfo->value.integer.min = 80000;
668 uinfo->value.integer.max = 120000;
669 uinfo->value.integer.step = 1;
670 return 0;
671}
672
673static int loopback_rate_shift_get(struct snd_kcontrol *kcontrol,
674 struct snd_ctl_elem_value *ucontrol)
675{
676 struct loopback *loopback = snd_kcontrol_chip(kcontrol);
677
678 ucontrol->value.integer.value[0] =
679 loopback->setup[kcontrol->id.subdevice]
680 [kcontrol->id.device].rate_shift;
681 return 0;
682}
683
684static int loopback_rate_shift_put(struct snd_kcontrol *kcontrol,
685 struct snd_ctl_elem_value *ucontrol)
686{
687 struct loopback *loopback = snd_kcontrol_chip(kcontrol);
688 unsigned int val;
689 int change = 0;
690
691 val = ucontrol->value.integer.value[0];
692 if (val < 80000)
693 val = 80000;
694 if (val > 120000)
695 val = 120000;
696 mutex_lock(&loopback->cable_lock);
697 if (val != loopback->setup[kcontrol->id.subdevice]
698 [kcontrol->id.device].rate_shift) {
699 loopback->setup[kcontrol->id.subdevice]
700 [kcontrol->id.device].rate_shift = val;
701 change = 1;
702 }
703 mutex_unlock(&loopback->cable_lock);
704 return change;
705}
706
707static int loopback_notify_get(struct snd_kcontrol *kcontrol,
708 struct snd_ctl_elem_value *ucontrol)
709{
710 struct loopback *loopback = snd_kcontrol_chip(kcontrol);
711
712 ucontrol->value.integer.value[0] =
713 loopback->setup[kcontrol->id.subdevice]
714 [kcontrol->id.device].notify;
715 return 0;
716}
717
718static int loopback_notify_put(struct snd_kcontrol *kcontrol,
719 struct snd_ctl_elem_value *ucontrol)
720{
721 struct loopback *loopback = snd_kcontrol_chip(kcontrol);
722 unsigned int val;
723 int change = 0;
724
725 val = ucontrol->value.integer.value[0] ? 1 : 0;
726 if (val != loopback->setup[kcontrol->id.subdevice]
727 [kcontrol->id.device].notify) {
728 loopback->setup[kcontrol->id.subdevice]
729 [kcontrol->id.device].notify = val;
730 change = 1;
731 }
732 return change;
733}
734
735static int loopback_active_get(struct snd_kcontrol *kcontrol,
736 struct snd_ctl_elem_value *ucontrol)
737{
738 struct loopback *loopback = snd_kcontrol_chip(kcontrol);
739 struct loopback_cable *cable = loopback->cables
740 [kcontrol->id.subdevice][kcontrol->id.device];
741 unsigned int val = 0;
742
743 if (cable != NULL)
744 val = (cable->running & (1 << SNDRV_PCM_STREAM_PLAYBACK)) ?
745 1 : 0;
746 ucontrol->value.integer.value[0] = val;
747 return 0;
748}
749
750static int loopback_format_info(struct snd_kcontrol *kcontrol,
751 struct snd_ctl_elem_info *uinfo)
752{
753 uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
754 uinfo->count = 1;
755 uinfo->value.integer.min = 0;
756 uinfo->value.integer.max = SNDRV_PCM_FORMAT_LAST;
757 uinfo->value.integer.step = 1;
758 return 0;
759}
760
761static int loopback_format_get(struct snd_kcontrol *kcontrol,
762 struct snd_ctl_elem_value *ucontrol)
763{
764 struct loopback *loopback = snd_kcontrol_chip(kcontrol);
765
766 ucontrol->value.integer.value[0] =
767 loopback->setup[kcontrol->id.subdevice]
768 [kcontrol->id.device].format;
769 return 0;
770}
771
772static int loopback_rate_info(struct snd_kcontrol *kcontrol,
773 struct snd_ctl_elem_info *uinfo)
774{
775 uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
776 uinfo->count = 1;
777 uinfo->value.integer.min = 0;
778 uinfo->value.integer.max = 192000;
779 uinfo->value.integer.step = 1;
780 return 0;
781}
782
783static int loopback_rate_get(struct snd_kcontrol *kcontrol,
784 struct snd_ctl_elem_value *ucontrol)
785{
786 struct loopback *loopback = snd_kcontrol_chip(kcontrol);
787
788 ucontrol->value.integer.value[0] =
789 loopback->setup[kcontrol->id.subdevice]
790 [kcontrol->id.device].rate;
791 return 0;
792}
793
794static int loopback_channels_info(struct snd_kcontrol *kcontrol,
795 struct snd_ctl_elem_info *uinfo)
796{
797 uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
798 uinfo->count = 1;
799 uinfo->value.integer.min = 1;
800 uinfo->value.integer.max = 1024;
801 uinfo->value.integer.step = 1;
802 return 0;
803}
804
805static int loopback_channels_get(struct snd_kcontrol *kcontrol,
806 struct snd_ctl_elem_value *ucontrol)
807{
808 struct loopback *loopback = snd_kcontrol_chip(kcontrol);
809
810 ucontrol->value.integer.value[0] =
811 loopback->setup[kcontrol->id.subdevice]
812 [kcontrol->id.device].rate;
813 return 0;
814}
815
816static struct snd_kcontrol_new loopback_controls[] __devinitdata = {
817{
818 .iface = SNDRV_CTL_ELEM_IFACE_PCM,
819 .name = "PCM Rate Shift 100000",
820 .info = loopback_rate_shift_info,
821 .get = loopback_rate_shift_get,
822 .put = loopback_rate_shift_put,
823},
824{
825 .iface = SNDRV_CTL_ELEM_IFACE_PCM,
826 .name = "PCM Notify",
827 .info = snd_ctl_boolean_mono_info,
828 .get = loopback_notify_get,
829 .put = loopback_notify_put,
830},
831#define ACTIVE_IDX 2
832{
833 .access = SNDRV_CTL_ELEM_ACCESS_READ,
834 .iface = SNDRV_CTL_ELEM_IFACE_PCM,
835 .name = "PCM Slave Active",
836 .info = snd_ctl_boolean_mono_info,
837 .get = loopback_active_get,
838},
839#define FORMAT_IDX 3
840{
841 .access = SNDRV_CTL_ELEM_ACCESS_READ,
842 .iface = SNDRV_CTL_ELEM_IFACE_PCM,
843 .name = "PCM Slave Format",
844 .info = loopback_format_info,
845 .get = loopback_format_get
846},
847#define RATE_IDX 4
848{
849 .access = SNDRV_CTL_ELEM_ACCESS_READ,
850 .iface = SNDRV_CTL_ELEM_IFACE_PCM,
851 .name = "PCM Slave Rate",
852 .info = loopback_rate_info,
853 .get = loopback_rate_get
854},
855#define CHANNELS_IDX 5
856{
857 .access = SNDRV_CTL_ELEM_ACCESS_READ,
858 .iface = SNDRV_CTL_ELEM_IFACE_PCM,
859 .name = "PCM Slave Channels",
860 .info = loopback_channels_info,
861 .get = loopback_channels_get
862}
863};
864
865static int __devinit loopback_mixer_new(struct loopback *loopback, int notify)
866{
867 struct snd_card *card = loopback->card;
868 struct snd_pcm *pcm;
869 struct snd_kcontrol *kctl;
870 struct loopback_setup *setup;
871 int err, dev, substr, substr_count, idx;
872
873 strcpy(card->mixername, "Loopback Mixer");
874 for (dev = 0; dev < 2; dev++) {
875 pcm = loopback->pcm[dev];
876 substr_count =
877 pcm->streams[SNDRV_PCM_STREAM_CAPTURE].substream_count;
878 for (substr = 0; substr < substr_count; substr++) {
879 setup = &loopback->setup[substr][dev];
880 setup->notify = notify;
881 setup->rate_shift = NO_PITCH;
882 setup->format = SNDRV_PCM_FORMAT_S16_LE;
883 setup->rate = 48000;
884 setup->channels = 2;
885 for (idx = 0; idx < ARRAY_SIZE(loopback_controls);
886 idx++) {
887 kctl = snd_ctl_new1(&loopback_controls[idx],
888 loopback);
889 if (!kctl)
890 return -ENOMEM;
891 kctl->id.device = dev;
892 kctl->id.subdevice = substr;
893 switch (idx) {
894 case ACTIVE_IDX:
895 setup->active_id = kctl->id;
896 break;
897 case FORMAT_IDX:
898 setup->format_id = kctl->id;
899 break;
900 case RATE_IDX:
901 setup->rate_id = kctl->id;
902 break;
903 case CHANNELS_IDX:
904 setup->channels_id = kctl->id;
905 break;
906 default:
907 break;
908 }
909 err = snd_ctl_add(card, kctl);
910 if (err < 0)
911 return err;
912 }
913 }
914 }
915 return 0;
916}
917
918static int __devinit loopback_probe(struct platform_device *devptr)
919{
920 struct snd_card *card;
921 struct loopback *loopback;
922 int dev = devptr->id;
923 int err;
924
925 err = snd_card_create(index[dev], id[dev], THIS_MODULE,
926 sizeof(struct loopback), &card);
927 if (err < 0)
928 return err;
929 loopback = card->private_data;
930
931 if (pcm_substreams[dev] < 1)
932 pcm_substreams[dev] = 1;
933 if (pcm_substreams[dev] > MAX_PCM_SUBSTREAMS)
934 pcm_substreams[dev] = MAX_PCM_SUBSTREAMS;
935
936 loopback->card = card;
937 mutex_init(&loopback->cable_lock);
938
939 err = loopback_pcm_new(loopback, 0, pcm_substreams[dev]);
940 if (err < 0)
941 goto __nodev;
942 err = loopback_pcm_new(loopback, 1, pcm_substreams[dev]);
943 if (err < 0)
944 goto __nodev;
945 err = loopback_mixer_new(loopback, pcm_notify[dev] ? 1 : 0);
946 if (err < 0)
947 goto __nodev;
948 strcpy(card->driver, "Loopback");
949 strcpy(card->shortname, "Loopback");
950 sprintf(card->longname, "Loopback %i", dev + 1);
951 err = snd_card_register(card);
952 if (!err) {
953 platform_set_drvdata(devptr, card);
954 return 0;
955 }
956 __nodev:
957 snd_card_free(card);
958 return err;
959}
960
961static int __devexit loopback_remove(struct platform_device *devptr)
962{
963 snd_card_free(platform_get_drvdata(devptr));
964 platform_set_drvdata(devptr, NULL);
965 return 0;
966}
967
968#ifdef CONFIG_PM
969static int loopback_suspend(struct platform_device *pdev,
970 pm_message_t state)
971{
972 struct snd_card *card = platform_get_drvdata(pdev);
973 struct loopback *loopback = card->private_data;
974
975 snd_power_change_state(card, SNDRV_CTL_POWER_D3hot);
976
977 snd_pcm_suspend_all(loopback->pcm[0]);
978 snd_pcm_suspend_all(loopback->pcm[1]);
979 return 0;
980}
981
982static int loopback_resume(struct platform_device *pdev)
983{
984 struct snd_card *card = platform_get_drvdata(pdev);
985
986 snd_power_change_state(card, SNDRV_CTL_POWER_D0);
987 return 0;
988}
989#endif
990
991#define SND_LOOPBACK_DRIVER "snd_aloop"
992
993static struct platform_driver loopback_driver = {
994 .probe = loopback_probe,
995 .remove = __devexit_p(loopback_remove),
996#ifdef CONFIG_PM
997 .suspend = loopback_suspend,
998 .resume = loopback_resume,
999#endif
1000 .driver = {
1001 .name = SND_LOOPBACK_DRIVER
1002 },
1003};
1004
1005static void loopback_unregister_all(void)
1006{
1007 int i;
1008
1009 for (i = 0; i < ARRAY_SIZE(devices); ++i)
1010 platform_device_unregister(devices[i]);
1011 platform_driver_unregister(&loopback_driver);
1012}
1013
1014static int __init alsa_card_loopback_init(void)
1015{
1016 int i, err, cards;
1017
1018 err = platform_driver_register(&loopback_driver);
1019 if (err < 0)
1020 return err;
1021
1022
1023 cards = 0;
1024 for (i = 0; i < SNDRV_CARDS; i++) {
1025 struct platform_device *device;
1026 if (!enable[i])
1027 continue;
1028 device = platform_device_register_simple(SND_LOOPBACK_DRIVER,
1029 i, NULL, 0);
1030 if (IS_ERR(device))
1031 continue;
1032 if (!platform_get_drvdata(device)) {
1033 platform_device_unregister(device);
1034 continue;
1035 }
1036 devices[i] = device;
1037 cards++;
1038 }
1039 if (!cards) {
1040#ifdef MODULE
1041 printk(KERN_ERR "aloop: No loopback enabled\n");
1042#endif
1043 loopback_unregister_all();
1044 return -ENODEV;
1045 }
1046 return 0;
1047}
1048
1049static void __exit alsa_card_loopback_exit(void)
1050{
1051 loopback_unregister_all();
1052}
1053
1054module_init(alsa_card_loopback_init)
1055module_exit(alsa_card_loopback_exit)