diff options
Diffstat (limited to 'zephyr/projects/nissa')
113 files changed, 15612 insertions, 0 deletions
diff --git a/zephyr/projects/nissa/BUILD.py b/zephyr/projects/nissa/BUILD.py new file mode 100644 index 0000000000..b1affe7b4c --- /dev/null +++ b/zephyr/projects/nissa/BUILD.py @@ -0,0 +1,66 @@ +# Copyright 2021 The ChromiumOS Authors +# Use of this source code is governed by a BSD-style license that can be +# found in the LICENSE file. + +"""Define zmake projects for nissa.""" + +# Nivviks and Craask, Pujjo, Xivu has NPCX993F, Nereid and Joxer, Yaviks has ITE81302 + + +def register_nissa_project( + project_name, + chip="it81302bx", +): + """Register a variant of nissa.""" + register_func = register_binman_project + if chip.startswith("npcx"): + register_func = register_npcx_project + + chip_kconfig = {"it81302bx": "it8xxx2", "npcx9m3f": "npcx"}[chip] + + return register_func( + project_name=project_name, + zephyr_board=chip, + dts_overlays=[here / project_name / "project.overlay"], + kconfig_files=[ + here / "program.conf", + here / f"{chip_kconfig}_program.conf", + here / project_name / "project.conf", + ], + ) + + +nivviks = register_nissa_project( + project_name="nivviks", + chip="npcx9m3f", +) + +nereid = register_nissa_project( + project_name="nereid", + chip="it81302bx", +) + +craask = register_nissa_project( + project_name="craask", + chip="npcx9m3f", +) + +pujjo = register_nissa_project( + project_name="pujjo", + chip="npcx9m3f", +) + +xivu = register_nissa_project( + project_name="xivu", + chip="npcx9m3f", +) + +joxer = register_nissa_project( + project_name="joxer", + chip="it81302bx", +) + +yaviks = register_nissa_project( + project_name="yaviks", + chip="it81302bx", +) diff --git a/zephyr/projects/nissa/CMakeLists.txt b/zephyr/projects/nissa/CMakeLists.txt new file mode 100644 index 0000000000..8769af58ba --- /dev/null +++ b/zephyr/projects/nissa/CMakeLists.txt @@ -0,0 +1,84 @@ +# Copyright 2021 The ChromiumOS Authors +# Use of this source code is governed by a BSD-style license that can be +# found in the LICENSE file. + +cmake_minimum_required(VERSION 3.13.1) + +find_package(Zephyr REQUIRED HINTS "${ZEPHYR_BASE}") + +zephyr_include_directories(include) +zephyr_library_sources("src/common.c") +zephyr_library_sources("src/sub_board.c") +zephyr_library_sources_ifdef(CONFIG_AP_PWRSEQ "src/board_power.c") + +if(DEFINED CONFIG_BOARD_NIVVIKS) + project(nivviks) + zephyr_library_sources( + "nivviks/src/led.c" + "nivviks/src/form_factor.c" + "nivviks/src/keyboard.c" + ) + zephyr_library_sources_ifdef(CONFIG_PLATFORM_EC_FAN "nivviks/src/fan.c") + zephyr_library_sources_ifdef(CONFIG_PLATFORM_EC_USBC "nivviks/src/usbc.c") + zephyr_library_sources_ifdef(CONFIG_PLATFORM_EC_CHARGER "nivviks/src/charger.c") +endif() +if(DEFINED CONFIG_BOARD_NEREID) + project(nereid) + zephyr_library_sources( + "src/led.c" + "nereid/src/keyboard.c" + "nereid/src/hdmi.c" + ) + zephyr_library_sources_ifdef(CONFIG_PLATFORM_EC_USBC "nereid/src/usbc.c") + zephyr_library_sources_ifdef(CONFIG_PLATFORM_EC_CHARGER "nereid/src/charger.c") +endif() +if(DEFINED CONFIG_BOARD_CRAASK) + zephyr_library_sources( + "craask/src/form_factor.c" + "craask/src/keyboard.c" + "craask/src/led.c" + ) + project(craask) + zephyr_library_sources_ifdef(CONFIG_PLATFORM_EC_USBC "craask/src/usbc.c") + zephyr_library_sources_ifdef(CONFIG_PLATFORM_EC_CHARGER "craask/src/charger.c") +endif() +if(DEFINED CONFIG_BOARD_PUJJO) + project(pujjo) + zephyr_library_sources( + "pujjo/src/led.c" + "pujjo/src/keyboard.c" + "pujjo/src/hdmi.c" + "pujjo/src/form_factor.c" + ) + zephyr_library_sources_ifdef(CONFIG_PLATFORM_EC_FAN "pujjo/src/fan.c") + zephyr_library_sources_ifdef(CONFIG_PLATFORM_EC_USBC "pujjo/src/usbc.c") + zephyr_library_sources_ifdef(CONFIG_PLATFORM_EC_CHARGER "pujjo/src/charger.c") +endif() +if(DEFINED CONFIG_BOARD_XIVU) + project(xivu) + zephyr_library_sources( + "xivu/src/keyboard.c" + ) + zephyr_library_sources_ifdef(CONFIG_PLATFORM_EC_USBC "xivu/src/usbc.c") + zephyr_library_sources_ifdef(CONFIG_PLATFORM_EC_CHARGER "xivu/src/charger.c") +endif() +if(DEFINED CONFIG_BOARD_JOXER) + project(joxer) + zephyr_library_sources( + "joxer/src/led.c" + "joxer/src/keyboard.c" + ) + zephyr_library_sources_ifdef(CONFIG_PLATFORM_EC_USBC "joxer/src/usbc.c") + zephyr_library_sources_ifdef(CONFIG_PLATFORM_EC_CHARGER "joxer/src/charger.c") + zephyr_library_sources_ifdef(CONFIG_PLATFORM_EC_FAN "joxer/src/fan.c") +endif() +if(DEFINED CONFIG_BOARD_YAVIKS) + project(yaviks) + zephyr_library_sources( + "yaviks/src/led.c" + "yaviks/src/keyboard.c" + ) + zephyr_library_sources_ifdef(CONFIG_PLATFORM_EC_USBC "yaviks/src/usbc.c") + zephyr_library_sources_ifdef(CONFIG_PLATFORM_EC_CHARGER "yaviks/src/charger.c") + zephyr_library_sources_ifdef(CONFIG_PLATFORM_EC_FAN "yaviks/src/fan.c") +endif()
\ No newline at end of file diff --git a/zephyr/projects/nissa/Kconfig b/zephyr/projects/nissa/Kconfig new file mode 100644 index 0000000000..9e9ffc2528 --- /dev/null +++ b/zephyr/projects/nissa/Kconfig @@ -0,0 +1,52 @@ +# Copyright 2021 The ChromiumOS Authors +# Use of this source code is governed by a BSD-style license that can be +# found in the LICENSE file. + +config BOARD_NIVVIKS + bool "Google Nivviks Board" + help + Build Google Nivviks reference board. Nivviks has Intel ADL-N SoC + with NPCX993FA0BX EC. + +config BOARD_NEREID + bool "Google Nereid Board" + help + Build Google Nereid reference board. Nereid has Intel ADL-N SoC + with IT81302 EC. + +config BOARD_CRAASK + bool "Google Craask Board" + help + Build Google Craask board. Craask has Intel ADL-N SoC + with NPCX993FA0BX EC. + +config BOARD_PUJJO + bool "Google Pujjo Board" + help + Build Google Pujjo board. Pujjo has Intel ADL-N SoC + with NPCX993FA0BX EC. + +config BOARD_XIVU + bool "Google Xivu Board" + help + Build Google Xivu board. Xivu has Intel ADL-N SoC + with NPCX993FA0BX EC. + +config BOARD_JOXER + bool "Google Joxer Board" + help + Build Google Joxer reference board. Joxer has Intel ADL-N SoC + with IT81302 EC. + +config BOARD_YAVIKS + bool "Google Yaviks Board" + help + Build Google Yaviks board. Yaviks has Intel ADL-N SoC + with IT81302 EC. + + +module = NISSA +module-str = Nissa board-specific code +source "subsys/logging/Kconfig.template.log_config" + +source "Kconfig.zephyr" diff --git a/zephyr/projects/nissa/cbi.dtsi b/zephyr/projects/nissa/cbi.dtsi new file mode 100644 index 0000000000..d841be1624 --- /dev/null +++ b/zephyr/projects/nissa/cbi.dtsi @@ -0,0 +1,61 @@ +/* Copyright 2022 The ChromiumOS Authors + * Use of this source code is governed by a BSD-style license that can be + * found in the LICENSE file. + */ + +/ { + nissa-fw-config { + compatible = "cros-ec,cbi-fw-config"; + + /* + * FW_CONFIG field to indicate which sub-board + * is attached. + */ + sub-board { + enum-name = "FW_SUB_BOARD"; + start = <0>; + size = <2>; + + sub-board-1 { + compatible = "cros-ec,cbi-fw-config-value"; + enum-name = "FW_SUB_BOARD_1"; + value = <1>; + }; + sub-board-2 { + compatible = "cros-ec,cbi-fw-config-value"; + enum-name = "FW_SUB_BOARD_2"; + value = <2>; + }; + sub-board-3 { + compatible = "cros-ec,cbi-fw-config-value"; + enum-name = "FW_SUB_BOARD_3"; + value = <3>; + }; + }; + + /* + * FW_CONFIG field to enable fan or not. + */ + fan { + enum-name = "FW_FAN"; + start = <2>; + size = <1>; + + no-fan { + compatible = "cros-ec,cbi-fw-config-value"; + enum-name = "FW_FAN_NOT_PRESENT"; + value = <0>; + }; + fan-present { + compatible = "cros-ec,cbi-fw-config-value"; + enum-name = "FW_FAN_PRESENT"; + value = <1>; + /* + * Set as default so that unprovisioned + * configs will run the fan regardless. + */ + default; + }; + }; + }; +}; diff --git a/zephyr/projects/nissa/craask/cbi.dtsi b/zephyr/projects/nissa/craask/cbi.dtsi new file mode 100644 index 0000000000..4c2e052f4d --- /dev/null +++ b/zephyr/projects/nissa/craask/cbi.dtsi @@ -0,0 +1,107 @@ +/* Copyright 2022 The ChromiumOS Authors + * Use of this source code is governed by a BSD-style license that can be + * found in the LICENSE file. + */ + +/ { + /* Craask-specific fw_config fields. */ + nissa-fw-config { + /* + * FW_CONFIG field to describe Lid sensor orientation. + */ + lid-inversion { + enum-name = "FW_LID_INVERSION"; + start = <8>; + size = <1>; + + /* + * 0: regular placement of the lid sensor + * 1: rotate 180' of xy plane. + */ + regular { + compatible = "cros-ec,cbi-fw-config-value"; + enum-name = "FW_LID_REGULAR"; + value = <0>; + default; + }; + xy_rotate_180 { + compatible = "cros-ec,cbi-fw-config-value"; + enum-name = "FW_LID_XY_ROT_180"; + value = <1>; + }; + }; + /* + * FW_CONFIG field to describe Clamshell/Convertible. + */ + form_factor { + enum-name = "FORM_FACTOR"; + start = <9>; + size = <1>; + + /* + * 0: convertible, 1: clamshell + */ + convertible { + compatible = "cros-ec,cbi-fw-config-value"; + enum-name = "CONVERTIBLE"; + value = <0>; + }; + clamshell { + compatible = "cros-ec,cbi-fw-config-value"; + enum-name = "CLAMSHELL"; + value = <1>; + }; + }; + }; + /* Craask-specific ssfc fields. */ + cbi-ssfc { + compatible = "named-cbi-ssfc"; + /* + * SSFC bit0-1 was defined for AUDIO CODEC. + * 0: ALC5682I_VS + * 1: NAU8825 + */ + audio_codec { + enum-name = "AUDIO_CODEC"; + size = <2>; + }; + /* + * SSFC field to identify LID motion sensor. + */ + lid-sensor { + enum-name = "LID_SENSOR"; + size = <2>; + + lid_sensor_0: lis2dw12 { + compatible = "named-cbi-ssfc-value"; + status = "okay"; + value = <0>; + default; + }; + lid_sensor_1: bma422 { + compatible = "named-cbi-ssfc-value"; + status = "okay"; + value = <1>; + }; + }; + /* + * SSFC field to identify BASE motion sensor. + */ + base-sensor { + enum-name = "BASE_SENSOR"; + size = <2>; + + base_sensor_0: lsm6dso { + compatible = "named-cbi-ssfc-value"; + status = "okay"; + value = <0>; + default; + }; + base_sensor_1: bmi323 { + compatible = "named-cbi-ssfc-value"; + status = "okay"; + value = <1>; + }; + }; + }; +}; diff --git a/zephyr/projects/nissa/craask/generated.dtsi b/zephyr/projects/nissa/craask/generated.dtsi new file mode 100644 index 0000000000..4303bbd4c5 --- /dev/null +++ b/zephyr/projects/nissa/craask/generated.dtsi @@ -0,0 +1,288 @@ +/* Copyright 2022 The ChromiumOS Authors + * Use of this source code is governed by a BSD-style license that can be + * found in the LICENSE file. + */ + +/ { + + named-adc-channels { + compatible = "named-adc-channels"; + + adc_ec_vsense_pp1050_proc: ec_vsense_pp1050_proc { + enum-name = "ADC_PP1050_PROC"; + io-channels = <&adc0 4>; + }; + adc_ec_vsense_pp3300_s5: ec_vsense_pp3300_s5 { + enum-name = "ADC_PP3300_S5"; + io-channels = <&adc0 6>; + }; + adc_temp_sensor_1: temp_sensor_1 { + enum-name = "ADC_TEMP_SENSOR_1"; + io-channels = <&adc0 0>; + }; + adc_temp_sensor_2: temp_sensor_2 { + enum-name = "ADC_TEMP_SENSOR_2"; + io-channels = <&adc0 1>; + }; + adc_temp_sensor_3: temp_sensor_3 { + enum-name = "ADC_TEMP_SENSOR_3"; + io-channels = <&adc0 10>; + }; + }; + + named-gpios { + compatible = "named-gpios"; + + gpio_acc_int_l: acc_int_l { + gpios = <&gpio5 0 GPIO_INPUT>; + }; + gpio_all_sys_pwrgd: all_sys_pwrgd { + gpios = <&gpioa 7 GPIO_INPUT>; + }; + gpio_ccd_mode_odl: ccd_mode_odl { + gpios = <&gpioe 5 GPIO_INPUT>; + enum-name = "GPIO_CCD_MODE_ODL"; + }; + gpio_cpu_c10_gate_l: cpu_c10_gate_l { + gpios = <&gpio6 7 GPIO_INPUT>; + }; + gpio_ec_battery_pres_odl: ec_battery_pres_odl { + gpios = <&gpioa 3 GPIO_INPUT>; + enum-name = "GPIO_BATT_PRES_ODL"; + }; + gpio_ec_cbi_wp: ec_cbi_wp { + gpios = <&gpio7 4 GPIO_OUTPUT>; + }; + gpio_ec_edp_bl_en_od: ec_edp_bl_en_od { + gpios = <&gpiod 3 GPIO_ODR_HIGH>; + enum-name = "GPIO_ENABLE_BACKLIGHT"; + }; + gpio_ec_entering_rw: ec_entering_rw { + gpios = <&gpio0 3 GPIO_OUTPUT>; + enum-name = "GPIO_ENTERING_RW"; + }; + gpio_ec_gsc_packet_mode: ec_gsc_packet_mode { + gpios = <&gpio7 5 GPIO_OUTPUT>; + enum-name = "GPIO_PACKET_MODE_EN"; + }; + gpio_ec_kso_02_inv: ec_kso_02_inv { + gpios = <&gpio1 7 (GPIO_OUTPUT | GPIO_ACTIVE_LOW)>; + }; + gpio_ec_pch_wake_odl: ec_pch_wake_odl { + gpios = <&gpiob 0 GPIO_ODR_LOW>; + }; + gpio_ec_prochot_odl: ec_prochot_odl { + gpios = <&gpiof 1 GPIO_ODR_HIGH>; + }; + gpio_ec_soc_dsw_pwrok: ec_soc_dsw_pwrok { + gpios = <&gpio6 1 GPIO_OUTPUT>; + }; + gpio_ec_soc_hdmi_hpd: ec_soc_hdmi_hpd { + gpios = <&gpioe 4 GPIO_OUTPUT>; + }; + gpio_ec_soc_int_odl: ec_soc_int_odl { + gpios = <&gpio8 0 GPIO_ODR_HIGH>; + enum-name = "GPIO_EC_INT_L"; + }; + gpio_ec_soc_pch_pwrok_od: ec_soc_pch_pwrok_od { + gpios = <&gpio7 2 GPIO_ODR_HIGH>; + }; + gpio_ec_soc_pwr_btn_odl: ec_soc_pwr_btn_odl { + gpios = <&gpioc 1 GPIO_ODR_HIGH>; + enum-name = "GPIO_PCH_PWRBTN_L"; + }; + gpio_ec_soc_rsmrst_l: ec_soc_rsmrst_l { + gpios = <&gpioa 6 GPIO_OUTPUT>; + }; + gpio_ec_soc_rtcrst: ec_soc_rtcrst { + gpios = <&gpio7 6 GPIO_OUTPUT>; + }; + gpio_ec_soc_sys_pwrok: ec_soc_sys_pwrok { + gpios = <&gpio3 7 GPIO_OUTPUT>; + }; + gpio_ec_soc_vccst_pwrgd_od: ec_soc_vccst_pwrgd_od { + gpios = <&gpioa 4 GPIO_ODR_HIGH>; + }; + gpio_ec_wp_odl: ec_wp_odl { + gpios = <&gpioa 1 (GPIO_INPUT | GPIO_ACTIVE_LOW)>; + }; + gpio_en_kb_bl: en_kb_bl { + gpios = <&gpioa 0 GPIO_OUTPUT>; + enum-name = "GPIO_EN_KEYBOARD_BACKLIGHT"; + }; + gpio_en_pp3300_s5: en_pp3300_s5 { + gpios = <&gpiob 6 GPIO_OUTPUT>; + enum-name = "GPIO_TEMP_SENSOR_POWER"; + }; + gpio_en_pp5000_pen_x: en_pp5000_pen_x { + gpios = <&gpioe 2 GPIO_OUTPUT>; + }; + gpio_en_pp5000_s5: en_pp5000_s5 { + gpios = <&gpio4 0 GPIO_OUTPUT>; + }; + gpio_en_slp_z: en_slp_z { + gpios = <&gpioe 1 GPIO_OUTPUT>; + }; + gpio_en_usb_a0_vbus: en_usb_a0_vbus { + gpios = <&gpio9 1 GPIO_OUTPUT>; + }; + gpio_gsc_ec_pwr_btn_odl: gsc_ec_pwr_btn_odl { + gpios = <&gpio0 0 GPIO_INPUT_PULL_UP>; + enum-name = "GPIO_POWER_BUTTON_L"; + }; + gpio_hdmi_sel: hdmi_sel { + gpios = <&gpioc 6 GPIO_OUTPUT>; + }; + gpio_imu_int_l: imu_int_l { + gpios = <&gpio5 6 GPIO_INPUT>; + }; + gpio_imvp91_vrrdy_od: imvp91_vrrdy_od { + gpios = <&gpio4 3 GPIO_INPUT>; + }; + gpio_lid_open: lid_open { + gpios = <&gpiod 2 GPIO_INPUT>; + enum-name = "GPIO_LID_OPEN"; + }; + gpio_pen_detect_odl: pen_detect_odl { + gpios = <&gpio9 6 GPIO_INPUT_PULL_UP>; + }; + gpio_pg_pp1050_mem_s3_od: pg_pp1050_mem_s3_od { + gpios = <&gpiof 0 GPIO_INPUT>; + }; + gpio_pg_pp5000_s5_od: pg_pp5000_s5_od { + gpios = <&gpio4 2 GPIO_INPUT>; + }; + gpio_rsmrst_pwrgd_l: rsmrst_pwrgd_l { + gpios = <&gpio9 4 GPIO_INPUT_PULL_UP>; + }; + gpio_slp_s0_l: slp_s0_l { + gpios = <&gpio9 7 GPIO_INPUT>; + }; + gpio_slp_s3_l: slp_s3_l { + gpios = <&gpioa 5 GPIO_INPUT>; + }; + gpio_slp_s4_l: slp_s4_l { + gpios = <&gpio7 0 GPIO_INPUT>; + }; + gpio_slp_sus_l: slp_sus_l { + gpios = <&gpio6 2 GPIO_INPUT>; + }; + gpio_sub_usb_a1_ilimit_sdp: sub_usb_a1_ilimit_sdp { + gpios = <&gpiod 5 GPIO_OUTPUT>; + enum-name = "GPIO_USB2_ILIM_SEL"; + }; + gpio_sys_rst_odl: sys_rst_odl { + gpios = <&gpioc 5 GPIO_ODR_HIGH>; + }; + gpio_tablet_mode_l: tablet_mode_l { + gpios = <&gpio9 5 GPIO_INPUT>; + enum-name = "GPIO_TABLET_MODE_L"; + }; + gpio_usb_a0_ilimit_sdp: usb_a0_ilimit_sdp { + gpios = <&gpio8 5 GPIO_OUTPUT>; + enum-name = "GPIO_USB1_ILIM_SEL"; + }; + gpio_usb_c0_int_odl: usb_c0_int_odl { + gpios = <&gpio0 1 GPIO_INPUT_PULL_UP>; + }; + gpio_vccin_aux_vid0: vccin_aux_vid0 { + gpios = <&gpio9 2 (GPIO_INPUT | GPIO_VOLTAGE_1P8)>; + }; + gpio_vccin_aux_vid1: vccin_aux_vid1 { + gpios = <&gpioe 3 (GPIO_INPUT | GPIO_VOLTAGE_1P8)>; + }; + gpio_voldn_btn_odl: voldn_btn_odl { + gpios = <&gpio9 3 GPIO_INPUT_PULL_UP>; + enum-name = "GPIO_VOLUME_DOWN_L"; + }; + gpio_volup_btn_odl: volup_btn_odl { + gpios = <&gpioa 2 GPIO_INPUT_PULL_UP>; + enum-name = "GPIO_VOLUME_UP_L"; + }; + }; + + named-i2c-ports { + compatible = "named-i2c-ports"; + + i2c_ec_i2c_eeprom: ec_i2c_eeprom { + i2c-port = <&i2c0_0>; + enum-names = "I2C_PORT_EEPROM"; + }; + i2c_ec_i2c_sensor: ec_i2c_sensor { + i2c-port = <&i2c1_0>; + enum-names = "I2C_PORT_SENSOR"; + }; + i2c_ec_i2c_usb_c0: ec_i2c_usb_c0 { + i2c-port = <&i2c3_0>; + enum-names = "I2C_PORT_USB_C0_TCPC"; + }; + i2c_ec_i2c_sub_usb_c1: ec_i2c_sub_usb_c1 { + i2c-port = <&i2c5_1>; + enum-names = "I2C_PORT_USB_C1_TCPC"; + }; + i2c_ec_i2c_batt: ec_i2c_batt { + i2c-port = <&i2c7_0>; + enum-names = "I2C_PORT_BATTERY"; + }; + }; +}; + +&adc0 { + status = "okay"; + pinctrl-0 = <&adc0_chan0_gp45 + &adc0_chan1_gp44 + &adc0_chan4_gp41 + &adc0_chan6_gp34 + &adc0_chan10_gpe0>; + pinctrl-names = "default"; +}; + +&i2c0_0 { + status = "okay"; + pinctrl-0 = <&i2c0_0_sda_scl_gpb4_b5>; + pinctrl-names = "default"; +}; + +&i2c1_0 { + status = "okay"; + pinctrl-0 = <&i2c1_0_sda_scl_gp87_90>; + pinctrl-names = "default"; +}; + +&i2c3_0 { + status = "okay"; + pinctrl-0 = <&i2c3_0_sda_scl_gpd0_d1>; + pinctrl-names = "default"; +}; + +&i2c5_1 { + status = "okay"; + pinctrl-0 = <&i2c5_1_sda_scl_gpf4_f5>; + pinctrl-names = "default"; +}; + +&i2c7_0 { + status = "okay"; + pinctrl-0 = <&i2c7_0_sda_scl_gpb2_b3>; + pinctrl-names = "default"; +}; + +&i2c_ctrl0 { + status = "okay"; +}; + +&i2c_ctrl1 { + status = "okay"; +}; + +&i2c_ctrl3 { + status = "okay"; +}; + +&i2c_ctrl5 { + status = "okay"; +}; + +&i2c_ctrl7 { + status = "okay"; +}; diff --git a/zephyr/projects/nissa/craask/keyboard.dtsi b/zephyr/projects/nissa/craask/keyboard.dtsi new file mode 100644 index 0000000000..f9e46de1f2 --- /dev/null +++ b/zephyr/projects/nissa/craask/keyboard.dtsi @@ -0,0 +1,32 @@ +/* Copyright 2022 The ChromiumOS Authors + * Use of this source code is governed by a BSD-style license that can be + * found in the LICENSE file. + */ + +&cros_kb_raw { + status = "okay"; + /* No KSO2 (it's inverted and implemented by GPIO) */ + pinctrl-0 = < + &ksi0_gp31 + &ksi1_gp30 + &ksi2_gp27 + &ksi3_gp26 + &ksi4_gp25 + &ksi5_gp24 + &ksi6_gp23 + &ksi7_gp22 + &kso00_gp21 + &kso01_gp20 + &kso03_gp16 + &kso04_gp15 + &kso05_gp14 + &kso06_gp13 + &kso07_gp12 + &kso08_gp11 + &kso09_gp10 + &kso10_gp07 + &kso11_gp06 + &kso12_gp05 + >; + pinctrl-names = "default"; +}; diff --git a/zephyr/projects/nissa/craask/motionsense.dtsi b/zephyr/projects/nissa/craask/motionsense.dtsi new file mode 100644 index 0000000000..448aed6991 --- /dev/null +++ b/zephyr/projects/nissa/craask/motionsense.dtsi @@ -0,0 +1,257 @@ +/* Copyright 2022 The ChromiumOS Authors + * Use of this source code is governed by a BSD-style license that can be + * found in the LICENSE file. + */ + +#include <dt-bindings/motionsense/utils.h> + + +/ { + aliases { + /* + * Interrupt bindings for sensor devices. + */ + lsm6dso-int = &base_accel; + lis2dw12-int = &lid_accel; + bmi3xx-int = &base_accel; + }; + + /* + * Declare mutexes used by sensor drivers. + * A mutex node is used to create an instance of mutex_t. + * A mutex node is referenced by a sensor node if the + * corresponding sensor driver needs to use the + * instance of the mutex. + */ + motionsense-mutex { + compatible = "cros-ec,motionsense-mutex"; + lid_mutex: lis2dw12-mutex { + }; + + lid_mutex_bma422: bma422-mutex { + }; + + base_mutex: base-mutex { + }; + + base_mutex_bmi323: bmi323-mutex { + }; + }; + + /* Rotation matrix used by drivers. */ + motionsense-rotation-ref { + compatible = "cros-ec,motionsense-rotation-ref"; + lid_rot_ref: lid-rotation-ref { + mat33 = <(-1) 0 0 + 0 1 0 + 0 0 (-1)>; + }; + + base_rot_ref: base-rotation-ref { + mat33 = <1 0 0 + 0 (-1) 0 + 0 0 (-1)>; + }; + + base_rot_ver1: base-rotation-ver1 { + mat33 = <(-1) 0 0 + 0 (-1) 0 + 0 0 1>; + }; + + lid_rot_bma422: lid-rotation-bma { + mat33 = <1 0 0 + 0 (-1) 0 + 0 0 (-1)>; + }; + + base_rot_bmi323: base-rotation-bmi323 { + mat33 = <1 0 0 + 0 (-1) 0 + 0 0 (-1)>; + }; + }; + + /* + * Driver specific data. A driver-specific data can be shared with + * different motion sensors while they are using the same driver. + * + * If a node's compatible starts with "cros-ec,accelgyro-", it is for + * a common structure defined in accelgyro.h. + * e.g) compatible = "cros-ec,accelgyro-als-drv-data" is for + * "struct als_drv_data_t" in accelgyro.h + */ + motionsense-sensor-data { + lsm6dso_accel_data: lsm6dso-accel-drv-data { + compatible = "cros-ec,drvdata-lsm6dso"; + status = "okay"; + }; + + lsm6dso_gyro_data: lsm6dso-gyro-drv-data { + compatible = "cros-ec,drvdata-lsm6dso"; + status = "okay"; + }; + + lis2dw12_data: lis2dw12-drv-data { + compatible = "cros-ec,drvdata-lis2dw12"; + status = "okay"; + }; + + bma422_data: bma4xx-drv-data { + compatible = "cros-ec,drvdata-bma4xx"; + status = "okay"; + }; + + bmi323_data: bmi323-drv-data { + compatible = "cros-ec,drvdata-bmi3xx"; + status = "okay"; + }; + }; + + /* + * List of motion sensors that creates motion_sensors array. + * The nodelabel "lid_accel" and "base_accel" are used to indicate + * motion sensor IDs for lid angle calculation. + * TODO(b/238139272): The first entries of the array must be + * accelerometers,then gyroscope. Fix this dependency in the DTS + * processing which makes the devicetree entries independent. + */ + motionsense-sensor { + lid_accel: lid-accel { + compatible = "cros-ec,lis2dw12"; + status = "okay"; + + active-mask = "SENSOR_ACTIVE_S0_S3"; + location = "MOTIONSENSE_LOC_LID"; + mutex = <&lid_mutex>; + port = <&i2c_ec_i2c_sensor>; + rot-standard-ref = <&lid_rot_ref>; + default-range = <2>; + drv-data = <&lis2dw12_data>; + i2c-spi-addr-flags = "LIS2DWL_ADDR0_FLAGS"; + configs { + compatible = + "cros-ec,motionsense-sensor-config"; + ec-s0 { + odr = <(10000 | ROUND_UP_FLAG)>; + }; + ec-s3 { + odr = <(10000 | ROUND_UP_FLAG)>; + }; + }; + }; + + base_accel: base-accel { + compatible = "cros-ec,lsm6dso-accel"; + status = "okay"; + + active-mask = "SENSOR_ACTIVE_S0_S3"; + location = "MOTIONSENSE_LOC_BASE"; + mutex = <&base_mutex>; + port = <&i2c_ec_i2c_sensor>; + rot-standard-ref = <&base_rot_ref>; + drv-data = <&lsm6dso_accel_data>; + configs { + compatible = + "cros-ec,motionsense-sensor-config"; + ec-s0 { + odr = <(10000 | ROUND_UP_FLAG)>; + }; + ec-s3 { + odr = <(10000 | ROUND_UP_FLAG)>; + }; + }; + }; + + base_gyro: base-gyro { + compatible = "cros-ec,lsm6dso-gyro"; + status = "okay"; + + active-mask = "SENSOR_ACTIVE_S0_S3"; + location = "MOTIONSENSE_LOC_BASE"; + mutex = <&base_mutex>; + port = <&i2c_ec_i2c_sensor>; + rot-standard-ref = <&base_rot_ref>; + default-range = <(1000 | ROUND_UP_FLAG)>; /* dps */ + drv-data = <&lsm6dso_gyro_data>; + }; + }; + + motionsense-sensor-alt { + alt_lid_accel: alt-lid-accel { + compatible = "cros-ec,bma4xx"; + status = "okay"; + + active-mask = "SENSOR_ACTIVE_S0_S3"; + location = "MOTIONSENSE_LOC_LID"; + mutex = <&lid_mutex_bma422>; + port = <&i2c_ec_i2c_sensor>; + rot-standard-ref = <&lid_rot_bma422>; + default-range = <2>; + drv-data = <&bma422_data>; + i2c-spi-addr-flags = "BMA4_I2C_ADDR_PRIMARY"; + alternate-for = <&lid_accel>; + alternate-ssfc-indicator = <&lid_sensor_1>; + configs { + compatible = + "cros-ec,motionsense-sensor-config"; + ec-s0 { + odr = <(10000 | ROUND_UP_FLAG)>; + }; + ec-s3 { + odr = <(10000 | ROUND_UP_FLAG)>; + }; + }; + }; + + alt_base_accel: alt-base-accel { + compatible = "cros-ec,bmi3xx-accel"; + status = "okay"; + + active-mask = "SENSOR_ACTIVE_S0_S3"; + location = "MOTIONSENSE_LOC_BASE"; + mutex = <&base_mutex_bmi323>; + port = <&i2c_ec_i2c_sensor>; + rot-standard-ref = <&base_rot_bmi323>; + drv-data = <&bmi323_data>; + alternate-for = <&base_accel>; + alternate-ssfc-indicator = <&base_sensor_1>; + configs { + compatible = + "cros-ec,motionsense-sensor-config"; + ec-s0 { + odr = <(10000 | ROUND_UP_FLAG)>; + }; + ec-s3 { + odr = <(10000 | ROUND_UP_FLAG)>; + }; + }; + }; + + alt_base_gyro: alt-base-gyro { + compatible = "cros-ec,bmi3xx-gyro"; + status = "okay"; + + active-mask = "SENSOR_ACTIVE_S0_S3"; + location = "MOTIONSENSE_LOC_BASE"; + mutex = <&base_mutex_bmi323>; + port = <&i2c_ec_i2c_sensor>; + rot-standard-ref = <&base_rot_bmi323>; + drv-data = <&bmi323_data>; + alternate-for = <&base_gyro>; + alternate-ssfc-indicator = <&base_sensor_1>; + }; + }; + + motionsense-sensor-info { + compatible = "cros-ec,motionsense-sensor-info"; + + /* + * list of GPIO interrupts that have to + * be enabled at initial stage + */ + sensor-irqs = <&int_imu>; + /* list of sensors in force mode */ + accel-force-mode-sensors = <&lid_accel>; + }; +}; diff --git a/zephyr/projects/nissa/craask/overlay.dtsi b/zephyr/projects/nissa/craask/overlay.dtsi new file mode 100644 index 0000000000..b3a510c111 --- /dev/null +++ b/zephyr/projects/nissa/craask/overlay.dtsi @@ -0,0 +1,360 @@ +/* Copyright 2022 The ChromiumOS Authors + * Use of this source code is governed by a BSD-style license that can be + * found in the LICENSE file. + */ + +#include <cros/thermistor/thermistor.dtsi> + +/ { + aliases { + gpio-cbi-wp = &gpio_ec_cbi_wp; + gpio-wp = &gpio_ec_wp_odl; + int-wp = &int_wp_l; + gpio-kbd-kso2 = &gpio_ec_kso_02_inv; + }; + + ec-console { + compatible = "ec-console"; + disabled = "events", "lpc", "hostcmd"; + }; + + batteries { + default_battery: lgc { + compatible = "lgc,ap18c8k", "battery-smart"; + }; + cosmx { + compatible = "cosmx,ap20cbl", "battery-smart"; + }; + cosmx-2 { + compatible = "cosmx,ap20cbl-2", "battery-smart"; + }; + }; + + hibernate-wake-pins { + compatible = "cros-ec,hibernate-wake-pins"; + wakeup-irqs = < + &int_power_button + &int_lid_open + >; + }; + + gpio-interrupts { + compatible = "cros-ec,gpio-interrupts"; + + int_power_button: power_button { + irq-pin = <&gpio_gsc_ec_pwr_btn_odl>; + flags = <GPIO_INT_EDGE_BOTH>; + handler = "power_button_interrupt"; + }; + int_wp_l: wp_l { + irq-pin = <&gpio_ec_wp_odl>; + flags = <GPIO_INT_EDGE_BOTH>; + handler = "switch_interrupt"; + }; + int_lid_open: lid_open { + irq-pin = <&gpio_lid_open>; + flags = <GPIO_INT_EDGE_BOTH>; + handler = "lid_interrupt"; + }; + int_tablet_mode: tablet_mode { + irq-pin = <&gpio_tablet_mode_l>; + flags = <GPIO_INT_EDGE_BOTH>; + handler = "gmr_tablet_switch_isr"; + }; + int_imu: ec_imu { + irq-pin = <&gpio_imu_int_l>; + flags = <GPIO_INT_EDGE_FALLING>; + handler = "motion_interrupt"; + }; + int_vol_down: vol_down { + irq-pin = <&gpio_voldn_btn_odl>; + flags = <GPIO_INT_EDGE_BOTH>; + handler = "button_interrupt"; + }; + int_vol_up: vol_up { + irq-pin = <&gpio_volup_btn_odl>; + flags = <GPIO_INT_EDGE_BOTH>; + handler = "button_interrupt"; + }; + int_usb_c0: usb_c0 { + irq-pin = <&gpio_usb_c0_int_odl>; + flags = <GPIO_INT_EDGE_FALLING>; + handler = "usb_interrupt"; + }; + int_usb_c1: usb_c1 { + irq-pin = <&gpio_sb_1>; + flags = <GPIO_INT_EDGE_FALLING>; + handler = "usb_interrupt"; + }; + }; + + named-gpios { + gpio_sb_1: sb-1 { + gpios = <&gpio0 2 GPIO_PULL_UP>; + no-auto-init; + }; + + gpio_sb_2: sb-2 { + gpios = <&gpiod 4 GPIO_OUTPUT>; + no-auto-init; + }; + + /* + * Set I2C pins for type C sub-board to be low voltage (I2C5_1). + * We do this for all boards, since the pins are 3.3V tolerant, + * and the only 2 types of sub-boards used on nivviks both have + * type-C ports on them. + */ + gpio_sb_3: sb-3 { + gpios = <&gpiof 4 (GPIO_OPEN_DRAIN | GPIO_VOLTAGE_1P8)>; + no-auto-init; + }; + gpio_sb_4: sb-4 { + gpios = <&gpiof 5 (GPIO_INPUT | GPIO_VOLTAGE_1P8)>; + no-auto-init; + }; + ec-i2c-sensor-scl { + gpios = <&gpio9 0 (GPIO_INPUT | GPIO_VOLTAGE_1P8)>; + }; + ec-i2c-sensor-sda { + gpios = <&gpio8 7 (GPIO_INPUT | GPIO_VOLTAGE_1P8)>; + }; + }; + + /* + * Aliases used for sub-board GPIOs. + */ + aliases { + /* + * Input GPIO when used with type-C port 1 + * Output when used with HDMI sub-board + */ + gpio-usb-c1-int-odl = &gpio_sb_1; + gpio-en-rails-odl = &gpio_sb_1; + /* + * Sub-board with type A USB, enable. + */ + gpio-en-usb-a1-vbus = &gpio_sb_2; + /* + * HPD pins for HDMI sub-board. + */ + gpio-hdmi-en-odl = &gpio_sb_3; + gpio-hpd-odl = &gpio_sb_4; + /* + * Enable S5 rails for LTE sub-board + */ + gpio-en-sub-s5-rails = &gpio_sb_2; + }; + + temp_memory: memory { + compatible = "cros-ec,temp-sensor-thermistor"; + thermistor = <&thermistor_3V3_51K1_47K_4050B>; + adc = <&adc_temp_sensor_1>; + }; + temp_charger: charger { + compatible = "cros-ec,temp-sensor-thermistor"; + thermistor = <&thermistor_3V3_51K1_47K_4050B>; + adc = <&adc_temp_sensor_2>; + }; + temp_ambient: ambient { + compatible = "cros-ec,temp-sensor-thermistor"; + thermistor = <&thermistor_3V3_51K1_47K_4050B>; + adc = <&adc_temp_sensor_3>; + }; + + named-temp-sensors { + compatible = "cros-ec,temp-sensors"; + memory { + temp_fan_off = <35>; + temp_fan_max = <60>; + temp_host_high = <85>; + temp_host_halt = <90>; + temp_host_release_high = <80>; + power-good-pin = <&gpio_ec_soc_dsw_pwrok>; + sensor = <&temp_memory>; + }; + charger { + temp_fan_off = <35>; + temp_fan_max = <60>; + temp_host_high = <85>; + temp_host_halt = <90>; + temp_host_release_high = <80>; + power-good-pin = <&gpio_ec_soc_dsw_pwrok>; + sensor = <&temp_charger>; + }; + ambient { + temp_fan_off = <35>; + temp_fan_max = <60>; + temp_host_high = <85>; + temp_host_halt = <90>; + temp_host_release_high = <80>; + power-good-pin = <&gpio_ec_soc_dsw_pwrok>; + sensor = <&temp_ambient>; + }; + }; + + usba { + compatible = "cros-ec,usba-port-enable-pins"; + /* + * sb_2 is only configured as GPIO when USB-A1 is present, + * but it's still safe to control when disabled. + * + * ILIM_SEL pins are referred to by legacy enum name, + * GPIO_USB*_ILIM_SEL. The one for port A1 is unused on + * sub-boards that don't have USB-A so is safe to control + * regardless of system configuration. + */ + enable-pins = <&gpio_en_usb_a0_vbus &gpio_sb_2>; + status = "okay"; + }; + + usbc { + #address-cells = <1>; + #size-cells = <0>; + + port0@0 { + compatible = "named-usbc-port"; + reg = <0>; + bc12 = <&bc12_port0>; + chg = <&chg_port0>; + usb-mux-chain-0 { + compatible = "cros-ec,usb-mux-chain"; + usb-muxes = <&virtual_mux_0>; + }; + }; + port0-muxes { + virtual_mux_0: virtual-mux-0 { + compatible = "cros-ec,usbc-mux-virtual"; + }; + }; + /* + * TODO(b:211693800): port1 may not be present on some + * sub-boards. + */ + port1@1 { + compatible = "named-usbc-port"; + reg = <1>; + bc12 = <&bc12_port1>; + chg = <&chg_port1>; + usb-mux-chain-1 { + compatible = "cros-ec,usb-mux-chain"; + usb-muxes = <&virtual_mux_1 &anx7483_mux_1>; + }; + usb_mux_chain_1_no_mux: usb-mux-chain-1-no-mux { + compatible = "cros-ec,usb-mux-chain"; + alternative-chain; + usb-muxes = <&virtual_mux_1>; + }; + }; + port1-muxes { + virtual_mux_1: virtual-mux-1 { + compatible = "cros-ec,usbc-mux-virtual"; + }; + }; + }; + + kblight { + compatible = "cros-ec,kblight-pwm"; + pwms = <&pwm6 6 PWM_HZ(2400) PWM_POLARITY_NORMAL>; + }; +}; + +&thermistor_3V3_51K1_47K_4050B { + status = "okay"; +}; + +&adc_ec_vsense_pp3300_s5 { + /* + * Voltage divider on input has 47k upper and 220k lower legs with + * 2714 mV full-scale reading on the ADC. Apply the largest possible + * multiplier (without overflowing int32) to get the best possible + * approximation of the actual ratio, but derate by a factor of two to + * ensure unexpectedly high values won't overflow. + */ + mul = <(791261 / 2)>; + div = <(651975 / 2)>; +}; + +/* Set bus speeds for I2C */ +&i2c0_0 { + label = "I2C_EEPROM"; + clock-frequency = <I2C_BITRATE_FAST>; + + cbi_eeprom: eeprom@50 { + compatible = "atmel,at24"; + reg = <0x50>; + size = <2048>; + pagesize = <16>; + address-width = <8>; + timeout = <5>; + }; +}; + +&i2c1_0 { + label = "I2C_SENSOR"; + clock-frequency = <I2C_BITRATE_FAST>; +}; + +&i2c3_0 { + label = "I2C_USB_C0_TCPC"; + clock-frequency = <I2C_BITRATE_FAST_PLUS>; + + bc12_port0: pi3usb9201@5f { + compatible = "pericom,pi3usb9201"; + status = "okay"; + reg = <0x5f>; + /* + * BC1.2 interrupt is shared with TCPC, so + * IRQ is not specified here and handled by + * usb_c0_interrupt. + */ + }; + + chg_port0: isl923x@9 { + compatible = "intersil,isl923x"; + status = "okay"; + reg = <0x9>; + }; +}; + +&i2c5_1 { + label = "I2C_SUB_C1_TCPC"; + clock-frequency = <I2C_BITRATE_FAST_PLUS>; + + bc12_port1: pi3usb9201@5f { + compatible = "pericom,pi3usb9201"; + status = "okay"; + reg = <0x5f>; + }; + + chg_port1: isl923x@9 { + compatible = "intersil,isl923x"; + status = "okay"; + reg = <0x9>; + }; + + anx7483_mux_1: anx7483-mux-1@3e { + compatible = "analogix,anx7483"; + reg = <0x3e>; + board-set = "anx7483_set_default_tuning"; + }; +}; + +&i2c7_0 { + label = "I2C_BATTERY"; + clock-frequency = <I2C_BITRATE_STANDARD>; +}; + +&pwm6 { + status = "okay"; + clock-bus = "NPCX_CLOCK_BUS_LFCLK"; + pinctrl-0 = <&pwm6_gpc0>; + pinctrl-names = "default"; +}; + +/* host interface */ +&espi0 { + status = "okay"; + pinctrl-0 = <&espi_lpc_gp46_47_51_52_53_54_55_57>; + pinctrl-names = "default"; +}; diff --git a/zephyr/projects/nissa/craask/power_signals.dtsi b/zephyr/projects/nissa/craask/power_signals.dtsi new file mode 100644 index 0000000000..1d2b23069d --- /dev/null +++ b/zephyr/projects/nissa/craask/power_signals.dtsi @@ -0,0 +1,220 @@ +/* Copyright 2022 The ChromiumOS Authors + * Use of this source code is governed by a BSD-style license that can be + * found in the LICENSE file. + */ + +/ { + chosen { + intel-ap-pwrseq,espi = &espi0; + }; + + common-pwrseq { + compatible = "intel,ap-pwrseq"; + + sys-pwrok-delay = <10>; + all-sys-pwrgd-timeout = <20>; + }; + + pwr-en-pp5000-s5 { + compatible = "intel,ap-pwrseq-gpio"; + dbg-label = "PP5000_S5 enable output to regulator"; + enum-name = "PWR_EN_PP5000_A"; + gpios = <&gpio4 0 0>; + output; + }; + pwr-en-pp3300-s5 { + compatible = "intel,ap-pwrseq-gpio"; + dbg-label = "PP3300_S5 enable output to LS"; + enum-name = "PWR_EN_PP3300_A"; + gpios = <&gpiob 6 0>; + output; + }; + pwr-pg-ec-rsmrst-od { + compatible = "intel,ap-pwrseq-gpio"; + dbg-label = "RSMRST power good from regulator"; + enum-name = "PWR_RSMRST"; + gpios = <&gpio9 4 0>; + interrupt-flags = <GPIO_INT_EDGE_BOTH>; + }; + pwr-ec-pch-rsmrst-odl { + compatible = "intel,ap-pwrseq-gpio"; + dbg-label = "RSMRST output to PCH"; + enum-name = "PWR_EC_PCH_RSMRST"; + gpios = <&gpioa 6 0>; + output; + }; + pwr-slp-s0-l { + compatible = "intel,ap-pwrseq-gpio"; + dbg-label = "SLP_S0_L input from PCH"; + enum-name = "PWR_SLP_S0"; + gpios = <&gpio9 7 GPIO_ACTIVE_LOW>; + interrupt-flags = <GPIO_INT_EDGE_BOTH>; + }; + pwr-slp-s3-l { + compatible = "intel,ap-pwrseq-gpio"; + dbg-label = "SLP_S3_L input from PCH"; + enum-name = "PWR_SLP_S3"; + gpios = <&gpioa 5 GPIO_ACTIVE_LOW>; + interrupt-flags = <GPIO_INT_EDGE_BOTH>; + }; + pwr-slp-sus-l { + compatible = "intel,ap-pwrseq-gpio"; + dbg-label = "SLP_SUS_L input from PCH"; + enum-name = "PWR_SLP_SUS"; + gpios = <&gpio6 2 GPIO_ACTIVE_LOW>; + interrupt-flags = <GPIO_INT_EDGE_BOTH>; + }; + pwr-ec-soc-dsw-pwrok { + compatible = "intel,ap-pwrseq-gpio"; + dbg-label = "DSW_PWROK output to PCH"; + enum-name = "PWR_EC_SOC_DSW_PWROK"; + gpios = <&gpio6 1 0>; + output; + }; + pwr-vccst-pwrgd-od { + compatible = "intel,ap-pwrseq-gpio"; + dbg-label = "VCCST_PWRGD output to PCH"; + enum-name = "PWR_VCCST_PWRGD"; + gpios = <&gpioa 4 GPIO_OPEN_DRAIN>; + output; + }; + pwr-imvp9-vrrdy-od { + compatible = "intel,ap-pwrseq-gpio"; + dbg-label = "VRRDY input from IMVP9"; + enum-name = "PWR_IMVP9_VRRDY"; + gpios = <&gpio4 3 0>; + }; + pwr-pch-pwrok { + compatible = "intel,ap-pwrseq-gpio"; + dbg-label = "PCH_PWROK output to PCH"; + enum-name = "PWR_PCH_PWROK"; + gpios = <&gpio7 2 GPIO_OPEN_DRAIN>; + output; + }; + pwr-ec-pch-sys-pwrok { + compatible = "intel,ap-pwrseq-gpio"; + dbg-label = "SYS_PWROK output to PCH"; + enum-name = "PWR_EC_PCH_SYS_PWROK"; + gpios = <&gpio3 7 0>; + output; + }; + pwr-sys-rst-l { + compatible = "intel,ap-pwrseq-gpio"; + dbg-label = "SYS_RESET# output to PCH"; + enum-name = "PWR_SYS_RST"; + gpios = <&gpioc 5 (GPIO_ACTIVE_LOW|GPIO_OPEN_DRAIN)>; + output; + }; + pwr-slp-s4 { + compatible = "intel,ap-pwrseq-vw"; + dbg-label = "SLP_S4 virtual wire input from PCH"; + enum-name = "PWR_SLP_S4"; + virtual-wire = "ESPI_VWIRE_SIGNAL_SLP_S4"; + vw-invert; + }; + pwr-slp-s5 { + compatible = "intel,ap-pwrseq-vw"; + dbg-label = "SLP_S5 virtual wire input from PCH"; + enum-name = "PWR_SLP_S5"; + virtual-wire = "ESPI_VWIRE_SIGNAL_SLP_S5"; + vw-invert; + }; + pwr-all-sys-pwrgd { + compatible = "intel,ap-pwrseq-external"; + dbg-label = "Combined all power good"; + enum-name = "PWR_ALL_SYS_PWRGD"; + }; + pwr-adc-pp3300 { + compatible = "intel,ap-pwrseq-adc"; + dbg-label = "PP3300 PWROK (from ADC)"; + enum-name = "PWR_DSW_PWROK"; + trigger-high = <&cmp_pp3300_s5_high>; + trigger-low = <&cmp_pp3300_s5_low>; + }; + pwr-adc-pp1p05 { + compatible = "intel,ap-pwrseq-adc"; + dbg-label = "PP1P05 PWROK (from ADC)"; + enum-name = "PWR_PG_PP1P05"; + trigger-high = <&cmp_pp1p05_high>; + trigger-low = <&cmp_pp1p05_low>; + }; + + adc-cmp { + cmp_pp3300_s5_high: pp3300_high { + compatible = "nuvoton,adc-cmp"; + io-channels = <&adc0 6>; + comparison = "ADC_CMP_NPCX_GREATER"; + /* + * This is 90% of nominal voltage considering voltage + * divider on ADC input. + */ + threshold-mv = <2448>; + }; + cmp_pp3300_s5_low: pp3300_low { + compatible = "nuvoton,adc-cmp"; + io-channels = <&adc0 6>; + comparison = "ADC_CMP_NPCX_LESS_OR_EQUAL"; + threshold-mv = <2448>; + }; + cmp_pp1p05_high: pp1p05_high { + compatible = "nuvoton,adc-cmp"; + io-channels = <&adc0 4>; + comparison = "ADC_CMP_NPCX_GREATER"; + /* Setting at 90% of nominal voltage */ + threshold-mv = <945>; + }; + cmp_pp1p05_low: pp1p05_low { + compatible = "nuvoton,adc-cmp"; + io-channels = <&adc0 4>; + comparison = "ADC_CMP_NPCX_LESS_OR_EQUAL"; + threshold-mv = <945>; + }; + }; +}; + +/* + * Because the power signals directly reference the GPIOs, + * the correspinding named-gpios need to have no-auto-init set. + */ +&gpio_ec_soc_dsw_pwrok { + no-auto-init; +}; +&gpio_ec_soc_pch_pwrok_od { + no-auto-init; +}; +&gpio_ec_soc_rsmrst_l { + no-auto-init; +}; +&gpio_ec_soc_sys_pwrok { + no-auto-init; +}; +&gpio_ec_soc_vccst_pwrgd_od { + no-auto-init; +}; +&gpio_en_pp3300_s5 { + no-auto-init; +}; +&gpio_en_pp5000_s5 { + no-auto-init; +}; +&gpio_imvp91_vrrdy_od { + no-auto-init; +}; +&gpio_rsmrst_pwrgd_l { + no-auto-init; +}; +&gpio_slp_s0_l { + no-auto-init; +}; +&gpio_slp_s3_l { + no-auto-init; +}; +&gpio_slp_s4_l { + no-auto-init; +}; +&gpio_slp_sus_l { + no-auto-init; +}; +&gpio_sys_rst_odl { + no-auto-init; +}; diff --git a/zephyr/projects/nissa/craask/project.conf b/zephyr/projects/nissa/craask/project.conf new file mode 100644 index 0000000000..b7f31cee63 --- /dev/null +++ b/zephyr/projects/nissa/craask/project.conf @@ -0,0 +1,15 @@ +# Copyright 2022 The ChromiumOS Authors +# Use of this source code is governed by a BSD-style license that can be +# found in the LICENSE file. + +CONFIG_BOARD_CRAASK=y +CONFIG_PLATFORM_EC_OCPC=y + +# Sensor drivers +CONFIG_PLATFORM_EC_ACCELGYRO_LSM6DSO=y +CONFIG_PLATFORM_EC_ACCEL_BMA4XX=y +CONFIG_PLATFORM_EC_ACCELGYRO_BMI_COMM_I2C=y +CONFIG_PLATFORM_EC_ACCELGYRO_BMI3XX=y +CONFIG_PLATFORM_EC_DYNAMIC_MOTION_SENSOR_COUNT=y + +CONFIG_PLATFORM_EC_BUTTONS_RUNTIME_CONFIG=y diff --git a/zephyr/projects/nissa/craask/project.overlay b/zephyr/projects/nissa/craask/project.overlay new file mode 100644 index 0000000000..9ca681d979 --- /dev/null +++ b/zephyr/projects/nissa/craask/project.overlay @@ -0,0 +1,14 @@ +/* Copyright 2022 The ChromiumOS Authors + * Use of this source code is governed by a BSD-style license that can be + * found in the LICENSE file. + */ + +#include "../cbi.dtsi" + +#include "cbi.dtsi" +#include "generated.dtsi" +#include "keyboard.dtsi" +#include "motionsense.dtsi" +#include "overlay.dtsi" +#include "power_signals.dtsi" +#include "pwm_leds.dtsi" diff --git a/zephyr/projects/nissa/craask/pwm_leds.dtsi b/zephyr/projects/nissa/craask/pwm_leds.dtsi new file mode 100644 index 0000000000..e55aa1c9ef --- /dev/null +++ b/zephyr/projects/nissa/craask/pwm_leds.dtsi @@ -0,0 +1,62 @@ +/* Copyright 2022 The ChromiumOS Authors + * Use of this source code is governed by a BSD-style license that can be + * found in the LICENSE file. + */ + +/ { + pwmleds { + compatible = "pwm-leds"; + pwm_led0: pwm_led_0 { + pwms = <&pwm2 2 PWM_HZ(324) PWM_POLARITY_INVERTED>, + <&pwm0 0 PWM_HZ(324) PWM_POLARITY_INVERTED>, + <&pwm1 1 PWM_HZ(324) PWM_POLARITY_INVERTED>; + }; + }; + + cros-pwmleds { + compatible = "cros-ec,pwm-leds"; + + leds = <&pwm_led0>; + + /*<red green blue>*/ + color-map-red = <100 0 0>; + color-map-green = < 0 100 0>; + color-map-blue = < 0 0 100>; + color-map-yellow = < 0 50 50>; + color-map-white = <100 100 100>; + color-map-amber = < 90 10 0>; + + brightness-range = <100 100 100 0 0 0>; + + #address-cells = <1>; + #size-cells = <0>; + + pwm_led_0@0 { + reg = <0>; + ec-led-name = "EC_LED_ID_BATTERY_LED"; + }; + }; +}; + +/* Enable LEDs to work while CPU suspended */ + +&pwm0 { + status = "okay"; + clock-bus = "NPCX_CLOCK_BUS_LFCLK"; + pinctrl-0 = <&pwm0_gpc3>; + pinctrl-names = "default"; +}; + +&pwm1 { + status = "okay"; + clock-bus = "NPCX_CLOCK_BUS_LFCLK"; + pinctrl-0 = <&pwm1_gpc2>; + pinctrl-names = "default"; +}; + +&pwm2 { + status = "okay"; + clock-bus = "NPCX_CLOCK_BUS_LFCLK"; + pinctrl-0 = <&pwm2_gpc4>; + pinctrl-names = "default"; +}; diff --git a/zephyr/projects/nissa/craask/src/charger.c b/zephyr/projects/nissa/craask/src/charger.c new file mode 100644 index 0000000000..d4723e4a0a --- /dev/null +++ b/zephyr/projects/nissa/craask/src/charger.c @@ -0,0 +1,56 @@ +/* Copyright 2022 The ChromiumOS Authors + * Use of this source code is governed by a BSD-style license that can be + * found in the LICENSE file. + */ + +#include <zephyr/logging/log.h> + +#include "battery.h" +#include "charger.h" +#include "charger/isl923x_public.h" +#include "console.h" +#include "extpower.h" +#include "usb_pd.h" +#include "nissa_common.h" + +LOG_MODULE_DECLARE(nissa, CONFIG_NISSA_LOG_LEVEL); + +int extpower_is_present(void) +{ + int port; + int rv; + bool acok; + + for (port = 0; port < board_get_usb_pd_port_count(); port++) { + rv = raa489000_is_acok(port, &acok); + if ((rv == EC_SUCCESS) && acok) + return 1; + } + + return 0; +} + +/* + * Craask does not have a GPIO indicating whether extpower is present, + * so detect using the charger(s). + */ +__override void board_check_extpower(void) +{ + static int last_extpower_present; + int extpower_present = extpower_is_present(); + + if (last_extpower_present ^ extpower_present) + extpower_handle_update(extpower_present); + + last_extpower_present = extpower_present; +} + +__override void board_hibernate(void) +{ + /* Shut down the chargers */ + if (board_get_usb_pd_port_count() == 2) + raa489000_hibernate(CHARGER_SECONDARY, true); + raa489000_hibernate(CHARGER_PRIMARY, true); + LOG_INF("Charger(s) hibernated"); + cflush(); +} diff --git a/zephyr/projects/nissa/craask/src/form_factor.c b/zephyr/projects/nissa/craask/src/form_factor.c new file mode 100644 index 0000000000..59869eaa2f --- /dev/null +++ b/zephyr/projects/nissa/craask/src/form_factor.c @@ -0,0 +1,121 @@ +/* Copyright 2022 The ChromiumOS Authors + * Use of this source code is governed by a BSD-style license that can be + * found in the LICENSE file. + */ + +#include <zephyr/devicetree.h> +#include <zephyr/logging/log.h> + +#include "accelgyro.h" +#include "button.h" +#include "cros_board_info.h" +#include "cros_cbi.h" +#include "driver/accelgyro_bmi323.h" +#include "driver/accelgyro_lsm6dso.h" +#include "gpio/gpio_int.h" +#include "hooks.h" +#include "motionsense_sensors.h" +#include "motion_sense.h" +#include "tablet_mode.h" + +#include "nissa_common.h" + +LOG_MODULE_DECLARE(nissa, CONFIG_NISSA_LOG_LEVEL); + +/* + * Mainboard orientation support. + */ + +#define LIS_ALT_MAT SENSOR_ROT_STD_REF_NAME(DT_NODELABEL(lid_rot_bma422)) +#define BMA_ALT_MAT SENSOR_ROT_STD_REF_NAME(DT_NODELABEL(lid_rot_ref)) +#define ALT_MAT SENSOR_ROT_STD_REF_NAME(DT_NODELABEL(base_rot_ver1)) +#define LID_SENSOR SENSOR_ID(DT_NODELABEL(lid_accel)) +#define BASE_SENSOR SENSOR_ID(DT_NODELABEL(base_accel)) +#define BASE_GYRO SENSOR_ID(DT_NODELABEL(base_gyro)) +#define ALT_LID_S SENSOR_ID(DT_NODELABEL(alt_lid_accel)) + +static bool use_alt_sensor; + +void motion_interrupt(enum gpio_signal signal) +{ + if (use_alt_sensor) + bmi3xx_interrupt(signal); + else + lsm6dso_interrupt(signal); +} + +static void form_factor_init(void) +{ + int ret; + uint32_t val; + enum nissa_sub_board_type sb = nissa_get_sb_type(); + + ret = cbi_get_board_version(&val); + if (ret != EC_SUCCESS) { + LOG_ERR("Error retrieving CBI BOARD_VER."); + return; + } + /* + * The volume up/down button are exchanged on ver3 USB + * sub board. + * + * LTE: + * volup -> gpioa2, voldn -> gpio93 + * USB: + * volup -> gpio93, voldn -> gpioa2 + */ + if (val == 3 && sb == NISSA_SB_C_A) { + LOG_INF("Volume up/down btn exchanged on ver3 USB sku"); + buttons[BUTTON_VOLUME_UP].gpio = GPIO_VOLUME_DOWN_L; + buttons[BUTTON_VOLUME_DOWN].gpio = GPIO_VOLUME_UP_L; + } + + /* + * If the board version is 1 + * use ver1 rotation matrix. + */ + if (val == 1) { + LOG_INF("Switching to ver1 base"); + motion_sensors[BASE_SENSOR].rot_standard_ref = &ALT_MAT; + motion_sensors[BASE_GYRO].rot_standard_ref = &ALT_MAT; + } + + /* + * If the firmware config indicates + * an craaskbowl form factor, use the alternative + * rotation matrix. + */ + ret = cros_cbi_get_fw_config(FW_LID_INVERSION, &val); + if (ret != 0) { + LOG_ERR("Error retrieving CBI FW_CONFIG field %d", + FW_LID_INVERSION); + return; + } + if (val == FW_LID_XY_ROT_180) { + LOG_INF("Lid sensor placement rotate 180 on xy plane"); + motion_sensors[LID_SENSOR].rot_standard_ref = &LIS_ALT_MAT; + motion_sensors_alt[ALT_LID_S].rot_standard_ref = &BMA_ALT_MAT; + } + + /* check which base sensor is used for motion_interrupt */ + use_alt_sensor = cros_cbi_ssfc_check_match( + CBI_SSFC_VALUE_ID(DT_NODELABEL(base_sensor_1))); + + motion_sensors_check_ssfc(); + + /* Check if it's clamshell or convertible */ + ret = cros_cbi_get_fw_config(FORM_FACTOR, &val); + if (ret != 0) { + LOG_ERR("Error retrieving CBI FW_CONFIG field %d", FORM_FACTOR); + return; + } + if (val == CLAMSHELL) { + LOG_INF("Clamshell: disable motionsense function."); + motion_sensor_count = 0; + gmr_tablet_switch_disable(); + gpio_disable_dt_interrupt(GPIO_INT_FROM_NODELABEL(int_imu)); + gpio_pin_configure_dt(GPIO_DT_FROM_NODELABEL(gpio_imu_int_l), + GPIO_DISCONNECTED); + } +} +DECLARE_HOOK(HOOK_INIT, form_factor_init, HOOK_PRIO_POST_I2C); diff --git a/zephyr/projects/nissa/craask/src/keyboard.c b/zephyr/projects/nissa/craask/src/keyboard.c new file mode 100644 index 0000000000..65229eb43f --- /dev/null +++ b/zephyr/projects/nissa/craask/src/keyboard.c @@ -0,0 +1,29 @@ +/* Copyright 2022 The ChromiumOS Authors + * Use of this source code is governed by a BSD-style license that can be + * found in the LICENSE file. + */ + +#include "ec_commands.h" + +static const struct ec_response_keybd_config craask_kb = { + .num_top_row_keys = 10, + .action_keys = { + TK_BACK, /* T1 */ + TK_REFRESH, /* T2 */ + TK_FULLSCREEN, /* T3 */ + TK_OVERVIEW, /* T4 */ + TK_SNAPSHOT, /* 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) +{ + return &craask_kb; +} diff --git a/zephyr/projects/nissa/craask/src/led.c b/zephyr/projects/nissa/craask/src/led.c new file mode 100644 index 0000000000..0af0202cf4 --- /dev/null +++ b/zephyr/projects/nissa/craask/src/led.c @@ -0,0 +1,56 @@ +/* Copyright 2022 The ChromiumOS Authors + * Use of this source code is governed by a BSD-style license that can be + * found in the LICENSE file. + * + * Battery LED control for nissa + */ +#include "common.h" +#include "ec_commands.h" +#include "led_common.h" +#include "led_onoff_states.h" +#include "led_pwm.h" + +__override const int led_charge_lvl_1 = 5; +__override const int led_charge_lvl_2 = 97; +__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_S0_BAT_LOW] = { { EC_LED_COLOR_AMBER, + 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_AMBER, + 2 * LED_ONE_SEC }, + { EC_LED_COLOR_BLUE, + 2 * LED_ONE_SEC } }, + }; + +__override void led_set_color_battery(enum ec_led_colors color) +{ + switch (color) { + case EC_LED_COLOR_RED: + set_pwm_led_color(EC_LED_ID_BATTERY_LED, EC_LED_COLOR_RED); + break; + case EC_LED_COLOR_BLUE: + set_pwm_led_color(EC_LED_ID_BATTERY_LED, EC_LED_COLOR_BLUE); + break; + case EC_LED_COLOR_AMBER: + set_pwm_led_color(EC_LED_ID_BATTERY_LED, EC_LED_COLOR_AMBER); + break; + default: /* LED_OFF and other unsupported colors */ + set_pwm_led_color(EC_LED_ID_BATTERY_LED, -1); + break; + } +} diff --git a/zephyr/projects/nissa/craask/src/usbc.c b/zephyr/projects/nissa/craask/src/usbc.c new file mode 100644 index 0000000000..a15460a212 --- /dev/null +++ b/zephyr/projects/nissa/craask/src/usbc.c @@ -0,0 +1,277 @@ +/* Copyright 2022 The ChromiumOS Authors + * Use of this source code is governed by a BSD-style license that can be + * found in the LICENSE file. + */ + +#include <zephyr/logging/log.h> + +#include "charge_state_v2.h" +#include "chipset.h" +#include "hooks.h" +#include "usb_mux.h" +#include "system.h" +#include "driver/charger/isl923x_public.h" +#include "driver/retimer/anx7483_public.h" +#include "driver/tcpm/tcpci.h" +#include "driver/tcpm/raa489000.h" + +#include "nissa_common.h" + +LOG_MODULE_DECLARE(nissa, CONFIG_NISSA_LOG_LEVEL); + +struct tcpc_config_t tcpc_config[CONFIG_USB_PD_PORT_MAX_COUNT] = { + { + .bus_type = EC_BUS_TYPE_I2C, + .i2c_info = { + .port = I2C_PORT_USB_C0_TCPC, + .addr_flags = RAA489000_TCPC0_I2C_FLAGS, + }, + .drv = &raa489000_tcpm_drv, + /* RAA489000 implements TCPCI 2.0 */ + .flags = TCPC_FLAGS_TCPCI_REV2_0 | + TCPC_FLAGS_VBUS_MONITOR, + }, + { /* sub-board */ + .bus_type = EC_BUS_TYPE_I2C, + .i2c_info = { + .port = I2C_PORT_USB_C1_TCPC, + .addr_flags = RAA489000_TCPC0_I2C_FLAGS, + }, + .drv = &raa489000_tcpm_drv, + /* RAA489000 implements TCPCI 2.0 */ + .flags = TCPC_FLAGS_TCPCI_REV2_0 | + TCPC_FLAGS_VBUS_MONITOR, + }, +}; + +int board_is_sourcing_vbus(int port) +{ + int regval; + + tcpc_read(port, TCPC_REG_POWER_STATUS, ®val); + return !!(regval & TCPC_REG_POWER_STATUS_SOURCING_VBUS); +} + +int board_set_active_charge_port(int port) +{ + int is_real_port = (port >= 0 && port < CONFIG_USB_PD_PORT_MAX_COUNT); + int i; + int old_port; + + if (!is_real_port && port != CHARGE_PORT_NONE) + return EC_ERROR_INVAL; + + old_port = charge_manager_get_active_charge_port(); + + LOG_INF("New chg p%d", port); + + /* Disable all ports. */ + if (port == CHARGE_PORT_NONE) { + for (i = 0; i < CONFIG_USB_PD_PORT_MAX_COUNT; i++) { + tcpc_write(i, TCPC_REG_COMMAND, + TCPC_REG_COMMAND_SNK_CTRL_LOW); + raa489000_enable_asgate(i, false); + } + + return EC_SUCCESS; + } + + /* Check if port is sourcing VBUS. */ + if (board_is_sourcing_vbus(port)) { + LOG_WRN("Skip enable p%d", port); + return EC_ERROR_INVAL; + } + + /* + * Turn off the other ports' sink path FETs, before enabling the + * requested charge port. + */ + for (i = 0; i < CONFIG_USB_PD_PORT_MAX_COUNT; i++) { + if (i == port) + continue; + + if (tcpc_write(i, TCPC_REG_COMMAND, + TCPC_REG_COMMAND_SNK_CTRL_LOW)) + LOG_WRN("p%d: sink path disable failed.", i); + raa489000_enable_asgate(i, false); + } + + /* + * Stop the charger IC from switching while changing ports. Otherwise, + * we can overcurrent the adapter we're switching to. (crbug.com/926056) + */ + if (old_port != CHARGE_PORT_NONE) + charger_discharge_on_ac(1); + + /* Enable requested charge port. */ + if (raa489000_enable_asgate(port, true) || + tcpc_write(port, TCPC_REG_COMMAND, + TCPC_REG_COMMAND_SNK_CTRL_HIGH)) { + LOG_WRN("p%d: sink path enable failed.", port); + charger_discharge_on_ac(0); + return EC_ERROR_UNKNOWN; + } + + /* Allow the charger IC to begin/continue switching. */ + charger_discharge_on_ac(0); + + return EC_SUCCESS; +} + +uint16_t tcpc_get_alert_status(void) +{ + uint16_t status = 0; + int regval; + + /* + * The interrupt line is shared between the TCPC and BC1.2 detector IC. + * Therefore, go out and actually read the alert registers to report the + * alert status. + */ + if (!gpio_pin_get_dt(GPIO_DT_FROM_NODELABEL(gpio_usb_c0_int_odl))) { + if (!tcpc_read16(0, TCPC_REG_ALERT, ®val)) { + /* The TCPCI Rev 1.0 spec says to ignore bits 14:12. */ + if (!(tcpc_config[0].flags & TCPC_FLAGS_TCPCI_REV2_0)) + regval &= ~((1 << 14) | (1 << 13) | (1 << 12)); + + if (regval) + status |= PD_STATUS_TCPC_ALERT_0; + } + } + + if (board_get_usb_pd_port_count() == 2 && + !gpio_pin_get_dt(GPIO_DT_FROM_ALIAS(gpio_usb_c1_int_odl))) { + if (!tcpc_read16(1, TCPC_REG_ALERT, ®val)) { + /* TCPCI spec Rev 1.0 says to ignore bits 14:12. */ + if (!(tcpc_config[1].flags & TCPC_FLAGS_TCPCI_REV2_0)) + regval &= ~((1 << 14) | (1 << 13) | (1 << 12)); + + if (regval) + status |= PD_STATUS_TCPC_ALERT_1; + } + } + + return status; +} + +void pd_power_supply_reset(int port) +{ + /* Disable VBUS */ + tcpc_write(port, TCPC_REG_COMMAND, TCPC_REG_COMMAND_SRC_CTRL_LOW); + + /* Notify host of power info change. */ + pd_send_host_event(PD_EVENT_POWER_CHANGE); +} + +__override void typec_set_source_current_limit(int port, enum tcpc_rp_value rp) +{ + if (port < 0 || port >= CONFIG_USB_PD_PORT_MAX_COUNT) + return; + + raa489000_set_output_current(port, rp); +} + +int pd_set_power_supply_ready(int port) +{ + int rv; + + if (port >= CONFIG_USB_PD_PORT_MAX_COUNT) + return EC_ERROR_INVAL; + + /* Disable charging. */ + rv = tcpc_write(port, TCPC_REG_COMMAND, TCPC_REG_COMMAND_SNK_CTRL_LOW); + if (rv) + return rv; + + /* Our policy is not to source VBUS when the AP is off. */ + if (chipset_in_state(CHIPSET_STATE_ANY_OFF)) + return EC_ERROR_NOT_POWERED; + + /* Provide Vbus. */ + rv = tcpc_write(port, TCPC_REG_COMMAND, TCPC_REG_COMMAND_SRC_CTRL_HIGH); + if (rv) + return rv; + + rv = raa489000_enable_asgate(port, true); + if (rv) + return rv; + + /* Notify host of power info change. */ + pd_send_host_event(PD_EVENT_POWER_CHANGE); + + return EC_SUCCESS; +} + +void board_reset_pd_mcu(void) +{ + /* + * TODO(b:147316511): could send a reset command to the TCPC here + * if needed. + */ +} + +/* + * Because the TCPCs and BC1.2 chips share interrupt lines, it's possible + * for an interrupt to be lost if one asserts the IRQ, the other does the same + * then the first releases it: there will only be one falling edge to trigger + * the interrupt, and the line will be held low. We handle this by running a + * deferred check after a falling edge to see whether the IRQ is still being + * asserted. If it is, we assume an interrupt may have been lost and we need + * to poll each chip for events again. + */ +#define USBC_INT_POLL_DELAY_US 5000 + +static void poll_c0_int(void); +DECLARE_DEFERRED(poll_c0_int); +static void poll_c1_int(void); +DECLARE_DEFERRED(poll_c1_int); + +static void usbc_interrupt_trigger(int port) +{ + schedule_deferred_pd_interrupt(port); + usb_charger_task_set_event(port, USB_CHG_EVENT_BC12); +} + +static inline void poll_usb_gpio(int port, const struct gpio_dt_spec *gpio, + const struct deferred_data *ud) +{ + if (!gpio_pin_get_dt(gpio)) { + usbc_interrupt_trigger(port); + hook_call_deferred(ud, USBC_INT_POLL_DELAY_US); + } +} + +static void poll_c0_int(void) +{ + poll_usb_gpio(0, GPIO_DT_FROM_NODELABEL(gpio_usb_c0_int_odl), + &poll_c0_int_data); +} + +static void poll_c1_int(void) +{ + poll_usb_gpio(1, GPIO_DT_FROM_ALIAS(gpio_usb_c1_int_odl), + &poll_c1_int_data); +} + +void usb_interrupt(enum gpio_signal signal) +{ + int port; + const struct deferred_data *ud; + + if (signal == GPIO_SIGNAL(DT_NODELABEL(gpio_usb_c0_int_odl))) { + port = 0; + ud = &poll_c0_int_data; + } else { + port = 1; + ud = &poll_c1_int_data; + } + /* + * We've just been called from a falling edge, so there's definitely + * no lost IRQ right now. Cancel any pending check. + */ + hook_call_deferred(ud, -1); + /* Trigger polling of TCPC and BC1.2 in respective tasks */ + usbc_interrupt_trigger(port); + /* Check for lost interrupts in a bit */ + hook_call_deferred(ud, USBC_INT_POLL_DELAY_US); +} diff --git a/zephyr/projects/nissa/include/nissa_common.h b/zephyr/projects/nissa/include/nissa_common.h new file mode 100644 index 0000000000..7cdaba2e50 --- /dev/null +++ b/zephyr/projects/nissa/include/nissa_common.h @@ -0,0 +1,23 @@ +/* Copyright 2022 The ChromiumOS Authors + * Use of this source code is governed by a BSD-style license that can be + * found in the LICENSE file. + */ + +/* Nissa common declarations */ + +#ifndef __CROS_EC_NISSA_NISSA_COMMON_H__ +#define __CROS_EC_NISSA_NISSA_COMMON_H__ + +#include "usb_mux.h" + +enum nissa_sub_board_type { + NISSA_SB_UNKNOWN = -1, /* Uninitialised */ + NISSA_SB_NONE = 0, /* No board defined */ + NISSA_SB_C_A = 1, /* USB type C, USB type A */ + NISSA_SB_C_LTE = 2, /* USB type C, WWAN LTE */ + NISSA_SB_HDMI_A = 3, /* HDMI, USB type A */ +}; + +enum nissa_sub_board_type nissa_get_sb_type(void); + +#endif /* __CROS_EC_NISSA_NISSA_COMMON_H__ */ diff --git a/zephyr/projects/nissa/include/nissa_hdmi.h b/zephyr/projects/nissa/include/nissa_hdmi.h new file mode 100644 index 0000000000..9f2f533ba7 --- /dev/null +++ b/zephyr/projects/nissa/include/nissa_hdmi.h @@ -0,0 +1,55 @@ +/* Copyright 2022 The ChromiumOS Authors + * Use of this source code is governed by a BSD-style license that can be + * found in the LICENSE file. + */ + +/* Nissa shared HDMI sub-board functionality */ + +#ifndef __CROS_EC_NISSA_NISSA_HDMI_H__ +#define __CROS_EC_NISSA_NISSA_HDMI_H__ + +#include "common.h" + +/** True if the board supports an HDMI sub-board. */ +#define NISSA_BOARD_HAS_HDMI_SUPPORT DT_NODE_EXISTS(DT_NODELABEL(gpio_hdmi_sel)) + +/** + * Configure the GPIO that controls core rails on the HDMI sub-board. + * + * This is the gpio_en_rails_odl pin, which is configured as active-low + * open-drain output to enable power to the HDMI sub-board (typically when the + * AP is in S5 or above). + * + * This function must be called if the pin is connected to the HDMI board and + * power is not enabled by default. + */ +void nissa_configure_hdmi_rails(void); + +/** + * Configure the GPIO that controls the HDMI VCC pin on the HDMI sub-board. + * + * This is the gpio_hdmi_en_odl pin, which is configured as active-low + * open-drain output to enable the VCC pin on the HDMI connector (typically when + * the AP is on, in S0 or S0ix). + * + * This function must be called if the pin is connected to the HDMI board and + * VCC is not enabled by default. + */ +void nissa_configure_hdmi_vcc(void); + +/** + * Configure the GPIOS controlling HDMI sub-board power (core rails and VCC). + * + * This function is called from shared code while configuring sub-boards, and + * used if an HDMI sub-board is present. The default implementation enables the + * core rails control pin (nissa_configure_hdmi_rails) but not VCC + * (nissa_configure_hdmi_vcc), assuming that the pin for VCC is not connected + * connected on most boards (and that VCC will be turned on whenever the core + * rails are turned on). + * + * A board should override this function if it needs to enable more IOs for + * HDMI, or if some pins need to be conditionally enabled. + */ +__override_proto void nissa_configure_hdmi_power_gpios(void); + +#endif /* __CROS_EC_NISSA_NISSA_HDMI_H__ */ diff --git a/zephyr/projects/nissa/it8xxx2_program.conf b/zephyr/projects/nissa/it8xxx2_program.conf new file mode 100644 index 0000000000..3272c04209 --- /dev/null +++ b/zephyr/projects/nissa/it8xxx2_program.conf @@ -0,0 +1,62 @@ +# Copyright 2022 The ChromiumOS Authors +# Use of this source code is governed by a BSD-style license that can be +# found in the LICENSE file. + +CONFIG_CROS_FLASH_IT8XXX2=y +CONFIG_CROS_SYSTEM_IT8XXX2=y +CONFIG_ESPI_IT8XXX2=y +CONFIG_FPU=y +# rv32iafc/ilp32f is not supported by the toolchain, so use soft-float +CONFIG_FLOAT_HARD=n + +# EC performance is bad; limiting sensor data rate helps keep it from degrading +# so much that it causes problems. b/240485526, b/230818312 +CONFIG_PLATFORM_EC_MAX_SENSOR_FREQ_MILLIHZ=100000 + +# Allow more time for the charger to stabilise +CONFIG_PLATFORM_EC_POWER_BUTTON_INIT_TIMEOUT=5 + +# ITE has more space, so don't restrict shell +CONFIG_SHELL_MINIMAL=n + +# RAM savings, since this chip is tight on available RAM. +# It's useful to store a lot of logs for the host to request, but the default 4k +# is pretty large. +CONFIG_PLATFORM_EC_HOSTCMD_CONSOLE_BUF_SIZE=2048 +# Our threads have short names, save 20 bytes per thread +CONFIG_THREAD_MAX_NAME_LEN=12 +# Task stacks, tuned by experiment. Most expanded to prevent overflow, and a few +# shrunk to save RAM. +CONFIG_AP_PWRSEQ_STACK_SIZE=1408 +CONFIG_TASK_HOSTCMD_STACK_SIZE=1280 +CONFIG_TASK_MOTIONSENSE_STACK_SIZE=1280 +CONFIG_TASK_PD_INT_STACK_SIZE=1280 + +# TCPC+PPC: ITE on-chip for C0, PS8745 for optional C1 +CONFIG_PLATFORM_EC_USB_PD_TCPM_ITE_ON_CHIP=y +CONFIG_PLATFORM_EC_USB_PD_TCPM_DRIVER_IT8XXX2=y +CONFIG_PLATFORM_EC_USB_PD_TCPM_PS8745=y +CONFIG_PLATFORM_EC_USB_PD_VBUS_DETECT_CHARGER=y +# SM5803 controls power path on both ports +CONFIG_PLATFORM_EC_USB_PD_5V_CHARGER_CTRL=y +# SM5803 can discharge VBUS, but not via one of the available options; +# pd_power_supply_reset() does discharge. +CONFIG_PLATFORM_EC_USB_PD_DISCHARGE=n +# The EC is put into programming mode while firmware is running +# (after releasing reset) and PD after being reset will hard-reset +# the port if a contract was already set up. If the system has no +# battery, this will prevent programming because it will brown out +# the system and reset. Inserting a delay gives the programmer more +# time to put the EC into programming mode. +CONFIG_PLATFORM_EC_USB_PD_STARTUP_DELAY_MS=2000 + +# Charger driver and configuration +CONFIG_PLATFORM_EC_OCPC=y +CONFIG_PLATFORM_EC_CHARGER_SM5803=y +CONFIG_PLATFORM_EC_OCPC_DEF_RBATT_MOHMS=21 +CONFIG_PLATFORM_EC_PD_MAX_VOLTAGE_MV=15000 + +# VSENSE: PP3300_S5 & PP1050_PROC +CONFIG_VCMP_IT8XXX2=y +CONFIG_SENSOR=y +CONFIG_SENSOR_SHELL=n diff --git a/zephyr/projects/nissa/joxer/cbi.dtsi b/zephyr/projects/nissa/joxer/cbi.dtsi new file mode 100644 index 0000000000..afbd125b32 --- /dev/null +++ b/zephyr/projects/nissa/joxer/cbi.dtsi @@ -0,0 +1,32 @@ +/* Copyright 2022 The ChromiumOS Authors + * Use of this source code is governed by a BSD-style license that can be + * found in the LICENSE file. + */ + +/ { + nissa-fw-config { + compatible = "cros-ec,cbi-fw-config"; + + /* + * FW_CONFIG field to indicate which keyboard layout + * should be used. + */ + keyboard { + enum-name = "FW_KB_LAYOUT"; + start = <3>; + size = <2>; + + layout-1 { + compatible = "cros-ec,cbi-fw-config-value"; + enum-name = "FW_KB_LAYOUT_DEFAULT"; + value = <0>; + default; + }; + layout-2 { + compatible = "cros-ec,cbi-fw-config-value"; + enum-name = "FW_KB_LAYOUT_US2"; + value = <1>; + }; + }; + }; +}; diff --git a/zephyr/projects/nissa/joxer/generated.dtsi b/zephyr/projects/nissa/joxer/generated.dtsi new file mode 100644 index 0000000000..22214b9726 --- /dev/null +++ b/zephyr/projects/nissa/joxer/generated.dtsi @@ -0,0 +1,260 @@ +/* Copyright 2022 The ChromiumOS Authors + * Use of this source code is governed by a BSD-style license that can be + * found in the LICENSE file. + * + * This file is auto-generated - do not edit! + */ + +/ { + + named-adc-channels { + compatible = "named-adc-channels"; + + adc_ec_vsense_pp1050_proc: ec_vsense_pp1050_proc { + enum-name = "ADC_PP1050_PROC"; + io-channels = <&adc0 14>; + }; + adc_ec_vsense_pp3300_s5: ec_vsense_pp3300_s5 { + enum-name = "ADC_PP3300_S5"; + io-channels = <&adc0 0>; + }; + adc_temp_sensor_1: temp_sensor_1 { + enum-name = "ADC_TEMP_SENSOR_1"; + io-channels = <&adc0 2>; + }; + adc_temp_sensor_2: temp_sensor_2 { + enum-name = "ADC_TEMP_SENSOR_2"; + io-channels = <&adc0 3>; + }; + adc_temp_sensor_3: temp_sensor_3 { + enum-name = "ADC_TEMP_SENSOR_3"; + io-channels = <&adc0 13>; + }; + }; + + named-gpios { + compatible = "named-gpios"; + + gpio_acc_int_l: acc_int_l { + gpios = <&gpioc 0 GPIO_INPUT>; + }; + gpio_all_sys_pwrgd: all_sys_pwrgd { + gpios = <&gpiob 7 GPIO_INPUT>; + }; + gpio_ccd_mode_odl: ccd_mode_odl { + gpios = <&gpioh 5 GPIO_INPUT>; + enum-name = "GPIO_CCD_MODE_ODL"; + }; + gpio_cpu_c10_gate_l: cpu_c10_gate_l { + gpios = <&gpiog 1 GPIO_INPUT>; + }; + gpio_ec_battery_pres_odl: ec_battery_pres_odl { + gpios = <&gpioi 4 GPIO_INPUT>; + enum-name = "GPIO_BATT_PRES_ODL"; + }; + gpio_ec_cbi_wp: ec_cbi_wp { + gpios = <&gpioj 5 GPIO_OUTPUT>; + }; + gpio_ec_edp_bl_en_od: ec_edp_bl_en_od { + gpios = <&gpiok 4 GPIO_ODR_HIGH>; + enum-name = "GPIO_ENABLE_BACKLIGHT"; + }; + gpio_ec_entering_rw: ec_entering_rw { + gpios = <&gpioc 7 GPIO_OUTPUT>; + enum-name = "GPIO_ENTERING_RW"; + }; + gpio_ec_gsc_packet_mode: ec_gsc_packet_mode { + gpios = <&gpioh 1 GPIO_OUTPUT>; + enum-name = "GPIO_PACKET_MODE_EN"; + }; + gpio_ec_pch_wake_odl: ec_pch_wake_odl { + gpios = <&gpiob 2 GPIO_ODR_LOW>; + }; + gpio_ec_prochot_odl: ec_prochot_odl { + gpios = <&gpioi 1 GPIO_ODR_HIGH>; + }; + gpio_ec_soc_dsw_pwrok: ec_soc_dsw_pwrok { + gpios = <&gpiol 7 GPIO_OUTPUT>; + }; + gpio_ec_soc_hdmi_hpd: ec_soc_hdmi_hpd { + gpios = <&gpiok 7 GPIO_OUTPUT>; + }; + gpio_ec_soc_int_odl: ec_soc_int_odl { + gpios = <&gpiod 5 GPIO_ODR_HIGH>; + enum-name = "GPIO_EC_INT_L"; + }; + gpio_ec_soc_pch_pwrok_od: ec_soc_pch_pwrok_od { + gpios = <&gpiod 6 GPIO_ODR_HIGH>; + }; + gpio_ec_soc_pwr_btn_odl: ec_soc_pwr_btn_odl { + gpios = <&gpiob 6 GPIO_ODR_HIGH>; + enum-name = "GPIO_PCH_PWRBTN_L"; + }; + gpio_ec_soc_rsmrst_l: ec_soc_rsmrst_l { + gpios = <&gpioh 0 GPIO_OUTPUT>; + }; + gpio_ec_soc_rtcrst: ec_soc_rtcrst { + gpios = <&gpiok 2 GPIO_OUTPUT>; + }; + gpio_ec_soc_sys_pwrok: ec_soc_sys_pwrok { + gpios = <&gpiof 2 GPIO_OUTPUT>; + }; + gpio_ec_soc_vccst_pwrgd_od: ec_soc_vccst_pwrgd_od { + gpios = <&gpioe 5 GPIO_ODR_HIGH>; + }; + gpio_ec_wp_odl: ec_wp_odl { + gpios = <&gpioa 6 (GPIO_INPUT | GPIO_ACTIVE_LOW)>; + }; + gpio_en_kb_bl: en_kb_bl { + gpios = <&gpioj 3 GPIO_OUTPUT>; + enum-name = "GPIO_EN_KEYBOARD_BACKLIGHT"; + }; + gpio_en_pp3300_s5: en_pp3300_s5 { + gpios = <&gpioc 5 GPIO_OUTPUT>; + enum-name = "GPIO_TEMP_SENSOR_POWER"; + }; + gpio_en_pp5000_pen_x: en_pp5000_pen_x { + gpios = <&gpiob 5 GPIO_OUTPUT>; + }; + gpio_en_pp5000_s5: en_pp5000_s5 { + gpios = <&gpiok 5 GPIO_OUTPUT>; + }; + gpio_en_slp_z: en_slp_z { + gpios = <&gpiok 3 GPIO_OUTPUT>; + }; + gpio_en_usb_a0_vbus: en_usb_a0_vbus { + gpios = <&gpiol 6 GPIO_OUTPUT>; + }; + gpio_en_usb_c0_cc1_vconn: en_usb_c0_cc1_vconn { + gpios = <&gpioh 4 GPIO_OUTPUT>; + }; + gpio_en_usb_c0_cc2_vconn: en_usb_c0_cc2_vconn { + gpios = <&gpioh 6 GPIO_OUTPUT>; + }; + gpio_gsc_ec_pwr_btn_odl: gsc_ec_pwr_btn_odl { + gpios = <&gpioe 2 GPIO_INPUT_PULL_UP>; + enum-name = "GPIO_POWER_BUTTON_L"; + }; + gpio_hdmi_sel: hdmi_sel { + gpios = <&gpioc 6 GPIO_OUTPUT>; + }; + gpio_imu_int_l: imu_int_l { + gpios = <&gpioj 0 GPIO_INPUT>; + }; + gpio_imvp91_vrrdy_od: imvp91_vrrdy_od { + gpios = <&gpioj 4 GPIO_INPUT>; + }; + gpio_lid_open: lid_open { + gpios = <&gpiof 3 GPIO_INPUT>; + enum-name = "GPIO_LID_OPEN"; + }; + gpio_pen_detect_odl: pen_detect_odl { + gpios = <&gpioj 1 GPIO_INPUT_PULL_UP>; + }; + gpio_pg_pp1050_mem_s3_od: pg_pp1050_mem_s3_od { + gpios = <&gpiod 3 GPIO_INPUT>; + }; + gpio_pg_pp5000_s5_od: pg_pp5000_s5_od { + gpios = <&gpioe 3 GPIO_INPUT>; + }; + gpio_rsmrst_pwrgd_l: rsmrst_pwrgd_l { + gpios = <&gpioe 1 GPIO_INPUT_PULL_UP>; + }; + gpio_slp_s0_l: slp_s0_l { + gpios = <&gpioe 4 GPIO_INPUT>; + }; + gpio_slp_s3_l: slp_s3_l { + gpios = <&gpioh 3 GPIO_INPUT>; + }; + gpio_slp_s4_l: slp_s4_l { + gpios = <&gpioi 5 GPIO_INPUT>; + }; + gpio_slp_sus_l: slp_sus_l { + gpios = <&gpiog 2 GPIO_INPUT>; + }; + gpio_sub_usb_a1_ilimit_sdp: sub_usb_a1_ilimit_sdp { + gpios = <&gpiof 1 GPIO_OUTPUT>; + enum-name = "GPIO_USB2_ILIM_SEL"; + }; + gpio_sys_rst_odl: sys_rst_odl { + gpios = <&gpiod 1 GPIO_ODR_HIGH>; + }; + gpio_tablet_mode_l: tablet_mode_l { + gpios = <&gpioj 7 GPIO_INPUT>; + enum-name = "GPIO_TABLET_MODE_L"; + }; + gpio_usb_a0_ilimit_sdp: usb_a0_ilimit_sdp { + gpios = <&gpiol 5 GPIO_OUTPUT>; + enum-name = "GPIO_USB1_ILIM_SEL"; + }; + gpio_usb_c0_frs: usb_c0_frs { + gpios = <&gpioc 4 GPIO_OUTPUT>; + }; + gpio_usb_c0_int_odl: usb_c0_int_odl { + gpios = <&gpiok 0 GPIO_INPUT_PULL_UP>; + }; + gpio_vccin_aux_vid0: vccin_aux_vid0 { + gpios = <&gpiod 0 GPIO_INPUT>; + }; + gpio_vccin_aux_vid1: vccin_aux_vid1 { + gpios = <&gpiok 1 GPIO_INPUT>; + }; + gpio_voldn_btn_odl: voldn_btn_odl { + gpios = <&gpioi 6 GPIO_INPUT_PULL_UP>; + enum-name = "GPIO_VOLUME_DOWN_L"; + }; + gpio_volup_btn_odl: volup_btn_odl { + gpios = <&gpioi 7 GPIO_INPUT_PULL_UP>; + enum-name = "GPIO_VOLUME_UP_L"; + }; + }; + + named-i2c-ports { + compatible = "named-i2c-ports"; + + i2c_ec_i2c_eeprom: ec_i2c_eeprom { + i2c-port = <&i2c0>; + enum-names = "I2C_PORT_EEPROM"; + }; + i2c_ec_i2c_batt: ec_i2c_batt { + i2c-port = <&i2c1>; + enum-names = "I2C_PORT_BATTERY"; + }; + i2c_ec_i2c_sensor: ec_i2c_sensor { + i2c-port = <&i2c2>; + enum-names = "I2C_PORT_SENSOR"; + }; + i2c_ec_i2c_sub_usb_c1: ec_i2c_sub_usb_c1 { + i2c-port = <&i2c4>; + enum-names = "I2C_PORT_USB_C1_TCPC"; + }; + i2c_ec_i2c_usb_c0: ec_i2c_usb_c0 { + i2c-port = <&i2c5>; + enum-names = "I2C_PORT_USB_C0_TCPC"; + }; + }; +}; + +&adc0 { + status = "okay"; +}; + +&i2c0 { + status = "okay"; +}; + +&i2c1 { + status = "okay"; +}; + +&i2c2 { + status = "okay"; +}; + +&i2c4 { + status = "okay"; +}; + +&i2c5 { + status = "okay"; +}; diff --git a/zephyr/projects/nissa/joxer/joxer_vif.xml b/zephyr/projects/nissa/joxer/joxer_vif.xml new file mode 100644 index 0000000000..cfbce5623a --- /dev/null +++ b/zephyr/projects/nissa/joxer/joxer_vif.xml @@ -0,0 +1,346 @@ +<?xml version="1.0" encoding="utf-8"?> +<vif:VIF xmlns:opt="http://usb.org/VendorInfoFileOptionalContent.xsd" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:vif="http://usb.org/VendorInfoFile.xsd"> + <vif:VIF_Specification>3.20</vif:VIF_Specification> + <vif:VIF_App> + <vif:Vendor>USB-IF</vif:Vendor> + <vif:Name>VIF Editor</vif:Name> + <vif:Version>3.3.0.0</vif:Version> + </vif:VIF_App> + <vif:Vendor_Name>Google</vif:Vendor_Name> + <vif:Model_Part_Number>Joxer</vif:Model_Part_Number> + <vif:Product_Revision>1</vif:Product_Revision> + <vif:TID>0</vif:TID> + <vif:VIF_Product_Type value="0">Port Product</vif:VIF_Product_Type> + <vif:Certification_Type value="1">Reference Platform</vif:Certification_Type> + <vif:Product> + <!--Product Level Content:--> + </vif:Product> + <vif:Component> + <!--Component 0: Port 0--> + <!--;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;--> + <!--;Component--> + <!--;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;--> + <vif:Port_Label>0</vif:Port_Label> + <vif:Connector_Type value="2">Type-C®</vif:Connector_Type> + <vif:USB4_Supported value="false" /> + <vif:USB_PD_Support value="true" /> + <vif:PD_Port_Type value="4">DRP</vif:PD_Port_Type> + <vif:Type_C_State_Machine value="2">DRP</vif:Type_C_State_Machine> + <vif:Port_Battery_Powered value="true" /> + <vif:BC_1_2_Support value="3">Both</vif:BC_1_2_Support> + <vif:Captive_Cable value="false" /> + <!--;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;--> + <!--;General PD--> + <!--;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;--> + <vif:PD_Spec_Revision_Major value="3" /> + <vif:PD_Spec_Revision_Minor value="1" /> + <vif:PD_Spec_Version_Major value="1" /> + <vif:PD_Spec_Version_Minor value="3" /> + <vif:PD_Specification_Revision value="2">Revision 3</vif:PD_Specification_Revision> + <vif:SOP_Capable value="true" /> + <vif:SOP_P_Capable value="true" /> + <vif:SOP_PP_Capable value="true" /> + <vif:SOP_P_Debug_Capable value="false" /> + <vif:SOP_PP_Debug_Capable value="false" /> + <vif:Manufacturer_Info_Supported_Port value="false" /> + <vif:Chunking_Implemented_SOP value="true" /> + <vif:Unchunked_Extended_Messages_Supported value="false" /> + <vif:Security_Msgs_Supported_SOP value="false" /> + <vif:Unconstrained_Power value="false" /> + <vif:Num_Fixed_Batteries value="1" /> + <vif:Num_Swappable_Battery_Slots value="1" /> + <vif:ID_Header_Connector_Type_SOP value="2">USB Type-C® Receptacle</vif:ID_Header_Connector_Type_SOP> + <!--;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;--> + <!--;PD Capabilities--> + <!--;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;--> + <vif:USB_Comms_Capable value="true" /> + <vif:DR_Swap_To_DFP_Supported value="true" /> + <vif:DR_Swap_To_UFP_Supported value="false" /> + <vif:VCONN_Swap_To_On_Supported value="true" /> + <vif:VCONN_Swap_To_Off_Supported value="true" /> + <vif:Responds_To_Discov_SOP_UFP value="false" /> + <vif:Responds_To_Discov_SOP_DFP value="true" /> + <vif:Attempts_Discov_SOP value="true" /> + <vif:Power_Interruption_Available value="0">No Interruption Possible</vif:Power_Interruption_Available> + <vif:Data_Reset_Supported value="false" /> + <vif:Enter_USB_Supported value="false" /> + <!--;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;--> + <!--;USB Type-C®--> + <!--;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;--> + <vif:Type_C_Can_Act_As_Host value="true" /> + <vif:Type_C_Can_Act_As_Device value="false" /> + <vif:Type_C_Implements_Try_SRC value="true" /> + <vif:Type_C_Implements_Try_SNK value="false" /> + <vif:Type_C_Supports_Audio_Accessory value="false" /> + <vif:Type_C_Is_VCONN_Powered_Accessory value="false" /> + <vif:Type_C_Is_Debug_Target_SRC value="true" /> + <vif:Type_C_Is_Debug_Target_SNK value="true" /> + <vif:RP_Value value="1">1.5A</vif:RP_Value> + <vif:Type_C_Port_On_Hub value="false" /> + <vif:Type_C_Power_Source value="2">Both</vif:Type_C_Power_Source> + <vif:Type_C_Sources_VCONN value="true" /> + <vif:Type_C_Is_Alt_Mode_Controller value="true" /> + <vif:Type_C_Is_Alt_Mode_Adapter value="false" /> + <!--;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;--> + <!--;Product Power--> + <!--;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;--> + <vif:Product_Total_Source_Power_mW value="15000">15000 mW</vif:Product_Total_Source_Power_mW> + <vif:Port_Source_Power_Type value="0">Assured</vif:Port_Source_Power_Type> + <!--;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;--> + <!--;USB Host--> + <!--;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;--> + <vif:Host_Supports_USB_Data value="true" /> + <vif:Host_Speed value="1">USB 3.2 Gen 1x1</vif:Host_Speed> + <vif:Host_Contains_Captive_Retimer value="false" /> + <vif:Host_Truncates_DP_For_tDHPResponse value="false" /> + <vif:Host_Is_Embedded value="false" /> + <vif:Host_Suspend_Supported value="true" /> + <vif:Is_DFP_On_Hub value="false" /> + <!--;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;--> + <!--;Battery Charging 1.2--> + <!--;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;--> + <vif:BC_1_2_Charging_Port_Type value="1">CDP</vif:BC_1_2_Charging_Port_Type> + <!--;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;--> + <!--;PD Source--> + <!--;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;--> + <vif:PD_Power_As_Source value="15000">15000 mW</vif:PD_Power_As_Source> + <vif:EPR_Supported_As_Src value="false" /> + <vif:USB_Suspend_May_Be_Cleared value="false" /> + <vif:Sends_Pings value="false" /> + <vif:FR_Swap_Type_C_Current_Capability_As_Initial_Sink value="0">FR_Swap not supported</vif:FR_Swap_Type_C_Current_Capability_As_Initial_Sink> + <vif:Master_Port value="false" /> + <vif:Num_Src_PDOs value="1" /> + <vif:PD_OC_Protection value="true" /> + <vif:PD_OCP_Method value="0">Over-Current Response</vif:PD_OCP_Method> + <!--Bundle: SrcPdoList--> + <vif:SrcPdoList> + <vif:SrcPDO> + <!--Source PDO 1--> + <vif:Src_PDO_Supply_Type value="0">Fixed</vif:Src_PDO_Supply_Type> + <vif:Src_PDO_Peak_Current value="0">100% IOC</vif:Src_PDO_Peak_Current> + <vif:Src_PDO_Voltage value="100">5000 mV</vif:Src_PDO_Voltage> + <vif:Src_PDO_Max_Current value="300">3000 mA</vif:Src_PDO_Max_Current> + <vif:Src_PD_OCP_OC_Debounce value="0">0 msec</vif:Src_PD_OCP_OC_Debounce> + <vif:Src_PD_OCP_OC_Threshold value="300">3000 mA</vif:Src_PD_OCP_OC_Threshold> + </vif:SrcPDO> + </vif:SrcPdoList> + <!--;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;--> + <!--;PD Sink--> + <!--;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;--> + <vif:PD_Power_As_Sink value="45000">45000 mW</vif:PD_Power_As_Sink> + <vif:EPR_Supported_As_Snk value="false" /> + <vif:No_USB_Suspend_May_Be_Set value="true" /> + <vif:GiveBack_May_Be_Set value="false" /> + <vif:Higher_Capability_Set value="false" /> + <vif:FR_Swap_Reqd_Type_C_Current_As_Initial_Source value="0">FR_Swap not supported</vif:FR_Swap_Reqd_Type_C_Current_As_Initial_Source> + <vif:Num_Snk_PDOs value="3" /> + <!--Bundle: SnkPdoList--> + <vif:SnkPdoList> + <vif:SnkPDO> + <!--Sink PDO 1--> + <vif:Snk_PDO_Supply_Type value="0">Fixed</vif:Snk_PDO_Supply_Type> + <vif:Snk_PDO_Voltage value="100">5000 mV</vif:Snk_PDO_Voltage> + <vif:Snk_PDO_Op_Current value="300">3000 mA</vif:Snk_PDO_Op_Current> + </vif:SnkPDO> + <vif:SnkPDO> + <!--Sink PDO 2--> + <vif:Snk_PDO_Supply_Type value="1">Battery</vif:Snk_PDO_Supply_Type> + <vif:Snk_PDO_Op_Power value="60">15000 mW</vif:Snk_PDO_Op_Power> + <vif:Snk_PDO_Min_Voltage value="95">4750 mV</vif:Snk_PDO_Min_Voltage> + <vif:Snk_PDO_Max_Voltage value="300">15000 mV</vif:Snk_PDO_Max_Voltage> + </vif:SnkPDO> + <vif:SnkPDO> + <!--Sink PDO 3--> + <vif:Snk_PDO_Supply_Type value="2">Variable</vif:Snk_PDO_Supply_Type> + <vif:Snk_PDO_Min_Voltage value="95">4750 mV</vif:Snk_PDO_Min_Voltage> + <vif:Snk_PDO_Max_Voltage value="300">15000 mV</vif:Snk_PDO_Max_Voltage> + <vif:Snk_PDO_Op_Current value="300">3000 mA</vif:Snk_PDO_Op_Current> + </vif:SnkPDO> + </vif:SnkPdoList> + <!--;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;--> + <!--;Dual Role--> + <!--;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;--> + <vif:Accepts_PR_Swap_As_Src value="true" /> + <vif:Accepts_PR_Swap_As_Snk value="true" /> + <vif:Requests_PR_Swap_As_Src value="true" /> + <vif:Requests_PR_Swap_As_Snk value="true" /> + <vif:FR_Swap_Supported_As_Initial_Sink value="false" /> + <!--;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;--> + <!--;SOP Discover ID--> + <!--;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;--> + <vif:XID_SOP value="0" /> + <vif:Data_Capable_As_USB_Host_SOP value="true" /> + <vif:Data_Capable_As_USB_Device_SOP value="false" /> + <vif:Product_Type_UFP_SOP value="0">Undefined</vif:Product_Type_UFP_SOP> + <vif:Product_Type_DFP_SOP value="2">PDUSB Host</vif:Product_Type_DFP_SOP> + <vif:DFP_VDO_Port_Number value="0" /> + <vif:Modal_Operation_Supported_SOP value="false" /> + <vif:USB_VID_SOP value="6353">18D1</vif:USB_VID_SOP> + <vif:PID_SOP value="20570">505A</vif:PID_SOP> + <vif:bcdDevice_SOP value="0">0000</vif:bcdDevice_SOP> + </vif:Component> + <vif:Component> + <!--Component 1: Port 1--> + <!--;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;--> + <!--;Component--> + <!--;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;--> + <vif:Port_Label>1</vif:Port_Label> + <vif:Connector_Type value="2">Type-C®</vif:Connector_Type> + <vif:USB4_Supported value="false" /> + <vif:USB_PD_Support value="true" /> + <vif:PD_Port_Type value="4">DRP</vif:PD_Port_Type> + <vif:Type_C_State_Machine value="2">DRP</vif:Type_C_State_Machine> + <vif:Port_Battery_Powered value="true" /> + <vif:BC_1_2_Support value="3">Both</vif:BC_1_2_Support> + <vif:Captive_Cable value="false" /> + <!--;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;--> + <!--;General PD--> + <!--;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;--> + <vif:PD_Spec_Revision_Major value="3" /> + <vif:PD_Spec_Revision_Minor value="1" /> + <vif:PD_Spec_Version_Major value="1" /> + <vif:PD_Spec_Version_Minor value="3" /> + <vif:PD_Specification_Revision value="2">Revision 3</vif:PD_Specification_Revision> + <vif:SOP_Capable value="true" /> + <vif:SOP_P_Capable value="true" /> + <vif:SOP_PP_Capable value="true" /> + <vif:SOP_P_Debug_Capable value="false" /> + <vif:SOP_PP_Debug_Capable value="false" /> + <vif:Manufacturer_Info_Supported_Port value="false" /> + <vif:Chunking_Implemented_SOP value="true" /> + <vif:Unchunked_Extended_Messages_Supported value="false" /> + <vif:Security_Msgs_Supported_SOP value="false" /> + <vif:Unconstrained_Power value="false" /> + <vif:Num_Fixed_Batteries value="1" /> + <vif:Num_Swappable_Battery_Slots value="1" /> + <vif:ID_Header_Connector_Type_SOP value="2">USB Type-C® Receptacle</vif:ID_Header_Connector_Type_SOP> + <!--;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;--> + <!--;PD Capabilities--> + <!--;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;--> + <vif:USB_Comms_Capable value="true" /> + <vif:DR_Swap_To_DFP_Supported value="true" /> + <vif:DR_Swap_To_UFP_Supported value="false" /> + <vif:VCONN_Swap_To_On_Supported value="true" /> + <vif:VCONN_Swap_To_Off_Supported value="true" /> + <vif:Responds_To_Discov_SOP_UFP value="false" /> + <vif:Responds_To_Discov_SOP_DFP value="true" /> + <vif:Attempts_Discov_SOP value="true" /> + <vif:Power_Interruption_Available value="0">No Interruption Possible</vif:Power_Interruption_Available> + <vif:Data_Reset_Supported value="false" /> + <vif:Enter_USB_Supported value="false" /> + <!--;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;--> + <!--;USB Type-C®--> + <!--;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;--> + <vif:Type_C_Can_Act_As_Host value="true" /> + <vif:Type_C_Can_Act_As_Device value="false" /> + <vif:Type_C_Implements_Try_SRC value="true" /> + <vif:Type_C_Implements_Try_SNK value="false" /> + <vif:Type_C_Supports_Audio_Accessory value="false" /> + <vif:Type_C_Is_VCONN_Powered_Accessory value="false" /> + <vif:Type_C_Is_Debug_Target_SRC value="true" /> + <vif:Type_C_Is_Debug_Target_SNK value="true" /> + <vif:RP_Value value="1">1.5A</vif:RP_Value> + <vif:Type_C_Port_On_Hub value="false" /> + <vif:Type_C_Power_Source value="2">Both</vif:Type_C_Power_Source> + <vif:Type_C_Sources_VCONN value="true" /> + <vif:Type_C_Is_Alt_Mode_Controller value="true" /> + <vif:Type_C_Is_Alt_Mode_Adapter value="false" /> + <!--;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;--> + <!--;Product Power--> + <!--;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;--> + <vif:Product_Total_Source_Power_mW value="15000">15000 mW</vif:Product_Total_Source_Power_mW> + <vif:Port_Source_Power_Type value="0">Assured</vif:Port_Source_Power_Type> + <!--;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;--> + <!--;USB Host--> + <!--;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;--> + <vif:Host_Supports_USB_Data value="true" /> + <vif:Host_Speed value="1">USB 3.2 Gen 1x1</vif:Host_Speed> + <vif:Host_Contains_Captive_Retimer value="true" /> + <vif:Host_Truncates_DP_For_tDHPResponse value="false" /> + <vif:Host_Is_Embedded value="false" /> + <vif:Host_Suspend_Supported value="true" /> + <vif:Is_DFP_On_Hub value="false" /> + <!--;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;--> + <!--;Battery Charging 1.2--> + <!--;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;--> + <vif:BC_1_2_Charging_Port_Type value="1">CDP</vif:BC_1_2_Charging_Port_Type> + <!--;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;--> + <!--;PD Source--> + <!--;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;--> + <vif:PD_Power_As_Source value="15000">15000 mW</vif:PD_Power_As_Source> + <vif:EPR_Supported_As_Src value="false" /> + <vif:USB_Suspend_May_Be_Cleared value="false" /> + <vif:Sends_Pings value="false" /> + <vif:FR_Swap_Type_C_Current_Capability_As_Initial_Sink value="0">FR_Swap not supported</vif:FR_Swap_Type_C_Current_Capability_As_Initial_Sink> + <vif:Master_Port value="false" /> + <vif:Num_Src_PDOs value="1" /> + <vif:PD_OC_Protection value="true" /> + <vif:PD_OCP_Method value="0">Over-Current Response</vif:PD_OCP_Method> + <!--Bundle: SrcPdoList--> + <vif:SrcPdoList> + <vif:SrcPDO> + <!--Source PDO 1--> + <vif:Src_PDO_Supply_Type value="0">Fixed</vif:Src_PDO_Supply_Type> + <vif:Src_PDO_Peak_Current value="0">100% IOC</vif:Src_PDO_Peak_Current> + <vif:Src_PDO_Voltage value="100">5000 mV</vif:Src_PDO_Voltage> + <vif:Src_PDO_Max_Current value="300">3000 mA</vif:Src_PDO_Max_Current> + <vif:Src_PD_OCP_OC_Debounce value="0">0 msec</vif:Src_PD_OCP_OC_Debounce> + <vif:Src_PD_OCP_OC_Threshold value="300">3000 mA</vif:Src_PD_OCP_OC_Threshold> + </vif:SrcPDO> + </vif:SrcPdoList> + <!--;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;--> + <!--;PD Sink--> + <!--;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;--> + <vif:PD_Power_As_Sink value="45000">45000 mW</vif:PD_Power_As_Sink> + <vif:EPR_Supported_As_Snk value="false" /> + <vif:No_USB_Suspend_May_Be_Set value="true" /> + <vif:GiveBack_May_Be_Set value="false" /> + <vif:Higher_Capability_Set value="false" /> + <vif:FR_Swap_Reqd_Type_C_Current_As_Initial_Source value="0">FR_Swap not supported</vif:FR_Swap_Reqd_Type_C_Current_As_Initial_Source> + <vif:Num_Snk_PDOs value="3" /> + <!--Bundle: SnkPdoList--> + <vif:SnkPdoList> + <vif:SnkPDO> + <!--Sink PDO 1--> + <vif:Snk_PDO_Supply_Type value="0">Fixed</vif:Snk_PDO_Supply_Type> + <vif:Snk_PDO_Voltage value="100">5000 mV</vif:Snk_PDO_Voltage> + <vif:Snk_PDO_Op_Current value="300">3000 mA</vif:Snk_PDO_Op_Current> + </vif:SnkPDO> + <vif:SnkPDO> + <!--Sink PDO 2--> + <vif:Snk_PDO_Supply_Type value="1">Battery</vif:Snk_PDO_Supply_Type> + <vif:Snk_PDO_Op_Power value="60">15000 mW</vif:Snk_PDO_Op_Power> + <vif:Snk_PDO_Min_Voltage value="95">4750 mV</vif:Snk_PDO_Min_Voltage> + <vif:Snk_PDO_Max_Voltage value="300">15000 mV</vif:Snk_PDO_Max_Voltage> + </vif:SnkPDO> + <vif:SnkPDO> + <!--Sink PDO 3--> + <vif:Snk_PDO_Supply_Type value="2">Variable</vif:Snk_PDO_Supply_Type> + <vif:Snk_PDO_Min_Voltage value="95">4750 mV</vif:Snk_PDO_Min_Voltage> + <vif:Snk_PDO_Max_Voltage value="300">15000 mV</vif:Snk_PDO_Max_Voltage> + <vif:Snk_PDO_Op_Current value="300">3000 mA</vif:Snk_PDO_Op_Current> + </vif:SnkPDO> + </vif:SnkPdoList> + <!--;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;--> + <!--;Dual Role--> + <!--;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;--> + <vif:Accepts_PR_Swap_As_Src value="true" /> + <vif:Accepts_PR_Swap_As_Snk value="true" /> + <vif:Requests_PR_Swap_As_Src value="true" /> + <vif:Requests_PR_Swap_As_Snk value="true" /> + <vif:FR_Swap_Supported_As_Initial_Sink value="false" /> + <!--;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;--> + <!--;SOP Discover ID--> + <!--;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;--> + <vif:XID_SOP value="0" /> + <vif:Data_Capable_As_USB_Host_SOP value="true" /> + <vif:Data_Capable_As_USB_Device_SOP value="false" /> + <vif:Product_Type_UFP_SOP value="0">Undefined</vif:Product_Type_UFP_SOP> + <vif:Product_Type_DFP_SOP value="2">PDUSB Host</vif:Product_Type_DFP_SOP> + <vif:DFP_VDO_Port_Number value="1" /> + <vif:Modal_Operation_Supported_SOP value="false" /> + <vif:USB_VID_SOP value="6353">18D1</vif:USB_VID_SOP> + <vif:PID_SOP value="20570">505A</vif:PID_SOP> + <vif:bcdDevice_SOP value="0">0000</vif:bcdDevice_SOP> + </vif:Component> +</vif:VIF>
\ No newline at end of file diff --git a/zephyr/projects/nissa/joxer/keyboard.dtsi b/zephyr/projects/nissa/joxer/keyboard.dtsi new file mode 100644 index 0000000000..04a620767a --- /dev/null +++ b/zephyr/projects/nissa/joxer/keyboard.dtsi @@ -0,0 +1,22 @@ +/* Copyright 2022 The ChromiumOS Authors + * Use of this source code is governed by a BSD-style license that can be + * found in the LICENSE file. + */ + +/ { + kblight { + compatible = "cros-ec,kblight-pwm"; + /* + * Use 324 Hz so that 32Khz clock source is used, + * which is not gated in power saving mode. + */ + pwms = <&pwm0 0 PWM_HZ(324) PWM_POLARITY_NORMAL>; + }; +}; + +&pwm0 { + status = "okay"; + prescaler-cx = <PWM_PRESCALER_C4>; + pinctrl-0 = <&pwm0_gpa0_default>; + pinctrl-names = "default"; +}; diff --git a/zephyr/projects/nissa/joxer/motionsense.dtsi b/zephyr/projects/nissa/joxer/motionsense.dtsi new file mode 100644 index 0000000000..537cc34451 --- /dev/null +++ b/zephyr/projects/nissa/joxer/motionsense.dtsi @@ -0,0 +1,149 @@ +/* Copyright 2022 The ChromiumOS Authors + * Use of this source code is governed by a BSD-style license that can be + * found in the LICENSE file. + */ + +#include <dt-bindings/motionsense/utils.h> + + +/ { + aliases { + /* + * Interrupt bindings for sensor devices. + */ + bmi3xx-int = &base_accel; + }; + + /* + * Declare mutexes used by sensor drivers. + * A mutex node is used to create an instance of mutex_t. + * A mutex node is referenced by a sensor node if the + * corresponding sensor driver needs to use the + * instance of the mutex. + */ + motionsense-mutex { + compatible = "cros-ec,motionsense-mutex"; + lid_mutex: lid-mutex { + }; + + base_mutex: base-mutex { + }; + }; + + /* Rotation matrix used by drivers. */ + motionsense-rotation-ref { + compatible = "cros-ec,motionsense-rotation-ref"; + lid_rot_ref: lid-rotation-ref { + mat33 = <0 (-1) 0 + (-1) 0 0 + 0 0 (-1)>; + }; + + base_rot_ref: base-rotation-ref { + mat33 = <1 0 0 + 0 1 0 + 0 0 1>; + }; + }; + + /* + * Driver specific data. A driver-specific data can be shared with + * different motion sensors while they are using the same driver. + * + * If a node's compatible starts with "cros-ec,accelgyro-", it is for + * a common structure defined in accelgyro.h. + * e.g) compatible = "cros-ec,accelgyro-als-drv-data" is for + * "struct als_drv_data_t" in accelgyro.h + */ + motionsense-sensor-data { + bmi323_data: bmi323-drv-data { + compatible = "cros-ec,drvdata-bmi3xx"; + status = "okay"; + }; + + bma422_data: bma422-drv-data { + compatible = "cros-ec,drvdata-bma4xx"; + status = "okay"; + }; + }; + + /* + * List of motion sensors that creates motion_sensors array. + * The nodelabel "lid_accel" and "base_accel" are used to indicate + * motion sensor IDs for lid angle calculation. + * TODO(b/238139272): The first entries of the array must be + * accelerometers,then gyroscope. Fix this dependency in the DTS + * processing which makes the devicetree entries independent. + */ + motionsense-sensor { + lid_accel: lid-accel { + compatible = "cros-ec,bma4xx"; + status = "okay"; + + active-mask = "SENSOR_ACTIVE_S0_S3"; + location = "MOTIONSENSE_LOC_LID"; + mutex = <&lid_mutex>; + port = <&i2c_ec_i2c_sensor>; + rot-standard-ref = <&lid_rot_ref>; + default-range = <2>; + drv-data = <&bma422_data>; + i2c-spi-addr-flags = "BMA4_I2C_ADDR_SECONDARY"; + configs { + compatible = + "cros-ec,motionsense-sensor-config"; + ec-s0 { + odr = <(10000 | ROUND_UP_FLAG)>; + }; + ec-s3 { + odr = <(10000 | ROUND_UP_FLAG)>; + }; + }; + }; + + base_accel: base-accel { + compatible = "cros-ec,bmi3xx-accel"; + status = "okay"; + + active-mask = "SENSOR_ACTIVE_S0_S3"; + location = "MOTIONSENSE_LOC_BASE"; + mutex = <&base_mutex>; + port = <&i2c_ec_i2c_sensor>; + rot-standard-ref = <&base_rot_ref>; + drv-data = <&bmi323_data>; + configs { + compatible = + "cros-ec,motionsense-sensor-config"; + ec-s0 { + odr = <(10000 | ROUND_UP_FLAG)>; + }; + ec-s3 { + odr = <(10000 | ROUND_UP_FLAG)>; + }; + }; + }; + + base_gyro: base-gyro { + compatible = "cros-ec,bmi3xx-gyro"; + status = "okay"; + + active-mask = "SENSOR_ACTIVE_S0_S3"; + location = "MOTIONSENSE_LOC_BASE"; + mutex = <&base_mutex>; + port = <&i2c_ec_i2c_sensor>; + rot-standard-ref = <&base_rot_ref>; + drv-data = <&bmi323_data>; + }; + }; + + motionsense-sensor-info { + compatible = "cros-ec,motionsense-sensor-info"; + + /* + * list of GPIO interrupts that have to + * be enabled at initial stage + */ + sensor-irqs = <&int_imu>; + /* list of sensors in force mode */ + accel-force-mode-sensors = <&lid_accel>; + }; +}; diff --git a/zephyr/projects/nissa/joxer/overlay.dtsi b/zephyr/projects/nissa/joxer/overlay.dtsi new file mode 100644 index 0000000000..b587da8fb1 --- /dev/null +++ b/zephyr/projects/nissa/joxer/overlay.dtsi @@ -0,0 +1,445 @@ +/* Copyright 2021 The ChromiumOS Authors + * Use of this source code is governed by a BSD-style license that can be + * found in the LICENSE file. + */ + +#include <cros/thermistor/thermistor.dtsi> + +/ { + aliases { + gpio-cbi-wp = &gpio_ec_cbi_wp; + gpio-wp = &gpio_ec_wp_odl; + int-wp = &int_wp_l; + /* + * USB-C: interrupt input. + * I2C pins are on i2c_ec_i2c_sub_usb_c1 + */ + gpio-usb-c1-int-odl = &gpio_sb_1; + /* + * USB-A: VBUS enable output + * LTE: power enable output + */ + gpio-en-usb-a1-vbus = &gpio_sb_2; + /* + * HDMI: power enable output, HDMI enable output, + * and HPD input + */ + gpio-en-rails-odl = &gpio_sb_1; + gpio-hdmi-en-odl = &gpio_sb_4; + gpio-hpd-odl = &gpio_sb_3; + /* + * Enable S5 rails for LTE sub-board + */ + gpio-en-sub-s5-rails = &gpio_sb_2; + }; + + ec-console { + compatible = "ec-console"; + disabled = "events", "lpc", "hostcmd"; + }; + + batteries { + default_battery: cosmx { + compatible = "cosmx,gh02047xl", "battery-smart"; + }; + dynapack_atl_gh02047xl { + compatible = "dynapack,atl_gh02047xl", "battery-smart"; + }; + dynapack_cosmx_gh02047xl { + compatible = "dynapack,cosmx_gh02047xl", "battery-smart"; + }; + smp_coslight_gh02047xl { + compatible = "smp,coslight_gh02047xl", "battery-smart"; + }; + smp_highpower_gh02047xl { + compatible = "smp,highpower_gh02047xl", "battery-smart"; + }; + }; + + hibernate-wake-pins { + compatible = "cros-ec,hibernate-wake-pins"; + wakeup-irqs = < + &int_power_button + &int_lid_open + >; + }; + + gpio-interrupts { + compatible = "cros-ec,gpio-interrupts"; + + int_power_button: power_button { + irq-pin = <&gpio_gsc_ec_pwr_btn_odl>; + flags = <GPIO_INT_EDGE_BOTH>; + handler = "power_button_interrupt"; + }; + int_vol_down: vol_down { + irq-pin = <&gpio_voldn_btn_odl>; + flags = <GPIO_INT_EDGE_BOTH>; + handler = "button_interrupt"; + }; + int_vol_up: vol_up { + irq-pin = <&gpio_volup_btn_odl>; + flags = <GPIO_INT_EDGE_BOTH>; + handler = "button_interrupt"; + }; + int_wp_l: wp_l { + irq-pin = <&gpio_ec_wp_odl>; + flags = <GPIO_INT_EDGE_BOTH>; + handler = "switch_interrupt"; + }; + int_lid_open: lid_open { + irq-pin = <&gpio_lid_open>; + flags = <GPIO_INT_EDGE_BOTH>; + handler = "lid_interrupt"; + }; + int_tablet_mode: tablet_mode { + irq-pin = <&gpio_tablet_mode_l>; + flags = <GPIO_INT_EDGE_BOTH>; + handler = "gmr_tablet_switch_isr"; + }; + int_imu: ec_imu { + irq-pin = <&gpio_imu_int_l>; + flags = <GPIO_INT_EDGE_FALLING>; + handler = "bmi3xx_interrupt"; + }; + int_usb_c0: usb_c0 { + irq-pin = <&gpio_usb_c0_int_odl>; + flags = <GPIO_INT_EDGE_FALLING>; + handler = "usb_c0_interrupt"; + }; + int_usb_c1: usb_c1 { + irq-pin = <&gpio_sb_1>; + flags = <GPIO_INT_EDGE_FALLING>; + handler = "usb_c1_interrupt"; + }; + }; + + unused-pins { + compatible = "unused-gpios"; + unused-gpios = <&gpioc 3 0>, + <&gpiod 4 0>, + <&gpioh 2 0>, + <&gpiol 4 0>; + }; + + named-gpios { + /* + * EC doesn't take any specific action on CC/SBU disconnect due to + * fault, but this definition is useful for hardware testing. + */ + gpio_usb_c0_prot_fault_odl: usb_c0_prot_fault_odl { + gpios = <&gpiok 6 GPIO_INPUT_PULL_UP>; + }; + + gpio_sb_1: sb_1 { + gpios = <&gpioe 6 0>; + no-auto-init; + }; + gpio_sb_2: sb_2 { + gpios = <&gpiof 0 0>; + no-auto-init; + }; + + gpio_sb_3: sb_3 { + gpios = <&gpioe 7 0>; + no-auto-init; + }; + gpio_sb_4: sb_4 { + gpios = <&gpioe 0 0>; + no-auto-init; + }; + gpio_fan_enable: fan-enable { + gpios = <&gpiol 4 GPIO_OUTPUT>; + no-auto-init; + }; + gpio_power_led_gate: power_led_gate { + gpios = <&gpiof 1 GPIO_OUTPUT_LOW>; + }; + gpio_led_1_odl: led_1_odl { + gpios = <&gpioa 1 GPIO_OUTPUT_HIGH>; + }; + gpio_led_2_odl: led_2_odl { + gpios = <&gpioa 2 GPIO_OUTPUT_HIGH>; + }; + gpio_led_3_l: led_3_l { + gpios = <&gpiol 2 GPIO_OUTPUT_HIGH>; + }; + gpio_led_4_l: led_4_l { + gpios = <&gpiol 3 GPIO_OUTPUT_HIGH>; + }; + }; + + temp_memory: memory { + compatible = "cros-ec,temp-sensor-thermistor"; + thermistor = <&thermistor_3V3_51K1_47K_4050B>; + adc = <&adc_temp_sensor_1>; + }; + temp_charger: charger { + compatible = "cros-ec,temp-sensor-thermistor"; + thermistor = <&thermistor_3V3_51K1_47K_4050B>; + adc = <&adc_temp_sensor_2>; + }; + temp_ambient: ambient { + compatible = "cros-ec,temp-sensor-thermistor"; + thermistor = <&thermistor_3V3_51K1_47K_4050B>; + adc = <&adc_temp_sensor_3>; + }; + + named-temp-sensors { + compatible = "cros-ec,temp-sensors"; + memory { + temp_fan_off = <35>; + temp_fan_max = <60>; + temp_host_high = <85>; + temp_host_halt = <90>; + temp_host_release_high = <80>; + power-good-pin = <&gpio_ec_soc_dsw_pwrok>; + sensor = <&temp_memory>; + }; + charger { + temp_fan_off = <35>; + temp_fan_max = <60>; + temp_host_high = <85>; + temp_host_halt = <90>; + temp_host_release_high = <80>; + power-good-pin = <&gpio_ec_soc_dsw_pwrok>; + sensor = <&temp_charger>; + }; + ambient { + temp_fan_off = <35>; + temp_fan_max = <60>; + temp_host_high = <85>; + temp_host_halt = <90>; + temp_host_release_high = <80>; + power-good-pin = <&gpio_ec_soc_dsw_pwrok>; + sensor = <&temp_ambient>; + }; + }; + + usba { + compatible = "cros-ec,usba-port-enable-pins"; + /* + * sb_2 is only configured as GPIO when USB-A1 is present, + * but it's still safe to control when disabled. + * + * ILIM_SEL pins are referred to by legacy enum name, + * GPIO_USB*_ILIM_SEL. The one for port A1 is unused on + * sub-boards that don't have USB-A so is safe to control + * regardless of system configuration. + */ + enable-pins = <&gpio_en_usb_a0_vbus &gpio_sb_2>; + status = "okay"; + }; + + usbc { + #address-cells = <1>; + #size-cells = <0>; + + port0@0 { + compatible = "named-usbc-port"; + reg = <0>; + bc12 = <&bc12_port0>; + chg = <&chg_port0>; + usb-mux-chain-0 { + compatible = "cros-ec,usb-mux-chain"; + usb-muxes = <&virtual_mux_0>; + }; + }; + port0-muxes { + virtual_mux_0: virtual-mux-0 { + compatible = "cros-ec,usbc-mux-virtual"; + }; + }; + port1@1 { + compatible = "named-usbc-port"; + reg = <1>; + bc12 = <&bc12_port1>; + chg = <&chg_port1>; + usb-mux-chain-1 { + compatible = "cros-ec,usb-mux-chain"; + usb-muxes = <&virtual_mux_1 &tcpci_mux_1>; + }; + usb_mux_chain_1_no_mux: usb-mux-chain-1-no-mux { + compatible = "cros-ec,usb-mux-chain"; + alternative-chain; + usb-muxes = <&virtual_mux_1>; + }; + }; + port1-muxes { + virtual_mux_1: virtual-mux-1 { + compatible = "cros-ec,usbc-mux-virtual"; + }; + tcpci_mux_1: tcpci-mux-1 { + compatible = "parade,usbc-mux-ps8xxx"; + }; + }; + }; + fans { + compatible = "cros-ec,fans"; + + fan_0 { + pwms = <&pwm7 PWM_CHANNEL_7 PWM_KHZ(30) PWM_POLARITY_NORMAL>; + tach = <&tach1>; + rpm_min = <1500>; + rpm_start = <1500>; + rpm_max = <6500>; + enable_gpio = <&gpio_fan_enable>; + }; + }; +}; + +&gpio_acc_int_l { + gpios = <&gpioc 0 (GPIO_INPUT | GPIO_VOLTAGE_1P8)>; +}; +&gpio_imu_int_l { + gpios = <&gpioj 0 (GPIO_INPUT | GPIO_VOLTAGE_1P8)>; +}; +&gpio_vccin_aux_vid0 { + gpios = <&gpiod 0 (GPIO_INPUT | GPIO_VOLTAGE_1P8)>; +}; +&gpio_vccin_aux_vid1 { + gpios = <&gpiok 1 (GPIO_INPUT | GPIO_VOLTAGE_1P8)>; +}; + +&gpio_ec_prochot_odl { + gpios = <&gpioi 1 (GPIO_ODR_HIGH | GPIO_VOLTAGE_1P8)>; +}; + +&thermistor_3V3_51K1_47K_4050B { + status = "okay"; +}; + +&adc_ec_vsense_pp3300_s5 { + /* + * Voltage divider on input has 47k upper and 220k lower legs with 3 V + * full-scale reading on the ADC. Apply the largest possible multiplier + * (without overflowing int32) to get the best possible approximation + * of the actual ratio, but derate by a factor of two to ensure + * unexpectedly high values won't overflow. + */ + mul = <(715828 / 2)>; + div = <(589820 / 2)>; +}; + +&adc0 { + pinctrl-0 = <&adc0_ch0_gpi0_default + &adc0_ch2_gpi2_default + &adc0_ch3_gpi3_default + &adc0_ch13_gpl0_default + &adc0_ch14_gpl1_default>; + pinctrl-names = "default"; +}; + +&pinctrl { + i2c2_clk_gpf6_default: i2c2_clk_gpf6_default { + gpio-voltage = "1v8"; + }; + i2c2_data_gpf7_default: i2c2_data_gpf7_default { + gpio-voltage = "1v8"; + }; +}; + + +&i2c0 { + label = "I2C_EEPROM"; + clock-frequency = <I2C_BITRATE_FAST>; + + cbi_eeprom: eeprom@50 { + compatible = "atmel,at24"; + reg = <0x50>; + size = <2048>; + pagesize = <16>; + address-width = <8>; + timeout = <5>; + }; + pinctrl-0 = <&i2c0_clk_gpb3_default + &i2c0_data_gpb4_default>; + pinctrl-names = "default"; +}; + +&i2c1 { + label = "I2C_BATTERY"; + clock-frequency = <50000>; + pinctrl-0 = <&i2c1_clk_gpc1_default + &i2c1_data_gpc2_default>; + pinctrl-names = "default"; +}; + +&i2c2 { + label = "I2C_SENSOR"; + clock-frequency = <I2C_BITRATE_FAST>; + pinctrl-0 = <&i2c2_clk_gpf6_default + &i2c2_data_gpf7_default>; + pinctrl-names = "default"; +}; + +&i2c4 { + label = "I2C_SUB_C1_TCPC"; + clock-frequency = <I2C_BITRATE_FAST_PLUS>; + pinctrl-0 = <&i2c4_clk_gpe0_default + &i2c4_data_gpe7_default>; + pinctrl-names = "default"; + + bc12_port1: pi3usb9201@5f { + compatible = "pericom,pi3usb9201"; + status = "okay"; + reg = <0x5f>; + }; + + chg_port1: sm5803@32 { + compatible = "siliconmitus,sm5803"; + status = "okay"; + reg = <0x32>; + }; +}; + +&i2c_ec_i2c_sub_usb_c1 { + /* + * Dynamic speed setting is used for AP-controlled firmware update + * of PS8745 TCPC/redriver: the AP lowers speed to 400 kHz in order + * to use more efficient window programming, then sets it back when + * done. + */ + dynamic-speed; +}; + +&i2c5 { + label = "I2C_USB_C0_TCPC"; + clock-frequency = <I2C_BITRATE_FAST_PLUS>; + pinctrl-0 = <&i2c5_clk_gpa4_default + &i2c5_data_gpa5_default>; + pinctrl-names = "default"; + + bc12_port0: pi3usb9201@5f { + compatible = "pericom,pi3usb9201"; + status = "okay"; + reg = <0x5f>; + }; + + chg_port0: sm5803@32 { + compatible = "siliconmitus,sm5803"; + status = "okay"; + reg = <0x32>; + }; +}; + +/* pwm for fan */ +&pwm7 { + status = "okay"; + prescaler-cx = <PWM_PRESCALER_C6>; + pinctrl-0 = <&pwm7_gpa7_default>; + pinctrl-names = "default"; +}; + +/* fan tachometer sensor */ +&tach1 { + status = "okay"; + channel = <IT8XXX2_TACH_CHANNEL_A>; + pulses-per-round = <2>; + pinctrl-0 = <&tach1a_gpd7_default>; + pinctrl-names = "default"; +}; + +&usbpd0 { + status = "okay"; +}; diff --git a/zephyr/projects/nissa/joxer/power_signals.dtsi b/zephyr/projects/nissa/joxer/power_signals.dtsi new file mode 100644 index 0000000000..8affae03b1 --- /dev/null +++ b/zephyr/projects/nissa/joxer/power_signals.dtsi @@ -0,0 +1,223 @@ +/* Copyright 2022 The ChromiumOS Authors + * Use of this source code is governed by a BSD-style license that can be + * found in the LICENSE file. + */ + +/ { + chosen { + intel-ap-pwrseq,espi = &espi0; + }; + + common-pwrseq { + compatible = "intel,ap-pwrseq"; + + sys-pwrok-delay = <10>; + all-sys-pwrgd-timeout = <20>; + }; + + pwr-en-pp5000-s5 { + compatible = "intel,ap-pwrseq-gpio"; + dbg-label = "PP5000_S5 enable output to regulator"; + enum-name = "PWR_EN_PP5000_A"; + gpios = <&gpiok 5 0>; + output; + }; + pwr-en-pp3300-s5 { + compatible = "intel,ap-pwrseq-gpio"; + dbg-label = "PP3300_S5 enable output to LS"; + enum-name = "PWR_EN_PP3300_A"; + gpios = <&gpioc 5 0>; + output; + }; + pwr-pg-ec-rsmrst-odl { + compatible = "intel,ap-pwrseq-gpio"; + dbg-label = "RSMRST power good from regulator"; + enum-name = "PWR_RSMRST"; + gpios = <&gpioe 1 0>; + interrupt-flags = <GPIO_INT_EDGE_BOTH>; + }; + pwr-ec-pch-rsmrst-odl { + compatible = "intel,ap-pwrseq-gpio"; + dbg-label = "RSMRST output to PCH"; + enum-name = "PWR_EC_PCH_RSMRST"; + gpios = <&gpioh 0 0>; + output; + }; + pwr-slp-s0-l { + compatible = "intel,ap-pwrseq-gpio"; + dbg-label = "SLP_S0_L input from PCH"; + enum-name = "PWR_SLP_S0"; + gpios = <&gpioe 4 GPIO_ACTIVE_LOW>; + interrupt-flags = <GPIO_INT_EDGE_BOTH>; + }; + pwr-slp-s3-l { + compatible = "intel,ap-pwrseq-gpio"; + dbg-label = "SLP_S3_L input from PCH"; + enum-name = "PWR_SLP_S3"; + gpios = <&gpioh 3 GPIO_ACTIVE_LOW>; + interrupt-flags = <GPIO_INT_EDGE_BOTH>; + }; + pwr-slp-sus-l { + compatible = "intel,ap-pwrseq-gpio"; + dbg-label = "SLP_SUS_L input from PCH"; + enum-name = "PWR_SLP_SUS"; + gpios = <&gpiog 2 GPIO_ACTIVE_LOW>; + interrupt-flags = <GPIO_INT_EDGE_BOTH>; + }; + pwr-ec-soc-dsw-pwrok { + compatible = "intel,ap-pwrseq-gpio"; + dbg-label = "DSW_PWROK output to PCH"; + enum-name = "PWR_EC_SOC_DSW_PWROK"; + gpios = <&gpiol 7 0>; + output; + }; + pwr-vccst-pwrgd-od { + compatible = "intel,ap-pwrseq-gpio"; + dbg-label = "VCCST_PWRGD output to PCH"; + enum-name = "PWR_VCCST_PWRGD"; + gpios = <&gpioe 5 (GPIO_OPEN_DRAIN | GPIO_VOLTAGE_1P8)>; + output; + }; + pwr-imvp9-vrrdy-od { + compatible = "intel,ap-pwrseq-gpio"; + dbg-label = "VRRDY input from IMVP9"; + enum-name = "PWR_IMVP9_VRRDY"; + gpios = <&gpioj 4 0>; + }; + pwr-pch-pwrok { + compatible = "intel,ap-pwrseq-gpio"; + dbg-label = "PCH_PWROK output to PCH"; + enum-name = "PWR_PCH_PWROK"; + gpios = <&gpiod 6 GPIO_OPEN_DRAIN>; + output; + }; + pwr-ec-pch-sys-pwrok { + compatible = "intel,ap-pwrseq-gpio"; + dbg-label = "SYS_PWROK output to PCH"; + enum-name = "PWR_EC_PCH_SYS_PWROK"; + gpios = <&gpiof 2 0>; + output; + }; + pwr-sys-rst-l { + compatible = "intel,ap-pwrseq-gpio"; + dbg-label = "SYS_RESET# output to PCH"; + enum-name = "PWR_SYS_RST"; + gpios = <&gpiod 1 (GPIO_ACTIVE_LOW|GPIO_OPEN_DRAIN)>; + output; + }; + pwr-slp-s4 { + compatible = "intel,ap-pwrseq-vw"; + dbg-label = "SLP_S4 virtual wire input from PCH"; + enum-name = "PWR_SLP_S4"; + virtual-wire = "ESPI_VWIRE_SIGNAL_SLP_S4"; + vw-invert; + }; + pwr-slp-s5 { + compatible = "intel,ap-pwrseq-vw"; + dbg-label = "SLP_S5 virtual wire input from PCH"; + enum-name = "PWR_SLP_S5"; + virtual-wire = "ESPI_VWIRE_SIGNAL_SLP_S5"; + vw-invert; + }; + pwr-all-sys-pwrgd { + /* + * This is a board level signal, since this + * signal needs some special processing. + */ + compatible = "intel,ap-pwrseq-external"; + dbg-label = "Combined all power good"; + enum-name = "PWR_ALL_SYS_PWRGD"; + }; + pwr-adc-pp3300 { + compatible = "intel,ap-pwrseq-adc"; + dbg-label = "PP3300_PROC"; + enum-name = "PWR_DSW_PWROK"; + trigger-high = <&vcmp0>; + trigger-low = <&vcmp1>; + }; + pwr-adc-pp1p05 { + compatible = "intel,ap-pwrseq-adc"; + dbg-label = "PP1P05_PROC"; + enum-name = "PWR_PG_PP1P05"; + trigger-high = <&vcmp2>; + trigger-low = <&vcmp3>; + }; + +}; + +/* + * Because the power signals directly reference the GPIOs, + * the correspinding named-gpios need to have no-auto-init set. + */ +&gpio_ec_soc_dsw_pwrok { + no-auto-init; +}; +&gpio_ec_soc_pch_pwrok_od { + no-auto-init; +}; +&gpio_ec_soc_rsmrst_l { + no-auto-init; +}; +&gpio_ec_soc_sys_pwrok { + no-auto-init; +}; +&gpio_ec_soc_vccst_pwrgd_od { + no-auto-init; +}; +&gpio_en_pp3300_s5 { + no-auto-init; +}; +&gpio_en_pp5000_s5 { + no-auto-init; +}; +&gpio_imvp91_vrrdy_od { + no-auto-init; +}; +&gpio_rsmrst_pwrgd_l { + no-auto-init; +}; +&gpio_slp_s0_l { + no-auto-init; +}; +&gpio_slp_s3_l { + no-auto-init; +}; +&gpio_slp_sus_l { + no-auto-init; +}; +&gpio_sys_rst_odl { + no-auto-init; +}; +&vcmp0 { + status = "okay"; + scan-period = <IT8XXX2_VCMP_SCAN_PERIOD_600US>; + comparison = <IT8XXX2_VCMP_GREATER>; + /* + * This is 90% of nominal voltage considering voltage + * divider on ADC input. + */ + threshold-mv = <2448>; + io-channels = <&adc0 0>; +}; +&vcmp1 { + status = "okay"; + scan-period = <IT8XXX2_VCMP_SCAN_PERIOD_600US>; + comparison = <IT8XXX2_VCMP_LESS_OR_EQUAL>; + threshold-mv = <2448>; + io-channels = <&adc0 0>; +}; +&vcmp2 { + status = "okay"; + scan-period = <IT8XXX2_VCMP_SCAN_PERIOD_600US>; + comparison = <IT8XXX2_VCMP_GREATER>; + /* Setting at 90% of nominal voltage */ + threshold-mv = <945>; + io-channels = <&adc0 14>; +}; +&vcmp3 { + status = "okay"; + scan-period = <IT8XXX2_VCMP_SCAN_PERIOD_600US>; + comparison = <IT8XXX2_VCMP_LESS_OR_EQUAL>; + threshold-mv = <945>; + io-channels = <&adc0 14>; +}; diff --git a/zephyr/projects/nissa/joxer/project.conf b/zephyr/projects/nissa/joxer/project.conf new file mode 100644 index 0000000000..a0de72294c --- /dev/null +++ b/zephyr/projects/nissa/joxer/project.conf @@ -0,0 +1,19 @@ +# Copyright 2021 The ChromiumOS Authors +# Use of this source code is governed by a BSD-style license that can be +# found in the LICENSE file. + +CONFIG_BOARD_JOXER=y + +# Ensure recovery key combination (esc+refresh+power) is reliable: b/236580049 +CONFIG_PLATFORM_EC_KEYBOARD_PWRBTN_ASSERTS_KSI3=y +CONFIG_PLATFORM_EC_KEYBOARD_REFRESH_ROW3=y + +# Sensor drivers +CONFIG_PLATFORM_EC_ACCELGYRO_BMI_COMM_I2C=y +CONFIG_PLATFORM_EC_ACCELGYRO_BMI3XX=y +CONFIG_PLATFORM_EC_ACCEL_BMA4XX=y +CONFIG_PLATFORM_EC_MAX_SENSOR_FREQ_MILLIHZ=100000 + +# LED +CONFIG_PLATFORM_EC_LED_PWM=n +CONFIG_PLATFORM_EC_LED_COMMON=y diff --git a/zephyr/projects/nissa/joxer/project.overlay b/zephyr/projects/nissa/joxer/project.overlay new file mode 100644 index 0000000000..9ca681d979 --- /dev/null +++ b/zephyr/projects/nissa/joxer/project.overlay @@ -0,0 +1,14 @@ +/* Copyright 2022 The ChromiumOS Authors + * Use of this source code is governed by a BSD-style license that can be + * found in the LICENSE file. + */ + +#include "../cbi.dtsi" + +#include "cbi.dtsi" +#include "generated.dtsi" +#include "keyboard.dtsi" +#include "motionsense.dtsi" +#include "overlay.dtsi" +#include "power_signals.dtsi" +#include "pwm_leds.dtsi" diff --git a/zephyr/projects/nissa/joxer/pwm_leds.dtsi b/zephyr/projects/nissa/joxer/pwm_leds.dtsi new file mode 100644 index 0000000000..aa4a76b271 --- /dev/null +++ b/zephyr/projects/nissa/joxer/pwm_leds.dtsi @@ -0,0 +1,60 @@ +/* Copyright 2022 The ChromiumOS Authors + * Use of this source code is governed by a BSD-style license that can be + * found in the LICENSE file. + */ + +/ { + pwmleds { + compatible = "pwm-leds"; + pwm_led0: pwm_led_0 { + pwms = <&pwm1 1 PWM_HZ(1296) PWM_POLARITY_INVERTED>, + <&pwm2 2 PWM_HZ(1296) PWM_POLARITY_INVERTED>, + <&pwm3 3 PWM_HZ(1296) PWM_POLARITY_INVERTED>; + }; + }; + + cros-pwmleds { + compatible = "cros-ec,pwm-leds"; + + leds = <&pwm_led0>; + + /*<red green blue>*/ + color-map-red = <100 0 0>; + color-map-green = < 0 100 0>; + color-map-blue = < 0 0 100>; + color-map-yellow = < 0 50 50>; + color-map-white = <100 100 100>; + color-map-amber = <100 15 0>; + + brightness-range = <100 100 100 0 0 0>; + + #address-cells = <1>; + #size-cells = <0>; + + pwm_led_0@0 { + reg = <0>; + ec-led-name = "EC_LED_ID_BATTERY_LED"; + }; + }; +}; + +&pwm1 { + status = "okay"; + prescaler-cx = <PWM_PRESCALER_C4>; + pinctrl-0 = <&pwm1_gpa1_default>; + pinctrl-names = "default"; +}; + +&pwm2 { + status = "okay"; + prescaler-cx = <PWM_PRESCALER_C4>; + pinctrl-0 = <&pwm2_gpa2_default>; + pinctrl-names = "default"; +}; + +&pwm3 { + status = "okay"; + prescaler-cx = <PWM_PRESCALER_C4>; + pinctrl-0 = <&pwm3_gpa3_default>; + pinctrl-names = "default"; +}; diff --git a/zephyr/projects/nissa/joxer/src/charger.c b/zephyr/projects/nissa/joxer/src/charger.c new file mode 100644 index 0000000000..b9454d8b80 --- /dev/null +++ b/zephyr/projects/nissa/joxer/src/charger.c @@ -0,0 +1,56 @@ +/* Copyright 2022 The ChromiumOS Authors + * Use of this source code is governed by a BSD-style license that can be + * found in the LICENSE file. + */ + +#include <zephyr/logging/log.h> + +#include "battery.h" +#include "charger.h" +#include "console.h" +#include "driver/charger/sm5803.h" +#include "extpower.h" +#include "usb_pd.h" +#include "nissa_common.h" + +LOG_MODULE_DECLARE(nissa, CONFIG_NISSA_LOG_LEVEL); + +int extpower_is_present(void) +{ + int port; + int rv; + bool acok; + + for (port = 0; port < board_get_usb_pd_port_count(); port++) { + rv = sm5803_is_acok(port, &acok); + if ((rv == EC_SUCCESS) && acok) + return 1; + } + + return 0; +} + +/* + * Joxer not have a GPIO indicating whether extpower is present, + * so detect using the charger(s). + */ +__override void board_check_extpower(void) +{ + static int last_extpower_present; + int extpower_present = extpower_is_present(); + + if (last_extpower_present ^ extpower_present) + extpower_handle_update(extpower_present); + + last_extpower_present = extpower_present; +} + +__override void board_hibernate(void) +{ + /* Shut down the chargers */ + if (board_get_usb_pd_port_count() == 2) + sm5803_hibernate(CHARGER_SECONDARY); + sm5803_hibernate(CHARGER_PRIMARY); + LOG_INF("Charger(s) hibernated"); + cflush(); +} diff --git a/zephyr/projects/nissa/joxer/src/fan.c b/zephyr/projects/nissa/joxer/src/fan.c new file mode 100644 index 0000000000..6d234b2fc3 --- /dev/null +++ b/zephyr/projects/nissa/joxer/src/fan.c @@ -0,0 +1,43 @@ +/* Copyright 2022 The ChromiumOS Authors + * Use of this source code is governed by a BSD-style license that can be + * found in the LICENSE file. + */ + +#include <zephyr/devicetree.h> +#include <zephyr/drivers/gpio.h> +#include <zephyr/logging/log.h> + +#include "cros_cbi.h" +#include "fan.h" +#include "gpio/gpio.h" +#include "hooks.h" + +#include "nissa_common.h" + +LOG_MODULE_DECLARE(nissa, CONFIG_NISSA_LOG_LEVEL); + +/* + * Joxer fan support + */ +static void fan_init(void) +{ + int ret; + uint32_t val; + /* + * Retrieve the fan config. + */ + ret = cros_cbi_get_fw_config(FW_FAN, &val); + if (ret != 0) { + LOG_ERR("Error retrieving CBI FW_CONFIG field %d", FW_FAN); + return; + } + if (val != FW_FAN_PRESENT) { + /* Disable the fan */ + fan_set_count(0); + } else { + /* Configure the fan enable GPIO */ + gpio_pin_configure_dt(GPIO_DT_FROM_NODELABEL(gpio_fan_enable), + GPIO_OUTPUT); + } +} +DECLARE_HOOK(HOOK_INIT, fan_init, HOOK_PRIO_POST_FIRST); diff --git a/zephyr/projects/nissa/joxer/src/keyboard.c b/zephyr/projects/nissa/joxer/src/keyboard.c new file mode 100644 index 0000000000..48db40f53f --- /dev/null +++ b/zephyr/projects/nissa/joxer/src/keyboard.c @@ -0,0 +1,68 @@ +/* Copyright 2022 The ChromiumOS Authors + * Use of this source code is governed by a BSD-style license that can be + * found in the LICENSE file. + */ + +#include <zephyr/devicetree.h> +#include <zephyr/drivers/gpio.h> +#include <zephyr/logging/log.h> + +#include "cros_cbi.h" +#include "ec_commands.h" +#include "gpio/gpio.h" +#include "hooks.h" +#include "keyboard_8042_sharedlib.h" +#include "nissa_common.h" + +LOG_MODULE_DECLARE(nissa, CONFIG_NISSA_LOG_LEVEL); + +static const struct ec_response_keybd_config joxer_kb_legacy = { + .num_top_row_keys = 13, + .action_keys = { + TK_BACK, /* T1 */ + TK_REFRESH, /* T2 */ + TK_FULLSCREEN, /* T3 */ + TK_OVERVIEW, /* T4 */ + TK_SNAPSHOT, /* T5 */ + TK_BRIGHTNESS_DOWN, /* T6 */ + TK_BRIGHTNESS_UP, /* T7 */ + TK_KBD_BKLIGHT_TOGGLE, /* T8 */ + TK_PLAY_PAUSE, /* T9 */ + TK_MICMUTE, /* T10 */ + TK_VOL_MUTE, /* T11 */ + TK_VOL_DOWN, /* T12 */ + TK_VOL_UP, /* T13 */ + }, + .capabilities = KEYBD_CAP_SCRNLOCK_KEY, +}; + +__override const struct ec_response_keybd_config * +board_vivaldi_keybd_config(void) +{ + return &joxer_kb_legacy; +} + +/* + * Keyboard layout decided by FW config. + */ +static void kb_layout_init(void) +{ + int ret; + uint32_t val; + /* + * Retrieve the kb layout config. + */ + ret = cros_cbi_get_fw_config(FW_KB_LAYOUT, &val); + if (ret != 0) { + LOG_ERR("Error retrieving CBI FW_CONFIG field %d", + FW_KB_LAYOUT); + return; + } + /* + * If keyboard is US2(FW_KB_LAYOUT_US2), we need translate right ctrl + * to backslash(\|) key. + */ + if (val == FW_KB_LAYOUT_US2) + set_scancode_set2(4, 0, get_scancode_set2(2, 7)); +} +DECLARE_HOOK(HOOK_INIT, kb_layout_init, HOOK_PRIO_POST_FIRST); diff --git a/zephyr/projects/nissa/joxer/src/led.c b/zephyr/projects/nissa/joxer/src/led.c new file mode 100644 index 0000000000..d66e5b27a6 --- /dev/null +++ b/zephyr/projects/nissa/joxer/src/led.c @@ -0,0 +1,181 @@ +/* Copyright 2022 The ChromiumOS Authors + * Use of this source code is governed by a BSD-style license that can be + * found in the LICENSE file. + * + * Battery LED control for nissa + */ +#include <stdint.h> + +#include "charge_manager.h" +#include "common.h" +#include "compile_time_macros.h" +#include "ec_commands.h" +#include "gpio.h" +#include "led_common.h" +#include "led_onoff_states.h" +#include "pwm.h" +#include "util.h" + +#define BAT_LED_ON_LVL 0 +#define BAT_LED_OFF_LVL 1 + +#define PWR_LED_ON_LVL 1 +#define PWR_LED_OFF_LVL 0 + +#define LED_SIDESEL_MB_PORT 0 +#define LED_SIDESEL_DB_PORT 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_WHITE, + LED_INDEFINITE } }, + [STATE_DISCHARGE_S0] = { { LED_OFF, LED_INDEFINITE } }, + [STATE_DISCHARGE_S0_BAT_LOW] = { { EC_LED_COLOR_AMBER, + 1 * LED_ONE_SEC }, + { LED_OFF, 1 * LED_ONE_SEC } }, + [STATE_DISCHARGE_S3] = { { LED_OFF, LED_INDEFINITE } }, + [STATE_DISCHARGE_S5] = { { LED_OFF, LED_INDEFINITE } }, + [STATE_BATTERY_ERROR] = { { EC_LED_COLOR_AMBER, + 0.5 * LED_ONE_SEC }, + { LED_OFF, 0.5 * LED_ONE_SEC } }, + [STATE_FACTORY_TEST] = { { EC_LED_COLOR_WHITE, + 1 * LED_ONE_SEC }, + { LED_OFF, 1 * LED_ONE_SEC } }, + }; + +__override const struct led_descriptor + led_pwr_state_table[PWR_LED_NUM_STATES][LED_NUM_PHASES] = { + [PWR_LED_STATE_ON] = { { EC_LED_COLOR_WHITE, LED_INDEFINITE } }, + [PWR_LED_STATE_SUSPEND_AC] = { { EC_LED_COLOR_WHITE, + 1 * LED_ONE_SEC }, + { LED_OFF, 1 * LED_ONE_SEC } }, + [PWR_LED_STATE_SUSPEND_NO_AC] = { { EC_LED_COLOR_WHITE, + 1 * LED_ONE_SEC }, + { LED_OFF, + 1 * LED_ONE_SEC } }, + [PWR_LED_STATE_OFF] = { { LED_OFF, LED_INDEFINITE } }, + }; + +const enum ec_led_id supported_led_ids[] = { + EC_LED_ID_BATTERY_LED, + EC_LED_ID_POWER_LED, +}; + +const int supported_led_ids_count = ARRAY_SIZE(supported_led_ids); + +__override void led_set_color_battery(enum ec_led_colors color) +{ + int port; + + /* There are four battery leds, LED1/LED2 are on MB side and + * LED3/LED4 are on DB side. All leds are OFF by default. + */ + int led1, led2, led3, led4; + + led1 = led2 = led3 = led4 = BAT_LED_OFF_LVL; + + /* Check which port is the charging port, + * and turn on the corresponding led. + */ + if (led_auto_control_is_enabled(EC_LED_ID_BATTERY_LED)) { + port = charge_manager_get_active_charge_port(); + switch (port) { + case LED_SIDESEL_MB_PORT: + switch (color) { + case EC_LED_COLOR_AMBER: + led1 = BAT_LED_ON_LVL; + break; + case EC_LED_COLOR_WHITE: + led2 = BAT_LED_ON_LVL; + break; + default: /* LED_OFF and other unsupported colors */ + break; + } + break; + case LED_SIDESEL_DB_PORT: + switch (color) { + case EC_LED_COLOR_AMBER: + led3 = BAT_LED_ON_LVL; + break; + case EC_LED_COLOR_WHITE: + led4 = BAT_LED_ON_LVL; + break; + default: /* LED_OFF and other unsupported colors */ + break; + } + break; + default: /* Unknown charging port */ + break; + } + } else { + switch (color) { + case EC_LED_COLOR_AMBER: + led1 = BAT_LED_ON_LVL; + led3 = BAT_LED_ON_LVL; + break; + case EC_LED_COLOR_WHITE: + led2 = BAT_LED_ON_LVL; + led4 = BAT_LED_ON_LVL; + break; + default: /* LED_OFF and other unsupported colors */ + break; + } + } + + gpio_pin_set_dt(GPIO_DT_FROM_NODELABEL(gpio_led_1_odl), led1); + gpio_pin_set_dt(GPIO_DT_FROM_NODELABEL(gpio_led_2_odl), led2); + gpio_pin_set_dt(GPIO_DT_FROM_NODELABEL(gpio_led_3_l), led3); + gpio_pin_set_dt(GPIO_DT_FROM_NODELABEL(gpio_led_4_l), led4); +} + +__override void led_set_color_power(enum ec_led_colors color) +{ + if (color == EC_LED_COLOR_WHITE) + gpio_pin_set_dt(GPIO_DT_FROM_NODELABEL(gpio_power_led_gate), + PWR_LED_ON_LVL); + else + /* LED_OFF and unsupported colors */ + gpio_pin_set_dt(GPIO_DT_FROM_NODELABEL(gpio_power_led_gate), + PWR_LED_OFF_LVL); +} + +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_WHITE] = 1; + } else if (led_id == EC_LED_ID_POWER_LED) { + brightness_range[EC_LED_COLOR_WHITE] = 1; + } +} + +int led_set_brightness(enum ec_led_id led_id, const uint8_t *brightness) +{ + if (led_id == EC_LED_ID_BATTERY_LED) { + led_auto_control(led_id, 0); + if (brightness[EC_LED_COLOR_AMBER] != 0) + led_set_color_battery(EC_LED_COLOR_AMBER); + else if (brightness[EC_LED_COLOR_WHITE] != 0) + led_set_color_battery(EC_LED_COLOR_WHITE); + else if (brightness[LED_OFF] != 0) + led_set_color_battery(LED_OFF); + else { + led_auto_control(led_id, 1); + led_set_color_battery(LED_OFF); + } + } else if (led_id == EC_LED_ID_POWER_LED) { + if (brightness[EC_LED_COLOR_WHITE] != 0) + led_set_color_power(EC_LED_COLOR_WHITE); + else + led_set_color_power(LED_OFF); + } + + return EC_SUCCESS; +} diff --git a/zephyr/projects/nissa/joxer/src/usbc.c b/zephyr/projects/nissa/joxer/src/usbc.c new file mode 100644 index 0000000000..5fec9ab544 --- /dev/null +++ b/zephyr/projects/nissa/joxer/src/usbc.c @@ -0,0 +1,392 @@ +/* Copyright 2022 The ChromiumOS Authors + * Use of this source code is governed by a BSD-style license that can be + * found in the LICENSE file. + */ + +#include <zephyr/logging/log.h> +#include <ap_power/ap_power.h> + +#include "charge_state_v2.h" +#include "chipset.h" +#include "hooks.h" +#include "usb_mux.h" +#include "system.h" +#include "driver/charger/sm5803.h" +#include "driver/tcpm/it83xx_pd.h" +#include "driver/tcpm/ps8xxx_public.h" +#include "driver/tcpm/tcpci.h" + +#include "nissa_common.h" + +LOG_MODULE_DECLARE(nissa, CONFIG_NISSA_LOG_LEVEL); + +struct tcpc_config_t tcpc_config[CONFIG_USB_PD_PORT_MAX_COUNT] = { + { + .bus_type = EC_BUS_TYPE_EMBEDDED, + /* TCPC is embedded within EC so no i2c config needed */ + .drv = &it8xxx2_tcpm_drv, + /* Alert is active-low, push-pull */ + .flags = 0, + }, + { + /* + * Sub-board: optional PS8745 TCPC+redriver. Behaves the same + * as PS8815. + */ + .bus_type = EC_BUS_TYPE_I2C, + .i2c_info = { + .port = I2C_PORT_USB_C1_TCPC, + .addr_flags = PS8XXX_I2C_ADDR1_FLAGS, + }, + .drv = &ps8xxx_tcpm_drv, + /* PS8745 implements TCPCI 2.0 */ + .flags = TCPC_FLAGS_TCPCI_REV2_0, + }, +}; + +/* Vconn control for integrated ITE TCPC */ +void board_pd_vconn_ctrl(int port, enum usbpd_cc_pin cc_pin, int enabled) +{ + /* Vconn control is only for port 0 */ + if (port) + return; + + if (cc_pin == USBPD_CC_PIN_1) + gpio_pin_set_dt( + GPIO_DT_FROM_NODELABEL(gpio_en_usb_c0_cc1_vconn), + !!enabled); + else + gpio_pin_set_dt( + GPIO_DT_FROM_NODELABEL(gpio_en_usb_c0_cc2_vconn), + !!enabled); +} + +__override bool pd_check_vbus_level(int port, enum vbus_level level) +{ + return sm5803_check_vbus_level(port, level); +} + +/* + * Putting chargers into LPM when in suspend reduces power draw by about 8mW + * per charger, but also seems critical to correct operation in source mode: + * if chargers are not in LPM when a sink is first connected, VBUS sourcing + * works even if the partner is later removed (causing LPM entry) and + * reconnected (causing LPM exit). If in LPM initially, sourcing VBUS + * consistently causes the charger to report (apparently spurious) overcurrent + * failures. + * + * In short, this is important to making things work correctly but we don't + * understand why. + */ +static void board_chargers_suspend(struct ap_power_ev_callback *const cb, + const struct ap_power_ev_data data) +{ + void (*fn)(int chgnum); + + switch (data.event) { + case AP_POWER_SUSPEND: + fn = sm5803_enable_low_power_mode; + break; + case AP_POWER_RESUME: + fn = sm5803_disable_low_power_mode; + break; + default: + LOG_WRN("%s: power event %d is not recognized", __func__, + data.event); + return; + } + + fn(CHARGER_PRIMARY); + if (board_get_charger_chip_count() > 1) + fn(CHARGER_SECONDARY); +} + +static int board_chargers_suspend_init(const struct device *unused) +{ + static struct ap_power_ev_callback cb = { + .handler = board_chargers_suspend, + .events = AP_POWER_SUSPEND | AP_POWER_RESUME, + }; + ap_power_ev_add_callback(&cb); + return 0; +} +SYS_INIT(board_chargers_suspend_init, APPLICATION, 0); + +int board_set_active_charge_port(int port) +{ + int is_real_port = (port >= 0 && port < board_get_usb_pd_port_count()); + int i; + int old_port; + int rv; + + if (!is_real_port && port != CHARGE_PORT_NONE) + return EC_ERROR_INVAL; + + old_port = charge_manager_get_active_charge_port(); + LOG_INF("Charge update: p%d -> p%d", old_port, port); + + /* Check if port is sourcing VBUS. */ + if (port != CHARGE_PORT_NONE && charger_is_sourcing_otg_power(port)) { + LOG_WRN("Skip enable p%d: already sourcing", port); + return EC_ERROR_INVAL; + } + + /* Disable sinking on all ports except the desired one */ + for (i = 0; i < board_get_usb_pd_port_count(); i++) { + if (i == port) + continue; + + if (sm5803_vbus_sink_enable(i, 0)) + /* + * Do not early-return because this can fail during + * power-on which would put us into a loop. + */ + LOG_WRN("p%d: sink path disable failed.", i); + } + + /* Don't enable anything (stop here) if no ports were requested */ + if ((port == CHARGE_PORT_NONE) || (old_port == port)) + return EC_SUCCESS; + + /* + * Stop the charger IC from switching while changing ports. Otherwise, + * we can overcurrent the adapter we're switching to. (crbug.com/926056) + */ + if (old_port != CHARGE_PORT_NONE) + charger_discharge_on_ac(1); + + /* Enable requested charge port. */ + rv = sm5803_vbus_sink_enable(port, 1); + if (rv) + LOG_WRN("p%d: sink path enable failed: code %d", port, rv); + + /* Allow the charger IC to begin/continue switching. */ + charger_discharge_on_ac(0); + + return rv; +} + +uint16_t tcpc_get_alert_status(void) +{ + /* + * TCPC 0 is embedded in the EC and processes interrupts in the chip + * code (it83xx/intc.c). This function only needs to poll port C1 if + * present. + */ + uint16_t status = 0; + int regval; + + /* Is the C1 port present and its IRQ line asserted? */ + if (board_get_usb_pd_port_count() == 2 && + !gpio_pin_get_dt(GPIO_DT_FROM_ALIAS(gpio_usb_c1_int_odl))) { + /* + * C1 IRQ is shared between BC1.2 and TCPC; poll TCPC to see if + * it asserted the IRQ. + */ + if (!tcpc_read16(1, TCPC_REG_ALERT, ®val)) { + if (regval) + status = PD_STATUS_TCPC_ALERT_1; + } + } + + return status; +} + +void pd_power_supply_reset(int port) +{ + int prev_en; + + if (port < 0 || port >= board_get_usb_pd_port_count()) + return; + + prev_en = charger_is_sourcing_otg_power(port); + + /* Disable Vbus */ + charger_enable_otg_power(port, 0); + + /* Discharge Vbus if previously enabled */ + if (prev_en) + sm5803_set_vbus_disch(port, 1); + + /* Notify host of power info change. */ + pd_send_host_event(PD_EVENT_POWER_CHANGE); +} + +int pd_set_power_supply_ready(int port) +{ + enum ec_error_list rv; + + if (port < 0 || port > board_get_usb_pd_port_count()) { + LOG_WRN("Port C%d does not exist, cannot enable VBUS", port); + return EC_ERROR_INVAL; + } + + /* Disable sinking */ + rv = sm5803_vbus_sink_enable(port, 0); + if (rv) { + LOG_WRN("C%d failed to disable sinking: %d", port, rv); + return rv; + } + + /* Disable Vbus discharge */ + rv = sm5803_set_vbus_disch(port, 0); + if (rv) { + LOG_WRN("C%d failed to clear VBUS discharge: %d", port, rv); + return rv; + } + + /* Provide Vbus */ + rv = charger_enable_otg_power(port, 1); + if (rv) { + LOG_WRN("C%d failed to enable VBUS sourcing: %d", port, rv); + return rv; + } + + /* Notify host of power info change. */ + pd_send_host_event(PD_EVENT_POWER_CHANGE); + + return EC_SUCCESS; +} + +__override void typec_set_source_current_limit(int port, enum tcpc_rp_value rp) +{ + int rv; + const int current = rp == TYPEC_RP_3A0 ? 3000 : 1500; + + rv = charger_set_otg_current_voltage(port, current, 5000); + if (rv != EC_SUCCESS) { + LOG_WRN("Failed to set source ilimit on port %d to %d: %d", + port, current, rv); + } +} + +void board_reset_pd_mcu(void) +{ + /* + * Do nothing. The integrated TCPC for C0 lacks a dedicated reset + * command, and C1 (if present) doesn't have a reset pin connected + * to the EC. + */ +} + +#define INT_RECHECK_US 5000 + +/* C0 interrupt line shared by BC 1.2 and charger */ + +static void check_c0_line(void); +DECLARE_DEFERRED(check_c0_line); + +static void notify_c0_chips(void) +{ + usb_charger_task_set_event(0, USB_CHG_EVENT_BC12); + sm5803_interrupt(0); +} + +static void check_c0_line(void) +{ + /* + * If line is still being held low, see if there's more to process from + * one of the chips + */ + if (!gpio_pin_get_dt(GPIO_DT_FROM_NODELABEL(gpio_usb_c0_int_odl))) { + notify_c0_chips(); + hook_call_deferred(&check_c0_line_data, INT_RECHECK_US); + } +} + +void usb_c0_interrupt(enum gpio_signal s) +{ + /* Cancel any previous calls to check the interrupt line */ + hook_call_deferred(&check_c0_line_data, -1); + + /* Notify all chips using this line that an interrupt came in */ + notify_c0_chips(); + + /* Check the line again in 5ms */ + hook_call_deferred(&check_c0_line_data, INT_RECHECK_US); +} + +/* C1 interrupt line shared by BC 1.2, TCPC, and charger */ +static void check_c1_line(void); +DECLARE_DEFERRED(check_c1_line); + +static void notify_c1_chips(void) +{ + schedule_deferred_pd_interrupt(1); + usb_charger_task_set_event(1, USB_CHG_EVENT_BC12); + /* Charger is handled in board_process_pd_alert */ +} + +static void check_c1_line(void) +{ + /* + * If line is still being held low, see if there's more to process from + * one of the chips. + */ + if (!gpio_pin_get_dt(GPIO_DT_FROM_ALIAS(gpio_usb_c1_int_odl))) { + notify_c1_chips(); + hook_call_deferred(&check_c1_line_data, INT_RECHECK_US); + } +} + +void usb_c1_interrupt(enum gpio_signal s) +{ + /* Cancel any previous calls to check the interrupt line */ + hook_call_deferred(&check_c1_line_data, -1); + + /* Notify all chips using this line that an interrupt came in */ + notify_c1_chips(); + + /* Check the line again in 5ms */ + hook_call_deferred(&check_c1_line_data, INT_RECHECK_US); +} + +/* + * Check state of IRQ lines at startup, ensuring an IRQ that happened before + * the EC started up won't get lost (leaving the IRQ line asserted and blocking + * any further interrupts on the port). + * + * Although the PD task will check for pending TCPC interrupts on startup, + * the charger sharing the IRQ will not be polled automatically. + */ +void board_handle_initial_typec_irq(void) +{ + check_c0_line(); + check_c1_line(); +} +/* + * This must run after sub-board detection (which happens in EC main()), + * but isn't depended on by anything else either. + */ +DECLARE_HOOK(HOOK_INIT, board_handle_initial_typec_irq, HOOK_PRIO_LAST); + +/* + * Handle charger interrupts in the PD task. Not doing so can lead to a priority + * inversion where we fail to respond to TCPC alerts quickly enough because we + * don't get another edge on a shared IRQ until the charger interrupt is cleared + * (or the IRQ is polled again), which happens in the low-priority charger task: + * the high-priority type-C handler is thus blocked on the lower-priority + * charger. + * + * To avoid that, we run charger interrupts at the same priority. + */ +void board_process_pd_alert(int port) +{ + /* + * Port 0 doesn't use an external TCPC, so its interrupts don't need + * this special handling. + */ + if (port == 1 && + !gpio_pin_get_dt(GPIO_DT_FROM_ALIAS(gpio_usb_c1_int_odl))) { + sm5803_handle_interrupt(port); + } +} + +int pd_snk_is_vbus_provided(int port) +{ + int chg_det = 0; + + sm5803_get_chg_det(port, &chg_det); + + return chg_det; +} diff --git a/zephyr/projects/nissa/nereid/generated.dtsi b/zephyr/projects/nissa/nereid/generated.dtsi new file mode 100644 index 0000000000..bca58c478e --- /dev/null +++ b/zephyr/projects/nissa/nereid/generated.dtsi @@ -0,0 +1,260 @@ +/* Copyright 2022 The ChromiumOS Authors + * Use of this source code is governed by a BSD-style license that can be + * found in the LICENSE file. + * + * This file is auto-generated - do not edit! + */ + +/ { + + named-adc-channels { + compatible = "named-adc-channels"; + + adc_ec_vsense_pp1050_proc: ec_vsense_pp1050_proc { + enum-name = "ADC_PP1050_PROC"; + io-channels = <&adc0 14>; + }; + adc_ec_vsense_pp3300_s5: ec_vsense_pp3300_s5 { + enum-name = "ADC_PP3300_S5"; + io-channels = <&adc0 0>; + }; + adc_temp_sensor_1: temp_sensor_1 { + enum-name = "ADC_TEMP_SENSOR_1"; + io-channels = <&adc0 2>; + }; + adc_temp_sensor_2: temp_sensor_2 { + enum-name = "ADC_TEMP_SENSOR_2"; + io-channels = <&adc0 3>; + }; + adc_temp_sensor_3: temp_sensor_3 { + enum-name = "ADC_TEMP_SENSOR_3"; + io-channels = <&adc0 13>; + }; + }; + + named-gpios { + compatible = "named-gpios"; + + gpio_acc_int_l: acc_int_l { + gpios = <&gpioc 0 GPIO_INPUT>; + }; + gpio_all_sys_pwrgd: all_sys_pwrgd { + gpios = <&gpiob 7 GPIO_INPUT>; + }; + gpio_ccd_mode_odl: ccd_mode_odl { + gpios = <&gpioh 5 GPIO_INPUT>; + enum-name = "GPIO_CCD_MODE_ODL"; + }; + gpio_cpu_c10_gate_l: cpu_c10_gate_l { + gpios = <&gpiog 1 GPIO_INPUT>; + }; + gpio_ec_battery_pres_odl: ec_battery_pres_odl { + gpios = <&gpioi 4 GPIO_INPUT>; + enum-name = "GPIO_BATT_PRES_ODL"; + }; + gpio_ec_cbi_wp: ec_cbi_wp { + gpios = <&gpioj 5 GPIO_OUTPUT>; + }; + gpio_ec_edp_bl_en_od: ec_edp_bl_en_od { + gpios = <&gpiok 4 GPIO_ODR_HIGH>; + enum-name = "GPIO_ENABLE_BACKLIGHT"; + }; + gpio_ec_entering_rw: ec_entering_rw { + gpios = <&gpioc 7 GPIO_OUTPUT>; + enum-name = "GPIO_ENTERING_RW"; + }; + gpio_ec_gsc_packet_mode: ec_gsc_packet_mode { + gpios = <&gpioh 1 GPIO_OUTPUT>; + enum-name = "GPIO_PACKET_MODE_EN"; + }; + gpio_ec_pch_wake_odl: ec_pch_wake_odl { + gpios = <&gpiob 2 GPIO_ODR_LOW>; + }; + gpio_ec_prochot_odl: ec_prochot_odl { + gpios = <&gpioi 1 GPIO_ODR_HIGH>; + }; + gpio_ec_soc_dsw_pwrok: ec_soc_dsw_pwrok { + gpios = <&gpiol 7 GPIO_OUTPUT>; + }; + gpio_ec_soc_hdmi_hpd: ec_soc_hdmi_hpd { + gpios = <&gpiok 7 GPIO_OUTPUT>; + }; + gpio_ec_soc_int_odl: ec_soc_int_odl { + gpios = <&gpiod 5 GPIO_ODR_HIGH>; + enum-name = "GPIO_EC_INT_L"; + }; + gpio_ec_soc_pch_pwrok_od: ec_soc_pch_pwrok_od { + gpios = <&gpiod 6 GPIO_ODR_HIGH>; + }; + gpio_ec_soc_pwr_btn_odl: ec_soc_pwr_btn_odl { + gpios = <&gpiob 6 GPIO_ODR_HIGH>; + enum-name = "GPIO_PCH_PWRBTN_L"; + }; + gpio_ec_soc_rsmrst_l: ec_soc_rsmrst_l { + gpios = <&gpioh 0 GPIO_OUTPUT>; + }; + gpio_ec_soc_rtcrst: ec_soc_rtcrst { + gpios = <&gpiok 2 GPIO_OUTPUT>; + }; + gpio_ec_soc_sys_pwrok: ec_soc_sys_pwrok { + gpios = <&gpiof 2 GPIO_OUTPUT>; + }; + gpio_ec_soc_vccst_pwrgd_od: ec_soc_vccst_pwrgd_od { + gpios = <&gpioe 5 GPIO_ODR_HIGH>; + }; + gpio_ec_wp_odl: ec_wp_odl { + gpios = <&gpioa 6 (GPIO_INPUT | GPIO_ACTIVE_LOW)>; + }; + gpio_en_kb_bl: en_kb_bl { + gpios = <&gpioj 3 GPIO_OUTPUT>; + enum-name = "GPIO_EN_KEYBOARD_BACKLIGHT"; + }; + gpio_en_pp3300_s5: en_pp3300_s5 { + gpios = <&gpioc 5 GPIO_OUTPUT>; + enum-name = "GPIO_TEMP_SENSOR_POWER"; + }; + gpio_en_pp5000_pen_x: en_pp5000_pen_x { + gpios = <&gpiob 5 GPIO_OUTPUT>; + }; + gpio_en_pp5000_s5: en_pp5000_s5 { + gpios = <&gpiok 5 GPIO_OUTPUT>; + }; + gpio_en_slp_z: en_slp_z { + gpios = <&gpiok 3 GPIO_OUTPUT>; + }; + gpio_en_usb_a0_vbus: en_usb_a0_vbus { + gpios = <&gpiol 6 GPIO_OUTPUT>; + }; + gpio_en_usb_c0_cc1_vconn: en_usb_c0_cc1_vconn { + gpios = <&gpioh 4 GPIO_OUTPUT>; + }; + gpio_en_usb_c0_cc2_vconn: en_usb_c0_cc2_vconn { + gpios = <&gpioh 6 GPIO_OUTPUT>; + }; + gpio_gsc_ec_pwr_btn_odl: gsc_ec_pwr_btn_odl { + gpios = <&gpioe 2 GPIO_INPUT_PULL_UP>; + enum-name = "GPIO_POWER_BUTTON_L"; + }; + gpio_hdmi_sel: hdmi_sel { + gpios = <&gpioc 6 GPIO_OUTPUT>; + }; + gpio_imu_int_l: imu_int_l { + gpios = <&gpioj 0 GPIO_INPUT>; + }; + gpio_imvp91_vrrdy_od: imvp91_vrrdy_od { + gpios = <&gpioj 4 GPIO_INPUT>; + }; + gpio_lid_open: lid_open { + gpios = <&gpiof 3 GPIO_INPUT>; + enum-name = "GPIO_LID_OPEN"; + }; + gpio_pen_detect_odl: pen_detect_odl { + gpios = <&gpioj 1 GPIO_INPUT_PULL_UP>; + }; + gpio_pg_pp1050_mem_s3_od: pg_pp1050_mem_s3_od { + gpios = <&gpiod 3 GPIO_INPUT>; + }; + gpio_pg_pp5000_s5_od: pg_pp5000_s5_od { + gpios = <&gpioe 3 GPIO_INPUT>; + }; + gpio_rsmrst_pwrgd_l: rsmrst_pwrgd_l { + gpios = <&gpioe 1 GPIO_INPUT_PULL_UP>; + }; + gpio_slp_s0_l: slp_s0_l { + gpios = <&gpioe 4 GPIO_INPUT>; + }; + gpio_slp_s3_l: slp_s3_l { + gpios = <&gpioh 3 GPIO_INPUT>; + }; + gpio_slp_s4_l: slp_s4_l { + gpios = <&gpioi 5 GPIO_INPUT>; + }; + gpio_slp_sus_l: slp_sus_l { + gpios = <&gpiog 2 GPIO_INPUT>; + }; + gpio_sub_usb_a1_ilimit_sdp: sub_usb_a1_ilimit_sdp { + gpios = <&gpiof 1 GPIO_OUTPUT>; + enum-name = "GPIO_USB2_ILIM_SEL"; + }; + gpio_sys_rst_odl: sys_rst_odl { + gpios = <&gpiod 1 GPIO_ODR_HIGH>; + }; + gpio_tablet_mode_l: tablet_mode_l { + gpios = <&gpioa 7 GPIO_INPUT>; + enum-name = "GPIO_TABLET_MODE_L"; + }; + gpio_usb_a0_ilimit_sdp: usb_a0_ilimit_sdp { + gpios = <&gpiol 5 GPIO_OUTPUT>; + enum-name = "GPIO_USB1_ILIM_SEL"; + }; + gpio_usb_c0_frs: usb_c0_frs { + gpios = <&gpioc 4 GPIO_OUTPUT>; + }; + gpio_usb_c0_int_odl: usb_c0_int_odl { + gpios = <&gpiok 0 GPIO_INPUT_PULL_UP>; + }; + gpio_vccin_aux_vid0: vccin_aux_vid0 { + gpios = <&gpiod 0 GPIO_INPUT>; + }; + gpio_vccin_aux_vid1: vccin_aux_vid1 { + gpios = <&gpiok 1 GPIO_INPUT>; + }; + gpio_voldn_btn_odl: voldn_btn_odl { + gpios = <&gpioi 6 GPIO_INPUT_PULL_UP>; + enum-name = "GPIO_VOLUME_DOWN_L"; + }; + gpio_volup_btn_odl: volup_btn_odl { + gpios = <&gpioi 7 GPIO_INPUT_PULL_UP>; + enum-name = "GPIO_VOLUME_UP_L"; + }; + }; + + named-i2c-ports { + compatible = "named-i2c-ports"; + + i2c_ec_i2c_eeprom: ec_i2c_eeprom { + i2c-port = <&i2c0>; + enum-names = "I2C_PORT_EEPROM"; + }; + i2c_ec_i2c_batt: ec_i2c_batt { + i2c-port = <&i2c1>; + enum-names = "I2C_PORT_BATTERY"; + }; + i2c_ec_i2c_sensor: ec_i2c_sensor { + i2c-port = <&i2c2>; + enum-names = "I2C_PORT_SENSOR"; + }; + i2c_ec_i2c_sub_usb_c1: ec_i2c_sub_usb_c1 { + i2c-port = <&i2c4>; + enum-names = "I2C_PORT_USB_C1_TCPC"; + }; + i2c_ec_i2c_usb_c0: ec_i2c_usb_c0 { + i2c-port = <&i2c5>; + enum-names = "I2C_PORT_USB_C0_TCPC"; + }; + }; +}; + +&adc0 { + status = "okay"; +}; + +&i2c0 { + status = "okay"; +}; + +&i2c1 { + status = "okay"; +}; + +&i2c2 { + status = "okay"; +}; + +&i2c4 { + status = "okay"; +}; + +&i2c5 { + status = "okay"; +}; diff --git a/zephyr/projects/nissa/nereid/keyboard.dtsi b/zephyr/projects/nissa/nereid/keyboard.dtsi new file mode 100644 index 0000000000..04a620767a --- /dev/null +++ b/zephyr/projects/nissa/nereid/keyboard.dtsi @@ -0,0 +1,22 @@ +/* Copyright 2022 The ChromiumOS Authors + * Use of this source code is governed by a BSD-style license that can be + * found in the LICENSE file. + */ + +/ { + kblight { + compatible = "cros-ec,kblight-pwm"; + /* + * Use 324 Hz so that 32Khz clock source is used, + * which is not gated in power saving mode. + */ + pwms = <&pwm0 0 PWM_HZ(324) PWM_POLARITY_NORMAL>; + }; +}; + +&pwm0 { + status = "okay"; + prescaler-cx = <PWM_PRESCALER_C4>; + pinctrl-0 = <&pwm0_gpa0_default>; + pinctrl-names = "default"; +}; diff --git a/zephyr/projects/nissa/nereid/motionsense.dtsi b/zephyr/projects/nissa/nereid/motionsense.dtsi new file mode 100644 index 0000000000..a65bb48fbd --- /dev/null +++ b/zephyr/projects/nissa/nereid/motionsense.dtsi @@ -0,0 +1,147 @@ +/* Copyright 2022 The ChromiumOS Authors + * Use of this source code is governed by a BSD-style license that can be + * found in the LICENSE file. + */ + +#include <dt-bindings/motionsense/utils.h> + + +/ { + aliases { + /* + * Interrupt bindings for sensor devices. + */ + bmi3xx-int = &base_accel; + bma4xx-int = &lid_accel; + }; + + /* + * Declare mutexes used by sensor drivers. + * A mutex node is used to create an instance of mutex_t. + * A mutex node is referenced by a sensor node if the + * corresponding sensor driver needs to use the + * instance of the mutex. + */ + motionsense-mutex { + compatible = "cros-ec,motionsense-mutex"; + lid_mutex: lid-mutex { + }; + + base_mutex: base-mutex { + }; + }; + + /* Rotation matrix used by drivers. */ + motionsense-rotation-ref { + compatible = "cros-ec,motionsense-rotation-ref"; + lid_rot_ref: lid-rotation-ref { + mat33 = <0 (-1) 0 + (-1) 0 0 + 0 0 (-1)>; + }; + + base_rot_ref: base-rotation-ref { + mat33 = <0 1 0 + (-1) 0 0 + 0 0 1>; + }; + }; + + /* + * Driver specific data. A driver-specific data can be shared with + * different motion sensors while they are using the same driver. + * + * If a node's compatible starts with "cros-ec,accelgyro-", it is for + * a common structure defined in accelgyro.h. + * e.g) compatible = "cros-ec,accelgyro-als-drv-data" is for + * "struct als_drv_data_t" in accelgyro.h + */ + motionsense-sensor-data { + bmi323_data: bmi323-drv-data { + compatible = "cros-ec,drvdata-bmi3xx"; + status = "okay"; + }; + + bma422_data: bma422-drv-data { + compatible = "cros-ec,drvdata-bma4xx"; + status = "okay"; + }; + }; + + /* + * List of motion sensors that creates motion_sensors array. + * The nodelabel "lid_accel" and "base_accel" are used to indicate + * motion sensor IDs for lid angle calculation. + * TODO(b/238139272): The first entries of the array must be + * accelerometers,then gyroscope. Fix this dependency in the DTS + * processing which makes the devicetree entries independent. + */ + motionsense-sensor { + lid_accel: lid-accel { + compatible = "cros-ec,bma4xx"; + status = "okay"; + + active-mask = "SENSOR_ACTIVE_S0_S3"; + location = "MOTIONSENSE_LOC_LID"; + mutex = <&lid_mutex>; + port = <&i2c_ec_i2c_sensor>; + rot-standard-ref = <&lid_rot_ref>; + default-range = <2>; + drv-data = <&bma422_data>; + configs { + compatible = + "cros-ec,motionsense-sensor-config"; + ec-s0 { + odr = <(10000 | ROUND_UP_FLAG)>; + }; + ec-s3 { + odr = <(10000 | ROUND_UP_FLAG)>; + }; + }; + }; + + base_accel: base-accel { + compatible = "cros-ec,bmi3xx-accel"; + status = "okay"; + + active-mask = "SENSOR_ACTIVE_S0_S3"; + location = "MOTIONSENSE_LOC_BASE"; + mutex = <&base_mutex>; + port = <&i2c_ec_i2c_sensor>; + rot-standard-ref = <&base_rot_ref>; + drv-data = <&bmi323_data>; + configs { + compatible = + "cros-ec,motionsense-sensor-config"; + ec-s0 { + odr = <(10000 | ROUND_UP_FLAG)>; + }; + ec-s3 { + odr = <(10000 | ROUND_UP_FLAG)>; + }; + }; + }; + + base_gyro: base-gyro { + compatible = "cros-ec,bmi3xx-gyro"; + status = "okay"; + + active-mask = "SENSOR_ACTIVE_S0_S3"; + location = "MOTIONSENSE_LOC_BASE"; + mutex = <&base_mutex>; + port = <&i2c_ec_i2c_sensor>; + rot-standard-ref = <&base_rot_ref>; + drv-data = <&bmi323_data>; + }; + }; + + motionsense-sensor-info { + compatible = "cros-ec,motionsense-sensor-info"; + + /* + * list of GPIO interrupts that have to + * be enabled at initial stage + */ + sensor-irqs = <&int_imu &int_lid_imu>; + }; +}; diff --git a/zephyr/projects/nissa/nereid/nereid_vif.xml b/zephyr/projects/nissa/nereid/nereid_vif.xml new file mode 100644 index 0000000000..91c8dbe68b --- /dev/null +++ b/zephyr/projects/nissa/nereid/nereid_vif.xml @@ -0,0 +1,350 @@ +<?xml version="1.0" encoding="utf-8"?>
+<vif:VIF xmlns:opt="http://usb.org/VendorInfoFileOptionalContent.xsd" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:vif="http://usb.org/VendorInfoFile.xsd">
+ <vif:VIF_Specification>3.19</vif:VIF_Specification>
+ <vif:VIF_App>
+ <vif:Vendor>USB-IF</vif:Vendor>
+ <vif:Name>VIF Editor</vif:Name>
+ <vif:Version>3.2.4.0</vif:Version>
+ </vif:VIF_App>
+ <vif:Vendor_Name>Google</vif:Vendor_Name>
+ <vif:Model_Part_Number>Nereid</vif:Model_Part_Number>
+ <vif:Product_Revision>1</vif:Product_Revision>
+ <vif:TID>0</vif:TID>
+ <vif:VIF_Product_Type value="0">Port Product</vif:VIF_Product_Type>
+ <vif:Certification_Type value="1">Reference Platform</vif:Certification_Type>
+ <vif:Product>
+ <!--Product Level Content:-->
+ </vif:Product>
+ <vif:Component>
+ <!--Component 0: Port 0-->
+ <!--;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-->
+ <!--;Component-->
+ <!--;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-->
+ <vif:Port_Label>0</vif:Port_Label>
+ <vif:Connector_Type value="2">Type-C®</vif:Connector_Type>
+ <vif:USB4_Supported value="false" />
+ <vif:USB_PD_Support value="true" />
+ <vif:PD_Port_Type value="4">DRP</vif:PD_Port_Type>
+ <vif:Type_C_State_Machine value="2">DRP</vif:Type_C_State_Machine>
+ <vif:Port_Battery_Powered value="true" />
+ <vif:BC_1_2_Support value="2">Charging Port</vif:BC_1_2_Support>
+ <vif:Captive_Cable value="false" />
+ <!--;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-->
+ <!--;General PD-->
+ <!--;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-->
+ <vif:PD_Spec_Revision_Major value="3" />
+ <vif:PD_Spec_Revision_Minor value="1" />
+ <vif:PD_Spec_Version_Major value="1" />
+ <vif:PD_Spec_Version_Minor value="3" />
+ <vif:PD_Specification_Revision value="2">Revision 3</vif:PD_Specification_Revision>
+ <vif:SOP_Capable value="true" />
+ <vif:SOP_P_Capable value="true" />
+ <vif:SOP_PP_Capable value="true" />
+ <vif:SOP_P_Debug_Capable value="false" />
+ <vif:SOP_PP_Debug_Capable value="false" />
+ <vif:Manufacturer_Info_Supported_Port value="true" />
+ <vif:Manufacturer_Info_VID_Port value="6353">18D1</vif:Manufacturer_Info_VID_Port>
+ <vif:Manufacturer_Info_PID_Port value="20570">505A</vif:Manufacturer_Info_PID_Port>
+ <vif:Chunking_Implemented_SOP value="true" />
+ <vif:Unchunked_Extended_Messages_Supported value="false" />
+ <vif:Security_Msgs_Supported_SOP value="false" />
+ <vif:Unconstrained_Power value="false" />
+ <vif:Num_Fixed_Batteries value="1" />
+ <vif:Num_Swappable_Battery_Slots value="0" />
+ <vif:ID_Header_Connector_Type_SOP value="2">USB Type-C® Receptacle</vif:ID_Header_Connector_Type_SOP>
+ <!--;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-->
+ <!--;PD Capabilities-->
+ <!--;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-->
+ <vif:USB_Comms_Capable value="true" />
+ <vif:DR_Swap_To_DFP_Supported value="true" />
+ <vif:DR_Swap_To_UFP_Supported value="false" />
+ <vif:VCONN_Swap_To_On_Supported value="true" />
+ <vif:VCONN_Swap_To_Off_Supported value="true" />
+ <vif:Responds_To_Discov_SOP_UFP value="false" />
+ <vif:Responds_To_Discov_SOP_DFP value="true" />
+ <vif:Attempts_Discov_SOP value="true" />
+ <vif:Power_Interruption_Available value="0">No Interruption Possible</vif:Power_Interruption_Available>
+ <vif:Data_Reset_Supported value="false" />
+ <vif:Enter_USB_Supported value="false" />
+ <!--;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-->
+ <!--;USB Type-C®-->
+ <!--;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-->
+ <vif:Type_C_Can_Act_As_Host value="true" />
+ <vif:Type_C_Can_Act_As_Device value="false" />
+ <vif:Type_C_Implements_Try_SRC value="true" />
+ <vif:Type_C_Implements_Try_SNK value="false" />
+ <vif:Type_C_Supports_Audio_Accessory value="false" />
+ <vif:Type_C_Is_VCONN_Powered_Accessory value="false" />
+ <vif:Type_C_Is_Debug_Target_SRC value="true" />
+ <vif:Type_C_Is_Debug_Target_SNK value="true" />
+ <vif:RP_Value value="1">1.5A</vif:RP_Value>
+ <vif:Type_C_Port_On_Hub value="false" />
+ <vif:Type_C_Power_Source value="2">Both</vif:Type_C_Power_Source>
+ <vif:Type_C_Sources_VCONN value="true" />
+ <vif:Type_C_Is_Alt_Mode_Controller value="true" />
+ <vif:Type_C_Is_Alt_Mode_Adapter value="false" />
+ <!--;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-->
+ <!--;Product Power-->
+ <!--;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-->
+ <vif:Product_Total_Source_Power_mW value="15000">15000 mW</vif:Product_Total_Source_Power_mW>
+ <vif:Port_Source_Power_Type value="0">Assured</vif:Port_Source_Power_Type>
+ <!--;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-->
+ <!--;USB Host-->
+ <!--;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-->
+ <vif:Host_Supports_USB_Data value="true" />
+ <vif:Host_Speed value="1">USB 3.2 Gen 1x1</vif:Host_Speed>
+ <vif:Host_Contains_Captive_Retimer value="false" />
+ <vif:Host_Truncates_DP_For_tDHPResponse value="false" />
+ <vif:Host_Is_Embedded value="false" />
+ <vif:Host_Suspend_Supported value="true" />
+ <vif:Is_DFP_On_Hub value="false" />
+ <!--;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-->
+ <!--;Battery Charging 1.2-->
+ <!--;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-->
+ <vif:BC_1_2_Charging_Port_Type value="1">CDP</vif:BC_1_2_Charging_Port_Type>
+ <!--;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-->
+ <!--;PD Source-->
+ <!--;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-->
+ <vif:PD_Power_As_Source value="15000">15000 mW</vif:PD_Power_As_Source>
+ <vif:EPR_Supported_As_Src value="false" />
+ <vif:USB_Suspend_May_Be_Cleared value="false" />
+ <vif:Sends_Pings value="false" />
+ <vif:FR_Swap_Type_C_Current_Capability_As_Initial_Sink value="0">FR_Swap not supported</vif:FR_Swap_Type_C_Current_Capability_As_Initial_Sink>
+ <vif:Master_Port value="false" />
+ <vif:Num_Src_PDOs value="1" />
+ <vif:PD_OC_Protection value="true" />
+ <vif:PD_OCP_Method value="0">Over-Current Response</vif:PD_OCP_Method>
+ <!--Bundle: SrcPdoList-->
+ <vif:SrcPdoList>
+ <vif:SrcPDO>
+ <!--Source PDO 1-->
+ <vif:Src_PDO_Supply_Type value="0">Fixed</vif:Src_PDO_Supply_Type>
+ <vif:Src_PDO_Peak_Current value="0">100% IOC</vif:Src_PDO_Peak_Current>
+ <vif:Src_PDO_Voltage value="100">5000 mV</vif:Src_PDO_Voltage>
+ <vif:Src_PDO_Max_Current value="300">3000 mA</vif:Src_PDO_Max_Current>
+ <vif:Src_PD_OCP_OC_Debounce value="0">0 msec</vif:Src_PD_OCP_OC_Debounce>
+ <vif:Src_PD_OCP_OC_Threshold value="300">3000 mA</vif:Src_PD_OCP_OC_Threshold>
+ </vif:SrcPDO>
+ </vif:SrcPdoList>
+ <!--;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-->
+ <!--;PD Sink-->
+ <!--;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-->
+ <vif:PD_Power_As_Sink value="45000">45000 mW</vif:PD_Power_As_Sink>
+ <vif:EPR_Supported_As_Snk value="false" />
+ <vif:No_USB_Suspend_May_Be_Set value="true" />
+ <vif:GiveBack_May_Be_Set value="false" />
+ <vif:Higher_Capability_Set value="false" />
+ <vif:FR_Swap_Reqd_Type_C_Current_As_Initial_Source value="0">FR_Swap not supported</vif:FR_Swap_Reqd_Type_C_Current_As_Initial_Source>
+ <vif:Num_Snk_PDOs value="3" />
+ <!--Bundle: SnkPdoList-->
+ <vif:SnkPdoList>
+ <vif:SnkPDO>
+ <!--Sink PDO 1-->
+ <vif:Snk_PDO_Supply_Type value="0">Fixed</vif:Snk_PDO_Supply_Type>
+ <vif:Snk_PDO_Voltage value="100">5000 mV</vif:Snk_PDO_Voltage>
+ <vif:Snk_PDO_Op_Current value="300">3000 mA</vif:Snk_PDO_Op_Current>
+ </vif:SnkPDO>
+ <vif:SnkPDO>
+ <!--Sink PDO 2-->
+ <vif:Snk_PDO_Supply_Type value="1">Battery</vif:Snk_PDO_Supply_Type>
+ <vif:Snk_PDO_Op_Power value="60">15000 mW</vif:Snk_PDO_Op_Power>
+ <vif:Snk_PDO_Min_Voltage value="95">4750 mV</vif:Snk_PDO_Min_Voltage>
+ <vif:Snk_PDO_Max_Voltage value="300">15000 mV</vif:Snk_PDO_Max_Voltage>
+ </vif:SnkPDO>
+ <vif:SnkPDO>
+ <!--Sink PDO 3-->
+ <vif:Snk_PDO_Supply_Type value="2">Variable</vif:Snk_PDO_Supply_Type>
+ <vif:Snk_PDO_Min_Voltage value="95">4750 mV</vif:Snk_PDO_Min_Voltage>
+ <vif:Snk_PDO_Max_Voltage value="300">15000 mV</vif:Snk_PDO_Max_Voltage>
+ <vif:Snk_PDO_Op_Current value="300">3000 mA</vif:Snk_PDO_Op_Current>
+ </vif:SnkPDO>
+ </vif:SnkPdoList>
+ <!--;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-->
+ <!--;Dual Role-->
+ <!--;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-->
+ <vif:Accepts_PR_Swap_As_Src value="true" />
+ <vif:Accepts_PR_Swap_As_Snk value="true" />
+ <vif:Requests_PR_Swap_As_Src value="true" />
+ <vif:Requests_PR_Swap_As_Snk value="true" />
+ <vif:FR_Swap_Supported_As_Initial_Sink value="false" />
+ <!--;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-->
+ <!--;SOP Discover ID-->
+ <!--;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-->
+ <vif:XID_SOP value="0" />
+ <vif:Data_Capable_As_USB_Host_SOP value="true" />
+ <vif:Data_Capable_As_USB_Device_SOP value="false" />
+ <vif:Product_Type_UFP_SOP value="0">Undefined</vif:Product_Type_UFP_SOP>
+ <vif:Product_Type_DFP_SOP value="2">PDUSB Host</vif:Product_Type_DFP_SOP>
+ <vif:DFP_VDO_Port_Number value="0" />
+ <vif:Modal_Operation_Supported_SOP value="false" />
+ <vif:USB_VID_SOP value="6353">18D1</vif:USB_VID_SOP>
+ <vif:PID_SOP value="20570">505A</vif:PID_SOP>
+ <vif:bcdDevice_SOP value="0">0000</vif:bcdDevice_SOP>
+ </vif:Component>
+ <vif:Component>
+ <!--Component 1: Port 1-->
+ <!--;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-->
+ <!--;Component-->
+ <!--;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-->
+ <vif:Port_Label>1</vif:Port_Label>
+ <vif:Connector_Type value="2">Type-C®</vif:Connector_Type>
+ <vif:USB4_Supported value="false" />
+ <vif:USB_PD_Support value="true" />
+ <vif:PD_Port_Type value="4">DRP</vif:PD_Port_Type>
+ <vif:Type_C_State_Machine value="2">DRP</vif:Type_C_State_Machine>
+ <vif:Port_Battery_Powered value="true" />
+ <vif:BC_1_2_Support value="2">Charging Port</vif:BC_1_2_Support>
+ <vif:Captive_Cable value="false" />
+ <!--;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-->
+ <!--;General PD-->
+ <!--;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-->
+ <vif:PD_Spec_Revision_Major value="3" />
+ <vif:PD_Spec_Revision_Minor value="1" />
+ <vif:PD_Spec_Version_Major value="1" />
+ <vif:PD_Spec_Version_Minor value="3" />
+ <vif:PD_Specification_Revision value="2">Revision 3</vif:PD_Specification_Revision>
+ <vif:SOP_Capable value="true" />
+ <vif:SOP_P_Capable value="true" />
+ <vif:SOP_PP_Capable value="true" />
+ <vif:SOP_P_Debug_Capable value="false" />
+ <vif:SOP_PP_Debug_Capable value="false" />
+ <vif:Manufacturer_Info_Supported_Port value="true" />
+ <vif:Manufacturer_Info_VID_Port value="6353">18D1</vif:Manufacturer_Info_VID_Port>
+ <vif:Manufacturer_Info_PID_Port value="20570">505A</vif:Manufacturer_Info_PID_Port>
+ <vif:Chunking_Implemented_SOP value="true" />
+ <vif:Unchunked_Extended_Messages_Supported value="false" />
+ <vif:Security_Msgs_Supported_SOP value="false" />
+ <vif:Unconstrained_Power value="false" />
+ <vif:Num_Fixed_Batteries value="1" />
+ <vif:Num_Swappable_Battery_Slots value="0" />
+ <vif:ID_Header_Connector_Type_SOP value="2">USB Type-C® Receptacle</vif:ID_Header_Connector_Type_SOP>
+ <!--;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-->
+ <!--;PD Capabilities-->
+ <!--;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-->
+ <vif:USB_Comms_Capable value="true" />
+ <vif:DR_Swap_To_DFP_Supported value="true" />
+ <vif:DR_Swap_To_UFP_Supported value="false" />
+ <vif:VCONN_Swap_To_On_Supported value="true" />
+ <vif:VCONN_Swap_To_Off_Supported value="true" />
+ <vif:Responds_To_Discov_SOP_UFP value="false" />
+ <vif:Responds_To_Discov_SOP_DFP value="true" />
+ <vif:Attempts_Discov_SOP value="true" />
+ <vif:Power_Interruption_Available value="0">No Interruption Possible</vif:Power_Interruption_Available>
+ <vif:Data_Reset_Supported value="false" />
+ <vif:Enter_USB_Supported value="false" />
+ <!--;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-->
+ <!--;USB Type-C®-->
+ <!--;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-->
+ <vif:Type_C_Can_Act_As_Host value="true" />
+ <vif:Type_C_Can_Act_As_Device value="false" />
+ <vif:Type_C_Implements_Try_SRC value="true" />
+ <vif:Type_C_Implements_Try_SNK value="false" />
+ <vif:Type_C_Supports_Audio_Accessory value="false" />
+ <vif:Type_C_Is_VCONN_Powered_Accessory value="false" />
+ <vif:Type_C_Is_Debug_Target_SRC value="true" />
+ <vif:Type_C_Is_Debug_Target_SNK value="true" />
+ <vif:RP_Value value="1">1.5A</vif:RP_Value>
+ <vif:Type_C_Port_On_Hub value="false" />
+ <vif:Type_C_Power_Source value="2">Both</vif:Type_C_Power_Source>
+ <vif:Type_C_Sources_VCONN value="true" />
+ <vif:Type_C_Is_Alt_Mode_Controller value="true" />
+ <vif:Type_C_Is_Alt_Mode_Adapter value="false" />
+ <!--;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-->
+ <!--;Product Power-->
+ <!--;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-->
+ <vif:Product_Total_Source_Power_mW value="15000">15000 mW</vif:Product_Total_Source_Power_mW>
+ <vif:Port_Source_Power_Type value="0">Assured</vif:Port_Source_Power_Type>
+ <!--;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-->
+ <!--;USB Host-->
+ <!--;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-->
+ <vif:Host_Supports_USB_Data value="true" />
+ <vif:Host_Speed value="1">USB 3.2 Gen 1x1</vif:Host_Speed>
+ <vif:Host_Contains_Captive_Retimer value="true" />
+ <vif:Host_Truncates_DP_For_tDHPResponse value="false" />
+ <vif:Host_Is_Embedded value="false" />
+ <vif:Host_Suspend_Supported value="true" />
+ <vif:Is_DFP_On_Hub value="false" />
+ <!--;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-->
+ <!--;Battery Charging 1.2-->
+ <!--;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-->
+ <vif:BC_1_2_Charging_Port_Type value="1">CDP</vif:BC_1_2_Charging_Port_Type>
+ <!--;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-->
+ <!--;PD Source-->
+ <!--;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-->
+ <vif:PD_Power_As_Source value="15000">15000 mW</vif:PD_Power_As_Source>
+ <vif:EPR_Supported_As_Src value="false" />
+ <vif:USB_Suspend_May_Be_Cleared value="false" />
+ <vif:Sends_Pings value="false" />
+ <vif:FR_Swap_Type_C_Current_Capability_As_Initial_Sink value="0">FR_Swap not supported</vif:FR_Swap_Type_C_Current_Capability_As_Initial_Sink>
+ <vif:Master_Port value="false" />
+ <vif:Num_Src_PDOs value="1" />
+ <vif:PD_OC_Protection value="true" />
+ <vif:PD_OCP_Method value="0">Over-Current Response</vif:PD_OCP_Method>
+ <!--Bundle: SrcPdoList-->
+ <vif:SrcPdoList>
+ <vif:SrcPDO>
+ <!--Source PDO 1-->
+ <vif:Src_PDO_Supply_Type value="0">Fixed</vif:Src_PDO_Supply_Type>
+ <vif:Src_PDO_Peak_Current value="0">100% IOC</vif:Src_PDO_Peak_Current>
+ <vif:Src_PDO_Voltage value="100">5000 mV</vif:Src_PDO_Voltage>
+ <vif:Src_PDO_Max_Current value="300">3000 mA</vif:Src_PDO_Max_Current>
+ <vif:Src_PD_OCP_OC_Debounce value="0">0 msec</vif:Src_PD_OCP_OC_Debounce>
+ <vif:Src_PD_OCP_OC_Threshold value="300">3000 mA</vif:Src_PD_OCP_OC_Threshold>
+ </vif:SrcPDO>
+ </vif:SrcPdoList>
+ <!--;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-->
+ <!--;PD Sink-->
+ <!--;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-->
+ <vif:PD_Power_As_Sink value="45000">45000 mW</vif:PD_Power_As_Sink>
+ <vif:EPR_Supported_As_Snk value="false" />
+ <vif:No_USB_Suspend_May_Be_Set value="true" />
+ <vif:GiveBack_May_Be_Set value="false" />
+ <vif:Higher_Capability_Set value="false" />
+ <vif:FR_Swap_Reqd_Type_C_Current_As_Initial_Source value="0">FR_Swap not supported</vif:FR_Swap_Reqd_Type_C_Current_As_Initial_Source>
+ <vif:Num_Snk_PDOs value="3" />
+ <!--Bundle: SnkPdoList-->
+ <vif:SnkPdoList>
+ <vif:SnkPDO>
+ <!--Sink PDO 1-->
+ <vif:Snk_PDO_Supply_Type value="0">Fixed</vif:Snk_PDO_Supply_Type>
+ <vif:Snk_PDO_Voltage value="100">5000 mV</vif:Snk_PDO_Voltage>
+ <vif:Snk_PDO_Op_Current value="300">3000 mA</vif:Snk_PDO_Op_Current>
+ </vif:SnkPDO>
+ <vif:SnkPDO>
+ <!--Sink PDO 2-->
+ <vif:Snk_PDO_Supply_Type value="1">Battery</vif:Snk_PDO_Supply_Type>
+ <vif:Snk_PDO_Op_Power value="60">15000 mW</vif:Snk_PDO_Op_Power>
+ <vif:Snk_PDO_Min_Voltage value="95">4750 mV</vif:Snk_PDO_Min_Voltage>
+ <vif:Snk_PDO_Max_Voltage value="300">15000 mV</vif:Snk_PDO_Max_Voltage>
+ </vif:SnkPDO>
+ <vif:SnkPDO>
+ <!--Sink PDO 3-->
+ <vif:Snk_PDO_Supply_Type value="2">Variable</vif:Snk_PDO_Supply_Type>
+ <vif:Snk_PDO_Min_Voltage value="95">4750 mV</vif:Snk_PDO_Min_Voltage>
+ <vif:Snk_PDO_Max_Voltage value="300">15000 mV</vif:Snk_PDO_Max_Voltage>
+ <vif:Snk_PDO_Op_Current value="300">3000 mA</vif:Snk_PDO_Op_Current>
+ </vif:SnkPDO>
+ </vif:SnkPdoList>
+ <!--;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-->
+ <!--;Dual Role-->
+ <!--;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-->
+ <vif:Accepts_PR_Swap_As_Src value="true" />
+ <vif:Accepts_PR_Swap_As_Snk value="true" />
+ <vif:Requests_PR_Swap_As_Src value="true" />
+ <vif:Requests_PR_Swap_As_Snk value="true" />
+ <vif:FR_Swap_Supported_As_Initial_Sink value="false" />
+ <!--;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-->
+ <!--;SOP Discover ID-->
+ <!--;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-->
+ <vif:XID_SOP value="0" />
+ <vif:Data_Capable_As_USB_Host_SOP value="true" />
+ <vif:Data_Capable_As_USB_Device_SOP value="false" />
+ <vif:Product_Type_UFP_SOP value="0">Undefined</vif:Product_Type_UFP_SOP>
+ <vif:Product_Type_DFP_SOP value="2">PDUSB Host</vif:Product_Type_DFP_SOP>
+ <vif:DFP_VDO_Port_Number value="1" />
+ <vif:Modal_Operation_Supported_SOP value="false" />
+ <vif:USB_VID_SOP value="6353">18D1</vif:USB_VID_SOP>
+ <vif:PID_SOP value="20570">505A</vif:PID_SOP>
+ <vif:bcdDevice_SOP value="0">0000</vif:bcdDevice_SOP>
+ </vif:Component>
+</vif:VIF>
\ No newline at end of file diff --git a/zephyr/projects/nissa/nereid/overlay.dtsi b/zephyr/projects/nissa/nereid/overlay.dtsi new file mode 100644 index 0000000000..a44a3e01bd --- /dev/null +++ b/zephyr/projects/nissa/nereid/overlay.dtsi @@ -0,0 +1,400 @@ +/* Copyright 2021 The ChromiumOS Authors + * Use of this source code is governed by a BSD-style license that can be + * found in the LICENSE file. + */ + +#include <cros/thermistor/thermistor.dtsi> + +/ { + aliases { + gpio-cbi-wp = &gpio_ec_cbi_wp; + gpio-wp = &gpio_ec_wp_odl; + int-wp = &int_wp_l; + /* + * USB-C: interrupt input. + * I2C pins are on i2c_ec_i2c_sub_usb_c1 + */ + gpio-usb-c1-int-odl = &gpio_sb_1; + /* + * USB-A: VBUS enable output + * LTE: power enable output + */ + gpio-en-usb-a1-vbus = &gpio_sb_2; + /* + * HDMI: power enable output, HDMI enable output, + * and HPD input + */ + gpio-en-rails-odl = &gpio_sb_1; + gpio-hdmi-en-odl = &gpio_sb_4; + gpio-hpd-odl = &gpio_sb_3; + /* + * Enable S5 rails for LTE sub-board + */ + gpio-en-sub-s5-rails = &gpio_sb_2; + }; + + + ec-console { + compatible = "ec-console"; + disabled = "events", "lpc", "hostcmd"; + }; + + batteries { + default_battery: smp { + compatible = "smp,l20m3pg0", "battery-smart"; + }; + }; + + hibernate-wake-pins { + compatible = "cros-ec,hibernate-wake-pins"; + wakeup-irqs = < + &int_power_button + &int_lid_open + >; + }; + + gpio-interrupts { + compatible = "cros-ec,gpio-interrupts"; + + int_power_button: power_button { + irq-pin = <&gpio_gsc_ec_pwr_btn_odl>; + flags = <GPIO_INT_EDGE_BOTH>; + handler = "power_button_interrupt"; + }; + int_vol_down: vol_down { + irq-pin = <&gpio_voldn_btn_odl>; + flags = <GPIO_INT_EDGE_BOTH>; + handler = "button_interrupt"; + }; + int_vol_up: vol_up { + irq-pin = <&gpio_volup_btn_odl>; + flags = <GPIO_INT_EDGE_BOTH>; + handler = "button_interrupt"; + }; + int_wp_l: wp_l { + irq-pin = <&gpio_ec_wp_odl>; + flags = <GPIO_INT_EDGE_BOTH>; + handler = "switch_interrupt"; + }; + int_lid_open: lid_open { + irq-pin = <&gpio_lid_open>; + flags = <GPIO_INT_EDGE_BOTH>; + handler = "lid_interrupt"; + }; + int_tablet_mode: tablet_mode { + irq-pin = <&gpio_tablet_mode_l>; + flags = <GPIO_INT_EDGE_BOTH>; + handler = "gmr_tablet_switch_isr"; + }; + int_imu: ec_imu { + irq-pin = <&gpio_imu_int_l>; + flags = <GPIO_INT_EDGE_FALLING>; + handler = "bmi3xx_interrupt"; + }; + int_lid_imu: lid_imu { + irq-pin = <&gpio_acc_int_l>; + flags = <GPIO_INT_EDGE_FALLING>; + handler = "bma4xx_interrupt"; + }; + int_usb_c0: usb_c0 { + irq-pin = <&gpio_usb_c0_int_odl>; + flags = <GPIO_INT_EDGE_FALLING>; + handler = "usb_c0_interrupt"; + }; + int_usb_c1: usb_c1 { + irq-pin = <&gpio_sb_1>; + flags = <GPIO_INT_EDGE_FALLING>; + handler = "usb_c1_interrupt"; + }; + }; + + unused-pins { + compatible = "unused-gpios"; + unused-gpios = <&gpioc 3 0>, + <&gpiod 4 0>, + <&gpiod 7 0>, + <&gpioh 2 0>, + <&gpioj 7 0>, + <&gpiol 4 0>; + }; + + named-gpios { + /* + * EC doesn't take any specific action on CC/SBU disconnect due to + * fault, but this definition is useful for hardware testing. + */ + gpio_usb_c0_prot_fault_odl: usb_c0_prot_fault_odl { + gpios = <&gpiok 6 GPIO_INPUT_PULL_UP>; + }; + + gpio_sb_1: sb_1 { + gpios = <&gpioe 6 0>; + no-auto-init; + }; + gpio_sb_2: sb_2 { + gpios = <&gpiof 0 0>; + no-auto-init; + }; + + gpio_sb_3: sb_3 { + gpios = <&gpioe 7 0>; + no-auto-init; + }; + gpio_sb_4: sb_4 { + gpios = <&gpioe 0 0>; + no-auto-init; + }; + }; + + temp_memory: memory { + compatible = "cros-ec,temp-sensor-thermistor"; + thermistor = <&thermistor_3V3_51K1_47K_4050B>; + adc = <&adc_temp_sensor_1>; + }; + temp_charger: charger { + compatible = "cros-ec,temp-sensor-thermistor"; + thermistor = <&thermistor_3V3_51K1_47K_4050B>; + adc = <&adc_temp_sensor_2>; + }; + temp_ambient: ambient { + compatible = "cros-ec,temp-sensor-thermistor"; + thermistor = <&thermistor_3V3_51K1_47K_4050B>; + adc = <&adc_temp_sensor_3>; + }; + + named-temp-sensors { + compatible = "cros-ec,temp-sensors"; + memory { + temp_fan_off = <35>; + temp_fan_max = <60>; + temp_host_high = <85>; + temp_host_halt = <90>; + temp_host_release_high = <80>; + power-good-pin = <&gpio_ec_soc_dsw_pwrok>; + sensor = <&temp_memory>; + }; + charger { + temp_fan_off = <35>; + temp_fan_max = <60>; + temp_host_high = <85>; + temp_host_halt = <90>; + temp_host_release_high = <80>; + power-good-pin = <&gpio_ec_soc_dsw_pwrok>; + sensor = <&temp_charger>; + }; + ambient { + temp_fan_off = <35>; + temp_fan_max = <60>; + temp_host_high = <85>; + temp_host_halt = <90>; + temp_host_release_high = <80>; + power-good-pin = <&gpio_ec_soc_dsw_pwrok>; + sensor = <&temp_ambient>; + }; + }; + + usba { + compatible = "cros-ec,usba-port-enable-pins"; + /* + * sb_2 is only configured as GPIO when USB-A1 is present, + * but it's still safe to control when disabled. + * + * ILIM_SEL pins are referred to by legacy enum name, + * GPIO_USB*_ILIM_SEL. The one for port A1 is unused on + * sub-boards that don't have USB-A so is safe to control + * regardless of system configuration. + */ + enable-pins = <&gpio_en_usb_a0_vbus &gpio_sb_2>; + status = "okay"; + }; + + usbc { + #address-cells = <1>; + #size-cells = <0>; + + port0@0 { + compatible = "named-usbc-port"; + reg = <0>; + bc12 = <&bc12_port0>; + chg = <&chg_port0>; + usb-mux-chain-0 { + compatible = "cros-ec,usb-mux-chain"; + usb-muxes = <&virtual_mux_0>; + }; + }; + port0-muxes { + virtual_mux_0: virtual-mux-0 { + compatible = "cros-ec,usbc-mux-virtual"; + }; + }; + port1@1 { + compatible = "named-usbc-port"; + reg = <1>; + bc12 = <&bc12_port1>; + chg = <&chg_port1>; + usb-mux-chain-1 { + compatible = "cros-ec,usb-mux-chain"; + usb-muxes = <&virtual_mux_1 &tcpci_mux_1>; + }; + usb_mux_chain_1_no_mux: usb-mux-chain-1-no-mux { + compatible = "cros-ec,usb-mux-chain"; + alternative-chain; + usb-muxes = <&virtual_mux_1>; + }; + }; + port1-muxes { + virtual_mux_1: virtual-mux-1 { + compatible = "cros-ec,usbc-mux-virtual"; + }; + tcpci_mux_1: tcpci-mux-1 { + compatible = "parade,usbc-mux-ps8xxx"; + }; + }; + }; +}; + +&gpio_acc_int_l { + gpios = <&gpioc 0 (GPIO_INPUT | GPIO_VOLTAGE_1P8)>; +}; +&gpio_imu_int_l { + gpios = <&gpioj 0 (GPIO_INPUT | GPIO_VOLTAGE_1P8)>; +}; +&gpio_vccin_aux_vid0 { + gpios = <&gpiod 0 (GPIO_INPUT | GPIO_VOLTAGE_1P8)>; +}; +&gpio_vccin_aux_vid1 { + gpios = <&gpiok 1 (GPIO_INPUT | GPIO_VOLTAGE_1P8)>; +}; + +&gpio_ec_prochot_odl { + gpios = <&gpioi 1 (GPIO_ODR_HIGH | GPIO_VOLTAGE_1P8)>; +}; + +&thermistor_3V3_51K1_47K_4050B { + status = "okay"; +}; + +&adc_ec_vsense_pp3300_s5 { + /* + * Voltage divider on input has 47k upper and 220k lower legs with 3 V + * full-scale reading on the ADC. Apply the largest possible multiplier + * (without overflowing int32) to get the best possible approximation + * of the actual ratio, but derate by a factor of two to ensure + * unexpectedly high values won't overflow. + */ + mul = <(715828 / 2)>; + div = <(589820 / 2)>; +}; + +&adc0 { + pinctrl-0 = <&adc0_ch0_gpi0_default + &adc0_ch2_gpi2_default + &adc0_ch3_gpi3_default + &adc0_ch13_gpl0_default + &adc0_ch14_gpl1_default>; + pinctrl-names = "default"; +}; + +&pinctrl { + i2c4_clk_gpe0_sleep: i2c4_clk_gpe0_sleep { + pinmuxs = <&pinctrle 0 IT8XXX2_ALT_DEFAULT>; + }; + i2c4_data_gpe7_sleep: i2c4_data_gpe7_sleep { + pinmuxs = <&pinctrle 7 IT8XXX2_ALT_DEFAULT>; + }; + i2c2_clk_gpf6_default: i2c2_clk_gpf6_default { + gpio-voltage = "1v8"; + }; + i2c2_data_gpf7_default: i2c2_data_gpf7_default { + gpio-voltage = "1v8"; + }; +}; + +&i2c0 { + label = "I2C_EEPROM"; + clock-frequency = <I2C_BITRATE_FAST>; + + cbi_eeprom: eeprom@50 { + compatible = "atmel,at24"; + reg = <0x50>; + size = <2048>; + pagesize = <16>; + address-width = <8>; + timeout = <5>; + }; + pinctrl-0 = <&i2c0_clk_gpb3_default + &i2c0_data_gpb4_default>; + pinctrl-names = "default"; +}; + +&i2c1 { + label = "I2C_BATTERY"; + clock-frequency = <50000>; + pinctrl-0 = <&i2c1_clk_gpc1_default + &i2c1_data_gpc2_default>; + pinctrl-names = "default"; +}; + +&i2c2 { + label = "I2C_SENSOR"; + clock-frequency = <I2C_BITRATE_FAST>; + pinctrl-0 = <&i2c2_clk_gpf6_default + &i2c2_data_gpf7_default>; + pinctrl-names = "default"; +}; + +&i2c4 { + label = "I2C_SUB_C1_TCPC"; + clock-frequency = <I2C_BITRATE_FAST_PLUS>; + pinctrl-0 = <&i2c4_clk_gpe0_default + &i2c4_data_gpe7_default>; + pinctrl-1 = <&i2c4_clk_gpe0_sleep + &i2c4_data_gpe7_sleep>; + pinctrl-names = "default", "sleep"; + + bc12_port1: pi3usb9201@5f { + compatible = "pericom,pi3usb9201"; + status = "okay"; + reg = <0x5f>; + }; + + chg_port1: sm5803@32 { + compatible = "siliconmitus,sm5803"; + status = "okay"; + reg = <0x32>; + }; +}; + +&i2c_ec_i2c_sub_usb_c1 { + /* + * Dynamic speed setting is used for AP-controlled firmware update + * of PS8745 TCPC/redriver: the AP lowers speed to 400 kHz in order + * to use more efficient window programming, then sets it back when + * done. + */ + dynamic-speed; +}; + +&i2c5 { + label = "I2C_USB_C0_TCPC"; + clock-frequency = <I2C_BITRATE_FAST_PLUS>; + pinctrl-0 = <&i2c5_clk_gpa4_default + &i2c5_data_gpa5_default>; + pinctrl-names = "default"; + + bc12_port0: pi3usb9201@5f { + compatible = "pericom,pi3usb9201"; + status = "okay"; + reg = <0x5f>; + }; + + chg_port0: sm5803@32 { + compatible = "siliconmitus,sm5803"; + status = "okay"; + reg = <0x32>; + }; +}; + +&usbpd0 { + status = "okay"; +}; diff --git a/zephyr/projects/nissa/nereid/power_signals.dtsi b/zephyr/projects/nissa/nereid/power_signals.dtsi new file mode 100644 index 0000000000..8affae03b1 --- /dev/null +++ b/zephyr/projects/nissa/nereid/power_signals.dtsi @@ -0,0 +1,223 @@ +/* Copyright 2022 The ChromiumOS Authors + * Use of this source code is governed by a BSD-style license that can be + * found in the LICENSE file. + */ + +/ { + chosen { + intel-ap-pwrseq,espi = &espi0; + }; + + common-pwrseq { + compatible = "intel,ap-pwrseq"; + + sys-pwrok-delay = <10>; + all-sys-pwrgd-timeout = <20>; + }; + + pwr-en-pp5000-s5 { + compatible = "intel,ap-pwrseq-gpio"; + dbg-label = "PP5000_S5 enable output to regulator"; + enum-name = "PWR_EN_PP5000_A"; + gpios = <&gpiok 5 0>; + output; + }; + pwr-en-pp3300-s5 { + compatible = "intel,ap-pwrseq-gpio"; + dbg-label = "PP3300_S5 enable output to LS"; + enum-name = "PWR_EN_PP3300_A"; + gpios = <&gpioc 5 0>; + output; + }; + pwr-pg-ec-rsmrst-odl { + compatible = "intel,ap-pwrseq-gpio"; + dbg-label = "RSMRST power good from regulator"; + enum-name = "PWR_RSMRST"; + gpios = <&gpioe 1 0>; + interrupt-flags = <GPIO_INT_EDGE_BOTH>; + }; + pwr-ec-pch-rsmrst-odl { + compatible = "intel,ap-pwrseq-gpio"; + dbg-label = "RSMRST output to PCH"; + enum-name = "PWR_EC_PCH_RSMRST"; + gpios = <&gpioh 0 0>; + output; + }; + pwr-slp-s0-l { + compatible = "intel,ap-pwrseq-gpio"; + dbg-label = "SLP_S0_L input from PCH"; + enum-name = "PWR_SLP_S0"; + gpios = <&gpioe 4 GPIO_ACTIVE_LOW>; + interrupt-flags = <GPIO_INT_EDGE_BOTH>; + }; + pwr-slp-s3-l { + compatible = "intel,ap-pwrseq-gpio"; + dbg-label = "SLP_S3_L input from PCH"; + enum-name = "PWR_SLP_S3"; + gpios = <&gpioh 3 GPIO_ACTIVE_LOW>; + interrupt-flags = <GPIO_INT_EDGE_BOTH>; + }; + pwr-slp-sus-l { + compatible = "intel,ap-pwrseq-gpio"; + dbg-label = "SLP_SUS_L input from PCH"; + enum-name = "PWR_SLP_SUS"; + gpios = <&gpiog 2 GPIO_ACTIVE_LOW>; + interrupt-flags = <GPIO_INT_EDGE_BOTH>; + }; + pwr-ec-soc-dsw-pwrok { + compatible = "intel,ap-pwrseq-gpio"; + dbg-label = "DSW_PWROK output to PCH"; + enum-name = "PWR_EC_SOC_DSW_PWROK"; + gpios = <&gpiol 7 0>; + output; + }; + pwr-vccst-pwrgd-od { + compatible = "intel,ap-pwrseq-gpio"; + dbg-label = "VCCST_PWRGD output to PCH"; + enum-name = "PWR_VCCST_PWRGD"; + gpios = <&gpioe 5 (GPIO_OPEN_DRAIN | GPIO_VOLTAGE_1P8)>; + output; + }; + pwr-imvp9-vrrdy-od { + compatible = "intel,ap-pwrseq-gpio"; + dbg-label = "VRRDY input from IMVP9"; + enum-name = "PWR_IMVP9_VRRDY"; + gpios = <&gpioj 4 0>; + }; + pwr-pch-pwrok { + compatible = "intel,ap-pwrseq-gpio"; + dbg-label = "PCH_PWROK output to PCH"; + enum-name = "PWR_PCH_PWROK"; + gpios = <&gpiod 6 GPIO_OPEN_DRAIN>; + output; + }; + pwr-ec-pch-sys-pwrok { + compatible = "intel,ap-pwrseq-gpio"; + dbg-label = "SYS_PWROK output to PCH"; + enum-name = "PWR_EC_PCH_SYS_PWROK"; + gpios = <&gpiof 2 0>; + output; + }; + pwr-sys-rst-l { + compatible = "intel,ap-pwrseq-gpio"; + dbg-label = "SYS_RESET# output to PCH"; + enum-name = "PWR_SYS_RST"; + gpios = <&gpiod 1 (GPIO_ACTIVE_LOW|GPIO_OPEN_DRAIN)>; + output; + }; + pwr-slp-s4 { + compatible = "intel,ap-pwrseq-vw"; + dbg-label = "SLP_S4 virtual wire input from PCH"; + enum-name = "PWR_SLP_S4"; + virtual-wire = "ESPI_VWIRE_SIGNAL_SLP_S4"; + vw-invert; + }; + pwr-slp-s5 { + compatible = "intel,ap-pwrseq-vw"; + dbg-label = "SLP_S5 virtual wire input from PCH"; + enum-name = "PWR_SLP_S5"; + virtual-wire = "ESPI_VWIRE_SIGNAL_SLP_S5"; + vw-invert; + }; + pwr-all-sys-pwrgd { + /* + * This is a board level signal, since this + * signal needs some special processing. + */ + compatible = "intel,ap-pwrseq-external"; + dbg-label = "Combined all power good"; + enum-name = "PWR_ALL_SYS_PWRGD"; + }; + pwr-adc-pp3300 { + compatible = "intel,ap-pwrseq-adc"; + dbg-label = "PP3300_PROC"; + enum-name = "PWR_DSW_PWROK"; + trigger-high = <&vcmp0>; + trigger-low = <&vcmp1>; + }; + pwr-adc-pp1p05 { + compatible = "intel,ap-pwrseq-adc"; + dbg-label = "PP1P05_PROC"; + enum-name = "PWR_PG_PP1P05"; + trigger-high = <&vcmp2>; + trigger-low = <&vcmp3>; + }; + +}; + +/* + * Because the power signals directly reference the GPIOs, + * the correspinding named-gpios need to have no-auto-init set. + */ +&gpio_ec_soc_dsw_pwrok { + no-auto-init; +}; +&gpio_ec_soc_pch_pwrok_od { + no-auto-init; +}; +&gpio_ec_soc_rsmrst_l { + no-auto-init; +}; +&gpio_ec_soc_sys_pwrok { + no-auto-init; +}; +&gpio_ec_soc_vccst_pwrgd_od { + no-auto-init; +}; +&gpio_en_pp3300_s5 { + no-auto-init; +}; +&gpio_en_pp5000_s5 { + no-auto-init; +}; +&gpio_imvp91_vrrdy_od { + no-auto-init; +}; +&gpio_rsmrst_pwrgd_l { + no-auto-init; +}; +&gpio_slp_s0_l { + no-auto-init; +}; +&gpio_slp_s3_l { + no-auto-init; +}; +&gpio_slp_sus_l { + no-auto-init; +}; +&gpio_sys_rst_odl { + no-auto-init; +}; +&vcmp0 { + status = "okay"; + scan-period = <IT8XXX2_VCMP_SCAN_PERIOD_600US>; + comparison = <IT8XXX2_VCMP_GREATER>; + /* + * This is 90% of nominal voltage considering voltage + * divider on ADC input. + */ + threshold-mv = <2448>; + io-channels = <&adc0 0>; +}; +&vcmp1 { + status = "okay"; + scan-period = <IT8XXX2_VCMP_SCAN_PERIOD_600US>; + comparison = <IT8XXX2_VCMP_LESS_OR_EQUAL>; + threshold-mv = <2448>; + io-channels = <&adc0 0>; +}; +&vcmp2 { + status = "okay"; + scan-period = <IT8XXX2_VCMP_SCAN_PERIOD_600US>; + comparison = <IT8XXX2_VCMP_GREATER>; + /* Setting at 90% of nominal voltage */ + threshold-mv = <945>; + io-channels = <&adc0 14>; +}; +&vcmp3 { + status = "okay"; + scan-period = <IT8XXX2_VCMP_SCAN_PERIOD_600US>; + comparison = <IT8XXX2_VCMP_LESS_OR_EQUAL>; + threshold-mv = <945>; + io-channels = <&adc0 14>; +}; diff --git a/zephyr/projects/nissa/nereid/project.conf b/zephyr/projects/nissa/nereid/project.conf new file mode 100644 index 0000000000..75a5faba5d --- /dev/null +++ b/zephyr/projects/nissa/nereid/project.conf @@ -0,0 +1,17 @@ +# Copyright 2021 The ChromiumOS Authors +# Use of this source code is governed by a BSD-style license that can be +# found in the LICENSE file. + +CONFIG_BOARD_NEREID=y + +# Ensure recovery key combination (esc+refresh+power) is reliable: b/236580049 +CONFIG_PLATFORM_EC_KEYBOARD_PWRBTN_ASSERTS_KSI2=y + +# Sensor drivers +CONFIG_PLATFORM_EC_ACCELGYRO_BMI_COMM_I2C=y +CONFIG_PLATFORM_EC_ACCELGYRO_BMI3XX=y +CONFIG_PLATFORM_EC_ACCEL_BMA4XX=y +CONFIG_PLATFORM_EC_MAX_SENSOR_FREQ_MILLIHZ=100000 + +# No fan supported, and tach is default-enabled +CONFIG_TACH_IT8XXX2=n diff --git a/zephyr/projects/nissa/nereid/project.overlay b/zephyr/projects/nissa/nereid/project.overlay new file mode 100644 index 0000000000..0aceac1c47 --- /dev/null +++ b/zephyr/projects/nissa/nereid/project.overlay @@ -0,0 +1,13 @@ +/* Copyright 2022 The ChromiumOS Authors + * Use of this source code is governed by a BSD-style license that can be + * found in the LICENSE file. + */ + +#include "../cbi.dtsi" + +#include "generated.dtsi" +#include "keyboard.dtsi" +#include "motionsense.dtsi" +#include "overlay.dtsi" +#include "power_signals.dtsi" +#include "pwm_leds.dtsi" diff --git a/zephyr/projects/nissa/nereid/pwm_leds.dtsi b/zephyr/projects/nissa/nereid/pwm_leds.dtsi new file mode 100644 index 0000000000..aa4a76b271 --- /dev/null +++ b/zephyr/projects/nissa/nereid/pwm_leds.dtsi @@ -0,0 +1,60 @@ +/* Copyright 2022 The ChromiumOS Authors + * Use of this source code is governed by a BSD-style license that can be + * found in the LICENSE file. + */ + +/ { + pwmleds { + compatible = "pwm-leds"; + pwm_led0: pwm_led_0 { + pwms = <&pwm1 1 PWM_HZ(1296) PWM_POLARITY_INVERTED>, + <&pwm2 2 PWM_HZ(1296) PWM_POLARITY_INVERTED>, + <&pwm3 3 PWM_HZ(1296) PWM_POLARITY_INVERTED>; + }; + }; + + cros-pwmleds { + compatible = "cros-ec,pwm-leds"; + + leds = <&pwm_led0>; + + /*<red green blue>*/ + color-map-red = <100 0 0>; + color-map-green = < 0 100 0>; + color-map-blue = < 0 0 100>; + color-map-yellow = < 0 50 50>; + color-map-white = <100 100 100>; + color-map-amber = <100 15 0>; + + brightness-range = <100 100 100 0 0 0>; + + #address-cells = <1>; + #size-cells = <0>; + + pwm_led_0@0 { + reg = <0>; + ec-led-name = "EC_LED_ID_BATTERY_LED"; + }; + }; +}; + +&pwm1 { + status = "okay"; + prescaler-cx = <PWM_PRESCALER_C4>; + pinctrl-0 = <&pwm1_gpa1_default>; + pinctrl-names = "default"; +}; + +&pwm2 { + status = "okay"; + prescaler-cx = <PWM_PRESCALER_C4>; + pinctrl-0 = <&pwm2_gpa2_default>; + pinctrl-names = "default"; +}; + +&pwm3 { + status = "okay"; + prescaler-cx = <PWM_PRESCALER_C4>; + pinctrl-0 = <&pwm3_gpa3_default>; + pinctrl-names = "default"; +}; diff --git a/zephyr/projects/nissa/nereid/src/charger.c b/zephyr/projects/nissa/nereid/src/charger.c new file mode 100644 index 0000000000..181e9a61fd --- /dev/null +++ b/zephyr/projects/nissa/nereid/src/charger.c @@ -0,0 +1,56 @@ +/* Copyright 2022 The ChromiumOS Authors + * Use of this source code is governed by a BSD-style license that can be + * found in the LICENSE file. + */ + +#include <zephyr/logging/log.h> + +#include "battery.h" +#include "charger.h" +#include "console.h" +#include "driver/charger/sm5803.h" +#include "extpower.h" +#include "usb_pd.h" +#include "nissa_common.h" + +LOG_MODULE_DECLARE(nissa, CONFIG_NISSA_LOG_LEVEL); + +int extpower_is_present(void) +{ + int port; + int rv; + bool acok; + + for (port = 0; port < board_get_usb_pd_port_count(); port++) { + rv = sm5803_is_acok(port, &acok); + if ((rv == EC_SUCCESS) && acok) + return 1; + } + + return 0; +} + +/* + * Nereid does not have a GPIO indicating whether extpower is present, + * so detect using the charger(s). + */ +__override void board_check_extpower(void) +{ + static int last_extpower_present; + int extpower_present = extpower_is_present(); + + if (last_extpower_present ^ extpower_present) + extpower_handle_update(extpower_present); + + last_extpower_present = extpower_present; +} + +__override void board_hibernate(void) +{ + /* Shut down the chargers */ + if (board_get_usb_pd_port_count() == 2) + sm5803_hibernate(CHARGER_SECONDARY); + sm5803_hibernate(CHARGER_PRIMARY); + LOG_INF("Charger(s) hibernated"); + cflush(); +} diff --git a/zephyr/projects/nissa/nereid/src/hdmi.c b/zephyr/projects/nissa/nereid/src/hdmi.c new file mode 100644 index 0000000000..7e5708c6eb --- /dev/null +++ b/zephyr/projects/nissa/nereid/src/hdmi.c @@ -0,0 +1,28 @@ +/* Copyright 2022 The ChromiumOS Authors + * Use of this source code is governed by a BSD-style license that can be + * found in the LICENSE file. + */ + +#include <cros_board_info.h> +#include "nissa_hdmi.h" + +__override void nissa_configure_hdmi_power_gpios(void) +{ + /* + * Nereid versions before 2 need hdmi-en-odl to be + * pulled down to enable VCC on the HDMI port, but later + * versions (and other boards) disconnect this so + * the port's VCC directly follows en-rails-odl. Only + * configure the GPIO if needed, to save power. + */ + uint32_t board_version = 0; + + /* CBI errors ignored, will configure the pin */ + cbi_get_board_version(&board_version); + if (board_version < 2) { + nissa_configure_hdmi_vcc(); + } + + /* Still always need core rails controlled */ + nissa_configure_hdmi_rails(); +} diff --git a/zephyr/projects/nissa/nereid/src/keyboard.c b/zephyr/projects/nissa/nereid/src/keyboard.c new file mode 100644 index 0000000000..b69bb4da33 --- /dev/null +++ b/zephyr/projects/nissa/nereid/src/keyboard.c @@ -0,0 +1,29 @@ +/* Copyright 2022 The ChromiumOS Authors + * Use of this source code is governed by a BSD-style license that can be + * found in the LICENSE file. + */ + +#include "ec_commands.h" + +static const struct ec_response_keybd_config nereid_kb_legacy = { + .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) +{ + return &nereid_kb_legacy; +} diff --git a/zephyr/projects/nissa/nereid/src/usbc.c b/zephyr/projects/nissa/nereid/src/usbc.c new file mode 100644 index 0000000000..48f7cfd9cb --- /dev/null +++ b/zephyr/projects/nissa/nereid/src/usbc.c @@ -0,0 +1,393 @@ +/* Copyright 2022 The ChromiumOS Authors + * Use of this source code is governed by a BSD-style license that can be + * found in the LICENSE file. + */ + +#include <zephyr/logging/log.h> +#include <ap_power/ap_power.h> + +#include "charge_state_v2.h" +#include "chipset.h" +#include "hooks.h" +#include "usb_mux.h" +#include "system.h" +#include "driver/charger/sm5803.h" +#include "driver/tcpm/it83xx_pd.h" +#include "driver/tcpm/ps8xxx_public.h" +#include "driver/tcpm/tcpci.h" + +#include "nissa_common.h" + +LOG_MODULE_DECLARE(nissa, CONFIG_NISSA_LOG_LEVEL); + +struct tcpc_config_t tcpc_config[CONFIG_USB_PD_PORT_MAX_COUNT] = { + { + .bus_type = EC_BUS_TYPE_EMBEDDED, + /* TCPC is embedded within EC so no i2c config needed */ + .drv = &it8xxx2_tcpm_drv, + /* Alert is active-low, push-pull */ + .flags = 0, + }, + { + /* + * Sub-board: optional PS8745 TCPC+redriver. Behaves the same + * as PS8815. + */ + .bus_type = EC_BUS_TYPE_I2C, + .i2c_info = { + .port = I2C_PORT_USB_C1_TCPC, + .addr_flags = PS8XXX_I2C_ADDR1_FLAGS, + }, + .drv = &ps8xxx_tcpm_drv, + /* PS8745 implements TCPCI 2.0 */ + .flags = TCPC_FLAGS_TCPCI_REV2_0, + }, +}; + +/* Vconn control for integrated ITE TCPC */ +void board_pd_vconn_ctrl(int port, enum usbpd_cc_pin cc_pin, int enabled) +{ + /* Vconn control is only for port 0 */ + if (port) + return; + + if (cc_pin == USBPD_CC_PIN_1) + gpio_pin_set_dt( + GPIO_DT_FROM_NODELABEL(gpio_en_usb_c0_cc1_vconn), + !!enabled); + else + gpio_pin_set_dt( + GPIO_DT_FROM_NODELABEL(gpio_en_usb_c0_cc2_vconn), + !!enabled); +} + +__override bool pd_check_vbus_level(int port, enum vbus_level level) +{ + return sm5803_check_vbus_level(port, level); +} + +/* + * Putting chargers into LPM when in suspend reduces power draw by about 8mW + * per charger, but also seems critical to correct operation in source mode: + * if chargers are not in LPM when a sink is first connected, VBUS sourcing + * works even if the partner is later removed (causing LPM entry) and + * reconnected (causing LPM exit). If in LPM initially, sourcing VBUS + * consistently causes the charger to report (apparently spurious) overcurrent + * failures. + * + * In short, this is important to making things work correctly but we don't + * understand why. + */ +static void board_chargers_suspend(struct ap_power_ev_callback *const cb, + const struct ap_power_ev_data data) +{ + void (*fn)(int chgnum); + + switch (data.event) { + case AP_POWER_SUSPEND: + fn = sm5803_enable_low_power_mode; + break; + case AP_POWER_RESUME: + fn = sm5803_disable_low_power_mode; + break; + default: + LOG_WRN("%s: power event %d is not recognized", __func__, + data.event); + return; + } + + fn(CHARGER_PRIMARY); + if (board_get_charger_chip_count() > 1) + fn(CHARGER_SECONDARY); +} + +static int board_chargers_suspend_init(const struct device *unused) +{ + static struct ap_power_ev_callback cb = { + .handler = board_chargers_suspend, + .events = AP_POWER_SUSPEND | AP_POWER_RESUME, + }; + ap_power_ev_add_callback(&cb); + return 0; +} +SYS_INIT(board_chargers_suspend_init, APPLICATION, 0); + +int board_set_active_charge_port(int port) +{ + int is_real_port = (port >= 0 && port < board_get_usb_pd_port_count()); + int i; + int old_port; + int rv; + + if (!is_real_port && port != CHARGE_PORT_NONE) + return EC_ERROR_INVAL; + + old_port = charge_manager_get_active_charge_port(); + LOG_INF("Charge update: p%d -> p%d", old_port, port); + + /* Check if port is sourcing VBUS. */ + if (port != CHARGE_PORT_NONE && charger_is_sourcing_otg_power(port)) { + LOG_WRN("Skip enable p%d: already sourcing", port); + return EC_ERROR_INVAL; + } + + /* Disable sinking on all ports except the desired one */ + for (i = 0; i < board_get_usb_pd_port_count(); i++) { + if (i == port) + continue; + + if (sm5803_vbus_sink_enable(i, 0)) + /* + * Do not early-return because this can fail during + * power-on which would put us into a loop. + */ + LOG_WRN("p%d: sink path disable failed.", i); + } + + /* Don't enable anything (stop here) if no ports were requested */ + if ((port == CHARGE_PORT_NONE) || (old_port == port)) + return EC_SUCCESS; + + /* + * Stop the charger IC from switching while changing ports. Otherwise, + * we can overcurrent the adapter we're switching to. (crbug.com/926056) + */ + if (old_port != CHARGE_PORT_NONE) + charger_discharge_on_ac(1); + + /* Enable requested charge port. */ + rv = sm5803_vbus_sink_enable(port, 1); + if (rv) + LOG_WRN("p%d: sink path enable failed: code %d", port, rv); + + /* Allow the charger IC to begin/continue switching. */ + charger_discharge_on_ac(0); + + return rv; +} + +uint16_t tcpc_get_alert_status(void) +{ + /* + * TCPC 0 is embedded in the EC and processes interrupts in the chip + * code (it83xx/intc.c). This function only needs to poll port C1 if + * present. + */ + uint16_t status = 0; + int regval; + + /* Is the C1 port present and its IRQ line asserted? */ + if (board_get_usb_pd_port_count() == 2 && + !gpio_pin_get_dt(GPIO_DT_FROM_ALIAS(gpio_usb_c1_int_odl))) { + /* + * C1 IRQ is shared between BC1.2 and TCPC; poll TCPC to see if + * it asserted the IRQ. + */ + if (!tcpc_read16(1, TCPC_REG_ALERT, ®val)) { + if (regval) + status = PD_STATUS_TCPC_ALERT_1; + } + } + + return status; +} + +void pd_power_supply_reset(int port) +{ + int prev_en; + + if (port < 0 || port >= board_get_usb_pd_port_count()) + return; + + prev_en = charger_is_sourcing_otg_power(port); + + /* Disable Vbus */ + charger_enable_otg_power(port, 0); + + /* Discharge Vbus if previously enabled */ + if (prev_en) + sm5803_set_vbus_disch(port, 1); + + /* Notify host of power info change. */ + pd_send_host_event(PD_EVENT_POWER_CHANGE); +} + +int pd_set_power_supply_ready(int port) +{ + enum ec_error_list rv; + + if (port < 0 || port > board_get_usb_pd_port_count()) { + LOG_WRN("Port C%d does not exist, cannot enable VBUS", port); + return EC_ERROR_INVAL; + } + + /* Disable sinking */ + rv = sm5803_vbus_sink_enable(port, 0); + if (rv) { + LOG_WRN("C%d failed to disable sinking: %d", port, rv); + return rv; + } + + /* Disable Vbus discharge */ + rv = sm5803_set_vbus_disch(port, 0); + if (rv) { + LOG_WRN("C%d failed to clear VBUS discharge: %d", port, rv); + return rv; + } + + /* Provide Vbus */ + rv = charger_enable_otg_power(port, 1); + if (rv) { + LOG_WRN("C%d failed to enable VBUS sourcing: %d", port, rv); + return rv; + } + + /* Notify host of power info change. */ + pd_send_host_event(PD_EVENT_POWER_CHANGE); + + return EC_SUCCESS; +} + +__override void typec_set_source_current_limit(int port, enum tcpc_rp_value rp) +{ + int rv; + const int current = rp == TYPEC_RP_3A0 ? 3000 : 1500; + + rv = charger_set_otg_current_voltage(port, current, 5000); + if (rv != EC_SUCCESS) { + LOG_WRN("Failed to set source ilimit on port %d to %d: %d", + port, current, rv); + } +} + +void board_reset_pd_mcu(void) +{ + /* + * Do nothing. The integrated TCPC for C0 lacks a dedicated reset + * command, and C1 (if present) doesn't have a reset pin connected + * to the EC. + */ +} + +#define INT_RECHECK_US 5000 + +/* C0 interrupt line shared by BC 1.2 and charger */ + +static void check_c0_line(void); +DECLARE_DEFERRED(check_c0_line); + +static void notify_c0_chips(void) +{ + usb_charger_task_set_event(0, USB_CHG_EVENT_BC12); + sm5803_interrupt(0); +} + +static void check_c0_line(void) +{ + /* + * If line is still being held low, see if there's more to process from + * one of the chips + */ + if (!gpio_pin_get_dt(GPIO_DT_FROM_NODELABEL(gpio_usb_c0_int_odl))) { + notify_c0_chips(); + hook_call_deferred(&check_c0_line_data, INT_RECHECK_US); + } +} + +void usb_c0_interrupt(enum gpio_signal s) +{ + /* Cancel any previous calls to check the interrupt line */ + hook_call_deferred(&check_c0_line_data, -1); + + /* Notify all chips using this line that an interrupt came in */ + notify_c0_chips(); + + /* Check the line again in 5ms */ + hook_call_deferred(&check_c0_line_data, INT_RECHECK_US); +} + +/* C1 interrupt line shared by BC 1.2, TCPC, and charger */ +static void check_c1_line(void); +DECLARE_DEFERRED(check_c1_line); + +static void notify_c1_chips(void) +{ + schedule_deferred_pd_interrupt(1); + usb_charger_task_set_event(1, USB_CHG_EVENT_BC12); + /* Charger is handled in board_process_pd_alert */ +} + +static void check_c1_line(void) +{ + /* + * If line is still being held low, see if there's more to process from + * one of the chips. + */ + if (!gpio_pin_get_dt(GPIO_DT_FROM_ALIAS(gpio_usb_c1_int_odl))) { + notify_c1_chips(); + hook_call_deferred(&check_c1_line_data, INT_RECHECK_US); + } +} + +void usb_c1_interrupt(enum gpio_signal s) +{ + /* Cancel any previous calls to check the interrupt line */ + hook_call_deferred(&check_c1_line_data, -1); + + /* Notify all chips using this line that an interrupt came in */ + notify_c1_chips(); + + /* Check the line again in 5ms */ + hook_call_deferred(&check_c1_line_data, INT_RECHECK_US); +} + +/* + * Check state of IRQ lines at startup, ensuring an IRQ that happened before + * the EC started up won't get lost (leaving the IRQ line asserted and blocking + * any further interrupts on the port). + * + * Although the PD task will check for pending TCPC interrupts on startup, + * the charger sharing the IRQ will not be polled automatically. + */ +void board_handle_initial_typec_irq(void) +{ + check_c0_line(); + if (board_get_usb_pd_port_count() == 2) + check_c1_line(); +} +/* + * This must run after sub-board detection (which happens in EC main()), + * but isn't depended on by anything else either. + */ +DECLARE_HOOK(HOOK_INIT, board_handle_initial_typec_irq, HOOK_PRIO_LAST); + +/* + * Handle charger interrupts in the PD task. Not doing so can lead to a priority + * inversion where we fail to respond to TCPC alerts quickly enough because we + * don't get another edge on a shared IRQ until the charger interrupt is cleared + * (or the IRQ is polled again), which happens in the low-priority charger task: + * the high-priority type-C handler is thus blocked on the lower-priority + * charger. + * + * To avoid that, we run charger interrupts at the same priority. + */ +void board_process_pd_alert(int port) +{ + /* + * Port 0 doesn't use an external TCPC, so its interrupts don't need + * this special handling. + */ + if (port == 1 && + !gpio_pin_get_dt(GPIO_DT_FROM_ALIAS(gpio_usb_c1_int_odl))) { + sm5803_handle_interrupt(port); + } +} + +int pd_snk_is_vbus_provided(int port) +{ + int chg_det = 0; + + sm5803_get_chg_det(port, &chg_det); + + return chg_det; +} diff --git a/zephyr/projects/nissa/nissa.csv b/zephyr/projects/nissa/nissa.csv new file mode 100644 index 0000000000..45b73ea229 --- /dev/null +++ b/zephyr/projects/nissa/nissa.csv @@ -0,0 +1,122 @@ +Signal Name,Subsystem,Description,DIR,Int,I/O Type,Internal PU,I/O Voltage,ICs attached,NPCX993 (Nivviks),NPCX993 (Nirwen),IT81302 (Nereid),Type,Enum,SW Notes,HW Notes
+ESPI_SOC_CLK,ESPI,ESPI clock,IN,no,--,N,1.80 V,,M1,M1,L1,OTHER,,,
+ESPI_SOC_CS_EC_L,ESPI,ESPI chip select,IN,F,--,N,1.80 V,,L2,L2,J2,OTHER,,,
+ESPI_SOC_D0_EC,ESPI,ESPI DATA0,I/O,,TTL,N,1.80 V,,H1,H1,L2,OTHER,,,
+ESPI_SOC_D1_EC,ESPI,ESPI DATA1,I/O,,TTL,N,1.80 V,,J1,J1,K1,OTHER,,,
+ESPI_SOC_D2_EC,ESPI,ESPI DATA2,I/O,,TTL,N,1.80 V,,K1,K1,K2,OTHER,,,
+ESPI_SOC_D3_EC,ESPI,ESPI DATA3,I/O,,TTL,N,1.80 V,,L1,L1,J1,OTHER,,,
+ESPI_SOC_RST_EC_L,ESPI,ESPI reset,IN,F,,N,1.80 V,,K3,K3,R5,OTHER,,,
+ESPI_EC_ALERT_SOC_L,ESPI,ESPI Alert,OUT,,TTL,N,1.80 V,,L3,L3,H1,OTHER,,,
+GSC_EC_PWR_BTN_ODL,GSC,Power Button input from GSC,IN,both,--,Y,3.30 V,,E7,E7,B13,INPUT_PU,GPIO_POWER_BUTTON_L,GPIO00,
+EC_RST_ODL,GSC,Reset signal for EC from GSC,IN,no,--,N,3.30 V,GSC,K6,K6,M2,OTHER,,,
+EC_GSC_PACKET_MODE,GSC,Wakes/interrupts GSC and (maybe) vice-versa,I/O,both,--,N,3.30 V,,J6,J6,F9,OUTPUT,GPIO_PACKET_MODE_EN,,
+EC_I2C_EEPROM_SCL,I2C,"I2C clock for CBI, reading INAs, programming EC (ITE only)",I/O,,OD,N,3.30 V,"EEPROMs, INAs",C12,C12,A5,I2C_CLOCK,I2C_PORT_EEPROM,,
+EC_I2C_EEPROM_SDA,I2C,"I2C data for CBI, reading INAs, programming EC (ITE only)",I/O,,OD,N,3.30 V,"EEPROMs, INAs",B12,B12,B3,I2C_DATA,,,
+EC_I2C_BATT_SDA,I2C,I2C data for battery pack,I/O,,OD,N,3.30 V,Battery Pack,K10,K10,A3,I2C_DATA,,,
+EC_I2C_BATT_SCL,I2C,I2C clock for battery pack,I/O,,OD,N,3.30 V,Battery Pack,J10,J10,A4,I2C_CLOCK,I2C_PORT_BATTERY,,
+EC_I2C_SENSOR_SCL,I2C,I2C clock for sensors,I/O,,OD,N,3.30 V,"IMU, accel, lid accel, kb bl",K8,K8,C2,I2C_CLOCK,I2C_PORT_SENSOR,,
+EC_I2C_SENSOR_SDA,I2C,I2C data for sensors,I/O,,OD,N,3.30 V,"IMU, accel, lid accel, kb bl",K7,K7,D2,I2C_DATA,,,
+EC_I2C_USB_C0_SDA,I2C,I2C clock for USB-C C0 and USB-A A0 port ICs,I/O,,OD,N,3.30 V,"TCPC, BC1.2, Charger",F9,F9,K7,I2C_DATA,,,
+EC_I2C_USB_C0_SCL,I2C,I2C data for USB-C C0 and USB-A A0 port ICs,I/O,,OD,N,3.30 V,"TCPC, BC1.2, Charger",F8,F8,L7,I2C_CLOCK,I2C_PORT_USB_C0_TCPC,,
+EC_I2C_SUB_USB_C1_SDA,I2C,I2C clock for USB-C C1 and USB-A A1 port ICs (HDMI: HDMI_EN_SUB_ODL - enable HDMI retimer/output/active low),I/O,,OD,N,3.30 V,"TCPC, BC1.2, Charger",E9,E9,R4,I2C_DATA,,,
+EC_I2C_SUB_USB_C1_SCL,I2C,"I2C data for USB-C C1 and USB-A A1 port ICs (HDMI_HPD_SUB_ODL, hot-plug detection/input (interrupt)/active low)",I/O,,OD,N,3.30 V,"TCPC, BC1.2, Charger",E8,E8,P3,I2C_CLOCK,I2C_PORT_USB_C1_TCPC,,
+EC_KSI_00,Keyboard,Keyboard Input,IN,no,--,Y,3.30 V,,A2,A2,K15,OTHER,,,
+KSI_01,Keyboard,Keyboard Input,IN,no,--,Y,3.30 V,,A3,A3,K14,OTHER,,,
+EC_KSI_02,Keyboard,Keyboard Input,IN,no,--,Y,3.30 V,,A4,A4,K10,OTHER,,,
+EC_KSI_03,Keyboard,Keyboard Input,IN,no,--,Y,3.30 V,,B3,B3,J15,OTHER,,,Vivaldi Support
+KSI_04,Keyboard,Keyboard Input,IN,no,--,Y,3.30 V,,B4,B4,J10,OTHER,,,
+KSI_05,Keyboard,Keyboard Input,IN,no,--,Y,3.30 V,,C3,C3,J11,OTHER,,,
+KSI_06,Keyboard,Keyboard Input,IN,no,--,Y,3.30 V,,C4,C4,J14,OTHER,,,
+KSI_07,Keyboard,Keyboard Input,IN,no,--,Y,3.30 V,,C5,C5,H10,OTHER,,,
+KSO_00,Keyboard,Keyboard Output,OUT,,OD,N,3.30 V,,B5,B5,R9,OTHER,,,
+KSO_01,Keyboard,Keyboard Output,OUT,,OD,N,3.30 V,,B6,B6,K8,OTHER,,,
+EC_KSO_02_INV,Keyboard,Keyboard Output,OUT,,TTL,N,3.30 V,,B7,B7,P10,OUTPUT_L,,KEYBOARD_COL2_INVERTED,
+KSO_03,Keyboard,Keyboard Output,OUT,,OD,N,3.30 V,,B8,B8,R10,OTHER,,,
+KSO_04,Keyboard,Keyboard Output,OUT,,OD,N,3.30 V,,C7,C7,L9,OTHER,,,
+KSO_05,Keyboard,Keyboard Output,OUT,,OD,N,3.30 V,,C6,C6,K9,OTHER,,,
+KSO_06,Keyboard,Keyboard Output,OUT,,OD,N,3.30 V,,C8,C8,P11,OTHER,,,
+KSO_07,Keyboard,Keyboard Output,OUT,,OD,N,3.30 V,,B9,B9,R11,OTHER,,,
+KSO_08,Keyboard,Keyboard Output,OUT,,OD,N,3.30 V,,C9,C9,P12,OTHER,,,
+KSO_09,Keyboard,Keyboard Output,OUT,,OD,N,3.30 V,,C10,C10,L10,OTHER,,,
+KSO_10,Keyboard,Keyboard Output,OUT,,OD,N,3.30 V,,B11,B11,P13,OTHER,,,
+KSO_11,Keyboard,Keyboard Output,OUT,,OD,N,3.30 V,,B10,B10,P14,OTHER,,,
+KSO_12,Keyboard,Keyboard Output,OUT,,OD,N,3.30 V,,C11,C11,N14,OTHER,,,
+KSO_13,Keyboard,Keyboard Output,OUT,,OD,N,3.30 V,,D11,D11,M15,OTHER,,,Required only for NUM PAD
+KSO_14,Keyboard,Keyboard Output,OUT,,OD,N,3.30 V,,D6,D6,M14,OTHER,,,Required only for NUM PAD
+EN_KB_BL,MISC,Enable Keyboard backlight,OUT,,TTL,N,3.30 V,,G11,G11,D14,OUTPUT,GPIO_EN_KEYBOARD_BACKLIGHT,,
+VOLDN_BTN_ODL,MISC,Volume down signal,IN,both,--,Y,3.30 V,Button,F12,E11,G15,INPUT_PU,GPIO_VOLUME_DOWN_L,,
+VOLUP_BTN_ODL,MISC,Volume up signal,IN,both,--,Y,3.30 V,Button,E11,F12,F14,INPUT_PU,GPIO_VOLUME_UP_L,,
+LID_OPEN,MISC,Indicator from lid switch that lid is open,IN,both,--,N,3.30 V,,G7,G7,A11,INPUT,GPIO_LID_OPEN,,
+TABLET_MODE_L,MISC,Indicator from lid switch that lid is flipped all the way around,IN,both,--,N,3.30 V,,M12,M12,L8,INPUT,GPIO_TABLET_MODE_L,,Not required to connect to EC?
+IMU_INT_L,MISC,Interrupt from base intertial measurement unit,IN,falling,,N,1.80 V,IMU,M2,M2,F15,INPUT,,,
+ACC_INT_L,MISC,Interrupt from lid accel (only in convertibles),IN,falling,,N,1.80 V,ACC,G10,G10,E2,INPUT,,,Not required from Dedede?
+EC_WP_ODL,MISC,Write protection status from GSC,IN,no,--,N,3.30 V,GSC,L12,L12,R8,INPUT_L,,,
+EC_EDP_BL_EN_OD,MISC,EC override of backlight enable,OUT,,OD,N,3.30 V,,E10,E10,R15,OUTPUT_ODR,GPIO_ENABLE_BACKLIGHT,,
+TEMP_SENSOR_1,MISC,NTC 1 - near memory,IN,no,ADC,N,ANA,,F2,F2,H15,ADC,ADC_TEMP_SENSOR_1,,
+TEMP_SENSOR_2,MISC,NTC 2 - near chassis hot spot,IN,no,ADC,N,ANA,,E3,E3,G10,ADC,ADC_TEMP_SENSOR_2,,
+TEMP_SENSOR_3,MISC,NTC 3 - Ambient/skin temp,IN,no,ADC,N,ANA,,,F4,A13,ADC,ADC_TEMP_SENSOR_3,,
+USB_C0_INT_ODL,MISC,Interrupt for all ICs for Type-C port 0,IN,,--,Y,3.30 V,,E6,E6,P1,INPUT_PU,,,
+USB_C0_PROT_FAULT_ODL,MISC,Fault out of the USB C0 protection IC,IN,falling,OD,Y,3.30 V,,,#N/A,,,,,
+"SUB_USB_C1_INT_ODL
+(HDMI: EN_SUB_RAILS_ODL)",MISC,"Interrupt for all ICs for Type-C port 1 or the sub-board
+HDMI: Enable 5V power rail/output/active low",IN,,--,Y,3.30 V,,F7,F7,N2,OTHER,,,
+HDMI_SEL,MISC,Configures AUX to be HDMI DDC,OUT,,TTL,N,3.30 V,,D10,D10,F2,OUTPUT,,,
+CCD_MODE_ODL,MISC,Indicates whether H1 is using SBU lines for debug. Also can trigger CCD if the EC decides to.,I/O,falling,--/OD,N,3.30 V,GSC,A12,A12,B9,INPUT,GPIO_CCD_MODE_ODL,,
+EC_BATTERY_PRES_ODL,MISC,or BATT_TEMP - indication of battery presence,IN,,--,N,3.30 V,Battery pack,K12,K12,G14,INPUT,GPIO_BATT_PRES_ODL,,
+EC_ENTERING_RW,MISC,Indicate when EC is transitioning to RW code,OUT,,TTL,N,3.30 V,GSC,D9,D9,N1,OUTPUT,GPIO_ENTERING_RW,,
+EN_USB_A0_VBUS,MISC,,OUT,,TTL,N,3.30 V,,K9,K9,B1,OUTPUT,,,
+USB_A0_ILIMIT_SDP,MISC,,OUT,,TTL,N,3.30 V,,J8,J8,A1,OUTPUT,GPIO_USB1_ILIM_SEL,??,
+EN_SUB_USB_A1_VBUS,MISC,,OUT,,TTL,N,3.30 V,,A9,A9,B12,OTHER,,??,
+SUB_USB_A1_ILIMIT_SDP,MISC,,OUT,,TTL,N,3.30 V,,A10,A10,A12,OUTPUT,GPIO_USB2_ILIM_SEL,??,
+PWM_FAN,MISC,,OUT,,PWM,N,3.30 V,,,J7,,PWM,,,
+EC_FAN_TACH,MISC,,IN,,,,5.00 V,,,G5,,TACH,,,
+EN_PP5000_FAN_X,MISC,,OUT,,TTL,N,3.30 V,,,J2,,OUTPUT,,,
+EC_CBI_WP,MISC,Updated EC WP method,OUT,,TTL,N,3.30 V,,H5,H5,D15,OUTPUT,,cbi_latch_eeprom_wp,
+IMVP91_VRRDY_OD,POWER SEQUENCE,,IN,,,,,,E2,E2,C14,INPUT,,,
+EC_SOC_SYS_PWROK,POWER SEQUENCE,"Generic power good input to PCH (platform specific), system ready to exit reset.",OUT,,TTL,N,3.30 V,SOC,C1,C1,B11,OUTPUT,,PCH_PWROK,
+EN_SLP_Z,POWER SEQUENCE,Enable Sleep State (Active high). For ITE only.,OUT,,TTL,N,3.30 V,,F3,F3,R3,OUTPUT,,,
+EN_PP5000_S5,POWER SEQUENCE,"Enable PP5000_S5. Figure 523, states this has to come after 3.3V , why?",OUT,,TTL,N,3.30 V,,E5,E5,R14,OUTPUT,,,
+EN_PP3300_S5,POWER SEQUENCE,Enable PP3300_S5.,OUT,,TTL,N,3.30 V,,L9,L9,K11,OUTPUT,GPIO_TEMP_SENSOR_POWER,,
+EC_SOC_DSW_PWROK,POWER SEQUENCE,DSW Power is OK to AP (diode logic with PP3300_PG),OUT,,TTL,N,3.30 V,SOC,K4,K4,C1,OUTPUT,,,
+EC_SOC_RSMRST_L,POWER SEQUENCE,"Asserted after S5-rails are stable, buffered to SOC from EC",OUT,,TTL,N,3.30 V,SOC,F11,F11,E9,OUTPUT,,,
+RSMRST_PWRGD_L,POWER SEQUENCE,,IN,both,--,Y,3.30 V,,M11,M11,B14,INPUT_PU,,,
+SLP_SUS_L,POWER SEQUENCE,"If high, EC must keep S5 on, used in both DSx and non-DSx platforms.",IN,both,--,N,3.30 V,,H2,H2,F8,INPUT,,,No virtual wire over eSPI
+SLP_S4_L,POWER SEQUENCE,"PCH S4 Sleep control. When low, shut-off power to all non critical systems in S4 and lower.",IN,both,--,N,3.30 V,,J4,J4,G11,INPUT,,,This signal is also virtual wire on the eSPI interface.
+SLP_S3_L,POWER SEQUENCE,"PCH S3 Sleep control. When low, shut-off power to all non critical systems in S3 and lower.",IN,both,--,N,3.30 V,,K11,K11,B10,INPUT,,,This signal is also virtual wire on the eSPI interface.
+SLP_S0_L,POWER SEQUENCE,"PCH S0 Sleep control, asserted when PCH = idle & CPU = C10",IN,both,--,N,3.30 V,,L10,L10,F1,INPUT,,,No virtual wire over eSPI
+CPU_C10_GATE_L,POWER SEQUENCE,Asserted low when going into CPU_C10,IN,both,--,N,3.30 V,"SOC, VRs, LS",J3,J3,B6,INPUT,,??,
+EC_VSENSE_PP3300_S5,POWER SEQUENCE,Voltage sense (or PGOOD) for PP3300_S5,IN,no,ADC,N,ANA,,B2,B2,H11,ADC,ADC_PP3300_S5,??,"Nuvoton VREF=2.816V, ITE VREF = AVCC or AVCC/1.1 (3V)"
+PG_PP5000_S5_OD,POWER SEQUENCE,PP5000_S5 power good signal.,IN,,--,N,3.30 V,,D3,D3,C15,INPUT,,,
+EC_SOC_VCCST_PWRGD_OD,POWER SEQUENCE,,OUT,,OD,N,1.05 V,,H11,H11,P9,OUTPUT_ODR,,,
+EC_SOC_PCH_PWROK_OD,POWER SEQUENCE,,OUT,,OD,N,3.30 V,,M4,M4,R12,OUTPUT_ODR,,,
+ALL_SYS_PWRGD,POWER SEQUENCE,,IN,both,,N,3.30 V,,J11,J11,B2,INPUT,,,Figure 398 PDG 0.5
+PG_PP1050_MEM_S3_OD,POWER SEQUENCE,,IN,both,--,N,3.30 V,,D2,D2,P5,INPUT,,??,
+EC_VSENSE_PP1050_PROC,POWER SEQUENCE,,IN,no,ADC,N,ANA,SOC,C2,C2,A14,ADC,ADC_PP1050_PROC,PP1050_PROC monitoring from FIVR output,
+SYS_RST_ODL,POWER SEQUENCE,Reset for SOC,OUT,,OD,N,3.30 V,SOC,H7,H7,P4,OUTPUT_ODR,,,
+EC_PCH_WAKE_ODL,POWER SEQUENCE,"Allows EC to wake AP (e.g., keyboard out of S0ix)",OUT,,OD,N,3.30 V,SOC,L11,L11,E1,OUTPUT_ODL,,EC_SOC_WAKE_ODL on schematic; software uses PCH_WAKE name,
+EC_SOC_RTCRST,POWER SEQUENCE,Allows EC to reset logic on the AP's RTC well,OUT,,TTL,N,3.30 V,SOC,J5,J5,R2,OUTPUT,,,
+VCCIN_AUX_VID0,POWER SEQUENCE,Debug purposes,IN,both,,N,1.80 V,,L8,L8,P2,INPUT,,,
+VCCIN_AUX_VID1,POWER SEQUENCE,Debug purposes,IN,both,,N,1.80 V,,L7,L7,R1,INPUT,,,
+PWM_KB_BL,PWM,Keyboard backlight PWM control signal,OUT,,PWM,N,3.30 V,,H8,H8,R6,PWM,,,
+PWM_LED_1_ODL,PWM,LED 1,OUT,,PWM,N,3.30 V,,G8,G8,P6,PWM_INVERT,,,
+PWM_LED_2_ODL,PWM,LED 2,OUT,,PWM,N,3.30 V,,G9,G9,R7,PWM_INVERT,,,
+PWM_LED_3_ODL,PWM,LED 3,OUT,,PWM,N,3.30 V,,H10,H10,P7,PWM_INVERT,,,
+EC_PSYS,PWM,System power monitoring output,OUT,,PWM,N,ANA,"Charger, IMVP9.1",G6,G6,E15,OTHER,,,
+EC_SOC_PWR_BTN_ODL,SOC,Buffered power button signal from EC to SOC,OUT,,OD,N,3.30 V,SOC,H9,H9,J5,OUTPUT_ODR,GPIO_PCH_PWRBTN_L,,
+EC_SOC_HDMI_HPD,SOC,HPD buffer output for HDMI,OUT,,TTL,N,3.30 V,,L6,L6,P15,OUTPUT,,,
+EC_PROCHOT_ODL,SOC,Allows us to send/read PROCHOT,I/O,both,OD,N,1.05 V,SOC,G3,G3,H14,OUTPUT_ODR,,,
+EC_PCHHOT_ODL,SOC,Allows us to send/read PCHHOT,,,,,,,#N/A,#N/A,#N/A,OTHER,,,Intel confirmed that this feature is not used.
+EC_SOC_INT_ODL,SOC,EC interrupt to SOC,OUT,,OD,N,,,K5,K5,P8,OUTPUT_ODR,GPIO_EC_INT_L,,Is this needed?
+UART_GSC_DBG_RX_EC_TX,UART,UART signal from EC to debugger,OUT,,TTL,N,3.30 V,,H4,H4,B4,OTHER,,,
+UART_GSC_DBG_TX_EC_RX,UART,UART signal from debugger to EC,IN,,--,N,3.30 V,,G4,G4,B5,OTHER,,,
+EN_PP5000_PEN_X,MISC,Enable signal for 5V PEN charging rail,OUT,,TTL,N,3.30 V,,A11,A11,G2,OUTPUT,,,
+PEN_DETECT_ODL,MISC,"PEN detect signal. Internal debouncing, if required.",IN,both,--,Y,3.30 V,,G12,G12,E14,INPUT_PU,,,
+USB_C0_CC1,USB-PD,CC1 for IT81302 only,I/O,,CC,PD,ANA,,#N/A,#N/A,E10,OTHER,,,
+USB_C0_CC2,USB-PD,CC2 for IT81302 only,I/O,,CC,PD,ANA,,#N/A,#N/A,A10,OTHER,,,
+USB_C0_FRS,USB-PD,FRS for IT81302 only,OUT,,TTL,N,3.30 V,,#N/A,#N/A,D1,OUTPUT,,,
+EN_USB_C0_CC1_VCONN,USB-PD,CC1 vconn en for IT81302 only,OUT,,TTL,N,3.30 V,,#N/A,#N/A,A9,OUTPUT,,,
+EN_USB_C0_CC2_VCONN,USB-PD,CC2 vconn en for IT81302 only,OUT,,TTL,N,3.30 V,,#N/A,#N/A,A8,OUTPUT,,,
+EC_TRIS_L,DEBUG,Debug for NPCX993,,,,,,,E4,E4,#N/A,OTHER,,,
+EC_TEST_L,DEBUG,Debug for NPCX994,,,,,,,K2,K2,#N/A,OTHER,,,
+EC_32KXOUT,DEBUG,Debug for NPCX995,,,,,,,M5,M5,#N/A,OTHER,,,
+EC_SHDF_ESPI_L,DEBUG,Debug for NPCX996,,,,,,,H3,H3,#N/A,OTHER,,,
\ No newline at end of file diff --git a/zephyr/projects/nissa/nivviks/cbi.dtsi b/zephyr/projects/nissa/nivviks/cbi.dtsi new file mode 100644 index 0000000000..112a2a885c --- /dev/null +++ b/zephyr/projects/nissa/nivviks/cbi.dtsi @@ -0,0 +1,30 @@ +/* Copyright 2022 The ChromiumOS Authors + * Use of this source code is governed by a BSD-style license that can be + * found in the LICENSE file. + */ + +/ { + /* Nivviks-specific fw_config fields. */ + nissa-fw-config { + /* + * FW_CONFIG field to describe mainboard orientation in chassis. + */ + base-inversion { + enum-name = "FW_BASE_INVERSION"; + start = <3>; + size = <1>; + + inverted { + compatible = "cros-ec,cbi-fw-config-value"; + enum-name = "FW_BASE_INVERTED"; + value = <0>; + }; + regular { + compatible = "cros-ec,cbi-fw-config-value"; + enum-name = "FW_BASE_REGULAR"; + value = <1>; + default; + }; + }; + }; +}; diff --git a/zephyr/projects/nissa/nivviks/generated.dtsi b/zephyr/projects/nissa/nivviks/generated.dtsi new file mode 100644 index 0000000000..91718302b4 --- /dev/null +++ b/zephyr/projects/nissa/nivviks/generated.dtsi @@ -0,0 +1,291 @@ +/* Copyright 2022 The ChromiumOS Authors + * Use of this source code is governed by a BSD-style license that can be + * found in the LICENSE file. + * + * This file is auto-generated - do not edit! + */ + +/ { + + named-adc-channels { + compatible = "named-adc-channels"; + + adc_ec_vsense_pp1050_proc: ec_vsense_pp1050_proc { + enum-name = "ADC_PP1050_PROC"; + io-channels = <&adc0 4>; + }; + adc_ec_vsense_pp3300_s5: ec_vsense_pp3300_s5 { + enum-name = "ADC_PP3300_S5"; + io-channels = <&adc0 6>; + }; + adc_temp_sensor_1: temp_sensor_1 { + enum-name = "ADC_TEMP_SENSOR_1"; + io-channels = <&adc0 0>; + }; + adc_temp_sensor_2: temp_sensor_2 { + enum-name = "ADC_TEMP_SENSOR_2"; + io-channels = <&adc0 1>; + }; + adc_temp_sensor_3: temp_sensor_3 { + enum-name = "ADC_TEMP_SENSOR_3"; + io-channels = <&adc0 10>; + }; + }; + + named-gpios { + compatible = "named-gpios"; + + gpio_acc_int_l: acc_int_l { + gpios = <&gpio5 0 GPIO_INPUT>; + }; + gpio_all_sys_pwrgd: all_sys_pwrgd { + gpios = <&gpioa 7 GPIO_INPUT>; + }; + gpio_ccd_mode_odl: ccd_mode_odl { + gpios = <&gpioe 5 GPIO_INPUT>; + enum-name = "GPIO_CCD_MODE_ODL"; + }; + gpio_cpu_c10_gate_l: cpu_c10_gate_l { + gpios = <&gpio6 7 GPIO_INPUT>; + }; + gpio_ec_battery_pres_odl: ec_battery_pres_odl { + gpios = <&gpioa 3 GPIO_INPUT>; + enum-name = "GPIO_BATT_PRES_ODL"; + }; + gpio_ec_cbi_wp: ec_cbi_wp { + gpios = <&gpio7 4 GPIO_OUTPUT>; + }; + gpio_ec_edp_bl_en_od: ec_edp_bl_en_od { + gpios = <&gpiod 3 GPIO_ODR_HIGH>; + enum-name = "GPIO_ENABLE_BACKLIGHT"; + }; + gpio_ec_entering_rw: ec_entering_rw { + gpios = <&gpio0 3 GPIO_OUTPUT>; + enum-name = "GPIO_ENTERING_RW"; + }; + gpio_ec_gsc_packet_mode: ec_gsc_packet_mode { + gpios = <&gpio7 5 GPIO_OUTPUT>; + enum-name = "GPIO_PACKET_MODE_EN"; + }; + gpio_ec_kso_02_inv: ec_kso_02_inv { + gpios = <&gpio1 7 (GPIO_OUTPUT_LOW | GPIO_ACTIVE_LOW)>; + }; + gpio_ec_pch_wake_odl: ec_pch_wake_odl { + gpios = <&gpiob 0 GPIO_ODR_LOW>; + }; + gpio_ec_prochot_odl: ec_prochot_odl { + gpios = <&gpiof 1 GPIO_ODR_HIGH>; + }; + gpio_ec_soc_dsw_pwrok: ec_soc_dsw_pwrok { + gpios = <&gpio6 1 GPIO_OUTPUT>; + }; + gpio_ec_soc_hdmi_hpd: ec_soc_hdmi_hpd { + gpios = <&gpioe 4 GPIO_OUTPUT>; + }; + gpio_ec_soc_int_odl: ec_soc_int_odl { + gpios = <&gpio8 0 GPIO_ODR_HIGH>; + enum-name = "GPIO_EC_INT_L"; + }; + gpio_ec_soc_pch_pwrok_od: ec_soc_pch_pwrok_od { + gpios = <&gpio7 2 GPIO_ODR_HIGH>; + }; + gpio_ec_soc_pwr_btn_odl: ec_soc_pwr_btn_odl { + gpios = <&gpioc 1 GPIO_ODR_HIGH>; + enum-name = "GPIO_PCH_PWRBTN_L"; + }; + gpio_ec_soc_rsmrst_l: ec_soc_rsmrst_l { + gpios = <&gpioa 6 GPIO_OUTPUT>; + }; + gpio_ec_soc_rtcrst: ec_soc_rtcrst { + gpios = <&gpio7 6 GPIO_OUTPUT>; + }; + gpio_ec_soc_sys_pwrok: ec_soc_sys_pwrok { + gpios = <&gpio3 7 GPIO_OUTPUT>; + }; + gpio_ec_soc_vccst_pwrgd_od: ec_soc_vccst_pwrgd_od { + gpios = <&gpioa 4 GPIO_ODR_HIGH>; + }; + gpio_ec_wp_odl: ec_wp_odl { + gpios = <&gpioa 1 (GPIO_INPUT | GPIO_ACTIVE_LOW)>; + }; + gpio_en_kb_bl: en_kb_bl { + gpios = <&gpioa 0 GPIO_OUTPUT>; + enum-name = "GPIO_EN_KEYBOARD_BACKLIGHT"; + }; + gpio_en_pp3300_s5: en_pp3300_s5 { + gpios = <&gpiob 6 GPIO_OUTPUT>; + enum-name = "GPIO_TEMP_SENSOR_POWER"; + }; + gpio_en_pp5000_pen_x: en_pp5000_pen_x { + gpios = <&gpioe 2 GPIO_OUTPUT>; + }; + gpio_en_pp5000_s5: en_pp5000_s5 { + gpios = <&gpio4 0 GPIO_OUTPUT>; + }; + gpio_en_slp_z: en_slp_z { + gpios = <&gpioe 1 GPIO_OUTPUT>; + }; + gpio_en_usb_a0_vbus: en_usb_a0_vbus { + gpios = <&gpio9 1 GPIO_OUTPUT>; + }; + gpio_gsc_ec_pwr_btn_odl: gsc_ec_pwr_btn_odl { + gpios = <&gpio0 0 GPIO_INPUT_PULL_UP>; + enum-name = "GPIO_POWER_BUTTON_L"; + }; + gpio_hdmi_sel: hdmi_sel { + gpios = <&gpioc 6 GPIO_OUTPUT>; + }; + gpio_imu_int_l: imu_int_l { + gpios = <&gpio5 6 GPIO_INPUT>; + }; + gpio_imvp91_vrrdy_od: imvp91_vrrdy_od { + gpios = <&gpio4 3 GPIO_INPUT>; + }; + gpio_lid_open: lid_open { + gpios = <&gpiod 2 GPIO_INPUT>; + enum-name = "GPIO_LID_OPEN"; + }; + gpio_pen_detect_odl: pen_detect_odl { + gpios = <&gpio9 6 GPIO_INPUT_PULL_UP>; + }; + gpio_pg_pp1050_mem_s3_od: pg_pp1050_mem_s3_od { + gpios = <&gpiof 0 GPIO_INPUT>; + }; + gpio_pg_pp5000_s5_od: pg_pp5000_s5_od { + gpios = <&gpio4 2 GPIO_INPUT>; + }; + gpio_rsmrst_pwrgd_l: rsmrst_pwrgd_l { + gpios = <&gpio9 4 GPIO_INPUT_PULL_UP>; + }; + gpio_slp_s0_l: slp_s0_l { + gpios = <&gpio9 7 GPIO_INPUT>; + }; + gpio_slp_s3_l: slp_s3_l { + gpios = <&gpioa 5 GPIO_INPUT>; + }; + gpio_slp_s4_l: slp_s4_l { + gpios = <&gpio7 0 GPIO_INPUT>; + }; + gpio_slp_sus_l: slp_sus_l { + gpios = <&gpio6 2 GPIO_INPUT>; + }; + gpio_sub_usb_a1_ilimit_sdp: sub_usb_a1_ilimit_sdp { + gpios = <&gpiod 5 GPIO_OUTPUT>; + enum-name = "GPIO_USB2_ILIM_SEL"; + }; + gpio_sys_rst_odl: sys_rst_odl { + gpios = <&gpioc 5 GPIO_ODR_HIGH>; + }; + gpio_tablet_mode_l: tablet_mode_l { + gpios = <&gpio9 5 GPIO_INPUT>; + enum-name = "GPIO_TABLET_MODE_L"; + }; + gpio_usb_a0_ilimit_sdp: usb_a0_ilimit_sdp { + gpios = <&gpio8 5 GPIO_OUTPUT>; + enum-name = "GPIO_USB1_ILIM_SEL"; + }; + gpio_usb_c0_int_odl: usb_c0_int_odl { + gpios = <&gpio0 1 GPIO_INPUT_PULL_UP>; + }; + gpio_vccin_aux_vid0: vccin_aux_vid0 { + gpios = <&gpio9 2 (GPIO_INPUT | GPIO_VOLTAGE_1P8)>; + }; + gpio_vccin_aux_vid1: vccin_aux_vid1 { + gpios = <&gpioe 3 (GPIO_INPUT | GPIO_VOLTAGE_1P8)>; + }; + gpio_voldn_btn_odl: voldn_btn_odl { + gpios = <&gpioa 2 GPIO_INPUT_PULL_UP>; + enum-name = "GPIO_VOLUME_DOWN_L"; + }; + gpio_volup_btn_odl: volup_btn_odl { + gpios = <&gpio9 3 GPIO_INPUT_PULL_UP>; + enum-name = "GPIO_VOLUME_UP_L"; + }; + }; + + named-i2c-ports { + compatible = "named-i2c-ports"; + + i2c_ec_i2c_eeprom: ec_i2c_eeprom { + i2c-port = <&i2c0_0>; + enum-names = "I2C_PORT_EEPROM"; + }; + i2c_ec_i2c_sensor: ec_i2c_sensor { + i2c-port = <&i2c1_0>; + enum-names = "I2C_PORT_SENSOR"; + }; + i2c_ec_i2c_usb_c0: ec_i2c_usb_c0 { + i2c-port = <&i2c3_0>; + enum-names = "I2C_PORT_USB_C0_TCPC"; + }; + i2c_ec_i2c_sub_usb_c1: ec_i2c_sub_usb_c1 { + i2c-port = <&i2c5_1>; + enum-names = "I2C_PORT_USB_C1_TCPC"; + }; + i2c_ec_i2c_batt: ec_i2c_batt { + i2c-port = <&i2c7_0>; + enum-names = "I2C_PORT_BATTERY"; + }; + }; +}; + +&adc0 { + status = "okay"; + pinctrl-0 = <&adc0_chan0_gp45 + &adc0_chan1_gp44 + &adc0_chan4_gp41 + &adc0_chan6_gp34 + &adc0_chan10_gpe0>; + pinctrl-names = "default"; +}; + + +&i2c0_0 { + status = "okay"; + pinctrl-0 = <&i2c0_0_sda_scl_gpb4_b5>; + pinctrl-names = "default"; +}; + +&i2c1_0 { + status = "okay"; + pinctrl-0 = <&i2c1_0_sda_scl_gp87_90>; + pinctrl-names = "default"; +}; + +&i2c3_0 { + status = "okay"; + pinctrl-0 = <&i2c3_0_sda_scl_gpd0_d1>; + pinctrl-names = "default"; +}; + +&i2c5_1 { + status = "okay"; + pinctrl-0 = <&i2c5_1_sda_scl_gpf4_f5>; + pinctrl-names = "default"; +}; + +&i2c7_0 { + status = "okay"; + pinctrl-0 = <&i2c7_0_sda_scl_gpb2_b3>; + pinctrl-names = "default"; +}; + +&i2c_ctrl0 { + status = "okay"; +}; + +&i2c_ctrl1 { + status = "okay"; +}; + +&i2c_ctrl3 { + status = "okay"; +}; + +&i2c_ctrl5 { + status = "okay"; +}; + +&i2c_ctrl7 { + status = "okay"; +}; diff --git a/zephyr/projects/nissa/nivviks/keyboard.dtsi b/zephyr/projects/nissa/nivviks/keyboard.dtsi new file mode 100644 index 0000000000..00610e4e18 --- /dev/null +++ b/zephyr/projects/nissa/nivviks/keyboard.dtsi @@ -0,0 +1,48 @@ +/* Copyright 2022 The ChromiumOS Authors + * Use of this source code is governed by a BSD-style license that can be + * found in the LICENSE file. + */ + +/ { + kblight { + compatible = "cros-ec,kblight-pwm"; + pwms = <&pwm6 6 PWM_HZ(2400) PWM_POLARITY_NORMAL>; + }; +}; + +&pwm6 { + status = "okay"; + clock-bus = "NPCX_CLOCK_BUS_LFCLK"; + pinctrl-0 = <&pwm6_gpc0>; + pinctrl-names = "default"; +}; + +&cros_kb_raw { + status = "okay"; + /* No KSO2 (it's inverted and implemented by GPIO) */ + pinctrl-0 = < + &ksi0_gp31 + &ksi1_gp30 + &ksi2_gp27 + &ksi3_gp26 + &ksi4_gp25 + &ksi5_gp24 + &ksi6_gp23 + &ksi7_gp22 + &kso00_gp21 + &kso01_gp20 + &kso03_gp16 + &kso04_gp15 + &kso05_gp14 + &kso06_gp13 + &kso07_gp12 + &kso08_gp11 + &kso09_gp10 + &kso10_gp07 + &kso11_gp06 + &kso12_gp05 + &kso13_gp04 + &kso14_gp82 + >; + pinctrl-names = "default"; +}; diff --git a/zephyr/projects/nissa/nivviks/motionsense.dtsi b/zephyr/projects/nissa/nivviks/motionsense.dtsi new file mode 100644 index 0000000000..6297a07bf5 --- /dev/null +++ b/zephyr/projects/nissa/nivviks/motionsense.dtsi @@ -0,0 +1,166 @@ +/* Copyright 2021 The ChromiumOS Authors + * Use of this source code is governed by a BSD-style license that can be + * found in the LICENSE file. + */ + +#include <dt-bindings/motionsense/utils.h> + + +/ { + aliases { + /* + * Interrupt bindings for sensor devices. + */ + lsm6dso-int = &base_accel; + lis2dw12-int = &lid_accel; + }; + + /* + * Declare mutexes used by sensor drivers. + * A mutex node is used to create an instance of mutex_t. + * A mutex node is referenced by a sensor node if the + * corresponding sensor driver needs to use the + * instance of the mutex. + */ + motionsense-mutex { + compatible = "cros-ec,motionsense-mutex"; + lid_mutex: lid-mutex { + }; + + base_mutex: base-mutex { + }; + }; + + /* Rotation matrix used by drivers. */ + motionsense-rotation-ref { + compatible = "cros-ec,motionsense-rotation-ref"; + lid_rot_ref: lid-rotation-ref { + mat33 = <(-1) 0 0 + 0 1 0 + 0 0 (-1)>; + }; + + base_rot_ref: base-rot-ref { + mat33 = <(-1) 0 0 + 0 (-1) 0 + 0 0 1>; + }; + + base_rot_inverted: base-rotation-inverted { + mat33 = <1 0 0 + 0 (-1) 0 + 0 0 (-1)>; + }; + }; + + /* + * Driver specific data. A driver-specific data can be shared with + * different motion sensors while they are using the same driver. + * + * If a node's compatible starts with "cros-ec,accelgyro-", it is for + * a common structure defined in accelgyro.h. + * e.g) compatible = "cros-ec,accelgyro-als-drv-data" is for + * "struct als_drv_data_t" in accelgyro.h + */ + motionsense-sensor-data { + lsm6dso_accel_data: lsm6dso-accel-drv-data { + compatible = "cros-ec,drvdata-lsm6dso"; + status = "okay"; + }; + + lsm6dso_gyro_data: lsm6dso-gyro-drv-data { + compatible = "cros-ec,drvdata-lsm6dso"; + status = "okay"; + }; + + lis2dw12_data: lis2dw12-drv-data { + compatible = "cros-ec,drvdata-lis2dw12"; + status = "okay"; + }; + }; + + /* + * List of motion sensors that creates motion_sensors array. + * The nodelabel "lid_accel" and "base_accel" are used to indicate + * motion sensor IDs for lid angle calculation. + * TODO(b/238139272): The first entries of the array must be + * accelerometers,then gyroscope. Fix this dependency in the DTS + * processing which makes the devicetree entries independent. + */ + motionsense-sensor { + lid_accel: lid-accel { + compatible = "cros-ec,lis2dw12"; + status = "okay"; + + active-mask = "SENSOR_ACTIVE_S0_S3"; + location = "MOTIONSENSE_LOC_LID"; + mutex = <&lid_mutex>; + port = <&i2c_ec_i2c_sensor>; + rot-standard-ref = <&lid_rot_ref>; + default-range = <2>; + drv-data = <&lis2dw12_data>; + i2c-spi-addr-flags = "LIS2DWL_ADDR0_FLAGS"; + configs { + compatible = + "cros-ec,motionsense-sensor-config"; + ec-s0 { + odr = <(10000 | ROUND_UP_FLAG)>; + }; + ec-s3 { + odr = <(10000 | ROUND_UP_FLAG)>; + }; + }; + }; + + base_accel: base-accel { + compatible = "cros-ec,lsm6dso-accel"; + status = "okay"; + + active-mask = "SENSOR_ACTIVE_S0_S3"; + location = "MOTIONSENSE_LOC_BASE"; + mutex = <&base_mutex>; + port = <&i2c_ec_i2c_sensor>; + /* + * May be replaced by alternate depending + * on board config. + */ + rot-standard-ref = <&base_rot_ref>; + drv-data = <&lsm6dso_accel_data>; + configs { + compatible = + "cros-ec,motionsense-sensor-config"; + ec-s0 { + odr = <(10000 | ROUND_UP_FLAG)>; + }; + ec-s3 { + odr = <(10000 | ROUND_UP_FLAG)>; + }; + }; + }; + + base_gyro: base-gyro { + compatible = "cros-ec,lsm6dso-gyro"; + status = "okay"; + + active-mask = "SENSOR_ACTIVE_S0_S3"; + location = "MOTIONSENSE_LOC_BASE"; + mutex = <&base_mutex>; + port = <&i2c_ec_i2c_sensor>; + rot-standard-ref = <&base_rot_ref>; + default-range = <(1000 | ROUND_UP_FLAG)>; /* dps */ + drv-data = <&lsm6dso_gyro_data>; + }; + }; + + motionsense-sensor-info { + compatible = "cros-ec,motionsense-sensor-info"; + + /* + * list of GPIO interrupts that have to + * be enabled at initial stage + */ + sensor-irqs = <&int_imu>; + /* list of sensors in force mode */ + accel-force-mode-sensors = <&lid_accel>; + }; +}; diff --git a/zephyr/projects/nissa/nivviks/overlay.dtsi b/zephyr/projects/nissa/nivviks/overlay.dtsi new file mode 100644 index 0000000000..c2d5e3f24b --- /dev/null +++ b/zephyr/projects/nissa/nivviks/overlay.dtsi @@ -0,0 +1,418 @@ +/* Copyright 2021 The ChromiumOS Authors + * Use of this source code is governed by a BSD-style license that can be + * found in the LICENSE file. + */ + +#include <cros/thermistor/thermistor.dtsi> + +/ { + aliases { + gpio-cbi-wp = &gpio_ec_cbi_wp; + gpio-wp = &gpio_ec_wp_odl; + int-wp = &int_wp_l; + gpio-kbd-kso2 = &gpio_ec_kso_02_inv; + }; + + ec-console { + compatible = "ec-console"; + disabled = "events", "lpc", "hostcmd"; + }; + + batteries { + default_battery: lgc { + compatible = "lgc,ap18c8k", "battery-smart"; + }; + lgc_ap19b8m { + compatible = "lgc,ap19b8m", "battery-smart"; + }; + }; + + hibernate-wake-pins { + compatible = "cros-ec,hibernate-wake-pins"; + wakeup-irqs = < + &int_power_button + &int_lid_open + >; + }; + + gpio-interrupts { + compatible = "cros-ec,gpio-interrupts"; + + int_power_button: power_button { + irq-pin = <&gpio_gsc_ec_pwr_btn_odl>; + flags = <GPIO_INT_EDGE_BOTH>; + handler = "power_button_interrupt"; + }; + int_wp_l: wp_l { + irq-pin = <&gpio_ec_wp_odl>; + flags = <GPIO_INT_EDGE_BOTH>; + handler = "switch_interrupt"; + }; + int_lid_open: lid_open { + irq-pin = <&gpio_lid_open>; + flags = <GPIO_INT_EDGE_BOTH>; + handler = "lid_interrupt"; + }; + int_tablet_mode: tablet_mode { + irq-pin = <&gpio_tablet_mode_l>; + flags = <GPIO_INT_EDGE_BOTH>; + handler = "gmr_tablet_switch_isr"; + }; + int_imu: ec_imu { + irq-pin = <&gpio_imu_int_l>; + flags = <GPIO_INT_EDGE_FALLING>; + handler = "lsm6dso_interrupt"; + }; + int_vol_down: vol_down { + irq-pin = <&gpio_voldn_btn_odl>; + flags = <GPIO_INT_EDGE_BOTH>; + handler = "button_interrupt"; + }; + int_vol_up: vol_up { + irq-pin = <&gpio_volup_btn_odl>; + flags = <GPIO_INT_EDGE_BOTH>; + handler = "button_interrupt"; + }; + int_usb_c0: usb_c0 { + irq-pin = <&gpio_usb_c0_int_odl>; + flags = <GPIO_INT_EDGE_FALLING>; + handler = "usb_interrupt"; + }; + int_usb_c1: usb_c1 { + irq-pin = <&gpio_sb_1>; + flags = <GPIO_INT_EDGE_FALLING>; + handler = "usb_interrupt"; + }; + }; + + named-gpios { + gpio_sb_1: sb-1 { + gpios = <&gpio0 2 GPIO_PULL_UP>; + no-auto-init; + }; + + gpio_sb_2: sb-2 { + gpios = <&gpiod 4 GPIO_OUTPUT>; + no-auto-init; + }; + + /* + * Set I2C pins for type C sub-board to be low voltage (I2C5_1). + * We do this for all boards, since the pins are 3.3V tolerant, + * and the only 2 types of sub-boards used on nivviks both have + * type-C ports on them. + */ + gpio_sb_3: sb-3 { + gpios = <&gpiof 4 (GPIO_OPEN_DRAIN | GPIO_VOLTAGE_1P8)>; + no-auto-init; + }; + gpio_sb_4: sb-4 { + gpios = <&gpiof 5 (GPIO_INPUT | GPIO_VOLTAGE_1P8)>; + no-auto-init; + }; + gpio_fan_enable: fan-enable { + gpios = <&gpio6 3 GPIO_OUTPUT>; + no-auto-init; + }; + ec-i2c-sensor-scl { + gpios = <&gpio9 0 (GPIO_INPUT | GPIO_VOLTAGE_1P8)>; + }; + ec-i2c-sensor-sda { + gpios = <&gpio8 7 (GPIO_INPUT | GPIO_VOLTAGE_1P8)>; + }; + }; + + /* + * Aliases used for sub-board GPIOs. + */ + aliases { + /* + * Input GPIO when used with type-C port 1 + * Output when used with HDMI sub-board + */ + gpio-usb-c1-int-odl = &gpio_sb_1; + gpio-en-rails-odl = &gpio_sb_1; + /* + * Sub-board with type A USB, enable. + */ + gpio-en-usb-a1-vbus = &gpio_sb_2; + /* + * HPD pins for HDMI sub-board. + */ + gpio-hdmi-en-odl = &gpio_sb_3; + gpio-hpd-odl = &gpio_sb_4; + /* + * Enable S5 rails for LTE sub-board + */ + gpio-en-sub-s5-rails = &gpio_sb_2; + }; + + temp_memory: memory { + compatible = "cros-ec,temp-sensor-thermistor"; + thermistor = <&thermistor_3V3_51K1_47K_4050B>; + adc = <&adc_temp_sensor_1>; + }; + temp_charger: charger { + compatible = "cros-ec,temp-sensor-thermistor"; + thermistor = <&thermistor_3V3_51K1_47K_4050B>; + adc = <&adc_temp_sensor_2>; + }; + temp_ambient: ambient { + compatible = "cros-ec,temp-sensor-thermistor"; + thermistor = <&thermistor_3V3_51K1_47K_4050B>; + adc = <&adc_temp_sensor_3>; + }; + + named-temp-sensors { + compatible = "cros-ec,temp-sensors"; + memory { + temp_fan_off = <35>; + temp_fan_max = <60>; + temp_host_high = <85>; + temp_host_halt = <90>; + temp_host_release_high = <80>; + power-good-pin = <&gpio_ec_soc_dsw_pwrok>; + sensor = <&temp_memory>; + }; + charger { + temp_fan_off = <35>; + temp_fan_max = <60>; + temp_host_high = <85>; + temp_host_halt = <90>; + temp_host_release_high = <80>; + power-good-pin = <&gpio_ec_soc_dsw_pwrok>; + sensor = <&temp_charger>; + }; + ambient { + temp_fan_off = <35>; + temp_fan_max = <60>; + temp_host_high = <85>; + temp_host_halt = <90>; + temp_host_release_high = <80>; + power-good-pin = <&gpio_ec_soc_dsw_pwrok>; + sensor = <&temp_ambient>; + }; + }; + + usba { + compatible = "cros-ec,usba-port-enable-pins"; + /* + * sb_2 is only configured as GPIO when USB-A1 is present, + * but it's still safe to control when disabled. + * + * ILIM_SEL pins are referred to by legacy enum name, + * GPIO_USB*_ILIM_SEL. The one for port A1 is unused on + * sub-boards that don't have USB-A so is safe to control + * regardless of system configuration. + */ + enable-pins = <&gpio_en_usb_a0_vbus &gpio_sb_2>; + status = "okay"; + }; + + usbc { + #address-cells = <1>; + #size-cells = <0>; + + port0@0 { + compatible = "named-usbc-port"; + reg = <0>; + bc12 = <&bc12_port0>; + chg = <&chg_port0>; + usb-mux-chain-0 { + compatible = "cros-ec,usb-mux-chain"; + usb-muxes = <&virtual_mux_0>; + }; + }; + port0-muxes { + virtual_mux_0: virtual-mux-0 { + compatible = "cros-ec,usbc-mux-virtual"; + }; + }; + /* + * TODO(b:211693800): port1 may not be present on some + * sub-boards. + */ + port1@1 { + compatible = "named-usbc-port"; + reg = <1>; + bc12 = <&bc12_port1>; + chg = <&chg_port1>; + usb-mux-chain-1 { + compatible = "cros-ec,usb-mux-chain"; + usb-muxes = <&virtual_mux_1 &anx7483_mux_1>; + }; + usb_mux_chain_1_no_mux: usb-mux-chain-1-no-mux { + compatible = "cros-ec,usb-mux-chain"; + alternative-chain; + usb-muxes = <&virtual_mux_1>; + }; + }; + port1-muxes { + virtual_mux_1: virtual-mux-1 { + compatible = "cros-ec,usbc-mux-virtual"; + }; + }; + }; + + fans { + compatible = "cros-ec,fans"; + + fan_0 { + pwms = <&pwm5 5 PWM_KHZ(1) PWM_POLARITY_NORMAL>; + rpm_min = <2200>; + rpm_start = <2200>; + rpm_max = <4200>; + tach = <&tach2>; + enable_gpio = <&gpio_fan_enable>; + }; + }; + + /* + * Declare unused GPIOs so that they are shut down + * and use minimal power + */ + unused-pins { + compatible = "unused-gpios"; + unused-gpios = + <&gpio3 2 0>, + <&gpio3 3 0>, + <&gpio3 5 0>, + <&gpio3 6 0>, + <&gpio5 7 0>, + <&gpio6 0 0>, + <&gpio6 3 0>, + <&gpio6 6 0>, + <&gpio7 3 0>, + <&gpio8 3 0>, + <&gpio8 6 0>, + <&gpiob 1 0>, + <&gpiob 7 0>, + <&gpioc 7 0>, + <&gpiof 2 0>, + <&gpiof 3 0>; + }; +}; + +&thermistor_3V3_51K1_47K_4050B { + status = "okay"; +}; + +&adc_ec_vsense_pp3300_s5 { + /* + * Voltage divider on input has 47k upper and 220k lower legs with + * 2714 mV full-scale reading on the ADC. Apply the largest possible + * multiplier (without overflowing int32) to get the best possible + * approximation of the actual ratio, but derate by a factor of two to + * ensure unexpectedly high values won't overflow. + */ + mul = <(791261 / 2)>; + div = <(651975 / 2)>; +}; + +/* Set bus speeds for I2C */ +&i2c0_0 { + label = "I2C_EEPROM"; + clock-frequency = <I2C_BITRATE_FAST>; + + cbi_eeprom: eeprom@50 { + compatible = "atmel,at24"; + reg = <0x50>; + size = <2048>; + pagesize = <16>; + address-width = <8>; + timeout = <5>; + }; +}; + +&i2c1_0 { + label = "I2C_SENSOR"; + clock-frequency = <I2C_BITRATE_FAST>; +}; + +&i2c3_0 { + label = "I2C_USB_C0_TCPC"; + clock-frequency = <I2C_BITRATE_FAST_PLUS>; + + bc12_port0: pi3usb9201@5f { + compatible = "pericom,pi3usb9201"; + status = "okay"; + reg = <0x5f>; + /* + * BC1.2 interrupt is shared with TCPC, so + * IRQ is not specified here and handled by + * usb_c0_interrupt. + */ + }; + + chg_port0: isl923x@9 { + compatible = "intersil,isl923x"; + status = "okay"; + reg = <0x9>; + }; +}; + +&i2c5_1 { + label = "I2C_SUB_C1_TCPC"; + clock-frequency = <I2C_BITRATE_FAST_PLUS>; + + bc12_port1: pi3usb9201@5f { + compatible = "pericom,pi3usb9201"; + status = "okay"; + reg = <0x5f>; + }; + + chg_port1: isl923x@9 { + compatible = "intersil,isl923x"; + status = "okay"; + reg = <0x9>; + }; + + anx7483_mux_1: anx7483-mux-1@3e { + compatible = "analogix,anx7483"; + reg = <0x3e>; + board-set = "anx7483_set_default_tuning"; + }; +}; + +&i2c7_0 { + label = "I2C_BATTERY"; + clock-frequency = <I2C_BITRATE_STANDARD>; +}; + +&pwm5_gpb7 { + drive-open-drain; +}; + +&pwm5 { + status = "okay"; + clock-bus = "NPCX_CLOCK_BUS_LFCLK"; + pinctrl-0 = <&pwm5_gpb7>; + pinctrl-names = "default"; +}; + +/* Tachometer for fan speed measurement */ +&tach2 { + status = "okay"; + pinctrl-0 = <&ta2_1_in_gp73>; + pinctrl-names = "default"; + port = <NPCX_TACH_PORT_A>; /* port-A is selected */ + sample-clk = <NPCX_TACH_FREQ_LFCLK>; /* Use LFCLK as sampling clock */ + pulses-per-round = <2>; /* number of pulses per round of encoder */ +}; + +/* host interface */ +&espi0 { + status = "okay"; + pinctrl-0 = <&espi_lpc_gp46_47_51_52_53_54_55_57>; + pinctrl-names = "default"; +}; + +/* + * Declare GPIOs that have leakage current caused by board issues here. NPCX ec + * will disable their input buffers before entering deep sleep and restore them + * after waking up automatically for better power consumption. + */ +&power_leakage_io { + leak-gpios = <&gpioa 4 0 + &gpiof 1 0>; +}; diff --git a/zephyr/projects/nissa/nivviks/power_signals.dtsi b/zephyr/projects/nissa/nivviks/power_signals.dtsi new file mode 100644 index 0000000000..1d2b23069d --- /dev/null +++ b/zephyr/projects/nissa/nivviks/power_signals.dtsi @@ -0,0 +1,220 @@ +/* Copyright 2022 The ChromiumOS Authors + * Use of this source code is governed by a BSD-style license that can be + * found in the LICENSE file. + */ + +/ { + chosen { + intel-ap-pwrseq,espi = &espi0; + }; + + common-pwrseq { + compatible = "intel,ap-pwrseq"; + + sys-pwrok-delay = <10>; + all-sys-pwrgd-timeout = <20>; + }; + + pwr-en-pp5000-s5 { + compatible = "intel,ap-pwrseq-gpio"; + dbg-label = "PP5000_S5 enable output to regulator"; + enum-name = "PWR_EN_PP5000_A"; + gpios = <&gpio4 0 0>; + output; + }; + pwr-en-pp3300-s5 { + compatible = "intel,ap-pwrseq-gpio"; + dbg-label = "PP3300_S5 enable output to LS"; + enum-name = "PWR_EN_PP3300_A"; + gpios = <&gpiob 6 0>; + output; + }; + pwr-pg-ec-rsmrst-od { + compatible = "intel,ap-pwrseq-gpio"; + dbg-label = "RSMRST power good from regulator"; + enum-name = "PWR_RSMRST"; + gpios = <&gpio9 4 0>; + interrupt-flags = <GPIO_INT_EDGE_BOTH>; + }; + pwr-ec-pch-rsmrst-odl { + compatible = "intel,ap-pwrseq-gpio"; + dbg-label = "RSMRST output to PCH"; + enum-name = "PWR_EC_PCH_RSMRST"; + gpios = <&gpioa 6 0>; + output; + }; + pwr-slp-s0-l { + compatible = "intel,ap-pwrseq-gpio"; + dbg-label = "SLP_S0_L input from PCH"; + enum-name = "PWR_SLP_S0"; + gpios = <&gpio9 7 GPIO_ACTIVE_LOW>; + interrupt-flags = <GPIO_INT_EDGE_BOTH>; + }; + pwr-slp-s3-l { + compatible = "intel,ap-pwrseq-gpio"; + dbg-label = "SLP_S3_L input from PCH"; + enum-name = "PWR_SLP_S3"; + gpios = <&gpioa 5 GPIO_ACTIVE_LOW>; + interrupt-flags = <GPIO_INT_EDGE_BOTH>; + }; + pwr-slp-sus-l { + compatible = "intel,ap-pwrseq-gpio"; + dbg-label = "SLP_SUS_L input from PCH"; + enum-name = "PWR_SLP_SUS"; + gpios = <&gpio6 2 GPIO_ACTIVE_LOW>; + interrupt-flags = <GPIO_INT_EDGE_BOTH>; + }; + pwr-ec-soc-dsw-pwrok { + compatible = "intel,ap-pwrseq-gpio"; + dbg-label = "DSW_PWROK output to PCH"; + enum-name = "PWR_EC_SOC_DSW_PWROK"; + gpios = <&gpio6 1 0>; + output; + }; + pwr-vccst-pwrgd-od { + compatible = "intel,ap-pwrseq-gpio"; + dbg-label = "VCCST_PWRGD output to PCH"; + enum-name = "PWR_VCCST_PWRGD"; + gpios = <&gpioa 4 GPIO_OPEN_DRAIN>; + output; + }; + pwr-imvp9-vrrdy-od { + compatible = "intel,ap-pwrseq-gpio"; + dbg-label = "VRRDY input from IMVP9"; + enum-name = "PWR_IMVP9_VRRDY"; + gpios = <&gpio4 3 0>; + }; + pwr-pch-pwrok { + compatible = "intel,ap-pwrseq-gpio"; + dbg-label = "PCH_PWROK output to PCH"; + enum-name = "PWR_PCH_PWROK"; + gpios = <&gpio7 2 GPIO_OPEN_DRAIN>; + output; + }; + pwr-ec-pch-sys-pwrok { + compatible = "intel,ap-pwrseq-gpio"; + dbg-label = "SYS_PWROK output to PCH"; + enum-name = "PWR_EC_PCH_SYS_PWROK"; + gpios = <&gpio3 7 0>; + output; + }; + pwr-sys-rst-l { + compatible = "intel,ap-pwrseq-gpio"; + dbg-label = "SYS_RESET# output to PCH"; + enum-name = "PWR_SYS_RST"; + gpios = <&gpioc 5 (GPIO_ACTIVE_LOW|GPIO_OPEN_DRAIN)>; + output; + }; + pwr-slp-s4 { + compatible = "intel,ap-pwrseq-vw"; + dbg-label = "SLP_S4 virtual wire input from PCH"; + enum-name = "PWR_SLP_S4"; + virtual-wire = "ESPI_VWIRE_SIGNAL_SLP_S4"; + vw-invert; + }; + pwr-slp-s5 { + compatible = "intel,ap-pwrseq-vw"; + dbg-label = "SLP_S5 virtual wire input from PCH"; + enum-name = "PWR_SLP_S5"; + virtual-wire = "ESPI_VWIRE_SIGNAL_SLP_S5"; + vw-invert; + }; + pwr-all-sys-pwrgd { + compatible = "intel,ap-pwrseq-external"; + dbg-label = "Combined all power good"; + enum-name = "PWR_ALL_SYS_PWRGD"; + }; + pwr-adc-pp3300 { + compatible = "intel,ap-pwrseq-adc"; + dbg-label = "PP3300 PWROK (from ADC)"; + enum-name = "PWR_DSW_PWROK"; + trigger-high = <&cmp_pp3300_s5_high>; + trigger-low = <&cmp_pp3300_s5_low>; + }; + pwr-adc-pp1p05 { + compatible = "intel,ap-pwrseq-adc"; + dbg-label = "PP1P05 PWROK (from ADC)"; + enum-name = "PWR_PG_PP1P05"; + trigger-high = <&cmp_pp1p05_high>; + trigger-low = <&cmp_pp1p05_low>; + }; + + adc-cmp { + cmp_pp3300_s5_high: pp3300_high { + compatible = "nuvoton,adc-cmp"; + io-channels = <&adc0 6>; + comparison = "ADC_CMP_NPCX_GREATER"; + /* + * This is 90% of nominal voltage considering voltage + * divider on ADC input. + */ + threshold-mv = <2448>; + }; + cmp_pp3300_s5_low: pp3300_low { + compatible = "nuvoton,adc-cmp"; + io-channels = <&adc0 6>; + comparison = "ADC_CMP_NPCX_LESS_OR_EQUAL"; + threshold-mv = <2448>; + }; + cmp_pp1p05_high: pp1p05_high { + compatible = "nuvoton,adc-cmp"; + io-channels = <&adc0 4>; + comparison = "ADC_CMP_NPCX_GREATER"; + /* Setting at 90% of nominal voltage */ + threshold-mv = <945>; + }; + cmp_pp1p05_low: pp1p05_low { + compatible = "nuvoton,adc-cmp"; + io-channels = <&adc0 4>; + comparison = "ADC_CMP_NPCX_LESS_OR_EQUAL"; + threshold-mv = <945>; + }; + }; +}; + +/* + * Because the power signals directly reference the GPIOs, + * the correspinding named-gpios need to have no-auto-init set. + */ +&gpio_ec_soc_dsw_pwrok { + no-auto-init; +}; +&gpio_ec_soc_pch_pwrok_od { + no-auto-init; +}; +&gpio_ec_soc_rsmrst_l { + no-auto-init; +}; +&gpio_ec_soc_sys_pwrok { + no-auto-init; +}; +&gpio_ec_soc_vccst_pwrgd_od { + no-auto-init; +}; +&gpio_en_pp3300_s5 { + no-auto-init; +}; +&gpio_en_pp5000_s5 { + no-auto-init; +}; +&gpio_imvp91_vrrdy_od { + no-auto-init; +}; +&gpio_rsmrst_pwrgd_l { + no-auto-init; +}; +&gpio_slp_s0_l { + no-auto-init; +}; +&gpio_slp_s3_l { + no-auto-init; +}; +&gpio_slp_s4_l { + no-auto-init; +}; +&gpio_slp_sus_l { + no-auto-init; +}; +&gpio_sys_rst_odl { + no-auto-init; +}; diff --git a/zephyr/projects/nissa/nivviks/project.conf b/zephyr/projects/nissa/nivviks/project.conf new file mode 100644 index 0000000000..af9e4e2586 --- /dev/null +++ b/zephyr/projects/nissa/nivviks/project.conf @@ -0,0 +1,8 @@ +# Copyright 2021 The ChromiumOS Authors +# Use of this source code is governed by a BSD-style license that can be +# found in the LICENSE file. + +CONFIG_BOARD_NIVVIKS=y +CONFIG_PLATFORM_EC_OCPC=y + +CONFIG_PLATFORM_EC_ACCELGYRO_LSM6DSO=y diff --git a/zephyr/projects/nissa/nivviks/project.overlay b/zephyr/projects/nissa/nivviks/project.overlay new file mode 100644 index 0000000000..9ca681d979 --- /dev/null +++ b/zephyr/projects/nissa/nivviks/project.overlay @@ -0,0 +1,14 @@ +/* Copyright 2022 The ChromiumOS Authors + * Use of this source code is governed by a BSD-style license that can be + * found in the LICENSE file. + */ + +#include "../cbi.dtsi" + +#include "cbi.dtsi" +#include "generated.dtsi" +#include "keyboard.dtsi" +#include "motionsense.dtsi" +#include "overlay.dtsi" +#include "power_signals.dtsi" +#include "pwm_leds.dtsi" diff --git a/zephyr/projects/nissa/nivviks/pwm_leds.dtsi b/zephyr/projects/nissa/nivviks/pwm_leds.dtsi new file mode 100644 index 0000000000..a265a5929e --- /dev/null +++ b/zephyr/projects/nissa/nivviks/pwm_leds.dtsi @@ -0,0 +1,62 @@ +/* Copyright 2022 The ChromiumOS Authors + * Use of this source code is governed by a BSD-style license that can be + * found in the LICENSE file. + */ + +/ { + pwmleds { + compatible = "pwm-leds"; + pwm_led0: pwm_led_0 { + pwms = <&pwm2 2 PWM_HZ(324) PWM_POLARITY_INVERTED>, + <&pwm0 0 PWM_HZ(324) PWM_POLARITY_INVERTED>, + <&pwm1 1 PWM_HZ(324) PWM_POLARITY_INVERTED>; + }; + }; + + cros-pwmleds { + compatible = "cros-ec,pwm-leds"; + + leds = <&pwm_led0>; + + /*<red green blue>*/ + color-map-red = <100 0 0>; + color-map-green = < 0 100 0>; + color-map-blue = < 0 0 100>; + color-map-yellow = < 0 50 50>; + color-map-white = <100 100 100>; + color-map-amber = <100 0 0>; + + brightness-range = <0 0 100 0 0 100>; + + #address-cells = <1>; + #size-cells = <0>; + + pwm_led_0@0 { + reg = <0>; + ec-led-name = "EC_LED_ID_BATTERY_LED"; + }; + }; +}; + +/* Enable LEDs to work while CPU suspended */ + +&pwm0 { + status = "okay"; + clock-bus = "NPCX_CLOCK_BUS_LFCLK"; + pinctrl-0 = <&pwm0_gpc3>; + pinctrl-names = "default"; +}; + +&pwm1 { + status = "okay"; + clock-bus = "NPCX_CLOCK_BUS_LFCLK"; + pinctrl-0 = <&pwm1_gpc2>; + pinctrl-names = "default"; +}; + +&pwm2 { + status = "okay"; + clock-bus = "NPCX_CLOCK_BUS_LFCLK"; + pinctrl-0 = <&pwm2_gpc4>; + pinctrl-names = "default"; +}; diff --git a/zephyr/projects/nissa/nivviks/src/charger.c b/zephyr/projects/nissa/nivviks/src/charger.c new file mode 100644 index 0000000000..e2f9f966e7 --- /dev/null +++ b/zephyr/projects/nissa/nivviks/src/charger.c @@ -0,0 +1,56 @@ +/* Copyright 2021 The ChromiumOS Authors + * Use of this source code is governed by a BSD-style license that can be + * found in the LICENSE file. + */ + +#include <zephyr/logging/log.h> + +#include "battery.h" +#include "charger.h" +#include "charger/isl923x_public.h" +#include "console.h" +#include "extpower.h" +#include "usb_pd.h" +#include "nissa_common.h" + +LOG_MODULE_DECLARE(nissa, CONFIG_NISSA_LOG_LEVEL); + +int extpower_is_present(void) +{ + int port; + int rv; + bool acok; + + for (port = 0; port < board_get_usb_pd_port_count(); port++) { + rv = raa489000_is_acok(port, &acok); + if ((rv == EC_SUCCESS) && acok) + return 1; + } + + return 0; +} + +/* + * Nivviks does not have a GPIO indicating whether extpower is present, + * so detect using the charger(s). + */ +__override void board_check_extpower(void) +{ + static int last_extpower_present; + int extpower_present = extpower_is_present(); + + if (last_extpower_present ^ extpower_present) + extpower_handle_update(extpower_present); + + last_extpower_present = extpower_present; +} + +__override void board_hibernate(void) +{ + /* Shut down the chargers */ + if (board_get_usb_pd_port_count() == 2) + raa489000_hibernate(CHARGER_SECONDARY, true); + raa489000_hibernate(CHARGER_PRIMARY, true); + LOG_INF("Charger(s) hibernated"); + cflush(); +} diff --git a/zephyr/projects/nissa/nivviks/src/fan.c b/zephyr/projects/nissa/nivviks/src/fan.c new file mode 100644 index 0000000000..840049722c --- /dev/null +++ b/zephyr/projects/nissa/nivviks/src/fan.c @@ -0,0 +1,43 @@ +/* Copyright 2022 The ChromiumOS Authors + * Use of this source code is governed by a BSD-style license that can be + * found in the LICENSE file. + */ + +#include <zephyr/devicetree.h> +#include <zephyr/drivers/gpio.h> +#include <zephyr/logging/log.h> + +#include "cros_cbi.h" +#include "fan.h" +#include "gpio/gpio.h" +#include "hooks.h" + +#include "nissa_common.h" + +LOG_MODULE_DECLARE(nissa, CONFIG_NISSA_LOG_LEVEL); + +/* + * Nirwen fan support + */ +static void fan_init(void) +{ + int ret; + uint32_t val; + /* + * Retrieve the fan config. + */ + ret = cros_cbi_get_fw_config(FW_FAN, &val); + if (ret != 0) { + LOG_ERR("Error retrieving CBI FW_CONFIG field %d", FW_FAN); + return; + } + if (val != FW_FAN_PRESENT) { + /* Disable the fan */ + fan_set_count(0); + } else { + /* Configure the fan enable GPIO */ + gpio_pin_configure_dt(GPIO_DT_FROM_NODELABEL(gpio_fan_enable), + GPIO_OUTPUT); + } +} +DECLARE_HOOK(HOOK_INIT, fan_init, HOOK_PRIO_POST_FIRST); diff --git a/zephyr/projects/nissa/nivviks/src/form_factor.c b/zephyr/projects/nissa/nivviks/src/form_factor.c new file mode 100644 index 0000000000..602b22baff --- /dev/null +++ b/zephyr/projects/nissa/nivviks/src/form_factor.c @@ -0,0 +1,47 @@ +/* Copyright 2022 The ChromiumOS Authors + * Use of this source code is governed by a BSD-style license that can be + * found in the LICENSE file. + */ + +#include <zephyr/devicetree.h> +#include <zephyr/logging/log.h> + +#include "accelgyro.h" +#include "cros_cbi.h" +#include "hooks.h" +#include "motionsense_sensors.h" + +#include "nissa_common.h" + +LOG_MODULE_DECLARE(nissa, CONFIG_NISSA_LOG_LEVEL); + +/* + * Mainboard orientation support. + */ + +#define ALT_MAT SENSOR_ROT_STD_REF_NAME(DT_NODELABEL(base_rot_inverted)) +#define BASE_SENSOR SENSOR_ID(DT_NODELABEL(base_accel)) +#define BASE_GYRO SENSOR_ID(DT_NODELABEL(base_gyro)) + +static void form_factor_init(void) +{ + int ret; + uint32_t val; + /* + * If the firmware config indicates + * an inverted form factor, use the alternative + * rotation matrix. + */ + ret = cros_cbi_get_fw_config(FW_BASE_INVERSION, &val); + if (ret != 0) { + LOG_ERR("Error retrieving CBI FW_CONFIG field %d", + FW_BASE_INVERSION); + return; + } + if (val == FW_BASE_INVERTED) { + LOG_INF("Switching to inverted base"); + motion_sensors[BASE_SENSOR].rot_standard_ref = &ALT_MAT; + motion_sensors[BASE_GYRO].rot_standard_ref = &ALT_MAT; + } +} +DECLARE_HOOK(HOOK_INIT, form_factor_init, HOOK_PRIO_POST_I2C); diff --git a/zephyr/projects/nissa/nivviks/src/keyboard.c b/zephyr/projects/nissa/nivviks/src/keyboard.c new file mode 100644 index 0000000000..f13d5bf78c --- /dev/null +++ b/zephyr/projects/nissa/nivviks/src/keyboard.c @@ -0,0 +1,29 @@ +/* Copyright 2022 The ChromiumOS Authors + * Use of this source code is governed by a BSD-style license that can be + * found in the LICENSE file. + */ + +#include "ec_commands.h" + +static const struct ec_response_keybd_config nivviks_kb = { + .num_top_row_keys = 10, + .action_keys = { + TK_BACK, /* T1 */ + TK_REFRESH, /* T2 */ + TK_FULLSCREEN, /* T3 */ + TK_OVERVIEW, /* T4 */ + TK_SNAPSHOT, /* 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) +{ + return &nivviks_kb; +} diff --git a/zephyr/projects/nissa/nivviks/src/led.c b/zephyr/projects/nissa/nivviks/src/led.c new file mode 100644 index 0000000000..9087982604 --- /dev/null +++ b/zephyr/projects/nissa/nivviks/src/led.c @@ -0,0 +1,51 @@ +/* Copyright 2022 The ChromiumOS Authors + * Use of this source code is governed by a BSD-style license that can be + * found in the LICENSE file. + * + * Battery LED control for nissa + */ +#include "common.h" +#include "ec_commands.h" +#include "led_common.h" +#include "led_onoff_states.h" +#include "led_pwm.h" + +__override const int led_charge_lvl_1 = 5; +__override const int led_charge_lvl_2 = 97; +__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_S0_BAT_LOW] = { { EC_LED_COLOR_AMBER, + LED_INDEFINITE } }, + [STATE_DISCHARGE_S3] = { { LED_OFF, LED_INDEFINITE } }, + [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_AMBER, + 2 * LED_ONE_SEC }, + { EC_LED_COLOR_BLUE, + 2 * LED_ONE_SEC } }, + }; + +__override void led_set_color_battery(enum ec_led_colors color) +{ + switch (color) { + case EC_LED_COLOR_BLUE: + set_pwm_led_color(EC_LED_ID_BATTERY_LED, EC_LED_COLOR_BLUE); + break; + case EC_LED_COLOR_AMBER: + set_pwm_led_color(EC_LED_ID_BATTERY_LED, EC_LED_COLOR_AMBER); + break; + default: /* LED_OFF and other unsupported colors */ + set_pwm_led_color(EC_LED_ID_BATTERY_LED, -1); + break; + } +} diff --git a/zephyr/projects/nissa/nivviks/src/usbc.c b/zephyr/projects/nissa/nivviks/src/usbc.c new file mode 100644 index 0000000000..14fc5a071d --- /dev/null +++ b/zephyr/projects/nissa/nivviks/src/usbc.c @@ -0,0 +1,277 @@ +/* Copyright 2021 The ChromiumOS Authors + * Use of this source code is governed by a BSD-style license that can be + * found in the LICENSE file. + */ + +#include <zephyr/logging/log.h> + +#include "charge_state_v2.h" +#include "chipset.h" +#include "hooks.h" +#include "usb_mux.h" +#include "system.h" +#include "driver/charger/isl923x_public.h" +#include "driver/retimer/anx7483_public.h" +#include "driver/tcpm/tcpci.h" +#include "driver/tcpm/raa489000.h" + +#include "nissa_common.h" + +LOG_MODULE_DECLARE(nissa, CONFIG_NISSA_LOG_LEVEL); + +struct tcpc_config_t tcpc_config[CONFIG_USB_PD_PORT_MAX_COUNT] = { + { + .bus_type = EC_BUS_TYPE_I2C, + .i2c_info = { + .port = I2C_PORT_USB_C0_TCPC, + .addr_flags = RAA489000_TCPC0_I2C_FLAGS, + }, + .drv = &raa489000_tcpm_drv, + /* RAA489000 implements TCPCI 2.0 */ + .flags = TCPC_FLAGS_TCPCI_REV2_0 | + TCPC_FLAGS_VBUS_MONITOR, + }, + { /* sub-board */ + .bus_type = EC_BUS_TYPE_I2C, + .i2c_info = { + .port = I2C_PORT_USB_C1_TCPC, + .addr_flags = RAA489000_TCPC0_I2C_FLAGS, + }, + .drv = &raa489000_tcpm_drv, + /* RAA489000 implements TCPCI 2.0 */ + .flags = TCPC_FLAGS_TCPCI_REV2_0 | + TCPC_FLAGS_VBUS_MONITOR, + }, +}; + +int board_is_sourcing_vbus(int port) +{ + int regval; + + tcpc_read(port, TCPC_REG_POWER_STATUS, ®val); + return !!(regval & TCPC_REG_POWER_STATUS_SOURCING_VBUS); +} + +int board_set_active_charge_port(int port) +{ + int is_real_port = (port >= 0 && port < CONFIG_USB_PD_PORT_MAX_COUNT); + int i; + int old_port; + + if (!is_real_port && port != CHARGE_PORT_NONE) + return EC_ERROR_INVAL; + + old_port = charge_manager_get_active_charge_port(); + + LOG_INF("New chg p%d", port); + + /* Disable all ports. */ + if (port == CHARGE_PORT_NONE) { + for (i = 0; i < CONFIG_USB_PD_PORT_MAX_COUNT; i++) { + tcpc_write(i, TCPC_REG_COMMAND, + TCPC_REG_COMMAND_SNK_CTRL_LOW); + raa489000_enable_asgate(i, false); + } + + return EC_SUCCESS; + } + + /* Check if port is sourcing VBUS. */ + if (board_is_sourcing_vbus(port)) { + LOG_WRN("Skip enable p%d", port); + return EC_ERROR_INVAL; + } + + /* + * Turn off the other ports' sink path FETs, before enabling the + * requested charge port. + */ + for (i = 0; i < CONFIG_USB_PD_PORT_MAX_COUNT; i++) { + if (i == port) + continue; + + if (tcpc_write(i, TCPC_REG_COMMAND, + TCPC_REG_COMMAND_SNK_CTRL_LOW)) + LOG_WRN("p%d: sink path disable failed.", i); + raa489000_enable_asgate(i, false); + } + + /* + * Stop the charger IC from switching while changing ports. Otherwise, + * we can overcurrent the adapter we're switching to. (crbug.com/926056) + */ + if (old_port != CHARGE_PORT_NONE) + charger_discharge_on_ac(1); + + /* Enable requested charge port. */ + if (raa489000_enable_asgate(port, true) || + tcpc_write(port, TCPC_REG_COMMAND, + TCPC_REG_COMMAND_SNK_CTRL_HIGH)) { + LOG_WRN("p%d: sink path enable failed.", port); + charger_discharge_on_ac(0); + return EC_ERROR_UNKNOWN; + } + + /* Allow the charger IC to begin/continue switching. */ + charger_discharge_on_ac(0); + + return EC_SUCCESS; +} + +uint16_t tcpc_get_alert_status(void) +{ + uint16_t status = 0; + int regval; + + /* + * The interrupt line is shared between the TCPC and BC1.2 detector IC. + * Therefore, go out and actually read the alert registers to report the + * alert status. + */ + if (!gpio_pin_get_dt(GPIO_DT_FROM_NODELABEL(gpio_usb_c0_int_odl))) { + if (!tcpc_read16(0, TCPC_REG_ALERT, ®val)) { + /* The TCPCI Rev 1.0 spec says to ignore bits 14:12. */ + if (!(tcpc_config[0].flags & TCPC_FLAGS_TCPCI_REV2_0)) + regval &= ~((1 << 14) | (1 << 13) | (1 << 12)); + + if (regval) + status |= PD_STATUS_TCPC_ALERT_0; + } + } + + if (board_get_usb_pd_port_count() == 2 && + !gpio_pin_get_dt(GPIO_DT_FROM_ALIAS(gpio_usb_c1_int_odl))) { + if (!tcpc_read16(1, TCPC_REG_ALERT, ®val)) { + /* TCPCI spec Rev 1.0 says to ignore bits 14:12. */ + if (!(tcpc_config[1].flags & TCPC_FLAGS_TCPCI_REV2_0)) + regval &= ~((1 << 14) | (1 << 13) | (1 << 12)); + + if (regval) + status |= PD_STATUS_TCPC_ALERT_1; + } + } + + return status; +} + +void pd_power_supply_reset(int port) +{ + /* Disable VBUS */ + tcpc_write(port, TCPC_REG_COMMAND, TCPC_REG_COMMAND_SRC_CTRL_LOW); + + /* Notify host of power info change. */ + pd_send_host_event(PD_EVENT_POWER_CHANGE); +} + +__override void typec_set_source_current_limit(int port, enum tcpc_rp_value rp) +{ + if (port < 0 || port >= CONFIG_USB_PD_PORT_MAX_COUNT) + return; + + raa489000_set_output_current(port, rp); +} + +int pd_set_power_supply_ready(int port) +{ + int rv; + + if (port >= CONFIG_USB_PD_PORT_MAX_COUNT) + return EC_ERROR_INVAL; + + /* Disable charging. */ + rv = tcpc_write(port, TCPC_REG_COMMAND, TCPC_REG_COMMAND_SNK_CTRL_LOW); + if (rv) + return rv; + + /* Our policy is not to source VBUS when the AP is off. */ + if (chipset_in_state(CHIPSET_STATE_ANY_OFF)) + return EC_ERROR_NOT_POWERED; + + /* Provide Vbus. */ + rv = tcpc_write(port, TCPC_REG_COMMAND, TCPC_REG_COMMAND_SRC_CTRL_HIGH); + if (rv) + return rv; + + rv = raa489000_enable_asgate(port, true); + if (rv) + return rv; + + /* Notify host of power info change. */ + pd_send_host_event(PD_EVENT_POWER_CHANGE); + + return EC_SUCCESS; +} + +void board_reset_pd_mcu(void) +{ + /* + * TODO(b:147316511): could send a reset command to the TCPC here + * if needed. + */ +} + +/* + * Because the TCPCs and BC1.2 chips share interrupt lines, it's possible + * for an interrupt to be lost if one asserts the IRQ, the other does the same + * then the first releases it: there will only be one falling edge to trigger + * the interrupt, and the line will be held low. We handle this by running a + * deferred check after a falling edge to see whether the IRQ is still being + * asserted. If it is, we assume an interrupt may have been lost and we need + * to poll each chip for events again. + */ +#define USBC_INT_POLL_DELAY_US 5000 + +static void poll_c0_int(void); +DECLARE_DEFERRED(poll_c0_int); +static void poll_c1_int(void); +DECLARE_DEFERRED(poll_c1_int); + +static void usbc_interrupt_trigger(int port) +{ + schedule_deferred_pd_interrupt(port); + usb_charger_task_set_event(port, USB_CHG_EVENT_BC12); +} + +static inline void poll_usb_gpio(int port, const struct gpio_dt_spec *gpio, + const struct deferred_data *ud) +{ + if (!gpio_pin_get_dt(gpio)) { + usbc_interrupt_trigger(port); + hook_call_deferred(ud, USBC_INT_POLL_DELAY_US); + } +} + +static void poll_c0_int(void) +{ + poll_usb_gpio(0, GPIO_DT_FROM_NODELABEL(gpio_usb_c0_int_odl), + &poll_c0_int_data); +} + +static void poll_c1_int(void) +{ + poll_usb_gpio(1, GPIO_DT_FROM_ALIAS(gpio_usb_c1_int_odl), + &poll_c1_int_data); +} + +void usb_interrupt(enum gpio_signal signal) +{ + int port; + const struct deferred_data *ud; + + if (signal == GPIO_SIGNAL(DT_NODELABEL(gpio_usb_c0_int_odl))) { + port = 0; + ud = &poll_c0_int_data; + } else { + port = 1; + ud = &poll_c1_int_data; + } + /* + * We've just been called from a falling edge, so there's definitely + * no lost IRQ right now. Cancel any pending check. + */ + hook_call_deferred(ud, -1); + /* Trigger polling of TCPC and BC1.2 in respective tasks */ + usbc_interrupt_trigger(port); + /* Check for lost interrupts in a bit */ + hook_call_deferred(ud, USBC_INT_POLL_DELAY_US); +} diff --git a/zephyr/projects/nissa/npcx_program.conf b/zephyr/projects/nissa/npcx_program.conf new file mode 100644 index 0000000000..5e0dd99501 --- /dev/null +++ b/zephyr/projects/nissa/npcx_program.conf @@ -0,0 +1,47 @@ +# Copyright 2022 The ChromiumOS Authors +# Use of this source code is governed by a BSD-style license that can be +# found in the LICENSE file. + +# EC chip configuration: NPCX993 +CONFIG_CROS_FLASH_NPCX=y +CONFIG_CROS_SYSTEM_NPCX=y +CONFIG_SOC_SERIES_NPCX9=y +CONFIG_PLATFORM_EC_WORKAROUND_FLASH_DOWNLOAD_API=y +CONFIG_SYSCON=y +CONFIG_TACH_NPCX=y +CONFIG_SHELL_BACKEND_SERIAL_RX_RING_BUFFER_SIZE=256 + +# Common sensor drivers +CONFIG_PLATFORM_EC_ACCEL_LIS2DW12=y + +# Keyboard +CONFIG_CROS_KB_RAW_NPCX=y +CONFIG_PLATFORM_EC_KBLIGHT_ENABLE_PIN=y +# Ensure recovery key combination (esc+refresh+power) is reliable +CONFIG_PLATFORM_EC_KEYBOARD_PWRBTN_ASSERTS_KSI3=y +CONFIG_PLATFORM_EC_KEYBOARD_REFRESH_ROW3=y + +# TCPC+PPC: both C0 and C1 (if present) are RAA489000 +CONFIG_PLATFORM_EC_USB_PD_TCPM_RAA489000=y +CONFIG_PLATFORM_EC_USB_PD_DISCHARGE_TCPC=y +CONFIG_PLATFORM_EC_USB_PD_VBUS_DETECT_TCPC=y +CONFIG_PLATFORM_EC_USB_PD_TCPC_LPM_EXIT_DEBOUNCE_US=100000 +# RAA489000 uses TCPCI but not a separate PPC, so custom function is required +CONFIG_PLATFORM_EC_USB_PD_5V_EN_CUSTOM=y +# type C port 1 redriver +CONFIG_PLATFORM_EC_USBC_RETIMER_ANX7483=y +# Save some space +CONFIG_SHELL_MINIMAL=y + +# FRS enable +CONFIG_PLATFORM_EC_USB_PD_FRS=y +CONFIG_PLATFORM_EC_USB_PD_FRS_TCPC=y + +# Charger driver and configuration +CONFIG_PLATFORM_EC_CHARGER_RAA489000=y +CONFIG_PLATFORM_EC_OCPC_DEF_RBATT_MOHMS=22 + +# VSENSE: PP3300_S5 & PP1050_PROC +CONFIG_ADC_CMP_NPCX=y +CONFIG_SENSOR=y +CONFIG_SENSOR_SHELL=n diff --git a/zephyr/projects/nissa/program.conf b/zephyr/projects/nissa/program.conf new file mode 100644 index 0000000000..c23a7f1381 --- /dev/null +++ b/zephyr/projects/nissa/program.conf @@ -0,0 +1,156 @@ +# Copyright 2021 The ChromiumOS Authors +# Use of this source code is governed by a BSD-style license that can be +# found in the LICENSE file. + +# Core EC configuration: build the EC application, using ECOS shims +# (which are currently required for a number of features). +CONFIG_CROS_EC=y +CONFIG_PLATFORM_EC=y +CONFIG_SHIMMED_TASKS=y +CONFIG_LTO=y + +# Debug options and features; can be disabled to save memory or once bringup +# is complete. +CONFIG_LOG=y +CONFIG_LOG_MODE_MINIMAL=y + +# RAM-saving options +# flash shell command is unused, allocated a 4kB buffer for flash test +CONFIG_FLASH_SHELL=n +# EC default 1kB buffer seems unnecessarily large, Zephyr default is 8 bytes +CONFIG_SHELL_BACKEND_SERIAL_TX_RING_BUFFER_SIZE=128 + +# Standard shimmed features +CONFIG_PLATFORM_EC_BACKLIGHT_LID=y +CONFIG_PLATFORM_EC_CONSOLE_CMD_SYSINFO=y +CONFIG_PLATFORM_EC_EEPROM_CBI_WP=y +CONFIG_PLATFORM_EC_LID_SWITCH=y +CONFIG_PLATFORM_EC_POWER_BUTTON=y +CONFIG_PLATFORM_EC_SWITCH=y +CONFIG_PLATFORM_EC_GMR_TABLET_MODE=y +CONFIG_PLATFORM_EC_TABLET_MODE=y +CONFIG_PLATFORM_EC_TABLET_MODE_SWITCH=y +CONFIG_PLATFORM_EC_VBOOT_EFS2=y +CONFIG_PLATFORM_EC_VBOOT_HASH=y + +# Application processor; communicates with EC via eSPI +CONFIG_AP=y +CONFIG_AP_X86_INTEL_ADL=y +CONFIG_ESPI=y +CONFIG_PLATFORM_EC_HOST_INTERFACE_ESPI_VW_SLP_S4=y +CONFIG_PLATFORM_EC_HOST_INTERFACE_ESPI_VW_SLP_S5=y +CONFIG_PLATFORM_EC_HOSTCMD=y +CONFIG_HCDEBUG_OFF=y +CONFIG_PLATFORM_EC_THROTTLE_AP=y +CONFIG_PLATFORM_EC_PORT80=y +CONFIG_PLATFORM_EC_PORT80_QUIET=y + +# AP Power Sequencing +CONFIG_AP_PWRSEQ=y +CONFIG_X86_NON_DSX_PWRSEQ_ADL=y +CONFIG_X86_NON_DSX_PWRSEQ_CONSOLE=y +CONFIG_X86_NON_DSX_PWRSEQ_HOST_CMD=y +CONFIG_AP_PWRSEQ_S0IX=y +CONFIG_AP_PWRSEQ_S0IX_ERROR_RECOVERY=y + +# I2C +CONFIG_I2C=y + +# Keyboard support +CONFIG_PLATFORM_EC_KBLIGHT_ENABLE_PIN=y +CONFIG_PLATFORM_EC_KEYBOARD=y +CONFIG_PLATFORM_EC_KEYBOARD_PROTOCOL_8042=y +CONFIG_PLATFORM_EC_VOLUME_BUTTONS=y +CONFIG_PLATFORM_EC_CMD_BUTTON=n +# Column 2 is driven through the GSC, which inverts the signal going through it +CONFIG_PLATFORM_EC_KEYBOARD_COL2_INVERTED=y + +# LED +CONFIG_PLATFORM_EC_LED_COMMON=y +CONFIG_PLATFORM_EC_LED_PWM=y +CONFIG_PLATFORM_EC_LED_ONOFF_STATES=y +CONFIG_PLATFORM_EC_CONSOLE_CMD_LEDTEST=n + +# MKBP event +CONFIG_PLATFORM_EC_MKBP_EVENT=y +CONFIG_PLATFORM_EC_MKBP_INPUT_DEVICES=y +CONFIG_PLATFORM_EC_MKBP_USE_GPIO_AND_HOST_EVENT=y + +# Temperature sensor support +CONFIG_PLATFORM_EC_TEMP_SENSOR=y +CONFIG_PLATFORM_EC_THERMISTOR=y +CONFIG_PLATFORM_EC_TEMP_SENSOR_FIRST_READ_DELAY=y + +# CBI EEPROM support +CONFIG_EEPROM=y +CONFIG_EEPROM_AT24=y +CONFIG_EEPROM_SHELL=n +CONFIG_PLATFORM_EC_CBI_EEPROM=y +CONFIG_PLATFORM_EC_BOARD_VERSION_CBI=y + + +# PWM support +CONFIG_PWM=y +CONFIG_PWM_SHELL=y + +# TODO(b/188605676): bring these features up +CONFIG_PLATFORM_EC_BACKLIGHT_LID=n + +# Sensors support +CONFIG_PLATFORM_EC_LID_ANGLE=y +CONFIG_PLATFORM_EC_LID_ANGLE_UPDATE=y +CONFIG_PLATFORM_EC_MOTIONSENSE=y +CONFIG_PLATFORM_EC_CONSOLE_CMD_ACCELS=y +CONFIG_PLATFORM_EC_CONSOLE_CMD_ACCEL_INFO=y +CONFIG_PLATFORM_EC_ACCEL_FIFO=y +CONFIG_PLATFORM_EC_SENSOR_TIGHT_TIMESTAMPS=y + +# USB-C: enable PD on up to two ports +CONFIG_PLATFORM_EC_USBC=y +CONFIG_PLATFORM_EC_USBC_PPC=n +CONFIG_PLATFORM_EC_USB_VID=0x18d1 +CONFIG_PLATFORM_EC_USB_PID=0x505a +# USB4 and TBT are unsupported +CONFIG_PLATFORM_EC_USB_PD_USB4=n +CONFIG_PLATFORM_EC_USB_PD_TBT_COMPAT_MODE=n + +CONFIG_PLATFORM_EC_USB_MUX_RUNTIME_CONFIG=y +CONFIG_PLATFORM_EC_USB_MUX_VIRTUAL=y +# ADL integrated muxes are slow: unblock PD +CONFIG_PLATFORM_EC_USB_MUX_TASK=y +CONFIG_PLATFORM_EC_BC12_DETECT_PI3USB9201=y + +# USB-C TCPC and PPC standard options +CONFIG_PLATFORM_EC_USB_PD_TCPC_LOW_POWER=y +CONFIG_PLATFORM_EC_USB_PD_VBUS_MEASURE_CHARGER=y + +# USB-A host ports +CONFIG_PLATFORM_EC_USBA=y +CONFIG_PLATFORM_EC_USB_PORT_ENABLE_DYNAMIC=y +# Both ports use a smart switch with CTL1..3 fixed high, for SDP2 or CDP only: +# either SLGC55545 or PI5USB2546. +CONFIG_PLATFORM_EC_USB_PORT_POWER_SMART=y +CONFIG_PLATFORM_EC_USB_PORT_POWER_SMART_CDP_SDP_ONLY=y +CONFIG_PLATFORM_EC_USB_PORT_POWER_SMART_DEFAULT_CDP=y +CONFIG_PLATFORM_EC_USB_PORT_POWER_SMART_INVERTED=y + +# Battery support +CONFIG_PLATFORM_EC_BATTERY=y +CONFIG_PLATFORM_EC_BATTERY_CUT_OFF=y +CONFIG_PLATFORM_EC_BATTERY_PRESENT_GPIO=y +CONFIG_PLATFORM_EC_BATTERY_FUEL_GAUGE=y +CONFIG_PLATFORM_EC_BATTERY_SMART=y +CONFIG_PLATFORM_EC_BATTERY_REVIVE_DISCONNECT=y + +# Charger support +CONFIG_PLATFORM_EC_CHARGER=y +CONFIG_PLATFORM_EC_CHARGER_SENSE_RESISTOR=10 +CONFIG_PLATFORM_EC_CHARGER_SENSE_RESISTOR_AC=10 +CONFIG_PLATFORM_EC_CHARGER_DISCHARGE_ON_AC=y +CONFIG_PLATFORM_EC_CHARGER_DISCHARGE_ON_AC_CHARGER=y + +# Dynamically select PD voltage to maximize charger efficiency +CONFIG_PLATFORM_EC_USB_PD_DPS=y +# Reduce logging so that state transitions do not cause protocol issues +# pd dump [1-3] can be used to increase the debugging level +CONFIG_PLATFORM_EC_USB_PD_INITIAL_DEBUG_LEVEL=0 diff --git a/zephyr/projects/nissa/pujjo/cbi.dtsi b/zephyr/projects/nissa/pujjo/cbi.dtsi new file mode 100644 index 0000000000..b5ba92bd9e --- /dev/null +++ b/zephyr/projects/nissa/pujjo/cbi.dtsi @@ -0,0 +1,190 @@ +/* Copyright 2022 The ChromiumOS Authors + * Use of this source code is governed by a BSD-style license that can be + * found in the LICENSE file. + */ + +/ { + /* Pujjo-specific fw_config fields. */ + nissa-fw-config { + /* + * FW_CONFIG field to enable KB back light or not. + */ + kb-bl { + enum-name = "FW_KB_BL"; + start = <3>; + size = <1>; + + no-kb-bl { + compatible = "cros-ec,cbi-fw-config-value"; + enum-name = "FW_KB_BL_NOT_PRESENT"; + value = <0>; + }; + kb-bl-present { + compatible = "cros-ec,cbi-fw-config-value"; + enum-name = "FW_KB_BL_PRESENT"; + value = <1>; + }; + }; + + /* + * FW_CONFIG field for KB PWB present or not. + */ + kb-pwb { + enum-name = "FW_KB_PWB"; + start = <4>; + size = <1>; + + no-kb-pwb { + compatible = "cros-ec,cbi-fw-config-value"; + enum-name = "FW_KB_PWB_NOT_PRESENT"; + value = <0>; + }; + kb-pwb-present { + compatible = "cros-ec,cbi-fw-config-value"; + enum-name = "FW_KB_PWB_PRESENT"; + value = <1>; + }; + }; + + /* + * FW_CONFIG field for tablet present or not. + */ + tablet { + enum-name = "FW_TABLET"; + start = <5>; + size = <1>; + + no-tablet { + compatible = "cros-ec,cbi-fw-config-value"; + enum-name = "FW_TABLET_NOT_PRESENT"; + value = <0>; + }; + tablet-present { + compatible = "cros-ec,cbi-fw-config-value"; + enum-name = "FW_TABLET_PRESENT"; + value = <1>; + }; + }; + + /* + * FW_CONFIG field for LTE board present or not. + * + * start = <6>; + * size = <1>; + */ + + /* + * FW_CONFIG field for SD card present or not. + * + * start = <7>; + * size = <1>; + */ + + /* + * FW_CONFIG field for pen present or not. + */ + pen { + enum-name = "FW_PEN"; + start = <8>; + size = <1>; + + no-pen { + compatible = "cros-ec,cbi-fw-config-value"; + enum-name = "FW_PEN_NOT_PRESENT"; + value = <0>; + }; + pen-present { + compatible = "cros-ec,cbi-fw-config-value"; + enum-name = "FW_PEN_PRESENT"; + value = <1>; + }; + }; + + /* + * FW_CONFIG field for WF camera present or not. + * + * start = <9>; + * size = <1>; + */ + + /* + * FW_CONFIG field for multiple thermal table. + */ + therm-table { + enum-name = "THERM_TABLE"; + start = <10>; + size = <2>; + + therm-table-1 { + compatible = "cros-ec,cbi-fw-config-value"; + enum-name = "THERM_TABLE_1"; + value = <1>; + }; + }; + + /* + * FW_CONFIG field for multiple audio module. + * + * start = <12>; + * size = <3>; + */ + + /* + * FW_CONFIG field for EXT_VR. + * + * start = <15>; + * size = <1>; + */ + + /* + * FW_CONFIG field for multiple wi-fi SAR. + * + * start = <16>; + * size = <2>; + */ + }; + + /* Pujjo-specific ssfc fields. */ + cbi-ssfc { + compatible = "named-cbi-ssfc"; + /* + * SSFC field to identify BASE motion sensor. + */ + base-sensor { + enum-name = "BASE_SENSOR"; + size = <2>; + + base_sensor_0: bmi323 { + compatible = "named-cbi-ssfc-value"; + status = "okay"; + value = <0>; + default; + }; + base_sensor_1: lsm6dsm { + compatible = "named-cbi-ssfc-value"; + status = "okay"; + value = <1>; + }; + }; + + /* + * SSFC field to identify LID motion sensor. + */ + lid-sensor { + enum-name = "LID_SENSOR"; + size = <2>; + + lid_sensor_0: bma422 { + compatible = "named-cbi-ssfc-value"; + status = "okay"; + value = <0>; + default; + }; + lid_sensor_1: lis2dw12 { + compatible = "named-cbi-ssfc-value"; + status = "okay"; + value = <1>; + }; + }; + }; +}; diff --git a/zephyr/projects/nissa/pujjo/generated.dtsi b/zephyr/projects/nissa/pujjo/generated.dtsi new file mode 100644 index 0000000000..727d2d3d53 --- /dev/null +++ b/zephyr/projects/nissa/pujjo/generated.dtsi @@ -0,0 +1,277 @@ +/* Copyright 2022 The ChromiumOS Authors + * Use of this source code is governed by a BSD-style license that can be + * found in the LICENSE file. + * + * This file is auto-generated - do not edit! + */ + +/ { + + named-adc-channels { + compatible = "named-adc-channels"; + + adc_ec_vsense_pp1050_proc: ec_vsense_pp1050_proc { + enum-name = "ADC_PP1050_PROC"; + io-channels = <&adc0 4>; + }; + adc_ec_vsense_pp3300_s5: ec_vsense_pp3300_s5 { + enum-name = "ADC_PP3300_S5"; + io-channels = <&adc0 6>; + }; + adc_temp_sensor_1: temp_sensor_1 { + enum-name = "ADC_TEMP_SENSOR_1"; + io-channels = <&adc0 0>; + }; + adc_temp_sensor_2: temp_sensor_2 { + enum-name = "ADC_TEMP_SENSOR_2"; + io-channels = <&adc0 1>; + }; + adc_temp_sensor_3: temp_sensor_3 { + enum-name = "ADC_TEMP_SENSOR_3"; + io-channels = <&adc0 10>; + }; + }; + + named-gpios { + compatible = "named-gpios"; + + gpio_acc_int_l: acc_int_l { + gpios = <&gpio5 0 GPIO_INPUT>; + }; + gpio_all_sys_pwrgd: all_sys_pwrgd { + gpios = <&gpioa 7 GPIO_INPUT>; + }; + gpio_ccd_mode_odl: ccd_mode_odl { + gpios = <&gpioe 5 GPIO_INPUT>; + enum-name = "GPIO_CCD_MODE_ODL"; + }; + gpio_cpu_c10_gate_l: cpu_c10_gate_l { + gpios = <&gpio6 7 GPIO_INPUT>; + }; + gpio_ec_battery_pres_odl: ec_battery_pres_odl { + gpios = <&gpioa 3 GPIO_INPUT>; + enum-name = "GPIO_BATT_PRES_ODL"; + }; + gpio_ec_cbi_wp: ec_cbi_wp { + gpios = <&gpio7 4 GPIO_OUTPUT>; + }; + gpio_ec_edp_bl_en_od: ec_edp_bl_en_od { + gpios = <&gpiod 3 GPIO_ODR_HIGH>; + enum-name = "GPIO_ENABLE_BACKLIGHT"; + }; + gpio_ec_entering_rw: ec_entering_rw { + gpios = <&gpio0 3 GPIO_OUTPUT>; + enum-name = "GPIO_ENTERING_RW"; + }; + gpio_ec_gsc_packet_mode: ec_gsc_packet_mode { + gpios = <&gpio7 5 GPIO_OUTPUT>; + enum-name = "GPIO_PACKET_MODE_EN"; + }; + gpio_ec_kso_02_inv: ec_kso_02_inv { + gpios = <&gpio1 7 (GPIO_OUTPUT_LOW | GPIO_ACTIVE_LOW)>; + }; + gpio_ec_pch_wake_odl: ec_pch_wake_odl { + gpios = <&gpiob 0 GPIO_ODR_LOW>; + }; + gpio_ec_prochot_odl: ec_prochot_odl { + gpios = <&gpiof 1 GPIO_ODR_HIGH>; + }; + gpio_ec_soc_dsw_pwrok: ec_soc_dsw_pwrok { + gpios = <&gpio6 1 GPIO_OUTPUT>; + }; + gpio_ec_soc_hdmi_hpd: ec_soc_hdmi_hpd { + gpios = <&gpioe 4 GPIO_OUTPUT>; + }; + gpio_ec_soc_int_odl: ec_soc_int_odl { + gpios = <&gpio8 0 GPIO_ODR_HIGH>; + enum-name = "GPIO_EC_INT_L"; + }; + gpio_ec_soc_pch_pwrok_od: ec_soc_pch_pwrok_od { + gpios = <&gpio7 2 GPIO_ODR_HIGH>; + }; + gpio_ec_soc_pwr_btn_odl: ec_soc_pwr_btn_odl { + gpios = <&gpioc 1 GPIO_ODR_HIGH>; + enum-name = "GPIO_PCH_PWRBTN_L"; + }; + gpio_ec_soc_rsmrst_l: ec_soc_rsmrst_l { + gpios = <&gpioa 6 GPIO_OUTPUT>; + }; + gpio_ec_soc_rtcrst: ec_soc_rtcrst { + gpios = <&gpio7 6 GPIO_OUTPUT>; + }; + gpio_ec_soc_sys_pwrok: ec_soc_sys_pwrok { + gpios = <&gpio3 7 GPIO_OUTPUT>; + }; + gpio_ec_soc_vccst_pwrgd_od: ec_soc_vccst_pwrgd_od { + gpios = <&gpioa 4 GPIO_ODR_HIGH>; + }; + gpio_ec_wp_odl: ec_wp_odl { + gpios = <&gpioa 1 (GPIO_INPUT | GPIO_ACTIVE_LOW)>; + }; + gpio_en_kb_bl: en_kb_bl { + gpios = <&gpioa 0 GPIO_OUTPUT>; + enum-name = "GPIO_EN_KEYBOARD_BACKLIGHT"; + }; + gpio_en_pp3300_s5: en_pp3300_s5 { + gpios = <&gpiob 6 GPIO_OUTPUT>; + enum-name = "GPIO_TEMP_SENSOR_POWER"; + }; + gpio_en_pp5000_pen_x: en_pp5000_pen_x { + gpios = <&gpioe 2 GPIO_OUTPUT>; + }; + gpio_en_pp5000_s5: en_pp5000_s5 { + gpios = <&gpio4 0 GPIO_OUTPUT>; + }; + gpio_en_slp_z: en_slp_z { + gpios = <&gpioe 1 GPIO_OUTPUT>; + }; + gpio_en_usb_a0_vbus: en_usb_a0_vbus { + gpios = <&gpio9 1 GPIO_OUTPUT>; + }; + gpio_gsc_ec_pwr_btn_odl: gsc_ec_pwr_btn_odl { + gpios = <&gpio0 0 GPIO_INPUT_PULL_UP>; + enum-name = "GPIO_POWER_BUTTON_L"; + }; + gpio_hdmi_sel: hdmi_sel { + gpios = <&gpioc 6 GPIO_OUTPUT>; + }; + gpio_imu_int_l: imu_int_l { + gpios = <&gpio5 6 GPIO_INPUT>; + }; + gpio_imvp91_vrrdy_od: imvp91_vrrdy_od { + gpios = <&gpio4 3 GPIO_INPUT>; + }; + gpio_lid_open: lid_open { + gpios = <&gpiod 2 GPIO_INPUT>; + enum-name = "GPIO_LID_OPEN"; + }; + gpio_pen_detect_odl: pen_detect_odl { + gpios = <&gpio9 6 GPIO_INPUT_PULL_UP>; + }; + gpio_pg_pp1050_mem_s3_od: pg_pp1050_mem_s3_od { + gpios = <&gpiof 0 GPIO_INPUT>; + }; + gpio_pg_pp5000_s5_od: pg_pp5000_s5_od { + gpios = <&gpio4 2 GPIO_INPUT>; + }; + gpio_rsmrst_pwrgd_l: rsmrst_pwrgd_l { + gpios = <&gpio9 4 GPIO_INPUT_PULL_UP>; + }; + gpio_slp_s0_l: slp_s0_l { + gpios = <&gpio9 7 GPIO_INPUT>; + }; + gpio_slp_s3_l: slp_s3_l { + gpios = <&gpioa 5 GPIO_INPUT>; + }; + gpio_slp_s4_l: slp_s4_l { + gpios = <&gpio7 0 GPIO_INPUT>; + }; + gpio_slp_sus_l: slp_sus_l { + gpios = <&gpio6 2 GPIO_INPUT>; + }; + gpio_sub_usb_a1_ilimit_sdp: sub_usb_a1_ilimit_sdp { + gpios = <&gpiod 5 GPIO_OUTPUT>; + enum-name = "GPIO_USB2_ILIM_SEL"; + }; + gpio_sys_rst_odl: sys_rst_odl { + gpios = <&gpioc 5 GPIO_ODR_HIGH>; + }; + gpio_tablet_mode_l: tablet_mode_l { + gpios = <&gpio9 5 GPIO_INPUT>; + enum-name = "GPIO_TABLET_MODE_L"; + }; + gpio_usb_a0_ilimit_sdp: usb_a0_ilimit_sdp { + gpios = <&gpio8 5 GPIO_OUTPUT>; + enum-name = "GPIO_USB1_ILIM_SEL"; + }; + gpio_usb_c0_int_odl: usb_c0_int_odl { + gpios = <&gpio0 1 GPIO_INPUT_PULL_UP>; + }; + gpio_vccin_aux_vid0: vccin_aux_vid0 { + gpios = <&gpio9 2 GPIO_INPUT>; + }; + gpio_vccin_aux_vid1: vccin_aux_vid1 { + gpios = <&gpioe 3 GPIO_INPUT>; + }; + gpio_voldn_btn_odl: voldn_btn_odl { + gpios = <&gpio9 3 GPIO_INPUT_PULL_UP>; + enum-name = "GPIO_VOLUME_DOWN_L"; + }; + gpio_volup_btn_odl: volup_btn_odl { + gpios = <&gpioa 2 GPIO_INPUT_PULL_UP>; + enum-name = "GPIO_VOLUME_UP_L"; + }; + }; + + named-i2c-ports { + compatible = "named-i2c-ports"; + + i2c_ec_i2c_eeprom: ec_i2c_eeprom { + i2c-port = <&i2c0_0>; + enum-names = "I2C_PORT_EEPROM"; + }; + i2c_ec_i2c_sensor: ec_i2c_sensor { + i2c-port = <&i2c1_0>; + enum-names = "I2C_PORT_SENSOR"; + }; + i2c_ec_i2c_usb_c0: ec_i2c_usb_c0 { + i2c-port = <&i2c3_0>; + enum-names = "I2C_PORT_USB_C0_TCPC"; + }; + i2c_ec_i2c_batt: ec_i2c_batt { + i2c-port = <&i2c7_0>; + enum-names = "I2C_PORT_BATTERY"; + }; + }; +}; + +&adc0 { + status = "okay"; + pinctrl-0 = <&adc0_chan0_gp45 + &adc0_chan1_gp44 + &adc0_chan4_gp41 + &adc0_chan6_gp34 + &adc0_chan10_gpe0>; + pinctrl-names = "default"; +}; + + +&i2c0_0 { + status = "okay"; + pinctrl-0 = <&i2c0_0_sda_scl_gpb4_b5>; + pinctrl-names = "default"; +}; + +&i2c1_0 { + status = "okay"; + pinctrl-0 = <&i2c1_0_sda_scl_gp87_90>; + pinctrl-names = "default"; +}; + +&i2c3_0 { + status = "okay"; + pinctrl-0 = <&i2c3_0_sda_scl_gpd0_d1>; + pinctrl-names = "default"; +}; + +&i2c7_0 { + status = "okay"; + pinctrl-0 = <&i2c7_0_sda_scl_gpb2_b3>; + pinctrl-names = "default"; +}; + +&i2c_ctrl0 { + status = "okay"; +}; + +&i2c_ctrl1 { + status = "okay"; +}; + +&i2c_ctrl3 { + status = "okay"; +}; + +&i2c_ctrl7 { + status = "okay"; +}; diff --git a/zephyr/projects/nissa/pujjo/keyboard.dtsi b/zephyr/projects/nissa/pujjo/keyboard.dtsi new file mode 100644 index 0000000000..00610e4e18 --- /dev/null +++ b/zephyr/projects/nissa/pujjo/keyboard.dtsi @@ -0,0 +1,48 @@ +/* Copyright 2022 The ChromiumOS Authors + * Use of this source code is governed by a BSD-style license that can be + * found in the LICENSE file. + */ + +/ { + kblight { + compatible = "cros-ec,kblight-pwm"; + pwms = <&pwm6 6 PWM_HZ(2400) PWM_POLARITY_NORMAL>; + }; +}; + +&pwm6 { + status = "okay"; + clock-bus = "NPCX_CLOCK_BUS_LFCLK"; + pinctrl-0 = <&pwm6_gpc0>; + pinctrl-names = "default"; +}; + +&cros_kb_raw { + status = "okay"; + /* No KSO2 (it's inverted and implemented by GPIO) */ + pinctrl-0 = < + &ksi0_gp31 + &ksi1_gp30 + &ksi2_gp27 + &ksi3_gp26 + &ksi4_gp25 + &ksi5_gp24 + &ksi6_gp23 + &ksi7_gp22 + &kso00_gp21 + &kso01_gp20 + &kso03_gp16 + &kso04_gp15 + &kso05_gp14 + &kso06_gp13 + &kso07_gp12 + &kso08_gp11 + &kso09_gp10 + &kso10_gp07 + &kso11_gp06 + &kso12_gp05 + &kso13_gp04 + &kso14_gp82 + >; + pinctrl-names = "default"; +}; diff --git a/zephyr/projects/nissa/pujjo/motionsense.dtsi b/zephyr/projects/nissa/pujjo/motionsense.dtsi new file mode 100644 index 0000000000..2dfca337c4 --- /dev/null +++ b/zephyr/projects/nissa/pujjo/motionsense.dtsi @@ -0,0 +1,245 @@ +/* Copyright 2022 The ChromiumOS Authors + * Use of this source code is governed by a BSD-style license that can be + * found in the LICENSE file. + */ + +#include <dt-bindings/motionsense/utils.h> + + +/ { + aliases { + /* + * Interrupt bindings for sensor devices. + */ + bmi3xx-int = &base_accel; + lsm6dsm-int = &base_accel; + lis2dw12-int = &lid_accel; + }; + + /* + * Declare mutexes used by sensor drivers. + * A mutex node is used to create an instance of mutex_t. + * A mutex node is referenced by a sensor node if the + * corresponding sensor driver needs to use the + * instance of the mutex. + */ + motionsense-mutex { + compatible = "cros-ec,motionsense-mutex"; + lid_mutex: lid-mutex { + }; + + base_mutex: base-mutex { + }; + }; + + /* Rotation matrix used by drivers. */ + motionsense-rotation-ref { + compatible = "cros-ec,motionsense-rotation-ref"; + lid_rot_ref: lid-rotation-ref { + mat33 = <0 (-1) 0 + (-1) 0 0 + 0 0 (-1)>; + }; + + lid_rot_lis2dw12: lid-rotation-lis2dw12 { + mat33 = <0 (-1) 0 + (-1) 0 0 + 0 0 (-1)>; + }; + + base_rot_ref: base-rotation-ref { + mat33 = <0 1 0 + (-1) 0 0 + 0 0 1>; + }; + + base_rot_lsm6dsm: base-rotation-lsm6dsm { + mat33 = <1 0 0 + 0 1 0 + 0 0 1>; + }; + }; + + /* + * Driver specific data. A driver-specific data can be shared with + * different motion sensors while they are using the same driver. + * + * If a node's compatible starts with "cros-ec,accelgyro-", it is for + * a common structure defined in accelgyro.h. + * e.g) compatible = "cros-ec,accelgyro-als-drv-data" is for + * "struct als_drv_data_t" in accelgyro.h + */ + motionsense-sensor-data { + bmi323_data: bmi323-drv-data { + compatible = "cros-ec,drvdata-bmi3xx"; + status = "okay"; + }; + + lsm6dsm_data_accel: lsm6dsm-accel-drv-data { + compatible = "cros-ec,drvdata-lsm6dsm"; + status = "okay"; + }; + + lsm6dsm_data_gyro: lsm6dsm-gyro-drv-data { + compatible = "cros-ec,drvdata-lsm6dsm"; + status = "okay"; + }; + + bma422_data: bma422-drv-data { + compatible = "cros-ec,drvdata-bma4xx"; + status = "okay"; + }; + + lis2dw12_data: lis2dw12-drv-data { + compatible = "cros-ec,drvdata-lis2dw12"; + status = "okay"; + }; + }; + + /* + * List of motion sensors that creates motion_sensors array. + * The nodelabel "lid_accel" and "base_accel" are used to indicate + * motion sensor IDs for lid angle calculation. + * TODO(b/238139272): The first entries of the array must be + * accelerometers,then gyroscope. Fix this dependency in the DTS + * processing which makes the devicetree entries independent. + */ + motionsense-sensor { + lid_accel: lid-accel { + compatible = "cros-ec,bma4xx"; + status = "okay"; + + active-mask = "SENSOR_ACTIVE_S0_S3"; + location = "MOTIONSENSE_LOC_LID"; + mutex = <&lid_mutex>; + port = <&i2c_ec_i2c_sensor>; + rot-standard-ref = <&lid_rot_ref>; + default-range = <2>; + drv-data = <&bma422_data>; + configs { + compatible = + "cros-ec,motionsense-sensor-config"; + ec-s0 { + odr = <(10000 | ROUND_UP_FLAG)>; + }; + ec-s3 { + odr = <(10000 | ROUND_UP_FLAG)>; + }; + }; + }; + + base_accel: base-accel { + compatible = "cros-ec,bmi3xx-accel"; + status = "okay"; + + active-mask = "SENSOR_ACTIVE_S0_S3"; + location = "MOTIONSENSE_LOC_BASE"; + mutex = <&base_mutex>; + port = <&i2c_ec_i2c_sensor>; + rot-standard-ref = <&base_rot_ref>; + drv-data = <&bmi323_data>; + configs { + compatible = + "cros-ec,motionsense-sensor-config"; + ec-s0 { + odr = <(10000 | ROUND_UP_FLAG)>; + }; + ec-s3 { + odr = <(10000 | ROUND_UP_FLAG)>; + }; + }; + }; + + base_gyro: base-gyro { + compatible = "cros-ec,bmi3xx-gyro"; + status = "okay"; + + active-mask = "SENSOR_ACTIVE_S0_S3"; + location = "MOTIONSENSE_LOC_BASE"; + mutex = <&base_mutex>; + port = <&i2c_ec_i2c_sensor>; + rot-standard-ref = <&base_rot_ref>; + drv-data = <&bmi323_data>; + }; + }; + + motionsense-sensor-alt { + alt_lid_accel: alt-lid-accel { + compatible = "cros-ec,lis2dw12"; + status = "okay"; + + active-mask = "SENSOR_ACTIVE_S0_S3"; + location = "MOTIONSENSE_LOC_LID"; + mutex = <&lid_mutex>; + port = <&i2c_ec_i2c_sensor>; + rot-standard-ref = <&lid_rot_lis2dw12>; + default-range = <2>; + drv-data = <&lis2dw12_data>; + i2c-spi-addr-flags = "LIS2DWL_ADDR1_FLAGS"; + alternate-for = <&lid_accel>; + alternate-ssfc-indicator = <&lid_sensor_1>; + configs { + compatible = + "cros-ec,motionsense-sensor-config"; + ec-s0 { + odr = <(10000 | ROUND_UP_FLAG)>; + }; + ec-s3 { + odr = <(10000 | ROUND_UP_FLAG)>; + }; + }; + }; + + alt_base_accel: alt-base-accel { + compatible = "cros-ec,lsm6dsm-accel"; + status = "okay"; + + active-mask = "SENSOR_ACTIVE_S0_S3"; + location = "MOTIONSENSE_LOC_BASE"; + mutex = <&base_mutex>; + port = <&i2c_ec_i2c_sensor>; + rot-standard-ref = <&base_rot_lsm6dsm>; + drv-data = <&lsm6dsm_data_accel>; + alternate-for = <&base_accel>; + alternate-ssfc-indicator = <&base_sensor_1>; + configs { + compatible = + "cros-ec,motionsense-sensor-config"; + ec-s0 { + odr = <(10000 | ROUND_UP_FLAG)>; + ec-rate = <(100 * USEC_PER_MSEC)>; + }; + ec-s3 { + odr = <(10000 | ROUND_UP_FLAG)>; + ec-rate = <0>; + }; + }; + }; + + alt_base_gyro: alt-base-gyro { + compatible = "cros-ec,lsm6dsm-gyro"; + status = "okay"; + + active-mask = "SENSOR_ACTIVE_S0_S3"; + location = "MOTIONSENSE_LOC_BASE"; + mutex = <&base_mutex>; + port = <&i2c_ec_i2c_sensor>; + rot-standard-ref = <&base_rot_lsm6dsm>; + drv-data = <&lsm6dsm_data_gyro>; + alternate-for = <&base_gyro>; + alternate-ssfc-indicator = <&base_sensor_1>; + }; + }; + + motionsense-sensor-info { + compatible = "cros-ec,motionsense-sensor-info"; + + /* + * list of GPIO interrupts that have to + * be enabled at initial stage + */ + sensor-irqs = <&int_imu>; + /* list of sensors in force mode */ + accel-force-mode-sensors = <&lid_accel>; + }; +}; diff --git a/zephyr/projects/nissa/pujjo/overlay.dtsi b/zephyr/projects/nissa/pujjo/overlay.dtsi new file mode 100644 index 0000000000..60b3b60003 --- /dev/null +++ b/zephyr/projects/nissa/pujjo/overlay.dtsi @@ -0,0 +1,350 @@ +/* Copyright 2022 The ChromiumOS Authors + * Use of this source code is governed by a BSD-style license that can be + * found in the LICENSE file. + */ + +#include <cros/thermistor/thermistor.dtsi> + +/ { + aliases { + gpio-cbi-wp = &gpio_ec_cbi_wp; + gpio-wp = &gpio_ec_wp_odl; + int-wp = &int_wp_l; + gpio-kbd-kso2 = &gpio_ec_kso_02_inv; + }; + + ec-console { + compatible = "ec-console"; + disabled = "events", "lpc", "hostcmd"; + }; + + batteries { + default_battery: smp { + compatible = "smp,l22m3pg0", "battery-smart"; + }; + smp_l22m3pg1 { + compatible = "smp,l22m3pg1", "battery-smart"; + }; + sunwoda_l22d3pg0 { + compatible = "sunwoda,l22d3pg0", "battery-smart"; + }; + sunwoda_l22d3pg1 { + compatible = "sunwoda,l22d3pg1", "battery-smart"; + }; + celxpert_l22c3pg0 { + compatible = "celxpert,l22c3pg0", "battery-smart"; + }; + }; + + hibernate-wake-pins { + compatible = "cros-ec,hibernate-wake-pins"; + wakeup-irqs = < + &int_power_button + &int_lid_open + >; + }; + + gpio-interrupts { + compatible = "cros-ec,gpio-interrupts"; + + int_power_button: power_button { + irq-pin = <&gpio_gsc_ec_pwr_btn_odl>; + flags = <GPIO_INT_EDGE_BOTH>; + handler = "power_button_interrupt"; + }; + int_wp_l: wp_l { + irq-pin = <&gpio_ec_wp_odl>; + flags = <GPIO_INT_EDGE_BOTH>; + handler = "switch_interrupt"; + }; + int_lid_open: lid_open { + irq-pin = <&gpio_lid_open>; + flags = <GPIO_INT_EDGE_BOTH>; + handler = "lid_interrupt"; + }; + int_tablet_mode: tablet_mode { + irq-pin = <&gpio_tablet_mode_l>; + flags = <GPIO_INT_EDGE_BOTH>; + handler = "gmr_tablet_switch_isr"; + }; + int_imu: ec_imu { + irq-pin = <&gpio_imu_int_l>; + flags = <GPIO_INT_EDGE_FALLING>; + handler = "motion_interrupt"; + }; + int_vol_down: vol_down { + irq-pin = <&gpio_voldn_btn_odl>; + flags = <GPIO_INT_EDGE_BOTH>; + handler = "button_interrupt"; + }; + int_vol_up: vol_up { + irq-pin = <&gpio_volup_btn_odl>; + flags = <GPIO_INT_EDGE_BOTH>; + handler = "button_interrupt"; + }; + int_usb_c0: usb_c0 { + irq-pin = <&gpio_usb_c0_int_odl>; + flags = <GPIO_INT_EDGE_FALLING>; + handler = "usb_interrupt"; + }; + }; + + named-gpios { + gpio_sb_2: sb_2 { + gpios = <&gpiod 4 GPIO_OUTPUT>; + no-auto-init; + }; + + gpio_sb_3: sb_3 { + gpios = <&gpiof 5 GPIO_OPEN_DRAIN>; + no-auto-init; + }; + gpio_sb_4: sb_4 { + gpios = <&gpiof 4 GPIO_INPUT>; + no-auto-init; + }; + gpio_fan_enable: fan-enable { + gpios = <&gpio6 3 GPIO_OUTPUT>; + no-auto-init; + }; + gpio_power_led: power_led { + gpios = <&gpioc 2 GPIO_OUTPUT_LOW>; + }; + gpio_led_1_odl: led_1_odl { + gpios = <&gpioc 4 GPIO_OUTPUT_LOW>; + }; + gpio_led_2_odl: led_2_odl { + gpios = <&gpioc 3 GPIO_OUTPUT_LOW>; + }; + }; + + /* + * Aliases used for sub-board GPIOs. + */ + aliases { + /* + * Sub-board with type A USB, enable. + */ + gpio-en-usb-a1-vbus = &gpio_sb_2; + /* + * HPD pins for HDMI sub-board. + */ + gpio-hdmi-en-odl = &gpio_sb_3; + gpio-hpd-odl = &gpio_sb_4; + /* + * Enable S5 rails for LTE sub-board + */ + gpio-en-sub-s5-rails = &gpio_sb_2; + }; + + temp_cpu: cpu { + compatible = "cros-ec,temp-sensor-thermistor"; + thermistor = <&thermistor_3V3_51K1_47K_4050B>; + adc = <&adc_temp_sensor_1>; + }; + temp_ddr: ddr { + compatible = "cros-ec,temp-sensor-thermistor"; + thermistor = <&thermistor_3V3_51K1_47K_4050B>; + adc = <&adc_temp_sensor_2>; + }; + temp_ambient: ambient { + compatible = "cros-ec,temp-sensor-thermistor"; + thermistor = <&thermistor_3V3_51K1_47K_4050B>; + adc = <&adc_temp_sensor_3>; + }; + + named-temp-sensors { + compatible = "cros-ec,temp-sensors"; + cpu { + temp_fan_off = <35>; + temp_fan_max = <60>; + temp_host_high = <90>; + temp_host_halt = <100>; + temp_host_release_high = <85>; + power-good-pin = <&gpio_ec_soc_dsw_pwrok>; + sensor = <&temp_cpu>; + }; + ddr { + temp_fan_off = <35>; + temp_fan_max = <60>; + temp_host_high = <90>; + temp_host_halt = <100>; + temp_host_release_high = <85>; + power-good-pin = <&gpio_ec_soc_dsw_pwrok>; + sensor = <&temp_ddr>; + }; + ambient { + temp_fan_off = <35>; + temp_fan_max = <60>; + temp_host_high = <90>; + temp_host_halt = <100>; + temp_host_release_high = <85>; + power-good-pin = <&gpio_ec_soc_dsw_pwrok>; + sensor = <&temp_ambient>; + }; + }; + + usba { + compatible = "cros-ec,usba-port-enable-pins"; + /* + * sb_2 is only configured as GPIO when USB-A1 is present, + * but it's still safe to control when disabled. + * + * ILIM_SEL pins are referred to by legacy enum name, + * GPIO_USB*_ILIM_SEL. The one for port A1 is unused on + * sub-boards that don't have USB-A so is safe to control + * regardless of system configuration. + */ + enable-pins = <&gpio_en_usb_a0_vbus &gpio_sb_2>; + status = "okay"; + }; + + usbc { + #address-cells = <1>; + #size-cells = <0>; + + port0@0 { + compatible = "named-usbc-port"; + reg = <0>; + bc12 = <&bc12_port0>; + chg = <&chg_port0>; + usb-mux-chain-0 { + compatible = "cros-ec,usb-mux-chain"; + usb-muxes = <&virtual_mux_0>; + }; + }; + port0-muxes { + virtual_mux_0: virtual-mux-0 { + compatible = "cros-ec,usbc-mux-virtual"; + }; + }; + }; + + fans { + compatible = "cros-ec,fans"; + + fan_0 { + pwms = <&pwm5 5 PWM_KHZ(1) PWM_POLARITY_NORMAL>; + rpm_min = <2200>; + rpm_start = <2200>; + rpm_max = <4200>; + tach = <&tach2>; + enable_gpio = <&gpio_fan_enable>; + }; + }; + + /* + * Declare unused GPIOs so that they are shut down + * and use minimal power + */ + unused-pins { + compatible = "unused-gpios"; + unused-gpios = + <&gpio3 3 0>, + <&gpio3 6 0>, + <&gpiod 7 0>, + <&gpiof 2 0>, + <&gpiof 3 0>; + }; +}; + +&thermistor_3V3_51K1_47K_4050B { + status = "okay"; +}; + +&adc_ec_vsense_pp3300_s5 { + /* + * Voltage divider on input has 47k upper and 220k lower legs with + * 2714 mV full-scale reading on the ADC. Apply the largest possible + * multiplier (without overflowing int32) to get the best possible + * approximation of the actual ratio, but derate by a factor of two to + * ensure unexpectedly high values won't overflow. + */ + mul = <(791261 / 2)>; + div = <(651975 / 2)>; +}; + +/* Set bus speeds for I2C */ +&i2c0_0 { + label = "I2C_EEPROM"; + clock-frequency = <I2C_BITRATE_FAST>; + + cbi_eeprom: eeprom@50 { + compatible = "atmel,at24"; + reg = <0x50>; + size = <2048>; + pagesize = <16>; + address-width = <8>; + timeout = <5>; + }; +}; + +&i2c1_0 { + label = "I2C_SENSOR"; + clock-frequency = <I2C_BITRATE_FAST>; +}; + +&i2c3_0 { + label = "I2C_USB_C0_TCPC"; + clock-frequency = <I2C_BITRATE_FAST_PLUS>; + + bc12_port0: pi3usb9201@5f { + compatible = "pericom,pi3usb9201"; + status = "okay"; + reg = <0x5f>; + /* + * BC1.2 interrupt is shared with TCPC, so + * IRQ is not specified here and handled by + * usb_c0_interrupt. + */ + }; + + chg_port0: isl923x@9 { + compatible = "intersil,isl923x"; + status = "okay"; + reg = <0x9>; + }; +}; + +&i2c7_0 { + label = "I2C_BATTERY"; + clock-frequency = <I2C_BITRATE_STANDARD>; +}; + +&pwm5_gpb7 { + drive-open-drain; +}; + +&pwm5 { + status = "okay"; + clock-bus = "NPCX_CLOCK_BUS_LFCLK"; + pinctrl-0 = <&pwm5_gpb7>; + pinctrl-names = "default"; +}; + +/* Tachometer for fan speed measurement */ +&tach2 { + status = "okay"; + pinctrl-0 = <&ta2_1_in_gp73>; + pinctrl-names = "default"; + port = <NPCX_TACH_PORT_A>; /* port-A is selected */ + sample-clk = <NPCX_TACH_FREQ_LFCLK>; /* Use LFCLK as sampling clock */ + pulses-per-round = <2>; /* number of pulses per round of encoder */ +}; + +/* host interface */ +&espi0 { + status = "okay"; + pinctrl-0 = <&espi_lpc_gp46_47_51_52_53_54_55_57>; + pinctrl-names = "default"; +}; + +/* + * Declare GPIOs that have leakage current caused by board issues here. NPCX ec + * will disable their input buffers before entering deep sleep and restore them + * after waking up automatically for better power consumption. + */ +&power_leakage_io { + leak-gpios = <&gpioa 4 0 + &gpiof 1 0>; +}; diff --git a/zephyr/projects/nissa/pujjo/power_signals.dtsi b/zephyr/projects/nissa/pujjo/power_signals.dtsi new file mode 100644 index 0000000000..1d2b23069d --- /dev/null +++ b/zephyr/projects/nissa/pujjo/power_signals.dtsi @@ -0,0 +1,220 @@ +/* Copyright 2022 The ChromiumOS Authors + * Use of this source code is governed by a BSD-style license that can be + * found in the LICENSE file. + */ + +/ { + chosen { + intel-ap-pwrseq,espi = &espi0; + }; + + common-pwrseq { + compatible = "intel,ap-pwrseq"; + + sys-pwrok-delay = <10>; + all-sys-pwrgd-timeout = <20>; + }; + + pwr-en-pp5000-s5 { + compatible = "intel,ap-pwrseq-gpio"; + dbg-label = "PP5000_S5 enable output to regulator"; + enum-name = "PWR_EN_PP5000_A"; + gpios = <&gpio4 0 0>; + output; + }; + pwr-en-pp3300-s5 { + compatible = "intel,ap-pwrseq-gpio"; + dbg-label = "PP3300_S5 enable output to LS"; + enum-name = "PWR_EN_PP3300_A"; + gpios = <&gpiob 6 0>; + output; + }; + pwr-pg-ec-rsmrst-od { + compatible = "intel,ap-pwrseq-gpio"; + dbg-label = "RSMRST power good from regulator"; + enum-name = "PWR_RSMRST"; + gpios = <&gpio9 4 0>; + interrupt-flags = <GPIO_INT_EDGE_BOTH>; + }; + pwr-ec-pch-rsmrst-odl { + compatible = "intel,ap-pwrseq-gpio"; + dbg-label = "RSMRST output to PCH"; + enum-name = "PWR_EC_PCH_RSMRST"; + gpios = <&gpioa 6 0>; + output; + }; + pwr-slp-s0-l { + compatible = "intel,ap-pwrseq-gpio"; + dbg-label = "SLP_S0_L input from PCH"; + enum-name = "PWR_SLP_S0"; + gpios = <&gpio9 7 GPIO_ACTIVE_LOW>; + interrupt-flags = <GPIO_INT_EDGE_BOTH>; + }; + pwr-slp-s3-l { + compatible = "intel,ap-pwrseq-gpio"; + dbg-label = "SLP_S3_L input from PCH"; + enum-name = "PWR_SLP_S3"; + gpios = <&gpioa 5 GPIO_ACTIVE_LOW>; + interrupt-flags = <GPIO_INT_EDGE_BOTH>; + }; + pwr-slp-sus-l { + compatible = "intel,ap-pwrseq-gpio"; + dbg-label = "SLP_SUS_L input from PCH"; + enum-name = "PWR_SLP_SUS"; + gpios = <&gpio6 2 GPIO_ACTIVE_LOW>; + interrupt-flags = <GPIO_INT_EDGE_BOTH>; + }; + pwr-ec-soc-dsw-pwrok { + compatible = "intel,ap-pwrseq-gpio"; + dbg-label = "DSW_PWROK output to PCH"; + enum-name = "PWR_EC_SOC_DSW_PWROK"; + gpios = <&gpio6 1 0>; + output; + }; + pwr-vccst-pwrgd-od { + compatible = "intel,ap-pwrseq-gpio"; + dbg-label = "VCCST_PWRGD output to PCH"; + enum-name = "PWR_VCCST_PWRGD"; + gpios = <&gpioa 4 GPIO_OPEN_DRAIN>; + output; + }; + pwr-imvp9-vrrdy-od { + compatible = "intel,ap-pwrseq-gpio"; + dbg-label = "VRRDY input from IMVP9"; + enum-name = "PWR_IMVP9_VRRDY"; + gpios = <&gpio4 3 0>; + }; + pwr-pch-pwrok { + compatible = "intel,ap-pwrseq-gpio"; + dbg-label = "PCH_PWROK output to PCH"; + enum-name = "PWR_PCH_PWROK"; + gpios = <&gpio7 2 GPIO_OPEN_DRAIN>; + output; + }; + pwr-ec-pch-sys-pwrok { + compatible = "intel,ap-pwrseq-gpio"; + dbg-label = "SYS_PWROK output to PCH"; + enum-name = "PWR_EC_PCH_SYS_PWROK"; + gpios = <&gpio3 7 0>; + output; + }; + pwr-sys-rst-l { + compatible = "intel,ap-pwrseq-gpio"; + dbg-label = "SYS_RESET# output to PCH"; + enum-name = "PWR_SYS_RST"; + gpios = <&gpioc 5 (GPIO_ACTIVE_LOW|GPIO_OPEN_DRAIN)>; + output; + }; + pwr-slp-s4 { + compatible = "intel,ap-pwrseq-vw"; + dbg-label = "SLP_S4 virtual wire input from PCH"; + enum-name = "PWR_SLP_S4"; + virtual-wire = "ESPI_VWIRE_SIGNAL_SLP_S4"; + vw-invert; + }; + pwr-slp-s5 { + compatible = "intel,ap-pwrseq-vw"; + dbg-label = "SLP_S5 virtual wire input from PCH"; + enum-name = "PWR_SLP_S5"; + virtual-wire = "ESPI_VWIRE_SIGNAL_SLP_S5"; + vw-invert; + }; + pwr-all-sys-pwrgd { + compatible = "intel,ap-pwrseq-external"; + dbg-label = "Combined all power good"; + enum-name = "PWR_ALL_SYS_PWRGD"; + }; + pwr-adc-pp3300 { + compatible = "intel,ap-pwrseq-adc"; + dbg-label = "PP3300 PWROK (from ADC)"; + enum-name = "PWR_DSW_PWROK"; + trigger-high = <&cmp_pp3300_s5_high>; + trigger-low = <&cmp_pp3300_s5_low>; + }; + pwr-adc-pp1p05 { + compatible = "intel,ap-pwrseq-adc"; + dbg-label = "PP1P05 PWROK (from ADC)"; + enum-name = "PWR_PG_PP1P05"; + trigger-high = <&cmp_pp1p05_high>; + trigger-low = <&cmp_pp1p05_low>; + }; + + adc-cmp { + cmp_pp3300_s5_high: pp3300_high { + compatible = "nuvoton,adc-cmp"; + io-channels = <&adc0 6>; + comparison = "ADC_CMP_NPCX_GREATER"; + /* + * This is 90% of nominal voltage considering voltage + * divider on ADC input. + */ + threshold-mv = <2448>; + }; + cmp_pp3300_s5_low: pp3300_low { + compatible = "nuvoton,adc-cmp"; + io-channels = <&adc0 6>; + comparison = "ADC_CMP_NPCX_LESS_OR_EQUAL"; + threshold-mv = <2448>; + }; + cmp_pp1p05_high: pp1p05_high { + compatible = "nuvoton,adc-cmp"; + io-channels = <&adc0 4>; + comparison = "ADC_CMP_NPCX_GREATER"; + /* Setting at 90% of nominal voltage */ + threshold-mv = <945>; + }; + cmp_pp1p05_low: pp1p05_low { + compatible = "nuvoton,adc-cmp"; + io-channels = <&adc0 4>; + comparison = "ADC_CMP_NPCX_LESS_OR_EQUAL"; + threshold-mv = <945>; + }; + }; +}; + +/* + * Because the power signals directly reference the GPIOs, + * the correspinding named-gpios need to have no-auto-init set. + */ +&gpio_ec_soc_dsw_pwrok { + no-auto-init; +}; +&gpio_ec_soc_pch_pwrok_od { + no-auto-init; +}; +&gpio_ec_soc_rsmrst_l { + no-auto-init; +}; +&gpio_ec_soc_sys_pwrok { + no-auto-init; +}; +&gpio_ec_soc_vccst_pwrgd_od { + no-auto-init; +}; +&gpio_en_pp3300_s5 { + no-auto-init; +}; +&gpio_en_pp5000_s5 { + no-auto-init; +}; +&gpio_imvp91_vrrdy_od { + no-auto-init; +}; +&gpio_rsmrst_pwrgd_l { + no-auto-init; +}; +&gpio_slp_s0_l { + no-auto-init; +}; +&gpio_slp_s3_l { + no-auto-init; +}; +&gpio_slp_s4_l { + no-auto-init; +}; +&gpio_slp_sus_l { + no-auto-init; +}; +&gpio_sys_rst_odl { + no-auto-init; +}; diff --git a/zephyr/projects/nissa/pujjo/project.conf b/zephyr/projects/nissa/pujjo/project.conf new file mode 100644 index 0000000000..b9dc28b9cd --- /dev/null +++ b/zephyr/projects/nissa/pujjo/project.conf @@ -0,0 +1,33 @@ +# Copyright 2022 The ChromiumOS Authors +# Use of this source code is governed by a BSD-style license that can be +# found in the LICENSE file. + +CONFIG_BOARD_PUJJO=y + +# Sensor drivers +CONFIG_PLATFORM_EC_ACCELGYRO_LSM6DSM=y +CONFIG_PLATFORM_EC_ACCEL_BMA4XX=y +CONFIG_PLATFORM_EC_ACCELGYRO_BMI_COMM_I2C=y +CONFIG_PLATFORM_EC_ACCELGYRO_BMI3XX=y +CONFIG_PLATFORM_EC_DYNAMIC_MOTION_SENSOR_COUNT=y + +# Increase PD max power from default +CONFIG_PLATFORM_EC_PD_MAX_POWER_MW=65000 +CONFIG_PLATFORM_EC_PD_MAX_CURRENT_MA=3250 + +# LED +CONFIG_PLATFORM_EC_LED_PWM=n +CONFIG_PLATFORM_EC_LED_COMMON=y + +# CBI +CONFIG_PLATFORM_EC_BYPASS_CBI_EEPROM_WP_CHECK=y +CONFIG_PLATFORM_EC_SYSTEM_UNLOCKED=y + +# DPS +CONFIG_PLATFORM_EC_USB_PD_DPS=n + +# BTN +CONFIG_PLATFORM_EC_BUTTONS_RUNTIME_CONFIG=y + +# Charger +CONFIG_PLATFORM_EC_RAA489000_TRICKLE_CHARGE_CURRENT_256MA=y
\ No newline at end of file diff --git a/zephyr/projects/nissa/pujjo/project.overlay b/zephyr/projects/nissa/pujjo/project.overlay new file mode 100644 index 0000000000..e498775714 --- /dev/null +++ b/zephyr/projects/nissa/pujjo/project.overlay @@ -0,0 +1,13 @@ +/* Copyright 2022 The ChromiumOS Authors + * Use of this source code is governed by a BSD-style license that can be + * found in the LICENSE file. + */ + +#include "../cbi.dtsi" + +#include "cbi.dtsi" +#include "generated.dtsi" +#include "keyboard.dtsi" +#include "motionsense.dtsi" +#include "overlay.dtsi" +#include "power_signals.dtsi" diff --git a/zephyr/projects/nissa/pujjo/pujjo_vif.xml b/zephyr/projects/nissa/pujjo/pujjo_vif.xml new file mode 100644 index 0000000000..b7d462584a --- /dev/null +++ b/zephyr/projects/nissa/pujjo/pujjo_vif.xml @@ -0,0 +1,350 @@ +<?xml version="1.0" encoding="utf-8"?>
+<vif:VIF xmlns:opt="http://usb.org/VendorInfoFileOptionalContent.xsd" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:vif="http://usb.org/VendorInfoFile.xsd">
+ <vif:VIF_Specification>3.19</vif:VIF_Specification>
+ <vif:VIF_App>
+ <vif:Vendor>USB-IF</vif:Vendor>
+ <vif:Name>VIF Editor</vif:Name>
+ <vif:Version>3.2.4.0</vif:Version>
+ </vif:VIF_App>
+ <vif:Vendor_Name>Google</vif:Vendor_Name>
+ <vif:Model_Part_Number>Pujjo</vif:Model_Part_Number>
+ <vif:Product_Revision>1</vif:Product_Revision>
+ <vif:TID>0</vif:TID>
+ <vif:VIF_Product_Type value="0">Port Product</vif:VIF_Product_Type>
+ <vif:Certification_Type value="0">End Product</vif:Certification_Type>
+ <vif:Product>
+ <!--Product Level Content:-->
+ </vif:Product>
+ <vif:Component>
+ <!--Component 0: Port 0-->
+ <!--;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-->
+ <!--;Component-->
+ <!--;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-->
+ <vif:Port_Label>0</vif:Port_Label>
+ <vif:Connector_Type value="2">Type-C®</vif:Connector_Type>
+ <vif:USB4_Supported value="false" />
+ <vif:USB_PD_Support value="true" />
+ <vif:PD_Port_Type value="4">DRP</vif:PD_Port_Type>
+ <vif:Type_C_State_Machine value="2">DRP</vif:Type_C_State_Machine>
+ <vif:Port_Battery_Powered value="true" />
+ <vif:BC_1_2_Support value="2">Charging Port</vif:BC_1_2_Support>
+ <vif:Captive_Cable value="false" />
+ <!--;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-->
+ <!--;General PD-->
+ <!--;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-->
+ <vif:PD_Spec_Revision_Major value="3" />
+ <vif:PD_Spec_Revision_Minor value="1" />
+ <vif:PD_Spec_Version_Major value="1" />
+ <vif:PD_Spec_Version_Minor value="3" />
+ <vif:PD_Specification_Revision value="2">Revision 3</vif:PD_Specification_Revision>
+ <vif:SOP_Capable value="true" />
+ <vif:SOP_P_Capable value="true" />
+ <vif:SOP_PP_Capable value="true" />
+ <vif:SOP_P_Debug_Capable value="false" />
+ <vif:SOP_PP_Debug_Capable value="false" />
+ <vif:Manufacturer_Info_Supported_Port value="true" />
+ <vif:Manufacturer_Info_VID_Port value="6353">18D1</vif:Manufacturer_Info_VID_Port>
+ <vif:Manufacturer_Info_PID_Port value="20570">505A</vif:Manufacturer_Info_PID_Port>
+ <vif:Chunking_Implemented_SOP value="true" />
+ <vif:Unchunked_Extended_Messages_Supported value="false" />
+ <vif:Security_Msgs_Supported_SOP value="false" />
+ <vif:Unconstrained_Power value="false" />
+ <vif:Num_Fixed_Batteries value="1" />
+ <vif:Num_Swappable_Battery_Slots value="0" />
+ <vif:ID_Header_Connector_Type_SOP value="2">USB Type-C® Receptacle</vif:ID_Header_Connector_Type_SOP>
+ <!--;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-->
+ <!--;PD Capabilities-->
+ <!--;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-->
+ <vif:USB_Comms_Capable value="true" />
+ <vif:DR_Swap_To_DFP_Supported value="true" />
+ <vif:DR_Swap_To_UFP_Supported value="false" />
+ <vif:VCONN_Swap_To_On_Supported value="true" />
+ <vif:VCONN_Swap_To_Off_Supported value="true" />
+ <vif:Responds_To_Discov_SOP_UFP value="false" />
+ <vif:Responds_To_Discov_SOP_DFP value="true" />
+ <vif:Attempts_Discov_SOP value="true" />
+ <vif:Power_Interruption_Available value="0">No Interruption Possible</vif:Power_Interruption_Available>
+ <vif:Data_Reset_Supported value="false" />
+ <vif:Enter_USB_Supported value="false" />
+ <!--;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-->
+ <!--;USB Type-C®-->
+ <!--;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-->
+ <vif:Type_C_Can_Act_As_Host value="true" />
+ <vif:Type_C_Can_Act_As_Device value="false" />
+ <vif:Type_C_Implements_Try_SRC value="true" />
+ <vif:Type_C_Implements_Try_SNK value="false" />
+ <vif:Type_C_Supports_Audio_Accessory value="false" />
+ <vif:Type_C_Is_VCONN_Powered_Accessory value="false" />
+ <vif:Type_C_Is_Debug_Target_SRC value="true" />
+ <vif:Type_C_Is_Debug_Target_SNK value="true" />
+ <vif:RP_Value value="1">1.5A</vif:RP_Value>
+ <vif:Type_C_Port_On_Hub value="false" />
+ <vif:Type_C_Power_Source value="2">Both</vif:Type_C_Power_Source>
+ <vif:Type_C_Sources_VCONN value="true" />
+ <vif:Type_C_Is_Alt_Mode_Controller value="true" />
+ <vif:Type_C_Is_Alt_Mode_Adapter value="false" />
+ <!--;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-->
+ <!--;Product Power-->
+ <!--;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-->
+ <vif:Product_Total_Source_Power_mW value="15000">15000 mW</vif:Product_Total_Source_Power_mW>
+ <vif:Port_Source_Power_Type value="0">Assured</vif:Port_Source_Power_Type>
+ <!--;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-->
+ <!--;USB Host-->
+ <!--;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-->
+ <vif:Host_Supports_USB_Data value="true" />
+ <vif:Host_Speed value="1">USB 3.2 Gen 1x1</vif:Host_Speed>
+ <vif:Host_Contains_Captive_Retimer value="false" />
+ <vif:Host_Truncates_DP_For_tDHPResponse value="false" />
+ <vif:Host_Is_Embedded value="false" />
+ <vif:Host_Suspend_Supported value="true" />
+ <vif:Is_DFP_On_Hub value="false" />
+ <!--;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-->
+ <!--;Battery Charging 1.2-->
+ <!--;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-->
+ <vif:BC_1_2_Charging_Port_Type value="1">CDP</vif:BC_1_2_Charging_Port_Type>
+ <!--;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-->
+ <!--;PD Source-->
+ <!--;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-->
+ <vif:PD_Power_As_Source value="15000">15000 mW</vif:PD_Power_As_Source>
+ <vif:EPR_Supported_As_Src value="false" />
+ <vif:USB_Suspend_May_Be_Cleared value="false" />
+ <vif:Sends_Pings value="false" />
+ <vif:FR_Swap_Type_C_Current_Capability_As_Initial_Sink value="0">FR_Swap not supported</vif:FR_Swap_Type_C_Current_Capability_As_Initial_Sink>
+ <vif:Master_Port value="false" />
+ <vif:Num_Src_PDOs value="1" />
+ <vif:PD_OC_Protection value="true" />
+ <vif:PD_OCP_Method value="0">Over-Current Response</vif:PD_OCP_Method>
+ <!--Bundle: SrcPdoList-->
+ <vif:SrcPdoList>
+ <vif:SrcPDO>
+ <!--Source PDO 1-->
+ <vif:Src_PDO_Supply_Type value="0">Fixed</vif:Src_PDO_Supply_Type>
+ <vif:Src_PDO_Peak_Current value="0">100% IOC</vif:Src_PDO_Peak_Current>
+ <vif:Src_PDO_Voltage value="100">5000 mV</vif:Src_PDO_Voltage>
+ <vif:Src_PDO_Max_Current value="300">3000 mA</vif:Src_PDO_Max_Current>
+ <vif:Src_PD_OCP_OC_Debounce value="0">0 msec</vif:Src_PD_OCP_OC_Debounce>
+ <vif:Src_PD_OCP_OC_Threshold value="300">3000 mA</vif:Src_PD_OCP_OC_Threshold>
+ </vif:SrcPDO>
+ </vif:SrcPdoList>
+ <!--;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-->
+ <!--;PD Sink-->
+ <!--;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-->
+ <vif:PD_Power_As_Sink value="60000">60000 mW</vif:PD_Power_As_Sink>
+ <vif:EPR_Supported_As_Snk value="false" />
+ <vif:No_USB_Suspend_May_Be_Set value="true" />
+ <vif:GiveBack_May_Be_Set value="false" />
+ <vif:Higher_Capability_Set value="false" />
+ <vif:FR_Swap_Reqd_Type_C_Current_As_Initial_Source value="0">FR_Swap not supported</vif:FR_Swap_Reqd_Type_C_Current_As_Initial_Source>
+ <vif:Num_Snk_PDOs value="3" />
+ <!--Bundle: SnkPdoList-->
+ <vif:SnkPdoList>
+ <vif:SnkPDO>
+ <!--Sink PDO 1-->
+ <vif:Snk_PDO_Supply_Type value="0">Fixed</vif:Snk_PDO_Supply_Type>
+ <vif:Snk_PDO_Voltage value="100">5000 mV</vif:Snk_PDO_Voltage>
+ <vif:Snk_PDO_Op_Current value="300">3000 mA</vif:Snk_PDO_Op_Current>
+ </vif:SnkPDO>
+ <vif:SnkPDO>
+ <!--Sink PDO 2-->
+ <vif:Snk_PDO_Supply_Type value="1">Battery</vif:Snk_PDO_Supply_Type>
+ <vif:Snk_PDO_Op_Power value="60">15000 mW</vif:Snk_PDO_Op_Power>
+ <vif:Snk_PDO_Min_Voltage value="95">4750 mV</vif:Snk_PDO_Min_Voltage>
+ <vif:Snk_PDO_Max_Voltage value="400">20000 mV</vif:Snk_PDO_Max_Voltage>
+ </vif:SnkPDO>
+ <vif:SnkPDO>
+ <!--Sink PDO 3-->
+ <vif:Snk_PDO_Supply_Type value="2">Variable</vif:Snk_PDO_Supply_Type>
+ <vif:Snk_PDO_Min_Voltage value="95">4750 mV</vif:Snk_PDO_Min_Voltage>
+ <vif:Snk_PDO_Max_Voltage value="400">20000 mV</vif:Snk_PDO_Max_Voltage>
+ <vif:Snk_PDO_Op_Current value="300">3000 mA</vif:Snk_PDO_Op_Current>
+ </vif:SnkPDO>
+ </vif:SnkPdoList>
+ <!--;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-->
+ <!--;Dual Role-->
+ <!--;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-->
+ <vif:Accepts_PR_Swap_As_Src value="true" />
+ <vif:Accepts_PR_Swap_As_Snk value="true" />
+ <vif:Requests_PR_Swap_As_Src value="true" />
+ <vif:Requests_PR_Swap_As_Snk value="true" />
+ <vif:FR_Swap_Supported_As_Initial_Sink value="false" />
+ <!--;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-->
+ <!--;SOP Discover ID-->
+ <!--;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-->
+ <vif:XID_SOP value="0" />
+ <vif:Data_Capable_As_USB_Host_SOP value="true" />
+ <vif:Data_Capable_As_USB_Device_SOP value="false" />
+ <vif:Product_Type_UFP_SOP value="0">Undefined</vif:Product_Type_UFP_SOP>
+ <vif:Product_Type_DFP_SOP value="2">PDUSB Host</vif:Product_Type_DFP_SOP>
+ <vif:DFP_VDO_Port_Number value="0" />
+ <vif:Modal_Operation_Supported_SOP value="false" />
+ <vif:USB_VID_SOP value="6353">18D1</vif:USB_VID_SOP>
+ <vif:PID_SOP value="20570">505A</vif:PID_SOP>
+ <vif:bcdDevice_SOP value="0">0000</vif:bcdDevice_SOP>
+ </vif:Component>
+ <vif:Component>
+ <!--Component 1: Port 1-->
+ <!--;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-->
+ <!--;Component-->
+ <!--;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-->
+ <vif:Port_Label>1</vif:Port_Label>
+ <vif:Connector_Type value="2">Type-C®</vif:Connector_Type>
+ <vif:USB4_Supported value="false" />
+ <vif:USB_PD_Support value="true" />
+ <vif:PD_Port_Type value="4">DRP</vif:PD_Port_Type>
+ <vif:Type_C_State_Machine value="2">DRP</vif:Type_C_State_Machine>
+ <vif:Port_Battery_Powered value="true" />
+ <vif:BC_1_2_Support value="2">Charging Port</vif:BC_1_2_Support>
+ <vif:Captive_Cable value="false" />
+ <!--;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-->
+ <!--;General PD-->
+ <!--;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-->
+ <vif:PD_Spec_Revision_Major value="3" />
+ <vif:PD_Spec_Revision_Minor value="1" />
+ <vif:PD_Spec_Version_Major value="1" />
+ <vif:PD_Spec_Version_Minor value="3" />
+ <vif:PD_Specification_Revision value="2">Revision 3</vif:PD_Specification_Revision>
+ <vif:SOP_Capable value="true" />
+ <vif:SOP_P_Capable value="true" />
+ <vif:SOP_PP_Capable value="true" />
+ <vif:SOP_P_Debug_Capable value="false" />
+ <vif:SOP_PP_Debug_Capable value="false" />
+ <vif:Manufacturer_Info_Supported_Port value="true" />
+ <vif:Manufacturer_Info_VID_Port value="6353">18D1</vif:Manufacturer_Info_VID_Port>
+ <vif:Manufacturer_Info_PID_Port value="20570">505A</vif:Manufacturer_Info_PID_Port>
+ <vif:Chunking_Implemented_SOP value="true" />
+ <vif:Unchunked_Extended_Messages_Supported value="false" />
+ <vif:Security_Msgs_Supported_SOP value="false" />
+ <vif:Unconstrained_Power value="false" />
+ <vif:Num_Fixed_Batteries value="1" />
+ <vif:Num_Swappable_Battery_Slots value="0" />
+ <vif:ID_Header_Connector_Type_SOP value="2">USB Type-C® Receptacle</vif:ID_Header_Connector_Type_SOP>
+ <!--;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-->
+ <!--;PD Capabilities-->
+ <!--;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-->
+ <vif:USB_Comms_Capable value="true" />
+ <vif:DR_Swap_To_DFP_Supported value="true" />
+ <vif:DR_Swap_To_UFP_Supported value="false" />
+ <vif:VCONN_Swap_To_On_Supported value="true" />
+ <vif:VCONN_Swap_To_Off_Supported value="true" />
+ <vif:Responds_To_Discov_SOP_UFP value="false" />
+ <vif:Responds_To_Discov_SOP_DFP value="true" />
+ <vif:Attempts_Discov_SOP value="true" />
+ <vif:Power_Interruption_Available value="0">No Interruption Possible</vif:Power_Interruption_Available>
+ <vif:Data_Reset_Supported value="false" />
+ <vif:Enter_USB_Supported value="false" />
+ <!--;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-->
+ <!--;USB Type-C®-->
+ <!--;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-->
+ <vif:Type_C_Can_Act_As_Host value="true" />
+ <vif:Type_C_Can_Act_As_Device value="false" />
+ <vif:Type_C_Implements_Try_SRC value="true" />
+ <vif:Type_C_Implements_Try_SNK value="false" />
+ <vif:Type_C_Supports_Audio_Accessory value="false" />
+ <vif:Type_C_Is_VCONN_Powered_Accessory value="false" />
+ <vif:Type_C_Is_Debug_Target_SRC value="true" />
+ <vif:Type_C_Is_Debug_Target_SNK value="true" />
+ <vif:RP_Value value="1">1.5A</vif:RP_Value>
+ <vif:Type_C_Port_On_Hub value="false" />
+ <vif:Type_C_Power_Source value="2">Both</vif:Type_C_Power_Source>
+ <vif:Type_C_Sources_VCONN value="true" />
+ <vif:Type_C_Is_Alt_Mode_Controller value="true" />
+ <vif:Type_C_Is_Alt_Mode_Adapter value="false" />
+ <!--;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-->
+ <!--;Product Power-->
+ <!--;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-->
+ <vif:Product_Total_Source_Power_mW value="15000">15000 mW</vif:Product_Total_Source_Power_mW>
+ <vif:Port_Source_Power_Type value="0">Assured</vif:Port_Source_Power_Type>
+ <!--;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-->
+ <!--;USB Host-->
+ <!--;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-->
+ <vif:Host_Supports_USB_Data value="true" />
+ <vif:Host_Speed value="1">USB 3.2 Gen 1x1</vif:Host_Speed>
+ <vif:Host_Contains_Captive_Retimer value="true" />
+ <vif:Host_Truncates_DP_For_tDHPResponse value="false" />
+ <vif:Host_Is_Embedded value="false" />
+ <vif:Host_Suspend_Supported value="true" />
+ <vif:Is_DFP_On_Hub value="false" />
+ <!--;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-->
+ <!--;Battery Charging 1.2-->
+ <!--;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-->
+ <vif:BC_1_2_Charging_Port_Type value="1">CDP</vif:BC_1_2_Charging_Port_Type>
+ <!--;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-->
+ <!--;PD Source-->
+ <!--;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-->
+ <vif:PD_Power_As_Source value="15000">15000 mW</vif:PD_Power_As_Source>
+ <vif:EPR_Supported_As_Src value="false" />
+ <vif:USB_Suspend_May_Be_Cleared value="false" />
+ <vif:Sends_Pings value="false" />
+ <vif:FR_Swap_Type_C_Current_Capability_As_Initial_Sink value="0">FR_Swap not supported</vif:FR_Swap_Type_C_Current_Capability_As_Initial_Sink>
+ <vif:Master_Port value="false" />
+ <vif:Num_Src_PDOs value="1" />
+ <vif:PD_OC_Protection value="true" />
+ <vif:PD_OCP_Method value="0">Over-Current Response</vif:PD_OCP_Method>
+ <!--Bundle: SrcPdoList-->
+ <vif:SrcPdoList>
+ <vif:SrcPDO>
+ <!--Source PDO 1-->
+ <vif:Src_PDO_Supply_Type value="0">Fixed</vif:Src_PDO_Supply_Type>
+ <vif:Src_PDO_Peak_Current value="0">100% IOC</vif:Src_PDO_Peak_Current>
+ <vif:Src_PDO_Voltage value="100">5000 mV</vif:Src_PDO_Voltage>
+ <vif:Src_PDO_Max_Current value="300">3000 mA</vif:Src_PDO_Max_Current>
+ <vif:Src_PD_OCP_OC_Debounce value="0">0 msec</vif:Src_PD_OCP_OC_Debounce>
+ <vif:Src_PD_OCP_OC_Threshold value="300">3000 mA</vif:Src_PD_OCP_OC_Threshold>
+ </vif:SrcPDO>
+ </vif:SrcPdoList>
+ <!--;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-->
+ <!--;PD Sink-->
+ <!--;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-->
+ <vif:PD_Power_As_Sink value="60000">60000 mW</vif:PD_Power_As_Sink>
+ <vif:EPR_Supported_As_Snk value="false" />
+ <vif:No_USB_Suspend_May_Be_Set value="true" />
+ <vif:GiveBack_May_Be_Set value="false" />
+ <vif:Higher_Capability_Set value="false" />
+ <vif:FR_Swap_Reqd_Type_C_Current_As_Initial_Source value="0">FR_Swap not supported</vif:FR_Swap_Reqd_Type_C_Current_As_Initial_Source>
+ <vif:Num_Snk_PDOs value="3" />
+ <!--Bundle: SnkPdoList-->
+ <vif:SnkPdoList>
+ <vif:SnkPDO>
+ <!--Sink PDO 1-->
+ <vif:Snk_PDO_Supply_Type value="0">Fixed</vif:Snk_PDO_Supply_Type>
+ <vif:Snk_PDO_Voltage value="100">5000 mV</vif:Snk_PDO_Voltage>
+ <vif:Snk_PDO_Op_Current value="300">3000 mA</vif:Snk_PDO_Op_Current>
+ </vif:SnkPDO>
+ <vif:SnkPDO>
+ <!--Sink PDO 2-->
+ <vif:Snk_PDO_Supply_Type value="1">Battery</vif:Snk_PDO_Supply_Type>
+ <vif:Snk_PDO_Op_Power value="60">15000 mW</vif:Snk_PDO_Op_Power>
+ <vif:Snk_PDO_Min_Voltage value="95">4750 mV</vif:Snk_PDO_Min_Voltage>
+ <vif:Snk_PDO_Max_Voltage value="400">20000 mV</vif:Snk_PDO_Max_Voltage>
+ </vif:SnkPDO>
+ <vif:SnkPDO>
+ <!--Sink PDO 3-->
+ <vif:Snk_PDO_Supply_Type value="2">Variable</vif:Snk_PDO_Supply_Type>
+ <vif:Snk_PDO_Min_Voltage value="95">4750 mV</vif:Snk_PDO_Min_Voltage>
+ <vif:Snk_PDO_Max_Voltage value="400">20000 mV</vif:Snk_PDO_Max_Voltage>
+ <vif:Snk_PDO_Op_Current value="300">3000 mA</vif:Snk_PDO_Op_Current>
+ </vif:SnkPDO>
+ </vif:SnkPdoList>
+ <!--;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-->
+ <!--;Dual Role-->
+ <!--;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-->
+ <vif:Accepts_PR_Swap_As_Src value="true" />
+ <vif:Accepts_PR_Swap_As_Snk value="true" />
+ <vif:Requests_PR_Swap_As_Src value="true" />
+ <vif:Requests_PR_Swap_As_Snk value="true" />
+ <vif:FR_Swap_Supported_As_Initial_Sink value="false" />
+ <!--;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-->
+ <!--;SOP Discover ID-->
+ <!--;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-->
+ <vif:XID_SOP value="0" />
+ <vif:Data_Capable_As_USB_Host_SOP value="true" />
+ <vif:Data_Capable_As_USB_Device_SOP value="false" />
+ <vif:Product_Type_UFP_SOP value="0">Undefined</vif:Product_Type_UFP_SOP>
+ <vif:Product_Type_DFP_SOP value="2">PDUSB Host</vif:Product_Type_DFP_SOP>
+ <vif:DFP_VDO_Port_Number value="1" />
+ <vif:Modal_Operation_Supported_SOP value="false" />
+ <vif:USB_VID_SOP value="6353">18D1</vif:USB_VID_SOP>
+ <vif:PID_SOP value="20570">505A</vif:PID_SOP>
+ <vif:bcdDevice_SOP value="0">0000</vif:bcdDevice_SOP>
+ </vif:Component>
+</vif:VIF>
\ No newline at end of file diff --git a/zephyr/projects/nissa/pujjo/src/charger.c b/zephyr/projects/nissa/pujjo/src/charger.c new file mode 100644 index 0000000000..f1f1d57790 --- /dev/null +++ b/zephyr/projects/nissa/pujjo/src/charger.c @@ -0,0 +1,64 @@ +/* Copyright 2022 The ChromiumOS Authors + * Use of this source code is governed by a BSD-style license that can be + * found in the LICENSE file. + */ + +#include <zephyr/logging/log.h> + +#include "battery.h" +#include "charger.h" +#include "charger/isl923x_public.h" +#include "driver/tcpm/raa489000.h" +#include "driver/charger/isl923x.h" +#include "console.h" +#include "extpower.h" +#include "usb_pd.h" +#include "nissa_common.h" +#include "hooks.h" + +LOG_MODULE_DECLARE(nissa, CONFIG_NISSA_LOG_LEVEL); + +int extpower_is_present(void) +{ + int port; + int rv; + bool acok; + + for (port = 0; port < board_get_usb_pd_port_count(); port++) { + rv = raa489000_is_acok(port, &acok); + if ((rv == EC_SUCCESS) && acok) + return 1; + } + + return 0; +} + +/* + * Pujjo does not have a GPIO indicating whether extpower is present, + * so detect using the charger(s). + */ +__override void board_check_extpower(void) +{ + static int last_extpower_present; + int extpower_present = extpower_is_present(); + + if (last_extpower_present ^ extpower_present) + extpower_handle_update(extpower_present); + + last_extpower_present = extpower_present; +} + +__override void board_hibernate(void) +{ + /* Shut down the chargers */ + raa489000_hibernate(0, true); + LOG_INF("Charger(s) hibernated"); + cflush(); +} + +static void charger_prochot_init(void) +{ + isl923x_set_ac_prochot(CHARGER_SOLO, 3500); + isl923x_set_dc_prochot(CHARGER_SOLO, 6528); +} +DECLARE_HOOK(HOOK_INIT, charger_prochot_init, HOOK_PRIO_POST_FIRST); diff --git a/zephyr/projects/nissa/pujjo/src/fan.c b/zephyr/projects/nissa/pujjo/src/fan.c new file mode 100644 index 0000000000..97323a7edf --- /dev/null +++ b/zephyr/projects/nissa/pujjo/src/fan.c @@ -0,0 +1,43 @@ +/* Copyright 2022 The ChromiumOS Authors + * Use of this source code is governed by a BSD-style license that can be + * found in the LICENSE file. + */ + +#include <zephyr/devicetree.h> +#include <zephyr/drivers/gpio.h> +#include <zephyr/logging/log.h> + +#include "cros_cbi.h" +#include "fan.h" +#include "gpio/gpio.h" +#include "hooks.h" + +#include "nissa_common.h" + +LOG_MODULE_DECLARE(nissa, CONFIG_NISSA_LOG_LEVEL); + +/* + * Pujjo fan support + */ +static void fan_init(void) +{ + int ret; + uint32_t val; + /* + * Retrieve the fan config. + */ + ret = cros_cbi_get_fw_config(FW_FAN, &val); + if (ret != 0) { + LOG_ERR("Error retrieving CBI FW_CONFIG field %d", FW_FAN); + return; + } + if (val != FW_FAN_PRESENT) { + /* Disable the fan */ + fan_set_count(0); + } else { + /* Configure the fan enable GPIO */ + gpio_pin_configure_dt(GPIO_DT_FROM_NODELABEL(gpio_fan_enable), + GPIO_OUTPUT); + } +} +DECLARE_HOOK(HOOK_INIT, fan_init, HOOK_PRIO_POST_FIRST); diff --git a/zephyr/projects/nissa/pujjo/src/form_factor.c b/zephyr/projects/nissa/pujjo/src/form_factor.c new file mode 100644 index 0000000000..6b02a258bc --- /dev/null +++ b/zephyr/projects/nissa/pujjo/src/form_factor.c @@ -0,0 +1,66 @@ +/* Copyright 2022 The ChromiumOS Authors + * Use of this source code is governed by a BSD-style license that can be + * found in the LICENSE file. + */ + +#include <zephyr/devicetree.h> +#include <zephyr/logging/log.h> + +#include "accelgyro.h" +#include "button.h" +#include "cros_board_info.h" +#include "cros_cbi.h" +#include "driver/accelgyro_bmi323.h" +#include "driver/accelgyro_lsm6dsm.h" +#include "gpio/gpio_int.h" +#include "hooks.h" +#include "motionsense_sensors.h" +#include "motion_sense.h" +#include "tablet_mode.h" + +#include "nissa_common.h" + +LOG_MODULE_DECLARE(nissa, CONFIG_NISSA_LOG_LEVEL); + +static bool use_alt_sensor; + +void motion_interrupt(enum gpio_signal signal) +{ + if (use_alt_sensor) + lsm6dsm_interrupt(signal); + else + bmi3xx_interrupt(signal); +} + +static void sensor_init(void) +{ + int ret; + uint32_t val; + /* check which base sensor is used for motion_interrupt */ + use_alt_sensor = cros_cbi_ssfc_check_match( + CBI_SSFC_VALUE_ID(DT_NODELABEL(base_sensor_1))); + + motion_sensors_check_ssfc(); + + /* Check if it's tablet or not */ + ret = cros_cbi_get_fw_config(FW_TABLET, &val); + if (ret != 0) { + LOG_ERR("Error retrieving CBI FW_CONFIG field %d", FW_TABLET); + return; + } + if (val == FW_TABLET_NOT_PRESENT) { + LOG_INF("Clamshell: disable motionsense function."); + motion_sensor_count = 0; + gmr_tablet_switch_disable(); + gpio_disable_dt_interrupt(GPIO_INT_FROM_NODELABEL(int_imu)); + gpio_pin_configure_dt(GPIO_DT_FROM_NODELABEL(gpio_imu_int_l), + GPIO_DISCONNECTED); + + LOG_INF("Clamshell: disable volume button function."); + button_disable_gpio(BUTTON_VOLUME_UP); + button_disable_gpio(BUTTON_VOLUME_DOWN); + } else { + LOG_INF("Tablet: Enable motionsense function."); + } +} +DECLARE_HOOK(HOOK_INIT, sensor_init, HOOK_PRIO_POST_I2C); diff --git a/zephyr/projects/nissa/pujjo/src/hdmi.c b/zephyr/projects/nissa/pujjo/src/hdmi.c new file mode 100644 index 0000000000..9461e7c53e --- /dev/null +++ b/zephyr/projects/nissa/pujjo/src/hdmi.c @@ -0,0 +1,12 @@ +/* Copyright 2022 The ChromiumOS Authors + * Use of this source code is governed by a BSD-style license that can be + * found in the LICENSE file. + */ + +#include "nissa_hdmi.h" + +__override void nissa_configure_hdmi_power_gpios(void) +{ + /* Pujjo needs to drive VCC enable but not core rails */ + nissa_configure_hdmi_vcc(); +} diff --git a/zephyr/projects/nissa/pujjo/src/keyboard.c b/zephyr/projects/nissa/pujjo/src/keyboard.c new file mode 100644 index 0000000000..1587030080 --- /dev/null +++ b/zephyr/projects/nissa/pujjo/src/keyboard.c @@ -0,0 +1,29 @@ +/* Copyright 2022 The ChromiumOS Authors + * Use of this source code is governed by a BSD-style license that can be + * found in the LICENSE file. + */ + +#include "ec_commands.h" + +static const struct ec_response_keybd_config pujjo_kb = { + .num_top_row_keys = 10, + .action_keys = { + TK_BACK, /* T1 */ + TK_REFRESH, /* T2 */ + TK_FULLSCREEN, /* T3 */ + TK_OVERVIEW, /* T4 */ + TK_BRIGHTNESS_DOWN, /* T5 */ + TK_BRIGHTNESS_UP, /* T6 */ + TK_MICMUTE, /* 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) +{ + return &pujjo_kb; +} diff --git a/zephyr/projects/nissa/pujjo/src/led.c b/zephyr/projects/nissa/pujjo/src/led.c new file mode 100644 index 0000000000..bd04af5a25 --- /dev/null +++ b/zephyr/projects/nissa/pujjo/src/led.c @@ -0,0 +1,134 @@ +/* Copyright 2022 The ChromiumOS Authors + * Use of this source code is governed by a BSD-style license that can be + * found in the LICENSE file. + */ + +/* Pujjo specific PWM LED settings: there are 2 LEDs on each side of the board, + * each one can be controlled separately. The LED colors are white or amber, + * and the default behavior is tied to the charging process: both sides are + * amber while charging the battery and white when the battery is charged. + */ + +#include "common.h" +#include "led_onoff_states.h" +#include "led_common.h" +#include "gpio.h" + +#define CPRINTS(format, args...) cprints(CC_CHARGER, format, ##args) +#define CPRINTF(format, args...) cprintf(CC_CHARGER, format, ##args) + +#define LED_OFF_LVL 1 +#define LED_ON_LVL 0 + +__override const int led_charge_lvl_1 = 5; + +__override const int led_charge_lvl_2 = 97; + +__override struct led_descriptor + led_bat_state_table[LED_NUM_STATES][LED_NUM_PHASES] = { + [STATE_CHARGING_LVL_1] = { { EC_LED_COLOR_RED, + LED_INDEFINITE } }, + [STATE_CHARGING_LVL_2] = { { EC_LED_COLOR_AMBER, + LED_INDEFINITE } }, + [STATE_CHARGING_FULL_CHARGE] = { { EC_LED_COLOR_GREEN, + LED_INDEFINITE } }, + [STATE_DISCHARGE_S0] = { { LED_OFF, LED_INDEFINITE } }, + [STATE_DISCHARGE_S3] = { { LED_OFF, LED_INDEFINITE } }, + [STATE_DISCHARGE_S5] = { { LED_OFF, LED_INDEFINITE } }, + [STATE_BATTERY_ERROR] = { { EC_LED_COLOR_RED, 1 * LED_ONE_SEC }, + { LED_OFF, 1 * LED_ONE_SEC } }, + [STATE_FACTORY_TEST] = { { EC_LED_COLOR_RED, 2 * LED_ONE_SEC }, + { EC_LED_COLOR_GREEN, + 2 * LED_ONE_SEC } }, + }; + +__override const struct led_descriptor + led_pwr_state_table[PWR_LED_NUM_STATES][LED_NUM_PHASES] = { + [PWR_LED_STATE_ON] = { { EC_LED_COLOR_WHITE, LED_INDEFINITE } }, + [PWR_LED_STATE_SUSPEND_AC] = { { EC_LED_COLOR_WHITE, + 3 * LED_ONE_SEC }, + { LED_OFF, 0.5 * LED_ONE_SEC } }, + [PWR_LED_STATE_SUSPEND_NO_AC] = { { EC_LED_COLOR_WHITE, + 3 * LED_ONE_SEC }, + { LED_OFF, + 0.5 * LED_ONE_SEC } }, + [PWR_LED_STATE_OFF] = { { LED_OFF, LED_INDEFINITE } }, + }; + +const enum ec_led_id supported_led_ids[] = { EC_LED_ID_BATTERY_LED, + EC_LED_ID_POWER_LED }; + +const int supported_led_ids_count = ARRAY_SIZE(supported_led_ids); + +__override void led_set_color_power(enum ec_led_colors color) +{ + if (color == EC_LED_COLOR_WHITE) + gpio_pin_set_dt(GPIO_DT_FROM_NODELABEL(gpio_power_led), + LED_ON_LVL); + else + /* LED_OFF and unsupported colors */ + gpio_pin_set_dt(GPIO_DT_FROM_NODELABEL(gpio_power_led), + LED_OFF_LVL); +} + +__override void led_set_color_battery(enum ec_led_colors color) +{ + switch (color) { + case EC_LED_COLOR_AMBER: + gpio_pin_set_dt(GPIO_DT_FROM_NODELABEL(gpio_led_1_odl), + LED_ON_LVL); + gpio_pin_set_dt(GPIO_DT_FROM_NODELABEL(gpio_led_2_odl), + LED_ON_LVL); + break; + case EC_LED_COLOR_RED: + gpio_pin_set_dt(GPIO_DT_FROM_NODELABEL(gpio_led_1_odl), + LED_ON_LVL); + gpio_pin_set_dt(GPIO_DT_FROM_NODELABEL(gpio_led_2_odl), + LED_OFF_LVL); + break; + case EC_LED_COLOR_GREEN: + gpio_pin_set_dt(GPIO_DT_FROM_NODELABEL(gpio_led_1_odl), + LED_OFF_LVL); + gpio_pin_set_dt(GPIO_DT_FROM_NODELABEL(gpio_led_2_odl), + LED_ON_LVL); + break; + default: /* LED_OFF and other unsupported colors */ + gpio_pin_set_dt(GPIO_DT_FROM_NODELABEL(gpio_led_1_odl), + LED_OFF_LVL); + gpio_pin_set_dt(GPIO_DT_FROM_NODELABEL(gpio_led_2_odl), + 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_RED] = 1; + brightness_range[EC_LED_COLOR_AMBER] = 1; + brightness_range[EC_LED_COLOR_GREEN] = 1; + } else if (led_id == EC_LED_ID_POWER_LED) { + brightness_range[EC_LED_COLOR_WHITE] = 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_RED] != 0) + led_set_color_battery(EC_LED_COLOR_RED); + else if (brightness[EC_LED_COLOR_AMBER] != 0) + led_set_color_battery(EC_LED_COLOR_AMBER); + else if (brightness[EC_LED_COLOR_GREEN] != 0) + led_set_color_battery(EC_LED_COLOR_GREEN); + else + led_set_color_battery(LED_OFF); + } else if (led_id == EC_LED_ID_POWER_LED) { + if (brightness[EC_LED_COLOR_WHITE] != 0) + led_set_color_power(EC_LED_COLOR_WHITE); + else + led_set_color_power(LED_OFF); + } + + return EC_SUCCESS; +} diff --git a/zephyr/projects/nissa/pujjo/src/usbc.c b/zephyr/projects/nissa/pujjo/src/usbc.c new file mode 100644 index 0000000000..5d3d94c243 --- /dev/null +++ b/zephyr/projects/nissa/pujjo/src/usbc.c @@ -0,0 +1,242 @@ +/* Copyright 2022 The ChromiumOS Authors + * Use of this source code is governed by a BSD-style license that can be + * found in the LICENSE file. + */ + +#include <zephyr/logging/log.h> + +#include "charge_state_v2.h" +#include "chipset.h" +#include "hooks.h" +#include "usb_mux.h" +#include "system.h" +#include "driver/charger/isl923x_public.h" +#include "driver/retimer/anx7483_public.h" +#include "driver/tcpm/tcpci.h" +#include "driver/tcpm/raa489000.h" + +#include "nissa_common.h" + +LOG_MODULE_DECLARE(nissa, CONFIG_NISSA_LOG_LEVEL); + +struct tcpc_config_t tcpc_config[CONFIG_USB_PD_PORT_MAX_COUNT] = { + { + .bus_type = EC_BUS_TYPE_I2C, + .i2c_info = { + .port = I2C_PORT_USB_C0_TCPC, + .addr_flags = RAA489000_TCPC0_I2C_FLAGS, + }, + .drv = &raa489000_tcpm_drv, + /* RAA489000 implements TCPCI 2.0 */ + .flags = TCPC_FLAGS_TCPCI_REV2_0 | + TCPC_FLAGS_VBUS_MONITOR, + }, +}; + +int board_is_sourcing_vbus(int port) +{ + int regval; + + tcpc_read(port, TCPC_REG_POWER_STATUS, ®val); + return !!(regval & TCPC_REG_POWER_STATUS_SOURCING_VBUS); +} + +int board_set_active_charge_port(int port) +{ + int is_real_port = (port >= 0 && port < CONFIG_USB_PD_PORT_MAX_COUNT); + int i; + int old_port; + + if (!is_real_port && port != CHARGE_PORT_NONE) + return EC_ERROR_INVAL; + + old_port = charge_manager_get_active_charge_port(); + + LOG_INF("New chg p%d", port); + + /* Disable all ports. */ + if (port == CHARGE_PORT_NONE) { + for (i = 0; i < CONFIG_USB_PD_PORT_MAX_COUNT; i++) { + tcpc_write(i, TCPC_REG_COMMAND, + TCPC_REG_COMMAND_SNK_CTRL_LOW); + raa489000_enable_asgate(i, false); + } + + return EC_SUCCESS; + } + + /* Check if port is sourcing VBUS. */ + if (board_is_sourcing_vbus(port)) { + LOG_WRN("Skip enable p%d", port); + return EC_ERROR_INVAL; + } + + /* + * Turn off the other ports' sink path FETs, before enabling the + * requested charge port. + */ + for (i = 0; i < CONFIG_USB_PD_PORT_MAX_COUNT; i++) { + if (i == port) + continue; + + if (tcpc_write(i, TCPC_REG_COMMAND, + TCPC_REG_COMMAND_SNK_CTRL_LOW)) + LOG_WRN("p%d: sink path disable failed.", i); + raa489000_enable_asgate(i, false); + } + + /* + * Stop the charger IC from switching while changing ports. Otherwise, + * we can overcurrent the adapter we're switching to. (crbug.com/926056) + */ + if (old_port != CHARGE_PORT_NONE) + charger_discharge_on_ac(1); + + /* Enable requested charge port. */ + if (raa489000_enable_asgate(port, true) || + tcpc_write(port, TCPC_REG_COMMAND, + TCPC_REG_COMMAND_SNK_CTRL_HIGH)) { + LOG_WRN("p%d: sink path enable failed.", port); + charger_discharge_on_ac(0); + return EC_ERROR_UNKNOWN; + } + + /* Allow the charger IC to begin/continue switching. */ + charger_discharge_on_ac(0); + + return EC_SUCCESS; +} + +uint16_t tcpc_get_alert_status(void) +{ + uint16_t status = 0; + int regval; + + /* + * The interrupt line is shared between the TCPC and BC1.2 detector IC. + * Therefore, go out and actually read the alert registers to report the + * alert status. + */ + if (!gpio_pin_get_dt(GPIO_DT_FROM_NODELABEL(gpio_usb_c0_int_odl))) { + if (!tcpc_read16(0, TCPC_REG_ALERT, ®val)) { + /* The TCPCI Rev 1.0 spec says to ignore bits 14:12. */ + if (!(tcpc_config[0].flags & TCPC_FLAGS_TCPCI_REV2_0)) + regval &= ~((1 << 14) | (1 << 13) | (1 << 12)); + + if (regval) + status |= PD_STATUS_TCPC_ALERT_0; + } + } + return status; +} + +void pd_power_supply_reset(int port) +{ + /* Disable VBUS */ + tcpc_write(port, TCPC_REG_COMMAND, TCPC_REG_COMMAND_SRC_CTRL_LOW); + + /* Notify host of power info change. */ + pd_send_host_event(PD_EVENT_POWER_CHANGE); +} + +__override void typec_set_source_current_limit(int port, enum tcpc_rp_value rp) +{ + if (port < 0 || port >= CONFIG_USB_PD_PORT_MAX_COUNT) + return; + + raa489000_set_output_current(port, rp); +} + +int pd_set_power_supply_ready(int port) +{ + int rv; + + if (port >= CONFIG_USB_PD_PORT_MAX_COUNT) + return EC_ERROR_INVAL; + + /* Disable charging. */ + rv = tcpc_write(port, TCPC_REG_COMMAND, TCPC_REG_COMMAND_SNK_CTRL_LOW); + if (rv) + return rv; + + /* Our policy is not to source VBUS when the AP is off. */ + if (chipset_in_state(CHIPSET_STATE_ANY_OFF)) + return EC_ERROR_NOT_POWERED; + + /* Provide Vbus. */ + rv = tcpc_write(port, TCPC_REG_COMMAND, TCPC_REG_COMMAND_SRC_CTRL_HIGH); + if (rv) + return rv; + + rv = raa489000_enable_asgate(port, true); + if (rv) + return rv; + + /* Notify host of power info change. */ + pd_send_host_event(PD_EVENT_POWER_CHANGE); + + return EC_SUCCESS; +} + +void board_reset_pd_mcu(void) +{ + /* + * TODO(b:147316511): could send a reset command to the TCPC here + * if needed. + */ +} + +/* + * Because the TCPCs and BC1.2 chips share interrupt lines, it's possible + * for an interrupt to be lost if one asserts the IRQ, the other does the same + * then the first releases it: there will only be one falling edge to trigger + * the interrupt, and the line will be held low. We handle this by running a + * deferred check after a falling edge to see whether the IRQ is still being + * asserted. If it is, we assume an interrupt may have been lost and we need + * to poll each chip for events again. + */ +#define USBC_INT_POLL_DELAY_US 5000 + +static void poll_c0_int(void); +DECLARE_DEFERRED(poll_c0_int); + +static void usbc_interrupt_trigger(int port) +{ + schedule_deferred_pd_interrupt(port); + usb_charger_task_set_event(port, USB_CHG_EVENT_BC12); +} + +static inline void poll_usb_gpio(int port, const struct gpio_dt_spec *gpio, + const struct deferred_data *ud) +{ + if (!gpio_pin_get_dt(gpio)) { + usbc_interrupt_trigger(port); + hook_call_deferred(ud, USBC_INT_POLL_DELAY_US); + } +} + +static void poll_c0_int(void) +{ + poll_usb_gpio(0, GPIO_DT_FROM_NODELABEL(gpio_usb_c0_int_odl), + &poll_c0_int_data); +} + +void usb_interrupt(enum gpio_signal signal) +{ + int port; + const struct deferred_data *ud; + + if (signal == GPIO_SIGNAL(DT_NODELABEL(gpio_usb_c0_int_odl))) { + port = 0; + ud = &poll_c0_int_data; + } + /* + * We've just been called from a falling edge, so there's definitely + * no lost IRQ right now. Cancel any pending check. + */ + hook_call_deferred(ud, -1); + /* Trigger polling of TCPC and BC1.2 in respective tasks */ + usbc_interrupt_trigger(port); + /* Check for lost interrupts in a bit */ + hook_call_deferred(ud, USBC_INT_POLL_DELAY_US); +} diff --git a/zephyr/projects/nissa/src/board_power.c b/zephyr/projects/nissa/src/board_power.c new file mode 100644 index 0000000000..d7fb4aeffe --- /dev/null +++ b/zephyr/projects/nissa/src/board_power.c @@ -0,0 +1,169 @@ +/* Copyright 2022 The ChromiumOS Authors + * Use of this source code is governed by a BSD-style license that can be + * found in the LICENSE file. + */ + +#include <zephyr/sys/atomic.h> +#include <zephyr/logging/log.h> +#include <zephyr/drivers/gpio.h> + +#include <ap_power/ap_power.h> +#include <ap_power/ap_power_events.h> +#include <ap_power/ap_power_interface.h> +#include <ap_power_override_functions.h> +#include <power_signals.h> +#include <x86_power_signals.h> + +#include "gpio_signal.h" +#include "gpio/gpio.h" + +LOG_MODULE_DECLARE(ap_pwrseq, LOG_LEVEL_INF); + +#define X86_NON_DSX_ADLP_NONPWRSEQ_FORCE_SHUTDOWN_TO_MS 5 + +static bool s0_stable; + +static void generate_ec_soc_dsw_pwrok_handler(int delay) +{ + int in_sig_val = power_signal_get(PWR_DSW_PWROK); + + if (in_sig_val != power_signal_get(PWR_EC_SOC_DSW_PWROK)) { + if (in_sig_val) + k_msleep(delay); + power_signal_set(PWR_EC_SOC_DSW_PWROK, 1); + } +} + +void board_ap_power_force_shutdown(void) +{ + int timeout_ms = X86_NON_DSX_ADLP_NONPWRSEQ_FORCE_SHUTDOWN_TO_MS; + + if (s0_stable) { + /* Enable these power signals in case of sudden shutdown */ + power_signal_enable(PWR_DSW_PWROK); + power_signal_enable(PWR_PG_PP1P05); + } + + power_signal_set(PWR_EC_SOC_DSW_PWROK, 0); + power_signal_set(PWR_EC_PCH_RSMRST, 0); + + while (power_signal_get(PWR_RSMRST) == 0 && + power_signal_get(PWR_SLP_SUS) == 0 && timeout_ms > 0) { + k_msleep(1); + timeout_ms--; + } + if (power_signal_get(PWR_SLP_SUS) == 0) { + LOG_WRN("SLP_SUS is not deasserted! Assuming G3"); + } + + if (power_signal_get(PWR_RSMRST) == 1) { + LOG_WRN("RSMRST is not deasserted! Assuming G3"); + } + + power_signal_set(PWR_EN_PP3300_A, 0); + + power_signal_set(PWR_EN_PP5000_A, 0); + + timeout_ms = X86_NON_DSX_ADLP_NONPWRSEQ_FORCE_SHUTDOWN_TO_MS; + while (power_signal_get(PWR_DSW_PWROK) && timeout_ms > 0) { + k_msleep(1); + timeout_ms--; + }; + + if (power_signal_get(PWR_DSW_PWROK)) + LOG_WRN("DSW_PWROK didn't go low! Assuming G3."); + + power_signal_disable(PWR_DSW_PWROK); + power_signal_disable(PWR_PG_PP1P05); + s0_stable = false; +} + +void board_ap_power_action_g3_s5(void) +{ + power_signal_enable(PWR_DSW_PWROK); + power_signal_enable(PWR_PG_PP1P05); + + LOG_DBG("Turning on PWR_EN_PP5000_A and PWR_EN_PP3300_A"); + power_signal_set(PWR_EN_PP5000_A, 1); + power_signal_set(PWR_EN_PP3300_A, 1); + + power_wait_signals_timeout(IN_PGOOD_ALL_CORE, + AP_PWRSEQ_DT_VALUE(wait_signal_timeout)); + + generate_ec_soc_dsw_pwrok_handler(AP_PWRSEQ_DT_VALUE(dsw_pwrok_delay)); + s0_stable = false; +} + +void board_ap_power_action_s3_s0(void) +{ + s0_stable = false; +} + +void board_ap_power_action_s0_s3(void) +{ + power_signal_enable(PWR_DSW_PWROK); + power_signal_enable(PWR_PG_PP1P05); + s0_stable = false; +} + +void board_ap_power_action_s0(void) +{ + if (s0_stable) { + return; + } + LOG_INF("Reaching S0"); + power_signal_disable(PWR_DSW_PWROK); + power_signal_disable(PWR_PG_PP1P05); + s0_stable = true; +} + +int board_ap_power_assert_pch_power_ok(void) +{ + /* Pass though PCH_PWROK */ + if (power_signal_get(PWR_PCH_PWROK) == 0) { + k_msleep(AP_PWRSEQ_DT_VALUE(pch_pwrok_delay)); + power_signal_set(PWR_PCH_PWROK, 1); + } + + return 0; +} + +bool board_ap_power_check_power_rails_enabled(void) +{ + return power_signal_get(PWR_EN_PP3300_A) && + power_signal_get(PWR_EN_PP5000_A) && + power_signal_get(PWR_EC_SOC_DSW_PWROK); +} + +int board_power_signal_get(enum power_signal signal) +{ + switch (signal) { + default: + LOG_ERR("Unknown signal for board get: %d", signal); + return -EINVAL; + + case PWR_ALL_SYS_PWRGD: + /* + * All system power is good. + * Checks that PWR_SLP_S3 is off, and + * the GPIO signal for all power good is set, + * and that the 1.05 volt line is ready. + */ + if (power_signal_get(PWR_SLP_S3)) { + return 0; + } + if (!gpio_pin_get_dt( + GPIO_DT_FROM_NODELABEL(gpio_all_sys_pwrgd))) { + return 0; + } + if (!power_signal_get(PWR_PG_PP1P05)) { + return 0; + } + return 1; + } +} + +int board_power_signal_set(enum power_signal signal, int value) +{ + return -EINVAL; +} diff --git a/zephyr/projects/nissa/src/common.c b/zephyr/projects/nissa/src/common.c new file mode 100644 index 0000000000..78f703ae49 --- /dev/null +++ b/zephyr/projects/nissa/src/common.c @@ -0,0 +1,154 @@ +/* Copyright 2022 The ChromiumOS Authors + * Use of this source code is governed by a BSD-style license that can be + * found in the LICENSE file. + */ + +#include <zephyr/device.h> +#include <ap_power/ap_power.h> + +#include "battery.h" +#include "charger.h" +#include "charge_state_v2.h" +#include "chipset.h" +#include "cros_cbi.h" +#include "hooks.h" +#include "usb_mux.h" +#include "system.h" + +#include "nissa_common.h" + +#include <zephyr/logging/log.h> +LOG_MODULE_REGISTER(nissa, CONFIG_NISSA_LOG_LEVEL); + +static uint8_t cached_usb_pd_port_count; + +__override uint8_t board_get_usb_pd_port_count(void) +{ + __ASSERT(cached_usb_pd_port_count != 0, + "sub-board detection did not run before a port count request"); + if (cached_usb_pd_port_count == 0) + LOG_WRN("USB PD Port count not initialized!"); + return cached_usb_pd_port_count; +} + +static void board_power_change(struct ap_power_ev_callback *cb, + struct ap_power_ev_data data) +{ + /* + * Enable power to pen garage when system is active (safe even if no + * pen is present). + */ + const struct gpio_dt_spec *const pen_power_gpio = + GPIO_DT_FROM_NODELABEL(gpio_en_pp5000_pen_x); + + switch (data.event) { + case AP_POWER_STARTUP: + gpio_pin_set_dt(pen_power_gpio, 1); + break; + case AP_POWER_SHUTDOWN: + gpio_pin_set_dt(pen_power_gpio, 0); + break; + default: + break; + } +} + +/* + * Initialise the USB PD port count, which + * depends on which sub-board is attached. + */ +static void board_setup_init(void) +{ + static struct ap_power_ev_callback cb; + + ap_power_ev_init_callback(&cb, board_power_change, + AP_POWER_STARTUP | AP_POWER_SHUTDOWN); + ap_power_ev_add_callback(&cb); + + switch (nissa_get_sb_type()) { + default: + cached_usb_pd_port_count = 1; + break; + + case NISSA_SB_C_A: + case NISSA_SB_C_LTE: + cached_usb_pd_port_count = 2; + break; + } +} +/* + * Make sure setup is done after EEPROM is readable. + */ +DECLARE_HOOK(HOOK_INIT, board_setup_init, HOOK_PRIO_INIT_I2C); + +__overridable void board_set_charge_limit(int port, int supplier, int charge_ma, + int max_ma, int charge_mv) +{ + int icl = MAX(charge_ma, CONFIG_CHARGER_INPUT_CURRENT); + + /* + * Assume charger overdraws by about 4%, keeping the actual draw + * within spec. This adjustment can be changed with characterization + * of actual hardware. + */ + icl = icl * 96 / 100; + charge_set_input_current_limit(icl, charge_mv); +} + +int pd_check_vconn_swap(int port) +{ + /* Allow VCONN swaps if the AP is on. */ + return chipset_in_state(CHIPSET_STATE_ANY_SUSPEND | CHIPSET_STATE_ON); +} + +/* + * Count of chargers depends on sub board presence. + */ +__override uint8_t board_get_charger_chip_count(void) +{ + return board_get_usb_pd_port_count(); +} + +/* + * Retrieve sub-board type from FW_CONFIG. + */ +enum nissa_sub_board_type nissa_get_sb_type(void) +{ + static enum nissa_sub_board_type sb = NISSA_SB_UNKNOWN; + int ret; + uint32_t val; + + /* + * Return cached value. + */ + if (sb != NISSA_SB_UNKNOWN) + return sb; + + sb = NISSA_SB_NONE; /* Defaults to none */ + ret = cros_cbi_get_fw_config(FW_SUB_BOARD, &val); + if (ret != 0) { + LOG_WRN("Error retrieving CBI FW_CONFIG field %d", + FW_SUB_BOARD); + return sb; + } + switch (val) { + default: + LOG_WRN("No sub-board defined"); + break; + case FW_SUB_BOARD_1: + sb = NISSA_SB_C_A; + LOG_INF("SB: USB type C, USB type A"); + break; + + case FW_SUB_BOARD_2: + sb = NISSA_SB_C_LTE; + LOG_INF("SB: USB type C, WWAN LTE"); + break; + + case FW_SUB_BOARD_3: + sb = NISSA_SB_HDMI_A; + LOG_INF("SB: HDMI, USB type A"); + break; + } + return sb; +} diff --git a/zephyr/projects/nissa/src/led.c b/zephyr/projects/nissa/src/led.c new file mode 100644 index 0000000000..2617d0092d --- /dev/null +++ b/zephyr/projects/nissa/src/led.c @@ -0,0 +1,52 @@ +/* Copyright 2022 The ChromiumOS Authors + * Use of this source code is governed by a BSD-style license that can be + * found in the LICENSE file. + * + * Battery LED control for nissa + */ +#include "common.h" +#include "ec_commands.h" +#include "led_common.h" +#include "led_onoff_states.h" +#include "led_pwm.h" + +__override const int led_charge_lvl_1 = 5; +__override const int led_charge_lvl_2 = 97; +__override struct led_descriptor + led_bat_state_table[LED_NUM_STATES][LED_NUM_PHASES] = { + [STATE_CHARGING_LVL_1] = { { EC_LED_COLOR_RED, + LED_INDEFINITE } }, + [STATE_CHARGING_LVL_2] = { { EC_LED_COLOR_AMBER, + LED_INDEFINITE } }, + [STATE_CHARGING_FULL_CHARGE] = { { EC_LED_COLOR_GREEN, + LED_INDEFINITE } }, + [STATE_DISCHARGE_S0] = { { LED_OFF, LED_INDEFINITE } }, + [STATE_DISCHARGE_S0_BAT_LOW] = { { EC_LED_COLOR_AMBER, + 1 * LED_ONE_SEC }, + { LED_OFF, 3 * LED_ONE_SEC } }, + [STATE_DISCHARGE_S3] = { { LED_OFF, LED_INDEFINITE } }, + [STATE_DISCHARGE_S5] = { { LED_OFF, LED_INDEFINITE } }, + [STATE_BATTERY_ERROR] = { { EC_LED_COLOR_RED, 1 * LED_ONE_SEC }, + { LED_OFF, 1 * LED_ONE_SEC } }, + [STATE_FACTORY_TEST] = { { EC_LED_COLOR_RED, 2 * LED_ONE_SEC }, + { EC_LED_COLOR_GREEN, + 2 * LED_ONE_SEC } }, + }; + +__override void led_set_color_battery(enum ec_led_colors color) +{ + switch (color) { + case EC_LED_COLOR_RED: + set_pwm_led_color(EC_LED_ID_BATTERY_LED, EC_LED_COLOR_RED); + break; + case EC_LED_COLOR_GREEN: + set_pwm_led_color(EC_LED_ID_BATTERY_LED, EC_LED_COLOR_GREEN); + break; + case EC_LED_COLOR_AMBER: + set_pwm_led_color(EC_LED_ID_BATTERY_LED, EC_LED_COLOR_AMBER); + break; + default: /* LED_OFF and other unsupported colors */ + set_pwm_led_color(EC_LED_ID_BATTERY_LED, -1); + break; + } +} diff --git a/zephyr/projects/nissa/src/sub_board.c b/zephyr/projects/nissa/src/sub_board.c new file mode 100644 index 0000000000..3ccbcd9325 --- /dev/null +++ b/zephyr/projects/nissa/src/sub_board.c @@ -0,0 +1,298 @@ +/* Copyright 2022 The ChromiumOS Authors + * Use of this source code is governed by a BSD-style license that can be + * found in the LICENSE file. + */ + +/* Nissa sub-board hardware configuration */ + +#include <ap_power/ap_power.h> +#include <zephyr/drivers/gpio.h> +#include <zephyr/drivers/pinctrl.h> +#include <zephyr/init.h> +#include <zephyr/kernel.h> +#include <zephyr/sys/printk.h> + +#include "cros_board_info.h" +#include "driver/tcpm/tcpci.h" +#include "gpio/gpio_int.h" +#include "hooks.h" +#include "usb_charge.h" +#include "usb_pd.h" +#include "usbc/usb_muxes.h" +#include "task.h" + +#include "nissa_common.h" +#include "nissa_hdmi.h" + +LOG_MODULE_DECLARE(nissa, CONFIG_NISSA_LOG_LEVEL); + +#if NISSA_BOARD_HAS_HDMI_SUPPORT +static void hdmi_power_handler(struct ap_power_ev_callback *cb, + struct ap_power_ev_data data) +{ + /* Enable VCC on the HDMI port. */ + const struct gpio_dt_spec *s3_rail = + GPIO_DT_FROM_ALIAS(gpio_hdmi_en_odl); + /* Connect AP's DDC to sub-board (default is USB-C aux) */ + const struct gpio_dt_spec *ddc_select = + GPIO_DT_FROM_NODELABEL(gpio_hdmi_sel); + + switch (data.event) { + case AP_POWER_PRE_INIT: + LOG_DBG("Connecting HDMI DDC to sub-board"); + gpio_pin_set_dt(ddc_select, 1); + break; + case AP_POWER_STARTUP: + LOG_DBG("Enabling HDMI VCC"); + gpio_pin_set_dt(s3_rail, 1); + break; + case AP_POWER_SHUTDOWN: + LOG_DBG("Disabling HDMI VCC"); + gpio_pin_set_dt(s3_rail, 0); + break; + case AP_POWER_HARD_OFF: + LOG_DBG("Disconnecting HDMI sub-board DDC"); + gpio_pin_set_dt(ddc_select, 0); + break; + default: + LOG_ERR("Unhandled HDMI power event %d", data.event); + break; + } +} + +static void hdmi_hpd_interrupt(const struct device *device, + struct gpio_callback *callback, + gpio_port_pins_t pins) +{ + int state = gpio_pin_get_dt(GPIO_DT_FROM_ALIAS(gpio_hpd_odl)); + + gpio_pin_set_dt(GPIO_DT_FROM_NODELABEL(gpio_ec_soc_hdmi_hpd), state); + LOG_DBG("HDMI HPD changed state to %d", state); +} + +void nissa_configure_hdmi_rails(void) +{ +#if DT_NODE_EXISTS(GPIO_DT_FROM_ALIAS(gpio_en_rails_odl)) + gpio_pin_configure_dt(GPIO_DT_FROM_ALIAS(gpio_en_rails_odl), + GPIO_OUTPUT_INACTIVE | GPIO_OPEN_DRAIN | + GPIO_PULL_UP | GPIO_ACTIVE_LOW); +#endif +} + +void nissa_configure_hdmi_vcc(void) +{ + gpio_pin_configure_dt(GPIO_DT_FROM_ALIAS(gpio_hdmi_en_odl), + GPIO_OUTPUT_INACTIVE | GPIO_OPEN_DRAIN | + GPIO_ACTIVE_LOW); +} + +__overridable void nissa_configure_hdmi_power_gpios(void) +{ + nissa_configure_hdmi_rails(); +} + +#ifdef CONFIG_SOC_IT8XXX2 +/* + * On it8xxx2, the below condition will break the EC to enter deep doze mode + * (b:237717730): + * Enhance i2c (GPE0/E7, GPH1/GPH2 or GPA4/GPA5) is enabled and its clock and + * data pins aren't both at high level. + * + * Since HDMI+type A SKU doesn't use i2c4, disable it for better power number. + */ +#define I2C4_NODE DT_NODELABEL(i2c4) +#if DT_NODE_EXISTS(I2C4_NODE) +PINCTRL_DT_DEFINE(I2C4_NODE); + +/* disable i2c4 alternate function */ +static void soc_it8xxx2_disable_i2c4_alt(void) +{ + const struct pinctrl_dev_config *pcfg = + PINCTRL_DT_DEV_CONFIG_GET(I2C4_NODE); + + pinctrl_apply_state(pcfg, PINCTRL_STATE_SLEEP); +} +#endif /* DT_NODE_EXISTS(I2C4_NODE) */ +#endif /* CONFIG_SOC_IT8XXX2 */ +#endif /* NISSA_BOARD_HAS_HDMI_SUPPORT */ + +static void lte_power_handler(struct ap_power_ev_callback *cb, + struct ap_power_ev_data data) +{ + /* Enable rails for S5 */ + const struct gpio_dt_spec *s5_rail = + GPIO_DT_FROM_ALIAS(gpio_en_sub_s5_rails); + switch (data.event) { + case AP_POWER_PRE_INIT: + LOG_DBG("Enabling LTE sub-board power rails"); + gpio_pin_set_dt(s5_rail, 1); + break; + case AP_POWER_HARD_OFF: + LOG_DBG("Disabling LTE sub-board power rails"); + gpio_pin_set_dt(s5_rail, 0); + break; + default: + LOG_ERR("Unhandled LTE power event %d", data.event); + break; + } +} + +/** + * Configure GPIOs (and other pin functions) that vary with present sub-board. + * + * The functions of some pins vary according to which sub-board is present + * (indicated by CBI fw_config); this function configures them according to the + * needs of the present sub-board. + */ +static void nereid_subboard_config(void) +{ + enum nissa_sub_board_type sb = nissa_get_sb_type(); + static struct ap_power_ev_callback power_cb; + + /* + * USB-A port: current limit output is configured by default and unused + * if this port is not present. VBUS enable must be configured if + * needed and is controlled by the usba-port-enable-pins driver. + */ + if (sb == NISSA_SB_C_A || sb == NISSA_SB_HDMI_A || + sb == NISSA_SB_NONE) { + /* + * Configure VBUS enable, default off. + * SB_NONE indicates missing fw_config; it's safe to enable VBUS + * control in this case since all that will happen is we turn + * off power to LTE, and it's useful to allow USB-A to work in + * such a configuration. + */ + gpio_pin_configure_dt(GPIO_DT_FROM_ALIAS(gpio_en_usb_a1_vbus), + GPIO_OUTPUT_LOW); + } else { + /* Turn off unused pins */ + gpio_pin_configure_dt( + GPIO_DT_FROM_NODELABEL(gpio_sub_usb_a1_ilimit_sdp), + GPIO_DISCONNECTED); + gpio_pin_configure_dt(GPIO_DT_FROM_ALIAS(gpio_en_usb_a1_vbus), + GPIO_DISCONNECTED); + /* Disable second USB-A port enable GPIO */ + __ASSERT(USB_PORT_ENABLE_COUNT == 2, + "USB A port count != 2 (%d)", USB_PORT_ENABLE_COUNT); + usb_port_enable[1] = -1; + } + /* + * USB-C port: the default configuration has I2C on the I2C pins, + * but the interrupt line needs to be configured. + */ +#if CONFIG_USB_PD_PORT_MAX_COUNT > 1 + if (sb == NISSA_SB_C_A || sb == NISSA_SB_C_LTE) { + /* Configure interrupt input */ + gpio_pin_configure_dt(GPIO_DT_FROM_ALIAS(gpio_usb_c1_int_odl), + GPIO_INPUT | GPIO_PULL_UP); + } else { + /* Port doesn't exist, doesn't need muxing */ + USB_MUX_ENABLE_ALTERNATIVE(usb_mux_chain_1_no_mux); + } +#endif + + switch (sb) { +#if NISSA_BOARD_HAS_HDMI_SUPPORT + case NISSA_SB_HDMI_A: { + /* + * HDMI: two outputs control power which must be configured to + * non-default settings, and HPD must be forwarded to the AP + * on another output pin. + */ + const struct gpio_dt_spec *hpd_gpio = + GPIO_DT_FROM_ALIAS(gpio_hpd_odl); + static struct gpio_callback hdmi_hpd_cb; + int rv, irq_key; + + nissa_configure_hdmi_power_gpios(); + +#if CONFIG_SOC_IT8XXX2 && DT_NODE_EXISTS(I2C4_NODE) + /* disable i2c4 alternate function for better power number */ + soc_it8xxx2_disable_i2c4_alt(); +#endif + + /* + * Control HDMI power according to AP power state. Some events + * won't do anything if the corresponding pin isn't configured, + * but that's okay. + */ + ap_power_ev_init_callback( + &power_cb, hdmi_power_handler, + AP_POWER_PRE_INIT | AP_POWER_HARD_OFF | + AP_POWER_STARTUP | AP_POWER_SHUTDOWN); + ap_power_ev_add_callback(&power_cb); + + /* + * Configure HPD input from sub-board; it's inverted by a buffer + * on the sub-board. + */ + gpio_pin_configure_dt(hpd_gpio, GPIO_INPUT | GPIO_ACTIVE_LOW); + /* Register interrupt handler for HPD changes */ + gpio_init_callback(&hdmi_hpd_cb, hdmi_hpd_interrupt, + BIT(hpd_gpio->pin)); + gpio_add_callback(hpd_gpio->port, &hdmi_hpd_cb); + rv = gpio_pin_interrupt_configure_dt(hpd_gpio, + GPIO_INT_EDGE_BOTH); + __ASSERT(rv == 0, + "HPD interrupt configuration returned error %d", rv); + /* + * Run the HPD handler once to ensure output is in sync. + * Lock interrupts to ensure that we don't cause desync if an + * HPD interrupt comes in between the internal read of the input + * and write to the output. + */ + irq_key = irq_lock(); + hdmi_hpd_interrupt(hpd_gpio->port, &hdmi_hpd_cb, + BIT(hpd_gpio->pin)); + irq_unlock(irq_key); + break; + } +#endif + case NISSA_SB_C_LTE: + /* + * LTE: Set up callbacks for enabling/disabling + * sub-board power on S5 state. + */ + gpio_pin_configure_dt(GPIO_DT_FROM_ALIAS(gpio_en_sub_s5_rails), + GPIO_OUTPUT_INACTIVE); + /* Control LTE power when CPU entering or + * exiting S5 state. + */ + ap_power_ev_init_callback(&power_cb, lte_power_handler, + AP_POWER_HARD_OFF | + AP_POWER_PRE_INIT); + ap_power_ev_add_callback(&power_cb); + break; + + default: + break; + } +} +DECLARE_HOOK(HOOK_INIT, nereid_subboard_config, HOOK_PRIO_POST_FIRST); + +/* + * Enable interrupts + */ +static void board_init(void) +{ + /* + * Enable USB-C interrupts. + */ + gpio_enable_dt_interrupt(GPIO_INT_FROM_NODELABEL(int_usb_c0)); +#if CONFIG_USB_PD_PORT_MAX_COUNT > 1 + if (board_get_usb_pd_port_count() == 2) + gpio_enable_dt_interrupt(GPIO_INT_FROM_NODELABEL(int_usb_c1)); +#endif +} +DECLARE_HOOK(HOOK_INIT, board_init, HOOK_PRIO_DEFAULT); + +/* Trigger shutdown by enabling the Z-sleep circuit */ +__override void board_hibernate_late(void) +{ + gpio_pin_set_dt(GPIO_DT_FROM_NODELABEL(gpio_en_slp_z), 1); + /* + * The system should hibernate, but there may be + * a small delay, so return. + */ +} diff --git a/zephyr/projects/nissa/xivu/cbi.dtsi b/zephyr/projects/nissa/xivu/cbi.dtsi new file mode 100644 index 0000000000..4149ea291c --- /dev/null +++ b/zephyr/projects/nissa/xivu/cbi.dtsi @@ -0,0 +1,77 @@ +/* Copyright 2022 The ChromiumOS Authors + * Use of this source code is governed by a BSD-style license that can be + * found in the LICENSE file. + */ + +/ { + /* Xivu-specific fw_config fields. */ + nissa-fw-config { + /* + * FW_CONFIG field to enable WFC or not. + */ + wfc { + enum-name = "FW_WFC"; + start = <0>; + size = <1>; + + wfc-mipi { + compatible = "cros-ec,cbi-fw-config-value"; + enum-name = "FW_WFC_MIPI"; + value = <0>; + }; + wfc-absent { + compatible = "cros-ec,cbi-fw-config-value"; + enum-name = "FW_WFC_ABSENT"; + value = <1>; + }; + }; + + /* + * FW_CONFIG field to enable stylus or not. + */ + stylus { + enum-name = "FW_STYLUS"; + start = <1>; + size = <1>; + + stylus-present { + compatible = "cros-ec,cbi-fw-config-value"; + enum-name = "FW_STYLUS_PRESENT"; + value = <0>; + }; + stylus-absent { + compatible = "cros-ec,cbi-fw-config-value"; + enum-name = "FW_STYLUS_ABSENT"; + value = <1>; + }; + }; + /* + * FW_CONFIG field to indicate which sub-board + * is attached. + */ + sub-board { + enum-name = "FW_SUB_BOARD"; + start = <2>; + size = <2>; + + sub-board-1 { + compatible = "cros-ec,cbi-fw-config-value"; + enum-name = "FW_SUB_BOARD_1"; + value = <0>; + }; + sub-board-2 { + compatible = "cros-ec,cbi-fw-config-value"; + enum-name = "FW_SUB_BOARD_2"; + value = <1>; + }; + sub-board-3 { + compatible = "cros-ec,cbi-fw-config-value"; + enum-name = "FW_SUB_BOARD_3"; + value = <2>; + }; + }; + +/delete-node/ fan; + }; + +}; diff --git a/zephyr/projects/nissa/xivu/generated.dtsi b/zephyr/projects/nissa/xivu/generated.dtsi new file mode 100644 index 0000000000..383054adf8 --- /dev/null +++ b/zephyr/projects/nissa/xivu/generated.dtsi @@ -0,0 +1,291 @@ +/* Copyright 2022 The ChromiumOS Authors + * Use of this source code is governed by a BSD-style license that can be + * found in the LICENSE file. + * + * This file is auto-generated - do not edit! + */ + +/ { + + named-adc-channels { + compatible = "named-adc-channels"; + + adc_ec_vsense_pp1050_proc: ec_vsense_pp1050_proc { + enum-name = "ADC_PP1050_PROC"; + io-channels = <&adc0 4>; + }; + adc_ec_vsense_pp3300_s5: ec_vsense_pp3300_s5 { + enum-name = "ADC_PP3300_S5"; + io-channels = <&adc0 6>; + }; + adc_temp_sensor_1: temp_sensor_1 { + enum-name = "ADC_TEMP_SENSOR_1"; + io-channels = <&adc0 0>; + }; + adc_temp_sensor_2: temp_sensor_2 { + enum-name = "ADC_TEMP_SENSOR_2"; + io-channels = <&adc0 1>; + }; + adc_temp_sensor_3: temp_sensor_3 { + enum-name = "ADC_TEMP_SENSOR_3"; + io-channels = <&adc0 10>; + }; + adc_temp_sensor_4: temp_sensor_4 { + enum-name = "ADC_TEMP_SENSOR_4"; + io-channels = <&adc0 11>; + }; + }; + + named-gpios { + compatible = "named-gpios"; + + gpio_acc_int_l: acc_int_l { + gpios = <&gpio5 0 GPIO_INPUT>; + }; + gpio_all_sys_pwrgd: all_sys_pwrgd { + gpios = <&gpioa 7 GPIO_INPUT>; + }; + gpio_ccd_mode_odl: ccd_mode_odl { + gpios = <&gpioe 5 GPIO_INPUT>; + enum-name = "GPIO_CCD_MODE_ODL"; + }; + gpio_cpu_c10_gate_l: cpu_c10_gate_l { + gpios = <&gpio6 7 GPIO_INPUT>; + }; + gpio_ec_battery_pres_odl: ec_battery_pres_odl { + gpios = <&gpioa 3 GPIO_INPUT>; + enum-name = "GPIO_BATT_PRES_ODL"; + }; + gpio_ec_cbi_wp: ec_cbi_wp { + gpios = <&gpio7 4 GPIO_OUTPUT>; + }; + gpio_ec_edp_bl_en_od: ec_edp_bl_en_od { + gpios = <&gpiod 3 GPIO_ODR_HIGH>; + enum-name = "GPIO_ENABLE_BACKLIGHT"; + }; + gpio_ec_entering_rw: ec_entering_rw { + gpios = <&gpio0 3 GPIO_OUTPUT>; + enum-name = "GPIO_ENTERING_RW"; + }; + gpio_ec_gsc_packet_mode: ec_gsc_packet_mode { + gpios = <&gpio7 5 GPIO_OUTPUT>; + enum-name = "GPIO_PACKET_MODE_EN"; + }; + gpio_ec_kso_02_inv: ec_kso_02_inv { + gpios = <&gpio1 7 (GPIO_OUTPUT | GPIO_ACTIVE_LOW)>; + }; + gpio_ec_pch_wake_odl: ec_pch_wake_odl { + gpios = <&gpiob 0 GPIO_ODR_LOW>; + }; + gpio_ec_prochot_odl: ec_prochot_odl { + gpios = <&gpiof 1 GPIO_ODR_HIGH>; + }; + gpio_ec_soc_dsw_pwrok: ec_soc_dsw_pwrok { + gpios = <&gpio6 1 GPIO_OUTPUT>; + }; + gpio_ec_acok_otg_c1: ec_acok_otg_c1 { + gpios = <&gpioe 4 GPIO_OUTPUT>; + }; + gpio_ec_soc_int_odl: ec_soc_int_odl { + gpios = <&gpio8 0 GPIO_ODR_HIGH>; + enum-name = "GPIO_EC_INT_L"; + }; + gpio_ec_soc_pch_pwrok_od: ec_soc_pch_pwrok_od { + gpios = <&gpio7 2 GPIO_ODR_HIGH>; + }; + gpio_ec_soc_pwr_btn_odl: ec_soc_pwr_btn_odl { + gpios = <&gpioc 1 GPIO_ODR_HIGH>; + enum-name = "GPIO_PCH_PWRBTN_L"; + }; + gpio_ec_soc_rsmrst_l: ec_soc_rsmrst_l { + gpios = <&gpioa 6 GPIO_OUTPUT>; + }; + gpio_ec_soc_rtcrst: ec_soc_rtcrst { + gpios = <&gpio7 6 GPIO_OUTPUT>; + }; + gpio_ec_soc_sys_pwrok: ec_soc_sys_pwrok { + gpios = <&gpio3 7 GPIO_OUTPUT>; + }; + gpio_ec_soc_vccst_pwrgd_od: ec_soc_vccst_pwrgd_od { + gpios = <&gpioa 4 GPIO_ODR_HIGH>; + }; + gpio_ec_wp_odl: ec_wp_odl { + gpios = <&gpioa 1 (GPIO_INPUT | GPIO_ACTIVE_LOW)>; + }; + gpio_en_pp3300_s5: en_pp3300_s5 { + gpios = <&gpiob 6 GPIO_OUTPUT>; + enum-name = "GPIO_TEMP_SENSOR_POWER"; + }; + gpio_en_pp5000_pen_x: en_pp5000_pen_x { + gpios = <&gpioe 2 GPIO_OUTPUT>; + }; + gpio_en_pp5000_s5: en_pp5000_s5 { + gpios = <&gpio4 0 GPIO_OUTPUT>; + }; + gpio_en_slp_z: en_slp_z { + gpios = <&gpioe 1 GPIO_OUTPUT>; + }; + gpio_en_usb_a0_vbus: en_usb_a0_vbus { + gpios = <&gpio9 1 GPIO_OUTPUT>; + }; + gpio_gsc_ec_pwr_btn_odl: gsc_ec_pwr_btn_odl { + gpios = <&gpio0 0 GPIO_INPUT_PULL_UP>; + enum-name = "GPIO_POWER_BUTTON_L"; + }; + gpio_ec_acok_otg_c0: ec_acok_otg_c0 { + gpios = <&gpioc 6 GPIO_OUTPUT>; + }; + gpio_imu_int_l: imu_int_l { + gpios = <&gpio5 6 GPIO_INPUT>; + }; + gpio_imvp91_vrrdy_od: imvp91_vrrdy_od { + gpios = <&gpio4 3 GPIO_INPUT>; + }; + gpio_lid_open: lid_open { + gpios = <&gpiod 2 GPIO_INPUT>; + enum-name = "GPIO_LID_OPEN"; + }; + gpio_pen_detect_odl: pen_detect_odl { + gpios = <&gpio9 6 GPIO_INPUT_PULL_UP>; + }; + gpio_pg_pp1050_mem_s3_od: pg_pp1050_mem_s3_od { + gpios = <&gpiof 0 GPIO_INPUT>; + }; + gpio_pg_pp5000_s5_od: pg_pp5000_s5_od { + gpios = <&gpio4 2 GPIO_INPUT>; + }; + gpio_rsmrst_pwrgd_l: rsmrst_pwrgd_l { + gpios = <&gpio9 4 GPIO_INPUT_PULL_UP>; + }; + gpio_slp_s0_l: slp_s0_l { + gpios = <&gpio9 7 GPIO_INPUT>; + }; + gpio_slp_s3_l: slp_s3_l { + gpios = <&gpioa 5 GPIO_INPUT>; + }; + gpio_slp_s4_l: slp_s4_l { + gpios = <&gpio7 0 GPIO_INPUT>; + }; + gpio_slp_sus_l: slp_sus_l { + gpios = <&gpio6 2 GPIO_INPUT>; + }; + gpio_sub_usb_a1_ilimit_sdp: sub_usb_a1_ilimit_sdp { + gpios = <&gpiod 5 GPIO_OUTPUT>; + enum-name = "GPIO_USB2_ILIM_SEL"; + }; + gpio_sys_rst_odl: sys_rst_odl { + gpios = <&gpioc 5 GPIO_ODR_HIGH>; + }; + gpio_tablet_mode_l: tablet_mode_l { + gpios = <&gpio9 5 GPIO_INPUT>; + enum-name = "GPIO_TABLET_MODE_L"; + }; + gpio_usb_a0_ilimit_sdp: usb_a0_ilimit_sdp { + gpios = <&gpio3 3 GPIO_OUTPUT>; + enum-name = "GPIO_USB1_ILIM_SEL"; + }; + gpio_usb_c0_int_odl: usb_c0_int_odl { + gpios = <&gpio0 1 GPIO_INPUT_PULL_UP>; + }; + gpio_vccin_aux_vid0: vccin_aux_vid0 { + gpios = <&gpio9 2 GPIO_INPUT>; + }; + gpio_vccin_aux_vid1: vccin_aux_vid1 { + gpios = <&gpioe 3 GPIO_INPUT>; + }; + gpio_voldn_btn_odl: voldn_btn_odl { + gpios = <&gpioa 2 GPIO_INPUT_PULL_UP>; + enum-name = "GPIO_VOLUME_DOWN_L"; + }; + gpio_volup_btn_odl: volup_btn_odl { + gpios = <&gpio9 3 GPIO_INPUT_PULL_UP>; + enum-name = "GPIO_VOLUME_UP_L"; + }; + }; + + named-i2c-ports { + compatible = "named-i2c-ports"; + + i2c_ec_i2c_eeprom: ec_i2c_eeprom { + i2c-port = <&i2c0_0>; + enum-names = "I2C_PORT_EEPROM"; + }; + i2c_ec_i2c_sensor: ec_i2c_sensor { + i2c-port = <&i2c1_0>; + enum-names = "I2C_PORT_SENSOR"; + }; + i2c_ec_i2c_usb_c0: ec_i2c_usb_c0 { + i2c-port = <&i2c3_0>; + enum-names = "I2C_PORT_USB_C0_TCPC"; + }; + i2c_ec_i2c_sub_usb_c1: ec_i2c_sub_usb_c1 { + i2c-port = <&i2c5_1>; + enum-names = "I2C_PORT_USB_C1_TCPC"; + }; + i2c_ec_i2c_batt: ec_i2c_batt { + i2c-port = <&i2c7_0>; + enum-names = "I2C_PORT_BATTERY"; + }; + }; +}; + +&adc0 { + status = "okay"; + pinctrl-0 = <&adc0_chan0_gp45 + &adc0_chan1_gp44 + &adc0_chan4_gp41 + &adc0_chan6_gp34 + &adc0_chan10_gpe0 + &adc0_chan11_gpc7>; + pinctrl-names = "default"; +}; + +&i2c0_0 { + status = "okay"; + pinctrl-0 = <&i2c0_0_sda_scl_gpb4_b5>; + pinctrl-names = "default"; +}; + +&i2c1_0 { + status = "okay"; + pinctrl-0 = <&i2c1_0_sda_scl_gp87_90>; + pinctrl-names = "default"; +}; + +&i2c3_0 { + status = "okay"; + pinctrl-0 = <&i2c3_0_sda_scl_gpd0_d1>; + pinctrl-names = "default"; +}; + +&i2c5_1 { + status = "okay"; + pinctrl-0 = <&i2c5_1_sda_scl_gpf4_f5>; + pinctrl-names = "default"; +}; + +&i2c7_0 { + status = "okay"; + pinctrl-0 = <&i2c7_0_sda_scl_gpb2_b3>; + pinctrl-names = "default"; +}; + +&i2c_ctrl0 { + status = "okay"; +}; + +&i2c_ctrl1 { + status = "okay"; +}; + +&i2c_ctrl3 { + status = "okay"; +}; + +&i2c_ctrl5 { + status = "okay"; +}; + +&i2c_ctrl7 { + status = "okay"; +}; diff --git a/zephyr/projects/nissa/xivu/keyboard.dtsi b/zephyr/projects/nissa/xivu/keyboard.dtsi new file mode 100644 index 0000000000..5248c4aaff --- /dev/null +++ b/zephyr/projects/nissa/xivu/keyboard.dtsi @@ -0,0 +1,34 @@ +/* Copyright 2022 The ChromiumOS Authors + * Use of this source code is governed by a BSD-style license that can be + * found in the LICENSE file. + */ + +&cros_kb_raw { + status = "okay"; + /* No KSO2 (it's inverted and implemented by GPIO) */ + pinctrl-0 = < + &ksi0_gp31 + &ksi1_gp30 + &ksi2_gp27 + &ksi3_gp26 + &ksi4_gp25 + &ksi5_gp24 + &ksi6_gp23 + &ksi7_gp22 + &kso00_gp21 + &kso01_gp20 + &kso03_gp16 + &kso04_gp15 + &kso05_gp14 + &kso06_gp13 + &kso07_gp12 + &kso08_gp11 + &kso09_gp10 + &kso10_gp07 + &kso11_gp06 + &kso12_gp05 + &kso13_gp04 + &kso14_gp82 + >; + pinctrl-names = "default"; +}; diff --git a/zephyr/projects/nissa/xivu/led_pins.dtsi b/zephyr/projects/nissa/xivu/led_pins.dtsi new file mode 100644 index 0000000000..d85004a0c9 --- /dev/null +++ b/zephyr/projects/nissa/xivu/led_pins.dtsi @@ -0,0 +1,94 @@ +/* Copyright 2022 The ChromiumOS Authors + * Use of this source code is governed by a BSD-style license that can be + * found in the LICENSE file. + */ + +/ { + pwm_pins { + compatible = "cros-ec,pwm-pin-config"; + pwm_led_y_c0: pwm_led_y_c0 { + #led-pin-cells = <1>; + pwms = <&pwm2 0 PWM_HZ(324) PWM_POLARITY_INVERTED>; + }; + + pwm_led_w_c0: pwm_led_w_c0 { + #led-pin-cells = <1>; + pwms = <&pwm0 0 PWM_HZ(324) PWM_POLARITY_INVERTED>; + }; + + pwm_led_y_c1: pwm_led_y_c1 { + #led-pin-cells = <1>; + pwms = <&pwm6 0 PWM_HZ(324) PWM_POLARITY_INVERTED>; + }; + + pwm_led_w_c1: pwm_led_w_c1 { + #led-pin-cells = <1>; + pwms = <&pwm1 0 PWM_HZ(324) PWM_POLARITY_INVERTED>; + }; + }; + + pwm-led-pins { + compatible = "cros-ec,pwm-led-pins"; + + color_off: color-off { + led-color = "LED_OFF"; + led-id = "EC_LED_ID_BATTERY_LED"; + led-pins = <&pwm_led_y_c0 0>, + <&pwm_led_y_c1 0>, + <&pwm_led_w_c0 0>, + <&pwm_led_w_c1 0>; + }; + + color_amber: color-amber { + led-color = "LED_AMBER"; + led-id = "EC_LED_ID_BATTERY_LED"; + br-color = "EC_LED_COLOR_AMBER"; + led-pins = <&pwm_led_y_c0 1>, + <&pwm_led_y_c1 1>, + <&pwm_led_w_c0 0>, + <&pwm_led_w_c1 0>; + }; + + color_white: color-white { + led-color = "LED_WHITE"; + led-id = "EC_LED_ID_BATTERY_LED"; + br-color = "EC_LED_COLOR_WHITE"; + led-pins = <&pwm_led_y_c0 0>, + <&pwm_led_y_c1 0>, + <&pwm_led_w_c0 1>, + <&pwm_led_w_c1 1>; + }; + }; +}; + +/* LED2 */ +&pwm0 { + status = "okay"; + clock-bus = "NPCX_CLOCK_BUS_LFCLK"; + pinctrl-0 = <&pwm0_gpc3>; + pinctrl-names = "default"; +}; + +/* LED3 */ +&pwm1 { + status = "okay"; + clock-bus = "NPCX_CLOCK_BUS_LFCLK"; + pinctrl-0 = <&pwm1_gpc2>; + pinctrl-names = "default"; +}; + +/* LED1 */ +&pwm2 { + status = "okay"; + clock-bus = "NPCX_CLOCK_BUS_LFCLK"; + pinctrl-0 = <&pwm2_gpc4>; + pinctrl-names = "default"; +}; + +/* LED0 */ +&pwm6 { + status = "okay"; + clock-bus = "NPCX_CLOCK_BUS_LFCLK"; + pinctrl-0 = <&pwm6_gpc0>; + pinctrl-names = "default"; +}; diff --git a/zephyr/projects/nissa/xivu/led_policy.dtsi b/zephyr/projects/nissa/xivu/led_policy.dtsi new file mode 100644 index 0000000000..562e361ec5 --- /dev/null +++ b/zephyr/projects/nissa/xivu/led_policy.dtsi @@ -0,0 +1,122 @@ +/ { + led-colors { + compatible = "cros-ec,led-policy"; + + power-state-charge { + charge-state = "PWR_STATE_CHARGE"; + /* Battery percent range (>= Empty, <= 94%) */ + batt-lvl = <0 94>; + + color-0 { + led-color = <&color_amber>; + }; + }; + + power-state-charge-lvl-2 { + charge-state = "PWR_STATE_CHARGE"; + /* Battery percent range (>= 95%, <= Near Full) */ + batt-lvl = <95 97>; + + color-0 { + led-color = <&color_white>; + }; + }; + + power-state-near-full { + charge-state = "PWR_STATE_CHARGE_NEAR_FULL"; + + color-0 { + led-color = <&color_white>; + }; + }; + + power-state-discharge-s0 { + charge-state = "PWR_STATE_DISCHARGE"; + chipset-state = "POWER_S0"; + /* Battery percent range (>= 11%, <= Full) */ + batt-lvl = <11 100>; + + color-0 { + led-color = <&color_white>; + }; + }; + + power-state-discharge-s3 { + charge-state = "PWR_STATE_DISCHARGE"; + chipset-state = "POWER_S3"; + + /* White 1 sec, off 3 sec */ + color-0 { + led-color = <&color_white>; + period-ms = <1000>; + }; + color-1 { + led-color = <&color_off>; + period-ms = <3000>; + }; + }; + + power-state-discharge-s5 { + charge-state = "PWR_STATE_DISCHARGE"; + chipset-state = "POWER_S5"; + + color-0 { + led-color = <&color_off>; + }; + }; + + power-state-discharge-s0-batt-low { + charge-state = "PWR_STATE_DISCHARGE"; + chipset-state = "POWER_S0"; + /* Battery percent range (>= Empty, <= 10%) */ + batt-lvl = <0 10>; + + /* Amber 1 sec, off 3 sec */ + color-0 { + led-color = <&color_amber>; + period-ms = <1000>; + }; + color-1 { + led-color = <&color_off>; + period-ms = <3000>; + }; + }; + + power-state-error-s0 { + charge-state = "PWR_STATE_ERROR"; + chipset-state = "POWER_S0"; + /* Amber 1 sec, off 1 sec */ + color-0 { + led-color = <&color_amber>; + period-ms = <1000>; + }; + color-1 { + led-color = <&color_off>; + period-ms = <1000>; + }; + }; + + power-state-error-s3 { + charge-state = "PWR_STATE_ERROR"; + chipset-state = "POWER_S3"; + /* White 1 sec, off 3 sec */ + color-0 { + led-color = <&color_white>; + period-ms = <1000>; + }; + color-1 { + led-color = <&color_off>; + period-ms = <3000>; + }; + }; + + power-state-error-s5 { + charge-state = "PWR_STATE_ERROR"; + chipset-state = "POWER_S5"; + + color-0 { + led-color = <&color_off>; + }; + }; + }; +}; diff --git a/zephyr/projects/nissa/xivu/motionsense.dtsi b/zephyr/projects/nissa/xivu/motionsense.dtsi new file mode 100644 index 0000000000..332252c4ef --- /dev/null +++ b/zephyr/projects/nissa/xivu/motionsense.dtsi @@ -0,0 +1,156 @@ +/* Copyright 2022 The ChromiumOS Authors + * Use of this source code is governed by a BSD-style license that can be + * found in the LICENSE file. + */ + +#include <dt-bindings/motionsense/utils.h> + + +/ { + aliases { + /* + * Interrupt bindings for sensor devices. + */ + lsm6dso-int = &base_accel; + lis2dw12-int = &lid_accel; + }; + + /* + * Declare mutexes used by sensor drivers. + * A mutex node is used to create an instance of mutex_t. + * A mutex node is referenced by a sensor node if the + * corresponding sensor driver needs to use the + * instance of the mutex. + */ + motionsense-mutex { + compatible = "cros-ec,motionsense-mutex"; + lid_mutex: lid-mutex { + }; + + base_mutex: base-mutex { + }; + }; + + /* Rotation matrix used by drivers. */ + motionsense-rotation-ref { + compatible = "cros-ec,motionsense-rotation-ref"; + lid_rot_ref: lid-rotation-ref { + mat33 = <0 1 0 + 1 0 0 + 0 0 (-1)>; + }; + + base_rot_ref: base-rotation-ref { + mat33 = <0 (-1) 0 + 1 0 0 + 0 0 1>; + }; + }; + + /* + * Driver specific data. A driver-specific data can be shared with + * different motion sensors while they are using the same driver. + * + * If a node's compatible starts with "cros-ec,accelgyro-", it is for + * a common structure defined in accelgyro.h. + * e.g) compatible = "cros-ec,accelgyro-als-drv-data" is for + * "struct als_drv_data_t" in accelgyro.h + */ + motionsense-sensor-data { + lsm6dso_accel_data: lsm6dso-accel-drv-data { + compatible = "cros-ec,drvdata-lsm6dso"; + status = "okay"; + }; + + lsm6dso_gyro_data: lsm6dso-gyro-drv-data { + compatible = "cros-ec,drvdata-lsm6dso"; + status = "okay"; + }; + + lis2dw12_data: lis2dw12-drv-data { + compatible = "cros-ec,drvdata-lis2dw12"; + status = "okay"; + }; + }; + + /* + * List of motion sensors that creates motion_sensors array. + * The nodelabel "lid_accel" and "base_accel" are used to indicate + * motion sensor IDs for lid angle calculation. + * TODO(b/238139272): The first entries of the array must be + * accelerometers,then gyroscope. Fix this dependency in the DTS + * processing which makes the devicetree entries independent. + */ + motionsense-sensor { + lid_accel: lid-accel { + compatible = "cros-ec,lis2dw12"; + status = "okay"; + + active-mask = "SENSOR_ACTIVE_S0_S3"; + location = "MOTIONSENSE_LOC_LID"; + mutex = <&lid_mutex>; + port = <&i2c_ec_i2c_sensor>; + rot-standard-ref = <&lid_rot_ref>; + default-range = <2>; + drv-data = <&lis2dw12_data>; + i2c-spi-addr-flags = "LIS2DWL_ADDR0_FLAGS"; + configs { + compatible = + "cros-ec,motionsense-sensor-config"; + ec-s0 { + odr = <(10000 | ROUND_UP_FLAG)>; + }; + ec-s3 { + odr = <(10000 | ROUND_UP_FLAG)>; + }; + }; + }; + + base_accel: base-accel { + compatible = "cros-ec,lsm6dso-accel"; + status = "okay"; + + active-mask = "SENSOR_ACTIVE_S0_S3"; + location = "MOTIONSENSE_LOC_BASE"; + mutex = <&base_mutex>; + port = <&i2c_ec_i2c_sensor>; + rot-standard-ref = <&base_rot_ref>; + drv-data = <&lsm6dso_accel_data>; + configs { + compatible = + "cros-ec,motionsense-sensor-config"; + ec-s0 { + odr = <(10000 | ROUND_UP_FLAG)>; + }; + ec-s3 { + odr = <(10000 | ROUND_UP_FLAG)>; + }; + }; + }; + + base_gyro: base-gyro { + compatible = "cros-ec,lsm6dso-gyro"; + status = "okay"; + + active-mask = "SENSOR_ACTIVE_S0_S3"; + location = "MOTIONSENSE_LOC_BASE"; + mutex = <&base_mutex>; + port = <&i2c_ec_i2c_sensor>; + rot-standard-ref = <&base_rot_ref>; + default-range = <(1000 | ROUND_UP_FLAG)>; /* dps */ + drv-data = <&lsm6dso_gyro_data>; + }; + }; + + motionsense-sensor-info { + compatible = "cros-ec,motionsense-sensor-info"; + + /* + * list of GPIO interrupts that have to + * be enabled at initial stage + */ + sensor-irqs = <&int_imu>; + /* list of sensors in force mode */ + accel-force-mode-sensors = <&lid_accel>; + }; +}; diff --git a/zephyr/projects/nissa/xivu/overlay.dtsi b/zephyr/projects/nissa/xivu/overlay.dtsi new file mode 100644 index 0000000000..de45db75e7 --- /dev/null +++ b/zephyr/projects/nissa/xivu/overlay.dtsi @@ -0,0 +1,357 @@ +/* Copyright 2022 The ChromiumOS Authors + * Use of this source code is governed by a BSD-style license that can be + * found in the LICENSE file. + */ + +#include <cros/thermistor/thermistor.dtsi> + +/ { + aliases { + gpio-cbi-wp = &gpio_ec_cbi_wp; + gpio-wp = &gpio_ec_wp_odl; + int-wp = &int_wp_l; + gpio-kbd-kso2 = &gpio_ec_kso_02_inv; + }; + + ec-console { + compatible = "ec-console"; + disabled = "events", "lpc", "hostcmd"; + }; + + batteries { + default_battery: smp_c31n2005 { + compatible = "smp,c31n2005", "battery-smart"; + }; + }; + + hibernate-wake-pins { + compatible = "cros-ec,hibernate-wake-pins"; + wakeup-irqs = < + &int_power_button + &int_lid_open + >; + }; + + gpio-interrupts { + compatible = "cros-ec,gpio-interrupts"; + + int_power_button: power_button { + irq-pin = <&gpio_gsc_ec_pwr_btn_odl>; + flags = <GPIO_INT_EDGE_BOTH>; + handler = "power_button_interrupt"; + }; + int_wp_l: wp_l { + irq-pin = <&gpio_ec_wp_odl>; + flags = <GPIO_INT_EDGE_BOTH>; + handler = "switch_interrupt"; + }; + int_lid_open: lid_open { + irq-pin = <&gpio_lid_open>; + flags = <GPIO_INT_EDGE_BOTH>; + handler = "lid_interrupt"; + }; + int_tablet_mode: tablet_mode { + irq-pin = <&gpio_tablet_mode_l>; + flags = <GPIO_INT_EDGE_BOTH>; + handler = "gmr_tablet_switch_isr"; + }; + int_imu: ec_imu { + irq-pin = <&gpio_imu_int_l>; + flags = <GPIO_INT_EDGE_FALLING>; + handler = "lsm6dso_interrupt"; + }; + int_vol_down: vol_down { + irq-pin = <&gpio_voldn_btn_odl>; + flags = <GPIO_INT_EDGE_BOTH>; + handler = "button_interrupt"; + }; + int_vol_up: vol_up { + irq-pin = <&gpio_volup_btn_odl>; + flags = <GPIO_INT_EDGE_BOTH>; + handler = "button_interrupt"; + }; + int_usb_c0: usb_c0 { + irq-pin = <&gpio_usb_c0_int_odl>; + flags = <GPIO_INT_EDGE_FALLING>; + handler = "usb_interrupt"; + }; + int_usb_c1: usb_c1 { + irq-pin = <&gpio_sb_1>; + flags = <GPIO_INT_EDGE_FALLING>; + handler = "usb_interrupt"; + }; + }; + + named-gpios { + gpio_sb_1: sb-1 { + gpios = <&gpio0 2 GPIO_PULL_UP>; + no-auto-init; + }; + + gpio_sb_2: sb-2 { + gpios = <&gpiod 4 GPIO_OUTPUT>; + no-auto-init; + }; + + /* + * Set I2C pins for type C sub-board to be low voltage (I2C5_1). + * We do this for all boards, since the pins are 3.3V tolerant, + * and the only 2 types of sub-boards used on nivviks both have + * type-C ports on them. + */ + gpio_sb_3: sb-3 { + gpios = <&gpiof 4 (GPIO_OPEN_DRAIN | GPIO_VOLTAGE_1P8)>; + no-auto-init; + }; + gpio_sb_4: sb-4 { + gpios = <&gpiof 5 (GPIO_INPUT | GPIO_VOLTAGE_1P8)>; + no-auto-init; + }; + }; + + /* + * Aliases used for sub-board GPIOs. + */ + aliases { + /* + * Input GPIO when used with type-C port 1 + */ + gpio-usb-c1-int-odl = &gpio_sb_1; + gpio-en-rails-odl = &gpio_sb_1; + /* + * Sub-board with type A USB, enable. + */ + gpio-en-usb-a1-vbus = &gpio_sb_2; + /* + * Enable S5 rails for LTE sub-board + */ + gpio-en-sub-s5-rails = &gpio_sb_2; + }; + + temp_memory: memory { + compatible = "cros-ec,temp-sensor-thermistor"; + thermistor = <&thermistor_3V3_51K1_47K_4050B>; + adc = <&adc_temp_sensor_1>; + }; + temp_ambient: ambient { + compatible = "cros-ec,temp-sensor-thermistor"; + thermistor = <&thermistor_3V3_51K1_47K_4050B>; + adc = <&adc_temp_sensor_2>; + }; + temp_charger1: charger1 { + compatible = "cros-ec,temp-sensor-thermistor"; + thermistor = <&thermistor_3V3_51K1_47K_4050B>; + adc = <&adc_temp_sensor_3>; + }; + temp_charger2: charger2 { + compatible = "cros-ec,temp-sensor-thermistor"; + thermistor = <&thermistor_3V3_51K1_47K_4050B>; + adc = <&adc_temp_sensor_4>; + }; + + named-temp-sensors { + compatible = "cros-ec,temp-sensors"; + memory { + temp_host_high = <85>; + temp_host_halt = <90>; + temp_host_release_high = <80>; + temp_host_release_halt = <80>; + power-good-pin = <&gpio_ec_soc_dsw_pwrok>; + sensor = <&temp_memory>; + }; + ambient { + temp_host_high = <85>; + temp_host_halt = <90>; + temp_host_release_high = <80>; + temp_host_release_halt = <80>; + power-good-pin = <&gpio_ec_soc_dsw_pwrok>; + sensor = <&temp_ambient>; + }; + charger1 { + temp_host_high = <85>; + temp_host_halt = <90>; + temp_host_release_high = <80>; + temp_host_release_halt = <80>; + power-good-pin = <&gpio_ec_soc_dsw_pwrok>; + sensor = <&temp_charger1>; + }; + charger2 { + temp_host_high = <85>; + temp_host_halt = <90>; + temp_host_release_high = <80>; + temp_host_release_halt = <80>; + power-good-pin = <&gpio_ec_soc_dsw_pwrok>; + sensor = <&temp_charger2>; + }; + }; + + usba { + compatible = "cros-ec,usba-port-enable-pins"; + /* + * sb_2 is only configured as GPIO when USB-A1 is present, + * but it's still safe to control when disabled. + * + * ILIM_SEL pins are referred to by legacy enum name, + * GPIO_USB*_ILIM_SEL. The one for port A1 is unused on + * sub-boards that don't have USB-A so is safe to control + * regardless of system configuration. + */ + enable-pins = <&gpio_en_usb_a0_vbus &gpio_sb_2>; + status = "okay"; + }; + + usbc { + #address-cells = <1>; + #size-cells = <0>; + + port0@0 { + compatible = "named-usbc-port"; + reg = <0>; + bc12 = <&bc12_port0>; + chg = <&chg_port0>; + usb-mux-chain-0 { + compatible = "cros-ec,usb-mux-chain"; + usb-muxes = <&virtual_mux_0>; + }; + }; + port0-muxes { + virtual_mux_0: virtual-mux-0 { + compatible = "cros-ec,usbc-mux-virtual"; + }; + }; + /* + * TODO(b:211693800): port1 may not be present on some + * sub-boards. + */ + port1@1 { + compatible = "named-usbc-port"; + reg = <1>; + bc12 = <&bc12_port1>; + chg = <&chg_port1>; + usb-mux-chain-1 { + compatible = "cros-ec,usb-mux-chain"; + usb-muxes = <&virtual_mux_1 &anx7483_mux_1>; + }; + usb_mux_chain_1_no_mux: usb-mux-chain-1-no-mux { + compatible = "cros-ec,usb-mux-chain"; + alternative-chain; + usb-muxes = <&virtual_mux_1>; + }; + }; + port1-muxes { + virtual_mux_1: virtual-mux-1 { + compatible = "cros-ec,usbc-mux-virtual"; + }; + }; + }; + + unused-pins { + compatible = "unused-gpios"; + unused-gpios = + <&gpio8 5 0>, + <&gpio3 6 0>, + <&gpiod 7 0>, + <&gpio6 0 0>, + <&gpiof 2 0>, + <&gpiof 3 0>; + }; +}; + +&thermistor_3V3_51K1_47K_4050B { + status = "okay"; +}; + +&adc_ec_vsense_pp3300_s5 { + /* + * Voltage divider on input has 47k upper and 220k lower legs with + * 2714 mV full-scale reading on the ADC. Apply the largest possible + * multiplier (without overflowing int32) to get the best possible + * approximation of the actual ratio, but derate by a factor of two to + * ensure unexpectedly high values won't overflow. + */ + mul = <(791261 / 2)>; + div = <(651975 / 2)>; +}; + +/* Set bus speeds for I2C */ +&i2c0_0 { + label = "I2C_EEPROM"; + clock-frequency = <I2C_BITRATE_FAST>; + + cbi_eeprom: eeprom@50 { + compatible = "atmel,at24"; + reg = <0x50>; + size = <2048>; + pagesize = <16>; + address-width = <8>; + timeout = <5>; + }; +}; + +&i2c1_0 { + label = "I2C_SENSOR"; + clock-frequency = <I2C_BITRATE_FAST>; +}; + +&i2c3_0 { + label = "I2C_USB_C0_TCPC"; + clock-frequency = <I2C_BITRATE_FAST_PLUS>; + + bc12_port0: pi3usb9201@5f { + compatible = "pericom,pi3usb9201"; + status = "okay"; + reg = <0x5f>; + /* + * BC1.2 interrupt is shared with TCPC, so + * IRQ is not specified here and handled by + * usb_c0_interrupt. + */ + }; + + chg_port0: isl923x@9 { + compatible = "intersil,isl923x"; + status = "okay"; + reg = <0x9>; + }; +}; + +&i2c5_1 { + label = "I2C_SUB_C1_TCPC"; + clock-frequency = <I2C_BITRATE_FAST_PLUS>; + + bc12_port1: pi3usb9201@5f { + compatible = "pericom,pi3usb9201"; + status = "okay"; + reg = <0x5f>; + }; + + chg_port1: isl923x@9 { + compatible = "intersil,isl923x"; + status = "okay"; + reg = <0x9>; + }; + + anx7483_mux_1: anx7483-mux-1@3e { + compatible = "analogix,anx7483"; + reg = <0x3e>; + board-set = "anx7483_set_default_tuning"; + }; +}; + +&i2c7_0 { + label = "I2C_BATTERY"; + clock-frequency = <I2C_BITRATE_STANDARD>; +}; + +&pwm6 { + status = "okay"; + pinctrl-0 = <&pwm6_gpc0>; + pinctrl-names = "default"; +}; + +/* host interface */ +&espi0 { + status = "okay"; + pinctrl-0 = <&espi_lpc_gp46_47_51_52_53_54_55_57>; + pinctrl-names = "default"; +}; diff --git a/zephyr/projects/nissa/xivu/power_signals.dtsi b/zephyr/projects/nissa/xivu/power_signals.dtsi new file mode 100644 index 0000000000..1d2b23069d --- /dev/null +++ b/zephyr/projects/nissa/xivu/power_signals.dtsi @@ -0,0 +1,220 @@ +/* Copyright 2022 The ChromiumOS Authors + * Use of this source code is governed by a BSD-style license that can be + * found in the LICENSE file. + */ + +/ { + chosen { + intel-ap-pwrseq,espi = &espi0; + }; + + common-pwrseq { + compatible = "intel,ap-pwrseq"; + + sys-pwrok-delay = <10>; + all-sys-pwrgd-timeout = <20>; + }; + + pwr-en-pp5000-s5 { + compatible = "intel,ap-pwrseq-gpio"; + dbg-label = "PP5000_S5 enable output to regulator"; + enum-name = "PWR_EN_PP5000_A"; + gpios = <&gpio4 0 0>; + output; + }; + pwr-en-pp3300-s5 { + compatible = "intel,ap-pwrseq-gpio"; + dbg-label = "PP3300_S5 enable output to LS"; + enum-name = "PWR_EN_PP3300_A"; + gpios = <&gpiob 6 0>; + output; + }; + pwr-pg-ec-rsmrst-od { + compatible = "intel,ap-pwrseq-gpio"; + dbg-label = "RSMRST power good from regulator"; + enum-name = "PWR_RSMRST"; + gpios = <&gpio9 4 0>; + interrupt-flags = <GPIO_INT_EDGE_BOTH>; + }; + pwr-ec-pch-rsmrst-odl { + compatible = "intel,ap-pwrseq-gpio"; + dbg-label = "RSMRST output to PCH"; + enum-name = "PWR_EC_PCH_RSMRST"; + gpios = <&gpioa 6 0>; + output; + }; + pwr-slp-s0-l { + compatible = "intel,ap-pwrseq-gpio"; + dbg-label = "SLP_S0_L input from PCH"; + enum-name = "PWR_SLP_S0"; + gpios = <&gpio9 7 GPIO_ACTIVE_LOW>; + interrupt-flags = <GPIO_INT_EDGE_BOTH>; + }; + pwr-slp-s3-l { + compatible = "intel,ap-pwrseq-gpio"; + dbg-label = "SLP_S3_L input from PCH"; + enum-name = "PWR_SLP_S3"; + gpios = <&gpioa 5 GPIO_ACTIVE_LOW>; + interrupt-flags = <GPIO_INT_EDGE_BOTH>; + }; + pwr-slp-sus-l { + compatible = "intel,ap-pwrseq-gpio"; + dbg-label = "SLP_SUS_L input from PCH"; + enum-name = "PWR_SLP_SUS"; + gpios = <&gpio6 2 GPIO_ACTIVE_LOW>; + interrupt-flags = <GPIO_INT_EDGE_BOTH>; + }; + pwr-ec-soc-dsw-pwrok { + compatible = "intel,ap-pwrseq-gpio"; + dbg-label = "DSW_PWROK output to PCH"; + enum-name = "PWR_EC_SOC_DSW_PWROK"; + gpios = <&gpio6 1 0>; + output; + }; + pwr-vccst-pwrgd-od { + compatible = "intel,ap-pwrseq-gpio"; + dbg-label = "VCCST_PWRGD output to PCH"; + enum-name = "PWR_VCCST_PWRGD"; + gpios = <&gpioa 4 GPIO_OPEN_DRAIN>; + output; + }; + pwr-imvp9-vrrdy-od { + compatible = "intel,ap-pwrseq-gpio"; + dbg-label = "VRRDY input from IMVP9"; + enum-name = "PWR_IMVP9_VRRDY"; + gpios = <&gpio4 3 0>; + }; + pwr-pch-pwrok { + compatible = "intel,ap-pwrseq-gpio"; + dbg-label = "PCH_PWROK output to PCH"; + enum-name = "PWR_PCH_PWROK"; + gpios = <&gpio7 2 GPIO_OPEN_DRAIN>; + output; + }; + pwr-ec-pch-sys-pwrok { + compatible = "intel,ap-pwrseq-gpio"; + dbg-label = "SYS_PWROK output to PCH"; + enum-name = "PWR_EC_PCH_SYS_PWROK"; + gpios = <&gpio3 7 0>; + output; + }; + pwr-sys-rst-l { + compatible = "intel,ap-pwrseq-gpio"; + dbg-label = "SYS_RESET# output to PCH"; + enum-name = "PWR_SYS_RST"; + gpios = <&gpioc 5 (GPIO_ACTIVE_LOW|GPIO_OPEN_DRAIN)>; + output; + }; + pwr-slp-s4 { + compatible = "intel,ap-pwrseq-vw"; + dbg-label = "SLP_S4 virtual wire input from PCH"; + enum-name = "PWR_SLP_S4"; + virtual-wire = "ESPI_VWIRE_SIGNAL_SLP_S4"; + vw-invert; + }; + pwr-slp-s5 { + compatible = "intel,ap-pwrseq-vw"; + dbg-label = "SLP_S5 virtual wire input from PCH"; + enum-name = "PWR_SLP_S5"; + virtual-wire = "ESPI_VWIRE_SIGNAL_SLP_S5"; + vw-invert; + }; + pwr-all-sys-pwrgd { + compatible = "intel,ap-pwrseq-external"; + dbg-label = "Combined all power good"; + enum-name = "PWR_ALL_SYS_PWRGD"; + }; + pwr-adc-pp3300 { + compatible = "intel,ap-pwrseq-adc"; + dbg-label = "PP3300 PWROK (from ADC)"; + enum-name = "PWR_DSW_PWROK"; + trigger-high = <&cmp_pp3300_s5_high>; + trigger-low = <&cmp_pp3300_s5_low>; + }; + pwr-adc-pp1p05 { + compatible = "intel,ap-pwrseq-adc"; + dbg-label = "PP1P05 PWROK (from ADC)"; + enum-name = "PWR_PG_PP1P05"; + trigger-high = <&cmp_pp1p05_high>; + trigger-low = <&cmp_pp1p05_low>; + }; + + adc-cmp { + cmp_pp3300_s5_high: pp3300_high { + compatible = "nuvoton,adc-cmp"; + io-channels = <&adc0 6>; + comparison = "ADC_CMP_NPCX_GREATER"; + /* + * This is 90% of nominal voltage considering voltage + * divider on ADC input. + */ + threshold-mv = <2448>; + }; + cmp_pp3300_s5_low: pp3300_low { + compatible = "nuvoton,adc-cmp"; + io-channels = <&adc0 6>; + comparison = "ADC_CMP_NPCX_LESS_OR_EQUAL"; + threshold-mv = <2448>; + }; + cmp_pp1p05_high: pp1p05_high { + compatible = "nuvoton,adc-cmp"; + io-channels = <&adc0 4>; + comparison = "ADC_CMP_NPCX_GREATER"; + /* Setting at 90% of nominal voltage */ + threshold-mv = <945>; + }; + cmp_pp1p05_low: pp1p05_low { + compatible = "nuvoton,adc-cmp"; + io-channels = <&adc0 4>; + comparison = "ADC_CMP_NPCX_LESS_OR_EQUAL"; + threshold-mv = <945>; + }; + }; +}; + +/* + * Because the power signals directly reference the GPIOs, + * the correspinding named-gpios need to have no-auto-init set. + */ +&gpio_ec_soc_dsw_pwrok { + no-auto-init; +}; +&gpio_ec_soc_pch_pwrok_od { + no-auto-init; +}; +&gpio_ec_soc_rsmrst_l { + no-auto-init; +}; +&gpio_ec_soc_sys_pwrok { + no-auto-init; +}; +&gpio_ec_soc_vccst_pwrgd_od { + no-auto-init; +}; +&gpio_en_pp3300_s5 { + no-auto-init; +}; +&gpio_en_pp5000_s5 { + no-auto-init; +}; +&gpio_imvp91_vrrdy_od { + no-auto-init; +}; +&gpio_rsmrst_pwrgd_l { + no-auto-init; +}; +&gpio_slp_s0_l { + no-auto-init; +}; +&gpio_slp_s3_l { + no-auto-init; +}; +&gpio_slp_s4_l { + no-auto-init; +}; +&gpio_slp_sus_l { + no-auto-init; +}; +&gpio_sys_rst_odl { + no-auto-init; +}; diff --git a/zephyr/projects/nissa/xivu/project.conf b/zephyr/projects/nissa/xivu/project.conf new file mode 100644 index 0000000000..4ce9c635c3 --- /dev/null +++ b/zephyr/projects/nissa/xivu/project.conf @@ -0,0 +1,14 @@ +# Copyright 2022 The ChromiumOS Authors +# Use of this source code is governed by a BSD-style license that can be +# found in the LICENSE file. + +CONFIG_BOARD_XIVU=y +CONFIG_PLATFORM_EC_OCPC=y +CONFIG_PLATFORM_EC_ACCELGYRO_LSM6DSO=y + +# LED +CONFIG_PLATFORM_EC_LED_COMMON=n +CONFIG_PLATFORM_EC_LED_DT=y + +# USBC +CONFIG_PLATFORM_EC_PD_MAX_POWER_MW=45000 diff --git a/zephyr/projects/nissa/xivu/project.overlay b/zephyr/projects/nissa/xivu/project.overlay new file mode 100644 index 0000000000..a7c5b7e9e7 --- /dev/null +++ b/zephyr/projects/nissa/xivu/project.overlay @@ -0,0 +1,15 @@ +/* Copyright 2022 The ChromiumOS Authors + * Use of this source code is governed by a BSD-style license that can be + * found in the LICENSE file. + */ + +#include "../cbi.dtsi" + +#include "cbi.dtsi" +#include "generated.dtsi" +#include "keyboard.dtsi" +#include "led_pins.dtsi" +#include "led_policy.dtsi" +#include "motionsense.dtsi" +#include "overlay.dtsi" +#include "power_signals.dtsi" diff --git a/zephyr/projects/nissa/xivu/src/charger.c b/zephyr/projects/nissa/xivu/src/charger.c new file mode 100644 index 0000000000..5021a55758 --- /dev/null +++ b/zephyr/projects/nissa/xivu/src/charger.c @@ -0,0 +1,69 @@ +/* Copyright 2022 The ChromiumOS Authors + * Use of this source code is governed by a BSD-style license that can be + * found in the LICENSE file. + */ + +#include <zephyr/logging/log.h> + +#include "battery.h" +#include "charger.h" +#include "charger/isl923x_public.h" +#include "console.h" +#include "extpower.h" +#include "usb_pd.h" +#include "nissa_common.h" + +LOG_MODULE_DECLARE(nissa, CONFIG_NISSA_LOG_LEVEL); + +int extpower_is_present(void) +{ + int port; + int rv; + bool acok; + + for (port = 0; port < board_get_usb_pd_port_count(); port++) { + rv = raa489000_is_acok(port, &acok); + if ((rv == EC_SUCCESS) && acok) + return 1; + } + + return 0; +} + +/* + * Xivu does not have a GPIO indicating whether extpower is present, + * so detect using the charger(s). + */ +__override void board_check_extpower(void) +{ + static int last_extpower_present; + int extpower_present_p0 = 0; + int extpower_present_p1 = 0; + + int extpower_present = extpower_is_present(); + + if (last_extpower_present ^ extpower_present) + extpower_handle_update(extpower_present); + + last_extpower_present = extpower_present; + + if (pd_is_connected(0)) + extpower_present_p0 = extpower_is_present(); + else if (pd_is_connected(1)) + extpower_present_p1 = extpower_is_present(); + + gpio_pin_set_dt(GPIO_DT_FROM_NODELABEL(gpio_ec_acok_otg_c0), + extpower_present_p0); + gpio_pin_set_dt(GPIO_DT_FROM_NODELABEL(gpio_ec_acok_otg_c1), + extpower_present_p1); +} + +__override void board_hibernate(void) +{ + /* Shut down the chargers */ + if (board_get_usb_pd_port_count() == 2) + raa489000_hibernate(CHARGER_SECONDARY, true); + raa489000_hibernate(CHARGER_PRIMARY, true); + LOG_INF("Charger(s) hibernated"); + cflush(); +} diff --git a/zephyr/projects/nissa/xivu/src/keyboard.c b/zephyr/projects/nissa/xivu/src/keyboard.c new file mode 100644 index 0000000000..ef799fb1d2 --- /dev/null +++ b/zephyr/projects/nissa/xivu/src/keyboard.c @@ -0,0 +1,29 @@ +/* Copyright 2022 The ChromiumOS Authors + * Use of this source code is governed by a BSD-style license that can be + * found in the LICENSE file. + */ + +#include "ec_commands.h" + +static const struct ec_response_keybd_config xivu_kb_legacy = { + .num_top_row_keys = 10, + .action_keys = { + TK_BACK, /* T1 */ + TK_REFRESH, /* T2 */ + TK_FULLSCREEN, /* T3 */ + TK_OVERVIEW, /* T4 */ + TK_SNAPSHOT, /* T5 */ + TK_BRIGHTNESS_DOWN, /* T6 */ + TK_BRIGHTNESS_UP, /* T7 */ + TK_VOL_MUTE, /* 8 */ + 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) +{ + return &xivu_kb_legacy; +} diff --git a/zephyr/projects/nissa/xivu/src/usbc.c b/zephyr/projects/nissa/xivu/src/usbc.c new file mode 100644 index 0000000000..1520efaa55 --- /dev/null +++ b/zephyr/projects/nissa/xivu/src/usbc.c @@ -0,0 +1,285 @@ +/* Copyright 2022 The ChromiumOS Authors + * Use of this source code is governed by a BSD-style license that can be + * found in the LICENSE file. + */ + +#include <zephyr/logging/log.h> + +#include "charge_state_v2.h" +#include "chipset.h" +#include "hooks.h" +#include "usb_mux.h" +#include "system.h" +#include "driver/charger/isl923x_public.h" +#include "driver/retimer/anx7483_public.h" +#include "driver/tcpm/tcpci.h" +#include "driver/tcpm/raa489000.h" + +#include "nissa_common.h" + +LOG_MODULE_DECLARE(nissa, CONFIG_NISSA_LOG_LEVEL); + +struct tcpc_config_t tcpc_config[CONFIG_USB_PD_PORT_MAX_COUNT] = { + { + .bus_type = EC_BUS_TYPE_I2C, + .i2c_info = { + .port = I2C_PORT_USB_C0_TCPC, + .addr_flags = RAA489000_TCPC0_I2C_FLAGS, + }, + .drv = &raa489000_tcpm_drv, + /* RAA489000 implements TCPCI 2.0 */ + .flags = TCPC_FLAGS_TCPCI_REV2_0 | + TCPC_FLAGS_VBUS_MONITOR, + }, + { /* sub-board */ + .bus_type = EC_BUS_TYPE_I2C, + .i2c_info = { + .port = I2C_PORT_USB_C1_TCPC, + .addr_flags = RAA489000_TCPC0_I2C_FLAGS, + }, + .drv = &raa489000_tcpm_drv, + /* RAA489000 implements TCPCI 2.0 */ + .flags = TCPC_FLAGS_TCPCI_REV2_0 | + TCPC_FLAGS_VBUS_MONITOR, + }, +}; + +int board_is_sourcing_vbus(int port) +{ + int regval; + + tcpc_read(port, TCPC_REG_POWER_STATUS, ®val); + return !!(regval & TCPC_REG_POWER_STATUS_SOURCING_VBUS); +} + +int board_set_active_charge_port(int port) +{ + int is_real_port = (port >= 0 && port < CONFIG_USB_PD_PORT_MAX_COUNT); + int i; + int old_port; + + if (!is_real_port && port != CHARGE_PORT_NONE) + return EC_ERROR_INVAL; + + old_port = charge_manager_get_active_charge_port(); + + LOG_INF("New chg p%d", port); + + /* Disable all ports. */ + if (port == CHARGE_PORT_NONE) { + for (i = 0; i < CONFIG_USB_PD_PORT_MAX_COUNT; i++) { + tcpc_write(i, TCPC_REG_COMMAND, + TCPC_REG_COMMAND_SNK_CTRL_LOW); + raa489000_enable_asgate(i, false); + } + + return EC_SUCCESS; + } + + /* Check if port is sourcing VBUS. */ + if (board_is_sourcing_vbus(port)) { + LOG_WRN("Skip enable p%d", port); + return EC_ERROR_INVAL; + } + + /* + * Turn off the other ports' sink path FETs, before enabling the + * requested charge port. + */ + for (i = 0; i < CONFIG_USB_PD_PORT_MAX_COUNT; i++) { + if (i == port) + continue; + + if (tcpc_write(i, TCPC_REG_COMMAND, + TCPC_REG_COMMAND_SNK_CTRL_LOW)) + LOG_WRN("p%d: sink path disable failed.", i); + raa489000_enable_asgate(i, false); + } + + /* + * Stop the charger IC from switching while changing ports. Otherwise, + * we can overcurrent the adapter we're switching to. (crbug.com/926056) + */ + if (old_port != CHARGE_PORT_NONE) + charger_discharge_on_ac(1); + + /* Enable requested charge port. */ + if (raa489000_enable_asgate(port, true) || + tcpc_write(port, TCPC_REG_COMMAND, + TCPC_REG_COMMAND_SNK_CTRL_HIGH)) { + LOG_WRN("p%d: sink path enable failed.", port); + charger_discharge_on_ac(0); + return EC_ERROR_UNKNOWN; + } + + /* Allow the charger IC to begin/continue switching. */ + charger_discharge_on_ac(0); + + return EC_SUCCESS; +} + +uint16_t tcpc_get_alert_status(void) +{ + uint16_t status = 0; + int regval; + + /* + * The interrupt line is shared between the TCPC and BC1.2 detector IC. + * Therefore, go out and actually read the alert registers to report the + * alert status. + */ + if (!gpio_pin_get_dt(GPIO_DT_FROM_NODELABEL(gpio_usb_c0_int_odl))) { + if (!tcpc_read16(0, TCPC_REG_ALERT, ®val)) { + /* The TCPCI Rev 1.0 spec says to ignore bits 14:12. */ + if (!(tcpc_config[0].flags & TCPC_FLAGS_TCPCI_REV2_0)) + regval &= ~((1 << 14) | (1 << 13) | (1 << 12)); + + if (regval) + status |= PD_STATUS_TCPC_ALERT_0; + } + } + + if (board_get_usb_pd_port_count() == 2 && + !gpio_pin_get_dt(GPIO_DT_FROM_ALIAS(gpio_usb_c1_int_odl))) { + if (!tcpc_read16(1, TCPC_REG_ALERT, ®val)) { + /* TCPCI spec Rev 1.0 says to ignore bits 14:12. */ + if (!(tcpc_config[1].flags & TCPC_FLAGS_TCPCI_REV2_0)) + regval &= ~((1 << 14) | (1 << 13) | (1 << 12)); + + if (regval) + status |= PD_STATUS_TCPC_ALERT_1; + } + } + + return status; +} + +void pd_power_supply_reset(int port) +{ + /* Disable VBUS */ + tcpc_write(port, TCPC_REG_COMMAND, TCPC_REG_COMMAND_SRC_CTRL_LOW); + + /* Notify host of power info change. */ + pd_send_host_event(PD_EVENT_POWER_CHANGE); +} + +__override void typec_set_source_current_limit(int port, enum tcpc_rp_value rp) +{ + if (port < 0 || port >= CONFIG_USB_PD_PORT_MAX_COUNT) + return; + + raa489000_set_output_current(port, rp); +} + +int pd_set_power_supply_ready(int port) +{ + int rv; + + if (port >= CONFIG_USB_PD_PORT_MAX_COUNT) + return EC_ERROR_INVAL; + + /* Disable charging. */ + rv = tcpc_write(port, TCPC_REG_COMMAND, TCPC_REG_COMMAND_SNK_CTRL_LOW); + if (rv) + return rv; + + /* Our policy is not to source VBUS when the AP is off. */ + if (chipset_in_state(CHIPSET_STATE_ANY_OFF)) + return EC_ERROR_NOT_POWERED; + + /* Provide Vbus. */ + rv = tcpc_write(port, TCPC_REG_COMMAND, TCPC_REG_COMMAND_SRC_CTRL_HIGH); + if (rv) + return rv; + + rv = raa489000_enable_asgate(port, true); + if (rv) + return rv; + + /* Notify host of power info change. */ + pd_send_host_event(PD_EVENT_POWER_CHANGE); + + return EC_SUCCESS; +} + +void board_reset_pd_mcu(void) +{ + /* + * TODO(b:147316511): could send a reset command to the TCPC here + * if needed. + */ +} + +/* + * Because the TCPCs and BC1.2 chips share interrupt lines, it's possible + * for an interrupt to be lost if one asserts the IRQ, the other does the same + * then the first releases it: there will only be one falling edge to trigger + * the interrupt, and the line will be held low. We handle this by running a + * deferred check after a falling edge to see whether the IRQ is still being + * asserted. If it is, we assume an interrupt may have been lost and we need + * to poll each chip for events again. + */ +#define USBC_INT_POLL_DELAY_US 5000 + +static void poll_c0_int(void); +DECLARE_DEFERRED(poll_c0_int); +static void poll_c1_int(void); +DECLARE_DEFERRED(poll_c1_int); + +static void usbc_interrupt_trigger(int port) +{ + schedule_deferred_pd_interrupt(port); + usb_charger_task_set_event(port, USB_CHG_EVENT_BC12); +} + +static inline void poll_usb_gpio(int port, const struct gpio_dt_spec *gpio, + const struct deferred_data *ud) +{ + if (!gpio_pin_get_dt(gpio)) { + usbc_interrupt_trigger(port); + hook_call_deferred(ud, USBC_INT_POLL_DELAY_US); + } +} + +static void poll_c0_int(void) +{ + poll_usb_gpio(0, GPIO_DT_FROM_NODELABEL(gpio_usb_c0_int_odl), + &poll_c0_int_data); +} + +static void poll_c1_int(void) +{ + poll_usb_gpio(1, GPIO_DT_FROM_ALIAS(gpio_usb_c1_int_odl), + &poll_c1_int_data); +} + +void usb_interrupt(enum gpio_signal signal) +{ + int port; + const struct deferred_data *ud; + + if (signal == GPIO_SIGNAL(DT_NODELABEL(gpio_usb_c0_int_odl))) { + port = 0; + ud = &poll_c0_int_data; + } else { + port = 1; + ud = &poll_c1_int_data; + } + /* + * We've just been called from a falling edge, so there's definitely + * no lost IRQ right now. Cancel any pending check. + */ + hook_call_deferred(ud, -1); + /* Trigger polling of TCPC and BC1.2 in respective tasks */ + usbc_interrupt_trigger(port); + /* Check for lost interrupts in a bit */ + hook_call_deferred(ud, USBC_INT_POLL_DELAY_US); +} + +__override void board_set_charge_limit(int port, int supplier, int charge_ma, + int max_ma, int charge_mv) +{ + charge_ma = (charge_ma * 90) / 100; + charge_set_input_current_limit( + MAX(charge_ma, CONFIG_CHARGER_INPUT_CURRENT), charge_mv); +} diff --git a/zephyr/projects/nissa/yaviks/cbi.dtsi b/zephyr/projects/nissa/yaviks/cbi.dtsi new file mode 100644 index 0000000000..c5716cbd37 --- /dev/null +++ b/zephyr/projects/nissa/yaviks/cbi.dtsi @@ -0,0 +1,99 @@ +/* Copyright 2022 The ChromiumOS Authors + * Use of this source code is governed by a BSD-style license that can be + * found in the LICENSE file. + */ + +/ { + /* Yaviks-specific fw_config fields. */ + nissa-fw-config { + /* + * FW_CONFIG field for multiple wi-fi SAR. + * + * start = <2>; + * size = <2>; + */ + + /* + * FW_CONFIG field to enable fan or not. + */ + fan { + enum-name = "FW_FAN"; + start = <4>; + size = <1>; + + no-fan { + compatible = "cros-ec,cbi-fw-config-value"; + enum-name = "FW_FAN_NOT_PRESENT"; + value = <0>; + }; + fan-present { + compatible = "cros-ec,cbi-fw-config-value"; + enum-name = "FW_FAN_PRESENT"; + value = <1>; + /* + * Set as default so that unprovisioned + * configs will run the fan regardless. + */ + default; + }; + }; + + /* + * FW_CONFIG field to indicate which keyboard layout + * should be used. + */ + keyboard { + enum-name = "FW_KB_LAYOUT"; + start = <5>; + size = <1>; + + layout-1 { + compatible = "cros-ec,cbi-fw-config-value"; + enum-name = "FW_KB_LAYOUT_DEFAULT"; + value = <0>; + default; + }; + layout-2 { + compatible = "cros-ec,cbi-fw-config-value"; + enum-name = "FW_KB_LAYOUT_US2"; + value = <1>; + }; + }; + + /* + * FW_CONFIG field to indicate which keyboard layout + * should be used. + */ + keyboard-backlight { + enum-name = "FW_KB_BACKLIGHT"; + start = <6>; + size = <1>; + + without-keyboard-backlight { + compatible = "cros-ec,cbi-fw-config-value"; + enum-name = "FW_KB_BACKLIGHT_OFF"; + value = <1>; + }; + with-keyboard-backlight { + compatible = "cros-ec,cbi-fw-config-value"; + enum-name = "FW_KB_BACKLIGHT_ON"; + value = <0>; + default; + }; + }; + + /* + * FW_CONFIG field for multiple touch panel. + * + * start = <7>; + * size = <2>; + */ + + /* + * FW_CONFIG field for multiple storage. + * + * start = <31>; + * size = <1>; + */ + }; +}; diff --git a/zephyr/projects/nissa/yaviks/gpio.dtsi b/zephyr/projects/nissa/yaviks/gpio.dtsi new file mode 100644 index 0000000000..dae1d641cd --- /dev/null +++ b/zephyr/projects/nissa/yaviks/gpio.dtsi @@ -0,0 +1,232 @@ +/* + * Copyright 2022 The ChromiumOS Authors + * Use of this source code is governed by a BSD-style license that can be + * found in the LICENSE file. + */ + +/ { + + named-adc-channels { + compatible = "named-adc-channels"; + + adc_ec_vsense_pp1050_proc: ec_vsense_pp1050_proc { + enum-name = "ADC_PP1050_PROC"; + io-channels = <&adc0 14>; + }; + adc_ec_vsense_pp3300_s5: ec_vsense_pp3300_s5 { + enum-name = "ADC_PP3300_S5"; + io-channels = <&adc0 0>; + }; + adc_temp_sensor_1: temp_sensor_1 { + enum-name = "ADC_TEMP_SENSOR_1"; + io-channels = <&adc0 2>; + }; + adc_temp_sensor_2: temp_sensor_2 { + enum-name = "ADC_TEMP_SENSOR_2"; + io-channels = <&adc0 3>; + }; + adc_temp_sensor_3: temp_sensor_3 { + enum-name = "ADC_TEMP_SENSOR_3"; + io-channels = <&adc0 13>; + }; + }; + + named-gpios { + compatible = "named-gpios"; + + gpio_all_sys_pwrgd: all_sys_pwrgd { + gpios = <&gpiob 7 GPIO_INPUT>; + }; + gpio_ccd_mode_odl: ccd_mode_odl { + gpios = <&gpioh 5 GPIO_INPUT>; + enum-name = "GPIO_CCD_MODE_ODL"; + }; + gpio_cpu_c10_gate_l: cpu_c10_gate_l { + gpios = <&gpiog 1 GPIO_INPUT>; + }; + gpio_ec_battery_pres_odl: ec_battery_pres_odl { + gpios = <&gpioi 4 GPIO_INPUT>; + enum-name = "GPIO_BATT_PRES_ODL"; + }; + gpio_ec_cbi_wp: ec_cbi_wp { + gpios = <&gpioj 5 GPIO_OUTPUT>; + }; + gpio_ec_edp_bl_en_od: ec_edp_bl_en_od { + gpios = <&gpiok 4 GPIO_ODR_HIGH>; + enum-name = "GPIO_ENABLE_BACKLIGHT"; + }; + gpio_ec_entering_rw: ec_entering_rw { + gpios = <&gpioc 7 GPIO_OUTPUT>; + enum-name = "GPIO_ENTERING_RW"; + }; + gpio_ec_gsc_packet_mode: ec_gsc_packet_mode { + gpios = <&gpioh 1 GPIO_OUTPUT>; + enum-name = "GPIO_PACKET_MODE_EN"; + }; + gpio_ec_pch_wake_odl: ec_pch_wake_odl { + gpios = <&gpiob 2 GPIO_ODR_LOW>; + }; + gpio_ec_prochot_odl: ec_prochot_odl { + gpios = <&gpioi 1 (GPIO_ODR_HIGH | GPIO_VOLTAGE_1P8)>; + }; + gpio_ec_soc_dsw_pwrok: ec_soc_dsw_pwrok { + gpios = <&gpiol 7 GPIO_OUTPUT>; + no-auto-init; + }; + gpio_ec_soc_int_odl: ec_soc_int_odl { + gpios = <&gpiod 5 GPIO_ODR_HIGH>; + enum-name = "GPIO_EC_INT_L"; + }; + gpio_ec_soc_pch_pwrok_od: ec_soc_pch_pwrok_od { + gpios = <&gpiod 6 GPIO_ODR_HIGH>; + no-auto-init; + }; + gpio_ec_soc_pwr_btn_odl: ec_soc_pwr_btn_odl { + gpios = <&gpiob 6 GPIO_ODR_HIGH>; + enum-name = "GPIO_PCH_PWRBTN_L"; + }; + gpio_ec_soc_rsmrst_l: ec_soc_rsmrst_l { + gpios = <&gpioh 0 GPIO_OUTPUT>; + no-auto-init; + }; + gpio_ec_soc_rtcrst: ec_soc_rtcrst { + gpios = <&gpiok 2 GPIO_OUTPUT>; + }; + gpio_ec_soc_sys_pwrok: ec_soc_sys_pwrok { + gpios = <&gpiof 2 GPIO_OUTPUT>; + no-auto-init; + }; + gpio_ec_soc_vccst_pwrgd_od: ec_soc_vccst_pwrgd_od { + gpios = <&gpioe 5 GPIO_ODR_HIGH>; + no-auto-init; + }; + gpio_ec_wp_odl: ec_wp_odl { + gpios = <&gpioa 6 (GPIO_INPUT | GPIO_ACTIVE_LOW)>; + }; + gpio_en_pp3300_s5: en_pp3300_s5 { + gpios = <&gpioc 5 GPIO_OUTPUT>; + enum-name = "GPIO_TEMP_SENSOR_POWER"; + no-auto-init; + }; + gpio_en_pp5000_pen_x: en_pp5000_pen_x { + gpios = <&gpiob 5 GPIO_OUTPUT>; + }; + gpio_en_pp5000_s5: en_pp5000_s5 { + gpios = <&gpiok 5 GPIO_OUTPUT>; + no-auto-init; + }; + gpio_en_slp_z: en_slp_z { + gpios = <&gpiok 3 GPIO_OUTPUT>; + }; + gpio_en_usb_a0_vbus: en_usb_a0_vbus { + gpios = <&gpiol 6 GPIO_OUTPUT>; + }; + gpio_en_usb_c0_cc1_vconn: en_usb_c0_cc1_vconn { + gpios = <&gpioh 4 GPIO_OUTPUT>; + }; + gpio_en_usb_c0_cc2_vconn: en_usb_c0_cc2_vconn { + gpios = <&gpioh 6 GPIO_OUTPUT>; + }; + gpio_gsc_ec_pwr_btn_odl: gsc_ec_pwr_btn_odl { + gpios = <&gpioe 2 GPIO_INPUT_PULL_UP>; + enum-name = "GPIO_POWER_BUTTON_L"; + }; + gpio_imvp91_vrrdy_od: imvp91_vrrdy_od { + gpios = <&gpioj 4 GPIO_INPUT>; + no-auto-init; + }; + gpio_lid_open: lid_open { + gpios = <&gpiof 3 GPIO_INPUT>; + enum-name = "GPIO_LID_OPEN"; + }; + gpio_pen_detect_odl: pen_detect_odl { + gpios = <&gpioj 1 GPIO_INPUT_PULL_UP>; + }; + gpio_pg_pp1050_mem_s3_od: pg_pp1050_mem_s3_od { + gpios = <&gpiod 3 GPIO_INPUT>; + }; + gpio_pg_pp5000_s5_od: pg_pp5000_s5_od { + gpios = <&gpioe 3 GPIO_INPUT>; + }; + gpio_rsmrst_pwrgd_l: rsmrst_pwrgd_l { + gpios = <&gpioe 1 GPIO_INPUT_PULL_UP>; + no-auto-init; + }; + gpio_slp_s0_l: slp_s0_l { + gpios = <&gpioe 4 GPIO_INPUT>; + no-auto-init; + }; + gpio_slp_s3_l: slp_s3_l { + gpios = <&gpioh 3 GPIO_INPUT>; + no-auto-init; + }; + gpio_slp_s4_l: slp_s4_l { + gpios = <&gpioi 5 GPIO_INPUT>; + }; + gpio_slp_sus_l: slp_sus_l { + gpios = <&gpiog 2 GPIO_INPUT>; + no-auto-init; + }; + gpio_sub_usb_a1_ilimit_sdp: sub_usb_a1_ilimit_sdp { + gpios = <&gpiof 1 GPIO_OUTPUT>; + enum-name = "GPIO_USB2_ILIM_SEL"; + }; + gpio_sys_rst_odl: sys_rst_odl { + gpios = <&gpiod 1 GPIO_ODR_HIGH>; + no-auto-init; + }; + gpio_usb_a0_ilimit_sdp: usb_a0_ilimit_sdp { + gpios = <&gpiol 5 GPIO_OUTPUT>; + enum-name = "GPIO_USB1_ILIM_SEL"; + }; + gpio_usb_c0_frs: usb_c0_frs { + gpios = <&gpioc 4 GPIO_OUTPUT>; + }; + gpio_usb_c0_int_odl: usb_c0_int_odl { + gpios = <&gpiok 0 GPIO_INPUT_PULL_UP>; + }; + gpio_vccin_aux_vid0: vccin_aux_vid0 { + gpios = <&gpiod 0 (GPIO_INPUT | GPIO_VOLTAGE_1P8)>; + }; + gpio_vccin_aux_vid1: vccin_aux_vid1 { + gpios = <&gpiok 1 (GPIO_INPUT | GPIO_VOLTAGE_1P8)>; + }; + gpio_c1_charger_led_white_l: c1_charger_led_white_l { + gpios = <&gpiol 4 GPIO_OUTPUT_HIGH>; + }; + gpio_c1_charger_led_amber_l: c1_charger_led_amber_l { + gpios = <&gpiod 4 GPIO_OUTPUT_HIGH>; + }; + gpio_c0_charger_led_white_l: c0_charger_led_white_l { + gpios = <&gpioc 3 GPIO_OUTPUT_HIGH>; + }; + gpio_c0_charger_led_amber_l: c0_charger_led_amber_l { + gpios = <&gpioj 7 GPIO_OUTPUT_HIGH>; + }; + }; + + named-i2c-ports { + compatible = "named-i2c-ports"; + + i2c_ec_i2c_eeprom: ec_i2c_eeprom { + i2c-port = <&i2c0>; + enum-names = "I2C_PORT_EEPROM"; + }; + i2c_ec_i2c_batt: ec_i2c_batt { + i2c-port = <&i2c1>; + enum-names = "I2C_PORT_BATTERY"; + }; + i2c_ec_i2c_sensor: ec_i2c_sensor { + i2c-port = <&i2c2>; + enum-names = "I2C_PORT_SENSOR"; + }; + i2c_ec_i2c_sub_usb_c1: ec_i2c_sub_usb_c1 { + i2c-port = <&i2c4>; + enum-names = "I2C_PORT_USB_C1_TCPC"; + }; + i2c_ec_i2c_usb_c0: ec_i2c_usb_c0 { + i2c-port = <&i2c5>; + enum-names = "I2C_PORT_USB_C0_TCPC"; + }; + }; +}; diff --git a/zephyr/projects/nissa/yaviks/keyboard.dtsi b/zephyr/projects/nissa/yaviks/keyboard.dtsi new file mode 100644 index 0000000000..04a620767a --- /dev/null +++ b/zephyr/projects/nissa/yaviks/keyboard.dtsi @@ -0,0 +1,22 @@ +/* Copyright 2022 The ChromiumOS Authors + * Use of this source code is governed by a BSD-style license that can be + * found in the LICENSE file. + */ + +/ { + kblight { + compatible = "cros-ec,kblight-pwm"; + /* + * Use 324 Hz so that 32Khz clock source is used, + * which is not gated in power saving mode. + */ + pwms = <&pwm0 0 PWM_HZ(324) PWM_POLARITY_NORMAL>; + }; +}; + +&pwm0 { + status = "okay"; + prescaler-cx = <PWM_PRESCALER_C4>; + pinctrl-0 = <&pwm0_gpa0_default>; + pinctrl-names = "default"; +}; diff --git a/zephyr/projects/nissa/yaviks/overlay.dtsi b/zephyr/projects/nissa/yaviks/overlay.dtsi new file mode 100644 index 0000000000..d768116444 --- /dev/null +++ b/zephyr/projects/nissa/yaviks/overlay.dtsi @@ -0,0 +1,402 @@ +/* Copyright 2022 The ChromiumOS Authors + * Use of this source code is governed by a BSD-style license that can be + * found in the LICENSE file. + */ + +#include <cros/thermistor/thermistor.dtsi> + +/ { + aliases { + gpio-cbi-wp = &gpio_ec_cbi_wp; + gpio-wp = &gpio_ec_wp_odl; + int-wp = &int_wp_l; + /* + * USB-C: interrupt input. + * I2C pins are on i2c_ec_i2c_sub_usb_c1 + */ + gpio-usb-c1-int-odl = &gpio_sb_1; + /* + * USB-A: VBUS enable output + * LTE: power enable output + */ + gpio-en-usb-a1-vbus = &gpio_sb_2; + /* + * Enable S5 rails for LTE sub-board + */ + gpio-en-sub-s5-rails = &gpio_sb_2; + }; + + ec-console { + compatible = "ec-console"; + disabled = "events", "lpc", "hostcmd"; + }; + + batteries { + default_battery: cosmx { + compatible = "cosmx,gh02047xl", "battery-smart"; + }; + dynapack_atl_gh02047xl { + compatible = "dynapack,atl_gh02047xl", "battery-smart"; + }; + dynapack_cosmx_gh02047xl { + compatible = "dynapack,cosmx_gh02047xl", "battery-smart"; + }; + smp_coslight_gh02047xl { + compatible = "smp,coslight_gh02047xl", "battery-smart"; + }; + smp_highpower_gh02047xl { + compatible = "smp,highpower_gh02047xl", "battery-smart"; + }; + default_battery_3s:cosmx_si03058xl { + compatible = "cosmx,si03058xl", "battery-smart"; + }; + smp_highpower_si03058xl { + compatible = "smp,highpower_si03058xl", "battery-smart"; + }; + }; + + hibernate-wake-pins { + compatible = "cros-ec,hibernate-wake-pins"; + wakeup-irqs = < + &int_power_button + &int_lid_open + >; + }; + + gpio-interrupts { + compatible = "cros-ec,gpio-interrupts"; + + int_power_button: power_button { + irq-pin = <&gpio_gsc_ec_pwr_btn_odl>; + flags = <GPIO_INT_EDGE_BOTH>; + handler = "power_button_interrupt"; + }; + int_wp_l: wp_l { + irq-pin = <&gpio_ec_wp_odl>; + flags = <GPIO_INT_EDGE_BOTH>; + handler = "switch_interrupt"; + }; + int_lid_open: lid_open { + irq-pin = <&gpio_lid_open>; + flags = <GPIO_INT_EDGE_BOTH>; + handler = "lid_interrupt"; + }; + int_usb_c0: usb_c0 { + irq-pin = <&gpio_usb_c0_int_odl>; + flags = <GPIO_INT_EDGE_FALLING>; + handler = "usb_c0_interrupt"; + }; + int_usb_c1: usb_c1 { + irq-pin = <&gpio_sb_1>; + flags = <GPIO_INT_EDGE_FALLING>; + handler = "usb_c1_interrupt"; + }; + }; + + unused-pins { + compatible = "unused-gpios"; + unused-gpios = <&gpioa 7 0>, + <&gpioc 0 0>, + <&gpioc 6 0>, + <&gpiod 7 0>, + <&gpioh 2 0>, + <&gpioi 6 0>, + <&gpioi 7 0>, + <&gpioj 0 0>, + <&gpioj 3 0>, + <&gpiok 7 GPIO_OUTPUT>; + }; + + named-gpios { + /* + * EC doesn't take any specific action on CC/SBU disconnect due to + * fault, but this definition is useful for hardware testing. + */ + gpio_usb_c0_prot_fault_odl: usb_c0_prot_fault_odl { + gpios = <&gpiok 6 GPIO_INPUT_PULL_UP>; + }; + + gpio_sb_1: sb_1 { + gpios = <&gpioe 6 0>; + no-auto-init; + }; + gpio_sb_2: sb_2 { + gpios = <&gpiof 0 0>; + no-auto-init; + }; + gpio_fan_enable: fan-enable { + gpios = <&gpioa 1 GPIO_OUTPUT>; + no-auto-init; + }; + }; + + temp_cpu: cpu { + compatible = "cros-ec,temp-sensor-thermistor"; + thermistor = <&thermistor_3V3_51K1_47K_4050B>; + adc = <&adc_temp_sensor_1>; + }; + temp_5v_regulator: 5v_regulator { + compatible = "cros-ec,temp-sensor-thermistor"; + thermistor = <&thermistor_3V3_51K1_47K_4050B>; + adc = <&adc_temp_sensor_2>; + }; + temp_charger: charger { + compatible = "cros-ec,temp-sensor-thermistor"; + thermistor = <&thermistor_3V3_51K1_47K_4050B>; + adc = <&adc_temp_sensor_3>; + }; + + named-temp-sensors { + compatible = "cros-ec,temp-sensors"; + cpu { + temp_fan_off = <45>; + temp_fan_max = <60>; + temp_host_high = <75>; + temp_host_halt = <85>; + temp_host_release_high = <65>; + power-good-pin = <&gpio_ec_soc_dsw_pwrok>; + sensor = <&temp_cpu>; + }; + 5v_regulator { + temp_fan_off = <50>; + temp_fan_max = <65>; + temp_host_high = <75>; + temp_host_halt = <85>; + temp_host_release_high = <65>; + power-good-pin = <&gpio_ec_soc_dsw_pwrok>; + sensor = <&temp_5v_regulator>; + }; + charger { + temp_fan_off = <50>; + temp_fan_max = <65>; + temp_host_high = <80>; + temp_host_halt = <85>; + temp_host_release_high = <75>; + power-good-pin = <&gpio_ec_soc_dsw_pwrok>; + sensor = <&temp_charger>; + }; + }; + + usba { + compatible = "cros-ec,usba-port-enable-pins"; + /* + * sb_2 is only configured as GPIO when USB-A1 is present, + * but it's still safe to control when disabled. + * + * ILIM_SEL pins are referred to by legacy enum name, + * GPIO_USB*_ILIM_SEL. The one for port A1 is unused on + * sub-boards that don't have USB-A so is safe to control + * regardless of system configuration. + */ + enable-pins = <&gpio_en_usb_a0_vbus &gpio_sb_2>; + status = "okay"; + }; + + usbc { + #address-cells = <1>; + #size-cells = <0>; + + port0@0 { + compatible = "named-usbc-port"; + reg = <0>; + bc12 = <&bc12_port0>; + chg = <&chg_port0>; + usb-mux-chain-0 { + compatible = "cros-ec,usb-mux-chain"; + usb-muxes = <&virtual_mux_0>; + }; + }; + port0-muxes { + virtual_mux_0: virtual-mux-0 { + compatible = "cros-ec,usbc-mux-virtual"; + }; + }; + port1@1 { + compatible = "named-usbc-port"; + reg = <1>; + bc12 = <&bc12_port1>; + chg = <&chg_port1>; + usb-mux-chain-1 { + compatible = "cros-ec,usb-mux-chain"; + usb-muxes = <&virtual_mux_1 &tcpci_mux_1>; + }; + usb_mux_chain_1_no_mux: usb-mux-chain-1-no-mux { + compatible = "cros-ec,usb-mux-chain"; + alternative-chain; + usb-muxes = <&virtual_mux_1>; + }; + }; + port1-muxes { + virtual_mux_1: virtual-mux-1 { + compatible = "cros-ec,usbc-mux-virtual"; + }; + tcpci_mux_1: tcpci-mux-1 { + compatible = "parade,usbc-mux-ps8xxx"; + }; + }; + }; + + fans { + compatible = "cros-ec,fans"; + fan_0 { + pwms = <&pwm2 PWM_CHANNEL_2 PWM_KHZ(25) PWM_POLARITY_NORMAL>; + tach = <&tach1>; + rpm_min = <2600>; + rpm_start = <2600>; + rpm_max = <4100>; + enable_gpio = <&gpio_fan_enable>; + }; + }; +}; + +&thermistor_3V3_51K1_47K_4050B { + status = "okay"; +}; + +&adc_ec_vsense_pp3300_s5 { + /* + * Voltage divider on input has 47k upper and 220k lower legs with 3 V + * full-scale reading on the ADC. Apply the largest possible multiplier + * (without overflowing int32) to get the best possible approximation + * of the actual ratio, but derate by a factor of two to ensure + * unexpectedly high values won't overflow. + */ + mul = <(715828 / 2)>; + div = <(589820 / 2)>; +}; + +&adc0 { + pinctrl-0 = <&adc0_ch0_gpi0_default + &adc0_ch2_gpi2_default + &adc0_ch3_gpi3_default + &adc0_ch13_gpl0_default + &adc0_ch14_gpl1_default>; + pinctrl-names = "default"; + status = "okay"; +}; + +&pinctrl { + i2c4_clk_gpe0_sleep: i2c4_clk_gpe0_sleep { + pinmuxs = <&pinctrle 0 IT8XXX2_ALT_DEFAULT>; + }; + i2c4_data_gpe7_sleep: i2c4_data_gpe7_sleep { + pinmuxs = <&pinctrle 7 IT8XXX2_ALT_DEFAULT>; + }; + i2c2_clk_gpf6_default: i2c2_clk_gpf6_default { + gpio-voltage = "1v8"; + }; + i2c2_data_gpf7_default: i2c2_data_gpf7_default { + gpio-voltage = "1v8"; + }; +}; + +&i2c0 { + label = "I2C_EEPROM"; + clock-frequency = <I2C_BITRATE_FAST>; + + cbi_eeprom: eeprom@50 { + compatible = "atmel,at24"; + reg = <0x50>; + label = "EEPROM_CBI"; + size = <2048>; + pagesize = <16>; + address-width = <8>; + timeout = <5>; + }; + pinctrl-0 = <&i2c0_clk_gpb3_default + &i2c0_data_gpb4_default>; + pinctrl-names = "default"; + status = "okay"; +}; + +&i2c1 { + label = "I2C_BATTERY"; + clock-frequency = <50000>; + pinctrl-0 = <&i2c1_clk_gpc1_default + &i2c1_data_gpc2_default>; + pinctrl-names = "default"; + status = "okay"; +}; + +&i2c2 { + label = "I2C_SENSOR"; + clock-frequency = <I2C_BITRATE_FAST>; + pinctrl-0 = <&i2c2_clk_gpf6_default + &i2c2_data_gpf7_default>; + pinctrl-names = "default"; + status = "okay"; +}; + +&i2c4 { + label = "I2C_SUB_C1_TCPC"; + clock-frequency = <I2C_BITRATE_FAST_PLUS>; + pinctrl-0 = <&i2c4_clk_gpe0_default + &i2c4_data_gpe7_default>; + pinctrl-1 = <&i2c4_clk_gpe0_sleep + &i2c4_data_gpe7_sleep>; + pinctrl-names = "default", "sleep"; + status = "okay"; + + bc12_port1: pi3usb9201@5f { + compatible = "pericom,pi3usb9201"; + status = "okay"; + reg = <0x5f>; + }; + + chg_port1: sm5803@32 { + compatible = "siliconmitus,sm5803"; + status = "okay"; + reg = <0x32>; + }; +}; + +&i2c_ec_i2c_sub_usb_c1 { + /* + * Dynamic speed setting is used for AP-controlled firmware update + * of PS8745 TCPC/redriver: the AP lowers speed to 400 kHz in order + * to use more efficient window programming, then sets it back when + * done. + */ + dynamic-speed; +}; + +&i2c5 { + label = "I2C_USB_C0_TCPC"; + clock-frequency = <I2C_BITRATE_FAST_PLUS>; + pinctrl-0 = <&i2c5_clk_gpa4_default + &i2c5_data_gpa5_default>; + pinctrl-names = "default"; + status = "okay"; + + bc12_port0: pi3usb9201@5f { + compatible = "pericom,pi3usb9201"; + status = "okay"; + reg = <0x5f>; + }; + + chg_port0: sm5803@32 { + compatible = "siliconmitus,sm5803"; + status = "okay"; + reg = <0x32>; + }; +}; + +&usbpd0 { + status = "okay"; +}; + +/* pwm for fan */ +&pwm2 { + status = "okay"; + prescaler-cx = <PWM_PRESCALER_C6>; + pinctrl-0 = <&pwm2_gpa2_default>; + pinctrl-names = "default"; +}; +/* fan tachometer sensor */ +&tach1 { + status = "okay"; + channel = <IT8XXX2_TACH_CHANNEL_A>; + pulses-per-round = <2>; + pinctrl-0 = <&tach1a_gpd7_default>; + pinctrl-names = "default"; +}; diff --git a/zephyr/projects/nissa/yaviks/power_signals.dtsi b/zephyr/projects/nissa/yaviks/power_signals.dtsi new file mode 100644 index 0000000000..d64ac83150 --- /dev/null +++ b/zephyr/projects/nissa/yaviks/power_signals.dtsi @@ -0,0 +1,180 @@ +/* Copyright 2022 The ChromiumOS Authors + * Use of this source code is governed by a BSD-style license that can be + * found in the LICENSE file. + */ + +/ { + chosen { + intel-ap-pwrseq,espi = &espi0; + }; + + common-pwrseq { + compatible = "intel,ap-pwrseq"; + + sys-pwrok-delay = <10>; + all-sys-pwrgd-timeout = <20>; + }; + + pwr-en-pp5000-s5 { + compatible = "intel,ap-pwrseq-gpio"; + dbg-label = "PP5000_S5 enable output to regulator"; + enum-name = "PWR_EN_PP5000_A"; + gpios = <&gpiok 5 0>; + output; + }; + pwr-en-pp3300-s5 { + compatible = "intel,ap-pwrseq-gpio"; + dbg-label = "PP3300_S5 enable output to LS"; + enum-name = "PWR_EN_PP3300_A"; + gpios = <&gpioc 5 0>; + output; + }; + pwr-pg-ec-rsmrst-odl { + compatible = "intel,ap-pwrseq-gpio"; + dbg-label = "RSMRST power good from regulator"; + enum-name = "PWR_RSMRST"; + gpios = <&gpioe 1 0>; + interrupt-flags = <GPIO_INT_EDGE_BOTH>; + }; + pwr-ec-pch-rsmrst-odl { + compatible = "intel,ap-pwrseq-gpio"; + dbg-label = "RSMRST output to PCH"; + enum-name = "PWR_EC_PCH_RSMRST"; + gpios = <&gpioh 0 0>; + output; + }; + pwr-slp-s0-l { + compatible = "intel,ap-pwrseq-gpio"; + dbg-label = "SLP_S0_L input from PCH"; + enum-name = "PWR_SLP_S0"; + gpios = <&gpioe 4 GPIO_ACTIVE_LOW>; + interrupt-flags = <GPIO_INT_EDGE_BOTH>; + }; + pwr-slp-s3-l { + compatible = "intel,ap-pwrseq-gpio"; + dbg-label = "SLP_S3_L input from PCH"; + enum-name = "PWR_SLP_S3"; + gpios = <&gpioh 3 GPIO_ACTIVE_LOW>; + interrupt-flags = <GPIO_INT_EDGE_BOTH>; + }; + pwr-slp-sus-l { + compatible = "intel,ap-pwrseq-gpio"; + dbg-label = "SLP_SUS_L input from PCH"; + enum-name = "PWR_SLP_SUS"; + gpios = <&gpiog 2 GPIO_ACTIVE_LOW>; + interrupt-flags = <GPIO_INT_EDGE_BOTH>; + }; + pwr-ec-soc-dsw-pwrok { + compatible = "intel,ap-pwrseq-gpio"; + dbg-label = "DSW_PWROK output to PCH"; + enum-name = "PWR_EC_SOC_DSW_PWROK"; + gpios = <&gpiol 7 0>; + output; + }; + pwr-vccst-pwrgd-od { + compatible = "intel,ap-pwrseq-gpio"; + dbg-label = "VCCST_PWRGD output to PCH"; + enum-name = "PWR_VCCST_PWRGD"; + gpios = <&gpioe 5 (GPIO_OPEN_DRAIN | GPIO_VOLTAGE_1P8)>; + output; + }; + pwr-imvp9-vrrdy-od { + compatible = "intel,ap-pwrseq-gpio"; + dbg-label = "VRRDY input from IMVP9"; + enum-name = "PWR_IMVP9_VRRDY"; + gpios = <&gpioj 4 0>; + }; + pwr-pch-pwrok { + compatible = "intel,ap-pwrseq-gpio"; + dbg-label = "PCH_PWROK output to PCH"; + enum-name = "PWR_PCH_PWROK"; + gpios = <&gpiod 6 GPIO_OPEN_DRAIN>; + output; + }; + pwr-ec-pch-sys-pwrok { + compatible = "intel,ap-pwrseq-gpio"; + dbg-label = "SYS_PWROK output to PCH"; + enum-name = "PWR_EC_PCH_SYS_PWROK"; + gpios = <&gpiof 2 0>; + output; + }; + pwr-sys-rst-l { + compatible = "intel,ap-pwrseq-gpio"; + dbg-label = "SYS_RESET# output to PCH"; + enum-name = "PWR_SYS_RST"; + gpios = <&gpiod 1 (GPIO_ACTIVE_LOW|GPIO_OPEN_DRAIN)>; + output; + }; + pwr-slp-s4 { + compatible = "intel,ap-pwrseq-vw"; + dbg-label = "SLP_S4 virtual wire input from PCH"; + enum-name = "PWR_SLP_S4"; + virtual-wire = "ESPI_VWIRE_SIGNAL_SLP_S4"; + vw-invert; + }; + pwr-slp-s5 { + compatible = "intel,ap-pwrseq-vw"; + dbg-label = "SLP_S5 virtual wire input from PCH"; + enum-name = "PWR_SLP_S5"; + virtual-wire = "ESPI_VWIRE_SIGNAL_SLP_S5"; + vw-invert; + }; + pwr-all-sys-pwrgd { + /* + * This is a board level signal, since this + * signal needs some special processing. + */ + compatible = "intel,ap-pwrseq-external"; + dbg-label = "Combined all power good"; + enum-name = "PWR_ALL_SYS_PWRGD"; + }; + pwr-adc-pp3300 { + compatible = "intel,ap-pwrseq-adc"; + dbg-label = "PP3300_PROC"; + enum-name = "PWR_DSW_PWROK"; + trigger-high = <&vcmp0>; + trigger-low = <&vcmp1>; + }; + pwr-adc-pp1p05 { + compatible = "intel,ap-pwrseq-adc"; + dbg-label = "PP1P05_PROC"; + enum-name = "PWR_PG_PP1P05"; + trigger-high = <&vcmp2>; + trigger-low = <&vcmp3>; + }; + +}; + +&vcmp0 { + status = "okay"; + scan-period = <IT8XXX2_VCMP_SCAN_PERIOD_600US>; + comparison = <IT8XXX2_VCMP_GREATER>; + /* + * This is 90% of nominal voltage considering voltage + * divider on ADC input. + */ + threshold-mv = <2448>; + io-channels = <&adc0 0>; +}; +&vcmp1 { + status = "okay"; + scan-period = <IT8XXX2_VCMP_SCAN_PERIOD_600US>; + comparison = <IT8XXX2_VCMP_LESS_OR_EQUAL>; + threshold-mv = <2448>; + io-channels = <&adc0 0>; +}; +&vcmp2 { + status = "okay"; + scan-period = <IT8XXX2_VCMP_SCAN_PERIOD_600US>; + comparison = <IT8XXX2_VCMP_GREATER>; + /* Setting at 90% of nominal voltage */ + threshold-mv = <945>; + io-channels = <&adc0 14>; +}; +&vcmp3 { + status = "okay"; + scan-period = <IT8XXX2_VCMP_SCAN_PERIOD_600US>; + comparison = <IT8XXX2_VCMP_LESS_OR_EQUAL>; + threshold-mv = <945>; + io-channels = <&adc0 14>; +}; diff --git a/zephyr/projects/nissa/yaviks/project.conf b/zephyr/projects/nissa/yaviks/project.conf new file mode 100644 index 0000000000..0e385b843e --- /dev/null +++ b/zephyr/projects/nissa/yaviks/project.conf @@ -0,0 +1,33 @@ +# Copyright 2022 The ChromiumOS Authors +# Use of this source code is governed by a BSD-style license that can be +# found in the LICENSE file. + +CONFIG_BOARD_YAVIKS=y + +# Ensure recovery key combination (esc+refresh+power) is reliable: b/236580049 +CONFIG_PLATFORM_EC_KEYBOARD_PWRBTN_ASSERTS_KSI3=y +CONFIG_PLATFORM_EC_KEYBOARD_REFRESH_ROW3=y + +# Sensors: disabled; yaviks is clamshell-only +CONFIG_PLATFORM_EC_LID_ANGLE=n +CONFIG_PLATFORM_EC_LID_ANGLE_UPDATE=n +CONFIG_PLATFORM_EC_MOTIONSENSE=n +CONFIG_PLATFORM_EC_CONSOLE_CMD_ACCELS=n +CONFIG_PLATFORM_EC_CONSOLE_CMD_ACCEL_INFO=n +CONFIG_PLATFORM_EC_ACCEL_FIFO=n +CONFIG_PLATFORM_EC_SENSOR_TIGHT_TIMESTAMPS=n +CONFIG_PLATFORM_EC_GMR_TABLET_MODE=n +CONFIG_PLATFORM_EC_TABLET_MODE=n +CONFIG_PLATFORM_EC_TABLET_MODE_SWITCH=n +CONFIG_PLATFORM_EC_VOLUME_BUTTONS=n +CONFIG_PLATFORM_EC_MAX_SENSOR_FREQ_MILLIHZ=100000 + +# Keyboard +CONFIG_PLATFORM_EC_KEYBOARD_KEYPAD=y +CONFIG_PLATFORM_EC_KBLIGHT_ENABLE_PIN=n + +# Fan +CONFIG_PLATFORM_EC_FAN=y + +# LED +CONFIG_PLATFORM_EC_LED_PWM=n diff --git a/zephyr/projects/nissa/yaviks/project.overlay b/zephyr/projects/nissa/yaviks/project.overlay new file mode 100644 index 0000000000..a7ce97a8b3 --- /dev/null +++ b/zephyr/projects/nissa/yaviks/project.overlay @@ -0,0 +1,12 @@ +/* Copyright 2022 The ChromiumOS Authors + * Use of this source code is governed by a BSD-style license that can be + * found in the LICENSE file. + */ + +#include "../cbi.dtsi" + +#include "cbi.dtsi" +#include "gpio.dtsi" +#include "keyboard.dtsi" +#include "overlay.dtsi" +#include "power_signals.dtsi" diff --git a/zephyr/projects/nissa/yaviks/src/charger.c b/zephyr/projects/nissa/yaviks/src/charger.c new file mode 100644 index 0000000000..9be2e685b0 --- /dev/null +++ b/zephyr/projects/nissa/yaviks/src/charger.c @@ -0,0 +1,74 @@ +/* Copyright 2022 The ChromiumOS Authors + * Use of this source code is governed by a BSD-style license that can be + * found in the LICENSE file. + */ + +#include <zephyr/logging/log.h> + +#include "battery.h" +#include "charger.h" +#include "console.h" +#include "driver/charger/sm5803.h" +#include "extpower.h" +#include "usb_pd.h" +#include "nissa_common.h" +#include "battery_fuel_gauge.h" + +LOG_MODULE_DECLARE(nissa, CONFIG_NISSA_LOG_LEVEL); + +int extpower_is_present(void) +{ + int port; + int rv; + bool acok; + + for (port = 0; port < board_get_usb_pd_port_count(); port++) { + rv = sm5803_is_acok(port, &acok); + if ((rv == EC_SUCCESS) && acok) + return 1; + } + + return 0; +} + +/* + * Yaviks does not have a GPIO indicating whether extpower is present, + * so detect using the charger(s). + */ +__override void board_check_extpower(void) +{ + static int last_extpower_present; + int extpower_present = extpower_is_present(); + + if (last_extpower_present ^ extpower_present) + extpower_handle_update(extpower_present); + + last_extpower_present = extpower_present; +} + +__override void board_hibernate(void) +{ + /* Shut down the chargers */ + if (board_get_usb_pd_port_count() == 2) + sm5803_hibernate(CHARGER_SECONDARY); + sm5803_hibernate(CHARGER_PRIMARY); + LOG_INF("Charger(s) hibernated"); + cflush(); +} + +__override int board_get_default_battery_type(void) +{ + int type = DEFAULT_BATTERY_TYPE; + int cells; + + if (charger_get_battery_cells(CHARGER_PRIMARY, &cells) == EC_SUCCESS) { + if (cells == 3) + type = DEFAULT_BATTERY_TYPE_3S; + if (cells != 2 && cells != 3) + LOG_ERR("Unexpected number of cells"); + } else { + LOG_ERR("Failed to get default battery type"); + } + + return type; +} diff --git a/zephyr/projects/nissa/yaviks/src/fan.c b/zephyr/projects/nissa/yaviks/src/fan.c new file mode 100644 index 0000000000..23c3ec1143 --- /dev/null +++ b/zephyr/projects/nissa/yaviks/src/fan.c @@ -0,0 +1,36 @@ +/* Copyright 2022 The ChromiumOS Authors + * Use of this source code is governed by a BSD-style license that can be + * found in the LICENSE file. + */ +#include <zephyr/devicetree.h> +#include <zephyr/drivers/gpio.h> +#include <zephyr/logging/log.h> +#include "cros_cbi.h" +#include "fan.h" +#include "gpio/gpio.h" +#include "hooks.h" +#include "nissa_common.h" +LOG_MODULE_DECLARE(nissa, CONFIG_NISSA_LOG_LEVEL); + +static void fan_init(void) +{ + int ret; + uint32_t val; + /* + * Retrieve the fan config. + */ + ret = cros_cbi_get_fw_config(FW_FAN, &val); + if (ret != 0) { + LOG_ERR("Error retrieving CBI FW_CONFIG field %d", FW_FAN); + return; + } + if (val != FW_FAN_PRESENT) { + /* Disable the fan */ + fan_set_count(0); + } else { + /* Configure the fan enable GPIO */ + gpio_pin_configure_dt(GPIO_DT_FROM_NODELABEL(gpio_fan_enable), + GPIO_OUTPUT); + } +} +DECLARE_HOOK(HOOK_INIT, fan_init, HOOK_PRIO_POST_FIRST); diff --git a/zephyr/projects/nissa/yaviks/src/keyboard.c b/zephyr/projects/nissa/yaviks/src/keyboard.c new file mode 100644 index 0000000000..46d6083dbf --- /dev/null +++ b/zephyr/projects/nissa/yaviks/src/keyboard.c @@ -0,0 +1,106 @@ +/* Copyright 2022 The ChromiumOS Authors + * Use of this source code is governed by a BSD-style license that can be + * found in the LICENSE file. + */ +#include <zephyr/logging/log.h> + +#include "cros_cbi.h" +#include "ec_commands.h" +#include "hooks.h" +#include "keyboard_8042_sharedlib.h" +#include "keyboard_scan.h" +#include "timer.h" + +LOG_MODULE_DECLARE(nissa, CONFIG_NISSA_LOG_LEVEL); + +/* Keyboard scan setting */ +__override 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 = { + 0x1c, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xa4, 0xff, 0xf6, 0x55, 0xfe, 0xff, 0xff, 0xff, /* full set */ + }, +}; + +static const struct ec_response_keybd_config yaviks_kb_w_kb_light = { + .num_top_row_keys = 13, + .action_keys = { + TK_BACK, /* T1 */ + TK_REFRESH, /* T2 */ + TK_FULLSCREEN, /* T3 */ + TK_OVERVIEW, /* T4 */ + TK_SNAPSHOT, /* T5 */ + TK_BRIGHTNESS_DOWN, /* T6 */ + TK_BRIGHTNESS_UP, /* T7 */ + TK_KBD_BKLIGHT_TOGGLE, /* T8 */ + TK_PLAY_PAUSE, /* T9 */ + TK_MICMUTE, /* T10 */ + TK_VOL_MUTE, /* T11 */ + TK_VOL_DOWN, /* T12 */ + TK_VOL_UP, /* T13 */ + }, + .capabilities = KEYBD_CAP_NUMERIC_KEYPAD, +}; + +static const struct ec_response_keybd_config yaviks_kb_wo_kb_light = { + .num_top_row_keys = 13, + .action_keys = { + TK_BACK, /* T1 */ + TK_REFRESH, /* T2 */ + TK_FULLSCREEN, /* T3 */ + TK_OVERVIEW, /* T4 */ + TK_SNAPSHOT, /* T5 */ + TK_BRIGHTNESS_DOWN, /* T6 */ + TK_BRIGHTNESS_UP, /* T7 */ + TK_PLAY_PAUSE, /* T8 */ + TK_MICMUTE, /* T9 */ + TK_VOL_MUTE, /* T10 */ + TK_VOL_DOWN, /* T11 */ + TK_VOL_UP, /* T12 */ + TK_MENU, /* T13 */ + }, + .capabilities = KEYBD_CAP_NUMERIC_KEYPAD, +}; + +__override const struct ec_response_keybd_config * +board_vivaldi_keybd_config(void) +{ + uint32_t val; + + cros_cbi_get_fw_config(FW_KB_BACKLIGHT, &val); + + if (val == FW_KB_BACKLIGHT_OFF) + return &yaviks_kb_wo_kb_light; + else + return &yaviks_kb_w_kb_light; +} + +/* + * Keyboard layout decided by FW config. + */ +static void kb_layout_init(void) +{ + int ret; + uint32_t val; + + ret = cros_cbi_get_fw_config(FW_KB_LAYOUT, &val); + if (ret != 0) { + LOG_ERR("Error retrieving CBI FW_CONFIG field %d", + FW_KB_LAYOUT); + return; + } + /* + * If keyboard is US2(FW_KB_LAYOUT_US2), we need translate right ctrl + * to backslash(\|) key. + */ + if (val == FW_KB_LAYOUT_US2) + set_scancode_set2(4, 0, get_scancode_set2(2, 7)); +} +DECLARE_HOOK(HOOK_INIT, kb_layout_init, HOOK_PRIO_POST_FIRST); diff --git a/zephyr/projects/nissa/yaviks/src/led.c b/zephyr/projects/nissa/yaviks/src/led.c new file mode 100644 index 0000000000..88a476f1b0 --- /dev/null +++ b/zephyr/projects/nissa/yaviks/src/led.c @@ -0,0 +1,231 @@ +/* Copyright 2022 The ChromiumOS Authors + * Use of this source code is governed by a BSD-style license that can be + * found in the LICENSE file. + */ + +#include <stdint.h> + +#include "battery.h" +#include "charge_manager.h" +#include "charge_state.h" +#include "chipset.h" +#include "ec_commands.h" +#include "gpio.h" +#include "host_command.h" +#include "led_common.h" +#include "hooks.h" + +#define BAT_LED_ON 0 +#define BAT_LED_OFF 1 + +#define BATT_LOW_BCT 10 + +#define LED_TICKS_PER_CYCLE 4 +#define LED_TICKS_PER_CYCLE_S3 4 +#define LED_ON_TICKS 2 +#define POWER_LED_ON_S3_TICKS 2 + +const enum ec_led_id supported_led_ids[] = { EC_LED_ID_LEFT_LED, + EC_LED_ID_RIGHT_LED }; + +const int supported_led_ids_count = ARRAY_SIZE(supported_led_ids); + +enum led_color { + LED_OFF = 0, + LED_AMBER, + LED_WHITE, + LED_COLOR_COUNT /* Number of colors, not a color itself */ +}; + +enum led_port { LEFT_PORT = 0, RIGHT_PORT }; + +static void led_set_color_battery(int port, enum led_color color) +{ + const struct gpio_dt_spec *amber_led, *white_led; + + if (port == LEFT_PORT) { + amber_led = GPIO_DT_FROM_NODELABEL(gpio_c0_charger_led_amber_l); + white_led = GPIO_DT_FROM_NODELABEL(gpio_c0_charger_led_white_l); + } else if (port == RIGHT_PORT) { + amber_led = GPIO_DT_FROM_NODELABEL(gpio_c1_charger_led_amber_l); + white_led = GPIO_DT_FROM_NODELABEL(gpio_c1_charger_led_white_l); + } + + switch (color) { + case LED_WHITE: + gpio_pin_set_dt(white_led, BAT_LED_ON); + gpio_pin_set_dt(amber_led, BAT_LED_OFF); + break; + case LED_AMBER: + gpio_pin_set_dt(white_led, BAT_LED_OFF); + gpio_pin_set_dt(amber_led, BAT_LED_ON); + break; + case LED_OFF: + gpio_pin_set_dt(white_led, BAT_LED_OFF); + gpio_pin_set_dt(amber_led, BAT_LED_OFF); + break; + default: + break; + } +} + +void led_get_brightness_range(enum ec_led_id led_id, uint8_t *brightness_range) +{ + switch (led_id) { + case EC_LED_ID_LEFT_LED: + brightness_range[EC_LED_COLOR_WHITE] = 1; + brightness_range[EC_LED_COLOR_AMBER] = 1; + break; + case EC_LED_ID_RIGHT_LED: + brightness_range[EC_LED_COLOR_WHITE] = 1; + brightness_range[EC_LED_COLOR_AMBER] = 1; + break; + default: + break; + } +} + +int led_set_brightness(enum ec_led_id led_id, const uint8_t *brightness) +{ + switch (led_id) { + case EC_LED_ID_LEFT_LED: + if (brightness[EC_LED_COLOR_WHITE] != 0) + led_set_color_battery(LEFT_PORT, LED_WHITE); + else if (brightness[EC_LED_COLOR_AMBER] != 0) + led_set_color_battery(LEFT_PORT, LED_AMBER); + else + led_set_color_battery(LEFT_PORT, LED_OFF); + break; + case EC_LED_ID_RIGHT_LED: + if (brightness[EC_LED_COLOR_WHITE] != 0) + led_set_color_battery(RIGHT_PORT, LED_WHITE); + else if (brightness[EC_LED_COLOR_AMBER] != 0) + led_set_color_battery(RIGHT_PORT, LED_AMBER); + else + led_set_color_battery(RIGHT_PORT, LED_OFF); + break; + default: + return EC_ERROR_PARAM1; + } + + return EC_SUCCESS; +} + +/* + * Set active charge port color to the parameter, turn off all others. + * If no port is active (-1), turn off all LEDs. + */ +static void set_active_port_color(enum led_color color) +{ + int port = charge_manager_get_active_charge_port(); + + if (led_auto_control_is_enabled(EC_LED_ID_RIGHT_LED)) + led_set_color_battery(RIGHT_PORT, + (port == RIGHT_PORT) ? color : LED_OFF); + if (led_auto_control_is_enabled(EC_LED_ID_LEFT_LED)) + led_set_color_battery(LEFT_PORT, + (port == LEFT_PORT) ? color : LED_OFF); +} + +static void led_set_battery(void) +{ + static unsigned int battery_ticks; + static int suspend_ticks; + + battery_ticks++; + + /* + * Override battery LEDs for Yaviks, Yaviks is non-power LED + * design, blinking both two side battery white LEDs to indicate + * system suspend with non-charging state. + */ + if (chipset_in_state(CHIPSET_STATE_ANY_SUSPEND) && + charge_get_state() != PWR_STATE_CHARGE) { + suspend_ticks++; + + led_set_color_battery(RIGHT_PORT, + suspend_ticks % LED_TICKS_PER_CYCLE_S3 < + POWER_LED_ON_S3_TICKS ? + LED_WHITE : + LED_OFF); + led_set_color_battery(LEFT_PORT, + suspend_ticks % LED_TICKS_PER_CYCLE_S3 < + POWER_LED_ON_S3_TICKS ? + LED_WHITE : + LED_OFF); + return; + } + + suspend_ticks = 0; + + switch (charge_get_state()) { + case PWR_STATE_CHARGE: + /* Always indicate when charging, even in suspend. */ + set_active_port_color(LED_AMBER); + break; + case PWR_STATE_DISCHARGE: + /* + * Blinking amber LEDs slowly if battery is lower 10 + * percentage. + */ + if (led_auto_control_is_enabled(EC_LED_ID_RIGHT_LED)) { + if (charge_get_percent() < BATT_LOW_BCT) + led_set_color_battery( + RIGHT_PORT, + (battery_ticks % LED_TICKS_PER_CYCLE < + LED_ON_TICKS) ? + LED_AMBER : + LED_OFF); + else + led_set_color_battery(RIGHT_PORT, LED_OFF); + } + + if (led_auto_control_is_enabled(EC_LED_ID_LEFT_LED)) { + if (charge_get_percent() < BATT_LOW_BCT) + led_set_color_battery( + LEFT_PORT, + (battery_ticks % LED_TICKS_PER_CYCLE < + LED_ON_TICKS) ? + LED_AMBER : + LED_OFF); + else + led_set_color_battery(LEFT_PORT, LED_OFF); + } + break; + case PWR_STATE_ERROR: + if (led_auto_control_is_enabled(EC_LED_ID_RIGHT_LED)) { + led_set_color_battery( + RIGHT_PORT, + (battery_ticks & 0x1) ? LED_AMBER : LED_OFF); + } + + if (led_auto_control_is_enabled(EC_LED_ID_LEFT_LED)) { + led_set_color_battery(LEFT_PORT, (battery_ticks & 0x1) ? + LED_AMBER : + LED_OFF); + } + break; + case PWR_STATE_CHARGE_NEAR_FULL: + set_active_port_color(LED_WHITE); + break; + case PWR_STATE_IDLE: /* External power connected in IDLE */ + set_active_port_color(LED_WHITE); + break; + case PWR_STATE_FORCED_IDLE: + set_active_port_color( + (battery_ticks % LED_TICKS_PER_CYCLE < LED_ON_TICKS) ? + LED_AMBER : + LED_OFF); + break; + default: + /* Other states don't alter LED behavior */ + break; + } +} + +/* Called by hook task every TICK(IT83xx 500ms) */ +static void led_tick(void) +{ + led_set_battery(); +} +DECLARE_HOOK(HOOK_TICK, led_tick, HOOK_PRIO_DEFAULT); diff --git a/zephyr/projects/nissa/yaviks/src/usbc.c b/zephyr/projects/nissa/yaviks/src/usbc.c new file mode 100644 index 0000000000..48f7cfd9cb --- /dev/null +++ b/zephyr/projects/nissa/yaviks/src/usbc.c @@ -0,0 +1,393 @@ +/* Copyright 2022 The ChromiumOS Authors + * Use of this source code is governed by a BSD-style license that can be + * found in the LICENSE file. + */ + +#include <zephyr/logging/log.h> +#include <ap_power/ap_power.h> + +#include "charge_state_v2.h" +#include "chipset.h" +#include "hooks.h" +#include "usb_mux.h" +#include "system.h" +#include "driver/charger/sm5803.h" +#include "driver/tcpm/it83xx_pd.h" +#include "driver/tcpm/ps8xxx_public.h" +#include "driver/tcpm/tcpci.h" + +#include "nissa_common.h" + +LOG_MODULE_DECLARE(nissa, CONFIG_NISSA_LOG_LEVEL); + +struct tcpc_config_t tcpc_config[CONFIG_USB_PD_PORT_MAX_COUNT] = { + { + .bus_type = EC_BUS_TYPE_EMBEDDED, + /* TCPC is embedded within EC so no i2c config needed */ + .drv = &it8xxx2_tcpm_drv, + /* Alert is active-low, push-pull */ + .flags = 0, + }, + { + /* + * Sub-board: optional PS8745 TCPC+redriver. Behaves the same + * as PS8815. + */ + .bus_type = EC_BUS_TYPE_I2C, + .i2c_info = { + .port = I2C_PORT_USB_C1_TCPC, + .addr_flags = PS8XXX_I2C_ADDR1_FLAGS, + }, + .drv = &ps8xxx_tcpm_drv, + /* PS8745 implements TCPCI 2.0 */ + .flags = TCPC_FLAGS_TCPCI_REV2_0, + }, +}; + +/* Vconn control for integrated ITE TCPC */ +void board_pd_vconn_ctrl(int port, enum usbpd_cc_pin cc_pin, int enabled) +{ + /* Vconn control is only for port 0 */ + if (port) + return; + + if (cc_pin == USBPD_CC_PIN_1) + gpio_pin_set_dt( + GPIO_DT_FROM_NODELABEL(gpio_en_usb_c0_cc1_vconn), + !!enabled); + else + gpio_pin_set_dt( + GPIO_DT_FROM_NODELABEL(gpio_en_usb_c0_cc2_vconn), + !!enabled); +} + +__override bool pd_check_vbus_level(int port, enum vbus_level level) +{ + return sm5803_check_vbus_level(port, level); +} + +/* + * Putting chargers into LPM when in suspend reduces power draw by about 8mW + * per charger, but also seems critical to correct operation in source mode: + * if chargers are not in LPM when a sink is first connected, VBUS sourcing + * works even if the partner is later removed (causing LPM entry) and + * reconnected (causing LPM exit). If in LPM initially, sourcing VBUS + * consistently causes the charger to report (apparently spurious) overcurrent + * failures. + * + * In short, this is important to making things work correctly but we don't + * understand why. + */ +static void board_chargers_suspend(struct ap_power_ev_callback *const cb, + const struct ap_power_ev_data data) +{ + void (*fn)(int chgnum); + + switch (data.event) { + case AP_POWER_SUSPEND: + fn = sm5803_enable_low_power_mode; + break; + case AP_POWER_RESUME: + fn = sm5803_disable_low_power_mode; + break; + default: + LOG_WRN("%s: power event %d is not recognized", __func__, + data.event); + return; + } + + fn(CHARGER_PRIMARY); + if (board_get_charger_chip_count() > 1) + fn(CHARGER_SECONDARY); +} + +static int board_chargers_suspend_init(const struct device *unused) +{ + static struct ap_power_ev_callback cb = { + .handler = board_chargers_suspend, + .events = AP_POWER_SUSPEND | AP_POWER_RESUME, + }; + ap_power_ev_add_callback(&cb); + return 0; +} +SYS_INIT(board_chargers_suspend_init, APPLICATION, 0); + +int board_set_active_charge_port(int port) +{ + int is_real_port = (port >= 0 && port < board_get_usb_pd_port_count()); + int i; + int old_port; + int rv; + + if (!is_real_port && port != CHARGE_PORT_NONE) + return EC_ERROR_INVAL; + + old_port = charge_manager_get_active_charge_port(); + LOG_INF("Charge update: p%d -> p%d", old_port, port); + + /* Check if port is sourcing VBUS. */ + if (port != CHARGE_PORT_NONE && charger_is_sourcing_otg_power(port)) { + LOG_WRN("Skip enable p%d: already sourcing", port); + return EC_ERROR_INVAL; + } + + /* Disable sinking on all ports except the desired one */ + for (i = 0; i < board_get_usb_pd_port_count(); i++) { + if (i == port) + continue; + + if (sm5803_vbus_sink_enable(i, 0)) + /* + * Do not early-return because this can fail during + * power-on which would put us into a loop. + */ + LOG_WRN("p%d: sink path disable failed.", i); + } + + /* Don't enable anything (stop here) if no ports were requested */ + if ((port == CHARGE_PORT_NONE) || (old_port == port)) + return EC_SUCCESS; + + /* + * Stop the charger IC from switching while changing ports. Otherwise, + * we can overcurrent the adapter we're switching to. (crbug.com/926056) + */ + if (old_port != CHARGE_PORT_NONE) + charger_discharge_on_ac(1); + + /* Enable requested charge port. */ + rv = sm5803_vbus_sink_enable(port, 1); + if (rv) + LOG_WRN("p%d: sink path enable failed: code %d", port, rv); + + /* Allow the charger IC to begin/continue switching. */ + charger_discharge_on_ac(0); + + return rv; +} + +uint16_t tcpc_get_alert_status(void) +{ + /* + * TCPC 0 is embedded in the EC and processes interrupts in the chip + * code (it83xx/intc.c). This function only needs to poll port C1 if + * present. + */ + uint16_t status = 0; + int regval; + + /* Is the C1 port present and its IRQ line asserted? */ + if (board_get_usb_pd_port_count() == 2 && + !gpio_pin_get_dt(GPIO_DT_FROM_ALIAS(gpio_usb_c1_int_odl))) { + /* + * C1 IRQ is shared between BC1.2 and TCPC; poll TCPC to see if + * it asserted the IRQ. + */ + if (!tcpc_read16(1, TCPC_REG_ALERT, ®val)) { + if (regval) + status = PD_STATUS_TCPC_ALERT_1; + } + } + + return status; +} + +void pd_power_supply_reset(int port) +{ + int prev_en; + + if (port < 0 || port >= board_get_usb_pd_port_count()) + return; + + prev_en = charger_is_sourcing_otg_power(port); + + /* Disable Vbus */ + charger_enable_otg_power(port, 0); + + /* Discharge Vbus if previously enabled */ + if (prev_en) + sm5803_set_vbus_disch(port, 1); + + /* Notify host of power info change. */ + pd_send_host_event(PD_EVENT_POWER_CHANGE); +} + +int pd_set_power_supply_ready(int port) +{ + enum ec_error_list rv; + + if (port < 0 || port > board_get_usb_pd_port_count()) { + LOG_WRN("Port C%d does not exist, cannot enable VBUS", port); + return EC_ERROR_INVAL; + } + + /* Disable sinking */ + rv = sm5803_vbus_sink_enable(port, 0); + if (rv) { + LOG_WRN("C%d failed to disable sinking: %d", port, rv); + return rv; + } + + /* Disable Vbus discharge */ + rv = sm5803_set_vbus_disch(port, 0); + if (rv) { + LOG_WRN("C%d failed to clear VBUS discharge: %d", port, rv); + return rv; + } + + /* Provide Vbus */ + rv = charger_enable_otg_power(port, 1); + if (rv) { + LOG_WRN("C%d failed to enable VBUS sourcing: %d", port, rv); + return rv; + } + + /* Notify host of power info change. */ + pd_send_host_event(PD_EVENT_POWER_CHANGE); + + return EC_SUCCESS; +} + +__override void typec_set_source_current_limit(int port, enum tcpc_rp_value rp) +{ + int rv; + const int current = rp == TYPEC_RP_3A0 ? 3000 : 1500; + + rv = charger_set_otg_current_voltage(port, current, 5000); + if (rv != EC_SUCCESS) { + LOG_WRN("Failed to set source ilimit on port %d to %d: %d", + port, current, rv); + } +} + +void board_reset_pd_mcu(void) +{ + /* + * Do nothing. The integrated TCPC for C0 lacks a dedicated reset + * command, and C1 (if present) doesn't have a reset pin connected + * to the EC. + */ +} + +#define INT_RECHECK_US 5000 + +/* C0 interrupt line shared by BC 1.2 and charger */ + +static void check_c0_line(void); +DECLARE_DEFERRED(check_c0_line); + +static void notify_c0_chips(void) +{ + usb_charger_task_set_event(0, USB_CHG_EVENT_BC12); + sm5803_interrupt(0); +} + +static void check_c0_line(void) +{ + /* + * If line is still being held low, see if there's more to process from + * one of the chips + */ + if (!gpio_pin_get_dt(GPIO_DT_FROM_NODELABEL(gpio_usb_c0_int_odl))) { + notify_c0_chips(); + hook_call_deferred(&check_c0_line_data, INT_RECHECK_US); + } +} + +void usb_c0_interrupt(enum gpio_signal s) +{ + /* Cancel any previous calls to check the interrupt line */ + hook_call_deferred(&check_c0_line_data, -1); + + /* Notify all chips using this line that an interrupt came in */ + notify_c0_chips(); + + /* Check the line again in 5ms */ + hook_call_deferred(&check_c0_line_data, INT_RECHECK_US); +} + +/* C1 interrupt line shared by BC 1.2, TCPC, and charger */ +static void check_c1_line(void); +DECLARE_DEFERRED(check_c1_line); + +static void notify_c1_chips(void) +{ + schedule_deferred_pd_interrupt(1); + usb_charger_task_set_event(1, USB_CHG_EVENT_BC12); + /* Charger is handled in board_process_pd_alert */ +} + +static void check_c1_line(void) +{ + /* + * If line is still being held low, see if there's more to process from + * one of the chips. + */ + if (!gpio_pin_get_dt(GPIO_DT_FROM_ALIAS(gpio_usb_c1_int_odl))) { + notify_c1_chips(); + hook_call_deferred(&check_c1_line_data, INT_RECHECK_US); + } +} + +void usb_c1_interrupt(enum gpio_signal s) +{ + /* Cancel any previous calls to check the interrupt line */ + hook_call_deferred(&check_c1_line_data, -1); + + /* Notify all chips using this line that an interrupt came in */ + notify_c1_chips(); + + /* Check the line again in 5ms */ + hook_call_deferred(&check_c1_line_data, INT_RECHECK_US); +} + +/* + * Check state of IRQ lines at startup, ensuring an IRQ that happened before + * the EC started up won't get lost (leaving the IRQ line asserted and blocking + * any further interrupts on the port). + * + * Although the PD task will check for pending TCPC interrupts on startup, + * the charger sharing the IRQ will not be polled automatically. + */ +void board_handle_initial_typec_irq(void) +{ + check_c0_line(); + if (board_get_usb_pd_port_count() == 2) + check_c1_line(); +} +/* + * This must run after sub-board detection (which happens in EC main()), + * but isn't depended on by anything else either. + */ +DECLARE_HOOK(HOOK_INIT, board_handle_initial_typec_irq, HOOK_PRIO_LAST); + +/* + * Handle charger interrupts in the PD task. Not doing so can lead to a priority + * inversion where we fail to respond to TCPC alerts quickly enough because we + * don't get another edge on a shared IRQ until the charger interrupt is cleared + * (or the IRQ is polled again), which happens in the low-priority charger task: + * the high-priority type-C handler is thus blocked on the lower-priority + * charger. + * + * To avoid that, we run charger interrupts at the same priority. + */ +void board_process_pd_alert(int port) +{ + /* + * Port 0 doesn't use an external TCPC, so its interrupts don't need + * this special handling. + */ + if (port == 1 && + !gpio_pin_get_dt(GPIO_DT_FROM_ALIAS(gpio_usb_c1_int_odl))) { + sm5803_handle_interrupt(port); + } +} + +int pd_snk_is_vbus_provided(int port) +{ + int chg_det = 0; + + sm5803_get_chg_det(port, &chg_det); + + return chg_det; +} diff --git a/zephyr/projects/nissa/yaviks/yaviks_vif.xml b/zephyr/projects/nissa/yaviks/yaviks_vif.xml new file mode 100644 index 0000000000..edc6299c58 --- /dev/null +++ b/zephyr/projects/nissa/yaviks/yaviks_vif.xml @@ -0,0 +1,350 @@ +<?xml version="1.0" encoding="utf-8"?>
+<vif:VIF xmlns:opt="http://usb.org/VendorInfoFileOptionalContent.xsd" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:vif="http://usb.org/VendorInfoFile.xsd">
+ <vif:VIF_Specification>3.19</vif:VIF_Specification>
+ <vif:VIF_App>
+ <vif:Vendor>USB-IF</vif:Vendor>
+ <vif:Name>VIF Editor</vif:Name>
+ <vif:Version>3.2.4.0</vif:Version>
+ </vif:VIF_App>
+ <vif:Vendor_Name>Google</vif:Vendor_Name>
+ <vif:Model_Part_Number>Yaviks</vif:Model_Part_Number>
+ <vif:Product_Revision>1</vif:Product_Revision>
+ <vif:TID>0</vif:TID>
+ <vif:VIF_Product_Type value="0">Port Product</vif:VIF_Product_Type>
+ <vif:Certification_Type value="1">Reference Platform</vif:Certification_Type>
+ <vif:Product>
+ <!--Product Level Content:-->
+ </vif:Product>
+ <vif:Component>
+ <!--Component 0: Port 0-->
+ <!--;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-->
+ <!--;Component-->
+ <!--;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-->
+ <vif:Port_Label>0</vif:Port_Label>
+ <vif:Connector_Type value="2">Type-C®</vif:Connector_Type>
+ <vif:USB4_Supported value="false" />
+ <vif:USB_PD_Support value="true" />
+ <vif:PD_Port_Type value="4">DRP</vif:PD_Port_Type>
+ <vif:Type_C_State_Machine value="2">DRP</vif:Type_C_State_Machine>
+ <vif:Port_Battery_Powered value="true" />
+ <vif:BC_1_2_Support value="2">Charging Port</vif:BC_1_2_Support>
+ <vif:Captive_Cable value="false" />
+ <!--;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-->
+ <!--;General PD-->
+ <!--;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-->
+ <vif:PD_Spec_Revision_Major value="3" />
+ <vif:PD_Spec_Revision_Minor value="1" />
+ <vif:PD_Spec_Version_Major value="1" />
+ <vif:PD_Spec_Version_Minor value="3" />
+ <vif:PD_Specification_Revision value="2">Revision 3</vif:PD_Specification_Revision>
+ <vif:SOP_Capable value="true" />
+ <vif:SOP_P_Capable value="true" />
+ <vif:SOP_PP_Capable value="true" />
+ <vif:SOP_P_Debug_Capable value="false" />
+ <vif:SOP_PP_Debug_Capable value="false" />
+ <vif:Manufacturer_Info_Supported_Port value="true" />
+ <vif:Manufacturer_Info_VID_Port value="6353">18D1</vif:Manufacturer_Info_VID_Port>
+ <vif:Manufacturer_Info_PID_Port value="20570">505A</vif:Manufacturer_Info_PID_Port>
+ <vif:Chunking_Implemented_SOP value="true" />
+ <vif:Unchunked_Extended_Messages_Supported value="false" />
+ <vif:Security_Msgs_Supported_SOP value="false" />
+ <vif:Unconstrained_Power value="false" />
+ <vif:Num_Fixed_Batteries value="1" />
+ <vif:Num_Swappable_Battery_Slots value="0" />
+ <vif:ID_Header_Connector_Type_SOP value="2">USB Type-C® Receptacle</vif:ID_Header_Connector_Type_SOP>
+ <!--;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-->
+ <!--;PD Capabilities-->
+ <!--;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-->
+ <vif:USB_Comms_Capable value="true" />
+ <vif:DR_Swap_To_DFP_Supported value="true" />
+ <vif:DR_Swap_To_UFP_Supported value="false" />
+ <vif:VCONN_Swap_To_On_Supported value="true" />
+ <vif:VCONN_Swap_To_Off_Supported value="true" />
+ <vif:Responds_To_Discov_SOP_UFP value="false" />
+ <vif:Responds_To_Discov_SOP_DFP value="true" />
+ <vif:Attempts_Discov_SOP value="true" />
+ <vif:Power_Interruption_Available value="0">No Interruption Possible</vif:Power_Interruption_Available>
+ <vif:Data_Reset_Supported value="false" />
+ <vif:Enter_USB_Supported value="false" />
+ <!--;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-->
+ <!--;USB Type-C®-->
+ <!--;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-->
+ <vif:Type_C_Can_Act_As_Host value="true" />
+ <vif:Type_C_Can_Act_As_Device value="false" />
+ <vif:Type_C_Implements_Try_SRC value="true" />
+ <vif:Type_C_Implements_Try_SNK value="false" />
+ <vif:Type_C_Supports_Audio_Accessory value="false" />
+ <vif:Type_C_Is_VCONN_Powered_Accessory value="false" />
+ <vif:Type_C_Is_Debug_Target_SRC value="true" />
+ <vif:Type_C_Is_Debug_Target_SNK value="true" />
+ <vif:RP_Value value="1">1.5A</vif:RP_Value>
+ <vif:Type_C_Port_On_Hub value="false" />
+ <vif:Type_C_Power_Source value="2">Both</vif:Type_C_Power_Source>
+ <vif:Type_C_Sources_VCONN value="true" />
+ <vif:Type_C_Is_Alt_Mode_Controller value="true" />
+ <vif:Type_C_Is_Alt_Mode_Adapter value="false" />
+ <!--;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-->
+ <!--;Product Power-->
+ <!--;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-->
+ <vif:Product_Total_Source_Power_mW value="15000">15000 mW</vif:Product_Total_Source_Power_mW>
+ <vif:Port_Source_Power_Type value="0">Assured</vif:Port_Source_Power_Type>
+ <!--;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-->
+ <!--;USB Host-->
+ <!--;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-->
+ <vif:Host_Supports_USB_Data value="true" />
+ <vif:Host_Speed value="1">USB 3.2 Gen 1x1</vif:Host_Speed>
+ <vif:Host_Contains_Captive_Retimer value="false" />
+ <vif:Host_Truncates_DP_For_tDHPResponse value="false" />
+ <vif:Host_Is_Embedded value="false" />
+ <vif:Host_Suspend_Supported value="true" />
+ <vif:Is_DFP_On_Hub value="false" />
+ <!--;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-->
+ <!--;Battery Charging 1.2-->
+ <!--;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-->
+ <vif:BC_1_2_Charging_Port_Type value="1">CDP</vif:BC_1_2_Charging_Port_Type>
+ <!--;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-->
+ <!--;PD Source-->
+ <!--;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-->
+ <vif:PD_Power_As_Source value="15000">15000 mW</vif:PD_Power_As_Source>
+ <vif:EPR_Supported_As_Src value="false" />
+ <vif:USB_Suspend_May_Be_Cleared value="false" />
+ <vif:Sends_Pings value="false" />
+ <vif:FR_Swap_Type_C_Current_Capability_As_Initial_Sink value="0">FR_Swap not supported</vif:FR_Swap_Type_C_Current_Capability_As_Initial_Sink>
+ <vif:Master_Port value="false" />
+ <vif:Num_Src_PDOs value="1" />
+ <vif:PD_OC_Protection value="true" />
+ <vif:PD_OCP_Method value="0">Over-Current Response</vif:PD_OCP_Method>
+ <!--Bundle: SrcPdoList-->
+ <vif:SrcPdoList>
+ <vif:SrcPDO>
+ <!--Source PDO 1-->
+ <vif:Src_PDO_Supply_Type value="0">Fixed</vif:Src_PDO_Supply_Type>
+ <vif:Src_PDO_Peak_Current value="0">100% IOC</vif:Src_PDO_Peak_Current>
+ <vif:Src_PDO_Voltage value="100">5000 mV</vif:Src_PDO_Voltage>
+ <vif:Src_PDO_Max_Current value="300">3000 mA</vif:Src_PDO_Max_Current>
+ <vif:Src_PD_OCP_OC_Debounce value="0">0 msec</vif:Src_PD_OCP_OC_Debounce>
+ <vif:Src_PD_OCP_OC_Threshold value="300">3000 mA</vif:Src_PD_OCP_OC_Threshold>
+ </vif:SrcPDO>
+ </vif:SrcPdoList>
+ <!--;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-->
+ <!--;PD Sink-->
+ <!--;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-->
+ <vif:PD_Power_As_Sink value="45000">45000 mW</vif:PD_Power_As_Sink>
+ <vif:EPR_Supported_As_Snk value="false" />
+ <vif:No_USB_Suspend_May_Be_Set value="true" />
+ <vif:GiveBack_May_Be_Set value="false" />
+ <vif:Higher_Capability_Set value="false" />
+ <vif:FR_Swap_Reqd_Type_C_Current_As_Initial_Source value="0">FR_Swap not supported</vif:FR_Swap_Reqd_Type_C_Current_As_Initial_Source>
+ <vif:Num_Snk_PDOs value="3" />
+ <!--Bundle: SnkPdoList-->
+ <vif:SnkPdoList>
+ <vif:SnkPDO>
+ <!--Sink PDO 1-->
+ <vif:Snk_PDO_Supply_Type value="0">Fixed</vif:Snk_PDO_Supply_Type>
+ <vif:Snk_PDO_Voltage value="100">5000 mV</vif:Snk_PDO_Voltage>
+ <vif:Snk_PDO_Op_Current value="300">3000 mA</vif:Snk_PDO_Op_Current>
+ </vif:SnkPDO>
+ <vif:SnkPDO>
+ <!--Sink PDO 2-->
+ <vif:Snk_PDO_Supply_Type value="1">Battery</vif:Snk_PDO_Supply_Type>
+ <vif:Snk_PDO_Op_Power value="60">15000 mW</vif:Snk_PDO_Op_Power>
+ <vif:Snk_PDO_Min_Voltage value="95">4750 mV</vif:Snk_PDO_Min_Voltage>
+ <vif:Snk_PDO_Max_Voltage value="300">15000 mV</vif:Snk_PDO_Max_Voltage>
+ </vif:SnkPDO>
+ <vif:SnkPDO>
+ <!--Sink PDO 3-->
+ <vif:Snk_PDO_Supply_Type value="2">Variable</vif:Snk_PDO_Supply_Type>
+ <vif:Snk_PDO_Min_Voltage value="95">4750 mV</vif:Snk_PDO_Min_Voltage>
+ <vif:Snk_PDO_Max_Voltage value="300">15000 mV</vif:Snk_PDO_Max_Voltage>
+ <vif:Snk_PDO_Op_Current value="300">3000 mA</vif:Snk_PDO_Op_Current>
+ </vif:SnkPDO>
+ </vif:SnkPdoList>
+ <!--;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-->
+ <!--;Dual Role-->
+ <!--;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-->
+ <vif:Accepts_PR_Swap_As_Src value="true" />
+ <vif:Accepts_PR_Swap_As_Snk value="true" />
+ <vif:Requests_PR_Swap_As_Src value="true" />
+ <vif:Requests_PR_Swap_As_Snk value="true" />
+ <vif:FR_Swap_Supported_As_Initial_Sink value="false" />
+ <!--;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-->
+ <!--;SOP Discover ID-->
+ <!--;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-->
+ <vif:XID_SOP value="0" />
+ <vif:Data_Capable_As_USB_Host_SOP value="true" />
+ <vif:Data_Capable_As_USB_Device_SOP value="false" />
+ <vif:Product_Type_UFP_SOP value="0">Undefined</vif:Product_Type_UFP_SOP>
+ <vif:Product_Type_DFP_SOP value="2">PDUSB Host</vif:Product_Type_DFP_SOP>
+ <vif:DFP_VDO_Port_Number value="0" />
+ <vif:Modal_Operation_Supported_SOP value="false" />
+ <vif:USB_VID_SOP value="6353">18D1</vif:USB_VID_SOP>
+ <vif:PID_SOP value="20570">505A</vif:PID_SOP>
+ <vif:bcdDevice_SOP value="0">0000</vif:bcdDevice_SOP>
+ </vif:Component>
+ <vif:Component>
+ <!--Component 1: Port 1-->
+ <!--;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-->
+ <!--;Component-->
+ <!--;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-->
+ <vif:Port_Label>1</vif:Port_Label>
+ <vif:Connector_Type value="2">Type-C®</vif:Connector_Type>
+ <vif:USB4_Supported value="false" />
+ <vif:USB_PD_Support value="true" />
+ <vif:PD_Port_Type value="4">DRP</vif:PD_Port_Type>
+ <vif:Type_C_State_Machine value="2">DRP</vif:Type_C_State_Machine>
+ <vif:Port_Battery_Powered value="true" />
+ <vif:BC_1_2_Support value="2">Charging Port</vif:BC_1_2_Support>
+ <vif:Captive_Cable value="false" />
+ <!--;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-->
+ <!--;General PD-->
+ <!--;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-->
+ <vif:PD_Spec_Revision_Major value="3" />
+ <vif:PD_Spec_Revision_Minor value="1" />
+ <vif:PD_Spec_Version_Major value="1" />
+ <vif:PD_Spec_Version_Minor value="3" />
+ <vif:PD_Specification_Revision value="2">Revision 3</vif:PD_Specification_Revision>
+ <vif:SOP_Capable value="true" />
+ <vif:SOP_P_Capable value="true" />
+ <vif:SOP_PP_Capable value="true" />
+ <vif:SOP_P_Debug_Capable value="false" />
+ <vif:SOP_PP_Debug_Capable value="false" />
+ <vif:Manufacturer_Info_Supported_Port value="true" />
+ <vif:Manufacturer_Info_VID_Port value="6353">18D1</vif:Manufacturer_Info_VID_Port>
+ <vif:Manufacturer_Info_PID_Port value="20570">505A</vif:Manufacturer_Info_PID_Port>
+ <vif:Chunking_Implemented_SOP value="true" />
+ <vif:Unchunked_Extended_Messages_Supported value="false" />
+ <vif:Security_Msgs_Supported_SOP value="false" />
+ <vif:Unconstrained_Power value="false" />
+ <vif:Num_Fixed_Batteries value="1" />
+ <vif:Num_Swappable_Battery_Slots value="0" />
+ <vif:ID_Header_Connector_Type_SOP value="2">USB Type-C® Receptacle</vif:ID_Header_Connector_Type_SOP>
+ <!--;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-->
+ <!--;PD Capabilities-->
+ <!--;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-->
+ <vif:USB_Comms_Capable value="true" />
+ <vif:DR_Swap_To_DFP_Supported value="true" />
+ <vif:DR_Swap_To_UFP_Supported value="false" />
+ <vif:VCONN_Swap_To_On_Supported value="true" />
+ <vif:VCONN_Swap_To_Off_Supported value="true" />
+ <vif:Responds_To_Discov_SOP_UFP value="false" />
+ <vif:Responds_To_Discov_SOP_DFP value="true" />
+ <vif:Attempts_Discov_SOP value="true" />
+ <vif:Power_Interruption_Available value="0">No Interruption Possible</vif:Power_Interruption_Available>
+ <vif:Data_Reset_Supported value="false" />
+ <vif:Enter_USB_Supported value="false" />
+ <!--;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-->
+ <!--;USB Type-C®-->
+ <!--;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-->
+ <vif:Type_C_Can_Act_As_Host value="true" />
+ <vif:Type_C_Can_Act_As_Device value="false" />
+ <vif:Type_C_Implements_Try_SRC value="true" />
+ <vif:Type_C_Implements_Try_SNK value="false" />
+ <vif:Type_C_Supports_Audio_Accessory value="false" />
+ <vif:Type_C_Is_VCONN_Powered_Accessory value="false" />
+ <vif:Type_C_Is_Debug_Target_SRC value="true" />
+ <vif:Type_C_Is_Debug_Target_SNK value="true" />
+ <vif:RP_Value value="1">1.5A</vif:RP_Value>
+ <vif:Type_C_Port_On_Hub value="false" />
+ <vif:Type_C_Power_Source value="2">Both</vif:Type_C_Power_Source>
+ <vif:Type_C_Sources_VCONN value="true" />
+ <vif:Type_C_Is_Alt_Mode_Controller value="true" />
+ <vif:Type_C_Is_Alt_Mode_Adapter value="false" />
+ <!--;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-->
+ <!--;Product Power-->
+ <!--;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-->
+ <vif:Product_Total_Source_Power_mW value="15000">15000 mW</vif:Product_Total_Source_Power_mW>
+ <vif:Port_Source_Power_Type value="0">Assured</vif:Port_Source_Power_Type>
+ <!--;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-->
+ <!--;USB Host-->
+ <!--;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-->
+ <vif:Host_Supports_USB_Data value="true" />
+ <vif:Host_Speed value="1">USB 3.2 Gen 1x1</vif:Host_Speed>
+ <vif:Host_Contains_Captive_Retimer value="true" />
+ <vif:Host_Truncates_DP_For_tDHPResponse value="false" />
+ <vif:Host_Is_Embedded value="false" />
+ <vif:Host_Suspend_Supported value="true" />
+ <vif:Is_DFP_On_Hub value="false" />
+ <!--;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-->
+ <!--;Battery Charging 1.2-->
+ <!--;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-->
+ <vif:BC_1_2_Charging_Port_Type value="1">CDP</vif:BC_1_2_Charging_Port_Type>
+ <!--;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-->
+ <!--;PD Source-->
+ <!--;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-->
+ <vif:PD_Power_As_Source value="15000">15000 mW</vif:PD_Power_As_Source>
+ <vif:EPR_Supported_As_Src value="false" />
+ <vif:USB_Suspend_May_Be_Cleared value="false" />
+ <vif:Sends_Pings value="false" />
+ <vif:FR_Swap_Type_C_Current_Capability_As_Initial_Sink value="0">FR_Swap not supported</vif:FR_Swap_Type_C_Current_Capability_As_Initial_Sink>
+ <vif:Master_Port value="false" />
+ <vif:Num_Src_PDOs value="1" />
+ <vif:PD_OC_Protection value="true" />
+ <vif:PD_OCP_Method value="0">Over-Current Response</vif:PD_OCP_Method>
+ <!--Bundle: SrcPdoList-->
+ <vif:SrcPdoList>
+ <vif:SrcPDO>
+ <!--Source PDO 1-->
+ <vif:Src_PDO_Supply_Type value="0">Fixed</vif:Src_PDO_Supply_Type>
+ <vif:Src_PDO_Peak_Current value="0">100% IOC</vif:Src_PDO_Peak_Current>
+ <vif:Src_PDO_Voltage value="100">5000 mV</vif:Src_PDO_Voltage>
+ <vif:Src_PDO_Max_Current value="300">3000 mA</vif:Src_PDO_Max_Current>
+ <vif:Src_PD_OCP_OC_Debounce value="0">0 msec</vif:Src_PD_OCP_OC_Debounce>
+ <vif:Src_PD_OCP_OC_Threshold value="300">3000 mA</vif:Src_PD_OCP_OC_Threshold>
+ </vif:SrcPDO>
+ </vif:SrcPdoList>
+ <!--;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-->
+ <!--;PD Sink-->
+ <!--;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-->
+ <vif:PD_Power_As_Sink value="45000">45000 mW</vif:PD_Power_As_Sink>
+ <vif:EPR_Supported_As_Snk value="false" />
+ <vif:No_USB_Suspend_May_Be_Set value="true" />
+ <vif:GiveBack_May_Be_Set value="false" />
+ <vif:Higher_Capability_Set value="false" />
+ <vif:FR_Swap_Reqd_Type_C_Current_As_Initial_Source value="0">FR_Swap not supported</vif:FR_Swap_Reqd_Type_C_Current_As_Initial_Source>
+ <vif:Num_Snk_PDOs value="3" />
+ <!--Bundle: SnkPdoList-->
+ <vif:SnkPdoList>
+ <vif:SnkPDO>
+ <!--Sink PDO 1-->
+ <vif:Snk_PDO_Supply_Type value="0">Fixed</vif:Snk_PDO_Supply_Type>
+ <vif:Snk_PDO_Voltage value="100">5000 mV</vif:Snk_PDO_Voltage>
+ <vif:Snk_PDO_Op_Current value="300">3000 mA</vif:Snk_PDO_Op_Current>
+ </vif:SnkPDO>
+ <vif:SnkPDO>
+ <!--Sink PDO 2-->
+ <vif:Snk_PDO_Supply_Type value="1">Battery</vif:Snk_PDO_Supply_Type>
+ <vif:Snk_PDO_Op_Power value="60">15000 mW</vif:Snk_PDO_Op_Power>
+ <vif:Snk_PDO_Min_Voltage value="95">4750 mV</vif:Snk_PDO_Min_Voltage>
+ <vif:Snk_PDO_Max_Voltage value="300">15000 mV</vif:Snk_PDO_Max_Voltage>
+ </vif:SnkPDO>
+ <vif:SnkPDO>
+ <!--Sink PDO 3-->
+ <vif:Snk_PDO_Supply_Type value="2">Variable</vif:Snk_PDO_Supply_Type>
+ <vif:Snk_PDO_Min_Voltage value="95">4750 mV</vif:Snk_PDO_Min_Voltage>
+ <vif:Snk_PDO_Max_Voltage value="300">15000 mV</vif:Snk_PDO_Max_Voltage>
+ <vif:Snk_PDO_Op_Current value="300">3000 mA</vif:Snk_PDO_Op_Current>
+ </vif:SnkPDO>
+ </vif:SnkPdoList>
+ <!--;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-->
+ <!--;Dual Role-->
+ <!--;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-->
+ <vif:Accepts_PR_Swap_As_Src value="true" />
+ <vif:Accepts_PR_Swap_As_Snk value="true" />
+ <vif:Requests_PR_Swap_As_Src value="true" />
+ <vif:Requests_PR_Swap_As_Snk value="true" />
+ <vif:FR_Swap_Supported_As_Initial_Sink value="false" />
+ <!--;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-->
+ <!--;SOP Discover ID-->
+ <!--;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-->
+ <vif:XID_SOP value="0" />
+ <vif:Data_Capable_As_USB_Host_SOP value="true" />
+ <vif:Data_Capable_As_USB_Device_SOP value="false" />
+ <vif:Product_Type_UFP_SOP value="0">Undefined</vif:Product_Type_UFP_SOP>
+ <vif:Product_Type_DFP_SOP value="2">PDUSB Host</vif:Product_Type_DFP_SOP>
+ <vif:DFP_VDO_Port_Number value="1" />
+ <vif:Modal_Operation_Supported_SOP value="false" />
+ <vif:USB_VID_SOP value="6353">18D1</vif:USB_VID_SOP>
+ <vif:PID_SOP value="20570">505A</vif:PID_SOP>
+ <vif:bcdDevice_SOP value="0">0000</vif:bcdDevice_SOP>
+ </vif:Component>
+</vif:VIF>
\ No newline at end of file |