diff options
Diffstat (limited to 'sound/soc/generic/simple-card.c')
-rw-r--r-- | sound/soc/generic/simple-card.c | 39 |
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 | ||
31 | static 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 | |||
49 | static struct snd_soc_ops asoc_simple_card_ops = { | ||
50 | .hw_params = asoc_simple_card_hw_params, | ||
51 | }; | ||
52 | |||
30 | static int __asoc_simple_card_dai_init(struct snd_soc_dai *dai, | 53 | static 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, | |||
144 | static int simple_card_dai_link_of(struct device_node *node, | 167 | static 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 | } |