diff options
Diffstat (limited to 'common/lid_angle.c')
-rw-r--r-- | common/lid_angle.c | 202 |
1 files changed, 0 insertions, 202 deletions
diff --git a/common/lid_angle.c b/common/lid_angle.c deleted file mode 100644 index 8a3775b959..0000000000 --- a/common/lid_angle.c +++ /dev/null @@ -1,202 +0,0 @@ -/* Copyright 2014 The Chromium OS Authors. All rights reserved. - * Use of this source code is governed by a BSD-style license that can be - * found in the LICENSE file. - */ - -/* Lid angle module for Chrome EC */ - -#include "chipset.h" -#include "common.h" -#include "console.h" -#include "hooks.h" -#include "keyboard_scan.h" -#include "lid_angle.h" -#include "lid_switch.h" -#include "math_util.h" -#include "motion_lid.h" -#include "motion_sense.h" -#include "tablet_mode.h" - -/* Console output macros */ -#define CPUTS(outstr) cputs(CC_LIDANGLE, outstr) -#define CPRINTS(format, args...) cprints(CC_LIDANGLE, format, ## args) - -/* - * Define the number of previous lid angle measurements to keep for determining - * whether to enable or disable peripherals that are only needed for laptop - * mode. These incude keyboard and trackpad. Note, that in order to change the - * enable/disable state of these peripherals, all stored measurements of the - * lid angle buffer must be in the specified range. - */ -#define LID_ANGLE_BUFFER_SIZE 4 - -/* - * Define two variables to determine if wake source peripherals that are only - * applicable for laptop mode 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 peripherals 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 peripherals 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 wake_large_angle = 180; -static const int wake_small_angle = 13; - -/* Define hysteresis value to add stability to the flags. */ -#define LID_ANGLE_HYSTERESIS_DEG 2 - -/* Define max and min values for wake_large_angle. */ -#define LID_ANGLE_MIN_LARGE_ANGLE 0 -#define LID_ANGLE_MAX_LARGE_ANGLE 360 - -/** - * Determine if given angle is in region to enable peripherals. - * - * @param ang Some lid angle in degrees [0, 360] - * - * @return true/false - */ -static int lid_in_range_to_enable_peripherals(int ang) -{ - /* - * If the wake large angle is min or max, then this function should - * return false or true respectively, independent of input angle. - */ - if (wake_large_angle == LID_ANGLE_MIN_LARGE_ANGLE) - return 0; - else if (wake_large_angle == LID_ANGLE_MAX_LARGE_ANGLE) - return 1; - - return (ang >= (wake_small_angle + LID_ANGLE_HYSTERESIS_DEG)) && - (ang <= (wake_large_angle - LID_ANGLE_HYSTERESIS_DEG)); -} - -/** - * Determine if given angle is in region to ignore peripherals. - * - * @param ang Some lid angle in degrees [0, 360] - * - * @return true/false - */ -static int lid_in_range_to_ignore_peripherals(int ang) -{ - /* - * If the wake large angle is min or max, then this function should - * return true or false respectively, independent of input angle. - */ - if (wake_large_angle == LID_ANGLE_MIN_LARGE_ANGLE) - return 1; - else if (wake_large_angle == LID_ANGLE_MAX_LARGE_ANGLE) - return 0; - - return (ang <= (wake_small_angle - LID_ANGLE_HYSTERESIS_DEG)) || - (ang >= (wake_large_angle + LID_ANGLE_HYSTERESIS_DEG)); -} - - -int lid_angle_get_wake_angle(void) -{ - return wake_large_angle; -} - -void lid_angle_set_wake_angle(int ang) -{ - if (ang < LID_ANGLE_MIN_LARGE_ANGLE) - ang = LID_ANGLE_MIN_LARGE_ANGLE; - else if (ang > LID_ANGLE_MAX_LARGE_ANGLE) - ang = LID_ANGLE_MAX_LARGE_ANGLE; - - wake_large_angle = ang; -} - -void lid_angle_update(int lid_ang) -{ - static int lidangle_buffer[LID_ANGLE_BUFFER_SIZE]; - static int index; - int i; - int accept = 1, ignore = 1; - - /* Record most recent lid angle in circular buffer. */ - lidangle_buffer[index] = lid_ang; - index = (index == LID_ANGLE_BUFFER_SIZE-1) ? 0 : index+1; - - /* - * Manage whether or not peripherals are enabled based on lid angle - * history. - */ - for (i = 0; i < LID_ANGLE_BUFFER_SIZE; i++) { - /* - * If any lid angle samples are unreliable, then - * don't change peripheral state. - */ - if (lidangle_buffer[i] == LID_ANGLE_UNRELIABLE) - return; - - /* - * Force all elements of the lid angle buffer to be - * in range of one of the conditions in order to change - * to the corresponding peripheral state. - */ - if (!lid_in_range_to_enable_peripherals(lidangle_buffer[i])) - accept = 0; - if (!lid_in_range_to_ignore_peripherals(lidangle_buffer[i])) - ignore = 0; - } - - /* Enable or disable peripherals as necessary. */ - if (accept) - lid_angle_peripheral_enable(1); - else if (ignore && !accept) - lid_angle_peripheral_enable(0); -} - -static void enable_peripherals(void) -{ - /* - * Make sure lid angle is not disabling peripherals when AP is running. - */ - lid_angle_peripheral_enable(1); -} -DECLARE_HOOK(HOOK_CHIPSET_RESUME, enable_peripherals, HOOK_PRIO_DEFAULT); - -#ifdef CONFIG_TABLET_MODE -static void suspend_peripherals(void) -{ - /* - * Make sure peripherals are disabled in S3 in tablet mode. - */ - if (tablet_get_mode()) - lid_angle_peripheral_enable(0); -} -DECLARE_HOOK(HOOK_CHIPSET_SUSPEND, suspend_peripherals, HOOK_PRIO_DEFAULT); -#endif /* CONFIG_TABLET_MODE */ - -#ifdef TEST_BUILD -__overridable void lid_angle_peripheral_enable(int enable) -{ -} -#else -__overridable void lid_angle_peripheral_enable(int enable) -{ - int chipset_in_s0 = chipset_in_state(CHIPSET_STATE_ON); - - if (enable) { - keyboard_scan_enable(1, KB_SCAN_DISABLE_LID_ANGLE); - } else { - /* - * Ensure that the chipset is off before disabling the keyboard. - * When the chipset is on, the EC keeps the keyboard enabled and - * the AP decides whether to ignore input devices or not. - */ - if (!chipset_in_s0) - keyboard_scan_enable(0, KB_SCAN_DISABLE_LID_ANGLE); - } -} -#endif /* TEST_BUILD */ |