Log "Mtouch device has inconsistent digit ordering" occurs when input event lib calls mtouch callback function

Hi there,

I have implemented three essential mtouch callback function - get_contact_id, is_contact_down and get_coords. Here’s my current implementation of is_contact_down.

static int is_contact_down(void *packet, uint8_t digit_idx, int *valid, void *arg)
{
struct tp_event *message = packet;
uint32_t i;

if (!packet && !valid) {
	mtouch_error(NOVATEK_DEVNAME, "Argument pointer packet/valid is NULL!");
	return -1;
} else {
	*valid = 0;
	if (message->touch_point[digit_idx].valid) {
		*valid = message->touch_point[digit_idx].status;
		if (ts->verbose >= 5) {
			mtouch_info(NOVATEK_DEVNAME, "%s: DigitIdx = %d is %s, num_touchpoints/%d", __func__, 
					digit_idx, (*valid) ? "Down" : "Up", message->num_touchpoints);
		}
	} else {
		if (ts->verbose >= 7) {
			mtouch_info(NOVATEK_DEVNAME, "%s: No touch with digit_idx %u", __func__, digit_idx);
		}
		return EOK;
	}
}

return EOK;

}

It’s fine now but I found that when the line which assigns 0 to “*valid” (*valid = 0) is removed, the console will show below error logs:

libinputevents[ERROR]: Mtouch device has inconsistent digit ordering and MTOUCH_FLAGS_INCONSISTENT_DIGIT_ORDER isn’t specified

It means that I need to report the touch point is up (the touch finger leaves the touch screen) despite the touch point isn’t originally active (down/move) for the input digit idx.
Take below case for example,
Frame (N-1): ID 1, 3 and 4 are moving
Frame (N): ID 1 and 3 are moving, ID 4 has leaved
Frame (N+1): ID 1 and 3 are moving

Let’s assumen that the maximum touch poiints are 5 and the correct way to report is as follows.
Frame (N-1): report ID 1, 3 and 4 are valid, additionally report ID 2 and 5 are invalid
Frame (N): report ID 1 and 3 are valid, ID 4 is invalid, additionally report ID 2 and 5 are invalid
Frame (N+1): report ID 1 and 3 are valid, additionally report ID 2, 4 and 5 are invalid

The error logs mentioned above will show if I report in the below way.
Frame (N-1): report ID 1, 3 and 4 are valid
Frame (N): report ID 1 and 3 are valid, ID 4 is invalid
Frame (N+1): report ID 1 and 3 are valid

Does anyone know that the reason I have to report in that way?
Thanks a lot in advance.

I am not sure what the specification is for the callback function is_contact_down() (I can’t find any doc that says what it has to return in the various pointers).

But looking at your code in the ‘else’ clause

	*valid = 0;
	if (message->touch_point[digit_idx].valid) {
		*valid = message->touch_point[digit_idx].status;
		if (ts->verbose >= 5) {
			mtouch_info(NOVATEK_DEVNAME, "%s: DigitIdx = %d is %s, num_touchpoints/%d", __func__, 
					digit_idx, (*valid) ? "Down" : "Up", message->num_touchpoints);
		}
	} else {
		if (ts->verbose >= 7) {
			mtouch_info(NOVATEK_DEVNAME, "%s: No touch with digit_idx %u", __func__, digit_idx);
		}
		return EOK;
	}

This block

	} else {
		if (ts->verbose >= 7) {
			mtouch_info(NOVATEK_DEVNAME, "%s: No touch with digit_idx %u", __func__, digit_idx);
		}
		return EOK;
	}

looks suspicious. You aren’t setting *valid in this block. So the ‘*valid = 0’ you have way above is the only way *valid gets set if this code block gets executed.

More importantly, you are returning EOK in this case. Are you sure you are meant to return EOK here and not -1. That EOK may be making the driver think *valid is set and causes the error when you remove the *valid=0 line.

Tim

Thanks for your comment.
Please let me explain the meaning of message->touch_point[digit_idx].valid and message->touch_point[digit_idx].status first.
The valid means the validity for the touch point of digit index, it will be 1 if there’re any changes for the touch points of digit index (no matter down/move or leave).
The status represents the down/move/up event for the touch point of digit index, it will be 1 in down/move and 0 in up case.

Let’s consider the previous example (max. touch point number is 5 and correct ID range to 0~4):
Frame (N-1): ID 0, 2 and 3 are moving

  • For ID 0: message->touch_point[0].valid = 1, message->touch_point[0].status = 1
  • For ID 1: message->touch_point[1].valid = 0
  • For ID 2: message->touch_point[2].valid = 1, message->touch_point[2].status = 1
  • For ID 3: message->touch_point[3].valid = 1, message->touch_point[3].status = 1
  • For ID 4: message->touch_point[4].valid = 0

Frame (N): ID 0 and 2 are moving, ID 3 has leaved

  • For ID 0: message->touch_point[0].valid = 1, message->touch_point[0].status = 1
  • For ID 1: message->touch_point[1].valid = 0
  • For ID 2: message->touch_point[2].valid = 1, message->touch_point[2].status = 1
  • For ID 3: message->touch_point[3].valid = 1, message->touch_point[3].status = 0
  • For ID 4: message->touch_point[4].valid = 0

Frame (N+1): ID 0 and 2 are moving

  • For ID 0: message->touch_point[0].valid = 1, message->touch_point[0].status = 1
  • For ID 1: message->touch_point[1].valid = 0
  • For ID 2: message->touch_point[2].valid = 1, message->touch_point[2].status = 1
  • For ID 3: message->touch_point[3].valid = 0
  • For ID 4: message->touch_point[4].valid = 0

Initially, I thought I can just take care the case that message->touch_point[digit_idx].valid is 1.
However, as per the test result, it seems that the case that message->touch_point[digit_idx].valid is 0 is also have to be considered.
Actually, “*valid = 0” is outside from if statement or in the else clause are the same logic for different implementations.
What I want to confirm is that if the implementation of is_contact_down follows the formal design?
As you said, I also can’t find related specfications about the implememtation of these callback function in any official documents for now.

As for the returned EOK value in the elase clause, the error log - libinputevents[ERROR]: Multitouch driver callback failed will show if the returned value is -1 in the case.
In addition, users usually don’t want error logs on consoles. That’s why EOK value is returned in the case.