From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 From: mcc45tr Date: Sat, 5 Sep 2026 19:20:56 +0300 Subject: [PATCH 096/117] input: nabu: sample pogo detect state instead of toggling --- drivers/input/misc/xiaomi-nabu-keyboard.c | 29 +++++++++++------------ 1 file changed, 14 insertions(+), 15 deletions(-) diff --git a/drivers/input/misc/xiaomi-nabu-keyboard.c b/drivers/input/misc/xiaomi-nabu-keyboard.c index 286075c23ade..14a4127fb20a 100644 --- a/drivers/input/misc/xiaomi-nabu-keyboard.c +++ b/drivers/input/misc/xiaomi-nabu-keyboard.c @@ -1,7 +1,6 @@ // SPDX-License-Identifier: GPL-2.0-only /* Xiaomi Pad 5 pogo keyboard-cover power, presence and mode controller. */ -#include #include #include #include @@ -23,7 +22,6 @@ struct nabu_keyboard { struct gpio_desc *detect; struct delayed_work detect_work; struct mutex lock; - atomic_t pending_edges; int irq; bool connected; bool computer_mode; @@ -45,8 +43,7 @@ static void nabu_keyboard_publish_state(struct nabu_keyboard *keyboard, } keyboard->connected = connected; - if (!connected) - keyboard->computer_mode = false; + keyboard->computer_mode = connected; computer_mode = keyboard->computer_mode; xiaomi_nabu_keyboard_update_mode(keyboard->connected, computer_mode); @@ -65,17 +62,18 @@ static void nabu_keyboard_publish_state(struct nabu_keyboard *keyboard, static void nabu_keyboard_detect_work(struct work_struct *work) { struct nabu_keyboard *keyboard; - bool connected; + int connected; keyboard = container_of(to_delayed_work(work), struct nabu_keyboard, detect_work); - if (!(atomic_xchg(&keyboard->pending_edges, 0) & 1)) + connected = gpiod_get_value_cansleep(keyboard->detect); + if (connected < 0) { + dev_warn_ratelimited(keyboard->dev, + "failed to sample keyboard detect GPIO: %d\n", + connected); return; + } - mutex_lock(&keyboard->lock); - connected = !keyboard->connected; - keyboard->computer_mode = connected; - mutex_unlock(&keyboard->lock); nabu_keyboard_publish_state(keyboard, connected, false); } @@ -92,7 +90,6 @@ static irqreturn_t nabu_keyboard_detect_irq(int irq, void *data) */ if (READ_ONCE(keyboard->wake_enabled)) pm_wakeup_event(keyboard->dev, 500); - atomic_inc(&keyboard->pending_edges); mod_delayed_work(system_percpu_wq, &keyboard->detect_work, msecs_to_jiffies(NABU_KEYBOARD_DEBOUNCE_MS)); return IRQ_HANDLED; @@ -199,7 +196,6 @@ static int nabu_keyboard_probe(struct platform_device *pdev) platform_set_drvdata(pdev, keyboard); INIT_DELAYED_WORK(&keyboard->detect_work, nabu_keyboard_detect_work); - atomic_set(&keyboard->pending_edges, 0); /* Power the internal USB controller and release its active-low reset. */ gpiod_set_value_cansleep(keyboard->vdd, 1); @@ -215,14 +211,18 @@ static int nabu_keyboard_probe(struct platform_device *pdev) ret = devm_request_threaded_irq(dev, keyboard->irq, NULL, nabu_keyboard_detect_irq, - IRQF_TRIGGER_RISING | IRQF_ONESHOT, + IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING | + IRQF_ONESHOT, dev_name(dev), keyboard); if (ret) goto err_power_off; device_init_wakeup(dev, of_property_read_bool(dev->of_node, "wakeup-source")); - nabu_keyboard_publish_state(keyboard, false, true); + ret = gpiod_get_value_cansleep(keyboard->detect); + if (ret < 0) + goto err_power_off; + nabu_keyboard_publish_state(keyboard, ret, true); return 0; @@ -249,7 +249,6 @@ static int nabu_keyboard_suspend(struct device *dev) int ret; cancel_delayed_work_sync(&keyboard->detect_work); - atomic_set(&keyboard->pending_edges, 0); mutex_lock(&keyboard->lock); connected = keyboard->connected; mutex_unlock(&keyboard->lock);