diff options
author | Boris Mittelberg <bmbm@google.com> | 2021-11-19 17:40:27 -0800 |
---|---|---|
committer | Commit Bot <commit-bot@chromium.org> | 2021-12-23 20:19:40 +0000 |
commit | 123d960047c8de7287d2bbee13cd4c2db44cdf79 (patch) | |
tree | e27f8b6ebdfb779ee86632049dc36976e2325f65 | |
parent | 57cb4c750e1f0ea74cdf1daba09a0ff741d09cb5 (diff) | |
download | chrome-ec-123d960047c8de7287d2bbee13cd4c2db44cdf79.tar.gz |
ppc: add ktu1125 driver
Initial implementation of KTU1125 PPC driver
BRANCH=none
BUG=b:207178886
TEST=none
Signed-off-by: Boris Mittelberg <bmbm@google.com>
Change-Id: I01b0eda570a1262ecf91b6f1f5e793b8a0465ac0
Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/platform/ec/+/3289470
Reviewed-by: Aseda Aboagye <aaboagye@chromium.org>
-rw-r--r-- | driver/build.mk | 1 | ||||
-rw-r--r-- | driver/ppc/ktu1125.c | 538 | ||||
-rw-r--r-- | driver/ppc/ktu1125.h | 125 | ||||
-rw-r--r-- | include/config.h | 2 | ||||
-rw-r--r-- | include/driver/ppc/ktu1125_public.h | 25 |
5 files changed, 691 insertions, 0 deletions
diff --git a/driver/build.mk b/driver/build.mk index 41eec29de3..2757eb3ceb 100644 --- a/driver/build.mk +++ b/driver/build.mk @@ -209,6 +209,7 @@ driver-y += ppc/nx20p348x.o endif driver-$(CONFIG_USBC_PPC_SYV682X)+=ppc/syv682x.o driver-$(CONFIG_USBC_PPC_NX20P3483)+=ppc/nx20p348x.o +driver-$(CONFIG_USBC_PPC_KTU1125)+=ppc/ktu1125.o # Switchcap driver-$(CONFIG_LN9310)+=ln9310.o diff --git a/driver/ppc/ktu1125.c b/driver/ppc/ktu1125.c new file mode 100644 index 0000000000..72caa068da --- /dev/null +++ b/driver/ppc/ktu1125.c @@ -0,0 +1,538 @@ +/* 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. + */ + +/* Kinetic KTU1125 USB-C Power Path Controller */ + +#include "common.h" +#include "console.h" +#include "ktu1125.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 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); +} + +static int set_field(const int port, const int addr, const int shift, + const int field_length, const int field_to_set) +{ + int val, rv, mask; + + mask = ((1 << field_length) - 1) << shift; + val = (field_to_set << shift) & mask; + + rv = clr_flags(port, addr, mask); + if (rv) + return rv; + + return set_flags(port, addr, val); +} + + +#ifdef CONFIG_CMD_PPC_DUMP +static int ktu1125_dump(int port) +{ + int i; + int data; + + for (i = KTU1125_ID; i <= KTU1125_INT_DATA; i++) { + read_reg(port, i, &data); + CPRINTF("REG %02Xh = 0x%02x\n", i, data); + } + + cflush(); + return EC_SUCCESS; +} +#endif /* defined(CONFIG_CMD_PPC_DUMP) */ + +/* helper */ +static int ktu1125_power_path_control(int port, int enable) +{ + int status = enable ? clr_flags(port, KTU1125_CTRL_SW_CFG, + KTU1125_SW_AB_EN) + : set_flags(port, KTU1125_CTRL_SW_CFG, + KTU1125_SW_AB_EN); + + if (status) { + CPRINTS("ppc p%d: Failed to %s power path", + port, enable ? "enable" : "disable"); + } + + return status; +} + +static int ktu1125_init(int port) +{ + int regval; + int ctrl_sw_cfg = 0; + int set_sw_cfg = 0; + int set_sw2_cfg = 0; + int sysb_clp; + int status; + + CPRINTF("KTU1125 init\n"); + + /* Read and verify KTU1125 Vendor and Chip ID */ + status = read_reg(port, KTU1125_ID, ®val); + + if (status) { + ppc_prints("Failed to read device ID!", port); + return status; + } + + if (regval != KTU1125_VENDOR_DIE_IDS) { + ppc_err_prints("KTU1125 ID mismatch!", port, regval); + return regval; + } + + + /* + * Setting control register CTRL_SW_CFG + */ + + /* Check if VBUS is present and set SW_AB_EN accordingly */ + status = read_reg(port, KTU1125_MONITOR_SNK, ®val); + if (status) { + ppc_err_prints("VBUS present error", port, status); + return 0; + } + + if (regval & KTU1125_SYSA_OK) + ctrl_sw_cfg = KTU1125_SW_AB_EN; + + status = write_reg(port, KTU1125_CTRL_SW_CFG, ctrl_sw_cfg); + if (status) { + ppc_err_prints("Failed to write CTRL_SW_CFG!", port, status); + return status; + } + + /* + * Setting control register SET_SW_CFG + */ + +#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 */ + sysb_clp = KTU1125_SYSB_ILIM_3_30; + break; + + case TYPEC_RP_1A5: + default: + /* Set current limit to ~1.5A */ + sysb_clp = KTU1125_SYSB_ILIM_1_70; + break; + } +#else /* !defined(CONFIG_USB_PD_MAX_SINGLE_SOURCE_CURRENT) */ + /* Default SRC current limit to ~1.5A */ + sysb_clp = KTU1125_SYSB_ILIM_1_70; +#endif /* defined(CONFIG_USB_PD_MAX_SINGLE_SOURCE_CURRENT) */ + + /* Set SYSB Current Limit Protection */ + set_sw_cfg |= sysb_clp << KTU1125_SYSB_CLP_SHIFT; + /* Set VCONN Current Limit Protection. + * Note: might be changed to 600mA in future + */ + set_sw_cfg |= KTU1125_VCONN_ILIM_0_40 << KTU1125_VCONN_CLP_SHIFT; + /* Disable Dead Battery resistance, because CC FETs are ON */ + set_sw_cfg |= KTU1125_RDB_DIS; + + status = write_reg(port, KTU1125_SET_SW_CFG, set_sw_cfg); + if (status) { + ppc_err_prints("Failed to write SET_SW_CFG!", port, status); + return status; + } + + /* + * Setting control register SET_SW2_CFG + */ + + /* Set T_HIC */ + set_sw2_cfg |= (KTU_T_HIC_MS_17 << KTU1125_T_HIC_SHIFT); + /* Set vbus discharge resistance */ + set_sw2_cfg |= (KTU1125_DIS_RES_1400 << KTU1125_DIS_RES_SHIFT); + /* Set Vbus OVP threshold to ~5V */ + set_sw2_cfg |= (KTU1125_SYSB_VLIM_6_00 << KTU1125_OVP_BUS_SHIFT); + + status = write_reg(port, KTU1125_SET_SW2_CFG, set_sw2_cfg); + if (status) { + ppc_err_prints("Failed to write SET_SW2_CFG!", port, status); + return status; + } + + /* + * 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; + + /* + * Enable interrupts + */ + + /* Leave SYSA_OK and FRS masked for SNK group of interrupts */ + regval = KTU1125_SNK_MASK_ALL & ~(KTU1125_SYSA_OK | KTU1125_FR_SWAP); + status = write_reg(port, KTU1125_INTMASK_SNK, regval); + if (status) { + ppc_err_prints("Failed to write INTMASK_SNK!", port, status); + return status; + } + + /* Only leave VBUS_OK masked for SRC group of interrupts */ + regval = KTU1125_SRC_MASK_ALL & ~KTU1125_VBUS_OK; + status = write_reg(port, KTU1125_INTMASK_SRC, regval); + if (status) { + ppc_err_prints("Failed to write INTMASK_SRC!", port, status); + return status; + } + + /* Unmask the entire DATA group of interrupts */ + status = write_reg(port, KTU1125_INTMASK_DATA, KTU1125_DATA_MASK_ALL); + if (status) { + ppc_err_prints("Failed to write INTMASK_DATA!", port, status); + return status; + } + + return EC_SUCCESS; +} + +#ifdef CONFIG_USB_PD_VBUS_DETECT_PPC +static int ktu1125_is_vbus_present(int port) +{ + int regval; + int rv; + + rv = read_reg(port, KTU1125_MONITOR_SNK, ®val); + if (rv) { + ppc_err_prints("VBUS present error", port, rv); + return 0; + } + + return regval & KTU1125_SYSA_OK; +} +#endif /* defined(CONFIG_USB_PD_VBUS_DETECT_PPC) */ + +static int ktu1125_is_sourcing_vbus(int port) +{ + int regval; + int rv; + + rv = read_reg(port, KTU1125_MONITOR_SRC, ®val); + if (rv) { + ppc_err_prints("Sourcing VBUS error", port, rv); + return 0; + } + + return regval & KTU1125_VBUS_OK; +} + +#ifdef CONFIG_USBC_PPC_POLARITY +static int ktu1125_set_polarity(int port, int polarity) +{ + if (polarity) { + /* CC2 active. */ + clr_flags(port, KTU1125_CTRL_SW_CFG, KTU1125_CC2S_VCONN); + return set_flags(port, KTU1125_CTRL_SW_CFG, + KTU1125_CC1S_VCONN); + } + + /* else CC1 active. */ + clr_flags(port, KTU1125_CTRL_SW_CFG, KTU1125_CC1S_VCONN); + return set_flags(port, KTU1125_CTRL_SW_CFG, KTU1125_CC2S_VCONN); +} +#endif + +static int ktu1125_set_vbus_src_current_limit(int port, enum tcpc_rp_value rp) +{ + int regval; + int 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 + */ + switch (rp) { + case TYPEC_RP_3A0: + regval = KTU1125_SYSB_ILIM_3_30; + break; + + case TYPEC_RP_1A5: + regval = KTU1125_SYSB_ILIM_1_70; + break; + + case TYPEC_RP_USB: + default: + regval = KTU1125_SYSB_ILIM_0_6; + break; + }; + + + status = set_field(port, KTU1125_SET_SW_CFG, KTU1125_SYSB_CLP_SHIFT, + KTU1125_SYSB_CLP_LEN, regval); + if (status) + ppc_prints("Failed to set KTU1125_SET_SW_CFG!", port); + + return status; +} + +static int ktu1125_discharge_vbus(int port, int enable) +{ + int status = enable ? set_flags(port, KTU1125_SET_SW2_CFG, + KTU1125_VBUS_DIS_EN) + : clr_flags(port, KTU1125_SET_SW2_CFG, + KTU1125_VBUS_DIS_EN); + + if (status) { + CPRINTS("ppc p%d: Failed to %s vbus discharge", + port, enable ? "enable" : "disable"); + return status; + } + + return EC_SUCCESS; +} + +#ifdef CONFIG_USBC_PPC_VCONN +static int ktu1125_set_vconn(int port, int enable) +{ + int status = enable ? set_flags(port, KTU1125_CTRL_SW_CFG, + KTU1125_VCONN_EN) + : clr_flags(port, KTU1125_CTRL_SW_CFG, + KTU1125_VCONN_EN); + + return status; +} +#endif + +#ifdef CONFIG_USB_PD_FRS_PPC +static int ktu1125_set_frs_enable(int port, int enable) +{ + /* Enable/Disable FR_SWAP Interrupt */ + int status = enable ? clr_flags(port, KTU1125_INTMASK_SNK, + KTU1125_FR_SWAP) + : set_flags(port, KTU1125_INTMASK_SNK, + KTU1125_FR_SWAP); + + if (status) { + ppc_prints("Failed to write KTU1125_INTMASK_SNK!", port); + return status; + } + + /* Set the FRS_EN bit */ + status = enable ? set_flags(port, KTU1125_CTRL_SW_CFG, + KTU1125_FRS_EN) + : clr_flags(port, KTU1125_CTRL_SW_CFG, + KTU1125_FRS_EN); + + return status; +} +#endif + +static int ktu1125_vbus_sink_enable(int port, int enable) +{ + /* Select active sink */ + int rv = clr_flags(port, KTU1125_CTRL_SW_CFG, KTU1125_POW_MODE); + + if (rv) { + ppc_err_prints("Could not select SNK path", port, rv); + return rv; + } + + return ktu1125_power_path_control(port, enable); +} + +static int ktu1125_vbus_source_enable(int port, int enable) +{ + /* Select active source */ + int rv = set_flags(port, KTU1125_CTRL_SW_CFG, KTU1125_POW_MODE); + + if (rv) { + ppc_err_prints("Could not select SRC path", port, rv); + return rv; + } + + return ktu1125_power_path_control(port, enable); +} + +#ifdef CONFIG_USBC_PPC_SBU +static int ktu1125_set_sbu(int port, int enable) +{ + int status = enable ? clr_flags(port, KTU1125_CTRL_SW_CFG, + KTU1125_SBU_SHUT) + : set_flags(port, KTU1125_CTRL_SW_CFG, + KTU1125_SBU_SHUT); + + if (status) { + CPRINTS("ppc p%d: Failed to %s sbu", + port, enable ? "enable" : "disable"); + } + + return status; +} +#endif /* CONFIG_USBC_PPC_SBU */ + +static void ktu1125_handle_interrupt(int port) +{ + int attempt = 0; + + /* + * KTU1135'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 ovp_int_count = 0; + int snk = 0; + int src = 0; + int data = 0; + + attempt++; + if (attempt > 1) + ppc_prints("Could not clear interrupts on first " + "try, retrying", port); + + /* Clear the interrupt by reading all 3 registers */ + read_reg(port, KTU1125_INT_SNK, &snk); + read_reg(port, KTU1125_INT_SRC, &src); + read_reg(port, KTU1125_INT_DATA, &data); + + CPRINTS("ppc p%d: INTERRUPT snk=%02X src=%02X data=%02X", + port, snk, src, data); + + if (snk & KTU1125_FR_SWAP) + pd_got_frs_signal(port); + + if (snk & (KTU1125_SYSA_SCP | + KTU1125_SYSA_OCP | + KTU1125_VBUS_OVP)) { + /* Log and PD reset */ + pd_handle_overcurrent(port); + } + + if (src & (KTU1125_SYSB_CLP | + KTU1125_SYSB_OCP | + KTU1125_SYSB_SCP | + KTU1125_VCONN_CLP | + KTU1125_VCONN_SCP)) { + /* Log and PD reset */ + pd_handle_overcurrent(port); + } + + if (data & (KTU1125_SBU2_OVP | KTU1125_SBU1_OVP)) { + /* Log and PD reset */ + pd_handle_overcurrent(port); + } + + if (data & (KTU1125_CC1_OVP | KTU1125_CC2_OVP)) { + ppc_prints("CC Over Voltage!", port); + /* + * Bug on ktu1125 Rev A: + * OVP interrupts are falsely triggered + * after IC reset (RST_L 0-> 1) + */ + if (ovp_int_count++) + pd_handle_cc_overvoltage(port); + } + } +} + +static void ktu1125_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) + ktu1125_handle_interrupt(i); +} +DECLARE_DEFERRED(ktu1125_irq_deferred); + +void ktu1125_interrupt(int port) +{ + atomic_or(&irq_pending, BIT(port)); + hook_call_deferred(&ktu1125_irq_deferred_data, 0); +} + +const struct ppc_drv ktu1125_drv = { + .init = &ktu1125_init, + .is_sourcing_vbus = &ktu1125_is_sourcing_vbus, + .vbus_sink_enable = &ktu1125_vbus_sink_enable, + .vbus_source_enable = &ktu1125_vbus_source_enable, +#ifdef CONFIG_USBC_PPC_POLARITY + .set_polarity = &ktu1125_set_polarity, +#endif + .set_vbus_source_current_limit = &ktu1125_set_vbus_src_current_limit, + .discharge_vbus = &ktu1125_discharge_vbus, +#ifdef CONFIG_USBC_PPC_SBU + .set_sbu = &ktu1125_set_sbu, +#endif +#ifdef CONFIG_USBC_PPC_VCONN + .set_vconn = &ktu1125_set_vconn, +#endif +#ifdef CONFIG_USB_PD_FRS_PPC + .set_frs_enable = &ktu1125_set_frs_enable, +#endif +#ifdef CONFIG_CMD_PPC_DUMP + .reg_dump = &ktu1125_dump, +#endif +#ifdef CONFIG_USB_PD_VBUS_DETECT_PPC + .is_vbus_present = &ktu1125_is_vbus_present, +#endif + .interrupt = &ktu1125_interrupt, +}; diff --git a/driver/ppc/ktu1125.h b/driver/ppc/ktu1125.h new file mode 100644 index 0000000000..826c6a925e --- /dev/null +++ b/driver/ppc/ktu1125.h @@ -0,0 +1,125 @@ +/* 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. + */ + +/* Kinetic KTU1125 Type-C Power Path Controller */ + +#ifndef __CROS_EC_KTU1125_H +#define __CROS_EC_KTU1125_H + +#include "common.h" + +#include "driver/ppc/ktu1125_public.h" + +#define KTU1125_ID 0x0 +#define KTU1125_CTRL_SW_CFG 0x1 +#define KTU1125_SET_SW_CFG 0x2 +#define KTU1125_SET_SW2_CFG 0x3 +#define KTU1125_MONITOR_SNK 0x4 +#define KTU1125_MONITOR_SRC 0x5 +#define KTU1125_MONITOR_DATA 0x6 +#define KTU1125_INTMASK_SNK 0x7 +#define KTU1125_INTMASK_SRC 0x8 +#define KTU1125_INTMASK_DATA 0x9 +#define KTU1125_INT_SNK 0xA +#define KTU1125_INT_SRC 0xB +#define KTU1125_INT_DATA 0xC + +/* KTU1125_ID default value */ +#define KTU1125_VENDOR_DIE_IDS 0xA5 + +/* KTU1125_CTRL_SW_CFG bits */ +#define KTU1125_SBU_SHUT BIT(0) +#define KTU1125_VCONN_EN BIT(1) +#define KTU1125_CC2S_VCONN BIT(2) +#define KTU1125_CC1S_VCONN BIT(3) +#define KTU1125_POW_MODE BIT(4) +#define KTU1125_SW_AB_EN BIT(5) +#define KTU1125_FRS_EN BIT(6) +#define KTU1125_EN_L BIT(7) + +/* KTU1125_SET_SW_CFG bits and fields */ +#define KTU1125_RDB_DIS BIT(0) +#define KTU1125_SS_CLP_SNK BIT(1) +#define KTU1125_TDON BIT(2) +#define KTU1125_VCONN_CLP_SHIFT 3 +#define KTU1125_VCONN_CLP_LEN 2 +#define KTU1125_SYSB_CLP_SHIFT 5 +#define KTU1125_SYSB_CLP_LEN 3 + +/* VBUS Switch Current Limit Settings - SYSB_CLP */ +#define KTU1125_SYSB_ILIM_0_6 0 +#define KTU1125_SYSB_ILIM_1_05 1 +#define KTU1125_SYSB_ILIM_1_70 2 +#define KTU1125_SYSB_ILIM_3_30 3 +#define KTU1125_SYSB_ILIM_3_60 4 + +/* VCONN Current Limit Settings - VCONN_CLP */ +#define KTU1125_VCONN_ILIM_0_40 0 +#define KTU1125_VCONN_ILIM_0_60 1 +#define KTU1125_VCONN_ILIM_1_00 2 +#define KTU1125_VCONN_ILIM_1_40 3 + +/* KTU1125_SET_SW2_CFG bits and fields */ +#define KTU1125_OVP_BUS_SHIFT 0 +#define KTU1125_OVP_BUS_LEN 3 +#define KTU1125_DIS_RES_SHIFT 3 +#define KTU1125_DIS_RES_LEN 2 +#define KTU1125_VBUS_DIS_EN BIT(5) +#define KTU1125_T_HIC_SHIFT 6 +#define KTU1125_T_HIC_LEN 2 + +/* VBUS Over Voltage Protection */ +#define KTU1125_SYSB_VLIM_25_00 0 +#define KTU1125_SYSB_VLIM_17_00 4 +#define KTU1125_SYSB_VLIM_13_75 5 +#define KTU1125_SYSB_VLIM_10_60 6 +#define KTU1125_SYSB_VLIM_6_00 7 + +/* Discharge resistor [ohms] */ +#define KTU1125_DIS_RES_1400 0 +#define KTU1125_DIS_RES_730 1 +#define KTU1125_DIS_RES_570 2 +#define KTU1125_DIS_RES_205 3 + +/* T _HIC values [ms] */ +#define KTU_T_HIC_MS_17 0 +#define KTU_T_HIC_MS_34 1 +#define KTU_T_HIC_MS_51 2 +#define KTU_T_HIC_MS_68 3 + +/* Bits for MONITOR/INTMASK/INT SNK */ +#define KTU1125_SS_FAIL BIT(0) +#define KTU1125_OTP BIT(1) +#define KTU1125_FR_SWAP BIT(2) +#define KTU1125_SYSA_SCP BIT(3) +#define KTU1125_SYSA_OCP BIT(4) +#define KTU1125_VBUS_OVP BIT(5) +#define KTU1125_VBUS_UVLO BIT(6) +#define KTU1125_SYSA_OK BIT(7) +#define KTU1125_SNK_MASK_ALL 0xFF + +/* Bits for MONITOR/INTMASK/INT SRC */ +#define KTU1125_VCONN_SCP BIT(0) +#define KTU1125_VCONN_CLP BIT(1) +#define KTU1125_VCONN_UVLO BIT(2) +#define KTU1125_SYSB_SCP BIT(3) +#define KTU1125_SYSB_OCP BIT(4) +#define KTU1125_SYSB_CLP BIT(5) +#define KTU1125_SYSB_UVLO BIT(6) +#define KTU1125_VBUS_OK BIT(7) +#define KTU1125_SRC_MASK_ALL 0xFF + +/* Bits for MONITOR/INTMASK/INT DATA */ +#define KTU1125_SBUB BIT(0) +#define KTU1125_SBUA BIT(1) +#define KTU1125_SBU2_OVP BIT(2) +#define KTU1125_SBU1_OVP BIT(3) +#define KTU1125_CC2_OVP BIT(4) +#define KTU1125_CC1_OVP BIT(5) +#define KTU1125_CC2S_CLAMP BIT(6) +#define KTU1125_CC1S_CLAMP BIT(7) +#define KTU1125_DATA_MASK_ALL 0xFC + +#endif /* defined(__CROS_EC_KTU1125_H) */ diff --git a/include/config.h b/include/config.h index e823a87208..aa5f7bc69c 100644 --- a/include/config.h +++ b/include/config.h @@ -4894,6 +4894,7 @@ /* USB Type-C Power Path Controllers (PPC) */ #undef CONFIG_USBC_PPC_AOZ1380 +#undef CONFIG_USBC_PPC_KTU1125 #undef CONFIG_USBC_PPC_NX20P3481 #undef CONFIG_USBC_PPC_NX20P3483 #undef CONFIG_USBC_PPC_RT1718S @@ -5920,6 +5921,7 @@ /*****************************************************************************/ /* Define CONFIG_USBC_OCP if a component can detect overcurrent */ #if defined(CONFIG_USBC_PPC_AOZ1380) || \ + defined(CONFIG_USBC_PPC_KTU1125) || \ defined(CONFIG_USBC_PPC_NX20P3481) || \ defined(CONFIG_USBC_PPC_NX20P3483) || \ defined(CONFIG_USBC_PPC_SN5S330) || \ diff --git a/include/driver/ppc/ktu1125_public.h b/include/driver/ppc/ktu1125_public.h new file mode 100644 index 0000000000..276f8c9a99 --- /dev/null +++ b/include/driver/ppc/ktu1125_public.h @@ -0,0 +1,25 @@ +/* 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. + */ + +/* Kinetic KTU1125 USB-C Power Path Controller */ + +#ifndef __CROS_EC_DRIVER_PPC_KTU1125_PUBLIC_H +#define __CROS_EC_DRIVER_PPC_KTU1125_PUBLIC_H + +#define KTU1125_ADDR0_FLAGS 0x78 +#define KTU1125_ADDR1_FLAGS 0x79 +#define KTU1125_ADDR2_FLAGS 0x7A +#define KTU1125_ADDR3_FLAGS 0x7B + +extern const struct ppc_drv ktu1125_drv; + +/** + * Interrupt Handler for the KTU1125. + * + * @param port: The Type-C port which triggered the interrupt. + */ +void ktu1125_interrupt(int port); + +#endif /* __CROS_EC_DRIVER_PPC_KTU1125_PUBLIC_H */ |