diff options
author | Takashi Iwai <tiwai@suse.de> | 2019-11-25 16:27:33 +0300 |
---|---|---|
committer | Takashi Iwai <tiwai@suse.de> | 2019-11-25 16:27:41 +0300 |
commit | 09578eacaaa44149738267083ccc050990409f86 (patch) | |
tree | cf614ee065fe5479e4638abebe12c9e1578b09d9 /sound/soc/codecs/tlv320aic31xx.c | |
parent | c6b6fc206586cc07a18595d2a3d815a806a057d0 (diff) | |
parent | 8c4d2a0bfbd27d030e4652b714cd5a1598f3559b (diff) | |
download | linux-09578eacaaa44149738267083ccc050990409f86.tar.xz |
Merge tag 'asoc-v5.5-2' of https://git.kernel.org/pub/scm/linux/kernel/git/broonie/sound into for-linus
ASoC: More updates for v5.5
Some more development work for v5.5. Highlights include:
- More cleanups from Morimoto-san.
- Trigger word detection for RT5677.
Signed-off-by: Takashi Iwai <tiwai@suse.de>
Diffstat (limited to 'sound/soc/codecs/tlv320aic31xx.c')
-rw-r--r-- | sound/soc/codecs/tlv320aic31xx.c | 45 |
1 files changed, 45 insertions, 0 deletions
diff --git a/sound/soc/codecs/tlv320aic31xx.c b/sound/soc/codecs/tlv320aic31xx.c index df627a08def9..f6f19fdc72f5 100644 --- a/sound/soc/codecs/tlv320aic31xx.c +++ b/sound/soc/codecs/tlv320aic31xx.c @@ -171,6 +171,7 @@ struct aic31xx_priv { int rate_div_line; bool master_dapm_route_applied; int irq; + u8 ocmv; /* output common-mode voltage */ }; struct aic31xx_rate_divs { @@ -1312,6 +1313,11 @@ static int aic31xx_codec_probe(struct snd_soc_component *component) if (ret) return ret; + /* set output common-mode voltage */ + snd_soc_component_update_bits(component, AIC31XX_HPDRIVER, + AIC31XX_HPD_OCMV_MASK, + aic31xx->ocmv << AIC31XX_HPD_OCMV_SHIFT); + return 0; } @@ -1501,6 +1507,43 @@ exit: return IRQ_NONE; } +static void aic31xx_configure_ocmv(struct aic31xx_priv *priv) +{ + struct device *dev = priv->dev; + int dvdd, avdd; + u32 value; + + if (dev->fwnode && + fwnode_property_read_u32(dev->fwnode, "ai31xx-ocmv", &value)) { + /* OCMV setting is forced by DT */ + if (value <= 3) { + priv->ocmv = value; + return; + } + } + + avdd = regulator_get_voltage(priv->supplies[3].consumer); + dvdd = regulator_get_voltage(priv->supplies[5].consumer); + + if (avdd > 3600000 || dvdd > 1950000) { + dev_warn(dev, + "Too high supply voltage(s) AVDD: %d, DVDD: %d\n", + avdd, dvdd); + } else if (avdd == 3600000 && dvdd == 1950000) { + priv->ocmv = AIC31XX_HPD_OCMV_1_8V; + } else if (avdd >= 3300000 && dvdd >= 1800000) { + priv->ocmv = AIC31XX_HPD_OCMV_1_65V; + } else if (avdd >= 3000000 && dvdd >= 1650000) { + priv->ocmv = AIC31XX_HPD_OCMV_1_5V; + } else if (avdd >= 2700000 && dvdd >= 1525000) { + priv->ocmv = AIC31XX_HPD_OCMV_1_35V; + } else { + dev_warn(dev, + "Invalid supply voltage(s) AVDD: %d, DVDD: %d\n", + avdd, dvdd); + } +} + static int aic31xx_i2c_probe(struct i2c_client *i2c, const struct i2c_device_id *id) { @@ -1570,6 +1613,8 @@ static int aic31xx_i2c_probe(struct i2c_client *i2c, return ret; } + aic31xx_configure_ocmv(aic31xx); + if (aic31xx->irq > 0) { regmap_update_bits(aic31xx->regmap, AIC31XX_GPIO1, AIC31XX_GPIO1_FUNC_MASK, |