summaryrefslogtreecommitdiff
path: root/driver/accelgyro_lsm6dso.h
diff options
context:
space:
mode:
authorMario Tesi <mario.tesi@st.com>2018-12-11 09:21:07 +0100
committerchrome-bot <chrome-bot@chromium.org>2019-03-06 06:51:38 -0800
commit9b3355b2f3fdc921b72a35a7bb2ae6cfe7395faa (patch)
tree14f4a6dded2b75f126e953dc39d0426755a3c140 /driver/accelgyro_lsm6dso.h
parent247f511b36985c840d7f70f173129e85e62fcf7f (diff)
downloadchrome-ec-9b3355b2f3fdc921b72a35a7bb2ae6cfe7395faa.tar.gz
driver: lsm6dso: Add support to LSM6DSO IMU
Added support to LSM6DSO IMU sensor. Features included in this driver are: - Basic Sensor Read acc/gyro data - ODR and FS runtime configuration - FIFO water mark interrupt - Shared commons function with ST MEMs devices BUG=none BRANCH=master TEST=Tested on discovery target BOARD with LSM6DSO connected to EC i2c master bus and motion sense task running. Commands used to test LSM6DSO device are: - accelinit - accelrange - accelinfo All basic features tested, including: 1) ODR change: - accelrate 0 [13000:208000] - accelrate 1 [13000:208000] 2) FS Range change: - accelrange 0 [2:16] - accelrange 1 [250:2000] 3) Interrupt on FIFO water mark Signed-off-by: Mario Tesi <mario.tesi@st.com> Change-Id: If2984f7d0d30b0ef475e0525aca2bc365aa4fe21 Signed-off-by: Mario Tesi <mario.tesi@st.com> Reviewed-on: https://chromium-review.googlesource.com/1371364 Commit-Ready: ChromeOS CL Exonerator Bot <chromiumos-cl-exonerator@appspot.gserviceaccount.com> Tested-by: Enrico Granata <egranata@chromium.org> Reviewed-by: Enrico Granata <egranata@chromium.org>
Diffstat (limited to 'driver/accelgyro_lsm6dso.h')
-rw-r--r--driver/accelgyro_lsm6dso.h233
1 files changed, 233 insertions, 0 deletions
diff --git a/driver/accelgyro_lsm6dso.h b/driver/accelgyro_lsm6dso.h
new file mode 100644
index 0000000000..7748c7fe94
--- /dev/null
+++ b/driver/accelgyro_lsm6dso.h
@@ -0,0 +1,233 @@
+/* Copyright 2019 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.
+ */
+
+/* LSM6DSO Accel and Gyro driver for Chrome EC */
+
+#ifndef __CROS_EC_ACCELGYRO_LSM6DSO_H
+#define __CROS_EC_ACCELGYRO_LSM6DSO_H
+
+#include "stm_mems_common.h"
+
+#define LSM6DSO_I2C_ADDR(__x) (__x << 1)
+
+/*
+ * 7-bit address is 110101xb. Where 'x' is determined
+ * by the voltage on the ADDR pin
+ */
+#define LSM6DSO_ADDR0 LSM6DSO_I2C_ADDR(0x6a)
+#define LSM6DSO_ADDR1 LSM6DSO_I2C_ADDR(0x6b)
+
+/* Access to embedded sensor hub register bank */
+#define LSM6DSO_FUNC_CFG_ACC_ADDR 0x01
+#define LSM6DSO_FUNC_CFG_EN 0x80
+
+/* Who Am I */
+#define LSM6DSO_WHO_AM_I_REG 0x0f
+#define LSM6DSO_WHO_AM_I 0x6c
+
+/* Common defines for Acc and Gyro sensors */
+#define LSM6DSO_EN_BIT 0x01
+#define LSM6DSO_DIS_BIT 0x00
+
+#define LSM6DSO_GYRO_OUT_X_L_ADDR 0x22
+#define LSM6DSO_ACCEL_OUT_X_L_ADDR 0x28
+
+#define LSM6DSO_CTRL1_ADDR 0x10
+#define LSM6DSO_CTRL2_ADDR 0x11
+#define LSM6DSO_CTRL3_ADDR 0x12
+#define LSM6DSO_SW_RESET 0x01
+#define LSM6DSO_IF_INC 0x04
+#define LSM6DSO_PP_OD 0x10
+#define LSM6DSO_H_L_ACTIVE 0x20
+#define LSM6DSO_BDU 0x40
+
+#define LSM6DSO_CTRL4_ADDR 0x13
+#define LSM6DSO_INT2_ON_INT1_MASK 0x20
+
+#define LSM6DSO_CTRL5_ADDR 0x14
+#define LSM6DSO_CTRL6_ADDR 0x15
+#define LSM6DSO_CTRL7_ADDR 0x16
+#define LSM6DSO_CTRL8_ADDR 0x17
+#define LSM6DSO_CTRL9_ADDR 0x18
+
+#define LSM6DSO_CTRL10_ADDR 0x19
+#define LSM6DSO_TIMESTAMP_EN 0x20
+
+#define LSM6DSO_STATUS_REG 0x1e
+
+/* Output data rate registers and masks */
+#define LSM6DSO_ODR_REG(_sensor) \
+ (LSM6DSO_CTRL1_ADDR + (_sensor))
+#define LSM6DSO_ODR_MASK 0xf0
+
+/* Hardware FIFO size in byte */
+#define LSM6DSO_MAX_FIFO_SIZE 4096
+#define LSM6DSO_MAX_FIFO_LENGTH (LSM6DSO_MAX_FIFO_SIZE / OUT_XYZ_SIZE)
+
+/* FIFO decimator registers and bitmask */
+#define LSM6DSO_FIFO_CTRL1_ADDR 0x07
+#define LSM6DSO_FIFO_CTRL2_ADDR 0x08
+
+#define LSM6DSO_FIFO_CTRL3_ADDR 0x09
+#define LSM6DSO_FIFO_ODR_XL_MASK 0x0f
+#define LSM6DSO_FIFO_ODR_G_MASK 0xf0
+
+#define LSM6DSO_FIFO_CTRL4_ADDR 0x0a
+#define LSM6DSO_FIFO_MODE_MASK 0x07
+
+#define LSM6DSO_INT1_CTRL 0x0d
+#define LSM6DSO_INT2_CTRL 0x0e
+#define LSM6DSO_INT_FIFO_TH 0x08
+#define LSM6DSO_INT_FIFO_OVR 0x10
+#define LSM6DSO_INT_FIFO_FULL 0x20
+
+#define LSM6DSO_FIFO_STS1_ADDR 0x3a
+#define LSM6DSO_FIFO_STS2_ADDR 0x3b
+#define LSM6DSO_FIFO_DIFF_MASK 0x07ff
+#define LSM6DSO_FIFO_FULL 0x2000
+#define LSM6DSO_FIFO_DATA_OVR 0x4000
+#define LSM6DSO_FIFO_WATERMARK 0x8000
+
+/* Out FIFO data register */
+#define LSM6DSO_FIFO_DATA_ADDR_TAG 0x78
+
+/* Registers value for supported FIFO mode */
+#define LSM6DSO_FIFO_MODE_BYPASS_VAL 0x00
+#define LSM6DSO_FIFO_MODE_CONTINUOUS_VAL 0x06
+
+/* Define device available in FIFO pattern */
+enum lsm6dso_dev_fifo {
+ LSM6DSO_FIFO_DEV_INVALID = -1,
+ LSM6DSO_FIFO_DEV_GYRO = 0,
+ LSM6DSO_FIFO_DEV_ACCEL,
+ LSM6DSO_FIFO_DEV_NUM,
+};
+
+/* Define FIFO data pattern, tag and len */
+#define LSM6DSO_SAMPLE_SIZE 6
+#define LSM6DSO_TS_SAMPLE_SIZE 4
+#define LSM6DSO_TAG_SIZE 1
+#define LSM6DSO_FIFO_SAMPLE_SIZE LSM6DSO_SAMPLE_SIZE + LSM6DSO_TAG_SIZE
+#define LSM6DSO_MAX_FIFO_DEPTH 416
+
+enum lsm6dso_tag_fifo {
+ LSM6DSO_GYRO_TAG = 0x01,
+ LSM6DSO_ACC_TAG = 0x02,
+};
+
+struct lsm6dso_fstatus {
+ uint16_t len;
+ uint16_t pattern;
+};
+
+/* Absolute maximum rate for Acc and Gyro sensors */
+#define LSM6DSO_ODR_MIN_VAL 13000
+#define LSM6DSO_ODR_MAX_VAL \
+ MOTION_MAX_SENSOR_FREQUENCY(416000, 13000)
+
+/* ODR reg value from selected data rate in mHz */
+#define LSM6DSO_ODR_TO_REG(_odr) (__fls(_odr / LSM6DSO_ODR_MIN_VAL) + 1)
+
+#define LSM6DSO_FIFO_ODR_TO_REG(_s) \
+ (_s->type == MOTIONSENSE_TYPE_ACCEL ? LSM6DSO_FIFO_ODR_XL_MASK : \
+ LSM6DSO_FIFO_ODR_G_MASK)
+
+/* Normalized ODR values from selected data rate in mHz */
+#define LSM6DSO_REG_TO_ODR(_reg) (LSM6DSO_ODR_MIN_VAL << (_reg - 1))
+
+/* Full Scale ranges value and gain for Acc */
+#define LSM6DSO_FS_LIST_NUM 4
+
+#define LSM6DSO_ACCEL_FS_ADDR 0x10
+#define LSM6DSO_ACCEL_FS_MASK 0x0c
+
+#define LSM6DSO_ACCEL_FS_2G_VAL 0x00
+#define LSM6DSO_ACCEL_FS_4G_VAL 0x02
+#define LSM6DSO_ACCEL_FS_8G_VAL 0x03
+#define LSM6DSO_ACCEL_FS_16G_VAL 0x01
+
+#define LSM6DSO_ACCEL_FS_MAX_VAL 16
+
+/* Accel reg value from Full Scale range */
+static inline uint8_t lsm6dso_accel_fs_reg(int fs)
+{
+ uint8_t ret;
+
+ switch(fs) {
+ case 2:
+ ret = LSM6DSO_ACCEL_FS_2G_VAL;
+ break;
+ case 16:
+ ret = LSM6DSO_ACCEL_FS_16G_VAL;
+ break;
+ default:
+ ret = __fls(fs);
+ break;
+ }
+
+ return ret;
+}
+
+/* Accel normalized FS value from Full Scale */
+#define LSM6DSO_ACCEL_NORMALIZE_FS(_fs) (1 << __fls(_fs))
+
+/* Full Scale range value and gain for Gyro */
+#define LSM6DSO_GYRO_FS_ADDR 0x11
+#define LSM6DSO_GYRO_FS_MASK 0x0c
+
+/* Minimal Gyro range in mDPS */
+#define LSM6DSO_GYRO_FS_MIN_VAL_MDPS ((8750 << 15) / 1000)
+#define LSM6DSO_GYRO_FS_MAX_REG_VAL 3
+
+/* Gyro reg value for Full Scale selection in DPS */
+#define LSM6DSO_GYRO_FS_REG(_fs) \
+ __fls(MAX(1, (_fs * 1000) / LSM6DSO_GYRO_FS_MIN_VAL_MDPS))
+
+/* Gyro normalized FS value (in DPS) from Full Scale register */
+#define LSM6DSO_GYRO_NORMALIZE_FS(_reg) \
+ ((LSM6DSO_GYRO_FS_MIN_VAL_MDPS << (_reg)) / 1000)
+
+/* FS register address/mask for Acc/Gyro sensors */
+#define LSM6DSO_RANGE_REG(_sensor) (LSM6DSO_ACCEL_FS_ADDR + (_sensor))
+#define LSM6DSO_RANGE_MASK 0x0c
+
+/* Status register bit for Acc/Gyro data ready */
+enum lsm6dso_status {
+ LSM6DSO_STS_DOWN = 0x00,
+ LSM6DSO_STS_XLDA_UP = 0x01,
+ LSM6DSO_STS_GDA_UP = 0x02
+};
+
+/* Status register bitmask for Acc/Gyro data ready */
+#define LSM6DSO_STS_XLDA_MASK 0x01
+#define LSM6DSO_STS_GDA_MASK 0x02
+
+/* Sensor resolution in number of bits: fixed 16 bit */
+#define LSM6DSO_RESOLUTION 16
+
+/* Aggregate private data for all supported sensor (Acc, Gyro) */
+struct lsm6dso_data {
+ struct stprivate_data st_data[LSM6DSO_FIFO_DEV_NUM];
+};
+
+/*
+ * Note: The specific number of samples to discard depends on the filters
+ * configured for the chip, as well as the ODR being set. For most of our
+ * allowed ODRs, 3 should suffice.
+ * See: ST's LSM6DSO application notes (AN5192) Tables 12 and 18 for details
+ */
+#define LSM6DSO_DISCARD_SAMPLES 3
+
+#define LSM6DSO_GET_DATA(_s) ((struct stprivate_data *)((_s)->drv_data))
+
+/* Macro to initialize motion_sensors structure */
+#define LSM6DSO_ST_DATA(g, type) (&(&(g))->st_data[(type)])
+#define LSM6DSO_MAIN_SENSOR(_s) ((_s) - (_s)->type)
+
+extern const struct accelgyro_drv lsm6dso_drv;
+
+void lsm6dso_interrupt(enum gpio_signal signal);
+
+#endif /* __CROS_EC_ACCELGYRO_LSM6DSO_H */