2022-08-22 12:58:57

by Ciprian Regus

[permalink] [raw]
Subject: [PATCH 2/3] drivers: iio: adc: LTC2499 support

The LTC2499 is a 16-channel (eight differential), 24-bit,
ADC with Easy Drive technology and a 2-wire, I2C interface.

Implement support for the LTC2499 ADC by extending the LTC2497
driver. A new chip_info struct is added to differentiate between
chip types and resolutions when reading data from the device.

Datasheet: https://www.analog.com/media/en/technical-documentation/data-sheets/2499fe.pdf

Signed-off-by: Ciprian Regus <[email protected]>
---
drivers/iio/adc/ltc2496.c | 8 +++++++-
drivers/iio/adc/ltc2497-core.c | 2 +-
drivers/iio/adc/ltc2497.c | 34 +++++++++++++++++++++++++++++-----
drivers/iio/adc/ltc2497.h | 13 ++++++++++++-
4 files changed, 49 insertions(+), 8 deletions(-)

diff --git a/drivers/iio/adc/ltc2496.c b/drivers/iio/adc/ltc2496.c
index dfb3bb5997e5..98338104c24a 100644
--- a/drivers/iio/adc/ltc2496.c
+++ b/drivers/iio/adc/ltc2496.c
@@ -14,6 +14,7 @@
#include <linux/iio/iio.h>
#include <linux/iio/driver.h>
#include <linux/module.h>
+#include <linux/property.h>
#include <linux/mod_devicetable.h>

#include "ltc2497.h"
@@ -74,6 +75,7 @@ static int ltc2496_probe(struct spi_device *spi)
spi_set_drvdata(spi, indio_dev);
st->spi = spi;
st->common_ddata.result_and_measure = ltc2496_result_and_measure;
+ st->common_ddata.chip_info = device_get_match_data(dev);

return ltc2497core_probe(dev, indio_dev);
}
@@ -85,8 +87,12 @@ static void ltc2496_remove(struct spi_device *spi)
ltc2497core_remove(indio_dev);
}

+static struct chip_info ltc2496_info = {
+ .resolution = 16,
+};
+
static const struct of_device_id ltc2496_of_match[] = {
- { .compatible = "lltc,ltc2496", },
+ { .compatible = "lltc,ltc2496", .data = (void *)&ltc2496_info },
{},
};
MODULE_DEVICE_TABLE(of, ltc2496_of_match);
diff --git a/drivers/iio/adc/ltc2497-core.c b/drivers/iio/adc/ltc2497-core.c
index 2a485c8a1940..b2752399402c 100644
--- a/drivers/iio/adc/ltc2497-core.c
+++ b/drivers/iio/adc/ltc2497-core.c
@@ -95,7 +95,7 @@ static int ltc2497core_read_raw(struct iio_dev *indio_dev,
return ret;

*val = ret / 1000;
- *val2 = 17;
+ *val2 = ddata->chip_info->resolution + 1;

return IIO_VAL_FRACTIONAL_LOG2;

diff --git a/drivers/iio/adc/ltc2497.c b/drivers/iio/adc/ltc2497.c
index f7c786f37ceb..bb5e0d4301e2 100644
--- a/drivers/iio/adc/ltc2497.c
+++ b/drivers/iio/adc/ltc2497.c
@@ -7,10 +7,14 @@
* Datasheet: http://cds.linear.com/docs/en/datasheet/2497fd.pdf
*/

+#include <linux/bitfield.h>
+#include <linux/bitops.h>
+
#include <linux/i2c.h>
#include <linux/iio/iio.h>
#include <linux/iio/driver.h>
#include <linux/module.h>
+#include <linux/property.h>
#include <linux/mod_devicetable.h>

#include "ltc2497.h"
@@ -19,6 +23,8 @@ struct ltc2497_driverdata {
/* this must be the first member */
struct ltc2497core_driverdata common_ddata;
struct i2c_client *client;
+ u32 recv_size;
+ u32 sub_lsb;
/*
* DMA (thus cache coherency maintenance) may require the
* transfer buffers to live in their own cache lines.
@@ -34,13 +40,14 @@ static int ltc2497_result_and_measure(struct ltc2497core_driverdata *ddata,
int ret;

if (val) {
- ret = i2c_master_recv(st->client, (char *)&st->buf, 3);
+ ret = i2c_master_recv(st->client, (char *)&st->buf, st->recv_size);
if (ret < 0) {
dev_err(&st->client->dev, "i2c_master_recv failed\n");
return ret;
}

- *val = (be32_to_cpu(st->buf) >> 14) - (1 << 17);
+ *val = (be32_to_cpu(st->buf) >> st->sub_lsb) -
+ BIT(ddata->chip_info->resolution + 1);
}

ret = i2c_smbus_write_byte(st->client,
@@ -54,6 +61,7 @@ static int ltc2497_result_and_measure(struct ltc2497core_driverdata *ddata,
static int ltc2497_probe(struct i2c_client *client,
const struct i2c_device_id *id)
{
+ u32 resolution;
struct iio_dev *indio_dev;
struct ltc2497_driverdata *st;
struct device *dev = &client->dev;
@@ -70,6 +78,11 @@ static int ltc2497_probe(struct i2c_client *client,
i2c_set_clientdata(client, indio_dev);
st->client = client;
st->common_ddata.result_and_measure = ltc2497_result_and_measure;
+ st->common_ddata.chip_info = device_get_match_data(dev);
+
+ resolution = st->common_ddata.chip_info->resolution;
+ st->sub_lsb = 31 - (resolution + 1);
+ st->recv_size = resolution / BITS_PER_BYTE + 1;

return ltc2497core_probe(dev, indio_dev);
}
@@ -83,15 +96,26 @@ static int ltc2497_remove(struct i2c_client *client)
return 0;
}

+static struct chip_info ltc2497_info[] = {
+ [TYPE_LTC2497] = {
+ .resolution = 16,
+ },
+ [TYPE_LTC2499] = {
+ .resolution = 24,
+ }
+};
+
static const struct i2c_device_id ltc2497_id[] = {
- { "ltc2497", 0 },
+ { "ltc2497", TYPE_LTC2497 },
+ { "ltc2499", TYPE_LTC2499 },
{ }
};
MODULE_DEVICE_TABLE(i2c, ltc2497_id);

static const struct of_device_id ltc2497_of_match[] = {
- { .compatible = "lltc,ltc2497", },
- {},
+ { .compatible = "lltc,ltc2497", .data = (void *)&ltc2497_info[TYPE_LTC2497] },
+ { .compatible = "lltc,ltc2499", .data = (void *)&ltc2497_info[TYPE_LTC2499] },
+ {}
};
MODULE_DEVICE_TABLE(of, ltc2497_of_match);

diff --git a/drivers/iio/adc/ltc2497.h b/drivers/iio/adc/ltc2497.h
index d0b42dd6b8ad..f4d939cfd48b 100644
--- a/drivers/iio/adc/ltc2497.h
+++ b/drivers/iio/adc/ltc2497.h
@@ -4,9 +4,20 @@
#define LTC2497_CONFIG_DEFAULT LTC2497_ENABLE
#define LTC2497_CONVERSION_TIME_MS 150ULL

+enum chip_type {
+ TYPE_LTC2496,
+ TYPE_LTC2497,
+ TYPE_LTC2499
+};
+
+struct chip_info {
+ u32 resolution;
+};
+
struct ltc2497core_driverdata {
struct regulator *ref;
- ktime_t time_prev;
+ ktime_t time_prev;
+ const struct chip_info *chip_info;
u8 addr_prev;
int (*result_and_measure)(struct ltc2497core_driverdata *ddata,
u8 address, int *val);
--
2.30.2


2022-08-22 20:34:46

by Jonathan Cameron

[permalink] [raw]
Subject: Re: [PATCH 2/3] drivers: iio: adc: LTC2499 support

On Mon, 22 Aug 2022 15:51:05 +0300
Ciprian Regus <[email protected]> wrote:

> The LTC2499 is a 16-channel (eight differential), 24-bit,
> ADC with Easy Drive technology and a 2-wire, I2C interface.
>
> Implement support for the LTC2499 ADC by extending the LTC2497
> driver. A new chip_info struct is added to differentiate between
> chip types and resolutions when reading data from the device.
>
> Datasheet: https://www.analog.com/media/en/technical-documentation/data-sheets/2499fe.pdf
>
> Signed-off-by: Ciprian Regus <[email protected]>
Hi Ciprian,

Various comments inline.

Thanks,

Jonathan

> ---
> drivers/iio/adc/ltc2496.c | 8 +++++++-
> drivers/iio/adc/ltc2497-core.c | 2 +-
> drivers/iio/adc/ltc2497.c | 34 +++++++++++++++++++++++++++++-----
> drivers/iio/adc/ltc2497.h | 13 ++++++++++++-
> 4 files changed, 49 insertions(+), 8 deletions(-)
>
> diff --git a/drivers/iio/adc/ltc2496.c b/drivers/iio/adc/ltc2496.c
> index dfb3bb5997e5..98338104c24a 100644
> --- a/drivers/iio/adc/ltc2496.c
> +++ b/drivers/iio/adc/ltc2496.c
> @@ -14,6 +14,7 @@
> #include <linux/iio/iio.h>
> #include <linux/iio/driver.h>
> #include <linux/module.h>
> +#include <linux/property.h>
why?

> #include <linux/mod_devicetable.h>
>
> #include "ltc2497.h"
> @@ -74,6 +75,7 @@ static int ltc2496_probe(struct spi_device *spi)
> spi_set_drvdata(spi, indio_dev);
> st->spi = spi;
> st->common_ddata.result_and_measure = ltc2496_result_and_measure;
> + st->common_ddata.chip_info = device_get_match_data(dev);
>
> return ltc2497core_probe(dev, indio_dev);
> }
> @@ -85,8 +87,12 @@ static void ltc2496_remove(struct spi_device *spi)
> ltc2497core_remove(indio_dev);
> }
>
> +static struct chip_info ltc2496_info = {
> + .resolution = 16,
> +};
> +
> static const struct of_device_id ltc2496_of_match[] = {
> - { .compatible = "lltc,ltc2496", },
> + { .compatible = "lltc,ltc2496", .data = (void *)&ltc2496_info },

as below. Take the chip_info structure const and drop the cast.

> {},
> };
> MODULE_DEVICE_TABLE(of, ltc2496_of_match);
> diff --git a/drivers/iio/adc/ltc2497-core.c b/drivers/iio/adc/ltc2497-core.c
> index 2a485c8a1940..b2752399402c 100644
> --- a/drivers/iio/adc/ltc2497-core.c
> +++ b/drivers/iio/adc/ltc2497-core.c
> @@ -95,7 +95,7 @@ static int ltc2497core_read_raw(struct iio_dev *indio_dev,
> return ret;
>
> *val = ret / 1000;
> - *val2 = 17;
> + *val2 = ddata->chip_info->resolution + 1;
>
> return IIO_VAL_FRACTIONAL_LOG2;
>
> diff --git a/drivers/iio/adc/ltc2497.c b/drivers/iio/adc/ltc2497.c
> index f7c786f37ceb..bb5e0d4301e2 100644
> --- a/drivers/iio/adc/ltc2497.c
> +++ b/drivers/iio/adc/ltc2497.c
> @@ -7,10 +7,14 @@
> * Datasheet: http://cds.linear.com/docs/en/datasheet/2497fd.pdf
> */
>
> +#include <linux/bitfield.h>
> +#include <linux/bitops.h>

Not immediately obvious why these need adding as part of this patch.
If just general include improvement, separate patch please.

> +
Why blank line?
> #include <linux/i2c.h>
> #include <linux/iio/iio.h>
> #include <linux/iio/driver.h>
> #include <linux/module.h>
> +#include <linux/property.h>

May make sense, but not obvious why it's in this patch.
If it's missing and should be present, please do it in a separate patch.

> #include <linux/mod_devicetable.h>
>
> #include "ltc2497.h"
> @@ -19,6 +23,8 @@ struct ltc2497_driverdata {
> /* this must be the first member */
> struct ltc2497core_driverdata common_ddata;
> struct i2c_client *client;
> + u32 recv_size;
> + u32 sub_lsb;

> /*
> * DMA (thus cache coherency maintenance) may require the
> * transfer buffers to live in their own cache lines.
> @@ -34,13 +40,14 @@ static int ltc2497_result_and_measure(struct ltc2497core_driverdata *ddata,
> int ret;
>
> if (val) {
> - ret = i2c_master_recv(st->client, (char *)&st->buf, 3);
> + ret = i2c_master_recv(st->client, (char *)&st->buf, st->recv_size);
Not helpful yet, but there was a patch series under review form Jason Gerecke that
changed the i2c transfer commands to use a u8.

Which raises a question. buf is a __be32 which is rather odd given size of 3 in original
code. If we have a case where it needs to have separate types for different transfers, use
a union.

> if (ret < 0) {
> dev_err(&st->client->dev, "i2c_master_recv failed\n");
> return ret;
> }
>
> - *val = (be32_to_cpu(st->buf) >> 14) - (1 << 17);

Old code here is less than ideal, should be reading into 3 bytes then using
the be24 accesors. Please fix whilst here. You will need multiple paths here
depending on size.

> + *val = (be32_to_cpu(st->buf) >> st->sub_lsb) -
> + BIT(ddata->chip_info->resolution + 1);
> }
>
> ret = i2c_smbus_write_byte(st->client,
> @@ -54,6 +61,7 @@ static int ltc2497_result_and_measure(struct ltc2497core_driverdata *ddata,
> static int ltc2497_probe(struct i2c_client *client,
> const struct i2c_device_id *id)
> {
> + u32 resolution;
> struct iio_dev *indio_dev;
> struct ltc2497_driverdata *st;
> struct device *dev = &client->dev;
> @@ -70,6 +78,11 @@ static int ltc2497_probe(struct i2c_client *client,
> i2c_set_clientdata(client, indio_dev);
> st->client = client;
> st->common_ddata.result_and_measure = ltc2497_result_and_measure;
> + st->common_ddata.chip_info = device_get_match_data(dev);
> +
> + resolution = st->common_ddata.chip_info->resolution;
> + st->sub_lsb = 31 - (resolution + 1);
> + st->recv_size = resolution / BITS_PER_BYTE + 1;
>
> return ltc2497core_probe(dev, indio_dev);
> }
> @@ -83,15 +96,26 @@ static int ltc2497_remove(struct i2c_client *client)
> return 0;
> }
>
> +static struct chip_info ltc2497_info[] = {

Should be const - which is why you need the cast below.

> + [TYPE_LTC2497] = {
> + .resolution = 16,
> + },
> + [TYPE_LTC2499] = {
> + .resolution = 24,
> + }
> +};
> +
> static const struct i2c_device_id ltc2497_id[] = {
> - { "ltc2497", 0 },
> + { "ltc2497", TYPE_LTC2497 },
> + { "ltc2499", TYPE_LTC2499 },
> { }
> };
> MODULE_DEVICE_TABLE(i2c, ltc2497_id);
>
> static const struct of_device_id ltc2497_of_match[] = {
> - { .compatible = "lltc,ltc2497", },
> - {},
> + { .compatible = "lltc,ltc2497", .data = (void *)&ltc2497_info[TYPE_LTC2497] },
> + { .compatible = "lltc,ltc2499", .data = (void *)&ltc2497_info[TYPE_LTC2499] },
Cast is a bad sign. Reason above.

> + {}
> };
> MODULE_DEVICE_TABLE(of, ltc2497_of_match);
>
> diff --git a/drivers/iio/adc/ltc2497.h b/drivers/iio/adc/ltc2497.h
> index d0b42dd6b8ad..f4d939cfd48b 100644
> --- a/drivers/iio/adc/ltc2497.h
> +++ b/drivers/iio/adc/ltc2497.h
> @@ -4,9 +4,20 @@
> #define LTC2497_CONFIG_DEFAULT LTC2497_ENABLE
> #define LTC2497_CONVERSION_TIME_MS 150ULL
>
> +enum chip_type {
> + TYPE_LTC2496,
> + TYPE_LTC2497,
> + TYPE_LTC2499
> +};
> +
> +struct chip_info {
> + u32 resolution;
> +};
> +
> struct ltc2497core_driverdata {
> struct regulator *ref;
> - ktime_t time_prev;
> + ktime_t time_prev;
I'm staring at this and can't see the difference between the two lines.
Closer inspection (i.e. messing with the stuff around it) tells me line
you are removing has a tab when should be a space. Whilst trivial please
call that out in patch description (or do it as a separate patch).

> + const struct chip_info *chip_info;
> u8 addr_prev;
> int (*result_and_measure)(struct ltc2497core_driverdata *ddata,
> u8 address, int *val);

2022-08-23 18:05:21

by Andy Shevchenko

[permalink] [raw]
Subject: Re: [PATCH 2/3] drivers: iio: adc: LTC2499 support

On Mon, Aug 22, 2022 at 11:13 PM Jonathan Cameron <[email protected]> wrote:
> On Mon, 22 Aug 2022 15:51:05 +0300
> Ciprian Regus <[email protected]> wrote:

In reply to Jonathan's comments to answer his question and add more
comments from me.

...

> > Datasheet: https://www.analog.com/media/en/technical-documentation/data-sheets/2499fe.pdf
> >
> > Signed-off-by: Ciprian Regus <[email protected]>

Tag block mustn't have the blank line(s).

...

> > #include <linux/iio/iio.h>
> > #include <linux/iio/driver.h>
> > #include <linux/module.h>
> > +#include <linux/property.h>
> why?

device_get_match_data() requires it.

But why not sort them?

> > #include <linux/mod_devicetable.h>

...

> > - *val = (be32_to_cpu(st->buf) >> 14) - (1 << 17);
>
> Old code here is less than ideal, should be reading into 3 bytes then using
> the be24 accesors. Please fix whilst here. You will need multiple paths here
> depending on size.
>
> > + *val = (be32_to_cpu(st->buf) >> st->sub_lsb) -
> > + BIT(ddata->chip_info->resolution + 1);

Shouldn't this use some kind of sign_extend()?

Also with a temporary variable for chip info this line can be single.

struct ... *ci = ddata->chip_info;

...BIT(ci->resolution + 1)

...

> > + u32 resolution;

Keep this in a way that the "longer lines go first".

...

> > + resolution = st->common_ddata.chip_info->resolution;
> > + st->sub_lsb = 31 - (resolution + 1);
> > + st->recv_size = resolution / BITS_PER_BYTE + 1;

BITS_TO_BYTES()

...

> > static const struct i2c_device_id ltc2497_id[] = {
> > - { "ltc2497", 0 },
> > + { "ltc2497", TYPE_LTC2497 },
> > + { "ltc2499", TYPE_LTC2499 },

Use pointers here like you have done for the OF table.

> > { }
> > };

...

> > +enum chip_type {
> > + TYPE_LTC2496,
> > + TYPE_LTC2497,
> > + TYPE_LTC2499

Keep trailing comma.

> > +};

--
With Best Regards,
Andy Shevchenko

2022-08-29 06:56:00

by Ciprian Regus

[permalink] [raw]
Subject: RE: [PATCH 2/3] drivers: iio: adc: LTC2499 support

In reply to one of Andy's questions.

> On Mon, Aug 22, 2022 at 11:13 PM Jonathan Cameron <[email protected]>
> wrote:
> > On Mon, 22 Aug 2022 15:51:05 +0300
> > Ciprian Regus <[email protected]> wrote:
>
> In reply to Jonathan's comments to answer his question and add more
> comments from me.
>
> ...
>
> > > Datasheet: https://www.analog.com/media/en/technical-
> documentation/data-sheets/2499fe.pdf
> > >
> > > Signed-off-by: Ciprian Regus <[email protected]>
>
> Tag block mustn't have the blank line(s).
>
> ...
>
> > > #include <linux/iio/iio.h>
> > > #include <linux/iio/driver.h>
> > > #include <linux/module.h>
> > > +#include <linux/property.h>
> > why?
>
> device_get_match_data() requires it.
>
> But why not sort them?
>
> > > #include <linux/mod_devicetable.h>
>
> ...
>
> > > - *val = (be32_to_cpu(st->buf) >> 14) - (1 << 17);
> >
> > Old code here is less than ideal, should be reading into 3 bytes then using
> > the be24 accesors. Please fix whilst here. You will need multiple paths here
> > depending on size.
> >
> > > + *val = (be32_to_cpu(st->buf) >> st->sub_lsb) -
> > > + BIT(ddata->chip_info->resolution + 1);
>
> Shouldn't this use some kind of sign_extend()?
The BIT(ddata->chip_info->resolution + 1) subtraction part is already doing the sign extension,
since that bit (which is the most significant one) will be 0 if the result is < 0, and 1 otherwise.

Regards,
Ciprian
>
> Also with a temporary variable for chip info this line can be single.
>
> struct ... *ci = ddata->chip_info;
>
> ...BIT(ci->resolution + 1)
>
> ...
>
> > > + u32 resolution;
>
> Keep this in a way that the "longer lines go first".
>
> ...
>
> > > + resolution = st->common_ddata.chip_info->resolution;
> > > + st->sub_lsb = 31 - (resolution + 1);
> > > + st->recv_size = resolution / BITS_PER_BYTE + 1;
>
> BITS_TO_BYTES()
>
> ...
>
> > > static const struct i2c_device_id ltc2497_id[] = {
> > > - { "ltc2497", 0 },
> > > + { "ltc2497", TYPE_LTC2497 },
> > > + { "ltc2499", TYPE_LTC2499 },
>
> Use pointers here like you have done for the OF table.
>
> > > { }
> > > };
>
> ...
>
> > > +enum chip_type {
> > > + TYPE_LTC2496,
> > > + TYPE_LTC2497,
> > > + TYPE_LTC2499
>
> Keep trailing comma.
>
> > > +};
>
> --
> With Best Regards,
> Andy Shevchenko

2022-08-29 17:47:39

by Jonathan Cameron

[permalink] [raw]
Subject: Re: [PATCH 2/3] drivers: iio: adc: LTC2499 support

On Mon, 29 Aug 2022 06:30:52 +0000
"Regus, Ciprian" <[email protected]> wrote:

> In reply to one of Andy's questions.
>
> > On Mon, Aug 22, 2022 at 11:13 PM Jonathan Cameron <[email protected]>
> > wrote:
> > > On Mon, 22 Aug 2022 15:51:05 +0300
> > > Ciprian Regus <[email protected]> wrote:
> >
> > In reply to Jonathan's comments to answer his question and add more
> > comments from me.
> >
> > ...
> >
> > > > Datasheet: https://www.analog.com/media/en/technical-
> > documentation/data-sheets/2499fe.pdf
> > > >
> > > > Signed-off-by: Ciprian Regus <[email protected]>
> >
> > Tag block mustn't have the blank line(s).
> >
> > ...
> >
> > > > #include <linux/iio/iio.h>
> > > > #include <linux/iio/driver.h>
> > > > #include <linux/module.h>
> > > > +#include <linux/property.h>
> > > why?
> >
> > device_get_match_data() requires it.
> >
> > But why not sort them?
> >
> > > > #include <linux/mod_devicetable.h>
> >
> > ...
> >
> > > > - *val = (be32_to_cpu(st->buf) >> 14) - (1 << 17);
> > >
> > > Old code here is less than ideal, should be reading into 3 bytes then using
> > > the be24 accesors. Please fix whilst here. You will need multiple paths here
> > > depending on size.
> > >
> > > > + *val = (be32_to_cpu(st->buf) >> st->sub_lsb) -
> > > > + BIT(ddata->chip_info->resolution + 1);
> >
> > Shouldn't this use some kind of sign_extend()?
> The BIT(ddata->chip_info->resolution + 1) subtraction part is already doing the sign extension,
> since that bit (which is the most significant one) will be 0 if the result is < 0, and 1 otherwise.

This wins the award for one of the strangest formats I've yet seen.
The format is normal 2s complement 24 bit, but with a bonus upper bit to allow representation of
ever so slightly more than 24 bits. Specifically on the postive side the out of range value.
0x7fffff + 1 = 0x800000 (which would normally be considered wrapped around to most negative value.

and on the negative side as well
0x800000 - 1 = 0x7fffff (normally most positive value).
It does this by throwing in an additional bit for sign which only tells us something useful
if in these two edge conditions (which are really an out of range error).
That bit corresponds int his case to
0x1000000 and is set for postive values only.

Thus our VS+ value becomes 0x01800000
and VS- value becomes 0x007fffff
(extended to 32 bits for reasons that will become clear)
Applying 2's complement subtraction of the magic value above.

0x01800000 - 0x01000000 = 0x00800000 (2^23)
0x007fffff - 0x01000000 = 0xff7fffff (-(2^23 + 1))

So it is indeed sign extended by the above.

Perhaps a few comments to set people off along the right path to what is
going on here would be useful?

Jonathan


>
> Regards,
> Ciprian
> >
> > Also with a temporary variable for chip info this line can be single.
> >
> > struct ... *ci = ddata->chip_info;
> >
> > ...BIT(ci->resolution + 1)
> >
> > ...
> >
> > > > + u32 resolution;
> >
> > Keep this in a way that the "longer lines go first".
> >
> > ...
> >
> > > > + resolution = st->common_ddata.chip_info->resolution;
> > > > + st->sub_lsb = 31 - (resolution + 1);
> > > > + st->recv_size = resolution / BITS_PER_BYTE + 1;
> >
> > BITS_TO_BYTES()
> >
> > ...
> >
> > > > static const struct i2c_device_id ltc2497_id[] = {
> > > > - { "ltc2497", 0 },
> > > > + { "ltc2497", TYPE_LTC2497 },
> > > > + { "ltc2499", TYPE_LTC2499 },
> >
> > Use pointers here like you have done for the OF table.
> >
> > > > { }
> > > > };
> >
> > ...
> >
> > > > +enum chip_type {
> > > > + TYPE_LTC2496,
> > > > + TYPE_LTC2497,
> > > > + TYPE_LTC2499
> >
> > Keep trailing comma.
> >
> > > > +};
> >
> > --
> > With Best Regards,
> > Andy Shevchenko