Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -4,13 +4,19 @@
$id: http://devicetree.org/schemas/iio/adc/lltc,ltc2497.yaml#
$schema: http://devicetree.org/meta-schemas/core.yaml#

title: Linear Technology / Analog Devices LTC2497 and LTC2309 ADC
title: Linear Technology / Analog Devices LTC2497 and similar ADCs

maintainers:
- Michael Hennerich <michael.hennerich@analog.com>
- Liam Beguin <liambeguin@gmail.com>

description: |
LTC2305:
low noise, low power, 2-channel, 12-bit successive approximation ADC with an
I2C compatible serial interface.

https://www.analog.com/media/en/technical-documentation/data-sheets/2305fa.pdf

LTC2309:
low noise, low power, 8-channel, 12-bit successive approximation ADC with an
I2C compatible serial interface.
Expand All @@ -28,6 +34,7 @@ description: |
properties:
compatible:
enum:
- lltc,ltc2305
- lltc,ltc2309
- lltc,ltc2497
- lltc,ltc2499
Expand Down
6 changes: 3 additions & 3 deletions drivers/iio/adc/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -1021,11 +1021,11 @@ config LTC2308
be called ltc2308.

config LTC2309
tristate "Linear Technology LTC2309 ADC driver"
tristate "Linear Technology LTC2309 and similar ADC driver"
depends on I2C
help
Say yes here to build support for Linear Technology LTC2309, a low
noise, low power, 8-channel, 12-bit SAR ADC
Say yes here to build support for Linear Technology LTC2309 and
similar low noise, low power SAR ADCs.

This driver can also be built as a module. If so, the module will
be called ltc2309.
Expand Down
45 changes: 40 additions & 5 deletions drivers/iio/adc/ltc2309.c
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
* Copyright (c) 2023, Liam Beguin <liambeguin@gmail.com>
*/
#include <linux/bitfield.h>
#include <linux/delay.h>
#include <linux/i2c.h>
#include <linux/iio/iio.h>
#include <linux/kernel.h>
Expand All @@ -26,18 +27,26 @@
#define LTC2309_DIN_UNI BIT(3)
#define LTC2309_DIN_SLEEP BIT(2)

struct ltc2309_chip_info {
const struct iio_chan_spec *channels;
unsigned int num_channels;
unsigned int read_delay_us;
};

/**
* struct ltc2309 - internal device data structure
* @dev: Device reference
* @client: I2C reference
* @lock: Lock to serialize data access
* @vref_mv: Internal voltage reference
* @chip_info: Chip-specific configuration data
*/
struct ltc2309 {
struct device *dev;
struct i2c_client *client;
struct mutex lock; /* serialize data access */
int vref_mv;
const struct ltc2309_chip_info *chip_info;
};

/* Order matches expected channel address, See datasheet Table 1. */
Expand Down Expand Up @@ -99,6 +108,13 @@ static const struct iio_chan_spec ltc2309_channels[] = {
LTC2309_DIFF_CHAN(7, 6, LTC2309_CH7_CH6),
};

static const struct iio_chan_spec ltc2305_channels[] = {
LTC2309_CHAN(0, LTC2309_CH0),
LTC2309_CHAN(1, LTC2309_CH1),
LTC2309_DIFF_CHAN(0, 1, LTC2309_CH0_CH1),
LTC2309_DIFF_CHAN(1, 0, LTC2309_CH1_CH0),
};

static int ltc2309_read_raw_channel(struct ltc2309 *ltc2309,
unsigned long address, int *val)
{
Expand All @@ -117,6 +133,10 @@ static int ltc2309_read_raw_channel(struct ltc2309 *ltc2309,
return ret;
}

if (ltc2309->chip_info->read_delay_us)
usleep_range(ltc2309->chip_info->read_delay_us,
ltc2309->chip_info->read_delay_us * 2);

ret = i2c_master_recv(ltc2309->client, (char *)&buf, 2);
if (ret < 0) {
dev_err(ltc2309->dev, "i2c read failed: %pe\n", ERR_PTR(ret));
Expand Down Expand Up @@ -156,6 +176,18 @@ static const struct iio_info ltc2309_info = {
.read_raw = ltc2309_read_raw,
};

static const struct ltc2309_chip_info ltc2309_chip_info = {
.channels = ltc2309_channels,
.num_channels = ARRAY_SIZE(ltc2309_channels),
.read_delay_us = 0,
};

static const struct ltc2309_chip_info ltc2305_chip_info = {
.channels = ltc2305_channels,
.num_channels = ARRAY_SIZE(ltc2305_channels),
.read_delay_us = 2,
};
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Preferred way in IIO is to have a variable per chip. Not an array. Also adding the chip_info struct could (and should) be a preparatory patch.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Noted and thanks. Added the preparatory patch and separated the array into their own variables.


static int ltc2309_probe(struct i2c_client *client)
{
struct iio_dev *indio_dev;
Expand All @@ -169,11 +201,12 @@ static int ltc2309_probe(struct i2c_client *client)
ltc2309 = iio_priv(indio_dev);
ltc2309->dev = &indio_dev->dev;
ltc2309->client = client;
ltc2309->chip_info = i2c_get_match_data(client);

indio_dev->name = "ltc2309";
indio_dev->modes = INDIO_DIRECT_MODE;
indio_dev->channels = ltc2309_channels;
indio_dev->num_channels = ARRAY_SIZE(ltc2309_channels);
indio_dev->channels = ltc2309->chip_info->channels;
indio_dev->num_channels = ltc2309->chip_info->num_channels;
indio_dev->info = &ltc2309_info;

ret = devm_regulator_get_enable_read_voltage(&client->dev, "vref");
Expand All @@ -189,13 +222,15 @@ static int ltc2309_probe(struct i2c_client *client)
}

static const struct of_device_id ltc2309_of_match[] = {
{ .compatible = "lltc,ltc2309" },
{ .compatible = "lltc,ltc2309", .data = &ltc2309_chip_info },
{ .compatible = "lltc,ltc2305", .data = &ltc2305_chip_info },
{ }
};
MODULE_DEVICE_TABLE(of, ltc2309_of_match);

static const struct i2c_device_id ltc2309_id[] = {
{ "ltc2309" },
{ "ltc2309", (kernel_ulong_t)&ltc2309_chip_info },
{ "ltc2305", (kernel_ulong_t)&ltc2305_chip_info },
{ }
};
MODULE_DEVICE_TABLE(i2c, ltc2309_id);
Expand All @@ -211,5 +246,5 @@ static struct i2c_driver ltc2309_driver = {
module_i2c_driver(ltc2309_driver);

MODULE_AUTHOR("Liam Beguin <liambeguin@gmail.com>");
MODULE_DESCRIPTION("Linear Technology LTC2309 ADC");
MODULE_DESCRIPTION("Linear Technology LTC2309 and similar ADC driver");
MODULE_LICENSE("GPL v2");
Loading