linux/include/sound/soc-dapm.h

/* SPDX-License-Identifier: GPL-2.0
 *
 * linux/sound/soc-dapm.h -- ALSA SoC Dynamic Audio Power Management
 *
 * Author:	Liam Girdwood
 * Created:	Aug 11th 2005
 * Copyright:	Wolfson Microelectronics. PLC.
 */

#ifndef __LINUX_SND_SOC_DAPM_H
#define __LINUX_SND_SOC_DAPM_H

#include <linux/types.h>
#include <sound/control.h>
#include <sound/soc-topology.h>
#include <sound/asoc.h>

struct device;
struct snd_pcm_substream;
struct snd_soc_pcm_runtime;
struct soc_enum;

/* widget has no PM register bit */
#define SND_SOC_NOPM

/*
 * SoC dynamic audio power management
 *
 * We can have up to 4 power domains
 *  1. Codec domain - VREF, VMID
 *     Usually controlled at codec probe/remove, although can be set
 *     at stream time if power is not needed for sidetone, etc.
 *  2. Platform/Machine domain - physically connected inputs and outputs
 *     Is platform/machine and user action specific, is set in the machine
 *     driver and by userspace e.g when HP are inserted
 *  3. Path domain - Internal codec path mixers
 *     Are automatically set when mixer and mux settings are
 *     changed by the user.
 *  4. Stream domain - DAC's and ADC's.
 *     Enabled when stream playback/capture is started.
 */

/* codec domain */
#define SND_SOC_DAPM_VMID(wname)

/* platform domain */
#define SND_SOC_DAPM_SIGGEN(wname)
#define SND_SOC_DAPM_SINK(wname)
#define SND_SOC_DAPM_INPUT(wname)
#define SND_SOC_DAPM_OUTPUT(wname)
#define SND_SOC_DAPM_MIC(wname, wevent)
#define SND_SOC_DAPM_HP(wname, wevent)
#define SND_SOC_DAPM_SPK(wname, wevent)
#define SND_SOC_DAPM_LINE(wname, wevent)

#define SND_SOC_DAPM_INIT_REG_VAL(wreg, wshift, winvert)

/* path domain */
#define SND_SOC_DAPM_PGA(wname, wreg, wshift, winvert,\
	 wcontrols, wncontrols)
#define SND_SOC_DAPM_OUT_DRV(wname, wreg, wshift, winvert,\
	 wcontrols, wncontrols)
#define SND_SOC_DAPM_MIXER(wname, wreg, wshift, winvert, \
	 wcontrols, wncontrols)
#define SND_SOC_DAPM_MIXER_NAMED_CTL(wname, wreg, wshift, winvert, \
	 wcontrols, wncontrols)
/* DEPRECATED: use SND_SOC_DAPM_SUPPLY */
#define SND_SOC_DAPM_MICBIAS(wname, wreg, wshift, winvert)
#define SND_SOC_DAPM_SWITCH(wname, wreg, wshift, winvert, wcontrols)
#define SND_SOC_DAPM_MUX(wname, wreg, wshift, winvert, wcontrols)
#define SND_SOC_DAPM_DEMUX(wname, wreg, wshift, winvert, wcontrols)

/* Simplified versions of above macros, assuming wncontrols = ARRAY_SIZE(wcontrols) */
#define SOC_PGA_ARRAY(wname, wreg, wshift, winvert,\
	 wcontrols)
#define SOC_MIXER_ARRAY(wname, wreg, wshift, winvert, \
	 wcontrols)
#define SOC_MIXER_NAMED_CTL_ARRAY(wname, wreg, wshift, winvert, \
	 wcontrols)

/* path domain with event - event handler must return 0 for success */
#define SND_SOC_DAPM_PGA_E(wname, wreg, wshift, winvert, wcontrols, \
	wncontrols, wevent, wflags)
#define SND_SOC_DAPM_OUT_DRV_E(wname, wreg, wshift, winvert, wcontrols, \
	wncontrols, wevent, wflags)
#define SND_SOC_DAPM_MIXER_E(wname, wreg, wshift, winvert, wcontrols, \
	wncontrols, wevent, wflags)
#define SND_SOC_DAPM_MIXER_NAMED_CTL_E(wname, wreg, wshift, winvert, \
	wcontrols, wncontrols, wevent, wflags)
#define SND_SOC_DAPM_SWITCH_E(wname, wreg, wshift, winvert, wcontrols, \
	wevent, wflags)
#define SND_SOC_DAPM_MUX_E(wname, wreg, wshift, winvert, wcontrols, \
	wevent, wflags)

/* additional sequencing control within an event type */
#define SND_SOC_DAPM_PGA_S(wname, wsubseq, wreg, wshift, winvert, \
	wevent, wflags)
#define SND_SOC_DAPM_SUPPLY_S(wname, wsubseq, wreg, wshift, winvert, wevent, \
	wflags)

/* Simplified versions of above macros, assuming wncontrols = ARRAY_SIZE(wcontrols) */
#define SOC_PGA_E_ARRAY(wname, wreg, wshift, winvert, wcontrols, \
	wevent, wflags)
#define SOC_MIXER_E_ARRAY(wname, wreg, wshift, winvert, wcontrols, \
	wevent, wflags)
#define SOC_MIXER_NAMED_CTL_E_ARRAY(wname, wreg, wshift, winvert, \
	wcontrols, wevent, wflags)

/* events that are pre and post DAPM */
#define SND_SOC_DAPM_PRE(wname, wevent)
#define SND_SOC_DAPM_POST(wname, wevent)

/* stream domain */
#define SND_SOC_DAPM_AIF_IN(wname, stname, wchan, wreg, wshift, winvert)
#define SND_SOC_DAPM_AIF_IN_E(wname, stname, wchan, wreg, wshift, winvert, \
			      wevent, wflags)
#define SND_SOC_DAPM_AIF_OUT(wname, stname, wchan, wreg, wshift, winvert)
#define SND_SOC_DAPM_AIF_OUT_E(wname, stname, wchan, wreg, wshift, winvert, \
			     wevent, wflags)
#define SND_SOC_DAPM_DAC(wname, stname, wreg, wshift, winvert)
#define SND_SOC_DAPM_DAC_E(wname, stname, wreg, wshift, winvert, \
			   wevent, wflags)

#define SND_SOC_DAPM_ADC(wname, stname, wreg, wshift, winvert)
#define SND_SOC_DAPM_ADC_E(wname, stname, wreg, wshift, winvert, \
			   wevent, wflags)
#define SND_SOC_DAPM_CLOCK_SUPPLY(wname)

/* generic widgets */
#define SND_SOC_DAPM_REG(wid, wname, wreg, wshift, wmask, won_val, woff_val)
#define SND_SOC_DAPM_SUPPLY(wname, wreg, wshift, winvert, wevent, wflags)
#define SND_SOC_DAPM_REGULATOR_SUPPLY(wname, wdelay, wflags)
#define SND_SOC_DAPM_PINCTRL(wname, active, sleep)



/* dapm kcontrol types */
#define SOC_DAPM_DOUBLE(xname, reg, lshift, rshift, max, invert)
#define SOC_DAPM_DOUBLE_R(xname, lreg, rreg, shift, max, invert)
#define SOC_DAPM_SINGLE(xname, reg, shift, max, invert)
#define SOC_DAPM_SINGLE_AUTODISABLE(xname, reg, shift, max, invert)
#define SOC_DAPM_SINGLE_VIRT(xname, max)
#define SOC_DAPM_SINGLE_TLV(xname, reg, shift, max, invert, tlv_array)
#define SOC_DAPM_SINGLE_TLV_AUTODISABLE(xname, reg, shift, max, invert, tlv_array)
#define SOC_DAPM_SINGLE_TLV_VIRT(xname, max, tlv_array)
#define SOC_DAPM_ENUM(xname, xenum)
#define SOC_DAPM_ENUM_EXT(xname, xenum, xget, xput)
#define SOC_DAPM_PIN_SWITCH(xname)

/* dapm stream operations */
#define SND_SOC_DAPM_STREAM_NOP
#define SND_SOC_DAPM_STREAM_START
#define SND_SOC_DAPM_STREAM_STOP
#define SND_SOC_DAPM_STREAM_SUSPEND
#define SND_SOC_DAPM_STREAM_RESUME
#define SND_SOC_DAPM_STREAM_PAUSE_PUSH
#define SND_SOC_DAPM_STREAM_PAUSE_RELEASE

/* dapm event types */
#define SND_SOC_DAPM_PRE_PMU
#define SND_SOC_DAPM_POST_PMU
#define SND_SOC_DAPM_PRE_PMD
#define SND_SOC_DAPM_POST_PMD
#define SND_SOC_DAPM_PRE_REG
#define SND_SOC_DAPM_POST_REG
#define SND_SOC_DAPM_WILL_PMU
#define SND_SOC_DAPM_WILL_PMD
#define SND_SOC_DAPM_PRE_POST_PMD
#define SND_SOC_DAPM_PRE_POST_PMU

/* convenience event type detection */
#define SND_SOC_DAPM_EVENT_ON(e)
#define SND_SOC_DAPM_EVENT_OFF(e)

/* regulator widget flags */
#define SND_SOC_DAPM_REGULATOR_BYPASS

struct snd_soc_dapm_widget;
enum snd_soc_dapm_type;
struct snd_soc_dapm_path;
struct snd_soc_dapm_pin;
struct snd_soc_dapm_route;
struct snd_soc_dapm_context;
struct regulator;
struct snd_soc_dapm_widget_list;
struct snd_soc_dapm_update;
enum snd_soc_dapm_direction;

/*
 * Bias levels
 *
 * @ON:      Bias is fully on for audio playback and capture operations.
 * @PREPARE: Prepare for audio operations. Called before DAPM switching for
 *           stream start and stop operations.
 * @STANDBY: Low power standby state when no playback/capture operations are
 *           in progress. NOTE: The transition time between STANDBY and ON
 *           should be as fast as possible and no longer than 10ms.
 * @OFF:     Power Off. No restrictions on transition times.
 */
enum snd_soc_bias_level {};

int dapm_regulator_event(struct snd_soc_dapm_widget *w, struct snd_kcontrol *kcontrol, int event);
int dapm_clock_event(struct snd_soc_dapm_widget *w, struct snd_kcontrol *kcontrol, int event);
int dapm_pinctrl_event(struct snd_soc_dapm_widget *w, struct snd_kcontrol *kcontrol, int event);

/* dapm controls */
int snd_soc_dapm_put_volsw(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol);
int snd_soc_dapm_get_volsw(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol);
int snd_soc_dapm_get_enum_double(struct snd_kcontrol *kcontrol,
	struct snd_ctl_elem_value *ucontrol);
int snd_soc_dapm_put_enum_double(struct snd_kcontrol *kcontrol,
	struct snd_ctl_elem_value *ucontrol);
int snd_soc_dapm_info_pin_switch(struct snd_kcontrol *kcontrol,
	struct snd_ctl_elem_info *uinfo);
int snd_soc_dapm_get_pin_switch(struct snd_kcontrol *kcontrol,
	struct snd_ctl_elem_value *uncontrol);
int snd_soc_dapm_put_pin_switch(struct snd_kcontrol *kcontrol,
	struct snd_ctl_elem_value *uncontrol);
int snd_soc_dapm_new_controls(struct snd_soc_dapm_context *dapm,
	const struct snd_soc_dapm_widget *widget, unsigned int num);
struct snd_soc_dapm_widget *snd_soc_dapm_new_control(struct snd_soc_dapm_context *dapm,
		const struct snd_soc_dapm_widget *widget);
struct snd_soc_dapm_widget *snd_soc_dapm_new_control_unlocked(struct snd_soc_dapm_context *dapm,
		const struct snd_soc_dapm_widget *widget);
int snd_soc_dapm_new_dai_widgets(struct snd_soc_dapm_context *dapm, struct snd_soc_dai *dai);
void snd_soc_dapm_free_widget(struct snd_soc_dapm_widget *w);
int snd_soc_dapm_link_dai_widgets(struct snd_soc_card *card);
void snd_soc_dapm_connect_dai_link_widgets(struct snd_soc_card *card);

int snd_soc_dapm_update_dai(struct snd_pcm_substream *substream,
			    struct snd_pcm_hw_params *params, struct snd_soc_dai *dai);
int snd_soc_dapm_widget_name_cmp(struct snd_soc_dapm_widget *widget, const char *s);

/* dapm path setup */
int snd_soc_dapm_new_widgets(struct snd_soc_card *card);
void snd_soc_dapm_free(struct snd_soc_dapm_context *dapm);
void snd_soc_dapm_init(struct snd_soc_dapm_context *dapm,
		       struct snd_soc_card *card, struct snd_soc_component *component);
int snd_soc_dapm_add_routes(struct snd_soc_dapm_context *dapm,
			    const struct snd_soc_dapm_route *route, int num);
int snd_soc_dapm_del_routes(struct snd_soc_dapm_context *dapm,
			    const struct snd_soc_dapm_route *route, int num);
int snd_soc_dapm_weak_routes(struct snd_soc_dapm_context *dapm,
			     const struct snd_soc_dapm_route *route, int num);
void snd_soc_dapm_free_widget(struct snd_soc_dapm_widget *w);

/* dapm events */
void snd_soc_dapm_stream_event(struct snd_soc_pcm_runtime *rtd, int stream, int event);
void snd_soc_dapm_stream_stop(struct snd_soc_pcm_runtime *rtd, int stream);
void snd_soc_dapm_shutdown(struct snd_soc_card *card);

/* external DAPM widget events */
int snd_soc_dapm_mixer_update_power(struct snd_soc_dapm_context *dapm,
		struct snd_kcontrol *kcontrol, int connect, struct snd_soc_dapm_update *update);
int snd_soc_dapm_mux_update_power(struct snd_soc_dapm_context *dapm,
		struct snd_kcontrol *kcontrol, int mux, struct soc_enum *e,
		struct snd_soc_dapm_update *update);

/* dapm sys fs - used by the core */
extern struct attribute *soc_dapm_dev_attrs[];
void snd_soc_dapm_debugfs_init(struct snd_soc_dapm_context *dapm, struct dentry *parent);

/* dapm audio pin control and status */
int snd_soc_dapm_enable_pin(struct snd_soc_dapm_context *dapm, const char *pin);
int snd_soc_dapm_enable_pin_unlocked(struct snd_soc_dapm_context *dapm, const char *pin);
int snd_soc_dapm_disable_pin(struct snd_soc_dapm_context *dapm, const char *pin);
int snd_soc_dapm_disable_pin_unlocked(struct snd_soc_dapm_context *dapm, const char *pin);
int snd_soc_dapm_nc_pin(struct snd_soc_dapm_context *dapm, const char *pin);
int snd_soc_dapm_nc_pin_unlocked(struct snd_soc_dapm_context *dapm, const char *pin);
int snd_soc_dapm_get_pin_status(struct snd_soc_dapm_context *dapm, const char *pin);
int snd_soc_dapm_sync(struct snd_soc_dapm_context *dapm);
int snd_soc_dapm_sync_unlocked(struct snd_soc_dapm_context *dapm);
int snd_soc_dapm_force_enable_pin(struct snd_soc_dapm_context *dapm, const char *pin);
int snd_soc_dapm_force_enable_pin_unlocked(struct snd_soc_dapm_context *dapm, const char *pin);
int snd_soc_dapm_ignore_suspend(struct snd_soc_dapm_context *dapm, const char *pin);
unsigned int dapm_kcontrol_get_value(const struct snd_kcontrol *kcontrol);

/* Mostly internal - should not normally be used */
void dapm_mark_endpoints_dirty(struct snd_soc_card *card);

/* dapm path query */
int snd_soc_dapm_dai_get_connected_widgets(struct snd_soc_dai *dai, int stream,
	struct snd_soc_dapm_widget_list **list,
	bool (*custom_stop_condition)(struct snd_soc_dapm_widget *, enum snd_soc_dapm_direction));
void snd_soc_dapm_dai_free_widgets(struct snd_soc_dapm_widget_list **list);

struct snd_soc_dapm_context *snd_soc_dapm_kcontrol_dapm(struct snd_kcontrol *kcontrol);
struct snd_soc_dapm_widget *snd_soc_dapm_kcontrol_widget(struct snd_kcontrol *kcontrol);

int snd_soc_dapm_force_bias_level(struct snd_soc_dapm_context *dapm, enum snd_soc_bias_level level);

/* dapm widget types */
enum snd_soc_dapm_type {};

/*
 * DAPM audio route definition.
 *
 * Defines an audio route originating at source via control and finishing
 * at sink.
 */
struct snd_soc_dapm_route {};

/* dapm audio path between two widgets */
struct snd_soc_dapm_path {};

/* dapm widget */
struct snd_soc_dapm_widget {};

struct snd_soc_dapm_update {};

/* DAPM context */
struct snd_soc_dapm_context {};

/* A list of widgets associated with an object, typically a snd_kcontrol */
struct snd_soc_dapm_widget_list {};

#define for_each_dapm_widgets(list, i, widget)

struct snd_soc_dapm_stats {};

struct snd_soc_dapm_pinctrl_priv {};

/**
 * snd_soc_dapm_init_bias_level() - Initialize DAPM bias level
 * @dapm: The DAPM context to initialize
 * @level: The DAPM level to initialize to
 *
 * This function only sets the driver internal state of the DAPM level and will
 * not modify the state of the device. Hence it should not be used during normal
 * operation, but only to synchronize the internal state to the device state.
 * E.g. during driver probe to set the DAPM level to the one corresponding with
 * the power-on reset state of the device.
 *
 * To change the DAPM state of the device use snd_soc_dapm_set_bias_level().
 */
static inline void snd_soc_dapm_init_bias_level(
	struct snd_soc_dapm_context *dapm, enum snd_soc_bias_level level)
{}

/**
 * snd_soc_dapm_get_bias_level() - Get current DAPM bias level
 * @dapm: The context for which to get the bias level
 *
 * Returns: The current bias level of the passed DAPM context.
 */
static inline enum snd_soc_bias_level snd_soc_dapm_get_bias_level(
	struct snd_soc_dapm_context *dapm)
{}

enum snd_soc_dapm_direction {};

#define SND_SOC_DAPM_DIR_TO_EP(x)

#define SND_SOC_DAPM_EP_SOURCE
#define SND_SOC_DAPM_EP_SINK

/**
 * snd_soc_dapm_widget_for_each_path - Iterates over all paths in the
 *   specified direction of a widget
 * @w: The widget
 * @dir: Whether to iterate over the paths where the specified widget is the
 *       incoming or outgoing widgets
 * @p: The path iterator variable
 */
#define snd_soc_dapm_widget_for_each_path(w, dir, p)

/**
 * snd_soc_dapm_widget_for_each_path_safe - Iterates over all paths in the
 *   specified direction of a widget
 * @w: The widget
 * @dir: Whether to iterate over the paths where the specified widget is the
 *       incoming or outgoing widgets
 * @p: The path iterator variable
 * @next_p: Temporary storage for the next path
 *
 *  This function works like snd_soc_dapm_widget_for_each_path, expect that
 *  it is safe to remove the current path from the list while iterating
 */
#define snd_soc_dapm_widget_for_each_path_safe(w, dir, p, next_p)

/**
 * snd_soc_dapm_widget_for_each_sink_path - Iterates over all paths leaving a
 *  widget
 * @w: The widget
 * @p: The path iterator variable
 */
#define snd_soc_dapm_widget_for_each_sink_path(w, p)

/**
 * snd_soc_dapm_widget_for_each_source_path - Iterates over all paths leading to
 *  a widget
 * @w: The widget
 * @p: The path iterator variable
 */
#define snd_soc_dapm_widget_for_each_source_path(w, p)

#endif