diff options
author | Kuninori Morimoto <kuninori.morimoto.gx@renesas.com> | 2017-06-16 01:47:34 +0000 |
---|---|---|
committer | Mark Brown <broonie@kernel.org> | 2017-06-16 17:56:41 +0100 |
commit | 907cd8809eebccc57a6a3ee9fa87b7602e72df38 (patch) | |
tree | 82c205a8556eb7c1f38d1ff07a4e1393772b9433 /sound/soc/codecs/ak4613.c | |
parent | a83ac4860925e1d0a7e38e7bea331fd2f2e0460d (diff) | |
download | linux-907cd8809eebccc57a6a3ee9fa87b7602e72df38.tar.bz2 |
ASoC: ak4613: add hw_constraint rule for Sampling Rate
Current ak4613 accepts all range of Sampling Rate, but it depends on
inputed master clock. This patch adds hw constraint rule for it.
Signed-off-by: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
Tested-by: Hiroyuki Yokoyama <hiroyuki.yokoyama.vx@renesas.com>
Signed-off-by: Mark Brown <broonie@kernel.org>
Diffstat (limited to 'sound/soc/codecs/ak4613.c')
-rw-r--r-- | sound/soc/codecs/ak4613.c | 61 |
1 files changed, 61 insertions, 0 deletions
diff --git a/sound/soc/codecs/ak4613.c b/sound/soc/codecs/ak4613.c index d5beca008dea..a4520a1f849d 100644 --- a/sound/soc/codecs/ak4613.c +++ b/sound/soc/codecs/ak4613.c @@ -94,6 +94,8 @@ struct ak4613_interface { struct ak4613_priv { struct mutex lock; const struct ak4613_interface *iface; + struct snd_pcm_hw_constraint_list constraint; + unsigned int sysclk; unsigned int fmt; u8 oc; @@ -252,6 +254,50 @@ static void ak4613_dai_shutdown(struct snd_pcm_substream *substream, mutex_unlock(&priv->lock); } +static void ak4613_hw_constraints(struct ak4613_priv *priv, + struct snd_pcm_runtime *runtime) +{ + static const unsigned int ak4613_rates[] = { + 32000, + 44100, + 48000, + 64000, + 88200, + 96000, + 176400, + 192000, + }; + struct snd_pcm_hw_constraint_list *constraint = &priv->constraint; + unsigned int fs; + int i; + + constraint->list = ak4613_rates; + constraint->mask = 0; + constraint->count = 0; + + /* + * Slave Mode + * Normal: [32kHz, 48kHz] : 256fs,384fs or 512fs + * Double: [64kHz, 96kHz] : 256fs + * Quad : [128kHz,192kHz]: 128fs + * + * Master mode + * Normal: [32kHz, 48kHz] : 256fs or 512fs + * Double: [64kHz, 96kHz] : 256fs + * Quad : [128kHz,192kHz]: 128fs + */ + for (i = 0; i < ARRAY_SIZE(ak4613_rates); i++) { + /* minimum fs on each range */ + fs = (ak4613_rates[i] <= 96000) ? 256 : 128; + + if (priv->sysclk >= ak4613_rates[i] * fs) + constraint->count = i + 1; + } + + snd_pcm_hw_constraint_list(runtime, 0, + SNDRV_PCM_HW_PARAM_RATE, constraint); +} + static int ak4613_dai_startup(struct snd_pcm_substream *substream, struct snd_soc_dai *dai) { @@ -260,6 +306,19 @@ static int ak4613_dai_startup(struct snd_pcm_substream *substream, priv->cnt++; + ak4613_hw_constraints(priv, substream->runtime); + + return 0; +} + +static int ak4613_dai_set_sysclk(struct snd_soc_dai *codec_dai, + int clk_id, unsigned int freq, int dir) +{ + struct snd_soc_codec *codec = codec_dai->codec; + struct ak4613_priv *priv = snd_soc_codec_get_drvdata(codec); + + priv->sysclk = freq; + return 0; } @@ -411,6 +470,7 @@ static int ak4613_set_bias_level(struct snd_soc_codec *codec, static const struct snd_soc_dai_ops ak4613_dai_ops = { .startup = ak4613_dai_startup, .shutdown = ak4613_dai_shutdown, + .set_sysclk = ak4613_dai_set_sysclk, .set_fmt = ak4613_dai_set_fmt, .hw_params = ak4613_dai_hw_params, }; @@ -529,6 +589,7 @@ static int ak4613_i2c_probe(struct i2c_client *i2c, priv->iface = NULL; priv->cnt = 0; + priv->sysclk = 0; mutex_init(&priv->lock); |