[alsa-devel] [PATCH 0/4] ASoC: Aux dev initialization cleanup
This patch cleans up the way a aux dev is initialized and bound to the rtd. This is useful for both componentization (moving aux devs to the component level) as well as for the multi-CODEC support patches.
The series depends on topic/component.
- Lars
Lars-Peter Clausen (4): ASoC: Remove duplicated rtd->codec initialization ASoC: Replace soc_find_matching_codec() with soc_find_codec() ASoC: Bind aux devs early ASoC: Move non-shared code paths out of snd_soc_post_component_init()
sound/soc/soc-core.c | 192 +++++++++++++++++---------------------------------- 1 file changed, 62 insertions(+), 130 deletions(-)
rtd->codec is already initialized in soc_bind_dai_link(), so there is no need to do it again in soc_dai_link_init(). Removing the rtd->codec initialization from soc_dai_link_init() also removes the need for soc_dai_link_init() to know about the CODEC at all.
Signed-off-by: Lars-Peter Clausen lars@metafoo.de --- sound/soc/soc-core.c | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-)
diff --git a/sound/soc/soc-core.c b/sound/soc/soc-core.c index 72d4a2b..0cd36b7 100644 --- a/sound/soc/soc-core.c +++ b/sound/soc/soc-core.c @@ -1308,9 +1308,7 @@ static int soc_aux_dev_init(struct snd_soc_card *card, return 0; }
-static int soc_dai_link_init(struct snd_soc_card *card, - struct snd_soc_codec *codec, - int num) +static int soc_dai_link_init(struct snd_soc_card *card, int num) { struct snd_soc_dai_link *dai_link = &card->dai_link[num]; struct snd_soc_pcm_runtime *rtd = &card->rtd[num]; @@ -1325,8 +1323,6 @@ static int soc_dai_link_init(struct snd_soc_card *card, return ret; }
- rtd->codec = codec; - return 0; }
@@ -1344,7 +1340,7 @@ static int soc_post_component_init(struct snd_soc_card *card, dai_link = &card->dai_link[num]; rtd = &card->rtd[num]; name = dai_link->name; - ret = soc_dai_link_init(card, codec, num); + ret = soc_dai_link_init(card, num); } else { aux_dev = &card->aux_dev[num]; rtd = &card->rtd_aux[num];
soc_find_matching_codec() works in the same way as soc_find_codec() except that it only works for auxdevs. It can easily be replaced by the generic soc_find_codec().
Signed-off-by: Lars-Peter Clausen lars@metafoo.de --- sound/soc/soc-core.c | 26 ++++---------------------- 1 file changed, 4 insertions(+), 22 deletions(-)
diff --git a/sound/soc/soc-core.c b/sound/soc/soc-core.c index 0cd36b7..c8bdac2 100644 --- a/sound/soc/soc-core.c +++ b/sound/soc/soc-core.c @@ -1649,32 +1649,13 @@ static void soc_unregister_ac97_dai_link(struct snd_soc_pcm_runtime *rtd) } #endif
-static struct snd_soc_codec *soc_find_matching_codec(struct snd_soc_card *card, - int num) -{ - struct snd_soc_aux_dev *aux_dev = &card->aux_dev[num]; - struct snd_soc_codec *codec; - - /* find CODEC from registered CODECs */ - list_for_each_entry(codec, &codec_list, list) { - if (aux_dev->codec_of_node && - (codec->dev->of_node != aux_dev->codec_of_node)) - continue; - if (aux_dev->codec_name && - strcmp(codec->component.name, aux_dev->codec_name)) - continue; - return codec; - } - - return NULL; -} - static int soc_check_aux_dev(struct snd_soc_card *card, int num) { struct snd_soc_aux_dev *aux_dev = &card->aux_dev[num]; const char *codecname = aux_dev->codec_name; - struct snd_soc_codec *codec = soc_find_matching_codec(card, num); + struct snd_soc_codec *codec;
+ codec = soc_find_codec(aux_dev->codec_of_node, aux_dev->codec_name); if (codec) return 0; if (aux_dev->codec_of_node) @@ -1689,8 +1670,9 @@ static int soc_probe_aux_dev(struct snd_soc_card *card, int num) struct snd_soc_aux_dev *aux_dev = &card->aux_dev[num]; const char *codecname = aux_dev->codec_name; int ret = -ENODEV; - struct snd_soc_codec *codec = soc_find_matching_codec(card, num); + struct snd_soc_codec *codec;
+ codec = soc_find_codec(aux_dev->codec_of_node, aux_dev->codec_name); if (!codec) { if (aux_dev->codec_of_node) codecname = of_node_full_name(aux_dev->codec_of_node);
Currently in snd_soc_instantiate_card() we only check if the aux dev exists, but do not yet assign it to its rtd. This means that we need to lookup the aux dev again in soc_probe_aux_dev(). This patch changes the behavior to assign the aux dev to the rtd in soc_check_aux_dev() (and renames it to soc_bind_aux_dev()). This simplifies the implementation a bit and also removes the need for soc_post_component_init() to know about the specific CODEC that was assigned to the rtd. The later is necessary for componentization as the code should work for all types of components not just CODECs. This new behavior is also more in sync with how soc_bind_dai_link()/soc_probe_link_dais() works.
Signed-off-by: Lars-Peter Clausen lars@metafoo.de --- sound/soc/soc-core.c | 67 ++++++++++++++++++++-------------------------------- 1 file changed, 25 insertions(+), 42 deletions(-)
diff --git a/sound/soc/soc-core.c b/sound/soc/soc-core.c index c8bdac2..0b870bb 100644 --- a/sound/soc/soc-core.c +++ b/sound/soc/soc-core.c @@ -1286,9 +1286,7 @@ static void rtd_release(struct device *dev) kfree(dev); }
-static int soc_aux_dev_init(struct snd_soc_card *card, - struct snd_soc_codec *codec, - int num) +static int soc_aux_dev_init(struct snd_soc_card *card, int num) { struct snd_soc_aux_dev *aux_dev = &card->aux_dev[num]; struct snd_soc_pcm_runtime *rtd = &card->rtd_aux[num]; @@ -1298,13 +1296,11 @@ static int soc_aux_dev_init(struct snd_soc_card *card,
/* do machine specific initialization */ if (aux_dev->init) { - ret = aux_dev->init(&codec->dapm); + ret = aux_dev->init(&rtd->codec->dapm); if (ret < 0) return ret; }
- rtd->codec = codec; - return 0; }
@@ -1327,7 +1323,6 @@ static int soc_dai_link_init(struct snd_soc_card *card, int num) }
static int soc_post_component_init(struct snd_soc_card *card, - struct snd_soc_codec *codec, int num, int dailess) { struct snd_soc_dai_link *dai_link = NULL; @@ -1345,7 +1340,7 @@ static int soc_post_component_init(struct snd_soc_card *card, aux_dev = &card->aux_dev[num]; rtd = &card->rtd_aux[num]; name = aux_dev->name; - ret = soc_aux_dev_init(card, codec, num); + ret = soc_aux_dev_init(card, num); }
if (ret < 0) { @@ -1380,13 +1375,13 @@ static int soc_post_component_init(struct snd_soc_card *card, /* add DAPM sysfs entries for this codec */ ret = snd_soc_dapm_sys_add(rtd->dev); if (ret < 0) - dev_err(codec->dev, + dev_err(rtd->dev, "ASoC: failed to add codec dapm sysfs entries: %d\n", ret);
/* add codec sysfs entries */ ret = device_create_file(rtd->dev, &dev_attr_codec_reg); if (ret < 0) - dev_err(codec->dev, + dev_err(rtd->dev, "ASoC: failed to add codec sysfs files: %d\n", ret);
#ifdef CONFIG_DEBUG_FS @@ -1551,7 +1546,7 @@ static int soc_probe_link_dais(struct snd_soc_card *card, int num, int order) if (order != SND_SOC_COMP_ORDER_LAST) return 0;
- ret = soc_post_component_init(card, codec, num, 0); + ret = soc_post_component_init(card, num, 0); if (ret) return ret;
@@ -1649,51 +1644,39 @@ static void soc_unregister_ac97_dai_link(struct snd_soc_pcm_runtime *rtd) } #endif
-static int soc_check_aux_dev(struct snd_soc_card *card, int num) -{ - struct snd_soc_aux_dev *aux_dev = &card->aux_dev[num]; - const char *codecname = aux_dev->codec_name; - struct snd_soc_codec *codec; - - codec = soc_find_codec(aux_dev->codec_of_node, aux_dev->codec_name); - if (codec) - return 0; - if (aux_dev->codec_of_node) - codecname = of_node_full_name(aux_dev->codec_of_node); - - dev_err(card->dev, "ASoC: %s not registered\n", codecname); - return -EPROBE_DEFER; -} - -static int soc_probe_aux_dev(struct snd_soc_card *card, int num) +static int soc_bind_aux_dev(struct snd_soc_card *card, int num) { + struct snd_soc_pcm_runtime *rtd = &card->rtd_aux[num]; struct snd_soc_aux_dev *aux_dev = &card->aux_dev[num]; const char *codecname = aux_dev->codec_name; - int ret = -ENODEV; - struct snd_soc_codec *codec;
- codec = soc_find_codec(aux_dev->codec_of_node, aux_dev->codec_name); - if (!codec) { + rtd->codec = soc_find_codec(aux_dev->codec_of_node, codecname); + if (!rtd->codec) { if (aux_dev->codec_of_node) codecname = of_node_full_name(aux_dev->codec_of_node);
- /* codec not found */ - dev_err(card->dev, "ASoC: codec %s not found", codecname); + dev_err(card->dev, "ASoC: %s not registered\n", codecname); return -EPROBE_DEFER; }
- if (codec->probed) { - dev_err(codec->dev, "ASoC: codec already probed"); + return 0; +} + +static int soc_probe_aux_dev(struct snd_soc_card *card, int num) +{ + struct snd_soc_pcm_runtime *rtd = &card->rtd_aux[num]; + int ret; + + if (rtd->codec->probed) { + dev_err(rtd->codec->dev, "ASoC: codec already probed\n"); return -EBUSY; }
- ret = soc_probe_codec(card, codec); + ret = soc_probe_codec(card, rtd->codec); if (ret < 0) return ret;
- ret = soc_post_component_init(card, codec, num, 1); - - return ret; + return soc_post_component_init(card, num, 1); }
static void soc_remove_aux_dev(struct snd_soc_card *card, int num) @@ -1745,9 +1728,9 @@ static int snd_soc_instantiate_card(struct snd_soc_card *card) goto base_error; }
- /* check aux_devs too */ + /* bind aux_devs too */ for (i = 0; i < card->num_aux_devs; i++) { - ret = soc_check_aux_dev(card, i); + ret = soc_bind_aux_dev(card, i); if (ret != 0) goto base_error; }
There are two call sites for snd_soc_post_component_init(), one passes 0 and the other 1 for the 'dailess' parameter of snd_soc_post_component_init(). Depending on whether 'dailess' is 0 or 1 snd_soc_post_component_init() runs different code at the beginning and the end of the function. The patch moves this conditional code out of snd_soc_post_component_init() and into the call sites. This removes the need for snd_soc_post_component_init() to know whether it is called for a DAI link or a aux dev.
Also do the initialization of rtd->card when the rtd struct is allocated.
Signed-off-by: Lars-Peter Clausen lars@metafoo.de --- sound/soc/soc-core.c | 121 ++++++++++++++++++++------------------------------- 1 file changed, 46 insertions(+), 75 deletions(-)
diff --git a/sound/soc/soc-core.c b/sound/soc/soc-core.c index 0b870bb..6712e2f 100644 --- a/sound/soc/soc-core.c +++ b/sound/soc/soc-core.c @@ -1286,74 +1286,17 @@ static void rtd_release(struct device *dev) kfree(dev); }
-static int soc_aux_dev_init(struct snd_soc_card *card, int num) +static int soc_post_component_init(struct snd_soc_pcm_runtime *rtd, + const char *name) { - struct snd_soc_aux_dev *aux_dev = &card->aux_dev[num]; - struct snd_soc_pcm_runtime *rtd = &card->rtd_aux[num]; - int ret; - - rtd->card = card; - - /* do machine specific initialization */ - if (aux_dev->init) { - ret = aux_dev->init(&rtd->codec->dapm); - if (ret < 0) - return ret; - } - - return 0; -} - -static int soc_dai_link_init(struct snd_soc_card *card, int num) -{ - struct snd_soc_dai_link *dai_link = &card->dai_link[num]; - struct snd_soc_pcm_runtime *rtd = &card->rtd[num]; - int ret; - - rtd->card = card; - - /* do machine specific initialization */ - if (dai_link->init) { - ret = dai_link->init(rtd); - if (ret < 0) - return ret; - } - - return 0; -} - -static int soc_post_component_init(struct snd_soc_card *card, - int num, int dailess) -{ - struct snd_soc_dai_link *dai_link = NULL; - struct snd_soc_aux_dev *aux_dev = NULL; - struct snd_soc_pcm_runtime *rtd; - const char *name; int ret = 0;
- if (!dailess) { - dai_link = &card->dai_link[num]; - rtd = &card->rtd[num]; - name = dai_link->name; - ret = soc_dai_link_init(card, num); - } else { - aux_dev = &card->aux_dev[num]; - rtd = &card->rtd_aux[num]; - name = aux_dev->name; - ret = soc_aux_dev_init(card, num); - } - - if (ret < 0) { - dev_err(card->dev, "ASoC: failed to init %s: %d\n", name, ret); - return ret; - } - /* register the rtd device */ rtd->dev = kzalloc(sizeof(struct device), GFP_KERNEL); if (!rtd->dev) return -ENOMEM; device_initialize(rtd->dev); - rtd->dev->parent = card->dev; + rtd->dev->parent = rtd->card->dev; rtd->dev->release = rtd_release; rtd->dev->init_name = name; dev_set_drvdata(rtd->dev, rtd); @@ -1366,7 +1309,7 @@ static int soc_post_component_init(struct snd_soc_card *card, if (ret < 0) { /* calling put_device() here to free the rtd->dev */ put_device(rtd->dev); - dev_err(card->dev, + dev_err(rtd->card->dev, "ASoC: failed to register runtime device: %d\n", ret); return ret; } @@ -1384,17 +1327,6 @@ static int soc_post_component_init(struct snd_soc_card *card, dev_err(rtd->dev, "ASoC: failed to add codec sysfs files: %d\n", ret);
-#ifdef CONFIG_DEBUG_FS - /* add DPCM sysfs entries */ - if (!dailess && !dai_link->dynamic) - goto out; - - ret = soc_dpcm_debugfs_add(rtd); - if (ret < 0) - dev_err(rtd->dev, "ASoC: failed to add dpcm sysfs entries: %d\n", ret); - -out: -#endif return 0; }
@@ -1546,10 +1478,33 @@ static int soc_probe_link_dais(struct snd_soc_card *card, int num, int order) if (order != SND_SOC_COMP_ORDER_LAST) return 0;
- ret = soc_post_component_init(card, num, 0); + /* do machine specific initialization */ + if (dai_link->init) { + ret = dai_link->init(rtd); + if (ret < 0) { + dev_err(card->dev, "ASoC: failed to init %s: %d\n", + dai_link->name, ret); + return ret; + } + } + + ret = soc_post_component_init(rtd, dai_link->name); if (ret) return ret;
+#ifdef CONFIG_DEBUG_FS + /* add DPCM sysfs entries */ + if (dai_link->dynamic) { + ret = soc_dpcm_debugfs_add(rtd); + if (ret < 0) { + dev_err(rtd->dev, + "ASoC: failed to add dpcm sysfs entries: %d\n", + ret); + return ret; + } + } +#endif + ret = device_create_file(rtd->dev, &dev_attr_pmdown_time); if (ret < 0) dev_warn(rtd->dev, "ASoC: failed to add pmdown_time sysfs: %d\n", @@ -1665,6 +1620,7 @@ static int soc_bind_aux_dev(struct snd_soc_card *card, int num) static int soc_probe_aux_dev(struct snd_soc_card *card, int num) { struct snd_soc_pcm_runtime *rtd = &card->rtd_aux[num]; + struct snd_soc_aux_dev *aux_dev = &card->aux_dev[num]; int ret;
if (rtd->codec->probed) { @@ -1676,7 +1632,17 @@ static int soc_probe_aux_dev(struct snd_soc_card *card, int num) if (ret < 0) return ret;
- return soc_post_component_init(card, num, 1); + /* do machine specific initialization */ + if (aux_dev->init) { + ret = aux_dev->init(&rtd->codec->dapm); + if (ret < 0) { + dev_err(card->dev, "ASoC: failed to init %s: %d\n", + aux_dev->name, ret); + return ret; + } + } + + return soc_post_component_init(rtd, aux_dev->name); }
static void soc_remove_aux_dev(struct snd_soc_card *card, int num) @@ -3775,8 +3741,13 @@ int snd_soc_register_card(struct snd_soc_card *card) card->num_rtd = 0; card->rtd_aux = &card->rtd[card->num_links];
- for (i = 0; i < card->num_links; i++) + for (i = 0; i < card->num_links; i++) { + card->rtd[i].card = card; card->rtd[i].dai_link = &card->dai_link[i]; + } + + for (i = 0; i < card->num_aux_devs; i++) + card->rtd_aux[i].card = card;
INIT_LIST_HEAD(&card->dapm_dirty); card->instantiated = 0;
On Tue, Jul 01, 2014 at 10:13:44PM +0200, Lars-Peter Clausen wrote:
This patch cleans up the way a aux dev is initialized and bound to the rtd. This is useful for both componentization (moving aux devs to the component level) as well as for the multi-CODEC support patches.
Applied all, thanks.
participants (2)
-
Lars-Peter Clausen
-
Mark Brown