Skip to content

Commit a451f79

Browse files
fwk: emit HID event when keyboard brightness changed via fn+space
Currently, changing the keyboard backlight brightness via fn+space does not notify the OS in any way. Therefore, OS indicators like GNOME Shell's keyboard backlight slider will show the wrong values. This PR corrects this issue by emitting a "Keyboard Backlight Set Level" HID event on fn+space. Signed-off-by: Jules Bertholet <[email protected]>
1 parent 553827c commit a451f79

6 files changed

+88
-6
lines changed

board/hx20/i2c_hid_mediakeys.c

+42-3
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@
2323

2424
#define REPORT_ID_RADIO 0x01
2525
#define REPORT_ID_CONSUMER 0x02
26+
#define REPORT_ID_KEYBOARD_BACKLIGHT 0x05
2627

2728
/*
2829
* See hid usage tables for consumer page
@@ -49,16 +50,21 @@ struct consumer_button_report {
4950
uint16_t button_id;
5051
} __packed;
5152

53+
struct keyboard_backlight_report {
54+
uint8_t level;
55+
} __packed;
56+
5257
static struct radio_report radio_button;
5358
static struct consumer_button_report consumer_button;
59+
static struct keyboard_backlight_report keyboard_backlight;
5460

5561

5662
int update_hid_key(enum media_key key, bool pressed)
5763
{
5864
if (key >= HID_KEY_MAX) {
5965
return EC_ERROR_INVAL;
6066
}
61-
if (key == HID_KEY_AIRPLANE_MODE) {
67+
if (key == HID_KEY_AIRPLANE_MODE || key == HID_KEY_KEYBOARD_BACKLIGHT) {
6268
key_states[key] = pressed;
6369
if (pressed)
6470
task_set_event(TASK_ID_HID, 1 << key, 0);
@@ -70,6 +76,13 @@ int update_hid_key(enum media_key key, bool pressed)
7076
return EC_SUCCESS;
7177
}
7278

79+
80+
void kblight_update_hid(uint8_t percent)
81+
{
82+
keyboard_backlight.level = percent;
83+
update_hid_key(HID_KEY_KEYBOARD_BACKLIGHT, 1);
84+
}
85+
7386
/* Called on AP S5 -> S3 transition */
7487
static void hid_startup(void)
7588
{
@@ -121,6 +134,18 @@ static const uint8_t report_desc[] = {
121134
0x81, 0x00, /* Input (Data,Arr,Abs) */
122135
0xC0, /* END_COLLECTION */
123136

137+
/* Keyboard Backlight Level Collection */
138+
0x05, 0x0C, /* USAGE_PAGE (Consumer Devices) */
139+
0x09, 0x01, /* USAGE (Consumer Control) */
140+
0xA1, 0x01, /* COLLECTION (Application) */
141+
0x85, REPORT_ID_KEYBOARD_BACKLIGHT, /* Report ID (Keyboard Backlight) */
142+
0x15, 0x00, /* LOGICAL_MINIMUM (0) */
143+
0x25, 0x64, /* LOGICAL_MAXIMUM (100) */
144+
0x09, 0x7B, /* USAGE (Keyboard Backlight Set Level) */
145+
0x95, 0x01, /* REPORT_COUNT (1) */
146+
0x75, 0x08, /* REPORT_SIZE (8) */
147+
0x81, 0x02, /* INPUT (Data,Var,Abs) */
148+
0xC0, /* END_COLLECTION */
124149
};
125150

126151

@@ -220,6 +245,12 @@ static int i2c_hid_touchpad_command_process(size_t len, uint8_t *buffer)
220245
&consumer_button,
221246
sizeof(struct consumer_button_report));
222247
break;
248+
case REPORT_ID_KEYBOARD_BACKLIGHT:
249+
response_len =
250+
fill_report(buffer, report_id,
251+
&keyboard_backlight,
252+
sizeof(struct keyboard_backlight_report));
253+
break;
223254
default:
224255
response_len = 2;
225256
buffer[0] = response_len;
@@ -297,12 +328,17 @@ int i2c_hid_process(unsigned int len, uint8_t *buffer)
297328
fill_report(buffer, REPORT_ID_RADIO,
298329
&radio_button,
299330
sizeof(struct radio_report));
300-
} else {
331+
} else if (input_mode == REPORT_ID_CONSUMER) {
301332
response_len =
302333
fill_report(buffer, REPORT_ID_CONSUMER,
303334
&consumer_button,
304335
sizeof(struct consumer_button_report));
305-
}
336+
} else if (input_mode == REPORT_ID_KEYBOARD_BACKLIGHT) {
337+
response_len =
338+
fill_report(buffer, REPORT_ID_KEYBOARD_BACKLIGHT,
339+
&keyboard_backlight,
340+
sizeof(struct keyboard_backlight_report));
341+
};
306342
break;
307343
case I2C_HID_COMMAND_REGISTER:
308344
response_len = i2c_hid_touchpad_command_process(len, buffer);
@@ -399,6 +435,9 @@ void hid_handler_task(void *p)
399435
input_mode = REPORT_ID_RADIO;
400436
radio_button.state = key_states[i] ? 1 : 0;
401437
break;
438+
case HID_KEY_KEYBOARD_BACKLIGHT:
439+
input_mode = REPORT_ID_KEYBOARD_BACKLIGHT;
440+
break;
402441
}
403442
hid_irq_to_host();
404443
}

board/hx20/i2c_hid_mediakeys.h

+2-1
Original file line numberDiff line numberDiff line change
@@ -28,12 +28,13 @@ enum media_key {
2828
HID_KEY_DISPLAY_BRIGHTNESS_UP,
2929
HID_KEY_DISPLAY_BRIGHTNESS_DN,
3030
HID_KEY_AIRPLANE_MODE,
31-
31+
HID_KEY_KEYBOARD_BACKLIGHT,
3232
HID_KEY_MAX
3333
};
3434
/*HID_KEY_MAX cannot be > TASK_EVENT_CUSTOM_BIT*/
3535
BUILD_ASSERT(HID_KEY_MAX < 16);
3636

3737
int update_hid_key(enum media_key key, bool pressed);
38+
void kblight_update_hid(uint8_t percent);
3839

3940
#endif /* __CROS_EC_I2C_HID_MEDIAKEYS_H */

board/hx20/keyboard_customization.c

+1
Original file line numberDiff line numberDiff line change
@@ -470,6 +470,7 @@ int functional_hotkey(uint16_t *key_code, int8_t pressed)
470470
break;
471471
}
472472
kblight_set(bl_brightness);
473+
kblight_update_hid(bl_brightness);
473474
}
474475
/* we dont want to pass the space key event to the OS */
475476
return EC_ERROR_UNIMPLEMENTED;

board/hx30/i2c_hid_mediakeys.c

+40-2
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@
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

7882
static struct radio_report radio_button;
7983
static struct consumer_button_report consumer_button;
8084
static struct als_input_report als_sensor;
8185
static struct als_feature_report als_feature;
86+
static struct keyboard_backlight_report keyboard_backlight;
8287

8388
int 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 */
101112
static 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;

board/hx30/i2c_hid_mediakeys.h

+2
Original file line numberDiff line numberDiff line change
@@ -81,6 +81,7 @@ enum media_key {
8181
HID_KEY_DISPLAY_BRIGHTNESS_UP,
8282
HID_KEY_DISPLAY_BRIGHTNESS_DN,
8383
HID_KEY_AIRPLANE_MODE,
84+
HID_KEY_KEYBOARD_BACKLIGHT,
8485
HID_ALS_REPORT_LUX,
8586
HID_KEY_MAX
8687
};
@@ -89,5 +90,6 @@ BUILD_ASSERT(HID_KEY_MAX < 16);
8990

9091
int update_hid_key(enum media_key key, bool pressed);
9192
void set_illuminance_value(uint16_t value);
93+
void kblight_update_hid(uint8_t percent);
9294

9395
#endif /* __CROS_EC_I2C_HID_MEDIAKEYS_H */

board/hx30/keyboard_customization.c

+1
Original file line numberDiff line numberDiff line change
@@ -470,6 +470,7 @@ int functional_hotkey(uint16_t *key_code, int8_t pressed)
470470
break;
471471
}
472472
kblight_set(bl_brightness);
473+
kblight_update_hid(bl_brightness);
473474
}
474475
/* we dont want to pass the space key event to the OS */
475476
return EC_ERROR_UNIMPLEMENTED;

0 commit comments

Comments
 (0)