aboutsummaryrefslogtreecommitdiffstats
path: root/sound/soc/codecs/sgtl5000.c
diff options
context:
space:
mode:
authorJean-Michel Hautbois <jean-michel.hautbois@vodalys.com>2014-10-14 02:43:11 -0400
committerMark Brown <broonie@kernel.org>2014-10-20 07:22:33 -0400
commitbd0593f5f6add279257334b4a76aecd3ee8d31dc (patch)
tree1bad69bc4a955dd74dcfb9c38cb069954bfdf20b /sound/soc/codecs/sgtl5000.c
parent7f6d75d77683c8f9c18836a2fea2a1e76efc3a9a (diff)
ASoC: sgtl5000: Add MicBias resistor support in DT
Some systems may require a different resistor than the default one (4K). This adds a property in sgtl5000 codec. It keeps the default of 4K when nothing is specified so it does not break existing code. Signed-off-by: Jean-Michel Hautbois <jean-michel.hautbois@vodalys.com> Signed-off-by: Mark Brown <broonie@kernel.org>
Diffstat (limited to 'sound/soc/codecs/sgtl5000.c')
-rw-r--r--sound/soc/codecs/sgtl5000.c55
1 files changed, 51 insertions, 4 deletions
diff --git a/sound/soc/codecs/sgtl5000.c b/sound/soc/codecs/sgtl5000.c
index 10160e7a9277..c417b4ad0492 100644
--- a/sound/soc/codecs/sgtl5000.c
+++ b/sound/soc/codecs/sgtl5000.c
@@ -16,6 +16,7 @@
16#include <linux/pm.h> 16#include <linux/pm.h>
17#include <linux/i2c.h> 17#include <linux/i2c.h>
18#include <linux/clk.h> 18#include <linux/clk.h>
19#include <linux/log2.h>
19#include <linux/regmap.h> 20#include <linux/regmap.h>
20#include <linux/regulator/driver.h> 21#include <linux/regulator/driver.h>
21#include <linux/regulator/machine.h> 22#include <linux/regulator/machine.h>
@@ -121,6 +122,13 @@ struct ldo_regulator {
121 bool enabled; 122 bool enabled;
122}; 123};
123 124
125enum sgtl5000_micbias_resistor {
126 SGTL5000_MICBIAS_OFF = 0,
127 SGTL5000_MICBIAS_2K = 2,
128 SGTL5000_MICBIAS_4K = 4,
129 SGTL5000_MICBIAS_8K = 8,
130};
131
124/* sgtl5000 private structure in codec */ 132/* sgtl5000 private structure in codec */
125struct sgtl5000_priv { 133struct sgtl5000_priv {
126 int sysclk; /* sysclk rate */ 134 int sysclk; /* sysclk rate */
@@ -131,6 +139,7 @@ struct sgtl5000_priv {
131 struct regmap *regmap; 139 struct regmap *regmap;
132 struct clk *mclk; 140 struct clk *mclk;
133 int revision; 141 int revision;
142 u8 micbias_resistor;
134}; 143};
135 144
136/* 145/*
@@ -145,12 +154,14 @@ struct sgtl5000_priv {
145static int mic_bias_event(struct snd_soc_dapm_widget *w, 154static int mic_bias_event(struct snd_soc_dapm_widget *w,
146 struct snd_kcontrol *kcontrol, int event) 155 struct snd_kcontrol *kcontrol, int event)
147{ 156{
157 struct sgtl5000_priv *sgtl5000 = snd_soc_codec_get_drvdata(w->codec);
158
148 switch (event) { 159 switch (event) {
149 case SND_SOC_DAPM_POST_PMU: 160 case SND_SOC_DAPM_POST_PMU:
150 /* change mic bias resistor to 4Kohm */ 161 /* change mic bias resistor */
151 snd_soc_update_bits(w->codec, SGTL5000_CHIP_MIC_CTRL, 162 snd_soc_update_bits(w->codec, SGTL5000_CHIP_MIC_CTRL,
152 SGTL5000_BIAS_R_MASK, 163 SGTL5000_BIAS_R_MASK,
153 SGTL5000_BIAS_R_4k << SGTL5000_BIAS_R_SHIFT); 164 sgtl5000->micbias_resistor << SGTL5000_BIAS_R_SHIFT);
154 break; 165 break;
155 166
156 case SND_SOC_DAPM_PRE_PMD: 167 case SND_SOC_DAPM_PRE_PMD:
@@ -1327,7 +1338,9 @@ static int sgtl5000_probe(struct snd_soc_codec *codec)
1327 SGTL5000_HP_ZCD_EN | 1338 SGTL5000_HP_ZCD_EN |
1328 SGTL5000_ADC_ZCD_EN); 1339 SGTL5000_ADC_ZCD_EN);
1329 1340
1330 snd_soc_write(codec, SGTL5000_CHIP_MIC_CTRL, 2); 1341 snd_soc_update_bits(codec, SGTL5000_CHIP_MIC_CTRL,
1342 SGTL5000_BIAS_R_MASK,
1343 sgtl5000->micbias_resistor << SGTL5000_BIAS_R_SHIFT);
1331 1344
1332 /* 1345 /*
1333 * disable DAP 1346 * disable DAP
@@ -1419,6 +1432,8 @@ static int sgtl5000_i2c_probe(struct i2c_client *client,
1419 struct sgtl5000_priv *sgtl5000; 1432 struct sgtl5000_priv *sgtl5000;
1420 int ret, reg, rev; 1433 int ret, reg, rev;
1421 unsigned int mclk; 1434 unsigned int mclk;
1435 struct device_node *np = client->dev.of_node;
1436 u32 value;
1422 1437
1423 sgtl5000 = devm_kzalloc(&client->dev, sizeof(struct sgtl5000_priv), 1438 sgtl5000 = devm_kzalloc(&client->dev, sizeof(struct sgtl5000_priv),
1424 GFP_KERNEL); 1439 GFP_KERNEL);
@@ -1471,6 +1486,38 @@ static int sgtl5000_i2c_probe(struct i2c_client *client,
1471 dev_info(&client->dev, "sgtl5000 revision 0x%x\n", rev); 1486 dev_info(&client->dev, "sgtl5000 revision 0x%x\n", rev);
1472 sgtl5000->revision = rev; 1487 sgtl5000->revision = rev;
1473 1488
1489 if (np) {
1490 if (!of_property_read_u32(np,
1491 "micbias-resistor-k-ohms", &value)) {
1492 switch (value) {
1493 case SGTL5000_MICBIAS_OFF:
1494 sgtl5000->micbias_resistor = 0;
1495 break;
1496 case SGTL5000_MICBIAS_2K:
1497 sgtl5000->micbias_resistor = 1;
1498 break;
1499 case SGTL5000_MICBIAS_4K:
1500 sgtl5000->micbias_resistor = 2;
1501 break;
1502 case SGTL5000_MICBIAS_8K:
1503 sgtl5000->micbias_resistor = 3;
1504 break;
1505 default:
1506 sgtl5000->micbias_resistor = 2;
1507 dev_err(&client->dev,
1508 "Unsuitable MicBias resistor\n");
1509 }
1510 } else {
1511 /* default is 4Kohms */
1512 sgtl5000->micbias_resistor = 2;
1513 }
1514 dev_err(&client->dev,
1515 "Unsuitable MicBias resistor\n");
1516 }
1517 } else {
1518 }
1519 }
1520
1474 i2c_set_clientdata(client, sgtl5000); 1521 i2c_set_clientdata(client, sgtl5000);
1475 1522
1476 /* Ensure sgtl5000 will start with sane register values */ 1523 /* Ensure sgtl5000 will start with sane register values */