[alsa-devel] [PATCH] ASoC: sgtl5000: Allow LRCLK pad drive strength to be changed

Max Krummenacher max.oss.09 at gmail.com
Wed Apr 5 19:38:47 CEST 2017


On Wed, 2017-04-05 at 11:32 -0300, Fabio Estevam wrote:
> Introduce the "lrclk-strength" property to allow LRCLK pad drive strength
> to be changed via device tree.
> 
> When running a stress playback loop test on a mx6dl wandboard channel
> swap can be noticed on about 10% of the times.
> 
> While debugging this issue I noticed that when probing the SGTL5000
> LRCLK pin with the scope the swap did not happen. After removing
> the probe the swap started to happen again.
> 
> After changing the LRCLK pad drive strength to the maximum value the
> issue is gone.
> 
> Same fix works on a mx6dl Colibri board as well.
> 
> Signed-off-by: Fabio Estevam <fabio.estevam at nxp.com>

Hi

I could reproduce the channel swap issue on a Colibri iMX6 Dual
with a i.MX 6DualLite. Without the patch I see channel swap in
about 3% of playback starts. The patch fixes the issue with the
following change to the sgtl5000 device-tree node:
diff --git a/arch/arm/boot/dts/imx6qdl-colibri.dtsi b/arch/arm/boot/dts/imx6qdl-colibri.dtsi
index e6faa65..80ece03 100644
--- a/arch/arm/boot/dts/imx6qdl-colibri.dtsi
+++ b/arch/arm/boot/dts/imx6qdl-colibri.dtsi
@@ -253,6 +253,7 @@
 		compatible = "fsl,sgtl5000";
 		reg = <0x0a>;
 		clocks = <&clks IMX6QDL_CLK_CKO>;
+		lrclk-strength = <0x3>;
 		VDDA-supply = <&reg_2p5v>;
 		VDDIO-supply = <&reg_3p3v>;
 	};


Tested-by: Max Krummenacher <max.krummenacher at toradex.com>

Max

> ---
>  Documentation/devicetree/bindings/sound/sgtl5000.txt |  9 +++++++++
>  sound/soc/codecs/sgtl5000.c                          | 19 ++++++++++++++++++-
>  2 files changed, 27 insertions(+), 1 deletion(-)
> 
> diff --git a/Documentation/devicetree/bindings/sound/sgtl5000.txt b/Documentation/devicetree/bindings/sound/sgtl5000.txt
> index 5666da7..7a73a9d 100644
> --- a/Documentation/devicetree/bindings/sound/sgtl5000.txt
> +++ b/Documentation/devicetree/bindings/sound/sgtl5000.txt
> @@ -26,6 +26,15 @@ Optional properties:
>  	If this node is not mentioned or the value is unknown, then
>  	the value is set to 1.25V.
>  
> +- lrclk-strength: the LRCLK pad strength. Possible values are:
> +0, 1, 2 and 3 as per the table below:
> +
> +VDDIO		1.8V		2.5V		3.3V
> +0 = 		Disable
> +1 =		1.66 mA		2.87 mA		4.02  mA
> +2 =		3.33 mA		5.74 mA		8.03  mA
> +3 =		4.99 mA		8.61 mA		12.05 mA
> +
>  Example:
>  
>  codec: sgtl5000 at 0a {
> diff --git a/sound/soc/codecs/sgtl5000.c b/sound/soc/codecs/sgtl5000.c
> index 1589325..5a2702e 100644
> --- a/sound/soc/codecs/sgtl5000.c
> +++ b/sound/soc/codecs/sgtl5000.c
> @@ -99,6 +99,13 @@ enum sgtl5000_micbias_resistor {
>  	SGTL5000_MICBIAS_8K = 8,
>  };
>  
> +enum  {
> +	I2S_LRCLK_STRENGTH_DISABLE,
> +	I2S_LRCLK_STRENGTH_LOW,
> +	I2S_LRCLK_STRENGTH_MEDIUM,
> +	I2S_LRCLK_STRENGTH_HIGH,
> +};
> +
>  /* sgtl5000 private structure in codec */
>  struct sgtl5000_priv {
>  	int sysclk;	/* sysclk rate */
> @@ -111,6 +118,7 @@ struct sgtl5000_priv {
>  	int revision;
>  	u8 micbias_resistor;
>  	u8 micbias_voltage;
> +	u8 lrclk_strength;
>  };
>  
>  /*
> @@ -1089,6 +1097,7 @@ static int sgtl5000_enable_regulators(struct i2c_client *client)
>  static int sgtl5000_probe(struct snd_soc_codec *codec)
>  {
>  	int ret;
> +	u16 reg;
>  	struct sgtl5000_priv *sgtl5000 = snd_soc_codec_get_drvdata(codec);
>  
>  	/* power up sgtl5000 */
> @@ -1118,7 +1127,8 @@ static int sgtl5000_probe(struct snd_soc_codec *codec)
>  			SGTL5000_DAC_MUTE_RIGHT |
>  			SGTL5000_DAC_MUTE_LEFT);
>  
> -	snd_soc_write(codec, SGTL5000_CHIP_PAD_STRENGTH, 0x015f);
> +	reg = ((sgtl5000->lrclk_strength) << SGTL5000_PAD_I2S_LRCLK_SHIFT | 0x5f);
> +	snd_soc_write(codec, SGTL5000_CHIP_PAD_STRENGTH, reg);
>  
>  	snd_soc_write(codec, SGTL5000_CHIP_ANA_CTRL,
>  			SGTL5000_HP_ZCD_EN |
> @@ -1347,6 +1357,13 @@ static int sgtl5000_i2c_probe(struct i2c_client *client,
>  		}
>  	}
>  
> +	sgtl5000->lrclk_strength = I2S_LRCLK_STRENGTH_LOW;
> +	if (!of_property_read_u32(np, "lrclk-strength", &value)) {
> +		if (value > I2S_LRCLK_STRENGTH_HIGH)
> +			value = I2S_LRCLK_STRENGTH_LOW;
> +		sgtl5000->lrclk_strength = value;
> +	}
> +
>  	/* Ensure sgtl5000 will start with sane register values */
>  	sgtl5000_fill_defaults(client);
>  


More information about the Alsa-devel mailing list