Skip to content

Commit 082d3c9

Browse files
Pavel Dobiasbroonie
authored andcommitted
ASoC: max9867: Implement exact integer mode
For 8kHz and 16kHz sample rates and certain PCLK values the codec can be programmed to operate in exact integer mode. If available, use it to achieve the exact sample rate. Signed-off-by: Pavel Dobias <[email protected]> Link: https://lore.kernel.org/r/[email protected] Signed-off-by: Mark Brown <[email protected]>
1 parent 7aa6d95 commit 082d3c9

File tree

1 file changed

+30
-3
lines changed

1 file changed

+30
-3
lines changed

sound/soc/codecs/max9867.c

Lines changed: 30 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -323,7 +323,7 @@ static int max9867_startup(struct snd_pcm_substream *substream,
323323
static int max9867_dai_hw_params(struct snd_pcm_substream *substream,
324324
struct snd_pcm_hw_params *params, struct snd_soc_dai *dai)
325325
{
326-
int value;
326+
int value, freq = 0;
327327
unsigned long int rate, ratio;
328328
struct snd_soc_component *component = dai->component;
329329
struct max9867_priv *max9867 = snd_soc_component_get_drvdata(component);
@@ -373,6 +373,35 @@ static int max9867_dai_hw_params(struct snd_pcm_substream *substream,
373373
}
374374
regmap_update_bits(max9867->regmap, MAX9867_IFC1B,
375375
MAX9867_IFC1B_BCLK_MASK, value);
376+
377+
/* Exact integer mode available for 8kHz and 16kHz sample rates
378+
* and certain PCLK (prescaled MCLK) values.
379+
*/
380+
if (params_rate(params) == 8000 ||
381+
params_rate(params) == 16000) {
382+
switch (max9867->pclk) {
383+
case 12000000:
384+
freq = 0x08;
385+
break;
386+
case 13000000:
387+
freq = 0x0A;
388+
break;
389+
case 16000000:
390+
freq = 0x0C;
391+
break;
392+
case 19200000:
393+
freq = 0x0E;
394+
break;
395+
}
396+
}
397+
if (freq && params_rate(params) == 16000)
398+
freq++;
399+
400+
/* If exact integer mode not available, the freq value
401+
* remains zero, i.e. normal mode is used.
402+
*/
403+
regmap_update_bits(max9867->regmap, MAX9867_SYSCLK,
404+
MAX9867_FREQ_MASK, freq);
376405
} else {
377406
/*
378407
* digital pll locks on to any externally supplied LRCLK signal
@@ -428,8 +457,6 @@ static int max9867_set_dai_sysclk(struct snd_soc_dai *codec_dai,
428457
freq);
429458
max9867->sysclk = freq;
430459
value = value << MAX9867_PSCLK_SHIFT;
431-
/* exact integer mode is not supported */
432-
value &= ~MAX9867_FREQ_MASK;
433460
regmap_update_bits(max9867->regmap, MAX9867_SYSCLK,
434461
MAX9867_PSCLK_MASK, value);
435462
return 0;

0 commit comments

Comments
 (0)