diff options
-rw-r--r-- | include/sound/soc.h | 13 | ||||
-rw-r--r-- | sound/soc/soc-core.c | 35 | ||||
-rw-r--r-- | sound/soc/soc-dapm.c | 34 |
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 */ |
451 | struct snd_soc_codec { | 451 | struct 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 | ||
581 | struct snd_soc_prefix_map { | ||
582 | const char *dev_name; | ||
583 | const char *name_prefix; | ||
584 | }; | ||
585 | |||
580 | /* SoC card */ | 586 | /* SoC card */ |
581 | struct snd_soc_card { | 587 | struct 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 | ||
1400 | static 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 | |||
1400 | static void rtd_release(struct device *dev) {} | 1417 | static void rtd_release(struct device *dev) {} |
1401 | 1418 | ||
1402 | static int soc_probe_dai_link(struct snd_soc_card *card, int num) | 1419 | static 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); |