1 // SPDX-License-Identifier: GPL-2.0 1 2 // 3 // soc-link.c 4 // 5 // Copyright (C) 2019 Renesas Electronics Corp 6 // Kuninori Morimoto <kuninori.morimoto.gx@ren 7 // 8 #include <sound/soc.h> 9 #include <sound/soc-link.h> 10 11 #define soc_link_ret(rtd, ret) _soc_link_ret(r 12 static inline int _soc_link_ret(struct snd_soc 13 const char *fu 14 { 15 /* Positive, Zero values are not error 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 27 func, rtd->dai_link->n 28 } 29 30 return ret; 31 } 32 33 /* 34 * We might want to check substream by using l 35 * In such case, we can update these macros. 36 */ 37 #define soc_link_mark_push(rtd, substream, tgt 38 #define soc_link_mark_pop(rtd, substream, tgt) 39 #define soc_link_mark_match(rtd, substream, tg 40 41 int snd_soc_link_init(struct snd_soc_pcm_runti 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 51 void snd_soc_link_exit(struct snd_soc_pcm_runt 52 { 53 if (rtd->dai_link->exit) 54 rtd->dai_link->exit(rtd); 55 } 56 57 int snd_soc_link_be_hw_params_fixup(struct snd 58 struct snd 59 { 60 int ret = 0; 61 62 if (rtd->dai_link->be_hw_params_fixup) 63 ret = rtd->dai_link->be_hw_par 64 65 return soc_link_ret(rtd, ret); 66 } 67 68 int snd_soc_link_startup(struct snd_pcm_substr 69 { 70 struct snd_soc_pcm_runtime *rtd = snd_ 71 int ret = 0; 72 73 if (rtd->dai_link->ops && 74 rtd->dai_link->ops->startup) 75 ret = rtd->dai_link->ops->star 76 77 /* mark substream if succeeded */ 78 if (ret == 0) 79 soc_link_mark_push(rtd, substr 80 81 return soc_link_ret(rtd, ret); 82 } 83 84 void snd_soc_link_shutdown(struct snd_pcm_subs 85 int rollback) 86 { 87 struct snd_soc_pcm_runtime *rtd = snd_ 88 89 if (rollback && !soc_link_mark_match(r 90 return; 91 92 if (rtd->dai_link->ops && 93 rtd->dai_link->ops->shutdown) 94 rtd->dai_link->ops->shutdown(s 95 96 /* remove marked substream */ 97 soc_link_mark_pop(rtd, substream, star 98 } 99 100 int snd_soc_link_prepare(struct snd_pcm_substr 101 { 102 struct snd_soc_pcm_runtime *rtd = snd_ 103 int ret = 0; 104 105 if (rtd->dai_link->ops && 106 rtd->dai_link->ops->prepare) 107 ret = rtd->dai_link->ops->prep 108 109 return soc_link_ret(rtd, ret); 110 } 111 112 int snd_soc_link_hw_params(struct snd_pcm_subs 113 struct snd_pcm_hw_p 114 { 115 struct snd_soc_pcm_runtime *rtd = snd_ 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_p 121 122 /* mark substream if succeeded */ 123 if (ret == 0) 124 soc_link_mark_push(rtd, substr 125 126 return soc_link_ret(rtd, ret); 127 } 128 129 void snd_soc_link_hw_free(struct snd_pcm_subst 130 { 131 struct snd_soc_pcm_runtime *rtd = snd_ 132 133 if (rollback && !soc_link_mark_match(r 134 return; 135 136 if (rtd->dai_link->ops && 137 rtd->dai_link->ops->hw_free) 138 rtd->dai_link->ops->hw_free(su 139 140 /* remove marked substream */ 141 soc_link_mark_pop(rtd, substream, hw_p 142 } 143 144 static int soc_link_trigger(struct snd_pcm_sub 145 { 146 struct snd_soc_pcm_runtime *rtd = snd_ 147 int ret = 0; 148 149 if (rtd->dai_link->ops && 150 rtd->dai_link->ops->trigger) 151 ret = rtd->dai_link->ops->trig 152 153 return soc_link_ret(rtd, ret); 154 } 155 156 int snd_soc_link_trigger(struct snd_pcm_substr 157 int rollback) 158 { 159 struct snd_soc_pcm_runtime *rtd = snd_ 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(substre 167 if (ret < 0) 168 break; 169 soc_link_mark_push(rtd, substr 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 175 break; 176 177 ret = soc_link_trigger(substre 178 soc_link_mark_pop(rtd, substre 179 } 180 181 return ret; 182 } 183 184 int snd_soc_link_compr_startup(struct snd_comp 185 { 186 struct snd_soc_pcm_runtime *rtd = cstr 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 192 193 if (ret == 0) 194 soc_link_mark_push(rtd, cstrea 195 196 return soc_link_ret(rtd, ret); 197 } 198 EXPORT_SYMBOL_GPL(snd_soc_link_compr_startup); 199 200 void snd_soc_link_compr_shutdown(struct snd_co 201 int rollback) 202 { 203 struct snd_soc_pcm_runtime *rtd = cstr 204 205 if (rollback && !soc_link_mark_match(r 206 return; 207 208 if (rtd->dai_link->compr_ops && 209 rtd->dai_link->compr_ops->shutdown 210 rtd->dai_link->compr_ops->shut 211 212 soc_link_mark_pop(rtd, cstream, compr_ 213 } 214 EXPORT_SYMBOL_GPL(snd_soc_link_compr_shutdown) 215 216 int snd_soc_link_compr_set_params(struct snd_c 217 { 218 struct snd_soc_pcm_runtime *rtd = cstr 219 int ret = 0; 220 221 if (rtd->dai_link->compr_ops && 222 rtd->dai_link->compr_ops->set_para 223 ret = rtd->dai_link->compr_ops 224 225 return soc_link_ret(rtd, ret); 226 } 227 EXPORT_SYMBOL_GPL(snd_soc_link_compr_set_param 228
Linux® is a registered trademark of Linus Torvalds in the United States and other countries.
TOMOYO® is a registered trademark of NTT DATA CORPORATION.