1 // SPDX-License-Identifier: GPL-2.0-only
3 * ltc2497.c - Driver for Analog Devices/Linear Technology LTC2497 ADC
5 * Copyright (C) 2017 Analog Devices Inc.
7 * Datasheet: http://cds.linear.com/docs/en/datasheet/2497fd.pdf
10 #include <linux/i2c.h>
11 #include <linux/iio/iio.h>
12 #include <linux/iio/driver.h>
13 #include <linux/module.h>
14 #include <linux/mod_devicetable.h>
15 #include <linux/property.h>
17 #include <linux/unaligned.h>
21 enum ltc2497_chip_type
{
26 struct ltc2497_driverdata
{
27 /* this must be the first member */
28 struct ltc2497core_driverdata common_ddata
;
29 struct i2c_client
*client
;
32 * DMA (thus cache coherency maintenance) may require the
33 * transfer buffers to live in their own cache lines.
38 } data
__aligned(IIO_DMA_MINALIGN
);
41 static int ltc2497_result_and_measure(struct ltc2497core_driverdata
*ddata
,
44 struct ltc2497_driverdata
*st
=
45 container_of(ddata
, struct ltc2497_driverdata
, common_ddata
);
49 if (st
->recv_size
== 3)
50 ret
= i2c_master_recv(st
->client
, (char *)&st
->data
.d8
,
53 ret
= i2c_master_recv(st
->client
, (char *)&st
->data
.d32
,
56 dev_err(&st
->client
->dev
, "i2c_master_recv failed\n");
61 * The data format is 16/24 bit 2s complement, but with an upper sign bit on the
62 * resolution + 1 position, which is set for positive values only. Given this
63 * bit's value, subtracting BIT(resolution + 1) from the ADC's result is
64 * equivalent to a sign extension.
66 if (st
->recv_size
== 3) {
67 *val
= (get_unaligned_be24(st
->data
.d8
) >> 6)
68 - BIT(ddata
->chip_info
->resolution
+ 1);
70 *val
= (be32_to_cpu(st
->data
.d32
) >> 6)
71 - BIT(ddata
->chip_info
->resolution
+ 1);
75 * The part started a new conversion at the end of the above i2c
76 * transfer, so if the address didn't change since the last call
77 * everything is fine and we can return early.
78 * If not (which should only happen when some sort of bulk
79 * conversion is implemented) we have to program the new
80 * address. Note that this probably fails as the conversion that
81 * was triggered above is like not complete yet and the two
82 * operations have to be done in a single transfer.
84 if (ddata
->addr_prev
== address
)
88 ret
= i2c_smbus_write_byte(st
->client
,
89 LTC2497_ENABLE
| address
);
91 dev_err(&st
->client
->dev
, "i2c transfer failed: %pe\n",
96 static int ltc2497_probe(struct i2c_client
*client
)
98 const struct ltc2497_chip_info
*chip_info
;
99 struct iio_dev
*indio_dev
;
100 struct ltc2497_driverdata
*st
;
101 struct device
*dev
= &client
->dev
;
104 if (!i2c_check_functionality(client
->adapter
, I2C_FUNC_I2C
|
105 I2C_FUNC_SMBUS_WRITE_BYTE
))
108 indio_dev
= devm_iio_device_alloc(dev
, sizeof(*st
));
112 st
= iio_priv(indio_dev
);
113 i2c_set_clientdata(client
, indio_dev
);
115 st
->common_ddata
.result_and_measure
= ltc2497_result_and_measure
;
117 chip_info
= i2c_get_match_data(client
);
118 st
->common_ddata
.chip_info
= chip_info
;
120 resolution
= chip_info
->resolution
;
121 st
->recv_size
= BITS_TO_BYTES(resolution
) + 1;
123 return ltc2497core_probe(dev
, indio_dev
);
126 static void ltc2497_remove(struct i2c_client
*client
)
128 struct iio_dev
*indio_dev
= i2c_get_clientdata(client
);
130 ltc2497core_remove(indio_dev
);
133 static const struct ltc2497_chip_info ltc2497_info
[] = {
144 static const struct i2c_device_id ltc2497_id
[] = {
145 { "ltc2497", (kernel_ulong_t
)<c2497_info
[TYPE_LTC2497
] },
146 { "ltc2499", (kernel_ulong_t
)<c2497_info
[TYPE_LTC2499
] },
149 MODULE_DEVICE_TABLE(i2c
, ltc2497_id
);
151 static const struct of_device_id ltc2497_of_match
[] = {
152 { .compatible
= "lltc,ltc2497", .data
= <c2497_info
[TYPE_LTC2497
] },
153 { .compatible
= "lltc,ltc2499", .data
= <c2497_info
[TYPE_LTC2499
] },
156 MODULE_DEVICE_TABLE(of
, ltc2497_of_match
);
158 static struct i2c_driver ltc2497_driver
= {
161 .of_match_table
= ltc2497_of_match
,
163 .probe
= ltc2497_probe
,
164 .remove
= ltc2497_remove
,
165 .id_table
= ltc2497_id
,
167 module_i2c_driver(ltc2497_driver
);
169 MODULE_AUTHOR("Michael Hennerich <michael.hennerich@analog.com>");
170 MODULE_DESCRIPTION("Linear Technology LTC2497 ADC driver");
171 MODULE_LICENSE("GPL v2");