Skip to content

Commit 93a0fc4

Browse files
AdityaGarg8Jiri Kosina
authored andcommitted
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 <[email protected]> Signed-off-by: Jiri Kosina <[email protected]>
1 parent 7d62ba8 commit 93a0fc4

File tree

2 files changed

+81
-4
lines changed

2 files changed

+81
-4
lines changed

drivers/hid/Kconfig

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -161,8 +161,10 @@ config HID_APPLETB_BL
161161
config HID_APPLETB_KBD
162162
tristate "Apple Touch Bar Keyboard Mode"
163163
depends on USB_HID
164+
depends on BACKLIGHT_CLASS_DEVICE
164165
depends on INPUT
165166
select INPUT_SPARSEKMAP
167+
select HID_APPLETB_BL
166168
help
167169
Say Y here if you want support for the keyboard mode (escape,
168170
function, media and brightness keys) of Touch Bars on x86 MacBook

drivers/hid/hid-appletb-kbd.c

Lines changed: 79 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,8 @@
1616
#include <linux/bitops.h>
1717
#include <linux/module.h>
1818
#include <linux/string.h>
19+
#include <linux/backlight.h>
20+
#include <linux/timer.h>
1921
#include <linux/input/sparse-keymap.h>
2022

2123
#include "hid-ids.h"
@@ -27,6 +29,7 @@
2729
#define APPLETB_KBD_MODE_MAX APPLETB_KBD_MODE_OFF
2830

2931
#define APPLETB_DEVID_KEYBOARD 1
32+
#define APPLETB_DEVID_TRACKPAD 2
3033

3134
#define HID_USAGE_MODE 0x00ff0004
3235

@@ -41,14 +44,29 @@ static bool appletb_tb_fn_toggle = true;
4144
module_param_named(fntoggle, appletb_tb_fn_toggle, bool, 0644);
4245
MODULE_PARM_DESC(fntoggle, "Switch between Fn and media controls on pressing Fn key");
4346

47+
static bool appletb_tb_autodim = true;
48+
module_param_named(autodim, appletb_tb_autodim, bool, 0644);
49+
MODULE_PARM_DESC(autodim, "Automatically dim and turn off the Touch Bar after some time");
50+
51+
static int appletb_tb_dim_timeout = 60;
52+
module_param_named(dim_timeout, appletb_tb_dim_timeout, int, 0644);
53+
MODULE_PARM_DESC(dim_timeout, "Dim timeout in sec");
54+
55+
static int appletb_tb_idle_timeout = 15;
56+
module_param_named(idle_timeout, appletb_tb_idle_timeout, int, 0644);
57+
MODULE_PARM_DESC(idle_timeout, "Idle timeout in sec");
58+
4459
struct appletb_kbd {
4560
struct hid_field *mode_field;
46-
47-
u8 saved_mode;
48-
u8 current_mode;
4961
struct input_handler inp_handler;
5062
struct input_handle kbd_handle;
51-
63+
struct input_handle tpd_handle;
64+
struct backlight_device *backlight_dev;
65+
struct timer_list inactivity_timer;
66+
bool has_dimmed;
67+
bool has_turned_off;
68+
u8 saved_mode;
69+
u8 current_mode;
5270
};
5371

5472
static const struct key_entry appletb_kbd_keymap[] = {
@@ -146,6 +164,34 @@ static int appletb_tb_key_to_slot(unsigned int code)
146164
}
147165
}
148166

167+
static void appletb_inactivity_timer(struct timer_list *t)
168+
{
169+
struct appletb_kbd *kbd = from_timer(kbd, t, inactivity_timer);
170+
171+
if (kbd->backlight_dev && appletb_tb_autodim) {
172+
if (!kbd->has_dimmed) {
173+
backlight_device_set_brightness(kbd->backlight_dev, 1);
174+
kbd->has_dimmed = true;
175+
mod_timer(&kbd->inactivity_timer, jiffies + msecs_to_jiffies(appletb_tb_idle_timeout * 1000));
176+
} else if (!kbd->has_turned_off) {
177+
backlight_device_set_brightness(kbd->backlight_dev, 0);
178+
kbd->has_turned_off = true;
179+
}
180+
}
181+
}
182+
183+
static void reset_inactivity_timer(struct appletb_kbd *kbd)
184+
{
185+
if (kbd->backlight_dev && appletb_tb_autodim) {
186+
if (kbd->has_dimmed || kbd->has_turned_off) {
187+
backlight_device_set_brightness(kbd->backlight_dev, 2);
188+
kbd->has_dimmed = false;
189+
kbd->has_turned_off = false;
190+
}
191+
mod_timer(&kbd->inactivity_timer, jiffies + msecs_to_jiffies(appletb_tb_dim_timeout * 1000));
192+
}
193+
}
194+
149195
static int appletb_kbd_hid_event(struct hid_device *hdev, struct hid_field *field,
150196
struct hid_usage *usage, __s32 value)
151197
{
@@ -170,6 +216,8 @@ static int appletb_kbd_hid_event(struct hid_device *hdev, struct hid_field *fiel
170216
if (slot < 0)
171217
return 0;
172218

219+
reset_inactivity_timer(kbd);
220+
173221
translation = sparse_keymap_entry_from_scancode(input, usage->code);
174222

175223
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
186234
{
187235
struct appletb_kbd *kbd = handle->private;
188236

237+
reset_inactivity_timer(kbd);
238+
189239
if (type == EV_KEY && code == KEY_FN && appletb_tb_fn_toggle) {
190240
if (value == 1) {
191241
kbd->saved_mode = kbd->current_mode;
@@ -211,6 +261,9 @@ static int appletb_kbd_inp_connect(struct input_handler *handler,
211261
if (id->driver_info == APPLETB_DEVID_KEYBOARD) {
212262
handle = &kbd->kbd_handle;
213263
handle->name = "tbkbd";
264+
} else if (id->driver_info == APPLETB_DEVID_TRACKPAD) {
265+
handle = &kbd->tpd_handle;
266+
handle->name = "tbtpd";
214267
} else {
215268
return -ENOENT;
216269
}
@@ -283,6 +336,15 @@ static const struct input_device_id appletb_kbd_input_devices[] = {
283336
.keybit = { [BIT_WORD(KEY_FN)] = BIT_MASK(KEY_FN) },
284337
.driver_info = APPLETB_DEVID_KEYBOARD,
285338
},
339+
{
340+
.flags = INPUT_DEVICE_ID_MATCH_BUS |
341+
INPUT_DEVICE_ID_MATCH_VENDOR |
342+
INPUT_DEVICE_ID_MATCH_KEYBIT,
343+
.bustype = BUS_USB,
344+
.vendor = USB_VENDOR_ID_APPLE,
345+
.keybit = { [BIT_WORD(BTN_TOUCH)] = BIT_MASK(BTN_TOUCH) },
346+
.driver_info = APPLETB_DEVID_TRACKPAD,
347+
},
286348
{ }
287349
};
288350

@@ -339,6 +401,15 @@ static int appletb_kbd_probe(struct hid_device *hdev, const struct hid_device_id
339401
goto stop_hw;
340402
}
341403

404+
kbd->backlight_dev = backlight_device_get_by_name("appletb_backlight");
405+
if (!kbd->backlight_dev)
406+
dev_err_probe(dev, ret, "Failed to get backlight device\n");
407+
else {
408+
backlight_device_set_brightness(kbd->backlight_dev, 2);
409+
timer_setup(&kbd->inactivity_timer, appletb_inactivity_timer, 0);
410+
mod_timer(&kbd->inactivity_timer, jiffies + msecs_to_jiffies(appletb_tb_dim_timeout * 1000));
411+
}
412+
342413
kbd->inp_handler.event = appletb_kbd_inp_event;
343414
kbd->inp_handler.connect = appletb_kbd_inp_connect;
344415
kbd->inp_handler.disconnect = appletb_kbd_inp_disconnect;
@@ -377,6 +448,7 @@ static void appletb_kbd_remove(struct hid_device *hdev)
377448
appletb_kbd_set_mode(kbd, APPLETB_KBD_MODE_OFF);
378449

379450
input_unregister_handler(&kbd->inp_handler);
451+
del_timer_sync(&kbd->inactivity_timer);
380452

381453
hid_hw_close(hdev);
382454
hid_hw_stop(hdev);
@@ -425,6 +497,9 @@ static struct hid_driver appletb_kbd_hid_driver = {
425497
};
426498
module_hid_driver(appletb_kbd_hid_driver);
427499

500+
/* The backlight driver should be loaded before the keyboard driver is initialised*/
501+
MODULE_SOFTDEP("pre: hid_appletb_bl");
502+
428503
MODULE_AUTHOR("Ronald Tschalär");
429504
MODULE_AUTHOR("Kerem Karabay <[email protected]>");
430505
MODULE_DESCRIPTION("MacBookPro Touch Bar Keyboard Mode Driver");

0 commit comments

Comments
 (0)