File Index
Files and directories
Sign in
FILE

soc-link.c

File preview with syntax highlighting.

linux-6.19.14/sound/soc/soc-link.c C
  1// SPDX-License-Identifier: GPL-2.0
  2//
  3// soc-link.c
  4//
  5// Copyright (C) 2019 Renesas Electronics Corp.
  6// Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
  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)
 12static 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
 27int 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
 37void 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
 43int 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
 54int 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
 70void 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
 86int 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
 98int 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
115void 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
130static 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
142int 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
170int 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}
184EXPORT_SYMBOL_GPL(snd_soc_link_compr_startup);
185
186void 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}
200EXPORT_SYMBOL_GPL(snd_soc_link_compr_shutdown);
201
202int 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}
213EXPORT_SYMBOL_GPL(snd_soc_link_compr_set_params);
~/ Read-only file preview.