diff options
Diffstat (limited to 'zephyr/test/drivers/src/isl923x.c')
-rw-r--r-- | zephyr/test/drivers/src/isl923x.c | 463 |
1 files changed, 446 insertions, 17 deletions
diff --git a/zephyr/test/drivers/src/isl923x.c b/zephyr/test/drivers/src/isl923x.c index e1b1dbc020..27ce29984a 100644 --- a/zephyr/test/drivers/src/isl923x.c +++ b/zephyr/test/drivers/src/isl923x.c @@ -5,6 +5,7 @@ #include <ztest.h> #include <drivers/emul.h> +#include <fff.h> #include "battery.h" #include "battery_smart.h" @@ -14,6 +15,7 @@ #include "emul/emul_common_i2c.h" #include "emul/emul_isl923x.h" #include "system.h" +#include "test_mocks.h" BUILD_ASSERT(CONFIG_CHARGER_SENSE_RESISTOR == 10 || CONFIG_CHARGER_SENSE_RESISTOR == 5); @@ -673,24 +675,451 @@ static void test_init(void) system_jumped_late_mock.ret_val = false; } +static void test_isl923x_is_acok(void) +{ + const struct emul *isl923x_emul = ISL923X_EMUL; + struct i2c_emul *i2c_emul = isl923x_emul_get_i2c_emul(isl923x_emul); + enum ec_error_list rv; + bool acok; + + /* Part 1: invalid charger number */ + rv = raa489000_is_acok(board_get_charger_chip_count() + 1, &acok); + zassert_equal(EC_ERROR_INVAL, rv, + "Invalid charger num, but AC OK check succeeded"); + + /* Part 2: error accessing register */ + i2c_common_emul_set_read_fail_reg(i2c_emul, ISL9238_REG_INFO2); + + rv = raa489000_is_acok(CHARGER_NUM, &acok); + zassert_equal(EC_ERROR_INVAL, rv, + "Register read failure, but AC OK check succeeded"); + + i2c_common_emul_set_read_fail_reg(i2c_emul, + I2C_COMMON_EMUL_NO_FAIL_REG); + + /* Part 3: successful path - ACOK is true */ + raa489000_emul_set_acok_pin(isl923x_emul, 1); + + rv = raa489000_is_acok(CHARGER_NUM, &acok); + zassert_equal(EC_SUCCESS, rv, "AC OK check did not return success"); + zassert_true(acok, "AC OK is false"); + + /* Part 3: successful path - ACOK is false */ + raa489000_emul_set_acok_pin(isl923x_emul, 0); + + rv = raa489000_is_acok(CHARGER_NUM, &acok); + zassert_equal(EC_SUCCESS, rv, "AC OK check did not return success"); + zassert_false(acok, "AC OK is true"); +} + +static void test_isl923x_enable_asgate(void) +{ + const struct emul *isl923x_emul = ISL923X_EMUL; + struct i2c_emul *i2c_emul = isl923x_emul_get_i2c_emul(isl923x_emul); + int rv; + + /* Part 1: Try enabling the ASGATE */ + rv = raa489000_enable_asgate(CHARGER_NUM, true); + + zassert_equal(EC_SUCCESS, rv, "Expected return code of %d but got %d", + EC_SUCCESS, rv); + zassert_true( + isl923x_emul_peek_reg(i2c_emul, RAA489000_REG_CONTROL8) & + RAA489000_C8_ASGATE_ON_READY, + "RAA489000_C8_ASGATE_ON_READY bit not set in Control Reg 8"); + + /* Part 2: Turn it back off */ + rv = raa489000_enable_asgate(CHARGER_NUM, false); + + zassert_equal(EC_SUCCESS, rv, "Expected return code of %d but got %d", + EC_SUCCESS, rv); + zassert_false(isl923x_emul_peek_reg(i2c_emul, RAA489000_REG_CONTROL8) & + RAA489000_C8_ASGATE_ON_READY, + "RAA489000_C8_ASGATE_ON_READY bit set in Control Reg 8"); +} + +/* Mock read and write functions to use in the hibernation test */ +FAKE_VALUE_FUNC(int, hibernate_mock_read_fn, struct i2c_emul *, int, uint8_t *, + int, void *); +FAKE_VALUE_FUNC(int, hibernate_mock_write_fn, struct i2c_emul *, int, uint8_t, + int, void *); + +/** + * @brief Setup function for the hibernate tests. + */ +static void hibernate_test_setup(void) +{ + const struct emul *isl923x_emul = ISL923X_EMUL; + struct i2c_emul *i2c_emul = isl923x_emul_get_i2c_emul(isl923x_emul); + + /* Reset mocks and make the read/write mocks pass all data through */ + RESET_FAKE(hibernate_mock_read_fn); + RESET_FAKE(hibernate_mock_write_fn); + hibernate_mock_read_fn_fake.return_val = 1; + hibernate_mock_write_fn_fake.return_val = 1; + + i2c_common_emul_set_read_func(i2c_emul, hibernate_mock_read_fn, NULL); + i2c_common_emul_set_write_func(i2c_emul, hibernate_mock_write_fn, NULL); + + /* Don't fail on any register access */ + i2c_common_emul_set_read_fail_reg(i2c_emul, + I2C_COMMON_EMUL_NO_FAIL_REG); + i2c_common_emul_set_write_fail_reg(i2c_emul, + I2C_COMMON_EMUL_NO_FAIL_REG); +} + +/** + * @brief Teardown function for the hibernate tests. + */ +static void hibernate_test_teardown(void) +{ + const struct emul *isl923x_emul = ISL923X_EMUL; + struct i2c_emul *i2c_emul = isl923x_emul_get_i2c_emul(isl923x_emul); + + /* Clear the mock read/write functions */ + i2c_common_emul_set_read_func(i2c_emul, NULL, NULL); + i2c_common_emul_set_write_func(i2c_emul, NULL, NULL); + + /* Don't fail on any register access */ + i2c_common_emul_set_read_fail_reg(i2c_emul, + I2C_COMMON_EMUL_NO_FAIL_REG); + i2c_common_emul_set_write_fail_reg(i2c_emul, + I2C_COMMON_EMUL_NO_FAIL_REG); +} + +static void test_isl923x_hibernate__happy_path(void) +{ + const struct emul *isl923x_emul = ISL923X_EMUL; + struct i2c_emul *i2c_emul = isl923x_emul_get_i2c_emul(isl923x_emul); + uint16_t actual; + + raa489000_hibernate(CHARGER_NUM, false); + + /* Check ISL923X_REG_CONTROL0 */ + actual = isl923x_emul_peek_reg(i2c_emul, ISL923X_REG_CONTROL0); + + zassert_false(actual & RAA489000_C0_EN_CHG_PUMPS_TO_100PCT, + "RAA489000_C0_EN_CHG_PUMPS_TO_100PCT should not be set"); + zassert_false(actual & RAA489000_C0_BGATE_FORCE_ON, + "RAA489000_C0_BGATE_FORCE_ON should not be set"); + + /* Check ISL923X_REG_CONTROL1 */ + actual = isl923x_emul_peek_reg(i2c_emul, ISL923X_REG_CONTROL1); + + zassert_false(actual & RAA489000_C1_ENABLE_SUPP_SUPPORT_MODE, + "RAA489000_C1_ENABLE_SUPP_SUPPORT_MODE should not be set"); + zassert_false(actual & ISL923X_C1_ENABLE_PSYS, + "ISL923X_C1_ENABLE_PSYS should not be set"); + zassert_true(actual & RAA489000_C1_BGATE_FORCE_OFF, + "RAA489000_C1_BGATE_FORCE_OFF should be set"); + zassert_true(actual & ISL923X_C1_DISABLE_MON, + "ISL923X_C1_DISABLE_MON should be set"); + + /* Check ISL9238_REG_CONTROL3 (disable_adc = false) */ + actual = isl923x_emul_peek_reg(i2c_emul, ISL9238_REG_CONTROL3); + + zassert_true(actual & RAA489000_ENABLE_ADC, + "RAA489000_ENABLE_ADC should be set"); + + /* Check ISL9238_REG_CONTROL4 */ + actual = isl923x_emul_peek_reg(i2c_emul, ISL9238_REG_CONTROL4); + + zassert_true(actual & RAA489000_C4_DISABLE_GP_CMP, + "RAA489000_C4_DISABLE_GP_CMP should be set"); + + /* Ensure all expected register reads and writes happened */ + int registers[] = { ISL923X_REG_CONTROL0, ISL923X_REG_CONTROL1, + ISL9238_REG_CONTROL3, ISL9238_REG_CONTROL4 }; + + for (int i = 0; i < ARRAY_SIZE(registers); i++) { + /* Each reg has 2 reads and 2 writes because they are 16-bit */ + MOCK_ASSERT_I2C_READ(hibernate_mock_read_fn, i * 2, + registers[i]); + MOCK_ASSERT_I2C_READ(hibernate_mock_read_fn, (i * 2) + 1, + registers[i]); + MOCK_ASSERT_I2C_WRITE(hibernate_mock_write_fn, i * 2, + registers[i], MOCK_IGNORE_VALUE); + MOCK_ASSERT_I2C_WRITE(hibernate_mock_write_fn, (i * 2) + 1, + registers[i], MOCK_IGNORE_VALUE); + } +} + +static void test_isl923x_hibernate__invalid_charger_number(void) +{ + /* Mocks should just be pass-through */ + RESET_FAKE(hibernate_mock_read_fn); + RESET_FAKE(hibernate_mock_write_fn); + hibernate_mock_read_fn_fake.return_val = 1; + hibernate_mock_write_fn_fake.return_val = 1; + + raa489000_hibernate(board_get_charger_chip_count() + 1, false); + + /* Make sure no I2C activity happened */ + zassert_equal(hibernate_mock_read_fn_fake.call_count, 0, + "No I2C reads should have happened"); + zassert_equal(hibernate_mock_write_fn_fake.call_count, 0, + "No I2C writes should have happened"); +} + +static void test_isl923x_hibernate__fail_at_ISL923X_REG_CONTROL0(void) +{ + const struct emul *isl923x_emul = ISL923X_EMUL; + struct i2c_emul *i2c_emul = isl923x_emul_get_i2c_emul(isl923x_emul); + + i2c_common_emul_set_read_fail_reg(i2c_emul, ISL923X_REG_CONTROL0); + + raa489000_hibernate(CHARGER_NUM, false); + + /* + * We have no return codes to check, so instead verify that the first + * successful I2C write is to CONTROL1 and not CONTROL0. + */ + + MOCK_ASSERT_I2C_WRITE(hibernate_mock_write_fn, 0, ISL923X_REG_CONTROL1, + MOCK_IGNORE_VALUE); +} + +static void test_isl923x_hibernate__fail_at_ISL923X_REG_CONTROL1(void) +{ + const struct emul *isl923x_emul = ISL923X_EMUL; + struct i2c_emul *i2c_emul = isl923x_emul_get_i2c_emul(isl923x_emul); + + i2c_common_emul_set_read_fail_reg(i2c_emul, ISL923X_REG_CONTROL1); + + raa489000_hibernate(CHARGER_NUM, false); + + /* + * Ensure we skipped CONTROL1. (NB: due to 16-bit regs, each write takes + * two calls to the mock_write_fn) + */ + + MOCK_ASSERT_I2C_WRITE(hibernate_mock_write_fn, 0, ISL923X_REG_CONTROL0, + MOCK_IGNORE_VALUE); + MOCK_ASSERT_I2C_WRITE(hibernate_mock_write_fn, 1, ISL923X_REG_CONTROL0, + MOCK_IGNORE_VALUE); + MOCK_ASSERT_I2C_WRITE(hibernate_mock_write_fn, 2, ISL9238_REG_CONTROL3, + MOCK_IGNORE_VALUE); + MOCK_ASSERT_I2C_WRITE(hibernate_mock_write_fn, 3, ISL9238_REG_CONTROL3, + MOCK_IGNORE_VALUE); +} + +static void test_isl923x_hibernate__fail_at_ISL9238_REG_CONTROL3(void) +{ + const struct emul *isl923x_emul = ISL923X_EMUL; + struct i2c_emul *i2c_emul = isl923x_emul_get_i2c_emul(isl923x_emul); + + i2c_common_emul_set_read_fail_reg(i2c_emul, ISL9238_REG_CONTROL3); + + raa489000_hibernate(CHARGER_NUM, false); + + /* + * Ensure we skipped CONTROL3. (NB: due to 16-bit regs, each write takes + * two calls to the mock_write_fn) + */ + + MOCK_ASSERT_I2C_WRITE(hibernate_mock_write_fn, 2, ISL923X_REG_CONTROL1, + MOCK_IGNORE_VALUE); + MOCK_ASSERT_I2C_WRITE(hibernate_mock_write_fn, 3, ISL923X_REG_CONTROL1, + MOCK_IGNORE_VALUE); + MOCK_ASSERT_I2C_WRITE(hibernate_mock_write_fn, 4, ISL9238_REG_CONTROL4, + MOCK_IGNORE_VALUE); + MOCK_ASSERT_I2C_WRITE(hibernate_mock_write_fn, 5, ISL9238_REG_CONTROL4, + MOCK_IGNORE_VALUE); +} + +static void test_isl923x_hibernate__fail_at_ISL9238_REG_CONTROL4(void) +{ + const struct emul *isl923x_emul = ISL923X_EMUL; + struct i2c_emul *i2c_emul = isl923x_emul_get_i2c_emul(isl923x_emul); + + i2c_common_emul_set_read_fail_reg(i2c_emul, ISL9238_REG_CONTROL4); + + raa489000_hibernate(CHARGER_NUM, false); + + /* + * Ensure we skipped CONTROL4. (i.e. the last calls should be to write + * to CONTROL3) + */ + MOCK_ASSERT_I2C_WRITE(hibernate_mock_write_fn, + hibernate_mock_write_fn_fake.call_count - 2, + ISL9238_REG_CONTROL3, MOCK_IGNORE_VALUE); + MOCK_ASSERT_I2C_WRITE(hibernate_mock_write_fn, + hibernate_mock_write_fn_fake.call_count - 1, + ISL9238_REG_CONTROL3, MOCK_IGNORE_VALUE); +} + +static void test_isl923x_hibernate__adc_disable(void) +{ + const struct emul *isl923x_emul = ISL923X_EMUL; + struct i2c_emul *i2c_emul = isl923x_emul_get_i2c_emul(isl923x_emul); + uint16_t expected; + + raa489000_hibernate(CHARGER_NUM, true); + + /* Check ISL9238_REG_CONTROL3 (disable_adc = true) */ + expected = isl923x_emul_peek_reg(i2c_emul, ISL9238_REG_CONTROL3); + expected &= ~RAA489000_ENABLE_ADC; + + MOCK_ASSERT_I2C_READ(hibernate_mock_read_fn, 4, ISL9238_REG_CONTROL3); + MOCK_ASSERT_I2C_READ(hibernate_mock_read_fn, 5, ISL9238_REG_CONTROL3); + MOCK_ASSERT_I2C_WRITE(hibernate_mock_write_fn, 4, ISL9238_REG_CONTROL3, + expected & 0xff); + MOCK_ASSERT_I2C_WRITE(hibernate_mock_write_fn, 5, ISL9238_REG_CONTROL3, + expected >> 8); +} + +static void test_isl9238c_hibernate(void) +{ + const struct emul *isl923x_emul = ISL923X_EMUL; + struct i2c_emul *i2c_emul = isl923x_emul_get_i2c_emul(isl923x_emul); + uint16_t control1_expected, control2_expected, control3_expected; + int rv; + + /* Part 1: Happy path */ + control1_expected = + (isl923x_emul_peek_reg(i2c_emul, ISL923X_REG_CONTROL1) & + ~ISL923X_C1_ENABLE_PSYS) | + ISL923X_C1_DISABLE_MON; + control2_expected = + isl923x_emul_peek_reg(i2c_emul, ISL923X_REG_CONTROL2) | + ISL923X_C2_COMPARATOR; + control3_expected = + isl923x_emul_peek_reg(i2c_emul, ISL9238_REG_CONTROL3) | + ISL9238_C3_BGATE_OFF; + + rv = isl9238c_hibernate(CHARGER_NUM); + + zassert_equal(EC_SUCCESS, rv, "Expected return code %d but got %d", + EC_SUCCESS, rv); + zassert_equal(isl923x_emul_peek_reg(i2c_emul, ISL923X_REG_CONTROL1), + control1_expected, + "Unexpected register value 0x%02x. Should be 0x%02x", + isl923x_emul_peek_reg(i2c_emul, ISL923X_REG_CONTROL1), + control1_expected); + zassert_equal(isl923x_emul_peek_reg(i2c_emul, ISL923X_REG_CONTROL2), + control2_expected, + "Unexpected register value 0x%02x. Should be 0x%02x", + isl923x_emul_peek_reg(i2c_emul, ISL923X_REG_CONTROL2), + control2_expected); + zassert_equal(isl923x_emul_peek_reg(i2c_emul, ISL9238_REG_CONTROL3), + control3_expected, + "Unexpected register value 0x%02x. Should be 0x%02x", + isl923x_emul_peek_reg(i2c_emul, ISL9238_REG_CONTROL3), + control3_expected); + + /* Part 2: Fail reading each register and check for error code */ + int registers[] = { ISL923X_REG_CONTROL1, ISL923X_REG_CONTROL2, + ISL9238_REG_CONTROL3 }; + + for (int i = 0; i < ARRAY_SIZE(registers); i++) { + i2c_common_emul_set_read_fail_reg(i2c_emul, registers[i]); + + rv = isl9238c_hibernate(CHARGER_NUM); + + zassert_equal(EC_ERROR_INVAL, rv, + "Wrong return code. Expected %d but got %d", + EC_ERROR_INVAL, rv); + } +} + +static void test_isl9238c_resume(void) +{ + const struct emul *isl923x_emul = ISL923X_EMUL; + struct i2c_emul *i2c_emul = isl923x_emul_get_i2c_emul(isl923x_emul); + uint16_t control1_expected, control2_expected, control3_expected; + int rv; + + /* Part 1: Happy path */ + control1_expected = + (isl923x_emul_peek_reg(i2c_emul, ISL923X_REG_CONTROL1) & + ~ISL923X_C1_DISABLE_MON) | ISL923X_C1_ENABLE_PSYS + ; + control2_expected = + isl923x_emul_peek_reg(i2c_emul, ISL923X_REG_CONTROL2) & + ~ISL923X_C2_COMPARATOR; + control3_expected = + isl923x_emul_peek_reg(i2c_emul, ISL9238_REG_CONTROL3) & + ~ISL9238_C3_BGATE_OFF; + + rv = isl9238c_resume(CHARGER_NUM); + + zassert_equal(EC_SUCCESS, rv, "Expected return code %d but got %d", + EC_SUCCESS, rv); + zassert_equal(isl923x_emul_peek_reg(i2c_emul, ISL923X_REG_CONTROL1), + control1_expected, + "Unexpected register value 0x%02x. Should be 0x%02x", + isl923x_emul_peek_reg(i2c_emul, ISL923X_REG_CONTROL1), + control1_expected); + zassert_equal(isl923x_emul_peek_reg(i2c_emul, ISL923X_REG_CONTROL2), + control2_expected, + "Unexpected register value 0x%02x. Should be 0x%02x", + isl923x_emul_peek_reg(i2c_emul, ISL923X_REG_CONTROL2), + control2_expected); + zassert_equal(isl923x_emul_peek_reg(i2c_emul, ISL9238_REG_CONTROL3), + control3_expected, + "Unexpected register value 0x%02x. Should be 0x%02x", + isl923x_emul_peek_reg(i2c_emul, ISL9238_REG_CONTROL3), + control3_expected); + + /* Part 2: Fail reading each register and check for error code */ + int registers[] = { ISL923X_REG_CONTROL1, ISL923X_REG_CONTROL2, + ISL9238_REG_CONTROL3 }; + + for (int i = 0; i < ARRAY_SIZE(registers); i++) { + i2c_common_emul_set_read_fail_reg(i2c_emul, registers[i]); + + rv = isl9238c_resume(CHARGER_NUM); + + zassert_equal(EC_ERROR_INVAL, rv, + "Wrong return code. Expected %d but got %d", + EC_ERROR_INVAL, rv); + } +} + void test_suite_isl923x(void) { - ztest_test_suite(isl923x, - ztest_unit_test(test_isl923x_set_current), - ztest_unit_test(test_isl923x_set_voltage), - ztest_unit_test(test_isl923x_set_input_current_limit), - ztest_unit_test(test_manufacturer_id), - ztest_unit_test(test_device_id), - ztest_unit_test(test_options), - ztest_unit_test(test_get_info), - ztest_unit_test(test_status), - ztest_unit_test(test_set_mode), - ztest_unit_test(test_post_init), - ztest_unit_test(test_set_ac_prochot), - ztest_unit_test(test_set_dc_prochot), - ztest_unit_test(test_comparator_inversion), - ztest_unit_test(test_discharge_on_ac), - ztest_unit_test(test_get_vbus_voltage), - ztest_unit_test(test_init)); + ztest_test_suite( + isl923x, ztest_unit_test(test_isl923x_set_current), + ztest_unit_test(test_isl923x_set_voltage), + ztest_unit_test(test_isl923x_set_input_current_limit), + ztest_unit_test(test_manufacturer_id), + ztest_unit_test(test_device_id), ztest_unit_test(test_options), + ztest_unit_test(test_get_info), ztest_unit_test(test_status), + ztest_unit_test(test_set_mode), ztest_unit_test(test_post_init), + ztest_unit_test(test_set_ac_prochot), + ztest_unit_test(test_set_dc_prochot), + ztest_unit_test(test_comparator_inversion), + ztest_unit_test(test_discharge_on_ac), + ztest_unit_test(test_get_vbus_voltage), + ztest_unit_test(test_init), + ztest_unit_test(test_isl923x_is_acok), + ztest_unit_test(test_isl923x_enable_asgate), + ztest_unit_test_setup_teardown( + test_isl923x_hibernate__happy_path, + hibernate_test_setup, hibernate_test_teardown), + ztest_unit_test_setup_teardown( + test_isl923x_hibernate__invalid_charger_number, + hibernate_test_setup, hibernate_test_teardown), + ztest_unit_test_setup_teardown( + test_isl923x_hibernate__fail_at_ISL923X_REG_CONTROL0, + hibernate_test_setup, hibernate_test_teardown), + ztest_unit_test_setup_teardown( + test_isl923x_hibernate__fail_at_ISL923X_REG_CONTROL1, + hibernate_test_setup, hibernate_test_teardown), + ztest_unit_test_setup_teardown( + test_isl923x_hibernate__fail_at_ISL9238_REG_CONTROL3, + hibernate_test_setup, hibernate_test_teardown), + ztest_unit_test_setup_teardown( + test_isl923x_hibernate__fail_at_ISL9238_REG_CONTROL4, + hibernate_test_setup, hibernate_test_teardown), + ztest_unit_test_setup_teardown( + test_isl923x_hibernate__adc_disable, + hibernate_test_setup, hibernate_test_teardown), + ztest_unit_test_setup_teardown(test_isl9238c_hibernate, + hibernate_test_teardown, + hibernate_test_teardown), + ztest_unit_test_setup_teardown(test_isl9238c_resume, + hibernate_test_teardown, + hibernate_test_teardown)); ztest_run_test_suite(isl923x); } |