saradc: saradc register initialization is incomplete [1/1]

PD#SWPL-4975

Problem:
some basic saradc registers are only initialized at bl2 stage, the ADC
value is abnormal when bl2 disable saradc init.

Solution:
to re-initialize the basic saradc registers in kernel.

Verify:
test pass on w400 and p212

Change-Id: Ie98e8789fd47cc43cafcb49d9862ccccbe1d9b66
Signed-off-by: Xingyu Chen <xingyu.chen@amlogic.com>
This commit is contained in:
Xingyu Chen
2019-02-26 17:45:31 +08:00
committed by Jianxin Pan
parent 6b4f4ac899
commit d737edb3b9

View File

@@ -110,8 +110,8 @@
#define MESON_SAR_ADC_FIFO_RD_SAMPLE_VALUE_MASK GENMASK(11, 0)
#define MESON_SAR_ADC_AUX_SW 0x1c
#define MESON_SAR_ADC_AUX_SW_MUX_SEL_CHAN_MASK(_chan) \
(GENMASK(10, 8) << (((_chan) - 2) * 2))
#define MESON_SAR_ADC_AUX_SW_MUX_SEL_CHAN_SHIFT(_chan) \
(8 + (((_chan) - 2) * 3))
#define MESON_SAR_ADC_AUX_SW_VREF_P_MUX BIT(6)
#define MESON_SAR_ADC_AUX_SW_VREF_N_MUX BIT(5)
#define MESON_SAR_ADC_AUX_SW_MODE_SEL BIT(4)
@@ -174,6 +174,9 @@
*/
#define MESON_SAR_ADC_REG11 0x2c
#define MESON_SAR_ADC_REG11_VREF_SEL BIT(0)
#define MESON_SAR_ADC_REG11_EOC BIT(1)
#define MESON_SAR_ADC_REG11_VREF_EN BIT(5)
#define MESON_SAR_ADC_REG11_CMV_SEL BIT(6)
#define MESON_SAR_ADC_REG11_BANDGAP_EN BIT(13)
#define MESON_SAR_ADC_REG11_CHNL_REGS_EN BIT(30)
#define MESON_SAR_ADC_REG11_FIFO_EN BIT(31)
@@ -305,9 +308,15 @@ enum vref_select {
*
* @reg3_ring_counter_disable: to disable continuous ring counter.
* gxl and later: 1; others(gxtvbb etc): 0
* @reg11_vref_en: g12a and later: 0; others(gxl etc): 1
* @reg11_cmv_sel: g12a and later: 0; others(gxl etc): 1
* @reg11_eoc: g12a and later: 1; others(gxl etc): 0
*/
struct meson_sar_adc_reg_diff {
bool reg3_ring_counter_disable;
bool reg11_vref_en;
bool reg11_cmv_sel;
bool reg11_eoc;
};
/*
@@ -330,6 +339,7 @@ struct meson_sar_adc_data {
bool has_chnl_regs;
unsigned int resolution;
const char *name;
const struct regmap_config *regmap_config;
struct meson_sar_adc_reg_diff regs_diff;
};
@@ -351,13 +361,27 @@ struct meson_sar_adc_priv {
u8 *datum_buf;
};
static const struct regmap_config meson_sar_adc_regmap_config = {
static const struct regmap_config meson_sar_adc_regmap_config_g12a = {
.reg_bits = 8,
.val_bits = 32,
.reg_stride = 4,
.max_register = MESON_SAR_ADC_CHNL67,
};
static const struct regmap_config meson_sar_adc_regmap_config_gxbb = {
.reg_bits = 8,
.val_bits = 32,
.reg_stride = 4,
.max_register = MESON_SAR_ADC_REG13,
};
static const struct regmap_config meson_sar_adc_regmap_config_meson8 = {
.reg_bits = 8,
.val_bits = 32,
.reg_stride = 4,
.max_register = MESON_SAR_ADC_DELTA_10,
};
static unsigned int meson_sar_adc_get_fifo_count(struct iio_dev *indio_dev)
{
struct meson_sar_adc_priv *priv = iio_priv(indio_dev);
@@ -529,7 +553,7 @@ static void meson_sar_adc_enable_channel(struct iio_dev *indio_dev,
MESON_SAR_ADC_CHAN_LIST_MAX_INDEX_MASK, regval);
/* map channel index 0 to the channel which we want to read */
regval = chan->channel << MESON_SAR_ADC_CHAN_LIST_ENTRY_SHIFT(idx),
regval = chan->channel << MESON_SAR_ADC_CHAN_LIST_ENTRY_SHIFT(idx);
regmap_update_bits(priv->regmap, MESON_SAR_ADC_CHAN_LIST,
MESON_SAR_ADC_CHAN_LIST_ENTRY_MASK(idx), regval);
@@ -835,6 +859,7 @@ static int meson_sar_adc_init(struct iio_dev *indio_dev)
{
struct meson_sar_adc_priv *priv = iio_priv(indio_dev);
int regval, ret;
int i;
/*
* make sure we start at CH7 input since the other muxes are only used
@@ -895,6 +920,55 @@ static int meson_sar_adc_init(struct iio_dev *indio_dev)
MESON_SAR_ADC_REG3_CTRL_CONT_RING_COUNTER_EN,
FIELD_PREP(MESON_SAR_ADC_REG3_CTRL_CONT_RING_COUNTER_EN,
priv->data->regs_diff.reg3_ring_counter_disable));
/*
* set up the input channel muxes in MESON_SAR_ADC_CHAN_10_SW
* (0 = SAR_ADC_CH0, 1 = SAR_ADC_CH1)
*/
regval = FIELD_PREP(MESON_SAR_ADC_CHAN_10_SW_CHAN0_MUX_SEL_MASK, 0);
regmap_update_bits(priv->regmap, MESON_SAR_ADC_CHAN_10_SW,
MESON_SAR_ADC_CHAN_10_SW_CHAN0_MUX_SEL_MASK,
regval);
regmap_update_bits(priv->regmap, MESON_SAR_ADC_CHAN_10_SW,
MESON_SAR_ADC_CHAN_10_SW_CHAN0_XP_DRIVE_SW,
MESON_SAR_ADC_CHAN_10_SW_CHAN0_XP_DRIVE_SW);
regmap_update_bits(priv->regmap, MESON_SAR_ADC_CHAN_10_SW,
MESON_SAR_ADC_CHAN_10_SW_CHAN0_YP_DRIVE_SW,
MESON_SAR_ADC_CHAN_10_SW_CHAN0_YP_DRIVE_SW);
regval = FIELD_PREP(MESON_SAR_ADC_CHAN_10_SW_CHAN1_MUX_SEL_MASK, 1);
regmap_update_bits(priv->regmap, MESON_SAR_ADC_CHAN_10_SW,
MESON_SAR_ADC_CHAN_10_SW_CHAN1_MUX_SEL_MASK,
regval);
regmap_update_bits(priv->regmap, MESON_SAR_ADC_CHAN_10_SW,
MESON_SAR_ADC_CHAN_10_SW_CHAN1_XP_DRIVE_SW,
MESON_SAR_ADC_CHAN_10_SW_CHAN1_XP_DRIVE_SW);
regmap_update_bits(priv->regmap, MESON_SAR_ADC_CHAN_10_SW,
MESON_SAR_ADC_CHAN_10_SW_CHAN1_YP_DRIVE_SW,
MESON_SAR_ADC_CHAN_10_SW_CHAN1_YP_DRIVE_SW);
/*
* set up the input channel muxes in MESON_SAR_ADC_AUX_SW
* (2 = SAR_ADC_CH2, 3 = SAR_ADC_CH3, ...) and enable
* MESON_SAR_ADC_AUX_SW_YP_DRIVE_SW and
* MESON_SAR_ADC_AUX_SW_XP_DRIVE_SW like the vendor driver.
*/
regval = 0;
for (i = 2; i <= 7; i++)
regval |= i << MESON_SAR_ADC_AUX_SW_MUX_SEL_CHAN_SHIFT(i);
regval |= MESON_SAR_ADC_AUX_SW_YP_DRIVE_SW;
regval |= MESON_SAR_ADC_AUX_SW_XP_DRIVE_SW;
regmap_write(priv->regmap, MESON_SAR_ADC_AUX_SW, regval);
/* must be set to <1> for g12a and later SoCs */
regmap_update_bits(priv->regmap, MESON_SAR_ADC_REG11,
MESON_SAR_ADC_REG11_EOC,
FIELD_PREP(MESON_SAR_ADC_REG11_EOC,
priv->data->regs_diff.reg11_eoc));
/* select the vref */
regmap_update_bits(priv->regmap, MESON_SAR_ADC_REG11,
MESON_SAR_ADC_REG11_VREF_SEL,
@@ -922,9 +996,20 @@ static int meson_sar_adc_hw_enable(struct iio_dev *indio_dev)
return ret;
}
regmap_update_bits(priv->regmap, MESON_SAR_ADC_REG11,
MESON_SAR_ADC_REG11_VREF_EN,
FIELD_PREP(MESON_SAR_ADC_REG11_VREF_EN,
priv->data->regs_diff.reg11_vref_en));
regmap_update_bits(priv->regmap, MESON_SAR_ADC_REG11,
MESON_SAR_ADC_REG11_CMV_SEL,
FIELD_PREP(MESON_SAR_ADC_REG11_CMV_SEL,
priv->data->regs_diff.reg11_cmv_sel));
regmap_update_bits(priv->regmap, MESON_SAR_ADC_REG11,
MESON_SAR_ADC_REG11_BANDGAP_EN,
MESON_SAR_ADC_REG11_BANDGAP_EN);
regmap_update_bits(priv->regmap, MESON_SAR_ADC_REG3,
MESON_SAR_ADC_REG3_ADC_EN,
MESON_SAR_ADC_REG3_ADC_EN);
@@ -1302,8 +1387,12 @@ struct meson_sar_adc_data meson_sar_adc_g12a_data = {
.vref_sel = VDDA_AS_VREF,
.resolution = SAR_ADC_12BIT,
.name = "meson-g12a-saradc",
.regmap_config = &meson_sar_adc_regmap_config_g12a,
.regs_diff = {
.reg3_ring_counter_disable = BIT_HIGH,
.reg11_vref_en = BIT_LOW,
.reg11_cmv_sel = BIT_LOW,
.reg11_eoc = BIT_HIGH,
},
};
@@ -1313,8 +1402,12 @@ struct meson_sar_adc_data meson_sar_adc_txlx_data = {
.vref_sel = VDDA_AS_VREF,
.resolution = SAR_ADC_12BIT,
.name = "meson-txlx-saradc",
.regmap_config = &meson_sar_adc_regmap_config_gxbb,
.regs_diff = {
.reg3_ring_counter_disable = BIT_HIGH,
.reg11_vref_en = BIT_HIGH,
.reg11_cmv_sel = BIT_HIGH,
.reg11_eoc = BIT_LOW,
},
};
@@ -1324,8 +1417,12 @@ struct meson_sar_adc_data meson_sar_adc_axg_data = {
.vref_sel = VDDA_AS_VREF,
.resolution = SAR_ADC_12BIT,
.name = "meson-axg-saradc",
.regmap_config = &meson_sar_adc_regmap_config_gxbb,
.regs_diff = {
.reg3_ring_counter_disable = BIT_HIGH,
.reg11_vref_en = BIT_HIGH,
.reg11_cmv_sel = BIT_HIGH,
.reg11_eoc = BIT_LOW,
},
};
@@ -1335,8 +1432,12 @@ struct meson_sar_adc_data meson_sar_adc_txl_data = {
.vref_sel = CALIB_VOL_AS_VREF,
.resolution = SAR_ADC_12BIT,
.name = "meson-txl-saradc",
.regmap_config = &meson_sar_adc_regmap_config_gxbb,
.regs_diff = {
.reg3_ring_counter_disable = BIT_HIGH,
.reg11_vref_en = BIT_HIGH,
.reg11_cmv_sel = BIT_HIGH,
.reg11_eoc = BIT_LOW,
},
};
@@ -1346,8 +1447,12 @@ struct meson_sar_adc_data meson_sar_adc_gxl_data = {
.vref_sel = CALIB_VOL_AS_VREF,
.resolution = SAR_ADC_12BIT,
.name = "meson-gxl-saradc",
.regmap_config = &meson_sar_adc_regmap_config_gxbb,
.regs_diff = {
.reg3_ring_counter_disable = BIT_HIGH,
.reg11_vref_en = BIT_HIGH,
.reg11_cmv_sel = BIT_HIGH,
.reg11_eoc = BIT_LOW,
},
};
@@ -1357,8 +1462,12 @@ struct meson_sar_adc_data meson_sar_adc_gxm_data = {
.vref_sel = CALIB_VOL_AS_VREF,
.resolution = SAR_ADC_12BIT,
.name = "meson-gxm-saradc",
.regmap_config = &meson_sar_adc_regmap_config_gxbb,
.regs_diff = {
.reg3_ring_counter_disable = BIT_HIGH,
.reg11_vref_en = BIT_HIGH,
.reg11_cmv_sel = BIT_HIGH,
.reg11_eoc = BIT_LOW,
},
};
@@ -1368,6 +1477,7 @@ struct meson_sar_adc_data meson_sar_adc_m8b_data = {
.vref_sel = CALIB_VOL_AS_VREF,
.resolution = SAR_ADC_10BIT,
.name = "meson-m8b-saradc",
.regmap_config = &meson_sar_adc_regmap_config_meson8,
.regs_diff = {
.reg3_ring_counter_disable = BIT_LOW,
},
@@ -1443,7 +1553,7 @@ static int meson_sar_adc_probe(struct platform_device *pdev)
return -EINVAL;
priv->regmap = devm_regmap_init_mmio(&pdev->dev, base,
&meson_sar_adc_regmap_config);
priv->data->regmap_config);
if (IS_ERR(priv->regmap))
return PTR_ERR(priv->regmap);