diff options
-rw-r--r-- | driver/charger/sm5803.c | 12 | ||||
-rw-r--r-- | zephyr/dts/bindings/emul/cros,sm5803-emul.yaml | 34 | ||||
-rw-r--r-- | zephyr/emul/CMakeLists.txt | 1 | ||||
-rw-r--r-- | zephyr/emul/Kconfig | 1 | ||||
-rw-r--r-- | zephyr/emul/Kconfig.sm5803 | 18 | ||||
-rw-r--r-- | zephyr/emul/emul_sm5803.c | 722 | ||||
-rw-r--r-- | zephyr/include/emul/emul_sm5803.h | 77 | ||||
-rw-r--r-- | zephyr/test/drivers/CMakeLists.txt | 1 | ||||
-rw-r--r-- | zephyr/test/drivers/Kconfig | 3 | ||||
-rw-r--r-- | zephyr/test/drivers/sm5803/CMakeLists.txt | 5 | ||||
-rw-r--r-- | zephyr/test/drivers/sm5803/prj.conf | 6 | ||||
-rw-r--r-- | zephyr/test/drivers/sm5803/sm5803.dts | 32 | ||||
-rw-r--r-- | zephyr/test/drivers/sm5803/src/sm5803.c | 709 | ||||
-rw-r--r-- | zephyr/test/drivers/sm5803/src/usbc.c | 42 | ||||
-rw-r--r-- | zephyr/test/drivers/testcase.yaml | 9 |
15 files changed, 7 insertions, 1665 deletions
diff --git a/driver/charger/sm5803.c b/driver/charger/sm5803.c index ec7132fb35..57b1a0330f 100644 --- a/driver/charger/sm5803.c +++ b/driver/charger/sm5803.c @@ -44,7 +44,7 @@ #define CPRINTS(format, args...) cprints(CC_CHARGER, format, ##args) #define UNKNOWN_DEV_ID -1 -test_export_static int dev_id = UNKNOWN_DEV_ID; +static int dev_id = UNKNOWN_DEV_ID; static const struct charger_info sm5803_charger_info = { .name = CHARGER_NAME, @@ -435,7 +435,7 @@ enum ec_error_list sm5803_vbus_sink_enable(int chgnum, int enable) * Track and store whether we've initialized the charger chips already on this * boot. This should prevent us from re-running inits after sysjumps. */ -test_export_static bool chip_inited[CHARGER_NUM]; +static bool chip_inited[CHARGER_NUM]; #define SM5803_SYSJUMP_TAG 0x534D /* SM */ #define SM5803_HOOK_VERSION 1 @@ -734,13 +734,15 @@ static void sm5803_init(int chgnum) SM5803_TINT_MIN_LEVEL); /* - * Configure VBAT_SNSP high and TINT interrupts to fire after - * thresholds are set. + * Configure VBAT_SNSP high interrupt to fire after thresholds are set. */ rv |= main_read8(chgnum, SM5803_REG_INT2_EN, ®); - reg |= SM5803_INT2_VBATSNSP | SM5803_INT2_TINT; + reg |= SM5803_INT2_VBATSNSP; rv |= main_write8(chgnum, SM5803_REG_INT2_EN, reg); + /* Configure TINT interrupts to fire after thresholds are set */ + rv |= main_write8(chgnum, SM5803_REG_INT2_EN, SM5803_INT2_TINT); + /* * Configure CHG_ENABLE to only be set through I2C by setting * HOST_MODE_EN bit (all other register bits are 0 by default) diff --git a/zephyr/dts/bindings/emul/cros,sm5803-emul.yaml b/zephyr/dts/bindings/emul/cros,sm5803-emul.yaml deleted file mode 100644 index a3e42682e6..0000000000 --- a/zephyr/dts/bindings/emul/cros,sm5803-emul.yaml +++ /dev/null @@ -1,34 +0,0 @@ -# Copyright 2023 The ChromiumOS Authors -# Use of this source code is governed by a BSD-style license that can be -# found in the LICENSE file. - -description: SM5803 charger emulator - -compatible: "cros,sm5803-emul" - -include: base.yaml - -properties: - main-addr: - type: int - default: 0x30 - description: | - I2C address of the charger base registers. This is always 0x30 on - hardware. - meas-addr: - type: int - default: 0x31 - description: | - I2C address of the charger measurement registers. This is always 0x31 on - hardware. - test-addr: - type: int - default: 0x37 - description: | - I2C address of the charger test registers. This is always 0x37 on - hardware. - interrupt-gpios: - type: phandle-array - description: | - Emulated GPIO pin acting as the active-low interrupt input from the - charger. diff --git a/zephyr/emul/CMakeLists.txt b/zephyr/emul/CMakeLists.txt index 65daeafbde..58eef44627 100644 --- a/zephyr/emul/CMakeLists.txt +++ b/zephyr/emul/CMakeLists.txt @@ -30,7 +30,6 @@ zephyr_library_sources_ifdef(CONFIG_EMUL_PS8743 emul_ps8743.c) zephyr_library_sources_ifdef(CONFIG_EMUL_RT9490 emul_rt9490.c) zephyr_library_sources_ifdef(CONFIG_EMUL_RTC emul_rtc.c) zephyr_library_sources_ifdef(CONFIG_EMUL_SMART_BATTERY emul_smart_battery.c) -zephyr_library_sources_ifdef(CONFIG_EMUL_SM5803 emul_sm5803.c) zephyr_library_sources_ifdef(CONFIG_EMUL_SN5S330 emul_sn5s330.c) zephyr_library_sources_ifdef(CONFIG_EMUL_TCS3400 emul_tcs3400.c) zephyr_library_sources_ifdef(CONFIG_EMUL_TUSB1064 emul_tusb1064.c) diff --git a/zephyr/emul/Kconfig b/zephyr/emul/Kconfig index ecd2d25055..ecdbfb426c 100644 --- a/zephyr/emul/Kconfig +++ b/zephyr/emul/Kconfig @@ -215,5 +215,4 @@ rsource "Kconfig.lis2dw12" rsource "Kconfig.i2c_mock" rsource "Kconfig.isl923x" rsource "Kconfig.clock_control" -rsource "Kconfig.sm5803" rsource "Kconfig.sn5s330" diff --git a/zephyr/emul/Kconfig.sm5803 b/zephyr/emul/Kconfig.sm5803 deleted file mode 100644 index b1ee48a392..0000000000 --- a/zephyr/emul/Kconfig.sm5803 +++ /dev/null @@ -1,18 +0,0 @@ -# Copyright 2023 The ChromiumOS Authors -# Use of this source code is governed by a BSD-style license that can be -# found in the LICENSE file. - -menuconfig EMUL_SM5803 - bool "SM5803 charger emulator" - default y - depends on DT_HAS_CROS_SM5803_EMUL_ENABLED - depends on I2C_EMUL - help - Enable the SM5803 emulator, used to test the sm5803 driver. - The emulator API is defined in zephyr/include/emul/emul_sm5803.h - -if EMUL_SM5803 -module = SM5803_EMUL -module-str = sm5803_emul -source "subsys/logging/Kconfig.template.log_config" -endif diff --git a/zephyr/emul/emul_sm5803.c b/zephyr/emul/emul_sm5803.c deleted file mode 100644 index 01038765ef..0000000000 --- a/zephyr/emul/emul_sm5803.c +++ /dev/null @@ -1,722 +0,0 @@ -/* Copyright 2023 The ChromiumOS Authors - * Use of this source code is governed by a BSD-style license that can be - * found in the LICENSE file. - */ -#include "driver/charger/sm5803.h" -#include "emul/emul_common_i2c.h" -#include "emul/emul_sm5803.h" -#include "emul/emul_stub_device.h" - -#include <zephyr/drivers/gpio/gpio_emul.h> -#include <zephyr/logging/log.h> -#include <zephyr/ztest.h> - -#define DT_DRV_COMPAT cros_sm5803_emul - -LOG_MODULE_REGISTER(sm5803_emul, CONFIG_SM5803_EMUL_LOG_LEVEL); - -#define VBUS_GPADC_LSB_MV 23.4 -#define ADC_CURRENT_LSB_MA 7.32 -#define ICL_LSB_MA 100 -#define CHG_DET_THRESHOLD_MV 4000 - -struct sm5803_emul_data { - struct i2c_common_emul_data i2c_main; - struct i2c_common_emul_data i2c_chg; - struct i2c_common_emul_data i2c_meas; - struct i2c_common_emul_data i2c_test; - - /** Device ID register value */ - uint8_t device_id; - /** PLATFORM register value */ - uint8_t pmode; - /** Raw value of ISO_CL_REG1 */ - uint8_t input_current_limit; - uint8_t gpadc_conf1, gpadc_conf2; - /** Raw values of INT_EN{1..4} */ - uint8_t int_en[4]; - /** Raw values of INT_REQ_{1..4} */ - uint8_t irq1, irq2, irq3, irq4; - uint16_t vbus; - uint16_t ibus; - uint16_t ibat_avg; - bool clock_slowed; - uint8_t cc_conf1; - /** Raw values of FLOW_REG* */ - uint8_t flow1, flow2, flow3; - /** Raw value of SWITCHER_CONF register */ - uint8_t switcher_conf; - /** Bit 0 (PSYS_DAC_EN) of PSYS_REG1 */ - bool psys_dac_enabled; - /** PHOT_REG1 raw value. */ - uint8_t phot1; - /** Raw values of DISCH_CONF_REG* */ - uint8_t disch_conf5; - /** Raw values of PRE_FAST_CONF_REG{1..6} */ - uint8_t pre_fast_conf[6]; - /** Raw value of GPIO0_CTRL register */ - uint8_t gpio_ctrl; -}; - -struct sm5803_emul_cfg { - const struct i2c_common_emul_cfg i2c_main; - const struct i2c_common_emul_cfg i2c_chg; - const struct i2c_common_emul_cfg i2c_meas; - const struct i2c_common_emul_cfg i2c_test; - struct gpio_dt_spec interrupt_gpio; -}; - -const struct gpio_dt_spec * -sm5803_emul_get_interrupt_gpio(const struct emul *emul) -{ - const struct sm5803_emul_cfg *cfg = emul->cfg; - - return &cfg->interrupt_gpio; -} - -struct i2c_common_emul_data *sm5803_emul_get_i2c_main(const struct emul *emul) -{ - struct sm5803_emul_data *data = emul->data; - - return &data->i2c_main; -} - -struct i2c_common_emul_data *sm5803_emul_get_i2c_chg(const struct emul *emul) -{ - struct sm5803_emul_data *data = emul->data; - - return &data->i2c_chg; -} - -struct i2c_common_emul_data *sm5803_emul_get_i2c_meas(const struct emul *emul) -{ - struct sm5803_emul_data *data = emul->data; - - return &data->i2c_meas; -} - -struct i2c_common_emul_data *sm5803_emul_get_i2c_test(const struct emul *emul) -{ - struct sm5803_emul_data *data = emul->data; - - return &data->i2c_test; -} - -int sm5803_emul_read_chg_reg(const struct emul *emul, uint8_t reg) -{ - struct sm5803_emul_data *data = emul->data; - - switch (reg) { - case SM5803_REG_CHG_ILIM: - return data->input_current_limit; - } - return -ENOTSUP; -} - -int sm5803_emul_get_fast_charge_current_limit(const struct emul *emul) -{ - struct sm5803_emul_data *data = emul->data; - - return data->pre_fast_conf[3] & GENMASK(5, 0); -} - -void sm5803_emul_set_vbus_voltage(const struct emul *emul, uint16_t mv) -{ - struct sm5803_emul_data *data = emul->data; - uint16_t old = (float)data->vbus * VBUS_GPADC_LSB_MV; - - data->vbus = (uint16_t)((float)mv / VBUS_GPADC_LSB_MV); - - if (MIN(mv, old) <= CHG_DET_THRESHOLD_MV && - MAX(mv, old) > CHG_DET_THRESHOLD_MV) { - /* CHG_DET changes state; trigger an interrupt. */ - sm5803_emul_set_irqs(emul, SM5803_INT1_CHG, 0, 0, 0); - } -} - -void sm5803_emul_set_input_current(const struct emul *emul, uint16_t mv) -{ - struct sm5803_emul_data *data = emul->data; - - data->ibus = (uint16_t)((float)mv / ADC_CURRENT_LSB_MA); -} - -void sm5803_emul_set_battery_current(const struct emul *emul, uint16_t ma) -{ - struct sm5803_emul_data *data = emul->data; - - data->ibat_avg = (uint16_t)((float)ma / ADC_CURRENT_LSB_MA); -} - -static void update_interrupt_pin(const struct emul *emul) -{ - struct sm5803_emul_data *data = emul->data; - const struct sm5803_emul_cfg *cfg = emul->cfg; - - bool pending = data->irq1 || data->irq2 || data->irq3 || data->irq4; - - /* Pin goes low if any IRQ is pending. */ - gpio_emul_input_set(cfg->interrupt_gpio.port, cfg->interrupt_gpio.pin, - !pending); -} - -void sm5803_emul_set_irqs(const struct emul *emul, uint8_t irq1, uint8_t irq2, - uint8_t irq3, uint8_t irq4) -{ - struct sm5803_emul_data *data = emul->data; - - data->irq1 |= irq1; - data->irq2 |= irq2; - data->irq3 |= irq3; - data->irq4 |= irq4; - update_interrupt_pin(emul); -} - -static bool is_chg_det(struct sm5803_emul_data *data) -{ - /* Assume charger presence is cut off at 4V VBUS. */ - return data->vbus * VBUS_GPADC_LSB_MV > CHG_DET_THRESHOLD_MV; -} - -void sm5803_emul_set_gpadc_conf(const struct emul *emul, uint8_t conf1, - uint8_t conf2) -{ - struct sm5803_emul_data *data = emul->data; - - data->gpadc_conf1 = conf1; - data->gpadc_conf2 = conf2; -} - -void sm5803_emul_get_gpadc_conf(const struct emul *emul, uint8_t *conf1, - uint8_t *conf2) -{ - struct sm5803_emul_data *data = emul->data; - - *conf1 = data->gpadc_conf1; - *conf2 = data->gpadc_conf2; -} - -bool sm5803_emul_is_clock_slowed(const struct emul *emul) -{ - struct sm5803_emul_data *data = emul->data; - - return data->clock_slowed; -} - -uint8_t sm5803_emul_get_cc_config(const struct emul *emul) -{ - struct sm5803_emul_data *data = emul->data; - - return data->cc_conf1; -} - -void sm5803_emul_get_flow_regs(const struct emul *emul, uint8_t *flow1, - uint8_t *flow2, uint8_t *flow3) -{ - struct sm5803_emul_data *data = emul->data; - - *flow1 = data->flow1; - *flow2 = data->flow2; - *flow3 = data->flow3; -} - -void sm5803_emul_set_pmode(const struct emul *emul, uint8_t pmode) -{ - struct sm5803_emul_data *data = emul->data; - - data->pmode = pmode & GENMASK(4, 0); -} - -void sm5803_emul_set_device_id(const struct emul *emul, uint8_t id) -{ - struct sm5803_emul_data *data = emul->data; - - data->device_id = id; -} - -uint8_t sm5803_emul_get_gpio_ctrl(const struct emul *emul) -{ - struct sm5803_emul_data *data = emul->data; - - return data->gpio_ctrl; -} - -static void sm5803_emul_reset(const struct emul *emul) -{ - struct sm5803_emul_data *data = emul->data; - const struct sm5803_emul_cfg *cfg = emul->cfg; - -#define RESET_I2C(page) \ - do { \ - struct i2c_common_emul_data *common = &data->i2c_##page; \ - \ - i2c_common_emul_set_read_func(common, NULL, NULL); \ - i2c_common_emul_set_write_func(common, NULL, NULL); \ - i2c_common_emul_set_read_fail_reg( \ - common, I2C_COMMON_EMUL_NO_FAIL_REG); \ - i2c_common_emul_set_write_fail_reg( \ - common, I2C_COMMON_EMUL_NO_FAIL_REG); \ - } while (0) - - RESET_I2C(main); - RESET_I2C(chg); - RESET_I2C(meas); - RESET_I2C(test); - - /* Registers set to chip reset values */ - data->device_id = 3; - data->pmode = 0x0b; - data->input_current_limit = 4; - data->gpadc_conf1 = 0xf3; - data->gpadc_conf2 = 0x01; - memset(data->int_en, 0, sizeof(data->int_en)); - data->irq1 = data->irq2 = data->irq3 = data->irq4 = 0; - data->vbus = 0; - data->ibus = 0; - data->ibat_avg = 0; - data->clock_slowed = false; - data->cc_conf1 = 0x09; - data->flow1 = 0x01; - data->flow2 = 0; - data->flow3 = 0; - data->switcher_conf = 1; - data->psys_dac_enabled = true; - data->phot1 = 0x20; - data->disch_conf5 = 0; - memset(data->pre_fast_conf, 0, sizeof(data->pre_fast_conf)); - data->gpio_ctrl = 0x04; - - /* Interrupt pin deasserted */ - gpio_emul_input_set(cfg->interrupt_gpio.port, cfg->interrupt_gpio.pin, - 1); -} - -static int sm5803_main_read_byte(const struct emul *target, int reg, - uint8_t *val, int bytes) -{ - struct sm5803_emul_data *data = target->data; - - switch (reg) { - case SM5803_REG_CHIP_ID: - *val = data->device_id; - return 0; - case SM5803_REG_STATUS1: - *val = is_chg_det(data) ? SM5803_STATUS1_CHG_DET : 0; - return 0; - case SM5803_REG_INT1_REQ: - *val = data->irq1; - /* register clears on read */ - data->irq1 = 0; - update_interrupt_pin(target); - return 0; - case SM5803_REG_INT2_REQ: - *val = data->irq2; - /* register clears on read */ - data->irq2 = 0; - update_interrupt_pin(target); - return 0; - case SM5803_REG_INT3_REQ: - *val = data->irq3; - /* register clears on read */ - data->irq3 = 0; - update_interrupt_pin(target); - return 0; - case SM5803_REG_INT4_REQ: - *val = data->irq4; - /* register clears on read */ - data->irq4 = 0; - update_interrupt_pin(target); - return 0; - case SM5803_REG_INT1_EN: - case SM5803_REG_INT2_EN: - case SM5803_REG_INT3_EN: - case SM5803_REG_INT4_EN: - *val = data->int_en[reg - SM5803_REG_INT1_EN]; - return 0; - case SM5803_REG_PLATFORM: - *val = data->pmode; - return 0; - case SM5803_REG_REFERENCE: - /* Driver never actually uses LDO PGOOD bits. */ - *val = 0; - return 0; - case SM5803_REG_CLOCK_SEL: - *val = data->clock_slowed ? 1 : 0; - return 0; - case SM5803_REG_GPIO0_CTRL: - *val = data->gpio_ctrl; - return 0; - } - LOG_INF("SM5803 main page read of register %#x unhandled", reg); - return -ENOTSUP; -} - -static int sm5803_main_write_byte(const struct emul *target, int reg, - uint8_t val, int bytes) -{ - struct sm5803_emul_data *data = target->data; - - switch (reg) { - case SM5803_REG_CLOCK_SEL: - data->clock_slowed = (val & 1) == 1; - return 0; - case SM5803_REG_GPIO0_CTRL: - data->gpio_ctrl = val & (GENMASK(7, 6) | GENMASK(2, 0)); - return 0; - } - LOG_INF("SM5803 main page write of register %#x unhandled", reg); - return -ENOTSUP; -} - -static int sm5803_chg_read_byte(const struct emul *target, int reg, - uint8_t *val, int bytes) -{ - struct sm5803_emul_data *data = target->data; - - switch (reg) { - case SM5803_REG_CC_CONFIG1: - *val = data->cc_conf1; - return 0; - case SM5803_REG_INT1_EN: - case SM5803_REG_INT2_EN: - case SM5803_REG_INT3_EN: - case SM5803_REG_INT4_EN: - *val = data->int_en[reg - SM5803_REG_INT1_EN]; - return 0; - case SM5803_REG_FLOW1: - *val = data->flow1; - return 0; - case SM5803_REG_FLOW2: - *val = data->flow2; - return 0; - case SM5803_REG_FLOW3: - *val = data->flow3; - return 0; - case SM5803_REG_SWITCHER_CONF: - *val = data->switcher_conf; - return 0; - case SM5803_REG_CHG_ILIM: - *val = data->input_current_limit; - return 0; - case SM5803_REG_DISCH_CONF5: - *val = data->disch_conf5; - return 0; - case SM5803_REG_PRE_FAST_CONF_REG1: - case SM5803_REG_PRE_FAST_CONF_REG1 + 1: - case SM5803_REG_PRE_FAST_CONF_REG1 + 2: - case SM5803_REG_PRE_FAST_CONF_REG1 + 3: - case SM5803_REG_PRE_FAST_CONF_REG1 + 4: - case SM5803_REG_PRE_FAST_CONF_REG1 + 5: - *val = data->pre_fast_conf[reg - SM5803_REG_PRE_FAST_CONF_REG1]; - return 0; - case SM5803_REG_LOG2: - *val = ((data->ibus * ADC_CURRENT_LSB_MA) > - (data->input_current_limit * ICL_LSB_MA)) - << 1; - return 0; - case SM5803_REG_PHOT1: - *val = data->phot1; - return 0; - } - LOG_INF("SM5803 charger page read of register %#x unhandled", reg); - return -ENOTSUP; -} - -static int sm5803_chg_write_byte(const struct emul *target, int reg, - uint8_t val, int bytes) -{ - struct sm5803_emul_data *data = target->data; - - switch (reg) { - case SM5803_REG_CC_CONFIG1: - data->cc_conf1 = val; - return 0; - case SM5803_REG_FLOW1: - data->flow1 = val & 0x8f; - return 0; - case SM5803_REG_FLOW2: - data->flow2 = val; - return 0; - case SM5803_REG_FLOW3: - data->flow3 = val & GENMASK(3, 0); - return 0; - case SM5803_REG_SWITCHER_CONF: - data->switcher_conf = val & 0xc1; - return 0; - case SM5803_REG_CHG_ILIM: - data->input_current_limit = val & GENMASK(4, 0); - return 0; - case SM5803_REG_PRE_FAST_CONF_REG1: - case SM5803_REG_PRE_FAST_CONF_REG1 + 1: - case SM5803_REG_PRE_FAST_CONF_REG1 + 2: - case SM5803_REG_PRE_FAST_CONF_REG1 + 3: - case SM5803_REG_PRE_FAST_CONF_REG1 + 4: - case SM5803_REG_PRE_FAST_CONF_REG1 + 5: - data->pre_fast_conf[reg - SM5803_REG_PRE_FAST_CONF_REG1] = val; - return 0; - case SM5803_REG_PHOT1: - data->phot1 = val; - return 0; - case SM5803_REG_DISCH_CONF5: - data->disch_conf5 = val; - return 0; - } - LOG_INF("SM5803 charger page write of register %#x unhandled", reg); - return -ENOTSUP; -} - -static int sm5803_meas_read_byte(const struct emul *target, int reg, - uint8_t *val, int bytes) -{ - struct sm5803_emul_data *data = target->data; - - switch (reg) { - case SM5803_REG_GPADC_CONFIG1: - *val = data->gpadc_conf1; - return 0; - case SM5803_REG_GPADC_CONFIG2: - *val = data->gpadc_conf2; - return 0; - case SM5803_REG_PSYS1: - *val = 0x04 | data->psys_dac_enabled; - return 0; - case SM5803_REG_IBUS_CHG_MEAS_MSB: - *val = (data->ibus & GENMASK(9, 2)) >> 2; - return 0; - case SM5803_REG_IBUS_CHG_MEAS_LSB: - *val = data->ibus & GENMASK(1, 0); - return 0; - case SM5803_REG_VBUS_MEAS_MSB: - *val = (data->vbus & GENMASK(9, 2)) >> 2; - return 0; - case SM5803_REG_VBUS_MEAS_LSB: - *val = (is_chg_det(data) ? SM5803_VBUS_MEAS_CHG_DET : 0) | - (data->vbus & GENMASK(1, 0)); - return 0; - case SM5803_REG_IBAT_CHG_AVG_MEAS_MSB: - *val = (data->ibat_avg & GENMASK(9, 2)) >> 2; - return 0; - case SM5803_REG_IBAT_CHG_AVG_MEAS_LSB: - *val = data->ibat_avg & GENMASK(1, 0); - return 0; - } - LOG_INF("SM5803 meas page read of register %#x unhandled", reg); - return -ENOTSUP; -} - -static int sm5803_meas_write_byte(const struct emul *target, int reg, - uint8_t val, int bytes) -{ - struct sm5803_emul_data *data = target->data; - - switch (reg) { - case SM5803_REG_GPADC_CONFIG1: - data->gpadc_conf1 = val; - return 0; - case SM5803_REG_GPADC_CONFIG2: - data->gpadc_conf2 = val; - return 0; - } - - LOG_INF("SM5803 meas page write of register %#x unhandled", reg); - return -ENOTSUP; -} - -static int sm5803_test_read_byte(const struct emul *target, int reg, - uint8_t *val, int bytes) -{ - switch (reg) { - case 0x8e: /* Mystery register used for init on chip ID 2 */ - *val = 0; - return 0; - } - LOG_INF("SM5803 test page read of register %#x unhandled", reg); - return -ENOTSUP; -} - -static int sm5803_test_write_byte(const struct emul *target, int reg, - uint8_t val, int bytes) -{ - switch (reg) { - case 0x8e: /* Mystery register used for init on chip ID 2 */ - return 0; - } - LOG_INF("SM5803 test page write of register %#x unhandled", reg); - return -ENOTSUP; -} - -static int sm5803_emul_i2c_transfer(const struct emul *target, - struct i2c_msg *msgs, int num_msgs, - int addr) -{ - struct sm5803_emul_data *data = target->data; - const struct sm5803_emul_cfg *cfg = target->cfg; - - if (addr == cfg->i2c_main.addr) { - return i2c_common_emul_transfer_workhorse(target, - &data->i2c_main, - &cfg->i2c_main, msgs, - num_msgs, addr); - } else if (addr == cfg->i2c_chg.addr) { - return i2c_common_emul_transfer_workhorse(target, - &data->i2c_chg, - &cfg->i2c_chg, msgs, - num_msgs, addr); - } else if (addr == cfg->i2c_meas.addr) { - return i2c_common_emul_transfer_workhorse(target, - &data->i2c_meas, - &cfg->i2c_meas, msgs, - num_msgs, addr); - } else if (addr == cfg->i2c_test.addr) { - return i2c_common_emul_transfer_workhorse(target, - &data->i2c_test, - &cfg->i2c_test, msgs, - num_msgs, addr); - } - LOG_ERR("I2C transaction for address %#x not supported by SM5803", - addr); - return -ENOTSUP; -} - -const static struct i2c_emul_api sm5803_emul_api = { - .transfer = sm5803_emul_i2c_transfer, -}; - -static int sm5803_emul_init(const struct emul *emul, - const struct device *parent) -{ - struct sm5803_emul_data *data = emul->data; - struct i2c_common_emul_data *const i2c_pages[] = { - &data->i2c_chg, - &data->i2c_main, - &data->i2c_meas, - &data->i2c_test, - }; - - for (int i = 0; i < ARRAY_SIZE(i2c_pages); i++) { - int rv = i2c_emul_register(parent, &i2c_pages[i]->emul); - - if (rv != 0) { - k_oops(); - } - i2c_common_emul_init(i2c_pages[i]); - } - - sm5803_emul_reset(emul); - - return 0; -} - -#define INIT_SM5803(n) \ - const static struct sm5803_emul_cfg sm5803_emul_cfg_##n; \ - static struct sm5803_emul_data sm5803_emul_data_##n = { \ - .i2c_main = { \ - .i2c = DEVICE_DT_GET(DT_INST_PARENT(n)), \ - .emul = \ - (struct i2c_emul){ \ - .target = EMUL_DT_GET( \ - DT_DRV_INST(n)), \ - .api = &sm5803_emul_api, \ - .addr = DT_INST_PROP( \ - n, main_addr), \ - }, \ - .cfg = &sm5803_emul_cfg_##n.i2c_main, \ - .read_byte = &sm5803_main_read_byte, \ - .write_byte = &sm5803_main_write_byte, \ - }, \ - .i2c_chg = { \ - .i2c = DEVICE_DT_GET(DT_INST_PARENT(n)), \ - .emul = \ - (struct i2c_emul){ \ - .target = EMUL_DT_GET( \ - DT_DRV_INST(n)), \ - .api = &sm5803_emul_api, \ - .addr = DT_INST_REG_ADDR(n), \ - }, \ - .cfg = &sm5803_emul_cfg_##n.i2c_chg, \ - .read_byte = &sm5803_chg_read_byte, \ - .write_byte = &sm5803_chg_write_byte, \ - }, \ - .i2c_meas = { \ - .i2c = DEVICE_DT_GET(DT_INST_PARENT(n)), \ - .emul = \ - (struct i2c_emul){ \ - .target = EMUL_DT_GET( \ - DT_DRV_INST(n)), \ - .api = &sm5803_emul_api, \ - .addr = DT_INST_PROP( \ - n, meas_addr), \ - }, \ - .cfg = &sm5803_emul_cfg_##n.i2c_meas, \ - .read_byte = &sm5803_meas_read_byte, \ - .write_byte = &sm5803_meas_write_byte, \ - }, \ - .i2c_test = { \ - .i2c = DEVICE_DT_GET(DT_INST_PARENT(n)), \ - .emul = \ - (struct i2c_emul){ \ - .target = EMUL_DT_GET( \ - DT_DRV_INST(n)), \ - .api = &sm5803_emul_api, \ - .addr = DT_INST_PROP( \ - n, test_addr), \ - }, \ - .cfg = &sm5803_emul_cfg_##n.i2c_test, \ - .read_byte = &sm5803_test_read_byte, \ - .write_byte = &sm5803_test_write_byte, \ - }, \ - }; \ - const static struct sm5803_emul_cfg sm5803_emul_cfg_##n = { \ - .i2c_main = \ - (struct i2c_common_emul_cfg){ \ - .dev_label = \ - DT_NODE_FULL_NAME(DT_DRV_INST(n)), \ - .addr = DT_INST_PROP(n, main_addr), \ - .data = &sm5803_emul_data_##n.i2c_main, \ - }, \ - .i2c_chg = \ - (struct i2c_common_emul_cfg){ \ - .dev_label = \ - DT_NODE_FULL_NAME(DT_DRV_INST(n)), \ - .addr = DT_INST_REG_ADDR(n), \ - .data = &sm5803_emul_data_##n.i2c_chg, \ - }, \ - .i2c_meas = \ - (struct i2c_common_emul_cfg){ \ - .dev_label = \ - DT_NODE_FULL_NAME(DT_DRV_INST(n)), \ - .addr = DT_INST_PROP(n, meas_addr), \ - .data = &sm5803_emul_data_##n.i2c_meas, \ - }, \ - .i2c_test = \ - (struct i2c_common_emul_cfg){ \ - .dev_label = \ - DT_NODE_FULL_NAME(DT_DRV_INST(n)), \ - .addr = DT_INST_PROP(n, test_addr), \ - .data = &sm5803_emul_data_##n.i2c_test, \ - }, \ - .interrupt_gpio = { \ - .port = DEVICE_DT_GET(DT_GPIO_CTLR(DT_DRV_INST(n), \ - interrupt_gpios)), \ - .pin = DT_INST_GPIO_PIN(n, interrupt_gpios), \ - .dt_flags = DT_INST_GPIO_FLAGS(n, interrupt_gpios), \ - }, \ - }; \ - EMUL_DT_INST_DEFINE(n, sm5803_emul_init, &sm5803_emul_data_##n, \ - &sm5803_emul_cfg_##n, &sm5803_emul_api, NULL); - -DT_INST_FOREACH_STATUS_OKAY(INIT_SM5803) -DT_INST_FOREACH_STATUS_OKAY(EMUL_STUB_DEVICE) - -static void sm5803_emul_reset_before(const struct ztest_unit_test *test, - void *data) -{ - ARG_UNUSED(test); - ARG_UNUSED(data); - -#define SM5803_EMUL_RESET_RULE_BEFORE(n) \ - sm5803_emul_reset(EMUL_DT_GET(DT_DRV_INST(n))); - - DT_INST_FOREACH_STATUS_OKAY(SM5803_EMUL_RESET_RULE_BEFORE); -} -ZTEST_RULE(sm5803_emul_reset, sm5803_emul_reset_before, NULL); diff --git a/zephyr/include/emul/emul_sm5803.h b/zephyr/include/emul/emul_sm5803.h deleted file mode 100644 index 006fe1d0c7..0000000000 --- a/zephyr/include/emul/emul_sm5803.h +++ /dev/null @@ -1,77 +0,0 @@ -/* Copyright 2023 The ChromiumOS Authors - * Use of this source code is governed by a BSD-style license that can be - * found in the LICENSE file. - */ - -#include <zephyr/drivers/emul.h> -#include <zephyr/drivers/gpio.h> - -const struct gpio_dt_spec * -sm5803_emul_get_interrupt_gpio(const struct emul *emul); -struct i2c_common_emul_data *sm5803_emul_get_i2c_main(const struct emul *emul); -struct i2c_common_emul_data *sm5803_emul_get_i2c_chg(const struct emul *emul); -struct i2c_common_emul_data *sm5803_emul_get_i2c_meas(const struct emul *emul); -struct i2c_common_emul_data *sm5803_emul_get_i2c_test(const struct emul *emul); - -/** - * Read the value of a charger page register, by address. - * - * This is useful to verify that a user has written an expected value to a - * register, without depending on the user's corresponding getter function. - * - * @return negative value on error, otherwise 8-bit register value. - */ -int sm5803_emul_read_chg_reg(const struct emul *emul, uint8_t reg); - -/** - * Set the reported VBUS voltage, in mV. - * - * If the VBUS voltage crosses the charger detection threshold as a result, - * a CHG_DET interrupt will automatically be triggered. - */ -void sm5803_emul_set_vbus_voltage(const struct emul *emul, uint16_t mv); - -/** Set the reported input current (from VBUS), in mA. */ -void sm5803_emul_set_input_current(const struct emul *emul, uint16_t mv); - -/** Set the reported battery charge current, in mA. */ -void sm5803_emul_set_battery_current(const struct emul *emul, uint16_t ma); - -/** Set the reported device ID (default 3). */ -void sm5803_emul_set_device_id(const struct emul *emul, uint8_t id); - -/** Set the platform ID as configured in hardware by the PMODE resistor. */ -void sm5803_emul_set_pmode(const struct emul *emul, uint8_t pmode); - -/** Get the register value of ICHG_FAST_SET; the fast charge current limit. */ -int sm5803_emul_get_fast_charge_current_limit(const struct emul *emul); - -/** Get the values of the GPADC_CONFIG_1 and GPADC_CONFIG_2 registers. */ -void sm5803_emul_get_gpadc_conf(const struct emul *emul, uint8_t *conf1, - uint8_t *conf2); - -/** Set the GPADC enable bits in GPADC_CONFIG_1 and GPADC_CONFIG_2 registers. */ -void sm5803_emul_set_gpadc_conf(const struct emul *emul, uint8_t conf1, - uint8_t conf2); - -/** Return whether the main clock is slowed (CLOCK_SEL:LOW_POWER_CLOCK_EN). */ -bool sm5803_emul_is_clock_slowed(const struct emul *emul); - -/** Get the value of the CC_CONFIG_1 register. */ -uint8_t sm5803_emul_get_cc_config(const struct emul *emul); - -/** Get the values of the FLOW1..FLOW3 registers. */ -void sm5803_emul_get_flow_regs(const struct emul *emul, uint8_t *flow1, - uint8_t *flow2, uint8_t *flow3); - -/** - * Set the INT_REQ_* registers to indicate pending interrupts. - * - * This does not clear pending IRQs; it only asserts them. IRQs are cleared only - * when the interrupt status registers are read. - */ -void sm5803_emul_set_irqs(const struct emul *emul, uint8_t irq1, uint8_t irq2, - uint8_t irq3, uint8_t irq4); - -/** Get the value of the GPIO_CTRL_1 register, which controls GPIO0. */ -uint8_t sm5803_emul_get_gpio_ctrl(const struct emul *emul); diff --git a/zephyr/test/drivers/CMakeLists.txt b/zephyr/test/drivers/CMakeLists.txt index c2e521585e..4768a7567b 100644 --- a/zephyr/test/drivers/CMakeLists.txt +++ b/zephyr/test/drivers/CMakeLists.txt @@ -75,7 +75,6 @@ add_subdirectory_ifdef(CONFIG_LINK_TEST_SUITE_PS8XXX ps8xxx) add_subdirectory_ifdef(CONFIG_LINK_TEST_SUITE_GPIO_UNHOOK gpio_unhook) add_subdirectory_ifdef(CONFIG_LINK_TEST_SUITE_HOST_COMMAND_MEMORY_DUMP host_command_memory_dump) add_subdirectory_ifdef(CONFIG_LINK_TEST_SUITE_ANX7452 anx7452) -add_subdirectory_ifdef(CONFIG_LINK_TEST_SUITE_SM5803 sm5803) get_target_property(TEST_SOURCES_NEW app SOURCES) diff --git a/zephyr/test/drivers/Kconfig b/zephyr/test/drivers/Kconfig index 0a39a54ec6..652b36110f 100644 --- a/zephyr/test/drivers/Kconfig +++ b/zephyr/test/drivers/Kconfig @@ -247,7 +247,4 @@ config LINK_TEST_SUITE_ANX7452 Include the test suite of ANX7452 retimer in the binary. The tests use I2C emulation. -config LINK_TEST_SUITE_SM5803 - bool "Link and test the SM5803 charger tests" - source "Kconfig.zephyr" diff --git a/zephyr/test/drivers/sm5803/CMakeLists.txt b/zephyr/test/drivers/sm5803/CMakeLists.txt deleted file mode 100644 index f7dfa41b4c..0000000000 --- a/zephyr/test/drivers/sm5803/CMakeLists.txt +++ /dev/null @@ -1,5 +0,0 @@ -# Copyright 2023 The ChromiumOS Authors -# Use of this source code is governed by a BSD-style license that can be -# found in the LICENSE file. - -target_sources(app PRIVATE src/sm5803.c src/usbc.c) diff --git a/zephyr/test/drivers/sm5803/prj.conf b/zephyr/test/drivers/sm5803/prj.conf deleted file mode 100644 index 67e8d4287e..0000000000 --- a/zephyr/test/drivers/sm5803/prj.conf +++ /dev/null @@ -1,6 +0,0 @@ -# Copyright 2023 The ChromiumOS Authors -# Use of this source code is governed by a BSD-style license that can be -# found in the LICENSE file. - -CONFIG_PLATFORM_EC_CHARGER_SM5803=y -CONFIG_PLATFORM_EC_PD_MAX_VOLTAGE_MV=15000 diff --git a/zephyr/test/drivers/sm5803/sm5803.dts b/zephyr/test/drivers/sm5803/sm5803.dts deleted file mode 100644 index 4e0fab39e3..0000000000 --- a/zephyr/test/drivers/sm5803/sm5803.dts +++ /dev/null @@ -1,32 +0,0 @@ -/* Copyright 2023 The ChromiumOS Authors - * Use of this source code is governed by a BSD-style license that can be - * found in the LICENSE file. - */ - -/ { - usbc { - port0@0 { - compatible = "named-usbc-port"; - chg = <&sm5803_emul>; - }; - }; - - gpio2: gpio@2000 { - status = "okay"; - compatible = "zephyr,gpio-emul"; - reg = <0x2000 0x4>; - falling-edge; - gpio-controller; - #gpio-cells = <2>; - ngpios = <1>; - }; -}; - -&i2c0 { - sm5803_emul: sm5803@32 { - compatible = "cros,sm5803-emul", "siliconmitus,sm5803"; - status = "okay"; - reg = <0x32>; - interrupt-gpios = <&gpio2 0 (GPIO_ACTIVE_LOW)>; - }; -}; diff --git a/zephyr/test/drivers/sm5803/src/sm5803.c b/zephyr/test/drivers/sm5803/src/sm5803.c deleted file mode 100644 index b9d4e17505..0000000000 --- a/zephyr/test/drivers/sm5803/src/sm5803.c +++ /dev/null @@ -1,709 +0,0 @@ -/* Copyright 2023 The ChromiumOS Authors - * Use of this source code is governed by a BSD-style license that can be - * found in the LICENSE file. - */ - -#include "battery_smart.h" -#include "charger.h" -#include "driver/charger/sm5803.h" -#include "emul/emul_common_i2c.h" -#include "emul/emul_sm5803.h" -#include "emul/tcpc/emul_tcpci_partner_src.h" -#include "test/drivers/charger_utils.h" -#include "test/drivers/test_state.h" -#include "test/drivers/utils.h" - -#include <zephyr/drivers/emul.h> -#include <zephyr/ztest.h> - -#define CHARGER_NUM get_charger_num(&sm5803_drv) -#define SM5803_EMUL EMUL_DT_GET(DT_NODELABEL(sm5803_emul)) - -ZTEST_SUITE(sm5803, drivers_predicate_post_main, NULL, NULL, NULL, NULL); - -ZTEST(sm5803, test_chip_id) -{ - int id; - - /* Emulator only implements chip revision 3. */ - zassert_ok(sm5803_drv.device_id(CHARGER_NUM, &id)); - zassert_equal(id, 3); - - /* After a successful read, the value is cached. */ - i2c_common_emul_set_read_fail_reg(sm5803_emul_get_i2c_main(SM5803_EMUL), - SM5803_REG_CHIP_ID); - zassert_ok(sm5803_drv.device_id(CHARGER_NUM, &id)); -} - -struct i2c_log_entry { - bool write; - uint8_t i2c_addr; - uint8_t reg_addr; - uint8_t value; -}; - -struct i2c_log { - struct i2c_log_entry entries[128]; - size_t entries_used; - size_t entries_asserted; -}; - -#define LOG_ASSERT(_write, _i2c_addr, _reg_addr, _value) \ - do { \ - zassert_true(log_ptr->entries_asserted < \ - log_ptr->entries_used, \ - "No more I2C transactions to verify " \ - "(logged %d)", \ - log_ptr->entries_used); \ - size_t i = log_ptr->entries_asserted++; \ - struct i2c_log_entry *entry = &log_ptr->entries[i]; \ - \ - zassert(entry->write == _write && \ - entry->i2c_addr == _i2c_addr && \ - entry->reg_addr == _reg_addr && \ - (!_write || entry->value == _value), \ - "I2C log mismatch", \ - "Transaction %d did not match expectations:\n" \ - "expected %5s of address %#04x register" \ - " %#04x with value %#04x\n" \ - " found %s of address %#04x register" \ - " %#04x with value %#04x", \ - i, _write ? "write" : "read", _i2c_addr, _reg_addr, \ - _value, entry->write ? "write" : "read", \ - entry->i2c_addr, entry->reg_addr, entry->value); \ - } while (0) - -#define LOG_ASSERT_R(_i2c_addr, _reg_addr) \ - LOG_ASSERT(false, _i2c_addr, _reg_addr, 0) -#define LOG_ASSERT_W(_i2c_addr, _reg_addr, _value) \ - LOG_ASSERT(true, _i2c_addr, _reg_addr, _value) -#define LOG_ASSERT_RW(_i2c_addr, _reg_addr, _value) \ - do { \ - LOG_ASSERT_R(_i2c_addr, _reg_addr); \ - LOG_ASSERT_W(_i2c_addr, _reg_addr, _value); \ - } while (0) - -/* - * Generate a function for each I2C address to log the correct address, because - * the target pointer is the same for each I2C address and there's no way to - * determine from parameters what address we're meant to be. - */ -#define DEFINE_LOG_FNS(name, addr) \ - static int i2c_log_write_##name(const struct emul *target, int reg, \ - uint8_t val, int bytes, void *ctx) \ - { \ - struct i2c_log *log = ctx; \ - \ - if (log->entries_used >= ARRAY_SIZE(log->entries)) { \ - return -ENOSPC; \ - } \ - \ - zassert_equal(target->bus_type, EMUL_BUS_TYPE_I2C); \ - log->entries[log->entries_used++] = (struct i2c_log_entry){ \ - .write = true, \ - .i2c_addr = addr, \ - .reg_addr = reg, \ - .value = val, \ - }; \ - \ - /* Discard write. */ \ - return 0; \ - } \ - \ - static int i2c_log_read_##name(const struct emul *target, int reg, \ - uint8_t *val, int bytes, void *ctx) \ - { \ - struct i2c_log *log = ctx; \ - \ - if (log->entries_used >= ARRAY_SIZE(log->entries)) { \ - return -ENOSPC; \ - } \ - \ - zassert_equal(target->bus_type, EMUL_BUS_TYPE_I2C); \ - log->entries[log->entries_used++] = (struct i2c_log_entry){ \ - .write = false, \ - .i2c_addr = addr, \ - .reg_addr = reg, \ - }; \ - \ - /* Fall through to emulator read. */ \ - return 1; \ - } - -DEFINE_LOG_FNS(main, SM5803_ADDR_MAIN_FLAGS); -DEFINE_LOG_FNS(meas, SM5803_ADDR_MEAS_FLAGS); -DEFINE_LOG_FNS(chg, SM5803_ADDR_CHARGER_FLAGS); -DEFINE_LOG_FNS(test, SM5803_ADDR_TEST_FLAGS); - -static void configure_i2c_log(const struct emul *emul, struct i2c_log *log) -{ - i2c_common_emul_set_read_func(sm5803_emul_get_i2c_main(emul), - i2c_log_read_main, log); - i2c_common_emul_set_write_func(sm5803_emul_get_i2c_main(emul), - i2c_log_write_main, log); - i2c_common_emul_set_read_func(sm5803_emul_get_i2c_meas(emul), - i2c_log_read_meas, log); - i2c_common_emul_set_write_func(sm5803_emul_get_i2c_meas(emul), - i2c_log_write_meas, log); - i2c_common_emul_set_read_func(sm5803_emul_get_i2c_chg(emul), - i2c_log_read_chg, log); - i2c_common_emul_set_write_func(sm5803_emul_get_i2c_chg(emul), - i2c_log_write_chg, log); - i2c_common_emul_set_read_func(sm5803_emul_get_i2c_test(emul), - i2c_log_read_test, log); - i2c_common_emul_set_write_func(sm5803_emul_get_i2c_test(emul), - i2c_log_write_test, log); -} - -static void verify_init_common(struct i2c_log *const log_ptr) -{ - /* Enable LDOs */ - LOG_ASSERT_RW(SM5803_ADDR_MAIN_FLAGS, SM5803_REG_REFERENCE, 0); - /* Psys DAC */ - LOG_ASSERT_RW(SM5803_ADDR_MEAS_FLAGS, SM5803_REG_PSYS1, 0x05); - /* ADC sigma delta */ - LOG_ASSERT_RW(SM5803_ADDR_CHARGER_FLAGS, SM5803_REG_CC_CONFIG1, 0x09); - /* PROCHOT comparators */ - LOG_ASSERT_RW(SM5803_ADDR_CHARGER_FLAGS, SM5803_REG_PHOT1, 0x2d); - /* DPM voltage */ - LOG_ASSERT_W(SM5803_ADDR_CHARGER_FLAGS, SM5803_REG_DPM_VL_SET_MSB, - 0x12); - LOG_ASSERT_W(SM5803_ADDR_CHARGER_FLAGS, SM5803_REG_DPM_VL_SET_LSB, - 0x04); - /* Default input current limit */ - LOG_ASSERT_W(SM5803_ADDR_CHARGER_FLAGS, SM5803_REG_CHG_ILIM, 0x05); - /* Interrupts */ - LOG_ASSERT_W(SM5803_ADDR_MAIN_FLAGS, SM5803_REG_INT1_EN, 0x04); - LOG_ASSERT_W(SM5803_ADDR_MAIN_FLAGS, SM5803_REG_INT4_EN, 0x13); - LOG_ASSERT_W(SM5803_ADDR_MEAS_FLAGS, SM5803_REG_TINT_HIGH_TH, 0xd1); - LOG_ASSERT_W(SM5803_ADDR_MEAS_FLAGS, SM5803_REG_TINT_LOW_TH, 0); - LOG_ASSERT_RW(SM5803_ADDR_MAIN_FLAGS, SM5803_REG_INT2_EN, 0x81); - /* Charging is exclusively EC-controlled */ - LOG_ASSERT_W(SM5803_ADDR_CHARGER_FLAGS, SM5803_REG_FLOW2, 0x40); - /* Battery parameters */ - LOG_ASSERT_RW(SM5803_ADDR_CHARGER_FLAGS, SM5803_REG_FAST_CONF5, 0x02); - LOG_ASSERT_RW(SM5803_ADDR_CHARGER_FLAGS, SM5803_REG_PRE_FAST_CONF_REG1, - 0); - LOG_ASSERT_W(SM5803_ADDR_CHARGER_FLAGS, SM5803_REG_PRECHG, 0x02); - /* BFET limits */ - LOG_ASSERT_W(SM5803_ADDR_MEAS_FLAGS, SM5803_REG_BFET_PWR_MAX_TH, 0x33); - LOG_ASSERT_W(SM5803_ADDR_MEAS_FLAGS, SM5803_REG_BFET_PWR_HWSAFE_MAX_TH, - 0xcd); - LOG_ASSERT_RW(SM5803_ADDR_MAIN_FLAGS, SM5803_REG_INT3_EN, 0x06); - LOG_ASSERT_RW(SM5803_ADDR_CHARGER_FLAGS, SM5803_REG_FLOW3, 0); - LOG_ASSERT_RW(SM5803_ADDR_CHARGER_FLAGS, SM5803_REG_SWITCHER_CONF, - 0x01); -} - -/** - * Driver internal "init completed" flag needs to be cleared to actually run - * init. - */ -extern bool chip_inited[1]; -/** Driver internal cached value of chip device ID. */ -extern int dev_id; - -ZTEST(sm5803, test_init_2s) -{ - struct i2c_log log = {}; - struct i2c_log *const log_ptr = &log; - - /* Hook up logging functions for each I2C address. */ - configure_i2c_log(SM5803_EMUL, &log); - - /* Emulator defaults to 2S PMODE so we don't need to set it. */ - chip_inited[0] = false; - sm5803_drv.init(CHARGER_NUM); - - /* Ensures we're in a safe state for operation. */ - LOG_ASSERT_R(SM5803_ADDR_MAIN_FLAGS, SM5803_REG_CLOCK_SEL); - LOG_ASSERT_W(SM5803_ADDR_MEAS_FLAGS, SM5803_REG_GPADC_CONFIG1, 0xf7); - /* Checks VBUS presence and disables charger. */ - LOG_ASSERT_R(SM5803_ADDR_MEAS_FLAGS, SM5803_REG_GPADC_CONFIG1); - LOG_ASSERT_R(SM5803_ADDR_MEAS_FLAGS, SM5803_REG_VBUS_MEAS_MSB); - LOG_ASSERT_R(SM5803_ADDR_MEAS_FLAGS, SM5803_REG_VBUS_MEAS_LSB); - LOG_ASSERT_W(SM5803_ADDR_CHARGER_FLAGS, SM5803_REG_FLOW1, 0); - /* Gets chip ID (already cached) and PMODE. */ - LOG_ASSERT_R(SM5803_ADDR_MAIN_FLAGS, SM5803_REG_PLATFORM); - /* Writes a lot of registers for presumably important reasons. */ - LOG_ASSERT_W(SM5803_ADDR_MEAS_FLAGS, 0x26, 0xdc); - LOG_ASSERT_W(SM5803_ADDR_CHARGER_FLAGS, 0x21, 0x9b); - LOG_ASSERT_W(SM5803_ADDR_MAIN_FLAGS, 0x30, 0xc0); - LOG_ASSERT_W(SM5803_ADDR_MAIN_FLAGS, 0x80, 0x01); - LOG_ASSERT_W(SM5803_ADDR_MAIN_FLAGS, 0x1a, 0x08); - LOG_ASSERT_W(SM5803_ADDR_MEAS_FLAGS, 0x08, 0xc2); - LOG_ASSERT_W(SM5803_ADDR_CHARGER_FLAGS, 0x1d, 0x40); - LOG_ASSERT_W(SM5803_ADDR_CHARGER_FLAGS, 0x22, 0xb3); - LOG_ASSERT_W(SM5803_ADDR_CHARGER_FLAGS, 0x3e, 0x3c); - LOG_ASSERT_W(SM5803_ADDR_CHARGER_FLAGS, 0x4f, 0xbf); - LOG_ASSERT_W(SM5803_ADDR_CHARGER_FLAGS, 0x52, 0x77); - LOG_ASSERT_W(SM5803_ADDR_CHARGER_FLAGS, 0x53, 0xD2); - LOG_ASSERT_W(SM5803_ADDR_CHARGER_FLAGS, 0x54, 0x02); - LOG_ASSERT_W(SM5803_ADDR_CHARGER_FLAGS, 0x55, 0xD1); - LOG_ASSERT_W(SM5803_ADDR_CHARGER_FLAGS, 0x56, 0x7F); - LOG_ASSERT_W(SM5803_ADDR_CHARGER_FLAGS, 0x57, 0x01); - LOG_ASSERT_W(SM5803_ADDR_CHARGER_FLAGS, 0x58, 0x50); - LOG_ASSERT_W(SM5803_ADDR_CHARGER_FLAGS, 0x59, 0x7F); - LOG_ASSERT_W(SM5803_ADDR_CHARGER_FLAGS, 0x5A, 0x13); - LOG_ASSERT_W(SM5803_ADDR_CHARGER_FLAGS, 0x5B, 0x52); - LOG_ASSERT_W(SM5803_ADDR_CHARGER_FLAGS, 0x5D, 0xD0); - LOG_ASSERT_W(SM5803_ADDR_CHARGER_FLAGS, 0x60, 0x44); - LOG_ASSERT_W(SM5803_ADDR_CHARGER_FLAGS, 0x65, 0x35); - LOG_ASSERT_W(SM5803_ADDR_CHARGER_FLAGS, 0x66, 0x29); - LOG_ASSERT_W(SM5803_ADDR_CHARGER_FLAGS, 0x7D, 0x97); - LOG_ASSERT_W(SM5803_ADDR_CHARGER_FLAGS, 0x7E, 0x07); - LOG_ASSERT_W(SM5803_ADDR_CHARGER_FLAGS, 0x33, 0x3C); - LOG_ASSERT_W(SM5803_ADDR_CHARGER_FLAGS, 0x5C, 0x7A); - LOG_ASSERT_W(SM5803_ADDR_CHARGER_FLAGS, 0x73, 0x22); - LOG_ASSERT_W(SM5803_ADDR_CHARGER_FLAGS, 0x50, 0x88); - LOG_ASSERT_RW(SM5803_ADDR_CHARGER_FLAGS, 0x34, 0x80); - LOG_ASSERT_W(SM5803_ADDR_MAIN_FLAGS, 0x1f, 0x01); - LOG_ASSERT_W(SM5803_ADDR_TEST_FLAGS, 0x43, 0x10); - LOG_ASSERT_W(SM5803_ADDR_TEST_FLAGS, 0x47, 0x10); - LOG_ASSERT_W(SM5803_ADDR_TEST_FLAGS, 0x48, 0x04); - LOG_ASSERT_W(SM5803_ADDR_MAIN_FLAGS, 0x1f, 0); - verify_init_common(log_ptr); - - zassert_equal(log.entries_asserted, log.entries_used, - "recorded %d transactions but only verified %d", - log.entries_used, log.entries_asserted); - - /* - * Running init again should check and update VBUS presence but not - * re-run complete initialization. Doing more than that probably means - * the first init failed. - */ - log.entries_used = 0; - sm5803_drv.init(CHARGER_NUM); - zassert_equal(log.entries_used, 6); -} - -ZTEST(sm5803, test_init_3s) -{ - struct i2c_log log = {}; - struct i2c_log *const log_ptr = &log; - - /* Hook up logging functions for each I2C address. */ - configure_i2c_log(SM5803_EMUL, &log); - - /* Set 3S PMODE and run init */ - chip_inited[0] = false; - sm5803_emul_set_pmode(SM5803_EMUL, 0x14); - sm5803_drv.init(CHARGER_NUM); - - /* Ensures we're in a safe state for operation. */ - LOG_ASSERT_R(SM5803_ADDR_MAIN_FLAGS, SM5803_REG_CLOCK_SEL); - LOG_ASSERT_W(SM5803_ADDR_MEAS_FLAGS, SM5803_REG_GPADC_CONFIG1, 0xf7); - /* Checks VBUS presence and disables charger. */ - LOG_ASSERT_R(SM5803_ADDR_MEAS_FLAGS, SM5803_REG_GPADC_CONFIG1); - LOG_ASSERT_R(SM5803_ADDR_MEAS_FLAGS, SM5803_REG_VBUS_MEAS_MSB); - LOG_ASSERT_R(SM5803_ADDR_MEAS_FLAGS, SM5803_REG_VBUS_MEAS_LSB); - LOG_ASSERT_W(SM5803_ADDR_CHARGER_FLAGS, SM5803_REG_FLOW1, 0); - /* Gets chip ID (already cached) and PMODE. */ - LOG_ASSERT_R(SM5803_ADDR_MAIN_FLAGS, SM5803_REG_PLATFORM); - /* Writes a lot of registers for presumably important reasons. */ - LOG_ASSERT_W(SM5803_ADDR_MEAS_FLAGS, 0x26, 0xd8); - LOG_ASSERT_W(SM5803_ADDR_CHARGER_FLAGS, 0x21, 0x9b); - LOG_ASSERT_W(SM5803_ADDR_MAIN_FLAGS, 0x30, 0xc0); - LOG_ASSERT_W(SM5803_ADDR_MAIN_FLAGS, 0x80, 0x01); - LOG_ASSERT_W(SM5803_ADDR_MAIN_FLAGS, 0x1a, 0x08); - LOG_ASSERT_W(SM5803_ADDR_MEAS_FLAGS, 0x08, 0xc2); - LOG_ASSERT_W(SM5803_ADDR_CHARGER_FLAGS, 0x1d, 0x40); - LOG_ASSERT_W(SM5803_ADDR_CHARGER_FLAGS, 0x22, 0xb3); - LOG_ASSERT_W(SM5803_ADDR_CHARGER_FLAGS, 0x3e, 0x3c); - LOG_ASSERT_W(SM5803_ADDR_CHARGER_FLAGS, 0x4b, 0xa6); - LOG_ASSERT_W(SM5803_ADDR_CHARGER_FLAGS, 0x4f, 0xbf); - LOG_ASSERT_W(SM5803_ADDR_CHARGER_FLAGS, 0x52, 0x77); - LOG_ASSERT_W(SM5803_ADDR_CHARGER_FLAGS, 0x53, 0xD2); - LOG_ASSERT_W(SM5803_ADDR_CHARGER_FLAGS, 0x54, 0x02); - LOG_ASSERT_W(SM5803_ADDR_CHARGER_FLAGS, 0x55, 0xD1); - LOG_ASSERT_W(SM5803_ADDR_CHARGER_FLAGS, 0x56, 0x7F); - LOG_ASSERT_W(SM5803_ADDR_CHARGER_FLAGS, 0x57, 0x01); - LOG_ASSERT_W(SM5803_ADDR_CHARGER_FLAGS, 0x58, 0x50); - LOG_ASSERT_W(SM5803_ADDR_CHARGER_FLAGS, 0x59, 0x7F); - LOG_ASSERT_W(SM5803_ADDR_CHARGER_FLAGS, 0x5A, 0x13); - LOG_ASSERT_W(SM5803_ADDR_CHARGER_FLAGS, 0x5B, 0x50); - LOG_ASSERT_W(SM5803_ADDR_CHARGER_FLAGS, 0x5D, 0xB0); - LOG_ASSERT_W(SM5803_ADDR_CHARGER_FLAGS, 0x60, 0x44); - LOG_ASSERT_W(SM5803_ADDR_CHARGER_FLAGS, 0x65, 0x35); - LOG_ASSERT_W(SM5803_ADDR_CHARGER_FLAGS, 0x66, 0x29); - LOG_ASSERT_W(SM5803_ADDR_CHARGER_FLAGS, 0x7D, 0x67); - LOG_ASSERT_W(SM5803_ADDR_CHARGER_FLAGS, 0x7E, 0x04); - LOG_ASSERT_W(SM5803_ADDR_CHARGER_FLAGS, 0x33, 0x3C); - LOG_ASSERT_W(SM5803_ADDR_CHARGER_FLAGS, 0x5C, 0x7A); - LOG_ASSERT_W(SM5803_ADDR_CHARGER_FLAGS, 0x73, 0x22); - LOG_ASSERT_W(SM5803_ADDR_CHARGER_FLAGS, 0x50, 0x88); - LOG_ASSERT_RW(SM5803_ADDR_CHARGER_FLAGS, 0x34, 0x80); - LOG_ASSERT_W(SM5803_ADDR_MAIN_FLAGS, 0x1f, 0x01); - LOG_ASSERT_W(SM5803_ADDR_TEST_FLAGS, 0x43, 0x10); - LOG_ASSERT_W(SM5803_ADDR_TEST_FLAGS, 0x47, 0x10); - LOG_ASSERT_W(SM5803_ADDR_TEST_FLAGS, 0x48, 0x04); - LOG_ASSERT_W(SM5803_ADDR_MAIN_FLAGS, 0x1f, 0); - verify_init_common(log_ptr); - - zassert_equal(log.entries_asserted, log.entries_used, - "recorded %d transactions but only verified %d", - log.entries_used, log.entries_asserted); -} - -ZTEST(sm5803, test_init_rev2) -{ - struct i2c_log log = {}; - struct i2c_log *const log_ptr = &log; - - /* Hook up logging functions for each I2C address. */ - configure_i2c_log(SM5803_EMUL, &log); - - chip_inited[0] = false; - dev_id = -1; - sm5803_emul_set_device_id(SM5803_EMUL, 2); - sm5803_drv.init(CHARGER_NUM); - - /* Ensures we're in a safe state for operation. */ - LOG_ASSERT_R(SM5803_ADDR_MAIN_FLAGS, SM5803_REG_CLOCK_SEL); - LOG_ASSERT_W(SM5803_ADDR_MEAS_FLAGS, SM5803_REG_GPADC_CONFIG1, 0xf7); - /* Checks VBUS presence and disables charger. */ - LOG_ASSERT_R(SM5803_ADDR_MEAS_FLAGS, SM5803_REG_GPADC_CONFIG1); - LOG_ASSERT_R(SM5803_ADDR_MEAS_FLAGS, SM5803_REG_VBUS_MEAS_MSB); - LOG_ASSERT_R(SM5803_ADDR_MEAS_FLAGS, SM5803_REG_VBUS_MEAS_LSB); - LOG_ASSERT_W(SM5803_ADDR_CHARGER_FLAGS, SM5803_REG_FLOW1, 0); - /* Gets chip ID */ - LOG_ASSERT_R(SM5803_ADDR_MAIN_FLAGS, SM5803_REG_CHIP_ID); - /* Writes a lot of registers for presumably important reasons. */ - LOG_ASSERT_W(SM5803_ADDR_MAIN_FLAGS, 0x20, 0x08); - LOG_ASSERT_W(SM5803_ADDR_MAIN_FLAGS, 0x30, 0xc0); - LOG_ASSERT_W(SM5803_ADDR_MAIN_FLAGS, 0x80, 0x01); - LOG_ASSERT_W(SM5803_ADDR_MEAS_FLAGS, 0x08, 0xc2); - LOG_ASSERT_W(SM5803_ADDR_CHARGER_FLAGS, 0x1d, 0x40); - LOG_ASSERT_W(SM5803_ADDR_CHARGER_FLAGS, 0x1f, 0x09); - LOG_ASSERT_W(SM5803_ADDR_CHARGER_FLAGS, 0x22, 0xb3); - LOG_ASSERT_W(SM5803_ADDR_CHARGER_FLAGS, 0x23, 0x81); - LOG_ASSERT_W(SM5803_ADDR_CHARGER_FLAGS, 0x28, 0xb7); - LOG_ASSERT_W(SM5803_ADDR_CHARGER_FLAGS, 0x4a, 0x82); - LOG_ASSERT_W(SM5803_ADDR_CHARGER_FLAGS, 0x4b, 0xa3); - LOG_ASSERT_W(SM5803_ADDR_CHARGER_FLAGS, 0x4c, 0xa8); - LOG_ASSERT_W(SM5803_ADDR_CHARGER_FLAGS, 0x4d, 0xca); - LOG_ASSERT_W(SM5803_ADDR_CHARGER_FLAGS, 0x4e, 0x07); - LOG_ASSERT_W(SM5803_ADDR_CHARGER_FLAGS, 0x4f, 0xff); - - LOG_ASSERT_W(SM5803_ADDR_CHARGER_FLAGS, 0x50, 0x98); - LOG_ASSERT_W(SM5803_ADDR_CHARGER_FLAGS, 0x51, 0); - LOG_ASSERT_W(SM5803_ADDR_CHARGER_FLAGS, 0x52, 0x77); - LOG_ASSERT_W(SM5803_ADDR_CHARGER_FLAGS, 0x53, 0xd2); - LOG_ASSERT_W(SM5803_ADDR_CHARGER_FLAGS, 0x54, 0x02); - LOG_ASSERT_W(SM5803_ADDR_CHARGER_FLAGS, 0x55, 0xd1); - LOG_ASSERT_W(SM5803_ADDR_CHARGER_FLAGS, 0x56, 0x7f); - LOG_ASSERT_W(SM5803_ADDR_CHARGER_FLAGS, 0x57, 0x02); - LOG_ASSERT_W(SM5803_ADDR_CHARGER_FLAGS, 0x58, 0xd1); - LOG_ASSERT_W(SM5803_ADDR_CHARGER_FLAGS, 0x59, 0x7f); - LOG_ASSERT_W(SM5803_ADDR_CHARGER_FLAGS, 0x5a, 0x13); - LOG_ASSERT_W(SM5803_ADDR_CHARGER_FLAGS, 0x5b, 0x50); - LOG_ASSERT_W(SM5803_ADDR_CHARGER_FLAGS, 0x5c, 0x5b); - LOG_ASSERT_W(SM5803_ADDR_CHARGER_FLAGS, 0x5d, 0xb0); - LOG_ASSERT_W(SM5803_ADDR_CHARGER_FLAGS, 0x5e, 0x3c); - LOG_ASSERT_W(SM5803_ADDR_CHARGER_FLAGS, 0x5f, 0x3c); - - LOG_ASSERT_W(SM5803_ADDR_CHARGER_FLAGS, 0x60, 0x44); - LOG_ASSERT_W(SM5803_ADDR_CHARGER_FLAGS, 0x61, 0x20); - LOG_ASSERT_W(SM5803_ADDR_CHARGER_FLAGS, 0x65, 0x35); - LOG_ASSERT_W(SM5803_ADDR_CHARGER_FLAGS, 0x66, 0x29); - LOG_ASSERT_W(SM5803_ADDR_CHARGER_FLAGS, 0x67, 0x64); - LOG_ASSERT_W(SM5803_ADDR_CHARGER_FLAGS, 0x68, 0x88); - LOG_ASSERT_W(SM5803_ADDR_CHARGER_FLAGS, 0x69, 0xc7); - - LOG_ASSERT_W(SM5803_ADDR_MAIN_FLAGS, 0x1f, 1); - LOG_ASSERT_RW(SM5803_ADDR_TEST_FLAGS, 0x8e, 0x20); - LOG_ASSERT_W(SM5803_ADDR_MAIN_FLAGS, 0x1f, 0); - - verify_init_common(log_ptr); - - zassert_equal(log.entries_asserted, log.entries_used, - "recorded %d transactions but only verified %d", - log.entries_used, log.entries_asserted); -} - -ZTEST(sm5803, test_fast_charge_current) -{ - int ma; - - /* - * Can set and read back charge current limit, - * which is adjusted when 0. - */ - zassert_ok(charger_set_current(CHARGER_NUM, 0)); - zassert_equal(1, sm5803_emul_get_fast_charge_current_limit(SM5803_EMUL), - "Zero current limit should be converted to nonzero"); - zassert_ok(charger_get_current(CHARGER_NUM, &ma)); - zassert_equal(ma, 100, - "Actual current should be 100 mA times register value"); - - /* Errors are propagated. */ - i2c_common_emul_set_read_fail_reg(sm5803_emul_get_i2c_chg(SM5803_EMUL), - SM5803_REG_FAST_CONF4); - zassert_not_equal( - 0, charger_set_current(CHARGER_NUM, 1000), - "set_current should fail if FAST_CONF4 is unreadable"); - zassert_not_equal( - 0, charger_get_current(CHARGER_NUM, &ma), - "get_current should fail if FAST_CONF4 is unreadable"); -} - -ZTEST(sm5803, test_measure_input_current) -{ - int ma; - - sm5803_emul_set_input_current(SM5803_EMUL, 852); - zassert_ok(charger_get_input_current(CHARGER_NUM, &ma)); - zassert_equal(ma, 849, "actual returned input current was %d", ma); - - /* Communication errors bubble up */ - i2c_common_emul_set_read_fail_reg(sm5803_emul_get_i2c_meas(SM5803_EMUL), - SM5803_REG_IBUS_CHG_MEAS_LSB); - zassert_not_equal(0, charger_get_input_current(CHARGER_NUM, &ma)); - i2c_common_emul_set_read_fail_reg(sm5803_emul_get_i2c_meas(SM5803_EMUL), - SM5803_REG_IBUS_CHG_MEAS_MSB); - zassert_not_equal(0, charger_get_input_current(CHARGER_NUM, &ma)); -} - -ZTEST(sm5803, test_input_current_limit) -{ - int icl; - bool reached; - - /* Can set and read back the input current limit. */ - zassert_ok(charger_set_input_current_limit(CHARGER_NUM, 2150)); - zassert_equal(21, sm5803_emul_read_chg_reg(SM5803_EMUL, - SM5803_REG_CHG_ILIM)); - zassert_ok(charger_get_input_current_limit(CHARGER_NUM, &icl)); - zassert_equal(2100, icl, - "expected 2100 mA input current limit, but was %d", icl); - - /* Can also check whether input current is limited. */ - zassert_ok(charger_is_icl_reached(CHARGER_NUM, &reached)); - zassert_false(reached); - sm5803_emul_set_input_current(SM5803_EMUL, 2400); - zassert_ok(charger_is_icl_reached(CHARGER_NUM, &reached)); - zassert_true(reached); - - /* Communication errors bubble up. */ - i2c_common_emul_set_read_fail_reg(sm5803_emul_get_i2c_chg(SM5803_EMUL), - SM5803_REG_CHG_ILIM); - zassert_not_equal(0, - charger_get_input_current_limit(CHARGER_NUM, &icl)); - i2c_common_emul_set_write_fail_reg(sm5803_emul_get_i2c_chg(SM5803_EMUL), - SM5803_REG_CHG_ILIM); - zassert_not_equal(0, - charger_set_input_current_limit(CHARGER_NUM, 1400)); -} - -/* Analog measurement of VBUS. */ -ZTEST(sm5803, test_get_vbus_voltage) -{ - int mv; - - /* Regular measurement with VBUS ADC enabled works. */ - sm5803_emul_set_vbus_voltage(SM5803_EMUL, 5032); - zassert_ok(charger_get_vbus_voltage(CHARGER_NUM, &mv)); - /* 5.031 is the nearest value representable by the VBUS ADC. */ - zassert_equal(mv, 5031, "driver reported %d mV VBUS", mv); - - /* Communication errors for ADC value bubble up. */ - i2c_common_emul_set_read_fail_reg(sm5803_emul_get_i2c_meas(SM5803_EMUL), - SM5803_REG_VBUS_MEAS_LSB); - zassert_not_equal(0, charger_get_vbus_voltage(CHARGER_NUM, &mv)); - i2c_common_emul_set_read_fail_reg(sm5803_emul_get_i2c_meas(SM5803_EMUL), - SM5803_REG_VBUS_MEAS_MSB); - zassert_not_equal(0, charger_get_vbus_voltage(CHARGER_NUM, &mv)); - - /* Returns a NOT_POWERED error if the VBUS ADC is disabled. */ - sm5803_emul_set_gpadc_conf(SM5803_EMUL, - (uint8_t)~SM5803_GPADCC1_VBUS_EN, 0); - zassert_equal(EC_ERROR_NOT_POWERED, - charger_get_vbus_voltage(CHARGER_NUM, &mv)); -} - -ZTEST(sm5803, test_get_battery_current) -{ - int ma; - - sm5803_emul_set_battery_current(SM5803_EMUL, 1234); - zassert_ok(charger_get_actual_current(CHARGER_NUM, &ma)); - /* 1229 mA is nearest value representable at ADC resolution */ - zassert_equal(ma, 1229, "read value was %d", ma); - - /* Communication errors bubble up. */ - i2c_common_emul_set_read_fail_reg(sm5803_emul_get_i2c_meas(SM5803_EMUL), - SM5803_REG_IBAT_CHG_AVG_MEAS_LSB); - zassert_not_equal(0, charger_get_actual_current(CHARGER_NUM, &ma)); - i2c_common_emul_set_read_fail_reg(sm5803_emul_get_i2c_meas(SM5803_EMUL), - SM5803_REG_IBAT_CHG_AVG_MEAS_MSB); - zassert_not_equal(0, charger_get_actual_current(CHARGER_NUM, &ma)); -} - -/* Digital VBUS presence detection derived from DHG_DET. */ -ZTEST(sm5803, test_digital_vbus_presence_detect) -{ - /* - * CHG_DET going high (from VBUS presence) triggers an interrupt and - * presence update. - */ - sm5803_emul_set_vbus_voltage(SM5803_EMUL, 5000); - k_sleep(K_SECONDS(1)); /* Allow interrupt to be serviced. */ - zassert_true(sm5803_is_vbus_present(CHARGER_NUM)); - - /* VBUS going away triggers another interrupt and update. */ - sm5803_emul_set_vbus_voltage(SM5803_EMUL, 0); - k_sleep(K_SECONDS(1)); /* Allow interrupt to be serviced. */ - zassert_false(sm5803_is_vbus_present(CHARGER_NUM)); -} - -/* VBUS detection for PD, analog or digital depending on chip state. */ -ZTEST(sm5803, test_check_vbus_level) -{ - /* Default state with VBUS ADC enabled: uses analog value */ - zassert_true(sm5803_check_vbus_level(CHARGER_NUM, VBUS_REMOVED)); - sm5803_emul_set_vbus_voltage(SM5803_EMUL, 5000); - zassert_true(sm5803_check_vbus_level(CHARGER_NUM, VBUS_PRESENT)); - - /* 4.6V is less than vSafe5V */ - sm5803_emul_set_vbus_voltage(SM5803_EMUL, 4600); - k_sleep(K_SECONDS(1)); - zassert_false(sm5803_check_vbus_level(CHARGER_NUM, VBUS_PRESENT)); - - /* - * With ADC disabled, uses digital presence only. 4.6V is high enough - * to trip CHG_DET but wasn't enough to count as present with the analog - * reading. - */ - sm5803_emul_set_gpadc_conf(SM5803_EMUL, 0, 0); - zassert_true(sm5803_check_vbus_level(CHARGER_NUM, VBUS_PRESENT)); - - /* 0.4V is !CHG_DET */ - sm5803_emul_set_vbus_voltage(SM5803_EMUL, 400); - k_sleep(K_SECONDS(1)); - zassert_true(sm5803_check_vbus_level(CHARGER_NUM, VBUS_REMOVED)); -} - -ZTEST(sm5803, test_lpm) -{ - const struct emul *tcpci_emul = EMUL_GET_USBC_BINDING(0, tcpc); - struct tcpci_partner_data partner; - struct tcpci_src_emul_data partner_src; - uint8_t gpadc1, gpadc2; - uint8_t cc_conf1; - uint8_t flow1, flow2, flow3; - - tcpci_partner_init(&partner, PD_REV30); - partner.extensions = tcpci_src_emul_init(&partner_src, &partner, NULL); - - /* Connect 5V source. */ - zassert_ok(tcpci_partner_connect_to_tcpci(&partner, tcpci_emul)); - sm5803_emul_set_vbus_voltage(SM5803_EMUL, 5000); - k_sleep(K_SECONDS(4)); - - /* Charger should now have exited runtime LPM. */ - zassert_false(sm5803_emul_is_clock_slowed(SM5803_EMUL)); - sm5803_emul_get_gpadc_conf(SM5803_EMUL, &gpadc1, &gpadc2); - /* All except IBAT_DISCHG enabled. */ - zassert_equal(gpadc1, 0xf7, "actual value was %#x", gpadc1); - /* Default value. */ - zassert_equal(gpadc2, 1, "actual value was %#x", gpadc2); - /* Sigma-delta for Coulomb Counter is enabled. */ - cc_conf1 = sm5803_emul_get_cc_config(SM5803_EMUL); - zassert_equal(cc_conf1, 0x09, "actual value was %#x", cc_conf1); - /* Charger is sinking. */ - sm5803_emul_get_flow_regs(SM5803_EMUL, &flow1, &flow2, &flow3); - zassert_equal(flow1, 0x01, "FLOW1 should be set for sinking, was %#x", - flow1); - - /* Disconnect source, causing charger to go to runtime LPM. */ - zassert_ok(tcpci_emul_disconnect_partner(tcpci_emul)); - sm5803_emul_set_vbus_voltage(SM5803_EMUL, 24); - k_sleep(K_SECONDS(4)); - - zassert_true(sm5803_emul_is_clock_slowed(SM5803_EMUL)); - /* Sigma delta was disabled. */ - cc_conf1 = sm5803_emul_get_cc_config(SM5803_EMUL); - zassert_equal(sm5803_emul_get_cc_config(SM5803_EMUL), 0x01, - "actual value was %#x", cc_conf1); - /* - * Runtime LPM hook runs before the charge manager updates, so we expect - * the GPADCs to be left on because the charger is still set for sinking - * when it goes to runtime LPM. - */ - sm5803_emul_get_gpadc_conf(SM5803_EMUL, &gpadc1, &gpadc2); - zassert_equal(gpadc1, 0xf7, "actual value was %#x", gpadc1); - zassert_equal(gpadc2, 1, "actual value was %#x", gpadc2); - - /* - * Reconnect the source and inhibit charging, so GPADCs can be disabled - * when we disconnect it. - */ - zassert_ok(tcpci_partner_connect_to_tcpci(&partner, tcpci_emul)); - sm5803_emul_set_vbus_voltage(SM5803_EMUL, 5010); - k_sleep(K_SECONDS(4)); - zassert_ok(charger_set_mode(CHARGE_FLAG_INHIBIT_CHARGE)); - zassert_ok(tcpci_emul_disconnect_partner(tcpci_emul)); - sm5803_emul_set_vbus_voltage(SM5803_EMUL, 0); - k_sleep(K_SECONDS(4)); - - /* This time LPM actually did disable the GPADCs. */ - sm5803_emul_get_gpadc_conf(SM5803_EMUL, &gpadc1, &gpadc2); - zassert_equal(gpadc1, 0, "actual value was %#x", gpadc1); - zassert_equal(gpadc2, 0, "actual value was %#x", gpadc2); -} - -ZTEST(sm5803, test_get_battery_cells) -{ - int cells; - - /* Default PMODE reports 2s */ - zassert_ok(sm5803_drv.get_battery_cells(CHARGER_NUM, &cells)); - zassert_equal(cells, 2); - - /* 3s PMODE is 3s */ - sm5803_emul_set_pmode(SM5803_EMUL, 0x14); - zassert_ok(sm5803_drv.get_battery_cells(CHARGER_NUM, &cells)); - zassert_equal(cells, 3); - - /* Unrecognized PMODE is an error */ - sm5803_emul_set_pmode(SM5803_EMUL, 0x1f); - zassert_not_equal(sm5803_drv.get_battery_cells(CHARGER_NUM, &cells), 0); - zassert_equal(cells, -1); - - /* Communication error bubbles up */ - i2c_common_emul_set_read_fail_reg(sm5803_emul_get_i2c_main(SM5803_EMUL), - SM5803_REG_PLATFORM); - zassert_not_equal(sm5803_drv.get_battery_cells(CHARGER_NUM, &cells), 0); -} - -ZTEST(sm5803, test_gpio) -{ - /* Open drain output */ - zassert_ok(sm5803_configure_gpio0(CHARGER_NUM, GPIO0_MODE_OUTPUT, 1)); - zassert_equal(sm5803_emul_get_gpio_ctrl(SM5803_EMUL), 0x42); - /* Set output high, from default of low. */ - zassert_ok(sm5803_set_gpio0_level(CHARGER_NUM, 1)); - zassert_equal(sm5803_emul_get_gpio_ctrl(SM5803_EMUL), 0x43); - /* Set it low again. */ - zassert_ok(sm5803_set_gpio0_level(CHARGER_NUM, 0)); - zassert_equal(sm5803_emul_get_gpio_ctrl(SM5803_EMUL), 0x42); - - /* Push-pull prochot. */ - zassert_ok(sm5803_configure_gpio0(CHARGER_NUM, GPIO0_MODE_PROCHOT, 0)); - zassert_equal(sm5803_emul_get_gpio_ctrl(SM5803_EMUL), 0x00); - - /* CHG_DET output enable lives in this register too */ - zassert_ok(sm5803_configure_chg_det_od(CHARGER_NUM, 1)); - zassert_equal(sm5803_emul_get_gpio_ctrl(SM5803_EMUL), 0x80); - zassert_ok(sm5803_configure_chg_det_od(CHARGER_NUM, 0)); - zassert_equal(sm5803_emul_get_gpio_ctrl(SM5803_EMUL), 0x00); - - /* Communication errors bubble up */ - i2c_common_emul_set_read_fail_reg(sm5803_emul_get_i2c_main(SM5803_EMUL), - SM5803_REG_GPIO0_CTRL); - zassert_not_equal( - sm5803_configure_gpio0(CHARGER_NUM, GPIO0_MODE_INPUT, 0), 0); - zassert_not_equal(sm5803_set_gpio0_level(CHARGER_NUM, 0), 0); - zassert_not_equal(sm5803_configure_chg_det_od(CHARGER_NUM, 1), 0); -} diff --git a/zephyr/test/drivers/sm5803/src/usbc.c b/zephyr/test/drivers/sm5803/src/usbc.c deleted file mode 100644 index 8028842a04..0000000000 --- a/zephyr/test/drivers/sm5803/src/usbc.c +++ /dev/null @@ -1,42 +0,0 @@ -/* Copyright 2023 The ChromiumOS Authors - * Use of this source code is governed by a BSD-style license that can be - * found in the LICENSE file. - */ -#include "driver/charger/sm5803.h" -#include "driver/tcpm/tcpci.h" -#include "emul/emul_sm5803.h" -#include "test/drivers/charger_utils.h" - -#include <zephyr/drivers/emul.h> -#include <zephyr/drivers/gpio/gpio_emul.h> - -__override bool pd_check_vbus_level(int port, enum vbus_level level) -{ - return sm5803_check_vbus_level(port, level); -} - -static void pin_interrupt_handler(const struct device *gpio, - struct gpio_callback *const cb, - gpio_port_pins_t pins) -{ - sm5803_interrupt(get_charger_num(&sm5803_drv)); -} - -static int configure_charger_interrupt(void) -{ - const struct gpio_dt_spec *gpio = sm5803_emul_get_interrupt_gpio( - EMUL_DT_GET(DT_NODELABEL(sm5803_emul))); - static struct gpio_callback callback; - - if (!device_is_ready(gpio->port)) - k_oops(); - - gpio_emul_input_set(gpio->port, gpio->pin, 1); - gpio_pin_configure_dt(gpio, GPIO_INPUT | GPIO_ACTIVE_LOW); - gpio_init_callback(&callback, pin_interrupt_handler, BIT(gpio->pin)); - gpio_add_callback(gpio->port, &callback); - gpio_pin_interrupt_configure_dt(gpio, GPIO_INT_EDGE_TO_ACTIVE); - - return 0; -} -SYS_INIT(configure_charger_interrupt, APPLICATION, 10); diff --git a/zephyr/test/drivers/testcase.yaml b/zephyr/test/drivers/testcase.yaml index cb63d66fc8..fb8d9b8fdc 100644 --- a/zephyr/test/drivers/testcase.yaml +++ b/zephyr/test/drivers/testcase.yaml @@ -338,15 +338,6 @@ tests: - CONFIG_PLATFORM_EC_RTC=y - CONFIG_PLATFORM_EC_HOSTCMD=y - CONFIG_PLATFORM_EC_HOSTCMD_RTC=y - drivers.sm5803: - extra_conf_files: - - prj.conf - - sm5803/prj.conf - extra_configs: - - CONFIG_LINK_TEST_SUITE_SM5803=y - extra_dtc_overlay_files: - - boards/native_posix.overlay - - sm5803/sm5803.dts drivers.system: tags: common system extra_configs: |