diff options
Diffstat (limited to 'board/servo_v4p1')
25 files changed, 0 insertions, 5249 deletions
diff --git a/board/servo_v4p1/board.c b/board/servo_v4p1/board.c deleted file mode 100644 index d8616ce340..0000000000 --- a/board/servo_v4p1/board.c +++ /dev/null @@ -1,538 +0,0 @@ -/* Copyright 2020 The Chromium OS Authors. All rights reserved. - * Use of this source code is governed by a BSD-style license that can be - * found in the LICENSE file. - */ -/* Servo V4p1 configuration */ - -#include "adc.h" -#include "ccd_measure_sbu.h" -#include "chg_control.h" -#include "common.h" -#include "console.h" -#include "dacs.h" -#include <driver/gl3590.h> -#include "driver/ioexpander/tca64xxa.h" -#include "ec_version.h" -#include "fusb302b.h" -#include "gpio.h" -#include "hooks.h" -#include "i2c.h" -#include "ina231s.h" -#include "ioexpanders.h" -#include "pathsel.h" -#include "pi3usb9201.h" -#include "queue_policies.h" -#include "registers.h" -#include "spi.h" -#include "system.h" -#include "task.h" -#include "timer.h" -#include "tusb1064.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_mux.h" -#include "usb_pd.h" -#include "usb_spi.h" -#include "usb-stream.h" -#include "util.h" - -#ifdef SECTION_IS_RO -#define CROS_EC_SECTION "RO" -#else -#define CROS_EC_SECTION "RW" -#endif - -/****************************************************************************** - * GPIO interrupt handlers. - */ -#ifdef SECTION_IS_RO -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 void tca_evt(enum gpio_signal signal) -{ - irq_ioexpanders(); -} - -const struct usb_mux usb_muxes[CONFIG_USB_PD_PORT_MAX_COUNT] = { - [CHG] = { /* CHG port connected directly to USB 3.0 hub, no mux */ }, - [DUT] = { /* DUT port with UFP mux */ - .usb_port = DUT, - .i2c_port = I2C_PORT_MASTER, - .i2c_addr_flags = TUSB1064_I2C_ADDR10_FLAGS, - .driver = &tusb1064_usb_mux_driver, - } -}; - -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); - ccprintf("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); - ccprintf("HPD: %d", level); - } -} -DECLARE_DEFERRED(hpd_lvl_deferred); - -static void dp_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; -} - -static void tcpc_evt(enum gpio_signal signal) -{ - update_status_fusb302b(); -} - -#define HOST_HUB 0 -struct uhub_i2c_iface_t uhub_config[] = { - {I2C_PORT_MASTER, GL3590_I2C_ADDR0}, -}; - -static void host_hub_evt(void) -{ - gl3590_irq_handler(HOST_HUB); -} -DECLARE_DEFERRED(host_hub_evt); - -static void hub_evt(enum gpio_signal signal) -{ - hook_call_deferred(&host_hub_evt_data, 0); -} - -static void dut_pwr_evt(enum gpio_signal signal) -{ - ccprintf("dut_pwr_evt\n"); -} - -/* Enable uservo USB. */ -static void init_uservo_port(void) -{ - /* Enable USERVO_POWER_EN */ - ec_uservo_power_en(1); - - gl3590_enable_ports(0, GL3590_DFP4, 1); - - /* Connect uservo to host hub */ - uservo_fastboot_mux_sel(0); -} - -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); - } -} -#endif /* SECTION_IS_RO */ - -#include "gpio_list.h" - -#define CPRINTS(format, args...) cprints(CC_SYSTEM, format, ## args) -#define CPRINTF(format, args...) cprintf(CC_SYSTEM, format, ## args) - -/****************************************************************************** - * 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_USART_IFACE(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, - usart4) - - -/* - * 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 V4p1"), - [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. - */ - -int board_get_version(void) -{ - return board_id_det(); -} - -#ifdef SECTION_IS_RO -/* Forward declaration */ -static void evaluate_input_power_def(void); -DECLARE_DEFERRED(evaluate_input_power_def); - -static void evaluate_input_power_def(void) -{ - int state; - static int retry = 3; - - /* Wait until host hub INTR# signal is asserted */ - state = gpio_get_level(GPIO_USBH_I2C_BUSY_INT); - if ((state == 0) && retry--) { - hook_call_deferred(&evaluate_input_power_def_data, 100 * MSEC); - return; - } - - if (retry == 0) - CPRINTF("Host hub I2C isn't online, expect issues with its " - "behaviour\n"); - - gpio_enable_interrupt(GPIO_USBH_I2C_BUSY_INT); - - gl3590_init(HOST_HUB); - - init_uservo_port(); - init_pathsel(); -} -#endif - -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(MSEC); - - init_pi3usb9201(); - - /* 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); - -#ifdef SECTION_IS_RO - init_ioexpanders(); - CPRINTS("Board ID is %d", board_id_det()); - - init_dacs(); - init_uservo_port(); - init_pathsel(); - init_ina231s(); - init_fusb302b(1); - vbus_dischrg_en(0); - - /* Bring atmel part out of reset */ - atmel_reset_l(1); - - /* - * Get data about available input power. Defer this check, since we need - * to wait for USB2/USB3 enumeration on host hub as well as I2C - * interface of this hub needs to be initialized. Genesys recommends at - * least 100ms. - */ - hook_call_deferred(&evaluate_input_power_def_data, 100 * MSEC); - - /* Enable DUT USB2.0 pair. */ - gpio_set_level(GPIO_FASTBOOT_DUTHUB_MUX_EN_L, 0); - - /* 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); - - gpio_enable_interrupt(GPIO_STM_FAULT_IRQ_L); - gpio_enable_interrupt(GPIO_DP_HPD); - gpio_enable_interrupt(GPIO_DUT_PWR_IRQ_ODL); - - /* Disable power to DUT by default */ - chg_power_select(CHG_POWER_OFF); - - /* - * 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); - - /* Start SuzyQ detection */ - start_ccd_meas_sbu_cycle(); -#else /* SECTION_IS_RO */ - CPRINTS("Board ID is %d", board_id_det()); -#endif /* SECTION_IS_RO */ -} -DECLARE_HOOK(HOOK_INIT, board_init, HOOK_PRIO_DEFAULT); - -#ifdef SECTION_IS_RO -void tick_event(void) -{ - static int i = 0; - - i++; - switch (i) { - case 1: - tca_gpio_dbg_led_k_odl(1); - break; - case 2: - break; - case 3: - tca_gpio_dbg_led_k_odl(0); - break; - case 4: - i = 0; - break; - } -} -DECLARE_HOOK(HOOK_TICK, tick_event, HOOK_PRIO_DEFAULT); - -struct ioexpander_config_t ioex_config[] = { - [0] = { - .drv = &tca64xxa_ioexpander_drv, - .i2c_host_port = TCA6416A_PORT, - .i2c_addr_flags = TCA6416A_ADDR, - .flags = TCA64XXA_FLAG_VER_TCA6416A - }, - [1] = { - .drv = &tca64xxa_ioexpander_drv, - .i2c_host_port = TCA6424A_PORT, - .i2c_addr_flags = TCA6424A_ADDR, - .flags = TCA64XXA_FLAG_VER_TCA6424A - } -}; - -#endif /* SECTION_IS_RO */ diff --git a/board/servo_v4p1/board.h b/board/servo_v4p1/board.h deleted file mode 100644 index daf450ded2..0000000000 --- a/board/servo_v4p1/board.h +++ /dev/null @@ -1,372 +0,0 @@ -/* Copyright 2020 The Chromium OS Authors. All rights reserved. - * Use of this source code is governed by a BSD-style license that can be - * found in the LICENSE file. - */ - -/* Servo V4p1 configuration */ - -#ifndef __CROS_EC_BOARD_H -#define __CROS_EC_BOARD_H - -/* Use Link-Time Optimizations to try to reduce the firmware code size */ -#define CONFIG_LTO - -/* 48 MHz SYSCLK clock frequency */ -#define CPU_CLOCK 48000000 - -/* Servo V4.1 Ports: - * CHG - port 0 - * DUT - port 1 - */ -#define CHG 0 -#define DUT 1 - -/* - * IO expanders I2C addresses and ports - */ -#define TCA6416A_PORT 1 -#define TCA6416A_ADDR 0x21 -#define TCA6424A_PORT 1 -#define TCA6424A_ADDR 0x23 - -/* - * Flash layout: we redefine the sections offsets and sizes as we want to - * include a pstate region, and will use RO/RW regions of different sizes. - * RO has size 92K and usb_updater along with the majority of code is placed - * here. - * RW has size 40K and usb_updater and other relevant code is placed here. - */ -#undef _IMAGE_SIZE -#undef CONFIG_ROLLBACK_OFF -#undef CONFIG_ROLLBACK_SIZE -#undef CONFIG_FLASH_PSTATE -#undef CONFIG_FW_PSTATE_SIZE -#undef CONFIG_FW_PSTATE_OFF -#undef CONFIG_SHAREDLIB_SIZE -#undef CONFIG_RO_MEM_OFF -#undef CONFIG_RO_STORAGE_OFF -#undef CONFIG_RO_SIZE -#undef CONFIG_RW_MEM_OFF -#undef CONFIG_RW_STORAGE_OFF -#undef CONFIG_RW_SIZE -#undef CONFIG_EC_PROTECTED_STORAGE_OFF -#undef CONFIG_EC_PROTECTED_STORAGE_SIZE -#undef CONFIG_EC_WRITABLE_STORAGE_OFF -#undef CONFIG_EC_WRITABLE_STORAGE_SIZE -#undef CONFIG_WP_STORAGE_OFF -#undef CONFIG_WP_STORAGE_SIZE - -#define CONFIG_RAM_BANK_SIZE CONFIG_RAM_SIZE - - -#define CONFIG_FLASH_PSTATE -#define CONFIG_FLASH_PSTATE_BANK - -#define CONFIG_SHAREDLIB_SIZE 0 - -#define CONFIG_RO_MEM_OFF 0 -#define CONFIG_RO_STORAGE_OFF 0 -#define CONFIG_RO_SIZE (92*1024) - -#define CONFIG_FW_PSTATE_OFF (CONFIG_RO_MEM_OFF + CONFIG_RO_SIZE) -#define CONFIG_FW_PSTATE_SIZE CONFIG_FLASH_BANK_SIZE - -#define CONFIG_RW_MEM_OFF (CONFIG_FW_PSTATE_OFF + CONFIG_FW_PSTATE_SIZE) -#define CONFIG_RW_STORAGE_OFF 0 -#define CONFIG_RW_SIZE (CONFIG_FLASH_SIZE_BYTES - \ - (CONFIG_RW_MEM_OFF - CONFIG_RO_MEM_OFF)) - -#define CONFIG_EC_PROTECTED_STORAGE_OFF CONFIG_RO_MEM_OFF -#define CONFIG_EC_PROTECTED_STORAGE_SIZE CONFIG_RO_SIZE -#define CONFIG_EC_WRITABLE_STORAGE_OFF CONFIG_RW_MEM_OFF -#define CONFIG_EC_WRITABLE_STORAGE_SIZE CONFIG_RW_SIZE - -#define CONFIG_WP_STORAGE_OFF CONFIG_EC_PROTECTED_STORAGE_OFF -#define CONFIG_WP_STORAGE_SIZE CONFIG_EC_PROTECTED_STORAGE_SIZE - -/* 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 - -/* The UART console is on USART1 (PA9/PA10) */ -#undef CONFIG_UART_CONSOLE -#define CONFIG_UART_CONSOLE 1 -#undef CONFIG_UART_TX_DMA -#undef CONFIG_UART_RX_DMA - -/* 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 0x520d -#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 - -/* Enable I/O expander */ -#ifdef SECTION_IS_RO -#define CONFIG_IO_EXPANDER -#define CONFIG_IO_EXPANDER_SUPPORT_GET_PORT -#define CONFIG_IO_EXPANDER_TCA64XXA -#define CONFIG_IO_EXPANDER_PORT_COUNT 2 -#endif - -/* 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_GETTIME -#undef CONFIG_CMD_MEM -#undef CONFIG_CMD_SHMEM -#undef CONFIG_CMD_SYSLOCK -#undef CONFIG_CMD_TIMERINFO -#undef CONFIG_CMD_WAITMS - -/* 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_USB_PD_PORT_MAX_COUNT 2 - -#ifdef SECTION_IS_RO -#define CONFIG_USB_HUB_GL3590 -#define CONFIG_INA231 -#define CONFIG_CHARGE_MANAGER -#undef CONFIG_CHARGE_MANAGER_SAFE_MODE -#define CONFIG_USB_MUX_TUSB1064 -#define CONFIG_USB_POWER_DELIVERY -#define CONFIG_USB_PD_TCPMV1 -#define CONFIG_CMD_PD -#define CONFIG_USB_PD_CUSTOM_PDO -#define CONFIG_USB_PD_DUAL_ROLE -#define CONFIG_USB_PD_DYNAMIC_SRC_CAP -#define CONFIG_USB_PD_INTERNAL_COMP -#define CONFIG_USB_PD_TCPC -#define CONFIG_USB_PD_TCPM_STUB -#undef CONFIG_USB_PD_PULLUP -/* Default pull-up should not be Rp3a0 due to Cr50 */ -#define CONFIG_USB_PD_PULLUP TYPEC_RP_USB -#define CONFIG_USB_PD_VBUS_MEASURE_NOT_PRESENT -#define CONFIG_USB_PD_ONLY_FIXED_PDOS -#define CONFIG_USB_PD_ALT_MODE -#define CONFIG_USBC_SS_MUX -#define CONFIG_USBC_SS_MUX_UFP_ONLY - -/* 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)) - -/* - * These power-supply timing values are now set towards maximum spec limit, - * to give the upstream charger the maximum time to respond. - * - * Currently tuned with the Apple 96W adapter. - */ -#define PD_POWER_SUPPLY_TURN_ON_DELAY (161*MSEC) -#define PD_POWER_SUPPLY_TURN_OFF_DELAY (461*MSEC) - -/* Define typical operating power and max power */ -#define PD_OPERATING_POWER_MW 15000 -#define PD_MAX_POWER_MW 100000 -#define PD_MAX_CURRENT_MA 5000 -#define PD_MAX_VOLTAGE_MV 20000 - -/* Add the raw option to the i2c_xfer command */ -#define CONFIG_CMD_I2C_XFER_RAW - -/* Enable command for managing host hub */ -#define CONFIG_CMD_GL3590 -#else -#undef CONFIG_CMD_I2C_XFER -#undef CONFIG_USB_POWER_DELIVERY -#endif /* SECTION_IS_RO */ - -/* - * 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 - -/* - * 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 -}; - -/* Servo V4.1 Board ID mappings */ -enum servo_board_id { - BOARD_ID_UNSET = -1, - BOARD_ID_REV0 = 0, /* Proto */ - BOARD_ID_REV1 = 1, /* EVT */ - BOARD_ID_REV2 = 2, /* DVT */ -}; - -/** - * 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_v4p1/build.mk b/board/servo_v4p1/build.mk deleted file mode 100644 index 872b4d4281..0000000000 --- a/board/servo_v4p1/build.mk +++ /dev/null @@ -1,32 +0,0 @@ -# -*- makefile -*- -# Copyright 2020 The Chromium OS Authors. All rights reserved. -# Use of this source code is governed by a BSD-style license that can be -# found in the LICENSE file. -# -# 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= - -# These files are compiled into RO and RW -board-y=board.o -board-y+=ioexpanders.o -board-y+=dacs.o -board-y+=pi3usb9201.o - -# These files are compiled into RO only -board-ro+=ccd_measure_sbu.o -board-ro+=pathsel.o -board-ro+=chg_control.o -board-ro+=ina231s.o -board-ro+=usb_pd_policy.o -board-ro+=fusb302b.o -board-ro+=usb_sm.o -board-ro+=usb_tc_snk_sm.o - -all_deps=$(patsubst ro,,$(def_all_deps)) diff --git a/board/servo_v4p1/ccd_measure_sbu.c b/board/servo_v4p1/ccd_measure_sbu.c deleted file mode 100644 index b9c9680cc9..0000000000 --- a/board/servo_v4p1/ccd_measure_sbu.c +++ /dev/null @@ -1,131 +0,0 @@ -/* Copyright 2020 The Chromium OS Authors. All rights reserved. - * Use of this source code is governed by a BSD-style license that can be - * found in the LICENSE file. - */ -/* CCD Measure SBU */ - -#include "adc.h" -#include "console.h" -#include "gpio.h" -#include "hooks.h" -#include "ioexpanders.h" -#include "timer.h" - -#define CPRINTS(format, args...) cprints(CC_SYSTEM, format, ## args) -#define CPRINTF(format, args...) cprintf(CC_SYSTEM, format, ## args) - -/* - * 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 */ - sbu_flip_sel(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 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); - } -} - -void start_ccd_meas_sbu_cycle(void) -{ - hook_call_deferred(&ccd_measure_sbu_data, 1000 * MSEC); -} diff --git a/board/servo_v4p1/ccd_measure_sbu.h b/board/servo_v4p1/ccd_measure_sbu.h deleted file mode 100644 index 0dd1ce0de7..0000000000 --- a/board/servo_v4p1/ccd_measure_sbu.h +++ /dev/null @@ -1,22 +0,0 @@ -/* Copyright 2020 The Chromium OS Authors. All rights reserved. - * Use of this source code is governed by a BSD-style license that can be - * found in the LICENSE file. - */ - -#ifndef __CROS_EC_CCD_MEASURE_SBU_H -#define __CROS_EC_CCD_MEASURE_SBU_H - -/** - * Enables or disables CCD for use with SuzyQ cable - * - * @param en 0 - Disable CCD - * 1 - Enable CCD - */ -void ccd_enable(int enable); - -/** - * Triggers the detection of a SuzyQ cable every 100mS - */ -void start_ccd_meas_sbu_cycle(void); - -#endif /* __CROS_EC_CCD_MEASURE_SBU_H */ diff --git a/board/servo_v4p1/chg_control.c b/board/servo_v4p1/chg_control.c deleted file mode 100644 index 19be03a755..0000000000 --- a/board/servo_v4p1/chg_control.c +++ /dev/null @@ -1,80 +0,0 @@ -/* Copyright 2020 The Chromium OS Authors. All rights reserved. - * Use of this source code is governed by a BSD-style license that can be - * found in the LICENSE file. - */ - -#include "chg_control.h" -#include "gpio.h" -#include "ioexpanders.h" -#include "registers.h" -#include "timer.h" -#include "usb_pd.h" - -#define CHG_P5V_POWER 0 -#define CHG_VBUS_POWER 1 - -void chg_reset(void) -{ - /* Disconnect DUT Power */ - chg_power_select(CHG_POWER_OFF); - - /* Disconnect CHG CC1(Rd) and CC2(Rd) */ - chg_attach_cc_rds(0); - - /* Give time for CHG to detach, use tErrorRecovery. */ - msleep(PD_T_ERROR_RECOVERY); - - /* Connect CHG CC1(Rd) and CC2(Rd) to detect charger */ - chg_attach_cc_rds(1); -} - -void chg_power_select(enum chg_power_select_t type) -{ - switch (type) { - case CHG_POWER_OFF: - dut_chg_en(0); - vbus_dischrg_en(1); - break; - case CHG_POWER_PP5000: - vbus_dischrg_en(0); - host_or_chg_ctl(CHG_P5V_POWER); - dut_chg_en(1); - break; - case CHG_POWER_VBUS: - vbus_dischrg_en(0); - host_or_chg_ctl(CHG_VBUS_POWER); - dut_chg_en(1); - break; - } -} - -void chg_attach_cc_rds(bool en) -{ - if (en) { - /* - * Configure USB_CHG_CC1_MCU and USB_CHG_CC2_MCU as - * ANALOG input - */ - STM32_GPIO_MODER(GPIO_A) = (STM32_GPIO_MODER(GPIO_A) - | (3 << (2*2)) | /* PA2 in ANALOG mode */ - (3 << (2*4))); /* PA4 in ANALOG mode */ - } else { - /* - * Configure USB_CHG_CC1_MCU and USB_CHG_CC2_MCU as GPIO and - * drive high to trigger disconnect. - * NOTE: The CC line has an external fixed Rd pull-down. - * Driving the CC line High overrides the pull down and this - * triggers a disconnection. - */ - /* Set level high */ - gpio_set_level(GPIO_USB_CHG_CC1_MCU, 1); - gpio_set_level(GPIO_USB_CHG_CC2_MCU, 1); - - /* Disable Analog mode and Enable GPO */ - STM32_GPIO_MODER(GPIO_A) = (STM32_GPIO_MODER(GPIO_A) - & ~(3 << (2*2) | /* PA2 disable ADC */ - 3 << (2*4))) /* PA4 disable ADC */ - | (1 << (2*2) | /* Set as GPO */ - 1 << (2*4)); /* Set as GPO */ - } -} diff --git a/board/servo_v4p1/chg_control.h b/board/servo_v4p1/chg_control.h deleted file mode 100644 index 8b81708ccc..0000000000 --- a/board/servo_v4p1/chg_control.h +++ /dev/null @@ -1,42 +0,0 @@ -/* Copyright 2020 The Chromium OS Authors. All rights reserved. - * Use of this source code is governed by a BSD-style license that can be - * found in the LICENSE file. - */ - -#ifndef __CROS_EC_CHG_CONTROL_H -#define __CROS_EC_CHG_CONTROL_H - -#include <stdbool.h> - -enum chg_cc_t { - CHG_OPEN, - CHG_CC1, - CHG_CC2 -}; - -enum chg_power_select_t { - CHG_POWER_OFF, - CHG_POWER_PP5000, - CHG_POWER_VBUS, -}; - -/* - * Triggers a disconnect and reconnect on the DUT Charger port - */ -void chg_reset(void); - -/* - * Disables or selects the DUT Charger Power source - * - * @param type Power source used for DUT - */ -void chg_power_select(enum chg_power_select_t type); - -/* - * Attaches or Removes the DUT Charger Ports CC1 and CC2 Rd resistors - * - * @param en True the CC RDs are attached else they are removed - */ -void chg_attach_cc_rds(bool en); - -#endif /* __CROS_EC_CHG_CONTROL_H */ diff --git a/board/servo_v4p1/dacs.c b/board/servo_v4p1/dacs.c deleted file mode 100644 index 087a334873..0000000000 --- a/board/servo_v4p1/dacs.c +++ /dev/null @@ -1,140 +0,0 @@ -/* Copyright 2020 The Chromium OS Authors. All rights reserved. - * Use of this source code is governed by a BSD-style license that can be - * found in the LICENSE file. - */ - -#include "dacs.h" -#include "i2c.h" -#include "ioexpanders.h" -#include "util.h" - -#define MAX_MV 5000 - -#define CC1_DAC_ADDR 0x48 -#define CC2_DAC_ADDR 0x49 - -#define REG_NOOP 0 -#define REG_DEVID 1 -#define REG_SYNC 2 -#define REG_CONFIG 3 -#define REG_GAIN 4 -#define REG_TRIGGER 5 -#define REG_STATUS 7 -#define REG_DAC 8 - -#define DAC1 BIT(0) -#define DAC2 BIT(1) - -static uint8_t dac_enabled; - -void init_dacs(void) -{ - /* Disable both DACS by default */ - enable_dac(CC1_DAC, 0); - enable_dac(CC2_DAC, 0); - dac_enabled = 0; -} - -void enable_dac(enum dac_t dac, uint8_t en) -{ - switch (dac) { - case CC1_DAC: - if (en) { - fault_clear_cc(1); - fault_clear_cc(0); - en_vout_buf_cc1(1); - /* Power ON DAC */ - i2c_write8(1, CC1_DAC_ADDR, REG_CONFIG, 0); - dac_enabled |= DAC1; - } else { - en_vout_buf_cc1(0); - /* Power OFF DAC */ - i2c_write8(1, CC1_DAC_ADDR, REG_CONFIG, 1); - dac_enabled &= ~DAC1; - } - break; - case CC2_DAC: - if (en) { - fault_clear_cc(1); - fault_clear_cc(0); - en_vout_buf_cc2(1); - i2c_write8(1, CC2_DAC_ADDR, REG_CONFIG, 0); - dac_enabled |= DAC2; - } else { - en_vout_buf_cc2(0); - /* Power down DAC */ - i2c_write8(1, CC2_DAC_ADDR, REG_CONFIG, 1); - dac_enabled &= ~DAC2; - } - break; - } -} - -int write_dac(enum dac_t dac, uint16_t value) -{ - uint16_t tmp; - - /* - * Data are MSB aligned in straight binary format, and - * use the following format: DATA[13:0], 0, 0 - */ - tmp = (value << 8) & 0xff00; - tmp |= (value >> 8) & 0xff; - tmp <<= 2; - - switch (dac) { - case CC1_DAC: - if (!(dac_enabled & DAC1)) { - ccprintf("CC1_DAC is disabled\n"); - return EC_ERROR_ACCESS_DENIED; - } - i2c_write16(1, CC1_DAC_ADDR, REG_DAC, tmp); - break; - case CC2_DAC: - if (!(dac_enabled & DAC2)) { - ccprintf("CC2_DAC is disabled\n"); - return EC_ERROR_ACCESS_DENIED; - } - i2c_write16(1, CC2_DAC_ADDR, REG_DAC, tmp); - break; - } - return EC_SUCCESS; -} - -#ifdef SECTION_IS_RO -static int cmd_cc_dac(int argc, char *argv[]) -{ - uint8_t dac; - uint64_t mv; - uint64_t round_up; - char *e; - - if (argc < 3) - return EC_ERROR_PARAM_COUNT; - - dac = strtoi(argv[1], &e, 10); - if (*e || (dac != CC1_DAC && dac != CC2_DAC)) - return EC_ERROR_PARAM2; - - if (!strcasecmp(argv[2], "on")) { - enable_dac(dac, 1); - } else if (!strcasecmp(argv[2], "off")) { - enable_dac(dac, 0); - } else { - /* get value in mV */ - mv = strtoi(argv[2], &e, 10); - /* 5000 mV max */ - if (*e || mv > MAX_MV) - return EC_ERROR_PARAM3; - /* 305176 = (5V / 2^14) * 1000000 */ - /* 152588 = 305176 / 2 : used for round up after division */ - round_up = (((mv * 1000000) + 152588) / 305176); - if (!write_dac(dac, (uint16_t)round_up)) - ccprintf("Setting DAC to %lld counts\n", round_up); - } - return EC_SUCCESS; -} -DECLARE_CONSOLE_COMMAND(cc_dac, cmd_cc_dac, - "dac <\"on\"|\"off\"|mv>", - "Set Servo v4.1 CC dacs"); -#endif diff --git a/board/servo_v4p1/dacs.h b/board/servo_v4p1/dacs.h deleted file mode 100644 index bd0ecd67da..0000000000 --- a/board/servo_v4p1/dacs.h +++ /dev/null @@ -1,37 +0,0 @@ -/* Copyright 2020 The Chromium OS Authors. All rights reserved. - * Use of this source code is governed by a BSD-style license that can be - * found in the LICENSE file. - */ -#ifndef __CROS_EC_DACS_H -#define __CROS_EC_DACS_H - -#include <stdint.h> - -enum dac_t { - CC1_DAC = 1, - CC2_DAC, -}; - -/* - * Initialize the DACs - */ -void init_dacs(void); - -/* - * Enable/Disable one of the DACs - * - * @param dac DAC to enable or disable - * @param en 0 to disable or 1 to enable - */ -void enable_dac(enum dac_t dac, uint8_t en); - -/* - * Write a value to the DAC - * - * @param dac DAC to write to - * @param value to write to the DAC in mV. (0 to 5000mV) - * @return EC_SUCCESS or EC_ERROR_ACCESS_DENIED on failure - */ -int write_dac(enum dac_t dac, uint16_t value); - -#endif /* __CROS_EC_DACS_H */ diff --git a/board/servo_v4p1/ec.tasklist b/board/servo_v4p1/ec.tasklist deleted file mode 100644 index 07250f018e..0000000000 --- a/board/servo_v4p1/ec.tasklist +++ /dev/null @@ -1,14 +0,0 @@ -/* Copyright 2020 The Chromium OS Authors. All rights reserved. - * Use of this source code is governed by a BSD-style license that can be - * found in the LICENSE file. - */ - -/** - * 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_RO(PD_C0, pd_task, NULL, ULTRA_TASK_STACK_SIZE) \ - TASK_ALWAYS_RO(PD_C1, pd_task, NULL, ULTRA_TASK_STACK_SIZE) \ - TASK_ALWAYS_RO(PD_C2, snk_task, NULL, VENTI_TASK_STACK_SIZE) diff --git a/board/servo_v4p1/fusb302b.c b/board/servo_v4p1/fusb302b.c deleted file mode 100644 index 4e144dec05..0000000000 --- a/board/servo_v4p1/fusb302b.c +++ /dev/null @@ -1,219 +0,0 @@ -/* Copyright 2020 The Chromium OS Authors. All rights reserved. - * Use of this source code is governed by a BSD-style license that can be - * found in the LICENSE file. - */ - -#include "i2c.h" -#include "fusb302b.h" -#include "gpio.h" -#include "hooks.h" -#include "ioexpanders.h" -#include "util.h" -#include "task.h" -#include "time.h" -#include "usb_pd.h" - -static int port; -static int status0; -static int status1; -static int interrupt; -static struct mutex measure_lock; - -static int tcpc_write(int reg, int val) -{ - return i2c_write8(port, FUSB302_I2C_ADDR_FLAGS, reg, val); -} - -static int tcpc_read(int reg, int *val) -{ - return i2c_read8(port, FUSB302_I2C_ADDR_FLAGS, reg, val); -} - -int init_fusb302b(int p) -{ - int ret; - int reg; - int interrupta; - int interruptb; - - /* Configure fusb302b for SNK only operation */ - port = p; - - ret = tcpc_write(TCPC_REG_RESET, TCPC_REG_RESET_SW_RESET); - if (ret) - return ret; - - /* Create interrupt masks */ - reg = 0xFF; - /* CC level changes */ - reg &= ~TCPC_REG_MASK_BC_LVL; - /* misc alert */ - reg &= ~TCPC_REG_MASK_ALERT; - /* VBUS threshold crossed (~4.0V) */ - reg &= ~TCPC_REG_MASK_VBUSOK; - tcpc_write(TCPC_REG_MASK, reg); - - /* Interrupt Enable */ - ret = tcpc_read(TCPC_REG_CONTROL0, ®); - if (ret) - return ret; - - reg &= ~TCPC_REG_CONTROL0_INT_MASK; - ret = tcpc_write(TCPC_REG_CONTROL0, reg); - if (ret) - return ret; - - ret = tcpc_write(TCPC_REG_POWER, TCPC_REG_POWER_PWR_ALL); - if (ret) - return ret; - - /* reading interrupt registers clears them */ - ret = tcpc_read(TCPC_REG_INTERRUPT, &interrupt); - if (ret) - return ret; - - - ret = tcpc_read(TCPC_REG_INTERRUPTA, &interrupta); - if (ret) - return ret; - - ret = tcpc_read(TCPC_REG_INTERRUPTB, &interruptb); - if (ret) - return ret; - - /* Call this, will detect a charger that's already plugged in */ - update_status_fusb302b(); - - /* Enable interrupt */ - gpio_enable_interrupt(GPIO_CHGSRV_TCPC_INT_ODL); - - return EC_SUCCESS; -} - -void fusb302b_irq(void) -{ - tcpc_read(TCPC_REG_INTERRUPT, &interrupt); - tcpc_read(TCPC_REG_STATUS0, &status0); - tcpc_read(TCPC_REG_STATUS1, &status1); - - task_wake(TASK_ID_PD_C2); -} -DECLARE_DEFERRED(fusb302b_irq); - -int update_status_fusb302b(void) -{ - hook_call_deferred(&fusb302b_irq_data, 0); - return EC_SUCCESS; -} - -int is_vbus_present(void) -{ - return (status0 & 0x80); -} - -/* Convert BC LVL values (in FUSB302) to Type-C CC Voltage Status */ -static int convert_bc_lvl(int bc_lvl) -{ - int ret; - - switch (bc_lvl) { - case 1: - ret = TYPEC_CC_VOLT_RP_DEF; - break; - case 2: - ret = TYPEC_CC_VOLT_RP_1_5; - break; - case 3: - ret = TYPEC_CC_VOLT_RP_3_0; - break; - default: - ret = TYPEC_CC_VOLT_OPEN; - } - - return ret; -} - -int get_cc(int *cc1, int *cc2) -{ - int reg; - int orig_meas_cc1; - int orig_meas_cc2; - int bc_lvl_cc1; - int bc_lvl_cc2; - - mutex_lock(&measure_lock); - - /* - * Measure CC1 first. - */ - tcpc_read(TCPC_REG_SWITCHES0, ®); - - /* save original state to be returned to later... */ - if (reg & TCPC_REG_SWITCHES0_MEAS_CC1) - orig_meas_cc1 = 1; - else - orig_meas_cc1 = 0; - - if (reg & TCPC_REG_SWITCHES0_MEAS_CC2) - orig_meas_cc2 = 1; - else - orig_meas_cc2 = 0; - - - /* Disable CC2 measurement switch, enable CC1 measurement switch */ - reg &= ~TCPC_REG_SWITCHES0_MEAS_CC2; - reg |= TCPC_REG_SWITCHES0_MEAS_CC1; - - tcpc_write(TCPC_REG_SWITCHES0, reg); - - /* CC1 is now being measured by FUSB302. */ - - /* Wait on measurement */ - usleep(250); - - tcpc_read(TCPC_REG_STATUS0, &bc_lvl_cc1); - - /* mask away unwanted bits */ - bc_lvl_cc1 &= (TCPC_REG_STATUS0_BC_LVL0 | TCPC_REG_STATUS0_BC_LVL1); - - /* - * Measure CC2 next. - */ - - tcpc_read(TCPC_REG_SWITCHES0, ®); - - /* Disable CC1 measurement switch, enable CC2 measurement switch */ - reg &= ~TCPC_REG_SWITCHES0_MEAS_CC1; - reg |= TCPC_REG_SWITCHES0_MEAS_CC2; - - tcpc_write(TCPC_REG_SWITCHES0, reg); - - /* CC2 is now being measured by FUSB302. */ - - /* Wait on measurement */ - usleep(250); - - tcpc_read(TCPC_REG_STATUS0, &bc_lvl_cc2); - - /* mask away unwanted bits */ - bc_lvl_cc2 &= (TCPC_REG_STATUS0_BC_LVL0 | TCPC_REG_STATUS0_BC_LVL1); - - *cc1 = convert_bc_lvl(bc_lvl_cc1); - *cc2 = convert_bc_lvl(bc_lvl_cc2); - - /* return MEAS_CC1/2 switches to original state */ - tcpc_read(TCPC_REG_SWITCHES0, ®); - if (orig_meas_cc1) - reg |= TCPC_REG_SWITCHES0_MEAS_CC1; - else - reg &= ~TCPC_REG_SWITCHES0_MEAS_CC1; - if (orig_meas_cc2) - reg |= TCPC_REG_SWITCHES0_MEAS_CC2; - else - reg &= ~TCPC_REG_SWITCHES0_MEAS_CC2; - - tcpc_write(TCPC_REG_SWITCHES0, reg); - - mutex_unlock(&measure_lock); - return 0; -} diff --git a/board/servo_v4p1/fusb302b.h b/board/servo_v4p1/fusb302b.h deleted file mode 100644 index ec89c0c207..0000000000 --- a/board/servo_v4p1/fusb302b.h +++ /dev/null @@ -1,236 +0,0 @@ -/* Copyright 2020 The Chromium OS Authors. All rights reserved. - * Use of this source code is governed by a BSD-style license that can be - * found in the LICENSE file. - */ - -/* USB Power delivery port management */ -/* For Fairchild FUSB302 */ -#ifndef __CROS_EC_DRIVER_TCPM_FUSB302_H -#define __CROS_EC_DRIVER_TCPM_FUSB302_H - -/* Chip Device ID - 302A or 302B */ -#define FUSB302_DEVID_302A 0x08 -#define FUSB302_DEVID_302B 0x09 - -/* I2C address varies by part number */ -/* FUSB302BUCX / FUSB302BMPX */ -#define FUSB302_I2C_ADDR_FLAGS 0x22 -/* FUSB302B01MPX */ -#define FUSB302_I2C_ADDR_B01_FLAGS 0x23 -/* FUSB302B10MPX */ -#define FUSB302_I2C_ADDR_B10_FLAGS 0x24 -/* FUSB302B11MPX */ -#define FUSB302_I2C_ADDR_B11_FLAGS 0x25 - -#define TCPC_REG_DEVICE_ID 0x01 - -#define TCPC_REG_SWITCHES0 0x02 -#define TCPC_REG_SWITCHES0_CC2_PU_EN (1<<7) -#define TCPC_REG_SWITCHES0_CC1_PU_EN (1<<6) -#define TCPC_REG_SWITCHES0_VCONN_CC2 (1<<5) -#define TCPC_REG_SWITCHES0_VCONN_CC1 (1<<4) -#define TCPC_REG_SWITCHES0_MEAS_CC2 (1<<3) -#define TCPC_REG_SWITCHES0_MEAS_CC1 (1<<2) -#define TCPC_REG_SWITCHES0_CC2_PD_EN (1<<1) -#define TCPC_REG_SWITCHES0_CC1_PD_EN (1<<0) - -#define TCPC_REG_SWITCHES1 0x03 -#define TCPC_REG_SWITCHES1_POWERROLE (1<<7) -#define TCPC_REG_SWITCHES1_SPECREV1 (1<<6) -#define TCPC_REG_SWITCHES1_SPECREV0 (1<<5) -#define TCPC_REG_SWITCHES1_DATAROLE (1<<4) -#define TCPC_REG_SWITCHES1_AUTO_GCRC (1<<2) -#define TCPC_REG_SWITCHES1_TXCC2_EN (1<<1) -#define TCPC_REG_SWITCHES1_TXCC1_EN (1<<0) - -#define TCPC_REG_MEASURE 0x04 -#define TCPC_REG_MEASURE_MDAC_MASK 0x3F -#define TCPC_REG_MEASURE_VBUS (1<<6) -/* - * MDAC reference voltage step size is 42 mV. Round our thresholds to reduce - * maximum error, which also matches suggested thresholds in datasheet - * (Table 3. Host Interrupt Summary). - */ -#define TCPC_REG_MEASURE_MDAC_MV(mv) (DIV_ROUND_NEAREST((mv), 42) & 0x3f) - -#define TCPC_REG_CONTROL0 0x06 -#define TCPC_REG_CONTROL0_TX_FLUSH (1<<6) -#define TCPC_REG_CONTROL0_INT_MASK (1<<5) -#define TCPC_REG_CONTROL0_HOST_CUR_MASK (3<<2) -#define TCPC_REG_CONTROL0_HOST_CUR_3A0 (3<<2) -#define TCPC_REG_CONTROL0_HOST_CUR_1A5 (2<<2) -#define TCPC_REG_CONTROL0_HOST_CUR_USB (1<<2) -#define TCPC_REG_CONTROL0_TX_START (1<<0) - -#define TCPC_REG_CONTROL1 0x07 -#define TCPC_REG_CONTROL1_ENSOP2DB (1<<6) -#define TCPC_REG_CONTROL1_ENSOP1DB (1<<5) -#define TCPC_REG_CONTROL1_BIST_MODE2 (1<<4) -#define TCPC_REG_CONTROL1_RX_FLUSH (1<<2) -#define TCPC_REG_CONTROL1_ENSOP2 (1<<1) -#define TCPC_REG_CONTROL1_ENSOP1 (1<<0) - -#define TCPC_REG_CONTROL2 0x08 -/* two-bit field, valid values below */ -#define TCPC_REG_CONTROL2_MODE_MASK (0x3<<TCPC_REG_CONTROL2_MODE_POS) -#define TCPC_REG_CONTROL2_MODE_DFP (0x3) -#define TCPC_REG_CONTROL2_MODE_UFP (0x2) -#define TCPC_REG_CONTROL2_MODE_DRP (0x1) -#define TCPC_REG_CONTROL2_MODE_POS (1) -#define TCPC_REG_CONTROL2_TOGGLE (1<<0) - -#define TCPC_REG_CONTROL3 0x09 -#define TCPC_REG_CONTROL3_SEND_HARDRESET (1<<6) -#define TCPC_REG_CONTROL3_BIST_TMODE (1<<5) /* 302B Only */ -#define TCPC_REG_CONTROL3_AUTO_HARDRESET (1<<4) -#define TCPC_REG_CONTROL3_AUTO_SOFTRESET (1<<3) -/* two-bit field */ -#define TCPC_REG_CONTROL3_N_RETRIES (1<<1) -#define TCPC_REG_CONTROL3_N_RETRIES_POS (1) -#define TCPC_REG_CONTROL3_N_RETRIES_SIZE (2) -#define TCPC_REG_CONTROL3_AUTO_RETRY (1<<0) - -#define TCPC_REG_MASK 0x0A -#define TCPC_REG_MASK_VBUSOK (1<<7) -#define TCPC_REG_MASK_ACTIVITY (1<<6) -#define TCPC_REG_MASK_COMP_CHNG (1<<5) -#define TCPC_REG_MASK_CRC_CHK (1<<4) -#define TCPC_REG_MASK_ALERT (1<<3) -#define TCPC_REG_MASK_WAKE (1<<2) -#define TCPC_REG_MASK_COLLISION (1<<1) -#define TCPC_REG_MASK_BC_LVL (1<<0) - -#define TCPC_REG_POWER 0x0B -#define TCPC_REG_POWER_PWR (1<<0) /* four-bit field */ -#define TCPC_REG_POWER_PWR_LOW 0x1 /* Bandgap + Wake circuitry */ -#define TCPC_REG_POWER_PWR_MEDIUM 0x3 /* LOW + Receiver + Current refs */ -#define TCPC_REG_POWER_PWR_HIGH 0x7 /* MEDIUM + Measure block */ -#define TCPC_REG_POWER_PWR_ALL 0xF /* HIGH + Internal Oscillator */ - -#define TCPC_REG_RESET 0x0C -#define TCPC_REG_RESET_PD_RESET (1<<1) -#define TCPC_REG_RESET_SW_RESET (1<<0) - -#define TCPC_REG_MASKA 0x0E -#define TCPC_REG_MASKA_OCP_TEMP (1<<7) -#define TCPC_REG_MASKA_TOGDONE (1<<6) -#define TCPC_REG_MASKA_SOFTFAIL (1<<5) -#define TCPC_REG_MASKA_RETRYFAIL (1<<4) -#define TCPC_REG_MASKA_HARDSENT (1<<3) -#define TCPC_REG_MASKA_TX_SUCCESS (1<<2) -#define TCPC_REG_MASKA_SOFTRESET (1<<1) -#define TCPC_REG_MASKA_HARDRESET (1<<0) - -#define TCPC_REG_MASKB 0x0F -#define TCPC_REG_MASKB_GCRCSENT (1<<0) - -#define TCPC_REG_STATUS0A 0x3C -#define TCPC_REG_STATUS0A_SOFTFAIL (1<<5) -#define TCPC_REG_STATUS0A_RETRYFAIL (1<<4) -#define TCPC_REG_STATUS0A_POWER (1<<2) /* two-bit field */ -#define TCPC_REG_STATUS0A_RX_SOFT_RESET (1<<1) -#define TCPC_REG_STATUS0A_RX_HARD_RESEt (1<<0) - -#define TCPC_REG_STATUS1A 0x3D -/* three-bit field, valid values below */ -#define TCPC_REG_STATUS1A_TOGSS (1<<3) -#define TCPC_REG_STATUS1A_TOGSS_RUNNING 0x0 -#define TCPC_REG_STATUS1A_TOGSS_SRC1 0x1 -#define TCPC_REG_STATUS1A_TOGSS_SRC2 0x2 -#define TCPC_REG_STATUS1A_TOGSS_SNK1 0x5 -#define TCPC_REG_STATUS1A_TOGSS_SNK2 0x6 -#define TCPC_REG_STATUS1A_TOGSS_AA 0x7 -#define TCPC_REG_STATUS1A_TOGSS_POS (3) -#define TCPC_REG_STATUS1A_TOGSS_MASK (0x7) - -#define TCPC_REG_STATUS1A_RXSOP2DB (1<<2) -#define TCPC_REG_STATUS1A_RXSOP1DB (1<<1) -#define TCPC_REG_STATUS1A_RXSOP (1<<0) - -#define TCPC_REG_INTERRUPTA 0x3E -#define TCPC_REG_INTERRUPTA_OCP_TEMP (1<<7) -#define TCPC_REG_INTERRUPTA_TOGDONE (1<<6) -#define TCPC_REG_INTERRUPTA_SOFTFAIL (1<<5) -#define TCPC_REG_INTERRUPTA_RETRYFAIL (1<<4) -#define TCPC_REG_INTERRUPTA_HARDSENT (1<<3) -#define TCPC_REG_INTERRUPTA_TX_SUCCESS (1<<2) -#define TCPC_REG_INTERRUPTA_SOFTRESET (1<<1) -#define TCPC_REG_INTERRUPTA_HARDRESET (1<<0) - -#define TCPC_REG_INTERRUPTB 0x3F -#define TCPC_REG_INTERRUPTB_GCRCSENT (1<<0) - -#define TCPC_REG_STATUS0 0x40 -#define TCPC_REG_STATUS0_VBUSOK (1<<7) -#define TCPC_REG_STATUS0_ACTIVITY (1<<6) -#define TCPC_REG_STATUS0_COMP (1<<5) -#define TCPC_REG_STATUS0_CRC_CHK (1<<4) -#define TCPC_REG_STATUS0_ALERT (1<<3) -#define TCPC_REG_STATUS0_WAKE (1<<2) -#define TCPC_REG_STATUS0_BC_LVL1 (1<<1) /* two-bit field */ -#define TCPC_REG_STATUS0_BC_LVL0 (1<<0) /* two-bit field */ - -#define TCPC_REG_STATUS1 0x41 -#define TCPC_REG_STATUS1_RXSOP2 (1<<7) -#define TCPC_REG_STATUS1_RXSOP1 (1<<6) -#define TCPC_REG_STATUS1_RX_EMPTY (1<<5) -#define TCPC_REG_STATUS1_RX_FULL (1<<4) -#define TCPC_REG_STATUS1_TX_EMPTY (1<<3) -#define TCPC_REG_STATUS1_TX_FULL (1<<2) - -#define TCPC_REG_INTERRUPT 0x42 -#define TCPC_REG_INTERRUPT_VBUSOK (1<<7) -#define TCPC_REG_INTERRUPT_ACTIVITY (1<<6) -#define TCPC_REG_INTERRUPT_COMP_CHNG (1<<5) -#define TCPC_REG_INTERRUPT_CRC_CHK (1<<4) -#define TCPC_REG_INTERRUPT_ALERT (1<<3) -#define TCPC_REG_INTERRUPT_WAKE (1<<2) -#define TCPC_REG_INTERRUPT_COLLISION (1<<1) -#define TCPC_REG_INTERRUPT_BC_LVL (1<<0) - -#define TCPC_REG_FIFOS 0x43 - -/* Tokens defined for the FUSB302 TX FIFO */ -enum fusb302_txfifo_tokens { - FUSB302_TKN_TXON = 0xA1, - FUSB302_TKN_SYNC1 = 0x12, - FUSB302_TKN_SYNC2 = 0x13, - FUSB302_TKN_SYNC3 = 0x1B, - FUSB302_TKN_RST1 = 0x15, - FUSB302_TKN_RST2 = 0x16, - FUSB302_TKN_PACKSYM = 0x80, - FUSB302_TKN_JAMCRC = 0xFF, - FUSB302_TKN_EOP = 0x14, - FUSB302_TKN_TXOFF = 0xFE, -}; - -/** - * Initializes the FUSB302 to operate - * as a SNK only. - * - * @param port The i2c bus of the FUSB302B - * - * @returns EC_SUCCESS or EC_XXX on error - */ -int init_fusb302b(int port); - -/** - * Should be called from the interrupt generated - * by the FUSB302. This function reads status - * and interrupt registers in the FUSB302. - */ -int update_status_fusb302b(void); - -/** - * Returns true if VBUS is present, else false - */ -int is_vbus_present(void); - -/* - * Reads the status of the CC lines - * - * @returns EC_SUCCESS or EC_XXX on failure - */ -int get_cc(int *cc1, int *cc2); - -#endif /* __CROS_EC_DRIVER_TCPM_FUSB302_H */ diff --git a/board/servo_v4p1/gpio.inc b/board/servo_v4p1/gpio.inc deleted file mode 100644 index 070aa90098..0000000000 --- a/board/servo_v4p1/gpio.inc +++ /dev/null @@ -1,127 +0,0 @@ -/* -*- mode:c -*- - * - * Copyright 2020 The Chromium OS Authors. All rights reserved. - * Use of this source code is governed by a BSD-style license that can be - * found in the LICENSE file. - */ - -#ifdef SECTION_IS_RO -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(STM_FAULT_IRQ_L, PIN(A, 8), GPIO_INT_FALLING, tca_evt) -GPIO_INT(DP_HPD, PIN(A, 15), GPIO_INT_BOTH, dp_evt) -GPIO_INT(CHGSRV_TCPC_INT_ODL, PIN(C, 0), GPIO_INT_FALLING, tcpc_evt) -GPIO_INT(USBH_I2C_BUSY_INT, PIN(C, 9), GPIO_INT_FALLING, hub_evt) -GPIO_INT(DUT_PWR_IRQ_ODL, PIN(F, 1), GPIO_INT_FALLING, dut_pwr_evt) -#endif /* SECTION_IS_RO */ - -/* Outputs */ -GPIO(HOST_USB_HUB_RESET_L, PIN(D, 2), GPIO_ODR_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_ODR_HIGH) -GPIO(ATMEL_HWB_L, PIN(B, 12), GPIO_OUT_HIGH) -GPIO(USB3_A1_MUX_EN_L, PIN(F, 0), GPIO_OUT_HIGH) - -/* Inputs */ - -/* Type-C */ -/* PD RX/TX */ -GPIO(USB_C_REF, PIN(A, 1), GPIO_ANALOG) -GPIO(USB_CHG_CC1_MCU, PIN(A, 2), GPIO_ANALOG) -GPIO(USB_CHG_CC2_MCU, PIN(A, 4), GPIO_ANALOG) -GPIO(USB_DUT_CC1_MCU, PIN(A, 0), GPIO_ANALOG) -GPIO(USB_DUT_CC2_MCU, 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_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_CC1_RP3A0, PIN(C, 14), GPIO_INPUT) -GPIO(USB_DUT_CC1_RP1A5, PIN(C, 15), 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) -GPIO(USB_DUT_CC2_RP1A5, PIN(C, 1), GPIO_INPUT) -GPIO(USB_DUT_CC2_RP3A0, PIN(C, 8), 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) - -/* IOEX */ -#ifdef SECTION_IS_RO - -IOEX(SBU_UART_SEL, EXPIN(0, 0, 0), GPIO_OUT_LOW) -IOEX(ATMEL_RESET_L, EXPIN(0, 0, 1), GPIO_OUT_LOW) -IOEX(SBU_FLIP_SEL, EXPIN(0, 0, 2), GPIO_OUT_HIGH) -IOEX(USB3_A0_MUX_SEL, EXPIN(0, 0, 3), GPIO_OUT_HIGH) -IOEX(USB3_A0_MUX_EN_L, EXPIN(0, 0, 4), GPIO_OUT_LOW) -IOEX(USB3_A0_PWR_EN, EXPIN(0, 0, 5), GPIO_OUT_LOW) -IOEX(UART_18_SEL, EXPIN(0, 0, 6), GPIO_OUT_LOW) -IOEX(USERVO_POWER_EN, EXPIN(0, 0, 7), GPIO_OUT_LOW) -IOEX(USERVO_FASTBOOT_MUX_SEL, EXPIN(0, 1, 0), GPIO_OUT_LOW) -IOEX(USB3_A1_PWR_EN, EXPIN(0, 1, 1), GPIO_OUT_LOW) -IOEX(USB3_A1_MUX_SEL, EXPIN(0, 1, 2), GPIO_OUT_HIGH) -IOEX(BOARD_ID_DET0, EXPIN(0, 1, 3), GPIO_INPUT) -IOEX(BOARD_ID_DET1, EXPIN(0, 1, 4), GPIO_INPUT) -IOEX(BOARD_ID_DET2, EXPIN(0, 1, 5), GPIO_INPUT) -IOEX(VBUS_DISCHRG_EN, EXPIN(0, 1, 6), GPIO_OUT_LOW) -IOEX(DONGLE_DET, EXPIN(0, 1, 7), GPIO_INPUT) - -IOEX(EN_PP5000_ALT_3P3, EXPIN(1, 0, 0), GPIO_OUT_LOW) -IOEX(EN_PP3300_ETH, EXPIN(1, 0, 1), GPIO_OUT_HIGH) -IOEX(EN_PP3300_DP, EXPIN(1, 0, 2), GPIO_OUT_HIGH) -IOEX(FAULT_CLEAR_CC, EXPIN(1, 0, 3), GPIO_OUT_LOW) -IOEX(EN_VOUT_BUF_CC1, EXPIN(1, 0, 4), GPIO_OUT_LOW) -IOEX(EN_VOUT_BUF_CC2, EXPIN(1, 0, 5), GPIO_OUT_LOW) -IOEX(DUT_CHG_EN, EXPIN(1, 0, 6), GPIO_OUT_LOW) -IOEX(HOST_OR_CHG_CTL, EXPIN(1, 0, 7), GPIO_OUT_LOW) -IOEX(USERVO_FAULT_L, EXPIN(1, 1, 0), GPIO_INPUT) -IOEX(USB3_A0_FAULT_L, EXPIN(1, 1, 1), GPIO_INPUT) -IOEX(USB3_A1_FAULT_L, EXPIN(1, 1, 2), GPIO_INPUT) -IOEX(USB_DUTCHG_FLT_ODL, EXPIN(1, 1, 3), GPIO_INPUT) -IOEX(PP3300_DP_FAULT_L, EXPIN(1, 1, 4), GPIO_INPUT) -IOEX(DAC_BUF1_LATCH_FAULT_L, EXPIN(1, 1, 5), GPIO_INPUT) -IOEX(DAC_BUF2_LATCH_FAULT_L, EXPIN(1, 1, 6), GPIO_INPUT) -IOEX(PP5000_SRC_SEL, EXPIN(1, 1, 7), GPIO_INPUT) -IOEX(HOST_CHRG_DET, EXPIN(1, 2, 0), GPIO_INPUT) -IOEX(USBH_PWRDN_L, EXPIN(1, 2, 1), GPIO_OUT_HIGH) -IOEX(ATMEL_SS, EXPIN(1, 2, 2), GPIO_INPUT) -IOEX(ATMEL_SCLK, EXPIN(1, 2, 3), GPIO_INPUT) -IOEX(ATMEL_MOSI, EXPIN(1, 2, 4), GPIO_INPUT) -IOEX(ATMEL_MISO, EXPIN(1, 2, 5), GPIO_INPUT) -IOEX(SYS_PWR_IRQ_ODL, EXPIN(1, 2, 6), GPIO_INPUT) -IOEX(TCA_GPIO_DBG_LED_K_ODL, EXPIN(1, 2, 7), GPIO_OUT_LOW) - -#endif - -/* Unimplemented signals since we are not an EC */ -UNIMPLEMENTED(ENTERING_RW) -UNIMPLEMENTED(WP_L) - -ALTERNATE(PIN_MASK(A, 0x0600), 1, MODULE_USART, 0) /* USART1: PA9/PA10 - Servo DBG UART1 */ -ALTERNATE(PIN_MASK(C, 0x0030), 1, MODULE_USART, 0) /* USART3: PC4/PC5 - Servo DUT UART3 */ -ALTERNATE(PIN_MASK(C, 0x0C00), 0, MODULE_USART, 0) /* USART4: PC10/PC11 - Servo UART4 */ -ALTERNATE(PIN_MASK(B, 0x0C00), 1, MODULE_I2C, GPIO_ODR_HIGH) /* I2C MASTER:PB10/11 */ -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_v4p1/ina231s.c b/board/servo_v4p1/ina231s.c deleted file mode 100644 index 3382686f3f..0000000000 --- a/board/servo_v4p1/ina231s.c +++ /dev/null @@ -1,69 +0,0 @@ -/* Copyright 2020 The Chromium OS Authors. All rights reserved. - * Use of this source code is governed by a BSD-style license that can be - * found in the LICENSE file. - */ - -#include "common.h" -#include "ina2xx.h" -#include "util.h" - -#define PP_DUT_IDX 0 -#define PP_CHG_IDX 1 -#define SR_CHG_IDX 2 - -void init_ina231s(void) -{ - /* Calibrate INA0 (PP DUT) with 1mA/LSB scale */ - ina2xx_init(PP_DUT_IDX, 0x8000, INA2XX_CALIB_1MA(5 /*mOhm*/)); - - /* Calibrate INA1 (PP CHG) with 1mA/LSB scale */ - ina2xx_init(PP_CHG_IDX, 0x8000, INA2XX_CALIB_1MA(5 /*mOhm*/)); - - /* Calibrate INA2 (SR CHG) with 1mA/LSB scale*/ - ina2xx_init(SR_CHG_IDX, 0x8000, INA2XX_CALIB_1MA(5 /*mOhm*/)); -} - -int pp_dut_voltage(void) -{ - return ina2xx_get_voltage(PP_DUT_IDX); -} - -int pp_dut_current(void) -{ - return ina2xx_get_current(PP_DUT_IDX); -} - -int pp_dut_power(void) -{ - return ina2xx_get_power(PP_DUT_IDX); -} - -int pp_chg_voltage(void) -{ - return ina2xx_get_voltage(PP_CHG_IDX); -} - -int pp_chg_current(void) -{ - return ina2xx_get_current(PP_CHG_IDX); -} - -int pp_chg_power(void) -{ - return ina2xx_get_power(PP_CHG_IDX); -} - -int sr_chg_voltage(void) -{ - return ina2xx_get_voltage(SR_CHG_IDX); -} - -int sr_chg_current(void) -{ - return ina2xx_get_current(SR_CHG_IDX); -} - -int sr_chg_power(void) -{ - return ina2xx_get_power(SR_CHG_IDX); -} diff --git a/board/servo_v4p1/ina231s.h b/board/servo_v4p1/ina231s.h deleted file mode 100644 index 9c3804e769..0000000000 --- a/board/servo_v4p1/ina231s.h +++ /dev/null @@ -1,59 +0,0 @@ -/* Copyright 2020 The Chromium OS Authors. All rights reserved. - * Use of this source code is governed by a BSD-style license that can be - * found in the LICENSE file. - */ - -#ifndef __CROS_EC_INA231S_H -#define __CROS_EC_INA231S_H - -/* - * Initialize the INA231s - */ -void init_ina231s(void); - -/* - * Return dut vbus voltage in milliVolts - */ -int pp_dut_voltage(void); - -/* - * Return current in milliAmps - */ -int pp_dut_current(void); - -/* - * Return power in milliWatts - */ -int pp_dut_power(void); - -/* - * Return bus voltage in milliVolts - */ -int pp_chg_voltage(void); - -/* - * Return current in milliAmps - */ -int pp_chg_current(void); - -/* - * Return power in milliWatts - */ -int pp_chg_power(void); - -/* - * Return bus voltage in milliVolts - */ -int sr_chg_voltage(void); - -/* - * Return current in milliAmps - */ -int sr_chg_current(void); - -/* - * Return power in milliWatts - */ -int sr_chg_power(void); - -#endif /* __CROS_EC_INA231S_H */ diff --git a/board/servo_v4p1/ioexpanders.c b/board/servo_v4p1/ioexpanders.c deleted file mode 100644 index 7482038879..0000000000 --- a/board/servo_v4p1/ioexpanders.c +++ /dev/null @@ -1,317 +0,0 @@ -/* Copyright 2020 The Chromium OS Authors. All rights reserved. - * Use of this source code is governed by a BSD-style license that can be - * found in the LICENSE file. - */ - -#include "hooks.h" -#include "i2c.h" -#include "ioexpander.h" -#include "ioexpanders.h" - -#define CPRINTF(format, args...) cprintf(CC_SYSTEM, format, ## args) -#define CPRINTS(format, args...) cprints(CC_SYSTEM, format, ## args) - -/****************************************************************************** - * Initialize IOExpanders. - */ - -static enum servo_board_id board_id_val = BOARD_ID_UNSET; - -#ifdef SECTION_IS_RO - -static int dut_chg_en_state; -static int bc12_charger; - -/* Enable all ioexpander outputs. */ -int init_ioexpanders(void) -{ - /* Clear any faults and other IRQs*/ - read_faults(); - read_irqs(); - - /* - * Cache initial value for BC1.2 indicator. This is the only pin, which - * notifies about event on both low and high levels, while notification - * should happen only when state has changed. - */ - ioex_get_level(IOEX_HOST_CHRG_DET, &bc12_charger); - - return EC_SUCCESS; -} - -static void ioexpanders_irq(void) -{ - int fault, irqs; - - fault = read_faults(); - irqs = read_irqs(); - - if (!(fault & USERVO_FAULT_L)) { - ec_uservo_power_en(0); - CPRINTF("FAULT: Microservo USB A port load switch\n"); - } - - if (!(fault & USB3_A0_FAULT_L)) { - ec_usb3_a0_pwr_en(0); - CPRINTF("FAULT: USB3 A0 port load switch\n"); - } - - if (!(fault & USB3_A1_FAULT_L)) { - ec_usb3_a1_pwr_en(0); - CPRINTF("FAULT: USB3 A1 port load switch\n"); - } - - if (!(fault & USB_DUTCHG_FLT_ODL)) { - CPRINTF("FAULT: Overcurrent on Charger or DUT CC/SBU lines\n"); - } - - if (!(fault & PP3300_DP_FAULT_L)) { - CPRINTF("FAULT: Overcurrent on DisplayPort\n"); - } - - if (!(fault & DAC_BUF1_LATCH_FAULT_L)) { - CPRINTF("FAULT: CC1 drive circuitry has exceeded thermal " - "or current limits. The CC1 DAC has been disabled " - "and disconnected.\n"); - - en_vout_buf_cc1(0); - } - - if (!(fault & DAC_BUF2_LATCH_FAULT_L)) { - CPRINTF("FAULT: CC2 drive circuitry has exceeded thermal " - "or current limits. The CC2 DAC has been disabled " - "and disconnected.\n"); - - en_vout_buf_cc2(0); - } - - /* - * In case of both DACs' faults, we should clear them only after - * disabling both DACs. - */ - if ((fault & (DAC_BUF1_LATCH_FAULT_L | DAC_BUF2_LATCH_FAULT_L)) != - (DAC_BUF1_LATCH_FAULT_L | DAC_BUF2_LATCH_FAULT_L)) { - fault_clear_cc(1); - fault_clear_cc(0); - } - - if ((!!(irqs & HOST_CHRG_DET) != bc12_charger) && - (board_id_det() <= BOARD_ID_REV1)) { - CPRINTF("BC1.2 charger %s\n", - (irqs & HOST_CHRG_DET) ? "plugged" : "unplugged"); - bc12_charger = !!(irqs & HOST_CHRG_DET); - } - - if (!(irqs & SYS_PWR_IRQ_ODL)) { - CPRINTF("System full power threshold exceeded\n"); - } -} -DECLARE_DEFERRED(ioexpanders_irq); - -int irq_ioexpanders(void) -{ - hook_call_deferred(&ioexpanders_irq_data, 0); - return 0; -} - -inline int sbu_uart_sel(int en) -{ - return ioex_set_level(IOEX_SBU_UART_SEL, en); -} - -inline int atmel_reset_l(int en) -{ - return ioex_set_level(IOEX_ATMEL_RESET_L, en); -} - -inline int sbu_flip_sel(int en) -{ - return ioex_set_level(IOEX_SBU_FLIP_SEL, en); -} - -inline int usb3_a0_mux_sel(int en) -{ - return ioex_set_level(IOEX_USB3_A0_MUX_SEL, en); -} - -inline int usb3_a0_mux_en_l(int en) -{ - return ioex_set_level(IOEX_USB3_A0_MUX_EN_L, en); -} - -inline int ec_usb3_a0_pwr_en(int en) -{ - return ioex_set_level(IOEX_USB3_A0_PWR_EN, en); -} - -inline int uart_18_sel(int en) -{ - return ioex_set_level(IOEX_UART_18_SEL, en); -} - -inline int ec_uservo_power_en(int en) -{ - return ioex_set_level(IOEX_USERVO_POWER_EN, en); -} - -inline int uservo_fastboot_mux_sel(enum uservo_fastboot_mux_sel_t sel) -{ - return ioex_set_level(IOEX_USERVO_FASTBOOT_MUX_SEL, (int)sel); -} - -inline int ec_usb3_a1_pwr_en(int en) -{ - return ioex_set_level(IOEX_USB3_A1_PWR_EN, en); -} - -inline int usb3_a1_mux_sel(int en) -{ - return ioex_set_level(IOEX_USB3_A1_MUX_SEL, en); -} - -inline int board_id_det(void) -{ - if (board_id_val == BOARD_ID_UNSET) { - int id; - - /* Cache board ID at init */ - if (ioex_get_port(IOEX_GET_INFO(IOEX_BOARD_ID_DET0)->ioex, - IOEX_GET_INFO(IOEX_BOARD_ID_DET0)->port, - &id)) - return id; - - /* Board ID consists of bits 5, 4, and 3 */ - board_id_val = (id >> BOARD_ID_DET_OFFSET) & BOARD_ID_DET_MASK; - } - - return board_id_val; -} - -inline int dongle_det(void) -{ - int val; - ioex_get_level(IOEX_DONGLE_DET, &val); - return val; -} - -inline int get_host_chrg_det(void) -{ - int val; - ioex_get_level(IOEX_HOST_CHRG_DET, &val); - return val; -} - -inline int en_pp5000_alt_3p3(int en) -{ - return ioex_set_level(IOEX_EN_PP5000_ALT_3P3, en); -} - -inline int en_pp3300_eth(int en) -{ - return ioex_set_level(IOEX_EN_PP3300_ETH, en); -} - -inline int en_pp3300_dp(int en) -{ - return ioex_set_level(IOEX_EN_PP3300_DP, en); -} - -inline int fault_clear_cc(int en) -{ - return ioex_set_level(IOEX_FAULT_CLEAR_CC, en); -} - -inline int en_vout_buf_cc1(int en) -{ - return ioex_set_level(IOEX_EN_VOUT_BUF_CC1, en); -} - -inline int en_vout_buf_cc2(int en) -{ - return ioex_set_level(IOEX_EN_VOUT_BUF_CC2, en); -} - -int dut_chg_en(int en) -{ - dut_chg_en_state = en; - return ioex_set_level(IOEX_DUT_CHG_EN, en); -} - -int get_dut_chg_en(void) -{ - return dut_chg_en_state; -} - -inline int host_or_chg_ctl(int en) -{ - return ioex_set_level(IOEX_HOST_OR_CHG_CTL, en); -} - -inline int read_faults(void) -{ - int val; - - ioex_get_port(IOEX_GET_INFO(IOEX_USERVO_FAULT_L)->ioex, - IOEX_GET_INFO(IOEX_USERVO_FAULT_L)->port, - &val); - - return val; -} - -inline int read_irqs(void) -{ - int val; - - ioex_get_port(IOEX_GET_INFO(IOEX_SYS_PWR_IRQ_ODL)->ioex, - IOEX_GET_INFO(IOEX_SYS_PWR_IRQ_ODL)->port, - &val); - - return val; -} - -inline int vbus_dischrg_en(int en) -{ - return ioex_set_level(IOEX_VBUS_DISCHRG_EN, en); -} - -inline int usbh_pwrdn_l(int en) -{ - return ioex_set_level(IOEX_USBH_PWRDN_L, en); -} - -inline int tca_gpio_dbg_led_k_odl(int en) -{ - return ioex_set_level(IOEX_TCA_GPIO_DBG_LED_K_ODL, !en); -} - -#else /* SECTION_IS_RO */ - -/* - * Due to lack of flash in RW section, it is not possible to use IOEX subsystem - * in it. Instead, RO section uses IOEX, and RW implements only required - * function with raw i2c operation. This function is required by 'version' - * console command and should work without any special initialization. - */ -inline int board_id_det(void) -{ - if (board_id_val == BOARD_ID_UNSET) { - int id; - int res; - - /* Cache board ID at init */ - res = i2c_read8(TCA6416A_PORT, - TCA6416A_ADDR, - BOARD_ID_DET_PORT, - &id); - if (res != EC_SUCCESS) - return res; - - /* Board ID consists of bits 5, 4, and 3 */ - board_id_val = (id >> BOARD_ID_DET_OFFSET) & BOARD_ID_DET_MASK; - } - - /* Board ID consists of bits 5, 4, and 3 */ - return board_id_val; -} - -#endif /* SECTION_IS_RO */ diff --git a/board/servo_v4p1/ioexpanders.h b/board/servo_v4p1/ioexpanders.h deleted file mode 100644 index 6565992857..0000000000 --- a/board/servo_v4p1/ioexpanders.h +++ /dev/null @@ -1,318 +0,0 @@ -/* Copyright 2020 The Chromium OS Authors. All rights reserved. - * Use of this source code is governed by a BSD-style license that can be - * found in the LICENSE file. - */ - -#ifndef __CROS_EC_IOEXPANDERS_H -#define __CROS_EC_IOEXPANDERS_H - -#define BOARD_ID_DET_MASK 0x7 -#define BOARD_ID_DET_OFFSET 3 -#define BOARD_ID_DET_PORT 1 - -enum uservo_fastboot_mux_sel_t { - MUX_SEL_USERVO = 0, - MUX_SEL_FASTBOOT = 1 -}; - -/* - * Initialize Ioexpanders - */ -int init_ioexpanders(void); - -/* - * Calls the Ioexpanders Deferred handler for interrupts - * Should be called from the ioexpanders IRQ handler - */ -int irq_ioexpanders(void); - -/** - * SBU Crosspoint select - * - * @param en 0 - HOST SBU to DUT SBU connected - * 1 - STM UART to DUT SBU connected - * @return EC_SUCCESS or EC_xxx on error - */ -int sbu_uart_sel(int en); - -/** - * Host KBC Controller reset - * - * @param en 0 - Assert reset - * 1 - Deassert reset - * @return EC_SUCCESS or EC_xxx on error - */ -int atmel_reset_l(int en); - -/** - * SBU Crosspoint polarity flip for DTU SBU to STM USART/Host SBU - * - * @param en 0 - Retain polarity (no inversion) - * 1 - Swap P for N polarity - * @return EC_SUCCESS or EC_xxx on error - */ -int sbu_flip_sel(int en); - -/** - * USB data path for general USB type A port - * - * @param en 0 - Host hub - * 1 - DUT hub - * @return EC_SUCCESS or EC_xxx on error - */ -int usb3_a0_mux_sel(int en); - -/** - * USB data path enable for general USB type A port, first on J2 - * - * @param en 0 - Data connected / enabled - * 1 - Data disconnected - * @return EC_SUCCESS or EC_xxx on error - */ -int usb3_a0_mux_en_l(int en); - -/** - * Controls load switches for 5V to general USB type A. - * - * @param en 0 - Disable power - * 1 - Enable power - * @return EC_SUCCESS or EC_xxx on error - */ -int ec_usb3_a0_pwr_en(int en); - -/** - * Controls logic to select 1.8V or 3.3V UART from STM to DUT on SBU lines - * - * @param en 0 - 3.3V level - * 1 - 1.8V level - * @return EC_SUCCESS or EC_xxx on error - */ -int uart_18_sel(int en); - -/** - * Controls load switches for 5V to uservo USB type A port - * - * @param en 0 - Disable power - * 1 - Enable power - * @return EC_SUCCESS or EC_xxx on error - */ -int ec_uservo_power_en(int en); - -/** - * USB data path enable from host hub to downstream userv or DUT peripheral - * - * @param sel MUX_SEL_USERVO - hub connected to uservo - * MUX_SEL_FASTBOOT - hub connected to DUT - * @return EC_SUCCESS or EC_xxx on error - */ -int uservo_fastboot_mux_sel(enum uservo_fastboot_mux_sel_t sel); - -/** - * Controls load switches for 5V to general USB type A second port - * - * @param en 0 - power off - * 1 - power enabled - * @return EC_SUCCESS or EC_xxx on error - */ -int ec_usb3_a1_pwr_en(int en); - -/** - * USB data path for general USB type A port, second on J2 - * - * @param en 0 - Host hub - * 1 - DUT hub - * @return EC_SUCCESS or EC_xxx on error - */ -int usb3_a1_mux_sel(int en); - -/** - * Reads the 3-bit Servo V4.1 version ID - * - * @return version ID - */ -int board_id_det(void); - -/** - * Reads the TypeA/TypeC DUT cable assembly pigtail - * - * @return 0 - for TypeA - * 1 - for TypeC - */ -int dongle_det(void); - -/** - * Reads state of BC1.2 on host connection - * - * @return 0 - BC1.2 not present - * 1 - BC1.2 present - */ -int get_host_chrg_det(void); - -/** - * Enable signal for supplemental power supply. This supply will support higher - * wattage servo needs. 10ms after enabling this bit, the server supply should - * switch over from the host supply and the higher wattage will be available - * - * @param en 0 - Alternate supply disabled - * 1 - Supply enabled - * @return EC_SUCCESS or EC_xxx on error - */ -int en_pp5000_alt_3p3(int en); - -/** - * Controls load switches for the RTL8153. By default, ethernet is enabled but - * power can be removed as a way to clear any bad conditions - * - * @param en 0 - disable power - * 1 - enable power - * @return EC_SUCCESS or EC_xxx on error - */ -int en_pp3300_eth(int en); - -/** - * Controls load switches that enables 3.3V supply on the Display Port - * connector. On by default - * - * @param en 0 - disable 3.3V to DP connector - * 1 - enable 3.3V to DP connector - * @return EC_SUCCESS or EC_xxx on error - */ -int en_pp3300_dp(int en); - -/** - * The rising edge of this signal clears the latched condition when thermal - * or overcurrent fault has occurred from both CC1 and CC2 channels. Note - * that if the CC drive circuitry continues to be overheated, it will reset - * the fault regardless of the FAULT_CLEAR_CC signal. - * - * @param en 0 to 1 transition - clear fault - * 1 to 0 transition, 0, or 1 - No change in fault - * @return EC_SUCCESS or EC_xxx on error - */ -int fault_clear_cc(int en); - -/** - * CC1 Drive circuitry enable - * - * @param en 0 - disable CC1 high output drive (normal CC Operation by STM) - * 1 - enable CC1 high drive output - * @return EC_SUCCESS or EC_xxx on error - */ -int en_vout_buf_cc1(int en); - -/** - * CC2 Drive circuitry enable - * - * @param en 0 - disable CC2 high output drive (normal CC Operation by STM) - * 1 - enable CC2 high drive output - * @return EC_SUCCESS or EC_xxx on error - */ -int en_vout_buf_cc2(int en); - -/** - * Controls load switches for servo to power DUT Vusb - * - * @param en 0 - disable power - * 1 - enable power - * @return EC_SUCCESS or EC_xxx on error - */ -int dut_chg_en(int en); - -/** - * Get state of DUT Vusb - * - * @return 0 - power is disabled - * 1 - power is enabled - * @return EC_SUCCESS or EC_xxx on error - */ -int get_dut_chg_en(void); - -/** - * Selects power source for DUT Vusb from servo - * - * @param en 0 - 5V - * 1 - charger Vbus - * @return EC_SUCCESS or EC_xxx on error - */ -int host_or_chg_ctl(int en); - -#define USERVO_FAULT_L BIT(0) -#define USB3_A0_FAULT_L BIT(1) -#define USB3_A1_FAULT_L BIT(2) -#define USB_DUTCHG_FLT_ODL BIT(3) -#define PP3300_DP_FAULT_L BIT(4) -#define DAC_BUF1_LATCH_FAULT_L BIT(5) -#define DAC_BUF2_LATCH_FAULT_L BIT(6) -#define PP5000_SRC_SEL BIT(7) - -/** - * Read any faults that may have occurred. A fault has occurred if the - * corresponding bit is 0. - * - * BIT: - * 0 (USERVO_FAULT_L) - Fault for port microservo USB A load switch - * 1 (USB3_A0_FAULT_L) - Fault for general port USB A load switch - * 2 (USB3_A1_FAULT_L) - Fault for general port USB A load switch - * 3 (USB_DUTCHG_FLT_ODL) - Overcurrent fault on Charger or DUB CC/SBU lines - * 4 (PP3300_DP_FAULT_L) - Overcurrent fault on DisplayPort - * 5 (DAC_BUF1_LATCH_FAULT_L) - Fault to indicate CC drive circuitry has - * exceeded thermal limits or exceeded current - * limits; when faults occur, the driver is - * disabled and needs to be reset. - * 6 (DAC_BUF2_LATCH_FAULT_L) - Fault to indicate CC drive circuitry has - * exceeded thermal limits or exceeded current - * limits; when faults occur, the driver is - * disabled and needs to be reset. - * 7 (PP5000_SRC_SEL) - Used to monitor whether Host power or Servo Charger - * USBC is providing source to PP5000. This may flip - * sources upon fault and should be monitored. - * 0 - USBC Servo charger is source - * 1 - host cable is source - */ -int read_faults(void); - -#define HOST_CHRG_DET BIT(0) -#define SYS_PWR_IRQ_ODL BIT(6) - -/** - * Read irqs which indicate some system event. - * - * BIT - * 0 (HOST_CHRG_DET) - Change of state of BC1.2 on host connection - * 0 - BC1.2 not present - * 1 - BC1.2 present - * 6 (SYS_PWR_IRQ_ODL) - IRQ from system full power INA231 monitor. IRQ can be - * programmed to trip on wattage threshold. - * 0 - IRQ asserted - * 1 - no IRQ - */ -int read_irqs(void); - -/** - * Enables active discharge for USB DUT Charger - * - * @param en 0 - disable active discharge (default) - * 1 - enable active discharge circuitry - * @return EC_SUCCESS or EC_xxx on error - */ -int vbus_dischrg_en(int en); - -/** - * Enables Hub - * - * @param en 0 - place hub in suspend (low power state) - * 1 - enable hub activity (including i2c) - * @return EC_SUCCESS or EC_xxx on error - */ -int usbh_pwrdn_l(int en); - -/** - * Debug LED - * - * @param en 0 - LED is OFF - * 1 - LED is ON - * @return EC_SUCCESS or EC_xxx on error - */ -int tca_gpio_dbg_led_k_odl(int en); - -#endif /* __CROS_EC_IOEXPANDERS_H */ diff --git a/board/servo_v4p1/pathsel.c b/board/servo_v4p1/pathsel.c deleted file mode 100644 index 7b71fba169..0000000000 --- a/board/servo_v4p1/pathsel.c +++ /dev/null @@ -1,76 +0,0 @@ -/* Copyright 2020 The Chromium OS Authors. All rights reserved. - * Use of this source code is governed by a BSD-style license that can be - * found in the LICENSE file. - */ - -#include "gl3590.h" -#include "gpio.h" -#include "ioexpanders.h" -#include "pathsel.h" - -static void hh_usb3_a0_pwr_en(int en) -{ - gl3590_enable_ports(0, GL3590_DFP2, en); -} - -static void hh_usb3_a1_pwr_en(int en) -{ - gl3590_enable_ports(0, GL3590_DFP1, en); -} - -void init_pathsel(void) -{ - /* Connect TypeA port to DUT hub */ - usb3_a0_to_dut(); - /* Connect data lines */ - usb3_a0_mux_en_l(0); - - /* Enable power */ - ec_usb3_a0_pwr_en(1); - - hh_usb3_a0_pwr_en(1); - - /* Connect TypeA port to DUT hub */ - usb3_a1_to_dut(); - /* Connect data lines */ - gpio_set_level(GPIO_USB3_A1_MUX_EN_L, 0); - - /* Enable power */ - ec_usb3_a1_pwr_en(1); - - hh_usb3_a1_pwr_en(1); -} - -void usb3_a0_to_dut(void) -{ - usb3_a0_mux_sel(1); - gpio_set_level(GPIO_FASTBOOT_DUTHUB_MUX_SEL, 1); -} - -void usb3_a1_to_dut(void) -{ - usb3_a1_mux_sel(1); - gpio_set_level(GPIO_FASTBOOT_DUTHUB_MUX_SEL, 1); -} - -void usb3_a0_to_host(void) -{ - usb3_a0_mux_sel(0); -} - -void usb3_a1_to_host(void) -{ - usb3_a1_mux_sel(0); -} - -void dut_to_host(void) -{ - gpio_set_level(GPIO_FASTBOOT_DUTHUB_MUX_SEL, 0); - gpio_set_level(GPIO_FASTBOOT_DUTHUB_MUX_EN_L, 0); - uservo_fastboot_mux_sel(MUX_SEL_FASTBOOT); -} - -void uservo_to_host(void) -{ - uservo_fastboot_mux_sel(MUX_SEL_USERVO); -} diff --git a/board/servo_v4p1/pathsel.h b/board/servo_v4p1/pathsel.h deleted file mode 100644 index 7365d3adf3..0000000000 --- a/board/servo_v4p1/pathsel.h +++ /dev/null @@ -1,44 +0,0 @@ -/* Copyright 2020 The Chromium OS Authors. All rights reserved. - * Use of this source code is governed by a BSD-style license that can be - * found in the LICENSE file. - */ - -#ifndef __CROS_EC_PATHSEL_H -#define __CROS_EC_PATHSEL_H - -/** - * Both USB3_TypeA0 and USB3_TypeA1 are routed to the DUT by default. - */ -void init_pathsel(void); - -/** - * Routes USB3_TypeA0 port to DUT - */ -void usb3_a0_to_dut(void); - -/** - * Routes USB3_TypeA1 port to DUT - */ -void usb3_a1_to_dut(void); - -/** - * Routes USB3_TypeA0 port to HOST - */ -void usb3_a0_to_host(void); - -/** - * Routes USB3_TypeA1 port to HOST - */ -void usb3_a1_to_host(void); - -/** - * Routes the DUT to the HOST. Used for fastboot - */ -void dut_to_host(void); - -/** - * Routes the Micro Servo to the Host - */ -void uservo_to_host(void); - -#endif /* __CROS_EC_PATHSEL_H */ diff --git a/board/servo_v4p1/pi3usb9201.c b/board/servo_v4p1/pi3usb9201.c deleted file mode 100644 index 102eaf790d..0000000000 --- a/board/servo_v4p1/pi3usb9201.c +++ /dev/null @@ -1,34 +0,0 @@ -/* Copyright 2020 The Chromium OS Authors. All rights reserved. - * Use of this source code is governed by a BSD-style license that can be - * found in the LICENSE file. - */ - -#include "i2c.h" -#include "pi3usb9201.h" - -#define PI3USB9201_ADDR 0x5f - -inline void init_pi3usb9201(void) -{ - /* - * Write 0x08 (Client mode detection and Enable USB switch auto ON) to - * control Reg 2 - * Write 0x08 (Client Mode) to Control Reg 1 - */ - i2c_write16(1, PI3USB9201_ADDR, CTRL_REG1, 0x0808); -} - -inline void write_pi3usb9201(enum pi3usb9201_reg_t reg, - enum pi3usb9201_dat_t dat) -{ - i2c_write8(1, PI3USB9201_ADDR, reg, dat); -} - -inline uint8_t read_pi3usb9201(enum pi3usb9201_reg_t reg) -{ - int tmp; - - i2c_read8(1, PI3USB9201_ADDR, reg, &tmp); - - return tmp; -} diff --git a/board/servo_v4p1/pi3usb9201.h b/board/servo_v4p1/pi3usb9201.h deleted file mode 100644 index 826db8b871..0000000000 --- a/board/servo_v4p1/pi3usb9201.h +++ /dev/null @@ -1,59 +0,0 @@ -/* Copyright 2020 The Chromium OS Authors. All rights reserved. - * Use of this source code is governed by a BSD-style license that can be - * found in the LICENSE file. - */ - -#ifndef __CROS_EC_PI3USB9201_H -#define __CROS_EC_PI3USB9201_H - -enum pi3usb9201_reg_t { - CTRL_REG1, - CTRL_REG2, - CLIENT_STATUS, - HOST_STATUS -}; - -enum pi3usb9201_dat_t { - POWER_DOWN = 0x0, - SDP_HOST_MODE = 0x2, - DCP_HOST_MODE = 0x4, - CDP_HOST_MODE = 0x6, - CLIENT_MODE = 0x8, - USB_PATH_ON = 0xe -}; - - -/* Client Status bits */ -#define CS_DCP BIT(7) -#define CS_SDP BIT(6) -#define CS_CDP BIT(5) -#define CS_1A_CHARGER BIT(3) -#define CS_2A_CHARGER BIT(2) -#define CS_2_4A_CHARGER BIT(1) - -/* Host Status bits */ -#define HS_USB_UNPLUGGED BIT(2) -#define HS_USB_PLUGGED BIT(1) -#define HS_BC1_2 BIT(0) - -/** - * Selects Client Mode and client mode detection - */ -void init_pi3usb9201(void); - -/** - * Write a byte to the pi3usb9201 - * - * @param reg register to write - * @param dat data to write to the register - */ -void write_pi3usb9201(enum pi3usb9201_reg_t reg, enum pi3usb9201_dat_t dat); - -/** - * Read a byte from the pi3usb9201 - * - * @param return data byte read from pi3usb9201 - */ -uint8_t read_pi3usb9201(enum pi3usb9201_reg_t reg); - -#endif /* __CROS_EC_PI3USB9201_H */ diff --git a/board/servo_v4p1/usb_pd_config.h b/board/servo_v4p1/usb_pd_config.h deleted file mode 100644 index 63fb6b5728..0000000000 --- a/board/servo_v4p1/usb_pd_config.h +++ /dev/null @@ -1,283 +0,0 @@ -/* Copyright 2020 The Chromium OS Authors. All rights reserved. - * Use of this source code is governed by a BSD-style license that can be - * found in the LICENSE file. - */ - -#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 - -/* 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 */ -#define CC_EMCA_SERVO BIT(6) /* - * Emulate Electronically Marked Cable Assembly - * (EMCA) servo (or non-EMCA) - */ -#define CC_FASTBOOT_DFP BIT(7) /* Allow mux uServo->Fastboot on DFP */ - -/* 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_MF_PREF BIT(3) /* Multi-Function preferred */ -#define ALT_DP_PLUG BIT(4) /* Plug or receptacle */ -#define ALT_DP_OVERRIDE_HPD BIT(5) /* Override the HPD signal */ -#define ALT_DP_HPD_LVL BIT(6) /* 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 == CHG) - 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 == CHG) { - /* 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 == CHG) { - /* 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_MCU, GPIO_USB_CHG_CC2_MCU }, - { GPIO_USB_DUT_CC1_MCU, GPIO_USB_DUT_CC2_MCU }, -}; - -/* 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 == CHG) { - /* 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 != DUT) - 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_v4p1/usb_pd_policy.c b/board/servo_v4p1/usb_pd_policy.c deleted file mode 100644 index c4d7c239a1..0000000000 --- a/board/servo_v4p1/usb_pd_policy.c +++ /dev/null @@ -1,1516 +0,0 @@ -/* Copyright 2020 The Chromium OS Authors. All rights reserved. - * Use of this source code is governed by a BSD-style license that can be - * found in the LICENSE file. - */ - -#include "atomic.h" -#include "chg_control.h" -#include "charge_manager.h" -#include "common.h" -#include "console.h" -#include "gpio.h" -#include "hooks.h" -#include "host_command.h" -#include "i2c.h" -#include "ioexpanders.h" -#include "pathsel.h" -#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_INACTIVE_CC_PD(r) DUT_INACTIVE_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) -#define DUT_ACTIVE_CC_OPEN(r) DUT_ACTIVE_CC_SET(r, GPIO_INPUT) -#define DUT_INACTIVE_CC_OPEN(r) DUT_INACTIVE_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 | CC_EMCA_SERVO; - -/* 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; -/* - * Make sure the below matches CC_EMCA_SERVO - * otherwise you'll have a bad time. - */ -static int cc_pull_stored = TYPEC_CC_RD; - -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) -{ - return 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. */ - chg_power_select(CHG_POWER_OFF); - 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 != DUT) - 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 != DUT) - 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 = -1; - - if (port == CHG) - 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. - */ - - /* - * TODO(b/161260559): Fix this logic because of leakage - * "phantom detects" Or flat-out mis-detects..... talking on - * leaking CC2 line. And Vconn-swap case... and Ra on second - * line (SERVO_EMCA)... - * - * This is basically a hack faking "vOpen" from TCPCI spec. - */ - if ((cc_config & CC_DISABLE_DTS) && - port == DUT && - cc == ((cc_config & CC_POLARITY) ? 0 : 1)) { - - if ((cc_pull_stored == TYPEC_CC_RD) || - (cc_pull_stored == TYPEC_CC_RA) || - (cc_pull_stored == TYPEC_CC_RA_RD)) - mv = -1; - else if (cc_pull_stored == TYPEC_CC_RP) - mv = 3301; - } 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 = -1; - } - - return mv; -} - -static int board_set_rp(int rp) -{ - if (cc_config & CC_DISABLE_DTS) { - /* TODO: Add SRC-EMCA mode (CC_EMCA_SERVO=1) */ - /* TODO: Add SRC-nonEMCA mode (CC_EMCA_SERVO=0)*/ - - /* - * 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; - } - - /* TODO: Verify this (CC_EMCA_SERVO) statement works */ - if (cc_config & CC_EMCA_SERVO) - DUT_INACTIVE_CC_PD(RA); - else - DUT_INACTIVE_CC_OPEN(RA); - } 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 != DUT) - 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 Ra for CC1/CC2 to High-Z. */ - DUT_BOTH_CC_OPEN(RA); - /* 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) || (cc_pull == TYPEC_CC_RA_RD) || - (cc_pull == TYPEC_CC_RA)) { - /* - * 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). - * - * TODO: EXCEPT if you have Ra_Rd or are "faking" an EMCA..... - * ... or are applying RA+RA....can't make assumptions with - * test equipment! - */ - if (cc_config & CC_DISABLE_DTS) { - if (cc_pull == TYPEC_CC_RD) { - DUT_ACTIVE_CC_PD(RD); - /* - * TODO: Verify this (CC_EMCA_SERVO) - * statement works - */ - if (cc_config & CC_EMCA_SERVO) - DUT_INACTIVE_CC_PD(RA); - else - DUT_INACTIVE_CC_OPEN(RA); - } else if (cc_pull == TYPEC_CC_RA) { - DUT_ACTIVE_CC_PD(RA); - /* - * TODO: Verify this (CC_EMCA_SERVO) - * statement works - */ - if (cc_config & CC_EMCA_SERVO) - DUT_INACTIVE_CC_PD(RA); - else - DUT_INACTIVE_CC_OPEN(RA); - } else if (cc_pull == TYPEC_CC_RA_RD) { - /* - * TODO: Verify this silly (TYPEC_CC_RA_RD) - * from TCPMv works - */ - DUT_ACTIVE_CC_PD(RD); - DUT_INACTIVE_CC_PD(RA); - } - } else - DUT_BOTH_CC_PD(RD); - - rv = EC_SUCCESS; - } else - return EC_ERROR_UNIMPLEMENTED; - - rp_value_stored = rp_value; - cc_pull_stored = cc_pull; - - return rv; -} - -int board_select_rp_value(int port, int rp) -{ - if (port != DUT) - 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 */ - chg_power_select(CHG_POWER_VBUS); - 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; - 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 */ - chg_power_select(CHG_POWER_OFF); - 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) -{ - if (port == CHG) - return; - - switch (data_role) { - case PD_ROLE_DFP: - if (cc_config & CC_FASTBOOT_DFP) { - dut_to_host(); - } else { - /* Disable USB2 lines from DUT */ - gpio_set_level(GPIO_FASTBOOT_DUTHUB_MUX_EN_L, 1); - uservo_to_host(); - } - break; - case PD_ROLE_UFP: - /* Ensure that FASTBOOT is disabled */ - gpio_set_level(GPIO_FASTBOOT_DUTHUB_MUX_SEL, 1); - - /* Enable USB2 lines */ - gpio_set_level(GPIO_FASTBOOT_DUTHUB_MUX_EN_L, 0); - - /* - * By default, uServo port will be enabled. Only if the user - * explicitly enable CC_FASTBOOT_DFP then uServo is disabled. - */ - if (!(cc_config & CC_FASTBOOT_DFP)) - uservo_to_host(); - break; - case PD_ROLE_DISCONNECTED: - /* Disable USB2 lines */ - gpio_set_level(GPIO_FASTBOOT_DUTHUB_MUX_EN_L, 1); - - if (!(cc_config & CC_FASTBOOT_DFP)) - uservo_to_host(); - break; - default: - CPRINTS("C%d: %s: Invalid data_role:%d", port, __func__, data_role); - } -} - -__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; - 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 TUSB1064 supports pin assignment C and D. 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 void set_typec_mux(int pin_cfg) -{ - mux_state_t mux_mode = USB_PD_MUX_NONE; - - switch (pin_cfg) { - case 0: /* return to USB3 only */ - mux_mode = USB_PD_MUX_USB_ENABLED; - CPRINTS("PinCfg:off"); - break; - case MODE_DP_PIN_C: /* DisplayPort 4 lanes */ - mux_mode = USB_PD_MUX_DP_ENABLED; - CPRINTS("PinCfg:C"); - break; - case MODE_DP_PIN_D: /* DP + USB */ - mux_mode = USB_PD_MUX_DOCK; - CPRINTS("PinCfg:D"); - break; - default: - CPRINTS("PinCfg not supported: %d", pin_cfg); - return; - } - - usb_mux_set(DUT, mux_mode, USB_SWITCH_CONNECT, - !!(cc_config & CC_POLARITY)); -} - -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(); - mux_state_t state = usb_mux_get(DUT); - int dp_enabled = !!(state & USB_PD_MUX_DP_ENABLED); - - 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 */ - dp_enabled, - 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) - return 0; - - if (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", - get_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"); - ccprintf("emca: %s\n", cc_config & CC_EMCA_SERVO ? - "emarked" : "non-emarked"); -} - - -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 */ - pd_power_supply_reset(DUT); - /* 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 if (!strcasecmp(argv[1], "emca")) - cc_config_new |= CC_EMCA_SERVO; - else if (!strcasecmp(argv[1], "nonemca")) - cc_config_new &= ~CC_EMCA_SERVO; - 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|emca|nonemca] [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); - 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; - } - } - } - CPRINTS("Pins: %s%s", - (alt_dp_config & ALT_DP_PIN_C) ? "C" : "", - (alt_dp_config & ALT_DP_PIN_D) ? "D" : ""); - } 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 if (!strcasecmp(argv[1], "fastboot")) { - if (argc == 2) { - CPRINTF("fastboot = %d\n", - !!(cc_config & CC_FASTBOOT_DFP)); - return EC_SUCCESS; - } - - if (argc != 3) - return EC_ERROR_PARAM2; - - if (!!atoi(argv[2])) - cc_config |= CC_FASTBOOT_DFP; - else - cc_config &= ~CC_FASTBOOT_DFP; - } 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_v4p1/usb_sm.c b/board/servo_v4p1/usb_sm.c deleted file mode 100644 index 94b5e0c08d..0000000000 --- a/board/servo_v4p1/usb_sm.c +++ /dev/null @@ -1,193 +0,0 @@ -/* Copyright 2020 The Chromium OS Authors. All rights reserved. - * Use of this source code is governed by a BSD-style license that can be - * found in the LICENSE file. - */ - -#include "common.h" -#include "console.h" -#include "stdbool.h" -#include "usb_pd.h" -#include "usb_sm.h" -#include "util.h" - -#ifdef CONFIG_COMMON_RUNTIME -#define CPRINTF(format, args...) cprintf(CC_USB, format, ## args) -#define CPRINTS(format, args...) cprints(CC_USB, format, ## args) -#else /* CONFIG_COMMON_RUNTIME */ -#define CPRINTF(format, args...) -#define CPRINTS(format, args...) -#endif - -/* Private structure (to this file) used to track state machine context */ -struct internal_ctx { - usb_state_ptr last_entered; - uint32_t running : 1; - uint32_t enter : 1; - uint32_t exit : 1; -}; -BUILD_ASSERT(sizeof(struct internal_ctx) == - member_size(struct sm_ctx, internal)); - -/* Gets the first shared parent state between a and b (inclusive) */ -static usb_state_ptr shared_parent_state(usb_state_ptr a, usb_state_ptr b) -{ - const usb_state_ptr orig_b = b; - - /* There are no common ancestors */ - if (b == NULL) - return NULL; - - /* This assumes that both A and B are NULL terminated without cycles */ - while (a != NULL) { - /* We found a match return */ - if (a == b) - return a; - - /* - * Otherwise, increment b down the list for comparison until we - * run out, then increment a and start over on b for comparison - */ - if (b->parent == NULL) { - a = a->parent; - b = orig_b; - } else { - b = b->parent; - } - } - - return NULL; -} - -/* - * Call all entry functions of parents before children. If set_state is called - * during one of the entry functions, then do not call any remaining entry - * functions. - */ -static void call_entry_functions(const int port, - struct internal_ctx *const internal, - const usb_state_ptr stop, - const usb_state_ptr current) -{ - if (current == stop) - return; - - call_entry_functions(port, internal, stop, current->parent); - - /* - * If the previous entry function called set_state, then don't enter - * remaining states. - */ - if (!internal->enter) - return; - - /* Track the latest state that was entered, so we can exit properly. */ - internal->last_entered = current; - if (current->entry) - current->entry(port); -} - -/* - * Call all exit functions of children before parents. Note set_state is ignored - * during an exit function. - */ -static void call_exit_functions(const int port, const usb_state_ptr stop, - const usb_state_ptr current) -{ - if (current == stop) - return; - - if (current->exit) - current->exit(port); - - call_exit_functions(port, stop, current->parent); -} - -void set_state(const int port, struct sm_ctx *const ctx, - const usb_state_ptr new_state) -{ - struct internal_ctx * const internal = (void *) ctx->internal; - usb_state_ptr last_state; - usb_state_ptr shared_parent; - - /* - * It does not make sense to call set_state in an exit phase of a state - * since we are already in a transition; we would always ignore the - * intended state to transition into. - */ - if (internal->exit) { - CPRINTF("C%d: Ignoring set state to 0x%pP within 0x%pP", - port, new_state, ctx->current); - return; - } - - /* - * Determine the last state that was entered. Normally it is current, - * but we could have called set_state within an entry phase, so we - * shouldn't exit any states that weren't fully entered. - */ - last_state = internal->enter ? internal->last_entered : ctx->current; - - /* We don't exit and re-enter shared parent states */ - shared_parent = shared_parent_state(last_state, new_state); - - /* - * Exit all of the non-common states from the last state. - */ - internal->exit = true; - call_exit_functions(port, shared_parent, last_state); - internal->exit = false; - - ctx->previous = ctx->current; - ctx->current = new_state; - - /* - * Enter all new non-common states. last_entered will contain the last - * state that successfully entered before another set_state was called. - */ - internal->last_entered = NULL; - internal->enter = true; - call_entry_functions(port, internal, shared_parent, ctx->current); - /* - * Setting enter to false ensures that all pending entry calls will be - * skipped (in the case of a parent state calling set_state, which means - * we should not enter any child states) - */ - internal->enter = false; - - /* - * If we set_state while we are running a child state, then stop running - * any remaining parent states. - */ - internal->running = false; -} - -/* - * Call all run functions of children before parents. If set_state is called - * during one of the entry functions, then do not call any remaining entry - * functions. - */ -static void call_run_functions(const int port, - const struct internal_ctx *const internal, - const usb_state_ptr current) -{ - if (!current) - return; - - /* If set_state is called during run, don't call remain functions. */ - if (!internal->running) - return; - - if (current->run) - current->run(port); - - call_run_functions(port, internal, current->parent); -} - -void run_state(const int port, struct sm_ctx *const ctx) -{ - struct internal_ctx * const internal = (void *) ctx->internal; - - internal->running = true; - call_run_functions(port, internal, ctx->current); - internal->running = false; -} diff --git a/board/servo_v4p1/usb_tc_snk_sm.c b/board/servo_v4p1/usb_tc_snk_sm.c deleted file mode 100644 index f9a3966434..0000000000 --- a/board/servo_v4p1/usb_tc_snk_sm.c +++ /dev/null @@ -1,291 +0,0 @@ -/* Copyright 2020 The Chromium OS Authors. All rights reserved. - * Use of this source code is governed by a BSD-style license that can be - * found in the LICENSE file. - */ - -#include "common.h" -#include "console.h" -#include "fusb302b.h" -#include "ioexpanders.h" -#include "system.h" -#include "task.h" -#include "usb_common.h" -#include "usb_pd.h" -#include "usb_sm.h" -#include "usb_tc_sm.h" - -#define EVT_TIMEOUT_NEVER (-1) -#define EVT_TIMEOUT_5MS (5 * MSEC) - -/* - * USB Type-C Sink - * See Figure 4-13 in Release 1.4 of USB Type-C Spec. - */ -#define CPRINTF(format, args...) cprintf(CC_USBPD, format, ## args) -#define CPRINTS(format, args...) cprints(CC_USBPD, format, ## args) - -/* Type-C Layer Flags */ - -/* List of all TypeC-level states */ -enum usb_tc_state { - TC_UNATTACHED_SNK, - TC_ATTACH_WAIT_SNK, - TC_ATTACHED_SNK, -}; -/* Forward declare the full list of states. This is indexed by usb_tc_state */ -static const struct usb_state tc_states[]; - -/* TypeC Power strings */ -static const char * const pwr2_5_str = "5V/0.5A"; -static const char * const pwr7_5_str = "5V/1.5A"; -static const char * const pwr15_str = "5V/3A"; - -static struct type_c { - /* state machine context */ - struct sm_ctx ctx; - /* Port polarity */ - enum tcpc_cc_polarity polarity; - /* event timeout */ - uint64_t evt_timeout; - /* Time a port shall wait before it can determine it is attached */ - uint64_t cc_debounce; - /* - * Time a Sink port shall wait before it can determine it is detached - * due to the potential for USB PD signaling on CC as described in - * the state definitions. - */ - uint64_t pd_debounce; - /* The cc state */ - enum pd_cc_states cc_state; - /* Generic timer */ - uint64_t timeout; - /* Voltage on CC pin */ - enum tcpc_cc_voltage_status cc_voltage; - /* Current CC1 value */ - int cc1; - /* Current CC2 value */ - int cc2; -} tc; - -/* Forward declare common, private functions */ -static void set_state_tc(const enum usb_tc_state new_state); - -static void restart_tc_sm(enum usb_tc_state start_state) -{ - int res; - - res = init_fusb302b(1); - CPRINTS("FUSB302b init %s", res ? "failed" : "ready"); - - /* State machine is disabled if init_fusb302b fails */ - if (!res) - set_state_tc(start_state); - - /* Disable timeout. Task will wake on interrupt */ - tc.evt_timeout = EVT_TIMEOUT_NEVER; -} - -/* - * Private Functions - */ - -/* Set the TypeC state machine to a new state. */ -static void set_state_tc(const enum usb_tc_state new_state) -{ - set_state(0, &tc.ctx, &tc_states[new_state]); -} - -static void print_alt_power(void) -{ - enum tcpc_cc_voltage_status cc; - char const *pwr; - - cc = tc.polarity ? tc.cc2 : tc.cc1; - if (cc == TYPEC_CC_VOLT_OPEN || - cc == TYPEC_CC_VOLT_RA || cc == TYPEC_CC_VOLT_RD) { - /* Supply removed or not detected */ - return; - } - - if (cc == TYPEC_CC_VOLT_RP_1_5) - pwr = pwr7_5_str; - else if (cc == TYPEC_CC_VOLT_RP_3_0) - pwr = pwr15_str; - else - pwr = pwr2_5_str; - - CPRINTS("ALT: Switching to alternate supply @ %s", pwr); -} - -static void sink_power_sub_states(void) -{ - enum tcpc_cc_voltage_status cc; - enum tcpc_cc_voltage_status new_cc_voltage; - - cc = tc.polarity ? tc.cc2 : tc.cc1; - - if (cc == TYPEC_CC_VOLT_RP_DEF) - new_cc_voltage = TYPEC_CC_VOLT_RP_DEF; - else if (cc == TYPEC_CC_VOLT_RP_1_5) - new_cc_voltage = TYPEC_CC_VOLT_RP_1_5; - else if (cc == TYPEC_CC_VOLT_RP_3_0) - new_cc_voltage = TYPEC_CC_VOLT_RP_3_0; - else - new_cc_voltage = TYPEC_CC_VOLT_OPEN; - - /* Debounce the cc state */ - if (new_cc_voltage != tc.cc_voltage) { - tc.cc_voltage = new_cc_voltage; - tc.cc_debounce = get_time().val + PD_T_RP_VALUE_CHANGE; - return; - } - - if (tc.cc_debounce == 0 || get_time().val < tc.cc_debounce) - return; - - tc.cc_debounce = 0; - print_alt_power(); -} - -/* - * TYPE-C State Implementations - */ - -/** - * Unattached.SNK - */ -static void tc_unattached_snk_entry(int port) -{ - tc.evt_timeout = EVT_TIMEOUT_NEVER; -} - -static void tc_unattached_snk_run(int port) -{ - /* - * The port shall transition to AttachWait.SNK when a Source - * connection is detected, as indicated by the SNK.Rp state - * on at least one of its CC pins. - */ - if (cc_is_rp(tc.cc1) || cc_is_rp(tc.cc2)) - set_state_tc(TC_ATTACH_WAIT_SNK); -} - -/** - * AttachWait.SNK - */ -static void tc_attach_wait_snk_entry(int port) -{ - tc.evt_timeout = EVT_TIMEOUT_5MS; - tc.cc_state = PD_CC_UNSET; -} - -static void tc_attach_wait_snk_run(int port) -{ - enum pd_cc_states new_cc_state; - - if (cc_is_rp(tc.cc1) && cc_is_rp(tc.cc2)) - new_cc_state = PD_CC_DFP_DEBUG_ACC; - else if (cc_is_rp(tc.cc1) || cc_is_rp(tc.cc2)) - new_cc_state = PD_CC_DFP_ATTACHED; - else - new_cc_state = PD_CC_NONE; - - /* Debounce the cc state */ - if (new_cc_state != tc.cc_state) { - tc.cc_debounce = get_time().val + PD_T_CC_DEBOUNCE; - tc.pd_debounce = get_time().val + PD_T_PD_DEBOUNCE; - tc.cc_state = new_cc_state; - return; - } - - /* Wait for CC debounce */ - if (get_time().val < tc.cc_debounce) - return; - - /* - * The port shall transition to Attached.SNK after the state of only - * one of the CC1 or CC2 pins is SNK.Rp for at least tCCDebounce and - * VBUS is detected. - */ - if (is_vbus_present() && (new_cc_state == PD_CC_DFP_ATTACHED)) - set_state_tc(TC_ATTACHED_SNK); - else - set_state_tc(TC_UNATTACHED_SNK); -} - -/** - * Attached.SNK - */ -static void tc_attached_snk_entry(int port) -{ - print_alt_power(); - - tc.evt_timeout = EVT_TIMEOUT_NEVER; - tc.cc_debounce = 0; - - /* Switch over to alternate supply */ - en_pp5000_alt_3p3(1); -} - -static void tc_attached_snk_run(int port) -{ - /* Detach detection */ - if (!is_vbus_present()) { - set_state_tc(TC_UNATTACHED_SNK); - return; - } - - /* Run Sink Power Sub-State */ - sink_power_sub_states(); -} - -static void tc_attached_snk_exit(int port) -{ - /* Alternate charger removed. Switch back to host power */ - en_pp5000_alt_3p3(0); -} - -/* - * Type-C State - * - * TC_UNATTACHED_SNK - * TC_ATTACH_WAIT_SNK - * TC_TRY_WAIT_SNK - * TC_ATTACHED_SNK - */ -static const struct usb_state tc_states[] = { - [TC_UNATTACHED_SNK] = { - .entry = tc_unattached_snk_entry, - .run = tc_unattached_snk_run, - }, - [TC_ATTACH_WAIT_SNK] = { - .entry = tc_attach_wait_snk_entry, - .run = tc_attach_wait_snk_run, - }, - [TC_ATTACHED_SNK] = { - .entry = tc_attached_snk_entry, - .run = tc_attached_snk_run, - .exit = tc_attached_snk_exit, - }, -}; - -void snk_task(void *u) -{ - /* Unattached.SNK is the default starting state. */ - restart_tc_sm(TC_UNATTACHED_SNK); - - while (1) { - /* wait for next event or timeout expiration */ - task_wait_event(tc.evt_timeout); - - /* Sample CC lines */ - get_cc(&tc.cc1, &tc.cc2); - - /* Detect polarity */ - tc.polarity = (tc.cc1 > tc.cc2) ? POLARITY_CC1 : POLARITY_CC2; - - /* Run TypeC state machine */ - run_state(0, &tc.ctx); - } -} - |