mirror of
https://github.com/hardkernel/linux.git
synced 2026-06-09 04:10:18 +09:00
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:
@@ -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);
|
||||
|
||||
|
||||
Reference in New Issue
Block a user