Re: [PATCH 01/28] mfd: Add Microchip ZL3073x support

From: Ivan Vecera
Date: Mon Apr 14 2025 - 10:34:44 EST


On 14. 04. 25 1:52 odp., Ivan Vecera wrote:


On 14. 04. 25 1:39 odp., Ivan Vecera wrote:


On 14. 04. 25 8:36 dop., Andy Shevchenko wrote:
What is wrong here?

I have a device that uses 7-bit addresses and have 16 register pages.
Each pages is from 0x00-0x7f and register 0x7f is used as page selector
where bits 0-3 select the page.
The problem is that you overlap virtual page over the real one (the main one).

The drivers you mentioned in v2 discussions most likely are also buggy.
As I implied in the above question the developers hardly get the regmap ranges
right. It took me quite a while to see the issue, so it's not particularly your
fault.
Hi Andy,

thank you I see the point.

Do you mean that the selector register should not be part of the range?

If so, does it mean that I have to specify a range for each page? Like this:

     {
         /* Page 0 */
         .range_min    = 0x000,
         .range_max    = 0x07e,
         .selector_reg    = ZL3073x_PAGE_SEL,
         .selector_mask    = GENMASK(3, 0),
         .selector_shift    = 0,
         .window_start    = 0,
         .window_len    = 0x7e,
     },
     {
         /* Page 1 */
         .range_min    = 0x080,
         .range_max    = 0x0fe,
         .selector_reg    = ZL3073x_PAGE_SEL,
         .selector_mask    = GENMASK(3, 0),
         .selector_shift    = 0,
         .window_start    = 0,
         .window_len    = 0x7e,
     },
...

No, I will answer by myself... this is non-sense.... window_len has to be 0x80. But I probably know what do you mean...

regmap range should not overlap... so I should use something like:

{
/* original <0x000-0x77f> with offset of 0x100 to move
the range outside of <0x00-0x7f> used by real one */
.range_min = 0x100,
.range_max = 0x87f,
.selector_reg = 0x7f,
.selector_mask = GENMASK(3, 0),
.selector_shift = 0,
.window_start = 0,
.window_len = 0x80,
},

With this I have to modify the driver to use this 0x100 offset. I mean the datasheet says that register BLAH is at 0x201-0x202. So in the driver I have to use 0x301-0x302.

Then the _regmap_select_page maps this 0x301 this way:
window_offset = (0x301 - range_min) % window_len;
window_page = (0x301 - range_min) / window len;
thus
window_offset = (0x301 - 0x100) % 0x80 = 0x001
window_page = (0x301 - 0x100) / 0x80 = 4

Long story short, I have to move virtual range outside real address range and apply this offset in the driver code.

Is this correct?

Thanks,
Ivan