diff options
author | Jarkko Nikula <jhnikula@gmail.com> | 2010-11-13 19:40:44 +0100 |
---|---|---|
committer | Mark Brown <broonie@opensource.wolfsonmicro.com> | 2010-11-15 16:24:58 +0100 |
commit | ead9b9199c09653dd9b889933c7af75f020c7286 (patch) | |
tree | 54ea7e4e8b8954236387f1131a9a09e305704c46 /sound/soc/soc-dapm.c | |
parent | Merge branch 'for-2.6.37' into for-2.6.38 (diff) | |
download | linux-ead9b9199c09653dd9b889933c7af75f020c7286.tar.xz linux-ead9b9199c09653dd9b889933c7af75f020c7286.zip |
ASoC: Add optional name_prefix for codec kcontrol, widget and route names
There is a need to prefix codec kcontrol, widget and internal route names in
an ASoC machine that has multiple codecs with conflicting names. The name
collision would occur when codec drivers try to registering kcontrols with
the same name or when building audio paths.
This patch introduces optional prefix_map into struct snd_soc_card. With it
machine drivers can specify a unique name prefix to each codec that have
conflicting names with anothers. Prefix to codec is matched with codec
name.
Following example illustrates a machine that has two same codec instances.
Name collision from kcontrol registration is avoided by specifying a name
prefix "foo" for the second codec. As the codec widget names are prefixed
then second audio map for that codec shows a prefixed widget name.
static const struct snd_soc_dapm_route map0[] = {
{"Spk", NULL, "MONO"},
};
static const struct snd_soc_dapm_route map1[] = {
{"Vibra", NULL, "foo MONO"},
};
static struct snd_soc_prefix_map codec_prefix[] = {
{
.dev_name = "codec.2",
.name_prefix = "foo",
},
};
static struct snd_soc_card card = {
...
.prefix_map = codec_prefix,
.num_prefixes = ARRAY_SIZE(codec_prefix),
};
Signed-off-by: Jarkko Nikula <jhnikula@gmail.com>
Acked-by: Liam Girdwood <lrg@slimlogic.co.uk>
Signed-off-by: Mark Brown <broonie@opensource.wolfsonmicro.com>
Diffstat (limited to '')
-rw-r--r-- | sound/soc/soc-dapm.c | 34 |
1 files changed, 32 insertions, 2 deletions
diff --git a/sound/soc/soc-dapm.c b/sound/soc/soc-dapm.c index bc2ec06943c0..60c8dec49480 100644 --- a/sound/soc/soc-dapm.c +++ b/sound/soc/soc-dapm.c @@ -1295,6 +1295,7 @@ static void dapm_free_widgets(struct snd_soc_dapm_context *dapm) list_for_each_entry_safe(w, next_w, &dapm->widgets, list) { list_del(&w->list); + kfree(w->name); kfree(w); } @@ -1346,11 +1347,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; - 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 */ list_for_each_entry(w, &dapm->widgets, list) { @@ -1978,10 +1993,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); + w->dapm = dapm; w->codec = dapm->codec; INIT_LIST_HEAD(&w->sources); |