summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRong Chang <rongchang@chromium.org>2017-09-20 06:17:49 +0800
committerchrome-bot <chrome-bot@chromium.org>2017-11-29 04:04:13 -0800
commit6d2066aa3942a62b856d32483cf93772412b132d (patch)
tree2302d84225df95a5cdfcd3c564edd00506dbfcf2
parent96bc7cd9b5fcc45322eb818c6b012c82b13683c3 (diff)
downloadchrome-ec-6d2066aa3942a62b856d32483cf93772412b132d.tar.gz
coffeecake: enable dual role
This change applies the diff between hoho and coffeecake. I2C master configuration is added to control buck-boost converter. BRANCH=none BUG=none TEST=make buildall -j Signed-off-by: Rong Chang <rongchang@chromium.org> Change-Id: Ia700404ccc4e8d2bd8368a823a0cae911257cf7d Reviewed-on: https://chromium-review.googlesource.com/673965 Reviewed-by: Benson Leung <bleung@chromium.org>
-rw-r--r--board/coffeecake/board.c60
-rw-r--r--board/coffeecake/board.h33
-rw-r--r--board/coffeecake/ec.tasklist1
-rw-r--r--board/coffeecake/gpio.inc31
-rw-r--r--board/coffeecake/usb_pd_config.h39
-rw-r--r--board/coffeecake/usb_pd_policy.c56
6 files changed, 182 insertions, 38 deletions
diff --git a/board/coffeecake/board.c b/board/coffeecake/board.c
index 27a5070651..bc44f07a00 100644
--- a/board/coffeecake/board.c
+++ b/board/coffeecake/board.c
@@ -6,11 +6,14 @@
#include "adc.h"
#include "adc_chip.h"
+#include "charger/sy21612.h"
+#include "clock.h"
#include "common.h"
#include "ec_commands.h"
#include "ec_version.h"
#include "gpio.h"
#include "hooks.h"
+#include "i2c.h"
#include "mcdp28x0.h"
#include "registers.h"
#include "task.h"
@@ -26,6 +29,12 @@ static volatile int hpd_prev_level;
void hpd_event(enum gpio_signal signal);
#include "gpio_list.h"
+/* I2C ports */
+const struct i2c_port_t i2c_ports[] = {
+ {"charger", I2C_PORT_SY21612, 400, GPIO_I2C0_SCL, GPIO_I2C0_SDA},
+};
+const unsigned int i2c_ports_used = ARRAY_SIZE(i2c_ports);
+
/**
* Hotplug detect deferred task
*
@@ -93,11 +102,39 @@ void hpd_event(enum gpio_signal signal)
hpd_prev_level = level;
}
+/* USB C VBUS output selection */
+void board_set_usb_output_voltage(int mv)
+{
+ const int ra = 40200;
+ const int rb = 10000;
+ const int rc = 6650;
+ int dac_mv;
+ uint32_t dac_val;
+
+ /* vbat = 1.0 * ra/rb + 1.0 - (vdac - 1.0) * ra/rc */
+ dac_mv = 1000 + (1000 * rc / rb) + ((1000 - mv) * rc / ra);
+ if (dac_mv < 0)
+ dac_mv = 0;
+
+ /* Set voltage Vout=Vdac with Vref = 3.3v */
+ /* TODO: use Vdda instead */
+ dac_val = dac_mv * 4096 / 3300;
+ STM32_DAC_DHR12RD = dac_val | (dac_val << 16);
+}
+
/* Initialize board. */
void board_config_pre_init(void)
{
- /* enable SYSCFG clock */
+ /* Enable SYSCFG clock */
STM32_RCC_APB2ENR |= 1 << 0;
+ /* Enable DAC interface clock. */
+ STM32_RCC_APB1ENR |= (1 << 29);
+ /* Delay 1 APB clock cycle after the clock is enabled */
+ clock_wait_bus_cycles(BUS_APB, 1);
+ /* Start DAC channel 1 & 2 */
+ STM32_DAC_CR = STM32_DAC_CR_EN1 | STM32_DAC_CR_EN2;
+ /* Set 5Vsafe Vdac */
+ board_set_usb_output_voltage(5000);
/* Remap USART DMA to match the USART driver */
STM32_SYSCFG_CFGR1 |= (1 << 9) | (1 << 10);/* Remap USART1 RX/TX DMA */
}
@@ -144,7 +181,6 @@ static void factory_validation_deferred(void)
/* test mcdp via serial to validate function */
if (!mcdp_get_info(&info) && (MCDP_FAMILY(info.family) == 0x0010) &&
(MCDP_CHIPID(info.chipid) == 0x2850)) {
- gpio_set_level(GPIO_MCDP_READY, 1);
pd_log_event(PD_EVENT_VIDEO_CODEC,
PD_LOG_PORT_SIZE(0, sizeof(info)),
0, &info);
@@ -154,6 +190,18 @@ static void factory_validation_deferred(void)
}
DECLARE_DEFERRED(factory_validation_deferred);
+static void board_post_init(void)
+{
+ sy21612_enable_regulator(1);
+ /*
+ * AC powered - DRP SOURCE
+ * DUT powered - DRP SINK
+ */
+ pd_set_dual_role(gpio_get_level(GPIO_AC_PRESENT_L) ?
+ PD_DRP_FORCE_SINK : PD_DRP_FORCE_SOURCE);
+}
+DECLARE_DEFERRED(board_post_init);
+
/* Initialize board. */
static void board_init(void)
{
@@ -166,9 +214,10 @@ static void board_init(void)
hpd_prev_ts = now.val;
gpio_enable_interrupt(GPIO_DP_HPD);
- gpio_set_level(GPIO_STM_READY, 1); /* factory test only */
/* Delay needed to allow HDMI MCU to boot. */
hook_call_deferred(&factory_validation_deferred_data, 200*MSEC);
+ /* Initialize buck-boost converter */
+ hook_call_deferred(&board_post_init_data, 0);
}
DECLARE_HOOK(HOOK_INIT, board_init, HOOK_PRIO_DEFAULT);
@@ -176,7 +225,10 @@ DECLARE_HOOK(HOOK_INIT, board_init, HOOK_PRIO_DEFAULT);
/* ADC channels */
const struct adc_t adc_channels[] = {
/* USB PD CC lines sensing. Converted to mV (3300mV/4096). */
- [ADC_CH_CC1_PD] = {"USB_C_CC1_PD", 3300, 4096, 0, STM32_AIN(1)},
+ [ADC_CH_CC1_PD] = {"USB_C_CC1_PD", 3300, 4096, 0, STM32_AIN(1)},
+ [ADC_VBUS_MON] = {"VBUS_MON", 13200, 4096, 0, STM32_AIN(2)},
+ [ADC_DAC_REF_TP28] = {"DAC_REF_TP28", 3300, 4096, 0, STM32_AIN(4)},
+ [ADC_DAC_VOLT] = {"DAC_VOLT", 3300, 4096, 0, STM32_AIN(5)},
};
BUILD_ASSERT(ARRAY_SIZE(adc_channels) == ADC_CH_COUNT);
diff --git a/board/coffeecake/board.h b/board/coffeecake/board.h
index f7bc554a21..0653253b51 100644
--- a/board/coffeecake/board.h
+++ b/board/coffeecake/board.h
@@ -18,8 +18,13 @@
#define CONFIG_STM_HWTIMER32
#define CONFIG_ADC
#define CONFIG_BOARD_PRE_INIT
+#define CONFIG_CMD_CHARGER
+#define CONFIG_CMD_GPIO_EXTENDED
#define CONFIG_CMD_SPI_FLASH
+#define CONFIG_CHARGER_SY21612
#define CONFIG_HW_CRC
+#define CONFIG_I2C
+#define CONFIG_I2C_MASTER
#define CONFIG_RSA
#define CONFIG_RWSIG
#define CONFIG_RWSIG_TYPE_USBPD1
@@ -75,6 +80,9 @@
/* ADC signal */
enum adc_channel {
ADC_CH_CC1_PD = 0,
+ ADC_VBUS_MON,
+ ADC_DAC_REF_TP28,
+ ADC_DAC_VOLT,
/* Number of ADC channels */
ADC_CH_COUNT
};
@@ -90,15 +98,25 @@ enum usb_strings {
USB_STR_COUNT
};
-/* we are never a source : don't care about power supply */
-#define PD_POWER_SUPPLY_TURN_ON_DELAY 0 /* us */
-#define PD_POWER_SUPPLY_TURN_OFF_DELAY 0 /* us */
+/* 3.0A Rp */
+#define PD_SRC_VNC PD_SRC_3_0_VNC_MV
+#define PD_SRC_RD_THRESHOLD PD_SRC_3_0_RD_THRESH_MV
+
+/* delay necessary for the voltage transition on the power supply */
+/* TODO (code.google.com/p/chrome-os-partner/issues/detail?id=37078)
+ * Need to measure these and adjust for honeybuns.
+ */
+#define PD_POWER_SUPPLY_TURN_ON_DELAY 50000 /* us */
+#define PD_POWER_SUPPLY_TURN_OFF_DELAY 50000 /* us */
/* Define typical operating power and max power */
#define PD_OPERATING_POWER_MW 1000
-#define PD_MAX_POWER_MW 1500
-#define PD_MAX_CURRENT_MA 300
-#define PD_MAX_VOLTAGE_MV 5000
+#define PD_MAX_POWER_MW 60000
+#define PD_MAX_CURRENT_MA 3000
+#define PD_MAX_VOLTAGE_MV 15000
+
+/* Board interfaces */
+void board_set_usb_output_voltage(int mv);
#endif /* !__ASSEMBLER__ */
@@ -112,4 +130,7 @@ enum usb_strings {
#define USB_EP_CONTROL 0
#define USB_EP_COUNT 1
+/* I2C ports */
+#define I2C_PORT_SY21612 0
+
#endif /* __CROS_EC_BOARD_H */
diff --git a/board/coffeecake/ec.tasklist b/board/coffeecake/ec.tasklist
index 5254b70e2b..63a775523d 100644
--- a/board/coffeecake/ec.tasklist
+++ b/board/coffeecake/ec.tasklist
@@ -18,5 +18,6 @@
*/
#define CONFIG_TASK_LIST \
TASK_ALWAYS(HOOKS, hook_task, NULL, TASK_STACK_SIZE) \
+ TASK_ALWAYS(SY21612, sy21612_task, NULL, SMALLER_TASK_STACK_SIZE) \
TASK_ALWAYS(CONSOLE, console_task, NULL, TASK_STACK_SIZE) \
TASK_ALWAYS(PD_C0, pd_task, NULL, LARGER_TASK_STACK_SIZE)
diff --git a/board/coffeecake/gpio.inc b/board/coffeecake/gpio.inc
index cfb689d825..bc0fea43e2 100644
--- a/board/coffeecake/gpio.inc
+++ b/board/coffeecake/gpio.inc
@@ -9,29 +9,44 @@
* Note: Those with interrupt handlers must be declared first. */
GPIO_INT(DP_HPD, PIN(A, 0), GPIO_INT_BOTH, hpd_event)
+GPIO_INT(CHARGER_INT, PIN(C, 13), GPIO_INT_FALLING, sy21612_int)
GPIO(USB_C_CC1_PD, PIN(A, 1), GPIO_ANALOG)
-GPIO(STM_READY, PIN(A, 2), GPIO_OUT_LOW) /* factory test only */
+GPIO(VBUS_DIV4_MON, PIN(A, 2), GPIO_ANALOG)
GPIO(MCDP_RESET_L, PIN(A, 3), GPIO_OUT_HIGH)
-GPIO(PD_DAC_REF, PIN(A, 4), GPIO_ANALOG)
+GPIO(PD_DAC_REF_TP28, PIN(A, 4), GPIO_ANALOG)
+GPIO(DAC_VBUS_VOLT, PIN(A, 5), GPIO_ANALOG)
+GPIO(LED_GREEN, PIN(A, 6), GPIO_OUT_LOW)
+GPIO(LED_BLUE, PIN(A, 7), GPIO_OUT_LOW)
-GPIO(MCDP_READY, PIN(A, 7), GPIO_OUT_LOW) /* factory test only */
GPIO(PD_SBU_ENABLE, PIN(A, 8), GPIO_OUT_LOW)
GPIO(USB_DM, PIN(A, 11), GPIO_ANALOG)
GPIO(USB_DP, PIN(A, 12), GPIO_ANALOG)
-GPIO(PD_CC1_TX_EN, PIN(A, 15), GPIO_OUT_LOW)
+GPIO(PD_DISCHARGE, PIN(A, 13), GPIO_OUT_LOW)
+GPIO(PD_CC1_ODL, PIN(A, 15), GPIO_ODR_LOW)
-GPIO(MCDP_GPIO1, PIN(B, 0), GPIO_INPUT)
-GPIO(MCDP_CONFIG1, PIN(B, 1), GPIO_INPUT)
+GPIO(EN_PP3300, PIN(B, 0), GPIO_OUT_HIGH)
+GPIO(MCU_PB1, PIN(B, 1), GPIO_OUT_LOW)
GPIO(PD_MCDP_SPI_WP_L, PIN(B, 2), GPIO_OUT_LOW)
-GPIO(PD_CC1_TX_DATA, PIN(B, 4), GPIO_OUT_LOW)
+GPIO(PD_CC1_TX_DATA, PIN(B, 4), GPIO_INPUT)
+GPIO(PD_CC1_HOST_HIGH, PIN(B, 5), GPIO_INPUT)
+GPIO(I2C0_SCL, PIN(B, 6), GPIO_INPUT)
+GPIO(I2C0_SDA, PIN(B, 7), GPIO_INPUT)
+GPIO(LED_ORANGE, PIN(B, 9), GPIO_OUT_LOW)
GPIO(PD_MCDP_SPI_CS_L, PIN(B, 12), GPIO_INPUT)
+GPIO(USB_C_VBUS_DET_L, PIN(C, 14), GPIO_INPUT)
+GPIO(AC_PRESENT_L, PIN(C, 15), GPIO_INPUT)
+
+GPIO(EN_PP5000, PIN(F, 0), GPIO_OUT_HIGH)
+GPIO(EN_USB_PD, PIN(F, 1), GPIO_OUT_HIGH)
+
/* Unimplemented signals which we need to emulate for now */
UNIMPLEMENTED(ENTERING_RW)
UNIMPLEMENTED(WP_L)
ALTERNATE(PIN_MASK(B, 0x0008), 0, MODULE_USB_PD, 0) /* SPI1: SCK(PB3) */
-ALTERNATE(PIN_MASK(B, 0x0200), 2, MODULE_USB_PD, 0) /* TIM17_CH1: PB9 */
+ALTERNATE(PIN_MASK(B, 0x0100), 2, MODULE_USB_PD, 0) /* TIM16_CH1: PB9 */
ALTERNATE(PIN_MASK(A, 0x0600), 1, MODULE_UART, GPIO_PULL_UP) /* USART1: PA9/PA10 */
ALTERNATE(PIN_MASK(B, 0x0C00), 4, MODULE_UART, GPIO_PULL_UP) /* USART3: PB10/PB11 */
+ALTERNATE(PIN_MASK(B, 0x00C0), 1, MODULE_I2C, 0) /* I2C MASTER:PB6/7 */
diff --git a/board/coffeecake/usb_pd_config.h b/board/coffeecake/usb_pd_config.h
index 181ccd20c2..2282ea4e4b 100644
--- a/board/coffeecake/usb_pd_config.h
+++ b/board/coffeecake/usb_pd_config.h
@@ -9,7 +9,7 @@
#define __CROS_EC_USB_PD_CONFIG_H
/* Timer selection for baseband PD communication */
-#define TIM_CLOCK_PD_TX_C0 17
+#define TIM_CLOCK_PD_TX_C0 16
#define TIM_CLOCK_PD_RX_C0 1
#define TIM_CLOCK_PD_TX(p) TIM_CLOCK_PD_TX_C0
@@ -80,19 +80,18 @@ static inline void pd_tx_enable(int port, int polarity)
{
/* PB4 is SPI1_MISO */
gpio_set_alternate_function(GPIO_B, 0x0010, 0);
-
- gpio_set_level(GPIO_PD_CC1_TX_EN, 1);
+ /* USB_C_CC1_PD: PA1 output low */
+ gpio_set_flags(GPIO_USB_C_CC1_PD, GPIO_OUTPUT);
+ gpio_set_level(GPIO_USB_C_CC1_PD, 0);
}
/* Put the TX driver in Hi-Z state */
static inline void pd_tx_disable(int port, int polarity)
{
- /* output low on SPI TX (PB4) to disable the FET */
- STM32_GPIO_MODER(GPIO_B) = (STM32_GPIO_MODER(GPIO_B)
- & ~(3 << (2*4)))
- | (1 << (2*4));
+ /* SPI TX (PB4) Hi-Z */
+ gpio_set_flags(GPIO_PD_CC1_TX_DATA, GPIO_INPUT);
/* put the low level reference in Hi-Z */
- gpio_set_level(GPIO_PD_CC1_TX_EN, 0);
+ gpio_set_flags(GPIO_USB_C_CC1_PD, GPIO_ANALOG);
}
static inline void pd_select_polarity(int port, int polarity)
@@ -111,7 +110,17 @@ static inline void pd_tx_init(void)
gpio_config_module(MODULE_USB_PD, 1);
}
-static inline void pd_set_host_mode(int port, int enable) {}
+static inline void pd_set_host_mode(int port, int enable)
+{
+ if (enable) {
+ gpio_set_level(GPIO_PD_CC1_ODL, 1);
+ gpio_set_flags(GPIO_PD_CC1_HOST_HIGH, GPIO_OUTPUT);
+ gpio_set_level(GPIO_PD_CC1_HOST_HIGH, 1);
+ } else {
+ gpio_set_flags(GPIO_PD_CC1_HOST_HIGH, GPIO_INPUT);
+ gpio_set_level(GPIO_PD_CC1_ODL, 0);
+ }
+}
static inline void pd_config_init(int port, uint8_t power_role)
{
@@ -121,8 +130,16 @@ static inline void pd_config_init(int port, uint8_t power_role)
static inline int pd_adc_read(int port, int cc)
{
- /* only one CC line, assume other one is always low */
- return (cc == 0) ? adc_read_channel(ADC_CH_CC1_PD) : 0;
+ if (cc == 0)
+ return adc_read_channel(ADC_CH_CC1_PD);
+ /*
+ * Check HOST_HIGH Rp setting.
+ * Return 3300mV on host mode.
+ */
+ if ((STM32_GPIO_MODER(GPIO_B) & (3 << (2*5))) == (1 << (2*5)))
+ return 3300;
+ else
+ return 0;
}
#endif /* __CROS_EC_USB_PD_CONFIG_H */
diff --git a/board/coffeecake/usb_pd_policy.c b/board/coffeecake/usb_pd_policy.c
index 2b9e9d60d3..e6150dea63 100644
--- a/board/coffeecake/usb_pd_policy.c
+++ b/board/coffeecake/usb_pd_policy.c
@@ -5,6 +5,7 @@
#include "adc.h"
#include "board.h"
+#include "charger/sy21612.h"
#include "common.h"
#include "console.h"
#include "ec_commands.h"
@@ -22,15 +23,28 @@
#define CPRINTF(format, args...) cprintf(CC_USBPD, format, ## args)
#define CPRINTS(format, args...) cprints(CC_USBPD, format, ## args)
-#define PDO_FIXED_FLAGS PDO_FIXED_COMM_CAP
+#define PDO_FIXED_FLAGS (PDO_FIXED_DUAL_ROLE | PDO_FIXED_DATA_SWAP |\
+ PDO_FIXED_COMM_CAP)
-/* Source PDOs */
-const uint32_t pd_src_pdo[] = {};
+
+/* Voltage indexes for the PDOs */
+enum volt_idx {
+ PDO_IDX_5V = 0,
+ PDO_IDX_9V = 1,
+ /* TODO: add PPS support */
+ PDO_IDX_COUNT
+};
+
+/* PDOs */
+const uint32_t pd_src_pdo[] = {
+ [PDO_IDX_5V] = PDO_FIXED(5000, 3000, PDO_FIXED_FLAGS),
+ [PDO_IDX_9V] = PDO_FIXED(9000, 3000, PDO_FIXED_FLAGS),
+};
const int pd_src_pdo_cnt = ARRAY_SIZE(pd_src_pdo);
+BUILD_ASSERT(ARRAY_SIZE(pd_src_pdo) == PDO_IDX_COUNT);
-/* Fake PDOs : we just want our pre-defined voltages */
const uint32_t pd_snk_pdo[] = {
- PDO_FIXED(5000, 500, PDO_FIXED_FLAGS),
+ PDO_FIXED(5000, 1500, PDO_FIXED_FLAGS),
};
const int pd_snk_pdo_cnt = ARRAY_SIZE(pd_snk_pdo);
@@ -52,16 +66,35 @@ int pd_is_valid_input_voltage(int mv)
void pd_transition_voltage(int idx)
{
- /* No operation: sink only */
+ /* TODO: discharge, PPS */
+ switch (idx - 1) {
+ case PDO_IDX_9V:
+ board_set_usb_output_voltage(9000);
+ break;
+ case PDO_IDX_5V:
+ default:
+ board_set_usb_output_voltage(5000);
+ break;
+ }
}
int pd_set_power_supply_ready(int port)
{
+ sy21612_set_sink_mode(1);
+ sy21612_set_vbus_volt(SY21612_VBUS_9V);
+ sy21612_set_adc_mode(1);
+ sy21612_enable_adc(1);
+ sy21612_set_vbus_discharge(1);
return EC_SUCCESS;
}
void pd_power_supply_reset(int port)
{
+ sy21612_set_sink_mode(0);
+ sy21612_set_vbus_volt(SY21612_VBUS_9V);
+ sy21612_set_adc_mode(1);
+ sy21612_enable_adc(1);
+ sy21612_set_vbus_discharge(1);
}
int pd_snk_is_vbus_provided(int port)
@@ -82,21 +115,26 @@ int pd_check_power_swap(int port)
int pd_check_data_swap(int port, int data_role)
{
- /* Always refuse data swap */
- return 0;
+ /* We can swap to UFP */
+ return data_role == PD_ROLE_DFP;
}
void pd_execute_data_swap(int port, int data_role)
{
- /* Do nothing */
+ /* TODO: turn on pp5000, pp3300 */
}
void pd_check_pr_role(int port, int pr_role, int flags)
{
+ if (pr_role == PD_ROLE_UFP && !gpio_get_level(GPIO_AC_PRESENT_L))
+ pd_request_power_swap(port);
+
}
void pd_check_dr_role(int port, int dr_role, int flags)
{
+ if ((flags & PD_FLAGS_PARTNER_DR_DATA) && dr_role == PD_ROLE_DFP)
+ pd_request_data_swap(port);
}
/* ----------------- Vendor Defined Messages ------------------ */
const uint32_t vdo_idh = VDO_IDH(0, /* data caps as USB host */