diff options
-rw-r--r-- | zephyr/dts/bindings/emul/cros,ln9310-emul.yaml | 13 | ||||
-rw-r--r-- | zephyr/emul/CMakeLists.txt | 1 | ||||
-rw-r--r-- | zephyr/emul/Kconfig | 2 | ||||
-rw-r--r-- | zephyr/emul/Kconfig.ln9310 | 22 | ||||
-rw-r--r-- | zephyr/emul/emul_common_i2c.c | 2 | ||||
-rw-r--r-- | zephyr/emul/emul_ln9310.c | 370 | ||||
-rw-r--r-- | zephyr/include/emul/emul_ln9310.h | 63 |
7 files changed, 472 insertions, 1 deletions
diff --git a/zephyr/dts/bindings/emul/cros,ln9310-emul.yaml b/zephyr/dts/bindings/emul/cros,ln9310-emul.yaml new file mode 100644 index 0000000000..811f77206f --- /dev/null +++ b/zephyr/dts/bindings/emul/cros,ln9310-emul.yaml @@ -0,0 +1,13 @@ +# Copyright 2021 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. + +description: Cros LN9310 Emulator + +compatible: "cros,ln9310-emul" + +include: base.yaml + +properties: + reg: + required: true diff --git a/zephyr/emul/CMakeLists.txt b/zephyr/emul/CMakeLists.txt index f1e38ee078..3c81040440 100644 --- a/zephyr/emul/CMakeLists.txt +++ b/zephyr/emul/CMakeLists.txt @@ -12,3 +12,4 @@ zephyr_library_sources_ifdef(CONFIG_EMUL_BMI emul_bmi160.c) zephyr_library_sources_ifdef(CONFIG_EMUL_BMI emul_bmi260.c) zephyr_library_sources_ifdef(CONFIG_EMUL_TCS3400 emul_tcs3400.c) zephyr_library_sources_ifdef(CONFIG_EMUL_BB_RETIMER emul_bb_retimer.c) +zephyr_library_sources_ifdef(CONFIG_EMUL_LN9310 emul_ln9310.c) diff --git a/zephyr/emul/Kconfig b/zephyr/emul/Kconfig index 9686baf24e..f52c27349b 100644 --- a/zephyr/emul/Kconfig +++ b/zephyr/emul/Kconfig @@ -66,3 +66,5 @@ config EMUL_BB_RETIMER emulated I2C bus. It is used to test bb_retimer driver. It supports reads and writes to all emulator registers. Emulators API is available in zephyr/include/emul/emul_bb_retimer.h + +rsource "Kconfig.ln9310" diff --git a/zephyr/emul/Kconfig.ln9310 b/zephyr/emul/Kconfig.ln9310 new file mode 100644 index 0000000000..f0ab50b61b --- /dev/null +++ b/zephyr/emul/Kconfig.ln9310 @@ -0,0 +1,22 @@ +# Copyright 2021 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. + +DT_COMPAT_LN9310_EMUL := cros,ln9310-emul + +menuconfig EMUL_LN9310 + bool "LN9310 switchcap emulator" + default $(dt_compat_enabled,$(DT_COMPAT_LN9310_EMUL)) + depends on I2C_EMUL + help + Enable the LN9310 emulator. This driver uses the emulated I2C bus. It + is used to test the ln9310 driver. Emulator API is available in + zephyr/include/emul/emul_ln9310.h + +if EMUL_LN9310 + +module = LN9310_EMUL +module-str = ln9310_emul +source "subsys/logging/Kconfig.template.log_config" + +endif # EMUL_LN9310
\ No newline at end of file diff --git a/zephyr/emul/emul_common_i2c.c b/zephyr/emul/emul_common_i2c.c index 99f3b1ced8..bd811f1424 100644 --- a/zephyr/emul/emul_common_i2c.c +++ b/zephyr/emul/emul_common_i2c.c @@ -377,7 +377,7 @@ int i2c_common_emul_transfer(struct i2c_emul *emul, struct i2c_msg *msgs, } else { i = 0; } - /* Dispatch wrtie command */ + /* Dispatch write command */ for (; i < msgs->len; i++, data->msg_byte++) { ret = i2c_common_emul_write_byte(emul, data, msgs->buf[i]); diff --git a/zephyr/emul/emul_ln9310.c b/zephyr/emul/emul_ln9310.c new file mode 100644 index 0000000000..19e3fc7276 --- /dev/null +++ b/zephyr/emul/emul_ln9310.c @@ -0,0 +1,370 @@ +/* Copyright 2021 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. + */ + +#define DT_DRV_COMPAT cros_ln9310_emul + +#include <device.h> +#include <drivers/i2c.h> +#include <drivers/i2c_emul.h> +#include <emul.h> +#include <errno.h> +#include <sys/__assert.h> + +#include "driver/ln9310.h" +#include "emul/emul_common_i2c.h" +#include "i2c.h" + +#include <logging/log.h> +LOG_MODULE_REGISTER(ln9310_emul, CONFIG_LN9310_EMUL_LOG_LEVEL); + +#define LN9310_DATA_FROM_I2C_EMUL(_emul) \ + CONTAINER_OF(CONTAINER_OF(_emul, struct i2c_common_emul_data, emul), \ + struct ln9310_emul_data, common) + +struct ln9310_emul_data { + /** Common I2C data */ + struct i2c_common_emul_data common; + /** The current emulated battery cell type */ + enum battery_cell_type battery_cell_type; + /** Emulated Lion control register */ + uint8_t lion_ctrl_reg; + /** Emulated startup control register */ + uint8_t startup_ctrl_reg; + /** Emulated BC STST B register */ + uint8_t bc_sts_b_reg; + /** Emulated BC STST C register */ + uint8_t bc_sts_c_reg; + /** Emulated cfg 0 register */ + uint8_t cfg_0_reg; + /** Emulated cfg 4 register */ + uint8_t cfg_4_reg; + /** Emulated cfg 5 register */ + uint8_t cfg_5_reg; + /** Emulated power control register */ + uint8_t power_ctrl_reg; + /** Emulated timer control register */ + uint8_t timer_ctrl_reg; + /** Emulated lower bound (LB) control register */ + uint8_t lower_bound_ctrl_reg; + /** Emulated spare 0 register */ + uint8_t spare_0_reg; + /** Emulated swap control 0 register */ + uint8_t swap_ctrl_0_reg; + /** Emulated swap control 1 register */ + uint8_t swap_ctrl_1_reg; + /** Emulated swap control 2 register */ + uint8_t swap_ctrl_2_reg; + /** Emulated swap control 3 register */ + uint8_t swap_ctrl_3_reg; + /** Emulated track control register */ + uint8_t track_ctrl_reg; + /** Emulated mode change register */ + uint8_t mode_change_reg; + /** Emulated system control register */ + uint8_t sys_ctrl_reg; +}; + +static const struct emul *singleton; + +void ln9310_emul_set_context(const struct emul *emulator) +{ + singleton = emulator; +} + +void ln9310_emul_reset(const struct emul *emulator) +{ + struct ln9310_emul_data *data = emulator->data; + + data->lion_ctrl_reg = 0; + data->startup_ctrl_reg = 0; + data->bc_sts_b_reg = 0; + data->cfg_0_reg = 0; + data->cfg_4_reg = 0; + data->cfg_5_reg = 0; + data->power_ctrl_reg = 0; + data->timer_ctrl_reg = 0; + data->lower_bound_ctrl_reg = 0; + data->spare_0_reg = 0; + data->swap_ctrl_0_reg = 0; + data->swap_ctrl_1_reg = 0; + data->swap_ctrl_2_reg = 0; + data->swap_ctrl_3_reg = 0; + data->track_ctrl_reg = 0; + data->mode_change_reg = 0; + data->sys_ctrl_reg = 0; +} + +void ln9310_emul_set_battery_cell_type(const struct emul *emulator, + enum battery_cell_type type) +{ + struct ln9310_emul_data *data = emulator->data; + + data->battery_cell_type = type; +} + +void ln9310_emul_set_version(const struct emul *emulator, int version) +{ + struct ln9310_emul_data *data = emulator->data; + + data->bc_sts_c_reg |= version & LN9310_BC_STS_C_CHIP_REV_MASK; +} + +void ln9310_emul_set_vin_gt_10v(const struct emul *emulator, bool is_gt_10v) +{ + struct ln9310_emul_data *data = emulator->data; + + if (is_gt_10v) + data->bc_sts_b_reg |= LN9310_BC_STS_B_INFET_OUT_SWITCH_OK; + else + data->bc_sts_b_reg &= ~LN9310_BC_STS_B_INFET_OUT_SWITCH_OK; +} + +enum battery_cell_type board_get_battery_cell_type(void) +{ + struct ln9310_emul_data *data = singleton->data; + + return data->battery_cell_type; +} + +static struct i2c_emul_api ln9310_emul_api_i2c = { + .transfer = i2c_common_emul_transfer, +}; + +static int ln9310_emul_start_write(struct i2c_emul *emul, int reg) +{ + return 0; +} + +static int ln9310_emul_finish_write(struct i2c_emul *emul, int reg, int bytes) +{ + return 0; +} + +static int ln9310_emul_write_byte(struct i2c_emul *emul, int reg, uint8_t val, + int bytes) +{ + struct ln9310_emul_data *data = LN9310_DATA_FROM_I2C_EMUL(emul); + + switch (reg) { + case LN9310_REG_STARTUP_CTRL: + __ASSERT_NO_MSG(bytes == 1); + data->startup_ctrl_reg = val; + break; + case LN9310_REG_LION_CTRL: + __ASSERT_NO_MSG(bytes == 1); + data->lion_ctrl_reg = val; + break; + case LN9310_REG_BC_STS_B: + __ASSERT_NO_MSG(bytes == 1); + data->bc_sts_b_reg = val; + break; + case LN9310_REG_BC_STS_C: + LOG_ERR("Can't write to BC STS C register"); + return -EINVAL; + case LN9310_REG_CFG_0: + __ASSERT_NO_MSG(bytes == 1); + data->cfg_0_reg = val; + break; + case LN9310_REG_CFG_4: + __ASSERT_NO_MSG(bytes == 1); + data->cfg_4_reg = val; + break; + case LN9310_REG_CFG_5: + __ASSERT_NO_MSG(bytes == 1); + data->cfg_5_reg = val; + break; + case LN9310_REG_PWR_CTRL: + __ASSERT_NO_MSG(bytes == 1); + data->power_ctrl_reg = val; + break; + case LN9310_REG_TIMER_CTRL: + __ASSERT_NO_MSG(bytes == 1); + data->timer_ctrl_reg = val; + break; + case LN9310_REG_LB_CTRL: + __ASSERT_NO_MSG(bytes = 1); + data->lower_bound_ctrl_reg = val; + break; + case LN9310_REG_SPARE_0: + __ASSERT_NO_MSG(bytes == 1); + data->spare_0_reg = val; + break; + case LN9310_REG_SWAP_CTRL_0: + __ASSERT_NO_MSG(bytes == 1); + data->swap_ctrl_0_reg = val; + break; + case LN9310_REG_SWAP_CTRL_1: + __ASSERT_NO_MSG(bytes == 1); + data->swap_ctrl_1_reg = val; + break; + case LN9310_REG_SWAP_CTRL_2: + __ASSERT_NO_MSG(bytes == 1); + data->swap_ctrl_2_reg = val; + break; + case LN9310_REG_SWAP_CTRL_3: + __ASSERT_NO_MSG(bytes == 1); + data->swap_ctrl_3_reg = val; + break; + case LN9310_REG_TRACK_CTRL: + __ASSERT_NO_MSG(bytes == 1); + data->track_ctrl_reg = val; + break; + case LN9310_REG_MODE_CHANGE_CFG: + __ASSERT_NO_MSG(bytes == 1); + data->mode_change_reg = val; + break; + case LN9310_REG_SYS_CTRL: + __ASSERT_NO_MSG(bytes == 1); + data->sys_ctrl_reg = val; + break; + default: + return -EINVAL; + } + return 0; +} + +static int ln9310_emul_start_read(struct i2c_emul *emul, int reg) +{ + return 0; +} + +static int ln9310_emul_finish_read(struct i2c_emul *emul, int reg, int bytes) +{ + return 0; +} + +static int ln9310_emul_read_byte(struct i2c_emul *emul, int reg, uint8_t *val, + int bytes) +{ + struct ln9310_emul_data *data = LN9310_DATA_FROM_I2C_EMUL(emul); + + switch (reg) { + case LN9310_REG_STARTUP_CTRL: + __ASSERT_NO_MSG(bytes == 0); + *val = data->startup_ctrl_reg; + break; + case LN9310_REG_LION_CTRL: + __ASSERT_NO_MSG(bytes == 0); + *val = data->lion_ctrl_reg; + break; + case LN9310_REG_BC_STS_B: + __ASSERT_NO_MSG(bytes == 0); + *val = data->bc_sts_b_reg; + break; + case LN9310_REG_BC_STS_C: + __ASSERT_NO_MSG(bytes == 0); + *val = data->bc_sts_c_reg; + break; + case LN9310_REG_CFG_0: + __ASSERT_NO_MSG(bytes == 0); + *val = data->cfg_0_reg; + break; + case LN9310_REG_CFG_4: + __ASSERT_NO_MSG(bytes == 0); + *val = data->cfg_4_reg; + break; + case LN9310_REG_CFG_5: + __ASSERT_NO_MSG(bytes == 0); + *val = data->cfg_5_reg; + break; + case LN9310_REG_PWR_CTRL: + __ASSERT_NO_MSG(bytes == 0); + *val = data->power_ctrl_reg; + break; + case LN9310_REG_TIMER_CTRL: + __ASSERT_NO_MSG(bytes == 0); + *val = data->timer_ctrl_reg; + break; + case LN9310_REG_LB_CTRL: + __ASSERT_NO_MSG(bytes == 0); + *val = data->lower_bound_ctrl_reg; + break; + case LN9310_REG_SPARE_0: + __ASSERT_NO_MSG(bytes == 0); + *val = data->spare_0_reg; + break; + case LN9310_REG_SWAP_CTRL_0: + __ASSERT_NO_MSG(bytes == 0); + *val = data->swap_ctrl_0_reg; + break; + case LN9310_REG_SWAP_CTRL_1: + __ASSERT_NO_MSG(bytes == 0); + *val = data->swap_ctrl_1_reg; + break; + case LN9310_REG_SWAP_CTRL_2: + __ASSERT_NO_MSG(bytes == 0); + *val = data->swap_ctrl_2_reg; + break; + case LN9310_REG_SWAP_CTRL_3: + __ASSERT_NO_MSG(bytes == 0); + *val = data->swap_ctrl_3_reg; + break; + case LN9310_REG_TRACK_CTRL: + __ASSERT_NO_MSG(bytes == 0); + *val = data->track_ctrl_reg; + break; + case LN9310_REG_MODE_CHANGE_CFG: + __ASSERT_NO_MSG(bytes == 0); + *val = data->mode_change_reg; + break; + case LN9310_REG_SYS_CTRL: + __ASSERT_NO_MSG(bytes == 0); + *val = data->sys_ctrl_reg; + break; + default: + return -EINVAL; + } + return 0; +} + +static int ln9310_emul_access_reg(struct i2c_emul *emul, int reg, int bytes, + bool read) +{ + return 0; +} + +static int emul_ln9310_init(const struct emul *emul, + const struct device *parent) +{ + const struct i2c_common_emul_cfg *cfg = emul->cfg; + struct ln9310_emul_data *data = emul->data; + + data->common.emul.api = &ln9310_emul_api_i2c; + data->common.emul.addr = cfg->addr; + data->common.emul.parent = emul; + data->common.i2c = parent; + data->common.cfg = cfg; + i2c_common_emul_init(&data->common); + + singleton = emul; + + return i2c_emul_register(parent, emul->dev_label, &data->common.emul); +} + +#define INIT_LN9310(n) \ + const struct ln9310_config_t ln9310_config = { \ + .i2c_port = NAMED_I2C(power), \ + .i2c_addr_flags = DT_INST_REG_ADDR(n), \ + }; \ + static struct ln9310_emul_data ln9310_emul_data_##n = { \ + .common = { \ + .start_write = ln9310_emul_start_write, \ + .write_byte = ln9310_emul_write_byte, \ + .finish_write = ln9310_emul_finish_write, \ + .start_read = ln9310_emul_start_read, \ + .read_byte = ln9310_emul_read_byte, \ + .finish_read = ln9310_emul_finish_read, \ + .access_reg = ln9310_emul_access_reg, \ + }, \ + }; \ + static const struct i2c_common_emul_cfg ln9310_emul_cfg_##n = { \ + .i2c_label = DT_INST_BUS_LABEL(n), \ + .dev_label = DT_INST_LABEL(n), \ + .addr = DT_INST_REG_ADDR(n), \ + }; \ + EMUL_DEFINE(emul_ln9310_init, DT_DRV_INST(n), &ln9310_emul_cfg_##n, \ + &ln9310_emul_data_##n) + +DT_INST_FOREACH_STATUS_OKAY(INIT_LN9310) diff --git a/zephyr/include/emul/emul_ln9310.h b/zephyr/include/emul/emul_ln9310.h new file mode 100644 index 0000000000..8c9101dfab --- /dev/null +++ b/zephyr/include/emul/emul_ln9310.h @@ -0,0 +1,63 @@ +/* Copyright 2021 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. + */ + +/** + * @file + * + * @brief Backend API for LN9310 emulator + */ + +#ifndef ZEPHYR_INCLUDE_EMUL_EMUL_LN9310_H_ +#define ZEPHYR_INCLUDE_EMUL_EMUL_LN9310_H_ + +#include <emul.h> +#include "driver/ln9310.h" + +/** + * @brief Select the current emulator to use. + * + * Currently, only a single ln9310 can be instantiated at any given instance due + * to how the driver was written. Once this restriction is removed, there's + * still an issue with the board_get_battery_cell_type() function as it doesn't + * take a device pointer. This function selects the current LN9310 context which + * will serve the data for that board function. + * + * @param emulator The LN9310 emulator to select. + */ +void ln9310_emul_set_context(const struct emul *emulator); + +/** + * @brief Clear all the emulator data. + * + * @param emulator The LN9310 emulator to clear. + */ +void ln9310_emul_reset(const struct emul *emulator); + +/** + * @brief Update the emulator's battery cell type. + * + * @param emulator The LN9310 emulator to update. + * @param type The battery type to use. + */ +void ln9310_emul_set_battery_cell_type(const struct emul *emulator, + enum battery_cell_type type); + +/** + * @brief Update the emulator's version number. + * + * @param emulator The LN9310 emulator to update. + * @param version The LN9310 chip version number. + */ +void ln9310_emul_set_version(const struct emul *emulator, int version); + +/** + * @brief Update whether or not the LN9310 is currently getting more than 10V. + * + * @param emulator The LN9310 emulator to update. + * @param is_gt_10v Whether or not the chip is currently getting more than 10V. + */ +void ln9310_emul_set_vin_gt_10v(const struct emul *emulator, bool is_gt_10v); + +#endif /* ZEPHYR_INCLUDE_EMUL_EMUL_LN9310_H_ */ |