aboutsummaryrefslogtreecommitdiffstats
path: root/sound/drivers
diff options
context:
space:
mode:
Diffstat (limited to 'sound/drivers')
-rw-r--r--sound/drivers/Kconfig19
-rw-r--r--sound/drivers/Makefile2
-rw-r--r--sound/drivers/aloop.c1257
-rw-r--r--sound/drivers/ml403-ac97cr.c4
-rw-r--r--sound/drivers/mtpav.c3
-rw-r--r--sound/drivers/pcm-indirect2.c4
-rw-r--r--sound/drivers/virmidi.c2
-rw-r--r--sound/drivers/vx/vx_pcm.c2
8 files changed, 1285 insertions, 8 deletions
diff --git a/sound/drivers/Kconfig b/sound/drivers/Kconfig
index 480c38623da8..c8961165277c 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..a0da7755fcea
--- /dev/null
+++ b/sound/drivers/aloop.c
@@ -0,0 +1,1257 @@
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/info.h>
43#include <sound/initval.h>
44
45MODULE_AUTHOR("Jaroslav Kysela <perex@perex.cz>");
46MODULE_DESCRIPTION("A loopback soundcard");
47MODULE_LICENSE("GPL");
48MODULE_SUPPORTED_DEVICE("{{ALSA,Loopback soundcard}}");
49
50#define MAX_PCM_SUBSTREAMS 8
51
52static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX; /* Index 0-MAX */
53static char *id[SNDRV_CARDS] = SNDRV_DEFAULT_STR; /* ID for this card */
54static int enable[SNDRV_CARDS] = {1, [1 ... (SNDRV_CARDS - 1)] = 0};
55static int pcm_substreams[SNDRV_CARDS] = {[0 ... (SNDRV_CARDS - 1)] = 8};
56static int pcm_notify[SNDRV_CARDS];
57
58module_param_array(index, int, NULL, 0444);
59MODULE_PARM_DESC(index, "Index value for loopback soundcard.");
60module_param_array(id, charp, NULL, 0444);
61MODULE_PARM_DESC(id, "ID string for loopback soundcard.");
62module_param_array(enable, bool, NULL, 0444);
63MODULE_PARM_DESC(enable, "Enable this loopback soundcard.");
64module_param_array(pcm_substreams, int, NULL, 0444);
65MODULE_PARM_DESC(pcm_substreams, "PCM substreams # (1-8) for loopback driver.");
66module_param_array(pcm_notify, int, NULL, 0444);
67MODULE_PARM_DESC(pcm_notify, "Break capture when PCM format/rate/channels changes.");
68
69#define NO_PITCH 100000
70
71struct loopback_pcm;
72
73struct loopback_cable {
74 spinlock_t lock;
75 struct loopback_pcm *streams[2];
76 struct snd_pcm_hardware hw;
77 /* flags */
78 unsigned int valid;
79 unsigned int running;
80 unsigned int pause;
81};
82
83struct loopback_setup {
84 unsigned int notify: 1;
85 unsigned int rate_shift;
86 unsigned int format;
87 unsigned int rate;
88 unsigned int channels;
89 struct snd_ctl_elem_id active_id;
90 struct snd_ctl_elem_id format_id;
91 struct snd_ctl_elem_id rate_id;
92 struct snd_ctl_elem_id channels_id;
93};
94
95struct loopback {
96 struct snd_card *card;
97 struct mutex cable_lock;
98 struct loopback_cable *cables[MAX_PCM_SUBSTREAMS][2];
99 struct snd_pcm *pcm[2];
100 struct loopback_setup setup[MAX_PCM_SUBSTREAMS][2];
101};
102
103struct loopback_pcm {
104 struct loopback *loopback;
105 struct snd_pcm_substream *substream;
106 struct loopback_cable *cable;
107 unsigned int pcm_buffer_size;
108 unsigned int buf_pos; /* position in buffer */
109 unsigned int silent_size;
110 /* PCM parameters */
111 unsigned int pcm_period_size;
112 unsigned int pcm_bps; /* bytes per second */
113 unsigned int pcm_salign; /* bytes per sample * channels */
114 unsigned int pcm_rate_shift; /* rate shift value */
115 /* flags */
116 unsigned int period_update_pending :1;
117 /* timer stuff */
118 unsigned int irq_pos; /* fractional IRQ position */
119 unsigned int period_size_frac;
120 unsigned long last_jiffies;
121 struct timer_list timer;
122};
123
124static struct platform_device *devices[SNDRV_CARDS];
125
126static inline unsigned int byte_pos(struct loopback_pcm *dpcm, unsigned int x)
127{
128 if (dpcm->pcm_rate_shift == NO_PITCH) {
129 x /= HZ;
130 } else {
131 x = div_u64(NO_PITCH * (unsigned long long)x,
132 HZ * (unsigned long long)dpcm->pcm_rate_shift);
133 }
134 return x - (x % dpcm->pcm_salign);
135}
136
137static inline unsigned int frac_pos(struct loopback_pcm *dpcm, unsigned int x)
138{
139 if (dpcm->pcm_rate_shift == NO_PITCH) { /* no pitch */
140 return x * HZ;
141 } else {
142 x = div_u64(dpcm->pcm_rate_shift * (unsigned long long)x * HZ,
143 NO_PITCH);
144 }
145 return x;
146}
147
148static inline struct loopback_setup *get_setup(struct loopback_pcm *dpcm)
149{
150 int device = dpcm->substream->pstr->pcm->device;
151
152 if (dpcm->substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
153 device ^= 1;
154 return &dpcm->loopback->setup[dpcm->substream->number][device];
155}
156
157static inline unsigned int get_notify(struct loopback_pcm *dpcm)
158{
159 return get_setup(dpcm)->notify;
160}
161
162static inline unsigned int get_rate_shift(struct loopback_pcm *dpcm)
163{
164 return get_setup(dpcm)->rate_shift;
165}
166
167static void loopback_timer_start(struct loopback_pcm *dpcm)
168{
169 unsigned long tick;
170 unsigned int rate_shift = get_rate_shift(dpcm);
171
172 if (rate_shift != dpcm->pcm_rate_shift) {
173 dpcm->pcm_rate_shift = rate_shift;
174 dpcm->period_size_frac = frac_pos(dpcm, dpcm->pcm_period_size);
175 }
176 if (dpcm->period_size_frac <= dpcm->irq_pos) {
177 dpcm->irq_pos %= dpcm->period_size_frac;
178 dpcm->period_update_pending = 1;
179 }
180 tick = dpcm->period_size_frac - dpcm->irq_pos;
181 tick = (tick + dpcm->pcm_bps - 1) / dpcm->pcm_bps;
182 dpcm->timer.expires = jiffies + tick;
183 add_timer(&dpcm->timer);
184}
185
186static inline void loopback_timer_stop(struct loopback_pcm *dpcm)
187{
188 del_timer(&dpcm->timer);
189 dpcm->timer.expires = 0;
190}
191
192#define CABLE_VALID_PLAYBACK (1 << SNDRV_PCM_STREAM_PLAYBACK)
193#define CABLE_VALID_CAPTURE (1 << SNDRV_PCM_STREAM_CAPTURE)
194#define CABLE_VALID_BOTH (CABLE_VALID_PLAYBACK|CABLE_VALID_CAPTURE)
195
196static int loopback_check_format(struct loopback_cable *cable, int stream)
197{
198 struct snd_pcm_runtime *runtime, *cruntime;
199 struct loopback_setup *setup;
200 struct snd_card *card;
201 int check;
202
203 if (cable->valid != CABLE_VALID_BOTH) {
204 if (stream == SNDRV_PCM_STREAM_PLAYBACK)
205 goto __notify;
206 return 0;
207 }
208 runtime = cable->streams[SNDRV_PCM_STREAM_PLAYBACK]->
209 substream->runtime;
210 cruntime = cable->streams[SNDRV_PCM_STREAM_CAPTURE]->
211 substream->runtime;
212 check = runtime->format != cruntime->format ||
213 runtime->rate != cruntime->rate ||
214 runtime->channels != cruntime->channels;
215 if (!check)
216 return 0;
217 if (stream == SNDRV_PCM_STREAM_CAPTURE) {
218 return -EIO;
219 } else {
220 snd_pcm_stop(cable->streams[SNDRV_PCM_STREAM_CAPTURE]->
221 substream, SNDRV_PCM_STATE_DRAINING);
222 __notify:
223 runtime = cable->streams[SNDRV_PCM_STREAM_PLAYBACK]->
224 substream->runtime;
225 setup = get_setup(cable->streams[SNDRV_PCM_STREAM_PLAYBACK]);
226 card = cable->streams[SNDRV_PCM_STREAM_PLAYBACK]->loopback->card;
227 if (setup->format != runtime->format) {
228 snd_ctl_notify(card, SNDRV_CTL_EVENT_MASK_VALUE,
229 &setup->format_id);
230 setup->format = runtime->format;
231 }
232 if (setup->rate != runtime->rate) {
233 snd_ctl_notify(card, SNDRV_CTL_EVENT_MASK_VALUE,
234 &setup->rate_id);
235 setup->rate = runtime->rate;
236 }
237 if (setup->channels != runtime->channels) {
238 snd_ctl_notify(card, SNDRV_CTL_EVENT_MASK_VALUE,
239 &setup->channels_id);
240 setup->channels = runtime->channels;
241 }
242 }
243 return 0;
244}
245
246static void loopback_active_notify(struct loopback_pcm *dpcm)
247{
248 snd_ctl_notify(dpcm->loopback->card,
249 SNDRV_CTL_EVENT_MASK_VALUE,
250 &get_setup(dpcm)->active_id);
251}
252
253static int loopback_trigger(struct snd_pcm_substream *substream, int cmd)
254{
255 struct snd_pcm_runtime *runtime = substream->runtime;
256 struct loopback_pcm *dpcm = runtime->private_data;
257 struct loopback_cable *cable = dpcm->cable;
258 int err, stream = 1 << substream->stream;
259
260 switch (cmd) {
261 case SNDRV_PCM_TRIGGER_START:
262 err = loopback_check_format(cable, substream->stream);
263 if (err < 0)
264 return err;
265 dpcm->last_jiffies = jiffies;
266 dpcm->pcm_rate_shift = 0;
267 spin_lock(&cable->lock);
268 cable->running |= stream;
269 cable->pause &= ~stream;
270 spin_unlock(&cable->lock);
271 loopback_timer_start(dpcm);
272 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
273 loopback_active_notify(dpcm);
274 break;
275 case SNDRV_PCM_TRIGGER_STOP:
276 spin_lock(&cable->lock);
277 cable->running &= ~stream;
278 cable->pause &= ~stream;
279 spin_unlock(&cable->lock);
280 loopback_timer_stop(dpcm);
281 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
282 loopback_active_notify(dpcm);
283 break;
284 case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
285 spin_lock(&cable->lock);
286 cable->pause |= stream;
287 spin_unlock(&cable->lock);
288 loopback_timer_stop(dpcm);
289 break;
290 case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
291 spin_lock(&cable->lock);
292 dpcm->last_jiffies = jiffies;
293 cable->pause &= ~stream;
294 spin_unlock(&cable->lock);
295 loopback_timer_start(dpcm);
296 break;
297 default:
298 return -EINVAL;
299 }
300 return 0;
301}
302
303static void params_change_substream(struct loopback_pcm *dpcm,
304 struct snd_pcm_runtime *runtime)
305{
306 struct snd_pcm_runtime *dst_runtime;
307
308 if (dpcm == NULL || dpcm->substream == NULL)
309 return;
310 dst_runtime = dpcm->substream->runtime;
311 if (dst_runtime == NULL)
312 return;
313 dst_runtime->hw = dpcm->cable->hw;
314}
315
316static void params_change(struct snd_pcm_substream *substream)
317{
318 struct snd_pcm_runtime *runtime = substream->runtime;
319 struct loopback_pcm *dpcm = runtime->private_data;
320 struct loopback_cable *cable = dpcm->cable;
321
322 cable->hw.formats = (1ULL << runtime->format);
323 cable->hw.rate_min = runtime->rate;
324 cable->hw.rate_max = runtime->rate;
325 cable->hw.channels_min = runtime->channels;
326 cable->hw.channels_max = runtime->channels;
327 params_change_substream(cable->streams[SNDRV_PCM_STREAM_PLAYBACK],
328 runtime);
329 params_change_substream(cable->streams[SNDRV_PCM_STREAM_CAPTURE],
330 runtime);
331}
332
333static int loopback_prepare(struct snd_pcm_substream *substream)
334{
335 struct snd_pcm_runtime *runtime = substream->runtime;
336 struct loopback_pcm *dpcm = runtime->private_data;
337 struct loopback_cable *cable = dpcm->cable;
338 int bps, salign;
339
340 salign = (snd_pcm_format_width(runtime->format) *
341 runtime->channels) / 8;
342 bps = salign * runtime->rate;
343 if (bps <= 0 || salign <= 0)
344 return -EINVAL;
345
346 dpcm->buf_pos = 0;
347 dpcm->pcm_buffer_size = frames_to_bytes(runtime, runtime->buffer_size);
348 if (substream->stream == SNDRV_PCM_STREAM_CAPTURE) {
349 /* clear capture buffer */
350 dpcm->silent_size = dpcm->pcm_buffer_size;
351 snd_pcm_format_set_silence(runtime->format, runtime->dma_area,
352 runtime->buffer_size * runtime->channels);
353 }
354
355 dpcm->irq_pos = 0;
356 dpcm->period_update_pending = 0;
357 dpcm->pcm_bps = bps;
358 dpcm->pcm_salign = salign;
359 dpcm->pcm_period_size = frames_to_bytes(runtime, runtime->period_size);
360
361 mutex_lock(&dpcm->loopback->cable_lock);
362 if (!(cable->valid & ~(1 << substream->stream)) ||
363 (get_setup(dpcm)->notify &&
364 substream->stream == SNDRV_PCM_STREAM_PLAYBACK))
365 params_change(substream);
366 cable->valid |= 1 << substream->stream;
367 mutex_unlock(&dpcm->loopback->cable_lock);
368
369 return 0;
370}
371
372static void clear_capture_buf(struct loopback_pcm *dpcm, unsigned int bytes)
373{
374 struct snd_pcm_runtime *runtime = dpcm->substream->runtime;
375 char *dst = runtime->dma_area;
376 unsigned int dst_off = dpcm->buf_pos;
377
378 if (dpcm->silent_size >= dpcm->pcm_buffer_size)
379 return;
380 if (dpcm->silent_size + bytes > dpcm->pcm_buffer_size)
381 bytes = dpcm->pcm_buffer_size - dpcm->silent_size;
382
383 for (;;) {
384 unsigned int size = bytes;
385 if (dst_off + size > dpcm->pcm_buffer_size)
386 size = dpcm->pcm_buffer_size - dst_off;
387 snd_pcm_format_set_silence(runtime->format, dst + dst_off,
388 bytes_to_frames(runtime, size) *
389 runtime->channels);
390 dpcm->silent_size += size;
391 bytes -= size;
392 if (!bytes)
393 break;
394 dst_off = 0;
395 }
396}
397
398static void copy_play_buf(struct loopback_pcm *play,
399 struct loopback_pcm *capt,
400 unsigned int bytes)
401{
402 struct snd_pcm_runtime *runtime = play->substream->runtime;
403 char *src = runtime->dma_area;
404 char *dst = capt->substream->runtime->dma_area;
405 unsigned int src_off = play->buf_pos;
406 unsigned int dst_off = capt->buf_pos;
407 unsigned int clear_bytes = 0;
408
409 /* check if playback is draining, trim the capture copy size
410 * when our pointer is at the end of playback ring buffer */
411 if (runtime->status->state == SNDRV_PCM_STATE_DRAINING &&
412 snd_pcm_playback_hw_avail(runtime) < runtime->buffer_size) {
413 snd_pcm_uframes_t appl_ptr, appl_ptr1, diff;
414 appl_ptr = appl_ptr1 = runtime->control->appl_ptr;
415 appl_ptr1 -= appl_ptr1 % runtime->buffer_size;
416 appl_ptr1 += play->buf_pos / play->pcm_salign;
417 if (appl_ptr < appl_ptr1)
418 appl_ptr1 -= runtime->buffer_size;
419 diff = (appl_ptr - appl_ptr1) * play->pcm_salign;
420 if (diff < bytes) {
421 clear_bytes = bytes - diff;
422 bytes = diff;
423 }
424 }
425
426 for (;;) {
427 unsigned int size = bytes;
428 if (src_off + size > play->pcm_buffer_size)
429 size = play->pcm_buffer_size - src_off;
430 if (dst_off + size > capt->pcm_buffer_size)
431 size = capt->pcm_buffer_size - dst_off;
432 memcpy(dst + dst_off, src + src_off, size);
433 capt->silent_size = 0;
434 bytes -= size;
435 if (!bytes)
436 break;
437 src_off = (src_off + size) % play->pcm_buffer_size;
438 dst_off = (dst_off + size) % capt->pcm_buffer_size;
439 }
440
441 if (clear_bytes > 0) {
442 clear_capture_buf(capt, clear_bytes);
443 capt->silent_size = 0;
444 }
445}
446
447#define BYTEPOS_UPDATE_POSONLY 0
448#define BYTEPOS_UPDATE_CLEAR 1
449#define BYTEPOS_UPDATE_COPY 2
450
451static void loopback_bytepos_update(struct loopback_pcm *dpcm,
452 unsigned int delta,
453 unsigned int cmd)
454{
455 unsigned int count;
456 unsigned long last_pos;
457
458 last_pos = byte_pos(dpcm, dpcm->irq_pos);
459 dpcm->irq_pos += delta * dpcm->pcm_bps;
460 count = byte_pos(dpcm, dpcm->irq_pos) - last_pos;
461 if (!count)
462 return;
463 if (cmd == BYTEPOS_UPDATE_CLEAR)
464 clear_capture_buf(dpcm, count);
465 else if (cmd == BYTEPOS_UPDATE_COPY)
466 copy_play_buf(dpcm->cable->streams[SNDRV_PCM_STREAM_PLAYBACK],
467 dpcm->cable->streams[SNDRV_PCM_STREAM_CAPTURE],
468 count);
469 dpcm->buf_pos += count;
470 dpcm->buf_pos %= dpcm->pcm_buffer_size;
471 if (dpcm->irq_pos >= dpcm->period_size_frac) {
472 dpcm->irq_pos %= dpcm->period_size_frac;
473 dpcm->period_update_pending = 1;
474 }
475}
476
477static unsigned int loopback_pos_update(struct loopback_cable *cable)
478{
479 struct loopback_pcm *dpcm_play =
480 cable->streams[SNDRV_PCM_STREAM_PLAYBACK];
481 struct loopback_pcm *dpcm_capt =
482 cable->streams[SNDRV_PCM_STREAM_CAPTURE];
483 unsigned long delta_play = 0, delta_capt = 0;
484 unsigned int running;
485 unsigned long flags;
486
487 spin_lock_irqsave(&cable->lock, flags);
488 running = cable->running ^ cable->pause;
489 if (running & (1 << SNDRV_PCM_STREAM_PLAYBACK)) {
490 delta_play = jiffies - dpcm_play->last_jiffies;
491 dpcm_play->last_jiffies += delta_play;
492 }
493
494 if (running & (1 << SNDRV_PCM_STREAM_CAPTURE)) {
495 delta_capt = jiffies - dpcm_capt->last_jiffies;
496 dpcm_capt->last_jiffies += delta_capt;
497 }
498
499 if (delta_play == 0 && delta_capt == 0)
500 goto unlock;
501
502 if (delta_play > delta_capt) {
503 loopback_bytepos_update(dpcm_play, delta_play - delta_capt,
504 BYTEPOS_UPDATE_POSONLY);
505 delta_play = delta_capt;
506 } else if (delta_play < delta_capt) {
507 loopback_bytepos_update(dpcm_capt, delta_capt - delta_play,
508 BYTEPOS_UPDATE_CLEAR);
509 delta_capt = delta_play;
510 }
511
512 if (delta_play == 0 && delta_capt == 0)
513 goto unlock;
514
515 /* note delta_capt == delta_play at this moment */
516 loopback_bytepos_update(dpcm_capt, delta_capt, BYTEPOS_UPDATE_COPY);
517 loopback_bytepos_update(dpcm_play, delta_play, BYTEPOS_UPDATE_POSONLY);
518 unlock:
519 spin_unlock_irqrestore(&cable->lock, flags);
520 return running;
521}
522
523static void loopback_timer_function(unsigned long data)
524{
525 struct loopback_pcm *dpcm = (struct loopback_pcm *)data;
526 unsigned int running;
527
528 running = loopback_pos_update(dpcm->cable);
529 if (running & (1 << dpcm->substream->stream)) {
530 loopback_timer_start(dpcm);
531 if (dpcm->period_update_pending) {
532 dpcm->period_update_pending = 0;
533 snd_pcm_period_elapsed(dpcm->substream);
534 }
535 }
536}
537
538static snd_pcm_uframes_t loopback_pointer(struct snd_pcm_substream *substream)
539{
540 struct snd_pcm_runtime *runtime = substream->runtime;
541 struct loopback_pcm *dpcm = runtime->private_data;
542
543 loopback_pos_update(dpcm->cable);
544 return bytes_to_frames(runtime, dpcm->buf_pos);
545}
546
547static struct snd_pcm_hardware loopback_pcm_hardware =
548{
549 .info = (SNDRV_PCM_INFO_INTERLEAVED | SNDRV_PCM_INFO_MMAP |
550 SNDRV_PCM_INFO_MMAP_VALID | SNDRV_PCM_INFO_PAUSE),
551 .formats = (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S16_BE |
552 SNDRV_PCM_FMTBIT_S32_LE | SNDRV_PCM_FMTBIT_S32_BE |
553 SNDRV_PCM_FMTBIT_FLOAT_LE | SNDRV_PCM_FMTBIT_FLOAT_BE),
554 .rates = SNDRV_PCM_RATE_CONTINUOUS | SNDRV_PCM_RATE_8000_192000,
555 .rate_min = 8000,
556 .rate_max = 192000,
557 .channels_min = 1,
558 .channels_max = 32,
559 .buffer_bytes_max = 2 * 1024 * 1024,
560 .period_bytes_min = 64,
561 /* note check overflow in frac_pos() using pcm_rate_shift before
562 changing period_bytes_max value */
563 .period_bytes_max = 1024 * 1024,
564 .periods_min = 1,
565 .periods_max = 1024,
566 .fifo_size = 0,
567};
568
569static void loopback_runtime_free(struct snd_pcm_runtime *runtime)
570{
571 struct loopback_pcm *dpcm = runtime->private_data;
572 kfree(dpcm);
573}
574
575static int loopback_hw_params(struct snd_pcm_substream *substream,
576 struct snd_pcm_hw_params *params)
577{
578 return snd_pcm_lib_malloc_pages(substream, params_buffer_bytes(params));
579}
580
581static int loopback_hw_free(struct snd_pcm_substream *substream)
582{
583 struct snd_pcm_runtime *runtime = substream->runtime;
584 struct loopback_pcm *dpcm = runtime->private_data;
585 struct loopback_cable *cable = dpcm->cable;
586
587 mutex_lock(&dpcm->loopback->cable_lock);
588 cable->valid &= ~(1 << substream->stream);
589 mutex_unlock(&dpcm->loopback->cable_lock);
590 return snd_pcm_lib_free_pages(substream);
591}
592
593static unsigned int get_cable_index(struct snd_pcm_substream *substream)
594{
595 if (!substream->pcm->device)
596 return substream->stream;
597 else
598 return !substream->stream;
599}
600
601static int rule_format(struct snd_pcm_hw_params *params,
602 struct snd_pcm_hw_rule *rule)
603{
604
605 struct snd_pcm_hardware *hw = rule->private;
606 struct snd_mask *maskp = hw_param_mask(params, rule->var);
607
608 maskp->bits[0] &= (u_int32_t)hw->formats;
609 maskp->bits[1] &= (u_int32_t)(hw->formats >> 32);
610 memset(maskp->bits + 2, 0, (SNDRV_MASK_MAX-64) / 8); /* clear rest */
611 if (! maskp->bits[0] && ! maskp->bits[1])
612 return -EINVAL;
613 return 0;
614}
615
616static int rule_rate(struct snd_pcm_hw_params *params,
617 struct snd_pcm_hw_rule *rule)
618{
619 struct snd_pcm_hardware *hw = rule->private;
620 struct snd_interval t;
621
622 t.min = hw->rate_min;
623 t.max = hw->rate_max;
624 t.openmin = t.openmax = 0;
625 t.integer = 0;
626 return snd_interval_refine(hw_param_interval(params, rule->var), &t);
627}
628
629static int rule_channels(struct snd_pcm_hw_params *params,
630 struct snd_pcm_hw_rule *rule)
631{
632 struct snd_pcm_hardware *hw = rule->private;
633 struct snd_interval t;
634
635 t.min = hw->channels_min;
636 t.max = hw->channels_max;
637 t.openmin = t.openmax = 0;
638 t.integer = 0;
639 return snd_interval_refine(hw_param_interval(params, rule->var), &t);
640}
641
642static int loopback_open(struct snd_pcm_substream *substream)
643{
644 struct snd_pcm_runtime *runtime = substream->runtime;
645 struct loopback *loopback = substream->private_data;
646 struct loopback_pcm *dpcm;
647 struct loopback_cable *cable;
648 int err = 0;
649 int dev = get_cable_index(substream);
650
651 mutex_lock(&loopback->cable_lock);
652 dpcm = kzalloc(sizeof(*dpcm), GFP_KERNEL);
653 if (!dpcm) {
654 err = -ENOMEM;
655 goto unlock;
656 }
657 dpcm->loopback = loopback;
658 dpcm->substream = substream;
659 setup_timer(&dpcm->timer, loopback_timer_function,
660 (unsigned long)dpcm);
661
662 cable = loopback->cables[substream->number][dev];
663 if (!cable) {
664 cable = kzalloc(sizeof(*cable), GFP_KERNEL);
665 if (!cable) {
666 kfree(dpcm);
667 err = -ENOMEM;
668 goto unlock;
669 }
670 spin_lock_init(&cable->lock);
671 cable->hw = loopback_pcm_hardware;
672 loopback->cables[substream->number][dev] = cable;
673 }
674 dpcm->cable = cable;
675 cable->streams[substream->stream] = dpcm;
676
677 snd_pcm_hw_constraint_integer(runtime, SNDRV_PCM_HW_PARAM_PERIODS);
678
679 /* use dynamic rules based on actual runtime->hw values */
680 /* note that the default rules created in the PCM midlevel code */
681 /* are cached -> they do not reflect the actual state */
682 err = snd_pcm_hw_rule_add(runtime, 0,
683 SNDRV_PCM_HW_PARAM_FORMAT,
684 rule_format, &runtime->hw,
685 SNDRV_PCM_HW_PARAM_FORMAT, -1);
686 if (err < 0)
687 goto unlock;
688 err = snd_pcm_hw_rule_add(runtime, 0,
689 SNDRV_PCM_HW_PARAM_RATE,
690 rule_rate, &runtime->hw,
691 SNDRV_PCM_HW_PARAM_RATE, -1);
692 if (err < 0)
693 goto unlock;
694 err = snd_pcm_hw_rule_add(runtime, 0,
695 SNDRV_PCM_HW_PARAM_CHANNELS,
696 rule_channels, &runtime->hw,
697 SNDRV_PCM_HW_PARAM_CHANNELS, -1);
698 if (err < 0)
699 goto unlock;
700
701 runtime->private_data = dpcm;
702 runtime->private_free = loopback_runtime_free;
703 if (get_notify(dpcm))
704 runtime->hw = loopback_pcm_hardware;
705 else
706 runtime->hw = cable->hw;
707 unlock:
708 mutex_unlock(&loopback->cable_lock);
709 return err;
710}
711
712static int loopback_close(struct snd_pcm_substream *substream)
713{
714 struct loopback *loopback = substream->private_data;
715 struct loopback_pcm *dpcm = substream->runtime->private_data;
716 struct loopback_cable *cable;
717 int dev = get_cable_index(substream);
718
719 loopback_timer_stop(dpcm);
720 mutex_lock(&loopback->cable_lock);
721 cable = loopback->cables[substream->number][dev];
722 if (cable->streams[!substream->stream]) {
723 /* other stream is still alive */
724 cable->streams[substream->stream] = NULL;
725 } else {
726 /* free the cable */
727 loopback->cables[substream->number][dev] = NULL;
728 kfree(cable);
729 }
730 mutex_unlock(&loopback->cable_lock);
731 return 0;
732}
733
734static struct snd_pcm_ops loopback_playback_ops = {
735 .open = loopback_open,
736 .close = loopback_close,
737 .ioctl = snd_pcm_lib_ioctl,
738 .hw_params = loopback_hw_params,
739 .hw_free = loopback_hw_free,
740 .prepare = loopback_prepare,
741 .trigger = loopback_trigger,
742 .pointer = loopback_pointer,
743};
744
745static struct snd_pcm_ops loopback_capture_ops = {
746 .open = loopback_open,
747 .close = loopback_close,
748 .ioctl = snd_pcm_lib_ioctl,
749 .hw_params = loopback_hw_params,
750 .hw_free = loopback_hw_free,
751 .prepare = loopback_prepare,
752 .trigger = loopback_trigger,
753 .pointer = loopback_pointer,
754};
755
756static int __devinit loopback_pcm_new(struct loopback *loopback,
757 int device, int substreams)
758{
759 struct snd_pcm *pcm;
760 int err;
761
762 err = snd_pcm_new(loopback->card, "Loopback PCM", device,
763 substreams, substreams, &pcm);
764 if (err < 0)
765 return err;
766 snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK, &loopback_playback_ops);
767 snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_CAPTURE, &loopback_capture_ops);
768
769 pcm->private_data = loopback;
770 pcm->info_flags = 0;
771 strcpy(pcm->name, "Loopback PCM");
772
773 loopback->pcm[device] = pcm;
774
775 snd_pcm_lib_preallocate_pages_for_all(pcm, SNDRV_DMA_TYPE_CONTINUOUS,
776 snd_dma_continuous_data(GFP_KERNEL),
777 0, 2 * 1024 * 1024);
778 return 0;
779}
780
781static int loopback_rate_shift_info(struct snd_kcontrol *kcontrol,
782 struct snd_ctl_elem_info *uinfo)
783{
784 uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
785 uinfo->count = 1;
786 uinfo->value.integer.min = 80000;
787 uinfo->value.integer.max = 120000;
788 uinfo->value.integer.step = 1;
789 return 0;
790}
791
792static int loopback_rate_shift_get(struct snd_kcontrol *kcontrol,
793 struct snd_ctl_elem_value *ucontrol)
794{
795 struct loopback *loopback = snd_kcontrol_chip(kcontrol);
796
797 ucontrol->value.integer.value[0] =
798 loopback->setup[kcontrol->id.subdevice]
799 [kcontrol->id.device].rate_shift;
800 return 0;
801}
802
803static int loopback_rate_shift_put(struct snd_kcontrol *kcontrol,
804 struct snd_ctl_elem_value *ucontrol)
805{
806 struct loopback *loopback = snd_kcontrol_chip(kcontrol);
807 unsigned int val;
808 int change = 0;
809
810 val = ucontrol->value.integer.value[0];
811 if (val < 80000)
812 val = 80000;
813 if (val > 120000)
814 val = 120000;
815 mutex_lock(&loopback->cable_lock);
816 if (val != loopback->setup[kcontrol->id.subdevice]
817 [kcontrol->id.device].rate_shift) {
818 loopback->setup[kcontrol->id.subdevice]
819 [kcontrol->id.device].rate_shift = val;
820 change = 1;
821 }
822 mutex_unlock(&loopback->cable_lock);
823 return change;
824}
825
826static int loopback_notify_get(struct snd_kcontrol *kcontrol,
827 struct snd_ctl_elem_value *ucontrol)
828{
829 struct loopback *loopback = snd_kcontrol_chip(kcontrol);
830
831 ucontrol->value.integer.value[0] =
832 loopback->setup[kcontrol->id.subdevice]
833 [kcontrol->id.device].notify;
834 return 0;
835}
836
837static int loopback_notify_put(struct snd_kcontrol *kcontrol,
838 struct snd_ctl_elem_value *ucontrol)
839{
840 struct loopback *loopback = snd_kcontrol_chip(kcontrol);
841 unsigned int val;
842 int change = 0;
843
844 val = ucontrol->value.integer.value[0] ? 1 : 0;
845 if (val != loopback->setup[kcontrol->id.subdevice]
846 [kcontrol->id.device].notify) {
847 loopback->setup[kcontrol->id.subdevice]
848 [kcontrol->id.device].notify = val;
849 change = 1;
850 }
851 return change;
852}
853
854static int loopback_active_get(struct snd_kcontrol *kcontrol,
855 struct snd_ctl_elem_value *ucontrol)
856{
857 struct loopback *loopback = snd_kcontrol_chip(kcontrol);
858 struct loopback_cable *cable = loopback->cables
859 [kcontrol->id.subdevice][kcontrol->id.device ^ 1];
860 unsigned int val = 0;
861
862 if (cable != NULL)
863 val = (cable->running & (1 << SNDRV_PCM_STREAM_PLAYBACK)) ?
864 1 : 0;
865 ucontrol->value.integer.value[0] = val;
866 return 0;
867}
868
869static int loopback_format_info(struct snd_kcontrol *kcontrol,
870 struct snd_ctl_elem_info *uinfo)
871{
872 uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
873 uinfo->count = 1;
874 uinfo->value.integer.min = 0;
875 uinfo->value.integer.max = SNDRV_PCM_FORMAT_LAST;
876 uinfo->value.integer.step = 1;
877 return 0;
878}
879
880static int loopback_format_get(struct snd_kcontrol *kcontrol,
881 struct snd_ctl_elem_value *ucontrol)
882{
883 struct loopback *loopback = snd_kcontrol_chip(kcontrol);
884
885 ucontrol->value.integer.value[0] =
886 loopback->setup[kcontrol->id.subdevice]
887 [kcontrol->id.device].format;
888 return 0;
889}
890
891static int loopback_rate_info(struct snd_kcontrol *kcontrol,
892 struct snd_ctl_elem_info *uinfo)
893{
894 uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
895 uinfo->count = 1;
896 uinfo->value.integer.min = 0;
897 uinfo->value.integer.max = 192000;
898 uinfo->value.integer.step = 1;
899 return 0;
900}
901
902static int loopback_rate_get(struct snd_kcontrol *kcontrol,
903 struct snd_ctl_elem_value *ucontrol)
904{
905 struct loopback *loopback = snd_kcontrol_chip(kcontrol);
906
907 ucontrol->value.integer.value[0] =
908 loopback->setup[kcontrol->id.subdevice]
909 [kcontrol->id.device].rate;
910 return 0;
911}
912
913static int loopback_channels_info(struct snd_kcontrol *kcontrol,
914 struct snd_ctl_elem_info *uinfo)
915{
916 uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
917 uinfo->count = 1;
918 uinfo->value.integer.min = 1;
919 uinfo->value.integer.max = 1024;
920 uinfo->value.integer.step = 1;
921 return 0;
922}
923
924static int loopback_channels_get(struct snd_kcontrol *kcontrol,
925 struct snd_ctl_elem_value *ucontrol)
926{
927 struct loopback *loopback = snd_kcontrol_chip(kcontrol);
928
929 ucontrol->value.integer.value[0] =
930 loopback->setup[kcontrol->id.subdevice]
931 [kcontrol->id.device].channels;
932 return 0;
933}
934
935static struct snd_kcontrol_new loopback_controls[] __devinitdata = {
936{
937 .iface = SNDRV_CTL_ELEM_IFACE_PCM,
938 .name = "PCM Rate Shift 100000",
939 .info = loopback_rate_shift_info,
940 .get = loopback_rate_shift_get,
941 .put = loopback_rate_shift_put,
942},
943{
944 .iface = SNDRV_CTL_ELEM_IFACE_PCM,
945 .name = "PCM Notify",
946 .info = snd_ctl_boolean_mono_info,
947 .get = loopback_notify_get,
948 .put = loopback_notify_put,
949},
950#define ACTIVE_IDX 2
951{
952 .access = SNDRV_CTL_ELEM_ACCESS_READ,
953 .iface = SNDRV_CTL_ELEM_IFACE_PCM,
954 .name = "PCM Slave Active",
955 .info = snd_ctl_boolean_mono_info,
956 .get = loopback_active_get,
957},
958#define FORMAT_IDX 3
959{
960 .access = SNDRV_CTL_ELEM_ACCESS_READ,
961 .iface = SNDRV_CTL_ELEM_IFACE_PCM,
962 .name = "PCM Slave Format",
963 .info = loopback_format_info,
964 .get = loopback_format_get
965},
966#define RATE_IDX 4
967{
968 .access = SNDRV_CTL_ELEM_ACCESS_READ,
969 .iface = SNDRV_CTL_ELEM_IFACE_PCM,
970 .name = "PCM Slave Rate",
971 .info = loopback_rate_info,
972 .get = loopback_rate_get
973},
974#define CHANNELS_IDX 5
975{
976 .access = SNDRV_CTL_ELEM_ACCESS_READ,
977 .iface = SNDRV_CTL_ELEM_IFACE_PCM,
978 .name = "PCM Slave Channels",
979 .info = loopback_channels_info,
980 .get = loopback_channels_get
981}
982};
983
984static int __devinit loopback_mixer_new(struct loopback *loopback, int notify)
985{
986 struct snd_card *card = loopback->card;
987 struct snd_pcm *pcm;
988 struct snd_kcontrol *kctl;
989 struct loopback_setup *setup;
990 int err, dev, substr, substr_count, idx;
991
992 strcpy(card->mixername, "Loopback Mixer");
993 for (dev = 0; dev < 2; dev++) {
994 pcm = loopback->pcm[dev];
995 substr_count =
996 pcm->streams[SNDRV_PCM_STREAM_CAPTURE].substream_count;
997 for (substr = 0; substr < substr_count; substr++) {
998 setup = &loopback->setup[substr][dev];
999 setup->notify = notify;
1000 setup->rate_shift = NO_PITCH;
1001 setup->format = SNDRV_PCM_FORMAT_S16_LE;
1002 setup->rate = 48000;
1003 setup->channels = 2;
1004 for (idx = 0; idx < ARRAY_SIZE(loopback_controls);
1005 idx++) {
1006 kctl = snd_ctl_new1(&loopback_controls[idx],
1007 loopback);
1008 if (!kctl)
1009 return -ENOMEM;
1010 kctl->id.device = dev;
1011 kctl->id.subdevice = substr;
1012 switch (idx) {
1013 case ACTIVE_IDX:
1014 setup->active_id = kctl->id;
1015 break;
1016 case FORMAT_IDX:
1017 setup->format_id = kctl->id;
1018 break;
1019 case RATE_IDX:
1020 setup->rate_id = kctl->id;
1021 break;
1022 case CHANNELS_IDX:
1023 setup->channels_id = kctl->id;
1024 break;
1025 default:
1026 break;
1027 }
1028 err = snd_ctl_add(card, kctl);
1029 if (err < 0)
1030 return err;
1031 }
1032 }
1033 }
1034 return 0;
1035}
1036
1037#ifdef CONFIG_PROC_FS
1038
1039static void print_dpcm_info(struct snd_info_buffer *buffer,
1040 struct loopback_pcm *dpcm,
1041 const char *id)
1042{
1043 snd_iprintf(buffer, " %s\n", id);
1044 if (dpcm == NULL) {
1045 snd_iprintf(buffer, " inactive\n");
1046 return;
1047 }
1048 snd_iprintf(buffer, " buffer_size:\t%u\n", dpcm->pcm_buffer_size);
1049 snd_iprintf(buffer, " buffer_pos:\t\t%u\n", dpcm->buf_pos);
1050 snd_iprintf(buffer, " silent_size:\t%u\n", dpcm->silent_size);
1051 snd_iprintf(buffer, " period_size:\t%u\n", dpcm->pcm_period_size);
1052 snd_iprintf(buffer, " bytes_per_sec:\t%u\n", dpcm->pcm_bps);
1053 snd_iprintf(buffer, " sample_align:\t%u\n", dpcm->pcm_salign);
1054 snd_iprintf(buffer, " rate_shift:\t\t%u\n", dpcm->pcm_rate_shift);
1055 snd_iprintf(buffer, " update_pending:\t%u\n",
1056 dpcm->period_update_pending);
1057 snd_iprintf(buffer, " irq_pos:\t\t%u\n", dpcm->irq_pos);
1058 snd_iprintf(buffer, " period_frac:\t%u\n", dpcm->period_size_frac);
1059 snd_iprintf(buffer, " last_jiffies:\t%lu (%lu)\n",
1060 dpcm->last_jiffies, jiffies);
1061 snd_iprintf(buffer, " timer_expires:\t%lu\n", dpcm->timer.expires);
1062}
1063
1064static void print_substream_info(struct snd_info_buffer *buffer,
1065 struct loopback *loopback,
1066 int sub,
1067 int num)
1068{
1069 struct loopback_cable *cable = loopback->cables[sub][num];
1070
1071 snd_iprintf(buffer, "Cable %i substream %i:\n", num, sub);
1072 if (cable == NULL) {
1073 snd_iprintf(buffer, " inactive\n");
1074 return;
1075 }
1076 snd_iprintf(buffer, " valid: %u\n", cable->valid);
1077 snd_iprintf(buffer, " running: %u\n", cable->running);
1078 snd_iprintf(buffer, " pause: %u\n", cable->pause);
1079 print_dpcm_info(buffer, cable->streams[0], "Playback");
1080 print_dpcm_info(buffer, cable->streams[1], "Capture");
1081}
1082
1083static void print_cable_info(struct snd_info_entry *entry,
1084 struct snd_info_buffer *buffer)
1085{
1086 struct loopback *loopback = entry->private_data;
1087 int sub, num;
1088
1089 mutex_lock(&loopback->cable_lock);
1090 num = entry->name[strlen(entry->name)-1];
1091 num = num == '0' ? 0 : 1;
1092 for (sub = 0; sub < MAX_PCM_SUBSTREAMS; sub++)
1093 print_substream_info(buffer, loopback, sub, num);
1094 mutex_unlock(&loopback->cable_lock);
1095}
1096
1097static int __devinit loopback_proc_new(struct loopback *loopback, int cidx)
1098{
1099 char name[32];
1100 struct snd_info_entry *entry;
1101 int err;
1102
1103 snprintf(name, sizeof(name), "cable#%d", cidx);
1104 err = snd_card_proc_new(loopback->card, name, &entry);
1105 if (err < 0)
1106 return err;
1107
1108 snd_info_set_text_ops(entry, loopback, print_cable_info);
1109 return 0;
1110}
1111
1112#else /* !CONFIG_PROC_FS */
1113
1114#define loopback_proc_new(loopback, cidx) do { } while (0)
1115
1116#endif
1117
1118static int __devinit loopback_probe(struct platform_device *devptr)
1119{
1120 struct snd_card *card;
1121 struct loopback *loopback;
1122 int dev = devptr->id;
1123 int err;
1124
1125 err = snd_card_create(index[dev], id[dev], THIS_MODULE,
1126 sizeof(struct loopback), &card);
1127 if (err < 0)
1128 return err;
1129 loopback = card->private_data;
1130
1131 if (pcm_substreams[dev] < 1)
1132 pcm_substreams[dev] = 1;
1133 if (pcm_substreams[dev] > MAX_PCM_SUBSTREAMS)
1134 pcm_substreams[dev] = MAX_PCM_SUBSTREAMS;
1135
1136 loopback->card = card;
1137 mutex_init(&loopback->cable_lock);
1138
1139 err = loopback_pcm_new(loopback, 0, pcm_substreams[dev]);
1140 if (err < 0)
1141 goto __nodev;
1142 err = loopback_pcm_new(loopback, 1, pcm_substreams[dev]);
1143 if (err < 0)
1144 goto __nodev;
1145 err = loopback_mixer_new(loopback, pcm_notify[dev] ? 1 : 0);
1146 if (err < 0)
1147 goto __nodev;
1148 loopback_proc_new(loopback, 0);
1149 loopback_proc_new(loopback, 1);
1150 strcpy(card->driver, "Loopback");
1151 strcpy(card->shortname, "Loopback");
1152 sprintf(card->longname, "Loopback %i", dev + 1);
1153 err = snd_card_register(card);
1154 if (!err) {
1155 platform_set_drvdata(devptr, card);
1156 return 0;
1157 }
1158 __nodev:
1159 snd_card_free(card);
1160 return err;
1161}
1162
1163static int __devexit loopback_remove(struct platform_device *devptr)
1164{
1165 snd_card_free(platform_get_drvdata(devptr));
1166 platform_set_drvdata(devptr, NULL);
1167 return 0;
1168}
1169
1170#ifdef CONFIG_PM
1171static int loopback_suspend(struct platform_device *pdev,
1172 pm_message_t state)
1173{
1174 struct snd_card *card = platform_get_drvdata(pdev);
1175 struct loopback *loopback = card->private_data;
1176
1177 snd_power_change_state(card, SNDRV_CTL_POWER_D3hot);
1178
1179 snd_pcm_suspend_all(loopback->pcm[0]);
1180 snd_pcm_suspend_all(loopback->pcm[1]);
1181 return 0;
1182}
1183
1184static int loopback_resume(struct platform_device *pdev)
1185{
1186 struct snd_card *card = platform_get_drvdata(pdev);
1187
1188 snd_power_change_state(card, SNDRV_CTL_POWER_D0);
1189 return 0;
1190}
1191#endif
1192
1193#define SND_LOOPBACK_DRIVER "snd_aloop"
1194
1195static struct platform_driver loopback_driver = {
1196 .probe = loopback_probe,
1197 .remove = __devexit_p(loopback_remove),
1198#ifdef CONFIG_PM
1199 .suspend = loopback_suspend,
1200 .resume = loopback_resume,
1201#endif
1202 .driver = {
1203 .name = SND_LOOPBACK_DRIVER
1204 },
1205};
1206
1207static void loopback_unregister_all(void)
1208{
1209 int i;
1210
1211 for (i = 0; i < ARRAY_SIZE(devices); ++i)
1212 platform_device_unregister(devices[i]);
1213 platform_driver_unregister(&loopback_driver);
1214}
1215
1216static int __init alsa_card_loopback_init(void)
1217{
1218 int i, err, cards;
1219
1220 err = platform_driver_register(&loopback_driver);
1221 if (err < 0)
1222 return err;
1223
1224
1225 cards = 0;
1226 for (i = 0; i < SNDRV_CARDS; i++) {
1227 struct platform_device *device;
1228 if (!enable[i])
1229 continue;
1230 device = platform_device_register_simple(SND_LOOPBACK_DRIVER,
1231 i, NULL, 0);
1232 if (IS_ERR(device))
1233 continue;
1234 if (!platform_get_drvdata(device)) {
1235 platform_device_unregister(device);
1236 continue;
1237 }
1238 devices[i] = device;
1239 cards++;
1240 }
1241 if (!cards) {
1242#ifdef MODULE
1243 printk(KERN_ERR "aloop: No loopback enabled\n");
1244#endif
1245 loopback_unregister_all();
1246 return -ENODEV;
1247 }
1248 return 0;
1249}
1250
1251static void __exit alsa_card_loopback_exit(void)
1252{
1253 loopback_unregister_all();
1254}
1255
1256module_init(alsa_card_loopback_init)
1257module_exit(alsa_card_loopback_exit)
diff --git a/sound/drivers/ml403-ac97cr.c b/sound/drivers/ml403-ac97cr.c
index a1282c1c0591..5cfcb908c430 100644
--- a/sound/drivers/ml403-ac97cr.c
+++ b/sound/drivers/ml403-ac97cr.c
@@ -1143,8 +1143,8 @@ snd_ml403_ac97cr_create(struct snd_card *card, struct platform_device *pfdev,
1143 (resource->start) + 1); 1143 (resource->start) + 1);
1144 if (ml403_ac97cr->port == NULL) { 1144 if (ml403_ac97cr->port == NULL) {
1145 snd_printk(KERN_ERR SND_ML403_AC97CR_DRIVER ": " 1145 snd_printk(KERN_ERR SND_ML403_AC97CR_DRIVER ": "
1146 "unable to remap memory region (%x to %x)\n", 1146 "unable to remap memory region (%pR)\n",
1147 resource->start, resource->end); 1147 resource);
1148 snd_ml403_ac97cr_free(ml403_ac97cr); 1148 snd_ml403_ac97cr_free(ml403_ac97cr);
1149 return -EBUSY; 1149 return -EBUSY;
1150 } 1150 }
diff --git a/sound/drivers/mtpav.c b/sound/drivers/mtpav.c
index da03597fc893..5c426df87678 100644
--- a/sound/drivers/mtpav.c
+++ b/sound/drivers/mtpav.c
@@ -55,14 +55,13 @@
55#include <linux/err.h> 55#include <linux/err.h>
56#include <linux/platform_device.h> 56#include <linux/platform_device.h>
57#include <linux/ioport.h> 57#include <linux/ioport.h>
58#include <linux/io.h>
58#include <linux/moduleparam.h> 59#include <linux/moduleparam.h>
59#include <sound/core.h> 60#include <sound/core.h>
60#include <sound/initval.h> 61#include <sound/initval.h>
61#include <sound/rawmidi.h> 62#include <sound/rawmidi.h>
62#include <linux/delay.h> 63#include <linux/delay.h>
63 64
64#include <asm/io.h>
65
66/* 65/*
67 * globals 66 * globals
68 */ 67 */
diff --git a/sound/drivers/pcm-indirect2.c b/sound/drivers/pcm-indirect2.c
index 3c93c23e4883..e73fafd761b3 100644
--- a/sound/drivers/pcm-indirect2.c
+++ b/sound/drivers/pcm-indirect2.c
@@ -264,7 +264,7 @@ snd_pcm_indirect2_playback_transfer(struct snd_pcm_substream *substream,
264 if (diff < -(snd_pcm_sframes_t) (runtime->boundary / 2)) 264 if (diff < -(snd_pcm_sframes_t) (runtime->boundary / 2))
265 diff += runtime->boundary; 265 diff += runtime->boundary;
266 /* number of bytes "added" by ALSA increases the number of 266 /* number of bytes "added" by ALSA increases the number of
267 * bytes which are ready to "be transfered to HW"/"played" 267 * bytes which are ready to "be transferred to HW"/"played"
268 * Then, set rec->appl_ptr to not count bytes twice next time. 268 * Then, set rec->appl_ptr to not count bytes twice next time.
269 */ 269 */
270 rec->sw_ready += (int)frames_to_bytes(runtime, diff); 270 rec->sw_ready += (int)frames_to_bytes(runtime, diff);
@@ -330,7 +330,7 @@ snd_pcm_indirect2_playback_transfer(struct snd_pcm_substream *substream,
330 /* copy bytes from intermediate buffer position sw_data to the 330 /* copy bytes from intermediate buffer position sw_data to the
331 * HW and return number of bytes actually written 331 * HW and return number of bytes actually written
332 * Furthermore, set hw_ready to 0, if the fifo isn't empty 332 * Furthermore, set hw_ready to 0, if the fifo isn't empty
333 * now => more could be transfered to fifo 333 * now => more could be transferred to fifo
334 */ 334 */
335 bytes = copy(substream, rec, bytes); 335 bytes = copy(substream, rec, bytes);
336 rec->bytes2hw += bytes; 336 rec->bytes2hw += bytes;
diff --git a/sound/drivers/virmidi.c b/sound/drivers/virmidi.c
index 0e631c3221e3..f4cd49336f33 100644
--- a/sound/drivers/virmidi.c
+++ b/sound/drivers/virmidi.c
@@ -94,7 +94,7 @@ static int __devinit snd_virmidi_probe(struct platform_device *devptr)
94 sizeof(struct snd_card_virmidi), &card); 94 sizeof(struct snd_card_virmidi), &card);
95 if (err < 0) 95 if (err < 0)
96 return err; 96 return err;
97 vmidi = (struct snd_card_virmidi *)card->private_data; 97 vmidi = card->private_data;
98 vmidi->card = card; 98 vmidi->card = card;
99 99
100 if (midi_devs[dev] > MAX_MIDI_DEVICES) { 100 if (midi_devs[dev] > MAX_MIDI_DEVICES) {
diff --git a/sound/drivers/vx/vx_pcm.c b/sound/drivers/vx/vx_pcm.c
index 35a2f71a6af5..5e897b236cec 100644
--- a/sound/drivers/vx/vx_pcm.c
+++ b/sound/drivers/vx/vx_pcm.c
@@ -1189,7 +1189,7 @@ void vx_pcm_update_intr(struct vx_core *chip, unsigned int events)
1189 1189
1190 1190
1191/* 1191/*
1192 * vx_init_audio_io - check the availabe audio i/o and allocate pipe arrays 1192 * vx_init_audio_io - check the available audio i/o and allocate pipe arrays
1193 */ 1193 */
1194static int vx_init_audio_io(struct vx_core *chip) 1194static int vx_init_audio_io(struct vx_core *chip)
1195{ 1195{