summaryrefslogtreecommitdiff
path: root/driver/ppc
diff options
context:
space:
mode:
Diffstat (limited to 'driver/ppc')
-rw-r--r--driver/ppc/aoz1380.c162
-rw-r--r--driver/ppc/aoz1380.h44
-rw-r--r--driver/ppc/nx20p348x.c566
-rw-r--r--driver/ppc/nx20p348x.h132
-rw-r--r--driver/ppc/rt1718s.c237
-rw-r--r--driver/ppc/rt1718s.h17
-rw-r--r--driver/ppc/sn5s330.c752
-rw-r--r--driver/ppc/sn5s330.h161
-rw-r--r--driver/ppc/syv682x.c837
-rw-r--r--driver/ppc/syv682x.h112
10 files changed, 0 insertions, 3020 deletions
diff --git a/driver/ppc/aoz1380.c b/driver/ppc/aoz1380.c
deleted file mode 100644
index 4e2188c60d..0000000000
--- a/driver/ppc/aoz1380.c
+++ /dev/null
@@ -1,162 +0,0 @@
-/* Copyright 2019 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.
- */
-
-/*
- * AOZ1380 USB-C Power Path Controller
- *
- * This is a basic TCPM controlled PPC driver. It could easily be
- * renamed and repurposed to be generic, if there are other TCPM
- * controlled PPC chips that are similar to the AOZ1380
- */
-
-#include "atomic.h"
-#include "common.h"
-#include "console.h"
-#include "aoz1380.h"
-#include "hooks.h"
-#include "system.h"
-#include "tcpm/tcpm.h"
-#include "usb_pd.h"
-#include "usb_pd_tcpc.h"
-#include "usbc_ppc.h"
-
-#define CPRINTF(format, args...) cprintf(CC_USBPD, format, ## args)
-#define CPRINTS(format, args...) cprints(CC_USBPD, format, ## args)
-
-static uint32_t irq_pending; /* Bitmask of ports signaling an interrupt. */
-
-#define AOZ1380_FLAGS_SOURCE_ENABLED BIT(0)
-#define AOZ1380_FLAGS_SINK_ENABLED BIT(1)
-#define AOZ1380_FLAGS_INT_ON_DISCONNECT BIT(2)
-static uint32_t flags[CONFIG_USB_PD_PORT_MAX_COUNT];
-
-#define AOZ1380_SET_FLAG(port, flag) atomic_or(&flags[port], (flag))
-#define AOZ1380_CLR_FLAG(port, flag) atomic_clear_bits(&flags[port], (flag))
-
-static int aoz1380_init(int port)
-{
- flags[port] = 0;
-
- if (tcpm_get_snk_ctrl(port))
- AOZ1380_SET_FLAG(port, AOZ1380_FLAGS_SINK_ENABLED);
-
- if (tcpm_get_src_ctrl(port))
- AOZ1380_SET_FLAG(port, AOZ1380_FLAGS_SOURCE_ENABLED);
-
- return EC_SUCCESS;
-}
-
-static int aoz1380_vbus_sink_enable(int port, int enable)
-{
- int rv;
-
- rv = tcpm_set_snk_ctrl(port, enable);
- if (rv)
- return rv;
-
- /*
- * On enable, we want to indicate connection as a SINK.
- * On disable, clear SINK and that we have interrupted.
- */
- if (enable)
- AOZ1380_SET_FLAG(port, AOZ1380_FLAGS_SINK_ENABLED);
- else
- AOZ1380_CLR_FLAG(port, (AOZ1380_FLAGS_SINK_ENABLED |
- AOZ1380_FLAGS_INT_ON_DISCONNECT));
-
- return EC_SUCCESS;
-}
-
-static int aoz1380_vbus_source_enable(int port, int enable)
-{
- int rv;
-
- rv = tcpm_set_src_ctrl(port, enable);
- if (rv)
- return rv;
-
- /*
- * On enable, we want to indicate connection as a SOURCE.
- * On disable, clear SOURCE and that we have interrupted.
- */
- if (enable)
- AOZ1380_SET_FLAG(port, AOZ1380_FLAGS_SOURCE_ENABLED);
- else
- AOZ1380_CLR_FLAG(port, (AOZ1380_FLAGS_SOURCE_ENABLED |
- AOZ1380_FLAGS_INT_ON_DISCONNECT));
-
- return EC_SUCCESS;
-}
-
-static int aoz1380_is_sourcing_vbus(int port)
-{
- return flags[port] & AOZ1380_FLAGS_SOURCE_ENABLED;
-}
-
-static int aoz1380_set_vbus_source_current_limit(int port,
- enum tcpc_rp_value rp)
-{
- return board_aoz1380_set_vbus_source_current_limit(port, rp);
-}
-
-/*
- * AOZ1380 Interrupt Handler
- *
- * This device only has a single over current/temperature interrupt.
- * TODO(b/141939343) Determine how to clear the interrupt
- * TODO(b/142076004) Test this to verify we shut off vbus current
- * TODO(b/147359722) Verify correct fault functionality
- */
-static void aoz1380_handle_interrupt(int port)
-{
- /*
- * We can get a false positive on disconnect that we
- * had an over current/temperature event when we are no
- * longer connected as sink or source. Ignore it if
- * that is the case.
- */
- if (flags[port] != 0) {
- /*
- * This is a over current/temperature condition
- */
- ppc_prints("Vbus overcurrent/temperature", port);
- pd_handle_overcurrent(port);
- } else {
- /*
- * Just in case there is a condition that we will
- * continue an interrupt storm, track that we have
- * already been here once and will take the other
- * path if we do this again before setting the
- * sink/source as enabled or disabled again.
- */
- AOZ1380_SET_FLAG(port, AOZ1380_FLAGS_INT_ON_DISCONNECT);
- }
-}
-
-static void aoz1380_irq_deferred(void)
-{
- int i;
- uint32_t pending = atomic_clear(&irq_pending);
-
- for (i = 0; i < board_get_usb_pd_port_count(); i++)
- if (BIT(i) & pending)
- aoz1380_handle_interrupt(i);
-}
-DECLARE_DEFERRED(aoz1380_irq_deferred);
-
-void aoz1380_interrupt(int port)
-{
- atomic_or(&irq_pending, BIT(port));
- hook_call_deferred(&aoz1380_irq_deferred_data, 0);
-}
-
-const struct ppc_drv aoz1380_drv = {
- .init = &aoz1380_init,
- .is_sourcing_vbus = &aoz1380_is_sourcing_vbus,
- .vbus_sink_enable = &aoz1380_vbus_sink_enable,
- .vbus_source_enable = &aoz1380_vbus_source_enable,
- .set_vbus_source_current_limit =
- &aoz1380_set_vbus_source_current_limit,
-};
diff --git a/driver/ppc/aoz1380.h b/driver/ppc/aoz1380.h
deleted file mode 100644
index 94f2b804b7..0000000000
--- a/driver/ppc/aoz1380.h
+++ /dev/null
@@ -1,44 +0,0 @@
-/* Copyright 2019 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.
- */
-
-/*
- * AOZ1380 USB-C Power Path Controller
- *
- * This is a basic TCPM controlled PPC driver. It could easily be
- * renamed and repurposed to be generic, if there are other TCPM
- * controlled PPC chips that are similar to the AOZ1380
- */
-
-#ifndef __CROS_EC_AOZ1380_H
-#define __CROS_EC_AOZ1380_H
-
-#include "usb_pd_tcpm.h"
-
-struct ppc_drv;
-extern const struct ppc_drv aoz1380_drv;
-
-/**
- * AOZ1380 Set VBus Source Current Limit.
- *
- * Using this driver requires a board_aoz1380_set_vbus_source_limit
- * function due to the lack of programability of this device and
- * requirement for hardware specific code to handle setting this limit.
- *
- * @param port The Type-C port
- * @param rp The Type-C RP value
- * @return EC_SUCCESS for success, otherwise error
- */
-int board_aoz1380_set_vbus_source_current_limit(int port,
- enum tcpc_rp_value rp);
-
-
-/**
- * Interrupt Handler for the AOZ1380.
- *
- * @param port: The Type-C port which triggered the interrupt.
- */
-void aoz1380_interrupt(int port);
-
-#endif /* defined(__CROS_EC_AOZ1380_H) */
diff --git a/driver/ppc/nx20p348x.c b/driver/ppc/nx20p348x.c
deleted file mode 100644
index a5136bbf23..0000000000
--- a/driver/ppc/nx20p348x.c
+++ /dev/null
@@ -1,566 +0,0 @@
-/* Copyright 2018 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.
- */
-
-/* NX20P348x USB-C Power Path Controller */
-
-#include "common.h"
-#include "console.h"
-#include "nx20p348x.h"
-#include "gpio.h"
-#include "hooks.h"
-#include "i2c.h"
-#include "system.h"
-#include "tcpm/tcpm.h"
-#include "usb_charge.h"
-#include "usb_pd_tcpm.h"
-#include "usb_pd.h"
-#include "usbc_ppc.h"
-#include "util.h"
-
-#define CPRINTF(format, args...) cprintf(CC_USBPD, format, ## args)
-#define CPRINTS(format, args...) cprints(CC_USBPD, format, ## args)
-
-static uint32_t irq_pending; /* Bitmask of ports signaling an interrupt. */
-
-#define NX20P348X_DB_EXIT_FAIL_THRESHOLD 10
-static int db_exit_fail_count[CONFIG_USB_PD_PORT_MAX_COUNT];
-
-#define NX20P348X_FLAGS_SOURCE_ENABLED BIT(0)
-static uint8_t flags[CONFIG_USB_PD_PORT_MAX_COUNT];
-
-#if !defined(CONFIG_USBC_PPC_NX20P3481) && !defined(CONFIG_USBC_PPC_NX20P3483)
-#error "Either the NX20P3481 or NX20P3483 must be selected"
-#endif
-
-static int read_reg(uint8_t port, int reg, int *regval)
-{
- return i2c_read8(ppc_chips[port].i2c_port,
- ppc_chips[port].i2c_addr_flags,
- reg,
- regval);
-}
-
-static int write_reg(uint8_t port, int reg, int regval)
-{
- return i2c_write8(ppc_chips[port].i2c_port,
- ppc_chips[port].i2c_addr_flags,
- reg,
- regval);
-}
-
-static int nx20p348x_set_ovp_limit(int port)
-{
- int rv;
- int reg;
-
- /* Set VBUS over voltage threshold (OVLO) */
- rv = read_reg(port, NX20P348X_OVLO_THRESHOLD_REG, &reg);
- if (rv)
- return rv;
- /* OVLO threshold is 3 bit field */
- reg &= ~NX20P348X_OVLO_THRESHOLD_MASK;
- /* Set SNK OVP to 23.0 V */
- reg |= NX20P348X_OVLO_23_0;
- rv = write_reg(port, NX20P348X_OVLO_THRESHOLD_REG, reg);
- if (rv)
- return rv;
-
- return EC_SUCCESS;
-}
-
-static int nx20p348x_is_sourcing_vbus(int port)
-{
- return flags[port] & NX20P348X_FLAGS_SOURCE_ENABLED;
-}
-
-static int nx20p348x_set_vbus_source_current_limit(int port,
- enum tcpc_rp_value rp)
-{
- int regval;
- int status;
-
- status = read_reg(port, NX20P348X_5V_SRC_OCP_THRESHOLD_REG, &regval);
- if (status)
- return status;
-
- regval &= ~NX20P348X_ILIM_MASK;
-
- /* We need buffer room for all current values. */
- switch (rp) {
- case TYPEC_RP_3A0:
- regval |= NX20P348X_ILIM_3_200;
- break;
-
- case TYPEC_RP_1A5:
- regval |= NX20P348X_ILIM_1_600;
- break;
-
- case TYPEC_RP_USB:
- default:
- regval |= NX20P348X_ILIM_0_600;
- break;
- };
-
-
- return write_reg(port, NX20P348X_5V_SRC_OCP_THRESHOLD_REG, regval);
-}
-
-static int nx20p348x_discharge_vbus(int port, int enable)
-{
- int regval;
- int newval;
- int status;
-
- status = read_reg(port, NX20P348X_DEVICE_CONTROL_REG, &regval);
- if (status)
- return status;
-
- if (enable)
- newval = regval | NX20P348X_CTRL_VBUSDIS_EN;
- else
- newval = regval & ~NX20P348X_CTRL_VBUSDIS_EN;
-
- if (newval == regval)
- return EC_SUCCESS;
-
- status = write_reg(port, NX20P348X_DEVICE_CONTROL_REG, newval);
- if (status) {
- CPRINTS("Failed to %s VBUS discharge",
- enable ? "enable" : "disable");
- return status;
- }
-
- return EC_SUCCESS;
-}
-
-__maybe_unused static int nx20p3481_vbus_sink_enable(int port, int enable)
-{
- int status;
- int rv;
- int control = enable ? NX20P3481_SWITCH_CONTROL_HVSNK : 0;
-
- if (enable) {
- /*
- * VBUS Discharge must be off in sink mode.
- */
- rv = nx20p348x_discharge_vbus(port, 0);
- if (rv)
- return rv;
- }
-
- rv = write_reg(port, NX20P348X_SWITCH_CONTROL_REG, control);
- if (rv)
- return rv;
-
- /*
- * Read switch status register. The bit definitions for switch control
- * and switch status resister are identical, so the control value can be
- * compared against the status value. The control switch has a debounce
- * (15 msec) before the status will reflect the control command.
- */
- msleep(NX20P348X_SWITCH_STATUS_DEBOUNCE_MSEC);
- rv = read_reg(port, NX20P348X_SWITCH_STATUS_REG, &status);
- if (rv)
- return rv;
-
- return (status & NX20P348X_SWITCH_STATUS_HVSNK) == control ?
- EC_SUCCESS : EC_ERROR_UNKNOWN;
-}
-
-__maybe_unused static int nx20p3481_vbus_source_enable(int port, int enable)
-{
- int status;
- int rv;
- uint8_t previous_flags = flags[port];
- int control = enable ? NX20P3481_SWITCH_CONTROL_5VSRC : 0;
-
- rv = write_reg(port, NX20P348X_SWITCH_CONTROL_REG, control);
- if (rv)
- return rv;
-
- /* Cache the anticipated Vbus state */
- if (enable)
- flags[port] |= NX20P348X_FLAGS_SOURCE_ENABLED;
- else
- flags[port] &= ~NX20P348X_FLAGS_SOURCE_ENABLED;
-
- /*
- * Read switch status register. The bit definitions for switch control
- * and switch status resister are identical, so the control value can be
- * compared against the status value. The control switch has a debounce
- * (15 msec) before the status will reflect the control command.
- */
- msleep(NX20P348X_SWITCH_STATUS_DEBOUNCE_MSEC);
-
- if (IS_ENABLED(CONFIG_USBC_PPC_NX20P3481)) {
- rv = read_reg(port, NX20P348X_SWITCH_STATUS_REG, &status);
- if (rv) {
- flags[port] = previous_flags;
- return rv;
- }
- if ((status & NX20P348X_SWITCH_STATUS_MASK) != control) {
- flags[port] = previous_flags;
- return EC_ERROR_UNKNOWN;
- }
- }
-
- return EC_SUCCESS;
-}
-
-__maybe_unused static int nx20p3483_vbus_sink_enable(int port, int enable)
-{
- int rv;
-
- enable = !!enable;
-
- if (enable) {
- /*
- * VBUS Discharge must be off in sink mode.
- */
- rv = nx20p348x_discharge_vbus(port, 0);
- if (rv)
- return rv;
- }
-
- /*
- * We cannot use an EC GPIO for EN_SNK since an EC reset
- * will float the GPIO thus browning out the board (without
- * a battery).
- */
- rv = tcpm_set_snk_ctrl(port, enable);
- if (rv)
- return rv;
-
- for (int i = 0; i < NX20P348X_SWITCH_STATUS_DEBOUNCE_MSEC; ++i) {
- int ds;
- bool is_sink;
-
- rv = read_reg(port, NX20P348X_DEVICE_STATUS_REG, &ds);
- if (rv != EC_SUCCESS)
- return rv;
-
- is_sink = (ds & NX20P3483_DEVICE_MODE_MASK) ==
- NX20P3483_MODE_HV_SNK;
- if (enable == is_sink)
- return EC_SUCCESS;
-
- msleep(1);
- }
-
- return EC_ERROR_TIMEOUT;
-}
-
-__maybe_unused static int nx20p3483_vbus_source_enable(int port, int enable)
-{
- int rv;
-
- enable = !!enable;
-
- /*
- * For parity's sake, we should not use an EC GPIO for
- * EN_SRC since we cannot use it for EN_SNK (for brown
- * out reason listed above).
- */
- rv = tcpm_set_src_ctrl(port, enable);
- if (rv)
- return rv;
-
- /*
- * Wait up to NX20P348X_SWITCH_STATUS_DEBOUNCE_MSEC for the status
- * to reflect the control command.
- */
-
- for (int i = 0; i < NX20P348X_SWITCH_STATUS_DEBOUNCE_MSEC; ++i) {
- int s;
-
- rv = read_reg(port, NX20P348X_SWITCH_STATUS_REG, &s);
- if (rv != EC_SUCCESS)
- return rv;
-
- if (!!(s & (NX20P348X_SWITCH_STATUS_5VSRC |
- NX20P348X_SWITCH_STATUS_HVSRC)) == enable) {
- if (enable)
- flags[port] |= NX20P348X_FLAGS_SOURCE_ENABLED;
- else
- flags[port] &= ~NX20P348X_FLAGS_SOURCE_ENABLED;
- return EC_SUCCESS;
- }
- msleep(1);
- }
-
- return EC_ERROR_TIMEOUT;
-}
-
-static int nx20p348x_init(int port)
-{
- int reg;
- int mask;
- int mode;
- int rv;
- enum tcpc_rp_value initial_current_limit;
-
- /* Mask interrupts for interrupt 2 register */
- mask = ~NX20P348X_INT2_EN_ERR;
- rv = write_reg(port, NX20P348X_INTERRUPT2_MASK_REG, mask);
- if (rv)
- return rv;
-
- /* Mask interrupts for interrupt 1 register */
- mask = ~(NX20P348X_INT1_OC_5VSRC | NX20P348X_INT1_SC_5VSRC |
- NX20P348X_INT1_RCP_5VSRC | NX20P348X_INT1_DBEXIT_ERR);
- if (IS_ENABLED(CONFIG_USBC_PPC_NX20P3481)) {
- /* Unmask Fast Role Swap detect interrupt */
- mask &= ~NX20P3481_INT1_FRS_DET;
- }
- rv = write_reg(port, NX20P348X_INTERRUPT1_MASK_REG, mask);
- if (rv)
- return rv;
-
- /* Clear any pending interrupts by reading interrupt registers */
- read_reg(port, NX20P348X_INTERRUPT1_REG, &reg);
- read_reg(port, NX20P348X_INTERRUPT2_REG, &reg);
-
- /* Get device mode */
- rv = read_reg(port, NX20P348X_DEVICE_STATUS_REG, &mode);
- if (rv)
- return rv;
-
- if (IS_ENABLED(CONFIG_USBC_PPC_NX20P3481))
- mode &= NX20P3481_DEVICE_MODE_MASK;
- else if (IS_ENABLED(CONFIG_USBC_PPC_NX20P3483))
- mode &= NX20P3483_DEVICE_MODE_MASK;
-
- /* Check if dead battery mode is active. */
- if (mode == NX20P348X_MODE_DEAD_BATTERY) {
- /*
- * If in dead battery mode, must enable HV SNK mode prior to
- * exiting dead battery mode or VBUS path will get cut off and
- * system will lose power. Before DB mode is exited, the device
- * mode will not reflect the correct value and therefore the
- * return value isn't useful here.
- */
- nx20p348x_drv.vbus_sink_enable(port, 1);
-
- /* Exit dead battery mode. */
- rv = read_reg(port, NX20P348X_DEVICE_CONTROL_REG, &reg);
- if (rv)
- return rv;
- reg |= NX20P348X_CTRL_DB_EXIT;
- rv = write_reg(port, NX20P348X_DEVICE_CONTROL_REG, reg);
- if (rv)
- return rv;
- }
-
- /*
- * Set VBUS over voltage threshold (OVLO). Note that while the PPC is in
- * dead battery mode, OVLO is forced to 6.8V, so this setting must be
- * done after dead battery mode is exited.
- */
- nx20p348x_set_ovp_limit(port);
-
- /* Set the Vbus current limit after dead battery mode exit */
-#ifdef CONFIG_USB_PD_MAX_SINGLE_SOURCE_CURRENT
- initial_current_limit = CONFIG_USB_PD_MAX_SINGLE_SOURCE_CURRENT;
-#else
- initial_current_limit = TYPEC_RP_1A5;
-#endif
- nx20p348x_set_vbus_source_current_limit(port, initial_current_limit);
-
- /* Restore power-on reset value */
- rv = write_reg(port, NX20P348X_DEVICE_CONTROL_REG, 0);
- if (rv)
- return rv;
-
- return EC_SUCCESS;
-}
-
-static void nx20p348x_handle_interrupt(int port)
-{
- int reg;
- int control_reg;
-
- /*
- * Read interrupt 1 status register. Note, interrupt register is
- * automatically cleared by reading.
- */
- read_reg(port, NX20P348X_INTERRUPT1_REG, &reg);
-
- /* Check for DBEXIT error */
- if (reg & NX20P348X_INT1_DBEXIT_ERR) {
- int mask_reg;
-
- /*
- * This failure is not expected. If for some reason, this
- * keeps happening, then log an error and mask the interrupt to
- * prevent interrupt floods.
- */
- if (++db_exit_fail_count[port] >=
- NX20P348X_DB_EXIT_FAIL_THRESHOLD) {
- ppc_prints("failed to exit DB mode", port);
- if (read_reg(port, NX20P348X_INTERRUPT1_MASK_REG,
- &mask_reg)) {
- mask_reg |= NX20P348X_INT1_DBEXIT_ERR;
- write_reg(port, NX20P348X_INTERRUPT1_MASK_REG,
- mask_reg);
- }
- }
- read_reg(port, NX20P348X_DEVICE_CONTROL_REG, &control_reg);
- control_reg |= NX20P348X_CTRL_DB_EXIT;
- write_reg(port, NX20P348X_DEVICE_CONTROL_REG, control_reg);
- /*
- * If DB exit mode failed, then the OVP limit setting done in
- * the init routine will not be successful. Set the OVP limit
- * again here.
- */
- nx20p348x_set_ovp_limit(port);
- }
-
- /* Check for 5V OC interrupt */
- if (reg & NX20P348X_INT1_OC_5VSRC) {
- ppc_prints("detected Vbus overcurrent!", port);
- pd_handle_overcurrent(port);
- }
-
- /* Check for Vbus reverse current protection */
- if (reg & NX20P348X_INT1_RCP_5VSRC)
- ppc_prints("detected Vbus reverse current!", port);
-
- /* Check for Vbus short protection */
- if (reg & NX20P348X_INT1_SC_5VSRC)
- ppc_prints("Vbus short detected!", port);
-
- /* Check for FRS detection */
- if (IS_ENABLED(CONFIG_USBC_PPC_NX20P3481) &&
- (reg & NX20P3481_INT1_FRS_DET)) {
- /*
- * TODO(b/113069469): Need to check for CC status and verifiy
- * that a sink is attached to continue with FRS. If a sink is
- * not attached, then this FRS detect is a false detect which is
- * triggered when removing an external charger. If FRS was
- * detected by the PPC, then it has automatically enabled the
- * 5V SRC mode and this must be undone for a proper detach.
- */
- /* Check CC status */
-
- /*
- * False detect, disable SRC mode which was enabled by
- * NX20P3481.
- */
- ppc_prints("FRS false detect, disabling SRC mode!", port);
- nx20p3481_vbus_source_enable(port, 0);
- }
-
- /*
- * Read interrupt 2 status register. Note, interrupt register is
- * automatically cleared by reading.
- */
- /*
- * TODO (b/75272421): Not sure if any of these interrupts
- * will be used. Might want to use EN_ERR which tracks when both
- * SNK_EN and SRC_EN are set. However, since for the Analogix TCPC
- * these values aren't controlled by the EC directly, not sure what
- * action if any can be taken.
- */
- read_reg(port, NX20P348X_INTERRUPT2_REG, &reg);
-}
-
-static void nx20p348x_irq_deferred(void)
-{
- int i;
- uint32_t pending = atomic_clear(&irq_pending);
-
- for (i = 0; i < board_get_usb_pd_port_count(); i++)
- if (BIT(i) & pending)
- nx20p348x_handle_interrupt(i);
-}
-DECLARE_DEFERRED(nx20p348x_irq_deferred);
-
-void nx20p348x_interrupt(int port)
-{
- atomic_or(&irq_pending, BIT(port));
- hook_call_deferred(&nx20p348x_irq_deferred_data, 0);
-}
-
-#ifdef CONFIG_CMD_PPC_DUMP
-static int nx20p348x_dump(int port)
-{
- int reg_addr;
- int reg;
- int rv;
-
- ccprintf("Port %d NX20P348X registers\n", port);
- for (reg_addr = NX20P348X_DEVICE_ID_REG; reg_addr <=
- NX20P348X_DEVICE_CONTROL_REG; reg_addr++) {
- rv = read_reg(port, reg_addr, &reg);
- if (rv) {
- ccprintf("nx20p: Failed to read register 0x%x\n",
- reg_addr);
- return rv;
- }
- ccprintf("[0x%02x]: 0x%02x\n", reg_addr, reg);
-
- /* Flush every call otherwise buffer may get full */
- cflush();
- }
-
- return EC_SUCCESS;
-}
-#endif /* defined(CONFIG_CMD_PPC_DUMP) */
-
-/*
- * TODO (b/112697473): The NX20P348x PPCs do not support vbus detection or vconn
- * generation. However, if a different PPC does support these features and needs
- * these config options, then these functions do need to exist. The
- * configuration for what each PPC supports should be converted to bits within
- * a flags variable that is part of the ppc_config_t struct.
- */
-#ifdef CONFIG_USB_PD_VBUS_DETECT_PPC
-static int nx20p348x_is_vbus_present(int port)
-{
- return EC_ERROR_UNIMPLEMENTED;
-}
-#endif /* defined(CONFIG_USB_PD_VBUS_DETECT_PPC) */
-
-#ifdef CONFIG_USBC_PPC_POLARITY
-static int nx20p348x_set_polarity(int port, int polarity)
-{
- return EC_ERROR_UNIMPLEMENTED;
-}
-#endif
-
-#ifdef CONFIG_USBC_PPC_VCONN
-static int nx20p348x_set_vconn(int port, int enable)
-{
- return EC_ERROR_UNIMPLEMENTED;
-}
-#endif
-
-const struct ppc_drv nx20p348x_drv = {
- .init = &nx20p348x_init,
- .is_sourcing_vbus = &nx20p348x_is_sourcing_vbus,
-#ifdef CONFIG_USBC_PPC_NX20P3481
- .vbus_sink_enable = &nx20p3481_vbus_sink_enable,
- .vbus_source_enable = &nx20p3481_vbus_source_enable,
-#endif /* CONFIG_USBC_PPC_NX20P3481 */
-#ifdef CONFIG_USBC_PPC_NX20P3483
- .vbus_sink_enable = &nx20p3483_vbus_sink_enable,
- .vbus_source_enable = &nx20p3483_vbus_source_enable,
-#endif /* CONFIG_USBC_PPC_NX20P3483 */
-#ifdef CONFIG_CMD_PPC_DUMP
- .reg_dump = &nx20p348x_dump,
-#endif /* defined(CONFIG_CMD_PPC_DUMP) */
- .set_vbus_source_current_limit =
- &nx20p348x_set_vbus_source_current_limit,
- .discharge_vbus = &nx20p348x_discharge_vbus,
-#ifdef CONFIG_USB_PD_VBUS_DETECT_PPC
- .is_vbus_present = &nx20p348x_is_vbus_present,
-#endif /* defined(CONFIG_USB_PD_VBUS_DETECT_PPC) */
-#ifdef CONFIG_USBC_PPC_POLARITY
- .set_polarity = &nx20p348x_set_polarity,
-#endif /* defined(CONFIG_USBC_PPC_POLARITY) */
-#ifdef CONFIG_USBC_PPC_VCONN
- .set_vconn = &nx20p348x_set_vconn,
-#endif /* defined(CONFIG_USBC_PPC_VCONN) */
-};
diff --git a/driver/ppc/nx20p348x.h b/driver/ppc/nx20p348x.h
deleted file mode 100644
index 54c6dc40b5..0000000000
--- a/driver/ppc/nx20p348x.h
+++ /dev/null
@@ -1,132 +0,0 @@
-/* Copyright 2018 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.
- */
-
-/* NX20P348x Type-C Power Path Controller */
-
-#ifndef __CROS_EC_NX20P348X_H
-#define __CROS_EC_NX20P348X_H
-
-#define NX20P3483_ADDR0_FLAGS 0x70
-#define NX20P3483_ADDR1_FLAGS 0x71
-#define NX20P3483_ADDR2_FLAGS 0x72
-#define NX20P3483_ADDR3_FLAGS 0x73
-
-#define NX20P3481_ADDR0_FLAGS 0x74
-#define NX20P3481_ADDR1_FLAGS 0x75
-#define NX20P3481_ADDR2_FLAGS 0x76
-#define NX20P3481_ADDR3_FLAGS 0x77
-
-/*
- * This PPC hard-codes the over voltage protect of Vbus at 6.8V in dead-battery
- * mode. If we ever are every going to drop the PD rail, we need to first ensure
- * that Vbus is negotiated to below 6.8V otherwise we can lock out Vbus.
- */
-#define NX20P348X_SAFE_RESET_VBUS_MV 5000
-
-/* NX20P348x register addresses */
-#define NX20P348X_DEVICE_ID_REG 0x00
-#define NX20P348X_DEVICE_STATUS_REG 0x01
-#define NX20P348X_SWITCH_CONTROL_REG 0x02
-#define NX20P348X_SWITCH_STATUS_REG 0x03
-#define NX20P348X_INTERRUPT1_REG 0x04
-#define NX20P348X_INTERRUPT2_REG 0x05
-#define NX20P348X_INTERRUPT1_MASK_REG 0x06
-#define NX20P348X_INTERRUPT2_MASK_REG 0x07
-#define NX20P348X_OVLO_THRESHOLD_REG 0x08
-#define NX20P348X_HV_SRC_OCP_THRESHOLD_REG 0x09
-#define NX20P348X_5V_SRC_OCP_THRESHOLD_REG 0x0A
-#define NX20P348X_DEVICE_CONTROL_REG 0x0B
-
-/* Device Control Register (0x0B) */
-#define NX20P3483_CTRL_FRS_AT BIT(3)
-#define NX20P348X_CTRL_DB_EXIT BIT(2)
-#define NX20P348X_CTRL_VBUSDIS_EN BIT(1)
-#define NX20P348X_CTRL_LDO_SD BIT(0)
-
-/* Device Status Modes (0x01) */
-#define NX20P3481_DEVICE_MODE_MASK 0x3
-#define NX20P3483_DEVICE_MODE_MASK 0x7
-#define NX20P348X_MODE_DEAD_BATTERY 0
-/* After dead battery, mode values are different between 3481 and 3483 */
-#define NX20P3481_MODE_NORMAL 1
-#define NX20P3481_MODE_FRS 2
-#define NX20P3481_MODE_STANDBY 3
-
-#define NX20P3483_MODE_HV_SNK 1
-#define NX20P3483_MODE_5V_SRC 2
-#define NX20P3483_MODE_HV_SRC 3
-#define NX20P3483_MODE_STANDBY 4
-
-/* Switch Control Register (0x02) */
-#define NX20P3481_SWITCH_CONTROL_5VSRC BIT(2)
-#define NX20P3481_SWITCH_CONTROL_HVSRC BIT(1)
-#define NX20P3481_SWITCH_CONTROL_HVSNK BIT(0)
-
-/* Switch Status Register (0x03) */
-#define NX20P348X_SWITCH_STATUS_5VSRC BIT(2)
-#define NX20P348X_SWITCH_STATUS_HVSRC BIT(1)
-#define NX20P348X_SWITCH_STATUS_HVSNK BIT(0)
-#define NX20P348X_SWITCH_STATUS_DEBOUNCE_MSEC 25
-#define NX20P348X_SWITCH_STATUS_MASK 0x7
-
-/* Internal 5V VBUS Switch Current Limit Settings (min) */
-#define NX20P348X_ILIM_MASK 0xF
-#define NX20P348X_ILIM_0_400 0
-#define NX20P348X_ILIM_0_600 1
-#define NX20P348X_ILIM_0_800 2
-#define NX20P348X_ILIM_1_000 3
-#define NX20P348X_ILIM_1_200 4
-#define NX20P348X_ILIM_1_400 5
-#define NX20P348X_ILIM_1_600 6
-#define NX20P348X_ILIM_1_800 7
-#define NX20P348X_ILIM_2_000 8
-#define NX20P348X_ILIM_2_200 9
-#define NX20P348X_ILIM_2_400 10
-#define NX20P348X_ILIM_2_600 11
-#define NX20P348X_ILIM_2_800 12
-#define NX20P348X_ILIM_3_000 13
-#define NX20P348X_ILIM_3_200 14
-#define NX20P348X_ILIM_3_400 15
-
-/* HV VBUS over voltage threshold settings V_mV*/
-#define NX20P348X_OVLO_THRESHOLD_MASK 0x7
-#define NX20P348X_OVLO_06_0 0
-#define NX20P348X_OVLO_06_8 1
-#define NX20P348X_OVLO_10_0 2
-#define NX20P348X_OVLO_11_5 3
-#define NX20P348X_OVLO_14_0 4
-#define NX20P348X_OVLO_17_0 5
-#define NX20P348X_OVLO_23_0 6
-
-/* Interrupt 1 Register Bits (0x04) */
-#define NX20P348X_INT1_DBEXIT_ERR BIT(7)
-#define NX20P3481_INT1_FRS_DET BIT(6)
-#define NX20P348X_INT1_OV_5VSRC BIT(4)
-#define NX20P348X_INT1_RCP_5VSRC BIT(3)
-#define NX20P348X_INT1_SC_5VSRC BIT(2)
-#define NX20P348X_INT1_OC_5VSRC BIT(1)
-#define NX20P348X_INT1_OTP BIT(0)
-
-/* Interrupt 2 Register Bits (0x05) */
-#define NX20P348X_INT2_EN_ERR BIT(7)
-#define NX20P348X_INT2_RCP_HVSNK BIT(6)
-#define NX20P348X_INT2_SC_HVSNK BIT(5)
-#define NX20P348X_INT2_OV_HVSNK BIT(4)
-#define NX20P348X_INT2_RCP_HVSRC BIT(3)
-#define NX20P348X_INT2_SC_HVSRC BIT(2)
-#define NX20P348X_INT2_OC_HVSRC BIT(1)
-#define NX20P348X_INT2_OV_HVSRC BIT(0)
-
-struct ppc_drv;
-extern const struct ppc_drv nx20p348x_drv;
-
-/**
- * Interrupt Handler for the NX20P348x.
- *
- * @param port: The Type-C port which triggered the interrupt.
- */
-void nx20p348x_interrupt(int port);
-
-#endif /* defined(__CROS_EC_NX20P348X_H) */
diff --git a/driver/ppc/rt1718s.c b/driver/ppc/rt1718s.c
deleted file mode 100644
index 96cb789cd0..0000000000
--- a/driver/ppc/rt1718s.c
+++ /dev/null
@@ -1,237 +0,0 @@
-/* Copyright 2021 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.
- */
-
-/* Richtek RT1718S USB-C Power Path Controller */
-#include "atomic.h"
-#include "common.h"
-#include "config.h"
-#include "console.h"
-#include "driver/ppc/rt1718s.h"
-#include "driver/tcpm/tcpci.h"
-#include "usbc_ppc.h"
-#include "util.h"
-
-
-#define RT1718S_FLAGS_SOURCE_ENABLED BIT(0)
-static atomic_t flags[CONFIG_USB_PD_PORT_MAX_COUNT];
-
-#define CPRINTS(format, args...) cprints(CC_USBPD, format, ## args)
-#define CPRINTF(format, args...) cprintf(CC_USBCHARGE, format, ## args)
-
-static int read_reg(uint8_t port, int reg, int *val)
-{
- if (reg > 0xFF) {
- return i2c_read_offset16(
- ppc_chips[port].i2c_port,
- ppc_chips[port].i2c_addr_flags,
- reg, val, 1);
- } else {
- return i2c_read8(
- ppc_chips[port].i2c_port,
- ppc_chips[port].i2c_addr_flags,
- reg, val);
- }
-}
-
-static int write_reg(uint8_t port, int reg, int val)
-{
- if (reg > 0xFF) {
- return i2c_write_offset16(
- ppc_chips[port].i2c_port,
- ppc_chips[port].i2c_addr_flags,
- reg, val, 1);
- } else {
- return i2c_write8(
- ppc_chips[port].i2c_port,
- ppc_chips[port].i2c_addr_flags,
- reg, val);
- }
-}
-
-static int update_bits(int port, int reg, int mask, int val)
-{
- int reg_val;
-
- if (mask == 0xFF)
- return write_reg(port, reg, val);
-
- RETURN_ERROR(read_reg(port, reg, &reg_val));
-
- reg_val &= (~mask);
- reg_val |= (mask & val);
- return write_reg(port, reg, reg_val);
-}
-
-static int rt1718s_is_sourcing_vbus(int port)
-{
- return (flags[port] & RT1718S_FLAGS_SOURCE_ENABLED);
-}
-
-static int rt1718s_vbus_source_enable(int port, int enable)
-{
- atomic_t prev_flag;
-
- if (enable)
- prev_flag = atomic_or(&flags[port],
- RT1718S_FLAGS_SOURCE_ENABLED);
- else
- prev_flag = atomic_clear_bits(&flags[port],
- RT1718S_FLAGS_SOURCE_ENABLED);
-
- /* Return if status doesn't change */
- if (!!(prev_flag & RT1718S_FLAGS_SOURCE_ENABLED) == !!enable)
- return EC_SUCCESS;
-
- RETURN_ERROR(tcpm_set_src_ctrl(port, enable));
-
-#if defined(CONFIG_USB_CHARGER) && defined(CONFIG_USB_PD_VBUS_DETECT_PPC)
- /*
- * Since the VBUS state could be changing here, need to wake the
- * USB_CHG_N task so that BC 1.2 detection will be triggered.
- */
- usb_charger_vbus_change(port, enable);
-#endif
-
- return EC_SUCCESS;
-}
-
-static int rt1718s_vbus_sink_enable(int port, int enable)
-{
- return tcpm_set_snk_ctrl(port, enable);
-}
-
-static int rt1718s_discharge_vbus(int port, int enable)
-{
- return update_bits(port,
- TCPC_REG_POWER_CTRL,
- TCPC_REG_POWER_CTRL_FORCE_DISCHARGE,
- enable ? 0xFF : 0x00);
-}
-
-#ifdef CONFIG_CMD_PPC_DUMP
-static int rt1718s_dump(int port)
-{
- for (int i = 0; i <= 0xEF; i++) {
- int val = 0;
- int rt = read_reg(port, i, &val);
-
- if (i % 16 == 0)
- CPRINTF("%02X: ", i);
- if (rt)
- CPRINTF("-- ");
- else
- CPRINTF("%02X ", val);
- if (i % 16 == 15)
- CPRINTF("\n");
- }
- for (int i = 0xF200; i <= 0xF2CF; i++) {
- int val = 0;
- int rt = read_reg(port, i, &val);
-
- if (i % 16 == 0)
- CPRINTF("%04X: ", i);
- if (rt)
- CPRINTF("-- ");
- else
- CPRINTF("%02X ", val);
- if (i % 16 == 15)
- CPRINTF("\n");
- }
-
- return EC_SUCCESS;
-}
-#endif /* defined(CONFIG_CMD_PPC_DUMP) */
-
-#ifdef CONFIG_USB_PD_VBUS_DETECT_PPC
-static int rt1718s_is_vbus_present(int port)
-{
- __maybe_unused static atomic_t vbus_prev[CONFIG_USB_PD_PORT_MAX_COUNT];
- int status, vbus;
-
- if (read_reg(port, TCPC_REG_POWER_STATUS, &status))
- return 0;
-
- vbus = !!(status & TCPC_REG_POWER_STATUS_VBUS_PRES);
-
-#ifdef CONFIG_USB_CHARGER
- if (!!(vbus_prev[port] != vbus))
- usb_charger_vbus_change(port, vbus);
-
- if (vbus)
- atomic_or(&vbus_prev[port], 1);
- else
- atomic_clear(&vbus_prev[port]);
-#endif
-
- return vbus;
-}
-#endif
-
-static int rt1718s_init(int port)
-{
- atomic_clear(&flags[port]);
-
- if (IS_ENABLED(CONFIG_USB_PD_FRS_PPC))
- /* Set Rx frs unmasked */
- RETURN_ERROR(update_bits(port, RT1718S_RT_MASK1,
- RT1718S_RT_MASK1_M_RX_FRS,
- 0xFF));
-
- return EC_SUCCESS;
-}
-
-#ifdef CONFIG_USBC_PPC_POLARITY
-static int rt1718s_set_polarity(int port, int polarity)
-{
- return tcpci_tcpm_set_polarity(port, polarity);
-}
-#endif
-
-#ifdef CONFIG_USB_PD_FRS_PPC
-static int rt1718s_set_frs_enable(int port, int enable)
-{
- /*
- * Use write instead of update to save 2 i2c read.
- * Assume other bits are at their reset value.
- */
- int frs_ctrl2 = 0x10, vbus_ctrl_en = 0x3F;
-
- if (enable) {
- frs_ctrl2 |= RT1718S_FRS_CTRL2_RX_FRS_EN;
- frs_ctrl2 |= RT1718S_FRS_CTRL2_VBUS_FRS_EN;
-
- vbus_ctrl_en |= RT1718S_VBUS_CTRL_EN_GPIO2_VBUS_PATH_EN;
- vbus_ctrl_en |= RT1718S_VBUS_CTRL_EN_GPIO1_VBUS_PATH_EN;
- }
-
- RETURN_ERROR(write_reg(port, RT1718S_FRS_CTRL2, frs_ctrl2));
- RETURN_ERROR(write_reg(port, RT1718S_VBUS_CTRL_EN, vbus_ctrl_en));
- return EC_SUCCESS;
-}
-#endif
-
-const struct ppc_drv rt1718s_ppc_drv = {
- .init = &rt1718s_init,
- .is_sourcing_vbus = &rt1718s_is_sourcing_vbus,
- .vbus_sink_enable = &rt1718s_vbus_sink_enable,
- .vbus_source_enable = &rt1718s_vbus_source_enable,
-#ifdef CONFIG_CMD_PPC_DUMP
- .reg_dump = &rt1718s_dump,
-#endif /* defined(CONFIG_CMD_PPC_DUMP) */
-
-#ifdef CONFIG_USB_PD_VBUS_DETECT_PPC
- .is_vbus_present = &rt1718s_is_vbus_present,
-#endif /* defined(CONFIG_USB_PD_VBUS_DETECT_PPC) */
- .discharge_vbus = &rt1718s_discharge_vbus,
-#ifdef CONFIG_USBC_PPC_POLARITY
- .set_polarity = &rt1718s_set_polarity,
-#endif
-#ifdef CONFIG_USBC_PPC_VCONN
- .set_vconn = &tcpci_tcpm_set_vconn,
-#endif
-#ifdef CONFIG_USB_PD_FRS_PPC
- .set_frs_enable = rt1718s_set_frs_enable,
-#endif
-};
diff --git a/driver/ppc/rt1718s.h b/driver/ppc/rt1718s.h
deleted file mode 100644
index f692bf3dd4..0000000000
--- a/driver/ppc/rt1718s.h
+++ /dev/null
@@ -1,17 +0,0 @@
-/* Copyright 2021 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.
- */
-
-/* Richtek RT1718S Type-C Power Path Controller */
-
-#ifndef __CROS_EC_PPC_RT1718S_H
-#define __CROS_EC_PPC_RT1718S_H
-
-#include "driver/tcpm/rt1718s.h"
-#include "usbc_ppc.h"
-
-extern const struct ppc_drv rt1718s_ppc_drv;
-
-#endif /* defined(__CROS_EC_PPC_RT1718S_H) */
-
diff --git a/driver/ppc/sn5s330.c b/driver/ppc/sn5s330.c
deleted file mode 100644
index 4abf85cf50..0000000000
--- a/driver/ppc/sn5s330.c
+++ /dev/null
@@ -1,752 +0,0 @@
-/* Copyright 2017 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.
- */
-
-/* TI SN5S330 USB-C Power Path Controller */
-
-/*
- * PP1 : Sourcing power path.
- * PP2 : Sinking power path.
- */
-
-#include "common.h"
-#include "console.h"
-#include "sn5s330.h"
-#include "hooks.h"
-#include "i2c.h"
-#include "system.h"
-#include "timer.h"
-#include "usb_charge.h"
-#include "usb_pd_tcpm.h"
-#include "usb_pd.h"
-#include "usbc_ppc.h"
-#include "util.h"
-
-#define CPRINTF(format, args...) cprintf(CC_USBPD, format, ## args)
-#define CPRINTS(format, args...) cprints(CC_USBPD, format, ## args)
-
-static uint32_t irq_pending; /* Bitmask of ports signaling an interrupt. */
-static int source_enabled[CONFIG_USB_PD_PORT_MAX_COUNT];
-
-static int read_reg(uint8_t port, int reg, int *regval)
-{
- return i2c_read8(ppc_chips[port].i2c_port,
- ppc_chips[port].i2c_addr_flags,
- reg,
- regval);
-}
-
-static int write_reg(uint8_t port, int reg, int regval)
-{
- return i2c_write8(ppc_chips[port].i2c_port,
- ppc_chips[port].i2c_addr_flags,
- reg,
- regval);
-}
-
-static int set_flags(const int port, const int addr, const int flags_to_set)
-{
- int val, rv;
-
- rv = read_reg(port, addr, &val);
- if (rv)
- return rv;
-
- val |= flags_to_set;
-
- return write_reg(port, addr, val);
-}
-
-
-static int clr_flags(const int port, const int addr, const int flags_to_clear)
-{
- int val, rv;
-
- rv = read_reg(port, addr, &val);
- if (rv)
- return rv;
-
- val &= ~flags_to_clear;
-
- return write_reg(port, addr, val);
-}
-
-#ifdef CONFIG_CMD_PPC_DUMP
-static int sn5s330_dump(int port)
-{
- int i;
- int data;
- const int i2c_port = ppc_chips[port].i2c_port;
- const uint16_t i2c_addr_flags = ppc_chips[port].i2c_addr_flags;
-
- /* Flush after every set otherwise console buffer may get full. */
-
- for (i = SN5S330_FUNC_SET1; i <= SN5S330_FUNC_SET12; i++) {
- i2c_read8(i2c_port, i2c_addr_flags, i, &data);
- ccprintf("FUNC_SET%d [%02Xh] = 0x%02x\n",
- i - SN5S330_FUNC_SET1 + 1,
- i,
- data);
- }
-
- cflush();
-
- for (i = SN5S330_INT_STATUS_REG1; i <= SN5S330_INT_STATUS_REG4; i++) {
- i2c_read8(i2c_port, i2c_addr_flags, i, &data);
- ccprintf("INT_STATUS_REG%d [%02Xh] = 0x%02x\n",
- i - SN5S330_INT_STATUS_REG1 + 1,
- i,
- data);
- }
-
- cflush();
-
- for (i = SN5S330_INT_TRIP_RISE_REG1; i <= SN5S330_INT_TRIP_RISE_REG3;
- i++) {
- i2c_read8(i2c_port, i2c_addr_flags, i, &data);
- ccprintf("INT_TRIP_RISE_REG%d [%02Xh] = 0x%02x\n",
- i - SN5S330_INT_TRIP_RISE_REG1 + 1,
- i,
- data);
- }
-
- cflush();
-
- for (i = SN5S330_INT_TRIP_FALL_REG1; i <= SN5S330_INT_TRIP_FALL_REG3;
- i++) {
- i2c_read8(i2c_port, i2c_addr_flags, i, &data);
- ccprintf("INT_TRIP_FALL_REG%d [%02Xh] = 0x%02x\n",
- i - SN5S330_INT_TRIP_FALL_REG1 + 1,
- i,
- data);
- }
-
- cflush();
-
- for (i = SN5S330_INT_MASK_RISE_REG1; i <= SN5S330_INT_MASK_RISE_REG3;
- i++) {
- i2c_read8(i2c_port, i2c_addr_flags, i, &data);
- ccprintf("INT_MASK_RISE_REG%d [%02Xh] = 0x%02x\n",
- i - SN5S330_INT_MASK_RISE_REG1 + 1,
- i,
- data);
- }
-
- cflush();
-
- for (i = SN5S330_INT_MASK_FALL_REG1; i <= SN5S330_INT_MASK_FALL_REG3;
- i++) {
- i2c_read8(i2c_port, i2c_addr_flags, i, &data);
- ccprintf("INT_MASK_FALL_REG%d [%02Xh] = 0x%02x\n",
- i - SN5S330_INT_MASK_FALL_REG1 + 1,
- i,
- data);
- }
-
- cflush();
-
- return EC_SUCCESS;
-}
-#endif /* defined(CONFIG_CMD_PPC_DUMP) */
-
-static int sn5s330_pp_fet_enable(uint8_t port, enum sn5s330_pp_idx pp,
- int enable)
-{
- int status;
- int pp_bit;
-
- if (pp == SN5S330_PP1)
- pp_bit = SN5S330_PP1_EN;
- else if (pp == SN5S330_PP2)
- pp_bit = SN5S330_PP2_EN;
- else
- return EC_ERROR_INVAL;
-
- status = enable ? set_flags(port, SN5S330_FUNC_SET3, pp_bit)
- : clr_flags(port, SN5S330_FUNC_SET3, pp_bit);
-
- if (status) {
- ppc_prints("Failed to set FUNC_SET3!", port);
- return status;
- }
-
- if (pp == SN5S330_PP1)
- source_enabled[port] = enable;
-
- return EC_SUCCESS;
-}
-
-static int sn5s330_init(int port)
-{
- int regval;
- int status;
- int retries;
- int reg;
- const int i2c_port = ppc_chips[port].i2c_port;
- const uint16_t i2c_addr_flags = ppc_chips[port].i2c_addr_flags;
-
-#ifdef CONFIG_USB_PD_MAX_SINGLE_SOURCE_CURRENT
- /* Set the sourcing current limit value. */
- switch (CONFIG_USB_PD_MAX_SINGLE_SOURCE_CURRENT) {
- case TYPEC_RP_3A0:
- /* Set current limit to ~3A. */
- regval = SN5S330_ILIM_3_06;
- break;
-
- case TYPEC_RP_1A5:
- default:
- /* Set current limit to ~1.5A. */
- regval = SN5S330_ILIM_1_62;
- break;
- }
-#else /* !defined(CONFIG_USB_PD_MAX_SINGLE_SOURCE_CURRENT) */
- /* Default SRC current limit to ~1.5A. */
- regval = SN5S330_ILIM_1_62;
-#endif /* defined(CONFIG_USB_PD_MAX_SINGLE_SOURCE_CURRENT) */
-
- /*
- * It seems that sometimes setting the FUNC_SET1 register fails
- * initially. Therefore, we'll retry a couple of times.
- */
- retries = 0;
- do {
- status = i2c_write8(i2c_port, i2c_addr_flags,
- SN5S330_FUNC_SET1, regval);
- if (status) {
- ppc_prints("Failed to set FUNC_SET1! Retrying..",
- port);
- retries++;
- msleep(1);
- } else {
- break;
- }
- } while (retries < 10);
-
- /* Set Vbus OVP threshold to ~22.325V. */
- regval = 0x37;
- status = i2c_write8(i2c_port, i2c_addr_flags,
- SN5S330_FUNC_SET5, regval);
- if (status) {
- ppc_prints("Failed to set FUNC_SET5!", port);
- return status;
- }
-
- /* Set Vbus UVP threshold to ~2.75V. */
- status = i2c_read8(i2c_port, i2c_addr_flags,
- SN5S330_FUNC_SET6, &regval);
- if (status) {
- ppc_prints("Failed to read FUNC_SET6!", port);
- return status;
- }
- regval &= ~0x3F;
- regval |= 1;
- status = i2c_write8(i2c_port, i2c_addr_flags,
- SN5S330_FUNC_SET6, regval);
- if (status) {
- ppc_prints("Failed to write FUNC_SET6!", port);
- return status;
- }
-
- /* Enable SBU Fets and set PP2 current limit to ~3A. */
- regval = SN5S330_SBU_EN | 0x8;
- status = i2c_write8(i2c_port, i2c_addr_flags,
- SN5S330_FUNC_SET2, regval);
- if (status) {
- ppc_prints("Failed to set FUNC_SET2!", port);
- return status;
- }
-
- /*
- * Indicate we are using PP2 configuration 2 and enable OVP comparator
- * for CC lines.
- *
- * Also, turn off under-voltage protection for incoming Vbus as it would
- * prevent us from enabling SNK path before we hibernate the ec. We
- * need to enable the SNK path so USB power will assert ACOK and wake
- * the EC up went inserting USB power. We always turn off under-voltage
- * protection because the battery charger will boost the voltage up
- * to the needed battery voltage either way (and it will have its own
- * low voltage protection).
- */
- regval = SN5S330_OVP_EN_CC | SN5S330_PP2_CONFIG | SN5S330_CONFIG_UVP;
- status = i2c_write8(i2c_port, i2c_addr_flags,
- SN5S330_FUNC_SET9, regval);
- if (status) {
- ppc_prints("Failed to set FUNC_SET9!", port);
- return status;
- }
-
- /*
- * Set analog current limit delay to 200 us for PP1,
- * set 1000 us for PP2 for compatibility.
- */
- regval = (PPX_ILIM_DEGLITCH_0_US_200 << 3) |
- PPX_ILIM_DEGLITCH_0_US_1000;
- status = i2c_write8(i2c_port, i2c_addr_flags, SN5S330_FUNC_SET11,
- regval);
- if (status) {
- ppc_prints("Failed to set FUNC_SET11", port);
- return status;
- }
-
-#ifdef CONFIG_USBC_PPC_VCONN
- /*
- * Set the deglitch timeout on the Vconn current limit to 640us. This
- * improves compatibility with some USB C -> HDMI devices versus the
- * reset default (20 us).
- */
- regval = 0;
- status = i2c_read8(i2c_port, i2c_addr_flags,
- SN5S330_FUNC_SET8, &regval);
- if (status) {
- ppc_prints("Failed to read FUNC_SET8!", port);
- return status;
- }
- regval &= ~SN5S330_VCONN_DEGLITCH_MASK;
- regval |= SN5S330_VCONN_DEGLITCH_640_US;
- status = i2c_write8(i2c_port, i2c_addr_flags,
- SN5S330_FUNC_SET8, regval);
- if (status) {
- ppc_prints("Failed to set FUNC_SET8!", port);
- return status;
- }
-#endif /* CONFIG_USBC_PPC_VCONN */
-
- /*
- * Turn off dead battery resistors, turn on CC FETs, and set the higher
- * of the two VCONN current limits (min 0.6A). Many VCONN accessories
- * trip the default current limit of min 0.35A.
- */
- status = set_flags(port, SN5S330_FUNC_SET4,
- SN5S330_CC_EN | SN5S330_VCONN_ILIM_SEL);
- if (status) {
- ppc_prints("Failed to set FUNC_SET4!", port);
- return status;
- }
-
- /* Set ideal diode mode for both PP1 and PP2. */
- status = set_flags(port, SN5S330_FUNC_SET3,
- SN5S330_SET_RCP_MODE_PP1 | SN5S330_SET_RCP_MODE_PP2);
- if (status) {
- ppc_prints("Failed to set FUNC_SET3!", port);
- return status;
- }
-
- /* Turn off PP1 FET. */
- status = sn5s330_pp_fet_enable(port, SN5S330_PP1, 0);
- if (status) {
- ppc_prints("Failed to turn off PP1 FET!", port);
- }
-
- /*
- * Don't proceed with the rest of initialization if we're sysjumping.
- * We would have already done this before.
- */
- if (system_jumped_late())
- return EC_SUCCESS;
-
- /*
- * Clear the digital reset bit, and mask off and clear vSafe0V
- * interrupts. Leave the dead battery mode bit unchanged since it
- * is checked below.
- */
- regval = SN5S330_DIG_RES | SN5S330_VSAFE0V_MASK;
- status = i2c_write8(i2c_port, i2c_addr_flags,
- SN5S330_INT_STATUS_REG4, regval);
- if (status) {
- ppc_prints("Failed to write INT_STATUS_REG4!", port);
- return status;
- }
-
- /*
- * Before turning on the PP2 FET, mask off all unwanted interrupts and
- * then clear all pending interrupts.
- *
- * TODO(aaboagye): Unmask fast-role swap events once fast-role swap is
- * implemented in the PD stack.
- */
-
- /* Enable PP1 overcurrent interrupts. */
- regval = ~SN5S330_ILIM_PP1_MASK;
- status = i2c_write8(i2c_port, i2c_addr_flags,
- SN5S330_INT_MASK_RISE_REG1, regval);
- if (status) {
- ppc_prints("Failed to write INT_MASK_RISE1!", port);
- return status;
- }
-
- status = i2c_write8(i2c_port, i2c_addr_flags,
- SN5S330_INT_MASK_FALL_REG1, 0xFF);
- if (status) {
- ppc_prints("Failed to write INT_MASK_FALL1!", port);
- return status;
- }
-
- /* Enable VCONN overcurrent and CC1/CC2 overvoltage interrupts. */
- regval = ~(SN5S330_VCONN_ILIM | SN5S330_CC1_CON | SN5S330_CC2_CON);
- status = i2c_write8(i2c_port, i2c_addr_flags,
- SN5S330_INT_MASK_RISE_REG2, regval);
- if (status) {
- ppc_prints("Failed to write INT_MASK_RISE2!", port);
- return status;
- }
-
- status = i2c_write8(i2c_port, i2c_addr_flags,
- SN5S330_INT_MASK_FALL_REG2, 0xFF);
- if (status) {
- ppc_prints("Failed to write INT_MASK_FALL2!", port);
- return status;
- }
-
-#if defined(CONFIG_USB_PD_VBUS_DETECT_PPC) && defined(CONFIG_USB_CHARGER)
- /* If PPC is being used to detect VBUS, enable VBUS interrupts. */
- regval = ~SN5S330_VBUS_GOOD_MASK;
-#else
- regval = 0xFF;
-#endif /* CONFIG_USB_PD_VBUS_DETECT_PPC && CONFIG_USB_CHARGER */
-
- status = i2c_write8(i2c_port, i2c_addr_flags,
- SN5S330_INT_MASK_RISE_REG3, regval);
- if (status) {
- ppc_prints("Failed to write INT_MASK_RISE3!", port);
- return status;
- }
-
- status = i2c_write8(i2c_port, i2c_addr_flags,
- SN5S330_INT_MASK_FALL_REG3, regval);
- if (status) {
- ppc_prints("Failed to write INT_MASK_FALL3!", port);
- return status;
- }
-
- /* Now clear any pending interrupts. */
- for (reg = SN5S330_INT_TRIP_RISE_REG1;
- reg <= SN5S330_INT_TRIP_FALL_REG3;
- reg++) {
- status = i2c_write8(i2c_port, i2c_addr_flags,
- reg, 0xFF);
- if (status) {
- CPRINTS("ppc p%d: Failed to write reg 0x%2x!",
- port, reg);
- return status;
- }
- }
-
-
- /*
- * For PP2, check to see if we booted in dead battery mode. If we
- * booted in dead battery mode, the PP2 FET will already be enabled.
- */
- status = i2c_read8(i2c_port, i2c_addr_flags,
- SN5S330_INT_STATUS_REG4, &regval);
- if (status) {
- ppc_prints("Failed to read INT_STATUS_REG4!", port);
- return status;
- }
-
- if (regval & SN5S330_DB_BOOT) {
- /*
- * Clear the bit by writing 1 and keep vSafe0V_MASK
- * unchanged.
- */
- i2c_write8(i2c_port, i2c_addr_flags,
- SN5S330_INT_STATUS_REG4, regval);
-
- /* Turn on PP2 FET. */
- status = sn5s330_pp_fet_enable(port, SN5S330_PP2, 1);
- if (status) {
- ppc_prints("Failed to turn on PP2 FET!", port);
- return status;
- }
- }
-
- return EC_SUCCESS;
-}
-
-#ifdef CONFIG_USB_PD_VBUS_DETECT_PPC
-static int sn5s330_is_vbus_present(int port)
-{
- int regval;
- int rv;
-
- rv = read_reg(port, SN5S330_INT_STATUS_REG3, &regval);
- if (rv) {
- ppc_err_prints("VBUS present error", port, rv);
- return 0;
- }
-
- return !!(regval & SN5S330_VBUS_GOOD);
-}
-#endif /* defined(CONFIG_USB_PD_VBUS_DETECT_PPC) */
-
-static int sn5s330_is_sourcing_vbus(int port)
-{
- return source_enabled[port];
-}
-
-#ifdef CONFIG_USBC_PPC_POLARITY
-static int sn5s330_set_polarity(int port, int polarity)
-{
- if (polarity)
- /* CC2 active. */
- return set_flags(port, SN5S330_FUNC_SET4, SN5S330_CC_POLARITY);
- else
- /* CC1 active. */
- return clr_flags(port, SN5S330_FUNC_SET4, SN5S330_CC_POLARITY);
-}
-#endif
-
-static int sn5s330_set_vbus_source_current_limit(int port,
- enum tcpc_rp_value rp)
-{
- int regval;
- int status;
-
- status = read_reg(port, SN5S330_FUNC_SET1, &regval);
- if (status)
- return status;
-
- /*
- * Note that we chose the lowest current limit setting that is just
- * above indicated Rp value. This is because these are minimum values
- * and we must be able to provide the current that we advertise.
- */
- regval &= ~0x1F; /* The current limit settings are 4:0. */
- switch (rp) {
- case TYPEC_RP_3A0:
- regval |= SN5S330_ILIM_3_06;
- break;
-
- case TYPEC_RP_1A5:
- regval |= SN5S330_ILIM_1_62;
- break;
-
- case TYPEC_RP_USB:
- default:
- regval |= SN5S330_ILIM_0_63;
- break;
- };
-
- status = write_reg(port, SN5S330_FUNC_SET1, regval);
-
- return status;
-}
-
-static int sn5s330_discharge_vbus(int port, int enable)
-{
- int status = enable ? set_flags(port, SN5S330_FUNC_SET3,
- SN5S330_VBUS_DISCH_EN)
- : clr_flags(port, SN5S330_FUNC_SET3,
- SN5S330_VBUS_DISCH_EN);
-
- if (status) {
- CPRINTS("ppc p%d: Failed to %s vbus discharge",
- port, enable ? "enable" : "disable");
- return status;
- }
-
- return EC_SUCCESS;
-}
-
-static int sn5s330_enter_low_power_mode(int port)
-{
- int rv;
-
- /* Turn off both SRC and SNK FETs */
- rv = clr_flags(port, SN5S330_FUNC_SET3,
- SN5S330_PP1_EN | SN5S330_PP2_EN);
-
- if (rv) {
- ppc_err_prints("Could not disable both FETS", port, rv);
- return rv;
- }
-
- /* Turn off Vconn power */
- rv = clr_flags(port, SN5S330_FUNC_SET4, SN5S330_VCONN_EN);
-
- if (rv) {
- ppc_err_prints("Could not disable Vconn", port, rv);
- return rv;
- }
-
- /* Turn off SBU path */
- rv = clr_flags(port, SN5S330_FUNC_SET2, SN5S330_SBU_EN);
-
- if (rv) {
- ppc_err_prints("Could not disable SBU path", port, rv);
- return rv;
- }
-
- /*
- * Turn off the Over Voltage Protection circuits. Needs to happen after
- * FETs are disabled, otherwise OVP can automatically turned back on.
- * Since FETs are off, any over voltage does not make it to the board
- * side of the PPC.
- */
- rv = clr_flags(port, SN5S330_FUNC_SET9,
- SN5S330_FORCE_OVP_EN_SBU | SN5S330_FORCE_ON_VBUS_OVP |
- SN5S330_FORCE_ON_VBUS_UVP);
-
- if (rv) {
- ppc_err_prints("Could not disable OVP circuit", port, rv);
- return rv;
- }
-
- return EC_SUCCESS;
-}
-
-#ifdef CONFIG_USBC_PPC_VCONN
-static int sn5s330_set_vconn(int port, int enable)
-{
- int regval;
- int status;
-
- status = read_reg(port, SN5S330_FUNC_SET4, &regval);
- if (status)
- return status;
-
- if (enable)
- regval |= SN5S330_VCONN_EN;
- else
- regval &= ~SN5S330_VCONN_EN;
-
- return write_reg(port, SN5S330_FUNC_SET4, regval);
-}
-#endif
-
-static int sn5s330_vbus_sink_enable(int port, int enable)
-{
- return sn5s330_pp_fet_enable(port, SN5S330_PP2, !!enable);
-}
-
-static int sn5s330_vbus_source_enable(int port, int enable)
-{
- return sn5s330_pp_fet_enable(port, SN5S330_PP1, !!enable);
-}
-
-#ifdef CONFIG_USBC_PPC_SBU
-static int sn5s330_set_sbu(int port, int enable)
-{
- int rv;
-
- if (enable)
- rv = set_flags(port, SN5S330_FUNC_SET2, SN5S330_SBU_EN);
- else
- rv = clr_flags(port, SN5S330_FUNC_SET2, SN5S330_SBU_EN);
-
- return rv;
-}
-#endif /* CONFIG_USBC_PPC_SBU */
-
-static void sn5s330_handle_interrupt(int port)
-{
- int attempt = 0;
-
- /*
- * SN5S330's /INT pin is level, so process interrupts until it
- * deasserts if the chip has a dedicated interrupt pin.
- */
-#ifdef CONFIG_USBC_PPC_DEDICATED_INT
- while (ppc_get_alert_status(port))
-#endif
- {
- int rise = 0;
- int fall = 0;
-
- attempt++;
-
- if (attempt > 1)
- ppc_prints("Could not clear interrupts on first "
- "try, retrying", port);
-
- read_reg(port, SN5S330_INT_TRIP_RISE_REG1, &rise);
- read_reg(port, SN5S330_INT_TRIP_FALL_REG1, &fall);
-
- /* Notify the system about the overcurrent event. */
- if (rise & SN5S330_ILIM_PP1_MASK)
- pd_handle_overcurrent(port);
-
- /* Clear the interrupt sources. */
- write_reg(port, SN5S330_INT_TRIP_RISE_REG1, rise);
- write_reg(port, SN5S330_INT_TRIP_FALL_REG1, fall);
-
- read_reg(port, SN5S330_INT_TRIP_RISE_REG2, &rise);
- read_reg(port, SN5S330_INT_TRIP_FALL_REG2, &fall);
-
- /*
- * VCONN may be latched off due to an overcurrent. Indicate
- * when the VCONN overcurrent happens.
- */
- if (rise & SN5S330_VCONN_ILIM)
- ppc_prints("VCONN OC!", port);
-
- /* Notify the system about the CC overvoltage event. */
- if (rise & SN5S330_CC1_CON || rise & SN5S330_CC2_CON) {
- ppc_prints("CC OV!", port);
- pd_handle_cc_overvoltage(port);
- }
-
- /* Clear the interrupt sources. */
- write_reg(port, SN5S330_INT_TRIP_RISE_REG2, rise);
- write_reg(port, SN5S330_INT_TRIP_FALL_REG2, fall);
-
-#if defined(CONFIG_USB_PD_VBUS_DETECT_PPC) && defined(CONFIG_USB_CHARGER)
- read_reg(port, SN5S330_INT_TRIP_RISE_REG3, &rise);
- read_reg(port, SN5S330_INT_TRIP_FALL_REG3, &fall);
-
- /* Inform other modules about VBUS level */
- if (rise & SN5S330_VBUS_GOOD_MASK
- || fall & SN5S330_VBUS_GOOD_MASK)
- usb_charger_vbus_change(port,
- sn5s330_is_vbus_present(port));
-
- /* Clear the interrupt sources. */
- write_reg(port, SN5S330_INT_TRIP_RISE_REG3, rise);
- write_reg(port, SN5S330_INT_TRIP_FALL_REG3, fall);
-#endif /* CONFIG_USB_PD_VBUS_DETECT_PPC && CONFIG_USB_CHARGER */
-
- }
-}
-
-static void sn5s330_irq_deferred(void)
-{
- int i;
- uint32_t pending = atomic_clear(&irq_pending);
-
- for (i = 0; i < board_get_usb_pd_port_count(); i++)
- if (BIT(i) & pending)
- sn5s330_handle_interrupt(i);
-}
-DECLARE_DEFERRED(sn5s330_irq_deferred);
-
-void sn5s330_interrupt(int port)
-{
- atomic_or(&irq_pending, BIT(port));
- hook_call_deferred(&sn5s330_irq_deferred_data, 0);
-}
-
-const struct ppc_drv sn5s330_drv = {
- .init = &sn5s330_init,
- .is_sourcing_vbus = &sn5s330_is_sourcing_vbus,
- .vbus_sink_enable = &sn5s330_vbus_sink_enable,
- .vbus_source_enable = &sn5s330_vbus_source_enable,
- .set_vbus_source_current_limit = &sn5s330_set_vbus_source_current_limit,
- .discharge_vbus = &sn5s330_discharge_vbus,
- .enter_low_power_mode = &sn5s330_enter_low_power_mode,
-#ifdef CONFIG_CMD_PPC_DUMP
- .reg_dump = &sn5s330_dump,
-#endif
-#ifdef CONFIG_USB_PD_VBUS_DETECT_PPC
- .is_vbus_present = &sn5s330_is_vbus_present,
-#endif
-#ifdef CONFIG_USBC_PPC_POLARITY
- .set_polarity = &sn5s330_set_polarity,
-#endif
-#ifdef CONFIG_USBC_PPC_SBU
- .set_sbu = &sn5s330_set_sbu,
-#endif /* defined(CONFIG_USBC_PPC_SBU) */
-#ifdef CONFIG_USBC_PPC_VCONN
- .set_vconn = &sn5s330_set_vconn,
-#endif
-};
diff --git a/driver/ppc/sn5s330.h b/driver/ppc/sn5s330.h
deleted file mode 100644
index f94a3e8e10..0000000000
--- a/driver/ppc/sn5s330.h
+++ /dev/null
@@ -1,161 +0,0 @@
-/* Copyright 2017 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.
- */
-
-/* TI SN5S330 Type-C Power Path Controller */
-
-#ifndef __CROS_EC_SN5S330_H
-#define __CROS_EC_SN5S330_H
-
-#include "common.h"
-
-#include "driver/ppc/sn5s330_public.h"
-
-struct sn5s330_config {
- uint8_t i2c_port;
- uint8_t i2c_addr_flags;
-};
-
-extern const struct sn5s330_config sn5s330_chips[];
-extern const unsigned int sn5s330_cnt;
-
-/* Power Path Indices */
-enum sn5s330_pp_idx {
- SN5S330_PP1,
- SN5S330_PP2,
- SN5S330_PP_COUNT,
-};
-
-#define SN5S330_FUNC_SET1 0x50
-#define SN5S330_FUNC_SET2 0x51
-#define SN5S330_FUNC_SET3 0x52
-#define SN5S330_FUNC_SET4 0x53
-#define SN5S330_FUNC_SET5 0x54
-#define SN5S330_FUNC_SET6 0x55
-#define SN5S330_FUNC_SET7 0x56
-#define SN5S330_FUNC_SET8 0x57
-#define SN5S330_FUNC_SET9 0x58
-#define SN5S330_FUNC_SET10 0x59
-#define SN5S330_FUNC_SET11 0x5A
-#define SN5S330_FUNC_SET12 0x5B
-
-#define SN5S330_INT_STATUS_REG1 0x2F
-#define SN5S330_INT_STATUS_REG2 0x30
-#define SN5S330_INT_STATUS_REG3 0x31
-#define SN5S330_INT_STATUS_REG4 0x32
-
-#define SN5S330_INT_TRIP_RISE_REG1 0x20
-#define SN5S330_INT_TRIP_RISE_REG2 0x21
-#define SN5S330_INT_TRIP_RISE_REG3 0x22
-#define SN5S330_INT_TRIP_FALL_REG1 0x23
-#define SN5S330_INT_TRIP_FALL_REG2 0x24
-#define SN5S330_INT_TRIP_FALL_REG3 0x25
-
-#define SN5S330_INT_MASK_RISE_REG1 0x26
-#define SN5S330_INT_MASK_RISE_REG2 0x27
-#define SN5S330_INT_MASK_RISE_REG3 0x28
-#define SN5S330_INT_MASK_FALL_REG1 0x29
-#define SN5S330_INT_MASK_FALL_REG2 0x2A
-#define SN5S330_INT_MASK_FALL_REG3 0x2B
-
-#define PPX_ILIM_DEGLITCH_0_US_20 0x1
-#define PPX_ILIM_DEGLITCH_0_US_50 0x2
-#define PPX_ILIM_DEGLITCH_0_US_100 0x3
-#define PPX_ILIM_DEGLITCH_0_US_200 0x4
-#define PPX_ILIM_DEGLITCH_0_US_1000 0x5
-#define PPX_ILIM_DEGLITCH_0_US_2000 0x6
-#define PPX_ILIM_DEGLITCH_0_US_10000 0x7
-
-/* Internal VBUS Switch Current Limit Settings (min) */
-#define SN5S330_ILIM_0_35 0
-#define SN5S330_ILIM_0_63 1
-#define SN5S330_ILIM_0_90 2
-#define SN5S330_ILIM_1_14 3
-#define SN5S330_ILIM_1_38 4
-#define SN5S330_ILIM_1_62 5
-#define SN5S330_ILIM_1_86 6
-#define SN5S330_ILIM_2_10 7
-#define SN5S330_ILIM_2_34 8
-#define SN5S330_ILIM_2_58 9
-#define SN5S330_ILIM_2_82 10
-#define SN5S330_ILIM_3_06 11
-#define SN5S330_ILIM_3_30 12
-
-/* FUNC_SET_2 */
-#define SN5S330_SBU_EN BIT(4)
-
-/* FUNC_SET_3 */
-#define SN5S330_PP1_EN BIT(0)
-#define SN5S330_PP2_EN BIT(1)
-#define SN5S330_VBUS_DISCH_EN BIT(2)
-#define SN5S330_SET_RCP_MODE_PP1 BIT(5)
-#define SN5S330_SET_RCP_MODE_PP2 BIT(6)
-
-/* FUNC_SET_4 */
-#define SN5S330_VCONN_EN BIT(0)
-#define SN5S330_CC_POLARITY BIT(1)
-#define SN5S330_CC_EN BIT(4)
-#define SN5S330_VCONN_ILIM_SEL BIT(5)
-
-/* FUNC_SET_8 */
-#define SN5S330_VCONN_DEGLITCH_MASK (3 << 6)
-#define SN5S330_VCONN_DEGLITCH_63_US (0 << 6)
-#define SN5S330_VCONN_DEGLITCH_125_US BIT(6)
-#define SN5S330_VCONN_DEGLITCH_640_US (2 << 6)
-#define SN5S330_VCONN_DEGLITCH_1280_US (3 << 6)
-
-/* FUNC_SET_9 */
-#define SN5S330_FORCE_OVP_EN_SBU BIT(1)
-#define SN5S330_PP2_CONFIG BIT(2)
-#define SN5S330_OVP_EN_CC BIT(4)
-#define SN5S330_CONFIG_UVP BIT(5)
-#define SN5S330_FORCE_ON_VBUS_OVP BIT(6)
-#define SN5S330_FORCE_ON_VBUS_UVP BIT(7)
-
-/* INT_STATUS_REG3 */
-#define SN5S330_VBUS_GOOD BIT(0)
-
-/* INT_STATUS_REG4 */
-#define SN5S330_DIG_RES BIT(0)
-#define SN5S330_DB_BOOT BIT(1)
-#define SN5S330_VSAFE0V_STAT BIT(2)
-#define SN5S330_VSAFE0V_MASK BIT(3)
-
-/*
- * INT_MASK_RISE/FALL_EDGE_1
- *
- * The ILIM_PP1 bit indicates an overcurrent condition when sourcing on power
- * path 1. For rising edge registers, this indicates an overcurrent has
- * occured; similarly for falling edge, it means the overcurrent condition is no
- * longer present.
- */
-#define SN5S330_ILIM_PP1_MASK BIT(4)
-
-/*
- * INT_MASK_RISE/FALL_EDGE2
- *
- * The VCONN_ILIM bit indicates an overcurrent condition on VCONN. By default,
- * VCONN will be latched off.
- */
-#define SN5S330_VCONN_ILIM (1 << 1)
-
-/*
- * INT_MASK_RISE/FALL_EDGE2
- *
- * The OV_CC1_CON/OV_CC2_CON bit indicates an over-voltage occurred on
- * C_CC1/C_CC2.
- */
-#define SN5S330_CC1_CON (1 << 2)
-#define SN5S330_CC2_CON (1 << 3)
-
-/*
- * INT_MASK_RISE/FALL_EDGE_3
- *
- * The VBUS_GOOD bit indicates VBUS has increased beyond a 4.0V threshold.
- * For rising edge registers, this indicates VBUS has risen above 4.0V.
- * For falling edge registers, this indicates VBUS has fallen below 4.0V.
- */
-#define SN5S330_VBUS_GOOD_MASK BIT(0)
-
-#endif /* defined(__CROS_EC_SN5S330_H) */
diff --git a/driver/ppc/syv682x.c b/driver/ppc/syv682x.c
deleted file mode 100644
index 0e49abdf6a..0000000000
--- a/driver/ppc/syv682x.c
+++ /dev/null
@@ -1,837 +0,0 @@
-/* Copyright 2018 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.
- */
-
-/* Silergy SYV682x USB-C Power Path Controller */
-#include "atomic.h"
-#include "common.h"
-#include "config.h"
-#include "console.h"
-#include "syv682x.h"
-#include "hooks.h"
-#include "i2c.h"
-#include "system.h"
-#include "timer.h"
-#include "usb_charge.h"
-#include "usb_pd_tcpm.h"
-#include "usbc_ppc.h"
-#include "usb_pd.h"
-#include "util.h"
-
-#define SYV682X_FLAGS_SOURCE_ENABLED BIT(0)
-#define SYV682X_FLAGS_SINK_ENABLED BIT(1)
-/* 0 -> CC1, 1 -> CC2 */
-#define SYV682X_FLAGS_CC_POLARITY BIT(2)
-#define SYV682X_FLAGS_VBUS_PRESENT BIT(3)
-#define SYV682X_FLAGS_TSD BIT(4)
-#define SYV682X_FLAGS_OVP BIT(5)
-#define SYV682X_FLAGS_5V_OC BIT(6)
-#define SYV682X_FLAGS_FRS BIT(7)
-#define SYV682X_FLAGS_VCONN_OCP BIT(8)
-
-static uint32_t irq_pending; /* Bitmask of ports signaling an interrupt. */
-static uint32_t flags[CONFIG_USB_PD_PORT_MAX_COUNT];
-/* Running count of sink ocp events */
-static uint32_t sink_ocp_count[CONFIG_USB_PD_PORT_MAX_COUNT];
-static timestamp_t vbus_oc_timer[CONFIG_USB_PD_PORT_MAX_COUNT];
-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. 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
-
-/* When FRS is enabled, the VCONN line isn't passed through to the TCPC */
-#if defined(CONFIG_USB_PD_FRS_PPC) && defined(CONFIG_USBC_VCONN) && \
- !defined(CONFIG_USBC_PPC_VCONN)
-#error "if FRS is enabled on the SYV682X, VCONN must be supplied by the PPC "
-"instead of the TCPC"
-#endif
-
-#define CPRINTS(format, args...) cprints(CC_USBPD, format, ## args)
-
-static int syv682x_vbus_sink_enable(int port, int enable);
-
-static int syv682x_init(int port);
-
-static void syv682x_interrupt_delayed(int port, int delay);
-
-static int read_reg(uint8_t port, int reg, int *regval)
-{
- return i2c_read8(ppc_chips[port].i2c_port,
- ppc_chips[port].i2c_addr_flags,
- reg,
- regval);
-}
-
-#ifdef CONFIG_USBC_PPC_SYV682C
-__overridable int syv682x_board_is_syv682c(int port)
-{
- return true;
-}
-#endif
-
-/*
- * During channel transition or discharge, the SYV682X silently ignores I2C
- * writes. Poll the BUSY bit until the SYV682A is ready.
- */
-static int syv682x_wait_for_ready(int port, int reg)
-{
- int regval;
- int rv;
- timestamp_t deadline;
-
-#ifdef CONFIG_USBC_PPC_SYV682C
- /* On SYV682C, busy bit is not applied to CONTROL_4 */
- if (syv682x_board_is_syv682c(port) && reg == SYV682X_CONTROL_4_REG)
- return EC_SUCCESS;
-#endif
-
- deadline.val = get_time().val
- + (SYV682X_MAX_VBUS_DISCHARGE_TIME_MS * MSEC);
-
- do {
- rv = read_reg(port, SYV682X_CONTROL_3_REG, &regval);
- if (rv)
- return rv;
-
- if (!(regval & SYV682X_BUSY))
- break;
-
- if (timestamp_expired(deadline, NULL)) {
- ppc_prints("busy timeout", port);
- return EC_ERROR_TIMEOUT;
- }
-
- msleep(1);
- } while (1);
-
- return EC_SUCCESS;
-}
-
-static int write_reg(uint8_t port, int reg, int regval)
-{
- int rv;
-
- rv = syv682x_wait_for_ready(port, reg);
- if (rv)
- return rv;
-
- return i2c_write8(ppc_chips[port].i2c_port,
- ppc_chips[port].i2c_addr_flags,
- reg,
- regval);
-}
-
-static int syv682x_is_sourcing_vbus(int port)
-{
- return !!(flags[port] & SYV682X_FLAGS_SOURCE_ENABLED);
-}
-
-static int syv682x_discharge_vbus(int port, int enable)
-{
-#ifndef CONFIG_USBC_PPC_SYV682X_SMART_DISCHARGE
- int regval;
- int rv;
-
- rv = read_reg(port, SYV682X_CONTROL_2_REG, &regval);
- if (rv)
- return rv;
-
- if (enable)
- regval |= SYV682X_CONTROL_2_FDSG;
- else
- regval &= ~SYV682X_CONTROL_2_FDSG;
-
- return write_reg(port, SYV682X_CONTROL_2_REG, regval);
-#else
- /*
- * Smart discharge mode is enabled, nothing to do
- */
- return EC_SUCCESS;
-#endif
-}
-
-static int syv682x_vbus_source_enable(int port, int enable)
-{
- int regval;
- int rv;
- /*
- * For source mode need to make sure 5V power path is connected
- * and source mode is selected.
- */
- rv = read_reg(port, SYV682X_CONTROL_1_REG, &regval);
- if (rv)
- return rv;
-
- if (enable) {
- /* Select 5V path and turn on channel */
- regval &= ~(SYV682X_CONTROL_1_CH_SEL |
- SYV682X_CONTROL_1_PWR_ENB);
- /* Disable HV Sink path */
- regval |= SYV682X_CONTROL_1_HV_DR;
- } else if (flags[port] & SYV682X_FLAGS_SOURCE_ENABLED) {
- /*
- * For the disable case, make sure that VBUS was being sourced
- * prior to disabling the source path. Because the source/sink
- * paths can't be independently disabled, and this function will
- * get called as part of USB PD initialization, setting the
- * PWR_ENB always can lead to broken dead battery behavior.
- *
- * No need to change the voltage path or channel direction. But,
- * turn both paths off.
- *
- * De-assert the FRS GPIO, which will be asserted if we got to
- * be a source via an FRS.
- */
- regval |= SYV682X_CONTROL_1_PWR_ENB;
- if (IS_ENABLED(CONFIG_USB_PD_FRS_PPC))
- gpio_set_level(ppc_chips[port].frs_en, 0);
- }
-
- rv = write_reg(port, SYV682X_CONTROL_1_REG, regval);
- if (rv)
- return rv;
-
- if (enable) {
- atomic_or(&flags[port], SYV682X_FLAGS_SOURCE_ENABLED);
- atomic_clear_bits(&flags[port], SYV682X_FLAGS_SINK_ENABLED);
- } else {
- atomic_clear_bits(&flags[port], SYV682X_FLAGS_SOURCE_ENABLED);
- }
-
-#if defined(CONFIG_USB_CHARGER) && defined(CONFIG_USB_PD_VBUS_DETECT_PPC)
- /*
- * Since the VBUS state could be changing here, need to wake the
- * USB_CHG_N task so that BC 1.2 detection will be triggered.
- */
- usb_charger_vbus_change(port, enable);
-#endif
-
- return EC_SUCCESS;
-}
-
-/* Filter interrupts with rising edge trigger */
-static bool syv682x_interrupt_filter(int port, int regval, int regmask,
- int flagmask)
-{
- if (regval & regmask) {
- if (!(flags[port] & flagmask)) {
- atomic_or(&flags[port], flagmask);
- return true;
- }
- } else {
- atomic_clear_bits(&flags[port], flagmask);
- }
- return false;
-}
-
-/*
- * Two status registers can trigger the ALERT_L pin, STATUS and CONTROL_4
- * These registers are clear on read if the condition has been cleared.
- * The ALERT_L pin will not de-assert if the alert condition has not been
- * cleared. Since they are clear on read, we should check the alerts whenever we
- * read these registers to avoid race conditions.
- */
-static void syv682x_handle_status_interrupt(int port, int regval)
-{
- /*
- * An FRS will automatically disable sinking immediately, and enable the
- * source path if VBUS is <5V. The FRS GPIO must remain asserted until
- * VBUS falls below 5V. SYV682X_FLAGS_FRS signals that the SRC state was
- * entered via an FRS.
- *
- * Note the FRS Alert will remain asserted until VBUS has fallen below
- * 5V or the frs_en gpio is de-asserted. So use the rising edge trigger.
- */
- if (IS_ENABLED(CONFIG_USB_PD_FRS_PPC)) {
- if (syv682x_interrupt_filter(port, regval, SYV682X_STATUS_FRS,
- SYV682X_FLAGS_FRS)) {
- atomic_or(&flags[port], SYV682X_FLAGS_SOURCE_ENABLED);
- atomic_clear_bits(&flags[port],
- SYV682X_FLAGS_SINK_ENABLED);
- if (!IS_ENABLED(CONFIG_USB_PD_FRS_TCPC))
- pd_got_frs_signal(port);
- }
- }
-
- /*
- * 5V OC is actually notifying that it is current limiting
- * to 3.3A. If this happens for a long time, we will trip TSD
- * which will disable the channel. We should disable the sourcing path
- * before that happens for safety reasons.
- *
- * On first check, set the flag and set the timer. This also clears the
- * flag if the OC is gone.
- */
- if (syv682x_interrupt_filter(port, regval, SYV682X_STATUS_OC_5V,
- SYV682X_FLAGS_5V_OC)) {
- vbus_oc_timer[port].val =
- get_time().val + SOURCE_OC_DEGLITCH_MS * MSEC;
- } else if ((regval & SYV682X_STATUS_OC_5V) &&
- (get_time().val > vbus_oc_timer[port].val)) {
- vbus_oc_timer[port].val = UINT64_MAX;
- atomic_clear_bits(&flags[port], SYV682X_FLAGS_5V_OC);
- syv682x_vbus_source_enable(port, 0);
- pd_handle_overcurrent(port);
- }
-
- /*
- * No PD handling for VBUS OVP or TSD events.
- * For TSD, this means we are in danger of burning the device so turn
- * everything off and leave it off. The power paths will be
- * automatically disabled.
- * In the case of OVP, the channels will be
- * disabled but don't unset the sink flag, since a sink OCP can
- * inadvertently cause an OVP, and we'd want to re-enable the sink
- * path in that situation.
- */
- if (syv682x_interrupt_filter(port, regval, SYV682X_STATUS_TSD,
- SYV682X_FLAGS_TSD)) {
- ppc_prints("TSD!", port);
- atomic_clear_bits(&flags[port],
- SYV682X_FLAGS_SOURCE_ENABLED |
- SYV682X_FLAGS_SINK_ENABLED);
- }
- if (syv682x_interrupt_filter(port, regval, SYV682X_STATUS_OVP,
- SYV682X_FLAGS_OVP)) {
- ppc_prints("VBUS OVP!", port);
- atomic_clear_bits(&flags[port], SYV682X_FLAGS_SOURCE_ENABLED);
- }
-
- /*
- * HV OC is a hard limit that will disable the sink path (automatically
- * removing this alert condition), so try re-enabling if we hit an OCP.
- * If we get multiple OCPs, don't re-enable. The OCP counter is reset on
- * the sink path being explicitly disabled or on a PPC init.
- */
- if (regval & SYV682X_STATUS_OC_HV) {
- ppc_prints("Sink OCP!", port);
- atomic_add(&sink_ocp_count[port], 1);
- if ((sink_ocp_count[port] < OCP_COUNT_LIMIT) &&
- (flags[port] & SYV682X_FLAGS_SINK_ENABLED)) {
- syv682x_vbus_sink_enable(port, 1);
- } else {
- ppc_prints("Disable sink", port);
- atomic_clear_bits(&flags[port],
- SYV682X_FLAGS_SINK_ENABLED);
- }
- }
-}
-
-static int syv682x_handle_control_4_interrupt(int port, int regval)
-{
- /*
- * VCONN OC is actually notifying that it is current limiting
- * to 600mA. If this happens for a long time, we will trip TSD
- * which will disable the channel. We should disable the sourcing path
- * before that happens for safety reasons.
- *
- * On first check, set the flag and set the timer. This also clears the
- * flag if the OC is gone.
- */
- if (syv682x_interrupt_filter(port, regval, SYV682X_CONTROL_4_VCONN_OCP,
- SYV682X_FLAGS_VCONN_OCP)) {
- vconn_oc_timer[port].val =
- get_time().val + VCONN_OC_DEGLITCH_MS * MSEC;
- } else if ((regval & SYV682X_CONTROL_4_VCONN_OCP) &&
- (get_time().val > vconn_oc_timer[port].val)) {
- vconn_oc_timer[port].val = UINT64_MAX;
- atomic_clear_bits(&flags[port], SYV682X_FLAGS_VCONN_OCP);
-
- /* Disable VCONN */
- regval &=
- ~(SYV682X_CONTROL_4_VCONN2 | SYV682X_CONTROL_4_VCONN1);
- write_reg(port, SYV682X_CONTROL_4_REG, regval);
-
- ppc_prints("VCONN OC!", port);
- }
-
- /*
- * On VBAT OVP, CC/VCONN are cut. Re-enable before sending the hard
- * reset using a PPC re-init. We could reconfigure CC based on flags,
- * but these will be updated anyway due to a hard reset so just re-init
- * for simplicity. If this happens return an error since this isn't
- * recoverable.
- */
- if (regval & SYV682X_CONTROL_4_VBAT_OVP) {
- ppc_prints("VBAT or CC OVP!", port);
- syv682x_init(port);
- pd_handle_cc_overvoltage(port);
- return EC_ERROR_UNKNOWN;
- }
- return EC_SUCCESS;
-}
-
-static int syv682x_vbus_sink_enable(int port, int enable)
-{
- int regval;
- int rv;
-
- if (!enable) {
- atomic_clear(&sink_ocp_count[port]);
- atomic_clear_bits(&flags[port], SYV682X_FLAGS_SINK_ENABLED);
- /*
- * We're currently a source, so nothing more to do
- */
- if (syv682x_is_sourcing_vbus(port))
- return EC_SUCCESS;
- } else if (sink_ocp_count[port] > OCP_COUNT_LIMIT) {
- /*
- * Don't re-enable the channel until an explicit sink disable
- * resets the ocp counter.
- */
- return EC_ERROR_UNKNOWN;
- }
-
- /*
- * For sink mode need to make sure high voltage power path is connected
- * and sink mode is selected.
- */
- rv = read_reg(port, SYV682X_CONTROL_1_REG, &regval);
- if (rv)
- return rv;
-
- if (enable) {
- /* Select high voltage path */
- regval |= SYV682X_CONTROL_1_CH_SEL;
- /* Select Sink mode and turn on the channel */
- regval &= ~(SYV682X_CONTROL_1_HV_DR |
- SYV682X_CONTROL_1_PWR_ENB);
- /* Set sink current limit to the configured value */
- regval |= CONFIG_SYV682X_HV_ILIM << SYV682X_HV_ILIM_BIT_SHIFT;
- atomic_clear_bits(&flags[port], SYV682X_FLAGS_SOURCE_ENABLED);
- atomic_or(&flags[port], SYV682X_FLAGS_SINK_ENABLED);
- } else {
- /*
- * No need to change the voltage path or channel direction. But,
- * turn both paths off because we are currently a sink.
- */
- regval |= SYV682X_CONTROL_1_PWR_ENB;
- }
-
- return write_reg(port, SYV682X_CONTROL_1_REG, regval);
-}
-
-#ifdef CONFIG_USB_PD_VBUS_DETECT_PPC
-static int syv682x_is_vbus_present(int port)
-{
- int val;
- int vbus = 0;
-
- if (read_reg(port, SYV682X_STATUS_REG, &val))
- return vbus;
- /*
- * The status register interrupt bits are clear on read, check
- * register value to see if there are interrupts to avoid race
- * conditions with the interrupt handler
- */
- syv682x_handle_status_interrupt(port, val);
-
- /*
- * VBUS is considered present if VSafe5V is detected or neither VSafe5V
- * or VSafe0V is detected, which implies VBUS > 5V.
- */
- if ((val & SYV682X_STATUS_VSAFE_5V) ||
- !(val & (SYV682X_STATUS_VSAFE_5V | SYV682X_STATUS_VSAFE_0V)))
- vbus = 1;
-#ifdef CONFIG_USB_CHARGER
- if (!!(flags[port] & SYV682X_FLAGS_VBUS_PRESENT) != vbus)
- usb_charger_vbus_change(port, vbus);
-
- if (vbus)
- atomic_or(&flags[port], SYV682X_FLAGS_VBUS_PRESENT);
- else
- atomic_clear_bits(&flags[port], SYV682X_FLAGS_VBUS_PRESENT);
-#endif
-
- return vbus;
-}
-#endif
-
-static int syv682x_set_vbus_source_current_limit(int port,
- enum tcpc_rp_value rp)
-{
- int rv;
- int limit;
- int regval;
-
- rv = read_reg(port, SYV682X_CONTROL_1_REG, &regval);
- if (rv)
- return rv;
-
- /* We need buffer room for all current values. */
- switch (rp) {
- case TYPEC_RP_3A0:
- limit = SYV682X_5V_ILIM_3_30;
- break;
-
- case TYPEC_RP_1A5:
- limit = SYV682X_5V_ILIM_1_75;
- break;
-
- case TYPEC_RP_USB:
- default:
- /* 1.25 A is lowest current limit setting for SVY682 */
- limit = SYV682X_5V_ILIM_1_25;
- break;
- };
-
- regval &= ~SYV682X_5V_ILIM_MASK;
- regval |= (limit << SYV682X_5V_ILIM_BIT_SHIFT);
- return write_reg(port, SYV682X_CONTROL_1_REG, regval);
-}
-
-#ifdef CONFIG_USBC_PPC_POLARITY
-static int syv682x_set_polarity(int port, int polarity)
-{
- /*
- * The SYV682x does not explicitly set CC polarity. However, if VCONN is
- * being used then the polarity is required to connect 5V to the correct
- * CC line. So this function saves the CC polarity as a bit in the flags
- * variable so VCONN is connected the correct CC line. The flag bit
- * being set means polarity = CC2, the flag bit clear means
- * polarity = CC1.
- */
- if (polarity)
- atomic_or(&flags[port], SYV682X_FLAGS_CC_POLARITY);
- else
- atomic_clear_bits(&flags[port], SYV682X_FLAGS_CC_POLARITY);
-
- return EC_SUCCESS;
-}
-#endif
-
-#ifdef CONFIG_USBC_PPC_VCONN
-static int syv682x_set_vconn(int port, int enable)
-{
- int regval;
- int rv;
-
- rv = read_reg(port, SYV682X_CONTROL_4_REG, &regval);
- if (rv)
- return rv;
- /*
- * The control4 register interrupt bits are clear on read, check
- * register value to see if there are interrupts to avoid race
- * conditions with the interrupt handler
- */
- rv = syv682x_handle_control_4_interrupt(port, regval);
- if (rv)
- return rv;
-
- regval &= ~(SYV682X_CONTROL_4_VCONN2 | SYV682X_CONTROL_4_VCONN1);
- if (enable) {
- regval |= flags[port] & SYV682X_FLAGS_CC_POLARITY ?
- SYV682X_CONTROL_4_VCONN1 :
- SYV682X_CONTROL_4_VCONN2;
- }
-
- return write_reg(port, SYV682X_CONTROL_4_REG, regval);
-}
-#endif
-
-#ifdef CONFIG_CMD_PPC_DUMP
-static int syv682x_dump(int port)
-{
- int reg_addr;
- int data;
- int rv;
- const int i2c_port = ppc_chips[port].i2c_port;
- const int i2c_addr_flags = ppc_chips[port].i2c_addr_flags;
-
- for (reg_addr = SYV682X_STATUS_REG; reg_addr <= SYV682X_CONTROL_4_REG;
- reg_addr++) {
- rv = i2c_read8(i2c_port, i2c_addr_flags, reg_addr, &data);
- if (rv)
- ccprintf("ppc_syv682[p%d]: Failed to read reg 0x%02x\n",
- port, reg_addr);
- else
- ccprintf("ppc_syv682[p%d]: reg 0x%02x = 0x%02x\n",
- port, reg_addr, data);
- }
-
- cflush();
-
- return EC_SUCCESS;
-}
-#endif /* defined(CONFIG_CMD_PPC_DUMP) */
-
-static void syv682x_handle_interrupt(int port)
-{
- int control4;
- int status;
-
- /* Both interrupt registers are clear on read */
- read_reg(port, SYV682X_CONTROL_4_REG, &control4);
- syv682x_handle_control_4_interrupt(port, control4);
-
- read_reg(port, SYV682X_STATUS_REG, &status);
- syv682x_handle_status_interrupt(port, status);
-
- /*
- * Since ALERT_L is level-triggered, check the alert status and repeat
- * 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 (status & SYV682X_STATUS_INT_MASK ||
- control4 & SYV682X_CONTROL_4_INT_MASK) {
- syv682x_interrupt_delayed(port, INTERRUPT_DELAY_MS);
- }
-}
-
-static void syv682x_irq_deferred(void)
-{
- int i;
- uint32_t pending = atomic_clear(&irq_pending);
-
- for (i = 0; i < board_get_usb_pd_port_count(); i++)
- if (BIT(i) & pending)
- syv682x_handle_interrupt(i);
-}
-DECLARE_DEFERRED(syv682x_irq_deferred);
-
-static void syv682x_interrupt_delayed(int port, int delay)
-{
- atomic_or(&irq_pending, BIT(port));
- hook_call_deferred(&syv682x_irq_deferred_data, delay * MSEC);
-}
-
-void syv682x_interrupt(int port)
-{
- /* FRS timings require <15ms response to an FRS event */
- syv682x_interrupt_delayed(port, 0);
-}
-
-/*
- * The frs_en signal can be driven from the TCPC as well (preferred).
- * In that case, no PPC configuration needs to be done to enable FRS
- */
-#ifdef CONFIG_USB_PD_FRS_PPC
-static int syv682x_set_frs_enable(int port, int enable)
-{
- int regval;
-
- read_reg(port, SYV682X_CONTROL_4_REG, &regval);
- syv682x_handle_control_4_interrupt(port, regval);
-
- if (enable) {
- /*
- * The CC line is the FRS trigger, and VCONN should
- * be ignored. The SYV682 uses the CCx_BPS fields to
- * determine if CC1 or CC2 is CC and should be used for
- * FRS. This CCx is also connected through to the TCPC.
- * The other CCx signal (VCONN) is isolated from the
- * TCPC with this write (VCONN must be provided by PPC).
- *
- * It is not a valid state to have both or neither
- * CC_BPS bits set and the CC_FRS enabled, exactly 1
- * should be set.
- */
- regval &= ~(SYV682X_CONTROL_4_CC1_BPS |
- SYV682X_CONTROL_4_CC2_BPS);
- regval |= flags[port] & SYV682X_FLAGS_CC_POLARITY ?
- SYV682X_CONTROL_4_CC2_BPS :
- SYV682X_CONTROL_4_CC1_BPS;
- /* set GPIO after configuring */
- write_reg(port, SYV682X_CONTROL_4_REG, regval);
- gpio_set_level(ppc_chips[port].frs_en, 1);
- } else {
- /*
- * Reconnect CC lines to TCPC. Since the FRS GPIO needs to be
- * asserted until VBUS falls below 5V during an FRS, if
- * SYV682X_FLAGS_FRS is set then don't deassert it, instead
- * disable when sourcing is disabled.
- */
- regval |= SYV682X_CONTROL_4_CC1_BPS | SYV682X_CONTROL_4_CC2_BPS;
- write_reg(port, SYV682X_CONTROL_4_REG, regval);
- if (!(flags[port] & SYV682X_FLAGS_FRS))
- gpio_set_level(ppc_chips[port].frs_en, 0);
- }
- return EC_SUCCESS;
-}
-#endif /*CONFIG_USB_PD_FRS_PPC*/
-
-#ifndef CONFIG_USBC_PPC_SYV682X_SMART_DISCHARGE
-static int syv682x_dev_is_connected(int port, enum ppc_device_role dev)
-{
- /*
- * (b:160548079) We disable the smart discharge(SDSG), so we should
- * turn off the discharge FET if a source is connected.
- */
- if (dev == PPC_DEV_SRC)
- return syv682x_discharge_vbus(port, 0);
- else if (dev == PPC_DEV_DISCONNECTED)
- return syv682x_discharge_vbus(port, 1);
-
- return EC_SUCCESS;
-}
-#endif
-
-static bool syv682x_is_sink(uint8_t control_1)
-{
- /*
- * The SYV682 integrates power paths: 5V and HV (high voltage).
- * The SYV682 can source either 5V or HV, but only sinks on the HV path.
- *
- * PD analyzer without a device connected confirms the SYV682 acts as
- * a source under these conditions:
- * HV_DR && !CH_SEL: source 5V
- * HV_DR && CH_SEL: source 15V
- * !HV_DR && !CH_SEL: source 5V
- *
- * The SYV682 is only a sink when !HV_DR && CH_SEL
- */
- if (!(control_1 & SYV682X_CONTROL_1_PWR_ENB)
- && !(control_1 & SYV682X_CONTROL_1_HV_DR)
- && (control_1 & SYV682X_CONTROL_1_CH_SEL))
- return true;
-
- return false;
-}
-
-static int syv682x_init(int port)
-{
- int rv;
- int regval;
- int status, control_1;
- enum tcpc_rp_value initial_current_limit;
-
- rv = read_reg(port, SYV682X_STATUS_REG, &status);
- if (rv)
- return rv;
-
- rv = read_reg(port, SYV682X_CONTROL_1_REG, &control_1);
- if (rv)
- return rv;
- atomic_clear(&sink_ocp_count[port]);
-
- /*
- * Disable FRS prior to configuring the power paths
- */
- if (IS_ENABLED(CONFIG_USB_PD_FRS_PPC))
- gpio_set_level(ppc_chips[port].frs_en, 0);
-
- if (!syv682x_is_sink(control_1)
- || (status & SYV682X_STATUS_VSAFE_0V)) {
- /*
- * Disable both power paths,
- * set HV_ILIM to 3.3A,
- * set 5V_ILIM to 3.3A,
- * set HV direction to sink,
- * select HV channel.
- */
- regval = SYV682X_CONTROL_1_PWR_ENB |
- (CONFIG_SYV682X_HV_ILIM << SYV682X_HV_ILIM_BIT_SHIFT) |
- /* !SYV682X_CONTROL_1_HV_DR */
- SYV682X_CONTROL_1_CH_SEL;
- rv = write_reg(port, SYV682X_CONTROL_1_REG, regval);
- if (rv)
- return rv;
- } else {
- /* Dead battery mode, or an existing PD contract is in place */
- rv = syv682x_vbus_sink_enable(port, 1);
- if (rv)
- return rv;
- }
-
-#ifdef CONFIG_USB_PD_MAX_SINGLE_SOURCE_CURRENT
- initial_current_limit = CONFIG_USB_PD_MAX_SINGLE_SOURCE_CURRENT;
-#else
- initial_current_limit = CONFIG_USB_PD_PULLUP;
-#endif
- rv = syv682x_set_vbus_source_current_limit(port, initial_current_limit);
- if (rv)
- return rv;
-
- /*
- * Set Control Reg 2 to defaults except 50ms smart discharge time.
- * Note: On SYV682A/B, enable smart discharge would block i2c
- * transactions for 50ms (discharge time) and this
- * prevents us from disabling Vconn when stop sourcing Vbus and has
- * tVconnOff (35ms) timeout.
- * On SYV682C, we are allowed to access CONTROL4 while the i2c busy.
- */
- regval = (SYV682X_OC_DELAY_10MS << SYV682X_OC_DELAY_SHIFT)
- | (SYV682X_DSG_RON_200_OHM << SYV682X_DSG_RON_SHIFT)
- | (SYV682X_DSG_TIME_50MS << SYV682X_DSG_TIME_SHIFT);
-
- if (IS_ENABLED(CONFIG_USBC_PPC_SYV682X_SMART_DISCHARGE))
- regval |= SYV682X_CONTROL_2_SDSG;
-
- rv = write_reg(port, SYV682X_CONTROL_2_REG, regval);
- if (rv)
- return rv;
-
- /*
- * Always set the over voltage setting to the maximum to support
- * sinking from a 20V PD charger. The common PPC code doesn't provide
- * any hooks for indicating what the currently negotiated voltage is.
- *
- * Mask Alerts due to Reverse Voltage.
- */
- regval = (SYV682X_OVP_23_7 << SYV682X_OVP_BIT_SHIFT) | SYV682X_RVS_MASK;
- rv = write_reg(port, SYV682X_CONTROL_3_REG, regval);
- if (rv)
- return rv;
-
- /*
- * Remove Rd and connect CC1/CC2 lines to TCPC
- * Disable Vconn
- * Enable CC detection of Fast Role Swap (FRS)
- */
- regval = SYV682X_CONTROL_4_CC1_BPS | SYV682X_CONTROL_4_CC2_BPS;
- rv = write_reg(port, SYV682X_CONTROL_4_REG, regval);
- if (rv)
- return rv;
-
- return EC_SUCCESS;
-}
-
-const struct ppc_drv syv682x_drv = {
- .init = &syv682x_init,
- .is_sourcing_vbus = &syv682x_is_sourcing_vbus,
- .vbus_sink_enable = &syv682x_vbus_sink_enable,
- .vbus_source_enable = &syv682x_vbus_source_enable,
-#ifdef CONFIG_CMD_PPC_DUMP
- .reg_dump = &syv682x_dump,
-#endif /* defined(CONFIG_CMD_PPC_DUMP) */
-#ifdef CONFIG_USB_PD_FRS_PPC
- .set_frs_enable = &syv682x_set_frs_enable,
-#endif
-#ifdef CONFIG_USB_PD_VBUS_DETECT_PPC
- .is_vbus_present = &syv682x_is_vbus_present,
-#endif /* defined(CONFIG_USB_PD_VBUS_DETECT_PPC) */
- .set_vbus_source_current_limit = &syv682x_set_vbus_source_current_limit,
- .discharge_vbus = &syv682x_discharge_vbus,
-#ifndef CONFIG_USBC_PPC_SYV682X_SMART_DISCHARGE
- .dev_is_connected = &syv682x_dev_is_connected,
-#endif /* defined(CONFIG_USBC_PPC_SYV682X_SMART_DISCHARGE) */
-#ifdef CONFIG_USBC_PPC_POLARITY
- .set_polarity = &syv682x_set_polarity,
-#endif
-#ifdef CONFIG_USBC_PPC_VCONN
- .set_vconn = &syv682x_set_vconn,
-#endif
-};
diff --git a/driver/ppc/syv682x.h b/driver/ppc/syv682x.h
deleted file mode 100644
index d9416f47f1..0000000000
--- a/driver/ppc/syv682x.h
+++ /dev/null
@@ -1,112 +0,0 @@
-/* Copyright 2018 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.
- */
-
-/* Silergy SYV682x Type-C Power Path Controller */
-
-#ifndef __CROS_EC_SYV682X_H
-#define __CROS_EC_SYV682X_H
-
-#include "common.h"
-#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
-#define SYV682X_CONTROL_2_REG 0x02
-#define SYV682X_CONTROL_3_REG 0x03
-#define SYV682X_CONTROL_4_REG 0x04
-
-/* Status Register */
-#define SYV682X_STATUS_OC_HV BIT(7)
-#define SYV682X_STATUS_RVS BIT(6)
-#define SYV682X_STATUS_OC_5V BIT(5)
-#define SYV682X_STATUS_OVP BIT(4)
-#define SYV682X_STATUS_FRS BIT(3)
-#define SYV682X_STATUS_TSD BIT(2)
-#define SYV682X_STATUS_VSAFE_5V BIT(1)
-#define SYV682X_STATUS_VSAFE_0V BIT(0)
-#define SYV682X_STATUS_INT_MASK 0xfc
-
-/* Control Register 1 */
-#define SYV682X_CONTROL_1_CH_SEL BIT(1)
-#define SYV682X_CONTROL_1_HV_DR BIT(2)
-#define SYV682X_CONTROL_1_PWR_ENB BIT(7)
-
-#define SYV682X_5V_ILIM_MASK 0x18
-#define SYV682X_5V_ILIM_BIT_SHIFT 3
-#define SYV682X_5V_ILIM_1_25 0
-#define SYV682X_5V_ILIM_1_75 1
-#define SYV682X_5V_ILIM_2_25 2
-#define SYV682X_5V_ILIM_3_30 3
-
-#define SYV682X_HV_ILIM_MASK 0x60
-#define SYV682X_HV_ILIM_BIT_SHIFT 5
-#define SYV682X_HV_ILIM_1_25 0
-#define SYV682X_HV_ILIM_1_75 1
-#define SYV682X_HV_ILIM_3_30 2
-#define SYV682X_HV_ILIM_5_50 3
-
-/* Control Register 2 */
-#define SYV682X_OC_DELAY_MASK GENMASK(7, 6)
-#define SYV682X_OC_DELAY_SHIFT 6
-#define SYV682X_OC_DELAY_1MS 0
-#define SYV682X_OC_DELAY_10MS 1
-#define SYV682X_OC_DELAY_50MS 2
-#define SYV682X_OC_DELAY_100MS 3
-#define SYV682X_DSG_TIME_MASK GENMASK(5, 4)
-#define SYV682X_DSG_TIME_SHIFT 4
-#define SYV682X_DSG_TIME_50MS 0
-#define SYV682X_DSG_TIME_100MS 1
-#define SYV682X_DSG_TIME_200MS 2
-#define SYV682X_DSG_TIME_400MS 3
-#define SYV682X_DSG_RON_MASK GENMASK(3, 2)
-#define SYV682X_DSG_RON_SHIFT 2
-#define SYV682X_DSG_RON_200_OHM 0
-#define SYV682X_DSG_RON_400_OHM 1
-#define SYV682X_DSG_RON_800_OHM 2
-#define SYV682X_DSG_RON_1600_OHM 3
-#define SYV682X_CONTROL_2_SDSG BIT(1)
-#define SYV682X_CONTROL_2_FDSG BIT(0)
-
-/* Control Register 3 */
-#define SYV682X_BUSY BIT(7)
-#define SYV682X_RVS_MASK BIT(3)
-#define SYV682X_RST_REG BIT(0)
-#define SYV682X_OVP_MASK 0x70
-#define SYV682X_OVP_BIT_SHIFT 4
-#define SYV682X_OVP_06_0 0
-#define SYV682X_OVP_08_0 1
-#define SYV682X_OVP_11_1 2
-#define SYV682X_OVP_12_1 3
-#define SYV682X_OVP_14_2 4
-#define SYV682X_OVP_17_9 5
-#define SYV682X_OVP_21_6 6
-#define SYV682X_OVP_23_7 7
-
-/* Control Register 4 */
-#define SYV682X_CONTROL_4_CC1_BPS BIT(7)
-#define SYV682X_CONTROL_4_CC2_BPS BIT(6)
-#define SYV682X_CONTROL_4_VCONN1 BIT(5)
-#define SYV682X_CONTROL_4_VCONN2 BIT(4)
-#define SYV682X_CONTROL_4_VBAT_OVP BIT(3)
-#define SYV682X_CONTROL_4_VCONN_OCP BIT(2)
-#define SYV682X_CONTROL_4_CC_FRS BIT(1)
-#define SYV682X_CONTROL_4_INT_MASK 0x0c
-
-/*
- * syv682x_board_is_syv682c
- *
- * b:160548079 This is a function to workaround that some board revisions
- * might have different SYV682 sub-version.
- *
- * @param port the query port
- * @return 1 if the PPC is SYV682C else 0
- */
-__override_proto int syv682x_board_is_syv682c(int port);
-
-#endif /* defined(__CROS_EC_SYV682X_H) */