Skip to content

Commit 2372d92

Browse files
committed
[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 <[email protected]>
1 parent 1f8c199 commit 2372d92

File tree

7 files changed

+344
-0
lines changed

7 files changed

+344
-0
lines changed

components/drivers/input/Kconfig

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,3 +9,8 @@ config RT_INPUT_POWER
99
bool "Input event power"
1010
depends on RT_USING_INPUT
1111
default y
12+
13+
if RT_USING_INPUT
14+
rsource "keyboard/Kconfig"
15+
rsource "misc/Kconfig"
16+
endif
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
menuconfig RT_INPUT_KEYBOARD
2+
bool "Keyboards"
3+
default n
4+
5+
config RT_INPUT_KEYBOARD_GPIO
6+
bool "GPIO"
7+
depends on RT_INPUT_KEYBOARD
8+
depends on RT_USING_OFW
9+
default n
10+
11+
if RT_INPUT_KEYBOARD
12+
osource "$(SOC_DM_INPUT_KEYBOARD_DIR)/Kconfig"
13+
endif
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
from building import *
2+
3+
group = []
4+
5+
if not GetDepend(['RT_INPUT_KEYBOARD']):
6+
Return('group')
7+
8+
cwd = GetCurrentDir()
9+
CPPPATH = [cwd + '/../../include']
10+
11+
src = []
12+
13+
if GetDepend(['RT_INPUT_KEYBOARD_GPIO']):
14+
src += ['keys-gpio.c']
15+
16+
group = DefineGroup('DeviceDrivers', src, depend = [''], CPPPATH = CPPPATH)
17+
18+
Return('group')
Lines changed: 163 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,163 @@
1+
/*
2+
* Copyright (c) 2006-2022, RT-Thread Development Team
3+
*
4+
* SPDX-License-Identifier: Apache-2.0
5+
*
6+
* Change Logs:
7+
* Date Author Notes
8+
* 2022-3-08 GuEe-GUI the first version
9+
*/
10+
11+
#include <rtthread.h>
12+
#include <rtdevice.h>
13+
#include <dt-bindings/input/event-codes.h>
14+
15+
#define DBG_TAG "input.keyboard.gpio"
16+
#define DBG_LVL DBG_INFO
17+
#include <rtdbg.h>
18+
19+
struct gpio_key
20+
{
21+
struct rt_input_device parent;
22+
23+
rt_base_t pin;
24+
rt_uint8_t mode;
25+
rt_uint32_t code;
26+
};
27+
28+
static void gpio_key_event(void *data)
29+
{
30+
struct gpio_key *gkey = data;
31+
32+
rt_input_report_key(&gkey->parent, gkey->code, 1);
33+
rt_input_sync(&gkey->parent);
34+
35+
rt_input_report_key(&gkey->parent, gkey->code, 0);
36+
rt_input_sync(&gkey->parent);
37+
}
38+
39+
static rt_err_t ofw_append_gpio_key(struct rt_ofw_node *np)
40+
{
41+
rt_err_t err = RT_EOK;
42+
rt_uint32_t debounce;
43+
const char *propname;
44+
struct gpio_key *gkey = rt_calloc(1, sizeof(*gkey));
45+
46+
gkey->pin = rt_ofw_get_named_pin(np, RT_NULL, 0, &gkey->mode, RT_NULL);
47+
48+
if (gkey->pin < 0)
49+
{
50+
err = gkey->pin;
51+
52+
goto _fail;
53+
}
54+
55+
if ((propname = rt_ofw_get_prop_fuzzy_name(np, ",code$")) &&
56+
!rt_ofw_prop_read_u32(np, propname, &gkey->code))
57+
{
58+
rt_input_set_capability(&gkey->parent, EV_KEY, gkey->code);
59+
60+
if (!(err = rt_input_device_register(&gkey->parent)))
61+
{
62+
err = rt_pin_attach_irq(gkey->pin, gkey->mode, gpio_key_event, gkey);
63+
64+
if (err)
65+
{
66+
rt_input_device_unregister(&gkey->parent);
67+
goto _fail;
68+
}
69+
70+
rt_pin_irq_enable(gkey->pin, RT_TRUE);
71+
}
72+
}
73+
74+
if (err)
75+
{
76+
goto _fail;
77+
}
78+
79+
if (!rt_ofw_prop_read_u32(np, "debounce-interval", &debounce))
80+
{
81+
rt_pin_debounce(gkey->pin, debounce);
82+
}
83+
84+
rt_ofw_data(np) = gkey;
85+
86+
return RT_EOK;
87+
88+
_fail:
89+
rt_free(gkey);
90+
91+
return err;
92+
}
93+
94+
static rt_err_t gpio_key_probe(struct rt_platform_device *pdev)
95+
{
96+
rt_err_t err = RT_EOK;
97+
struct rt_ofw_node *key_np, *np = pdev->parent.ofw_node;
98+
99+
#ifdef RT_USING_PINCTRL
100+
rt_pin_ctrl_confs_apply(&pdev->parent, 0);
101+
#endif
102+
103+
rt_ofw_foreach_available_child_node(np, key_np)
104+
{
105+
err = ofw_append_gpio_key(key_np);
106+
107+
if (err == -RT_ENOMEM)
108+
{
109+
rt_ofw_node_put(key_np);
110+
111+
return err;
112+
}
113+
else if (err)
114+
{
115+
LOG_E("%s: create KEY fail", rt_ofw_node_full_name(key_np));
116+
continue;
117+
}
118+
}
119+
120+
return err;
121+
}
122+
123+
static rt_err_t gpio_key_remove(struct rt_platform_device *pdev)
124+
{
125+
struct rt_ofw_node *key_np, *np = pdev->parent.ofw_node;
126+
127+
rt_ofw_foreach_available_child_node(np, key_np)
128+
{
129+
struct gpio_key *gkey = rt_ofw_data(key_np);
130+
131+
if (!gkey)
132+
{
133+
continue;
134+
}
135+
136+
rt_ofw_data(key_np) = RT_NULL;
137+
138+
rt_pin_irq_enable(gkey->pin, RT_FALSE);
139+
rt_pin_detach_irq(gkey->pin);
140+
141+
rt_input_device_unregister(&gkey->parent);
142+
143+
rt_free(gkey);
144+
}
145+
146+
return RT_EOK;
147+
}
148+
149+
static const struct rt_ofw_node_id gpio_key_ofw_ids[] =
150+
{
151+
{ .compatible = "gpio-keys" },
152+
{ /* sentinel */ }
153+
};
154+
155+
static struct rt_platform_driver gpio_key_driver =
156+
{
157+
.name = "gpio-keys",
158+
.ids = gpio_key_ofw_ids,
159+
160+
.probe = gpio_key_probe,
161+
.remove = gpio_key_remove,
162+
};
163+
RT_PLATFORM_DRIVER_EXPORT(gpio_key_driver);
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
menuconfig RT_INPUT_MISC
2+
bool "Misc"
3+
default n
4+
5+
config RT_INPUT_MISC_BUTTON_E3X0
6+
bool "NI Ettus Research USRP E3xx Button support"
7+
depends on RT_INPUT_MISC
8+
default n
9+
10+
if RT_INPUT_MISC
11+
osource "$(SOC_DM_INPUT_MISC_DIR)/Kconfig"
12+
endif
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
from building import *
2+
3+
group = []
4+
5+
if not GetDepend(['RT_INPUT_MISC']):
6+
Return('group')
7+
8+
cwd = GetCurrentDir()
9+
CPPPATH = [cwd + '/../../include']
10+
11+
src = []
12+
13+
if GetDepend(['RT_INPUT_MISC_BUTTON_E3X0']):
14+
src += ['button-e3x0.c']
15+
16+
group = DefineGroup('DeviceDrivers', src, depend = [''], CPPPATH = CPPPATH)
17+
18+
Return('group')
Lines changed: 115 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,115 @@
1+
/*
2+
* Copyright (c) 2006-2022, RT-Thread Development Team
3+
*
4+
* SPDX-License-Identifier: Apache-2.0
5+
*
6+
* Change Logs:
7+
* Date Author Notes
8+
* 2022-3-08 GuEe-GUI the first version
9+
*/
10+
11+
#include <rthw.h>
12+
#include <rtthread.h>
13+
#include <rtdevice.h>
14+
15+
struct e3x0_button
16+
{
17+
struct rt_input_device parent;
18+
19+
int press_irq, release_irq;
20+
};
21+
22+
static void e3x0_button_press_isr(int irqno, void *param)
23+
{
24+
struct e3x0_button *btn = param;
25+
26+
rt_input_report_key(&btn->parent, KEY_POWER, 1);
27+
rt_input_sync(&btn->parent);
28+
}
29+
30+
static void e3x0_button_release_isr(int irqno, void *param)
31+
{
32+
struct e3x0_button *btn = param;
33+
34+
rt_input_report_key(&btn->parent, KEY_POWER, 0);
35+
rt_input_sync(&btn->parent);
36+
}
37+
38+
static rt_err_t e3x0_button_probe(struct rt_platform_device *pdev)
39+
{
40+
rt_err_t err;
41+
struct rt_device *dev = &pdev->parent;
42+
struct e3x0_button *btn = rt_calloc(1, sizeof(*btn));
43+
44+
if (!btn)
45+
{
46+
return -RT_ENOMEM;
47+
}
48+
49+
if ((btn->press_irq = rt_dm_dev_get_irq_by_name(dev, "press")) < 0)
50+
{
51+
err = btn->press_irq;
52+
goto _fail;
53+
}
54+
55+
if ((btn->release_irq = rt_dm_dev_get_irq_by_name(dev, "release")) < 0)
56+
{
57+
err = btn->release_irq;
58+
goto _fail;
59+
}
60+
61+
rt_input_set_capability(&btn->parent, EV_KEY, KEY_POWER);
62+
63+
if ((err = rt_input_device_register(&btn->parent)))
64+
{
65+
goto _fail;
66+
}
67+
68+
dev->user_data = btn;
69+
70+
rt_hw_interrupt_install(btn->press_irq, e3x0_button_press_isr, btn, "button-e3x0-press");
71+
rt_hw_interrupt_umask(btn->press_irq);
72+
73+
rt_hw_interrupt_install(btn->release_irq, e3x0_button_release_isr, btn, "button-e3x0-release");
74+
rt_hw_interrupt_umask(btn->release_irq);
75+
76+
return RT_EOK;
77+
78+
_fail:
79+
rt_free(btn);
80+
81+
return err;
82+
}
83+
84+
static rt_err_t e3x0_button_remove(struct rt_platform_device *pdev)
85+
{
86+
struct e3x0_button *btn = pdev->parent.user_data;
87+
88+
rt_hw_interrupt_mask(btn->press_irq);
89+
rt_pic_detach_irq(btn->press_irq, btn);
90+
91+
rt_hw_interrupt_mask(btn->release_irq);
92+
rt_pic_detach_irq(btn->release_irq, btn);
93+
94+
rt_input_device_unregister(&btn->parent);
95+
96+
rt_free(btn);
97+
98+
return RT_EOK;
99+
}
100+
101+
static const struct rt_ofw_node_id e3x0_button_ofw_ids[] =
102+
{
103+
{ .compatible = "ettus,e3x0-button" },
104+
{ /* sentinel */ }
105+
};
106+
107+
static struct rt_platform_driver e3x0_button_driver =
108+
{
109+
.name = "e3x0-button",
110+
.ids = e3x0_button_ofw_ids,
111+
112+
.probe = e3x0_button_probe,
113+
.remove = e3x0_button_remove,
114+
};
115+
RT_PLATFORM_DRIVER_EXPORT(e3x0_button_driver);

0 commit comments

Comments
 (0)