/*
 * Copyright 2023 Cirrus Logic, Inc.
 *
 * SPDX-License-Identifier: Apache-2.0
 */

#define DT_DRV_COMPAT ti_bq24190

#include <errno.h>

#include "bq24190.h"

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

LOG_MODULE_REGISTER(ti_bq24190);

struct bq24190_config {
	struct i2c_dt_spec i2c;
	struct gpio_dt_spec ce_gpio;
};

struct bq24190_data {
	uint8_t ss_reg;
	unsigned int ichg_ua;
	unsigned int vreg_uv;
	enum charger_status state;
	enum charger_online online;
};

static int bq24190_register_reset(const struct device *dev)
{
	const struct bq24190_config *const config = dev->config;
	int ret, limit = BQ24190_RESET_MAX_TRIES;
	uint8_t val;

	ret = i2c_reg_update_byte_dt(&config->i2c, BQ24190_REG_POC, BQ24190_REG_POC_RESET_MASK,
				     BQ24190_REG_POC_RESET_MASK);
	if (ret) {
		return ret;
	}

	/*
	 * No explicit reset timing characteristcs are provided in the datasheet.
	 * Instead, poll every 100µs for 100 attempts to see if the reset request
	 * bit has cleared.
	 */
	do {
		ret = i2c_reg_read_byte_dt(&config->i2c, BQ24190_REG_POC, &val);
		if (ret) {
			return ret;
		}

		if (!(val & BQ24190_REG_POC_RESET_MASK)) {
			return 0;
		}

		k_usleep(100);
	} while (--limit);

	return -EIO;
}

static int bq24190_charger_get_charge_type(const struct device *dev,
					   enum charger_charge_type *charge_type)
{
	const struct bq24190_config *const config = dev->config;
	uint8_t v;
	int ret;

	*charge_type = CHARGER_CHARGE_TYPE_UNKNOWN;

	ret = i2c_reg_read_byte_dt(&config->i2c, BQ24190_REG_POC, &v);
	if (ret) {
		return ret;
	}

	v = FIELD_GET(BQ24190_REG_POC_CHG_CONFIG_MASK, v);

	if (!v) {
		*charge_type = CHARGER_CHARGE_TYPE_NONE;
	} else {
		ret = i2c_reg_read_byte_dt(&config->i2c, BQ24190_REG_CCC, &v);
		if (ret) {
			return ret;
		}

		v = FIELD_GET(BQ24190_REG_CCC_FORCE_20PCT_MASK, v);

		if (v) {
			*charge_type = CHARGER_CHARGE_TYPE_TRICKLE;
		} else {
			*charge_type = CHARGER_CHARGE_TYPE_FAST;
		}
	}

	return 0;
}

static int bq24190_charger_get_health(const struct device *dev, enum charger_health *health)
{
	const struct bq24190_config *const config = dev->config;
	uint8_t v;
	int ret;

	ret = i2c_reg_read_byte_dt(&config->i2c, BQ24190_REG_F, &v);
	if (ret) {
		return ret;
	}

	if (v & BQ24190_REG_F_NTC_FAULT_MASK) {
		switch (v >> BQ24190_REG_F_NTC_FAULT_SHIFT & 0x7) {
		case BQ24190_NTC_FAULT_TS1_COLD:
		case BQ24190_NTC_FAULT_TS2_COLD:
		case BQ24190_NTC_FAULT_TS1_TS2_COLD:
			*health = CHARGER_HEALTH_COLD;
			break;
		case BQ24190_NTC_FAULT_TS1_HOT:
		case BQ24190_NTC_FAULT_TS2_HOT:
		case BQ24190_NTC_FAULT_TS1_TS2_HOT:
			*health = CHARGER_HEALTH_HOT;
			break;
		default:
			*health = CHARGER_HEALTH_UNKNOWN;
		}
	} else if (v & BQ24190_REG_F_BAT_FAULT_MASK) {
		*health = CHARGER_HEALTH_OVERVOLTAGE;
	} else if (v & BQ24190_REG_F_CHRG_FAULT_MASK) {
		switch (v >> BQ24190_REG_F_CHRG_FAULT_SHIFT & 0x3) {
		case BQ24190_CHRG_FAULT_INPUT_FAULT:
			/*
			 * This could be over-voltage or under-voltage
			 * and there's no way to tell which.  Instead
			 * of looking foolish and returning 'OVERVOLTAGE'
			 * when its really under-voltage, just return
			 * 'UNSPEC_FAILURE'.
			 */
			*health = CHARGER_HEALTH_UNSPEC_FAILURE;
			break;
		case BQ24190_CHRG_FAULT_TSHUT:
			*health = CHARGER_HEALTH_OVERHEAT;
			break;
		case BQ24190_CHRG_SAFETY_TIMER:
			*health = CHARGER_HEALTH_SAFETY_TIMER_EXPIRE;
			break;
		default: /* prevent compiler warning */
			*health = CHARGER_HEALTH_UNKNOWN;
		}
	} else if (v & BQ24190_REG_F_BOOST_FAULT_MASK) {
		/*
		 * This could be over-current or over-voltage but there's
		 * no way to tell which.  Return 'OVERVOLTAGE' since there
		 * isn't an 'OVERCURRENT' value defined that we can return
		 * even if it was over-current.
		 */
		*health = CHARGER_HEALTH_OVERVOLTAGE;
	} else {
		*health = CHARGER_HEALTH_GOOD;
	}

	return 0;
}

static int bq24190_charger_get_online(const struct device *dev, enum charger_online *online)
{
	const struct bq24190_config *const config = dev->config;
	uint8_t pg_stat, batfet_disable;
	int ret;

	ret = i2c_reg_read_byte_dt(&config->i2c, BQ24190_REG_SS, &pg_stat);
	if (ret) {
		return ret;
	}

	pg_stat = FIELD_GET(BQ24190_REG_SS_PG_STAT_MASK, pg_stat);

	ret = i2c_reg_read_byte_dt(&config->i2c, BQ24190_REG_MOC, &batfet_disable);
	if (ret) {
		return ret;
	}

	batfet_disable = FIELD_GET(BQ24190_REG_MOC_BATFET_DISABLE_MASK, batfet_disable);

	if (pg_stat && !batfet_disable) {
		*online = CHARGER_ONLINE_FIXED;
	} else {
		*online = CHARGER_ONLINE_OFFLINE;
	}

	return 0;
}

static int bq24190_charger_get_status(const struct device *dev, enum charger_status *status)
{
	const struct bq24190_config *const config = dev->config;
	uint8_t ss_reg, chrg_fault;
	int ret;

	ret = i2c_reg_read_byte_dt(&config->i2c, BQ24190_REG_F, &chrg_fault);
	if (ret) {
		return ret;
	}

	chrg_fault = FIELD_GET(BQ24190_REG_F_CHRG_FAULT_MASK, chrg_fault);

	ret = i2c_reg_read_byte_dt(&config->i2c, BQ24190_REG_SS, &ss_reg);
	if (ret) {
		return ret;
	}

	/*
	 * The battery must be discharging when any of these are true:
	 * - there is no good power source;
	 * - there is a charge fault.
	 * Could also be discharging when in "supplement mode" but
	 * there is no way to tell when its in that mode.
	 */
	if (!(ss_reg & BQ24190_REG_SS_PG_STAT_MASK) || chrg_fault) {
		*status = CHARGER_STATUS_DISCHARGING;
	} else {
		ss_reg = FIELD_GET(BQ24190_REG_SS_CHRG_STAT_MASK, ss_reg);

		switch (ss_reg) {
		case BQ24190_CHRG_STAT_NOT_CHRGING:
			*status = CHARGER_STATUS_NOT_CHARGING;
			break;
		case BQ24190_CHRG_STAT_PRECHRG:
		case BQ24190_CHRG_STAT_FAST_CHRG:
			*status = CHARGER_STATUS_CHARGING;
			break;
		case BQ24190_CHRG_STAT_CHRG_TERM:
			*status = CHARGER_STATUS_FULL;
			break;
		default:
			return -EIO;
		}
	}

	return 0;
}

static int bq24190_charger_get_constant_charge_current(const struct device *dev,
						       uint32_t *current_ua)
{
	const struct bq24190_config *const config = dev->config;
	bool frc_20pct;
	uint8_t v;
	int ret;

	ret = i2c_reg_read_byte_dt(&config->i2c, BQ24190_REG_CCC, &v);
	if (ret) {
		return ret;
	}

	frc_20pct = v & BQ24190_REG_CCC_FORCE_20PCT_MASK;

	v = FIELD_GET(BQ24190_REG_CCC_ICHG_MASK, v);

	*current_ua = (v * BQ24190_REG_CCC_ICHG_STEP_UA) + BQ24190_REG_CCC_ICHG_OFFSET_UA;

	if (frc_20pct) {
		*current_ua /= 5;
	}

	return 0;
}

static int bq24190_charger_get_precharge_current(const struct device *dev, uint32_t *current_ua)
{
	const struct bq24190_config *const config = dev->config;
	bool frc_20pct;
	uint8_t v;
	int ret;

	ret = i2c_reg_read_byte_dt(&config->i2c, BQ24190_REG_CCC, &v);
	if (ret) {
		return ret;
	}

	frc_20pct = v & BQ24190_REG_CCC_FORCE_20PCT_MASK;

	ret = i2c_reg_read_byte_dt(&config->i2c, BQ24190_REG_PCTCC, &v);
	if (ret) {
		return ret;
	}

	v = FIELD_GET(BQ24190_REG_PCTCC_IPRECHG_MASK, v);

	*current_ua = (v * BQ24190_REG_PCTCC_IPRECHG_STEP_UA) + BQ24190_REG_PCTCC_IPRECHG_OFFSET_UA;

	if (frc_20pct) {
		*current_ua /= 2;
	}

	return 0;
}

static int bq24190_charger_get_charge_term_current(const struct device *dev, uint32_t *current_ua)
{
	const struct bq24190_config *const config = dev->config;
	uint8_t v;
	int ret;

	ret = i2c_reg_read_byte_dt(&config->i2c, BQ24190_REG_PCTCC, &v);
	if (ret) {
		return ret;
	}

	v = FIELD_GET(BQ24190_REG_PCTCC_ITERM_MASK, v);

	*current_ua = (v * BQ24190_REG_PCTCC_ITERM_STEP_UA) + BQ24190_REG_PCTCC_ITERM_OFFSET_UA;

	return 0;
}

static int bq24190_get_constant_charge_voltage(const struct device *dev, uint32_t *voltage_uv)
{
	const struct bq24190_config *const config = dev->config;
	uint8_t v;
	int ret;

	ret = i2c_reg_read_byte_dt(&config->i2c, BQ24190_REG_CVC, &v);
	if (ret < 0) {
		return ret;
	}

	v = FIELD_GET(BQ24190_REG_CVC_VREG_MASK, v);

	*voltage_uv = (v * BQ24190_REG_CVC_VREG_STEP_UV) + BQ24190_REG_CVC_VREG_OFFSET_UV;

	return 0;
}

static int bq24190_set_constant_charge_current(const struct device *dev, uint32_t current_ua)
{
	const struct bq24190_config *const config = dev->config;
	uint8_t v;
	int ret;

	ret = i2c_reg_read_byte_dt(&config->i2c, BQ24190_REG_CCC, &v);
	if (ret < 0) {
		return ret;
	}

	v &= BQ24190_REG_CCC_FORCE_20PCT_MASK;

	if (v) {
		current_ua *= 5;
	}

	current_ua = CLAMP(current_ua, BQ24190_REG_CCC_ICHG_MIN_UA, BQ24190_REG_CCC_ICHG_MAX_UA);

	v = (current_ua - BQ24190_REG_CCC_ICHG_OFFSET_UA) / BQ24190_REG_CCC_ICHG_STEP_UA;

	v = FIELD_PREP(BQ24190_REG_CCC_ICHG_MASK, v);

	return i2c_reg_update_byte_dt(&config->i2c, BQ24190_REG_CCC, BQ24190_REG_CCC_ICHG_MASK, v);
}

static int bq24190_set_constant_charge_voltage(const struct device *dev, uint32_t voltage_uv)
{
	const struct bq24190_config *const config = dev->config;
	uint8_t v;

	voltage_uv = CLAMP(voltage_uv, BQ24190_REG_CVC_VREG_MIN_UV, BQ24190_REG_CVC_VREG_MAX_UV);

	v = (voltage_uv - BQ24190_REG_CVC_VREG_OFFSET_UV) / BQ24190_REG_CVC_VREG_STEP_UV;

	v = FIELD_PREP(BQ24190_REG_CVC_VREG_MASK, v);

	return i2c_reg_update_byte_dt(&config->i2c, BQ24190_REG_CVC, BQ24190_REG_CVC_VREG_MASK, v);
}

static int bq24190_set_config(const struct device *dev)
{
	struct bq24190_data *data = dev->data;
	union charger_propval val;
	int ret;

	val.const_charge_current_ua = data->ichg_ua;

	ret = bq24190_set_constant_charge_current(dev, val.const_charge_current_ua);
	if (ret < 0) {
		return ret;
	}

	val.const_charge_voltage_uv = data->vreg_uv;

	return bq24190_set_constant_charge_voltage(dev, val.const_charge_voltage_uv);
}

static int bq24190_get_prop(const struct device *dev, charger_prop_t prop,
			    union charger_propval *val)
{
	switch (prop) {
	case CHARGER_PROP_ONLINE:
		return bq24190_charger_get_online(dev, &val->online);
	case CHARGER_PROP_CHARGE_TYPE:
		return bq24190_charger_get_charge_type(dev, &val->charge_type);
	case CHARGER_PROP_HEALTH:
		return bq24190_charger_get_health(dev, &val->health);
	case CHARGER_PROP_STATUS:
		return bq24190_charger_get_status(dev, &val->status);
	case CHARGER_PROP_CONSTANT_CHARGE_CURRENT_UA:
		return bq24190_charger_get_constant_charge_current(dev,
								   &val->const_charge_current_ua);
	case CHARGER_PROP_CONSTANT_CHARGE_VOLTAGE_UV:
		return bq24190_get_constant_charge_voltage(dev, &val->const_charge_voltage_uv);
	case CHARGER_PROP_PRECHARGE_CURRENT_UA:
		return bq24190_charger_get_precharge_current(dev, &val->precharge_current_ua);
	case CHARGER_PROP_CHARGE_TERM_CURRENT_UA:
		return bq24190_charger_get_charge_term_current(dev, &val->charge_term_current_ua);
	default:
		return -ENOTSUP;
	}
}

static int bq24190_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 bq24190_set_constant_charge_current(dev, val->const_charge_current_ua);
	case CHARGER_PROP_CONSTANT_CHARGE_VOLTAGE_UV:
		return bq24190_set_constant_charge_voltage(dev, val->const_charge_voltage_uv);
	default:
		return -ENOTSUP;
	}
}

static int bq24190_init(const struct device *dev)
{
	const struct bq24190_config *const config = dev->config;
	struct bq24190_data *data = dev->data;
	uint8_t val;
	int ret;

	ret = i2c_reg_read_byte_dt(&config->i2c, BQ24190_REG_VPRS, &val);
	if (ret) {
		return ret;
	}

	val = FIELD_GET(BQ24190_REG_VPRS_PN_MASK, val);

	switch (val) {
	case BQ24190_REG_VPRS_PN_24190:
	case BQ24190_REG_VPRS_PN_24192:
	case BQ24190_REG_VPRS_PN_24192I:
		break;
	default:
		LOG_ERR("Error unknown model: 0x%02x\n", val);
		return -ENODEV;
	}

	ret = bq24190_register_reset(dev);
	if (ret) {
		return ret;
	}

	ret = bq24190_set_config(dev);
	if (ret) {
		return ret;
	}

	return i2c_reg_read_byte_dt(&config->i2c, BQ24190_REG_SS, &data->ss_reg);
}

static const struct charger_driver_api bq24190_driver_api = {
	.get_property = bq24190_get_prop,
	.set_property = bq24190_set_prop,
};

#define BQ24190_INIT(inst)                                                                         \
                                                                                                   \
	static const struct bq24190_config bq24190_config_##inst = {                               \
		.i2c = I2C_DT_SPEC_INST_GET(inst),                                                 \
	};                                                                                         \
                                                                                                   \
	static struct bq24190_data bq24190_data_##inst = {                                         \
		.ichg_ua = DT_INST_PROP(inst, constant_charge_current_max_microamp),               \
		.vreg_uv = DT_INST_PROP(inst, constant_charge_voltage_max_microvolt),              \
	};                                                                                         \
                                                                                                   \
	DEVICE_DT_INST_DEFINE(inst, bq24190_init, NULL, &bq24190_data_##inst,                      \
			      &bq24190_config_##inst, POST_KERNEL, CONFIG_CHARGER_INIT_PRIORITY,   \
			      &bq24190_driver_api);

DT_INST_FOREACH_STATUS_OKAY(BQ24190_INIT)
