mirror of
https://github.com/archr-linux/Arch-R.git
synced 2026-03-31 14:41:55 -07:00
unified-joypad: add option to ignore events
This commit is contained in:
@@ -27,9 +27,34 @@
|
||||
* expect a standard controller.
|
||||
*/
|
||||
virtual-device-name = "ROCKNIX Unified Joypad";
|
||||
virtual-vendor-id = <0xdead>; // USB Vendor ID in hexadecimal
|
||||
virtual-product-id = <0xbeef>; // USB Product ID in hexadecimal
|
||||
virtual-version-id = <0x0100>; // Device version in hexadecimal
|
||||
virtual-vendor-id = <0x0fff>; // USB Vendor ID in hexadecimal
|
||||
virtual-product-id = <0x0fff>; // USB Product ID in hexadecimal
|
||||
virtual-version-id = <0x9001>; // Device version in hexadecimal
|
||||
|
||||
/*
|
||||
* --- Optional: Event Ignore List ---
|
||||
*
|
||||
* Use this property to specify input events that should be completely
|
||||
* blocked from the source devices. This is useful for preventing
|
||||
* "double inputs" where a single button press generates both a
|
||||
* button event (EV_KEY) and an axis event (EV_ABS).
|
||||
*
|
||||
* The list consists of pairs of u32 values: <TYPE CODE>.
|
||||
* - The first value is the event type (e.g., EV_ABS).
|
||||
* - The second value is the event code (e.g., ABS_BRAKE).
|
||||
*
|
||||
* The total number of elements must be even. You can find the numerical
|
||||
* values for types and codes in the kernel's 'linux/input-event-codes.h'
|
||||
* or use the macros defined in 'dt-bindings/input/input.h'.
|
||||
*
|
||||
* Example: Block the analog axis events from the L2/R2 triggers that
|
||||
* also send digital button events.
|
||||
*/
|
||||
ignore-events = <
|
||||
/* Type Code */
|
||||
EV_ABS ABS_BRAKE, // Block the L2 trigger's analog axis (ABS_BRAKE)
|
||||
EV_ABS ABS_GAS // Block the R2 trigger's analog axis (ABS_GAS)
|
||||
>;
|
||||
|
||||
/*
|
||||
* --- Optional: Button Remapping Rules ---
|
||||
|
||||
@@ -29,6 +29,11 @@ struct key_remap {
|
||||
u32 to;
|
||||
};
|
||||
|
||||
struct event_filter {
|
||||
u32 type;
|
||||
u32 code;
|
||||
};
|
||||
|
||||
struct device_remap_config {
|
||||
const char *name;
|
||||
const char *phys;
|
||||
@@ -59,6 +64,9 @@ static u16 vdev_version;
|
||||
static struct device_remap_config *remap_configs;
|
||||
static int num_remap_configs;
|
||||
|
||||
static struct event_filter *ignored_events;
|
||||
static int num_ignored_events;
|
||||
|
||||
static struct delayed_work rebuild_work;
|
||||
static struct mutex dev_mutex;
|
||||
|
||||
@@ -154,6 +162,11 @@ static void joypad_event(struct input_handle *handle, unsigned int type,
|
||||
struct device_remap_config *remap_cfg = handle->private;
|
||||
int i;
|
||||
|
||||
for (i = 0; i < num_ignored_events; i++) {
|
||||
if (type == ignored_events[i].type && code == ignored_events[i].code)
|
||||
return; /* This is an ignored event, do nothing. */
|
||||
}
|
||||
|
||||
if (vdev) {
|
||||
if (type == EV_KEY && remap_cfg) {
|
||||
for (i = 0; i < remap_cfg->num_remaps; i++) {
|
||||
@@ -294,6 +307,37 @@ static void rebuild_virtual_device_work(struct work_struct *work)
|
||||
mutex_unlock(&dev_mutex);
|
||||
}
|
||||
|
||||
static int parse_ignore_list(struct platform_device *pdev)
|
||||
{
|
||||
struct device_node *np = pdev->dev.of_node;
|
||||
int n_vals;
|
||||
|
||||
n_vals = of_property_count_u32_elems(np, "ignore-events");
|
||||
if (n_vals <= 0)
|
||||
return 0; /* No property found, which is fine */
|
||||
|
||||
if (n_vals % 2 != 0) {
|
||||
dev_warn(&pdev->dev, "Property 'ignore-events' must have an even number of elements (type/code pairs).\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
num_ignored_events = n_vals / 2;
|
||||
ignored_events = devm_kcalloc(&pdev->dev, num_ignored_events, sizeof(*ignored_events), GFP_KERNEL);
|
||||
if (!ignored_events) {
|
||||
num_ignored_events = 0;
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
if (of_property_read_u32_array(np, "ignore-events", (u32 *)ignored_events, n_vals)) {
|
||||
dev_err(&pdev->dev, "Failed to read 'ignore-events' property.\n");
|
||||
num_ignored_events = 0;
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
pr_info(DRV_NAME ": Will ignore %d event types.\n", num_ignored_events);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int parse_remaps(struct platform_device *pdev)
|
||||
{
|
||||
struct device_node *remaps_np, *child;
|
||||
@@ -382,6 +426,10 @@ static int unified_joypad_probe(struct platform_device *pdev)
|
||||
if (of_property_read_u32(np, "virtual-version-id", &temp_val) == 0)
|
||||
vdev_version = (u16)temp_val;
|
||||
|
||||
ret = parse_ignore_list(pdev);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
ret = parse_remaps(pdev);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
Reference in New Issue
Block a user