/*
 * ntc_thermistor.c - NTC Thermistors
 *
 *  Copyright (C) 2010 Samsung Electronics
 *  MyungJoo Ham <myungjoo.ham@samsung.com>
 *
 * 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; either version 2 of the License, or
 * (at your option) any later version.
 *
 * 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., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 *
 */

#include <linux/slab.h>
#include <linux/module.h>
#include <linux/pm_runtime.h>
#include <linux/math64.h>
#include <linux/platform_device.h>
#include <linux/err.h>

#include <linux/platform_data/ntc_thermistor.h>

#include <linux/hwmon.h>
#include <linux/hwmon-sysfs.h>

struct ntc_compensation {
	int		temp_C;
	unsigned int	ohm;
};

/*
 * A compensation table should be sorted by the values of .ohm
 * in descending order.
 * The following compensation tables are from the specification of Murata NTC
 * Thermistors Datasheet
 */
static const struct ntc_compensation ncpXXwb473[] = {
	{ .temp_C	= -40, .ohm	= 1747920 },
	{ .temp_C	= -35, .ohm	= 1245428 },
	{ .temp_C	= -30, .ohm	= 898485 },
	{ .temp_C	= -25, .ohm	= 655802 },
	{ .temp_C	= -20, .ohm	= 483954 },
	{ .temp_C	= -15, .ohm	= 360850 },
	{ .temp_C	= -10, .ohm	= 271697 },
	{ .temp_C	= -5, .ohm	= 206463 },
	{ .temp_C	= 0, .ohm	= 158214 },
	{ .temp_C	= 5, .ohm	= 122259 },
	{ .temp_C	= 10, .ohm	= 95227 },
	{ .temp_C	= 15, .ohm	= 74730 },
	{ .temp_C	= 20, .ohm	= 59065 },
	{ .temp_C	= 25, .ohm	= 47000 },
	{ .temp_C	= 30, .ohm	= 37643 },
	{ .temp_C	= 35, .ohm	= 30334 },
	{ .temp_C	= 40, .ohm	= 24591 },
	{ .temp_C	= 45, .ohm	= 20048 },
	{ .temp_C	= 50, .ohm	= 16433 },
	{ .temp_C	= 55, .ohm	= 13539 },
	{ .temp_C	= 60, .ohm	= 11209 },
	{ .temp_C	= 65, .ohm	= 9328 },
	{ .temp_C	= 70, .ohm	= 7798 },
	{ .temp_C	= 75, .ohm	= 6544 },
	{ .temp_C	= 80, .ohm	= 5518 },
	{ .temp_C	= 85, .ohm	= 4674 },
	{ .temp_C	= 90, .ohm	= 3972 },
	{ .temp_C	= 95, .ohm	= 3388 },
	{ .temp_C	= 100, .ohm	= 2902 },
	{ .temp_C	= 105, .ohm	= 2494 },
	{ .temp_C	= 110, .ohm	= 2150 },
	{ .temp_C	= 115, .ohm	= 1860 },
	{ .temp_C	= 120, .ohm	= 1615 },
	{ .temp_C	= 125, .ohm	= 1406 },
};
static const struct ntc_compensation ncpXXwl333[] = {
	{ .temp_C	= -40, .ohm	= 1610154 },
	{ .temp_C	= -35, .ohm	= 1130850 },
	{ .temp_C	= -30, .ohm	= 802609 },
	{ .temp_C	= -25, .ohm	= 575385 },
	{ .temp_C	= -20, .ohm	= 416464 },
	{ .temp_C	= -15, .ohm	= 304219 },
	{ .temp_C	= -10, .ohm	= 224193 },
	{ .temp_C	= -5, .ohm	= 166623 },
	{ .temp_C	= 0, .ohm	= 124850 },
	{ .temp_C	= 5, .ohm	= 94287 },
	{ .temp_C	= 10, .ohm	= 71747 },
	{ .temp_C	= 15, .ohm	= 54996 },
	{ .temp_C	= 20, .ohm	= 42455 },
	{ .temp_C	= 25, .ohm	= 33000 },
	{ .temp_C	= 30, .ohm	= 25822 },
	{ .temp_C	= 35, .ohm	= 20335 },
	{ .temp_C	= 40, .ohm	= 16115 },
	{ .temp_C	= 45, .ohm	= 12849 },
	{ .temp_C	= 50, .ohm	= 10306 },
	{ .temp_C	= 55, .ohm	= 8314 },
	{ .temp_C	= 60, .ohm	= 6746 },
	{ .temp_C	= 65, .ohm	= 5503 },
	{ .temp_C	= 70, .ohm	= 4513 },
	{ .temp_C	= 75, .ohm	= 3721 },
	{ .temp_C	= 80, .ohm	= 3084 },
	{ .temp_C	= 85, .ohm	= 2569 },
	{ .temp_C	= 90, .ohm	= 2151 },
	{ .temp_C	= 95, .ohm	= 1809 },
	{ .temp_C	= 100, .ohm	= 1529 },
	{ .temp_C	= 105, .ohm	= 1299 },
	{ .temp_C	= 110, .ohm	= 1108 },
	{ .temp_C	= 115, .ohm	= 949 },
	{ .temp_C	= 120, .ohm	= 817 },
	{ .temp_C	= 125, .ohm	= 707 },
};

struct ntc_data {
	struct device *hwmon_dev;
	struct ntc_thermistor_platform_data *pdata;
	const struct ntc_compensation *comp;
	struct device *dev;
	int n_comp;
	char name[PLATFORM_NAME_SIZE];
};

static inline u64 div64_u64_safe(u64 dividend, u64 divisor)
{
	if (divisor == 0 && dividend == 0)
		return 0;
	if (divisor == 0)
		return UINT_MAX;
	return div64_u64(dividend, divisor);
}

static int get_ohm_of_thermistor(struct ntc_data *data, unsigned int uV)
{
	struct ntc_thermistor_platform_data *pdata = data->pdata;
	u64 mV = uV / 1000;
	u64 pmV = pdata->pullup_uV / 1000;
	u64 N, puO, pdO;
	puO = pdata->pullup_ohm;
	pdO = pdata->pulldown_ohm;

	if (mV == 0) {
		if (pdata->connect == NTC_CONNECTED_POSITIVE)
			return INT_MAX;
		return 0;
	}
	if (mV >= pmV)
		return (pdata->connect == NTC_CONNECTED_POSITIVE) ?
			0 : INT_MAX;

	if (pdata->connect == NTC_CONNECTED_POSITIVE && puO == 0)
		N = div64_u64_safe(pdO * (pmV - mV), mV);
	else if (pdata->connect == NTC_CONNECTED_GROUND && pdO == 0)
		N = div64_u64_safe(puO * mV, pmV - mV);
	else if (pdata->connect == NTC_CONNECTED_POSITIVE)
		N = div64_u64_safe(pdO * puO * (pmV - mV),
				puO * mV - pdO * (pmV - mV));
	else
		N = div64_u64_safe(pdO * puO * mV, pdO * (pmV - mV) - puO * mV);

	if (N > INT_MAX)
		N = INT_MAX;
	return N;
}

static void lookup_comp(struct ntc_data *data, unsigned int ohm,
			int *i_low, int *i_high)
{
	int start, end, mid;

	/*
	 * Handle special cases: Resistance is higher than or equal to
	 * resistance in first table entry, or resistance is lower or equal
	 * to resistance in last table entry.
	 * In these cases, return i_low == i_high, either pointing to the
	 * beginning or to the end of the table depending on the condition.
	 */
	if (ohm >= data->comp[0].ohm) {
		*i_low = 0;
		*i_high = 0;
		return;
	}
	if (ohm <= data->comp[data->n_comp - 1].ohm) {
		*i_low = data->n_comp - 1;
		*i_high = data->n_comp - 1;
		return;
	}

	/* Do a binary search on compensation table */
	start = 0;
	end = data->n_comp;
	while (start < end) {
		mid = start + (end - start) / 2;
		/*
		 * start <= mid < end
		 * data->comp[start].ohm > ohm >= data->comp[end].ohm
		 *
		 * We could check for "ohm == data->comp[mid].ohm" here, but
		 * that is a quite unlikely condition, and we would have to
		 * check again after updating start. Check it at the end instead
		 * for simplicity.
		 */
		if (ohm >= data->comp[mid].ohm) {
			end = mid;
		} else {
			start = mid + 1;
			/*
			 * ohm >= data->comp[start].ohm might be true here,
			 * since we set start to mid + 1. In that case, we are
			 * done. We could keep going, but the condition is quite
			 * likely to occur, so it is worth checking for it.
			 */
			if (ohm >= data->comp[start].ohm)
				end = start;
		}
		/*
		 * start <= end
		 * data->comp[start].ohm >= ohm >= data->comp[end].ohm
		 */
	}
	/*
	 * start == end
	 * ohm >= data->comp[end].ohm
	 */
	*i_low = end;
	if (ohm == data->comp[end].ohm)
		*i_high = end;
	else
		*i_high = end - 1;
}

static int get_temp_mC(struct ntc_data *data, unsigned int ohm)
{
	int low, high;
	int temp;

	lookup_comp(data, ohm, &low, &high);
	if (low == high) {
		/* Unable to use linear approximation */
		temp = data->comp[low].temp_C * 1000;
	} else {
		temp = data->comp[low].temp_C * 1000 +
			((data->comp[high].temp_C - data->comp[low].temp_C) *
			 1000 * ((int)ohm - (int)data->comp[low].ohm)) /
			((int)data->comp[high].ohm - (int)data->comp[low].ohm);
	}
	return temp;
}

static int ntc_thermistor_get_ohm(struct ntc_data *data)
{
	int read_uV;

	if (data->pdata->read_ohm)
		return data->pdata->read_ohm();

	if (data->pdata->read_uV) {
		read_uV = data->pdata->read_uV();
		if (read_uV < 0)
			return read_uV;
		return get_ohm_of_thermistor(data, read_uV);
	}
	return -EINVAL;
}

static ssize_t ntc_show_name(struct device *dev,
		struct device_attribute *attr, char *buf)
{
	struct ntc_data *data = dev_get_drvdata(dev);

	return sprintf(buf, "%s\n", data->name);
}

static ssize_t ntc_show_type(struct device *dev,
		struct device_attribute *attr, char *buf)
{
	return sprintf(buf, "4\n");
}

static ssize_t ntc_show_temp(struct device *dev,
		struct device_attribute *attr, char *buf)
{
	struct ntc_data *data = dev_get_drvdata(dev);
	int ohm;

	ohm = ntc_thermistor_get_ohm(data);
	if (ohm < 0)
		return ohm;

	return sprintf(buf, "%d\n", get_temp_mC(data, ohm));
}

static SENSOR_DEVICE_ATTR(temp1_type, S_IRUGO, ntc_show_type, NULL, 0);
static SENSOR_DEVICE_ATTR(temp1_input, S_IRUGO, ntc_show_temp, NULL, 0);
static DEVICE_ATTR(name, S_IRUGO, ntc_show_name, NULL);

static struct attribute *ntc_attributes[] = {
	&dev_attr_name.attr,
	&sensor_dev_attr_temp1_type.dev_attr.attr,
	&sensor_dev_attr_temp1_input.dev_attr.attr,
	NULL,
};

static const struct attribute_group ntc_attr_group = {
	.attrs = ntc_attributes,
};

static int ntc_thermistor_probe(struct platform_device *pdev)
{
	struct ntc_data *data;
	struct ntc_thermistor_platform_data *pdata = pdev->dev.platform_data;
	int ret = 0;

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

	/* Either one of the two is required. */
	if (!pdata->read_uV && !pdata->read_ohm) {
		dev_err(&pdev->dev,
			"Both read_uV and read_ohm missing. Need either one of the two.\n");
		return -EINVAL;
	}

	if (pdata->read_uV && pdata->read_ohm) {
		dev_warn(&pdev->dev,
			 "Only one of read_uV and read_ohm is needed; ignoring read_uV.\n");
		pdata->read_uV = NULL;
	}

	if (pdata->read_uV && (pdata->pullup_uV == 0 ||
				(pdata->pullup_ohm == 0 && pdata->connect ==
				 NTC_CONNECTED_GROUND) ||
				(pdata->pulldown_ohm == 0 && pdata->connect ==
				 NTC_CONNECTED_POSITIVE) ||
				(pdata->connect != NTC_CONNECTED_POSITIVE &&
				 pdata->connect != NTC_CONNECTED_GROUND))) {
		dev_err(&pdev->dev,
			"Required data to use read_uV not supplied.\n");
		return -EINVAL;
	}

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

	data->dev = &pdev->dev;
	data->pdata = pdata;
	strlcpy(data->name, pdev->id_entry->name, sizeof(data->name));

	switch (pdev->id_entry->driver_data) {
	case TYPE_NCPXXWB473:
		data->comp = ncpXXwb473;
		data->n_comp = ARRAY_SIZE(ncpXXwb473);
		break;
	case TYPE_NCPXXWL333:
		data->comp = ncpXXwl333;
		data->n_comp = ARRAY_SIZE(ncpXXwl333);
		break;
	default:
		dev_err(&pdev->dev, "Unknown device type: %lu(%s)\n",
				pdev->id_entry->driver_data,
				pdev->id_entry->name);
		return -EINVAL;
	}

	platform_set_drvdata(pdev, data);

	ret = sysfs_create_group(&data->dev->kobj, &ntc_attr_group);
	if (ret) {
		dev_err(data->dev, "unable to create sysfs files\n");
		return ret;
	}

	data->hwmon_dev = hwmon_device_register(data->dev);
	if (IS_ERR(data->hwmon_dev)) {
		dev_err(data->dev, "unable to register as hwmon device.\n");
		ret = PTR_ERR(data->hwmon_dev);
		goto err_after_sysfs;
	}

	dev_info(&pdev->dev, "Thermistor %s:%d (type: %s/%lu) successfully probed.\n",
			pdev->name, pdev->id, pdev->id_entry->name,
			pdev->id_entry->driver_data);
	return 0;
err_after_sysfs:
	sysfs_remove_group(&data->dev->kobj, &ntc_attr_group);
	return ret;
}

static int ntc_thermistor_remove(struct platform_device *pdev)
{
	struct ntc_data *data = platform_get_drvdata(pdev);

	hwmon_device_unregister(data->hwmon_dev);
	sysfs_remove_group(&data->dev->kobj, &ntc_attr_group);
	platform_set_drvdata(pdev, NULL);

	return 0;
}

static const struct platform_device_id ntc_thermistor_id[] = {
	{ "ncp15wb473", TYPE_NCPXXWB473 },
	{ "ncp18wb473", TYPE_NCPXXWB473 },
	{ "ncp21wb473", TYPE_NCPXXWB473 },
	{ "ncp03wb473", TYPE_NCPXXWB473 },
	{ "ncp15wl333", TYPE_NCPXXWL333 },
	{ },
};

static struct platform_driver ntc_thermistor_driver = {
	.driver = {
		.name = "ntc-thermistor",
		.owner = THIS_MODULE,
	},
	.probe = ntc_thermistor_probe,
	.remove = ntc_thermistor_remove,
	.id_table = ntc_thermistor_id,
};

module_platform_driver(ntc_thermistor_driver);

MODULE_DESCRIPTION("NTC Thermistor Driver");
MODULE_AUTHOR("MyungJoo Ham <myungjoo.ham@samsung.com>");
MODULE_LICENSE("GPL");
MODULE_ALIAS("platform:ntc-thermistor");
