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-21 05:46:30 +0000
commita29f68a815b8e0ddb472c2cc812d6b18ac4b8c74 (patch)
tree9b20c9be82c45c8a0d1b52372bb523bf74320187
parent74f268374972bdc8bd6c2a5c412d31edafa812b1 (diff)
downloadchrome-ec-a29f68a815b8e0ddb472c2cc812d6b18ac4b8c74.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>
-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.h31
-rw-r--r--include/ec_commands.h1
-rw-r--r--include/motion_sense.h5
-rw-r--r--util/ectool.c3
7 files changed, 65 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 0770734496..e110e41667 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 5bb89a7a46..faf64f0153 100644
--- a/include/config.h
+++ b/include/config.h
@@ -84,7 +84,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
@@ -4723,6 +4737,23 @@
#define CONFIG_ACCEL_LIS2D_COMMON
#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
diff --git a/include/ec_commands.h b/include/ec_commands.h
index ce0ec1fce9..12ce2cd4d5 100644
--- a/include/ec_commands.h
+++ b/include/ec_commands.h
@@ -2468,6 +2468,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 f6abf8949c..8c3f0cdbde 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 5cf43d0df3..0107f5c020 100644
--- a/util/ectool.c
+++ b/util/ectool.c
@@ -4676,6 +4676,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");
}