Devicetree
 help / color / mirror / Atom feed
From: Jonathan Cameron <jic23@kernel.org>
To: Kanak Shilledar <kanak.shilledar@axis.com>
Cc: "Henrik Grimler" <henrik.grimler@axis.com>,
	"David Lechner" <dlechner@baylibre.com>,
	"Nuno Sá" <nuno.sa@analog.com>,
	"Andy Shevchenko" <andy@kernel.org>,
	"Rob Herring" <robh@kernel.org>,
	"Krzysztof Kozlowski" <krzk+dt@kernel.org>,
	"Conor Dooley" <conor+dt@kernel.org>,
	"Jean-Baptiste Maneyrol" <jean-baptiste.maneyrol@tdk.com>,
	"Joshua Crofts" <joshua.crofts1@gmail.com>,
	"Marcelo Schmitt" <marcelo.schmitt1@gmail.com>,
	"Chris Morgan" <macromorgan@hotmail.com>,
	kernel@axis.com, linux-iio@vger.kernel.org,
	devicetree@vger.kernel.org, linux-kernel@vger.kernel.org,
	"Jonathan Cameron" <jonathan.cameron@oss.qualcomm.com>,
	"Krzysztof Kozlowski" <krzysztof.kozlowski@oss.qualcomm.com>
Subject: Re: [PATCH v7 6/7] iio: imu: inv_icm42607: Implement MREGx register access
Date: Sun, 1 Nov 2026 22:22:30 +0000	[thread overview]
Message-ID: <20261101222230.2ce697cf@jic23-hlaptop> (raw)
In-Reply-To: <20261026-b4-inv_icm42370p-v7-6-222e296ac1e0@axis.com>

On Mon, 26 Oct 2026 12:02:54 +0100
Kanak Shilledar <kanak.shilledar@axis.com> wrote:

> The device supports indirect register access to different banks. A
> specific routine needs to be followed when accessing the registers in
> another bank as documented in the datasheet (section 13). This is
> required for accessing registers configured via the user and
> implementing buffer support. The implementation is inspired from the
> icm45600 driver.
> 
> The banks are defined based on their initial bank access code which are
> written to the BLK_SEL_* regs. However, there is a variation for MREG1
> as User Bank 0 and MREG1 both share the same 0x00, so User Bank 1 has
> 0x00 and MREG1 has 0x01. When MREG1 register is accessed, then BLK_SEL_*
> is written with 0x00 instead of 0x01. All the register access goes
> through the 16 bit virtual regmap layered on top of the 8bit bus regmap.
> Bank id in the upper byte and the register address in the lower byte.
> Bank 0 accesses are forwarded to the bus regmap with the bank field
> stripped, while MREG accesses are forwarded to bank switching sequence.
> 
> Due to the specific bank switching routine, it is not possible to use
> regmap-ranges. Only User Bank 0 supports bulk read/writes whereas other
> banks can only be accessed serially. Each time some data in the other
> bank needs to be accessed, it should go through the complete bank
> switching sequence.
> 
> Datasheet: https://www.invensense.tdk.com/en-us/products/3-axis/icm-42370-p
> Datasheet: https://www.lcsc.com/product-detail/C5129967.html
> Assisted-by: LLM

Drop this assisted by. The rules changes again :(  Now the plan is
just to have the LLM usage bit you have below the --- and
keep nothing in the git log.

> Signed-off-by: Kanak Shilledar <kanak.shilledar@axis.com>
> ---
> LLM was used to implement the mreg back switching support.
> ---
>  drivers/iio/imu/inv_icm42607/inv_icm42607.h      | 166 ++++++++++------
>  drivers/iio/imu/inv_icm42607/inv_icm42607_core.c | 242 +++++++++++++++++++++--
>  2 files changed, 329 insertions(+), 79 deletions(-)
> 
> diff --git a/drivers/iio/imu/inv_icm42607/inv_icm42607.h b/drivers/iio/imu/inv_icm42607/inv_icm42607.h
> index 674a9896fabb3..eecf4c46cbdb0 100644
> --- a/drivers/iio/imu/inv_icm42607/inv_icm42607.h
> +++ b/drivers/iio/imu/inv_icm42607/inv_icm42607.h


> diff --git a/drivers/iio/imu/inv_icm42607/inv_icm42607_core.c b/drivers/iio/imu/inv_icm42607/inv_icm42607_core.c
> index 018a7506ad50c..414642f8ec930 100644
> --- a/drivers/iio/imu/inv_icm42607/inv_icm42607_core.c
> +++ b/drivers/iio/imu/inv_icm42607/inv_icm42607_core.c

> -	return false;
> +static int inv_icm42607_mreg_read(struct regmap *map, unsigned int reg,
> +				  u8 *data, size_t count)
> +{
> +	int ret, ret2, ret3;
> +	unsigned int val;
> +	bool idle_set;
> +	u8 blk_sel;
> +
> +	/* MREG access is one byte per transaction, no burst support. */
> +	if (count != 1)
> +		return -EINVAL;
> +
> +	ret = inv_icm42607_blk_sel(reg, &blk_sel);
> +	if (ret)
> +		return ret;
> +
> +	ret = inv_icm42607_mclk_get(map, &idle_set);
> +	if (ret)
If this fails, why don't we need to undo the blk select?
> +		return ret;
> +
> +	ret = regmap_write(map, INV_ICM42607_REG_BLK_SEL_R, blk_sel);
> +	if (ret)
> +		goto out;
> +
> +	ret = regmap_write(map, INV_ICM42607_REG_MADDR_R,
> +			   FIELD_GET(INV_ICM42607_REG_ADDR_MASK, reg));
> +	fsleep(INV_ICM42607_MREG_ACCESS_DELAY_US);
> +	if (ret)
> +		goto out;
> +
> +	ret = regmap_read(map, INV_ICM42607_REG_M_R, &val);
> +	fsleep(INV_ICM42607_MREG_ACCESS_DELAY_US);
> +	if (ret)
> +		goto out;
> +
> +	*data = val;
> +out:
> +	/* Restore direct access. */
> +	ret2 = regmap_write(map, INV_ICM42607_REG_BLK_SEL_R, 0);
> +	ret3 = inv_icm42607_mclk_put(map, idle_set);
> +
> +	return ret ?: ret2 ?: ret3;
From a readability point of view, this is getting a bit too creative.
I think I'd just separate the good and bad paths and burn a few more
lines to do it.  The lack of balance between get and release also
concerns me.

If we to do blk select then mclk manipulation in the same order for
both, then break it out to helpers where you can easily document why.

static int inv_icm42607_switch_to_mreg()
{
	int ret;

	ret = inv_icm42607_blk_sel(reg, &blk_sel);
	if (ret)
		return ret;

	ret = inv_icm42607_mclk_get(map, &idle_set);
	if (ret)
		//Can't undo the blk select?   Add comment here.
		return ret;

	return 0;
}

static int inv_icm42607_switch_from_mreg()
{
	int ret;

	/* Restore direct access - Say why ordering */
	ret = regmap_write(map, INV_ICM42607_REG_BLK_SEL_R, 0);
	if (ret) {
		inv_icm42607_mclk_put(map, idle_set);
		return ret;
	}
	return inv_icm42607_mclk_put(map, idle_set);
}

Even with this, split the inv_icm42607_mreg_read()
ending into a good path and error path to avoid the ret2 type
dance.



>  
> +static int inv_icm42607_mreg_write(struct regmap *map, unsigned int reg,
> +				   const u8 *data, size_t count)
> +{
> +	int ret, ret2, ret3;
> +	bool idle_set;
> +	u8 blk_sel;
> +
> +	/* MREG access is one byte per transaction, no burst support. */
> +	if (count != 1)
> +		return -EINVAL;
> +
> +	ret = inv_icm42607_blk_sel(reg, &blk_sel);
> +	if (ret)
> +		return ret;
> +
> +	ret = inv_icm42607_mclk_get(map, &idle_set);
> +	if (ret)
> +		return ret;
> +
> +	ret = regmap_write(map, INV_ICM42607_REG_BLK_SEL_W, blk_sel);
> +	if (ret)
> +		goto out;
> +
> +	ret = regmap_write(map, INV_ICM42607_REG_MADDR_W,
> +			   FIELD_GET(INV_ICM42607_REG_ADDR_MASK, reg));
> +	if (ret)
> +		goto out;
> +
> +	ret = regmap_write(map, INV_ICM42607_REG_M_W, *data);
> +	fsleep(INV_ICM42607_MREG_ACCESS_DELAY_US);
> +
> +out:
> +	/* Restore direct access. */
> +	ret2 = regmap_write(map, INV_ICM42607_REG_BLK_SEL_W, 0);
> +	ret3 = inv_icm42607_mclk_put(map, idle_set);
> +
> +	return ret ?: ret2 ?: ret3;

As above.

> +}
> +


  reply	other threads:[~2026-11-01 22:22 UTC|newest]

Thread overview: 11+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-10-26 11:02 [PATCH v7 0/7] Add support for InvenSense ICM-42370-P accelerometer Kanak Shilledar
2026-10-26 11:02 ` [PATCH v7 1/7] dt-bindings: iio: imu: icm42600: Drop interrupt requirement Kanak Shilledar
2026-10-26 11:02 ` [PATCH v7 2/7] dt-bindings: iio: imu: icm42600: Add ICM-42670-P Kanak Shilledar
2026-10-26 11:02 ` [PATCH v7 3/7] iio: imu: inv_icm42607: Simplify IIO channel macros Kanak Shilledar
2026-10-26 11:02 ` [PATCH v7 4/7] iio: imu: inv_icm42607: Initialize gyro based on chip_info Kanak Shilledar
2026-10-26 13:07   ` Andy Shevchenko
2026-10-26 11:02 ` [PATCH v7 5/7] iio: imu: inv_icm42607: Add support for ICM-42370-P Kanak Shilledar
2026-10-26 11:02 ` [PATCH v7 6/7] iio: imu: inv_icm42607: Implement MREGx register access Kanak Shilledar
2026-11-01 22:22   ` Jonathan Cameron [this message]
2026-10-26 11:02 ` [PATCH v7 7/7] iio: imu: inv_icm42607: Add accelerometer calibbias support Kanak Shilledar
2026-11-01 22:25   ` Jonathan Cameron

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=20261101222230.2ce697cf@jic23-hlaptop \
    --to=jic23@kernel.org \
    --cc=andy@kernel.org \
    --cc=conor+dt@kernel.org \
    --cc=devicetree@vger.kernel.org \
    --cc=dlechner@baylibre.com \
    --cc=henrik.grimler@axis.com \
    --cc=jean-baptiste.maneyrol@tdk.com \
    --cc=jonathan.cameron@oss.qualcomm.com \
    --cc=joshua.crofts1@gmail.com \
    --cc=kanak.shilledar@axis.com \
    --cc=kernel@axis.com \
    --cc=krzk+dt@kernel.org \
    --cc=krzysztof.kozlowski@oss.qualcomm.com \
    --cc=linux-iio@vger.kernel.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=macromorgan@hotmail.com \
    --cc=marcelo.schmitt1@gmail.com \
    --cc=nuno.sa@analog.com \
    --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