Lines Matching +full:keypad +full:- +full:num +full:- +full:columns

1 // SPDX-License-Identifier: GPL-2.0-only
3 * Copyright (C) ST-Ericsson SA 2010
8 * TC35893 MFD Keypad Controller driver
21 /* Maximum supported keypad matrix row/columns size */
25 /* keypad related Constants */
73 * struct tc3589x_keypad_platform_data - platform specific keypad data
76 * @kcol: mask for available columns, value is 0xFF
80 * @enable_wakeup: specifies if keypad event can wake up system from sleep
95 * struct tc_keypad - data structure used by keypad driver
98 * @board: keypad platform device
100 * @kcol: number of columns
102 * @keypad_stopped: holds keypad status
114 static int tc3589x_keypad_init_key_hardware(struct tc_keypad *keypad) in tc3589x_keypad_init_key_hardware() argument
117 struct tc3589x *tc3589x = keypad->tc3589x; in tc3589x_keypad_init_key_hardware()
118 const struct tc3589x_keypad_platform_data *board = keypad->board; in tc3589x_keypad_init_key_hardware()
121 if (board->kcol > TC3589x_MAX_KPCOL || board->krow > TC3589x_MAX_KPROW) in tc3589x_keypad_init_key_hardware()
122 return -EINVAL; in tc3589x_keypad_init_key_hardware()
126 (board->krow << KP_ROW_SHIFT) | board->kcol); in tc3589x_keypad_init_key_hardware()
141 board->settle_time); in tc3589x_keypad_init_key_hardware()
147 board->debounce_period); in tc3589x_keypad_init_key_hardware()
151 /* Start of initialise keypad GPIOs */ in tc3589x_keypad_init_key_hardware()
156 /* Configure pull-up resistors for all row GPIOs */ in tc3589x_keypad_init_key_hardware()
167 /* Configure pull-up resistors for all column GPIOs */ in tc3589x_keypad_init_key_hardware()
191 struct tc_keypad *keypad = dev; in tc3589x_keypad_irq() local
192 struct tc3589x *tc3589x = keypad->tc3589x; in tc3589x_keypad_irq()
211 input_event(keypad->input, EV_MSC, MSC_SCAN, code); in tc3589x_keypad_irq()
212 input_report_key(keypad->input, keypad->keymap[code], !up); in tc3589x_keypad_irq()
213 input_sync(keypad->input); in tc3589x_keypad_irq()
226 static int tc3589x_keypad_enable(struct tc_keypad *keypad) in tc3589x_keypad_enable() argument
228 struct tc3589x *tc3589x = keypad->tc3589x; in tc3589x_keypad_enable()
231 /* pull the keypad module out of reset */ in tc3589x_keypad_enable()
241 /* enable the keypad clock */ in tc3589x_keypad_enable()
257 keypad->keypad_stopped = false; in tc3589x_keypad_enable()
262 static int tc3589x_keypad_disable(struct tc_keypad *keypad) in tc3589x_keypad_disable() argument
264 struct tc3589x *tc3589x = keypad->tc3589x; in tc3589x_keypad_disable()
279 /* disable the keypad module */ in tc3589x_keypad_disable()
284 /* put the keypad module into reset */ in tc3589x_keypad_disable()
287 keypad->keypad_stopped = true; in tc3589x_keypad_disable()
295 struct tc_keypad *keypad = input_get_drvdata(input); in tc3589x_keypad_open() local
297 /* enable the keypad module */ in tc3589x_keypad_open()
298 error = tc3589x_keypad_enable(keypad); in tc3589x_keypad_open()
300 dev_err(&input->dev, "failed to enable keypad module\n"); in tc3589x_keypad_open()
304 error = tc3589x_keypad_init_key_hardware(keypad); in tc3589x_keypad_open()
306 dev_err(&input->dev, "failed to configure keypad module\n"); in tc3589x_keypad_open()
315 struct tc_keypad *keypad = input_get_drvdata(input); in tc3589x_keypad_close() local
317 /* disable the keypad module */ in tc3589x_keypad_close()
318 tc3589x_keypad_disable(keypad); in tc3589x_keypad_close()
324 struct device_node *np = dev->of_node; in tc3589x_keypad_of_probe()
330 return ERR_PTR(-ENODEV); in tc3589x_keypad_of_probe()
334 return ERR_PTR(-ENOMEM); in tc3589x_keypad_of_probe()
336 of_property_read_u32(np, "keypad,num-columns", &cols); in tc3589x_keypad_of_probe()
337 of_property_read_u32(np, "keypad,num-rows", &rows); in tc3589x_keypad_of_probe()
338 plat->kcol = (u8) cols; in tc3589x_keypad_of_probe()
339 plat->krow = (u8) rows; in tc3589x_keypad_of_probe()
340 if (!plat->krow || !plat->kcol || in tc3589x_keypad_of_probe()
341 plat->krow > TC_KPD_ROWS || plat->kcol > TC_KPD_COLUMNS) { in tc3589x_keypad_of_probe()
343 "keypad columns/rows not properly specified (%ux%u)\n", in tc3589x_keypad_of_probe()
344 plat->kcol, plat->krow); in tc3589x_keypad_of_probe()
345 return ERR_PTR(-EINVAL); in tc3589x_keypad_of_probe()
350 return ERR_PTR(-ENOENT); in tc3589x_keypad_of_probe()
353 plat->no_autorepeat = of_property_read_bool(np, "linux,no-autorepeat"); in tc3589x_keypad_of_probe()
355 plat->enable_wakeup = of_property_read_bool(np, "wakeup-source") || in tc3589x_keypad_of_probe()
360 of_property_read_u32(np, "debounce-delay-ms", &debounce_ms); in tc3589x_keypad_of_probe()
362 plat->debounce_period = debounce_ms * 16; in tc3589x_keypad_of_probe()
364 plat->debounce_period = TC_KPD_DEBOUNCE_PERIOD; in tc3589x_keypad_of_probe()
366 plat->settle_time = TC_KPD_SETTLE_TIME; in tc3589x_keypad_of_probe()
368 plat->irqtype = IRQF_TRIGGER_FALLING; in tc3589x_keypad_of_probe()
375 struct tc3589x *tc3589x = dev_get_drvdata(pdev->dev.parent); in tc3589x_keypad_probe()
376 struct tc_keypad *keypad; in tc3589x_keypad_probe() local
381 plat = tc3589x_keypad_of_probe(&pdev->dev); in tc3589x_keypad_probe()
383 dev_err(&pdev->dev, "invalid keypad platform data\n"); in tc3589x_keypad_probe()
391 keypad = devm_kzalloc(&pdev->dev, sizeof(struct tc_keypad), in tc3589x_keypad_probe()
393 if (!keypad) in tc3589x_keypad_probe()
394 return -ENOMEM; in tc3589x_keypad_probe()
396 input = devm_input_allocate_device(&pdev->dev); in tc3589x_keypad_probe()
398 dev_err(&pdev->dev, "failed to allocate input device\n"); in tc3589x_keypad_probe()
399 return -ENOMEM; in tc3589x_keypad_probe()
402 keypad->board = plat; in tc3589x_keypad_probe()
403 keypad->input = input; in tc3589x_keypad_probe()
404 keypad->tc3589x = tc3589x; in tc3589x_keypad_probe()
406 input->id.bustype = BUS_I2C; in tc3589x_keypad_probe()
407 input->name = pdev->name; in tc3589x_keypad_probe()
408 input->dev.parent = &pdev->dev; in tc3589x_keypad_probe()
410 input->open = tc3589x_keypad_open; in tc3589x_keypad_probe()
411 input->close = tc3589x_keypad_close; in tc3589x_keypad_probe()
413 error = matrix_keypad_build_keymap(plat->keymap_data, NULL, in tc3589x_keypad_probe()
417 dev_err(&pdev->dev, "Failed to build keymap\n"); in tc3589x_keypad_probe()
421 keypad->keymap = input->keycode; in tc3589x_keypad_probe()
424 if (!plat->no_autorepeat) in tc3589x_keypad_probe()
425 __set_bit(EV_REP, input->evbit); in tc3589x_keypad_probe()
427 input_set_drvdata(input, keypad); in tc3589x_keypad_probe()
429 tc3589x_keypad_disable(keypad); in tc3589x_keypad_probe()
431 error = devm_request_threaded_irq(&pdev->dev, irq, in tc3589x_keypad_probe()
433 plat->irqtype | IRQF_ONESHOT, in tc3589x_keypad_probe()
434 "tc3589x-keypad", keypad); in tc3589x_keypad_probe()
436 dev_err(&pdev->dev, in tc3589x_keypad_probe()
444 dev_err(&pdev->dev, "Could not register input device\n"); in tc3589x_keypad_probe()
448 /* let platform decide if keypad is a wakeup source or not */ in tc3589x_keypad_probe()
449 device_init_wakeup(&pdev->dev, plat->enable_wakeup); in tc3589x_keypad_probe()
450 device_set_wakeup_capable(&pdev->dev, plat->enable_wakeup); in tc3589x_keypad_probe()
452 platform_set_drvdata(pdev, keypad); in tc3589x_keypad_probe()
460 struct tc_keypad *keypad = platform_get_drvdata(pdev); in tc3589x_keypad_suspend() local
463 /* keypad is already off; we do nothing */ in tc3589x_keypad_suspend()
464 if (keypad->keypad_stopped) in tc3589x_keypad_suspend()
468 if (!device_may_wakeup(&pdev->dev)) in tc3589x_keypad_suspend()
469 tc3589x_keypad_disable(keypad); in tc3589x_keypad_suspend()
479 struct tc_keypad *keypad = platform_get_drvdata(pdev); in tc3589x_keypad_resume() local
482 if (!keypad->keypad_stopped) in tc3589x_keypad_resume()
486 if (!device_may_wakeup(&pdev->dev)) in tc3589x_keypad_resume()
487 tc3589x_keypad_enable(keypad); in tc3589x_keypad_resume()
499 .name = "tc3589x-keypad",
508 MODULE_DESCRIPTION("TC35893 Keypad Driver");
509 MODULE_ALIAS("platform:tc3589x-keypad");