Commit 3e42f200 authored by Linus Walleij's avatar Linus Walleij
Browse files

Merge branch 'ib-pca953x' into devel

parents c5510b8d b7657430
Loading
Loading
Loading
Loading
+302 −182
Original line number Original line Diff line number Diff line
@@ -20,6 +20,7 @@
#include <linux/module.h>
#include <linux/module.h>
#include <linux/of_platform.h>
#include <linux/of_platform.h>
#include <linux/platform_data/pca953x.h>
#include <linux/platform_data/pca953x.h>
#include <linux/regmap.h>
#include <linux/regulator/consumer.h>
#include <linux/regulator/consumer.h>
#include <linux/slab.h>
#include <linux/slab.h>


@@ -30,6 +31,8 @@
#define PCA953X_INVERT		0x02
#define PCA953X_INVERT		0x02
#define PCA953X_DIRECTION	0x03
#define PCA953X_DIRECTION	0x03


#define REG_ADDR_MASK		0x3f
#define REG_ADDR_EXT		0x40
#define REG_ADDR_AI		0x80
#define REG_ADDR_AI		0x80


#define PCA957X_IN		0x00
#define PCA957X_IN		0x00
@@ -58,7 +61,7 @@
#define PCA_GPIO_MASK		0x00FF
#define PCA_GPIO_MASK		0x00FF


#define PCAL_GPIO_MASK		0x1f
#define PCAL_GPIO_MASK		0x1f
#define PCAL_PINCTRL_MASK	0xe0
#define PCAL_PINCTRL_MASK	0x60


#define PCA_INT			0x0100
#define PCA_INT			0x0100
#define PCA_PCAL		0x0200
#define PCA_PCAL		0x0200
@@ -119,25 +122,27 @@ struct pca953x_reg_config {
	int direction;
	int direction;
	int output;
	int output;
	int input;
	int input;
	int invert;
};
};


static const struct pca953x_reg_config pca953x_regs = {
static const struct pca953x_reg_config pca953x_regs = {
	.direction = PCA953X_DIRECTION,
	.direction = PCA953X_DIRECTION,
	.output = PCA953X_OUTPUT,
	.output = PCA953X_OUTPUT,
	.input = PCA953X_INPUT,
	.input = PCA953X_INPUT,
	.invert = PCA953X_INVERT,
};
};


static const struct pca953x_reg_config pca957x_regs = {
static const struct pca953x_reg_config pca957x_regs = {
	.direction = PCA957X_CFG,
	.direction = PCA957X_CFG,
	.output = PCA957X_OUT,
	.output = PCA957X_OUT,
	.input = PCA957X_IN,
	.input = PCA957X_IN,
	.invert = PCA957X_INVRT,
};
};


struct pca953x_chip {
struct pca953x_chip {
	unsigned gpio_start;
	unsigned gpio_start;
	u8 reg_output[MAX_BANK];
	u8 reg_direction[MAX_BANK];
	struct mutex i2c_lock;
	struct mutex i2c_lock;
	struct regmap *regmap;


#ifdef CONFIG_GPIO_PCA953X_IRQ
#ifdef CONFIG_GPIO_PCA953X_IRQ
	struct mutex irq_lock;
	struct mutex irq_lock;
@@ -154,131 +159,191 @@ struct pca953x_chip {
	struct regulator *regulator;
	struct regulator *regulator;


	const struct pca953x_reg_config *regs;
	const struct pca953x_reg_config *regs;

	int (*write_regs)(struct pca953x_chip *, int, u8 *);
	int (*read_regs)(struct pca953x_chip *, int, u8 *);
};
};


static int pca953x_read_single(struct pca953x_chip *chip, int reg, u32 *val,
static int pca953x_bank_shift(struct pca953x_chip *chip)
				int off)
{
{
	int ret;
	return fls((chip->gpio_chip.ngpio - 1) / BANK_SZ);
	int bank_shift = fls((chip->gpio_chip.ngpio - 1) / BANK_SZ);
}
	int offset = off / BANK_SZ;


	ret = i2c_smbus_read_byte_data(chip->client,
#define PCA953x_BANK_INPUT	BIT(0)
				(reg << bank_shift) + offset);
#define PCA953x_BANK_OUTPUT	BIT(1)
	*val = ret;
#define PCA953x_BANK_POLARITY	BIT(2)
#define PCA953x_BANK_CONFIG	BIT(3)


	if (ret < 0) {
#define PCA957x_BANK_INPUT	BIT(0)
		dev_err(&chip->client->dev, "failed reading register\n");
#define PCA957x_BANK_POLARITY	BIT(1)
		return ret;
#define PCA957x_BANK_BUSHOLD	BIT(2)
	}
#define PCA957x_BANK_CONFIG	BIT(4)
#define PCA957x_BANK_OUTPUT	BIT(5)


	return 0;
#define PCAL9xxx_BANK_IN_LATCH	BIT(8 + 2)
}
#define PCAL9xxx_BANK_IRQ_MASK	BIT(8 + 5)
#define PCAL9xxx_BANK_IRQ_STAT	BIT(8 + 6)


static int pca953x_write_single(struct pca953x_chip *chip, int reg, u32 val,
/*
				int off)
 * We care about the following registers:
{
 * - Standard set, below 0x40, each port can be replicated up to 8 times
	int ret;
 *   - PCA953x standard
	int bank_shift = fls((chip->gpio_chip.ngpio - 1) / BANK_SZ);
 *     Input port			0x00 + 0 * bank_size	R
	int offset = off / BANK_SZ;
 *     Output port			0x00 + 1 * bank_size	RW
 *     Polarity Inversion port		0x00 + 2 * bank_size	RW
 *     Configuration port		0x00 + 3 * bank_size	RW
 *   - PCA957x with mixed up registers
 *     Input port			0x00 + 0 * bank_size	R
 *     Polarity Inversion port		0x00 + 1 * bank_size	RW
 *     Bus hold port			0x00 + 2 * bank_size	RW
 *     Configuration port		0x00 + 4 * bank_size	RW
 *     Output port			0x00 + 5 * bank_size	RW
 *
 * - Extended set, above 0x40, often chip specific.
 *   - PCAL6524/PCAL9555A with custom PCAL IRQ handling:
 *     Input latch register		0x40 + 2 * bank_size	RW
 *     Interrupt mask register		0x40 + 5 * bank_size	RW
 *     Interrupt status register	0x40 + 6 * bank_size	R
 *
 * - Registers with bit 0x80 set, the AI bit
 *   The bit is cleared and the registers fall into one of the
 *   categories above.
 */


	ret = i2c_smbus_write_byte_data(chip->client,
static bool pca953x_check_register(struct pca953x_chip *chip, unsigned int reg,
					(reg << bank_shift) + offset, val);
				   u32 checkbank)
{
	int bank_shift = pca953x_bank_shift(chip);
	int bank = (reg & REG_ADDR_MASK) >> bank_shift;
	int offset = reg & (BIT(bank_shift) - 1);


	if (ret < 0) {
	/* Special PCAL extended register check. */
		dev_err(&chip->client->dev, "failed writing register\n");
	if (reg & REG_ADDR_EXT) {
		return ret;
		if (!(chip->driver_data & PCA_PCAL))
			return false;
		bank += 8;
	}
	}


	return 0;
	/* Register is not in the matching bank. */
	if (!(BIT(bank) & checkbank))
		return false;

	/* Register is not within allowed range of bank. */
	if (offset >= NBANK(chip))
		return false;

	return true;
}
}


static int pca953x_write_regs_8(struct pca953x_chip *chip, int reg, u8 *val)
static bool pca953x_readable_register(struct device *dev, unsigned int reg)
{
{
	return i2c_smbus_write_byte_data(chip->client, reg, *val);
	struct pca953x_chip *chip = dev_get_drvdata(dev);
	u32 bank;

	if (PCA_CHIP_TYPE(chip->driver_data) == PCA953X_TYPE) {
		bank = PCA953x_BANK_INPUT | PCA953x_BANK_OUTPUT |
		       PCA953x_BANK_POLARITY | PCA953x_BANK_CONFIG;
	} else {
		bank = PCA957x_BANK_INPUT | PCA957x_BANK_OUTPUT |
		       PCA957x_BANK_POLARITY | PCA957x_BANK_CONFIG |
		       PCA957x_BANK_BUSHOLD;
	}
	}


static int pca953x_write_regs_16(struct pca953x_chip *chip, int reg, u8 *val)
	if (chip->driver_data & PCA_PCAL) {
{
		bank |= PCAL9xxx_BANK_IN_LATCH | PCAL9xxx_BANK_IRQ_MASK |
	u16 word = get_unaligned((u16 *)val);
			PCAL9xxx_BANK_IRQ_STAT;
	}


	return i2c_smbus_write_word_data(chip->client, reg << 1, word);
	return pca953x_check_register(chip, reg, bank);
}
}


static int pca957x_write_regs_16(struct pca953x_chip *chip, int reg, u8 *val)
static bool pca953x_writeable_register(struct device *dev, unsigned int reg)
{
{
	int ret;
	struct pca953x_chip *chip = dev_get_drvdata(dev);

	u32 bank;
	ret = i2c_smbus_write_byte_data(chip->client, reg << 1, val[0]);
	if (ret < 0)
		return ret;


	return i2c_smbus_write_byte_data(chip->client, (reg << 1) + 1, val[1]);
	if (PCA_CHIP_TYPE(chip->driver_data) == PCA953X_TYPE) {
		bank = PCA953x_BANK_OUTPUT | PCA953x_BANK_POLARITY |
			PCA953x_BANK_CONFIG;
	} else {
		bank = PCA957x_BANK_OUTPUT | PCA957x_BANK_POLARITY |
			PCA957x_BANK_CONFIG | PCA957x_BANK_BUSHOLD;
	}
	}


static int pca953x_write_regs_24(struct pca953x_chip *chip, int reg, u8 *val)
	if (chip->driver_data & PCA_PCAL)
{
		bank |= PCAL9xxx_BANK_IN_LATCH | PCAL9xxx_BANK_IRQ_MASK;
	int bank_shift = fls((chip->gpio_chip.ngpio - 1) / BANK_SZ);
	int addr = (reg & PCAL_GPIO_MASK) << bank_shift;
	int pinctrl = (reg & PCAL_PINCTRL_MASK) << 1;


	return i2c_smbus_write_i2c_block_data(chip->client,
	return pca953x_check_register(chip, reg, bank);
					      pinctrl | addr | REG_ADDR_AI,
					      NBANK(chip), val);
}
}


static int pca953x_write_regs(struct pca953x_chip *chip, int reg, u8 *val)
static bool pca953x_volatile_register(struct device *dev, unsigned int reg)
{
{
	int ret = 0;
	struct pca953x_chip *chip = dev_get_drvdata(dev);
	u32 bank;


	ret = chip->write_regs(chip, reg, val);
	if (PCA_CHIP_TYPE(chip->driver_data) == PCA953X_TYPE)
	if (ret < 0) {
		bank = PCA953x_BANK_INPUT;
		dev_err(&chip->client->dev, "failed writing register\n");
	else
		return ret;
		bank = PCA957x_BANK_INPUT;
	}


	return 0;
	if (chip->driver_data & PCA_PCAL)
		bank |= PCAL9xxx_BANK_IRQ_STAT;

	return pca953x_check_register(chip, reg, bank);
}
}


static int pca953x_read_regs_8(struct pca953x_chip *chip, int reg, u8 *val)
const struct regmap_config pca953x_i2c_regmap = {
	.reg_bits = 8,
	.val_bits = 8,

	.readable_reg = pca953x_readable_register,
	.writeable_reg = pca953x_writeable_register,
	.volatile_reg = pca953x_volatile_register,

	.cache_type = REGCACHE_RBTREE,
	.max_register = 0x7f,
};

static u8 pca953x_recalc_addr(struct pca953x_chip *chip, int reg, int off,
			      bool write, bool addrinc)
{
{
	int ret;
	int bank_shift = pca953x_bank_shift(chip);
	int addr = (reg & PCAL_GPIO_MASK) << bank_shift;
	int pinctrl = (reg & PCAL_PINCTRL_MASK) << 1;
	u8 regaddr = pinctrl | addr | (off / BANK_SZ);


	ret = i2c_smbus_read_byte_data(chip->client, reg);
	/* Single byte read doesn't need AI bit set. */
	*val = ret;
	if (!addrinc)
		return regaddr;


	return ret;
	/* Chips with 24 and more GPIOs always support Auto Increment */
	if (write && NBANK(chip) > 2)
		regaddr |= REG_ADDR_AI;

	/* PCA9575 needs address-increment on multi-byte writes */
	if (PCA_CHIP_TYPE(chip->driver_data) == PCA957X_TYPE)
		regaddr |= REG_ADDR_AI;

	return regaddr;
}
}


static int pca953x_read_regs_16(struct pca953x_chip *chip, int reg, u8 *val)
static int pca953x_write_regs(struct pca953x_chip *chip, int reg, u8 *val)
{
{
	u8 regaddr = pca953x_recalc_addr(chip, reg, 0, true, true);
	int ret;
	int ret;


	ret = i2c_smbus_read_word_data(chip->client, reg << 1);
	ret = regmap_bulk_write(chip->regmap, regaddr, val, NBANK(chip));
	put_unaligned(ret, (u16 *)val);
	if (ret < 0) {

		dev_err(&chip->client->dev, "failed writing register\n");
		return ret;
		return ret;
	}
	}


static int pca953x_read_regs_24(struct pca953x_chip *chip, int reg, u8 *val)
	return 0;
{
	int bank_shift = fls((chip->gpio_chip.ngpio - 1) / BANK_SZ);
	int addr = (reg & PCAL_GPIO_MASK) << bank_shift;
	int pinctrl = (reg & PCAL_PINCTRL_MASK) << 1;

	return i2c_smbus_read_i2c_block_data(chip->client,
					     pinctrl | addr | REG_ADDR_AI,
					     NBANK(chip), val);
}
}


static int pca953x_read_regs(struct pca953x_chip *chip, int reg, u8 *val)
static int pca953x_read_regs(struct pca953x_chip *chip, int reg, u8 *val)
{
{
	u8 regaddr = pca953x_recalc_addr(chip, reg, 0, false, true);
	int ret;
	int ret;


	ret = chip->read_regs(chip, reg, val);
	ret = regmap_bulk_read(chip->regmap, regaddr, val, NBANK(chip));
	if (ret < 0) {
	if (ret < 0) {
		dev_err(&chip->client->dev, "failed reading register\n");
		dev_err(&chip->client->dev, "failed reading register\n");
		return ret;
		return ret;
@@ -290,18 +355,13 @@ static int pca953x_read_regs(struct pca953x_chip *chip, int reg, u8 *val)
static int pca953x_gpio_direction_input(struct gpio_chip *gc, unsigned off)
static int pca953x_gpio_direction_input(struct gpio_chip *gc, unsigned off)
{
{
	struct pca953x_chip *chip = gpiochip_get_data(gc);
	struct pca953x_chip *chip = gpiochip_get_data(gc);
	u8 reg_val;
	u8 dirreg = pca953x_recalc_addr(chip, chip->regs->direction, off,
					true, false);
	u8 bit = BIT(off % BANK_SZ);
	int ret;
	int ret;


	mutex_lock(&chip->i2c_lock);
	mutex_lock(&chip->i2c_lock);
	reg_val = chip->reg_direction[off / BANK_SZ] | (1u << (off % BANK_SZ));
	ret = regmap_write_bits(chip->regmap, dirreg, bit, bit);

	ret = pca953x_write_single(chip, chip->regs->direction, reg_val, off);
	if (ret)
		goto exit;

	chip->reg_direction[off / BANK_SZ] = reg_val;
exit:
	mutex_unlock(&chip->i2c_lock);
	mutex_unlock(&chip->i2c_lock);
	return ret;
	return ret;
}
}
@@ -310,31 +370,21 @@ static int pca953x_gpio_direction_output(struct gpio_chip *gc,
		unsigned off, int val)
		unsigned off, int val)
{
{
	struct pca953x_chip *chip = gpiochip_get_data(gc);
	struct pca953x_chip *chip = gpiochip_get_data(gc);
	u8 reg_val;
	u8 dirreg = pca953x_recalc_addr(chip, chip->regs->direction, off,
					true, false);
	u8 outreg = pca953x_recalc_addr(chip, chip->regs->output, off,
					true, false);
	u8 bit = BIT(off % BANK_SZ);
	int ret;
	int ret;


	mutex_lock(&chip->i2c_lock);
	mutex_lock(&chip->i2c_lock);
	/* set output level */
	/* set output level */
	if (val)
	ret = regmap_write_bits(chip->regmap, outreg, bit, val ? bit : 0);
		reg_val = chip->reg_output[off / BANK_SZ]
			| (1u << (off % BANK_SZ));
	else
		reg_val = chip->reg_output[off / BANK_SZ]
			& ~(1u << (off % BANK_SZ));

	ret = pca953x_write_single(chip, chip->regs->output, reg_val, off);
	if (ret)
	if (ret)
		goto exit;
		goto exit;


	chip->reg_output[off / BANK_SZ] = reg_val;

	/* then direction */
	/* then direction */
	reg_val = chip->reg_direction[off / BANK_SZ] & ~(1u << (off % BANK_SZ));
	ret = regmap_write_bits(chip->regmap, dirreg, bit, 0);
	ret = pca953x_write_single(chip, chip->regs->direction, reg_val, off);
	if (ret)
		goto exit;

	chip->reg_direction[off / BANK_SZ] = reg_val;
exit:
exit:
	mutex_unlock(&chip->i2c_lock);
	mutex_unlock(&chip->i2c_lock);
	return ret;
	return ret;
@@ -343,11 +393,14 @@ static int pca953x_gpio_direction_output(struct gpio_chip *gc,
static int pca953x_gpio_get_value(struct gpio_chip *gc, unsigned off)
static int pca953x_gpio_get_value(struct gpio_chip *gc, unsigned off)
{
{
	struct pca953x_chip *chip = gpiochip_get_data(gc);
	struct pca953x_chip *chip = gpiochip_get_data(gc);
	u8 inreg = pca953x_recalc_addr(chip, chip->regs->input, off,
				       true, false);
	u8 bit = BIT(off % BANK_SZ);
	u32 reg_val;
	u32 reg_val;
	int ret;
	int ret;


	mutex_lock(&chip->i2c_lock);
	mutex_lock(&chip->i2c_lock);
	ret = pca953x_read_single(chip, chip->regs->input, &reg_val, off);
	ret = regmap_read(chip->regmap, inreg, &reg_val);
	mutex_unlock(&chip->i2c_lock);
	mutex_unlock(&chip->i2c_lock);
	if (ret < 0) {
	if (ret < 0) {
		/* NOTE:  diagnostic already emitted; that's all we should
		/* NOTE:  diagnostic already emitted; that's all we should
@@ -357,45 +410,37 @@ static int pca953x_gpio_get_value(struct gpio_chip *gc, unsigned off)
		return 0;
		return 0;
	}
	}


	return (reg_val & (1u << (off % BANK_SZ))) ? 1 : 0;
	return !!(reg_val & bit);
}
}


static void pca953x_gpio_set_value(struct gpio_chip *gc, unsigned off, int val)
static void pca953x_gpio_set_value(struct gpio_chip *gc, unsigned off, int val)
{
{
	struct pca953x_chip *chip = gpiochip_get_data(gc);
	struct pca953x_chip *chip = gpiochip_get_data(gc);
	u8 reg_val;
	u8 outreg = pca953x_recalc_addr(chip, chip->regs->output, off,
	int ret;
					true, false);
	u8 bit = BIT(off % BANK_SZ);


	mutex_lock(&chip->i2c_lock);
	mutex_lock(&chip->i2c_lock);
	if (val)
	regmap_write_bits(chip->regmap, outreg, bit, val ? bit : 0);
		reg_val = chip->reg_output[off / BANK_SZ]
			| (1u << (off % BANK_SZ));
	else
		reg_val = chip->reg_output[off / BANK_SZ]
			& ~(1u << (off % BANK_SZ));

	ret = pca953x_write_single(chip, chip->regs->output, reg_val, off);
	if (ret)
		goto exit;

	chip->reg_output[off / BANK_SZ] = reg_val;
exit:
	mutex_unlock(&chip->i2c_lock);
	mutex_unlock(&chip->i2c_lock);
}
}


static int pca953x_gpio_get_direction(struct gpio_chip *gc, unsigned off)
static int pca953x_gpio_get_direction(struct gpio_chip *gc, unsigned off)
{
{
	struct pca953x_chip *chip = gpiochip_get_data(gc);
	struct pca953x_chip *chip = gpiochip_get_data(gc);
	u8 dirreg = pca953x_recalc_addr(chip, chip->regs->direction, off,
					true, false);
	u8 bit = BIT(off % BANK_SZ);
	u32 reg_val;
	u32 reg_val;
	int ret;
	int ret;


	mutex_lock(&chip->i2c_lock);
	mutex_lock(&chip->i2c_lock);
	ret = pca953x_read_single(chip, chip->regs->direction, &reg_val, off);
	ret = regmap_read(chip->regmap, dirreg, &reg_val);
	mutex_unlock(&chip->i2c_lock);
	mutex_unlock(&chip->i2c_lock);
	if (ret < 0)
	if (ret < 0)
		return ret;
		return ret;


	return !!(reg_val & (1u << (off % BANK_SZ)));
	return !!(reg_val & bit);
}
}


static void pca953x_gpio_set_multiple(struct gpio_chip *gc,
static void pca953x_gpio_set_multiple(struct gpio_chip *gc,
@@ -403,14 +448,15 @@ static void pca953x_gpio_set_multiple(struct gpio_chip *gc,
{
{
	struct pca953x_chip *chip = gpiochip_get_data(gc);
	struct pca953x_chip *chip = gpiochip_get_data(gc);
	unsigned int bank_mask, bank_val;
	unsigned int bank_mask, bank_val;
	int bank_shift, bank;
	int bank;
	u8 reg_val[MAX_BANK];
	u8 reg_val[MAX_BANK];
	int ret;
	int ret;


	bank_shift = fls((chip->gpio_chip.ngpio - 1) / BANK_SZ);

	mutex_lock(&chip->i2c_lock);
	mutex_lock(&chip->i2c_lock);
	memcpy(reg_val, chip->reg_output, NBANK(chip));
	ret = pca953x_read_regs(chip, chip->regs->output, reg_val);
	if (ret)
		goto exit;

	for (bank = 0; bank < NBANK(chip); bank++) {
	for (bank = 0; bank < NBANK(chip); bank++) {
		bank_mask = mask[bank / sizeof(*mask)] >>
		bank_mask = mask[bank / sizeof(*mask)] >>
			   ((bank % sizeof(*mask)) * 8);
			   ((bank % sizeof(*mask)) * 8);
@@ -422,13 +468,7 @@ static void pca953x_gpio_set_multiple(struct gpio_chip *gc,
		}
		}
	}
	}


	ret = i2c_smbus_write_i2c_block_data(chip->client,
	pca953x_write_regs(chip, chip->regs->output, reg_val);
					     chip->regs->output << bank_shift,
					     NBANK(chip), reg_val);
	if (ret)
		goto exit;

	memcpy(chip->reg_output, reg_val, NBANK(chip));
exit:
exit:
	mutex_unlock(&chip->i2c_lock);
	mutex_unlock(&chip->i2c_lock);
}
}
@@ -487,6 +527,10 @@ static void pca953x_irq_bus_sync_unlock(struct irq_data *d)
	u8 new_irqs;
	u8 new_irqs;
	int level, i;
	int level, i;
	u8 invert_irq_mask[MAX_BANK];
	u8 invert_irq_mask[MAX_BANK];
	int reg_direction[MAX_BANK];

	regmap_bulk_read(chip->regmap, chip->regs->direction, reg_direction,
			 NBANK(chip));


	if (chip->driver_data & PCA_PCAL) {
	if (chip->driver_data & PCA_PCAL) {
		/* Enable latch on interrupt-enabled inputs */
		/* Enable latch on interrupt-enabled inputs */
@@ -502,7 +546,7 @@ static void pca953x_irq_bus_sync_unlock(struct irq_data *d)
	/* Look for any newly setup interrupt */
	/* Look for any newly setup interrupt */
	for (i = 0; i < NBANK(chip); i++) {
	for (i = 0; i < NBANK(chip); i++) {
		new_irqs = chip->irq_trig_fall[i] | chip->irq_trig_raise[i];
		new_irqs = chip->irq_trig_fall[i] | chip->irq_trig_raise[i];
		new_irqs &= ~chip->reg_direction[i];
		new_irqs &= reg_direction[i];


		while (new_irqs) {
		while (new_irqs) {
			level = __ffs(new_irqs);
			level = __ffs(new_irqs);
@@ -567,6 +611,7 @@ static bool pca953x_irq_pending(struct pca953x_chip *chip, u8 *pending)
	bool pending_seen = false;
	bool pending_seen = false;
	bool trigger_seen = false;
	bool trigger_seen = false;
	u8 trigger[MAX_BANK];
	u8 trigger[MAX_BANK];
	int reg_direction[MAX_BANK];
	int ret, i;
	int ret, i;


	if (chip->driver_data & PCA_PCAL) {
	if (chip->driver_data & PCA_PCAL) {
@@ -597,8 +642,10 @@ static bool pca953x_irq_pending(struct pca953x_chip *chip, u8 *pending)
		return false;
		return false;


	/* Remove output pins from the equation */
	/* Remove output pins from the equation */
	regmap_bulk_read(chip->regmap, chip->regs->direction, reg_direction,
			 NBANK(chip));
	for (i = 0; i < NBANK(chip); i++)
	for (i = 0; i < NBANK(chip); i++)
		cur_stat[i] &= chip->reg_direction[i];
		cur_stat[i] &= reg_direction[i];


	memcpy(old_stat, chip->irq_stat, NBANK(chip));
	memcpy(old_stat, chip->irq_stat, NBANK(chip));


@@ -652,6 +699,7 @@ static int pca953x_irq_setup(struct pca953x_chip *chip,
			     int irq_base)
			     int irq_base)
{
{
	struct i2c_client *client = chip->client;
	struct i2c_client *client = chip->client;
	int reg_direction[MAX_BANK];
	int ret, i;
	int ret, i;


	if (client->irq && irq_base != -1
	if (client->irq && irq_base != -1
@@ -666,8 +714,10 @@ static int pca953x_irq_setup(struct pca953x_chip *chip,
		 * interrupt.  We have to rely on the previous read for
		 * interrupt.  We have to rely on the previous read for
		 * this purpose.
		 * this purpose.
		 */
		 */
		regmap_bulk_read(chip->regmap, chip->regs->direction,
				 reg_direction, NBANK(chip));
		for (i = 0; i < NBANK(chip); i++)
		for (i = 0; i < NBANK(chip); i++)
			chip->irq_stat[i] &= chip->reg_direction[i];
			chip->irq_stat[i] &= reg_direction[i];
		mutex_init(&chip->irq_lock);
		mutex_init(&chip->irq_lock);


		ret = devm_request_threaded_irq(&client->dev,
		ret = devm_request_threaded_irq(&client->dev,
@@ -715,20 +765,19 @@ static int pca953x_irq_setup(struct pca953x_chip *chip,
}
}
#endif
#endif


static int device_pca953x_init(struct pca953x_chip *chip, u32 invert)
static int device_pca95xx_init(struct pca953x_chip *chip, u32 invert)
{
{
	int ret;
	int ret;
	u8 val[MAX_BANK];
	u8 val[MAX_BANK];


	chip->regs = &pca953x_regs;
	ret = regcache_sync_region(chip->regmap, chip->regs->output,

				   chip->regs->output + NBANK(chip));
	ret = pca953x_read_regs(chip, chip->regs->output, chip->reg_output);
	if (ret != 0)
	if (ret)
		goto out;
		goto out;


	ret = pca953x_read_regs(chip, chip->regs->direction,
	ret = regcache_sync_region(chip->regmap, chip->regs->direction,
				chip->reg_direction);
				   chip->regs->direction + NBANK(chip));
	if (ret)
	if (ret != 0)
		goto out;
		goto out;


	/* set platform specific polarity inversion */
	/* set platform specific polarity inversion */
@@ -737,7 +786,7 @@ static int device_pca953x_init(struct pca953x_chip *chip, u32 invert)
	else
	else
		memset(val, 0, NBANK(chip));
		memset(val, 0, NBANK(chip));


	ret = pca953x_write_regs(chip, PCA953X_INVERT, val);
	ret = pca953x_write_regs(chip, chip->regs->invert, val);
out:
out:
	return ret;
	return ret;
}
}
@@ -747,22 +796,7 @@ static int device_pca957x_init(struct pca953x_chip *chip, u32 invert)
	int ret;
	int ret;
	u8 val[MAX_BANK];
	u8 val[MAX_BANK];


	chip->regs = &pca957x_regs;
	ret = device_pca95xx_init(chip, invert);

	ret = pca953x_read_regs(chip, chip->regs->output, chip->reg_output);
	if (ret)
		goto out;
	ret = pca953x_read_regs(chip, chip->regs->direction,
				chip->reg_direction);
	if (ret)
		goto out;

	/* set platform specific polarity inversion */
	if (invert)
		memset(val, 0xFF, NBANK(chip));
	else
		memset(val, 0, NBANK(chip));
	ret = pca953x_write_regs(chip, PCA957X_INVRT, val);
	if (ret)
	if (ret)
		goto out;
		goto out;


@@ -853,6 +887,16 @@ static int pca953x_probe(struct i2c_client *client,
		}
		}
	}
	}


	i2c_set_clientdata(client, chip);

	chip->regmap = devm_regmap_init_i2c(client, &pca953x_i2c_regmap);
	if (IS_ERR(chip->regmap)) {
		ret = PTR_ERR(chip->regmap);
		goto err_exit;
	}

	regcache_mark_dirty(chip->regmap);

	mutex_init(&chip->i2c_lock);
	mutex_init(&chip->i2c_lock);
	/*
	/*
	 * In case we have an i2c-mux controlled by a GPIO provided by an
	 * In case we have an i2c-mux controlled by a GPIO provided by an
@@ -878,24 +922,13 @@ static int pca953x_probe(struct i2c_client *client,
	 */
	 */
	pca953x_setup_gpio(chip, chip->driver_data & PCA_GPIO_MASK);
	pca953x_setup_gpio(chip, chip->driver_data & PCA_GPIO_MASK);


	if (chip->gpio_chip.ngpio <= 8) {
	if (PCA_CHIP_TYPE(chip->driver_data) == PCA953X_TYPE) {
		chip->write_regs = pca953x_write_regs_8;
		chip->regs = &pca953x_regs;
		chip->read_regs = pca953x_read_regs_8;
		ret = device_pca95xx_init(chip, invert);
	} else if (chip->gpio_chip.ngpio >= 24) {
		chip->write_regs = pca953x_write_regs_24;
		chip->read_regs = pca953x_read_regs_24;
	} else {
	} else {
		if (PCA_CHIP_TYPE(chip->driver_data) == PCA953X_TYPE)
		chip->regs = &pca957x_regs;
			chip->write_regs = pca953x_write_regs_16;
		else
			chip->write_regs = pca957x_write_regs_16;
		chip->read_regs = pca953x_read_regs_16;
	}

	if (PCA_CHIP_TYPE(chip->driver_data) == PCA953X_TYPE)
		ret = device_pca953x_init(chip, invert);
	else
		ret = device_pca957x_init(chip, invert);
		ret = device_pca957x_init(chip, invert);
	}
	if (ret)
	if (ret)
		goto err_exit;
		goto err_exit;


@@ -914,7 +947,6 @@ static int pca953x_probe(struct i2c_client *client,
			dev_warn(&client->dev, "setup failed, %d\n", ret);
			dev_warn(&client->dev, "setup failed, %d\n", ret);
	}
	}


	i2c_set_clientdata(client, chip);
	return 0;
	return 0;


err_exit:
err_exit:
@@ -943,6 +975,91 @@ static int pca953x_remove(struct i2c_client *client)
	return ret;
	return ret;
}
}


#ifdef CONFIG_PM_SLEEP
static int pca953x_regcache_sync(struct device *dev)
{
	struct pca953x_chip *chip = dev_get_drvdata(dev);
	int ret;

	/*
	 * The ordering between direction and output is important,
	 * sync these registers first and only then sync the rest.
	 */
	ret = regcache_sync_region(chip->regmap, chip->regs->direction,
				   chip->regs->direction + NBANK(chip));
	if (ret != 0) {
		dev_err(dev, "Failed to sync GPIO dir registers: %d\n", ret);
		return ret;
	}

	ret = regcache_sync_region(chip->regmap, chip->regs->output,
				   chip->regs->output + NBANK(chip));
	if (ret != 0) {
		dev_err(dev, "Failed to sync GPIO out registers: %d\n", ret);
		return ret;
	}

#ifdef CONFIG_GPIO_PCA953X_IRQ
	if (chip->driver_data & PCA_PCAL) {
		ret = regcache_sync_region(chip->regmap, PCAL953X_IN_LATCH,
					   PCAL953X_IN_LATCH + NBANK(chip));
		if (ret != 0) {
			dev_err(dev, "Failed to sync INT latch registers: %d\n",
				ret);
			return ret;
		}

		ret = regcache_sync_region(chip->regmap, PCAL953X_INT_MASK,
					   PCAL953X_INT_MASK + NBANK(chip));
		if (ret != 0) {
			dev_err(dev, "Failed to sync INT mask registers: %d\n",
				ret);
			return ret;
		}
	}
#endif

	return 0;
}

static int pca953x_suspend(struct device *dev)
{
	struct pca953x_chip *chip = dev_get_drvdata(dev);

	regcache_cache_only(chip->regmap, true);

	regulator_disable(chip->regulator);

	return 0;
}

static int pca953x_resume(struct device *dev)
{
	struct pca953x_chip *chip = dev_get_drvdata(dev);
	int ret;

	ret = regulator_enable(chip->regulator);
	if (ret != 0) {
		dev_err(dev, "Failed to enable regulator: %d\n", ret);
		return 0;
	}

	regcache_cache_only(chip->regmap, false);
	regcache_mark_dirty(chip->regmap);
	ret = pca953x_regcache_sync(dev);
	if (ret)
		return ret;

	ret = regcache_sync(chip->regmap);
	if (ret != 0) {
		dev_err(dev, "Failed to restore register map: %d\n", ret);
		return ret;
	}

	return 0;
}
#endif

/* convenience to stop overlong match-table lines */
/* convenience to stop overlong match-table lines */
#define OF_953X(__nrgpio, __int) (void *)(__nrgpio | PCA953X_TYPE | __int)
#define OF_953X(__nrgpio, __int) (void *)(__nrgpio | PCA953X_TYPE | __int)
#define OF_957X(__nrgpio, __int) (void *)(__nrgpio | PCA957X_TYPE | __int)
#define OF_957X(__nrgpio, __int) (void *)(__nrgpio | PCA957X_TYPE | __int)
@@ -986,9 +1103,12 @@ static const struct of_device_id pca953x_dt_ids[] = {


MODULE_DEVICE_TABLE(of, pca953x_dt_ids);
MODULE_DEVICE_TABLE(of, pca953x_dt_ids);


static SIMPLE_DEV_PM_OPS(pca953x_pm_ops, pca953x_suspend, pca953x_resume);

static struct i2c_driver pca953x_driver = {
static struct i2c_driver pca953x_driver = {
	.driver = {
	.driver = {
		.name	= "pca953x",
		.name	= "pca953x",
		.pm	= &pca953x_pm_ops,
		.of_match_table = pca953x_dt_ids,
		.of_match_table = pca953x_dt_ids,
		.acpi_match_table = ACPI_PTR(pca953x_acpi_ids),
		.acpi_match_table = ACPI_PTR(pca953x_acpi_ids),
	},
	},