asoc_simple_card_parse_convert(dev, ep, NULL, adata);
}
-static int asoc_graph_card_dai_link_of_dpcm(struct device_node *top,
+static int asoc_graph_card_dai_link_of_dpcm(struct graph_card_data *priv,
struct device_node *cpu_ep,
struct device_node *codec_ep,
- struct graph_card_data *priv,
- struct link_info *li)
+ struct link_info *li,
+ int dup_codec)
{
struct device *dev = graph_priv_to_dev(priv);
struct snd_soc_dai_link *dai_link = graph_priv_to_link(priv, li->link);
struct graph_dai_props *dai_props = graph_priv_to_props(priv, li->link);
+ struct device_node *top = dev->of_node;
struct device_node *ep = li->cpu ? cpu_ep : codec_ep;
- struct device_node *port = of_get_parent(ep);
- struct device_node *ports = of_get_parent(port);
- struct device_node *node = of_graph_get_port_parent(ep);
+ struct device_node *port;
+ struct device_node *ports;
+ struct device_node *node;
struct asoc_simple_dai *dai;
struct snd_soc_dai_link_component *codecs = dai_link->codecs;
int ret;
+ /* Do it all CPU endpoint, and 1st Codec endpoint */
+ if (!li->cpu && dup_codec)
+ return 0;
+
+ port = of_get_parent(ep);
+ ports = of_get_parent(port);
+ node = of_graph_get_port_parent(ep);
+
li->link++;
dev_dbg(dev, "link_of DPCM (%pOF)\n", ep);
of_node_put(ports);
of_node_put(port);
+ of_node_put(node);
if (li->cpu) {
return 0;
}
-static int asoc_graph_card_dai_link_of(struct device_node *top,
+static int asoc_graph_card_dai_link_of(struct graph_card_data *priv,
struct device_node *cpu_ep,
struct device_node *codec_ep,
- struct graph_card_data *priv,
struct link_info *li)
{
struct device *dev = graph_priv_to_dev(priv);
struct snd_soc_dai_link *dai_link = graph_priv_to_link(priv, li->link);
struct graph_dai_props *dai_props = graph_priv_to_props(priv, li->link);
- struct device_node *cpu_port = of_get_parent(cpu_ep);
- struct device_node *codec_port = of_get_parent(codec_ep);
- struct device_node *cpu_ports = of_get_parent(cpu_port);
- struct device_node *codec_ports = of_get_parent(codec_port);
+ struct device_node *top = dev->of_node;
+ struct device_node *cpu_port;
+ struct device_node *codec_port;
+ struct device_node *cpu_ports;
+ struct device_node *codec_ports;
struct asoc_simple_dai *cpu_dai;
struct asoc_simple_dai *codec_dai;
int ret;
+ /* Do it only CPU turn */
+ if (!li->cpu)
+ return 0;
+
+ cpu_port = of_get_parent(cpu_ep);
+ cpu_ports = of_get_parent(cpu_port);
+ codec_port = of_get_parent(codec_ep);
+ codec_ports = of_get_parent(codec_port);
+
dev_dbg(dev, "link_of (%pOF)\n", cpu_ep);
li->link++;
/*
* for DPCM sound
*/
- if (!li.cpu) {
- if (codec_port_old == codec_port)
- continue;
- codec_port_old = codec_port;
- }
ret = asoc_graph_card_dai_link_of_dpcm(
- top, cpu_ep, codec_ep, priv, &li);
+ priv, cpu_ep, codec_ep, &li,
+ (codec_port_old == codec_port));
} else if (li.cpu) {
/*
* for Normal sound
*/
ret = asoc_graph_card_dai_link_of(
- top, cpu_ep, codec_ep, priv, &li);
+ priv, cpu_ep, codec_ep, &li);
}
if (ret < 0)
return ret;
+ codec_port_old = codec_port;
}
}
}
return asoc_simple_card_parse_card_name(card, NULL);
}
-static void asoc_graph_get_dais_count(struct device *dev,
+static int asoc_graph_card_count_noml(struct graph_card_data *priv,
+ struct device_node *cpu_ep,
+ struct device_node *codec_ep,
struct link_info *li)
{
+ struct device *dev = graph_priv_to_dev(priv);
+
+ li->link += 1; /* 1xCPU-Codec */
+ li->dais += 2; /* 1xCPU + 1xCodec */
+
+ dev_dbg(dev, "Count As Normal\n");
+
+ return 0;
+}
+
+static int asoc_graph_card_count_dpcm(struct graph_card_data *priv,
+ struct device_node *cpu_ep,
+ struct device_node *codec_ep,
+ struct link_info *li,
+ int dup_codec)
+{
+ struct device *dev = graph_priv_to_dev(priv);
+
+ li->link++; /* 1xCPU-dummy */
+ li->dais++; /* 1xCPU */
+
+ if (!dup_codec) {
+ li->link++; /* 1xdummy-Codec */
+ li->conf++; /* 1xdummy-Codec */
+ li->dais++; /* 1xCodec */
+ }
+
+ dev_dbg(dev, "Count As DPCM\n");
+
+ return 0;
+}
+
+static void asoc_graph_get_dais_count(struct graph_card_data *priv,
+ struct link_info *li)
+{
+ struct device *dev = graph_priv_to_dev(priv);
struct of_phandle_iterator it;
struct device_node *node = dev->of_node;
struct device_node *cpu_port;
of_node_put(codec_ep);
of_node_put(codec_port);
- li->link++;
- li->dais++;
-
memset(&adata, 0, sizeof(adata));
asoc_graph_card_get_conversion(dev, codec_ep, &adata);
asoc_graph_card_get_conversion(dev, cpu_ep, &adata);
if ((of_get_child_count(codec_port) > 1) ||
adata.convert_rate || adata.convert_channels) {
-
- if (codec_port_old == codec_port)
- continue;
-
- li->link++;
- li->conf++;
- li->dais++;
+ asoc_graph_card_count_dpcm(priv,
+ cpu_ep, codec_ep, li,
+ (codec_port_old == codec_port));
} else {
- li->dais++;
+ asoc_graph_card_count_noml(priv,
+ cpu_ep, codec_ep, li);
}
codec_port_old = codec_port;
}
if (!priv)
return -ENOMEM;
+ card = graph_priv_to_card(priv);
+ card->owner = THIS_MODULE;
+ card->dev = dev;
+ card->dapm_widgets = asoc_graph_card_dapm_widgets;
+ card->num_dapm_widgets = ARRAY_SIZE(asoc_graph_card_dapm_widgets);
+ card->probe = asoc_graph_soc_card_probe;
+
memset(&li, 0, sizeof(li));
- asoc_graph_get_dais_count(dev, &li);
+ asoc_graph_get_dais_count(priv, &li);
if (!li.link || !li.dais)
return -EINVAL;
return ret;
}
- priv->dai_props = dai_props;
- priv->dai_link = dai_link;
- priv->dais = dais;
- priv->codec_conf = cconf;
+ priv->dai_props = dai_props;
+ priv->dai_link = dai_link;
+ priv->dais = dais;
+ priv->codec_conf = cconf;
- /* Init snd_soc_card */
- card = graph_priv_to_card(priv);
- card->owner = THIS_MODULE;
- card->dev = dev;
card->dai_link = dai_link;
card->num_links = li.link;
- card->dapm_widgets = asoc_graph_card_dapm_widgets;
- card->num_dapm_widgets = ARRAY_SIZE(asoc_graph_card_dapm_widgets);
- card->probe = asoc_graph_soc_card_probe;
card->codec_conf = cconf;
card->num_configs = li.conf;