summaryrefslogtreecommitdiff
path: root/drivers/input/keyboard/adp5589-keys.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/input/keyboard/adp5589-keys.c')
-rw-r--r--drivers/input/keyboard/adp5589-keys.c61
1 files changed, 31 insertions, 30 deletions
diff --git a/drivers/input/keyboard/adp5589-keys.c b/drivers/input/keyboard/adp5589-keys.c
index 8996e00cd63a..81d0876ee358 100644
--- a/drivers/input/keyboard/adp5589-keys.c
+++ b/drivers/input/keyboard/adp5589-keys.c
@@ -391,10 +391,17 @@ static int adp5589_gpio_get_value(struct gpio_chip *chip, unsigned off)
struct adp5589_kpad *kpad = gpiochip_get_data(chip);
unsigned int bank = kpad->var->bank(kpad->gpiomap[off]);
unsigned int bit = kpad->var->bit(kpad->gpiomap[off]);
+ int val;
- return !!(adp5589_read(kpad->client,
- kpad->var->reg(ADP5589_GPI_STATUS_A) + bank) &
- bit);
+ mutex_lock(&kpad->gpio_lock);
+ if (kpad->dir[bank] & bit)
+ val = kpad->dat_out[bank];
+ else
+ val = adp5589_read(kpad->client,
+ kpad->var->reg(ADP5589_GPI_STATUS_A) + bank);
+ mutex_unlock(&kpad->gpio_lock);
+
+ return !!(val & bit);
}
static void adp5589_gpio_set_value(struct gpio_chip *chip,
@@ -404,7 +411,7 @@ static void adp5589_gpio_set_value(struct gpio_chip *chip,
unsigned int bank = kpad->var->bank(kpad->gpiomap[off]);
unsigned int bit = kpad->var->bit(kpad->gpiomap[off]);
- mutex_lock(&kpad->gpio_lock);
+ guard(mutex)(&kpad->gpio_lock);
if (val)
kpad->dat_out[bank] |= bit;
@@ -413,8 +420,6 @@ static void adp5589_gpio_set_value(struct gpio_chip *chip,
adp5589_write(kpad->client, kpad->var->reg(ADP5589_GPO_DATA_OUT_A) +
bank, kpad->dat_out[bank]);
-
- mutex_unlock(&kpad->gpio_lock);
}
static int adp5589_gpio_direction_input(struct gpio_chip *chip, unsigned off)
@@ -422,18 +427,13 @@ static int adp5589_gpio_direction_input(struct gpio_chip *chip, unsigned off)
struct adp5589_kpad *kpad = gpiochip_get_data(chip);
unsigned int bank = kpad->var->bank(kpad->gpiomap[off]);
unsigned int bit = kpad->var->bit(kpad->gpiomap[off]);
- int ret;
- mutex_lock(&kpad->gpio_lock);
+ guard(mutex)(&kpad->gpio_lock);
kpad->dir[bank] &= ~bit;
- ret = adp5589_write(kpad->client,
- kpad->var->reg(ADP5589_GPIO_DIRECTION_A) + bank,
- kpad->dir[bank]);
-
- mutex_unlock(&kpad->gpio_lock);
-
- return ret;
+ return adp5589_write(kpad->client,
+ kpad->var->reg(ADP5589_GPIO_DIRECTION_A) + bank,
+ kpad->dir[bank]);
}
static int adp5589_gpio_direction_output(struct gpio_chip *chip,
@@ -442,9 +442,9 @@ static int adp5589_gpio_direction_output(struct gpio_chip *chip,
struct adp5589_kpad *kpad = gpiochip_get_data(chip);
unsigned int bank = kpad->var->bank(kpad->gpiomap[off]);
unsigned int bit = kpad->var->bit(kpad->gpiomap[off]);
- int ret;
+ int error;
- mutex_lock(&kpad->gpio_lock);
+ guard(mutex)(&kpad->gpio_lock);
kpad->dir[bank] |= bit;
@@ -453,15 +453,19 @@ static int adp5589_gpio_direction_output(struct gpio_chip *chip,
else
kpad->dat_out[bank] &= ~bit;
- ret = adp5589_write(kpad->client, kpad->var->reg(ADP5589_GPO_DATA_OUT_A)
- + bank, kpad->dat_out[bank]);
- ret |= adp5589_write(kpad->client,
- kpad->var->reg(ADP5589_GPIO_DIRECTION_A) + bank,
- kpad->dir[bank]);
+ error = adp5589_write(kpad->client,
+ kpad->var->reg(ADP5589_GPO_DATA_OUT_A) + bank,
+ kpad->dat_out[bank]);
+ if (error)
+ return error;
- mutex_unlock(&kpad->gpio_lock);
+ error = adp5589_write(kpad->client,
+ kpad->var->reg(ADP5589_GPIO_DIRECTION_A) + bank,
+ kpad->dir[bank]);
+ if (error)
+ return error;
- return ret;
+ return 0;
}
static int adp5589_build_gpiomap(struct adp5589_kpad *kpad,
@@ -936,10 +940,9 @@ static int adp5589_keypad_add(struct adp5589_kpad *kpad, unsigned int revid)
static void adp5589_clear_config(void *data)
{
- struct i2c_client *client = data;
- struct adp5589_kpad *kpad = i2c_get_clientdata(client);
+ struct adp5589_kpad *kpad = data;
- adp5589_write(client, kpad->var->reg(ADP5589_GENERAL_CFG), 0);
+ adp5589_write(kpad->client, kpad->var->reg(ADP5589_GENERAL_CFG), 0);
}
static int adp5589_probe(struct i2c_client *client)
@@ -983,7 +986,7 @@ static int adp5589_probe(struct i2c_client *client)
}
error = devm_add_action_or_reset(&client->dev, adp5589_clear_config,
- client);
+ kpad);
if (error)
return error;
@@ -1010,8 +1013,6 @@ static int adp5589_probe(struct i2c_client *client)
if (error)
return error;
- i2c_set_clientdata(client, kpad);
-
dev_info(&client->dev, "Rev.%d keypad, irq %d\n", revid, client->irq);
return 0;
}