summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSue Chen <sue.chen@quanta.corp-partner.google.com>2021-07-28 17:11:52 +0800
committerCommit Bot <commit-bot@chromium.org>2021-08-02 09:03:12 +0000
commitf099ba6d54bb226608117a3298ad8ade9810f303 (patch)
treebfca421e073486a9773155438520a553e2f1c2ee
parentc68e54f989647fb9880e633c3159b4e6c3d529be (diff)
downloadchrome-ec-f099ba6d54bb226608117a3298ad8ade9810f303.tar.gz
Pico: Initial EC image
Create the initial EC image for the pico variant by copying the icarus reference board EC files into a new directory named for the variant. BUG=none BRANCH=icarus TEST=make BOARD=pico Signed-off-by: Sue Chen <sue.chen@quanta.corp-partner.google.com> Change-Id: I0eeae3e76b1cfabd0be54d1b29c9af7fac1238c2 Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/platform/ec/+/3058159 Reviewed-by: Ting Shen <phoenixshen@chromium.org> (cherry picked from commit 7d4846d48e4625d3556f27d7419d2358da2b64a5) Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/platform/ec/+/3062701 Commit-Queue: Ting Shen <phoenixshen@chromium.org>
-rw-r--r--board/pico/battery.c189
-rw-r--r--board/pico/board.c275
-rw-r--r--board/pico/board.h139
-rw-r--r--board/pico/build.mk15
-rw-r--r--board/pico/ec.tasklist17
-rw-r--r--board/pico/gpio.inc148
-rw-r--r--board/pico/led.c80
-rw-r--r--board/pico/vif_override.xml3
8 files changed, 866 insertions, 0 deletions
diff --git a/board/pico/battery.c b/board/pico/battery.c
new file mode 100644
index 0000000000..6f6b49899a
--- /dev/null
+++ b/board/pico/battery.c
@@ -0,0 +1,189 @@
+/* Copyright 2021 The Chromium OS Authors. All rights reserved.
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+#include "battery.h"
+#include "battery_fuel_gauge.h"
+#include "gpio.h"
+
+const struct board_batt_params board_battery_info[] = {
+ /* LGC AP18C8K Battery Information */
+ [BATTERY_LGC_AP18C8K] = {
+ .fuel_gauge = {
+ .manuf_name = "LGC KT0030G020",
+ .device_name = "AP18C8K",
+ .ship_mode = {
+ .reg_addr = 0x3A,
+ .reg_data = { 0xC574, 0xC574 },
+ },
+ .fet = {
+ .reg_addr = 0x43,
+ .reg_mask = 0x0001,
+ .disconnect_val = 0x0,
+ },
+ },
+ .batt_info = {
+ .voltage_max = 13050,
+ .voltage_normal = 11250,
+ .voltage_min = 9000,
+ .precharge_current = 256,
+ .start_charging_min_c = 0,
+ .start_charging_max_c = 50,
+ .charging_min_c = 0,
+ .charging_max_c = 60,
+ .discharging_min_c = -20,
+ .discharging_max_c = 75,
+ },
+ },
+ /* Murata AP18C4K Battery Information */
+ [BATTERY_MURATA_AP18C4K] = {
+ .fuel_gauge = {
+ .manuf_name = "Murata KT00304012",
+ .device_name = "AP18C4K",
+ .ship_mode = {
+ .reg_addr = 0x3A,
+ .reg_data = { 0xC574, 0xC574 },
+ },
+ .fet = {
+ .reg_addr = 0x0,
+ .reg_mask = 0x2000,
+ .disconnect_val = 0x2000,
+ },
+ },
+ .batt_info = {
+ .voltage_max = 13200,
+ .voltage_normal = 11400,
+ .voltage_min = 9000,
+ .precharge_current = 256,
+ .start_charging_min_c = 0,
+ .start_charging_max_c = 50,
+ .charging_min_c = 0,
+ .charging_max_c = 60,
+ .discharging_min_c = -20,
+ .discharging_max_c = 75,
+ },
+ },
+ /* Panasonic AP19B5K Battery Information */
+ [BATTERY_PANASONIC_AP19B5K_KT00305011] = {
+ .fuel_gauge = {
+ .manuf_name = "PANASONIC KT00305011",
+ .device_name = "AP19B5K",
+ .ship_mode = {
+ .reg_addr = 0x3A,
+ .reg_data = { 0xC574, 0xC574 },
+ },
+ .fet = {
+ .reg_addr = 0x0,
+ .reg_mask = 0x4000,
+ .disconnect_val = 0x0,
+ }
+ },
+ .batt_info = {
+ .voltage_max = 13200,
+ .voltage_normal = 11550,
+ .voltage_min = 9000,
+ .precharge_current = 256,
+ .start_charging_min_c = 0,
+ .start_charging_max_c = 50,
+ .charging_min_c = 0,
+ .charging_max_c = 60,
+ .discharging_min_c = -20,
+ .discharging_max_c = 75,
+ },
+ },
+ /* LGC AP19B8K Battery Information */
+ [BATTERY_LGC_AP19B8K] = {
+ .fuel_gauge = {
+ .manuf_name = "LGC KT0030G022",
+ .device_name = "AP19B8K",
+ .ship_mode = {
+ .reg_addr = 0x3A,
+ .reg_data = { 0xC574, 0xC574 },
+ },
+ .fet = {
+ .reg_addr = 0x43,
+ .reg_mask = 0x0001,
+ .disconnect_val = 0x0,
+ },
+ },
+ .batt_info = {
+ .voltage_max = 13050,
+ .voltage_normal = 11250,
+ .voltage_min = 9000,
+ .precharge_current = 256,
+ .start_charging_min_c = 0,
+ .start_charging_max_c = 50,
+ .charging_min_c = 0,
+ .charging_max_c = 60,
+ .discharging_min_c = -20,
+ .discharging_max_c = 75,
+ },
+ },
+ /* COSMX AP20CBL Battery Information */
+ [BATTERY_COSMX_AP20CBL] = {
+ .fuel_gauge = {
+ .manuf_name = "COSMX KT0030B002",
+ .device_name = "AP20CBL",
+ .ship_mode = {
+ .reg_addr = 0x3A,
+ .reg_data = { 0xC574, 0xC574 },
+ },
+ .fet = {
+ .mfgacc_support = 1,
+ .reg_addr = 0x0,
+ .reg_mask = 0x0002,
+ .disconnect_val = 0x0,
+ },
+ },
+ .batt_info = {
+ .voltage_max = 13200,
+ .voltage_normal = 11550,
+ .voltage_min = 9000,
+ .precharge_current = 256,
+ .start_charging_min_c = 0,
+ .start_charging_max_c = 50,
+ .charging_min_c = 0,
+ .charging_max_c = 60,
+ .discharging_min_c = -20,
+ .discharging_max_c = 75,
+ },
+ },
+ /* SMP AP18C7K Battery Information */
+ [BATTERY_SMP_AP18C7K] = {
+ .fuel_gauge = {
+ .manuf_name = "SMP KT00307010",
+ .device_name = "AP18C7K",
+ .ship_mode = {
+ .reg_addr = 0x3A,
+ .reg_data = { 0xC574, 0xC574 },
+ },
+ .fet = {
+ .mfgacc_support = 1,
+ .reg_addr = 0x0,
+ .reg_mask = 0x0002,
+ .disconnect_val = 0x0,
+ },
+ },
+ .batt_info = {
+ .voltage_max = 13200,
+ .voltage_normal = 11550,
+ .voltage_min = 9000,
+ .precharge_current = 256,
+ .start_charging_min_c = 0,
+ .start_charging_max_c = 45,
+ .charging_min_c = 0,
+ .charging_max_c = 60,
+ .discharging_min_c = -20,
+ .discharging_max_c = 75,
+ },
+ },
+};
+BUILD_ASSERT(ARRAY_SIZE(board_battery_info) == BATTERY_TYPE_COUNT);
+
+const enum battery_type DEFAULT_BATTERY_TYPE = BATTERY_LGC_AP18C8K;
+
+enum battery_present battery_hw_present(void)
+{
+ return gpio_get_level(GPIO_EC_BATT_PRES_ODL) ? BP_NO : BP_YES;
+}
diff --git a/board/pico/board.c b/board/pico/board.c
new file mode 100644
index 0000000000..d094210c67
--- /dev/null
+++ b/board/pico/board.c
@@ -0,0 +1,275 @@
+/* Copyright 2021 The Chromium OS Authors. All rights reserved.
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+#include "adc.h"
+#include "adc_chip.h"
+#include "backlight.h"
+#include "button.h"
+#include "charge_manager.h"
+#include "charge_ramp.h"
+#include "charge_state.h"
+#include "charger.h"
+#include "chipset.h"
+#include "common.h"
+#include "console.h"
+#include "driver/battery/max17055.h"
+#include "driver/bc12/pi3usb9201.h"
+#include "driver/charger/isl923x.h"
+#include "driver/tcpm/it83xx_pd.h"
+#include "driver/usb_mux/it5205.h"
+#include "ec_commands.h"
+#include "extpower.h"
+#include "gpio.h"
+#include "hooks.h"
+#include "host_command.h"
+#include "i2c.h"
+#include "keyboard_scan.h"
+#include "lid_switch.h"
+#include "power.h"
+#include "power_button.h"
+#include "registers.h"
+#include "spi.h"
+#include "system.h"
+#include "task.h"
+#include "tcpm/tcpm.h"
+#include "timer.h"
+#include "uart.h"
+#include "usb_charge.h"
+#include "usb_mux.h"
+#include "usb_pd_tcpm.h"
+#include "util.h"
+
+#define CPRINTS(format, args...) cprints(CC_USBCHARGE, format, ## args)
+#define CPRINTF(format, args...) cprintf(CC_USBCHARGE, format, ## args)
+
+#include "gpio_list.h"
+
+/*
+ * Map keyboard connector pins to EC GPIO pins for factory test.
+ * Pins mapped to {-1, -1} are skipped.
+ * The connector has 24 pins total, and there is no pin 0.
+ */
+const int keyboard_factory_scan_pins[][2] = {
+ {-1, -1}, {GPIO_KSO_H, 4}, {GPIO_KSO_H, 0}, {GPIO_KSO_H, 1},
+ {GPIO_KSO_H, 3}, {GPIO_KSO_H, 2}, {-1, -1}, {-1, -1},
+ {GPIO_KSO_L, 5}, {GPIO_KSO_L, 6}, {-1, -1}, {GPIO_KSO_L, 3},
+ {GPIO_KSO_L, 2}, {GPIO_KSI, 0}, {GPIO_KSO_L, 1}, {GPIO_KSO_L, 4},
+ {GPIO_KSI, 3}, {GPIO_KSI, 2}, {GPIO_KSO_L, 0}, {GPIO_KSI, 5},
+ {GPIO_KSI, 4}, {GPIO_KSO_L, 7}, {GPIO_KSI, 6}, {GPIO_KSI, 7},
+ {GPIO_KSI, 1}, {-1, -1}, {GPIO_KSO_H, 5}, {-1, -1},
+ {GPIO_KSO_H, 6}, {-1, -1}, {-1, -1},
+};
+
+const int keyboard_factory_scan_pins_used =
+ ARRAY_SIZE(keyboard_factory_scan_pins);
+
+/* Wake-up pins for hibernate */
+const enum gpio_signal hibernate_wake_pins[] = {
+ GPIO_AC_PRESENT,
+ GPIO_LID_OPEN,
+ GPIO_POWER_BUTTON_L,
+};
+const int hibernate_wake_pins_used = ARRAY_SIZE(hibernate_wake_pins);
+
+/******************************************************************************/
+/* ADC channels. Must be in the exactly same order as in enum adc_channel. */
+const struct adc_t adc_channels[] = {
+ [ADC_BOARD_ID] = {"BOARD_ID", ADC_MAX_MVOLT, ADC_READ_MAX + 1, 0,
+ CHIP_ADC_CH1},
+ [ADC_EC_SKU_ID] = {"EC_SKU_ID", ADC_MAX_MVOLT, ADC_READ_MAX + 1, 0,
+ CHIP_ADC_CH2},
+ [ADC_VBUS] = {"VBUS", ADC_MAX_MVOLT * 10, ADC_READ_MAX + 1, 0,
+ CHIP_ADC_CH0},
+};
+BUILD_ASSERT(ARRAY_SIZE(adc_channels) == ADC_CH_COUNT);
+
+/******************************************************************************/
+/* I2C ports */
+const struct i2c_port_t i2c_ports[] = {
+ {"typec", IT83XX_I2C_CH_C, 400, GPIO_I2C_C_SCL, GPIO_I2C_C_SDA},
+ {"other", IT83XX_I2C_CH_B, 100, GPIO_I2C_B_SCL, GPIO_I2C_B_SDA},
+ {"battery", IT83XX_I2C_CH_A, 100, GPIO_I2C_A_SCL, GPIO_I2C_A_SDA},
+};
+const unsigned int i2c_ports_used = ARRAY_SIZE(i2c_ports);
+
+#define BC12_I2C_ADDR PI3USB9201_I2C_ADDR_3
+
+/* power signal list. Must match order of enum power_signal. */
+const struct power_signal_info power_signal_list[] = {
+ {GPIO_AP_IN_SLEEP_L, POWER_SIGNAL_ACTIVE_LOW, "AP_IN_S3_L"},
+ {GPIO_PMIC_EC_RESETB, POWER_SIGNAL_ACTIVE_HIGH, "PMIC_PWR_GOOD"},
+};
+BUILD_ASSERT(ARRAY_SIZE(power_signal_list) == POWER_SIGNAL_COUNT);
+
+/******************************************************************************/
+const struct pi3usb9201_config_t pi3usb9201_bc12_chips[] = {
+ {
+ .i2c_port = I2C_PORT_BC12,
+ .i2c_addr_flags = PI3USB9201_I2C_ADDR_3_FLAGS,
+ },
+};
+
+/******************************************************************************/
+const 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,
+ },
+};
+
+static void board_hpd_status(const struct usb_mux *me,
+ int hpd_lvl, int hpd_irq)
+{
+ /*
+ * svdm_dp_attention() did most of the work, we only need to notify
+ * host here.
+ */
+ host_set_single_event(EC_HOST_EVENT_USB_MUX);
+}
+
+const struct usb_mux usb_muxes[CONFIG_USB_PD_PORT_MAX_COUNT] = {
+ {
+ .usb_port = 0,
+ .i2c_port = I2C_PORT_USB_MUX,
+ .i2c_addr_flags = IT5205_I2C_ADDR1_FLAGS,
+ .driver = &it5205_usb_mux_driver,
+ .hpd_update = &board_hpd_status,
+ },
+};
+
+/* Charger config. Start i2c address at 1, update during runtime */
+struct charger_config_t chg_chips[] = {
+ {
+ .i2c_port = I2C_PORT_CHARGER,
+ .i2c_addr_flags = ISL923X_ADDR_FLAGS,
+ .drv = &isl923x_drv,
+ },
+};
+
+static int force_discharge;
+
+int board_set_active_charge_port(int charge_port)
+{
+ CPRINTS("New chg p%d", charge_port);
+
+ /* ignore all request when discharge mode is on */
+ if (force_discharge && charge_port != CHARGE_PORT_NONE)
+ return EC_SUCCESS;
+
+ switch (charge_port) {
+ case CHARGE_PORT_USB_C:
+ /* Don't charge from a source port */
+ if (board_vbus_source_enabled(charge_port))
+ return -1;
+ break;
+ case CHARGE_PORT_NONE:
+ /*
+ * To ensure the fuel gauge (max17055) is always powered
+ * even when battery is disconnected, keep VBAT rail on but
+ * set the charging current to minimum.
+ */
+ charger_set_current(CHARGER_SOLO, 0);
+ break;
+ default:
+ panic("Invalid charge port\n");
+ break;
+ }
+
+ return EC_SUCCESS;
+}
+
+void board_set_charge_limit(int port, int supplier, int charge_ma,
+ int max_ma, int charge_mv)
+{
+ charge_ma = (charge_ma * 95) / 100;
+ charge_set_input_current_limit(MAX(charge_ma,
+ CONFIG_CHARGER_INPUT_CURRENT), charge_mv);
+}
+
+int board_discharge_on_ac(int enable)
+{
+ int ret, port;
+
+ if (enable) {
+ port = CHARGE_PORT_NONE;
+ } else {
+ /* restore the charge port state */
+ port = charge_manager_get_override();
+ if (port == OVERRIDE_OFF)
+ port = charge_manager_get_active_charge_port();
+ }
+
+ ret = charger_discharge_on_ac(enable);
+ if (ret)
+ return ret;
+
+ force_discharge = enable;
+ return board_set_active_charge_port(port);
+}
+
+#define VBUS_THRESHOLD_MV 4200
+int pd_snk_is_vbus_provided(int port)
+{
+ /* This board has only one port. */
+ if (!port)
+ return adc_read_channel(ADC_VBUS) > VBUS_THRESHOLD_MV ? 1 : 0;
+ else
+ return 0;
+}
+
+void bc12_interrupt(enum gpio_signal signal)
+{
+ task_set_event(TASK_ID_USB_CHG_P0, USB_CHG_EVENT_BC12);
+}
+
+static void board_init(void)
+{
+ /* If the reset cause is external, pulse PMIC force reset. */
+ if (system_get_reset_flags() == EC_RESET_FLAG_RESET_PIN) {
+ gpio_set_level(GPIO_PMIC_FORCE_RESET_ODL, 0);
+ msleep(100);
+ gpio_set_level(GPIO_PMIC_FORCE_RESET_ODL, 1);
+ }
+
+ /* Enable interrupts from BMI160 sensor. */
+ gpio_enable_interrupt(GPIO_ACCEL_INT_ODL);
+
+ /* Enable interrupt from PMIC. */
+ gpio_enable_interrupt(GPIO_PMIC_EC_RESETB);
+
+ /* Enable BC12 interrupt */
+ gpio_enable_interrupt(GPIO_BC12_EC_INT_ODL);
+}
+DECLARE_HOOK(HOOK_INIT, board_init, HOOK_PRIO_DEFAULT);
+
+/* 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_set_level(GPIO_EN_USB_C0_CC1_VCONN, !!enabled);
+ else
+ gpio_set_level(GPIO_EN_USB_C0_CC2_VCONN, !!enabled);
+}
+
+/* Called on AP S5 -> S3 transition */
+static void board_chipset_startup(void)
+{
+ gpio_set_level(GPIO_EN_USBA_5V, 1);
+}
+DECLARE_HOOK(HOOK_CHIPSET_STARTUP, board_chipset_startup, HOOK_PRIO_DEFAULT);
+
+/* Called on AP S3 -> S5 transition */
+static void board_chipset_shutdown(void)
+{
+ gpio_set_level(GPIO_EN_USBA_5V, 0);
+}
+DECLARE_HOOK(HOOK_CHIPSET_SHUTDOWN, board_chipset_shutdown, HOOK_PRIO_DEFAULT);
diff --git a/board/pico/board.h b/board/pico/board.h
new file mode 100644
index 0000000000..e70fc7113d
--- /dev/null
+++ b/board/pico/board.h
@@ -0,0 +1,139 @@
+/* Copyright 2021 The Chromium OS Authors. All rights reserved.
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+/* Configuration for Kukui */
+
+#ifndef __CROS_EC_BOARD_H
+#define __CROS_EC_BOARD_H
+
+#define VARIANT_KUKUI_JACUZZI
+#define VARIANT_KUKUI_BATTERY_SMART
+#define VARIANT_KUKUI_CHARGER_ISL9238
+#define VARIANT_KUKUI_EC_IT81202
+
+#include "baseboard.h"
+
+/* TODO: remove me once we fix IT83XX_ILM_BLOCK_SIZE out of space issue */
+#undef CONFIG_LTO
+
+#undef CONFIG_CHIPSET_POWER_SEQ_VERSION
+#define CONFIG_CHIPSET_POWER_SEQ_VERSION 1
+
+#define CONFIG_BATTERY_HW_PRESENT_CUSTOM
+
+#define CONFIG_CHARGER_PSYS
+
+#define CONFIG_CHARGER_RUNTIME_CONFIG
+
+#define CONFIG_BC12_DETECT_PI3USB9201
+
+#define CONFIG_EXTPOWER_GPIO
+#undef CONFIG_EXTPOWER_DEBOUNCE_MS
+#define CONFIG_EXTPOWER_DEBOUNCE_MS 200
+
+#undef CONFIG_I2C_NACK_RETRY_COUNT
+#define CONFIG_I2C_NACK_RETRY_COUNT 10
+#define CONFIG_SMBUS_PEC
+
+#define CONFIG_USB_PD_TCPM_ITE_ON_CHIP
+#define CONFIG_USB_PD_DISCHARGE_GPIO
+#define CONFIG_USB_PD_TCPC_LOW_POWER
+
+#define CONFIG_USB_MUX_IT5205
+
+#undef CONFIG_ACCEL_FIFO
+#undef CONFIG_ACCEL_FIFO_SIZE
+#undef CONFIG_ACCEL_FIFO_THRES
+
+/* I2C ports */
+#define I2C_PORT_BC12 IT83XX_I2C_CH_C
+#define I2C_PORT_TCPC0 IT83XX_I2C_CH_C
+#define I2C_PORT_USB_MUX IT83XX_I2C_CH_C
+#define I2C_PORT_CHARGER IT83XX_I2C_CH_A
+#define I2C_PORT_SENSORS IT83XX_I2C_CH_B
+#define I2C_PORT_ACCEL I2C_PORT_SENSORS
+#define I2C_PORT_BATTERY IT83XX_I2C_CH_A
+#define I2C_PORT_VIRTUAL_BATTERY I2C_PORT_BATTERY
+
+#define CONFIG_KEYBOARD_PROTOCOL_MKBP
+#define CONFIG_MKBP_EVENT
+#define CONFIG_MKBP_USE_GPIO
+
+#define CONFIG_LED_ONOFF_STATES
+
+#undef CONFIG_GMR_TABLET_MODE
+#undef GMR_TABLET_MODE_GPIO_L
+#undef CONFIG_TABLET_MODE
+#undef CONFIG_TABLET_MODE_SWITCH
+
+#ifndef __ASSEMBLER__
+
+enum adc_channel {
+ /* Real ADC channels begin here */
+ ADC_BOARD_ID = 0,
+ ADC_EC_SKU_ID,
+ ADC_VBUS,
+ ADC_CH_COUNT
+};
+
+/* power signal definitions */
+enum power_signal {
+ AP_IN_S3_L,
+ PMIC_PWR_GOOD,
+
+ /* Number of signals */
+ POWER_SIGNAL_COUNT,
+};
+
+/* Motion sensors */
+enum sensor_id {
+ LID_ACCEL = 0,
+ BASE_ACCEL,
+ BASE_GYRO,
+ SENSOR_COUNT,
+};
+
+enum charge_port {
+ CHARGE_PORT_USB_C,
+};
+
+enum battery_type {
+ BATTERY_LGC_AP18C8K,
+ BATTERY_MURATA_AP18C4K,
+ BATTERY_PANASONIC_AP19B5K_KT00305011,
+ BATTERY_LGC_AP19B8K,
+ BATTERY_COSMX_AP20CBL,
+ BATTERY_SMP_AP18C7K,
+ BATTERY_TYPE_COUNT,
+};
+
+#include "gpio_signal.h"
+#include "registers.h"
+
+/* support factory keyboard test */
+#define CONFIG_KEYBOARD_FACTORY_TEST
+#define GPIO_KBD_KSO2 GPIO_EC_KSO_02_INV
+extern const int keyboard_factory_scan_pins[][2];
+extern const int keyboard_factory_scan_pins_used;
+
+#ifdef SECTION_IS_RO
+/* Interrupt handler for AP jump to BL */
+void emmc_ap_jump_to_bl(enum gpio_signal signal);
+#endif
+
+void bc12_interrupt(enum gpio_signal signal);
+void board_reset_pd_mcu(void);
+int board_get_version(void);
+
+/* returns the i2c port number of charger/battery */
+int board_get_charger_i2c(void);
+int board_get_battery_i2c(void);
+
+/* Motion sensor interrupt */
+void motion_interrupt(enum gpio_signal signal);
+
+#endif /* !__ASSEMBLER__ */
+
+#endif /* __CROS_EC_BOARD_H */
diff --git a/board/pico/build.mk b/board/pico/build.mk
new file mode 100644
index 0000000000..9ca7933e2a
--- /dev/null
+++ b/board/pico/build.mk
@@ -0,0 +1,15 @@
+# -*- makefile -*-
+# Copyright 2021 The Chromium OS Authors. All rights reserved.
+# Use of this source code is governed by a BSD-style license that can be
+# found in the LICENSE file.
+#
+# Board specific files build
+#
+#
+# IC is ITE IT81202
+CHIP:=it83xx
+CHIP_FAMILY:=it8xxx2
+CHIP_VARIANT:=it81202bx_1024
+BASEBOARD:=kukui
+
+board-y=battery.o board.o led.o
diff --git a/board/pico/ec.tasklist b/board/pico/ec.tasklist
new file mode 100644
index 0000000000..e8ad538bc2
--- /dev/null
+++ b/board/pico/ec.tasklist
@@ -0,0 +1,17 @@
+/* Copyright 2021 The Chromium OS Authors. All rights reserved.
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+/**
+ * See CONFIG_TASK_LIST in config.h for details.
+ */
+#define CONFIG_TASK_LIST \
+ TASK_ALWAYS(HOOKS, hook_task, NULL, VENTI_TASK_STACK_SIZE) \
+ TASK_ALWAYS(CHARGER, charger_task, NULL, VENTI_TASK_STACK_SIZE) \
+ TASK_ALWAYS(USB_CHG_P0, usb_charger_task, NULL, VENTI_TASK_STACK_SIZE) \
+ TASK_NOTEST(CHIPSET, chipset_task, NULL, LARGER_TASK_STACK_SIZE) \
+ TASK_ALWAYS(HOSTCMD, host_command_task, NULL, 1024) \
+ TASK_ALWAYS(CONSOLE, console_task, NULL, VENTI_TASK_STACK_SIZE) \
+ TASK_NOTEST(KEYSCAN, keyboard_scan_task, NULL, LARGER_TASK_STACK_SIZE) \
+ TASK_ALWAYS(PD_C0, pd_task, NULL, 1280)
diff --git a/board/pico/gpio.inc b/board/pico/gpio.inc
new file mode 100644
index 0000000000..a3a097c17b
--- /dev/null
+++ b/board/pico/gpio.inc
@@ -0,0 +1,148 @@
+/* -*- mode:c -*-
+ *
+ * Copyright 2021 The Chromium OS Authors. All rights reserved.
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+/*
+ * Declare symbolic names for all the GPIOs that we care about.
+ * Note: Those with interrupt handlers must be declared first.
+ */
+
+/* Interrupts */
+GPIO_INT(POWER_BUTTON_L, PIN(E, 4), GPIO_INT_BOTH,
+ power_button_interrupt) /* EC_PWR_BTN_ODL */
+GPIO_INT(AP_IN_SLEEP_L, PIN(F, 2), GPIO_INT_BOTH | GPIO_PULL_DOWN | GPIO_SEL_1P8V,
+ power_signal_interrupt)
+GPIO_INT(PMIC_EC_RESETB, PIN(F, 3), GPIO_INT_BOTH | GPIO_PULL_DOWN | GPIO_SEL_1P8V,
+ power_signal_interrupt)
+GPIO_INT(WARM_RESET_REQ, PIN(D, 3), GPIO_INT_RISING | GPIO_PULL_DOWN | GPIO_SEL_1P8V,
+ chipset_reset_request_interrupt)
+GPIO_INT_RO(BOOTBLOCK_EN_L, PIN(J, 1), GPIO_INT_RISING | GPIO_SEL_1P8V,
+ emmc_ap_jump_to_bl)
+GPIO_INT(SPI0_CS, PIN(M, 5), GPIO_INT_FALLING,
+ spi_event) /* SPI slave Chip Select -- AP_SPI_EC_CS_L */
+GPIO_INT(LID_OPEN, PIN(E, 2), GPIO_INT_BOTH,
+ lid_interrupt)
+GPIO_INT(AC_PRESENT, PIN(E, 5), GPIO_INT_BOTH,
+ extpower_interrupt) /* ACOK_OD */
+GPIO_INT(BC12_EC_INT_ODL, PIN(J, 6), GPIO_INT_FALLING,
+ bc12_interrupt)
+GPIO_INT(AP_EC_WATCHDOG_L, PIN(C, 7), GPIO_INT_FALLING | GPIO_SEL_1P8V,
+ chipset_watchdog_interrupt)
+GPIO_INT(UART1_RX, PIN(B, 0), GPIO_INT_FALLING,
+ uart_deepsleep_interrupt) /* UART_DEBUG_TX_EC_RX */
+/* Unimplemented interrupts */
+GPIO(ACCEL_INT_ODL, PIN(J, 2), GPIO_INPUT)
+GPIO(TABLET_MODE_L, PIN(J, 7), GPIO_INPUT)
+GPIO(VOLUME_DOWN_L, PIN(D, 5), GPIO_INPUT)
+GPIO(VOLUME_UP_L, PIN(D, 6), GPIO_INPUT)
+GPIO(ALS_RGB_INT_ODL, PIN(F, 0), GPIO_INPUT)
+GPIO(LID_ACCEL_INT_ODL, PIN(J, 3), GPIO_INPUT | GPIO_SEL_1P8V)
+
+/* Reset pins */
+GPIO(AP_SYS_RST_L, PIN(B, 6), GPIO_OUT_LOW)
+/* 1.8V PP or 1.8V OD output with external 10K PU */
+GPIO(PMIC_WATCHDOG_L, PIN(H, 0), GPIO_ODR_LOW | GPIO_SEL_1P8V)
+/* OD output with 5VT (there is 5V internal PU on PWRKEY of MT6358) */
+GPIO(PMIC_EN_ODL, PIN(E, 1), GPIO_ODR_HIGH)
+
+/*
+ * I2C pins should be configured as inputs until I2C module is
+ * initialized. This will avoid driving the lines unintentionally.
+ */
+/* EC programming */
+GPIO(I2C_E_SCL, PIN(A, 4), GPIO_INPUT | GPIO_SEL_1P8V)
+GPIO(I2C_E_SDA, PIN(A, 5), GPIO_INPUT | GPIO_SEL_1P8V)
+/* battery and charger */
+GPIO(I2C_A_SCL, PIN(B, 3), GPIO_INPUT)
+GPIO(I2C_A_SDA, PIN(B, 4), GPIO_INPUT)
+/* sensor */
+GPIO(I2C_B_SCL, PIN(C, 1), GPIO_INPUT | GPIO_SEL_1P8V)
+GPIO(I2C_B_SDA, PIN(C, 2), GPIO_INPUT | GPIO_SEL_1P8V)
+/* typec */
+GPIO(I2C_C_SCL, PIN(F, 6), GPIO_INPUT)
+GPIO(I2C_C_SDA, PIN(F, 7), GPIO_INPUT)
+
+/* Other input pins */
+/* TODO(WP_L): change to interrupt pin ? */
+GPIO(WP_L, PIN(I, 4), GPIO_INPUT | GPIO_SEL_1P8V) /* EC_FLASH_WP_ODL */
+GPIO(CCD_MODE_ODL, PIN(C, 4), GPIO_INPUT)
+
+/* Other output pins */
+GPIO(EC_BATT_PRES_ODL, PIN(C, 0), GPIO_INPUT)
+GPIO(EC_BL_EN_OD, PIN(B, 5), GPIO_ODR_HIGH | GPIO_SEL_1P8V)
+GPIO(EN_USBA_5V, PIN(B, 7), GPIO_OUT_LOW)
+GPIO(ENTERING_RW, PIN(C, 5), GPIO_ODR_HIGH) /* EC_ENTERING_RW_ODL */
+GPIO(EC_INT_L, PIN(E, 6), GPIO_ODR_HIGH | GPIO_SEL_1P8V) /* EC_AP_INT_ODL */
+GPIO(EC_BOARD_ID_EN_L, PIN(H, 5), GPIO_ODR_HIGH) /* EC_BOARD_ID_EN_ODL */
+GPIO(USB_C0_HPD_OD, PIN(J, 0), GPIO_ODR_LOW)
+GPIO(USB_C0_DISCHARGE, PIN(H, 3), GPIO_OUT_LOW)
+GPIO(EN_USB_C0_CC1_VCONN, PIN(H, 1), GPIO_OUT_LOW)
+GPIO(EN_USB_C0_CC2_VCONN, PIN(H, 2), GPIO_OUT_LOW)
+
+/* LEDs */
+GPIO(LED_BLUE, PIN(A, 2), GPIO_OUT_HIGH)
+GPIO(LED_GREEN, PIN(A, 1), GPIO_OUT_HIGH)
+GPIO(LED_ORANGE, PIN(A, 0), GPIO_OUT_HIGH)
+GPIO(EN_PP1800_S5_L, PIN(D, 0), GPIO_OUT_LOW)
+
+/* Unimplemented Pins */
+GPIO(PG_PP5000_A_OD, PIN(A, 6), GPIO_INPUT)
+GPIO(USB_A0_OC_ODL, PIN(A, 7), GPIO_INPUT)
+GPIO(EC_PROCHOT_ODL, PIN(C, 3), GPIO_INPUT)
+GPIO(PMIC_FORCE_RESET_ODL, PIN(C, 6), GPIO_INPUT)
+GPIO(USB_C0_PD_INT_ODL, PIN(D, 1), GPIO_INPUT) /* no used on this board */
+GPIO(EN_PP5000A_USM, PIN(D, 7), GPIO_INPUT)
+GPIO(EN_USBC_CHARGE_L, PIN(F, 1), GPIO_INPUT)
+GPIO(EN_PP5000_USBC, PIN(H, 4), GPIO_INPUT)
+GPIO(PP1800_H1_PG, PIN(H, 6), GPIO_INPUT)
+
+/* NC pins, ensure they aren't in floating state. */
+GPIO(NC_GPA3, PIN(A, 3), GPIO_INPUT | GPIO_PULL_DOWN)
+GPIO(NC_GPB2, PIN(B, 2), GPIO_INPUT | GPIO_PULL_DOWN)
+GPIO(NC_GPD2, PIN(D, 2), GPIO_INPUT | GPIO_PULL_DOWN)
+GPIO(NC_GPD4, PIN(D, 4), GPIO_INPUT | GPIO_PULL_DOWN)
+GPIO(NC_GPE0, PIN(E, 0), GPIO_INPUT | GPIO_PULL_DOWN)
+GPIO(NC_GPE3, PIN(E, 3), GPIO_INPUT | GPIO_PULL_DOWN)
+GPIO(NC_GPE7, PIN(E, 7), GPIO_INPUT | GPIO_PULL_DOWN)
+/*
+ * ADC pins don't have internal pull-down capability,
+ * so we set them as output low.
+ */
+GPIO(NC_GPI5, PIN(I, 5), GPIO_OUT_LOW)
+GPIO(NC_GPI7, PIN(I, 7), GPIO_OUT_LOW)
+
+GPIO(NC_GPJ4, PIN(J, 4), GPIO_INPUT | GPIO_PULL_DOWN)
+GPIO(NC_GPJ5, PIN(J, 5), GPIO_INPUT | GPIO_PULL_DOWN)
+/*
+ * GPG3,4,5,7 don't have internal pull-down capability,
+ * so we set them as output low.
+ */
+GPIO(NC_GPG0, PIN(G, 0), GPIO_INPUT | GPIO_PULL_DOWN)
+/* Don't touch GPG1 and GPG2 */
+GPIO(NC_GPG3, PIN(G, 3), GPIO_OUT_LOW)
+GPIO(EC_SPI_FLASH_MOSI, PIN(G, 4), GPIO_OUT_LOW)
+GPIO(EC_SPI_FLASH_MISO, PIN(G, 5), GPIO_OUT_LOW)
+GPIO(EC_SPI_FLASH_CLK, PIN(G, 6), GPIO_INPUT | GPIO_PULL_UP)
+GPIO(EC_SPI_FLASH_CS_L, PIN(G, 7), GPIO_OUT_LOW)
+
+/* Alternate functions GPIO definitions */
+/* Keyboard */
+ALTERNATE(PIN_MASK(KSI, 0xFF), 0, MODULE_KEYBOARD_SCAN, 0) /* KSI0-7 */
+ALTERNATE(PIN_MASK(KSO_H, 0xFF), 0, MODULE_KEYBOARD_SCAN, 0) /* KSO8-15 */
+ALTERNATE(PIN_MASK(KSO_L, 0xFB), 0, MODULE_KEYBOARD_SCAN, 0) /* KSO0-1, 3-7 */
+GPIO(EC_KSO_02_INV, PIN(KSO_L, 2), GPIO_OUT_LOW) /* KSO2 inverted */
+/* I2C */
+ALTERNATE(PIN_MASK(B, 0x18), 1, MODULE_I2C, 0) /* I2C A */
+ALTERNATE(PIN_MASK(C, 0x06), 1, MODULE_I2C, GPIO_SEL_1P8V) /* I2C B */
+ALTERNATE(PIN_MASK(F, 0xC0), 1, MODULE_I2C, 0) /* I2C C */
+/* ADC */
+ALTERNATE(PIN_MASK(I, 0x4F), 0, MODULE_ADC, 0) /* ADC 0,1,2,3,6 */
+/* UART */
+ALTERNATE(PIN_MASK(B, 0x03), 1, MODULE_UART, 0) /* EC to Servo */
+/* EMMC SPI SLAVE M2:CLK, M3:CMD, M6:DATA0 */
+ALTERNATE(PIN_MASK(M, 0x4C), 0, MODULE_SPI_FLASH, 0)
+/* SPI */
+ALTERNATE(PIN_MASK(M, 0x33), 0, MODULE_SPI, 0) /* SPI for communication */
diff --git a/board/pico/led.c b/board/pico/led.c
new file mode 100644
index 0000000000..076199b2ed
--- /dev/null
+++ b/board/pico/led.c
@@ -0,0 +1,80 @@
+/* Copyright 2021 The Chromium OS Authors. All rights reserved.
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ *
+ * Power and battery LED control for Jacuzzi
+ */
+#include "common.h"
+#include "ec_commands.h"
+#include "gpio.h"
+#include "led_common.h"
+#include "led_onoff_states.h"
+#define LED_ON_LVL 0
+#define LED_OFF_LVL 1
+__override const int led_charge_lvl_1 = 5;
+__override const int led_charge_lvl_2 = 95;
+__override struct led_descriptor
+ led_bat_state_table[LED_NUM_STATES][LED_NUM_PHASES] = {
+ [STATE_CHARGING_LVL_1] = {{EC_LED_COLOR_AMBER, LED_INDEFINITE} },
+ [STATE_CHARGING_LVL_2] = {{EC_LED_COLOR_AMBER, LED_INDEFINITE} },
+ [STATE_CHARGING_FULL_CHARGE] = {{EC_LED_COLOR_BLUE, LED_INDEFINITE} },
+ [STATE_DISCHARGE_S0] = {{EC_LED_COLOR_BLUE, LED_INDEFINITE} },
+ [STATE_DISCHARGE_S3] = {{EC_LED_COLOR_AMBER, 1 * LED_ONE_SEC},
+ {LED_OFF, 3 * LED_ONE_SEC} },
+ [STATE_DISCHARGE_S5] = {{LED_OFF, LED_INDEFINITE} },
+ [STATE_BATTERY_ERROR] = {{EC_LED_COLOR_AMBER, 1 * LED_ONE_SEC},
+ {LED_OFF, 1 * LED_ONE_SEC} },
+ [STATE_FACTORY_TEST] = {{EC_LED_COLOR_BLUE, 2 * LED_ONE_SEC},
+ {EC_LED_COLOR_AMBER, 2 * LED_ONE_SEC} },
+};
+const enum ec_led_id supported_led_ids[] = {
+ EC_LED_ID_BATTERY_LED
+};
+const int supported_led_ids_count = ARRAY_SIZE(supported_led_ids);
+__override void led_set_color_battery(enum ec_led_colors color)
+{
+ switch (color) {
+ case EC_LED_COLOR_AMBER:
+ gpio_set_level(GPIO_LED_ORANGE, LED_ON_LVL);
+ gpio_set_level(GPIO_LED_BLUE, LED_OFF_LVL);
+ gpio_set_level(GPIO_LED_GREEN, LED_OFF_LVL);
+ break;
+ case EC_LED_COLOR_BLUE:
+ gpio_set_level(GPIO_LED_BLUE, LED_ON_LVL);
+ gpio_set_level(GPIO_LED_ORANGE, LED_OFF_LVL);
+ gpio_set_level(GPIO_LED_GREEN, LED_OFF_LVL);
+ break;
+ case EC_LED_COLOR_GREEN:
+ gpio_set_level(GPIO_LED_GREEN, LED_ON_LVL);
+ gpio_set_level(GPIO_LED_BLUE, LED_OFF_LVL);
+ gpio_set_level(GPIO_LED_ORANGE, LED_OFF_LVL);
+ break;
+ default: /* LED_OFF and other unsupported colors */
+ gpio_set_level(GPIO_LED_GREEN, LED_OFF_LVL);
+ gpio_set_level(GPIO_LED_BLUE, LED_OFF_LVL);
+ gpio_set_level(GPIO_LED_ORANGE, LED_OFF_LVL);
+ break;
+ }
+}
+void led_get_brightness_range(enum ec_led_id led_id, uint8_t *brightness_range)
+{
+ if (led_id == EC_LED_ID_BATTERY_LED) {
+ brightness_range[EC_LED_COLOR_AMBER] = 1;
+ brightness_range[EC_LED_COLOR_BLUE] = 1;
+ brightness_range[EC_LED_COLOR_GREEN] = 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_AMBER] != 0)
+ led_set_color_battery(EC_LED_COLOR_AMBER);
+ else if (brightness[EC_LED_COLOR_BLUE] != 0)
+ led_set_color_battery(EC_LED_COLOR_BLUE);
+ else if (brightness[EC_LED_COLOR_GREEN] != 0)
+ led_set_color_battery(EC_LED_COLOR_GREEN);
+ else
+ led_set_color_battery(LED_OFF);
+ }
+ return EC_SUCCESS;
+}
diff --git a/board/pico/vif_override.xml b/board/pico/vif_override.xml
new file mode 100644
index 0000000000..32736caf64
--- /dev/null
+++ b/board/pico/vif_override.xml
@@ -0,0 +1,3 @@
+<!-- Add VIF field overrides here. See genvif.c and the Vendor Info File
+ Definition from the USB-IF.
+-->