Skip to content

Commit

Permalink
Input: tca8418 - enable interrupt after it has been requested
Browse files Browse the repository at this point in the history
Currently, enabling keypad interrupts is one of the first operations
done on the keypad, even before the interrupt is requested, so there is
a small time window where the keypad can fire interrupts but the driver
is not yet ready to handle them. It's fine for level interrupts because
they will be handled anyway, but not so much for edge ones.

This commit modifies and moves the function in charge of configuring the
keypad. Enabling interrupts is now the last thing done on the keypad,
and after the interrupt has been requested by the driver.

Writing to the config register was also used to determine if the device
was indeed present on the bus or not, this has been replaced by reading
the lock/event count register to keep the same functionality.

Signed-off-by: Damien Riegel <damien.riegel@savoirfairelinux.com>
Signed-off-by: Dmitry Torokhov <dmitry.torokhov@gmail.com>
  • Loading branch information
Damien Riegel authored and Dmitry Torokhov committed Oct 19, 2017
1 parent c9bfb2f commit 8f75bc3
Showing 1 changed file with 17 additions and 12 deletions.
29 changes: 17 additions & 12 deletions drivers/input/keyboard/tca8418_keypad.c
Original file line number Diff line number Diff line change
Expand Up @@ -234,14 +234,7 @@ static irqreturn_t tca8418_irq_handler(int irq, void *dev_id)
static int tca8418_configure(struct tca8418_keypad *keypad_data,
u32 rows, u32 cols)
{
int reg, error;

/* Write config register, if this fails assume device not present */
error = tca8418_write_byte(keypad_data, REG_CFG,
CFG_INT_CFG | CFG_OVR_FLOW_IEN | CFG_KE_IEN);
if (error < 0)
return -ENODEV;

int reg, error = 0;

/* Assemble a mask for row and column registers */
reg = ~(~0 << rows);
Expand All @@ -257,6 +250,12 @@ static int tca8418_configure(struct tca8418_keypad *keypad_data,
error |= tca8418_write_byte(keypad_data, REG_DEBOUNCE_DIS2, reg >> 8);
error |= tca8418_write_byte(keypad_data, REG_DEBOUNCE_DIS3, reg >> 16);

if (error)
return error;

error = tca8418_write_byte(keypad_data, REG_CFG,
CFG_INT_CFG | CFG_OVR_FLOW_IEN | CFG_KE_IEN);

return error;
}

Expand All @@ -268,6 +267,7 @@ static int tca8418_keypad_probe(struct i2c_client *client,
struct input_dev *input;
u32 rows = 0, cols = 0;
int error, row_shift, max_keys;
u8 reg;

/* Check i2c driver capabilities */
if (!i2c_check_functionality(client->adapter, I2C_FUNC_SMBUS_BYTE)) {
Expand Down Expand Up @@ -301,10 +301,10 @@ static int tca8418_keypad_probe(struct i2c_client *client,
keypad_data->client = client;
keypad_data->row_shift = row_shift;

/* Initialize the chip or fail if chip isn't present */
error = tca8418_configure(keypad_data, rows, cols);
if (error < 0)
return error;
/* Read key lock register, if this fails assume device not present */
error = tca8418_read_byte(keypad_data, REG_KEY_LCK_EC, &reg);
if (error)
return -ENODEV;

/* Configure input device */
input = devm_input_allocate_device(dev);
Expand Down Expand Up @@ -340,6 +340,11 @@ static int tca8418_keypad_probe(struct i2c_client *client,
return error;
}

/* Initialize the chip */
error = tca8418_configure(keypad_data, rows, cols);
if (error < 0)
return error;

error = input_register_device(input);
if (error) {
dev_err(dev, "Unable to register input device, error: %d\n",
Expand Down

0 comments on commit 8f75bc3

Please sign in to comment.