diff options
author | Koro Chen <koro.chen@mediatek.com> | 2016-03-07 21:53:14 +0800 |
---|---|---|
committer | chrome-bot <chrome-bot@chromium.org> | 2016-04-20 01:40:00 -0700 |
commit | f00d4621a480f12293214f14716ac33a90281ce7 (patch) | |
tree | 7ca0a72d7cf3b0ea93371b70a603d3b24edf4be4 | |
parent | ee5d09823f3f26ab5d31a32c96d550bb28ace808 (diff) | |
download | chrome-ec-f00d4621a480f12293214f14716ac33a90281ce7.tar.gz |
elm: kionix: allow dynamic selection of SPI or I2C transport
This CL ports c9832e04f1528 to Kionix accel driver. And also enables SPI
access of Elm's base kx022.
BUG=none
BRANCH=none
TEST=manual
Change-Id: I0c1de028c82fc62a124bb5b930a3882c4b368d71
Signed-off-by: Koro Chen <koro.chen@mediatek.com>
Reviewed-on: https://chromium-review.googlesource.com/331851
Reviewed-by: Wei-Ning Huang <wnhuang@chromium.org>
-rw-r--r-- | board/elm/board.c | 2 | ||||
-rw-r--r-- | board/elm/gpio.inc | 2 | ||||
-rw-r--r-- | driver/accel_kionix.c | 58 | ||||
-rw-r--r-- | driver/accel_kionix.h | 14 |
4 files changed, 68 insertions, 8 deletions
diff --git a/board/elm/board.c b/board/elm/board.c index ee2d6275c0..d772d7e372 100644 --- a/board/elm/board.c +++ b/board/elm/board.c @@ -106,7 +106,7 @@ const unsigned int i2c_ports_used = ARRAY_SIZE(i2c_ports); /* SPI devices */ const struct spi_device_t spi_devices[] = { - { CONFIG_SPI_ACCEL_PORT, 1, GPIO_SPI2_NSS } + { CONFIG_SPI_ACCEL_PORT, 2, GPIO_SPI2_NSS } }; const unsigned int spi_devices_used = ARRAY_SIZE(spi_devices); diff --git a/board/elm/gpio.inc b/board/elm/gpio.inc index 3c23b59ea2..0488d5f405 100644 --- a/board/elm/gpio.inc +++ b/board/elm/gpio.inc @@ -99,7 +99,7 @@ GPIO(I2C1_SCL, PIN(B, 13), GPIO_INPUT) /* PD I2C */ GPIO(I2C1_SDA, PIN(B, 14), GPIO_INPUT) /* SPI MASTER. For SPI sensor */ -GPIO(SPI2_NSS, PIN(D, 0), GPIO_OUT_LOW) +GPIO(SPI2_NSS, PIN(D, 0), GPIO_OUT_HIGH) ALTERNATE(PIN_MASK(A, 0x0600), 1, MODULE_UART, 0) /* USART1: PA9/PA10 */ ALTERNATE(PIN_MASK(B, 0x00c0), 1, MODULE_I2C, 0) /* I2C MASTER:PB6/7 */ diff --git a/driver/accel_kionix.c b/driver/accel_kionix.c index 0a3754b4dd..b715173b7e 100644 --- a/driver/accel_kionix.c +++ b/driver/accel_kionix.c @@ -17,6 +17,7 @@ #include "driver/accel_kxcj9.h" #include "i2c.h" #include "math_util.h" +#include "spi.h" #include "task.h" #include "util.h" @@ -128,7 +129,23 @@ static int find_param_index(const int eng_val, const int round_up, static int raw_read8(const int port, const int addr, const int reg, int *data_ptr) { - return i2c_read8(port, addr, reg, data_ptr); + int rv; + + if (KIONIX_IS_SPI(addr)) { +#ifdef CONFIG_SPI_ACCEL_PORT + uint8_t val; + uint8_t cmd = 0x80 | reg; + + rv = spi_transaction(&spi_devices[KIONIX_SPI_ADDRESS(addr)], + &cmd, 1, &val, 1); + if (rv == EC_SUCCESS) + *data_ptr = val; + +#endif + } else { + rv = i2c_read8(port, addr, reg, data_ptr); + } + return rv; } /** @@ -136,7 +153,39 @@ static int raw_read8(const int port, const int addr, const int reg, */ static int raw_write8(const int port, const int addr, const int reg, int data) { - return i2c_write8(port, addr, reg, data); + int rv; + + if (KIONIX_IS_SPI(addr)) { +#ifdef CONFIG_SPI_ACCEL_PORT + uint8_t cmd[2] = { reg, data }; + + rv = spi_transaction(&spi_devices[KIONIX_SPI_ADDRESS(addr)], + cmd, 2, NULL, 0); +#endif + } else { + rv = i2c_write8(port, addr, reg, data); + } + return rv; +} + +static int raw_read_multi(const int port, int addr, uint8_t reg, + uint8_t *rxdata, int rxlen) +{ + int rv; + + if (KIONIX_IS_SPI(addr)) { +#ifdef CONFIG_SPI_ACCEL_PORT + reg |= 0x80; + rv = spi_transaction(&spi_devices[KIONIX_SPI_ADDRESS(addr)], + ®, 1, rxdata, rxlen); +#endif + } else { + i2c_lock(port, 1); + rv = i2c_xfer(port, addr, ®, 1, rxdata, rxlen, + I2C_XFER_SINGLE); + i2c_lock(port, 0); + } + return rv; } /** @@ -378,10 +427,7 @@ static int read(const struct motion_sensor_t *s, vector_3_t v) /* Read 6 bytes starting at XOUT_L. */ reg = KIONIX_XOUT_L(data->variant); mutex_lock(s->mutex); - i2c_lock(s->port, 1); - ret = i2c_xfer(s->port, s->addr, ®, 1, acc, 6, - I2C_XFER_SINGLE); - i2c_lock(s->port, 0); + ret = raw_read_multi(s->port, s->addr, reg, acc, 6); mutex_unlock(s->mutex); if (ret != EC_SUCCESS) diff --git a/driver/accel_kionix.h b/driver/accel_kionix.h index e326dd3cb3..3dc7f314a4 100644 --- a/driver/accel_kionix.h +++ b/driver/accel_kionix.h @@ -44,6 +44,20 @@ struct kionix_accel_data { extern const struct accelgyro_drv kionix_accel_drv; +/* + * The addr field of motion_sensor support both SPI and I2C: + * + * +-------------------------------+---+ + * | 7 bit i2c address | 0 | + * +-------------------------------+---+ + * Or + * +-------------------------------+---+ + * | SPI device ID | 1 | + * +-------------------------------+---+ + */ +#define KIONIX_IS_SPI(_addr) ((_addr) & 1) +#define KIONIX_SPI_ADDRESS(_addr) ((_addr) >> 1) + #define KIONIX_CTRL1_REG(v) (KX022_CNTL1 + \ (v) * (KXCJ9_CTRL1 - KX022_CNTL1)) #define KIONIX_CTRL2_REG(v) (KX022_CNTL2 + \ |