meson_saradc: merge from mainline

PD#SWPL-15312

Change-Id: I77692c66e245135f8f325702626c52c24eb3e180
Signed-off-by: Lei Qian <lei.qian@amlogic.com>
This commit is contained in:
Lei Qian
2019-10-17 14:35:41 +08:00
committed by Luke Go
parent c705f69697
commit 6456487cc0

View File

@@ -214,9 +214,7 @@
.info_mask_separate = BIT(IIO_CHAN_INFO_RAW) | \
BIT(IIO_CHAN_INFO_AVERAGE_RAW) | \
BIT(IIO_CHAN_INFO_PROCESSED), \
.info_mask_shared_by_type = BIT(IIO_CHAN_INFO_SCALE) | \
BIT(IIO_CHAN_INFO_CALIBBIAS) | \
BIT(IIO_CHAN_INFO_CALIBSCALE), \
.info_mask_shared_by_type = BIT(IIO_CHAN_INFO_SCALE), \
.scan_type = { \
.sign = 'u', \
.storagebits = 16, \
@@ -326,6 +324,7 @@ struct meson_sar_adc_reg_diff {
* @obt_temp_chan6: whether to read data of temp sensor by channel 6
* @has_bl30_integration:
* @vref_sel: txlx and later: VDDA; others(txl etc): calibration voltage
* @calib_enable: txlx and later: disable; others(txl etc): enable
* @period_support: periodic sampling support
* @has_chnl_regs: whether support for chnl[X] registers
* @resolution: gxl and later: 12bit; others(gxtvbb etc): 10bit
@@ -336,6 +335,7 @@ struct meson_sar_adc_data {
bool obt_temp_chan6;
bool has_bl30_integration;
bool vref_sel;
bool calib_enable;
bool period_support;
bool has_chnl_regs;
unsigned int resolution;
@@ -455,7 +455,10 @@ static int meson_sar_adc_read_raw_sample(struct iio_dev *indio_dev,
fifo_val &= GENMASK(priv->data->resolution - 1, 0);
/* to fix the sample value by software */
*val = meson_sar_adc_calib_val(indio_dev, fifo_val);
if (priv->data->calib_enable)
*val = meson_sar_adc_calib_val(indio_dev, fifo_val);
else
*val = fifo_val;
return 0;
}
@@ -496,7 +499,10 @@ static int meson_sar_adc_read_raw_sample_from_chnl(struct iio_dev *indio_dev,
fifo_val &= GENMASK(priv->data->resolution - 1, 0);
/* to fix the sample value by software */
*val = meson_sar_adc_calib_val(indio_dev, fifo_val);
if (priv->data->calib_enable)
*val = meson_sar_adc_calib_val(indio_dev, fifo_val);
else
*val = fifo_val;
return 0;
}
@@ -614,6 +620,7 @@ static int meson_sar_adc_lock(struct iio_dev *indio_dev)
mutex_lock(&indio_dev->mlock);
if (priv->data->has_bl30_integration) {
again:
/* wait until BL30 releases it's lock (so we can use
* the SAR ADC)
*/
@@ -631,10 +638,10 @@ static int meson_sar_adc_lock(struct iio_dev *indio_dev)
MESON_SAR_ADC_DELAY_KERNEL_BUSY);
isb();
dsb(sy);
udelay(1);
udelay(5);
regmap_read(priv->regmap, MESON_SAR_ADC_DELAY, &val);
if (val & MESON_SAR_ADC_DELAY_BL30_BUSY)
return -ETIMEDOUT;
goto again;
}
return 0;
@@ -644,10 +651,14 @@ static void meson_sar_adc_unlock(struct iio_dev *indio_dev)
{
struct meson_sar_adc_priv *priv = iio_priv(indio_dev);
if (priv->data->has_bl30_integration)
if (priv->data->has_bl30_integration) {
/* allow BL30 to use the SAR ADC again */
regmap_update_bits(priv->regmap, MESON_SAR_ADC_DELAY,
MESON_SAR_ADC_DELAY_KERNEL_BUSY, 0);
isb();
dsb(sy);
udelay(5);
}
mutex_unlock(&indio_dev->mlock);
}
@@ -762,10 +773,16 @@ static int meson_sar_adc_iio_info_read_raw(struct iio_dev *indio_dev,
return IIO_VAL_FRACTIONAL_LOG2;
case IIO_CHAN_INFO_CALIBBIAS:
if (!priv->data->calib_enable)
return -EINVAL;
*val = priv->calibbias;
return IIO_VAL_INT;
case IIO_CHAN_INFO_CALIBSCALE:
if (!priv->data->calib_enable)
return -EINVAL;
*val = priv->calibscale / MILLION;
*val2 = priv->calibscale % MILLION;
return IIO_VAL_INT_PLUS_MICRO;
@@ -1433,6 +1450,7 @@ struct meson_sar_adc_data meson_sar_adc_txl_data = {
.obt_temp_chan6 = false,
.has_bl30_integration = true,
.vref_sel = CALIB_VOL_AS_VREF,
.calib_enable = true,
.resolution = SAR_ADC_12BIT,
.name = "meson-txl-saradc",
.regmap_config = &meson_sar_adc_regmap_config_gxbb,
@@ -1448,6 +1466,7 @@ struct meson_sar_adc_data meson_sar_adc_gxl_data = {
.obt_temp_chan6 = false,
.has_bl30_integration = true,
.vref_sel = CALIB_VOL_AS_VREF,
.calib_enable = true,
.resolution = SAR_ADC_12BIT,
.name = "meson-gxl-saradc",
.regmap_config = &meson_sar_adc_regmap_config_gxbb,
@@ -1463,6 +1482,7 @@ struct meson_sar_adc_data meson_sar_adc_gxm_data = {
.obt_temp_chan6 = false,
.has_bl30_integration = true,
.vref_sel = CALIB_VOL_AS_VREF,
.calib_enable = true,
.resolution = SAR_ADC_12BIT,
.name = "meson-gxm-saradc",
.regmap_config = &meson_sar_adc_regmap_config_gxbb,
@@ -1478,6 +1498,7 @@ struct meson_sar_adc_data meson_sar_adc_m8b_data = {
.obt_temp_chan6 = true,
.has_bl30_integration = true,
.vref_sel = CALIB_VOL_AS_VREF,
.calib_enable = true,
.resolution = SAR_ADC_10BIT,
.name = "meson-m8b-saradc",
.regmap_config = &meson_sar_adc_regmap_config_meson8,
@@ -1520,8 +1541,10 @@ static int meson_sar_adc_probe(struct platform_device *pdev)
struct resource *res;
void __iomem *base;
const struct of_device_id *match;
struct iio_chan_spec *chan;
int ret;
int irq;
int i;
indio_dev = devm_iio_device_alloc(&pdev->dev, sizeof(*priv));
if (!indio_dev) {
@@ -1593,8 +1616,6 @@ static int meson_sar_adc_probe(struct platform_device *pdev)
return ret;
}
priv->calibscale = MILLION;
if (priv->data->period_support) {
ret = of_property_read_u32(pdev->dev.of_node,
"amlogic,delay-per-tick", &priv->delay_per_tick);
@@ -1633,10 +1654,24 @@ static int meson_sar_adc_probe(struct platform_device *pdev)
if (ret)
goto err;
ret = meson_sar_adc_calib(indio_dev);
if (ret)
dev_warn(&pdev->dev, "calibration failed\n");
if (priv->data->calib_enable) {
priv->calibscale = MILLION;
for (i = 0; i < indio_dev->num_channels; i++) {
chan = (struct iio_chan_spec *)indio_dev->channels + i;
if (chan->channel < 0)
continue;
chan->info_mask_shared_by_all =
BIT(IIO_CHAN_INFO_CALIBBIAS) |
BIT(IIO_CHAN_INFO_CALIBSCALE);
}
ret = meson_sar_adc_calib(indio_dev);
if (ret)
dev_warn(&pdev->dev, "calibration failed\n");
}
platform_set_drvdata(pdev, indio_dev);
ret = iio_device_register(indio_dev);