Skip to content
Permalink
Browse files
card2
Signed-off-by: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
  • Loading branch information
morimoto committed Jan 19, 2021
1 parent e60d139 commit 9dcb567a2d18cdc9984d16da266b963f5a8e045b
Show file tree
Hide file tree
Showing 2 changed files with 88 additions and 62 deletions.
@@ -176,20 +176,22 @@
compatible = "audio-graph-card2-dsp";
ports@0 {
format = "dsp_a";
bitclock-master;
frame-master;
mix_fe0: port@0 { mix_fe0_ep: endpoint { remote-endpoint = <&cpu2_ep>; }; };
mix_fe1: port@1 { mix_fe1_ep: endpoint { remote-endpoint = <&cpu3_ep>; }; };
};
ports@1 {
format = "dsp_a";
bitclock-master;
frame-master;
format = "dsp_b";
mix_be0: port { mix_be0_ep: endpoint { remote-endpoint = <&codec2_ep>; }; };
};
};

test_cpu {
compatible = "test-cpu";
ports {
bitclock-master;
frame-master;
cpu0: port@0 { cpu0_ep: endpoint { remote-endpoint = <&codec0_ep>; }; };
cpu1: port@1 { cpu1_ep: endpoint { remote-endpoint = <&codec1_ep>; }; };
cpu2: port@2 { cpu2_ep: endpoint { remote-endpoint = <&mix_fe0_ep>; }; };
@@ -21,6 +21,34 @@
#include <sound/graph_card.h>

/************************************
daifmt
************************************
ports {
format = "left_j";
port@0 {
bitclock-master;
sample0: endpoint@0 {
frame-master;
};
sample1: endpoint@1 {
format = "i2s";
};
};
...
};
You can set daifmt at ports/port/endpoint.
It uses *latest* format, and *share* master settings.
In above case,
sample0: left_j, bitclock-master, frame-master
sample1: i2s, bitclock-master
If there was no settings, *Codec* will be
bitclock/frame master as default.
see
graph_parse_daifmt().
************************************
Normal Audio-Graph
************************************
@@ -298,49 +326,6 @@ static void graph_parse_mclk_fs(struct device_node *ep,
of_node_put(ports);
}

static void graph_daifmt_update(struct snd_soc_dai_link *dai_link,
unsigned int fmt)
{
unsigned int mask = 0;

if (fmt & SND_SOC_DAIFMT_FORMAT_MASK)
mask |= SND_SOC_DAIFMT_FORMAT_MASK;
if (fmt & SND_SOC_DAIFMT_CLOCK_MASK)
mask |= SND_SOC_DAIFMT_CLOCK_MASK;
if (fmt & SND_SOC_DAIFMT_INV_MASK)
mask |= SND_SOC_DAIFMT_INV_MASK;
if (fmt & SND_SOC_DAIFMT_MASTER_MASK)
mask |= SND_SOC_DAIFMT_MASTER_MASK;

/* overwrite */
dai_link->dai_fmt = (dai_link->dai_fmt & ~mask) | fmt;
}

static void graph_parse_daifmt(struct device_node *ep,
struct snd_soc_dai_link *dai_link)
{
unsigned int fmt;
struct device_node *port = of_get_parent(ep);
struct device_node *ports = of_get_parent(port);

* bitclock-master はあるけど、 bitclock-slave 等がないので、
* 無設定だと CBP_CFP になってしまう
* overwrite する仕様だとすると
* bitclock-master を ports に書いていても、endpoint のデフォルトで
* 上書きされてしまう

if (of_node_name_eq(ports, "ports"))
fmt = snd_soc_of_parse_daifmt(ports, NULL, NULL, NULL);

__graph_parse_daifmt(ports, dai_link);

__graph_parse_daifmt(port, dai_link);
__graph_parse_daifmt(ep, dai_link);

of_node_put(port);
of_node_put(ports);
}

static int graph_dai_init(struct snd_soc_pcm_runtime *rtd)
{
struct snd_soc_dai *dai;
@@ -402,26 +387,69 @@ static int graph_parse_node(struct asoc_simple_priv *priv,
return 0;
}

static void graph_parse_daifmt(struct device_node *node,
unsigned int *daifmt, unsigned int *bit_frame)
{
unsigned fmt;

/* master: use "or" */
*bit_frame |= snd_soc_of_parse_daifmt_master(node, NULL, NULL, NULL);

#define update_daifmt(name) \
if (!(*daifmt & SND_SOC_DAIFMT_##name##_MASK) && \
(fmt & SND_SOC_DAIFMT_##name##_MASK)) \
*daifmt |= fmt & SND_SOC_DAIFMT_##name##_MASK;

/* non-master: use last one */
fmt = snd_soc_of_parse_daifmt(node, NULL);
update_daifmt(FORMAT);
update_daifmt(CLOCK);
update_daifmt(INV);
}

static int graph_link_init(struct asoc_simple_priv *priv,
struct device_node *link_ep,
struct device_node *target_ep,
struct device_node *ep,
struct link_info *li,
int is_cpu_node,
char *name)
{
struct device *dev = simple_priv_to_dev(priv);
struct snd_soc_dai_link *dai_link = simple_priv_to_link(priv, li->link);
struct device_node *port = of_get_parent(ep);
struct device_node *ports = of_get_parent(port);
unsigned int daifmt = 0, bit_frame = 0;

if (link_ep)
graph_parse_daifmt(link_ep, dai_link);
printk("1----%lx\n", dai_link->dai_fmt);
graph_parse_daifmt(target_ep, dai_link);
printk("2----%lx\n", dai_link->dai_fmt);
/*
* ports {
*(A)
* port {
*(B)
* endpoint {
*(C)
* };
* };
* };
* };
*/
graph_parse_daifmt(ep, &daifmt, &bit_frame);
graph_parse_daifmt(port, &daifmt, &bit_frame);
if (of_node_name_eq(ports, "ports"))
graph_parse_daifmt(ports, &daifmt, &bit_frame);

/*
* convert bit_frame
* We need to flip master if it was CPU node,
* because it is Codec base.
*/
bit_frame = snd_soc_daifmt_master_pickup(bit_frame);
if (is_cpu_node)
bit_frame = snd_soc_daifmt_master_fliped(bit_frame);

dai_link->dai_fmt = daifmt | bit_frame;
dai_link->init = graph_dai_init;
dai_link->ops = &graph_ops;
if (priv->ops)
dai_link->ops = priv->ops;
else
dai_link->ops = &graph_ops;

return asoc_simple_set_dailink_name(dev, dai_link, name);
}
@@ -450,7 +478,7 @@ int asoc_graph2_link_normal(struct asoc_simple_priv *priv,
sprintf(dai_name, "%s-%s", cpus->dai_name,
codecs->dai_name);

ret = graph_link_init(priv, NULL, cpu_ep, li, dai_name);
ret = graph_link_init(priv, cpu_ep, li, 1, dai_name);
if (ret < 0)
goto err;

@@ -514,7 +542,7 @@ int asoc_graph2_link_dpcm(struct asoc_simple_priv *priv,
cpus->of_node,
cpus->dai_name);
printk("------fe\n");
ret = graph_link_init(priv, ep, rep, li, dai_name);
ret = graph_link_init(priv, ep, li, 1, dai_name);
if (ret < 0)
goto err;
} else {
@@ -569,13 +597,9 @@ int asoc_graph2_link_dpcm(struct asoc_simple_priv *priv,
codecs->of_node,
codecs->dai_name);
printk("------be\n");
ret = graph_link_init(priv, ep, rep, li, dai_name);
ret = graph_link_init(priv, ep, li, 0, dai_name);
if (ret < 0)
goto err;

/* We need to flip master, since It is CPU base dai_fmt */
dai_link->dai_fmt = snd_soc_dai_fmt_master_fliped(dai_link->dai_fmt);
printk("3----%lx\n", dai_link->dai_fmt);
}

graph_parse_convert(dev, rep, &dai_props->adata);

0 comments on commit 9dcb567

Please sign in to comment.