/*
 *
 * OMAP4460 Plus bandgap on die sensor hwmon driver.
 *
 * Copyright (C) 2011 Texas Instruments Incorporated - http://www.ti.com/
 * J Keerthy <j-keerthy@ti.com>
 *
 * This program is free software; you can redistribute it and/or
 * modify it under the terms of the GNU General Public License
 * version 2 as published by the Free Software Foundation.
 *
 * This program is distributed in the hope that it will be useful, but
 * WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
 * 02110-1301 USA
 *
 */
#include <linux/init.h>
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/i2c/twl.h>
#include <linux/device.h>
#include <linux/platform_device.h>
#include <linux/i2c/twl4030-madc.h>
#include <linux/hwmon.h>
#include <linux/hwmon-sysfs.h>
#include <linux/stddef.h>
#include <linux/sysfs.h>
#include <linux/err.h>
#include <linux/types.h>
#include <plat/scm.h>
#include <linux/mfd/omap4_scm.h>

static ssize_t show_name(struct device *dev,
			 struct device_attribute *attr, char *buf)
{
	struct temp_sensor_hwmon *tsh = dev_get_drvdata(dev);

	return sprintf(buf, tsh->name);
}

static ssize_t show_temp_max(struct device *dev,
			     struct device_attribute *devattr, char *buf)
{
	struct temp_sensor_hwmon *tsh = dev_get_drvdata(dev);
	struct platform_device *pdev = container_of(dev,
						struct platform_device, dev);
	int id = pdev->id;
	int temp;

	temp = omap4460plus_scm_show_temp_max(tsh->scm_ptr, id);

	return sprintf(buf, "%d\n", temp);
}

static ssize_t set_temp_max(struct device *dev,
			    struct device_attribute *devattr,
			    const char *buf, size_t count)
{
	struct temp_sensor_hwmon *tsh = dev_get_drvdata(dev);
	struct platform_device *pdev = container_of(dev,
						struct platform_device, dev);
	int id = pdev->id, ret;
	long val;

	if (strict_strtol(buf, 10, &val))
		return -EINVAL;
	ret = omap4460plus_scm_set_temp_max(tsh->scm_ptr, id, val);
	if (ret < 0)
		return ret;

	return count;
}

static ssize_t show_temp_max_hyst(struct device *dev,
				  struct device_attribute *devattr, char *buf)
{
	struct temp_sensor_hwmon *tsh = dev_get_drvdata(dev);
	struct platform_device *pdev = container_of(dev,
						struct platform_device, dev);
	int id = pdev->id;
	int temp;

	temp = omap4460plus_scm_show_temp_max_hyst(tsh->scm_ptr, id);

	return sprintf(buf, "%d\n", temp);
}

static ssize_t set_temp_max_hyst(struct device *dev,
				 struct device_attribute *devattr,
				 const char *buf, size_t count)
{
	struct temp_sensor_hwmon *tsh = dev_get_drvdata(dev);
	struct platform_device *pdev = container_of(dev,
						struct platform_device, dev);
	int id = pdev->id, ret;
	long val;

	if (strict_strtol(buf, 10, &val))
		return -EINVAL;
	ret = omap4460plus_scm_set_temp_max_hyst(tsh->scm_ptr, id, val);
	if (ret < 0)
		return ret;

	return count;
}

static ssize_t show_update_interval(struct device *dev,
				    struct device_attribute *devattr, char *buf)
{
	int time = 0;
	struct temp_sensor_hwmon *tsh = dev_get_drvdata(dev);
	struct platform_device *pdev = container_of(dev,
						struct platform_device, dev);
	int id = pdev->id;

	time = omap4460plus_scm_show_update_interval(tsh->scm_ptr, id);

	return sprintf(buf, "%d\n", time);
}

static ssize_t set_update_interval(struct device *dev,
				   struct device_attribute *devattr,
				   const char *buf, size_t count)
{
	struct temp_sensor_hwmon *tsh = dev_get_drvdata(dev);
	struct platform_device *pdev = container_of(dev,
						struct platform_device, dev);
	int id = pdev->id;
	unsigned long val;

	if (strict_strtoul(buf, 10, &val))
		return -EINVAL;

	omap4460plus_scm_set_update_interval(tsh->scm_ptr, val, id);
	return count;
}

static int read_temp(struct device *dev,
		     struct device_attribute *devattr, char *buf)
{
	struct temp_sensor_hwmon *tsh = dev_get_drvdata(dev);
	struct platform_device *pdev = container_of(dev,
						struct platform_device, dev);
	int id = pdev->id;
	int temp;

	temp = omap4460plus_scm_read_temp(tsh->scm_ptr, id);

	return sprintf(buf, "%d\n", temp);
}

static DEVICE_ATTR(name, S_IRUGO, show_name, NULL);
static SENSOR_DEVICE_ATTR(temp1_input, S_IRUGO, read_temp, NULL, 0);
static SENSOR_DEVICE_ATTR(temp1_max, S_IWUSR | S_IRUGO, show_temp_max,
			  set_temp_max, 0);
static SENSOR_DEVICE_ATTR(temp1_max_hyst, S_IWUSR | S_IRUGO, show_temp_max_hyst,
			  set_temp_max_hyst, 0);
static SENSOR_DEVICE_ATTR(update_interval, S_IWUSR | S_IRUGO,
			  show_update_interval, set_update_interval, 0);

static struct attribute *temp_sensor_attributes[] = {
	&dev_attr_name.attr,

	&sensor_dev_attr_temp1_input.dev_attr.attr,
	&sensor_dev_attr_temp1_max.dev_attr.attr,
	&sensor_dev_attr_temp1_max_hyst.dev_attr.attr,
	&sensor_dev_attr_update_interval.dev_attr.attr,
	NULL
};

static const struct attribute_group temp_sensor_group = {
	.attrs = temp_sensor_attributes,
};

static int __devinit omap4460plus_temp_sensor_probe(struct platform_device
							*pdev)
{
	int ret;
	struct device *hwmon;

	ret = sysfs_create_group(&pdev->dev.kobj, &temp_sensor_group);
	if (ret)
		goto err_sysfs;
	hwmon = hwmon_device_register(&pdev->dev);
	if (IS_ERR(hwmon)) {
		dev_err(&pdev->dev, "hwmon_device_register failed.\n");
		ret = PTR_ERR(hwmon);
		goto err_reg;
	}

	return 0;

err_reg:
	sysfs_remove_group(&pdev->dev.kobj, &temp_sensor_group);
err_sysfs:

	return ret;
}

static int __devexit omap4460plus_temp_sensor_remove(struct platform_device
						     *pdev)
{
	hwmon_device_unregister(&pdev->dev);
	sysfs_remove_group(&pdev->dev.kobj, &temp_sensor_group);

	return 0;
}

static struct platform_driver omap4460plus_temp_sensor_driver = {
	.probe = omap4460plus_temp_sensor_probe,
	.remove = omap4460plus_temp_sensor_remove,
	.driver = {
		   .name = "temp_sensor_hwmon",
		   },
};

int __init omap4460plus_hwmon_temp_sensor_init(void)
{
	return platform_driver_register(&omap4460plus_temp_sensor_driver);
}

module_init(omap4460plus_hwmon_temp_sensor_init);

static void __exit omap4460plus_hwmon_temp_sensor_exit(void)
{
	platform_driver_unregister(&omap4460plus_temp_sensor_driver);
}

module_exit(omap4460plus_hwmon_temp_sensor_exit);

MODULE_DESCRIPTION("OMAP446X temperature sensor Hwmon Driver");
MODULE_LICENSE("GPL");
MODULE_ALIAS("platform:" DRIVER_NAME);
MODULE_AUTHOR("J Keerthy <j-keerthy@ti.com>");
