summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPaul Ma <magf@bitland.corp-partner.google.com>2019-08-06 16:59:49 +0800
committerCommit Bot <commit-bot@chromium.org>2019-08-23 00:12:35 +0000
commit4e0f0652f035f97aa933c4e74e17514ff785e46f (patch)
tree1bbf720bfab57aa2da88347c26d7783d463b99fa
parent5d7f972a9d867055810da24ac62fb359a21639e3 (diff)
downloadchrome-ec-4e0f0652f035f97aa933c4e74e17514ff785e46f.tar.gz
driver: lis2dwl: add driver support
lis2dwl has almost the same register interface as lis2dw12. lis2dwl only has one low power mode and when in low power mode, it has only 12 bit resolution. In order to get 14 bit resolution, we only use its high performance mode. Add MOTIONSENSE_FLAG_INT_ACTIVE_HIGH flag to support both active high and active low interrupt. BUG=b:138768226, b:138978278 BRANCH=none TEST=use Akemi board, add lis2dwl as accel sensor, boot the board and make sure sensor x/y/z get correct value by 'accelinfo on' Cq-Depend: chromium:515302 Change-Id: I37fcc0f43af3c8055079e09db00757b665813ba8 Signed-off-by: Paul Ma <magf@bitland.corp-partner.google.com> Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/platform/ec/+/1739026 Tested-by: Martin Roth <martinroth@chromium.org> Reviewed-by: Jett Rink <jettrink@chromium.org> Reviewed-by: Martin Roth <martinroth@chromium.org> Reviewed-by: Paul Fagerburg <pfagerburg@chromium.org> Reviewed-by: mario tesi <mario.tesi@st.com> Commit-Queue: Martin Roth <martinroth@chromium.org> Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/platform/ec/+/1767532 Reviewed-by: Edward Hill <ecgh@chromium.org> Commit-Queue: Edward Hill <ecgh@chromium.org> Tested-by: Edward Hill <ecgh@chromium.org>
-rw-r--r--driver/accel_lis2dw12.c24
-rw-r--r--driver/accel_lis2dw12.h3
-rw-r--r--driver/build.mk2
-rw-r--r--include/config.h37
-rw-r--r--include/ec_commands.h1
-rw-r--r--include/motion_sense.h5
-rw-r--r--util/ectool.c3
7 files changed, 71 insertions, 4 deletions
diff --git a/driver/accel_lis2dw12.c b/driver/accel_lis2dw12.c
index 7faed478c2..13359575de 100644
--- a/driver/accel_lis2dw12.c
+++ b/driver/accel_lis2dw12.c
@@ -109,7 +109,8 @@ static int fifo_data_avail(struct motion_sensor_t *s)
int ret, nsamples;
if (s->flags & MOTIONSENSE_FLAG_INT_SIGNAL)
- return gpio_get_level(s->int_signal);
+ return gpio_get_level(s->int_signal) ==
+ !!(MOTIONSENSE_FLAG_INT_ACTIVE_HIGH & s->flags);
ret = lis2dw12_get_fifo_samples(s, &nsamples);
/* If we failed to read the FIFO size assume empty. */
@@ -387,11 +388,18 @@ static int set_data_rate(const struct motion_sensor_t *s, int rate, int rnd)
reg_val = LIS2DW12_ODR_12HZ_VAL;
normalized_rate = LIS2DW12_ODR_MIN_VAL;
}
+
+ /* lis2dwl supports 14 bit resolution only at high performance mode,
+ * and it will always stay at high performance mode from initialization.
+ * But lis2dw12 needs switch low power mode according to odr value.
+ */
+#ifndef CONFIG_ACCEL_LIS2DWL
if (reg_val > LIS2DW12_ODR_200HZ_VAL)
ret = set_power_mode(s, LIS2DW12_HIGH_PERF, 0);
else
ret = set_power_mode(s, LIS2DW12_LOW_POWER,
LIS2DW12_LOW_POWER_MODE_2);
+#endif
ret = st_write_data_with_mask(s, LIS2DW12_ACC_ODR_ADDR,
LIS2DW12_ACC_ODR_MASK, reg_val);
@@ -508,8 +516,22 @@ static int init(const struct motion_sensor_t *s)
if (ret != EC_SUCCESS)
goto err_unlock;
+ /* Interrupt trigger level of power-on-reset is HIGH */
+ if (!(MOTIONSENSE_FLAG_INT_ACTIVE_HIGH & s->flags)) {
+ ret = st_write_data_with_mask(s, LIS2DW12_H_ACTIVE_ADDR,
+ LIS2DW12_H_ACTIVE_MASK,
+ LIS2DW12_EN_BIT);
+ if (ret != EC_SUCCESS)
+ goto err_unlock;
+ }
+
+#ifdef CONFIG_ACCEL_LIS2DWL
+ /* lis2dwl supports 14 bit resolution only at high perfomance mode */
+ ret = set_power_mode(s, LIS2DW12_HIGH_PERF, 0);
+#else
/* Set default Mode and Low Power Mode. */
ret = set_power_mode(s, LIS2DW12_LOW_POWER, LIS2DW12_LOW_POWER_MODE_2);
+#endif
if (ret != EC_SUCCESS)
goto err_unlock;
diff --git a/driver/accel_lis2dw12.h b/driver/accel_lis2dw12.h
index de547cb3ad..a4d183de78 100644
--- a/driver/accel_lis2dw12.h
+++ b/driver/accel_lis2dw12.h
@@ -20,6 +20,9 @@
#define LIS2DW12_ADDR0 0x18
#define LIS2DW12_ADDR1 0x19
+#define LIS2DWL_ADDR0_FLAGS 0x18
+#define LIS2DWL_ADDR1_FLAGS 0x19
+
#define LIS2DW12_EN_BIT 0x01
#define LIS2DW12_DIS_BIT 0x00
diff --git a/driver/build.mk b/driver/build.mk
index e09bad1c53..9b3b986e6a 100644
--- a/driver/build.mk
+++ b/driver/build.mk
@@ -19,7 +19,7 @@ driver-$(CONFIG_ACCEL_LIS2D_COMMON)+=accel_lis2dh.o stm_mems_common.o
driver-$(CONFIG_MAG_LIS2MDL)+=mag_lis2mdl.o
driver-$(CONFIG_SENSORHUB_LSM6DSM)+=sensorhub_lsm6dsm.o
driver-$(CONFIG_SYNC)+=sync.o
-driver-$(CONFIG_ACCEL_LIS2DW12)+=accel_lis2dw12.o stm_mems_common.o
+driver-$(CONFIG_ACCEL_LIS2DW_COMMON)+=accel_lis2dw12.o stm_mems_common.o
# BC1.2 Charger Detection Devices
driver-$(CONFIG_BC12_DETECT_MAX14637)+=bc12/max14637.o
diff --git a/include/config.h b/include/config.h
index d301714f63..a39d899573 100644
--- a/include/config.h
+++ b/include/config.h
@@ -76,7 +76,21 @@
#undef CONFIG_ACCEL_LIS2DH
#undef CONFIG_ACCEL_LNG2DM
#undef CONFIG_ACCEL_LIS2D_COMMON
+
+/*
+ * lis2dw12 and lis2dwl have almost the same register interface.
+ * lis2dw12 supports 4 low power modes but lis2dwl only supports one. lis2dwl
+ * only supports 12 bit resolution under low power mode. But lis2dw12 can
+ * support 12 bit or 14 bit resolution at different low power modes. In order
+ * to get 14 bit resolution, lis2dwl does not use low power mode and lis2dw12
+ * only uses 3 of 4 low power modes.
+ *
+ * Use the define for your correct chip and the CONFIG_ACCEL_LIS2DW_COMMON will
+ * automatically get defined.
+ */
#undef CONFIG_ACCEL_LIS2DW12
+#undef CONFIG_ACCEL_LIS2DWL
+#undef CONFIG_ACCEL_LIS2DW_COMMON
#undef CONFIG_ACCELGYRO_BMI160
#undef CONFIG_ACCELGYRO_LSM6DS0
@@ -4205,6 +4219,29 @@
#endif
/*
+ * Automatically define CONFIG_ACCEL_LIS2DW_COMMON if a child option is defined.
+ */
+#if defined(CONFIG_ACCEL_LIS2DW12) || \
+ defined(CONFIG_ACCEL_LIS2DWL)
+#define CONFIG_ACCEL_LIS2DW_COMMON
+#endif
+
+/*
+ * CONFIG_ACCEL_LIS2DW12 and CONFIG_ACCEL_LIS2DWL can't be defined at the same
+ * time.
+ */
+#if defined(CONFIG_ACCEL_LIS2DW12) && \
+ defined(CONFIG_ACCEL_LIS2DWL)
+#error "Define only one of CONFIG_ACCEL_LIS2DW12 and CONFIG_ACCEL_LIS2DWL"
+#endif
+
+/*****************************************************************************/
+/* Define derived seven segment display common path */
+#ifdef CONFIG_MAX695X_SEVEN_SEGMENT_DISPLAY
+#define CONFIG_SEVEN_SEG_DISPLAY
+#endif /* CONFIG_MAX695X_SEVEN_SEGMENT_DISPLAY */
+
+/*
* Apply fuzzer and test config overrides last, since fuzzers and tests need to
* override some of the config flags in non-standard ways to mock only parts of
* the system.
diff --git a/include/ec_commands.h b/include/ec_commands.h
index 9c62c83f0f..20171bed4e 100644
--- a/include/ec_commands.h
+++ b/include/ec_commands.h
@@ -2422,6 +2422,7 @@ enum motionsensor_chip {
MOTIONSENSE_CHIP_LNG2DM = 19,
MOTIONSENSE_CHIP_TCS3400 = 20,
MOTIONSENSE_CHIP_LIS2DW12 = 21,
+ MOTIONSENSE_CHIP_LIS2DWL = 22,
MOTIONSENSE_CHIP_MAX,
};
diff --git a/include/motion_sense.h b/include/motion_sense.h
index a7e130ad33..547547b75b 100644
--- a/include/motion_sense.h
+++ b/include/motion_sense.h
@@ -130,8 +130,9 @@ struct motion_data_t {
* When set, spoof mode will allow the EC to report arbitrary values for any of
* the components.
*/
-#define MOTIONSENSE_FLAG_IN_SPOOF_MODE BIT(1)
-#define MOTIONSENSE_FLAG_INT_SIGNAL BIT(2)
+#define MOTIONSENSE_FLAG_IN_SPOOF_MODE BIT(1)
+#define MOTIONSENSE_FLAG_INT_SIGNAL BIT(2)
+#define MOTIONSENSE_FLAG_INT_ACTIVE_HIGH BIT(3)
struct motion_sensor_t {
/* RO fields */
diff --git a/util/ectool.c b/util/ectool.c
index 887b28a11d..057c261ed3 100644
--- a/util/ectool.c
+++ b/util/ectool.c
@@ -4301,6 +4301,9 @@ static int cmd_motionsense(int argc, char **argv)
case MOTIONSENSE_CHIP_LIS2DW12:
printf("lis2dw12\n");
break;
+ case MOTIONSENSE_CHIP_LIS2DWL:
+ printf("lis2dwl\n");
+ break;
default:
printf("unknown\n");
}