From: Jonathan Cameron <jic23@kernel.org>
To: Harald Geyer <harald@ccbib.org>, linux-iio@vger.kernel.org
Cc: Marek Vasut <marex@denx.de>, Liam Girdwood <lgirdwood@gmail.com>,
Mark Brown <broonie@kernel.org>
Subject: Re: [RFC] iio: mxs-lradc: Add support for current source
Date: Sat, 08 Feb 2014 11:59:38 +0000 [thread overview]
Message-ID: <52F61C2A.90101@kernel.org> (raw)
In-Reply-To: <E1W895a-0000yo-Tm@stardust.g4.wien.funkfeuer.at>
On 28/01/14 13:52, 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@ccbib.org>
> ---
> 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.
I'd be tempted to do this via the regulator framework instead of IIO.
At somepoint we could have a bridge to allow an iio interface on a regulator
if anyone wants it (you never know)
Have cc'd Mark and Liam for opinions.
I guess the main advantage in doing it in IIO would be to keep stuff in
one logical group. Still they might just as easily be using an external
regulator to drive thermistors so using the regulator framework would be
more consistent...
>
> 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.
Oops, we want to match hwmon for this probably so milli amps rather than micro.
>
> 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;
> + } else {
> + return -EINVAL;
> + }
> +
> + return IIO_VAL_INT;
> +}
> +
> static int mxs_lradc_read_raw(struct iio_dev *iio_dev,
> const struct iio_chan_spec *chan,
> int *val, int *val2, long m)
> @@ -905,6 +935,8 @@ static int mxs_lradc_read_raw(struct iio_dev *iio_dev,
> case IIO_CHAN_INFO_RAW:
> if (chan->type == IIO_TEMP)
> return mxs_lradc_read_temp(iio_dev, val);
> + else if (chan->type == IIO_CURRENT)
> + return mxs_lradc_read_current(lradc, chan, val);
>
> return mxs_lradc_read_single(iio_dev, chan->channel, val);
>
> @@ -916,6 +948,9 @@ static int mxs_lradc_read_raw(struct iio_dev *iio_dev,
> *val = 0;
> *val2 = 253000;
> return IIO_VAL_INT_PLUS_MICRO;
> + } else if (chan->type == IIO_CURRENT) {
> + *val = 20;
> + return IIO_VAL_INT;
> }
>
> *val = lradc->vref_mv[chan->channel];
> @@ -977,6 +1012,31 @@ static int mxs_lradc_write_raw(struct iio_dev *iio_dev,
> }
>
> break;
> + case IIO_CHAN_INFO_RAW:
> + ret = -EINVAL;
> + if (!chan->output || (val & ~LRADC_CTRL2_TEMP_ISRC_MASK) != 0) {
> + break;
> + } else if (chan->channel == 0) {
> + mxs_lradc_reg_clear(lradc, LRADC_CTRL2_TEMP_ISRC_MASK
> + << LRADC_CTRL2_TEMP_ISRC0_OFFSET,
> + LRADC_CTRL2);
> + mxs_lradc_reg_set(lradc,
> + val << LRADC_CTRL2_TEMP_ISRC0_OFFSET
> + | LRADC_CTRL2_TEMP_SENSOR_IENABLE0,
> + LRADC_CTRL2);
> + ret = 0;
> + } else if (chan->channel == 1) {
> + mxs_lradc_reg_clear(lradc, LRADC_CTRL2_TEMP_ISRC_MASK
> + << LRADC_CTRL2_TEMP_ISRC1_OFFSET,
> + LRADC_CTRL2);
> + mxs_lradc_reg_set(lradc,
> + val << LRADC_CTRL2_TEMP_ISRC1_OFFSET
> + | LRADC_CTRL2_TEMP_SENSOR_IENABLE1,
> + LRADC_CTRL2);
> + ret = 0;
> + }
> +
> + break;
> default:
> ret = -EINVAL;
> break;
> @@ -1417,6 +1477,24 @@ static const struct iio_chan_spec mxs_lradc_chan_spec[] = {
> MXS_ADC_CHAN(13, IIO_VOLTAGE), /* VDDD */
> MXS_ADC_CHAN(14, IIO_VOLTAGE), /* VBG */
> MXS_ADC_CHAN(15, IIO_VOLTAGE), /* VDD5V */
> + {
> + .output = 1,
> + .type = IIO_CURRENT,
> + .indexed = 1,
> + .info_mask_separate = BIT(IIO_CHAN_INFO_RAW) |
> + BIT(IIO_CHAN_INFO_SCALE),
> + .channel = 0,
> + .scan_type = {.sign = 'u', .realbits = 4,},
> + },
> + {
> + .output = 1,
> + .type = IIO_CURRENT,
> + .indexed = 1,
> + .info_mask_separate = BIT(IIO_CHAN_INFO_RAW) |
> + BIT(IIO_CHAN_INFO_SCALE),
> + .channel = 1,
> + .scan_type = {.sign = 'u', .realbits = 4,},
> + },
> };
>
> static int mxs_lradc_hw_init(struct mxs_lradc *lradc)
> @@ -1657,6 +1735,8 @@ static int mxs_lradc_remove(struct platform_device *pdev)
> struct iio_dev *iio = platform_get_drvdata(pdev);
> struct mxs_lradc *lradc = iio_priv(iio);
>
> + mxs_lradc_reg_clear(lradc, LRADC_CTRL2_TEMP_SENSOR_IENABLE0 |
> + LRADC_CTRL2_TEMP_SENSOR_IENABLE1, LRADC_CTRL2);
> iio_device_unregister(iio);
> mxs_lradc_ts_unregister(lradc);
> mxs_lradc_hw_stop(lradc);
>
next prev parent reply other threads:[~2014-02-08 11:59 UTC|newest]
Thread overview: 6+ messages / expand[flat|nested] mbox.gz Atom feed top
2014-01-28 13:52 [RFC] iio: mxs-lradc: Add support for current source Harald Geyer
2014-02-08 11:59 ` Jonathan Cameron [this message]
2014-02-12 16:10 ` Mark Brown
2014-02-12 17:20 ` Jonathan Cameron
2014-02-12 17:28 ` Lars-Peter Clausen
2014-02-08 14:38 ` Marek Vasut
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=52F61C2A.90101@kernel.org \
--to=jic23@kernel.org \
--cc=broonie@kernel.org \
--cc=harald@ccbib.org \
--cc=lgirdwood@gmail.com \
--cc=linux-iio@vger.kernel.org \
--cc=marex@denx.de \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).