zinger: add hibernate if disconnected for 60s

Automatically go into hibernate (standby mode) if not powering
anything for 60 seconds. Will wake up when it is plugged into
something (senses pull-down on CC line).

BUG=chrome-os-partner:28335
BRANCH=samus
TEST=load onto zinger. if disconnected for 60s, see hibernate
print on zinger console. when connected to a device, verified
it boots again.

Change-Id: I2564c6192395bb5e4f6d7586c2725f13a4581049
Signed-off-by: Alec Berg <alecaberg@chromium.org>
Reviewed-on: https://chromium-review.googlesource.com/220837
Reviewed-by: Vincent Palatin <vpalatin@chromium.org>
This commit is contained in:
Alec Berg
2014-09-27 11:56:04 -07:00
committed by chrome-internal-fetch
parent beaddbf1a3
commit ba624e7241
5 changed files with 55 additions and 4 deletions

View File

@@ -41,6 +41,7 @@
#undef CONFIG_DEBUG_STACK_OVERFLOW
#undef CONFIG_FLASH
#undef CONFIG_FMAP
#define CONFIG_HIBERNATE_WAKEUP_PINS STM32_PWR_CSR_EWUP1
/* debug printf flash footprinf is about 1400 bytes */
#define CONFIG_DEBUG_PRINTF
@@ -92,6 +93,7 @@ void set_rtc_alarm(uint32_t delay_s, uint32_t delay_us,
void reset_rtc_alarm(uint32_t *rtc, uint32_t *rtcss);
int32_t get_rtc_diff(uint32_t rtc0, uint32_t rtc0ss,
uint32_t rtc1, uint32_t rtc1ss);
void __enter_hibernate(uint32_t seconds, uint32_t microseconds);
/* Reboot the CPU */
void cpu_reset(void);

View File

@@ -73,6 +73,14 @@ static void pins_init(void)
* PF0 (OUT - GPIO) : LM5050 FET driver off
* PF1 (OUT - GPIO) : discharge FET
*/
/*
* Clear power control/status register to disable wakeup
* pin A0, so that we can change it to an output.
*/
STM32_PWR_CSR = 0;
STM32_PWR_CR |= 0xc;
STM32_GPIO_ODR(GPIO_A) = HIGH(0) | HIGH(4);
STM32_GPIO_AFRL(GPIO_A) = AFx(7, 1);
STM32_GPIO_AFRH(GPIO_A) = AFx(9, 1) | AFx(10, 1);
@@ -157,7 +165,26 @@ static void irq_init(void)
extern void runtime_init(void);
void hardware_init(void)
{
uint32_t raw_cause = STM32_RCC_CSR;
uint32_t pwr_status = STM32_PWR_CSR;
power_init();
/* Clear the hardware reset cause by setting the RMVF bit */
STM32_RCC_CSR |= 1 << 24;
/* Clear SBF in PWR_CSR */
STM32_PWR_CR |= 1 << 3;
/*
* WORKAROUND: as we cannot de-activate the watchdog during
* long hibernation, we are woken-up once by the watchdog and
* go back to hibernate if we detect that condition, without
* watchdog initialized this time.
* The RTC deadline (if any) is already set.
*/
if ((pwr_status & 0x2) && (raw_cause & 0x60000000))
__enter_hibernate(0, 0);
system_init();
runtime_init(); /* sets clock */
pins_init();

View File

@@ -256,12 +256,25 @@ void pd_power_supply_reset(int port)
int pd_board_checks(void)
{
static timestamp_t hib_to;
static int hib_to_ready;
int vbus_volt;
int ovp_idx;
/* Reload the watchdog */
STM32_IWDG_KR = STM32_IWDG_KR_RELOAD;
/* If output is disabled for long enough, then hibernate */
if (!pd_is_connected(0) && hib_to_ready) {
if (get_time().val >= hib_to.val) {
debug_printf("hibernate\n");
__enter_hibernate(0, 0);
}
} else {
hib_to.val = get_time().val + 60*SECOND;
hib_to_ready = 1;
}
vbus_volt = adc_read_channel(ADC_CH_V_SENSE);
vbus_amp = adc_read_channel(ADC_CH_A_SENSE);

View File

@@ -285,7 +285,7 @@ static inline void set_state_timeout(int port,
}
/* Return flag for pd state is connected */
static int pd_is_connected(int port)
int pd_is_connected(int port)
{
if (pd[port].task_state == PD_STATE_DISABLED)
return 0;

View File

@@ -228,9 +228,6 @@ enum pd_data_msg_type {
#define PD_RST2 0x19
#define PD_EOP 0x0D
/* Issue PD soft reset */
void pd_soft_reset(void);
/* --- Policy layer functions --- */
/**
@@ -513,6 +510,15 @@ void pd_hw_release(int port);
*/
void pd_hw_init(int port);
/* --- Protocol layer functions --- */
/**
* Get connected state
*
* @param port USB-C port number
* @return True if port is in connected state
*/
int pd_is_connected(int port);
/**
* Get port polarity.
*
@@ -539,4 +545,7 @@ void pd_comm_enable(int enable);
*/
void pd_ping_enable(int port, int enable);
/* Issue PD soft reset */
void pd_soft_reset(void);
#endif /* __USB_PD_H */