brintos

brintos / linux-shallow public Read only

0
0
Text · 5.6 KiB · fee4022 Raw
228 lines · c
1// SPDX-License-Identifier: GPL-2.02//3// soc-link.c4//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	/* Positive, Zero values are not errors */16	if (ret >= 0)17		return ret;18 19	/* Negative values might be errors */20	switch (ret) {21	case -EPROBE_DEFER:22	case -ENOTSUPP:23		break;24	default:25		dev_err(rtd->dev,26			"ASoC: error at %s on %s: %d\n",27			func, rtd->dai_link->name, ret);28	}29 30	return ret;31}32 33/*34 * We might want to check substream by using list.35 * In such case, we can update these macros.36 */37#define soc_link_mark_push(rtd, substream, tgt)		((rtd)->mark_##tgt = substream)38#define soc_link_mark_pop(rtd, substream, tgt)		((rtd)->mark_##tgt = NULL)39#define soc_link_mark_match(rtd, substream, tgt)	((rtd)->mark_##tgt == substream)40 41int snd_soc_link_init(struct snd_soc_pcm_runtime *rtd)42{43	int ret = 0;44 45	if (rtd->dai_link->init)46		ret = rtd->dai_link->init(rtd);47 48	return soc_link_ret(rtd, ret);49}50 51void snd_soc_link_exit(struct snd_soc_pcm_runtime *rtd)52{53	if (rtd->dai_link->exit)54		rtd->dai_link->exit(rtd);55}56 57int snd_soc_link_be_hw_params_fixup(struct snd_soc_pcm_runtime *rtd,58				    struct snd_pcm_hw_params *params)59{60	int ret = 0;61 62	if (rtd->dai_link->be_hw_params_fixup)63		ret = rtd->dai_link->be_hw_params_fixup(rtd, params);64 65	return soc_link_ret(rtd, ret);66}67 68int snd_soc_link_startup(struct snd_pcm_substream *substream)69{70	struct snd_soc_pcm_runtime *rtd = snd_soc_substream_to_rtd(substream);71	int ret = 0;72 73	if (rtd->dai_link->ops &&74	    rtd->dai_link->ops->startup)75		ret = rtd->dai_link->ops->startup(substream);76 77	/* mark substream if succeeded */78	if (ret == 0)79		soc_link_mark_push(rtd, substream, startup);80 81	return soc_link_ret(rtd, ret);82}83 84void snd_soc_link_shutdown(struct snd_pcm_substream *substream,85			   int rollback)86{87	struct snd_soc_pcm_runtime *rtd = snd_soc_substream_to_rtd(substream);88 89	if (rollback && !soc_link_mark_match(rtd, substream, startup))90		return;91 92	if (rtd->dai_link->ops &&93	    rtd->dai_link->ops->shutdown)94		rtd->dai_link->ops->shutdown(substream);95 96	/* remove marked substream */97	soc_link_mark_pop(rtd, substream, startup);98}99 100int snd_soc_link_prepare(struct snd_pcm_substream *substream)101{102	struct snd_soc_pcm_runtime *rtd = snd_soc_substream_to_rtd(substream);103	int ret = 0;104 105	if (rtd->dai_link->ops &&106	    rtd->dai_link->ops->prepare)107		ret = rtd->dai_link->ops->prepare(substream);108 109	return soc_link_ret(rtd, ret);110}111 112int snd_soc_link_hw_params(struct snd_pcm_substream *substream,113			   struct snd_pcm_hw_params *params)114{115	struct snd_soc_pcm_runtime *rtd = snd_soc_substream_to_rtd(substream);116	int ret = 0;117 118	if (rtd->dai_link->ops &&119	    rtd->dai_link->ops->hw_params)120		ret = rtd->dai_link->ops->hw_params(substream, params);121 122	/* mark substream if succeeded */123	if (ret == 0)124		soc_link_mark_push(rtd, substream, hw_params);125 126	return soc_link_ret(rtd, ret);127}128 129void snd_soc_link_hw_free(struct snd_pcm_substream *substream, int rollback)130{131	struct snd_soc_pcm_runtime *rtd = snd_soc_substream_to_rtd(substream);132 133	if (rollback && !soc_link_mark_match(rtd, substream, hw_params))134		return;135 136	if (rtd->dai_link->ops &&137	    rtd->dai_link->ops->hw_free)138		rtd->dai_link->ops->hw_free(substream);139 140	/* remove marked substream */141	soc_link_mark_pop(rtd, substream, hw_params);142}143 144static int soc_link_trigger(struct snd_pcm_substream *substream, int cmd)145{146	struct snd_soc_pcm_runtime *rtd = snd_soc_substream_to_rtd(substream);147	int ret = 0;148 149	if (rtd->dai_link->ops &&150	    rtd->dai_link->ops->trigger)151		ret = rtd->dai_link->ops->trigger(substream, cmd);152 153	return soc_link_ret(rtd, ret);154}155 156int snd_soc_link_trigger(struct snd_pcm_substream *substream, int cmd,157			 int rollback)158{159	struct snd_soc_pcm_runtime *rtd = snd_soc_substream_to_rtd(substream);160	int ret = 0;161 162	switch (cmd) {163	case SNDRV_PCM_TRIGGER_START:164	case SNDRV_PCM_TRIGGER_RESUME:165	case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:166		ret = soc_link_trigger(substream, cmd);167		if (ret < 0)168			break;169		soc_link_mark_push(rtd, substream, trigger);170		break;171	case SNDRV_PCM_TRIGGER_STOP:172	case SNDRV_PCM_TRIGGER_SUSPEND:173	case SNDRV_PCM_TRIGGER_PAUSE_PUSH:174		if (rollback && !soc_link_mark_match(rtd, substream, trigger))175			break;176 177		ret = soc_link_trigger(substream, cmd);178		soc_link_mark_pop(rtd, substream, startup);179	}180 181	return ret;182}183 184int snd_soc_link_compr_startup(struct snd_compr_stream *cstream)185{186	struct snd_soc_pcm_runtime *rtd = cstream->private_data;187	int ret = 0;188 189	if (rtd->dai_link->compr_ops &&190	    rtd->dai_link->compr_ops->startup)191		ret = rtd->dai_link->compr_ops->startup(cstream);192 193	if (ret == 0)194		soc_link_mark_push(rtd, cstream, compr_startup);195 196	return soc_link_ret(rtd, ret);197}198EXPORT_SYMBOL_GPL(snd_soc_link_compr_startup);199 200void snd_soc_link_compr_shutdown(struct snd_compr_stream *cstream,201				 int rollback)202{203	struct snd_soc_pcm_runtime *rtd = cstream->private_data;204 205	if (rollback && !soc_link_mark_match(rtd, cstream, compr_startup))206		return;207 208	if (rtd->dai_link->compr_ops &&209	    rtd->dai_link->compr_ops->shutdown)210		rtd->dai_link->compr_ops->shutdown(cstream);211 212	soc_link_mark_pop(rtd, cstream, compr_startup);213}214EXPORT_SYMBOL_GPL(snd_soc_link_compr_shutdown);215 216int snd_soc_link_compr_set_params(struct snd_compr_stream *cstream)217{218	struct snd_soc_pcm_runtime *rtd = cstream->private_data;219	int ret = 0;220 221	if (rtd->dai_link->compr_ops &&222	    rtd->dai_link->compr_ops->set_params)223		ret = rtd->dai_link->compr_ops->set_params(cstream);224 225	return soc_link_ret(rtd, ret);226}227EXPORT_SYMBOL_GPL(snd_soc_link_compr_set_params);228