linux/sound/hda/hdac_stream.c

// SPDX-License-Identifier: GPL-2.0-only
/*
 * HD-audio stream operations
 */

#include <linux/kernel.h>
#include <linux/delay.h>
#include <linux/export.h>
#include <linux/clocksource.h>
#include <sound/compress_driver.h>
#include <sound/core.h>
#include <sound/pcm.h>
#include <sound/hdaudio.h>
#include <sound/hda_register.h>
#include "trace.h"

/*
 * the hdac_stream library is intended to be used with the following
 * transitions. The states are not formally defined in the code but loosely
 * inspired by boolean variables. Note that the 'prepared' field is not used
 * in this library but by the callers during the hw_params/prepare transitions
 *
 *			   |
 *	stream_init()	   |
 *			   v
 *			+--+-------+
 *			|  unused  |
 *			+--+----+--+
 *			   |    ^
 *	stream_assign()	   | 	|    stream_release()
 *			   v	|
 *			+--+----+--+
 *			|  opened  |
 *			+--+----+--+
 *			   |    ^
 *	stream_reset()	   |    |
 *	stream_setup()	   |	|    stream_cleanup()
 *			   v	|
 *			+--+----+--+
 *			| prepared |
 *			+--+----+--+
 *			   |    ^
 *	stream_start()	   | 	|    stream_stop()
 *			   v	|
 *			+--+----+--+
 *			|  running |
 *			+----------+
 */

/**
 * snd_hdac_get_stream_stripe_ctl - get stripe control value
 * @bus: HD-audio core bus
 * @substream: PCM substream
 */
int snd_hdac_get_stream_stripe_ctl(struct hdac_bus *bus,
				   struct snd_pcm_substream *substream)
{}
EXPORT_SYMBOL_GPL();

/**
 * snd_hdac_stream_init - initialize each stream (aka device)
 * @bus: HD-audio core bus
 * @azx_dev: HD-audio core stream object to initialize
 * @idx: stream index number
 * @direction: stream direction (SNDRV_PCM_STREAM_PLAYBACK or SNDRV_PCM_STREAM_CAPTURE)
 * @tag: the tag id to assign
 *
 * Assign the starting bdl address to each stream (device) and initialize.
 */
void snd_hdac_stream_init(struct hdac_bus *bus, struct hdac_stream *azx_dev,
			  int idx, int direction, int tag)
{}
EXPORT_SYMBOL_GPL();

/**
 * snd_hdac_stream_start - start a stream
 * @azx_dev: HD-audio core stream to start
 *
 * Start a stream, set start_wallclk and set the running flag.
 */
void snd_hdac_stream_start(struct hdac_stream *azx_dev)
{}
EXPORT_SYMBOL_GPL();

/**
 * snd_hdac_stream_clear - helper to clear stream registers and stop DMA transfers
 * @azx_dev: HD-audio core stream to stop
 */
static void snd_hdac_stream_clear(struct hdac_stream *azx_dev)
{}

/**
 * snd_hdac_stream_stop - stop a stream
 * @azx_dev: HD-audio core stream to stop
 *
 * Stop a stream DMA and disable stream interrupt
 */
void snd_hdac_stream_stop(struct hdac_stream *azx_dev)
{}
EXPORT_SYMBOL_GPL();

/**
 * snd_hdac_stop_streams - stop all streams
 * @bus: HD-audio core bus
 */
void snd_hdac_stop_streams(struct hdac_bus *bus)
{}
EXPORT_SYMBOL_GPL();

/**
 * snd_hdac_stop_streams_and_chip - stop all streams and chip if running
 * @bus: HD-audio core bus
 */
void snd_hdac_stop_streams_and_chip(struct hdac_bus *bus)
{}
EXPORT_SYMBOL_GPL();

/**
 * snd_hdac_stream_reset - reset a stream
 * @azx_dev: HD-audio core stream to reset
 */
void snd_hdac_stream_reset(struct hdac_stream *azx_dev)
{}
EXPORT_SYMBOL_GPL();

/**
 * snd_hdac_stream_setup -  set up the SD for streaming
 * @azx_dev: HD-audio core stream to set up
 * @code_loading: Whether the stream is for PCM or code-loading.
 */
int snd_hdac_stream_setup(struct hdac_stream *azx_dev, bool code_loading)
{}
EXPORT_SYMBOL_GPL();

/**
 * snd_hdac_stream_cleanup - cleanup a stream
 * @azx_dev: HD-audio core stream to clean up
 */
void snd_hdac_stream_cleanup(struct hdac_stream *azx_dev)
{}
EXPORT_SYMBOL_GPL();

/**
 * snd_hdac_stream_assign - assign a stream for the PCM
 * @bus: HD-audio core bus
 * @substream: PCM substream to assign
 *
 * Look for an unused stream for the given PCM substream, assign it
 * and return the stream object.  If no stream is free, returns NULL.
 * The function tries to keep using the same stream object when it's used
 * beforehand.  Also, when bus->reverse_assign flag is set, the last free
 * or matching entry is returned.  This is needed for some strange codecs.
 */
struct hdac_stream *snd_hdac_stream_assign(struct hdac_bus *bus,
					   struct snd_pcm_substream *substream)
{}
EXPORT_SYMBOL_GPL();

/**
 * snd_hdac_stream_release_locked - release the assigned stream
 * @azx_dev: HD-audio core stream to release
 *
 * Release the stream that has been assigned by snd_hdac_stream_assign().
 * The bus->reg_lock needs to be taken at a higher level
 */
void snd_hdac_stream_release_locked(struct hdac_stream *azx_dev)
{}
EXPORT_SYMBOL_GPL();

/**
 * snd_hdac_stream_release - release the assigned stream
 * @azx_dev: HD-audio core stream to release
 *
 * Release the stream that has been assigned by snd_hdac_stream_assign().
 */
void snd_hdac_stream_release(struct hdac_stream *azx_dev)
{}
EXPORT_SYMBOL_GPL();

/**
 * snd_hdac_get_stream - return hdac_stream based on stream_tag and
 * direction
 *
 * @bus: HD-audio core bus
 * @dir: direction for the stream to be found
 * @stream_tag: stream tag for stream to be found
 */
struct hdac_stream *snd_hdac_get_stream(struct hdac_bus *bus,
					int dir, int stream_tag)
{}
EXPORT_SYMBOL_GPL();

/*
 * set up a BDL entry
 */
static int setup_bdle(struct hdac_bus *bus,
		      struct snd_dma_buffer *dmab,
		      struct hdac_stream *azx_dev, __le32 **bdlp,
		      int ofs, int size, int with_ioc)
{}

/**
 * snd_hdac_stream_setup_periods - set up BDL entries
 * @azx_dev: HD-audio core stream to set up
 *
 * Set up the buffer descriptor table of the given stream based on the
 * period and buffer sizes of the assigned PCM substream.
 */
int snd_hdac_stream_setup_periods(struct hdac_stream *azx_dev)
{}
EXPORT_SYMBOL_GPL();

/**
 * snd_hdac_stream_set_params - set stream parameters
 * @azx_dev: HD-audio core stream for which parameters are to be set
 * @format_val: format value parameter
 *
 * Setup the HD-audio core stream parameters from substream of the stream
 * and passed format value
 */
int snd_hdac_stream_set_params(struct hdac_stream *azx_dev,
				 unsigned int format_val)
{}
EXPORT_SYMBOL_GPL();

static u64 azx_cc_read(const struct cyclecounter *cc)
{}

static void azx_timecounter_init(struct hdac_stream *azx_dev,
				 bool force, u64 last)
{}

/**
 * snd_hdac_stream_timecounter_init - initialize time counter
 * @azx_dev: HD-audio core stream (master stream)
 * @streams: bit flags of streams to set up
 *
 * Initializes the time counter of streams marked by the bit flags (each
 * bit corresponds to the stream index).
 * The trigger timestamp of PCM substream assigned to the given stream is
 * updated accordingly, too.
 */
void snd_hdac_stream_timecounter_init(struct hdac_stream *azx_dev,
				      unsigned int streams)
{}
EXPORT_SYMBOL_GPL();

/**
 * snd_hdac_stream_sync_trigger - turn on/off stream sync register
 * @azx_dev: HD-audio core stream (master stream)
 * @set: true = set, false = clear
 * @streams: bit flags of streams to sync
 * @reg: the stream sync register address
 */
void snd_hdac_stream_sync_trigger(struct hdac_stream *azx_dev, bool set,
				  unsigned int streams, unsigned int reg)
{}
EXPORT_SYMBOL_GPL();

/**
 * snd_hdac_stream_sync - sync with start/stop trigger operation
 * @azx_dev: HD-audio core stream (master stream)
 * @start: true = start, false = stop
 * @streams: bit flags of streams to sync
 *
 * For @start = true, wait until all FIFOs get ready.
 * For @start = false, wait until all RUN bits are cleared.
 */
void snd_hdac_stream_sync(struct hdac_stream *azx_dev, bool start,
			  unsigned int streams)
{}
EXPORT_SYMBOL_GPL();

/**
 * snd_hdac_stream_spbcap_enable - enable SPIB for a stream
 * @bus: HD-audio core bus
 * @enable: flag to enable/disable SPIB
 * @index: stream index for which SPIB need to be enabled
 */
void snd_hdac_stream_spbcap_enable(struct hdac_bus *bus,
				   bool enable, int index)
{}
EXPORT_SYMBOL_GPL();

/**
 * snd_hdac_stream_set_spib - sets the spib value of a stream
 * @bus: HD-audio core bus
 * @azx_dev: hdac_stream
 * @value: spib value to set
 */
int snd_hdac_stream_set_spib(struct hdac_bus *bus,
			     struct hdac_stream *azx_dev, u32 value)
{}
EXPORT_SYMBOL_GPL();

/**
 * snd_hdac_stream_get_spbmaxfifo - gets the spib value of a stream
 * @bus: HD-audio core bus
 * @azx_dev: hdac_stream
 *
 * Return maxfifo for the stream
 */
int snd_hdac_stream_get_spbmaxfifo(struct hdac_bus *bus,
				   struct hdac_stream *azx_dev)
{}
EXPORT_SYMBOL_GPL();

/**
 * snd_hdac_stream_drsm_enable - enable DMA resume for a stream
 * @bus: HD-audio core bus
 * @enable: flag to enable/disable DRSM
 * @index: stream index for which DRSM need to be enabled
 */
void snd_hdac_stream_drsm_enable(struct hdac_bus *bus,
				 bool enable, int index)
{}
EXPORT_SYMBOL_GPL();

/*
 * snd_hdac_stream_wait_drsm - wait for HW to clear RSM for a stream
 * @azx_dev: HD-audio core stream to await RSM for
 *
 * Returns 0 on success and -ETIMEDOUT upon a timeout.
 */
int snd_hdac_stream_wait_drsm(struct hdac_stream *azx_dev)
{}
EXPORT_SYMBOL_GPL();

/**
 * snd_hdac_stream_set_dpibr - sets the dpibr value of a stream
 * @bus: HD-audio core bus
 * @azx_dev: hdac_stream
 * @value: dpib value to set
 */
int snd_hdac_stream_set_dpibr(struct hdac_bus *bus,
			      struct hdac_stream *azx_dev, u32 value)
{}
EXPORT_SYMBOL_GPL();

/**
 * snd_hdac_stream_set_lpib - sets the lpib value of a stream
 * @azx_dev: hdac_stream
 * @value: lpib value to set
 */
int snd_hdac_stream_set_lpib(struct hdac_stream *azx_dev, u32 value)
{}
EXPORT_SYMBOL_GPL();

#ifdef CONFIG_SND_HDA_DSP_LOADER
/**
 * snd_hdac_dsp_prepare - prepare for DSP loading
 * @azx_dev: HD-audio core stream used for DSP loading
 * @format: HD-audio stream format
 * @byte_size: data chunk byte size
 * @bufp: allocated buffer
 *
 * Allocate the buffer for the given size and set up the given stream for
 * DSP loading.  Returns the stream tag (>= 0), or a negative error code.
 */
int snd_hdac_dsp_prepare(struct hdac_stream *azx_dev, unsigned int format,
			 unsigned int byte_size, struct snd_dma_buffer *bufp)
{}
EXPORT_SYMBOL_GPL();

/**
 * snd_hdac_dsp_trigger - start / stop DSP loading
 * @azx_dev: HD-audio core stream used for DSP loading
 * @start: trigger start or stop
 */
void snd_hdac_dsp_trigger(struct hdac_stream *azx_dev, bool start)
{}
EXPORT_SYMBOL_GPL();

/**
 * snd_hdac_dsp_cleanup - clean up the stream from DSP loading to normal
 * @azx_dev: HD-audio core stream used for DSP loading
 * @dmab: buffer used by DSP loading
 */
void snd_hdac_dsp_cleanup(struct hdac_stream *azx_dev,
			  struct snd_dma_buffer *dmab)
{}
EXPORT_SYMBOL_GPL();
#endif /* CONFIG_SND_HDA_DSP_LOADER */