Most LRADC channels have an optional divisor by two which allows a maximum input voltage of VDDIO - 50mV. This patch adds the scaling info flag to these channels (all except 7 -VBATT-, 10 -VDDIO- and 15 -VDD5V-) to allow enabled divide_by_two read operation. Reference: http://www.spinics.net/lists/linux-iio/msg08876.html Signed-off-by: Hector Palacios <hector.palacios@xxxxxxxx> --- drivers/staging/iio/adc/mxs-lradc.c | 52 +++++++++++++++++++++++-------------- 1 file changed, 33 insertions(+), 19 deletions(-) diff --git a/drivers/staging/iio/adc/mxs-lradc.c b/drivers/staging/iio/adc/mxs-lradc.c index 51f781f..4363bb6 100644 --- a/drivers/staging/iio/adc/mxs-lradc.c +++ b/drivers/staging/iio/adc/mxs-lradc.c @@ -197,6 +197,7 @@ struct mxs_lradc { #define LRADC_CTRL1_LRADC_IRQ_OFFSET 0 #define LRADC_CTRL2 0x20 +#define LRADC_CTRL2_DIVIDE_BY_TWO_OFFSET 24 #define LRADC_CTRL2_TEMPSENSE_PWD (1 << 15) #define LRADC_STATUS 0x40 @@ -234,7 +235,7 @@ static int mxs_lradc_read_raw(struct iio_dev *iio_dev, struct mxs_lradc *lradc = iio_priv(iio_dev); int ret; - if (m != IIO_CHAN_INFO_RAW) + if (m != IIO_CHAN_INFO_RAW && m != IIO_CHAN_INFO_SCALE) return -EINVAL; /* Check for invalid channel */ @@ -262,6 +263,11 @@ static int mxs_lradc_read_raw(struct iio_dev *iio_dev, lradc->base + LRADC_CTRL1 + STMP_OFFSET_REG_CLR); writel(0xff, lradc->base + LRADC_CTRL0 + STMP_OFFSET_REG_CLR); + /* Enable DIVIDE_BY_TWO on channel 0 if reading scaled value */ + if (IIO_CHAN_INFO_SCALE == m) + writel(1 << LRADC_CTRL2_DIVIDE_BY_TWO_OFFSET, + lradc->base + LRADC_CTRL2 + STMP_OFFSET_REG_SET); + /* Clean the slot's previous content, then set new one. */ writel(LRADC_CTRL4_LRADCSELECT_MASK(0), lradc->base + LRADC_CTRL4 + STMP_OFFSET_REG_CLR); @@ -286,6 +292,10 @@ static int mxs_lradc_read_raw(struct iio_dev *iio_dev, ret = IIO_VAL_INT; err: + /* Disable DIVIDE_BY_TWO on channel 0 if reading scaled value */ + if (IIO_CHAN_INFO_SCALE == m) + writel(1 << LRADC_CTRL2_DIVIDE_BY_TWO_OFFSET, + lradc->base + LRADC_CTRL2 + STMP_OFFSET_REG_CLR); writel(LRADC_CTRL1_LRADC_IRQ_EN(0), lradc->base + LRADC_CTRL1 + STMP_OFFSET_REG_CLR); @@ -806,11 +816,11 @@ static const struct iio_buffer_setup_ops mxs_lradc_buffer_ops = { * Driver initialization */ -#define MXS_ADC_CHAN(idx, chan_type) { \ +#define MXS_ADC_CHAN(idx, chan_type, info) { \ .type = (chan_type), \ .indexed = 1, \ .scan_index = (idx), \ - .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT, \ + .info_mask = (info), \ .channel = (idx), \ .scan_type = { \ .sign = 'u', \ @@ -819,23 +829,27 @@ static const struct iio_buffer_setup_ops mxs_lradc_buffer_ops = { }, \ } +#define RAW IIO_CHAN_INFO_RAW_SEPARATE_BIT +#define RAW_SCALED (IIO_CHAN_INFO_RAW_SEPARATE_BIT | \ + IIO_CHAN_INFO_SCALE_SEPARATE_BIT) + static const struct iio_chan_spec mxs_lradc_chan_spec[] = { - MXS_ADC_CHAN(0, IIO_VOLTAGE), - MXS_ADC_CHAN(1, IIO_VOLTAGE), - MXS_ADC_CHAN(2, IIO_VOLTAGE), - MXS_ADC_CHAN(3, IIO_VOLTAGE), - MXS_ADC_CHAN(4, IIO_VOLTAGE), - MXS_ADC_CHAN(5, IIO_VOLTAGE), - MXS_ADC_CHAN(6, IIO_VOLTAGE), - MXS_ADC_CHAN(7, IIO_VOLTAGE), /* VBATT */ - MXS_ADC_CHAN(8, IIO_TEMP), /* Temp sense 0 */ - MXS_ADC_CHAN(9, IIO_TEMP), /* Temp sense 1 */ - MXS_ADC_CHAN(10, IIO_VOLTAGE), /* VDDIO */ - MXS_ADC_CHAN(11, IIO_VOLTAGE), /* VTH */ - MXS_ADC_CHAN(12, IIO_VOLTAGE), /* VDDA */ - MXS_ADC_CHAN(13, IIO_VOLTAGE), /* VDDD */ - MXS_ADC_CHAN(14, IIO_VOLTAGE), /* VBG */ - MXS_ADC_CHAN(15, IIO_VOLTAGE), /* VDD5V */ + MXS_ADC_CHAN(0, IIO_VOLTAGE, RAW_SCALED), + MXS_ADC_CHAN(1, IIO_VOLTAGE, RAW_SCALED), + MXS_ADC_CHAN(2, IIO_VOLTAGE, RAW_SCALED), + MXS_ADC_CHAN(3, IIO_VOLTAGE, RAW_SCALED), + MXS_ADC_CHAN(4, IIO_VOLTAGE, RAW_SCALED), + MXS_ADC_CHAN(5, IIO_VOLTAGE, RAW_SCALED), + MXS_ADC_CHAN(6, IIO_VOLTAGE, RAW_SCALED), + MXS_ADC_CHAN(7, IIO_VOLTAGE, RAW), /* VBATT */ + MXS_ADC_CHAN(8, IIO_TEMP, RAW_SCALED), /* Temp sense 0 */ + MXS_ADC_CHAN(9, IIO_TEMP, RAW_SCALED), /* Temp sense 1 */ + MXS_ADC_CHAN(10, IIO_VOLTAGE, RAW), /* VDDIO */ + MXS_ADC_CHAN(11, IIO_VOLTAGE, RAW_SCALED), /* VTH */ + MXS_ADC_CHAN(12, IIO_VOLTAGE, RAW_SCALED), /* VDDA */ + MXS_ADC_CHAN(13, IIO_VOLTAGE, RAW_SCALED), /* VDDD */ + MXS_ADC_CHAN(14, IIO_VOLTAGE, RAW_SCALED), /* VBG */ + MXS_ADC_CHAN(15, IIO_VOLTAGE, RAW), /* VDD5V */ }; static void mxs_lradc_hw_init(struct mxs_lradc *lradc) -- To unsubscribe from this list: send the line "unsubscribe linux-iio" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html