diff options
Diffstat (limited to 'common/lid_angle.c')
-rw-r--r-- | common/lid_angle.c | 92 |
1 files changed, 90 insertions, 2 deletions
diff --git a/common/lid_angle.c b/common/lid_angle.c index e7a3139ebb..02f72f1991 100644 --- a/common/lid_angle.c +++ b/common/lid_angle.c @@ -25,6 +25,94 @@ */ #define KEY_SCAN_LID_ANGLE_BUFFER_SIZE 4 +/* + * Define two variables to determine if keyboard scanning should be enabled + * or disabled in S3 based on the current lid angle. Note, the lid angle is + * bound to [0, 360]. Here are two angles, defined such that we segregate the + * lid angle space into two regions. The first region is the region in which + * we enable keyboard scanning in S3 and is when the lid angle CCW of the + * small_angle and CW of the large_angle. The second region is the region in + * which we disable keyboard scanning in S3 and is when the lid angle is CCW + * of the large_angle and CW of the small_angle. + * + * Note, the most sensical values are small_angle = 0 and large_angle = 180, + * but, the angle measurement is not perfect, and we know that if the angle is + * near 0 and the lid isn't closed, then the lid must be near 360. So, the + * small_angle is set to a small positive value to make sure we don't swap modes + * when the lid is open all the way but is measuring a small positive value. + */ +static int kb_wake_large_angle = 180; +static const int kb_wake_small_angle = 13; + +/* Define hysteresis value to add stability to the keyboard scanning flag. */ +#define KB_DIS_HYSTERESIS_DEG 2 + +/* Define max and min values for kb_wake_large_angle. */ +#define KB_DIS_MIN_LARGE_ANGLE 0 +#define KB_DIS_MAX_LARGE_ANGLE 360 + +/** + * Determine if given angle is in region to accept keyboard presses. + * + * @param ang Some lid angle in degrees [0, 360] + * + * @return true/false + */ +static int lid_in_range_to_accept_keys(float ang) +{ + /* + * If the keyboard wake large angle is min or max, then this + * function should return false or true respectively, independent of + * input angle. + */ + if (kb_wake_large_angle == KB_DIS_MIN_LARGE_ANGLE) + return 0; + else if (kb_wake_large_angle == KB_DIS_MAX_LARGE_ANGLE) + return 1; + + return (ang >= (kb_wake_small_angle + KB_DIS_HYSTERESIS_DEG)) && + (ang <= (kb_wake_large_angle - KB_DIS_HYSTERESIS_DEG)); +} + +/** + * Determine if given angle is in region to ignore keyboard presses. + * + * @param ang Some lid angle in degrees [0, 360] + * + * @return true/false + */ +static int lid_in_range_to_ignore_keys(float ang) +{ + /* + * If the keyboard wake large angle is min or max, then this + * function should return true or false respectively, independent of + * input angle. + */ + if (kb_wake_large_angle == KB_DIS_MIN_LARGE_ANGLE) + return 1; + else if (kb_wake_large_angle == KB_DIS_MAX_LARGE_ANGLE) + return 0; + + return (ang <= (kb_wake_small_angle - KB_DIS_HYSTERESIS_DEG)) || + (ang >= (kb_wake_large_angle + KB_DIS_HYSTERESIS_DEG)); +} + + +int lid_angle_get_kb_wake_angle(void) +{ + return kb_wake_large_angle; +} + +void lid_angle_set_kb_wake_angle(int ang) +{ + if (ang < KB_DIS_MIN_LARGE_ANGLE) + ang = KB_DIS_MIN_LARGE_ANGLE; + else if (ang > KB_DIS_MAX_LARGE_ANGLE) + ang = KB_DIS_MAX_LARGE_ANGLE; + + kb_wake_large_angle = ang; +} + void lidangle_keyscan_update(float lid_ang) { static float lidangle_buffer[KEY_SCAN_LID_ANGLE_BUFFER_SIZE]; @@ -60,9 +148,9 @@ void lidangle_keyscan_update(float lid_ang) * in range of one of the conditions in order to change * to the corresponding key scanning state. */ - if (!LID_IN_RANGE_TO_ACCEPT_KEYS(lidangle_buffer[i])) + if (!lid_in_range_to_accept_keys(lidangle_buffer[i])) keys_accept = 0; - if (!LID_IN_RANGE_TO_IGNORE_KEYS(lidangle_buffer[i])) + if (!lid_in_range_to_ignore_keys(lidangle_buffer[i])) keys_ignore = 0; } |