Received: by 2002:a25:c593:0:0:0:0:0 with SMTP id v141csp2085043ybe; Tue, 3 Sep 2019 07:47:53 -0700 (PDT) X-Google-Smtp-Source: APXvYqzFurFGepNckfccChIqzGbqjXgZcDHZF07jhQadVdEuwGdTfXAA8V67+pT7TxfrqIcjs6x3 X-Received: by 2002:a62:26c4:: with SMTP id m187mr42058437pfm.49.1567522073605; Tue, 03 Sep 2019 07:47:53 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1567522073; cv=none; d=google.com; s=arc-20160816; b=QUSpHZHaHnEE9oWrcVTM14N8p2CfzdvGo/iLAaux68iuvLKtId/ZPc4PXj7LWcs3yp krBy7Lh7IZWf+KefJ79t/tDVl9Lj0L8lVtBYzcXc+jX6oWIB8/SZ1UXLgd0NtwUvybjV 8MHeJYdF5fhwRzuJdZIxFuj+Z0KdPLY+stLh3Vf4ioaQ4/yexwyOl/UrbCqO64XiIlhw lqVGu7cRdcLVldVVc/vpSbWBfEEFD4uiBUZ0oFjkvtXNRnKJzePm1ALXHZtWbhWeHehf WtdRFyHYuRaIaIGD9iCCCABVX7qe57oDokSTDd8Js+GLM2VoeottJW/GK6cQnQtbnTHj FVkw== 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 :message-id:date:subject:cc:to:from; bh=iSxylVWkEUHxudj+tccsJFuI5S8Mya6czB7/Azy93K8=; b=AYXBd5Mq79xjKJGudc1kt8VdmY0d2Zfl/vOUsPpWq7IPVuyrT5Zmz2ajPK9sxAFBzF LipM4dEdc+fP6fnIkPgy2YKuj26GrfyP4jqrvMS7Ybi3eAUlbyE2W9nZIz7ANd9gXZ3c 3dTlA3cqVtz30jaYcMODEB2dGbyjN5v9huNw2MQh9W7gMIFfZw7E4nZgXWAHfhi41/bG 0qXrzjpFOiwQlTN/tN/ddbcj2atpIsTz6jbnqGd8bASy4Daw3ivczr0z5TnmuXKoDqEY BK6D2nm//46xctbGcUzLbCGlq/uZGXOC9gZHgr1RgMIs5kI0BfaKpR7YlQSUSkKotWFv Dh0A== ARC-Authentication-Results: i=1; mx.google.com; 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=fail (p=NONE sp=NONE dis=NONE) header.from=redhat.com Return-Path: Received: from vger.kernel.org (vger.kernel.org. [209.132.180.67]) by mx.google.com with ESMTP id g13si15690579pgr.297.2019.09.03.07.47.37; Tue, 03 Sep 2019 07:47:53 -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; 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=fail (p=NONE sp=NONE dis=NONE) header.from=redhat.com Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1729578AbfICOql (ORCPT + 99 others); Tue, 3 Sep 2019 10:46:41 -0400 Received: from mx1.redhat.com ([209.132.183.28]:28043 "EHLO mx1.redhat.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1725782AbfICOqk (ORCPT ); Tue, 3 Sep 2019 10:46:40 -0400 Received: from smtp.corp.redhat.com (int-mx03.intmail.prod.int.phx2.redhat.com [10.5.11.13]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mx1.redhat.com (Postfix) with ESMTPS id 6574B31752AF; Tue, 3 Sep 2019 14:46:40 +0000 (UTC) Received: from plouf.redhat.com (ovpn-204-26.brq.redhat.com [10.40.204.26]) by smtp.corp.redhat.com (Postfix) with ESMTP id 4FF8160606; Tue, 3 Sep 2019 14:46:34 +0000 (UTC) From: Benjamin Tissoires To: Joao Moreno , Jiri Kosina Cc: linux-input@vger.kernel.org, linux-kernel@vger.kernel.org, Benjamin Tissoires Subject: [PATCH v2] HID: apple: Fix stuck function keys when using FN Date: Tue, 3 Sep 2019 16:46:32 +0200 Message-Id: <20190903144632.26299-1-benjamin.tissoires@redhat.com> MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Scanned-By: MIMEDefang 2.79 on 10.5.11.13 X-Greylist: Sender IP whitelisted, not delayed by milter-greylist-4.5.16 (mx1.redhat.com [10.5.110.49]); Tue, 03 Sep 2019 14:46:40 +0000 (UTC) Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org From: Joao Moreno 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 --- Hi Joao, last chance to pull back :) If you are still happy, I'll push this version Cheers, Benjamin 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 81df62f48c4c..6ac8becc2372 100644 --- a/drivers/hid/hid-apple.c +++ b/drivers/hid/hid-apple.c @@ -54,7 +54,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); }; @@ -181,6 +180,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; @@ -189,8 +190,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; @@ -202,25 +201,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.19.2