Skip to content

Commit

Permalink
hid-xpadneo: Adhere to Linux Gamepad Specification
Browse files Browse the repository at this point in the history
Linux Gamepad Specification defines the idle position of the joystick
to have values (0,0). Let's add a parameter for this and turn the
feature on by default.

This may negatively impact a few Wine games which access the joystick
directly. You may also need the reset calibration data of `jscal` by
opening `/var/lib/joystick/joystick.state` and removing the line
prefixed with `jscal -s` while the controller is turned off. If the
file does not exist or is empty, there's nothing to fix.

Fixes: #57

This reverts commit 232a732.

Signed-off-by: Kai Krakow <[email protected]>
  • Loading branch information
kakra committed Jul 11, 2020
1 parent b15cca8 commit b2967bc
Showing 1 changed file with 26 additions and 1 deletion.
27 changes: 26 additions & 1 deletion hid-xpadneo/src/hid-xpadneo.c
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,12 @@ module_param_named(ff_connect_notify, param_ff_connect_notify, bool, 0644);
MODULE_PARM_DESC(ff_connect_notify,
"(bool) Connection notification using force feedback. 1: enable, 0: disable.");

static bool param_gamepad_compliance = 1;
module_param_named(gamepad_compliance, param_gamepad_compliance, bool, 0444);
MODULE_PARM_DESC(gamepad_compliance,
"(bool) Adhere to Linux Gamepad Specification by using signed axis values. "
"1: enable, 0: disable.");

#define XPADNEO_QUIRK_NO_PULSE 1
#define XPADNEO_QUIRK_NO_TRIGGER_RUMBLE 2
#define XPADNEO_QUIRK_NO_MOTOR_MASK 4
Expand Down Expand Up @@ -913,6 +919,14 @@ static int xpadneo_input_configured(struct hid_device *hdev, struct hid_input *h
break;
}

if (param_gamepad_compliance) {
hid_info(hdev, "enabling compliance with Linux Gamepad Specification\n");
input_set_abs_params(xdata->idev, ABS_X, -32768, 32767, 255, 4095);
input_set_abs_params(xdata->idev, ABS_Y, -32768, 32767, 255, 4095);
input_set_abs_params(xdata->idev, ABS_RX, -32768, 32767, 255, 4095);
input_set_abs_params(xdata->idev, ABS_RY, -32768, 32767, 255, 4095);
}

if (param_combined_z_axis) {
/*
* We also need to translate the incoming events to fit within
Expand All @@ -932,11 +946,22 @@ static int xpadneo_event(struct hid_device *hdev, struct hid_field *field,
struct input_dev *idev = xdata->idev;

if (usage->type == EV_ABS) {
switch (usage->code) {
case ABS_X:
case ABS_Y:
case ABS_RX:
case ABS_RY:
/* Linux Gamepad Specification */
if (param_gamepad_compliance) {
input_report_abs(idev, usage->code, value - 32768);
/* no need to sync here */
goto stop_processing;
}
break;
/*
* We need to combine ABS_Z and ABS_RZ if param_combined_z_axis
* is set, so remember the current value
*/
switch (usage->code) {
case ABS_Z:
xdata->last_abs_z = value;
if (param_combined_z_axis)
Expand Down

0 comments on commit b2967bc

Please sign in to comment.