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