From patchwork Sat Aug 17 11:47:29 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Aditya Garg X-Patchwork-Id: 13767169 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 gabe.freedesktop.org (gabe.freedesktop.org [131.252.210.177]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.lore.kernel.org (Postfix) with ESMTPS id 5E98AC52D7F for ; Sat, 17 Aug 2024 11:47:37 +0000 (UTC) Received: from gabe.freedesktop.org (localhost [127.0.0.1]) by gabe.freedesktop.org (Postfix) with ESMTP id D13AA10E08E; Sat, 17 Aug 2024 11:47:36 +0000 (UTC) Authentication-Results: gabe.freedesktop.org; dkim=pass (2048-bit key; unprotected) header.d=live.com header.i=@live.com header.b="d/W5kU1K"; dkim-atps=neutral Received: from IND01-MAX-obe.outbound.protection.outlook.com (mail-maxind01olkn2011.outbound.protection.outlook.com [40.92.102.11]) by gabe.freedesktop.org (Postfix) with ESMTPS id 9026410E08E for ; Sat, 17 Aug 2024 11:47:35 +0000 (UTC) ARC-Seal: i=1; a=rsa-sha256; s=arcselector10001; d=microsoft.com; cv=none; b=OpQnoYk1AY3wRIJOazhxvEIwfSZIBxhGPw9f7BjpxHoqFFQPU/Q75iWY+bjnr4AbosNJyOjYdW0r2FOAPeg8F18G8x5oJ+gUH/vnFjvj7n4W95ZgOSHqBDE/pDNUhUhYTXTfrCfrjROHhn8+CgJ17brUPIMGOv415adF8TGU1evj2/GFLWd7AQR1tx0nmx5PIP+gTp5M8Kqvx93SSvYOI8PI757GOFclwmaG+exMm6XFVCiC4Bism2JQi1TnZgYxW3sWbzBnWEaq3SvfNz4zbtrUzbOEGSGMtPO7n+mrjtVg4YgARVTzt1YZ8KwiSZqyNTW967F4Q8OTvtD7dSZ3yw== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=microsoft.com; s=arcselector10001; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-AntiSpam-MessageData-ChunkCount:X-MS-Exchange-AntiSpam-MessageData-0:X-MS-Exchange-AntiSpam-MessageData-1; bh=rksG0PShVf77+ncLm+Y6Lr8HDvgrVuZIjwB0qkcNqfw=; b=db1v7Vi4WksyyMPh4T2lz1qtNQ9z4INiavW1mBPELtw15UOZ1Yc2XoVuOkqN6PoEpgENeQ5oP/2/PhwWMFUR2KgLR3KPI/4cimRwozHthQPTEXng2mTE+JU1i1BjgnuawsV5hWyQwq60f75ZSHrrGcYcDUtmypG/AF/IdxVTIWYKAbiDIGwitn7pqu6S3OzEr03/vKWhRloftAb2sJQfzrkGiVQEpcQyYdwnHw8tpMQfI/hLV6kcKPOoCDgZllZXX3yp0JyBsKKSUrguC+7eYhL6W+hjl3LZoiOjK+qFpRml5Kvsca9nwpagpAwKQh7T+S2b3+P9fdkaShVy2Oq+Lg== ARC-Authentication-Results: i=1; mx.microsoft.com 1; spf=none; dmarc=none; dkim=none; arc=none DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=live.com; s=selector1; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-SenderADCheck; bh=rksG0PShVf77+ncLm+Y6Lr8HDvgrVuZIjwB0qkcNqfw=; b=d/W5kU1KexMyw8Uq4EkqbjHdXIqZ7HBN65ewNzVpCenUyLmKmx5nXBQzN+MGuTtcZ0HonbxnNMzwV66Lt5qb/tDN0Acq40XC6ZWEYv6O+QZK6RLNjsgKU83Rkr+OZeWQQa4sSqiS+cWk91B+QtV0pDZ7lFEN3cFfaMg17Ui+RnbNaKocA+/GHH5gMGTU/sQfARj/S6QGi0vNwmnjVjMkbs49mxMUvMrZrf4xDCar77h0cG89VjyPWaDrGm6t0V+GaHK72nFEakQ1BqCA4/igUXp0bn1UKuXqF4y+uocuwvi4QpVUIw7vFtM3R0veezwYjh7ZOWpVzL/L4JpPtgloLQ== Received: from MA0P287MB0217.INDP287.PROD.OUTLOOK.COM (2603:1096:a01:b3::9) by PN3P287MB0241.INDP287.PROD.OUTLOOK.COM (2603:1096:c01:d2::12) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.7875.20; Sat, 17 Aug 2024 11:47:29 +0000 Received: from MA0P287MB0217.INDP287.PROD.OUTLOOK.COM ([fe80::98d2:3610:b33c:435a]) by MA0P287MB0217.INDP287.PROD.OUTLOOK.COM ([fe80::98d2:3610:b33c:435a%6]) with mapi id 15.20.7875.016; Sat, 17 Aug 2024 11:47:29 +0000 From: Aditya Garg To: "tzimmermann@suse.de" , "maarten.lankhorst@linux.intel.com" , "mripard@kernel.org" , "airlied@gmail.com" , "daniel@ffwll.ch" , Jiri Kosina , "bentiss@kernel.org" , =?iso-8859-1?q?Thomas_Wei=DFschuh?= CC: Orlando Chamberlain , Kerem Karabay , Linux Kernel Mailing List , "linux-input@vger.kernel.org" , "dri-devel@lists.freedesktop.org" Subject: [PATCH v5 3/10] HID: hid-appletb-kbd: add support for fn toggle between media and function mode Thread-Topic: [PATCH v5 3/10] HID: hid-appletb-kbd: add support for fn toggle between media and function mode Thread-Index: AQHa8Js8PQ8afFSH10idm9Ss908Y+A== Date: Sat, 17 Aug 2024 11:47:29 +0000 Message-ID: <022CB692-B465-4485-B7F3-31F965B3963D@live.com> References: In-Reply-To: Accept-Language: en-IN, en-US Content-Language: en-US X-MS-Has-Attach: X-MS-TNEF-Correlator: x-ms-exchange-messagesentrepresentingtype: 1 x-tmn: [AK+2/Nm9UfrWAFgU/yO+MA8I/IAN6YeuAQBLy9m8P8DZv8uJ5si7WWq6/aVRSxD1XUVI94FsOCo=] x-ms-publictraffictype: Email x-ms-traffictypediagnostic: MA0P287MB0217:EE_|PN3P287MB0241:EE_ x-ms-office365-filtering-correlation-id: 38867387-a24d-456d-11be-08dcbeb25f4e x-microsoft-antispam: BCL:0; ARA:14566002|461199028|15080799003|8060799006|19110799003|440099028|3412199025|102099032; x-microsoft-antispam-message-info: lrGuntFIOwp4/UkAnoQA81QJlvY57/nMCx33w8dF9MFF9kFqw8II8OwZ9yUAi6v1FoLsZXyoGOePsSzAlwl2a+Ia4x2AIfhYOsAHbRX0qFf6HYoT4yfK4lWDfYptav9LqyUu/nJfGT/fSKENU7i7yAeSFSapeJXZBzYwQiUpx/ejCMPLm2cCmg213mJb0MWKMhkuX/ixmubYNs8BVDOmfHj+uF7KjuNW0eWEd3aYFOKB4GDmLqyFpggHzhluwyiCXNX9Xrg/lfDXTrAvVbExr5RSZgI99d3o+qx2gImZAdP1+jLPXlLZp4EtyuDOx5Quxbtv3rJkiIdSt8dWgsdX1r2Q6mmuj+eC4csXFfKMaS6ZmbkWgjfSv9E3p5OJVVNaxIHTHP9xc1Squ85ffdALv3W4wgp01BTMZPhO0B+vH3f7BudxMXWapw6+ZtLueVnqAmzEII1ODN/+fKoC1hpKVCzHvDChCTtl1gRJCfEaV1mluL0rDvTSYIXIxjfJjZVw7u+Wg9erLFnmonJ+ac9F7n2H6VvM7I/WE015UPlr+k3ewPpsQp45RsV8VxHihuu4QxEFyHrJWhX3iYYEPBLl0/pDCXlbk/c0/Xj5P4FSEz4CXhLOh161/8XlvNpgZQAugeXgjrUpXI1fybjQpgmuNMLCslNRxgmvgrWls7jnVsTjyTciNzs/HUMSG1+JJ9fo x-ms-exchange-antispam-messagedata-chunkcount: 1 x-ms-exchange-antispam-messagedata-0: =?iso-8859-1?q?0MfXWRV+HCqmQzXseordGwR?= =?iso-8859-1?q?Cu6wCdsiWlbD+7YTzQkSjA0GaHIvETXsDFkc4VnRCQDhW3eVjtyFlLfd/S85?= =?iso-8859-1?q?Dzc4K0UYHksXUXeAaw/zkv+Dz2y4z/x/bF5bMx5XR6xWpBq0f3VkqX9Eb7dg?= =?iso-8859-1?q?eBeFuNhb3KUAEpxspbNbNxqS967zG/Wsj+W7kOZQNibwg6TmfSus1nLfnDoA?= =?iso-8859-1?q?HyyLWwRBDBiDWflMXA4qyWvknq/midiEsXPrggGkj4Oyl3dsVtifiJiFtGGC?= =?iso-8859-1?q?ZX69q/plKo2/oq6KoxIcDo1LlWD9Z00OWeKAfY4t6udkgGXQL3RJQorYW12F?= =?iso-8859-1?q?gZhAUeqBHxNSNeOy3ls65vc2BNFzTEYthH8mL3pIG6bkYhs/7OLWVMZBF3uI?= =?iso-8859-1?q?Le/Xc9r8uz8upgAKdLo8D9QfKw4NdkJyoONyCWBIjtNrEG6MuPs/h7MU1eDO?= =?iso-8859-1?q?IPEc73zZN7stn7WkQFTGFS1kyTR0tMrtbtvx1Exl1ANSJjIlbQeqApkKwX3i?= =?iso-8859-1?q?jL+fx6WG6C5TKtiygSRCDAXSuE4SGkQnrJm8EwQPDPhPdFaWrqjkyablshZc?= =?iso-8859-1?q?zN+W9v7pTqgkuCJhZ6bupt6NYM397I0+Yu1WTt3c3tziuSnG4eugzZcGNz8R?= =?iso-8859-1?q?B266k+p7zFDjhB59nYDRGmiiscBxx4ao2dUPxgpOyLSyn398hYoEwx8JqjwB?= =?iso-8859-1?q?AUPQMr1/OdzwiYCh0QOpB11AtcbuBlDN0Y5GIxBjOyM01TJfNZYgiwa4oUST?= =?iso-8859-1?q?z0r63LokxkD1+EwFCMZxjVaTVTOiB7xIek3543oE8v93QfrfV8AnmUxDsxQC?= =?iso-8859-1?q?jblgTQ+JRNRXwdQCQoWmbmWIoxEADoRDICvzYvqFSAJxmysO9EoSrjIBjrSM?= =?iso-8859-1?q?wGs3ZAAlbFy+wYip6rKcZW6qTTDNRojwHJvWUsuySDvtUlgdKlOg8MxFJs7o?= =?iso-8859-1?q?59hOval5sprZJPzGrW6YKsmggGUUrexOMaeTqwxSm2ATbUe2NK7reJPYS+uc?= =?iso-8859-1?q?vOg0v5S3nZJm8rE/wsgiOdRPFLAS2J7G71TPeGYnHyYRbr94+piLRcltzwdL?= =?iso-8859-1?q?0G0ixPGRMDqmlh8n62lXEDEwDDCTEFsEZZWrTBWStIOki+NcpbOE93ZLQZzE?= =?iso-8859-1?q?qvpdttOByj4KGNQHSvhhgsjLZBA6YdBk+BAdvO2HU5qBCzKLFlqu2Vs3azFL?= =?iso-8859-1?q?llXcUZ5HYQztYcKMNYJWZBrSCFSRLLQoBEH2+qQekUuKtJzrWqYP1WCNtTje?= =?iso-8859-1?q?aKSQB9HrJ7k0ByBgX3ihF/Qn0TwcAy0XVM/h5YT6Ldr4o+1ZthpeypLnCbrC?= =?iso-8859-1?q?+AYZy185kEbXNEfJUsfG75QnIXMOgwBxSFMX3X5Mv6OgCKRzW2ZW1R8da+hf?= =?iso-8859-1?q?F?= Content-ID: MIME-Version: 1.0 X-OriginatorOrg: sct-15-20-7719-20-msonline-outlook-24072.templateTenant X-MS-Exchange-CrossTenant-AuthAs: Internal X-MS-Exchange-CrossTenant-AuthSource: MA0P287MB0217.INDP287.PROD.OUTLOOK.COM X-MS-Exchange-CrossTenant-RMS-PersistedConsumerOrg: 00000000-0000-0000-0000-000000000000 X-MS-Exchange-CrossTenant-Network-Message-Id: 38867387-a24d-456d-11be-08dcbeb25f4e X-MS-Exchange-CrossTenant-rms-persistedconsumerorg: 00000000-0000-0000-0000-000000000000 X-MS-Exchange-CrossTenant-originalarrivaltime: 17 Aug 2024 11:47:29.1628 (UTC) X-MS-Exchange-CrossTenant-fromentityheader: Hosted X-MS-Exchange-CrossTenant-id: 84df9e7f-e9f6-40af-b435-aaaaaaaaaaaa X-MS-Exchange-Transport-CrossTenantHeadersStamped: PN3P287MB0241 X-BeenThere: dri-devel@lists.freedesktop.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Direct Rendering Infrastructure - Development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: dri-devel-bounces@lists.freedesktop.org Sender: "dri-devel" From: Aditya Garg This patch adds support for the switching between the Media and Function keys on the touchbar by pressing the Fn key on Apple Internal Keyboard. Signed-off-by: Aditya Garg --- drivers/hid/hid-appletb-kbd.c | 128 ++++++++++++++++++++++++++++++++++ 1 file changed, 128 insertions(+) diff --git a/drivers/hid/hid-appletb-kbd.c b/drivers/hid/hid-appletb-kbd.c index ecac68fc7..442c4d884 100644 --- a/drivers/hid/hid-appletb-kbd.c +++ b/drivers/hid/hid-appletb-kbd.c @@ -26,6 +26,8 @@ #define APPLETB_KBD_MODE_OFF 3 #define APPLETB_KBD_MODE_MAX APPLETB_KBD_MODE_OFF +#define APPLETB_DEVID_KEYBOARD 1 + #define HID_USAGE_MODE 0x00ff0004 static int appletb_tb_def_mode = APPLETB_KBD_MODE_SPCL; @@ -35,11 +37,18 @@ MODULE_PARM_DESC(mode, "Default touchbar mode:\n" " 1 - function-keys\n" " [2] - special keys"); +static bool appletb_tb_fn_toggle = true; +module_param_named(fntoggle, appletb_tb_fn_toggle, bool, 0644); +MODULE_PARM_DESC(fntoggle, "Switch between Fn and media controls on pressing Fn key"); + struct appletb_kbd { struct hid_field *mode_field; u8 saved_mode; u8 current_mode; + struct input_handler inp_handler; + struct input_handle kbd_handle; + }; static const struct key_entry appletb_kbd_keymap[] = { @@ -172,6 +181,75 @@ static int appletb_kbd_hid_event(struct hid_device *hdev, struct hid_field *fiel return kbd->current_mode == APPLETB_KBD_MODE_OFF; } +static void appletb_kbd_inp_event(struct input_handle *handle, unsigned int type, + unsigned int code, int value) +{ + struct appletb_kbd *kbd = handle->private; + + if (type == EV_KEY && code == KEY_FN && appletb_tb_fn_toggle) { + if (value == 1) { + kbd->saved_mode = kbd->current_mode; + if (kbd->current_mode == APPLETB_KBD_MODE_SPCL) + appletb_kbd_set_mode(kbd, APPLETB_KBD_MODE_FN); + else if (kbd->current_mode == APPLETB_KBD_MODE_FN) + appletb_kbd_set_mode(kbd, APPLETB_KBD_MODE_SPCL); + } else if (value == 0) { + if (kbd->saved_mode != kbd->current_mode) + appletb_kbd_set_mode(kbd, kbd->saved_mode); + } + } +} + +static int appletb_kbd_inp_connect(struct input_handler *handler, + struct input_dev *dev, + const struct input_device_id *id) +{ + struct appletb_kbd *kbd = handler->private; + struct input_handle *handle; + int rc; + + if (id->driver_info == APPLETB_DEVID_KEYBOARD) { + handle = &kbd->kbd_handle; + handle->name = "tbkbd"; + } else { + return -ENOENT; + } + + if (handle->dev) + return -EEXIST; + + handle->open = 0; + handle->dev = input_get_device(dev); + handle->handler = handler; + handle->private = kbd; + + rc = input_register_handle(handle); + if (rc) + goto err_free_dev; + + rc = input_open_device(handle); + if (rc) + goto err_unregister_handle; + + return 0; + + err_unregister_handle: + input_unregister_handle(handle); + err_free_dev: + input_put_device(handle->dev); + handle->dev = NULL; + return rc; +} + +static void appletb_kbd_inp_disconnect(struct input_handle *handle) +{ + input_close_device(handle); + input_unregister_handle(handle); + + input_put_device(handle->dev); + handle->dev = NULL; +} + static int appletb_kbd_input_configured(struct hid_device *hdev, struct hid_input *hidinput) { int idx; @@ -196,6 +274,40 @@ static int appletb_kbd_input_configured(struct hid_device *hdev, struct hid_inpu return 0; } +static const struct input_device_id appletb_kbd_input_devices[] = { + { + .flags = INPUT_DEVICE_ID_MATCH_BUS | + INPUT_DEVICE_ID_MATCH_VENDOR | + INPUT_DEVICE_ID_MATCH_KEYBIT, + .bustype = BUS_USB, + .vendor = USB_VENDOR_ID_APPLE, + .keybit = { [BIT_WORD(KEY_FN)] = BIT_MASK(KEY_FN) }, + .driver_info = APPLETB_DEVID_KEYBOARD, + }, + { } +}; + +static bool appletb_kbd_match_internal_device(struct input_handler *handler, + struct input_dev *inp_dev) +{ + struct device *dev = &inp_dev->dev; + + /* in kernel: dev && !is_usb_device(dev) */ + while (dev && !(dev->type && dev->type->name && + !strcmp(dev->type->name, "usb_device"))) + dev = dev->parent; + + /* + * Apple labels all their internal keyboards and trackpads as such, + * instead of maintaining an ever expanding list of product-id's we + * just look at the device's product name. + */ + if (dev) + return !!strstr(to_usb_device(dev)->product, "Internal Keyboard"); + + return false; +} + static int appletb_kbd_probe(struct hid_device *hdev, const struct hid_device_id *id) { struct appletb_kbd *kbd; @@ -228,6 +340,20 @@ static int appletb_kbd_probe(struct hid_device *hdev, const struct hid_device_id goto stop_hw; } + kbd->inp_handler.event = appletb_kbd_inp_event; + kbd->inp_handler.connect = appletb_kbd_inp_connect; + kbd->inp_handler.disconnect = appletb_kbd_inp_disconnect; + kbd->inp_handler.name = "appletb"; + kbd->inp_handler.id_table = appletb_kbd_input_devices; + kbd->inp_handler.match = appletb_kbd_match_internal_device; + kbd->inp_handler.private = kbd; + + ret = input_register_handler(&kbd->inp_handler); + if (ret) { + dev_err_probe(dev, ret, "Unable to register keyboard handler\n"); + goto close_hw; + } + ret = appletb_kbd_set_mode(kbd, appletb_tb_def_mode); if (ret) { dev_err_probe(dev, ret, "Failed to set touchbar mode\n"); @@ -251,6 +377,8 @@ static void appletb_kbd_remove(struct hid_device *hdev) appletb_kbd_set_mode(kbd, APPLETB_KBD_MODE_OFF); + input_unregister_handler(&kbd->inp_handler); + hid_hw_close(hdev); hid_hw_stop(hdev); }