Re: [PATCH v7 4/4] iio: cdc: add Texas Instruments FDC1004 driver
From: Victor Chernyakin
Date: Tue Nov 10 2026 - 07:02:14 EST
> > > > + return regmap_write(map, FDC1004_REG_OFFSET_CAL_CINn(chan->channel),
> > > > + (u16)DIV_S64_ROUND_CLOSEST(val64, fdc1004_calibbias[1]));
> > >
> > > Why casting? Shouldn't it be handled on the regmap_write() stage based on
> > > the register / field description?
> >
> > This was prompted by this sashiko review:
> >
> > https://lore.kernel.org/SN1PR12MB252888B43D53AB1723952D21A5742@xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
> >
> > TLDR I'm not certain the cast is necessary, but I'm also not certain
> > it's not necessary (if regmap does handle it, I couldn't figure out
> > where), so I've added it out of caution.
>
> Yes, regmap core code is tricky in many places. So, as far as I read it,
> the I2C default bus with val_bits == 16 (if you have no custom regmap IO
> accessors) uses internal format operation regmap_format_16_be() along
> with format_write kept at NULL and hence defer_cache set to true (cache
> after formatting). The default working buffer for the data is work_buf,
> to which the above formatter puts the data, it doesn't put anything outside
> 16 LSBs.
>
> Since the code is tricky, please double check my way of understanding the code
> and confirm or point out any mistakes I made.
So to explain it to myself, the call chain is:
regmap_write() forwards to _regmap_write() forwards to map->reg_write().
What is map->reg_write() at this point? It is _regmap_bus_raw_write,
because that's what it was set to in __regmap_init().
_regmap_bus_raw_write() formats the value using map->format.format_val(),
which at this point is regmap_format_16_be(), also set in __regmap_init().
regmap_format_16_be() discards the top 16 bits.
I still haven't quite grasped all the logic in __regmap_init,
but I'm relatively sure of that description. Okay, that makes
me confident enough to remove the cast.