• Uwe Kleine-König's avatar
    gpio: pca953x: fix handling of automatic address incrementing · bcf41dc4
    Uwe Kleine-König authored
    Some of the chips supported by the pca953x driver need the most
    significant bit in the address word set to automatically increment the
    address pointer on subsequent reads and writes (example: PCA9505). With
    this bit unset the same register is read multiple times on a multi-byte
    read sequence. Other chips must not have this bit set and autoincrement
    always (example: PCA9555).
    
    Up to now this AI bit was interpreted to be part of the address, which
    resulted in inconsistent regmap caching when a register was written with
    AI set and then read without it. This happened for the PCA9505 in
    pca953x_gpio_set_multiple() where pca953x_read_regs() bulk read from the
    cache for registers 0x8-0xc and then wrote to registers 0x88-0x8c. (Side
    note: reading 5 values from offset 0x8 yiels OP0 5 times because AI must
    be set to get OP0-OP4, which is another bug that is resolved here as a
    by-product.) The same problem happens when calls to gpio_set_value() and
    gpio_set_array_value() were mixed.
    
    With this patch the AI bit is always set for chips that support it. This
    works as there are no code locations that make use of the behaviour with
    AI unset (for the chips that support it).
    
    Note that the call to pca953x_setup_gpio() had to be done a bit earlier
    to make the NBANK macro work.
    
    The history of this bug is a bit complicated. Commit b32cecb4
    ("gpio: pca953x: Extract the register address mangling to single
    function") changed which chips and functions are affected. Commit
    3b00691c ("gpio: pca953x: hack to fix 24 bit gpio expanders") used
    some duct tape to make the driver at least appear to work. Commit
    49427232 ("gpio: pca953x: Perform basic regmap conversion")
    introduced the caching. Commit b4818afe ("gpio: pca953x: Add
    set_multiple to allow multiple bits to be set in one write.") introduced
    the .set_multiple() callback which didn't work for chips that need the
    AI bit which was fixed later for some chips in 8958262a ("gpio:
    pca953x: Repair multi-byte IO address increment on PCA9575"). So I'm
    sorry, I don't know which commit I should pick for a Fixes: line.
    Tested-by: default avatarMarcel Gudert <m.gudert@eckelmann.de>
    Signed-off-by: default avatarUwe Kleine-König <u.kleine-koenig@pengutronix.de>
    Tested-by: default avatarAndy Shevchenko <andriy.shevchenko@linux.intel.com>
    Reviewed-by: default avatarAndy Shevchenko <andriy.shevchenko@linux.intel.com>
    Signed-off-by: default avatarAndy Shevchenko <andriy.shevchenko@linux.intel.com>
    Signed-off-by: default avatarBartosz Golaszewski <bgolaszewski@baylibre.com>
    bcf41dc4
gpio-pca953x.c 32.6 KB