Current ASoC has register function for platform/codec/dai/card, but doesn't have for cpu. It often produces confusion and fault on ASoC. This patch adds very basic register function for cpu
Signed-off-by: Kuninori Morimoto kuninori.morimoto.gx@renesas.com --- v6 -> v7
- new feature - based on snd_soc_register_codec()
include/sound/soc.h | 19 ++++++++++++ sound/soc/soc-core.c | 78 ++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 97 insertions(+)
diff --git a/include/sound/soc.h b/include/sound/soc.h index e227880..faffc9c 100644 --- a/include/sound/soc.h +++ b/include/sound/soc.h @@ -322,6 +322,8 @@ struct snd_soc_dai_link; struct snd_soc_platform_driver; struct snd_soc_codec; struct snd_soc_codec_driver; +struct snd_soc_cpu; +struct snd_soc_cpu_driver; struct soc_enum; struct snd_soc_jack; struct snd_soc_jack_zone; @@ -375,6 +377,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_cpu(struct device *dev, + const struct snd_soc_cpu_driver *cpu_drv, + struct snd_soc_dai_driver *dai_drv, int num_dai); +void snd_soc_unregister_cpu(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, @@ -839,6 +845,19 @@ struct snd_soc_platform { #endif };
+struct snd_soc_cpu_driver { +}; + +struct snd_soc_cpu { + const char *name; + int id; + int num_dai; + struct device *dev; + struct list_head list; + + const struct snd_soc_cpu_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 5f44d22..14976ff 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(cpu_list);
/* * This is a timeout to do a DAPM powerdown after a stream is closed(). @@ -4095,6 +4096,83 @@ found: } EXPORT_SYMBOL_GPL(snd_soc_unregister_codec);
+ +/** + * snd_soc_register_cpu - Register a cpu with the ASoC core + * + */ +int snd_soc_register_cpu(struct device *dev, + const struct snd_soc_cpu_driver *cpu_drv, + struct snd_soc_dai_driver *dai_drv, + int num_dai) +{ + struct snd_soc_cpu *cpu; + int ret; + + dev_dbg(dev, "cpu register %s\n", dev_name(dev)); + + cpu = kzalloc(sizeof(struct snd_soc_cpu), GFP_KERNEL); + if (!cpu) + return -ENOMEM; + + cpu->name = fmt_single_name(dev, &cpu->id); + if (!cpu->name) { + ret = -ENOMEM; + goto error_cpu; + } + + cpu->dev = dev; + cpu->driver = cpu_drv; + cpu->num_dai = num_dai; + + mutex_lock(&client_mutex); + list_add(&cpu->list, &cpu_list); + mutex_unlock(&client_mutex); + + ret = snd_soc_register_dais(dev, dai_drv, num_dai); + if (ret < 0) { + dev_err(cpu->dev, "ASoC: Failed to regster DAIs: %d\n", ret); + goto error_cpu_name; + } + + dev_dbg(cpu->dev, "ASoC: Registered cpu '%s'\n", cpu->name); + + return ret; + +error_cpu_name: + kfree(cpu->name); +error_cpu: + kfree(cpu); + + return ret; +} + +/** + * snd_soc_unregister_cpu - Unregister a cpu from the ASoC core + * + */ +void snd_soc_unregister_cpu(struct device *dev) +{ + struct snd_soc_cpu *cpu; + + list_for_each_entry(cpu, &cpu_list, list) { + if (dev == cpu->dev) + goto found; + } + return; + +found: + snd_soc_unregister_dais(dev, cpu->num_dai); + + mutex_lock(&client_mutex); + list_del(&cpu->list); + mutex_unlock(&client_mutex); + + dev_dbg(dev, "ASoC: Unregistered cpu '%s'\n", cpu->name); + kfree(cpu->name); + kfree(cpu); +} + /* Retrieve a card's name from device tree */ int snd_soc_of_parse_card_name(struct snd_soc_card *card, const char *propname)