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);
>
prev 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).