gpio: pca953x: Zap ad-hoc reg_direction cache
Replace the ad-hoc reg_direction direction register caching with generic regcache cache. This reduces code duplication. Signed-off-by: Marek Vasut <marek.vasut+renesas@gmail.com> Cc: Bartosz Golaszewski <bgolaszewski@baylibre.com> Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
This commit is contained in:
parent
4942723276
commit
0f25fda840
1 changed files with 31 additions and 24 deletions
|
@ -142,7 +142,6 @@ static const struct pca953x_reg_config pca957x_regs = {
|
||||||
struct pca953x_chip {
|
struct pca953x_chip {
|
||||||
unsigned gpio_start;
|
unsigned gpio_start;
|
||||||
u8 reg_output[MAX_BANK];
|
u8 reg_output[MAX_BANK];
|
||||||
u8 reg_direction[MAX_BANK];
|
|
||||||
struct mutex i2c_lock;
|
struct mutex i2c_lock;
|
||||||
struct regmap *regmap;
|
struct regmap *regmap;
|
||||||
|
|
||||||
|
@ -387,18 +386,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;
|
||||||
}
|
}
|
||||||
|
@ -407,6 +401,9 @@ 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 dirreg = pca953x_recalc_addr(chip, chip->regs->direction, off,
|
||||||
|
true, false);
|
||||||
|
u8 bit = BIT(off % BANK_SZ);
|
||||||
u8 reg_val;
|
u8 reg_val;
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
|
@ -426,12 +423,7 @@ static int pca953x_gpio_direction_output(struct gpio_chip *gc,
|
||||||
chip->reg_output[off / BANK_SZ] = reg_val;
|
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;
|
||||||
|
@ -483,16 +475,19 @@ exit:
|
||||||
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, ®_val, off);
|
ret = regmap_read(chip->regmap, dirreg, ®_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,
|
||||||
|
@ -580,6 +575,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 */
|
||||||
|
@ -595,7 +594,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);
|
||||||
|
@ -660,6 +659,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) {
|
||||||
|
@ -690,8 +690,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));
|
||||||
|
|
||||||
|
@ -745,6 +747,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
|
||||||
|
@ -759,8 +762,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,
|
||||||
|
@ -817,9 +822,9 @@ static int device_pca95xx_init(struct pca953x_chip *chip, u32 invert)
|
||||||
if (ret)
|
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 */
|
||||||
|
@ -937,6 +942,8 @@ static int pca953x_probe(struct i2c_client *client,
|
||||||
goto err_exit;
|
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
|
||||||
|
|
Loading…
Add table
Reference in a new issue