xref: /openbmc/linux/sound/soc/soc-card.c (revision d17b60b2)
11793936bSKuninori Morimoto // SPDX-License-Identifier: GPL-2.0
21793936bSKuninori Morimoto //
31793936bSKuninori Morimoto // soc-card.c
41793936bSKuninori Morimoto //
51793936bSKuninori Morimoto // Copyright (C) 2019 Renesas Electronics Corp.
61793936bSKuninori Morimoto // Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
71793936bSKuninori Morimoto //
81793936bSKuninori Morimoto #include <sound/soc.h>
93359e9b6SKuninori Morimoto #include <sound/jack.h>
101793936bSKuninori Morimoto 
111793936bSKuninori Morimoto #define soc_card_ret(dai, ret) _soc_card_ret(dai, __func__, ret)
121793936bSKuninori Morimoto static inline int _soc_card_ret(struct snd_soc_card *card,
131793936bSKuninori Morimoto 				const char *func, int ret)
141793936bSKuninori Morimoto {
151793936bSKuninori Morimoto 	switch (ret) {
161793936bSKuninori Morimoto 	case -EPROBE_DEFER:
171793936bSKuninori Morimoto 	case -ENOTSUPP:
181793936bSKuninori Morimoto 	case 0:
191793936bSKuninori Morimoto 		break;
201793936bSKuninori Morimoto 	default:
211793936bSKuninori Morimoto 		dev_err(card->dev,
221793936bSKuninori Morimoto 			"ASoC: error at %s on %s: %d\n",
231793936bSKuninori Morimoto 			func, card->name, ret);
241793936bSKuninori Morimoto 	}
251793936bSKuninori Morimoto 
261793936bSKuninori Morimoto 	return ret;
271793936bSKuninori Morimoto }
28209c6cdfSKuninori Morimoto 
29209c6cdfSKuninori Morimoto struct snd_kcontrol *snd_soc_card_get_kcontrol(struct snd_soc_card *soc_card,
30209c6cdfSKuninori Morimoto 					       const char *name)
31209c6cdfSKuninori Morimoto {
32209c6cdfSKuninori Morimoto 	struct snd_card *card = soc_card->snd_card;
33209c6cdfSKuninori Morimoto 	struct snd_kcontrol *kctl;
34209c6cdfSKuninori Morimoto 
35209c6cdfSKuninori Morimoto 	if (unlikely(!name))
36209c6cdfSKuninori Morimoto 		return NULL;
37209c6cdfSKuninori Morimoto 
38209c6cdfSKuninori Morimoto 	list_for_each_entry(kctl, &card->controls, list)
39209c6cdfSKuninori Morimoto 		if (!strncmp(kctl->id.name, name, sizeof(kctl->id.name)))
40209c6cdfSKuninori Morimoto 			return kctl;
41209c6cdfSKuninori Morimoto 	return NULL;
42209c6cdfSKuninori Morimoto }
43209c6cdfSKuninori Morimoto EXPORT_SYMBOL_GPL(snd_soc_card_get_kcontrol);
443359e9b6SKuninori Morimoto 
453359e9b6SKuninori Morimoto /**
463359e9b6SKuninori Morimoto  * snd_soc_card_jack_new - Create a new jack
473359e9b6SKuninori Morimoto  * @card:  ASoC card
483359e9b6SKuninori Morimoto  * @id:    an identifying string for this jack
493359e9b6SKuninori Morimoto  * @type:  a bitmask of enum snd_jack_type values that can be detected by
503359e9b6SKuninori Morimoto  *         this jack
513359e9b6SKuninori Morimoto  * @jack:  structure to use for the jack
523359e9b6SKuninori Morimoto  * @pins:  Array of jack pins to be added to the jack or NULL
533359e9b6SKuninori Morimoto  * @num_pins: Number of elements in the @pins array
543359e9b6SKuninori Morimoto  *
553359e9b6SKuninori Morimoto  * Creates a new jack object.
563359e9b6SKuninori Morimoto  *
573359e9b6SKuninori Morimoto  * Returns zero if successful, or a negative error code on failure.
583359e9b6SKuninori Morimoto  * On success jack will be initialised.
593359e9b6SKuninori Morimoto  */
603359e9b6SKuninori Morimoto int snd_soc_card_jack_new(struct snd_soc_card *card, const char *id, int type,
613359e9b6SKuninori Morimoto 			  struct snd_soc_jack *jack,
623359e9b6SKuninori Morimoto 			  struct snd_soc_jack_pin *pins, unsigned int num_pins)
633359e9b6SKuninori Morimoto {
643359e9b6SKuninori Morimoto 	int ret;
653359e9b6SKuninori Morimoto 
663359e9b6SKuninori Morimoto 	mutex_init(&jack->mutex);
673359e9b6SKuninori Morimoto 	jack->card = card;
683359e9b6SKuninori Morimoto 	INIT_LIST_HEAD(&jack->pins);
693359e9b6SKuninori Morimoto 	INIT_LIST_HEAD(&jack->jack_zones);
703359e9b6SKuninori Morimoto 	BLOCKING_INIT_NOTIFIER_HEAD(&jack->notifier);
713359e9b6SKuninori Morimoto 
723359e9b6SKuninori Morimoto 	ret = snd_jack_new(card->snd_card, id, type, &jack->jack, false, false);
733359e9b6SKuninori Morimoto 	if (ret)
743359e9b6SKuninori Morimoto 		goto end;
753359e9b6SKuninori Morimoto 
763359e9b6SKuninori Morimoto 	if (num_pins)
773359e9b6SKuninori Morimoto 		ret = snd_soc_jack_add_pins(jack, num_pins, pins);
783359e9b6SKuninori Morimoto end:
793359e9b6SKuninori Morimoto 	return soc_card_ret(card, ret);
803359e9b6SKuninori Morimoto }
813359e9b6SKuninori Morimoto EXPORT_SYMBOL_GPL(snd_soc_card_jack_new);
82130dc08cSKuninori Morimoto 
83130dc08cSKuninori Morimoto int snd_soc_card_suspend_pre(struct snd_soc_card *card)
84130dc08cSKuninori Morimoto {
85130dc08cSKuninori Morimoto 	int ret = 0;
86130dc08cSKuninori Morimoto 
87130dc08cSKuninori Morimoto 	if (card->suspend_pre)
88130dc08cSKuninori Morimoto 		ret = card->suspend_pre(card);
89130dc08cSKuninori Morimoto 
90130dc08cSKuninori Morimoto 	return soc_card_ret(card, ret);
91130dc08cSKuninori Morimoto }
92d17b60b2SKuninori Morimoto 
93d17b60b2SKuninori Morimoto int snd_soc_card_suspend_post(struct snd_soc_card *card)
94d17b60b2SKuninori Morimoto {
95d17b60b2SKuninori Morimoto 	int ret = 0;
96d17b60b2SKuninori Morimoto 
97d17b60b2SKuninori Morimoto 	if (card->suspend_post)
98d17b60b2SKuninori Morimoto 		ret = card->suspend_post(card);
99d17b60b2SKuninori Morimoto 
100d17b60b2SKuninori Morimoto 	return soc_card_ret(card, ret);
101d17b60b2SKuninori Morimoto }
102