| From 040c08b8952ac619c0750ad17ca3138bf8148f89 Mon Sep 17 00:00:00 2001 |
| From: "H. Nikolaus Schaller" <hns@goldelico.com> |
| Date: Tue, 4 Jun 2019 14:35:58 +0200 |
| Subject: gpio: pca953x: hack to fix 24 bit gpio expanders |
| |
| [ Upstream commit 3b00691cc46a4089368a008b30655a8343411715 ] |
| |
| 24 bit expanders use REG_ADDR_AI in combination with register addressing. This |
| conflicts with regmap which takes this bit as part of the register number, |
| i.e. a second cache entry is defined for accessed with REG_ADDR_AI being |
| set although on the chip it is the same register as with REG_ADDR_AI being |
| cleared. |
| |
| The problem was introduced by |
| |
| commit b32cecb46bdc ("gpio: pca953x: Extract the register address mangling to single function") |
| |
| but only became visible by |
| |
| commit 8b9f9d4dc511 ("regmap: verify if register is writeable before writing operations") |
| |
| because before, the regmap size was effectively ignored and |
| pca953x_writeable_register() did know to ignore REG_ADDR_AI. Still, there |
| were two separate cache entries created. |
| |
| Since the use of REG_ADDR_AI seems to be static we can work around this |
| issue by simply increasing the size of the regmap to cover the "virtual" |
| registers with REG_ADDR_AI being set. This only means that half of the |
| regmap buffer will be unused. |
| |
| Reported-by: H. Nikolaus Schaller <hns@goldelico.com> |
| Suggested-by: Linus Walleij <linus.walleij@linaro.org> |
| Signed-off-by: H. Nikolaus Schaller <hns@goldelico.com> |
| Signed-off-by: Linus Walleij <linus.walleij@linaro.org> |
| Signed-off-by: Sasha Levin <sashal@kernel.org> |
| --- |
| drivers/gpio/gpio-pca953x.c | 3 ++- |
| 1 file changed, 2 insertions(+), 1 deletion(-) |
| |
| diff --git a/drivers/gpio/gpio-pca953x.c b/drivers/gpio/gpio-pca953x.c |
| index 7e76830b3368..b6f10e56dfa0 100644 |
| --- a/drivers/gpio/gpio-pca953x.c |
| +++ b/drivers/gpio/gpio-pca953x.c |
| @@ -306,7 +306,8 @@ static const struct regmap_config pca953x_i2c_regmap = { |
| .volatile_reg = pca953x_volatile_register, |
| |
| .cache_type = REGCACHE_RBTREE, |
| - .max_register = 0x7f, |
| + /* REVISIT: should be 0x7f but some 24 bit chips use REG_ADDR_AI */ |
| + .max_register = 0xff, |
| }; |
| |
| static u8 pca953x_recalc_addr(struct pca953x_chip *chip, int reg, int off, |
| -- |
| 2.20.1 |
| |