summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorFabio Estevam <fabio.estevam@nxp.com>2017-04-05 11:32:34 -0300
committerPhilippe Schenker <philippe.schenker@toradex.com>2019-05-09 11:13:55 +0200
commit0c1a191e8181f8664d79c6e4e7f4d826f10791c8 (patch)
tree83918ac6c0cf80dd5b61e0e4a2c804a594d6c751
parentc000827003594be386e326b2fd7d6188954e0d30 (diff)
ASoC: sgtl5000: Allow LRCLK pad drive strength to be changed
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@nxp.com> Tested-by: Max Krummenacher <max.krummenacher@toradex.com> Signed-off-by: Mark Brown <broonie@kernel.org> (cherry picked from commit 91dca475d4368bef170fe9b20bb2005b241cc4bc)
-rw-r--r--Documentation/devicetree/bindings/sound/sgtl5000.txt9
-rw-r--r--sound/soc/codecs/sgtl5000.c19
2 files changed, 27 insertions, 1 deletions
diff --git a/Documentation/devicetree/bindings/sound/sgtl5000.txt b/Documentation/devicetree/bindings/sound/sgtl5000.txt
index 5666da7b8605..7a73a9d62015 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@0a {
diff --git a/sound/soc/codecs/sgtl5000.c b/sound/soc/codecs/sgtl5000.c
index 2d242cfd7e8e..d55fdff55e62 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;
};
/*
@@ -1142,6 +1150,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 */
@@ -1171,7 +1180,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 |
@@ -1400,6 +1410,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);