Add wheel WASD

This commit is contained in:
2026-01-17 15:18:58 +01:00
parent aedde65362
commit 87217f1150

View File

@@ -21,6 +21,9 @@
#include <linux/usb.h> #include <linux/usb.h>
#include <linux/usb/input.h> #include <linux/usb/input.h>
#include <linux/input.h> #include <linux/input.h>
#include <linux/timer.h>
#include <linux/jiffies.h>
#include <linux/hid.h>
MODULE_AUTHOR("LLP group 16"); MODULE_AUTHOR("LLP group 16");
MODULE_DESCRIPTION("Logitech G29 USB driver"); MODULE_DESCRIPTION("Logitech G29 USB driver");
@@ -89,9 +92,26 @@ struct g29_dev {
int interval; int interval;
int endpoint; int endpoint;
struct timer_list steer_timer;
u32 steer_phase_ms;
struct g29_state last; struct g29_state last;
}; };
static void g29_steer_timer_fn(struct timer_list *t) {
struct g29_dev *g29 = timer_container_of(g29, t, steer_timer);
const int rot = le16_to_cpu(g29->last.rot_le);
input_report_key(g29->input, KEY_W, g29->last.gas <= 0x80);
input_report_key(g29->input, KEY_S, g29->last.clt <= 0x80);
input_report_key(g29->input, KEY_A, rot <= 0x6000);
input_report_key(g29->input, KEY_D, rot >= 0xA000);
mod_timer(&g29->steer_timer, jiffies + msecs_to_jiffies(2));
}
static void g29_apply_media_mode(struct g29_dev *g29, const struct g29_state *cur, const struct g29_state *prev) { static void g29_apply_media_mode(struct g29_dev *g29, const struct g29_state *cur, const struct g29_state *prev) {
u32 pressed = le32_to_cpu(cur->buttons_le & ~prev->buttons_le); u32 pressed = le32_to_cpu(cur->buttons_le & ~prev->buttons_le);
for (int i = 0; i < ARRAY_SIZE(g29_media_edge_map); i++) { for (int i = 0; i < ARRAY_SIZE(g29_media_edge_map); i++) {
@@ -149,11 +169,14 @@ static int g29_input_open(struct input_dev *input) {
if (usb_submit_urb(g29->urb, GFP_KERNEL)) if (usb_submit_urb(g29->urb, GFP_KERNEL))
return -EIO; return -EIO;
mod_timer(&g29->steer_timer, jiffies + msecs_to_jiffies(2));
return 0; return 0;
} }
static void g29_input_close(struct input_dev *input) { static void g29_input_close(struct input_dev *input) {
struct g29_dev *g29 = input_get_drvdata(input); struct g29_dev *g29 = input_get_drvdata(input);
timer_delete_sync(&g29->steer_timer);
usb_kill_urb(g29->urb); usb_kill_urb(g29->urb);
} }
@@ -194,6 +217,8 @@ static int g29_probe(struct usb_interface *intf, const struct usb_device_id *id)
g29->interval = ep->bInterval; g29->interval = ep->bInterval;
memset(&g29->last, 0, sizeof(g29->last)); memset(&g29->last, 0, sizeof(g29->last));
timer_setup(&g29->steer_timer, g29_steer_timer_fn, 0);
if ((g29->buf = usb_alloc_coherent(udev, g29->maxp, GFP_KERNEL, &g29->buf_dma)) == NULL) { if ((g29->buf = usb_alloc_coherent(udev, g29->maxp, GFP_KERNEL, &g29->buf_dma)) == NULL) {
ret = -ENOMEM; ret = -ENOMEM;
goto err_free_input; goto err_free_input;
@@ -234,6 +259,11 @@ static int g29_probe(struct usb_interface *intf, const struct usb_device_id *id)
input_set_capability(input, EV_KEY, KEY_NEXTSONG); input_set_capability(input, EV_KEY, KEY_NEXTSONG);
input_set_capability(input, EV_KEY, KEY_PREVIOUSSONG); input_set_capability(input, EV_KEY, KEY_PREVIOUSSONG);
input_set_capability(input, EV_KEY, KEY_W);
input_set_capability(input, EV_KEY, KEY_A);
input_set_capability(input, EV_KEY, KEY_S);
input_set_capability(input, EV_KEY, KEY_D);
input_set_drvdata(input, g29); input_set_drvdata(input, g29);
input->open = g29_input_open; input->open = g29_input_open;
input->close = g29_input_close; input->close = g29_input_close;