diff options
Diffstat (limited to 'loopback')
-rw-r--r-- | loopback/Kconfig | 12 | ||||
-rw-r--r-- | loopback/Makefile | 6 | ||||
-rw-r--r-- | loopback/loopback.c | 112 |
3 files changed, 130 insertions, 0 deletions
diff --git a/loopback/Kconfig b/loopback/Kconfig new file mode 100644 index 0000000..6293c5c --- /dev/null +++ b/loopback/Kconfig @@ -0,0 +1,12 @@ +# +# AVIRT Loopback Audio Path +# + +config AVIRT_LOOPBACKAP + tristate "LoopbackAP" + select SND_PCM + ---help--- + Say Y here if you want to add loopback audio path. + + To compile this driver as a module, choose M here: the + module will be called avirt_loopbackap. diff --git a/loopback/Makefile b/loopback/Makefile new file mode 100644 index 0000000..55da206 --- /dev/null +++ b/loopback/Makefile @@ -0,0 +1,6 @@ +obj-$(CONFIG_AVIRT_LOOPBACKAP) += avirt_loopbackap.o + +$(info $(src)) +avirt_loopbackap-objs := loopback.o +ccflags-y += -Idrivers/staging/ +ccflags-y += -I$(src)/../../ diff --git a/loopback/loopback.c b/loopback/loopback.c new file mode 100644 index 0000000..57f3c34 --- /dev/null +++ b/loopback/loopback.c @@ -0,0 +1,112 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * ALSA Virtual Soundcard + * + * loopback_audiopath.c - AVIRT sample Audio Path definition + * + * Copyright (C) 2010-2018 Fiberdyne Systems Pty Ltd + */ + +#include <linux/module.h> +#include <linux/slab.h> +#include <avirt/core.h> + +MODULE_AUTHOR("JOSHANNE <james.oshannessy@fiberdyne.com.au>"); +MODULE_AUTHOR("MFARRUGI <mark.farrugia@fiberdyne.com.au>"); +MODULE_DESCRIPTION("Sample Audio Path Module Interface"); +MODULE_LICENSE("GPL v2"); + +static struct avirt_coreinfo *coreinfo; + +/******************************************************************************* + * Audio Path ALSA PCM Callbacks + ******************************************************************************/ +static int loopback_pcm_open(struct snd_pcm_substream *substream) +{ + return 0; +} + +static int loopback_pcm_close(struct snd_pcm_substream *substream) +{ + return 0; +} + +static snd_pcm_uframes_t + loopback_pcm_pointer(struct snd_pcm_substream *substream) +{ + return 0; +} + +static int loopback_pcm_trigger(struct snd_pcm_substream *substream, int cmd) +{ + switch (cmd) { + case SNDRV_PCM_TRIGGER_START: + case SNDRV_PCM_TRIGGER_RESUME: + case SNDRV_PCM_TRIGGER_STOP: + case SNDRV_PCM_TRIGGER_SUSPEND: + return 0; + } + return -EINVAL; +} + +static int loopback_pcm_prepare(struct snd_pcm_substream *substream) +{ + return 0; +} + +static struct snd_pcm_ops loopbackap_pcm_ops = { + .open = loopback_pcm_open, + .close = loopback_pcm_close, + .prepare = loopback_pcm_prepare, + .pointer = loopback_pcm_pointer, + .trigger = loopback_pcm_trigger, +}; + +/******************************************************************************* + * Loopback Audio Path AVIRT registration + ******************************************************************************/ +static struct snd_pcm_hardware loopbackap_hw = { + .formats = SNDRV_PCM_FMTBIT_S16_LE, + .info = (SNDRV_PCM_INFO_INTERLEAVED // Channel interleaved audio + | SNDRV_PCM_INFO_BLOCK_TRANSFER | SNDRV_PCM_INFO_MMAP | + SNDRV_PCM_INFO_MMAP_VALID), + .rates = SNDRV_PCM_RATE_48000, + .rate_min = 48000, + .rate_max = 48000, + .periods_min = 1, + .periods_max = 8, +}; + +static struct avirt_audiopath loopbackap_module = { + .name = "Loopback Audio Path", + .version = { 0, 0, 1 }, + .value = 10, + .hw = &loopbackap_hw, + .pcm_ops = &loopbackap_pcm_ops, + .blocksize = 512, +}; + +static int __init loopback_init(void) +{ + int err = 0; + + pr_info("init()\n"); + + err = avirt_register_audiopath(&loopbackap_module, &coreinfo); + if ((err < 0) || (!coreinfo)) { + pr_err("%s: coreinfo is NULL!\n", __func__); + return err; + } + + return err; +} + +static void __exit loopback_exit(void) +{ + pr_info("exit()\n"); + + avirt_deregister_audiopath(&loopbackap_module); +} + +module_init(loopback_init); +module_exit(loopback_exit); |