Lines Matching +full:wakeup +full:- +full:delay
1 // SPDX-License-Identifier: GPL-2.0-or-later
6 * Copyright (c) 2009-2011, NVIDIA Corporation.
13 #include <linux/delay.h>
33 /* KBC row scan time and delay for beginning the row scan. */
89 bool wakeup; member
156 val = readl(kbc->mmio + KBC_KP_ENT0_0 + i); in tegra_kbc_report_keys()
165 keycodes[num_down] = kbc->keycode[scancode]; in tegra_kbc_report_keys()
167 if ((keycodes[num_down] == KEY_FN) && kbc->use_fn_map) in tegra_kbc_report_keys()
178 * Ghosting occurs if there are 3 keys such that - in tegra_kbc_report_keys()
182 if (kbc->use_ghost_filter && num_down >= 3) { in tegra_kbc_report_keys()
190 * and the other is in the same column as the i-th key. in tegra_kbc_report_keys()
210 scancodes[i] += kbc->max_keys; in tegra_kbc_report_keys()
211 keycodes[i] = kbc->keycode[scancodes[i]]; in tegra_kbc_report_keys()
219 tegra_kbc_report_released_keys(kbc->idev, in tegra_kbc_report_keys()
220 kbc->current_keys, kbc->num_pressed_keys, in tegra_kbc_report_keys()
222 tegra_kbc_report_pressed_keys(kbc->idev, scancodes, keycodes, num_down); in tegra_kbc_report_keys()
223 input_sync(kbc->idev); in tegra_kbc_report_keys()
225 memcpy(kbc->current_keys, keycodes, sizeof(kbc->current_keys)); in tegra_kbc_report_keys()
226 kbc->num_pressed_keys = num_down; in tegra_kbc_report_keys()
233 val = readl(kbc->mmio + KBC_CONTROL_0); in tegra_kbc_set_fifo_interrupt()
238 writel(val, kbc->mmio + KBC_CONTROL_0); in tegra_kbc_set_fifo_interrupt()
247 guard(spinlock_irqsave)(&kbc->lock); in tegra_kbc_keypress_timer()
249 val = (readl(kbc->mmio + KBC_INT_0) >> 4) & 0xf; in tegra_kbc_keypress_timer()
257 * for the repoll delay. in tegra_kbc_keypress_timer()
259 dly = (val == 1) ? kbc->repoll_dly : 1; in tegra_kbc_keypress_timer()
260 mod_timer(&kbc->timer, jiffies + msecs_to_jiffies(dly)); in tegra_kbc_keypress_timer()
263 for (i = 0; i < kbc->num_pressed_keys; i++) in tegra_kbc_keypress_timer()
264 input_report_key(kbc->idev, kbc->current_keys[i], 0); in tegra_kbc_keypress_timer()
265 input_sync(kbc->idev); in tegra_kbc_keypress_timer()
267 kbc->num_pressed_keys = 0; in tegra_kbc_keypress_timer()
279 guard(spinlock_irqsave)(&kbc->lock); in tegra_kbc_isr()
285 val = readl(kbc->mmio + KBC_INT_0); in tegra_kbc_isr()
286 writel(val, kbc->mmio + KBC_INT_0); in tegra_kbc_isr()
294 mod_timer(&kbc->timer, jiffies + kbc->cp_dly_jiffies); in tegra_kbc_isr()
297 kbc->keypress_caused_wake = true; in tegra_kbc_isr()
309 rst_val = (filter && !kbc->wakeup) ? ~0 : 0; in tegra_kbc_setup_wakekeys()
311 for (i = 0; i < kbc->hw_support->max_rows; i++) in tegra_kbc_setup_wakekeys()
312 writel(rst_val, kbc->mmio + KBC_ROW0_MASK_0 + i * 4); in tegra_kbc_setup_wakekeys()
326 u32 row_cfg = readl(kbc->mmio + r_offs); in tegra_kbc_config_pins()
327 u32 col_cfg = readl(kbc->mmio + c_offs); in tegra_kbc_config_pins()
332 switch (kbc->pin_cfg[i].type) { in tegra_kbc_config_pins()
334 row_cfg |= ((kbc->pin_cfg[i].num << 1) | 1) << r_shft; in tegra_kbc_config_pins()
338 col_cfg |= ((kbc->pin_cfg[i].num << 1) | 1) << c_shft; in tegra_kbc_config_pins()
345 writel(row_cfg, kbc->mmio + r_offs); in tegra_kbc_config_pins()
346 writel(col_cfg, kbc->mmio + c_offs); in tegra_kbc_config_pins()
356 ret = clk_prepare_enable(kbc->clk); in tegra_kbc_start()
361 reset_control_assert(kbc->rst); in tegra_kbc_start()
363 reset_control_deassert(kbc->rst); in tegra_kbc_start()
369 writel(kbc->repeat_cnt, kbc->mmio + KBC_RPT_DLY_0); in tegra_kbc_start()
372 debounce_cnt = min(kbc->debounce_cnt, KBC_MAX_DEBOUNCE_CNT); in tegra_kbc_start()
377 writel(val, kbc->mmio + KBC_CONTROL_0); in tegra_kbc_start()
380 * Compute the delay(ns) from interrupt mode to continuous polling in tegra_kbc_start()
383 val = readl(kbc->mmio + KBC_INIT_DLY_0); in tegra_kbc_start()
384 kbc->cp_dly_jiffies = usecs_to_jiffies((val & 0xfffff) * 32); in tegra_kbc_start()
386 kbc->num_pressed_keys = 0; in tegra_kbc_start()
393 val = readl(kbc->mmio + KBC_INT_0); in tegra_kbc_start()
398 val = readl(kbc->mmio + KBC_KP_ENT0_0); in tegra_kbc_start()
399 val = readl(kbc->mmio + KBC_KP_ENT1_0); in tegra_kbc_start()
401 writel(0x7, kbc->mmio + KBC_INT_0); in tegra_kbc_start()
403 enable_irq(kbc->irq); in tegra_kbc_start()
412 scoped_guard(spinlock_irqsave, &kbc->lock) { in tegra_kbc_stop()
413 val = readl(kbc->mmio + KBC_CONTROL_0); in tegra_kbc_stop()
415 writel(val, kbc->mmio + KBC_CONTROL_0); in tegra_kbc_stop()
418 disable_irq(kbc->irq); in tegra_kbc_stop()
419 del_timer_sync(&kbc->timer); in tegra_kbc_stop()
421 clk_disable_unprepare(kbc->clk); in tegra_kbc_stop()
446 const struct tegra_kbc_pin_cfg *pin_cfg = &kbc->pin_cfg[i]; in tegra_kbc_check_pin_cfg()
448 switch (pin_cfg->type) { in tegra_kbc_check_pin_cfg()
450 if (pin_cfg->num >= kbc->hw_support->max_rows) { in tegra_kbc_check_pin_cfg()
451 dev_err(kbc->dev, in tegra_kbc_check_pin_cfg()
453 i, pin_cfg->num); in tegra_kbc_check_pin_cfg()
460 if (pin_cfg->num >= kbc->hw_support->max_columns) { in tegra_kbc_check_pin_cfg()
461 dev_err(kbc->dev, in tegra_kbc_check_pin_cfg()
463 i, pin_cfg->num); in tegra_kbc_check_pin_cfg()
472 dev_err(kbc->dev, in tegra_kbc_check_pin_cfg()
474 pin_cfg->type, pin_cfg->num); in tegra_kbc_check_pin_cfg()
484 struct device_node *np = kbc->dev->of_node; in tegra_kbc_parse_dt()
492 if (!of_property_read_u32(np, "nvidia,debounce-delay-ms", &prop)) in tegra_kbc_parse_dt()
493 kbc->debounce_cnt = prop; in tegra_kbc_parse_dt()
495 if (!of_property_read_u32(np, "nvidia,repeat-delay-ms", &prop)) in tegra_kbc_parse_dt()
496 kbc->repeat_cnt = prop; in tegra_kbc_parse_dt()
498 kbc->use_ghost_filter = of_property_present(np, "nvidia,needs-ghost-filter"); in tegra_kbc_parse_dt()
500 if (of_property_read_bool(np, "wakeup-source") || in tegra_kbc_parse_dt()
501 of_property_read_bool(np, "nvidia,wakeup-source")) /* legacy */ in tegra_kbc_parse_dt()
502 kbc->wakeup = true; in tegra_kbc_parse_dt()
505 dev_err(kbc->dev, "property linux,keymap not found\n"); in tegra_kbc_parse_dt()
506 return -ENOENT; in tegra_kbc_parse_dt()
509 /* Set all pins as non-configured */ in tegra_kbc_parse_dt()
510 for (i = 0; i < kbc->num_rows_and_columns; i++) in tegra_kbc_parse_dt()
511 kbc->pin_cfg[i].type = PIN_CFG_IGNORE; in tegra_kbc_parse_dt()
513 num_rows = of_property_read_variable_u32_array(np, "nvidia,kbc-row-pins", in tegra_kbc_parse_dt()
516 dev_err(kbc->dev, "Rows configurations are not proper\n"); in tegra_kbc_parse_dt()
518 } else if (num_rows > kbc->hw_support->max_rows) { in tegra_kbc_parse_dt()
519 dev_err(kbc->dev, in tegra_kbc_parse_dt()
521 return -EINVAL; in tegra_kbc_parse_dt()
525 kbc->pin_cfg[rows_cfg[i]].type = PIN_CFG_ROW; in tegra_kbc_parse_dt()
526 kbc->pin_cfg[rows_cfg[i]].num = i; in tegra_kbc_parse_dt()
529 num_cols = of_property_read_variable_u32_array(np, "nvidia,kbc-col-pins", in tegra_kbc_parse_dt()
532 dev_err(kbc->dev, "Cols configurations are not proper\n"); in tegra_kbc_parse_dt()
534 } else if (num_cols > kbc->hw_support->max_columns) { in tegra_kbc_parse_dt()
535 dev_err(kbc->dev, in tegra_kbc_parse_dt()
537 return -EINVAL; in tegra_kbc_parse_dt()
541 kbc->pin_cfg[cols_cfg[i]].type = PIN_CFG_COL; in tegra_kbc_parse_dt()
542 kbc->pin_cfg[cols_cfg[i]].num = i; in tegra_kbc_parse_dt()
546 dev_err(kbc->dev, in tegra_kbc_parse_dt()
548 return -EINVAL; in tegra_kbc_parse_dt()
565 { .compatible = "nvidia,tegra114-kbc", .data = &tegra11_kbc_hw_support},
566 { .compatible = "nvidia,tegra30-kbc", .data = &tegra20_kbc_hw_support},
567 { .compatible = "nvidia,tegra20-kbc", .data = &tegra20_kbc_hw_support},
581 kbc = devm_kzalloc(&pdev->dev, sizeof(*kbc), GFP_KERNEL); in tegra_kbc_probe()
583 dev_err(&pdev->dev, "failed to alloc memory for kbc\n"); in tegra_kbc_probe()
584 return -ENOMEM; in tegra_kbc_probe()
587 kbc->dev = &pdev->dev; in tegra_kbc_probe()
588 kbc->hw_support = device_get_match_data(&pdev->dev); in tegra_kbc_probe()
589 kbc->max_keys = kbc->hw_support->max_rows * in tegra_kbc_probe()
590 kbc->hw_support->max_columns; in tegra_kbc_probe()
591 kbc->num_rows_and_columns = kbc->hw_support->max_rows + in tegra_kbc_probe()
592 kbc->hw_support->max_columns; in tegra_kbc_probe()
593 keymap_rows = kbc->max_keys; in tegra_kbc_probe()
594 spin_lock_init(&kbc->lock); in tegra_kbc_probe()
601 return -EINVAL; in tegra_kbc_probe()
603 kbc->irq = platform_get_irq(pdev, 0); in tegra_kbc_probe()
604 if (kbc->irq < 0) in tegra_kbc_probe()
605 return -ENXIO; in tegra_kbc_probe()
607 kbc->idev = devm_input_allocate_device(&pdev->dev); in tegra_kbc_probe()
608 if (!kbc->idev) { in tegra_kbc_probe()
609 dev_err(&pdev->dev, "failed to allocate input device\n"); in tegra_kbc_probe()
610 return -ENOMEM; in tegra_kbc_probe()
613 timer_setup(&kbc->timer, tegra_kbc_keypress_timer, 0); in tegra_kbc_probe()
615 kbc->mmio = devm_platform_ioremap_resource(pdev, 0); in tegra_kbc_probe()
616 if (IS_ERR(kbc->mmio)) in tegra_kbc_probe()
617 return PTR_ERR(kbc->mmio); in tegra_kbc_probe()
619 kbc->clk = devm_clk_get(&pdev->dev, NULL); in tegra_kbc_probe()
620 if (IS_ERR(kbc->clk)) { in tegra_kbc_probe()
621 dev_err(&pdev->dev, "failed to get keyboard clock\n"); in tegra_kbc_probe()
622 return PTR_ERR(kbc->clk); in tegra_kbc_probe()
625 kbc->rst = devm_reset_control_get(&pdev->dev, "kbc"); in tegra_kbc_probe()
626 if (IS_ERR(kbc->rst)) { in tegra_kbc_probe()
627 dev_err(&pdev->dev, "failed to get keyboard reset\n"); in tegra_kbc_probe()
628 return PTR_ERR(kbc->rst); in tegra_kbc_probe()
632 * The time delay between two consecutive reads of the FIFO is in tegra_kbc_probe()
634 * the rows. There is an additional delay before the row scanning in tegra_kbc_probe()
635 * starts. The repoll delay is computed in milliseconds. in tegra_kbc_probe()
637 debounce_cnt = min(kbc->debounce_cnt, KBC_MAX_DEBOUNCE_CNT); in tegra_kbc_probe()
639 kbc->repoll_dly = KBC_ROW_SCAN_DLY + scan_time_rows + kbc->repeat_cnt; in tegra_kbc_probe()
640 kbc->repoll_dly = DIV_ROUND_UP(kbc->repoll_dly, KBC_CYCLE_MS); in tegra_kbc_probe()
642 kbc->idev->name = pdev->name; in tegra_kbc_probe()
643 kbc->idev->id.bustype = BUS_HOST; in tegra_kbc_probe()
644 kbc->idev->dev.parent = &pdev->dev; in tegra_kbc_probe()
645 kbc->idev->open = tegra_kbc_open; in tegra_kbc_probe()
646 kbc->idev->close = tegra_kbc_close; in tegra_kbc_probe()
648 if (kbc->keymap_data && kbc->use_fn_map) in tegra_kbc_probe()
651 err = matrix_keypad_build_keymap(kbc->keymap_data, NULL, in tegra_kbc_probe()
653 kbc->hw_support->max_columns, in tegra_kbc_probe()
654 kbc->keycode, kbc->idev); in tegra_kbc_probe()
656 dev_err(&pdev->dev, "failed to setup keymap\n"); in tegra_kbc_probe()
660 __set_bit(EV_REP, kbc->idev->evbit); in tegra_kbc_probe()
661 input_set_capability(kbc->idev, EV_MSC, MSC_SCAN); in tegra_kbc_probe()
663 input_set_drvdata(kbc->idev, kbc); in tegra_kbc_probe()
665 err = devm_request_irq(&pdev->dev, kbc->irq, tegra_kbc_isr, in tegra_kbc_probe()
667 pdev->name, kbc); in tegra_kbc_probe()
669 dev_err(&pdev->dev, "failed to request keyboard IRQ\n"); in tegra_kbc_probe()
673 err = input_register_device(kbc->idev); in tegra_kbc_probe()
675 dev_err(&pdev->dev, "failed to register input device\n"); in tegra_kbc_probe()
680 device_init_wakeup(&pdev->dev, kbc->wakeup); in tegra_kbc_probe()
689 val = readl(kbc->mmio + KBC_CONTROL_0); in tegra_kbc_set_keypress_interrupt()
694 writel(val, kbc->mmio + KBC_CONTROL_0); in tegra_kbc_set_keypress_interrupt()
702 guard(mutex)(&kbc->idev->mutex); in tegra_kbc_suspend()
704 if (device_may_wakeup(&pdev->dev)) { in tegra_kbc_suspend()
705 disable_irq(kbc->irq); in tegra_kbc_suspend()
706 del_timer_sync(&kbc->timer); in tegra_kbc_suspend()
710 writel(0x7, kbc->mmio + KBC_INT_0); in tegra_kbc_suspend()
715 kbc->cp_to_wkup_dly = readl(kbc->mmio + KBC_TO_CNT_0); in tegra_kbc_suspend()
716 writel(0, kbc->mmio + KBC_TO_CNT_0); in tegra_kbc_suspend()
721 kbc->keypress_caused_wake = false; in tegra_kbc_suspend()
724 enable_irq(kbc->irq); in tegra_kbc_suspend()
725 enable_irq_wake(kbc->irq); in tegra_kbc_suspend()
726 } else if (input_device_enabled(kbc->idev)) { in tegra_kbc_suspend()
739 guard(mutex)(&kbc->idev->mutex); in tegra_kbc_resume()
741 if (device_may_wakeup(&pdev->dev)) { in tegra_kbc_resume()
742 disable_irq_wake(kbc->irq); in tegra_kbc_resume()
748 writel(kbc->cp_to_wkup_dly, kbc->mmio + KBC_TO_CNT_0); in tegra_kbc_resume()
752 if (kbc->keypress_caused_wake && kbc->wakeup_key) { in tegra_kbc_resume()
756 * wakeup request and we get a nasty warning when in tegra_kbc_resume()
760 input_report_key(kbc->idev, kbc->wakeup_key, 1); in tegra_kbc_resume()
761 input_sync(kbc->idev); in tegra_kbc_resume()
762 input_report_key(kbc->idev, kbc->wakeup_key, 0); in tegra_kbc_resume()
763 input_sync(kbc->idev); in tegra_kbc_resume()
765 } else if (input_device_enabled(kbc->idev)) { in tegra_kbc_resume()
780 .name = "tegra-kbc",
790 MODULE_ALIAS("platform:tegra-kbc");