From 22fbd73fab83a6f4f012221d00d4d445b1c5096e Mon Sep 17 00:00:00 2001 From: Fabio Baltieri Date: Sat, 26 Aug 2023 17:13:24 +0100 Subject: [PATCH] sensor: max17055: fix v_empty setting Fix the whole v_empty setting code, this was using a wrong scaling factor, but also incorrectly clearing the recovery voltage part of the register. Change the code to read the previous value and mask out the bits not used by VE. Signed-off-by: Fabio Baltieri --- drivers/sensor/max17055/max17055.c | 34 ++++++++++++++++++++++++------ drivers/sensor/max17055/max17055.h | 1 + 2 files changed, 28 insertions(+), 7 deletions(-) diff --git a/drivers/sensor/max17055/max17055.c b/drivers/sensor/max17055/max17055.c index a50069643af..c2db8255623 100644 --- a/drivers/sensor/max17055/max17055.c +++ b/drivers/sensor/max17055/max17055.c @@ -112,14 +112,23 @@ static int capacity_to_max17055(unsigned int rsense_mohms, uint16_t val_mha) } /** - * @brief Convert voltage in millivolts to MAX17055 units + * @brief Update empty voltage target in v_empty * + * @param v_empty The register value to update * @param val_mv Value in millivolts to convert - * @return corresponding value in MAX17055 units, ready to write to a register + * @return 0 on success, -EINVAL on invalid val_mv */ -static int voltage_mV_to_max17055(uint16_t val_mv) +static int max17055_update_vempty(uint16_t *v_empty, uint16_t val_mv) { - return (val_mv * 16) * 10 / 8; /* * 1.25 */ + uint32_t val = (val_mv / 10) << 7; + + if (val & ~VEMPTY_VE) { + return -EINVAL; + } + + *v_empty = (*v_empty & ~VEMPTY_VE) | (uint16_t)val; + + return 0; } static void set_millis(struct sensor_value *val, int val_millis) @@ -338,27 +347,38 @@ static int max17055_write_config(const struct device *dev) uint16_t d_qacc = design_capacity / 32; uint16_t d_pacc = d_qacc * 44138 / design_capacity; uint16_t i_chg_term = current_ma_to_max17055(config->rsense_mohms, config->i_chg_term); - uint16_t v_empty = voltage_mV_to_max17055(config->v_empty); + uint16_t v_empty; LOG_DBG("Writing configuration parameters"); - LOG_DBG("DesignCap: %u, dQAcc: %u, IChgTerm: %u, VEmpty: %u, dPAcc: %u", - design_capacity, d_qacc, i_chg_term, v_empty, d_pacc); + LOG_DBG("DesignCap: %u, dQAcc: %u, IChgTerm: %u, dPAcc: %u", + design_capacity, d_qacc, i_chg_term, d_pacc); if (max17055_reg_write(dev, DESIGN_CAP, design_capacity)) { return -EIO; } + if (max17055_reg_write(dev, D_QACC, d_qacc)) { return -EIO; } + if (max17055_reg_write(dev, ICHG_TERM, i_chg_term)) { return -EIO; } + + if (max17055_reg_read(dev, V_EMPTY, &v_empty)) { + return -EIO; + } + if (max17055_update_vempty(&v_empty, config->v_empty)) { + return -EINVAL; + } if (max17055_reg_write(dev, V_EMPTY, v_empty)) { return -EIO; } + if (max17055_reg_write(dev, D_PACC, d_pacc)) { return -EIO; } + if (max17055_reg_write(dev, MODEL_CFG, MODELCFG_REFRESH)) { return -EIO; } diff --git a/drivers/sensor/max17055/max17055.h b/drivers/sensor/max17055/max17055.h index 476b8663ec5..38bf100f0d9 100644 --- a/drivers/sensor/max17055/max17055.h +++ b/drivers/sensor/max17055/max17055.h @@ -41,6 +41,7 @@ enum { SOFT_WAKEUP_CLEAR = 0x0000, SOFT_WAKEUP_WAKEUP = 0x0090, STATUS_POR = 0x0002, + VEMPTY_VE = 0xff80, }; struct max17055_data {