diff options
-rw-r--r-- | driver/ppc/syv682x.c | 30 | ||||
-rw-r--r-- | driver/ppc/syv682x.h | 3 |
2 files changed, 19 insertions, 14 deletions
diff --git a/driver/ppc/syv682x.c b/driver/ppc/syv682x.c index fe1b85b607..e66411fd0a 100644 --- a/driver/ppc/syv682x.c +++ b/driver/ppc/syv682x.c @@ -39,15 +39,22 @@ static timestamp_t vconn_oc_timer[CONFIG_USB_PD_PORT_MAX_COUNT]; #define SYV682X_VBUS_DET_THRESH_MV 4000 /* Longest time that can be programmed in DSG_TIME field */ -#define SYV682X_MAX_VBUS_DISCHARGE_TIME_MS 400 -/* Delay between checks when polling the interrupt registers */ -#define INTERRUPT_DELAY_MS 10 +#define SYV682X_MAX_VBUS_DISCHARGE_TIME_MS 400 +/* + * Delay between checks when polling the interrupt registers. Must be longer + * than the HW deglitch on OC (10ms) + */ +#define INTERRUPT_DELAY_MS 15 /* Deglitch in ms of sourcing overcurrent detection */ #define SOURCE_OC_DEGLITCH_MS 100 #define VCONN_OC_DEGLITCH_MS 100 /* Max. number of OC events allowed before disabling port */ #define OCP_COUNT_LIMIT 3 +#if INTERRUPT_DELAY_MS <= SYV682X_HW_OC_DEGLITCH_MS +#error "INTERRUPT_DELAY_MS should be greater than SYV682X_HW_OC_DEGLITCH_MS" +#endif + #if SOURCE_OC_DEGLITCH_MS < INTERRUPT_DELAY_MS #error "SOURCE_OC_DEGLITCH_MS should be at least INTERRUPT_DELAY_MS" #endif @@ -563,20 +570,15 @@ static void syv682x_handle_interrupt(int port) /* * Since ALERT_L is level-triggered, check the alert status and repeat - * until all interrupts are cleared. This will not spam indefinitely on - * OCP, but may on OVP, RVS, or TSD + * until all interrupts are cleared. The SYV682B and later have a 10ms + * deglitch on OC, so make sure not to check the status register again + * for at least 10ms to give it time to re-trigger. This will not spam + * indefinitely on OCP, but may on OVP, RVS, or TSD. */ - if (IS_ENABLED(CONFIG_USBC_PPC_DEDICATED_INT) && - ppc_get_alert_status(port)) { + if (status & SYV682X_STATUS_INT_MASK || + control4 & SYV682X_CONTROL_4_INT_MASK) { syv682x_interrupt_delayed(port, INTERRUPT_DELAY_MS); - } else { - read_reg(port, SYV682X_CONTROL_4_REG, &control4); - read_reg(port, SYV682X_STATUS_REG, &status); - if (status & SYV682X_STATUS_INT_MASK || - control4 & SYV682X_CONTROL_4_INT_MASK) { - syv682x_interrupt_delayed(port, INTERRUPT_DELAY_MS); - } } } diff --git a/driver/ppc/syv682x.h b/driver/ppc/syv682x.h index 0afa56190f..3ecbede18c 100644 --- a/driver/ppc/syv682x.h +++ b/driver/ppc/syv682x.h @@ -10,6 +10,9 @@ #include "driver/ppc/syv682x_public.h" +/* Source OC deglitch implemented in HW for SYV682B */ +#define SYV682X_HW_OC_DEGLITCH_MS 10 + /* SYV682x register addresses */ #define SYV682X_STATUS_REG 0x00 #define SYV682X_CONTROL_1_REG 0x01 |