提交 215edda3 编写于 作者: M Mark Brown

ASoC: Allow per-route connectedness checks for supplies

Some chips with complex internal supply (particularly clocking)
arragements may have multiple options for some of the supply
connections. Since these don't affect user-visible audio routing
the expectation would be that they would be managed automatically
by one of the drivers.

Support these users by allowing routes to have a connected function
which is queried before the connectedness of the path is checked as
normal. Currently this is only done for supplies, other widgets
could be supported but are not currently since the expectation for
them is that audio routing will be under the control of userspace.
Signed-off-by: NMark Brown <broonie@opensource.wolfsonmicro.com>
上级 341c9b84
...@@ -333,6 +333,10 @@ struct snd_soc_dapm_route { ...@@ -333,6 +333,10 @@ struct snd_soc_dapm_route {
const char *sink; const char *sink;
const char *control; const char *control;
const char *source; const char *source;
/* Note: currently only supported for links where source is a supply */
int (*connected)(struct snd_soc_dapm_widget *source,
struct snd_soc_dapm_widget *sink);
}; };
/* dapm audio path between two widgets */ /* dapm audio path between two widgets */
...@@ -349,6 +353,9 @@ struct snd_soc_dapm_path { ...@@ -349,6 +353,9 @@ struct snd_soc_dapm_path {
u32 connect:1; /* source and sink widgets are connected */ u32 connect:1; /* source and sink widgets are connected */
u32 walked:1; /* path has been walked */ u32 walked:1; /* path has been walked */
int (*connected)(struct snd_soc_dapm_widget *source,
struct snd_soc_dapm_widget *sink);
struct list_head list_source; struct list_head list_source;
struct list_head list_sink; struct list_head list_sink;
struct list_head list; struct list_head list;
......
...@@ -718,6 +718,10 @@ static int dapm_supply_check_power(struct snd_soc_dapm_widget *w) ...@@ -718,6 +718,10 @@ static int dapm_supply_check_power(struct snd_soc_dapm_widget *w)
/* Check if one of our outputs is connected */ /* Check if one of our outputs is connected */
list_for_each_entry(path, &w->sinks, list_source) { list_for_each_entry(path, &w->sinks, list_source) {
if (path->connected &&
!path->connected(path->source, path->sink))
continue;
if (path->sink && path->sink->power_check && if (path->sink && path->sink->power_check &&
path->sink->power_check(path->sink)) { path->sink->power_check(path->sink)) {
power = 1; power = 1;
...@@ -1136,6 +1140,9 @@ static ssize_t dapm_widget_power_read_file(struct file *file, ...@@ -1136,6 +1140,9 @@ static ssize_t dapm_widget_power_read_file(struct file *file,
w->sname); w->sname);
list_for_each_entry(p, &w->sources, list_sink) { list_for_each_entry(p, &w->sources, list_sink) {
if (p->connected && !p->connected(w, p->sink))
continue;
if (p->connect) if (p->connect)
ret += snprintf(buf + ret, PAGE_SIZE - ret, ret += snprintf(buf + ret, PAGE_SIZE - ret,
" in %s %s\n", " in %s %s\n",
...@@ -1143,6 +1150,9 @@ static ssize_t dapm_widget_power_read_file(struct file *file, ...@@ -1143,6 +1150,9 @@ static ssize_t dapm_widget_power_read_file(struct file *file,
p->source->name); p->source->name);
} }
list_for_each_entry(p, &w->sinks, list_source) { list_for_each_entry(p, &w->sinks, list_source) {
if (p->connected && !p->connected(w, p->sink))
continue;
if (p->connect) if (p->connect)
ret += snprintf(buf + ret, PAGE_SIZE - ret, ret += snprintf(buf + ret, PAGE_SIZE - ret,
" out %s %s\n", " out %s %s\n",
...@@ -1385,10 +1395,13 @@ int snd_soc_dapm_sync(struct snd_soc_codec *codec) ...@@ -1385,10 +1395,13 @@ int snd_soc_dapm_sync(struct snd_soc_codec *codec)
EXPORT_SYMBOL_GPL(snd_soc_dapm_sync); EXPORT_SYMBOL_GPL(snd_soc_dapm_sync);
static int snd_soc_dapm_add_route(struct snd_soc_codec *codec, static int snd_soc_dapm_add_route(struct snd_soc_codec *codec,
const char *sink, const char *control, const char *source) const struct snd_soc_dapm_route *route)
{ {
struct snd_soc_dapm_path *path; struct snd_soc_dapm_path *path;
struct snd_soc_dapm_widget *wsource = NULL, *wsink = NULL, *w; struct snd_soc_dapm_widget *wsource = NULL, *wsink = NULL, *w;
const char *sink = route->sink;
const char *control = route->control;
const char *source = route->source;
int ret = 0; int ret = 0;
/* find src and dest widgets */ /* find src and dest widgets */
...@@ -1412,6 +1425,7 @@ static int snd_soc_dapm_add_route(struct snd_soc_codec *codec, ...@@ -1412,6 +1425,7 @@ static int snd_soc_dapm_add_route(struct snd_soc_codec *codec,
path->source = wsource; path->source = wsource;
path->sink = wsink; path->sink = wsink;
path->connected = route->connected;
INIT_LIST_HEAD(&path->list); INIT_LIST_HEAD(&path->list);
INIT_LIST_HEAD(&path->list_source); INIT_LIST_HEAD(&path->list_source);
INIT_LIST_HEAD(&path->list_sink); INIT_LIST_HEAD(&path->list_sink);
...@@ -1512,8 +1526,7 @@ int snd_soc_dapm_add_routes(struct snd_soc_codec *codec, ...@@ -1512,8 +1526,7 @@ int snd_soc_dapm_add_routes(struct snd_soc_codec *codec,
int i, ret; int i, ret;
for (i = 0; i < num; i++) { for (i = 0; i < num; i++) {
ret = snd_soc_dapm_add_route(codec, route->sink, ret = snd_soc_dapm_add_route(codec, route);
route->control, route->source);
if (ret < 0) { if (ret < 0) {
printk(KERN_ERR "Failed to add route %s->%s\n", printk(KERN_ERR "Failed to add route %s->%s\n",
route->source, route->source,
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册