summaryrefslogtreecommitdiff
path: root/driver
diff options
context:
space:
mode:
authorGwendal Grignou <gwendal@chromium.org>2015-07-30 17:47:11 -0700
committerChromeOS Commit Bot <chromeos-commit-bot@chromium.org>2015-08-01 02:51:10 +0000
commitc9832e04f15288ea9d617dba13ba606aa667def5 (patch)
tree6e076a771896c4fb1b354e8d4820c2514f57faa0 /driver
parent5abd6087d4360e9aefa60d4b5eab06fcdb1d851f (diff)
downloadchrome-ec-c9832e04f15288ea9d617dba13ba606aa667def5.tar.gz
driver: bmi160: Allow Dynamic selection of SPI or I2C transport
Using the LSB bit of motion_sensor addr field, we can select at run time if a sensor is using SPI or I2C. When the hardware stabilize, this CL can be removed. BRANCH=smaug TEST=Check that same image works on both i2c and SPI devices. BUG=chrome-os-partner:42304 Change-Id: I9aef9a4dc739366a3d4e2f6fafe063ecfb5199c6 Signed-off-by: Gwendal Grignou <gwendal@chromium.org> Reviewed-on: https://chromium-review.googlesource.com/289925 Reviewed-by: Vincent Palatin <vpalatin@chromium.org>
Diffstat (limited to 'driver')
-rw-r--r--driver/accelgyro_bmi160.c140
-rw-r--r--driver/accelgyro_bmi160.h17
2 files changed, 81 insertions, 76 deletions
diff --git a/driver/accelgyro_bmi160.c b/driver/accelgyro_bmi160.c
index d2fd5d7532..29152fe1f0 100644
--- a/driver/accelgyro_bmi160.c
+++ b/driver/accelgyro_bmi160.c
@@ -98,6 +98,7 @@ static int get_reg_val(const int eng_val, const int round_up,
const struct accel_param_pair *pairs, const int size)
{
int i;
+
for (i = 0; i < size - 1; i++) {
if (eng_val <= pairs[i].val)
break;
@@ -118,6 +119,7 @@ static int get_engineering_val(const int reg_val,
const struct accel_param_pair *pairs, const int size)
{
int i;
+
for (i = 0; i < size; i++) {
if (reg_val == pairs[i].reg_val)
break;
@@ -126,116 +128,102 @@ static int get_engineering_val(const int reg_val,
}
#ifdef CONFIG_SPI_ACCEL_PORT
-/**
- * Write 8bit register from accelerometer.
- */
-static inline int raw_write8(const int addr, const uint8_t reg, int data)
-{
- int rv;
- uint8_t cmd[2] = { reg, data };
- rv = spi_transaction(&spi_devices[addr], cmd, 2, NULL, 0);
- msleep(1);
- return rv;
-}
-
static inline int 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.
*/
-static inline int raw_read8(const int addr, const uint8_t reg, int *data)
+static int raw_read8(const int addr, const uint8_t reg, int *data_ptr)
{
- int rv;
- uint8_t val;
- rv = spi_raw_read(addr, reg, &val, 1);
- if (rv == EC_SUCCESS)
- *data = val;
- return rv;
-}
+ int rv = -EC_ERROR_PARAM1;
-/**
- * Read 16bit register from accelerometer.
- */
-static inline int raw_read16(const int addr, const uint8_t reg, int *data)
-{
- int rv;
- uint16_t val;
- rv = spi_raw_read(addr, reg, (uint8_t *)&val, 2);
- if (rv == EC_SUCCESS)
- *data = val;
+ if (BMI160_IS_SPI(addr)) {
+#ifdef CONFIG_SPI_ACCEL_PORT
+ uint8_t val;
+ rv = spi_raw_read(BMI160_SPI_ADDRESS(addr), reg, &val, 1);
+ if (rv == EC_SUCCESS)
+ *data_ptr = val;
+#endif
+ } else {
+#ifdef I2C_PORT_ACCEL
+ rv = i2c_read8(I2C_PORT_ACCEL, BMI160_I2C_ADDRESS(addr),
+ reg, data_ptr);
+#endif
+ }
return rv;
}
/**
- * Read 32bit register from accelerometer.
- */
-static inline int raw_read32(const int addr, const uint8_t reg, int *data)
-{
- return spi_raw_read(addr, reg, (uint8_t *)data, 4);
-}
-
-/**
- * Read n bytes from accelerometer.
- */
-static inline int raw_read_n(const int addr, const uint8_t reg,
- uint8_t *data_ptr, const int len)
-{
- return spi_raw_read(addr, reg, data_ptr, len);
-}
-#else /* CONFIG_SPI_ACCEL_PORT */
-/**
- * Read 8bit register from accelerometer.
- */
-static inline int raw_read8(const int addr, const uint8_t reg, int *data_ptr)
-{
- return i2c_read8(I2C_PORT_ACCEL, addr, reg, data_ptr);
-}
-
-/**
* Write 8bit register from accelerometer.
*/
-static inline int raw_write8(const int addr, const uint8_t reg, int data)
+static int raw_write8(const int addr, const uint8_t reg, int data)
{
- int rv = i2c_write8(I2C_PORT_ACCEL, addr, reg, data);
+ int rv = -EC_ERROR_PARAM1;
+
+ if (BMI160_IS_SPI(addr)) {
+#ifdef CONFIG_SPI_ACCEL_PORT
+ uint8_t cmd[2] = { reg, data };
+ rv = spi_transaction(&spi_devices[BMI160_SPI_ADDRESS(addr)],
+ cmd, 2, NULL, 0);
+#endif
+ } else {
+#ifdef I2C_PORT_ACCEL
+ rv = i2c_write8(I2C_PORT_ACCEL, BMI160_I2C_ADDRESS(addr),
+ reg, data);
+#endif
+ }
msleep(1);
return rv;
}
/**
- * Read 16bit register from accelerometer.
- */
-static inline int raw_read16(const int addr, const uint8_t reg, int *data_ptr)
-{
- return i2c_read16(I2C_PORT_ACCEL, addr, reg, data_ptr);
-}
-
-/**
* Read 32bit register from accelerometer.
*/
-static inline int raw_read32(const int addr, const uint8_t reg, int *data_ptr)
+static int raw_read32(const int addr, const uint8_t reg, int *data_ptr)
{
- return i2c_read32(I2C_PORT_ACCEL, addr, reg, data_ptr);
+ int rv = -EC_ERROR_PARAM1;
+ if (BMI160_IS_SPI(addr)) {
+#ifdef CONFIG_SPI_ACCEL_PORT
+ rv = spi_raw_read(BMI160_SPI_ADDRESS(addr), reg,
+ (uint8_t *)data_ptr, 4);
+#endif
+ } else {
+#ifdef I2C_PORT_ACCEL
+ rv = i2c_read32(I2C_PORT_ACCEL, BMI160_I2C_ADDRESS(addr),
+ reg, data_ptr);
+#endif
+ }
+ return rv;
}
/**
* Read n bytes from accelerometer.
*/
-static inline int raw_read_n(const int addr, const uint8_t reg,
+static int raw_read_n(const int addr, const uint8_t reg,
uint8_t *data_ptr, const int len)
{
- int ret;
- i2c_lock(I2C_PORT_ACCEL, 1);
- ret = i2c_xfer(I2C_PORT_ACCEL, addr, &reg, 1, data_ptr, len,
- I2C_XFER_SINGLE);
- i2c_lock(I2C_PORT_ACCEL, 0);
- return ret;
+ int rv = -EC_ERROR_PARAM1;
+
+ if (BMI160_IS_SPI(addr)) {
+#ifdef CONFIG_SPI_ACCEL_PORT
+ rv = spi_raw_read(BMI160_SPI_ADDRESS(addr), reg, data_ptr, len);
+#endif
+ } else {
+#ifdef I2C_PORT_ACCEL
+ i2c_lock(I2C_PORT_ACCEL, 1);
+ rv = i2c_xfer(I2C_PORT_ACCEL, BMI160_I2C_ADDRESS(addr), &reg, 1,
+ data_ptr, len, I2C_XFER_SINGLE);
+ i2c_lock(I2C_PORT_ACCEL, 0);
+#endif
+ }
+ return rv;
}
-#endif /* CONFIG_SPI_ACCEL_PORT */
#ifdef CONFIG_MAG_BMI160_BMM150
/**
diff --git a/driver/accelgyro_bmi160.h b/driver/accelgyro_bmi160.h
index 4101b1f07e..4740c9a23e 100644
--- a/driver/accelgyro_bmi160.h
+++ b/driver/accelgyro_bmi160.h
@@ -11,6 +11,23 @@
#include "accelgyro.h"
#include "mag_bmm150.h"
+/*
+ * The addr field of motion_sensor support both SPI and I2C:
+ *
+ * +-------------------------------+---+
+ * | 7 bit i2c address | 0 |
+ * +-------------------------------+---+
+ * Or
+ * +-------------------------------+---+
+ * | SPI device ID | 1 |
+ * +-------------------------------+---+
+ */
+#define BMI160_SET_SPI_ADDRESS(_addr) (((_addr) << 1) | 1)
+#define BMI160_IS_SPI(_addr) ((_addr) & 1)
+#define BMI160_SPI_ADDRESS(_addr) ((_addr) >> 1)
+#define BMI160_I2C_ADDRESS(_addr) (_addr)
+
+/* I2C addresses */
#define BMI160_ADDR0 0xd0
#define BMI160_ADDR1 0xd2