blob: ccc1fa0e84436f4a1ad0c6b2539175defa422926 [file] [log] [blame]
/* Copyright 2019 The ChromiumOS Authors
* 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 "driver/accelgyro_lsm6dso_public.h"
#include "stm_mems_common.h"
/* 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
/* 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_TAG_SIZE 1
#define LSM6DSO_FIFO_SAMPLE_SIZE (OUT_XYZ_SIZE + LSM6DSO_TAG_SIZE)
enum lsm6dso_tag_fifo {
LSM6DSO_GYRO_TAG = 0x01,
LSM6DSO_ACC_TAG = 0x02,
};
struct lsm6dso_fstatus {
uint16_t len;
uint16_t pattern;
};
/* 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_MASK(_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
/* Macro to initialize motion_sensors structure */
#define LSM6DSO_ST_DATA(g, type) (&((g).st_data[type]))
extern const struct accelgyro_drv lsm6dso_drv;
void lsm6dso_interrupt(enum gpio_signal signal);
#if defined(CONFIG_ZEPHYR)
#if DT_NODE_EXISTS(DT_ALIAS(lsm6dso_int))
/* Get the motion sensor ID of the LSM6DSO sensor that generates the
* interrupt. The interrupt is converted to the event and transferred to
* motion sense task that actually handles the interrupt.
*
* Here we use an alias (lsm6dso_int) to get the motion sensor ID. This alias
* MUST be defined for this driver to work.
* aliases {
* lsm6dso-int = &lid_accel;
* };
*/
#define CONFIG_ACCEL_LSM6DSO_INT_EVENT \
TASK_EVENT_MOTION_SENSOR_INTERRUPT(SENSOR_ID(DT_ALIAS(lsm6dso_int)))
#endif
#endif /* CONFIG_ZEPHYR */
#endif /* __CROS_EC_ACCELGYRO_LSM6DSO_H */