summaryrefslogtreecommitdiff
path: root/sound/soc/fsl/imx-pdm.c
diff options
context:
space:
mode:
authorAdrian Alonso <adrian.alonso@nxp.com>2020-06-02 18:39:12 -0500
committerAdrian Alonso <adrian.alonso@nxp.com>2020-06-05 11:07:41 -0500
commit251d8ae450186f72e8e0c9e09cb00a4feecdfd0f (patch)
tree87515c105fcfefdb068c03ee03994c740f7d356d /sound/soc/fsl/imx-pdm.c
parent1c91db7d5bb8bbf6f971d3e4c6c629106d3ed517 (diff)
MLK-24232-2: sound: soc fsl: imx-pdm compute mclk performance mode
Compute mclk to allow low power and performance settings based on sample_rate: [ 8000 - 11025] low power mode [16000 - 64000] performance mode Update Copyright year. Signed-off-by: Adrian Alonso <adrian.alonso@nxp.com> Reviewed-by: Viorel Suman <viorel.suman@nxp.com>
Diffstat (limited to 'sound/soc/fsl/imx-pdm.c')
-rw-r--r--sound/soc/fsl/imx-pdm.c44
1 files changed, 39 insertions, 5 deletions
diff --git a/sound/soc/fsl/imx-pdm.c b/sound/soc/fsl/imx-pdm.c
index 3fdbc00a7279..f21abbf25295 100644
--- a/sound/soc/fsl/imx-pdm.c
+++ b/sound/soc/fsl/imx-pdm.c
@@ -1,5 +1,5 @@
/*
- * Copyright 2017 NXP.
+ * Copyright 2017-2020 NXP.
*
* The code contained herein is licensed under the GNU General Public
* License. You may obtain a copy of the GNU General Public License
@@ -27,10 +27,18 @@ struct imx_pdm_data {
unsigned int decimation;
};
+static const struct imx_pdm_mic_fs_mul {
+ unsigned int min;
+ unsigned int max;
+ unsigned int mul;
+} fs_mul[] = {
+ { .min = 8000, .max = 11025, .mul = 8 }, /* low power */
+ { .min = 16000, .max = 64000, .mul = 16 }, /* performance */
+};
+
static const unsigned int imx_pdm_mic_rates[] = {
- 8000, 11025, 12000, 16000,
- 22050, 24000, 32000, 44100,
- 48000, 64000,
+ 8000, 11025, 16000, 22050,
+ 32000, 44100, 48000, 64000,
};
static struct snd_pcm_hw_constraint_list imx_pdm_mic_rate_constrains = {
.count = ARRAY_SIZE(imx_pdm_mic_rates),
@@ -42,6 +50,20 @@ static struct snd_pcm_hw_constraint_list imx_pdm_mic_channels_constrains = {
.list = imx_pdm_mic_channels,
};
+static unsigned long imx_pdm_mic_mclk_freq(unsigned int decimation,
+ unsigned int rate)
+{
+ int i;
+
+ /* Find appropriate mclk freq */
+ for (i = 0; i < ARRAY_SIZE(fs_mul); i++) {
+ if (rate >= fs_mul[i].min && rate <= fs_mul[i].max)
+ return (rate * decimation * fs_mul[i].mul);
+ }
+
+ return 0;
+}
+
static int imx_pdm_mic_startup(struct snd_pcm_substream *substream)
{
struct snd_soc_pcm_runtime *rtd = substream->private_data;
@@ -83,6 +105,8 @@ static int imx_pdm_mic_hw_params(struct snd_pcm_substream *substream,
struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
struct snd_soc_card *card = rtd->card;
struct imx_pdm_data *data = snd_soc_card_get_drvdata(card);
+ unsigned int sample_rate = params_rate(params);
+ unsigned long mclk_freq;
int ret;
/* set cpu dai format configuration */
@@ -92,12 +116,22 @@ static int imx_pdm_mic_hw_params(struct snd_pcm_substream *substream,
dev_err(card->dev, "fail to set cpu dai fmt: %d\n", ret);
return ret;
}
- /* Set clock out */
+
+ /* Set bitclk ratio */
ret = snd_soc_dai_set_bclk_ratio(cpu_dai, data->decimation);
if (ret) {
dev_err(card->dev, "fail to set cpu sysclk: %d\n", ret);
return ret;
}
+ /* set mclk freq */
+ mclk_freq = imx_pdm_mic_mclk_freq(data->decimation, sample_rate);
+ ret = snd_soc_dai_set_sysclk(cpu_dai, FSL_SAI_CLK_MAST1,
+ mclk_freq, SND_SOC_CLOCK_OUT);
+ if (ret) {
+ dev_err(card->dev, "fail to set cpu mclk1 rate: %lu\n",
+ mclk_freq);
+ return ret;
+ }
return 0;
}