// SPDX-License-Identifier: GPL-2.0-only
/*
 * Battery measurement code for WM97xx
 *
 * based on tosa_battery.c
 *
 * Copyright (C) 2008 Marek Vasut <marek.vasut@gmail.com>
 */

#include <linux/init.h>
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/platform_device.h>
#include <linux/power_supply.h>
#include <linux/wm97xx.h>
#include <linux/spinlock.h>
#include <linux/interrupt.h>
#include <linux/gpio/consumer.h>
#include <linux/irq.h>
#include <linux/slab.h>

static struct work_struct bat_work;
static struct gpio_desc *charge_gpiod;
static DEFINE_MUTEX(work_lock);
static int bat_status = POWER_SUPPLY_STATUS_UNKNOWN;
static enum power_supply_property *prop;

static unsigned long wm97xx_read_bat(struct power_supply *bat_ps)
{
	struct wm97xx_batt_pdata *pdata = power_supply_get_drvdata(bat_ps);

	return wm97xx_read_aux_adc(dev_get_drvdata(bat_ps->dev.parent),
					pdata->batt_aux) * pdata->batt_mult /
					pdata->batt_div;
}

static unsigned long wm97xx_read_temp(struct power_supply *bat_ps)
{
	struct wm97xx_batt_pdata *pdata = power_supply_get_drvdata(bat_ps);

	return wm97xx_read_aux_adc(dev_get_drvdata(bat_ps->dev.parent),
					pdata->temp_aux) * pdata->temp_mult /
					pdata->temp_div;
}

static int wm97xx_bat_get_property(struct power_supply *bat_ps,
			    enum power_supply_property psp,
			    union power_supply_propval *val)
{
	struct wm97xx_batt_pdata *pdata = power_supply_get_drvdata(bat_ps);

	switch (psp) {
	case POWER_SUPPLY_PROP_STATUS:
		val->intval = bat_status;
		break;
	case POWER_SUPPLY_PROP_TECHNOLOGY:
		val->intval = pdata->batt_tech;
		break;
	case POWER_SUPPLY_PROP_VOLTAGE_NOW:
		if (pdata->batt_aux >= 0)
			val->intval = wm97xx_read_bat(bat_ps);
		else
			return -EINVAL;
		break;
	case POWER_SUPPLY_PROP_TEMP:
		if (pdata->temp_aux >= 0)
			val->intval = wm97xx_read_temp(bat_ps);
		else
			return -EINVAL;
		break;
	case POWER_SUPPLY_PROP_VOLTAGE_MAX:
		if (pdata->max_voltage >= 0)
			val->intval = pdata->max_voltage;
		else
			return -EINVAL;
		break;
	case POWER_SUPPLY_PROP_VOLTAGE_MIN:
		if (pdata->min_voltage >= 0)
			val->intval = pdata->min_voltage;
		else
			return -EINVAL;
		break;
	case POWER_SUPPLY_PROP_PRESENT:
		val->intval = 1;
		break;
	default:
		return -EINVAL;
	}
	return 0;
}

static void wm97xx_bat_external_power_changed(struct power_supply *bat_ps)
{
	schedule_work(&bat_work);
}

static void wm97xx_bat_update(struct power_supply *bat_ps)
{
	int old_status = bat_status;

	mutex_lock(&work_lock);

	bat_status = (charge_gpiod) ?
			(gpiod_get_value(charge_gpiod) ?
			POWER_SUPPLY_STATUS_DISCHARGING :
			POWER_SUPPLY_STATUS_CHARGING) :
			POWER_SUPPLY_STATUS_UNKNOWN;

	if (old_status != bat_status) {
		pr_debug("%s: %i -> %i\n", bat_ps->desc->name, old_status,
					bat_status);
		power_supply_changed(bat_ps);
	}

	mutex_unlock(&work_lock);
}

static struct power_supply *bat_psy;
static struct power_supply_desc bat_psy_desc = {
	.type			= POWER_SUPPLY_TYPE_BATTERY,
	.get_property		= wm97xx_bat_get_property,
	.external_power_changed = wm97xx_bat_external_power_changed,
	.use_for_apm		= 1,
};

static void wm97xx_bat_work(struct work_struct *work)
{
	wm97xx_bat_update(bat_psy);
}

static irqreturn_t wm97xx_chrg_irq(int irq, void *data)
{
	schedule_work(&bat_work);
	return IRQ_HANDLED;
}

#ifdef CONFIG_PM
static int wm97xx_bat_suspend(struct device *dev)
{
	flush_work(&bat_work);
	return 0;
}

static int wm97xx_bat_resume(struct device *dev)
{
	schedule_work(&bat_work);
	return 0;
}

static const struct dev_pm_ops wm97xx_bat_pm_ops = {
	.suspend	= wm97xx_bat_suspend,
	.resume		= wm97xx_bat_resume,
};
#endif

static int wm97xx_bat_probe(struct platform_device *dev)
{
	int ret = 0;
	int props = 1;	/* POWER_SUPPLY_PROP_PRESENT */
	int i = 0;
	struct wm97xx_batt_pdata *pdata = dev->dev.platform_data;
	struct power_supply_config cfg = {};

	if (!pdata) {
		dev_err(&dev->dev, "No platform data supplied\n");
		return -EINVAL;
	}

	cfg.drv_data = pdata;

	if (dev->id != -1)
		return -EINVAL;

	charge_gpiod = devm_gpiod_get_optional(&dev->dev, NULL, GPIOD_IN);
	if (IS_ERR(charge_gpiod))
		return dev_err_probe(&dev->dev,
				     PTR_ERR(charge_gpiod),
				     "failed to get charge GPIO\n");
	if (charge_gpiod) {
		gpiod_set_consumer_name(charge_gpiod, "BATT CHRG");
		ret = request_irq(gpiod_to_irq(charge_gpiod),
				wm97xx_chrg_irq, 0,
				"AC Detect", dev);
		if (ret)
			return dev_err_probe(&dev->dev, ret,
					     "failed to request GPIO irq\n");
		props++;	/* POWER_SUPPLY_PROP_STATUS */
	}

	if (pdata->batt_tech >= 0)
		props++;	/* POWER_SUPPLY_PROP_TECHNOLOGY */
	if (pdata->temp_aux >= 0)
		props++;	/* POWER_SUPPLY_PROP_TEMP */
	if (pdata->batt_aux >= 0)
		props++;	/* POWER_SUPPLY_PROP_VOLTAGE_NOW */
	if (pdata->max_voltage >= 0)
		props++;	/* POWER_SUPPLY_PROP_VOLTAGE_MAX */
	if (pdata->min_voltage >= 0)
		props++;	/* POWER_SUPPLY_PROP_VOLTAGE_MIN */

	prop = kcalloc(props, sizeof(*prop), GFP_KERNEL);
	if (!prop) {
		ret = -ENOMEM;
		goto err3;
	}

	prop[i++] = POWER_SUPPLY_PROP_PRESENT;
	if (charge_gpiod)
		prop[i++] = POWER_SUPPLY_PROP_STATUS;
	if (pdata->batt_tech >= 0)
		prop[i++] = POWER_SUPPLY_PROP_TECHNOLOGY;
	if (pdata->temp_aux >= 0)
		prop[i++] = POWER_SUPPLY_PROP_TEMP;
	if (pdata->batt_aux >= 0)
		prop[i++] = POWER_SUPPLY_PROP_VOLTAGE_NOW;
	if (pdata->max_voltage >= 0)
		prop[i++] = POWER_SUPPLY_PROP_VOLTAGE_MAX;
	if (pdata->min_voltage >= 0)
		prop[i++] = POWER_SUPPLY_PROP_VOLTAGE_MIN;

	INIT_WORK(&bat_work, wm97xx_bat_work);

	if (!pdata->batt_name) {
		dev_info(&dev->dev, "Please consider setting proper battery "
				"name in platform definition file, falling "
				"back to name \"wm97xx-batt\"\n");
		bat_psy_desc.name = "wm97xx-batt";
	} else
		bat_psy_desc.name = pdata->batt_name;

	bat_psy_desc.properties = prop;
	bat_psy_desc.num_properties = props;

	bat_psy = power_supply_register(&dev->dev, &bat_psy_desc, &cfg);
	if (!IS_ERR(bat_psy)) {
		schedule_work(&bat_work);
	} else {
		ret = PTR_ERR(bat_psy);
		goto err4;
	}

	return 0;
err4:
	kfree(prop);
err3:
	if (charge_gpiod)
		free_irq(gpiod_to_irq(charge_gpiod), dev);
	return ret;
}

static int wm97xx_bat_remove(struct platform_device *dev)
{
	if (charge_gpiod)
		free_irq(gpiod_to_irq(charge_gpiod), dev);
	cancel_work_sync(&bat_work);
	power_supply_unregister(bat_psy);
	kfree(prop);
	return 0;
}

static struct platform_driver wm97xx_bat_driver = {
	.driver	= {
		.name	= "wm97xx-battery",
#ifdef CONFIG_PM
		.pm	= &wm97xx_bat_pm_ops,
#endif
	},
	.probe		= wm97xx_bat_probe,
	.remove		= wm97xx_bat_remove,
};

module_platform_driver(wm97xx_bat_driver);

MODULE_LICENSE("GPL");
MODULE_AUTHOR("Marek Vasut <marek.vasut@gmail.com>");
MODULE_DESCRIPTION("WM97xx battery driver");
