PCAL chips ("L" seems to stand for "latched") have additional registers starting at address 0x40 to control the latches, interrupt mask, pull-up and pull down etc.
The constants are so far defined in a way that they fit for the pcal9555a when shifted by the number of banks, i.e. multiplied by 2.
Now the pcal6524 has 3 banks which means the relative offset must be multiplied by 4 which gives a wrong result if not done carefully, since the base offset is already included in the offset.
For the basic registers shared with all pca93xx/tca64xx chips there is no such offset.
Therefore, we add code to adjust the register number for exended registers in this case.
And we add additional register offset constants (not yet used by the driver code) which are specific to the pcal6524.
Signed-off-by: H. Nikolaus Schaller hns@goldelico.com --- drivers/gpio/gpio-pca953x.c | 24 +++++++++++++++++++++--- 1 file changed, 21 insertions(+), 3 deletions(-)
diff --git a/drivers/gpio/gpio-pca953x.c b/drivers/gpio/gpio-pca953x.c index 4a075619b93e..c70acba710c7 100644 --- a/drivers/gpio/gpio-pca953x.c +++ b/drivers/gpio/gpio-pca953x.c @@ -41,9 +41,19 @@ #define PCA957X_MSK 6 #define PCA957X_INTS 7
-#define PCAL953X_IN_LATCH 34 -#define PCAL953X_INT_MASK 37 -#define PCAL953X_INT_STAT 38 +#define PCAL953X_OUT_STRENGTH 0x20 +#define PCAL953X_IN_LATCH 0x22 +#define PCAL953X_PULL_EN 0x23 +#define PCAL953X_PULL_SEL 0x24 +#define PCAL953X_INT_MASK 0x25 +#define PCAL953X_INT_STAT 0x26 +#define PCAL953X_OUT_CONF 0x27 + +#define PCAL6524_INT_EDGE 0x28 +#define PCAL6524_INT_CLR 0x2a +#define PCAL6524_IN_STATUS 0x2b +#define PCAL6524_OUT_INDCONF 0x2c +#define PCAL6524_DEBOUNCE 0x2d
#define PCA_GPIO_MASK 0x00FF #define PCA_INT 0x0100 @@ -208,6 +218,10 @@ static int pca953x_write_regs_24(struct pca953x_chip *chip, int reg, u8 *val) { int bank_shift = fls((chip->gpio_chip.ngpio - 1) / BANK_SZ);
+ /* adjust register address for pcal6524 */ + if (reg >= PCAL953X_OUT_STRENGTH) + reg -= PCAL953X_OUT_STRENGTH >> 1; + return i2c_smbus_write_i2c_block_data(chip->client, (reg << bank_shift) | REG_ADDR_AI, NBANK(chip), val); @@ -250,6 +264,10 @@ static int pca953x_read_regs_24(struct pca953x_chip *chip, int reg, u8 *val) { int bank_shift = fls((chip->gpio_chip.ngpio - 1) / BANK_SZ);
+ /* adjust register address for pcal6524 */ + if (reg >= PCAL953X_OUT_STRENGTH) + reg -= PCAL953X_OUT_STRENGTH >> 1; + return i2c_smbus_read_i2c_block_data(chip->client, (reg << bank_shift) | REG_ADDR_AI, NBANK(chip), val);