summaryrefslogtreecommitdiff
path: root/chip
diff options
context:
space:
mode:
authorWei-Ning Huang <wnhuang@google.com>2017-11-15 11:15:25 +0800
committerchrome-bot <chrome-bot@chromium.org>2017-12-12 03:57:19 -0800
commit4ced1d7d6a903e8ae3e22ec2f754566f937bc6bd (patch)
tree75349dcc49618e258dc46cee78f02c878c817520 /chip
parente3c1e2265c732d465f3df90e5ea64bd02f02234f (diff)
downloadchrome-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.c155
-rw-r--r--chip/stm32/usb_hw.h3
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,
};