summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--board/fusb307bgevb/board.c58
-rw-r--r--board/fusb307bgevb/board.h31
-rw-r--r--board/fusb307bgevb/ec.tasklist4
-rw-r--r--driver/build.mk1
-rw-r--r--driver/tcpm/fusb307.c102
-rw-r--r--driver/tcpm/fusb307.h28
-rw-r--r--include/config.h1
7 files changed, 223 insertions, 2 deletions
diff --git a/board/fusb307bgevb/board.c b/board/fusb307bgevb/board.c
index 9d92b5a560..a872afc7e8 100644
--- a/board/fusb307bgevb/board.c
+++ b/board/fusb307bgevb/board.c
@@ -6,6 +6,7 @@
#include "common.h"
#include "ec_version.h"
+#include "fusb307.h"
#include "gpio.h"
#include "hooks.h"
#include "i2c.h"
@@ -26,6 +27,7 @@
static void tcpc_alert_event(enum gpio_signal signal)
{
+ schedule_deferred_pd_interrupt(0);
}
/******************************************************************************
@@ -151,6 +153,62 @@ const struct i2c_port_t i2c_ports[] = {
const unsigned int i2c_ports_used = ARRAY_SIZE(i2c_ports);
/******************************************************************************
+ * PD
+ */
+const struct tcpc_config_t tcpc_config[CONFIG_USB_PD_PORT_MAX_COUNT] = {
+ {
+ .bus_type = EC_BUS_TYPE_I2C,
+ .i2c_info = {
+ .port = I2C_PORT_TCPC,
+ .addr_flags = FUSB307_I2C_SLAVE_ADDR_FLAGS,
+ },
+ .drv = &fusb307_tcpm_drv,
+ },
+};
+
+
+uint16_t tcpc_get_alert_status(void)
+{
+ uint16_t status = 0;
+
+ if (!gpio_get_level(GPIO_USB_C0_PD_INT_ODL))
+ status |= PD_STATUS_TCPC_ALERT_0;
+
+ return status;
+}
+
+void board_reset_pd_mcu(void)
+{
+}
+
+int pd_snk_is_vbus_provided(int port)
+{
+ return EC_ERROR_UNIMPLEMENTED;
+}
+
+void pd_set_input_current_limit(int port, uint32_t max_ma,
+ uint32_t supply_voltage)
+{
+ /* No battery, nothing to do */
+}
+
+void pd_power_supply_reset(int port)
+{
+ /* Disable VBUS */
+ fusb307_power_supply_reset(port);
+}
+
+int pd_set_power_supply_ready(int port)
+{
+ return EC_SUCCESS;
+}
+
+int pd_board_checks(void)
+{
+ return EC_SUCCESS;
+}
+
+/******************************************************************************
* Initialize board.
*/
static void board_init(void)
diff --git a/board/fusb307bgevb/board.h b/board/fusb307bgevb/board.h
index e920c7efd1..2497dc7c69 100644
--- a/board/fusb307bgevb/board.h
+++ b/board/fusb307bgevb/board.h
@@ -12,6 +12,10 @@
/* 48 MHz SYSCLK clock frequency */
#define CPU_CLOCK 48000000
+/* Debug Congifuation */
+#define DEBUG_GET_CC
+#define DEBUG_ROLE_CTRL_UPDATES
+
/* Enable USART1,3,4 and USB streams */
#define CONFIG_STREAM_USART
#define CONFIG_STREAM_USART1
@@ -34,8 +38,33 @@
#define CONFIG_USB_PID 0x1234
#define CONFIG_USB_CONSOLE
+/* USB Power Delivery configuration */
+#define CONFIG_USB_POWER_DELIVERY
+#define CONFIG_USB_PD_TCPMV1
+#define CONFIG_USB_PD_PORT_MAX_COUNT 1
+#define CONFIG_USB_PD_TCPM_TCPCI
+#define CONFIG_USB_PD_DUAL_ROLE
+#define CONFIG_USB_PD_VBUS_DETECT_TCPC
+#define CONFIG_USB_PD_REV30
+#define CONFIG_USB_PD_DECODE_SOP
+#define CONFIG_USBC_VCONN
+#define CONFIG_USB_PD_DUAL_ROLE_AUTO_TOGGLE
+#define CONFIG_USB_PD_TCPM_FUSB307
+
+/* delay to turn on/off vconn */
+#define PD_VCONN_SWAP_DELAY 5000 /* us */
+/* Define operating power and max power */
+#define PD_OPERATING_POWER_MW 15000
+#define PD_MAX_VOLTAGE_MV 20000
+#define PD_MAX_CURRENT_MA 3000
+#define PD_MAX_POWER_MW ((PD_MAX_VOLTAGE_MV * PD_MAX_CURRENT_MA) / 1000)
+
+/* Degine board specific type-C power constants */
+#define PD_POWER_SUPPLY_TURN_OFF_DELAY 250000 /* us */
+#define PD_POWER_SUPPLY_TURN_ON_DELAY 160000 /* us */
+
/* I2C master port connected to the TCPC */
-#define I2C_PORT_TCPC 0
+#define I2C_PORT_TCPC 1
/* LCD Configuration */
#define LCD_SLAVE_ADDR 0x27
diff --git a/board/fusb307bgevb/ec.tasklist b/board/fusb307bgevb/ec.tasklist
index 0c2a274a1f..e25b8f7a68 100644
--- a/board/fusb307bgevb/ec.tasklist
+++ b/board/fusb307bgevb/ec.tasklist
@@ -8,4 +8,6 @@
*/
#define CONFIG_TASK_LIST \
TASK_ALWAYS(HOOKS, hook_task, NULL, TASK_STACK_SIZE) \
- TASK_ALWAYS(CONSOLE, console_task, NULL, TASK_STACK_SIZE)
+ TASK_ALWAYS(CONSOLE, console_task, NULL, TASK_STACK_SIZE) \
+ TASK_ALWAYS(PD_C0, pd_task, NULL, 1280) \
+ TASK_ALWAYS(PD_INT_C0, pd_interrupt_handler_task, 0, ULTRA_TASK_STACK_SIZE)
diff --git a/driver/build.mk b/driver/build.mk
index 5645c16094..5b1f89605a 100644
--- a/driver/build.mk
+++ b/driver/build.mk
@@ -147,6 +147,7 @@ driver-$(CONFIG_USB_PD_TCPM_TUSB422)+=tcpm/tusb422.o
driver-$(CONFIG_USB_PD_TCPM_RT1715)+=tcpm/rt1715.o
driver-$(CONFIG_USB_PD_TCPM_NCT38XX)+=tcpm/nct38xx.o
driver-$(CONFIG_USB_PD_TCPM_RAA489000)+=tcpm/raa489000.o
+driver-$(CONFIG_USB_PD_TCPM_FUSB307)+=tcpm/fusb307.o
# Type-C Retimer drivers
driver-$(CONFIG_USBC_RETIMER_INTEL_BB)+=retimer/bb_retimer.o
diff --git a/driver/tcpm/fusb307.c b/driver/tcpm/fusb307.c
new file mode 100644
index 0000000000..9a578637a9
--- /dev/null
+++ b/driver/tcpm/fusb307.c
@@ -0,0 +1,102 @@
+/* Copyright 2020 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.
+ */
+
+/* Type-C port manager for Fairchild's FUSB307 */
+
+#include "console.h"
+#include "fusb307.h"
+#include "hooks.h"
+#include "task.h"
+#include "tcpci.h"
+#include "tcpm.h"
+#include "timer.h"
+#include "util.h"
+
+#define CPRINTF(format, args...) cprintf(CC_USBPD, format, ## args)
+#define CPRINTS(format, args...) cprints(CC_USBPD, format, ## args)
+
+int fusb307_power_supply_reset(int port)
+{
+ return tcpc_write(port, TCPC_REG_COMMAND, 0x66);
+}
+
+static int fusb307_tcpm_init(int port)
+{
+ int rv;
+
+ rv = tcpci_tcpm_init(port);
+
+ rv = tcpci_set_role_ctrl(port, 1, TYPEC_RP_USB, TYPEC_CC_RD);
+ pd_set_dual_role(port, PD_DRP_TOGGLE_ON);
+
+ return rv;
+}
+
+int fusb307_tcpm_set_polarity(int port, enum tcpc_cc_polarity polarity)
+{
+ int rv;
+ enum tcpc_cc_voltage_status cc1, cc2;
+
+ rv = tcpci_tcpm_set_polarity(port, polarity);
+
+ tcpm_get_cc(port, &cc1, &cc2);
+ if (cc1) {
+ if (pd_get_power_role(port) == PD_ROLE_SINK) {
+ int role = TCPC_REG_ROLE_CTRL_SET(0,
+ tcpci_get_cached_rp(port), TYPEC_CC_RD, TYPEC_CC_OPEN);
+
+ tcpc_write(port, TCPC_REG_ROLE_CTRL, role);
+ } else {
+ int role = TCPC_REG_ROLE_CTRL_SET(0,
+ tcpci_get_cached_rp(port), TYPEC_CC_RP, TYPEC_CC_OPEN);
+
+ tcpc_write(port, TCPC_REG_ROLE_CTRL, role);
+ }
+ } else if (cc2) {
+ if (pd_get_power_role(port) == PD_ROLE_SINK) {
+ int role = TCPC_REG_ROLE_CTRL_SET(0,
+ tcpci_get_cached_rp(port), TYPEC_CC_OPEN, TYPEC_CC_RD);
+
+ tcpc_write(port, TCPC_REG_ROLE_CTRL, role);
+ } else {
+ int role = TCPC_REG_ROLE_CTRL_SET(0,
+ tcpci_get_cached_rp(port), TYPEC_CC_OPEN, TYPEC_CC_RP);
+
+ tcpc_write(port, TCPC_REG_ROLE_CTRL, role);
+ }
+ } else {
+ if (pd_get_power_role(port) == PD_ROLE_SINK)
+ tcpci_tcpm_set_cc(port, TYPEC_CC_RD);
+ else
+ tcpci_tcpm_set_cc(port, TYPEC_CC_RP);
+ }
+
+ return rv;
+}
+
+const struct tcpm_drv fusb307_tcpm_drv = {
+ .init = &fusb307_tcpm_init,
+ .release = &tcpci_tcpm_release,
+ .get_cc = &tcpci_tcpm_get_cc,
+#ifdef CONFIG_USB_PD_VBUS_DETECT_TCPC
+ .check_vbus_level = &tcpci_tcpm_check_vbus_level,
+#endif
+ .select_rp_value = &tcpci_tcpm_select_rp_value,
+ .set_cc = &tcpci_tcpm_set_cc,
+ .set_polarity = &fusb307_tcpm_set_polarity,
+ .set_vconn = &tcpci_tcpm_set_vconn,
+ .set_msg_header = &tcpci_tcpm_set_msg_header,
+ .set_rx_enable = &tcpci_tcpm_set_rx_enable,
+ .get_message_raw = &tcpci_tcpm_get_message_raw,
+ .transmit = &tcpci_tcpm_transmit,
+ .tcpc_alert = &tcpci_tcpc_alert,
+ .tcpc_enable_auto_discharge_disconnect =
+ &tcpci_tcpc_enable_auto_discharge_disconnect,
+ .get_chip_info = &tcpci_get_chip_info,
+#if defined(CONFIG_USB_PD_DUAL_ROLE_AUTO_TOGGLE)
+ .drp_toggle = &tcpci_tcpc_drp_toggle,
+#endif
+};
+
diff --git a/driver/tcpm/fusb307.h b/driver/tcpm/fusb307.h
new file mode 100644
index 0000000000..943b12d5ed
--- /dev/null
+++ b/driver/tcpm/fusb307.h
@@ -0,0 +1,28 @@
+/* Copyright 2020 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.
+ */
+
+/* USB Power delivery port management */
+/* For Fairchild FUSB307 */
+#ifndef __CROS_EC_FUSB307_H
+#define __CROS_EC_FUSB307_H
+
+#include "usb_pd.h"
+
+#define FUSB307_I2C_SLAVE_ADDR_FLAGS 0x50
+
+#define TCPC_REG_RESET 0xA2
+#define TCPC_REG_RESET_PD_RESET BIT(1)
+#define TCPC_REG_RESET_SW_RESET BIT(0)
+
+#define TCPC_REG_GPIO1_CFG 0xA4
+#define TCPC_REG_GPIO1_CFG_GPO1_VAL BIT(2)
+#define TCPC_REG_GPIO1_CFG_GPI1_EN BIT(1)
+#define TCPC_REG_GPIO1_CFG_GPO1_EN BIT(0)
+
+int fusb307_power_supply_reset(int port);
+
+extern const struct tcpm_drv fusb307_tcpm_drv;
+
+#endif /* __CROS_EC_FUSB307_H */
diff --git a/include/config.h b/include/config.h
index 6cd9c4cd82..bc95e85046 100644
--- a/include/config.h
+++ b/include/config.h
@@ -4136,6 +4136,7 @@
#undef CONFIG_USB_PD_TCPM_TUSB422
#undef CONFIG_USB_PD_TCPM_RAA489000
#undef CONFIG_USB_PD_TCPM_RT1715
+#undef CONFIG_USB_PD_TCPM_FUSB307
/* PS8XXX series are all supported by a single driver with a build time config
* listed below (CONFIG_USB_PD_TCPM_PS*) defined to enable the specific product.