Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

Input: omap4-keypad - add device tree support

Add device tree support for omap4 keypad driver and update the
Documentation with omap4 keypad device tree binding information.

Tested on omap4430 sdp.

Signed-off-by: Sourav Poddar <sourav.poddar@ti.com>
Signed-off-by: Dmitry Torokhov <dmitry.torokhov@gmail.com>

authored by

Sourav Poddar and committed by
Dmitry Torokhov
13987435 8a90c034

+119 -41
+31
Documentation/devicetree/bindings/input/omap-keypad.txt
··· 1 + * TI's Keypad Controller device tree bindings 2 + 3 + TI's Keypad controller is used to interface a SoC with a matrix-type 4 + keypad device. The keypad controller supports multiple row and column lines. 5 + A key can be placed at each intersection of a unique row and a unique column. 6 + The keypad controller can sense a key-press and key-release and report the 7 + event using a interrupt to the cpu. 8 + 9 + Required SoC Specific Properties: 10 + - compatible: should be one of the following 11 + - "ti,omap4-keypad": For controllers compatible with omap4 keypad 12 + controller. 13 + 14 + Required Board Specific Properties, in addition to those specified by 15 + the shared matrix-keyboard bindings: 16 + - keypad,num-rows: Number of row lines connected to the keypad 17 + controller. 18 + 19 + - keypad,num-columns: Number of column lines connected to the 20 + keypad controller. 21 + 22 + Optional Properties specific to linux: 23 + - linux,keypad-no-autorepeat: do no enable autorepeat feature. 24 + 25 + Example: 26 + keypad@4ae1c000{ 27 + compatible = "ti,omap4-keypad"; 28 + keypad,num-rows = <2>; 29 + keypad,num-columns = <8>; 30 + linux,keypad-no-autorepeat; 31 + };
+88 -41
drivers/input/keyboard/omap4-keypad.c
··· 27 27 #include <linux/platform_device.h> 28 28 #include <linux/errno.h> 29 29 #include <linux/io.h> 30 + #include <linux/of.h> 30 31 #include <linux/input.h> 31 32 #include <linux/slab.h> 32 33 #include <linux/pm_runtime.h> ··· 85 84 u32 reg_offset; 86 85 u32 irqreg_offset; 87 86 unsigned int row_shift; 87 + bool no_autorepeat; 88 88 unsigned char key_state[8]; 89 - unsigned short keymap[]; 89 + unsigned short *keymap; 90 90 }; 91 91 92 92 static int kbd_readl(struct omap4_keypad *keypad_data, u32 offset) ··· 210 208 pm_runtime_put_sync(input->dev.parent); 211 209 } 212 210 211 + #ifdef CONFIG_OF 212 + static int __devinit omap4_keypad_parse_dt(struct device *dev, 213 + struct omap4_keypad *keypad_data) 214 + { 215 + struct device_node *np = dev->of_node; 216 + 217 + if (!np) { 218 + dev_err(dev, "missing DT data"); 219 + return -EINVAL; 220 + } 221 + 222 + of_property_read_u32(np, "keypad,num-rows", &keypad_data->rows); 223 + of_property_read_u32(np, "keypad,num-columns", &keypad_data->cols); 224 + if (!keypad_data->rows || !keypad_data->cols) { 225 + dev_err(dev, "number of keypad rows/columns not specified\n"); 226 + return -EINVAL; 227 + } 228 + 229 + if (of_get_property(np, "linux,input-no-autorepeat", NULL)) 230 + keypad_data->no_autorepeat = true; 231 + 232 + return 0; 233 + } 234 + #else 235 + static inline int omap4_keypad_parse_dt(struct device *dev, 236 + struct omap4_keypad *keypad_data) 237 + { 238 + return -ENOSYS; 239 + } 240 + #endif 241 + 213 242 static int __devinit omap4_keypad_probe(struct platform_device *pdev) 214 243 { 215 - const struct omap4_keypad_platform_data *pdata; 244 + const struct omap4_keypad_platform_data *pdata = 245 + dev_get_platdata(&pdev->dev); 246 + const struct matrix_keymap_data *keymap_data = 247 + pdata ? pdata->keymap_data : NULL; 216 248 struct omap4_keypad *keypad_data; 217 249 struct input_dev *input_dev; 218 250 struct resource *res; 219 - resource_size_t size; 220 - unsigned int row_shift, max_keys; 251 + unsigned int max_keys; 221 252 int rev; 222 253 int irq; 223 254 int error; 224 - 225 - /* platform data */ 226 - pdata = pdev->dev.platform_data; 227 - if (!pdata) { 228 - dev_err(&pdev->dev, "no platform data defined\n"); 229 - return -EINVAL; 230 - } 231 255 232 256 res = platform_get_resource(pdev, IORESOURCE_MEM, 0); 233 257 if (!res) { ··· 267 239 return -EINVAL; 268 240 } 269 241 270 - if (!pdata->keymap_data) { 271 - dev_err(&pdev->dev, "no keymap data defined\n"); 272 - return -EINVAL; 273 - } 274 - 275 - row_shift = get_count_order(pdata->cols); 276 - max_keys = pdata->rows << row_shift; 277 - 278 - keypad_data = kzalloc(sizeof(struct omap4_keypad) + 279 - max_keys * sizeof(keypad_data->keymap[0]), 280 - GFP_KERNEL); 242 + keypad_data = kzalloc(sizeof(struct omap4_keypad), GFP_KERNEL); 281 243 if (!keypad_data) { 282 244 dev_err(&pdev->dev, "keypad_data memory allocation failed\n"); 283 245 return -ENOMEM; 284 246 } 285 247 286 - size = resource_size(res); 248 + keypad_data->irq = irq; 287 249 288 - res = request_mem_region(res->start, size, pdev->name); 250 + if (pdata) { 251 + keypad_data->rows = pdata->rows; 252 + keypad_data->cols = pdata->cols; 253 + } else { 254 + error = omap4_keypad_parse_dt(&pdev->dev, keypad_data); 255 + if (error) 256 + return error; 257 + } 258 + 259 + res = request_mem_region(res->start, resource_size(res), pdev->name); 289 260 if (!res) { 290 261 dev_err(&pdev->dev, "can't request mem region\n"); 291 262 error = -EBUSY; ··· 298 271 goto err_release_mem; 299 272 } 300 273 301 - keypad_data->irq = irq; 302 - keypad_data->row_shift = row_shift; 303 - keypad_data->rows = pdata->rows; 304 - keypad_data->cols = pdata->cols; 305 274 306 275 /* 307 - * Enable clocks for the keypad module so that we can read 308 - * revision register. 309 - */ 276 + * Enable clocks for the keypad module so that we can read 277 + * revision register. 278 + */ 310 279 pm_runtime_enable(&pdev->dev); 311 280 error = pm_runtime_get_sync(&pdev->dev); 312 281 if (error) { ··· 345 322 input_dev->open = omap4_keypad_open; 346 323 input_dev->close = omap4_keypad_close; 347 324 348 - error = matrix_keypad_build_keymap(pdata->keymap_data, NULL, 349 - pdata->rows, pdata->cols, 350 - keypad_data->keymap, input_dev); 351 - if (error) { 352 - dev_err(&pdev->dev, "failed to build keymap\n"); 325 + input_set_capability(input_dev, EV_MSC, MSC_SCAN); 326 + if (!keypad_data->no_autorepeat) 327 + __set_bit(EV_REP, input_dev->evbit); 328 + 329 + input_set_drvdata(input_dev, keypad_data); 330 + 331 + keypad_data->row_shift = get_count_order(keypad_data->cols); 332 + max_keys = keypad_data->rows << keypad_data->row_shift; 333 + keypad_data->keymap = kzalloc(max_keys * sizeof(keypad_data->keymap[0]), 334 + GFP_KERNEL); 335 + if (!keypad_data->keymap) { 336 + dev_err(&pdev->dev, "Not enough memory for keymap\n"); 337 + error = -ENOMEM; 353 338 goto err_free_input; 354 339 } 355 340 356 - __set_bit(EV_REP, input_dev->evbit); 357 - input_set_capability(input_dev, EV_MSC, MSC_SCAN); 358 - 359 - input_set_drvdata(input_dev, keypad_data); 341 + error = matrix_keypad_build_keymap(keymap_data, NULL, 342 + keypad_data->rows, keypad_data->cols, 343 + keypad_data->keymap, input_dev); 344 + if (error) { 345 + dev_err(&pdev->dev, "failed to build keymap\n"); 346 + goto err_free_keymap; 347 + } 360 348 361 349 error = request_irq(keypad_data->irq, omap4_keypad_interrupt, 362 350 IRQF_TRIGGER_RISING, ··· 391 357 err_pm_disable: 392 358 pm_runtime_disable(&pdev->dev); 393 359 free_irq(keypad_data->irq, keypad_data); 360 + err_free_keymap: 361 + kfree(keypad_data->keymap); 394 362 err_free_input: 395 363 input_free_device(input_dev); 396 364 err_pm_put_sync: ··· 400 364 err_unmap: 401 365 iounmap(keypad_data->base); 402 366 err_release_mem: 403 - release_mem_region(res->start, size); 367 + release_mem_region(res->start, resource_size(res)); 404 368 err_free_keypad: 405 369 kfree(keypad_data); 406 370 return error; ··· 422 386 res = platform_get_resource(pdev, IORESOURCE_MEM, 0); 423 387 release_mem_region(res->start, resource_size(res)); 424 388 389 + kfree(keypad_data->keymap); 425 390 kfree(keypad_data); 391 + 426 392 platform_set_drvdata(pdev, NULL); 427 393 428 394 return 0; 429 395 } 396 + 397 + #ifdef CONFIG_OF 398 + static const struct of_device_id omap_keypad_dt_match[] = { 399 + { .compatible = "ti,omap4-keypad" }, 400 + {}, 401 + }; 402 + MODULE_DEVICE_TABLE(of, omap_keypad_dt_match); 403 + #endif 430 404 431 405 static struct platform_driver omap4_keypad_driver = { 432 406 .probe = omap4_keypad_probe, ··· 444 398 .driver = { 445 399 .name = "omap4-keypad", 446 400 .owner = THIS_MODULE, 401 + .of_match_table = of_match_ptr(omap_keypad_dt_match), 447 402 }, 448 403 }; 449 404 module_platform_driver(omap4_keypad_driver);