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