aboutsummaryrefslogtreecommitdiffstats
path: root/sound/soc/soc-dapm.c
diff options
context:
space:
mode:
authorJarkko Nikula <jhnikula@gmail.com>2010-12-14 05:18:31 -0500
committerMark Brown <broonie@opensource.wolfsonmicro.com>2010-12-15 13:01:01 -0500
commit97c866defc0fc6e18b49603ac19f732f53e79c46 (patch)
tree66ba8412fad0974ebf9a30c45ad5d81f26607e6e /sound/soc/soc-dapm.c
parent8ddab3f5107c3955e70e87a632d4d179ddba1189 (diff)
ASoC: Move widgets from DAPM context to snd_soc_card
Decoupling widgets from DAPM context is required when extending the ASoC core to cross-device paths. Even the list of widgets are now kept in struct snd_soc_card, the widget listing in sysfs and debugs remain sorted per device. This patch makes possible to build cross-device paths but does not extend yet the DAPM to handle codec bias and widget power changes of an another device. Cross-device paths are registered by listing the widgets from device A in a map for device B. In case of conflicting widget names between the devices, a uniform name prefix is needed to separate them. See commit ead9b91 "ASoC: Add optional name_prefix for kcontrol, widget and route names" for help. An example below shows a path that connects MONO out of A into Line In of B: static const struct snd_soc_dapm_route mapA[] = { {"MONO", NULL, "DAC"}, }; static const struct snd_soc_dapm_route mapB[] = { {"Line In", NULL, "MONO"}, }; 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 'sound/soc/soc-dapm.c')
-rw-r--r--sound/soc/soc-dapm.c69
1 files changed, 49 insertions, 20 deletions
diff --git a/sound/soc/soc-dapm.c b/sound/soc/soc-dapm.c
index 5d9ec4a3a9f..8731e89646a 100644
--- a/sound/soc/soc-dapm.c
+++ b/sound/soc/soc-dapm.c
@@ -940,7 +940,9 @@ static int dapm_power_widgets(struct snd_soc_dapm_context *dapm, int event)
940 /* Check which widgets we need to power and store them in 940 /* Check which widgets we need to power and store them in
941 * lists indicating if they should be powered up or down. 941 * lists indicating if they should be powered up or down.
942 */ 942 */
943 list_for_each_entry(w, &dapm->widgets, list) { 943 list_for_each_entry(w, &card->widgets, list) {
944 if (w->dapm != dapm)
945 continue;
944 switch (w->id) { 946 switch (w->id) {
945 case snd_soc_dapm_pre: 947 case snd_soc_dapm_pre:
946 dapm_seq_insert(w, &down_list, dapm_down_seq); 948 dapm_seq_insert(w, &down_list, dapm_down_seq);
@@ -978,7 +980,7 @@ static int dapm_power_widgets(struct snd_soc_dapm_context *dapm, int event)
978 /* If there are no DAPM widgets then try to figure out power from the 980 /* If there are no DAPM widgets then try to figure out power from the
979 * event type. 981 * event type.
980 */ 982 */
981 if (list_empty(&dapm->widgets)) { 983 if (!dapm->n_widgets) {
982 switch (event) { 984 switch (event) {
983 case SND_SOC_DAPM_STREAM_START: 985 case SND_SOC_DAPM_STREAM_START:
984 case SND_SOC_DAPM_STREAM_RESUME: 986 case SND_SOC_DAPM_STREAM_RESUME:
@@ -1145,8 +1147,8 @@ void snd_soc_dapm_debugfs_init(struct snd_soc_dapm_context *dapm)
1145 if (!dapm->debugfs_dapm) 1147 if (!dapm->debugfs_dapm)
1146 return; 1148 return;
1147 1149
1148 list_for_each_entry(w, &dapm->widgets, list) { 1150 list_for_each_entry(w, &dapm->card->widgets, list) {
1149 if (!w->name) 1151 if (!w->name || w->dapm != dapm)
1150 continue; 1152 continue;
1151 1153
1152 d = debugfs_create_file(w->name, 0444, 1154 d = debugfs_create_file(w->name, 0444,
@@ -1241,7 +1243,9 @@ static ssize_t dapm_widget_show(struct device *dev,
1241 int count = 0; 1243 int count = 0;
1242 char *state = "not set"; 1244 char *state = "not set";
1243 1245
1244 list_for_each_entry(w, &codec->dapm.widgets, list) { 1246 list_for_each_entry(w, &codec->card->widgets, list) {
1247 if (w->dapm != &codec->dapm)
1248 continue;
1245 1249
1246 /* only display widgets that burnm power */ 1250 /* only display widgets that burnm power */
1247 switch (w->id) { 1251 switch (w->id) {
@@ -1303,7 +1307,9 @@ static void dapm_free_widgets(struct snd_soc_dapm_context *dapm)
1303 struct snd_soc_dapm_widget *w, *next_w; 1307 struct snd_soc_dapm_widget *w, *next_w;
1304 struct snd_soc_dapm_path *p, *next_p; 1308 struct snd_soc_dapm_path *p, *next_p;
1305 1309
1306 list_for_each_entry_safe(w, next_w, &dapm->widgets, list) { 1310 list_for_each_entry_safe(w, next_w, &dapm->card->widgets, list) {
1311 if (w->dapm != dapm)
1312 continue;
1307 list_del(&w->list); 1313 list_del(&w->list);
1308 /* 1314 /*
1309 * remove source and sink paths associated to this widget. 1315 * remove source and sink paths associated to this widget.
@@ -1334,7 +1340,9 @@ static int snd_soc_dapm_set_pin(struct snd_soc_dapm_context *dapm,
1334{ 1340{
1335 struct snd_soc_dapm_widget *w; 1341 struct snd_soc_dapm_widget *w;
1336 1342
1337 list_for_each_entry(w, &dapm->widgets, list) { 1343 list_for_each_entry(w, &dapm->card->widgets, list) {
1344 if (w->dapm != dapm)
1345 continue;
1338 if (!strcmp(w->name, pin)) { 1346 if (!strcmp(w->name, pin)) {
1339 dev_dbg(w->dapm->dev, "dapm: pin %s = %d\n", 1347 dev_dbg(w->dapm->dev, "dapm: pin %s = %d\n",
1340 pin, status); 1348 pin, status);
@@ -1370,6 +1378,7 @@ static int snd_soc_dapm_add_route(struct snd_soc_dapm_context *dapm,
1370{ 1378{
1371 struct snd_soc_dapm_path *path; 1379 struct snd_soc_dapm_path *path;
1372 struct snd_soc_dapm_widget *wsource = NULL, *wsink = NULL, *w; 1380 struct snd_soc_dapm_widget *wsource = NULL, *wsink = NULL, *w;
1381 struct snd_soc_dapm_widget *wtsource = NULL, *wtsink = NULL;
1373 const char *sink; 1382 const char *sink;
1374 const char *control = route->control; 1383 const char *control = route->control;
1375 const char *source; 1384 const char *source;
@@ -1389,17 +1398,28 @@ static int snd_soc_dapm_add_route(struct snd_soc_dapm_context *dapm,
1389 source = route->source; 1398 source = route->source;
1390 } 1399 }
1391 1400
1392 /* find src and dest widgets */ 1401 /*
1393 list_for_each_entry(w, &dapm->widgets, list) { 1402 * find src and dest widgets over all widgets but favor a widget from
1394 1403 * current DAPM context
1404 */
1405 list_for_each_entry(w, &dapm->card->widgets, list) {
1395 if (!wsink && !(strcmp(w->name, sink))) { 1406 if (!wsink && !(strcmp(w->name, sink))) {
1396 wsink = w; 1407 wtsink = w;
1408 if (w->dapm == dapm)
1409 wsink = w;
1397 continue; 1410 continue;
1398 } 1411 }
1399 if (!wsource && !(strcmp(w->name, source))) { 1412 if (!wsource && !(strcmp(w->name, source))) {
1400 wsource = w; 1413 wtsource = w;
1414 if (w->dapm == dapm)
1415 wsource = w;
1401 } 1416 }
1402 } 1417 }
1418 /* use widget from another DAPM context if not found from this */
1419 if (!wsink)
1420 wsink = wtsink;
1421 if (!wsource)
1422 wsource = wtsource;
1403 1423
1404 if (wsource == NULL || wsink == NULL) 1424 if (wsource == NULL || wsink == NULL)
1405 return -ENODEV; 1425 return -ENODEV;
@@ -1537,7 +1557,7 @@ int snd_soc_dapm_new_widgets(struct snd_soc_dapm_context *dapm)
1537{ 1557{
1538 struct snd_soc_dapm_widget *w; 1558 struct snd_soc_dapm_widget *w;
1539 1559
1540 list_for_each_entry(w, &dapm->widgets, list) 1560 list_for_each_entry(w, &dapm->card->widgets, list)
1541 { 1561 {
1542 if (w->new) 1562 if (w->new)
1543 continue; 1563 continue;
@@ -2037,12 +2057,13 @@ int snd_soc_dapm_new_control(struct snd_soc_dapm_context *dapm,
2037 else 2057 else
2038 snprintf(w->name, name_len, "%s", widget->name); 2058 snprintf(w->name, name_len, "%s", widget->name);
2039 2059
2060 dapm->n_widgets++;
2040 w->dapm = dapm; 2061 w->dapm = dapm;
2041 w->codec = dapm->codec; 2062 w->codec = dapm->codec;
2042 INIT_LIST_HEAD(&w->sources); 2063 INIT_LIST_HEAD(&w->sources);
2043 INIT_LIST_HEAD(&w->sinks); 2064 INIT_LIST_HEAD(&w->sinks);
2044 INIT_LIST_HEAD(&w->list); 2065 INIT_LIST_HEAD(&w->list);
2045 list_add(&w->list, &dapm->widgets); 2066 list_add(&w->list, &dapm->card->widgets);
2046 2067
2047 /* machine layer set ups unconnected pins and insertions */ 2068 /* machine layer set ups unconnected pins and insertions */
2048 w->connected = 1; 2069 w->connected = 1;
@@ -2085,9 +2106,9 @@ static void soc_dapm_stream_event(struct snd_soc_dapm_context *dapm,
2085{ 2106{
2086 struct snd_soc_dapm_widget *w; 2107 struct snd_soc_dapm_widget *w;
2087 2108
2088 list_for_each_entry(w, &dapm->widgets, list) 2109 list_for_each_entry(w, &dapm->card->widgets, list)
2089 { 2110 {
2090 if (!w->sname) 2111 if (!w->sname || w->dapm != dapm)
2091 continue; 2112 continue;
2092 dev_dbg(w->dapm->dev, "widget %s\n %s stream %s event %d\n", 2113 dev_dbg(w->dapm->dev, "widget %s\n %s stream %s event %d\n",
2093 w->name, w->sname, stream, event); 2114 w->name, w->sname, stream, event);
@@ -2170,7 +2191,9 @@ int snd_soc_dapm_force_enable_pin(struct snd_soc_dapm_context *dapm,
2170{ 2191{
2171 struct snd_soc_dapm_widget *w; 2192 struct snd_soc_dapm_widget *w;
2172 2193
2173 list_for_each_entry(w, &dapm->widgets, list) { 2194 list_for_each_entry(w, &dapm->card->widgets, list) {
2195 if (w->dapm != dapm)
2196 continue;
2174 if (!strcmp(w->name, pin)) { 2197 if (!strcmp(w->name, pin)) {
2175 dev_dbg(w->dapm->dev, 2198 dev_dbg(w->dapm->dev,
2176 "dapm: force enable pin %s\n", pin); 2199 "dapm: force enable pin %s\n", pin);
@@ -2235,7 +2258,9 @@ int snd_soc_dapm_get_pin_status(struct snd_soc_dapm_context *dapm,
2235{ 2258{
2236 struct snd_soc_dapm_widget *w; 2259 struct snd_soc_dapm_widget *w;
2237 2260
2238 list_for_each_entry(w, &dapm->widgets, list) { 2261 list_for_each_entry(w, &dapm->card->widgets, list) {
2262 if (w->dapm != dapm)
2263 continue;
2239 if (!strcmp(w->name, pin)) 2264 if (!strcmp(w->name, pin))
2240 return w->connected; 2265 return w->connected;
2241 } 2266 }
@@ -2260,7 +2285,9 @@ int snd_soc_dapm_ignore_suspend(struct snd_soc_dapm_context *dapm,
2260{ 2285{
2261 struct snd_soc_dapm_widget *w; 2286 struct snd_soc_dapm_widget *w;
2262 2287
2263 list_for_each_entry(w, &dapm->widgets, list) { 2288 list_for_each_entry(w, &dapm->card->widgets, list) {
2289 if (w->dapm != dapm)
2290 continue;
2264 if (!strcmp(w->name, pin)) { 2291 if (!strcmp(w->name, pin)) {
2265 w->ignore_suspend = 1; 2292 w->ignore_suspend = 1;
2266 return 0; 2293 return 0;
@@ -2291,7 +2318,9 @@ static void soc_dapm_shutdown_codec(struct snd_soc_dapm_context *dapm)
2291 LIST_HEAD(down_list); 2318 LIST_HEAD(down_list);
2292 int powerdown = 0; 2319 int powerdown = 0;
2293 2320
2294 list_for_each_entry(w, &dapm->widgets, list) { 2321 list_for_each_entry(w, &dapm->card->widgets, list) {
2322 if (w->dapm != dapm)
2323 continue;
2295 if (w->power) { 2324 if (w->power) {
2296 dapm_seq_insert(w, &down_list, dapm_down_seq); 2325 dapm_seq_insert(w, &down_list, dapm_down_seq);
2297 w->power = 0; 2326 w->power = 0;