/*
 * Copyright (C) ST-Ericsson 2010 - 2013
 * Author: Martin Persson <martin.persson@stericsson.com>
 *         Hongbo Zhang <hongbo.zhang@linaro.org>
 * License Terms: GNU General Public License v2
 *
 * ABX500 does not provide auto ADC, so to monitor the required temperatures,
 * a periodic work is used. It is more important to not wake up the CPU than
 * to perform this job, hence the use of a deferred delay.
 *
 * A deferred delay for thermal monitor is considered safe because:
 * If the chip gets too hot during a sleep state it's most likely due to
 * external factors, such as the surrounding temperature. I.e. no SW decisions
 * will make any difference.
 */

#include <linux/err.h>
#include <linux/hwmon.h>
#include <linux/hwmon-sysfs.h>
#include <linux/interrupt.h>
#include <linux/jiffies.h>
#include <linux/module.h>
#include <linux/mutex.h>
#include <linux/of.h>
#include <linux/platform_device.h>
#include <linux/pm.h>
#include <linux/slab.h>
#include <linux/sysfs.h>
#include <linux/workqueue.h>
#include "abx500.h"

#define DEFAULT_MONITOR_DELAY	HZ
#define DEFAULT_MAX_TEMP	130

static inline void schedule_monitor(struct abx500_temp *data)
{
	data->work_active = true;
	schedule_delayed_work(&data->work, DEFAULT_MONITOR_DELAY);
}

static void threshold_updated(struct abx500_temp *data)
{
	int i;
	for (i = 0; i < data->monitored_sensors; i++)
		if (data->max[i] != 0 || data->min[i] != 0) {
			schedule_monitor(data);
			return;
		}

	dev_dbg(&data->pdev->dev, "No active thresholds.\n");
	cancel_delayed_work_sync(&data->work);
	data->work_active = false;
}

static void gpadc_monitor(struct work_struct *work)
{
	int temp, i, ret;
	char alarm_node[30];
	bool updated_min_alarm, updated_max_alarm;
	struct abx500_temp *data;

	data = container_of(work, struct abx500_temp, work.work);
	mutex_lock(&data->lock);

	for (i = 0; i < data->monitored_sensors; i++) {
		/* Thresholds are considered inactive if set to 0 */
		if (data->max[i] == 0 && data->min[i] == 0)
			continue;

		if (data->max[i] < data->min[i])
			continue;

		ret = data->ops.read_sensor(data, data->gpadc_addr[i], &temp);
		if (ret < 0) {
			dev_err(&data->pdev->dev, "GPADC read failed\n");
			continue;
		}

		updated_min_alarm = false;
		updated_max_alarm = false;

		if (data->min[i] != 0) {
			if (temp < data->min[i]) {
				if (data->min_alarm[i] == false) {
					data->min_alarm[i] = true;
					updated_min_alarm = true;
				}
			} else {
				if (data->min_alarm[i] == true) {
					data->min_alarm[i] = false;
					updated_min_alarm = true;
				}
			}
		}
		if (data->max[i] != 0) {
			if (temp > data->max[i]) {
				if (data->max_alarm[i] == false) {
					data->max_alarm[i] = true;
					updated_max_alarm = true;
				}
			} else if (temp < data->max[i] - data->max_hyst[i]) {
				if (data->max_alarm[i] == true) {
					data->max_alarm[i] = false;
					updated_max_alarm = true;
				}
			}
		}

		if (updated_min_alarm) {
			ret = sprintf(alarm_node, "temp%d_min_alarm", i + 1);
			sysfs_notify(&data->pdev->dev.kobj, NULL, alarm_node);
		}
		if (updated_max_alarm) {
			ret = sprintf(alarm_node, "temp%d_max_alarm", i + 1);
			sysfs_notify(&data->pdev->dev.kobj, NULL, alarm_node);
		}
	}

	schedule_monitor(data);
	mutex_unlock(&data->lock);
}

/* HWMON sysfs interfaces */
static ssize_t name_show(struct device *dev, struct device_attribute *devattr,
			 char *buf)
{
	struct abx500_temp *data = dev_get_drvdata(dev);
	/* Show chip name */
	return data->ops.show_name(dev, devattr, buf);
}

static ssize_t label_show(struct device *dev,
			  struct device_attribute *devattr, char *buf)
{
	struct abx500_temp *data = dev_get_drvdata(dev);
	/* Show each sensor label */
	return data->ops.show_label(dev, devattr, buf);
}

static ssize_t input_show(struct device *dev,
			  struct device_attribute *devattr, char *buf)
{
	int ret, temp;
	struct abx500_temp *data = dev_get_drvdata(dev);
	struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr);
	u8 gpadc_addr = data->gpadc_addr[attr->index];

	ret = data->ops.read_sensor(data, gpadc_addr, &temp);
	if (ret < 0)
		return ret;

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

/* Set functions (RW nodes) */
static ssize_t min_store(struct device *dev, struct device_attribute *devattr,
			 const char *buf, size_t count)
{
	unsigned long val;
	struct abx500_temp *data = dev_get_drvdata(dev);
	struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr);
	int res = kstrtol(buf, 10, &val);
	if (res < 0)
		return res;

	val = clamp_val(val, 0, DEFAULT_MAX_TEMP);

	mutex_lock(&data->lock);
	data->min[attr->index] = val;
	threshold_updated(data);
	mutex_unlock(&data->lock);

	return count;
}

static ssize_t max_store(struct device *dev, struct device_attribute *devattr,
			 const char *buf, size_t count)
{
	unsigned long val;
	struct abx500_temp *data = dev_get_drvdata(dev);
	struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr);
	int res = kstrtol(buf, 10, &val);
	if (res < 0)
		return res;

	val = clamp_val(val, 0, DEFAULT_MAX_TEMP);

	mutex_lock(&data->lock);
	data->max[attr->index] = val;
	threshold_updated(data);
	mutex_unlock(&data->lock);

	return count;
}

static ssize_t max_hyst_store(struct device *dev,
			      struct device_attribute *devattr,
			      const char *buf, size_t count)
{
	unsigned long val;
	struct abx500_temp *data = dev_get_drvdata(dev);
	struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr);
	int res = kstrtoul(buf, 10, &val);
	if (res < 0)
		return res;

	val = clamp_val(val, 0, DEFAULT_MAX_TEMP);

	mutex_lock(&data->lock);
	data->max_hyst[attr->index] = val;
	threshold_updated(data);
	mutex_unlock(&data->lock);

	return count;
}

/* Show functions (RO nodes) */
static ssize_t min_show(struct device *dev, struct device_attribute *devattr,
			char *buf)
{
	struct abx500_temp *data = dev_get_drvdata(dev);
	struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr);

	return sprintf(buf, "%lu\n", data->min[attr->index]);
}

static ssize_t max_show(struct device *dev, struct device_attribute *devattr,
			char *buf)
{
	struct abx500_temp *data = dev_get_drvdata(dev);
	struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr);

	return sprintf(buf, "%lu\n", data->max[attr->index]);
}

static ssize_t max_hyst_show(struct device *dev,
			     struct device_attribute *devattr, char *buf)
{
	struct abx500_temp *data = dev_get_drvdata(dev);
	struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr);

	return sprintf(buf, "%lu\n", data->max_hyst[attr->index]);
}

static ssize_t min_alarm_show(struct device *dev,
			      struct device_attribute *devattr, char *buf)
{
	struct abx500_temp *data = dev_get_drvdata(dev);
	struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr);

	return sprintf(buf, "%d\n", data->min_alarm[attr->index]);
}

static ssize_t max_alarm_show(struct device *dev,
			      struct device_attribute *devattr, char *buf)
{
	struct abx500_temp *data = dev_get_drvdata(dev);
	struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr);

	return sprintf(buf, "%d\n", data->max_alarm[attr->index]);
}

static umode_t abx500_attrs_visible(struct kobject *kobj,
				   struct attribute *attr, int n)
{
	struct device *dev = container_of(kobj, struct device, kobj);
	struct abx500_temp *data = dev_get_drvdata(dev);

	if (data->ops.is_visible)
		return data->ops.is_visible(attr, n);

	return attr->mode;
}

/* Chip name, required by hwmon */
static SENSOR_DEVICE_ATTR_RO(name, name, 0);

/* GPADC - SENSOR1 */
static SENSOR_DEVICE_ATTR_RO(temp1_label, label, 0);
static SENSOR_DEVICE_ATTR_RO(temp1_input, input, 0);
static SENSOR_DEVICE_ATTR_RW(temp1_min, min, 0);
static SENSOR_DEVICE_ATTR_RW(temp1_max, max, 0);
static SENSOR_DEVICE_ATTR_RW(temp1_max_hyst, max_hyst, 0);
static SENSOR_DEVICE_ATTR_RO(temp1_min_alarm, min_alarm, 0);
static SENSOR_DEVICE_ATTR_RO(temp1_max_alarm, max_alarm, 0);

/* GPADC - SENSOR2 */
static SENSOR_DEVICE_ATTR_RO(temp2_label, label, 1);
static SENSOR_DEVICE_ATTR_RO(temp2_input, input, 1);
static SENSOR_DEVICE_ATTR_RW(temp2_min, min, 1);
static SENSOR_DEVICE_ATTR_RW(temp2_max, max, 1);
static SENSOR_DEVICE_ATTR_RW(temp2_max_hyst, max_hyst, 1);
static SENSOR_DEVICE_ATTR_RO(temp2_min_alarm, min_alarm, 1);
static SENSOR_DEVICE_ATTR_RO(temp2_max_alarm, max_alarm, 1);

/* GPADC - SENSOR3 */
static SENSOR_DEVICE_ATTR_RO(temp3_label, label, 2);
static SENSOR_DEVICE_ATTR_RO(temp3_input, input, 2);
static SENSOR_DEVICE_ATTR_RW(temp3_min, min, 2);
static SENSOR_DEVICE_ATTR_RW(temp3_max, max, 2);
static SENSOR_DEVICE_ATTR_RW(temp3_max_hyst, max_hyst, 2);
static SENSOR_DEVICE_ATTR_RO(temp3_min_alarm, min_alarm, 2);
static SENSOR_DEVICE_ATTR_RO(temp3_max_alarm, max_alarm, 2);

/* GPADC - SENSOR4 */
static SENSOR_DEVICE_ATTR_RO(temp4_label, label, 3);
static SENSOR_DEVICE_ATTR_RO(temp4_input, input, 3);
static SENSOR_DEVICE_ATTR_RW(temp4_min, min, 3);
static SENSOR_DEVICE_ATTR_RW(temp4_max, max, 3);
static SENSOR_DEVICE_ATTR_RW(temp4_max_hyst, max_hyst, 3);
static SENSOR_DEVICE_ATTR_RO(temp4_min_alarm, min_alarm, 3);
static SENSOR_DEVICE_ATTR_RO(temp4_max_alarm, max_alarm, 3);

static struct attribute *abx500_temp_attributes[] = {
	&sensor_dev_attr_name.dev_attr.attr,

	&sensor_dev_attr_temp1_label.dev_attr.attr,
	&sensor_dev_attr_temp1_input.dev_attr.attr,
	&sensor_dev_attr_temp1_min.dev_attr.attr,
	&sensor_dev_attr_temp1_max.dev_attr.attr,
	&sensor_dev_attr_temp1_max_hyst.dev_attr.attr,
	&sensor_dev_attr_temp1_min_alarm.dev_attr.attr,
	&sensor_dev_attr_temp1_max_alarm.dev_attr.attr,

	&sensor_dev_attr_temp2_label.dev_attr.attr,
	&sensor_dev_attr_temp2_input.dev_attr.attr,
	&sensor_dev_attr_temp2_min.dev_attr.attr,
	&sensor_dev_attr_temp2_max.dev_attr.attr,
	&sensor_dev_attr_temp2_max_hyst.dev_attr.attr,
	&sensor_dev_attr_temp2_min_alarm.dev_attr.attr,
	&sensor_dev_attr_temp2_max_alarm.dev_attr.attr,

	&sensor_dev_attr_temp3_label.dev_attr.attr,
	&sensor_dev_attr_temp3_input.dev_attr.attr,
	&sensor_dev_attr_temp3_min.dev_attr.attr,
	&sensor_dev_attr_temp3_max.dev_attr.attr,
	&sensor_dev_attr_temp3_max_hyst.dev_attr.attr,
	&sensor_dev_attr_temp3_min_alarm.dev_attr.attr,
	&sensor_dev_attr_temp3_max_alarm.dev_attr.attr,

	&sensor_dev_attr_temp4_label.dev_attr.attr,
	&sensor_dev_attr_temp4_input.dev_attr.attr,
	&sensor_dev_attr_temp4_min.dev_attr.attr,
	&sensor_dev_attr_temp4_max.dev_attr.attr,
	&sensor_dev_attr_temp4_max_hyst.dev_attr.attr,
	&sensor_dev_attr_temp4_min_alarm.dev_attr.attr,
	&sensor_dev_attr_temp4_max_alarm.dev_attr.attr,
	NULL
};

static const struct attribute_group abx500_temp_group = {
	.attrs = abx500_temp_attributes,
	.is_visible = abx500_attrs_visible,
};

static irqreturn_t abx500_temp_irq_handler(int irq, void *irq_data)
{
	struct platform_device *pdev = irq_data;
	struct abx500_temp *data = platform_get_drvdata(pdev);

	data->ops.irq_handler(irq, data);
	return IRQ_HANDLED;
}

static int setup_irqs(struct platform_device *pdev)
{
	int ret;
	int irq = platform_get_irq_byname(pdev, "ABX500_TEMP_WARM");

	if (irq < 0) {
		dev_err(&pdev->dev, "Get irq by name failed\n");
		return irq;
	}

	ret = devm_request_threaded_irq(&pdev->dev, irq, NULL,
		abx500_temp_irq_handler, 0, "abx500-temp", pdev);
	if (ret < 0)
		dev_err(&pdev->dev, "Request threaded irq failed (%d)\n", ret);

	return ret;
}

static int abx500_temp_probe(struct platform_device *pdev)
{
	struct abx500_temp *data;
	int err;

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

	data->pdev = pdev;
	mutex_init(&data->lock);

	/* Chip specific initialization */
	err = abx500_hwmon_init(data);
	if (err	< 0 || !data->ops.read_sensor || !data->ops.show_name ||
			!data->ops.show_label)
		return err;

	INIT_DEFERRABLE_WORK(&data->work, gpadc_monitor);

	platform_set_drvdata(pdev, data);

	err = sysfs_create_group(&pdev->dev.kobj, &abx500_temp_group);
	if (err < 0) {
		dev_err(&pdev->dev, "Create sysfs group failed (%d)\n", err);
		return err;
	}

	data->hwmon_dev = hwmon_device_register(&pdev->dev);
	if (IS_ERR(data->hwmon_dev)) {
		err = PTR_ERR(data->hwmon_dev);
		dev_err(&pdev->dev, "Class registration failed (%d)\n", err);
		goto exit_sysfs_group;
	}

	if (data->ops.irq_handler) {
		err = setup_irqs(pdev);
		if (err < 0)
			goto exit_hwmon_reg;
	}
	return 0;

exit_hwmon_reg:
	hwmon_device_unregister(data->hwmon_dev);
exit_sysfs_group:
	sysfs_remove_group(&pdev->dev.kobj, &abx500_temp_group);
	return err;
}

static int abx500_temp_remove(struct platform_device *pdev)
{
	struct abx500_temp *data = platform_get_drvdata(pdev);

	cancel_delayed_work_sync(&data->work);
	hwmon_device_unregister(data->hwmon_dev);
	sysfs_remove_group(&pdev->dev.kobj, &abx500_temp_group);

	return 0;
}

static int abx500_temp_suspend(struct platform_device *pdev,
			       pm_message_t state)
{
	struct abx500_temp *data = platform_get_drvdata(pdev);

	if (data->work_active)
		cancel_delayed_work_sync(&data->work);

	return 0;
}

static int abx500_temp_resume(struct platform_device *pdev)
{
	struct abx500_temp *data = platform_get_drvdata(pdev);

	if (data->work_active)
		schedule_monitor(data);

	return 0;
}

#ifdef CONFIG_OF
static const struct of_device_id abx500_temp_match[] = {
	{ .compatible = "stericsson,abx500-temp" },
	{},
};
MODULE_DEVICE_TABLE(of, abx500_temp_match);
#endif

static struct platform_driver abx500_temp_driver = {
	.driver = {
		.name = "abx500-temp",
		.of_match_table = of_match_ptr(abx500_temp_match),
	},
	.suspend = abx500_temp_suspend,
	.resume = abx500_temp_resume,
	.probe = abx500_temp_probe,
	.remove = abx500_temp_remove,
};

module_platform_driver(abx500_temp_driver);

MODULE_AUTHOR("Martin Persson <martin.persson@stericsson.com>");
MODULE_DESCRIPTION("ABX500 temperature driver");
MODULE_LICENSE("GPL");
