summaryrefslogtreecommitdiff
path: root/driver/accelgyro_bmi_common.c
diff options
context:
space:
mode:
authorChing-Kang Yen <chingkang@chromium.org>2020-03-31 19:37:17 +0800
committerChing-Kang Yen <chingkang@chromium.org>2020-04-23 17:30:41 +0000
commit00b4226613aa84f9734a22e50acd4d7ede960cc1 (patch)
tree93934e49b0d533489df3eb3bdc0475807e6c0206 /driver/accelgyro_bmi_common.c
parent557dafbacbc61cd4c5dec9f27ead4ea17b67aac6 (diff)
downloadchrome-ec-00b4226613aa84f9734a22e50acd4d7ede960cc1.tar.gz
driver: Add BMI260 basic driver support
Add BMI260 accel/gyro driver code. Be able to do initial configuration, start up sensor, config interrupt and fifo, perform calibration, and access the sensor data from AP. BRANCH=None BUG=b:146144827 TEST=make -j4 BOARD=volteer \ && flash_ec --image build/volteer/ec.bin --board volteer Then, check sensor data is available on DUT by "ectool motionsense". TEST=make buildall -j TEST=tast run ${IP} hardware.SensorRing Cq-Depend: chromium:2148802 Change-Id: I5124ee8359a74f98cfe8d26da640325f5e00cb15 Signed-off-by: Ching-Kang Yen <chingkang@chromium.org> Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/platform/ec/+/2086534 Reviewed-by: Gwendal Grignou <gwendal@chromium.org>
Diffstat (limited to 'driver/accelgyro_bmi_common.c')
-rw-r--r--driver/accelgyro_bmi_common.c110
1 files changed, 75 insertions, 35 deletions
diff --git a/driver/accelgyro_bmi_common.c b/driver/accelgyro_bmi_common.c
index 87ad203170..f348edb1c5 100644
--- a/driver/accelgyro_bmi_common.c
+++ b/driver/accelgyro_bmi_common.c
@@ -21,35 +21,66 @@
#define CPRINTF(format, args...) cprintf(CC_ACCEL, format, ## args)
#define CPRINTS(format, args...) cprints(CC_ACCEL, format, ## args)
+#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] = {
- {2, BMI160_GSEL_2G},
- {4, BMI160_GSEL_4G},
- {8, BMI160_GSEL_8G},
- {16, BMI160_GSEL_16G},
+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] = {
- {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},
+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;
+ return BMI_ACC_DATA(V(s));
case MOTIONSENSE_TYPE_GYRO:
- return BMI_GYR_DATA;
+ return BMI_GYR_DATA(V(s));
case MOTIONSENSE_TYPE_MAG:
- return BMI_AUX_DATA;
+ return BMI_AUX_DATA(V(s));
default:
return -1;
}
@@ -60,12 +91,12 @@ const struct bmi_accel_param_pair *bmi_get_range_table(
{
if (s->type == MOTIONSENSE_TYPE_ACCEL) {
if (psize)
- *psize = ARRAY_SIZE(g_ranges);
- return g_ranges;
+ *psize = ARRAY_SIZE(g_ranges[T(s)]);
+ return g_ranges[T(s)];
}
if (psize)
- *psize = ARRAY_SIZE(dps_ranges);
- return dps_ranges;
+ *psize = ARRAY_SIZE(dps_ranges[T(s)]);
+ return dps_ranges[T(s)];
}
/**
@@ -188,7 +219,7 @@ int bmi_read16(const int port, const uint16_t i2c_spi_addr_flags,
if (SLAVE_IS_SPI(i2c_spi_addr_flags)) {
#ifdef CONFIG_SPI_ACCEL_PORT
rv = bmi_spi_raw_read(SLAVE_GET_SPI_ADDR(i2c_spi_addr_flags),
- reg, (uint8_t *)data_ptr, 2);
+ reg, (uint8_t *)data_ptr, 2);
#endif
} else {
#ifdef I2C_PORT_ACCEL
@@ -430,21 +461,27 @@ int bmi_load_fifo(struct motion_sensor_t *s, uint32_t last_ts)
* When sensor is resumed, we won't read old data.
*/
bmi_write8(s->port, s->i2c_spi_addr_flags,
- BMI_CMD_REG, BMI_CMD_FIFO_FLUSH);
+ 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,
+ BMI_FIFO_LENGTH_0(V(s)),
(uint8_t *)&length, sizeof(length));
- length &= BMI_FIFO_LENGTH_MASK;
+ 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) {
- CPRINTS("unexpected empty FIFO");
+ /*
+ * 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;
}
@@ -456,7 +493,7 @@ int bmi_load_fifo(struct motion_sensor_t *s, uint32_t last_ts)
length = MIN(length, sizeof(bmi_buffer));
bmi_read_n(s->port, s->i2c_spi_addr_flags,
- BMI_FIFO_DATA, bmi_buffer, length);
+ BMI_FIFO_DATA(V(s)), bmi_buffer, length);
beginning = *(uint32_t *)bmi_buffer;
ep = bmi_buffer + length;
/*
@@ -502,7 +539,7 @@ int bmi_load_fifo(struct motion_sensor_t *s, uint32_t last_ts)
CPRINTS("Unknown header: 0x%02x @ %zd",
hdr, bp - bmi_buffer);
bmi_write8(s->port, s->i2c_spi_addr_flags,
- BMI_CMD_REG,
+ BMI_CMD_REG(V(s)),
BMI_CMD_FIFO_FLUSH);
return EC_ERROR_NOT_HANDLED;
}
@@ -518,7 +555,10 @@ int bmi_load_fifo(struct motion_sensor_t *s, uint32_t last_ts)
CPRINTS("@ %zd - %d, config change: 0x%02x",
bp - bmi_buffer, length, *bp);
bp++;
- state = FIFO_HEADER;
+ if (V(s))
+ state = FIFO_DATA_TIME;
+ else
+ state = FIFO_HEADER;
break;
case FIFO_DATA_TIME:
if (bp + 3 > ep) {
@@ -655,8 +695,8 @@ int bmi_enable_fifo(const struct motion_sensor_t *s, int enable)
int ret;
/* FIFO start/stop collecting events */
- ret = bmi_enable_reg8(s, BMI_FIFO_CONFIG_1,
- BMI_FIFO_SENSOR_EN(s->type), enable);
+ ret = bmi_enable_reg8(s, BMI_FIFO_CONFIG_1(V(s)),
+ BMI_FIFO_SENSOR_EN(V(s), s->type), enable);
if (ret)
return ret;
@@ -674,7 +714,7 @@ int bmi_read(const struct motion_sensor_t *s, intv3_t v)
int ret, status = 0;
ret = bmi_read8(s->port, s->i2c_spi_addr_flags,
- BMI_STATUS, &status);
+ BMI_STATUS(V(s)), &status);
if (ret != EC_SUCCESS)
return ret;
@@ -713,7 +753,7 @@ int bmi_get_sensor_temp(int idx, int *temp_ptr)
int ret;
ret = bmi_read_n(s->port, s->i2c_spi_addr_flags,
- BMI_TEMPERATURE_0,
+ BMI_TEMPERATURE_0(V(s)),
(uint8_t *)&temp, sizeof(temp));
if (ret || temp == BMI_INVALID_TEMP)
@@ -765,7 +805,7 @@ void bmi_accel_get_offset(const struct motion_sensor_t *accel, intv3_t v)
for (i = X; i <= Z; i++) {
bmi_read8(accel->port, accel->i2c_spi_addr_flags,
- BMI_OFFSET_ACC70 + i, &val);
+ BMI_OFFSET_ACC70(V(accel)) + i, &val);
if (val > 0x7f)
val = -256 + val;
v[i] = round_divide(
@@ -781,10 +821,10 @@ void bmi_gyro_get_offset(const struct motion_sensor_t *gyro, intv3_t v)
/* Read the MSB first */
bmi_read8(gyro->port, gyro->i2c_spi_addr_flags,
- BMI_OFFSET_EN_GYR98, &val98);
+ BMI_OFFSET_EN_GYR98(V(gyro)), &val98);
for (i = X; i <= Z; i++) {
bmi_read8(gyro->port, gyro->i2c_spi_addr_flags,
- BMI_OFFSET_GYR70 + i, &val);
+ BMI_OFFSET_GYR70(V(gyro)) + i, &val);
val |= ((val98 >> (2 * i)) & 0x3) << 8;
if (val > 0x1ff)
val = -1024 + val;
@@ -809,7 +849,7 @@ void bmi_set_accel_offset(const struct motion_sensor_t *accel, intv3_t v)
if (val < 0)
val = 256 + val;
bmi_write8(accel->port, accel->i2c_spi_addr_flags,
- BMI_OFFSET_ACC70 + i, val);
+ BMI_OFFSET_ACC70(V(accel)) + i, val);
}
}
@@ -829,7 +869,7 @@ void bmi_set_gyro_offset(const struct motion_sensor_t *gyro, intv3_t v,
if (val < 0)
val = 1024 + val;
bmi_write8(gyro->port, gyro->i2c_spi_addr_flags,
- BMI_OFFSET_GYR70 + i, val & 0xFF);
+ BMI_OFFSET_GYR70(V(gyro)) + i, val & 0xFF);
*val98_ptr &= ~(0x3 << (2 * i));
*val98_ptr |= (val >> 8) << (2 * i);
}