#include <linux/init.h>
#include <linux/jiffies.h>
#include <linux/slab.h>
#include <linux/time.h>
#include <linux/wait.h>
#include <linux/module.h>
#include <linux/platform_device.h>
#include <sound/core.h>
#include <sound/control.h>
#include <sound/pcm.h>
#include <sound/pcm_params.h>
#include <sound/info.h>
#include <sound/initval.h>
#include <sound/timer.h>
MODULE_AUTHOR(…) …;
MODULE_DESCRIPTION(…) …;
MODULE_LICENSE(…) …;
#define MAX_PCM_SUBSTREAMS …
static int index[SNDRV_CARDS] = …;
static char *id[SNDRV_CARDS] = …;
static bool enable[SNDRV_CARDS] = …;
static int pcm_substreams[SNDRV_CARDS] = …;
static int pcm_notify[SNDRV_CARDS];
static char *timer_source[SNDRV_CARDS];
module_param_array(…);
MODULE_PARM_DESC(…) …;
module_param_array(…);
MODULE_PARM_DESC(…) …;
module_param_array(…);
MODULE_PARM_DESC(…) …;
module_param_array(…);
MODULE_PARM_DESC(…) …;
module_param_array(…);
MODULE_PARM_DESC(…) …;
module_param_array(…);
MODULE_PARM_DESC(…) …;
#define NO_PITCH …
#define CABLE_VALID_PLAYBACK …
#define CABLE_VALID_CAPTURE …
#define CABLE_VALID_BOTH …
struct loopback_cable;
struct loopback_pcm;
struct loopback_ops { … };
struct loopback_cable { … };
struct loopback_setup { … };
struct loopback { … };
struct loopback_pcm { … };
static struct platform_device *devices[SNDRV_CARDS];
static inline unsigned int byte_pos(struct loopback_pcm *dpcm, unsigned int x)
{ … }
static inline unsigned int frac_pos(struct loopback_pcm *dpcm, unsigned int x)
{ … }
static inline struct loopback_setup *get_setup(struct loopback_pcm *dpcm)
{ … }
static inline unsigned int get_notify(struct loopback_pcm *dpcm)
{ … }
static inline unsigned int get_rate_shift(struct loopback_pcm *dpcm)
{ … }
static int loopback_jiffies_timer_start(struct loopback_pcm *dpcm)
{ … }
static int loopback_snd_timer_start(struct loopback_pcm *dpcm)
{ … }
static inline int loopback_jiffies_timer_stop(struct loopback_pcm *dpcm)
{ … }
static int loopback_snd_timer_stop(struct loopback_pcm *dpcm)
{ … }
static inline int loopback_jiffies_timer_stop_sync(struct loopback_pcm *dpcm)
{ … }
static int loopback_snd_timer_close_cable(struct loopback_pcm *dpcm)
{ … }
static bool is_access_interleaved(snd_pcm_access_t access)
{
switch (access) {
case SNDRV_PCM_ACCESS_MMAP_INTERLEAVED:
case SNDRV_PCM_ACCESS_RW_INTERLEAVED:
return true;
default:
return false;
}
};
static int loopback_check_format(struct loopback_cable *cable, int stream)
{ … }
static void loopback_active_notify(struct loopback_pcm *dpcm)
{ … }
static int loopback_trigger(struct snd_pcm_substream *substream, int cmd)
{ … }
static void params_change(struct snd_pcm_substream *substream)
{ … }
static int loopback_prepare(struct snd_pcm_substream *substream)
{ … }
static void clear_capture_buf(struct loopback_pcm *dpcm, unsigned int bytes)
{ … }
static void copy_play_buf_part_n(struct loopback_pcm *play, struct loopback_pcm *capt,
unsigned int size, unsigned int src_off, unsigned int dst_off)
{ … }
static void copy_play_buf(struct loopback_pcm *play,
struct loopback_pcm *capt,
unsigned int bytes)
{ … }
static inline unsigned int bytepos_delta(struct loopback_pcm *dpcm,
unsigned int jiffies_delta)
{ … }
static inline void bytepos_finish(struct loopback_pcm *dpcm,
unsigned int delta)
{ … }
static unsigned int loopback_jiffies_timer_pos_update
(struct loopback_cable *cable)
{ … }
static void loopback_jiffies_timer_function(struct timer_list *t)
{ … }
static int loopback_snd_timer_check_resolution(struct snd_pcm_runtime *runtime,
unsigned long resolution)
{ … }
static void loopback_snd_timer_period_elapsed(struct loopback_cable *cable,
int event,
unsigned long resolution)
{ … }
static void loopback_snd_timer_function(struct snd_timer_instance *timeri,
unsigned long resolution,
unsigned long ticks)
{ … }
static void loopback_snd_timer_work(struct work_struct *work)
{ … }
static void loopback_snd_timer_event(struct snd_timer_instance *timeri,
int event,
struct timespec64 *tstamp,
unsigned long resolution)
{ … }
static void loopback_jiffies_timer_dpcm_info(struct loopback_pcm *dpcm,
struct snd_info_buffer *buffer)
{ … }
static void loopback_snd_timer_dpcm_info(struct loopback_pcm *dpcm,
struct snd_info_buffer *buffer)
{ … }
static snd_pcm_uframes_t loopback_pointer(struct snd_pcm_substream *substream)
{ … }
static const struct snd_pcm_hardware loopback_pcm_hardware = …;
static void loopback_runtime_free(struct snd_pcm_runtime *runtime)
{ … }
static int loopback_hw_free(struct snd_pcm_substream *substream)
{ … }
static unsigned int get_cable_index(struct snd_pcm_substream *substream)
{ … }
static int rule_format(struct snd_pcm_hw_params *params,
struct snd_pcm_hw_rule *rule)
{ … }
static int rule_rate(struct snd_pcm_hw_params *params,
struct snd_pcm_hw_rule *rule)
{ … }
static int rule_channels(struct snd_pcm_hw_params *params,
struct snd_pcm_hw_rule *rule)
{ … }
static int rule_period_bytes(struct snd_pcm_hw_params *params,
struct snd_pcm_hw_rule *rule)
{ … }
static void free_cable(struct snd_pcm_substream *substream)
{ … }
static int loopback_jiffies_timer_open(struct loopback_pcm *dpcm)
{ … }
static const struct loopback_ops loopback_jiffies_timer_ops = …;
static int loopback_parse_timer_id(const char *str,
struct snd_timer_id *tid)
{ … }
static int loopback_snd_timer_open(struct loopback_pcm *dpcm)
{ … }
static const struct loopback_ops loopback_snd_timer_ops = …;
static int loopback_open(struct snd_pcm_substream *substream)
{ … }
static int loopback_close(struct snd_pcm_substream *substream)
{ … }
static const struct snd_pcm_ops loopback_pcm_ops = …;
static int loopback_pcm_new(struct loopback *loopback,
int device, int substreams)
{ … }
static int loopback_rate_shift_info(struct snd_kcontrol *kcontrol,
struct snd_ctl_elem_info *uinfo)
{ … }
static int loopback_rate_shift_get(struct snd_kcontrol *kcontrol,
struct snd_ctl_elem_value *ucontrol)
{ … }
static int loopback_rate_shift_put(struct snd_kcontrol *kcontrol,
struct snd_ctl_elem_value *ucontrol)
{ … }
static int loopback_notify_get(struct snd_kcontrol *kcontrol,
struct snd_ctl_elem_value *ucontrol)
{ … }
static int loopback_notify_put(struct snd_kcontrol *kcontrol,
struct snd_ctl_elem_value *ucontrol)
{ … }
static int loopback_active_get(struct snd_kcontrol *kcontrol,
struct snd_ctl_elem_value *ucontrol)
{ … }
static int loopback_format_info(struct snd_kcontrol *kcontrol,
struct snd_ctl_elem_info *uinfo)
{ … }
static int loopback_format_get(struct snd_kcontrol *kcontrol,
struct snd_ctl_elem_value *ucontrol)
{ … }
static int loopback_rate_info(struct snd_kcontrol *kcontrol,
struct snd_ctl_elem_info *uinfo)
{ … }
static int loopback_rate_get(struct snd_kcontrol *kcontrol,
struct snd_ctl_elem_value *ucontrol)
{ … }
static int loopback_channels_info(struct snd_kcontrol *kcontrol,
struct snd_ctl_elem_info *uinfo)
{ … }
static int loopback_channels_get(struct snd_kcontrol *kcontrol,
struct snd_ctl_elem_value *ucontrol)
{ … }
static int loopback_access_info(struct snd_kcontrol *kcontrol,
struct snd_ctl_elem_info *uinfo)
{ … }
static int loopback_access_get(struct snd_kcontrol *kcontrol,
struct snd_ctl_elem_value *ucontrol)
{ … }
static const struct snd_kcontrol_new loopback_controls[] = …;
static int loopback_mixer_new(struct loopback *loopback, int notify)
{ … }
static void print_dpcm_info(struct snd_info_buffer *buffer,
struct loopback_pcm *dpcm,
const char *id)
{ … }
static void print_substream_info(struct snd_info_buffer *buffer,
struct loopback *loopback,
int sub,
int num)
{ … }
static void print_cable_info(struct snd_info_entry *entry,
struct snd_info_buffer *buffer)
{ … }
static int loopback_cable_proc_new(struct loopback *loopback, int cidx)
{ … }
static void loopback_set_timer_source(struct loopback *loopback,
const char *value)
{ … }
static void print_timer_source_info(struct snd_info_entry *entry,
struct snd_info_buffer *buffer)
{ … }
static void change_timer_source_info(struct snd_info_entry *entry,
struct snd_info_buffer *buffer)
{ … }
static int loopback_timer_source_proc_new(struct loopback *loopback)
{ … }
static int loopback_probe(struct platform_device *devptr)
{ … }
static int loopback_suspend(struct device *pdev)
{ … }
static int loopback_resume(struct device *pdev)
{ … }
static DEFINE_SIMPLE_DEV_PM_OPS(loopback_pm, loopback_suspend, loopback_resume);
#define SND_LOOPBACK_DRIVER …
static struct platform_driver loopback_driver = …;
static void loopback_unregister_all(void)
{ … }
static int __init alsa_card_loopback_init(void)
{ … }
static void __exit alsa_card_loopback_exit(void)
{ … }
module_init(…) …
module_exit(…)