/* 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 */