Input: tca8418-keypad - switch to using managed resources
Let's switch to using devm_*() interfaces to manage our resources, thus will simplify error unwinding a bit. Reviewed-by: Alban Bedel <alban.bedel@avionic-design.de> Signed-off-by: Dmitry Torokhov <dmitry.torokhov@gmail.com>
This commit is contained in:
parent
91c5d67f17
commit
16ff7cb184
@ -111,14 +111,10 @@
|
|||||||
#define KEY_EVENT_VALUE 0x80
|
#define KEY_EVENT_VALUE 0x80
|
||||||
|
|
||||||
struct tca8418_keypad {
|
struct tca8418_keypad {
|
||||||
unsigned int irq;
|
|
||||||
unsigned int row_shift;
|
|
||||||
|
|
||||||
struct i2c_client *client;
|
struct i2c_client *client;
|
||||||
struct input_dev *input;
|
struct input_dev *input;
|
||||||
|
|
||||||
/* Flexible array member, must be at end of struct */
|
unsigned int row_shift;
|
||||||
unsigned short keymap[];
|
|
||||||
};
|
};
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -163,6 +159,8 @@ static int tca8418_read_byte(struct tca8418_keypad *keypad_data,
|
|||||||
|
|
||||||
static void tca8418_read_keypad(struct tca8418_keypad *keypad_data)
|
static void tca8418_read_keypad(struct tca8418_keypad *keypad_data)
|
||||||
{
|
{
|
||||||
|
struct input_dev *input = keypad_data->input;
|
||||||
|
unsigned short *keymap = input->keycode;
|
||||||
int error, col, row;
|
int error, col, row;
|
||||||
u8 reg, state, code;
|
u8 reg, state, code;
|
||||||
|
|
||||||
@ -181,9 +179,8 @@ static void tca8418_read_keypad(struct tca8418_keypad *keypad_data)
|
|||||||
col = (col) ? col - 1 : TCA8418_MAX_COLS - 1;
|
col = (col) ? col - 1 : TCA8418_MAX_COLS - 1;
|
||||||
|
|
||||||
code = MATRIX_SCAN_CODE(row, col, keypad_data->row_shift);
|
code = MATRIX_SCAN_CODE(row, col, keypad_data->row_shift);
|
||||||
input_event(keypad_data->input, EV_MSC, MSC_SCAN, code);
|
input_event(input, EV_MSC, MSC_SCAN, code);
|
||||||
input_report_key(keypad_data->input,
|
input_report_key(input, keymap[code], state);
|
||||||
keypad_data->keymap[code], state);
|
|
||||||
|
|
||||||
/* Read for next loop */
|
/* Read for next loop */
|
||||||
error = tca8418_read_byte(keypad_data, REG_KEY_EVENT_A, ®);
|
error = tca8418_read_byte(keypad_data, REG_KEY_EVENT_A, ®);
|
||||||
@ -193,7 +190,7 @@ static void tca8418_read_keypad(struct tca8418_keypad *keypad_data)
|
|||||||
dev_err(&keypad_data->client->dev,
|
dev_err(&keypad_data->client->dev,
|
||||||
"unable to read REG_KEY_EVENT_A\n");
|
"unable to read REG_KEY_EVENT_A\n");
|
||||||
|
|
||||||
input_sync(keypad_data->input);
|
input_sync(input);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -275,6 +272,7 @@ static int tca8418_keypad_probe(struct i2c_client *client,
|
|||||||
u32 rows = 0, cols = 0;
|
u32 rows = 0, cols = 0;
|
||||||
bool rep = false;
|
bool rep = false;
|
||||||
bool irq_is_gpio = false;
|
bool irq_is_gpio = false;
|
||||||
|
int irq;
|
||||||
int error, row_shift, max_keys;
|
int error, row_shift, max_keys;
|
||||||
|
|
||||||
/* Copy the platform data */
|
/* Copy the platform data */
|
||||||
@ -315,9 +313,8 @@ static int tca8418_keypad_probe(struct i2c_client *client,
|
|||||||
row_shift = get_count_order(cols);
|
row_shift = get_count_order(cols);
|
||||||
max_keys = rows << row_shift;
|
max_keys = rows << row_shift;
|
||||||
|
|
||||||
/* Allocate memory for keypad_data, keymap and input device */
|
/* Allocate memory for keypad_data and input device */
|
||||||
keypad_data = kzalloc(sizeof(*keypad_data) +
|
keypad_data = devm_kzalloc(dev, sizeof(*keypad_data), GFP_KERNEL);
|
||||||
max_keys * sizeof(keypad_data->keymap[0]), GFP_KERNEL);
|
|
||||||
if (!keypad_data)
|
if (!keypad_data)
|
||||||
return -ENOMEM;
|
return -ENOMEM;
|
||||||
|
|
||||||
@ -327,29 +324,26 @@ static int tca8418_keypad_probe(struct i2c_client *client,
|
|||||||
/* Initialize the chip or fail if chip isn't present */
|
/* Initialize the chip or fail if chip isn't present */
|
||||||
error = tca8418_configure(keypad_data, rows, cols);
|
error = tca8418_configure(keypad_data, rows, cols);
|
||||||
if (error < 0)
|
if (error < 0)
|
||||||
goto fail1;
|
return error;
|
||||||
|
|
||||||
/* Configure input device */
|
/* Configure input device */
|
||||||
input = input_allocate_device();
|
input = devm_input_allocate_device(dev);
|
||||||
if (!input) {
|
if (!input)
|
||||||
error = -ENOMEM;
|
return -ENOMEM;
|
||||||
goto fail1;
|
|
||||||
}
|
|
||||||
keypad_data->input = input;
|
keypad_data->input = input;
|
||||||
|
|
||||||
input->name = client->name;
|
input->name = client->name;
|
||||||
input->dev.parent = &client->dev;
|
|
||||||
|
|
||||||
input->id.bustype = BUS_I2C;
|
input->id.bustype = BUS_I2C;
|
||||||
input->id.vendor = 0x0001;
|
input->id.vendor = 0x0001;
|
||||||
input->id.product = 0x001;
|
input->id.product = 0x001;
|
||||||
input->id.version = 0x0001;
|
input->id.version = 0x0001;
|
||||||
|
|
||||||
error = matrix_keypad_build_keymap(keymap_data, NULL, rows, cols,
|
error = matrix_keypad_build_keymap(keymap_data, NULL, rows, cols,
|
||||||
keypad_data->keymap, input);
|
NULL, input);
|
||||||
if (error) {
|
if (error) {
|
||||||
dev_err(dev, "Failed to build keymap\n");
|
dev_err(dev, "Failed to build keymap\n");
|
||||||
goto fail2;
|
return error;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (rep)
|
if (rep)
|
||||||
@ -358,49 +352,28 @@ static int tca8418_keypad_probe(struct i2c_client *client,
|
|||||||
|
|
||||||
input_set_drvdata(input, keypad_data);
|
input_set_drvdata(input, keypad_data);
|
||||||
|
|
||||||
|
irq = client->irq;
|
||||||
if (irq_is_gpio)
|
if (irq_is_gpio)
|
||||||
client->irq = gpio_to_irq(client->irq);
|
irq = gpio_to_irq(irq);
|
||||||
|
|
||||||
error = request_threaded_irq(client->irq, NULL, tca8418_irq_handler,
|
error = devm_request_threaded_irq(dev, irq, NULL, tca8418_irq_handler,
|
||||||
IRQF_TRIGGER_FALLING |
|
IRQF_TRIGGER_FALLING |
|
||||||
IRQF_SHARED |
|
IRQF_SHARED |
|
||||||
IRQF_ONESHOT,
|
IRQF_ONESHOT,
|
||||||
client->name, keypad_data);
|
client->name, keypad_data);
|
||||||
if (error) {
|
if (error) {
|
||||||
dev_err(dev, "Unable to claim irq %d; error %d\n",
|
dev_err(dev, "Unable to claim irq %d; error %d\n",
|
||||||
client->irq, error);
|
client->irq, error);
|
||||||
goto fail2;
|
return error;
|
||||||
}
|
}
|
||||||
|
|
||||||
error = input_register_device(input);
|
error = input_register_device(input);
|
||||||
if (error) {
|
if (error) {
|
||||||
dev_err(dev, "Unable to register input device, error: %d\n",
|
dev_err(dev, "Unable to register input device, error: %d\n",
|
||||||
error);
|
error);
|
||||||
goto fail3;
|
return error;
|
||||||
}
|
}
|
||||||
|
|
||||||
i2c_set_clientdata(client, keypad_data);
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
fail3:
|
|
||||||
free_irq(client->irq, keypad_data);
|
|
||||||
fail2:
|
|
||||||
input_free_device(input);
|
|
||||||
fail1:
|
|
||||||
kfree(keypad_data);
|
|
||||||
return error;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int tca8418_keypad_remove(struct i2c_client *client)
|
|
||||||
{
|
|
||||||
struct tca8418_keypad *keypad_data = i2c_get_clientdata(client);
|
|
||||||
|
|
||||||
free_irq(keypad_data->client->irq, keypad_data);
|
|
||||||
|
|
||||||
input_unregister_device(keypad_data->input);
|
|
||||||
|
|
||||||
kfree(keypad_data);
|
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -425,7 +398,6 @@ static struct i2c_driver tca8418_keypad_driver = {
|
|||||||
.of_match_table = of_match_ptr(tca8418_dt_ids),
|
.of_match_table = of_match_ptr(tca8418_dt_ids),
|
||||||
},
|
},
|
||||||
.probe = tca8418_keypad_probe,
|
.probe = tca8418_keypad_probe,
|
||||||
.remove = tca8418_keypad_remove,
|
|
||||||
.id_table = tca8418_id,
|
.id_table = tca8418_id,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user