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"
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;
4144module_param_named (fntoggle , appletb_tb_fn_toggle , bool , 0644 );
4245MODULE_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+
4459struct 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
5472static 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+
149195static 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};
426498module_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+
428503MODULE_AUTHOR ("Ronald Tschalär" );
429504MODULE_AUTHOR ("Kerem Karabay <kekrby@gmail.com>" );
430505MODULE_DESCRIPTION ("MacBookPro Touch Bar Keyboard Mode Driver" );
0 commit comments