summaryrefslogtreecommitdiff
path: root/driver/accelgyro_bmi_common.c
diff options
context:
space:
mode:
authorJack Rosenthal <jrosenth@chromium.org>2021-11-04 12:11:58 -0600
committerCommit Bot <commit-bot@chromium.org>2021-11-05 04:22:34 +0000
commit252457d4b21f46889eebad61d4c0a65331919cec (patch)
tree01856c4d31d710b20e85a74c8d7b5836e35c3b98 /driver/accelgyro_bmi_common.c
parent08f5a1e6fc2c9467230444ac9b582dcf4d9f0068 (diff)
downloadchrome-ec-firmware-brya-14505.B-ish.tar.gz
In the interest of making long-term branch maintenance incur as little technical debt on us as possible, we should not maintain any files on the branch we are not actually using. This has the added effect of making it extremely clear when merging CLs from the main branch when changes have the possibility to affect us. The follow-on CL adds a convenience script to actually pull updates from the main branch and generate a CL for the update. BUG=b:204206272 BRANCH=ish TEST=make BOARD=arcada_ish && make BOARD=drallion_ish Signed-off-by: Jack Rosenthal <jrosenth@chromium.org> Change-Id: I17e4694c38219b5a0823e0a3e55a28d1348f4b18 Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/platform/ec/+/3262038 Reviewed-by: Jett Rink <jettrink@chromium.org> Reviewed-by: Tom Hughes <tomhughes@chromium.org>
Diffstat (limited to 'driver/accelgyro_bmi_common.c')
-rw-r--r--driver/accelgyro_bmi_common.c902
1 files changed, 0 insertions, 902 deletions
diff --git a/driver/accelgyro_bmi_common.c b/driver/accelgyro_bmi_common.c
deleted file mode 100644
index 2da407427e..0000000000
--- a/driver/accelgyro_bmi_common.c
+++ /dev/null
@@ -1,902 +0,0 @@
-/* Copyright 2020 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.
- */
-
-/**
- * BMI accelerometer and gyro module for Chrome EC
- * 3D digital accelerometer & 3D digital gyroscope
- */
-
-
-#include "accelgyro.h"
-#include "console.h"
-#include "accelgyro_bmi_common.h"
-#include "mag_bmm150.h"
-#include "mag_lis2mdl.h"
-#include "i2c.h"
-#include "math_util.h"
-#include "motion_sense_fifo.h"
-#include "spi.h"
-
-#define CPUTS(outstr) cputs(CC_ACCEL, outstr)
-#define CPRINTF(format, args...) cprintf(CC_ACCEL, format, ## args)
-#define CPRINTS(format, args...) cprints(CC_ACCEL, format, ## args)
-
-#if !defined(CONFIG_ACCELGYRO_BMI160) && !defined(CONFIG_ACCELGYRO_BMI260) \
-&& !defined(CONFIG_ACCELGYRO_BMI3XX)
-#error "Must use following sensors BMI160 BMI260 BMI3XX"
-#endif
-
-#if defined(CONFIG_ACCELGYRO_BMI260) && !defined(CONFIG_ACCELGYRO_BMI160)
-#define V(s_) 1
-#elif defined(CONFIG_ACCELGYRO_BMI160) && !defined(CONFIG_ACCELGYRO_BMI260)
-#define V(s_) 0
-#else
-#define V(s_) ((s_)->chip == MOTIONSENSE_CHIP_BMI260)
-#endif
-/* Index for which table to use. */
-#if !defined(CONFIG_ACCELGYRO_BMI160) || !defined(CONFIG_ACCELGYRO_BMI260)
-#define T(s_) 0
-#else
-#define T(s_) V(s_)
-#endif
-
-/* List of range values in +/-G's and their associated register values. */
-const struct bmi_accel_param_pair g_ranges[][4] = {
-#ifdef CONFIG_ACCELGYRO_BMI160
- { {2, BMI160_GSEL_2G},
- {4, BMI160_GSEL_4G},
- {8, BMI160_GSEL_8G},
- {16, BMI160_GSEL_16G} },
-#endif
-#ifdef CONFIG_ACCELGYRO_BMI260
- { {2, BMI260_GSEL_2G},
- {4, BMI260_GSEL_4G},
- {8, BMI260_GSEL_8G},
- {16, BMI260_GSEL_16G} },
-#endif
-};
-
-/*
- * List of angular rate range values in +/-dps's
- * and their associated register values.
- */
-const struct bmi_accel_param_pair dps_ranges[][5] = {
-#ifdef CONFIG_ACCELGYRO_BMI160
- { {125, BMI160_DPS_SEL_125},
- {250, BMI160_DPS_SEL_250},
- {500, BMI160_DPS_SEL_500},
- {1000, BMI160_DPS_SEL_1000},
- {2000, BMI160_DPS_SEL_2000} },
-#endif
-#ifdef CONFIG_ACCELGYRO_BMI260
- { {125, BMI260_DPS_SEL_125},
- {250, BMI260_DPS_SEL_250},
- {500, BMI260_DPS_SEL_500},
- {1000, BMI260_DPS_SEL_1000},
- {2000, BMI260_DPS_SEL_2000} },
-#endif
-};
-
-int bmi_get_xyz_reg(const struct motion_sensor_t *s)
-{
- switch (s->type) {
- case MOTIONSENSE_TYPE_ACCEL:
- return BMI_ACC_DATA(V(s));
- case MOTIONSENSE_TYPE_GYRO:
- return BMI_GYR_DATA(V(s));
- case MOTIONSENSE_TYPE_MAG:
- return BMI_AUX_DATA(V(s));
- default:
- return -1;
- }
-}
-
-const struct bmi_accel_param_pair *bmi_get_range_table(
- const struct motion_sensor_t *s, int *psize)
-{
- if (s->type == MOTIONSENSE_TYPE_ACCEL) {
- if (psize)
- *psize = ARRAY_SIZE(g_ranges[T(s)]);
- return g_ranges[T(s)];
- }
- if (psize)
- *psize = ARRAY_SIZE(dps_ranges[T(s)]);
- return dps_ranges[T(s)];
-}
-
-/**
- * @return reg value that matches the given engineering value passed in.
- * The round_up flag is used to specify whether to round up or down.
- * Note, this function always returns a valid reg value. If the request is
- * outside the range of values, it returns the closest valid reg value.
- */
-int bmi_get_reg_val(const int eng_val, const int round_up,
- const struct bmi_accel_param_pair *pairs,
- const int size)
-{
- int i;
-
- for (i = 0; i < size - 1; i++) {
- if (eng_val <= pairs[i].val)
- break;
-
- if (eng_val < pairs[i+1].val) {
- if (round_up)
- i += 1;
- break;
- }
- }
- return pairs[i].reg_val;
-}
-
-/**
- * @return engineering value that matches the given reg val
- */
-int bmi_get_engineering_val(const int reg_val,
- const struct bmi_accel_param_pair *pairs,
- const int size)
-{
- int i;
-
- for (i = 0; i < size; i++) {
- if (reg_val == pairs[i].reg_val)
- break;
- }
- return pairs[i].val;
-}
-
-#ifdef CONFIG_ACCELGYRO_BMI_COMM_SPI
-static int bmi_spi_raw_read(const int addr, const uint8_t reg,
- uint8_t *data, const int len)
-{
- uint8_t cmd = 0x80 | reg;
-
- return spi_transaction(&spi_devices[addr], &cmd, 1, data, len);
-}
-#endif
-
-/**
- * Read 8bit register from accelerometer.
- */
-int bmi_read8(const int port, const uint16_t i2c_spi_addr_flags,
- const int reg, int *data_ptr)
-{
- int rv;
-
-#ifdef CONFIG_ACCELGYRO_BMI_COMM_SPI
- {
- uint8_t val;
-
- rv = bmi_spi_raw_read(ACCEL_GET_SPI_ADDR(i2c_spi_addr_flags),
- reg, &val, 1);
- if (rv == EC_SUCCESS)
- *data_ptr = val;
- }
-#else
- rv = i2c_read8(port, i2c_spi_addr_flags, reg, data_ptr);
-#endif
- return rv;
-}
-
-/**
- * Write 8bit register from accelerometer.
- */
-int bmi_write8(const int port, const uint16_t i2c_spi_addr_flags,
- const int reg, int data)
-{
- int rv;
-
-#ifdef CONFIG_ACCELGYRO_BMI_COMM_SPI
- {
- uint8_t cmd[2] = { reg, data };
-
- rv = spi_transaction(
- &spi_devices[ACCEL_GET_SPI_ADDR(i2c_spi_addr_flags)],
- cmd, 2, NULL, 0);
- }
-#else
- rv = i2c_write8(port, i2c_spi_addr_flags, reg, data);
-#endif
- /*
- * From Bosch: BMI needs a delay of 450us after each write if it
- * is in suspend mode, otherwise the operation may be ignored by
- * the sensor. Given we are only doing write during init, add
- * the delay unconditionally.
- */
- msleep(1);
-
- return rv;
-}
-
-/**
- * Read 16bit register from accelerometer.
- */
-int bmi_read16(const int port, const uint16_t i2c_spi_addr_flags,
- const uint8_t reg, int *data_ptr)
-{
-#ifdef CONFIG_ACCELGYRO_BMI_COMM_SPI
- return bmi_spi_raw_read(ACCEL_GET_SPI_ADDR(i2c_spi_addr_flags), reg,
- (uint8_t *)data_ptr, 2);
-#else
- return i2c_read16(port, i2c_spi_addr_flags, reg, data_ptr);
-#endif
-}
-
-/**
- * Write 16bit register from accelerometer.
- */
-int bmi_write16(const int port, const uint16_t i2c_spi_addr_flags,
- const int reg, int data)
-{
- int rv = -EC_ERROR_PARAM1;
-
-#ifdef CONFIG_ACCELGYRO_BMI_COMM_SPI
- CPRINTS("%s() spi part is not implemented", __func__);
-#else
- rv = i2c_write16(port, i2c_spi_addr_flags, reg, data);
-#endif
- /*
- * From Bosch: BMI needs a delay of 450us after each write if it
- * is in suspend mode, otherwise the operation may be ignored by
- * the sensor. Given we are only doing write during init, add
- * the delay unconditionally.
- */
- msleep(1);
- return rv;
-}
-
-/**
- * Read 32bit register from accelerometer.
- */
-int bmi_read32(const int port, const uint16_t i2c_spi_addr_flags,
- const uint8_t reg, int *data_ptr)
-{
-#ifdef CONFIG_ACCELGYRO_BMI_COMM_SPI
- return bmi_spi_raw_read(ACCEL_GET_SPI_ADDR(i2c_spi_addr_flags), reg,
- (uint8_t *)data_ptr, 4);
-#else
- return i2c_read32(port, i2c_spi_addr_flags, reg, data_ptr);
-#endif
-}
-
-/**
- * Read n bytes from accelerometer.
- */
-int bmi_read_n(const int port, const uint16_t i2c_spi_addr_flags,
- const uint8_t reg, uint8_t *data_ptr, const int len)
-{
-#ifdef CONFIG_ACCELGYRO_BMI_COMM_SPI
- return bmi_spi_raw_read(ACCEL_GET_SPI_ADDR(i2c_spi_addr_flags), reg,
- data_ptr, len);
-#else
- return i2c_read_block(port, i2c_spi_addr_flags, reg, data_ptr, len);
-#endif
-}
-
-/**
- * Write n bytes from accelerometer.
- */
-int bmi_write_n(const int port, const uint16_t i2c_spi_addr_flags,
- const uint8_t reg, const uint8_t *data_ptr, const int len)
-{
- int rv = -EC_ERROR_PARAM1;
-
-#ifdef CONFIG_ACCELGYRO_BMI_COMM_SPI
- CPRINTS("%s() spi part is not implemented", __func__);
-#else
- rv = i2c_write_block(port, i2c_spi_addr_flags, reg, data_ptr, len);
-#endif
- /*
- * From Bosch: BMI needs a delay of 450us after each write if it
- * is in suspend mode, otherwise the operation may be ignored by
- * the sensor. Given we are only doing write during init, add
- * the delay unconditionally.
- */
- msleep(1);
-
- return rv;
-}
-/*
- * Enable/Disable specific bit set of a 8-bit reg.
- */
-int bmi_enable_reg8(const struct motion_sensor_t *s, int reg, uint8_t bits,
- int enable)
-{
- if (enable)
- return bmi_set_reg8(s, reg, bits, 0);
- return bmi_set_reg8(s, reg, 0, bits);
-}
-
-/*
- * Set specific bit set to certain value of a 8-bit reg.
- */
-int bmi_set_reg8(const struct motion_sensor_t *s, int reg, uint8_t bits,
- int mask)
-{
- int ret, val;
-
- ret = bmi_read8(s->port, s->i2c_spi_addr_flags, reg, &val);
- if (ret)
- return ret;
- val = (val & ~mask) | bits;
- ret = bmi_write8(s->port, s->i2c_spi_addr_flags, reg, val);
- return ret;
-}
-
-void bmi_normalize(const struct motion_sensor_t *s, intv3_t v, uint8_t *input)
-{
- int i;
- struct accelgyro_saved_data_t *data = BMI_GET_SAVED_DATA(s);
-
- if (IS_ENABLED(CONFIG_MAG_BMI_BMM150) &&
- (s->type == MOTIONSENSE_TYPE_MAG)) {
- bmm150_normalize(s, v, input);
- } else if (IS_ENABLED(CONFIG_MAG_BMI_LIS2MDL) &&
- (s->type == MOTIONSENSE_TYPE_MAG)) {
- lis2mdl_normalize(s, v, input);
- } else {
- v[0] = ((int16_t)((input[1] << 8) | input[0]));
- v[1] = ((int16_t)((input[3] << 8) | input[2]));
- v[2] = ((int16_t)((input[5] << 8) | input[4]));
- }
- rotate(v, *s->rot_standard_ref, v);
- for (i = X; i <= Z; i++)
- v[i] = SENSOR_APPLY_SCALE(v[i], data->scale[i]);
-}
-
-int bmi_decode_header(struct motion_sensor_t *accel, enum fifo_header hdr,
- uint32_t last_ts, uint8_t **bp, uint8_t *ep)
-{
- if ((hdr & BMI_FH_MODE_MASK) == BMI_FH_EMPTY &&
- (hdr & BMI_FH_PARM_MASK) != 0) {
- int i, size = 0;
- /* Check if there is enough space for the data frame */
- for (i = MOTIONSENSE_TYPE_MAG; i >= MOTIONSENSE_TYPE_ACCEL;
- i--) {
- if (hdr & (1 << (i + BMI_FH_PARM_OFFSET)))
- size += (i == MOTIONSENSE_TYPE_MAG ? 8 : 6);
- }
- if (*bp + size > ep) {
- /* frame is not complete, it will be retransmitted. */
- *bp = ep;
- return 1;
- }
- for (i = MOTIONSENSE_TYPE_MAG; i >= MOTIONSENSE_TYPE_ACCEL;
- i--) {
- struct motion_sensor_t *s = accel + i;
-
- if (hdr & (1 << (i + BMI_FH_PARM_OFFSET))) {
- struct ec_response_motion_sensor_data vector;
- int *v = s->raw_xyz;
-
- vector.flags = 0;
- bmi_normalize(s, v, *bp);
- if (IS_ENABLED(CONFIG_ACCEL_SPOOF_MODE) &&
- s->flags & MOTIONSENSE_FLAG_IN_SPOOF_MODE)
- v = s->spoof_xyz;
- vector.data[X] = v[X];
- vector.data[Y] = v[Y];
- vector.data[Z] = v[Z];
- vector.sensor_num = s - motion_sensors;
- motion_sense_fifo_stage_data(&vector, s, 3,
- last_ts);
- *bp += (i == MOTIONSENSE_TYPE_MAG ? 8 : 6);
- }
- }
-
- return 1;
- } else {
- return 0;
- }
-}
-
-enum fifo_state {
- FIFO_HEADER,
- FIFO_DATA_SKIP,
- FIFO_DATA_TIME,
- FIFO_DATA_CONFIG,
-};
-
-#define BMI_FIFO_BUFFER 64
-static uint8_t bmi_buffer[BMI_FIFO_BUFFER];
-
-int bmi_load_fifo(struct motion_sensor_t *s, uint32_t last_ts)
-{
- struct bmi_drv_data_t *data = BMI_GET_DATA(s);
- uint16_t length;
- enum fifo_state state = FIFO_HEADER;
- uint8_t *bp = bmi_buffer;
- uint8_t *ep;
- uint32_t beginning;
-
- if (s->type != MOTIONSENSE_TYPE_ACCEL)
- return EC_SUCCESS;
-
- if (!(data->flags & (BMI_FIFO_ALL_MASK << BMI_FIFO_FLAG_OFFSET))) {
- /*
- * The FIFO was disabled while we were processing it.
- *
- * Flush potential left over:
- * When sensor is resumed, we won't read old data.
- */
- bmi_write8(s->port, s->i2c_spi_addr_flags, BMI_CMD_REG(V(s)),
- BMI_CMD_FIFO_FLUSH);
- return EC_SUCCESS;
- }
-
- bmi_read_n(s->port, s->i2c_spi_addr_flags, BMI_FIFO_LENGTH_0(V(s)),
- (uint8_t *)&length, sizeof(length));
- length &= BMI_FIFO_LENGTH_MASK(V(s));
-
- /*
- * We have not requested timestamp, no extra frame to read.
- * if we have too much to read, read the whole buffer.
- */
- if (length == 0) {
- /*
- * Disable this message on BMI260, due to this seems to always
- * happen after we complete to read the data.
- * TODO(chingkang): check why this happen on BMI260.
- */
- if (V(s) == 0)
- CPRINTS("unexpected empty FIFO");
- return EC_SUCCESS;
- }
-
- /* Add one byte to get an empty FIFO frame.*/
- length++;
-
- if (length > sizeof(bmi_buffer))
- CPRINTS("unexpected large FIFO: %d", length);
- length = MIN(length, sizeof(bmi_buffer));
-
- bmi_read_n(s->port, s->i2c_spi_addr_flags, BMI_FIFO_DATA(V(s)),
- bmi_buffer, length);
- beginning = *(uint32_t *)bmi_buffer;
- ep = bmi_buffer + length;
- /*
- * FIFO is invalid when reading while the sensors are all
- * suspended.
- * Instead of returning the empty frame, it can return a
- * pattern that looks like a valid header: 84 or 40.
- * If we see those, assume the sensors have been disabled
- * while this thread was running.
- */
- if (beginning == 0x84848484 || (beginning & 0xdcdcdcdc) == 0x40404040) {
- CPRINTS("Suspended FIFO: accel ODR/rate: %d/%d: 0x%08x",
- BASE_ODR(s->config[SENSOR_CONFIG_AP].odr),
- BMI_GET_SAVED_DATA(s)->odr, beginning);
- return EC_SUCCESS;
- }
-
- while (bp < ep) {
- switch (state) {
- case FIFO_HEADER: {
- enum fifo_header hdr = *bp++;
-
- if (bmi_decode_header(s, hdr, last_ts, &bp, ep))
- continue;
- /* Other cases */
- hdr &= 0xdc;
- switch (hdr) {
- case BMI_FH_EMPTY:
- return EC_SUCCESS;
- case BMI_FH_SKIP:
- state = FIFO_DATA_SKIP;
- break;
- case BMI_FH_TIME:
- state = FIFO_DATA_TIME;
- break;
- case BMI_FH_CONFIG:
- state = FIFO_DATA_CONFIG;
- break;
- default:
- CPRINTS("Unknown header: 0x%02x @ %zd", hdr,
- bp - bmi_buffer);
- bmi_write8(s->port, s->i2c_spi_addr_flags,
- BMI_CMD_REG(V(s)),
- BMI_CMD_FIFO_FLUSH);
- return EC_ERROR_NOT_HANDLED;
- }
- break;
- }
- case FIFO_DATA_SKIP:
- CPRINTS("@ %zd - %d, skipped %d frames",
- bp - bmi_buffer, length, *bp);
- bp++;
- state = FIFO_HEADER;
- break;
- case FIFO_DATA_CONFIG:
- CPRINTS("@ %zd - %d, config change: 0x%02x",
- bp - bmi_buffer, length, *bp);
- bp++;
- if (V(s))
- state = FIFO_DATA_TIME;
- else
- state = FIFO_HEADER;
- break;
- case FIFO_DATA_TIME:
- if (bp + 3 > ep) {
- bp = ep;
- continue;
- }
- /* We are not requesting timestamp */
- CPRINTS("timestamp %d",
- (bp[2] << 16) | (bp[1] << 8) | bp[0]);
- state = FIFO_HEADER;
- bp += 3;
- break;
- default:
- CPRINTS("Unknown data: 0x%02x", *bp++);
- state = FIFO_HEADER;
- }
- }
-
- return EC_SUCCESS;
-}
-
-int bmi_set_range(struct motion_sensor_t *s, int range, int rnd)
-{
- int ret, range_tbl_size;
- uint8_t reg_val, ctrl_reg;
- const struct bmi_accel_param_pair *ranges;
-
- if (s->type == MOTIONSENSE_TYPE_MAG) {
- s->current_range = range;
- return EC_SUCCESS;
- }
-
- ctrl_reg = BMI_RANGE_REG(s->type);
- ranges = bmi_get_range_table(s, &range_tbl_size);
- reg_val = bmi_get_reg_val(range, rnd, ranges, range_tbl_size);
-
- ret = bmi_write8(s->port, s->i2c_spi_addr_flags, ctrl_reg, reg_val);
- /* Now that we have set the range, update the driver's value. */
- if (ret == EC_SUCCESS)
- s->current_range = bmi_get_engineering_val(reg_val, ranges,
- range_tbl_size);
- return ret;
-}
-
-int bmi_get_data_rate(const struct motion_sensor_t *s)
-{
- struct accelgyro_saved_data_t *data = BMI_GET_SAVED_DATA(s);
-
- return data->odr;
-}
-
-int bmi_get_offset(const struct motion_sensor_t *s, int16_t *offset,
- int16_t *temp)
-{
- int i, ret = EC_SUCCESS;
- intv3_t v;
-
- switch (s->type) {
- case MOTIONSENSE_TYPE_ACCEL:
- /*
- * The offset of the accelerometer off_acc_[xyz] is a 8 bit
- * two-complement number in units of 3.9 mg independent of the
- * range selected for the accelerometer.
- */
- ret = bmi_accel_get_offset(s, v);
- break;
- case MOTIONSENSE_TYPE_GYRO:
- /*
- * The offset of the gyroscope off_gyr_[xyz] is a 10 bit
- * two-complement number in units of 0.061 °/s.
- * Therefore a maximum range that can be compensated is
- * -31.25 °/s to +31.25 °/s
- */
- ret = bmi_gyro_get_offset(s, v);
- break;
-#ifdef CONFIG_MAG_BMI_BMM150
- case MOTIONSENSE_TYPE_MAG:
- ret = bmm150_get_offset(s, v);
- break;
-#endif /* defined(CONFIG_MAG_BMI_BMM150) */
- default:
- for (i = X; i <= Z; i++)
- v[i] = 0;
- }
-
- if (ret != EC_SUCCESS)
- return ret;
-
- rotate(v, *s->rot_standard_ref, v);
- offset[X] = v[X];
- offset[Y] = v[Y];
- offset[Z] = v[Z];
- /* Saving temperature at calibration not supported yet */
- *temp = EC_MOTION_SENSE_INVALID_CALIB_TEMP;
- return EC_SUCCESS;
-}
-
-#ifdef CONFIG_BODY_DETECTION
-int bmi_get_rms_noise(const struct motion_sensor_t *s)
-{
- int ret;
- fp_t noise_100hz, rate, sqrt_rate_ratio;
-
- switch (s->type) {
- case MOTIONSENSE_TYPE_ACCEL:
- /* change unit of ODR to Hz to prevent INT_TO_FP() overflow */
- rate = INT_TO_FP(bmi_get_data_rate(s) / 1000);
- /*
- * Since the noise is proportional to sqrt(ODR) in BMI, and we
- * have rms noise in 100 Hz, we multiply it with the sqrt(ratio
- * of ODR to 100Hz) to get current noise.
- */
- noise_100hz = INT_TO_FP(BMI_ACCEL_RMS_NOISE_100HZ(V(s)));
- sqrt_rate_ratio =
- fp_sqrtf(fp_div(rate, INT_TO_FP(BMI_ACCEL_100HZ)));
- ret = FP_TO_INT(fp_mul(noise_100hz, sqrt_rate_ratio));
- break;
- default:
- CPRINTS("%s with gyro/mag is not implemented", __func__);
- return 0;
- }
- return ret;
-}
-#endif
-
-int bmi_get_resolution(const struct motion_sensor_t *s)
-{
- return BMI_RESOLUTION;
-}
-
-int bmi_set_scale(const struct motion_sensor_t *s, const uint16_t *scale,
- int16_t temp)
-{
- struct accelgyro_saved_data_t *data = BMI_GET_SAVED_DATA(s);
-
- data->scale[X] = scale[X];
- data->scale[Y] = scale[Y];
- data->scale[Z] = scale[Z];
- return EC_SUCCESS;
-}
-
-int bmi_get_scale(const struct motion_sensor_t *s, uint16_t *scale,
- int16_t *temp)
-{
- struct accelgyro_saved_data_t *data = BMI_GET_SAVED_DATA(s);
-
- scale[X] = data->scale[X];
- scale[Y] = data->scale[Y];
- scale[Z] = data->scale[Z];
- *temp = EC_MOTION_SENSE_INVALID_CALIB_TEMP;
- return EC_SUCCESS;
-}
-
-int bmi_enable_fifo(const struct motion_sensor_t *s, int enable)
-{
- struct bmi_drv_data_t *data = BMI_GET_DATA(s);
- int ret;
-
- /* FIFO start/stop collecting events */
- ret = bmi_enable_reg8(s, BMI_FIFO_CONFIG_1(V(s)),
- BMI_FIFO_SENSOR_EN(V(s), s->type), enable);
- if (ret)
- return ret;
-
- if (enable)
- data->flags |= 1 << (s->type + BMI_FIFO_FLAG_OFFSET);
- else
- data->flags &= ~(1 << (s->type + BMI_FIFO_FLAG_OFFSET));
-
- return ret;
-}
-
-int bmi_read(const struct motion_sensor_t *s, intv3_t v)
-{
- uint8_t data[6];
- int ret, status = 0;
-
- ret = bmi_read8(s->port, s->i2c_spi_addr_flags, BMI_STATUS(V(s)),
- &status);
- if (ret != EC_SUCCESS)
- return ret;
-
- /*
- * If sensor data is not ready, return the previous read data.
- * Note: return success so that motion senor task can read again
- * to get the latest updated sensor data quickly.
- */
- if (!(status & BMI_DRDY_MASK(s->type))) {
- if (v != s->raw_xyz)
- memcpy(v, s->raw_xyz, sizeof(s->raw_xyz));
- return EC_SUCCESS;
- }
-
- /* Read 6 bytes starting at xyz_reg */
- ret = bmi_read_n(s->port, s->i2c_spi_addr_flags, bmi_get_xyz_reg(s),
- data, 6);
-
- if (ret != EC_SUCCESS) {
- CPRINTS("%s: type:0x%X RD XYZ Error %d", s->name, s->type, ret);
- return ret;
- }
- bmi_normalize(s, v, data);
- return EC_SUCCESS;
-}
-
-int bmi_read_temp(const struct motion_sensor_t *s, int *temp_ptr)
-{
- return bmi_get_sensor_temp(s - motion_sensors, temp_ptr);
-}
-
-int bmi_get_sensor_temp(int idx, int *temp_ptr)
-{
- struct motion_sensor_t *s = &motion_sensors[idx];
- int16_t temp;
- int ret;
-
- ret = bmi_read_n(s->port, s->i2c_spi_addr_flags,
- BMI_TEMPERATURE_0(V(s)), (uint8_t *)&temp,
- sizeof(temp));
-
- if (ret || temp == (int16_t)BMI_INVALID_TEMP)
- return EC_ERROR_NOT_POWERED;
-
- *temp_ptr = C_TO_K(23 + ((temp + 256) >> 9));
- return 0;
-}
-
-int bmi_get_normalized_rate(const struct motion_sensor_t *s, int rate, int rnd,
- int *normalized_rate_ptr, uint8_t *reg_val_ptr)
-{
- *reg_val_ptr = BMI_ODR_TO_REG(rate);
- *normalized_rate_ptr = BMI_REG_TO_ODR(*reg_val_ptr);
- if (rnd && (*normalized_rate_ptr < rate)) {
- (*reg_val_ptr)++;
- *normalized_rate_ptr = BMI_REG_TO_ODR(*reg_val_ptr);
- }
-
- switch (s->type) {
- case MOTIONSENSE_TYPE_ACCEL:
- if (*normalized_rate_ptr > BMI_ACCEL_MAX_FREQ ||
- *normalized_rate_ptr < BMI_ACCEL_MIN_FREQ)
- return EC_RES_INVALID_PARAM;
- break;
- case MOTIONSENSE_TYPE_GYRO:
- if (*normalized_rate_ptr > BMI_GYRO_MAX_FREQ ||
- *normalized_rate_ptr < BMI_GYRO_MIN_FREQ)
- return EC_RES_INVALID_PARAM;
- break;
-#ifdef CONFIG_MAG_BMI_BMM150
- case MOTIONSENSE_TYPE_MAG:
- /* We use the regular preset we can go about 100Hz */
- if (*reg_val_ptr > BMI_ODR_100HZ ||
- *reg_val_ptr < BMI_ODR_0_78HZ)
- return EC_RES_INVALID_PARAM;
- break;
-#endif
-
- default:
- return EC_RES_INVALID_PARAM;
- }
- return EC_SUCCESS;
-}
-
-int bmi_accel_get_offset(const struct motion_sensor_t *accel, intv3_t v)
-{
- int i, val, ret;
-
- for (i = X; i <= Z; i++) {
- ret = bmi_read8(accel->port, accel->i2c_spi_addr_flags,
- BMI_OFFSET_ACC70(V(accel)) + i, &val);
- if (ret != EC_SUCCESS)
- return ret;
-
- if (val > 0x7f)
- val = -256 + val;
- v[i] = round_divide((int64_t)val * BMI_OFFSET_ACC_MULTI_MG,
- BMI_OFFSET_ACC_DIV_MG);
- }
-
- return EC_SUCCESS;
-}
-
-int bmi_gyro_get_offset(const struct motion_sensor_t *gyro, intv3_t v)
-{
- int i, val, val98, ret;
-
- /* Read the MSB first */
- ret = bmi_read8(gyro->port, gyro->i2c_spi_addr_flags,
- BMI_OFFSET_EN_GYR98(V(gyro)), &val98);
- if (ret != EC_SUCCESS)
- return ret;
-
- for (i = X; i <= Z; i++) {
- ret = bmi_read8(gyro->port, gyro->i2c_spi_addr_flags,
- BMI_OFFSET_GYR70(V(gyro)) + i, &val);
- if (ret != EC_SUCCESS)
- return ret;
-
- val |= ((val98 >> (2 * i)) & 0x3) << 8;
- if (val > 0x1ff)
- val = -1024 + val;
- v[i] = round_divide((int64_t)val * BMI_OFFSET_GYRO_MULTI_MDS,
- BMI_OFFSET_GYRO_DIV_MDS);
- }
-
- return EC_SUCCESS;
-}
-
-int bmi_set_accel_offset(const struct motion_sensor_t *accel, intv3_t v)
-{
- int i, val, ret;
-
- for (i = X; i <= Z; ++i) {
- val = round_divide((int64_t)v[i] * BMI_OFFSET_ACC_DIV_MG,
- BMI_OFFSET_ACC_MULTI_MG);
- if (val > 127)
- val = 127;
- if (val < -128)
- val = -128;
- if (val < 0)
- val = 256 + val;
- ret = bmi_write8(accel->port, accel->i2c_spi_addr_flags,
- BMI_OFFSET_ACC70(V(accel)) + i, val);
- if (ret != EC_SUCCESS)
- return ret;
- }
-
- return EC_SUCCESS;
-}
-
-int bmi_set_gyro_offset(const struct motion_sensor_t *gyro, intv3_t v,
- int *val98_ptr)
-{
- int i, val, ret;
-
- for (i = X; i <= Z; i++) {
- val = round_divide((int64_t)v[i] * BMI_OFFSET_GYRO_DIV_MDS,
- BMI_OFFSET_GYRO_MULTI_MDS);
- if (val > 511)
- val = 511;
- if (val < -512)
- val = -512;
- if (val < 0)
- val = 1024 + val;
- ret = bmi_write8(gyro->port, gyro->i2c_spi_addr_flags,
- BMI_OFFSET_GYR70(V(gyro)) + i, val & 0xFF);
- if (ret != EC_SUCCESS)
- return ret;
-
- *val98_ptr &= ~(0x3 << (2 * i));
- *val98_ptr |= (val >> 8) << (2 * i);
- }
-
- return EC_SUCCESS;
-}
-
-#ifdef CONFIG_BMI_ORIENTATION_SENSOR
-bool motion_orientation_changed(const struct motion_sensor_t *s)
-{
- return BMI_GET_DATA(s)->orientation !=
- BMI_GET_DATA(s)->last_orientation;
-}
-
-enum motionsensor_orientation *
-motion_orientation_ptr(const struct motion_sensor_t *s)
-{
- return &BMI_GET_DATA(s)->orientation;
-}
-
-void motion_orientation_update(const struct motion_sensor_t *s)
-{
- BMI_GET_DATA(s)->last_orientation = BMI_GET_DATA(s)->orientation;
-}
-#endif
-
-int bmi_list_activities(const struct motion_sensor_t *s,
- uint32_t *enabled,
- uint32_t *disabled)
-{
- struct bmi_drv_data_t *data = BMI_GET_DATA(s);
- *enabled = data->enabled_activities;
- *disabled = data->disabled_activities;
- return EC_RES_SUCCESS;
-}