/*
 * 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
 *
 * When the AB8500 thermal warning temperature is reached (threshold cannot
 * be changed by SW), an interrupt is set, and if no further action is taken
 * within a certain time frame, pm_power off will be called.
 *
 * When AB8500 thermal shutdown temperature is reached a hardware shutdown of
 * the AB8500 will occur.
 */

#include <linux/err.h>
#include <linux/hwmon.h>
#include <linux/hwmon-sysfs.h>
#include <linux/mfd/abx500.h>
#include <linux/mfd/abx500/ab8500-bm.h>
#include <linux/mfd/abx500/ab8500-gpadc.h>
#include <linux/module.h>
#include <linux/platform_device.h>
#include <linux/power/ab8500.h>
#include <linux/slab.h>
#include <linux/sysfs.h>
#include "abx500.h"

#define DEFAULT_POWER_OFF_DELAY	(HZ * 10)
#define THERMAL_VCC		1800
#define PULL_UP_RESISTOR	47000
/* Number of monitored sensors should not greater than NUM_SENSORS */
#define NUM_MONITORED_SENSORS	4

struct ab8500_gpadc_cfg {
	const struct abx500_res_to_temp *temp_tbl;
	int tbl_sz;
	int vcc;
	int r_up;
};

struct ab8500_temp {
	struct ab8500_gpadc *gpadc;
	struct ab8500_btemp *btemp;
	struct delayed_work power_off_work;
	struct ab8500_gpadc_cfg cfg;
	struct abx500_temp *abx500_data;
};

/*
 * The hardware connection is like this:
 * VCC----[ R_up ]-----[ NTC ]----GND
 * where R_up is pull-up resistance, and GPADC measures voltage on NTC.
 * and res_to_temp table is strictly sorted by falling resistance values.
 */
static int ab8500_voltage_to_temp(struct ab8500_gpadc_cfg *cfg,
		int v_ntc, int *temp)
{
	int r_ntc, i = 0, tbl_sz = cfg->tbl_sz;
	const struct abx500_res_to_temp *tbl = cfg->temp_tbl;

	if (cfg->vcc < 0 || v_ntc >= cfg->vcc)
		return -EINVAL;

	r_ntc = v_ntc * cfg->r_up / (cfg->vcc - v_ntc);
	if (r_ntc > tbl[0].resist || r_ntc < tbl[tbl_sz - 1].resist)
		return -EINVAL;

	while (!(r_ntc <= tbl[i].resist && r_ntc > tbl[i + 1].resist) &&
			i < tbl_sz - 2)
		i++;

	/* return milli-Celsius */
	*temp = tbl[i].temp * 1000 + ((tbl[i + 1].temp - tbl[i].temp) * 1000 *
		(r_ntc - tbl[i].resist)) / (tbl[i + 1].resist - tbl[i].resist);

	return 0;
}

static int ab8500_read_sensor(struct abx500_temp *data, u8 sensor, int *temp)
{
	int voltage, ret;
	struct ab8500_temp *ab8500_data = data->plat_data;

	if (sensor == BAT_CTRL) {
		*temp = ab8500_btemp_get_batctrl_temp(ab8500_data->btemp);
	} else if (sensor == BTEMP_BALL) {
		*temp = ab8500_btemp_get_temp(ab8500_data->btemp);
	} else {
		voltage = ab8500_gpadc_convert(ab8500_data->gpadc, sensor);
		if (voltage < 0)
			return voltage;

		ret = ab8500_voltage_to_temp(&ab8500_data->cfg, voltage, temp);
		if (ret < 0)
			return ret;
	}

	return 0;
}

static void ab8500_thermal_power_off(struct work_struct *work)
{
	struct ab8500_temp *ab8500_data = container_of(work,
				struct ab8500_temp, power_off_work.work);
	struct abx500_temp *abx500_data = ab8500_data->abx500_data;

	dev_warn(&abx500_data->pdev->dev, "Power off due to critical temp\n");

	pm_power_off();
}

static ssize_t ab8500_show_name(struct device *dev,
		struct device_attribute *devattr, char *buf)
{
	return sprintf(buf, "ab8500\n");
}

static ssize_t ab8500_show_label(struct device *dev,
		struct device_attribute *devattr, char *buf)
{
	char *label;
	struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr);
	int index = attr->index;

	switch (index) {
	case 1:
		label = "ext_adc1";
		break;
	case 2:
		label = "ext_adc2";
		break;
	case 3:
		label = "bat_temp";
		break;
	case 4:
		label = "bat_ctrl";
		break;
	default:
		return -EINVAL;
	}

	return sprintf(buf, "%s\n", label);
}

static int ab8500_temp_irq_handler(int irq, struct abx500_temp *data)
{
	struct ab8500_temp *ab8500_data = data->plat_data;

	dev_warn(&data->pdev->dev, "Power off in %d s\n",
		 DEFAULT_POWER_OFF_DELAY / HZ);

	schedule_delayed_work(&ab8500_data->power_off_work,
		DEFAULT_POWER_OFF_DELAY);
	return 0;
}

int abx500_hwmon_init(struct abx500_temp *data)
{
	struct ab8500_temp *ab8500_data;

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

	ab8500_data->gpadc = ab8500_gpadc_get("ab8500-gpadc.0");
	if (IS_ERR(ab8500_data->gpadc))
		return PTR_ERR(ab8500_data->gpadc);

	ab8500_data->btemp = ab8500_btemp_get();
	if (IS_ERR(ab8500_data->btemp))
		return PTR_ERR(ab8500_data->btemp);

	INIT_DELAYED_WORK(&ab8500_data->power_off_work,
			  ab8500_thermal_power_off);

	ab8500_data->cfg.vcc = THERMAL_VCC;
	ab8500_data->cfg.r_up = PULL_UP_RESISTOR;
	ab8500_data->cfg.temp_tbl = ab8500_temp_tbl_a_thermistor;
	ab8500_data->cfg.tbl_sz = ab8500_temp_tbl_a_size;

	data->plat_data = ab8500_data;

	/*
	 * ADC_AUX1 and ADC_AUX2, connected to external NTC
	 * BTEMP_BALL and BAT_CTRL, fixed usage
	 */
	data->gpadc_addr[0] = ADC_AUX1;
	data->gpadc_addr[1] = ADC_AUX2;
	data->gpadc_addr[2] = BTEMP_BALL;
	data->gpadc_addr[3] = BAT_CTRL;
	data->monitored_sensors = NUM_MONITORED_SENSORS;

	data->ops.read_sensor = ab8500_read_sensor;
	data->ops.irq_handler = ab8500_temp_irq_handler;
	data->ops.show_name = ab8500_show_name;
	data->ops.show_label = ab8500_show_label;
	data->ops.is_visible = NULL;

	return 0;
}
EXPORT_SYMBOL(abx500_hwmon_init);

MODULE_AUTHOR("Hongbo Zhang <hongbo.zhang@linaro.org>");
MODULE_DESCRIPTION("AB8500 temperature driver");
MODULE_LICENSE("GPL");
