Received: by 2002:a25:824b:0:0:0:0:0 with SMTP id d11csp6022163ybn; Sun, 29 Sep 2019 10:37:50 -0700 (PDT) X-Google-Smtp-Source: APXvYqwLzvrtEKpJxL/nZD+GzG5AEQOLU2qTL9I03+WTOK6HMBOW9XJXLIEmBuGqkGESr9F4pOT1 X-Received: by 2002:a05:6402:651:: with SMTP id u17mr15873973edx.104.1569778670180; Sun, 29 Sep 2019 10:37:50 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1569778670; cv=none; d=google.com; s=arc-20160816; b=ylzkxlDDyfWjWTE7MFpo58WKj/RO3huwh2KaUv7S86aQSWfgHfNZTGWSdptfeyARkH z88lVtieNyjqquM0nMtwAnzP8Qiv7R2bxw4pWwFZvnTbsuUhIsme6mHnNUvnbpDILGOE N0ZtPxgU7jw9d23Pq0GZMWdpxXzduwGnDxm9hdSbjFaPP+7uhqHoezX6Dy6797SjN4P5 DvhPMvExBeI4Ubh/+oFjy8NepBZATGqO4wkyby8dLvDCdnaKGtFPKMLMBmelDTSCaiMx 8OCJfzmj8goEjpd0DJcDJFXMeQZ1kNg8Qb4wZbjYBMqdq+sl5lipl8BGmHGiXqqhAaQK DcMA== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:sender:content-transfer-encoding:mime-version :references:in-reply-to:message-id:date:subject:cc:to:from :dkim-signature; bh=vOPPaW0QXMKmLm58fA+RaNRRDLRhQo6WBtUQ9NOS9Gw=; b=MTGswjpwQqYfDswhbaL9bDNXPQqtxBRpbDIdhIfNX9A9Ig3eC+y3xtIUsv1xebn5cR b1IS4ls+qyNw/GoOuzBZGlXJ2aJT0iEV1Js+jIKxLEBMPQhJQ5gbYacS9s42t+Fhoub/ eivtWTwzk4KoxuwbCaj7HwTaJej6a9UhRaUBI7F69EeHnim+UH+0MGBGHGWM6uyMU5+2 J+O+tn5RJFbuYfPIAndb8Abz2XlKfrnYDMyv9kM8zJAIxV9Jyc+imAPVvXNeImvquG0E TqUjy+Rs/9Lfb4o/G6BOpohD01fCm/2g83mYRDcORRuGEKhlnE47zDZUeyjq/4QGCG7o 1QUg== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@kernel.org header.s=default header.b=bUFRnF4P; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=kernel.org Return-Path: Received: from vger.kernel.org (vger.kernel.org. [209.132.180.67]) by mx.google.com with ESMTP id si9si6064371ejb.97.2019.09.29.10.37.26; Sun, 29 Sep 2019 10:37:50 -0700 (PDT) Received-SPF: pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) client-ip=209.132.180.67; Authentication-Results: mx.google.com; dkim=pass header.i=@kernel.org header.s=default header.b=bUFRnF4P; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=kernel.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1729357AbfI2RfF (ORCPT + 99 others); Sun, 29 Sep 2019 13:35:05 -0400 Received: from mail.kernel.org ([198.145.29.99]:47026 "EHLO mail.kernel.org" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1730481AbfI2Re4 (ORCPT ); Sun, 29 Sep 2019 13:34:56 -0400 Received: from sasha-vm.mshome.net (c-73-47-72-35.hsd1.nh.comcast.net [73.47.72.35]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPSA id 33D0621A4C; Sun, 29 Sep 2019 17:34:54 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=default; t=1569778494; bh=loZr7MLJpU4XU6TOPh2BVQXDVFm5QAyJaqArvekhQzo=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=bUFRnF4P4fuaR1jUgNIXB0AdfwlU8WC5R4zK6ZLuP7cTreFGBtWQJWIFWj49hJZ/5 WOCsDmhsM6RJTyKQYGrKkQEvHIZSY6a8kkxwM58cwjyrfFCRWTWkGRo0kyOlr1Qv+u qQumsquvdnSqGxvBAckZprPb1adBdRwbR5s/CT9c= From: Sasha Levin To: linux-kernel@vger.kernel.org, stable@vger.kernel.org Cc: Joao Moreno , Benjamin Tissoires , Sasha Levin , linux-input@vger.kernel.org Subject: [PATCH AUTOSEL 4.19 16/33] HID: apple: Fix stuck function keys when using FN Date: Sun, 29 Sep 2019 13:34:04 -0400 Message-Id: <20190929173424.9361-16-sashal@kernel.org> X-Mailer: git-send-email 2.20.1 In-Reply-To: <20190929173424.9361-1-sashal@kernel.org> References: <20190929173424.9361-1-sashal@kernel.org> MIME-Version: 1.0 X-stable: review X-Patchwork-Hint: Ignore Content-Transfer-Encoding: 8bit Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org From: Joao Moreno [ Upstream commit aec256d0ecd561036f188dbc8fa7924c47a9edfd ] This fixes an issue in which key down events for function keys would be repeatedly emitted even after the user has raised the physical key. For example, the driver fails to emit the F5 key up event when going through the following steps: - fnmode=1: hold FN, hold F5, release FN, release F5 - fnmode=2: hold F5, hold FN, release F5, release FN The repeated F5 key down events can be easily verified using xev. Signed-off-by: Joao Moreno Co-developed-by: Benjamin Tissoires Signed-off-by: Benjamin Tissoires Signed-off-by: Sasha Levin --- drivers/hid/hid-apple.c | 49 +++++++++++++++++++++++------------------ 1 file changed, 28 insertions(+), 21 deletions(-) diff --git a/drivers/hid/hid-apple.c b/drivers/hid/hid-apple.c index 1cb41992aaa1f..d0a81a03ddbdd 100644 --- a/drivers/hid/hid-apple.c +++ b/drivers/hid/hid-apple.c @@ -57,7 +57,6 @@ MODULE_PARM_DESC(swap_opt_cmd, "Swap the Option (\"Alt\") and Command (\"Flag\") struct apple_sc { unsigned long quirks; unsigned int fn_on; - DECLARE_BITMAP(pressed_fn, KEY_CNT); DECLARE_BITMAP(pressed_numlock, KEY_CNT); }; @@ -184,6 +183,8 @@ static int hidinput_apple_event(struct hid_device *hid, struct input_dev *input, { struct apple_sc *asc = hid_get_drvdata(hid); const struct apple_key_translation *trans, *table; + bool do_translate; + u16 code = 0; if (usage->code == KEY_FN) { asc->fn_on = !!value; @@ -192,8 +193,6 @@ static int hidinput_apple_event(struct hid_device *hid, struct input_dev *input, } if (fnmode) { - int do_translate; - if (hid->product >= USB_DEVICE_ID_APPLE_WELLSPRING4_ANSI && hid->product <= USB_DEVICE_ID_APPLE_WELLSPRING4A_JIS) table = macbookair_fn_keys; @@ -205,25 +204,33 @@ static int hidinput_apple_event(struct hid_device *hid, struct input_dev *input, trans = apple_find_translation (table, usage->code); if (trans) { - if (test_bit(usage->code, asc->pressed_fn)) - do_translate = 1; - else if (trans->flags & APPLE_FLAG_FKEY) - do_translate = (fnmode == 2 && asc->fn_on) || - (fnmode == 1 && !asc->fn_on); - else - do_translate = asc->fn_on; - - if (do_translate) { - if (value) - set_bit(usage->code, asc->pressed_fn); - else - clear_bit(usage->code, asc->pressed_fn); - - input_event(input, usage->type, trans->to, - value); - - return 1; + if (test_bit(trans->from, input->key)) + code = trans->from; + else if (test_bit(trans->to, input->key)) + code = trans->to; + + if (!code) { + if (trans->flags & APPLE_FLAG_FKEY) { + switch (fnmode) { + case 1: + do_translate = !asc->fn_on; + break; + case 2: + do_translate = asc->fn_on; + break; + default: + /* should never happen */ + do_translate = false; + } + } else { + do_translate = asc->fn_on; + } + + code = do_translate ? trans->to : trans->from; } + + input_event(input, usage->type, code, value); + return 1; } if (asc->quirks & APPLE_NUMLOCK_EMULATION && -- 2.20.1