diff options
-rw-r--r-- | driver/build.mk | 1 | ||||
-rw-r--r-- | driver/ppc/aoz1380.c | 115 | ||||
-rw-r--r-- | driver/ppc/aoz1380.h | 44 | ||||
-rw-r--r-- | include/config.h | 5 |
4 files changed, 164 insertions, 1 deletions
diff --git a/driver/build.mk b/driver/build.mk index 5d48edb242..5b82ffc95e 100644 --- a/driver/build.mk +++ b/driver/build.mk @@ -127,6 +127,7 @@ driver-$(CONFIG_USB_MUX_PS8743)+=usb_mux_ps874x.o driver-$(CONFIG_USB_MUX_VIRTUAL)+=usb_mux_virtual.o # Type-C Power Path Controllers (PPC) +driver-$(CONFIG_USBC_PPC_AOZ1380)+=ppc/aoz1380.o driver-$(CONFIG_USBC_PPC_SN5S330)+=ppc/sn5s330.o ifeq ($(CONFIG_USBC_PPC_NX20P3481)$(CONFIG_USBC_PPC_NX20P3483),y) driver-y += ppc/nx20p348x.o diff --git a/driver/ppc/aoz1380.c b/driver/ppc/aoz1380.c new file mode 100644 index 0000000000..708d488e94 --- /dev/null +++ b/driver/ppc/aoz1380.c @@ -0,0 +1,115 @@ +/* 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 "common.h" +#include "console.h" +#include "driver/ppc/aoz1380.h" +#include "hooks.h" +#include "system.h" +#include "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) +static uint8_t flags[CONFIG_USB_PD_PORT_MAX_COUNT]; + +static int aoz1380_init(int port) +{ + flags[port] = 0; + + return EC_SUCCESS; +} + +static int aoz1380_vbus_sink_enable(int port, int enable) +{ + int rv; + + rv = tcpm_set_snk_ctrl(port, enable); + + return rv; +} + +static int aoz1380_vbus_source_enable(int port, int enable) +{ + int rv; + + rv = tcpm_set_src_ctrl(port, enable); + if (rv) + return rv; + + if (enable) + flags[port] |= AOZ1380_FLAGS_SOURCE_ENABLED; + else + flags[port] &= ~AOZ1380_FLAGS_SOURCE_ENABLED; + + return rv; +} + +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 + */ +static void aoz1380_handle_interrupt(int port) +{ + /* + * This is a over current/temperature condition + */ + CPRINTS("C%d: PPC detected Vbus overcurrent/temperature!", port); + pd_handle_overcurrent(port); +} + +static void aoz1380_irq_deferred(void) +{ + int i; + uint32_t pending = atomic_read_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 new file mode 100644 index 0000000000..672be8eb75 --- /dev/null +++ b/driver/ppc/aoz1380.h @@ -0,0 +1,44 @@ +/* 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" + +/** + * 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); + + +struct ppc_drv; +extern const struct ppc_drv aoz1380_drv; + +/** + * 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/include/config.h b/include/config.h index c4d3f6e52f..405e1cec93 100644 --- a/include/config.h +++ b/include/config.h @@ -3371,6 +3371,7 @@ #undef CONFIG_USBC_PPC_POLARITY /* USB Type-C Power Path Controllers (PPC) */ +#undef CONFIG_USBC_PPC_AOZ1380 #undef CONFIG_USBC_PPC_NX20P3481 #undef CONFIG_USBC_PPC_NX20P3483 #undef CONFIG_USBC_PPC_SN5S330 @@ -3908,7 +3909,9 @@ /*****************************************************************************/ /* Define CONFIG_USBC_PPC if board has a USB Type-C Power Path Controller. */ -#if defined(CONFIG_USBC_PPC_SN5S330) || defined(CONFIG_USBC_PPC_NX20P3483) +#if defined(CONFIG_USBC_PPC_AOZ1380) || \ + defined(CONFIG_USBC_PPC_NX20P3483) || \ + defined(CONFIG_USBC_PPC_SN5S330) #define CONFIG_USBC_PPC #endif /* "has a PPC" */ |