aboutsummaryrefslogtreecommitdiffstats
path: root/sound/soc/generic/simple-card.c
diff options
context:
space:
mode:
Diffstat (limited to 'sound/soc/generic/simple-card.c')
-rw-r--r--sound/soc/generic/simple-card.c39
1 files changed, 35 insertions, 4 deletions
diff --git a/sound/soc/generic/simple-card.c b/sound/soc/generic/simple-card.c
index 98f97e543c29..03a7fdcdf114 100644
--- a/sound/soc/generic/simple-card.c
+++ b/sound/soc/generic/simple-card.c
@@ -24,9 +24,32 @@ struct simple_card_data {
24 struct asoc_simple_dai cpu_dai; 24 struct asoc_simple_dai cpu_dai;
25 struct asoc_simple_dai codec_dai; 25 struct asoc_simple_dai codec_dai;
26 } *dai_props; 26 } *dai_props;
27 unsigned int mclk_fs;
27 struct snd_soc_dai_link dai_link[]; /* dynamically allocated */ 28 struct snd_soc_dai_link dai_link[]; /* dynamically allocated */
28}; 29};
29 30
31static int asoc_simple_card_hw_params(struct snd_pcm_substream *substream,
32 struct snd_pcm_hw_params *params)
33{
34 struct snd_soc_pcm_runtime *rtd = substream->private_data;
35 struct snd_soc_dai *codec_dai = rtd->codec_dai;
36 struct simple_card_data *priv = snd_soc_card_get_drvdata(rtd->card);
37 unsigned int mclk;
38 int ret = 0;
39
40 if (priv->mclk_fs) {
41 mclk = params_rate(params) * priv->mclk_fs;
42 ret = snd_soc_dai_set_sysclk(codec_dai, 0, mclk,
43 SND_SOC_CLOCK_IN);
44 }
45
46 return ret;
47}
48
49static struct snd_soc_ops asoc_simple_card_ops = {
50 .hw_params = asoc_simple_card_hw_params,
51};
52
30static int __asoc_simple_card_dai_init(struct snd_soc_dai *dai, 53static int __asoc_simple_card_dai_init(struct snd_soc_dai *dai,
31 struct asoc_simple_dai *set) 54 struct asoc_simple_dai *set)
32{ 55{
@@ -144,7 +167,8 @@ asoc_simple_card_sub_parse_of(struct device_node *np,
144static int simple_card_dai_link_of(struct device_node *node, 167static int simple_card_dai_link_of(struct device_node *node,
145 struct device *dev, 168 struct device *dev,
146 struct snd_soc_dai_link *dai_link, 169 struct snd_soc_dai_link *dai_link,
147 struct simple_dai_props *dai_props) 170 struct simple_dai_props *dai_props,
171 bool is_top_level_node)
148{ 172{
149 struct device_node *np = NULL; 173 struct device_node *np = NULL;
150 struct device_node *bitclkmaster = NULL; 174 struct device_node *bitclkmaster = NULL;
@@ -155,7 +179,8 @@ static int simple_card_dai_link_of(struct device_node *node,
155 char *prefix = ""; 179 char *prefix = "";
156 int ret; 180 int ret;
157 181
158 prefix = "simple-audio-card,"; 182 if (is_top_level_node)
183 prefix = "simple-audio-card,";
159 184
160 daifmt = snd_soc_of_parse_daifmt(node, prefix, 185 daifmt = snd_soc_of_parse_daifmt(node, prefix,
161 &bitclkmaster, &framemaster); 186 &bitclkmaster, &framemaster);
@@ -249,6 +274,7 @@ static int simple_card_dai_link_of(struct device_node *node,
249 sprintf(name, "%s-%s", dai_link->cpu_dai_name, 274 sprintf(name, "%s-%s", dai_link->cpu_dai_name,
250 dai_link->codec_dai_name); 275 dai_link->codec_dai_name);
251 dai_link->name = dai_link->stream_name = name; 276 dai_link->name = dai_link->stream_name = name;
277 dai_link->ops = &asoc_simple_card_ops;
252 278
253 dev_dbg(dev, "\tname : %s\n", dai_link->stream_name); 279 dev_dbg(dev, "\tname : %s\n", dai_link->stream_name);
254 dev_dbg(dev, "\tcpu : %s / %04x / %d\n", 280 dev_dbg(dev, "\tcpu : %s / %04x / %d\n",
@@ -298,6 +324,10 @@ static int asoc_simple_card_parse_of(struct device_node *node,
298 return ret; 324 return ret;
299 } 325 }
300 326
327 /* Factor to mclk, used in hw_params() */
328 of_property_read_u32(node, "simple-audio-card,mclk-fs",
329 &priv->mclk_fs);
330
301 dev_dbg(dev, "New simple-card: %s\n", priv->snd_card.name ? 331 dev_dbg(dev, "New simple-card: %s\n", priv->snd_card.name ?
302 priv->snd_card.name : ""); 332 priv->snd_card.name : "");
303 333
@@ -307,14 +337,15 @@ static int asoc_simple_card_parse_of(struct device_node *node,
307 for (i = 0; (np = of_get_next_child(node, np)); i++) { 337 for (i = 0; (np = of_get_next_child(node, np)); i++) {
308 dev_dbg(dev, "\tlink %d:\n", i); 338 dev_dbg(dev, "\tlink %d:\n", i);
309 ret = simple_card_dai_link_of(np, dev, dai_link + i, 339 ret = simple_card_dai_link_of(np, dev, dai_link + i,
310 dai_props + i); 340 dai_props + i, false);
311 if (ret < 0) { 341 if (ret < 0) {
312 of_node_put(np); 342 of_node_put(np);
313 return ret; 343 return ret;
314 } 344 }
315 } 345 }
316 } else { 346 } else {
317 ret = simple_card_dai_link_of(node, dev, dai_link, dai_props); 347 ret = simple_card_dai_link_of(node, dev, dai_link, dai_props,
348 true);
318 if (ret < 0) 349 if (ret < 0)
319 return ret; 350 return ret;
320 } 351 }