diff mbox series

[2/2] gpio: pca953x: Add interrupt mask support for chips with the standard register set

Message ID 20221010132007.924810-3-levente.revesz@eilabs.com
State New
Headers show
Series gpio: pca953x: Add interrupt mask support for pca953x chips | expand

Commit Message

Révész, Levente Oct. 10, 2022, 1:20 p.m. UTC
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(-)
diff mbox series

Patch

diff --git a/drivers/gpio/gpio-pca953x.c b/drivers/gpio/gpio-pca953x.c
index 71bfc38c3930..bb8355540a46 100644
--- a/drivers/gpio/gpio-pca953x.c
+++ b/drivers/gpio/gpio-pca953x.c
@@ -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), },