diff options
author | Nicolas Boichat <drinkcat@chromium.org> | 2018-05-30 15:55:57 +0800 |
---|---|---|
committer | chrome-bot <chrome-bot@chromium.org> | 2018-06-06 05:00:49 -0700 |
commit | 65d87bf9f0ef9b084d91ed44eda58b7463c82b48 (patch) | |
tree | 64bcafd6797a3a60bc9c5a7e2164688ad9bb7a38 | |
parent | 8290d879dab1fbba805cfcdb4f2409bdee803dc6 (diff) | |
download | chrome-ec-65d87bf9f0ef9b084d91ed44eda58b7463c82b48.tar.gz |
whiskers: Expose a switch for tablet mode
With this, whiskers exposes a tablet mode switch to inform the
lid when the base is flipped around.
We take this opportunity to clean up a bit whiskers/keyboard
code:
- Use tablet mode switch instead of lid switch
- Refactor usb_hid_keyboard.c to accept either assistant key
or tablet mode switch, or both.
- Remove bit-field usage in HID report struct, and instead,
generalize with an "extra" field that can be used for
additional key/switches.
BRANCH=none
BUG=b:73133611
TEST=Flash whiskers, see that tablet mode events are sent when
a magnet approaches the hall sensor.
Change-Id: Ibf43bb04fdc867d18d9f318388d1ebd17b49d47f
Signed-off-by: Nicolas Boichat <drinkcat@chromium.org>
Reviewed-on: https://chromium-review.googlesource.com/1077915
Reviewed-by: Wei-Han Chen <stimim@chromium.org>
-rw-r--r-- | board/hammer/board.c | 14 | ||||
-rw-r--r-- | board/hammer/board.h | 6 | ||||
-rw-r--r-- | board/hammer/gpio.inc | 2 | ||||
-rw-r--r-- | chip/stm32/usb_hid_keyboard.c | 108 | ||||
-rw-r--r-- | common/tablet_mode.c | 2 | ||||
-rw-r--r-- | include/config.h | 3 |
6 files changed, 98 insertions, 37 deletions
diff --git a/board/hammer/board.c b/board/hammer/board.c index e0edde5884..80910fbf16 100644 --- a/board/hammer/board.c +++ b/board/hammer/board.c @@ -15,7 +15,6 @@ #include "i2c.h" #include "keyboard_raw.h" #include "keyboard_scan.h" -#include "lid_switch.h" #include "printf.h" #include "pwm.h" #include "pwm_chip.h" @@ -25,6 +24,7 @@ #include "rollback.h" #include "spi.h" #include "system.h" +#include "tablet_mode.h" #include "task.h" #include "touchpad.h" #include "timer.h" @@ -253,18 +253,6 @@ void board_touchpad_reset(void) #endif } -#if defined(SECTION_IS_RW) && defined(BOARD_WHISKERS) -static void lid_change(void) -{ - if (lid_is_open()) - usb_connect(); - else - usb_disconnect(); -} -DECLARE_HOOK(HOOK_LID_CHANGE, lid_change, HOOK_PRIO_DEFAULT); -DECLARE_HOOK(HOOK_INIT, lid_change, HOOK_PRIO_DEFAULT + 1); -#endif - /* * Get entropy based on Clock Recovery System, which is enabled on hammer to * synchronize USB SOF with internal oscillator. diff --git a/board/hammer/board.h b/board/hammer/board.h index 0f84c53d39..aa5678f5d2 100644 --- a/board/hammer/board.h +++ b/board/hammer/board.h @@ -231,8 +231,10 @@ #ifdef BOARD_WHISKERS #define CONFIG_LED_DRIVER_LM3630A -#define CONFIG_LID_SWITCH -#define CONFIG_USB_INHIBIT_CONNECT +#define CONFIG_TABLET_MODE +#define CONFIG_TABLET_SWITCH +#define TABLET_MODE_GPIO_L GPIO_TABLET_MODE_L +#define CONFIG_KEYBOARD_TABLET_MODE_SWITCH /* Enable control of SPI over USB */ #define CONFIG_USB_SPI #define CONFIG_SPI_MASTER diff --git a/board/hammer/gpio.inc b/board/hammer/gpio.inc index 8786c435d1..4f8e28a5a7 100644 --- a/board/hammer/gpio.inc +++ b/board/hammer/gpio.inc @@ -11,7 +11,7 @@ #ifdef SECTION_IS_RW GPIO_INT(TOUCHPAD_INT, PIN(B, 8), GPIO_INT_FALLING, touchpad_interrupt) #ifdef BOARD_WHISKERS -GPIO_INT(LID_OPEN, PIN(B, 11), GPIO_PULL_UP | GPIO_INT_BOTH, lid_interrupt) +GPIO_INT(TABLET_MODE_L, PIN(B, 11), GPIO_PULL_UP | GPIO_INT_BOTH, tablet_mode_isr) #endif /* BOARD_WHISKERS */ #endif /* SECTION_IS_RW */ diff --git a/chip/stm32/usb_hid_keyboard.c b/chip/stm32/usb_hid_keyboard.c index e7c63b3fa6..566be2440f 100644 --- a/chip/stm32/usb_hid_keyboard.c +++ b/chip/stm32/usb_hid_keyboard.c @@ -17,6 +17,7 @@ #include "pwm.h" #include "queue.h" #include "registers.h" +#include "tablet_mode.h" #include "task.h" #include "timer.h" #include "util.h" @@ -49,6 +50,11 @@ enum hid_protocol { /* Current protocol, behaviour is identical in both modes. */ static enum hid_protocol protocol = HID_REPORT_PROTOCOL; +#if defined(CONFIG_KEYBOARD_ASSISTANT_KEY) || \ + defined(CONFIG_KEYBOARD_TABLET_MODE_SWITCH) +#define HID_KEYBOARD_EXTRA_FIELD +#endif + /* * Note: This first 8 bytes of this report format cannot be changed, as that * would break HID Boot protocol compatibility (see HID 1.11 "Appendix B: Boot @@ -59,9 +65,9 @@ struct usb_hid_keyboard_report { uint8_t reserved; /* 0x0 */ uint8_t keys[6]; /* Non-boot protocol fields below */ -#ifdef CONFIG_KEYBOARD_ASSISTANT_KEY - uint8_t assistant:1; - uint8_t reserved2:7; +#ifdef HID_KEYBOARD_EXTRA_FIELD + /* Assistant/tablet mode switch bitmask */ + uint8_t extra; #endif } __packed; @@ -99,7 +105,11 @@ struct usb_hid_keyboard_output_report { #define HID_KEYBOARD_MODIFIER_LOW 0xe0 #define HID_KEYBOARD_MODIFIER_HIGH 0xe7 +/* Special keys/switches */ +#define HID_KEYBOARD_EXTRA_LOW 0xf0 #define HID_KEYBOARD_ASSISTANT_KEY 0xf0 +#define HID_KEYBOARD_TABLET_MODE_SWITCH 0xf1 +#define HID_KEYBOARD_EXTRA_HIGH 0xf1 /* The standard Chrome OS keyboard matrix table. See HUT 1.12v2 Table 12 and * https://www.w3.org/TR/DOM-Level-3-Events-code . @@ -191,19 +201,56 @@ const struct usb_endpoint_descriptor USB_EP_DESC(USB_IFACE_HID_KEYBOARD, 02) = { 0x29, 0xa4, /* Usage Maximum (164) */ \ 0x81, 0x00, /* Input (Data, Array), ;Key arrays (6 bytes) */ +/* + * Vendor-defined Usage Page 0xffd1: + * - 0x18: Assistant key + * - 0x19: Tablet mode switch + */ +#ifdef HID_KEYBOARD_EXTRA_FIELD +#ifdef CONFIG_KEYBOARD_ASSISTANT_KEY #define KEYBOARD_ASSISTANT_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 */ \ + 0x81, 0x02, /* Input (Data, Variable, Absolute), ;Modifier byte */ +#else +/* No assistant key: just pad 1 bit. */ +#define KEYBOARD_ASSISTANT_KEY_DESC \ + 0x95, 0x01, /* Report Count (1) */ \ + 0x75, 0x01, /* Report Size (1) */ \ + 0x81, 0x01, /* Input (Constant), ;1-bit padding */ +#endif /* !CONFIG_KEYBOARD_ASSISTANT_KEY */ + +#ifdef CONFIG_KEYBOARD_TABLET_MODE_SWITCH +#define KEYBOARD_TABLET_MODE_SWITCH_DESC \ + 0x19, 0x19, /* Usage Minimum */ \ + 0x29, 0x19, /* 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 */ +#else +/* No tablet mode swtch: just pad 1 bit. */ +#define KEYBOARD_TABLET_MODE_SWITCH_DESC \ + 0x95, 0x01, /* Report Count (1) */ \ + 0x75, 0x01, /* Report Size (1) */ \ + 0x81, 0x01, /* Input (Constant), ;1-bit padding */ +#endif /* CONFIG_KEYBOARD_TABLET_MODE_SWITCH */ + +#define KEYBOARD_VENDOR_DESC \ + 0x06, 0xd1, 0xff, /* Usage Page (Vendor-defined 0xffd1) */ \ + \ + KEYBOARD_ASSISTANT_KEY_DESC \ + KEYBOARD_TABLET_MODE_SWITCH_DESC \ \ 0x95, 0x01, /* Report Count (1) */ \ - 0x75, 0x07, /* Report Size (7) */ \ - 0x81, 0x01, /* Input (Constant), ;7-bit padding */ + 0x75, 0x06, /* Report Size (6) */ \ + 0x81, 0x01, /* Input (Constant), ;6-bit padding */ +#endif /* HID_KEYBOARD_EXTRA_FIELD */ #define KEYBOARD_BACKLIGHT_DESC \ 0xA1, 0x02, /* Collection (Logical) */ \ @@ -226,8 +273,8 @@ static const uint8_t report_desc[] = { KEYBOARD_BASE_DESC -#ifdef CONFIG_KEYBOARD_ASSISTANT_KEY - KEYBOARD_ASSISTANT_KEY_DESC +#ifdef KEYBOARD_VENDOR_DESC + KEYBOARD_VENDOR_DESC #endif 0xC0 /* End Collection */ @@ -241,8 +288,8 @@ static const uint8_t report_desc_with_backlight[] = { KEYBOARD_BASE_DESC -#ifdef CONFIG_KEYBOARD_ASSISTANT_KEY - KEYBOARD_ASSISTANT_KEY_DESC +#ifdef KEYBOARD_VENDOR_DESC + KEYBOARD_VENDOR_DESC #endif KEYBOARD_BACKLIGHT_DESC @@ -501,9 +548,14 @@ static void keyboard_process_queue(void) queue_advance_head(&key_queue, 1); - if (ev.keycode == HID_KEYBOARD_ASSISTANT_KEY) { -#ifdef CONFIG_KEYBOARD_ASSISTANT_KEY - report.assistant = ev.pressed ? 1 : 0; + if (ev.keycode >= HID_KEYBOARD_EXTRA_LOW && + ev.keycode <= HID_KEYBOARD_EXTRA_HIGH) { +#ifdef HID_KEYBOARD_EXTRA_FIELD + mask = 0x01 << (ev.keycode - HID_KEYBOARD_EXTRA_LOW); + if (ev.pressed) + report.extra |= mask; + else + report.extra &= ~mask; valid = 1; #endif } else if (ev.keycode >= HID_KEYBOARD_MODIFIER_LOW && @@ -550,20 +602,14 @@ static void keyboard_process_queue(void) write_keyboard_report(); } -void keyboard_state_changed(int row, int col, int is_pressed) +static void queue_keycode_event(uint8_t keycode, int is_pressed) { - uint8_t keycode = keycodes[row][col]; struct key_event ev = { .time = __hw_clock_source_read(), .keycode = keycode, .pressed = is_pressed, }; - if (!keycode) { - CPRINTF("Unknown key at %d/%d\n", row, col); - return; - } - mutex_lock(&key_queue_mutex); queue_add_unit(&key_queue, &ev); mutex_unlock(&key_queue_mutex); @@ -571,6 +617,26 @@ void keyboard_state_changed(int row, int col, int is_pressed) keyboard_process_queue(); } +#ifdef CONFIG_KEYBOARD_TABLET_MODE_SWITCH +static void tablet_mode_change(void) +{ + queue_keycode_event(HID_KEYBOARD_TABLET_MODE_SWITCH, tablet_get_mode()); +} +DECLARE_HOOK(HOOK_TABLET_MODE_CHANGE, tablet_mode_change, HOOK_PRIO_DEFAULT); +#endif + +void keyboard_state_changed(int row, int col, int is_pressed) +{ + uint8_t keycode = keycodes[row][col]; + + if (!keycode) { + CPRINTF("Unknown key at %d/%d\n", row, col); + return; + } + + queue_keycode_event(keycode, is_pressed); +} + void clear_typematic_key(void) { } diff --git a/common/tablet_mode.c b/common/tablet_mode.c index 5e73dd4c93..edda95085f 100644 --- a/common/tablet_mode.c +++ b/common/tablet_mode.c @@ -41,6 +41,7 @@ static void tablet_mode_debounce(void) /* We won't reach here on boards without a dedicated tablet switch */ tablet_set_mode(!gpio_get_level(TABLET_MODE_GPIO_L)); +#ifdef CONFIG_LID_ANGLE_UPDATE /* Then, we disable peripherals only when the lid reaches 360 position. * (It's probably already disabled by motion_sense_task.) * We deliberately do not enable peripherals when the lid is leaving @@ -48,6 +49,7 @@ static void tablet_mode_debounce(void) * reaches laptop zone (180 or less). */ if (tablet_mode) lid_angle_peripheral_enable(0); +#endif /* CONFIG_LID_ANGLE_UPDATE */ } DECLARE_DEFERRED(tablet_mode_debounce); diff --git a/include/config.h b/include/config.h index da3a89dcb3..9f805446ec 100644 --- a/include/config.h +++ b/include/config.h @@ -1931,6 +1931,9 @@ /* Add support for the assistant key. */ #undef CONFIG_KEYBOARD_ASSISTANT_KEY +/* Add support for a switch that indicates if the device is in tablet mode. */ +#undef CONFIG_KEYBOARD_TABLET_MODE_SWITCH + /* * Minimum CPU clocks between scans. This ensures that keyboard scanning * doesn't starve the other EC tasks of CPU when running at a decreased system |