18 #include <linux/input.h>
21 #include <linux/module.h>
25 #include <linux/slab.h>
28 #include <linux/sched.h>
31 #define SAMSUNG_KEYIFCON 0x00
32 #define SAMSUNG_KEYIFSTSCLR 0x04
33 #define SAMSUNG_KEYIFCOL 0x08
34 #define SAMSUNG_KEYIFROW 0x0c
35 #define SAMSUNG_KEYIFFC 0x10
38 #define SAMSUNG_KEYIFCON_INT_F_EN (1 << 0)
39 #define SAMSUNG_KEYIFCON_INT_R_EN (1 << 1)
40 #define SAMSUNG_KEYIFCON_DF_EN (1 << 2)
41 #define SAMSUNG_KEYIFCON_FC_EN (1 << 3)
42 #define SAMSUNG_KEYIFCON_WAKEUPEN (1 << 4)
45 #define SAMSUNG_KEYIFSTSCLR_P_INT_MASK (0xff << 0)
46 #define SAMSUNG_KEYIFSTSCLR_R_INT_MASK (0xff << 8)
47 #define SAMSUNG_KEYIFSTSCLR_R_INT_OFFSET 8
48 #define S5PV210_KEYIFSTSCLR_P_INT_MASK (0x3fff << 0)
49 #define S5PV210_KEYIFSTSCLR_R_INT_MASK (0x3fff << 16)
50 #define S5PV210_KEYIFSTSCLR_R_INT_OFFSET 16
53 #define SAMSUNG_KEYIFCOL_MASK (0xff << 0)
54 #define S5PV210_KEYIFCOLEN_MASK (0xff << 8)
57 #define SAMSUNG_KEYIFROW_MASK (0xff << 0)
58 #define S5PV210_KEYIFROW_MASK (0x3fff << 0)
61 #define SAMSUNG_KEYIFFC_MASK (0x3ff << 0)
90 unsigned int *row_state)
95 for (col = 0; col < keypad->
cols; col++) {
98 val &= ~(1 << col) << 8;
108 row_state[col] = ~val & ((1 << keypad->
rows) - 1);
116 unsigned int *row_state)
118 struct input_dev *input_dev = keypad->
input_dev;
120 unsigned int pressed;
121 unsigned int key_down = 0;
123 unsigned int col, row;
125 for (col = 0; col < keypad->
cols; col++) {
126 changed = row_state[col] ^ keypad->
row_state[col];
127 key_down |= row_state[col];
131 for (row = 0; row < keypad->
rows; row++) {
132 if (!(changed & (1 << row)))
135 pressed = row_state[col] & (1 << row);
138 "key %s, row: %d, col: %d\n",
139 pressed ?
"pressed" :
"released", row, col);
144 input_report_key(input_dev,
162 pm_runtime_get_sync(&keypad->
pdev->dev);
169 samsung_keypad_scan(keypad, row_state);
171 key_down = samsung_keypad_report(keypad, row_state);
176 }
while (key_down && !keypad->
stopped);
178 pm_runtime_put(&keypad->
pdev->dev);
187 pm_runtime_get_sync(&keypad->
pdev->dev);
202 pm_runtime_put(&keypad->
pdev->dev);
209 pm_runtime_get_sync(&keypad->
pdev->dev);
232 pm_runtime_put(&keypad->
pdev->dev);
235 static int samsung_keypad_open(
struct input_dev *input_dev)
239 samsung_keypad_start(keypad);
244 static void samsung_keypad_close(
struct input_dev *input_dev)
248 samsung_keypad_stop(keypad);
259 unsigned int key_count;
263 dev_err(dev,
"could not allocate memory for platform data\n");
267 of_property_read_u32(np,
"samsung,keypad-num-rows", &num_rows);
268 of_property_read_u32(np,
"samsung,keypad-num-columns", &num_cols);
269 if (!num_rows || !num_cols) {
270 dev_err(dev,
"number of keypad rows/columns not specified\n");
273 pdata->
rows = num_rows;
274 pdata->
cols = num_cols;
278 dev_err(dev,
"could not allocate memory for keymap data\n");
283 key_count = of_get_child_count(np);
287 dev_err(dev,
"could not allocate memory for keymap\n");
290 keymap_data->
keymap = keymap;
293 u32 row, col, key_code;
294 of_property_read_u32(key_np,
"keypad,row", &row);
295 of_property_read_u32(key_np,
"keypad,column", &col);
296 of_property_read_u32(key_np,
"linux,code", &key_code);
297 *keymap++ =
KEY(row, col, key_code);
308 static void samsung_keypad_parse_dt_gpio(
struct device *dev,
314 for (row = 0; row < keypad->
rows; row++) {
315 gpio = of_get_named_gpio(np,
"row-gpios", row);
316 keypad->row_gpios[row] =
gpio;
317 if (!gpio_is_valid(gpio)) {
318 dev_err(dev,
"keypad row[%d]: invalid gpio %d\n",
325 dev_err(dev,
"keypad row[%d] gpio request failed\n",
329 for (col = 0; col < keypad->
cols; col++) {
330 gpio = of_get_named_gpio(np,
"col-gpios", col);
331 keypad->col_gpios[col] =
gpio;
332 if (!gpio_is_valid(gpio)) {
333 dev_err(dev,
"keypad column[%d]: invalid gpio %d\n",
340 dev_err(dev,
"keypad column[%d] gpio request failed\n",
345 static void samsung_keypad_dt_gpio_free(
struct samsung_keypad *keypad)
349 for (cnt = 0; cnt < keypad->
rows; cnt++)
350 if (gpio_is_valid(keypad->row_gpios[cnt]))
353 for (cnt = 0; cnt < keypad->
cols; cnt++)
354 if (gpio_is_valid(keypad->col_gpios[cnt]))
364 static void samsung_keypad_dt_gpio_free(
struct samsung_keypad *keypad)
375 struct input_dev *input_dev;
376 unsigned int row_shift;
377 unsigned int keymap_size;
380 if (pdev->
dev.of_node)
381 pdata = samsung_keypad_parse_dt(&pdev->
dev);
383 pdata = pdev->
dev.platform_data;
385 dev_err(&pdev->
dev,
"no platform data defined\n");
391 dev_err(&pdev->
dev,
"no keymap data defined\n");
405 row_shift = get_count_order(pdata->
cols);
406 keymap_size = (pdata->
rows << row_shift) *
sizeof(keypad->
keycodes[0]);
408 keypad = kzalloc(
sizeof(*keypad) + keymap_size,
GFP_KERNEL);
409 input_dev = input_allocate_device();
410 if (!keypad || !input_dev) {
428 if (IS_ERR(keypad->
clk)) {
429 dev_err(&pdev->
dev,
"failed to get keypad clk\n");
430 error = PTR_ERR(keypad->
clk);
436 dev_err(&pdev->
dev,
"keypad clock prepare failed\n");
448 if (pdev->
dev.of_node) {
450 samsung_keypad_parse_dt_gpio(&pdev->
dev, keypad);
452 "samsung,s5pv210-keypad");
458 input_dev->name = pdev->
name;
460 input_dev->dev.parent = &pdev->
dev;
462 input_dev->open = samsung_keypad_open;
463 input_dev->close = samsung_keypad_close;
469 dev_err(&pdev->
dev,
"failed to build keymap\n");
470 goto err_unprepare_clk;
477 input_set_drvdata(input_dev, keypad);
480 if (keypad->
irq < 0) {
488 dev_err(&pdev->
dev,
"failed to register keypad interrupt\n");
493 platform_set_drvdata(pdev, keypad);
496 error = input_register_device(keypad->
input_dev);
500 if (pdev->
dev.of_node) {
509 pm_runtime_disable(&pdev->
dev);
511 platform_set_drvdata(pdev,
NULL);
516 samsung_keypad_dt_gpio_free(keypad);
520 input_free_device(input_dev);
530 pm_runtime_disable(&pdev->
dev);
532 platform_set_drvdata(pdev,
NULL);
534 input_unregister_device(keypad->
input_dev);
544 samsung_keypad_dt_gpio_free(keypad);
552 #ifdef CONFIG_PM_RUNTIME
553 static int samsung_keypad_runtime_suspend(
struct device *dev)
564 error = enable_irq_wake(keypad->
irq);
577 static int samsung_keypad_runtime_resume(
struct device *dev)
593 disable_irq_wake(keypad->
irq);
599 #ifdef CONFIG_PM_SLEEP
600 static void samsung_keypad_toggle_wakeup(
struct samsung_keypad *keypad,
610 if (device_may_wakeup(&keypad->
pdev->dev))
611 enable_irq_wake(keypad->
irq);
614 if (device_may_wakeup(&keypad->
pdev->dev))
615 disable_irq_wake(keypad->
irq);
622 static int samsung_keypad_suspend(
struct device *dev)
626 struct input_dev *input_dev = keypad->
input_dev;
630 if (input_dev->users)
631 samsung_keypad_stop(keypad);
633 samsung_keypad_toggle_wakeup(keypad,
true);
640 static int samsung_keypad_resume(
struct device *dev)
644 struct input_dev *input_dev = keypad->
input_dev;
648 samsung_keypad_toggle_wakeup(keypad,
false);
650 if (input_dev->users)
651 samsung_keypad_start(keypad);
659 static const struct dev_pm_ops samsung_keypad_pm_ops = {
662 samsung_keypad_runtime_resume,
NULL)
666 static const struct of_device_id samsung_keypad_dt_match[] = {
668 { .compatible =
"samsung,s5pv210-keypad" },
676 .name =
"samsung-keypad",
679 .name =
"s5pv210-keypad",
687 .probe = samsung_keypad_probe,
690 .name =
"samsung-keypad",
692 .of_match_table =
of_match_ptr(samsung_keypad_dt_match),
693 .pm = &samsung_keypad_pm_ops,
695 .id_table = samsung_keypad_driver_ids,