summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--driver/usb_mux/it5205.c37
-rw-r--r--driver/usb_mux/it5205.h35
-rw-r--r--include/config.h3
3 files changed, 73 insertions, 2 deletions
diff --git a/driver/usb_mux/it5205.c b/driver/usb_mux/it5205.c
index 95416547cd..f275568313 100644
--- a/driver/usb_mux/it5205.c
+++ b/driver/usb_mux/it5205.c
@@ -6,10 +6,8 @@
*/
#include "common.h"
-#include "console.h"
#include "i2c.h"
#include "it5205.h"
-#include "usb_mux.h"
#include "util.h"
#define MUX_STATE_DP_USB_MASK (USB_PD_MUX_USB_ENABLED | USB_PD_MUX_DP_ENABLED)
@@ -24,6 +22,20 @@ static int it5205_write(const struct usb_mux *me, uint8_t reg, uint8_t val)
return i2c_write8(me->i2c_port, me->i2c_addr_flags, reg, val);
}
+static int it5205h_sbu_update(const struct usb_mux *me, uint8_t reg,
+ uint8_t mask, enum mask_update_action action)
+{
+ return i2c_update8(me->i2c_port, IT5205H_SBU_I2C_ADDR_FLAGS,
+ reg, mask, action);
+}
+
+static int it5205h_sbu_field_update(const struct usb_mux *me, uint8_t reg,
+ uint8_t field_mask, uint8_t set_value)
+{
+ return i2c_field_update8(me->i2c_port, IT5205H_SBU_I2C_ADDR_FLAGS,
+ reg, field_mask, set_value);
+}
+
struct mux_chip_id_t {
uint8_t chip_id;
uint8_t reg;
@@ -54,9 +66,30 @@ static int it5205_init(const struct usb_mux *me)
return EC_ERROR_UNKNOWN;
}
+ if (IS_ENABLED(CONFIG_USB_MUX_IT5205H_SBU_OVP)) {
+ RETURN_ERROR(it5205h_sbu_field_update(me, IT5205H_REG_VSR,
+ IT5205H_VREF_SELECT_MASK,
+ IT5205H_VREF_SELECT_3_3V));
+
+ RETURN_ERROR(it5205h_sbu_field_update(me, IT5205H_REG_CSBUOVPSR,
+ IT5205H_OVP_SELECT_MASK,
+ IT5205H_OVP_3_68V));
+
+ RETURN_ERROR(it5205h_sbu_update(me, IT5205H_REG_ISR,
+ IT5205H_ISR_CSBU_MASK, MASK_CLR));
+
+ RETURN_ERROR(it5205h_enable_csbu_switch(me, true));
+ }
+
return EC_SUCCESS;
}
+enum ec_error_list it5205h_enable_csbu_switch(const struct usb_mux *me, bool en)
+{
+ return it5205h_sbu_update(me, IT5205H_REG_CSBUSR,
+ IT5205H_CSBUSR_SWITCH, en ? MASK_SET : MASK_CLR);
+}
+
/* Writes control register to set switch mode */
static int it5205_set_mux(const struct usb_mux *me, mux_state_t mux_state)
{
diff --git a/driver/usb_mux/it5205.h b/driver/usb_mux/it5205.h
index 9e9c4ccfcc..c4fdc6ce49 100644
--- a/driver/usb_mux/it5205.h
+++ b/driver/usb_mux/it5205.h
@@ -8,6 +8,9 @@
#ifndef __CROS_EC_IT5205_H
#define __CROS_EC_IT5205_H
+#include "stdbool.h"
+#include "usb_mux.h"
+
/* I2C interface */
#define IT5205_I2C_ADDR1_FLAGS 0x48
#define IT5205_I2C_ADDR2_FLAGS 0x58
@@ -31,4 +34,36 @@
#define IT5205_DP_USB 0x03
#define IT5205_USB 0x07
+
+/* IT5205-H SBU module */
+
+/* I2C address for SBU switch control */
+#define IT5205H_SBU_I2C_ADDR_FLAGS 0x6a
+
+/* Vref Select Register */
+#define IT5205H_REG_VSR 0x10
+#define IT5205H_VREF_SELECT_MASK 0x30
+#define IT5205H_VREF_SELECT_3_3V 0x00
+#define IT5205H_VREF_SELECT_OFF 0x20
+
+/* CSBU OVP Select Register */
+#define IT5205H_REG_CSBUOVPSR 0x1e
+#define IT5205H_OVP_SELECT_MASK 0x30
+#define IT5205H_OVP_3_90V 0x00
+#define IT5205H_OVP_3_68V 0x10
+#define IT5205H_OVP_3_62V 0x20
+#define IT5205H_OVP_3_57V 0x30
+
+/* CSBU Switch Register */
+#define IT5205H_REG_CSBUSR 0x22
+#define IT5205H_CSBUSR_SWITCH BIT(0)
+
+/* Interrupt Switch Register */
+#define IT5205H_REG_ISR 0x25
+#define IT5205H_ISR_CSBU_MASK BIT(4)
+#define IT5205H_ISR_CSBU_OVP BIT(0)
+
+enum ec_error_list it5205h_enable_csbu_switch(const struct usb_mux *me,
+ bool en);
+
#endif /* __CROS_EC_IT5205_H */
diff --git a/include/config.h b/include/config.h
index db68f2f8e7..3a6251422d 100644
--- a/include/config.h
+++ b/include/config.h
@@ -4538,6 +4538,9 @@
/* 'Virtual' USB mux under host (not EC) control */
#undef CONFIG_USB_MUX_VIRTUAL
+/* Enable IT5205H SBU protection switch */
+#undef CONFIG_USB_MUX_IT5205H_SBU_OVP
+
/*****************************************************************************/
/* USB GPIO config */
#undef CONFIG_USB_GPIO