aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--include/sound/soc.h13
-rw-r--r--sound/soc/soc-core.c35
-rw-r--r--sound/soc/soc-dapm.c34
3 files changed, 78 insertions, 4 deletions
diff --git a/include/sound/soc.h b/include/sound/soc.h
index af23f4228869..3eb92ef6c83f 100644
--- a/include/sound/soc.h
+++ b/include/sound/soc.h
@@ -450,6 +450,7 @@ struct snd_soc_cache_ops {
450/* SoC Audio Codec device */ 450/* SoC Audio Codec device */
451struct snd_soc_codec { 451struct snd_soc_codec {
452 const char *name; 452 const char *name;
453 const char *name_prefix;
453 int id; 454 int id;
454 struct device *dev; 455 struct device *dev;
455 struct snd_soc_codec_driver *driver; 456 struct snd_soc_codec_driver *driver;
@@ -577,6 +578,11 @@ struct snd_soc_dai_link {
577 struct snd_soc_ops *ops; 578 struct snd_soc_ops *ops;
578}; 579};
579 580
581struct snd_soc_prefix_map {
582 const char *dev_name;
583 const char *name_prefix;
584};
585
580/* SoC card */ 586/* SoC card */
581struct snd_soc_card { 587struct snd_soc_card {
582 const char *name; 588 const char *name;
@@ -611,6 +617,13 @@ struct snd_soc_card {
611 struct snd_soc_pcm_runtime *rtd; 617 struct snd_soc_pcm_runtime *rtd;
612 int num_rtd; 618 int num_rtd;
613 619
620 /*
621 * optional map of kcontrol, widget and path name prefixes that are
622 * associated per device
623 */
624 struct snd_soc_prefix_map *prefix_map;
625 int num_prefixes;
626
614 struct work_struct deferred_resume_work; 627 struct work_struct deferred_resume_work;
615 628
616 /* lists of probed devices belonging to this card */ 629 /* lists of probed devices belonging to this card */
diff --git a/sound/soc/soc-core.c b/sound/soc/soc-core.c
index 3d70ce58d03c..2540efd67ee7 100644
--- a/sound/soc/soc-core.c
+++ b/sound/soc/soc-core.c
@@ -1397,6 +1397,23 @@ static void soc_remove_dai_link(struct snd_soc_card *card, int num)
1397 } 1397 }
1398} 1398}
1399 1399
1400static void soc_set_name_prefix(struct snd_soc_card *card,
1401 struct snd_soc_codec *codec)
1402{
1403 int i;
1404
1405 if (card->prefix_map == NULL)
1406 return;
1407
1408 for (i = 0; i < card->num_prefixes; i++) {
1409 struct snd_soc_prefix_map *map = &card->prefix_map[i];
1410 if (map->dev_name && !strcmp(codec->name, map->dev_name)) {
1411 codec->name_prefix = map->name_prefix;
1412 break;
1413 }
1414 }
1415}
1416
1400static void rtd_release(struct device *dev) {} 1417static void rtd_release(struct device *dev) {}
1401 1418
1402static int soc_probe_dai_link(struct snd_soc_card *card, int num) 1419static int soc_probe_dai_link(struct snd_soc_card *card, int num)
@@ -1406,6 +1423,7 @@ static int soc_probe_dai_link(struct snd_soc_card *card, int num)
1406 struct snd_soc_codec *codec = rtd->codec; 1423 struct snd_soc_codec *codec = rtd->codec;
1407 struct snd_soc_platform *platform = rtd->platform; 1424 struct snd_soc_platform *platform = rtd->platform;
1408 struct snd_soc_dai *codec_dai = rtd->codec_dai, *cpu_dai = rtd->cpu_dai; 1425 struct snd_soc_dai *codec_dai = rtd->codec_dai, *cpu_dai = rtd->cpu_dai;
1426 const char *temp;
1409 int ret; 1427 int ret;
1410 1428
1411 dev_dbg(card->dev, "probe %s dai link %d\n", card->name, num); 1429 dev_dbg(card->dev, "probe %s dai link %d\n", card->name, num);
@@ -1440,6 +1458,7 @@ static int soc_probe_dai_link(struct snd_soc_card *card, int num)
1440 /* probe the CODEC */ 1458 /* probe the CODEC */
1441 if (!codec->probed) { 1459 if (!codec->probed) {
1442 codec->dapm.card = card; 1460 codec->dapm.card = card;
1461 soc_set_name_prefix(card, codec);
1443 if (codec->driver->probe) { 1462 if (codec->driver->probe) {
1444 ret = codec->driver->probe(codec); 1463 ret = codec->driver->probe(codec);
1445 if (ret < 0) { 1464 if (ret < 0) {
@@ -1492,11 +1511,15 @@ static int soc_probe_dai_link(struct snd_soc_card *card, int num)
1492 1511
1493 /* now that all clients have probed, initialise the DAI link */ 1512 /* now that all clients have probed, initialise the DAI link */
1494 if (dai_link->init) { 1513 if (dai_link->init) {
1514 /* machine controls, routes and widgets are not prefixed */
1515 temp = rtd->codec->name_prefix;
1516 rtd->codec->name_prefix = NULL;
1495 ret = dai_link->init(rtd); 1517 ret = dai_link->init(rtd);
1496 if (ret < 0) { 1518 if (ret < 0) {
1497 printk(KERN_ERR "asoc: failed to init %s\n", dai_link->stream_name); 1519 printk(KERN_ERR "asoc: failed to init %s\n", dai_link->stream_name);
1498 return ret; 1520 return ret;
1499 } 1521 }
1522 rtd->codec->name_prefix = temp;
1500 } 1523 }
1501 1524
1502 /* Make sure all DAPM widgets are instantiated */ 1525 /* Make sure all DAPM widgets are instantiated */
@@ -2072,14 +2095,22 @@ int snd_soc_add_controls(struct snd_soc_codec *codec,
2072 const struct snd_kcontrol_new *controls, int num_controls) 2095 const struct snd_kcontrol_new *controls, int num_controls)
2073{ 2096{
2074 struct snd_card *card = codec->card->snd_card; 2097 struct snd_card *card = codec->card->snd_card;
2098 char prefixed_name[44], *name;
2075 int err, i; 2099 int err, i;
2076 2100
2077 for (i = 0; i < num_controls; i++) { 2101 for (i = 0; i < num_controls; i++) {
2078 const struct snd_kcontrol_new *control = &controls[i]; 2102 const struct snd_kcontrol_new *control = &controls[i];
2079 err = snd_ctl_add(card, snd_soc_cnew(control, codec, NULL)); 2103 if (codec->name_prefix) {
2104 snprintf(prefixed_name, sizeof(prefixed_name), "%s %s",
2105 codec->name_prefix, control->name);
2106 name = prefixed_name;
2107 } else {
2108 name = control->name;
2109 }
2110 err = snd_ctl_add(card, snd_soc_cnew(control, codec, name));
2080 if (err < 0) { 2111 if (err < 0) {
2081 dev_err(codec->dev, "%s: Failed to add %s: %d\n", 2112 dev_err(codec->dev, "%s: Failed to add %s: %d\n",
2082 codec->name, control->name, err); 2113 codec->name, name, err);
2083 return err; 2114 return err;
2084 } 2115 }
2085 } 2116 }
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)
1295 1295
1296 list_for_each_entry_safe(w, next_w, &dapm->widgets, list) { 1296 list_for_each_entry_safe(w, next_w, &dapm->widgets, list) {
1297 list_del(&w->list); 1297 list_del(&w->list);
1298 kfree(w->name);
1298 kfree(w); 1299 kfree(w);
1299 } 1300 }
1300 1301
@@ -1346,11 +1347,25 @@ static int snd_soc_dapm_add_route(struct snd_soc_dapm_context *dapm,
1346{ 1347{
1347 struct snd_soc_dapm_path *path; 1348 struct snd_soc_dapm_path *path;
1348 struct snd_soc_dapm_widget *wsource = NULL, *wsink = NULL, *w; 1349 struct snd_soc_dapm_widget *wsource = NULL, *wsink = NULL, *w;
1349 const char *sink = route->sink; 1350 const char *sink;
1350 const char *control = route->control; 1351 const char *control = route->control;
1351 const char *source = route->source; 1352 const char *source;
1353 char prefixed_sink[80];
1354 char prefixed_source[80];
1352 int ret = 0; 1355 int ret = 0;
1353 1356
1357 if (dapm->codec->name_prefix) {
1358 snprintf(prefixed_sink, sizeof(prefixed_sink), "%s %s",
1359 dapm->codec->name_prefix, route->sink);
1360 sink = prefixed_sink;
1361 snprintf(prefixed_source, sizeof(prefixed_source), "%s %s",
1362 dapm->codec->name_prefix, route->source);
1363 source = prefixed_source;
1364 } else {
1365 sink = route->sink;
1366 source = route->source;
1367 }
1368
1354 /* find src and dest widgets */ 1369 /* find src and dest widgets */
1355 list_for_each_entry(w, &dapm->widgets, list) { 1370 list_for_each_entry(w, &dapm->widgets, list) {
1356 1371
@@ -1978,10 +1993,25 @@ int snd_soc_dapm_new_control(struct snd_soc_dapm_context *dapm,
1978 const struct snd_soc_dapm_widget *widget) 1993 const struct snd_soc_dapm_widget *widget)
1979{ 1994{
1980 struct snd_soc_dapm_widget *w; 1995 struct snd_soc_dapm_widget *w;
1996 size_t name_len;
1981 1997
1982 if ((w = dapm_cnew_widget(widget)) == NULL) 1998 if ((w = dapm_cnew_widget(widget)) == NULL)
1983 return -ENOMEM; 1999 return -ENOMEM;
1984 2000
2001 name_len = strlen(widget->name) + 1;
2002 if (dapm->codec->name_prefix)
2003 name_len += 1 + strlen(dapm->codec->name_prefix);
2004 w->name = kmalloc(name_len, GFP_KERNEL);
2005 if (w->name == NULL) {
2006 kfree(w);
2007 return -ENOMEM;
2008 }
2009 if (dapm->codec->name_prefix)
2010 snprintf(w->name, name_len, "%s %s",
2011 dapm->codec->name_prefix, widget->name);
2012 else
2013 snprintf(w->name, name_len, "%s", widget->name);
2014
1985 w->dapm = dapm; 2015 w->dapm = dapm;
1986 w->codec = dapm->codec; 2016 w->codec = dapm->codec;
1987 INIT_LIST_HEAD(&w->sources); 2017 INIT_LIST_HEAD(&w->sources);