mirror of
https://github.com/Telecominfraproject/OpenCellular.git
synced 2025-12-29 01:50:53 +00:00
Update switch positions in EC mapped data
Note that this only handles lid and power button; see crosbug.com/p/8325 for write protect. Signed-off-by: Randall Spangler <rspangler@chromium.org> BUG=chrome-os-partner:8185 TEST=manual 1. Check state with lid open localhost ~ # ectool switches Current switches: 0x01 Lid switch: OPEN Power button: UP Write protect: ENABLED 2. Press power button localhost ~ # ectool switches Current switches: 0x03 Lid switch: OPEN Power button: DOWN Write protect: ENABLED 3. Release power button and close lid localhost ~ # ectool switches Current switches: 0x00 Lid switch: CLOSED Power button: UP Write protect: ENABLED Change-Id: I25f2fa3dfeac004dde9b10a4243ee235875f1b6e
This commit is contained in:
@@ -58,6 +58,8 @@ static uint64_t tnext_state;
|
||||
static uint64_t tdebounce_lid;
|
||||
static uint64_t tdebounce_pwr;
|
||||
|
||||
static uint8_t *memmap_switches;
|
||||
|
||||
|
||||
static void set_pwrbtn_to_pch(int high)
|
||||
{
|
||||
@@ -109,12 +111,14 @@ static void power_button_changed(uint64_t tnow)
|
||||
if (!gpio_get_level(GPIO_POWER_BUTTONn)) {
|
||||
/* pressed */
|
||||
pwrbtn_state = PWRBTN_STATE_START;
|
||||
*memmap_switches |= EC_LPC_SWITCH_POWER_BUTTON_PRESSED;
|
||||
keyboard_set_power_button(1);
|
||||
lpc_set_host_events(
|
||||
EC_LPC_HOST_EVENT_MASK(EC_LPC_HOST_EVENT_POWER_BUTTON));
|
||||
} else {
|
||||
/* released */
|
||||
pwrbtn_state = PWRBTN_STATE_STOPPING;
|
||||
*memmap_switches &= ~EC_LPC_SWITCH_POWER_BUTTON_PRESSED;
|
||||
keyboard_set_power_button(0);
|
||||
}
|
||||
tnext_state = tnow; /* Trigger next state transition now */
|
||||
@@ -134,12 +138,20 @@ static void lid_switch_changed(uint64_t tnow)
|
||||
lpc_set_host_events(EC_LPC_HOST_EVENT_MASK((v ?
|
||||
EC_LPC_HOST_EVENT_LID_OPEN : EC_LPC_HOST_EVENT_LID_CLOSED)));
|
||||
|
||||
/* If the lid has opened and the chipset is is soft-off, send a power
|
||||
* button pulse to wake up the chipset. */
|
||||
if (v && chipset_in_state(CHIPSET_STATE_SOFT_OFF)) {
|
||||
set_pwrbtn_to_pch(0);
|
||||
pwrbtn_state = PWRBTN_STATE_STOPPING;
|
||||
tnext_state = tnow + LID_PWRBTN_US;
|
||||
if (v) {
|
||||
/* Lid open */
|
||||
*memmap_switches |= EC_LPC_SWITCH_LID_OPEN;
|
||||
|
||||
/* If the chipset is is soft-off, send a power button pulse to
|
||||
* wake up the chipset. */
|
||||
if (chipset_in_state(CHIPSET_STATE_SOFT_OFF)) {
|
||||
set_pwrbtn_to_pch(0);
|
||||
pwrbtn_state = PWRBTN_STATE_STOPPING;
|
||||
tnext_state = tnow + LID_PWRBTN_US;
|
||||
}
|
||||
} else {
|
||||
/* Lid closed */
|
||||
*memmap_switches &= ~EC_LPC_SWITCH_LID_OPEN;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -163,6 +175,14 @@ void power_button_interrupt(enum gpio_signal signal)
|
||||
|
||||
int power_button_init(void)
|
||||
{
|
||||
/* Set up memory-mapped switch positions */
|
||||
memmap_switches = lpc_get_memmap_range() + EC_LPC_MEMMAP_SWITCHES;
|
||||
*memmap_switches = 0;
|
||||
if (gpio_get_level(GPIO_POWER_BUTTONn) == 0)
|
||||
*memmap_switches |= EC_LPC_SWITCH_POWER_BUTTON_PRESSED;
|
||||
if (gpio_get_level(GPIO_PCH_LID_SWITCHn) != 0)
|
||||
*memmap_switches |= EC_LPC_SWITCH_LID_OPEN;
|
||||
|
||||
/* Copy initial switch states to PCH */
|
||||
gpio_set_level(GPIO_PCH_PWRBTNn, gpio_get_level(GPIO_POWER_BUTTONn));
|
||||
gpio_set_level(GPIO_PCH_LID_SWITCHn, gpio_get_level(GPIO_LID_SWITCHn));
|
||||
@@ -235,6 +255,9 @@ static int command_powerbtn(int argc, char **argv)
|
||||
}
|
||||
}
|
||||
|
||||
/* Note that this only simulates the raw power button signal to the
|
||||
* PCH. It does not simulate the full state machine which sends SMIs
|
||||
* and other events to other parts of the EC and chipset. */
|
||||
uart_printf("Simulating %d ms power button press.\n", ms);
|
||||
set_pwrbtn_to_pch(0);
|
||||
usleep(ms * 1000);
|
||||
|
||||
@@ -40,13 +40,18 @@
|
||||
#define EC_LPC_MEMMAP_SWITCHES 0x30
|
||||
#define EC_LPC_MEMMAP_HOST_EVENTS 0x34
|
||||
|
||||
/* The battery bit flags. */
|
||||
/* Battery bit flags at EC_LPC_MEMMAP_BATT_FLAG. */
|
||||
#define EC_BATT_FLAG_AC_PRESENT 0x01
|
||||
#define EC_BATT_FLAG_BATT_PRESENT 0x02
|
||||
#define EC_BATT_FLAG_DISCHARGING 0x04
|
||||
#define EC_BATT_FLAG_CHARGING 0x08
|
||||
#define EC_BATT_FLAG_LEVEL_CRITICAL 0x10
|
||||
|
||||
/* Switch flags at EC_LPC_MEMMAP_SWITCHES */
|
||||
#define EC_LPC_SWITCH_LID_OPEN 0x01
|
||||
#define EC_LPC_SWITCH_POWER_BUTTON_PRESSED 0x02
|
||||
#define EC_LPC_SWITCH_WRITE_PROTECT_DISABLED 0x04
|
||||
|
||||
/* The offset of temperature value stored in mapped memory.
|
||||
* This allows reporting a temperature range of
|
||||
* 200K to 454K = -73C to 181C.
|
||||
|
||||
@@ -52,6 +52,8 @@ const char help_str[] =
|
||||
" Reads a pattern from the EC via LPC\n"
|
||||
" sertest\n"
|
||||
" Serial output test for COM2\n"
|
||||
" switches\n"
|
||||
" Prints current EC switch positions\n"
|
||||
" version\n"
|
||||
" Prints EC version\n"
|
||||
" temps <sensorid>\n"
|
||||
@@ -1030,6 +1032,21 @@ int cmd_host_event_clear(int argc, char *argv[])
|
||||
}
|
||||
|
||||
|
||||
int cmd_switches(int argc, char *argv[])
|
||||
{
|
||||
uint8_t s = read_mapped_mem8(EC_LPC_MEMMAP_SWITCHES);
|
||||
printf("Current switches: 0x%02x\n", s);
|
||||
printf("Lid switch: %s\n",
|
||||
(s & EC_LPC_SWITCH_LID_OPEN ? "OPEN" : "CLOSED"));
|
||||
printf("Power button: %s\n",
|
||||
(s & EC_LPC_SWITCH_POWER_BUTTON_PRESSED ? "DOWN" : "UP"));
|
||||
printf("Write protect: %sABLED\n",
|
||||
(s & EC_LPC_SWITCH_WRITE_PROTECT_DISABLED ? "DIS" : "EN"));
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
struct command {
|
||||
const char *name;
|
||||
int (*handler)(int argc, char *argv[]);
|
||||
@@ -1059,6 +1076,7 @@ const struct command commands[] = {
|
||||
{"queryec", cmd_acpi_query_ec},
|
||||
{"readtest", cmd_read_test},
|
||||
{"sertest", cmd_serial_test},
|
||||
{"switches", cmd_switches},
|
||||
{"temps", cmd_temperature},
|
||||
{"thermalget", cmd_thermal_get_threshold},
|
||||
{"thermalset", cmd_thermal_set_threshold},
|
||||
|
||||
Reference in New Issue
Block a user