diff options
author | Diana Z <dzigterman@chromium.org> | 2023-03-30 10:22:52 -0600 |
---|---|---|
committer | Chromeos LUCI <chromeos-scoped@luci-project-accounts.iam.gserviceaccount.com> | 2023-03-31 22:05:47 +0000 |
commit | 05c272ecc43d85af2515cbc863eaf81503658924 (patch) | |
tree | 984577378b0df983ab69a64d85bb2a2c106c2e18 | |
parent | 9ba8369296711de6e470265a04b2b4c083908b9d (diff) | |
download | chrome-ec-05c272ecc43d85af2515cbc863eaf81503658924.tar.gz |
Zephyr test: Add ISL9241 emulator
Add an emulator for the ISL9241 charger chip.
BRANCH=None
BUG=b:273722902
TEST=builds
Change-Id: I1d8ea900188ca3868d09df7620d172403a94e926
Signed-off-by: Diana Z <dzigterman@chromium.org>
Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/platform/ec/+/4387136
Reviewed-by: Aaron Massey <aaronmassey@google.com>
Reviewed-by: Simon Glass <sjg@chromium.org>
-rw-r--r-- | zephyr/emul/CMakeLists.txt | 1 | ||||
-rw-r--r-- | zephyr/emul/Kconfig | 10 | ||||
-rw-r--r-- | zephyr/emul/emul_isl9241.c | 182 | ||||
-rw-r--r-- | zephyr/include/emul/emul_isl9241.h | 36 |
4 files changed, 229 insertions, 0 deletions
diff --git a/zephyr/emul/CMakeLists.txt b/zephyr/emul/CMakeLists.txt index 77a8de3213..b9025e97d8 100644 --- a/zephyr/emul/CMakeLists.txt +++ b/zephyr/emul/CMakeLists.txt @@ -18,6 +18,7 @@ zephyr_library_sources_ifdef(CONFIG_EMUL_CLOCK_CONTROL emul_clock_control.c) zephyr_library_sources_ifdef(CONFIG_EMUL_COMMON_I2C emul_common_i2c.c) zephyr_library_sources_ifdef(CONFIG_EMUL_CROS_FLASH emul_flash.c) zephyr_library_sources_ifdef(CONFIG_EMUL_ISL923X emul_isl923x.c) +zephyr_library_sources_ifdef(CONFIG_EMUL_CHARGER_ISL9241 emul_isl9241.c) zephyr_library_sources_ifdef(CONFIG_EMUL_KB_RAW emul_kb_raw.c) zephyr_library_sources_ifdef(CONFIG_EMUL_LIS2DW12 emul_lis2dw12.c) zephyr_library_sources_ifdef(CONFIG_EMUL_LN9310 emul_ln9310.c) diff --git a/zephyr/emul/Kconfig b/zephyr/emul/Kconfig index b7bfc88aa2..700e0c0eaf 100644 --- a/zephyr/emul/Kconfig +++ b/zephyr/emul/Kconfig @@ -49,6 +49,16 @@ config EMUL_BC12_DETECT_PI3USB9201 detector/advertiser. The emulator supports reading and writing the 4 I2C registers of the PI3USB9201 using the emulated I2C bus. +config EMUL_CHARGER_ISL9241 + bool "Renesas buck-boost battery charger emulator" + default y + depends on ZTEST && DT_HAS_INTERSIL_ISL9241_ENABLED + select EMUL_COMMON_I2C + help + Enable the ISL9241 emulator. This chip is a configurable buck-boost + battery charger which can communicate over I2C, and utilizes the + emulated I2C bus. + config EMUL_PPC_SYV682X bool "Silergy SYV682x PPC emulator" default y diff --git a/zephyr/emul/emul_isl9241.c b/zephyr/emul/emul_isl9241.c new file mode 100644 index 0000000000..2b41230e5b --- /dev/null +++ b/zephyr/emul/emul_isl9241.c @@ -0,0 +1,182 @@ +/* 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 "charger/chg_isl9241.h" +#include "driver/charger/isl9241.h" +#include "emul/emul_common_i2c.h" +#include "emul/emul_stub_device.h" +#include "util.h" + +#include <zephyr/device.h> +#include <zephyr/logging/log.h> +#include <zephyr/ztest.h> + +#define DT_DRV_COMPAT ISL9241_CHG_COMPAT + +#define LOG_LEVEL CONFIG_I2C_LOG_LEVEL +LOG_MODULE_REGISTER(emul_isl9241); + +/* Device ID sits at the end of the register space (0xFF) */ +#define ISL9241_MAX_REG ISL9241_REG_DEVICE_ID + +struct isl9241_emul_data { + struct i2c_common_emul_data common; + uint16_t regs[ISL9241_MAX_REG + 1]; +}; + +/* Note: registers are all 2 bytes */ +struct isl9241_reg_default { + uint8_t offset; + uint16_t val; +}; + +/* Chip defaults for non-zero registers (spec Rev 5.0, Table 1) */ +struct isl9241_reg_default isl9241_defaults[] = { + /* Note: 3s default here */ + { .offset = ISL9241_REG_MAX_SYSTEM_VOLTAGE, .val = 0x3120 }, + { .offset = ISL9241_REG_ADAPTER_CUR_LIMIT2, .val = 0x05DC }, + { .offset = ISL9241_REG_CONTROL1, .val = 0x0103 }, + { .offset = ISL9241_REG_CONTROL2, .val = 0x6000 }, + { .offset = ISL9241_REG_ADAPTER_CUR_LIMIT1, .val = 0x05DC }, + { .offset = ISL9241_REG_CONTROL6, .val = 0x1FFF }, + { .offset = ISL9241_REG_AC_PROCHOT, .val = 0x0C00 }, + { .offset = ISL9241_REG_DC_PROCHOT, .val = 0x1000 }, + { .offset = ISL9241_REG_OTG_VOLTAGE, .val = 0x0D08 }, + { .offset = ISL9241_REG_OTG_CURRENT, .val = 0x0200 }, + { .offset = ISL9241_REG_VIN_VOLTAGE, .val = 0x0C00 }, + { .offset = ISL9241_REG_CONTROL3, .val = 0x0300 }, + { .offset = ISL9241_REG_MANUFACTURER_ID, .val = 0x0049 }, + { .offset = ISL9241_REG_DEVICE_ID, .val = 0x000E }, +}; + +void isl9241_emul_reset_regs(const struct emul *emul) +{ + struct isl9241_emul_data *data = (struct isl9241_emul_data *)emul->data; + + memset(data->regs, 0, sizeof(data->regs)); + + for (int i = 0; i < ARRAY_SIZE(isl9241_defaults); i++) { + struct isl9241_reg_default def = isl9241_defaults[i]; + + data->regs[def.offset] = def.val; + } +} + +uint16_t isl9241_emul_peek(const struct emul *emul, int reg) +{ + __ASSERT_NO_MSG(IN_RANGE(reg, 0, ISL9241_MAX_REG)); + + struct isl9241_emul_data *data = (struct isl9241_emul_data *)emul->data; + + return data->regs[reg]; +} + +void isl9241_emul_set_vbus(const struct emul *emul, int vbus_mv) +{ + struct isl9241_emul_data *data = (struct isl9241_emul_data *)emul->data; + uint16_t adc_reg; + + if (vbus_mv > 0) + data->regs[ISL9241_REG_INFORMATION2] |= + ISL9241_INFORMATION2_ACOK_PIN; + else + data->regs[ISL9241_REG_INFORMATION2] &= + ~ISL9241_INFORMATION2_ACOK_PIN; + + adc_reg = vbus_mv / ISL9241_VIN_ADC_STEP_MV; + adc_reg <<= ISL9241_VIN_ADC_BIT_OFFSET; + data->regs[ISL9241_REG_VIN_ADC_RESULTS] = adc_reg; +} + +void isl9241_emul_set_vsys(const struct emul *emul, int vsys_mv) +{ + struct isl9241_emul_data *data = (struct isl9241_emul_data *)emul->data; + uint16_t adc_reg; + + adc_reg = vsys_mv / ISL9241_VIN_ADC_STEP_MV; + adc_reg <<= ISL9241_VIN_ADC_BIT_OFFSET; + data->regs[ISL9241_REG_VSYS_ADC_RESULTS] = adc_reg; +} + +static int isl9241_emul_read(const struct emul *emul, int reg, uint8_t *val, + int bytes, void *unused_data) +{ + struct isl9241_emul_data *data = (struct isl9241_emul_data *)emul->data; + + if (!IN_RANGE(reg, 0, ISL9241_MAX_REG)) + return -EINVAL; + + if (!IN_RANGE(bytes, 0, 1)) + return -EINVAL; + + if (bytes == 0) + *val = (uint8_t)(data->regs[reg] & 0xFF); + else + *val = (uint8_t)((data->regs[reg] >> 8) & 0xFF); + + return 0; +} + +static int isl9241_emul_write(const struct emul *emul, int reg, uint8_t val, + int bytes, void *unused_data) +{ + struct isl9241_emul_data *data = (struct isl9241_emul_data *)emul->data; + + if (!IN_RANGE(reg, 0, ISL9241_MAX_REG)) + return -EINVAL; + + if (!IN_RANGE(bytes, 1, 2)) + return -EINVAL; + + if (bytes == 1) + data->regs[reg] = val & 0xFF; + else + data->regs[reg] |= val << 8; + + return 0; +} + +static int isl9241_emul_init(const struct emul *emul, + const struct device *parent) +{ + struct isl9241_emul_data *data = (struct isl9241_emul_data *)emul->data; + struct i2c_common_emul_data *common_data = &data->common; + + i2c_common_emul_init(common_data); + i2c_common_emul_set_read_func(common_data, isl9241_emul_read, NULL); + i2c_common_emul_set_write_func(common_data, isl9241_emul_write, NULL); + + isl9241_emul_reset_regs(emul); + + return 0; +} + +#define INIT_ISL9241_EMUL(n) \ + static struct i2c_common_emul_cfg common_cfg_##n; \ + static struct isl9241_emul_data isl9241_emul_data_##n; \ + static struct i2c_common_emul_cfg common_cfg_##n = { \ + .dev_label = DT_NODE_FULL_NAME(DT_DRV_INST(n)), \ + .data = &isl9241_emul_data_##n.common, \ + .addr = DT_INST_REG_ADDR(n) \ + }; \ + EMUL_DT_INST_DEFINE(n, isl9241_emul_init, &isl9241_emul_data_##n, \ + &common_cfg_##n, &i2c_common_emul_api, NULL) + +DT_INST_FOREACH_STATUS_OKAY(INIT_ISL9241_EMUL) + +DT_INST_FOREACH_STATUS_OKAY(EMUL_STUB_DEVICE); + +static void isl9241_emul_reset_rule_before(const struct ztest_unit_test *test, + void *data) +{ + ARG_UNUSED(test); + ARG_UNUSED(data); + +#define ISL9241_EMUL_RESET_RULE_BEFORE(n) \ + isl9241_emul_reset_regs(EMUL_DT_GET(DT_DRV_INST(n))) + + DT_INST_FOREACH_STATUS_OKAY(ISL9241_EMUL_RESET_RULE_BEFORE); +} +ZTEST_RULE(isl9241_emul_reset, isl9241_emul_reset_rule_before, NULL); diff --git a/zephyr/include/emul/emul_isl9241.h b/zephyr/include/emul/emul_isl9241.h new file mode 100644 index 0000000000..2838687731 --- /dev/null +++ b/zephyr/include/emul/emul_isl9241.h @@ -0,0 +1,36 @@ +/* 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. + */ + +#ifndef EMUL_ISL9241_H +#define EMUL_ISL9241_H + +#include <zephyr/drivers/emul.h> + +/** + * Peek an internal register value + * + * @param emul - ISL9241 emulator data + * @param reg - which register to peek + * @return register contents + */ +uint16_t isl9241_emul_peek(const struct emul *emul, int reg); + +/** + * Fake a Vbus voltage presence + * + * @param emul - ISL9241 emulator data + * @param vbus_mv - desired Vbus mV to set + */ +void isl9241_emul_set_vbus(const struct emul *emul, int vbus_mv); + +/** + * Fake a specific Vsys voltage + * + * @param emul - ISL9241 emulator data + * @param vsys_mv - desired Vsys mV to set + */ +void isl9241_emul_set_vsys(const struct emul *emul, int vsys_mv); + +#endif |