Commit 522f88da authored by Mark Brown's avatar Mark Brown

ASoC: simple-card: sync support

Merge series from Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>:

We have simple-card / audio-graph / audio-graph2, basically these supports
same feature but is using different DT style.

Because we are using 3 drivers, some feature was added to one driver,
but other drivers doesn't have it. This patch set try to sync it on these
3 drivers.
parents 9d52d7ea c4cfe113
...@@ -197,7 +197,7 @@ int graph_util_is_ports0(struct device_node *port); ...@@ -197,7 +197,7 @@ int graph_util_is_ports0(struct device_node *port);
int graph_util_parse_dai(struct device *dev, struct device_node *ep, int graph_util_parse_dai(struct device *dev, struct device_node *ep,
struct snd_soc_dai_link_component *dlc, int *is_single_link); struct snd_soc_dai_link_component *dlc, int *is_single_link);
int graph_util_parse_link_direction(struct device_node *np, void graph_util_parse_link_direction(struct device_node *np,
bool *is_playback_only, bool *is_capture_only); bool *is_playback_only, bool *is_capture_only);
#ifdef DEBUG #ifdef DEBUG
......
...@@ -19,6 +19,18 @@ ...@@ -19,6 +19,18 @@
#define DPCM_SELECTABLE 1 #define DPCM_SELECTABLE 1
#define ep_to_port(ep) of_get_parent(ep)
static struct device_node *port_to_ports(struct device_node *port)
{
struct device_node *ports = of_get_parent(port);
if (!of_node_name_eq(ports, "ports")) {
of_node_put(ports);
return NULL;
}
return ports;
}
static int graph_outdrv_event(struct snd_soc_dapm_widget *w, static int graph_outdrv_event(struct snd_soc_dapm_widget *w,
struct snd_kcontrol *kcontrol, struct snd_kcontrol *kcontrol,
int event) int event)
...@@ -68,13 +80,12 @@ static void graph_parse_convert(struct device *dev, ...@@ -68,13 +80,12 @@ static void graph_parse_convert(struct device *dev,
struct simple_util_data *adata) struct simple_util_data *adata)
{ {
struct device_node *top = dev->of_node; struct device_node *top = dev->of_node;
struct device_node *port = of_get_parent(ep); struct device_node *port = ep_to_port(ep);
struct device_node *ports = of_get_parent(port); struct device_node *ports = port_to_ports(port);
struct device_node *node = of_graph_get_port_parent(ep); struct device_node *node = of_graph_get_port_parent(ep);
simple_util_parse_convert(top, NULL, adata); simple_util_parse_convert(top, NULL, adata);
if (of_node_name_eq(ports, "ports")) simple_util_parse_convert(ports, NULL, adata);
simple_util_parse_convert(ports, NULL, adata);
simple_util_parse_convert(port, NULL, adata); simple_util_parse_convert(port, NULL, adata);
simple_util_parse_convert(ep, NULL, adata); simple_util_parse_convert(ep, NULL, adata);
...@@ -83,30 +94,12 @@ static void graph_parse_convert(struct device *dev, ...@@ -83,30 +94,12 @@ static void graph_parse_convert(struct device *dev,
of_node_put(node); of_node_put(node);
} }
static void graph_parse_mclk_fs(struct device_node *top,
struct device_node *ep,
struct simple_dai_props *props)
{
struct device_node *port = of_get_parent(ep);
struct device_node *ports = of_get_parent(port);
of_property_read_u32(top, "mclk-fs", &props->mclk_fs);
if (of_node_name_eq(ports, "ports"))
of_property_read_u32(ports, "mclk-fs", &props->mclk_fs);
of_property_read_u32(port, "mclk-fs", &props->mclk_fs);
of_property_read_u32(ep, "mclk-fs", &props->mclk_fs);
of_node_put(port);
of_node_put(ports);
}
static int graph_parse_node(struct simple_util_priv *priv, static int graph_parse_node(struct simple_util_priv *priv,
struct device_node *ep, struct device_node *ep,
struct link_info *li, struct link_info *li,
int *cpu) int *cpu)
{ {
struct device *dev = simple_priv_to_dev(priv); struct device *dev = simple_priv_to_dev(priv);
struct device_node *top = dev->of_node;
struct snd_soc_dai_link *dai_link = simple_priv_to_link(priv, li->link); struct snd_soc_dai_link *dai_link = simple_priv_to_link(priv, li->link);
struct simple_dai_props *dai_props = simple_priv_to_props(priv, li->link); struct simple_dai_props *dai_props = simple_priv_to_props(priv, li->link);
struct snd_soc_dai_link_component *dlc; struct snd_soc_dai_link_component *dlc;
...@@ -121,8 +114,6 @@ static int graph_parse_node(struct simple_util_priv *priv, ...@@ -121,8 +114,6 @@ static int graph_parse_node(struct simple_util_priv *priv,
dai = simple_props_to_dai_codec(dai_props, 0); dai = simple_props_to_dai_codec(dai_props, 0);
} }
graph_parse_mclk_fs(top, ep, dai_props);
ret = graph_util_parse_dai(dev, ep, dlc, cpu); ret = graph_util_parse_dai(dev, ep, dlc, cpu);
if (ret < 0) if (ret < 0)
return ret; return ret;
...@@ -139,26 +130,57 @@ static int graph_parse_node(struct simple_util_priv *priv, ...@@ -139,26 +130,57 @@ static int graph_parse_node(struct simple_util_priv *priv,
} }
static int graph_link_init(struct simple_util_priv *priv, static int graph_link_init(struct simple_util_priv *priv,
struct device_node *cpu_ep, struct device_node *ep_cpu,
struct device_node *codec_ep, struct device_node *ep_codec,
struct link_info *li, struct link_info *li,
char *name) char *name)
{ {
struct device *dev = simple_priv_to_dev(priv); struct device *dev = simple_priv_to_dev(priv);
struct device_node *top = dev->of_node;
struct snd_soc_dai_link *dai_link = simple_priv_to_link(priv, li->link); struct snd_soc_dai_link *dai_link = simple_priv_to_link(priv, li->link);
struct simple_dai_props *dai_props = simple_priv_to_props(priv, li->link);
struct device_node *port_cpu = ep_to_port(ep_cpu);
struct device_node *port_codec = ep_to_port(ep_codec);
struct device_node *ports_cpu = port_to_ports(port_cpu);
struct device_node *ports_codec = port_to_ports(port_codec);
bool playback_only = 0, capture_only = 0;
int ret; int ret;
ret = simple_util_parse_daifmt(dev, cpu_ep, codec_ep, ret = simple_util_parse_daifmt(dev, ep_cpu, ep_codec,
NULL, &dai_link->dai_fmt); NULL, &dai_link->dai_fmt);
if (ret < 0) if (ret < 0)
return ret; goto init_end;
graph_util_parse_link_direction(top, &playback_only, &capture_only);
graph_util_parse_link_direction(port_cpu, &playback_only, &capture_only);
graph_util_parse_link_direction(port_codec, &playback_only, &capture_only);
graph_util_parse_link_direction(ep_cpu, &playback_only, &capture_only);
graph_util_parse_link_direction(ep_codec, &playback_only, &capture_only);
of_property_read_u32(top, "mclk-fs", &dai_props->mclk_fs);
of_property_read_u32(ports_cpu, "mclk-fs", &dai_props->mclk_fs);
of_property_read_u32(ports_codec, "mclk-fs", &dai_props->mclk_fs);
of_property_read_u32(port_cpu, "mclk-fs", &dai_props->mclk_fs);
of_property_read_u32(port_codec, "mclk-fs", &dai_props->mclk_fs);
of_property_read_u32(ep_cpu, "mclk-fs", &dai_props->mclk_fs);
of_property_read_u32(ep_codec, "mclk-fs", &dai_props->mclk_fs);
dai_link->playback_only = playback_only;
dai_link->capture_only = capture_only;
dai_link->init = simple_util_dai_init; dai_link->init = simple_util_dai_init;
dai_link->ops = &graph_ops; dai_link->ops = &graph_ops;
if (priv->ops) if (priv->ops)
dai_link->ops = priv->ops; dai_link->ops = priv->ops;
return simple_util_set_dailink_name(dev, dai_link, name); ret = simple_util_set_dailink_name(dev, dai_link, name);
init_end:
of_node_put(ports_cpu);
of_node_put(ports_codec);
of_node_put(port_cpu);
of_node_put(port_codec);
return ret;
} }
static int graph_dai_link_of_dpcm(struct simple_util_priv *priv, static int graph_dai_link_of_dpcm(struct simple_util_priv *priv,
...@@ -231,14 +253,11 @@ static int graph_dai_link_of_dpcm(struct simple_util_priv *priv, ...@@ -231,14 +253,11 @@ static int graph_dai_link_of_dpcm(struct simple_util_priv *priv,
"be.%pOFP.%s", codecs->of_node, codecs->dai_name); "be.%pOFP.%s", codecs->of_node, codecs->dai_name);
/* check "prefix" from top node */ /* check "prefix" from top node */
port = of_get_parent(ep); port = ep_to_port(ep);
ports = of_get_parent(port); ports = port_to_ports(port);
snd_soc_of_parse_node_prefix(top, cconf, codecs->of_node, snd_soc_of_parse_node_prefix(top, cconf, codecs->of_node, "prefix");
"prefix"); snd_soc_of_parse_node_prefix(ports, cconf, codecs->of_node, "prefix");
if (of_node_name_eq(ports, "ports")) snd_soc_of_parse_node_prefix(port, cconf, codecs->of_node, "prefix");
snd_soc_of_parse_node_prefix(ports, cconf, codecs->of_node, "prefix");
snd_soc_of_parse_node_prefix(port, cconf, codecs->of_node,
"prefix");
of_node_put(ports); of_node_put(ports);
of_node_put(port); of_node_put(port);
...@@ -350,7 +369,7 @@ static int __graph_for_each_link(struct simple_util_priv *priv, ...@@ -350,7 +369,7 @@ static int __graph_for_each_link(struct simple_util_priv *priv,
/* get codec */ /* get codec */
codec_ep = of_graph_get_remote_endpoint(cpu_ep); codec_ep = of_graph_get_remote_endpoint(cpu_ep);
codec_port = of_get_parent(codec_ep); codec_port = ep_to_port(codec_ep);
/* get convert-xxx property */ /* get convert-xxx property */
memset(&adata, 0, sizeof(adata)); memset(&adata, 0, sizeof(adata));
......
...@@ -236,6 +236,18 @@ enum graph_type { ...@@ -236,6 +236,18 @@ enum graph_type {
#define port_to_endpoint(port) of_get_child_by_name(port, "endpoint") #define port_to_endpoint(port) of_get_child_by_name(port, "endpoint")
#define ep_to_port(ep) of_get_parent(ep)
static struct device_node *port_to_ports(struct device_node *port)
{
struct device_node *ports = of_get_parent(port);
if (!of_node_name_eq(ports, "ports")) {
of_node_put(ports);
return NULL;
}
return ports;
}
static enum graph_type __graph_get_type(struct device_node *lnk) static enum graph_type __graph_get_type(struct device_node *lnk)
{ {
struct device_node *np, *parent_np; struct device_node *np, *parent_np;
...@@ -320,7 +332,7 @@ static int graph_lnk_is_multi(struct device_node *lnk) ...@@ -320,7 +332,7 @@ static int graph_lnk_is_multi(struct device_node *lnk)
static struct device_node *graph_get_next_multi_ep(struct device_node **port) static struct device_node *graph_get_next_multi_ep(struct device_node **port)
{ {
struct device_node *ports = of_get_parent(*port); struct device_node *ports = port_to_ports(*port);
struct device_node *ep = NULL; struct device_node *ep = NULL;
struct device_node *rep = NULL; struct device_node *rep = NULL;
...@@ -365,12 +377,11 @@ static const struct snd_soc_ops graph_ops = { ...@@ -365,12 +377,11 @@ static const struct snd_soc_ops graph_ops = {
static void graph_parse_convert(struct device_node *ep, static void graph_parse_convert(struct device_node *ep,
struct simple_dai_props *props) struct simple_dai_props *props)
{ {
struct device_node *port = of_get_parent(ep); struct device_node *port = ep_to_port(ep);
struct device_node *ports = of_get_parent(port); struct device_node *ports = port_to_ports(port);
struct simple_util_data *adata = &props->adata; struct simple_util_data *adata = &props->adata;
if (of_node_name_eq(ports, "ports")) simple_util_parse_convert(ports, NULL, adata);
simple_util_parse_convert(ports, NULL, adata);
simple_util_parse_convert(port, NULL, adata); simple_util_parse_convert(port, NULL, adata);
simple_util_parse_convert(ep, NULL, adata); simple_util_parse_convert(ep, NULL, adata);
...@@ -378,21 +389,6 @@ static void graph_parse_convert(struct device_node *ep, ...@@ -378,21 +389,6 @@ static void graph_parse_convert(struct device_node *ep,
of_node_put(ports); of_node_put(ports);
} }
static void graph_parse_mclk_fs(struct device_node *ep,
struct simple_dai_props *props)
{
struct device_node *port = of_get_parent(ep);
struct device_node *ports = of_get_parent(port);
if (of_node_name_eq(ports, "ports"))
of_property_read_u32(ports, "mclk-fs", &props->mclk_fs);
of_property_read_u32(port, "mclk-fs", &props->mclk_fs);
of_property_read_u32(ep, "mclk-fs", &props->mclk_fs);
of_node_put(port);
of_node_put(ports);
}
static int __graph_parse_node(struct simple_util_priv *priv, static int __graph_parse_node(struct simple_util_priv *priv,
enum graph_type gtype, enum graph_type gtype,
struct device_node *ep, struct device_node *ep,
...@@ -414,8 +410,6 @@ static int __graph_parse_node(struct simple_util_priv *priv, ...@@ -414,8 +410,6 @@ static int __graph_parse_node(struct simple_util_priv *priv,
dai = simple_props_to_dai_codec(dai_props, idx); dai = simple_props_to_dai_codec(dai_props, idx);
} }
graph_parse_mclk_fs(ep, dai_props);
ret = graph_util_parse_dai(dev, ep, dlc, &is_single_links); ret = graph_util_parse_dai(dev, ep, dlc, &is_single_links);
if (ret < 0) if (ret < 0)
return ret; return ret;
...@@ -481,11 +475,10 @@ static int __graph_parse_node(struct simple_util_priv *priv, ...@@ -481,11 +475,10 @@ static int __graph_parse_node(struct simple_util_priv *priv,
if (!is_cpu && gtype == GRAPH_DPCM) { if (!is_cpu && gtype == GRAPH_DPCM) {
struct snd_soc_dai_link_component *codecs = snd_soc_link_to_codec(dai_link, idx); struct snd_soc_dai_link_component *codecs = snd_soc_link_to_codec(dai_link, idx);
struct snd_soc_codec_conf *cconf = simple_props_to_codec_conf(dai_props, idx); struct snd_soc_codec_conf *cconf = simple_props_to_codec_conf(dai_props, idx);
struct device_node *rport = of_get_parent(ep); struct device_node *rport = ep_to_port(ep);
struct device_node *rports = of_get_parent(rport); struct device_node *rports = port_to_ports(rport);
if (of_node_name_eq(rports, "ports")) snd_soc_of_parse_node_prefix(rports, cconf, codecs->of_node, "prefix");
snd_soc_of_parse_node_prefix(rports, cconf, codecs->of_node, "prefix");
snd_soc_of_parse_node_prefix(rport, cconf, codecs->of_node, "prefix"); snd_soc_of_parse_node_prefix(rport, cconf, codecs->of_node, "prefix");
of_node_put(rport); of_node_put(rport);
...@@ -539,11 +532,11 @@ static int graph_parse_node_multi_nm(struct snd_soc_dai_link *dai_link, ...@@ -539,11 +532,11 @@ static int graph_parse_node_multi_nm(struct snd_soc_dai_link *dai_link,
*/ */
struct device_node *mcpu_ep = port_to_endpoint(mcpu_port); struct device_node *mcpu_ep = port_to_endpoint(mcpu_port);
struct device_node *mcpu_ep_n = mcpu_ep; struct device_node *mcpu_ep_n = mcpu_ep;
struct device_node *mcpu_port_top = of_get_next_child(of_get_parent(mcpu_port), NULL); struct device_node *mcpu_port_top = of_get_next_child(port_to_ports(mcpu_port), NULL);
struct device_node *mcpu_ep_top = port_to_endpoint(mcpu_port_top); struct device_node *mcpu_ep_top = port_to_endpoint(mcpu_port_top);
struct device_node *mcodec_ep_top = of_graph_get_remote_endpoint(mcpu_ep_top); struct device_node *mcodec_ep_top = of_graph_get_remote_endpoint(mcpu_ep_top);
struct device_node *mcodec_port_top = of_get_parent(mcodec_ep_top); struct device_node *mcodec_port_top = ep_to_port(mcodec_ep_top);
struct device_node *mcodec_ports = of_get_parent(mcodec_port_top); struct device_node *mcodec_ports = port_to_ports(mcodec_port_top);
int nm_max = max(dai_link->num_cpus, dai_link->num_codecs); int nm_max = max(dai_link->num_cpus, dai_link->num_codecs);
int ret = -EINVAL; int ret = -EINVAL;
...@@ -566,9 +559,9 @@ static int graph_parse_node_multi_nm(struct snd_soc_dai_link *dai_link, ...@@ -566,9 +559,9 @@ static int graph_parse_node_multi_nm(struct snd_soc_dai_link *dai_link,
} }
mcodec_ep_n = of_graph_get_remote_endpoint(mcpu_ep_n); mcodec_ep_n = of_graph_get_remote_endpoint(mcpu_ep_n);
mcodec_port = of_get_parent(mcodec_ep_n); mcodec_port = ep_to_port(mcodec_ep_n);
if (mcodec_ports != of_get_parent(mcodec_port)) if (mcodec_ports != port_to_ports(mcodec_port))
goto mcpu_err; goto mcpu_err;
codec_idx = 0; codec_idx = 0;
...@@ -705,6 +698,9 @@ static void graph_parse_daifmt(struct device_node *node, ...@@ -705,6 +698,9 @@ static void graph_parse_daifmt(struct device_node *node,
{ {
unsigned int fmt; unsigned int fmt;
if (!node)
return;
/* /*
* see also above "daifmt" explanation * see also above "daifmt" explanation
* and samples. * and samples.
...@@ -751,43 +747,64 @@ static void graph_parse_daifmt(struct device_node *node, ...@@ -751,43 +747,64 @@ static void graph_parse_daifmt(struct device_node *node,
} }
static void graph_link_init(struct simple_util_priv *priv, static void graph_link_init(struct simple_util_priv *priv,
struct device_node *port, struct device_node *lnk,
struct device_node *port_cpu,
struct device_node *port_codec,
struct link_info *li, struct link_info *li,
int is_cpu_node) int is_cpu_node)
{ {
struct snd_soc_dai_link *dai_link = simple_priv_to_link(priv, li->link); struct snd_soc_dai_link *dai_link = simple_priv_to_link(priv, li->link);
struct device_node *ep; struct simple_dai_props *dai_props = simple_priv_to_props(priv, li->link);
struct device_node *ports; struct device_node *ep_cpu, *ep_codec;
struct device_node *ports_cpu, *ports_codec;
unsigned int daifmt = 0, daiclk = 0; unsigned int daifmt = 0, daiclk = 0;
bool playback_only = 0, capture_only = 0; bool playback_only = 0, capture_only = 0;
unsigned int bit_frame = 0; unsigned int bit_frame = 0;
if (graph_lnk_is_multi(port)) { of_node_get(port_cpu);
of_node_get(port); if (graph_lnk_is_multi(port_cpu)) {
ep = graph_get_next_multi_ep(&port); ep_cpu = graph_get_next_multi_ep(&port_cpu);
port = of_get_parent(ep); of_node_put(port_cpu);
port_cpu = ep_to_port(ep_cpu);
} else { } else {
ep = port_to_endpoint(port); ep_cpu = port_to_endpoint(port_cpu);
} }
ports_cpu = port_to_ports(port_cpu);
ports = of_get_parent(port); of_node_get(port_codec);
if (graph_lnk_is_multi(port_codec)) {
/* ep_codec = graph_get_next_multi_ep(&port_codec);
* ports { of_node_put(port_cpu);
* (A) port_codec = ep_to_port(ep_codec);
* port { } else {
* (B) ep_codec = port_to_endpoint(port_codec);
* endpoint { }
* (C) ports_codec = port_to_ports(port_codec);
* };
* };
* }; graph_parse_daifmt(ep_cpu, &daifmt, &bit_frame);
* }; graph_parse_daifmt(ep_codec, &daifmt, &bit_frame);
*/ graph_parse_daifmt(port_cpu, &daifmt, &bit_frame);
graph_parse_daifmt(ep, &daifmt, &bit_frame); /* (C) */ graph_parse_daifmt(port_codec, &daifmt, &bit_frame);
graph_parse_daifmt(port, &daifmt, &bit_frame); /* (B) */ graph_parse_daifmt(ports_cpu, &daifmt, &bit_frame);
if (of_node_name_eq(ports, "ports")) graph_parse_daifmt(ports_codec, &daifmt, &bit_frame);
graph_parse_daifmt(ports, &daifmt, &bit_frame); /* (A) */ graph_parse_daifmt(lnk, &daifmt, &bit_frame);
graph_util_parse_link_direction(lnk, &playback_only, &capture_only);
graph_util_parse_link_direction(ports_cpu, &playback_only, &capture_only);
graph_util_parse_link_direction(ports_codec, &playback_only, &capture_only);
graph_util_parse_link_direction(port_cpu, &playback_only, &capture_only);
graph_util_parse_link_direction(port_codec, &playback_only, &capture_only);
graph_util_parse_link_direction(ep_cpu, &playback_only, &capture_only);
graph_util_parse_link_direction(ep_codec, &playback_only, &capture_only);
of_property_read_u32(lnk, "mclk-fs", &dai_props->mclk_fs);
of_property_read_u32(ports_cpu, "mclk-fs", &dai_props->mclk_fs);
of_property_read_u32(ports_codec, "mclk-fs", &dai_props->mclk_fs);
of_property_read_u32(port_cpu, "mclk-fs", &dai_props->mclk_fs);
of_property_read_u32(port_codec, "mclk-fs", &dai_props->mclk_fs);
of_property_read_u32(ep_cpu, "mclk-fs", &dai_props->mclk_fs);
of_property_read_u32(ep_codec, "mclk-fs", &dai_props->mclk_fs);
/* /*
* convert bit_frame * convert bit_frame
...@@ -798,16 +815,21 @@ static void graph_link_init(struct simple_util_priv *priv, ...@@ -798,16 +815,21 @@ static void graph_link_init(struct simple_util_priv *priv,
if (is_cpu_node) if (is_cpu_node)
daiclk = snd_soc_daifmt_clock_provider_flipped(daiclk); daiclk = snd_soc_daifmt_clock_provider_flipped(daiclk);
graph_util_parse_link_direction(port, &playback_only, &capture_only); dai_link->playback_only = playback_only;
dai_link->capture_only = capture_only;
dai_link->playback_only = playback_only;
dai_link->capture_only = capture_only;
dai_link->dai_fmt = daifmt | daiclk; dai_link->dai_fmt = daifmt | daiclk;
dai_link->init = simple_util_dai_init; dai_link->init = simple_util_dai_init;
dai_link->ops = &graph_ops; dai_link->ops = &graph_ops;
if (priv->ops) if (priv->ops)
dai_link->ops = priv->ops; dai_link->ops = priv->ops;
of_node_put(ports_cpu);
of_node_put(ports_codec);
of_node_put(port_cpu);
of_node_put(port_codec);
of_node_put(ep_cpu);
of_node_put(ep_codec);
} }
int audio_graph2_link_normal(struct simple_util_priv *priv, int audio_graph2_link_normal(struct simple_util_priv *priv,
...@@ -835,7 +857,7 @@ int audio_graph2_link_normal(struct simple_util_priv *priv, ...@@ -835,7 +857,7 @@ int audio_graph2_link_normal(struct simple_util_priv *priv,
if (ret < 0) if (ret < 0)
goto err; goto err;
graph_link_init(priv, cpu_port, li, 1); graph_link_init(priv, lnk, cpu_port, codec_port, li, 1);
err: err:
of_node_put(codec_port); of_node_put(codec_port);
of_node_put(cpu_ep); of_node_put(cpu_ep);
...@@ -850,13 +872,16 @@ int audio_graph2_link_dpcm(struct simple_util_priv *priv, ...@@ -850,13 +872,16 @@ int audio_graph2_link_dpcm(struct simple_util_priv *priv,
{ {
struct device_node *ep = port_to_endpoint(lnk); struct device_node *ep = port_to_endpoint(lnk);
struct device_node *rep = of_graph_get_remote_endpoint(ep); struct device_node *rep = of_graph_get_remote_endpoint(ep);
struct device_node *rport = of_graph_get_remote_port(ep); struct device_node *cpu_port = NULL;
struct device_node *codec_port = NULL;
struct snd_soc_dai_link *dai_link = simple_priv_to_link(priv, li->link); struct snd_soc_dai_link *dai_link = simple_priv_to_link(priv, li->link);
struct simple_dai_props *dai_props = simple_priv_to_props(priv, li->link); struct simple_dai_props *dai_props = simple_priv_to_props(priv, li->link);
int is_cpu = graph_util_is_ports0(lnk); int is_cpu = graph_util_is_ports0(lnk);
int ret; int ret;
if (is_cpu) { if (is_cpu) {
cpu_port = of_graph_get_remote_port(ep); /* rport */
/* /*
* dpcm { * dpcm {
* // Front-End * // Front-End
...@@ -884,10 +909,13 @@ int audio_graph2_link_dpcm(struct simple_util_priv *priv, ...@@ -884,10 +909,13 @@ int audio_graph2_link_dpcm(struct simple_util_priv *priv,
dai_link->dynamic = 1; dai_link->dynamic = 1;
dai_link->dpcm_merged_format = 1; dai_link->dpcm_merged_format = 1;
ret = graph_parse_node(priv, GRAPH_DPCM, rport, li, 1); ret = graph_parse_node(priv, GRAPH_DPCM, cpu_port, li, 1);
if (ret) if (ret)
goto err; goto err;
} else { } else {
codec_port = of_graph_get_remote_port(ep); /* rport */
/* /*
* dpcm { * dpcm {
* // Front-End * // Front-End
...@@ -917,7 +945,7 @@ int audio_graph2_link_dpcm(struct simple_util_priv *priv, ...@@ -917,7 +945,7 @@ int audio_graph2_link_dpcm(struct simple_util_priv *priv,
dai_link->no_pcm = 1; dai_link->no_pcm = 1;
dai_link->be_hw_params_fixup = simple_util_be_hw_params_fixup; dai_link->be_hw_params_fixup = simple_util_be_hw_params_fixup;
ret = graph_parse_node(priv, GRAPH_DPCM, rport, li, 0); ret = graph_parse_node(priv, GRAPH_DPCM, codec_port, li, 0);
if (ret < 0) if (ret < 0)
goto err; goto err;
} }
...@@ -927,11 +955,12 @@ int audio_graph2_link_dpcm(struct simple_util_priv *priv, ...@@ -927,11 +955,12 @@ int audio_graph2_link_dpcm(struct simple_util_priv *priv,
snd_soc_dai_link_set_capabilities(dai_link); snd_soc_dai_link_set_capabilities(dai_link);
graph_link_init(priv, rport, li, is_cpu); graph_link_init(priv, lnk, cpu_port, codec_port, li, is_cpu);
err: err:
of_node_put(ep); of_node_put(ep);
of_node_put(rep); of_node_put(rep);
of_node_put(rport); of_node_put(cpu_port);
of_node_put(codec_port);
return ret; return ret;
} }
...@@ -966,7 +995,7 @@ int audio_graph2_link_c2c(struct simple_util_priv *priv, ...@@ -966,7 +995,7 @@ int audio_graph2_link_c2c(struct simple_util_priv *priv,
*/ */
of_node_get(lnk); of_node_get(lnk);
port0 = lnk; port0 = lnk;
ports = of_get_parent(port0); ports = port_to_ports(port0);
port1 = of_get_next_child(ports, lnk); port1 = of_get_next_child(ports, lnk);
/* /*
...@@ -1019,7 +1048,7 @@ int audio_graph2_link_c2c(struct simple_util_priv *priv, ...@@ -1019,7 +1048,7 @@ int audio_graph2_link_c2c(struct simple_util_priv *priv,
if (ret < 0) if (ret < 0)
goto err2; goto err2;
graph_link_init(priv, codec0_port, li, 1); graph_link_init(priv, lnk, codec0_port, codec1_port, li, 1);
err2: err2:
of_node_put(ep0); of_node_put(ep0);
of_node_put(ep1); of_node_put(ep1);
...@@ -1098,7 +1127,7 @@ static int graph_counter(struct device_node *lnk) ...@@ -1098,7 +1127,7 @@ static int graph_counter(struct device_node *lnk)
* ignore first lnk part * ignore first lnk part
*/ */
if (graph_lnk_is_multi(lnk)) { if (graph_lnk_is_multi(lnk)) {
struct device_node *ports = of_get_parent(lnk); struct device_node *ports = port_to_ports(lnk);
struct device_node *port = NULL; struct device_node *port = NULL;
int cnt = 0; int cnt = 0;
...@@ -1195,7 +1224,7 @@ static int graph_count_c2c(struct simple_util_priv *priv, ...@@ -1195,7 +1224,7 @@ static int graph_count_c2c(struct simple_util_priv *priv,
struct device_node *lnk, struct device_node *lnk,
struct link_info *li) struct link_info *li)
{ {
struct device_node *ports = of_get_parent(lnk); struct device_node *ports = port_to_ports(lnk);
struct device_node *port0 = lnk; struct device_node *port0 = lnk;
struct device_node *port1 = of_get_next_child(ports, of_node_get(lnk)); struct device_node *port1 = of_get_next_child(ports, of_node_get(lnk));
struct device_node *ep0 = port_to_endpoint(port0); struct device_node *ep0 = port_to_endpoint(port0);
......
...@@ -60,6 +60,9 @@ void simple_util_parse_convert(struct device_node *np, ...@@ -60,6 +60,9 @@ void simple_util_parse_convert(struct device_node *np,
{ {
char prop[128]; char prop[128];
if (!np)
return;
if (!prefix) if (!prefix)
prefix = ""; prefix = "";
...@@ -1140,22 +1143,16 @@ int graph_util_parse_dai(struct device *dev, struct device_node *ep, ...@@ -1140,22 +1143,16 @@ int graph_util_parse_dai(struct device *dev, struct device_node *ep,
} }
EXPORT_SYMBOL_GPL(graph_util_parse_dai); EXPORT_SYMBOL_GPL(graph_util_parse_dai);
int graph_util_parse_link_direction(struct device_node *np, void graph_util_parse_link_direction(struct device_node *np,
bool *playback_only, bool *capture_only) bool *playback_only, bool *capture_only)
{ {
bool is_playback_only = false; bool is_playback_only = of_property_read_bool(np, "playback-only");
bool is_capture_only = false; bool is_capture_only = of_property_read_bool(np, "capture-only");
is_playback_only = of_property_read_bool(np, "playback-only");
is_capture_only = of_property_read_bool(np, "capture-only");
if (is_playback_only && is_capture_only)
return -EINVAL;
*playback_only = is_playback_only;
*capture_only = is_capture_only;
return 0; if (is_playback_only)
*playback_only = is_playback_only;
if (is_capture_only)
*capture_only = is_capture_only;
} }
EXPORT_SYMBOL_GPL(graph_util_parse_link_direction); EXPORT_SYMBOL_GPL(graph_util_parse_link_direction);
......
...@@ -129,24 +129,6 @@ static void simple_parse_convert(struct device *dev, ...@@ -129,24 +129,6 @@ static void simple_parse_convert(struct device *dev,
of_node_put(node); of_node_put(node);
} }
static void simple_parse_mclk_fs(struct device_node *top,
struct device_node *np,
struct simple_dai_props *props,
char *prefix)
{
struct device_node *node = of_get_parent(np);
char prop[128];
snprintf(prop, sizeof(prop), "%smclk-fs", PREFIX);
of_property_read_u32(top, prop, &props->mclk_fs);
snprintf(prop, sizeof(prop), "%smclk-fs", prefix);
of_property_read_u32(node, prop, &props->mclk_fs);
of_property_read_u32(np, prop, &props->mclk_fs);
of_node_put(node);
}
static int simple_parse_node(struct simple_util_priv *priv, static int simple_parse_node(struct simple_util_priv *priv,
struct device_node *np, struct device_node *np,
struct link_info *li, struct link_info *li,
...@@ -154,7 +136,6 @@ static int simple_parse_node(struct simple_util_priv *priv, ...@@ -154,7 +136,6 @@ static int simple_parse_node(struct simple_util_priv *priv,
int *cpu) int *cpu)
{ {
struct device *dev = simple_priv_to_dev(priv); struct device *dev = simple_priv_to_dev(priv);
struct device_node *top = dev->of_node;
struct snd_soc_dai_link *dai_link = simple_priv_to_link(priv, li->link); struct snd_soc_dai_link *dai_link = simple_priv_to_link(priv, li->link);
struct simple_dai_props *dai_props = simple_priv_to_props(priv, li->link); struct simple_dai_props *dai_props = simple_priv_to_props(priv, li->link);
struct snd_soc_dai_link_component *dlc; struct snd_soc_dai_link_component *dlc;
...@@ -169,8 +150,6 @@ static int simple_parse_node(struct simple_util_priv *priv, ...@@ -169,8 +150,6 @@ static int simple_parse_node(struct simple_util_priv *priv,
dai = simple_props_to_dai_codec(dai_props, 0); dai = simple_props_to_dai_codec(dai_props, 0);
} }
simple_parse_mclk_fs(top, np, dai_props, prefix);
ret = simple_parse_dai(dev, np, dlc, cpu); ret = simple_parse_dai(dev, np, dlc, cpu);
if (ret) if (ret)
return ret; return ret;
...@@ -187,24 +166,49 @@ static int simple_parse_node(struct simple_util_priv *priv, ...@@ -187,24 +166,49 @@ static int simple_parse_node(struct simple_util_priv *priv,
} }
static int simple_link_init(struct simple_util_priv *priv, static int simple_link_init(struct simple_util_priv *priv,
struct device_node *node, struct device_node *cpu,
struct device_node *codec, struct device_node *codec,
struct link_info *li, struct link_info *li,
char *prefix, char *name) char *prefix, char *name)
{ {
struct device *dev = simple_priv_to_dev(priv); struct device *dev = simple_priv_to_dev(priv);
struct device_node *top = dev->of_node;
struct snd_soc_dai_link *dai_link = simple_priv_to_link(priv, li->link); struct snd_soc_dai_link *dai_link = simple_priv_to_link(priv, li->link);
struct simple_dai_props *dai_props = simple_priv_to_props(priv, li->link);
struct device_node *node = of_get_parent(cpu);
bool playback_only = 0, capture_only = 0;
int ret; int ret;
ret = simple_util_parse_daifmt(dev, node, codec, ret = simple_util_parse_daifmt(dev, node, codec,
prefix, &dai_link->dai_fmt); prefix, &dai_link->dai_fmt);
if (ret < 0) if (ret < 0)
return 0; goto init_end;
graph_util_parse_link_direction(top, &playback_only, &capture_only);
graph_util_parse_link_direction(node, &playback_only, &capture_only);
graph_util_parse_link_direction(cpu, &playback_only, &capture_only);
graph_util_parse_link_direction(codec, &playback_only, &capture_only);
of_property_read_u32(top, "mclk-fs", &dai_props->mclk_fs);
of_property_read_u32(top, PREFIX "mclk-fs", &dai_props->mclk_fs);
of_property_read_u32(node, "mclk-fs", &dai_props->mclk_fs);
of_property_read_u32(node, PREFIX "mclk-fs", &dai_props->mclk_fs);
of_property_read_u32(cpu, "mclk-fs", &dai_props->mclk_fs);
of_property_read_u32(cpu, PREFIX "mclk-fs", &dai_props->mclk_fs);
of_property_read_u32(codec, "mclk-fs", &dai_props->mclk_fs);
of_property_read_u32(codec, PREFIX "mclk-fs", &dai_props->mclk_fs);
dai_link->playback_only = playback_only;
dai_link->capture_only = capture_only;
dai_link->init = simple_util_dai_init; dai_link->init = simple_util_dai_init;
dai_link->ops = &simple_ops; dai_link->ops = &simple_ops;
return simple_util_set_dailink_name(dev, dai_link, name); ret = simple_util_set_dailink_name(dev, dai_link, name);
init_end:
of_node_put(node);
return ret;
} }
static int simple_dai_link_of_dpcm(struct simple_util_priv *priv, static int simple_dai_link_of_dpcm(struct simple_util_priv *priv,
...@@ -278,7 +282,7 @@ static int simple_dai_link_of_dpcm(struct simple_util_priv *priv, ...@@ -278,7 +282,7 @@ static int simple_dai_link_of_dpcm(struct simple_util_priv *priv,
snd_soc_dai_link_set_capabilities(dai_link); snd_soc_dai_link_set_capabilities(dai_link);
ret = simple_link_init(priv, node, codec, li, prefix, dai_name); ret = simple_link_init(priv, np, codec, li, prefix, dai_name);
out_put_node: out_put_node:
li->link++; li->link++;
...@@ -336,7 +340,7 @@ static int simple_dai_link_of(struct simple_util_priv *priv, ...@@ -336,7 +340,7 @@ static int simple_dai_link_of(struct simple_util_priv *priv,
simple_util_canonicalize_cpu(cpus, single_cpu); simple_util_canonicalize_cpu(cpus, single_cpu);
simple_util_canonicalize_platform(platforms, cpus); simple_util_canonicalize_platform(platforms, cpus);
ret = simple_link_init(priv, node, codec, li, prefix, dai_name); ret = simple_link_init(priv, cpu, codec, li, prefix, dai_name);
dai_link_of_err: dai_link_of_err:
of_node_put(plat); of_node_put(plat);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment