summaryrefslogtreecommitdiff
path: root/sound/soc/generic
diff options
context:
space:
mode:
Diffstat (limited to 'sound/soc/generic')
-rw-r--r--sound/soc/generic/Makefile1
-rw-r--r--sound/soc/generic/audio-graph-card.c60
-rw-r--r--sound/soc/generic/audio-graph-scu-card.c18
-rw-r--r--sound/soc/generic/simple-card-utils.c19
-rw-r--r--sound/soc/generic/simple-card.c10
-rw-r--r--sound/soc/generic/simple-scu-card.c5
6 files changed, 74 insertions, 39 deletions
diff --git a/sound/soc/generic/Makefile b/sound/soc/generic/Makefile
index 9e000523a3b4..9dec293a4c4d 100644
--- a/sound/soc/generic/Makefile
+++ b/sound/soc/generic/Makefile
@@ -1,3 +1,4 @@
+# SPDX-License-Identifier: GPL-2.0
snd-soc-simple-card-utils-objs := simple-card-utils.o
snd-soc-simple-card-objs := simple-card.o
snd-soc-simple-scu-card-objs := simple-scu-card.o
diff --git a/sound/soc/generic/audio-graph-card.c b/sound/soc/generic/audio-graph-card.c
index 105ec3a6e30d..1b6164249341 100644
--- a/sound/soc/generic/audio-graph-card.c
+++ b/sound/soc/generic/audio-graph-card.c
@@ -29,7 +29,9 @@ struct graph_card_data {
struct graph_dai_props {
struct asoc_simple_dai cpu_dai;
struct asoc_simple_dai codec_dai;
+ unsigned int mclk_fs;
} *dai_props;
+ unsigned int mclk_fs;
struct snd_soc_dai_link *dai_link;
struct gpio_desc *pa_gpio;
};
@@ -95,9 +97,43 @@ static void asoc_graph_card_shutdown(struct snd_pcm_substream *substream)
asoc_simple_card_clk_disable(&dai_props->codec_dai);
}
-static struct snd_soc_ops asoc_graph_card_ops = {
+static int asoc_graph_card_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 graph_card_data *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 (priv->mclk_fs)
+ mclk_fs = priv->mclk_fs;
+ else 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;
+ }
+ return 0;
+err:
+ return ret;
+}
+
+static const struct snd_soc_ops asoc_graph_card_ops = {
.startup = asoc_graph_card_startup,
.shutdown = asoc_graph_card_shutdown,
+ .hw_params = asoc_graph_card_hw_params,
};
static int asoc_graph_card_dai_init(struct snd_soc_pcm_runtime *rtd)
@@ -146,10 +182,7 @@ static int asoc_graph_card_dai_link_of(struct device_node *cpu_port,
if (ret < 0)
goto dai_link_of_err;
- /*
- * we need to consider "mclk-fs" around here
- * see simple-card
- */
+ of_property_read_u32(rcpu_ep, "mclk-fs", &dai_props->mclk_fs);
ret = asoc_simple_card_parse_graph_cpu(cpu_ep, dai_link);
if (ret < 0)
@@ -217,16 +250,16 @@ static int asoc_graph_card_parse_of(struct graph_card_data *priv)
if (ret < 0)
return ret;
- /*
- * we need to consider "mclk-fs" around here
- * see simple-card
- */
+ /* Factor to mclk, used in hw_params() */
+ of_property_read_u32(node, "mclk-fs", &priv->mclk_fs);
of_for_each_phandle(&it, rc, node, "dais", NULL, 0) {
ret = asoc_graph_card_dai_link_of(it.node, priv, idx++);
- of_node_put(it.node);
- if (ret < 0)
+ if (ret < 0) {
+ of_node_put(it.node);
+
return ret;
+ }
}
return asoc_simple_card_parse_card_name(card, NULL);
@@ -239,10 +272,8 @@ static int asoc_graph_get_dais_count(struct device *dev)
int count = 0;
int rc;
- of_for_each_phandle(&it, rc, node, "dais", NULL, 0) {
+ of_for_each_phandle(&it, rc, node, "dais", NULL, 0)
count++;
- of_node_put(it.node);
- }
return count;
}
@@ -325,6 +356,7 @@ MODULE_DEVICE_TABLE(of, asoc_graph_of_match);
static struct platform_driver asoc_graph_card = {
.driver = {
.name = "asoc-audio-graph-card",
+ .pm = &snd_soc_pm_ops,
.of_match_table = asoc_graph_of_match,
},
.probe = asoc_graph_card_probe,
diff --git a/sound/soc/generic/audio-graph-scu-card.c b/sound/soc/generic/audio-graph-scu-card.c
index dcd2df37bc3b..a967aa143d51 100644
--- a/sound/soc/generic/audio-graph-scu-card.c
+++ b/sound/soc/generic/audio-graph-scu-card.c
@@ -56,7 +56,7 @@ static void asoc_graph_card_shutdown(struct snd_pcm_substream *substream)
asoc_simple_card_clk_disable(dai_props);
}
-static struct snd_soc_ops asoc_graph_card_ops = {
+static const struct snd_soc_ops asoc_graph_card_ops = {
.startup = asoc_graph_card_startup,
.shutdown = asoc_graph_card_shutdown,
};
@@ -215,7 +215,6 @@ static int asoc_graph_card_parse_of(struct graph_card_data *priv)
codec_ep = of_graph_get_remote_endpoint(cpu_ep);
rcpu_ep = of_graph_get_remote_endpoint(codec_ep);
- of_node_put(cpu_port);
of_node_put(cpu_ep);
of_node_put(codec_ep);
of_node_put(rcpu_ep);
@@ -232,8 +231,10 @@ static int asoc_graph_card_parse_of(struct graph_card_data *priv)
ret = asoc_simple_card_parse_daifmt(dev, cpu_ep, codec_ep,
NULL, &daifmt);
- if (ret < 0)
+ if (ret < 0) {
+ of_node_put(cpu_port);
goto parse_of_err;
+ }
}
dai_idx = 0;
@@ -250,7 +251,6 @@ static int asoc_graph_card_parse_of(struct graph_card_data *priv)
codec_ep = of_graph_get_remote_endpoint(cpu_ep);
codec_port = of_graph_get_port_parent(codec_ep);
- of_node_put(cpu_port);
of_node_put(cpu_ep);
of_node_put(codec_ep);
of_node_put(codec_port);
@@ -266,13 +266,17 @@ static int asoc_graph_card_parse_of(struct graph_card_data *priv)
/* Back-End (= Codec) */
ret = asoc_graph_card_dai_link_of(codec_ep, priv, daifmt, dai_idx++, 0);
- if (ret < 0)
+ if (ret < 0) {
+ of_node_put(cpu_port);
goto parse_of_err;
+ }
} else {
/* Front-End (= CPU) */
ret = asoc_graph_card_dai_link_of(cpu_ep, priv, daifmt, dai_idx++, 1);
- if (ret < 0)
+ if (ret < 0) {
+ of_node_put(cpu_port);
goto parse_of_err;
+ }
}
}
}
@@ -306,7 +310,6 @@ static int asoc_graph_get_dais_count(struct device *dev)
codec_ep = of_graph_get_remote_endpoint(cpu_ep);
codec_port = of_graph_get_port_parent(codec_ep);
- of_node_put(cpu_port);
of_node_put(cpu_ep);
of_node_put(codec_ep);
of_node_put(codec_port);
@@ -398,6 +401,7 @@ MODULE_DEVICE_TABLE(of, asoc_graph_of_match);
static struct platform_driver asoc_graph_card = {
.driver = {
.name = "asoc-audio-graph-scu-card",
+ .pm = &snd_soc_pm_ops,
.of_match_table = asoc_graph_of_match,
},
.probe = asoc_graph_card_probe,
diff --git a/sound/soc/generic/simple-card-utils.c b/sound/soc/generic/simple-card-utils.c
index 26d64fa40c9c..3751a07de6aa 100644
--- a/sound/soc/generic/simple-card-utils.c
+++ b/sound/soc/generic/simple-card-utils.c
@@ -132,7 +132,7 @@ int asoc_simple_card_parse_card_name(struct snd_soc_card *card,
/* Parse the card name from DT */
ret = snd_soc_of_parse_card_name(card, "label");
- if (ret < 0) {
+ if (ret < 0 || !card->name) {
char prop[128];
snprintf(prop, sizeof(prop), "%sname", prefix);
@@ -196,7 +196,11 @@ int asoc_simple_card_parse_clk(struct device *dev,
simple_dai->sysclk = clk_get_rate(clk);
}
- dev_dbg(dev, "%s : sysclk = %d\n", name, simple_dai->sysclk);
+ 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", name,
+ simple_dai->sysclk, simple_dai->clk_direction);
return 0;
}
@@ -263,6 +267,9 @@ static int asoc_simple_card_get_dai_id(struct device_node *ep)
id = i;
i++;
}
+
+ of_node_put(node);
+
if (id < 0)
return -ENODEV;
@@ -282,11 +289,6 @@ int asoc_simple_card_parse_graph_dai(struct device_node *ep,
if (!dai_name)
return 0;
- /*
- * of_graph_get_port_parent() will call
- * of_node_put(). So, call of_node_get() here
- */
- of_node_get(ep);
node = of_graph_get_port_parent(ep);
/* Get dai->name */
@@ -310,7 +312,8 @@ int asoc_simple_card_init_dai(struct snd_soc_dai *dai,
int ret;
if (simple_dai->sysclk) {
- ret = snd_soc_dai_set_sysclk(dai, 0, simple_dai->sysclk, 0);
+ ret = snd_soc_dai_set_sysclk(dai, 0, simple_dai->sysclk,
+ simple_dai->clk_direction);
if (ret && ret != -ENOTSUPP) {
dev_err(dai->dev, "simple-card: set_sysclk error\n");
return ret;
diff --git a/sound/soc/generic/simple-card.c b/sound/soc/generic/simple-card.c
index dfaf48ff88b0..6959a74a6f49 100644
--- a/sound/soc/generic/simple-card.c
+++ b/sound/soc/generic/simple-card.c
@@ -104,12 +104,6 @@ static int asoc_simple_card_init_jack(struct snd_soc_card *card,
return 0;
}
-static void asoc_simple_card_remove_jack(struct asoc_simple_jack *sjack)
-{
- if (gpio_is_valid(sjack->gpio.gpio))
- snd_soc_jack_free_gpios(&sjack->jack, 1, &sjack->gpio);
-}
-
static int asoc_simple_card_startup(struct snd_pcm_substream *substream)
{
struct snd_soc_pcm_runtime *rtd = substream->private_data;
@@ -493,10 +487,6 @@ err:
static int asoc_simple_card_remove(struct platform_device *pdev)
{
struct snd_soc_card *card = platform_get_drvdata(pdev);
- struct simple_card_data *priv = snd_soc_card_get_drvdata(card);
-
- asoc_simple_card_remove_jack(&priv->hp_jack);
- asoc_simple_card_remove_jack(&priv->mic_jack);
return asoc_simple_card_clean_reference(card);
}
diff --git a/sound/soc/generic/simple-scu-card.c b/sound/soc/generic/simple-scu-card.c
index a75b385455c4..48606c63562a 100644
--- a/sound/soc/generic/simple-scu-card.c
+++ b/sound/soc/generic/simple-scu-card.c
@@ -191,6 +191,10 @@ static int asoc_simple_card_parse_of(struct simple_card_data *priv)
if (!node)
return -EINVAL;
+ ret = asoc_simple_card_of_parse_widgets(card, PREFIX);
+ if (ret < 0)
+ return ret;
+
ret = asoc_simple_card_of_parse_routing(card, PREFIX, 0);
if (ret < 0)
return ret;
@@ -296,6 +300,7 @@ MODULE_DEVICE_TABLE(of, asoc_simple_of_match);
static struct platform_driver asoc_simple_card = {
.driver = {
.name = "simple-scu-audio-card",
+ .pm = &snd_soc_pm_ops,
.of_match_table = asoc_simple_of_match,
},
.probe = asoc_simple_card_probe,