From 251d8ae450186f72e8e0c9e09cb00a4feecdfd0f Mon Sep 17 00:00:00 2001 From: Adrian Alonso Date: Tue, 2 Jun 2020 18:39:12 -0500 Subject: 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 Reviewed-by: Viorel Suman --- sound/soc/fsl/imx-pdm.c | 44 +++++++++++++++++++++++++++++++++++++++----- 1 file changed, 39 insertions(+), 5 deletions(-) (limited to 'sound/soc/fsl/imx-pdm.c') 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; } -- cgit v1.2.3