You've already forked linux-t2-patches
mirror of
https://github.com/t2linux/linux-t2-patches.git
synced 2026-04-30 13:52:11 -07:00
Add upstream changes done for touchbar driver
This commit is contained in:
@@ -1,4 +1,4 @@
|
||||
From 9fd738032d10a6b9d36972f2df61fb55d7a8a1b4 Mon Sep 17 00:00:00 2001
|
||||
From 7d40e39bbd21efdb24f3ab6cb6afb57d2153c3b2 Mon Sep 17 00:00:00 2001
|
||||
From: Kerem Karabay <kekrby@gmail.com>
|
||||
Date: Sun, 5 Mar 2023 18:52:43 +0300
|
||||
Subject: [PATCH 1/2] HID: hid-appletb-bl: add driver for the backlight of
|
||||
@@ -19,13 +19,13 @@ Signed-off-by: Aditya Garg <gargaditya08@live.com>
|
||||
---
|
||||
drivers/hid/Kconfig | 10 ++
|
||||
drivers/hid/Makefile | 1 +
|
||||
drivers/hid/hid-appletb-bl.c | 203 +++++++++++++++++++++++++++++++++++
|
||||
drivers/hid/hid-appletb-bl.c | 204 +++++++++++++++++++++++++++++++++++
|
||||
drivers/hid/hid-quirks.c | 4 +-
|
||||
4 files changed, 217 insertions(+), 1 deletion(-)
|
||||
4 files changed, 218 insertions(+), 1 deletion(-)
|
||||
create mode 100644 drivers/hid/hid-appletb-bl.c
|
||||
|
||||
diff --git a/drivers/hid/Kconfig b/drivers/hid/Kconfig
|
||||
index b53eb569b..b58c09f84 100644
|
||||
index dfc245867..8d80a624f 100644
|
||||
--- a/drivers/hid/Kconfig
|
||||
+++ b/drivers/hid/Kconfig
|
||||
@@ -148,6 +148,16 @@ config HID_APPLEIR
|
||||
@@ -59,10 +59,10 @@ index 482b096ee..d001c3ffd 100644
|
||||
obj-$(CONFIG_HID_AUREAL) += hid-aureal.o
|
||||
diff --git a/drivers/hid/hid-appletb-bl.c b/drivers/hid/hid-appletb-bl.c
|
||||
new file mode 100644
|
||||
index 000000000..1a3dcd44b
|
||||
index 000000000..bad2aead8
|
||||
--- /dev/null
|
||||
+++ b/drivers/hid/hid-appletb-bl.c
|
||||
@@ -0,0 +1,203 @@
|
||||
@@ -0,0 +1,204 @@
|
||||
+// SPDX-License-Identifier: GPL-2.0
|
||||
+/*
|
||||
+ * Apple Touch Bar Backlight Driver
|
||||
@@ -210,7 +210,8 @@ index 000000000..1a3dcd44b
|
||||
+ appletb_bl_brightness_map[(appletb_bl_def_brightness > 2) ? 2 : appletb_bl_def_brightness]);
|
||||
+
|
||||
+ if (ret) {
|
||||
+ dev_err_probe(dev, ret, "Failed to set touch bar brightness to off\n");
|
||||
+ dev_err_probe(dev, ret, "Failed to set default touch bar brightness to %d\n",
|
||||
+ appletb_bl_def_brightness);
|
||||
+ goto close_hw;
|
||||
+ }
|
||||
+
|
||||
@@ -264,10 +265,10 @@ index 000000000..1a3dcd44b
|
||||
+
|
||||
+MODULE_AUTHOR("Ronald Tschalär");
|
||||
+MODULE_AUTHOR("Kerem Karabay <kekrby@gmail.com>");
|
||||
+MODULE_DESCRIPTION("MacBookPro Touch Bar Backlight Driver");
|
||||
+MODULE_DESCRIPTION("MacBook Pro Touch Bar Backlight driver");
|
||||
+MODULE_LICENSE("GPL");
|
||||
diff --git a/drivers/hid/hid-quirks.c b/drivers/hid/hid-quirks.c
|
||||
index e0bbf0c63..818d41a35 100644
|
||||
index 5d7a418cc..0e055bc73 100644
|
||||
--- a/drivers/hid/hid-quirks.c
|
||||
+++ b/drivers/hid/hid-quirks.c
|
||||
@@ -328,7 +328,6 @@ static const struct hid_device_id hid_have_special_driver[] = {
|
||||
@@ -289,5 +290,5 @@ index e0bbf0c63..818d41a35 100644
|
||||
{ HID_I2C_DEVICE(USB_VENDOR_ID_ASUSTEK, USB_DEVICE_ID_ASUSTEK_I2C_KEYBOARD) },
|
||||
{ HID_I2C_DEVICE(USB_VENDOR_ID_ASUSTEK, USB_DEVICE_ID_ASUSTEK_I2C_TOUCHPAD) },
|
||||
--
|
||||
2.48.1
|
||||
2.43.0
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
From a7b5b204d9f2d5c6a93c255ecf6bc99465f7f24d Mon Sep 17 00:00:00 2001
|
||||
From e0707964b82b6994dacc06eb5899e69bdcc63bc0 Mon Sep 17 00:00:00 2001
|
||||
From: Kerem Karabay <kekrby@gmail.com>
|
||||
Date: Sun, 5 Mar 2023 18:17:23 +0300
|
||||
Subject: [PATCH 2/2] HID: hid-appletb-kbd: add driver for the keyboard mode of
|
||||
@@ -23,11 +23,11 @@ Co-developed-by: Aditya Garg <gargaditya08@live.com>
|
||||
Signed-off-by: Aditya Garg <gargaditya08@live.com>
|
||||
---
|
||||
.../ABI/testing/sysfs-driver-hid-appletb-kbd | 13 +
|
||||
drivers/hid/Kconfig | 13 +
|
||||
drivers/hid/Kconfig | 15 +
|
||||
drivers/hid/Makefile | 1 +
|
||||
drivers/hid/hid-appletb-kbd.c | 303 ++++++++++++++++++
|
||||
drivers/hid/hid-appletb-kbd.c | 507 ++++++++++++++++++
|
||||
drivers/hid/hid-quirks.c | 4 +-
|
||||
5 files changed, 333 insertions(+), 1 deletion(-)
|
||||
5 files changed, 539 insertions(+), 1 deletion(-)
|
||||
create mode 100644 Documentation/ABI/testing/sysfs-driver-hid-appletb-kbd
|
||||
create mode 100644 drivers/hid/hid-appletb-kbd.c
|
||||
|
||||
@@ -51,18 +51,20 @@ index 000000000..2a19584d0
|
||||
+ 3 None
|
||||
+ == =================
|
||||
diff --git a/drivers/hid/Kconfig b/drivers/hid/Kconfig
|
||||
index b58c09f84..c42f98955 100644
|
||||
index 8d80a624f..e9da46dd4 100644
|
||||
--- a/drivers/hid/Kconfig
|
||||
+++ b/drivers/hid/Kconfig
|
||||
@@ -158,6 +158,19 @@ config HID_APPLETB_BL
|
||||
@@ -158,6 +158,21 @@ config HID_APPLETB_BL
|
||||
To compile this driver as a module, choose M here: the
|
||||
module will be called hid-appletb-bl.
|
||||
|
||||
+config HID_APPLETB_KBD
|
||||
+ tristate "Apple Touch Bar Keyboard Mode"
|
||||
+ depends on USB_HID
|
||||
+ depends on BACKLIGHT_CLASS_DEVICE
|
||||
+ depends on INPUT
|
||||
+ select INPUT_SPARSEKMAP
|
||||
+ select HID_APPLETB_BL
|
||||
+ help
|
||||
+ Say Y here if you want support for the keyboard mode (escape,
|
||||
+ function, media and brightness keys) of Touch Bars on x86 MacBook
|
||||
@@ -88,10 +90,10 @@ index d001c3ffd..0775269be 100644
|
||||
obj-$(CONFIG_HID_AUREAL) += hid-aureal.o
|
||||
diff --git a/drivers/hid/hid-appletb-kbd.c b/drivers/hid/hid-appletb-kbd.c
|
||||
new file mode 100644
|
||||
index 000000000..7a93f1bba
|
||||
index 000000000..d4b95aa3e
|
||||
--- /dev/null
|
||||
+++ b/drivers/hid/hid-appletb-kbd.c
|
||||
@@ -0,0 +1,303 @@
|
||||
@@ -0,0 +1,507 @@
|
||||
+// SPDX-License-Identifier: GPL-2.0
|
||||
+/*
|
||||
+ * Apple Touch Bar Keyboard Mode Driver
|
||||
@@ -110,6 +112,8 @@ index 000000000..7a93f1bba
|
||||
+#include <linux/bitops.h>
|
||||
+#include <linux/module.h>
|
||||
+#include <linux/string.h>
|
||||
+#include <linux/backlight.h>
|
||||
+#include <linux/timer.h>
|
||||
+#include <linux/input/sparse-keymap.h>
|
||||
+
|
||||
+#include "hid-ids.h"
|
||||
@@ -120,6 +124,9 @@ index 000000000..7a93f1bba
|
||||
+#define APPLETB_KBD_MODE_OFF 3
|
||||
+#define APPLETB_KBD_MODE_MAX APPLETB_KBD_MODE_OFF
|
||||
+
|
||||
+#define APPLETB_DEVID_KEYBOARD 1
|
||||
+#define APPLETB_DEVID_TRACKPAD 2
|
||||
+
|
||||
+#define HID_USAGE_MODE 0x00ff0004
|
||||
+
|
||||
+static int appletb_tb_def_mode = APPLETB_KBD_MODE_SPCL;
|
||||
@@ -129,9 +136,31 @@ index 000000000..7a93f1bba
|
||||
+ " 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");
|
||||
+
|
||||
+static bool appletb_tb_autodim = true;
|
||||
+module_param_named(autodim, appletb_tb_autodim, bool, 0644);
|
||||
+MODULE_PARM_DESC(autodim, "Automatically dim and turn off the Touch Bar after some time");
|
||||
+
|
||||
+static int appletb_tb_dim_timeout = 60;
|
||||
+module_param_named(dim_timeout, appletb_tb_dim_timeout, int, 0644);
|
||||
+MODULE_PARM_DESC(dim_timeout, "Dim timeout in sec");
|
||||
+
|
||||
+static int appletb_tb_idle_timeout = 15;
|
||||
+module_param_named(idle_timeout, appletb_tb_idle_timeout, int, 0644);
|
||||
+MODULE_PARM_DESC(idle_timeout, "Idle timeout in sec");
|
||||
+
|
||||
+struct appletb_kbd {
|
||||
+ struct hid_field *mode_field;
|
||||
+
|
||||
+ struct input_handler inp_handler;
|
||||
+ struct input_handle kbd_handle;
|
||||
+ struct input_handle tpd_handle;
|
||||
+ struct backlight_device *backlight_dev;
|
||||
+ struct timer_list inactivity_timer;
|
||||
+ bool has_dimmed;
|
||||
+ bool has_turned_off;
|
||||
+ u8 saved_mode;
|
||||
+ u8 current_mode;
|
||||
+};
|
||||
@@ -231,6 +260,34 @@ index 000000000..7a93f1bba
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
+static void appletb_inactivity_timer(struct timer_list *t)
|
||||
+{
|
||||
+ struct appletb_kbd *kbd = from_timer(kbd, t, inactivity_timer);
|
||||
+
|
||||
+ if (kbd->backlight_dev && appletb_tb_autodim) {
|
||||
+ if (!kbd->has_dimmed) {
|
||||
+ backlight_device_set_brightness(kbd->backlight_dev, 1);
|
||||
+ kbd->has_dimmed = true;
|
||||
+ mod_timer(&kbd->inactivity_timer, jiffies + msecs_to_jiffies(appletb_tb_idle_timeout * 1000));
|
||||
+ } else if (!kbd->has_turned_off) {
|
||||
+ backlight_device_set_brightness(kbd->backlight_dev, 0);
|
||||
+ kbd->has_turned_off = true;
|
||||
+ }
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
+static void reset_inactivity_timer(struct appletb_kbd *kbd)
|
||||
+{
|
||||
+ if (kbd->backlight_dev && appletb_tb_autodim) {
|
||||
+ if (kbd->has_dimmed || kbd->has_turned_off) {
|
||||
+ backlight_device_set_brightness(kbd->backlight_dev, 2);
|
||||
+ kbd->has_dimmed = false;
|
||||
+ kbd->has_turned_off = false;
|
||||
+ }
|
||||
+ mod_timer(&kbd->inactivity_timer, jiffies + msecs_to_jiffies(appletb_tb_dim_timeout * 1000));
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
+static int appletb_kbd_hid_event(struct hid_device *hdev, struct hid_field *field,
|
||||
+ struct hid_usage *usage, __s32 value)
|
||||
+{
|
||||
@@ -255,6 +312,8 @@ index 000000000..7a93f1bba
|
||||
+ if (slot < 0)
|
||||
+ return 0;
|
||||
+
|
||||
+ reset_inactivity_timer(kbd);
|
||||
+
|
||||
+ translation = sparse_keymap_entry_from_scancode(input, usage->code);
|
||||
+
|
||||
+ if (translation && kbd->current_mode == APPLETB_KBD_MODE_SPCL) {
|
||||
@@ -266,6 +325,80 @@ index 000000000..7a93f1bba
|
||||
+ 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;
|
||||
+
|
||||
+ reset_inactivity_timer(kbd);
|
||||
+
|
||||
+ if (type == EV_KEY && code == KEY_FN && appletb_tb_fn_toggle &&
|
||||
+ (kbd->current_mode == APPLETB_KBD_MODE_SPCL ||
|
||||
+ kbd->current_mode == APPLETB_KBD_MODE_FN)) {
|
||||
+ if (value == 1) {
|
||||
+ kbd->saved_mode = kbd->current_mode;
|
||||
+ appletb_kbd_set_mode(kbd, kbd->current_mode == APPLETB_KBD_MODE_SPCL
|
||||
+ ? APPLETB_KBD_MODE_FN : 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 if (id->driver_info == APPLETB_DEVID_TRACKPAD) {
|
||||
+ handle = &kbd->tpd_handle;
|
||||
+ handle->name = "tbtpd";
|
||||
+ } 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;
|
||||
@@ -289,6 +422,49 @@ index 000000000..7a93f1bba
|
||||
+ 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,
|
||||
+ },
|
||||
+ {
|
||||
+ .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(BTN_TOUCH)] = BIT_MASK(BTN_TOUCH) },
|
||||
+ .driver_info = APPLETB_DEVID_TRACKPAD,
|
||||
+ },
|
||||
+ { }
|
||||
+};
|
||||
+
|
||||
+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;
|
||||
@@ -321,6 +497,29 @@ index 000000000..7a93f1bba
|
||||
+ goto stop_hw;
|
||||
+ }
|
||||
+
|
||||
+ kbd->backlight_dev = backlight_device_get_by_name("appletb_backlight");
|
||||
+ if (!kbd->backlight_dev) {
|
||||
+ dev_err_probe(dev, -ENODEV, "Failed to get backlight device\n");
|
||||
+ } else {
|
||||
+ backlight_device_set_brightness(kbd->backlight_dev, 2);
|
||||
+ timer_setup(&kbd->inactivity_timer, appletb_inactivity_timer, 0);
|
||||
+ mod_timer(&kbd->inactivity_timer, jiffies + msecs_to_jiffies(appletb_tb_dim_timeout * 1000));
|
||||
+ }
|
||||
+
|
||||
+ 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");
|
||||
@@ -344,6 +543,9 @@ index 000000000..7a93f1bba
|
||||
+
|
||||
+ appletb_kbd_set_mode(kbd, APPLETB_KBD_MODE_OFF);
|
||||
+
|
||||
+ input_unregister_handler(&kbd->inp_handler);
|
||||
+ del_timer_sync(&kbd->inactivity_timer);
|
||||
+
|
||||
+ hid_hw_close(hdev);
|
||||
+ hid_hw_stop(hdev);
|
||||
+}
|
||||
@@ -391,12 +593,16 @@ index 000000000..7a93f1bba
|
||||
+};
|
||||
+module_hid_driver(appletb_kbd_hid_driver);
|
||||
+
|
||||
+/* The backlight driver should be loaded before the keyboard driver is initialised */
|
||||
+MODULE_SOFTDEP("pre: hid_appletb_bl");
|
||||
+
|
||||
+MODULE_AUTHOR("Ronald Tschalär");
|
||||
+MODULE_AUTHOR("Kerem Karabay <kekrby@gmail.com>");
|
||||
+MODULE_DESCRIPTION("MacBookPro Touch Bar Keyboard Mode Driver");
|
||||
+MODULE_AUTHOR("Aditya Garg <gargaditya08@live.com>");
|
||||
+MODULE_DESCRIPTION("MacBook Pro Touch Bar Keyboard Mode driver");
|
||||
+MODULE_LICENSE("GPL");
|
||||
diff --git a/drivers/hid/hid-quirks.c b/drivers/hid/hid-quirks.c
|
||||
index 818d41a35..7c576d654 100644
|
||||
index 0e055bc73..ff1364f6e 100644
|
||||
--- a/drivers/hid/hid-quirks.c
|
||||
+++ b/drivers/hid/hid-quirks.c
|
||||
@@ -328,7 +328,6 @@ static const struct hid_device_id hid_have_special_driver[] = {
|
||||
@@ -418,5 +624,5 @@ index 818d41a35..7c576d654 100644
|
||||
{ HID_I2C_DEVICE(USB_VENDOR_ID_ASUSTEK, USB_DEVICE_ID_ASUSTEK_I2C_KEYBOARD) },
|
||||
{ HID_I2C_DEVICE(USB_VENDOR_ID_ASUSTEK, USB_DEVICE_ID_ASUSTEK_I2C_TOUCHPAD) },
|
||||
--
|
||||
2.48.1
|
||||
2.43.0
|
||||
|
||||
|
||||
@@ -1,196 +0,0 @@
|
||||
From e2e32c6300afa1f8a0a2c9fc721cfc975645999c Mon Sep 17 00:00:00 2001
|
||||
From: Aditya Garg <gargaditya08@live.com>
|
||||
Date: Fri, 9 Aug 2024 19:40:53 +0530
|
||||
Subject: [PATCH 3/4] HID: hid-appletb-kbd: add support for fn toggle between
|
||||
media and function mode
|
||||
|
||||
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 <gargaditya08@live.com>
|
||||
---
|
||||
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 80c87396f..de5770500 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;
|
||||
@@ -195,6 +273,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;
|
||||
@@ -227,6 +339,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");
|
||||
@@ -250,6 +376,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);
|
||||
}
|
||||
--
|
||||
2.43.0
|
||||
|
||||
@@ -1,203 +0,0 @@
|
||||
From fb310a1f5dabf18a559b1368d5cf5ce33b30924e Mon Sep 17 00:00:00 2001
|
||||
From: Aditya Garg <gargaditya08@live.com>
|
||||
Date: Sun, 29 Dec 2024 12:36:09 +0530
|
||||
Subject: [PATCH 4/4] HID: hid-appletb-kbd: add support for automatic
|
||||
brightness control while using the touchbar
|
||||
|
||||
On Windows, if there is no input by the user for 60 sec, the Touch Bar dims
|
||||
automatically, and after further 15 sec, it turns off. On receiving input,
|
||||
the Touch Bar resets the timer and goes back to full brightness. This patch
|
||||
implements the same functionality.
|
||||
|
||||
Signed-off-by: Aditya Garg <gargaditya08@live.com>
|
||||
---
|
||||
drivers/hid/Kconfig | 2 +
|
||||
drivers/hid/hid-appletb-kbd.c | 83 +++++++++++++++++++++++++++++++++--
|
||||
2 files changed, 81 insertions(+), 4 deletions(-)
|
||||
|
||||
diff --git a/drivers/hid/Kconfig b/drivers/hid/Kconfig
|
||||
index 5b16bfadc..4dadf42a2 100644
|
||||
--- a/drivers/hid/Kconfig
|
||||
+++ b/drivers/hid/Kconfig
|
||||
@@ -161,8 +161,10 @@ config HID_APPLETB_BL
|
||||
config HID_APPLETB_KBD
|
||||
tristate "Apple Touch Bar Keyboard Mode"
|
||||
depends on USB_HID
|
||||
+ depends on BACKLIGHT_CLASS_DEVICE
|
||||
depends on INPUT
|
||||
select INPUT_SPARSEKMAP
|
||||
+ select HID_APPLETB_BL
|
||||
help
|
||||
Say Y here if you want support for the keyboard mode (escape,
|
||||
function, media and brightness keys) of Touch Bars on x86 MacBook
|
||||
diff --git a/drivers/hid/hid-appletb-kbd.c b/drivers/hid/hid-appletb-kbd.c
|
||||
index de5770500..fa28a691d 100644
|
||||
--- a/drivers/hid/hid-appletb-kbd.c
|
||||
+++ b/drivers/hid/hid-appletb-kbd.c
|
||||
@@ -16,6 +16,8 @@
|
||||
#include <linux/bitops.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/string.h>
|
||||
+#include <linux/backlight.h>
|
||||
+#include <linux/timer.h>
|
||||
#include <linux/input/sparse-keymap.h>
|
||||
|
||||
#include "hid-ids.h"
|
||||
@@ -27,6 +29,7 @@
|
||||
#define APPLETB_KBD_MODE_MAX APPLETB_KBD_MODE_OFF
|
||||
|
||||
#define APPLETB_DEVID_KEYBOARD 1
|
||||
+#define APPLETB_DEVID_TRACKPAD 2
|
||||
|
||||
#define HID_USAGE_MODE 0x00ff0004
|
||||
|
||||
@@ -41,14 +44,29 @@ 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");
|
||||
|
||||
+static bool appletb_tb_autodim = true;
|
||||
+module_param_named(autodim, appletb_tb_autodim, bool, 0644);
|
||||
+MODULE_PARM_DESC(autodim, "Automatically dim and turn off the Touch Bar after some time");
|
||||
+
|
||||
+static int appletb_tb_dim_timeout = 60;
|
||||
+module_param_named(dim_timeout, appletb_tb_dim_timeout, int, 0644);
|
||||
+MODULE_PARM_DESC(dim_timeout, "Dim timeout in sec");
|
||||
+
|
||||
+static int appletb_tb_idle_timeout = 15;
|
||||
+module_param_named(idle_timeout, appletb_tb_idle_timeout, int, 0644);
|
||||
+MODULE_PARM_DESC(idle_timeout, "Idle timeout in sec");
|
||||
+
|
||||
struct appletb_kbd {
|
||||
struct hid_field *mode_field;
|
||||
-
|
||||
- u8 saved_mode;
|
||||
- u8 current_mode;
|
||||
struct input_handler inp_handler;
|
||||
struct input_handle kbd_handle;
|
||||
-
|
||||
+ struct input_handle tpd_handle;
|
||||
+ struct backlight_device *backlight_dev;
|
||||
+ struct timer_list inactivity_timer;
|
||||
+ bool has_dimmed;
|
||||
+ bool has_turned_off;
|
||||
+ u8 saved_mode;
|
||||
+ u8 current_mode;
|
||||
};
|
||||
|
||||
static const struct key_entry appletb_kbd_keymap[] = {
|
||||
@@ -146,6 +164,34 @@ static int appletb_tb_key_to_slot(unsigned int code)
|
||||
}
|
||||
}
|
||||
|
||||
+static void appletb_inactivity_timer(struct timer_list *t)
|
||||
+{
|
||||
+ struct appletb_kbd *kbd = from_timer(kbd, t, inactivity_timer);
|
||||
+
|
||||
+ if (kbd->backlight_dev && appletb_tb_autodim) {
|
||||
+ if (!kbd->has_dimmed) {
|
||||
+ backlight_device_set_brightness(kbd->backlight_dev, 1);
|
||||
+ kbd->has_dimmed = true;
|
||||
+ mod_timer(&kbd->inactivity_timer, jiffies + msecs_to_jiffies(appletb_tb_idle_timeout * 1000));
|
||||
+ } else if (!kbd->has_turned_off) {
|
||||
+ backlight_device_set_brightness(kbd->backlight_dev, 0);
|
||||
+ kbd->has_turned_off = true;
|
||||
+ }
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
+static void reset_inactivity_timer(struct appletb_kbd *kbd)
|
||||
+{
|
||||
+ if (kbd->backlight_dev && appletb_tb_autodim) {
|
||||
+ if (kbd->has_dimmed || kbd->has_turned_off) {
|
||||
+ backlight_device_set_brightness(kbd->backlight_dev, 2);
|
||||
+ kbd->has_dimmed = false;
|
||||
+ kbd->has_turned_off = false;
|
||||
+ }
|
||||
+ mod_timer(&kbd->inactivity_timer, jiffies + msecs_to_jiffies(appletb_tb_dim_timeout * 1000));
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
static int appletb_kbd_hid_event(struct hid_device *hdev, struct hid_field *field,
|
||||
struct hid_usage *usage, __s32 value)
|
||||
{
|
||||
@@ -170,6 +216,8 @@ static int appletb_kbd_hid_event(struct hid_device *hdev, struct hid_field *fiel
|
||||
if (slot < 0)
|
||||
return 0;
|
||||
|
||||
+ reset_inactivity_timer(kbd);
|
||||
+
|
||||
translation = sparse_keymap_entry_from_scancode(input, usage->code);
|
||||
|
||||
if (translation && kbd->current_mode == APPLETB_KBD_MODE_SPCL) {
|
||||
@@ -186,6 +234,8 @@ static void appletb_kbd_inp_event(struct input_handle *handle, unsigned int type
|
||||
{
|
||||
struct appletb_kbd *kbd = handle->private;
|
||||
|
||||
+ reset_inactivity_timer(kbd);
|
||||
+
|
||||
if (type == EV_KEY && code == KEY_FN && appletb_tb_fn_toggle) {
|
||||
if (value == 1) {
|
||||
kbd->saved_mode = kbd->current_mode;
|
||||
@@ -211,6 +261,9 @@ static int appletb_kbd_inp_connect(struct input_handler *handler,
|
||||
if (id->driver_info == APPLETB_DEVID_KEYBOARD) {
|
||||
handle = &kbd->kbd_handle;
|
||||
handle->name = "tbkbd";
|
||||
+ } else if (id->driver_info == APPLETB_DEVID_TRACKPAD) {
|
||||
+ handle = &kbd->tpd_handle;
|
||||
+ handle->name = "tbtpd";
|
||||
} else {
|
||||
return -ENOENT;
|
||||
}
|
||||
@@ -283,6 +336,15 @@ static const struct input_device_id appletb_kbd_input_devices[] = {
|
||||
.keybit = { [BIT_WORD(KEY_FN)] = BIT_MASK(KEY_FN) },
|
||||
.driver_info = APPLETB_DEVID_KEYBOARD,
|
||||
},
|
||||
+ {
|
||||
+ .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(BTN_TOUCH)] = BIT_MASK(BTN_TOUCH) },
|
||||
+ .driver_info = APPLETB_DEVID_TRACKPAD,
|
||||
+ },
|
||||
{ }
|
||||
};
|
||||
|
||||
@@ -339,6 +401,15 @@ static int appletb_kbd_probe(struct hid_device *hdev, const struct hid_device_id
|
||||
goto stop_hw;
|
||||
}
|
||||
|
||||
+ kbd->backlight_dev = backlight_device_get_by_name("appletb_backlight");
|
||||
+ if (!kbd->backlight_dev)
|
||||
+ dev_err_probe(dev, ret, "Failed to get backlight device\n");
|
||||
+ else {
|
||||
+ backlight_device_set_brightness(kbd->backlight_dev, 2);
|
||||
+ timer_setup(&kbd->inactivity_timer, appletb_inactivity_timer, 0);
|
||||
+ mod_timer(&kbd->inactivity_timer, jiffies + msecs_to_jiffies(appletb_tb_dim_timeout * 1000));
|
||||
+ }
|
||||
+
|
||||
kbd->inp_handler.event = appletb_kbd_inp_event;
|
||||
kbd->inp_handler.connect = appletb_kbd_inp_connect;
|
||||
kbd->inp_handler.disconnect = appletb_kbd_inp_disconnect;
|
||||
@@ -377,6 +448,7 @@ static void appletb_kbd_remove(struct hid_device *hdev)
|
||||
appletb_kbd_set_mode(kbd, APPLETB_KBD_MODE_OFF);
|
||||
|
||||
input_unregister_handler(&kbd->inp_handler);
|
||||
+ del_timer_sync(&kbd->inactivity_timer);
|
||||
|
||||
hid_hw_close(hdev);
|
||||
hid_hw_stop(hdev);
|
||||
@@ -425,6 +497,9 @@ static struct hid_driver appletb_kbd_hid_driver = {
|
||||
};
|
||||
module_hid_driver(appletb_kbd_hid_driver);
|
||||
|
||||
+/* The backlight driver should be loaded before the keyboard driver is initialised*/
|
||||
+MODULE_SOFTDEP("pre: hid_appletb_bl");
|
||||
+
|
||||
MODULE_AUTHOR("Ronald Tschalär");
|
||||
MODULE_AUTHOR("Kerem Karabay <kekrby@gmail.com>");
|
||||
MODULE_DESCRIPTION("MacBookPro Touch Bar Keyboard Mode Driver");
|
||||
--
|
||||
2.43.0
|
||||
|
||||
Reference in New Issue
Block a user