[PATCH 07/10] Modified initialization code of VI sensing
From: Ryan Lee
Date: Fri Mar 03 2017 - 14:40:36 EST
Signed-off-by: Ryan Lee <ryans.lee@xxxxxxxxxxxxxxxxxxx>
---
Initialization code of TX(VI sensing) had a problem for interleave mode configuration.
Additional configuration for volume, DC blocker, Voltage/Current limit and ADC have been added.
sound/soc/codecs/max98927.c | 195 +++++++++++++++++++++++++++++++++-----------
1 file changed, 146 insertions(+), 49 deletions(-)
diff --git a/sound/soc/codecs/max98927.c b/sound/soc/codecs/max98927.c
index 9e70883..df2f4ff 100755
--- a/sound/soc/codecs/max98927.c
+++ b/sound/soc/codecs/max98927.c
@@ -1,7 +1,7 @@
/*
* max98927.c -- MAX98927 ALSA Soc Audio driver
*
- * Copyright 2013-15 Maxim Integrated Products
+ * Copyright (C) 2016 Maxim Integrated Products
* Author: Ryan Lee <ryans.lee@xxxxxxxxxxxxxxxxxxx>
*
* This program is free software; you can redistribute it and/or modify it
@@ -230,18 +230,12 @@ static int max98927_dai_set_fmt(struct snd_soc_dai *codec_dai, unsigned int fmt)
max98927->iface, max98927->iface);
/* pcm channel configuration */
- if (max98927->iface & (SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_LEFT_J)) {
+ if (max98927->iface & (SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_LEFT_J))
regmap_write(max98927->regmap,
MAX98927_R0018_PCM_RX_EN_A,
MAX98927_PCM_RX_CH0_EN|
MAX98927_PCM_RX_CH1_EN);
- regmap_write(max98927->regmap,
- MAX98927_R0021_PCM_MASTER_MODE,
- MAX98927_PCM_TX_CH0_EN|
- MAX98927_PCM_TX_CH1_EN);
- }
- regmap_update_bits(max98927->regmap, MAX98927_R0020_PCM_MODE_CFG,
- MAX98927_PCM_MODE_CFG_PCM_BCLKEDGE, invert);
+
return 0;
}
@@ -367,12 +361,27 @@ static int max98927_dai_hw_params(struct snd_pcm_substream *substream,
goto err;
}
/* set DAI_SR to correct LRCLK frequency */
- regmap_update_bits(max98927->regmap, MAX98927_R0023_PCM_SR_SETUP1,
- MAX98927_PCM_SR_SET1_SR_MASK, sampling_rate);
- regmap_update_bits(max98927->regmap, MAX98927_R0024_PCM_SR_SETUP2,
- MAX98927_PCM_SR_SET2_SR_MASK, sampling_rate<<4);
- regmap_update_bits(max98927->regmap, MAX98927_R0024_PCM_SR_SETUP2,
- MAX98927_PCM_SR_SET2_IVADC_SR_MASK, sampling_rate);
+ regmap_update_bits(max98927->regmap,
+ MAX98927_R0023_PCM_SR_SETUP1,
+ MAX98927_PCM_SR_SET1_SR_MASK,
+ sampling_rate);
+ regmap_update_bits(max98927->regmap,
+ MAX98927_R0024_PCM_SR_SETUP2,
+ MAX98927_PCM_SR_SET2_SR_MASK,
+ sampling_rate << MAX98927_PCM_SR_SET2_SR_SHIFT);
+
+ /* set sampling rate of IV */
+ if (max98927->interleave_mode &&
+ sampling_rate > MAX98927_PCM_SR_SET1_SR_16000)
+ regmap_update_bits(max98927->regmap,
+ MAX98927_R0024_PCM_SR_SETUP2,
+ MAX98927_PCM_SR_SET2_IVADC_SR_MASK,
+ sampling_rate - 3);
+ else
+ regmap_update_bits(max98927->regmap,
+ MAX98927_R0024_PCM_SR_SETUP2,
+ MAX98927_PCM_SR_SET2_IVADC_SR_MASK,
+ sampling_rate);
return max98927_set_clock(max98927, params);
err:
return -EINVAL;
@@ -408,33 +417,28 @@ static int max98927_dac_event(struct snd_soc_dapm_widget *w,
switch (event) {
case SND_SOC_DAPM_POST_PMU:
regmap_update_bits(max98927->regmap,
- MAX98927_R003A_AMP_EN, 1, 1);
- /* enable the v and i for vi feedback */
- regmap_update_bits(max98927->regmap,
- MAX98927_R003E_MEAS_EN,
- MAX98927_MEAS_V_EN,
- MAX98927_MEAS_V_EN);
+ MAX98927_R003A_AMP_EN,
+ MAX98927_AMP_EN_MASK, 1);
+ /* enable VMON and IMON */
regmap_update_bits(max98927->regmap,
MAX98927_R003E_MEAS_EN,
- MAX98927_MEAS_I_EN,
- MAX98927_MEAS_I_EN);
+ MAX98927_MEAS_V_EN | MAX98927_MEAS_I_EN,
+ MAX98927_MEAS_V_EN | MAX98927_MEAS_I_EN);
regmap_update_bits(max98927->regmap,
- MAX98927_GLOBAL_EN_MASK, 1, 1);
+ MAX98927_R00FF_GLOBAL_SHDN,
+ MAX98927_GLOBAL_EN_MASK, 1);
break;
case SND_SOC_DAPM_POST_PMD:
regmap_update_bits(max98927->regmap,
- MAX98927_R00FF_GLOBAL_SHDN, 1, 0);
+ MAX98927_R00FF_GLOBAL_SHDN,
+ MAX98927_GLOBAL_EN_MASK, 0);
regmap_update_bits(max98927->regmap,
- MAX98927_R003A_AMP_EN, 1, 0);
- /* disable the v and i for vi feedback */
+ MAX98927_R003A_AMP_EN,
+ MAX98927_AMP_EN_MASK, 0);
+ /* disable VMON and IMON */
regmap_update_bits(max98927->regmap,
MAX98927_R003E_MEAS_EN,
- MAX98927_MEAS_V_EN,
- 0);
- regmap_update_bits(max98927->regmap,
- MAX98927_R003E_MEAS_EN,
- MAX98927_MEAS_I_EN,
- 0);
+ MAX98927_MEAS_V_EN | MAX98927_MEAS_I_EN, 0);
break;
default:
return 0;
@@ -754,13 +758,107 @@ static int max98927_probe(struct snd_soc_codec *codec)
dev_info(codec->dev,
"MAX98927 revisionID: 0x%02X\n", reg);
+ /* IV default slot configuration */
+ regmap_write(max98927->regmap,
+ MAX98927_R001C_PCM_TX_HIZ_CTRL_A,
+ 0xFF);
+ regmap_write(max98927->regmap,
+ MAX98927_R001D_PCM_TX_HIZ_CTRL_B,
+ 0xFF);
+ regmap_write(max98927->regmap,
+ MAX98927_R0025_PCM_TO_SPK_MONOMIX_A,
+ 0x80);
+ regmap_write(max98927->regmap,
+ MAX98927_R0026_PCM_TO_SPK_MONOMIX_B,
+ 0x1);
+ /* Set inital volume (+13dB) */
+ regmap_write(max98927->regmap,
+ MAX98927_R0036_AMP_VOL_CTRL,
+ 0x38);
+ regmap_write(max98927->regmap,
+ MAX98927_R003C_SPK_GAIN,
+ 0x05);
+ /* Enable DC blocker */
+ regmap_write(max98927->regmap,
+ MAX98927_R0037_AMP_DSP_CFG,
+ 0x03);
+ /* Enable IMON VMON DC blocker */
+ regmap_write(max98927->regmap,
+ MAX98927_R003F_MEAS_DSP_CFG,
+ 0xF7);
+ /* Boost Output Voltage & Current limit */
+ regmap_write(max98927->regmap,
+ MAX98927_R0040_BOOST_CTRL0,
+ 0x1C);
+ regmap_write(max98927->regmap,
+ MAX98927_R0042_BOOST_CTRL1,
+ 0x3E);
+ /* Measurement ADC config */
+ regmap_write(max98927->regmap,
+ MAX98927_R0043_MEAS_ADC_CFG,
+ 0x04);
+ regmap_write(max98927->regmap,
+ MAX98927_R0044_MEAS_ADC_BASE_MSB,
+ 0x00);
+ regmap_write(max98927->regmap,
+ MAX98927_R0045_MEAS_ADC_BASE_LSB,
+ 0x24);
+ /* Brownout Level */
+ regmap_write(max98927->regmap,
+ MAX98927_R007F_BROWNOUT_LVL4_AMP1_CTRL1,
+ 0x06);
+ /* Envelope Tracking configuration */
+ regmap_write(max98927->regmap,
+ MAX98927_R0082_ENV_TRACK_VOUT_HEADROOM,
+ 0x08);
+ regmap_write(max98927->regmap,
+ MAX98927_R0086_ENV_TRACK_CTRL,
+ 0x01);
+ regmap_write(max98927->regmap,
+ MAX98927_R0087_ENV_TRACK_BOOST_VOUT_READ,
+ 0x10);
- if (max98927->regmap)
- regmap_write(max98927->regmap,
- MAX98927_R001E_PCM_TX_CH_SRC_A,
- ((max98927->i_l_slot <<
- MAX98927_PCM_TX_CH_SRC_A_I_SHIFT)
- | max98927->v_l_slot) & 0xFF);
+ /* voltage, current slot configuration */
+ regmap_write(max98927->regmap,
+ MAX98927_R001E_PCM_TX_CH_SRC_A,
+ (max98927->i_l_slot<<MAX98927_PCM_TX_CH_SRC_A_I_SHIFT|
+ max98927->v_l_slot)&0xFF);
+
+ if (max98927->v_l_slot < 8) {
+ regmap_update_bits(max98927->regmap,
+ MAX98927_R001C_PCM_TX_HIZ_CTRL_A,
+ 1 << max98927->v_l_slot, 0);
+ regmap_update_bits(max98927->regmap,
+ MAX98927_R001A_PCM_TX_EN_A,
+ 1 << max98927->v_l_slot,
+ 1 << max98927->v_l_slot);
+ } else {
+ regmap_update_bits(max98927->regmap,
+ MAX98927_R001D_PCM_TX_HIZ_CTRL_B,
+ 1 << (max98927->v_l_slot - 8), 0);
+ regmap_update_bits(max98927->regmap,
+ MAX98927_R001B_PCM_TX_EN_B,
+ 1 << (max98927->v_l_slot - 8),
+ 1 << (max98927->v_l_slot - 8));
+ }
+
+ if (max98927->i_l_slot < 8) {
+ regmap_update_bits(max98927->regmap,
+ MAX98927_R001C_PCM_TX_HIZ_CTRL_A,
+ 1 << max98927->i_l_slot, 0);
+ regmap_update_bits(max98927->regmap,
+ MAX98927_R001A_PCM_TX_EN_A,
+ 1 << max98927->i_l_slot,
+ 1 << max98927->i_l_slot);
+ } else {
+ regmap_update_bits(max98927->regmap,
+ MAX98927_R001D_PCM_TX_HIZ_CTRL_B,
+ 1 << (max98927->i_l_slot - 8), 0);
+ regmap_update_bits(max98927->regmap,
+ MAX98927_R001B_PCM_TX_EN_B,
+ 1 << (max98927->i_l_slot - 8),
+ 1 << (max98927->i_l_slot - 8));
+ }
/* Set interleave mode */
if (max98927->interleave_mode)
@@ -793,9 +891,10 @@ static const struct regmap_config max98927_regmap = {
.cache_type = REGCACHE_RBTREE,
};
-int probe_common(struct i2c_client *i2c, struct max98927_priv *max98927)
+static void max98927_slot_config(struct i2c_client *i2c,
+ struct max98927_priv *max98927)
{
- int ret = 0, value;
+ int value;
if (!of_property_read_u32(i2c->dev.of_node, "vmon-l-slot", &value))
max98927->v_l_slot = value & 0xF;
@@ -805,13 +904,6 @@ int probe_common(struct i2c_client *i2c, struct max98927_priv *max98927)
max98927->i_l_slot = value & 0xF;
else
max98927->i_l_slot = 1;
-
- ret = snd_soc_register_codec(&i2c->dev, &soc_codec_dev_max98927,
- max98927_dai, ARRAY_SIZE(max98927_dai));
- if (ret < 0)
- dev_err(&i2c->dev,
- "Failed to register codec: %d\n", ret);
- return ret;
}
static int max98927_i2c_probe(struct i2c_client *i2c,
@@ -850,9 +942,14 @@ static int max98927_i2c_probe(struct i2c_client *i2c,
goto err;
}
+ /* voltage/current slot configuration */
+ max98927_slot_config(i2c, max98927);
/* codec registeration */
- ret = probe_common(i2c, max98927);
+ ret = snd_soc_register_codec(&i2c->dev, &soc_codec_dev_max98927,
+ max98927_dai, ARRAY_SIZE(max98927_dai));
+ if (ret < 0)
+ dev_err(&i2c->dev, "Failed to register codec: %d\n", ret);
return ret;
--
2.7.4