summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorVic Yang <victoryang@chromium.org>2013-09-29 00:55:36 +0800
committerchrome-internal-fetch <chrome-internal-fetch@google.com>2013-10-01 08:16:34 +0000
commitc77575ac0daa5966772779cedbaab6f607cf9a98 (patch)
treef1e7cf3ca7f232e4be95b7bd57e652253eddaacc
parent2d856c51039153effe4b9e9d7924c841fb741da5 (diff)
downloadchrome-ec-c77575ac0daa5966772779cedbaab6f607cf9a98.tar.gz
Emulator support of fake GPIO input
For all GPIOs, the current values are recorded. A test can then change the value of a GPIO input by gpio_set_level(). The changed value is recorded and also interrupt is fired if the change fits the interrupt flags defined in board/host/board.c. BUG=chrome-os-partner:19235 TEST=Pass all tests BRANCH=None Change-Id: If8e547e5adf4a20dcb118f5fe2187293005d4ca3 Signed-off-by: Vic Yang <victoryang@chromium.org> Reviewed-on: https://chromium-review.googlesource.com/170907 Reviewed-by: Bill Richardson <wfrichar@chromium.org> Reviewed-by: Randall Spangler <rspangler@chromium.org> Reviewed-by: Vincent Palatin <vpalatin@chromium.org>
-rw-r--r--board/host/board.c10
-rw-r--r--chip/host/gpio.c35
-rw-r--r--test/adapter.c14
-rw-r--r--test/extpwr_gpio.c13
-rw-r--r--test/kb_8042.c27
-rw-r--r--test/led_lp5562.c10
-rw-r--r--test/lid_sw.c27
-rw-r--r--test/power_button.c30
-rw-r--r--test/sbs_charging.c32
9 files changed, 79 insertions, 119 deletions
diff --git a/board/host/board.c b/board/host/board.c
index c48a1d3c44..3fdc75f163 100644
--- a/board/host/board.c
+++ b/board/host/board.c
@@ -4,19 +4,23 @@
*/
/* Emulator board-specific configuration */
+#include "extpower.h"
#include "gpio.h"
+#include "lid_switch.h"
+#include "power_button.h"
#include "temp_sensor.h"
#include "util.h"
#define MOCK_GPIO(x) {#x, 0, 0, 0, 0}
+#define MOCK_GPIO_INT(x, i, r) {#x, 0, 0, i, r}
const struct gpio_info gpio_list[] = {
MOCK_GPIO(EC_INT),
- MOCK_GPIO(LID_OPEN),
- MOCK_GPIO(POWER_BUTTON_L),
+ MOCK_GPIO_INT(LID_OPEN, GPIO_INT_BOTH, lid_interrupt),
+ MOCK_GPIO_INT(POWER_BUTTON_L, GPIO_INT_BOTH, power_button_interrupt),
MOCK_GPIO(WP),
MOCK_GPIO(ENTERING_RW),
- MOCK_GPIO(AC_PRESENT),
+ MOCK_GPIO_INT(AC_PRESENT, GPIO_INT_BOTH, extpower_interrupt),
MOCK_GPIO(PCH_BKLTEN),
MOCK_GPIO(ENABLE_BACKLIGHT),
};
diff --git a/chip/host/gpio.c b/chip/host/gpio.c
index 64191aaca5..2fcb32b2a8 100644
--- a/chip/host/gpio.c
+++ b/chip/host/gpio.c
@@ -5,8 +5,15 @@
/* GPIO module for emulator */
+#include "console.h"
+
#include "common.h"
#include "gpio.h"
+#include "timer.h"
+#include "util.h"
+
+static int gpio_values[GPIO_COUNT];
+static int gpio_interrupt_enabled[GPIO_COUNT];
test_mockable void gpio_pre_init(void)
{
@@ -15,16 +22,42 @@ test_mockable void gpio_pre_init(void)
test_mockable int gpio_get_level(enum gpio_signal signal)
{
+ return gpio_values[signal];
+}
+
+static int gpio_interrupt_check(uint32_t flags, int old, int new)
+{
+ if ((flags & (GPIO_INT_F_RISING|GPIO_INT_F_BOTH)) &&
+ old == 0 && new == 1)
+ return 1;
+ if ((flags & (GPIO_INT_F_FALLING|GPIO_INT_F_BOTH)) &&
+ old == 1 && new == 0)
+ return 1;
+ if ((flags & GPIO_INT_F_LOW) && new == 0)
+ return 1;
+ if ((flags & GPIO_INT_F_HIGH) && new == 1)
+ return 1;
return 0;
}
test_mockable void gpio_set_level(enum gpio_signal signal, int value)
{
- /* Nothing */
+ const struct gpio_info *g = gpio_list + signal;
+ const uint32_t flags = g->flags;
+ const int old_value = gpio_values[signal];
+
+ gpio_values[signal] = value;
+
+ if (g->irq_handler == NULL || !gpio_interrupt_enabled[signal])
+ return;
+
+ if (gpio_interrupt_check(flags, old_value, value))
+ g->irq_handler(signal);
}
test_mockable int gpio_enable_interrupt(enum gpio_signal signal)
{
+ gpio_interrupt_enabled[signal] = 1;
return EC_SUCCESS;
}
diff --git a/test/adapter.c b/test/adapter.c
index 4a93e6089a..5ce9733b4b 100644
--- a/test/adapter.c
+++ b/test/adapter.c
@@ -22,14 +22,13 @@
#include "adapter_externs.h"
/* Local state */
-static int mock_ac;
static int mock_id;
static int mock_current;
static struct power_state_context ctx;
static void test_reset_mocks(void)
{
- mock_ac = 0;
+ gpio_set_level(GPIO_AC_PRESENT, 0);
mock_id = 0;
mock_current = 0;
memset(&ctx, 0, sizeof(ctx));
@@ -37,13 +36,6 @@ static void test_reset_mocks(void)
/* Mocked functions from the rest of the EC */
-int gpio_get_level(enum gpio_signal signal)
-{
- if (signal == GPIO_AC_PRESENT)
- return mock_ac;
- return 0;
-}
-
int adc_read_channel(enum adc_channel ch)
{
switch (ch) {
@@ -83,8 +75,7 @@ void chipset_throttle_cpu(int throttle)
static void change_ac(int val)
{
- mock_ac = val;
- extpower_interrupt(GPIO_AC_PRESENT);
+ gpio_set_level(GPIO_AC_PRESENT, val);
msleep(50);
}
@@ -183,6 +174,7 @@ static int test_turbo(void)
TEST_ASSERT(ac_turbo == 0);
test_turbo_init();
+ change_ac(0);
set_id(ad_id_vals[1].lo - 1);
change_ac(1);
watch_adapter_closely(&ctx);
diff --git a/test/extpwr_gpio.c b/test/extpwr_gpio.c
index c10dad6627..e2a6f830bf 100644
--- a/test/extpwr_gpio.c
+++ b/test/extpwr_gpio.c
@@ -15,22 +15,11 @@
#include "timer.h"
#include "util.h"
-static int mock_ac;
static int ac_hook_count;
-int gpio_get_level(enum gpio_signal signal)
-{
- if (signal == GPIO_AC_PRESENT)
- return mock_ac;
- return 0;
-}
-
static void set_ac(int val)
{
- if (val == mock_ac)
- return;
- mock_ac = val;
- extpower_interrupt(GPIO_AC_PRESENT);
+ gpio_set_level(GPIO_AC_PRESENT, val);
msleep(50);
}
diff --git a/test/kb_8042.c b/test/kb_8042.c
index 0bac5fedcf..88bae5d633 100644
--- a/test/kb_8042.c
+++ b/test/kb_8042.c
@@ -29,8 +29,6 @@ static unsigned int lpc_char_cnt;
/*****************************************************************************/
/* Mock functions */
-static int mock_power_button = 1;
-
int lid_is_open(void)
{
return 1;
@@ -41,13 +39,6 @@ void lpc_keyboard_put_char(uint8_t chr, int send_irq)
lpc_char_buf[lpc_char_cnt++] = chr;
}
-int gpio_get_level(enum gpio_signal signal)
-{
- if (signal == GPIO_POWER_BUTTON_L)
- return mock_power_button;
- return 0;
-}
-
/*****************************************************************************/
/* Test utilities */
@@ -209,33 +200,27 @@ static int test_power_button(void)
set_scancode(1);
test_chipset_on();
- mock_power_button = 0;
- power_button_interrupt(GPIO_POWER_BUTTON_L);
+ gpio_set_level(GPIO_POWER_BUTTON_L, 0);
VERIFY_LPC_CHAR_DELAY("\xe0\x5e", 100);
- mock_power_button = 1;
- power_button_interrupt(GPIO_POWER_BUTTON_L);
+ gpio_set_level(GPIO_POWER_BUTTON_L, 1);
VERIFY_LPC_CHAR_DELAY("\xe0\xde", 100);
set_scancode(2);
write_cmd_byte(read_cmd_byte() & ~I8042_XLATE);
- mock_power_button = 0;
- power_button_interrupt(GPIO_POWER_BUTTON_L);
+ gpio_set_level(GPIO_POWER_BUTTON_L, 0);
VERIFY_LPC_CHAR_DELAY("\xe0\x37", 100);
- mock_power_button = 1;
- power_button_interrupt(GPIO_POWER_BUTTON_L);
+ gpio_set_level(GPIO_POWER_BUTTON_L, 1);
VERIFY_LPC_CHAR_DELAY("\xe0\xf0\x37", 100);
test_chipset_off();
- mock_power_button = 0;
- power_button_interrupt(GPIO_POWER_BUTTON_L);
+ gpio_set_level(GPIO_POWER_BUTTON_L, 0);
VERIFY_NO_CHAR();
- mock_power_button = 1;
- power_button_interrupt(GPIO_POWER_BUTTON_L);
+ gpio_set_level(GPIO_POWER_BUTTON_L, 1);
VERIFY_NO_CHAR();
return EC_SUCCESS;
diff --git a/test/led_lp5562.c b/test/led_lp5562.c
index fe99d5eb44..79f01b297f 100644
--- a/test/led_lp5562.c
+++ b/test/led_lp5562.c
@@ -24,7 +24,6 @@ static uint8_t lp5562_reg[LP5562_NUM_WATCH_REG];
#define LED_COLOR_YELLOW LP5562_COLOR_BLUE(0x40)
#define LED_COLOR_RED LP5562_COLOR_RED(0x80)
-static int mock_ac;
static enum charging_state mock_charge_state = ST_IDLE;
static int lp5562_failed_i2c_reg = -1;
static const char * const state_names[] = POWER_STATE_NAME_TABLE;
@@ -32,16 +31,9 @@ static const char * const state_names[] = POWER_STATE_NAME_TABLE;
/*****************************************************************************/
/* Mock functions */
-int gpio_get_level(enum gpio_signal signal)
-{
- if (signal == GPIO_AC_PRESENT)
- return mock_ac;
- return 0;
-}
-
static void set_ac(int ac)
{
- mock_ac = ac;
+ gpio_set_level(GPIO_AC_PRESENT, ac);
ccprintf("[%T TEST AC = %d]\n", ac);
}
diff --git a/test/lid_sw.c b/test/lid_sw.c
index 52a4d033cb..dbd009990d 100644
--- a/test/lid_sw.c
+++ b/test/lid_sw.c
@@ -7,6 +7,7 @@
#include "common.h"
#include "console.h"
+#include "gpio.h"
#include "hooks.h"
#include "host_command.h"
#include "lid_switch.h"
@@ -14,16 +15,8 @@
#include "timer.h"
#include "util.h"
-static int mock_lid;
static int lid_hook_count;
-int gpio_get_level(enum gpio_signal signal)
-{
- if (signal == GPIO_LID_OPEN)
- return mock_lid;
- return 0;
-}
-
static void lid_change_hook(void)
{
lid_hook_count++;
@@ -39,14 +32,12 @@ int lid_memmap_state(void)
static int test_hook(void)
{
/* Close lid for testing */
- mock_lid = 0;
- lid_interrupt(GPIO_LID_OPEN);
+ gpio_set_level(GPIO_LID_OPEN, 0);
msleep(100);
lid_hook_count = 0;
host_clear_events(0xffffffff);
- mock_lid = 1;
- lid_interrupt(GPIO_LID_OPEN);
+ gpio_set_level(GPIO_LID_OPEN, 1);
msleep(50);
TEST_ASSERT(lid_hook_count == 1);
TEST_ASSERT(lid_is_open());
@@ -54,8 +45,7 @@ static int test_hook(void)
TEST_ASSERT(host_get_events() &
EC_HOST_EVENT_MASK(EC_HOST_EVENT_LID_OPEN));
- mock_lid = 0;
- lid_interrupt(GPIO_LID_OPEN);
+ gpio_set_level(GPIO_LID_OPEN, 0);
msleep(50);
TEST_ASSERT(lid_hook_count == 2);
TEST_ASSERT(!lid_is_open());
@@ -69,14 +59,12 @@ static int test_hook(void)
static int test_debounce(void)
{
/* Close lid for testing */
- mock_lid = 0;
- lid_interrupt(GPIO_LID_OPEN);
+ gpio_set_level(GPIO_LID_OPEN, 0);
msleep(100);
lid_hook_count = 0;
host_clear_events(0xffffffff);
- mock_lid = 1;
- lid_interrupt(GPIO_LID_OPEN);
+ gpio_set_level(GPIO_LID_OPEN, 1);
msleep(20);
TEST_ASSERT(lid_hook_count == 0);
TEST_ASSERT(!lid_is_open());
@@ -84,8 +72,7 @@ static int test_debounce(void)
TEST_ASSERT(!(host_get_events() &
EC_HOST_EVENT_MASK(EC_HOST_EVENT_LID_OPEN)));
- mock_lid = 0;
- lid_interrupt(GPIO_LID_OPEN);
+ gpio_set_level(GPIO_LID_OPEN, 0);
msleep(50);
TEST_ASSERT(lid_hook_count == 0);
TEST_ASSERT(!lid_is_open());
diff --git a/test/power_button.c b/test/power_button.c
index 5f7231b9f4..1205cfcca4 100644
--- a/test/power_button.c
+++ b/test/power_button.c
@@ -7,6 +7,7 @@
#include "common.h"
#include "console.h"
+#include "gpio.h"
#include "hooks.h"
#include "host_command.h"
#include "power_button.h"
@@ -14,20 +15,11 @@
#include "timer.h"
#include "util.h"
-static int mock_power_button = 1;
-static int mock_lid = 1;
static int pb_hook_count;
-int gpio_get_level(enum gpio_signal signal)
-{
- if (signal == GPIO_POWER_BUTTON_L)
- return mock_power_button;
- return 0;
-}
-
int lid_is_open(void)
{
- return mock_lid;
+ return 1;
}
static void pb_change_hook(void)
@@ -45,14 +37,12 @@ int pb_memmap_state(void)
static int test_hook(void)
{
/* Release power button for testing */
- mock_power_button = 1;
- power_button_interrupt(GPIO_POWER_BUTTON_L);
+ gpio_set_level(GPIO_POWER_BUTTON_L, 1);
msleep(100);
pb_hook_count = 0;
host_clear_events(0xffffffff);
- mock_power_button = 0;
- power_button_interrupt(GPIO_POWER_BUTTON_L);
+ gpio_set_level(GPIO_POWER_BUTTON_L, 0);
msleep(50);
TEST_ASSERT(pb_hook_count == 1);
TEST_ASSERT(power_button_is_pressed());
@@ -61,8 +51,7 @@ static int test_hook(void)
EC_HOST_EVENT_MASK(EC_HOST_EVENT_POWER_BUTTON));
host_clear_events(0xffffffff);
- mock_power_button = 1;
- power_button_interrupt(GPIO_POWER_BUTTON_L);
+ gpio_set_level(GPIO_POWER_BUTTON_L, 1);
msleep(50);
TEST_ASSERT(pb_hook_count == 2);
TEST_ASSERT(!power_button_is_pressed());
@@ -76,14 +65,12 @@ static int test_hook(void)
static int test_debounce(void)
{
/* Release power button for testing */
- mock_power_button = 1;
- power_button_interrupt(GPIO_POWER_BUTTON_L);
+ gpio_set_level(GPIO_POWER_BUTTON_L, 1);
msleep(100);
pb_hook_count = 0;
host_clear_events(0xffffffff);
- mock_power_button = 0;
- power_button_interrupt(GPIO_POWER_BUTTON_L);
+ gpio_set_level(GPIO_POWER_BUTTON_L, 0);
msleep(20);
TEST_ASSERT(pb_hook_count == 0);
TEST_ASSERT(!power_button_is_pressed());
@@ -91,8 +78,7 @@ static int test_debounce(void)
TEST_ASSERT(!(host_get_events() &
EC_HOST_EVENT_MASK(EC_HOST_EVENT_POWER_BUTTON)));
- mock_power_button = 1;
- power_button_interrupt(GPIO_POWER_BUTTON_L);
+ gpio_set_level(GPIO_POWER_BUTTON_L, 1);
msleep(50);
TEST_ASSERT(pb_hook_count == 0);
TEST_ASSERT(!power_button_is_pressed());
diff --git a/test/sbs_charging.c b/test/sbs_charging.c
index a411504ff2..adfc053e01 100644
--- a/test/sbs_charging.c
+++ b/test/sbs_charging.c
@@ -10,6 +10,7 @@
#include "chipset.h"
#include "common.h"
#include "ec_commands.h"
+#include "gpio.h"
#include "hooks.h"
#include "host_command.h"
#include "smart_battery.h"
@@ -20,20 +21,11 @@
#define WAIT_CHARGER_TASK 500
#define BATTERY_DETACH_DELAY 35000
-static int mock_ac_present = 1;
static int mock_chipset_state = CHIPSET_STATE_ON;
static int is_shutdown;
static int is_force_discharge;
static int is_hibernated;
-/* Mock GPIOs */
-int gpio_get_level(enum gpio_signal signal)
-{
- if (signal == GPIO_AC_PRESENT)
- return mock_ac_present;
- return 0;
-}
-
void chipset_force_shutdown(void)
{
is_shutdown = 1;
@@ -72,7 +64,7 @@ static void test_setup(void)
/* Discharging at 100mAh */
sb_write(SB_CURRENT, -100);
/* Unplug AC */
- mock_ac_present = 0;
+ gpio_set_level(GPIO_AC_PRESENT, 0);
}
static int wait_charging_state(void)
@@ -100,7 +92,7 @@ static int test_charge_state(void)
state = wait_charging_state();
/* Plug AC, charging at 1000mAh */
ccprintf("[CHARGING TEST] AC on\n");
- mock_ac_present = 1;
+ gpio_set_level(GPIO_AC_PRESENT, 1);
sb_write(SB_CURRENT, 1000);
state = wait_charging_state();
TEST_ASSERT(state == PWR_STATE_CHARGE);
@@ -121,14 +113,14 @@ static int test_charge_state(void)
/* Unplug AC, discharging at 1000mAh */
ccprintf("[CHARGING TEST] AC off\n");
- mock_ac_present = 0;
+ gpio_set_level(GPIO_AC_PRESENT, 0);
sb_write(SB_CURRENT, -1000);
state = wait_charging_state();
TEST_ASSERT(state == PWR_STATE_DISCHARGE);
/* Discharging overtemp */
ccprintf("[CHARGING TEST] AC off, batt temp = 90 C\n");
- mock_ac_present = 0;
+ gpio_set_level(GPIO_AC_PRESENT, 0);
sb_write(SB_CURRENT, -1000);
state = wait_charging_state();
@@ -141,7 +133,7 @@ static int test_charge_state(void)
/* Force idle */
ccprintf("[CHARGING TEST] AC on, force idle\n");
- mock_ac_present = 1;
+ gpio_set_level(GPIO_AC_PRESENT, 1);
sb_write(SB_CURRENT, 1000);
state = wait_charging_state();
TEST_ASSERT(state == PWR_STATE_CHARGE);
@@ -154,7 +146,7 @@ static int test_charge_state(void)
/* Force discharge */
ccprintf("[CHARGING TEST] AC on, force discharge\n");
- mock_ac_present = 1;
+ gpio_set_level(GPIO_AC_PRESENT, 1);
sb_write(SB_CURRENT, 1000);
charge_control(CHARGE_CONTROL_DISCHARGE);
state = wait_charging_state();
@@ -171,7 +163,7 @@ static int test_charge_state(void)
static int test_low_battery(void)
{
ccprintf("[CHARGING TEST] Low battery with AC\n");
- mock_ac_present = 1;
+ gpio_set_level(GPIO_AC_PRESENT, 1);
is_hibernated = 0;
sb_write(SB_CURRENT, 1000);
sb_write(SB_RELATIVE_STATE_OF_CHARGE, 2);
@@ -184,7 +176,7 @@ static int test_low_battery(void)
mock_chipset_state = CHIPSET_STATE_ON;
hook_notify(HOOK_CHIPSET_PRE_INIT);
hook_notify(HOOK_CHIPSET_STARTUP);
- mock_ac_present = 0;
+ gpio_set_level(GPIO_AC_PRESENT, 0);
is_hibernated = 0;
sb_write(SB_CURRENT, -1000);
sb_write(SB_RELATIVE_STATE_OF_CHARGE, 2);
@@ -205,10 +197,10 @@ static int test_low_battery(void)
is_shutdown = 0;
mock_chipset_state = CHIPSET_STATE_ON;
sb_write(SB_RELATIVE_STATE_OF_CHARGE, 10);
- mock_ac_present = 1;
+ gpio_set_level(GPIO_AC_PRESENT, 1);
sb_write(SB_CURRENT, 1000);
wait_charging_state();
- mock_ac_present = 0;
+ gpio_set_level(GPIO_AC_PRESENT, 0);
sb_write(SB_CURRENT, -1000);
sb_write(SB_RELATIVE_STATE_OF_CHARGE, 2);
wait_charging_state();
@@ -225,7 +217,7 @@ static int test_batt_fake(void)
mock_chipset_state = CHIPSET_STATE_ON;
hook_notify(HOOK_CHIPSET_PRE_INIT);
hook_notify(HOOK_CHIPSET_STARTUP);
- mock_ac_present = 0;
+ gpio_set_level(GPIO_AC_PRESENT, 0);
is_hibernated = 0;
sb_write(SB_CURRENT, -1000);
sb_write(SB_RELATIVE_STATE_OF_CHARGE, 30);