From patchwork Thu Apr 20 21:03:51 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: =?utf-8?q?Andr=C3=A9_Apitzsch?= X-Patchwork-Id: 86041 Return-Path: Delivered-To: ouuuleilei@gmail.com Received: by 2002:a59:b0ea:0:b0:3b6:4342:cba0 with SMTP id b10csp622235vqo; Thu, 20 Apr 2023 14:18:29 -0700 (PDT) X-Google-Smtp-Source: AKy350blxspEu/RzvKPyWPhh/6TT10RelEpgpuoz2+uP61MWkBPxYebRGXCTuUCwK0HC07qM1awE X-Received: by 2002:a05:6a20:d2ca:b0:d6:c92:9925 with SMTP id ir10-20020a056a20d2ca00b000d60c929925mr3775766pzb.31.1682025509632; Thu, 20 Apr 2023 14:18:29 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1682025509; cv=none; d=google.com; s=arc-20160816; b=ctWBlcXAn3QgXOy7G7DE6M4Ply9cScEqHvhrF9DqqHZi6791pFlSePr0VnIziLIRAn VpklR1Z9MpMlM78mNMFnisl5XrCrgxErPKfa+y0FpD9dxcia4+0aB/sSjnjKsYecL5DQ QOFOrueOmVZ8EcNqahNXISrRhTSdeB/i97Ba2WVI/ezVvRBgSskRum45WynyxyOXjhoB KnXNKeis+J5Y2H6ENhN5OZxjxXFaLanXvDU9e/REhRuNEdQYJ4jqfwG0X5LPdjP404qU nc7fOtBVfF/ZnYeiV1jkDWTgzEvbohi0CfNoYY3EhBiJEE1nN9Xql2bhtQsKyLniSXp6 qxHA== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:cc:to:in-reply-to:references:message-id :content-transfer-encoding:mime-version:subject:date:from; bh=IXMLtxaY9EiusYakPgKrV7my+emTLCXw2FIgbQbFQgI=; b=MVYcS6CNxGVIZVYvbsJJqBHLpiQcwHYY9dr5HsMOiMePJdHzgSJfvzu84V33oMsxTu yWQ0LJL91S9r8a8ANCXjGoR2KK/2ffSRTI3eJuWugLOO/mRmqKB8Ca9QXLjtT4L9yv4g ALecjLSYoUTF7oyUnE2qdv7KQp99NkQtGFpreF5Ih+ph/qduKQIeaPyjxCbd3wVVbr4Z 4pXkNOR7C3Fu7a25/AD0E+NWh8Qe1k3rnTivSBYzifiP7a8TriMVOOgKe+JM/HKg3eIh Tm/7l26GhfijBTByP3OR1zoQfrVcppSCfj9ZTnmUbuZ4HtQ29v6d3TLh48ZT+hDNS3sV 2eSg== ARC-Authentication-Results: i=1; mx.google.com; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org Received: from out1.vger.email (out1.vger.email. [2620:137:e000::1:20]) by mx.google.com with ESMTP id i7-20020a654847000000b0051b1542d6efsi2508290pgs.213.2023.04.20.14.18.14; Thu, 20 Apr 2023 14:18:29 -0700 (PDT) Received-SPF: pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) client-ip=2620:137:e000::1:20; Authentication-Results: mx.google.com; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S232030AbjDTVE2 (ORCPT + 99 others); Thu, 20 Apr 2023 17:04:28 -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 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= X-Spam-Status: No, score=-1.9 required=5.0 tests=BAYES_00,RCVD_IN_DNSWL_NONE, RCVD_IN_MSPIKE_H2,SPF_HELO_PASS,SPF_PASS,T_SCC_BODY_TEXT_LINE autolearn=ham autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on lindbergh.monkeyblade.net Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org X-getmail-retrieved-from-mailbox: =?utf-8?q?INBOX?= X-GMAIL-THRID: =?utf-8?q?1763731580571041419?= X-GMAIL-MSGID: =?utf-8?q?1763731580571041419?= Add support for touch keys found in some Atmel touch controller configurations. Reviewed-by: Claudiu Beznea Reviewed-by: Linus Walleij Signed-off-by: André 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/touchscreen/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; @@ -344,6 +349,9 @@ struct mxt_data { u32 *t19_keymap; unsigned int t19_num_keys; + u32 *t15_keymap; + unsigned int t15_num_keys; + enum mxt_suspend_mode suspend_mode; 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 = true; } +static void mxt_proc_t15_messages(struct mxt_data *data, u8 *message) +{ + struct input_dev *input_dev = data->input_dev; + unsigned long keystates = get_unaligned_le32(&message[2]); + int key; + + for (key = 0; key < data->t15_num_keys; key++) { + input_report_key(input_dev, data->t15_keymap[key], + !!(keystates & BIT(key))); + } + + data->update_input = 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 = &data->client->dev; @@ -1017,6 +1045,12 @@ static int mxt_proc_message(struct mxt_data *data, u8 *message) } else if (report_id >= data->T9_reportid_min && report_id <= data->T9_reportid_max) { mxt_proc_t9_message(data, message); + } else if (report_id >= data->T15_reportid_min && + report_id <= data->T15_reportid_max) { + mxt_proc_t15_messages(data, message); + } else if (report_id >= data->T97_reportid_min && + report_id <= data->T97_reportid_max) { + mxt_proc_t97_messages(data, message); } else if (report_id >= data->T100_reportid_min && report_id <= data->T100_reportid_max) { mxt_proc_t100_message(data, message); @@ -1689,9 +1723,13 @@ static void mxt_free_object_table(struct mxt_data *data) data->T71_address = 0; data->T9_reportid_min = 0; data->T9_reportid_max = 0; + data->T15_reportid_min = 0; + data->T15_reportid_max = 0; data->T18_address = 0; data->T19_reportid = 0; data->T44_address = 0; + data->T97_reportid_min = 0; + data->T97_reportid_max = 0; data->T100_reportid_min = 0; data->T100_reportid_max = 0; data->max_reportid = 0; @@ -1764,6 +1802,10 @@ static int mxt_parse_object_table(struct mxt_data *data, object->num_report_ids - 1; data->num_touchids = object->num_report_ids; break; + case MXT_TOUCH_KEYARRAY_T15: + data->T15_reportid_min = min_id; + data->T15_reportid_max = max_id; + break; case MXT_SPT_COMMSCONFIG_T18: data->T18_address = object->start_address; break; @@ -1773,6 +1815,10 @@ static int mxt_parse_object_table(struct mxt_data *data, case MXT_SPT_GPIOPWM_T19: data->T19_reportid = min_id; break; + case MXT_TOUCH_PTC_KEYS_T97: + data->T97_reportid_min = min_id; + data->T97_reportid_max = max_id; + break; case MXT_TOUCH_MULTITOUCHSCREEN_T100: data->multitouch = MXT_TOUCH_MULTITOUCHSCREEN_T100; data->T100_reportid_min = min_id; @@ -2050,6 +2096,7 @@ static int mxt_initialize_input_device(struct mxt_data *data) int error; unsigned int num_mt_slots; unsigned int mt_flags = 0; + int i; switch (data->multitouch) { case MXT_TOUCH_MULTI_T9: @@ -2095,6 +2142,10 @@ static int mxt_initialize_input_device(struct mxt_data *data) input_dev->open = mxt_input_open; input_dev->close = mxt_input_close; + input_dev->keycode = data->t15_keymap; + input_dev->keycodemax = data->t15_num_keys; + input_dev->keycodesize = sizeof(data->t15_keymap[0]); + input_set_capability(input_dev, EV_KEY, BTN_TOUCH); /* For single touch */ @@ -2162,6 +2213,12 @@ static int mxt_initialize_input_device(struct mxt_data *data) 0, 255, 0, 0); } + /* For T15 and T97 Key Array */ + if (data->T15_reportid_min || data->T97_reportid_min) { + for (i = 0; i < data->t15_num_keys; i++) + input_set_capability(input_dev, EV_KEY, data->t15_keymap[i]); + } + input_set_drvdata(input_dev, data); error = 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[] = "linux,gpio-keymap"; + static const char buttons_property[] = "linux,keycodes"; struct device *dev = &data->client->dev; u32 *keymap; + u32 *buttonmap; int n_keys; int error; @@ -3111,6 +3170,32 @@ static int mxt_parse_device_properties(struct mxt_data *data) data->t19_num_keys = n_keys; } + if (device_property_present(dev, buttons_property)) { + n_keys = device_property_count_u32(dev, buttons_property); + if (n_keys <= 0) { + error = n_keys < 0 ? n_keys : -EINVAL; + dev_err(dev, "invalid/malformed '%s' property: %d\n", + buttons_property, error); + return error; + } + + buttonmap = devm_kmalloc_array(dev, n_keys, sizeof(*buttonmap), + GFP_KERNEL); + if (!buttonmap) + return -ENOMEM; + + error = 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 = buttonmap; + data->t15_num_keys = n_keys; + } + return 0; }