All of lore.kernel.org
 help / color / mirror / Atom feed
From: Nikolai Kondrashov <spbnick@gmail.com>
To: Benjamin Tissoires <benjamin.tissoires@redhat.com>
Cc: Jiri Kosina <jkosina@suse.cz>,
	Peter Hutterer <peter.hutterer@who-t.net>,
	linux-input@vger.kernel.org, linux-kernel@vger.kernel.org,
	DIGImend-devel <DIGImend-devel@lists.sourceforge.net>
Subject: Re: [PATCH 1/2] HID: huion: enable button mode reporting
Date: Thu, 19 Feb 2015 13:37:24 +0200	[thread overview]
Message-ID: <54E5CAF4.5070205@gmail.com> (raw)
In-Reply-To: <20150218202447.GD5928@mail.corp.redhat.com>

On 02/18/2015 10:24 PM, Benjamin Tissoires wrote:
> On Feb 18 2015 or thereabouts, Nikolai Kondrashov wrote:
>> On 02/18/2015 12:54 AM, Benjamin Tissoires wrote:
>>> diff --git a/drivers/hid/hid-huion.c b/drivers/hid/hid-huion.c
>>> index 61b68ca..50fbda4 100644
>>> --- a/drivers/hid/hid-huion.c
>>> +++ b/drivers/hid/hid-huion.c
>>> @@ -34,6 +34,9 @@ enum huion_ph_id {
>>>   	HUION_PH_ID_NUM
>>>   };
>>>
>>> +/* header of a button report sent through the Pen report */
>>> +static const u8 button_report[]  = {0x07, 0xa0, 0x01, 0x01};
>>
>> Hmm, I see the second byte being 0xe0 on Huion H610, the rest is the same.
>> Considering this, the fact that bit 7 is always 1 and bit 6 is pen proximity,
>> I think we can assume that bit 5 in byte 2 indicates button reports and get
>> away with just a "data[1] & 0x20" test.
>
> that would be a nicer approach. Thanks for the analysis.
> Actually, I understood the difference. I tested the bits _after_ the
> driver reverts the in-range bit :)

Ah, I missed that.

> The raw data is {0x07, 0xe0, 0x01, 0x01} on the H610 Pro too.

That's good, less weirdness to handle :)

>>>   /* Report descriptor template placeholder */
>>>   #define HUION_PH(_ID) HUION_PH_HEAD, HUION_PH_ID_##_ID
>>>
>>> @@ -81,6 +84,31 @@ static const __u8 huion_tablet_rdesc_template[] = {
>>>   	HUION_PH(PRESSURE_LM),  /*          Logical Maximum (PLACEHOLDER),  */
>>>   	0x81, 0x02,             /*          Input (Variable),               */
>>>   	0xC0,                   /*      End Collection,                     */
>>> +	0x05, 0x01,             /*      Usage Page (Desktop)                */
>>> +	0x09, 0x07,             /*      Usage (Keypad)                      */
>>> +	0xa1, 0x01,             /*      Collection (Application)            */
>>> +	0x85, 0x08,             /*          Report ID (8)                   */
>>> +	0x05, 0x0d,             /*          Usage Page (Digitizers)         */
>>> +	0x09, 0x22,             /*          Usage (Finger)                  */
>>
>> I'd say "Finger" usage is wrong here. The spec says:
>>
>>      Finger
>>
>>          CL – Any human appendage used as a transducer, such as a finger
>>          touching a touch screen to set the location of the screen cursor.  A
>>          digitizer typically reports the coordinates of center of the finger.
>>          In the Finger collection a Pointer physical collection will contain
>>          the axes reported by the finger.
>>
>> I.e. the buttons are not a pointing device. The specification contains another
>> collection usage which seems more suitable:
>>
>>      Tablet Function Keys
>>
>>          CL – These controls are located on the surface of a digitizing tablet,
>>          and may be implemented as actual switches, or as soft keys actuated by
>>          the digitizing transducer. These are often used to trigger
>>          location-independent macros or other events.
>
> Actually, the kernel knows about it: HID_DG_TABLETFUNCTIONKEY.
> I don't think it should influence to have it set. The hid processing
> would work on the BTN usages, not on the physical.
>
> [5 min later]
>
> yep, just works :)

Cool :)!

>> However the kernel doesn't seem to know anything about it (but we can fix
>> that). In my version of this I simply used a keyboard with buttons:
>>
>>      0x05, 0x01,             /*  Usage Page (Desktop),                   */
>>      0x09, 0x06,             /*  Usage (Keyboard),                       */
>>      0xA1, 0x01,             /*  Collection (Application),               */
>>      0x85, 0xF7,             /*      Report ID (247),                    */
>>      0x05, 0x09,             /*      Usage Page (Button),                */
>>      0x75, 0x01,             /*      Report Size (1),                    */
>>      0x95, 0x18,             /*      Report Count (24),                  */
>>      0x81, 0x03,             /*      Input (Constant, Variable),         */
>>      0x19, 0x01,             /*      Usage Minimum (01h),                */
>>      0x29, 0x08,             /*      Usage Maximum (08h),                */
>>      0x95, 0x08,             /*      Report Count (8),                   */
>>      0x81, 0x02,             /*      Input (Variable),                   */
>>      0xC0                    /*  End Collection                          */
>>
>> Although it might not be entirely correct either.
>
> Even if no-one but hid-core uses the report descriptor, I would rather
> not declare ourself as a keyboard. It's shooting on our own foot if
> someone decides to actually merge a keyboard and a tablet.

Yes, I think you're right.

>>> +	0xa0,                   /*          Collection (Physical)           */
>>> +	0x14,                   /*              Logical Minimum (0)         */
>>> +	0x25, 0x01,             /*              Logical Maximum (1)         */
>>> +	0x75, 0x08,             /*              Report Size (8)             */
>>> +	0x95, 0x03,             /*              Report Count (3)            */
>>> +	0x81, 0x03,             /*              Input (Cnst,Var,Abs)        */
>>> +	0x05, 0x09,             /*              Usage Page (Button)         */
>>> +	0x19, 0x01,             /*              Usage Minimum (1)           */
>>> +	0x29, 0x08,             /*              Usage Maximum (8)           */
>>> +	0x14,                   /*              Logical Minimum (0)         */
>>> +	0x25, 0x01,             /*              Logical Maximum (1)         */
>>> +	0x75, 0x01,             /*              Report Size (1)             */
>>> +	0x95, 0x08,             /*              Report Count (8)            */
>>> +	0x81, 0x02,             /*              Input (Data,Var,Abs)        */
>>> +	0x75, 0x08,             /*              Report Size (8)             */
>>> +	0x95, 0x03,             /*              Report Count (3)            */
>>> +	0x81, 0x03,             /*              Input (Cnst,Var,Abs)        */
>>> +	0xc0,                   /*          End Collection                  */
>>> +	0xc0,                   /*      End Collection                      */
>>
>> Which tool did you use to generate this?
>
> My own custom-made:
> https://github.com/bentiss/hid-replay/blob/master/tools/editor.py
>
> not 100% implemented, but it works for me :)

Ah, nice :) Here is mine: https://github.com/DIGImend/hidrd

>>>   	0xC0                    /*  End Collection                          */
>>>   };
>>>
>>> @@ -205,6 +233,25 @@ static int huion_tablet_enable(struct hid_device *hdev)
>>>   		}
>>>   	}
>>>
>>> +	/* switch to the button mode reporting */
>>> +	rc = usb_control_msg(usb_dev, usb_rcvctrlpipe(usb_dev, 0),
>>> +				USB_REQ_GET_DESCRIPTOR, USB_DIR_IN,
>>> +				(USB_DT_STRING << 8) + 0x7b,
>>> +				0x0409, buf, len,
>>> +				USB_CTRL_GET_TIMEOUT);
>>
>> I'm a bit uncomfortable about reusing a buffer which was sized specifically
>> for another task, as it's confusing. But it will work as is, so it's OK.
>
> Yes, and no :)
>
> Actually, I would prefer that we stick to what the Windows driver do.
> But it requests 32 bytes in each requests, and we receive 14 and 22
> IIRC. The trick I exploited here is that the ctrl message answers back
> at most len data, so we are find in both cases because 12 is less than
> 14 and 22. I am not sure we should check at all the length of the
> returning buffer (though for the first command, we have to be sure that
> we received enough to get the values in the buffer).

In that case, if we want to mimic the Windows driver we can request 32 bytes
always and do a compile-time check that our parameters fit into that.

> Side note: the huion-abstract-keyboard branch uses usb_string() instead
> of a plain usb_control_msg(). I like this much better and I think we
> should change the first call with that. This way, it will be clear that
> the tablet is not fully HID compatible and that we need to keep the usb
> access.

No, we can't do that to the parameters string, because usb_string() does
utf16s_to_utf8s on the received data.

>>> +		/* check for buttons events and change the report ID */
>>> +		if (size >= sizeof(button_report) &&
>>> +		    !memcmp(data, button_report, sizeof(button_report)))
>>
>> So, yes, I think it's better to have a "data[1] & 0x20" test here instead.
>
> Yep, works just fine.

Nice :)

Nick
--
To unsubscribe from this list: send the line "unsubscribe linux-input" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

WARNING: multiple messages have this Message-ID (diff)
From: Nikolai Kondrashov <spbnick@gmail.com>
To: Benjamin Tissoires <benjamin.tissoires@redhat.com>
Cc: Jiri Kosina <jkosina@suse.cz>,
	Peter Hutterer <peter.hutterer@who-t.net>,
	linux-input@vger.kernel.org, linux-kernel@vger.kernel.org,
	DIGImend-devel <DIGImend-devel@lists.sourceforge.net>
Subject: Re: [PATCH 1/2] HID: huion: enable button mode reporting
Date: Thu, 19 Feb 2015 13:37:24 +0200	[thread overview]
Message-ID: <54E5CAF4.5070205@gmail.com> (raw)
In-Reply-To: <20150218202447.GD5928@mail.corp.redhat.com>

On 02/18/2015 10:24 PM, Benjamin Tissoires wrote:
> On Feb 18 2015 or thereabouts, Nikolai Kondrashov wrote:
>> On 02/18/2015 12:54 AM, Benjamin Tissoires wrote:
>>> diff --git a/drivers/hid/hid-huion.c b/drivers/hid/hid-huion.c
>>> index 61b68ca..50fbda4 100644
>>> --- a/drivers/hid/hid-huion.c
>>> +++ b/drivers/hid/hid-huion.c
>>> @@ -34,6 +34,9 @@ enum huion_ph_id {
>>>   	HUION_PH_ID_NUM
>>>   };
>>>
>>> +/* header of a button report sent through the Pen report */
>>> +static const u8 button_report[]  = {0x07, 0xa0, 0x01, 0x01};
>>
>> Hmm, I see the second byte being 0xe0 on Huion H610, the rest is the same.
>> Considering this, the fact that bit 7 is always 1 and bit 6 is pen proximity,
>> I think we can assume that bit 5 in byte 2 indicates button reports and get
>> away with just a "data[1] & 0x20" test.
>
> that would be a nicer approach. Thanks for the analysis.
> Actually, I understood the difference. I tested the bits _after_ the
> driver reverts the in-range bit :)

Ah, I missed that.

> The raw data is {0x07, 0xe0, 0x01, 0x01} on the H610 Pro too.

That's good, less weirdness to handle :)

>>>   /* Report descriptor template placeholder */
>>>   #define HUION_PH(_ID) HUION_PH_HEAD, HUION_PH_ID_##_ID
>>>
>>> @@ -81,6 +84,31 @@ static const __u8 huion_tablet_rdesc_template[] = {
>>>   	HUION_PH(PRESSURE_LM),  /*          Logical Maximum (PLACEHOLDER),  */
>>>   	0x81, 0x02,             /*          Input (Variable),               */
>>>   	0xC0,                   /*      End Collection,                     */
>>> +	0x05, 0x01,             /*      Usage Page (Desktop)                */
>>> +	0x09, 0x07,             /*      Usage (Keypad)                      */
>>> +	0xa1, 0x01,             /*      Collection (Application)            */
>>> +	0x85, 0x08,             /*          Report ID (8)                   */
>>> +	0x05, 0x0d,             /*          Usage Page (Digitizers)         */
>>> +	0x09, 0x22,             /*          Usage (Finger)                  */
>>
>> I'd say "Finger" usage is wrong here. The spec says:
>>
>>      Finger
>>
>>          CL – Any human appendage used as a transducer, such as a finger
>>          touching a touch screen to set the location of the screen cursor.  A
>>          digitizer typically reports the coordinates of center of the finger.
>>          In the Finger collection a Pointer physical collection will contain
>>          the axes reported by the finger.
>>
>> I.e. the buttons are not a pointing device. The specification contains another
>> collection usage which seems more suitable:
>>
>>      Tablet Function Keys
>>
>>          CL – These controls are located on the surface of a digitizing tablet,
>>          and may be implemented as actual switches, or as soft keys actuated by
>>          the digitizing transducer. These are often used to trigger
>>          location-independent macros or other events.
>
> Actually, the kernel knows about it: HID_DG_TABLETFUNCTIONKEY.
> I don't think it should influence to have it set. The hid processing
> would work on the BTN usages, not on the physical.
>
> [5 min later]
>
> yep, just works :)

Cool :)!

>> However the kernel doesn't seem to know anything about it (but we can fix
>> that). In my version of this I simply used a keyboard with buttons:
>>
>>      0x05, 0x01,             /*  Usage Page (Desktop),                   */
>>      0x09, 0x06,             /*  Usage (Keyboard),                       */
>>      0xA1, 0x01,             /*  Collection (Application),               */
>>      0x85, 0xF7,             /*      Report ID (247),                    */
>>      0x05, 0x09,             /*      Usage Page (Button),                */
>>      0x75, 0x01,             /*      Report Size (1),                    */
>>      0x95, 0x18,             /*      Report Count (24),                  */
>>      0x81, 0x03,             /*      Input (Constant, Variable),         */
>>      0x19, 0x01,             /*      Usage Minimum (01h),                */
>>      0x29, 0x08,             /*      Usage Maximum (08h),                */
>>      0x95, 0x08,             /*      Report Count (8),                   */
>>      0x81, 0x02,             /*      Input (Variable),                   */
>>      0xC0                    /*  End Collection                          */
>>
>> Although it might not be entirely correct either.
>
> Even if no-one but hid-core uses the report descriptor, I would rather
> not declare ourself as a keyboard. It's shooting on our own foot if
> someone decides to actually merge a keyboard and a tablet.

Yes, I think you're right.

>>> +	0xa0,                   /*          Collection (Physical)           */
>>> +	0x14,                   /*              Logical Minimum (0)         */
>>> +	0x25, 0x01,             /*              Logical Maximum (1)         */
>>> +	0x75, 0x08,             /*              Report Size (8)             */
>>> +	0x95, 0x03,             /*              Report Count (3)            */
>>> +	0x81, 0x03,             /*              Input (Cnst,Var,Abs)        */
>>> +	0x05, 0x09,             /*              Usage Page (Button)         */
>>> +	0x19, 0x01,             /*              Usage Minimum (1)           */
>>> +	0x29, 0x08,             /*              Usage Maximum (8)           */
>>> +	0x14,                   /*              Logical Minimum (0)         */
>>> +	0x25, 0x01,             /*              Logical Maximum (1)         */
>>> +	0x75, 0x01,             /*              Report Size (1)             */
>>> +	0x95, 0x08,             /*              Report Count (8)            */
>>> +	0x81, 0x02,             /*              Input (Data,Var,Abs)        */
>>> +	0x75, 0x08,             /*              Report Size (8)             */
>>> +	0x95, 0x03,             /*              Report Count (3)            */
>>> +	0x81, 0x03,             /*              Input (Cnst,Var,Abs)        */
>>> +	0xc0,                   /*          End Collection                  */
>>> +	0xc0,                   /*      End Collection                      */
>>
>> Which tool did you use to generate this?
>
> My own custom-made:
> https://github.com/bentiss/hid-replay/blob/master/tools/editor.py
>
> not 100% implemented, but it works for me :)

Ah, nice :) Here is mine: https://github.com/DIGImend/hidrd

>>>   	0xC0                    /*  End Collection                          */
>>>   };
>>>
>>> @@ -205,6 +233,25 @@ static int huion_tablet_enable(struct hid_device *hdev)
>>>   		}
>>>   	}
>>>
>>> +	/* switch to the button mode reporting */
>>> +	rc = usb_control_msg(usb_dev, usb_rcvctrlpipe(usb_dev, 0),
>>> +				USB_REQ_GET_DESCRIPTOR, USB_DIR_IN,
>>> +				(USB_DT_STRING << 8) + 0x7b,
>>> +				0x0409, buf, len,
>>> +				USB_CTRL_GET_TIMEOUT);
>>
>> I'm a bit uncomfortable about reusing a buffer which was sized specifically
>> for another task, as it's confusing. But it will work as is, so it's OK.
>
> Yes, and no :)
>
> Actually, I would prefer that we stick to what the Windows driver do.
> But it requests 32 bytes in each requests, and we receive 14 and 22
> IIRC. The trick I exploited here is that the ctrl message answers back
> at most len data, so we are find in both cases because 12 is less than
> 14 and 22. I am not sure we should check at all the length of the
> returning buffer (though for the first command, we have to be sure that
> we received enough to get the values in the buffer).

In that case, if we want to mimic the Windows driver we can request 32 bytes
always and do a compile-time check that our parameters fit into that.

> Side note: the huion-abstract-keyboard branch uses usb_string() instead
> of a plain usb_control_msg(). I like this much better and I think we
> should change the first call with that. This way, it will be clear that
> the tablet is not fully HID compatible and that we need to keep the usb
> access.

No, we can't do that to the parameters string, because usb_string() does
utf16s_to_utf8s on the received data.

>>> +		/* check for buttons events and change the report ID */
>>> +		if (size >= sizeof(button_report) &&
>>> +		    !memcmp(data, button_report, sizeof(button_report)))
>>
>> So, yes, I think it's better to have a "data[1] & 0x20" test here instead.
>
> Yep, works just fine.

Nice :)

Nick

  reply	other threads:[~2015-02-19 11:37 UTC|newest]

Thread overview: 21+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2015-02-17 22:54 [PATCH 0/2] HID: huion: add libinput support Benjamin Tissoires
2015-02-17 22:54 ` [PATCH 1/2] HID: huion: enable button mode reporting Benjamin Tissoires
2015-02-18 10:11   ` Nikolai Kondrashov
2015-02-18 20:24     ` Benjamin Tissoires
2015-02-19 11:37       ` Nikolai Kondrashov [this message]
2015-02-19 11:37         ` Nikolai Kondrashov
2015-02-18 12:17   ` Nikolai Kondrashov
2015-02-18 20:25     ` Benjamin Tissoires
2015-02-17 22:54 ` [PATCH 2/2] HID: huion: split the stylus and pad in 2 nodes Benjamin Tissoires
2015-02-18 10:17   ` Nikolai Kondrashov
2015-02-18  9:25 ` [PATCH 0/2] HID: huion: add libinput support Nikolai Kondrashov
2015-02-18 20:04   ` Benjamin Tissoires
2015-02-19 11:54     ` Nikolai Kondrashov
2015-02-20  5:34       ` Peter Hutterer
2015-02-22 12:33         ` Nikolai Kondrashov
2015-02-22 23:28           ` Peter Hutterer
2015-02-23 22:34             ` Benjamin Tissoires
2015-02-24 11:22               ` Nikolai Kondrashov
2015-02-24 21:45                 ` Peter Hutterer
2015-02-23 22:44       ` Benjamin Tissoires
2015-02-24 11:27         ` Nikolai Kondrashov

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=54E5CAF4.5070205@gmail.com \
    --to=spbnick@gmail.com \
    --cc=DIGImend-devel@lists.sourceforge.net \
    --cc=benjamin.tissoires@redhat.com \
    --cc=jkosina@suse.cz \
    --cc=linux-input@vger.kernel.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=peter.hutterer@who-t.net \
    /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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.