FILE
soc-card.c
File preview with syntax highlighting.
linux-6.19.14/sound/soc/soc-card.c
1// SPDX-License-Identifier: GPL-2.0 2// 3// soc-card.c 4// 5// Copyright (C) 2019 Renesas Electronics Corp. 6// Kuninori Morimoto <kuninori.morimoto.gx@renesas.com> 7// 8 9#include <linux/lockdep.h> 10#include <linux/rwsem.h> 11#include <sound/soc.h> 12#include <sound/jack.h> 13 14#define soc_card_ret(dai, ret) _soc_card_ret(dai, __func__, ret) 15static inline int _soc_card_ret(struct snd_soc_card *card, 16 const char *func, int ret) 17{ 18 return snd_soc_ret(card->dev, ret, 19 "at %s() on %s\n", func, card->name); 20} 21 22struct snd_kcontrol *snd_soc_card_get_kcontrol(struct snd_soc_card *soc_card, 23 const char *name) 24{ 25 if (unlikely(!name)) 26 return NULL; 27 28 return snd_ctl_find_id_mixer(soc_card->snd_card, name); 29} 30EXPORT_SYMBOL_GPL(snd_soc_card_get_kcontrol); 31 32static int jack_new(struct snd_soc_card *card, const char *id, int type, 33 struct snd_soc_jack *jack, bool initial_kctl) 34{ 35 mutex_init(&jack->mutex); 36 jack->card = card; 37 INIT_LIST_HEAD(&jack->pins); 38 INIT_LIST_HEAD(&jack->jack_zones); 39 BLOCKING_INIT_NOTIFIER_HEAD(&jack->notifier); 40 41 return snd_jack_new(card->snd_card, id, type, &jack->jack, initial_kctl, false); 42} 43 44/** 45 * snd_soc_card_jack_new - Create a new jack without pins 46 * @card: ASoC card 47 * @id: an identifying string for this jack 48 * @type: a bitmask of enum snd_jack_type values that can be detected by 49 * this jack 50 * @jack: structure to use for the jack 51 * 52 * Creates a new jack object without pins. If adding pins later, 53 * snd_soc_card_jack_new_pins() should be used instead with 0 as num_pins 54 * argument. 55 * 56 * Returns zero if successful, or a negative error code on failure. 57 * On success jack will be initialised. 58 */ 59int snd_soc_card_jack_new(struct snd_soc_card *card, const char *id, int type, 60 struct snd_soc_jack *jack) 61{ 62 return soc_card_ret(card, jack_new(card, id, type, jack, true)); 63} 64EXPORT_SYMBOL_GPL(snd_soc_card_jack_new); 65 66/** 67 * snd_soc_card_jack_new_pins - Create a new jack with pins 68 * @card: ASoC card 69 * @id: an identifying string for this jack 70 * @type: a bitmask of enum snd_jack_type values that can be detected by 71 * this jack 72 * @jack: structure to use for the jack 73 * @pins: Array of jack pins to be added to the jack or NULL 74 * @num_pins: Number of elements in the @pins array 75 * 76 * Creates a new jack object with pins. If not adding pins, 77 * snd_soc_card_jack_new() should be used instead. 78 * 79 * Returns zero if successful, or a negative error code on failure. 80 * On success jack will be initialised. 81 */ 82int snd_soc_card_jack_new_pins(struct snd_soc_card *card, const char *id, 83 int type, struct snd_soc_jack *jack, 84 struct snd_soc_jack_pin *pins, 85 unsigned int num_pins) 86{ 87 int ret; 88 89 ret = jack_new(card, id, type, jack, false); 90 if (ret) 91 goto end; 92 93 if (num_pins) 94 ret = snd_soc_jack_add_pins(jack, num_pins, pins); 95end: 96 return soc_card_ret(card, ret); 97} 98EXPORT_SYMBOL_GPL(snd_soc_card_jack_new_pins); 99 100int snd_soc_card_suspend_pre(struct snd_soc_card *card) 101{ 102 int ret = 0; 103 104 if (card->suspend_pre) 105 ret = card->suspend_pre(card); 106 107 return soc_card_ret(card, ret); 108} 109 110int snd_soc_card_suspend_post(struct snd_soc_card *card) 111{ 112 int ret = 0; 113 114 if (card->suspend_post) 115 ret = card->suspend_post(card); 116 117 return soc_card_ret(card, ret); 118} 119 120int snd_soc_card_resume_pre(struct snd_soc_card *card) 121{ 122 int ret = 0; 123 124 if (card->resume_pre) 125 ret = card->resume_pre(card); 126 127 return soc_card_ret(card, ret); 128} 129 130int snd_soc_card_resume_post(struct snd_soc_card *card) 131{ 132 int ret = 0; 133 134 if (card->resume_post) 135 ret = card->resume_post(card); 136 137 return soc_card_ret(card, ret); 138} 139 140int snd_soc_card_probe(struct snd_soc_card *card) 141{ 142 if (card->probe) { 143 int ret = card->probe(card); 144 145 if (ret < 0) 146 return soc_card_ret(card, ret); 147 148 /* 149 * It has "card->probe" and "card->late_probe" callbacks. 150 * So, set "probed" flag here, because it needs to care 151 * about "late_probe". 152 * 153 * see 154 * snd_soc_bind_card() 155 * snd_soc_card_late_probe() 156 */ 157 card->probed = 1; 158 } 159 160 return 0; 161} 162 163int snd_soc_card_late_probe(struct snd_soc_card *card) 164{ 165 if (card->late_probe) { 166 int ret = card->late_probe(card); 167 168 if (ret < 0) 169 return soc_card_ret(card, ret); 170 } 171 172 /* 173 * It has "card->probe" and "card->late_probe" callbacks, 174 * and "late_probe" callback is called after "probe". 175 * This means, we can set "card->probed" flag afer "late_probe" 176 * for all cases. 177 * 178 * see 179 * snd_soc_bind_card() 180 * snd_soc_card_probe() 181 */ 182 card->probed = 1; 183 184 return 0; 185} 186 187void snd_soc_card_fixup_controls(struct snd_soc_card *card) 188{ 189 if (card->fixup_controls) 190 card->fixup_controls(card); 191} 192 193int snd_soc_card_remove(struct snd_soc_card *card) 194{ 195 int ret = 0; 196 197 if (card->probed && 198 card->remove) 199 ret = card->remove(card); 200 201 card->probed = 0; 202 203 return soc_card_ret(card, ret); 204} 205 206int snd_soc_card_set_bias_level(struct snd_soc_card *card, 207 struct snd_soc_dapm_context *dapm, 208 enum snd_soc_bias_level level) 209{ 210 int ret = 0; 211 212 if (card->set_bias_level) 213 ret = card->set_bias_level(card, dapm, level); 214 215 return soc_card_ret(card, ret); 216} 217 218int snd_soc_card_set_bias_level_post(struct snd_soc_card *card, 219 struct snd_soc_dapm_context *dapm, 220 enum snd_soc_bias_level level) 221{ 222 int ret = 0; 223 224 if (card->set_bias_level_post) 225 ret = card->set_bias_level_post(card, dapm, level); 226 227 return soc_card_ret(card, ret); 228} 229 230int snd_soc_card_add_dai_link(struct snd_soc_card *card, 231 struct snd_soc_dai_link *dai_link) 232{ 233 int ret = 0; 234 235 if (card->add_dai_link) 236 ret = card->add_dai_link(card, dai_link); 237 238 return soc_card_ret(card, ret); 239} 240EXPORT_SYMBOL_GPL(snd_soc_card_add_dai_link); 241 242void snd_soc_card_remove_dai_link(struct snd_soc_card *card, 243 struct snd_soc_dai_link *dai_link) 244{ 245 if (card->remove_dai_link) 246 card->remove_dai_link(card, dai_link); 247} 248EXPORT_SYMBOL_GPL(snd_soc_card_remove_dai_link);
~/
Read-only file preview.