aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/input/keyboard
diff options
context:
space:
mode:
authorAlban Bedel <alban.bedel@avionic-design.de>2012-11-05 13:55:25 -0500
committerDmitry Torokhov <dmitry.torokhov@gmail.com>2012-11-29 12:28:50 -0500
commite89e29b8585379c844b03fb3aa2cca73e2bc5b26 (patch)
tree904bb25bb9c50818617ccf5e83ae501cb534f386 /drivers/input/keyboard
parent852d20aed8a029ea8496e85052493b275f19d22b (diff)
Input: tca8418_keypad - add support for device tree bindings
Signed-off-by: Alban Bedel <alban.bedel@avionic-design.de> Signed-off-by: Dmitry Torokhov <dmitry.torokhov@gmail.com>
Diffstat (limited to 'drivers/input/keyboard')
-rw-r--r--drivers/input/keyboard/tca8418_keypad.c68
1 files changed, 41 insertions, 27 deletions
diff --git a/drivers/input/keyboard/tca8418_keypad.c b/drivers/input/keyboard/tca8418_keypad.c
index f1e966bdcff5..1a2894dd03ca 100644
--- a/drivers/input/keyboard/tca8418_keypad.c
+++ b/drivers/input/keyboard/tca8418_keypad.c
@@ -35,6 +35,7 @@
35#include <linux/i2c.h> 35#include <linux/i2c.h>
36#include <linux/input.h> 36#include <linux/input.h>
37#include <linux/input/tca8418_keypad.h> 37#include <linux/input/tca8418_keypad.h>
38#include <linux/of.h>
38 39
39/* TCA8418 hardware limits */ 40/* TCA8418 hardware limits */
40#define TCA8418_MAX_ROWS 8 41#define TCA8418_MAX_ROWS 8
@@ -116,10 +117,15 @@ static const struct i2c_device_id tca8418_id[] = {
116}; 117};
117MODULE_DEVICE_TABLE(i2c, tca8418_id); 118MODULE_DEVICE_TABLE(i2c, tca8418_id);
118 119
120#ifdef CONFIG_OF
121static const struct of_device_id tca8418_dt_ids[] __devinitconst = {
122 { .compatible = "ti,tca8418", },
123 { }
124};
125MODULE_DEVICE_TABLE(of, tca8418_dt_ids);
126#endif
127
119struct tca8418_keypad { 128struct tca8418_keypad {
120 unsigned int rows;
121 unsigned int cols;
122 unsigned int keypad_mask; /* Mask for keypad col/rol regs */
123 unsigned int irq; 129 unsigned int irq;
124 unsigned int row_shift; 130 unsigned int row_shift;
125 131
@@ -241,7 +247,8 @@ exit:
241/* 247/*
242 * Configure the TCA8418 for keypad operation 248 * Configure the TCA8418 for keypad operation
243 */ 249 */
244static int tca8418_configure(struct tca8418_keypad *keypad_data) 250static int tca8418_configure(struct tca8418_keypad *keypad_data,
251 u32 rows, u32 cols)
245{ 252{
246 int reg, error; 253 int reg, error;
247 254
@@ -253,9 +260,8 @@ static int tca8418_configure(struct tca8418_keypad *keypad_data)
253 260
254 261
255 /* Assemble a mask for row and column registers */ 262 /* Assemble a mask for row and column registers */
256 reg = ~(~0 << keypad_data->rows); 263 reg = ~(~0 << rows);
257 reg += (~(~0 << keypad_data->cols)) << 8; 264 reg += (~(~0 << cols)) << 8;
258 keypad_data->keypad_mask = reg;
259 265
260 /* Set registers to keypad mode */ 266 /* Set registers to keypad mode */
261 error |= tca8418_write_byte(keypad_data, REG_KP_GPIO1, reg); 267 error |= tca8418_write_byte(keypad_data, REG_KP_GPIO1, reg);
@@ -277,25 +283,36 @@ static int tca8418_keypad_probe(struct i2c_client *client,
277 client->dev.platform_data; 283 client->dev.platform_data;
278 struct tca8418_keypad *keypad_data; 284 struct tca8418_keypad *keypad_data;
279 struct input_dev *input; 285 struct input_dev *input;
286 const struct matrix_keymap_data *keymap_data = NULL;
287 u32 rows = 0, cols = 0;
288 bool rep = false;
289 bool irq_is_gpio = false;
280 int error, row_shift, max_keys; 290 int error, row_shift, max_keys;
281 291
282 /* Copy the platform data */ 292 /* Copy the platform data */
283 if (!pdata) { 293 if (pdata) {
284 dev_dbg(&client->dev, "no platform data\n"); 294 if (!pdata->keymap_data) {
285 return -EINVAL; 295 dev_err(&client->dev, "no keymap data defined\n");
296 return -EINVAL;
297 }
298 keymap_data = pdata->keymap_data;
299 rows = pdata->rows;
300 cols = pdata->cols;
301 rep = pdata->rep;
302 irq_is_gpio = pdata->irq_is_gpio;
303 } else {
304 struct device_node *np = client->dev.of_node;
305 of_property_read_u32(np, "keypad,num-rows", &rows);
306 of_property_read_u32(np, "keypad,num-columns", &cols);
307 rep = of_property_read_bool(np, "keypad,autorepeat");
286 } 308 }
287 309
288 if (!pdata->keymap_data) { 310 if (!rows || rows > TCA8418_MAX_ROWS) {
289 dev_err(&client->dev, "no keymap data defined\n");
290 return -EINVAL;
291 }
292
293 if (!pdata->rows || pdata->rows > TCA8418_MAX_ROWS) {
294 dev_err(&client->dev, "invalid rows\n"); 311 dev_err(&client->dev, "invalid rows\n");
295 return -EINVAL; 312 return -EINVAL;
296 } 313 }
297 314
298 if (!pdata->cols || pdata->cols > TCA8418_MAX_COLS) { 315 if (!cols || cols > TCA8418_MAX_COLS) {
299 dev_err(&client->dev, "invalid columns\n"); 316 dev_err(&client->dev, "invalid columns\n");
300 return -EINVAL; 317 return -EINVAL;
301 } 318 }
@@ -307,8 +324,8 @@ static int tca8418_keypad_probe(struct i2c_client *client,
307 return -ENODEV; 324 return -ENODEV;
308 } 325 }
309 326
310 row_shift = get_count_order(pdata->cols); 327 row_shift = get_count_order(cols);
311 max_keys = pdata->rows << row_shift; 328 max_keys = rows << row_shift;
312 329
313 /* Allocate memory for keypad_data, keymap and input device */ 330 /* Allocate memory for keypad_data, keymap and input device */
314 keypad_data = kzalloc(sizeof(*keypad_data) + 331 keypad_data = kzalloc(sizeof(*keypad_data) +
@@ -316,13 +333,11 @@ static int tca8418_keypad_probe(struct i2c_client *client,
316 if (!keypad_data) 333 if (!keypad_data)
317 return -ENOMEM; 334 return -ENOMEM;
318 335
319 keypad_data->rows = pdata->rows;
320 keypad_data->cols = pdata->cols;
321 keypad_data->client = client; 336 keypad_data->client = client;
322 keypad_data->row_shift = row_shift; 337 keypad_data->row_shift = row_shift;
323 338
324 /* Initialize the chip or fail if chip isn't present */ 339 /* Initialize the chip or fail if chip isn't present */
325 error = tca8418_configure(keypad_data); 340 error = tca8418_configure(keypad_data, rows, cols);
326 if (error < 0) 341 if (error < 0)
327 goto fail1; 342 goto fail1;
328 343
@@ -342,21 +357,20 @@ static int tca8418_keypad_probe(struct i2c_client *client,
342 input->id.product = 0x001; 357 input->id.product = 0x001;
343 input->id.version = 0x0001; 358 input->id.version = 0x0001;
344 359
345 error = matrix_keypad_build_keymap(pdata->keymap_data, NULL, 360 error = matrix_keypad_build_keymap(keymap_data, NULL, rows, cols,
346 pdata->rows, pdata->cols,
347 keypad_data->keymap, input); 361 keypad_data->keymap, input);
348 if (error) { 362 if (error) {
349 dev_dbg(&client->dev, "Failed to build keymap\n"); 363 dev_dbg(&client->dev, "Failed to build keymap\n");
350 goto fail2; 364 goto fail2;
351 } 365 }
352 366
353 if (pdata->rep) 367 if (rep)
354 __set_bit(EV_REP, input->evbit); 368 __set_bit(EV_REP, input->evbit);
355 input_set_capability(input, EV_MSC, MSC_SCAN); 369 input_set_capability(input, EV_MSC, MSC_SCAN);
356 370
357 input_set_drvdata(input, keypad_data); 371 input_set_drvdata(input, keypad_data);
358 372
359 if (pdata->irq_is_gpio) 373 if (irq_is_gpio)
360 client->irq = gpio_to_irq(client->irq); 374 client->irq = gpio_to_irq(client->irq);
361 375
362 error = request_threaded_irq(client->irq, NULL, tca8418_irq_handler, 376 error = request_threaded_irq(client->irq, NULL, tca8418_irq_handler,
@@ -401,11 +415,11 @@ static int tca8418_keypad_remove(struct i2c_client *client)
401 return 0; 415 return 0;
402} 416}
403 417
404
405static struct i2c_driver tca8418_keypad_driver = { 418static struct i2c_driver tca8418_keypad_driver = {
406 .driver = { 419 .driver = {
407 .name = TCA8418_NAME, 420 .name = TCA8418_NAME,
408 .owner = THIS_MODULE, 421 .owner = THIS_MODULE,
422 .of_match_table = of_match_ptr(tca8418_dt_ids),
409 }, 423 },
410 .probe = tca8418_keypad_probe, 424 .probe = tca8418_keypad_probe,
411 .remove = tca8418_keypad_remove, 425 .remove = tca8418_keypad_remove,