Commit 53661f3b authored by Bartosz Golaszewski's avatar Bartosz Golaszewski Committed by Linus Walleij

gpio: pca953x: code shrink

There are multiple places in the driver code where a
switch (chip->chip_type) is used to determine the proper register
offset.

Unduplicate the code by adding a simple structure holding the possible
offsets that differ between the pca953x and pca957x chip families and
use it to avoid the checks.
Signed-off-by: default avatarBartosz Golaszewski <bgolaszewski@baylibre.com>
Reviewed-by: default avatarAndy Shevchenko <andriy.shevchenko@linux.intel.com>
Signed-off-by: default avatarLinus Walleij <linus.walleij@linaro.org>
parent 14bf873e
...@@ -95,6 +95,24 @@ MODULE_DEVICE_TABLE(acpi, pca953x_acpi_ids); ...@@ -95,6 +95,24 @@ MODULE_DEVICE_TABLE(acpi, pca953x_acpi_ids);
#define NBANK(chip) DIV_ROUND_UP(chip->gpio_chip.ngpio, BANK_SZ) #define NBANK(chip) DIV_ROUND_UP(chip->gpio_chip.ngpio, BANK_SZ)
struct pca953x_reg_config {
int direction;
int output;
int input;
};
static const struct pca953x_reg_config pca953x_regs = {
.direction = PCA953X_DIRECTION,
.output = PCA953X_OUTPUT,
.input = PCA953X_INPUT,
};
static const struct pca953x_reg_config pca957x_regs = {
.direction = PCA957X_CFG,
.output = PCA957X_OUT,
.input = PCA957X_IN,
};
struct pca953x_chip { struct pca953x_chip {
unsigned gpio_start; unsigned gpio_start;
u8 reg_output[MAX_BANK]; u8 reg_output[MAX_BANK];
...@@ -115,6 +133,8 @@ struct pca953x_chip { ...@@ -115,6 +133,8 @@ struct pca953x_chip {
int chip_type; int chip_type;
unsigned long driver_data; unsigned long driver_data;
struct regulator *regulator; struct regulator *regulator;
const struct pca953x_reg_config *regs;
}; };
static int pca953x_read_single(struct pca953x_chip *chip, int reg, u32 *val, static int pca953x_read_single(struct pca953x_chip *chip, int reg, u32 *val,
...@@ -224,20 +244,12 @@ static int pca953x_gpio_direction_input(struct gpio_chip *gc, unsigned off) ...@@ -224,20 +244,12 @@ 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 reg_val;
int ret, offset = 0; int ret;
mutex_lock(&chip->i2c_lock); mutex_lock(&chip->i2c_lock);
reg_val = chip->reg_direction[off / BANK_SZ] | (1u << (off % BANK_SZ)); reg_val = chip->reg_direction[off / BANK_SZ] | (1u << (off % BANK_SZ));
switch (chip->chip_type) { ret = pca953x_write_single(chip, chip->regs->direction, reg_val, off);
case PCA953X_TYPE:
offset = PCA953X_DIRECTION;
break;
case PCA957X_TYPE:
offset = PCA957X_CFG;
break;
}
ret = pca953x_write_single(chip, offset, reg_val, off);
if (ret) if (ret)
goto exit; goto exit;
...@@ -252,7 +264,7 @@ static int pca953x_gpio_direction_output(struct gpio_chip *gc, ...@@ -252,7 +264,7 @@ static int pca953x_gpio_direction_output(struct gpio_chip *gc,
{ {
struct pca953x_chip *chip = gpiochip_get_data(gc); struct pca953x_chip *chip = gpiochip_get_data(gc);
u8 reg_val; u8 reg_val;
int ret, offset = 0; int ret;
mutex_lock(&chip->i2c_lock); mutex_lock(&chip->i2c_lock);
/* set output level */ /* set output level */
...@@ -263,15 +275,7 @@ static int pca953x_gpio_direction_output(struct gpio_chip *gc, ...@@ -263,15 +275,7 @@ static int pca953x_gpio_direction_output(struct gpio_chip *gc,
reg_val = chip->reg_output[off / BANK_SZ] reg_val = chip->reg_output[off / BANK_SZ]
& ~(1u << (off % BANK_SZ)); & ~(1u << (off % BANK_SZ));
switch (chip->chip_type) { ret = pca953x_write_single(chip, chip->regs->output, reg_val, off);
case PCA953X_TYPE:
offset = PCA953X_OUTPUT;
break;
case PCA957X_TYPE:
offset = PCA957X_OUT;
break;
}
ret = pca953x_write_single(chip, offset, reg_val, off);
if (ret) if (ret)
goto exit; goto exit;
...@@ -279,15 +283,7 @@ static int pca953x_gpio_direction_output(struct gpio_chip *gc, ...@@ -279,15 +283,7 @@ static int pca953x_gpio_direction_output(struct gpio_chip *gc,
/* then direction */ /* then direction */
reg_val = chip->reg_direction[off / BANK_SZ] & ~(1u << (off % BANK_SZ)); reg_val = chip->reg_direction[off / BANK_SZ] & ~(1u << (off % BANK_SZ));
switch (chip->chip_type) { ret = pca953x_write_single(chip, chip->regs->direction, reg_val, off);
case PCA953X_TYPE:
offset = PCA953X_DIRECTION;
break;
case PCA957X_TYPE:
offset = PCA957X_CFG;
break;
}
ret = pca953x_write_single(chip, offset, reg_val, off);
if (ret) if (ret)
goto exit; goto exit;
...@@ -301,18 +297,10 @@ static int pca953x_gpio_get_value(struct gpio_chip *gc, unsigned off) ...@@ -301,18 +297,10 @@ 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);
u32 reg_val; u32 reg_val;
int ret, offset = 0; int ret;
mutex_lock(&chip->i2c_lock); mutex_lock(&chip->i2c_lock);
switch (chip->chip_type) { ret = pca953x_read_single(chip, chip->regs->input, &reg_val, off);
case PCA953X_TYPE:
offset = PCA953X_INPUT;
break;
case PCA957X_TYPE:
offset = PCA957X_IN;
break;
}
ret = pca953x_read_single(chip, offset, &reg_val, off);
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
...@@ -329,7 +317,7 @@ static void pca953x_gpio_set_value(struct gpio_chip *gc, unsigned off, int val) ...@@ -329,7 +317,7 @@ 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 reg_val;
int ret, offset = 0; int ret;
mutex_lock(&chip->i2c_lock); mutex_lock(&chip->i2c_lock);
if (val) if (val)
...@@ -339,15 +327,7 @@ static void pca953x_gpio_set_value(struct gpio_chip *gc, unsigned off, int val) ...@@ -339,15 +327,7 @@ static void pca953x_gpio_set_value(struct gpio_chip *gc, unsigned off, int val)
reg_val = chip->reg_output[off / BANK_SZ] reg_val = chip->reg_output[off / BANK_SZ]
& ~(1u << (off % BANK_SZ)); & ~(1u << (off % BANK_SZ));
switch (chip->chip_type) { ret = pca953x_write_single(chip, chip->regs->output, reg_val, off);
case PCA953X_TYPE:
offset = PCA953X_OUTPUT;
break;
case PCA957X_TYPE:
offset = PCA957X_OUT;
break;
}
ret = pca953x_write_single(chip, offset, reg_val, off);
if (ret) if (ret)
goto exit; goto exit;
...@@ -361,19 +341,10 @@ static void pca953x_gpio_set_multiple(struct gpio_chip *gc, ...@@ -361,19 +341,10 @@ 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);
u8 reg_val[MAX_BANK]; u8 reg_val[MAX_BANK];
int ret, offset = 0; int ret;
int bank_shift = fls((chip->gpio_chip.ngpio - 1) / BANK_SZ); int bank_shift = fls((chip->gpio_chip.ngpio - 1) / BANK_SZ);
int bank; int bank;
switch (chip->chip_type) {
case PCA953X_TYPE:
offset = PCA953X_OUTPUT;
break;
case PCA957X_TYPE:
offset = PCA957X_OUT;
break;
}
memcpy(reg_val, chip->reg_output, NBANK(chip)); memcpy(reg_val, chip->reg_output, NBANK(chip));
mutex_lock(&chip->i2c_lock); mutex_lock(&chip->i2c_lock);
for(bank=0; bank<NBANK(chip); bank++) { for(bank=0; bank<NBANK(chip); bank++) {
...@@ -385,7 +356,9 @@ static void pca953x_gpio_set_multiple(struct gpio_chip *gc, ...@@ -385,7 +356,9 @@ static void pca953x_gpio_set_multiple(struct gpio_chip *gc,
reg_val[bank] = (reg_val[bank] & ~bankmask) | bankval; reg_val[bank] = (reg_val[bank] & ~bankmask) | bankval;
} }
} }
ret = i2c_smbus_write_i2c_block_data(chip->client, offset << bank_shift, NBANK(chip), reg_val); ret = i2c_smbus_write_i2c_block_data(chip->client,
chip->regs->output << bank_shift,
NBANK(chip), reg_val);
if (ret) if (ret)
goto exit; goto exit;
...@@ -517,7 +490,7 @@ static bool pca953x_irq_pending(struct pca953x_chip *chip, u8 *pending) ...@@ -517,7 +490,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 ret, i, offset = 0; int ret, i;
if (chip->driver_data & PCA_PCAL) { if (chip->driver_data & PCA_PCAL) {
/* Read the current interrupt status from the device */ /* Read the current interrupt status from the device */
...@@ -542,15 +515,7 @@ static bool pca953x_irq_pending(struct pca953x_chip *chip, u8 *pending) ...@@ -542,15 +515,7 @@ static bool pca953x_irq_pending(struct pca953x_chip *chip, u8 *pending)
return pending_seen; return pending_seen;
} }
switch (chip->chip_type) { ret = pca953x_read_regs(chip, chip->regs->input, cur_stat);
case PCA953X_TYPE:
offset = PCA953X_INPUT;
break;
case PCA957X_TYPE:
offset = PCA957X_IN;
break;
}
ret = pca953x_read_regs(chip, offset, cur_stat);
if (ret) if (ret)
return false; return false;
...@@ -610,20 +575,13 @@ static int pca953x_irq_setup(struct pca953x_chip *chip, ...@@ -610,20 +575,13 @@ 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 ret, i, offset = 0; int ret, i;
if (client->irq && irq_base != -1 if (client->irq && irq_base != -1
&& (chip->driver_data & PCA_INT)) { && (chip->driver_data & PCA_INT)) {
switch (chip->chip_type) { ret = pca953x_read_regs(chip,
case PCA953X_TYPE: chip->regs->input, chip->irq_stat);
offset = PCA953X_INPUT;
break;
case PCA957X_TYPE:
offset = PCA957X_IN;
break;
}
ret = pca953x_read_regs(chip, offset, chip->irq_stat);
if (ret) if (ret)
return ret; return ret;
...@@ -686,12 +644,14 @@ static int device_pca953x_init(struct pca953x_chip *chip, u32 invert) ...@@ -686,12 +644,14 @@ static int device_pca953x_init(struct pca953x_chip *chip, u32 invert)
int ret; int ret;
u8 val[MAX_BANK]; u8 val[MAX_BANK];
ret = pca953x_read_regs(chip, PCA953X_OUTPUT, chip->reg_output); chip->regs = &pca953x_regs;
ret = pca953x_read_regs(chip, chip->regs->output, chip->reg_output);
if (ret) if (ret)
goto out; goto out;
ret = pca953x_read_regs(chip, PCA953X_DIRECTION, ret = pca953x_read_regs(chip, chip->regs->direction,
chip->reg_direction); chip->reg_direction);
if (ret) if (ret)
goto out; goto out;
...@@ -711,10 +671,13 @@ static int device_pca957x_init(struct pca953x_chip *chip, u32 invert) ...@@ -711,10 +671,13 @@ static int device_pca957x_init(struct pca953x_chip *chip, u32 invert)
int ret; int ret;
u8 val[MAX_BANK]; u8 val[MAX_BANK];
ret = pca953x_read_regs(chip, PCA957X_OUT, chip->reg_output); chip->regs = &pca957x_regs;
ret = pca953x_read_regs(chip, chip->regs->output, chip->reg_output);
if (ret) if (ret)
goto out; goto out;
ret = pca953x_read_regs(chip, PCA957X_CFG, chip->reg_direction); ret = pca953x_read_regs(chip, chip->regs->direction,
chip->reg_direction);
if (ret) if (ret)
goto out; goto out;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment