struct asoc_simple_dai cpu_dai;
struct asoc_simple_dai codec_dai;
} *dai_props;
+ unsigned int mclk_fs;
struct snd_soc_dai_link dai_link[]; /* dynamically allocated */
};
+static int asoc_simple_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 simple_card_data *priv = snd_soc_card_get_drvdata(rtd->card);
+ unsigned int mclk;
+ int ret = 0;
+
+ if (priv->mclk_fs) {
+ mclk = params_rate(params) * priv->mclk_fs;
+ ret = snd_soc_dai_set_sysclk(codec_dai, 0, mclk,
+ SND_SOC_CLOCK_IN);
+ }
+
+ return ret;
+}
+
+static struct snd_soc_ops asoc_simple_card_ops = {
+ .hw_params = asoc_simple_card_hw_params,
+};
+
static int __asoc_simple_card_dai_init(struct snd_soc_dai *dai,
struct asoc_simple_dai *set)
{
static int asoc_simple_card_dai_init(struct snd_soc_pcm_runtime *rtd)
{
- struct simple_card_data *priv =
- snd_soc_card_get_drvdata(rtd->card);
+ struct simple_card_data *priv = snd_soc_card_get_drvdata(rtd->card);
struct snd_soc_dai *codec = rtd->codec_dai;
struct snd_soc_dai *cpu = rtd->cpu_dai;
struct simple_dai_props *dai_props;
static int simple_card_dai_link_of(struct device_node *node,
struct device *dev,
struct snd_soc_dai_link *dai_link,
- struct simple_dai_props *dai_props)
+ struct simple_dai_props *dai_props,
+ bool is_top_level_node)
{
struct device_node *np = NULL;
struct device_node *bitclkmaster = NULL;
char *prefix = "";
int ret;
- prefix = "simple-audio-card,";
+ if (is_top_level_node)
+ prefix = "simple-audio-card,";
daifmt = snd_soc_of_parse_daifmt(node, prefix,
&bitclkmaster, &framemaster);
np = of_get_child_by_name(node, prop);
if (!np) {
ret = -EINVAL;
- dev_err(dev, "%s: Can't find simple-audio-card,cpu DT node\n",
- __func__);
+ dev_err(dev, "%s: Can't find %s DT node\n", __func__, prop);
goto dai_link_of_err;
}
goto dai_link_of_err;
dai_props->cpu_dai.fmt = daifmt;
- switch (((np == bitclkmaster)<<4)|(np == framemaster)) {
+ switch (((np == bitclkmaster) << 4) | (np == framemaster)) {
case 0x11:
dai_props->cpu_dai.fmt |= SND_SOC_DAIFMT_CBS_CFS;
break;
np = of_get_child_by_name(node, prop);
if (!np) {
ret = -EINVAL;
- dev_err(dev, "%s: Can't find simple-audio-card,codec DT node\n",
- __func__);
+ dev_err(dev, "%s: Can't find %s DT node\n", __func__, prop);
goto dai_link_of_err;
}
(daifmt & ~SND_SOC_DAIFMT_CLOCK_MASK);
} else {
dai_props->codec_dai.fmt = daifmt;
- switch (((np == bitclkmaster)<<4)|(np == framemaster)) {
+ switch (((np == bitclkmaster) << 4) | (np == framemaster)) {
case 0x11:
dai_props->codec_dai.fmt |= SND_SOC_DAIFMT_CBM_CFM;
break;
}
if (!dai_link->cpu_dai_name || !dai_link->codec_dai_name) {
- ret = -EINVAL;
- goto dai_link_of_err;
+ ret = -EINVAL;
+ goto dai_link_of_err;
}
/* simple-card assumes platform == cpu */
sprintf(name, "%s-%s", dai_link->cpu_dai_name,
dai_link->codec_dai_name);
dai_link->name = dai_link->stream_name = name;
+ dai_link->ops = &asoc_simple_card_ops;
dev_dbg(dev, "\tname : %s\n", dai_link->stream_name);
dev_dbg(dev, "\tcpu : %s / %04x / %d\n",
return ret;
}
+ /* Factor to mclk, used in hw_params() */
+ of_property_read_u32(node, "simple-audio-card,mclk-fs",
+ &priv->mclk_fs);
+
dev_dbg(dev, "New simple-card: %s\n", priv->snd_card.name ?
priv->snd_card.name : "");
for (i = 0; (np = of_get_next_child(node, np)); i++) {
dev_dbg(dev, "\tlink %d:\n", i);
ret = simple_card_dai_link_of(np, dev, dai_link + i,
- dai_props + i);
+ dai_props + i, false);
if (ret < 0) {
of_node_put(np);
return ret;
}
}
} else {
- ret = simple_card_dai_link_of(node, dev, dai_link, dai_props);
+ ret = simple_card_dai_link_of(node, dev, dai_link, dai_props,
+ true);
if (ret < 0)
return ret;
}
return -EINVAL;
}
- if (!cinfo->name ||
- !cinfo->codec_dai.name ||
- !cinfo->codec ||
- !cinfo->platform ||
+ if (!cinfo->name ||
+ !cinfo->codec_dai.name ||
+ !cinfo->codec ||
+ !cinfo->platform ||
!cinfo->cpu_dai.name) {
dev_err(dev, "insufficient asoc_simple_card_info settings\n");
return -EINVAL;
static struct platform_driver asoc_simple_card = {
.driver = {
- .name = "asoc-simple-card",
+ .name = "asoc-simple-card",
.owner = THIS_MODULE,
.of_match_table = asoc_simple_of_match,
},
- .probe = asoc_simple_card_probe,
+ .probe = asoc_simple_card_probe,
};
module_platform_driver(asoc_simple_card);