diff options
author | Andrew Lunn <andrew@lunn.ch> | 2014-05-22 11:31:49 -0400 |
---|---|---|
committer | Mark Brown <broonie@linaro.org> | 2014-05-26 09:29:30 -0400 |
commit | 2942a0e285c46587a1025f12597df63ec04d08c6 (patch) | |
tree | 4376a294b4b8be8093b46650a9c0a3e26873a460 /sound | |
parent | 648722155dc081b019ab0ef548bbebde760a2b83 (diff) |
ASoC: simple-card: Support setting mclk via a fixed factor
Some platforms require that the codecs mclk is a fixed multiplication
factor of the audio stream rate. Add a optional property to the
binding to hold this factor and implement a hw_params() function to
make use of it.
Signed-off-by: Andrew Lunn <andrew@lunn.ch>
Signed-off-by: Mark Brown <broonie@linaro.org>
Diffstat (limited to 'sound')
-rw-r--r-- | sound/soc/generic/simple-card.c | 28 |
1 files changed, 28 insertions, 0 deletions
diff --git a/sound/soc/generic/simple-card.c b/sound/soc/generic/simple-card.c index 06fe0e22b267..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 | { |
@@ -251,6 +274,7 @@ static int simple_card_dai_link_of(struct device_node *node, | |||
251 | sprintf(name, "%s-%s", dai_link->cpu_dai_name, | 274 | sprintf(name, "%s-%s", dai_link->cpu_dai_name, |
252 | dai_link->codec_dai_name); | 275 | dai_link->codec_dai_name); |
253 | 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; | ||
254 | 278 | ||
255 | dev_dbg(dev, "\tname : %s\n", dai_link->stream_name); | 279 | dev_dbg(dev, "\tname : %s\n", dai_link->stream_name); |
256 | dev_dbg(dev, "\tcpu : %s / %04x / %d\n", | 280 | dev_dbg(dev, "\tcpu : %s / %04x / %d\n", |
@@ -300,6 +324,10 @@ static int asoc_simple_card_parse_of(struct device_node *node, | |||
300 | return ret; | 324 | return ret; |
301 | } | 325 | } |
302 | 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 | |||
303 | 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 ? |
304 | priv->snd_card.name : ""); | 332 | priv->snd_card.name : ""); |
305 | 333 | ||