diff --git a/projects/ROCKNIX/packages/linux-drivers/unified-joypad/sources/example.dts b/projects/ROCKNIX/packages/linux-drivers/unified-joypad/sources/example.dts index ecce6d9460..3225d3209d 100644 --- a/projects/ROCKNIX/packages/linux-drivers/unified-joypad/sources/example.dts +++ b/projects/ROCKNIX/packages/linux-drivers/unified-joypad/sources/example.dts @@ -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: . + * - 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 --- diff --git a/projects/ROCKNIX/packages/linux-drivers/unified-joypad/sources/unified-joypad.c b/projects/ROCKNIX/packages/linux-drivers/unified-joypad/sources/unified-joypad.c index f03b55d18b..1304e55aab 100644 --- a/projects/ROCKNIX/packages/linux-drivers/unified-joypad/sources/unified-joypad.c +++ b/projects/ROCKNIX/packages/linux-drivers/unified-joypad/sources/unified-joypad.c @@ -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;