/*
 * Copyright 2024 Google LLC
 *
 * SPDX-License-Identifier: Apache-2.0
 *
 * BQ25180 Datasheet: https://www.ti.com/lit/gpn/bq25180
 */

#define DT_DRV_COMPAT ti_bq25180

#include <zephyr/device.h>
#include <zephyr/drivers/charger.h>
#include <zephyr/drivers/i2c.h>
#include <zephyr/kernel.h>
#include <zephyr/logging/log.h>
#include <zephyr/sys/util.h>

LOG_MODULE_REGISTER(bq25180, CONFIG_CHARGER_LOG_LEVEL);

#define BQ25180_STAT0 0x00
#define BQ25180_STAT1 0x01
#define BQ25180_FLAG0 0x02
#define BQ25180_VBAT_CTRL 0x03
#define BQ25180_ICHG_CTRL 0x04
#define BQ25180_IC_CTRL 0x07
#define BQ25180_SHIP_RST 0x09
#define BQ25180_MASK_ID 0x0c

#define BQ25180_STAT0_CHG_STAT_MASK GENMASK(6, 5)
#define BQ25180_STAT0_CHG_STAT_NOT_CHARGING 0x00
#define BQ25180_STAT0_CHG_STAT_CONSTANT_CURRENT 0x01
#define BQ25180_STAT0_CHG_STAT_CONSTANT_VOLTAGE 0x02
#define BQ25180_STAT0_CHG_STAT_DONE 0x03
#define BQ25180_STAT0_VIN_PGOOD_STAT BIT(0)
#define BQ25180_VBAT_MSK                        GENMASK(6, 0)
#define BQ25180_ICHG_CHG_DIS BIT(7)
#define BQ25180_ICHG_MSK GENMASK(6, 0)
#define BQ25180_IC_CTRL_VRCH_100                0x00
#define BQ25180_IC_CTRL_VRCH_200                BIT(5)
#define BQ25180_IC_CTRL_VRCH_MSK                BIT(5)
#define BQ25180_VLOWV_SEL_2_8                   BIT(6)
#define BQ25180_VLOWV_SEL_3_0                   0x00
#define BQ25180_VLOWV_SEL_MSK                   BIT(6)
#define BQ25180_WATCHDOG_SEL_1_MSK GENMASK(1, 0)
#define BQ25180_WATCHDOG_DISABLE 0x03
#define BQ25180_DEVICE_ID_MSK GENMASK(3, 0)
#define BQ25180_DEVICE_ID 0x00
#define BQ25180_SHIP_RST_EN_RST_SHIP_MSK GENMASK(6, 5)
#define BQ25180_SHIP_RST_EN_RST_SHIP_ADAPTER 0x20
#define BQ25180_SHIP_RST_EN_RST_SHIP_BUTTON 0x40

/* Charging current limits */
#define BQ25180_CURRENT_MIN_MA 5
#define BQ25180_CURRENT_MAX_MA 1000
#define BQ25180_VOLTAGE_MIN_MV 3500
#define BQ25180_VOLTAGE_MAX_MV 4650

#define BQ25180_FACTOR_VBAT_TO_MV 10

struct bq25180_config {
	struct i2c_dt_spec i2c;
	uint32_t initial_current_microamp;
	uint32_t max_voltage_microvolt;
	uint32_t recharge_voltage_microvolt;
	uint32_t precharge_threshold_voltage_microvolt;
};

/*
 * For ICHG <= 35mA = ICHGCODE + 5mA
 * For ICHG > 35mA = 40 + ((ICHGCODE-31)*10)mA.
 * Maximum programmable current = 1000mA
 *
 * Return: value between 0 and 127, negative on error.
 */
static int bq25180_ma_to_ichg(uint32_t current_ma, uint8_t *ichg)
{
	if (!IN_RANGE(current_ma, BQ25180_CURRENT_MIN_MA, BQ25180_CURRENT_MAX_MA)) {
		LOG_WRN("charging current out of range: %dmA, "
			"clamping to the nearest limit", current_ma);
	}
	current_ma = CLAMP(current_ma, BQ25180_CURRENT_MIN_MA, BQ25180_CURRENT_MAX_MA);

	if (current_ma <= 35) {
		*ichg = current_ma - 5;
		return 0;
	}

	*ichg = (current_ma - 40) / 10 + 31;

	return 0;
}

static uint32_t bq25180_ichg_to_ma(uint8_t ichg)
{
	ichg &= BQ25180_ICHG_MSK;

	if (ichg <= 30) {
		return (ichg + 5);
	}

	return (ichg - 31) * 10 + 40;
}

static int bq25180_mv_to_vbatreg(const struct bq25180_config *cfg, uint32_t voltage_mv,
				 uint8_t *vbat)
{
	if (!IN_RANGE(voltage_mv, BQ25180_VOLTAGE_MIN_MV, cfg->max_voltage_microvolt)) {
		LOG_WRN("charging voltage out of range: %dmV, "
			"clamping to the nearest limit",
			voltage_mv);
	}
	voltage_mv = CLAMP(voltage_mv, BQ25180_VOLTAGE_MIN_MV, cfg->max_voltage_microvolt);

	*vbat = (voltage_mv - BQ25180_VOLTAGE_MIN_MV) / BQ25180_FACTOR_VBAT_TO_MV;

	return 0;
}

static uint32_t bq25180_vbatreg_to_mv(uint8_t vbat)
{
	vbat &= BQ25180_VBAT_MSK;

	return (vbat * BQ25180_FACTOR_VBAT_TO_MV) + BQ25180_VOLTAGE_MIN_MV;
}

static int bq25183_charge_enable(const struct device *dev, const bool enable)
{
	const struct bq25180_config *cfg = dev->config;
	uint8_t value = enable ? 0 : BQ25180_ICHG_CHG_DIS;
	int ret;

	ret = i2c_reg_update_byte_dt(&cfg->i2c, BQ25180_ICHG_CTRL,
				     BQ25180_ICHG_CHG_DIS, value);
	if (ret < 0) {
		return ret;
	}

	return 0;
}

static int bq25180_set_charge_current(const struct device *dev,
				      uint32_t const_charge_current_ua)
{
	const struct bq25180_config *cfg = dev->config;
	uint8_t val;
	int ret;

	ret = bq25180_ma_to_ichg(const_charge_current_ua / 1000, &val);
	if (ret < 0) {
		return ret;
	}

	ret = i2c_reg_update_byte_dt(&cfg->i2c, BQ25180_ICHG_CTRL,
				     BQ25180_ICHG_MSK, val);
	if (ret < 0) {
		return ret;
	}

	return 0;
}

static int bq25180_get_charge_current(const struct device *dev,
				      uint32_t *const_charge_current_ua)
{
	const struct bq25180_config *cfg = dev->config;
	uint8_t val;
	int ret;

	ret = i2c_reg_read_byte_dt(&cfg->i2c, BQ25180_ICHG_CTRL, &val);
	if (ret < 0) {
		return ret;
	}

	*const_charge_current_ua = bq25180_ichg_to_ma(val) * 1000;

	return 0;
}

static int bq25180_set_charge_voltage(const struct device *dev, uint32_t const_charge_voltage_uv)
{
	const struct bq25180_config *cfg = dev->config;
	uint8_t val;
	int ret;

	ret = bq25180_mv_to_vbatreg(cfg, const_charge_voltage_uv / 1000, &val);
	if (ret < 0) {
		return ret;
	}

	ret = i2c_reg_update_byte_dt(&cfg->i2c, BQ25180_VBAT_CTRL, BQ25180_VBAT_MSK, val);
	if (ret < 0) {
		return ret;
	}

	return 0;
}

static int bq25180_get_charge_voltage(const struct device *dev, uint32_t *const_charge_voltage_uv)
{
	const struct bq25180_config *cfg = dev->config;
	uint8_t val;
	int ret;

	ret = i2c_reg_read_byte_dt(&cfg->i2c, BQ25180_VBAT_CTRL, &val);
	if (ret < 0) {
		return ret;
	}

	*const_charge_voltage_uv = bq25180_vbatreg_to_mv(val) * 1000;

	return 0;
}

static int bq25180_get_online(const struct device *dev,
			      enum charger_online *online)
{
	const struct bq25180_config *cfg = dev->config;
	uint8_t val;
	int ret;

	ret = i2c_reg_read_byte_dt(&cfg->i2c, BQ25180_STAT0, &val);
	if (ret < 0) {
		return ret;
	}

	if ((val & BQ25180_STAT0_VIN_PGOOD_STAT) != 0x00) {
		*online = CHARGER_ONLINE_FIXED;
	} else {
		*online = CHARGER_ONLINE_OFFLINE;
	}

	return 0;
}

static int bq25180_get_status(const struct device *dev,
			      enum charger_status *status)
{
	const struct bq25180_config *cfg = dev->config;
	uint8_t stat0;
	uint8_t ichg_ctrl;
	int ret;

	ret = i2c_reg_read_byte_dt(&cfg->i2c, BQ25180_STAT0, &stat0);
	if (ret < 0) {
		return ret;
	}

	if ((stat0 & BQ25180_STAT0_VIN_PGOOD_STAT) == 0x00) {
		*status = CHARGER_STATUS_DISCHARGING;
		return 0;
	}

	ret = i2c_reg_read_byte_dt(&cfg->i2c, BQ25180_ICHG_CTRL, &ichg_ctrl);
	if (ret < 0) {
		return ret;
	}

	if ((ichg_ctrl & BQ25180_ICHG_CHG_DIS) != 0x00) {
		*status = CHARGER_STATUS_NOT_CHARGING;
		return 0;
	}

	switch (FIELD_GET(BQ25180_STAT0_CHG_STAT_MASK, stat0)) {
	case BQ25180_STAT0_CHG_STAT_NOT_CHARGING:
		*status = CHARGER_STATUS_NOT_CHARGING;
		break;
	case BQ25180_STAT0_CHG_STAT_CONSTANT_CURRENT:
	case BQ25180_STAT0_CHG_STAT_CONSTANT_VOLTAGE:
		*status = CHARGER_STATUS_CHARGING;
		break;
	case BQ25180_STAT0_CHG_STAT_DONE:
		*status = CHARGER_STATUS_FULL;
		break;
	}

	return 0;
}

static int bq25180_get_prop(const struct device *dev, charger_prop_t prop,
			    union charger_propval *val)
{
	switch (prop) {
	case CHARGER_PROP_ONLINE:
		return bq25180_get_online(dev, &val->online);
	case CHARGER_PROP_STATUS:
		return bq25180_get_status(dev, &val->status);
	case CHARGER_PROP_CONSTANT_CHARGE_CURRENT_UA:
		return bq25180_get_charge_current(dev, &val->const_charge_current_ua);
	case CHARGER_PROP_CONSTANT_CHARGE_VOLTAGE_UV:
		return bq25180_get_charge_voltage(dev, &val->const_charge_voltage_uv);
	default:
		return -ENOTSUP;
	}
}

static int bq25180_set_prop(const struct device *dev, charger_prop_t prop,
			    const union charger_propval *val)
{
	switch (prop) {
	case CHARGER_PROP_CONSTANT_CHARGE_CURRENT_UA:
		return bq25180_set_charge_current(dev, val->const_charge_current_ua);
	case CHARGER_PROP_CONSTANT_CHARGE_VOLTAGE_UV:
		return bq25180_set_charge_voltage(dev, val->const_charge_voltage_uv);
	default:
		return -ENOTSUP;
	}
}

static const struct charger_driver_api bq25180_api = {
	.get_property = bq25180_get_prop,
	.set_property = bq25180_set_prop,
	.charge_enable = bq25183_charge_enable,
};

static int bq25180_init(const struct device *dev)
{
	const struct bq25180_config *cfg = dev->config;
	uint8_t val;
	int ret;

	ret = i2c_reg_read_byte_dt(&cfg->i2c, BQ25180_MASK_ID, &val);
	if (ret < 0) {
		return ret;
	}

	val &= BQ25180_DEVICE_ID_MSK;
	if (val != BQ25180_DEVICE_ID) {
		LOG_ERR("Invalid device id: %02x", val);
		return -EINVAL;
	}

	/* Disable the watchdog */
	ret = i2c_reg_update_byte_dt(&cfg->i2c, BQ25180_IC_CTRL,
				     BQ25180_WATCHDOG_SEL_1_MSK,
				     BQ25180_WATCHDOG_DISABLE);
	if (ret < 0) {
		return ret;
	}

	ret = bq25180_set_charge_voltage(dev, cfg->max_voltage_microvolt);
	if (ret < 0) {
		LOG_ERR("Could not set the target voltage. (rc: %d)", ret);
		return ret;
	}

	if (cfg->recharge_voltage_microvolt > 0) {
		if ((cfg->max_voltage_microvolt - cfg->recharge_voltage_microvolt) > 100000) {
			val = BQ25180_IC_CTRL_VRCH_200;
		} else {
			val = BQ25180_IC_CTRL_VRCH_100;
		}

		ret = i2c_reg_update_byte_dt(&cfg->i2c, BQ25180_IC_CTRL, BQ25180_IC_CTRL_VRCH_MSK,
					     val);
		if (ret < 0) {
			return ret;
		}
	}

	/* Precharge threshold voltage */
	if (cfg->precharge_threshold_voltage_microvolt <= 2800000) {
		val = BQ25180_VLOWV_SEL_2_8;
	} else {
		val = BQ25180_VLOWV_SEL_3_0;
	}

	ret = i2c_reg_update_byte_dt(&cfg->i2c, BQ25180_IC_CTRL, BQ25180_VLOWV_SEL_MSK, val);
	if (ret < 0) {
		return ret;
	}

	if (cfg->initial_current_microamp > 0) {
		ret = bq25180_set_charge_current(dev, cfg->initial_current_microamp);
		if (ret < 0) {
			return ret;
		}
	}

	return 0;
}

#define CHARGER_BQ25180_INIT(inst)                                                                 \
	static const struct bq25180_config bq25180_config_##inst = {                               \
		.i2c = I2C_DT_SPEC_INST_GET(inst),                                                 \
		.initial_current_microamp =                                                        \
			DT_INST_PROP(inst, constant_charge_current_max_microamp),                  \
		.max_voltage_microvolt =                                                           \
			DT_INST_PROP(inst, constant_charge_voltage_max_microvolt),                 \
		.recharge_voltage_microvolt =                                                      \
			DT_INST_PROP_OR(inst, re_charge_voltage_microvolt, 0),                     \
		.precharge_threshold_voltage_microvolt =                                           \
			DT_INST_PROP(inst, precharge_voltage_threshold_microvolt),                 \
	};                                                                                         \
                                                                                                   \
	DEVICE_DT_INST_DEFINE(inst, bq25180_init, NULL, NULL, &bq25180_config_##inst, POST_KERNEL, \
			      CONFIG_CHARGER_INIT_PRIORITY, &bq25180_api);

DT_INST_FOREACH_STATUS_OKAY(CHARGER_BQ25180_INIT)
