mirror of
https://github.com/Telecominfraproject/OpenCellular.git
synced 2026-01-13 03:15:06 +00:00
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>
This commit is contained in:
committed by
chrome-bot
parent
8290d879da
commit
65d87bf9f0
@@ -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.
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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 */
|
||||
|
||||
|
||||
@@ -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)
|
||||
{ }
|
||||
|
||||
|
||||
@@ -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);
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user