From nobody Fri Oct 2 12:58:19 2026 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id BA3F637756F; Fri, 31 Jul 2026 20:34:21 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=10.30.226.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1785530061; cv=none; b=GvI++wKgiqlAjZKnBbIMxZSG/ZkUpL8fByj+2/VhQ6MJXfSw/4YG/g6xI6SL6txsA3qbk1mvsE+B9GSzxGfjZ0l3g+Pff8LDXSP7F0mHHZw5bVGQck71EaqY03uCzmvJGg4RsqrSf8uuhHOYd3pnEJ/sxZt46/XkWICFS8W1wb4= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1785530061; c=relaxed/simple; bh=gx9bijnn+Hz1eN9yKjmxkI87RpcUy74TLPj4ERZMN1g=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=evU5suBKofPs3WRy2DpUSmZs30McmrYVQoTxTXZwvyxBpWNlkaDcrfbr+7i1sl+k9Tm34qxX7loD8LTYupFPyZogDqPkg2gtN1RzhJVxFFk0ZJuWEkpvZM+Pq1xr2yVaks2OZX/bqQc2KyahdBSxHA2tQYe3PlSb6h4WVrSNL1c= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=V1b1kK6r; arc=none smtp.client-ip=10.30.226.201 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="V1b1kK6r" Received: by smtp.kernel.org (Postfix) with ESMTPS id 65662C2BCB9; Fri, 31 Jul 2026 20:34:21 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1785530061; bh=gx9bijnn+Hz1eN9yKjmxkI87RpcUy74TLPj4ERZMN1g=; h=From:Date:Subject:References:In-Reply-To:To:Cc:Reply-To:From; b=V1b1kK6r+gnSFKEMelfll8k+HkYG4o2OXUqxUAbmg0sPrDdhl1/DQrfRm38pQ4Iaa 5fcq1Up+u5WshMZ9ZPjIQ8NHYT97jzqAlYtDj0tZg0DzjAz8X21nGP5vaKNvI2HlA/ XjiJJx/x+V22//Mgcrl6YMdKP07j8jwNLj+PB3xTyDdBQ8YbcGi195ObRL8fQ5ULiL wTcOsee6c4R2WiRPrvwL6B9G2ukZUS1tCqej2hMBxoWo5oHXtWcHtG2s2r8DQjwUX+ Fz3tN1FJLuSZEDsQTlFT3ZV4ImhRPZTr+bnuHlPG/HX7mX+GDi3fQrOjgI8wZr8uQ8 cj/g3upHGOQ1A== Received: from aws-us-west-2-korg-lkml-1.web.codeaurora.org (localhost.localdomain [127.0.0.1]) by smtp.lore.kernel.org (Postfix) with ESMTP id 45E6DC55174; Fri, 31 Jul 2026 20:34:21 +0000 (UTC) From: David Heidelberg via B4 Relay Date: Fri, 31 Jul 2026 22:34:12 +0200 Subject: [PATCH v9 1/5] Input: synaptics-rmi4 - handle duplicate/unknown PDT entries Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Message-Id: <20260731-synaptics-rmi4-v9-1-f088c47af6c5@ixit.cz> References: <20260731-synaptics-rmi4-v9-0-f088c47af6c5@ixit.cz> In-Reply-To: <20260731-synaptics-rmi4-v9-0-f088c47af6c5@ixit.cz> To: Kaustabh Chakraborty , Dmitry Torokhov , Rob Herring , Krzysztof Kozlowski , Conor Dooley , "Jason A. Donenfeld" , Matthias Schiffer , Vincent Huang , Marcus Ramberg , Casey Connolly Cc: David Heidelberg , linux-input@vger.kernel.org, devicetree@vger.kernel.org, linux-kernel@vger.kernel.org, phone-devel@vger.kernel.org X-Mailer: b4 0.15.2 X-Developer-Signature: v=1; a=openpgp-sha256; l=4835; i=david@ixit.cz; h=from:subject:message-id; bh=QMmRp8KVD1VgRiH9r3c9vC9t2faLPigCXSGNEqMux4o=; b=owEBbQKS/ZANAwAIAWACP8TTSSByAcsmYgBqbQbLdbwhgLM+vUDHssT065RleIOK4kdKZsiWP /hyFkkNeMyJAjMEAAEIAB0WIQTXegnP7twrvVOnBHRgAj/E00kgcgUCam0GywAKCRBgAj/E00kg cqBND/wJMxsTYkoG+1yN8r2lL0YR57M6mu13XPU2KVd9e8M7Tro17L2KLqcibf7/4XKoZI2jPuu ny5AE7B9fvtxdvrhPhnaUlQ8s4hn1OEq+GHfXT7PqhGxqjpimFNy6Ic7qC4HA/YeXl3YMBZQl7j h7loBfNoqZU8/bHhwFyzxur+rQx4ib3KEP8iITXNV9xijlKIy39OwFJ0eYZSQoznqiU/q+6nhso E39rVd9Ptkx2sBh49Ybk0d5aBiNFKEGnqL4MDZQ33MXJR+/WomJFbJFXaIQyLnmtlAMyA7B+Mir ze550DrD1IYatrWYV7wB3N/ld2nPLxyzj6pp160saV0A5aDy9XHNg8Ll0dl22ILq6JJhjI7jbWa nxYjfEKLbMhFjmZ4xo+pPPeLJvw5widNjkuFSxmCEcf3hpTPY/rX/x1kCY+rVemzgSw70lGONHJ 6+4KVz+XCncbJ1Yd3ijwSjVHDcqn5lmbEysKF9ydogfdMUdzzoxA2fX7lvmkz+diFLOl1FwQdbr h0SugZDpiSY54gnGCs6+djCFTs/M9zn4ymn00byaINHQ3WT7u++4PZx/0Uc89e47GGMvuJ9t3BJ cUrND48duKOU5cg0DOB5xlqqWMVkfZE8CbXveewYaZmHltvNRXRkhjlEGVR1MZBbyrJhzlnnfhv mVUIxy77bd6U5hg== X-Developer-Key: i=david@ixit.cz; a=openpgp; fpr=D77A09CFEEDC2BBD53A7047460023FC4D3492072 X-Endpoint-Received: by B4 Relay for david@ixit.cz/default with auth_id=355 X-Original-From: David Heidelberg Reply-To: david@ixit.cz From: Casey Connolly Some third party rmi4-compatible ICs don't expose their PDT entries very well. Add a few checks to skip duplicate entries as well as entries for unsupported functions. This is required to support some phones with third party displays. Validated on a stock OnePlus 6T (original parts): manufacturer: Synaptics, product: S3706B, fw id: 2852315 Co-developed-by: Kaustabh Chakraborty Signed-off-by: Kaustabh Chakraborty Signed-off-by: Casey Connolly Co-developed-by: David Heidelberg Signed-off-by: David Heidelberg --- drivers/input/rmi4/rmi_driver.c | 41 +++++++++++++++++++++++++++++++++++--= ---- drivers/input/rmi4/rmi_driver.h | 7 +++++++ 2 files changed, 42 insertions(+), 6 deletions(-) diff --git a/drivers/input/rmi4/rmi_driver.c b/drivers/input/rmi4/rmi_drive= r.c index 5d49a9021c7d0..3edec5ae1f8c9 100644 --- a/drivers/input/rmi4/rmi_driver.c +++ b/drivers/input/rmi4/rmi_driver.c @@ -493,22 +493,48 @@ static void rmi_driver_copy_pdt_to_fd(const struct pd= t_entry *pdt, fd->command_base_addr =3D pdt->command_base_addr + pdt->page_start; fd->control_base_addr =3D pdt->control_base_addr + pdt->page_start; fd->data_base_addr =3D pdt->data_base_addr + pdt->page_start; fd->function_number =3D pdt->function_number; fd->interrupt_source_count =3D pdt->interrupt_source_count; fd->function_version =3D pdt->function_version; } =20 +static bool rmi_pdt_entry_is_valid(struct rmi_device *rmi_dev, + struct pdt_scan_state *state, u8 fn) +{ + switch (fn) { + case 0x01: + case 0x03: + case 0x11: + case 0x12: + case 0x30: + case 0x34: + case 0x3a: + case 0x54: + case 0x55: + if (state->pdts[fn] =3D=3D true) + return false; + break; + default: + rmi_dbg(RMI_DEBUG_CORE, &rmi_dev->dev, + "PDT has unknown function number %#02x\n", fn); + return false; + } + + state->pdts[fn] =3D true; + return true; +} + #define RMI_SCAN_CONTINUE 0 #define RMI_SCAN_DONE 1 =20 static int rmi_scan_pdt_page(struct rmi_device *rmi_dev, int page, - int *empty_pages, + struct pdt_scan_state *state, void *ctx, int (*callback)(struct rmi_device *rmi_dev, void *ctx, const struct pdt_entry *entry)) { struct rmi_driver_data *data =3D dev_get_drvdata(&rmi_dev->dev); struct pdt_entry pdt_entry; u16 page_start =3D RMI4_PAGE_SIZE * page; @@ -521,44 +547,47 @@ static int rmi_scan_pdt_page(struct rmi_device *rmi_d= ev, for (addr =3D pdt_start; addr >=3D pdt_end; addr -=3D RMI_PDT_ENTRY_SIZE)= { error =3D rmi_read_pdt_entry(rmi_dev, &pdt_entry, addr); if (error) return error; =20 if (RMI4_END_OF_PDT(pdt_entry.function_number)) break; =20 + if (!rmi_pdt_entry_is_valid(rmi_dev, state, pdt_entry.function_number)) + continue; + retval =3D callback(rmi_dev, ctx, &pdt_entry); if (retval !=3D RMI_SCAN_CONTINUE) return retval; } =20 /* * Count number of empty PDT pages. If a gap of two pages * or more is found, stop scanning. */ if (addr =3D=3D pdt_start) - ++*empty_pages; + ++state->empty_pages; else - *empty_pages =3D 0; + state->empty_pages =3D 0; =20 - return (data->bootloader_mode || *empty_pages >=3D 2) ? + return (data->bootloader_mode || state->empty_pages >=3D 2) ? RMI_SCAN_DONE : RMI_SCAN_CONTINUE; } =20 int rmi_scan_pdt(struct rmi_device *rmi_dev, void *ctx, int (*callback)(struct rmi_device *rmi_dev, void *ctx, const struct pdt_entry *entry)) { int page; - int empty_pages =3D 0; + struct pdt_scan_state state =3D {0, 0, {0}}; int retval =3D RMI_SCAN_DONE; =20 for (page =3D 0; page <=3D RMI4_MAX_PAGE; page++) { - retval =3D rmi_scan_pdt_page(rmi_dev, page, &empty_pages, + retval =3D rmi_scan_pdt_page(rmi_dev, page, &state, ctx, callback); if (retval !=3D RMI_SCAN_CONTINUE) break; } =20 return retval < 0 ? retval : 0; } =20 diff --git a/drivers/input/rmi4/rmi_driver.h b/drivers/input/rmi4/rmi_drive= r.h index abeafb77a4838..6de8faed08917 100644 --- a/drivers/input/rmi4/rmi_driver.h +++ b/drivers/input/rmi4/rmi_driver.h @@ -44,16 +44,23 @@ struct pdt_entry { u8 interrupt_source_count; u8 function_version; u8 function_number; }; =20 #define RMI_REG_DESC_PRESENCE_BITS (32 * BITS_PER_BYTE) #define RMI_REG_DESC_PRESENCE_REGS_MAX (3 + RMI_REG_DESC_PRESENCE_BITS / 8) #define RMI_REG_DESC_SUBPACKET_BITS (37 * BITS_PER_BYTE) +#define RMI_PDT_MAX 0x55 + +struct pdt_scan_state { + u8 empty_pages; + bool pdts[RMI_PDT_MAX + 1]; +}; + =20 /* describes a single packet register */ struct rmi_register_desc_item { u32 reg_size; u16 reg; u16 num_subpackets; DECLARE_BITMAP(subpacket_map, RMI_REG_DESC_SUBPACKET_BITS); }; --=20 2.53.0 From nobody Fri Oct 2 12:58:19 2026 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id CBA3D378D9C; Fri, 31 Jul 2026 20:34:21 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=10.30.226.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1785530061; cv=none; b=qx7ZjNUfRrSARFvuvaFoBPSsIuKYW4IhQ2NH20nXhKbnhvnjNyzbcnFzC1WsOPLQbWxwxFfoLugPNLJRTdsidb+7arShj63doD2zfiLXODW4vuFER9v/IAe3XBj4T93NkLSiP8IIJSTpfX7kS/rRjrpCJWWt/wvwA4E8Zv94pAM= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1785530061; c=relaxed/simple; bh=Iwf1FUXnFPvDq7usnbTNgpPV39ZDh3CoMWHTirrNPpM=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=oVjU7y99ZC+POIwpzVmGsU3a8+V5obpqXRXnCBWefbnEEmia1pP5NQhFZ7CJQBQUxBU8jcuUW6qbs2v2e6HFJzVAhqBcMfWK0H4ewit5UkCK8UEnhwBvU6DulSopnwY3vpVEVoYjMKBJfRO9UqqdfoctmoQ6TXqEL2bM4AK5gGE= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=FW3E4b+z; arc=none smtp.client-ip=10.30.226.201 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="FW3E4b+z" Received: by smtp.kernel.org (Postfix) with ESMTPS id 83ABEC2BCFA; Fri, 31 Jul 2026 20:34:21 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1785530061; bh=Iwf1FUXnFPvDq7usnbTNgpPV39ZDh3CoMWHTirrNPpM=; h=From:Date:Subject:References:In-Reply-To:To:Cc:Reply-To:From; b=FW3E4b+z+hNnhxzd0t+1KrXN3X44r/j3NW6lbJs1kJHnge1dGJZBVL4yyFdwX+QGr aGZxRRc8vQ54S79BH5Vi7R1wuqYKXuurglBXBQocHRJ7oUF129iRr+5+xL9F7tvN4t LYz1SDkIaE1vWamecqxk/JkK5d5oMtrc0aEDuTqW4GxUfOMr3NfopOW6lOlVyC1DZu YPDBAathvN5LiQfSOsyFqNrxHSfObobKUPaFiHUFEPCddg1QdK1wVIVSbfAweeUJFk 7ZLCA7qhX8YwGGtkloQe8afDebAVLgajdFTAw9dbSOj2BTyfS13ZgU6k6RAGaQyW7B QQFRCFPC1OD5g== Received: from aws-us-west-2-korg-lkml-1.web.codeaurora.org (localhost.localdomain [127.0.0.1]) by smtp.lore.kernel.org (Postfix) with ESMTP id 567F3C55175; Fri, 31 Jul 2026 20:34:21 +0000 (UTC) From: David Heidelberg via B4 Relay Date: Fri, 31 Jul 2026 22:34:13 +0200 Subject: [PATCH v9 2/5] Input: synaptics-rmi4 - f12: use hardcoded values for aftermarket touch ICs Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Message-Id: <20260731-synaptics-rmi4-v9-2-f088c47af6c5@ixit.cz> References: <20260731-synaptics-rmi4-v9-0-f088c47af6c5@ixit.cz> In-Reply-To: <20260731-synaptics-rmi4-v9-0-f088c47af6c5@ixit.cz> To: Kaustabh Chakraborty , Dmitry Torokhov , Rob Herring , Krzysztof Kozlowski , Conor Dooley , "Jason A. Donenfeld" , Matthias Schiffer , Vincent Huang , Marcus Ramberg , Casey Connolly Cc: David Heidelberg , linux-input@vger.kernel.org, devicetree@vger.kernel.org, linux-kernel@vger.kernel.org, phone-devel@vger.kernel.org X-Mailer: b4 0.15.2 X-Developer-Signature: v=1; a=openpgp-sha256; l=6682; i=david@ixit.cz; h=from:subject:message-id; bh=lj5joNi8om0GFyhh8zVBAWd6c5wifksQUnwqxhrVhqg=; b=owEBbQKS/ZANAwAIAWACP8TTSSByAcsmYgBqbQbLF3f7RuF8iobIeEz/9MnZ19e1tLihDJS9Q RtUU0KgMKeJAjMEAAEIAB0WIQTXegnP7twrvVOnBHRgAj/E00kgcgUCam0GywAKCRBgAj/E00kg ckwkEADAeglHb+q595lfwBrIHV7imzJ4UHysCHlcT6ILvcAbnDuRXaA/MJRe7/P+cuqATrFGi7+ 61Q1crH5f3HZDsiPtwkZdF0fDKBVDJ+GhG3cNJcYNOCfUhR18Dr2o0kGR2o4YdZrShzqZJvYnar 0FtKJq+oarORhKCa8iLOxK8MVox8mD9x9Oeh/tMh/BorqJETcmIRyHEnCWnZVd0bKtNodkOTgjY xtlEgNNgDJ2GLw+tFCj41438NByO6s+SH8FtXD/gyi2auambbE5Xvr0P5nDC+qaA0iqGiJHWzav xZqvUXD+OUUauBwEbVqSq20OTafN0/fLsMr0aub5GZgFbdDgQg/odZqk//WkmOd1a1Z/TryQlmI 8f7iZDyjZWBT3kJDubCIx7WQUaizSNUeEv1hKdy855JkD0BaplO9pgGL47EkB/UCQNvBjeILycH Gg5j6AbZ292SKdmOewdowhpqRtMSl5SgHkwpNWGHgWuuRaLmfSipVLHv7UJMWuONH1ODzgR3Bwj 4xbSCyX00z6h3CAvRpZiyphf5yvY27hFoIFqbJzGWvVUB84Vzie2P7JJuBxLsW0IrDkITUwvfEx mtFQA3xmXG0rU0LaueeOhTBBKhzoL77jvWb5FekKdNLY4jaxUDwoTH6jixoPSqDOSmEmvIT7uQR W0b5rbHKcoQTCXA== X-Developer-Key: i=david@ixit.cz; a=openpgp; fpr=D77A09CFEEDC2BBD53A7047460023FC4D3492072 X-Endpoint-Received: by B4 Relay for david@ixit.cz/default with auth_id=355 X-Original-From: David Heidelberg Reply-To: david@ixit.cz From: Kaustabh Chakraborty Some replacement displays include third-party touch ICs which are devoid of register descriptors. Create a fake data register descriptor for such ICs and provide hardcoded default values. It isn't possible to reliably determine if the touch IC is original or not, so these fallback values are offered as an alternative to the error path when register descriptors aren't available. Signed-off-by: Kaustabh Chakraborty [changes for readability / codeflow, checkpatch fixes] Signed-off-by: Casey Connolly Signed-off-by: David Heidelberg --- drivers/input/rmi4/rmi_f12.c | 76 +++++++++++++++++++++++++++++++++++++---= ---- 1 file changed, 64 insertions(+), 12 deletions(-) diff --git a/drivers/input/rmi4/rmi_f12.c b/drivers/input/rmi4/rmi_f12.c index 333477bf0663e..ace97468b218d 100644 --- a/drivers/input/rmi4/rmi_f12.c +++ b/drivers/input/rmi4/rmi_f12.c @@ -240,16 +240,51 @@ static void rmi_f12_process_objects(struct f12_data *= f12, u8 *data1, u32 size) sensor->tracking_pos, sensor->nbr_fingers, sensor->dmax); =20 for (i =3D 0; i < objects; i++) rmi_2d_sensor_abs_report(sensor, &sensor->objs[i], i); } =20 +static void rmi_f12_set_hardcoded_desc(struct rmi_function *fn, struct f12= _data *f12) +{ + struct rmi_2d_sensor *sensor =3D &f12->sensor; + struct rmi_register_desc_item *reg_desc; + + /* We have no f12->data_reg_desc, so the pkt_size is 0, override it with + * a somewhat sensible default (this corresponds to 10 fingers). + */ + sensor->pkt_size =3D 88; + + /* + * There are no register descriptors to get these values from. + * We set them to high values to either be overwritten by the clip + * properties from devicetree, or to just not get in the way. + */ + sensor->max_x =3D 65535; + sensor->max_y =3D 65535; + + /* + * Create the Data1 register descriptor so that touch events + * can work properly. + */ + reg_desc =3D devm_kcalloc(&fn->dev, 1, + sizeof(struct rmi_register_desc_item), GFP_KERNEL); + reg_desc->reg =3D 1; + reg_desc->reg_size =3D 80; + reg_desc->num_subpackets =3D 10; + + f12->data1 =3D reg_desc; + f12->data1_offset =3D 0; + sensor->nbr_fingers =3D reg_desc->num_subpackets; + sensor->report_abs =3D 1; + sensor->attn_size +=3D reg_desc->reg_size; +} + static irqreturn_t rmi_f12_attention(int irq, void *ctx) { struct rmi_function *fn =3D ctx; struct rmi_device *rmi_dev =3D fn->rmi_dev; struct rmi_driver_data *drvdata =3D dev_get_drvdata(&rmi_dev->dev); struct f12_data *f12 =3D dev_get_drvdata(&fn->dev); struct rmi_2d_sensor *sensor =3D &f12->sensor; u32 valid_bytes =3D sensor->pkt_size; @@ -371,22 +406,27 @@ static int rmi_f12_config(struct rmi_function *fn) =20 static int rmi_f12_sensor_init(struct rmi_function *fn, struct f12_data *f= 12) { struct rmi_2d_sensor *sensor =3D &f12->sensor; size_t pkt_size; =20 sensor->fn =3D fn; f12->data_addr =3D fn->fd.data_base_addr; - pkt_size =3D rmi_register_desc_calc_size(&f12->data_reg_desc); - if (pkt_size > SZ_1M) { - dev_err(&fn->dev, "Invalid data packet size: %zu\n", pkt_size); - return -EINVAL; + /* On quirky devices that don't have a data_reg_desc we hardcode the pack= et + * in rmi_f12_set_hardcoded_desc(). Make sure not to set it to 0 here. + */ + if (!sensor->pkt_size) { + pkt_size =3D rmi_register_desc_calc_size(&f12->data_reg_desc); + if (pkt_size > SZ_1M) { + dev_err(&fn->dev, "Invalid data packet size: %zu\n", pkt_size); + return -EINVAL; + } + sensor->pkt_size =3D pkt_size; } - sensor->pkt_size =3D pkt_size; =20 sensor->axis_align =3D f12->sensor_pdata.axis_align; =20 sensor->x_mm =3D f12->sensor_pdata.x_mm; sensor->y_mm =3D f12->sensor_pdata.y_mm; sensor->dribble =3D f12->sensor_pdata.dribble; =20 if (sensor->sensor_type =3D=3D rmi_sensor_default) @@ -410,65 +450,76 @@ static int rmi_f12_probe(struct rmi_function *fn) u16 query_addr =3D fn->fd.query_base_addr; const struct rmi_register_desc_item *item; struct rmi_2d_sensor *sensor; struct rmi_device_platform_data *pdata =3D rmi_get_platform_data(rmi_dev); struct rmi_driver_data *drvdata =3D dev_get_drvdata(&rmi_dev->dev); size_t data_offset =3D 0; int irq_mask_size; int i; + bool hardcoded_desc_quirk =3D false; =20 rmi_dbg(RMI_DEBUG_FN, &fn->dev, "%s\n", __func__); =20 irq_mask_size =3D BITS_TO_LONGS(drvdata->irq_count); =20 ret =3D rmi_read(fn->rmi_dev, query_addr, &buf); if (ret < 0) { dev_err(&fn->dev, "Failed to read general info register: %d\n", ret); return -ENODEV; } ++query_addr; =20 if (!(buf & BIT(0))) { - dev_err(&fn->dev, - "Behavior of F12 without register descriptors is undefined.\n"); - return -ENODEV; + rmi_dbg(RMI_DEBUG_FN, &fn->dev, + "No register descriptors defined for F12, using fallback\n"); + hardcoded_desc_quirk =3D true; } =20 f12 =3D devm_kzalloc(&fn->dev, struct_size(f12, irq_mask, irq_mask_size *= 2), GFP_KERNEL); if (!f12) return -ENOMEM; =20 + dev_set_drvdata(&fn->dev, f12); + set_bit(fn->irq_pos, f12->irq_mask); set_bit(fn->irq_pos + 1, f12->irq_mask + irq_mask_size); =20 f12->has_dribble =3D !!(buf & BIT(3)); =20 if (fn->dev.of_node) { ret =3D rmi_2d_sensor_of_probe(&fn->dev, &f12->sensor_pdata); if (ret) return ret; } else { f12->sensor_pdata =3D pdata->sensor_pdata; } =20 + sensor =3D &f12->sensor; + + if (hardcoded_desc_quirk) { + rmi_f12_set_hardcoded_desc(fn, f12); + + ret =3D rmi_f12_sensor_init(fn, f12); + if (ret) + return ret; + + goto skip_register_desc; + } + ret =3D rmi_f12_read_register_descs(fn, f12, query_addr); if (ret) return ret; =20 - sensor =3D &f12->sensor; - ret =3D rmi_f12_sensor_init(fn, f12); if (ret) return ret; =20 - dev_set_drvdata(&fn->dev, f12); - ret =3D rmi_f12_read_sensor_tuning(f12); if (ret) return ret; =20 /* * Identify available data registers and calculate their offsets within * the attention report. For HID devices, only Data1 and Data5 are * included in the report; other registers may be described but are @@ -528,16 +579,17 @@ static int rmi_f12_probe(struct rmi_function *fn) f12->data15 =3D item; f12->data15_offset =3D data_offset; break; } =20 data_offset +=3D item->reg_size; } =20 +skip_register_desc: /* allocate the in-kernel tracking buffers */ sensor->tracking_pos =3D devm_kcalloc(&fn->dev, sensor->nbr_fingers, sizeof(*sensor->tracking_pos), GFP_KERNEL); if (!sensor->tracking_pos) return -ENOMEM; =20 sensor->tracking_slots =3D devm_kcalloc(&fn->dev, sensor->nbr_fingers, --=20 2.53.0 From nobody Fri Oct 2 12:58:19 2026 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id BA478378823; Fri, 31 Jul 2026 20:34:21 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=10.30.226.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1785530061; cv=none; b=WcSQVqESAB4LhZzedt0Bf6DzKCgj2jAtaKLzuuJcyvDiPlWpnpjpTx/Mh/JDthXOXLlPlpxS9TOjYcd60un/lGAw9aMes9m/hxsRYK3aGDGUfog8zRrzaY4Wr1vASqzWX32w+STTjLz48sxMymj7Z76Iod5t53bICX/jGevMzLw= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1785530061; c=relaxed/simple; bh=Aw+NrUCA5ebHr7SpJt83ZqJ1Oul+yWL/nBP/ZUMMB6M=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=pFN/ZCe+tr0fJrjZ0EZdwQvZ5dCR+Ccy495h9TmmgVZjkYLAuZdZSurrdHKEsBR9Dx6qCHQzk4mZu7pvLWQFuB+OCXpwDgfJCIpbE7Mx1W3P6kv+3dNJchI+o29zLW25P9WKSvJa/VhVeqZ5/jzbbyygEwssqJPpEZCQ24+9dFI= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=FsEdIuc1; arc=none smtp.client-ip=10.30.226.201 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="FsEdIuc1" Received: by smtp.kernel.org (Postfix) with ESMTPS id 7F966C2BCF6; Fri, 31 Jul 2026 20:34:21 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1785530061; bh=Aw+NrUCA5ebHr7SpJt83ZqJ1Oul+yWL/nBP/ZUMMB6M=; h=From:Date:Subject:References:In-Reply-To:To:Cc:Reply-To:From; b=FsEdIuc1RSrnzF/iOVLy5g96TP8utoFWskYC77ow79m/CLFjCUPrhpy+b6YAzp9IC ffxtwmh0E+gnFypj/KBgTUhynzwQS5n06kkJpJhvzi+BMGkUZnCY/ibHTq3sz9x8Ro iiDPNM2y3jPjKMz61kKgH7DkRkXJyHxgFc2DOJYsplSI3FWNn56C3rEMINrYclylM7 IpZTRzbDxUQmGWh/ckc7kgo5m0hhAhZPNGTLWHeh+wlo+TqhcJIEH/RKfB3VpFors7 5S0iJjJ0u6pmjnVQHu/t4plToD2bmmpykEAeGUGDnKgj2Zhyi2+V1KqjMnKXmjtjlx cCHHYhnq/b+bg== Received: from aws-us-west-2-korg-lkml-1.web.codeaurora.org (localhost.localdomain [127.0.0.1]) by smtp.lore.kernel.org (Postfix) with ESMTP id 64723C55173; Fri, 31 Jul 2026 20:34:21 +0000 (UTC) From: David Heidelberg via B4 Relay Date: Fri, 31 Jul 2026 22:34:14 +0200 Subject: [PATCH v9 3/5] Input: synaptics-rmi4 - don't do unaligned reads in IRQ context Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Message-Id: <20260731-synaptics-rmi4-v9-3-f088c47af6c5@ixit.cz> References: <20260731-synaptics-rmi4-v9-0-f088c47af6c5@ixit.cz> In-Reply-To: <20260731-synaptics-rmi4-v9-0-f088c47af6c5@ixit.cz> To: Kaustabh Chakraborty , Dmitry Torokhov , Rob Herring , Krzysztof Kozlowski , Conor Dooley , "Jason A. Donenfeld" , Matthias Schiffer , Vincent Huang , Marcus Ramberg , Casey Connolly Cc: David Heidelberg , linux-input@vger.kernel.org, devicetree@vger.kernel.org, linux-kernel@vger.kernel.org, phone-devel@vger.kernel.org X-Mailer: b4 0.15.2 X-Developer-Signature: v=1; a=openpgp-sha256; l=2886; i=david@ixit.cz; h=from:subject:message-id; bh=vAqnQGN6pz6rr7DIayEzXt/GiaRM85ZXWL7LWrBPOzA=; b=owEBbQKS/ZANAwAIAWACP8TTSSByAcsmYgBqbQbLDb7vW+fOcETd68pmui1yZb4EPzX4JJYER 8z2eXJvI/2JAjMEAAEIAB0WIQTXegnP7twrvVOnBHRgAj/E00kgcgUCam0GywAKCRBgAj/E00kg cpQREADJf5PE0SUaT6a7UkeXvChP0dBZP0GkVwrJKuSvXC/Is6YISns/p5VkcRkGcCGFmbJeLPE qXi1gENbyoPfSAQpTKQPUKyZ4mPLMPVwTk6m/RLuS1gp0us9noq5poScpIjYiq5LaX6REZTdNJQ +vvLH0xSXAViYnz0tl+J7P9eo63FuYTqxdkkK+M+Dii5i/a9sUVkDgOcjamNnjJuU+bzJYxnMoN knqOODf83/OhWkjVXI1hh8SlE3d4m3xjiPH2A3/qvpBLVdf8FUTTHLm2LWTU3L4p6Gszx/FUM/W JYvGuhc9+aGnBTsvNuE0Sh9BcyGhfdFNQJN/9qBwuhMCFNZ4ehNtjJA5aHM//sjDauX7JpuedLW 7EfrOU3p6aIPaKFK89dBZysk5KVe1a3NOGWQ+G0WQEs+xj/A9Cf6DuJMjl+NfwJApMYJimVsTmP JvCdwcq0Ea1MoR6OkjwiMfdzOV0laqINSkIClKV5c8dqz3DJsKUJGf1MZrI6VJKYdqnQLnc3Seg K8HZXenVJghJGUeCzRbM7iNw0vkyqMsSOzTY1XS6KYiqG5jzTxsSIaD1LzYomHjiaetzQH4TOyn GHJCpYZympEkl4JdHiKUWqrs0S0oxdwfpd3GhCrVs004qj+g9pD5n9Bc/9EkpxEjzLqFbji76Oe rSxLjxhPpWT1FLw== X-Developer-Key: i=david@ixit.cz; a=openpgp; fpr=D77A09CFEEDC2BBD53A7047460023FC4D3492072 X-Endpoint-Received: by B4 Relay for david@ixit.cz/default with auth_id=355 X-Original-From: David Heidelberg Reply-To: david@ixit.cz From: Kaustabh Chakraborty Some replacement displays include third-party touch ICs which incur a significant penalty (1-2 seconds) when doing certain unaligned reads. This is enough to break functionality when it happens in the hot path, so adjust the interrupt handler to not read from an unaligned address. Signed-off-by: Kaustabh Chakraborty Signed-off-by: Casey Connolly Signed-off-by: David Heidelberg --- drivers/input/rmi4/rmi_driver.c | 20 +++++++++++++------- 1 file changed, 13 insertions(+), 7 deletions(-) diff --git a/drivers/input/rmi4/rmi_driver.c b/drivers/input/rmi4/rmi_drive= r.c index 3edec5ae1f8c9..5e7766363aa23 100644 --- a/drivers/input/rmi4/rmi_driver.c +++ b/drivers/input/rmi4/rmi_driver.c @@ -133,19 +133,24 @@ static int rmi_process_interrupt_requests(struct rmi_= device *rmi_dev) struct device *dev =3D &rmi_dev->dev; int i; int error; =20 if (!data) return 0; =20 if (!data->attn_data.data) { + /* + * Read the device status register as well and ignore it. + * Some aftermarket ICs have issues with interrupt requests + * otherwise. + */ error =3D rmi_read_block(rmi_dev, - data->f01_container->fd.data_base_addr + 1, - data->irq_status, data->num_of_irq_regs); + data->f01_container->fd.data_base_addr, + (u8 *)data->irq_status - 1, data->num_of_irq_regs + 1); if (error < 0) { dev_err(dev, "Failed to read irqs, code=3D%d\n", error); return error; } } =20 mutex_lock(&data->irq_mutex); bitmap_and(data->irq_status, data->irq_status, data->fn_irq_bits, @@ -1117,26 +1122,27 @@ int rmi_probe_interrupts(struct rmi_driver_data *da= ta) dev_err(&rmi_dev->dev, "Failed to create IRQ domain\n"); return -ENOMEM; } =20 data->irq_count =3D irq_count; data->num_of_irq_regs =3D (data->irq_count + 7) / 8; =20 size =3D BITS_TO_LONGS(data->irq_count) * sizeof(unsigned long); - data->irq_memory =3D devm_kcalloc(dev, size, 4, GFP_KERNEL); + data->irq_memory =3D devm_kzalloc(dev, size * 4 + 1, GFP_KERNEL); if (!data->irq_memory) { dev_err(dev, "Failed to allocate memory for irq masks.\n"); return -ENOMEM; } =20 - data->irq_status =3D data->irq_memory + size * 0; - data->fn_irq_bits =3D data->irq_memory + size * 1; - data->current_irq_mask =3D data->irq_memory + size * 2; - data->new_irq_mask =3D data->irq_memory + size * 3; + /* The first byte is reserved for the device status register */ + data->irq_status =3D data->irq_memory + size * 0 + 1; + data->fn_irq_bits =3D data->irq_memory + size * 1 + 1; + data->current_irq_mask =3D data->irq_memory + size * 2 + 1; + data->new_irq_mask =3D data->irq_memory + size * 3 + 1; =20 return retval; } =20 int rmi_init_functions(struct rmi_driver_data *data) { struct rmi_device *rmi_dev =3D data->rmi_dev; struct device *dev =3D &rmi_dev->dev; --=20 2.53.0 From nobody Fri Oct 2 12:58:19 2026 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id D33A737996C; Fri, 31 Jul 2026 20:34:21 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=10.30.226.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1785530061; cv=none; b=n4kUSWStUiJAlM4Lo5QgydLgRgVILcvvbduS3buqEkgMRxaG5HGMhyD9VM53kSUr1CJbnjb+TwUJsdWrZsRJhErTbO3ZeSkL3wRpUxe/BaKGn6gHdy0JKLA8U+8svl2/JCvBUwGTxgKxmNUYbT5GiRxsLJKGGZcx3Kl0dM03rqM= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1785530061; c=relaxed/simple; bh=4epTUOwQQZ+rFZbePVbmil++6zzCxjsEGEoTZaY1rIg=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=ImS9h/bxWUFhtpi7b2F7pI0y4DQHfSHlhiUX0Ax9IiNe2llkomAzNxCPrDjDStowKA4OnNNDBRdhLIw1jKwVvq1K2D+Qesk8g6mKBCwb9E/kNfhUNTNSAEhy+D8HZlBdeWqnuyn1tXEtCxyODkrBc5MiTGFHIkKvlKx5j3mC4+8= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=G4UBi4PQ; arc=none smtp.client-ip=10.30.226.201 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="G4UBi4PQ" Received: by smtp.kernel.org (Postfix) with ESMTPS id 87D58C2BCFC; Fri, 31 Jul 2026 20:34:21 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1785530061; bh=4epTUOwQQZ+rFZbePVbmil++6zzCxjsEGEoTZaY1rIg=; h=From:Date:Subject:References:In-Reply-To:To:Cc:Reply-To:From; b=G4UBi4PQIb4w76qRS59ehfbiZ/3RXmEsRdU0MJ+oWQsT8SDQ3fUoilEurhh4+onzX AGM3kB5u6AAHoQR+Kssx93+9FoPRa7yBcBjCCH31nOJVarRsXqfsVEOwXum1XnmPPG gZZnQh0r3FPIoGtD2yaJF8dGU95z1K+PeApVICNQ0sIkKWfyStQMMCgbVUaebSQAHd vaeZmJ+TIfxKms39sZSPLaESuBOKcG4yKFcCSWBJMVQeqmcTfFyin4AtuLqZFeLcc+ sz0dSLjYTSCF/OufoODIFvb/IkbMoxd/aDT7evfWHF2umCcQejxZKfac90ZRab4Hqk 8rN7CZDivkOWg== Received: from aws-us-west-2-korg-lkml-1.web.codeaurora.org (localhost.localdomain [127.0.0.1]) by smtp.lore.kernel.org (Postfix) with ESMTP id 722EFC55178; Fri, 31 Jul 2026 20:34:21 +0000 (UTC) From: David Heidelberg via B4 Relay Date: Fri, 31 Jul 2026 22:34:15 +0200 Subject: [PATCH v9 4/5] Input: synaptics-rmi4 - read product ID on aftermarket touch ICs Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Message-Id: <20260731-synaptics-rmi4-v9-4-f088c47af6c5@ixit.cz> References: <20260731-synaptics-rmi4-v9-0-f088c47af6c5@ixit.cz> In-Reply-To: <20260731-synaptics-rmi4-v9-0-f088c47af6c5@ixit.cz> To: Kaustabh Chakraborty , Dmitry Torokhov , Rob Herring , Krzysztof Kozlowski , Conor Dooley , "Jason A. Donenfeld" , Matthias Schiffer , Vincent Huang , Marcus Ramberg , Casey Connolly Cc: David Heidelberg , linux-input@vger.kernel.org, devicetree@vger.kernel.org, linux-kernel@vger.kernel.org, phone-devel@vger.kernel.org X-Mailer: b4 0.15.2 X-Developer-Signature: v=1; a=openpgp-sha256; l=1495; i=david@ixit.cz; h=from:subject:message-id; bh=0ZX7YD1h+ukbpiEVF+1UBqpg30+ZDcn5w6CgQP4D90Y=; b=owEBbQKS/ZANAwAIAWACP8TTSSByAcsmYgBqbQbL9kDNHl04tATOlcEIr/yxofbkl7EcbhWZC ioxIdPepYWJAjMEAAEIAB0WIQTXegnP7twrvVOnBHRgAj/E00kgcgUCam0GywAKCRBgAj/E00kg ckW4D/9gv+UAdqO3cjHjyI42Qnbxm+nHT3tXwG6zreed2KxC07y1b89ZYsyryI/uRf+EkaVr3x2 Tja5uaqQ2ZrjHMzdr/iFX5jyqnCTMW5xWbMDMt9sDxVBgYmmdpM4+Iircb2MJKJO5vyLgjrtlxM h/VZxMHYErvlh3VeUpGtDaXPl2Jwy5L1zzCgR9UJPbmkx7RmgEeAc8dqXMoOlerN2ZnNrN/eORp Z95j87dSWo4Fz1PaKRsoe8l6Lr63w6ntXm2UITi9DMugebNQumd0pRDSuMZ8vunvuIhxIjyRF2B esYugAxPXsDuhjMa5P5OQsp26gMkxJ2JR/ghD1FhseBM1WrdcOIyERkSIfWAPl3f8Luzu6gMIey b40Jh4kL8pIPdpeyUAxI+8gBL+6oEDv9cnFH+1CsIy5PNPsXNuF2TUbEX1eTm5QxkFPnVIPSWbu dwo+7DCxeF+Y4WCULHy9C+eYfPH0nMjiqDl3zTKlPCpLaSfTKGk17xemlwgbwV8+uBA5WDjMD9l R1jzZY1qK6WQcKmdQv1CmlMhSXLVJ2BSDM5+k9ZLfRbTSgrF+xxaTLu3XKEWI/68hlT5IY7NfLg EUgx77r55rVKjCSW/eplwfhL9V0pGRr4BtJrNjSMDQwrtI4z6BE8ihzKCuASeFEh1HJH1VtW6rd YRK81VdOcQuoVyA== X-Developer-Key: i=david@ixit.cz; a=openpgp; fpr=D77A09CFEEDC2BBD53A7047460023FC4D3492072 X-Endpoint-Received: by B4 Relay for david@ixit.cz/default with auth_id=355 X-Original-From: David Heidelberg Reply-To: david@ixit.cz From: Kaustabh Chakraborty Some replacement displays include third-party touch ICs which do not report the product ID correctly unless we read directly from the product ID register. Add a check and a fallback read to handle this. Signed-off-by: Kaustabh Chakraborty Signed-off-by: Casey Connolly Signed-off-by: David Heidelberg --- drivers/input/rmi4/rmi_f01.c | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/drivers/input/rmi4/rmi_f01.c b/drivers/input/rmi4/rmi_f01.c index 47be64284b25e..2278e9b6a9207 100644 --- a/drivers/input/rmi4/rmi_f01.c +++ b/drivers/input/rmi4/rmi_f01.c @@ -245,16 +245,30 @@ static int rmi_f01_read_properties(struct rmi_device = *rmi_dev, return ret; } =20 props->firmware_id =3D queries[1] << 8 | queries[0]; props->firmware_id +=3D queries[2] * 65536; } } =20 + /* + * Some aftermarket ICs put garbage into the product id field unless + * we read directly from the product id register. + */ + if (props->product_id[0] < 0x20) { + ret =3D rmi_read_block(rmi_dev, query_base_addr + 11, + props->product_id, RMI_PRODUCT_ID_LENGTH); + if (ret) { + dev_err(&rmi_dev->dev, + "Failed to read product id: %d\n", ret); + return ret; + } + } + return 0; } =20 const char *rmi_f01_get_product_ID(struct rmi_function *fn) { struct f01_data *f01 =3D dev_get_drvdata(&fn->dev); =20 return f01->properties.product_id; --=20 2.53.0 From nobody Fri Oct 2 12:58:19 2026 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id F098D37B032; Fri, 31 Jul 2026 20:34:21 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=10.30.226.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1785530062; cv=none; b=TfFhIJWsrDSumBD29ktegkxx0MXyFdBN4kOkT9pg4QiUsaMFTnNx+EBjEW1U49FnMbJfSFA3iUIJ4UI+C0RkAMgjZ31wATLxawVkRKO9ZGeIglytbF29XpgDoV2KkmVCcfTz4g7dqkn1SBq7dcph9GaPRasxXhTwbzEaPrndS9Y= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1785530062; c=relaxed/simple; bh=oZUebJj3CUYHrhXP9UjDxB8MkIwn4Y04a2b4+t3YuYY=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=KgSPongGRKckIKovVGO/pU6iAjhVcsAZWWDd/SktDYm+TdCAjezG0yXM7wD6nrYEI3LLArYFde/q/NANuF1m/WLC7agztaWIzFWYuJV1QgmKR1BDu3p4xNdc/LjWDK3EuqWxzVGHNMzM1XKMV/2EAn1e3C4Vy9fdakyAmrS4gMs= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=sx/BFpXP; arc=none smtp.client-ip=10.30.226.201 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="sx/BFpXP" Received: by smtp.kernel.org (Postfix) with ESMTPS id 95723C2BCFF; Fri, 31 Jul 2026 20:34:21 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1785530061; bh=oZUebJj3CUYHrhXP9UjDxB8MkIwn4Y04a2b4+t3YuYY=; h=From:Date:Subject:References:In-Reply-To:To:Cc:Reply-To:From; b=sx/BFpXPjKkBoaUX60Q+rhq1JIAyKU1EniqVNHIjwKmFbKvFUnpL8ZxSmuSA2rF8S 0h0Z9xUR+Wbk8ySdLzyizBVw2liyYnOT7wY/yCanbD9S644IKgiRXUNAuad1OpYhp5 tOtRNNEEv2gxBRsDD0Oc0bJZWN45rG5SJjXeJwRoSjzcfoxpYWaHlt6D01oTjg26c1 9+EwOkHke9P+s+Y+fGECIh2pDZz+zPd9ay4ORfe9XwrUMWcwBocTRZ50FOAJNu7vGv zCOA0ImZIj9XyinY+HY8RvgdLdp5I0bxyzggTKPd1gsC4GCKNuUmHOek+4kwJGMaye aN7ESxc5whj/Q== Received: from aws-us-west-2-korg-lkml-1.web.codeaurora.org (localhost.localdomain [127.0.0.1]) by smtp.lore.kernel.org (Postfix) with ESMTP id 80AA3C55177; Fri, 31 Jul 2026 20:34:21 +0000 (UTC) From: David Heidelberg via B4 Relay Date: Fri, 31 Jul 2026 22:34:16 +0200 Subject: [PATCH v9 5/5] Input: synaptics-rmi4 - support fallback values for PDT descriptor bytes Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Message-Id: <20260731-synaptics-rmi4-v9-5-f088c47af6c5@ixit.cz> References: <20260731-synaptics-rmi4-v9-0-f088c47af6c5@ixit.cz> In-Reply-To: <20260731-synaptics-rmi4-v9-0-f088c47af6c5@ixit.cz> To: Kaustabh Chakraborty , Dmitry Torokhov , Rob Herring , Krzysztof Kozlowski , Conor Dooley , "Jason A. Donenfeld" , Matthias Schiffer , Vincent Huang , Marcus Ramberg , Casey Connolly Cc: David Heidelberg , linux-input@vger.kernel.org, devicetree@vger.kernel.org, linux-kernel@vger.kernel.org, phone-devel@vger.kernel.org X-Mailer: b4 0.15.2 X-Developer-Signature: v=1; a=openpgp-sha256; l=8394; i=david@ixit.cz; h=from:subject:message-id; bh=VT8TqHstCB13MOIEZKScbmgMfHxX/aBtoMoj8AVgz1U=; b=owEBbQKS/ZANAwAIAWACP8TTSSByAcsmYgBqbQbLYCH85x470qignNeRtHqHSpeLX1zBIYo36 HtaEIOvm1yJAjMEAAEIAB0WIQTXegnP7twrvVOnBHRgAj/E00kgcgUCam0GywAKCRBgAj/E00kg chbiEACi51t1O1LIBouUqUYMob8colomKQr/xm30fx4f/7e5otQT2Y3oBMv0CTJTWNzuEtDmzbc DWC3Bba9q44387xMuUrOCv/IQj+Yzb3ltVGvkQzLCuyGKSCphw88n3C8fq65utK5kiLAE5+pYqd h6L6EbTxmkDARYXjnW7/dp/lryGa0BY9tb/+YPykQPlIW0YDND9j+4pkHTnhh/1mAqKE9XFjloW 3OWG4SgrZ8QXZM14n+qwI5G2b5QOisLqeio8CpPPkjRIIyr+P2e5lfAzPxOkNVhq7juwhOdNhYF 8Uiy8hqtxmEGsYjcUyFH99lYudIXYcRp24mJ0b9To23O/Ie34dXrLfycsr/zdgVyTpvhPeYsMBX 7pVwYLg0ucg55shSCQF1QAs+9fTXygBAtELStH9ofOx/gnAXp3pcvSUJ0pvPLhyTSaIJZlDnj+0 kJj/j9cEvr+ytKBejGCI3OhiEaUjE28F9TYaLjCOyqKMTQEqHrZCana6ypJStqP21IEPadMw6gt rGmPiJRqdzdiSHv1cZ7A9PAFdF0OHBwtXyZwwf+cbflfSb3+tyiD2zlEuXDNesn0dNC1e/oaBmw rz07wSTQBleaAnQQffhWmBVL9IPIVqXUxLjEq9yDcLl0yQ6WKOIwjrIS9OFXXlzScsycmP4ABxc mQNnBCFHf2hs8kA== X-Developer-Key: i=david@ixit.cz; a=openpgp; fpr=D77A09CFEEDC2BBD53A7047460023FC4D3492072 X-Endpoint-Received: by B4 Relay for david@ixit.cz/default with auth_id=355 X-Original-From: David Heidelberg Reply-To: david@ixit.cz From: Kaustabh Chakraborty Some replacement displays include third-party touch ICs which do not expose the function number and the interrupt status in its PDT entries. OnePlus 6 (original touch IC) rmi4_i2c 12-0020: read 6 bytes at 0x00e3: 0 (2b 22 0d 06 01 01) OnePlus 6 (aftermarket touch IC) rmi4_i2c 12-0020: read 6 bytes at 0x00e3: 0 (2c 23 0d 06 00 00) Signed-off-by: Kaustabh Chakraborty [codeflow adjustments, checkpatch fixes, wording] Signed-off-by: Casey Connolly Co-developed-by: David Heidelberg Signed-off-by: David Heidelberg --- drivers/input/rmi4/rmi_driver.c | 64 +++++++++++++++++++++++++++++++++++--= ---- drivers/input/rmi4/rmi_driver.h | 3 ++ include/linux/rmi.h | 3 ++ 3 files changed, 62 insertions(+), 8 deletions(-) diff --git a/drivers/input/rmi4/rmi_driver.c b/drivers/input/rmi4/rmi_drive= r.c index 5e7766363aa23..dac26458f0937 100644 --- a/drivers/input/rmi4/rmi_driver.c +++ b/drivers/input/rmi4/rmi_driver.c @@ -461,29 +461,45 @@ static int rmi_driver_reset_handler(struct rmi_device= *rmi_dev) =20 error =3D rmi_driver_process_config_requests(rmi_dev); if (error < 0) return error; =20 return 0; } =20 -static int rmi_read_pdt_entry(struct rmi_device *rmi_dev, - struct pdt_entry *entry, u16 pdt_address) +static int rmi_read_pdt_entry(struct rmi_device *rmi_dev, struct pdt_entry= *entry, + struct pdt_scan_state *state, u16 pdt_address) { + const struct rmi_device_platform_data *pdata =3D rmi_get_platform_data(rm= i_dev); u8 buf[RMI_PDT_ENTRY_SIZE]; int error; =20 error =3D rmi_read_block(rmi_dev, pdt_address, buf, RMI_PDT_ENTRY_SIZE); if (error) { dev_err(&rmi_dev->dev, "Read PDT entry at %#06x failed, code: %d.\n", pdt_address, error); return error; } =20 + if (pdata->pdt_fallback_size > state->pdt_count * RMI_OF_PDT_DESC_CELLS += 1) { + /* Use the description bytes from the driver */ + buf[5] =3D pdata->pdt_fallback_desc[state->pdt_count * RMI_OF_PDT_DESC_C= ELLS]; + buf[4] =3D pdata->pdt_fallback_desc[state->pdt_count * RMI_OF_PDT_DESC_C= ELLS + 1]; + + error =3D rmi_read_block(rmi_dev, pdt_address, buf, + RMI_PDT_ENTRY_SIZE - 2); + if (error) { + dev_err(&rmi_dev->dev, + "Read PDT entry at %#06x failed, code: %d.\n", + pdt_address, error); + return error; + } + } + entry->page_start =3D pdt_address & RMI4_PAGE_MASK; entry->query_base_addr =3D buf[0]; entry->command_base_addr =3D buf[1]; entry->control_base_addr =3D buf[2]; entry->data_base_addr =3D buf[3]; entry->interrupt_source_count =3D buf[4] & RMI_PDT_INT_SOURCE_COUNT_MASK; entry->function_version =3D (buf[4] & RMI_PDT_FUNCTION_VERSION_MASK) >> 5; entry->function_number =3D buf[5]; @@ -521,16 +537,17 @@ static bool rmi_pdt_entry_is_valid(struct rmi_device = *rmi_dev, break; default: rmi_dbg(RMI_DEBUG_CORE, &rmi_dev->dev, "PDT has unknown function number %#02x\n", fn); return false; } =20 state->pdts[fn] =3D true; + state->pdt_count++; return true; } =20 #define RMI_SCAN_CONTINUE 0 #define RMI_SCAN_DONE 1 =20 static int rmi_scan_pdt_page(struct rmi_device *rmi_dev, int page, @@ -545,17 +562,17 @@ static int rmi_scan_pdt_page(struct rmi_device *rmi_d= ev, u16 page_start =3D RMI4_PAGE_SIZE * page; u16 pdt_start =3D page_start + PDT_START_SCAN_LOCATION; u16 pdt_end =3D page_start + PDT_END_SCAN_LOCATION; u16 addr; int error; int retval; =20 for (addr =3D pdt_start; addr >=3D pdt_end; addr -=3D RMI_PDT_ENTRY_SIZE)= { - error =3D rmi_read_pdt_entry(rmi_dev, &pdt_entry, addr); + error =3D rmi_read_pdt_entry(rmi_dev, &pdt_entry, state, addr); if (error) return error; =20 if (RMI4_END_OF_PDT(pdt_entry.function_number)) break; =20 if (!rmi_pdt_entry_is_valid(rmi_dev, state, pdt_entry.function_number)) continue; @@ -1062,31 +1079,62 @@ static int rmi_driver_remove(struct device *dev) =20 irq_domain_remove(data->irqdomain); data->irqdomain =3D NULL; =20 return 0; } =20 #ifdef CONFIG_OF -static int rmi_driver_of_probe(struct device *dev, - struct rmi_device_platform_data *pdata) +static const u8 rmi_s3706_fallback_pdt[] =3D {0x34, 0x41, 0x01, + 0x01, 0x12, 0x01}; + +static int rmi_driver_of_probe(struct rmi_device *rmi_dev, + struct rmi_device_platform_data *pdata) { + struct device *dev =3D rmi_dev->xport->dev; + u8 buf[RMI_PDT_ENTRY_SIZE]; int retval; =20 retval =3D rmi_of_property_read_u32(dev, &pdata->reset_delay_ms, "syna,reset-delay-ms", 1); if (retval) return retval; =20 + /* + * In some aftermerket touch ICs, the first PDT entry is empty and + * the function number register is 0. If so, the driver + * may have provide backup PDT entries. + */ + + retval =3D rmi_read_block(rmi_dev, PDT_START_SCAN_LOCATION, + buf, RMI_PDT_ENTRY_SIZE); + if (retval) { + dev_err(dev, "Read PDT entry at %#06x failed, code: %d.\n", + PDT_START_SCAN_LOCATION, retval); + return retval; + } + + if (!RMI4_END_OF_PDT(buf[5])) + return 0; + + /* List of known PDT entries per compatible. */ + if (of_device_is_compatible(dev->of_node, "syna,rmi4-s3706b")) { + pdata->pdt_fallback_desc =3D rmi_s3706_fallback_pdt; + pdata->pdt_fallback_size =3D ARRAY_SIZE(rmi_s3706_fallback_pdt); + } else { + dev_err(dev, "First PDT entry is empty and no backup values provided.\n"= ); + return -EINVAL; + } + return 0; } #else -static inline int rmi_driver_of_probe(struct device *dev, - struct rmi_device_platform_data *pdata) +static inline int rmi_driver_of_probe(struct rmi_device *rmi_dev, + struct rmi_device_platform_data *pdata) { return -ENODEV; } #endif =20 int rmi_probe_interrupts(struct rmi_driver_data *data) { struct rmi_device *rmi_dev =3D data->rmi_dev; @@ -1197,17 +1245,17 @@ static int rmi_driver_probe(struct device *dev) =20 rmi_dev =3D to_rmi_device(dev); rmi_driver =3D to_rmi_driver(dev->driver); rmi_dev->driver =3D rmi_driver; =20 pdata =3D rmi_get_platform_data(rmi_dev); =20 if (rmi_dev->xport->dev->of_node) { - retval =3D rmi_driver_of_probe(rmi_dev->xport->dev, pdata); + retval =3D rmi_driver_of_probe(rmi_dev, pdata); if (retval) return retval; } =20 data =3D devm_kzalloc(dev, sizeof(struct rmi_driver_data), GFP_KERNEL); if (!data) return -ENOMEM; =20 diff --git a/drivers/input/rmi4/rmi_driver.h b/drivers/input/rmi4/rmi_drive= r.h index 6de8faed08917..f69337510c333 100644 --- a/drivers/input/rmi4/rmi_driver.h +++ b/drivers/input/rmi4/rmi_driver.h @@ -26,16 +26,18 @@ #define RMI_PDT_PROPS_HAS_BSR 0x02 =20 #define NAME_BUFFER_SIZE 256 =20 #define RMI_PDT_ENTRY_SIZE 6 #define RMI_PDT_FUNCTION_VERSION_MASK 0x60 #define RMI_PDT_INT_SOURCE_COUNT_MASK 0x07 =20 +#define RMI_OF_PDT_DESC_CELLS 2 + #define PDT_START_SCAN_LOCATION 0x00e9 #define PDT_END_SCAN_LOCATION 0x0005 #define RMI4_END_OF_PDT(id) ((id) =3D=3D 0x00 || (id) =3D=3D 0xff) =20 struct pdt_entry { u16 page_start; u8 query_base_addr; u8 command_base_addr; @@ -48,16 +50,17 @@ struct pdt_entry { =20 #define RMI_REG_DESC_PRESENCE_BITS (32 * BITS_PER_BYTE) #define RMI_REG_DESC_PRESENCE_REGS_MAX (3 + RMI_REG_DESC_PRESENCE_BITS / 8) #define RMI_REG_DESC_SUBPACKET_BITS (37 * BITS_PER_BYTE) #define RMI_PDT_MAX 0x55 =20 struct pdt_scan_state { u8 empty_pages; + u8 pdt_count; bool pdts[RMI_PDT_MAX + 1]; }; =20 =20 /* describes a single packet register */ struct rmi_register_desc_item { u32 reg_size; u16 reg; diff --git a/include/linux/rmi.h b/include/linux/rmi.h index ab7eea01ab427..4ba2cefac8558 100644 --- a/include/linux/rmi.h +++ b/include/linux/rmi.h @@ -209,16 +209,19 @@ struct rmi_device_platform_data_spi { * driver waits a few milliseconds to give the firmware a chance to * re-initialize. You can override the default wait period here. * @irq: irq associated with the attn gpio line, or negative */ struct rmi_device_platform_data { int reset_delay_ms; int irq; =20 + unsigned int pdt_fallback_size; + const u8 *pdt_fallback_desc; + struct rmi_device_platform_data_spi spi_data; =20 /* function handler pdata */ struct rmi_2d_sensor_platform_data sensor_pdata; struct rmi_f01_power_management power_management; struct rmi_gpio_data gpio_data; }; =20 --=20 2.53.0