summaryrefslogtreecommitdiff
path: root/zephyr/projects/nissa/src/common.c
diff options
context:
space:
mode:
Diffstat (limited to 'zephyr/projects/nissa/src/common.c')
-rw-r--r--zephyr/projects/nissa/src/common.c154
1 files changed, 154 insertions, 0 deletions
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;
+}