summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--driver/build.mk1
-rw-r--r--driver/ppc/aoz1380.c115
-rw-r--r--driver/ppc/aoz1380.h44
-rw-r--r--include/config.h5
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" */