// SPDX-License-Identifier: GPL-2.0+
/*
 * Battery driver for Acer Iconia Tab A500.
 *
 * Copyright 2020 GRATE-driver project.
 *
 * Based on downstream driver from Acer Inc.
 * Based on NVIDIA Gas Gauge driver for SBS Compliant Batteries.
 *
 * Copyright (c) 2010, NVIDIA Corporation.
 */

#include <linux/module.h>
#include <linux/platform_device.h>
#include <linux/power_supply.h>
#include <linux/regmap.h>
#include <linux/sched.h>
#include <linux/slab.h>
#include <linux/workqueue.h>

enum {
	REG_CAPACITY,
	REG_VOLTAGE,
	REG_CURRENT,
	REG_DESIGN_CAPACITY,
	REG_TEMPERATURE,
};

#define EC_DATA(_reg, _psp) {			\
	.psp = POWER_SUPPLY_PROP_ ## _psp,	\
	.reg = _reg,				\
}

static const struct battery_register {
	enum power_supply_property psp;
	unsigned int reg;
} ec_data[] = {
	[REG_CAPACITY]		= EC_DATA(0x00, CAPACITY),
	[REG_VOLTAGE]		= EC_DATA(0x01, VOLTAGE_NOW),
	[REG_CURRENT]		= EC_DATA(0x03, CURRENT_NOW),
	[REG_DESIGN_CAPACITY]	= EC_DATA(0x08, CHARGE_FULL_DESIGN),
	[REG_TEMPERATURE]	= EC_DATA(0x0a, TEMP),
};

static const enum power_supply_property a500_battery_properties[] = {
	POWER_SUPPLY_PROP_CAPACITY,
	POWER_SUPPLY_PROP_CHARGE_FULL_DESIGN,
	POWER_SUPPLY_PROP_CURRENT_NOW,
	POWER_SUPPLY_PROP_PRESENT,
	POWER_SUPPLY_PROP_STATUS,
	POWER_SUPPLY_PROP_TECHNOLOGY,
	POWER_SUPPLY_PROP_TEMP,
	POWER_SUPPLY_PROP_VOLTAGE_NOW,
};

struct a500_battery {
	struct delayed_work poll_work;
	struct power_supply *psy;
	struct regmap *regmap;
	unsigned int capacity;
};

static bool a500_battery_update_capacity(struct a500_battery *bat)
{
	unsigned int capacity;
	int err;

	err = regmap_read(bat->regmap, ec_data[REG_CAPACITY].reg, &capacity);
	if (err)
		return false;

	/* capacity can be >100% even if max value is 100% */
	capacity = min(capacity, 100u);

	if (bat->capacity != capacity) {
		bat->capacity = capacity;
		return true;
	}

	return false;
}

static int a500_battery_get_status(struct a500_battery *bat)
{
	if (bat->capacity < 100) {
		if (power_supply_am_i_supplied(bat->psy))
			return POWER_SUPPLY_STATUS_CHARGING;
		else
			return POWER_SUPPLY_STATUS_DISCHARGING;
	}

	return POWER_SUPPLY_STATUS_FULL;
}

static void a500_battery_unit_adjustment(struct device *dev,
					 enum power_supply_property psp,
					 union power_supply_propval *val)
{
	const unsigned int base_unit_conversion = 1000;
	const unsigned int temp_kelvin_to_celsius = 2731;

	switch (psp) {
	case POWER_SUPPLY_PROP_CHARGE_FULL_DESIGN:
	case POWER_SUPPLY_PROP_CURRENT_NOW:
	case POWER_SUPPLY_PROP_VOLTAGE_NOW:
		val->intval *= base_unit_conversion;
		break;

	case POWER_SUPPLY_PROP_TEMP:
		val->intval -= temp_kelvin_to_celsius;
		break;

	case POWER_SUPPLY_PROP_PRESENT:
		val->intval = !!val->intval;
		break;

	default:
		dev_dbg(dev,
			"%s: no need for unit conversion %d\n", __func__, psp);
	}
}

static int a500_battery_get_ec_data_index(struct device *dev,
					  enum power_supply_property psp)
{
	unsigned int i;

	/*
	 * DESIGN_CAPACITY register always returns a non-zero value if
	 * battery is connected and zero if disconnected, hence we'll use
	 * it for judging the battery presence.
	 */
	if (psp == POWER_SUPPLY_PROP_PRESENT)
		psp = POWER_SUPPLY_PROP_CHARGE_FULL_DESIGN;

	for (i = 0; i < ARRAY_SIZE(ec_data); i++)
		if (psp == ec_data[i].psp)
			return i;

	dev_dbg(dev, "%s: invalid property %u\n", __func__, psp);

	return -EINVAL;
}

static int a500_battery_get_property(struct power_supply *psy,
				     enum power_supply_property psp,
				     union power_supply_propval *val)
{
	struct a500_battery *bat = power_supply_get_drvdata(psy);
	struct device *dev = psy->dev.parent;
	int ret = 0;

	switch (psp) {
	case POWER_SUPPLY_PROP_STATUS:
		val->intval = a500_battery_get_status(bat);
		break;

	case POWER_SUPPLY_PROP_TECHNOLOGY:
		val->intval = POWER_SUPPLY_TECHNOLOGY_LION;
		break;

	case POWER_SUPPLY_PROP_CAPACITY:
		a500_battery_update_capacity(bat);
		val->intval = bat->capacity;
		break;

	case POWER_SUPPLY_PROP_CHARGE_FULL_DESIGN:
	case POWER_SUPPLY_PROP_CURRENT_NOW:
	case POWER_SUPPLY_PROP_VOLTAGE_NOW:
	case POWER_SUPPLY_PROP_PRESENT:
	case POWER_SUPPLY_PROP_TEMP:
		ret = a500_battery_get_ec_data_index(dev, psp);
		if (ret < 0)
			break;

		ret = regmap_read(bat->regmap, ec_data[ret].reg, &val->intval);
		break;

	default:
		dev_err(dev, "%s: invalid property %u\n", __func__, psp);
		return -EINVAL;
	}

	if (!ret) {
		/* convert units to match requirements of power supply class */
		a500_battery_unit_adjustment(dev, psp, val);
	}

	dev_dbg(dev, "%s: property = %d, value = %x\n",
		__func__, psp, val->intval);

	/* return NODATA for properties if battery not presents */
	if (ret)
		return -ENODATA;

	return 0;
}

static void a500_battery_poll_work(struct work_struct *work)
{
	struct a500_battery *bat;
	bool capacity_changed;

	bat = container_of(work, struct a500_battery, poll_work.work);
	capacity_changed = a500_battery_update_capacity(bat);

	if (capacity_changed)
		power_supply_changed(bat->psy);

	/* continuously send uevent notification */
	schedule_delayed_work(&bat->poll_work, 30 * HZ);
}

static const struct power_supply_desc a500_battery_desc = {
	.name = "ec-battery",
	.type = POWER_SUPPLY_TYPE_BATTERY,
	.properties = a500_battery_properties,
	.get_property = a500_battery_get_property,
	.num_properties = ARRAY_SIZE(a500_battery_properties),
	.external_power_changed = power_supply_changed,
};

static int a500_battery_probe(struct platform_device *pdev)
{
	struct power_supply_config psy_cfg = {};
	struct a500_battery *bat;

	bat = devm_kzalloc(&pdev->dev, sizeof(*bat), GFP_KERNEL);
	if (!bat)
		return -ENOMEM;

	platform_set_drvdata(pdev, bat);

	psy_cfg.of_node = pdev->dev.parent->of_node;
	psy_cfg.drv_data = bat;

	bat->regmap = dev_get_regmap(pdev->dev.parent, "KB930");
	if (!bat->regmap)
		return -EINVAL;

	bat->psy = devm_power_supply_register_no_ws(&pdev->dev,
						    &a500_battery_desc,
						    &psy_cfg);
	if (IS_ERR(bat->psy))
		return dev_err_probe(&pdev->dev, PTR_ERR(bat->psy),
				     "failed to register battery\n");

	INIT_DELAYED_WORK(&bat->poll_work, a500_battery_poll_work);
	schedule_delayed_work(&bat->poll_work, HZ);

	return 0;
}

static int a500_battery_remove(struct platform_device *pdev)
{
	struct a500_battery *bat = dev_get_drvdata(&pdev->dev);

	cancel_delayed_work_sync(&bat->poll_work);

	return 0;
}

static int __maybe_unused a500_battery_suspend(struct device *dev)
{
	struct a500_battery *bat = dev_get_drvdata(dev);

	cancel_delayed_work_sync(&bat->poll_work);

	return 0;
}

static int __maybe_unused a500_battery_resume(struct device *dev)
{
	struct a500_battery *bat = dev_get_drvdata(dev);

	schedule_delayed_work(&bat->poll_work, HZ);

	return 0;
}

static SIMPLE_DEV_PM_OPS(a500_battery_pm_ops,
			 a500_battery_suspend, a500_battery_resume);

static struct platform_driver a500_battery_driver = {
	.driver = {
		.name = "acer-a500-iconia-battery",
		.pm = &a500_battery_pm_ops,
	},
	.probe = a500_battery_probe,
	.remove = a500_battery_remove,
};
module_platform_driver(a500_battery_driver);

MODULE_DESCRIPTION("Battery gauge driver for Acer Iconia Tab A500");
MODULE_AUTHOR("Dmitry Osipenko <digetx@gmail.com>");
MODULE_ALIAS("platform:acer-a500-iconia-battery");
MODULE_LICENSE("GPL");
