diff options
author | Daisuke Nojiri <dnojiri@chromium.org> | 2018-04-23 13:39:21 -0700 |
---|---|---|
committer | chrome-bot <chrome-bot@chromium.org> | 2018-05-09 14:40:07 -0700 |
commit | 50ba7ef146aea95baa5ac74d6ac0ccf140568a6d (patch) | |
tree | 2ed55809c825fc3c1c14fb1cdea6372ddaf363ed /common/motion_lid.c | |
parent | 4461fb7ab7c5d264126040d6588866ed43dde9ed (diff) | |
download | chrome-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>
Diffstat (limited to 'common/motion_lid.c')
-rw-r--r-- | common/motion_lid.c | 169 |
1 files changed, 90 insertions, 79 deletions
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 |