From nobody Wed Dec 17 11:31:57 2025 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id DF883C7618E for ; Thu, 20 Apr 2023 21:04:30 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S231960AbjDTVE3 (ORCPT ); Thu, 20 Apr 2023 17:04:29 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:40938 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S232050AbjDTVEW (ORCPT ); Thu, 20 Apr 2023 17:04:22 -0400 Received: from smtprelay06.ispgateway.de (smtprelay06.ispgateway.de [80.67.18.29]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 91BB544AF; Thu, 20 Apr 2023 14:04:11 -0700 (PDT) Received: from [92.206.161.29] (helo=note-book.lan) by smtprelay06.ispgateway.de with esmtpsa (TLS1.2) tls TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 (Exim 4.94.2) (envelope-from ) id 1ppbRm-0006yb-L2; Thu, 20 Apr 2023 23:04:06 +0200 From: =?utf-8?q?Andr=C3=A9_Apitzsch?= Date: Thu, 20 Apr 2023 23:03:51 +0200 Subject: [PATCH RESEND v2 2/2] Input: atmel_mxt_ts - support capacitive keys MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Message-Id: <20230407-atmel_keys-v2-2-e7b016886109@apitzsch.eu> References: <20230407-atmel_keys-v2-0-e7b016886109@apitzsch.eu> In-Reply-To: <20230407-atmel_keys-v2-0-e7b016886109@apitzsch.eu> To: Nick Dyer , Dmitry Torokhov , Rob Herring , Krzysztof Kozlowski , Nicolas Ferre , Alexandre Belloni , Claudiu Beznea , Linus Walleij Cc: linux-input@vger.kernel.org, devicetree@vger.kernel.org, linux-arm-kernel@lists.infradead.org, linux-kernel@vger.kernel.org, =?utf-8?q?Andr=C3=A9_Apitzsch?= X-Mailer: b4 0.12.2 X-Df-Sender: YW5kcmVAYXBpdHpzY2guZXU= Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Add support for touch keys found in some Atmel touch controller configurations. Reviewed-by: Claudiu Beznea Reviewed-by: Linus Walleij Signed-off-by: Andr=C3=A9 Apitzsch --- drivers/input/touchscreen/atmel_mxt_ts.c | 85 ++++++++++++++++++++++++++++= ++++ 1 file changed, 85 insertions(+) diff --git a/drivers/input/touchscreen/atmel_mxt_ts.c b/drivers/input/touch= screen/atmel_mxt_ts.c index 996bf434e1cb..eb368dd1abf0 100644 --- a/drivers/input/touchscreen/atmel_mxt_ts.c +++ b/drivers/input/touchscreen/atmel_mxt_ts.c @@ -55,6 +55,7 @@ #define MXT_TOUCH_KEYARRAY_T15 15 #define MXT_TOUCH_PROXIMITY_T23 23 #define MXT_TOUCH_PROXKEY_T52 52 +#define MXT_TOUCH_PTC_KEYS_T97 97 #define MXT_PROCI_GRIPFACE_T20 20 #define MXT_PROCG_NOISE_T22 22 #define MXT_PROCI_ONETOUCH_T24 24 @@ -326,9 +327,13 @@ struct mxt_data { u16 T71_address; u8 T9_reportid_min; u8 T9_reportid_max; + u8 T15_reportid_min; + u8 T15_reportid_max; u16 T18_address; u8 T19_reportid; u16 T44_address; + u8 T97_reportid_min; + u8 T97_reportid_max; u8 T100_reportid_min; u8 T100_reportid_max; =20 @@ -344,6 +349,9 @@ struct mxt_data { u32 *t19_keymap; unsigned int t19_num_keys; =20 + u32 *t15_keymap; + unsigned int t15_num_keys; + enum mxt_suspend_mode suspend_mode; =20 u32 wakeup_method; @@ -375,6 +383,7 @@ static bool mxt_object_readable(unsigned int type) case MXT_TOUCH_KEYARRAY_T15: case MXT_TOUCH_PROXIMITY_T23: case MXT_TOUCH_PROXKEY_T52: + case MXT_TOUCH_PTC_KEYS_T97: case MXT_TOUCH_MULTITOUCHSCREEN_T100: case MXT_PROCI_GRIPFACE_T20: case MXT_PROCG_NOISE_T22: @@ -891,6 +900,25 @@ static void mxt_proc_t9_message(struct mxt_data *data,= u8 *message) data->update_input =3D true; } =20 +static void mxt_proc_t15_messages(struct mxt_data *data, u8 *message) +{ + struct input_dev *input_dev =3D data->input_dev; + unsigned long keystates =3D get_unaligned_le32(&message[2]); + int key; + + for (key =3D 0; key < data->t15_num_keys; key++) { + input_report_key(input_dev, data->t15_keymap[key], + !!(keystates & BIT(key))); + } + + data->update_input =3D true; +} + +static void mxt_proc_t97_messages(struct mxt_data *data, u8 *message) +{ + mxt_proc_t15_messages(data, message); +} + static void mxt_proc_t100_message(struct mxt_data *data, u8 *message) { struct device *dev =3D &data->client->dev; @@ -1017,6 +1045,12 @@ static int mxt_proc_message(struct mxt_data *data, u= 8 *message) } else if (report_id >=3D data->T9_reportid_min && report_id <=3D data->T9_reportid_max) { mxt_proc_t9_message(data, message); + } else if (report_id >=3D data->T15_reportid_min && + report_id <=3D data->T15_reportid_max) { + mxt_proc_t15_messages(data, message); + } else if (report_id >=3D data->T97_reportid_min && + report_id <=3D data->T97_reportid_max) { + mxt_proc_t97_messages(data, message); } else if (report_id >=3D data->T100_reportid_min && report_id <=3D data->T100_reportid_max) { mxt_proc_t100_message(data, message); @@ -1689,9 +1723,13 @@ static void mxt_free_object_table(struct mxt_data *d= ata) data->T71_address =3D 0; data->T9_reportid_min =3D 0; data->T9_reportid_max =3D 0; + data->T15_reportid_min =3D 0; + data->T15_reportid_max =3D 0; data->T18_address =3D 0; data->T19_reportid =3D 0; data->T44_address =3D 0; + data->T97_reportid_min =3D 0; + data->T97_reportid_max =3D 0; data->T100_reportid_min =3D 0; data->T100_reportid_max =3D 0; data->max_reportid =3D 0; @@ -1764,6 +1802,10 @@ static int mxt_parse_object_table(struct mxt_data *d= ata, object->num_report_ids - 1; data->num_touchids =3D object->num_report_ids; break; + case MXT_TOUCH_KEYARRAY_T15: + data->T15_reportid_min =3D min_id; + data->T15_reportid_max =3D max_id; + break; case MXT_SPT_COMMSCONFIG_T18: data->T18_address =3D object->start_address; break; @@ -1773,6 +1815,10 @@ static int mxt_parse_object_table(struct mxt_data *d= ata, case MXT_SPT_GPIOPWM_T19: data->T19_reportid =3D min_id; break; + case MXT_TOUCH_PTC_KEYS_T97: + data->T97_reportid_min =3D min_id; + data->T97_reportid_max =3D max_id; + break; case MXT_TOUCH_MULTITOUCHSCREEN_T100: data->multitouch =3D MXT_TOUCH_MULTITOUCHSCREEN_T100; data->T100_reportid_min =3D min_id; @@ -2050,6 +2096,7 @@ static int mxt_initialize_input_device(struct mxt_dat= a *data) int error; unsigned int num_mt_slots; unsigned int mt_flags =3D 0; + int i; =20 switch (data->multitouch) { case MXT_TOUCH_MULTI_T9: @@ -2095,6 +2142,10 @@ static int mxt_initialize_input_device(struct mxt_da= ta *data) input_dev->open =3D mxt_input_open; input_dev->close =3D mxt_input_close; =20 + input_dev->keycode =3D data->t15_keymap; + input_dev->keycodemax =3D data->t15_num_keys; + input_dev->keycodesize =3D sizeof(data->t15_keymap[0]); + input_set_capability(input_dev, EV_KEY, BTN_TOUCH); =20 /* For single touch */ @@ -2162,6 +2213,12 @@ static int mxt_initialize_input_device(struct mxt_da= ta *data) 0, 255, 0, 0); } =20 + /* For T15 and T97 Key Array */ + if (data->T15_reportid_min || data->T97_reportid_min) { + for (i =3D 0; i < data->t15_num_keys; i++) + input_set_capability(input_dev, EV_KEY, data->t15_keymap[i]); + } + input_set_drvdata(input_dev, data); =20 error =3D input_register_device(input_dev); @@ -3080,8 +3137,10 @@ static void mxt_input_close(struct input_dev *dev) static int mxt_parse_device_properties(struct mxt_data *data) { static const char keymap_property[] =3D "linux,gpio-keymap"; + static const char buttons_property[] =3D "linux,keycodes"; struct device *dev =3D &data->client->dev; u32 *keymap; + u32 *buttonmap; int n_keys; int error; =20 @@ -3111,6 +3170,32 @@ static int mxt_parse_device_properties(struct mxt_da= ta *data) data->t19_num_keys =3D n_keys; } =20 + if (device_property_present(dev, buttons_property)) { + n_keys =3D device_property_count_u32(dev, buttons_property); + if (n_keys <=3D 0) { + error =3D n_keys < 0 ? n_keys : -EINVAL; + dev_err(dev, "invalid/malformed '%s' property: %d\n", + buttons_property, error); + return error; + } + + buttonmap =3D devm_kmalloc_array(dev, n_keys, sizeof(*buttonmap), + GFP_KERNEL); + if (!buttonmap) + return -ENOMEM; + + error =3D device_property_read_u32_array(dev, buttons_property, + buttonmap, n_keys); + if (error) { + dev_err(dev, "failed to parse '%s' property: %d\n", + buttons_property, error); + return error; + } + + data->t15_keymap =3D buttonmap; + data->t15_num_keys =3D n_keys; + } + return 0; } =20 --=20 2.40.0