/* Copyright 2015 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. */ /* glados_pd board configuration */ #include "adc.h" #include "adc_chip.h" #include "common.h" #include "console.h" #include "gpio.h" #include "hooks.h" #include "host_command.h" #include "i2c.h" #include "registers.h" #include "switch.h" #include "system.h" #include "task.h" #include "usb_pd.h" #include "usb_pd_tcpc.h" #include "util.h" #define CPRINTS(format, args...) cprints(CC_USBCHARGE, format, ## args) /* Indicate which source is driving the ec_int line. */ static uint32_t ec_int_status; static uint32_t pd_status_flags; void pd_send_ec_int(void) { /* If any sources are active, then drive the line low */ gpio_set_level(GPIO_EC_INT, !ec_int_status); } void board_config_pre_init(void) { /* enable SYSCFG clock */ STM32_RCC_APB2ENR |= 1 << 0; /* * the DMA mapping is : * Chan 2 : TIM1_CH1 (C0 RX) * Chan 3 : SPI1_TX (C0 TX) * Chan 4 : TIM3_CH1 (C1 RX) * Chan 5 : SPI2_TX (C1 TX) */ } #include "gpio_list.h" /* Initialize board. */ static void board_init(void) { /* Enable interrupts on VBUS transitions. */ gpio_enable_interrupt(GPIO_USB_C0_VBUS_WAKE_L); gpio_enable_interrupt(GPIO_USB_C1_VBUS_WAKE_L); /* Set PD MCU system status bits */ if (system_jumped_to_this_image()) pd_status_flags |= PD_STATUS_JUMPED_TO_IMAGE; if (system_is_in_rw()) pd_status_flags |= PD_STATUS_IN_RW; } DECLARE_HOOK(HOOK_INIT, board_init, HOOK_PRIO_DEFAULT); /* ADC channels */ const struct adc_t adc_channels[] = { /* USB PD CC lines sensing. Converted to mV (3300mV/4096). */ [ADC_C1_CC1_PD] = {"C1_CC1_PD", 3300, 4096, 0, STM32_AIN(0)}, [ADC_C0_CC1_PD] = {"C0_CC1_PD", 3300, 4096, 0, STM32_AIN(2)}, [ADC_C0_CC2_PD] = {"C0_CC2_PD", 3300, 4096, 0, STM32_AIN(4)}, [ADC_C1_CC2_PD] = {"C1_CC2_PD", 3300, 4096, 0, STM32_AIN(5)}, }; BUILD_ASSERT(ARRAY_SIZE(adc_channels) == ADC_CH_COUNT); /* I2C ports */ const struct i2c_port_t i2c_ports[] = { {"slave", I2C_PORT_SLAVE, 1000, GPIO_SLAVE_I2C_SCL, GPIO_SLAVE_I2C_SDA} }; const unsigned int i2c_ports_used = ARRAY_SIZE(i2c_ports); void tcpc_alert(int port) { /* * This function is called when the TCPC sets one of * bits in the Alert register and that bit's corresponding * location in the Alert_Mask register is set. */ atomic_or(&ec_int_status, port ? PD_STATUS_TCPC_ALERT_1 : PD_STATUS_TCPC_ALERT_0); pd_send_ec_int(); } void tcpc_alert_clear(int port) { /* * The TCPM has acknowledged all Alert bits and the * Alert# line needs to be set inactive. Clear * the corresponding port's bit in the static variable. */ atomic_clear(&ec_int_status, port ? PD_STATUS_TCPC_ALERT_1 : PD_STATUS_TCPC_ALERT_0); pd_send_ec_int(); } static void system_hibernate_deferred(void) { ccprintf("EC requested hibernate\n"); cflush(); system_hibernate(0, 0); } DECLARE_DEFERRED(system_hibernate_deferred); /****************************************************************************/ /* Console commands */ static int command_ec_int(int argc, char **argv) { /* Indicate that ec_int gpio is active due to host command */ atomic_or(&ec_int_status, PD_STATUS_HOST_EVENT); pd_send_ec_int(); return EC_SUCCESS; } DECLARE_CONSOLE_COMMAND(ecint, command_ec_int, "", "Toggle EC interrupt line"); static int ec_status_host_cmd(struct host_cmd_handler_args *args) { const struct ec_params_pd_status *p = args->params; struct ec_response_pd_status *r = args->response; /* * ec_int_status is used to store state for HOST_EVENT, * TCPC 0 Alert, and TCPC 1 Alert bits. */ r->status = ec_int_status | pd_status_flags; args->response_size = sizeof(*r); /* Have the PD follow the EC into hibernate. */ if (p->status & EC_STATUS_HIBERNATING) hook_call_deferred(&system_hibernate_deferred_data, 0); /* * If the source of the EC int line was HOST_EVENT, it has * been acknowledged so can always clear HOST_EVENT bit * from the ec_int_status variable */ atomic_clear(&ec_int_status, PD_STATUS_HOST_EVENT); return EC_RES_SUCCESS; } DECLARE_HOST_COMMAND(EC_CMD_PD_EXCHANGE_STATUS, ec_status_host_cmd, EC_VER_MASK(EC_VER_PD_EXCHANGE_STATUS));