blob: 2f208aaa54cf75c3aec594c3430e126db2aff4bc [file] [log] [blame]
Thomas Gleixner1a59d1b82019-05-27 08:55:05 +02001// SPDX-License-Identifier: GPL-2.0-or-later
Jaroslav Kysela597603d2010-08-09 14:21:11 +02002/*
3 * Loopback soundcard
4 *
5 * Original code:
6 * Copyright (c) by Jaroslav Kysela <perex@perex.cz>
7 *
8 * More accurate positioning and full-duplex support:
9 * Copyright (c) Ahmet İnan <ainan at mathematik.uni-freiburg.de>
10 *
11 * Major (almost complete) rewrite:
12 * Copyright (c) by Takashi Iwai <tiwai@suse.de>
13 *
14 * A next major update in 2010 (separate timers for playback and capture):
15 * Copyright (c) Jaroslav Kysela <perex@perex.cz>
Jaroslav Kysela597603d2010-08-09 14:21:11 +020016 */
17
18#include <linux/init.h>
19#include <linux/jiffies.h>
20#include <linux/slab.h>
21#include <linux/time.h>
22#include <linux/wait.h>
Paul Gortmaker65a77212011-07-15 13:13:37 -040023#include <linux/module.h>
Jaroslav Kysela597603d2010-08-09 14:21:11 +020024#include <linux/platform_device.h>
25#include <sound/core.h>
26#include <sound/control.h>
27#include <sound/pcm.h>
Takashi Iwaib088b532018-01-05 16:15:33 +010028#include <sound/pcm_params.h>
Jaroslav Kyselae74670b2010-10-18 09:43:10 +020029#include <sound/info.h>
Jaroslav Kysela597603d2010-08-09 14:21:11 +020030#include <sound/initval.h>
31
32MODULE_AUTHOR("Jaroslav Kysela <perex@perex.cz>");
33MODULE_DESCRIPTION("A loopback soundcard");
34MODULE_LICENSE("GPL");
35MODULE_SUPPORTED_DEVICE("{{ALSA,Loopback soundcard}}");
36
37#define MAX_PCM_SUBSTREAMS 8
38
39static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX; /* Index 0-MAX */
40static char *id[SNDRV_CARDS] = SNDRV_DEFAULT_STR; /* ID for this card */
Rusty Russella67ff6a2011-12-15 13:49:36 +103041static bool enable[SNDRV_CARDS] = {1, [1 ... (SNDRV_CARDS - 1)] = 0};
Jaroslav Kysela597603d2010-08-09 14:21:11 +020042static int pcm_substreams[SNDRV_CARDS] = {[0 ... (SNDRV_CARDS - 1)] = 8};
43static int pcm_notify[SNDRV_CARDS];
44
45module_param_array(index, int, NULL, 0444);
46MODULE_PARM_DESC(index, "Index value for loopback soundcard.");
47module_param_array(id, charp, NULL, 0444);
48MODULE_PARM_DESC(id, "ID string for loopback soundcard.");
49module_param_array(enable, bool, NULL, 0444);
50MODULE_PARM_DESC(enable, "Enable this loopback soundcard.");
51module_param_array(pcm_substreams, int, NULL, 0444);
52MODULE_PARM_DESC(pcm_substreams, "PCM substreams # (1-8) for loopback driver.");
53module_param_array(pcm_notify, int, NULL, 0444);
54MODULE_PARM_DESC(pcm_notify, "Break capture when PCM format/rate/channels changes.");
55
56#define NO_PITCH 100000
57
Timo Wischer133f3752019-11-20 11:49:51 -060058struct loopback_cable;
Jaroslav Kysela597603d2010-08-09 14:21:11 +020059struct loopback_pcm;
60
Timo Wischer133f3752019-11-20 11:49:51 -060061struct loopback_ops {
62 /* optional
63 * call in loopback->cable_lock
64 */
65 int (*open)(struct loopback_pcm *dpcm);
66 /* required
67 * call in cable->lock
68 */
69 int (*start)(struct loopback_pcm *dpcm);
70 /* required
71 * call in cable->lock
72 */
73 int (*stop)(struct loopback_pcm *dpcm);
74 /* optional */
75 int (*stop_sync)(struct loopback_pcm *dpcm);
76 /* optional */
77 int (*close_substream)(struct loopback_pcm *dpcm);
78 /* optional
79 * call in loopback->cable_lock
80 */
81 int (*close_cable)(struct loopback_pcm *dpcm);
82 /* optional
83 * call in cable->lock
84 */
85 unsigned int (*pos_update)(struct loopback_cable *cable);
86 /* optional */
87 void (*dpcm_info)(struct loopback_pcm *dpcm,
88 struct snd_info_buffer *buffer);
89};
90
Jaroslav Kysela597603d2010-08-09 14:21:11 +020091struct loopback_cable {
92 spinlock_t lock;
93 struct loopback_pcm *streams[2];
94 struct snd_pcm_hardware hw;
95 /* flags */
96 unsigned int valid;
97 unsigned int running;
Jaroslav Kysela5de9e452010-10-20 09:33:03 +020098 unsigned int pause;
Timo Wischer133f3752019-11-20 11:49:51 -060099 /* timer specific */
100 struct loopback_ops *ops;
Jaroslav Kysela597603d2010-08-09 14:21:11 +0200101};
102
103struct loopback_setup {
104 unsigned int notify: 1;
105 unsigned int rate_shift;
106 unsigned int format;
107 unsigned int rate;
108 unsigned int channels;
109 struct snd_ctl_elem_id active_id;
110 struct snd_ctl_elem_id format_id;
111 struct snd_ctl_elem_id rate_id;
112 struct snd_ctl_elem_id channels_id;
113};
114
115struct loopback {
116 struct snd_card *card;
117 struct mutex cable_lock;
118 struct loopback_cable *cables[MAX_PCM_SUBSTREAMS][2];
119 struct snd_pcm *pcm[2];
120 struct loopback_setup setup[MAX_PCM_SUBSTREAMS][2];
121};
122
123struct loopback_pcm {
124 struct loopback *loopback;
125 struct snd_pcm_substream *substream;
126 struct loopback_cable *cable;
127 unsigned int pcm_buffer_size;
128 unsigned int buf_pos; /* position in buffer */
129 unsigned int silent_size;
130 /* PCM parameters */
131 unsigned int pcm_period_size;
132 unsigned int pcm_bps; /* bytes per second */
133 unsigned int pcm_salign; /* bytes per sample * channels */
134 unsigned int pcm_rate_shift; /* rate shift value */
135 /* flags */
136 unsigned int period_update_pending :1;
137 /* timer stuff */
Timo Wischer97dda3d2019-11-20 11:49:49 -0600138 unsigned int irq_pos; /* fractional IRQ position in jiffies
139 * ticks
140 */
141 unsigned int period_size_frac; /* period size in jiffies ticks */
Jaroslav Kyselab0125132012-05-13 13:39:45 +0200142 unsigned int last_drift;
Jaroslav Kysela597603d2010-08-09 14:21:11 +0200143 unsigned long last_jiffies;
144 struct timer_list timer;
145};
146
147static struct platform_device *devices[SNDRV_CARDS];
148
149static inline unsigned int byte_pos(struct loopback_pcm *dpcm, unsigned int x)
150{
151 if (dpcm->pcm_rate_shift == NO_PITCH) {
152 x /= HZ;
153 } else {
154 x = div_u64(NO_PITCH * (unsigned long long)x,
155 HZ * (unsigned long long)dpcm->pcm_rate_shift);
156 }
157 return x - (x % dpcm->pcm_salign);
158}
159
160static inline unsigned int frac_pos(struct loopback_pcm *dpcm, unsigned int x)
161{
162 if (dpcm->pcm_rate_shift == NO_PITCH) { /* no pitch */
163 return x * HZ;
164 } else {
165 x = div_u64(dpcm->pcm_rate_shift * (unsigned long long)x * HZ,
166 NO_PITCH);
167 }
168 return x;
169}
170
171static inline struct loopback_setup *get_setup(struct loopback_pcm *dpcm)
172{
173 int device = dpcm->substream->pstr->pcm->device;
174
175 if (dpcm->substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
176 device ^= 1;
177 return &dpcm->loopback->setup[dpcm->substream->number][device];
178}
179
180static inline unsigned int get_notify(struct loopback_pcm *dpcm)
181{
182 return get_setup(dpcm)->notify;
183}
184
185static inline unsigned int get_rate_shift(struct loopback_pcm *dpcm)
186{
187 return get_setup(dpcm)->rate_shift;
188}
189
Takashi Iwai999fc9f2012-10-21 10:53:14 +0200190/* call in cable->lock */
Timo Wischer8e3bf7c2019-11-20 11:49:52 -0600191static int loopback_jiffies_timer_start(struct loopback_pcm *dpcm)
Jaroslav Kysela597603d2010-08-09 14:21:11 +0200192{
193 unsigned long tick;
194 unsigned int rate_shift = get_rate_shift(dpcm);
195
196 if (rate_shift != dpcm->pcm_rate_shift) {
197 dpcm->pcm_rate_shift = rate_shift;
198 dpcm->period_size_frac = frac_pos(dpcm, dpcm->pcm_period_size);
199 }
Jaroslav Kysela0db71022010-10-14 21:46:12 +0200200 if (dpcm->period_size_frac <= dpcm->irq_pos) {
201 dpcm->irq_pos %= dpcm->period_size_frac;
202 dpcm->period_update_pending = 1;
203 }
Jaroslav Kysela597603d2010-08-09 14:21:11 +0200204 tick = dpcm->period_size_frac - dpcm->irq_pos;
205 tick = (tick + dpcm->pcm_bps - 1) / dpcm->pcm_bps;
Takashi Iwaidb974552015-01-19 11:27:31 +0100206 mod_timer(&dpcm->timer, jiffies + tick);
Timo Wischer09419f12019-11-20 11:49:50 -0600207
208 return 0;
Jaroslav Kysela597603d2010-08-09 14:21:11 +0200209}
210
Takashi Iwai999fc9f2012-10-21 10:53:14 +0200211/* call in cable->lock */
Timo Wischer8e3bf7c2019-11-20 11:49:52 -0600212static inline int loopback_jiffies_timer_stop(struct loopback_pcm *dpcm)
Jaroslav Kysela597603d2010-08-09 14:21:11 +0200213{
214 del_timer(&dpcm->timer);
Jaroslav Kyselae74670b2010-10-18 09:43:10 +0200215 dpcm->timer.expires = 0;
Timo Wischer09419f12019-11-20 11:49:50 -0600216
217 return 0;
Jaroslav Kysela597603d2010-08-09 14:21:11 +0200218}
219
Timo Wischer8e3bf7c2019-11-20 11:49:52 -0600220static inline int loopback_jiffies_timer_stop_sync(struct loopback_pcm *dpcm)
Takashi Iwai67a01af2018-03-22 08:56:06 +0100221{
222 del_timer_sync(&dpcm->timer);
Timo Wischer09419f12019-11-20 11:49:50 -0600223
224 return 0;
Takashi Iwai67a01af2018-03-22 08:56:06 +0100225}
226
Jaroslav Kysela597603d2010-08-09 14:21:11 +0200227#define CABLE_VALID_PLAYBACK (1 << SNDRV_PCM_STREAM_PLAYBACK)
228#define CABLE_VALID_CAPTURE (1 << SNDRV_PCM_STREAM_CAPTURE)
229#define CABLE_VALID_BOTH (CABLE_VALID_PLAYBACK|CABLE_VALID_CAPTURE)
230
231static int loopback_check_format(struct loopback_cable *cable, int stream)
232{
Jaroslav Kyselab1c73fc2010-10-11 10:45:00 +0200233 struct snd_pcm_runtime *runtime, *cruntime;
Jaroslav Kysela597603d2010-08-09 14:21:11 +0200234 struct loopback_setup *setup;
235 struct snd_card *card;
236 int check;
237
238 if (cable->valid != CABLE_VALID_BOTH) {
239 if (stream == SNDRV_PCM_STREAM_PLAYBACK)
240 goto __notify;
241 return 0;
242 }
243 runtime = cable->streams[SNDRV_PCM_STREAM_PLAYBACK]->
244 substream->runtime;
Jaroslav Kyselab1c73fc2010-10-11 10:45:00 +0200245 cruntime = cable->streams[SNDRV_PCM_STREAM_CAPTURE]->
246 substream->runtime;
247 check = runtime->format != cruntime->format ||
248 runtime->rate != cruntime->rate ||
249 runtime->channels != cruntime->channels;
Jaroslav Kysela597603d2010-08-09 14:21:11 +0200250 if (!check)
251 return 0;
252 if (stream == SNDRV_PCM_STREAM_CAPTURE) {
253 return -EIO;
254 } else {
255 snd_pcm_stop(cable->streams[SNDRV_PCM_STREAM_CAPTURE]->
256 substream, SNDRV_PCM_STATE_DRAINING);
257 __notify:
258 runtime = cable->streams[SNDRV_PCM_STREAM_PLAYBACK]->
259 substream->runtime;
260 setup = get_setup(cable->streams[SNDRV_PCM_STREAM_PLAYBACK]);
261 card = cable->streams[SNDRV_PCM_STREAM_PLAYBACK]->loopback->card;
262 if (setup->format != runtime->format) {
263 snd_ctl_notify(card, SNDRV_CTL_EVENT_MASK_VALUE,
264 &setup->format_id);
265 setup->format = runtime->format;
266 }
267 if (setup->rate != runtime->rate) {
268 snd_ctl_notify(card, SNDRV_CTL_EVENT_MASK_VALUE,
269 &setup->rate_id);
270 setup->rate = runtime->rate;
271 }
272 if (setup->channels != runtime->channels) {
273 snd_ctl_notify(card, SNDRV_CTL_EVENT_MASK_VALUE,
274 &setup->channels_id);
275 setup->channels = runtime->channels;
276 }
277 }
278 return 0;
279}
280
281static void loopback_active_notify(struct loopback_pcm *dpcm)
282{
283 snd_ctl_notify(dpcm->loopback->card,
284 SNDRV_CTL_EVENT_MASK_VALUE,
285 &get_setup(dpcm)->active_id);
286}
287
288static int loopback_trigger(struct snd_pcm_substream *substream, int cmd)
289{
290 struct snd_pcm_runtime *runtime = substream->runtime;
291 struct loopback_pcm *dpcm = runtime->private_data;
292 struct loopback_cable *cable = dpcm->cable;
Timo Wischer09419f12019-11-20 11:49:50 -0600293 int err = 0, stream = 1 << substream->stream;
Jaroslav Kysela597603d2010-08-09 14:21:11 +0200294
295 switch (cmd) {
296 case SNDRV_PCM_TRIGGER_START:
297 err = loopback_check_format(cable, substream->stream);
298 if (err < 0)
299 return err;
300 dpcm->last_jiffies = jiffies;
301 dpcm->pcm_rate_shift = 0;
Jaroslav Kyselab0125132012-05-13 13:39:45 +0200302 dpcm->last_drift = 0;
Jaroslav Kyseladd04bb12010-10-20 08:27:02 +0200303 spin_lock(&cable->lock);
Jaroslav Kysela5de9e452010-10-20 09:33:03 +0200304 cable->running |= stream;
305 cable->pause &= ~stream;
Timo Wischer133f3752019-11-20 11:49:51 -0600306 err = cable->ops->start(dpcm);
Takashi Iwai999fc9f2012-10-21 10:53:14 +0200307 spin_unlock(&cable->lock);
Jaroslav Kysela597603d2010-08-09 14:21:11 +0200308 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
309 loopback_active_notify(dpcm);
310 break;
311 case SNDRV_PCM_TRIGGER_STOP:
Jaroslav Kyseladd04bb12010-10-20 08:27:02 +0200312 spin_lock(&cable->lock);
Jaroslav Kysela5de9e452010-10-20 09:33:03 +0200313 cable->running &= ~stream;
314 cable->pause &= ~stream;
Timo Wischer133f3752019-11-20 11:49:51 -0600315 err = cable->ops->stop(dpcm);
Takashi Iwai999fc9f2012-10-21 10:53:14 +0200316 spin_unlock(&cable->lock);
Jaroslav Kysela597603d2010-08-09 14:21:11 +0200317 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
318 loopback_active_notify(dpcm);
319 break;
Jaroslav Kysela5de9e452010-10-20 09:33:03 +0200320 case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
Takashi Iwaiedac8942013-02-04 10:28:15 +0100321 case SNDRV_PCM_TRIGGER_SUSPEND:
Jaroslav Kysela5de9e452010-10-20 09:33:03 +0200322 spin_lock(&cable->lock);
323 cable->pause |= stream;
Timo Wischer133f3752019-11-20 11:49:51 -0600324 err = cable->ops->stop(dpcm);
Takashi Iwai999fc9f2012-10-21 10:53:14 +0200325 spin_unlock(&cable->lock);
Robert Rosengren306a4f32018-03-26 07:24:49 +0200326 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
327 loopback_active_notify(dpcm);
Jaroslav Kysela5de9e452010-10-20 09:33:03 +0200328 break;
329 case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
Takashi Iwaiedac8942013-02-04 10:28:15 +0100330 case SNDRV_PCM_TRIGGER_RESUME:
Jaroslav Kysela5de9e452010-10-20 09:33:03 +0200331 spin_lock(&cable->lock);
332 dpcm->last_jiffies = jiffies;
333 cable->pause &= ~stream;
Timo Wischer133f3752019-11-20 11:49:51 -0600334 err = cable->ops->start(dpcm);
Takashi Iwai999fc9f2012-10-21 10:53:14 +0200335 spin_unlock(&cable->lock);
Robert Rosengren306a4f32018-03-26 07:24:49 +0200336 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
337 loopback_active_notify(dpcm);
Jaroslav Kysela5de9e452010-10-20 09:33:03 +0200338 break;
Jaroslav Kysela597603d2010-08-09 14:21:11 +0200339 default:
340 return -EINVAL;
341 }
Timo Wischer09419f12019-11-20 11:49:50 -0600342 return err;
Jaroslav Kysela597603d2010-08-09 14:21:11 +0200343}
344
Jaroslav Kyselab1c73fc2010-10-11 10:45:00 +0200345static void params_change(struct snd_pcm_substream *substream)
346{
347 struct snd_pcm_runtime *runtime = substream->runtime;
348 struct loopback_pcm *dpcm = runtime->private_data;
349 struct loopback_cable *cable = dpcm->cable;
350
Eldad Zack74c34ca2013-04-23 01:00:41 +0200351 cable->hw.formats = pcm_format_to_bits(runtime->format);
Jaroslav Kyselab1c73fc2010-10-11 10:45:00 +0200352 cable->hw.rate_min = runtime->rate;
353 cable->hw.rate_max = runtime->rate;
354 cable->hw.channels_min = runtime->channels;
355 cable->hw.channels_max = runtime->channels;
Jaroslav Kyselab1c73fc2010-10-11 10:45:00 +0200356}
357
Jaroslav Kysela597603d2010-08-09 14:21:11 +0200358static int loopback_prepare(struct snd_pcm_substream *substream)
359{
360 struct snd_pcm_runtime *runtime = substream->runtime;
361 struct loopback_pcm *dpcm = runtime->private_data;
362 struct loopback_cable *cable = dpcm->cable;
Timo Wischer09419f12019-11-20 11:49:50 -0600363 int err, bps, salign;
Jaroslav Kysela597603d2010-08-09 14:21:11 +0200364
Timo Wischer133f3752019-11-20 11:49:51 -0600365 if (cable->ops->stop_sync) {
366 err = cable->ops->stop_sync(dpcm);
367 if (err < 0)
368 return err;
369 }
Takashi Iwai67a01af2018-03-22 08:56:06 +0100370
Timo Wischer50e09082019-03-25 16:14:14 +0100371 salign = (snd_pcm_format_physical_width(runtime->format) *
Jaroslav Kysela597603d2010-08-09 14:21:11 +0200372 runtime->channels) / 8;
373 bps = salign * runtime->rate;
374 if (bps <= 0 || salign <= 0)
375 return -EINVAL;
376
377 dpcm->buf_pos = 0;
378 dpcm->pcm_buffer_size = frames_to_bytes(runtime, runtime->buffer_size);
379 if (substream->stream == SNDRV_PCM_STREAM_CAPTURE) {
380 /* clear capture buffer */
381 dpcm->silent_size = dpcm->pcm_buffer_size;
382 snd_pcm_format_set_silence(runtime->format, runtime->dma_area,
383 runtime->buffer_size * runtime->channels);
384 }
385
386 dpcm->irq_pos = 0;
387 dpcm->period_update_pending = 0;
388 dpcm->pcm_bps = bps;
389 dpcm->pcm_salign = salign;
390 dpcm->pcm_period_size = frames_to_bytes(runtime, runtime->period_size);
391
392 mutex_lock(&dpcm->loopback->cable_lock);
Jaroslav Kyselab1c73fc2010-10-11 10:45:00 +0200393 if (!(cable->valid & ~(1 << substream->stream)) ||
394 (get_setup(dpcm)->notify &&
395 substream->stream == SNDRV_PCM_STREAM_PLAYBACK))
396 params_change(substream);
Jaroslav Kysela597603d2010-08-09 14:21:11 +0200397 cable->valid |= 1 << substream->stream;
398 mutex_unlock(&dpcm->loopback->cable_lock);
399
400 return 0;
401}
402
403static void clear_capture_buf(struct loopback_pcm *dpcm, unsigned int bytes)
404{
405 struct snd_pcm_runtime *runtime = dpcm->substream->runtime;
406 char *dst = runtime->dma_area;
407 unsigned int dst_off = dpcm->buf_pos;
408
409 if (dpcm->silent_size >= dpcm->pcm_buffer_size)
410 return;
411 if (dpcm->silent_size + bytes > dpcm->pcm_buffer_size)
412 bytes = dpcm->pcm_buffer_size - dpcm->silent_size;
413
414 for (;;) {
415 unsigned int size = bytes;
416 if (dst_off + size > dpcm->pcm_buffer_size)
417 size = dpcm->pcm_buffer_size - dst_off;
418 snd_pcm_format_set_silence(runtime->format, dst + dst_off,
419 bytes_to_frames(runtime, size) *
420 runtime->channels);
421 dpcm->silent_size += size;
422 bytes -= size;
423 if (!bytes)
424 break;
425 dst_off = 0;
426 }
427}
428
429static void copy_play_buf(struct loopback_pcm *play,
430 struct loopback_pcm *capt,
431 unsigned int bytes)
432{
433 struct snd_pcm_runtime *runtime = play->substream->runtime;
Jaroslav Kysela20d9a262010-09-30 00:16:50 +0200434 char *src = runtime->dma_area;
Jaroslav Kysela597603d2010-08-09 14:21:11 +0200435 char *dst = capt->substream->runtime->dma_area;
436 unsigned int src_off = play->buf_pos;
437 unsigned int dst_off = capt->buf_pos;
438 unsigned int clear_bytes = 0;
439
440 /* check if playback is draining, trim the capture copy size
441 * when our pointer is at the end of playback ring buffer */
442 if (runtime->status->state == SNDRV_PCM_STATE_DRAINING &&
443 snd_pcm_playback_hw_avail(runtime) < runtime->buffer_size) {
444 snd_pcm_uframes_t appl_ptr, appl_ptr1, diff;
445 appl_ptr = appl_ptr1 = runtime->control->appl_ptr;
446 appl_ptr1 -= appl_ptr1 % runtime->buffer_size;
447 appl_ptr1 += play->buf_pos / play->pcm_salign;
448 if (appl_ptr < appl_ptr1)
449 appl_ptr1 -= runtime->buffer_size;
450 diff = (appl_ptr - appl_ptr1) * play->pcm_salign;
451 if (diff < bytes) {
452 clear_bytes = bytes - diff;
453 bytes = diff;
454 }
455 }
456
457 for (;;) {
458 unsigned int size = bytes;
459 if (src_off + size > play->pcm_buffer_size)
460 size = play->pcm_buffer_size - src_off;
461 if (dst_off + size > capt->pcm_buffer_size)
462 size = capt->pcm_buffer_size - dst_off;
463 memcpy(dst + dst_off, src + src_off, size);
464 capt->silent_size = 0;
465 bytes -= size;
466 if (!bytes)
467 break;
468 src_off = (src_off + size) % play->pcm_buffer_size;
469 dst_off = (dst_off + size) % capt->pcm_buffer_size;
470 }
471
Jaroslav Kysela20d9a262010-09-30 00:16:50 +0200472 if (clear_bytes > 0) {
Jaroslav Kysela597603d2010-08-09 14:21:11 +0200473 clear_capture_buf(capt, clear_bytes);
Jaroslav Kysela20d9a262010-09-30 00:16:50 +0200474 capt->silent_size = 0;
475 }
Jaroslav Kysela597603d2010-08-09 14:21:11 +0200476}
477
Jaroslav Kyselab0125132012-05-13 13:39:45 +0200478static inline unsigned int bytepos_delta(struct loopback_pcm *dpcm,
479 unsigned int jiffies_delta)
Jaroslav Kysela597603d2010-08-09 14:21:11 +0200480{
Jaroslav Kysela597603d2010-08-09 14:21:11 +0200481 unsigned long last_pos;
Jaroslav Kyselab0125132012-05-13 13:39:45 +0200482 unsigned int delta;
Jaroslav Kysela597603d2010-08-09 14:21:11 +0200483
484 last_pos = byte_pos(dpcm, dpcm->irq_pos);
Jaroslav Kyselab0125132012-05-13 13:39:45 +0200485 dpcm->irq_pos += jiffies_delta * dpcm->pcm_bps;
486 delta = byte_pos(dpcm, dpcm->irq_pos) - last_pos;
487 if (delta >= dpcm->last_drift)
488 delta -= dpcm->last_drift;
489 dpcm->last_drift = 0;
Jaroslav Kysela597603d2010-08-09 14:21:11 +0200490 if (dpcm->irq_pos >= dpcm->period_size_frac) {
491 dpcm->irq_pos %= dpcm->period_size_frac;
492 dpcm->period_update_pending = 1;
493 }
Jaroslav Kyselab0125132012-05-13 13:39:45 +0200494 return delta;
495}
496
497static inline void bytepos_finish(struct loopback_pcm *dpcm,
498 unsigned int delta)
499{
500 dpcm->buf_pos += delta;
501 dpcm->buf_pos %= dpcm->pcm_buffer_size;
Jaroslav Kysela597603d2010-08-09 14:21:11 +0200502}
503
Takashi Iwai999fc9f2012-10-21 10:53:14 +0200504/* call in cable->lock */
Timo Wischer8e3bf7c2019-11-20 11:49:52 -0600505static unsigned int loopback_jiffies_timer_pos_update
506 (struct loopback_cable *cable)
Jaroslav Kysela597603d2010-08-09 14:21:11 +0200507{
508 struct loopback_pcm *dpcm_play =
509 cable->streams[SNDRV_PCM_STREAM_PLAYBACK];
510 struct loopback_pcm *dpcm_capt =
511 cable->streams[SNDRV_PCM_STREAM_CAPTURE];
512 unsigned long delta_play = 0, delta_capt = 0;
Jaroslav Kyselab0125132012-05-13 13:39:45 +0200513 unsigned int running, count1, count2;
Jaroslav Kysela597603d2010-08-09 14:21:11 +0200514
Jaroslav Kysela5de9e452010-10-20 09:33:03 +0200515 running = cable->running ^ cable->pause;
Jaroslav Kyseladd04bb12010-10-20 08:27:02 +0200516 if (running & (1 << SNDRV_PCM_STREAM_PLAYBACK)) {
Jaroslav Kysela597603d2010-08-09 14:21:11 +0200517 delta_play = jiffies - dpcm_play->last_jiffies;
518 dpcm_play->last_jiffies += delta_play;
519 }
520
Jaroslav Kyseladd04bb12010-10-20 08:27:02 +0200521 if (running & (1 << SNDRV_PCM_STREAM_CAPTURE)) {
Jaroslav Kysela597603d2010-08-09 14:21:11 +0200522 delta_capt = jiffies - dpcm_capt->last_jiffies;
523 dpcm_capt->last_jiffies += delta_capt;
524 }
525
Takashi Iwai98d21df2011-03-18 07:31:53 +0100526 if (delta_play == 0 && delta_capt == 0)
527 goto unlock;
Jaroslav Kysela597603d2010-08-09 14:21:11 +0200528
529 if (delta_play > delta_capt) {
Jaroslav Kyselab0125132012-05-13 13:39:45 +0200530 count1 = bytepos_delta(dpcm_play, delta_play - delta_capt);
531 bytepos_finish(dpcm_play, count1);
Jaroslav Kysela597603d2010-08-09 14:21:11 +0200532 delta_play = delta_capt;
533 } else if (delta_play < delta_capt) {
Jaroslav Kyselab0125132012-05-13 13:39:45 +0200534 count1 = bytepos_delta(dpcm_capt, delta_capt - delta_play);
535 clear_capture_buf(dpcm_capt, count1);
536 bytepos_finish(dpcm_capt, count1);
Jaroslav Kysela597603d2010-08-09 14:21:11 +0200537 delta_capt = delta_play;
538 }
539
Takashi Iwai98d21df2011-03-18 07:31:53 +0100540 if (delta_play == 0 && delta_capt == 0)
541 goto unlock;
542
Jaroslav Kysela597603d2010-08-09 14:21:11 +0200543 /* note delta_capt == delta_play at this moment */
Jaroslav Kyselab0125132012-05-13 13:39:45 +0200544 count1 = bytepos_delta(dpcm_play, delta_play);
545 count2 = bytepos_delta(dpcm_capt, delta_capt);
546 if (count1 < count2) {
547 dpcm_capt->last_drift = count2 - count1;
548 count1 = count2;
549 } else if (count1 > count2) {
550 dpcm_play->last_drift = count1 - count2;
551 }
552 copy_play_buf(dpcm_play, dpcm_capt, count1);
553 bytepos_finish(dpcm_play, count1);
554 bytepos_finish(dpcm_capt, count1);
Takashi Iwai98d21df2011-03-18 07:31:53 +0100555 unlock:
Jaroslav Kyseladd04bb12010-10-20 08:27:02 +0200556 return running;
Jaroslav Kysela597603d2010-08-09 14:21:11 +0200557}
558
Timo Wischer8e3bf7c2019-11-20 11:49:52 -0600559static void loopback_jiffies_timer_function(struct timer_list *t)
Jaroslav Kysela597603d2010-08-09 14:21:11 +0200560{
Kees Cookbc47ba92017-10-24 08:34:29 -0700561 struct loopback_pcm *dpcm = from_timer(dpcm, t, timer);
Takashi Iwai999fc9f2012-10-21 10:53:14 +0200562 unsigned long flags;
Jaroslav Kysela597603d2010-08-09 14:21:11 +0200563
Takashi Iwai999fc9f2012-10-21 10:53:14 +0200564 spin_lock_irqsave(&dpcm->cable->lock, flags);
Timo Wischer8e3bf7c2019-11-20 11:49:52 -0600565 if (loopback_jiffies_timer_pos_update(dpcm->cable) &
566 (1 << dpcm->substream->stream)) {
567 loopback_jiffies_timer_start(dpcm);
Jaroslav Kyseladd04bb12010-10-20 08:27:02 +0200568 if (dpcm->period_update_pending) {
569 dpcm->period_update_pending = 0;
Takashi Iwai999fc9f2012-10-21 10:53:14 +0200570 spin_unlock_irqrestore(&dpcm->cable->lock, flags);
571 /* need to unlock before calling below */
Jaroslav Kysela597603d2010-08-09 14:21:11 +0200572 snd_pcm_period_elapsed(dpcm->substream);
Takashi Iwai999fc9f2012-10-21 10:53:14 +0200573 return;
Jaroslav Kyseladd04bb12010-10-20 08:27:02 +0200574 }
Jaroslav Kysela597603d2010-08-09 14:21:11 +0200575 }
Takashi Iwai999fc9f2012-10-21 10:53:14 +0200576 spin_unlock_irqrestore(&dpcm->cable->lock, flags);
Jaroslav Kysela597603d2010-08-09 14:21:11 +0200577}
578
Timo Wischer133f3752019-11-20 11:49:51 -0600579static void loopback_jiffies_timer_dpcm_info(struct loopback_pcm *dpcm,
580 struct snd_info_buffer *buffer)
581{
582 snd_iprintf(buffer, " update_pending:\t%u\n",
583 dpcm->period_update_pending);
584 snd_iprintf(buffer, " irq_pos:\t\t%u\n", dpcm->irq_pos);
585 snd_iprintf(buffer, " period_frac:\t%u\n", dpcm->period_size_frac);
586 snd_iprintf(buffer, " last_jiffies:\t%lu (%lu)\n",
587 dpcm->last_jiffies, jiffies);
588 snd_iprintf(buffer, " timer_expires:\t%lu\n", dpcm->timer.expires);
589}
590
Jaroslav Kysela597603d2010-08-09 14:21:11 +0200591static snd_pcm_uframes_t loopback_pointer(struct snd_pcm_substream *substream)
592{
593 struct snd_pcm_runtime *runtime = substream->runtime;
594 struct loopback_pcm *dpcm = runtime->private_data;
Takashi Iwai999fc9f2012-10-21 10:53:14 +0200595 snd_pcm_uframes_t pos;
Jaroslav Kysela597603d2010-08-09 14:21:11 +0200596
Takashi Iwai999fc9f2012-10-21 10:53:14 +0200597 spin_lock(&dpcm->cable->lock);
Timo Wischer133f3752019-11-20 11:49:51 -0600598 if (dpcm->cable->ops->pos_update)
599 dpcm->cable->ops->pos_update(dpcm->cable);
Takashi Iwai999fc9f2012-10-21 10:53:14 +0200600 pos = dpcm->buf_pos;
601 spin_unlock(&dpcm->cable->lock);
602 return bytes_to_frames(runtime, pos);
Jaroslav Kysela597603d2010-08-09 14:21:11 +0200603}
604
Bhumika Goyalb6c0b712017-08-17 14:45:51 +0530605static const struct snd_pcm_hardware loopback_pcm_hardware =
Jaroslav Kysela597603d2010-08-09 14:21:11 +0200606{
607 .info = (SNDRV_PCM_INFO_INTERLEAVED | SNDRV_PCM_INFO_MMAP |
Takashi Iwaiedac8942013-02-04 10:28:15 +0100608 SNDRV_PCM_INFO_MMAP_VALID | SNDRV_PCM_INFO_PAUSE |
609 SNDRV_PCM_INFO_RESUME),
Jaroslav Kysela597603d2010-08-09 14:21:11 +0200610 .formats = (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S16_BE |
Timo Wischer50e09082019-03-25 16:14:14 +0100611 SNDRV_PCM_FMTBIT_S24_LE | SNDRV_PCM_FMTBIT_S24_BE |
612 SNDRV_PCM_FMTBIT_S24_3LE | SNDRV_PCM_FMTBIT_S24_3BE |
Jaroslav Kysela597603d2010-08-09 14:21:11 +0200613 SNDRV_PCM_FMTBIT_S32_LE | SNDRV_PCM_FMTBIT_S32_BE |
614 SNDRV_PCM_FMTBIT_FLOAT_LE | SNDRV_PCM_FMTBIT_FLOAT_BE),
615 .rates = SNDRV_PCM_RATE_CONTINUOUS | SNDRV_PCM_RATE_8000_192000,
616 .rate_min = 8000,
617 .rate_max = 192000,
618 .channels_min = 1,
619 .channels_max = 32,
620 .buffer_bytes_max = 2 * 1024 * 1024,
621 .period_bytes_min = 64,
Jaroslav Kysela0db71022010-10-14 21:46:12 +0200622 /* note check overflow in frac_pos() using pcm_rate_shift before
623 changing period_bytes_max value */
624 .period_bytes_max = 1024 * 1024,
Jaroslav Kysela597603d2010-08-09 14:21:11 +0200625 .periods_min = 1,
626 .periods_max = 1024,
627 .fifo_size = 0,
628};
629
630static void loopback_runtime_free(struct snd_pcm_runtime *runtime)
631{
632 struct loopback_pcm *dpcm = runtime->private_data;
633 kfree(dpcm);
634}
635
636static int loopback_hw_params(struct snd_pcm_substream *substream,
637 struct snd_pcm_hw_params *params)
638{
Takashi Iwaib29e5ef2019-11-05 16:18:41 +0100639 return snd_pcm_lib_malloc_pages(substream, params_buffer_bytes(params));
Jaroslav Kysela597603d2010-08-09 14:21:11 +0200640}
641
642static int loopback_hw_free(struct snd_pcm_substream *substream)
643{
644 struct snd_pcm_runtime *runtime = substream->runtime;
645 struct loopback_pcm *dpcm = runtime->private_data;
646 struct loopback_cable *cable = dpcm->cable;
647
648 mutex_lock(&dpcm->loopback->cable_lock);
649 cable->valid &= ~(1 << substream->stream);
650 mutex_unlock(&dpcm->loopback->cable_lock);
Takashi Iwaib29e5ef2019-11-05 16:18:41 +0100651 return snd_pcm_lib_free_pages(substream);
Jaroslav Kysela597603d2010-08-09 14:21:11 +0200652}
653
654static unsigned int get_cable_index(struct snd_pcm_substream *substream)
655{
656 if (!substream->pcm->device)
657 return substream->stream;
658 else
659 return !substream->stream;
660}
661
Jaroslav Kyselab1c73fc2010-10-11 10:45:00 +0200662static int rule_format(struct snd_pcm_hw_params *params,
663 struct snd_pcm_hw_rule *rule)
664{
Takashi Iwai898dfe42018-01-04 17:38:54 +0100665 struct loopback_pcm *dpcm = rule->private;
666 struct loopback_cable *cable = dpcm->cable;
Takashi Iwaib088b532018-01-05 16:15:33 +0100667 struct snd_mask m;
Jaroslav Kyselab1c73fc2010-10-11 10:45:00 +0200668
Takashi Iwaib088b532018-01-05 16:15:33 +0100669 snd_mask_none(&m);
Takashi Iwai898dfe42018-01-04 17:38:54 +0100670 mutex_lock(&dpcm->loopback->cable_lock);
671 m.bits[0] = (u_int32_t)cable->hw.formats;
672 m.bits[1] = (u_int32_t)(cable->hw.formats >> 32);
673 mutex_unlock(&dpcm->loopback->cable_lock);
Takashi Iwaib088b532018-01-05 16:15:33 +0100674 return snd_mask_refine(hw_param_mask(params, rule->var), &m);
Jaroslav Kyselab1c73fc2010-10-11 10:45:00 +0200675}
676
677static int rule_rate(struct snd_pcm_hw_params *params,
678 struct snd_pcm_hw_rule *rule)
679{
Takashi Iwai898dfe42018-01-04 17:38:54 +0100680 struct loopback_pcm *dpcm = rule->private;
681 struct loopback_cable *cable = dpcm->cable;
Jaroslav Kyselab1c73fc2010-10-11 10:45:00 +0200682 struct snd_interval t;
683
Takashi Iwai898dfe42018-01-04 17:38:54 +0100684 mutex_lock(&dpcm->loopback->cable_lock);
685 t.min = cable->hw.rate_min;
686 t.max = cable->hw.rate_max;
687 mutex_unlock(&dpcm->loopback->cable_lock);
Jaroslav Kyselab1c73fc2010-10-11 10:45:00 +0200688 t.openmin = t.openmax = 0;
689 t.integer = 0;
690 return snd_interval_refine(hw_param_interval(params, rule->var), &t);
691}
692
693static int rule_channels(struct snd_pcm_hw_params *params,
694 struct snd_pcm_hw_rule *rule)
695{
Takashi Iwai898dfe42018-01-04 17:38:54 +0100696 struct loopback_pcm *dpcm = rule->private;
697 struct loopback_cable *cable = dpcm->cable;
Jaroslav Kyselab1c73fc2010-10-11 10:45:00 +0200698 struct snd_interval t;
699
Takashi Iwai898dfe42018-01-04 17:38:54 +0100700 mutex_lock(&dpcm->loopback->cable_lock);
701 t.min = cable->hw.channels_min;
702 t.max = cable->hw.channels_max;
703 mutex_unlock(&dpcm->loopback->cable_lock);
Jaroslav Kyselab1c73fc2010-10-11 10:45:00 +0200704 t.openmin = t.openmax = 0;
705 t.integer = 0;
706 return snd_interval_refine(hw_param_interval(params, rule->var), &t);
707}
708
Takashi Iwai96853472018-01-05 16:09:47 +0100709static void free_cable(struct snd_pcm_substream *substream)
710{
711 struct loopback *loopback = substream->private_data;
712 int dev = get_cable_index(substream);
713 struct loopback_cable *cable;
714
715 cable = loopback->cables[substream->number][dev];
716 if (!cable)
717 return;
718 if (cable->streams[!substream->stream]) {
719 /* other stream is still alive */
Takashi Iwai8e6b1a72018-03-22 10:40:27 +0100720 spin_lock_irq(&cable->lock);
Takashi Iwai96853472018-01-05 16:09:47 +0100721 cable->streams[substream->stream] = NULL;
Takashi Iwai8e6b1a72018-03-22 10:40:27 +0100722 spin_unlock_irq(&cable->lock);
Takashi Iwai96853472018-01-05 16:09:47 +0100723 } else {
Timo Wischer133f3752019-11-20 11:49:51 -0600724 struct loopback_pcm *dpcm = substream->runtime->private_data;
725
726 if (cable->ops && cable->ops->close_cable && dpcm)
727 cable->ops->close_cable(dpcm);
Takashi Iwai96853472018-01-05 16:09:47 +0100728 /* free the cable */
729 loopback->cables[substream->number][dev] = NULL;
730 kfree(cable);
731 }
732}
733
Timo Wischer133f3752019-11-20 11:49:51 -0600734static int loopback_jiffies_timer_open(struct loopback_pcm *dpcm)
735{
Timo Wischer8e3bf7c2019-11-20 11:49:52 -0600736 timer_setup(&dpcm->timer, loopback_jiffies_timer_function, 0);
Timo Wischer133f3752019-11-20 11:49:51 -0600737
738 return 0;
739}
740
741static struct loopback_ops loopback_jiffies_timer_ops = {
742 .open = loopback_jiffies_timer_open,
Timo Wischer8e3bf7c2019-11-20 11:49:52 -0600743 .start = loopback_jiffies_timer_start,
744 .stop = loopback_jiffies_timer_stop,
745 .stop_sync = loopback_jiffies_timer_stop_sync,
746 .close_substream = loopback_jiffies_timer_stop_sync,
747 .pos_update = loopback_jiffies_timer_pos_update,
Timo Wischer133f3752019-11-20 11:49:51 -0600748 .dpcm_info = loopback_jiffies_timer_dpcm_info,
749};
750
Jaroslav Kysela597603d2010-08-09 14:21:11 +0200751static int loopback_open(struct snd_pcm_substream *substream)
752{
753 struct snd_pcm_runtime *runtime = substream->runtime;
754 struct loopback *loopback = substream->private_data;
755 struct loopback_pcm *dpcm;
Takashi Iwai96853472018-01-05 16:09:47 +0100756 struct loopback_cable *cable = NULL;
Jaroslav Kysela597603d2010-08-09 14:21:11 +0200757 int err = 0;
758 int dev = get_cable_index(substream);
759
760 mutex_lock(&loopback->cable_lock);
761 dpcm = kzalloc(sizeof(*dpcm), GFP_KERNEL);
762 if (!dpcm) {
763 err = -ENOMEM;
764 goto unlock;
765 }
766 dpcm->loopback = loopback;
767 dpcm->substream = substream;
Jaroslav Kysela597603d2010-08-09 14:21:11 +0200768
769 cable = loopback->cables[substream->number][dev];
770 if (!cable) {
771 cable = kzalloc(sizeof(*cable), GFP_KERNEL);
772 if (!cable) {
Jaroslav Kysela597603d2010-08-09 14:21:11 +0200773 err = -ENOMEM;
774 goto unlock;
775 }
776 spin_lock_init(&cable->lock);
777 cable->hw = loopback_pcm_hardware;
Timo Wischer133f3752019-11-20 11:49:51 -0600778 cable->ops = &loopback_jiffies_timer_ops;
Jaroslav Kysela597603d2010-08-09 14:21:11 +0200779 loopback->cables[substream->number][dev] = cable;
780 }
781 dpcm->cable = cable;
Timo Wischer133f3752019-11-20 11:49:51 -0600782 runtime->private_data = dpcm;
783
784 if (cable->ops->open) {
785 err = cable->ops->open(dpcm);
786 if (err < 0)
787 goto unlock;
788 }
Jaroslav Kysela597603d2010-08-09 14:21:11 +0200789
790 snd_pcm_hw_constraint_integer(runtime, SNDRV_PCM_HW_PARAM_PERIODS);
791
Jaroslav Kyselab1c73fc2010-10-11 10:45:00 +0200792 /* use dynamic rules based on actual runtime->hw values */
793 /* note that the default rules created in the PCM midlevel code */
794 /* are cached -> they do not reflect the actual state */
795 err = snd_pcm_hw_rule_add(runtime, 0,
796 SNDRV_PCM_HW_PARAM_FORMAT,
Takashi Iwai898dfe42018-01-04 17:38:54 +0100797 rule_format, dpcm,
Jaroslav Kyselab1c73fc2010-10-11 10:45:00 +0200798 SNDRV_PCM_HW_PARAM_FORMAT, -1);
799 if (err < 0)
800 goto unlock;
801 err = snd_pcm_hw_rule_add(runtime, 0,
802 SNDRV_PCM_HW_PARAM_RATE,
Takashi Iwai898dfe42018-01-04 17:38:54 +0100803 rule_rate, dpcm,
Jaroslav Kyselab1c73fc2010-10-11 10:45:00 +0200804 SNDRV_PCM_HW_PARAM_RATE, -1);
805 if (err < 0)
806 goto unlock;
807 err = snd_pcm_hw_rule_add(runtime, 0,
808 SNDRV_PCM_HW_PARAM_CHANNELS,
Takashi Iwai898dfe42018-01-04 17:38:54 +0100809 rule_channels, dpcm,
Jaroslav Kyselab1c73fc2010-10-11 10:45:00 +0200810 SNDRV_PCM_HW_PARAM_CHANNELS, -1);
811 if (err < 0)
812 goto unlock;
813
Timo Wischer133f3752019-11-20 11:49:51 -0600814 /* loopback_runtime_free() has not to be called if kfree(dpcm) was
815 * already called here. Otherwise it will end up with a double free.
816 */
Jaroslav Kysela597603d2010-08-09 14:21:11 +0200817 runtime->private_free = loopback_runtime_free;
Jaroslav Kyselab1c73fc2010-10-11 10:45:00 +0200818 if (get_notify(dpcm))
Jaroslav Kysela597603d2010-08-09 14:21:11 +0200819 runtime->hw = loopback_pcm_hardware;
Jaroslav Kyselab1c73fc2010-10-11 10:45:00 +0200820 else
Jaroslav Kysela597603d2010-08-09 14:21:11 +0200821 runtime->hw = cable->hw;
Takashi Iwai8e6b1a72018-03-22 10:40:27 +0100822
823 spin_lock_irq(&cable->lock);
824 cable->streams[substream->stream] = dpcm;
825 spin_unlock_irq(&cable->lock);
826
Jaroslav Kysela597603d2010-08-09 14:21:11 +0200827 unlock:
Takashi Iwai96853472018-01-05 16:09:47 +0100828 if (err < 0) {
829 free_cable(substream);
830 kfree(dpcm);
831 }
Jaroslav Kysela597603d2010-08-09 14:21:11 +0200832 mutex_unlock(&loopback->cable_lock);
833 return err;
834}
835
836static int loopback_close(struct snd_pcm_substream *substream)
837{
838 struct loopback *loopback = substream->private_data;
839 struct loopback_pcm *dpcm = substream->runtime->private_data;
Timo Wischer133f3752019-11-20 11:49:51 -0600840 int err = 0;
Jaroslav Kysela597603d2010-08-09 14:21:11 +0200841
Timo Wischer133f3752019-11-20 11:49:51 -0600842 if (dpcm->cable->ops->close_substream)
843 err = dpcm->cable->ops->close_substream(dpcm);
Jaroslav Kysela597603d2010-08-09 14:21:11 +0200844 mutex_lock(&loopback->cable_lock);
Takashi Iwai96853472018-01-05 16:09:47 +0100845 free_cable(substream);
Jaroslav Kysela597603d2010-08-09 14:21:11 +0200846 mutex_unlock(&loopback->cable_lock);
Timo Wischer133f3752019-11-20 11:49:51 -0600847 return err;
Jaroslav Kysela597603d2010-08-09 14:21:11 +0200848}
849
Takashi Iwai9f880582018-05-27 13:55:01 +0200850static const struct snd_pcm_ops loopback_pcm_ops = {
Jaroslav Kysela597603d2010-08-09 14:21:11 +0200851 .open = loopback_open,
852 .close = loopback_close,
853 .ioctl = snd_pcm_lib_ioctl,
854 .hw_params = loopback_hw_params,
855 .hw_free = loopback_hw_free,
856 .prepare = loopback_prepare,
857 .trigger = loopback_trigger,
858 .pointer = loopback_pointer,
859};
860
Bill Pembertonfbbb01a2012-12-06 12:35:27 -0500861static int loopback_pcm_new(struct loopback *loopback,
862 int device, int substreams)
Jaroslav Kysela597603d2010-08-09 14:21:11 +0200863{
864 struct snd_pcm *pcm;
865 int err;
866
867 err = snd_pcm_new(loopback->card, "Loopback PCM", device,
868 substreams, substreams, &pcm);
869 if (err < 0)
870 return err;
Takashi Iwai9f880582018-05-27 13:55:01 +0200871 snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK, &loopback_pcm_ops);
872 snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_CAPTURE, &loopback_pcm_ops);
Takashi Iwaib29e5ef2019-11-05 16:18:41 +0100873 snd_pcm_lib_preallocate_pages_for_all(pcm, SNDRV_DMA_TYPE_VMALLOC,
874 NULL, 0, 0);
Jaroslav Kysela597603d2010-08-09 14:21:11 +0200875
876 pcm->private_data = loopback;
877 pcm->info_flags = 0;
878 strcpy(pcm->name, "Loopback PCM");
879
880 loopback->pcm[device] = pcm;
Jaroslav Kysela597603d2010-08-09 14:21:11 +0200881 return 0;
882}
883
884static int loopback_rate_shift_info(struct snd_kcontrol *kcontrol,
885 struct snd_ctl_elem_info *uinfo)
886{
887 uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
888 uinfo->count = 1;
889 uinfo->value.integer.min = 80000;
890 uinfo->value.integer.max = 120000;
891 uinfo->value.integer.step = 1;
892 return 0;
893}
894
895static int loopback_rate_shift_get(struct snd_kcontrol *kcontrol,
896 struct snd_ctl_elem_value *ucontrol)
897{
898 struct loopback *loopback = snd_kcontrol_chip(kcontrol);
899
Takashi Iwai76b34212018-04-30 10:06:48 +0200900 mutex_lock(&loopback->cable_lock);
Jaroslav Kysela597603d2010-08-09 14:21:11 +0200901 ucontrol->value.integer.value[0] =
902 loopback->setup[kcontrol->id.subdevice]
903 [kcontrol->id.device].rate_shift;
Takashi Iwai76b34212018-04-30 10:06:48 +0200904 mutex_unlock(&loopback->cable_lock);
Jaroslav Kysela597603d2010-08-09 14:21:11 +0200905 return 0;
906}
907
908static int loopback_rate_shift_put(struct snd_kcontrol *kcontrol,
909 struct snd_ctl_elem_value *ucontrol)
910{
911 struct loopback *loopback = snd_kcontrol_chip(kcontrol);
912 unsigned int val;
913 int change = 0;
914
915 val = ucontrol->value.integer.value[0];
916 if (val < 80000)
917 val = 80000;
918 if (val > 120000)
919 val = 120000;
920 mutex_lock(&loopback->cable_lock);
921 if (val != loopback->setup[kcontrol->id.subdevice]
922 [kcontrol->id.device].rate_shift) {
923 loopback->setup[kcontrol->id.subdevice]
924 [kcontrol->id.device].rate_shift = val;
925 change = 1;
926 }
927 mutex_unlock(&loopback->cable_lock);
928 return change;
929}
930
931static int loopback_notify_get(struct snd_kcontrol *kcontrol,
932 struct snd_ctl_elem_value *ucontrol)
933{
934 struct loopback *loopback = snd_kcontrol_chip(kcontrol);
935
Takashi Iwai76b34212018-04-30 10:06:48 +0200936 mutex_lock(&loopback->cable_lock);
Jaroslav Kysela597603d2010-08-09 14:21:11 +0200937 ucontrol->value.integer.value[0] =
938 loopback->setup[kcontrol->id.subdevice]
939 [kcontrol->id.device].notify;
Takashi Iwai76b34212018-04-30 10:06:48 +0200940 mutex_unlock(&loopback->cable_lock);
Jaroslav Kysela597603d2010-08-09 14:21:11 +0200941 return 0;
942}
943
944static int loopback_notify_put(struct snd_kcontrol *kcontrol,
945 struct snd_ctl_elem_value *ucontrol)
946{
947 struct loopback *loopback = snd_kcontrol_chip(kcontrol);
948 unsigned int val;
949 int change = 0;
950
951 val = ucontrol->value.integer.value[0] ? 1 : 0;
Takashi Iwai76b34212018-04-30 10:06:48 +0200952 mutex_lock(&loopback->cable_lock);
Jaroslav Kysela597603d2010-08-09 14:21:11 +0200953 if (val != loopback->setup[kcontrol->id.subdevice]
954 [kcontrol->id.device].notify) {
955 loopback->setup[kcontrol->id.subdevice]
956 [kcontrol->id.device].notify = val;
957 change = 1;
958 }
Takashi Iwai76b34212018-04-30 10:06:48 +0200959 mutex_unlock(&loopback->cable_lock);
Jaroslav Kysela597603d2010-08-09 14:21:11 +0200960 return change;
961}
962
963static int loopback_active_get(struct snd_kcontrol *kcontrol,
964 struct snd_ctl_elem_value *ucontrol)
965{
966 struct loopback *loopback = snd_kcontrol_chip(kcontrol);
Takashi Iwai76b34212018-04-30 10:06:48 +0200967 struct loopback_cable *cable;
968
Jaroslav Kysela597603d2010-08-09 14:21:11 +0200969 unsigned int val = 0;
970
Takashi Iwai76b34212018-04-30 10:06:48 +0200971 mutex_lock(&loopback->cable_lock);
972 cable = loopback->cables[kcontrol->id.subdevice][kcontrol->id.device ^ 1];
Robert Rosengren306a4f32018-03-26 07:24:49 +0200973 if (cable != NULL) {
974 unsigned int running = cable->running ^ cable->pause;
975
976 val = (running & (1 << SNDRV_PCM_STREAM_PLAYBACK)) ? 1 : 0;
977 }
Takashi Iwai76b34212018-04-30 10:06:48 +0200978 mutex_unlock(&loopback->cable_lock);
Jaroslav Kysela597603d2010-08-09 14:21:11 +0200979 ucontrol->value.integer.value[0] = val;
980 return 0;
981}
982
983static int loopback_format_info(struct snd_kcontrol *kcontrol,
984 struct snd_ctl_elem_info *uinfo)
985{
986 uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
987 uinfo->count = 1;
988 uinfo->value.integer.min = 0;
989 uinfo->value.integer.max = SNDRV_PCM_FORMAT_LAST;
990 uinfo->value.integer.step = 1;
991 return 0;
992}
993
994static int loopback_format_get(struct snd_kcontrol *kcontrol,
995 struct snd_ctl_elem_value *ucontrol)
996{
997 struct loopback *loopback = snd_kcontrol_chip(kcontrol);
998
999 ucontrol->value.integer.value[0] =
1000 loopback->setup[kcontrol->id.subdevice]
1001 [kcontrol->id.device].format;
1002 return 0;
1003}
1004
1005static int loopback_rate_info(struct snd_kcontrol *kcontrol,
1006 struct snd_ctl_elem_info *uinfo)
1007{
1008 uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
1009 uinfo->count = 1;
1010 uinfo->value.integer.min = 0;
1011 uinfo->value.integer.max = 192000;
1012 uinfo->value.integer.step = 1;
1013 return 0;
1014}
1015
1016static int loopback_rate_get(struct snd_kcontrol *kcontrol,
1017 struct snd_ctl_elem_value *ucontrol)
1018{
1019 struct loopback *loopback = snd_kcontrol_chip(kcontrol);
1020
Takashi Iwai76b34212018-04-30 10:06:48 +02001021 mutex_lock(&loopback->cable_lock);
Jaroslav Kysela597603d2010-08-09 14:21:11 +02001022 ucontrol->value.integer.value[0] =
1023 loopback->setup[kcontrol->id.subdevice]
1024 [kcontrol->id.device].rate;
Takashi Iwai76b34212018-04-30 10:06:48 +02001025 mutex_unlock(&loopback->cable_lock);
Jaroslav Kysela597603d2010-08-09 14:21:11 +02001026 return 0;
1027}
1028
1029static int loopback_channels_info(struct snd_kcontrol *kcontrol,
1030 struct snd_ctl_elem_info *uinfo)
1031{
1032 uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
1033 uinfo->count = 1;
1034 uinfo->value.integer.min = 1;
1035 uinfo->value.integer.max = 1024;
1036 uinfo->value.integer.step = 1;
1037 return 0;
1038}
1039
1040static int loopback_channels_get(struct snd_kcontrol *kcontrol,
1041 struct snd_ctl_elem_value *ucontrol)
1042{
1043 struct loopback *loopback = snd_kcontrol_chip(kcontrol);
1044
Takashi Iwai76b34212018-04-30 10:06:48 +02001045 mutex_lock(&loopback->cable_lock);
Jaroslav Kysela597603d2010-08-09 14:21:11 +02001046 ucontrol->value.integer.value[0] =
1047 loopback->setup[kcontrol->id.subdevice]
Jaroslav Kysela1446c5f2010-09-15 08:01:57 +02001048 [kcontrol->id.device].channels;
Takashi Iwai76b34212018-04-30 10:06:48 +02001049 mutex_unlock(&loopback->cable_lock);
Jaroslav Kysela597603d2010-08-09 14:21:11 +02001050 return 0;
1051}
1052
Bill Pembertonfbbb01a2012-12-06 12:35:27 -05001053static struct snd_kcontrol_new loopback_controls[] = {
Jaroslav Kysela597603d2010-08-09 14:21:11 +02001054{
1055 .iface = SNDRV_CTL_ELEM_IFACE_PCM,
1056 .name = "PCM Rate Shift 100000",
1057 .info = loopback_rate_shift_info,
1058 .get = loopback_rate_shift_get,
1059 .put = loopback_rate_shift_put,
1060},
1061{
1062 .iface = SNDRV_CTL_ELEM_IFACE_PCM,
1063 .name = "PCM Notify",
1064 .info = snd_ctl_boolean_mono_info,
1065 .get = loopback_notify_get,
1066 .put = loopback_notify_put,
1067},
1068#define ACTIVE_IDX 2
1069{
1070 .access = SNDRV_CTL_ELEM_ACCESS_READ,
1071 .iface = SNDRV_CTL_ELEM_IFACE_PCM,
1072 .name = "PCM Slave Active",
1073 .info = snd_ctl_boolean_mono_info,
1074 .get = loopback_active_get,
1075},
1076#define FORMAT_IDX 3
1077{
1078 .access = SNDRV_CTL_ELEM_ACCESS_READ,
1079 .iface = SNDRV_CTL_ELEM_IFACE_PCM,
1080 .name = "PCM Slave Format",
1081 .info = loopback_format_info,
1082 .get = loopback_format_get
1083},
1084#define RATE_IDX 4
1085{
1086 .access = SNDRV_CTL_ELEM_ACCESS_READ,
1087 .iface = SNDRV_CTL_ELEM_IFACE_PCM,
1088 .name = "PCM Slave Rate",
1089 .info = loopback_rate_info,
1090 .get = loopback_rate_get
1091},
1092#define CHANNELS_IDX 5
1093{
1094 .access = SNDRV_CTL_ELEM_ACCESS_READ,
1095 .iface = SNDRV_CTL_ELEM_IFACE_PCM,
1096 .name = "PCM Slave Channels",
1097 .info = loopback_channels_info,
1098 .get = loopback_channels_get
1099}
1100};
1101
Bill Pembertonfbbb01a2012-12-06 12:35:27 -05001102static int loopback_mixer_new(struct loopback *loopback, int notify)
Jaroslav Kysela597603d2010-08-09 14:21:11 +02001103{
1104 struct snd_card *card = loopback->card;
1105 struct snd_pcm *pcm;
1106 struct snd_kcontrol *kctl;
1107 struct loopback_setup *setup;
1108 int err, dev, substr, substr_count, idx;
1109
1110 strcpy(card->mixername, "Loopback Mixer");
1111 for (dev = 0; dev < 2; dev++) {
1112 pcm = loopback->pcm[dev];
1113 substr_count =
1114 pcm->streams[SNDRV_PCM_STREAM_CAPTURE].substream_count;
1115 for (substr = 0; substr < substr_count; substr++) {
1116 setup = &loopback->setup[substr][dev];
1117 setup->notify = notify;
1118 setup->rate_shift = NO_PITCH;
1119 setup->format = SNDRV_PCM_FORMAT_S16_LE;
1120 setup->rate = 48000;
1121 setup->channels = 2;
1122 for (idx = 0; idx < ARRAY_SIZE(loopback_controls);
1123 idx++) {
1124 kctl = snd_ctl_new1(&loopback_controls[idx],
1125 loopback);
1126 if (!kctl)
1127 return -ENOMEM;
1128 kctl->id.device = dev;
1129 kctl->id.subdevice = substr;
1130 switch (idx) {
1131 case ACTIVE_IDX:
1132 setup->active_id = kctl->id;
1133 break;
1134 case FORMAT_IDX:
1135 setup->format_id = kctl->id;
1136 break;
1137 case RATE_IDX:
1138 setup->rate_id = kctl->id;
1139 break;
1140 case CHANNELS_IDX:
1141 setup->channels_id = kctl->id;
1142 break;
1143 default:
1144 break;
1145 }
1146 err = snd_ctl_add(card, kctl);
1147 if (err < 0)
1148 return err;
1149 }
1150 }
1151 }
1152 return 0;
1153}
1154
Jaroslav Kyselae74670b2010-10-18 09:43:10 +02001155static void print_dpcm_info(struct snd_info_buffer *buffer,
1156 struct loopback_pcm *dpcm,
1157 const char *id)
1158{
1159 snd_iprintf(buffer, " %s\n", id);
1160 if (dpcm == NULL) {
1161 snd_iprintf(buffer, " inactive\n");
1162 return;
1163 }
1164 snd_iprintf(buffer, " buffer_size:\t%u\n", dpcm->pcm_buffer_size);
1165 snd_iprintf(buffer, " buffer_pos:\t\t%u\n", dpcm->buf_pos);
1166 snd_iprintf(buffer, " silent_size:\t%u\n", dpcm->silent_size);
1167 snd_iprintf(buffer, " period_size:\t%u\n", dpcm->pcm_period_size);
1168 snd_iprintf(buffer, " bytes_per_sec:\t%u\n", dpcm->pcm_bps);
1169 snd_iprintf(buffer, " sample_align:\t%u\n", dpcm->pcm_salign);
1170 snd_iprintf(buffer, " rate_shift:\t\t%u\n", dpcm->pcm_rate_shift);
Timo Wischer133f3752019-11-20 11:49:51 -06001171 if (dpcm->cable->ops->dpcm_info)
1172 dpcm->cable->ops->dpcm_info(dpcm, buffer);
Jaroslav Kyselae74670b2010-10-18 09:43:10 +02001173}
1174
1175static void print_substream_info(struct snd_info_buffer *buffer,
1176 struct loopback *loopback,
1177 int sub,
1178 int num)
1179{
1180 struct loopback_cable *cable = loopback->cables[sub][num];
1181
1182 snd_iprintf(buffer, "Cable %i substream %i:\n", num, sub);
1183 if (cable == NULL) {
1184 snd_iprintf(buffer, " inactive\n");
1185 return;
1186 }
1187 snd_iprintf(buffer, " valid: %u\n", cable->valid);
1188 snd_iprintf(buffer, " running: %u\n", cable->running);
Jaroslav Kysela5de9e452010-10-20 09:33:03 +02001189 snd_iprintf(buffer, " pause: %u\n", cable->pause);
Jaroslav Kyselae74670b2010-10-18 09:43:10 +02001190 print_dpcm_info(buffer, cable->streams[0], "Playback");
1191 print_dpcm_info(buffer, cable->streams[1], "Capture");
1192}
1193
1194static void print_cable_info(struct snd_info_entry *entry,
1195 struct snd_info_buffer *buffer)
1196{
1197 struct loopback *loopback = entry->private_data;
1198 int sub, num;
1199
1200 mutex_lock(&loopback->cable_lock);
1201 num = entry->name[strlen(entry->name)-1];
1202 num = num == '0' ? 0 : 1;
1203 for (sub = 0; sub < MAX_PCM_SUBSTREAMS; sub++)
1204 print_substream_info(buffer, loopback, sub, num);
1205 mutex_unlock(&loopback->cable_lock);
1206}
1207
Bill Pembertonfbbb01a2012-12-06 12:35:27 -05001208static int loopback_proc_new(struct loopback *loopback, int cidx)
Jaroslav Kyselae74670b2010-10-18 09:43:10 +02001209{
1210 char name[32];
Jaroslav Kyselae74670b2010-10-18 09:43:10 +02001211
1212 snprintf(name, sizeof(name), "cable#%d", cidx);
Takashi Iwai815d8082019-02-04 15:58:33 +01001213 return snd_card_ro_proc_new(loopback->card, name, loopback,
1214 print_cable_info);
Jaroslav Kyselae74670b2010-10-18 09:43:10 +02001215}
1216
Bill Pembertonfbbb01a2012-12-06 12:35:27 -05001217static int loopback_probe(struct platform_device *devptr)
Jaroslav Kysela597603d2010-08-09 14:21:11 +02001218{
1219 struct snd_card *card;
1220 struct loopback *loopback;
1221 int dev = devptr->id;
1222 int err;
1223
Takashi Iwai5872f3f2014-01-29 12:59:08 +01001224 err = snd_card_new(&devptr->dev, index[dev], id[dev], THIS_MODULE,
1225 sizeof(struct loopback), &card);
Jaroslav Kysela597603d2010-08-09 14:21:11 +02001226 if (err < 0)
1227 return err;
1228 loopback = card->private_data;
1229
1230 if (pcm_substreams[dev] < 1)
1231 pcm_substreams[dev] = 1;
1232 if (pcm_substreams[dev] > MAX_PCM_SUBSTREAMS)
1233 pcm_substreams[dev] = MAX_PCM_SUBSTREAMS;
1234
1235 loopback->card = card;
1236 mutex_init(&loopback->cable_lock);
1237
1238 err = loopback_pcm_new(loopback, 0, pcm_substreams[dev]);
1239 if (err < 0)
1240 goto __nodev;
1241 err = loopback_pcm_new(loopback, 1, pcm_substreams[dev]);
1242 if (err < 0)
1243 goto __nodev;
1244 err = loopback_mixer_new(loopback, pcm_notify[dev] ? 1 : 0);
1245 if (err < 0)
1246 goto __nodev;
Jaroslav Kyselae74670b2010-10-18 09:43:10 +02001247 loopback_proc_new(loopback, 0);
1248 loopback_proc_new(loopback, 1);
Jaroslav Kysela597603d2010-08-09 14:21:11 +02001249 strcpy(card->driver, "Loopback");
1250 strcpy(card->shortname, "Loopback");
1251 sprintf(card->longname, "Loopback %i", dev + 1);
1252 err = snd_card_register(card);
1253 if (!err) {
1254 platform_set_drvdata(devptr, card);
1255 return 0;
1256 }
1257 __nodev:
1258 snd_card_free(card);
1259 return err;
1260}
1261
Bill Pembertonfbbb01a2012-12-06 12:35:27 -05001262static int loopback_remove(struct platform_device *devptr)
Jaroslav Kysela597603d2010-08-09 14:21:11 +02001263{
1264 snd_card_free(platform_get_drvdata(devptr));
Jaroslav Kysela597603d2010-08-09 14:21:11 +02001265 return 0;
1266}
1267
Takashi Iwaid34e4e02012-08-09 15:47:15 +02001268#ifdef CONFIG_PM_SLEEP
Takashi Iwai284e7ca2012-07-02 11:22:40 +02001269static int loopback_suspend(struct device *pdev)
Jaroslav Kysela597603d2010-08-09 14:21:11 +02001270{
Takashi Iwai284e7ca2012-07-02 11:22:40 +02001271 struct snd_card *card = dev_get_drvdata(pdev);
Jaroslav Kysela597603d2010-08-09 14:21:11 +02001272
1273 snd_power_change_state(card, SNDRV_CTL_POWER_D3hot);
Jaroslav Kysela597603d2010-08-09 14:21:11 +02001274 return 0;
1275}
1276
Takashi Iwai284e7ca2012-07-02 11:22:40 +02001277static int loopback_resume(struct device *pdev)
Jaroslav Kysela597603d2010-08-09 14:21:11 +02001278{
Takashi Iwai284e7ca2012-07-02 11:22:40 +02001279 struct snd_card *card = dev_get_drvdata(pdev);
Jaroslav Kysela597603d2010-08-09 14:21:11 +02001280
1281 snd_power_change_state(card, SNDRV_CTL_POWER_D0);
1282 return 0;
1283}
Takashi Iwai284e7ca2012-07-02 11:22:40 +02001284
1285static SIMPLE_DEV_PM_OPS(loopback_pm, loopback_suspend, loopback_resume);
1286#define LOOPBACK_PM_OPS &loopback_pm
1287#else
1288#define LOOPBACK_PM_OPS NULL
Jaroslav Kysela597603d2010-08-09 14:21:11 +02001289#endif
1290
1291#define SND_LOOPBACK_DRIVER "snd_aloop"
1292
1293static struct platform_driver loopback_driver = {
1294 .probe = loopback_probe,
Bill Pembertonfbbb01a2012-12-06 12:35:27 -05001295 .remove = loopback_remove,
Jaroslav Kysela597603d2010-08-09 14:21:11 +02001296 .driver = {
Takashi Iwai8bf01d82012-07-02 10:50:24 +02001297 .name = SND_LOOPBACK_DRIVER,
Takashi Iwai284e7ca2012-07-02 11:22:40 +02001298 .pm = LOOPBACK_PM_OPS,
Jaroslav Kysela597603d2010-08-09 14:21:11 +02001299 },
1300};
1301
1302static void loopback_unregister_all(void)
1303{
1304 int i;
1305
1306 for (i = 0; i < ARRAY_SIZE(devices); ++i)
1307 platform_device_unregister(devices[i]);
1308 platform_driver_unregister(&loopback_driver);
1309}
1310
1311static int __init alsa_card_loopback_init(void)
1312{
1313 int i, err, cards;
1314
1315 err = platform_driver_register(&loopback_driver);
1316 if (err < 0)
1317 return err;
1318
1319
1320 cards = 0;
1321 for (i = 0; i < SNDRV_CARDS; i++) {
1322 struct platform_device *device;
1323 if (!enable[i])
1324 continue;
1325 device = platform_device_register_simple(SND_LOOPBACK_DRIVER,
1326 i, NULL, 0);
1327 if (IS_ERR(device))
1328 continue;
1329 if (!platform_get_drvdata(device)) {
1330 platform_device_unregister(device);
1331 continue;
1332 }
1333 devices[i] = device;
1334 cards++;
1335 }
1336 if (!cards) {
1337#ifdef MODULE
1338 printk(KERN_ERR "aloop: No loopback enabled\n");
1339#endif
1340 loopback_unregister_all();
1341 return -ENODEV;
1342 }
1343 return 0;
1344}
1345
1346static void __exit alsa_card_loopback_exit(void)
1347{
1348 loopback_unregister_all();
1349}
1350
1351module_init(alsa_card_loopback_init)
1352module_exit(alsa_card_loopback_exit)