diff options
-rw-r--r-- | Documentation/devicetree/bindings/sound/tlv320aic3x.txt | 6 | ||||
-rw-r--r-- | include/sound/tlv320aic3x.h | 10 | ||||
-rw-r--r-- | sound/soc/codecs/tlv320aic3x.c | 83 | ||||
-rw-r--r-- | sound/soc/codecs/tlv320aic3x.h | 4 | ||||
-rw-r--r-- | sound/soc/davinci/davinci-evm.c | 6 | ||||
-rw-r--r-- | sound/soc/omap/n810.c | 4 | ||||
-rw-r--r-- | sound/soc/omap/rx51.c | 8 |
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 | ||
15 | Example: | 21 | Example: |
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 | ||
49 | enum 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 | |||
49 | struct aic3x_setup_data { | 56 | struct 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 { | |||
53 | struct aic3x_pdata { | 60 | struct 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 | */ | ||
210 | static 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 | |||
198 | static const char *aic3x_left_dac_mux[] = { "DAC_L1", "DAC_L3", "DAC_L2" }; | 232 | static const char *aic3x_left_dac_mux[] = { "DAC_L1", "DAC_L3", "DAC_L2" }; |
199 | static const char *aic3x_right_dac_mux[] = { "DAC_R1", "DAC_R3", "DAC_R2" }; | 233 | static const char *aic3x_right_dac_mux[] = { "DAC_R1", "DAC_R3", "DAC_R2" }; |
200 | static const char *aic3x_left_hpcom_mux[] = | 234 | static 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 | ||
237 | static const char *spk_function[] = {"Off", "On"}; | 237 | static 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 | ||
255 | static const struct snd_soc_dapm_route audio_mapb[] = { | 255 | static 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 | ||
263 | static const char *spk_function[] = {"Off", "On"}; | 263 | static const char *spk_function[] = {"Off", "On"}; |