summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNicolas Boichat <drinkcat@chromium.org>2018-05-30 15:55:57 +0800
committerchrome-bot <chrome-bot@chromium.org>2018-06-06 05:00:49 -0700
commit65d87bf9f0ef9b084d91ed44eda58b7463c82b48 (patch)
tree64bcafd6797a3a60bc9c5a7e2164688ad9bb7a38
parent8290d879dab1fbba805cfcdb4f2409bdee803dc6 (diff)
downloadchrome-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.c14
-rw-r--r--board/hammer/board.h6
-rw-r--r--board/hammer/gpio.inc2
-rw-r--r--chip/stm32/usb_hid_keyboard.c108
-rw-r--r--common/tablet_mode.c2
-rw-r--r--include/config.h3
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