/* Copyright (c) 2012-2019, The Linux Foundation. All rights reserved.
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License version 2 and
 * only 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.
 *
 */

#include <linux/module.h>
#include <linux/platform_device.h>
#include <linux/slab.h>
#include <linux/err.h>
#include <linux/of.h>
#include <linux/vmalloc.h>
#include "tsens.h"
#include "thermal_core.h"

#define TSENS_DRIVER_NAME			"msm-tsens"

#define TSENS_UPPER_LOWER_INTERRUPT_CTRL(n)		(n)
#define TSENS_INTERRUPT_EN		BIT(0)

#define TSENS_S0_UPPER_LOWER_STATUS_CTRL_ADDR(n)	((n) + 0x04)
#define TSENS_UPPER_STATUS_CLR		BIT(21)
#define TSENS_LOWER_STATUS_CLR		BIT(20)
#define TSENS_UPPER_THRESHOLD_MASK	0xffc00
#define TSENS_LOWER_THRESHOLD_MASK	0x3ff
#define TSENS_UPPER_THRESHOLD_SHIFT	10

#define TSENS_S0_STATUS_ADDR(n)		((n) + 0x30)
#define TSENS_S0_TRDY_ADDR(n)		((n) + 0x5c)
#define TSENS_SN_ADDR_OFFSET		0x4
#define TSENS_SN_STATUS_TEMP_MASK	0x3ff
#define TSENS_SN_STATUS_LOWER_STATUS	BIT(11)
#define TSENS_SN_STATUS_UPPER_STATUS	BIT(12)
#define TSENS_STATUS_ADDR_OFFSET			2

#define TSENS_TRDY_MASK			BIT(0)

#define TSENS_SN_STATUS_ADDR(n)	((n) + 0x44)
#define TSENS_SN_STATUS_VALID		BIT(14)
#define TSENS_SN_STATUS_VALID_MASK	0x4000
#define TSENS_TRDY_ADDR(n)		((n) + 0x84)

#define TSENS_CTRL_ADDR(n)		(n)
#define TSENS_EN				BIT(0)
#define TSENS_CTRL_SENSOR_EN_MASK(n)		((n >> 3) & 0x7ff)
#define TSENS_TRDY_RDY_MIN_TIME		2000
#define TSENS_TRDY_RDY_MAX_TIME		2100
#define TSENS_THRESHOLD_MAX_CODE	0x3ff
#define TSENS_THRESHOLD_MIN_CODE	0x0
#define TSENS_SCALE_MILLIDEG		1000

static int code_to_degc(u32 adc_code, const struct tsens_sensor *sensor)
{
	int degc, num, den;

	num = (adc_code * SLOPE_FACTOR) - sensor->offset;
	den = sensor->slope;

	if (num > 0)
		degc = num + (den / 2);
	else if (num < 0)
		degc = num - (den / 2);
	else
		degc = num;

	degc /= den;

	return degc;
}

static int degc_to_code(int degc, const struct tsens_sensor *sensor)
{
	int code = ((degc * sensor->slope)
		+ sensor->offset)/SLOPE_FACTOR;

	if (code > TSENS_THRESHOLD_MAX_CODE)
		code = TSENS_THRESHOLD_MAX_CODE;
	else if (code < TSENS_THRESHOLD_MIN_CODE)
		code = TSENS_THRESHOLD_MIN_CODE;
	pr_debug("raw_code:0x%x, degc:%d\n",
			code, degc);
	return code;
}

static int tsens1xxx_get_temp(struct tsens_sensor *sensor, int *temp)
{
	struct tsens_device *tmdev = NULL;
	unsigned int code;
	void __iomem *sensor_addr;
	void __iomem *trdy_addr;
	int last_temp = 0, last_temp2 = 0, last_temp3 = 0;
	bool last_temp_valid = false, last_temp2_valid = false;
	bool last_temp3_valid = false;

	if (!sensor)
		return -EINVAL;

	tmdev = sensor->tmdev;

	if ((tmdev->ctrl_data->ver_major == 1) &&
			(tmdev->ctrl_data->ver_minor == 1)) {
		trdy_addr = TSENS_S0_TRDY_ADDR(tmdev->tsens_tm_addr);
		sensor_addr = TSENS_S0_STATUS_ADDR(tmdev->tsens_tm_addr);

		if (!(tmdev->prev_reading_avail)) {
			while (!((readl_relaxed(trdy_addr)) & TSENS_TRDY_MASK))
				usleep_range(TSENS_TRDY_RDY_MIN_TIME,
						TSENS_TRDY_RDY_MAX_TIME);
			tmdev->prev_reading_avail = true;
		}
	} else {
		trdy_addr = TSENS_TRDY_ADDR(tmdev->tsens_tm_addr);
		sensor_addr = TSENS_SN_STATUS_ADDR(tmdev->tsens_tm_addr);
	}

	code = readl_relaxed(sensor_addr +
			(sensor->hw_id << TSENS_STATUS_ADDR_OFFSET));
	last_temp = code & TSENS_SN_STATUS_TEMP_MASK;

	if (tmdev->ctrl_data->valid_status_check) {
		if (code & TSENS_SN_STATUS_VALID)
			last_temp_valid = true;
		else {
			code = readl_relaxed(sensor_addr +
				(sensor->hw_id << TSENS_STATUS_ADDR_OFFSET));
			last_temp2 = code & TSENS_SN_STATUS_TEMP_MASK;
			if (code & TSENS_SN_STATUS_VALID) {
				last_temp = last_temp2;
				last_temp2_valid = true;
			} else {
				code = readl_relaxed(sensor_addr +
					(sensor->hw_id <<
					TSENS_STATUS_ADDR_OFFSET));
				last_temp3 = code & TSENS_SN_STATUS_TEMP_MASK;
				if (code & TSENS_SN_STATUS_VALID) {
					last_temp = last_temp3;
					last_temp3_valid = true;
				}
			}
		}
	}

	if ((tmdev->ctrl_data->valid_status_check) &&
		(!last_temp_valid && !last_temp2_valid && !last_temp3_valid)) {
		if (last_temp == last_temp2)
			last_temp = last_temp2;
		else if (last_temp2 == last_temp3)
			last_temp = last_temp3;
	}

	*temp = code_to_degc(last_temp, sensor);
	*temp = *temp * TSENS_SCALE_MILLIDEG;

	if (tmdev->ops->dbg)
		tmdev->ops->dbg(tmdev, (u32)sensor->hw_id,
				TSENS_DBG_LOG_TEMP_READS, temp);

	return 0;
}

static int tsens_tz_activate_trip_type(struct tsens_sensor *tm_sensor,
			int trip, enum thermal_trip_activation_mode mode)
{
	struct tsens_device *tmdev = NULL;
	unsigned int reg_cntl, code, hi_code, lo_code, mask;

	/* clear the interrupt and unmask */
	if (!tm_sensor || trip < 0)
		return -EINVAL;

	tmdev = tm_sensor->tmdev;
	if (!tmdev)
		return -EINVAL;

	lo_code = TSENS_THRESHOLD_MIN_CODE;
	hi_code = TSENS_THRESHOLD_MAX_CODE;

	reg_cntl = readl_relaxed((TSENS_S0_UPPER_LOWER_STATUS_CTRL_ADDR
					(tmdev->tsens_tm_addr) +
					(tm_sensor->hw_id *
					TSENS_SN_ADDR_OFFSET)));

	switch (trip) {
	case THERMAL_TRIP_CONFIGURABLE_HI:
		tmdev->sensor[tm_sensor->hw_id].thr_state.high_th_state = mode;

		code = (reg_cntl & TSENS_UPPER_THRESHOLD_MASK)
					>> TSENS_UPPER_THRESHOLD_SHIFT;
		mask = TSENS_UPPER_STATUS_CLR;

		if (!(reg_cntl & TSENS_LOWER_STATUS_CLR))
			lo_code = (reg_cntl & TSENS_LOWER_THRESHOLD_MASK);
		break;
	case THERMAL_TRIP_CONFIGURABLE_LOW:
		tmdev->sensor[tm_sensor->hw_id].thr_state.low_th_state = mode;

		code = (reg_cntl & TSENS_LOWER_THRESHOLD_MASK);
		mask = TSENS_LOWER_STATUS_CLR;

		if (!(reg_cntl & TSENS_UPPER_STATUS_CLR))
			hi_code = (reg_cntl & TSENS_UPPER_THRESHOLD_MASK)
					>> TSENS_UPPER_THRESHOLD_SHIFT;
		break;
	default:
		return -EINVAL;
	}

	if (mode == THERMAL_TRIP_ACTIVATION_DISABLED)
		writel_relaxed(reg_cntl | mask,
		(TSENS_S0_UPPER_LOWER_STATUS_CTRL_ADDR(tmdev->tsens_tm_addr) +
			(tm_sensor->hw_id * TSENS_SN_ADDR_OFFSET)));
	else
		writel_relaxed(reg_cntl & ~mask,
		(TSENS_S0_UPPER_LOWER_STATUS_CTRL_ADDR(tmdev->tsens_tm_addr) +
		(tm_sensor->hw_id * TSENS_SN_ADDR_OFFSET)));
	/* Enable the thresholds */
	mb();

	return 0;
}

static int tsens1xxx_set_trip_temp(struct tsens_sensor *tm_sensor,
						int low_temp, int high_temp)
{
	unsigned int reg_cntl;
	unsigned long flags;
	struct tsens_device *tmdev = NULL;
	int high_code, low_code, rc = 0;

	if (!tm_sensor)
		return -EINVAL;

	tmdev = tm_sensor->tmdev;
	if (!tmdev)
		return -EINVAL;

	spin_lock_irqsave(&tmdev->tsens_upp_low_lock, flags);

	if (high_temp != INT_MAX) {
		high_temp /= TSENS_SCALE_MILLIDEG;
		high_code = degc_to_code(high_temp, tm_sensor);
		tmdev->sensor[tm_sensor->hw_id].thr_state.high_adc_code =
							high_code;
		tmdev->sensor[tm_sensor->hw_id].thr_state.high_temp =
							high_temp;

		reg_cntl = readl_relaxed(TSENS_S0_UPPER_LOWER_STATUS_CTRL_ADDR
					(tmdev->tsens_tm_addr) +
					(tm_sensor->hw_id *
					 TSENS_SN_ADDR_OFFSET));

		high_code <<= TSENS_UPPER_THRESHOLD_SHIFT;
		reg_cntl &= ~TSENS_UPPER_THRESHOLD_MASK;
		writel_relaxed(reg_cntl | high_code,
				(TSENS_S0_UPPER_LOWER_STATUS_CTRL_ADDR
					(tmdev->tsens_tm_addr) +
					(tm_sensor->hw_id *
					TSENS_SN_ADDR_OFFSET)));
	}

	if (low_temp != INT_MIN) {
		low_temp /= TSENS_SCALE_MILLIDEG;
		low_code = degc_to_code(low_temp, tm_sensor);
		tmdev->sensor[tm_sensor->hw_id].thr_state.low_adc_code =
							low_code;
		tmdev->sensor[tm_sensor->hw_id].thr_state.low_temp =
							low_temp;

		reg_cntl = readl_relaxed(TSENS_S0_UPPER_LOWER_STATUS_CTRL_ADDR
					(tmdev->tsens_tm_addr) +
					(tm_sensor->hw_id *
					TSENS_SN_ADDR_OFFSET));

		reg_cntl &= ~TSENS_LOWER_THRESHOLD_MASK;
		writel_relaxed(reg_cntl | low_code,
				(TSENS_S0_UPPER_LOWER_STATUS_CTRL_ADDR
					(tmdev->tsens_tm_addr) +
					(tm_sensor->hw_id *
					TSENS_SN_ADDR_OFFSET)));
	}
	/* Set trip temperature thresholds */
	mb();

	if (high_temp != INT_MAX) {
		rc = tsens_tz_activate_trip_type(tm_sensor,
				THERMAL_TRIP_CONFIGURABLE_HI,
				THERMAL_TRIP_ACTIVATION_ENABLED);
		if (rc) {
			pr_err("trip high enable error :%d\n", rc);
			goto fail;
		}
	} else {
		rc = tsens_tz_activate_trip_type(tm_sensor,
				THERMAL_TRIP_CONFIGURABLE_HI,
				THERMAL_TRIP_ACTIVATION_DISABLED);
		if (rc) {
			pr_err("trip high disable error :%d\n", rc);
			goto fail;
		}
	}

	if (low_temp != INT_MIN) {
		rc = tsens_tz_activate_trip_type(tm_sensor,
				THERMAL_TRIP_CONFIGURABLE_LOW,
				THERMAL_TRIP_ACTIVATION_ENABLED);
		if (rc) {
			pr_err("trip low enable activation error :%d\n", rc);
			goto fail;
		}
	} else {
		rc = tsens_tz_activate_trip_type(tm_sensor,
				THERMAL_TRIP_CONFIGURABLE_LOW,
				THERMAL_TRIP_ACTIVATION_DISABLED);
		if (rc) {
			pr_err("trip low disable error :%d\n", rc);
			goto fail;
		}
	}

fail:
	spin_unlock_irqrestore(&tmdev->tsens_upp_low_lock, flags);
	return rc;
}

static irqreturn_t tsens_irq_thread(int irq, void *data)
{
	struct tsens_device *tm = data;
	unsigned int i, status, threshold, temp, th_temp;
	unsigned long flags;
	void __iomem *sensor_status_addr;
	void __iomem *sensor_status_ctrl_addr;
	u32 rc = 0, addr_offset;


	if ((tm->ctrl_data->ver_major == 1) &&
			(tm->ctrl_data->ver_minor == 1))
		sensor_status_addr = TSENS_S0_STATUS_ADDR(tm->tsens_tm_addr);
	else
		sensor_status_addr = TSENS_SN_STATUS_ADDR(tm->tsens_tm_addr);

	sensor_status_ctrl_addr =
		TSENS_S0_UPPER_LOWER_STATUS_CTRL_ADDR(tm->tsens_tm_addr);

	for (i = 0; i < tm->ctrl_data->num_sensors; i++) {
		bool upper_thr = false, lower_thr = false;

		if (IS_ERR(tm->sensor[i].tzd))
			continue;

		rc = tsens1xxx_get_temp(&tm->sensor[i], &temp);
		if (rc) {
			pr_debug("Error:%d reading temp sensor:%d\n", rc, i);
			continue;
		}

		spin_lock_irqsave(&tm->tsens_upp_low_lock, flags);

		addr_offset = tm->sensor[i].hw_id *
						TSENS_SN_ADDR_OFFSET;
		status = readl_relaxed(sensor_status_addr + addr_offset);
		threshold = readl_relaxed(sensor_status_ctrl_addr +
								addr_offset);

		if (status & TSENS_SN_STATUS_UPPER_STATUS) {
			writel_relaxed(threshold | TSENS_UPPER_STATUS_CLR,
				TSENS_S0_UPPER_LOWER_STATUS_CTRL_ADDR(
					tm->tsens_tm_addr + addr_offset));
			th_temp = code_to_degc((threshold &
					TSENS_UPPER_THRESHOLD_MASK) >>
					TSENS_UPPER_THRESHOLD_SHIFT,
					(tm->sensor + i));
			if (th_temp > (temp/TSENS_SCALE_MILLIDEG)) {
				pr_debug("Re-arm high threshold\n");
				rc = tsens_tz_activate_trip_type(
					&tm->sensor[i],
					THERMAL_TRIP_CONFIGURABLE_HI,
					THERMAL_TRIP_ACTIVATION_ENABLED);
				if (rc)
					pr_err("high rearm failed");
			} else {
				upper_thr = true;
				tm->sensor[i].thr_state.high_th_state =
					THERMAL_TRIP_ACTIVATION_DISABLED;
			}
		}

		if (status & TSENS_SN_STATUS_LOWER_STATUS) {
			writel_relaxed(threshold | TSENS_LOWER_STATUS_CLR,
				TSENS_S0_UPPER_LOWER_STATUS_CTRL_ADDR(
					tm->tsens_tm_addr + addr_offset));
			th_temp = code_to_degc((threshold &
					TSENS_LOWER_THRESHOLD_MASK),
					(tm->sensor + i));
			if (th_temp < (temp/TSENS_SCALE_MILLIDEG)) {
				pr_debug("Re-arm Low threshold\n");
				rc = tsens_tz_activate_trip_type(
					&tm->sensor[i],
					THERMAL_TRIP_CONFIGURABLE_LOW,
					THERMAL_TRIP_ACTIVATION_ENABLED);
				if (rc)
					pr_err("low rearm failed");
			} else {
				lower_thr = true;
				tm->sensor[i].thr_state.low_th_state =
					THERMAL_TRIP_ACTIVATION_DISABLED;
			}
		}
		spin_unlock_irqrestore(&tm->tsens_upp_low_lock, flags);

		if (upper_thr || lower_thr) {
			pr_debug("sensor:%d trigger temp (%d degC)\n",
				tm->sensor[i].hw_id,
				code_to_degc((status &
				TSENS_SN_STATUS_TEMP_MASK),
				tm->sensor));
			of_thermal_handle_trip(tm->sensor[i].tzd);
		}
	}

	/* Disable monitoring sensor trip threshold for triggered sensor */
	mb();

	if (tm->ops->dbg)
		tm->ops->dbg(tm, 0, TSENS_DBG_LOG_INTERRUPT_TIMESTAMP, NULL);

	return IRQ_HANDLED;
}

static int tsens1xxx_hw_sensor_en(struct tsens_device *tmdev,
					u32 sensor_id)
{
	void __iomem *srot_addr;
	unsigned int srot_val, sensor_en;

	if ((tmdev->ctrl_data->ver_major == 1) &&
			(tmdev->ctrl_data->ver_minor == 1))
		srot_addr = TSENS_CTRL_ADDR(tmdev->tsens_srot_addr);
	else
		srot_addr = TSENS_CTRL_ADDR(tmdev->tsens_srot_addr + 0x4);

	srot_val = readl_relaxed(srot_addr);
	srot_val = TSENS_CTRL_SENSOR_EN_MASK(srot_val);

	sensor_en = ((1 << sensor_id) & srot_val);

	return sensor_en;
}

static int tsens1xxx_hw_init(struct tsens_device *tmdev)
{
	void __iomem *srot_addr;
	unsigned int srot_val;

	if ((tmdev->ctrl_data->ver_major == 1) &&
			(tmdev->ctrl_data->ver_minor == 1))
		srot_addr = TSENS_CTRL_ADDR(tmdev->tsens_srot_addr);
	else
		srot_addr = TSENS_CTRL_ADDR(tmdev->tsens_srot_addr + 0x4);

	srot_val = readl_relaxed(srot_addr);
	if (!(srot_val & TSENS_EN)) {
		pr_err("TSENS device is not enabled\n");
		return -ENODEV;
	}

	writel_relaxed(TSENS_INTERRUPT_EN,
			TSENS_UPPER_LOWER_INTERRUPT_CTRL(tmdev->tsens_tm_addr));

	spin_lock_init(&tmdev->tsens_upp_low_lock);

	if (tmdev->ctrl_data->mtc) {
		if (tmdev->ops->dbg)
			tmdev->ops->dbg(tmdev, 0, TSENS_DBG_MTC_DATA, NULL);
	}

	return 0;
}

static const struct tsens_irqs tsens1xxx_irqs[] = {
	{ "tsens-upper-lower", tsens_irq_thread},
};

static int tsens1xxx_register_interrupts(struct tsens_device *tmdev)
{
	struct platform_device *pdev;
	int i, rc;

	if (!tmdev)
		return -EINVAL;

	pdev = tmdev->pdev;

	for (i = 0; i < ARRAY_SIZE(tsens1xxx_irqs); i++) {
		int irq;

		irq = platform_get_irq_byname(pdev, tsens1xxx_irqs[i].name);
		if (irq < 0) {
			dev_err(&pdev->dev, "failed to get irq %s\n",
					tsens1xxx_irqs[i].name);
			return irq;
		}

		rc = devm_request_threaded_irq(&pdev->dev, irq, NULL,
				tsens1xxx_irqs[i].handler,
				IRQF_TRIGGER_HIGH | IRQF_ONESHOT,
				tsens1xxx_irqs[i].name, tmdev);
		if (rc) {
			dev_err(&pdev->dev, "failed to get irq %s\n",
					tsens1xxx_irqs[i].name);
			return rc;
		}
		enable_irq_wake(irq);
	}

	return 0;
}

static const struct tsens_ops ops_tsens1xxx = {
	.hw_init		= tsens1xxx_hw_init,
	.get_temp		= tsens1xxx_get_temp,
	.set_trips		= tsens1xxx_set_trip_temp,
	.interrupts_reg	= tsens1xxx_register_interrupts,
	.sensor_en		= tsens1xxx_hw_sensor_en,
	.calibrate		= calibrate_8937,
	.dbg            = tsens2xxx_dbg,
};

const struct tsens_data data_tsens14xx = {
	.num_sensors = TSENS_NUM_SENSORS_8937,
	.ops = &ops_tsens1xxx,
	.valid_status_check = true,
	.mtc = true,
	.ver_major = 1,
	.ver_minor = 4,
};

static const struct tsens_ops ops_tsens1xxx_8909 = {
	.hw_init		= tsens1xxx_hw_init,
	.get_temp		= tsens1xxx_get_temp,
	.set_trips		= tsens1xxx_set_trip_temp,
	.interrupts_reg	= tsens1xxx_register_interrupts,
	.sensor_en		= tsens1xxx_hw_sensor_en,
	.calibrate		= calibrate_8909,
	.dbg			= tsens2xxx_dbg,
};

const struct tsens_data data_tsens1xxx_8909 = {
	.num_sensors = TSENS_NUM_SENSORS_8909,
	.ops = &ops_tsens1xxx_8909,
	.ver_major = 1,
	.ver_minor = 1,
};
