Current ASoC has register function for platform/codec/dai/card, but doesn't have for cpu. It often produces confusion and fault on ASoC.
As result of ASoC community discussion, we consider new struct snd_soc_chip for CPU/CODEC, and will switch over to use it.
This patch adds very basic struct snd_soc_chip, and register function for it.
Signed-off-by: Kuninori Morimoto kuninori.morimoto.gx@renesas.com --- include/sound/soc.h | 19 +++++++++++++ sound/soc/soc-core.c | 77 ++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 96 insertions(+)
diff --git a/include/sound/soc.h b/include/sound/soc.h index a6a059c..e0a665c 100644 --- a/include/sound/soc.h +++ b/include/sound/soc.h @@ -324,6 +324,8 @@ struct snd_soc_dai_link; struct snd_soc_platform_driver; struct snd_soc_codec; struct snd_soc_codec_driver; +struct snd_soc_chip; +struct snd_soc_chip_driver; struct soc_enum; struct snd_soc_jack; struct snd_soc_jack_zone; @@ -377,6 +379,10 @@ int snd_soc_register_codec(struct device *dev, const struct snd_soc_codec_driver *codec_drv, struct snd_soc_dai_driver *dai_drv, int num_dai); void snd_soc_unregister_codec(struct device *dev); +int snd_soc_register_chip(struct device *dev, + const struct snd_soc_chip_driver *chip_drv, + struct snd_soc_dai_driver *dai_drv, int num_dai); +void snd_soc_unregister_chip(struct device *dev); int snd_soc_codec_volatile_register(struct snd_soc_codec *codec, unsigned int reg); int snd_soc_codec_readable_register(struct snd_soc_codec *codec, @@ -841,6 +847,19 @@ struct snd_soc_platform { #endif };
+struct snd_soc_chip_driver { +}; + +struct snd_soc_chip { + const char *name; + int id; + int num_dai; + struct device *dev; + struct list_head list; + + const struct snd_soc_chip_driver *driver; +}; + struct snd_soc_dai_link { /* config - must be set by machine driver */ const char *name; /* Codec name */ diff --git a/sound/soc/soc-core.c b/sound/soc/soc-core.c index e02c374..1ac96df 100644 --- a/sound/soc/soc-core.c +++ b/sound/soc/soc-core.c @@ -58,6 +58,7 @@ static DEFINE_MUTEX(client_mutex); static LIST_HEAD(dai_list); static LIST_HEAD(platform_list); static LIST_HEAD(codec_list); +static LIST_HEAD(chip_list);
/* * This is a timeout to do a DAPM powerdown after a stream is closed(). @@ -4134,6 +4135,82 @@ found: } EXPORT_SYMBOL_GPL(snd_soc_unregister_codec);
+ +/** + * snd_soc_register_chip - Register a chip with the ASoC core + * + */ +int snd_soc_register_chip(struct device *dev, + const struct snd_soc_chip_driver *chip_drv, + struct snd_soc_dai_driver *dai_drv, + int num_dai) +{ + struct snd_soc_chip *chip; + int ret; + + dev_dbg(dev, "chip register %s\n", dev_name(dev)); + + chip = devm_kzalloc(dev, sizeof(*chip), GFP_KERNEL); + if (!chip) { + dev_err(dev, "ASoC: Failed to allocate memory\n"); + return -ENOMEM; + } + + chip->name = fmt_single_name(dev, &chip->id); + if (!chip->name) { + dev_err(dev, "ASoC: Failed to simplifying name\n"); + return -ENOMEM; + } + + chip->dev = dev; + chip->driver = chip_drv; + chip->num_dai = num_dai; + + ret = snd_soc_register_dais(dev, dai_drv, num_dai); + if (ret < 0) { + dev_err(dev, "ASoC: Failed to regster DAIs: %d\n", ret); + goto error_chip_name; + } + + mutex_lock(&client_mutex); + list_add(&chip->list, &chip_list); + mutex_unlock(&client_mutex); + + dev_dbg(chip->dev, "ASoC: Registered chip '%s'\n", chip->name); + + return ret; + +error_chip_name: + kfree(chip->name); + + return ret; +} + +/** + * snd_soc_unregister_chip - Unregister a chip from the ASoC core + * + */ +void snd_soc_unregister_chip(struct device *dev) +{ + struct snd_soc_chip *chip; + + list_for_each_entry(chip, &chip_list, list) { + if (dev == chip->dev) + goto found; + } + return; + +found: + snd_soc_unregister_dais(dev, chip->num_dai); + + mutex_lock(&client_mutex); + list_del(&chip->list); + mutex_unlock(&client_mutex); + + dev_dbg(dev, "ASoC: Unregistered chip '%s'\n", chip->name); + kfree(chip->name); +} + /* Retrieve a card's name from device tree */ int snd_soc_of_parse_card_name(struct snd_soc_card *card, const char *propname)