diff mbox series

[RFC,1/3] gpio: pca953x: Replace chip type flags with a type enum

Message ID 77a8e6b4-15d4-da2a-4697-5181994920d4@eilabs.com
State New
Headers show
Series gpio: pca953x: Redesign handling of chip types | expand

Commit Message

Levente Révész Jan. 30, 2023, 8:59 p.m. UTC
The driver supports 8 chip types. The chip type is encoded in
driver_data so that different chip types can be handled appropriately.

Encoding the type information in separate bit flags was not too
straightforward, and it didn't make it possible to encode 8 chip
types.

Replace bit flags with a pca953x_chip_type enum. Encode this enum in
driver_data as a number. Add missing chip types based on chip functions
and register layout.

Suggested-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
Signed-off-by: Levente Révész <levente.revesz@eilabs.com>
---
 drivers/gpio/gpio-pca953x.c | 255 ++++++++++++++++++++----------------
 1 file changed, 143 insertions(+), 112 deletions(-)

Comments

Andy Shevchenko Jan. 30, 2023, 9:57 p.m. UTC | #1
On Mon, Jan 30, 2023 at 09:59:42PM +0100, Levente Révész wrote:
> The driver supports 8 chip types. The chip type is encoded in
> driver_data so that different chip types can be handled appropriately.
> 
> Encoding the type information in separate bit flags was not too
> straightforward, and it didn't make it possible to encode 8 chip
> types.
> 
> Replace bit flags with a pca953x_chip_type enum. Encode this enum in
> driver_data as a number. Add missing chip types based on chip functions
> and register layout.

...

> +/*
> + * driver_data
> + *
> + *   31    24 23    16 15     8 7      0
> + *   xxxxxxxx xxxxxxxx xxxx____ ________
> + *                         ^^^^ ^^^^^^^^
> + *                         |    number of gpio lines
> + *                         chip type
> + */

Not sure we need this as it's self explanatory from the below masks.
Moreover, driver_data is 64-bit or 32-bit depending on the build.

> +#define PCA_GPIO_MASK		GENMASK(7, 0)
> +#define PCA_TYPE_MASK		GENMASK(11, 8)

...

> +enum pca953x_chip_type {

> +	TYPE_PCA953X_NOINT,
> +	TYPE_PCA953X,

Hmm... Since you change this anyway, I think I would distinguish them better.
Perhaps

	TYPE_PCA953X_INT,
	TYPE_PCA953X_NOINT,

?

In any case, please add a kernel doc to this enum to explain each type briefly.

> +	TYPE_PCA950X,

Can we make sorted? (I.e. move this before PCA953X)

> +	TYPE_PCAL953X,
> +	TYPE_PCAL652X,
> +	TYPE_PCAL653X,
> +	TYPE_PCA957X,

Can we make sorted? (I.e. move this after PCA953X)

> +	TYPE_XRA120X,

	TYPE_MAX

> +};

static_assert((PCA_TYPE_MASK + 1) >= (TYPE_MAX << 8));
Andy Shevchenko Jan. 30, 2023, 10:01 p.m. UTC | #2
On Mon, Jan 30, 2023 at 11:57:11PM +0200, Andy Shevchenko wrote:
> On Mon, Jan 30, 2023 at 09:59:42PM +0100, Levente Révész wrote:

...

> static_assert((PCA_TYPE_MASK + 1) >= (TYPE_MAX << 8));

Actually better

static_assert(PCA_TYPE_MASK >= ((TYPE_MAX - 1) << 8));

to prevent potential overflow if we move this field to the end of the type.
diff mbox series

Patch

diff --git a/drivers/gpio/gpio-pca953x.c b/drivers/gpio/gpio-pca953x.c
index e4b7f34424e4..d6099fc18b01 100644
--- a/drivers/gpio/gpio-pca953x.c
+++ b/drivers/gpio/gpio-pca953x.c
@@ -57,60 +57,78 @@ 
 #define PCAL6524_OUT_INDCONF	0x2c
 #define PCAL6524_DEBOUNCE	0x2d
 
-#define PCA_GPIO_MASK		GENMASK(7, 0)
-
 #define PCAL_GPIO_MASK		GENMASK(4, 0)
 #define PCAL_PINCTRL_MASK	GENMASK(6, 5)
 
-#define PCA_INT			BIT(8)
-#define PCA_PCAL		BIT(9)
-#define PCA_LATCH_INT		(PCA_PCAL | PCA_INT)
-#define PCA953X_TYPE		BIT(12)
-#define PCA957X_TYPE		BIT(13)
-#define PCAL653X_TYPE		BIT(14)
-#define PCA_TYPE_MASK		GENMASK(15, 12)
+/*
+ * driver_data
+ *
+ *   31    24 23    16 15     8 7      0
+ *   xxxxxxxx xxxxxxxx xxxx____ ________
+ *                         ^^^^ ^^^^^^^^
+ *                         |    number of gpio lines
+ *                         chip type
+ */
+
+#define PCA_GPIO_MASK		GENMASK(7, 0)
+#define PCA_TYPE_MASK		GENMASK(11, 8)
+
+enum pca953x_chip_type {
+	TYPE_PCA953X_NOINT,
+	TYPE_PCA953X,
+	TYPE_PCA950X,
+	TYPE_PCAL953X,
+	TYPE_PCAL652X,
+	TYPE_PCAL653X,
+	TYPE_PCA957X,
+	TYPE_XRA120X,
+};
+
+/* Get chip type from driver_data */
+#define PCA_GET_TYPE(x)		(((x) & PCA_TYPE_MASK) >> 8)
 
-#define PCA_CHIP_TYPE(x)	((x) & PCA_TYPE_MASK)
+/* Set chip type in driver_data */
+#define PCA_SET_TYPE(x)		((x) << 8 & PCA_TYPE_MASK)
 
 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, },
-	{ "pca9534", 8  | PCA953X_TYPE | PCA_INT, },
-	{ "pca9535", 16 | PCA953X_TYPE | PCA_INT, },
-	{ "pca9536", 4  | PCA953X_TYPE, },
-	{ "pca9537", 4  | PCA953X_TYPE | PCA_INT, },
-	{ "pca9538", 8  | PCA953X_TYPE | PCA_INT, },
-	{ "pca9539", 16 | PCA953X_TYPE | PCA_INT, },
-	{ "pca9554", 8  | PCA953X_TYPE | PCA_INT, },
-	{ "pca9555", 16 | PCA953X_TYPE | PCA_INT, },
-	{ "pca9556", 8  | PCA953X_TYPE, },
-	{ "pca9557", 8  | PCA953X_TYPE, },
-	{ "pca9574", 8  | PCA957X_TYPE | PCA_INT, },
-	{ "pca9575", 16 | PCA957X_TYPE | PCA_INT, },
-	{ "pca9698", 40 | PCA953X_TYPE, },
-
-	{ "pcal6408", 8 | PCA953X_TYPE | PCA_LATCH_INT, },
-	{ "pcal6416", 16 | PCA953X_TYPE | PCA_LATCH_INT, },
-	{ "pcal6524", 24 | PCA953X_TYPE | PCA_LATCH_INT, },
-	{ "pcal6534", 34 | PCAL653X_TYPE | PCA_LATCH_INT, },
-	{ "pcal9535", 16 | PCA953X_TYPE | PCA_LATCH_INT, },
-	{ "pcal9554b", 8  | PCA953X_TYPE | PCA_LATCH_INT, },
-	{ "pcal9555a", 16 | PCA953X_TYPE | PCA_LATCH_INT, },
-
-	{ "max7310", 8  | PCA953X_TYPE, },
-	{ "max7312", 16 | PCA953X_TYPE | PCA_INT, },
-	{ "max7313", 16 | PCA953X_TYPE | PCA_INT, },
-	{ "max7315", 8  | PCA953X_TYPE | PCA_INT, },
-	{ "max7318", 16 | PCA953X_TYPE | PCA_INT, },
-	{ "pca6107", 8  | PCA953X_TYPE | PCA_INT, },
-	{ "tca6408", 8  | PCA953X_TYPE | PCA_INT, },
-	{ "tca6416", 16 | PCA953X_TYPE | PCA_INT, },
-	{ "tca6424", 24 | PCA953X_TYPE | PCA_INT, },
-	{ "tca9539", 16 | PCA953X_TYPE | PCA_INT, },
-	{ "tca9554", 8  | PCA953X_TYPE | PCA_INT, },
-	{ "xra1202", 8  | PCA953X_TYPE },
+	{ "pca6408", 8 | PCA_SET_TYPE(TYPE_PCA953X), },
+	{ "pca6416", 16 | PCA_SET_TYPE(TYPE_PCA953X), },
+	{ "pca9505", 40 | PCA_SET_TYPE(TYPE_PCA950X), },
+	{ "pca9506", 40 | PCA_SET_TYPE(TYPE_PCA950X), },
+	{ "pca9534", 8 | PCA_SET_TYPE(TYPE_PCA953X), },
+	{ "pca9535", 16 | PCA_SET_TYPE(TYPE_PCA953X), },
+	{ "pca9536", 4 | PCA_SET_TYPE(TYPE_PCA953X_NOINT), },
+	{ "pca9537", 4 | PCA_SET_TYPE(TYPE_PCA953X), },
+	{ "pca9538", 8 | PCA_SET_TYPE(TYPE_PCA953X), },
+	{ "pca9539", 16 | PCA_SET_TYPE(TYPE_PCA953X), },
+	{ "pca9554", 8 | PCA_SET_TYPE(TYPE_PCA953X), },
+	{ "pca9555", 16 | PCA_SET_TYPE(TYPE_PCA953X), },
+	{ "pca9556", 8 | PCA_SET_TYPE(TYPE_PCA953X_NOINT), },
+	{ "pca9557", 8 | PCA_SET_TYPE(TYPE_PCA953X_NOINT), },
+	{ "pca9574", 8 | PCA_SET_TYPE(TYPE_PCA957X), },
+	{ "pca9575", 16 | PCA_SET_TYPE(TYPE_PCA957X), },
+	{ "pca9698", 40 | PCA_SET_TYPE(TYPE_PCA950X), },
+
+	{ "pcal6408", 8 | PCA_SET_TYPE(TYPE_PCAL953X), },
+	{ "pcal6416", 16 | PCA_SET_TYPE(TYPE_PCAL953X), },
+	{ "pcal6524", 24 | PCA_SET_TYPE(TYPE_PCAL652X), },
+	{ "pcal6534", 34 | PCA_SET_TYPE(TYPE_PCAL653X), },
+	{ "pcal9535", 16 | PCA_SET_TYPE(TYPE_PCAL953X), },
+	{ "pcal9554b", 8 | PCA_SET_TYPE(TYPE_PCAL953X), },
+	{ "pcal9555a", 16 | PCA_SET_TYPE(TYPE_PCAL953X), },
+
+	{ "max7310", 8 | PCA_SET_TYPE(TYPE_PCA953X_NOINT), },
+	{ "max7312", 16 | PCA_SET_TYPE(TYPE_PCA953X), },
+	{ "max7313", 16 | PCA_SET_TYPE(TYPE_PCA953X), },
+	{ "max7315", 8 | PCA_SET_TYPE(TYPE_PCA953X), },
+	{ "max7318", 16 | PCA_SET_TYPE(TYPE_PCA953X), },
+	{ "pca6107", 8 | PCA_SET_TYPE(TYPE_PCA953X), },
+	{ "tca6408", 8 | PCA_SET_TYPE(TYPE_PCA953X), },
+	{ "tca6416", 16 | PCA_SET_TYPE(TYPE_PCA953X), },
+	{ "tca6424", 24 | PCA_SET_TYPE(TYPE_PCA953X), },
+	{ "tca9539", 16 | PCA_SET_TYPE(TYPE_PCA953X), },
+	{ "tca9554", 8 | PCA_SET_TYPE(TYPE_PCA953X), },
+	{ "xra1202", 8 | PCA_SET_TYPE(TYPE_XRA120X) },
 	{ }
 };
 MODULE_DEVICE_TABLE(i2c, pca953x_id);
@@ -162,7 +180,7 @@  static const struct dmi_system_id pca953x_dmi_acpi_irq_info[] = {
 #endif
 
 static const struct acpi_device_id pca953x_acpi_ids[] = {
-	{ "INT3491", 16 | PCA953X_TYPE | PCA_LATCH_INT, },
+	{ "INT3491", 16 | PCA_SET_TYPE(TYPE_PCAL953X), },
 	{ }
 };
 MODULE_DEVICE_TABLE(acpi, pca953x_acpi_ids);
@@ -214,6 +232,7 @@  struct pca953x_chip {
 	unsigned long driver_data;
 	struct regulator *regulator;
 
+	enum pca953x_chip_type type;
 	const struct pca953x_reg_config *regs;
 
 	u8 (*recalc_addr)(struct pca953x_chip *chip, int reg, int off);
@@ -221,6 +240,18 @@  struct pca953x_chip {
 			  u32 checkbank);
 };
 
+static bool pca953x_has_int(struct pca953x_chip *chip)
+{
+	return chip->type != TYPE_PCA953X_NOINT;
+}
+
+static bool pca953x_is_pcal_type(struct pca953x_chip *chip)
+{
+	return chip->type == TYPE_PCAL953X ||
+	       chip->type == TYPE_PCAL652X ||
+	       chip->type == TYPE_PCAL653X;
+}
+
 static int pca953x_bank_shift(struct pca953x_chip *chip)
 {
 	return fls((chip->gpio_chip.ngpio - 1) / BANK_SZ);
@@ -280,7 +311,7 @@  static bool pca953x_check_register(struct pca953x_chip *chip, unsigned int reg,
 
 	/* Special PCAL extended register check. */
 	if (reg & REG_ADDR_EXT) {
-		if (!(chip->driver_data & PCA_PCAL))
+		if (!pca953x_is_pcal_type(chip))
 			return false;
 		bank += 8;
 	}
@@ -347,7 +378,7 @@  static bool pca953x_readable_register(struct device *dev, unsigned int reg)
 	struct pca953x_chip *chip = dev_get_drvdata(dev);
 	u32 bank;
 
-	if (PCA_CHIP_TYPE(chip->driver_data) == PCA957X_TYPE) {
+	if (chip->type == TYPE_PCA957X) {
 		bank = PCA957x_BANK_INPUT | PCA957x_BANK_OUTPUT |
 		       PCA957x_BANK_POLARITY | PCA957x_BANK_CONFIG |
 		       PCA957x_BANK_BUSHOLD;
@@ -356,7 +387,7 @@  static bool pca953x_readable_register(struct device *dev, unsigned int reg)
 		       PCA953x_BANK_POLARITY | PCA953x_BANK_CONFIG;
 	}
 
-	if (chip->driver_data & PCA_PCAL) {
+	if (pca953x_is_pcal_type(chip)) {
 		bank |= PCAL9xxx_BANK_IN_LATCH | PCAL9xxx_BANK_PULL_EN |
 			PCAL9xxx_BANK_PULL_SEL | PCAL9xxx_BANK_IRQ_MASK |
 			PCAL9xxx_BANK_IRQ_STAT;
@@ -370,7 +401,7 @@  static bool pca953x_writeable_register(struct device *dev, unsigned int reg)
 	struct pca953x_chip *chip = dev_get_drvdata(dev);
 	u32 bank;
 
-	if (PCA_CHIP_TYPE(chip->driver_data) == PCA957X_TYPE) {
+	if (chip->type == TYPE_PCA957X) {
 		bank = PCA957x_BANK_OUTPUT | PCA957x_BANK_POLARITY |
 			PCA957x_BANK_CONFIG | PCA957x_BANK_BUSHOLD;
 	} else {
@@ -378,7 +409,7 @@  static bool pca953x_writeable_register(struct device *dev, unsigned int reg)
 			PCA953x_BANK_CONFIG;
 	}
 
-	if (chip->driver_data & PCA_PCAL)
+	if (pca953x_is_pcal_type(chip))
 		bank |= PCAL9xxx_BANK_IN_LATCH | PCAL9xxx_BANK_PULL_EN |
 			PCAL9xxx_BANK_PULL_SEL | PCAL9xxx_BANK_IRQ_MASK;
 
@@ -390,12 +421,12 @@  static bool pca953x_volatile_register(struct device *dev, unsigned int reg)
 	struct pca953x_chip *chip = dev_get_drvdata(dev);
 	u32 bank;
 
-	if (PCA_CHIP_TYPE(chip->driver_data) == PCA957X_TYPE)
+	if (chip->type == TYPE_PCA957X)
 		bank = PCA957x_BANK_INPUT;
 	else
 		bank = PCA953x_BANK_INPUT;
 
-	if (chip->driver_data & PCA_PCAL)
+	if (pca953x_is_pcal_type(chip))
 		bank |= PCAL9xxx_BANK_IRQ_STAT;
 
 	return chip->check_reg(chip, reg, bank);
@@ -645,7 +676,7 @@  static int pca953x_gpio_set_pull_up_down(struct pca953x_chip *chip,
 	 * pull-up/pull-down configuration requires PCAL extended
 	 * registers
 	 */
-	if (!(chip->driver_data & PCA_PCAL))
+	if (!pca953x_is_pcal_type(chip))
 		return -ENOTSUPP;
 
 	mutex_lock(&chip->i2c_lock);
@@ -761,7 +792,7 @@  static void pca953x_irq_bus_sync_unlock(struct irq_data *d)
 	DECLARE_BITMAP(reg_direction, MAX_LINE);
 	int level;
 
-	if (chip->driver_data & PCA_PCAL) {
+	if (pca953x_is_pcal_type(chip)) {
 		/* Enable latch on interrupt-enabled inputs */
 		pca953x_write_regs(chip, PCAL953X_IN_LATCH, chip->irq_mask);
 
@@ -843,7 +874,7 @@  static bool pca953x_irq_pending(struct pca953x_chip *chip, unsigned long *pendin
 	DECLARE_BITMAP(trigger, MAX_LINE);
 	int ret;
 
-	if (chip->driver_data & PCA_PCAL) {
+	if (pca953x_is_pcal_type(chip)) {
 		/* Read the current interrupt status from the device */
 		ret = pca953x_read_regs(chip, PCAL953X_INT_STAT, trigger);
 		if (ret)
@@ -941,7 +972,7 @@  static int pca953x_irq_setup(struct pca953x_chip *chip, int irq_base)
 	if (irq_base == -1)
 		return 0;
 
-	if (!(chip->driver_data & PCA_INT))
+	if (!pca953x_has_int(chip))
 		return 0;
 
 	ret = pca953x_read_regs(chip, chip->regs->input, irq_stat);
@@ -987,7 +1018,7 @@  static int pca953x_irq_setup(struct pca953x_chip *chip,
 {
 	struct i2c_client *client = chip->client;
 
-	if (client->irq && irq_base != -1 && (chip->driver_data & PCA_INT))
+	if (client->irq && irq_base != -1 && pca953x_has_int(chip))
 		dev_warn(&client->dev, "interrupt support not compiled in\n");
 
 	return 0;
@@ -1117,7 +1148,9 @@  static int pca953x_probe(struct i2c_client *client)
 
 	pca953x_setup_gpio(chip, chip->driver_data & PCA_GPIO_MASK);
 
-	if (NBANK(chip) > 2 || PCA_CHIP_TYPE(chip->driver_data) == PCA957X_TYPE) {
+	chip->type = PCA_GET_TYPE(chip->driver_data);
+
+	if (NBANK(chip) > 2 || chip->type == TYPE_PCA957X) {
 		dev_info(&client->dev, "using AI\n");
 		regmap_config = &pca953x_ai_i2c_regmap;
 	} else {
@@ -1125,7 +1158,7 @@  static int pca953x_probe(struct i2c_client *client)
 		regmap_config = &pca953x_i2c_regmap;
 	}
 
-	if (PCA_CHIP_TYPE(chip->driver_data) == PCAL653X_TYPE) {
+	if (chip->type == TYPE_PCAL653X) {
 		chip->recalc_addr = pcal6534_recalc_addr;
 		chip->check_reg = pcal6534_check_register;
 	} else {
@@ -1164,7 +1197,7 @@  static int pca953x_probe(struct i2c_client *client)
 	/* initialize cached registers from their original values.
 	 * we can't share this chip with another i2c master.
 	 */
-	if (PCA_CHIP_TYPE(chip->driver_data) == PCA957X_TYPE) {
+	if (chip->type == TYPE_PCA957X) {
 		chip->regs = &pca957x_regs;
 		ret = device_pca957x_init(chip, invert);
 	} else {
@@ -1235,7 +1268,7 @@  static int pca953x_regcache_sync(struct device *dev)
 	}
 
 #ifdef CONFIG_GPIO_PCA953X_IRQ
-	if (chip->driver_data & PCA_PCAL) {
+	if (pca953x_is_pcal_type(chip)) {
 		regaddr = chip->recalc_addr(chip, PCAL953X_IN_LATCH, 0);
 		ret = regcache_sync_region(chip->regmap, regaddr,
 					   regaddr + NBANK(chip) - 1);
@@ -1309,55 +1342,53 @@  static int pca953x_resume(struct device *dev)
 #endif
 
 /* convenience to stop overlong match-table lines */
-#define OF_653X(__nrgpio, __int) ((void *)(__nrgpio | PCAL653X_TYPE | __int))
-#define OF_953X(__nrgpio, __int) (void *)(__nrgpio | PCA953X_TYPE | __int)
-#define OF_957X(__nrgpio, __int) (void *)(__nrgpio | PCA957X_TYPE | __int)
+#define OF_DATA(__nrgpio, __type) ((void *)(__nrgpio | PCA_SET_TYPE(__type)))
 
 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,pca9534", .data = OF_953X( 8, PCA_INT), },
-	{ .compatible = "nxp,pca9535", .data = OF_953X(16, PCA_INT), },
-	{ .compatible = "nxp,pca9536", .data = OF_953X( 4, 0), },
-	{ .compatible = "nxp,pca9537", .data = OF_953X( 4, PCA_INT), },
-	{ .compatible = "nxp,pca9538", .data = OF_953X( 8, PCA_INT), },
-	{ .compatible = "nxp,pca9539", .data = OF_953X(16, PCA_INT), },
-	{ .compatible = "nxp,pca9554", .data = OF_953X( 8, PCA_INT), },
-	{ .compatible = "nxp,pca9555", .data = OF_953X(16, PCA_INT), },
-	{ .compatible = "nxp,pca9556", .data = OF_953X( 8, 0), },
-	{ .compatible = "nxp,pca9557", .data = OF_953X( 8, 0), },
-	{ .compatible = "nxp,pca9574", .data = OF_957X( 8, PCA_INT), },
-	{ .compatible = "nxp,pca9575", .data = OF_957X(16, PCA_INT), },
-	{ .compatible = "nxp,pca9698", .data = OF_953X(40, 0), },
-
-	{ .compatible = "nxp,pcal6408", .data = OF_953X(8, PCA_LATCH_INT), },
-	{ .compatible = "nxp,pcal6416", .data = OF_953X(16, PCA_LATCH_INT), },
-	{ .compatible = "nxp,pcal6524", .data = OF_953X(24, PCA_LATCH_INT), },
-	{ .compatible = "nxp,pcal6534", .data = OF_653X(34, PCA_LATCH_INT), },
-	{ .compatible = "nxp,pcal9535", .data = OF_953X(16, PCA_LATCH_INT), },
-	{ .compatible = "nxp,pcal9554b", .data = OF_953X( 8, PCA_LATCH_INT), },
-	{ .compatible = "nxp,pcal9555a", .data = OF_953X(16, PCA_LATCH_INT), },
-
-	{ .compatible = "maxim,max7310", .data = OF_953X( 8, 0), },
-	{ .compatible = "maxim,max7312", .data = OF_953X(16, PCA_INT), },
-	{ .compatible = "maxim,max7313", .data = OF_953X(16, PCA_INT), },
-	{ .compatible = "maxim,max7315", .data = OF_953X( 8, PCA_INT), },
-	{ .compatible = "maxim,max7318", .data = OF_953X(16, PCA_INT), },
-
-	{ .compatible = "ti,pca6107", .data = OF_953X( 8, PCA_INT), },
-	{ .compatible = "ti,pca9536", .data = OF_953X( 4, 0), },
-	{ .compatible = "ti,tca6408", .data = OF_953X( 8, PCA_INT), },
-	{ .compatible = "ti,tca6416", .data = OF_953X(16, PCA_INT), },
-	{ .compatible = "ti,tca6424", .data = OF_953X(24, PCA_INT), },
-	{ .compatible = "ti,tca9539", .data = OF_953X(16, PCA_INT), },
-
-	{ .compatible = "onnn,cat9554", .data = OF_953X( 8, PCA_INT), },
-	{ .compatible = "onnn,pca9654", .data = OF_953X( 8, PCA_INT), },
-	{ .compatible = "onnn,pca9655", .data = OF_953X(16, PCA_INT), },
-
-	{ .compatible = "exar,xra1202", .data = OF_953X( 8, 0), },
+	{ .compatible = "nxp,pca6408", .data = OF_DATA(8, TYPE_PCA953X), },
+	{ .compatible = "nxp,pca6416", .data = OF_DATA(16, TYPE_PCA953X), },
+	{ .compatible = "nxp,pca9505", .data = OF_DATA(40, TYPE_PCA950X), },
+	{ .compatible = "nxp,pca9506", .data = OF_DATA(40, TYPE_PCA950X), },
+	{ .compatible = "nxp,pca9534", .data = OF_DATA(8, TYPE_PCA953X), },
+	{ .compatible = "nxp,pca9535", .data = OF_DATA(16, TYPE_PCA953X), },
+	{ .compatible = "nxp,pca9536", .data = OF_DATA(4, TYPE_PCA953X_NOINT), },
+	{ .compatible = "nxp,pca9537", .data = OF_DATA(4, TYPE_PCA953X), },
+	{ .compatible = "nxp,pca9538", .data = OF_DATA(8, TYPE_PCA953X), },
+	{ .compatible = "nxp,pca9539", .data = OF_DATA(16, TYPE_PCA953X), },
+	{ .compatible = "nxp,pca9554", .data = OF_DATA(8, TYPE_PCA953X), },
+	{ .compatible = "nxp,pca9555", .data = OF_DATA(16, TYPE_PCA953X), },
+	{ .compatible = "nxp,pca9556", .data = OF_DATA(8, TYPE_PCA953X_NOINT), },
+	{ .compatible = "nxp,pca9557", .data = OF_DATA(8, TYPE_PCA953X_NOINT), },
+	{ .compatible = "nxp,pca9574", .data = OF_DATA(8, TYPE_PCA957X), },
+	{ .compatible = "nxp,pca9575", .data = OF_DATA(16, TYPE_PCA957X), },
+	{ .compatible = "nxp,pca9698", .data = OF_DATA(40, TYPE_PCA950X), },
+
+	{ .compatible = "nxp,pcal6408", .data = OF_DATA(8, TYPE_PCAL953X), },
+	{ .compatible = "nxp,pcal6416", .data = OF_DATA(16, TYPE_PCAL953X), },
+	{ .compatible = "nxp,pcal6524", .data = OF_DATA(24, TYPE_PCAL652X), },
+	{ .compatible = "nxp,pcal6534", .data = OF_DATA(34, TYPE_PCAL653X), },
+	{ .compatible = "nxp,pcal9535", .data = OF_DATA(16, TYPE_PCAL953X), },
+	{ .compatible = "nxp,pcal9554b", .data = OF_DATA(8, TYPE_PCAL953X), },
+	{ .compatible = "nxp,pcal9555a", .data = OF_DATA(16, TYPE_PCAL953X), },
+
+	{ .compatible = "maxim,max7310", .data = OF_DATA(8, TYPE_PCA953X_NOINT), },
+	{ .compatible = "maxim,max7312", .data = OF_DATA(16, TYPE_PCA953X), },
+	{ .compatible = "maxim,max7313", .data = OF_DATA(16, TYPE_PCA953X), },
+	{ .compatible = "maxim,max7315", .data = OF_DATA(8, TYPE_PCA953X), },
+	{ .compatible = "maxim,max7318", .data = OF_DATA(16, TYPE_PCA953X), },
+
+	{ .compatible = "ti,pca6107", .data = OF_DATA(8, TYPE_PCA953X), },
+	{ .compatible = "ti,pca9536", .data = OF_DATA(4, TYPE_PCA953X_NOINT), },
+	{ .compatible = "ti,tca6408", .data = OF_DATA(8, TYPE_PCA953X), },
+	{ .compatible = "ti,tca6416", .data = OF_DATA(16, TYPE_PCA953X), },
+	{ .compatible = "ti,tca6424", .data = OF_DATA(24, TYPE_PCA953X), },
+	{ .compatible = "ti,tca9539", .data = OF_DATA(16, TYPE_PCA953X), },
+
+	{ .compatible = "onnn,cat9554", .data = OF_DATA(8, TYPE_PCA953X), },
+	{ .compatible = "onnn,pca9654", .data = OF_DATA(8, TYPE_PCA953X), },
+	{ .compatible = "onnn,pca9655", .data = OF_DATA(16, TYPE_PCA953X), },
+
+	{ .compatible = "exar,xra1202", .data = OF_DATA(8, TYPE_XRA120X), },
 	{ }
 };