lists.openwall.net   lists  /  announce  owl-users  owl-dev  john-users  john-dev  passwdqc-users  yescrypt  popa3d-users  /  oss-security  kernel-hardening  musl  sabotage  tlsify  passwords  /  crypt-dev  xvendor  /  Bugtraq  Full-Disclosure  linux-kernel  linux-netdev  linux-ext4  linux-hardening  linux-cve-announce  PHC 
Open Source and information security mailing list archives
 
Hash Suite: Windows password security audit tool. GUI, reports in PDF.
[<prev] [next>] [day] [month] [year] [list]
Message-ID: <8d8413be9ec10852ca40e091a26db19436d23b71.camel@collabora.com>
Date:   Wed, 24 Aug 2022 15:54:30 +0100
From:   Martyn Welch <martyn.welch@...labora.com>
To:     Andy Shevchenko <andy.shevchenko@...il.com>
Cc:     Linus Walleij <linus.walleij@...aro.org>,
        Bartosz Golaszewski <brgl@...ev.pl>,
        Collabora Kernel ML <kernel@...labora.com>,
        "open list:GPIO SUBSYSTEM" <linux-gpio@...r.kernel.org>,
        Linux Kernel Mailing List <linux-kernel@...r.kernel.org>
Subject: Re: [RFC PATCH] gpio: pca953x: Support for pcal6534

On Mon, 2022-08-22 at 11:56 +0300, Andy Shevchenko wrote:
> 
> 
> On Monday, August 22, 2022, Martyn Welch <martyn.welch@...labora.com>
> wrote:
> > On Sat, 2022-08-20 at 01:35 +0300, Andy Shevchenko wrote:
> > > On Wed, Aug 17, 2022 at 2:29 PM Martyn Welch
> > > <martyn.welch@...labora.com> wrote:
> > > >  
> > > > -       int bank_shift = pca953x_bank_shift(chip);
> > > > -       int bank = (reg & REG_ADDR_MASK) >> bank_shift;
> > > > -       int offset = reg & (BIT(bank_shift) - 1);
> > > > +       int bank;
> > > > +       int offset;
> > > > +
> > > > +       if (chip->driver_data & PCAL6534_ALIGN) {
> > > > +               bank = (reg & REG_ADDR_MASK) / NBANK(chip);
> > > > +               offset = reg - (bank * NBANK(chip));
> > > > +       } else {
> > > > +               int bank_shift = pca953x_bank_shift(chip);
> > > > +               bank = (reg & REG_ADDR_MASK) >> bank_shift;
> > > > +               offset = reg & (BIT(bank_shift) - 1);
> > > > +       }
> > > 
> > > I'm wondering if it can be moved to bank_shift()  and possibly a
> > > new
> > > helper to get an offset.
> > > 
> > 
> > Due to the different register spacing, I don't think these chips
> > obey
> > any offset based rules. For the record, I've done a bit more work
> > here
> > to get it returning the correct values for all the extended
> > registers.
> > What I currently have is this (which I don't particularly like and
> > would be open to alternative implementations):
> > 
> > 
> >  static u8 pca953x_recalc_addr(struct pca953x_chip *chip, int reg,
> > int
> > off)
> >  {
> > -       int bank_shift = pca953x_bank_shift(chip);
> > -       int addr = (reg & PCAL_GPIO_MASK) << bank_shift;
> > -       int pinctrl = (reg & PCAL_PINCTRL_MASK) << 1;
> > -       u8 regaddr = pinctrl | addr | (off / BANK_SZ);
> > +       int bank_shift;
> > +       int addr;
> > +       int pinctrl;
> > +       u8 regaddr;
> > +
> > +       if (chip->driver_data & PCAL6534_ALIGN) {
> > +               addr = (reg & PCAL_GPIO_MASK) * NBANK(chip);
> > +
> > +               switch(reg) {
> > +               case PCAL953X_OUT_STRENGTH:
> > +               case PCAL953X_IN_LATCH:
> > +               case PCAL953X_PULL_EN:
> > +               case PCAL953X_PULL_SEL:
> > +               case PCAL953X_INT_MASK:
> > +               case PCAL953X_INT_STAT:
> > +               case PCAL953X_OUT_CONF:
> > +                       pinctrl = ((reg & PCAL_PINCTRL_MASK) >> 1)
> > +
> > 0x20;
> > +                       break;
> > +               case PCAL6524_INT_EDGE:
> > +               case PCAL6524_INT_CLR:
> > +               case PCAL6524_IN_STATUS:
> > +               case PCAL6524_OUT_INDCONF:
> > +               case PCAL6524_DEBOUNCE:
> > +                       pinctrl = ((reg & PCAL_PINCTRL_MASK) >> 1)
> > +
> > 0x1c;
> > +                       break;
> > +               }
> > +               regaddr = pinctrl + addr + (off / BANK_SZ);
> > +       } else {
> > +               bank_shift = pca953x_bank_shift(chip);
> > +               addr = (reg & PCAL_GPIO_MASK) << bank_shift;
> > +               pinctrl = (reg & PCAL_PINCTRL_MASK) << 1;
> > +               regaddr = pinctrl | addr | (off / BANK_SZ);
> > +       }
> > 
> >         return regaddr;
> >  }
> > 
> > As I said, whilst the functionality of this chip seems to closely
> > match
> > some of the others driven by this driver, the register offsets are
> > quite different and hard to incorporate cleanly in this driver due
> > to
> > the way it determines register locations.
> > 
> 
> 
> I think it can be done much easier with the specific regmap callbacks
> specific to these kind of chips.
>  

Are you thinking of defining functions via struct regmap_bus?  If so,
I'm not sure how this helps. Unless I've miss understood how that would
work, those would come into play after regmap_bulk_write(), etc are
called, by which point the desired (and in this case wrong) offset will
have already been calculated in pca953x_recalc_addr().

Am I missing something?

Martyn

Powered by blists - more mailing lists

Powered by Openwall GNU/*/Linux Powered by OpenVZ