1 // SPDX-License-Identifier: GPL-2.0
5 // Copyright (C) 2019 Renesas Electronics Corp.
6 // Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
9 #include <linux/lockdep.h>
10 #include <linux/rwsem.h>
11 #include <sound/soc.h>
12 #include <sound/jack.h>
14 #define soc_card_ret(dai, ret) _soc_card_ret(dai, __func__, ret)
15 static inline int _soc_card_ret(struct snd_soc_card
*card
,
16 const char *func
, int ret
)
25 "ASoC: error at %s on %s: %d\n",
26 func
, card
->name
, ret
);
32 struct snd_kcontrol
*snd_soc_card_get_kcontrol(struct snd_soc_card
*soc_card
,
38 return snd_ctl_find_id_mixer(soc_card
->snd_card
, name
);
40 EXPORT_SYMBOL_GPL(snd_soc_card_get_kcontrol
);
42 static int jack_new(struct snd_soc_card
*card
, const char *id
, int type
,
43 struct snd_soc_jack
*jack
, bool initial_kctl
)
45 mutex_init(&jack
->mutex
);
47 INIT_LIST_HEAD(&jack
->pins
);
48 INIT_LIST_HEAD(&jack
->jack_zones
);
49 BLOCKING_INIT_NOTIFIER_HEAD(&jack
->notifier
);
51 return snd_jack_new(card
->snd_card
, id
, type
, &jack
->jack
, initial_kctl
, false);
55 * snd_soc_card_jack_new - Create a new jack without pins
57 * @id: an identifying string for this jack
58 * @type: a bitmask of enum snd_jack_type values that can be detected by
60 * @jack: structure to use for the jack
62 * Creates a new jack object without pins. If adding pins later,
63 * snd_soc_card_jack_new_pins() should be used instead with 0 as num_pins
66 * Returns zero if successful, or a negative error code on failure.
67 * On success jack will be initialised.
69 int snd_soc_card_jack_new(struct snd_soc_card
*card
, const char *id
, int type
,
70 struct snd_soc_jack
*jack
)
72 return soc_card_ret(card
, jack_new(card
, id
, type
, jack
, true));
74 EXPORT_SYMBOL_GPL(snd_soc_card_jack_new
);
77 * snd_soc_card_jack_new_pins - Create a new jack with pins
79 * @id: an identifying string for this jack
80 * @type: a bitmask of enum snd_jack_type values that can be detected by
82 * @jack: structure to use for the jack
83 * @pins: Array of jack pins to be added to the jack or NULL
84 * @num_pins: Number of elements in the @pins array
86 * Creates a new jack object with pins. If not adding pins,
87 * snd_soc_card_jack_new() should be used instead.
89 * Returns zero if successful, or a negative error code on failure.
90 * On success jack will be initialised.
92 int snd_soc_card_jack_new_pins(struct snd_soc_card
*card
, const char *id
,
93 int type
, struct snd_soc_jack
*jack
,
94 struct snd_soc_jack_pin
*pins
,
95 unsigned int num_pins
)
99 ret
= jack_new(card
, id
, type
, jack
, false);
104 ret
= snd_soc_jack_add_pins(jack
, num_pins
, pins
);
106 return soc_card_ret(card
, ret
);
108 EXPORT_SYMBOL_GPL(snd_soc_card_jack_new_pins
);
110 int snd_soc_card_suspend_pre(struct snd_soc_card
*card
)
114 if (card
->suspend_pre
)
115 ret
= card
->suspend_pre(card
);
117 return soc_card_ret(card
, ret
);
120 int snd_soc_card_suspend_post(struct snd_soc_card
*card
)
124 if (card
->suspend_post
)
125 ret
= card
->suspend_post(card
);
127 return soc_card_ret(card
, ret
);
130 int snd_soc_card_resume_pre(struct snd_soc_card
*card
)
134 if (card
->resume_pre
)
135 ret
= card
->resume_pre(card
);
137 return soc_card_ret(card
, ret
);
140 int snd_soc_card_resume_post(struct snd_soc_card
*card
)
144 if (card
->resume_post
)
145 ret
= card
->resume_post(card
);
147 return soc_card_ret(card
, ret
);
150 int snd_soc_card_probe(struct snd_soc_card
*card
)
153 int ret
= card
->probe(card
);
156 return soc_card_ret(card
, ret
);
159 * It has "card->probe" and "card->late_probe" callbacks.
160 * So, set "probed" flag here, because it needs to care
161 * about "late_probe".
164 * snd_soc_bind_card()
165 * snd_soc_card_late_probe()
173 int snd_soc_card_late_probe(struct snd_soc_card
*card
)
175 if (card
->late_probe
) {
176 int ret
= card
->late_probe(card
);
179 return soc_card_ret(card
, ret
);
183 * It has "card->probe" and "card->late_probe" callbacks,
184 * and "late_probe" callback is called after "probe".
185 * This means, we can set "card->probed" flag afer "late_probe"
189 * snd_soc_bind_card()
190 * snd_soc_card_probe()
197 void snd_soc_card_fixup_controls(struct snd_soc_card
*card
)
199 if (card
->fixup_controls
)
200 card
->fixup_controls(card
);
203 int snd_soc_card_remove(struct snd_soc_card
*card
)
209 ret
= card
->remove(card
);
213 return soc_card_ret(card
, ret
);
216 int snd_soc_card_set_bias_level(struct snd_soc_card
*card
,
217 struct snd_soc_dapm_context
*dapm
,
218 enum snd_soc_bias_level level
)
222 if (card
&& card
->set_bias_level
)
223 ret
= card
->set_bias_level(card
, dapm
, level
);
225 return soc_card_ret(card
, ret
);
228 int snd_soc_card_set_bias_level_post(struct snd_soc_card
*card
,
229 struct snd_soc_dapm_context
*dapm
,
230 enum snd_soc_bias_level level
)
234 if (card
&& card
->set_bias_level_post
)
235 ret
= card
->set_bias_level_post(card
, dapm
, level
);
237 return soc_card_ret(card
, ret
);
240 int snd_soc_card_add_dai_link(struct snd_soc_card
*card
,
241 struct snd_soc_dai_link
*dai_link
)
245 if (card
->add_dai_link
)
246 ret
= card
->add_dai_link(card
, dai_link
);
248 return soc_card_ret(card
, ret
);
250 EXPORT_SYMBOL_GPL(snd_soc_card_add_dai_link
);
252 void snd_soc_card_remove_dai_link(struct snd_soc_card
*card
,
253 struct snd_soc_dai_link
*dai_link
)
255 if (card
->remove_dai_link
)
256 card
->remove_dai_link(card
, dai_link
);
258 EXPORT_SYMBOL_GPL(snd_soc_card_remove_dai_link
);