* [PATCH v3 3/3] iio: adc: add new lp8788 adc driver
@ 2012-08-16 7:39 ` Kim, Milo
0 siblings, 0 replies; 3+ messages in thread
From: Kim, Milo @ 2012-08-16 7:39 UTC (permalink / raw)
To: Jonathan Cameron
Cc: Lars-Peter Clausen, jic23@cam.ac.uk, linux-kernel@vger.kernel.org,
linux-iio@vger.kernel.org, Sangwook Lee
Patch v3.
(a) Delete unnecessary blank line of description
(b) Sort alphabetical order for header
(c) Replace udelay() with usleep_range()
(d) Change read_raw() in case of scale and offset
: result can be calculated as raw * (scaleint + scalepart * 1000000) + =
offset.
(scale: micro unit)
(e) Add 'const' for static constant iio_chan_spec
(f) Fix wrong size of allocating iio private data
Signed-off-by: Milo(Woogyom) Kim <milo.kim@ti.com>
---
drivers/iio/adc/Kconfig | 6 +
drivers/iio/adc/Makefile | 1 +
drivers/iio/adc/lp8788_adc.c | 224 ++++++++++++++++++++++++++++++++++++++=
++++
3 files changed, 231 insertions(+), 0 deletions(-)
create mode 100644 drivers/iio/adc/lp8788_adc.c
diff --git a/drivers/iio/adc/Kconfig b/drivers/iio/adc/Kconfig
index 8a78b4f..30c06ed 100644
--- a/drivers/iio/adc/Kconfig
+++ b/drivers/iio/adc/Kconfig
@@ -22,4 +22,10 @@ config AT91_ADC
help
Say yes here to build support for Atmel AT91 ADC.
=20
+config LP8788_ADC
+ bool "LP8788 ADC driver"
+ depends on MFD_LP8788
+ help
+ Say yes here to build support for TI LP8788 ADC.
+
endmenu
diff --git a/drivers/iio/adc/Makefile b/drivers/iio/adc/Makefile
index 52eec25..72f9a76 100644
--- a/drivers/iio/adc/Makefile
+++ b/drivers/iio/adc/Makefile
@@ -4,3 +4,4 @@
=20
obj-$(CONFIG_AD7266) +=3D ad7266.o
obj-$(CONFIG_AT91_ADC) +=3D at91_adc.o
+obj-$(CONFIG_LP8788_ADC) +=3D lp8788_adc.o
diff --git a/drivers/iio/adc/lp8788_adc.c b/drivers/iio/adc/lp8788_adc.c
new file mode 100644
index 0000000..1bd636a
--- /dev/null
+++ b/drivers/iio/adc/lp8788_adc.c
@@ -0,0 +1,224 @@
+/*
+ * TI LP8788 MFD - ADC driver
+ *
+ * Copyright 2012 Texas Instruments
+ *
+ * Author: Milo(Woogyom) Kim <milo.kim@ti.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include <linux/delay.h>
+#include <linux/iio/iio.h>
+#include <linux/iio/driver.h>
+#include <linux/mfd/lp8788.h>
+#include <linux/module.h>
+#include <linux/platform_device.h>
+#include <linux/slab.h>
+
+/* register address */
+#define LP8788_ADC_CONF 0x60
+#define LP8788_ADC_RAW 0x61
+#define LP8788_ADC_DONE 0x63
+
+#define START_ADC_CHANNEL LPADC_VBATT_5P5
+#define END_ADC_CHANNEL LPADC_MAX
+#define ADC_CONV_START 1
+
+struct lp8788_adc {
+ struct lp8788 *lp;
+};
+
+static const int lp8788_scale[LPADC_MAX] =3D {
+ [LPADC_VBATT_5P5] =3D 1343,
+ [LPADC_VIN_CHG] =3D 3052,
+ [LPADC_IBATT] =3D 610,
+ [LPADC_IC_TEMP] =3D 610,
+ [LPADC_VBATT_6P0] =3D 1465,
+ [LPADC_VBATT_5P0] =3D 1221,
+ [LPADC_ADC1] =3D 610,
+ [LPADC_ADC2] =3D 610,
+ [LPADC_VDD] =3D 1025,
+ [LPADC_VCOIN] =3D 757,
+ [LPADC_VDD_LDO] =3D 610,
+ [LPADC_ADC3] =3D 610,
+ [LPADC_ADC4] =3D 610,
+};
+
+static inline int lp8788_adc_read_raw(struct iio_dev *indio_dev,
+ struct iio_chan_spec const *chan,
+ int *val, int *val2, long mask)
+{
+ struct lp8788_adc *adc =3D iio_priv(indio_dev);
+ int retry =3D 5;
+ unsigned int msb, lsb, result;
+ u8 data, rawdata[2];
+ int size =3D ARRAY_SIZE(rawdata);
+ enum lp8788_adc_id id =3D chan->channel;
+
+ data =3D (id << 1) | ADC_CONV_START;
+ if (lp8788_write_byte(adc->lp, LP8788_ADC_CONF, data))
+ goto err;
+
+ /* retry until adc conversion is done */
+ data =3D 0;
+ while (retry--) {
+ usleep_range(100, 200);
+
+ if (lp8788_read_byte(adc->lp, LP8788_ADC_DONE, &data))
+ goto err;
+
+ /* conversion done */
+ if (data)
+ break;
+ }
+
+ if (lp8788_read_multi_bytes(adc->lp, LP8788_ADC_RAW, rawdata, size))
+ goto err;
+
+ msb =3D (rawdata[0] << 4) & 0x00000ff0;
+ lsb =3D (rawdata[1] >> 4) & 0x0000000f;
+ result =3D msb | lsb;
+
+ /* iio consumer: result =3D raw * scale + offset */
+ switch (mask) {
+ case IIO_CHAN_INFO_RAW:
+ *val =3D result;
+ return IIO_VAL_INT;
+ case IIO_CHAN_INFO_SCALE:
+ *val =3D lp8788_scale[id];
+ *val2 =3D 0;
+ return IIO_VAL_INT_PLUS_MICRO;
+ case IIO_CHAN_INFO_OFFSET:
+ *val =3D lp8788_scale[id] / 2;
+ return IIO_VAL_INT;
+ default:
+ break;
+ }
+
+err:
+ return -EINVAL;
+}
+
+static const struct iio_info lp8788_adc_info =3D {
+ .read_raw =3D &lp8788_adc_read_raw,
+ .driver_module =3D THIS_MODULE,
+};
+
+#define LP8788_CHAN(_id, _type) { \
+ .type =3D _type, \
+ .indexed =3D 1, \
+ .channel =3D LPADC_##_id, \
+ .info_mask =3D IIO_CHAN_INFO_RAW_SEPARATE_BIT | \
+ IIO_CHAN_INFO_SCALE_SEPARATE_BIT, \
+ .address =3D LP8788_ADC_RAW, \
+ .scan_type =3D IIO_ST('u', 8, 12, 4), \
+ .scan_index =3D 1, \
+ .datasheet_name =3D #_id, \
+}
+
+static const struct iio_chan_spec lp8788_adc_channels[] =3D {
+ [LPADC_VBATT_5P5] =3D LP8788_CHAN(VBATT_5P5, IIO_VOLTAGE),
+ [LPADC_VIN_CHG] =3D LP8788_CHAN(VIN_CHG, IIO_VOLTAGE),
+ [LPADC_IBATT] =3D LP8788_CHAN(IBATT, IIO_CURRENT),
+ [LPADC_IC_TEMP] =3D LP8788_CHAN(IC_TEMP, IIO_TEMP),
+ [LPADC_VBATT_6P0] =3D LP8788_CHAN(VBATT_6P0, IIO_VOLTAGE),
+ [LPADC_VBATT_5P0] =3D LP8788_CHAN(VBATT_5P0, IIO_VOLTAGE),
+ [LPADC_ADC1] =3D LP8788_CHAN(ADC1, IIO_VOLTAGE),
+ [LPADC_ADC2] =3D LP8788_CHAN(ADC2, IIO_VOLTAGE),
+ [LPADC_VDD] =3D LP8788_CHAN(VDD, IIO_VOLTAGE),
+ [LPADC_VCOIN] =3D LP8788_CHAN(VCOIN, IIO_VOLTAGE),
+ [LPADC_VDD_LDO] =3D LP8788_CHAN(VDD_LDO, IIO_VOLTAGE),
+ [LPADC_ADC3] =3D LP8788_CHAN(ADC3, IIO_VOLTAGE),
+ [LPADC_ADC4] =3D LP8788_CHAN(ADC4, IIO_VOLTAGE),
+};
+
+static int __devinit lp8788_adc_probe(struct platform_device *pdev)
+{
+ struct lp8788 *lp =3D dev_get_drvdata(pdev->dev.parent);
+ struct iio_dev *indio_dev;
+ struct iio_map *map;
+ struct lp8788_adc *adc;
+ int i, ret;
+
+ indio_dev =3D iio_device_alloc(sizeof(*adc));
+ if (!indio_dev)
+ return -ENOMEM;
+
+ adc =3D iio_priv(indio_dev);
+ adc->lp =3D lp;
+ platform_set_drvdata(pdev, indio_dev);
+
+ if (lp->pdata) {
+ for (i =3D START_ADC_CHANNEL; i < END_ADC_CHANNEL ; i++) {
+ map =3D lp->pdata->adc_pdata[i];
+ ret =3D iio_map_array_register(indio_dev, map);
+ if (ret) {
+ dev_err(lp->dev, "iio map err: %d\n", ret);
+ goto err_iio_map_array;
+ }
+ }
+ }
+
+ indio_dev->dev.parent =3D lp->dev;
+ indio_dev->name =3D pdev->name;
+ indio_dev->modes =3D INDIO_DIRECT_MODE;
+ indio_dev->info =3D &lp8788_adc_info;
+ indio_dev->channels =3D lp8788_adc_channels;
+ indio_dev->num_channels =3D ARRAY_SIZE(lp8788_adc_channels);
+
+ ret =3D iio_device_register(indio_dev);
+ if (ret) {
+ dev_err(lp->dev, "iio dev register err: %d\n", ret);
+ goto err_iio_register;
+ }
+
+ return 0;
+
+err_iio_map_array:
+ while (--i >=3D START_ADC_CHANNEL) {
+ map =3D lp->pdata->adc_pdata[i];
+ iio_map_array_unregister(indio_dev, map);
+ }
+err_iio_register:
+ iio_device_free(indio_dev);
+ return ret;
+}
+
+static int __devexit lp8788_adc_remove(struct platform_device *pdev)
+{
+ struct iio_dev *indio_dev =3D platform_get_drvdata(pdev);
+ struct lp8788_adc *adc =3D iio_priv(indio_dev);
+ struct lp8788 *lp =3D adc->lp;
+ struct iio_map *map;
+ int i;
+
+ if (lp->pdata) {
+ for (i =3D START_ADC_CHANNEL; i < END_ADC_CHANNEL ; i++) {
+ map =3D lp->pdata->adc_pdata[i];
+ iio_map_array_unregister(indio_dev, map);
+ }
+ }
+
+ iio_device_unregister(indio_dev);
+ iio_device_free(indio_dev);
+
+ return 0;
+}
+
+static struct platform_driver lp8788_adc_driver =3D {
+ .probe =3D lp8788_adc_probe,
+ .remove =3D __devexit_p(lp8788_adc_remove),
+ .driver =3D {
+ .name =3D LP8788_DEV_ADC,
+ .owner =3D THIS_MODULE,
+ },
+};
+module_platform_driver(lp8788_adc_driver);
+
+MODULE_DESCRIPTION("Texas Instruments LP8788 ADC Driver");
+MODULE_AUTHOR("Milo Kim");
+MODULE_LICENSE("GPL");
+MODULE_ALIAS("platform:lp8788-adc");
--=20
1.7.2.5
Best Regards,
Milo
^ permalink raw reply related [flat|nested] 3+ messages in thread
* [PATCH v3 3/3] iio: adc: add new lp8788 adc driver
@ 2012-08-16 7:39 ` Kim, Milo
0 siblings, 0 replies; 3+ messages in thread
From: Kim, Milo @ 2012-08-16 7:39 UTC (permalink / raw)
To: Jonathan Cameron
Cc: Lars-Peter Clausen, jic23@cam.ac.uk, linux-kernel@vger.kernel.org,
linux-iio@vger.kernel.org, Sangwook Lee
Patch v3.
(a) Delete unnecessary blank line of description
(b) Sort alphabetical order for header
(c) Replace udelay() with usleep_range()
(d) Change read_raw() in case of scale and offset
: result can be calculated as raw * (scaleint + scalepart * 1000000) + offset.
(scale: micro unit)
(e) Add 'const' for static constant iio_chan_spec
(f) Fix wrong size of allocating iio private data
Signed-off-by: Milo(Woogyom) Kim <milo.kim@ti.com>
---
drivers/iio/adc/Kconfig | 6 +
drivers/iio/adc/Makefile | 1 +
drivers/iio/adc/lp8788_adc.c | 224 ++++++++++++++++++++++++++++++++++++++++++
3 files changed, 231 insertions(+), 0 deletions(-)
create mode 100644 drivers/iio/adc/lp8788_adc.c
diff --git a/drivers/iio/adc/Kconfig b/drivers/iio/adc/Kconfig
index 8a78b4f..30c06ed 100644
--- a/drivers/iio/adc/Kconfig
+++ b/drivers/iio/adc/Kconfig
@@ -22,4 +22,10 @@ config AT91_ADC
help
Say yes here to build support for Atmel AT91 ADC.
+config LP8788_ADC
+ bool "LP8788 ADC driver"
+ depends on MFD_LP8788
+ help
+ Say yes here to build support for TI LP8788 ADC.
+
endmenu
diff --git a/drivers/iio/adc/Makefile b/drivers/iio/adc/Makefile
index 52eec25..72f9a76 100644
--- a/drivers/iio/adc/Makefile
+++ b/drivers/iio/adc/Makefile
@@ -4,3 +4,4 @@
obj-$(CONFIG_AD7266) += ad7266.o
obj-$(CONFIG_AT91_ADC) += at91_adc.o
+obj-$(CONFIG_LP8788_ADC) += lp8788_adc.o
diff --git a/drivers/iio/adc/lp8788_adc.c b/drivers/iio/adc/lp8788_adc.c
new file mode 100644
index 0000000..1bd636a
--- /dev/null
+++ b/drivers/iio/adc/lp8788_adc.c
@@ -0,0 +1,224 @@
+/*
+ * TI LP8788 MFD - ADC driver
+ *
+ * Copyright 2012 Texas Instruments
+ *
+ * Author: Milo(Woogyom) Kim <milo.kim@ti.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include <linux/delay.h>
+#include <linux/iio/iio.h>
+#include <linux/iio/driver.h>
+#include <linux/mfd/lp8788.h>
+#include <linux/module.h>
+#include <linux/platform_device.h>
+#include <linux/slab.h>
+
+/* register address */
+#define LP8788_ADC_CONF 0x60
+#define LP8788_ADC_RAW 0x61
+#define LP8788_ADC_DONE 0x63
+
+#define START_ADC_CHANNEL LPADC_VBATT_5P5
+#define END_ADC_CHANNEL LPADC_MAX
+#define ADC_CONV_START 1
+
+struct lp8788_adc {
+ struct lp8788 *lp;
+};
+
+static const int lp8788_scale[LPADC_MAX] = {
+ [LPADC_VBATT_5P5] = 1343,
+ [LPADC_VIN_CHG] = 3052,
+ [LPADC_IBATT] = 610,
+ [LPADC_IC_TEMP] = 610,
+ [LPADC_VBATT_6P0] = 1465,
+ [LPADC_VBATT_5P0] = 1221,
+ [LPADC_ADC1] = 610,
+ [LPADC_ADC2] = 610,
+ [LPADC_VDD] = 1025,
+ [LPADC_VCOIN] = 757,
+ [LPADC_VDD_LDO] = 610,
+ [LPADC_ADC3] = 610,
+ [LPADC_ADC4] = 610,
+};
+
+static inline int lp8788_adc_read_raw(struct iio_dev *indio_dev,
+ struct iio_chan_spec const *chan,
+ int *val, int *val2, long mask)
+{
+ struct lp8788_adc *adc = iio_priv(indio_dev);
+ int retry = 5;
+ unsigned int msb, lsb, result;
+ u8 data, rawdata[2];
+ int size = ARRAY_SIZE(rawdata);
+ enum lp8788_adc_id id = chan->channel;
+
+ data = (id << 1) | ADC_CONV_START;
+ if (lp8788_write_byte(adc->lp, LP8788_ADC_CONF, data))
+ goto err;
+
+ /* retry until adc conversion is done */
+ data = 0;
+ while (retry--) {
+ usleep_range(100, 200);
+
+ if (lp8788_read_byte(adc->lp, LP8788_ADC_DONE, &data))
+ goto err;
+
+ /* conversion done */
+ if (data)
+ break;
+ }
+
+ if (lp8788_read_multi_bytes(adc->lp, LP8788_ADC_RAW, rawdata, size))
+ goto err;
+
+ msb = (rawdata[0] << 4) & 0x00000ff0;
+ lsb = (rawdata[1] >> 4) & 0x0000000f;
+ result = msb | lsb;
+
+ /* iio consumer: result = raw * scale + offset */
+ switch (mask) {
+ case IIO_CHAN_INFO_RAW:
+ *val = result;
+ return IIO_VAL_INT;
+ case IIO_CHAN_INFO_SCALE:
+ *val = lp8788_scale[id];
+ *val2 = 0;
+ return IIO_VAL_INT_PLUS_MICRO;
+ case IIO_CHAN_INFO_OFFSET:
+ *val = lp8788_scale[id] / 2;
+ return IIO_VAL_INT;
+ default:
+ break;
+ }
+
+err:
+ return -EINVAL;
+}
+
+static const struct iio_info lp8788_adc_info = {
+ .read_raw = &lp8788_adc_read_raw,
+ .driver_module = THIS_MODULE,
+};
+
+#define LP8788_CHAN(_id, _type) { \
+ .type = _type, \
+ .indexed = 1, \
+ .channel = LPADC_##_id, \
+ .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT | \
+ IIO_CHAN_INFO_SCALE_SEPARATE_BIT, \
+ .address = LP8788_ADC_RAW, \
+ .scan_type = IIO_ST('u', 8, 12, 4), \
+ .scan_index = 1, \
+ .datasheet_name = #_id, \
+}
+
+static const struct iio_chan_spec lp8788_adc_channels[] = {
+ [LPADC_VBATT_5P5] = LP8788_CHAN(VBATT_5P5, IIO_VOLTAGE),
+ [LPADC_VIN_CHG] = LP8788_CHAN(VIN_CHG, IIO_VOLTAGE),
+ [LPADC_IBATT] = LP8788_CHAN(IBATT, IIO_CURRENT),
+ [LPADC_IC_TEMP] = LP8788_CHAN(IC_TEMP, IIO_TEMP),
+ [LPADC_VBATT_6P0] = LP8788_CHAN(VBATT_6P0, IIO_VOLTAGE),
+ [LPADC_VBATT_5P0] = LP8788_CHAN(VBATT_5P0, IIO_VOLTAGE),
+ [LPADC_ADC1] = LP8788_CHAN(ADC1, IIO_VOLTAGE),
+ [LPADC_ADC2] = LP8788_CHAN(ADC2, IIO_VOLTAGE),
+ [LPADC_VDD] = LP8788_CHAN(VDD, IIO_VOLTAGE),
+ [LPADC_VCOIN] = LP8788_CHAN(VCOIN, IIO_VOLTAGE),
+ [LPADC_VDD_LDO] = LP8788_CHAN(VDD_LDO, IIO_VOLTAGE),
+ [LPADC_ADC3] = LP8788_CHAN(ADC3, IIO_VOLTAGE),
+ [LPADC_ADC4] = LP8788_CHAN(ADC4, IIO_VOLTAGE),
+};
+
+static int __devinit lp8788_adc_probe(struct platform_device *pdev)
+{
+ struct lp8788 *lp = dev_get_drvdata(pdev->dev.parent);
+ struct iio_dev *indio_dev;
+ struct iio_map *map;
+ struct lp8788_adc *adc;
+ int i, ret;
+
+ indio_dev = iio_device_alloc(sizeof(*adc));
+ if (!indio_dev)
+ return -ENOMEM;
+
+ adc = iio_priv(indio_dev);
+ adc->lp = lp;
+ platform_set_drvdata(pdev, indio_dev);
+
+ if (lp->pdata) {
+ for (i = START_ADC_CHANNEL; i < END_ADC_CHANNEL ; i++) {
+ map = lp->pdata->adc_pdata[i];
+ ret = iio_map_array_register(indio_dev, map);
+ if (ret) {
+ dev_err(lp->dev, "iio map err: %d\n", ret);
+ goto err_iio_map_array;
+ }
+ }
+ }
+
+ indio_dev->dev.parent = lp->dev;
+ indio_dev->name = pdev->name;
+ indio_dev->modes = INDIO_DIRECT_MODE;
+ indio_dev->info = &lp8788_adc_info;
+ indio_dev->channels = lp8788_adc_channels;
+ indio_dev->num_channels = ARRAY_SIZE(lp8788_adc_channels);
+
+ ret = iio_device_register(indio_dev);
+ if (ret) {
+ dev_err(lp->dev, "iio dev register err: %d\n", ret);
+ goto err_iio_register;
+ }
+
+ return 0;
+
+err_iio_map_array:
+ while (--i >= START_ADC_CHANNEL) {
+ map = lp->pdata->adc_pdata[i];
+ iio_map_array_unregister(indio_dev, map);
+ }
+err_iio_register:
+ iio_device_free(indio_dev);
+ return ret;
+}
+
+static int __devexit lp8788_adc_remove(struct platform_device *pdev)
+{
+ struct iio_dev *indio_dev = platform_get_drvdata(pdev);
+ struct lp8788_adc *adc = iio_priv(indio_dev);
+ struct lp8788 *lp = adc->lp;
+ struct iio_map *map;
+ int i;
+
+ if (lp->pdata) {
+ for (i = START_ADC_CHANNEL; i < END_ADC_CHANNEL ; i++) {
+ map = lp->pdata->adc_pdata[i];
+ iio_map_array_unregister(indio_dev, map);
+ }
+ }
+
+ iio_device_unregister(indio_dev);
+ iio_device_free(indio_dev);
+
+ return 0;
+}
+
+static struct platform_driver lp8788_adc_driver = {
+ .probe = lp8788_adc_probe,
+ .remove = __devexit_p(lp8788_adc_remove),
+ .driver = {
+ .name = LP8788_DEV_ADC,
+ .owner = THIS_MODULE,
+ },
+};
+module_platform_driver(lp8788_adc_driver);
+
+MODULE_DESCRIPTION("Texas Instruments LP8788 ADC Driver");
+MODULE_AUTHOR("Milo Kim");
+MODULE_LICENSE("GPL");
+MODULE_ALIAS("platform:lp8788-adc");
--
1.7.2.5
Best Regards,
Milo
^ permalink raw reply related [flat|nested] 3+ messages in thread
* Re: [PATCH v3 3/3] iio: adc: add new lp8788 adc driver
2012-08-16 7:39 ` Kim, Milo
(?)
@ 2012-08-16 8:16 ` Lars-Peter Clausen
-1 siblings, 0 replies; 3+ messages in thread
From: Lars-Peter Clausen @ 2012-08-16 8:16 UTC (permalink / raw)
To: Kim, Milo
Cc: Jonathan Cameron, jic23@cam.ac.uk, linux-kernel@vger.kernel.org,
linux-iio@vger.kernel.org, Sangwook Lee
On 08/16/2012 09:39 AM, Kim, Milo wrote:
> Patch v3.
> (a) Delete unnecessary blank line of description
> (b) Sort alphabetical order for header
> (c) Replace udelay() with usleep_range()
> (d) Change read_raw() in case of scale and offset
> : result can be calculated as raw * (scaleint + scalepart * 1000000) + offset.
> (scale: micro unit)
For IIO it should actually be (raw + offset) * scale and the result should be
in the unit which is specified in the IIO sysfs ABI document. E.g. milivolts
for voltages.
[...]
> +
> + if (lp8788_read_multi_bytes(adc->lp, LP8788_ADC_RAW, rawdata, size))
> + goto err;
> +
> + msb = (rawdata[0] << 4) & 0x00000ff0;
> + lsb = (rawdata[1] >> 4) & 0x0000000f;
> + result = msb | lsb;
> +
> + /* iio consumer: result = raw * scale + offset */
> + switch (mask) {
> + case IIO_CHAN_INFO_RAW:
> + *val = result;
> + return IIO_VAL_INT;
> + case IIO_CHAN_INFO_SCALE:
> + *val = lp8788_scale[id];
> + *val2 = 0;
Scale should be the number of millivolts per bit. Given the number in the table
above I somehow doubt that this is what you return here. Well or maybe this
part is actually used to measure up to a few kilo volts ;)
> + return IIO_VAL_INT_PLUS_MICRO;
> + case IIO_CHAN_INFO_OFFSET:
> + *val = lp8788_scale[id] / 2;
> + return IIO_VAL_INT;
As said above offset should be in the same unit as the raw result. I'd expect
it to be same for each channel.
Btw. how does the voltage mapping look in you case?
0x000 raw -> ? V
0x800 raw -> ? V
0xfff raw -> ? V
> + default:
> + break;
> + }
> +
> +err:
> + return -EINVAL;
> +}
> +
> +static const struct iio_info lp8788_adc_info = {
> + .read_raw = &lp8788_adc_read_raw,
> + .driver_module = THIS_MODULE,
> +};
> +
> +#define LP8788_CHAN(_id, _type) { \
> + .type = _type, \
> + .indexed = 1, \
> + .channel = LPADC_##_id, \
> + .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT | \
> + IIO_CHAN_INFO_SCALE_SEPARATE_BIT, \
> + .address = LP8788_ADC_RAW, \
> + .scan_type = IIO_ST('u', 8, 12, 4), \
This says your sample has 8 bits and you want to store them in a 12 bit word.
This seems wrong.
> + .scan_index = 1, \
> + .datasheet_name = #_id, \
> +}
> +
^ permalink raw reply [flat|nested] 3+ messages in thread
end of thread, other threads:[~2012-08-16 8:16 UTC | newest]
Thread overview: 3+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2012-08-16 7:39 [PATCH v3 3/3] iio: adc: add new lp8788 adc driver Kim, Milo
2012-08-16 7:39 ` Kim, Milo
2012-08-16 8:16 ` Lars-Peter Clausen
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.