/*
 * 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/gpio/consumer.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_desc bat_psd;
	struct power_supply *bat_ps;
	struct iio_channel *chan;
	unsigned int r1_ohm;
	unsigned int r2_ohm;
	struct gpio_desc *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 = container_of(bat_ps->desc,
						  struct adc_div_device,
						  bat_psd);
	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(dev->enable_gpio) {
			mutex_lock(&dev->adc_lock);
			gpiod_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 (dev->enable_gpio) {
			gpiod_set_value(dev->enable_gpio, 0);
			mutex_unlock(&dev->adc_lock);
		}

		break;

	default:
		ret = -EINVAL;
	}

	return ret;
}

static int adc_div_probe(struct platform_device *pdev)
{
	struct adc_div_device *dev;
	struct device_node *np;
	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 = devm_gpiod_get(&pdev->dev, "vbatt-adc-input-enable");

	if (!IS_ERR(dev->enable_gpio)) {
		ret = gpiod_direction_output(dev->enable_gpio, 0);
		if(!ret) {
			char* active_low = gpiod_is_active_low(dev->enable_gpio) ? "active low" : "active high";
			dev_info(&pdev->dev, "register vbatt-adc-input-enable-gpio %s\n", active_low);
		}
		else
		{
			dev_info(&pdev->dev, "could not configure vbat-adc-input-enable %d\n", ret);
		}
	}
	else
	{
		dev_info(&pdev->dev, "failed to register vbatt-adc-input-enable-gpio err %ld\n", PTR_ERR(dev->enable_gpio));
		dev->enable_gpio = NULL;
	}

	/* 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;
	}

	mutex_init(&dev->adc_lock);

	/* Register as power supply */
	dev->bat_psd.name = "adc-div-battery";
	dev->bat_psd.type = POWER_SUPPLY_TYPE_BATTERY;
	dev->bat_psd.get_property = adc_div_bat_get_property;
	dev->bat_psd.properties = adc_div_bat_props;
	dev->bat_psd.num_properties = ARRAY_SIZE(adc_div_bat_props);

	dev->bat_ps = devm_power_supply_register(&pdev->dev, &dev->bat_psd,
						 NULL);
	if (IS_ERR(dev->bat_ps)) {
		dev->bat_ps = NULL;
		return PTR_ERR(dev->bat_ps);
	}

	dev->chan = iio_channel_get(&pdev->dev, "vbat");
	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);
		}
	}

	//FIXME: this isn't supported by mainline linux at 3.14
	//iio_channel_write(dev->chan, 12453, 0, IIO_CHAN_INFO_SAMP_FREQ);

	return 0;
}


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

	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");
