From: Sasha Levin <sashal@kernel.org>
To: linux-kernel@vger.kernel.org, stable@vger.kernel.org
Cc: Allen Ballway <ballway@chromium.org>,
Jiri Kosina <jkosina@suse.cz>, Sasha Levin <sashal@kernel.org>,
jikos@kernel.org, benjamin.tissoires@redhat.com,
alistair@alistair23.me, groeck@chromium.org,
dmitry.torokhov@gmail.com, peter.senna@gmail.com,
Jonathan.Cameron@huawei.com, olteanv@gmail.com,
cminyard@mvista.com, khalasa@piap.pl,
u.kleine-koenig@pengutronix.de, linux-input@vger.kernel.org
Subject: [PATCH AUTOSEL 6.2 23/60] HID: multitouch: Add quirks for flipped axes
Date: Sun, 26 Feb 2023 21:00:08 -0500 [thread overview]
Message-ID: <20230227020045.1045105-23-sashal@kernel.org> (raw)
In-Reply-To: <20230227020045.1045105-1-sashal@kernel.org>
From: Allen Ballway <ballway@chromium.org>
[ Upstream commit a2f416bf062a38bb76cccd526d2d286b8e4db4d9 ]
Certain touchscreen devices, such as the ELAN9034, are oriented
incorrectly and report touches on opposite points on the X and Y axes.
For example, a 100x200 screen touched at (10,20) would report (90, 180)
and vice versa.
This is fixed by adding device quirks to transform the touch points
into the correct spaces, from X -> MAX(X) - X, and Y -> MAX(Y) - Y.
Signed-off-by: Allen Ballway <ballway@chromium.org>
Signed-off-by: Jiri Kosina <jkosina@suse.cz>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/hid/hid-multitouch.c | 39 ++++++++++++++++++---
drivers/hid/hid-quirks.c | 6 ++++
drivers/hid/i2c-hid/i2c-hid-dmi-quirks.c | 43 ++++++++++++++++++++++++
drivers/hid/i2c-hid/i2c-hid.h | 3 ++
4 files changed, 87 insertions(+), 4 deletions(-)
diff --git a/drivers/hid/hid-multitouch.c b/drivers/hid/hid-multitouch.c
index 372cbdd223e09..e31be0cb8b850 100644
--- a/drivers/hid/hid-multitouch.c
+++ b/drivers/hid/hid-multitouch.c
@@ -71,6 +71,7 @@ MODULE_LICENSE("GPL");
#define MT_QUIRK_SEPARATE_APP_REPORT BIT(19)
#define MT_QUIRK_FORCE_MULTI_INPUT BIT(20)
#define MT_QUIRK_DISABLE_WAKEUP BIT(21)
+#define MT_QUIRK_ORIENTATION_INVERT BIT(22)
#define MT_INPUTMODE_TOUCHSCREEN 0x02
#define MT_INPUTMODE_TOUCHPAD 0x03
@@ -1009,6 +1010,7 @@ static int mt_process_slot(struct mt_device *td, struct input_dev *input,
struct mt_usages *slot)
{
struct input_mt *mt = input->mt;
+ struct hid_device *hdev = td->hdev;
__s32 quirks = app->quirks;
bool valid = true;
bool confidence_state = true;
@@ -1086,6 +1088,10 @@ static int mt_process_slot(struct mt_device *td, struct input_dev *input,
int orientation = wide;
int max_azimuth;
int azimuth;
+ int x;
+ int y;
+ int cx;
+ int cy;
if (slot->a != DEFAULT_ZERO) {
/*
@@ -1104,6 +1110,9 @@ static int mt_process_slot(struct mt_device *td, struct input_dev *input,
if (azimuth > max_azimuth * 2)
azimuth -= max_azimuth * 4;
orientation = -azimuth;
+ if (quirks & MT_QUIRK_ORIENTATION_INVERT)
+ orientation = -orientation;
+
}
if (quirks & MT_QUIRK_TOUCH_SIZE_SCALING) {
@@ -1115,10 +1124,23 @@ static int mt_process_slot(struct mt_device *td, struct input_dev *input,
minor = minor >> 1;
}
- input_event(input, EV_ABS, ABS_MT_POSITION_X, *slot->x);
- input_event(input, EV_ABS, ABS_MT_POSITION_Y, *slot->y);
- input_event(input, EV_ABS, ABS_MT_TOOL_X, *slot->cx);
- input_event(input, EV_ABS, ABS_MT_TOOL_Y, *slot->cy);
+ x = hdev->quirks & HID_QUIRK_X_INVERT ?
+ input_abs_get_max(input, ABS_MT_POSITION_X) - *slot->x :
+ *slot->x;
+ y = hdev->quirks & HID_QUIRK_Y_INVERT ?
+ input_abs_get_max(input, ABS_MT_POSITION_Y) - *slot->y :
+ *slot->y;
+ cx = hdev->quirks & HID_QUIRK_X_INVERT ?
+ input_abs_get_max(input, ABS_MT_POSITION_X) - *slot->cx :
+ *slot->cx;
+ cy = hdev->quirks & HID_QUIRK_Y_INVERT ?
+ input_abs_get_max(input, ABS_MT_POSITION_Y) - *slot->cy :
+ *slot->cy;
+
+ input_event(input, EV_ABS, ABS_MT_POSITION_X, x);
+ input_event(input, EV_ABS, ABS_MT_POSITION_Y, y);
+ input_event(input, EV_ABS, ABS_MT_TOOL_X, cx);
+ input_event(input, EV_ABS, ABS_MT_TOOL_Y, cy);
input_event(input, EV_ABS, ABS_MT_DISTANCE, !*slot->tip_state);
input_event(input, EV_ABS, ABS_MT_ORIENTATION, orientation);
input_event(input, EV_ABS, ABS_MT_PRESSURE, *slot->p);
@@ -1735,6 +1757,15 @@ static int mt_probe(struct hid_device *hdev, const struct hid_device_id *id)
if (id->vendor == HID_ANY_ID && id->product == HID_ANY_ID)
td->serial_maybe = true;
+
+ /* Orientation is inverted if the X or Y axes are
+ * flipped, but normalized if both are inverted.
+ */
+ if (hdev->quirks & (HID_QUIRK_X_INVERT | HID_QUIRK_Y_INVERT) &&
+ !((hdev->quirks & HID_QUIRK_X_INVERT)
+ && (hdev->quirks & HID_QUIRK_Y_INVERT)))
+ td->mtclass.quirks = MT_QUIRK_ORIENTATION_INVERT;
+
/* This allows the driver to correctly support devices
* that emit events over several HID messages.
*/
diff --git a/drivers/hid/hid-quirks.c b/drivers/hid/hid-quirks.c
index 5bc91f68b3747..30e35f79def47 100644
--- a/drivers/hid/hid-quirks.c
+++ b/drivers/hid/hid-quirks.c
@@ -19,6 +19,7 @@
#include <linux/input/elan-i2c-ids.h>
#include "hid-ids.h"
+#include "i2c-hid/i2c-hid.h"
/*
* Alphabetically sorted by vendor then product.
@@ -1298,6 +1299,11 @@ unsigned long hid_lookup_quirk(const struct hid_device *hdev)
quirks = hid_gets_squirk(hdev);
mutex_unlock(&dquirks_lock);
+ /* Get quirks specific to I2C devices */
+ if (IS_ENABLED(CONFIG_I2C_DMI_CORE) && IS_ENABLED(CONFIG_DMI) &&
+ hdev->bus == BUS_I2C)
+ quirks |= i2c_hid_get_dmi_quirks(hdev->vendor, hdev->product);
+
return quirks;
}
EXPORT_SYMBOL_GPL(hid_lookup_quirk);
diff --git a/drivers/hid/i2c-hid/i2c-hid-dmi-quirks.c b/drivers/hid/i2c-hid/i2c-hid-dmi-quirks.c
index 8e0f67455c098..554a7dc285365 100644
--- a/drivers/hid/i2c-hid/i2c-hid-dmi-quirks.c
+++ b/drivers/hid/i2c-hid/i2c-hid-dmi-quirks.c
@@ -10,8 +10,10 @@
#include <linux/types.h>
#include <linux/dmi.h>
#include <linux/mod_devicetable.h>
+#include <linux/hid.h>
#include "i2c-hid.h"
+#include "../hid-ids.h"
struct i2c_hid_desc_override {
@@ -416,6 +418,28 @@ static const struct dmi_system_id i2c_hid_dmi_desc_override_table[] = {
{ } /* Terminate list */
};
+static const struct hid_device_id i2c_hid_elan_flipped_quirks = {
+ HID_DEVICE(BUS_I2C, HID_GROUP_MULTITOUCH_WIN_8, USB_VENDOR_ID_ELAN, 0x2dcd),
+ HID_QUIRK_X_INVERT | HID_QUIRK_Y_INVERT
+};
+
+/*
+ * This list contains devices which have specific issues based on the system
+ * they're on and not just the device itself. The driver_data will have a
+ * specific hid device to match against.
+ */
+static const struct dmi_system_id i2c_hid_dmi_quirk_table[] = {
+ {
+ .ident = "DynaBook K50/FR",
+ .matches = {
+ DMI_EXACT_MATCH(DMI_SYS_VENDOR, "Dynabook Inc."),
+ DMI_EXACT_MATCH(DMI_PRODUCT_NAME, "dynabook K50/FR"),
+ },
+ .driver_data = (void *)&i2c_hid_elan_flipped_quirks,
+ },
+ { } /* Terminate list */
+};
+
struct i2c_hid_desc *i2c_hid_get_dmi_i2c_hid_desc_override(uint8_t *i2c_name)
{
@@ -450,3 +474,22 @@ char *i2c_hid_get_dmi_hid_report_desc_override(uint8_t *i2c_name,
*size = override->hid_report_desc_size;
return override->hid_report_desc;
}
+
+u32 i2c_hid_get_dmi_quirks(const u16 vendor, const u16 product)
+{
+ u32 quirks = 0;
+ const struct dmi_system_id *system_id =
+ dmi_first_match(i2c_hid_dmi_quirk_table);
+
+ if (system_id) {
+ const struct hid_device_id *device_id =
+ (struct hid_device_id *)(system_id->driver_data);
+
+ if (device_id && device_id->vendor == vendor &&
+ device_id->product == product)
+ quirks = device_id->driver_data;
+ }
+
+ return quirks;
+}
+EXPORT_SYMBOL_GPL(i2c_hid_get_dmi_quirks);
diff --git a/drivers/hid/i2c-hid/i2c-hid.h b/drivers/hid/i2c-hid/i2c-hid.h
index 96c75510ad3f1..2c7b66d5caa0f 100644
--- a/drivers/hid/i2c-hid/i2c-hid.h
+++ b/drivers/hid/i2c-hid/i2c-hid.h
@@ -9,6 +9,7 @@
struct i2c_hid_desc *i2c_hid_get_dmi_i2c_hid_desc_override(uint8_t *i2c_name);
char *i2c_hid_get_dmi_hid_report_desc_override(uint8_t *i2c_name,
unsigned int *size);
+u32 i2c_hid_get_dmi_quirks(const u16 vendor, const u16 product);
#else
static inline struct i2c_hid_desc
*i2c_hid_get_dmi_i2c_hid_desc_override(uint8_t *i2c_name)
@@ -16,6 +17,8 @@ static inline struct i2c_hid_desc
static inline char *i2c_hid_get_dmi_hid_report_desc_override(uint8_t *i2c_name,
unsigned int *size)
{ return NULL; }
+static inline u32 i2c_hid_get_dmi_quirks(const u16 vendor, const u16 product)
+{ return 0; }
#endif
/**
--
2.39.0
next prev parent reply other threads:[~2023-02-27 2:04 UTC|newest]
Thread overview: 62+ messages / expand[flat|nested] mbox.gz Atom feed top
2023-02-27 1:59 [PATCH AUTOSEL 6.2 01/60] drm: panel-orientation-quirks: Add quirk for Lenovo Yoga Tab 3 X90F Sasha Levin
2023-02-27 1:59 ` [PATCH AUTOSEL 6.2 02/60] drm: panel-orientation-quirks: Add quirk for DynaBook K50 Sasha Levin
2023-02-27 1:59 ` [PATCH AUTOSEL 6.2 03/60] drm/amd/display: Reduce expected sdp bandwidth for dcn321 Sasha Levin
2023-02-27 1:59 ` [PATCH AUTOSEL 6.2 04/60] drm/amd/display: Revert Reduce delay when sink device not able to ACK 00340h write Sasha Levin
2023-02-27 1:59 ` [PATCH AUTOSEL 6.2 05/60] drm/amd/display: Fix potential null-deref in dm_resume Sasha Levin
2023-02-27 1:59 ` [PATCH AUTOSEL 6.2 06/60] drm/omap: dsi: Fix excessive stack usage Sasha Levin
2023-02-27 1:59 ` [PATCH AUTOSEL 6.2 07/60] HID: Add Mapping for System Microphone Mute Sasha Levin
2023-02-27 1:59 ` [PATCH AUTOSEL 6.2 08/60] drm/tiny: ili9486: Do not assume 8-bit only SPI controllers Sasha Levin
2023-02-27 1:59 ` [PATCH AUTOSEL 6.2 09/60] drm/amd/display: Defer DIG FIFO disable after VID stream enable Sasha Levin
2023-02-27 1:59 ` [PATCH AUTOSEL 6.2 10/60] drm/radeon: free iio for atombios when driver shutdown Sasha Levin
2023-02-27 1:59 ` [PATCH AUTOSEL 6.2 11/60] drm/amd: Avoid BUG() for case of SRIOV missing IP version Sasha Levin
2023-02-27 1:59 ` [PATCH AUTOSEL 6.2 12/60] drm/amdkfd: Page aligned memory reserve size Sasha Levin
2023-02-27 1:59 ` [PATCH AUTOSEL 6.2 13/60] scsi: lpfc: Fix use-after-free KFENCE violation during sysfs firmware write Sasha Levin
2023-02-27 1:59 ` [PATCH AUTOSEL 6.2 14/60] Revert "fbcon: don't lose the console font across generic->chip driver switch" Sasha Levin
2023-02-27 2:00 ` [PATCH AUTOSEL 6.2 15/60] drm/amd: Avoid ASSERT for some message failures Sasha Levin
2023-02-27 2:00 ` [PATCH AUTOSEL 6.2 16/60] drm: amd: display: Fix memory leakage Sasha Levin
2023-02-27 2:00 ` [PATCH AUTOSEL 6.2 17/60] drm/amd/display: fix mapping to non-allocated address Sasha Levin
2023-02-27 2:00 ` [PATCH AUTOSEL 6.2 18/60] drm/msm/dp: Remove INIT_SETUP delay Sasha Levin
2023-02-27 9:12 ` Johan Hovold
2023-03-01 14:15 ` Sasha Levin
2023-02-27 2:00 ` [PATCH AUTOSEL 6.2 19/60] HID: uclogic: Add frame type quirk Sasha Levin
2023-02-27 2:00 ` [PATCH AUTOSEL 6.2 20/60] HID: uclogic: Add battery quirk Sasha Levin
2023-02-27 2:00 ` [PATCH AUTOSEL 6.2 21/60] HID: uclogic: Add support for XP-PEN Deco Pro SW Sasha Levin
2023-02-27 2:00 ` [PATCH AUTOSEL 6.2 22/60] HID: uclogic: Add support for XP-PEN Deco Pro MW Sasha Levin
2023-02-27 2:00 ` Sasha Levin [this message]
2023-02-27 2:00 ` [PATCH AUTOSEL 6.2 24/60] drm/msm/dsi: Add missing check for alloc_ordered_workqueue Sasha Levin
2023-02-27 2:00 ` [PATCH AUTOSEL 6.2 25/60] drm: rcar-du: Add quirk for H3 ES1.x pclk workaround Sasha Levin
2023-02-27 2:00 ` [PATCH AUTOSEL 6.2 26/60] drm: rcar-du: Fix setting a reserved bit in DPLLCR Sasha Levin
2023-02-27 2:00 ` [PATCH AUTOSEL 6.2 27/60] drm/drm_print: correct format problem Sasha Levin
2023-02-27 2:00 ` [PATCH AUTOSEL 6.2 28/60] drm/amd/display: Set hvm_enabled flag for S/G mode Sasha Levin
2023-02-27 2:00 ` [PATCH AUTOSEL 6.2 29/60] drm/client: Test for connectors before sending hotplug event Sasha Levin
2023-02-27 2:00 ` [PATCH AUTOSEL 6.2 30/60] habanalabs: extend fatal messages to contain PCI info Sasha Levin
2023-02-27 2:00 ` [PATCH AUTOSEL 6.2 31/60] habanalabs: fix bug in timestamps registration code Sasha Levin
2023-02-27 2:00 ` [PATCH AUTOSEL 6.2 32/60] docs/scripts/gdb: add necessary make scripts_gdb step Sasha Levin
2023-02-27 2:00 ` [PATCH AUTOSEL 6.2 33/60] drm/msm/dpu: Add DSC hardware blocks to register snapshot Sasha Levin
2023-02-27 2:00 ` [PATCH AUTOSEL 6.2 34/60] ASoC: soc-compress: Reposition and add pcm_mutex Sasha Levin
2023-02-27 2:00 ` [PATCH AUTOSEL 6.2 35/60] ASoC: kirkwood: Iterate over array indexes instead of using pointer math Sasha Levin
2023-02-27 2:00 ` [PATCH AUTOSEL 6.2 36/60] regulator: max77802: Bounds check regulator id against opmode Sasha Levin
2023-02-27 2:00 ` [PATCH AUTOSEL 6.2 37/60] regulator: s5m8767: Bounds check id indexing into arrays Sasha Levin
2023-02-27 2:00 ` [PATCH AUTOSEL 6.2 38/60] Revert "drm/amdgpu: TA unload messages are not actually sent to psp when amdgpu is uninstalled" Sasha Levin
2023-02-27 2:00 ` [PATCH AUTOSEL 6.2 39/60] drm/amd/display: fix FCLK pstate change underflow Sasha Levin
2023-02-27 2:00 ` [PATCH AUTOSEL 6.2 40/60] gfs2: Improve gfs2_make_fs_rw error handling Sasha Levin
2023-02-27 2:00 ` [PATCH AUTOSEL 6.2 41/60] hwmon: (coretemp) Simplify platform device handling Sasha Levin
2023-02-27 2:00 ` [PATCH AUTOSEL 6.2 42/60] hwmon: (nct6775) Directly call ASUS ACPI WMI method Sasha Levin
2023-02-27 2:00 ` [PATCH AUTOSEL 6.2 43/60] hwmon: (nct6775) B650/B660/X670 ASUS boards support Sasha Levin
2023-02-27 2:00 ` [PATCH AUTOSEL 6.2 44/60] pinctrl: at91: use devm_kasprintf() to avoid potential leaks Sasha Levin
2023-02-27 2:00 ` [PATCH AUTOSEL 6.2 45/60] drm/amd/display: Do not set DRR on pipe commit Sasha Levin
2023-02-27 2:00 ` [PATCH AUTOSEL 6.2 46/60] drm/amd/display: Do not commit pipe when updating DRR Sasha Levin
2023-02-27 2:00 ` [PATCH AUTOSEL 6.2 47/60] scsi: snic: Fix memory leak with using debugfs_lookup() Sasha Levin
2023-02-27 2:00 ` [PATCH AUTOSEL 6.2 48/60] scsi: ufs: core: Fix device management cmd timeout flow Sasha Levin
2023-02-27 2:00 ` [PATCH AUTOSEL 6.2 49/60] HID: logitech-hidpp: Don't restart communication if not necessary Sasha Levin
2023-02-27 2:00 ` [PATCH AUTOSEL 6.2 50/60] drm/amd/display: Move DCN314 DOMAIN power control to DMCUB Sasha Levin
2023-02-27 2:00 ` [PATCH AUTOSEL 6.2 51/60] drm/amd/display: Enable P-state validation checks for DCN314 Sasha Levin
2023-02-27 2:00 ` [PATCH AUTOSEL 6.2 52/60] drm: panel-orientation-quirks: Add quirk for Lenovo IdeaPad Duet 3 10IGL5 Sasha Levin
2023-02-27 2:00 ` [PATCH AUTOSEL 6.2 53/60] drm/amd/display: Disable HUBP/DPP PG on DCN314 for now Sasha Levin
2023-02-27 2:00 ` [PATCH AUTOSEL 6.2 54/60] drm/amd/display: disable SubVP + DRR to prevent underflow Sasha Levin
2023-02-27 2:00 ` [PATCH AUTOSEL 6.2 55/60] dm thin: add cond_resched() to various workqueue loops Sasha Levin
2023-02-27 2:00 ` [PATCH AUTOSEL 6.2 56/60] dm cache: " Sasha Levin
2023-02-27 2:00 ` [PATCH AUTOSEL 6.2 57/60] nfsd: zero out pointers after putting nfsd_files on COPY setup error Sasha Levin
2023-02-27 2:00 ` [PATCH AUTOSEL 6.2 58/60] nfsd: clean up potential nfsd_file refcount leaks in COPY codepath Sasha Levin
2023-02-27 2:00 ` [PATCH AUTOSEL 6.2 59/60] nfsd: don't hand out delegation on setuid files being opened for write Sasha Levin
2023-02-27 2:00 ` [PATCH AUTOSEL 6.2 60/60] cifs: prevent data race in smb2_reconnect() Sasha Levin
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=20230227020045.1045105-23-sashal@kernel.org \
--to=sashal@kernel.org \
--cc=Jonathan.Cameron@huawei.com \
--cc=alistair@alistair23.me \
--cc=ballway@chromium.org \
--cc=benjamin.tissoires@redhat.com \
--cc=cminyard@mvista.com \
--cc=dmitry.torokhov@gmail.com \
--cc=groeck@chromium.org \
--cc=jikos@kernel.org \
--cc=jkosina@suse.cz \
--cc=khalasa@piap.pl \
--cc=linux-input@vger.kernel.org \
--cc=linux-kernel@vger.kernel.org \
--cc=olteanv@gmail.com \
--cc=peter.senna@gmail.com \
--cc=stable@vger.kernel.org \
--cc=u.kleine-koenig@pengutronix.de \
/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).