]> git.baikalelectronics.ru Git - kernel.git/commit
gpio: pca953x: fix handling of automatic address incrementing
authorUwe Kleine-König <u.kleine-koenig@pengutronix.de>
Mon, 20 Apr 2020 17:27:51 +0000 (20:27 +0300)
committerBartosz Golaszewski <bgolaszewski@baylibre.com>
Wed, 29 Apr 2020 11:19:51 +0000 (13:19 +0200)
commit779c7fde74ed9751708df0497416e63b294c8e64
treee1b70f52396baf8277e38262b96b5ac1cbd8b934
parentef75e704f236f7baebf2498f3255e941e7ed2123
gpio: pca953x: fix handling of automatic address incrementing

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 ad42c78b6147
("gpio: pca953x: Extract the register address mangling to single
function") changed which chips and functions are affected. Commit
12a08f92addf ("gpio: pca953x: hack to fix 24 bit gpio expanders") used
some duct tape to make the driver at least appear to work. Commit
8ab8aaf83e5a ("gpio: pca953x: Perform basic regmap conversion")
introduced the caching. Commit f5de1144623b ("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 78ab150df1bd ("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: Marcel Gudert <m.gudert@eckelmann.de>
Signed-off-by: Uwe Kleine-König <u.kleine-koenig@pengutronix.de>
Tested-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
Reviewed-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
Signed-off-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
Signed-off-by: Bartosz Golaszewski <bgolaszewski@baylibre.com>
drivers/gpio/gpio-pca953x.c