diff options
author | Name <poornima.tom@intel.com> | 2020-06-19 11:16:23 +0530 |
---|---|---|
committer | Commit Bot <commit-bot@chromium.org> | 2020-10-26 21:09:23 +0000 |
commit | 426024dbcc36608744103aaecce815457a9de8a1 (patch) | |
tree | 1caf38b89ce6a3d2ad2cea276decd9a1d3e9eb1e | |
parent | 8a4a98641799f54ce93ef707288d1fc1a7d35db0 (diff) | |
download | chrome-ec-426024dbcc36608744103aaecce815457a9de8a1.tar.gz |
IO-expander: Add driver support for PCA9675
BRANCH=None
BUG=b:169551130
TEST=make buildall -j
Change-Id: If565996850c5c75f3d425e2dc7f705b624ad4cc4
Signed-off-by: pandeyan <anshuman.pandey@intel.com>
Signed-off-by: Vijay Hiremath <vijay.p.hiremath@intel.com>
Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/platform/ec/+/2435172
Reviewed-by: caveh jalali <caveh@chromium.org>
Commit-Queue: Poornima Tom <poornima.tom@intel.com>
-rw-r--r-- | driver/build.mk | 3 | ||||
-rw-r--r-- | driver/ioexpander/pca9675.c | 80 | ||||
-rw-r--r-- | driver/ioexpander/pca9675.h | 87 | ||||
-rw-r--r-- | include/config.h | 3 |
4 files changed, 172 insertions, 1 deletions
diff --git a/driver/build.mk b/driver/build.mk index ded9530eb1..94348c340d 100644 --- a/driver/build.mk +++ b/driver/build.mk @@ -78,8 +78,9 @@ include $(_driver_cur_dir)fingerprint/build.mk # I/O expander driver-$(CONFIG_IO_EXPANDER_IT8801)+=ioexpander/it8801.o -driver-$(CONFIG_IO_EXPANDER_PCA9534)+=ioexpander/pca9534.o driver-$(CONFIG_IO_EXPANDER_NCT38XX)+=ioexpander/ioexpander_nct38xx.o +driver-$(CONFIG_IO_EXPANDER_PCA9534)+=ioexpander/pca9534.o +driver-$(CONFIG_IO_EXPANDER_PCA9675)+=ioexpander/pca9675.o driver-$(CONFIG_IO_EXPANDER_PCAL6408)+=ioexpander/pcal6408.o diff --git a/driver/ioexpander/pca9675.c b/driver/ioexpander/pca9675.c new file mode 100644 index 0000000000..df1217bba0 --- /dev/null +++ b/driver/ioexpander/pca9675.c @@ -0,0 +1,80 @@ +/* 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. + * + * NXP PCA9675PW I/O Port expander driver source + */ + +/* TODO (b/169814014): Implement code to fit "struct ioexpander_drv" */ + +#include "pca9675.h" + +static uint16_t cache_out_pins[CONFIG_IO_EXPANDER_PORT_COUNT]; + +static int pca9675_read(int ioex, uint16_t *data) +{ + return i2c_xfer(pca9675_iox[ioex].i2c_host_port, + pca9675_iox[ioex].i2c_addr_flags, + NULL, 0, (uint8_t *)data, 2); +} + +static int pca9675_write(int ioex, uint16_t data) +{ + /* + * PCA9675 is Quasi-bidirectional I/O architecture hence + * append the direction (1 = input, 0 = output) to prevent + * overwriting I/O pins inadvertently. + */ + data |= pca9675_iox[ioex].io_direction; + + return i2c_xfer(pca9675_iox[ioex].i2c_host_port, + pca9675_iox[ioex].i2c_addr_flags, + (uint8_t *)&data, 2, NULL, 0); +} + +static int pca9675_reset(int ioex) +{ + uint8_t reset = PCA9675_RESET_SEQ_DATA; + + return i2c_xfer(pca9675_iox[ioex].i2c_host_port, + 0, &reset, 1, NULL, 0); +} + +int pca9675_get_pin(int ioex, uint16_t pin, bool *level) +{ + int rv = EC_SUCCESS; + uint16_t data_read; + + /* Read from IO-expander only if the pin is input */ + if (pca9675_iox[ioex].io_direction & pin) { + rv = pca9675_read(ioex, &data_read); + if (!rv) + *level = !!(data_read & pin); + } else { + *level = !!(cache_out_pins[ioex] & pin); + } + + return rv; +} + +int pca9675_update_pins(int ioex, uint16_t setpins, uint16_t clearpins) +{ + /* Update the output pins */ + cache_out_pins[ioex] |= setpins; + cache_out_pins[ioex] &= ~clearpins; + + return pca9675_write(ioex, cache_out_pins[ioex]); +} + +int pca9675_init(int ioex) +{ + int rv; + + /* Set pca9675 to Power-on reset */ + rv = pca9675_reset(ioex); + if (rv) + return rv; + + /* Initialize the I/O direction */ + return pca9675_write(ioex, 0); +} diff --git a/driver/ioexpander/pca9675.h b/driver/ioexpander/pca9675.h new file mode 100644 index 0000000000..e01278f7d6 --- /dev/null +++ b/driver/ioexpander/pca9675.h @@ -0,0 +1,87 @@ +/* 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. + * + * NXP PCA9675PW I/O Port expander driver header + */ + +#ifndef __CROS_EC_IOEXPANDER_PCA9675_H +#define __CROS_EC_IOEXPANDER_PCA9675_H + +#include <stdbool.h> + +#include "hooks.h" +#include "i2c.h" + +#define PCA9675_IO_P00 BIT(0) +#define PCA9675_IO_P01 BIT(1) +#define PCA9675_IO_P02 BIT(2) +#define PCA9675_IO_P03 BIT(3) +#define PCA9675_IO_P04 BIT(4) +#define PCA9675_IO_P05 BIT(5) +#define PCA9675_IO_P06 BIT(6) +#define PCA9675_IO_P07 BIT(7) + +#define PCA9675_IO_P10 BIT(8) +#define PCA9675_IO_P11 BIT(9) +#define PCA9675_IO_P12 BIT(10) +#define PCA9675_IO_P13 BIT(11) +#define PCA9675_IO_P14 BIT(12) +#define PCA9675_IO_P15 BIT(13) +#define PCA9675_IO_P16 BIT(14) +#define PCA9675_IO_P17 BIT(15) + +/* Sent 06 to address 00 to reset the PCA9675 to back to power up state */ +#define PCA9675_RESET_SEQ_DATA 0x06 + +/* Default I/O directons of PCA9675 is input */ +#define PCA9675_DEFAULT_IO_DIRECTION 0xffff + +#define HOOK_PRIO_INIT_PCA9675 (HOOK_PRIO_INIT_I2C + 1) + +/* PCA9675 IOexpander structure */ +struct pca9675_ioexpander { + /* Physical I2C port connects to the IO expander chip. */ + const int i2c_host_port; + /* I2C slave address */ + const uint16_t i2c_addr_flags; + /* I/O port direction (1 = input, 0 = output) */ + const uint16_t io_direction; +}; + +extern const struct pca9675_ioexpander pca9675_iox[]; + +/* + * Get input level. Note that this reflects the actual level on the + * pin, even if the pin is configured as output. + * + * @param ioex I/O expander port number + * @param pin Pin number + * @param level Pointer to get pin level + * + * @return EC_SUCCESS, or EC_ERROR_* on error. + */ +int pca9675_get_pin(int ioex, uint16_t pin, bool *level); + +/* + * Update pin levels. This function has no effect if the pin is + * configured as input. + * + * @param ioex I/O expander port number + * @param setpins Pins to be set + * @param clearpins Pins to be cleared + * + * @return EC_SUCCESS, or EC_ERROR_* on error. + */ +int pca9675_update_pins(int ioex, uint16_t setpins, uint16_t clearpins); + +/* + * Initialize the PCA9675 to power up state + * + * @param ioex I/O expander port number + * + * @return EC_SUCCESS, or EC_ERROR_* on error. + */ +int pca9675_init(int ioex); + +#endif /* __CROS_EC_IOEXPANDER_PCA9675_H */ diff --git a/include/config.h b/include/config.h index 4c3ec5289e..71baba5efc 100644 --- a/include/config.h +++ b/include/config.h @@ -2451,6 +2451,9 @@ /* Support NXP PCA9534 I/O expander. */ #undef CONFIG_IO_EXPANDER_PCA9534 +/* Support NXP PCA9675 I/O expander. */ +#undef CONFIG_IO_EXPANDER_PCA9675 + /* Support NXP PCAL6408 I/O expander. */ #undef CONFIG_IO_EXPANDER_PCAL6408 |