Lines Matching refs:keypad

3  * Samsung keypad driver
23 #include <linux/input/samsung-keypad.h>
79 static void samsung_keypad_scan(struct samsung_keypad *keypad,
85 for (col = 0; col < keypad->cols; col++) {
86 if (keypad->type == KEYPAD_TYPE_S5PV210) {
94 writel(val, keypad->base + SAMSUNG_KEYIFCOL);
97 val = readl(keypad->base + SAMSUNG_KEYIFROW);
98 row_state[col] = ~val & ((1 << keypad->rows) - 1);
102 writel(0, keypad->base + SAMSUNG_KEYIFCOL);
105 static bool samsung_keypad_report(struct samsung_keypad *keypad,
108 struct input_dev *input_dev = keypad->input_dev;
115 for (col = 0; col < keypad->cols; col++) {
116 changed = row_state[col] ^ keypad->row_state[col];
121 for (row = 0; row < keypad->rows; row++) {
127 dev_dbg(&keypad->input_dev->dev,
131 val = MATRIX_SCAN_CODE(row, col, keypad->row_shift);
135 keypad->keycodes[val], pressed);
137 input_sync(keypad->input_dev);
140 memcpy(keypad->row_state, row_state, sizeof(keypad->row_state));
147 struct samsung_keypad *keypad = dev_id;
152 pm_runtime_get_sync(&keypad->pdev->dev);
155 val = readl(keypad->base + SAMSUNG_KEYIFSTSCLR);
157 writel(~0x0, keypad->base + SAMSUNG_KEYIFSTSCLR);
159 samsung_keypad_scan(keypad, row_state);
161 key_down = samsung_keypad_report(keypad, row_state);
163 wait_event_timeout(keypad->wait, keypad->stopped,
166 } while (key_down && !keypad->stopped);
168 pm_runtime_put(&keypad->pdev->dev);
173 static void samsung_keypad_start(struct samsung_keypad *keypad)
177 pm_runtime_get_sync(&keypad->pdev->dev);
180 keypad->stopped = false;
182 clk_enable(keypad->clk);
185 val = readl(keypad->base + SAMSUNG_KEYIFCON);
187 writel(val, keypad->base + SAMSUNG_KEYIFCON);
190 writel(0, keypad->base + SAMSUNG_KEYIFCOL);
192 pm_runtime_put(&keypad->pdev->dev);
195 static void samsung_keypad_stop(struct samsung_keypad *keypad)
199 pm_runtime_get_sync(&keypad->pdev->dev);
202 keypad->stopped = true;
203 wake_up(&keypad->wait);
204 disable_irq(keypad->irq);
207 writel(~0x0, keypad->base + SAMSUNG_KEYIFSTSCLR);
210 val = readl(keypad->base + SAMSUNG_KEYIFCON);
212 writel(val, keypad->base + SAMSUNG_KEYIFCON);
214 clk_disable(keypad->clk);
220 enable_irq(keypad->irq);
222 pm_runtime_put(&keypad->pdev->dev);
227 struct samsung_keypad *keypad = input_get_drvdata(input_dev);
229 samsung_keypad_start(keypad);
236 struct samsung_keypad *keypad = input_get_drvdata(input_dev);
238 samsung_keypad_stop(keypad);
262 of_property_read_u32(np, "samsung,keypad-num-rows", &num_rows);
263 of_property_read_u32(np, "samsung,keypad-num-columns", &num_cols);
265 dev_err(dev, "number of keypad rows/columns not specified\n");
289 of_property_read_u32(key_np, "keypad,row", &row);
290 of_property_read_u32(key_np, "keypad,column", &col);
319 struct samsung_keypad *keypad;
350 keymap_size = (pdata->rows << row_shift) * sizeof(keypad->keycodes[0]);
352 keypad = devm_kzalloc(&pdev->dev, sizeof(*keypad) + keymap_size,
355 if (!keypad || !input_dev)
362 keypad->base = devm_ioremap(&pdev->dev, res->start, resource_size(res));
363 if (!keypad->base)
366 keypad->clk = devm_clk_get(&pdev->dev, "keypad");
367 if (IS_ERR(keypad->clk)) {
368 dev_err(&pdev->dev, "failed to get keypad clk\n");
369 return PTR_ERR(keypad->clk);
372 error = clk_prepare(keypad->clk);
374 dev_err(&pdev->dev, "keypad clock prepare failed\n");
378 keypad->input_dev = input_dev;
379 keypad->pdev = pdev;
380 keypad->row_shift = row_shift;
381 keypad->rows = pdata->rows;
382 keypad->cols = pdata->cols;
383 keypad->stopped = true;
384 init_waitqueue_head(&keypad->wait);
387 keypad->type = of_device_is_compatible(pdev->dev.of_node,
388 "samsung,s5pv210-keypad");
390 keypad->type = platform_get_device_id(pdev)->driver_data;
401 keypad->keycodes, input_dev);
411 input_set_drvdata(input_dev, keypad);
413 keypad->irq = platform_get_irq(pdev, 0);
414 if (keypad->irq < 0) {
415 error = keypad->irq;
419 error = devm_request_threaded_irq(&pdev->dev, keypad->irq, NULL,
421 dev_name(&pdev->dev), keypad);
423 dev_err(&pdev->dev, "failed to register keypad interrupt\n");
428 platform_set_drvdata(pdev, keypad);
431 error = input_register_device(keypad->input_dev);
445 clk_unprepare(keypad->clk);
451 struct samsung_keypad *keypad = platform_get_drvdata(pdev);
455 input_unregister_device(keypad->input_dev);
457 clk_unprepare(keypad->clk);
466 struct samsung_keypad *keypad = platform_get_drvdata(pdev);
470 if (keypad->stopped)
474 error = enable_irq_wake(keypad->irq);
476 keypad->wake_enabled = true;
478 val = readl(keypad->base + SAMSUNG_KEYIFCON);
480 writel(val, keypad->base + SAMSUNG_KEYIFCON);
482 clk_disable(keypad->clk);
490 struct samsung_keypad *keypad = platform_get_drvdata(pdev);
493 if (keypad->stopped)
496 clk_enable(keypad->clk);
498 val = readl(keypad->base + SAMSUNG_KEYIFCON);
500 writel(val, keypad->base + SAMSUNG_KEYIFCON);
502 if (keypad->wake_enabled)
503 disable_irq_wake(keypad->irq);
510 static void samsung_keypad_toggle_wakeup(struct samsung_keypad *keypad,
515 clk_enable(keypad->clk);
517 val = readl(keypad->base + SAMSUNG_KEYIFCON);
520 if (device_may_wakeup(&keypad->pdev->dev))
521 enable_irq_wake(keypad->irq);
524 if (device_may_wakeup(&keypad->pdev->dev))
525 disable_irq_wake(keypad->irq);
527 writel(val, keypad->base + SAMSUNG_KEYIFCON);
529 clk_disable(keypad->clk);
535 struct samsung_keypad *keypad = platform_get_drvdata(pdev);
536 struct input_dev *input_dev = keypad->input_dev;
541 samsung_keypad_stop(keypad);
543 samsung_keypad_toggle_wakeup(keypad, true);
553 struct samsung_keypad *keypad = platform_get_drvdata(pdev);
554 struct input_dev *input_dev = keypad->input_dev;
558 samsung_keypad_toggle_wakeup(keypad, false);
561 samsung_keypad_start(keypad);
577 { .compatible = "samsung,s3c6410-keypad" },
578 { .compatible = "samsung,s5pv210-keypad" },
586 .name = "samsung-keypad",
589 .name = "s5pv210-keypad",
600 .name = "samsung-keypad",
608 MODULE_DESCRIPTION("Samsung keypad driver");