All of lore.kernel.org
 help / color / mirror / Atom feed
From: Bernd Edlinger <bernd.edlinger@hotmail.de>
To: Dmitry Torokhov <dmitry.torokhov@gmail.com>,
	"Gustavo A. R. Silva" <gustavoars@kernel.org>,
	Colin Ian King <colin.king@canonical.com>,
	"jingle.wu" <jingle.wu@emc.com.tw>,
	Lee Jones <lee.jones@linaro.org>,
	Benjamin Tissoires <benjamin.tissoires@redhat.com>,
	"linux-input@vger.kernel.org" <linux-input@vger.kernel.org>,
	"linux-kernel@vger.kernel.org" <linux-kernel@vger.kernel.org>
Subject: Re: [PATCH v3] Input: elantech - fix x_max/y_max values
Date: Sun, 6 Jun 2021 08:44:01 +0200	[thread overview]
Message-ID: <AM8PR10MB4708B71F7479A2F6EDB8F010E4399@AM8PR10MB4708.EURPRD10.PROD.OUTLOOK.COM> (raw)
In-Reply-To: <AM8PR10MB47082E49F8A2DC4B9B522023E4209@AM8PR10MB4708.EURPRD10.PROD.OUTLOOK.COM>

Ping...

On 5/30/21 6:35 AM, Bernd Edlinger wrote:
> Since commit 37548659bb22 ("Input: elantech - query the min/max information beforehand too")
> moved the querying of the x_max/y_max values from
> elantech_set_input_params to elantech_query_info,
> the returned x_max/y_max values are different than before,
> at least for some firmware versions.
> 
> The reason is likely that this is now done before
> elantech_set_absolute_mode does run.  So it may happen that
> the returned values are exactly half of what they used to be,
> which makes input_report_abs in PS/2 mode report ABS_X values which
> exceed the x_max value, which is very annoying since the mouse stops
> to move then, and ABS_Y value become negative, which is benign.
> 
> This was observed with a MSI GX70 laptop:
> 
> elantech: assuming hardware version 3 (with firmware version 0x250f01)
> elantech: Synaptics capabilities query result 0x18, 0x17, 0x0b.
> elantech: Elan sample query result 05, 0e, 00
> input: ETPS/2 Elantech Touchpad as /devices/platform/i8042/serio...
> 
> This patch moves the code sending the ETP_FW_ID_QUERY command to
> the function elantech_set_range and calls this function in
> elantech_query_info for hw_version == 4, but for hw_version < 4 it is
> called in elantech_setup_ps2 after the function elantech_set_absolute_mode.
> 
> It is right to switch the touchpad into absolute mode first to get valid
> results from the ID query call in hardware version 2 and 3.
> 
> There is no way how this change can affect the state of the firmware
> when elantech_setup_smbus is called later, since that can only happen for
> hardware version 4, see elantech_init_smbusand elantech_use_host_notify
> which uses ETP_NEW_IC_SMBUS_HOST_NOTIFY and info->bus.
> 
> The macro ETP_NEW_IC_SMBUS_HOST_NOTIFY can only return true
> for (fw_version & 0x0f0000) == 0x0f0000 which implies v4 hardware.
> The value info->bus can only be unequal to ETP_BUS_PS2_ONLY,
> if elantech_get_resolution_v4 was called from elantech_query_info,
> which is again guarded by info->hw_version == 4.
> 
> Fixes: 37548659bb22 ("Input: elantech - query the min/max information beforehand too")
> 
> Signed-off-by: Bernd Edlinger <bernd.edlinger@hotmail.de>
> ---
> v3: Do the ID_QUEERY after set absoulute mode for hw_version < 4.
>     Note: It turned out to be more difficult to call elantech_set_absolute_mode
>     from elantech_query_info.
> 
>  drivers/input/mouse/elantech.c | 172 ++++++++++++++++++++++-------------------
>  1 file changed, 94 insertions(+), 78 deletions(-)
> 
> diff --git a/drivers/input/mouse/elantech.c b/drivers/input/mouse/elantech.c
> index 97381e2..5f4a1a4 100644
> --- a/drivers/input/mouse/elantech.c
> +++ b/drivers/input/mouse/elantech.c
> @@ -1078,6 +1078,94 @@ static int elantech_set_absolute_mode(struct psmouse *psmouse)
>  	return rc;
>  }
>  
> +static int elantech_set_range(struct psmouse *psmouse,
> +			      struct elantech_device_info *info)
> +{
> +	unsigned char param[3];
> +	unsigned char traces;
> +
> +	/* query range information */
> +	switch (info->hw_version) {
> +	case 1:
> +		info->x_min = ETP_XMIN_V1;
> +		info->y_min = ETP_YMIN_V1;
> +		info->x_max = ETP_XMAX_V1;
> +		info->y_max = ETP_YMAX_V1;
> +		break;
> +
> +	case 2:
> +		if (info->fw_version == 0x020800 ||
> +		    info->fw_version == 0x020b00 ||
> +		    info->fw_version == 0x020030) {
> +			info->x_min = ETP_XMIN_V2;
> +			info->y_min = ETP_YMIN_V2;
> +			info->x_max = ETP_XMAX_V2;
> +			info->y_max = ETP_YMAX_V2;
> +		} else {
> +			int i;
> +			int fixed_dpi;
> +
> +			i = (info->fw_version > 0x020800 &&
> +			     info->fw_version < 0x020900) ? 1 : 2;
> +
> +			if (info->send_cmd(psmouse, ETP_FW_ID_QUERY, param))
> +				return -EINVAL;
> +
> +			fixed_dpi = param[1] & 0x10;
> +
> +			if (((info->fw_version >> 16) == 0x14) && fixed_dpi) {
> +				if (info->send_cmd(psmouse, ETP_SAMPLE_QUERY, param))
> +					return -EINVAL;
> +
> +				info->x_max = (info->capabilities[1] - i) * param[1] / 2;
> +				info->y_max = (info->capabilities[2] - i) * param[2] / 2;
> +			} else if (info->fw_version == 0x040216) {
> +				info->x_max = 819;
> +				info->y_max = 405;
> +			} else if (info->fw_version == 0x040219 || info->fw_version == 0x040215) {
> +				info->x_max = 900;
> +				info->y_max = 500;
> +			} else {
> +				info->x_max = (info->capabilities[1] - i) * 64;
> +				info->y_max = (info->capabilities[2] - i) * 64;
> +			}
> +		}
> +		break;
> +
> +	case 3:
> +		if (info->send_cmd(psmouse, ETP_FW_ID_QUERY, param))
> +			return -EINVAL;
> +
> +		info->x_max = (0x0f & param[0]) << 8 | param[1];
> +		info->y_max = (0xf0 & param[0]) << 4 | param[2];
> +		break;
> +
> +	case 4:
> +		if (info->send_cmd(psmouse, ETP_FW_ID_QUERY, param))
> +			return -EINVAL;
> +
> +		info->x_max = (0x0f & param[0]) << 8 | param[1];
> +		info->y_max = (0xf0 & param[0]) << 4 | param[2];
> +		traces = info->capabilities[1];
> +		if ((traces < 2) || (traces > info->x_max))
> +			return -EINVAL;
> +
> +		info->width = info->x_max / (traces - 1);
> +
> +		/* column number of traces */
> +		info->x_traces = traces;
> +
> +		/* row number of traces */
> +		traces = info->capabilities[2];
> +		if ((traces >= 2) && (traces <= info->y_max))
> +			info->y_traces = traces;
> +
> +		break;
> +	}
> +
> +	return 0;
> +}
> +
>  /*
>   * (value from firmware) * 10 + 790 = dpi
>   * we also have to convert dpi to dots/mm (*10/254 to avoid floating point)
> @@ -1659,7 +1747,6 @@ static int elantech_query_info(struct psmouse *psmouse,
>  			       struct elantech_device_info *info)
>  {
>  	unsigned char param[3];
> -	unsigned char traces;
>  	unsigned char ic_body[3];
>  
>  	memset(info, 0, sizeof(*info));
> @@ -1759,85 +1846,9 @@ static int elantech_query_info(struct psmouse *psmouse,
>  			psmouse_warn(psmouse,
>  				     "failed to query resolution data.\n");
>  		}
> -	}
> -
> -	/* query range information */
> -	switch (info->hw_version) {
> -	case 1:
> -		info->x_min = ETP_XMIN_V1;
> -		info->y_min = ETP_YMIN_V1;
> -		info->x_max = ETP_XMAX_V1;
> -		info->y_max = ETP_YMAX_V1;
> -		break;
> -
> -	case 2:
> -		if (info->fw_version == 0x020800 ||
> -		    info->fw_version == 0x020b00 ||
> -		    info->fw_version == 0x020030) {
> -			info->x_min = ETP_XMIN_V2;
> -			info->y_min = ETP_YMIN_V2;
> -			info->x_max = ETP_XMAX_V2;
> -			info->y_max = ETP_YMAX_V2;
> -		} else {
> -			int i;
> -			int fixed_dpi;
> -
> -			i = (info->fw_version > 0x020800 &&
> -			     info->fw_version < 0x020900) ? 1 : 2;
> -
> -			if (info->send_cmd(psmouse, ETP_FW_ID_QUERY, param))
> -				return -EINVAL;
>  
> -			fixed_dpi = param[1] & 0x10;
> -
> -			if (((info->fw_version >> 16) == 0x14) && fixed_dpi) {
> -				if (info->send_cmd(psmouse, ETP_SAMPLE_QUERY, param))
> -					return -EINVAL;
> -
> -				info->x_max = (info->capabilities[1] - i) * param[1] / 2;
> -				info->y_max = (info->capabilities[2] - i) * param[2] / 2;
> -			} else if (info->fw_version == 0x040216) {
> -				info->x_max = 819;
> -				info->y_max = 405;
> -			} else if (info->fw_version == 0x040219 || info->fw_version == 0x040215) {
> -				info->x_max = 900;
> -				info->y_max = 500;
> -			} else {
> -				info->x_max = (info->capabilities[1] - i) * 64;
> -				info->y_max = (info->capabilities[2] - i) * 64;
> -			}
> -		}
> -		break;
> -
> -	case 3:
> -		if (info->send_cmd(psmouse, ETP_FW_ID_QUERY, param))
> -			return -EINVAL;
> -
> -		info->x_max = (0x0f & param[0]) << 8 | param[1];
> -		info->y_max = (0xf0 & param[0]) << 4 | param[2];
> -		break;
> -
> -	case 4:
> -		if (info->send_cmd(psmouse, ETP_FW_ID_QUERY, param))
> +		if (elantech_set_range(psmouse, info))
>  			return -EINVAL;
> -
> -		info->x_max = (0x0f & param[0]) << 8 | param[1];
> -		info->y_max = (0xf0 & param[0]) << 4 | param[2];
> -		traces = info->capabilities[1];
> -		if ((traces < 2) || (traces > info->x_max))
> -			return -EINVAL;
> -
> -		info->width = info->x_max / (traces - 1);
> -
> -		/* column number of traces */
> -		info->x_traces = traces;
> -
> -		/* row number of traces */
> -		traces = info->capabilities[2];
> -		if ((traces >= 2) && (traces <= info->y_max))
> -			info->y_traces = traces;
> -
> -		break;
>  	}
>  
>  	/* check for the middle button: DMI matching or new v4 firmwares */
> @@ -2037,6 +2048,11 @@ static int elantech_setup_ps2(struct psmouse *psmouse,
>  		goto init_fail;
>  	}
>  
> +	if (info->hw_version < 4) {
> +		if (elantech_set_range(psmouse, &etd->info))
> +			goto init_fail;
> +	}
> +
>  	if (info->fw_version == 0x381f17) {
>  		etd->original_set_rate = psmouse->set_rate;
>  		psmouse->set_rate = elantech_set_rate_restore_reg_07;
> 

  reply	other threads:[~2021-06-06  6:44 UTC|newest]

Thread overview: 3+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2021-05-30  4:35 [PATCH v3] Input: elantech - fix x_max/y_max values Bernd Edlinger
2021-06-06  6:44 ` Bernd Edlinger [this message]
2021-07-08  7:04   ` [PING] " Bernd Edlinger

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=AM8PR10MB4708B71F7479A2F6EDB8F010E4399@AM8PR10MB4708.EURPRD10.PROD.OUTLOOK.COM \
    --to=bernd.edlinger@hotmail.de \
    --cc=benjamin.tissoires@redhat.com \
    --cc=colin.king@canonical.com \
    --cc=dmitry.torokhov@gmail.com \
    --cc=gustavoars@kernel.org \
    --cc=jingle.wu@emc.com.tw \
    --cc=lee.jones@linaro.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 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.