Received: by 2002:a05:6358:5282:b0:b5:90e7:25cb with SMTP id g2csp3321947rwa; Tue, 23 Aug 2022 02:48:35 -0700 (PDT) X-Google-Smtp-Source: AA6agR7+eMkwwLYgCY6fTxp/Tn5B5K1n329vxEC11BKXlp4T7uCJ4Dy0D3pVUmUo+E2+37cROxP7 X-Received: by 2002:a17:902:ecce:b0:16e:e6e9:69ba with SMTP id a14-20020a170902ecce00b0016ee6e969bamr24322735plh.97.1661248115150; Tue, 23 Aug 2022 02:48:35 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1661248115; cv=none; d=google.com; s=arc-20160816; b=s/QIRh6r4vklC+CXthlRpnehgqyUDNXcVSiuGMXlVPSyb6hU7rui7rwKBGRRFIfBHY uaBRbd6UJ8rIsF3qi8ZsfkiNeWvItYcKD+S03CGZdos59E2v6y1Kq8AMYnv+hCVMCjJ0 Motc5eRenLYhR8FIbNLjmYC6xGMW/ooQ5WodHjuHCvRoIamNEEA2xthRV6J6rXo31ZTI LXOXf5QI5cJcVINB+e37wKxMEs1yVc/hqYzmH/RW8n9T85n0DRLma59JB0dNjJDAwg/7 LQdiYkCOPEtM1fN94d4y5S8gDmcWF8UlEyEhi0OqRYgMerDs/EoGU0fSbZKOpM4MBBNa r8Fg== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:content-transfer-encoding:mime-version :user-agent:references:in-reply-to:message-id:date:subject:cc:to :from:dkim-signature; bh=tkUlaQu9GnDnuXBylTFLvYD7m3T9ytMwRP2BCrQDbbM=; b=d4FvqwbbW00QuEsvN4jJd8TNwc3V829Ao1x20DgSbyr3rb7nttgx2+CQxKp2+H96h6 bHeJNhRkF1y65+3yHr6Hoxz4ngVFbd07Exj3FgdpqR30SthAFl9O+219TjBwuoTUIrVR km4IhQg6y5s8U1Vp3w1YP+t3X1t0F+8NHTTkb3uvKmFbtc8uPYjKmfMTruRyITbhbW4+ 5Y2NGaTv5X9vvl6X0JpcU2Oq9SnP7RLXv2wZq+YUw+jIcSSbP1CgkK5RoDrzTTMsf08f RfakJz3Ro+TCjp44zsTNF7o/ACDSXoXYBVNxnfWew1pfEjbQFt8fEUnn9oHtiKCKz6s4 A7TQ== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@linuxfoundation.org header.s=korg header.b=U+sy+wgX; 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; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=linuxfoundation.org Return-Path: Received: from out1.vger.email (out1.vger.email. [2620:137:e000::1:20]) by mx.google.com with ESMTP id gb5-20020a17090b060500b001fae363bebfsi7582037pjb.142.2022.08.23.02.48.24; Tue, 23 Aug 2022 02:48:35 -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; dkim=pass header.i=@linuxfoundation.org header.s=korg header.b=U+sy+wgX; 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; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=linuxfoundation.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S243407AbiHWI1H (ORCPT + 99 others); Tue, 23 Aug 2022 04:27:07 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:34140 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S243727AbiHWIVh (ORCPT ); Tue, 23 Aug 2022 04:21:37 -0400 Received: from ams.source.kernel.org (ams.source.kernel.org [IPv6:2604:1380:4601:e00::1]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 16C1C6B64B; Tue, 23 Aug 2022 01:12:56 -0700 (PDT) Received: from smtp.kernel.org (relay.kernel.org [52.25.139.140]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ams.source.kernel.org (Postfix) with ESMTPS id 2B7A0B81C21; Tue, 23 Aug 2022 08:12:51 +0000 (UTC) Received: by smtp.kernel.org (Postfix) with ESMTPSA id 8BBD8C433C1; Tue, 23 Aug 2022 08:12:49 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=linuxfoundation.org; s=korg; t=1661242369; bh=Sp/PKn2N+G/yihFkstUdpOykzSfSeZinpiz0MriimTc=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=U+sy+wgXLgkQZg6Dfc+KT17iBuptV8TOWbKn9ylw3wWpY4zoKcqzp1UqkjHDxx6qQ h05lPSDKd5K5yguJjkRrZaAsxUQe9bHBCpO/kuJegBtJocS8XSwePj17o0i/RxgtO3 rN+dy1Eo/llb+CflBNxpDHblNbU/J2SLd3pZmKow= From: Greg Kroah-Hartman To: linux-kernel@vger.kernel.org Cc: Greg Kroah-Hartman , stable@vger.kernel.org, Jeff LaBundy , Dmitry Torokhov Subject: [PATCH 5.19 105/365] Input: iqs7222 - fortify slider event reporting Date: Tue, 23 Aug 2022 10:00:06 +0200 Message-Id: <20220823080122.584732753@linuxfoundation.org> X-Mailer: git-send-email 2.37.2 In-Reply-To: <20220823080118.128342613@linuxfoundation.org> References: <20220823080118.128342613@linuxfoundation.org> User-Agent: quilt/0.67 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-Spam-Status: No, score=-7.1 required=5.0 tests=BAYES_00,DKIMWL_WL_HIGH, DKIM_SIGNED,DKIM_VALID,DKIM_VALID_AU,DKIM_VALID_EF,RCVD_IN_DNSWL_HI, SPF_HELO_NONE,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 From: Jeff LaBundy commit 95215d3d19c5b47b8ccef8cb61c9dcd17ac7a669 upstream. The release cycle of any key mapped to a slider gesture relies upon trailing interrupts generated by other unmasked sources, the timing and presence of which are inconsistent. To solve this problem, explicitly report a release cycle to emulate a full keystroke. Also, unmask touch interrupts if the slider press event is defined; this ensures the device reports a final interrupt with coordinate = 0xFFFF once the finger is lifted. As a result of how the logic has been refactored, the press/release event can now be mapped to a GPIO. This is more convenient than the previous solution, which required each channel within the slider to specify the same GPIO. As part of this change, use the device's resolution rather than its number of interrupt status registers to more safely determine if it is capable of reporting gestures. Last but not least, make the code a bit simpler by eliminating some unnecessarily complex conditional statements and a macro that could be derived using information that is already available. Fixes: e505edaedcb9 ("Input: add support for Azoteq IQS7222A/B/C") Signed-off-by: Jeff LaBundy Link: https://lore.kernel.org/r/20220626072412.475211-3-jeff@labundy.com Signed-off-by: Dmitry Torokhov Signed-off-by: Greg Kroah-Hartman --- drivers/input/misc/iqs7222.c | 96 ++++++++++++++++++++++-------------- 1 file changed, 58 insertions(+), 38 deletions(-) diff --git a/drivers/input/misc/iqs7222.c b/drivers/input/misc/iqs7222.c index 53df74f3a982..57616a7ebeae 100644 --- a/drivers/input/misc/iqs7222.c +++ b/drivers/input/misc/iqs7222.c @@ -40,7 +40,6 @@ #define IQS7222_SLDR_SETUP_2_RES_MASK GENMASK(15, 8) #define IQS7222_SLDR_SETUP_2_RES_SHIFT 8 #define IQS7222_SLDR_SETUP_2_TOP_SPEED_MASK GENMASK(7, 0) -#define IQS7222_SLDR_SETUP_3_CHAN_SEL_MASK GENMASK(9, 0) #define IQS7222_GPIO_SETUP_0_GPIO_EN BIT(0) @@ -54,6 +53,9 @@ #define IQS7222_SYS_SETUP_ACK_RESET BIT(0) #define IQS7222_EVENT_MASK_ATI BIT(12) +#define IQS7222_EVENT_MASK_SLDR BIT(10) +#define IQS7222_EVENT_MASK_TOUCH BIT(1) +#define IQS7222_EVENT_MASK_PROX BIT(0) #define IQS7222_COMMS_HOLD BIT(0) #define IQS7222_COMMS_ERROR 0xEEEE @@ -135,12 +137,12 @@ struct iqs7222_event_desc { static const struct iqs7222_event_desc iqs7222_kp_events[] = { { .name = "event-prox", - .enable = BIT(0), + .enable = IQS7222_EVENT_MASK_PROX, .reg_key = IQS7222_REG_KEY_PROX, }, { .name = "event-touch", - .enable = BIT(1), + .enable = IQS7222_EVENT_MASK_TOUCH, .reg_key = IQS7222_REG_KEY_TOUCH, }, }; @@ -1957,8 +1959,8 @@ static int iqs7222_parse_sldr(struct iqs7222_private *iqs7222, int sldr_index) int num_chan = dev_desc->reg_grps[IQS7222_REG_GRP_CHAN].num_row; int ext_chan = rounddown(num_chan, 10); int count, error, reg_offset, i; + u16 *event_mask = &iqs7222->sys_setup[dev_desc->event_offset]; u16 *sldr_setup = iqs7222->sldr_setup[sldr_index]; - u16 *sys_setup = iqs7222->sys_setup; unsigned int chan_sel[4], val; error = iqs7222_parse_props(iqs7222, &sldr_node, sldr_index, @@ -2003,7 +2005,7 @@ static int iqs7222_parse_sldr(struct iqs7222_private *iqs7222, int sldr_index) reg_offset = dev_desc->sldr_res < U16_MAX ? 0 : 1; sldr_setup[0] |= count; - sldr_setup[3 + reg_offset] &= ~IQS7222_SLDR_SETUP_3_CHAN_SEL_MASK; + sldr_setup[3 + reg_offset] &= ~GENMASK(ext_chan - 1, 0); for (i = 0; i < ARRAY_SIZE(chan_sel); i++) { sldr_setup[5 + reg_offset + i] = 0; @@ -2106,6 +2108,22 @@ static int iqs7222_parse_sldr(struct iqs7222_private *iqs7222, int sldr_index) if (error) return error; + /* + * The press/release event does not expose a direct GPIO link, + * but one can be emulated by tying each of the participating + * channels to the same GPIO. + */ + error = iqs7222_gpio_select(iqs7222, event_node, + i ? iqs7222_sl_events[i].enable + : sldr_setup[3 + reg_offset], + i ? 1568 + sldr_index * 30 + : sldr_setup[4 + reg_offset]); + if (error) + return error; + + if (!reg_offset) + sldr_setup[9] |= iqs7222_sl_events[i].enable; + error = fwnode_property_read_u32(event_node, "linux,code", &val); if (error) { @@ -2117,26 +2135,20 @@ static int iqs7222_parse_sldr(struct iqs7222_private *iqs7222, int sldr_index) iqs7222->sl_code[sldr_index][i] = val; input_set_capability(iqs7222->keypad, EV_KEY, val); - /* - * The press/release event is determined based on whether the - * coordinate field reports 0xFFFF and has no explicit enable - * control. - */ - if (!iqs7222_sl_events[i].enable || reg_offset) - continue; - - sldr_setup[9] |= iqs7222_sl_events[i].enable; - - error = iqs7222_gpio_select(iqs7222, event_node, - iqs7222_sl_events[i].enable, - 1568 + sldr_index * 30); - if (error) - return error; - if (!dev_desc->event_offset) continue; - sys_setup[dev_desc->event_offset] |= BIT(10 + sldr_index); + /* + * The press/release event is determined based on whether the + * coordinate field reports 0xFFFF and solely relies on touch + * or proximity interrupts to be unmasked. + */ + if (i && !reg_offset) + *event_mask |= (IQS7222_EVENT_MASK_SLDR << sldr_index); + else if (sldr_setup[4 + reg_offset] == dev_desc->touch_link) + *event_mask |= IQS7222_EVENT_MASK_TOUCH; + else + *event_mask |= IQS7222_EVENT_MASK_PROX; } /* @@ -2301,29 +2313,37 @@ static int iqs7222_report(struct iqs7222_private *iqs7222) input_report_abs(iqs7222->keypad, iqs7222->sl_axis[i], sldr_pos); - for (j = 0; j < ARRAY_SIZE(iqs7222_sl_events); j++) { - u16 mask = iqs7222_sl_events[j].mask; - u16 val = iqs7222_sl_events[j].val; + input_report_key(iqs7222->keypad, iqs7222->sl_code[i][0], + sldr_pos < dev_desc->sldr_res); - if (!iqs7222_sl_events[j].enable) { - input_report_key(iqs7222->keypad, - iqs7222->sl_code[i][j], - sldr_pos < dev_desc->sldr_res); - continue; - } + /* + * A maximum resolution indicates the device does not support + * gestures, in which case the remaining fields are ignored. + */ + if (dev_desc->sldr_res == U16_MAX) + continue; - /* - * The remaining offsets represent gesture state, and - * are discarded in the case of IQS7222C because only - * absolute position is reported. - */ - if (num_stat < IQS7222_MAX_COLS_STAT) - continue; + if (!(le16_to_cpu(status[1]) & IQS7222_EVENT_MASK_SLDR << i)) + continue; + + /* + * Skip the press/release event, as it does not have separate + * status fields and is handled separately. + */ + for (j = 1; j < ARRAY_SIZE(iqs7222_sl_events); j++) { + u16 mask = iqs7222_sl_events[j].mask; + u16 val = iqs7222_sl_events[j].val; input_report_key(iqs7222->keypad, iqs7222->sl_code[i][j], (state & mask) == val); } + + input_sync(iqs7222->keypad); + + for (j = 1; j < ARRAY_SIZE(iqs7222_sl_events); j++) + input_report_key(iqs7222->keypad, + iqs7222->sl_code[i][j], 0); } input_sync(iqs7222->keypad); -- 2.37.2