diff options
Diffstat (limited to 'board/servo_v4')
-rw-r--r-- | board/servo_v4/board.c | 576 | ||||
-rw-r--r-- | board/servo_v4/board.h | 277 | ||||
-rw-r--r-- | board/servo_v4/build.mk | 19 | ||||
-rw-r--r-- | board/servo_v4/ec.tasklist | 13 | ||||
-rw-r--r-- | board/servo_v4/gpio.inc | 81 | ||||
-rw-r--r-- | board/servo_v4/usb_pd_config.h | 288 | ||||
-rw-r--r-- | board/servo_v4/usb_pd_policy.c | 1419 | ||||
-rw-r--r-- | board/servo_v4/vif_override.xml | 3 |
8 files changed, 0 insertions, 2676 deletions
diff --git a/board/servo_v4/board.c b/board/servo_v4/board.c deleted file mode 100644 index 8540de710f..0000000000 --- a/board/servo_v4/board.c +++ /dev/null @@ -1,576 +0,0 @@ -/* Copyright 2016 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. - */ -/* Servo V4 configuration */ - -#include "adc.h" -#include "common.h" -#include "console.h" -#include "ec_version.h" -#include "gpio.h" -#include "hooks.h" -#include "i2c.h" -/* Just want the .h file for PS8742 definitions, not the large object file. */ -#define CONFIG_USB_MUX_PS8742 -#include "ps8740.h" -#undef CONFIG_USB_MUX_PS8742 -#include "queue_policies.h" -#include "registers.h" -#include "spi.h" -#include "system.h" -#include "task.h" -#include "timer.h" -#include "update_fw.h" -#include "usart-stm32f0.h" -#include "usart_tx_dma.h" -#include "usart_rx_dma.h" -#include "usb_gpio.h" -#include "usb_i2c.h" -#include "usb_pd.h" -#include "usb_pd_config.h" -#include "usb_spi.h" -#include "usb-stream.h" -#include "util.h" - -#define CPRINTS(format, args...) cprints(CC_SYSTEM, format, ## args) -#define CPRINTF(format, args...) cprintf(CC_SYSTEM, format, ## args) - -/****************************************************************************** - * GPIO interrupt handlers. - */ - -static void vbus0_evt(enum gpio_signal signal) -{ - task_wake(TASK_ID_PD_C0); -} - -static void vbus1_evt(enum gpio_signal signal) -{ - task_wake(TASK_ID_PD_C1); -} - -static volatile uint64_t hpd_prev_ts; -static volatile int hpd_prev_level; - -/** - * Hotplug detect deferred task - * - * Called after level change on hpd GPIO to evaluate (and debounce) what event - * has occurred. There are 3 events that occur on HPD: - * 1. low : downstream display sink is deattached - * 2. high : downstream display sink is attached - * 3. irq : downstream display sink signalling an interrupt. - * - * The debounce times for these various events are: - * HPD_USTREAM_DEBOUNCE_LVL : min pulse width of level value. - * HPD_USTREAM_DEBOUNCE_IRQ : min pulse width of IRQ low pulse. - * - * lvl(n-2) lvl(n-1) lvl prev_delta now_delta event - * ---------------------------------------------------- - * 1 0 1 <IRQ n/a low glitch (ignore) - * 1 0 1 >IRQ <LVL irq - * x 0 1 n/a >LVL high - * 0 1 0 <LVL n/a high glitch (ignore) - * x 1 0 n/a >LVL low - */ - -void hpd_irq_deferred(void) -{ - int dp_mode = pd_alt_mode(1, TCPCI_MSG_SOP, USB_SID_DISPLAYPORT); - - if (dp_mode) { - pd_send_hpd(DUT, hpd_irq); - CPRINTS("HPD IRQ"); - } -} -DECLARE_DEFERRED(hpd_irq_deferred); - -void hpd_lvl_deferred(void) -{ - int level = gpio_get_level(GPIO_DP_HPD); - int dp_mode = pd_alt_mode(1, TCPCI_MSG_SOP, USB_SID_DISPLAYPORT); - - if (level != hpd_prev_level) { - /* It's a glitch while in deferred or canceled action */ - return; - } - - if (dp_mode) { - pd_send_hpd(DUT, level ? hpd_high : hpd_low); - CPRINTS("HPD: %d", level); - } -} -DECLARE_DEFERRED(hpd_lvl_deferred); - -void hpd_evt(enum gpio_signal signal) -{ - timestamp_t now = get_time(); - int level = gpio_get_level(signal); - uint64_t cur_delta = now.val - hpd_prev_ts; - - /* Store current time */ - hpd_prev_ts = now.val; - - /* All previous hpd level events need to be re-triggered */ - hook_call_deferred(&hpd_lvl_deferred_data, -1); - - /* It's a glitch. Previous time moves but level is the same. */ - if (cur_delta < HPD_USTREAM_DEBOUNCE_IRQ) - return; - - if ((!hpd_prev_level && level) && - (cur_delta < HPD_USTREAM_DEBOUNCE_LVL)) { - /* It's an irq */ - hook_call_deferred(&hpd_irq_deferred_data, 0); - } else if (cur_delta >= HPD_USTREAM_DEBOUNCE_LVL) { - hook_call_deferred(&hpd_lvl_deferred_data, - HPD_USTREAM_DEBOUNCE_LVL); - } - - hpd_prev_level = level; -} - -#include "gpio_list.h" - -/****************************************************************************** - * Board pre-init function. - */ - -void board_config_pre_init(void) -{ - /* enable SYSCFG clock */ - STM32_RCC_APB2ENR |= BIT(0); - - /* - * the DMA mapping is : - * Chan 2 : TIM1_CH1 (CHG RX) - Default mapping - * Chan 3 : SPI1_TX (CHG TX) - Default mapping - * Chan 4 : USART1 TX - Remapped from default Chan 2 - * Chan 5 : USART1 RX - Remapped from default Chan 3 - * Chan 6 : TIM3_CH1 (DUT RX) - Remapped from default Chan 4 - * Chan 7 : SPI2_TX (DUT TX) - Remapped from default Chan 5 - * - * As described in the comments above, both USART1 TX/RX and DUT Tx/RX - * channels must be remapped from the defulat locations. Remapping is - * acoomplished by setting the following bits in the STM32_SYSCFG_CFGR1 - * register. Information about this register and its settings can be - * found in section 11.3.7 DMA Request Mapping of the STM RM0091 - * Reference Manual - */ - /* Remap USART1 Tx from DMA channel 2 to channel 4 */ - STM32_SYSCFG_CFGR1 |= BIT(9); - /* Remap USART1 Rx from DMA channel 3 to channel 5 */ - STM32_SYSCFG_CFGR1 |= BIT(10); - /* Remap TIM3_CH1 from DMA channel 4 to channel 6 */ - STM32_SYSCFG_CFGR1 |= BIT(30); - /* Remap SPI2 Tx from DMA channel 5 to channel 7 */ - STM32_SYSCFG_CFGR1 |= BIT(24); -} - -/****************************************************************************** - * Set up USB PD - */ - -/* ADC channels */ -const struct adc_t adc_channels[] = { - /* USB PD CC lines sensing. Converted to mV (3300mV/4096). */ - [ADC_CHG_CC1_PD] = {"CHG_CC1_PD", 3300, 4096, 0, STM32_AIN(2)}, - [ADC_CHG_CC2_PD] = {"CHG_CC2_PD", 3300, 4096, 0, STM32_AIN(4)}, - [ADC_DUT_CC1_PD] = {"DUT_CC1_PD", 3300, 4096, 0, STM32_AIN(0)}, - [ADC_DUT_CC2_PD] = {"DUT_CC2_PD", 3300, 4096, 0, STM32_AIN(5)}, - [ADC_SBU1_DET] = {"SBU1_DET", 3300, 4096, 0, STM32_AIN(3)}, - [ADC_SBU2_DET] = {"SBU2_DET", 3300, 4096, 0, STM32_AIN(7)}, - [ADC_SUB_C_REF] = {"SUB_C_REF", 3300, 4096, 0, STM32_AIN(1)}, -}; -BUILD_ASSERT(ARRAY_SIZE(adc_channels) == ADC_CH_COUNT); - - -/****************************************************************************** - * Forward UARTs as a USB serial interface. - */ - -#define USB_STREAM_RX_SIZE 16 -#define USB_STREAM_TX_SIZE 16 - -/****************************************************************************** - * Forward USART3 as a simple USB serial interface. - */ - -static struct usart_config const usart3; -struct usb_stream_config const usart3_usb; - -static struct queue const usart3_to_usb = QUEUE_DIRECT(64, uint8_t, - usart3.producer, usart3_usb.consumer); -static struct queue const usb_to_usart3 = QUEUE_DIRECT(64, uint8_t, - usart3_usb.producer, usart3.consumer); - -static struct usart_config const usart3 = - USART_CONFIG(usart3_hw, - usart_rx_interrupt, - usart_tx_interrupt, - 115200, - 0, - usart3_to_usb, - usb_to_usart3); - -USB_STREAM_CONFIG(usart3_usb, - USB_IFACE_USART3_STREAM, - USB_STR_USART3_STREAM_NAME, - USB_EP_USART3_STREAM, - USB_STREAM_RX_SIZE, - USB_STREAM_TX_SIZE, - usb_to_usart3, - usart3_to_usb) - - -/****************************************************************************** - * Forward USART4 as a simple USB serial interface. - */ - -static struct usart_config const usart4; -struct usb_stream_config const usart4_usb; - -static struct queue const usart4_to_usb = QUEUE_DIRECT(64, uint8_t, - usart4.producer, usart4_usb.consumer); -static struct queue const usb_to_usart4 = QUEUE_DIRECT(64, uint8_t, - usart4_usb.producer, usart4.consumer); - -static struct usart_config const usart4 = - USART_CONFIG(usart4_hw, - usart_rx_interrupt, - usart_tx_interrupt, - 9600, - 0, - usart4_to_usb, - usb_to_usart4); - -USB_STREAM_CONFIG(usart4_usb, - USB_IFACE_USART4_STREAM, - USB_STR_USART4_STREAM_NAME, - USB_EP_USART4_STREAM, - USB_STREAM_RX_SIZE, - USB_STREAM_TX_SIZE, - usb_to_usart4, - usart4_to_usb) - -/* - * Define usb interface descriptor for the `EMPTY` usb interface, to satisfy - * UEFI and kernel requirements (see b/183857501). - */ -const struct usb_interface_descriptor -USB_IFACE_DESC(USB_IFACE_EMPTY) = { - .bLength = USB_DT_INTERFACE_SIZE, - .bDescriptorType = USB_DT_INTERFACE, - .bInterfaceNumber = USB_IFACE_EMPTY, - .bAlternateSetting = 0, - .bNumEndpoints = 0, - .bInterfaceClass = USB_CLASS_VENDOR_SPEC, - .bInterfaceSubClass = 0, - .bInterfaceProtocol = 0, - .iInterface = 0, -}; - -/****************************************************************************** - * Define the strings used in our USB descriptors. - */ - -const void *const usb_strings[] = { - [USB_STR_DESC] = usb_string_desc, - [USB_STR_VENDOR] = USB_STRING_DESC("Google Inc."), - [USB_STR_PRODUCT] = USB_STRING_DESC("Servo V4"), - [USB_STR_SERIALNO] = USB_STRING_DESC("1234-a"), - [USB_STR_VERSION] = USB_STRING_DESC(CROS_EC_VERSION32), - [USB_STR_I2C_NAME] = USB_STRING_DESC("I2C"), - [USB_STR_CONSOLE_NAME] = USB_STRING_DESC("Servo EC Shell"), - [USB_STR_USART3_STREAM_NAME] = USB_STRING_DESC("DUT UART"), - [USB_STR_USART4_STREAM_NAME] = USB_STRING_DESC("Atmega UART"), - [USB_STR_UPDATE_NAME] = USB_STRING_DESC("Firmware update"), -}; - -BUILD_ASSERT(ARRAY_SIZE(usb_strings) == USB_STR_COUNT); - - - -/****************************************************************************** - * Support I2C bridging over USB. - */ - -/* I2C ports */ -const struct i2c_port_t i2c_ports[] = { - {"master", I2C_PORT_MASTER, 100, - GPIO_MASTER_I2C_SCL, GPIO_MASTER_I2C_SDA}, -}; -const unsigned int i2c_ports_used = ARRAY_SIZE(i2c_ports); - -int usb_i2c_board_is_enabled(void) { return 1; } - -/****************************************************************************** - * Initialize board. - */ - -/* - * Support tca6416 I2C ioexpander. - */ -#define GPIOX_I2C_ADDR_FLAGS 0x20 -#define GPIOX_IN_PORT_A 0x0 -#define GPIOX_IN_PORT_B 0x1 -#define GPIOX_OUT_PORT_A 0x2 -#define GPIOX_OUT_PORT_B 0x3 -#define GPIOX_DIR_PORT_A 0x6 -#define GPIOX_DIR_PORT_B 0x7 - - -/* Write a GPIO output on the tca6416 I2C ioexpander. */ -static void write_ioexpander(int bank, int gpio, int val) -{ - int tmp; - - /* Read output port register */ - i2c_read8(1, GPIOX_I2C_ADDR_FLAGS, GPIOX_OUT_PORT_A + bank, &tmp); - if (val) - tmp |= BIT(gpio); - else - tmp &= ~BIT(gpio); - /* Write back modified output port register */ - i2c_write8(1, GPIOX_I2C_ADDR_FLAGS, GPIOX_OUT_PORT_A + bank, tmp); -} - -/* Read a single GPIO input on the tca6416 I2C ioexpander. */ -static int read_ioexpander_bit(int bank, int bit) -{ - int tmp; - int mask = 1 << bit; - - /* Read input port register */ - i2c_read8(1, GPIOX_I2C_ADDR_FLAGS, GPIOX_IN_PORT_A + bank, &tmp); - - return (tmp & mask) >> bit; -} - -/* Enable uservo USB. */ -static void init_uservo_port(void) -{ - /* Write USERVO_POWER_EN */ - write_ioexpander(0, 7, 1); - /* Write USERVO_FASTBOOT_MUX_SEL */ - write_ioexpander(1, 0, 0); -} - -/* Enable blue USB port to DUT. */ -static void init_usb3_port(void) -{ - /* Write USB3.0_TYPEA_MUX_SEL */ - write_ioexpander(0, 3, 1); - /* Write USB3.0_TYPEA_MUX_EN_L */ - write_ioexpander(0, 4, 0); - /* Write USB3.0_TYPE_A_PWR_EN */ - write_ioexpander(0, 5, 1); -} - -/* Enable all ioexpander outputs. */ -static void init_ioexpander(void) -{ - /* Write all GPIO to output 0 */ - i2c_write8(1, GPIOX_I2C_ADDR_FLAGS, GPIOX_OUT_PORT_A, 0x0); - i2c_write8(1, GPIOX_I2C_ADDR_FLAGS, GPIOX_OUT_PORT_B, 0x0); - - /* - * Write GPIO direction: strap resistors to input, - * all others to output. - */ - i2c_write8(1, GPIOX_I2C_ADDR_FLAGS, GPIOX_DIR_PORT_A, 0x0); - i2c_write8(1, GPIOX_I2C_ADDR_FLAGS, GPIOX_DIR_PORT_B, 0x18); -} - -/* - * Define voltage thresholds for SBU USB detection. - * - * Max observed USB low across sampled systems: 666mV - * Min observed USB high across sampled systems: 3026mV - */ -#define GND_MAX_MV 700 -#define USB_HIGH_MV 2500 -#define SBU_DIRECT 0 -#define SBU_FLIP 1 - -#define MODE_SBU_DISCONNECT 0 -#define MODE_SBU_CONNECT 1 -#define MODE_SBU_FLIP 2 -#define MODE_SBU_OTHER 3 - -static void ccd_measure_sbu(void); -DECLARE_DEFERRED(ccd_measure_sbu); -static void ccd_measure_sbu(void) -{ - int sbu1; - int sbu2; - int mux_en; - static int count /* = 0 */; - static int last /* = 0 */; - static int polarity /* = 0 */; - - /* Read sbu voltage levels */ - sbu1 = adc_read_channel(ADC_SBU1_DET); - sbu2 = adc_read_channel(ADC_SBU2_DET); - mux_en = gpio_get_level(GPIO_SBU_MUX_EN); - - /* - * While SBU_MUX is disabled (SuzyQ unplugged), we'll poll the SBU lines - * to check if an idling, unconfigured USB device is present. - * USB FS pulls one line high for connect request. - * If so, and it persists for 500ms, we'll enable the SuzyQ in that - * orientation. - */ - if ((!mux_en) && (sbu1 > USB_HIGH_MV) && (sbu2 < GND_MAX_MV)) { - /* Check flip connection polarity. */ - if (last != MODE_SBU_FLIP) { - last = MODE_SBU_FLIP; - polarity = SBU_FLIP; - count = 0; - } else { - count++; - } - } else if ((!mux_en) && (sbu2 > USB_HIGH_MV) && (sbu1 < GND_MAX_MV)) { - /* Check direct connection polarity. */ - if (last != MODE_SBU_CONNECT) { - last = MODE_SBU_CONNECT; - polarity = SBU_DIRECT; - count = 0; - } else { - count++; - } - /* - * If SuzyQ is enabled, we'll poll for a persistent no-signal for - * 500ms. Since USB is differential, we should never see GND/GND - * while the device is connected. - * If disconnected, electrically remove SuzyQ. - */ - } else if ((mux_en) && (sbu1 < GND_MAX_MV) && (sbu2 < GND_MAX_MV)) { - /* Check for SBU disconnect if connected. */ - if (last != MODE_SBU_DISCONNECT) { - last = MODE_SBU_DISCONNECT; - count = 0; - } else { - count++; - } - } else { - /* Didn't find anything, reset state. */ - last = MODE_SBU_OTHER; - count = 0; - } - - /* - * We have seen a new state continuously for 500ms. - * Let's update the mux to enable/disable SuzyQ appropriately. - */ - if (count > 5) { - if (mux_en) { - /* Disable mux as it's disconnected now. */ - gpio_set_level(GPIO_SBU_MUX_EN, 0); - msleep(10); - CPRINTS("CCD: disconnected."); - } else { - /* SBU flip = polarity */ - write_ioexpander(0, 2, polarity); - gpio_set_level(GPIO_SBU_MUX_EN, 1); - msleep(10); - CPRINTS("CCD: connected %s", - polarity ? "flip" : "noflip"); - } - } - - /* Measure every 100ms, forever. */ - hook_call_deferred(&ccd_measure_sbu_data, 100 * MSEC); -} - -void ext_hpd_detection_enable(int enable) -{ - if (enable) { - timestamp_t now = get_time(); - - hpd_prev_level = gpio_get_level(GPIO_DP_HPD); - hpd_prev_ts = now.val; - gpio_enable_interrupt(GPIO_DP_HPD); - } else { - gpio_disable_interrupt(GPIO_DP_HPD); - } -} - -void ccd_enable(int enable) -{ - if (enable) { - hook_call_deferred(&ccd_measure_sbu_data, 0); - } else { - gpio_set_level(GPIO_SBU_MUX_EN, 0); - hook_call_deferred(&ccd_measure_sbu_data, -1); - } -} - -int board_get_version(void) -{ - static int ver = -1; - - if (ver < 0) { - uint8_t id0, id1; - - id0 = read_ioexpander_bit(1, 3); - id1 = read_ioexpander_bit(1, 4); - - ver = (id1 * 2) + id0; - CPRINTS("Board ID = %d", ver); - } - - return ver; -} - -static void board_init(void) -{ - /* USB to serial queues */ - queue_init(&usart3_to_usb); - queue_init(&usb_to_usart3); - queue_init(&usart4_to_usb); - queue_init(&usb_to_usart4); - - /* UART init */ - usart_init(&usart3); - usart_init(&usart4); - - /* Delay DUT hub to avoid brownout. */ - usleep(1000); - gpio_set_flags(GPIO_DUT_HUB_USB_RESET_L, GPIO_OUT_HIGH); - - /* - * Disable USB3 mode in PS8742 USB/DP Mux. - */ - i2c_write8(I2C_PORT_MASTER, PS8740_I2C_ADDR0_FLAG, PS8740_REG_MODE, 0); - - /* Enable uservo USB by default. */ - init_ioexpander(); - init_uservo_port(); - init_usb3_port(); - - /* Clear BBRAM, we don't want any PD state carried over on reset. */ - system_set_bbram(SYSTEM_BBRAM_IDX_PD0, 0); - system_set_bbram(SYSTEM_BBRAM_IDX_PD1, 0); - - /* - * Disable SBU mux. The polarity is set each time a presense is detected - * on SBU, and wired thorugh. On missing voltage on SBU. SBU wires are - * disconnected. - */ - gpio_set_level(GPIO_SBU_MUX_EN, 0); - - /* - * Voltage transition needs to occur in lockstep between the CHG and - * DUT ports, so initially limit voltage to 5V. - */ - pd_set_max_voltage(PD_MIN_MV); - - /* Enable VBUS detection to wake PD tasks fast enough */ - gpio_enable_interrupt(GPIO_USB_DET_PP_CHG); - gpio_enable_interrupt(GPIO_USB_DET_PP_DUT); - - hook_call_deferred(&ccd_measure_sbu_data, 1000 * MSEC); -} -DECLARE_HOOK(HOOK_INIT, board_init, HOOK_PRIO_DEFAULT); diff --git a/board/servo_v4/board.h b/board/servo_v4/board.h deleted file mode 100644 index f932752ef4..0000000000 --- a/board/servo_v4/board.h +++ /dev/null @@ -1,277 +0,0 @@ -/* Copyright 2016 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. - */ - -/* Servo V4 configuration */ - -#ifndef __CROS_EC_BOARD_H -#define __CROS_EC_BOARD_H - -#define CONFIG_LTO - -/* Free up flash space */ -#ifdef SECTION_IS_RO -#define CONFIG_DEBUG_ASSERT_BRIEF -#endif - -/* - * Board Versions: - * Versions are designated by the PCB color and consist of red, blue, and - * black. Only the black version has pullup resistors to distinguish its board - * id from previous versions. - */ -#define BOARD_VERSION_BLACK 3 - -/* 48 MHz SYSCLK clock frequency */ -#define CPU_CLOCK 48000000 - -/* Enable USART1,3,4 and USB streams */ -#define CONFIG_STREAM_USART -#define CONFIG_STREAM_USART3 -#define CONFIG_STREAM_USART4 -#define CONFIG_STREAM_USB -#define CONFIG_CMD_USART_INFO - -/* Optional features */ -#define CONFIG_STM_HWTIMER32 -#define CONFIG_HW_CRC -#define CONFIG_PVD -/* See 'Programmable voltage detector characteristics' in the STM32F072x8 Datasheet. - PVD Threshold 1 corresponds to a falling voltage threshold of min:2.09V, max:2.27V. */ -#define PVD_THRESHOLD (1) - -/* USB Configuration */ -#define CONFIG_USB -#define CONFIG_USB_PID 0x501b -#define CONFIG_USB_CONSOLE -#define CONFIG_USB_UPDATE -#define CONFIG_USB_BCD_DEV 0x0001 /* v 0.01 */ - -#define CONFIG_USB_PD_IDENTITY_HW_VERS 1 -#define CONFIG_USB_PD_IDENTITY_SW_VERS 1 - -#define CONFIG_USB_SELF_POWERED - -#define CONFIG_USB_SERIALNO -#define DEFAULT_SERIALNO "Uninitialized" -#define CONFIG_MAC_ADDR -#define DEFAULT_MAC_ADDR "Uninitialized" - -/* USB interface indexes (use define rather than enum to expand them) */ -#define USB_IFACE_CONSOLE 0 -#define USB_IFACE_EMPTY 1 -#define USB_IFACE_I2C 2 -#define USB_IFACE_USART3_STREAM 3 -#define USB_IFACE_USART4_STREAM 4 -#define USB_IFACE_UPDATE 5 -#define USB_IFACE_COUNT 6 - -/* USB endpoint indexes (use define rather than enum to expand them) */ -#define USB_EP_CONTROL 0 -#define USB_EP_CONSOLE 1 -#define USB_EP_EMPTY 2 -#define USB_EP_I2C 3 -#define USB_EP_USART3_STREAM 4 -#define USB_EP_USART4_STREAM 5 -#define USB_EP_UPDATE 6 -#define USB_EP_COUNT 7 - -/* Enable console recasting of GPIO type. */ -#define CONFIG_CMD_GPIO_EXTENDED - -/* This is not actually an EC so disable some features. */ -#undef CONFIG_WATCHDOG_HELP -#undef CONFIG_LID_SWITCH -#undef CONFIG_HIBERNATE - -/* Remove console commands / features for flash / RAM savings */ -#undef CONFIG_USB_PD_HOST_CMD -#undef CONFIG_CONSOLE_CMDHELP -#undef CONFIG_CONSOLE_HISTORY -#undef CONFIG_CMD_CRASH -#undef CONFIG_CMD_ACCELSPOOF -#undef CONFIG_CMD_FASTCHARGE -#undef CONFIG_CMD_FLASHINFO -#undef CONFIG_CMD_FLASH_WP -#undef CONFIG_CMD_GETTIME -#undef CONFIG_CMD_MEM -#undef CONFIG_CMD_SHMEM -#undef CONFIG_CMD_SYSLOCK -#undef CONFIG_CMD_TIMERINFO -#undef CONFIG_CMD_WAITMS -#undef CONFIG_CMD_USART_INFO -#undef CONFIG_CMD_CHARGE_SUPPLIER_INFO - -/* Enable control of I2C over USB */ -#define CONFIG_USB_I2C -#define CONFIG_I2C -#define CONFIG_I2C_CONTROLLER -#define I2C_PORT_MASTER 1 - -/* PD features */ -#define CONFIG_ADC -#undef CONFIG_ADC_WATCHDOG -#define CONFIG_BOARD_PRE_INIT -/* - * If task profiling is enabled then the rx falling edge detection interrupts - * can't be processed in time and can't support USB PD messaging. - */ -#undef CONFIG_TASK_PROFILING - -#define CONFIG_CHARGE_MANAGER -#undef CONFIG_CHARGE_MANAGER_SAFE_MODE -#define CONFIG_USB_POWER_DELIVERY -#define CONFIG_USB_PD_TCPMV1 -#define CONFIG_CMD_PD -#define CONFIG_USB_PD_CUSTOM_PDO -#define CONFIG_USB_PD_ALT_MODE -#define CONFIG_USB_PD_DUAL_ROLE -#define CONFIG_USB_PD_DYNAMIC_SRC_CAP -#define CONFIG_USB_PD_INTERNAL_COMP -#define CONFIG_USB_PD_PORT_MAX_COUNT 2 -#define CONFIG_USB_PD_TCPC -#define CONFIG_USB_PD_TCPM_STUB -#undef CONFIG_USB_PD_PULLUP -#define CONFIG_USB_PD_PULLUP TYPEC_RP_USB -#define CONFIG_USB_PD_VBUS_MEASURE_NOT_PRESENT -#define CONFIG_USB_PD_ONLY_FIXED_PDOS - -/* Don't automatically change roles */ -#undef CONFIG_USB_PD_INITIAL_DRP_STATE -#define CONFIG_USB_PD_INITIAL_DRP_STATE PD_DRP_FORCE_SINK - -/* Variable-current Rp no connect and Ra attach macros */ -#define CC_NC(port, cc, sel) (pd_tcpc_cc_nc(port, cc, sel)) -#define CC_RA(port, cc, sel) (pd_tcpc_cc_ra(port, cc, sel)) - -/* - * TODO(crosbug.com/p/60792): The delay values are currently just place holders - * and the delay will need to be relative to the circuitry that allows VBUS to - * be supplied to the DUT port from the CHG port. - */ -#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 15000 -#define PD_MAX_POWER_MW 60000 -#define PD_MAX_CURRENT_MA 3000 -#define PD_MAX_VOLTAGE_MV 20000 -/* - * Define PDO selection logic for SourceCap. - * On a 45W PD charger, it might provide PDOs with 15V/3A and 20V/2.25A. - * In this case, pd_find_pdo_index() would always prefer 15V/3A rather than - * 20V/2.25A and such that the 20V PDO will be disappeared when servo-v4 - * advertise the SrcCap. We define PD_PREFER_HIGH_VOLTAGE so that all the - * PDOs could be advertised by servo-v4. - */ -#define PD_PREFER_HIGH_VOLTAGE - -/* - * Allow dangerous commands all the time, since we don't have a write protect - * switch. - */ -#define CONFIG_SYSTEM_UNLOCKED - -#ifndef __ASSEMBLER__ - -/* Timer selection */ -#define TIM_CLOCK32 2 -#define TIM_ADC 3 - - -#include "gpio_signal.h" - -/* USB string indexes */ -enum usb_strings { - USB_STR_DESC = 0, - USB_STR_VENDOR, - USB_STR_PRODUCT, - USB_STR_SERIALNO, - USB_STR_VERSION, - USB_STR_I2C_NAME, - USB_STR_CONSOLE_NAME, - USB_STR_USART3_STREAM_NAME, - USB_STR_USART4_STREAM_NAME, - USB_STR_UPDATE_NAME, - USB_STR_COUNT -}; - - -/* ADC signal */ -enum adc_channel { - ADC_CHG_CC1_PD, - ADC_CHG_CC2_PD, - ADC_DUT_CC1_PD, - ADC_DUT_CC2_PD, - ADC_SBU1_DET, - ADC_SBU2_DET, - ADC_SUB_C_REF, - /* Number of ADC channels */ - ADC_CH_COUNT -}; - -/** - * Compare cc_voltage to disconnect threshold - * - * This function can be used for boards that support variable Rp settings and - * require a different voltage threshold based on the Rp value attached to a - * given cc line. - * - * @param port USB-C port number - * @param cc_volt voltage measured in mV of the CC line - * @param cc_sel cc1 or cc2 selection - * @return 1 if voltage is >= threshold value for disconnect - */ -int pd_tcpc_cc_nc(int port, int cc_volt, int cc_sel); - -/** - * Compare cc_voltage to Ra threshold - * - * This function can be used for boards that support variable Rp settings and - * require a different voltage threshold based on the Rp value attached to a - * given cc line. - * - * @param port USB-C port number - * @param cc_volt voltage measured in mV of the CC line - * @param cc_sel cc1 or cc2 selection - * @return 1 if voltage is < threshold value for Ra attach - */ -int pd_tcpc_cc_ra(int port, int cc_volt, int cc_sel); - -/** - * Set Rp or Rd resistor for CC lines - * - * This function is used to configure the CC pullup or pulldown resistor to - * the requested value. - * - * @param port USB-C port number - * @param cc_pull 1 for Rp and 0 for Rd - * @param rp_value If cc_pull == 1, the value of Rp to use - * @return 1 if cc_pull == 1 and Rp is invalid, otherwise 0 - */ -int pd_set_rp_rd(int port, int cc_pull, int rp_value); - -/** - * Get board HW ID version - * - * @return HW ID version - */ -int board_get_version(void); - -/** - * Enable or disable external HPD detection - * - * @param enable Enable external HPD detection if true, otherwise disable - */ -void ext_hpd_detection_enable(int enable); - -/** - * Enable or disable CCD - * - * @param enable Enable CCD if true, otherwise disable - */ -void ccd_enable(int enable); -#endif /* !__ASSEMBLER__ */ -#endif /* __CROS_EC_BOARD_H */ diff --git a/board/servo_v4/build.mk b/board/servo_v4/build.mk deleted file mode 100644 index 6336bbfab6..0000000000 --- a/board/servo_v4/build.mk +++ /dev/null @@ -1,19 +0,0 @@ -# -*- makefile -*- -# Copyright 2016 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. -# -# Board specific files build - -# the IC is STmicro STM32F072RBT6 -CHIP:=stm32 -CHIP_FAMILY:=stm32f0 -CHIP_VARIANT:=stm32f07x - -# Not enough SRAM: Disable all tests -test-list-y= - -board-y=board.o -board-$(CONFIG_USB_POWER_DELIVERY)+=usb_pd_policy.o - -all_deps=$(patsubst ro,,$(def_all_deps)) diff --git a/board/servo_v4/ec.tasklist b/board/servo_v4/ec.tasklist deleted file mode 100644 index 2111c6b761..0000000000 --- a/board/servo_v4/ec.tasklist +++ /dev/null @@ -1,13 +0,0 @@ -/* Copyright 2016 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. - */ - -/** - * See CONFIG_TASK_LIST in config.h for details. - */ -#define CONFIG_TASK_LIST \ - TASK_ALWAYS(HOOKS, hook_task, NULL, VENTI_TASK_STACK_SIZE) \ - TASK_ALWAYS(CONSOLE, console_task, NULL, VENTI_TASK_STACK_SIZE) \ - TASK_ALWAYS(PD_C0, pd_task, NULL, TRENTA_TASK_STACK_SIZE) \ - TASK_ALWAYS(PD_C1, pd_task, NULL, TRENTA_TASK_STACK_SIZE) diff --git a/board/servo_v4/gpio.inc b/board/servo_v4/gpio.inc deleted file mode 100644 index 76b9a06d0f..0000000000 --- a/board/servo_v4/gpio.inc +++ /dev/null @@ -1,81 +0,0 @@ -/* -*- mode:c -*- - * - * Copyright 2016 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. - */ - -GPIO_INT(USB_DET_PP_CHG, PIN(C, 13), GPIO_INT_BOTH, vbus0_evt) -GPIO_INT(USB_DET_PP_DUT, PIN(C, 12), GPIO_INT_BOTH, vbus1_evt) -GPIO_INT(DP_HPD, PIN(A, 14), GPIO_INT_BOTH, hpd_evt) - -/* Outputs */ -GPIO(DUT_CHG_EN, PIN(A, 10), GPIO_OUT_LOW) -GPIO(HOST_OR_CHG_CTL, PIN(A, 13), GPIO_OUT_HIGH) -GPIO(SBU_UART_SEL, PIN(A, 15), GPIO_OUT_LOW) -GPIO(HOST_USB_HUB_RESET_L, PIN(D, 2), GPIO_OUT_HIGH) -GPIO(FASTBOOT_DUTHUB_MUX_SEL, PIN(B, 5), GPIO_OUT_HIGH) -GPIO(SBU_MUX_EN, PIN(B, 6), GPIO_OUT_LOW) -GPIO(FASTBOOT_DUTHUB_MUX_EN_L, PIN(B, 7), GPIO_OUT_LOW) -/* Power on init has reset asserted, we will pull the hub out of reset - * in the board init to help avoid brownout. - */ -GPIO(DUT_HUB_USB_RESET_L, PIN(B, 9), GPIO_OUT_LOW) -GPIO(ATMEL_HWB_L, PIN(B, 12), GPIO_OUT_HIGH) -GPIO(CMUX_EN, PIN(C, 14), GPIO_OUT_HIGH) -GPIO(EMMC_MUX_EN_L, PIN(F, 0), GPIO_OUT_HIGH) -GPIO(EMMC_PWR_EN, PIN(F, 1), GPIO_OUT_LOW) - -/* Inputs */ -GPIO(USERVO_FAULT_L, PIN(A, 8), GPIO_INPUT) -GPIO(USB_FAULT_L, PIN(A, 9), GPIO_INPUT) -GPIO(DONGLE_DET, PIN(C, 15), GPIO_INPUT) - -/* Type-C */ -/* PD RX/TX */ -GPIO(USB_C_REF, PIN(A, 1), GPIO_ANALOG) -GPIO(USB_CHG_CC1_PD, PIN(A, 2), GPIO_ANALOG) -GPIO(USB_CHG_CC2_PD, PIN(A, 4), GPIO_ANALOG) -GPIO(USB_DUT_CC1_PD, PIN(A, 0), GPIO_ANALOG) -GPIO(USB_DUT_CC2_PD, PIN(A, 5), GPIO_ANALOG) - -GPIO(USB_CHG_CC1_TX_DATA, PIN(B, 4), GPIO_INPUT) -GPIO(USB_CHG_CC2_TX_DATA, PIN(A, 6), GPIO_INPUT) -GPIO(USB_DUT_CC1_TX_DATA, PIN(B, 14), GPIO_INPUT) -GPIO(USB_DUT_CC2_TX_DATA, PIN(C, 2), GPIO_INPUT) - -GPIO(USB_DUT_CC1_RP3A0, PIN(C, 0), GPIO_INPUT) -GPIO(USB_DUT_CC1_RP1A5, PIN(C, 1), GPIO_INPUT) -GPIO(USB_DUT_CC1_RPUSB, PIN(C, 3), GPIO_INPUT) -GPIO(USB_DUT_CC1_RD, PIN(C, 6), GPIO_INPUT) -GPIO(USB_DUT_CC1_RA, PIN(C, 7), GPIO_INPUT) - -GPIO(USB_DUT_CC2_RP3A0, PIN(C, 8), GPIO_INPUT) -GPIO(USB_DUT_CC2_RP1A5, PIN(C, 9), GPIO_INPUT) -GPIO(USB_DUT_CC2_RPUSB, PIN(B, 0), GPIO_INPUT) -GPIO(USB_DUT_CC2_RD, PIN(B, 1), GPIO_INPUT) -GPIO(USB_DUT_CC2_RA, PIN(B, 2), GPIO_INPUT) - -/* Alternate PD functions */ -GPIO(USB_CHG_TX_CLKOUT, PIN(B, 8), GPIO_INPUT) -GPIO(USB_CHG_TX_CLKIN, PIN(B, 3), GPIO_INPUT) -GPIO(USB_DUT_TX_CLKOUT, PIN(B, 15), GPIO_INPUT) -GPIO(USB_DUT_TX_CLKIN, PIN(B, 13), GPIO_INPUT) - -/* I2C pins should be configured as inputs until I2C module is */ -/* initialized. This will avoid driving the lines unintentionally.*/ -GPIO(MASTER_I2C_SCL, PIN(B, 10), GPIO_INPUT) -GPIO(MASTER_I2C_SDA, PIN(B, 11), GPIO_INPUT) - -/* Unimplemented signals since we are not an EC */ -UNIMPLEMENTED(ENTERING_RW) -UNIMPLEMENTED(WP_L) - -ALTERNATE(PIN_MASK(C, 0x0030), 1, MODULE_USART, 0) /* USART3: PC4/PC5 - Servo DUT UART */ -ALTERNATE(PIN_MASK(C, 0x0C00), 0, MODULE_USART, 0) /* USART4: PC10/PC11 - Servo UART3 */ -ALTERNATE(PIN_MASK(B, 0x0C00), 1, MODULE_I2C, GPIO_ODR_HIGH) /* I2C MASTER:PB8/9 */ -ALTERNATE(PIN_MASK(B, 0x0008), 0, MODULE_USB_PD, 0) /* SPI1_SCK: PB3 */ -ALTERNATE(PIN_MASK(B, 0x2000), 0, MODULE_USB_PD, 0) /* SPI2_SCK: PB13 */ -ALTERNATE(PIN_MASK(B, 0x0100), 2, MODULE_USB_PD, 0) /* TIM16_CH1: PB8 */ -ALTERNATE(PIN_MASK(B, 0x8000), 1, MODULE_USB_PD, 0) /* TIM15_CH2: PB15 */ - diff --git a/board/servo_v4/usb_pd_config.h b/board/servo_v4/usb_pd_config.h deleted file mode 100644 index b865057618..0000000000 --- a/board/servo_v4/usb_pd_config.h +++ /dev/null @@ -1,288 +0,0 @@ -/* Copyright 2017 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. - */ - -#include "adc.h" -#include "chip/stm32/registers.h" -#include "console.h" -#include "gpio.h" -#include "ec_commands.h" -#include "usb_pd_tcpm.h" - -/* USB Power delivery board configuration */ - -#ifndef __CROS_EC_USB_PD_CONFIG_H -#define __CROS_EC_USB_PD_CONFIG_H - -/* NOTES: Servo V4 and glados equivalents: - * Glados Servo V4 - * C0 CHG - * C1 DUT - * - */ -#define CHG 0 -#define DUT 1 - -/* Timer selection for baseband PD communication */ -#define TIM_CLOCK_PD_TX_CHG 16 -#define TIM_CLOCK_PD_RX_CHG 1 -#define TIM_CLOCK_PD_TX_DUT 15 -#define TIM_CLOCK_PD_RX_DUT 3 - -/* Timer channel */ -#define TIM_TX_CCR_CHG 1 -#define TIM_RX_CCR_CHG 1 -#define TIM_TX_CCR_DUT 2 -#define TIM_RX_CCR_DUT 1 - -#define TIM_CLOCK_PD_TX(p) ((p) ? TIM_CLOCK_PD_TX_DUT : TIM_CLOCK_PD_TX_CHG) -#define TIM_CLOCK_PD_RX(p) ((p) ? TIM_CLOCK_PD_RX_DUT : TIM_CLOCK_PD_RX_CHG) - -/* RX timer capture/compare register */ -#define TIM_CCR_CHG (&STM32_TIM_CCRx(TIM_CLOCK_PD_RX_CHG, TIM_RX_CCR_CHG)) -#define TIM_CCR_DUT (&STM32_TIM_CCRx(TIM_CLOCK_PD_RX_DUT, TIM_RX_CCR_DUT)) -#define TIM_RX_CCR_REG(p) ((p) ? TIM_CCR_DUT : TIM_CCR_CHG) - -/* TX and RX timer register */ -#define TIM_REG_TX_CHG (STM32_TIM_BASE(TIM_CLOCK_PD_TX_CHG)) -#define TIM_REG_RX_CHG (STM32_TIM_BASE(TIM_CLOCK_PD_RX_CHG)) -#define TIM_REG_TX_DUT (STM32_TIM_BASE(TIM_CLOCK_PD_TX_DUT)) -#define TIM_REG_RX_DUT (STM32_TIM_BASE(TIM_CLOCK_PD_RX_DUT)) -#define TIM_REG_TX(p) ((p) ? TIM_REG_TX_DUT : TIM_REG_TX_CHG) -#define TIM_REG_RX(p) ((p) ? TIM_REG_RX_DUT : TIM_REG_RX_CHG) - -/* use the hardware accelerator for CRC */ -#define CONFIG_HW_CRC - -/* Servo v4 CC configuration */ -#define CC_DETACH BIT(0) /* Emulate detach: both CC open */ -#define CC_DISABLE_DTS BIT(1) /* Apply resistors to single or both CC? */ -#define CC_ALLOW_SRC BIT(2) /* Allow charge through by policy? */ -#define CC_ENABLE_DRP BIT(3) /* Enable dual-role port */ -#define CC_SNK_WITH_PD BIT(4) /* Force enabling PD comm for sink role */ -#define CC_POLARITY BIT(5) /* CC polarity */ - -/* Servo v4 DP alt-mode configuration */ -#define ALT_DP_ENABLE BIT(0) /* Enable DP alt-mode or not */ -#define ALT_DP_PIN_C BIT(1) /* Pin assignment C supported */ -#define ALT_DP_PIN_D BIT(2) /* Pin assignment D supported */ -#define ALT_DP_PIN_E BIT(3) /* Pin assignment E supported */ -#define ALT_DP_MF_PREF BIT(4) /* Multi-Function preferred */ -#define ALT_DP_PLUG BIT(5) /* Plug or receptacle */ -#define ALT_DP_OVERRIDE_HPD BIT(6) /* Override the HPD signal */ -#define ALT_DP_HPD_LVL BIT(7) /* HPD level if overridden */ - -/* TX uses SPI1 on PB3-4 for CHG port, SPI2 on PB 13-14 for DUT port */ -#define SPI_REGS(p) ((p) ? STM32_SPI2_REGS : STM32_SPI1_REGS) -static inline void spi_enable_clock(int port) -{ - if (port == 0) - STM32_RCC_APB2ENR |= STM32_RCC_PB2_SPI1; - else - STM32_RCC_APB1ENR |= STM32_RCC_PB1_SPI2; -} - -/* DMA for transmit uses DMA CH3 for CHG and DMA_CH7 for DUT */ -#define DMAC_SPI_TX(p) ((p) ? STM32_DMAC_CH7 : STM32_DMAC_CH3) - -/* RX uses COMP1 and TIM1_CH1 on port CHG and COMP2 and TIM3_CH1 for port DUT*/ -/* DUT RX use CMP1, TIM3_CH1, DMA_CH6 */ -#define CMP1OUTSEL STM32_COMP_CMP1OUTSEL_TIM3_IC1 -/* CHG RX use CMP2, TIM1_CH1, DMA_CH2 */ -#define CMP2OUTSEL STM32_COMP_CMP2OUTSEL_TIM1_IC1 - -#define TIM_TX_CCR_IDX(p) ((p) ? TIM_TX_CCR_DUT : TIM_TX_CCR_CHG) -#define TIM_RX_CCR_IDX(p) ((p) ? TIM_RX_CCR_DUT : TIM_RX_CCR_CHG) -#define TIM_CCR_CS 1 - -/* - * EXTI line 21 is connected to the CMP1 output, - * EXTI line 22 is connected to the CMP2 output, - * CHG uses CMP2, and DUT uses CMP1. - */ -#define EXTI_COMP_MASK(p) ((p) ? (1<<21) : BIT(22)) - -#define IRQ_COMP STM32_IRQ_COMP -/* triggers packet detection on comparator falling edge */ -#define EXTI_XTSR STM32_EXTI_FTSR - -/* DMA for receive uses DMA_CH2 for CHG and DMA_CH6 for DUT */ -#define DMAC_TIM_RX(p) ((p) ? STM32_DMAC_CH6 : STM32_DMAC_CH2) - -/* the pins used for communication need to be hi-speed */ -static inline void pd_set_pins_speed(int port) -{ - if (port == 0) { - /* 40 MHz pin speed on SPI PB3&4, - * (USB_CHG_TX_CLKIN & USB_CHG_CC1_TX_DATA) - */ - STM32_GPIO_OSPEEDR(GPIO_B) |= 0x000003C0; - /* 40 MHz pin speed on TIM16_CH1 (PB8), - * (USB_CHG_TX_CLKOUT) - */ - STM32_GPIO_OSPEEDR(GPIO_B) |= 0x00030000; - } else { - /* 40 MHz pin speed on SPI PB13/14, - * (USB_DUT_TX_CLKIN & USB_DUT_CC1_TX_DATA) - */ - STM32_GPIO_OSPEEDR(GPIO_B) |= 0x3C000000; - /* 40 MHz pin speed on TIM15_CH2 (PB15) */ - STM32_GPIO_OSPEEDR(GPIO_B) |= 0xC0000000; - } -} - -/* Reset SPI peripheral used for TX */ -static inline void pd_tx_spi_reset(int port) -{ - if (port == 0) { - /* Reset SPI1 */ - STM32_RCC_APB2RSTR |= BIT(12); - STM32_RCC_APB2RSTR &= ~BIT(12); - } else { - /* Reset SPI2 */ - STM32_RCC_APB1RSTR |= BIT(14); - STM32_RCC_APB1RSTR &= ~BIT(14); - } -} - -static const uint8_t tx_gpio[2 /* port */][2 /* polarity */] = { - { GPIO_USB_CHG_CC1_TX_DATA, GPIO_USB_CHG_CC2_TX_DATA }, - { GPIO_USB_DUT_CC1_TX_DATA, GPIO_USB_DUT_CC2_TX_DATA }, -}; -static const uint8_t ref_gpio[2 /* port */][2 /* polarity */] = { - { GPIO_USB_CHG_CC1_PD, GPIO_USB_CHG_CC2_PD }, - { GPIO_USB_DUT_CC1_PD, GPIO_USB_DUT_CC2_PD }, -}; - -/* Drive the CC line from the TX block */ -static inline void pd_tx_enable(int port, int polarity) -{ -#ifndef VIF_BUILD /* genvif doesn't like tricks with GPIO macros */ - const struct gpio_info *tx = gpio_list + tx_gpio[port][polarity]; - const struct gpio_info *ref = gpio_list + ref_gpio[port][polarity]; - - /* use directly GPIO registers, latency before the PD preamble is key */ - - /* switch the TX pin Mode from Input (00) to Alternate (10) for SPI */ - STM32_GPIO_MODER(tx->port) |= 2 << ((31 - __builtin_clz(tx->mask)) * 2); - /* switch the ref pin Mode from analog (11) to Out (01) for low level */ - STM32_GPIO_MODER(ref->port) &= - ~(2 << ((31 - __builtin_clz(ref->mask)) * 2)); -#endif /* !VIF_BUILD */ -} - -/* Put the TX driver in Hi-Z state */ -static inline void pd_tx_disable(int port, int polarity) -{ - const struct gpio_info *tx = gpio_list + tx_gpio[port][polarity]; - const struct gpio_info *ref = gpio_list + ref_gpio[port][polarity]; - - gpio_set_flags_by_mask(tx->port, tx->mask, GPIO_INPUT); - gpio_set_flags_by_mask(ref->port, ref->mask, GPIO_ANALOG); -} - -/* we know the plug polarity, do the right configuration */ -static inline void pd_select_polarity(int port, int polarity) -{ - uint32_t val = STM32_COMP_CSR; - - /* Use window mode so that COMP1 and COMP2 share non-inverting input */ - val |= STM32_COMP_CMP1EN | STM32_COMP_CMP2EN | STM32_COMP_WNDWEN; - - if (port == 0) { - /* CHG use the right comparator inverted input for COMP2 */ - STM32_COMP_CSR = (val & ~STM32_COMP_CMP2INSEL_MASK) | - (polarity ? STM32_COMP_CMP2INSEL_INM4 /* PA4: C0_CC2 */ - : STM32_COMP_CMP2INSEL_INM6);/* PA2: C0_CC1 */ - } else { - /* DUT use the right comparator inverted input for COMP1 */ - STM32_COMP_CSR = (val & ~STM32_COMP_CMP1INSEL_MASK) | - (polarity ? STM32_COMP_CMP1INSEL_INM5 /* PA5: C1_CC2 */ - : STM32_COMP_CMP1INSEL_INM6);/* PA0: C1_CC1 */ - } -} - -/* Initialize pins used for TX and put them in Hi-Z */ -static inline void pd_tx_init(void) -{ - const struct gpio_info *c2 = gpio_list + GPIO_USB_CHG_CC2_TX_DATA; - const struct gpio_info *c1 = gpio_list + GPIO_USB_CHG_CC1_TX_DATA; - const struct gpio_info *d2 = gpio_list + GPIO_USB_DUT_CC2_TX_DATA; - const struct gpio_info *d1 = gpio_list + GPIO_USB_DUT_CC1_TX_DATA; - - gpio_config_module(MODULE_USB_PD, 1); - /* Select the proper alternate SPI function on TX_DATA pins */ - /* USB_CHG_CC2_TX_DATA: PA6 is SPI1 MISO (AF0) */ - gpio_set_alternate_function(c2->port, c2->mask, 0); - gpio_set_flags_by_mask(c2->port, c2->mask, GPIO_INPUT); - /* USB_CHG_CC1_TX_DATA: PB4 is SPI1 MISO (AF0) */ - gpio_set_alternate_function(c1->port, c1->mask, 0); - gpio_set_flags_by_mask(c1->port, c1->mask, GPIO_INPUT); - /* USB_DUT_CC2_TX_DATA: PC2 is SPI2 MISO (AF1) */ - gpio_set_alternate_function(d2->port, d2->mask, 1); - gpio_set_flags_by_mask(d2->port, d2->mask, GPIO_INPUT); - /* USB_DUT_CC1_TX_DATA: PB14 is SPI2 MISO (AF0) */ - gpio_set_alternate_function(d1->port, d1->mask, 0); - gpio_set_flags_by_mask(d1->port, d1->mask, GPIO_INPUT); -} - -static inline void pd_set_host_mode(int port, int enable) -{ - /* - * CHG (port == 0) port has fixed Rd attached and therefore can only - * present as a SNK device. If port != DUT (port == 1), then nothing to - * do in this function. - */ - if (!port) - return; - - if (enable) { - /* - * Servo_v4 in SRC mode acts as a DTS (debug test - * accessory) and needs to present Rp on both CC - * lines. In order to support orientation detection, and - * advertise the correct TypeC current level, the - * values of Rp1/Rp2 need to asymmetric with Rp1 > Rp2. This - * function is called without a specified Rp value so assume the - * servo_v4 default of USB level current. If a higher current - * can be supported, then the Rp value will get adjusted when - * VBUS is enabled. - */ - pd_set_rp_rd(port, TYPEC_CC_RP, TYPEC_RP_USB); - - gpio_set_flags(GPIO_USB_DUT_CC1_TX_DATA, GPIO_INPUT); - gpio_set_flags(GPIO_USB_DUT_CC2_TX_DATA, GPIO_INPUT); - } else { - /* Select Rd, the Rp value is a don't care */ - pd_set_rp_rd(port, TYPEC_CC_RD, TYPEC_RP_RESERVED); - } -} - -/** - * Initialize various GPIOs and interfaces to safe state at start of pd_task. - * - * These include: - * VBUS, charge path based on power role. - * Physical layer CC transmit. - * - * @param port USB-C port number - * @param power_role Power role of device - */ -static inline void pd_config_init(int port, uint8_t power_role) -{ - /* - * Set CC pull resistors. The PD state machine will then transit and - * enable VBUS after it detects valid voltages on CC lines. - */ - pd_set_host_mode(port, power_role); - - /* Initialize TX pins and put them in Hi-Z */ - pd_tx_init(); - -} - -int pd_adc_read(int port, int cc); - -#endif /* __CROS_EC_USB_PD_CONFIG_H */ - diff --git a/board/servo_v4/usb_pd_policy.c b/board/servo_v4/usb_pd_policy.c deleted file mode 100644 index 00eaa1e628..0000000000 --- a/board/servo_v4/usb_pd_policy.c +++ /dev/null @@ -1,1419 +0,0 @@ -/* Copyright 2017 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. - */ - -#include "atomic.h" -#include "charge_manager.h" -#include "common.h" -#include "console.h" -#include "gpio.h" -#include "hooks.h" -#include "host_command.h" -#include "i2c.h" -/* Just want the .h file for PS8742 definitions, not the large object file. */ -#define CONFIG_USB_MUX_PS8742 -#include "ps8740.h" -#undef CONFIG_USB_MUX_PS8742 -#include "registers.h" -#include "system.h" -#include "task.h" -#include "tcpm/tcpm.h" -#include "timer.h" -#include "util.h" -#include "usb_common.h" -#include "usb_mux.h" -#include "usb_pd.h" -#include "usb_pd_config.h" -#include "usb_pd_tcpm.h" - -#define CPRINTF(format, args...) cprintf(CC_USBPD, format, ## args) -#define CPRINTS(format, args...) cprints(CC_USBPD, format, ## args) - -#define DUT_PDO_FIXED_FLAGS (PDO_FIXED_DUAL_ROLE | PDO_FIXED_DATA_SWAP |\ - PDO_FIXED_COMM_CAP) - -#define CHG_PDO_FIXED_FLAGS (PDO_FIXED_DATA_SWAP) - -#define VBUS_UNCHANGED(curr, pend, new) (curr == new && pend == new) - -/* Macros to config the PD role */ -#define CONF_SET_CLEAR(c, set, clear) ((c | (set)) & ~(clear)) -#define CONF_SRC(c) CONF_SET_CLEAR(c, \ - CC_DISABLE_DTS | CC_ALLOW_SRC, \ - CC_ENABLE_DRP | CC_SNK_WITH_PD) -#define CONF_SNK(c) CONF_SET_CLEAR(c, \ - CC_DISABLE_DTS, \ - CC_ALLOW_SRC | CC_ENABLE_DRP | CC_SNK_WITH_PD) -#define CONF_PDSNK(c) CONF_SET_CLEAR(c, \ - CC_DISABLE_DTS | CC_SNK_WITH_PD, \ - CC_ALLOW_SRC | CC_ENABLE_DRP) -#define CONF_DRP(c) CONF_SET_CLEAR(c, \ - CC_DISABLE_DTS | CC_ALLOW_SRC | CC_ENABLE_DRP, \ - CC_SNK_WITH_PD) -#define CONF_SRCDTS(c) CONF_SET_CLEAR(c, \ - CC_ALLOW_SRC, \ - CC_ENABLE_DRP | CC_DISABLE_DTS | CC_SNK_WITH_PD) -#define CONF_SNKDTS(c) CONF_SET_CLEAR(c, \ - 0, \ - CC_ALLOW_SRC | CC_ENABLE_DRP | \ - CC_DISABLE_DTS | CC_SNK_WITH_PD) -#define CONF_PDSNKDTS(c) CONF_SET_CLEAR(c, \ - CC_SNK_WITH_PD, \ - CC_ALLOW_SRC | CC_ENABLE_DRP | CC_DISABLE_DTS) -#define CONF_DRPDTS(c) CONF_SET_CLEAR(c, \ - CC_ALLOW_SRC | CC_ENABLE_DRP, \ - CC_DISABLE_DTS | CC_SNK_WITH_PD) - -/* Macros to apply Rd/Rp to CC lines */ -#define DUT_ACTIVE_CC_SET(r, flags) \ - gpio_set_flags(cc_config & CC_POLARITY ? \ - CONCAT2(GPIO_USB_DUT_CC2_, r) : \ - CONCAT2(GPIO_USB_DUT_CC1_, r), \ - flags) -#define DUT_INACTIVE_CC_SET(r, flags) \ - gpio_set_flags(cc_config & CC_POLARITY ? \ - CONCAT2(GPIO_USB_DUT_CC1_, r) : \ - CONCAT2(GPIO_USB_DUT_CC2_, r), \ - flags) -#define DUT_BOTH_CC_SET(r, flags) \ - do { \ - gpio_set_flags(CONCAT2(GPIO_USB_DUT_CC1_, r), flags); \ - gpio_set_flags(CONCAT2(GPIO_USB_DUT_CC2_, r), flags); \ - } while (0) - -#define DUT_ACTIVE_CC_PU(r) DUT_ACTIVE_CC_SET(r, GPIO_OUT_HIGH) -#define DUT_INACTIVE_CC_PU(r) DUT_INACTIVE_CC_SET(r, GPIO_OUT_HIGH) -#define DUT_ACTIVE_CC_PD(r) DUT_ACTIVE_CC_SET(r, GPIO_OUT_LOW) -#define DUT_BOTH_CC_PD(r) DUT_BOTH_CC_SET(r, GPIO_OUT_LOW) -#define DUT_BOTH_CC_OPEN(r) DUT_BOTH_CC_SET(r, GPIO_INPUT) - -/* - * Dynamic PDO that reflects capabilities present on the CHG port. Allow for - * multiple entries so that we can offer greater than 5V charging. The 1st - * entry will be fixed 5V, but its current value may change based on the CHG - * port vbus info. Subsequent entries are used for when offering vbus greater - * than 5V. - */ -static const uint16_t pd_src_voltages_mv[] = { - 5000, 9000, 10000, 12000, 15000, 20000, -}; -static uint32_t pd_src_chg_pdo[ARRAY_SIZE(pd_src_voltages_mv)]; -static uint8_t chg_pdo_cnt; - -const uint32_t pd_snk_pdo[] = { - PDO_FIXED(5000, 500, CHG_PDO_FIXED_FLAGS), - PDO_BATT(4750, 21000, 15000), - PDO_VAR(4750, 21000, 3000), -}; -const int pd_snk_pdo_cnt = ARRAY_SIZE(pd_snk_pdo); - -struct vbus_prop { - int mv; - int ma; -}; -static struct vbus_prop vbus[CONFIG_USB_PD_PORT_MAX_COUNT]; -static int active_charge_port = CHARGE_PORT_NONE; -static enum charge_supplier active_charge_supplier; -static uint8_t vbus_rp = TYPEC_RP_RESERVED; - -static int cc_config = CC_ALLOW_SRC; - -/* Voltage thresholds for no connect in DTS mode */ -static int pd_src_vnc_dts[TYPEC_RP_RESERVED][2] = { - {PD_SRC_3_0_VNC_MV, PD_SRC_1_5_VNC_MV}, - {PD_SRC_1_5_VNC_MV, PD_SRC_DEF_VNC_MV}, - {PD_SRC_3_0_VNC_MV, PD_SRC_DEF_VNC_MV}, -}; -/* Voltage thresholds for Ra attach in DTS mode */ -static int pd_src_rd_threshold_dts[TYPEC_RP_RESERVED][2] = { - {PD_SRC_3_0_RD_THRESH_MV, PD_SRC_1_5_RD_THRESH_MV}, - {PD_SRC_1_5_RD_THRESH_MV, PD_SRC_DEF_RD_THRESH_MV}, - {PD_SRC_3_0_RD_THRESH_MV, PD_SRC_DEF_RD_THRESH_MV}, -}; -/* Voltage thresholds for no connect in normal SRC mode */ -static int pd_src_vnc[TYPEC_RP_RESERVED] = { - PD_SRC_DEF_VNC_MV, - PD_SRC_1_5_VNC_MV, - PD_SRC_3_0_VNC_MV, -}; -/* Voltage thresholds for Ra attach in normal SRC mode */ -static int pd_src_rd_threshold[TYPEC_RP_RESERVED] = { - PD_SRC_DEF_RD_THRESH_MV, - PD_SRC_1_5_RD_THRESH_MV, - PD_SRC_3_0_RD_THRESH_MV, -}; - -/* Saved value for the duration of faking PD disconnect */ -static int fake_pd_disconnect_duration_us; - -/* Shadow what would be in TCPC register state. */ -static int rp_value_stored = TYPEC_RP_USB; -static int cc_pull_stored = TYPEC_CC_RD; - -/* - * Set the USB PD max voltage to value appropriate for the board version. - * The red/blue versions of servo_v4 have an ESD between VBUS and CC1/CC2 - * that has a breakdown voltage of 11V. - */ -#define MAX_MV_RED_BLUE 9000 - -static int user_limited_max_mv = 20000; - -static uint8_t allow_pr_swap = 1; -static uint8_t allow_dr_swap = 1; - -static uint32_t max_supported_voltage(void) -{ - int board_max_mv = board_get_version() >= BOARD_VERSION_BLACK ? - PD_MAX_VOLTAGE_MV : MAX_MV_RED_BLUE; - - return board_max_mv < user_limited_max_mv ? board_max_mv : - user_limited_max_mv; -} - -static int charge_port_is_active(void) -{ - return active_charge_port == CHG && vbus[CHG].mv > 0; -} - -static int is_charge_through_allowed(void) -{ - return charge_port_is_active() && cc_config & CC_ALLOW_SRC; -} - -static int get_dual_role_of_src(void) -{ - return cc_config & CC_ENABLE_DRP ? PD_DRP_TOGGLE_ON : - PD_DRP_FORCE_SOURCE; -} - -static void dut_allow_charge(void) -{ - /* - * Update to charge enable if charger still present and not - * already charging. - */ - if (is_charge_through_allowed() && - pd_get_dual_role(DUT) != PD_DRP_FORCE_SOURCE && - pd_get_dual_role(DUT) != PD_DRP_TOGGLE_ON) { - CPRINTS("Enable DUT charge through"); - pd_set_dual_role(DUT, get_dual_role_of_src()); - /* - * If DRP role, don't set any CC pull resistor, the PD - * state machine will toggle and set the pull resistors - * when needed. - */ - if (!(cc_config & CC_ENABLE_DRP)) - pd_set_host_mode(DUT, 1); - - /* - * Enable PD comm. The PD comm may be disabled during - * the power charge-through was detached. - */ - pd_comm_enable(DUT, 1); - - pd_update_contract(DUT); - } -} -DECLARE_DEFERRED(dut_allow_charge); - -static void board_manage_dut_port(void) -{ - enum pd_dual_role_states allowed_role; - enum pd_dual_role_states current_role; - - /* - * This function is called by the CHG port whenever there has been a - * change in its vbus voltage or current. That change may necessitate - * that the DUT port present a different Rp value or renogiate its PD - * contract if it is connected. - */ - - /* Assume the default value of Rd */ - allowed_role = PD_DRP_FORCE_SINK; - - /* If VBUS charge through is available, mark as such. */ - if (is_charge_through_allowed()) - allowed_role = get_dual_role_of_src(); - - current_role = pd_get_dual_role(DUT); - if (current_role != allowed_role) { - /* Update role. */ - if (allowed_role == PD_DRP_FORCE_SINK) { - /* We've lost charge through. Disable VBUS. */ - gpio_set_level(GPIO_DUT_CHG_EN, 0); - - /* Mark as SNK only. */ - pd_set_dual_role(DUT, PD_DRP_FORCE_SINK); - pd_set_host_mode(DUT, 0); - - /* - * Disable PD comm. It matches the user expectation that - * unplugging the power charge-through makes servo v4 as - * a passive hub, without any PD support. - * - * There is an exception that servo v4 is explicitly set - * to have PD, like the "pnsnk" mode. - */ - pd_comm_enable(DUT, cc_config & CC_SNK_WITH_PD ? 1 : 0); - } else { - /* Allow charge through after PD negotiate. */ - hook_call_deferred(&dut_allow_charge_data, 2000 * MSEC); - } - } - - /* - * Update PD contract to reflect new available CHG - * voltage/current values. - */ - pd_update_contract(DUT); -} - -static void update_ports(void) -{ - int pdo_index, src_index, snk_index, i; - uint32_t pdo, max_ma, max_mv, unused; - - /* - * CHG Vbus has changed states, update PDO that reflects CHG port - * state - */ - if (!charge_port_is_active()) { - /* CHG Vbus has dropped, so become SNK. */ - chg_pdo_cnt = 0; - } else { - /* Advertise the 'best' PDOs at various discrete voltages */ - if (active_charge_supplier == CHARGE_SUPPLIER_PD) { - src_index = 0; - snk_index = -1; - - for (i = 0; i < ARRAY_SIZE(pd_src_voltages_mv); ++i) { - /* Adhere to board voltage limits */ - if (pd_src_voltages_mv[i] > - max_supported_voltage()) - break; - - /* Find the 'best' PDO <= voltage */ - pdo_index = - pd_find_pdo_index(pd_get_src_cap_cnt(CHG), - pd_get_src_caps(CHG), - pd_src_voltages_mv[i], &pdo); - /* Don't duplicate PDOs */ - if (pdo_index == snk_index) - continue; - /* Skip battery / variable PDOs */ - if ((pdo & PDO_TYPE_MASK) != PDO_TYPE_FIXED) - continue; - - snk_index = pdo_index; - pd_extract_pdo_power(pdo, &max_ma, &max_mv, - &unused); - pd_src_chg_pdo[src_index++] = - PDO_FIXED_VOLT(max_mv) | - PDO_FIXED_CURR(max_ma) | - DUT_PDO_FIXED_FLAGS | - PDO_FIXED_UNCONSTRAINED; - } - chg_pdo_cnt = src_index; - } else { - /* 5V PDO */ - pd_src_chg_pdo[0] = PDO_FIXED_VOLT(PD_MIN_MV) | - PDO_FIXED_CURR(vbus[CHG].ma) | - DUT_PDO_FIXED_FLAGS | - PDO_FIXED_UNCONSTRAINED; - - chg_pdo_cnt = 1; - } - } - - /* Call DUT port manager to update Rp and possible PD contract */ - board_manage_dut_port(); -} - -int board_set_active_charge_port(int charge_port) -{ - if (charge_port == DUT) - return -1; - - active_charge_port = charge_port; - update_ports(); - - if (!charge_port_is_active()) - /* Don't negotiate > 5V, except in lockstep with DUT */ - pd_set_external_voltage_limit(CHG, PD_MIN_MV); - - return 0; -} - -void board_set_charge_limit(int port, int supplier, int charge_ma, - int max_ma, int charge_mv) -{ - if (port != CHG) - return; - - active_charge_supplier = supplier; - - /* Update the voltage/current values for CHG port */ - vbus[CHG].ma = charge_ma; - vbus[CHG].mv = charge_mv; - update_ports(); -} - -__override uint8_t board_get_src_dts_polarity(int port) -{ - /* - * When servo configured as srcdts, the CC polarity is based - * on the flags. - */ - if (port == DUT) - return !!(cc_config & CC_POLARITY); - - return 0; -} - -int pd_tcpc_cc_nc(int port, int cc_volt, int cc_sel) -{ - int rp_index; - int nc; - - /* Can never be called from CHG port as it's sink only */ - if (port == CHG) - return 0; - - rp_index = vbus_rp; - /* - * If rp_index > 2, then always return not connected. This case should - * only happen when all Rp GPIO controls are tri-stated. - */ - if (rp_index >= TYPEC_RP_RESERVED) - return 1; - - /* Select the correct voltage threshold for current Rp and DTS mode */ - if (cc_config & CC_DISABLE_DTS) - nc = cc_volt >= pd_src_vnc[rp_index]; - else - nc = cc_volt >= pd_src_vnc_dts[rp_index][ - cc_config & CC_POLARITY ? !cc_sel : cc_sel]; - - return nc; -} - -int pd_tcpc_cc_ra(int port, int cc_volt, int cc_sel) -{ - int rp_index; - int ra; - - /* Can never be called from CHG port as it's sink only */ - if (port == CHG) - return 0; - - rp_index = vbus_rp; - /* - * If rp_index > 2, then can't be Ra. This case should - * only happen when all Rp GPIO controls are tri-stated. - */ - if (rp_index >= TYPEC_RP_RESERVED) - return 0; - - /* Select the correct voltage threshold for current Rp and DTS mode */ - if (cc_config & CC_DISABLE_DTS) - ra = cc_volt < pd_src_rd_threshold[rp_index]; - else - ra = cc_volt < pd_src_rd_threshold_dts[rp_index][ - cc_config & CC_POLARITY ? !cc_sel : cc_sel]; - - return ra; -} - -/* DUT CC readings aren't valid if we aren't applying CC pulls */ -bool cc_is_valid(void) -{ - if ((cc_config & CC_DETACH) || (cc_pull_stored == TYPEC_CC_OPEN) || - ((cc_pull_stored == TYPEC_CC_RP) && - (rp_value_stored == TYPEC_RP_RESERVED))) - return false; - return true; -} - -int pd_adc_read(int port, int cc) -{ - int mv; - if (port == 0) - mv = adc_read_channel(cc ? ADC_CHG_CC2_PD : ADC_CHG_CC1_PD); - else if (cc_is_valid()) { - /* - * In servo v4 hardware logic, both CC lines are wired directly - * to DUT. When servo v4 as a snk, DUT may source Vconn to CC2 - * (CC1 if polarity flip) and make the voltage high as vRd-3.0, - * which makes the PD state mess up. As the PD state machine - * doesn't handle this case. It assumes that CC2 (CC1 if - * polarity flip) is separated by a Type-C cable, resulting a - * voltage lower than the max of vRa. - * - * It fakes the voltage within vRa. - */ - if ((cc_config & CC_DISABLE_DTS) && - cc_pull_stored == TYPEC_CC_RD && port == DUT && - cc == (cc_config & CC_POLARITY ? 0 : 1)) - mv = 0; - else - mv = adc_read_channel(cc ? ADC_DUT_CC2_PD : - ADC_DUT_CC1_PD); - } else { - /* - * When emulating detach, fake the voltage on CC to 0 to avoid - * triggering some debounce logic. - * - * The servo v4 makes Rd/Rp open but the DUT may present Rd/Rp - * alternatively that makes the voltage on CC falls into some - * unexpected range and triggers the PD state machine switching - * between SNK_DISCONNECTED and SNK_DISCONNECTED_DEBOUNCE. - */ - mv = 0; - } - return mv; -} - -static int board_set_rp(int rp) -{ - if (cc_config & CC_DISABLE_DTS) { - /* - * DTS mode is disabled, so only present the requested Rp value - * on CC1 (active) and leave all Rp/Rd resistors on CC2 - * (inactive) disconnected. - */ - switch (rp) { - case TYPEC_RP_USB: - DUT_ACTIVE_CC_PU(RPUSB); - break; - case TYPEC_RP_1A5: - DUT_ACTIVE_CC_PU(RP1A5); - break; - case TYPEC_RP_3A0: - DUT_ACTIVE_CC_PU(RP3A0); - break; - case TYPEC_RP_RESERVED: - /* - * This case can be used to force a detach event since - * all values are set to inputs above. Nothing else to - * set. - */ - break; - default: - return EC_ERROR_INVAL; - } - } else { - /* DTS mode is enabled. The rp parameter is used to select the - * Type C current limit to advertise. The combinations of Rp on - * each CC line is shown in the table below. - * - * CC values for Debug sources (DTS) - * - * Source type Mode of Operation CC1 CC2 - * --------------------------------------------- - * DTS Default USB Power Rp3A0 Rp1A5 - * DTS USB-C @ 1.5 A Rp1A5 RpUSB - * DTS USB-C @ 3 A Rp3A0 RpUSB - */ - switch (rp) { - case TYPEC_RP_USB: - DUT_ACTIVE_CC_PU(RP3A0); - DUT_INACTIVE_CC_PU(RP1A5); - break; - case TYPEC_RP_1A5: - DUT_ACTIVE_CC_PU(RP1A5); - DUT_INACTIVE_CC_PU(RPUSB); - break; - case TYPEC_RP_3A0: - DUT_ACTIVE_CC_PU(RP3A0); - DUT_INACTIVE_CC_PU(RPUSB); - break; - case TYPEC_RP_RESERVED: - /* - * This case can be used to force a detach event since - * all values are set to inputs above. Nothing else to - * set. - */ - break; - default: - return EC_ERROR_INVAL; - } - } - /* Save new Rp value for DUT port */ - vbus_rp = rp; - - return EC_SUCCESS; -} - -int pd_set_rp_rd(int port, int cc_pull, int rp_value) -{ - int rv = EC_SUCCESS; - - if (port != 1) - return EC_ERROR_UNIMPLEMENTED; - - /* CC is disabled for emulating detach. Don't change Rd/Rp. */ - if (cc_config & CC_DETACH) - return EC_SUCCESS; - - /* By default disconnect all Rp/Rd resistors from both CC lines */ - /* Set Rd for CC1/CC2 to High-Z. */ - DUT_BOTH_CC_OPEN(RD); - /* Set Rp for CC1/CC2 to High-Z. */ - DUT_BOTH_CC_OPEN(RP3A0); - DUT_BOTH_CC_OPEN(RP1A5); - DUT_BOTH_CC_OPEN(RPUSB); - /* Set TX Hi-Z */ - DUT_BOTH_CC_OPEN(TX_DATA); - - if (cc_pull == TYPEC_CC_RP) { - rv = board_set_rp(rp_value); - } else if (cc_pull == TYPEC_CC_RD) { - /* - * The DUT port uses a captive cable. It can present Rd on both - * CC1 and CC2. If DTS mode is enabled, then present Rd on both - * CC lines. However, if DTS mode is disabled only present Rd on - * CC1 (active). - */ - if (cc_config & CC_DISABLE_DTS) - DUT_ACTIVE_CC_PD(RD); - else - DUT_BOTH_CC_PD(RD); - - } - - rp_value_stored = rp_value; - cc_pull_stored = cc_pull; - - return rv; -} - -int board_select_rp_value(int port, int rp) -{ - if (port != 1) - return EC_ERROR_UNIMPLEMENTED; - - /* - * Update Rp value to indicate non-pd power available. - * Do not change pull direction though. - */ - if ((rp != rp_value_stored) && (cc_pull_stored == TYPEC_CC_RP)) { - rp_value_stored = rp; - return pd_set_rp_rd(port, TYPEC_CC_RP, rp); - } - - return EC_SUCCESS; -} - -int charge_manager_get_source_pdo(const uint32_t **src_pdo, const int port) -{ - int pdo_cnt = 0; - - /* - * If CHG is providing VBUS, then advertise what's available on the CHG - * port, otherwise we provide no power. - */ - if (charge_port_is_active()) { - *src_pdo = pd_src_chg_pdo; - pdo_cnt = chg_pdo_cnt; - } - - return pdo_cnt; -} - -__override void pd_transition_voltage(int idx) -{ - timestamp_t deadline; - uint32_t ma, mv, unused; - - pd_extract_pdo_power(pd_src_chg_pdo[idx - 1], &ma, &mv, &unused); - /* Is this a transition to a new voltage? */ - if (charge_port_is_active() && vbus[CHG].mv != mv) { - /* - * Alter voltage limit on charge port, this should cause - * the port to select the desired PDO. - */ - pd_set_external_voltage_limit(CHG, mv); - - /* Wait for CHG transition */ - deadline.val = get_time().val + PD_T_PS_TRANSITION; - CPRINTS("Waiting for CHG port transition"); - while (charge_port_is_active() && - vbus[CHG].mv != mv && - get_time().val < deadline.val) - msleep(10); - - if (vbus[CHG].mv != mv) { - CPRINTS("Missed CHG transition, resetting DUT"); - pd_power_supply_reset(DUT); - return; - } - - CPRINTS("CHG transitioned"); - } - - vbus[DUT].mv = vbus[CHG].mv; - vbus[DUT].ma = vbus[CHG].ma; -} - -int pd_set_power_supply_ready(int port) -{ - /* Port 0 can never provide vbus. */ - if (port == CHG) - return EC_ERROR_INVAL; - - if (charge_port_is_active()) { - /* Enable VBUS */ - gpio_set_level(GPIO_DUT_CHG_EN, 1); - - if (vbus[CHG].mv != PD_MIN_MV) - CPRINTS("ERROR, CHG port voltage %d != PD_MIN_MV", - vbus[CHG].mv); - - vbus[DUT].mv = vbus[CHG].mv; - vbus[DUT].ma = vbus[CHG].mv; - pd_set_dual_role(DUT, get_dual_role_of_src()); - } else { - vbus[DUT].mv = 0; - vbus[DUT].ma = 0; - gpio_set_level(GPIO_DUT_CHG_EN, 0); - pd_set_dual_role(DUT, PD_DRP_FORCE_SINK); - return EC_ERROR_NOT_POWERED; - } - - return EC_SUCCESS; /* we are ready */ -} - -void pd_power_supply_reset(int port) -{ - /* Port 0 can never provide vbus. */ - if (port == CHG) - return; - - /* Disable VBUS */ - gpio_set_level(GPIO_DUT_CHG_EN, 0); - - /* DUT is lost, back to 5V limit on CHG */ - pd_set_external_voltage_limit(CHG, PD_MIN_MV); -} - -int pd_snk_is_vbus_provided(int port) -{ - - return gpio_get_level(port ? GPIO_USB_DET_PP_DUT : - GPIO_USB_DET_PP_CHG); -} - -__override int pd_check_power_swap(int port) -{ - /* - * When only host VBUS is available, then servo_v4 is not setting - * PDO_FIXED_UNCONSTRAINED in the src_pdo sent to the DUT. When this bit - * is not set, the DUT will always attempt to swap its power role to - * SRC. Let servo_v4 have more control over its power role by always - * rejecting power swap requests from the DUT. - */ - - /* Port 0 can never provide vbus. */ - if (port == CHG) - return 0; - - if (pd_get_power_role(port) == PD_ROLE_SINK && !(cc_config & CC_ALLOW_SRC)) - return 0; - - if (pd_snk_is_vbus_provided(CHG)) - return allow_pr_swap; - - return 0; -} - -__override int pd_check_data_swap(int port, - enum pd_data_role data_role) -{ - /* - * Servo should allow data role swaps to let DUT see the USB hub, but - * doing it on CHG port is a waste as its data lines is unconnected. - */ - if (port == CHG) - return 0; - - return allow_dr_swap; -} - -__override void pd_execute_data_swap(int port, - enum pd_data_role data_role) -{ - /* - * TODO(b/137887386): Turn on the fastboot/DFU path when data swap to - * DFP? - */ -} - -__override void pd_check_pr_role(int port, - enum pd_power_role pr_role, - int flags) -{ - /* - * Don't define any policy to initiate power role swap. - * - * CHG port is SNK only. DUT port requires a user to switch its - * role by commands. So don't do anything implicitly. - */ -} - -__override void pd_check_dr_role(int port, - enum pd_data_role dr_role, - int flags) -{ - if (port == CHG) - return; - - /* If DFP, try to switch to UFP, to let DUT see the USB hub. */ - if ((flags & PD_FLAGS_PARTNER_DR_DATA) && dr_role == PD_ROLE_DFP) - pd_request_data_swap(port); -} - - -/* ----------------- Vendor Defined Messages ------------------ */ -/* - * DP alt-mode config, user configurable. - * Default is the mode disabled, supporting the C and D pin assignment, - * multi-function preferred, and a plug. - */ -static int alt_dp_config = (ALT_DP_PIN_C | ALT_DP_PIN_D | ALT_DP_MF_PREF | - ALT_DP_PLUG); - -/** - * Get the pins based on the user config. - */ -static int alt_dp_config_pins(void) -{ - int pins = 0; - - if (alt_dp_config & ALT_DP_PIN_C) - pins |= MODE_DP_PIN_C; - if (alt_dp_config & ALT_DP_PIN_D) - pins |= MODE_DP_PIN_D; - if (alt_dp_config & ALT_DP_PIN_E) - pins |= MODE_DP_PIN_E; - return pins; -} - -/** - * Get the cable outlet value (plug or receptacle) based on the user config. - */ -static int alt_dp_config_cable(void) -{ - return (alt_dp_config & ALT_DP_PLUG) ? CABLE_PLUG : CABLE_RECEPTACLE; -} - -const uint32_t vdo_idh = VDO_IDH(0, /* data caps as USB host */ - 1, /* data caps as USB device */ - IDH_PTYPE_AMA, /* Alternate mode */ - 1, /* supports alt modes */ - USB_VID_GOOGLE); - -const uint32_t vdo_product = VDO_PRODUCT(CONFIG_USB_PID, CONFIG_USB_BCD_DEV); - -const uint32_t vdo_ama = VDO_AMA(CONFIG_USB_PD_IDENTITY_HW_VERS, - CONFIG_USB_PD_IDENTITY_SW_VERS, - 0, 0, 0, 0, /* SS[TR][12] */ - 0, /* Vconn power */ - 0, /* Vconn power required */ - 0, /* Vbus power required */ - AMA_USBSS_U31_GEN1 /* USB SS support */); - -static int svdm_response_identity(int port, uint32_t *payload) -{ - int dp_supported = (alt_dp_config & ALT_DP_ENABLE) != 0; - - if (dp_supported) { - payload[VDO_I(IDH)] = vdo_idh; - payload[VDO_I(CSTAT)] = VDO_CSTAT(0); - payload[VDO_I(PRODUCT)] = vdo_product; - payload[VDO_I(AMA)] = vdo_ama; - return VDO_I(AMA) + 1; - } else { - return 0; - } -} - -static int svdm_response_svids(int port, uint32_t *payload) -{ - payload[1] = VDO_SVID(USB_SID_DISPLAYPORT, 0); - return 2; -} - -#define MODE_CNT 1 -#define OPOS 1 - -/* - * The Type-C demux PS8742 supports pin assignment C, D, and E. Response the DP - * capabilities with supporting all of them. - */ -uint32_t vdo_dp_mode[MODE_CNT]; - -static int svdm_response_modes(int port, uint32_t *payload) -{ - vdo_dp_mode[0] = - VDO_MODE_DP(0, /* UFP pin cfg supported: none */ - alt_dp_config_pins(), /* DFP pin */ - 1, /* no usb2.0 signalling in AMode */ - alt_dp_config_cable(), /* plug or receptacle */ - MODE_DP_V13, /* DPv1.3 Support, no Gen2 */ - MODE_DP_SNK); /* Its a sink only */ - - /* CCD uses the SBU lines; don't enable DP when dts-mode enabled */ - if (!(cc_config & CC_DISABLE_DTS)) - return 0; /* NAK */ - - if (PD_VDO_VID(payload[0]) != USB_SID_DISPLAYPORT) - return 0; /* NAK */ - - memcpy(payload + 1, vdo_dp_mode, sizeof(vdo_dp_mode)); - return MODE_CNT + 1; -} - -static int is_typec_dp_muxed(void) -{ - int value; - - i2c_read8(I2C_PORT_MASTER, PS8740_I2C_ADDR0_FLAG, PS8740_REG_MODE, - &value); - return value & PS8740_MODE_DP_ENABLED ? 1 : 0; -} - -static void set_typec_mux(int pin_cfg) -{ - int value; - - switch (pin_cfg) { - case 0: - value = 0; - CPRINTS("PinCfg:off"); - break; - case MODE_DP_PIN_C: - value = PS8740_MODE_DP_ENABLED; - CPRINTS("PinCfg:C"); - break; - case MODE_DP_PIN_D: - value = PS8740_MODE_DP_ENABLED | PS8740_MODE_USB_ENABLED; - CPRINTS("PinCfg:D"); - break; - case MODE_DP_PIN_E: - value = PS8740_MODE_DP_ENABLED | PS8740_MODE_CE_DP_ENABLED; - CPRINTS("PinCfg:E"); - break; - default: - CPRINTS("PinCfg not supported: %d", pin_cfg); - return; - } - if (value && cc_config & CC_POLARITY) - value |= PS8740_MODE_POLARITY_INVERTED; - i2c_write8(I2C_PORT_MASTER, PS8740_I2C_ADDR0_FLAG, PS8740_REG_MODE, - value); -} - -static int get_hpd_level(void) -{ - if (alt_dp_config & ALT_DP_OVERRIDE_HPD) - return (alt_dp_config & ALT_DP_HPD_LVL) != 0; - else - return gpio_get_level(GPIO_DP_HPD); -} - -static int dp_status(int port, uint32_t *payload) -{ - int opos = PD_VDO_OPOS(payload[0]); - int hpd = get_hpd_level(); - - if (opos != OPOS) - return 0; /* NAK */ - - payload[1] = VDO_DP_STATUS( - 0, /* IRQ_HPD */ - hpd, /* HPD_HI|LOW */ - 0, /* request exit DP */ - 0, /* request exit USB */ - (alt_dp_config & ALT_DP_MF_PREF) != 0, /* MF pref */ - is_typec_dp_muxed(), - 0, /* power low */ - hpd ? 0x2 : 0); - return 2; -} - -static int dp_config(int port, uint32_t *payload) -{ - if (PD_DP_CFG_DPON(payload[1])) - set_typec_mux(PD_DP_CFG_PIN(payload[1])); - - return 1; -} - -/* Whether alternate mode has been entered or not */ -static int alt_mode; - -static int svdm_enter_mode(int port, uint32_t *payload) -{ - /* SID & mode request is valid */ - if ((PD_VDO_VID(payload[0]) != USB_SID_DISPLAYPORT) || - (PD_VDO_OPOS(payload[0]) != OPOS)) - return 0; /* NAK */ - - alt_mode = OPOS; - return 1; -} - -int pd_alt_mode(int port, enum tcpci_msg_type type, uint16_t svid) -{ - if (type == TCPCI_MSG_SOP && svid == USB_SID_DISPLAYPORT) - return alt_mode; - - return 0; -} - -static int svdm_exit_mode(int port, uint32_t *payload) -{ - if (PD_VDO_VID(payload[0]) == USB_SID_DISPLAYPORT) - set_typec_mux(0); - - alt_mode = 0; - - return 1; /* Must return ACK */ -} - -static struct amode_fx dp_fx = { - .status = &dp_status, - .config = &dp_config, -}; - -const struct svdm_response svdm_rsp = { - .identity = &svdm_response_identity, - .svids = &svdm_response_svids, - .modes = &svdm_response_modes, - .enter_mode = &svdm_enter_mode, - .amode = &dp_fx, - .exit_mode = &svdm_exit_mode, -}; - -__override int pd_custom_vdm(int port, int cnt, uint32_t *payload, - uint32_t **rpayload) -{ - int cmd = PD_VDO_CMD(payload[0]); - - /* make sure we have some payload */ - if (cnt == 0) - return 0; - - switch (cmd) { - case VDO_CMD_VERSION: - /* guarantee last byte of payload is null character */ - *(payload + cnt - 1) = 0; - CPRINTF("ver: %s\n", (char *)(payload+1)); - break; - case VDO_CMD_CURRENT: - CPRINTF("Current: %dmA\n", payload[1]); - break; - } - - return 0; -} - -__override const struct svdm_amode_fx supported_modes[] = {}; -__override const int supported_modes_cnt = ARRAY_SIZE(supported_modes); - -static void print_cc_mode(void) -{ - /* Get current CCD status */ - ccprintf("cc: %s\n", cc_config & CC_DETACH ? "off" : "on"); - ccprintf("dts mode: %s\n", cc_config & CC_DISABLE_DTS ? "off" : "on"); - ccprintf("chg mode: %s\n", - gpio_get_level(GPIO_DUT_CHG_EN) ? "on" : "off"); - ccprintf("chg allowed: %s\n", cc_config & CC_ALLOW_SRC ? "on" : "off"); - ccprintf("drp enabled: %s\n", cc_config & CC_ENABLE_DRP ? "on" : "off"); - ccprintf("cc polarity: %s\n", cc_config & CC_POLARITY ? "cc2" : - "cc1"); - ccprintf("pd enabled: %s\n", pd_comm_is_enabled(DUT) ? "on" : "off"); -} - - -static void do_cc(int cc_config_new) -{ - int chargeable; - int dualrole; - - if (cc_config_new != cc_config) { - if (!(cc_config & CC_DETACH)) { - /* Force detach */ - gpio_set_level(GPIO_DUT_CHG_EN, 0); - /* Always set to 0 here so both CC lines are changed */ - cc_config &= ~(CC_DISABLE_DTS & CC_ALLOW_SRC); - - /* Remove Rp/Rd on both CC lines */ - pd_comm_enable(DUT, 0); - pd_set_rp_rd(DUT, TYPEC_CC_RP, TYPEC_RP_RESERVED); - - /* - * If just changing mode (cc keeps enabled), give some - * time for DUT to detach, use tErrorRecovery. - */ - if (!(cc_config_new & CC_DETACH)) - usleep(PD_T_ERROR_RECOVERY); - } - - if ((cc_config & ~cc_config_new) & CC_DISABLE_DTS) { - /* DTS-disabled -> DTS-enabled */ - ccd_enable(1); - ext_hpd_detection_enable(0); - } else if ((cc_config_new & ~cc_config) & CC_DISABLE_DTS) { - /* DTS-enabled -> DTS-disabled */ - ccd_enable(0); - if (!(alt_dp_config & ALT_DP_OVERRIDE_HPD)) - ext_hpd_detection_enable(1); - } - - /* Accept new cc_config value */ - cc_config = cc_config_new; - - if (!(cc_config & CC_DETACH)) { - /* Can we source? */ - chargeable = is_charge_through_allowed(); - dualrole = chargeable ? get_dual_role_of_src() : - PD_DRP_FORCE_SINK; - pd_set_dual_role(DUT, dualrole); - /* - * If force_source or force_sink role, explicitly set - * the Rp or Rd resistors on CC lines. - * - * If DRP role, don't set any CC pull resistor, the PD - * state machine will toggle and set the pull resistors - * when needed. - */ - if (dualrole != PD_DRP_TOGGLE_ON) - pd_set_host_mode(DUT, chargeable); - - /* - * For the normal lab use, emulating a sink has no PD - * comm, like a passive hub. For the PD FAFT use, we - * need to validate some PD behavior, so a flag - * CC_SNK_WITH_PD to force enabling PD comm. - */ - if (cc_config & CC_SNK_WITH_PD) - pd_comm_enable(DUT, 1); - else - pd_comm_enable(DUT, chargeable); - } - } -} - -static int command_cc(int argc, char **argv) -{ - int cc_config_new = cc_config; - - if (argc < 2) { - print_cc_mode(); - return EC_SUCCESS; - } - - if (!strcasecmp(argv[1], "off")) { - cc_config_new |= CC_DETACH; - } else if (!strcasecmp(argv[1], "on")) { - cc_config_new &= ~CC_DETACH; - } else { - cc_config_new &= ~CC_DETACH; - if (!strcasecmp(argv[1], "src")) - cc_config_new = CONF_SRC(cc_config_new); - else if (!strcasecmp(argv[1], "snk")) - cc_config_new = CONF_SNK(cc_config_new); - else if (!strcasecmp(argv[1], "pdsnk")) - cc_config_new = CONF_PDSNK(cc_config_new); - else if (!strcasecmp(argv[1], "drp")) - cc_config_new = CONF_DRP(cc_config_new); - else if (!strcasecmp(argv[1], "srcdts")) - cc_config_new = CONF_SRCDTS(cc_config_new); - else if (!strcasecmp(argv[1], "snkdts")) - cc_config_new = CONF_SNKDTS(cc_config_new); - else if (!strcasecmp(argv[1], "pdsnkdts")) - cc_config_new = CONF_PDSNKDTS(cc_config_new); - else if (!strcasecmp(argv[1], "drpdts")) - cc_config_new = CONF_DRPDTS(cc_config_new); - else - return EC_ERROR_PARAM2; - } - - if (!strcasecmp(argv[2], "cc1")) - cc_config_new &= ~CC_POLARITY; - else if (!strcasecmp(argv[2], "cc2")) - cc_config_new |= CC_POLARITY; - else if (argc >= 3) - return EC_ERROR_PARAM3; - - do_cc(cc_config_new); - print_cc_mode(); - - return EC_SUCCESS; -} -DECLARE_CONSOLE_COMMAND(cc, command_cc, - "[off|on|src|snk|pdsnk|drp|srcdts|snkdts|pdsnkdts|" - "drpdts] [cc1|cc2]", - "Servo_v4 DTS and CHG mode"); - -static void fake_disconnect_end(void) -{ - /* Reenable CC lines with previous dts and src modes */ - do_cc(cc_config & ~CC_DETACH); -} -DECLARE_DEFERRED(fake_disconnect_end); - -static void fake_disconnect_start(void) -{ - /* Disable CC lines */ - do_cc(cc_config | CC_DETACH); - - hook_call_deferred(&fake_disconnect_end_data, - fake_pd_disconnect_duration_us); -} -DECLARE_DEFERRED(fake_disconnect_start); - -static int cmd_fake_disconnect(int argc, char *argv[]) -{ - int delay_ms, duration_ms; - char *e; - - if (argc < 3) - return EC_ERROR_PARAM_COUNT; - - delay_ms = strtoi(argv[1], &e, 0); - if (*e || delay_ms < 0) - return EC_ERROR_PARAM1; - duration_ms = strtoi(argv[2], &e, 0); - if (*e || duration_ms < 0) - return EC_ERROR_PARAM2; - - /* Cancel any pending function calls */ - hook_call_deferred(&fake_disconnect_start_data, -1); - hook_call_deferred(&fake_disconnect_end_data, -1); - - fake_pd_disconnect_duration_us = duration_ms * MSEC; - hook_call_deferred(&fake_disconnect_start_data, delay_ms * MSEC); - - ccprintf("Fake disconnect for %d ms starting in %d ms.\n", - duration_ms, delay_ms); - - return EC_SUCCESS; -} -DECLARE_CONSOLE_COMMAND(fakedisconnect, cmd_fake_disconnect, - "<delay_ms> <duration_ms>", NULL); - -static int cmd_ada_srccaps(int argc, char *argv[]) -{ - int i; - const uint32_t * const ada_srccaps = pd_get_src_caps(CHG); - - for (i = 0; i < pd_get_src_cap_cnt(CHG); ++i) { - uint32_t max_ma, max_mv, unused; - - if (IS_ENABLED(CONFIG_USB_PD_ONLY_FIXED_PDOS) && - (ada_srccaps[i] & PDO_TYPE_MASK) != PDO_TYPE_FIXED) - continue; - - pd_extract_pdo_power(ada_srccaps[i], &max_ma, &max_mv, &unused); - ccprintf("%d: %dmV/%dmA\n", i, max_mv, max_ma); - } - - return EC_SUCCESS; -} -DECLARE_CONSOLE_COMMAND(ada_srccaps, cmd_ada_srccaps, - "", - "Print adapter SrcCap"); - -static int cmd_dp_action(int argc, char *argv[]) -{ - int i; - char *e; - - if (argc < 1) - return EC_ERROR_PARAM_COUNT; - - if (argc == 1) { - CPRINTS("DP alt-mode: %s", - (alt_dp_config & ALT_DP_ENABLE) ? "enable" : "disable"); - } - - if (!strcasecmp(argv[1], "enable")) { - alt_dp_config |= ALT_DP_ENABLE; - } else if (!strcasecmp(argv[1], "disable")) { - alt_dp_config &= ~ALT_DP_ENABLE; - } else if (!strcasecmp(argv[1], "pins")) { - if (argc >= 3) { - alt_dp_config &= ~(ALT_DP_PIN_C | ALT_DP_PIN_D | - ALT_DP_PIN_E); - for (i = 0; i < 3; i++) { - if (!argv[2][i]) - break; - - switch (argv[2][i]) { - case 'c': - case 'C': - alt_dp_config |= ALT_DP_PIN_C; - break; - case 'd': - case 'D': - alt_dp_config |= ALT_DP_PIN_D; - break; - case 'e': - case 'E': - alt_dp_config |= ALT_DP_PIN_E; - break; - } - } - } - CPRINTS("Pins: %s%s%s", - (alt_dp_config & ALT_DP_PIN_C) ? "C" : "", - (alt_dp_config & ALT_DP_PIN_D) ? "D" : "", - (alt_dp_config & ALT_DP_PIN_E) ? "E" : ""); - } else if (!strcasecmp(argv[1], "mf")) { - if (argc >= 3) { - i = strtoi(argv[2], &e, 10); - if (*e) - return EC_ERROR_PARAM3; - if (i) - alt_dp_config |= ALT_DP_MF_PREF; - else - alt_dp_config &= ~ALT_DP_MF_PREF; - } - CPRINTS("MF pref: %d", (alt_dp_config & ALT_DP_MF_PREF) != 0); - } else if (!strcasecmp(argv[1], "plug")) { - if (argc >= 3) { - i = strtoi(argv[2], &e, 10); - if (*e) - return EC_ERROR_PARAM3; - if (i) - alt_dp_config |= ALT_DP_PLUG; - else - alt_dp_config &= ~ALT_DP_PLUG; - } - CPRINTS("Plug or receptacle: %d", - (alt_dp_config & ALT_DP_PLUG) != 0); - } else if (!strcasecmp(argv[1], "hpd")) { - if (argc >= 3) { - if (!strncasecmp(argv[2], "ext", 3)) { - alt_dp_config &= ~ALT_DP_OVERRIDE_HPD; - ext_hpd_detection_enable(1); - } else if (!strncasecmp(argv[2], "h", 1)) { - alt_dp_config |= ALT_DP_OVERRIDE_HPD; - alt_dp_config |= ALT_DP_HPD_LVL; - /* - * Modify the HPD to high. Need to enable the - * external HPD signal monitoring. A monitor - * may send a IRQ at any time to notify DUT. - */ - ext_hpd_detection_enable(1); - pd_send_hpd(DUT, hpd_high); - } else if (!strncasecmp(argv[2], "l", 1)) { - alt_dp_config |= ALT_DP_OVERRIDE_HPD; - alt_dp_config &= ~ALT_DP_HPD_LVL; - ext_hpd_detection_enable(0); - pd_send_hpd(DUT, hpd_low); - } else if (!strcasecmp(argv[2], "irq")) { - pd_send_hpd(DUT, hpd_irq); - } - } - CPRINTS("HPD source: %s", - (alt_dp_config & ALT_DP_OVERRIDE_HPD) ? "overridden" - : "external"); - CPRINTS("HPD level: %d", get_hpd_level()); - } else if (!strcasecmp(argv[1], "help")) { - CPRINTS("Usage: usbc_action dp [enable|disable|hpd|mf|pins|" - "plug]"); - } - - return EC_SUCCESS; -} - -static int cmd_usbc_action(int argc, char *argv[]) -{ - if (argc >= 2 && !strcasecmp(argv[1], "dp")) - return cmd_dp_action(argc - 1, &argv[1]); - - if (argc != 2 && argc != 3) - return EC_ERROR_PARAM_COUNT; - - /* TODO(b:140256624): drop *v command if we migrate to chg cmd. */ - if (!strcasecmp(argv[1], "5v")) { - do_cc(CONF_SRC(cc_config)); - user_limited_max_mv = 5000; - update_ports(); - } else if (!strcasecmp(argv[1], "12v")) { - do_cc(CONF_SRC(cc_config)); - user_limited_max_mv = 12000; - update_ports(); - } else if (!strcasecmp(argv[1], "20v")) { - do_cc(CONF_SRC(cc_config)); - user_limited_max_mv = 20000; - update_ports(); - } else if (!strcasecmp(argv[1], "dev")) { - /* Set the limit back to original */ - user_limited_max_mv = 20000; - do_cc(CONF_PDSNK(cc_config)); - } else if (!strcasecmp(argv[1], "pol0")) { - do_cc(cc_config & ~CC_POLARITY); - } else if (!strcasecmp(argv[1], "pol1")) { - do_cc(cc_config | CC_POLARITY); - } else if (!strcasecmp(argv[1], "drp")) { - /* Toggle the DRP state, compatible with Plankton. */ - do_cc(cc_config ^ CC_ENABLE_DRP); - CPRINTF("DRP = %d, host_mode = %d\n", - !!(cc_config & CC_ENABLE_DRP), - !!(cc_config & CC_ALLOW_SRC)); - } else if (!strcasecmp(argv[1], "chg")) { - int sink_v; - - if (argc != 3) - return EC_ERROR_PARAM2; - - sink_v = atoi(argv[2]); - if (!sink_v) - return EC_ERROR_PARAM2; - - user_limited_max_mv = sink_v * 1000; - do_cc(CONF_SRC(cc_config)); - update_ports(); - /* - * TODO(b:140256624): servod captures 'chg SRC' keyword to - * recognize if this command is supported in the firmware. - * Drop this message if when we phase out the usbc_role control. - */ - ccprintf("CHG SRC %dmV\n", user_limited_max_mv); - } else if (!strcasecmp(argv[1], "drswap")) { - if (argc == 2) { - CPRINTF("allow_dr_swap = %d\n", allow_dr_swap); - return EC_SUCCESS; - } - - if (argc != 3) - return EC_ERROR_PARAM2; - - allow_dr_swap = !!atoi(argv[2]); - - } else if (!strcasecmp(argv[1], "prswap")) { - if (argc == 2) { - CPRINTF("allow_pr_swap = %d\n", allow_pr_swap); - return EC_SUCCESS; - } - - if (argc != 3) - return EC_ERROR_PARAM2; - - allow_pr_swap = !!atoi(argv[2]); - } else { - return EC_ERROR_PARAM1; - } - - return EC_SUCCESS; -} -DECLARE_CONSOLE_COMMAND(usbc_action, cmd_usbc_action, - "5v|12v|20v|dev|pol0|pol1|drp|dp|chg x(x=voltage)|" - "drswap [1|0]|prswap [1|0]", - "Set Servo v4 type-C port state"); diff --git a/board/servo_v4/vif_override.xml b/board/servo_v4/vif_override.xml deleted file mode 100644 index 32736caf64..0000000000 --- a/board/servo_v4/vif_override.xml +++ /dev/null @@ -1,3 +0,0 @@ -<!-- Add VIF field overrides here. See genvif.c and the Vendor Info File - Definition from the USB-IF. ---> |