diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2020-06-04 11:07:38 -0700 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2020-06-04 11:07:38 -0700 |
commit | 631d6914085b4eea8d68a84f800974a6ad8fb5c0 (patch) | |
tree | d38b189458bb186a016816c41c7e7321ba5e94ba /sound/soc/soc-card.c | |
parent | a0a4d17e02a80a74a63c7cbb7bc8cea2f0b7d8b1 (diff) | |
parent | d9b8fbf15d05350b36081eddafcf7b15aa1add50 (diff) |
Merge tag 'sound-5.8-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/tiwai/sound
Pull sound updates from Takashi Iwai:
"It was another busy development cycle, and the majority of changes are
found in ASoC side. Below are Some highlights.
ASoC core:
- Lots of core cleanups and refactorings, still on-going work by
Morimoto-san
ASoC drivers:
- Continued work on cleaning up and improving the Intel SOF stuff,
along with new platform support including SoundWire
- Fixes to make the Marvell SSPA driver work upstream
- Support for AMD Renoir ACP, Dialog DA7212, Freescale EASRC and
i.MX8M, Intel Elkhard Lake, Maxim MAX98390, Nuvoton NAU8812 and
NAU8814 and Realtek RT1016.
USB-audio:
- Improvement for sync and implicit feedback streams with the more
accurate frame size calculation and full-duplex support
- Support for RME Babyface Pro and Prioneer DJ DJM
HD-audio:
- Fixes for Mic mute LED on HP machines
- Re-enable support of Intel SST driver for SKL/KBL platforms
FireWire:
- Lots of refactoring, add support for RME FireFace and MOTU
UltraLite-mk3"
* tag 'sound-5.8-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/tiwai/sound: (428 commits)
ALSA: es1688: Add the missed snd_card_free()
ALSA: hda: add sienna_cichlid audio asic id for sienna_cichlid up
ALSA: usb-audio: Add Pioneer DJ DJM-900NXS2 support
ASoC: qcom: q6asm-dai: kCFI fix
ASoC: soc-card: add snd_soc_card_remove_dai_link()
ASoC: soc-card: add snd_soc_card_add_dai_link()
ASoC: soc-card: add snd_soc_card_set_bias_level_post()
ASoC: soc-card: add snd_soc_card_set_bias_level()
ASoC: soc-card: add snd_soc_card_remove()
ASoC: soc-card: add snd_soc_card_late_probe()
ASoC: soc-card: add snd_soc_card_probe()
ASoC: soc-card: add probed bit field to snd_soc_card
ASoC: soc-card: add snd_soc_card_resume_post()
ASoC: soc-card: add snd_soc_card_resume_pre()
ASoC: soc-card: add snd_soc_card_suspend_post()
ASoC: soc-card: add snd_soc_card_suspend_pre()
ASoC: soc-card: move snd_soc_card_subclass to soc-card
ASoC: soc-card: move snd_soc_card_get_codec_dai() to soc-card
ASoC: soc-card: move snd_soc_card_set/get_drvdata() to soc-card
ASoC: soc-card: move snd_soc_card_jack_new() to soc-card
...
Diffstat (limited to 'sound/soc/soc-card.c')
-rw-r--r-- | sound/soc/soc-card.c | 225 |
1 files changed, 225 insertions, 0 deletions
diff --git a/sound/soc/soc-card.c b/sound/soc/soc-card.c new file mode 100644 index 000000000000..41c586b86dc3 --- /dev/null +++ b/sound/soc/soc-card.c @@ -0,0 +1,225 @@ +// SPDX-License-Identifier: GPL-2.0 +// +// soc-card.c +// +// Copyright (C) 2019 Renesas Electronics Corp. +// Kuninori Morimoto <kuninori.morimoto.gx@renesas.com> +// +#include <sound/soc.h> +#include <sound/jack.h> + +#define soc_card_ret(dai, ret) _soc_card_ret(dai, __func__, ret) +static inline int _soc_card_ret(struct snd_soc_card *card, + const char *func, int ret) +{ + switch (ret) { + case -EPROBE_DEFER: + case -ENOTSUPP: + case 0: + break; + default: + dev_err(card->dev, + "ASoC: error at %s on %s: %d\n", + func, card->name, ret); + } + + return ret; +} + +struct snd_kcontrol *snd_soc_card_get_kcontrol(struct snd_soc_card *soc_card, + const char *name) +{ + struct snd_card *card = soc_card->snd_card; + struct snd_kcontrol *kctl; + + if (unlikely(!name)) + return NULL; + + list_for_each_entry(kctl, &card->controls, list) + if (!strncmp(kctl->id.name, name, sizeof(kctl->id.name))) + return kctl; + return NULL; +} +EXPORT_SYMBOL_GPL(snd_soc_card_get_kcontrol); + +/** + * snd_soc_card_jack_new - Create a new jack + * @card: ASoC card + * @id: an identifying string for this jack + * @type: a bitmask of enum snd_jack_type values that can be detected by + * this jack + * @jack: structure to use for the jack + * @pins: Array of jack pins to be added to the jack or NULL + * @num_pins: Number of elements in the @pins array + * + * Creates a new jack object. + * + * Returns zero if successful, or a negative error code on failure. + * On success jack will be initialised. + */ +int snd_soc_card_jack_new(struct snd_soc_card *card, const char *id, int type, + struct snd_soc_jack *jack, + struct snd_soc_jack_pin *pins, unsigned int num_pins) +{ + int ret; + + mutex_init(&jack->mutex); + jack->card = card; + INIT_LIST_HEAD(&jack->pins); + INIT_LIST_HEAD(&jack->jack_zones); + BLOCKING_INIT_NOTIFIER_HEAD(&jack->notifier); + + ret = snd_jack_new(card->snd_card, id, type, &jack->jack, false, false); + if (ret) + goto end; + + if (num_pins) + ret = snd_soc_jack_add_pins(jack, num_pins, pins); +end: + return soc_card_ret(card, ret); +} +EXPORT_SYMBOL_GPL(snd_soc_card_jack_new); + +int snd_soc_card_suspend_pre(struct snd_soc_card *card) +{ + int ret = 0; + + if (card->suspend_pre) + ret = card->suspend_pre(card); + + return soc_card_ret(card, ret); +} + +int snd_soc_card_suspend_post(struct snd_soc_card *card) +{ + int ret = 0; + + if (card->suspend_post) + ret = card->suspend_post(card); + + return soc_card_ret(card, ret); +} + +int snd_soc_card_resume_pre(struct snd_soc_card *card) +{ + int ret = 0; + + if (card->resume_pre) + ret = card->resume_pre(card); + + return soc_card_ret(card, ret); +} + +int snd_soc_card_resume_post(struct snd_soc_card *card) +{ + int ret = 0; + + if (card->resume_post) + ret = card->resume_post(card); + + return soc_card_ret(card, ret); +} + +int snd_soc_card_probe(struct snd_soc_card *card) +{ + if (card->probe) { + int ret = card->probe(card); + + if (ret < 0) + return soc_card_ret(card, ret); + + /* + * It has "card->probe" and "card->late_probe" callbacks. + * So, set "probed" flag here, because it needs to care + * about "late_probe". + * + * see + * snd_soc_bind_card() + * snd_soc_card_late_probe() + */ + card->probed = 1; + } + + return 0; +} + +int snd_soc_card_late_probe(struct snd_soc_card *card) +{ + if (card->late_probe) { + int ret = card->late_probe(card); + + if (ret < 0) + return soc_card_ret(card, ret); + } + + /* + * It has "card->probe" and "card->late_probe" callbacks, + * and "late_probe" callback is called after "probe". + * This means, we can set "card->probed" flag afer "late_probe" + * for all cases. + * + * see + * snd_soc_bind_card() + * snd_soc_card_probe() + */ + card->probed = 1; + + return 0; +} + +int snd_soc_card_remove(struct snd_soc_card *card) +{ + int ret = 0; + + if (card->probed && + card->remove) + ret = card->remove(card); + + card->probed = 0; + + return soc_card_ret(card, ret); +} + +int snd_soc_card_set_bias_level(struct snd_soc_card *card, + struct snd_soc_dapm_context *dapm, + enum snd_soc_bias_level level) +{ + int ret = 0; + + if (card && card->set_bias_level) + ret = card->set_bias_level(card, dapm, level); + + return soc_card_ret(card, ret); +} + +int snd_soc_card_set_bias_level_post(struct snd_soc_card *card, + struct snd_soc_dapm_context *dapm, + enum snd_soc_bias_level level) +{ + int ret = 0; + + if (card && card->set_bias_level_post) + ret = card->set_bias_level_post(card, dapm, level); + + return soc_card_ret(card, ret); +} + +int snd_soc_card_add_dai_link(struct snd_soc_card *card, + struct snd_soc_dai_link *dai_link) +{ + int ret = 0; + + if (card->add_dai_link) + ret = card->add_dai_link(card, dai_link); + + return soc_card_ret(card, ret); +} +EXPORT_SYMBOL_GPL(snd_soc_card_add_dai_link); + +void snd_soc_card_remove_dai_link(struct snd_soc_card *card, + struct snd_soc_dai_link *dai_link) +{ + if (card->remove_dai_link) + card->remove_dai_link(card, dai_link); +} +EXPORT_SYMBOL_GPL(snd_soc_card_remove_dai_link); |