mirror of
https://github.com/Telecominfraproject/OpenCellular.git
synced 2026-01-04 05:51:34 +00:00
For historical reasons, CCD, reset, and power button control were scattered around several files. Consolidate the code in more sensible (in retrospect) places. No functional changes, just moving code. BUG=none BRANCH=cr50 TEST=make buildall; boot cr50 Change-Id: Ic381a5a5d0627753cc771189aa377e88b81b155e Signed-off-by: Randall Spangler <rspangler@chromium.org> Reviewed-on: https://chromium-review.googlesource.com/653766 Reviewed-by: Mary Ruthven <mruthven@chromium.org>
119 lines
3.0 KiB
C
119 lines
3.0 KiB
C
/* Copyright 2017 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 "console.h"
|
|
#include "gpio.h"
|
|
#include "hooks.h"
|
|
#include "physical_presence.h"
|
|
#include "rbox.h"
|
|
#include "registers.h"
|
|
#include "system.h"
|
|
#include "system_chip.h"
|
|
#include "task.h"
|
|
#include "timer.h"
|
|
|
|
#define CPRINTS(format, args...) cprints(CC_RBOX, format, ## args)
|
|
#define CPRINTF(format, args...) cprintf(CC_RBOX, format, ## args)
|
|
|
|
/**
|
|
* Enable/disable power button interrupt.
|
|
*
|
|
* @param enable Enable (!=0) or disable (==0)
|
|
*/
|
|
static void power_button_enable_interrupt(int enable)
|
|
{
|
|
if (enable) {
|
|
/* Clear any leftover power button interrupts */
|
|
GWRITE_FIELD(RBOX, INT_STATE, INTR_PWRB_IN_FED, 1);
|
|
|
|
/* Enable power button interrupt */
|
|
GWRITE_FIELD(RBOX, INT_ENABLE, INTR_PWRB_IN_FED, 1);
|
|
task_enable_irq(GC_IRQNUM_RBOX0_INTR_PWRB_IN_FED_INT);
|
|
} else {
|
|
GWRITE_FIELD(RBOX, INT_ENABLE, INTR_PWRB_IN_FED, 0);
|
|
task_disable_irq(GC_IRQNUM_RBOX0_INTR_PWRB_IN_FED_INT);
|
|
}
|
|
}
|
|
|
|
static void power_button_handler(void)
|
|
{
|
|
CPRINTS("power button pressed");
|
|
|
|
if (physical_detect_press() != EC_SUCCESS) {
|
|
/* Not consumed by physical detect */
|
|
#ifdef CONFIG_U2F
|
|
/* Track last power button press for U2F */
|
|
power_button_record();
|
|
#endif
|
|
}
|
|
|
|
GWRITE_FIELD(RBOX, INT_STATE, INTR_PWRB_IN_FED, 1);
|
|
}
|
|
DECLARE_IRQ(GC_IRQNUM_RBOX0_INTR_PWRB_IN_FED_INT, power_button_handler, 1);
|
|
|
|
#ifdef CONFIG_U2F
|
|
static void power_button_init(void)
|
|
{
|
|
/*
|
|
* Enable power button interrupts all the time for U2F.
|
|
*
|
|
* Ideally U2F should only enable physical presence after the start of
|
|
* a U2F request (using atomic operations for the PP enable mask so it
|
|
* plays nicely with CCD config), but that doesn't happen yet.
|
|
*/
|
|
power_button_enable_interrupt(1);
|
|
}
|
|
DECLARE_HOOK(HOOK_INIT, power_button_init, HOOK_PRIO_DEFAULT);
|
|
#endif /* CONFIG_U2F */
|
|
|
|
void board_physical_presence_enable(int enable)
|
|
{
|
|
#ifndef CONFIG_U2F
|
|
/* Enable/disable power button interrupts */
|
|
power_button_enable_interrupt(enable);
|
|
#endif
|
|
|
|
/* Stay awake while we're doing this, just in case. */
|
|
if (enable)
|
|
disable_sleep(SLEEP_MASK_PHYSICAL_PRESENCE);
|
|
else
|
|
enable_sleep(SLEEP_MASK_PHYSICAL_PRESENCE);
|
|
}
|
|
|
|
static int command_powerbtn(int argc, char **argv)
|
|
{
|
|
char *e;
|
|
int ms = 200;
|
|
|
|
if (argc > 1) {
|
|
if (!strcasecmp("pulse", argv[1])) {
|
|
if (argc == 3) {
|
|
ms = strtoi(argv[2], &e, 0);
|
|
if (*e)
|
|
return EC_ERROR_PARAM2;
|
|
}
|
|
|
|
ccprintf("Force %dms power button press\n", ms);
|
|
|
|
rbox_powerbtn_press();
|
|
msleep(ms);
|
|
rbox_powerbtn_release();
|
|
} else if (!strcasecmp("press", argv[1])) {
|
|
rbox_powerbtn_press();
|
|
} else if (!strcasecmp("release", argv[1])) {
|
|
rbox_powerbtn_release();
|
|
} else
|
|
return EC_ERROR_PARAM1;
|
|
}
|
|
|
|
ccprintf("powerbtn: %s\n",
|
|
rbox_powerbtn_override_is_enabled() ? "forced press" :
|
|
rbox_powerbtn_is_pressed() ? "pressed\n" : "released\n");
|
|
return EC_SUCCESS;
|
|
}
|
|
DECLARE_CONSOLE_COMMAND(powerbtn, command_powerbtn,
|
|
"[pulse [ms] | press | release]",
|
|
"get/set the state of the power button");
|