summaryrefslogtreecommitdiff
path: root/common/motion_lid.c
diff options
context:
space:
mode:
authorFurquan Shaikh <furquan@google.com>2018-11-27 19:44:19 -0800
committerchrome-bot <chrome-bot@chromium.org>2018-11-29 04:31:50 -0800
commit7b3088705a977cabc736405f291b39510763aa44 (patch)
tree9e2ae837c479640e4a1f848f0bbf7290a8df819f /common/motion_lid.c
parentba1f417b824cae748474a3a210d75f109f8a8473 (diff)
downloadchrome-ec-7b3088705a977cabc736405f291b39510763aa44.tar.gz
motion_lid: Allow host to configure tablet mode detection threshold
This change adds support for host to configure the tablet mode threshold angle and hysteresis degree using a new motionsense command MOTIONSENSE_CMD_TABLET_MODE_LID_ANGLE. Additionally, the EC sets a new feature bit to indicate support for this refined tablet mode detection. This feature bit can be used by kernel to expose an inclinometer device which can eventually help remove the redundant lid angle calculation in Chrome. BUG=b:120050761 BRANCH=octopus TEST=make -j buildall. Additionally, verified that tablet mode lid angle can be configured by host using ectool. Also, feature flag is correctly set to indicate support for this feature. Change-Id: I51bd160bbfae02d899bdf63096618c13eb5800e8 Signed-off-by: Furquan Shaikh <furquan@google.com> Reviewed-on: https://chromium-review.googlesource.com/1351518 Commit-Ready: Furquan Shaikh <furquan@chromium.org> Tested-by: Furquan Shaikh <furquan@chromium.org> Reviewed-by: Jett Rink <jettrink@chromium.org>
Diffstat (limited to 'common/motion_lid.c')
-rw-r--r--common/motion_lid.c70
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;
}