summaryrefslogtreecommitdiff
path: root/board/pdeval-stm32f072
diff options
context:
space:
mode:
authorDylan Lai <dylai@analogixsemi.com>2018-03-09 13:54:08 +0800
committerchrome-bot <chrome-bot@chromium.org>2018-04-03 21:40:51 -0700
commit82a357a385f9eee75bfbca9911e404d54b0c3217 (patch)
tree7509a8b541a6541b1d56fce2a5d9008a9c4323c9 /board/pdeval-stm32f072
parenta9c7d6b0d73eaf0c48438124b40fc054183701aa (diff)
downloadchrome-ec-82a357a385f9eee75bfbca9911e404d54b0c3217.tar.gz
TCPM: Add TCPM driver for Analogix anx7447 chip
Driver implements TCPC for ANX7447 chip. Enable Type C port for USB and DP alt mode. BUG=b:73793947 BRANCH=NONE TEST=tested compiled binary for pdeval-stm32f072 board with this patch. Power contract establishment, port role swap, DP alt mode works fine. Change-Id: Ic11e499fc5fb4aba7732c75e4cb2fee54828c616 Reviewed-on: https://chromium-review.googlesource.com/956790 Commit-Ready: Scott Collyer <scollyer@chromium.org> Tested-by: Scott Collyer <scollyer@chromium.org> Reviewed-by: Scott Collyer <scollyer@chromium.org>
Diffstat (limited to 'board/pdeval-stm32f072')
-rw-r--r--board/pdeval-stm32f072/board.c11
-rw-r--r--board/pdeval-stm32f072/board.h22
-rw-r--r--board/pdeval-stm32f072/ec.tasklist3
-rw-r--r--board/pdeval-stm32f072/gpio.inc3
-rw-r--r--board/pdeval-stm32f072/usb_pd_policy.c128
5 files changed, 144 insertions, 23 deletions
diff --git a/board/pdeval-stm32f072/board.c b/board/pdeval-stm32f072/board.c
index f5aa26d10b..a306d853ac 100644
--- a/board/pdeval-stm32f072/board.c
+++ b/board/pdeval-stm32f072/board.c
@@ -4,6 +4,7 @@
*/
/* STM32F072-discovery board based USB PD evaluation configuration */
+#include "anx7447.h"
#include "common.h"
#include "ec_version.h"
#include "gpio.h"
@@ -52,15 +53,12 @@ void board_reset_pd_mcu(void)
/* I2C ports */
const struct i2c_port_t i2c_ports[] = {
- {"tcpc", I2C_PORT_TCPC, 100 /* kHz */, GPIO_I2C0_SCL, GPIO_I2C0_SDA}
+ {"tcpc", I2C_PORT_TCPC, 400 /* kHz */, GPIO_I2C0_SCL, GPIO_I2C0_SDA}
};
const unsigned int i2c_ports_used = ARRAY_SIZE(i2c_ports);
const struct tcpc_config_t tcpc_config[CONFIG_USB_PD_PORT_COUNT] = {
- {I2C_PORT_TCPC, TCPC1_I2C_ADDR, &tcpci_tcpm_drv},
-#if CONFIG_USB_PD_PORT_COUNT >= 2
- {I2C_PORT_TCPC, TCPC2_I2C_ADDR, &tcpci_tcpm_drv},
-#endif
+ {I2C_PORT_TCPC, AN7447_TCPC3_I2C_ADDR, &anx7447_tcpm_drv}
};
uint16_t tcpc_get_alert_status(void)
@@ -69,9 +67,6 @@ uint16_t tcpc_get_alert_status(void)
if (!gpio_get_level(GPIO_PD_MCU_INT)) {
status = PD_STATUS_TCPC_ALERT_0;
-#if CONFIG_USB_PD_PORT_COUNT >= 2
- status |= PD_STATUS_TCPC_ALERT_1;
-#endif
}
return status;
diff --git a/board/pdeval-stm32f072/board.h b/board/pdeval-stm32f072/board.h
index df32ec2683..9100ab1a94 100644
--- a/board/pdeval-stm32f072/board.h
+++ b/board/pdeval-stm32f072/board.h
@@ -26,12 +26,21 @@
#define CONFIG_USB_PD_ALT_MODE_DFP
#define CONFIG_USB_PD_CUSTOM_VDM
#define CONFIG_USB_PD_DUAL_ROLE
-#define CONFIG_USB_PD_PORT_COUNT 2
+#define CONFIG_USB_PD_PORT_COUNT 1
#define CONFIG_USB_PD_TCPM_TCPCI
+#define CONFIG_USB_PD_VBUS_DETECT_TCPC
+#define CONFIG_USB_PD_TCPM_ANX7447
+#define CONFIG_USB_PD_TCPM_MUX
+
+#undef CONFIG_USB_PD_INITIAL_DRP_STATE
+#define CONFIG_USB_PD_INITIAL_DRP_STATE PD_DRP_TOGGLE_ON
+
+#undef CONFIG_USB_PD_PULLUP
+#define CONFIG_USB_PD_PULLUP TYPEC_RP_USB
/* fake board specific type-C power constants */
#define PD_POWER_SUPPLY_TURN_ON_DELAY 30000 /* us */
-#define PD_POWER_SUPPLY_TURN_OFF_DELAY 250000 /* us */
+#define PD_POWER_SUPPLY_TURN_OFF_DELAY 650000 /* us */
/* Define typical operating power and max power */
#define PD_OPERATING_POWER_MW 15000
@@ -43,12 +52,13 @@
#define I2C_PORT_TCPC 0
#define I2C_PORT_PD_MCU 0
-/* TCPC I2C slave addresses */
-#define TCPC1_I2C_ADDR 0x9c
-#define TCPC2_I2C_ADDR 0x9e
-
/* Timer selection */
+#define CONFIG_USBC_VCONN
+#define CONFIG_USBC_VCONN_SWAP
+/* delay to turn on/off vconn */
+#define PD_VCONN_SWAP_DELAY 5000 /* us */
+
/* USB Configuration */
#define CONFIG_USB
#define CONFIG_USB_PID 0x500f
diff --git a/board/pdeval-stm32f072/ec.tasklist b/board/pdeval-stm32f072/ec.tasklist
index fd87fc0237..f58f5e3a7c 100644
--- a/board/pdeval-stm32f072/ec.tasklist
+++ b/board/pdeval-stm32f072/ec.tasklist
@@ -20,5 +20,4 @@
TASK_ALWAYS(HOOKS, hook_task, NULL, TASK_STACK_SIZE) \
TASK_NOTEST(PDCMD, pd_command_task,NULL, TASK_STACK_SIZE) \
TASK_ALWAYS(CONSOLE, console_task, NULL, TASK_STACK_SIZE) \
- TASK_ALWAYS(PD_C0, pd_task, NULL, LARGER_TASK_STACK_SIZE) \
- TASK_ALWAYS(PD_C1, pd_task, NULL, LARGER_TASK_STACK_SIZE)
+ TASK_ALWAYS(PD_C0, pd_task, NULL, LARGER_TASK_STACK_SIZE)
diff --git a/board/pdeval-stm32f072/gpio.inc b/board/pdeval-stm32f072/gpio.inc
index cd3c601a0a..f71d69441e 100644
--- a/board/pdeval-stm32f072/gpio.inc
+++ b/board/pdeval-stm32f072/gpio.inc
@@ -16,6 +16,9 @@ GPIO(LED_U, PIN(C, 6), GPIO_OUT_LOW)
GPIO(LED_D, PIN(C, 7), GPIO_OUT_LOW)
GPIO(LED_L, PIN(C, 8), GPIO_OUT_LOW)
GPIO(LED_R, PIN(C, 9), GPIO_OUT_LOW)
+GPIO(USB_C0_DVDDIO, PIN(C, 14), GPIO_OUT_HIGH)
+GPIO(USB_C0_AVDD33, PIN(C, 15), GPIO_OUT_HIGH)
+GPIO(VBUS_PMIC_CTRL, PIN(A, 4), GPIO_OUT_LOW)
/*
* I2C pins should be configured as inputs until I2C module is
diff --git a/board/pdeval-stm32f072/usb_pd_policy.c b/board/pdeval-stm32f072/usb_pd_policy.c
index 73add50ca4..9b81222d58 100644
--- a/board/pdeval-stm32f072/usb_pd_policy.c
+++ b/board/pdeval-stm32f072/usb_pd_policy.c
@@ -3,6 +3,7 @@
* found in the LICENSE file.
*/
+#include "anx7447.h"
#include "common.h"
#include "console.h"
#include "gpio.h"
@@ -12,6 +13,7 @@
#include "task.h"
#include "timer.h"
#include "util.h"
+#include "usb_mux.h"
#include "usb_pd.h"
#define CPRINTF(format, args...) cprintf(CC_USBPD, format, ## args)
@@ -23,15 +25,25 @@
static int vbus_present;
const uint32_t pd_src_pdo[] = {
- PDO_FIXED(5000, 1500, PDO_FIXED_FLAGS),
+ PDO_FIXED(5000, 3000, PDO_FIXED_FLAGS),
};
const int pd_src_pdo_cnt = ARRAY_SIZE(pd_src_pdo);
const uint32_t pd_snk_pdo[] = {
- PDO_FIXED(5000, 500, PDO_FIXED_FLAGS),
+ PDO_FIXED(5000, 900, PDO_FIXED_FLAGS),
+ PDO_BATT(5000, 21000, 30000),
};
const int pd_snk_pdo_cnt = ARRAY_SIZE(pd_snk_pdo);
+#if defined(CONFIG_USB_PD_TCPM_MUX) && defined(CONFIG_USB_PD_TCPM_ANX7447)
+struct usb_mux usb_muxes[CONFIG_USB_PD_PORT_COUNT] = {
+ {
+ .port_addr = 0,
+ .driver = &anx7447_usb_mux_driver,
+ },
+};
+#endif
+
int pd_is_valid_input_voltage(int mv)
{
return 1;
@@ -42,6 +54,34 @@ void pd_transition_voltage(int idx)
/* No-operation: we are always 5V */
}
+#ifdef CONFIG_USB_PD_TCPM_ANX7447
+int pd_set_power_supply_ready(int port)
+{
+ /* Disable charging */
+ anx7447_board_charging_enable(port, 0);
+
+ /* Provide VBUS */
+ gpio_set_level(GPIO_VBUS_PMIC_CTRL, 1);
+ anx7447_set_power_supply_ready(port);
+
+ /* notify host of power info change */
+
+ CPRINTS("Enable VBUS, port%d", port);
+
+ return EC_SUCCESS;
+}
+
+void pd_power_supply_reset(int port)
+{
+ /* Disable VBUS */
+ anx7447_power_supply_reset(port);
+ gpio_set_level(GPIO_VBUS_PMIC_CTRL, 0);
+ CPRINTS("Disable VBUS, port%d", port);
+
+ /* Enable charging */
+ anx7447_board_charging_enable(port, 1);
+}
+#else
int pd_set_power_supply_ready(int port)
{
/* Turn on the "up" LED when we output VBUS */
@@ -57,6 +97,7 @@ void pd_power_supply_reset(int port)
/* Disable VBUS */
CPRINTS("Disable VBUS", port);
}
+#endif /* CONFIG_USB_PD_TCPM_ANX7447 */
void pd_set_input_current_limit(int port, uint32_t max_ma,
uint32_t supply_voltage)
@@ -117,7 +158,7 @@ int pd_check_power_swap(int port)
* otherwise assume our role is fixed (not in S0 or console command
* to fix our role).
*/
- return pd_get_dual_role() == PD_DRP_TOGGLE_ON ? 1 : 0;
+ return pd_get_dual_role() == PD_DRP_TOGGLE_ON;
}
int pd_check_data_swap(int port, int data_role)
@@ -126,6 +167,18 @@ int pd_check_data_swap(int port, int data_role)
return 1;
}
+#ifdef CONFIG_USBC_VCONN_SWAP
+int pd_check_vconn_swap(int port)
+{
+ /*
+ * Allow vconn swap as long as we are acting as a dual role device,
+ * otherwise assume our role is fixed (not in S0 or console command
+ * to fix our role).
+ */
+ return pd_get_dual_role() == PD_DRP_TOGGLE_ON;
+}
+#endif
+
void pd_execute_data_swap(int port, int data_role)
{
}
@@ -138,8 +191,24 @@ void pd_check_dr_role(int port, int dr_role, int flags)
{
}
/* ----------------- Vendor Defined Messages ------------------ */
+const uint32_t vdo_idh = VDO_IDH(1, /* data caps as USB host */
+ 0, /* data caps as USB device */
+ IDH_PTYPE_PERIPH,
+ 0, /* supports alt modes */
+ 0x0000);
+
+const uint32_t vdo_product = VDO_PRODUCT(0x0000, 0x0000);
+
+static int svdm_response_identity(int port, uint32_t *payload)
+{
+ payload[VDO_I(IDH)] = vdo_idh;
+ payload[VDO_I(CSTAT)] = VDO_CSTAT(0);
+ payload[VDO_I(PRODUCT)] = vdo_product;
+ return VDO_I(PRODUCT) + 1;
+}
+
const struct svdm_response svdm_rsp = {
- .identity = NULL,
+ .identity = &svdm_response_identity,
.svids = NULL,
.modes = NULL,
};
@@ -186,6 +255,7 @@ int pd_custom_vdm(int port, int cnt, uint32_t *payload,
#ifdef CONFIG_USB_PD_ALT_MODE_DFP
static int dp_flags[CONFIG_USB_PD_PORT_COUNT];
+static uint32_t dp_status[CONFIG_USB_PD_PORT_COUNT];
static void svdm_safe_dp_mode(int port)
{
@@ -224,24 +294,66 @@ static int svdm_dp_status(int port, uint32_t *payload)
static int svdm_dp_config(int port, uint32_t *payload)
{
int opos = pd_alt_mode(port, USB_SID_DISPLAYPORT);
+ int pin_mode = pd_dfp_dp_get_pin_mode(port, dp_status[port]);
+
+#ifdef CONFIG_USB_PD_TCPM_ANX7447
+ mux_state_t mux_state = TYPEC_MUX_NONE;
+ if (pd_get_polarity(port))
+ mux_state |= MUX_POLARITY_INVERTED;
+#endif
+
+ CPRINTS("pin_mode = %d\n", pin_mode);
+ if (!pin_mode)
+ return 0;
+
+#if defined(CONFIG_USB_PD_TCPM_MUX) && defined(CONFIG_USB_PD_TCPM_ANX7447)
+ switch (pin_mode) {
+ case MODE_DP_PIN_A:
+ case MODE_DP_PIN_C:
+ case MODE_DP_PIN_E:
+ mux_state |= TYPEC_MUX_DP;
+ usb_muxes[port].driver->set(port, mux_state);
+ break;
+ case MODE_DP_PIN_B:
+ case MODE_DP_PIN_D:
+ case MODE_DP_PIN_F:
+ mux_state |= TYPEC_MUX_DOCK;
+ usb_muxes[port].driver->set(port, mux_state);
+ break;
+ }
+#endif
+
/* board_set_usb_mux(port, TYPEC_MUX_DP, pd_get_polarity(port)); */
payload[0] = VDO(USB_SID_DISPLAYPORT, 1,
CMD_DP_CONFIG | VDO_OPOS(opos));
- payload[1] = VDO_DP_CFG(MODE_DP_PIN_E, /* pin mode */
+ payload[1] = VDO_DP_CFG(pin_mode, /* pin mode */
1, /* DPv1.3 signaling */
2); /* UFP connected */
return 2;
-};
+}
static void svdm_dp_post_config(int port)
{
dp_flags[port] |= DP_FLAGS_DP_ON;
if (!(dp_flags[port] & DP_FLAGS_HPD_HI_PENDING))
return;
+
+#ifdef CONFIG_USB_PD_TCPM_ANX7447
+ anx7447_tcpc_update_hpd_status(port, 1, 0);
+#endif
}
static int svdm_dp_attention(int port, uint32_t *payload)
{
+#ifdef CONFIG_USB_PD_TCPM_ANX7447
+ int lvl = PD_VDO_DPSTS_HPD_LVL(payload[1]);
+ int irq = PD_VDO_DPSTS_HPD_IRQ(payload[1]);
+
+ CPRINTS("Attention: 0x%x\n", payload[1]);
+ anx7447_tcpc_update_hpd_status(port, lvl, irq);
+#endif
+ dp_status[port] = payload[1];
+
/* ack */
return 1;
}
@@ -249,7 +361,9 @@ static int svdm_dp_attention(int port, uint32_t *payload)
static void svdm_exit_dp_mode(int port)
{
svdm_safe_dp_mode(port);
- /* gpio_set_level(PORT_TO_HPD(port), 0); */
+#ifdef CONFIG_USB_PD_TCPM_ANX7447
+ anx7447_tcpc_clear_hpd_status(port);
+#endif
}
static int svdm_enter_gfu_mode(int port, uint32_t mode_caps)