Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Report fn key and lock states via HID #55

Open
wants to merge 2 commits into
base: fwk-hx20-hx30-4410
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 10 additions & 0 deletions board/hx20/host_command_customization.c
Original file line number Diff line number Diff line change
Expand Up @@ -290,3 +290,13 @@ static enum ec_status standalone_mode(struct host_cmd_handler_args *args)

}
DECLARE_HOST_COMMAND(EC_CMD_STANDALONE_MODE, standalone_mode, EC_VER_MASK(0));

static enum ec_status display_toggle_key_hid(struct host_cmd_handler_args *args)
{
const struct ec_params_display_toggle_key_hid *p = args->params;

set_display_toggle_key_hid(p->enable);
return EC_RES_SUCCESS;

}
DECLARE_HOST_COMMAND(EC_CMD_DISPLAY_TOGGLE_KEY_HID, display_toggle_key_hid, EC_VER_MASK(0));
8 changes: 8 additions & 0 deletions board/hx20/host_command_customization.h
Original file line number Diff line number Diff line change
Expand Up @@ -203,4 +203,12 @@ struct ec_params_standalone_mode {
uint8_t enable;
} __ec_align1;

/* If enabled, display key emits HID System Display Toggle Int/Ext Mode;
otherwise emits Win+P */
#define EC_CMD_DISPLAY_TOGGLE_KEY_HID 0x3E16

struct ec_params_display_toggle_key_hid {
uint8_t enable;
} __ec_align1;

#endif /* __HOST_COMMAND_CUSTOMIZATION_H */
84 changes: 78 additions & 6 deletions board/hx20/i2c_hid_mediakeys.c
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@

#define REPORT_ID_RADIO 0x01
#define REPORT_ID_CONSUMER 0x02
#define REPORT_ID_SYSTEM 0x04

/*
* See hid usage tables for consumer page
Expand All @@ -49,20 +50,28 @@ struct consumer_button_report {
uint16_t button_id;
} __packed;

struct system_report {
uint8_t state;
} __packed;

enum system_buttons: uint8_t {
SYSTEM_KEY_FN = BIT(0),
SYSTEM_KEY_FN_LOCK = BIT(1),
SYSTEM_FN_LOCK_INDICATOR = BIT(2),
SYSTEM_KEY_DISPLAY_TOGGLE = BIT(3),
};

static struct radio_report radio_button;
static struct consumer_button_report consumer_button;
static struct system_report system_buttons;


int update_hid_key(enum media_key key, bool pressed)
{
if (key >= HID_KEY_MAX) {
return EC_ERROR_INVAL;
}
if (key == HID_KEY_AIRPLANE_MODE) {
key_states[key] = pressed;
if (pressed)
task_set_event(TASK_ID_HID, 1 << key, 0);
} else if (key_states[key] != pressed) {
if (key_states[key] != pressed) {
key_states[key] = pressed;
task_set_event(TASK_ID_HID, 1 << key, 0);
}
Expand Down Expand Up @@ -121,6 +130,26 @@ static const uint8_t report_desc[] = {
0x81, 0x00, /* Input (Data,Arr,Abs) */
0xC0, /* END_COLLECTION */

/* System Control Collection */
0x05, 0x01, /* USAGE_PAGE (Generic Desktop) */
0x09, 0x80, /* USAGE (System Control) */
0xA1, 0x01, /* COLLECTION (Application) */
0x85, REPORT_ID_SYSTEM, /* Report ID (System) */
0x15, 0x00, /* LOGICAL_MINIMUM (0) */
0x25, 0x01, /* LOGICAL_MAXIMUM (1) */
0x95, 0x01, /* REPORT_COUNT (1) */
0x75, 0x01, /* REPORT_SIZE (1) */
0x09, 0x97, /* USAGE (System Function Shift) */
0x81, 0x02, /* INPUT (Data,Var,Abs) */
0x09, 0x98, /* USAGE (System Function Shift Lock) */
0x81, 0x06, /* INPUT (Data,Var,Rel) */
0x09, 0x99, /* USAGE (System Function Shift Lock Indicator) */
0x81, 0x02, /* INPUT (Data,Var,Abs) */
0x09, 0xB5, /* USAGE (System Display Toggle Int/Ext Mode) */
0x81, 0x06, /* INPUT (Data,Var,Rel) */
0x75, 0x04, /* REPORT_SIZE (4) */
0x81, 0x03, /* INPUT (Cnst,Var,Abs) */
0xC0, /* END_COLLECTION */
};


Expand Down Expand Up @@ -220,6 +249,12 @@ static int i2c_hid_touchpad_command_process(size_t len, uint8_t *buffer)
&consumer_button,
sizeof(struct consumer_button_report));
break;
case REPORT_ID_SYSTEM:
response_len =
fill_report(buffer, report_id,
&system_buttons,
sizeof(struct system_report));
break;
default:
response_len = 2;
buffer[0] = response_len;
Expand Down Expand Up @@ -297,11 +332,16 @@ int i2c_hid_process(unsigned int len, uint8_t *buffer)
fill_report(buffer, REPORT_ID_RADIO,
&radio_button,
sizeof(struct radio_report));
} else {
} else if (input_mode == REPORT_ID_CONSUMER) {
response_len =
fill_report(buffer, REPORT_ID_CONSUMER,
&consumer_button,
sizeof(struct consumer_button_report));
} else if (input_mode == REPORT_ID_SYSTEM) {
response_len =
fill_report(buffer, REPORT_ID_SYSTEM,
&system_buttons,
sizeof(struct system_report));
}
break;
case I2C_HID_COMMAND_REGISTER:
Expand Down Expand Up @@ -399,6 +439,38 @@ void hid_handler_task(void *p)
input_mode = REPORT_ID_RADIO;
radio_button.state = key_states[i] ? 1 : 0;
break;
case HID_KEY_FN:
input_mode = REPORT_ID_SYSTEM;
if (key_states[i]) {
system_buttons.state |= SYSTEM_KEY_FN;
} else {
system_buttons.state &= ~SYSTEM_KEY_FN;
}
break;
case HID_KEY_FN_LOCK:
input_mode = REPORT_ID_SYSTEM;
if (key_states[i]) {
system_buttons.state |= SYSTEM_KEY_FN_LOCK;
} else {
system_buttons.state &= ~SYSTEM_KEY_FN_LOCK;
}
break;
case HID_FN_LOCK_INDICATOR:
input_mode = REPORT_ID_SYSTEM;
if (key_states[i]) {
system_buttons.state |= SYSTEM_FN_LOCK_INDICATOR;
} else {
system_buttons.state &= ~SYSTEM_FN_LOCK_INDICATOR;
}
break;
case HID_KEY_DISPLAY_TOGGLE:
input_mode = REPORT_ID_SYSTEM;
if (key_states[i]) {
system_buttons.state |= SYSTEM_KEY_DISPLAY_TOGGLE;
} else {
system_buttons.state &= ~SYSTEM_KEY_DISPLAY_TOGGLE;
}
break;
}
hid_irq_to_host();
}
Expand Down
5 changes: 4 additions & 1 deletion board/hx20/i2c_hid_mediakeys.h
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,10 @@ enum media_key {
HID_KEY_DISPLAY_BRIGHTNESS_UP,
HID_KEY_DISPLAY_BRIGHTNESS_DN,
HID_KEY_AIRPLANE_MODE,

HID_KEY_FN,
HID_KEY_FN_LOCK,
HID_FN_LOCK_INDICATOR,
HID_KEY_DISPLAY_TOGGLE,
HID_KEY_MAX
};
/*HID_KEY_MAX cannot be > TASK_EVENT_CUSTOM_BIT*/
Expand Down
40 changes: 27 additions & 13 deletions board/hx20/keyboard_customization.c
Original file line number Diff line number Diff line change
Expand Up @@ -216,6 +216,14 @@ void board_kblight_init(void)
}
#endif

uint8_t display_toggle_key_hid = 0;

void set_display_toggle_key_hid(uint8_t enable)
{
CPRINTS("set display_toggle_key_hid = %hhd", enable);
display_toggle_key_hid = enable;
}

#ifdef CONFIG_KEYBOARD_CUSTOMIZATION_COMBINATION_KEY
#define FN_PRESSED BIT(0)
#define FN_LOCKED BIT(1)
Expand Down Expand Up @@ -273,6 +281,8 @@ void fnkey_startup(void) {
Fn_key |= FN_LOCKED;
}
}

update_hid_key(HID_FN_LOCK_INDICATOR, (Fn_key & FN_LOCKED) != 0);
}
DECLARE_HOOK(HOOK_CHIPSET_STARTUP, fnkey_startup, HOOK_PRIO_DEFAULT);

Expand Down Expand Up @@ -329,12 +339,11 @@ int hotkey_F1_F12(uint16_t *key_code, uint16_t fn, int8_t pressed)
break;
case SCANCODE_F9: /* EXTERNAL_DISPLAY */
if (fn_table_media_set(pressed, KB_FN_F9)) {
if (pressed) {
simulate_keyboard(SCANCODE_LEFT_WIN, 1);
simulate_keyboard(SCANCODE_P, 1);
if (display_toggle_key_hid) {
update_hid_key(HID_KEY_DISPLAY_TOGGLE, pressed);
} else {
simulate_keyboard(SCANCODE_P, 0);
simulate_keyboard(SCANCODE_LEFT_WIN, 0);
simulate_keyboard(SCANCODE_LEFT_WIN, pressed);
simulate_keyboard(SCANCODE_P, pressed);
}
return EC_ERROR_UNIMPLEMENTED;
}
Expand Down Expand Up @@ -415,11 +424,15 @@ int functional_hotkey(uint16_t *key_code, int8_t pressed)
switch (prss_key) {
case SCANCODE_ESC: /* TODO: FUNCTION_LOCK */
if (fn_table_set(pressed, KB_FN_ESC)) {
update_hid_key(HID_KEY_FN_LOCK, pressed);
if (pressed) {
if (Fn_key & FN_LOCKED)
if (Fn_key & FN_LOCKED) {
Fn_key &= ~FN_LOCKED;
else
update_hid_key(HID_FN_LOCK_INDICATOR, 0);
} else {
Fn_key |= FN_LOCKED;
update_hid_key(HID_FN_LOCK_INDICATOR, 1);
}
}
return EC_ERROR_UNIMPLEMENTED;
}
Expand Down Expand Up @@ -488,12 +501,13 @@ enum ec_error_list keyboard_scancode_callback(uint16_t *make_code,
if (factory_status())
return EC_SUCCESS;

if (pressed_key == SCANCODE_FN && pressed) {
Fn_key |= FN_PRESSED;
return EC_ERROR_UNIMPLEMENTED;
} else if (pressed_key == SCANCODE_FN && !pressed) {
Fn_key &= ~FN_PRESSED;
return EC_ERROR_UNIMPLEMENTED;
if (pressed_key == SCANCODE_FN) {
if (pressed) {
Fn_key |= FN_PRESSED;
} else {
Fn_key &= ~FN_PRESSED;
}
update_hid_key(HID_KEY_FN, pressed);
}

/*
Expand Down
2 changes: 2 additions & 0 deletions board/hx20/keyboard_customization.h
Original file line number Diff line number Diff line change
Expand Up @@ -112,4 +112,6 @@ int factory_status(void);
void hx20_8042_led_control(int data);
#endif

void set_display_toggle_key_hid(uint8_t enable);

#endif /* __KEYBOARD_CUSTOMIZATION_H */
10 changes: 10 additions & 0 deletions board/hx30/host_command_customization.c
Original file line number Diff line number Diff line change
Expand Up @@ -353,3 +353,13 @@ static enum ec_status standalone_mode(struct host_cmd_handler_args *args)
}
DECLARE_HOST_COMMAND(EC_CMD_STANDALONE_MODE, standalone_mode, EC_VER_MASK(0));

static enum ec_status display_toggle_key_hid(struct host_cmd_handler_args *args)
{
const struct ec_params_display_toggle_key_hid *p = args->params;

set_display_toggle_key_hid(p->enable);
return EC_RES_SUCCESS;

}
DECLARE_HOST_COMMAND(EC_CMD_DISPLAY_TOGGLE_KEY_HID, display_toggle_key_hid, EC_VER_MASK(0));

8 changes: 8 additions & 0 deletions board/hx30/host_command_customization.h
Original file line number Diff line number Diff line change
Expand Up @@ -229,4 +229,12 @@ struct ec_response_chassis_counter {
uint8_t press_counter;
} __ec_align1;

/* If enabled, display key emits HID System Display Toggle Int/Ext Mode;
otherwise emits Win+P */
#define EC_CMD_DISPLAY_TOGGLE_KEY_HID 0x3E16

struct ec_params_display_toggle_key_hid {
uint8_t enable;
} __ec_align1;

#endif /* __HOST_COMMAND_CUSTOMIZATION_H */
Loading