ASoC: simple-card, fsl-sai, ak4458, imx-ak4458

Eliot Blennerhassett eliot at blennerhassett.gen.nz
Wed Jan 20 00:41:18 CET 2021


Greetings,

late last year I worked on a project using $SUBJECT. That has been
suspended at least for now, so I'm writing these notes to my future
self, or anyone else who may want to tread the same path.
I'm happy to expand on explanation, or work on patches if anyone is
interested.

Background:

Normally, fsl-sai is used with the platform-specific imx-ak4458 (afaik
only in vendor tree).

However, our project wished to be able use pcm1789 which has no imx
specific driver so I started trying to use simple-card with the generic
ak4458 driver.  I encountered a some of problems doing this:


------------------------------------------------------------------------
1) Reset polarity of ak4458.

When imx-ak4458 is used, the platform driver handles the codec reset
specified in DT
	compatible = "fsl,imx-audio-ak4458";
	ak4458,pdn-gpio = <&gpio4 20 GPIO_ACTIVE_LOW>;

Used here. Afaics gpio_set_value sets the raw value given, ignoring the
polarity specified by the DT?

	gpio_set_value_cansleep(priv->pdn_gpio, 0);
	usleep_range(1000, 2000);
	gpio_set_value_cansleep(priv->pdn_gpio, 1);
	usleep_range(1000, 2000);


The codec driver reset code is not used.



When simple-card is used, the codec driver handles reset, specified like:
	compatible = "asahi-kasei,ak4458";
	reset-gpios  = <&gpio4 20 GPIO_ACTIVE_LOW>;

and used here (inverse for power on)
static void ak4458_power_off(struct ak4458_priv *ak4458)
{
	if (ak4458->reset_gpiod) {
		gpiod_set_value_cansleep(ak4458->reset_gpiod, 0);
		usleep_range(1000, 2000);
	}
}

My understanding of gpiod functions is that value being set is the
*logical* value of the GPIO. I.e. setting an active low gpio to 0 will
set the hardware pin high.
So it appears that the power_off and power_on functions are doing the
opposite of what is intended.
This is borne out by my hardware working correctly when the


------------------------------------------------------------------------
2) Clock rate setting with simple-card

When simple-card is used and DT specifies mclk fs:
	simple-audio-card,mclk-fs = <256>;

asoc_simple_hw_params() calls snd_soc_dai_set_sysclk(..., clk_id=0, ...)

The hard-coded clk_id=0 doesn't work with fsl-sai, which requires clk_id==1.

For my testing purposes I changed the hard-coded value, but I think the
proper solution could be to add a DT property to specify the clk_id
(default=0) ?


------------------------------------------------------------------------
3) Memory mapped stream access by aplay does not work.
This precludes use of alsa plugins e.g. dmix

I have found no reason or solution for this so far

------------------------------------------------------------------------
4) Unable to get multiple source clocks working with fsl-sai

With a single assigned-clock, switching between 48k and 44k1 clock rate
families is accomplished by reparenting the root clock to the
appropriate audio pll clock.

&sai2 {
	assigned-clock-parents = <&clk IMX8MM_AUDIO_PLL1_OUT>;
	assigned-clocks        = <&clk IMX8MM_CLK_SAI2>;
	assigned-clock-rates   = <12288000>;
	...
};



However if two of the sai mclks could be set to 48k and 44k1 derived
rates respectively, the clock reparenting would not be required, and
fsl_sai_set_bclk() would search the mclks and choose the appropriate
mclk for the requested rate.

DT would be something like this:

&sai2 {
	assigned-clock-parents = <&clk IMX8MM_AUDIO_PLL1_OUT>, <&clk
IMX8MM_AUDIO_PLL2_OUT>;
	assigned-clocks        = <&clk IMX8MM_CLK_SAI2>,       <&clk
IMX8MM_CLK_SAI1>;
	assigned-clock-rates   = <12288000>,                   <11289600>;
};

This setup doesn't work as I hoped it would, don't know why not.

regards

-- 
Eliot Blennerhassett



More information about the Alsa-devel mailing list