Lines Matching refs:kbc

156 static void tegra_kbc_report_keys(struct tegra_kbc *kbc)  in tegra_kbc_report_keys()  argument
169 val = readl(kbc->mmio + KBC_KP_ENT0_0 + i); in tegra_kbc_report_keys()
178 keycodes[num_down] = kbc->keycode[scancode]; in tegra_kbc_report_keys()
180 if ((keycodes[num_down] == KEY_FN) && kbc->use_fn_map) in tegra_kbc_report_keys()
195 if (kbc->use_ghost_filter && num_down >= 3) { in tegra_kbc_report_keys()
223 scancodes[i] += kbc->max_keys; in tegra_kbc_report_keys()
224 keycodes[i] = kbc->keycode[scancodes[i]]; in tegra_kbc_report_keys()
232 tegra_kbc_report_released_keys(kbc->idev, in tegra_kbc_report_keys()
233 kbc->current_keys, kbc->num_pressed_keys, in tegra_kbc_report_keys()
235 tegra_kbc_report_pressed_keys(kbc->idev, scancodes, keycodes, num_down); in tegra_kbc_report_keys()
236 input_sync(kbc->idev); in tegra_kbc_report_keys()
238 memcpy(kbc->current_keys, keycodes, sizeof(kbc->current_keys)); in tegra_kbc_report_keys()
239 kbc->num_pressed_keys = num_down; in tegra_kbc_report_keys()
242 static void tegra_kbc_set_fifo_interrupt(struct tegra_kbc *kbc, bool enable) in tegra_kbc_set_fifo_interrupt() argument
246 val = readl(kbc->mmio + KBC_CONTROL_0); in tegra_kbc_set_fifo_interrupt()
251 writel(val, kbc->mmio + KBC_CONTROL_0); in tegra_kbc_set_fifo_interrupt()
256 struct tegra_kbc *kbc = from_timer(kbc, t, timer); in tegra_kbc_keypress_timer() local
261 spin_lock_irqsave(&kbc->lock, flags); in tegra_kbc_keypress_timer()
263 val = (readl(kbc->mmio + KBC_INT_0) >> 4) & 0xf; in tegra_kbc_keypress_timer()
267 tegra_kbc_report_keys(kbc); in tegra_kbc_keypress_timer()
273 dly = (val == 1) ? kbc->repoll_dly : 1; in tegra_kbc_keypress_timer()
274 mod_timer(&kbc->timer, jiffies + msecs_to_jiffies(dly)); in tegra_kbc_keypress_timer()
277 for (i = 0; i < kbc->num_pressed_keys; i++) in tegra_kbc_keypress_timer()
278 input_report_key(kbc->idev, kbc->current_keys[i], 0); in tegra_kbc_keypress_timer()
279 input_sync(kbc->idev); in tegra_kbc_keypress_timer()
281 kbc->num_pressed_keys = 0; in tegra_kbc_keypress_timer()
284 tegra_kbc_set_fifo_interrupt(kbc, true); in tegra_kbc_keypress_timer()
287 spin_unlock_irqrestore(&kbc->lock, flags); in tegra_kbc_keypress_timer()
292 struct tegra_kbc *kbc = args; in tegra_kbc_isr() local
296 spin_lock_irqsave(&kbc->lock, flags); in tegra_kbc_isr()
302 val = readl(kbc->mmio + KBC_INT_0); in tegra_kbc_isr()
303 writel(val, kbc->mmio + KBC_INT_0); in tegra_kbc_isr()
310 tegra_kbc_set_fifo_interrupt(kbc, false); in tegra_kbc_isr()
311 mod_timer(&kbc->timer, jiffies + kbc->cp_dly_jiffies); in tegra_kbc_isr()
314 kbc->keypress_caused_wake = true; in tegra_kbc_isr()
317 spin_unlock_irqrestore(&kbc->lock, flags); in tegra_kbc_isr()
322 static void tegra_kbc_setup_wakekeys(struct tegra_kbc *kbc, bool filter) in tegra_kbc_setup_wakekeys() argument
328 rst_val = (filter && !kbc->wakeup) ? ~0 : 0; in tegra_kbc_setup_wakekeys()
330 for (i = 0; i < kbc->hw_support->max_rows; i++) in tegra_kbc_setup_wakekeys()
331 writel(rst_val, kbc->mmio + KBC_ROW0_MASK_0 + i * 4); in tegra_kbc_setup_wakekeys()
334 static void tegra_kbc_config_pins(struct tegra_kbc *kbc) in tegra_kbc_config_pins() argument
345 u32 row_cfg = readl(kbc->mmio + r_offs); in tegra_kbc_config_pins()
346 u32 col_cfg = readl(kbc->mmio + c_offs); in tegra_kbc_config_pins()
351 switch (kbc->pin_cfg[i].type) { in tegra_kbc_config_pins()
353 row_cfg |= ((kbc->pin_cfg[i].num << 1) | 1) << r_shft; in tegra_kbc_config_pins()
357 col_cfg |= ((kbc->pin_cfg[i].num << 1) | 1) << c_shft; in tegra_kbc_config_pins()
364 writel(row_cfg, kbc->mmio + r_offs); in tegra_kbc_config_pins()
365 writel(col_cfg, kbc->mmio + c_offs); in tegra_kbc_config_pins()
369 static int tegra_kbc_start(struct tegra_kbc *kbc) in tegra_kbc_start() argument
375 ret = clk_prepare_enable(kbc->clk); in tegra_kbc_start()
380 reset_control_assert(kbc->rst); in tegra_kbc_start()
382 reset_control_deassert(kbc->rst); in tegra_kbc_start()
385 tegra_kbc_config_pins(kbc); in tegra_kbc_start()
386 tegra_kbc_setup_wakekeys(kbc, false); in tegra_kbc_start()
388 writel(kbc->repeat_cnt, kbc->mmio + KBC_RPT_DLY_0); in tegra_kbc_start()
391 debounce_cnt = min(kbc->debounce_cnt, KBC_MAX_DEBOUNCE_CNT); in tegra_kbc_start()
396 writel(val, kbc->mmio + KBC_CONTROL_0); in tegra_kbc_start()
402 val = readl(kbc->mmio + KBC_INIT_DLY_0); in tegra_kbc_start()
403 kbc->cp_dly_jiffies = usecs_to_jiffies((val & 0xfffff) * 32); in tegra_kbc_start()
405 kbc->num_pressed_keys = 0; in tegra_kbc_start()
412 val = readl(kbc->mmio + KBC_INT_0); in tegra_kbc_start()
417 val = readl(kbc->mmio + KBC_KP_ENT0_0); in tegra_kbc_start()
418 val = readl(kbc->mmio + KBC_KP_ENT1_0); in tegra_kbc_start()
420 writel(0x7, kbc->mmio + KBC_INT_0); in tegra_kbc_start()
422 enable_irq(kbc->irq); in tegra_kbc_start()
427 static void tegra_kbc_stop(struct tegra_kbc *kbc) in tegra_kbc_stop() argument
432 spin_lock_irqsave(&kbc->lock, flags); in tegra_kbc_stop()
433 val = readl(kbc->mmio + KBC_CONTROL_0); in tegra_kbc_stop()
435 writel(val, kbc->mmio + KBC_CONTROL_0); in tegra_kbc_stop()
436 spin_unlock_irqrestore(&kbc->lock, flags); in tegra_kbc_stop()
438 disable_irq(kbc->irq); in tegra_kbc_stop()
439 del_timer_sync(&kbc->timer); in tegra_kbc_stop()
441 clk_disable_unprepare(kbc->clk); in tegra_kbc_stop()
446 struct tegra_kbc *kbc = input_get_drvdata(dev); in tegra_kbc_open() local
448 return tegra_kbc_start(kbc); in tegra_kbc_open()
453 struct tegra_kbc *kbc = input_get_drvdata(dev); in tegra_kbc_close() local
455 return tegra_kbc_stop(kbc); in tegra_kbc_close()
458 static bool tegra_kbc_check_pin_cfg(const struct tegra_kbc *kbc, in tegra_kbc_check_pin_cfg() argument
466 const struct tegra_kbc_pin_cfg *pin_cfg = &kbc->pin_cfg[i]; in tegra_kbc_check_pin_cfg()
470 if (pin_cfg->num >= kbc->hw_support->max_rows) { in tegra_kbc_check_pin_cfg()
471 dev_err(kbc->dev, in tegra_kbc_check_pin_cfg()
480 if (pin_cfg->num >= kbc->hw_support->max_columns) { in tegra_kbc_check_pin_cfg()
481 dev_err(kbc->dev, in tegra_kbc_check_pin_cfg()
492 dev_err(kbc->dev, in tegra_kbc_check_pin_cfg()
502 static int tegra_kbc_parse_dt(struct tegra_kbc *kbc) in tegra_kbc_parse_dt() argument
504 struct device_node *np = kbc->dev->of_node; in tegra_kbc_parse_dt()
515 kbc->debounce_cnt = prop; in tegra_kbc_parse_dt()
518 kbc->repeat_cnt = prop; in tegra_kbc_parse_dt()
521 kbc->use_ghost_filter = true; in tegra_kbc_parse_dt()
525 kbc->wakeup = true; in tegra_kbc_parse_dt()
528 dev_err(kbc->dev, "property nvidia,kbc-row-pins not found\n"); in tegra_kbc_parse_dt()
534 dev_err(kbc->dev, "property nvidia,kbc-col-pins not found\n"); in tegra_kbc_parse_dt()
539 if (num_rows > kbc->hw_support->max_rows) { in tegra_kbc_parse_dt()
540 dev_err(kbc->dev, in tegra_kbc_parse_dt()
545 if (num_cols > kbc->hw_support->max_columns) { in tegra_kbc_parse_dt()
546 dev_err(kbc->dev, in tegra_kbc_parse_dt()
552 dev_err(kbc->dev, "property linux,keymap not found\n"); in tegra_kbc_parse_dt()
557 dev_err(kbc->dev, in tegra_kbc_parse_dt()
563 for (i = 0; i < kbc->num_rows_and_columns; i++) in tegra_kbc_parse_dt()
564 kbc->pin_cfg[i].type = PIN_CFG_IGNORE; in tegra_kbc_parse_dt()
569 dev_err(kbc->dev, "Rows configurations are not proper\n"); in tegra_kbc_parse_dt()
576 dev_err(kbc->dev, "Cols configurations are not proper\n"); in tegra_kbc_parse_dt()
581 kbc->pin_cfg[rows_cfg[i]].type = PIN_CFG_ROW; in tegra_kbc_parse_dt()
582 kbc->pin_cfg[rows_cfg[i]].num = i; in tegra_kbc_parse_dt()
586 kbc->pin_cfg[cols_cfg[i]].type = PIN_CFG_COL; in tegra_kbc_parse_dt()
587 kbc->pin_cfg[cols_cfg[i]].num = i; in tegra_kbc_parse_dt()
613 struct tegra_kbc *kbc; in tegra_kbc_probe() local
624 kbc = devm_kzalloc(&pdev->dev, sizeof(*kbc), GFP_KERNEL); in tegra_kbc_probe()
625 if (!kbc) { in tegra_kbc_probe()
630 kbc->dev = &pdev->dev; in tegra_kbc_probe()
631 kbc->hw_support = match->data; in tegra_kbc_probe()
632 kbc->max_keys = kbc->hw_support->max_rows * in tegra_kbc_probe()
633 kbc->hw_support->max_columns; in tegra_kbc_probe()
634 kbc->num_rows_and_columns = kbc->hw_support->max_rows + in tegra_kbc_probe()
635 kbc->hw_support->max_columns; in tegra_kbc_probe()
636 keymap_rows = kbc->max_keys; in tegra_kbc_probe()
637 spin_lock_init(&kbc->lock); in tegra_kbc_probe()
639 err = tegra_kbc_parse_dt(kbc); in tegra_kbc_probe()
643 if (!tegra_kbc_check_pin_cfg(kbc, &num_rows)) in tegra_kbc_probe()
646 kbc->irq = platform_get_irq(pdev, 0); in tegra_kbc_probe()
647 if (kbc->irq < 0) { in tegra_kbc_probe()
652 kbc->idev = devm_input_allocate_device(&pdev->dev); in tegra_kbc_probe()
653 if (!kbc->idev) { in tegra_kbc_probe()
658 timer_setup(&kbc->timer, tegra_kbc_keypress_timer, 0); in tegra_kbc_probe()
661 kbc->mmio = devm_ioremap_resource(&pdev->dev, res); in tegra_kbc_probe()
662 if (IS_ERR(kbc->mmio)) in tegra_kbc_probe()
663 return PTR_ERR(kbc->mmio); in tegra_kbc_probe()
665 kbc->clk = devm_clk_get(&pdev->dev, NULL); in tegra_kbc_probe()
666 if (IS_ERR(kbc->clk)) { in tegra_kbc_probe()
668 return PTR_ERR(kbc->clk); in tegra_kbc_probe()
671 kbc->rst = devm_reset_control_get(&pdev->dev, "kbc"); in tegra_kbc_probe()
672 if (IS_ERR(kbc->rst)) { in tegra_kbc_probe()
674 return PTR_ERR(kbc->rst); in tegra_kbc_probe()
683 debounce_cnt = min(kbc->debounce_cnt, KBC_MAX_DEBOUNCE_CNT); in tegra_kbc_probe()
685 kbc->repoll_dly = KBC_ROW_SCAN_DLY + scan_time_rows + kbc->repeat_cnt; in tegra_kbc_probe()
686 kbc->repoll_dly = DIV_ROUND_UP(kbc->repoll_dly, KBC_CYCLE_MS); in tegra_kbc_probe()
688 kbc->idev->name = pdev->name; in tegra_kbc_probe()
689 kbc->idev->id.bustype = BUS_HOST; in tegra_kbc_probe()
690 kbc->idev->dev.parent = &pdev->dev; in tegra_kbc_probe()
691 kbc->idev->open = tegra_kbc_open; in tegra_kbc_probe()
692 kbc->idev->close = tegra_kbc_close; in tegra_kbc_probe()
694 if (kbc->keymap_data && kbc->use_fn_map) in tegra_kbc_probe()
697 err = matrix_keypad_build_keymap(kbc->keymap_data, NULL, in tegra_kbc_probe()
699 kbc->hw_support->max_columns, in tegra_kbc_probe()
700 kbc->keycode, kbc->idev); in tegra_kbc_probe()
706 __set_bit(EV_REP, kbc->idev->evbit); in tegra_kbc_probe()
707 input_set_capability(kbc->idev, EV_MSC, MSC_SCAN); in tegra_kbc_probe()
709 input_set_drvdata(kbc->idev, kbc); in tegra_kbc_probe()
711 err = devm_request_irq(&pdev->dev, kbc->irq, tegra_kbc_isr, in tegra_kbc_probe()
712 IRQF_TRIGGER_HIGH, pdev->name, kbc); in tegra_kbc_probe()
718 disable_irq(kbc->irq); in tegra_kbc_probe()
720 err = input_register_device(kbc->idev); in tegra_kbc_probe()
726 platform_set_drvdata(pdev, kbc); in tegra_kbc_probe()
727 device_init_wakeup(&pdev->dev, kbc->wakeup); in tegra_kbc_probe()
733 static void tegra_kbc_set_keypress_interrupt(struct tegra_kbc *kbc, bool enable) in tegra_kbc_set_keypress_interrupt() argument
737 val = readl(kbc->mmio + KBC_CONTROL_0); in tegra_kbc_set_keypress_interrupt()
742 writel(val, kbc->mmio + KBC_CONTROL_0); in tegra_kbc_set_keypress_interrupt()
748 struct tegra_kbc *kbc = platform_get_drvdata(pdev); in tegra_kbc_suspend() local
750 mutex_lock(&kbc->idev->mutex); in tegra_kbc_suspend()
752 disable_irq(kbc->irq); in tegra_kbc_suspend()
753 del_timer_sync(&kbc->timer); in tegra_kbc_suspend()
754 tegra_kbc_set_fifo_interrupt(kbc, false); in tegra_kbc_suspend()
757 writel(0x7, kbc->mmio + KBC_INT_0); in tegra_kbc_suspend()
762 kbc->cp_to_wkup_dly = readl(kbc->mmio + KBC_TO_CNT_0); in tegra_kbc_suspend()
763 writel(0, kbc->mmio + KBC_TO_CNT_0); in tegra_kbc_suspend()
765 tegra_kbc_setup_wakekeys(kbc, true); in tegra_kbc_suspend()
768 kbc->keypress_caused_wake = false; in tegra_kbc_suspend()
770 tegra_kbc_set_keypress_interrupt(kbc, true); in tegra_kbc_suspend()
771 enable_irq(kbc->irq); in tegra_kbc_suspend()
772 enable_irq_wake(kbc->irq); in tegra_kbc_suspend()
774 if (kbc->idev->users) in tegra_kbc_suspend()
775 tegra_kbc_stop(kbc); in tegra_kbc_suspend()
777 mutex_unlock(&kbc->idev->mutex); in tegra_kbc_suspend()
785 struct tegra_kbc *kbc = platform_get_drvdata(pdev); in tegra_kbc_resume() local
788 mutex_lock(&kbc->idev->mutex); in tegra_kbc_resume()
790 disable_irq_wake(kbc->irq); in tegra_kbc_resume()
791 tegra_kbc_setup_wakekeys(kbc, false); in tegra_kbc_resume()
793 tegra_kbc_set_keypress_interrupt(kbc, false); in tegra_kbc_resume()
796 writel(kbc->cp_to_wkup_dly, kbc->mmio + KBC_TO_CNT_0); in tegra_kbc_resume()
798 tegra_kbc_set_fifo_interrupt(kbc, true); in tegra_kbc_resume()
800 if (kbc->keypress_caused_wake && kbc->wakeup_key) { in tegra_kbc_resume()
808 input_report_key(kbc->idev, kbc->wakeup_key, 1); in tegra_kbc_resume()
809 input_sync(kbc->idev); in tegra_kbc_resume()
810 input_report_key(kbc->idev, kbc->wakeup_key, 0); in tegra_kbc_resume()
811 input_sync(kbc->idev); in tegra_kbc_resume()
814 if (kbc->idev->users) in tegra_kbc_resume()
815 err = tegra_kbc_start(kbc); in tegra_kbc_resume()
817 mutex_unlock(&kbc->idev->mutex); in tegra_kbc_resume()