// 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/debugfs.h>
#include <linux/hwmon.h>
#include <linux/kstrtox.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/slab.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

#define VM_NUM_MAX	(VM_NUM_MSK >> VM_NUM_SFT)

/* 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_CONV_BITS		10
#define PVT_N_CONST		90
#define PVT_R_CONST		245805

#define PVT_TEMP_MIN_mC		-40000
#define PVT_TEMP_MAX_mC		125000

/* Temperature coefficients for series 5 */
#define PVT_SERIES5_H_CONST	200000
#define PVT_SERIES5_G_CONST	60000
#define PVT_SERIES5_J_CONST	-100
#define PVT_SERIES5_CAL5_CONST	4094

/* Temperature coefficients for series 6 */
#define PVT_SERIES6_H_CONST	249400
#define PVT_SERIES6_G_CONST	57400
#define PVT_SERIES6_J_CONST	0
#define PVT_SERIES6_CAL5_CONST	4096

#define TEMPERATURE_SENSOR_SERIES_5	5
#define TEMPERATURE_SENSOR_SERIES_6	6

#define PRE_SCALER_X1	1
#define PRE_SCALER_X2	2

/**
 * struct voltage_device - VM single input parameters.
 * @vm_map: Map channel number to VM index.
 * @ch_map: Map channel number to channel index.
 * @pre_scaler: Pre scaler value (1 or 2) used to normalize the voltage output
 *              result.
 *
 * The structure provides mapping between channel-number (0..N-1) to VM-index
 * (0..num_vm-1) and channel-index (0..ch_num-1) where N = num_vm * ch_num.
 * It also provides normalization factor for the VM equation.
 */
struct voltage_device {
	u32 vm_map;
	u32 ch_map;
	u32 pre_scaler;
};

/**
 * struct voltage_channels - VM channel count.
 * @total: Total number of channels in all VMs.
 * @max: Maximum number of channels among all VMs.
 *
 * The structure provides channel count information across all VMs.
 */
struct voltage_channels {
	u32 total;
	u8 max;
};

struct temp_coeff {
	u32 h;
	u32 g;
	u32 cal5;
	s32 j;
};

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;
	struct dentry		*dbgfs_dir;
	struct voltage_device	*vd;
	struct voltage_channels	vm_channels;
	struct temp_coeff	ts_coeff;
	u32			t_num;
	u32			p_num;
	u32			v_num;
	u32			ip_freq;
};

static ssize_t pvt_ts_coeff_j_read(struct file *file, char __user *user_buf,
				   size_t count, loff_t *ppos)
{
	struct pvt_device *pvt = file->private_data;
	unsigned int len;
	char buf[13];

	len = scnprintf(buf, sizeof(buf), "%d\n", pvt->ts_coeff.j);

	return simple_read_from_buffer(user_buf, count, ppos, buf, len);
}

static ssize_t pvt_ts_coeff_j_write(struct file *file,
				    const char __user *user_buf,
				    size_t count, loff_t *ppos)
{
	struct pvt_device *pvt = file->private_data;
	int ret;

	ret = kstrtos32_from_user(user_buf, count, 0, &pvt->ts_coeff.j);
	if (ret)
		return ret;

	return count;
}

static const struct file_operations pvt_ts_coeff_j_fops = {
	.read = pvt_ts_coeff_j_read,
	.write = pvt_ts_coeff_j_write,
	.open = simple_open,
	.owner = THIS_MODULE,
	.llseek = default_llseek,
};

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

	debugfs_remove_recursive(pvt->dbgfs_dir);
	pvt->dbgfs_dir = NULL;
}

static int pvt_ts_dbgfs_create(struct pvt_device *pvt, struct device *dev)
{
	pvt->dbgfs_dir = debugfs_create_dir(dev_name(dev), NULL);

	debugfs_create_u32("ts_coeff_h", 0644, pvt->dbgfs_dir,
			   &pvt->ts_coeff.h);
	debugfs_create_u32("ts_coeff_g", 0644, pvt->dbgfs_dir,
			   &pvt->ts_coeff.g);
	debugfs_create_u32("ts_coeff_cal5", 0644, pvt->dbgfs_dir,
			   &pvt->ts_coeff.cal5);
	debugfs_create_file("ts_coeff_j", 0644, pvt->dbgfs_dir, pvt,
			    &pvt_ts_coeff_j_fops);

	return devm_add_action_or_reset(dev, devm_pvt_ts_dbgfs_remove, pvt);
}

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 long pvt_calc_temp(struct pvt_device *pvt, u32 nbs)
{
	/*
	 * Convert the register value to degrees centigrade temperature:
	 * T = G + H * (n / cal5 - 0.5) + J * F
	 */
	struct temp_coeff *ts_coeff = &pvt->ts_coeff;

	s64 tmp = ts_coeff->g +
		div_s64(ts_coeff->h * (s64)nbs, ts_coeff->cal5) -
		ts_coeff->h / 2 +
		div_s64(ts_coeff->j * (s64)pvt->ip_freq, HZ_PER_MHZ);

	return clamp_val(tmp, PVT_TEMP_MIN_mC, PVT_TEMP_MAX_mC);
}

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;

	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
		 */
		*val = pvt_calc_temp(pvt, nbs);

		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;
	u32 n, stat, pre_scaler;
	u8 vm_idx, ch_idx;
	int ret;

	if (channel >= pvt->vm_channels.total)
		return -EINVAL;

	vm_idx = pvt->vd[channel].vm_map;
	ch_idx = pvt->vd[channel].ch_map;

	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;
		pre_scaler = pvt->vd[channel].pre_scaler;
		/*
		 * 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 = pre_scaler * (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 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 = clk_get_rate(pvt->clk) / (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->vm_channels.max) - 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_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 pvt_get_active_channel(struct device *dev, struct pvt_device *pvt,
				  u32 vm_num, u32 ch_num, u8 *vm_idx)
{
	u8 vm_active_ch[VM_NUM_MAX];
	int ret, i, j, k;

	ret = device_property_read_u8_array(dev, "moortec,vm-active-channels",
					    vm_active_ch, vm_num);
	if (ret) {
		/*
		 * Incase "moortec,vm-active-channels" property is not defined,
		 * we assume each VM sensor has all of its channels active.
		 */
		memset(vm_active_ch, ch_num, vm_num);
		pvt->vm_channels.max = ch_num;
		pvt->vm_channels.total = ch_num * vm_num;
	} else {
		for (i = 0; i < vm_num; i++) {
			if (vm_active_ch[i] > ch_num) {
				dev_err(dev, "invalid active channels: %u\n",
					vm_active_ch[i]);
				return -EINVAL;
			}

			pvt->vm_channels.total += vm_active_ch[i];

			if (vm_active_ch[i] > pvt->vm_channels.max)
				pvt->vm_channels.max = vm_active_ch[i];
		}
	}

	/*
	 * Map between the channel-number to VM-index and channel-index.
	 * Example - 3 VMs, "moortec,vm_active_ch" = <5 2 4>:
	 * vm_map = [0 0 0 0 0 1 1 2 2 2 2]
	 * ch_map = [0 1 2 3 4 0 1 0 1 2 3]
	 */
	pvt->vd = devm_kcalloc(dev, pvt->vm_channels.total, sizeof(*pvt->vd),
			       GFP_KERNEL);
	if (!pvt->vd)
		return -ENOMEM;

	k = 0;
	for (i = 0; i < vm_num; i++) {
		for (j = 0; j < vm_active_ch[i]; j++) {
			pvt->vd[k].vm_map = vm_idx[i];
			pvt->vd[k].ch_map = j;
			k++;
		}
	}

	return 0;
}

static int pvt_get_pre_scaler(struct device *dev, struct pvt_device *pvt)
{
	u8 *pre_scaler_ch_list;
	int i, ret, num_ch;
	u32 channel;

	/* Set default pre-scaler value to be 1. */
	for (i = 0; i < pvt->vm_channels.total; i++)
		pvt->vd[i].pre_scaler = PRE_SCALER_X1;

	/* Get number of channels configured in "moortec,vm-pre-scaler-x2". */
	num_ch = device_property_count_u8(dev, "moortec,vm-pre-scaler-x2");
	if (num_ch <= 0)
		return 0;

	pre_scaler_ch_list = kcalloc(num_ch, sizeof(*pre_scaler_ch_list),
				     GFP_KERNEL);
	if (!pre_scaler_ch_list)
		return -ENOMEM;

	/* Get list of all channels that have pre-scaler of 2. */
	ret = device_property_read_u8_array(dev, "moortec,vm-pre-scaler-x2",
					    pre_scaler_ch_list, num_ch);
	if (ret)
		goto out;

	for (i = 0; i < num_ch; i++) {
		channel = pre_scaler_ch_list[i];
		pvt->vd[channel].pre_scaler = PRE_SCALER_X2;
	}

out:
	kfree(pre_scaler_ch_list);

	return ret;
}

static int pvt_set_temp_coeff(struct device *dev, struct pvt_device *pvt)
{
	struct temp_coeff *ts_coeff = &pvt->ts_coeff;
	u32 series;
	int ret;

	/* Incase ts-series property is not defined, use default 5. */
	ret = device_property_read_u32(dev, "moortec,ts-series", &series);
	if (ret)
		series = TEMPERATURE_SENSOR_SERIES_5;

	switch (series) {
	case TEMPERATURE_SENSOR_SERIES_5:
		ts_coeff->h = PVT_SERIES5_H_CONST;
		ts_coeff->g = PVT_SERIES5_G_CONST;
		ts_coeff->j = PVT_SERIES5_J_CONST;
		ts_coeff->cal5 = PVT_SERIES5_CAL5_CONST;
		break;
	case TEMPERATURE_SENSOR_SERIES_6:
		ts_coeff->h = PVT_SERIES6_H_CONST;
		ts_coeff->g = PVT_SERIES6_G_CONST;
		ts_coeff->j = PVT_SERIES6_J_CONST;
		ts_coeff->cal5 = PVT_SERIES6_CAL5_CONST;
		break;
	default:
		dev_err(dev, "invalid temperature sensor series (%u)\n",
			series);
		return -EINVAL;
	}

	dev_dbg(dev, "temperature sensor series = %u\n", series);

	/* Override ts-coeff-h/g/j/cal5 if they are defined. */
	device_property_read_u32(dev, "moortec,ts-coeff-h", &ts_coeff->h);
	device_property_read_u32(dev, "moortec,ts-coeff-g", &ts_coeff->g);
	device_property_read_u32(dev, "moortec,ts-coeff-j", &ts_coeff->j);
	device_property_read_u32(dev, "moortec,ts-coeff-cal5", &ts_coeff->cal5);

	dev_dbg(dev, "ts-coeff: h = %u, g = %u, j = %d, cal5 = %u\n",
		ts_coeff->h, ts_coeff->g, ts_coeff->j, ts_coeff->cal5);

	return 0;
}

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_enabled(dev, NULL);
	if (IS_ERR(pvt->clk))
		return dev_err_probe(dev, PTR_ERR(pvt->clk), "failed to get clock\n");

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

	if (pvt->rst) {
		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;
	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] = HWMON_CHANNEL_INFO(chip, HWMON_C_REGISTER_TZ);
	index = 1;

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

		ret = pvt_set_temp_coeff(dev, 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;

		pvt_ts_dbgfs_create(pvt, dev);
	}

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

	if (vm_num) {
		u8 vm_idx[VM_NUM_MAX];

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

		ret = device_property_read_u8_array(dev, "intel,vm-map", 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++)
				vm_idx[i] = i;
		} else {
			for (i = 0; i < vm_num; i++)
				if (vm_idx[i] >= vm_num || vm_idx[i] == 0xff) {
					pvt->v_num = i;
					vm_num = i;
					break;
				}
		}

		ret = pvt_get_active_channel(dev, pvt, vm_num, ch_num, vm_idx);
		if (ret)
			return ret;

		ret = pvt_get_pre_scaler(dev, pvt);
		if (ret)
			return ret;

		in_config = devm_kcalloc(dev, pvt->vm_channels.total + 1,
					 sizeof(*in_config), GFP_KERNEL);
		if (!in_config)
			return -ENOMEM;

		memset32(in_config, HWMON_I_INPUT, pvt->vm_channels.total);
		in_config[pvt->vm_channels.total] = 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");
