From a1e17c1a08f514ae50a4a26062e33435ed66d05c Mon Sep 17 00:00:00 2001 From: GuEe-GUI <2991707448@qq.com> Date: Fri, 29 Nov 2024 13:38:49 +0800 Subject: [PATCH] [DM/INPUT] Add simple drivers 1. GPIO-Key always use in poweroff/reset in OFW. 2. E3xx Button is a simple power event input device, Just two IRQs work. Signed-off-by: GuEe-GUI <2991707448@qq.com> --- components/drivers/input/Kconfig | 5 + components/drivers/input/keyboard/Kconfig | 13 ++ components/drivers/input/keyboard/SConscript | 18 ++ components/drivers/input/keyboard/keys-gpio.c | 159 ++++++++++++++++++ components/drivers/input/misc/Kconfig | 12 ++ components/drivers/input/misc/SConscript | 18 ++ components/drivers/input/misc/button-e3x0.c | 115 +++++++++++++ 7 files changed, 340 insertions(+) create mode 100644 components/drivers/input/keyboard/Kconfig create mode 100644 components/drivers/input/keyboard/SConscript create mode 100644 components/drivers/input/keyboard/keys-gpio.c create mode 100644 components/drivers/input/misc/Kconfig create mode 100644 components/drivers/input/misc/SConscript create mode 100644 components/drivers/input/misc/button-e3x0.c diff --git a/components/drivers/input/Kconfig b/components/drivers/input/Kconfig index d386332fd8..8da7ceaedd 100644 --- a/components/drivers/input/Kconfig +++ b/components/drivers/input/Kconfig @@ -9,3 +9,8 @@ config RT_INPUT_POWER bool "Input event power" depends on RT_USING_INPUT default y + +if RT_USING_INPUT + rsource "keyboard/Kconfig" + rsource "misc/Kconfig" +endif 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..0d0893aad9 --- /dev/null +++ b/components/drivers/input/keyboard/keys-gpio.c @@ -0,0 +1,159 @@ +/* + * 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 +#include +#include + +#define DBG_TAG "input.keyboard.gpio" +#define DBG_LVL DBG_INFO +#include + +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)); + + 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); diff --git a/components/drivers/input/misc/Kconfig b/components/drivers/input/misc/Kconfig new file mode 100644 index 0000000000..0928bc3f42 --- /dev/null +++ b/components/drivers/input/misc/Kconfig @@ -0,0 +1,12 @@ +menuconfig RT_INPUT_MISC + bool "Misc" + default n + +config RT_INPUT_MISC_BUTTON_E3X0 + bool "NI Ettus Research USRP E3xx Button support" + depends on RT_INPUT_MISC + default n + +if RT_INPUT_MISC + osource "$(SOC_DM_INPUT_MISC_DIR)/Kconfig" +endif diff --git a/components/drivers/input/misc/SConscript b/components/drivers/input/misc/SConscript new file mode 100644 index 0000000000..6b80c70aca --- /dev/null +++ b/components/drivers/input/misc/SConscript @@ -0,0 +1,18 @@ +from building import * + +group = [] + +if not GetDepend(['RT_INPUT_MISC']): + Return('group') + +cwd = GetCurrentDir() +CPPPATH = [cwd + '/../../include'] + +src = [] + +if GetDepend(['RT_INPUT_MISC_BUTTON_E3X0']): + src += ['button-e3x0.c'] + +group = DefineGroup('DeviceDrivers', src, depend = [''], CPPPATH = CPPPATH) + +Return('group') diff --git a/components/drivers/input/misc/button-e3x0.c b/components/drivers/input/misc/button-e3x0.c new file mode 100644 index 0000000000..2c09a54016 --- /dev/null +++ b/components/drivers/input/misc/button-e3x0.c @@ -0,0 +1,115 @@ +/* + * 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 +#include +#include + +struct e3x0_button +{ + struct rt_input_device parent; + + int press_irq, release_irq; +}; + +static void e3x0_button_press_isr(int irqno, void *param) +{ + struct e3x0_button *btn = param; + + rt_input_report_key(&btn->parent, KEY_POWER, 1); + rt_input_sync(&btn->parent); +} + +static void e3x0_button_release_isr(int irqno, void *param) +{ + struct e3x0_button *btn = param; + + rt_input_report_key(&btn->parent, KEY_POWER, 0); + rt_input_sync(&btn->parent); +} + +static rt_err_t e3x0_button_probe(struct rt_platform_device *pdev) +{ + rt_err_t err; + struct rt_device *dev = &pdev->parent; + struct e3x0_button *btn = rt_calloc(1, sizeof(*btn)); + + if (!btn) + { + return -RT_ENOMEM; + } + + if ((btn->press_irq = rt_dm_dev_get_irq_by_name(dev, "press")) < 0) + { + err = btn->press_irq; + goto _fail; + } + + if ((btn->release_irq = rt_dm_dev_get_irq_by_name(dev, "release")) < 0) + { + err = btn->release_irq; + goto _fail; + } + + rt_input_set_capability(&btn->parent, EV_KEY, KEY_POWER); + + if ((err = rt_input_device_register(&btn->parent))) + { + goto _fail; + } + + dev->user_data = btn; + + rt_hw_interrupt_install(btn->press_irq, e3x0_button_press_isr, btn, "button-e3x0-press"); + rt_hw_interrupt_umask(btn->press_irq); + + rt_hw_interrupt_install(btn->release_irq, e3x0_button_release_isr, btn, "button-e3x0-release"); + rt_hw_interrupt_umask(btn->release_irq); + + return RT_EOK; + +_fail: + rt_free(btn); + + return err; +} + +static rt_err_t e3x0_button_remove(struct rt_platform_device *pdev) +{ + struct e3x0_button *btn = pdev->parent.user_data; + + rt_hw_interrupt_mask(btn->press_irq); + rt_pic_detach_irq(btn->press_irq, btn); + + rt_hw_interrupt_mask(btn->release_irq); + rt_pic_detach_irq(btn->release_irq, btn); + + rt_input_device_unregister(&btn->parent); + + rt_free(btn); + + return RT_EOK; +} + +static const struct rt_ofw_node_id e3x0_button_ofw_ids[] = +{ + { .compatible = "ettus,e3x0-button" }, + { /* sentinel */ } +}; + +static struct rt_platform_driver e3x0_button_driver = +{ + .name = "e3x0-button", + .ids = e3x0_button_ofw_ids, + + .probe = e3x0_button_probe, + .remove = e3x0_button_remove, +}; +RT_PLATFORM_DRIVER_EXPORT(e3x0_button_driver);