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;
151 pm_runtime_get_sync(&keypad->pdev->dev);
154 readl(keypad->base + SAMSUNG_KEYIFSTSCLR);
156 writel(~0x0, keypad->base + SAMSUNG_KEYIFSTSCLR);
158 samsung_keypad_scan(keypad, row_state);
160 key_down = samsung_keypad_report(keypad, row_state);
162 wait_event_timeout(keypad->wait, keypad->stopped,
165 } while (key_down && !keypad->stopped);
167 pm_runtime_put(&keypad->pdev->dev);
172 static void samsung_keypad_start(struct samsung_keypad *keypad)
176 pm_runtime_get_sync(&keypad->pdev->dev);
179 keypad->stopped = false;
181 clk_enable(keypad->clk);
184 val = readl(keypad->base + SAMSUNG_KEYIFCON);
186 writel(val, keypad->base + SAMSUNG_KEYIFCON);
189 writel(0, keypad->base + SAMSUNG_KEYIFCOL);
191 pm_runtime_put(&keypad->pdev->dev);
194 static void samsung_keypad_stop(struct samsung_keypad *keypad)
198 pm_runtime_get_sync(&keypad->pdev->dev);
201 keypad->stopped = true;
202 wake_up(&keypad->wait);
203 disable_irq(keypad->irq);
206 writel(~0x0, keypad->base + SAMSUNG_KEYIFSTSCLR);
209 val = readl(keypad->base + SAMSUNG_KEYIFCON);
211 writel(val, keypad->base + SAMSUNG_KEYIFCON);
213 clk_disable(keypad->clk);
219 enable_irq(keypad->irq);
221 pm_runtime_put(&keypad->pdev->dev);
226 struct samsung_keypad *keypad = input_get_drvdata(input_dev);
228 samsung_keypad_start(keypad);
235 struct samsung_keypad *keypad = input_get_drvdata(input_dev);
237 samsung_keypad_stop(keypad);
261 of_property_read_u32(np, "samsung,keypad-num-rows", &num_rows);
262 of_property_read_u32(np, "samsung,keypad-num-columns", &num_cols);
264 dev_err(dev, "number of keypad rows/columns not specified\n");
288 of_property_read_u32(key_np, "keypad,row", &row);
289 of_property_read_u32(key_np, "keypad,column", &col);
317 struct samsung_keypad *keypad;
348 keymap_size = (pdata->rows << row_shift) * sizeof(keypad->keycodes[0]);
350 keypad = devm_kzalloc(&pdev->dev, sizeof(*keypad) + keymap_size,
353 if (!keypad || !input_dev)
360 keypad->base = devm_ioremap(&pdev->dev, res->start, resource_size(res));
361 if (!keypad->base)
364 keypad->clk = devm_clk_get(&pdev->dev, "keypad");
365 if (IS_ERR(keypad->clk)) {
366 dev_err(&pdev->dev, "failed to get keypad clk\n");
367 return PTR_ERR(keypad->clk);
370 error = clk_prepare(keypad->clk);
372 dev_err(&pdev->dev, "keypad clock prepare failed\n");
376 keypad->input_dev = input_dev;
377 keypad->pdev = pdev;
378 keypad->row_shift = row_shift;
379 keypad->rows = pdata->rows;
380 keypad->cols = pdata->cols;
381 keypad->stopped = true;
382 init_waitqueue_head(&keypad->wait);
385 keypad->type = of_device_is_compatible(pdev->dev.of_node,
386 "samsung,s5pv210-keypad");
388 keypad->type = platform_get_device_id(pdev)->driver_data;
399 keypad->keycodes, input_dev);
409 input_set_drvdata(input_dev, keypad);
411 keypad->irq = platform_get_irq(pdev, 0);
412 if (keypad->irq < 0) {
413 error = keypad->irq;
417 error = devm_request_threaded_irq(&pdev->dev, keypad->irq, NULL,
419 dev_name(&pdev->dev), keypad);
421 dev_err(&pdev->dev, "failed to register keypad interrupt\n");
426 platform_set_drvdata(pdev, keypad);
429 error = input_register_device(keypad->input_dev);
443 clk_unprepare(keypad->clk);
449 struct samsung_keypad *keypad = platform_get_drvdata(pdev);
453 input_unregister_device(keypad->input_dev);
455 clk_unprepare(keypad->clk);
463 struct samsung_keypad *keypad = platform_get_drvdata(pdev);
467 if (keypad->stopped)
471 error = enable_irq_wake(keypad->irq);
473 keypad->wake_enabled = true;
475 val = readl(keypad->base + SAMSUNG_KEYIFCON);
477 writel(val, keypad->base + SAMSUNG_KEYIFCON);
479 clk_disable(keypad->clk);
487 struct samsung_keypad *keypad = platform_get_drvdata(pdev);
490 if (keypad->stopped)
493 clk_enable(keypad->clk);
495 val = readl(keypad->base + SAMSUNG_KEYIFCON);
497 writel(val, keypad->base + SAMSUNG_KEYIFCON);
499 if (keypad->wake_enabled)
500 disable_irq_wake(keypad->irq);
505 static void samsung_keypad_toggle_wakeup(struct samsung_keypad *keypad,
510 clk_enable(keypad->clk);
512 val = readl(keypad->base + SAMSUNG_KEYIFCON);
515 if (device_may_wakeup(&keypad->pdev->dev))
516 enable_irq_wake(keypad->irq);
519 if (device_may_wakeup(&keypad->pdev->dev))
520 disable_irq_wake(keypad->irq);
522 writel(val, keypad->base + SAMSUNG_KEYIFCON);
524 clk_disable(keypad->clk);
530 struct samsung_keypad *keypad = platform_get_drvdata(pdev);
531 struct input_dev *input_dev = keypad->input_dev;
536 samsung_keypad_stop(keypad);
538 samsung_keypad_toggle_wakeup(keypad, true);
548 struct samsung_keypad *keypad = platform_get_drvdata(pdev);
549 struct input_dev *input_dev = keypad->input_dev;
553 samsung_keypad_toggle_wakeup(keypad, false);
556 samsung_keypad_start(keypad);
571 { .compatible = "samsung,s3c6410-keypad" },
572 { .compatible = "samsung,s5pv210-keypad" },
580 .name = "samsung-keypad",
583 .name = "s5pv210-keypad",
594 .name = "samsung-keypad",
602 MODULE_DESCRIPTION("Samsung keypad driver");