Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
torvalds
GitHub Repository: torvalds/linux
Path: blob/master/sound/soc/soc-link.c
26378 views
1
// SPDX-License-Identifier: GPL-2.0
2
//
3
// soc-link.c
4
//
5
// Copyright (C) 2019 Renesas Electronics Corp.
6
// Kuninori Morimoto <[email protected]>
7
//
8
#include <sound/soc.h>
9
#include <sound/soc-link.h>
10
11
#define soc_link_ret(rtd, ret) _soc_link_ret(rtd, __func__, ret)
12
static inline int _soc_link_ret(struct snd_soc_pcm_runtime *rtd,
13
const char *func, int ret)
14
{
15
return snd_soc_ret(rtd->dev, ret,
16
"at %s() on %s\n", func, rtd->dai_link->name);
17
}
18
19
/*
20
* We might want to check substream by using list.
21
* In such case, we can update these macros.
22
*/
23
#define soc_link_mark_push(rtd, substream, tgt) ((rtd)->mark_##tgt = substream)
24
#define soc_link_mark_pop(rtd, tgt) ((rtd)->mark_##tgt = NULL)
25
#define soc_link_mark_match(rtd, substream, tgt) ((rtd)->mark_##tgt == substream)
26
27
int snd_soc_link_init(struct snd_soc_pcm_runtime *rtd)
28
{
29
int ret = 0;
30
31
if (rtd->dai_link->init)
32
ret = rtd->dai_link->init(rtd);
33
34
return soc_link_ret(rtd, ret);
35
}
36
37
void snd_soc_link_exit(struct snd_soc_pcm_runtime *rtd)
38
{
39
if (rtd->dai_link->exit)
40
rtd->dai_link->exit(rtd);
41
}
42
43
int snd_soc_link_be_hw_params_fixup(struct snd_soc_pcm_runtime *rtd,
44
struct snd_pcm_hw_params *params)
45
{
46
int ret = 0;
47
48
if (rtd->dai_link->be_hw_params_fixup)
49
ret = rtd->dai_link->be_hw_params_fixup(rtd, params);
50
51
return soc_link_ret(rtd, ret);
52
}
53
54
int snd_soc_link_startup(struct snd_pcm_substream *substream)
55
{
56
struct snd_soc_pcm_runtime *rtd = snd_soc_substream_to_rtd(substream);
57
int ret = 0;
58
59
if (rtd->dai_link->ops &&
60
rtd->dai_link->ops->startup)
61
ret = rtd->dai_link->ops->startup(substream);
62
63
/* mark substream if succeeded */
64
if (ret == 0)
65
soc_link_mark_push(rtd, substream, startup);
66
67
return soc_link_ret(rtd, ret);
68
}
69
70
void snd_soc_link_shutdown(struct snd_pcm_substream *substream,
71
int rollback)
72
{
73
struct snd_soc_pcm_runtime *rtd = snd_soc_substream_to_rtd(substream);
74
75
if (rollback && !soc_link_mark_match(rtd, substream, startup))
76
return;
77
78
if (rtd->dai_link->ops &&
79
rtd->dai_link->ops->shutdown)
80
rtd->dai_link->ops->shutdown(substream);
81
82
/* remove marked substream */
83
soc_link_mark_pop(rtd, startup);
84
}
85
86
int snd_soc_link_prepare(struct snd_pcm_substream *substream)
87
{
88
struct snd_soc_pcm_runtime *rtd = snd_soc_substream_to_rtd(substream);
89
int ret = 0;
90
91
if (rtd->dai_link->ops &&
92
rtd->dai_link->ops->prepare)
93
ret = rtd->dai_link->ops->prepare(substream);
94
95
return soc_link_ret(rtd, ret);
96
}
97
98
int snd_soc_link_hw_params(struct snd_pcm_substream *substream,
99
struct snd_pcm_hw_params *params)
100
{
101
struct snd_soc_pcm_runtime *rtd = snd_soc_substream_to_rtd(substream);
102
int ret = 0;
103
104
if (rtd->dai_link->ops &&
105
rtd->dai_link->ops->hw_params)
106
ret = rtd->dai_link->ops->hw_params(substream, params);
107
108
/* mark substream if succeeded */
109
if (ret == 0)
110
soc_link_mark_push(rtd, substream, hw_params);
111
112
return soc_link_ret(rtd, ret);
113
}
114
115
void snd_soc_link_hw_free(struct snd_pcm_substream *substream, int rollback)
116
{
117
struct snd_soc_pcm_runtime *rtd = snd_soc_substream_to_rtd(substream);
118
119
if (rollback && !soc_link_mark_match(rtd, substream, hw_params))
120
return;
121
122
if (rtd->dai_link->ops &&
123
rtd->dai_link->ops->hw_free)
124
rtd->dai_link->ops->hw_free(substream);
125
126
/* remove marked substream */
127
soc_link_mark_pop(rtd, hw_params);
128
}
129
130
static int soc_link_trigger(struct snd_pcm_substream *substream, int cmd)
131
{
132
struct snd_soc_pcm_runtime *rtd = snd_soc_substream_to_rtd(substream);
133
int ret = 0;
134
135
if (rtd->dai_link->ops &&
136
rtd->dai_link->ops->trigger)
137
ret = rtd->dai_link->ops->trigger(substream, cmd);
138
139
return soc_link_ret(rtd, ret);
140
}
141
142
int snd_soc_link_trigger(struct snd_pcm_substream *substream, int cmd,
143
int rollback)
144
{
145
struct snd_soc_pcm_runtime *rtd = snd_soc_substream_to_rtd(substream);
146
int ret = 0;
147
148
switch (cmd) {
149
case SNDRV_PCM_TRIGGER_START:
150
case SNDRV_PCM_TRIGGER_RESUME:
151
case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
152
ret = soc_link_trigger(substream, cmd);
153
if (ret < 0)
154
break;
155
soc_link_mark_push(rtd, substream, trigger);
156
break;
157
case SNDRV_PCM_TRIGGER_STOP:
158
case SNDRV_PCM_TRIGGER_SUSPEND:
159
case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
160
if (rollback && !soc_link_mark_match(rtd, substream, trigger))
161
break;
162
163
ret = soc_link_trigger(substream, cmd);
164
soc_link_mark_pop(rtd, startup);
165
}
166
167
return ret;
168
}
169
170
int snd_soc_link_compr_startup(struct snd_compr_stream *cstream)
171
{
172
struct snd_soc_pcm_runtime *rtd = cstream->private_data;
173
int ret = 0;
174
175
if (rtd->dai_link->compr_ops &&
176
rtd->dai_link->compr_ops->startup)
177
ret = rtd->dai_link->compr_ops->startup(cstream);
178
179
if (ret == 0)
180
soc_link_mark_push(rtd, cstream, compr_startup);
181
182
return soc_link_ret(rtd, ret);
183
}
184
EXPORT_SYMBOL_GPL(snd_soc_link_compr_startup);
185
186
void snd_soc_link_compr_shutdown(struct snd_compr_stream *cstream,
187
int rollback)
188
{
189
struct snd_soc_pcm_runtime *rtd = cstream->private_data;
190
191
if (rollback && !soc_link_mark_match(rtd, cstream, compr_startup))
192
return;
193
194
if (rtd->dai_link->compr_ops &&
195
rtd->dai_link->compr_ops->shutdown)
196
rtd->dai_link->compr_ops->shutdown(cstream);
197
198
soc_link_mark_pop(rtd, compr_startup);
199
}
200
EXPORT_SYMBOL_GPL(snd_soc_link_compr_shutdown);
201
202
int snd_soc_link_compr_set_params(struct snd_compr_stream *cstream)
203
{
204
struct snd_soc_pcm_runtime *rtd = cstream->private_data;
205
int ret = 0;
206
207
if (rtd->dai_link->compr_ops &&
208
rtd->dai_link->compr_ops->set_params)
209
ret = rtd->dai_link->compr_ops->set_params(cstream);
210
211
return soc_link_ret(rtd, ret);
212
}
213
EXPORT_SYMBOL_GPL(snd_soc_link_compr_set_params);
214
215