aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/input
diff options
context:
space:
mode:
authorDmitry Torokhov <dmitry.torokhov@gmail.com>2012-11-05 14:13:11 -0500
committerDmitry Torokhov <dmitry.torokhov@gmail.com>2012-11-29 12:30:49 -0500
commit16ff7cb1848a8898ff19f77b4a9632a73ff98457 (patch)
tree0d13e26449e299cfae3b03a1a4bbaea3b88dcae3 /drivers/input
parent91c5d67f17784078169bdcce4c21df82ac6c234c (diff)
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>
Diffstat (limited to 'drivers/input')
-rw-r--r--drivers/input/keyboard/tca8418_keypad.c78
1 files changed, 25 insertions, 53 deletions
diff --git a/drivers/input/keyboard/tca8418_keypad.c b/drivers/input/keyboard/tca8418_keypad.c
index 8fcce37b089b..50e9c5e195e1 100644
--- a/drivers/input/keyboard/tca8418_keypad.c
+++ b/drivers/input/keyboard/tca8418_keypad.c
@@ -111,14 +111,10 @@
111#define KEY_EVENT_VALUE 0x80 111#define KEY_EVENT_VALUE 0x80
112 112
113struct tca8418_keypad { 113struct tca8418_keypad {
114 unsigned int irq;
115 unsigned int row_shift;
116
117 struct i2c_client *client; 114 struct i2c_client *client;
118 struct input_dev *input; 115 struct input_dev *input;
119 116
120 /* Flexible array member, must be at end of struct */ 117 unsigned int row_shift;
121 unsigned short keymap[];
122}; 118};
123 119
124/* 120/*
@@ -163,6 +159,8 @@ static int tca8418_read_byte(struct tca8418_keypad *keypad_data,
163 159
164static void tca8418_read_keypad(struct tca8418_keypad *keypad_data) 160static void tca8418_read_keypad(struct tca8418_keypad *keypad_data)
165{ 161{
162 struct input_dev *input = keypad_data->input;
163 unsigned short *keymap = input->keycode;
166 int error, col, row; 164 int error, col, row;
167 u8 reg, state, code; 165 u8 reg, state, code;
168 166
@@ -181,9 +179,8 @@ static void tca8418_read_keypad(struct tca8418_keypad *keypad_data)
181 col = (col) ? col - 1 : TCA8418_MAX_COLS - 1; 179 col = (col) ? col - 1 : TCA8418_MAX_COLS - 1;
182 180
183 code = MATRIX_SCAN_CODE(row, col, keypad_data->row_shift); 181 code = MATRIX_SCAN_CODE(row, col, keypad_data->row_shift);
184 input_event(keypad_data->input, EV_MSC, MSC_SCAN, code); 182 input_event(input, EV_MSC, MSC_SCAN, code);
185 input_report_key(keypad_data->input, 183 input_report_key(input, keymap[code], state);
186 keypad_data->keymap[code], state);
187 184
188 /* Read for next loop */ 185 /* Read for next loop */
189 error = tca8418_read_byte(keypad_data, REG_KEY_EVENT_A, &reg); 186 error = tca8418_read_byte(keypad_data, REG_KEY_EVENT_A, &reg);
@@ -193,7 +190,7 @@ static void tca8418_read_keypad(struct tca8418_keypad *keypad_data)
193 dev_err(&keypad_data->client->dev, 190 dev_err(&keypad_data->client->dev,
194 "unable to read REG_KEY_EVENT_A\n"); 191 "unable to read REG_KEY_EVENT_A\n");
195 192
196 input_sync(keypad_data->input); 193 input_sync(input);
197} 194}
198 195
199/* 196/*
@@ -275,6 +272,7 @@ static int tca8418_keypad_probe(struct i2c_client *client,
275 u32 rows = 0, cols = 0; 272 u32 rows = 0, cols = 0;
276 bool rep = false; 273 bool rep = false;
277 bool irq_is_gpio = false; 274 bool irq_is_gpio = false;
275 int irq;
278 int error, row_shift, max_keys; 276 int error, row_shift, max_keys;
279 277
280 /* Copy the platform data */ 278 /* Copy the platform data */
@@ -315,9 +313,8 @@ static int tca8418_keypad_probe(struct i2c_client *client,
315 row_shift = get_count_order(cols); 313 row_shift = get_count_order(cols);
316 max_keys = rows << row_shift; 314 max_keys = rows << row_shift;
317 315
318 /* Allocate memory for keypad_data, keymap and input device */ 316 /* Allocate memory for keypad_data and input device */
319 keypad_data = kzalloc(sizeof(*keypad_data) + 317 keypad_data = devm_kzalloc(dev, sizeof(*keypad_data), GFP_KERNEL);
320 max_keys * sizeof(keypad_data->keymap[0]), GFP_KERNEL);
321 if (!keypad_data) 318 if (!keypad_data)
322 return -ENOMEM; 319 return -ENOMEM;
323 320
@@ -327,29 +324,26 @@ static int tca8418_keypad_probe(struct i2c_client *client,
327 /* Initialize the chip or fail if chip isn't present */ 324 /* Initialize the chip or fail if chip isn't present */
328 error = tca8418_configure(keypad_data, rows, cols); 325 error = tca8418_configure(keypad_data, rows, cols);
329 if (error < 0) 326 if (error < 0)
330 goto fail1; 327 return error;
331 328
332 /* Configure input device */ 329 /* Configure input device */
333 input = input_allocate_device(); 330 input = devm_input_allocate_device(dev);
334 if (!input) { 331 if (!input)
335 error = -ENOMEM; 332 return -ENOMEM;
336 goto fail1; 333
337 }
338 keypad_data->input = input; 334 keypad_data->input = input;
339 335
340 input->name = client->name; 336 input->name = client->name;
341 input->dev.parent = &client->dev;
342
343 input->id.bustype = BUS_I2C; 337 input->id.bustype = BUS_I2C;
344 input->id.vendor = 0x0001; 338 input->id.vendor = 0x0001;
345 input->id.product = 0x001; 339 input->id.product = 0x001;
346 input->id.version = 0x0001; 340 input->id.version = 0x0001;
347 341
348 error = matrix_keypad_build_keymap(keymap_data, NULL, rows, cols, 342 error = matrix_keypad_build_keymap(keymap_data, NULL, rows, cols,
349 keypad_data->keymap, input); 343 NULL, input);
350 if (error) { 344 if (error) {
351 dev_err(dev, "Failed to build keymap\n"); 345 dev_err(dev, "Failed to build keymap\n");
352 goto fail2; 346 return error;
353 } 347 }
354 348
355 if (rep) 349 if (rep)
@@ -358,49 +352,28 @@ static int tca8418_keypad_probe(struct i2c_client *client,
358 352
359 input_set_drvdata(input, keypad_data); 353 input_set_drvdata(input, keypad_data);
360 354
355 irq = client->irq;
361 if (irq_is_gpio) 356 if (irq_is_gpio)
362 client->irq = gpio_to_irq(client->irq); 357 irq = gpio_to_irq(irq);
363 358
364 error = request_threaded_irq(client->irq, NULL, tca8418_irq_handler, 359 error = devm_request_threaded_irq(dev, irq, NULL, tca8418_irq_handler,
365 IRQF_TRIGGER_FALLING | 360 IRQF_TRIGGER_FALLING |
366 IRQF_SHARED | 361 IRQF_SHARED |
367 IRQF_ONESHOT, 362 IRQF_ONESHOT,
368 client->name, keypad_data); 363 client->name, keypad_data);
369 if (error) { 364 if (error) {
370 dev_err(dev, "Unable to claim irq %d; error %d\n", 365 dev_err(dev, "Unable to claim irq %d; error %d\n",
371 client->irq, error); 366 client->irq, error);
372 goto fail2; 367 return error;
373 } 368 }
374 369
375 error = input_register_device(input); 370 error = input_register_device(input);
376 if (error) { 371 if (error) {
377 dev_err(dev, "Unable to register input device, error: %d\n", 372 dev_err(dev, "Unable to register input device, error: %d\n",
378 error); 373 error);
379 goto fail3; 374 return error;
380 } 375 }
381 376
382 i2c_set_clientdata(client, keypad_data);
383 return 0;
384
385fail3:
386 free_irq(client->irq, keypad_data);
387fail2:
388 input_free_device(input);
389fail1:
390 kfree(keypad_data);
391 return error;
392}
393
394static int tca8418_keypad_remove(struct i2c_client *client)
395{
396 struct tca8418_keypad *keypad_data = i2c_get_clientdata(client);
397
398 free_irq(keypad_data->client->irq, keypad_data);
399
400 input_unregister_device(keypad_data->input);
401
402 kfree(keypad_data);
403
404 return 0; 377 return 0;
405} 378}
406 379
@@ -425,7 +398,6 @@ static struct i2c_driver tca8418_keypad_driver = {
425 .of_match_table = of_match_ptr(tca8418_dt_ids), 398 .of_match_table = of_match_ptr(tca8418_dt_ids),
426 }, 399 },
427 .probe = tca8418_keypad_probe, 400 .probe = tca8418_keypad_probe,
428 .remove = tca8418_keypad_remove,
429 .id_table = tca8418_id, 401 .id_table = tca8418_id,
430}; 402};
431 403