// SPDX-License-Identifier: GPL-2.0
/*
 * max31827.c - Support for Maxim Low-Power Switch
 *
 * Copyright (c) 2023 Daniel Matyas <daniel.matyas@analog.com>
 */

#include <linux/bitfield.h>
#include <linux/bitops.h>
#include <linux/delay.h>
#include <linux/hwmon.h>
#include <linux/i2c.h>
#include <linux/mutex.h>
#include <linux/of_device.h>
#include <linux/regmap.h>
#include <linux/regulator/consumer.h>

#define MAX31827_T_REG			0x0
#define MAX31827_CONFIGURATION_REG	0x2
#define MAX31827_TH_REG			0x4
#define MAX31827_TL_REG			0x6
#define MAX31827_TH_HYST_REG		0x8
#define MAX31827_TL_HYST_REG		0xA

#define MAX31827_CONFIGURATION_1SHOT_MASK	BIT(0)
#define MAX31827_CONFIGURATION_CNV_RATE_MASK	GENMASK(3, 1)
#define MAX31827_CONFIGURATION_TIMEOUT_MASK	BIT(5)
#define MAX31827_CONFIGURATION_RESOLUTION_MASK	GENMASK(7, 6)
#define MAX31827_CONFIGURATION_ALRM_POL_MASK	BIT(8)
#define MAX31827_CONFIGURATION_COMP_INT_MASK	BIT(9)
#define MAX31827_CONFIGURATION_FLT_Q_MASK	GENMASK(11, 10)
#define MAX31827_CONFIGURATION_U_TEMP_STAT_MASK	BIT(14)
#define MAX31827_CONFIGURATION_O_TEMP_STAT_MASK	BIT(15)

#define MAX31827_ALRM_POL_LOW	0x0
#define MAX31827_ALRM_POL_HIGH	0x1
#define MAX31827_FLT_Q_1	0x0
#define MAX31827_FLT_Q_4	0x2

#define MAX31827_8_BIT_CNV_TIME		9
#define MAX31827_9_BIT_CNV_TIME		18
#define MAX31827_10_BIT_CNV_TIME	35
#define MAX31827_12_BIT_CNV_TIME	140

#define MAX31827_16_BIT_TO_M_DGR(x)	(sign_extend32(x, 15) * 1000 / 16)
#define MAX31827_M_DGR_TO_16_BIT(x)	(((x) << 4) / 1000)
#define MAX31827_DEVICE_ENABLE(x)	((x) ? 0xA : 0x0)

enum chips { max31827 = 1, max31828, max31829 };

enum max31827_cnv {
	MAX31827_CNV_1_DIV_64_HZ = 1,
	MAX31827_CNV_1_DIV_32_HZ,
	MAX31827_CNV_1_DIV_16_HZ,
	MAX31827_CNV_1_DIV_4_HZ,
	MAX31827_CNV_1_HZ,
	MAX31827_CNV_4_HZ,
	MAX31827_CNV_8_HZ,
};

static const u16 max31827_conversions[] = {
	[MAX31827_CNV_1_DIV_64_HZ] = 64000,
	[MAX31827_CNV_1_DIV_32_HZ] = 32000,
	[MAX31827_CNV_1_DIV_16_HZ] = 16000,
	[MAX31827_CNV_1_DIV_4_HZ] = 4000,
	[MAX31827_CNV_1_HZ] = 1000,
	[MAX31827_CNV_4_HZ] = 250,
	[MAX31827_CNV_8_HZ] = 125,
};

enum max31827_resolution {
	MAX31827_RES_8_BIT = 0,
	MAX31827_RES_9_BIT,
	MAX31827_RES_10_BIT,
	MAX31827_RES_12_BIT,
};

static const u16 max31827_resolutions[] = {
	[MAX31827_RES_8_BIT] = 1000,
	[MAX31827_RES_9_BIT] = 500,
	[MAX31827_RES_10_BIT] = 250,
	[MAX31827_RES_12_BIT] = 62,
};

static const u16 max31827_conv_times[] = {
	[MAX31827_RES_8_BIT] = MAX31827_8_BIT_CNV_TIME,
	[MAX31827_RES_9_BIT] = MAX31827_9_BIT_CNV_TIME,
	[MAX31827_RES_10_BIT] = MAX31827_10_BIT_CNV_TIME,
	[MAX31827_RES_12_BIT] = MAX31827_12_BIT_CNV_TIME,
};

struct max31827_state {
	/*
	 * Prevent simultaneous access to the i2c client.
	 */
	struct mutex lock;
	struct regmap *regmap;
	bool enable;
	unsigned int resolution;
	unsigned int update_interval;
};

static const struct regmap_config max31827_regmap = {
	.reg_bits = 8,
	.val_bits = 16,
	.max_register = 0xA,
};

static int shutdown_write(struct max31827_state *st, unsigned int reg,
			  unsigned int mask, unsigned int val)
{
	unsigned int cfg;
	unsigned int cnv_rate;
	int ret;

	/*
	 * Before the Temperature Threshold Alarm, Alarm Hysteresis Threshold
	 * and Resolution bits from Configuration register are changed over I2C,
	 * the part must be in shutdown mode.
	 *
	 * Mutex is used to ensure, that some other process doesn't change the
	 * configuration register.
	 */
	mutex_lock(&st->lock);

	if (!st->enable) {
		if (!mask)
			ret = regmap_write(st->regmap, reg, val);
		else
			ret = regmap_update_bits(st->regmap, reg, mask, val);
		goto unlock;
	}

	ret = regmap_read(st->regmap, MAX31827_CONFIGURATION_REG, &cfg);
	if (ret)
		goto unlock;

	cnv_rate = MAX31827_CONFIGURATION_CNV_RATE_MASK & cfg;
	cfg = cfg & ~(MAX31827_CONFIGURATION_1SHOT_MASK |
		      MAX31827_CONFIGURATION_CNV_RATE_MASK);
	ret = regmap_write(st->regmap, MAX31827_CONFIGURATION_REG, cfg);
	if (ret)
		goto unlock;

	if (!mask)
		ret = regmap_write(st->regmap, reg, val);
	else
		ret = regmap_update_bits(st->regmap, reg, mask, val);

	if (ret)
		goto unlock;

	ret = regmap_update_bits(st->regmap, MAX31827_CONFIGURATION_REG,
				 MAX31827_CONFIGURATION_CNV_RATE_MASK,
				 cnv_rate);

unlock:
	mutex_unlock(&st->lock);
	return ret;
}

static int write_alarm_val(struct max31827_state *st, unsigned int reg,
			   long val)
{
	val = MAX31827_M_DGR_TO_16_BIT(val);

	return shutdown_write(st, reg, 0, val);
}

static umode_t max31827_is_visible(const void *state,
				   enum hwmon_sensor_types type, u32 attr,
				   int channel)
{
	if (type == hwmon_temp) {
		switch (attr) {
		case hwmon_temp_enable:
		case hwmon_temp_max:
		case hwmon_temp_min:
		case hwmon_temp_max_hyst:
		case hwmon_temp_min_hyst:
			return 0644;
		case hwmon_temp_input:
		case hwmon_temp_min_alarm:
		case hwmon_temp_max_alarm:
			return 0444;
		default:
			return 0;
		}
	} else if (type == hwmon_chip) {
		if (attr == hwmon_chip_update_interval)
			return 0644;
	}

	return 0;
}

static int max31827_read(struct device *dev, enum hwmon_sensor_types type,
			 u32 attr, int channel, long *val)
{
	struct max31827_state *st = dev_get_drvdata(dev);
	unsigned int uval;
	int ret = 0;

	switch (type) {
	case hwmon_temp:
		switch (attr) {
		case hwmon_temp_enable:
			ret = regmap_read(st->regmap,
					  MAX31827_CONFIGURATION_REG, &uval);
			if (ret)
				break;

			uval = FIELD_GET(MAX31827_CONFIGURATION_1SHOT_MASK |
					 MAX31827_CONFIGURATION_CNV_RATE_MASK,
					 uval);
			*val = !!uval;

			break;
		case hwmon_temp_input:
			mutex_lock(&st->lock);

			if (!st->enable) {
				/*
				 * This operation requires mutex protection,
				 * because the chip configuration should not
				 * be changed during the conversion process.
				 */

				ret = regmap_update_bits(st->regmap,
							 MAX31827_CONFIGURATION_REG,
							 MAX31827_CONFIGURATION_1SHOT_MASK,
							 1);
				if (ret) {
					mutex_unlock(&st->lock);
					return ret;
				}
				msleep(max31827_conv_times[st->resolution]);
			}

			/*
			 * For 12-bit resolution the conversion time is 140 ms,
			 * thus an additional 15 ms is needed to complete the
			 * conversion: 125 ms + 15 ms = 140 ms
			 */
			if (max31827_resolutions[st->resolution] == 12 &&
			    st->update_interval == 125)
				usleep_range(15000, 20000);

			ret = regmap_read(st->regmap, MAX31827_T_REG, &uval);

			mutex_unlock(&st->lock);

			if (ret)
				break;

			*val = MAX31827_16_BIT_TO_M_DGR(uval);

			break;
		case hwmon_temp_max:
			ret = regmap_read(st->regmap, MAX31827_TH_REG, &uval);
			if (ret)
				break;

			*val = MAX31827_16_BIT_TO_M_DGR(uval);
			break;
		case hwmon_temp_max_hyst:
			ret = regmap_read(st->regmap, MAX31827_TH_HYST_REG,
					  &uval);
			if (ret)
				break;

			*val = MAX31827_16_BIT_TO_M_DGR(uval);
			break;
		case hwmon_temp_max_alarm:
			ret = regmap_read(st->regmap,
					  MAX31827_CONFIGURATION_REG, &uval);
			if (ret)
				break;

			*val = FIELD_GET(MAX31827_CONFIGURATION_O_TEMP_STAT_MASK,
					 uval);
			break;
		case hwmon_temp_min:
			ret = regmap_read(st->regmap, MAX31827_TL_REG, &uval);
			if (ret)
				break;

			*val = MAX31827_16_BIT_TO_M_DGR(uval);
			break;
		case hwmon_temp_min_hyst:
			ret = regmap_read(st->regmap, MAX31827_TL_HYST_REG,
					  &uval);
			if (ret)
				break;

			*val = MAX31827_16_BIT_TO_M_DGR(uval);
			break;
		case hwmon_temp_min_alarm:
			ret = regmap_read(st->regmap,
					  MAX31827_CONFIGURATION_REG, &uval);
			if (ret)
				break;

			*val = FIELD_GET(MAX31827_CONFIGURATION_U_TEMP_STAT_MASK,
					 uval);
			break;
		default:
			ret = -EOPNOTSUPP;
			break;
		}

		break;

	case hwmon_chip:
		if (attr == hwmon_chip_update_interval) {
			ret = regmap_read(st->regmap,
					  MAX31827_CONFIGURATION_REG, &uval);
			if (ret)
				break;

			uval = FIELD_GET(MAX31827_CONFIGURATION_CNV_RATE_MASK,
					 uval);
			*val = max31827_conversions[uval];
		}
		break;

	default:
		ret = -EOPNOTSUPP;
		break;
	}

	return ret;
}

static int max31827_write(struct device *dev, enum hwmon_sensor_types type,
			  u32 attr, int channel, long val)
{
	struct max31827_state *st = dev_get_drvdata(dev);
	int res = 1;
	int ret;

	switch (type) {
	case hwmon_temp:
		switch (attr) {
		case hwmon_temp_enable:
			if (val >> 1)
				return -EINVAL;

			mutex_lock(&st->lock);
			/**
			 * The chip should not be enabled while a conversion is
			 * performed. Neither should the chip be enabled when
			 * the alarm values are changed.
			 */

			st->enable = val;

			ret = regmap_update_bits(st->regmap,
						 MAX31827_CONFIGURATION_REG,
						 MAX31827_CONFIGURATION_1SHOT_MASK |
						 MAX31827_CONFIGURATION_CNV_RATE_MASK,
						 MAX31827_DEVICE_ENABLE(val));

			mutex_unlock(&st->lock);

			return ret;

		case hwmon_temp_max:
			return write_alarm_val(st, MAX31827_TH_REG, val);

		case hwmon_temp_max_hyst:
			return write_alarm_val(st, MAX31827_TH_HYST_REG, val);

		case hwmon_temp_min:
			return write_alarm_val(st, MAX31827_TL_REG, val);

		case hwmon_temp_min_hyst:
			return write_alarm_val(st, MAX31827_TL_HYST_REG, val);

		default:
			return -EOPNOTSUPP;
		}

	case hwmon_chip:
		if (attr == hwmon_chip_update_interval) {
			if (!st->enable)
				return -EINVAL;

			/*
			 * Convert the desired conversion rate into register
			 * bits. res is already initialized with 1.
			 *
			 * This was inspired by lm73 driver.
			 */
			while (res < ARRAY_SIZE(max31827_conversions) &&
			       val < max31827_conversions[res])
				res++;

			if (res == ARRAY_SIZE(max31827_conversions))
				res = ARRAY_SIZE(max31827_conversions) - 1;

			res = FIELD_PREP(MAX31827_CONFIGURATION_CNV_RATE_MASK,
					 res);

			ret = regmap_update_bits(st->regmap,
						 MAX31827_CONFIGURATION_REG,
						 MAX31827_CONFIGURATION_CNV_RATE_MASK,
						 res);
			if (ret)
				return ret;

			st->update_interval = val;
		}
		break;

	default:
		return -EOPNOTSUPP;
	}

	return 0;
}

static ssize_t temp1_resolution_show(struct device *dev,
				     struct device_attribute *devattr,
				     char *buf)
{
	struct max31827_state *st = dev_get_drvdata(dev);
	unsigned int val;
	int ret;

	ret = regmap_read(st->regmap, MAX31827_CONFIGURATION_REG, &val);
	if (ret)
		return ret;

	val = FIELD_GET(MAX31827_CONFIGURATION_RESOLUTION_MASK, val);

	return scnprintf(buf, PAGE_SIZE, "%u\n", max31827_resolutions[val]);
}

static ssize_t temp1_resolution_store(struct device *dev,
				      struct device_attribute *devattr,
				      const char *buf, size_t count)
{
	struct max31827_state *st = dev_get_drvdata(dev);
	unsigned int idx = 0;
	unsigned int val;
	int ret;

	ret = kstrtouint(buf, 10, &val);
	if (ret)
		return ret;

	/*
	 * Convert the desired resolution into register
	 * bits. idx is already initialized with 0.
	 *
	 * This was inspired by lm73 driver.
	 */
	while (idx < ARRAY_SIZE(max31827_resolutions) &&
	       val < max31827_resolutions[idx])
		idx++;

	if (idx == ARRAY_SIZE(max31827_resolutions))
		idx = ARRAY_SIZE(max31827_resolutions) - 1;

	st->resolution = idx;

	ret = shutdown_write(st, MAX31827_CONFIGURATION_REG,
			     MAX31827_CONFIGURATION_RESOLUTION_MASK,
			     FIELD_PREP(MAX31827_CONFIGURATION_RESOLUTION_MASK,
					idx));

	return ret ? ret : count;
}

static DEVICE_ATTR_RW(temp1_resolution);

static struct attribute *max31827_attrs[] = {
	&dev_attr_temp1_resolution.attr,
	NULL
};
ATTRIBUTE_GROUPS(max31827);

static const struct i2c_device_id max31827_i2c_ids[] = {
	{ "max31827", max31827 },
	{ "max31828", max31828 },
	{ "max31829", max31829 },
	{ }
};
MODULE_DEVICE_TABLE(i2c, max31827_i2c_ids);

static int max31827_init_client(struct max31827_state *st,
				struct device *dev)
{
	struct fwnode_handle *fwnode;
	unsigned int res = 0;
	u32 data, lsb_idx;
	enum chips type;
	bool prop;
	int ret;

	fwnode = dev_fwnode(dev);

	st->enable = true;
	res |= MAX31827_DEVICE_ENABLE(1);

	res |= MAX31827_CONFIGURATION_RESOLUTION_MASK;

	prop = fwnode_property_read_bool(fwnode, "adi,comp-int");
	res |= FIELD_PREP(MAX31827_CONFIGURATION_COMP_INT_MASK, prop);

	prop = fwnode_property_read_bool(fwnode, "adi,timeout-enable");
	res |= FIELD_PREP(MAX31827_CONFIGURATION_TIMEOUT_MASK, !prop);

	type = (enum chips)(uintptr_t)device_get_match_data(dev);

	if (fwnode_property_present(fwnode, "adi,alarm-pol")) {
		ret = fwnode_property_read_u32(fwnode, "adi,alarm-pol", &data);
		if (ret)
			return ret;

		res |= FIELD_PREP(MAX31827_CONFIGURATION_ALRM_POL_MASK, !!data);
	} else {
		/*
		 * Set default value.
		 */
		switch (type) {
		case max31827:
		case max31828:
			res |= FIELD_PREP(MAX31827_CONFIGURATION_ALRM_POL_MASK,
					  MAX31827_ALRM_POL_LOW);
			break;
		case max31829:
			res |= FIELD_PREP(MAX31827_CONFIGURATION_ALRM_POL_MASK,
					  MAX31827_ALRM_POL_HIGH);
			break;
		default:
			return -EOPNOTSUPP;
		}
	}

	if (fwnode_property_present(fwnode, "adi,fault-q")) {
		ret = fwnode_property_read_u32(fwnode, "adi,fault-q", &data);
		if (ret)
			return ret;

		/*
		 * Convert the desired fault queue into register bits.
		 */
		if (data != 0)
			lsb_idx = __ffs(data);

		if (hweight32(data) != 1 || lsb_idx > 4) {
			dev_err(dev, "Invalid data in adi,fault-q\n");
			return -EINVAL;
		}

		res |= FIELD_PREP(MAX31827_CONFIGURATION_FLT_Q_MASK, lsb_idx);
	} else {
		/*
		 * Set default value.
		 */
		switch (type) {
		case max31827:
			res |= FIELD_PREP(MAX31827_CONFIGURATION_FLT_Q_MASK,
					  MAX31827_FLT_Q_1);
			break;
		case max31828:
		case max31829:
			res |= FIELD_PREP(MAX31827_CONFIGURATION_FLT_Q_MASK,
					  MAX31827_FLT_Q_4);
			break;
		default:
			return -EOPNOTSUPP;
		}
	}

	return regmap_write(st->regmap, MAX31827_CONFIGURATION_REG, res);
}

static const struct hwmon_channel_info *max31827_info[] = {
	HWMON_CHANNEL_INFO(temp, HWMON_T_ENABLE | HWMON_T_INPUT | HWMON_T_MIN |
					 HWMON_T_MIN_HYST | HWMON_T_MIN_ALARM |
					 HWMON_T_MAX | HWMON_T_MAX_HYST |
					 HWMON_T_MAX_ALARM),
	HWMON_CHANNEL_INFO(chip, HWMON_C_UPDATE_INTERVAL),
	NULL,
};

static const struct hwmon_ops max31827_hwmon_ops = {
	.is_visible = max31827_is_visible,
	.read = max31827_read,
	.write = max31827_write,
};

static const struct hwmon_chip_info max31827_chip_info = {
	.ops = &max31827_hwmon_ops,
	.info = max31827_info,
};

static int max31827_probe(struct i2c_client *client)
{
	struct device *dev = &client->dev;
	struct device *hwmon_dev;
	struct max31827_state *st;
	int err;

	if (!i2c_check_functionality(client->adapter, I2C_FUNC_SMBUS_WORD_DATA))
		return -EOPNOTSUPP;

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

	mutex_init(&st->lock);

	st->regmap = devm_regmap_init_i2c(client, &max31827_regmap);
	if (IS_ERR(st->regmap))
		return dev_err_probe(dev, PTR_ERR(st->regmap),
				     "Failed to allocate regmap.\n");

	err = devm_regulator_get_enable(dev, "vref");
	if (err)
		return dev_err_probe(dev, err, "failed to enable regulator\n");

	err = max31827_init_client(st, dev);
	if (err)
		return err;

	hwmon_dev = devm_hwmon_device_register_with_info(dev, client->name, st,
							 &max31827_chip_info,
							 max31827_groups);

	return PTR_ERR_OR_ZERO(hwmon_dev);
}

static const struct of_device_id max31827_of_match[] = {
	{
		.compatible = "adi,max31827",
		.data = (void *)max31827
	},
	{
		.compatible = "adi,max31828",
		.data = (void *)max31828
	},
	{
		.compatible = "adi,max31829",
		.data = (void *)max31829
	},
	{ }
};
MODULE_DEVICE_TABLE(of, max31827_of_match);

static struct i2c_driver max31827_driver = {
	.driver = {
		.name = "max31827",
		.of_match_table = max31827_of_match,
	},
	.probe = max31827_probe,
	.id_table = max31827_i2c_ids,
};
module_i2c_driver(max31827_driver);

MODULE_AUTHOR("Daniel Matyas <daniel.matyas@analog.com>");
MODULE_DESCRIPTION("Maxim MAX31827 low-power temperature switch driver");
MODULE_LICENSE("GPL");
