[alsa-devel] [RFC 4/4] ASoC: Change soc-card codec_conf array to a list

Vaibhav Agarwal vaibhav.agarwal at linaro.org
Mon Feb 15 13:19:32 CET 2016


Currently, number & type of codec(s) available on a platform is
fixed. Thus, machine driver knows in advance the corresponding
device name and can easily define codec_configuration
(name_prefix, compress_type) statically.

However, with the scope of adding codec devices dynamically there
is a need to add codec configuration dynamically as well.
Now we can add/remove codec configuration dynamically in response
to any codec device added/removed.

For backward compatibility, there is a provision to create list
for predefined codec configuration as well.

ToDo:
For snd_soc_remove_codec_config(), possible argument should be
of_node as well to identify codec_conf

Signed-off-by: Vaibhav Agarwal <vaibhav.agarwal at linaro.org>
---
 include/sound/soc.h  | 10 +++++++++-
 sound/soc/soc-core.c | 48 ++++++++++++++++++++++++++++++++++++++++++++----
 2 files changed, 53 insertions(+), 5 deletions(-)

diff --git a/include/sound/soc.h b/include/sound/soc.h
index 44d8568..4074ec3 100644
--- a/include/sound/soc.h
+++ b/include/sound/soc.h
@@ -396,6 +396,7 @@ struct snd_soc_dai_link;
 struct snd_soc_platform_driver;
 struct snd_soc_codec;
 struct snd_soc_codec_driver;
+struct snd_soc_codec_conf;
 struct snd_soc_component;
 struct snd_soc_component_driver;
 struct soc_enum;
@@ -1074,6 +1075,7 @@ struct snd_soc_codec_conf {
 	 * associated per device
 	 */
 	const char *name_prefix;
+	struct list_head list; /* codec_conf list of the soc card */
 };
 
 struct snd_soc_aux_dev {
@@ -1140,8 +1142,9 @@ struct snd_soc_card {
 	int num_rtd;
 
 	/* optional codec specific configuration */
-	struct snd_soc_codec_conf *codec_conf;
+	struct snd_soc_codec_conf *codec_conf; /* predefined configs only */
 	int num_configs;
+	struct list_head codec_conf_list; /* all configs */
 
 	/*
 	 * optional auxiliary devices such as amplifiers or codecs with DAI
@@ -1688,6 +1691,11 @@ int snd_soc_add_dailink(struct snd_soc_card *card,
 			struct snd_soc_dai_link *dai_link);
 void snd_soc_remove_dailink(struct snd_soc_card *card, const char *link_name);
 
+void snd_soc_add_codec_config(struct snd_soc_card *card,
+			      struct snd_soc_codec_conf *codec_conf);
+void snd_soc_remove_codec_config(struct snd_soc_card *card,
+				 const char *dev_name);
+
 int snd_soc_register_dai(struct snd_soc_component *component,
 	struct snd_soc_dai_driver *dai_drv);
 
diff --git a/sound/soc/soc-core.c b/sound/soc/soc-core.c
index 7049f9b..57ce151 100644
--- a/sound/soc/soc-core.c
+++ b/sound/soc/soc-core.c
@@ -1584,16 +1584,51 @@ void snd_soc_remove_dailink(struct snd_soc_card *card, const char *link_name)
 }
 EXPORT_SYMBOL_GPL(snd_soc_remove_dailink);
 
+/**
+ * snd_soc_add_codec_config - add codec configuration to a sound card.
+ *
+ * @card: Sound card identifier to add codec configuration to
+ * @codec_conf: codec configuration to add
+ */
+void snd_soc_add_codec_config(struct snd_soc_card *card,
+			      struct snd_soc_codec_conf *codec_conf)
+{
+	mutex_lock(&client_mutex);
+	list_add_tail(&codec_conf->list, &card->codec_conf_list);
+	mutex_unlock(&client_mutex);
+}
+EXPORT_SYMBOL(snd_soc_add_codec_config);
+
+/**
+ * snd_soc_remove_codec_config - remove codec configuration from a sound card.
+ *
+ * @card: Sound card identifier to remove codec configuration from
+ * @dev_name: codec configuration identifier
+ */
+void snd_soc_remove_codec_config(struct snd_soc_card *card,
+				 const char *dev_name)
+{
+	struct snd_soc_codec_conf *codec_conf;
+
+	mutex_lock(&client_mutex);
+	list_for_each_entry(codec_conf, &card->codec_conf_list, list)
+		if (!strcmp(codec_conf->dev_name, dev_name)) {
+			list_del(&codec_conf->list);
+			break;
+		}
+	mutex_unlock(&client_mutex);
+}
+EXPORT_SYMBOL(snd_soc_remove_codec_config);
+
 static void soc_set_name_prefix(struct snd_soc_card *card,
 				struct snd_soc_component *component)
 {
-	int i;
+	struct snd_soc_codec_conf *map, *_map;
 
-	if (card->codec_conf == NULL)
+	if (list_empty(&card->codec_conf_list))
 		return;
 
-	for (i = 0; i < card->num_configs; i++) {
-		struct snd_soc_codec_conf *map = &card->codec_conf[i];
+	list_for_each_entry_safe(map, _map, &card->codec_conf_list, list) {
 		if (map->of_node && component->dev->of_node != map->of_node)
 			continue;
 		if (map->dev_name && strcmp(component->name, map->dev_name))
@@ -2119,6 +2154,10 @@ static int snd_soc_instantiate_card(struct snd_soc_card *card)
 	for (i = 0; i < card->num_links; i++)
 		snd_soc_add_dai_link(card, card->dai_link+i);
 
+	/* add predefined codec_configs to the list */
+	for (i = 0; i < card->num_configs; i++)
+		snd_soc_add_codec_config(card, card->codec_conf+i);
+
 	/* initialize the register cache for each available codec */
 	list_for_each_entry(codec, &codec_list, list) {
 		if (codec->cache_init)
@@ -2899,6 +2938,7 @@ int snd_soc_register_card(struct snd_soc_card *card)
 	INIT_LIST_HEAD(&card->rtd_list);
 	card->num_rtd = 0;
 
+	INIT_LIST_HEAD(&card->codec_conf_list);
 	INIT_LIST_HEAD(&card->dapm_dirty);
 	INIT_LIST_HEAD(&card->dobj_list);
 	card->instantiated = 0;
-- 
2.1.4



More information about the Alsa-devel mailing list