summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGwendal Grignou <gwendal@chromium.org>2016-09-08 10:49:49 -0700
committerchrome-bot <chrome-bot@chromium.org>2016-09-09 12:33:19 -0700
commit8a3b9988683e8d2d42837daede1fbd3f220c19b5 (patch)
treefc72ea2e9eeb85d89d2c61824edea125ef509e20
parent2b82ad78004e8ce37272743792acdb347a5a1001 (diff)
downloadchrome-ec-8a3b9988683e8d2d42837daede1fbd3f220c19b5.tar.gz
common: motion_lid: Add tablet mode detection using lid angle.
Using the lid angle, detect if we are in tablet mode or not. We are in tablet mode when the lid angle is large enough: tablet_mode: 1 | +-----<----+---------- | \/ /\ | | | 0 |------------------------>----+ +------------------+----------+----------+ lid angle 0 240 300 360 BRANCH=kevin BUG=chrome-os-partner:55702,b:27849483 TEST=Check on Kevin event are sent on tablet mode transition. Change-Id: Id9935ce4dd717e2c20fa6c9520defb504a1760d9 Signed-off-by: Gwendal Grignou <gwendal@chromium.org> Reviewed-on: https://chromium-review.googlesource.com/383073 Reviewed-by: Aseda Aboagye <aaboagye@chromium.org>
-rw-r--r--common/motion_lid.c53
-rw-r--r--include/config.h5
-rw-r--r--include/motion_lid.h6
-rw-r--r--test/test_config.h1
4 files changed, 65 insertions, 0 deletions
diff --git a/common/motion_lid.c b/common/motion_lid.c
index d46173918c..3f68480484 100644
--- a/common/motion_lid.c
+++ b/common/motion_lid.c
@@ -26,6 +26,40 @@
#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)
+
+static int tablet_mode = 1;
+#endif
+
#ifdef CONFIG_LID_ANGLE_INVALID_CHECK
/* Previous lid_angle. */
static fp_t last_lid_angle_fp = FLOAT_TO_FP(-1);
@@ -113,6 +147,9 @@ 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_mode;
+#endif
/*
* The angle between lid and base is:
@@ -192,6 +229,16 @@ 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
+ 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;
+ if (tablet_mode != new_tablet_mode) {
+ tablet_mode = new_tablet_mode;
+ hook_notify(HOOK_TABLET_MODE_CHANGE);
+ }
+#endif /* CONFIG_LID_ANGLE_TABLET_MODE */
#else /* CONFIG_LID_ANGLE_INVALID_CHECK */
*lid_angle = FP_TO_INT(lid_to_base_fp + FLOAT_TO_FP(0.5));
#endif
@@ -234,8 +281,14 @@ void motion_lid_calc(void)
#ifdef CONFIG_LID_ANGLE_UPDATE
lid_angle_update(motion_lid_get_angle());
#endif
+}
+#ifdef CONFIG_LID_ANGLE_TABLET_MODE
+int motion_lid_in_tablet_mode(void)
+{
+ return tablet_mode;
}
+#endif
/*****************************************************************************/
/* Host commands */
diff --git a/include/config.h b/include/config.h
index 31912eee94..0e9d937c42 100644
--- a/include/config.h
+++ b/include/config.h
@@ -1065,6 +1065,11 @@
*/
#undef CONFIG_LID_ANGLE_INVALID_CHECK
+/*
+ * Use lid angle to detect tablet mode.
+ */
+#undef CONFIG_LID_ANGLE_TABLET_MODE
+
/* Which sensor is located on the base? */
#undef CONFIG_LID_ANGLE_SENSOR_BASE
/* Which sensor is located on the lid? */
diff --git a/include/motion_lid.h b/include/motion_lid.h
index 155c7735c9..405d5e5e5d 100644
--- a/include/motion_lid.h
+++ b/include/motion_lid.h
@@ -46,6 +46,12 @@ int host_cmd_motion_lid(struct host_cmd_handler_args *args);
void motion_lid_calc(void);
+#ifdef CONFIG_LID_ANGLE_TABLET_MODE
+int motion_lid_in_tablet_mode(void);
+#else
+static inline int motion_lid_in_tablet_mode(void) { return 0; }
+#endif
+
#endif /* __CROS_EC_MOTION_LID_H */
diff --git a/test/test_config.h b/test/test_config.h
index ffb8e877f4..371303b4cb 100644
--- a/test/test_config.h
+++ b/test/test_config.h
@@ -45,6 +45,7 @@
#ifdef TEST_MOTION_LID
#define CONFIG_LID_ANGLE
#define CONFIG_LID_ANGLE_INVALID_CHECK
+#define CONFIG_LID_ANGLE_TABLET_MODE
#define CONFIG_LID_ANGLE_SENSOR_BASE 0
#define CONFIG_LID_ANGLE_SENSOR_LID 1
#endif