diff options
Diffstat (limited to 'driver/tcpm')
-rw-r--r-- | driver/tcpm/ps8xxx.c | 52 | ||||
-rw-r--r-- | driver/tcpm/ps8xxx.h | 38 |
2 files changed, 90 insertions, 0 deletions
diff --git a/driver/tcpm/ps8xxx.c b/driver/tcpm/ps8xxx.c index e435621b37..b9e83c6d13 100644 --- a/driver/tcpm/ps8xxx.c +++ b/driver/tcpm/ps8xxx.c @@ -172,6 +172,58 @@ static int ps8815_dci_disable(int port) } #endif /* CONFIG_USB_PD_TCPM_PS8815 */ +#ifdef CONFIG_USB_PD_TCPM_PS8805 +static int ps8805_gpio_mask[] = { + PS8805_REG_GPIO_0, + PS8805_REG_GPIO_1, + PS8805_REG_GPIO_2, +}; + +int ps8805_gpio_set_level(int port, enum ps8805_gpio signal, int level) +{ + int rv; + int regval; + int mask; + + if (signal >= PS8805_GPIO_NUM) + return EC_ERROR_INVAL; + + rv = i2c_read8(tcpc_config[port].i2c_info.port, + PS8805_VENDOR_DEFINED_I2C_ADDR, + PS8805_REG_GPIO_CONTROL, ®val); + if (rv) + return rv; + + mask = ps8805_gpio_mask[signal]; + if (level) + regval |= mask; + else + regval &= ~mask; + + return i2c_write8(tcpc_config[port].i2c_info.port, + PS8805_VENDOR_DEFINED_I2C_ADDR, + PS8805_REG_GPIO_CONTROL, regval); +} + +int ps8805_gpio_get_level(int port, enum ps8805_gpio signal, int *level) +{ + int regval; + int rv; + + if (signal >= PS8805_GPIO_NUM) + return EC_ERROR_INVAL; + + rv = i2c_read8(tcpc_config[port].i2c_info.port, + PS8805_VENDOR_DEFINED_I2C_ADDR, + PS8805_REG_GPIO_CONTROL, ®val); + if (rv) + return rv; + *level = !!(regval & ps8805_gpio_mask[signal]); + + return EC_SUCCESS; +} +#endif /* CONFIG_USB_PD_TCPM_PS8805 */ + enum ps8xxx_variant_regs { REG_FIRST_INDEX = 0, /* NOTE: The rev will read as 0x00 if the FW has malfunctioned. */ diff --git a/driver/tcpm/ps8xxx.h b/driver/tcpm/ps8xxx.h index 1f3d2d9b88..514579ecca 100644 --- a/driver/tcpm/ps8xxx.h +++ b/driver/tcpm/ps8xxx.h @@ -58,4 +58,42 @@ /* Vendor defined registers */ #define PS8815_P1_REG_HW_REVISION 0xF0 +/* + * PS8805 GPIO control register. Note the device I2C address of 0x1A is + * independent of the ADDR pin on the chip, and not the same address being used + * for TCPCI functions. + */ +#define PS8805_VENDOR_DEFINED_I2C_ADDR 0x1A +#define PS8805_REG_GPIO_CONTROL 0x21 +#define PS8805_REG_GPIO_0 BIT(7) +#define PS8805_REG_GPIO_1 BIT(5) +#define PS8805_REG_GPIO_2 BIT(6) + +enum ps8805_gpio { + PS8805_GPIO_0, + PS8805_GPIO_1, + PS8805_GPIO_2, + PS8805_GPIO_NUM, +}; + +/** + * Set PS8805 gpio signal to desired level + * + * @param port: The Type-C port number. + * @param signal PS8805 gpio number (0, 1, or 2) + * @param level desired level + * @return EC_SUCCESS if I2C accesses are successful + */ +int ps8805_gpio_set_level(int port, enum ps8805_gpio signal, int level); + +/** + * Get PS8805 gpio signal value + * + * @param port: The Type-C port number. + * @param signal PS8805 gpio number (0, 1, or 2) + * @param pointer location to store gpio level + * @return EC_SUCCESS if I2C accesses are successful + */ +int ps8805_gpio_get_level(int port, enum ps8805_gpio signal, int *level); + #endif /* defined(__CROS_EC_USB_PD_TCPM_PS8XXX_H) */ |