16
16
#include <linux/bitops.h>
17
17
#include <linux/module.h>
18
18
#include <linux/string.h>
19
+ #include <linux/backlight.h>
20
+ #include <linux/timer.h>
19
21
#include <linux/input/sparse-keymap.h>
20
22
21
23
#include "hid-ids.h"
27
29
#define APPLETB_KBD_MODE_MAX APPLETB_KBD_MODE_OFF
28
30
29
31
#define APPLETB_DEVID_KEYBOARD 1
32
+ #define APPLETB_DEVID_TRACKPAD 2
30
33
31
34
#define HID_USAGE_MODE 0x00ff0004
32
35
@@ -41,14 +44,29 @@ static bool appletb_tb_fn_toggle = true;
41
44
module_param_named (fntoggle , appletb_tb_fn_toggle , bool , 0644 );
42
45
MODULE_PARM_DESC (fntoggle , "Switch between Fn and media controls on pressing Fn key" );
43
46
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
+
44
59
struct appletb_kbd {
45
60
struct hid_field * mode_field ;
46
-
47
- u8 saved_mode ;
48
- u8 current_mode ;
49
61
struct input_handler inp_handler ;
50
62
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 ;
52
70
};
53
71
54
72
static const struct key_entry appletb_kbd_keymap [] = {
@@ -146,6 +164,34 @@ static int appletb_tb_key_to_slot(unsigned int code)
146
164
}
147
165
}
148
166
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
+
149
195
static int appletb_kbd_hid_event (struct hid_device * hdev , struct hid_field * field ,
150
196
struct hid_usage * usage , __s32 value )
151
197
{
@@ -170,6 +216,8 @@ static int appletb_kbd_hid_event(struct hid_device *hdev, struct hid_field *fiel
170
216
if (slot < 0 )
171
217
return 0 ;
172
218
219
+ reset_inactivity_timer (kbd );
220
+
173
221
translation = sparse_keymap_entry_from_scancode (input , usage -> code );
174
222
175
223
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
186
234
{
187
235
struct appletb_kbd * kbd = handle -> private ;
188
236
237
+ reset_inactivity_timer (kbd );
238
+
189
239
if (type == EV_KEY && code == KEY_FN && appletb_tb_fn_toggle ) {
190
240
if (value == 1 ) {
191
241
kbd -> saved_mode = kbd -> current_mode ;
@@ -211,6 +261,9 @@ static int appletb_kbd_inp_connect(struct input_handler *handler,
211
261
if (id -> driver_info == APPLETB_DEVID_KEYBOARD ) {
212
262
handle = & kbd -> kbd_handle ;
213
263
handle -> name = "tbkbd" ;
264
+ } else if (id -> driver_info == APPLETB_DEVID_TRACKPAD ) {
265
+ handle = & kbd -> tpd_handle ;
266
+ handle -> name = "tbtpd" ;
214
267
} else {
215
268
return - ENOENT ;
216
269
}
@@ -283,6 +336,15 @@ static const struct input_device_id appletb_kbd_input_devices[] = {
283
336
.keybit = { [BIT_WORD (KEY_FN )] = BIT_MASK (KEY_FN ) },
284
337
.driver_info = APPLETB_DEVID_KEYBOARD ,
285
338
},
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
+ },
286
348
{ }
287
349
};
288
350
@@ -339,6 +401,15 @@ static int appletb_kbd_probe(struct hid_device *hdev, const struct hid_device_id
339
401
goto stop_hw ;
340
402
}
341
403
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
+
342
413
kbd -> inp_handler .event = appletb_kbd_inp_event ;
343
414
kbd -> inp_handler .connect = appletb_kbd_inp_connect ;
344
415
kbd -> inp_handler .disconnect = appletb_kbd_inp_disconnect ;
@@ -377,6 +448,7 @@ static void appletb_kbd_remove(struct hid_device *hdev)
377
448
appletb_kbd_set_mode (kbd , APPLETB_KBD_MODE_OFF );
378
449
379
450
input_unregister_handler (& kbd -> inp_handler );
451
+ del_timer_sync (& kbd -> inactivity_timer );
380
452
381
453
hid_hw_close (hdev );
382
454
hid_hw_stop (hdev );
@@ -425,6 +497,9 @@ static struct hid_driver appletb_kbd_hid_driver = {
425
497
};
426
498
module_hid_driver (appletb_kbd_hid_driver );
427
499
500
+ /* The backlight driver should be loaded before the keyboard driver is initialised*/
501
+ MODULE_SOFTDEP ("pre: hid_appletb_bl" );
502
+
428
503
MODULE_AUTHOR ("Ronald Tschalär" );
429
504
MODULE_AUTHOR (
"Kerem Karabay <[email protected] >" );
430
505
MODULE_DESCRIPTION ("MacBookPro Touch Bar Keyboard Mode Driver" );
0 commit comments