aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Documentation/devicetree/bindings/sound/tlv320aic3x.txt6
-rw-r--r--include/sound/tlv320aic3x.h10
-rw-r--r--sound/soc/codecs/tlv320aic3x.c83
-rw-r--r--sound/soc/codecs/tlv320aic3x.h4
-rw-r--r--sound/soc/davinci/davinci-evm.c6
-rw-r--r--sound/soc/omap/n810.c4
-rw-r--r--sound/soc/omap/rx51.c8
7 files changed, 106 insertions, 15 deletions
diff --git a/Documentation/devicetree/bindings/sound/tlv320aic3x.txt b/Documentation/devicetree/bindings/sound/tlv320aic3x.txt
index e7b98f41fa5f..f47c3f589fd0 100644
--- a/Documentation/devicetree/bindings/sound/tlv320aic3x.txt
+++ b/Documentation/devicetree/bindings/sound/tlv320aic3x.txt
@@ -11,6 +11,12 @@ Optional properties:
11 11
12- gpio-reset - gpio pin number used for codec reset 12- gpio-reset - gpio pin number used for codec reset
13- ai3x-gpio-func - <array of 2 int> - AIC3X_GPIO1 & AIC3X_GPIO2 Functionality 13- ai3x-gpio-func - <array of 2 int> - AIC3X_GPIO1 & AIC3X_GPIO2 Functionality
14- ai3x-micbias-vg - MicBias Voltage required.
15 1 - MICBIAS output is powered to 2.0V,
16 2 - MICBIAS output is powered to 2.5V,
17 3 - MICBIAS output is connected to AVDD,
18 If this node is not mentioned or if the value is incorrect, then MicBias
19 is powered down.
14 20
15Example: 21Example:
16 22
diff --git a/include/sound/tlv320aic3x.h b/include/sound/tlv320aic3x.h
index ffd9bc793105..9407fd00363b 100644
--- a/include/sound/tlv320aic3x.h
+++ b/include/sound/tlv320aic3x.h
@@ -46,6 +46,13 @@ enum {
46 AIC3X_GPIO2_FUNC_BUTTON_PRESS_IRQ = 15 46 AIC3X_GPIO2_FUNC_BUTTON_PRESS_IRQ = 15
47}; 47};
48 48
49enum aic3x_micbias_voltage {
50 AIC3X_MICBIAS_OFF = 0,
51 AIC3X_MICBIAS_2_0V = 1,
52 AIC3X_MICBIAS_2_5V = 2,
53 AIC3X_MICBIAS_AVDDV = 3,
54};
55
49struct aic3x_setup_data { 56struct aic3x_setup_data {
50 unsigned int gpio_func[2]; 57 unsigned int gpio_func[2];
51}; 58};
@@ -53,6 +60,9 @@ struct aic3x_setup_data {
53struct aic3x_pdata { 60struct aic3x_pdata {
54 int gpio_reset; /* < 0 if not used */ 61 int gpio_reset; /* < 0 if not used */
55 struct aic3x_setup_data *setup; 62 struct aic3x_setup_data *setup;
63
64 /* Selects the micbias voltage */
65 enum aic3x_micbias_voltage micbias_vg;
56}; 66};
57 67
58#endif 68#endif
diff --git a/sound/soc/codecs/tlv320aic3x.c b/sound/soc/codecs/tlv320aic3x.c
index 5708a973a776..ba82ba2a7133 100644
--- a/sound/soc/codecs/tlv320aic3x.c
+++ b/sound/soc/codecs/tlv320aic3x.c
@@ -85,6 +85,9 @@ struct aic3x_priv {
85#define AIC3X_MODEL_33 1 85#define AIC3X_MODEL_33 1
86#define AIC3X_MODEL_3007 2 86#define AIC3X_MODEL_3007 2
87 u16 model; 87 u16 model;
88
89 /* Selects the micbias voltage */
90 enum aic3x_micbias_voltage micbias_vg;
88}; 91};
89 92
90/* 93/*
@@ -195,6 +198,37 @@ static int snd_soc_dapm_put_volsw_aic3x(struct snd_kcontrol *kcontrol,
195 return ret; 198 return ret;
196} 199}
197 200
201/*
202 * mic bias power on/off share the same register bits with
203 * output voltage of mic bias. when power on mic bias, we
204 * need reclaim it to voltage value.
205 * 0x0 = Powered off
206 * 0x1 = MICBIAS output is powered to 2.0V,
207 * 0x2 = MICBIAS output is powered to 2.5V
208 * 0x3 = MICBIAS output is connected to AVDD
209 */
210static int mic_bias_event(struct snd_soc_dapm_widget *w,
211 struct snd_kcontrol *kcontrol, int event)
212{
213 struct snd_soc_codec *codec = w->codec;
214 struct aic3x_priv *aic3x = snd_soc_codec_get_drvdata(codec);
215
216 switch (event) {
217 case SND_SOC_DAPM_POST_PMU:
218 /* change mic bias voltage to user defined */
219 snd_soc_update_bits(codec, MICBIAS_CTRL,
220 MICBIAS_LEVEL_MASK,
221 aic3x->micbias_vg << MICBIAS_LEVEL_SHIFT);
222 break;
223
224 case SND_SOC_DAPM_PRE_PMD:
225 snd_soc_update_bits(codec, MICBIAS_CTRL,
226 MICBIAS_LEVEL_MASK, 0);
227 break;
228 }
229 return 0;
230}
231
198static const char *aic3x_left_dac_mux[] = { "DAC_L1", "DAC_L3", "DAC_L2" }; 232static const char *aic3x_left_dac_mux[] = { "DAC_L1", "DAC_L3", "DAC_L2" };
199static const char *aic3x_right_dac_mux[] = { "DAC_R1", "DAC_R3", "DAC_R2" }; 233static const char *aic3x_right_dac_mux[] = { "DAC_R1", "DAC_R3", "DAC_R2" };
200static const char *aic3x_left_hpcom_mux[] = 234static const char *aic3x_left_hpcom_mux[] =
@@ -596,12 +630,9 @@ static const struct snd_soc_dapm_widget aic3x_dapm_widgets[] = {
596 AIC3X_ASD_INTF_CTRLA, 0, 3, 3, 0), 630 AIC3X_ASD_INTF_CTRLA, 0, 3, 3, 0),
597 631
598 /* Mic Bias */ 632 /* Mic Bias */
599 SND_SOC_DAPM_REG(snd_soc_dapm_micbias, "Mic Bias 2V", 633 SND_SOC_DAPM_SUPPLY("Mic Bias", MICBIAS_CTRL, 6, 0,
600 MICBIAS_CTRL, 6, 3, 1, 0), 634 mic_bias_event,
601 SND_SOC_DAPM_REG(snd_soc_dapm_micbias, "Mic Bias 2.5V", 635 SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_PRE_PMD),
602 MICBIAS_CTRL, 6, 3, 2, 0),
603 SND_SOC_DAPM_REG(snd_soc_dapm_micbias, "Mic Bias AVDD",
604 MICBIAS_CTRL, 6, 3, 3, 0),
605 636
606 /* Output mixers */ 637 /* Output mixers */
607 SND_SOC_DAPM_MIXER("Left Line Mixer", SND_SOC_NOPM, 0, 0, 638 SND_SOC_DAPM_MIXER("Left Line Mixer", SND_SOC_NOPM, 0, 0,
@@ -1386,6 +1417,24 @@ static int aic3x_probe(struct snd_soc_codec *codec)
1386 if (aic3x->model == AIC3X_MODEL_3007) 1417 if (aic3x->model == AIC3X_MODEL_3007)
1387 snd_soc_add_codec_controls(codec, &aic3x_classd_amp_gain_ctrl, 1); 1418 snd_soc_add_codec_controls(codec, &aic3x_classd_amp_gain_ctrl, 1);
1388 1419
1420 /* set mic bias voltage */
1421 switch (aic3x->micbias_vg) {
1422 case AIC3X_MICBIAS_2_0V:
1423 case AIC3X_MICBIAS_2_5V:
1424 case AIC3X_MICBIAS_AVDDV:
1425 snd_soc_update_bits(codec, MICBIAS_CTRL,
1426 MICBIAS_LEVEL_MASK,
1427 (aic3x->micbias_vg) << MICBIAS_LEVEL_SHIFT);
1428 break;
1429 case AIC3X_MICBIAS_OFF:
1430 /*
1431 * noting to do. target won't enter here. This is just to avoid
1432 * compile time warning "warning: enumeration value
1433 * 'AIC3X_MICBIAS_OFF' not handled in switch"
1434 */
1435 break;
1436 }
1437
1389 aic3x_add_widgets(codec); 1438 aic3x_add_widgets(codec);
1390 list_add(&aic3x->list, &reset_list); 1439 list_add(&aic3x->list, &reset_list);
1391 1440
@@ -1461,6 +1510,7 @@ static int aic3x_i2c_probe(struct i2c_client *i2c,
1461 struct aic3x_setup_data *ai3x_setup; 1510 struct aic3x_setup_data *ai3x_setup;
1462 struct device_node *np = i2c->dev.of_node; 1511 struct device_node *np = i2c->dev.of_node;
1463 int ret; 1512 int ret;
1513 u32 value;
1464 1514
1465 aic3x = devm_kzalloc(&i2c->dev, sizeof(struct aic3x_priv), GFP_KERNEL); 1515 aic3x = devm_kzalloc(&i2c->dev, sizeof(struct aic3x_priv), GFP_KERNEL);
1466 if (aic3x == NULL) { 1516 if (aic3x == NULL) {
@@ -1474,6 +1524,7 @@ static int aic3x_i2c_probe(struct i2c_client *i2c,
1474 if (pdata) { 1524 if (pdata) {
1475 aic3x->gpio_reset = pdata->gpio_reset; 1525 aic3x->gpio_reset = pdata->gpio_reset;
1476 aic3x->setup = pdata->setup; 1526 aic3x->setup = pdata->setup;
1527 aic3x->micbias_vg = pdata->micbias_vg;
1477 } else if (np) { 1528 } else if (np) {
1478 ai3x_setup = devm_kzalloc(&i2c->dev, sizeof(*ai3x_setup), 1529 ai3x_setup = devm_kzalloc(&i2c->dev, sizeof(*ai3x_setup),
1479 GFP_KERNEL); 1530 GFP_KERNEL);
@@ -1493,6 +1544,26 @@ static int aic3x_i2c_probe(struct i2c_client *i2c,
1493 aic3x->setup = ai3x_setup; 1544 aic3x->setup = ai3x_setup;
1494 } 1545 }
1495 1546
1547 if (!of_property_read_u32(np, "ai3x-micbias-vg", &value)) {
1548 switch (value) {
1549 case 1 :
1550 aic3x->micbias_vg = AIC3X_MICBIAS_2_0V;
1551 break;
1552 case 2 :
1553 aic3x->micbias_vg = AIC3X_MICBIAS_2_5V;
1554 break;
1555 case 3 :
1556 aic3x->micbias_vg = AIC3X_MICBIAS_AVDDV;
1557 break;
1558 default :
1559 aic3x->micbias_vg = AIC3X_MICBIAS_OFF;
1560 dev_err(&i2c->dev, "Unsuitable MicBias voltage "
1561 "found in DT\n");
1562 }
1563 } else {
1564 aic3x->micbias_vg = AIC3X_MICBIAS_OFF;
1565 }
1566
1496 } else { 1567 } else {
1497 aic3x->gpio_reset = -1; 1568 aic3x->gpio_reset = -1;
1498 } 1569 }
diff --git a/sound/soc/codecs/tlv320aic3x.h b/sound/soc/codecs/tlv320aic3x.h
index 6db3c41b0163..e521ac3ddde8 100644
--- a/sound/soc/codecs/tlv320aic3x.h
+++ b/sound/soc/codecs/tlv320aic3x.h
@@ -238,6 +238,10 @@
238/* Default input volume */ 238/* Default input volume */
239#define DEFAULT_GAIN 0x20 239#define DEFAULT_GAIN 0x20
240 240
241/* MICBIAS Control Register */
242#define MICBIAS_LEVEL_SHIFT (6)
243#define MICBIAS_LEVEL_MASK (3 << 6)
244
241/* headset detection / button API */ 245/* headset detection / button API */
242 246
243/* The AIC3x supports detection of stereo headsets (GND + left + right signal) 247/* The AIC3x supports detection of stereo headsets (GND + left + right signal)
diff --git a/sound/soc/davinci/davinci-evm.c b/sound/soc/davinci/davinci-evm.c
index d55e6477bff0..484b22c5df5d 100644
--- a/sound/soc/davinci/davinci-evm.c
+++ b/sound/soc/davinci/davinci-evm.c
@@ -116,9 +116,9 @@ static const struct snd_soc_dapm_route audio_map[] = {
116 {"Line Out", NULL, "RLOUT"}, 116 {"Line Out", NULL, "RLOUT"},
117 117
118 /* Mic connected to (MIC3L | MIC3R) */ 118 /* Mic connected to (MIC3L | MIC3R) */
119 {"MIC3L", NULL, "Mic Bias 2V"}, 119 {"MIC3L", NULL, "Mic Bias"},
120 {"MIC3R", NULL, "Mic Bias 2V"}, 120 {"MIC3R", NULL, "Mic Bias"},
121 {"Mic Bias 2V", NULL, "Mic Jack"}, 121 {"Mic Bias", NULL, "Mic Jack"},
122 122
123 /* Line In connected to (LINE1L | LINE2L), (LINE1R | LINE2R) */ 123 /* Line In connected to (LINE1L | LINE2L), (LINE1R | LINE2R) */
124 {"LINE1L", NULL, "Line In"}, 124 {"LINE1L", NULL, "Line In"},
diff --git a/sound/soc/omap/n810.c b/sound/soc/omap/n810.c
index 230b8c144848..ee7cd53aa3ee 100644
--- a/sound/soc/omap/n810.c
+++ b/sound/soc/omap/n810.c
@@ -230,8 +230,8 @@ static const struct snd_soc_dapm_route audio_map[] = {
230 {"Ext Spk", NULL, "LLOUT"}, 230 {"Ext Spk", NULL, "LLOUT"},
231 {"Ext Spk", NULL, "RLOUT"}, 231 {"Ext Spk", NULL, "RLOUT"},
232 232
233 {"DMic Rate 64", NULL, "Mic Bias 2V"}, 233 {"DMic Rate 64", NULL, "Mic Bias"},
234 {"Mic Bias 2V", NULL, "DMic"}, 234 {"Mic Bias", NULL, "DMic"},
235}; 235};
236 236
237static const char *spk_function[] = {"Off", "On"}; 237static const char *spk_function[] = {"Off", "On"};
diff --git a/sound/soc/omap/rx51.c b/sound/soc/omap/rx51.c
index d921ddbe3ecb..3cd525748975 100644
--- a/sound/soc/omap/rx51.c
+++ b/sound/soc/omap/rx51.c
@@ -248,16 +248,16 @@ static const struct snd_soc_dapm_route audio_map[] = {
248 {"FM Transmitter", NULL, "LLOUT"}, 248 {"FM Transmitter", NULL, "LLOUT"},
249 {"FM Transmitter", NULL, "RLOUT"}, 249 {"FM Transmitter", NULL, "RLOUT"},
250 250
251 {"DMic Rate 64", NULL, "Mic Bias 2V"}, 251 {"DMic Rate 64", NULL, "Mic Bias"},
252 {"Mic Bias 2V", NULL, "DMic"}, 252 {"Mic Bias", NULL, "DMic"},
253}; 253};
254 254
255static const struct snd_soc_dapm_route audio_mapb[] = { 255static const struct snd_soc_dapm_route audio_mapb[] = {
256 {"b LINE2R", NULL, "MONO_LOUT"}, 256 {"b LINE2R", NULL, "MONO_LOUT"},
257 {"Earphone", NULL, "b HPLOUT"}, 257 {"Earphone", NULL, "b HPLOUT"},
258 258
259 {"LINE1L", NULL, "b Mic Bias 2.5V"}, 259 {"LINE1L", NULL, "b Mic Bias"},
260 {"b Mic Bias 2.5V", NULL, "HS Mic"} 260 {"b Mic Bias", NULL, "HS Mic"}
261}; 261};
262 262
263static const char *spk_function[] = {"Off", "On"}; 263static const char *spk_function[] = {"Off", "On"};