Skip to contentSkip to conversation

iio: adc: ltc2485: add support for Linear Technology LTC2485 ADC

PATCH In review Alison Schofield 2 participants 4 messages Aug 25, 2016 – Sep 3, 2016 IIO

lore
Share & tools
lore
#0 lore raw

PATCH v2 1/1 iio: adc: ltc2485: add support for Linear Technology LTC2485 ADC

Adds basic support for the LTC2485 ADC - a delta-sigma analog-to-digital converter with an I2C interface that operates in single shot conversion mode.

The driver supports an on board 5V reference and the power-on default configuration which rejects both 50hz & 60hz line frequencies and operates in 1x speed mode.

---
Changes in v2:
- changed the wait conversion time function to use monotonic rather than real time and to use milliseconds rather than nanoseconds.
- made conv time a constant int.

Same notes as in v1:
Reviewers: In addition to commenting on what is present, please comment on what is absent and the priority in which you would like to see additional features added to this driver, or needed in this first submittal.

Not supported:
1. External Vref
2. Additional Configuration Modes
Temperature Sensor Mode: report temp data (not voltage).

Line Frequency Rejection Mode: select to reject 50Hz or 60Hz or both. (both is default)

Speed Mode: Default speed mode (1x) performs two conversions each cycle and combines the results. 2x speed mode only does one conversion each cycle.
3. Power management
4. DT Bindings
5. Triggered buffers
6. What else?

 drivers/iio/adc/Kconfig   |   9 +++
 drivers/iio/adc/Makefile  |   1 +
 drivers/iio/adc/ltc2485.c | 146 ++++++++++++++++++++++++++++++++++++++++++++++
 3 files changed, 156 insertions(+)
 create mode 100644 drivers/iio/adc/ltc2485.c
drivers/iio/adc/Kconfig +9 -0
index 1de31bd..a042611 100644
@@ -264,6 +264,15 @@ config LPC18XX_ADC
 	  To compile this driver as a module, choose M here: the module will be
 	  called lpc18xx_adc.
 
+config LTC2485
+	tristate "Linear Technology LTC2485 ADC driver"
+	depends on I2C
+	help
+	  Say yes here to build support for Linear Technology LTC2485 ADC.
+
+	  To compile this driver as a module, choose M here: the module will be
+	  called ltc2485.
+
 config MAX1027
 	tristate "Maxim max1027 ADC driver"
 	depends on SPI
drivers/iio/adc/Makefile +1 -0
index 0ba0d50..1be5747 100644
@@ -27,6 +27,7 @@ obj-$(CONFIG_IMX7D_ADC) += imx7d_adc.o
 obj-$(CONFIG_INA2XX_ADC) += ina2xx-adc.o
 obj-$(CONFIG_LP8788_ADC) += lp8788_adc.o
 obj-$(CONFIG_LPC18XX_ADC) += lpc18xx_adc.o
+obj-$(CONFIG_LTC2485) += ltc2485.o
 obj-$(CONFIG_MAX1027) += max1027.o
 obj-$(CONFIG_MAX1363) += max1363.o
 obj-$(CONFIG_MCP320X) += mcp320x.o
drivers/iio/adc/ltc2485.c new file +146 -0

146 lines not on this page · raw message

Signature · 1 line
2.1.4
maintainer
#1 lore raw
Quoted 16 lines · Alison Schofield

Adds basic support for the LTC2485 ADC - a delta-sigma analog-to-digital converter with an I2C interface that operates in single shot conversion mode.

The driver supports an on board 5V reference and the power-on default configuration which rejects both 50hz & 60hz line frequencies and operates in 1x speed mode.

---
Changes in v2:
- changed the wait conversion time function to use monotonic rather than real time and to use milliseconds rather than nanoseconds.
- made conv time a constant int.

Quoted 4 lines

Same notes as in v1:
Reviewers: In addition to commenting on what is present, please comment on what is absent and the priority in which you would like to see additional features added to this driver, or needed in this first submittal.

None of the below are needed for initially submital.
All 'value' add features at the end of the day. Job one: get reading from ADC done :)

I made a few really small white space changes and applied this to the togreg branch of iio.git. Will be initially pushed out as testing in a few minutes time to check the autobuilders can't find anything.

Thanks,

Jonathan

Quoted 8 lines

Not supported:
1. External Vref
2. Additional Configuration Modes
Temperature Sensor Mode: report temp data (not voltage).

Line Frequency Rejection Mode: select to reject 50Hz or 60Hz or both. (both is default)

This is interesting... Will need some new ABI. It's a filter so we probably want to try and fit it in with the existing filter ABI.

Quoted 4 lines

Speed Mode: Default speed mode (1x) performs two conversions each cycle and combines the results. 2x speed mode only does one conversion each cycle.

Really simple case of oversampling. So this one is easy ;)

Quoted 3 lines

3. Power management
4. DT Bindings
5. Triggered buffers

Device is really slow, so no real rush on this one. Nice to have for the convenience of using standard interfaces in libiio etc, but at 7sps reading sysfs will work fine for all usecases!

Quoted 1 line

6. What else?

Other power supply regulators..
(allows complete power disabling if there is an appropriate controllable regulator on the board).

Quoted 90 lines

 drivers/iio/adc/Kconfig   |   9 +++
 drivers/iio/adc/Makefile  |   1 +
 drivers/iio/adc/ltc2485.c | 146 ++++++++++++++++++++++++++++++++++++++++++++++
 3 files changed, 156 insertions(+)
 create mode 100644 drivers/iio/adc/ltc2485.c
drivers/iio/adc/Kconfig +9 -0
index 1de31bd..a042611 100644
@@ -264,6 +264,15 @@ config LPC18XX_ADC
 	  To compile this driver as a module, choose M here: the module will be
 	  called lpc18xx_adc.
 
+config LTC2485
+	tristate "Linear Technology LTC2485 ADC driver"
+	depends on I2C
+	help
+	  Say yes here to build support for Linear Technology LTC2485 ADC.
+
+	  To compile this driver as a module, choose M here: the module will be
+	  called ltc2485.
+
 config MAX1027
 	tristate "Maxim max1027 ADC driver"
 	depends on SPI
drivers/iio/adc/Makefile +1 -0
index 0ba0d50..1be5747 100644
@@ -27,6 +27,7 @@ obj-$(CONFIG_IMX7D_ADC) += imx7d_adc.o
 obj-$(CONFIG_INA2XX_ADC) += ina2xx-adc.o
 obj-$(CONFIG_LP8788_ADC) += lp8788_adc.o
 obj-$(CONFIG_LPC18XX_ADC) += lpc18xx_adc.o
+obj-$(CONFIG_LTC2485) += ltc2485.o
 obj-$(CONFIG_MAX1027) += max1027.o
 obj-$(CONFIG_MAX1363) += max1363.o
 obj-$(CONFIG_MCP320X) += mcp320x.o
drivers/iio/adc/ltc2485.c new file +44 -0
new file mode 100644
index 0000000..d8f9dac
@@ -0,0 +1,146 @@
+/*
+ * ltc2485.c - Driver for Linear Technology LTC2485 ADC
+ *
+ * Copyright (C) 2016 Alison Schofield <[email protected]>
+ *
+ * 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.
+ *
+ * Datasheet: http://cds.linear.com/docs/en/datasheet/2485fd.pdf
+ */
+
+#include <linux/delay.h>
+#include <linux/i2c.h>
+#include <linux/module.h>
+
+#include <linux/iio/iio.h>
+#include <linux/iio/sysfs.h>
+
+/* Power-on configuration: rejects both 50/60Hz, operates at 1x speed */
+#define LTC2485_CONFIG_DEFAULT		0
+
+struct ltc2485_data {
+	struct i2c_client	*client;
+	ktime_t			time_prev;	/* last conversion */
+};
+
+static void ltc2485_wait_conv(struct ltc2485_data *data)
+{
+	const unsigned int conv_time = 147;	/* conversion time ms */
+	unsigned int time_elapsed;
+
+	/* delay if conversion time not passed since last read or write */
+	time_elapsed = ktime_ms_delta(ktime_get(), data->time_prev);
+
+	if (time_elapsed < conv_time)
+		msleep(conv_time - time_elapsed);
+}
+
+static int ltc2485_read(struct ltc2485_data *data, int *val)
+{
+	struct i2c_client *client = data->client;
+	__be32 buf = 0;
+	int ret;

drivers/iio/adc/ltc2485.c line 54

Quoted 10 lines
drivers/iio/adc/ltc2485.c new file +10 -0
+
+	ltc2485_wait_conv(data);
+
+	ret = i2c_master_recv(client, (char *)&buf, 4);
+	if (ret < 0)  {
+		dev_err(&client->dev, "i2c_master_recv failed\n");
+		return ret;
+	}
+	data->time_prev = ktime_get();
+	*val = sign_extend32(be32_to_cpu(buf) >> 6, 24);

Slightly preference for a blank line before a simple return statement like this. Makes it ever so slightly easier to read.

Quoted 93 lines
drivers/iio/adc/ltc2485.c new file +92 -0
+	return ret;
+}
+
+static int ltc2485_read_raw(struct iio_dev *indio_dev,
+			    struct iio_chan_spec const *chan,
+			    int *val, int *val2, long mask)
+{
+	struct ltc2485_data *data = iio_priv(indio_dev);
+	int ret;
+
+	if (mask == IIO_CHAN_INFO_RAW) {
+		ret = ltc2485_read(data, val);
+		if (ret < 0)
+			return ret;
+
+		return IIO_VAL_INT;
+
+	} else if (mask == IIO_CHAN_INFO_SCALE) {
+		*val = 5000;			/* on board vref millivolts */
+		*val2 = 25;			/* 25 (24 + sign) data bits */
+		return IIO_VAL_FRACTIONAL_LOG2;
+
+	} else {
+		return -EINVAL;
+	}
+}
+
+static const struct iio_chan_spec ltc2485_channel[] = {
+	{
+		.type = IIO_VOLTAGE,
+		.info_mask_separate = BIT(IIO_CHAN_INFO_RAW),
+		.info_mask_shared_by_type = BIT(IIO_CHAN_INFO_SCALE)
+	},
+};
+
+static const struct iio_info ltc2485_info = {
+	.read_raw = ltc2485_read_raw,
+	.driver_module = THIS_MODULE,
+};
+
+static int ltc2485_probe(struct i2c_client *client,
+			 const struct i2c_device_id *id)
+{
+	struct iio_dev *indio_dev;
+	struct ltc2485_data *data;
+	int ret;
+
+	if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C |
+				     I2C_FUNC_SMBUS_WRITE_BYTE))
+		return -EOPNOTSUPP;
+
+	indio_dev = devm_iio_device_alloc(&client->dev, sizeof(*data));
+	if (!indio_dev)
+		return -ENOMEM;
+
+	data = iio_priv(indio_dev);
+	i2c_set_clientdata(client, indio_dev);
+	data->client = client;
+
+	indio_dev->dev.parent = &client->dev;
+	indio_dev->name = id->name;
+	indio_dev->info = &ltc2485_info;
+	indio_dev->modes = INDIO_DIRECT_MODE;
+	indio_dev->channels = ltc2485_channel;
+	indio_dev->num_channels = ARRAY_SIZE(ltc2485_channel);
+
+	ret = i2c_smbus_write_byte(data->client, LTC2485_CONFIG_DEFAULT);
+	if (ret < 0)
+		return ret;
+
+	data->time_prev = ktime_get();
+	return devm_iio_device_register(&client->dev, indio_dev);
+}
+
+static const struct i2c_device_id ltc2485_id[] = {
+	{ "ltc2485", 0 },
+	{ }
+};
+MODULE_DEVICE_TABLE(i2c, ltc2485_id);
+
+static struct i2c_driver ltc2485_driver = {
+	.driver = {
+		.name = "ltc2485",
+	},
+	.probe = ltc2485_probe,
+	.id_table = ltc2485_id,
+};
+module_i2c_driver(ltc2485_driver);
+
+MODULE_AUTHOR("Alison Schofield <[email protected]>");
+MODULE_DESCRIPTION("Linear Technology LTC2485 ADC driver");
+MODULE_LICENSE("GPL v2");
#2 lore raw
Quoted 52 lines · Jonathan Cameron
Quoted 16 lines · Alison Schofield

Adds basic support for the LTC2485 ADC - a delta-sigma analog-to-digital converter with an I2C interface that operates in single shot conversion mode.

The driver supports an on board 5V reference and the power-on default configuration which rejects both 50hz & 60hz line frequencies and operates in 1x speed mode.

---
Changes in v2:
- changed the wait conversion time function to use monotonic rather than real time and to use milliseconds rather than nanoseconds.
- made conv time a constant int.

Quoted 4 lines

Same notes as in v1:
Reviewers: In addition to commenting on what is present, please comment on what is absent and the priority in which you would like to see additional features added to this driver, or needed in this first submittal.

None of the below are needed for initially submital.
All 'value' add features at the end of the day. Job one: get reading from ADC done :)

I made a few really small white space changes and applied this to the togreg branch of iio.git. Will be initially pushed out as testing in a few minutes time to check the autobuilders can't find anything.

Thanks,

Jonathan

Quoted 8 lines

Not supported:
1. External Vref
2. Additional Configuration Modes
Temperature Sensor Mode: report temp data (not voltage).

Line Frequency Rejection Mode: select to reject 50Hz or 60Hz or both. (both is default)

This is interesting... Will need some new ABI. It's a filter so we probably want to try and fit it in with the existing filter ABI.

Quoted 4 lines

Speed Mode: Default speed mode (1x) performs two conversions each cycle and combines the results. 2x speed mode only does one conversion each cycle.

Really simple case of oversampling. So this one is easy ;)

Quoted 3 lines

3. Power management
4. DT Bindings
5. Triggered buffers

Quoted 9 lines

Device is really slow, so no real rush on this one. Nice to have for the convenience of using standard interfaces in libiio etc, but at 7sps reading sysfs will work fine for all usecases!

Quoted 1 line

6. What else?

Other power supply regulators..
(allows complete power disabling if there is an appropriate controllable regulator on the board).

Thanks Jonathan!
I need more direction on the power supply regulators.

When you say power supply regulator, is that the same as reference voltage?

The driver uses onboard vref now. I see how I can add support for an external vref. But, it seems like maybe you are commenting that we can have both, an external vref with an onboard vref as a fallback?

Thanks,
alisons

maintainer
#3 lore raw
Quoted 65 lines · Alison Schofield
Quoted 52 lines · Jonathan Cameron
Quoted 16 lines · Alison Schofield

Adds basic support for the LTC2485 ADC - a delta-sigma analog-to-digital converter with an I2C interface that operates in single shot conversion mode.

The driver supports an on board 5V reference and the power-on default configuration which rejects both 50hz & 60hz line frequencies and operates in 1x speed mode.

---
Changes in v2:
- changed the wait conversion time function to use monotonic rather than real time and to use milliseconds rather than nanoseconds.
- made conv time a constant int.

Quoted 4 lines

Same notes as in v1:
Reviewers: In addition to commenting on what is present, please comment on what is absent and the priority in which you would like to see additional features added to this driver, or needed in this first submittal.

None of the below are needed for initially submital.
All 'value' add features at the end of the day. Job one: get reading from ADC done :)

I made a few really small white space changes and applied this to the togreg branch of iio.git. Will be initially pushed out as testing in a few minutes time to check the autobuilders can't find anything.

Thanks,

Jonathan

Quoted 8 lines

Not supported:
1. External Vref
2. Additional Configuration Modes
Temperature Sensor Mode: report temp data (not voltage).

Line Frequency Rejection Mode: select to reject 50Hz or 60Hz or both. (both is default)

This is interesting... Will need some new ABI. It's a filter so we probably want to try and fit it in with the existing filter ABI.

Quoted 4 lines

Speed Mode: Default speed mode (1x) performs two conversions each cycle and combines the results. 2x speed mode only does one conversion each cycle.

Really simple case of oversampling. So this one is easy ;)

Quoted 3 lines

3. Power management
4. DT Bindings
5. Triggered buffers

Quoted 9 lines

Device is really slow, so no real rush on this one. Nice to have for the convenience of using standard interfaces in libiio etc, but at 7sps reading sysfs will work fine for all usecases!

Quoted 1 line

6. What else?

Other power supply regulators..
(allows complete power disabling if there is an appropriate controllable regulator on the board).

Thanks Jonathan!
I need more direction on the power supply regulators.

Quoted 6 lines

When you say power supply regulator, is that the same as reference voltage?

The driver uses onboard vref now. I see how I can add support for an external vref. But, it seems like maybe you are commenting that we can have both, an external vref with an onboard vref as a fallback?

Usual trick here is that if the external vref is wired, then it makes sense to use it (or why would the hardware designer have put the source device on the board!). Hence we use regulator_get_optional call and handle the not present response which would indicate that the optional devicetree parameter or similar was not supplied - implying no hardware present.

So if it's not there we use the internal reference as currently doing.

Actually when I brought this up I meant the main power supply to the chip. On a lot of boards it makes sense to power down the regulators when going to sleep etc and sometimes even during runtime. To do that we have to make the device aware of its regulators (including the reference one if present).

Linus Waleij is someone who does this stuff right in his drivers, so take a look at one of those.

Personally I've always counted this as a feature. If it's not there then on boards where that powersupply is turned off the device won't work, but there are plenty of boards with out fined grained enough control where it doesn't matter. If it's initially on adding this support improves power saving. Nice to have again, but not a requirement for a driver to 'work'.

Jonathan

Quoted 8 lines

Thanks,
alisons
--
To unsubscribe from this list: send the line "unsubscribe linux-iio" in the body of a message to [email protected]
More majordomo info at http://vger.kernel.org/majordomo-info.html