cachepc-linux

Fork of AMDESE/linux with modifications for CachePC side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-linux
Log | Files | Refs | README | LICENSE | sfeed.txt

soc-card.c (5956B)


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