On Mon, 15 Aug 2022 09:16:47 +0000 Denys Zagorui <dzagorui@xxxxxxxxx> wrote: > From: Uwe Kleine-König <u.kleine-koenig@xxxxxxxxxxxxxx> > > After the result of the previous conversion is read the chip > automatically starts a new conversion and doesn't accept new i2c > transfers until this conversion is completed which makes the function > return failure. That's rather nasty. Could we add a cheeky sleep in the other path to ensure there is always time for the conversion to be done? Not ideal, but might ensure there isn't a known problem path without introducing much complexity. > > So add an early return iff the programming of the new address isn't > needed. Note this will not fix the problem in general, but all cases > that are currently used. Once this changes we get the failure back, but > this can be addressed when the need arises. > > Fixes: 69548b7c2c4f ("iio: adc: ltc2497: split protocol independent part in a separate module ") > Reported-by: Meng Li <Meng.Li@xxxxxxxxxxxxx> > Signed-off-by: Uwe Kleine-König <u.kleine-koenig@xxxxxxxxxxxxxx> > Tested-by: Denys Zagorui <dzagorui@xxxxxxxxx> > --- > drivers/iio/adc/ltc2497.c | 13 +++++++++++++ > 1 file changed, 13 insertions(+) > > diff --git a/drivers/iio/adc/ltc2497.c b/drivers/iio/adc/ltc2497.c > index f7c786f37ceb..78b93c99cc47 100644 > --- a/drivers/iio/adc/ltc2497.c > +++ b/drivers/iio/adc/ltc2497.c > @@ -41,6 +41,19 @@ static int ltc2497_result_and_measure(struct ltc2497core_driverdata *ddata, > } > > *val = (be32_to_cpu(st->buf) >> 14) - (1 << 17); > + > + /* > + * The part started a new conversion at the end of the above i2c > + * transfer, so if the address didn't change since the last call > + * everything is fine and we can return early. > + * If not (which should only happen when some sort of bulk > + * conversion is implemented) we have to program the new > + * address. Note that this probably fails as the conversion that > + * was triggered above is like not complete yet and the two > + * operations have to be done in a single transfer. > + */ > + if (ddata->addr_prev == address) > + return 0; > } > > ret = i2c_smbus_write_byte(st->client,