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>
This commit is contained in:
Gwendal Grignou
2016-09-08 10:49:49 -07:00
committed by chrome-bot
parent 2b82ad7800
commit 8a3b998868
4 changed files with 66 additions and 1 deletions

View File

@@ -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,9 +281,15 @@ 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 */

View File

@@ -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? */

View File

@@ -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 */

View File

@@ -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