@@ -28,6 +28,7 @@
#define PCA953X_OUTPUT 0x01
#define PCA953X_INVERT 0x02
#define PCA953X_DIRECTION 0x03
+#define PCA953X_INT_MASK 0x04
#define REG_ADDR_MASK GENMASK(5, 0)
#define REG_ADDR_EXT BIT(6)
@@ -76,8 +77,8 @@
static const struct i2c_device_id pca953x_id[] = {
{ "pca6408", 8 | PCA953X_TYPE | PCA_INT, },
{ "pca6416", 16 | PCA953X_TYPE | PCA_INT, },
- { "pca9505", 40 | PCA953X_TYPE | PCA_INT, },
- { "pca9506", 40 | PCA953X_TYPE | PCA_INT, },
+ { "pca9505", 40 | PCA953X_TYPE | PCA_MASKED_INT, },
+ { "pca9506", 40 | PCA953X_TYPE | PCA_MASKED_INT, },
{ "pca9534", 8 | PCA953X_TYPE | PCA_INT, },
{ "pca9535", 16 | PCA953X_TYPE | PCA_INT, },
{ "pca9536", 4 | PCA953X_TYPE, },
@@ -187,6 +188,7 @@ static const struct pca953x_reg_config pca953x_regs = {
.output = PCA953X_OUTPUT,
.input = PCA953X_INPUT,
.invert = PCA953X_INVERT,
+ .int_mask = PCA953X_INT_MASK,
};
static const struct pca953x_reg_config pcal953x_regs = {
@@ -240,6 +242,7 @@ static int pca953x_bank_shift(struct pca953x_chip *chip)
#define PCA953x_BANK_OUTPUT BIT(1)
#define PCA953x_BANK_POLARITY BIT(2)
#define PCA953x_BANK_CONFIG BIT(3)
+#define PCA953x_BANK_INT_MASK BIT(4)
#define PCA957x_BANK_INPUT BIT(0)
#define PCA957x_BANK_POLARITY BIT(1)
@@ -261,6 +264,8 @@ static int pca953x_bank_shift(struct pca953x_chip *chip)
* Output port 0x00 + 1 * bank_size RW
* Polarity Inversion port 0x00 + 2 * bank_size RW
* Configuration port 0x00 + 3 * bank_size RW
+ * - Some chips have the standard layout with additional interrupt mask:
+ * Interrupt Mask port 0x00 + 4 * bank_size RW
* - PCA957x with mixed up registers
* Input port 0x00 + 0 * bank_size R
* Polarity Inversion port 0x00 + 1 * bank_size RW
@@ -374,6 +379,8 @@ static bool pca953x_readable_register(struct device *dev, unsigned int reg)
PCAL9xxx_BANK_PULL_SEL |
PCAL9xxx_BANK_IRQ_MASK |
PCAL9xxx_BANK_IRQ_STAT;
+ else if (chip->driver_data & PCA_HAS_INT_MASK)
+ bank |= PCA953x_BANK_INT_MASK;
}
return chip->check_reg(chip, reg, bank);
@@ -396,6 +403,8 @@ static bool pca953x_writeable_register(struct device *dev, unsigned int reg)
PCAL9xxx_BANK_PULL_EN |
PCAL9xxx_BANK_PULL_SEL |
PCAL9xxx_BANK_IRQ_MASK;
+ else if (chip->driver_data & PCA_HAS_INT_MASK)
+ bank |= PCA953x_BANK_INT_MASK;
}
return chip->check_reg(chip, reg, bank);
@@ -1342,8 +1351,8 @@ static int pca953x_resume(struct device *dev)
static const struct of_device_id pca953x_dt_ids[] = {
{ .compatible = "nxp,pca6408", .data = OF_953X(8, PCA_INT), },
{ .compatible = "nxp,pca6416", .data = OF_953X(16, PCA_INT), },
- { .compatible = "nxp,pca9505", .data = OF_953X(40, PCA_INT), },
- { .compatible = "nxp,pca9506", .data = OF_953X(40, PCA_INT), },
+ { .compatible = "nxp,pca9505", .data = OF_953X(40, PCA_MASKED_INT), },
+ { .compatible = "nxp,pca9506", .data = OF_953X(40, PCA_MASKED_INT), },
{ .compatible = "nxp,pca9534", .data = OF_953X( 8, PCA_INT), },
{ .compatible = "nxp,pca9535", .data = OF_953X(16, PCA_INT), },
{ .compatible = "nxp,pca9536", .data = OF_953X( 4, 0), },
Some chips in the pca953x family in addition to the standard 4 registers have a fifth interrupt mask register: 0: INPUT 1: OUTPUT 2: POLARITY 3: CONFIGURATION 4: INTERRUPT MASK Chips with this register: - pca9505 - pca9506 - pca9698 Otherwise the interrupt mask register works exactly the same as the corresponding register in the already supported pcal chips. Add PCA_953X_INT_MASK register. Use it as the interrupt register of (non-pcal) pca953x chips. Set pca9505 and pca9506 to use this register. Signed-off-by: Levente Révész <levente.revesz@eilabs.com> --- drivers/gpio/gpio-pca953x.c | 17 +++++++++++++---- 1 file changed, 13 insertions(+), 4 deletions(-)