summaryrefslogtreecommitdiff
path: root/components/drivers/input/keyboard
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/keyboard
parent357c9b7b5a61ce2062cbfcb37d9dba8d17ff3d6d (diff)
[dm][input] support input #11031
Diffstat (limited to 'components/drivers/input/keyboard')
-rw-r--r--components/drivers/input/keyboard/Kconfig13
-rw-r--r--components/drivers/input/keyboard/SConscript18
-rw-r--r--components/drivers/input/keyboard/keys-gpio.c163
3 files changed, 194 insertions, 0 deletions
diff --git a/components/drivers/input/keyboard/Kconfig b/components/drivers/input/keyboard/Kconfig
new file mode 100644
index 0000000000..6cce9d514b
--- /dev/null
+++ b/components/drivers/input/keyboard/Kconfig
@@ -0,0 +1,13 @@
+menuconfig RT_INPUT_KEYBOARD
+ bool "Keyboards"
+ default n
+
+config RT_INPUT_KEYBOARD_GPIO
+ bool "GPIO"
+ depends on RT_INPUT_KEYBOARD
+ depends on RT_USING_OFW
+ default n
+
+if RT_INPUT_KEYBOARD
+ osource "$(SOC_DM_INPUT_KEYBOARD_DIR)/Kconfig"
+endif
diff --git a/components/drivers/input/keyboard/SConscript b/components/drivers/input/keyboard/SConscript
new file mode 100644
index 0000000000..67c4713e79
--- /dev/null
+++ b/components/drivers/input/keyboard/SConscript
@@ -0,0 +1,18 @@
+from building import *
+
+group = []
+
+if not GetDepend(['RT_INPUT_KEYBOARD']):
+ Return('group')
+
+cwd = GetCurrentDir()
+CPPPATH = [cwd + '/../../include']
+
+src = []
+
+if GetDepend(['RT_INPUT_KEYBOARD_GPIO']):
+ src += ['keys-gpio.c']
+
+group = DefineGroup('DeviceDrivers', src, depend = [''], CPPPATH = CPPPATH)
+
+Return('group')
diff --git a/components/drivers/input/keyboard/keys-gpio.c b/components/drivers/input/keyboard/keys-gpio.c
new file mode 100644
index 0000000000..5de974bf4a
--- /dev/null
+++ b/components/drivers/input/keyboard/keys-gpio.c
@@ -0,0 +1,163 @@
+/*
+ * 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 <rtthread.h>
+#include <rtdevice.h>
+
+#define DBG_TAG "input.keyboard.gpio"
+#define DBG_LVL DBG_INFO
+#include <rtdbg.h>
+
+struct gpio_key
+{
+ struct rt_input_device parent;
+
+ rt_base_t pin;
+ rt_uint8_t mode;
+ rt_uint32_t code;
+};
+
+static void gpio_key_event(void *data)
+{
+ struct gpio_key *gkey = data;
+
+ rt_input_report_key(&gkey->parent, gkey->code, 1);
+ rt_input_sync(&gkey->parent);
+
+ rt_input_report_key(&gkey->parent, gkey->code, 0);
+ rt_input_sync(&gkey->parent);
+}
+
+static rt_err_t ofw_append_gpio_key(struct rt_ofw_node *np)
+{
+ rt_err_t err = RT_EOK;
+ rt_uint32_t debounce;
+ const char *propname;
+ struct gpio_key *gkey = rt_calloc(1, sizeof(*gkey));
+
+ if (!gkey)
+ {
+ return -RT_ENOMEM;
+ }
+
+ gkey->pin = rt_ofw_get_named_pin(np, RT_NULL, 0, &gkey->mode, RT_NULL);
+
+ if (gkey->pin < 0)
+ {
+ err = gkey->pin;
+
+ goto _fail;
+ }
+
+ if ((propname = rt_ofw_get_prop_fuzzy_name(np, ",code$")) &&
+ !rt_ofw_prop_read_u32(np, propname, &gkey->code))
+ {
+ rt_input_set_capability(&gkey->parent, EV_KEY, gkey->code);
+
+ if (!(err = rt_input_device_register(&gkey->parent)))
+ {
+ err = rt_pin_attach_irq(gkey->pin, gkey->mode, gpio_key_event, gkey);
+
+ if (err)
+ {
+ rt_input_device_unregister(&gkey->parent);
+ goto _fail;
+ }
+
+ rt_pin_irq_enable(gkey->pin, RT_TRUE);
+ }
+ }
+
+ if (err)
+ {
+ goto _fail;
+ }
+
+ if (!rt_ofw_prop_read_u32(np, "debounce-interval", &debounce))
+ {
+ rt_pin_debounce(gkey->pin, debounce);
+ }
+
+ rt_ofw_data(np) = gkey;
+
+ return RT_EOK;
+
+_fail:
+ rt_free(gkey);
+
+ return err;
+}
+
+static rt_err_t gpio_key_probe(struct rt_platform_device *pdev)
+{
+ rt_err_t err = RT_EOK;
+ struct rt_ofw_node *key_np, *np = pdev->parent.ofw_node;
+
+ rt_ofw_foreach_available_child_node(np, key_np)
+ {
+ err = ofw_append_gpio_key(key_np);
+
+ if (err == -RT_ENOMEM)
+ {
+ rt_ofw_node_put(key_np);
+
+ return err;
+ }
+ else if (err)
+ {
+ LOG_E("%s: create KEY fail", rt_ofw_node_full_name(key_np));
+ continue;
+ }
+ }
+
+ return err;
+}
+
+static rt_err_t gpio_key_remove(struct rt_platform_device *pdev)
+{
+ struct rt_ofw_node *key_np, *np = pdev->parent.ofw_node;
+
+ rt_ofw_foreach_available_child_node(np, key_np)
+ {
+ struct gpio_key *gkey = rt_ofw_data(key_np);
+
+ if (!gkey)
+ {
+ continue;
+ }
+
+ rt_ofw_data(key_np) = RT_NULL;
+
+ rt_pin_irq_enable(gkey->pin, RT_FALSE);
+ rt_pin_detach_irq(gkey->pin);
+
+ rt_input_device_unregister(&gkey->parent);
+
+ rt_free(gkey);
+ }
+
+ return RT_EOK;
+}
+
+static const struct rt_ofw_node_id gpio_key_ofw_ids[] =
+{
+ { .compatible = "gpio-keys" },
+ { /* sentinel */ }
+};
+
+static struct rt_platform_driver gpio_key_driver =
+{
+ .name = "gpio-keys",
+ .ids = gpio_key_ofw_ids,
+
+ .probe = gpio_key_probe,
+ .remove = gpio_key_remove,
+};
+RT_PLATFORM_DRIVER_EXPORT(gpio_key_driver);