File Index
Files and directories
Sign in
FILE

soc-card.c

File preview with syntax highlighting.

linux-6.19.14/sound/soc/soc-card.c 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.