* [PATCHv4 0/3] iio: mxs-lradc: add support to optional divider_by_two
@ 2013-12-07 0:23 Alexandre Belloni
2013-12-07 0:23 ` [PATCHv4 1/3] iio: mxs-lradc: add scale attribute to channels Alexandre Belloni
` (3 more replies)
0 siblings, 4 replies; 7+ messages in thread
From: Alexandre Belloni @ 2013-12-07 0:23 UTC (permalink / raw)
To: Jonathan Cameron
Cc: lars, Marek Vasut, harald, hector.palacios, linux-iio,
linux-kernel, Alexandre Belloni
Hello,
This is v4 of the patchset that adds support to the optional divider_by_two of
LRADC channels.
Changes since v3:
- removed DT bindings for vref_mv (was the second patch of the series)
- rebased on v3.13.0-rc3
- the first patch of the previous series had been applied previously
- this will apply after https://lkml.org/lkml/2013/12/6/676
This was tested on a custom i.MX28 platform.
Could someone please test on an i.MX23?
Hector Palacios (3):
iio: mxs-lradc: add scale attribute to channels
iio: mxs-lradc: add scale_available file to channels
iio: mxs-lradc: add write_raw function to modify scale
drivers/staging/iio/adc/mxs-lradc.c | 222 +++++++++++++++++++++++++++++++++++-
1 file changed, 219 insertions(+), 3 deletions(-)
--
1.8.3.2
^ permalink raw reply [flat|nested] 7+ messages in thread
* [PATCHv4 1/3] iio: mxs-lradc: add scale attribute to channels
2013-12-07 0:23 [PATCHv4 0/3] iio: mxs-lradc: add support to optional divider_by_two Alexandre Belloni
@ 2013-12-07 0:23 ` Alexandre Belloni
2013-12-07 0:23 ` [PATCHv4 2/3] iio: mxs-lradc: add scale_available file " Alexandre Belloni
` (2 subsequent siblings)
3 siblings, 0 replies; 7+ messages in thread
From: Alexandre Belloni @ 2013-12-07 0:23 UTC (permalink / raw)
To: Jonathan Cameron
Cc: lars, Marek Vasut, harald, hector.palacios, linux-iio,
linux-kernel, Alexandre Belloni
From: Hector Palacios <hector.palacios@digi.com>
Some LRADC channels have fixed pre-dividers and all have an optional
divider by two which allows a maximum input voltage of VDDIO - 50mV.
This patch
- adds the scaling info flag to all channels
- grabs the max reference voltage per channel
(where the fixed pre-dividers apply)
- allows to read the scaling attribute (computed from the Vref)
Signed-off-by: Hector Palacios <hector.palacios@digi.com>.
Signed-off-by: Alexandre Belloni <alexandre.belloni@free-electrons.com>
---
drivers/staging/iio/adc/mxs-lradc.c | 56 +++++++++++++++++++++++++++++++++++--
1 file changed, 54 insertions(+), 2 deletions(-)
diff --git a/drivers/staging/iio/adc/mxs-lradc.c b/drivers/staging/iio/adc/mxs-lradc.c
index 5a4499c3d22a..22fef0a408db 100644
--- a/drivers/staging/iio/adc/mxs-lradc.c
+++ b/drivers/staging/iio/adc/mxs-lradc.c
@@ -111,16 +111,59 @@ static const char * const mx28_lradc_irq_names[] = {
struct mxs_lradc_of_config {
const int irq_count;
const char * const *irq_name;
+ const uint32_t *vref_mv;
+};
+
+#define VREF_MV_BASE 1850
+
+static const uint32_t mx23_vref_mv[LRADC_MAX_TOTAL_CHANS] = {
+ VREF_MV_BASE, /* CH0 */
+ VREF_MV_BASE, /* CH1 */
+ VREF_MV_BASE, /* CH2 */
+ VREF_MV_BASE, /* CH3 */
+ VREF_MV_BASE, /* CH4 */
+ VREF_MV_BASE, /* CH5 */
+ VREF_MV_BASE * 2, /* CH6 VDDIO */
+ VREF_MV_BASE * 4, /* CH7 VBATT */
+ VREF_MV_BASE, /* CH8 Temp sense 0 */
+ VREF_MV_BASE, /* CH9 Temp sense 1 */
+ VREF_MV_BASE, /* CH10 */
+ VREF_MV_BASE, /* CH11 */
+ VREF_MV_BASE, /* CH12 USB_DP */
+ VREF_MV_BASE, /* CH13 USB_DN */
+ VREF_MV_BASE, /* CH14 VBG */
+ VREF_MV_BASE * 4, /* CH15 VDD5V */
+};
+
+static const uint32_t mx28_vref_mv[LRADC_MAX_TOTAL_CHANS] = {
+ VREF_MV_BASE, /* CH0 */
+ VREF_MV_BASE, /* CH1 */
+ VREF_MV_BASE, /* CH2 */
+ VREF_MV_BASE, /* CH3 */
+ VREF_MV_BASE, /* CH4 */
+ VREF_MV_BASE, /* CH5 */
+ VREF_MV_BASE, /* CH6 */
+ VREF_MV_BASE * 4, /* CH7 VBATT */
+ VREF_MV_BASE, /* CH8 Temp sense 0 */
+ VREF_MV_BASE, /* CH9 Temp sense 1 */
+ VREF_MV_BASE * 2, /* CH10 VDDIO */
+ VREF_MV_BASE, /* CH11 VTH */
+ VREF_MV_BASE * 2, /* CH12 VDDA */
+ VREF_MV_BASE, /* CH13 VDDD */
+ VREF_MV_BASE, /* CH14 VBG */
+ VREF_MV_BASE * 4, /* CH15 VDD5V */
};
static const struct mxs_lradc_of_config mxs_lradc_of_config[] = {
[IMX23_LRADC] = {
.irq_count = ARRAY_SIZE(mx23_lradc_irq_names),
.irq_name = mx23_lradc_irq_names,
+ .vref_mv = mx23_vref_mv,
},
[IMX28_LRADC] = {
.irq_count = ARRAY_SIZE(mx28_lradc_irq_names),
.irq_name = mx28_lradc_irq_names,
+ .vref_mv = mx28_vref_mv,
},
};
@@ -155,6 +198,8 @@ struct mxs_lradc {
struct completion completion;
+ const uint32_t *vref_mv;
+
/*
* Touchscreen LRADC channels receives a private slot in the CTRL4
* register, the slot #7. Therefore only 7 slots instead of 8 in the
@@ -836,6 +881,8 @@ static int mxs_lradc_read_raw(struct iio_dev *iio_dev,
const struct iio_chan_spec *chan,
int *val, int *val2, long m)
{
+ struct mxs_lradc *lradc = iio_priv(iio_dev);
+
/* Check for invalid channel */
if (chan->channel > LRADC_MAX_TOTAL_CHANS)
return -EINVAL;
@@ -857,7 +904,9 @@ static int mxs_lradc_read_raw(struct iio_dev *iio_dev,
return IIO_VAL_INT_PLUS_MICRO;
}
- return -EINVAL;
+ *val = lradc->vref_mv[chan->channel];
+ *val2 = chan->scan_type.realbits;
+ return IIO_VAL_FRACTIONAL_LOG2;
case IIO_CHAN_INFO_OFFSET:
if (chan->type == IIO_TEMP) {
@@ -1189,7 +1238,8 @@ static const struct iio_buffer_setup_ops mxs_lradc_buffer_ops = {
.type = (chan_type), \
.indexed = 1, \
.scan_index = (idx), \
- .info_mask_separate = BIT(IIO_CHAN_INFO_RAW), \
+ .info_mask_separate = BIT(IIO_CHAN_INFO_RAW) | \
+ BIT(IIO_CHAN_INFO_SCALE), \
.channel = (idx), \
.scan_type = { \
.sign = 'u', \
@@ -1381,6 +1431,8 @@ static int mxs_lradc_probe(struct platform_device *pdev)
return ret;
}
+ lradc->vref_mv = of_cfg->vref_mv;
+
platform_set_drvdata(pdev, iio);
init_completion(&lradc->completion);
--
1.8.3.2
^ permalink raw reply related [flat|nested] 7+ messages in thread
* [PATCHv4 2/3] iio: mxs-lradc: add scale_available file to channels
2013-12-07 0:23 [PATCHv4 0/3] iio: mxs-lradc: add support to optional divider_by_two Alexandre Belloni
2013-12-07 0:23 ` [PATCHv4 1/3] iio: mxs-lradc: add scale attribute to channels Alexandre Belloni
@ 2013-12-07 0:23 ` Alexandre Belloni
2013-12-08 13:33 ` Jonathan Cameron
2013-12-07 0:24 ` [PATCHv4 3/3] iio: mxs-lradc: add write_raw function to modify scale Alexandre Belloni
2013-12-09 0:18 ` [PATCHv4 0/3] iio: mxs-lradc: add support to optional divider_by_two Marek Vasut
3 siblings, 1 reply; 7+ messages in thread
From: Alexandre Belloni @ 2013-12-07 0:23 UTC (permalink / raw)
To: Jonathan Cameron
Cc: lars, Marek Vasut, harald, hector.palacios, linux-iio,
linux-kernel, Alexandre Belloni
From: Hector Palacios <hector.palacios@digi.com>
Adds in_voltageX_scale_available file for every channel to read
the different available scales.
There are two scales per channel:
[0] = divider_by_two disabled (default)
[1] = divider_by_two enabled
The scale is a struct made of integer and nano parts to build
a long decimal number.
Signed-off-by: Hector Palacios <hector.palacios@digi.com>
Signed-off-by: Alexandre Belloni <alexandre.belloni@free-electrons.com>
---
drivers/staging/iio/adc/mxs-lradc.c | 112 +++++++++++++++++++++++++++++++++++-
1 file changed, 111 insertions(+), 1 deletion(-)
diff --git a/drivers/staging/iio/adc/mxs-lradc.c b/drivers/staging/iio/adc/mxs-lradc.c
index 22fef0a408db..eca766dce644 100644
--- a/drivers/staging/iio/adc/mxs-lradc.c
+++ b/drivers/staging/iio/adc/mxs-lradc.c
@@ -38,6 +38,7 @@
#include <linux/clk.h>
#include <linux/iio/iio.h>
+#include <linux/iio/sysfs.h>
#include <linux/iio/buffer.h>
#include <linux/iio/trigger.h>
#include <linux/iio/trigger_consumer.h>
@@ -184,6 +185,16 @@ enum lradc_ts_plate {
LRADC_SAMPLE_VALID,
};
+enum mxs_lradc_divbytwo {
+ MXS_LRADC_DIV_DISABLED = 0,
+ MXS_LRADC_DIV_ENABLED,
+};
+
+struct mxs_lradc_scale {
+ unsigned int integer;
+ unsigned int nano;
+};
+
struct mxs_lradc {
struct device *dev;
void __iomem *base;
@@ -199,6 +210,8 @@ struct mxs_lradc {
struct completion completion;
const uint32_t *vref_mv;
+ struct mxs_lradc_scale scale_avail[LRADC_MAX_TOTAL_CHANS][2];
+ unsigned int is_divided[LRADC_MAX_TOTAL_CHANS];
/*
* Touchscreen LRADC channels receives a private slot in the CTRL4
@@ -929,9 +942,84 @@ static int mxs_lradc_read_raw(struct iio_dev *iio_dev,
return -EINVAL;
}
+static ssize_t mxs_lradc_show_scale_available_ch(struct device *dev,
+ struct device_attribute *attr,
+ char *buf,
+ int ch)
+{
+ struct iio_dev *iio = dev_to_iio_dev(dev);
+ struct mxs_lradc *lradc = iio_priv(iio);
+ int i, len = 0;
+
+ for (i = 0; i < ARRAY_SIZE(lradc->scale_avail[ch]); i++)
+ len += sprintf(buf + len, "%d.%09u ",
+ lradc->scale_avail[ch][i].integer,
+ lradc->scale_avail[ch][i].nano);
+
+ len += sprintf(buf + len, "\n");
+
+ return len;
+}
+
+static ssize_t mxs_lradc_show_scale_available(struct device *dev,
+ struct device_attribute *attr,
+ char *buf)
+{
+ struct iio_dev_attr *iio_attr = to_iio_dev_attr(attr);
+
+ return mxs_lradc_show_scale_available_ch(dev, attr, buf,
+ iio_attr->address);
+}
+
+#define SHOW_SCALE_AVAILABLE_ATTR(ch) \
+static IIO_DEVICE_ATTR(in_voltage##ch##_scale_available, S_IRUGO, \
+ mxs_lradc_show_scale_available, NULL, ch)
+
+SHOW_SCALE_AVAILABLE_ATTR(0);
+SHOW_SCALE_AVAILABLE_ATTR(1);
+SHOW_SCALE_AVAILABLE_ATTR(2);
+SHOW_SCALE_AVAILABLE_ATTR(3);
+SHOW_SCALE_AVAILABLE_ATTR(4);
+SHOW_SCALE_AVAILABLE_ATTR(5);
+SHOW_SCALE_AVAILABLE_ATTR(6);
+SHOW_SCALE_AVAILABLE_ATTR(7);
+SHOW_SCALE_AVAILABLE_ATTR(8);
+SHOW_SCALE_AVAILABLE_ATTR(9);
+SHOW_SCALE_AVAILABLE_ATTR(10);
+SHOW_SCALE_AVAILABLE_ATTR(11);
+SHOW_SCALE_AVAILABLE_ATTR(12);
+SHOW_SCALE_AVAILABLE_ATTR(13);
+SHOW_SCALE_AVAILABLE_ATTR(14);
+SHOW_SCALE_AVAILABLE_ATTR(15);
+
+static struct attribute *mxs_lradc_attributes[] = {
+ &iio_dev_attr_in_voltage0_scale_available.dev_attr.attr,
+ &iio_dev_attr_in_voltage1_scale_available.dev_attr.attr,
+ &iio_dev_attr_in_voltage2_scale_available.dev_attr.attr,
+ &iio_dev_attr_in_voltage3_scale_available.dev_attr.attr,
+ &iio_dev_attr_in_voltage4_scale_available.dev_attr.attr,
+ &iio_dev_attr_in_voltage5_scale_available.dev_attr.attr,
+ &iio_dev_attr_in_voltage6_scale_available.dev_attr.attr,
+ &iio_dev_attr_in_voltage7_scale_available.dev_attr.attr,
+ &iio_dev_attr_in_voltage8_scale_available.dev_attr.attr,
+ &iio_dev_attr_in_voltage9_scale_available.dev_attr.attr,
+ &iio_dev_attr_in_voltage10_scale_available.dev_attr.attr,
+ &iio_dev_attr_in_voltage11_scale_available.dev_attr.attr,
+ &iio_dev_attr_in_voltage12_scale_available.dev_attr.attr,
+ &iio_dev_attr_in_voltage13_scale_available.dev_attr.attr,
+ &iio_dev_attr_in_voltage14_scale_available.dev_attr.attr,
+ &iio_dev_attr_in_voltage15_scale_available.dev_attr.attr,
+ NULL
+};
+
+static const struct attribute_group mxs_lradc_attribute_group = {
+ .attrs = mxs_lradc_attributes,
+};
+
static const struct iio_info mxs_lradc_iio_info = {
.driver_module = THIS_MODULE,
.read_raw = mxs_lradc_read_raw,
+ .attrs = &mxs_lradc_attribute_group,
};
static int mxs_lradc_ts_open(struct input_dev *dev)
@@ -1241,6 +1329,7 @@ static const struct iio_buffer_setup_ops mxs_lradc_buffer_ops = {
.info_mask_separate = BIT(IIO_CHAN_INFO_RAW) | \
BIT(IIO_CHAN_INFO_SCALE), \
.channel = (idx), \
+ .address = (idx), \
.scan_type = { \
.sign = 'u', \
.realbits = LRADC_RESOLUTION, \
@@ -1386,7 +1475,8 @@ static int mxs_lradc_probe(struct platform_device *pdev)
struct iio_dev *iio;
struct resource *iores;
int ret = 0, touch_ret;
- int i;
+ int i, s;
+ unsigned int scale_uv;
/* Allocate the IIO device. */
iio = devm_iio_device_alloc(dev, sizeof(*lradc));
@@ -1456,6 +1546,26 @@ static int mxs_lradc_probe(struct platform_device *pdev)
if (ret)
goto err_trig;
+ /* Populate available ADC input ranges */
+ for (i = 0; i < LRADC_MAX_TOTAL_CHANS; i++) {
+ for (s = 0; s < ARRAY_SIZE(lradc->scale_avail[i]); s++) {
+ /*
+ * [s=0] = optional divider by two disabled (default)
+ * [s=1] = optional divider by two enabled
+ *
+ * The scale is calculated by doing:
+ * Vref >> (realbits - s)
+ * which multiplies by two on the second component
+ * of the array.
+ */
+ scale_uv = ((u64)lradc->vref_mv[i] * 100000000) >>
+ (iio->channels[i].scan_type.realbits - s);
+ lradc->scale_avail[i][s].nano =
+ do_div(scale_uv, 100000000) * 10;
+ lradc->scale_avail[i][s].integer = scale_uv;
+ }
+ }
+
/* Configure the hardware. */
ret = mxs_lradc_hw_init(lradc);
if (ret)
--
1.8.3.2
^ permalink raw reply related [flat|nested] 7+ messages in thread
* [PATCHv4 3/3] iio: mxs-lradc: add write_raw function to modify scale
2013-12-07 0:23 [PATCHv4 0/3] iio: mxs-lradc: add support to optional divider_by_two Alexandre Belloni
2013-12-07 0:23 ` [PATCHv4 1/3] iio: mxs-lradc: add scale attribute to channels Alexandre Belloni
2013-12-07 0:23 ` [PATCHv4 2/3] iio: mxs-lradc: add scale_available file " Alexandre Belloni
@ 2013-12-07 0:24 ` Alexandre Belloni
2013-12-08 13:35 ` Jonathan Cameron
2013-12-09 0:18 ` [PATCHv4 0/3] iio: mxs-lradc: add support to optional divider_by_two Marek Vasut
3 siblings, 1 reply; 7+ messages in thread
From: Alexandre Belloni @ 2013-12-07 0:24 UTC (permalink / raw)
To: Jonathan Cameron
Cc: lars, Marek Vasut, harald, hector.palacios, linux-iio,
linux-kernel, Alexandre Belloni
From: Hector Palacios <hector.palacios@digi.com>
Added write_raw function to manipulate the optional divider_by_two
through the scaling attribute out of the available scales.
Signed-off-by: Hector Palacios <hector.palacios@digi.com>
Signed-off-by: Alexandre Belloni <alexandre.belloni@free-electrons.com>
---
drivers/staging/iio/adc/mxs-lradc.c | 56 ++++++++++++++++++++++++++++++++++++-
1 file changed, 55 insertions(+), 1 deletion(-)
diff --git a/drivers/staging/iio/adc/mxs-lradc.c b/drivers/staging/iio/adc/mxs-lradc.c
index eca766dce644..a58c6aaa94d3 100644
--- a/drivers/staging/iio/adc/mxs-lradc.c
+++ b/drivers/staging/iio/adc/mxs-lradc.c
@@ -301,6 +301,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
@@ -918,7 +919,8 @@ static int mxs_lradc_read_raw(struct iio_dev *iio_dev,
}
*val = lradc->vref_mv[chan->channel];
- *val2 = chan->scan_type.realbits;
+ *val2 = chan->scan_type.realbits -
+ lradc->is_divided[chan->channel];
return IIO_VAL_FRACTIONAL_LOG2;
case IIO_CHAN_INFO_OFFSET:
@@ -942,6 +944,56 @@ static int mxs_lradc_read_raw(struct iio_dev *iio_dev,
return -EINVAL;
}
+static int mxs_lradc_write_raw(struct iio_dev *iio_dev,
+ const struct iio_chan_spec *chan,
+ int val, int val2, long m)
+{
+ struct mxs_lradc *lradc = iio_priv(iio_dev);
+ struct mxs_lradc_scale *scale_avail =
+ lradc->scale_avail[chan->channel];
+ int ret;
+
+ ret = mutex_trylock(&lradc->lock);
+ if (!ret)
+ return -EBUSY;
+
+ switch (m) {
+ case IIO_CHAN_INFO_SCALE:
+ ret = -EINVAL;
+ if (val == scale_avail[MXS_LRADC_DIV_DISABLED].integer &&
+ val2 == scale_avail[MXS_LRADC_DIV_DISABLED].nano) {
+ /* divider by two disabled */
+ writel(1 << LRADC_CTRL2_DIVIDE_BY_TWO_OFFSET,
+ lradc->base + LRADC_CTRL2 + STMP_OFFSET_REG_CLR);
+ lradc->is_divided[chan->channel] = 0;
+ ret = 0;
+ } else if (val == scale_avail[MXS_LRADC_DIV_ENABLED].integer &&
+ val2 == scale_avail[MXS_LRADC_DIV_ENABLED].nano) {
+ /* divider by two enabled */
+ writel(1 << LRADC_CTRL2_DIVIDE_BY_TWO_OFFSET,
+ lradc->base + LRADC_CTRL2 + STMP_OFFSET_REG_SET);
+ lradc->is_divided[chan->channel] = 1;
+ ret = 0;
+ }
+
+ break;
+ default:
+ ret = -EINVAL;
+ break;
+ }
+
+ mutex_unlock(&lradc->lock);
+
+ return ret;
+}
+
+static int mxs_lradc_write_raw_get_fmt(struct iio_dev *iio_dev,
+ const struct iio_chan_spec *chan,
+ long m)
+{
+ return IIO_VAL_INT_PLUS_NANO;
+}
+
static ssize_t mxs_lradc_show_scale_available_ch(struct device *dev,
struct device_attribute *attr,
char *buf,
@@ -1019,6 +1071,8 @@ static const struct attribute_group mxs_lradc_attribute_group = {
static const struct iio_info mxs_lradc_iio_info = {
.driver_module = THIS_MODULE,
.read_raw = mxs_lradc_read_raw,
+ .write_raw = mxs_lradc_write_raw,
+ .write_raw_get_fmt = mxs_lradc_write_raw_get_fmt,
.attrs = &mxs_lradc_attribute_group,
};
--
1.8.3.2
^ permalink raw reply related [flat|nested] 7+ messages in thread
* Re: [PATCHv4 2/3] iio: mxs-lradc: add scale_available file to channels
2013-12-07 0:23 ` [PATCHv4 2/3] iio: mxs-lradc: add scale_available file " Alexandre Belloni
@ 2013-12-08 13:33 ` Jonathan Cameron
0 siblings, 0 replies; 7+ messages in thread
From: Jonathan Cameron @ 2013-12-08 13:33 UTC (permalink / raw)
To: Alexandre Belloni
Cc: lars, Marek Vasut, harald, hector.palacios, linux-iio,
linux-kernel
On 12/07/13 00:23, Alexandre Belloni wrote:
> From: Hector Palacios <hector.palacios@digi.com>
>
> Adds in_voltageX_scale_available file for every channel to read
> the different available scales.
> There are two scales per channel:
> [0] = divider_by_two disabled (default)
> [1] = divider_by_two enabled
> The scale is a struct made of integer and nano parts to build
> a long decimal number.
>
> Signed-off-by: Hector Palacios <hector.palacios@digi.com>
> Signed-off-by: Alexandre Belloni <alexandre.belloni@free-electrons.com>
Hi Alexandre,
You introduce a few things in here that are not used until the next patch.
Please do a quick respin moving them over...
Otherwise, this looks good to me. Whilst I wish I'd finished tidying
up my series reworking the _available attributes so that I could tell
you to use that, it is not ready and it would not be fair to hold your
series up on it!
Incidentally, thanks for breaking this up into the 3 patches. It makes
it a pleasure to review by keeping each one nice and focussed!
As this only adds new functionality, we won't introduced any regressions into the
imx23 so I'm not overly fussed about getting a tested by on that.
I'll be more than happy to add one though if someone does have time!
Jonathan
> ---
> drivers/staging/iio/adc/mxs-lradc.c | 112 +++++++++++++++++++++++++++++++++++-
> 1 file changed, 111 insertions(+), 1 deletion(-)
>
> diff --git a/drivers/staging/iio/adc/mxs-lradc.c b/drivers/staging/iio/adc/mxs-lradc.c
> index 22fef0a408db..eca766dce644 100644
> --- a/drivers/staging/iio/adc/mxs-lradc.c
> +++ b/drivers/staging/iio/adc/mxs-lradc.c
> @@ -38,6 +38,7 @@
> #include <linux/clk.h>
>
> #include <linux/iio/iio.h>
> +#include <linux/iio/sysfs.h>
> #include <linux/iio/buffer.h>
> #include <linux/iio/trigger.h>
> #include <linux/iio/trigger_consumer.h>
> @@ -184,6 +185,16 @@ enum lradc_ts_plate {
> LRADC_SAMPLE_VALID,
> };
>
> +enum mxs_lradc_divbytwo {
> + MXS_LRADC_DIV_DISABLED = 0,
> + MXS_LRADC_DIV_ENABLED,
> +};
This enum isn't used until the next patch, so should not be here.
Whilst not used, it is sort of used in spirit as you loop over
the two elements of the array so if you prefer, leave this one here.
> +
> +struct mxs_lradc_scale {
> + unsigned int integer;
> + unsigned int nano;
> +};
> +
> struct mxs_lradc {
> struct device *dev;
> void __iomem *base;
> @@ -199,6 +210,8 @@ struct mxs_lradc {
> struct completion completion;
>
> const uint32_t *vref_mv;
> + struct mxs_lradc_scale scale_avail[LRADC_MAX_TOTAL_CHANS][2];
> + unsigned int is_divided[LRADC_MAX_TOTAL_CHANS];
It strikes me that a array of integers to represent a set of boolean
values is overkill! It would add a little more complexity to the
get and set, but I would use a bitmap.
(and this highlights why you should be careful about when stuff is
introduced given I had to read the next patch to review this one and I
am lazy!)
>
> /*
> * Touchscreen LRADC channels receives a private slot in the CTRL4
> @@ -929,9 +942,84 @@ static int mxs_lradc_read_raw(struct iio_dev *iio_dev,
> return -EINVAL;
> }
>
> +static ssize_t mxs_lradc_show_scale_available_ch(struct device *dev,
> + struct device_attribute *attr,
> + char *buf,
> + int ch)
> +{
> + struct iio_dev *iio = dev_to_iio_dev(dev);
> + struct mxs_lradc *lradc = iio_priv(iio);
> + int i, len = 0;
> +
> + for (i = 0; i < ARRAY_SIZE(lradc->scale_avail[ch]); i++)
> + len += sprintf(buf + len, "%d.%09u ",
> + lradc->scale_avail[ch][i].integer,
> + lradc->scale_avail[ch][i].nano);
> +
> + len += sprintf(buf + len, "\n");
> +
> + return len;
> +}
> +
> +static ssize_t mxs_lradc_show_scale_available(struct device *dev,
> + struct device_attribute *attr,
> + char *buf)
> +{
> + struct iio_dev_attr *iio_attr = to_iio_dev_attr(attr);
> +
> + return mxs_lradc_show_scale_available_ch(dev, attr, buf,
> + iio_attr->address);
> +}
> +
> +#define SHOW_SCALE_AVAILABLE_ATTR(ch) \
> +static IIO_DEVICE_ATTR(in_voltage##ch##_scale_available, S_IRUGO, \
> + mxs_lradc_show_scale_available, NULL, ch)
> +
> +SHOW_SCALE_AVAILABLE_ATTR(0);
> +SHOW_SCALE_AVAILABLE_ATTR(1);
> +SHOW_SCALE_AVAILABLE_ATTR(2);
> +SHOW_SCALE_AVAILABLE_ATTR(3);
> +SHOW_SCALE_AVAILABLE_ATTR(4);
> +SHOW_SCALE_AVAILABLE_ATTR(5);
> +SHOW_SCALE_AVAILABLE_ATTR(6);
> +SHOW_SCALE_AVAILABLE_ATTR(7);
> +SHOW_SCALE_AVAILABLE_ATTR(8);
> +SHOW_SCALE_AVAILABLE_ATTR(9);
> +SHOW_SCALE_AVAILABLE_ATTR(10);
> +SHOW_SCALE_AVAILABLE_ATTR(11);
> +SHOW_SCALE_AVAILABLE_ATTR(12);
> +SHOW_SCALE_AVAILABLE_ATTR(13);
> +SHOW_SCALE_AVAILABLE_ATTR(14);
> +SHOW_SCALE_AVAILABLE_ATTR(15);
> +
> +static struct attribute *mxs_lradc_attributes[] = {
> + &iio_dev_attr_in_voltage0_scale_available.dev_attr.attr,
> + &iio_dev_attr_in_voltage1_scale_available.dev_attr.attr,
> + &iio_dev_attr_in_voltage2_scale_available.dev_attr.attr,
> + &iio_dev_attr_in_voltage3_scale_available.dev_attr.attr,
> + &iio_dev_attr_in_voltage4_scale_available.dev_attr.attr,
> + &iio_dev_attr_in_voltage5_scale_available.dev_attr.attr,
> + &iio_dev_attr_in_voltage6_scale_available.dev_attr.attr,
> + &iio_dev_attr_in_voltage7_scale_available.dev_attr.attr,
> + &iio_dev_attr_in_voltage8_scale_available.dev_attr.attr,
> + &iio_dev_attr_in_voltage9_scale_available.dev_attr.attr,
> + &iio_dev_attr_in_voltage10_scale_available.dev_attr.attr,
> + &iio_dev_attr_in_voltage11_scale_available.dev_attr.attr,
> + &iio_dev_attr_in_voltage12_scale_available.dev_attr.attr,
> + &iio_dev_attr_in_voltage13_scale_available.dev_attr.attr,
> + &iio_dev_attr_in_voltage14_scale_available.dev_attr.attr,
> + &iio_dev_attr_in_voltage15_scale_available.dev_attr.attr,
> + NULL
> +};
> +
> +static const struct attribute_group mxs_lradc_attribute_group = {
> + .attrs = mxs_lradc_attributes,
> +};
> +
> static const struct iio_info mxs_lradc_iio_info = {
> .driver_module = THIS_MODULE,
> .read_raw = mxs_lradc_read_raw,
> + .attrs = &mxs_lradc_attribute_group,
> };
>
> static int mxs_lradc_ts_open(struct input_dev *dev)
> @@ -1241,6 +1329,7 @@ static const struct iio_buffer_setup_ops mxs_lradc_buffer_ops = {
> .info_mask_separate = BIT(IIO_CHAN_INFO_RAW) | \
> BIT(IIO_CHAN_INFO_SCALE), \
> .channel = (idx), \
> + .address = (idx), \
> .scan_type = { \
> .sign = 'u', \
> .realbits = LRADC_RESOLUTION, \
> @@ -1386,7 +1475,8 @@ static int mxs_lradc_probe(struct platform_device *pdev)
> struct iio_dev *iio;
> struct resource *iores;
> int ret = 0, touch_ret;
> - int i;
> + int i, s;
> + unsigned int scale_uv;
>
> /* Allocate the IIO device. */
> iio = devm_iio_device_alloc(dev, sizeof(*lradc));
> @@ -1456,6 +1546,26 @@ static int mxs_lradc_probe(struct platform_device *pdev)
> if (ret)
> goto err_trig;
>
> + /* Populate available ADC input ranges */
> + for (i = 0; i < LRADC_MAX_TOTAL_CHANS; i++) {
> + for (s = 0; s < ARRAY_SIZE(lradc->scale_avail[i]); s++) {
> + /*
> + * [s=0] = optional divider by two disabled (default)
> + * [s=1] = optional divider by two enabled
> + *
> + * The scale is calculated by doing:
> + * Vref >> (realbits - s)
> + * which multiplies by two on the second component
> + * of the array.
> + */
> + scale_uv = ((u64)lradc->vref_mv[i] * 100000000) >>
> + (iio->channels[i].scan_type.realbits - s);
> + lradc->scale_avail[i][s].nano =
> + do_div(scale_uv, 100000000) * 10;
> + lradc->scale_avail[i][s].integer = scale_uv;
> + }
> + }
> +
> /* Configure the hardware. */
> ret = mxs_lradc_hw_init(lradc);
> if (ret)
>
^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: [PATCHv4 3/3] iio: mxs-lradc: add write_raw function to modify scale
2013-12-07 0:24 ` [PATCHv4 3/3] iio: mxs-lradc: add write_raw function to modify scale Alexandre Belloni
@ 2013-12-08 13:35 ` Jonathan Cameron
0 siblings, 0 replies; 7+ messages in thread
From: Jonathan Cameron @ 2013-12-08 13:35 UTC (permalink / raw)
To: Alexandre Belloni
Cc: lars, Marek Vasut, harald, hector.palacios, linux-iio,
linux-kernel
On 12/07/13 00:24, Alexandre Belloni wrote:
> From: Hector Palacios <hector.palacios@digi.com>
>
> Added write_raw function to manipulate the optional divider_by_two
> through the scaling attribute out of the available scales.
>
> Signed-off-by: Hector Palacios <hector.palacios@digi.com>
> Signed-off-by: Alexandre Belloni <alexandre.belloni@free-electrons.com>
Looks good to me - make that little tiny tweak I mentioned in the previous
patch and I'll be happy to take these.
Thanks,
Jonathan
> ---
> drivers/staging/iio/adc/mxs-lradc.c | 56 ++++++++++++++++++++++++++++++++++++-
> 1 file changed, 55 insertions(+), 1 deletion(-)
>
> diff --git a/drivers/staging/iio/adc/mxs-lradc.c b/drivers/staging/iio/adc/mxs-lradc.c
> index eca766dce644..a58c6aaa94d3 100644
> --- a/drivers/staging/iio/adc/mxs-lradc.c
> +++ b/drivers/staging/iio/adc/mxs-lradc.c
> @@ -301,6 +301,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
> @@ -918,7 +919,8 @@ static int mxs_lradc_read_raw(struct iio_dev *iio_dev,
> }
>
> *val = lradc->vref_mv[chan->channel];
> - *val2 = chan->scan_type.realbits;
> + *val2 = chan->scan_type.realbits -
> + lradc->is_divided[chan->channel];
> return IIO_VAL_FRACTIONAL_LOG2;
>
> case IIO_CHAN_INFO_OFFSET:
> @@ -942,6 +944,56 @@ static int mxs_lradc_read_raw(struct iio_dev *iio_dev,
> return -EINVAL;
> }
>
> +static int mxs_lradc_write_raw(struct iio_dev *iio_dev,
> + const struct iio_chan_spec *chan,
> + int val, int val2, long m)
> +{
> + struct mxs_lradc *lradc = iio_priv(iio_dev);
> + struct mxs_lradc_scale *scale_avail =
> + lradc->scale_avail[chan->channel];
> + int ret;
> +
> + ret = mutex_trylock(&lradc->lock);
> + if (!ret)
> + return -EBUSY;
> +
> + switch (m) {
> + case IIO_CHAN_INFO_SCALE:
> + ret = -EINVAL;
> + if (val == scale_avail[MXS_LRADC_DIV_DISABLED].integer &&
> + val2 == scale_avail[MXS_LRADC_DIV_DISABLED].nano) {
> + /* divider by two disabled */
> + writel(1 << LRADC_CTRL2_DIVIDE_BY_TWO_OFFSET,
> + lradc->base + LRADC_CTRL2 + STMP_OFFSET_REG_CLR);
> + lradc->is_divided[chan->channel] = 0;
> + ret = 0;
> + } else if (val == scale_avail[MXS_LRADC_DIV_ENABLED].integer &&
> + val2 == scale_avail[MXS_LRADC_DIV_ENABLED].nano) {
> + /* divider by two enabled */
> + writel(1 << LRADC_CTRL2_DIVIDE_BY_TWO_OFFSET,
> + lradc->base + LRADC_CTRL2 + STMP_OFFSET_REG_SET);
> + lradc->is_divided[chan->channel] = 1;
> + ret = 0;
> + }
> +
> + break;
> + default:
> + ret = -EINVAL;
> + break;
> + }
> +
> + mutex_unlock(&lradc->lock);
> +
> + return ret;
> +}
> +
> +static int mxs_lradc_write_raw_get_fmt(struct iio_dev *iio_dev,
> + const struct iio_chan_spec *chan,
> + long m)
> +{
> + return IIO_VAL_INT_PLUS_NANO;
> +}
> +
> static ssize_t mxs_lradc_show_scale_available_ch(struct device *dev,
> struct device_attribute *attr,
> char *buf,
> @@ -1019,6 +1071,8 @@ static const struct attribute_group mxs_lradc_attribute_group = {
> static const struct iio_info mxs_lradc_iio_info = {
> .driver_module = THIS_MODULE,
> .read_raw = mxs_lradc_read_raw,
> + .write_raw = mxs_lradc_write_raw,
> + .write_raw_get_fmt = mxs_lradc_write_raw_get_fmt,
> .attrs = &mxs_lradc_attribute_group,
> };
>
>
^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: [PATCHv4 0/3] iio: mxs-lradc: add support to optional divider_by_two
2013-12-07 0:23 [PATCHv4 0/3] iio: mxs-lradc: add support to optional divider_by_two Alexandre Belloni
` (2 preceding siblings ...)
2013-12-07 0:24 ` [PATCHv4 3/3] iio: mxs-lradc: add write_raw function to modify scale Alexandre Belloni
@ 2013-12-09 0:18 ` Marek Vasut
3 siblings, 0 replies; 7+ messages in thread
From: Marek Vasut @ 2013-12-09 0:18 UTC (permalink / raw)
To: Alexandre Belloni
Cc: Jonathan Cameron, lars, harald, hector.palacios, linux-iio,
linux-kernel
On Saturday, December 07, 2013 at 01:23:57 AM, Alexandre Belloni wrote:
> Hello,
>
> This is v4 of the patchset that adds support to the optional divider_by_two
> of LRADC channels.
>
> Changes since v3:
> - removed DT bindings for vref_mv (was the second patch of the series)
> - rebased on v3.13.0-rc3
> - the first patch of the previous series had been applied previously
> - this will apply after https://lkml.org/lkml/2013/12/6/676
>
> This was tested on a custom i.MX28 platform.
> Could someone please test on an i.MX23?
>
> Hector Palacios (3):
> iio: mxs-lradc: add scale attribute to channels
> iio: mxs-lradc: add scale_available file to channels
> iio: mxs-lradc: add write_raw function to modify scale
>
> drivers/staging/iio/adc/mxs-lradc.c | 222
> +++++++++++++++++++++++++++++++++++- 1 file changed, 219 insertions(+), 3
> deletions(-)
Looks OK to me for all but the tweaks Jonathan requested, thanks!
Whole series otherwise:
Acked-by: Marek Vasut <marex@denx.de>
Best regards,
Marek Vasut
^ permalink raw reply [flat|nested] 7+ messages in thread
end of thread, other threads:[~2013-12-09 0:18 UTC | newest]
Thread overview: 7+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2013-12-07 0:23 [PATCHv4 0/3] iio: mxs-lradc: add support to optional divider_by_two Alexandre Belloni
2013-12-07 0:23 ` [PATCHv4 1/3] iio: mxs-lradc: add scale attribute to channels Alexandre Belloni
2013-12-07 0:23 ` [PATCHv4 2/3] iio: mxs-lradc: add scale_available file " Alexandre Belloni
2013-12-08 13:33 ` Jonathan Cameron
2013-12-07 0:24 ` [PATCHv4 3/3] iio: mxs-lradc: add write_raw function to modify scale Alexandre Belloni
2013-12-08 13:35 ` Jonathan Cameron
2013-12-09 0:18 ` [PATCHv4 0/3] iio: mxs-lradc: add support to optional divider_by_two Marek Vasut
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).