2525#define REPORT_ID_RADIO 0x01
2626#define REPORT_ID_CONSUMER 0x02
2727#define REPORT_ID_SENSOR 0x03
28+ #define REPORT_ID_KEYBOARD_BACKLIGHT 0x05
2829
2930#define ALS_REPORT_STOP 0x00
3031#define ALS_REPORT_POLLING 0x01
@@ -74,18 +75,22 @@ struct als_feature_report {
7475 uint16_t minimum ;
7576} __packed ;
7677
78+ struct keyboard_backlight_report {
79+ uint8_t level ;
80+ } __packed ;
7781
7882static struct radio_report radio_button ;
7983static struct consumer_button_report consumer_button ;
8084static struct als_input_report als_sensor ;
8185static struct als_feature_report als_feature ;
86+ static struct keyboard_backlight_report keyboard_backlight ;
8287
8388int update_hid_key (enum media_key key , bool pressed )
8489{
8590 if (key >= HID_KEY_MAX ) {
8691 return EC_ERROR_INVAL ;
8792 }
88- if (key == HID_KEY_AIRPLANE_MODE ) {
93+ if (key == HID_KEY_AIRPLANE_MODE || key == HID_KEY_KEYBOARD_BACKLIGHT ) {
8994 key_states [key ] = pressed ;
9095 if (pressed )
9196 task_set_event (TASK_ID_HID , 1 << key , 0 );
@@ -97,6 +102,12 @@ int update_hid_key(enum media_key key, bool pressed)
97102 return EC_SUCCESS ;
98103}
99104
105+ void kblight_update_hid (uint8_t percent )
106+ {
107+ keyboard_backlight .level = percent ;
108+ update_hid_key (HID_KEY_KEYBOARD_BACKLIGHT , 1 );
109+ }
110+
100111/* Called on AP S5 -> S3 transition */
101112static void hid_startup (void )
102113{
@@ -285,6 +296,19 @@ static const uint8_t report_desc[] = {
285296 0x95 , 0x01 , /* Report Count (1) */
286297 0x81 , 0x02 , /* Input (Data,Arr,Abs) */
287298 0xC0 , /* END_COLLECTION */
299+
300+ /* Keyboard Backlight Level Collection */
301+ 0x05 , 0x0C , /* USAGE_PAGE (Consumer Devices) */
302+ 0x09 , 0x01 , /* USAGE (Consumer Control) */
303+ 0xA1 , 0x01 , /* COLLECTION (Application) */
304+ 0x85 , REPORT_ID_KEYBOARD_BACKLIGHT , /* Report ID (Keyboard Backlight) */
305+ 0x15 , 0x00 , /* LOGICAL_MINIMUM (0) */
306+ 0x25 , 0x64 , /* LOGICAL_MAXIMUM (100) */
307+ 0x09 , 0x7B , /* USAGE (Keyboard Backlight Set Level) */
308+ 0x95 , 0x01 , /* REPORT_COUNT (1) */
309+ 0x75 , 0x08 , /* REPORT_SIZE (8) */
310+ 0x81 , 0x02 , /* INPUT (Data,Var,Abs) */
311+ 0xC0 , /* END_COLLECTION */
288312};
289313
290314
@@ -478,6 +502,12 @@ static int i2c_hid_touchpad_command_process(size_t len, uint8_t *buffer)
478502 sizeof (struct als_feature_report ));
479503 }
480504 break ;
505+ case REPORT_ID_KEYBOARD_BACKLIGHT :
506+ response_len =
507+ fill_report (buffer , report_id ,
508+ & keyboard_backlight ,
509+ sizeof (struct keyboard_backlight_report ));
510+ break ;
481511 default :
482512 response_len = 2 ;
483513 buffer [0 ] = response_len ;
@@ -564,7 +594,12 @@ int i2c_hid_process(unsigned int len, uint8_t *buffer)
564594 fill_report (buffer , REPORT_ID_SENSOR ,
565595 & als_sensor ,
566596 sizeof (struct als_input_report ));
567- }
597+ } else if (input_mode == REPORT_ID_KEYBOARD_BACKLIGHT ) {
598+ response_len =
599+ fill_report (buffer , REPORT_ID_KEYBOARD_BACKLIGHT ,
600+ & keyboard_backlight ,
601+ sizeof (struct keyboard_backlight_report ));
602+ };
568603 break ;
569604 case I2C_HID_COMMAND_REGISTER :
570605 response_len = i2c_hid_touchpad_command_process (len , buffer );
@@ -673,6 +708,9 @@ void hid_handler_task(void *p)
673708 input_mode = REPORT_ID_RADIO ;
674709 radio_button .state = key_states [i ] ? 1 : 0 ;
675710 break ;
711+ case HID_KEY_KEYBOARD_BACKLIGHT :
712+ input_mode = REPORT_ID_KEYBOARD_BACKLIGHT ;
713+ break ;
676714 case HID_ALS_REPORT_LUX :
677715
678716 input_mode = REPORT_ID_SENSOR ;
0 commit comments