/*
 * Copyright (C) 2014 Nest Labs
 *
 * This program is free software; you can redistribute it and/or
 * modify it under the terms of the GNU General Public License as
 * published by the Free Software Foundation version 2.
 *
 * This program is distributed "as is" WITHOUT ANY WARRANTY of any
 * kind, whether express or implied; without even the implied warranty
 * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 */

#include <linux/err.h>
#include <linux/iio/consumer.h>
#include <linux/iio/types.h>
#include <linux/iio/iio.h>
#include <linux/interrupt.h>
#include <linux/module.h>
#include <linux/of_gpio.h>
#include <linux/platform_device.h>
#include <linux/power_supply.h>
#include <linux/printk.h>
#include <linux/mutex.h>
#include <linux/delay.h>


struct adc_div_device {
	struct power_supply *bat_ps;
	struct iio_channel *chan;
	unsigned int r1_ohm;
	unsigned int r2_ohm;
	unsigned int enable_gpio;
	unsigned int delay_us;
	struct mutex adc_lock;
};

static enum power_supply_property adc_div_bat_props[] = {
	POWER_SUPPLY_PROP_ONLINE,
	POWER_SUPPLY_PROP_VOLTAGE_NOW,
};

static int adc_div_bat_get_property(struct power_supply *bat_ps,
				enum power_supply_property prop,
				union power_supply_propval *val)
{
	struct adc_div_device *dev = power_supply_get_drvdata(bat_ps);
	int ret = 0;

	switch (prop) {

	case POWER_SUPPLY_PROP_ONLINE:
		/* Always online */
		val->intval = 1;
		break;

	case POWER_SUPPLY_PROP_VOLTAGE_NOW:
		BUG_ON(!dev->chan);

		if (gpio_is_valid(dev->enable_gpio)) {
			mutex_lock(&dev->adc_lock);
			gpio_set_value(dev->enable_gpio, 1);
			usleep_range(dev->delay_us, dev->delay_us + 500);
		}

		/* Read ADC voltage and then compensate for the divider */
		ret = iio_read_channel_processed(dev->chan, &val->intval);
		val->intval *= dev->r1_ohm + dev->r2_ohm;
		val->intval /= dev->r2_ohm;

		/* Processed IIO returns mV but power supply returns uV */
		val->intval *= 1000;

		if (gpio_is_valid(dev->enable_gpio)) {
			gpio_set_value(dev->enable_gpio, 0);
			mutex_unlock(&dev->adc_lock);
		}

		break;

	default:
		ret = -EINVAL;
	}

	return ret;
}

static const struct power_supply_desc bat_ps_desc =
{
    .name = "adc-div-battery",
    .type = POWER_SUPPLY_TYPE_BATTERY,
    .properties = adc_div_bat_props,
    .num_properties = ARRAY_SIZE(adc_div_bat_props),
    .get_property = adc_div_bat_get_property,
};

static int adc_div_probe(struct platform_device *pdev)
{
	struct adc_div_device *dev;
	struct device_node *np;
	struct power_supply_config adc_div_cfg = {};
	int ret;

	/* Check for OF node */
	np = pdev->dev.of_node;
	if (!np) {
		dev_err(&pdev->dev, "Missing DT node\n");
		return -ENODEV;
	}

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

	platform_set_drvdata(pdev, dev);

	/* Read DT Properties */
	/* Request the enable gpio if given */
	dev->enable_gpio = of_get_named_gpio(np, "vbatt-adc-input-enable-gpio", 0);
	if (gpio_is_valid(dev->enable_gpio)) {
		ret = devm_gpio_request_one(&pdev->dev, dev->enable_gpio, GPIOF_DIR_OUT, "vbatt-adc-input-enable-gpio");
		if (ret) {
			dev_info(&pdev->dev, "failed to register vbatt-adc-input-enable-gpio %d\n", dev->enable_gpio);
			return ret;
		} else {
			dev_info(&pdev->dev, "register vbatt-adc-input-enable-gpio %d\n", dev->enable_gpio);
		}
	}

	/* Set the delay us if given */
	ret = of_property_read_u32(np, "delay-us", &dev->delay_us);
	if (ret)
		dev->delay_us = 0;

	dev_info(&pdev->dev, "register delay-us %d\n", dev->delay_us);

	ret = of_property_read_u32(np, "divider-r1-ohm", &dev->r1_ohm);
	if (ret) {
		dev_err(&pdev->dev, "Couldn't get r1 property from DT\n");
		return ret;
	}

	ret = of_property_read_u32(np, "divider-r2-ohm", &dev->r2_ohm);
	if (ret) {
		dev_err(&pdev->dev, "Couldn't get r2 property from DT\n");
		return ret;
	}

	if (!dev->r1_ohm || !dev->r2_ohm) {
		dev_err(&pdev->dev, "Divider values must be non-zero\n");
		return -EINVAL;
	}

	dev->chan = iio_channel_get(&pdev->dev, NULL);
	if (IS_ERR(dev->chan)) {
		dev_err(&pdev->dev, "Couldn't get ADC channel error %ld \n", PTR_ERR(dev->chan));
		if (PTR_ERR(dev->chan) == -ENODEV) {
			return -EPROBE_DEFER;
		} else {
			return PTR_ERR(dev->chan);
		}
	}

	iio_channel_write(dev->chan, 12458, 0, IIO_CHAN_INFO_SAMP_FREQ);

	mutex_init(&dev->adc_lock);

    adc_div_cfg.drv_data = dev;
	dev->bat_ps = power_supply_register(&pdev->dev, &bat_ps_desc, &adc_div_cfg);

	return 0;
}




static int adc_div_remove(struct platform_device *pdev)
{
	struct adc_div_device *dev = platform_get_drvdata(pdev);

	power_supply_unregister(dev->bat_ps);

	iio_channel_release(dev->chan);

	return 0;
}

static const struct of_device_id adc_div_match[] = {
	{ .compatible = "adc-div-battery", },
	{ },
};

static struct platform_driver adc_div_driver = {
	.probe = adc_div_probe,
	.remove = adc_div_remove,
	.driver = {
		.name = "adc-div-battery",
		.of_match_table = adc_div_match,
	},
};
module_platform_driver(adc_div_driver);

MODULE_AUTHOR("Tim Kryger <tkryger@nestlabs.com>");
MODULE_DESCRIPTION("Generic ADC Divider Battery driver");
MODULE_LICENSE("GPL v2");
