struct pca953x_chip {
unsigned gpio_start;
u8 reg_output[MAX_BANK];
- u8 reg_direction[MAX_BANK];
struct mutex i2c_lock;
struct regmap *regmap;
static int pca953x_gpio_direction_input(struct gpio_chip *gc, unsigned off)
{
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;
mutex_lock(&chip->i2c_lock);
- reg_val = chip->reg_direction[off / BANK_SZ] | (1u << (off % BANK_SZ));
-
- ret = pca953x_write_single(chip, chip->regs->direction, reg_val, off);
- if (ret)
- goto exit;
-
- chip->reg_direction[off / BANK_SZ] = reg_val;
-exit:
+ ret = regmap_write_bits(chip->regmap, dirreg, bit, bit);
mutex_unlock(&chip->i2c_lock);
return ret;
}
unsigned off, int val)
{
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);
u8 reg_val;
int ret;
chip->reg_output[off / BANK_SZ] = reg_val;
/* then direction */
- reg_val = chip->reg_direction[off / BANK_SZ] & ~(1u << (off % BANK_SZ));
- ret = pca953x_write_single(chip, chip->regs->direction, reg_val, off);
- if (ret)
- goto exit;
-
- chip->reg_direction[off / BANK_SZ] = reg_val;
+ ret = regmap_write_bits(chip->regmap, dirreg, bit, 0);
exit:
mutex_unlock(&chip->i2c_lock);
return ret;
static int pca953x_gpio_get_direction(struct gpio_chip *gc, unsigned off)
{
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;
int ret;
mutex_lock(&chip->i2c_lock);
- ret = pca953x_read_single(chip, chip->regs->direction, ®_val, off);
+ ret = regmap_read(chip->regmap, dirreg, ®_val);
mutex_unlock(&chip->i2c_lock);
if (ret < 0)
return ret;
- return !!(reg_val & (1u << (off % BANK_SZ)));
+ return !!(reg_val & bit);
}
static void pca953x_gpio_set_multiple(struct gpio_chip *gc,
u8 new_irqs;
int level, i;
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) {
/* Enable latch on interrupt-enabled inputs */
/* Look for any newly setup interrupt */
for (i = 0; i < NBANK(chip); 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) {
level = __ffs(new_irqs);
bool pending_seen = false;
bool trigger_seen = false;
u8 trigger[MAX_BANK];
+ int reg_direction[MAX_BANK];
int ret, i;
if (chip->driver_data & PCA_PCAL) {
return false;
/* 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++)
- cur_stat[i] &= chip->reg_direction[i];
+ cur_stat[i] &= reg_direction[i];
memcpy(old_stat, chip->irq_stat, NBANK(chip));
int irq_base)
{
struct i2c_client *client = chip->client;
+ int reg_direction[MAX_BANK];
int ret, i;
if (client->irq && irq_base != -1
* interrupt. We have to rely on the previous read for
* this purpose.
*/
+ regmap_bulk_read(chip->regmap, chip->regs->direction,
+ reg_direction, NBANK(chip));
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);
ret = devm_request_threaded_irq(&client->dev,
if (ret)
goto out;
- ret = pca953x_read_regs(chip, chip->regs->direction,
- chip->reg_direction);
- if (ret)
+ ret = regcache_sync_region(chip->regmap, chip->regs->direction,
+ chip->regs->direction + NBANK(chip));
+ if (ret != 0)
goto out;
/* set platform specific polarity inversion */
goto err_exit;
}
+ regcache_mark_dirty(chip->regmap);
+
mutex_init(&chip->i2c_lock);
/*
* In case we have an i2c-mux controlled by a GPIO provided by an