// SPDX-License-Identifier: GPL-2.0
/*
 * Copyright (C) 2020 MaxLinear, Inc.
 *
 * This driver is a hardware monitoring driver for PVT controller
 * (MR75203) which is used to configure & control Moortec embedded
 * analog IP to enable multiple embedded temperature sensor(TS),
 * voltage monitor(VM) & process detector(PD) modules.
 */
#include <linux/bits.h>
#include <linux/clk.h>
#include <linux/hwmon.h>
#include <linux/module.h>
#include <linux/mod_devicetable.h>
#include <linux/mutex.h>
#include <linux/platform_device.h>
#include <linux/property.h>
#include <linux/regmap.h>
#include <linux/reset.h>
#include <linux/units.h>

/* PVT Common register */
#define PVT_IP_CONFIG	0x04
#define TS_NUM_MSK	GENMASK(4, 0)
#define TS_NUM_SFT	0
#define PD_NUM_MSK	GENMASK(12, 8)
#define PD_NUM_SFT	8
#define VM_NUM_MSK	GENMASK(20, 16)
#define VM_NUM_SFT	16
#define CH_NUM_MSK	GENMASK(31, 24)
#define CH_NUM_SFT	24

/* Macro Common Register */
#define CLK_SYNTH		0x00
#define CLK_SYNTH_LO_SFT	0
#define CLK_SYNTH_HI_SFT	8
#define CLK_SYNTH_HOLD_SFT	16
#define CLK_SYNTH_EN		BIT(24)
#define CLK_SYS_CYCLES_MAX	514
#define CLK_SYS_CYCLES_MIN	2

#define SDIF_DISABLE	0x04

#define SDIF_STAT	0x08
#define SDIF_BUSY	BIT(0)
#define SDIF_LOCK	BIT(1)

#define SDIF_W		0x0c
#define SDIF_PROG	BIT(31)
#define SDIF_WRN_W	BIT(27)
#define SDIF_WRN_R	0x00
#define SDIF_ADDR_SFT	24

#define SDIF_HALT	0x10
#define SDIF_CTRL	0x14
#define SDIF_SMPL_CTRL	0x20

/* TS & PD Individual Macro Register */
#define COM_REG_SIZE	0x40

#define SDIF_DONE(n)	(COM_REG_SIZE + 0x14 + 0x40 * (n))
#define SDIF_SMPL_DONE	BIT(0)

#define SDIF_DATA(n)	(COM_REG_SIZE + 0x18 + 0x40 * (n))
#define SAMPLE_DATA_MSK	GENMASK(15, 0)

#define HILO_RESET(n)	(COM_REG_SIZE + 0x2c + 0x40 * (n))

/* VM Individual Macro Register */
#define VM_COM_REG_SIZE	0x200
#define VM_SDIF_DONE(vm)	(VM_COM_REG_SIZE + 0x34 + 0x200 * (vm))
#define VM_SDIF_DATA(vm, ch)	\
	(VM_COM_REG_SIZE + 0x40 + 0x200 * (vm) + 0x4 * (ch))

/* SDA Slave Register */
#define IP_CTRL			0x00
#define IP_RST_REL		BIT(1)
#define IP_RUN_CONT		BIT(3)
#define IP_AUTO			BIT(8)
#define IP_VM_MODE		BIT(10)

#define IP_CFG			0x01
#define CFG0_MODE_2		BIT(0)
#define CFG0_PARALLEL_OUT	0
#define CFG0_12_BIT		0
#define CFG1_VOL_MEAS_MODE	0
#define CFG1_PARALLEL_OUT	0
#define CFG1_14_BIT		0

#define IP_DATA		0x03

#define IP_POLL		0x04
#define VM_CH_INIT	BIT(20)
#define VM_CH_REQ	BIT(21)

#define IP_TMR			0x05
#define POWER_DELAY_CYCLE_256	0x100
#define POWER_DELAY_CYCLE_64	0x40

#define PVT_POLL_DELAY_US	20
#define PVT_POLL_TIMEOUT_US	20000
#define PVT_H_CONST		100000
#define PVT_CAL5_CONST		2047
#define PVT_G_CONST		40000
#define PVT_CONV_BITS		10
#define PVT_N_CONST		90
#define PVT_R_CONST		245805

struct pvt_device {
	struct regmap		*c_map;
	struct regmap		*t_map;
	struct regmap		*p_map;
	struct regmap		*v_map;
	struct clk		*clk;
	struct reset_control	*rst;
	u32			t_num;
	u32			p_num;
	u32			v_num;
	u32			c_num;
	u32			ip_freq;
	u8			*vm_idx;
};

static umode_t pvt_is_visible(const void *data, enum hwmon_sensor_types type,
			      u32 attr, int channel)
{
	switch (type) {
	case hwmon_temp:
		if (attr == hwmon_temp_input)
			return 0444;
		break;
	case hwmon_in:
		if (attr == hwmon_in_input)
			return 0444;
		break;
	default:
		break;
	}
	return 0;
}

static int pvt_read_temp(struct device *dev, u32 attr, int channel, long *val)
{
	struct pvt_device *pvt = dev_get_drvdata(dev);
	struct regmap *t_map = pvt->t_map;
	u32 stat, nbs;
	int ret;
	u64 tmp;

	switch (attr) {
	case hwmon_temp_input:
		ret = regmap_read_poll_timeout(t_map, SDIF_DONE(channel),
					       stat, stat & SDIF_SMPL_DONE,
					       PVT_POLL_DELAY_US,
					       PVT_POLL_TIMEOUT_US);
		if (ret)
			return ret;

		ret = regmap_read(t_map, SDIF_DATA(channel), &nbs);
		if(ret < 0)
			return ret;

		nbs &= SAMPLE_DATA_MSK;

		/*
		 * Convert the register value to
		 * degrees centigrade temperature
		 */
		tmp = nbs * PVT_H_CONST;
		do_div(tmp, PVT_CAL5_CONST);
		*val = tmp - PVT_G_CONST - pvt->ip_freq;

		return 0;
	default:
		return -EOPNOTSUPP;
	}
}

static int pvt_read_in(struct device *dev, u32 attr, int channel, long *val)
{
	struct pvt_device *pvt = dev_get_drvdata(dev);
	struct regmap *v_map = pvt->v_map;
	u8 vm_idx, ch_idx;
	u32 n, stat;
	int ret;

	if (channel >= pvt->v_num * pvt->c_num)
		return -EINVAL;

	vm_idx = pvt->vm_idx[channel / pvt->c_num];
	ch_idx = channel % pvt->c_num;

	switch (attr) {
	case hwmon_in_input:
		ret = regmap_read_poll_timeout(v_map, VM_SDIF_DONE(vm_idx),
					       stat, stat & SDIF_SMPL_DONE,
					       PVT_POLL_DELAY_US,
					       PVT_POLL_TIMEOUT_US);
		if (ret)
			return ret;

		ret = regmap_read(v_map, VM_SDIF_DATA(vm_idx, ch_idx), &n);
		if(ret < 0)
			return ret;

		n &= SAMPLE_DATA_MSK;
		/*
		 * Convert the N bitstream count into voltage.
		 * To support negative voltage calculation for 64bit machines
		 * n must be cast to long, since n and *val differ both in
		 * signedness and in size.
		 * Division is used instead of right shift, because for signed
		 * numbers, the sign bit is used to fill the vacated bit
		 * positions, and if the number is negative, 1 is used.
		 * BIT(x) may not be used instead of (1 << x) because it's
		 * unsigned.
		 */
		*val = (PVT_N_CONST * (long)n - PVT_R_CONST) / (1 << PVT_CONV_BITS);

		return 0;
	default:
		return -EOPNOTSUPP;
	}
}

static int pvt_read(struct device *dev, enum hwmon_sensor_types type,
		    u32 attr, int channel, long *val)
{
	switch (type) {
	case hwmon_temp:
		return pvt_read_temp(dev, attr, channel, val);
	case hwmon_in:
		return pvt_read_in(dev, attr, channel, val);
	default:
		return -EOPNOTSUPP;
	}
}

static const u32 pvt_chip_config[] = {
	HWMON_C_REGISTER_TZ,
	0
};

static const struct hwmon_channel_info pvt_chip = {
	.type = hwmon_chip,
	.config = pvt_chip_config,
};

static struct hwmon_channel_info pvt_temp = {
	.type = hwmon_temp,
};

static struct hwmon_channel_info pvt_in = {
	.type = hwmon_in,
};

static const struct hwmon_ops pvt_hwmon_ops = {
	.is_visible = pvt_is_visible,
	.read = pvt_read,
};

static struct hwmon_chip_info pvt_chip_info = {
	.ops = &pvt_hwmon_ops,
};

static int pvt_init(struct pvt_device *pvt)
{
	u16 sys_freq, key, middle, low = 4, high = 8;
	struct regmap *t_map = pvt->t_map;
	struct regmap *p_map = pvt->p_map;
	struct regmap *v_map = pvt->v_map;
	u32 t_num = pvt->t_num;
	u32 p_num = pvt->p_num;
	u32 v_num = pvt->v_num;
	u32 clk_synth, val;
	int ret;

	sys_freq = clk_get_rate(pvt->clk) / HZ_PER_MHZ;
	while (high >= low) {
		middle = (low + high + 1) / 2;
		key = DIV_ROUND_CLOSEST(sys_freq, middle);
		if (key > CLK_SYS_CYCLES_MAX) {
			low = middle + 1;
			continue;
		} else if (key < CLK_SYS_CYCLES_MIN) {
			high = middle - 1;
			continue;
		} else {
			break;
		}
	}

	/*
	 * The system supports 'clk_sys' to 'clk_ip' frequency ratios
	 * from 2:1 to 512:1
	 */
	key = clamp_val(key, CLK_SYS_CYCLES_MIN, CLK_SYS_CYCLES_MAX) - 2;

	clk_synth = ((key + 1) >> 1) << CLK_SYNTH_LO_SFT |
		    (key >> 1) << CLK_SYNTH_HI_SFT |
		    (key >> 1) << CLK_SYNTH_HOLD_SFT | CLK_SYNTH_EN;

	pvt->ip_freq = sys_freq * 100 / (key + 2);

	if (t_num) {
		ret = regmap_write(t_map, SDIF_SMPL_CTRL, 0x0);
		if(ret < 0)
			return ret;

		ret = regmap_write(t_map, SDIF_HALT, 0x0);
		if(ret < 0)
			return ret;

		ret = regmap_write(t_map, CLK_SYNTH, clk_synth);
		if(ret < 0)
			return ret;

		ret = regmap_write(t_map, SDIF_DISABLE, 0x0);
		if(ret < 0)
			return ret;

		ret = regmap_read_poll_timeout(t_map, SDIF_STAT,
					       val, !(val & SDIF_BUSY),
					       PVT_POLL_DELAY_US,
					       PVT_POLL_TIMEOUT_US);
		if (ret)
			return ret;

		val = CFG0_MODE_2 | CFG0_PARALLEL_OUT | CFG0_12_BIT |
		      IP_CFG << SDIF_ADDR_SFT | SDIF_WRN_W | SDIF_PROG;
		ret = regmap_write(t_map, SDIF_W, val);
		if(ret < 0)
			return ret;

		ret = regmap_read_poll_timeout(t_map, SDIF_STAT,
					       val, !(val & SDIF_BUSY),
					       PVT_POLL_DELAY_US,
					       PVT_POLL_TIMEOUT_US);
		if (ret)
			return ret;

		val = POWER_DELAY_CYCLE_256 | IP_TMR << SDIF_ADDR_SFT |
			      SDIF_WRN_W | SDIF_PROG;
		ret = regmap_write(t_map, SDIF_W, val);
		if(ret < 0)
			return ret;

		ret = regmap_read_poll_timeout(t_map, SDIF_STAT,
					       val, !(val & SDIF_BUSY),
					       PVT_POLL_DELAY_US,
					       PVT_POLL_TIMEOUT_US);
		if (ret)
			return ret;

		val = IP_RST_REL | IP_RUN_CONT | IP_AUTO |
		      IP_CTRL << SDIF_ADDR_SFT |
		      SDIF_WRN_W | SDIF_PROG;
		ret = regmap_write(t_map, SDIF_W, val);
		if(ret < 0)
			return ret;
	}

	if (p_num) {
		ret = regmap_write(p_map, SDIF_HALT, 0x0);
		if(ret < 0)
			return ret;

		ret = regmap_write(p_map, SDIF_DISABLE, BIT(p_num) - 1);
		if(ret < 0)
			return ret;

		ret = regmap_write(p_map, CLK_SYNTH, clk_synth);
		if(ret < 0)
			return ret;
	}

	if (v_num) {
		ret = regmap_write(v_map, SDIF_SMPL_CTRL, 0x0);
		if(ret < 0)
			return ret;

		ret = regmap_write(v_map, SDIF_HALT, 0x0);
		if(ret < 0)
			return ret;

		ret = regmap_write(v_map, CLK_SYNTH, clk_synth);
		if(ret < 0)
			return ret;

		ret = regmap_write(v_map, SDIF_DISABLE, 0x0);
		if(ret < 0)
			return ret;

		ret = regmap_read_poll_timeout(v_map, SDIF_STAT,
					       val, !(val & SDIF_BUSY),
					       PVT_POLL_DELAY_US,
					       PVT_POLL_TIMEOUT_US);
		if (ret)
			return ret;

		val = (BIT(pvt->c_num) - 1) | VM_CH_INIT |
		      IP_POLL << SDIF_ADDR_SFT | SDIF_WRN_W | SDIF_PROG;
		ret = regmap_write(v_map, SDIF_W, val);
		if (ret < 0)
			return ret;

		ret = regmap_read_poll_timeout(v_map, SDIF_STAT,
					       val, !(val & SDIF_BUSY),
					       PVT_POLL_DELAY_US,
					       PVT_POLL_TIMEOUT_US);
		if (ret)
			return ret;

		val = CFG1_VOL_MEAS_MODE | CFG1_PARALLEL_OUT |
		      CFG1_14_BIT | IP_CFG << SDIF_ADDR_SFT |
		      SDIF_WRN_W | SDIF_PROG;
		ret = regmap_write(v_map, SDIF_W, val);
		if(ret < 0)
			return ret;

		ret = regmap_read_poll_timeout(v_map, SDIF_STAT,
					       val, !(val & SDIF_BUSY),
					       PVT_POLL_DELAY_US,
					       PVT_POLL_TIMEOUT_US);
		if (ret)
			return ret;

		val = POWER_DELAY_CYCLE_64 | IP_TMR << SDIF_ADDR_SFT |
		      SDIF_WRN_W | SDIF_PROG;
		ret = regmap_write(v_map, SDIF_W, val);
		if(ret < 0)
			return ret;

		ret = regmap_read_poll_timeout(v_map, SDIF_STAT,
					       val, !(val & SDIF_BUSY),
					       PVT_POLL_DELAY_US,
					       PVT_POLL_TIMEOUT_US);
		if (ret)
			return ret;

		val = IP_RST_REL | IP_RUN_CONT | IP_AUTO | IP_VM_MODE |
		      IP_CTRL << SDIF_ADDR_SFT |
		      SDIF_WRN_W | SDIF_PROG;
		ret = regmap_write(v_map, SDIF_W, val);
		if(ret < 0)
			return ret;
	}

	return 0;
}

static struct regmap_config pvt_regmap_config = {
	.reg_bits = 32,
	.reg_stride = 4,
	.val_bits = 32,
};

static int pvt_get_regmap(struct platform_device *pdev, char *reg_name,
			  struct pvt_device *pvt)
{
	struct device *dev = &pdev->dev;
	struct regmap **reg_map;
	void __iomem *io_base;

	if (!strcmp(reg_name, "common"))
		reg_map = &pvt->c_map;
	else if (!strcmp(reg_name, "ts"))
		reg_map = &pvt->t_map;
	else if (!strcmp(reg_name, "pd"))
		reg_map = &pvt->p_map;
	else if (!strcmp(reg_name, "vm"))
		reg_map = &pvt->v_map;
	else
		return -EINVAL;

	io_base = devm_platform_ioremap_resource_byname(pdev, reg_name);
	if (IS_ERR(io_base))
		return PTR_ERR(io_base);

	pvt_regmap_config.name = reg_name;
	*reg_map = devm_regmap_init_mmio(dev, io_base, &pvt_regmap_config);
	if (IS_ERR(*reg_map)) {
		dev_err(dev, "failed to init register map\n");
		return PTR_ERR(*reg_map);
	}

	return 0;
}

static void pvt_clk_disable(void *data)
{
	struct pvt_device *pvt = data;

	clk_disable_unprepare(pvt->clk);
}

static int pvt_clk_enable(struct device *dev, struct pvt_device *pvt)
{
	int ret;

	ret = clk_prepare_enable(pvt->clk);
	if (ret)
		return ret;

	return devm_add_action_or_reset(dev, pvt_clk_disable, pvt);
}

static void pvt_reset_control_assert(void *data)
{
	struct pvt_device *pvt = data;

	reset_control_assert(pvt->rst);
}

static int pvt_reset_control_deassert(struct device *dev, struct pvt_device *pvt)
{
	int ret;

	ret = reset_control_deassert(pvt->rst);
	if (ret)
		return ret;

	return devm_add_action_or_reset(dev, pvt_reset_control_assert, pvt);
}

static int mr75203_probe(struct platform_device *pdev)
{
	u32 ts_num, vm_num, pd_num, ch_num, val, index, i;
	const struct hwmon_channel_info **pvt_info;
	struct device *dev = &pdev->dev;
	u32 *temp_config, *in_config;
	struct device *hwmon_dev;
	struct pvt_device *pvt;
	int ret;

	pvt = devm_kzalloc(dev, sizeof(*pvt), GFP_KERNEL);
	if (!pvt)
		return -ENOMEM;

	ret = pvt_get_regmap(pdev, "common", pvt);
	if (ret)
		return ret;

	pvt->clk = devm_clk_get(dev, NULL);
	if (IS_ERR(pvt->clk))
		return dev_err_probe(dev, PTR_ERR(pvt->clk), "failed to get clock\n");

	ret = pvt_clk_enable(dev, pvt);
	if (ret) {
		dev_err(dev, "failed to enable clock\n");
		return ret;
	}

	pvt->rst = devm_reset_control_get_exclusive(dev, NULL);
	if (IS_ERR(pvt->rst))
		return dev_err_probe(dev, PTR_ERR(pvt->rst),
				     "failed to get reset control\n");

	ret = pvt_reset_control_deassert(dev, pvt);
	if (ret)
		return dev_err_probe(dev, ret, "cannot deassert reset control\n");

	ret = regmap_read(pvt->c_map, PVT_IP_CONFIG, &val);
	if(ret < 0)
		return ret;

	ts_num = (val & TS_NUM_MSK) >> TS_NUM_SFT;
	pd_num = (val & PD_NUM_MSK) >> PD_NUM_SFT;
	vm_num = (val & VM_NUM_MSK) >> VM_NUM_SFT;
	ch_num = (val & CH_NUM_MSK) >> CH_NUM_SFT;
	pvt->t_num = ts_num;
	pvt->p_num = pd_num;
	pvt->v_num = vm_num;
	pvt->c_num = ch_num;
	val = 0;
	if (ts_num)
		val++;
	if (vm_num)
		val++;
	if (!val)
		return -ENODEV;

	pvt_info = devm_kcalloc(dev, val + 2, sizeof(*pvt_info), GFP_KERNEL);
	if (!pvt_info)
		return -ENOMEM;
	pvt_info[0] = &pvt_chip;
	index = 1;

	if (ts_num) {
		ret = pvt_get_regmap(pdev, "ts", pvt);
		if (ret)
			return ret;

		temp_config = devm_kcalloc(dev, ts_num + 1,
					   sizeof(*temp_config), GFP_KERNEL);
		if (!temp_config)
			return -ENOMEM;

		memset32(temp_config, HWMON_T_INPUT, ts_num);
		pvt_temp.config = temp_config;
		pvt_info[index++] = &pvt_temp;
	}

	if (pd_num) {
		ret = pvt_get_regmap(pdev, "pd", pvt);
		if (ret)
			return ret;
	}

	if (vm_num) {
		u32 total_ch;

		ret = pvt_get_regmap(pdev, "vm", pvt);
		if (ret)
			return ret;

		pvt->vm_idx = devm_kcalloc(dev, vm_num, sizeof(*pvt->vm_idx),
					   GFP_KERNEL);
		if (!pvt->vm_idx)
			return -ENOMEM;

		ret = device_property_read_u8_array(dev, "intel,vm-map",
						    pvt->vm_idx, vm_num);
		if (ret) {
			/*
			 * Incase intel,vm-map property is not defined, we
			 * assume incremental channel numbers.
			 */
			for (i = 0; i < vm_num; i++)
				pvt->vm_idx[i] = i;
		} else {
			for (i = 0; i < vm_num; i++)
				if (pvt->vm_idx[i] >= vm_num ||
				    pvt->vm_idx[i] == 0xff) {
					pvt->v_num = i;
					vm_num = i;
					break;
				}
		}

		total_ch = ch_num * vm_num;
		in_config = devm_kcalloc(dev, total_ch + 1,
					 sizeof(*in_config), GFP_KERNEL);
		if (!in_config)
			return -ENOMEM;

		memset32(in_config, HWMON_I_INPUT, total_ch);
		in_config[total_ch] = 0;
		pvt_in.config = in_config;

		pvt_info[index++] = &pvt_in;
	}

	ret = pvt_init(pvt);
	if (ret) {
		dev_err(dev, "failed to init pvt: %d\n", ret);
		return ret;
	}

	pvt_chip_info.info = pvt_info;
	hwmon_dev = devm_hwmon_device_register_with_info(dev, "pvt",
							 pvt,
							 &pvt_chip_info,
							 NULL);

	return PTR_ERR_OR_ZERO(hwmon_dev);
}

static const struct of_device_id moortec_pvt_of_match[] = {
	{ .compatible = "moortec,mr75203" },
	{ }
};
MODULE_DEVICE_TABLE(of, moortec_pvt_of_match);

static struct platform_driver moortec_pvt_driver = {
	.driver = {
		.name = "moortec-pvt",
		.of_match_table = moortec_pvt_of_match,
	},
	.probe = mr75203_probe,
};
module_platform_driver(moortec_pvt_driver);

MODULE_LICENSE("GPL v2");
