^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1) // SPDX-License-Identifier: GPL-2.0+
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2) //
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3) // soc-devres.c -- ALSA SoC Audio Layer devres functions
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4) //
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5) // Copyright (C) 2013 Linaro Ltd
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7) #include <linux/module.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8) #include <linux/moduleparam.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9) #include <sound/soc.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10) #include <sound/dmaengine_pcm.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12) static void devm_dai_release(struct device *dev, void *res)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14) snd_soc_unregister_dai(*(struct snd_soc_dai **)res);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18) * devm_snd_soc_register_dai - resource-managed dai registration
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19) * @dev: Device used to manage component
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20) * @component: The component the DAIs are registered for
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21) * @dai_drv: DAI driver to use for the DAI
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22) * @legacy_dai_naming: if %true, use legacy single-name format;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23) * if %false, use multiple-name format;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25) struct snd_soc_dai *devm_snd_soc_register_dai(struct device *dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26) struct snd_soc_component *component,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27) struct snd_soc_dai_driver *dai_drv,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28) bool legacy_dai_naming)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30) struct snd_soc_dai **ptr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31) struct snd_soc_dai *dai;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33) ptr = devres_alloc(devm_dai_release, sizeof(*ptr), GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34) if (!ptr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35) return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37) dai = snd_soc_register_dai(component, dai_drv, legacy_dai_naming);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38) if (dai) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39) *ptr = dai;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40) devres_add(dev, ptr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42) devres_free(ptr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45) return dai;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47) EXPORT_SYMBOL_GPL(devm_snd_soc_register_dai);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49) static void devm_component_release(struct device *dev, void *res)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51) const struct snd_soc_component_driver **cmpnt_drv = res;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53) snd_soc_unregister_component_by_driver(dev, *cmpnt_drv);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57) * devm_snd_soc_register_component - resource managed component registration
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58) * @dev: Device used to manage component
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59) * @cmpnt_drv: Component driver
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60) * @dai_drv: DAI driver
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61) * @num_dai: Number of DAIs to register
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63) * Register a component with automatic unregistration when the device is
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 64) * unregistered.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 65) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 66) int devm_snd_soc_register_component(struct device *dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67) const struct snd_soc_component_driver *cmpnt_drv,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 68) struct snd_soc_dai_driver *dai_drv, int num_dai)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 69) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 70) const struct snd_soc_component_driver **ptr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 71) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 72)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 73) ptr = devres_alloc(devm_component_release, sizeof(*ptr), GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 74) if (!ptr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 75) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 76)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 77) ret = snd_soc_register_component(dev, cmpnt_drv, dai_drv, num_dai);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 78) if (ret == 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 79) *ptr = cmpnt_drv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 80) devres_add(dev, ptr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 81) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 82) devres_free(ptr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 83) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 84)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 85) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 86) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 87) EXPORT_SYMBOL_GPL(devm_snd_soc_register_component);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 88)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 89) static void devm_card_release(struct device *dev, void *res)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 90) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 91) snd_soc_unregister_card(*(struct snd_soc_card **)res);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 92) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 93)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 94) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 95) * devm_snd_soc_register_card - resource managed card registration
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 96) * @dev: Device used to manage card
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 97) * @card: Card to register
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 98) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 99) * Register a card with automatic unregistration when the device is
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) * unregistered.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) int devm_snd_soc_register_card(struct device *dev, struct snd_soc_card *card)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) struct snd_soc_card **ptr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) ptr = devres_alloc(devm_card_release, sizeof(*ptr), GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) if (!ptr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) ret = snd_soc_register_card(card);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) if (ret == 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) *ptr = card;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) devres_add(dev, ptr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) devres_free(ptr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) EXPORT_SYMBOL_GPL(devm_snd_soc_register_card);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) #ifdef CONFIG_SND_SOC_GENERIC_DMAENGINE_PCM
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) static void devm_dmaengine_pcm_release(struct device *dev, void *res)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) snd_dmaengine_pcm_unregister(*(struct device **)res);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) * devm_snd_dmaengine_pcm_register - resource managed dmaengine PCM registration
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132) * @dev: The parent device for the PCM device
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) * @config: Platform specific PCM configuration
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) * @flags: Platform specific quirks
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136) * Register a dmaengine based PCM device with automatic unregistration when the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) * device is unregistered.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139) int devm_snd_dmaengine_pcm_register(struct device *dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140) const struct snd_dmaengine_pcm_config *config, unsigned int flags)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142) struct device **ptr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145) ptr = devres_alloc(devm_dmaengine_pcm_release, sizeof(*ptr), GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146) if (!ptr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149) ret = snd_dmaengine_pcm_register(dev, config, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150) if (ret == 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151) *ptr = dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152) devres_add(dev, ptr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154) devres_free(ptr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159) EXPORT_SYMBOL_GPL(devm_snd_dmaengine_pcm_register);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161) #endif