aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorFabio Estevam <fabio.estevam@nxp.com>2017-04-05 10:32:34 -0400
committerMark Brown <broonie@kernel.org>2017-04-10 15:21:46 -0400
commit570c70a60f53ca737ead4e5966c446bf0d39fac9 (patch)
treec7e65a6d8af2200085c3ab86ef76eff2d7f1db8e
parenta5de5b74a50113564a1e0850e2da96c37c35e55d (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>
-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:
26 If this node is not mentioned or the value is unknown, then 26 If this node is not mentioned or the value is unknown, then
27 the value is set to 1.25V. 27 the value is set to 1.25V.
28 28
29- lrclk-strength: the LRCLK pad strength. Possible values are:
300, 1, 2 and 3 as per the table below:
31
32VDDIO 1.8V 2.5V 3.3V
330 = Disable
341 = 1.66 mA 2.87 mA 4.02 mA
352 = 3.33 mA 5.74 mA 8.03 mA
363 = 4.99 mA 8.61 mA 12.05 mA
37
29Example: 38Example:
30 39
31codec: sgtl5000@0a { 40codec: sgtl5000@0a {
diff --git a/sound/soc/codecs/sgtl5000.c b/sound/soc/codecs/sgtl5000.c
index 1589325855bc..5a2702edeb77 100644
--- a/sound/soc/codecs/sgtl5000.c
+++ b/sound/soc/codecs/sgtl5000.c
@@ -99,6 +99,13 @@ enum sgtl5000_micbias_resistor {
99 SGTL5000_MICBIAS_8K = 8, 99 SGTL5000_MICBIAS_8K = 8,
100}; 100};
101 101
102enum {
103 I2S_LRCLK_STRENGTH_DISABLE,
104 I2S_LRCLK_STRENGTH_LOW,
105 I2S_LRCLK_STRENGTH_MEDIUM,
106 I2S_LRCLK_STRENGTH_HIGH,
107};
108
102/* sgtl5000 private structure in codec */ 109/* sgtl5000 private structure in codec */
103struct sgtl5000_priv { 110struct sgtl5000_priv {
104 int sysclk; /* sysclk rate */ 111 int sysclk; /* sysclk rate */
@@ -111,6 +118,7 @@ struct sgtl5000_priv {
111 int revision; 118 int revision;
112 u8 micbias_resistor; 119 u8 micbias_resistor;
113 u8 micbias_voltage; 120 u8 micbias_voltage;
121 u8 lrclk_strength;
114}; 122};
115 123
116/* 124/*
@@ -1089,6 +1097,7 @@ static int sgtl5000_enable_regulators(struct i2c_client *client)
1089static int sgtl5000_probe(struct snd_soc_codec *codec) 1097static int sgtl5000_probe(struct snd_soc_codec *codec)
1090{ 1098{
1091 int ret; 1099 int ret;
1100 u16 reg;
1092 struct sgtl5000_priv *sgtl5000 = snd_soc_codec_get_drvdata(codec); 1101 struct sgtl5000_priv *sgtl5000 = snd_soc_codec_get_drvdata(codec);
1093 1102
1094 /* power up sgtl5000 */ 1103 /* power up sgtl5000 */
@@ -1118,7 +1127,8 @@ static int sgtl5000_probe(struct snd_soc_codec *codec)
1118 SGTL5000_DAC_MUTE_RIGHT | 1127 SGTL5000_DAC_MUTE_RIGHT |
1119 SGTL5000_DAC_MUTE_LEFT); 1128 SGTL5000_DAC_MUTE_LEFT);
1120 1129
1121 snd_soc_write(codec, SGTL5000_CHIP_PAD_STRENGTH, 0x015f); 1130 reg = ((sgtl5000->lrclk_strength) << SGTL5000_PAD_I2S_LRCLK_SHIFT | 0x5f);
1131 snd_soc_write(codec, SGTL5000_CHIP_PAD_STRENGTH, reg);
1122 1132
1123 snd_soc_write(codec, SGTL5000_CHIP_ANA_CTRL, 1133 snd_soc_write(codec, SGTL5000_CHIP_ANA_CTRL,
1124 SGTL5000_HP_ZCD_EN | 1134 SGTL5000_HP_ZCD_EN |
@@ -1347,6 +1357,13 @@ static int sgtl5000_i2c_probe(struct i2c_client *client,
1347 } 1357 }
1348 } 1358 }
1349 1359
1360 sgtl5000->lrclk_strength = I2S_LRCLK_STRENGTH_LOW;
1361 if (!of_property_read_u32(np, "lrclk-strength", &value)) {
1362 if (value > I2S_LRCLK_STRENGTH_HIGH)
1363 value = I2S_LRCLK_STRENGTH_LOW;
1364 sgtl5000->lrclk_strength = value;
1365 }
1366
1350 /* Ensure sgtl5000 will start with sane register values */ 1367 /* Ensure sgtl5000 will start with sane register values */
1351 sgtl5000_fill_defaults(client); 1368 sgtl5000_fill_defaults(client);
1352 1369