On Fri, 29 Oct 2010 14:42:45 -0700 Mark Brown <broonie@xxxxxxxxxxxxxxxxxxxxxxxxxxx> wrote: > On Fri, Oct 29, 2010 at 03:03:43PM +0300, Jarkko Nikula wrote: > > > @@ -547,6 +548,9 @@ struct snd_soc_dev_map { > > > > /* machine stream operations */ > > struct snd_soc_ops *ops; > > + > > + /* optional name prefix for kcontrols and widgets */ > > + const char *name_prefix; > > This is another issue with using the DAI links to map these things - as > previously discussed we want to be able to support CODEC<->CODEC DAI > links, and we don't have a way to associate controls with specific DAI > links on multi-DAI devices. Indeed, I forgot these links and then name_prefix in snd_soc_dev_map/_dai_link is not the right place. One of my earlier version of this prefixing stuff implemented a prefix_map to snd_soc_card associating a prefix with codec name. Compile tested diff below. I don't know would it fit to multi-DAI devices. Should those drivers differentiate inside their controls & widgets for different DAIs? -- Jarkko diff --git a/include/sound/soc.h b/include/sound/soc.h index 17f985c..9012c4a 100644 --- a/include/sound/soc.h +++ b/include/sound/soc.h @@ -424,6 +424,7 @@ struct snd_soc_ops { /* SoC Audio Codec device */ struct snd_soc_codec { const char *name; + const char *name_prefix; int id; struct device *dev; struct snd_soc_codec_driver *driver; @@ -549,6 +550,11 @@ struct snd_soc_dev_map { struct snd_soc_ops *ops; }; +struct snd_soc_prefix_map { + const char *codec_name; + const char *name_prefix; +}; + /* SoC card */ struct snd_soc_card { const char *name; @@ -583,6 +589,10 @@ struct snd_soc_card { struct snd_soc_pcm_runtime *rtd; int num_rtd; + /* optional map of name prefixes that are associated per codec */ + struct snd_soc_prefix_map *prefix_map; + int num_prefixes; + struct work_struct deferred_resume_work; /* lists of probed devices belonging to this card */ diff --git a/sound/soc/soc-core.c b/sound/soc/soc-core.c index b904a20..9b8d657 100644 --- a/sound/soc/soc-core.c +++ b/sound/soc/soc-core.c @@ -1371,6 +1371,23 @@ static void soc_remove_dev_map(struct snd_soc_card *card, int num) } } +static void soc_set_name_prefix(struct snd_soc_card *card, + struct snd_soc_codec *codec) +{ + int i; + + if (card->prefix_map == NULL) + return; + + for (i = 0; i < card->num_prefixes; i++) { + struct snd_soc_prefix_map *map = &card->prefix_map[i]; + if (map->codec_name && !strcmp(codec->name, map->codec_name)) { + codec->name_prefix = map->name_prefix; + break; + } + } +} + static void rtd_release(struct device *dev) {} static int soc_probe_dev_map(struct snd_soc_card *card, int num) @@ -1380,6 +1397,7 @@ static int soc_probe_dev_map(struct snd_soc_card *card, int num) struct snd_soc_codec *codec = rtd->codec; struct snd_soc_platform *platform = rtd->platform; struct snd_soc_dai *codec_dai = rtd->codec_dai, *cpu_dai = rtd->cpu_dai; + const char *temp; int ret; dev_dbg(card->dev, "probe %s dai link %d\n", card->name, num); @@ -1416,6 +1434,7 @@ static int soc_probe_dev_map(struct snd_soc_card *card, int num) /* probe the CODEC */ if (!codec->probed) { codec->dapm->card = card; + soc_set_name_prefix(card, codec); if (codec->driver->probe) { ret = codec->driver->probe(codec); if (ret < 0) { @@ -1469,11 +1488,15 @@ static int soc_probe_dev_map(struct snd_soc_card *card, int num) /* now that all clients have probed, initialise the DAI link */ if (dev_map->init) { + /* machine controls, routes and widgets are not prefixed */ + temp = rtd->codec->name_prefix; + rtd->codec->name_prefix = NULL; ret = dev_map->init(rtd); if (ret < 0) { printk(KERN_ERR "asoc: failed to init %s\n", dev_map->stream_name); return ret; } + rtd->codec->name_prefix = temp; } /* Make sure all DAPM widgets are instantiated */ @@ -2030,14 +2053,22 @@ int snd_soc_add_controls(struct snd_soc_codec *codec, const struct snd_kcontrol_new *controls, int num_controls) { struct snd_card *card = codec->card->snd_card; + char prefixed_name[44], *name; int err, i; for (i = 0; i < num_controls; i++) { const struct snd_kcontrol_new *control = &controls[i]; - err = snd_ctl_add(card, snd_soc_cnew(control, codec, NULL)); + if (codec->name_prefix) { + snprintf(prefixed_name, sizeof(prefixed_name), "%s %s", + codec->name_prefix, control->name); + name = prefixed_name; + } else { + name = control->name; + } + err = snd_ctl_add(card, snd_soc_cnew(control, codec, name)); if (err < 0) { dev_err(codec->dev, "%s: Failed to add %s: %d\n", - codec->name, control->name, err); + codec->name, name, err); return err; } } diff --git a/sound/soc/soc-dapm.c b/sound/soc/soc-dapm.c index 2bccc9d..34bc7a8 100644 --- a/sound/soc/soc-dapm.c +++ b/sound/soc/soc-dapm.c @@ -1291,6 +1291,7 @@ static void dapm_free_widgets(struct snd_soc_dapm_context *dapm) kfree(p->long_name); kfree(p); } + kfree(w->name); kfree(w); } } @@ -1339,11 +1340,25 @@ static int snd_soc_dapm_add_route(struct snd_soc_dapm_context *dapm, struct snd_soc_dapm_path *path; struct snd_soc_dapm_widget *wsource = NULL, *wsink = NULL, *w; struct snd_soc_dapm_widget *wtsource = NULL, *wtsink = NULL; - const char *sink = route->sink; + const char *sink; const char *control = route->control; - const char *source = route->source; + const char *source; + char prefixed_sink[80]; + char prefixed_source[80]; int ret = 0; + if (dapm->codec->name_prefix) { + snprintf(prefixed_sink, sizeof(prefixed_sink), "%s %s", + dapm->codec->name_prefix, route->sink); + sink = prefixed_sink; + snprintf(prefixed_source, sizeof(prefixed_source), "%s %s", + dapm->codec->name_prefix, route->source); + source = prefixed_source; + } else { + sink = route->sink; + source = route->source; + } + /* * find src and dest widgets over all widgets but favor a widget from * current DAPM context @@ -1983,10 +1998,25 @@ int snd_soc_dapm_new_control(struct snd_soc_dapm_context *dapm, const struct snd_soc_dapm_widget *widget) { struct snd_soc_dapm_widget *w; + size_t name_len; if ((w = dapm_cnew_widget(widget)) == NULL) return -ENOMEM; + name_len = strlen(widget->name) + 1; + if (dapm->codec->name_prefix) + name_len += 1 + strlen(dapm->codec->name_prefix); + w->name = kmalloc(name_len, GFP_KERNEL); + if (w->name == NULL) { + kfree(w); + return -ENOMEM; + } + if (dapm->codec->name_prefix) + snprintf(w->name, name_len, "%s %s", + dapm->codec->name_prefix, widget->name); + else + snprintf(w->name, name_len, "%s", widget->name); + dapm->n_widgets++; w->dapm = dapm; w->codec = dapm->codec; _______________________________________________ Alsa-devel mailing list Alsa-devel@xxxxxxxxxxxxxxxx http://mailman.alsa-project.org/mailman/listinfo/alsa-devel