diff options
author | Sheng-Liang Pan <sheng-liang.pan@quanta.corp-partner.google.com> | 2021-05-03 16:47:28 +0800 |
---|---|---|
committer | Commit Bot <commit-bot@chromium.org> | 2021-05-06 17:44:53 +0000 |
commit | 147f8d37d1a88587c762f4238a860826c4498432 (patch) | |
tree | f44352a0fc8337730a0996971725ed55a9998df4 | |
parent | 8fc5f8d3beb7ab3ba79d04c1bd9e84c2c38d9d16 (diff) | |
download | chrome-ec-147f8d37d1a88587c762f4238a860826c4498432.tar.gz |
volet: Initial EC image
Create the initial EC image for the volet variant by copying the
voxel reference board EC files into a new directory named for
the variant.
(Auto-Generated by create_initial_ec_image.sh version 1.5.0).
BUG=b:186334008
BRANCH=None
TEST=make BOARD=volet
Change-Id: I97cee656f4f12785110297afb323d2feac2b48d1
Signed-off-by: Ben Chen <ben.chen2@quanta.corp-partner.google.com>
Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/platform/ec/+/2866925
Reviewed-by: Keith Short <keithshort@chromium.org>
Commit-Queue: Keith Short <keithshort@chromium.org>
Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/platform/ec/+/2874432
Tested-by: Abe Levkoy <alevkoy@chromium.org>
Reviewed-by: Abe Levkoy <alevkoy@chromium.org>
Commit-Queue: Abe Levkoy <alevkoy@chromium.org>
-rw-r--r-- | board/volet/battery.c | 125 | ||||
-rw-r--r-- | board/volet/board.c | 495 | ||||
-rw-r--r-- | board/volet/board.h | 199 | ||||
-rw-r--r-- | board/volet/build.mk | 17 | ||||
-rw-r--r-- | board/volet/ec.tasklist | 26 | ||||
-rw-r--r-- | board/volet/gpio.inc | 186 | ||||
-rw-r--r-- | board/volet/led.c | 79 | ||||
-rw-r--r-- | board/volet/sensors.c | 266 | ||||
-rw-r--r-- | board/volet/vif_override.xml | 158 |
9 files changed, 1551 insertions, 0 deletions
diff --git a/board/volet/battery.c b/board/volet/battery.c new file mode 100644 index 0000000000..2e4fb7dc71 --- /dev/null +++ b/board/volet/battery.c @@ -0,0 +1,125 @@ +/* Copyright 2021 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. + * + * Battery pack vendor provided charging profile + */ + +#include "battery_fuel_gauge.h" +#include "common.h" +#include "util.h" + +/* + * Battery info for all Volteer battery types. Note that the fields + * start_charging_min/max and charging_min/max are not used for the charger. + * The effective temperature limits are given by discharging_min/max_c. + * + * Fuel Gauge (FG) parameters which are used for determining if the battery + * is connected, the appropriate ship mode (battery cutoff) command, and the + * charge/discharge FETs status. + * + * Ship mode (battery cutoff) requires 2 writes to the appropriate smart battery + * register. For some batteries, the charge/discharge FET bits are set when + * charging/discharging is active, in other types, these bits set mean that + * charging/discharging is disabled. Therefore, in addition to the mask for + * these bits, a disconnect value must be specified. Note that for TI fuel + * gauge, the charge/discharge FET status is found in Operation Status (0x54), + * but a read of Manufacturer Access (0x00) will return the lower 16 bits of + * Operation status which contains the FET status bits. + * + * The assumption for battery types supported is that the charge/discharge FET + * status can be read with a sb_read() command and therefore, only the register + * address, mask, and disconnect value need to be provided. + */ +const struct board_batt_params board_battery_info[] = { + /* AP19B8M */ + [BATTERY_AP19B8M] = { + .fuel_gauge = { + .manuf_name = "LGC KT0030G024", + .ship_mode = { + .reg_addr = 0x3A, + .reg_data = { 0xC574, 0xC574 }, + }, + .fet = { + .reg_addr = 0x43, + .reg_mask = 0x0001, + .disconnect_val = 0x0, + .cfet_mask = 0x0002, + .cfet_off_val = 0x0000, + } + }, + .batt_info = { + .voltage_max = 13350, + .voltage_normal = 11610, + .voltage_min = 9000, + .precharge_current = 256, + .start_charging_min_c = 0, + .start_charging_max_c = 50, + .charging_min_c = 0, + .charging_max_c = 60, + .discharging_min_c = -20, + .discharging_max_c = 75, + }, + }, + /* LGC AP18C8K Battery Information */ + [BATTERY_LGC_AP18C8K] = { + .fuel_gauge = { + .manuf_name = "LGC KT0030G020", + .ship_mode = { + .reg_addr = 0x3A, + .reg_data = { 0xC574, 0xC574 }, + }, + .fet = { + .reg_addr = 0x43, + .reg_mask = 0x0001, + .disconnect_val = 0x0, + .cfet_mask = 0x0002, + .cfet_off_val = 0x0000, + }, + }, + .batt_info = { + .voltage_max = 13050, + .voltage_normal = 11250, + .voltage_min = 9000, + .precharge_current = 256, + .start_charging_min_c = 0, + .start_charging_max_c = 50, + .charging_min_c = 0, + .charging_max_c = 60, + .discharging_min_c = -20, + .discharging_max_c = 75, + }, + }, + /* COSMX AP20CBL Battery Information */ + [BATTERY_COSMX_AP20CBL] = { + .fuel_gauge = { + .manuf_name = "COSMX KT0030B002", + .device_name = "AP20CBL", + .ship_mode = { + .reg_addr = 0x3A, + .reg_data = { 0xC574, 0xC574 }, + }, + .fet = { + .mfgacc_support = 1, + .reg_addr = 0x0, + .reg_mask = 0x2000, + .disconnect_val = 0x2000, + }, + }, + .batt_info = { + .voltage_max = 13200, + .voltage_normal = 11550, + .voltage_min = 9000, + .precharge_current = 256, + .start_charging_min_c = 0, + .start_charging_max_c = 50, + .charging_min_c = 0, + .charging_max_c = 60, + .discharging_min_c = -20, + .discharging_max_c = 75, + }, + }, +}; +BUILD_ASSERT(ARRAY_SIZE(board_battery_info) == BATTERY_TYPE_COUNT); + +const enum battery_type DEFAULT_BATTERY_TYPE = BATTERY_AP19B8M; diff --git a/board/volet/board.c b/board/volet/board.c new file mode 100644 index 0000000000..d366e25eca --- /dev/null +++ b/board/volet/board.c @@ -0,0 +1,495 @@ +/* Copyright 2021 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. + */ + +/* Volteer board-specific configuration */ +#include "bb_retimer.h" +#include "button.h" +#include "common.h" +#include "accelgyro.h" +#include "cbi_ec_fw_config.h" +#include "driver/accel_bma2x2.h" +#include "driver/accelgyro_bmi160.h" +#include "driver/als_tcs3400.h" +#include "driver/bc12/pi3usb9201.h" +#include "driver/ppc/syv682x.h" +#include "driver/tcpm/tcpci.h" +#include "driver/tcpm/tusb422.h" +#include "driver/tcpm/rt1715.h" +#include "driver/retimer/bb_retimer.h" +#include "driver/sync.h" +#include "extpower.h" +#include "fan.h" +#include "fan_chip.h" +#include "gpio.h" +#include "hooks.h" +#include "keyboard_scan.h" +#include "lid_switch.h" +#include "power.h" +#include "power_button.h" +#include "pwm.h" +#include "pwm_chip.h" +#include "switch.h" +#include "system.h" +#include "task.h" +#include "tablet_mode.h" +#include "throttle_ap.h" +#include "uart.h" +#include "usb_mux.h" +#include "usb_pd.h" +#include "usb_pd_tbt.h" +#include "usb_pd_tcpm.h" +#include "usbc_ppc.h" +#include "util.h" + +#include "gpio_list.h" /* Must come after other header files. */ + +#define CPRINTS(format, args...) cprints(CC_CHIPSET, format, ## args) + +static const struct ec_response_keybd_config zbu_new_kb = { + .num_top_row_keys = 10, + .action_keys = { + TK_BACK, + TK_REFRESH, + TK_FULLSCREEN, + TK_OVERVIEW, + TK_SNAPSHOT, + TK_BRIGHTNESS_DOWN, + TK_BRIGHTNESS_UP, + TK_VOL_MUTE, + TK_VOL_DOWN, + TK_VOL_UP, + }, + .capabilities = KEYBD_CAP_SCRNLOCK_KEY, +}; + +static const struct ec_response_keybd_config zbu_old_kb = { + .num_top_row_keys = 10, + .action_keys = { + TK_BACK, /* T1 */ + TK_FORWARD, /* T2 */ + TK_REFRESH, /* T3 */ + TK_FULLSCREEN, /* T4 */ + TK_OVERVIEW, /* T5 */ + TK_BRIGHTNESS_DOWN, /* T6 */ + TK_BRIGHTNESS_UP, /* T7 */ + TK_VOL_MUTE, /* T8 */ + TK_VOL_DOWN, /* T9 */ + TK_VOL_UP, /* T10 */ + }, + .capabilities = KEYBD_CAP_SCRNLOCK_KEY, +}; + +__override +const struct ec_response_keybd_config *board_vivaldi_keybd_config(void) +{ + if (get_board_id() > 2) + return &zbu_new_kb; + else + return &zbu_old_kb; +} + +/* Keyboard scan setting */ +struct keyboard_scan_config keyscan_config = { + /* Increase from 50 us, because KSO_02 passes through the H1. */ + .output_settle_us = 80, + /* Other values should be the same as the default configuration. */ + .debounce_down_us = 9 * MSEC, + .debounce_up_us = 30 * MSEC, + .scan_period_us = 3 * MSEC, + .min_post_scan_delay_us = 1000, + .poll_timeout_us = 100 * MSEC, + .actual_key_mask = { + 0x14, 0xff, 0xff, 0xff, 0xff, 0xf5, 0xff, + 0xa4, 0xff, 0xfe, 0x55, 0xfa, 0xca /* full set */ + }, +}; + +__override uint32_t board_override_feature_flags0(uint32_t flags0) +{ + /* + * Remove keyboard backlight feature for devices that don't support it. + */ + if (!ec_cfg_has_keyboard_backlight()) + return (flags0 & ~EC_FEATURE_MASK_0(EC_FEATURE_PWM_KEYB)); + else + return flags0; +} + +/******************************************************************************/ +/* + * FW_CONFIG defaults for Voxel if the CBI data is not initialized. + */ +union volteer_cbi_fw_config fw_config_defaults = { + .usb_db = DB_USB4_GEN3, +}; + +/******************************************************************************/ +/* Physical fans. These are logically separate from pwm_channels. */ + +const struct fan_conf fan_conf_0 = { + .flags = FAN_USE_RPM_MODE, + .ch = MFT_CH_0, /* Use MFT id to control fan */ + .pgood_gpio = -1, + .enable_gpio = GPIO_EN_PP5000_FAN, +}; + +/* + * Fan specs from datasheet: + * Max speed 5900 rpm (+/- 7%), minimum duty cycle 30%. + * Minimum speed not specified by RPM. Set minimum RPM to max speed (with + * margin) x 30%. + * 5900 x 1.07 x 0.30 = 1894, round up to 1900 + * reference that temperature and fan settings + * are derived from data in b/167523658#39 + */ +const struct fan_rpm fan_rpm_0 = { + .rpm_min = 2100, + .rpm_start = 2100, + .rpm_max = 5800, +}; + +const struct fan_t fans[FAN_CH_COUNT] = { + [FAN_CH_0] = { + .conf = &fan_conf_0, + .rpm = &fan_rpm_0, + }, +}; + +/******************************************************************************/ +/* EC thermal management configuration */ + +/* + * Reference that temperature and fan settings + * are derived from data in b/167523658#39 + */ +const static struct ec_thermal_config thermal_cpu = { + .temp_host = { + [EC_TEMP_THRESH_HIGH] = C_TO_K(75), + [EC_TEMP_THRESH_HALT] = C_TO_K(85), + }, + .temp_host_release = { + [EC_TEMP_THRESH_HIGH] = C_TO_K(68), + }, + .temp_fan_off = C_TO_K(25), + .temp_fan_max = C_TO_K(90), +}; + +struct ec_thermal_config thermal_params[] = { + [TEMP_SENSOR_1_CHARGER] = thermal_cpu, + [TEMP_SENSOR_2_PP3300_REGULATOR] = thermal_cpu, + [TEMP_SENSOR_3_DDR_SOC] = thermal_cpu, + [TEMP_SENSOR_4_FAN] = thermal_cpu, +}; +BUILD_ASSERT(ARRAY_SIZE(thermal_params) == TEMP_SENSOR_COUNT); + +/******************************************************************************/ +/* MFT channels. These are logically separate from pwm_channels. */ +const struct mft_t mft_channels[] = { + [MFT_CH_0] = { + .module = NPCX_MFT_MODULE_1, + .clk_src = TCKC_LFCLK, + .pwm_id = PWM_CH_FAN, + }, +}; +BUILD_ASSERT(ARRAY_SIZE(mft_channels) == MFT_CH_COUNT); + +/******************************************************************************/ +/* I2C port map configuration */ +const struct i2c_port_t i2c_ports[] = { + { + .name = "sensor", + .port = I2C_PORT_SENSOR, + .kbps = 400, + .scl = GPIO_EC_I2C0_SENSOR_SCL, + .sda = GPIO_EC_I2C0_SENSOR_SDA, + }, + { + .name = "usb_c0", + .port = I2C_PORT_USB_C0, + .kbps = 1000, + .scl = GPIO_EC_I2C1_USB_C0_SCL, + .sda = GPIO_EC_I2C1_USB_C0_SDA, + }, + { + .name = "usb_c1", + .port = I2C_PORT_USB_C1, + .kbps = 1000, + .scl = GPIO_EC_I2C2_USB_C1_SCL, + .sda = GPIO_EC_I2C2_USB_C1_SDA, + }, + { + .name = "usb_0_mix", + .port = I2C_PORT_USB_0_MIX, + .kbps = 100, + .scl = GPIO_EC_I2C3_USB_1_MIX_SCL, + .sda = GPIO_EC_I2C3_USB_1_MIX_SDA, + }, + { + .name = "usb_1_mix", + .port = I2C_PORT_USB_1_MIX, + .kbps = 100, + .scl = GPIO_EC_I2C4_USB_1_MIX_SCL, + .sda = GPIO_EC_I2C4_USB_1_MIX_SDA, + }, + { + .name = "power", + .port = I2C_PORT_POWER, + .kbps = 100, + .scl = GPIO_EC_I2C5_POWER_SCL, + .sda = GPIO_EC_I2C5_POWER_SDA, + }, + { + .name = "eeprom", + .port = I2C_PORT_EEPROM, + .kbps = 400, + .scl = GPIO_EC_I2C7_EEPROM_SCL, + .sda = GPIO_EC_I2C7_EEPROM_SDA, + }, +}; +const unsigned int i2c_ports_used = ARRAY_SIZE(i2c_ports); + +/******************************************************************************/ +/* PWM configuration */ +const struct pwm_t pwm_channels[] = { + [PWM_CH_FAN] = { + .channel = 5, + .flags = PWM_CONFIG_OPEN_DRAIN, + .freq = 25000 + }, + [PWM_CH_KBLIGHT] = { + .channel = 3, + .flags = 0, + /* + * Set PWM frequency to multiple of 50 Hz and 60 Hz to prevent + * flicker. Higher frequencies consume similar average power to + * lower PWM frequencies, but higher frequencies record a much + * lower maximum power. + */ + .freq = 2400, + }, +}; +BUILD_ASSERT(ARRAY_SIZE(pwm_channels) == PWM_CH_COUNT); + +static void kb_backlight_enable(void) +{ + if (ec_cfg_has_keyboard_backlight()) + gpio_set_level(GPIO_EC_KB_BL_EN, 1); +} +DECLARE_HOOK(HOOK_CHIPSET_RESUME, kb_backlight_enable, HOOK_PRIO_DEFAULT); + +static void kb_backlight_disable(void) +{ + if (ec_cfg_has_keyboard_backlight()) + gpio_set_level(GPIO_EC_KB_BL_EN, 0); +} +DECLARE_HOOK(HOOK_CHIPSET_SUSPEND, kb_backlight_disable, HOOK_PRIO_DEFAULT); + +/* Config TCPC dynamic by Board version */ +static void setup_board_tcpc(void) +{ + uint8_t board_id = get_board_id(); + + if (board_id == 0) { + /* config typec C0 prot TUSB422 TCPC */ + tcpc_config[USBC_PORT_C0].i2c_info.addr_flags + = TUSB422_I2C_ADDR_FLAGS; + tcpc_config[USBC_PORT_C0].drv = &tusb422_tcpm_drv; + /* config typec C1 prot TUSB422 TCPC */ + tcpc_config[USBC_PORT_C1].i2c_info.addr_flags + = TUSB422_I2C_ADDR_FLAGS; + tcpc_config[USBC_PORT_C1].drv = &tusb422_tcpm_drv; + } +} + +void board_reset_pd_mcu(void) +{ + /* + * Only the Burnside Bridge retimers provide a reset pin, but this is + * already handled by the bb_retimer.c driver. + */ +} + +/******************************************************************************/ +/* USB-A charging control */ + +const int usb_port_enable[USB_PORT_COUNT] = { + GPIO_EN_PP5000_USBA, +}; + +/******************************************************************************/ +/* USBC PPC configuration */ +struct ppc_config_t ppc_chips[] = { + [USBC_PORT_C0] = { + .i2c_port = I2C_PORT_USB_C0, + .i2c_addr_flags = SYV682X_ADDR0_FLAGS, + .drv = &syv682x_drv, + .frs_en = GPIO_USB_C0_FRS_EN, + }, + [USBC_PORT_C1] = { + .i2c_port = I2C_PORT_USB_C1, + .i2c_addr_flags = SYV682X_ADDR0_FLAGS, + .drv = &syv682x_drv, + .frs_en = GPIO_USB_C1_FRS_EN, + }, +}; +BUILD_ASSERT(ARRAY_SIZE(ppc_chips) == USBC_PORT_COUNT); +unsigned int ppc_cnt = ARRAY_SIZE(ppc_chips); + +/******************************************************************************/ +/* PPC support routines */ +void ppc_interrupt(enum gpio_signal signal) +{ + switch (signal) { + case GPIO_USB_C0_PPC_INT_ODL: + syv682x_interrupt(USBC_PORT_C0); + break; + case GPIO_USB_C1_PPC_INT_ODL: + syv682x_interrupt(USBC_PORT_C1); + default: + break; + } +} + +/* Disable FRS on boards with the SYV682A. FRS only works on the SYV682B. */ +void setup_board_ppc(void) +{ + uint8_t board_id = get_board_id(); + + if (board_id < 2) { + ppc_chips[USBC_PORT_C0].frs_en = 0; + ppc_chips[USBC_PORT_C1].frs_en = 0; + } +} + +__override void board_cbi_init(void) +{ + setup_board_tcpc(); + setup_board_ppc(); +} + +/******************************************************************************/ +/* BC1.2 charger detect configuration */ +const struct pi3usb9201_config_t pi3usb9201_bc12_chips[] = { + [USBC_PORT_C0] = { + .i2c_port = I2C_PORT_USB_C0, + .i2c_addr_flags = PI3USB9201_I2C_ADDR_3_FLAGS, + }, + [USBC_PORT_C1] = { + .i2c_port = I2C_PORT_USB_C1, + .i2c_addr_flags = PI3USB9201_I2C_ADDR_3_FLAGS, + }, +}; +BUILD_ASSERT(ARRAY_SIZE(pi3usb9201_bc12_chips) == USBC_PORT_COUNT); + +/******************************************************************************/ +/* USBC TCPC configuration */ +struct tcpc_config_t tcpc_config[] = { + [USBC_PORT_C0] = { + .bus_type = EC_BUS_TYPE_I2C, + .i2c_info = { + .port = I2C_PORT_USB_C0, + .addr_flags = RT1715_I2C_ADDR_FLAGS, + }, + .drv = &rt1715_tcpm_drv, + }, + [USBC_PORT_C1] = { + .bus_type = EC_BUS_TYPE_I2C, + .i2c_info = { + .port = I2C_PORT_USB_C1, + .addr_flags = RT1715_I2C_ADDR_FLAGS, + }, + .drv = &rt1715_tcpm_drv, + }, +}; +BUILD_ASSERT(ARRAY_SIZE(tcpc_config) == USBC_PORT_COUNT); +BUILD_ASSERT(CONFIG_USB_PD_PORT_MAX_COUNT == USBC_PORT_COUNT); + +/******************************************************************************/ +/* USBC mux configuration - Tiger Lake includes internal mux */ +struct usb_mux usbc0_tcss_usb_mux = { + .usb_port = USBC_PORT_C0, + .driver = &virtual_usb_mux_driver, + .hpd_update = &virtual_hpd_update, +}; +struct usb_mux usbc1_tcss_usb_mux = { + .usb_port = USBC_PORT_C1, + .driver = &virtual_usb_mux_driver, + .hpd_update = &virtual_hpd_update, +}; + +struct usb_mux usb_muxes[] = { + [USBC_PORT_C0] = { + .usb_port = USBC_PORT_C0, + .next_mux = &usbc0_tcss_usb_mux, + .driver = &bb_usb_retimer, + .i2c_port = I2C_PORT_USB_0_MIX, + .i2c_addr_flags = USBC_PORT_C0_BB_RETIMER_I2C_ADDR, + }, + [USBC_PORT_C1] = { + .usb_port = USBC_PORT_C1, + .next_mux = &usbc1_tcss_usb_mux, + .driver = &bb_usb_retimer, + .i2c_port = I2C_PORT_USB_1_MIX, + .i2c_addr_flags = USBC_PORT_C1_BB_RETIMER_I2C_ADDR, + }, +}; +BUILD_ASSERT(ARRAY_SIZE(usb_muxes) == USBC_PORT_COUNT); + +struct bb_usb_control bb_controls[] = { + [USBC_PORT_C0] = { + .usb_ls_en_gpio = GPIO_USB_C0_LS_EN, + .retimer_rst_gpio = GPIO_USB_C0_RT_RST_ODL, + }, + [USBC_PORT_C1] = { + .usb_ls_en_gpio = GPIO_USB_C1_LS_EN, + .retimer_rst_gpio = GPIO_USB_C1_RT_RST_ODL, + }, +}; +BUILD_ASSERT(ARRAY_SIZE(bb_controls) == USBC_PORT_COUNT); + +static void board_tcpc_init(void) +{ + /* Don't reset TCPCs after initial reset */ + if (!system_jumped_late()) + board_reset_pd_mcu(); + + /* Enable PPC interrupts. */ + gpio_enable_interrupt(GPIO_USB_C0_PPC_INT_ODL); + gpio_enable_interrupt(GPIO_USB_C1_PPC_INT_ODL); + + /* Enable TCPC interrupts. */ + gpio_enable_interrupt(GPIO_USB_C0_TCPC_INT_ODL); + gpio_enable_interrupt(GPIO_USB_C1_TCPC_INT_ODL); + + /* Enable BC1.2 interrupts. */ + gpio_enable_interrupt(GPIO_USB_C0_BC12_INT_ODL); + gpio_enable_interrupt(GPIO_USB_C1_BC12_INT_ODL); +} +DECLARE_HOOK(HOOK_INIT, board_tcpc_init, HOOK_PRIO_INIT_CHIPSET); + +/******************************************************************************/ +/* TCPC support routines */ +uint16_t tcpc_get_alert_status(void) +{ + uint16_t status = 0; + + /* + * Check which port has the ALERT line set + */ + if (!gpio_get_level(GPIO_USB_C0_TCPC_INT_ODL)) + status |= PD_STATUS_TCPC_ALERT_0; + if (!gpio_get_level(GPIO_USB_C1_TCPC_INT_ODL)) + status |= PD_STATUS_TCPC_ALERT_1; + + return status; +} + +int ppc_get_alert_status(int port) +{ + if (port == USBC_PORT_C0) + return gpio_get_level(GPIO_USB_C0_PPC_INT_ODL) == 0; + else + return gpio_get_level(GPIO_USB_C1_PPC_INT_ODL) == 0; +} diff --git a/board/volet/board.h b/board/volet/board.h new file mode 100644 index 0000000000..6793f4ae9f --- /dev/null +++ b/board/volet/board.h @@ -0,0 +1,199 @@ +/* Copyright 2021 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. + */ + +/* Volteer board configuration */ + +#ifndef __CROS_EC_BOARD_H +#define __CROS_EC_BOARD_H + +/* Baseboard features */ +#include "baseboard.h" + +/* Optional features */ +#undef NPCX7_PWM1_SEL +#define NPCX7_PWM1_SEL 0 /* GPIO C2 is not used as PWM1. */ + +/* + * The RAM and flash size combination on the the NPCX797FC does not leave + * any unused flash space that can be used to store the .init_rom section. + */ +#undef CONFIG_CHIP_INIT_ROM_REGION + +#define CONFIG_VBOOT_EFS2 + +#define CONFIG_POWER_BUTTON + +#undef CONFIG_UART_TX_BUF_SIZE +#define CONFIG_UART_TX_BUF_SIZE 4096 + +/* Chipset features */ +#define CONFIG_POWER_PP5000_CONTROL + +/* LED defines */ +#define CONFIG_LED_ONOFF_STATES + +/* Keyboard features */ +#define CONFIG_KEYBOARD_REFRESH_ROW3 + +/* Keyboard backliht */ +#define CONFIG_PWM +#define CONFIG_PWM_KBLIGHT + +/* Sensors */ +#define CONFIG_DYNAMIC_MOTION_SENSOR_COUNT +/* BMI160 Base accel/gyro */ +#define CONFIG_ACCELGYRO_BMI160 +#define CONFIG_ACCELGYRO_ICM426XX /* Base accel second source*/ +#define CONFIG_ACCELGYRO_BMI160_INT_EVENT \ + TASK_EVENT_MOTION_SENSOR_INTERRUPT(BASE_ACCEL) +#define CONFIG_ACCELGYRO_ICM426XX_INT_EVENT \ + TASK_EVENT_MOTION_SENSOR_INTERRUPT(BASE_ACCEL) + +/* Lid operates in forced mode, base in FIFO */ +#define CONFIG_ACCEL_FORCE_MODE_MASK BIT(LID_ACCEL) + +/* BMA253 Lid accel */ +#define CONFIG_ACCEL_KX022 /* Lid accel */ +#define CONFIG_ACCEL_BMA255 +#define CONFIG_LID_ANGLE +#define CONFIG_LID_ANGLE_UPDATE +#define CONFIG_LID_ANGLE_SENSOR_BASE BASE_ACCEL +#define CONFIG_LID_ANGLE_SENSOR_LID LID_ACCEL + +/* USB Type C and USB PD defines */ +#define CONFIG_USB_PD_PORT_MAX_COUNT 2 + +#define PD_POWER_SUPPLY_TURN_ON_DELAY 30000 /* us */ +#define PD_POWER_SUPPLY_TURN_OFF_DELAY 30000 /* us */ + +/* + * SN5S30 PPC supports up to 24V VBUS source and sink, however passive USB-C + * cables only support up to 60W. + */ +#define PD_OPERATING_POWER_MW 15000 +#define PD_MAX_POWER_MW 60000 +#define PD_MAX_CURRENT_MA 3000 +#define PD_MAX_VOLTAGE_MV 20000 + +#define CONFIG_USB_PD_REQUIRE_AP_MODE_ENTRY +#ifdef BOARD_VOXEL_ECMODEENTRY +#undef CONFIG_USB_PD_REQUIRE_AP_MODE_ENTRY +#endif + +/* Enabling Thunderbolt-compatible mode */ +#define CONFIG_USB_PD_TBT_COMPAT_MODE + +/* Enabling USB4 mode */ +#define CONFIG_USB_PD_USB4 +#define USBC_PORT_C0_BB_RETIMER_I2C_ADDR 0x40 +#define USBC_PORT_C1_BB_RETIMER_I2C_ADDR 0x41 + +/* USB Type A Features */ +#define USB_PORT_COUNT 1 +#define CONFIG_USB_PORT_POWER_DUMB + +/* USBC PPC*/ +#define CONFIG_USBC_PPC_SYV682X /* USBC port C0/C1 */ +#define CONFIG_USB_PD_FRS_PPC + +/* BC 1.2 */ + +/* TCPC */ +#define CONFIG_USB_PD_TCPM_RT1715 + +/* Volume Button feature */ + +/* Fan features */ + +/* charger defines */ +#define CONFIG_CHARGER_SENSE_RESISTOR 10 +#define CONFIG_CHARGER_SENSE_RESISTOR_AC 10 + +/* + * Macros for GPIO signals used in common code that don't match the + * schematic names. Signal names in gpio.inc match the schematic and are + * then redefined here to so it's more clear which signal is being used for + * which purpose. + */ +#define GPIO_AC_PRESENT GPIO_ACOK_OD +#define GPIO_EC_INT_L GPIO_EC_PCH_INT_ODL +#define GPIO_EN_PP5000 GPIO_EN_PP5000_A +#define GPIO_ENTERING_RW GPIO_EC_ENTERING_RW +#define GPIO_LID_OPEN GPIO_EC_LID_OPEN +#define GPIO_KBD_KSO2 GPIO_EC_KSO_02_INV +#define GPIO_PACKET_MODE_EN GPIO_EC_H1_PACKET_MODE +#define GPIO_PCH_WAKE_L GPIO_EC_PCH_WAKE_ODL +#define GPIO_PCH_PWRBTN_L GPIO_EC_PCH_PWR_BTN_ODL +#define GPIO_PCH_RSMRST_L GPIO_EC_PCH_RSMRST_ODL +#define GPIO_PCH_RTCRST GPIO_EC_PCH_RTCRST +#define GPIO_PCH_SLP_S0_L GPIO_SLP_S0_L +#define GPIO_PCH_SLP_S3_L GPIO_SLP_S3_L +#define GPIO_PCH_DSW_PWROK GPIO_EC_PCH_DSW_PWROK +#define GPIO_POWER_BUTTON_L GPIO_H1_EC_PWR_BTN_ODL +#define GPIO_RSMRST_L_PGOOD GPIO_PG_EC_RSMRST_ODL +#define GPIO_CPU_PROCHOT GPIO_EC_PROCHOT_ODL +#define GPIO_SYS_RESET_L GPIO_SYS_RST_ODL +#define GPIO_WP_L GPIO_EC_WP_L +#define GPIO_USB_C1_BC12_INT_ODL GPIO_USB_C1_MIX_INT_ODL +#define GPIO_VOLUME_UP_L GPIO_EC_VOLUP_BTN_ODL +#define GPIO_VOLUME_DOWN_L GPIO_EC_VOLDN_BTN_ODL +#define GMR_TABLET_MODE_GPIO_L GPIO_TABLET_MODE_L + +/* I2C Bus Configuration */ +#define CONFIG_I2C +#define I2C_PORT_ACCEL I2C_PORT_SENSOR +#define I2C_PORT_SENSOR NPCX_I2C_PORT0_0 +#define I2C_PORT_USB_C0 NPCX_I2C_PORT1_0 +#define I2C_PORT_USB_C1 NPCX_I2C_PORT2_0 +#define I2C_PORT_USB_0_MIX NPCX_I2C_PORT3_0 +#define I2C_PORT_USB_1_MIX NPCX_I2C_PORT4_1 +#define I2C_PORT_POWER NPCX_I2C_PORT5_0 +#define I2C_PORT_EEPROM NPCX_I2C_PORT7_0 + +#define I2C_PORT_BATTERY I2C_PORT_POWER +#define I2C_PORT_CHARGER I2C_PORT_EEPROM + +#define I2C_ADDR_EEPROM_FLAGS 0x50 +#define CONFIG_I2C_CONTROLLER + + +#ifndef __ASSEMBLER__ + +#include "gpio_signal.h" +#include "registers.h" + +enum battery_type { + BATTERY_AP19B8M, + BATTERY_LGC_AP18C8K, + BATTERY_COSMX_AP20CBL, + BATTERY_TYPE_COUNT, +}; + +enum pwm_channel { + PWM_CH_FAN, + PWM_CH_KBLIGHT, + PWM_CH_COUNT +}; + +enum sensor_id { + LID_ACCEL = 0, + BASE_ACCEL, + BASE_GYRO, + SENSOR_COUNT, +}; + +enum usbc_port { + USBC_PORT_C0 = 0, + USBC_PORT_C1, + USBC_PORT_COUNT +}; + +void board_reset_pd_mcu(void); + +void motion_interrupt(enum gpio_signal signal); + +#endif /* !__ASSEMBLER__ */ + +#endif /* __CROS_EC_BOARD_H */ diff --git a/board/volet/build.mk b/board/volet/build.mk new file mode 100644 index 0000000000..546bcba8d2 --- /dev/null +++ b/board/volet/build.mk @@ -0,0 +1,17 @@ +# -*- makefile -*- +# Copyright 2021 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 +# + +CHIP:=npcx +CHIP_FAMILY:=npcx7 +CHIP_VARIANT:=npcx7m7fc +BASEBOARD:=volteer + +board-y=board.o +board-y+=battery.o +board-y+=led.o +board-y+=sensors.o diff --git a/board/volet/ec.tasklist b/board/volet/ec.tasklist new file mode 100644 index 0000000000..e76bd368eb --- /dev/null +++ b/board/volet/ec.tasklist @@ -0,0 +1,26 @@ +/* Copyright 2021 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, LARGER_TASK_STACK_SIZE) \ + TASK_ALWAYS(CHG_RAMP, chg_ramp_task, NULL, TASK_STACK_SIZE) \ + TASK_ALWAYS(USB_CHG_P0, usb_charger_task, 0, TASK_STACK_SIZE) \ + TASK_ALWAYS(USB_CHG_P1, usb_charger_task, 0, TASK_STACK_SIZE) \ + TASK_ALWAYS(CHARGER, charger_task, NULL, VENTI_TASK_STACK_SIZE) \ + TASK_ALWAYS(MOTIONSENSE, motion_sense_task, NULL, VENTI_TASK_STACK_SIZE) \ + TASK_NOTEST(KEYPROTO, keyboard_protocol_task, NULL, TASK_STACK_SIZE) \ + TASK_NOTEST(CHIPSET, chipset_task, NULL, LARGER_TASK_STACK_SIZE) \ + TASK_ALWAYS(HOSTCMD, host_command_task, NULL, LARGER_TASK_STACK_SIZE) \ + TASK_ALWAYS(CONSOLE, console_task, NULL, VENTI_TASK_STACK_SIZE) \ + TASK_ALWAYS(POWERBTN, power_button_task, NULL, LARGER_TASK_STACK_SIZE) \ + TASK_NOTEST(KEYSCAN, keyboard_scan_task, NULL, TASK_STACK_SIZE) \ + TASK_ALWAYS(PD_C0, pd_task, NULL, VENTI_TASK_STACK_SIZE) \ + TASK_ALWAYS(PD_C1, pd_task, NULL, VENTI_TASK_STACK_SIZE) \ + TASK_ALWAYS(PD_INT_C0, pd_interrupt_handler_task, 0, TASK_STACK_SIZE) \ + TASK_ALWAYS(PD_INT_C1, pd_interrupt_handler_task, 1, TASK_STACK_SIZE) diff --git a/board/volet/gpio.inc b/board/volet/gpio.inc new file mode 100644 index 0000000000..0b5d462b61 --- /dev/null +++ b/board/volet/gpio.inc @@ -0,0 +1,186 @@ +/* -*- mode:c -*- + * + * Copyright 2021 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. */ + +/* Wake Source interrupts */ +GPIO_INT(EC_LID_OPEN, PIN(D, 2), GPIO_INT_BOTH | GPIO_HIB_WAKE_HIGH, lid_interrupt) +GPIO_INT(EC_WP_L, PIN(A, 1), GPIO_INT_BOTH, switch_interrupt) +GPIO_INT(H1_EC_PWR_BTN_ODL, PIN(0, 1), GPIO_INT_BOTH, power_button_interrupt) +GPIO_INT(ACOK_OD, PIN(0, 0), GPIO_INT_BOTH | GPIO_HIB_WAKE_HIGH, extpower_interrupt) + +/* Power sequencing interrupts */ +GPIO_INT(SLP_S0_L, PIN(D, 5), GPIO_INT_BOTH, power_signal_interrupt) +#ifndef CONFIG_HOSTCMD_ESPI_VW_SLP_S3 +GPIO_INT(SLP_S3_L, PIN(A, 5), GPIO_INT_BOTH, power_signal_interrupt) +#endif +GPIO_INT(SLP_SUS_L, PIN(D, 7), GPIO_INT_BOTH, power_signal_interrupt) +GPIO_INT(PG_EC_RSMRST_ODL, PIN(E, 2), GPIO_INT_BOTH, power_signal_interrupt) +GPIO_INT(PG_EC_DSW_PWROK, PIN(C, 7), GPIO_INT_BOTH, power_signal_interrupt) +GPIO_INT(PG_EC_ALL_SYS_PWRGD, PIN(F, 4), GPIO_INT_BOTH, power_signal_interrupt) + +/* Sensor Interrupts */ +GPIO_INT(EC_IMU_INT_L, PIN(5, 6), GPIO_INT_FALLING | GPIO_SEL_1P8V, motion_interrupt) +GPIO(EC_ALS_RGB_INT_L, PIN(D, 4), GPIO_INPUT | GPIO_PULL_UP) /* unused */ +GPIO_INT(TABLET_MODE_L, PIN(9, 5), GPIO_INT_BOTH, gmr_tablet_switch_isr) +/* + * Lid g-sensor interrupt unused on Voxel, configure as regular input for + * power saving. + */ +GPIO(EC_ACCEL_INT, PIN(8, 1), GPIO_INPUT | GPIO_PULL_UP) + +/* USB-C interrupts */ +GPIO_INT(USB_C0_TCPC_INT_ODL, PIN(E, 0), GPIO_INT_BOTH, tcpc_alert_event) +GPIO_INT(USB_C1_TCPC_INT_ODL, PIN(A, 2), GPIO_INT_BOTH, tcpc_alert_event) + +GPIO_INT(USB_C0_PPC_INT_ODL, PIN(6, 2), GPIO_INT_BOTH, ppc_interrupt) +GPIO_INT(USB_C1_PPC_INT_ODL, PIN(F, 5), GPIO_INT_BOTH, ppc_interrupt) + +GPIO_INT(USB_C0_BC12_INT_ODL, PIN(E, 4), GPIO_INT_BOTH, bc12_interrupt) +GPIO_INT(USB_C1_MIX_INT_ODL, PIN(0, 3), GPIO_INT_BOTH, bc12_interrupt) + +/* HDMI interrupts */ + +/* Volume button interrupts */ +GPIO_INT(EC_VOLDN_BTN_ODL, PIN(9, 3), GPIO_INT_BOTH | GPIO_PULL_UP, button_interrupt) +GPIO_INT(EC_VOLUP_BTN_ODL, PIN(9, 7), GPIO_INT_BOTH | GPIO_PULL_UP, button_interrupt) + +/* Power Sequencing Signals */ +GPIO(EN_PP3300_A, PIN(A, 3), GPIO_OUT_LOW) +GPIO(EN_PP5000_A, PIN(A, 4), GPIO_OUT_LOW) +GPIO(EN_PPVAR_VCCIN, PIN(4, 3), GPIO_OUT_LOW) /* Enables VCCIN IMPV9 */ +GPIO(EC_PCH_DSW_PWROK, PIN(C, 0), GPIO_OUT_LOW) + +/* Other wake sources */ +/* + * GPIO_INT_BOTH is required for PSL wake from hibernate, but we don't need an + * interrupt handler because it is automatically handled by the PSL. + * + * We need to lock the setting so this gpio can't be reconfigured to overdrive + * the real reset signal. (This is the PSL input pin not the real reset pin). + */ +GPIO(EC_RST_ODL, PIN(0, 2), GPIO_INT_BOTH | + GPIO_HIB_WAKE_HIGH | + GPIO_LOCKED) + +/* AP/PCH Signals */ +GPIO(EC_PCH_SYS_PWROK, PIN(3, 7), GPIO_OUT_LOW) +GPIO(EC_PCH_RSMRST_ODL, PIN(A, 6), GPIO_ODR_LOW) /* TODO - b/140950085 - implement TGL sequencing requirement */ +GPIO(EC_PCH_PWR_BTN_ODL, PIN(C, 1), GPIO_ODR_HIGH) +GPIO(EC_PCH_RTCRST, PIN(7, 6), GPIO_OUT_LOW) +GPIO(EC_PCH_WAKE_ODL, PIN(7, 4), GPIO_ODR_HIGH) +GPIO(EC_ENTERING_RW, PIN(E, 3), GPIO_OUT_LOW) +GPIO(EC_PROCHOT_ODL, PIN(6, 3), GPIO_ODR_HIGH) +GPIO_INT(EC_PROCHOT_IN_L, PIN(F, 0), GPIO_INT_BOTH, throttle_ap_prochot_input_interrupt) +GPIO(SYS_RST_ODL, PIN(C, 5), GPIO_ODR_HIGH) + +GPIO(EC_PCH_INT_ODL, PIN(B, 0), GPIO_ODR_HIGH) +GPIO(CPU_C10_GATE_L, PIN(6, 7), GPIO_INPUT) + +/* USB and USBC Signals */ +GPIO(EN_PP5000_USBA, PIN(3, 5), GPIO_OUT_LOW) /* Enable USB-A charging - all ports */ +GPIO(USB_A_LOW_PWR_OD, PIN(6, 6), GPIO_ODR_LOW) /* Don't limit USB-A charging by default - all ports */ + +/* + * USB_C1 moved from GPIO32 to GPIO83 on boards with board ID >=1. + * GPIO83/EN_PP1800_A is DNS on board ID 0 and GPIO32 is N/C on board ID >=1 + * so it's safe to define GPIOs compatible with both designs. + * TODO (b/149858568): remove board ID=0 support. + */ +GPIO(USB_C0_RT_RST_ODL, PIN(4, 1), GPIO_ODR_LOW) +GPIO(USB_C1_RT_RST_ODL, PIN(8, 3), GPIO_ODR_LOW) /* USB_C1 Reset on boards board ID >=1 */ +GPIO(USB_C0_OC_ODL, PIN(B, 1), GPIO_ODR_HIGH) +GPIO(USB_C1_OC_ODL, PIN(5, 0), GPIO_ODR_HIGH) +GPIO(USB_C0_RT_INT_ODL, PIN(C, 6), GPIO_INPUT) +GPIO(USB_C1_RT_INT_ODL, PIN(9, 6), GPIO_INPUT) +GPIO(USB_C0_FRS_EN, PIN(C, 2), GPIO_OUT_LOW) +GPIO(USB_C1_FRS_EN, PIN(9, 4), GPIO_OUT_LOW) + +/* Don't have a load switch for retimer */ +UNIMPLEMENTED(USB_C0_LS_EN) +UNIMPLEMENTED(USB_C1_LS_EN) + +/* Misc Signals */ +GPIO(EC_H1_PACKET_MODE, PIN(7, 5), GPIO_OUT_LOW) /* H1 Packet Mode */ +GPIO(LED_1_L, PIN(C, 4), GPIO_OUT_HIGH) /* Blue */ +GPIO(LED_2_L, PIN(C, 3), GPIO_OUT_HIGH) /* Yellow */ +GPIO(EC_KB_BL_EN, PIN(8, 6), GPIO_OUT_LOW) /* Keyboard backlight enable*/ + +GPIO(M2_SSD_PLN, PIN(A, 0), GPIO_ODR_HIGH) /* SSD power-loss notification */ +GPIO(M2_SSD_PLA, PIN(7, 0), GPIO_INPUT) /* SSD power-loss acknowledgment */ +GPIO(CCD_MODE_ODL, PIN(E, 5), GPIO_INPUT) /* Case Closed Debug Mode */ +GPIO(EC_SLP_S0IX, PIN(7, 2), GPIO_INPUT | GPIO_PULL_UP) + +/* Unused signals */ +GPIO(UNUSED_GPIO34, PIN(3, 4), GPIO_INPUT | GPIO_PULL_UP) +GPIO(UNUSED_GPIO60, PIN(6, 0), GPIO_INPUT | GPIO_PULL_UP) +GPIO(UNUSED_GPIOA7, PIN(A, 7), GPIO_INPUT | GPIO_PULL_UP) + +/* + * eDP backlight - both PCH and EC have enable pins that must be high + * for the backlight to turn on. Default state is high, and can be turned + * off during sleep states. + */ +GPIO(EC_EDP_BL_EN, PIN(D, 3), GPIO_OUT_HIGH) + +/* I2C pins - Alternate function below configures I2C module on these pins */ +GPIO(EC_I2C0_SENSOR_SCL, PIN(B, 5), GPIO_INPUT | GPIO_SEL_1P8V) +GPIO(EC_I2C0_SENSOR_SDA, PIN(B, 4), GPIO_INPUT | GPIO_SEL_1P8V) +GPIO(EC_I2C1_USB_C0_SCL, PIN(9, 0), GPIO_INPUT) +GPIO(EC_I2C1_USB_C0_SDA, PIN(8, 7), GPIO_INPUT) +GPIO(EC_I2C2_USB_C1_SCL, PIN(9, 2), GPIO_INPUT) +GPIO(EC_I2C2_USB_C1_SDA, PIN(9, 1), GPIO_INPUT) +GPIO(EC_I2C3_USB_1_MIX_SCL, PIN(D, 1), GPIO_INPUT) +GPIO(EC_I2C3_USB_1_MIX_SDA, PIN(D, 0), GPIO_INPUT) +GPIO(EC_I2C4_USB_1_MIX_SCL, PIN(F, 3), GPIO_INPUT) +GPIO(EC_I2C4_USB_1_MIX_SDA, PIN(F, 2), GPIO_INPUT) +GPIO(EC_I2C5_POWER_SCL, PIN(3, 3), GPIO_INPUT) +GPIO(EC_I2C5_POWER_SDA, PIN(3, 6), GPIO_INPUT) +GPIO(EC_I2C7_EEPROM_SCL, PIN(B, 3), GPIO_INPUT) +GPIO(EC_I2C7_EEPROM_SDA, PIN(B, 2), GPIO_INPUT) + +/* Battery signals */ +GPIO(EC_BATT_PRES_ODL, PIN(E, 1), GPIO_INPUT) + +/* Alternate functions GPIO definitions */ +ALTERNATE(PIN_MASK(B, BIT(5) | BIT(4)), 0, MODULE_I2C, (GPIO_INPUT | GPIO_SEL_1P8V)) /* I2C0 */ +ALTERNATE(PIN_MASK(9, BIT(0) | BIT(2) | BIT(1)), 0, MODULE_I2C, 0) /* I2C1 SCL / I2C2 */ +ALTERNATE(PIN_MASK(8, BIT(7)), 0, MODULE_I2C, 0) /* I2C1 SDA */ +ALTERNATE(PIN_MASK(D, BIT(1) | BIT(0)), 0, MODULE_I2C, 0) /* I2C3 */ +ALTERNATE(PIN_MASK(F, BIT(3) | BIT(2)), 0, MODULE_I2C, 0) /* I2C4 */ +ALTERNATE(PIN_MASK(3, BIT(3) | BIT(6)), 0, MODULE_I2C, 0) /* I2C5 */ +ALTERNATE(PIN_MASK(B, BIT(3) | BIT(2)), 0, MODULE_I2C, 0) /* I2C7 */ + +/* Fan signals */ +GPIO(EN_PP5000_FAN, PIN(6, 1), GPIO_OUT_LOW) +ALTERNATE(PIN_MASK(B, BIT(7)), 0, MODULE_PWM, 0) /* FAN_PWM */ +ALTERNATE(PIN_MASK(4, BIT(0)), 0, MODULE_PWM, 0) /* FAN_SPEED_TACH */ + +/* Keyboard pins */ +#define GPIO_KB_INPUT (GPIO_INPUT | GPIO_PULL_UP) +ALTERNATE(PIN_MASK(3, 0x03), 0, MODULE_KEYBOARD_SCAN, GPIO_KB_INPUT) /* KSI_00-01 */ +ALTERNATE(PIN_MASK(2, 0xFC), 0, MODULE_KEYBOARD_SCAN, GPIO_KB_INPUT) /* KSI_02-07 */ +ALTERNATE(PIN_MASK(2, 0x03), 0, MODULE_KEYBOARD_SCAN, GPIO_ODR_HIGH) /* KSO_00-01 */ +GPIO(EC_KSO_02_INV, PIN(1, 7), GPIO_OUT_LOW) /* KSO_02 */ +ALTERNATE(PIN_MASK(1, 0x7F), 0, MODULE_KEYBOARD_SCAN, GPIO_ODR_HIGH) /* KSO_03-09 */ +ALTERNATE(PIN_MASK(0, 0xF0), 0, MODULE_KEYBOARD_SCAN, GPIO_ODR_HIGH) /* KSO_10-13 */ +ALTERNATE(PIN_MASK(8, 0x04), 0, MODULE_KEYBOARD_SCAN, GPIO_ODR_HIGH) /* KSO_14 */ +ALTERNATE(PIN_MASK(8, BIT(0)), 0, MODULE_PWM, 0) /* EC_KB_BL_PWM */ + +/* UART */ +ALTERNATE(PIN_MASK(6, BIT(5) | BIT(4)), 0, MODULE_UART, 0) /* UART from EC to Servo */ + +/* Power Switch Logic (PSL) inputs */ +ALTERNATE(PIN_MASK(D, BIT(2)), 0, MODULE_PMU, 0) /* GPIOD2 = EC_LID_OPEN */ +ALTERNATE(PIN_MASK(0, BIT(0) | BIT(1) | BIT(2)), 0, MODULE_PMU, 0) /* GPIO00 = ACOK_OD, + GPIO01 = H1_EC_PWR_BTN_ODL + GPIO02 = EC_RST_ODL */ + +/* Temperature sensors */ +ALTERNATE(PIN_MASK(4, BIT(2) | BIT(4) | BIT(5)), 0, MODULE_ADC, 0) /* TEMP_SENSOR1,2,4 */ +ALTERNATE(PIN(F, 1), 0, MODULE_ADC, 0) /* TEMP_SENSOR3 */ diff --git a/board/volet/led.c b/board/volet/led.c new file mode 100644 index 0000000000..ba4af36163 --- /dev/null +++ b/board/volet/led.c @@ -0,0 +1,79 @@ +/* Copyright 2021 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. + * + * Power and battery LED control for Volteer + */ + +#include "ec_commands.h" +#include "gpio.h" +#include "led_common.h" +#include "led_onoff_states.h" +#include "chipset.h" + +#define LED_ON_LVL 0 +#define LED_OFF_LVL 1 + +__override const int led_charge_lvl_1 = 5; + +__override const int led_charge_lvl_2 = 95; + +__override struct led_descriptor + led_bat_state_table[LED_NUM_STATES][LED_NUM_PHASES] = { + [STATE_CHARGING_LVL_1] = {{EC_LED_COLOR_AMBER, LED_INDEFINITE} }, + [STATE_CHARGING_LVL_2] = {{EC_LED_COLOR_AMBER, LED_INDEFINITE} }, + [STATE_CHARGING_FULL_CHARGE] = {{EC_LED_COLOR_BLUE, LED_INDEFINITE} }, + [STATE_DISCHARGE_S0] = {{EC_LED_COLOR_BLUE, LED_INDEFINITE} }, + [STATE_DISCHARGE_S3] = {{EC_LED_COLOR_AMBER, 1 * LED_ONE_SEC}, + {LED_OFF, 3 * LED_ONE_SEC} }, + [STATE_DISCHARGE_S5] = {{LED_OFF, LED_INDEFINITE} }, + [STATE_BATTERY_ERROR] = {{EC_LED_COLOR_AMBER, 1 * LED_ONE_SEC}, + {LED_OFF, 1 * LED_ONE_SEC} }, + [STATE_FACTORY_TEST] = {{EC_LED_COLOR_BLUE, 2 * LED_ONE_SEC}, + {EC_LED_COLOR_AMBER, 2 * LED_ONE_SEC} }, +}; + +const enum ec_led_id supported_led_ids[] = { + EC_LED_ID_BATTERY_LED +}; + +const int supported_led_ids_count = ARRAY_SIZE(supported_led_ids); + +__override void led_set_color_battery(enum ec_led_colors color) +{ + switch (color) { + case EC_LED_COLOR_AMBER: + gpio_set_level(GPIO_LED_2_L, LED_ON_LVL); + gpio_set_level(GPIO_LED_1_L, LED_OFF_LVL); + break; + case EC_LED_COLOR_BLUE: + gpio_set_level(GPIO_LED_1_L, LED_ON_LVL); + gpio_set_level(GPIO_LED_2_L, LED_OFF_LVL); + break; + default: /* LED_OFF and other unsupported colors */ + gpio_set_level(GPIO_LED_1_L, LED_OFF_LVL); + gpio_set_level(GPIO_LED_2_L, LED_OFF_LVL); + break; + } +} + +void led_get_brightness_range(enum ec_led_id led_id, uint8_t *brightness_range) +{ + if (led_id == EC_LED_ID_BATTERY_LED) { + brightness_range[EC_LED_COLOR_AMBER] = 1; + brightness_range[EC_LED_COLOR_BLUE] = 1; + } +} + +int led_set_brightness(enum ec_led_id led_id, const uint8_t *brightness) +{ + if (led_id == EC_LED_ID_BATTERY_LED) { + if (brightness[EC_LED_COLOR_BLUE] != 0) + led_set_color_battery(EC_LED_COLOR_BLUE); + else if (brightness[EC_LED_COLOR_AMBER] != 0) + led_set_color_battery(EC_LED_COLOR_AMBER); + else + led_set_color_battery(LED_OFF); + } + return EC_SUCCESS; +} diff --git a/board/volet/sensors.c b/board/volet/sensors.c new file mode 100644 index 0000000000..7185a9d65d --- /dev/null +++ b/board/volet/sensors.c @@ -0,0 +1,266 @@ +/* Copyright 2021 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. + */ + +/* Volteer family-specific sensor configuration */ +#include "common.h" +#include "accelgyro.h" +#include "cbi_ec_fw_config.h" +#include "cbi_ssfc.h" +#include "driver/accel_bma2x2.h" +#include "driver/accel_kionix.h" +#include "driver/accelgyro_bmi_common.h" +#include "driver/accelgyro_bmi160.h" +#include "driver/accelgyro_icm_common.h" +#include "driver/accelgyro_icm426xx.h" +#include "driver/als_tcs3400.h" +#include "driver/sync.h" +#include "keyboard_scan.h" +#include "hooks.h" +#include "i2c.h" +#include "task.h" +#include "tablet_mode.h" +#include "util.h" + +#define CPRINTS(format, args...) cprints(CC_MOTION_SENSE, format, ## args) +/******************************************************************************/ +/* Sensors */ +static struct mutex g_lid_accel_mutex; +static struct mutex g_base_mutex; + +/* BMA253 private data */ +static struct accelgyro_saved_data_t g_bma253_data; +static struct kionix_accel_data g_kx022_data; + +/* BMI160 private data */ +static struct bmi_drv_data_t g_bmi160_data; +static struct icm_drv_data_t g_icm426xx_data; + +/* Rotation matrix for the lid accelerometer */ +static const mat33_fp_t lid_standard_ref = { + { FLOAT_TO_FP(-1), 0, 0}, + { 0, FLOAT_TO_FP(-1), 0}, + { 0, 0, FLOAT_TO_FP(1)} +}; + +const mat33_fp_t base_standard_ref = { + { 0, FLOAT_TO_FP(1), 0}, + { FLOAT_TO_FP(-1), 0, 0}, + { 0, 0, FLOAT_TO_FP(1)} +}; + +static const mat33_fp_t base_icm_ref = { + { FLOAT_TO_FP(1), 0, 0}, + { 0, FLOAT_TO_FP(1), 0}, + { 0, 0, FLOAT_TO_FP(1)} +}; + +struct motion_sensor_t kx022_lid_accel = { + .name = "Lid Accel", + .active_mask = SENSOR_ACTIVE_S0_S3, + .chip = MOTIONSENSE_CHIP_KX022, + .type = MOTIONSENSE_TYPE_ACCEL, + .location = MOTIONSENSE_LOC_LID, + .drv = &kionix_accel_drv, + .mutex = &g_lid_accel_mutex, + .drv_data = &g_kx022_data, + .port = I2C_PORT_ACCEL, + .i2c_spi_addr_flags = KX022_ADDR0_FLAGS, + .rot_standard_ref = &lid_standard_ref, + .min_frequency = KX022_ACCEL_MIN_FREQ, + .max_frequency = KX022_ACCEL_MAX_FREQ, + .default_range = 2, /* g, to support tablet mode */ + .config = { + /* EC use accel for angle detection */ + [SENSOR_CONFIG_EC_S0] = { + .odr = 10000 | ROUND_UP_FLAG, + }, + /* EC use accel for angle detection */ + [SENSOR_CONFIG_EC_S3] = { + .odr = 10000 | ROUND_UP_FLAG, + }, + }, +}; + +struct motion_sensor_t icm426xx_base_accel = { + .name = "Base Accel", + .active_mask = SENSOR_ACTIVE_S0_S3, + .chip = MOTIONSENSE_CHIP_ICM426XX, + .type = MOTIONSENSE_TYPE_ACCEL, + .location = MOTIONSENSE_LOC_BASE, + .drv = &icm426xx_drv, + .mutex = &g_base_mutex, + .drv_data = &g_icm426xx_data, + .port = I2C_PORT_ACCEL, + .i2c_spi_addr_flags = ICM426XX_ADDR0_FLAGS, + .default_range = 4, /* g, to meet CDD 7.3.1/C-1-4 reqs.*/ + .rot_standard_ref = &base_icm_ref, + .min_frequency = ICM426XX_ACCEL_MIN_FREQ, + .max_frequency = ICM426XX_ACCEL_MAX_FREQ, + .config = { + /* EC use accel for angle detection */ + [SENSOR_CONFIG_EC_S0] = { + .odr = 10000 | ROUND_UP_FLAG, + .ec_rate = 100 * MSEC, + }, + /* EC use accel for angle detection */ + [SENSOR_CONFIG_EC_S3] = { + .odr = 10000 | ROUND_UP_FLAG, + .ec_rate = 100 * MSEC, + }, + }, +}; + +struct motion_sensor_t icm426xx_base_gyro = { + .name = "Base Gyro", + .active_mask = SENSOR_ACTIVE_S0_S3, + .chip = MOTIONSENSE_CHIP_ICM426XX, + .type = MOTIONSENSE_TYPE_GYRO, + .location = MOTIONSENSE_LOC_BASE, + .drv = &icm426xx_drv, + .mutex = &g_base_mutex, + .drv_data = &g_icm426xx_data, + .port = I2C_PORT_ACCEL, + .i2c_spi_addr_flags = ICM426XX_ADDR0_FLAGS, + .default_range = 1000, /* dps */ + .rot_standard_ref = &base_icm_ref, + .min_frequency = ICM426XX_GYRO_MIN_FREQ, + .max_frequency = ICM426XX_GYRO_MAX_FREQ, +}; + +struct motion_sensor_t motion_sensors[] = { + [LID_ACCEL] = { + .name = "Lid Accel", + .active_mask = SENSOR_ACTIVE_S0_S3, + .chip = MOTIONSENSE_CHIP_BMA255, + .type = MOTIONSENSE_TYPE_ACCEL, + .location = MOTIONSENSE_LOC_LID, + .drv = &bma2x2_accel_drv, + .mutex = &g_lid_accel_mutex, + .drv_data = &g_bma253_data, + .port = I2C_PORT_SENSOR, + .i2c_spi_addr_flags = BMA2x2_I2C_ADDR1_FLAGS, + .rot_standard_ref = &lid_standard_ref, + .min_frequency = BMA255_ACCEL_MIN_FREQ, + .max_frequency = BMA255_ACCEL_MAX_FREQ, + .default_range = 2, /* g, to support tablet mode */ + .config = { + /* EC use accel for angle detection */ + [SENSOR_CONFIG_EC_S0] = { + .odr = 10000 | ROUND_UP_FLAG, + }, + /* Sensor on in S3 */ + [SENSOR_CONFIG_EC_S3] = { + .odr = 10000 | ROUND_UP_FLAG, + }, + }, + }, + [BASE_ACCEL] = { + .name = "Base Accel", + .active_mask = SENSOR_ACTIVE_S0_S3, + .chip = MOTIONSENSE_CHIP_BMI160, + .type = MOTIONSENSE_TYPE_ACCEL, + .location = MOTIONSENSE_LOC_BASE, + .drv = &bmi160_drv, + .mutex = &g_base_mutex, + .drv_data = &g_bmi160_data, + .port = I2C_PORT_SENSOR, + .i2c_spi_addr_flags = BMI160_ADDR0_FLAGS, + .rot_standard_ref = &base_standard_ref, + .min_frequency = BMI_ACCEL_MIN_FREQ, + .max_frequency = BMI_ACCEL_MAX_FREQ, + .default_range = 4, /* g */ + .config = { + /* EC use accel for angle detection */ + [SENSOR_CONFIG_EC_S0] = { + .odr = 10000 | ROUND_UP_FLAG, + .ec_rate = 100 * MSEC, + }, + /* Sensor on in S3 */ + [SENSOR_CONFIG_EC_S3] = { + .odr = 10000 | ROUND_UP_FLAG, + .ec_rate = 100 * MSEC, + }, + }, + }, + + [BASE_GYRO] = { + .name = "Base Gyro", + .active_mask = SENSOR_ACTIVE_S0_S3, + .chip = MOTIONSENSE_CHIP_BMI160, + .type = MOTIONSENSE_TYPE_GYRO, + .location = MOTIONSENSE_LOC_BASE, + .drv = &bmi160_drv, + .mutex = &g_base_mutex, + .drv_data = &g_bmi160_data, + .port = I2C_PORT_SENSOR, + .i2c_spi_addr_flags = BMI160_ADDR0_FLAGS, + .default_range = 1000, /* dps */ + .rot_standard_ref = &base_standard_ref, + .min_frequency = BMI_GYRO_MIN_FREQ, + .max_frequency = BMI_GYRO_MAX_FREQ, + }, +}; +unsigned int motion_sensor_count = ARRAY_SIZE(motion_sensors); + +static void board_sensors_init(void) +{ + if (ec_cfg_has_tabletmode()) { + if (get_cbi_ssfc_base_sensor() == SSFC_SENSOR_BASE_ICM426XX) { + motion_sensors[BASE_ACCEL] = icm426xx_base_accel; + motion_sensors[BASE_GYRO] = icm426xx_base_gyro; + ccprints("BASE GYRO is ICM426XX"); + } else + ccprints("BASE GYRO is BMI160"); + + if (get_cbi_ssfc_lid_sensor() == SSFC_SENSOR_LID_KX022) { + motion_sensors[LID_ACCEL] = kx022_lid_accel; + ccprints("LID_ACCEL is KX022"); + } else + ccprints("LID_ACCEL is BMA253"); + + motion_sensor_count = ARRAY_SIZE(motion_sensors); + /* Enable interrupt for the accel/gyro sensor */ + gpio_enable_interrupt(GPIO_EC_IMU_INT_L); + } else { + motion_sensor_count = 0; + gmr_tablet_switch_disable(); + /* Base accel is not stuffed, don't allow line to float */ + gpio_set_flags(GPIO_EC_IMU_INT_L, + GPIO_INPUT | GPIO_PULL_DOWN); + } +} +DECLARE_HOOK(HOOK_INIT, board_sensors_init, HOOK_PRIO_DEFAULT); + +void motion_interrupt(enum gpio_signal signal) +{ + switch (get_cbi_ssfc_base_sensor()) { + case SSFC_SENSOR_BASE_ICM426XX: + icm426xx_interrupt(signal); + break; + case SSFC_SENSOR_BASE_BMI160: + default: + bmi160_interrupt(signal); + break; + } +} + +#ifndef TEST_BUILD +void lid_angle_peripheral_enable(int enable) +{ + int chipset_in_s0 = chipset_in_state(CHIPSET_STATE_ON); + + if (enable) { + keyboard_scan_enable(1, KB_SCAN_DISABLE_LID_ANGLE); + } else { + /* + * Ensure that the chipset is off before disabling the keyboard. + * When the chipset is on, the EC keeps the keyboard enabled and + * the AP decides whether to ignore input devices or not. + */ + if (!chipset_in_s0) + keyboard_scan_enable(0, KB_SCAN_DISABLE_LID_ANGLE); + } +} +#endif diff --git a/board/volet/vif_override.xml b/board/volet/vif_override.xml new file mode 100644 index 0000000000..3fc41630da --- /dev/null +++ b/board/volet/vif_override.xml @@ -0,0 +1,158 @@ +<?xml version="1.0" encoding="utf-8"?> +<VIF xmlns="http://usb.org/VendorInfoFile.xsd"> + <Model_Part_Number>Voxel</Model_Part_Number> + <Product_Revision>0</Product_Revision> + <TID>0</TID> + <Product> + <!-- Information about TGL USB4 provided by Intel. See b/172963736 --> + <USB4_Num_Internal_Host_Controllers value="1" /> + <USB4_Num_PCIe_DN_Bridges value="0" /> + <USB4RouterList> + <Usb4Router> + <USB4_Router_ID value="1" /> + <USB4_Silicon_VID value="32903">8087</USB4_Silicon_VID> + <USB4_Num_Lane_Adapters value="4" /> + <USB4_Num_USB3_DN_Adapters value="1" /> + <USB4_Num_DP_IN_Adapters value="1" /> + <USB4_Num_DP_OUT_Adapters value="0" /> + <USB4_Num_PCIe_DN_Adapters value="4" /> + <USB4_TBT3_Not_Supported value="0">TBT3 Compatible</USB4_TBT3_Not_Supported> + <USB4_PCIe_Wake_Supported value="true" /> + <USB4_USB3_Wake_Supported value="false" /> + <USB4_Num_Unused_Adapters value="0" /> + <USB4_TBT3_VID value="32903">8087</USB4_TBT3_VID> + <USB4_PCIe_Switch_Vendor_ID value="32902">8086</USB4_PCIe_Switch_Vendor_ID> + <USB4_PCIe_Switch_Device_ID value="39451">9A1B</USB4_PCIe_Switch_Device_ID> + </Usb4Router> + <Usb4Router> + <USB4_Router_ID value="0" /> + <USB4_Silicon_VID value="32903">8087</USB4_Silicon_VID> + <USB4_Num_Lane_Adapters value="2" /> + <USB4_Num_USB3_DN_Adapters value="1" /> + <USB4_Num_DP_IN_Adapters value="0" /> + <USB4_Num_DP_OUT_Adapters value="0" /> + <USB4_Num_PCIe_DN_Adapters value="0" /> + <USB4_TBT3_Not_Supported value="1">Not TBT3-Compatible</USB4_TBT3_Not_Supported> + <USB4_PCIe_Wake_Supported value="false" /> + <USB4_USB3_Wake_Supported value="false" /> + <USB4_Num_Unused_Adapters value="0" /> + </Usb4Router> + </USB4RouterList> + </Product> + <Component> + <USB4_Max_Speed value="1">Gen 3 (40Gb)</USB4_Max_Speed> + <USB4_DFP_Supported value="true" /> + <USB4_UFP_Supported value="false" /> + <USB4_USB3_Tunneling_Supported value="true" /> + <USB4_DP_Tunneling_Supported value="true" /> + <USB4_PCIe_Tunneling_Supported value="true" /> + <USB4_TBT3_Compatibility_Supported value="true" /> + <USB4_CL1_State_Supported value="true" /> + <USB4_CL2_State_Supported value="true" /> + <USB4_Num_Retimers value="1" /> + <USB4_DP_Bit_Rate value="3">HBR3</USB4_DP_Bit_Rate> + <USB4_Num_DP_Lanes value="4">4 Lanes</USB4_Num_DP_Lanes> + <USB4_Lane_0_Adapter value="1" /> + <Host_Supports_USB_Data value="true" /> + <Host_Speed value="2">USB 3.2 Gen 2x1</Host_Speed> + <Host_Contains_Captive_Retimer value="true" /> + <Host_Truncates_DP_For_tDHPResponse value="false" /> + <Host_Suspend_Supported value="true" /> + <Is_DFP_On_Hub value="false" /> + <USB_Suspend_May_Be_Cleared value="true" /> + <FR_Swap_Type_C_Current_Capability_As_Initial_Sink value="3">3A @ 5V</FR_Swap_Type_C_Current_Capability_As_Initial_Sink> + <FR_Swap_Supported_As_Initial_Sink value="true" /> + <SrcPdoList> + <SrcPDO> + <!-- Add in missing fields for SrcPdo0, derived from SYV682B datasheet. --> + <Src_PD_OCP_OC_Debounce value="50">50 msec</Src_PD_OCP_OC_Debounce> + <Src_PD_OCP_OC_Threshold value="360">3600 mA</Src_PD_OCP_OC_Threshold> + </SrcPDO> + </SrcPdoList> + <Data_Capable_As_USB_Host_SOP value="true" /> + <Data_Capable_As_USB_Device_SOP value="false" /> + <!-- TODO(b/173028252): Figure out the appropriate Discover Identity ACK for + Volteer and update the EC and VIF accordingly. --> + <Product_Type_UFP_SOP value="3">PSD</Product_Type_UFP_SOP> + <Product_Type_DFP_SOP value="4">Alternate Mode Controller (AMC)</Product_Type_DFP_SOP> + <DFP_VDO_Port_Number value="0" /> + <Modal_Operation_Supported_SOP value="true" /> + <USB_VID_SOP value="6353">18D1</USB_VID_SOP> + <bcdDevice_SOP value="0">0000</bcdDevice_SOP> + <SVID_Fixed_SOP value="true" /> + <Num_SVIDs_Min_SOP value="1" /> + <Num_SVIDs_Max_SOP value="1" /> + <SOPSVIDList> + <SOPSVID> + <SVID_SOP value="32903">8087</SVID_SOP> + <SVID_Modes_Fixed_SOP value="true" /> + <SVID_Num_Modes_Min_SOP value="1" /> + <SVID_Num_Modes_Max_SOP value="1" /> + <SOPSVIDModeList> + <SOPSVIDMode> + <SVID_Mode_Enter_SOP value="true" /> + <SVID_Mode_Recog_Value_SOP value="0">00000000</SVID_Mode_Recog_Value_SOP> + </SOPSVIDMode> + </SOPSVIDModeList> + </SOPSVID> + </SOPSVIDList> + </Component> + <Component> + <USB4_Max_Speed value="1">Gen 3 (40Gb)</USB4_Max_Speed> + <USB4_DFP_Supported value="true" /> + <USB4_UFP_Supported value="false" /> + <USB4_USB3_Tunneling_Supported value="true" /> + <USB4_DP_Tunneling_Supported value="true" /> + <USB4_PCIe_Tunneling_Supported value="true" /> + <USB4_TBT3_Compatibility_Supported value="true" /> + <USB4_CL1_State_Supported value="true" /> + <USB4_CL2_State_Supported value="true" /> + <USB4_Num_Retimers value="1" /> + <USB4_DP_Bit_Rate value="3">HBR3</USB4_DP_Bit_Rate> + <USB4_Num_DP_Lanes value="4">4 Lanes</USB4_Num_DP_Lanes> + <USB4_Lane_0_Adapter value="1" /> + <Host_Supports_USB_Data value="true" /> + <Host_Speed value="2">USB 3.2 Gen 2x1</Host_Speed> + <Host_Contains_Captive_Retimer value="true" /> + <Host_Truncates_DP_For_tDHPResponse value="false" /> + <Host_Suspend_Supported value="true" /> + <Is_DFP_On_Hub value="false" /> + <USB_Suspend_May_Be_Cleared value="true" /> + <FR_Swap_Type_C_Current_Capability_As_Initial_Sink value="3">3A @ 5V</FR_Swap_Type_C_Current_Capability_As_Initial_Sink> + <FR_Swap_Supported_As_Initial_Sink value="true" /> + <SrcPdoList> + <SrcPDO> + <!-- Add in missing fields for SrcPdo0, derived from SYV682B datasheet. --> + <Src_PD_OCP_OC_Debounce value="50">50 msec</Src_PD_OCP_OC_Debounce> + <Src_PD_OCP_OC_Threshold value="360">3600 mA</Src_PD_OCP_OC_Threshold> + </SrcPDO> + </SrcPdoList> + <Data_Capable_As_USB_Host_SOP value="true" /> + <Data_Capable_As_USB_Device_SOP value="false" /> + <!-- TODO(b/173028252): Figure out the appropriate Discover Identity ACK for + Volteer and update the EC and VIF accordingly. --> + <Product_Type_UFP_SOP value="3">PSD</Product_Type_UFP_SOP> + <Product_Type_DFP_SOP value="4">Alternate Mode Controller (AMC)</Product_Type_DFP_SOP> + <DFP_VDO_Port_Number value="1" /> + <Modal_Operation_Supported_SOP value="true" /> + <USB_VID_SOP value="6353">18D1</USB_VID_SOP> + <bcdDevice_SOP value="0">0000</bcdDevice_SOP> + <SVID_Fixed_SOP value="true" /> + <Num_SVIDs_Min_SOP value="1" /> + <Num_SVIDs_Max_SOP value="1" /> + <SOPSVIDList> + <SOPSVID> + <SVID_SOP value="32903">8087</SVID_SOP> + <SVID_Modes_Fixed_SOP value="true" /> + <SVID_Num_Modes_Min_SOP value="1" /> + <SVID_Num_Modes_Max_SOP value="1" /> + <SOPSVIDModeList> + <SOPSVIDMode> + <SVID_Mode_Enter_SOP value="true" /> + <SVID_Mode_Recog_Value_SOP value="0">00000000</SVID_Mode_Recog_Value_SOP> + </SOPSVIDMode> + </SOPSVIDModeList> + </SOPSVID> + </SOPSVIDList> + </Component> +</VIF> |