summaryrefslogtreecommitdiff
path: root/driver/ppc
diff options
context:
space:
mode:
authorJack Rosenthal <jrosenth@chromium.org>2021-11-04 12:11:58 -0600
committerCommit Bot <commit-bot@chromium.org>2021-11-05 04:22:34 +0000
commit252457d4b21f46889eebad61d4c0a65331919cec (patch)
tree01856c4d31d710b20e85a74c8d7b5836e35c3b98 /driver/ppc
parent08f5a1e6fc2c9467230444ac9b582dcf4d9f0068 (diff)
downloadchrome-ec-252457d4b21f46889eebad61d4c0a65331919cec.tar.gz
In the interest of making long-term branch maintenance incur as little technical debt on us as possible, we should not maintain any files on the branch we are not actually using. This has the added effect of making it extremely clear when merging CLs from the main branch when changes have the possibility to affect us. The follow-on CL adds a convenience script to actually pull updates from the main branch and generate a CL for the update. BUG=b:204206272 BRANCH=ish TEST=make BOARD=arcada_ish && make BOARD=drallion_ish Signed-off-by: Jack Rosenthal <jrosenth@chromium.org> Change-Id: I17e4694c38219b5a0823e0a3e55a28d1348f4b18 Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/platform/ec/+/3262038 Reviewed-by: Jett Rink <jettrink@chromium.org> Reviewed-by: Tom Hughes <tomhughes@chromium.org>
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) */