diff options
author | Jean-Michel Hautbois <jean-michel.hautbois@vodalys.com> | 2014-10-14 02:43:11 -0400 |
---|---|---|
committer | Mark Brown <broonie@kernel.org> | 2014-10-20 07:22:33 -0400 |
commit | bd0593f5f6add279257334b4a76aecd3ee8d31dc (patch) | |
tree | 1bad69bc4a955dd74dcfb9c38cb069954bfdf20b /sound/soc/codecs/sgtl5000.c | |
parent | 7f6d75d77683c8f9c18836a2fea2a1e76efc3a9a (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.c | 55 |
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 | ||
125 | enum 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 */ |
125 | struct sgtl5000_priv { | 133 | struct 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 { | |||
145 | static int mic_bias_event(struct snd_soc_dapm_widget *w, | 154 | static 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 */ |