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