summaryrefslogtreecommitdiff
path: root/test/led_spring.c
diff options
context:
space:
mode:
Diffstat (limited to 'test/led_spring.c')
-rw-r--r--test/led_spring.c270
1 files changed, 270 insertions, 0 deletions
diff --git a/test/led_spring.c b/test/led_spring.c
new file mode 100644
index 0000000000..79f01b297f
--- /dev/null
+++ b/test/led_spring.c
@@ -0,0 +1,270 @@
+/* Copyright (c) 2013 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.
+ *
+ * Test lid switch.
+ */
+
+#include "common.h"
+#include "console.h"
+#include "host_command.h"
+#include "lp5562.h"
+#include "pmu_tpschrome.h"
+#include "smart_battery.h"
+#include "test_util.h"
+#include "timer.h"
+#include "util.h"
+
+#define LP5562_I2C_ADDR (0x30 << 1)
+#define LP5562_NUM_WATCH_REG 0x71
+static uint8_t lp5562_reg[LP5562_NUM_WATCH_REG];
+
+#define LED_COLOR_NONE LP5562_COLOR_NONE
+#define LED_COLOR_GREEN LP5562_COLOR_GREEN(0x10)
+#define LED_COLOR_YELLOW LP5562_COLOR_BLUE(0x40)
+#define LED_COLOR_RED LP5562_COLOR_RED(0x80)
+
+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;
+
+/*****************************************************************************/
+/* Mock functions */
+
+static void set_ac(int ac)
+{
+ gpio_set_level(GPIO_AC_PRESENT, ac);
+ ccprintf("[%T TEST AC = %d]\n", ac);
+}
+
+enum charging_state charge_get_state(void)
+{
+ return mock_charge_state;
+}
+
+static void set_charge_state(enum charging_state s)
+{
+ mock_charge_state = s;
+ ccprintf("[%T TEST Charge state = %s]\n", state_names[s]);
+}
+
+static void set_battery_soc(int soc)
+{
+ sb_write(SB_RELATIVE_STATE_OF_CHARGE, soc);
+ sb_write(SB_ABSOLUTE_STATE_OF_CHARGE, soc);
+}
+
+/*****************************************************************************/
+/* Test utilities */
+
+static int lp5562_i2c_write8(int port, int slave_addr, int offset, int data)
+{
+ if (port != I2C_PORT_HOST || slave_addr != LP5562_I2C_ADDR)
+ return EC_ERROR_INVAL;
+ if (offset == lp5562_failed_i2c_reg)
+ return EC_ERROR_UNKNOWN;
+ if (offset < LP5562_NUM_WATCH_REG)
+ lp5562_reg[offset] = data;
+ return EC_SUCCESS;
+}
+DECLARE_TEST_I2C_WRITE8(lp5562_i2c_write8);
+
+static int lp5562_get_color(void)
+{
+ return lp5562_reg[LP5562_REG_B_PWM] |
+ (lp5562_reg[LP5562_REG_G_PWM] << 8) |
+ (lp5562_reg[LP5562_REG_R_PWM] << 16);
+}
+
+static int lp5562_powered(void)
+{
+ return lp5562_reg[LP5562_REG_ENABLE] & 0x40;
+}
+
+static int lp5562_in_pwm_mode(void)
+{
+ return lp5562_reg[LP5562_REG_LED_MAP] == 0;
+}
+
+static int verify_color(int expected_color)
+{
+ int actual = lp5562_get_color();
+
+ if (expected_color == LED_COLOR_NONE)
+ return !lp5562_powered();
+ if (!lp5562_powered())
+ return 0;
+ if (!lp5562_in_pwm_mode())
+ return 0;
+
+ ccprintf("[%T LED color = 0x%06x]\n", actual);
+
+ return actual == expected_color;
+}
+
+/*****************************************************************************/
+/* Tests */
+
+static int test_led_power(void)
+{
+ /* Check LED is off */
+ TEST_ASSERT(!lp5562_powered());
+
+ /* Plug in AC, and LED should turn on within a second */
+ set_ac(1);
+ msleep(1500);
+ TEST_ASSERT(lp5562_powered());
+
+ /* Change state while AC is on. LED should keep on */
+ set_charge_state(ST_CHARGING_ERROR);
+ msleep(1500);
+ TEST_ASSERT(lp5562_powered());
+
+ /* Unplug AC. LED should turn off */
+ set_ac(0);
+ msleep(1500);
+ TEST_ASSERT(!lp5562_powered());
+
+ /* Plug AC again. LED should turn on */
+ set_ac(1);
+ msleep(1500);
+ TEST_ASSERT(lp5562_powered());
+
+ return EC_SUCCESS;
+}
+
+static int test_led_color(void)
+{
+ /* IDLE0 */
+ set_ac(1);
+ set_charge_state(ST_IDLE0);
+ msleep(30000);
+ TEST_ASSERT(verify_color(LED_COLOR_YELLOW));
+
+ /* BAD_COND*/
+ set_charge_state(ST_BAD_COND);
+ msleep(30000);
+ TEST_ASSERT(verify_color(LED_COLOR_YELLOW));
+
+ /* PRE_CHARGING */
+ set_charge_state(ST_PRE_CHARGING);
+ msleep(30000);
+ TEST_ASSERT(verify_color(LED_COLOR_YELLOW));
+
+ /* IDLE */
+ set_charge_state(ST_IDLE);
+ set_battery_soc(50);
+ msleep(30000);
+ TEST_ASSERT(verify_color(LED_COLOR_YELLOW));
+ set_battery_soc(99);
+ msleep(30000);
+ TEST_ASSERT(verify_color(LED_COLOR_GREEN));
+
+ /* DISCHARGING */
+ set_charge_state(ST_DISCHARGING);
+ set_battery_soc(50);
+ msleep(30000);
+ TEST_ASSERT(verify_color(LED_COLOR_YELLOW));
+ set_battery_soc(99);
+ msleep(30000);
+ TEST_ASSERT(verify_color(LED_COLOR_GREEN));
+
+ /* CHARGING */
+ set_charge_state(ST_CHARGING);
+ set_battery_soc(50);
+ msleep(30000);
+ TEST_ASSERT(verify_color(LED_COLOR_YELLOW));
+ set_battery_soc(99);
+ msleep(30000);
+ TEST_ASSERT(verify_color(LED_COLOR_GREEN));
+
+ /* CHARGING_ERROR */
+ set_charge_state(ST_CHARGING_ERROR);
+ msleep(1500);
+ TEST_ASSERT(verify_color(LED_COLOR_RED));
+
+ return EC_SUCCESS;
+}
+
+static int test_green_yellow(void)
+{
+ /* Make LED green */
+ set_ac(1);
+ set_charge_state(ST_CHARGING);
+ set_battery_soc(95);
+ msleep(30000);
+ TEST_ASSERT(verify_color(LED_COLOR_GREEN));
+
+ /* Make it yellow now */
+ set_battery_soc(90);
+ msleep(1500);
+ TEST_ASSERT(verify_color(LED_COLOR_YELLOW));
+
+ /* Shouldn't change from yellow to green in 15 seconds */
+ set_battery_soc(95);
+ msleep(13000);
+ TEST_ASSERT(verify_color(LED_COLOR_YELLOW));
+
+ /* After 15 seconds, it should turn green */
+ msleep(3000);
+ TEST_ASSERT(verify_color(LED_COLOR_GREEN));
+
+ /* Shouldn't change from green to yellow in 15 seconds */
+ set_charge_state(ST_BAD_COND);
+ msleep(12000);
+ TEST_ASSERT(verify_color(LED_COLOR_GREEN));
+
+ /* After 15 seconds, it should turn yellow */
+ msleep(4000);
+ TEST_ASSERT(verify_color(LED_COLOR_YELLOW));
+
+ return EC_SUCCESS;
+}
+
+static int test_bad_i2c(void)
+{
+ /* Make LED green */
+ set_ac(1);
+ set_charge_state(ST_DISCHARGING);
+ set_battery_soc(95);
+ msleep(30000);
+ TEST_ASSERT(verify_color(LED_COLOR_GREEN));
+
+ /* Make it red, but fail the I2C write to green PWM register */
+ lp5562_failed_i2c_reg = LP5562_REG_G_PWM;
+ set_charge_state(ST_CHARGING_ERROR);
+ msleep(3000);
+ TEST_ASSERT(!verify_color(LED_COLOR_RED));
+
+ /* I2C works again. LED should turn red */
+ lp5562_failed_i2c_reg = -1;
+ msleep(1500);
+ TEST_ASSERT(verify_color(LED_COLOR_RED));
+
+ /* Make it green, but I2C fails again */
+ lp5562_failed_i2c_reg = LP5562_REG_R_PWM;
+ set_charge_state(ST_DISCHARGING);
+ msleep(1500);
+ TEST_ASSERT(!verify_color(LED_COLOR_GREEN));
+ TEST_ASSERT(!verify_color(LED_COLOR_RED));
+
+ /* I2C works now, but LED turns red at the same time */
+ lp5562_failed_i2c_reg = -1;
+ set_charge_state(ST_CHARGING_ERROR);
+ msleep(1500);
+ TEST_ASSERT(verify_color(LED_COLOR_RED));
+
+ return EC_SUCCESS;
+}
+
+void run_test(void)
+{
+ test_reset();
+
+ RUN_TEST(test_led_power);
+ RUN_TEST(test_led_color);
+ RUN_TEST(test_green_yellow);
+ RUN_TEST(test_bad_i2c);
+
+ test_print_result();
+}