On Tuesday, January 28, 2014 at 02:52:30 PM, Harald Geyer wrote: > We pretend the current source to be an independent 4-bit DAC, > which seems to be a valid use of the device. The channel also > allows reading back the value previously written. > > Signed-off-by: Harald Geyer <harald@xxxxxxxxx> > --- > The LRADC can drive two of its ADC channels with a defined current > between 0 and 300uA to allow reading thermistors without external > current source. I'm not sure what the right IIO ABI in this case > should be. The way it is done now has the advantage that no new > ABI is needed and somebody might actually use the device as very > low resolution DAC. OTOH the relationship between output and input > channels is a bit non obvious this way. > > Also note, that I didn't find any documentation about the expected > current unit in iio. I think uA is a reasonable choice, but this > should be confirmed and documented at least. > > Harald > > drivers/staging/iio/adc/mxs-lradc.c | 80 > +++++++++++++++++++++++++++++++++++ 1 files changed, 80 insertions(+), 0 > deletions(-) > > diff --git a/drivers/staging/iio/adc/mxs-lradc.c > b/drivers/staging/iio/adc/mxs-lradc.c index df71669..48b1ed7 100644 > --- a/drivers/staging/iio/adc/mxs-lradc.c > +++ b/drivers/staging/iio/adc/mxs-lradc.c > @@ -303,6 +303,11 @@ struct mxs_lradc { > #define LRADC_CTRL2 0x20 > #define LRADC_CTRL2_DIVIDE_BY_TWO_OFFSET 24 > #define LRADC_CTRL2_TEMPSENSE_PWD (1 << 15) > +#define LRADC_CTRL2_TEMP_SENSOR_IENABLE1 (1 << 9) > +#define LRADC_CTRL2_TEMP_SENSOR_IENABLE0 (1 << 8) > +#define LRADC_CTRL2_TEMP_ISRC1_OFFSET 4 > +#define LRADC_CTRL2_TEMP_ISRC0_OFFSET 0 > +#define LRADC_CTRL2_TEMP_ISRC_MASK (0x0f) > > #define LRADC_STATUS 0x40 > #define LRADC_STATUS_TOUCH_DETECT_RAW (1 << 0) > @@ -891,6 +896,31 @@ static int mxs_lradc_read_temp(struct iio_dev > *iio_dev, int *val) return IIO_VAL_INT; > } > > +static int mxs_lradc_read_current(struct mxs_lradc *lradc, > + const struct iio_chan_spec *chan, int *val) > +{ > + *val = 0; > + if (chan->channel == 0) { > + if ((readl(lradc->base + LRADC_CTRL2) & > + LRADC_CTRL2_TEMP_SENSOR_IENABLE0) == 0) > + return IIO_VAL_INT; > + *val = (readl(lradc->base + LRADC_CTRL2) >> > + LRADC_CTRL2_TEMP_ISRC0_OFFSET) & > + LRADC_CTRL2_TEMP_ISRC_MASK; > + } else if (chan->channel == 1) { > + if ((readl(lradc->base + LRADC_CTRL2) & > + LRADC_CTRL2_TEMP_SENSOR_IENABLE1) == 0) > + return IIO_VAL_INT; > + *val = (readl(lradc->base + LRADC_CTRL2) >> > + LRADC_CTRL2_TEMP_ISRC1_OFFSET) & > + LRADC_CTRL2_TEMP_ISRC_MASK; You can use parametrized macros here, lik LRADC_CTRL2_TEMP_ISRCn_OFFSET(n) , that way you'd trim down the code duplication here nicely. DTTO for the other large chunk of code down below. [...] -- 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