linux-input.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
From: Benjamin Tissoires <benjamin.tissoires@gmail.com>
To: Henrik Rydberg <rydberg@euromail.se>
Cc: Dmitry Torokhov <dmitry.torokhov@gmail.com>,
	Jiri Kosina <jkosina@suse.cz>, Stephane Chatty <chatty@enac.fr>,
	linux-input@vger.kernel.org, linux-kernel@vger.kernel.org
Subject: Re: [PATCH v4 14/14] HID: hid-multitouch: forwards MSC_TIMESTAMP
Date: Wed, 14 Nov 2012 22:27:15 +0100	[thread overview]
Message-ID: <50A40CB3.8070105@gmail.com> (raw)
In-Reply-To: <20121114195852.GA14840@polaris.bitmath.org>

Hi Henrik,

On 11/14/2012 08:58 PM, Henrik Rydberg wrote:
> Hi Benjamin,
> 
>> Computes the device timestamp according to the specification.
>> It also ensures that if the time between two events is greater
>> than MAX_TIMESTAMP_INTERVAL, the timestamp will be reset.
>>
>> Signed-off-by: Benjamin Tissoires <benjamin.tissoires@gmail.com>
>> ---
> 
> This was not what I envisioned from the discussion yesterday, I was
> probably too vague. Firstly, the absolute time interval checked seems
> to be 500 ms, which is arbitrary. Second, the wrap should probably use

Not exactly. The time interval was 5s, near enough the minimum requirement for this field (6.5535 s).

> (logical_maximum + 1). Third, we are still not sure whether we should
> take the 'time = 0 means reset' logic literally, I think it needs to
> be tested.

Again, the device I have never does any reset at the first touch, it just wraps the counter.
The problem is that when there is no event, we now that no events occurred since the previous timestamp, modulus 6.5535 seconds.


> 
> In light of this, I would like to suggest the patch below instead. It
> should follow the current interpretation of the definition to the
> letter. I imagine very few devices will actually do anything but wrap
> the counter, but that remains to be seen. In that case, we could
> simplify the code further, since we will have no hope of detecting
> large intervals properly anyways.
> 
> Thanks,
> Henrik
> 
>  From 448808dd988e96d58b79148292fde147935305ab Mon Sep 17 00:00:00 2001
> From: Henrik Rydberg <rydberg@euromail.se>
> Date: Wed, 14 Nov 2012 20:53:17 +0100
> Subject: [PATCH] HID: hid-multitouch: send the device timestamp when present
> 
> Compute and relay the device timestamp when present. The counter
> value range varies between devices, but the MSC_TIMESTAMP event
> is always 32 bits long. A value of zero means the time since the
> previous event is unknown.
> 
> Signed-off-by: Henrik Rydberg <rydberg@euromail.se>
> ---
>   drivers/hid/hid-multitouch.c | 36 +++++++++++++++++++++++++++++++++---
>   include/linux/hid.h          |  1 +
>   2 files changed, 34 insertions(+), 3 deletions(-)
> 
> diff --git a/drivers/hid/hid-multitouch.c b/drivers/hid/hid-multitouch.c
> index 61543c0..586f9c6 100644
> --- a/drivers/hid/hid-multitouch.c
> +++ b/drivers/hid/hid-multitouch.c
> @@ -98,6 +98,8 @@ struct mt_device {
>   	bool serial_maybe;	/* need to check for serial protocol */
>   	bool curvalid;		/* is the current contact valid? */
>   	unsigned mt_flags;	/* flags to pass to input-mt */
> +	unsigned dev_time;	/* device scan time in units of 100 us */
> +	unsigned timestamp;	/* the timestamp to be sent */
>   };
>   
>   /* classes of device behavior */
> @@ -458,12 +460,19 @@ static int mt_input_mapping(struct hid_device *hdev, struct hid_input *hi,
>   			mt_store_field(usage, td, hi);
>   			td->last_field_index = field->index;
>   			return 1;
> +		case HID_DG_SCANTIME:
> +			hid_map_usage(hi, usage, bit, max,
> +				EV_MSC, MSC_TIMESTAMP);
> +			set_bit(MSC_TIMESTAMP, hi->input->mscbit);
> +			td->last_field_index = field->index;
> +			return 1;
>   		case HID_DG_CONTACTCOUNT:
>   			td->last_field_index = field->index;
>   			return 1;
>   		case HID_DG_CONTACTMAX:
> -			/* we don't set td->last_slot_field as contactcount and
> -			 * contact max are global to the report */
> +			/* we don't set td->last_slot_field as scan time,
> +			 * contactcount and contact max are global to the
> +			 * report */
>   			td->last_field_index = field->index;
>   			return -1;
>   		case HID_DG_TOUCH:
> @@ -492,7 +501,8 @@ static int mt_input_mapped(struct hid_device *hdev, struct hid_input *hi,
>   		struct hid_field *field, struct hid_usage *usage,
>   		unsigned long **bit, int *max)
>   {
> -	if (usage->type == EV_KEY || usage->type == EV_ABS)
> +	if (usage->type == EV_KEY || usage->type == EV_ABS ||
> +	    usage->type == EV_MSC)
>   		set_bit(usage->type, hi->input->evbit);
>   
>   	return -1;
> @@ -571,10 +581,27 @@ static void mt_complete_slot(struct mt_device *td, struct input_dev *input)
>   static void mt_sync_frame(struct mt_device *td, struct input_dev *input)
>   {
>   	input_mt_sync_frame(input);
> +	input_event(input, EV_MSC, MSC_TIMESTAMP, td->timestamp);
>   	input_sync(input);
>   	td->num_received = 0;
>   }
>   
> +static void mt_compute_timestamp(struct mt_device *td, struct hid_field *field,
> +				 unsigned value)
> +{
> +	unsigned dt;
> +
> +	if (value) {
> +		dt = (value - td->dev_time) % (field->logical_maximum + 1);

The curious thing is that this is not working on my kernel:

this is the output of the following printk:
 printk(KERN_ERR "%s timestamp=%d value=%d dt=%d field->logical_maximum=%d !td->timestamp=%d\n", __func__, td->timestamp, value, dt, field->logical_maximum, !td->timestamp);

Nov 14 22:09:55 localhost kernel: [ 1288.821899] mt_compute_timestamp timestamp=6535900 value=65359 dt=93 field->logical_maximum=65535 !td->timestamp=0
Nov 14 22:09:55 localhost kernel: [ 1288.831938] mt_compute_timestamp timestamp=6545200 value=65452 dt=93 field->logical_maximum=65535 !td->timestamp=0
Nov 14 22:09:55 localhost kernel: [ 1288.841852] mt_compute_timestamp timestamp=900 value=9 dt=-65443 field->logical_maximum=65535 !td->timestamp=0
Nov 14 22:09:55 localhost kernel: [ 1288.850852] mt_compute_timestamp timestamp=10300 value=103 dt=94 field->logical_maximum=65535 !td->timestamp=0
Nov 14 22:09:55 localhost kernel: [ 1288.860839] mt_compute_timestamp timestamp=19600 value=196 dt=93 field->logical_maximum=65535 !td->timestamp=0

I know I cheated when I put "dt=%d" for an unsigned, but the fact is that the counter rolls back...

However, his construction works:

static void mt_compute_timestamp(struct mt_device *td, struct hid_field *field,
		__s32 value)
{
	__s32 dt;

	if (value) {
		dt = value - td->dev_time;
		if (dt < 0)
			dt += field->logical_maximum + 1;
		td->timestamp += 100 * dt;
	} else {
		td->timestamp = 0;
	}

	td->dev_time = value;
}


> +		td->timestamp += 100 * dt;
> +		td->timestamp += !td->timestamp;

I don't understand the meaning of adding !td->timestamp. :/

> +	} else {
> +		td->timestamp = 0;

My particular device never falls into this case... So I never reset the timestamp.
This is problematic because we compute the timestamp on an unsigned, and the struct input_absinfo sends __s32... I'm afraid we will have some troubles after a long use of the device.

Anyway, many thanks for the review of this whole patchset!

Cheers,
Benjamin


> +	}
> +
> +	td->dev_time = value;
> +}
> +
>   static int mt_event(struct hid_device *hid, struct hid_field *field,
>   				struct hid_usage *usage, __s32 value)
>   {
> @@ -622,6 +649,9 @@ static int mt_event(struct hid_device *hid, struct hid_field *field,
>   		case HID_DG_HEIGHT:
>   			td->curdata.h = value;
>   			break;
> +		case HID_DG_SCANTIME:
> +			mt_compute_timestamp(td, field, value);
> +			break;
>   		case HID_DG_CONTACTCOUNT:
>   			/*
>   			 * Includes multi-packet support where subsequent
> diff --git a/include/linux/hid.h b/include/linux/hid.h
> index d2c42dd..eb7ec6c 100644
> --- a/include/linux/hid.h
> +++ b/include/linux/hid.h
> @@ -242,6 +242,7 @@ struct hid_item {
>   #define HID_DG_DEVICEINDEX	0x000d0053
>   #define HID_DG_CONTACTCOUNT	0x000d0054
>   #define HID_DG_CONTACTMAX	0x000d0055
> +#define HID_DG_SCANTIME		0x000d0056
>   
>   /*
>    * HID report types --- Ouch! HID spec says 1 2 3!
> 

  reply	other threads:[~2012-11-14 21:27 UTC|newest]

Thread overview: 33+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2012-11-14 15:59 [PATCH v4 00/14] Win 8 support for digitizers Benjamin Tissoires
2012-11-14 15:59 ` [PATCH v4 01/14] HID: hid-input: export hidinput_calc_abs_res Benjamin Tissoires
2012-11-14 15:59 ` [PATCH v4 02/14] HID: hid-input: round return value of hidinput_calc_abs_res Benjamin Tissoires
2012-11-14 15:59 ` [PATCH v4 03/14] HID: core: fix unit exponent parsing Benjamin Tissoires
2012-11-14 15:59 ` [PATCH v4 04/14] HID: hid-input: add usage_index in struct hid_usage Benjamin Tissoires
2012-11-14 15:59 ` [PATCH v4 05/14] HID: hid-multitouch: support arrays for the split of the touches in a report Benjamin Tissoires
2012-11-14 15:59 ` [PATCH v4 06/14] HID: hid-multitouch: get maxcontacts also from logical_max value Benjamin Tissoires
2012-11-14 15:59 ` [PATCH v4 07/14] HID: hid-multitouch: support T and C for win8 devices Benjamin Tissoires
2012-11-14 15:59 ` [PATCH v4 08/14] HID: hid-multitouch: move ALWAYS_VALID quirk check Benjamin Tissoires
2012-11-14 15:59 ` [PATCH v4 09/14] Input: introduce EV_MSC Timestamp Benjamin Tissoires
2012-11-14 16:33   ` Dmitry Torokhov
2012-11-15  9:14     ` Jiri Kosina
2012-11-14 17:53   ` Henrik Rydberg
2012-11-14 15:59 ` [PATCH v4 10/14] Input: mt: add input_mt_is_used Benjamin Tissoires
2012-11-14 17:16   ` Henrik Rydberg
2012-11-14 15:59 ` [PATCH v4 11/14] HID: hid-multitouch: add MT_QUIRK_IGNORE_DUPLICATES Benjamin Tissoires
2012-11-14 18:08   ` Henrik Rydberg
2012-11-14 15:59 ` [PATCH v4 12/14] HID: hid-multitouch: support for hovering devices Benjamin Tissoires
2012-11-14 18:43   ` Henrik Rydberg
2012-11-14 15:59 ` [PATCH v4 13/14] HID: hid-multitouch: fix Win 8 protocol Benjamin Tissoires
2012-11-14 18:47   ` Henrik Rydberg
2012-11-14 15:59 ` [PATCH v4 14/14] HID: hid-multitouch: forwards MSC_TIMESTAMP Benjamin Tissoires
2012-11-14 19:58   ` Henrik Rydberg
2012-11-14 21:27     ` Benjamin Tissoires [this message]
2012-11-16 20:09       ` Henrik Rydberg
2012-11-19 14:50         ` Benjamin Tissoires
2012-11-20 20:51           ` Henrik Rydberg
2012-11-20 20:54             ` Henrik Rydberg
2012-11-22 20:12               ` Benjamin Tissoires
2012-11-22 21:03                 ` Henrik Rydberg
2012-11-14 20:01 ` [PATCH v4 00/14] Win 8 support for digitizers Henrik Rydberg
2012-11-15  9:33   ` Jiri Kosina
2012-11-15 11:11     ` Benjamin Tissoires

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=50A40CB3.8070105@gmail.com \
    --to=benjamin.tissoires@gmail.com \
    --cc=chatty@enac.fr \
    --cc=dmitry.torokhov@gmail.com \
    --cc=jkosina@suse.cz \
    --cc=linux-input@vger.kernel.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=rydberg@euromail.se \
    /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).