diff options
author | Wei-Ning Huang <wnhuang@google.com> | 2017-11-15 11:15:25 +0800 |
---|---|---|
committer | chrome-bot <chrome-bot@chromium.org> | 2017-12-12 03:57:19 -0800 |
commit | 4ced1d7d6a903e8ae3e22ec2f754566f937bc6bd (patch) | |
tree | 75349dcc49618e258dc46cee78f02c878c817520 /chip | |
parent | e3c1e2265c732d465f3df90e5ea64bd02f02234f (diff) | |
download | chrome-ec-4ced1d7d6a903e8ae3e22ec2f754566f937bc6bd.tar.gz |
chip/stm32/usb_hid_keyboard: add dynamic backlight detection support
In order to make a single hammer image support both base with and
without keyboard backlight. We need a way to dynamically determine if
backlight is present, and send the correct HID descriptors. This is done
through declaring two HID descriptors and return the correct one
depending on whether or not the backlight is present.
BRANCH=none
BUG=b:67722756
TEST=On reworked board with pull-down on backlight pin,
USB descriptor has backlight HID report descriptor, and is
functional.
TEST=On old board with both pull-up and pull-down (equivalent to
having pull-up only, i.e. no backlight)
USB descriptor does not have backlight HID report descriptor
Change-Id: Ie3eac9b3d4cd749308ccfb96a7db469701f9793b
Signed-off-by: Nicolas Boichat <drinkcat@chromium.org>
Reviewed-on: https://chromium-review.googlesource.com/770600
Reviewed-by: Vincent Palatin <vpalatin@chromium.org>
Diffstat (limited to 'chip')
-rw-r--r-- | chip/stm32/usb_hid_keyboard.c | 155 | ||||
-rw-r--r-- | chip/stm32/usb_hw.h | 3 |
2 files changed, 107 insertions, 51 deletions
diff --git a/chip/stm32/usb_hid_keyboard.c b/chip/stm32/usb_hid_keyboard.c index 0d30783a1e..e882b88d7b 100644 --- a/chip/stm32/usb_hid_keyboard.c +++ b/chip/stm32/usb_hid_keyboard.c @@ -162,66 +162,96 @@ const struct usb_endpoint_descriptor USB_EP_DESC(USB_IFACE_HID_KEYBOARD, 02) = { }; #endif +#define KEYBOARD_BASE_DESC \ + 0x05, 0x01, /* Usage Page (Generic Desktop) */ \ + 0x09, 0x06, /* Usage (Keyboard) */ \ + 0xA1, 0x01, /* Collection (Application) */ \ + \ + /* Modifiers */ \ + 0x05, 0x07, /* Usage Page (Key Codes) */ \ + 0x19, HID_KEYBOARD_MODIFIER_LOW, /* Usage Minimum */ \ + 0x29, HID_KEYBOARD_MODIFIER_HIGH, /* Usage Maximum */ \ + 0x15, 0x00, /* Logical Minimum (0) */ \ + 0x25, 0x01, /* Logical Maximum (1) */ \ + 0x75, 0x01, /* Report Size (1) */ \ + 0x95, 0x08, /* Report Count (8) */ \ + 0x81, 0x02, /* Input (Data, Variable, Absolute), ;Modifier byte */ \ + \ + 0x95, 0x01, /* Report Count (1) */ \ + 0x75, 0x08, /* Report Size (8) */ \ + 0x81, 0x01, /* Input (Constant), ;Reserved byte */ \ + \ + /* Normal keys */ \ + 0x95, 0x06, /* Report Count (6) */ \ + 0x75, 0x08, /* Report Size (8) */ \ + 0x15, 0x00, /* Logical Minimum (0) */ \ + 0x25, 0xa4, /* Logical Maximum (164) */ \ + 0x05, 0x07, /* Usage Page (Key Codes) */ \ + 0x19, 0x00, /* Usage Minimum (0) */ \ + 0x29, 0xa4, /* Usage Maximum (164) */ \ + 0x81, 0x00, /* Input (Data, Array), ;Key arrays (6 bytes) */ + +#define KEYBOARD_NEW_KEY_DESC \ + 0x06, 0xd1, 0xff, /* Usage Page (Vendor-defined 0xffd1) */ \ + 0x19, 0x18, /* Usage Minimum */ \ + 0x29, 0x18, /* Usage Maximum */ \ + 0x15, 0x00, /* Logical Minimum (0) */ \ + 0x25, 0x01, /* Logical Maximum (1) */ \ + 0x75, 0x01, /* Report Size (1) */ \ + 0x95, 0x01, /* Report Count (1) */ \ + 0x81, 0x02, /* Input (Data, Variable, Absolute), ;Modifier byte */ \ + \ + 0x95, 0x01, /* Report Count (1) */ \ + 0x75, 0x07, /* Report Size (7) */ \ + 0x81, 0x01, /* Input (Constant), ;7-bit padding */ + +#define KEYBOARD_BACKLIGHT_DESC \ + 0xA1, 0x02, /* Collection (Logical) */ \ + 0x05, 0x14, /* Usage Page (Alphanumeric Display) */ \ + 0x09, 0x46, /* Usage (Display Brightness) */ \ + 0x95, 0x01, /* Report Count (1) */ \ + 0x75, 0x08, /* Report Size (8) */ \ + 0x15, 0x00, /* Logical Minimum (0) */ \ + 0x25, 0x64, /* Logical Maximum (100) */ \ + 0x91, 0x02, /* Output (Data, Variable, Absolute) */ \ + 0xC0, /* End Collection */ + +/* + * To allow dynamic detection of keyboard backlights, we define two descriptors. + * One has keyboard backlight, and the other one does not. + */ + /* HID : Report Descriptor */ static const uint8_t report_desc[] = { - 0x05, 0x01, /* Usage Page (Generic Desktop) */ - 0x09, 0x06, /* Usage (Keyboard) */ - 0xA1, 0x01, /* Collection (Application) */ - - /* Modifiers */ - 0x05, 0x07, /* Usage Page (Key Codes) */ - 0x19, HID_KEYBOARD_MODIFIER_LOW, /* Usage Minimum */ - 0x29, HID_KEYBOARD_MODIFIER_HIGH, /* Usage Maximum */ - 0x15, 0x00, /* Logical Minimum (0) */ - 0x25, 0x01, /* Logical Maximum (1) */ - 0x75, 0x01, /* Report Size (1) */ - 0x95, 0x08, /* Report Count (8) */ - 0x81, 0x02, /* Input (Data, Variable, Absolute), ;Modifier byte */ - - 0x95, 0x01, /* Report Count (1) */ - 0x75, 0x08, /* Report Size (8) */ - 0x81, 0x01, /* Input (Constant), ;Reserved byte */ - - /* Normal keys */ - 0x95, 0x06, /* Report Count (6) */ - 0x75, 0x08, /* Report Size (8) */ - 0x15, 0x00, /* Logical Minimum (0) */ - 0x25, 0xa4, /* Logical Maximum (164) */ - 0x05, 0x07, /* Usage Page (Key Codes) */ - 0x19, 0x00, /* Usage Minimum (0) */ - 0x29, 0xa4, /* Usage Maximum (164) */ - 0x81, 0x00, /* Input (Data, Array), ;Key arrays (6 bytes) */ + + KEYBOARD_BASE_DESC #ifdef CONFIG_KEYBOARD_NEW_KEY - 0x06, 0xd1, 0xff, /* Usage Page (Vendor-defined 0xffd1) */ - 0x19, 0x18, /* Usage Minimum */ - 0x29, 0x18, /* Usage Maximum */ - 0x15, 0x00, /* Logical Minimum (0) */ - 0x25, 0x01, /* Logical Maximum (1) */ - 0x75, 0x01, /* Report Size (1) */ - 0x95, 0x01, /* Report Count (1) */ - 0x81, 0x02, /* Input (Data, Variable, Absolute), ;Modifier byte */ - - 0x95, 0x01, /* Report Count (1) */ - 0x75, 0x07, /* Report Size (7) */ - 0x81, 0x01, /* Input (Constant), ;7-bit padding */ + KEYBOARD_NEW_KEY_DESC #endif + 0xC0 /* End Collection */ +}; + + #ifdef CONFIG_USB_HID_KEYBOARD_BACKLIGHT - 0xA1, 0x02, /* Collection (Logical) */ - 0x05, 0x14, /* Usage Page (Alphanumeric Display) */ - 0x09, 0x46, /* Usage (Display Brightness) */ - 0x95, 0x01, /* Report Count (1) */ - 0x75, 0x08, /* Report Size (8) */ - 0x15, 0x00, /* Logical Minimum (0) */ - 0x25, 0x64, /* Logical Maximum (100) */ - 0x91, 0x02, /* Output (Data, Variable, Absolute) */ - 0xC0, /* End Collection */ + +/* HID : Report Descriptor with keyboard backlight */ +static const uint8_t report_desc_with_backlight[] = { + + KEYBOARD_BASE_DESC + +#ifdef CONFIG_KEYBOARD_NEW_KEY + KEYBOARD_NEW_KEY_DESC #endif + KEYBOARD_BACKLIGHT_DESC + 0xC0 /* End Collection */ }; +#endif + /* HID: HID Descriptor */ const struct usb_hid_descriptor USB_CUSTOM_DESC_VAR(USB_IFACE_HID_KEYBOARD, hid, hid_desc_kb) = { @@ -348,9 +378,19 @@ USB_DECLARE_EP(USB_EP_HID_KEYBOARD, hid_keyboard_tx, static int hid_keyboard_iface_request(usb_uint *ep0_buf_rx, usb_uint *ep0_buf_tx) { - int ret = hid_iface_request(ep0_buf_rx, ep0_buf_tx, - report_desc, sizeof(report_desc), - &hid_desc_kb); + int ret; + const uint8_t *desc = report_desc; + uint32_t size = sizeof(report_desc); + +#ifdef CONFIG_USB_HID_KEYBOARD_BACKLIGHT + if (board_has_keyboard_backlight()) { + desc = report_desc_with_backlight; + size = sizeof(report_desc_with_backlight); + } +#endif + + ret = hid_iface_request(ep0_buf_rx, ep0_buf_tx, + desc, size, &hid_desc_kb); if (ret >= 0) return ret; @@ -530,3 +570,16 @@ void keyboard_state_changed(int row, int col, int is_pressed) keyboard_process_queue(); } + +#ifdef CONFIG_USB_HID_KEYBOARD_BACKLIGHT +void usb_hid_keyboard_init(void) +{ + if (board_has_keyboard_backlight()) { + set_descriptor_patch(USB_DESC_KEYBOARD_BACKLIGHT, + &hid_desc_kb.desc[0].wDescriptorLength, + sizeof(report_desc_with_backlight)); + } +} +/* This needs to happen before usb_init (HOOK_PRIO_DEFAULT) */ +DECLARE_HOOK(HOOK_INIT, usb_hid_keyboard_init, HOOK_PRIO_DEFAULT - 1); +#endif diff --git a/chip/stm32/usb_hw.h b/chip/stm32/usb_hw.h index 94734d8569..0ba7fb369d 100644 --- a/chip/stm32/usb_hw.h +++ b/chip/stm32/usb_hw.h @@ -69,6 +69,9 @@ void *memcpy_from_usbram(void *dest, const void *src, size_t n); */ enum usb_desc_patch_type { +#ifdef CONFIG_USB_HID_KEYBOARD_BACKLIGHT + USB_DESC_KEYBOARD_BACKLIGHT, +#endif USB_DESC_PATCH_COUNT, }; |