From: Marcus Folkesson <marcus.folkesson@gmail.com>
To: Benjamin Tissoires <benjamin.tissoires@redhat.com>
Cc: Jonathan Corbet <corbet@lwn.net>, Jiri Kosina <jikos@kernel.org>,
Linux Doc Mailing List <linux-doc@vger.kernel.org>,
lkml <linux-kernel@vger.kernel.org>,
"open list:HID CORE LAYER" <linux-input@vger.kernel.org>
Subject: Re: [RESEND PATCH 1/2] HID: Add driver for RC Simulator Controllers
Date: Thu, 25 Aug 2022 08:48:52 +0200 [thread overview]
Message-ID: <YwcbVJswrL1Doi4s@gmail.com> (raw)
In-Reply-To: <CAO-hwJKiq50fWwXNUGcXeWtWcUXb65ZmJMsADfrsUTac_Xj2dw@mail.gmail.com>
[-- Attachment #1: Type: text/plain, Size: 10706 bytes --]
Hi Benjamin,
Thank you!
I have a few questions regarding the report descriptor, please see
below.
On Tue, Aug 23, 2022 at 06:43:47PM +0200, Benjamin Tissoires wrote:
> On Tue, Aug 23, 2022 at 5:13 PM Marcus Folkesson
> <marcus.folkesson@gmail.com> wrote:
> >
> > Thank you Benjamin,
> >
> > On Tue, Aug 23, 2022 at 11:49:59AM +0200, Benjamin Tissoires wrote:
> > > Hi Marcus,
> > >
> > > [and sorry for the delay in the review of your patches]
> > >
> > > On Mon, Aug 22, 2022 at 8:04 AM Marcus Folkesson
> > > <marcus.folkesson@gmail.com> wrote:
[...]
> > > > + };
> > > > +
> > > > + priv->input = input;
> > > > + return input_register_device(priv->input);
> > > > +}
> > >
> > > You are basically rewriting hid-input.c, which is suboptimal.
> >
> > Ouch. I will have a look at hid-input, thanks.
> >
> > >
> > > I guess the report descriptor provided by these devices are basically
> > > useless, and so you have to parse the reports yourself in the
> > > raw_event callback.
> >
> > Yep.
> >
> > >
> > > But instead of manually doing that, why not overwrite the report
> > > descriptor (with .rdesc_fixup) and declare here all of the data that
> > Do you mean .report_fixup?
>
> yes, sorry :/
>
> >
> > > needs to be exported. You could remove basically everything in this
> > > driver by just providing a fixed report descriptor.
> >
> > What you are aiming for is to fixup the report descriptor and let the
> > generic hid-raw driver handle the rest, or do I get you wrong?
>
> yep, exactly
>
> >
> > How is the report mapped to certain events then?
>
> Have a look at hid_configure_usage in hid-input.c [3]. Most of HID
> events are mapped to input events with a one to one mapping.
>
> >
> > I do read at [1] but it is not obvious how to put it together.
> > Most drivers I've looked at that is using .report_fixup just fix broken
> > reports. I guess these reports are not "broken", just.. odd?
>
> Have a look at [2], lots of full report descriptors :)
>
> And in your case, the reports are incomplete, not odd.
Got it.
I've parsed [4] the report descriptor for VRC2, and I guess it does not looks
that good:
0x05, 0x01, // Usage Page (Generic Desktop Ctrls)
0x09, 0x00, // Usage (Undefined)
0xA1, 0x01, // Collection (Application)
0x15, 0x00, // Logical Minimum (0)
0x25, 0x01, // Logical Maximum (1)
0x75, 0x01, // Report Size (1)
0x05, 0x09, // Usage Page (Button)
0x19, 0x01, // Usage Minimum (0x01)
0x29, 0x3F, // Usage Maximum (0x3F)
0x95, 0x40, // Report Count (64)
0x81, 0x02, // Input (Data,Var,Abs,No Wrap,Linear,Preferred State,No Null Position)
0xC0, // End Collection
The Usage should rather be Joystick than undefined, the other
fields does also looks wrong to me.
The data for each axis (WHEEL and GAS) is 11 bit long (Logical maximum
2047 ?), how does the report descriptor map to the actual data in terms
of offset, order and length?
>
> >
> >
> > >
> > > > +
> > > > +static int rcsim_raw_event(struct hid_device *hdev,
> > > > + struct hid_report *report,
> > > > + u8 *raw_data, int size)
> > > > +{
> > > > + struct rcsim_priv *priv = hid_get_drvdata(hdev);
> > > > + u16 value;
> > > > +
> > > > + switch (priv->controller) {
> > > > + case PHOENIXRC:
> > > > + if (size != PHOENIXRC_DSIZE)
> > > > + break;
> > > > +
> > > > + /* X, RX, Y and RY, RUDDER and THROTTLE are sent every time */
> > > > + input_report_abs(priv->input, ABS_X, raw_data[2]);
> > > > + input_report_abs(priv->input, ABS_Y, raw_data[0]);
> > > > + input_report_abs(priv->input, ABS_RX, raw_data[4]);
> > > > + input_report_abs(priv->input, ABS_RY, raw_data[3]);
> > > > + input_report_abs(priv->input, ABS_RUDDER, raw_data[5]);
> > > > + input_report_abs(priv->input, ABS_THROTTLE, raw_data[6]);
> > > > +
> > > > + /* Z and RZ are sent every other time */
> > > > + if (priv->alt)
> > > > + input_report_abs(priv->input, ABS_Z, raw_data[7]);
> > > > + else
> > > > + input_report_abs(priv->input, ABS_RZ, raw_data[7]);
> > > > +
> > > > + priv->alt ^= 1;
> > > > + break;
> > > > + case VRC2:
> > > > + if (size != VRC2_DSIZE)
> > > > + break;
> > > > + value = (raw_data[1] << 8 | raw_data[0]) & GENMASK(10, 0);
> > > > + input_report_abs(priv->input, ABS_GAS, value);
> > > > + value = (raw_data[3] << 8 | raw_data[2]) & GENMASK(10, 0);
> > > > + input_report_abs(priv->input, ABS_WHEEL, value);
> > > > + break;
> > > > + case REALFLIGHT:
> > > > + if (size != REALFLIGHT_DSIZE)
> > > > + break;
> > > > + input_report_abs(priv->input, ABS_X, raw_data[2]);
> > > > + input_report_abs(priv->input, ABS_Y, raw_data[1]);
> > > > + input_report_abs(priv->input, ABS_RX, raw_data[5]);
> > > > + input_report_abs(priv->input, ABS_RY, raw_data[3]);
> > > > + input_report_abs(priv->input, ABS_MISC, raw_data[4]);
> > > > + input_report_key(priv->input, BTN_A,
> > > > + raw_data[7] & REALFLIGHT_BTN_A);
> > > > + input_report_key(priv->input, BTN_B,
> > > > + raw_data[7] & REALFLIGHT_BTN_B);
> > > > + break;
> > > > + case XTRG2FMS:
> > > > + if (size != XTRG2FMS_DSIZE)
> > > > + break;
> > > > +
> > > > + /* X, RX, Y and RY are sent every time */
> > > > + value = FIELD_GET(XTRG2FMS_X_HI, raw_data[3]);
> > > > + value = (value << 8) | raw_data[1];
> > > > + input_report_abs(priv->input, ABS_X, value);
> > > > +
> > > > + value = FIELD_GET(XTRG2FMS_Y_HI, raw_data[3]);
> > > > + value = (value << 8) | raw_data[2];
> > > > + input_report_abs(priv->input, ABS_Y, value);
> > > > +
> > > > + value = FIELD_GET(XTRG2FMS_RX_HI, raw_data[3]);
> > > > + value = (value << 8) | raw_data[0];
> > > > + input_report_abs(priv->input, ABS_RX, value);
> > > > +
> > > > + value = FIELD_GET(XTRG2FMS_RY_HI, raw_data[3]);
> > > > + value = (value << 8) | raw_data[4];
> > > > + input_report_abs(priv->input, ABS_RY, value);
> > > > +
> > > > + /* Z, RZ, RUDDER and THROTTLE are sent every other time */
> > > > + value = FIELD_GET(XTRG2FMS_ALT1_HI, raw_data[7]);
> > > > + value = (value << 8) | raw_data[6];
> > > > + if (priv->alt)
> > > > + input_report_abs(priv->input, ABS_Z, value);
> > > > + else
> > > > + input_report_abs(priv->input, ABS_RUDDER, value);
> > > > +
> > > > + value = FIELD_GET(XTRG2FMS_ALT2_HI, raw_data[7]);
> > > > + value = (value << 8) | raw_data[5];
> > > > + if (priv->alt)
> > > > + input_report_abs(priv->input, ABS_RZ, value);
> > > > + else
> > > > + input_report_abs(priv->input, ABS_THROTTLE, value);
> > > > +
> > > > + priv->alt ^= 1;
> > > > + break;
> > > > + case ORANGERX:
> > > > + if (size != ORANGERX_DSIZE)
> > > > + break;
> > > > + input_report_abs(priv->input, ABS_X, raw_data[0]);
> > > > + input_report_abs(priv->input, ABS_Y, raw_data[2]);
> > > > + input_report_abs(priv->input, ABS_RX, raw_data[3]);
> > > > + input_report_abs(priv->input, ABS_RY, raw_data[1]);
> > > > + input_report_abs(priv->input, ABS_RUDDER, raw_data[5]);
> > > > + input_report_abs(priv->input, ABS_THROTTLE, raw_data[6]);
> > > > + break;
> > > > + };
> > > > +
> > > > + input_sync(priv->input);
> > > > + return 0;
> > > > +}
> > > > +
> > > > +static int rcsim_probe(struct hid_device *hdev, const struct hid_device_id *id)
> > > > +{
> > > > + struct device *dev = &hdev->dev;
> > > > + struct rcsim_priv *priv;
> > > > + int ret;
> > > > +
> > > > + if (!hid_is_using_ll_driver(hdev, &usb_hid_driver))
> > > > + return -ENODEV;
> > >
> > > You are not accessing anything in the USB stack, so there is no need
> > > to prevent regression tests that could inject uhid devices to your
> > > drivers.
> >
> > Ok, thanks.
> >
> > >
> > > Cheers,
> > > Benjamin
> > >
> >
> > Best regards,
> > Marcus Folkesson
> >
> > [1] https://www.usb.org/hid
> >
>
> If you need help in writing report descriptors, I can give you some,
> but the easiest might be for you to start from the report descriptor
> in hid-sony.c. I used to have a tool to dynamically write a report
> descriptor, but I'm not sure it still works...
I think at least some advice would be great :-)
The VRC2 would be the most simple of those, it only has 2 axis with
resolution of 11-bit.
If you have time, would you please give some advice what a report descriptor would look
like and I could probably come up with something for the others.
>
> FYI, I just re-read rcsim_raw_event() and there is stuff that would
> require more than just a report descriptor fixup (the fact that some
> data is sent every other report is not good and will need some manual
> handling though).
Is the fact that more than one button share the same
byte hard to describe in the report?
value = FIELD_GET(XTRG2FMS_ALT1_HI, raw_data[7]);
value = (value << 8) | raw_data[6];
...
value = FIELD_GET(XTRG2FMS_ALT2_HI, raw_data[7]);
value = (value << 8) | raw_data[5];
>
> Cheers,
> Benjamin
>
Best regards
Marcus Folkesson
> [2] https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/drivers/hid/hid-uclogic-rdesc.c
> [3] https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/drivers/hid/hid-input.c#n817
[4] https://eleccelerator.com/usbdescreqparser/
[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 833 bytes --]
next prev parent reply other threads:[~2022-08-25 6:44 UTC|newest]
Thread overview: 16+ messages / expand[flat|nested] mbox.gz Atom feed top
2022-08-22 6:09 [RESEND PATCH 1/2] HID: Add driver for RC Simulator Controllers Marcus Folkesson
2022-08-22 6:09 ` [RESEND PATCH 2/2] MAINTAINERS: Add entry " Marcus Folkesson
2022-08-23 9:49 ` [RESEND PATCH 1/2] HID: Add driver " Benjamin Tissoires
2022-08-23 15:18 ` Marcus Folkesson
2022-08-23 16:43 ` Benjamin Tissoires
2022-08-25 6:48 ` Marcus Folkesson [this message]
2022-08-30 12:45 ` Benjamin Tissoires
2022-09-15 7:34 ` Marcus Folkesson
2022-09-15 7:35 ` Benjamin Tissoires
2022-09-19 13:32 ` Benjamin Tissoires
2023-01-10 14:48 ` Marcus Folkesson
2022-08-28 14:18 ` Marcus Folkesson
2022-08-30 12:35 ` Benjamin Tissoires
2022-08-30 14:43 ` Marcus Folkesson
2022-08-30 15:01 ` Benjamin Tissoires
2023-03-25 16:08 ` Pavel Machek
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=YwcbVJswrL1Doi4s@gmail.com \
--to=marcus.folkesson@gmail.com \
--cc=benjamin.tissoires@redhat.com \
--cc=corbet@lwn.net \
--cc=jikos@kernel.org \
--cc=linux-doc@vger.kernel.org \
--cc=linux-input@vger.kernel.org \
--cc=linux-kernel@vger.kernel.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).