summaryrefslogtreecommitdiff
path: root/components/drivers/input/input_power.c
diff options
context:
space:
mode:
authorGUI <[email protected]>2025-12-10 16:58:10 +0800
committerGitHub <[email protected]>2025-12-10 16:58:10 +0800
commit3ff3fc39485c725cd93053805d25125353dd53e9 (patch)
tree708ac806078173a5bb47d56278f3dc8edbc865b9 /components/drivers/input/input_power.c
parent357c9b7b5a61ce2062cbfcb37d9dba8d17ff3d6d (diff)
[dm][input] support input #11031
Diffstat (limited to 'components/drivers/input/input_power.c')
-rw-r--r--components/drivers/input/input_power.c130
1 files changed, 130 insertions, 0 deletions
diff --git a/components/drivers/input/input_power.c b/components/drivers/input/input_power.c
new file mode 100644
index 0000000000..11bf7b86aa
--- /dev/null
+++ b/components/drivers/input/input_power.c
@@ -0,0 +1,130 @@
+/*
+ * Copyright (c) 2006-2022, RT-Thread Development Team
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Change Logs:
+ * Date Author Notes
+ * 2022-3-08 GuEe-GUI the first version
+ */
+
+#include <rthw.h>
+#include <rtthread.h>
+#include <rtdevice.h>
+
+#define DBG_TAG "input.power"
+#define DBG_LVL DBG_INFO
+#include <rtdbg.h>
+
+struct input_event_cap
+{
+ rt_uint16_t code;
+ rt_int32_t value;
+ rt_int32_t current;
+};
+
+static rt_bool_t power_input_identify(struct rt_input_handler *handler,
+ struct rt_input_device *idev)
+{
+ struct input_event_cap *cap = handler->priv;
+
+ if (rt_bitmap_test_bit(idev->key_map, cap->code))
+ {
+ if (cap->value == cap->current)
+ {
+ return RT_TRUE;
+ }
+
+ ++cap->current;
+ }
+
+ return RT_FALSE;
+}
+
+static rt_bool_t power_input_callback(struct rt_input_handler *handler,
+ struct rt_input_event *ev)
+{
+ if (ev->code == KEY_POWER)
+ {
+ if (ev->value == 0)
+ {
+ rt_hw_cpu_shutdown();
+ }
+
+ return RT_TRUE;
+ }
+ else if (ev->code == KEY_RESTART)
+ {
+ if (ev->value == 0)
+ {
+ rt_hw_cpu_reset();
+ }
+
+ return RT_TRUE;
+ }
+
+ return RT_FALSE;
+}
+
+static rt_bool_t power_test_cap(struct rt_input_handler *handler,
+ struct rt_input_device *idev)
+{
+ struct input_event_cap *cap = handler->priv;
+
+ if (rt_bitmap_test_bit(idev->key_map, cap->code))
+ {
+ ++cap->value;
+ }
+
+ return RT_FALSE;
+}
+
+static void power_handler_install(rt_uint16_t code)
+{
+ rt_uint32_t idev_count;
+ struct input_event_cap cap;
+ struct rt_input_handler tmp_handler, *handlers;
+
+ cap.code = code;
+ cap.value = 0;
+ tmp_handler.idev = RT_NULL;
+ tmp_handler.identify = &power_test_cap;
+ tmp_handler.callback = &power_input_callback;
+ tmp_handler.priv = &cap;
+ rt_input_add_handler(&tmp_handler); /* Just test */
+
+ if (!(idev_count = cap.value))
+ {
+ return;
+ }
+
+ handlers = rt_calloc(idev_count, sizeof(*handlers));
+
+ if (!handlers)
+ {
+ LOG_E("No memory to install power handler");
+ return;
+ }
+
+ for (int i = 0; i < idev_count; ++i, ++handlers)
+ {
+ cap.value = i;
+ cap.current = 0;
+
+ handlers->identify = &power_input_identify;
+ handlers->callback = &power_input_callback;
+ handlers->priv = &cap;
+
+ rt_input_add_handler(handlers);
+ handlers->priv = RT_NULL;
+ }
+}
+
+static int input_event_power_init(void)
+{
+ power_handler_install(KEY_POWER);
+ power_handler_install(KEY_RESTART);
+
+ return 0;
+}
+INIT_ENV_EXPORT(input_event_power_init);