Lines Matching +full:imx21 +full:- +full:kpp

1 // SPDX-License-Identifier: GPL-2.0
70 * -stable: achieved after a complete debounce process.
71 * -unstable: used in the debouncing process.
85 if ((keypad->cols_en_mask & (1 << col)) == 0) in imx_keypad_scan_matrix()
90 * 3. configure columns as totem-pole to discharge capacitance. in imx_keypad_scan_matrix()
91 * 4. configure columns as open-drain. in imx_keypad_scan_matrix()
93 reg_val = readw(keypad->mmio_base + KPDR); in imx_keypad_scan_matrix()
95 writew(reg_val, keypad->mmio_base + KPDR); in imx_keypad_scan_matrix()
97 reg_val = readw(keypad->mmio_base + KPCR); in imx_keypad_scan_matrix()
98 reg_val &= ~((keypad->cols_en_mask & 0xff) << 8); in imx_keypad_scan_matrix()
99 writew(reg_val, keypad->mmio_base + KPCR); in imx_keypad_scan_matrix()
103 reg_val = readw(keypad->mmio_base + KPCR); in imx_keypad_scan_matrix()
104 reg_val |= (keypad->cols_en_mask & 0xff) << 8; in imx_keypad_scan_matrix()
105 writew(reg_val, keypad->mmio_base + KPCR); in imx_keypad_scan_matrix()
110 * 7. Repeat steps 2 - 6 for remaining columns. in imx_keypad_scan_matrix()
112 reg_val = readw(keypad->mmio_base + KPDR); in imx_keypad_scan_matrix()
114 writew(reg_val, keypad->mmio_base + KPDR); in imx_keypad_scan_matrix()
126 reg_val = readw(keypad->mmio_base + KPDR); in imx_keypad_scan_matrix()
127 matrix_volatile_state[col] = (~reg_val) & keypad->rows_en_mask; in imx_keypad_scan_matrix()
134 reg_val = readw(keypad->mmio_base + KPDR); in imx_keypad_scan_matrix()
136 writew(reg_val, keypad->mmio_base + KPDR); in imx_keypad_scan_matrix()
141 * keypad->matrix_stable_state and fire events if changes are detected.
146 struct input_dev *input_dev = keypad->input_dev; in imx_keypad_fire_events()
153 if ((keypad->cols_en_mask & (1 << col)) == 0) in imx_keypad_fire_events()
156 bits_changed = keypad->matrix_stable_state[col] ^ in imx_keypad_fire_events()
163 if ((keypad->rows_en_mask & (1 << row)) == 0) in imx_keypad_fire_events()
170 input_report_key(input_dev, keypad->keycodes[code], in imx_keypad_fire_events()
172 dev_dbg(&input_dev->dev, "Event code: %d, val: %d", in imx_keypad_fire_events()
173 keypad->keycodes[code], in imx_keypad_fire_events()
197 if ((keypad->cols_en_mask & (1 << i)) == 0) in imx_keypad_check_for_events()
200 if (keypad->matrix_unstable_state[i] ^ matrix_volatile_state[i]) { in imx_keypad_check_for_events()
209 * keypad->matrix_unstable_state. in imx_keypad_check_for_events()
214 memcpy(keypad->matrix_unstable_state, matrix_volatile_state, in imx_keypad_check_for_events()
216 keypad->stable_count = 0; in imx_keypad_check_for_events()
218 keypad->stable_count++; in imx_keypad_check_for_events()
224 if (keypad->stable_count < IMX_KEYPAD_SCANS_FOR_STABILITY) { in imx_keypad_check_for_events()
225 mod_timer(&keypad->check_matrix_timer, in imx_keypad_check_for_events()
233 * (keypad->stable_count > IMX_KEYPAD_SCANS_FOR_STABILITY) all in imx_keypad_check_for_events()
236 if (keypad->stable_count == IMX_KEYPAD_SCANS_FOR_STABILITY) { in imx_keypad_check_for_events()
239 memcpy(keypad->matrix_stable_state, matrix_volatile_state, in imx_keypad_check_for_events()
258 reg_val = readw(keypad->mmio_base + KPSR); in imx_keypad_check_for_events()
260 writew(reg_val, keypad->mmio_base + KPSR); in imx_keypad_check_for_events()
262 reg_val = readw(keypad->mmio_base + KPSR); in imx_keypad_check_for_events()
265 writew(reg_val, keypad->mmio_base + KPSR); in imx_keypad_check_for_events()
273 mod_timer(&keypad->check_matrix_timer, in imx_keypad_check_for_events()
276 reg_val = readw(keypad->mmio_base + KPSR); in imx_keypad_check_for_events()
278 writew(reg_val, keypad->mmio_base + KPSR); in imx_keypad_check_for_events()
280 reg_val = readw(keypad->mmio_base + KPSR); in imx_keypad_check_for_events()
283 writew(reg_val, keypad->mmio_base + KPSR); in imx_keypad_check_for_events()
292 reg_val = readw(keypad->mmio_base + KPSR); in imx_keypad_irq_handler()
298 writew(reg_val, keypad->mmio_base + KPSR); in imx_keypad_irq_handler()
300 if (keypad->enabled) { in imx_keypad_irq_handler()
302 keypad->stable_count = 0; in imx_keypad_irq_handler()
305 mod_timer(&keypad->check_matrix_timer, in imx_keypad_irq_handler()
318 * Configure keypad columns as open-drain (KPCR[15:8]) in imx_keypad_config()
320 reg_val = readw(keypad->mmio_base + KPCR); in imx_keypad_config()
321 reg_val |= keypad->rows_en_mask & 0xff; /* rows */ in imx_keypad_config()
322 reg_val |= (keypad->cols_en_mask & 0xff) << 8; /* cols */ in imx_keypad_config()
323 writew(reg_val, keypad->mmio_base + KPCR); in imx_keypad_config()
326 reg_val = readw(keypad->mmio_base + KPDR); in imx_keypad_config()
328 writew(reg_val, keypad->mmio_base + KPDR); in imx_keypad_config()
331 writew(0xff00, keypad->mmio_base + KDDR); in imx_keypad_config()
337 reg_val = readw(keypad->mmio_base + KPSR); in imx_keypad_config()
340 writew(reg_val, keypad->mmio_base + KPSR); in imx_keypad_config()
345 writew(reg_val, keypad->mmio_base + KPSR); in imx_keypad_config()
353 reg_val = readw(keypad->mmio_base + KPSR); in imx_keypad_inhibit()
356 writew(reg_val, keypad->mmio_base + KPSR); in imx_keypad_inhibit()
359 reg_val = (keypad->cols_en_mask & 0xff) << 8; in imx_keypad_inhibit()
360 writew(reg_val, keypad->mmio_base + KPCR); in imx_keypad_inhibit()
367 dev_dbg(&dev->dev, ">%s\n", __func__); in imx_keypad_close()
370 keypad->enabled = false; in imx_keypad_close()
371 synchronize_irq(keypad->irq); in imx_keypad_close()
372 del_timer_sync(&keypad->check_matrix_timer); in imx_keypad_close()
377 clk_disable_unprepare(keypad->clk); in imx_keypad_close()
385 dev_dbg(&dev->dev, ">%s\n", __func__); in imx_keypad_open()
387 /* Enable the kpp clock */ in imx_keypad_open()
388 error = clk_prepare_enable(keypad->clk); in imx_keypad_open()
393 keypad->enabled = true; in imx_keypad_open()
398 if ((readw(keypad->mmio_base + KPDR) & keypad->rows_en_mask) == 0) { in imx_keypad_open()
399 dev_err(&dev->dev, in imx_keypad_open()
408 return -EIO; in imx_keypad_open()
412 { .compatible = "fsl,imx21-kpp", },
427 input_dev = devm_input_allocate_device(&pdev->dev); in imx_keypad_probe()
429 dev_err(&pdev->dev, "failed to allocate the input device\n"); in imx_keypad_probe()
430 return -ENOMEM; in imx_keypad_probe()
433 keypad = devm_kzalloc(&pdev->dev, sizeof(*keypad), GFP_KERNEL); in imx_keypad_probe()
435 dev_err(&pdev->dev, "not enough memory for driver data\n"); in imx_keypad_probe()
436 return -ENOMEM; in imx_keypad_probe()
439 keypad->input_dev = input_dev; in imx_keypad_probe()
440 keypad->irq = irq; in imx_keypad_probe()
441 keypad->stable_count = 0; in imx_keypad_probe()
443 timer_setup(&keypad->check_matrix_timer, in imx_keypad_probe()
446 keypad->mmio_base = devm_platform_ioremap_resource(pdev, 0); in imx_keypad_probe()
447 if (IS_ERR(keypad->mmio_base)) in imx_keypad_probe()
448 return PTR_ERR(keypad->mmio_base); in imx_keypad_probe()
450 keypad->clk = devm_clk_get(&pdev->dev, NULL); in imx_keypad_probe()
451 if (IS_ERR(keypad->clk)) { in imx_keypad_probe()
452 dev_err(&pdev->dev, "failed to get keypad clock\n"); in imx_keypad_probe()
453 return PTR_ERR(keypad->clk); in imx_keypad_probe()
457 input_dev->name = pdev->name; in imx_keypad_probe()
458 input_dev->id.bustype = BUS_HOST; in imx_keypad_probe()
459 input_dev->dev.parent = &pdev->dev; in imx_keypad_probe()
460 input_dev->open = imx_keypad_open; in imx_keypad_probe()
461 input_dev->close = imx_keypad_close; in imx_keypad_probe()
466 keypad->keycodes, input_dev); in imx_keypad_probe()
468 dev_err(&pdev->dev, "failed to build keymap\n"); in imx_keypad_probe()
476 if (keypad->keycodes[i] != KEY_RESERVED) { in imx_keypad_probe()
477 keypad->rows_en_mask |= 1 << row; in imx_keypad_probe()
478 keypad->cols_en_mask |= 1 << col; in imx_keypad_probe()
482 dev_dbg(&pdev->dev, "enabled rows mask: %x\n", keypad->rows_en_mask); in imx_keypad_probe()
483 dev_dbg(&pdev->dev, "enabled cols mask: %x\n", keypad->cols_en_mask); in imx_keypad_probe()
485 __set_bit(EV_REP, input_dev->evbit); in imx_keypad_probe()
490 error = clk_prepare_enable(keypad->clk); in imx_keypad_probe()
494 clk_disable_unprepare(keypad->clk); in imx_keypad_probe()
496 error = devm_request_irq(&pdev->dev, irq, imx_keypad_irq_handler, 0, in imx_keypad_probe()
497 pdev->name, keypad); in imx_keypad_probe()
499 dev_err(&pdev->dev, "failed to request IRQ\n"); in imx_keypad_probe()
506 dev_err(&pdev->dev, "failed to register input device\n"); in imx_keypad_probe()
511 device_init_wakeup(&pdev->dev, 1); in imx_keypad_probe()
520 struct input_dev *input_dev = kbd->input_dev; in imx_kbd_noirq_suspend()
521 unsigned short reg_val = readw(kbd->mmio_base + KPSR); in imx_kbd_noirq_suspend()
524 mutex_lock(&input_dev->mutex); in imx_kbd_noirq_suspend()
527 clk_disable_unprepare(kbd->clk); in imx_kbd_noirq_suspend()
529 mutex_unlock(&input_dev->mutex); in imx_kbd_noirq_suspend()
531 if (device_may_wakeup(&pdev->dev)) { in imx_kbd_noirq_suspend()
536 writew(reg_val, kbd->mmio_base + KPSR); in imx_kbd_noirq_suspend()
538 enable_irq_wake(kbd->irq); in imx_kbd_noirq_suspend()
548 struct input_dev *input_dev = kbd->input_dev; in imx_kbd_noirq_resume()
551 if (device_may_wakeup(&pdev->dev)) in imx_kbd_noirq_resume()
552 disable_irq_wake(kbd->irq); in imx_kbd_noirq_resume()
554 mutex_lock(&input_dev->mutex); in imx_kbd_noirq_resume()
557 ret = clk_prepare_enable(kbd->clk); in imx_kbd_noirq_resume()
563 mutex_unlock(&input_dev->mutex); in imx_kbd_noirq_resume()
574 .name = "imx-keypad",
585 MODULE_ALIAS("platform:imx-keypad");