aboutsummaryrefslogtreecommitdiffstats
path: root/include/sound/soc-dsp.h
blob: 033d61a2529a8996211231f96bf8856f70713c36 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
/*
 * linux/sound/soc-dsp.h -- ALSA SoC DSP
 *
 * Author:		Liam Girdwood <lrg@slimlogic.co.uk>
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License version 2 as
 * published by the Free Software Foundation.
 */

#ifndef __LINUX_SND_SOC_DSP_H
#define __LINUX_SND_SOC_DSP_H

#include <sound/pcm.h>

struct snd_soc_dapm_widget;

/*
 * Types of runtime_update to perform (e.g. originated from FE PCM ops
 * or audio route changes triggered by muxes/mixers.
 */
#define SND_SOC_DSP_UPDATE_NO	0
#define SND_SOC_DSP_UPDATE_BE	1
#define SND_SOC_DSP_UPDATE_FE	2

/*
 * DSP trigger ordering. Triggering flexibility is required as some DSPs
 * require triggering before/after their clients/hosts.
 *
 * i.e. some clients may want to manually order this call in their PCM
 * trigger() whilst others will just use the regular core ordering.
 */
enum snd_soc_dsp_trigger {
	SND_SOC_DSP_TRIGGER_PRE		= 0,
	SND_SOC_DSP_TRIGGER_POST,
	SND_SOC_DSP_TRIGGER_BESPOKE,
};

/*
 * The DSP Frontend -> Backend link state.
 */
enum snd_soc_dsp_link_state {
	SND_SOC_DSP_LINK_STATE_NEW	= 0,	/* newly created path */
	SND_SOC_DSP_LINK_STATE_FREE,			/* path to be dismantled */
};

struct snd_soc_dsp_params {
	struct snd_soc_pcm_runtime *be;
	struct snd_soc_pcm_runtime *fe;
	enum snd_soc_dsp_link_state state;
	struct list_head list_be;
	struct list_head list_fe;
	struct snd_pcm_hw_params hw_params;
#ifdef CONFIG_DEBUG_FS
	struct dentry *debugfs_state;
#endif
};

struct snd_soc_dsp_link {
	bool capture;
	bool playback;
	enum snd_soc_dsp_trigger trigger[2];
};

/* FE DSP PCM ops - called by soc-core */
int soc_dsp_fe_dai_open(struct snd_pcm_substream *substream);
int soc_dsp_fe_dai_close(struct snd_pcm_substream *substream);
int soc_dsp_fe_dai_prepare(struct snd_pcm_substream *substream);
int soc_dsp_fe_dai_hw_free(struct snd_pcm_substream *substream);
int soc_dsp_fe_dai_trigger(struct snd_pcm_substream *substream, int cmd);
int soc_dsp_fe_dai_hw_params(struct snd_pcm_substream *substream,
				    struct snd_pcm_hw_params *params);

/* Backend DSP trigger.
 * Can be called by core or components depending on trigger config.
 */
int soc_dsp_be_dai_trigger(struct snd_soc_pcm_runtime *fe, int stream, int cmd);

/* Is this trigger() call required for this FE and stream */
static inline int snd_soc_dsp_is_trigger_for_fe(struct snd_soc_pcm_runtime *fe,
		int stream)
{
	return (fe->dsp[stream].runtime_update == SND_SOC_DSP_UPDATE_FE);
}

static inline int snd_soc_dsp_is_op_for_be(struct snd_soc_pcm_runtime *fe,
		struct snd_soc_pcm_runtime *be, int stream)
{
	if ((fe->dsp[stream].runtime_update == SND_SOC_DSP_UPDATE_FE) ||
	    ((fe->dsp[stream].runtime_update == SND_SOC_DSP_UPDATE_BE) &&
		  be->dsp[stream].runtime_update))
		return 1;
	else
		return 0;
}

static inline int snd_soc_dsp_platform_trigger(struct snd_pcm_substream *substream,
	int cmd, struct snd_soc_platform *platform)
{
	if (platform->driver->ops->trigger)
		return platform->driver->ops->trigger(substream, cmd);
	return 0;
}

int soc_dsp_fe_state_count(struct snd_soc_pcm_runtime *be, int stream,
			enum snd_soc_dsp_state state);

/* Runtime update - open/close Backend DSP paths depending on mixer updates */
int soc_dsp_runtime_update(struct snd_soc_dapm_widget *widget);

/* Backend DSP suspend and resume */
int soc_dsp_be_digital_mute(struct snd_soc_pcm_runtime *fe, int mute);
int soc_dsp_fe_suspend(struct snd_soc_pcm_runtime *fe);
int soc_dsp_be_ac97_cpu_dai_suspend(struct snd_soc_pcm_runtime *fe);
int soc_dsp_fe_resume(struct snd_soc_pcm_runtime *fe);
int soc_dsp_be_ac97_cpu_dai_resume(struct snd_soc_pcm_runtime *fe);

/* DAPM stream events for Backend DSP paths */
int soc_dsp_dapm_stream_event(struct snd_soc_pcm_runtime *fe,
	int dir, const char *stream, int event);

static inline struct snd_pcm_substream *snd_soc_dsp_get_substream(
		struct snd_soc_pcm_runtime *be, int stream)
{
	return be->pcm->streams[stream].substream;
}

#endif