summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDaisuke Nojiri <dnojiri@chromium.org>2018-04-23 13:39:21 -0700
committerchrome-bot <chrome-bot@chromium.org>2018-05-09 14:40:07 -0700
commit50ba7ef146aea95baa5ac74d6ac0ccf140568a6d (patch)
tree2ed55809c825fc3c1c14fb1cdea6372ddaf363ed
parent4461fb7ab7c5d264126040d6588866ed43dde9ed (diff)
downloadchrome-ec-50ba7ef146aea95baa5ac74d6ac0ccf140568a6d.tar.gz
Nami: Use lid angle to detect tablet mode for Vayne & Nami
This patch refactors motion_lid so that EC can decide to use lid angles to set tablet mode at run time. Then, it implements board_is_lid_angle_tablet_mode to enable the feature for Nami and Vayne. Signed-off-by: Daisuke Nojiri <dnojiri@chromium.org> BUG=b:77298177 BRANCH=none TEST=Verify on Nami. Change-Id: Ib717911a16fe031aa6c6ede731e6aa722d32d022 Reviewed-on: https://chromium-review.googlesource.com/1024914 Commit-Ready: Daisuke Nojiri <dnojiri@chromium.org> Tested-by: Daisuke Nojiri <dnojiri@chromium.org> Reviewed-by: Daisuke Nojiri <dnojiri@chromium.org>
-rw-r--r--board/nami/board.c32
-rw-r--r--common/motion_lid.c169
2 files changed, 103 insertions, 98 deletions
diff --git a/board/nami/board.c b/board/nami/board.c
index 3752815a59..53e4575de3 100644
--- a/board/nami/board.c
+++ b/board/nami/board.c
@@ -65,6 +65,8 @@
#define USB_PD_PORT_PS8751 0
#define USB_PD_PORT_ANX7447 1
+static uint32_t oem = PROJECT_NAMI;
+
static void tcpc_alert_event(enum gpio_signal signal)
{
if ((signal == GPIO_USB_C0_PD_INT_ODL) &&
@@ -661,23 +663,6 @@ static void board_chipset_suspend(void)
}
DECLARE_HOOK(HOOK_CHIPSET_SUSPEND, board_chipset_suspend, HOOK_PRIO_DEFAULT);
-static void board_set_motion_sensor_count(void)
-{
- /* There are two possible sensor configurations.
- * Vayne/Sona/Pantheon/Akali are without ALS sensor
- * Nami is with ALS sensor
- * Use the oem id to different them.
- */
- uint32_t oem_id;
-
- if (cbi_get_oem_id(&oem_id) == EC_SUCCESS) {
- if (oem_id == PROJECT_VAYNE || oem_id == PROJECT_SONA
- || oem_id == PROJECT_PANTHEON
- || oem_id == PROJECT_AKALI)
- motion_sensor_count = ARRAY_SIZE(motion_sensors) - 1;
- }
-}
-
/* Initialize board. */
static void board_init(void)
{
@@ -686,6 +671,9 @@ static void board_init(void)
if (cbi_get_board_version(&version) == EC_SUCCESS)
CPRINTS("Board Version: 0x%04x", version);
+ if (cbi_get_oem_id(&oem))
+ CPRINTS("OEM: 0x%x", oem);
+
/*
* This enables pull-down on F_DIO1 (SPI MISO), and F_DIO0 (SPI MOSI),
* whenever the EC is not doing SPI flash transactions. This avoids
@@ -711,8 +699,9 @@ static void board_init(void)
/* Enable Gyro interrupt for BMI160 */
gpio_enable_interrupt(GPIO_ACCELGYRO3_INT_L);
- /* Update motion_sensor_count */
- board_set_motion_sensor_count();
+ /* Only Nami has an ALS sensor. */
+ if (oem != PROJECT_NAMI)
+ motion_sensor_count = ARRAY_SIZE(motion_sensors) - 1;
}
DECLARE_HOOK(HOOK_INIT, board_init, HOOK_PRIO_DEFAULT);
@@ -736,3 +725,8 @@ struct keyboard_scan_config keyscan_config = {
},
};
+int board_is_lid_angle_tablet_mode(void)
+{
+ /* Boards with no GMR sensor use lid angles to detect tablet mode. */
+ return oem == PROJECT_NAMI || oem == PROJECT_VAYNE;
+}
diff --git a/common/motion_lid.c b/common/motion_lid.c
index 38efea172e..befd71a271 100644
--- a/common/motion_lid.c
+++ b/common/motion_lid.c
@@ -28,49 +28,6 @@
#define CPRINTS(format, args...) cprints(CC_MOTION_LID, format, ## args)
#define CPRINTF(format, args...) cprintf(CC_MOTION_LID, format, ## args)
-#ifdef CONFIG_LID_ANGLE_TABLET_MODE
-
-#ifndef CONFIG_LID_ANGLE_INVALID_CHECK
-#error "Check for invalid transition needed"
-#endif
-/*
- * We are in tablet mode when the lid angle has been calculated
- * to be large.
- *
- * By default, at boot, we are in tablet mode.
- * Once a lid angle is calculated, we will get out of this fake state and enter
- * tablet mode only if a high angle has been calculated.
- *
- * There might be false positives:
- * - when the EC enters RO or RW mode.
- * - when lid is closed while the hinge is perpendicalar to the floor, we will
- * stay in tablet mode.
- *
- * Tablet mode is defined as the base being behind the lid. We use 2 threshold
- * to calculate tablet mode:
- * tablet_mode:
- * 1 | +-----<----+----------
- * | \/ /\
- * | | |
- * 0 |------------------------>----+
- * +------------------+----------+----------+ lid angle
- * 0 240 300 360
- */
-#define TABLET_ZONE_LID_ANGLE FLOAT_TO_FP(300)
-#define LAPTOP_ZONE_LID_ANGLE FLOAT_TO_FP(240)
-
-/*
- * We will change our tablet mode status when we are "convinced" that it has
- * changed. This means we will have to consecutively calculate our new tablet
- * mode while the angle is stable and come to the same conclusion. The number
- * of consecutive calculations is the debounce count with an interval between
- * readings set by the motion_sense task. This should avoid spurious forces
- * that may trigger false transitions of the tablet mode switch.
- */
-#define TABLET_MODE_DEBOUNCE_COUNT 3
-static int tablet_mode_debounce_cnt = TABLET_MODE_DEBOUNCE_COUNT;
-#endif
-
#ifdef CONFIG_LID_ANGLE_INVALID_CHECK
/* Previous lid_angle. */
static fp_t last_lid_angle_fp = FLOAT_TO_FP(-1);
@@ -158,6 +115,94 @@ const struct motion_sensor_t * const accel_base =
const struct motion_sensor_t * const accel_lid =
&motion_sensors[CONFIG_LID_ANGLE_SENSOR_LID];
+__attribute__((weak)) int board_is_lid_angle_tablet_mode(void)
+{
+#ifdef CONFIG_LID_ANGLE_TABLET_MODE
+ return 1;
+#else
+ return 0;
+#endif
+}
+
+#ifdef CONFIG_LID_ANGLE_TABLET_MODE
+#ifndef CONFIG_LID_ANGLE_INVALID_CHECK
+#error "Check for invalid transition needed"
+#endif
+/*
+ * We are in tablet mode when the lid angle has been calculated
+ * to be large.
+ *
+ * By default, at boot, we are in tablet mode.
+ * Once a lid angle is calculated, we will get out of this fake state and enter
+ * tablet mode only if a high angle has been calculated.
+ *
+ * There might be false positives:
+ * - when the EC enters RO or RW mode.
+ * - when lid is closed while the hinge is perpendicalar to the floor, we will
+ * stay in tablet mode.
+ *
+ * Tablet mode is defined as the base being behind the lid. We use 2 threshold
+ * to calculate tablet mode:
+ * tablet_mode:
+ * 1 | +-----<----+----------
+ * | \/ /\
+ * | | |
+ * 0 |------------------------>----+
+ * +------------------+----------+----------+ lid angle
+ * 0 240 300 360
+ */
+#define TABLET_ZONE_LID_ANGLE FLOAT_TO_FP(300)
+#define LAPTOP_ZONE_LID_ANGLE FLOAT_TO_FP(240)
+
+/*
+ * We will change our tablet mode status when we are "convinced" that it has
+ * changed. This means we will have to consecutively calculate our new tablet
+ * mode while the angle is stable and come to the same conclusion. The number
+ * of consecutive calculations is the debounce count with an interval between
+ * readings set by the motion_sense task. This should avoid spurious forces
+ * that may trigger false transitions of the tablet mode switch.
+ */
+#define TABLET_MODE_DEBOUNCE_COUNT 3
+
+static int motion_lid_set_tablet_mode(int reliable)
+{
+ static int tablet_mode_debounce_cnt = TABLET_MODE_DEBOUNCE_COUNT;
+ const int current_mode = tablet_get_mode();
+ int new_mode = current_mode;
+
+ if (reliable) {
+ if (last_lid_angle_fp > TABLET_ZONE_LID_ANGLE)
+ new_mode = 1;
+ else if (last_lid_angle_fp < LAPTOP_ZONE_LID_ANGLE)
+ new_mode = 0;
+
+ /* Only change tablet mode if we're sure. */
+ if (current_mode != new_mode) {
+ if (tablet_mode_debounce_cnt == 0) {
+ /* Alright, we're convinced. */
+ tablet_mode_debounce_cnt =
+ TABLET_MODE_DEBOUNCE_COUNT;
+ tablet_set_mode(new_mode);
+ return reliable;
+ }
+ tablet_mode_debounce_cnt--;
+ return reliable;
+ }
+ }
+
+ /*
+ * If we got a reliable measurement that agrees with our current tablet
+ * mode, then reset the debounce counter. Also, make it harder to leave
+ * tablet mode by resetting the debounce count when we encounter an
+ * unreliable angle when we're already in tablet mode.
+ */
+ if (((reliable == 0) && current_mode == 1) ||
+ ((reliable == 1) && (current_mode == new_mode)))
+ tablet_mode_debounce_cnt = TABLET_MODE_DEBOUNCE_COUNT;
+ return reliable;
+}
+#endif
+
/**
* Calculate the lid angle using two acceleration vectors, one recorded in
* the base and one in the lid.
@@ -176,10 +221,6 @@ static int calculate_lid_angle(const vector_3_t base, const vector_3_t lid,
fp_t lid_to_base, base_to_hinge;
fp_t denominator;
int reliable = 1;
-#ifdef CONFIG_LID_ANGLE_TABLET_MODE
- int new_tablet_mode = tablet_get_mode();
- int current_tablet_mode;
-#endif
int base_magnitude2, lid_magnitude2;
int base_range, lid_range, i;
vector_3_t scaled_base, scaled_lid;
@@ -354,38 +395,8 @@ static int calculate_lid_angle(const vector_3_t base, const vector_3_t lid,
*/
*lid_angle = FP_TO_INT(last_lid_angle_fp + FLOAT_TO_FP(0.5));
-#ifdef CONFIG_LID_ANGLE_TABLET_MODE
- current_tablet_mode = tablet_get_mode();
- if (reliable) {
- if (last_lid_angle_fp > TABLET_ZONE_LID_ANGLE)
- new_tablet_mode = 1;
- else if (last_lid_angle_fp < LAPTOP_ZONE_LID_ANGLE)
- new_tablet_mode = 0;
-
- /* Only change tablet mode if we're sure. */
- if (current_tablet_mode != new_tablet_mode) {
- if (tablet_mode_debounce_cnt == 0) {
- /* Alright, we're convinced. */
- tablet_mode_debounce_cnt =
- TABLET_MODE_DEBOUNCE_COUNT;
- tablet_set_mode(new_tablet_mode);
- return reliable;
- }
- tablet_mode_debounce_cnt--;
- return reliable;
- }
- }
-
- /*
- * If we got a reliable measurement that agrees with our current tablet
- * mode, then reset the debounce counter. Also, make it harder to leave
- * tablet mode by resetting the debounce count when we encounter an
- * unreliable angle when we're already in tablet mode.
- */
- if (((reliable == 0) && current_tablet_mode == 1) ||
- ((reliable == 1) && (current_tablet_mode == new_tablet_mode)))
- tablet_mode_debounce_cnt = TABLET_MODE_DEBOUNCE_COUNT;
-#endif /* CONFIG_LID_ANGLE_TABLET_MODE */
+ if (board_is_lid_angle_tablet_mode())
+ reliable = motion_lid_set_tablet_mode(reliable);
#else /* CONFIG_LID_ANGLE_INVALID_CHECK */
*lid_angle = FP_TO_INT(lid_to_base_fp + FLOAT_TO_FP(0.5));
#endif