summaryrefslogtreecommitdiff
path: root/sound/soc/generic
diff options
context:
space:
mode:
Diffstat (limited to 'sound/soc/generic')
-rw-r--r--sound/soc/generic/audio-graph-card.c429
-rw-r--r--sound/soc/generic/simple-card-utils.c440
-rw-r--r--sound/soc/generic/simple-card.c383
3 files changed, 579 insertions, 673 deletions
diff --git a/sound/soc/generic/audio-graph-card.c b/sound/soc/generic/audio-graph-card.c
index 69bc4848d787..ec7e673ba475 100644
--- a/sound/soc/generic/audio-graph-card.c
+++ b/sound/soc/generic/audio-graph-card.c
@@ -22,37 +22,6 @@
#define DPCM_SELECTABLE 1
-struct graph_priv {
- struct snd_soc_card snd_card;
- struct graph_dai_props {
- struct asoc_simple_dai *cpu_dai;
- struct asoc_simple_dai *codec_dai;
- struct snd_soc_dai_link_component codecs; /* single codec */
- struct snd_soc_dai_link_component platforms;
- struct asoc_simple_card_data adata;
- struct snd_soc_codec_conf *codec_conf;
- unsigned int mclk_fs;
- } *dai_props;
- struct asoc_simple_jack hp_jack;
- struct asoc_simple_jack mic_jack;
- struct snd_soc_dai_link *dai_link;
- struct asoc_simple_dai *dais;
- struct snd_soc_codec_conf *codec_conf;
- struct gpio_desc *pa_gpio;
-};
-
-struct link_info {
- int dais; /* number of dai */
- int link; /* number of link */
- int conf; /* number of codec_conf */
- int cpu; /* turn for CPU / Codec */
-};
-
-#define graph_priv_to_card(priv) (&(priv)->snd_card)
-#define graph_priv_to_props(priv, i) ((priv)->dai_props + (i))
-#define graph_priv_to_dev(priv) (graph_priv_to_card(priv)->dev)
-#define graph_priv_to_link(priv, i) (graph_priv_to_card(priv)->dai_link + (i))
-
#define PREFIX "audio-graph-card,"
static int graph_outdrv_event(struct snd_soc_dapm_widget *w,
@@ -60,7 +29,7 @@ static int graph_outdrv_event(struct snd_soc_dapm_widget *w,
int event)
{
struct snd_soc_dapm_context *dapm = w->dapm;
- struct graph_priv *priv = snd_soc_card_get_drvdata(dapm->card);
+ struct asoc_simple_priv *priv = snd_soc_card_get_drvdata(dapm->card);
switch (event) {
case SND_SOC_DAPM_POST_PMU:
@@ -82,127 +51,156 @@ static const struct snd_soc_dapm_widget graph_dapm_widgets[] = {
SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_PRE_PMD),
};
-static int graph_startup(struct snd_pcm_substream *substream)
+static const struct snd_soc_ops graph_ops = {
+ .startup = asoc_simple_startup,
+ .shutdown = asoc_simple_shutdown,
+ .hw_params = asoc_simple_hw_params,
+};
+
+static int graph_get_dai_id(struct device_node *ep)
{
- struct snd_soc_pcm_runtime *rtd = substream->private_data;
- struct graph_priv *priv = snd_soc_card_get_drvdata(rtd->card);
- struct graph_dai_props *dai_props = graph_priv_to_props(priv, rtd->num);
+ struct device_node *node;
+ struct device_node *endpoint;
+ struct of_endpoint info;
+ int i, id;
int ret;
- ret = asoc_simple_card_clk_enable(dai_props->cpu_dai);
- if (ret)
+ /* use driver specified DAI ID if exist */
+ ret = snd_soc_get_dai_id(ep);
+ if (ret != -ENOTSUPP)
return ret;
- ret = asoc_simple_card_clk_enable(dai_props->codec_dai);
- if (ret)
- asoc_simple_card_clk_disable(dai_props->cpu_dai);
+ /* use endpoint/port reg if exist */
+ ret = of_graph_parse_endpoint(ep, &info);
+ if (ret == 0) {
+ /*
+ * Because it will count port/endpoint if it doesn't have "reg".
+ * But, we can't judge whether it has "no reg", or "reg = <0>"
+ * only of_graph_parse_endpoint().
+ * We need to check "reg" property
+ */
+ if (of_get_property(ep, "reg", NULL))
+ return info.id;
- return ret;
-}
+ node = of_get_parent(ep);
+ of_node_put(node);
+ if (of_get_property(node, "reg", NULL))
+ return info.port;
+ }
+ node = of_graph_get_port_parent(ep);
-static void graph_shutdown(struct snd_pcm_substream *substream)
-{
- struct snd_soc_pcm_runtime *rtd = substream->private_data;
- struct graph_priv *priv = snd_soc_card_get_drvdata(rtd->card);
- struct graph_dai_props *dai_props = graph_priv_to_props(priv, rtd->num);
+ /*
+ * Non HDMI sound case, counting port/endpoint on its DT
+ * is enough. Let's count it.
+ */
+ i = 0;
+ id = -1;
+ for_each_endpoint_of_node(node, endpoint) {
+ if (endpoint == ep)
+ id = i;
+ i++;
+ }
- asoc_simple_card_clk_disable(dai_props->cpu_dai);
+ of_node_put(node);
+
+ if (id < 0)
+ return -ENODEV;
- asoc_simple_card_clk_disable(dai_props->codec_dai);
+ return id;
}
-static int graph_hw_params(struct snd_pcm_substream *substream,
- struct snd_pcm_hw_params *params)
+static int asoc_simple_parse_dai(struct device_node *ep,
+ struct snd_soc_dai_link_component *dlc,
+ struct device_node **dai_of_node,
+ const char **dai_name,
+ int *is_single_link)
{
- struct snd_soc_pcm_runtime *rtd = substream->private_data;
- struct snd_soc_dai *codec_dai = rtd->codec_dai;
- struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
- struct graph_priv *priv = snd_soc_card_get_drvdata(rtd->card);
- struct graph_dai_props *dai_props = graph_priv_to_props(priv, rtd->num);
- unsigned int mclk, mclk_fs = 0;
- int ret = 0;
-
- if (dai_props->mclk_fs)
- mclk_fs = dai_props->mclk_fs;
-
- if (mclk_fs) {
- mclk = params_rate(params) * mclk_fs;
- ret = snd_soc_dai_set_sysclk(codec_dai, 0, mclk,
- SND_SOC_CLOCK_IN);
- if (ret && ret != -ENOTSUPP)
- goto err;
-
- ret = snd_soc_dai_set_sysclk(cpu_dai, 0, mclk,
- SND_SOC_CLOCK_OUT);
- if (ret && ret != -ENOTSUPP)
- goto err;
+ struct device_node *node;
+ struct of_phandle_args args;
+ int ret;
+
+ /*
+ * Use snd_soc_dai_link_component instead of legacy style.
+ * It is only for codec, but cpu will be supported in the future.
+ * see
+ * soc-core.c :: snd_soc_init_multicodec()
+ */
+ if (dlc) {
+ dai_name = &dlc->dai_name;
+ dai_of_node = &dlc->of_node;
}
- return 0;
-err:
- return ret;
-}
-static const struct snd_soc_ops graph_ops = {
- .startup = graph_startup,
- .shutdown = graph_shutdown,
- .hw_params = graph_hw_params,
-};
+ if (!ep)
+ return 0;
+ if (!dai_name)
+ return 0;
-static int graph_dai_init(struct snd_soc_pcm_runtime *rtd)
-{
- struct graph_priv *priv = snd_soc_card_get_drvdata(rtd->card);
- struct graph_dai_props *dai_props = graph_priv_to_props(priv, rtd->num);
- int ret = 0;
+ node = of_graph_get_port_parent(ep);
- ret = asoc_simple_card_init_dai(rtd->codec_dai,
- dai_props->codec_dai);
- if (ret < 0)
- return ret;
+ /* Get dai->name */
+ args.np = node;
+ args.args[0] = graph_get_dai_id(ep);
+ args.args_count = (of_graph_get_endpoint_count(node) > 1);
- ret = asoc_simple_card_init_dai(rtd->cpu_dai,
- dai_props->cpu_dai);
+ ret = snd_soc_get_dai_name(&args, dai_name);
if (ret < 0)
return ret;
- return 0;
-}
-
-static int graph_be_hw_params_fixup(struct snd_soc_pcm_runtime *rtd,
- struct snd_pcm_hw_params *params)
-{
- struct graph_priv *priv = snd_soc_card_get_drvdata(rtd->card);
- struct graph_dai_props *dai_props = graph_priv_to_props(priv, rtd->num);
+ *dai_of_node = node;
- asoc_simple_card_convert_fixup(&dai_props->adata, params);
+ if (is_single_link)
+ *is_single_link = of_graph_get_endpoint_count(node) == 1;
return 0;
}
-static void graph_get_conversion(struct device *dev,
- struct device_node *ep,
- struct asoc_simple_card_data *adata)
+static void graph_parse_convert(struct device *dev,
+ struct device_node *ep,
+ struct asoc_simple_data *adata)
{
struct device_node *top = dev->of_node;
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);
- asoc_simple_card_parse_convert(dev, top, NULL, adata);
- asoc_simple_card_parse_convert(dev, node, PREFIX, adata);
- asoc_simple_card_parse_convert(dev, ports, NULL, adata);
- asoc_simple_card_parse_convert(dev, port, NULL, adata);
- asoc_simple_card_parse_convert(dev, ep, NULL, adata);
+ asoc_simple_parse_convert(dev, top, NULL, adata);
+ asoc_simple_parse_convert(dev, node, PREFIX, adata);
+ asoc_simple_parse_convert(dev, ports, NULL, adata);
+ asoc_simple_parse_convert(dev, port, NULL, adata);
+ asoc_simple_parse_convert(dev, ep, NULL, adata);
+
+ of_node_put(port);
+ of_node_put(ports);
+ of_node_put(node);
}
-static int graph_dai_link_of_dpcm(struct graph_priv *priv,
+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);
+ struct device_node *node = of_graph_get_port_parent(ep);
+
+ of_property_read_u32(top, "mclk-fs", &props->mclk_fs);
+ 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);
+ of_node_put(node);
+}
+
+static int graph_dai_link_of_dpcm(struct asoc_simple_priv *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);
- 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 *dev = simple_priv_to_dev(priv);
+ 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 *top = dev->of_node;
struct device_node *ep = li->cpu ? cpu_ep : codec_ep;
struct device_node *port;
@@ -224,18 +222,12 @@ static int graph_dai_link_of_dpcm(struct graph_priv *priv,
dev_dbg(dev, "link_of DPCM (%pOF)\n", ep);
- of_property_read_u32(top, "mclk-fs", &dai_props->mclk_fs);
- of_property_read_u32(ports, "mclk-fs", &dai_props->mclk_fs);
- of_property_read_u32(port, "mclk-fs", &dai_props->mclk_fs);
- of_property_read_u32(ep, "mclk-fs", &dai_props->mclk_fs);
-
- graph_get_conversion(dev, ep, &dai_props->adata);
-
of_node_put(ports);
of_node_put(port);
of_node_put(node);
if (li->cpu) {
+ int is_single_links = 0;
/* BE is dummy */
codecs->of_node = NULL;
@@ -249,23 +241,22 @@ static int graph_dai_link_of_dpcm(struct graph_priv *priv,
dai =
dai_props->cpu_dai = &priv->dais[li->dais++];
- ret = asoc_simple_card_parse_graph_cpu(ep, dai_link);
+ ret = asoc_simple_parse_cpu(ep, dai_link, &is_single_links);
if (ret)
return ret;
- ret = asoc_simple_card_parse_clk_cpu(dev, ep, dai_link, dai);
+ ret = asoc_simple_parse_clk_cpu(dev, ep, dai_link, dai);
if (ret < 0)
return ret;
- ret = asoc_simple_card_set_dailink_name(dev, dai_link,
- "fe.%s",
- dai_link->cpu_dai_name);
+ ret = asoc_simple_set_dailink_name(dev, dai_link,
+ "fe.%s",
+ dai_link->cpu_dai_name);
if (ret < 0)
return ret;
/* card->num_links includes Codec */
- asoc_simple_card_canonicalize_cpu(dai_link,
- of_graph_get_endpoint_count(dai_link->cpu_of_node) == 1);
+ asoc_simple_canonicalize_cpu(dai_link, is_single_links);
} else {
struct snd_soc_codec_conf *cconf;
@@ -276,7 +267,7 @@ static int graph_dai_link_of_dpcm(struct graph_priv *priv,
/* BE settings */
dai_link->no_pcm = 1;
- dai_link->be_hw_params_fixup = graph_be_hw_params_fixup;
+ dai_link->be_hw_params_fixup = asoc_simple_be_hw_params_fixup;
dai =
dai_props->codec_dai = &priv->dais[li->dais++];
@@ -284,17 +275,17 @@ static int graph_dai_link_of_dpcm(struct graph_priv *priv,
cconf =
dai_props->codec_conf = &priv->codec_conf[li->conf++];
- ret = asoc_simple_card_parse_graph_codec(ep, dai_link);
+ ret = asoc_simple_parse_codec(ep, dai_link);
if (ret < 0)
return ret;
- ret = asoc_simple_card_parse_clk_codec(dev, ep, dai_link, dai);
+ ret = asoc_simple_parse_clk_codec(dev, ep, dai_link, dai);
if (ret < 0)
return ret;
- ret = asoc_simple_card_set_dailink_name(dev, dai_link,
- "be.%s",
- codecs->dai_name);
+ ret = asoc_simple_set_dailink_name(dev, dai_link,
+ "be.%s",
+ codecs->dai_name);
if (ret < 0)
return ret;
@@ -309,51 +300,45 @@ static int graph_dai_link_of_dpcm(struct graph_priv *priv,
"prefix");
}
- asoc_simple_card_canonicalize_platform(dai_link);
+ graph_parse_convert(dev, ep, &dai_props->adata);
+ graph_parse_mclk_fs(top, ep, dai_props);
- ret = asoc_simple_card_of_parse_tdm(ep, dai);
+ asoc_simple_canonicalize_platform(dai_link);
+
+ ret = asoc_simple_parse_tdm(ep, dai);
if (ret)
return ret;
- ret = asoc_simple_card_parse_daifmt(dev, cpu_ep, codec_ep,
- NULL, &dai_link->dai_fmt);
+ ret = asoc_simple_parse_daifmt(dev, cpu_ep, codec_ep,
+ NULL, &dai_link->dai_fmt);
if (ret < 0)
return ret;
dai_link->dpcm_playback = 1;
dai_link->dpcm_capture = 1;
dai_link->ops = &graph_ops;
- dai_link->init = graph_dai_init;
+ dai_link->init = asoc_simple_dai_init;
return 0;
}
-static int graph_dai_link_of(struct graph_priv *priv,
+static int graph_dai_link_of(struct asoc_simple_priv *priv,
struct device_node *cpu_ep,
struct device_node *codec_ep,
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 *dev = simple_priv_to_dev(priv);
+ 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 *top = dev->of_node;
- struct device_node *cpu_port;
- struct device_node *cpu_ports;
- struct device_node *codec_port;
- struct device_node *codec_ports;
struct asoc_simple_dai *cpu_dai;
struct asoc_simple_dai *codec_dai;
- int ret;
+ int ret, single_cpu;
/* 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++;
@@ -364,84 +349,74 @@ static int graph_dai_link_of(struct graph_priv *priv,
dai_props->codec_dai = &priv->dais[li->dais++];
/* Factor to mclk, used in hw_params() */
- of_property_read_u32(top, "mclk-fs", &dai_props->mclk_fs);
- of_property_read_u32(cpu_ports, "mclk-fs", &dai_props->mclk_fs);
- of_property_read_u32(codec_ports, "mclk-fs", &dai_props->mclk_fs);
- of_property_read_u32(cpu_port, "mclk-fs", &dai_props->mclk_fs);
- of_property_read_u32(codec_port, "mclk-fs", &dai_props->mclk_fs);
- of_property_read_u32(cpu_ep, "mclk-fs", &dai_props->mclk_fs);
- of_property_read_u32(codec_ep, "mclk-fs", &dai_props->mclk_fs);
- of_node_put(cpu_port);
- of_node_put(cpu_ports);
- of_node_put(codec_port);
- of_node_put(codec_ports);
-
- ret = asoc_simple_card_parse_daifmt(dev, cpu_ep, codec_ep,
- NULL, &dai_link->dai_fmt);
+ graph_parse_mclk_fs(top, cpu_ep, dai_props);
+ graph_parse_mclk_fs(top, codec_ep, dai_props);
+
+ ret = asoc_simple_parse_daifmt(dev, cpu_ep, codec_ep,
+ NULL, &dai_link->dai_fmt);
if (ret < 0)
return ret;
- ret = asoc_simple_card_parse_graph_cpu(cpu_ep, dai_link);
+ ret = asoc_simple_parse_cpu(cpu_ep, dai_link, &single_cpu);
if (ret < 0)
return ret;
- ret = asoc_simple_card_parse_graph_codec(codec_ep, dai_link);
+ ret = asoc_simple_parse_codec(codec_ep, dai_link);
if (ret < 0)
return ret;
- ret = asoc_simple_card_of_parse_tdm(cpu_ep, cpu_dai);
+ ret = asoc_simple_parse_tdm(cpu_ep, cpu_dai);
if (ret < 0)
return ret;
- ret = asoc_simple_card_of_parse_tdm(codec_ep, codec_dai);
+ ret = asoc_simple_parse_tdm(codec_ep, codec_dai);
if (ret < 0)
return ret;
- ret = asoc_simple_card_parse_clk_cpu(dev, cpu_ep, dai_link, cpu_dai);
+ ret = asoc_simple_parse_clk_cpu(dev, cpu_ep, dai_link, cpu_dai);
if (ret < 0)
return ret;
- ret = asoc_simple_card_parse_clk_codec(dev, codec_ep, dai_link, codec_dai);
+ ret = asoc_simple_parse_clk_codec(dev, codec_ep, dai_link, codec_dai);
if (ret < 0)
return ret;
- ret = asoc_simple_card_set_dailink_name(dev, dai_link,
- "%s-%s",
- dai_link->cpu_dai_name,
- dai_link->codecs->dai_name);
+ ret = asoc_simple_set_dailink_name(dev, dai_link,
+ "%s-%s",
+ dai_link->cpu_dai_name,
+ dai_link->codecs->dai_name);
if (ret < 0)
return ret;
dai_link->ops = &graph_ops;
- dai_link->init = graph_dai_init;
+ dai_link->init = asoc_simple_dai_init;
- asoc_simple_card_canonicalize_platform(dai_link);
- asoc_simple_card_canonicalize_cpu(dai_link,
- of_graph_get_endpoint_count(dai_link->cpu_of_node) == 1);
+ asoc_simple_canonicalize_cpu(dai_link, single_cpu);
+ asoc_simple_canonicalize_platform(dai_link);
return 0;
}
-static int graph_for_each_link(struct graph_priv *priv,
+static int graph_for_each_link(struct asoc_simple_priv *priv,
struct link_info *li,
- int (*func_noml)(struct graph_priv *priv,
+ int (*func_noml)(struct asoc_simple_priv *priv,
struct device_node *cpu_ep,
struct device_node *codec_ep,
struct link_info *li),
- int (*func_dpcm)(struct graph_priv *priv,
+ int (*func_dpcm)(struct asoc_simple_priv *priv,
struct device_node *cpu_ep,
struct device_node *codec_ep,
struct link_info *li, int dup_codec))
{
struct of_phandle_iterator it;
- struct device *dev = graph_priv_to_dev(priv);
+ struct device *dev = simple_priv_to_dev(priv);
struct device_node *node = dev->of_node;
struct device_node *cpu_port;
struct device_node *cpu_ep;
struct device_node *codec_ep;
struct device_node *codec_port;
struct device_node *codec_port_old = NULL;
- struct asoc_simple_card_data adata;
+ struct asoc_simple_data adata;
uintptr_t dpcm_selectable = (uintptr_t)of_device_get_match_data(dev);
int rc, ret;
@@ -465,8 +440,8 @@ static int graph_for_each_link(struct graph_priv *priv,
/* get convert-xxx property */
memset(&adata, 0, sizeof(adata));
- graph_get_conversion(dev, codec_ep, &adata);
- graph_get_conversion(dev, cpu_ep, &adata);
+ graph_parse_convert(dev, codec_ep, &adata);
+ graph_parse_convert(dev, cpu_ep, &adata);
/*
* It is DPCM
@@ -492,17 +467,17 @@ static int graph_for_each_link(struct graph_priv *priv,
return 0;
}
-static int graph_parse_of(struct graph_priv *priv)
+static int graph_parse_of(struct asoc_simple_priv *priv)
{
- struct snd_soc_card *card = graph_priv_to_card(priv);
+ struct snd_soc_card *card = simple_priv_to_card(priv);
struct link_info li;
int ret;
- ret = asoc_simple_card_of_parse_widgets(card, NULL);
+ ret = asoc_simple_parse_widgets(card, NULL);
if (ret < 0)
return ret;
- ret = asoc_simple_card_of_parse_routing(card, NULL);
+ ret = asoc_simple_parse_routing(card, NULL);
if (ret < 0)
return ret;
@@ -527,15 +502,15 @@ static int graph_parse_of(struct graph_priv *priv)
return ret;
}
- return asoc_simple_card_parse_card_name(card, NULL);
+ return asoc_simple_parse_card_name(card, NULL);
}
-static int graph_count_noml(struct graph_priv *priv,
+static int graph_count_noml(struct asoc_simple_priv *priv,
struct device_node *cpu_ep,
struct device_node *codec_ep,
struct link_info *li)
{
- struct device *dev = graph_priv_to_dev(priv);
+ struct device *dev = simple_priv_to_dev(priv);
li->link += 1; /* 1xCPU-Codec */
li->dais += 2; /* 1xCPU + 1xCodec */
@@ -545,13 +520,13 @@ static int graph_count_noml(struct graph_priv *priv,
return 0;
}
-static int graph_count_dpcm(struct graph_priv *priv,
+static int graph_count_dpcm(struct asoc_simple_priv *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);
+ struct device *dev = simple_priv_to_dev(priv);
li->link++; /* 1xCPU-dummy */
li->dais++; /* 1xCPU */
@@ -567,10 +542,10 @@ static int graph_count_dpcm(struct graph_priv *priv,
return 0;
}
-static void graph_get_dais_count(struct graph_priv *priv,
+static void graph_get_dais_count(struct asoc_simple_priv *priv,
struct link_info *li)
{
- struct device *dev = graph_priv_to_dev(priv);
+ struct device *dev = simple_priv_to_dev(priv);
/*
* link_num : number of links.
@@ -627,14 +602,14 @@ static void graph_get_dais_count(struct graph_priv *priv,
static int graph_card_probe(struct snd_soc_card *card)
{
- struct graph_priv *priv = snd_soc_card_get_drvdata(card);
+ struct asoc_simple_priv *priv = snd_soc_card_get_drvdata(card);
int ret;
- ret = asoc_simple_card_init_hp(card, &priv->hp_jack, NULL);
+ ret = asoc_simple_init_hp(card, &priv->hp_jack, NULL);
if (ret < 0)
return ret;
- ret = asoc_simple_card_init_mic(card, &priv->mic_jack, NULL);
+ ret = asoc_simple_init_mic(card, &priv->mic_jack, NULL);
if (ret < 0)
return ret;
@@ -643,22 +618,18 @@ static int graph_card_probe(struct snd_soc_card *card)
static int graph_probe(struct platform_device *pdev)
{
- struct graph_priv *priv;
- struct snd_soc_dai_link *dai_link;
- struct graph_dai_props *dai_props;
- struct asoc_simple_dai *dais;
+ struct asoc_simple_priv *priv;
struct device *dev = &pdev->dev;
struct snd_soc_card *card;
- struct snd_soc_codec_conf *cconf;
struct link_info li;
- int ret, i;
+ int ret;
/* Allocate the private data and the DAI link array */
priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL);
if (!priv)
return -ENOMEM;
- card = graph_priv_to_card(priv);
+ card = simple_priv_to_card(priv);
card->owner = THIS_MODULE;
card->dev = dev;
card->dapm_widgets = graph_dapm_widgets;
@@ -670,25 +641,9 @@ static int graph_probe(struct platform_device *pdev)
if (!li.link || !li.dais)
return -EINVAL;
- dai_props = devm_kcalloc(dev, li.link, sizeof(*dai_props), GFP_KERNEL);
- dai_link = devm_kcalloc(dev, li.link, sizeof(*dai_link), GFP_KERNEL);
- dais = devm_kcalloc(dev, li.dais, sizeof(*dais), GFP_KERNEL);
- cconf = devm_kcalloc(dev, li.conf, sizeof(*cconf), GFP_KERNEL);
- if (!dai_props || !dai_link || !dais)
- return -ENOMEM;
-
- /*
- * Use snd_soc_dai_link_component instead of legacy style
- * It is codec only. but cpu/platform will be supported in the future.
- * see
- * soc-core.c :: snd_soc_init_multicodec()
- */
- for (i = 0; i < li.link; i++) {
- dai_link[i].codecs = &dai_props[i].codecs;
- dai_link[i].num_codecs = 1;
- dai_link[i].platforms = &dai_props[i].platforms;
- dai_link[i].num_platforms = 1;
- }
+ ret = asoc_simple_init_priv(priv, &li);
+ if (ret < 0)
+ return ret;
priv->pa_gpio = devm_gpiod_get_optional(dev, "pa", GPIOD_OUT_LOW);
if (IS_ERR(priv->pa_gpio)) {
@@ -697,16 +652,6 @@ static int graph_probe(struct platform_device *pdev)
return ret;
}
- priv->dai_props = dai_props;
- priv->dai_link = dai_link;
- priv->dais = dais;
- priv->codec_conf = cconf;
-
- card->dai_link = dai_link;
- card->num_links = li.link;
- card->codec_conf = cconf;
- card->num_configs = li.conf;
-
ret = graph_parse_of(priv);
if (ret < 0) {
if (ret != -EPROBE_DEFER)
@@ -716,13 +661,15 @@ static int graph_probe(struct platform_device *pdev)
snd_soc_card_set_drvdata(card, priv);
+ asoc_simple_debug_info(priv);
+
ret = devm_snd_soc_register_card(dev, card);
if (ret < 0)
goto err;
return 0;
err:
- asoc_simple_card_clean_reference(card);
+ asoc_simple_clean_reference(card);
return ret;
}
@@ -731,7 +678,7 @@ static int graph_remove(struct platform_device *pdev)
{
struct snd_soc_card *card = platform_get_drvdata(pdev);
- return asoc_simple_card_clean_reference(card);
+ return asoc_simple_clean_reference(card);
}
static const struct of_device_id graph_of_match[] = {
diff --git a/sound/soc/generic/simple-card-utils.c b/sound/soc/generic/simple-card-utils.c
index 5c1424f03620..f4c6375d11c7 100644
--- a/sound/soc/generic/simple-card-utils.c
+++ b/sound/soc/generic/simple-card-utils.c
@@ -14,8 +14,8 @@
#include <sound/jack.h>
#include <sound/simple_card_utils.h>
-void asoc_simple_card_convert_fixup(struct asoc_simple_card_data *data,
- struct snd_pcm_hw_params *params)
+void asoc_simple_convert_fixup(struct asoc_simple_data *data,
+ struct snd_pcm_hw_params *params)
{
struct snd_interval *rate = hw_param_interval(params,
SNDRV_PCM_HW_PARAM_RATE);
@@ -30,12 +30,12 @@ void asoc_simple_card_convert_fixup(struct asoc_simple_card_data *data,
channels->min =
channels->max = data->convert_channels;
}
-EXPORT_SYMBOL_GPL(asoc_simple_card_convert_fixup);
+EXPORT_SYMBOL_GPL(asoc_simple_convert_fixup);
-void asoc_simple_card_parse_convert(struct device *dev,
- struct device_node *np,
- char *prefix,
- struct asoc_simple_card_data *data)
+void asoc_simple_parse_convert(struct device *dev,
+ struct device_node *np,
+ char *prefix,
+ struct asoc_simple_data *data)
{
char prop[128];
@@ -49,17 +49,14 @@ void asoc_simple_card_parse_convert(struct device *dev,
/* channels transfer */
snprintf(prop, sizeof(prop), "%s%s", prefix, "convert-channels");
of_property_read_u32(np, prop, &data->convert_channels);
-
- dev_dbg(dev, "convert_rate %d\n", data->convert_rate);
- dev_dbg(dev, "convert_channels %d\n", data->convert_channels);
}
-EXPORT_SYMBOL_GPL(asoc_simple_card_parse_convert);
+EXPORT_SYMBOL_GPL(asoc_simple_parse_convert);
-int asoc_simple_card_parse_daifmt(struct device *dev,
- struct device_node *node,
- struct device_node *codec,
- char *prefix,
- unsigned int *retfmt)
+int asoc_simple_parse_daifmt(struct device *dev,
+ struct device_node *node,
+ struct device_node *codec,
+ char *prefix,
+ unsigned int *retfmt)
{
struct device_node *bitclkmaster = NULL;
struct device_node *framemaster = NULL;
@@ -93,15 +90,13 @@ int asoc_simple_card_parse_daifmt(struct device *dev,
*retfmt = daifmt;
- dev_dbg(dev, "format : %04x\n", daifmt);
-
return 0;
}
-EXPORT_SYMBOL_GPL(asoc_simple_card_parse_daifmt);
+EXPORT_SYMBOL_GPL(asoc_simple_parse_daifmt);
-int asoc_simple_card_set_dailink_name(struct device *dev,
- struct snd_soc_dai_link *dai_link,
- const char *fmt, ...)
+int asoc_simple_set_dailink_name(struct device *dev,
+ struct snd_soc_dai_link *dai_link,
+ const char *fmt, ...)
{
va_list ap;
char *name = NULL;
@@ -116,16 +111,14 @@ int asoc_simple_card_set_dailink_name(struct device *dev,
dai_link->name = name;
dai_link->stream_name = name;
-
- dev_dbg(dev, "name : %s\n", name);
}
return ret;
}
-EXPORT_SYMBOL_GPL(asoc_simple_card_set_dailink_name);
+EXPORT_SYMBOL_GPL(asoc_simple_set_dailink_name);
-int asoc_simple_card_parse_card_name(struct snd_soc_card *card,
- char *prefix)
+int asoc_simple_parse_card_name(struct snd_soc_card *card,
+ char *prefix)
{
int ret;
@@ -146,34 +139,30 @@ int asoc_simple_card_parse_card_name(struct snd_soc_card *card,
if (!card->name && card->dai_link)
card->name = card->dai_link->name;
- dev_dbg(card->dev, "Card Name: %s\n", card->name ? card->name : "");
-
return 0;
}
-EXPORT_SYMBOL_GPL(asoc_simple_card_parse_card_name);
+EXPORT_SYMBOL_GPL(asoc_simple_parse_card_name);
-int asoc_simple_card_clk_enable(struct asoc_simple_dai *dai)
+static int asoc_simple_clk_enable(struct asoc_simple_dai *dai)
{
if (dai)
return clk_prepare_enable(dai->clk);
return 0;
}
-EXPORT_SYMBOL_GPL(asoc_simple_card_clk_enable);
-void asoc_simple_card_clk_disable(struct asoc_simple_dai *dai)
+static void asoc_simple_clk_disable(struct asoc_simple_dai *dai)
{
if (dai)
clk_disable_unprepare(dai->clk);
}
-EXPORT_SYMBOL_GPL(asoc_simple_card_clk_disable);
-
-int asoc_simple_card_parse_clk(struct device *dev,
- struct device_node *node,
- struct device_node *dai_of_node,
- struct asoc_simple_dai *simple_dai,
- const char *dai_name,
- struct snd_soc_dai_link_component *dlc)
+
+int asoc_simple_parse_clk(struct device *dev,
+ struct device_node *node,
+ struct device_node *dai_of_node,
+ struct asoc_simple_dai *simple_dai,
+ const char *dai_name,
+ struct snd_soc_dai_link_component *dlc)
{
struct clk *clk;
u32 val;
@@ -184,10 +173,8 @@ int asoc_simple_card_parse_clk(struct device *dev,
* see
* soc-core.c :: snd_soc_init_multicodec()
*/
- if (dlc) {
+ if (dlc)
dai_of_node = dlc->of_node;
- dai_name = dlc->dai_name;
- }
/*
* Parse dai->sysclk come from "clocks = <&xxx>"
@@ -211,158 +198,113 @@ int asoc_simple_card_parse_clk(struct device *dev,
if (of_property_read_bool(node, "system-clock-direction-out"))
simple_dai->clk_direction = SND_SOC_CLOCK_OUT;
- dev_dbg(dev, "%s : sysclk = %d, direction %d\n", dai_name,
- simple_dai->sysclk, simple_dai->clk_direction);
-
return 0;
}
-EXPORT_SYMBOL_GPL(asoc_simple_card_parse_clk);
-
-int asoc_simple_card_parse_dai(struct device_node *node,
- struct snd_soc_dai_link_component *dlc,
- struct device_node **dai_of_node,
- const char **dai_name,
- const char *list_name,
- const char *cells_name,
- int *is_single_link)
+EXPORT_SYMBOL_GPL(asoc_simple_parse_clk);
+
+int asoc_simple_startup(struct snd_pcm_substream *substream)
{
- struct of_phandle_args args;
+ struct snd_soc_pcm_runtime *rtd = substream->private_data;
+ struct asoc_simple_priv *priv = snd_soc_card_get_drvdata(rtd->card);
+ struct simple_dai_props *dai_props = simple_priv_to_props(priv, rtd->num);
int ret;
- if (!node)
- return 0;
-
- /*
- * Use snd_soc_dai_link_component instead of legacy style.
- * It is only for codec, but cpu will be supported in the future.
- * see
- * soc-core.c :: snd_soc_init_multicodec()
- */
- if (dlc) {
- dai_name = &dlc->dai_name;
- dai_of_node = &dlc->of_node;
- }
-
- /*
- * Get node via "sound-dai = <&phandle port>"
- * it will be used as xxx_of_node on soc_bind_dai_link()
- */
- ret = of_parse_phandle_with_args(node, list_name, cells_name, 0, &args);
+ ret = asoc_simple_clk_enable(dai_props->cpu_dai);
if (ret)
return ret;
- /* Get dai->name */
- if (dai_name) {
- ret = snd_soc_of_get_dai_name(node, dai_name);
- if (ret < 0)
- return ret;
- }
-
- *dai_of_node = args.np;
-
- if (is_single_link)
- *is_single_link = !args.args_count;
+ ret = asoc_simple_clk_enable(dai_props->codec_dai);
+ if (ret)
+ asoc_simple_clk_disable(dai_props->cpu_dai);
- return 0;
+ return ret;
}
-EXPORT_SYMBOL_GPL(asoc_simple_card_parse_dai);
+EXPORT_SYMBOL_GPL(asoc_simple_startup);
-static int asoc_simple_card_get_dai_id(struct device_node *ep)
+void asoc_simple_shutdown(struct snd_pcm_substream *substream)
{
- struct device_node *node;
- struct device_node *endpoint;
- struct of_endpoint info;
- int i, id;
- int ret;
+ struct snd_soc_pcm_runtime *rtd = substream->private_data;
+ struct asoc_simple_priv *priv = snd_soc_card_get_drvdata(rtd->card);
+ struct simple_dai_props *dai_props =
+ simple_priv_to_props(priv, rtd->num);
- /* use driver specified DAI ID if exist */
- ret = snd_soc_get_dai_id(ep);
- if (ret != -ENOTSUPP)
- return ret;
+ asoc_simple_clk_disable(dai_props->cpu_dai);
- /* use endpoint/port reg if exist */
- ret = of_graph_parse_endpoint(ep, &info);
- if (ret == 0) {
- /*
- * Because it will count port/endpoint if it doesn't have "reg".
- * But, we can't judge whether it has "no reg", or "reg = <0>"
- * only of_graph_parse_endpoint().
- * We need to check "reg" property
- */
- if (of_get_property(ep, "reg", NULL))
- return info.id;
-
- node = of_get_parent(ep);
- of_node_put(node);
- if (of_get_property(node, "reg", NULL))
- return info.port;
- }
- node = of_graph_get_port_parent(ep);
+ asoc_simple_clk_disable(dai_props->codec_dai);
+}
+EXPORT_SYMBOL_GPL(asoc_simple_shutdown);
- /*
- * Non HDMI sound case, counting port/endpoint on its DT
- * is enough. Let's count it.
- */
- i = 0;
- id = -1;
- for_each_endpoint_of_node(node, endpoint) {
- if (endpoint == ep)
- id = i;
- i++;
- }
+static int asoc_simple_set_clk_rate(struct asoc_simple_dai *simple_dai,
+ unsigned long rate)
+{
+ if (!simple_dai)
+ return 0;
- of_node_put(node);
+ if (!simple_dai->clk)
+ return 0;
- if (id < 0)
- return -ENODEV;
+ if (clk_get_rate(simple_dai->clk) == rate)
+ return 0;
- return id;
+ return clk_set_rate(simple_dai->clk, rate);
}
-int asoc_simple_card_parse_graph_dai(struct device_node *ep,
- struct snd_soc_dai_link_component *dlc,
- struct device_node **dai_of_node,
- const char **dai_name)
+int asoc_simple_hw_params(struct snd_pcm_substream *substream,
+ struct snd_pcm_hw_params *params)
{
- struct device_node *node;
- struct of_phandle_args args;
- int ret;
-
- /*
- * Use snd_soc_dai_link_component instead of legacy style.
- * It is only for codec, but cpu will be supported in the future.
- * see
- * soc-core.c :: snd_soc_init_multicodec()
- */
- if (dlc) {
- dai_name = &dlc->dai_name;
- dai_of_node = &dlc->of_node;
- }
+ struct snd_soc_pcm_runtime *rtd = substream->private_data;
+ struct snd_soc_dai *codec_dai = rtd->codec_dai;
+ struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
+ struct asoc_simple_priv *priv = snd_soc_card_get_drvdata(rtd->card);
+ struct simple_dai_props *dai_props =
+ simple_priv_to_props(priv, rtd->num);
+ unsigned int mclk, mclk_fs = 0;
+ int ret = 0;
+
+ if (dai_props->mclk_fs)
+ mclk_fs = dai_props->mclk_fs;
+
+ if (mclk_fs) {
+ mclk = params_rate(params) * mclk_fs;
+
+ ret = asoc_simple_set_clk_rate(dai_props->codec_dai, mclk);
+ if (ret < 0)
+ return ret;
- if (!ep)
- return 0;
- if (!dai_name)
- return 0;
+ ret = asoc_simple_set_clk_rate(dai_props->cpu_dai, mclk);
+ if (ret < 0)
+ return ret;
- node = of_graph_get_port_parent(ep);
+ ret = snd_soc_dai_set_sysclk(codec_dai, 0, mclk,
+ SND_SOC_CLOCK_IN);
+ if (ret && ret != -ENOTSUPP)
+ goto err;
- /* Get dai->name */
- args.np = node;
- args.args[0] = asoc_simple_card_get_dai_id(ep);
- args.args_count = (of_graph_get_endpoint_count(node) > 1);
+ ret = snd_soc_dai_set_sysclk(cpu_dai, 0, mclk,
+ SND_SOC_CLOCK_OUT);
+ if (ret && ret != -ENOTSUPP)
+ goto err;
+ }
+ return 0;
+err:
+ return ret;
+}
+EXPORT_SYMBOL_GPL(asoc_simple_hw_params);
- ret = snd_soc_get_dai_name(&args, dai_name);
- if (ret < 0)
- return ret;
+int asoc_simple_be_hw_params_fixup(struct snd_soc_pcm_runtime *rtd,
+ struct snd_pcm_hw_params *params)
+{
+ struct asoc_simple_priv *priv = snd_soc_card_get_drvdata(rtd->card);
+ struct simple_dai_props *dai_props = simple_priv_to_props(priv, rtd->num);
- *dai_of_node = node;
+ asoc_simple_convert_fixup(&dai_props->adata, params);
return 0;
}
-EXPORT_SYMBOL_GPL(asoc_simple_card_parse_graph_dai);
+EXPORT_SYMBOL_GPL(asoc_simple_be_hw_params_fixup);
-int asoc_simple_card_init_dai(struct snd_soc_dai *dai,
- struct asoc_simple_dai *simple_dai)
+static int asoc_simple_init_dai(struct snd_soc_dai *dai,
+ struct asoc_simple_dai *simple_dai)
{
int ret;
@@ -392,18 +334,37 @@ int asoc_simple_card_init_dai(struct snd_soc_dai *dai,
return 0;
}
-EXPORT_SYMBOL_GPL(asoc_simple_card_init_dai);
-void asoc_simple_card_canonicalize_platform(struct snd_soc_dai_link *dai_link)
+int asoc_simple_dai_init(struct snd_soc_pcm_runtime *rtd)
+{
+ struct asoc_simple_priv *priv = snd_soc_card_get_drvdata(rtd->card);
+ struct simple_dai_props *dai_props = simple_priv_to_props(priv, rtd->num);
+ int ret;
+
+ ret = asoc_simple_init_dai(rtd->codec_dai,
+ dai_props->codec_dai);
+ if (ret < 0)
+ return ret;
+
+ ret = asoc_simple_init_dai(rtd->cpu_dai,
+ dai_props->cpu_dai);
+ if (ret < 0)
+ return ret;
+
+ return 0;
+}
+EXPORT_SYMBOL_GPL(asoc_simple_dai_init);
+
+void asoc_simple_canonicalize_platform(struct snd_soc_dai_link *dai_link)
{
/* Assumes platform == cpu */
if (!dai_link->platforms->of_node)
dai_link->platforms->of_node = dai_link->cpu_of_node;
}
-EXPORT_SYMBOL_GPL(asoc_simple_card_canonicalize_platform);
+EXPORT_SYMBOL_GPL(asoc_simple_canonicalize_platform);
-void asoc_simple_card_canonicalize_cpu(struct snd_soc_dai_link *dai_link,
- int is_single_links)
+void asoc_simple_canonicalize_cpu(struct snd_soc_dai_link *dai_link,
+ int is_single_links)
{
/*
* In soc_bind_dai_link() will check cpu name after
@@ -417,9 +378,9 @@ void asoc_simple_card_canonicalize_cpu(struct snd_soc_dai_link *dai_link,
if (is_single_links)
dai_link->cpu_dai_name = NULL;
}
-EXPORT_SYMBOL_GPL(asoc_simple_card_canonicalize_cpu);
+EXPORT_SYMBOL_GPL(asoc_simple_canonicalize_cpu);
-int asoc_simple_card_clean_reference(struct snd_soc_card *card)
+int asoc_simple_clean_reference(struct snd_soc_card *card)
{
struct snd_soc_dai_link *dai_link;
int i;
@@ -430,10 +391,10 @@ int asoc_simple_card_clean_reference(struct snd_soc_card *card)
}
return 0;
}
-EXPORT_SYMBOL_GPL(asoc_simple_card_clean_reference);
+EXPORT_SYMBOL_GPL(asoc_simple_clean_reference);
-int asoc_simple_card_of_parse_routing(struct snd_soc_card *card,
- char *prefix)
+int asoc_simple_parse_routing(struct snd_soc_card *card,
+ char *prefix)
{
struct device_node *node = card->dev->of_node;
char prop[128];
@@ -448,10 +409,10 @@ int asoc_simple_card_of_parse_routing(struct snd_soc_card *card,
return snd_soc_of_parse_audio_routing(card, prop);
}
-EXPORT_SYMBOL_GPL(asoc_simple_card_of_parse_routing);
+EXPORT_SYMBOL_GPL(asoc_simple_parse_routing);
-int asoc_simple_card_of_parse_widgets(struct snd_soc_card *card,
- char *prefix)
+int asoc_simple_parse_widgets(struct snd_soc_card *card,
+ char *prefix)
{
struct device_node *node = card->dev->of_node;
char prop[128];
@@ -467,11 +428,68 @@ int asoc_simple_card_of_parse_widgets(struct snd_soc_card *card,
/* no widgets is not error */
return 0;
}
-EXPORT_SYMBOL_GPL(asoc_simple_card_of_parse_widgets);
+EXPORT_SYMBOL_GPL(asoc_simple_parse_widgets);
+
+int asoc_simple_parse_pin_switches(struct snd_soc_card *card,
+ char *prefix)
+{
+ const unsigned int nb_controls_max = 16;
+ const char **strings, *control_name;
+ struct snd_kcontrol_new *controls;
+ struct device *dev = card->dev;
+ unsigned int i, nb_controls;
+ char prop[128];
+ int ret;
+
+ if (!prefix)
+ prefix = "";
+
+ snprintf(prop, sizeof(prop), "%s%s", prefix, "pin-switches");
+
+ if (!of_property_read_bool(dev->of_node, prop))
+ return 0;
+
+ strings = devm_kcalloc(dev, nb_controls_max,
+ sizeof(*strings), GFP_KERNEL);
+ if (!strings)
+ return -ENOMEM;
+
+ ret = of_property_read_string_array(dev->of_node, prop,
+ strings, nb_controls_max);
+ if (ret < 0)
+ return ret;
+
+ nb_controls = (unsigned int)ret;
+
+ controls = devm_kcalloc(dev, nb_controls,
+ sizeof(*controls), GFP_KERNEL);
+ if (!controls)
+ return -ENOMEM;
+
+ for (i = 0; i < nb_controls; i++) {
+ control_name = devm_kasprintf(dev, GFP_KERNEL,
+ "%s Switch", strings[i]);
+ if (!control_name)
+ return -ENOMEM;
+
+ controls[i].iface = SNDRV_CTL_ELEM_IFACE_MIXER;
+ controls[i].name = control_name;
+ controls[i].info = snd_soc_dapm_info_pin_switch;
+ controls[i].get = snd_soc_dapm_get_pin_switch;
+ controls[i].put = snd_soc_dapm_put_pin_switch;
+ controls[i].private_value = (unsigned long)strings[i];
+ }
+
+ card->controls = controls;
+ card->num_controls = nb_controls;
+
+ return 0;
+}
+EXPORT_SYMBOL_GPL(asoc_simple_parse_pin_switches);
-int asoc_simple_card_init_jack(struct snd_soc_card *card,
- struct asoc_simple_jack *sjack,
- int is_hp, char *prefix)
+int asoc_simple_init_jack(struct snd_soc_card *card,
+ struct asoc_simple_jack *sjack,
+ int is_hp, char *prefix)
{
struct device *dev = card->dev;
enum of_gpio_flags flags;
@@ -522,7 +540,61 @@ int asoc_simple_card_init_jack(struct snd_soc_card *card,
return 0;
}
-EXPORT_SYMBOL_GPL(asoc_simple_card_init_jack);
+EXPORT_SYMBOL_GPL(asoc_simple_init_jack);
+
+int asoc_simple_init_priv(struct asoc_simple_priv *priv,
+ struct link_info *li)
+{
+ struct snd_soc_card *card = simple_priv_to_card(priv);
+ struct device *dev = simple_priv_to_dev(priv);
+ struct snd_soc_dai_link *dai_link;
+ struct simple_dai_props *dai_props;
+ struct asoc_simple_dai *dais;
+ struct snd_soc_codec_conf *cconf = NULL;
+ int i;
+
+ dai_props = devm_kcalloc(dev, li->link, sizeof(*dai_props), GFP_KERNEL);
+ dai_link = devm_kcalloc(dev, li->link, sizeof(*dai_link), GFP_KERNEL);
+ dais = devm_kcalloc(dev, li->dais, sizeof(*dais), GFP_KERNEL);
+ if (!dai_props || !dai_link || !dais)
+ return -ENOMEM;
+
+ if (li->conf) {
+ cconf = devm_kcalloc(dev, li->conf, sizeof(*cconf), GFP_KERNEL);
+ if (!cconf)
+ return -ENOMEM;
+ }
+
+ /*
+ * Use snd_soc_dai_link_component instead of legacy style
+ * It is codec only. but cpu/platform will be supported in the future.
+ * see
+ * soc-core.c :: snd_soc_init_multicodec()
+ *
+ * "platform" might be removed
+ * see
+ * simple-card-utils.c :: asoc_simple_canonicalize_platform()
+ */
+ for (i = 0; i < li->link; i++) {
+ dai_link[i].codecs = &dai_props[i].codecs;
+ dai_link[i].num_codecs = 1;
+ dai_link[i].platforms = &dai_props[i].platforms;
+ dai_link[i].num_platforms = 1;
+ }
+
+ priv->dai_props = dai_props;
+ priv->dai_link = dai_link;
+ priv->dais = dais;
+ priv->codec_conf = cconf;
+
+ card->dai_link = priv->dai_link;
+ card->num_links = li->link;
+ card->codec_conf = cconf;
+ card->num_configs = li->conf;
+
+ return 0;
+}
+EXPORT_SYMBOL_GPL(asoc_simple_init_priv);
/* Module information */
MODULE_AUTHOR("Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>");
diff --git a/sound/soc/generic/simple-card.c b/sound/soc/generic/simple-card.c
index 34de32efc4c4..9b568f578bcd 100644
--- a/sound/soc/generic/simple-card.c
+++ b/sound/soc/generic/simple-card.c
@@ -18,179 +18,98 @@
#define DPCM_SELECTABLE 1
-struct simple_priv {
- struct snd_soc_card snd_card;
- struct simple_dai_props {
- struct asoc_simple_dai *cpu_dai;
- struct asoc_simple_dai *codec_dai;
- struct snd_soc_dai_link_component codecs; /* single codec */
- struct snd_soc_dai_link_component platforms;
- struct asoc_simple_card_data adata;
- struct snd_soc_codec_conf *codec_conf;
- unsigned int mclk_fs;
- } *dai_props;
- struct asoc_simple_jack hp_jack;
- struct asoc_simple_jack mic_jack;
- struct snd_soc_dai_link *dai_link;
- struct asoc_simple_dai *dais;
- struct snd_soc_codec_conf *codec_conf;
-};
-
-struct link_info {
- int dais; /* number of dai */
- int link; /* number of link */
- int conf; /* number of codec_conf */
- int cpu; /* turn for CPU / Codec */
-};
-
-#define simple_priv_to_card(priv) (&(priv)->snd_card)
-#define simple_priv_to_props(priv, i) ((priv)->dai_props + (i))
-#define simple_priv_to_dev(priv) (simple_priv_to_card(priv)->dev)
-#define simple_priv_to_link(priv, i) (simple_priv_to_card(priv)->dai_link + (i))
-
#define DAI "sound-dai"
#define CELL "#sound-dai-cells"
#define PREFIX "simple-audio-card,"
-static int simple_startup(struct snd_pcm_substream *substream)
-{
- struct snd_soc_pcm_runtime *rtd = substream->private_data;
- struct simple_priv *priv = snd_soc_card_get_drvdata(rtd->card);
- struct simple_dai_props *dai_props =
- simple_priv_to_props(priv, rtd->num);
- int ret;
-
- ret = asoc_simple_card_clk_enable(dai_props->cpu_dai);
- if (ret)
- return ret;
-
- ret = asoc_simple_card_clk_enable(dai_props->codec_dai);
- if (ret)
- asoc_simple_card_clk_disable(dai_props->cpu_dai);
-
- return ret;
-}
-
-static void simple_shutdown(struct snd_pcm_substream *substream)
-{
- struct snd_soc_pcm_runtime *rtd = substream->private_data;
- struct simple_priv *priv = snd_soc_card_get_drvdata(rtd->card);
- struct simple_dai_props *dai_props =
- simple_priv_to_props(priv, rtd->num);
-
- asoc_simple_card_clk_disable(dai_props->cpu_dai);
-
- asoc_simple_card_clk_disable(dai_props->codec_dai);
-}
+static const struct snd_soc_ops simple_ops = {
+ .startup = asoc_simple_startup,
+ .shutdown = asoc_simple_shutdown,
+ .hw_params = asoc_simple_hw_params,
+};
-static int simple_set_clk_rate(struct asoc_simple_dai *simple_dai,
- unsigned long rate)
+static int asoc_simple_parse_dai(struct device_node *node,
+ struct snd_soc_dai_link_component *dlc,
+ struct device_node **dai_of_node,
+ const char **dai_name,
+ int *is_single_link)
{
- if (!simple_dai)
- return 0;
-
- if (!simple_dai->clk)
- return 0;
+ struct of_phandle_args args;
+ int ret;
- if (clk_get_rate(simple_dai->clk) == rate)
+ if (!node)
return 0;
- return clk_set_rate(simple_dai->clk, rate);
-}
-
-static int simple_hw_params(struct snd_pcm_substream *substream,
- struct snd_pcm_hw_params *params)
-{
- struct snd_soc_pcm_runtime *rtd = substream->private_data;
- struct snd_soc_dai *codec_dai = rtd->codec_dai;
- struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
- struct simple_priv *priv = snd_soc_card_get_drvdata(rtd->card);
- struct simple_dai_props *dai_props =
- simple_priv_to_props(priv, rtd->num);
- unsigned int mclk, mclk_fs = 0;
- int ret = 0;
-
- if (dai_props->mclk_fs)
- mclk_fs = dai_props->mclk_fs;
-
- if (mclk_fs) {
- mclk = params_rate(params) * mclk_fs;
+ /*
+ * Use snd_soc_dai_link_component instead of legacy style.
+ * It is only for codec, but cpu will be supported in the future.
+ * see
+ * soc-core.c :: snd_soc_init_multicodec()
+ */
+ if (dlc) {
+ dai_name = &dlc->dai_name;
+ dai_of_node = &dlc->of_node;
+ }
- ret = simple_set_clk_rate(dai_props->codec_dai, mclk);
- if (ret < 0)
- return ret;
+ /*
+ * Get node via "sound-dai = <&phandle port>"
+ * it will be used as xxx_of_node on soc_bind_dai_link()
+ */
+ ret = of_parse_phandle_with_args(node, DAI, CELL, 0, &args);
+ if (ret)
+ return ret;
- ret = simple_set_clk_rate(dai_props->cpu_dai, mclk);
+ /* Get dai->name */
+ if (dai_name) {
+ ret = snd_soc_of_get_dai_name(node, dai_name);
if (ret < 0)
return ret;
-
- ret = snd_soc_dai_set_sysclk(codec_dai, 0, mclk,
- SND_SOC_CLOCK_IN);
- if (ret && ret != -ENOTSUPP)
- goto err;
-
- ret = snd_soc_dai_set_sysclk(cpu_dai, 0, mclk,
- SND_SOC_CLOCK_OUT);
- if (ret && ret != -ENOTSUPP)
- goto err;
}
- return 0;
-err:
- return ret;
-}
-
-static const struct snd_soc_ops simple_ops = {
- .startup = simple_startup,
- .shutdown = simple_shutdown,
- .hw_params = simple_hw_params,
-};
-static int simple_dai_init(struct snd_soc_pcm_runtime *rtd)
-{
- struct simple_priv *priv = snd_soc_card_get_drvdata(rtd->card);
- struct simple_dai_props *dai_props = simple_priv_to_props(priv, rtd->num);
- int ret;
+ *dai_of_node = args.np;
- ret = asoc_simple_card_init_dai(rtd->codec_dai,
- dai_props->codec_dai);
- if (ret < 0)
- return ret;
-
- ret = asoc_simple_card_init_dai(rtd->cpu_dai,
- dai_props->cpu_dai);
- if (ret < 0)
- return ret;
+ if (is_single_link)
+ *is_single_link = !args.args_count;
return 0;
}
-static int simple_be_hw_params_fixup(struct snd_soc_pcm_runtime *rtd,
- struct snd_pcm_hw_params *params)
+static void simple_parse_convert(struct device *dev,
+ struct device_node *np,
+ struct asoc_simple_data *adata)
{
- struct simple_priv *priv = snd_soc_card_get_drvdata(rtd->card);
- struct simple_dai_props *dai_props = simple_priv_to_props(priv, rtd->num);
+ struct device_node *top = dev->of_node;
+ struct device_node *node = of_get_parent(np);
- asoc_simple_card_convert_fixup(&dai_props->adata, params);
+ asoc_simple_parse_convert(dev, top, PREFIX, adata);
+ asoc_simple_parse_convert(dev, node, PREFIX, adata);
+ asoc_simple_parse_convert(dev, node, NULL, adata);
+ asoc_simple_parse_convert(dev, np, NULL, adata);
- return 0;
+ of_node_put(node);
}
-static void simple_get_conversion(struct device *dev,
- struct device_node *np,
- struct asoc_simple_card_data *adata)
+static void simple_parse_mclk_fs(struct device_node *top,
+ struct device_node *cpu,
+ struct device_node *codec,
+ struct simple_dai_props *props,
+ char *prefix)
{
- struct device_node *top = dev->of_node;
- struct device_node *node = of_get_parent(np);
+ struct device_node *node = of_get_parent(cpu);
+ char prop[128];
- asoc_simple_card_parse_convert(dev, top, PREFIX, adata);
- asoc_simple_card_parse_convert(dev, node, PREFIX, adata);
- asoc_simple_card_parse_convert(dev, node, NULL, adata);
- asoc_simple_card_parse_convert(dev, np, NULL, adata);
+ 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(cpu, prop, &props->mclk_fs);
+ of_property_read_u32(codec, prop, &props->mclk_fs);
of_node_put(node);
}
-static int simple_dai_link_of_dpcm(struct simple_priv *priv,
+static int simple_dai_link_of_dpcm(struct asoc_simple_priv *priv,
struct device_node *np,
struct device_node *codec,
struct link_info *li,
@@ -203,7 +122,6 @@ static int simple_dai_link_of_dpcm(struct simple_priv *priv,
struct snd_soc_dai_link_component *codecs = dai_link->codecs;
struct device_node *top = dev->of_node;
struct device_node *node = of_get_parent(np);
- char prop[128];
char *prefix = "";
int ret;
@@ -241,22 +159,21 @@ static int simple_dai_link_of_dpcm(struct simple_priv *priv,
dai =
dai_props->cpu_dai = &priv->dais[li->dais++];
- ret = asoc_simple_card_parse_cpu(np, dai_link, DAI, CELL,
- &is_single_links);
+ ret = asoc_simple_parse_cpu(np, dai_link, &is_single_links);
if (ret)
return ret;
- ret = asoc_simple_card_parse_clk_cpu(dev, np, dai_link, dai);
+ ret = asoc_simple_parse_clk_cpu(dev, np, dai_link, dai);
if (ret < 0)
return ret;
- ret = asoc_simple_card_set_dailink_name(dev, dai_link,
- "fe.%s",
- dai_link->cpu_dai_name);
+ ret = asoc_simple_set_dailink_name(dev, dai_link,
+ "fe.%s",
+ dai_link->cpu_dai_name);
if (ret < 0)
return ret;
- asoc_simple_card_canonicalize_cpu(dai_link, is_single_links);
+ asoc_simple_canonicalize_cpu(dai_link, is_single_links);
} else {
struct snd_soc_codec_conf *cconf;
@@ -267,7 +184,7 @@ static int simple_dai_link_of_dpcm(struct simple_priv *priv,
/* BE settings */
dai_link->no_pcm = 1;
- dai_link->be_hw_params_fixup = simple_be_hw_params_fixup;
+ dai_link->be_hw_params_fixup = asoc_simple_be_hw_params_fixup;
dai =
dai_props->codec_dai = &priv->dais[li->dais++];
@@ -275,17 +192,17 @@ static int simple_dai_link_of_dpcm(struct simple_priv *priv,
cconf =
dai_props->codec_conf = &priv->codec_conf[li->conf++];
- ret = asoc_simple_card_parse_codec(np, dai_link, DAI, CELL);
+ ret = asoc_simple_parse_codec(np, dai_link);
if (ret < 0)
return ret;
- ret = asoc_simple_card_parse_clk_codec(dev, np, dai_link, dai);
+ ret = asoc_simple_parse_clk_codec(dev, np, dai_link, dai);
if (ret < 0)
return ret;
- ret = asoc_simple_card_set_dailink_name(dev, dai_link,
- "be.%s",
- codecs->dai_name);
+ ret = asoc_simple_set_dailink_name(dev, dai_link,
+ "be.%s",
+ codecs->dai_name);
if (ret < 0)
return ret;
@@ -298,33 +215,29 @@ static int simple_dai_link_of_dpcm(struct simple_priv *priv,
"prefix");
}
- simple_get_conversion(dev, np, &dai_props->adata);
+ simple_parse_convert(dev, np, &dai_props->adata);
+ simple_parse_mclk_fs(top, np, codec, dai_props, prefix);
- asoc_simple_card_canonicalize_platform(dai_link);
+ asoc_simple_canonicalize_platform(dai_link);
- ret = asoc_simple_card_of_parse_tdm(np, dai);
+ ret = asoc_simple_parse_tdm(np, dai);
if (ret)
return ret;
- snprintf(prop, sizeof(prop), "%smclk-fs", prefix);
- of_property_read_u32(top, PREFIX "mclk-fs", &dai_props->mclk_fs);
- of_property_read_u32(node, prop, &dai_props->mclk_fs);
- of_property_read_u32(np, prop, &dai_props->mclk_fs);
-
- ret = asoc_simple_card_parse_daifmt(dev, node, codec,
- prefix, &dai_link->dai_fmt);
+ ret = asoc_simple_parse_daifmt(dev, node, codec,
+ prefix, &dai_link->dai_fmt);
if (ret < 0)
return ret;
dai_link->dpcm_playback = 1;
dai_link->dpcm_capture = 1;
dai_link->ops = &simple_ops;
- dai_link->init = simple_dai_init;
+ dai_link->init = asoc_simple_dai_init;
return 0;
}
-static int simple_dai_link_of(struct simple_priv *priv,
+static int simple_dai_link_of(struct asoc_simple_priv *priv,
struct device_node *np,
struct device_node *codec,
struct link_info *li,
@@ -370,58 +283,53 @@ static int simple_dai_link_of(struct simple_priv *priv,
codec_dai =
dai_props->codec_dai = &priv->dais[li->dais++];
- ret = asoc_simple_card_parse_daifmt(dev, node, codec,
- prefix, &dai_link->dai_fmt);
+ ret = asoc_simple_parse_daifmt(dev, node, codec,
+ prefix, &dai_link->dai_fmt);
if (ret < 0)
goto dai_link_of_err;
- snprintf(prop, sizeof(prop), "%smclk-fs", prefix);
- of_property_read_u32(top, PREFIX "mclk-fs", &dai_props->mclk_fs);
- of_property_read_u32(node, prop, &dai_props->mclk_fs);
- of_property_read_u32(cpu, prop, &dai_props->mclk_fs);
- of_property_read_u32(codec, prop, &dai_props->mclk_fs);
+ simple_parse_mclk_fs(top, cpu, codec, dai_props, prefix);
- ret = asoc_simple_card_parse_cpu(cpu, dai_link,
- DAI, CELL, &single_cpu);
+ ret = asoc_simple_parse_cpu(cpu, dai_link, &single_cpu);
if (ret < 0)
goto dai_link_of_err;
- ret = asoc_simple_card_parse_codec(codec, dai_link, DAI, CELL);
+ ret = asoc_simple_parse_codec(codec, dai_link);
if (ret < 0)
goto dai_link_of_err;
- ret = asoc_simple_card_parse_platform(plat, dai_link, DAI, CELL);
+ ret = asoc_simple_parse_platform(plat, dai_link);
if (ret < 0)
goto dai_link_of_err;
- ret = asoc_simple_card_of_parse_tdm(cpu, cpu_dai);
+ ret = asoc_simple_parse_tdm(cpu, cpu_dai);
if (ret < 0)
goto dai_link_of_err;
- ret = asoc_simple_card_of_parse_tdm(codec, codec_dai);
+ ret = asoc_simple_parse_tdm(codec, codec_dai);
if (ret < 0)
goto dai_link_of_err;
- ret = asoc_simple_card_parse_clk_cpu(dev, cpu, dai_link, cpu_dai);
+ ret = asoc_simple_parse_clk_cpu(dev, cpu, dai_link, cpu_dai);
if (ret < 0)
goto dai_link_of_err;
- ret = asoc_simple_card_parse_clk_codec(dev, codec, dai_link, codec_dai);
+ ret = asoc_simple_parse_clk_codec(dev, codec, dai_link, codec_dai);
if (ret < 0)
goto dai_link_of_err;
- ret = asoc_simple_card_set_dailink_name(dev, dai_link,
- "%s-%s",
- dai_link->cpu_dai_name,
- dai_link->codecs->dai_name);
+ ret = asoc_simple_set_dailink_name(dev, dai_link,
+ "%s-%s",
+ dai_link->cpu_dai_name,
+ dai_link->codecs->dai_name);
if (ret < 0)
goto dai_link_of_err;
dai_link->ops = &simple_ops;
- dai_link->init = simple_dai_init;
+ dai_link->init = asoc_simple_dai_init;
- asoc_simple_card_canonicalize_cpu(dai_link, single_cpu);
- asoc_simple_card_canonicalize_platform(dai_link);
+ asoc_simple_canonicalize_cpu(dai_link, single_cpu);
+ asoc_simple_canonicalize_platform(dai_link);
dai_link_of_err:
of_node_put(plat);
@@ -430,13 +338,13 @@ dai_link_of_err:
return ret;
}
-static int simple_for_each_link(struct simple_priv *priv,
+static int simple_for_each_link(struct asoc_simple_priv *priv,
struct link_info *li,
- int (*func_noml)(struct simple_priv *priv,
+ int (*func_noml)(struct asoc_simple_priv *priv,
struct device_node *np,
struct device_node *codec,
struct link_info *li, bool is_top),
- int (*func_dpcm)(struct simple_priv *priv,
+ int (*func_dpcm)(struct asoc_simple_priv *priv,
struct device_node *np,
struct device_node *codec,
struct link_info *li, bool is_top))
@@ -457,7 +365,7 @@ static int simple_for_each_link(struct simple_priv *priv,
/* loop for all dai-link */
do {
- struct asoc_simple_card_data adata;
+ struct asoc_simple_data adata;
struct device_node *codec;
struct device_node *np;
int num = of_get_child_count(node);
@@ -475,7 +383,7 @@ static int simple_for_each_link(struct simple_priv *priv,
/* get convert-xxx property */
memset(&adata, 0, sizeof(adata));
for_each_child_of_node(node, np)
- simple_get_conversion(dev, np, &adata);
+ simple_parse_convert(dev, np, &adata);
/* loop for all CPU/Codec node */
for_each_child_of_node(node, np) {
@@ -507,7 +415,7 @@ static int simple_for_each_link(struct simple_priv *priv,
}
static int simple_parse_aux_devs(struct device_node *node,
- struct simple_priv *priv)
+ struct asoc_simple_priv *priv)
{
struct device *dev = simple_priv_to_dev(priv);
struct device_node *aux_node;
@@ -537,7 +445,7 @@ static int simple_parse_aux_devs(struct device_node *node,
return 0;
}
-static int simple_parse_of(struct simple_priv *priv)
+static int simple_parse_of(struct asoc_simple_priv *priv)
{
struct device *dev = simple_priv_to_dev(priv);
struct device_node *top = dev->of_node;
@@ -548,11 +456,15 @@ static int simple_parse_of(struct simple_priv *priv)
if (!top)
return -EINVAL;
- ret = asoc_simple_card_of_parse_widgets(card, PREFIX);
+ ret = asoc_simple_parse_widgets(card, PREFIX);
if (ret < 0)
return ret;
- ret = asoc_simple_card_of_parse_routing(card, PREFIX);
+ ret = asoc_simple_parse_routing(card, PREFIX);
+ if (ret < 0)
+ return ret;
+
+ ret = asoc_simple_parse_pin_switches(card, PREFIX);
if (ret < 0)
return ret;
@@ -578,7 +490,7 @@ static int simple_parse_of(struct simple_priv *priv)
return ret;
}
- ret = asoc_simple_card_parse_card_name(card, PREFIX);
+ ret = asoc_simple_parse_card_name(card, PREFIX);
if (ret < 0)
return ret;
@@ -587,7 +499,7 @@ static int simple_parse_of(struct simple_priv *priv)
return ret;
}
-static int simple_count_noml(struct simple_priv *priv,
+static int simple_count_noml(struct asoc_simple_priv *priv,
struct device_node *np,
struct device_node *codec,
struct link_info *li, bool is_top)
@@ -599,7 +511,7 @@ static int simple_count_noml(struct simple_priv *priv,
return 0;
}
-static int simple_count_dpcm(struct simple_priv *priv,
+static int simple_count_dpcm(struct asoc_simple_priv *priv,
struct device_node *np,
struct device_node *codec,
struct link_info *li, bool is_top)
@@ -612,7 +524,7 @@ static int simple_count_dpcm(struct simple_priv *priv,
return 0;
}
-static void simple_get_dais_count(struct simple_priv *priv,
+static void simple_get_dais_count(struct asoc_simple_priv *priv,
struct link_info *li)
{
struct device *dev = simple_priv_to_dev(priv);
@@ -681,14 +593,14 @@ static void simple_get_dais_count(struct simple_priv *priv,
static int simple_soc_probe(struct snd_soc_card *card)
{
- struct simple_priv *priv = snd_soc_card_get_drvdata(card);
+ struct asoc_simple_priv *priv = snd_soc_card_get_drvdata(card);
int ret;
- ret = asoc_simple_card_init_hp(card, &priv->hp_jack, PREFIX);
+ ret = asoc_simple_init_hp(card, &priv->hp_jack, PREFIX);
if (ret < 0)
return ret;
- ret = asoc_simple_card_init_mic(card, &priv->mic_jack, PREFIX);
+ ret = asoc_simple_init_mic(card, &priv->mic_jack, PREFIX);
if (ret < 0)
return ret;
@@ -697,16 +609,12 @@ static int simple_soc_probe(struct snd_soc_card *card)
static int simple_probe(struct platform_device *pdev)
{
- struct simple_priv *priv;
- struct snd_soc_dai_link *dai_link;
- struct simple_dai_props *dai_props;
- struct asoc_simple_dai *dais;
+ struct asoc_simple_priv *priv;
struct device *dev = &pdev->dev;
struct device_node *np = dev->of_node;
struct snd_soc_card *card;
- struct snd_soc_codec_conf *cconf;
struct link_info li;
- int ret, i;
+ int ret;
/* Allocate the private data and the DAI link array */
priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL);
@@ -723,35 +631,9 @@ static int simple_probe(struct platform_device *pdev)
if (!li.link || !li.dais)
return -EINVAL;
- dai_props = devm_kcalloc(dev, li.link, sizeof(*dai_props), GFP_KERNEL);
- dai_link = devm_kcalloc(dev, li.link, sizeof(*dai_link), GFP_KERNEL);
- dais = devm_kcalloc(dev, li.dais, sizeof(*dais), GFP_KERNEL);
- cconf = devm_kcalloc(dev, li.conf, sizeof(*cconf), GFP_KERNEL);
- if (!dai_props || !dai_link || !dais)
- return -ENOMEM;
-
- /*
- * Use snd_soc_dai_link_component instead of legacy style
- * It is codec only. but cpu/platform will be supported in the future.
- * see
- * soc-core.c :: snd_soc_init_multicodec()
- */
- for (i = 0; i < li.link; i++) {
- dai_link[i].codecs = &dai_props[i].codecs;
- dai_link[i].num_codecs = 1;
- dai_link[i].platforms = &dai_props[i].platforms;
- dai_link[i].num_platforms = 1;
- }
-
- priv->dai_props = dai_props;
- priv->dai_link = dai_link;
- priv->dais = dais;
- priv->codec_conf = cconf;
-
- card->dai_link = priv->dai_link;
- card->num_links = li.link;
- card->codec_conf = cconf;
- card->num_configs = li.conf;
+ ret = asoc_simple_init_priv(priv, &li);
+ if (ret < 0)
+ return ret;
if (np && of_device_is_available(np)) {
@@ -766,6 +648,9 @@ static int simple_probe(struct platform_device *pdev)
struct asoc_simple_card_info *cinfo;
struct snd_soc_dai_link_component *codecs;
struct snd_soc_dai_link_component *platform;
+ struct snd_soc_dai_link *dai_link = priv->dai_link;
+ struct simple_dai_props *dai_props = priv->dai_props;
+
int dai_idx = 0;
cinfo = dev->platform_data;
@@ -798,22 +683,24 @@ static int simple_probe(struct platform_device *pdev)
dai_link->stream_name = cinfo->name;
dai_link->cpu_dai_name = cinfo->cpu_dai.name;
dai_link->dai_fmt = cinfo->daifmt;
- dai_link->init = simple_dai_init;
- memcpy(priv->dai_props->cpu_dai, &cinfo->cpu_dai,
- sizeof(*priv->dai_props->cpu_dai));
- memcpy(priv->dai_props->codec_dai, &cinfo->codec_dai,
- sizeof(*priv->dai_props->codec_dai));
+ dai_link->init = asoc_simple_dai_init;
+ memcpy(dai_props->cpu_dai, &cinfo->cpu_dai,
+ sizeof(*dai_props->cpu_dai));
+ memcpy(dai_props->codec_dai, &cinfo->codec_dai,
+ sizeof(*dai_props->codec_dai));
}
snd_soc_card_set_drvdata(card, priv);
+ asoc_simple_debug_info(priv);
+
ret = devm_snd_soc_register_card(dev, card);
if (ret < 0)
goto err;
return 0;
err:
- asoc_simple_card_clean_reference(card);
+ asoc_simple_clean_reference(card);
return ret;
}
@@ -822,7 +709,7 @@ static int simple_remove(struct platform_device *pdev)
{
struct snd_soc_card *card = platform_get_drvdata(pdev);
- return asoc_simple_card_clean_reference(card);
+ return asoc_simple_clean_reference(card);
}
static const struct of_device_id simple_of_match[] = {