public inbox for devicetree@vger.kernel.org
 help / color / mirror / Atom feed
From: <Victor.Duicu@microchip.com>
To: <linux@roeck-us.net>
Cc: <corbet@lwn.net>, <linux-hwmon@vger.kernel.org>,
	<devicetree@vger.kernel.org>, <robh@kernel.org>,
	<linux-kernel@vger.kernel.org>, <krzk+dt@kernel.org>,
	<linux-doc@vger.kernel.org>, <conor+dt@kernel.org>,
	<Marius.Cristea@microchip.com>
Subject: Re: [PATCH v10 2/2] hwmon: add support for MCP998X
Date: Mon, 30 Mar 2026 12:01:16 +0000	[thread overview]
Message-ID: <2d3955f5b906018fd7670ed5b8d37eaffa0ec207.camel@microchip.com> (raw)
In-Reply-To: <ccda48d0-3b10-4c3c-a632-6f70b54436fb@roeck-us.net>

Hi Guenter,

...

> > +     }
> > +
> > +     switch (type) {
> > +     case hwmon_temp:
> > +             switch (attr) {
> > +             case hwmon_temp_input:
> > +                     /* Block reading from addresses 0x00->0x09 is
> > not allowed. */
> > +                     ret = regmap_read(priv->regmap,
> > MCP9982_HIGH_BYTE_ADDR(channel), &reg_high);
> > +                     if (ret)
> > +                             return ret;
> > +
> > +                     ret = regmap_read(priv->regmap,
> > MCP9982_HIGH_BYTE_ADDR(channel) + 1,
> > +                                       &reg_low);
> > +                     if (ret)
> > +                             return ret;
> 
> Reading the 11-bit temperature value involves two separate 8-bit
> register reads.
> If the chip updates the temperature between these two reads, the
> resulting value
> may be torn. While some chips latch the low byte upon reading the
> high byte,
> the driver does not explicitly rely on or document this behavior, and
> it's safer
> to use regmap_bulk_read if supported, or at least ensure the correct
> order and
> atomicity if possible.
> 
> Note: Maybe the low temperature is latched, but there is no
> indication in the
> datasheet that this would be the case. Even if it is, the code above
> is
> inefficient.

The low temperature register is latched. In the documentation at
page 32 it is described that when reading the high byte register,
the value from the low byte register is copied into a 'shadow'
register. In this way it is guaranteed that when we read the low byte,
it will correspond to the high byte.

Regarding the bulk read, the chip has a number of design quirks and
because of that different commands are supported only on some
particular memory regions.

According to the documentation page 26, the only areas of memory that
support SMBus block read are 80h->89h(temperature memory block) and
90h->97h(status memory block). In order to block read the temperatures,
the area of memory targeted has to be the temperature memory block. In
this context the read operation uses SMBus protocol and the first value
returned will be the number of addresses that can be read (in our
particular case a max value of 10 bytes).

In v8 of the driver
https://lore.kernel.org/all/20251120071248.3767-1-victor.duicu@microchip.com/
,
the temperature values were read with regmap_bulk_read(). In that
version, regmap_bulk_read() was also used to read the temperature
limits, without returning count (this is an undocumented feature of the
chip and because of that we could assume is not supported).
In order to avoid this behaviour and avoid mixing the SMBus and I2C
protocols all block readings were removed.

In the hopes of bypassing a long chain of replies, I tested the
behaviour of the chip with different read instructions.
Regmap_bulk_read() when applied to the temperature memory block
(80h->89h) returns count and the high and low bytes. When it is applied
to the 00h->09h memory, it uses I2C. It returns one temperature byte,
but all other bytes are returned as 0xFF. The chip behaves as if
it is at the last register location in the temperature block while the
host continues to ACK.(behaviour described at page 26).
If we set use_single_read in regmap_config and apply regmap_bulk_read()
to the 00h->09h register area the high and low temperature bytes are
read successfully without count.

Regmap_multi_reg_read() reads a number of registers one by one. When
applied to the 00h->09h area, I2C is used and it returns only the high
and low temperature bytes. When applied to the temperature memory block
(80h->89h), because it is not a bulk function, returns the count till
the end of the temperature memory block (aka SMBus count).

I2c_smbus_read_block_data() when applied to the temperature block (80h-
89h) returns the count, the driver replies with an NACK and the
communication is stopped. In our case, the board we are using to test
the driver has an AT91 adapter and supports
I2C_FUNC_SMBUS_READ_BLOCK_DATA. It seems that the I2C driver for AT91
does not modify the buff length of the message, leaving it 1.

I2c_smbus_read_i2c_block_data() when applied to the temperature block
(80h-89h) returns count and the temperature values.

If you are of the opinion that block reading the temperatures is worth
introducing (even in case we need to skip count) then I can add it, but
we should come to an agreement on which function to use.
Please let me know your thoughts.

Kind regards,
Victor

      reply	other threads:[~2026-03-30 12:01 UTC|newest]

Thread overview: 11+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-02-17 14:06 [PATCH v10 0/2] add support in hwmon for MCP998X Victor Duicu
2026-02-17 14:06 ` [PATCH v10 1/2] dt-bindings: hwmon: add support " Victor Duicu
2026-02-17 20:11   ` Krzysztof Kozlowski
2026-02-20 14:58     ` Victor.Duicu
2026-02-21 14:34       ` Krzysztof Kozlowski
2026-02-23 11:09         ` Victor.Duicu
2026-02-23 11:23           ` Krzysztof Kozlowski
2026-03-04  8:15             ` Victor.Duicu
2026-02-17 14:06 ` [PATCH v10 2/2] " Victor Duicu
2026-03-08 16:56   ` Guenter Roeck
2026-03-30 12:01     ` Victor.Duicu [this message]

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=2d3955f5b906018fd7670ed5b8d37eaffa0ec207.camel@microchip.com \
    --to=victor.duicu@microchip.com \
    --cc=Marius.Cristea@microchip.com \
    --cc=conor+dt@kernel.org \
    --cc=corbet@lwn.net \
    --cc=devicetree@vger.kernel.org \
    --cc=krzk+dt@kernel.org \
    --cc=linux-doc@vger.kernel.org \
    --cc=linux-hwmon@vger.kernel.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=linux@roeck-us.net \
    --cc=robh@kernel.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox