Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Expose Axis enable and Direction arrays #69

Open
3 of 8 tasks
Lawstorant opened this issue Feb 17, 2025 · 2 comments
Open
3 of 8 tasks

Expose Axis enable and Direction arrays #69

Lawstorant opened this issue Feb 17, 2025 · 2 comments

Comments

@Lawstorant
Copy link
Contributor

Lawstorant commented Feb 17, 2025

Overview

USB PID standard defines two ways to enable axes when uploading an effect. Direction enable (hid-pidff currently only ever uses this one) or Axes enable. In this issue, we will track the progress on exposing axis enable in Linux kernel and it's FF api.

From PID document:
Axes Enable: US – The Axes Enable collection contains joint collections. Each
joint collection contains axes or vectors from the Generic Desktop
page. This usage changes the type of these Generic Desktop
usages to Dynamic Flags (DF) where each usage identifies
whether the respective axis or vector is enabled for this effect.

Direction: CL – The Direction collection contains joint collections. Each
joint collection contains axes or vectors from the Generic Desktop
page. Each axis usage is treated as a Dynamic Variable (DV).
If the values are in Cartesian coordinates then axes usages X, Y or
Z or vector usages Vx, Vy or Vz will be declared in this collection
as normalized values.
If the values are in polar coordinates then axes usages Rx, Ry or
Rz or vector usages Vbrx, Vbry or Vbrz will be declared in this
collection as normalized values.

I'm working on it here:
Axes Enable branch

TODO

  • Find Axes Enable field
  • Find axis usages in the field
  • Send out Axis enable and directions
  • Check if report_count of Axes Enable and Direction is the same
  • Prepare pidff_set_effect for Axes Enable and direction array exposition
  • Expose Axes Enable in ff api
  • Expose direction array in ff api (probably a separate one for compatibility?)
  • Connect exposed api values to fields in the driver
@Lawstorant
Copy link
Contributor Author

Lawstorant commented Feb 17, 2025

I added the AXES_ENABLE field and 6 corresponding axes to the driver.

/* PID special fields */
#define PID_AXES_ENABLE			0x55

/* AXES_ENABLE and DIRECTION axes */
#define PID_AXIS_X	0
#define PID_AXIS_Y	1
#define PID_AXIS_Z	2
#define PID_AXIS_RX	3
#define PID_AXIS_RY	4
#define PID_AXIS_RZ	5
static const u8 pidff_direction_axis[] = {
	HID_USAGE & HID_GD_X,
	HID_USAGE & HID_GD_Y,
	HID_USAGE & HID_GD_Z,
	HID_USAGE & HID_GD_RX,
	HID_USAGE & HID_GD_RY,
	HID_USAGE & HID_GD_RZ
};

Adapted pidff_find_special_keys to search for generic desktop usages. Added configurable usage_page here:

static int pidff_find_special_keys(int *keys, struct hid_field *fld,
				   const u8 *usagetable, int count,
				   unsigned usage_page)

Which changes internal if from:

if (fld->usage[j].hid == (HID_UP_PID | usagetable[i]))

To:

if (fld->usage[j].hid == (usage_page | usagetable[i]))

This in turn is used by modified PIDFF_FIND_SPECIAL_KEYS and new PIDFF_FIND_GENERIC_DESKTOP:

#define PIDFF_FIND_SPECIAL_KEYS(keys, field, name) \
	pidff_find_special_keys(pidff->keys, pidff->field, pidff_ ## name, \
		sizeof(pidff_ ## name), HID_UP_PID)

#define PIDFF_FIND_GENERAL_DESKTOP(keys, field, name) \
	pidff_find_special_keys(pidff->keys, pidff->field, pidff_ ## name, \
		sizeof(pidff_ ## name), HID_UP_GENDESK)

Searching:

pidff->axes_enable = pidff_find_special_field(pidff->reports[PID_SET_EFFECT],
					      PID_AXES_ENABLE, 0);

PIDFF_FIND_GENERAL_DESKTOP(direction_axis_id, axes_enable, direction_axis);

With some additional debugs I managed to find everything on my Moza R9:

Image

@Lawstorant
Copy link
Contributor Author

Now, I adapted pidff_set_effect_report to not use PID_DIRECTION_ENABLE but ENABLE_AXES on all found axes + set the direction on all found axes:

int i, index;
for (i = 0; i < sizeof(pidff_direction_axis); i++) {
	index = pidff->direction_axis_id[i] - 1;

	/* Check if axis usage was found */
	if (index >= 0) {
		pidff->axes_enable->value[index] = 1;
		pidff->effect_direction->value[index] = pidff_rescale(
			effect->direction, U16_MAX, pidff->effect_direction);
	}
}

With some earlier tests, I managed to enable X and Y axis separately. My Moza R9 correctly refused to play Constant force effect when only Y axis was enabled:

Image

Image

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant