diff options
author | Sam Hurst <shurst@google.com> | 2018-09-13 09:27:08 -0700 |
---|---|---|
committer | chrome-bot <chrome-bot@chromium.org> | 2019-04-08 22:30:19 -0700 |
commit | 0fe6147a9d8d9feef5049aa6c6c4a6ad30d12b26 (patch) | |
tree | 05d4509bcfe68a248ec3fa58168f3de2536c2d9c /board/chocodile_vpdmcu | |
parent | e097feb8b2db20cd2435a483517356defa222db1 (diff) | |
download | chrome-ec-0fe6147a9d8d9feef5049aa6c6c4a6ad30d12b26.tar.gz |
chocodile_vpdmcu: Firmware for chocodile mcu
Implement Chocodile Charge-Through Vconn Powered firmware for mcu
using new Type-C/PD State machine stack.
BUG=b:115626873
BRANCH=none
TEST=manual
Charge-Through was tested on an Atlas running a DRP USB-C/PD state
machine with CTUnattached.SNK and CTAttached.SNK states.
Signed-off-by: Sam Hurst <shurst@chromium.org>
Change-Id: I847f1bcd2fc3ce41e66edd133a10c943d5e8c819
Reviewed-on: https://chromium-review.googlesource.com/1225250
Commit-Ready: ChromeOS CL Exonerator Bot <chromiumos-cl-exonerator@appspot.gserviceaccount.com>
Tested-by: Sam Hurst <shurst@google.com>
Reviewed-by: Stefan Reinauer <reinauer@google.com>
Diffstat (limited to 'board/chocodile_vpdmcu')
-rw-r--r-- | board/chocodile_vpdmcu/board.c | 70 | ||||
-rw-r--r-- | board/chocodile_vpdmcu/board.h | 139 | ||||
-rw-r--r-- | board/chocodile_vpdmcu/build.mk | 16 | ||||
-rw-r--r-- | board/chocodile_vpdmcu/ec.tasklist | 22 | ||||
-rw-r--r-- | board/chocodile_vpdmcu/gpio.inc | 80 | ||||
-rw-r--r-- | board/chocodile_vpdmcu/usb_pd_config.h | 163 | ||||
-rw-r--r-- | board/chocodile_vpdmcu/vpd_api.c | 531 | ||||
-rw-r--r-- | board/chocodile_vpdmcu/vpd_api.h | 276 |
8 files changed, 1297 insertions, 0 deletions
diff --git a/board/chocodile_vpdmcu/board.c b/board/chocodile_vpdmcu/board.c new file mode 100644 index 0000000000..ea4d129502 --- /dev/null +++ b/board/chocodile_vpdmcu/board.c @@ -0,0 +1,70 @@ +/* Copyright 2019 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. + */ + +/* chocodile board configuration */ + +#include "adc.h" +#include "adc_chip.h" +#include "common.h" +#include "gpio.h" +#include "hooks.h" +#include "host_command.h" +#include "i2c.h" +#include "registers.h" +#include "switch.h" +#include "system.h" +#include "task.h" +#include "usb_pd.h" +#include "usb_pd_tcpc.h" +#include "util.h" +#include "vpd_api.h" + +#define CPRINTS(format, args...) cprints(CC_USBCHARGE, format, ## args) + +void board_config_pre_init(void) +{ + /* enable SYSCFG clock */ + STM32_RCC_APB2ENR |= 1 << 0; +} + +#include "gpio_list.h" + +/* Initialize board. */ +static void board_init(void) +{ + /* Do nothing */ +} +DECLARE_HOOK(HOOK_INIT, board_init, HOOK_PRIO_DEFAULT); + +/* ADC channels */ +const struct adc_t adc_channels[] = { + /* USB PD CC lines sensing. Converted to mV (3300mV/4096). */ + [ADC_VCONN_VSENSE] = { + "VCONN_VSENSE", 3000, 4096, 0, STM32_AIN(ADC_VCONN_VSENSE)}, + [ADC_CC_VPDMCU] = { + "CC_VPDMCU", 3000, 4096, 0, STM32_AIN(ADC_CC_VPDMCU)}, + [ADC_CC_RP3A0_RD_L] = { + "CC_RP3A0_RD_L", 3000, 4096, 0, STM32_AIN(ADC_CC_RP3A0_RD_L)}, + [ADC_RDCONNECT_REF] = { + "RDCONNECT_REF", 3000, 4096, 0, STM32_AIN(ADC_RDCONNECT_REF)}, + [ADC_CC1_RP3A0_RD_L] = { + "CC1_RP1A5_ODH", 3000, 4096, 0, STM32_AIN(ADC_CC1_RP3A0_RD_L)}, + [ADC_CC2_RP3A0_RD_L] = { + "CC2_RP1A5_ODH", 3000, 4096, 0, STM32_AIN(ADC_CC2_RP3A0_RD_L)}, + [ADC_HOST_VBUS_VSENSE] = { + "HOST_VBUS_VSENSE", 3000, 4096, 0, STM32_AIN(ADC_HOST_VBUS_VSENSE)}, + [ADC_CHARGE_VBUS_VSENSE] = { + "CHARGE_VBUS_VSENSE", 3000, 4096, 0, STM32_AIN(ADC_CHARGE_VBUS_VSENSE)}, + [ADC_CC1_RPUSB_ODH] = { + "CC1_RPUSB_ODH", 3000, 4096, 0, STM32_AIN(ADC_CC1_RPUSB_ODH)}, + [ADC_CC2_RPUSB_ODH] = { + "CC2_RPUSB_ODH", 3000, 4096, 0, STM32_AIN(ADC_CC2_RPUSB_ODH)}, +}; +BUILD_ASSERT(ARRAY_SIZE(adc_channels) == ADC_CH_COUNT); + +void tcpc_alert_clear(int port) +{ + /* Do nothing */ +} diff --git a/board/chocodile_vpdmcu/board.h b/board/chocodile_vpdmcu/board.h new file mode 100644 index 0000000000..850d1d0011 --- /dev/null +++ b/board/chocodile_vpdmcu/board.h @@ -0,0 +1,139 @@ +/* Copyright 2019 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. + */ + +/* chocodile_mcu board configuration */ + +#ifndef __CROS_EC_BOARD_H +#define __CROS_EC_BOARD_H + +/* + * The console task is too big to include in both RO and RW images. Therefore, + * if the console task is defined, then only build an RW image. This can be + * useful for debugging to have a full console. Otherwise, without this task, + * a full RO and RW is built with a limited one-way output console. + */ +#ifdef HAS_TASK_CONSOLE +/* + * The flash size is only 32kB. + * No space for 2 partitions, + * put only RW at the beginning of the flash + */ +#undef CONFIG_FW_INCLUDE_RO +#undef CONFIG_RW_MEM_OFF +#define CONFIG_RW_MEM_OFF 0 +#undef CONFIG_RO_SIZE +#define CONFIG_RO_SIZE 0 +/* Fake full size if we had a RO partition */ +#undef CONFIG_RW_SIZE +#define CONFIG_RW_SIZE CONFIG_FLASH_SIZE +#endif /* HAS_TASK_CONSOLE */ + +/* 48 MHz SYSCLK clock frequency */ +#define CPU_CLOCK 48000000 + +/* the UART console is on USART1 (PA9/PA10) */ +#undef CONFIG_UART_CONSOLE +#define CONFIG_UART_CONSOLE 1 + +/* Optional features */ +#define CONFIG_ADC +#undef CONFIG_ADC_WATCHDOG +#define CONFIG_ADC_SAMPLE_TIME STM32_ADC_SMPR_41_5_CY +#define CONFIG_BOARD_PRE_INIT +#define CONFIG_COMMON_GPIO_SHORTNAMES +#undef CONFIG_DEBUG_ASSERT +#define CONFIG_FORCE_CONSOLE_RESUME +#define CONFIG_HIBERNATE +#undef CONFIG_HOSTCMD_EVENTS +#define CONFIG_HW_CRC +#undef CONFIG_LID_SWITCH +#define CONFIG_LOW_POWER_IDLE +#define CONFIG_LTO +#define CONFIG_STM_HWTIMER32 +#undef CONFIG_TASK_PROFILING +#undef CONFIG_UART_TX_BUF_SIZE +#undef CONFIG_UART_TX_DMA +#undef CONFIG_UART_RX_DMA +#define CONFIG_UART_TX_BUF_SIZE 128 +#define CONFIG_USB_PD_PORT_COUNT 1 +#define CONFIG_USB_PD_TCPC +#define CONFIG_USB_PD_VBUS_DETECT_NONE +#define CONFIG_USB_PD_TCPM_STUB +#define CONFIG_USB_SM_FRAMEWORK +#define CONFIG_USB_TYPEC_CTVPD +#define CONFIG_USB_PD_DUAL_ROLE +#define CONFIG_USB_PD_INTERNAL_COMP +#define CONFIG_VBOOT_HASH +#define CONFIG_WATCHDOG +#undef CONFIG_WATCHDOG_HELP +#undef CONFIG_SM_NESTING_NUM +#define CONFIG_SM_NESTING_NUM 3 + +#define CONFIG_USB_PID 0x5036 +#define VPD_HW_VERSION 0x0001 +#define VPD_FW_VERSION 0x0001 + +/* USB bcdDevice */ +#define USB_BCD_DEVICE 0 + +/* Vbus impedance in milliohms */ +#define VPD_VBUS_IMPEDANCE 65 + +/* GND impedance in milliohms */ +#define VPD_GND_IMPEDANCE 33 + +/* + * TODO(crosbug.com/p/50519): Remove CONFIG_SYSTEM_UNLOCKED prior to building + * MP FW. + */ +#define CONFIG_SYSTEM_UNLOCKED + +#ifdef HAS_TASK_CONSOLE +#undef CONFIG_CONSOLE_HISTORY +#define CONFIG_CONSOLE_HISTORY 2 + +#else +#undef CONFIG_CONSOLE_CMDHELP +#define CONFIG_DEBUG_PRINTF +#define UARTN CONFIG_UART_CONSOLE +#define UARTN_BASE STM32_USART_BASE(CONFIG_UART_CONSOLE) +#endif /* HAS_TASK_CONSOLE */ + +/* Use PSTATE embedded in the RO image, not in its own erase block */ +#undef CONFIG_FLASH_PSTATE_BANK +#undef CONFIG_FW_PSTATE_SIZE +#define CONFIG_FW_PSTATE_SIZE 0 + +#ifndef __ASSEMBLER__ + +/* Timer selection */ +#define TIM_CLOCK32 2 +#define TIM_ADC 3 + +#include "gpio_signal.h" + +/* ADC signal */ +enum adc_channel { + ADC_VCONN_VSENSE = 0, + ADC_CC_VPDMCU, + ADC_CC_RP3A0_RD_L, + ADC_RDCONNECT_REF, + ADC_CC1_RP3A0_RD_L, + ADC_CC2_RP3A0_RD_L, + ADC_HOST_VBUS_VSENSE, + ADC_CHARGE_VBUS_VSENSE, + ADC_CC1_RPUSB_ODH, + ADC_CC2_RPUSB_ODH, + /* Number of ADC channels */ + ADC_CH_COUNT +}; + +/* 1.5A Rp */ +#define PD_SRC_VNC PD_SRC_1_5_VNC_MV +#define PD_SRC_RD_THRESHOLD PD_SRC_1_5_RD_THRESH_MV + +#endif /* !__ASSEMBLER__ */ + +#endif /* __CROS_EC_BOARD_H */ diff --git a/board/chocodile_vpdmcu/build.mk b/board/chocodile_vpdmcu/build.mk new file mode 100644 index 0000000000..d4e5f58962 --- /dev/null +++ b/board/chocodile_vpdmcu/build.mk @@ -0,0 +1,16 @@ +# -*- makefile -*- +# Copyright 2019 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 STM32F051K8U6TR +CHIP:=stm32 +CHIP_FAMILY:=stm32f0 +CHIP_VARIANT:=stm32f05x + +board-y=board.o vpd_api.o +# +# This target builds RW only. Therefore, remove RO from dependencies. +all_deps=$(patsubst ro,,$(def_all_deps)) diff --git a/board/chocodile_vpdmcu/ec.tasklist b/board/chocodile_vpdmcu/ec.tasklist new file mode 100644 index 0000000000..e386c745e3 --- /dev/null +++ b/board/chocodile_vpdmcu/ec.tasklist @@ -0,0 +1,22 @@ +/* Copyright 2019 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. + */ + +/** + * List of enabled tasks in the priority order + * + * The first one has the lowest priority. + * + * For each task, use the macro TASK_ALWAYS(n, r, d, s) for base tasks and + * TASK_NOTEST(n, r, d, s) for tasks that can be excluded in test binaries, + * where : + * 'n' in the name of the task + * 'r' in the main routine of the task + * 'd' in an opaque parameter passed to the routine at startup + * 's' is the stack size in bytes; must be a multiple of 8 + */ +#define CONFIG_TASK_LIST \ + TASK_ALWAYS(HOOKS, hook_task, NULL, LARGER_TASK_STACK_SIZE) \ + TASK_ALWAYS(CONSOLE, console_task, NULL, TASK_STACK_SIZE) \ + TASK_ALWAYS(PD_C0, pd_task, NULL, LARGER_TASK_STACK_SIZE) diff --git a/board/chocodile_vpdmcu/gpio.inc b/board/chocodile_vpdmcu/gpio.inc new file mode 100644 index 0000000000..a34c617ef1 --- /dev/null +++ b/board/chocodile_vpdmcu/gpio.inc @@ -0,0 +1,80 @@ +/* -*- mode:c -*- + * + * Copyright 2019 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. + */ + +/* Declare symbolic names for all the GPIOs that we care about. + * Note: Those with interrupt handlers must be declared first. */ + +/* Divided Vconn voltage sense */ +GPIO(VCONN_VSENSE, PIN(A, 0), GPIO_ANALOG) +/* CC ADC, PD in comparator, or tx enable out (low) */ +GPIO(CC_VPDMCU, PIN(A, 1), GPIO_ANALOG) +/* CC 0.2V comparator during charge-through, active Rd (low) or Rp3A0 (high) */ +GPIO(CC_RP3A0_RD_L, PIN(A, 2), GPIO_ANALOG) +/* 0.2V resistor divider for various CC comapators */ +GPIO(RDCONNECT_REF, PIN(A, 3), GPIO_ANALOG) +/* Charger CC1 0.2V comparator and ADC, drive a Rp3A0 (high) or Rd (low) */ +GPIO(CC1_RP3A0_RD_L, PIN(A, 4), GPIO_ANALOG) +/* Charger CC2 0.2V comparator and ADC, drive a Rp3A0 (high) or Rd (low) */ +GPIO(CC2_RP3A0_RD_L, PIN(A, 5), GPIO_ANALOG) +/* Divided host VBUS voltage sense */ +GPIO(HOST_VBUS_VSENSE, PIN(A, 6), GPIO_ANALOG) +/* Divided charger VBUS voltage sense */ +GPIO(CHARGER_VBUS_VSENSE, PIN(A, 7), GPIO_ANALOG) +/* Charger CC1 ADC, or drive a RpUSB (high) */ +GPIO(CC1_RPUSB_ODH, PIN(B, 0), GPIO_ANALOG) +/* Charger CC2 ADC, or drive a RpUSB (high) */ +GPIO(CC2_RPUSB_ODH, PIN(B, 1), GPIO_ANALOG) + +/* PD TX data output */ +GPIO(CC_TX_DATA, PIN(B, 4), GPIO_INPUT) + +/* Enables the VBUS pass-through (high) */ +GPIO(VBUS_PASS_EN, PIN(B, 2), GPIO_OUT_LOW) + +/* + * Desired billboard state. One of "no billboard/nothing connected" (low), + * "source connected but not in charge-through" (pull-up), or "sink connected" + * (high) + */ +GPIO(PRESENT_BILLBOARD, PIN(A, 8), GPIO_OUT_LOW) + +/* Enables cReceiver and the path to the PD RX/TX, RpUSB, and Rp1A5 */ +GPIO(VPDMCU_CC_EN, PIN(A, 11), GPIO_OUT_LOW) + +/* Disables dead battery Rd on host side (low) */ +GPIO(CC_DB_EN_OD, PIN(A, 12), GPIO_ODR_HIGH) + +/* RpUSB on host side (high) */ +GPIO(CC_RPUSB_ODH, PIN(A, 13), GPIO_INPUT) + +/* + * Controls the dead-battery pull-downs on charger side; either dead battery + * Rd (low) or Hi-Z (high) + */ +GPIO(CC1_CC2_DB_EN_L, PIN(A, 15), GPIO_OUT_LOW) + +/* Chooses between Vconn (low) and VBUS (high) */ +GPIO(VCONN_PWR_SEL_ODL, PIN(B, 6), GPIO_INPUT) + +/* Passes CC1 to the host CC (high) */ +GPIO(CC1_SEL, PIN(F, 0), GPIO_OUT_LOW) +/* Passes CC2 to the host CC (high) */ +GPIO(CC2_SEL, PIN(F, 1), GPIO_OUT_LOW) +/* Debug red LED driver (low). Keep off for power measurements */ +GPIO(DEBUG_LED_R_L, PIN(B, 5), GPIO_ODR_HIGH) +/* Debug green LED driver (low). Keep off for power measurements */ +GPIO(DEBUG_LED_G_L, PIN(B, 7), GPIO_ODR_HIGH) + +UNIMPLEMENTED(WP_L) +UNIMPLEMENTED(ENTERING_RW) + +/* SCK(PB3): PD_TX_CLK_IN - Clock input for PD TX */ +ALTERNATE(PIN_MASK(B, 0x0008), 0, MODULE_USB_PD, 0) +/* TIM16_CH1(PB8): PD_TX_CLK_OUT - Clock generator for PD TX */ +ALTERNATE(PIN_MASK(B, 0x0100), 2, MODULE_USB_PD, 0) +/* USART1 (PA9/PA10): TX/RX for debug and programming */ +ALTERNATE(PIN_MASK(A, 0x0600), 1, MODULE_UART, 0) diff --git a/board/chocodile_vpdmcu/usb_pd_config.h b/board/chocodile_vpdmcu/usb_pd_config.h new file mode 100644 index 0000000000..a6c1adbc61 --- /dev/null +++ b/board/chocodile_vpdmcu/usb_pd_config.h @@ -0,0 +1,163 @@ +/* Copyright 2019 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 "ec_commands.h" +#include "gpio.h" +#include "vpd_api.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_C0 16 +#define TIM_CLOCK_PD_RX_C0 1 + +#define TIM_CLOCK_PD_TX(p) TIM_CLOCK_PD_TX_C0 +#define TIM_CLOCK_PD_RX(p) TIM_CLOCK_PD_RX_C0 + +/* Timer channel */ +#define TIM_TX_CCR_C0 1 +#define TIM_RX_CCR_C0 1 + +/* RX timer capture/compare register */ +#define TIM_CCR_C0 (&STM32_TIM_CCRx(TIM_CLOCK_PD_RX_C0, TIM_RX_CCR_C0)) +#define TIM_RX_CCR_REG(p) TIM_CCR_C0 + +/* TX and RX timer register */ +#define TIM_REG_TX_C0 (STM32_TIM_BASE(TIM_CLOCK_PD_TX_C0)) +#define TIM_REG_RX_C0 (STM32_TIM_BASE(TIM_CLOCK_PD_RX_C0)) +#define TIM_REG_TX(p) TIM_REG_TX_C0 +#define TIM_REG_RX(p) TIM_REG_RX_C0 + +/* use the hardware accelerator for CRC */ +#define CONFIG_HW_CRC + +/* TX uses SPI1 on PB3-4 for port C0 */ +#define SPI_REGS(p) STM32_SPI1_REGS + +static inline void spi_enable_clock(int port) +{ + STM32_RCC_APB2ENR |= STM32_RCC_PB2_SPI1; +} + +/* SPI1_TX no remap needed */ +#define DMAC_SPI_TX(p) STM32_DMAC_CH3 + +/* RX is using COMP1 triggering TIM1 CH1 */ +#define CMP1OUTSEL STM32_COMP_CMP1OUTSEL_TIM1_IC1 +#define CMP2OUTSEL 0 + +#define TIM_TX_CCR_IDX(p) TIM_TX_CCR_C0 +#define TIM_RX_CCR_IDX(p) TIM_RX_CCR_C0 +#define TIM_CCR_CS 1 + +/* EXTI line 21 is connected to the CMP1 output */ +#define EXTI_COMP1_MASK (1 << 21) +/* EXTI line 22 is connected to the CMP1 output */ +#define EXTI_COMP2_MASK (1 << 22) + +#define EXTI_COMP_MASK(p) (EXTI_COMP1_MASK | EXTI_COMP2_MASK) +#define IRQ_COMP STM32_IRQ_COMP +/* triggers packet detection on comparator falling edge */ +#define EXTI_XTSR STM32_EXTI_FTSR + +/* TIM1_CH1 no remap needed */ +#define DMAC_TIM_RX(p) STM32_DMAC_CH2 + +/* the pins used for communication need to be hi-speed */ +static inline void pd_set_pins_speed(int port) +{ + /* + * 40 MHz pin speed on SPI PB3&4, + * (USB_C0_TX_CLKIN & USB_C0_CC1_TX_DATA) + * + * 40 MHz pin speed on TIM17_CH1 (PB7), + * (PD_TX_CLK_OUT) + */ + STM32_GPIO_OSPEEDR(GPIO_B) |= 0x0000C3C0; +} + +/* Reset SPI peripheral used for TX */ +static inline void pd_tx_spi_reset(int port) +{ + /* Reset SPI1 */ + STM32_RCC_APB2RSTR |= (1 << 12); + STM32_RCC_APB2RSTR &= ~(1 << 12); +} + +/* Drive the CC line from the TX block */ +static inline void pd_tx_enable(int port, int polarity) +{ + /* USB_CC_TX_DATA: PB4 is SPI1 MISO */ + STM32_GPIO_MODER(GPIO_B) = (STM32_GPIO_MODER(GPIO_B) + & ~(3 << (2*4))) /* PB4 disable ADC */ + | (2 << (2*4)); /* Set as SPI1_MISO */ + /* MCU ADC PA1 pin output low */ + STM32_GPIO_MODER(GPIO_A) = (STM32_GPIO_MODER(GPIO_A) + & ~(3 << (2*1))) /* PA1 disable ADC */ + | (1 << (2*1)); /* Set as GPO */ + gpio_set_level(GPIO_CC_VPDMCU, 0); +} + +/* Put the TX driver in Hi-Z state */ +static inline void pd_tx_disable(int port, int polarity) +{ + /* Set CC_TX_DATA to Hi-Z, PB4 is SPI1 MISO */ + STM32_GPIO_MODER(GPIO_B) = (STM32_GPIO_MODER(GPIO_B) + & ~(3 << (2*4))); + /* set ADC PA1 pin to ADC function (Hi-Z) */ + STM32_GPIO_MODER(GPIO_A) = (STM32_GPIO_MODER(GPIO_A) + | (3 << (2*1))); /* PA1 as ADC */ +} + +/* we know the plug polarity, do the right configuration */ +static inline void pd_select_polarity(int port, int polarity) +{ + /* + * use the right comparator : CC1 -> PA1 (COMP1 INP) + * use VrefInt / 2 as INM (about 600mV) + */ + STM32_COMP_CSR = (STM32_COMP_CSR & ~STM32_COMP_CMP1INSEL_MASK) + | STM32_COMP_CMP1EN | STM32_COMP_CMP1INSEL_VREF12; +} + +/* Initialize pins used for TX and put them in Hi-Z */ +static inline void pd_tx_init(void) +{ + gpio_config_module(MODULE_USB_PD, 1); +} + +static inline void pd_set_host_mode(int port, int enable) +{ + /* Do nothing */ +} + +/** + * Initialize various GPIOs and interfaces to safe state at start of pd_task. + * + * These include: + * 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) +{ + /* Initialize TX pins and put them in Hi-Z */ + pd_tx_init(); + pd_tx_disable(0, 0); +} + +static inline int pd_adc_read(int port, int cc) +{ + return 0; +} + +#endif /* __CROS_EC_USB_PD_CONFIG_H */ + diff --git a/board/chocodile_vpdmcu/vpd_api.c b/board/chocodile_vpdmcu/vpd_api.c new file mode 100644 index 0000000000..ecbedd082f --- /dev/null +++ b/board/chocodile_vpdmcu/vpd_api.c @@ -0,0 +1,531 @@ +/* Copyright 2019 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 "gpio.h" +#include "registers.h" +#include "vpd_api.h" +#include "driver/tcpm/tcpm.h" + +/* + * Polarity based on 'DFP Perspective' (see table 4-10 USB Type-C Cable and + * Connector Specification Release 1.3) + * + * CC1 CC2 STATE POSITION + * ---------------------------------------- + * open open NC N/A + * Rd open UFP attached 1 + * open Rd UFP attached 2 + * open Ra pwr cable no UFP N/A + * Ra open pwr cable no UFP N/A + * Rd Ra pwr cable & UFP 1 + * Ra Rd pwr cable & UFP 2 + * Rd Rd dbg accessory N/A + * Ra Ra audio accessory N/A + * + * Note, V(Rd) > V(Ra) + */ +#ifndef PD_SRC_RD_THRESHOLD +#define PD_SRC_RD_THRESHOLD PD_SRC_DEF_RD_THRESH_MV +#endif +#ifndef PD_SRC_VNC +#define PD_SRC_VNC PD_SRC_DEF_VNC_MV +#endif + +#undef CC_RA +#define CC_RA(cc, sel) (cc < pd_src_rd_threshold[sel]) +#undef CC_RD +#define CC_RD(cc, sel) ((cc >= pd_src_rd_threshold[sel]) && (cc < PD_SRC_VNC)) + +/* (15.8K / (100K + 15.8K)) * 1000 = 136.4 */ +#define VBUS_SCALE_FACTOR 136 +/* (118K / (100K + 118K)) * 1000 = 541.3 */ +#define VCONN_SCALE_FACTOR 541 + +#define VBUS_DETECT_THRESHOLD 2500 /* mV */ +#define VCONN_DETECT_THRESHOLD 2500 /* mV */ + +#define SCALE(vmeas, sfactor) (((vmeas) * 1000) / (sfactor)) + +/* + * Type C power source charge current limits are identified by their cc + * voltage (set by selecting the proper Rd resistor). Any voltage below + * TYPE_C_SRC_500_THRESHOLD will not be identified as a type C charger. + */ +#define TYPE_C_SRC_DEFAULT_THRESHOLD 200 /* mV */ +#define TYPE_C_SRC_1500_THRESHOLD 660 /* mV */ +#define TYPE_C_SRC_3000_THRESHOLD 1230 /* mV */ + +/* Charge-Through pull up/down enabled */ +static int ct_cc_pull; +/* Charge-Through pull up value */ +static int ct_cc_rp_value; + +/* Charge-Through pull up/down enabled */ +static int host_cc_pull; +/* Charge-Through pull up value */ +static int host_cc_rp_value; + +/* 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, +}; + +/* Convert CC voltage to CC status */ +static int vpd_cc_voltage_to_status(int cc_volt, int cc_pull) +{ + /* If we have a pull-up, then we are source, check for Rd. */ + if (cc_pull == TYPEC_CC_RP) { + if (CC_RD(cc_volt, ct_cc_rp_value)) + return TYPEC_CC_RD; + else if (CC_RA(cc_volt, ct_cc_rp_value)) + return TYPEC_CC_VOLT_RA; + else + return TYPEC_CC_VOLT_OPEN; + /* If we have a pull-down, then we are sink, check for Rp. */ + } else if (cc_pull == TYPEC_CC_RD || cc_pull == TYPEC_CC_RA_RD) { + if (cc_volt >= TYPE_C_SRC_3000_THRESHOLD) + return TYPEC_CC_VOLT_RP_3_0; + else if (cc_volt >= TYPE_C_SRC_1500_THRESHOLD) + return TYPEC_CC_VOLT_RP_1_5; + else if (cc_volt >= TYPE_C_SRC_DEFAULT_THRESHOLD) + return TYPEC_CC_VOLT_RP_DEF; + else + return TYPEC_CC_VOLT_OPEN; + } else { + /* If we are open, then always return 0 */ + return 0; + } +} + +void vpd_ct_set_pull(int pull, int rp_value) +{ + ct_cc_pull = pull; + + switch (pull) { + case TYPEC_CC_RP: + ct_cc_rp_value = rp_value; + vpd_cc1_cc2_db_en_l(GPO_HIGH); + switch (rp_value) { + case TYPEC_RP_USB: + vpd_config_cc1_rp3a0_rd_l(PIN_ADC, 0); + vpd_config_cc2_rp3a0_rd_l(PIN_ADC, 0); + vpd_config_cc1_rpusb_odh(PIN_GPO, 1); + vpd_config_cc2_rpusb_odh(PIN_GPO, 1); + break; + case TYPEC_RP_3A0: + vpd_config_cc1_rpusb_odh(PIN_ADC, 0); + vpd_config_cc2_rpusb_odh(PIN_ADC, 0); + vpd_config_cc1_rp3a0_rd_l(PIN_GPO, 1); + vpd_config_cc2_rp3a0_rd_l(PIN_GPO, 1); + break; + } + break; + case TYPEC_CC_RD: + vpd_config_cc1_rpusb_odh(PIN_ADC, 0); + vpd_config_cc2_rpusb_odh(PIN_ADC, 0); + vpd_config_cc1_rp3a0_rd_l(PIN_GPO, 0); + vpd_config_cc2_rp3a0_rd_l(PIN_GPO, 0); + vpd_cc1_cc2_db_en_l(GPO_HIGH); + break; + case TYPEC_CC_OPEN: + vpd_cc1_cc2_db_en_l(GPO_HIGH); + vpd_config_cc1_rpusb_odh(PIN_ADC, 0); + vpd_config_cc2_rpusb_odh(PIN_ADC, 0); + vpd_config_cc1_rp3a0_rd_l(PIN_ADC, 0); + vpd_config_cc2_rp3a0_rd_l(PIN_ADC, 0); + break; + } +} + +void vpd_ct_get_cc(int *cc1, int *cc2) +{ + int cc1_v; + int cc2_v; + + switch (ct_cc_pull) { + case TYPEC_CC_RP: + switch (ct_cc_rp_value) { + case TYPEC_RP_USB: + cc1_v = adc_read_channel(ADC_CC1_RP3A0_RD_L); + cc2_v = adc_read_channel(ADC_CC2_RP3A0_RD_L); + break; + case TYPEC_RP_3A0: + cc1_v = adc_read_channel(ADC_CC1_RPUSB_ODH); + cc2_v = adc_read_channel(ADC_CC2_RPUSB_ODH); + break; + } + break; + case TYPEC_CC_RD: + cc1_v = adc_read_channel(ADC_CC1_RPUSB_ODH); + cc2_v = adc_read_channel(ADC_CC2_RPUSB_ODH); + break; + case TYPEC_CC_OPEN: + *cc1 = 0; + *cc2 = 0; + return; + } + + *cc1 = vpd_cc_voltage_to_status(cc1_v, ct_cc_pull); + *cc2 = vpd_cc_voltage_to_status(cc2_v, ct_cc_pull); +} + +void vpd_host_set_pull(int pull, int rp_value) +{ + host_cc_pull = pull; + + switch (pull) { + case TYPEC_CC_RP: + vpd_cc_db_en_od(GPO_LOW); + host_cc_rp_value = rp_value; + switch (rp_value) { + case TYPEC_RP_USB: + vpd_config_cc_rp3a0_rd_l(PIN_CMP, 0); + vpd_cc_rpusb_odh(GPO_HIGH); + break; + case TYPEC_RP_3A0: + vpd_cc_rpusb_odh(GPO_HZ); + vpd_config_cc_rp3a0_rd_l(PIN_GPO, 1); + break; + } + break; + case TYPEC_CC_RD: + vpd_cc_rpusb_odh(GPO_HZ); + vpd_cc_db_en_od(GPO_LOW); + vpd_config_cc_rp3a0_rd_l(PIN_GPO, 0); + break; + case TYPEC_CC_RA_RD: + vpd_cc_rpusb_odh(GPO_HZ); + vpd_config_cc_rp3a0_rd_l(PIN_GPO, 0); + + /* + * RA is connected to VCONN + * RD is connected to CC + */ + vpd_cc_db_en_od(GPO_HZ); + break; + case TYPEC_CC_OPEN: + vpd_cc_rpusb_odh(GPO_HZ); + vpd_config_cc_rp3a0_rd_l(PIN_CMP, 0); + vpd_cc_db_en_od(GPO_LOW); + break; + } +} + +void vpd_host_get_cc(int *cc) +{ + *cc = vpd_cc_voltage_to_status( + adc_read_channel(ADC_CC_VPDMCU), host_cc_pull); +} + +void vpd_rx_enable(int en) +{ + tcpm_set_rx_enable(0, en); +} + +/* + * PA2: Configure as COMP2_INM6 or GPO + */ +void vpd_config_cc_rp3a0_rd_l(enum vpd_pin cfg, int en) +{ + if (cfg == PIN_GPO) { + /* Set output value in register */ + gpio_set_level(GPIO_CC_RP3A0_RD_L, en ? 1 : 0); + + /* Disable Analog mode and Enable GPO */ + STM32_GPIO_MODER(GPIO_A) = (STM32_GPIO_MODER(GPIO_A) + & ~(3 << (2*2))) /* PA2 disable ADC */ + | (1 << (2*2)); /* Set as GPO */ + } else { + /* Set PA2 pin to ANALOG function */ + STM32_GPIO_MODER(GPIO_A) = (STM32_GPIO_MODER(GPIO_A) + | (3 << (2*2))); /* PA2 in ANALOG mode */ + + /* Set PA3 pin to ANALOG function */ + STM32_GPIO_MODER(GPIO_A) = (STM32_GPIO_MODER(GPIO_A) + | (3 << (2*3))); /* PA3 in ANALOG mode */ + + /* Disable Window Mode. Select PA3 */ + STM32_COMP_CSR &= ~STM32_COMP_WNDWEN; + + /* No output selection. We will use Interrupt */ + STM32_COMP_CSR &= ~STM32_COMP_CMP2OUTSEL_NONE; + + /* Not inverting */ + STM32_COMP_CSR &= ~STM32_COMP_CMP2POL; + + /* Select COMP2_INM6 (PA2) */ + STM32_COMP_CSR |= STM32_COMP_CMP2INSEL_INM6; + + /* COMP Enable */ + STM32_COMP_CSR |= STM32_COMP_CMP2EN; + } +} + +/* + * PA4: Configure as ADC, CMP, or GPO + */ +void vpd_config_cc1_rp3a0_rd_l(enum vpd_pin cfg, int en) +{ + if (cfg == PIN_GPO) { + /* Default high. Enable cc1 Rp3A0 pullup */ + gpio_set_level(GPIO_CC1_RP3A0_RD_L, en ? 1 : 0); + + /* Disable Analog mode and Enable GPO */ + STM32_GPIO_MODER(GPIO_A) = (STM32_GPIO_MODER(GPIO_A) + & ~(3 << (2*4))) /* PA4 disable ADC */ + | (1 << (2*4)); /* Set as GPO */ + } + + if (cfg == PIN_ADC || cfg == PIN_CMP) { + /* Disable COMP2 */ + STM32_COMP_CSR &= ~STM32_COMP_CMP2EN; + + /* Set PA4 pin to Analog mode */ + STM32_GPIO_MODER(GPIO_A) = (STM32_GPIO_MODER(GPIO_A) + | (3 << (2*4))); /* PA4 in ANALOG mode */ + + if (cfg == PIN_CMP) { + /* Set PA3 pin to ANALOG function */ + STM32_GPIO_MODER(GPIO_A) = (STM32_GPIO_MODER(GPIO_A) + | (3 << (2*3))); /* PA3 in ANALOG mode */ + + /* Disable Window Mode. Select PA3*/ + STM32_COMP_CSR &= ~STM32_COMP_WNDWEN; + + /* No output selection. We will use Interrupt */ + STM32_COMP_CSR &= ~STM32_COMP_CMP2OUTSEL_NONE; + + /* Select COMP2_INM4 (PA4) */ + STM32_COMP_CSR |= STM32_COMP_CMP2INSEL_INM4; + + /* COMP2 Enable */ + STM32_COMP_CSR |= STM32_COMP_CMP2EN; + } + } +} + +/* + * PA5: Configure as ADC, COMP, or GPO + */ +void vpd_config_cc2_rp3a0_rd_l(enum vpd_pin cfg, int en) +{ + if (cfg == PIN_GPO) { + /* Set output value in register */ + gpio_set_level(GPIO_CC2_RP3A0_RD_L, en ? 1 : 0); + + /* Disable Analog mode and Enable GPO */ + STM32_GPIO_MODER(GPIO_A) = (STM32_GPIO_MODER(GPIO_A) + & ~(3 << (2*5))) /* PA5 disable ADC */ + | (1 << (2*5)); /* Set as GPO */ + } + + if (cfg == PIN_ADC || cfg == PIN_CMP) { + /* Disable COMP2 */ + STM32_COMP_CSR &= ~STM32_COMP_CMP2EN; + + /* Set PA5 pin to ANALOG function */ + STM32_GPIO_MODER(GPIO_A) = (STM32_GPIO_MODER(GPIO_A) + | (3 << (2*5))); /* PA5 in ANALOG mode */ + + if (cfg == PIN_CMP) { + /* Set PA3 pin to ANALOG function */ + STM32_GPIO_MODER(GPIO_A) = (STM32_GPIO_MODER(GPIO_A) + | (3 << (2*3))); /* PA3 in ANALOG mode */ + + /* Disable Window Mode. */ + STM32_COMP_CSR &= ~STM32_COMP_WNDWEN; + + /* No output selection. We will use Interrupt */ + STM32_COMP_CSR &= ~STM32_COMP_CMP2OUTSEL_NONE; + + /* Select COMP2_INM5 (PA5) */ + STM32_COMP_CSR |= STM32_COMP_CMP2INSEL_INM5; + + /* COMP2 Enable */ + STM32_COMP_CSR |= STM32_COMP_CMP2EN; + } + } +} + +/* + * PB0: Configure as ADC or GPO + */ +void vpd_config_cc1_rpusb_odh(enum vpd_pin cfg, int en) +{ + if (cfg == PIN_GPO) { + /* Set output value in register */ + gpio_set_level(GPIO_CC1_RPUSB_ODH, en ? 1 : 0); + + /* Disable Analog mode and Enable GPO */ + STM32_GPIO_MODER(GPIO_B) = (STM32_GPIO_MODER(GPIO_B) + & ~(3 << (2*0))) /* PB0 disable ADC */ + | (1 << (2*0)); /* Set as GPO */ + } else { + /* Enable Analog mode */ + STM32_GPIO_MODER(GPIO_B) = (STM32_GPIO_MODER(GPIO_B) + | (3 << (2*0))); /* PB0 in ANALOG mode */ + } +} + +/* + * PB1: Configure as ADC or GPO + */ +void vpd_config_cc2_rpusb_odh(enum vpd_pin cfg, int en) +{ + if (cfg == PIN_GPO) { + /* Set output value in register */ + gpio_set_level(GPIO_CC2_RPUSB_ODH, en ? 1 : 0); + + /* Disable Analog mode and Enable GPO */ + STM32_GPIO_MODER(GPIO_B) = (STM32_GPIO_MODER(GPIO_B) + & ~(3 << (2*1))) /* PB1 disable ADC */ + | (1 << (2*1)); /* Set as GPO */ + } else { + /* Enable Analog mode */ + STM32_GPIO_MODER(GPIO_B) = (STM32_GPIO_MODER(GPIO_B) + | (3 << (2*1))); /* PB1 in ANALOG mode */ + } +} + +inline int vpd_read_cc_vpdmcu(void) +{ + return adc_read_channel(ADC_CC_VPDMCU); +} + +inline int vpd_read_host_vbus(void) +{ + return SCALE(adc_read_channel(ADC_HOST_VBUS_VSENSE), VBUS_SCALE_FACTOR); +} + +inline int vpd_read_ct_vbus(void) +{ + return SCALE(adc_read_channel(ADC_CHARGE_VBUS_VSENSE), + VBUS_SCALE_FACTOR); +} + +inline int vpd_read_vconn(void) +{ + return SCALE(adc_read_channel(ADC_VCONN_VSENSE), VCONN_SCALE_FACTOR); +} + +inline int vpd_is_host_vbus_present(void) +{ + return (vpd_read_host_vbus() >= VBUS_DETECT_THRESHOLD); +} + +inline int vpd_is_ct_vbus_present(void) +{ + return (vpd_read_ct_vbus() >= VBUS_DETECT_THRESHOLD); +} + +inline int vpd_is_vconn_present(void) +{ + return (vpd_read_vconn() >= VCONN_DETECT_THRESHOLD); +} + +inline int vpd_read_rdconnect_ref(void) +{ + return adc_read_channel(ADC_RDCONNECT_REF); +} + +void vpd_red_led(int on) +{ + gpio_set_level(GPIO_DEBUG_LED_R_L, (on) ? 0 : 1); +} + +void vpd_green_led(int on) +{ + gpio_set_level(GPIO_DEBUG_LED_G_L, (on) ? 0 : 1); +} + +void vpd_vbus_pass_en(int en) +{ + gpio_set_level(GPIO_VBUS_PASS_EN, (en) ? 1 : 0); +} + +void vpd_present_billboard(enum vpd_billboard bb) +{ + switch (bb) { + case BB_NONE: + gpio_set_level(GPIO_PRESENT_BILLBOARD, 0); + gpio_set_flags(GPIO_PRESENT_BILLBOARD, GPIO_OUTPUT); + break; + case BB_SRC: + gpio_set_flags(GPIO_PRESENT_BILLBOARD, GPIO_INPUT); + /* Enable Pull-up on PA8 */ + STM32_GPIO_PUPDR(GPIO_A) |= (1 << (2 * 8)); + break; + case BB_SNK: + gpio_set_level(GPIO_PRESENT_BILLBOARD, 1); + gpio_set_flags(GPIO_PRESENT_BILLBOARD, GPIO_OUTPUT); + break; + } +} + +void vpd_mcu_cc_en(int en) +{ + gpio_set_level(GPIO_VPDMCU_CC_EN, (en) ? 1 : 0); +} + +void vpd_ct_cc_sel(enum vpd_cc sel) +{ + switch (sel) { + case CT_OPEN: + gpio_set_level(GPIO_CC1_SEL, 0); + gpio_set_level(GPIO_CC2_SEL, 0); + break; + case CT_CC1: + gpio_set_level(GPIO_CC2_SEL, 0); + gpio_set_level(GPIO_CC1_SEL, 1); + break; + case CT_CC2: + gpio_set_level(GPIO_CC1_SEL, 0); + gpio_set_level(GPIO_CC2_SEL, 1); + break; + } +} + +/* Set as GPO High, GPO Low, or High-Z */ +void vpd_cc_db_en_od(enum vpd_gpo val) +{ + if (val == GPO_HZ) { + gpio_set_flags(GPIO_CC_DB_EN_OD, GPIO_INPUT); + } else { + if (val == GPO_HIGH) + gpio_set_level(GPIO_CC_DB_EN_OD, 1); + else + gpio_set_level(GPIO_CC_DB_EN_OD, 0); + + gpio_set_flags(GPIO_CC_DB_EN_OD, GPIO_OUTPUT); + } +} + +void vpd_cc_rpusb_odh(enum vpd_gpo val) +{ + if (val == GPO_HZ) { + gpio_set_flags(GPIO_CC_RPUSB_ODH, GPIO_INPUT); + } else { + gpio_set_level(GPIO_CC_RPUSB_ODH, (val == GPO_HIGH) ? 1 : 0); + gpio_set_flags(GPIO_CC_RPUSB_ODH, GPIO_OUTPUT); + } +} + +void vpd_cc1_cc2_db_en_l(enum vpd_gpo val) +{ + if (val == GPO_HZ) { + gpio_set_flags(GPIO_CC1_CC2_DB_EN_L, GPIO_INPUT); + } else { + gpio_set_level(GPIO_CC1_CC2_DB_EN_L, (val == GPO_HIGH) ? 1 : 0); + gpio_set_flags(GPIO_CC1_CC2_DB_EN_L, GPIO_OUTPUT); + } +} + +void vpd_vconn_pwr_sel_odl(enum vpd_pwr en) +{ + gpio_set_level(GPIO_VCONN_PWR_SEL_ODL, (en == PWR_VBUS) ? 1 : 0); +} diff --git a/board/chocodile_vpdmcu/vpd_api.h b/board/chocodile_vpdmcu/vpd_api.h new file mode 100644 index 0000000000..df50f92006 --- /dev/null +++ b/board/chocodile_vpdmcu/vpd_api.h @@ -0,0 +1,276 @@ +/* Copyright 2019 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. + */ + +/* Vconn Power Device API module */ + +#ifndef __CROS_EC_VPD_API_H +#define __CROS_EC_VPD_API_H + +#include "adc.h" +#include "gpio.h" +#include "usb_pd.h" + +enum vpd_pin { + PIN_ADC, + PIN_CMP, + PIN_GPO +}; + +enum vpd_gpo { + GPO_HZ, + GPO_HIGH, + GPO_LOW +}; + +enum vpd_pwr { + PWR_VCONN, + PWR_VBUS, +}; + +enum vpd_cc { + CT_OPEN, + CT_CC1, + CT_CC2 +}; + +enum vpd_billboard { + BB_NONE, + BB_SRC, + BB_SNK +}; + +/** + * Set Charge-Through Rp or Rd on CC lines + * + * @param pull Either TYPEC_CC_RP or TYPEC_CC_RD + * @param rp_value When pull is RP, set this to + * TYPEC_RP_USB or TYPEC_RP_1A5. Ignored + * for TYPEC_CC_RD + */ +void vpd_ct_set_pull(int pull, int rp_value); + +/** + * Get the status of the Charge-Through CC lines + * + * @param cc1 Either TYPEC_CC_VOLT_OPEN, + * TYPEC_CC_VOLT_RA, + * TYPEC_CC_VOLT_RD, + * any other value is considered RP + * @param cc2 Either TYPEC_CC_VOLT_OPEN, + * TYPEC_CC_VOLT_RA, + * TYPEC_CC_VOLT_RD, + * any other value is considered RP + */ +void vpd_ct_get_cc(int *cc1, int *cc2); + +/** + * Set Host Rp or Rd on CC lines + * + * @param pull Either TYPEC_CC_RP or TYPEC_CC_RD + * @param rp_value When pull is RP, set this to + * TYPEC_RP_USB or TYPEC_RP_1A5. Ignored + * for TYPEC_CC_RD + */ +void vpd_host_set_pull(int pull, int rp_value); + +/** + * Get the status of the Host CC line + * + * @param cc Either TYPEC_CC_VOLT_SNK_DEF, TYPEC_CC_VOLT_SNK_1_5, + * TYPEC_CC_VOLT_SNK_3_0, or TYPEC_CC_RD + */ +void vpd_host_get_cc(int *cc); + +/** + * Set RX Enable flag + * + * @param en 1 for enable, 0 for disable + */ +void vpd_rx_enable(int en); + +/** + * Configure the cc_rp3a0_rd_l pin as ADC, CMP, or GPO + * + * @param cfg PIN_ADC, PIN_CMP, or PIN_GPO + * @param en When cfg is PIN_GPO, 1 sets pin high + * and 0 sets pin low. Else ignored + */ +void vpd_config_cc_rp3a0_rd_l(enum vpd_pin cfg, int en); + +/** + * Configure the cc1_rp3a0_rd_l pin as ADC, CMP, or GPO + * + * @param cfg PIN_ADC, PIN_CMP, or PIN_GPO + * @param en When cfg is PIN_GPO, 1 sets pin high + * and 0 sets pin low. Else ignored + */ +void vpd_config_cc1_rp3a0_rd_l(enum vpd_pin cfg, int en); + +/** + * Configure the cc2_rp3a0_rd_l pin as ADC, CMP, or GPO + * + * @param cfg PIN_ADC, PIN_CMP, or PIN_GPO + * @param en When cfg is PIN_GPO, 1 sets pin high + * and 0 sets pin low. Else ignored + */ +void vpd_config_cc2_rp3a0_rd_l(enum vpd_pin cfg, int en); + +/** + * Configure the cc1_rpusb_odh pin as ADC, CMP, or GPO + * + * @param cfg PIN_ADC, PIN_CMP, or PIN_GPO + * @param en When cfg is PIN_GPO, 1 sets pin high + * and 0 sets pin low. Else ignored + */ +void vpd_config_cc1_rpusb_odh(enum vpd_pin cfg, int en); + +/** + * Configure the cc2_rpusb_odh pin as ADC, CMP, or GPO + * + * @param cfg PIN_ADC, PIN_CMP, or PIN_GPO + * @param en When cfg is PIN_GPO, 1 sets pin high + * and 0 sets pin low. Else ignored + */ +void vpd_config_cc2_rpusb_odh(enum vpd_pin cfg, int en); + +/** + * Configure the cc_db_en_od pin to High-Impedance, low, or high + * + * @param val GPO_HZ, GPO_HIGH, GPO_LOW + */ +void vpd_cc_db_en_od(enum vpd_gpo val); + +/** + * Configure the cc_rpusb_odh pin to High-Impedance, low, or high + * + * @param val GPO_HZ, GPO_HIGH, GPO_LOW + */ +void vpd_cc_rpusb_odh(enum vpd_gpo val); + +/** + * Configure the cc_rp1a5_odh pin to High-Impedance, low, or high + * + * @param val GPO_HZ, GPO_HIGH, GPO_LOW + */ +void vpd_cc_rp1a5_odh(enum vpd_gpo val); + +/** + * Configure the cc1_cc2_db_en_l pin to High-Impedance, low, or high + * + * @param val GPO_HZ, GPO_HIGH, GPO_LOW + */ +void vpd_cc1_cc2_db_en_l(enum vpd_gpo val); + +/** + * Get status of host vbus + * + * @return 1 if host vbus is present, else 0 + */ +int vpd_is_host_vbus_present(void); + +/** + * Get status of charge-through vbus + * + * @return 1 if charge-through vbus is present, else 0 + */ +int vpd_is_ct_vbus_present(void); + +/** + * Get status of vconn + * + * @return 1 if vconn is present, else 0 + */ +int vpd_is_vconn_present(void); + +/** + * Read Host VBUS voltage. Range from 22000mV to 3000mV + * + * @return vbus voltage + */ +int vpd_read_host_vbus(void); + +/** + * Read Host CC voltage. + * + * @return cc voltage + */ +int vpd_read_cc_host(void); + +/** + * Read voltage on cc_vpdmcu pin + * + * @return cc_vpdmcu voltage + */ +int vpd_read_cc_vpdmcu(void); + +/** + * Read charge-through VBUS voltage. Range from 22000mV to 3000mV + * + * @return charge-through vbus voltage + */ +int vpd_read_ct_vbus(void); + +/** + * Read VCONN Voltage. Range from 5500mV to 3000mV + * + * @return vconn voltage + */ +int vpd_read_vconn(void); + +/** + * Turn ON/OFF Red LED. Should be off when performing power + * measurements. + * + * @param on 0 turns LED off, any other value turns it ON + */ +void vpd_red_led(int on); + +/** + * Turn ON/OFF Green LED. Should be off when performing power + * measurements. + * + * @param on 0 turns LED off, any other value turns it ON + */ +void vpd_green_led(int on); + +/** + * Connects/Disconnects the Host VBUS to the Charge-Through VBUS. + * + * @param en 0 disconnectes the VBUS, any other value connects VBUS. + */ +void vpd_vbus_pass_en(int en); + +/** + * Preset Billboard device + * + * @param bb BB_NONE no billboard presented, + * BB_SRC source connected but not in charge-through + * BB_SNK sink connected + */ +void vpd_present_billboard(enum vpd_billboard bb); + +/** + * Enables the MCU to host cc communication + * + * @param en 1 enabled, 0 disabled + */ +void vpd_mcu_cc_en(int en); + +/** + * Selects which supply to power the VPD from + * + * @param en PWR_VCONN or PWR_VBUS + */ +void vpd_vconn_pwr_sel_odl(enum vpd_pwr en); + +/** + * Controls if the Charge-Through's CC1, CC2, or neither is + * connected to Host CC + * + * @param sel CT_OPEN neither, CT_CC1 cc1, CT_CC2 cc2 + */ +void vpd_ct_cc_sel(enum vpd_cc sel); + +#endif /* __CROS_EC_VPD_API_H */ |