linux/sound/core/pcm.c

// SPDX-License-Identifier: GPL-2.0-or-later
/*
 *  Digital Audio (PCM) abstract layer
 *  Copyright (c) by Jaroslav Kysela <[email protected]>
 */

#include <linux/init.h>
#include <linux/slab.h>
#include <linux/module.h>
#include <linux/time.h>
#include <linux/mutex.h>
#include <linux/device.h>
#include <linux/nospec.h>
#include <sound/core.h>
#include <sound/minors.h>
#include <sound/pcm.h>
#include <sound/timer.h>
#include <sound/control.h>
#include <sound/info.h>

#include "pcm_local.h"

MODULE_AUTHOR();
MODULE_DESCRIPTION();
MODULE_LICENSE();

static LIST_HEAD(snd_pcm_devices);
static DEFINE_MUTEX(register_mutex);
#if IS_ENABLED(CONFIG_SND_PCM_OSS)
static LIST_HEAD(snd_pcm_notify_list);
#endif

static int snd_pcm_free(struct snd_pcm *pcm);
static int snd_pcm_dev_free(struct snd_device *device);
static int snd_pcm_dev_register(struct snd_device *device);
static int snd_pcm_dev_disconnect(struct snd_device *device);

static struct snd_pcm *snd_pcm_get(struct snd_card *card, int device)
{}

static int snd_pcm_next(struct snd_card *card, int device)
{}

static int snd_pcm_add(struct snd_pcm *newpcm)
{}

static int snd_pcm_control_ioctl(struct snd_card *card,
				 struct snd_ctl_file *control,
				 unsigned int cmd, unsigned long arg)
{}

#define FORMAT(v)

static const char * const snd_pcm_format_names[] =;

/**
 * snd_pcm_format_name - Return a name string for the given PCM format
 * @format: PCM format
 *
 * Return: the format name string
 */
const char *snd_pcm_format_name(snd_pcm_format_t format)
{}
EXPORT_SYMBOL_GPL();

#ifdef CONFIG_SND_VERBOSE_PROCFS

#define STATE(v)
#define STREAM(v)
#define READY(v)
#define XRUN(v)
#define SILENCE(v)
#define TSTAMP(v)
#define ACCESS(v)
#define START(v)
#define SUBFORMAT(v) 

static const char * const snd_pcm_stream_names[] =;

static const char * const snd_pcm_state_names[] =;

static const char * const snd_pcm_access_names[] =;

static const char * const snd_pcm_subformat_names[] =;

static const char * const snd_pcm_tstamp_mode_names[] =;

static const char *snd_pcm_stream_name(int stream)
{}

static const char *snd_pcm_access_name(snd_pcm_access_t access)
{}

static const char *snd_pcm_subformat_name(snd_pcm_subformat_t subformat)
{}

static const char *snd_pcm_tstamp_mode_name(int mode)
{}

static const char *snd_pcm_state_name(snd_pcm_state_t state)
{}

#if IS_ENABLED(CONFIG_SND_PCM_OSS)
#include <linux/soundcard.h>

static const char *snd_pcm_oss_format_name(int format)
{}
#endif

static void snd_pcm_proc_info_read(struct snd_pcm_substream *substream,
				   struct snd_info_buffer *buffer)
{}

static void snd_pcm_stream_proc_info_read(struct snd_info_entry *entry,
					  struct snd_info_buffer *buffer)
{}

static void snd_pcm_substream_proc_info_read(struct snd_info_entry *entry,
					     struct snd_info_buffer *buffer)
{}

static void snd_pcm_substream_proc_hw_params_read(struct snd_info_entry *entry,
						  struct snd_info_buffer *buffer)
{}

static void snd_pcm_substream_proc_sw_params_read(struct snd_info_entry *entry,
						  struct snd_info_buffer *buffer)
{}

static void snd_pcm_substream_proc_status_read(struct snd_info_entry *entry,
					       struct snd_info_buffer *buffer)
{}

#ifdef CONFIG_SND_PCM_XRUN_DEBUG
static void snd_pcm_xrun_injection_write(struct snd_info_entry *entry,
					 struct snd_info_buffer *buffer)
{}

static void snd_pcm_xrun_debug_read(struct snd_info_entry *entry,
				    struct snd_info_buffer *buffer)
{}

static void snd_pcm_xrun_debug_write(struct snd_info_entry *entry,
				     struct snd_info_buffer *buffer)
{}
#endif

static int snd_pcm_stream_proc_init(struct snd_pcm_str *pstr)
{}

static int snd_pcm_stream_proc_done(struct snd_pcm_str *pstr)
{}

static struct snd_info_entry *
create_substream_info_entry(struct snd_pcm_substream *substream,
			    const char *name,
			    void (*read)(struct snd_info_entry *,
					 struct snd_info_buffer *))
{}

static int snd_pcm_substream_proc_init(struct snd_pcm_substream *substream)
{}

#else /* !CONFIG_SND_VERBOSE_PROCFS */
static inline int snd_pcm_stream_proc_init(struct snd_pcm_str *pstr) { return 0; }
static inline int snd_pcm_stream_proc_done(struct snd_pcm_str *pstr) { return 0; }
static inline int snd_pcm_substream_proc_init(struct snd_pcm_substream *substream) { return 0; }
#endif /* CONFIG_SND_VERBOSE_PROCFS */

static const struct attribute_group *pcm_dev_attr_groups[];

/*
 * PM callbacks: we need to deal only with suspend here, as the resume is
 * triggered either from user-space or the driver's resume callback
 */
#ifdef CONFIG_PM_SLEEP
static int do_pcm_suspend(struct device *dev)
{}
#endif

static const struct dev_pm_ops pcm_dev_pm_ops =;

/* device type for PCM -- basically only for passing PM callbacks */
static const struct device_type pcm_dev_type =;

/**
 * snd_pcm_new_stream - create a new PCM stream
 * @pcm: the pcm instance
 * @stream: the stream direction, SNDRV_PCM_STREAM_XXX
 * @substream_count: the number of substreams
 *
 * Creates a new stream for the pcm.
 * The corresponding stream on the pcm must have been empty before
 * calling this, i.e. zero must be given to the argument of
 * snd_pcm_new().
 *
 * Return: Zero if successful, or a negative error code on failure.
 */
int snd_pcm_new_stream(struct snd_pcm *pcm, int stream, int substream_count)
{}				
EXPORT_SYMBOL();

static int _snd_pcm_new(struct snd_card *card, const char *id, int device,
		int playback_count, int capture_count, bool internal,
		struct snd_pcm **rpcm)
{}

/**
 * snd_pcm_new - create a new PCM instance
 * @card: the card instance
 * @id: the id string
 * @device: the device index (zero based)
 * @playback_count: the number of substreams for playback
 * @capture_count: the number of substreams for capture
 * @rpcm: the pointer to store the new pcm instance
 *
 * Creates a new PCM instance.
 *
 * The pcm operators have to be set afterwards to the new instance
 * via snd_pcm_set_ops().
 *
 * Return: Zero if successful, or a negative error code on failure.
 */
int snd_pcm_new(struct snd_card *card, const char *id, int device,
		int playback_count, int capture_count, struct snd_pcm **rpcm)
{}
EXPORT_SYMBOL();

/**
 * snd_pcm_new_internal - create a new internal PCM instance
 * @card: the card instance
 * @id: the id string
 * @device: the device index (zero based - shared with normal PCMs)
 * @playback_count: the number of substreams for playback
 * @capture_count: the number of substreams for capture
 * @rpcm: the pointer to store the new pcm instance
 *
 * Creates a new internal PCM instance with no userspace device or procfs
 * entries. This is used by ASoC Back End PCMs in order to create a PCM that
 * will only be used internally by kernel drivers. i.e. it cannot be opened
 * by userspace. It provides existing ASoC components drivers with a substream
 * and access to any private data.
 *
 * The pcm operators have to be set afterwards to the new instance
 * via snd_pcm_set_ops().
 *
 * Return: Zero if successful, or a negative error code on failure.
 */
int snd_pcm_new_internal(struct snd_card *card, const char *id, int device,
	int playback_count, int capture_count,
	struct snd_pcm **rpcm)
{}
EXPORT_SYMBOL();

static void free_chmap(struct snd_pcm_str *pstr)
{}

static void snd_pcm_free_stream(struct snd_pcm_str * pstr)
{}

#if IS_ENABLED(CONFIG_SND_PCM_OSS)
#define pcm_call_notify(pcm, call)
#else
#define pcm_call_notify
#endif

static int snd_pcm_free(struct snd_pcm *pcm)
{}

static int snd_pcm_dev_free(struct snd_device *device)
{}

int snd_pcm_attach_substream(struct snd_pcm *pcm, int stream,
			     struct file *file,
			     struct snd_pcm_substream **rsubstream)
{}

void snd_pcm_detach_substream(struct snd_pcm_substream *substream)
{}

static ssize_t pcm_class_show(struct device *dev,
			      struct device_attribute *attr, char *buf)
{}

static DEVICE_ATTR_RO(pcm_class);
static struct attribute *pcm_dev_attrs[] =;

static const struct attribute_group pcm_dev_attr_group =;

static const struct attribute_group *pcm_dev_attr_groups[] =;

static int snd_pcm_dev_register(struct snd_device *device)
{}

static int snd_pcm_dev_disconnect(struct snd_device *device)
{}

#if IS_ENABLED(CONFIG_SND_PCM_OSS)
/**
 * snd_pcm_notify - Add/remove the notify list
 * @notify: PCM notify list
 * @nfree: 0 = register, 1 = unregister
 *
 * This adds the given notifier to the global list so that the callback is
 * called for each registered PCM devices.  This exists only for PCM OSS
 * emulation, so far.
 *
 * Return: zero if successful, or a negative error code
 */
int snd_pcm_notify(struct snd_pcm_notify *notify, int nfree)
{}
EXPORT_SYMBOL();
#endif /* CONFIG_SND_PCM_OSS */

#ifdef CONFIG_SND_PROC_FS
/*
 *  Info interface
 */

static void snd_pcm_proc_read(struct snd_info_entry *entry,
			      struct snd_info_buffer *buffer)
{}

static struct snd_info_entry *snd_pcm_proc_entry;

static void snd_pcm_proc_init(void)
{}

static void snd_pcm_proc_done(void)
{}

#else /* !CONFIG_SND_PROC_FS */
#define snd_pcm_proc_init
#define snd_pcm_proc_done
#endif /* CONFIG_SND_PROC_FS */


/*
 *  ENTRY functions
 */

static int __init alsa_pcm_init(void)
{}

static void __exit alsa_pcm_exit(void)
{}

module_init()
module_exit()