FILE
soc-link.c
File preview with syntax highlighting.
linux-6.19.14/sound/soc/soc-link.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.