linux-input.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
From: Hans de Goede <hdegoede@redhat.com>
To: Dmitry Torokhov <dmitry.torokhov@gmail.com>
Cc: linux-input@vger.kernel.org, platform-driver-x86@vger.kernel.org
Subject: Re: [PATCH regression fix 1/2] Input: silead - Add support for EFI-embedded fw using different min/max coordinates
Date: Sun, 5 Sep 2021 14:47:20 +0200	[thread overview]
Message-ID: <627a0fc0-61fb-090a-1adc-07ddcf6e2159@redhat.com> (raw)
In-Reply-To: <20210905124547.31567-1-hdegoede@redhat.com>

Hi,

These 2 patches obviously are not regression-fixes, I accidentally
still had a subjectprefix set when sending these, sorry about that.

Other then that these are ready for merging :)

Regards,

Hans


On 9/5/21 2:45 PM, Hans de Goede wrote:
> Unfortunately, at the time of writing this commit message, we have been
> unable to get permission from Silead, or from device OEMs, to distribute
> the necessary Silead firmware files in linux-firmware.
> 
> On a whole bunch of devices the UEFI BIOS code contains a touchscreen
> driver, which contains an embedded copy of the firmware. The fw-loader
> code has a "platform" fallback mechanism, which together with info on the
> firmware from drivers/platform/x86/touchscreen_dmi.c will use the firmware
> from the UEFI driver when the firmware is missing from /lib/firmware. This
> makes the touchscreen work OOTB without users needing to manually download
> the firmware.
> 
> The firmware bundled with the original Windows/Android is usually newer
> then the firmware in the UEFI driver and it is better calibrated. This
> better calibration can lead to significant differences in the reported
> min/max coordinates.
> 
> Add support for a new (optional) "silead,efi-fw-min-max" property which
> provides a set of alternative min/max values to use for the x/y axis when
> the EFI embedded firmware is used.
> 
> The new property is only used on (x86) devices which do not use devicetree,
> IOW it is not used in actual devicetree files. The devicetree-bindings
> maintainers have requested properties like these to not be added to the
> devicetree-bindings, so the new property is deliberately not added to the
> existing silead devicetree-bindings documentation.
> 
> Signed-off-by: Hans de Goede <hdegoede@redhat.com>
> ---
>  drivers/input/touchscreen/silead.c | 73 ++++++++++++++++++++++++++++--
>  1 file changed, 68 insertions(+), 5 deletions(-)
> 
> diff --git a/drivers/input/touchscreen/silead.c b/drivers/input/touchscreen/silead.c
> index 1ee760bac0cf..caa25af53e6e 100644
> --- a/drivers/input/touchscreen/silead.c
> +++ b/drivers/input/touchscreen/silead.c
> @@ -75,6 +75,8 @@ struct silead_ts_data {
>  	struct input_mt_pos pos[SILEAD_MAX_FINGERS];
>  	int slots[SILEAD_MAX_FINGERS];
>  	int id[SILEAD_MAX_FINGERS];
> +	u32 efi_fw_min_max[4];
> +	bool efi_fw_min_max_set;
>  };
>  
>  struct silead_fw_data {
> @@ -82,6 +84,35 @@ struct silead_fw_data {
>  	u32 val;
>  };
>  
> +static void silead_apply_efi_fw_min_max(struct silead_ts_data *data)
> +{
> +	struct input_absinfo *absinfo_x = &data->input->absinfo[ABS_MT_POSITION_X];
> +	struct input_absinfo *absinfo_y = &data->input->absinfo[ABS_MT_POSITION_Y];
> +
> +	if (!data->efi_fw_min_max_set)
> +		return;
> +
> +	absinfo_x->minimum = data->efi_fw_min_max[0];
> +	absinfo_x->maximum = data->efi_fw_min_max[1];
> +	absinfo_y->minimum = data->efi_fw_min_max[2];
> +	absinfo_y->maximum = data->efi_fw_min_max[3];
> +
> +	if (data->prop.invert_x) {
> +		absinfo_x->maximum -= absinfo_x->minimum;
> +		absinfo_x->minimum = 0;
> +	}
> +
> +	if (data->prop.invert_y) {
> +		absinfo_y->maximum -= absinfo_y->minimum;
> +		absinfo_y->minimum = 0;
> +	}
> +
> +	if (data->prop.swap_x_y) {
> +		swap(absinfo_x->minimum, absinfo_y->minimum);
> +		swap(absinfo_x->maximum, absinfo_y->maximum);
> +	}
> +}
> +
>  static int silead_ts_request_input_dev(struct silead_ts_data *data)
>  {
>  	struct device *dev = &data->client->dev;
> @@ -97,6 +128,7 @@ static int silead_ts_request_input_dev(struct silead_ts_data *data)
>  	input_set_abs_params(data->input, ABS_MT_POSITION_X, 0, 4095, 0, 0);
>  	input_set_abs_params(data->input, ABS_MT_POSITION_Y, 0, 4095, 0, 0);
>  	touchscreen_parse_properties(data->input, true, &data->prop);
> +	silead_apply_efi_fw_min_max(data);
>  
>  	input_mt_init_slots(data->input, data->max_fingers,
>  			    INPUT_MT_DIRECT | INPUT_MT_DROP_UNUSED |
> @@ -282,17 +314,48 @@ static int silead_ts_load_fw(struct i2c_client *client)
>  {
>  	struct device *dev = &client->dev;
>  	struct silead_ts_data *data = i2c_get_clientdata(client);
> -	unsigned int fw_size, i;
> -	const struct firmware *fw;
> +	const struct firmware *fw = NULL;
>  	struct silead_fw_data *fw_data;
> +	unsigned int fw_size, i;
>  	int error;
>  
>  	dev_dbg(dev, "Firmware file name: %s", data->fw_name);
>  
> -	error = firmware_request_platform(&fw, data->fw_name, dev);
> +	/*
> +	 * Unfortunately, at the time of writing this comment, we have been unable to
> +	 * get permission from Silead, or from device OEMs, to distribute the necessary
> +	 * Silead firmware files in linux-firmware.
> +	 *
> +	 * On a whole bunch of devices the UEFI BIOS code contains a touchscreen driver,
> +	 * which contains an embedded copy of the firmware. The fw-loader code has a
> +	 * "platform" fallback mechanism, which together with info on the firmware
> +	 * from drivers/platform/x86/touchscreen_dmi.c will use the firmware from the
> +	 * UEFI driver when the firmware is missing from /lib/firmware. This makes the
> +	 * touchscreen work OOTB without users needing to manually download the firmware.
> +	 *
> +	 * The firmware bundled with the original Windows/Android is usually newer then
> +	 * the firmware in the UEFI driver and it is better calibrated. This better
> +	 * calibration can lead to significant differences in the reported min/max
> +	 * coordinates.
> +	 *
> +	 * To deal with this we first try to load the firmware without "platform"
> +	 * fallback. If that fails we retry with "platform" fallback and if that
> +	 * succeeds we apply an (optional) set of alternative min/max values from the
> +	 * "silead,efi-fw-min-max" property.
> +	 */
> +	error = firmware_request_nowarn(&fw, data->fw_name, dev);
>  	if (error) {
> -		dev_err(dev, "Firmware request error %d\n", error);
> -		return error;
> +		error = firmware_request_platform(&fw, data->fw_name, dev);
> +		if (error) {
> +			dev_err(dev, "Firmware request error %d\n", error);
> +			return error;
> +		}
> +
> +		error = device_property_read_u32_array(dev, "silead,efi-fw-min-max",
> +						       data->efi_fw_min_max,
> +						       ARRAY_SIZE(data->efi_fw_min_max));
> +		if (!error)
> +			data->efi_fw_min_max_set = true;
>  	}
>  
>  	fw_size = fw->size / sizeof(*fw_data);
> 


      parent reply	other threads:[~2021-09-05 12:47 UTC|newest]

Thread overview: 3+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2021-09-05 12:45 [PATCH regression fix 1/2] Input: silead - Add support for EFI-embedded fw using different min/max coordinates Hans de Goede
2021-09-05 12:45 ` [PATCH regression fix 2/2] Input: silead - Add pen support Hans de Goede
2021-09-05 12:47 ` Hans de Goede [this message]

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=627a0fc0-61fb-090a-1adc-07ddcf6e2159@redhat.com \
    --to=hdegoede@redhat.com \
    --cc=dmitry.torokhov@gmail.com \
    --cc=linux-input@vger.kernel.org \
    --cc=platform-driver-x86@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).