mirror of
https://github.com/Telecominfraproject/OpenCellular.git
synced 2026-01-08 16:41:55 +00:00
Add a test of checking power button handling
This test checks power button is correctly debounced, and also check power button press of different length are handled correctly. BUG=chrome-os-partner:10273 TEST=Test passed Change-Id: I18595c60896255d36326731d28bab55e64c6bca2 Reviewed-on: https://gerrit.chromium.org/gerrit/25505 Reviewed-by: Vincent Palatin <vpalatin@chromium.org> Reviewed-by: Randall Spangler <rspangler@chromium.org> Tested-by: Vic Yang <victoryang@chromium.org> Commit-Ready: Vic Yang <victoryang@chromium.org>
This commit is contained in:
117
chip/lm4/mock_gpio.c
Normal file
117
chip/lm4/mock_gpio.c
Normal file
@@ -0,0 +1,117 @@
|
||||
/* Copyright (c) 2012 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.
|
||||
*/
|
||||
|
||||
/* Mock GPIO module for Chrome EC */
|
||||
|
||||
#include "board.h"
|
||||
#include "console.h"
|
||||
#include "gpio.h"
|
||||
#include "util.h"
|
||||
|
||||
|
||||
static int8_t mock_value[GPIO_COUNT] = {0};
|
||||
static int8_t mock_gpio_im[GPIO_COUNT] = {0};
|
||||
|
||||
|
||||
int gpio_pre_init(void)
|
||||
{
|
||||
/* Nothing to do */
|
||||
return EC_SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
void gpio_set_alternate_function(int port, int mask, int func)
|
||||
{
|
||||
/* Not implemented */
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
const char *gpio_get_name(enum gpio_signal signal)
|
||||
{
|
||||
return gpio_list[signal].name;
|
||||
}
|
||||
|
||||
|
||||
int gpio_get_level(enum gpio_signal signal)
|
||||
{
|
||||
return mock_value[signal] ? 1 : 0;
|
||||
}
|
||||
|
||||
|
||||
int gpio_set_level(enum gpio_signal signal, int value)
|
||||
{
|
||||
mock_value[signal] = value;
|
||||
return EC_SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
int gpio_set_flags(enum gpio_signal signal, int flags)
|
||||
{
|
||||
/* Not implemented */
|
||||
return EC_SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
int gpio_enable_interrupt(enum gpio_signal signal)
|
||||
{
|
||||
const struct gpio_info *g = gpio_list + signal;
|
||||
|
||||
/* Fail if no interrupt handler */
|
||||
if (!g->irq_handler)
|
||||
return EC_ERROR_UNKNOWN;
|
||||
|
||||
mock_gpio_im[signal] = 1;
|
||||
return EC_SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
/* Find a GPIO signal by name. Returns the signal index, or GPIO_COUNT if
|
||||
* no match. */
|
||||
static enum gpio_signal find_signal_by_name(const char *name)
|
||||
{
|
||||
const struct gpio_info *g = gpio_list;
|
||||
int i;
|
||||
|
||||
if (!name || !*name)
|
||||
return GPIO_COUNT;
|
||||
|
||||
for (i = 0; i < GPIO_COUNT; i++, g++) {
|
||||
if (!strcasecmp(name, g->name))
|
||||
return i;
|
||||
}
|
||||
|
||||
return GPIO_COUNT;
|
||||
}
|
||||
|
||||
|
||||
static int command_gpio_mock(int argc, char **argv)
|
||||
{
|
||||
char *e;
|
||||
int v, i;
|
||||
const struct gpio_info *g;
|
||||
|
||||
if (argc < 3)
|
||||
return EC_ERROR_PARAM_COUNT;
|
||||
|
||||
i = find_signal_by_name(argv[1]);
|
||||
if (i == GPIO_COUNT)
|
||||
return EC_ERROR_PARAM1;
|
||||
g = gpio_list + i;
|
||||
|
||||
v = strtoi(argv[2], &e, 0);
|
||||
if (*e)
|
||||
return EC_ERROR_PARAM2;
|
||||
|
||||
gpio_set_level(i, v);
|
||||
|
||||
if (g->irq_handler && mock_gpio_im[i])
|
||||
g->irq_handler(i);
|
||||
return EC_SUCCESS;
|
||||
}
|
||||
DECLARE_CONSOLE_COMMAND(gpiomock, command_gpio_mock,
|
||||
"name <0 | 1>",
|
||||
"Mock a GPIO input",
|
||||
NULL);
|
||||
@@ -47,6 +47,13 @@ int pwm_get_keyboard_backlight_enabled(void)
|
||||
}
|
||||
|
||||
|
||||
int pwm_enable_keyboard_backlight(int enable)
|
||||
{
|
||||
/* Not implemented */
|
||||
return EC_SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
void pwm_task(void)
|
||||
{
|
||||
/* Do nothing */
|
||||
|
||||
58
common/mock_i8042.c
Normal file
58
common/mock_i8042.c
Normal file
@@ -0,0 +1,58 @@
|
||||
/* Copyright (c) 2012 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.
|
||||
*
|
||||
* Mock EC i8042 interface code.
|
||||
*/
|
||||
|
||||
#include "i8042.h"
|
||||
#include "timer.h"
|
||||
#include "uart.h"
|
||||
|
||||
|
||||
void i8042_receives_data(int data)
|
||||
{
|
||||
/* Not implemented */
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
void i8042_receives_command(int cmd)
|
||||
{
|
||||
/* Not implemented */
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
void i8042_command_task(void)
|
||||
{
|
||||
/* Do nothing */
|
||||
while (1)
|
||||
usleep(5000000);
|
||||
}
|
||||
|
||||
|
||||
enum ec_error_list i8042_send_to_host(int len, const uint8_t *bytes)
|
||||
{
|
||||
uart_printf("i8042 SEND\n");
|
||||
return EC_SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
void i8042_enable_keyboard_irq(void) {
|
||||
/* Not implemented */
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
void i8042_disable_keyboard_irq(void) {
|
||||
/* Not implemented */
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
void i8042_flush_buffer()
|
||||
{
|
||||
/* Not implemented */
|
||||
return;
|
||||
}
|
||||
@@ -6,11 +6,15 @@
|
||||
/* Mock X86 chipset power control module for Chrome EC */
|
||||
|
||||
#include "chipset.h"
|
||||
#include "console.h"
|
||||
#include "lpc.h"
|
||||
#include "timer.h"
|
||||
#include "uart.h"
|
||||
#include "util.h"
|
||||
#include "x86_power.h"
|
||||
|
||||
static int mock_power_on = 0;
|
||||
|
||||
void x86_power_cpu_overheated(int too_hot)
|
||||
{
|
||||
/* Print transitions */
|
||||
@@ -31,6 +35,12 @@ void x86_power_force_shutdown(void)
|
||||
}
|
||||
|
||||
|
||||
void x86_power_reset(int cold_reset)
|
||||
{
|
||||
uart_printf("X86 Power %s reset\n", cold_reset ? "cold" : "warm");
|
||||
}
|
||||
|
||||
|
||||
void chipset_throttle_cpu(int throttle)
|
||||
{
|
||||
/* Print transitions */
|
||||
@@ -45,6 +55,23 @@ void chipset_throttle_cpu(int throttle)
|
||||
}
|
||||
|
||||
|
||||
void chipset_exit_hard_off(void)
|
||||
{
|
||||
/* Not implemented */
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
int chipset_in_state(int state_mask)
|
||||
{
|
||||
if (mock_power_on)
|
||||
return state_mask == CHIPSET_STATE_ON;
|
||||
else
|
||||
return (state_mask == CHIPSET_STATE_SOFT_OFF) ||
|
||||
(state_mask == CHIPSET_STATE_ANY_OFF);
|
||||
}
|
||||
|
||||
|
||||
void x86_power_interrupt(enum gpio_signal signal)
|
||||
{
|
||||
/* Not implemented */
|
||||
@@ -58,3 +85,25 @@ void x86_power_task(void)
|
||||
while (1)
|
||||
usleep(5000000);
|
||||
}
|
||||
|
||||
|
||||
static int command_mock_power(int argc, char **argv)
|
||||
{
|
||||
if (argc != 2)
|
||||
return EC_ERROR_PARAM_COUNT;
|
||||
|
||||
if (!strcasecmp(argv[1], "on")) {
|
||||
mock_power_on = 1;
|
||||
}
|
||||
else if (!strcasecmp(argv[1], "off")) {
|
||||
mock_power_on = 0;
|
||||
}
|
||||
else
|
||||
return EC_ERROR_PARAM1;
|
||||
|
||||
return EC_SUCCESS;
|
||||
}
|
||||
DECLARE_CONSOLE_COMMAND(powermock, command_mock_power,
|
||||
"<on | off>",
|
||||
"Mock power state",
|
||||
NULL);
|
||||
|
||||
@@ -7,6 +7,7 @@
|
||||
#
|
||||
|
||||
test-list=hello pingpong timer_calib timer_dos timer_jump mutex thermal
|
||||
test-list+=power_button
|
||||
#disable: powerdemo
|
||||
|
||||
pingpong-y=pingpong.o
|
||||
@@ -20,3 +21,9 @@ chip-mock-thermal-lpc.o=mock_lpc.o
|
||||
chip-mock-thermal-pwm.o=mock_pwm.o
|
||||
common-mock-thermal-x86_power.o=mock_x86_power.o
|
||||
common-mock-thermal-temp_sensor.o=mock_temp_sensor.o
|
||||
|
||||
# Mock modules for 'power_button'
|
||||
chip-mock-power_button-gpio.o=mock_gpio.o
|
||||
chip-mock-power_button-pwm.o=mock_pwm.o
|
||||
common-mock-power_button-x86_power.o=mock_x86_power.o
|
||||
common-mock-power_button-i8042.o=mock_i8042.o
|
||||
|
||||
174
test/power_button.py
Normal file
174
test/power_button.py
Normal file
@@ -0,0 +1,174 @@
|
||||
# Copyright (c) 2011 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.
|
||||
#
|
||||
# Power button debounce test
|
||||
#
|
||||
# Refer to section 1.3 Power Button of
|
||||
# https://sites.google.com/a/google.com/chromeos-partners/pages/
|
||||
# tech-docs/firmware/ec-specification-v119
|
||||
#
|
||||
|
||||
import time
|
||||
|
||||
SHORTER_THAN_T0 = 0.01
|
||||
LONGER_THAN_T0 = 0.05
|
||||
LONGER_THAN_T1 = 5
|
||||
|
||||
def check_no_output(helper, reg_ex):
|
||||
success = False
|
||||
try:
|
||||
helper.wait_output(reg_ex, use_re=True, timeout=1)
|
||||
except:
|
||||
success = True
|
||||
return success
|
||||
|
||||
def consume_output(helper, reg_ex):
|
||||
done = False
|
||||
while not done:
|
||||
try:
|
||||
helper.wait_output(reg_ex, use_re=True, timeout=1)
|
||||
except:
|
||||
done = True
|
||||
|
||||
def test(helper):
|
||||
helper.wait_output("--- UART initialized")
|
||||
# Release power button, set to soft off, and enable keyboard
|
||||
helper.ec_command("gpiomock POWER_BUTTONn 1")
|
||||
helper.ec_command("powermock off")
|
||||
helper.ec_command("kbd enable")
|
||||
consume_output(helper, "PB released")
|
||||
|
||||
helper.trace("Press power button for shorter than T0 and check this\n" +
|
||||
"event is ignored\n")
|
||||
helper.ec_command("gpiomock POWER_BUTTONn 0")
|
||||
time.sleep(SHORTER_THAN_T0)
|
||||
helper.ec_command("gpiomock POWER_BUTTONn 1")
|
||||
if not check_no_output(helper, "PB released"):
|
||||
return False
|
||||
|
||||
helper.trace("Press power button for longer than T0 and check this\n" +
|
||||
"event is treated as a single press.")
|
||||
helper.ec_command("gpiomock POWER_BUTTONn 0")
|
||||
time.sleep(LONGER_THAN_T0)
|
||||
helper.ec_command("gpiomock POWER_BUTTONn 1")
|
||||
helper.wait_output("PB released", timeout=1)
|
||||
# Expect shown only once
|
||||
if not check_no_output(helper, "PB released"):
|
||||
return False
|
||||
|
||||
helper.trace("Press power button for two consecutive SHORTER_THAN_T0\n" +
|
||||
"period and check this event is ignored\n")
|
||||
helper.ec_command("gpiomock POWER_BUTTONn 0")
|
||||
time.sleep(SHORTER_THAN_T0)
|
||||
helper.ec_command("gpiomock POWER_BUTTONn 1")
|
||||
time.sleep(SHORTER_THAN_T0)
|
||||
helper.ec_command("gpiomock POWER_BUTTONn 0")
|
||||
time.sleep(SHORTER_THAN_T0)
|
||||
helper.ec_command("gpiomock POWER_BUTTONn 1")
|
||||
if not check_no_output(helper, "PB released"):
|
||||
return False
|
||||
|
||||
helper.trace("Hold down power button for LONGER_THAN_T0 and check a\n" +
|
||||
"single press is sent out\n")
|
||||
consume_output(helper, "pwrbtn=")
|
||||
helper.ec_command("gpiomock POWER_BUTTONn 0")
|
||||
time.sleep(LONGER_THAN_T0)
|
||||
helper.ec_command("gpiomock POWER_BUTTONn 1")
|
||||
helper.wait_output("pwrbtn=LOW", timeout=1)
|
||||
helper.wait_output("pwrbtn=HIGH", timeout=1)
|
||||
if not check_no_output(helper, "pwrbtn=LOW"):
|
||||
return False
|
||||
|
||||
helper.trace("Press power button for SHORTER_THAN_T0, release for\n" +
|
||||
"SHORTER_THAN_T0, and then press for LONGER_THAN_T0.\n" +
|
||||
"Check this is treated as a single press\n")
|
||||
helper.ec_command("gpiomock POWER_BUTTONn 0")
|
||||
time.sleep(SHORTER_THAN_T0)
|
||||
helper.ec_command("gpiomock POWER_BUTTONn 1")
|
||||
time.sleep(SHORTER_THAN_T0)
|
||||
helper.ec_command("gpiomock POWER_BUTTONn 0")
|
||||
time.sleep(LONGER_THAN_T0)
|
||||
helper.ec_command("gpiomock POWER_BUTTONn 1")
|
||||
helper.wait_output("pwrbtn=LOW", timeout=1)
|
||||
helper.wait_output("pwrbtn=HIGH", timeout=1)
|
||||
if not check_no_output(helper, "pwrbtn=LOW"):
|
||||
return False
|
||||
|
||||
helper.trace("Hold down power button, wait for power button press\n" +
|
||||
"sent out. Then relase for SHORTER_THAN_T0, check power\n" +
|
||||
"button release is not sent out. Expect power button is\n" +
|
||||
"treated as hold (ignoring the relase bounce)\n")
|
||||
helper.ec_command("gpiomock POWER_BUTTONn 0")
|
||||
helper.wait_output("pwrbtn=LOW", timeout=1)
|
||||
helper.ec_command("gpiomock POWER_BUTTONn 1")
|
||||
time.sleep(SHORTER_THAN_T0)
|
||||
helper.ec_command("gpiomock POWER_BUTTONn 0")
|
||||
if not check_no_output(helper, "PB released"):
|
||||
return False
|
||||
helper.ec_command("gpiomock POWER_BUTTONn 1")
|
||||
helper.wait_output("PB released", timeout=1)
|
||||
|
||||
helper.trace("When system is off, hold down power button for\n" +
|
||||
"LONGER_THAN_T0. Check the initial is stretched\n")
|
||||
consume_output(helper, "pwrbtn=")
|
||||
helper.ec_command("gpiomock POWER_BUTTONn 0")
|
||||
time.sleep(LONGER_THAN_T0)
|
||||
helper.ec_command("gpiomock POWER_BUTTONn 1")
|
||||
t_low = helper.wait_output("\[(?P<t>[\d\.]+) PB PCH pwrbtn=LOW\]",
|
||||
use_re=True)["t"]
|
||||
t_high = helper.wait_output("\[(?P<t>[\d\.]+) PB PCH pwrbtn=HIGH\]",
|
||||
use_re=True)["t"]
|
||||
if not check_no_output(helper, "pwrbtn=LOW"):
|
||||
return False
|
||||
if float(t_high) - float(t_low) <= LONGER_THAN_T0 - 0.1:
|
||||
return False
|
||||
|
||||
helper.trace("When system is off, hold down power button for\n" +
|
||||
"LONGER_THAN_T0. Check no scan code is send\n")
|
||||
consume_output(helper, "i8042 SEND")
|
||||
helper.ec_command("gpiomock POWER_BUTTONn 0")
|
||||
time.sleep(LONGER_THAN_T0)
|
||||
helper.ec_command("gpiomock POWER_BUTTONn 1")
|
||||
if not check_no_output(helper, "i8042 SEND"):
|
||||
return False
|
||||
|
||||
helper.trace("While powered on, hold down power button for\n" +
|
||||
"LONGER_THAN_T0. A single short pulse should be sent\n")
|
||||
consume_output(helper, "pwrbtn=")
|
||||
helper.ec_command("powermock on")
|
||||
helper.ec_command("gpiomock POWER_BUTTONn 0")
|
||||
time.sleep(LONGER_THAN_T0)
|
||||
helper.ec_command("gpiomock POWER_BUTTONn 1")
|
||||
t_low = helper.wait_output("\[(?P<t>[\d\.]+) PB PCH pwrbtn=LOW\]",
|
||||
use_re=True)["t"]
|
||||
t_high = helper.wait_output("\[(?P<t>[\d\.]+) PB PCH pwrbtn=HIGH\]",
|
||||
use_re=True)["t"]
|
||||
if not check_no_output(helper, "pwrbtn=LOW"):
|
||||
return False
|
||||
if float(t_high) - float(t_low) >= 0.1:
|
||||
return False
|
||||
|
||||
helper.trace("While powered on, hold down power button for\n" +
|
||||
"LONGER_THAN_T0. Scan code should be sent\n")
|
||||
consume_output(helper, "i8042 SEND")
|
||||
helper.ec_command("gpiomock POWER_BUTTONn 0")
|
||||
helper.wait_output("i8042 SEND", timeout=1) # Expect make code
|
||||
time.sleep(LONGER_THAN_T0)
|
||||
helper.ec_command("gpiomock POWER_BUTTONn 1")
|
||||
helper.wait_output("i8042 SEND", timeout=1) # Expect release code
|
||||
|
||||
helper.trace("While powered on, hold down power button for\n" +
|
||||
"LONGER_THAN_T1 and check two presses are sent out\n")
|
||||
consume_output(helper, "pwrbtn=")
|
||||
helper.ec_command("gpiomock POWER_BUTTONn 0")
|
||||
time.sleep(LONGER_THAN_T1)
|
||||
helper.ec_command("gpiomock POWER_BUTTONn 1")
|
||||
helper.wait_output("pwrbtn=LOW", timeout=1)
|
||||
helper.wait_output("pwrbtn=HIGH", timeout=1)
|
||||
helper.wait_output("pwrbtn=LOW", timeout=1)
|
||||
helper.wait_output("pwrbtn=HIGH", timeout=1)
|
||||
if not check_no_output(helper, "pwrbtn=LOW"):
|
||||
return False
|
||||
|
||||
return True # PASS !
|
||||
24
test/power_button.tasklist
Normal file
24
test/power_button.tasklist
Normal file
@@ -0,0 +1,24 @@
|
||||
/* Copyright (c) 2011 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.
|
||||
*/
|
||||
|
||||
/**
|
||||
* List of enabled tasks in the priority order
|
||||
*
|
||||
* The first one has the lowest priority.
|
||||
*
|
||||
* For each task, use the macro TASK(n, r, d) where :
|
||||
* 'n' in the name of the task
|
||||
* 'r' in the main routine of the task
|
||||
* 'd' in an opaque parameter passed to the routine at startup
|
||||
*/
|
||||
#define CONFIG_TASK_LIST \
|
||||
TASK(WATCHDOG, watchdog_task, NULL) \
|
||||
TASK(PWM, pwm_task, NULL) \
|
||||
TASK(TYPEMATIC, keyboard_typematic_task, NULL) \
|
||||
TASK(X86POWER, x86_power_task, NULL) \
|
||||
TASK(I8042CMD, i8042_command_task, NULL) \
|
||||
TASK(POWERBTN, power_button_task, NULL) \
|
||||
TASK(KEYSCAN, keyboard_scan_task, NULL) \
|
||||
TASK(CONSOLE, console_task, NULL)
|
||||
Reference in New Issue
Block a user