232 lines
6.3 KiB
C
232 lines
6.3 KiB
C
/* 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"
|
|
|
|
/*
|
|
* 7-bit address is 110101xb. Where 'x' is determined
|
|
* by the voltage on the ADDR pin
|
|
*/
|
|
#define LSM6DSO_ADDR0_FLAGS 0x6a
|
|
#define LSM6DSO_ADDR1_FLAGS 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 */
|