diff options
Diffstat (limited to 'common/motion_lid.c')
-rw-r--r-- | common/motion_lid.c | 70 |
1 files changed, 64 insertions, 6 deletions
diff --git a/common/motion_lid.c b/common/motion_lid.c index d737046c53..db7b076afa 100644 --- a/common/motion_lid.c +++ b/common/motion_lid.c @@ -135,8 +135,8 @@ __attribute__((weak)) int board_is_lid_angle_tablet_mode(void) * - when lid is closed while the hinge is perpendicular to the floor, we will * stay in tablet mode. * - * Tablet mode is defined as the lid angle being greater than 180 degree. We use - * 2 threshold to calculate tablet mode: + * Tablet mode is defined as the lid angle being greater than 180 degree(by + * default). We use 2 threshold to calculate tablet mode: * tablet_mode: * 1 | +-----<----+---------- * | \/ /\ @@ -144,9 +144,26 @@ __attribute__((weak)) int board_is_lid_angle_tablet_mode(void) * 0 |------------------>----+ * +------------+----------+----------+ lid angle * 0 160 200 360 + * + * Host can configure the threshold to be different than default of 180 +/- 20 + * by using MOTIONSENSE_CMD_TABLET_MODE_LID_ANGLE. */ -#define TABLET_ZONE_LID_ANGLE FLOAT_TO_FP(200) -#define LAPTOP_ZONE_LID_ANGLE FLOAT_TO_FP(160) + +#define DEFAULT_TABLET_MODE_ANG (180) +#define DEFAULT_TABLET_MODE_HYS (20) + +#define TABLET_ZONE_ANGLE(a, h) ((a) + (h)) +#define LAPTOP_ZONE_ANGLE(a, h) ((a) - (h)) + +static fp_t tablet_zone_lid_angle = + FLOAT_TO_FP(TABLET_ZONE_ANGLE(DEFAULT_TABLET_MODE_ANG, + DEFAULT_TABLET_MODE_HYS)); +static fp_t laptop_zone_lid_angle = + FLOAT_TO_FP(LAPTOP_ZONE_ANGLE(DEFAULT_TABLET_MODE_ANG, + DEFAULT_TABLET_MODE_HYS)); + +static int tablet_mode_lid_ang = DEFAULT_TABLET_MODE_ANG; +static int tablet_mode_hys_deg = DEFAULT_TABLET_MODE_HYS; /* * We will change our tablet mode status when we are "convinced" that it has @@ -165,9 +182,9 @@ static void motion_lid_set_tablet_mode(int reliable) int new_mode = current_mode; if (reliable) { - if (last_lid_angle_fp > TABLET_ZONE_LID_ANGLE) + if (last_lid_angle_fp > tablet_zone_lid_angle) new_mode = 1; - else if (last_lid_angle_fp < LAPTOP_ZONE_LID_ANGLE) + else if (last_lid_angle_fp < laptop_zone_lid_angle) new_mode = 0; /* Only change tablet mode if we're sure. */ @@ -195,6 +212,24 @@ static void motion_lid_set_tablet_mode(int reliable) tablet_mode_debounce_cnt = TABLET_MODE_DEBOUNCE_COUNT; } +static int lid_angle_set_tablet_mode_threshold(int ang, int hys) +{ + if ((ang == EC_MOTION_SENSE_NO_VALUE) || + (hys == EC_MOTION_SENSE_NO_VALUE)) + return EC_RES_SUCCESS; + + if ((ang < 0) || (hys < 0) || (ang < hys) || ((ang + hys) > 360)) + return EC_RES_INVALID_PARAM; + + tablet_mode_lid_ang = ang; + tablet_mode_hys_deg = hys; + + tablet_zone_lid_angle = INT_TO_FP(TABLET_ZONE_ANGLE(ang, hys)); + laptop_zone_lid_angle = INT_TO_FP(LAPTOP_ZONE_ANGLE(ang, hys)); + + return EC_RES_SUCCESS; +} + #endif /* CONFIG_TABLET_MODE */ #if defined(CONFIG_DPTF_MULTI_PROFILE) && \ @@ -534,6 +569,29 @@ int host_cmd_motion_lid(struct host_cmd_handler_args *args) #endif break; + case MOTIONSENSE_CMD_TABLET_MODE_LID_ANGLE: + { +#ifdef CONFIG_TABLET_MODE + int ret; + ret = lid_angle_set_tablet_mode_threshold( + in->tablet_mode_threshold.lid_ang, + in->tablet_mode_threshold.hys_deg); + + if (ret != EC_RES_SUCCESS) + return ret; + + out->tablet_mode_threshold.lid_ang = + tablet_mode_lid_ang; + out->tablet_mode_threshold.hys_deg = + tablet_mode_hys_deg; + + args->response_size = + sizeof(out->tablet_mode_threshold); +#else + return EC_RES_INVALID_PARAM; +#endif + } + break; default: return EC_RES_INVALID_PARAM; } |