All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH] ASoC: nau8822: choose the best master clock prescalar
@ 2022-05-24  3:33 Hui Wang
  2022-05-24  8:07 ` David Lin
  2022-05-24  8:23 ` David Lin
  0 siblings, 2 replies; 6+ messages in thread
From: Hui Wang @ 2022-05-24  3:33 UTC (permalink / raw)
  To: alsa-devel, broonie; +Cc: wtli, kchsu0, ctlin0

We have an imx6sx EVB with the codec nau8822, when playing the audio
with 48k sample rate, the audio sounds distorted and obviously faster
than expected.

The codec input MCLK is 24000000Hz on our board, if the target sample
rate is 48000Hz, with the current algorithm, the computed prescalar
will result in 62500Hz, with the patched algorithm, the sample rate
will be 46875Hz which is nearer the target sample rate.

And for other sample rate like 44100, 22050, 11025 or 8000, the
patched algorithm has no difference with the current algorithm, they
will generate the same prescalar and the same sample rate.

Signed-off-by: Hui Wang <hui.wang@canonical.com>
---
 sound/soc/codecs/nau8822.c | 9 ++++++---
 1 file changed, 6 insertions(+), 3 deletions(-)

diff --git a/sound/soc/codecs/nau8822.c b/sound/soc/codecs/nau8822.c
index 66bbd8f4f1ad..b67fdf64ddab 100644
--- a/sound/soc/codecs/nau8822.c
+++ b/sound/soc/codecs/nau8822.c
@@ -668,21 +668,24 @@ static int nau8822_config_clkdiv(struct snd_soc_dai *dai, int div, int rate)
 	struct snd_soc_component *component = dai->component;
 	struct nau8822 *nau8822 = snd_soc_component_get_drvdata(component);
 	struct nau8822_pll *pll = &nau8822->pll;
+	int diff = INT_MAX;
 	int i, sclk, imclk;
 
 	switch (nau8822->div_id) {
 	case NAU8822_CLK_MCLK:
 		/* Configure the master clock prescaler div to make system
 		 * clock to approximate the internal master clock (IMCLK);
-		 * and large or equal to IMCLK.
+		 * and find the nearest value to IMCLK.
 		 */
 		div = 0;
 		imclk = rate * 256;
 		for (i = 1; i < ARRAY_SIZE(nau8822_mclk_scaler); i++) {
 			sclk = (nau8822->sysclk * 10) /	nau8822_mclk_scaler[i];
-			if (sclk < imclk)
+			if (abs(sclk - imclk) < diff) {
+				diff = abs(sclk - imclk);
+				div =  i;
+			} else
 				break;
-			div = i;
 		}
 		dev_dbg(component->dev, "master clock prescaler %x for fs %d\n",
 			div, rate);
-- 
2.25.1


^ permalink raw reply related	[flat|nested] 6+ messages in thread

* Re: [PATCH] ASoC: nau8822: choose the best master clock prescalar
  2022-05-24  3:33 [PATCH] ASoC: nau8822: choose the best master clock prescalar Hui Wang
@ 2022-05-24  8:07 ` David Lin
  2022-05-24  8:38   ` Hui Wang
  2022-05-24  8:23 ` David Lin
  1 sibling, 1 reply; 6+ messages in thread
From: David Lin @ 2022-05-24  8:07 UTC (permalink / raw)
  To: Hui Wang, alsa-devel, broonie; +Cc: wtli, YHCHuang, SJLIN0, kchsu0, David Lin

On 2022/5/24 上午 11:33, Hui Wang wrote:
> We have an imx6sx EVB with the codec nau8822, when playing the audio
> with 48k sample rate, the audio sounds distorted and obviously faster
> than expected.
>
> The codec input MCLK is 24000000Hz on our board, if the target sample
> rate is 48000Hz, with the current algorithm, the computed prescalar
> will result in 62500Hz, with the patched algorithm, the sample rate
> will be 46875Hz which is nearer the target sample rate.
>
> And for other sample rate like 44100, 22050, 11025 or 8000, the
> patched algorithm has no difference with the current algorithm, they
> will generate the same prescalar and the same sample rate.
>
> Signed-off-by: Hui Wang <hui.wang@canonical.com>
> ---
>   sound/soc/codecs/nau8822.c | 9 ++++++---
>   1 file changed, 6 insertions(+), 3 deletions(-)
>
> diff --git a/sound/soc/codecs/nau8822.c b/sound/soc/codecs/nau8822.c
> index 66bbd8f4f1ad..b67fdf64ddab 100644
> --- a/sound/soc/codecs/nau8822.c
> +++ b/sound/soc/codecs/nau8822.c
> @@ -668,21 +668,24 @@ static int nau8822_config_clkdiv(struct snd_soc_dai *dai, int div, int rate)
>   	struct snd_soc_component *component = dai->component;
>   	struct nau8822 *nau8822 = snd_soc_component_get_drvdata(component);
>   	struct nau8822_pll *pll = &nau8822->pll;
> +	int diff = INT_MAX;
>   	int i, sclk, imclk;
>   
>   	switch (nau8822->div_id) {
>   	case NAU8822_CLK_MCLK:
>   		/* Configure the master clock prescaler div to make system
>   		 * clock to approximate the internal master clock (IMCLK);
> -		 * and large or equal to IMCLK.
> +		 * and find the nearest value to IMCLK.
>   		 */
>   		div = 0;
>   		imclk = rate * 256;
>   		for (i = 1; i < ARRAY_SIZE(nau8822_mclk_scaler); i++) {
>   			sclk = (nau8822->sysclk * 10) /	nau8822_mclk_scaler[i];
> -			if (sclk < imclk)
> +			if (abs(sclk - imclk) < diff) {
> +				diff = abs(sclk - imclk);
> +				div =  i;
> +			} else
>   				break;
> -			div = i;
>   		}
>   		dev_dbg(component->dev, "master clock prescaler %x for fs %d\n",
>   			div, rate);

Regarding to your environment with input MCLK is 24 MHz, I think you 
should enable PLL for the internal process of codec.

So you should do the following calls/operations:

//PLL
     ret = snd_soc_dai_set_sysclk(codec_dai, NAU8822_CLK_PLL,
                       24000000, SND_SOC_CLOCK_IN);
     if (ret < 0 )
         dev_err(card->dev, "failed to set codec sysclk: %d\n", ret);

     ret = snd_soc_dai_set_pll(codec_dai, 0, 0,
                   24000000, 256 * params_rate(params));
     if (ret < 0 )

         dev_err(card->dev, "failed to set codec pll: %d\n", ret);

David


^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: [PATCH] ASoC: nau8822: choose the best master clock prescalar
  2022-05-24  3:33 [PATCH] ASoC: nau8822: choose the best master clock prescalar Hui Wang
  2022-05-24  8:07 ` David Lin
@ 2022-05-24  8:23 ` David Lin
  1 sibling, 0 replies; 6+ messages in thread
From: David Lin @ 2022-05-24  8:23 UTC (permalink / raw)
  To: Hui Wang, alsa-devel, broonie; +Cc: wtli, David Lin, SJLIN0, kchsu0, YHCHuang

On 2022/5/24 上午 11:33, Hui Wang wrote:
> We have an imx6sx EVB with the codec nau8822, when playing the audio
> with 48k sample rate, the audio sounds distorted and obviously faster
> than expected.
>
> The codec input MCLK is 24000000Hz on our board, if the target sample
> rate is 48000Hz, with the current algorithm, the computed prescalar
> will result in 62500Hz, with the patched algorithm, the sample rate
> will be 46875Hz which is nearer the target sample rate.
>
> And for other sample rate like 44100, 22050, 11025 or 8000, the
> patched algorithm has no difference with the current algorithm, they
> will generate the same prescalar and the same sample rate.
>
> Signed-off-by: Hui Wang <hui.wang@canonical.com>
> ---
>   sound/soc/codecs/nau8822.c | 9 ++++++---
>   1 file changed, 6 insertions(+), 3 deletions(-)
>
> diff --git a/sound/soc/codecs/nau8822.c b/sound/soc/codecs/nau8822.c
> index 66bbd8f4f1ad..b67fdf64ddab 100644
> --- a/sound/soc/codecs/nau8822.c
> +++ b/sound/soc/codecs/nau8822.c
> @@ -668,21 +668,24 @@ static int nau8822_config_clkdiv(struct snd_soc_dai *dai, int div, int rate)
>   	struct snd_soc_component *component = dai->component;
>   	struct nau8822 *nau8822 = snd_soc_component_get_drvdata(component);
>   	struct nau8822_pll *pll = &nau8822->pll;
> +	int diff = INT_MAX;
>   	int i, sclk, imclk;
>   
>   	switch (nau8822->div_id) {
>   	case NAU8822_CLK_MCLK:
>   		/* Configure the master clock prescaler div to make system
>   		 * clock to approximate the internal master clock (IMCLK);
> -		 * and large or equal to IMCLK.
> +		 * and find the nearest value to IMCLK.
>   		 */
>   		div = 0;
>   		imclk = rate * 256;
>   		for (i = 1; i < ARRAY_SIZE(nau8822_mclk_scaler); i++) {
>   			sclk = (nau8822->sysclk * 10) /	nau8822_mclk_scaler[i];
> -			if (sclk < imclk)
> +			if (abs(sclk - imclk) < diff) {
> +				diff = abs(sclk - imclk);
> +				div =  i;
> +			} else
>   				break;
> -			div = i;
>   		}
>   		dev_dbg(component->dev, "master clock prescaler %x for fs %d\n",
>   			div, rate);
Regarding to your environment with input MCLK is 24 MHz, I think you 
should enable PLL for the internal process of codec.

So you should do the following calls/operations from machine driver.

//PLL
     ret = snd_soc_dai_set_sysclk(codec_dai, NAU8822_CLK_PLL,
                       24000000, SND_SOC_CLOCK_IN);
     if (ret < 0 )
         dev_err(card->dev, "failed to set codec sysclk: %d\n", ret);

     ret = snd_soc_dai_set_pll(codec_dai, 0, 0,
                   24000000, 256 * params_rate(params));
     if (ret < 0 )

         dev_err(card->dev, "failed to set codec pll: %d\n", ret);

David

^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: [PATCH] ASoC: nau8822: choose the best master clock prescalar
  2022-05-24  8:07 ` David Lin
@ 2022-05-24  8:38   ` Hui Wang
  2022-05-24 10:22     ` David Lin
  0 siblings, 1 reply; 6+ messages in thread
From: Hui Wang @ 2022-05-24  8:38 UTC (permalink / raw)
  To: David Lin, alsa-devel, broonie; +Cc: wtli, YHCHuang, SJLIN0, kchsu0, David Lin


On 5/24/22 16:07, David Lin wrote:
> On 2022/5/24 上午 11:33, Hui Wang wrote:
>> We have an imx6sx EVB with the codec nau8822, when playing the audio
>> with 48k sample rate, the audio sounds distorted and obviously faster
>>
<snip>
>> -            div = i;
>>           }
>>           dev_dbg(component->dev, "master clock prescaler %x for fs 
>> %d\n",
>>               div, rate);
>
> Regarding to your environment with input MCLK is 24 MHz, I think you 
> should enable PLL for the internal process of codec.
>
> So you should do the following calls/operations:
>
Thanks for your suggestion. In our case, we use the simple-card as the 
machine driver, the simple-card hard-codes the 2nd parameter of 
snd_soc_dai_set_sysclk() to 0, and we don't plan to write a new machine 
driver since sound quality is pretty good if setting to 46875Hz.

So according to your experience, does the new algorithm bring any side 
effect or break existing platforms? If so, we have to write a new 
machine driver (that is a big effort).

Thanks,

Hui.

> //PLL
>     ret = snd_soc_dai_set_sysclk(codec_dai, NAU8822_CLK_PLL,
>                       24000000, SND_SOC_CLOCK_IN);
>     if (ret < 0 )
>         dev_err(card->dev, "failed to set codec sysclk: %d\n", ret);
>
>     ret = snd_soc_dai_set_pll(codec_dai, 0, 0,
>                   24000000, 256 * params_rate(params));
>     if (ret < 0 )
>
>         dev_err(card->dev, "failed to set codec pll: %d\n", ret);
>
> David
>

^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: [PATCH] ASoC: nau8822: choose the best master clock prescalar
  2022-05-24  8:38   ` Hui Wang
@ 2022-05-24 10:22     ` David Lin
  2022-05-25  3:34       ` Hui Wang
  0 siblings, 1 reply; 6+ messages in thread
From: David Lin @ 2022-05-24 10:22 UTC (permalink / raw)
  To: Hui Wang, alsa-devel, broonie; +Cc: wtli, YHCHuang, SJLIN0, kchsu0, David Lin

On 2022/5/24 下午 04:38, Hui Wang wrote:
>
> On 5/24/22 16:07, David Lin wrote:
>> On 2022/5/24 上午 11:33, Hui Wang wrote:
>>> We have an imx6sx EVB with the codec nau8822, when playing the audio
>>> with 48k sample rate, the audio sounds distorted and obviously faster
>>>
> <snip>
>>> -            div = i;
>>>           }
>>>           dev_dbg(component->dev, "master clock prescaler %x for fs 
>>> %d\n",
>>>               div, rate);
>>
>> Regarding to your environment with input MCLK is 24 MHz, I think you 
>> should enable PLL for the internal process of codec.
>>
>> So you should do the following calls/operations:
>>
> Thanks for your suggestion. In our case, we use the simple-card as the 
> machine driver, the simple-card hard-codes the 2nd parameter of 
> snd_soc_dai_set_sysclk() to 0, and we don't plan to write a new 
> machine driver since sound quality is pretty good if setting to 46875Hz.
>
> So according to your experience, does the new algorithm bring any side 
> effect or break existing platforms? If so, we have to write a new 
> machine driver (that is a big effort).
>
> Thanks,
>
> Hui.
>
Even you can hear better sound quality than original, it don't still 
have better performance(THD+N) than MCLK is 256FS. Generally,  we will 
suggest the below that for customer support.
1. Check dts description from simple-card about the value of mclk-fs is 
256? The reason is nau8822 codec just support 256FS. Besides, the I.MX 
EVB should be with flexible clock generation.
2. Based on the flexible clock generation, you should input 12.288Mhz as 
MCLK, so the simple-card is suitable for your case with low effort.
3. If your MCLK is always 24MHz, PLL enable is preferred as previous 
mention. One is to implement/porting a machine driver, the other is to 
revise asoc_simple_hw_params callback function from simple-card-utils.c.
>> //PLL
>>     ret = snd_soc_dai_set_sysclk(codec_dai, NAU8822_CLK_PLL,
>>                       24000000, SND_SOC_CLOCK_IN);
>>     if (ret < 0 )
>>         dev_err(card->dev, "failed to set codec sysclk: %d\n", ret);
>>
>>     ret = snd_soc_dai_set_pll(codec_dai, 0, 0,
>>                   24000000, 256 * params_rate(params));
>>     if (ret < 0 )
>>
>>         dev_err(card->dev, "failed to set codec pll: %d\n", ret);
>>
>> David
>>

^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: [PATCH] ASoC: nau8822: choose the best master clock prescalar
  2022-05-24 10:22     ` David Lin
@ 2022-05-25  3:34       ` Hui Wang
  0 siblings, 0 replies; 6+ messages in thread
From: Hui Wang @ 2022-05-25  3:34 UTC (permalink / raw)
  To: David Lin, alsa-devel, broonie; +Cc: wtli, YHCHuang, SJLIN0, kchsu0, David Lin


On 5/24/22 18:22, David Lin wrote:
> On 2022/5/24 下午 04:38, Hui Wang wrote:
>>
>> On 5/24/22 16:07, David Lin wrote:
>>> On 2022/5/24 上午 11:33, Hui Wang wrote:
>>>> We have an imx6sx EVB with the codec nau8822, when playing the audio
>>>> with 48k sample rate, the audio sounds distorted and obviously faster
>>>>
>> <snip>
>>>> -            div = i;
>>>>           }
>>>>           dev_dbg(component->dev, "master clock prescaler %x for fs 
>>>> %d\n",
>>>>               div, rate);
>>>
>>> Regarding to your environment with input MCLK is 24 MHz, I think you 
>>> should enable PLL for the internal process of codec.
>>>
>>> So you should do the following calls/operations:
>>>
>> Thanks for your suggestion. In our case, we use the simple-card as 
>> the machine driver, the simple-card hard-codes the 2nd parameter of 
>> snd_soc_dai_set_sysclk() to 0, and we don't plan to write a new 
>> machine driver since sound quality is pretty good if setting to 46875Hz.
>>
>> So according to your experience, does the new algorithm bring any 
>> side effect or break existing platforms? If so, we have to write a 
>> new machine driver (that is a big effort).
>>
>> Thanks,
>>
>> Hui.
>>
> Even you can hear better sound quality than original, it don't still 
> have better performance(THD+N) than MCLK is 256FS. Generally,  we will 
> suggest the below that for customer support.
> 1. Check dts description from simple-card about the value of mclk-fs 
> is 256? The reason is nau8822 codec just support 256FS. Besides, the 
> I.MX EVB should be with flexible clock generation.
> 2. Based on the flexible clock generation, you should input 12.288Mhz 
> as MCLK, so the simple-card is suitable for your case with low effort.
> 3. If your MCLK is always 24MHz, PLL enable is preferred as previous 
> mention. One is to implement/porting a machine driver, the other is to 
> revise asoc_simple_hw_params callback function from simple-card-utils.c.

OK, got it. Thanks.


>>> //PLL
>>>     ret = snd_soc_dai_set_sysclk(codec_dai, NAU8822_CLK_PLL,
>>>                       24000000, SND_SOC_CLOCK_IN);
>>>     if (ret < 0 )
>>>         dev_err(card->dev, "failed to set codec sysclk: %d\n", ret);
>>>
>>>     ret = snd_soc_dai_set_pll(codec_dai, 0, 0,
>>>                   24000000, 256 * params_rate(params));
>>>     if (ret < 0 )
>>>
>>>         dev_err(card->dev, "failed to set codec pll: %d\n", ret);
>>>
>>> David
>>>

^ permalink raw reply	[flat|nested] 6+ messages in thread

end of thread, other threads:[~2022-05-25 14:11 UTC | newest]

Thread overview: 6+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2022-05-24  3:33 [PATCH] ASoC: nau8822: choose the best master clock prescalar Hui Wang
2022-05-24  8:07 ` David Lin
2022-05-24  8:38   ` Hui Wang
2022-05-24 10:22     ` David Lin
2022-05-25  3:34       ` Hui Wang
2022-05-24  8:23 ` David Lin

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.