Lines Matching +full:imx21 +full:- +full:kpp
1 // SPDX-License-Identifier: GPL-2.0
71 * -stable: achieved after a complete debounce process.
72 * -unstable: used in the debouncing process.
86 if ((keypad->cols_en_mask & (1 << col)) == 0) in imx_keypad_scan_matrix()
91 * 3. configure columns as totem-pole to discharge capacitance. in imx_keypad_scan_matrix()
92 * 4. configure columns as open-drain. in imx_keypad_scan_matrix()
94 reg_val = readw(keypad->mmio_base + KPDR); in imx_keypad_scan_matrix()
96 writew(reg_val, keypad->mmio_base + KPDR); in imx_keypad_scan_matrix()
98 reg_val = readw(keypad->mmio_base + KPCR); in imx_keypad_scan_matrix()
99 reg_val &= ~((keypad->cols_en_mask & 0xff) << 8); in imx_keypad_scan_matrix()
100 writew(reg_val, keypad->mmio_base + KPCR); in imx_keypad_scan_matrix()
104 reg_val = readw(keypad->mmio_base + KPCR); in imx_keypad_scan_matrix()
105 reg_val |= (keypad->cols_en_mask & 0xff) << 8; in imx_keypad_scan_matrix()
106 writew(reg_val, keypad->mmio_base + KPCR); in imx_keypad_scan_matrix()
111 * 7. Repeat steps 2 - 6 for remaining columns. in imx_keypad_scan_matrix()
113 reg_val = readw(keypad->mmio_base + KPDR); in imx_keypad_scan_matrix()
115 writew(reg_val, keypad->mmio_base + KPDR); in imx_keypad_scan_matrix()
127 reg_val = readw(keypad->mmio_base + KPDR); in imx_keypad_scan_matrix()
128 matrix_volatile_state[col] = (~reg_val) & keypad->rows_en_mask; in imx_keypad_scan_matrix()
135 reg_val = readw(keypad->mmio_base + KPDR); in imx_keypad_scan_matrix()
137 writew(reg_val, keypad->mmio_base + KPDR); in imx_keypad_scan_matrix()
142 * keypad->matrix_stable_state and fire events if changes are detected.
147 struct input_dev *input_dev = keypad->input_dev; in imx_keypad_fire_events()
154 if ((keypad->cols_en_mask & (1 << col)) == 0) in imx_keypad_fire_events()
157 bits_changed = keypad->matrix_stable_state[col] ^ in imx_keypad_fire_events()
164 if ((keypad->rows_en_mask & (1 << row)) == 0) in imx_keypad_fire_events()
171 input_report_key(input_dev, keypad->keycodes[code], in imx_keypad_fire_events()
173 dev_dbg(&input_dev->dev, "Event code: %d, val: %d", in imx_keypad_fire_events()
174 keypad->keycodes[code], in imx_keypad_fire_events()
199 if ((keypad->cols_en_mask & (1 << i)) == 0) in imx_keypad_check_for_events()
202 if (keypad->matrix_unstable_state[i] ^ matrix_volatile_state[i]) { in imx_keypad_check_for_events()
211 * keypad->matrix_unstable_state. in imx_keypad_check_for_events()
216 memcpy(keypad->matrix_unstable_state, matrix_volatile_state, in imx_keypad_check_for_events()
218 keypad->stable_count = 0; in imx_keypad_check_for_events()
220 keypad->stable_count++; in imx_keypad_check_for_events()
226 if (keypad->stable_count < IMX_KEYPAD_SCANS_FOR_STABILITY) { in imx_keypad_check_for_events()
227 mod_timer(&keypad->check_matrix_timer, in imx_keypad_check_for_events()
235 * (keypad->stable_count > IMX_KEYPAD_SCANS_FOR_STABILITY) all in imx_keypad_check_for_events()
238 if (keypad->stable_count == IMX_KEYPAD_SCANS_FOR_STABILITY) { in imx_keypad_check_for_events()
241 memcpy(keypad->matrix_stable_state, matrix_volatile_state, in imx_keypad_check_for_events()
260 reg_val = readw(keypad->mmio_base + KPSR); in imx_keypad_check_for_events()
262 writew(reg_val, keypad->mmio_base + KPSR); in imx_keypad_check_for_events()
264 reg_val = readw(keypad->mmio_base + KPSR); in imx_keypad_check_for_events()
267 writew(reg_val, keypad->mmio_base + KPSR); in imx_keypad_check_for_events()
275 mod_timer(&keypad->check_matrix_timer, in imx_keypad_check_for_events()
278 reg_val = readw(keypad->mmio_base + KPSR); in imx_keypad_check_for_events()
280 writew(reg_val, keypad->mmio_base + KPSR); in imx_keypad_check_for_events()
282 reg_val = readw(keypad->mmio_base + KPSR); in imx_keypad_check_for_events()
285 writew(reg_val, keypad->mmio_base + KPSR); in imx_keypad_check_for_events()
294 reg_val = readw(keypad->mmio_base + KPSR); in imx_keypad_irq_handler()
300 writew(reg_val, keypad->mmio_base + KPSR); in imx_keypad_irq_handler()
302 if (keypad->enabled) { in imx_keypad_irq_handler()
304 keypad->stable_count = 0; in imx_keypad_irq_handler()
307 mod_timer(&keypad->check_matrix_timer, in imx_keypad_irq_handler()
320 * Configure keypad columns as open-drain (KPCR[15:8]) in imx_keypad_config()
322 reg_val = readw(keypad->mmio_base + KPCR); in imx_keypad_config()
323 reg_val |= keypad->rows_en_mask & 0xff; /* rows */ in imx_keypad_config()
324 reg_val |= (keypad->cols_en_mask & 0xff) << 8; /* cols */ in imx_keypad_config()
325 writew(reg_val, keypad->mmio_base + KPCR); in imx_keypad_config()
328 reg_val = readw(keypad->mmio_base + KPDR); in imx_keypad_config()
330 writew(reg_val, keypad->mmio_base + KPDR); in imx_keypad_config()
333 writew(0xff00, keypad->mmio_base + KDDR); in imx_keypad_config()
339 reg_val = readw(keypad->mmio_base + KPSR); in imx_keypad_config()
342 writew(reg_val, keypad->mmio_base + KPSR); in imx_keypad_config()
347 writew(reg_val, keypad->mmio_base + KPSR); in imx_keypad_config()
355 reg_val = readw(keypad->mmio_base + KPSR); in imx_keypad_inhibit()
358 writew(reg_val, keypad->mmio_base + KPSR); in imx_keypad_inhibit()
361 reg_val = (keypad->cols_en_mask & 0xff) << 8; in imx_keypad_inhibit()
362 writew(reg_val, keypad->mmio_base + KPCR); in imx_keypad_inhibit()
369 dev_dbg(&dev->dev, ">%s\n", __func__); in imx_keypad_close()
372 keypad->enabled = false; in imx_keypad_close()
373 synchronize_irq(keypad->irq); in imx_keypad_close()
374 timer_delete_sync(&keypad->check_matrix_timer); in imx_keypad_close()
379 clk_disable_unprepare(keypad->clk); in imx_keypad_close()
387 dev_dbg(&dev->dev, ">%s\n", __func__); in imx_keypad_open()
389 /* Enable the kpp clock */ in imx_keypad_open()
390 error = clk_prepare_enable(keypad->clk); in imx_keypad_open()
395 keypad->enabled = true; in imx_keypad_open()
400 if ((readw(keypad->mmio_base + KPDR) & keypad->rows_en_mask) == 0) { in imx_keypad_open()
401 dev_err(&dev->dev, in imx_keypad_open()
410 return -EIO; in imx_keypad_open()
414 { .compatible = "fsl,imx21-kpp", },
429 input_dev = devm_input_allocate_device(&pdev->dev); in imx_keypad_probe()
431 dev_err(&pdev->dev, "failed to allocate the input device\n"); in imx_keypad_probe()
432 return -ENOMEM; in imx_keypad_probe()
435 keypad = devm_kzalloc(&pdev->dev, sizeof(*keypad), GFP_KERNEL); in imx_keypad_probe()
437 dev_err(&pdev->dev, "not enough memory for driver data\n"); in imx_keypad_probe()
438 return -ENOMEM; in imx_keypad_probe()
441 keypad->input_dev = input_dev; in imx_keypad_probe()
442 keypad->irq = irq; in imx_keypad_probe()
443 keypad->stable_count = 0; in imx_keypad_probe()
445 timer_setup(&keypad->check_matrix_timer, in imx_keypad_probe()
448 keypad->mmio_base = devm_platform_ioremap_resource(pdev, 0); in imx_keypad_probe()
449 if (IS_ERR(keypad->mmio_base)) in imx_keypad_probe()
450 return PTR_ERR(keypad->mmio_base); in imx_keypad_probe()
452 keypad->clk = devm_clk_get(&pdev->dev, NULL); in imx_keypad_probe()
453 if (IS_ERR(keypad->clk)) { in imx_keypad_probe()
454 dev_err(&pdev->dev, "failed to get keypad clock\n"); in imx_keypad_probe()
455 return PTR_ERR(keypad->clk); in imx_keypad_probe()
459 input_dev->name = pdev->name; in imx_keypad_probe()
460 input_dev->id.bustype = BUS_HOST; in imx_keypad_probe()
461 input_dev->dev.parent = &pdev->dev; in imx_keypad_probe()
462 input_dev->open = imx_keypad_open; in imx_keypad_probe()
463 input_dev->close = imx_keypad_close; in imx_keypad_probe()
468 keypad->keycodes, input_dev); in imx_keypad_probe()
470 dev_err(&pdev->dev, "failed to build keymap\n"); in imx_keypad_probe()
478 if (keypad->keycodes[i] != KEY_RESERVED) { in imx_keypad_probe()
479 keypad->rows_en_mask |= 1 << row; in imx_keypad_probe()
480 keypad->cols_en_mask |= 1 << col; in imx_keypad_probe()
484 dev_dbg(&pdev->dev, "enabled rows mask: %x\n", keypad->rows_en_mask); in imx_keypad_probe()
485 dev_dbg(&pdev->dev, "enabled cols mask: %x\n", keypad->cols_en_mask); in imx_keypad_probe()
487 __set_bit(EV_REP, input_dev->evbit); in imx_keypad_probe()
492 error = clk_prepare_enable(keypad->clk); in imx_keypad_probe()
496 clk_disable_unprepare(keypad->clk); in imx_keypad_probe()
498 error = devm_request_irq(&pdev->dev, irq, imx_keypad_irq_handler, 0, in imx_keypad_probe()
499 pdev->name, keypad); in imx_keypad_probe()
501 dev_err(&pdev->dev, "failed to request IRQ\n"); in imx_keypad_probe()
508 dev_err(&pdev->dev, "failed to register input device\n"); in imx_keypad_probe()
513 device_init_wakeup(&pdev->dev, 1); in imx_keypad_probe()
522 struct input_dev *input_dev = kbd->input_dev; in imx_kbd_noirq_suspend()
523 unsigned short reg_val = readw(kbd->mmio_base + KPSR); in imx_kbd_noirq_suspend()
525 scoped_guard(mutex, &input_dev->mutex) { in imx_kbd_noirq_suspend()
528 clk_disable_unprepare(kbd->clk); 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 guard(mutex)(&input_dev->mutex); in imx_kbd_noirq_resume()
557 error = clk_prepare_enable(kbd->clk); in imx_kbd_noirq_resume()
571 .name = "imx-keypad",
582 MODULE_ALIAS("platform:imx-keypad");