summaryrefslogtreecommitdiff
path: root/board/treeya/board.c
diff options
context:
space:
mode:
authorChris Wang <chris.wang@amd.corp-partner.google.com>2019-07-19 14:03:30 +0800
committerCommit Bot <commit-bot@chromium.org>2019-07-25 02:21:44 +0000
commita4bc620109faba857e7e40fae76696b6374f87e7 (patch)
tree7b4e35ea3f68b40e397c48023f7f97c8deaf69da /board/treeya/board.c
parentfa1d673cfb32a89c5a067a06226dffb37ea2ed70 (diff)
downloadchrome-ec-a4bc620109faba857e7e40fae76696b6374f87e7.tar.gz
treeya: Add new grunt-family board.
Add treeya board. Initially base on aleena. BUG=b:135551210 BRANCH=none TEST=emerge-grunt chromeos-ec Ensure that ec.bin are created Change-Id: I16abc65af81d5127c0f964a42327e60a8674be22 Signed-off-by: Chris Wang <chris.wang@amd.corp-partner.google.com> Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/platform/ec/+/1710209 Reviewed-by: Edward Hill <ecgh@chromium.org> Commit-Queue: Edward Hill <ecgh@chromium.org> Tested-by: Edward Hill <ecgh@chromium.org>
Diffstat (limited to 'board/treeya/board.c')
-rw-r--r--board/treeya/board.c252
1 files changed, 252 insertions, 0 deletions
diff --git a/board/treeya/board.c b/board/treeya/board.c
new file mode 100644
index 0000000000..12f985e727
--- /dev/null
+++ b/board/treeya/board.c
@@ -0,0 +1,252 @@
+/* Copyright 2019 The Chromium OS Authors. All rights reserved.
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+/* Treeya board-specific configuration */
+
+#include "adc.h"
+#include "adc_chip.h"
+#include "button.h"
+#include "charge_manager.h"
+#include "charge_state.h"
+#include "charge_state_v2.h"
+#include "common.h"
+#include "compile_time_macros.h"
+#include "console.h"
+#include "driver/accelgyro_bmi160.h"
+#include "driver/led/lm3630a.h"
+#include "driver/ppc/sn5s330.h"
+#include "driver/tcpm/anx74xx.h"
+#include "driver/tcpm/ps8xxx.h"
+#include "driver/temp_sensor/sb_tsi.h"
+#include "ec_commands.h"
+#include "extpower.h"
+#include "gpio.h"
+#include "hooks.h"
+#include "i2c.h"
+#include "keyboard_scan.h"
+#include "lid_switch.h"
+#include "power.h"
+#include "power_button.h"
+#include "pwm.h"
+#include "pwm_chip.h"
+#include "registers.h"
+#include "switch.h"
+#include "system.h"
+#include "tablet_mode.h"
+#include "task.h"
+#include "tcpci.h"
+#include "temp_sensor.h"
+#include "thermistor.h"
+#include "usb_mux.h"
+#include "usb_pd_tcpm.h"
+#include "usbc_ppc.h"
+#include "util.h"
+
+#define CPRINTS(format, args...) cprints(CC_USBCHARGE, format, ## args)
+#define CPRINTF(format, args...) cprintf(CC_USBCHARGE, format, ## args)
+
+#ifdef CONFIG_USB_PD_TCPC_LOW_POWER
+static void anx74xx_cable_det_handler(void)
+{
+ int cable_det = gpio_get_level(GPIO_USB_C0_CABLE_DET);
+ int reset_n = gpio_get_level(GPIO_USB_C0_PD_RST_L);
+
+ /*
+ * A cable_det low->high transition was detected. If following the
+ * debounce time, cable_det is high, and reset_n is low, then ANX3429 is
+ * currently in standby mode and needs to be woken up. Set the
+ * TCPC_RESET event which will bring the ANX3429 out of standby
+ * mode. Setting this event is gated on reset_n being low because the
+ * ANX3429 will always set cable_det when transitioning to normal mode
+ * and if in normal mode, then there is no need to trigger a tcpc reset.
+ */
+ if (cable_det && !reset_n)
+ task_set_event(TASK_ID_PD_C0, PD_EVENT_TCPC_RESET, 0);
+}
+DECLARE_DEFERRED(anx74xx_cable_det_handler);
+
+void anx74xx_cable_det_interrupt(enum gpio_signal signal)
+{
+ /* debounce for 2 msec */
+ hook_call_deferred(&anx74xx_cable_det_handler_data, (2 * MSEC));
+}
+#endif
+
+static void ppc_interrupt(enum gpio_signal signal)
+{
+ int port = (signal == GPIO_USB_C0_SWCTL_INT_ODL) ? 0 : 1;
+
+ sn5s330_interrupt(port);
+}
+
+#include "gpio_list.h"
+
+const enum gpio_signal hibernate_wake_pins[] = {
+ GPIO_LID_OPEN,
+ GPIO_AC_PRESENT,
+ GPIO_POWER_BUTTON_L,
+ GPIO_EC_RST_ODL,
+};
+const int hibernate_wake_pins_used = ARRAY_SIZE(hibernate_wake_pins);
+
+/* I2C port map. */
+const struct i2c_port_t i2c_ports[] = {
+ {"power", I2C_PORT_POWER, 100, GPIO_I2C0_SCL, GPIO_I2C0_SDA},
+ {"tcpc0", I2C_PORT_TCPC0, 400, GPIO_I2C1_SCL, GPIO_I2C1_SDA},
+ {"tcpc1", I2C_PORT_TCPC1, 400, GPIO_I2C2_SCL, GPIO_I2C2_SDA},
+ {"thermal", I2C_PORT_THERMAL, 400, GPIO_I2C3_SCL, GPIO_I2C3_SDA},
+ {"kblight", I2C_PORT_KBLIGHT, 100, GPIO_I2C5_SCL, GPIO_I2C5_SDA},
+ {"sensor", I2C_PORT_SENSOR, 400, GPIO_I2C7_SCL, GPIO_I2C7_SDA},
+};
+const unsigned int i2c_ports_used = ARRAY_SIZE(i2c_ports);
+
+/* PWM channels. Must be in the exactly same order as in enum pwm_channel. */
+const struct pwm_t pwm_channels[] = {
+ [PWM_CH_KBLIGHT] = {
+ .channel = 5,
+ .flags = PWM_CONFIG_DSLEEP,
+ .freq = 100,
+ },
+};
+BUILD_ASSERT(ARRAY_SIZE(pwm_channels) == PWM_CH_COUNT);
+
+void board_update_sensor_config_from_sku(void)
+{
+ if (board_is_convertible()) {
+ /* Enable Gyro interrupts */
+ gpio_enable_interrupt(GPIO_6AXIS_INT_L);
+ } else {
+ motion_sensor_count = 0;
+ /* Device is clamshell only */
+ tablet_set_mode(0);
+ /* Gyro is not present, don't allow line to float */
+ gpio_set_flags(GPIO_6AXIS_INT_L,
+ GPIO_INPUT | GPIO_PULL_DOWN);
+ }
+}
+
+void board_overcurrent_event(int port, int is_overcurrented)
+{
+ enum gpio_signal signal = (port == 0) ? GPIO_USB_C0_OC_L
+ : GPIO_USB_C1_OC_L;
+ /* Note that the levels are inverted because the pin is active low. */
+ int lvl = is_overcurrented ? 0 : 1;
+
+ gpio_set_level(signal, lvl);
+
+ CPRINTS("p%d: overcurrent!", port);
+}
+
+void board_tcpc_init(void)
+{
+ int port;
+
+ /* Only reset TCPC if not sysjump */
+ if (!system_jumped_to_this_image())
+ board_reset_pd_mcu();
+
+ /* Enable PPC interrupts. */
+ gpio_enable_interrupt(GPIO_USB_C0_SWCTL_INT_ODL);
+ gpio_enable_interrupt(GPIO_USB_C1_SWCTL_INT_ODL);
+
+ /* Enable TCPC interrupts. */
+ gpio_enable_interrupt(GPIO_USB_C0_PD_INT_ODL);
+ gpio_enable_interrupt(GPIO_USB_C1_PD_INT_ODL);
+
+#ifdef CONFIG_USB_PD_TCPC_LOW_POWER
+ /* Enable CABLE_DET interrupt for ANX3429 wake from standby */
+ gpio_enable_interrupt(GPIO_USB_C0_CABLE_DET);
+#endif
+ /*
+ * Initialize HPD to low; after sysjump SOC needs to see
+ * HPD pulse to enable video path
+ */
+ for (port = 0; port < CONFIG_USB_PD_PORT_COUNT; port++) {
+ const struct usb_mux *mux = &usb_muxes[port];
+
+ mux->hpd_update(port, 0, 0);
+ }
+}
+DECLARE_HOOK(HOOK_INIT, board_tcpc_init, HOOK_PRIO_INIT_I2C + 1);
+
+uint16_t tcpc_get_alert_status(void)
+{
+ uint16_t status = 0;
+
+ if (!gpio_get_level(GPIO_USB_C0_PD_INT_ODL)) {
+ if (gpio_get_level(GPIO_USB_C0_PD_RST_L))
+ status |= PD_STATUS_TCPC_ALERT_0;
+ }
+
+ if (!gpio_get_level(GPIO_USB_C1_PD_INT_ODL)) {
+ if (gpio_get_level(GPIO_USB_C1_PD_RST_L))
+ status |= PD_STATUS_TCPC_ALERT_1;
+ }
+
+ return status;
+}
+
+/**
+ * Power on (or off) a single TCPC.
+ * minimum on/off delays are included.
+ *
+ * @param port Port number of TCPC.
+ * @param mode 0: power off, 1: power on.
+ */
+void board_set_tcpc_power_mode(int port, int mode)
+{
+ if (port != USB_PD_PORT_ANX74XX)
+ return;
+
+ switch (mode) {
+ case ANX74XX_NORMAL_MODE:
+ gpio_set_level(GPIO_EN_USB_C0_TCPC_PWR, 1);
+ msleep(ANX74XX_PWR_H_RST_H_DELAY_MS);
+ gpio_set_level(GPIO_USB_C0_PD_RST_L, 1);
+ break;
+ case ANX74XX_STANDBY_MODE:
+ gpio_set_level(GPIO_USB_C0_PD_RST_L, 0);
+ msleep(ANX74XX_RST_L_PWR_L_DELAY_MS);
+ gpio_set_level(GPIO_EN_USB_C0_TCPC_PWR, 0);
+ msleep(ANX74XX_PWR_L_PWR_H_DELAY_MS);
+ break;
+ default:
+ break;
+ }
+}
+
+void board_reset_pd_mcu(void)
+{
+ /* Assert reset to TCPC1 (ps8751) */
+ gpio_set_level(GPIO_USB_C1_PD_RST_L, 0);
+
+ /* Assert reset to TCPC0 (anx3429) */
+ gpio_set_level(GPIO_USB_C0_PD_RST_L, 0);
+
+ /* TCPC1 (ps8751) requires 1ms reset down assertion */
+ msleep(MAX(1, ANX74XX_RST_L_PWR_L_DELAY_MS));
+
+ /* Deassert reset to TCPC1 */
+ gpio_set_level(GPIO_USB_C1_PD_RST_L, 1);
+ /* Disable TCPC0 power */
+ gpio_set_level(GPIO_EN_USB_C0_TCPC_PWR, 0);
+
+ /*
+ * anx3429 requires 10ms reset/power down assertion
+ */
+ msleep(ANX74XX_PWR_L_PWR_H_DELAY_MS);
+ board_set_tcpc_power_mode(USB_PD_PORT_ANX74XX, 1);
+}
+
+static void board_kblight_init(void)
+{
+ /*
+ * Enable keyboard backlight. This needs to be done here because
+ * the chip doesn't have power until PP3300_S0 comes up.
+ */
+ gpio_set_level(GPIO_KB_BL_EN, 1);
+ lm3630a_poweron();
+}
+DECLARE_HOOK(HOOK_CHIPSET_RESUME, board_kblight_init, HOOK_PRIO_DEFAULT);