diff options
author | Gwendal Grignou <gwendal@chromium.org> | 2015-07-30 17:47:11 -0700 |
---|---|---|
committer | ChromeOS Commit Bot <chromeos-commit-bot@chromium.org> | 2015-08-01 02:51:10 +0000 |
commit | c9832e04f15288ea9d617dba13ba606aa667def5 (patch) | |
tree | 6e076a771896c4fb1b354e8d4820c2514f57faa0 /driver | |
parent | 5abd6087d4360e9aefa60d4b5eab06fcdb1d851f (diff) | |
download | chrome-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.c | 140 | ||||
-rw-r--r-- | driver/accelgyro_bmi160.h | 17 |
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, ®, 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), ®, 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 |