// SPDX-License-Identifier: GPL-2.0-or-later

/* Driver for the Texas Instruments TMP464 SMBus temperature sensor IC.
 * Supported models: TMP464, TMP468

 * Copyright (C) 2022 Agathe Porte <agathe.porte@nokia.com>
 * Preliminary support by:
 * Lionel Pouliquen <lionel.lp.pouliquen@nokia.com>
 */

#include <linux/err.h>
#include <linux/hwmon.h>
#include <linux/i2c.h>
#include <linux/init.h>
#include <linux/module.h>
#include <linux/of.h>
#include <linux/regmap.h>
#include <linux/slab.h>

/* Addresses to scan */
static const unsigned short normal_i2c[] = { 0x48, 0x49, 0x4a, 0x4b, I2C_CLIENT_END };

#define TMP464_NUM_CHANNELS		5	/* chan 0 is internal, 1-4 are remote */
#define TMP468_NUM_CHANNELS		9	/* chan 0 is internal, 1-8 are remote */

#define MAX_CHANNELS			9

#define TMP464_TEMP_REG(channel)	(channel)
#define TMP464_TEMP_OFFSET_REG(channel)	(0x40 + ((channel) - 1) * 8)
#define TMP464_N_FACTOR_REG(channel)	(0x41 + ((channel) - 1) * 8)

static const u8 TMP464_THERM_LIMIT[MAX_CHANNELS] = {
	0x39, 0x42, 0x4A, 0x52, 0x5A, 0x62, 0x6a, 0x72, 0x7a };
static const u8 TMP464_THERM2_LIMIT[MAX_CHANNELS] = {
	0x3A, 0x43, 0x4B, 0x53, 0x5B, 0x63, 0x6b, 0x73, 0x7b };

#define TMP464_THERM_STATUS_REG			0x21
#define TMP464_THERM2_STATUS_REG		0x22
#define TMP464_REMOTE_OPEN_REG			0x23
#define TMP464_CONFIG_REG			0x30
#define TMP464_TEMP_HYST_REG			0x38
#define TMP464_LOCK_REG				0xc4

/* Identification */
#define TMP464_MANUFACTURER_ID_REG		0xFE
#define TMP464_DEVICE_ID_REG			0xFF

/* Flags */
#define TMP464_CONFIG_SHUTDOWN			BIT(5)
#define TMP464_CONFIG_RANGE			0x04
#define TMP464_CONFIG_REG_REN(x)		(BIT(7 + (x)))
#define TMP464_CONFIG_REG_REN_MASK		GENMASK(15, 7)
#define TMP464_CONFIG_CONVERSION_RATE_B0	2
#define TMP464_CONFIG_CONVERSION_RATE_B2	4
#define TMP464_CONFIG_CONVERSION_RATE_MASK      GENMASK(TMP464_CONFIG_CONVERSION_RATE_B2, \
							TMP464_CONFIG_CONVERSION_RATE_B0)

#define TMP464_UNLOCK_VAL			0xeb19
#define TMP464_LOCK_VAL				0x5ca6
#define TMP464_LOCKED				0x8000

/* Manufacturer / Device ID's */
#define TMP464_MANUFACTURER_ID			0x5449
#define TMP464_DEVICE_ID			0x1468
#define TMP468_DEVICE_ID			0x0468

static const struct i2c_device_id tmp464_id[] = {
	{ .name = "tmp464", .driver_data = TMP464_NUM_CHANNELS },
	{ .name = "tmp468", .driver_data = TMP468_NUM_CHANNELS },
	{ }
};
MODULE_DEVICE_TABLE(i2c, tmp464_id);

static const struct of_device_id __maybe_unused tmp464_of_match[] = {
	{
		.compatible = "ti,tmp464",
		.data = (void *)TMP464_NUM_CHANNELS
	},
	{
		.compatible = "ti,tmp468",
		.data = (void *)TMP468_NUM_CHANNELS
	},
	{},
};
MODULE_DEVICE_TABLE(of, tmp464_of_match);

struct tmp464_channel {
	const char *label;
	bool enabled;
};

struct tmp464_data {
	struct regmap *regmap;
	int channels;
	s16 config_orig;
	u16 open_reg;
	unsigned long last_updated;
	bool valid;
	int update_interval;
	struct tmp464_channel channel[MAX_CHANNELS];
};

static int temp_from_reg(s16 reg)
{
	return DIV_ROUND_CLOSEST((reg >> 3) * 625, 10);
}

static s16 temp_to_limit_reg(long temp)
{
	return DIV_ROUND_CLOSEST(temp, 500) << 6;
}

static s16 temp_to_offset_reg(long temp)
{
	return DIV_ROUND_CLOSEST(temp * 10, 625) << 3;
}

static int tmp464_enable_channels(struct tmp464_data *data)
{
	struct regmap *regmap = data->regmap;
	u16 enable = 0;
	int i;

	for (i = 0; i < data->channels; i++)
		if (data->channel[i].enabled)
			enable |= TMP464_CONFIG_REG_REN(i);

	return regmap_update_bits(regmap, TMP464_CONFIG_REG, TMP464_CONFIG_REG_REN_MASK, enable);
}

static int tmp464_chip_read(struct device *dev, u32 attr, int channel, long *val)
{
	struct tmp464_data *data = dev_get_drvdata(dev);

	switch (attr) {
	case hwmon_chip_update_interval:
		*val = data->update_interval;
		return 0;
	default:
		return -EOPNOTSUPP;
	}
}

static int tmp464_temp_read(struct device *dev, u32 attr, int channel, long *val)
{
	struct tmp464_data *data = dev_get_drvdata(dev);
	struct regmap *regmap = data->regmap;
	unsigned int regs[2];
	unsigned int regval;
	u16 regvals[2];
	int err = 0;

	switch (attr) {
	case hwmon_temp_max_alarm:
		err = regmap_read(regmap, TMP464_THERM_STATUS_REG, &regval);
		if (err < 0)
			break;
		*val = !!(regval & BIT(channel + 7));
		break;
	case hwmon_temp_crit_alarm:
		err = regmap_read(regmap, TMP464_THERM2_STATUS_REG, &regval);
		if (err < 0)
			break;
		*val = !!(regval & BIT(channel + 7));
		break;
	case hwmon_temp_fault:
		/*
		 * The chip clears TMP464_REMOTE_OPEN_REG after it is read
		 * and only updates it after the next measurement cycle is
		 * complete. That means we have to cache the value internally
		 * for one measurement cycle and report the cached value.
		 */
		if (!data->valid || time_after(jiffies, data->last_updated +
					       msecs_to_jiffies(data->update_interval))) {
			err = regmap_read(regmap, TMP464_REMOTE_OPEN_REG, &regval);
			if (err < 0)
				break;
			data->open_reg = regval;
			data->last_updated = jiffies;
			data->valid = true;
		}
		*val = !!(data->open_reg & BIT(channel + 7));
		break;
	case hwmon_temp_max_hyst:
		regs[0] = TMP464_THERM_LIMIT[channel];
		regs[1] = TMP464_TEMP_HYST_REG;
		err = regmap_multi_reg_read(regmap, regs, regvals, 2);
		if (err < 0)
			break;
		*val = temp_from_reg(regvals[0] - regvals[1]);
		break;
	case hwmon_temp_max:
		err = regmap_read(regmap, TMP464_THERM_LIMIT[channel], &regval);
		if (err < 0)
			break;
		*val = temp_from_reg(regval);
		break;
	case hwmon_temp_crit_hyst:
		regs[0] = TMP464_THERM2_LIMIT[channel];
		regs[1] = TMP464_TEMP_HYST_REG;
		err = regmap_multi_reg_read(regmap, regs, regvals, 2);
		if (err < 0)
			break;
		*val = temp_from_reg(regvals[0] - regvals[1]);
		break;
	case hwmon_temp_crit:
		err = regmap_read(regmap, TMP464_THERM2_LIMIT[channel], &regval);
		if (err < 0)
			break;
		*val = temp_from_reg(regval);
		break;
	case hwmon_temp_offset:
		err = regmap_read(regmap, TMP464_TEMP_OFFSET_REG(channel), &regval);
		if (err < 0)
			break;
		*val = temp_from_reg(regval);
		break;
	case hwmon_temp_input:
		if (!data->channel[channel].enabled) {
			err = -ENODATA;
			break;
		}
		err = regmap_read(regmap, TMP464_TEMP_REG(channel), &regval);
		if (err < 0)
			break;
		*val = temp_from_reg(regval);
		break;
	case hwmon_temp_enable:
		*val = data->channel[channel].enabled;
		break;
	default:
		err = -EOPNOTSUPP;
		break;
	}

	return err;
}

static int tmp464_read(struct device *dev, enum hwmon_sensor_types type,
		       u32 attr, int channel, long *val)
{
	switch (type) {
	case hwmon_chip:
		return tmp464_chip_read(dev, attr, channel, val);
	case hwmon_temp:
		return tmp464_temp_read(dev, attr, channel, val);
	default:
		return -EOPNOTSUPP;
	}
}

static int tmp464_read_string(struct device *dev, enum hwmon_sensor_types type,
			      u32 attr, int channel, const char **str)
{
	struct tmp464_data *data = dev_get_drvdata(dev);

	*str = data->channel[channel].label;

	return 0;
}

static int tmp464_set_convrate(struct tmp464_data *data, long interval)
{
	int rate;

	/*
	 * For valid rates, interval in milli-seconds can be calculated as
	 *      interval = 125 << (7 - rate);
	 * or
	 *      interval = (1 << (7 - rate)) * 125;
	 * The rate is therefore
	 *      rate = 7 - __fls(interval / 125);
	 * and the rounded rate is
	 *      rate = 7 - __fls(interval * 4 / (125 * 3));
	 * Use clamp_val() to avoid overflows, and to ensure valid input
	 * for __fls.
	 */
	interval = clamp_val(interval, 125, 16000);
	rate = 7 - __fls(interval * 4 / (125 * 3));
	data->update_interval = 125 << (7 - rate);

	return regmap_update_bits(data->regmap, TMP464_CONFIG_REG,
				  TMP464_CONFIG_CONVERSION_RATE_MASK,
				  rate << TMP464_CONFIG_CONVERSION_RATE_B0);
}

static int tmp464_chip_write(struct tmp464_data *data, u32 attr, int channel, long val)
{
	switch (attr) {
	case hwmon_chip_update_interval:
		return tmp464_set_convrate(data, val);
	default:
		return -EOPNOTSUPP;
	}
}

static int tmp464_temp_write(struct tmp464_data *data, u32 attr, int channel, long val)
{
	struct regmap *regmap = data->regmap;
	unsigned int regval;
	int err = 0;

	switch (attr) {
	case hwmon_temp_max_hyst:
		err = regmap_read(regmap, TMP464_THERM_LIMIT[0], &regval);
		if (err < 0)
			break;
		val = clamp_val(val, -256000, 256000);	/* prevent overflow/underflow */
		val = clamp_val(temp_from_reg(regval) - val, 0, 255000);
		err = regmap_write(regmap, TMP464_TEMP_HYST_REG,
				   DIV_ROUND_CLOSEST(val, 1000) << 7);
		break;
	case hwmon_temp_max:
		val = temp_to_limit_reg(clamp_val(val, -255000, 255500));
		err = regmap_write(regmap, TMP464_THERM_LIMIT[channel], val);
		break;
	case hwmon_temp_crit:
		val = temp_to_limit_reg(clamp_val(val, -255000, 255500));
		err = regmap_write(regmap, TMP464_THERM2_LIMIT[channel], val);
		break;
	case hwmon_temp_offset:
		val = temp_to_offset_reg(clamp_val(val, -128000, 127937));
		err = regmap_write(regmap, TMP464_TEMP_OFFSET_REG(channel), val);
		break;
	case hwmon_temp_enable:
		data->channel[channel].enabled = !!val;
		err = tmp464_enable_channels(data);
		break;
	default:
		err = -EOPNOTSUPP;
		break;
	}

	return err;
}

static int tmp464_write(struct device *dev, enum hwmon_sensor_types type,
			u32 attr, int channel, long val)
{
	struct tmp464_data *data = dev_get_drvdata(dev);
	int err;

	switch (type) {
	case hwmon_chip:
		err = tmp464_chip_write(data, attr, channel, val);
		break;
	case hwmon_temp:
		err = tmp464_temp_write(data, attr, channel, val);
		break;
	default:
		err = -EOPNOTSUPP;
		break;
	}

	return err;
}

static umode_t tmp464_is_visible(const void *_data, enum hwmon_sensor_types type,
				 u32 attr, int channel)
{
	const struct tmp464_data *data = _data;

	if (channel >= data->channels)
		return 0;

	if (type == hwmon_chip) {
		if (attr == hwmon_chip_update_interval)
			return 0644;
		return 0;
	}

	switch (attr) {
	case hwmon_temp_input:
	case hwmon_temp_max_alarm:
	case hwmon_temp_crit_alarm:
	case hwmon_temp_crit_hyst:
		return 0444;
	case hwmon_temp_enable:
	case hwmon_temp_max:
	case hwmon_temp_crit:
		return 0644;
	case hwmon_temp_max_hyst:
		if (!channel)
			return 0644;
		return 0444;
	case hwmon_temp_label:
		if (data->channel[channel].label)
			return 0444;
		return 0;
	case hwmon_temp_fault:
		if (channel)
			return 0444;
		return 0;
	case hwmon_temp_offset:
		if (channel)
			return 0644;
		return 0;
	default:
		return 0;
	}
}

static void tmp464_restore_lock(void *regmap)
{
	regmap_write(regmap, TMP464_LOCK_REG, TMP464_LOCK_VAL);
}

static void tmp464_restore_config(void *_data)
{
	struct tmp464_data *data = _data;

	regmap_write(data->regmap, TMP464_CONFIG_REG, data->config_orig);
}

static int tmp464_init_client(struct device *dev, struct tmp464_data *data)
{
	struct regmap *regmap = data->regmap;
	unsigned int regval;
	int err;

	err = regmap_read(regmap, TMP464_LOCK_REG, &regval);
	if (err)
		return err;
	if (regval == TMP464_LOCKED) {
		/* Explicitly unlock chip if it is locked */
		err = regmap_write(regmap, TMP464_LOCK_REG, TMP464_UNLOCK_VAL);
		if (err)
			return err;
		/* and lock it again when unloading the driver */
		err = devm_add_action_or_reset(dev, tmp464_restore_lock, regmap);
		if (err)
			return err;
	}

	err = regmap_read(regmap, TMP464_CONFIG_REG, &regval);
	if (err)
		return err;
	data->config_orig = regval;
	err = devm_add_action_or_reset(dev, tmp464_restore_config, data);
	if (err)
		return err;

	/* Default to 500 ms update interval */
	err = regmap_update_bits(regmap, TMP464_CONFIG_REG,
				 TMP464_CONFIG_CONVERSION_RATE_MASK | TMP464_CONFIG_SHUTDOWN,
				 BIT(TMP464_CONFIG_CONVERSION_RATE_B0) |
				 BIT(TMP464_CONFIG_CONVERSION_RATE_B2));
	if (err)
		return err;

	data->update_interval = 500;

	return tmp464_enable_channels(data);
}

static int tmp464_detect(struct i2c_client *client,
			 struct i2c_board_info *info)
{
	struct i2c_adapter *adapter = client->adapter;
	char *name, *chip;
	int reg;

	if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_WORD_DATA))
		return -ENODEV;

	reg = i2c_smbus_read_word_swapped(client, TMP464_MANUFACTURER_ID_REG);
	if (reg < 0)
		return reg;
	if (reg != TMP464_MANUFACTURER_ID)
		return -ENODEV;

	/* Check for "always return zero" bits */
	reg = i2c_smbus_read_word_swapped(client, TMP464_THERM_STATUS_REG);
	if (reg < 0)
		return reg;
	if (reg & 0x1f)
		return -ENODEV;
	reg = i2c_smbus_read_word_swapped(client, TMP464_THERM2_STATUS_REG);
	if (reg < 0)
		return reg;
	if (reg & 0x1f)
		return -ENODEV;

	reg = i2c_smbus_read_word_swapped(client, TMP464_DEVICE_ID_REG);
	if (reg < 0)
		return reg;
	switch (reg) {
	case TMP464_DEVICE_ID:
		name = "tmp464";
		chip = "TMP464";
		break;
	case TMP468_DEVICE_ID:
		name = "tmp468";
		chip = "TMP468";
		break;
	default:
		return -ENODEV;
	}

	strscpy(info->type, name, I2C_NAME_SIZE);
	dev_info(&adapter->dev, "Detected TI %s chip at 0x%02x\n", chip, client->addr);

	return 0;
}

static int tmp464_probe_child_from_dt(struct device *dev,
				      struct device_node *child,
				      struct tmp464_data *data)

{
	struct regmap *regmap = data->regmap;
	u32 channel;
	s32 nfactor;
	int err;

	err = of_property_read_u32(child, "reg", &channel);
	if (err) {
		dev_err(dev, "missing reg property of %pOFn\n", child);
		return err;
	}

	if (channel >= data->channels) {
		dev_err(dev, "invalid reg %d of %pOFn\n", channel, child);
		return -EINVAL;
	}

	of_property_read_string(child, "label", &data->channel[channel].label);

	data->channel[channel].enabled = of_device_is_available(child);

	err = of_property_read_s32(child, "ti,n-factor", &nfactor);
	if (err && err != -EINVAL)
		return err;
	if (!err) {
		if (channel == 0) {
			dev_err(dev, "n-factor can't be set for internal channel\n");
			return -EINVAL;
		}
		if (nfactor > 127 || nfactor < -128) {
			dev_err(dev, "n-factor for channel %d invalid (%d)\n",
				channel, nfactor);
			return -EINVAL;
		}
		err = regmap_write(regmap, TMP464_N_FACTOR_REG(channel),
				   (nfactor << 8) & 0xff00);
		if (err)
			return err;
	}

	return 0;
}

static int tmp464_probe_from_dt(struct device *dev, struct tmp464_data *data)
{
	const struct device_node *np = dev->of_node;
	int err;

	for_each_child_of_node_scoped(np, child) {
		if (strcmp(child->name, "channel"))
			continue;

		err = tmp464_probe_child_from_dt(dev, child, data);
		if (err)
			return err;
	}

	return 0;
}

static const struct hwmon_ops tmp464_ops = {
	.is_visible = tmp464_is_visible,
	.read = tmp464_read,
	.read_string = tmp464_read_string,
	.write = tmp464_write,
};

static const struct hwmon_channel_info * const tmp464_info[] = {
	HWMON_CHANNEL_INFO(chip,
			   HWMON_C_UPDATE_INTERVAL),
	HWMON_CHANNEL_INFO(temp,
			   HWMON_T_INPUT | HWMON_T_MAX | HWMON_T_MAX_HYST | HWMON_T_CRIT |
			   HWMON_T_CRIT_HYST | HWMON_T_MAX_ALARM | HWMON_T_CRIT_ALARM |
			   HWMON_T_LABEL | HWMON_T_ENABLE,
			   HWMON_T_INPUT | HWMON_T_OFFSET | HWMON_T_MAX | HWMON_T_MAX_HYST |
			   HWMON_T_CRIT | HWMON_T_CRIT_HYST | HWMON_T_MAX_ALARM |
			   HWMON_T_CRIT_ALARM | HWMON_T_FAULT | HWMON_T_LABEL | HWMON_T_ENABLE,
			   HWMON_T_INPUT | HWMON_T_OFFSET | HWMON_T_MAX | HWMON_T_MAX_HYST |
			   HWMON_T_CRIT | HWMON_T_CRIT_HYST | HWMON_T_MAX_ALARM |
			   HWMON_T_CRIT_ALARM | HWMON_T_FAULT | HWMON_T_LABEL | HWMON_T_ENABLE,
			   HWMON_T_INPUT | HWMON_T_OFFSET | HWMON_T_MAX | HWMON_T_MAX_HYST |
			   HWMON_T_CRIT | HWMON_T_CRIT_HYST | HWMON_T_MAX_ALARM |
			   HWMON_T_CRIT_ALARM | HWMON_T_FAULT | HWMON_T_LABEL | HWMON_T_ENABLE,
			   HWMON_T_INPUT | HWMON_T_OFFSET | HWMON_T_MAX | HWMON_T_MAX_HYST |
			   HWMON_T_CRIT | HWMON_T_CRIT_HYST | HWMON_T_MAX_ALARM |
			   HWMON_T_CRIT_ALARM | HWMON_T_FAULT | HWMON_T_LABEL | HWMON_T_ENABLE,
			   HWMON_T_INPUT | HWMON_T_OFFSET | HWMON_T_MAX | HWMON_T_MAX_HYST |
			   HWMON_T_CRIT | HWMON_T_CRIT_HYST | HWMON_T_MAX_ALARM |
			   HWMON_T_CRIT_ALARM | HWMON_T_FAULT | HWMON_T_LABEL | HWMON_T_ENABLE,
			   HWMON_T_INPUT | HWMON_T_OFFSET | HWMON_T_MAX | HWMON_T_MAX_HYST |
			   HWMON_T_CRIT | HWMON_T_CRIT_HYST | HWMON_T_MAX_ALARM |
			   HWMON_T_CRIT_ALARM | HWMON_T_FAULT | HWMON_T_LABEL | HWMON_T_ENABLE,
			   HWMON_T_INPUT | HWMON_T_OFFSET | HWMON_T_MAX | HWMON_T_MAX_HYST |
			   HWMON_T_CRIT | HWMON_T_CRIT_HYST | HWMON_T_MAX_ALARM |
			   HWMON_T_CRIT_ALARM | HWMON_T_FAULT | HWMON_T_LABEL | HWMON_T_ENABLE,
			   HWMON_T_INPUT | HWMON_T_OFFSET | HWMON_T_MAX | HWMON_T_MAX_HYST |
			   HWMON_T_CRIT | HWMON_T_CRIT_HYST | HWMON_T_MAX_ALARM |
			   HWMON_T_CRIT_ALARM | HWMON_T_FAULT | HWMON_T_LABEL | HWMON_T_ENABLE),
	NULL
};

static const struct hwmon_chip_info tmp464_chip_info = {
	.ops = &tmp464_ops,
	.info = tmp464_info,
};

/* regmap */

static bool tmp464_is_volatile_reg(struct device *dev, unsigned int reg)
{
	return (reg < TMP464_TEMP_REG(TMP468_NUM_CHANNELS) ||
		reg == TMP464_THERM_STATUS_REG ||
		reg == TMP464_THERM2_STATUS_REG ||
		reg == TMP464_REMOTE_OPEN_REG);
}

static const struct regmap_config tmp464_regmap_config = {
	.reg_bits = 8,
	.val_bits = 16,
	.max_register = TMP464_DEVICE_ID_REG,
	.volatile_reg = tmp464_is_volatile_reg,
	.val_format_endian = REGMAP_ENDIAN_BIG,
	.cache_type = REGCACHE_MAPLE,
	.use_single_read = true,
	.use_single_write = true,
};

static int tmp464_probe(struct i2c_client *client)
{
	struct device *dev = &client->dev;
	struct device *hwmon_dev;
	struct tmp464_data *data;
	int i, err;

	if (!i2c_check_functionality(client->adapter, I2C_FUNC_SMBUS_WORD_DATA)) {
		dev_err(&client->dev, "i2c functionality check failed\n");
		return -ENODEV;
	}
	data = devm_kzalloc(dev, sizeof(struct tmp464_data), GFP_KERNEL);
	if (!data)
		return -ENOMEM;

	data->channels = (int)(unsigned long)i2c_get_match_data(client);

	data->regmap = devm_regmap_init_i2c(client, &tmp464_regmap_config);
	if (IS_ERR(data->regmap))
		return PTR_ERR(data->regmap);

	for (i = 0; i < data->channels; i++)
		data->channel[i].enabled = true;

	err = tmp464_init_client(dev, data);
	if (err)
		return err;

	if (dev->of_node) {
		err = tmp464_probe_from_dt(dev, data);
		if (err)
			return err;
	}

	hwmon_dev = devm_hwmon_device_register_with_info(dev, client->name,
							 data, &tmp464_chip_info, NULL);
	return PTR_ERR_OR_ZERO(hwmon_dev);
}

static struct i2c_driver tmp464_driver = {
	.class = I2C_CLASS_HWMON,
	.driver = {
		.name	= "tmp464",
		.of_match_table = of_match_ptr(tmp464_of_match),
	},
	.probe = tmp464_probe,
	.id_table = tmp464_id,
	.detect = tmp464_detect,
	.address_list = normal_i2c,
};

module_i2c_driver(tmp464_driver);

MODULE_AUTHOR("Agathe Porte <agathe.porte@nokia.com>");
MODULE_DESCRIPTION("Texas Instruments TMP464 temperature sensor driver");
MODULE_LICENSE("GPL");
