diff options
| -rw-r--r-- | Documentation/devicetree/bindings/sound/tlv320aic3x.txt | 5 | ||||
| -rw-r--r-- | sound/soc/codecs/tlv320aic3x.c | 45 | ||||
| -rw-r--r-- | sound/soc/codecs/tlv320aic3x.h | 8 |
3 files changed, 58 insertions, 0 deletions
diff --git a/Documentation/devicetree/bindings/sound/tlv320aic3x.txt b/Documentation/devicetree/bindings/sound/tlv320aic3x.txt index 47a213c411ce..ba5b45c483f5 100644 --- a/Documentation/devicetree/bindings/sound/tlv320aic3x.txt +++ b/Documentation/devicetree/bindings/sound/tlv320aic3x.txt | |||
| @@ -26,6 +26,11 @@ Optional properties: | |||
| 26 | 3 - MICBIAS output is connected to AVDD, | 26 | 3 - MICBIAS output is connected to AVDD, |
| 27 | If this node is not mentioned or if the value is incorrect, then MicBias | 27 | If this node is not mentioned or if the value is incorrect, then MicBias |
| 28 | is powered down. | 28 | is powered down. |
| 29 | - ai3x-ocmv - Output Common-Mode Voltage selection: | ||
| 30 | 0 - 1.35V, | ||
| 31 | 1 - 1.5V, | ||
| 32 | 2 - 1.65V, | ||
| 33 | 3 - 1.8V | ||
| 29 | - AVDD-supply, IOVDD-supply, DRVDD-supply, DVDD-supply : power supplies for the | 34 | - AVDD-supply, IOVDD-supply, DRVDD-supply, DVDD-supply : power supplies for the |
| 30 | device as covered in Documentation/devicetree/bindings/regulator/regulator.txt | 35 | device as covered in Documentation/devicetree/bindings/regulator/regulator.txt |
| 31 | 36 | ||
diff --git a/sound/soc/codecs/tlv320aic3x.c b/sound/soc/codecs/tlv320aic3x.c index 29bf8c81ae02..ca880859f0c3 100644 --- a/sound/soc/codecs/tlv320aic3x.c +++ b/sound/soc/codecs/tlv320aic3x.c | |||
| @@ -93,6 +93,8 @@ struct aic3x_priv { | |||
| 93 | 93 | ||
| 94 | /* Selects the micbias voltage */ | 94 | /* Selects the micbias voltage */ |
| 95 | enum aic3x_micbias_voltage micbias_vg; | 95 | enum aic3x_micbias_voltage micbias_vg; |
| 96 | /* Output Common-Mode Voltage */ | ||
| 97 | u8 ocmv; | ||
| 96 | }; | 98 | }; |
| 97 | 99 | ||
| 98 | static const struct reg_default aic3x_reg[] = { | 100 | static const struct reg_default aic3x_reg[] = { |
| @@ -1572,6 +1574,10 @@ static int aic3x_init(struct snd_soc_codec *codec) | |||
| 1572 | break; | 1574 | break; |
| 1573 | } | 1575 | } |
| 1574 | 1576 | ||
| 1577 | /* Output common-mode voltage = 1.5 V */ | ||
| 1578 | snd_soc_update_bits(codec, HPOUT_SC, HPOUT_SC_OCMV_MASK, | ||
| 1579 | aic3x->ocmv << HPOUT_SC_OCMV_SHIFT); | ||
| 1580 | |||
| 1575 | return 0; | 1581 | return 0; |
| 1576 | } | 1582 | } |
| 1577 | 1583 | ||
| @@ -1699,6 +1705,43 @@ static struct snd_soc_codec_driver soc_codec_dev_aic3x = { | |||
| 1699 | }, | 1705 | }, |
| 1700 | }; | 1706 | }; |
| 1701 | 1707 | ||
| 1708 | static void aic3x_configure_ocmv(struct i2c_client *client) | ||
| 1709 | { | ||
| 1710 | struct device_node *np = client->dev.of_node; | ||
| 1711 | struct aic3x_priv *aic3x = i2c_get_clientdata(client); | ||
| 1712 | u32 value; | ||
| 1713 | int dvdd, avdd; | ||
| 1714 | |||
| 1715 | if (np && !of_property_read_u32(np, "ai3x-ocmv", &value)) { | ||
| 1716 | /* OCMV setting is forced by DT */ | ||
| 1717 | if (value <= 3) { | ||
| 1718 | aic3x->ocmv = value; | ||
| 1719 | return; | ||
| 1720 | } | ||
| 1721 | } | ||
| 1722 | |||
| 1723 | dvdd = regulator_get_voltage(aic3x->supplies[1].consumer); | ||
| 1724 | avdd = regulator_get_voltage(aic3x->supplies[2].consumer); | ||
| 1725 | |||
| 1726 | if (avdd > 3600000 || dvdd > 1950000) { | ||
| 1727 | dev_warn(&client->dev, | ||
| 1728 | "Too high supply voltage(s) AVDD: %d, DVDD: %d\n", | ||
| 1729 | avdd, dvdd); | ||
| 1730 | } else if (avdd == 3600000 && dvdd == 1950000) { | ||
| 1731 | aic3x->ocmv = HPOUT_SC_OCMV_1_8V; | ||
| 1732 | } else if (avdd > 3300000 && dvdd > 1800000) { | ||
| 1733 | aic3x->ocmv = HPOUT_SC_OCMV_1_65V; | ||
| 1734 | } else if (avdd > 3000000 && dvdd > 1650000) { | ||
| 1735 | aic3x->ocmv = HPOUT_SC_OCMV_1_5V; | ||
| 1736 | } else if (avdd >= 2700000 && dvdd >= 1525000) { | ||
| 1737 | aic3x->ocmv = HPOUT_SC_OCMV_1_35V; | ||
| 1738 | } else { | ||
| 1739 | dev_warn(&client->dev, | ||
| 1740 | "Invalid supply voltage(s) AVDD: %d, DVDD: %d\n", | ||
| 1741 | avdd, dvdd); | ||
| 1742 | } | ||
| 1743 | } | ||
| 1744 | |||
| 1702 | /* | 1745 | /* |
| 1703 | * AIC3X 2 wire address can be up to 4 devices with device addresses | 1746 | * AIC3X 2 wire address can be up to 4 devices with device addresses |
| 1704 | * 0x18, 0x19, 0x1A, 0x1B | 1747 | * 0x18, 0x19, 0x1A, 0x1B |
| @@ -1816,6 +1859,8 @@ static int aic3x_i2c_probe(struct i2c_client *i2c, | |||
| 1816 | goto err_gpio; | 1859 | goto err_gpio; |
| 1817 | } | 1860 | } |
| 1818 | 1861 | ||
| 1862 | aic3x_configure_ocmv(i2c); | ||
| 1863 | |||
| 1819 | if (aic3x->model == AIC3X_MODEL_3007) { | 1864 | if (aic3x->model == AIC3X_MODEL_3007) { |
| 1820 | ret = regmap_register_patch(aic3x->regmap, aic3007_class_d, | 1865 | ret = regmap_register_patch(aic3x->regmap, aic3007_class_d, |
| 1821 | ARRAY_SIZE(aic3007_class_d)); | 1866 | ARRAY_SIZE(aic3007_class_d)); |
diff --git a/sound/soc/codecs/tlv320aic3x.h b/sound/soc/codecs/tlv320aic3x.h index 89fa692df206..34c35196aa0d 100644 --- a/sound/soc/codecs/tlv320aic3x.h +++ b/sound/soc/codecs/tlv320aic3x.h | |||
| @@ -243,6 +243,14 @@ | |||
| 243 | #define MICBIAS_LEVEL_SHIFT (6) | 243 | #define MICBIAS_LEVEL_SHIFT (6) |
| 244 | #define MICBIAS_LEVEL_MASK (3 << 6) | 244 | #define MICBIAS_LEVEL_MASK (3 << 6) |
| 245 | 245 | ||
| 246 | /* HPOUT_SC */ | ||
| 247 | #define HPOUT_SC_OCMV_MASK (3 << 6) | ||
| 248 | #define HPOUT_SC_OCMV_SHIFT (6) | ||
| 249 | #define HPOUT_SC_OCMV_1_35V 0 | ||
| 250 | #define HPOUT_SC_OCMV_1_5V 1 | ||
| 251 | #define HPOUT_SC_OCMV_1_65V 2 | ||
| 252 | #define HPOUT_SC_OCMV_1_8V 3 | ||
| 253 | |||
| 246 | /* headset detection / button API */ | 254 | /* headset detection / button API */ |
| 247 | 255 | ||
| 248 | /* The AIC3x supports detection of stereo headsets (GND + left + right signal) | 256 | /* The AIC3x supports detection of stereo headsets (GND + left + right signal) |
