// SPDX-License-Identifier: GPL-2.0-or-later
/*
 * Driver for MAX31730 3-Channel Remote Temperature Sensor
 *
 * Copyright (c) 2019 Guenter Roeck <linux@roeck-us.net>
 */

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

/* Addresses scanned */
static const unsigned short normal_i2c[] = { 0x1c, 0x1d, 0x1e, 0x1f, 0x4c,
					     0x4d, 0x4e, 0x4f, I2C_CLIENT_END };

/* The MAX31730 registers */
#define MAX31730_REG_TEMP		0x00
#define MAX31730_REG_CONF		0x13
#define  MAX31730_STOP			BIT(7)
#define  MAX31730_EXTRANGE		BIT(1)
#define MAX31730_REG_TEMP_OFFSET	0x16
#define  MAX31730_TEMP_OFFSET_BASELINE	0x77
#define MAX31730_REG_OFFSET_ENABLE	0x17
#define MAX31730_REG_TEMP_MAX		0x20
#define MAX31730_REG_TEMP_MIN		0x30
#define MAX31730_REG_STATUS_HIGH	0x32
#define MAX31730_REG_STATUS_LOW		0x33
#define MAX31730_REG_CHANNEL_ENABLE	0x35
#define MAX31730_REG_TEMP_FAULT		0x36

#define MAX31730_REG_MFG_ID		0x50
#define  MAX31730_MFG_ID		0x4d
#define MAX31730_REG_MFG_REV		0x51
#define  MAX31730_MFG_REV		0x01

#define MAX31730_TEMP_MIN		(-128000)
#define MAX31730_TEMP_MAX		127937

/* Each client has this additional data */
struct max31730_data {
	struct i2c_client	*client;
	u8			orig_conf;
	u8			current_conf;
	u8			offset_enable;
	u8			channel_enable;
};

/*-----------------------------------------------------------------------*/

static inline long max31730_reg_to_mc(s16 temp)
{
	return DIV_ROUND_CLOSEST((temp >> 4) * 1000, 16);
}

static int max31730_write_config(struct max31730_data *data, u8 set_mask,
				 u8 clr_mask)
{
	u8 value;

	clr_mask |= MAX31730_EXTRANGE;
	value = data->current_conf & ~clr_mask;
	value |= set_mask;

	if (data->current_conf != value) {
		s32 err;

		err = i2c_smbus_write_byte_data(data->client, MAX31730_REG_CONF,
						value);
		if (err)
			return err;
		data->current_conf = value;
	}
	return 0;
}

static int max31730_set_enable(struct i2c_client *client, int reg,
			       u8 *confdata, int channel, bool enable)
{
	u8 regval = *confdata;
	int err;

	if (enable)
		regval |= BIT(channel);
	else
		regval &= ~BIT(channel);

	if (regval != *confdata) {
		err = i2c_smbus_write_byte_data(client, reg, regval);
		if (err)
			return err;
		*confdata = regval;
	}
	return 0;
}

static int max31730_set_offset_enable(struct max31730_data *data, int channel,
				      bool enable)
{
	return max31730_set_enable(data->client, MAX31730_REG_OFFSET_ENABLE,
				   &data->offset_enable, channel, enable);
}

static int max31730_set_channel_enable(struct max31730_data *data, int channel,
				       bool enable)
{
	return max31730_set_enable(data->client, MAX31730_REG_CHANNEL_ENABLE,
				   &data->channel_enable, channel, enable);
}

static int max31730_read(struct device *dev, enum hwmon_sensor_types type,
			 u32 attr, int channel, long *val)
{
	struct max31730_data *data = dev_get_drvdata(dev);
	int regval, reg, offset;

	if (type != hwmon_temp)
		return -EINVAL;

	switch (attr) {
	case hwmon_temp_input:
		if (!(data->channel_enable & BIT(channel)))
			return -ENODATA;
		reg = MAX31730_REG_TEMP + (channel * 2);
		break;
	case hwmon_temp_max:
		reg = MAX31730_REG_TEMP_MAX + (channel * 2);
		break;
	case hwmon_temp_min:
		reg = MAX31730_REG_TEMP_MIN;
		break;
	case hwmon_temp_enable:
		*val = !!(data->channel_enable & BIT(channel));
		return 0;
	case hwmon_temp_offset:
		if (!channel)
			return -EINVAL;
		if (!(data->offset_enable & BIT(channel))) {
			*val = 0;
			return 0;
		}
		offset = i2c_smbus_read_byte_data(data->client,
						  MAX31730_REG_TEMP_OFFSET);
		if (offset < 0)
			return offset;
		*val = (offset - MAX31730_TEMP_OFFSET_BASELINE) * 125;
		return 0;
	case hwmon_temp_fault:
		regval = i2c_smbus_read_byte_data(data->client,
						  MAX31730_REG_TEMP_FAULT);
		if (regval < 0)
			return regval;
		*val = !!(regval & BIT(channel));
		return 0;
	case hwmon_temp_min_alarm:
		regval = i2c_smbus_read_byte_data(data->client,
						  MAX31730_REG_STATUS_LOW);
		if (regval < 0)
			return regval;
		*val = !!(regval & BIT(channel));
		return 0;
	case hwmon_temp_max_alarm:
		regval = i2c_smbus_read_byte_data(data->client,
						  MAX31730_REG_STATUS_HIGH);
		if (regval < 0)
			return regval;
		*val = !!(regval & BIT(channel));
		return 0;
	default:
		return -EINVAL;
	}
	regval = i2c_smbus_read_word_swapped(data->client, reg);
	if (regval < 0)
		return regval;

	*val = max31730_reg_to_mc(regval);

	return 0;
}

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

	if (type != hwmon_temp)
		return -EINVAL;

	switch (attr) {
	case hwmon_temp_max:
		reg = MAX31730_REG_TEMP_MAX + channel * 2;
		break;
	case hwmon_temp_min:
		reg = MAX31730_REG_TEMP_MIN;
		break;
	case hwmon_temp_enable:
		if (val != 0 && val != 1)
			return -EINVAL;
		return max31730_set_channel_enable(data, channel, val);
	case hwmon_temp_offset:
		val = clamp_val(val, -14875, 17000) + 14875;
		val = DIV_ROUND_CLOSEST(val, 125);
		err = max31730_set_offset_enable(data, channel,
					val != MAX31730_TEMP_OFFSET_BASELINE);
		if (err)
			return err;
		return i2c_smbus_write_byte_data(data->client,
						 MAX31730_REG_TEMP_OFFSET, val);
	default:
		return -EINVAL;
	}

	val = clamp_val(val, MAX31730_TEMP_MIN, MAX31730_TEMP_MAX);
	val = DIV_ROUND_CLOSEST(val << 4, 1000) << 4;

	return i2c_smbus_write_word_swapped(data->client, reg, (u16)val);
}

static umode_t max31730_is_visible(const void *data,
				   enum hwmon_sensor_types type,
				   u32 attr, int channel)
{
	switch (type) {
	case hwmon_temp:
		switch (attr) {
		case hwmon_temp_input:
		case hwmon_temp_min_alarm:
		case hwmon_temp_max_alarm:
		case hwmon_temp_fault:
			return 0444;
		case hwmon_temp_min:
			return channel ? 0444 : 0644;
		case hwmon_temp_offset:
		case hwmon_temp_enable:
		case hwmon_temp_max:
			return 0644;
		}
		break;
	default:
		break;
	}
	return 0;
}

static const struct hwmon_channel_info *max31730_info[] = {
	HWMON_CHANNEL_INFO(chip,
			   HWMON_C_REGISTER_TZ),
	HWMON_CHANNEL_INFO(temp,
			   HWMON_T_INPUT | HWMON_T_MIN | HWMON_T_MAX |
			   HWMON_T_ENABLE |
			   HWMON_T_MIN_ALARM | HWMON_T_MAX_ALARM,
			   HWMON_T_INPUT | HWMON_T_MIN | HWMON_T_MAX |
			   HWMON_T_OFFSET | HWMON_T_ENABLE |
			   HWMON_T_MIN_ALARM | HWMON_T_MAX_ALARM |
			   HWMON_T_FAULT,
			   HWMON_T_INPUT | HWMON_T_MIN | HWMON_T_MAX |
			   HWMON_T_OFFSET | HWMON_T_ENABLE |
			   HWMON_T_MIN_ALARM | HWMON_T_MAX_ALARM |
			   HWMON_T_FAULT,
			   HWMON_T_INPUT | HWMON_T_MIN | HWMON_T_MAX |
			   HWMON_T_OFFSET | HWMON_T_ENABLE |
			   HWMON_T_MIN_ALARM | HWMON_T_MAX_ALARM |
			   HWMON_T_FAULT
			   ),
	NULL
};

static const struct hwmon_ops max31730_hwmon_ops = {
	.is_visible = max31730_is_visible,
	.read = max31730_read,
	.write = max31730_write,
};

static const struct hwmon_chip_info max31730_chip_info = {
	.ops = &max31730_hwmon_ops,
	.info = max31730_info,
};

static void max31730_remove(void *data)
{
	struct max31730_data *max31730 = data;
	struct i2c_client *client = max31730->client;

	i2c_smbus_write_byte_data(client, MAX31730_REG_CONF,
				  max31730->orig_conf);
}

static int
max31730_probe(struct i2c_client *client)
{
	struct device *dev = &client->dev;
	struct device *hwmon_dev;
	struct max31730_data *data;
	int status, err;

	if (!i2c_check_functionality(client->adapter,
			I2C_FUNC_SMBUS_BYTE_DATA | I2C_FUNC_SMBUS_WORD_DATA))
		return -EIO;

	data = devm_kzalloc(dev, sizeof(struct max31730_data), GFP_KERNEL);
	if (!data)
		return -ENOMEM;

	data->client = client;

	/* Cache original configuration and enable status */
	status = i2c_smbus_read_byte_data(client, MAX31730_REG_CHANNEL_ENABLE);
	if (status < 0)
		return status;
	data->channel_enable = status;

	status = i2c_smbus_read_byte_data(client, MAX31730_REG_OFFSET_ENABLE);
	if (status < 0)
		return status;
	data->offset_enable = status;

	status = i2c_smbus_read_byte_data(client, MAX31730_REG_CONF);
	if (status < 0)
		return status;
	data->orig_conf = status;
	data->current_conf = status;

	err = max31730_write_config(data,
				    data->channel_enable ? 0 : MAX31730_STOP,
				    data->channel_enable ? MAX31730_STOP : 0);
	if (err)
		return err;

	dev_set_drvdata(dev, data);

	err = devm_add_action_or_reset(dev, max31730_remove, data);
	if (err)
		return err;

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

static const struct i2c_device_id max31730_ids[] = {
	{ "max31730", 0, },
	{ }
};
MODULE_DEVICE_TABLE(i2c, max31730_ids);

static const struct of_device_id __maybe_unused max31730_of_match[] = {
	{
		.compatible = "maxim,max31730",
	},
	{ },
};
MODULE_DEVICE_TABLE(of, max31730_of_match);

static bool max31730_check_reg_temp(struct i2c_client *client,
				    int reg)
{
	int regval;

	regval = i2c_smbus_read_byte_data(client, reg + 1);
	return regval < 0 || (regval & 0x0f);
}

/* Return 0 if detection is successful, -ENODEV otherwise */
static int max31730_detect(struct i2c_client *client,
			   struct i2c_board_info *info)
{
	struct i2c_adapter *adapter = client->adapter;
	int regval;
	int i;

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

	regval = i2c_smbus_read_byte_data(client, MAX31730_REG_MFG_ID);
	if (regval != MAX31730_MFG_ID)
		return -ENODEV;
	regval = i2c_smbus_read_byte_data(client, MAX31730_REG_MFG_REV);
	if (regval != MAX31730_MFG_REV)
		return -ENODEV;

	/* lower 4 bit of temperature and limit registers must be 0 */
	if (max31730_check_reg_temp(client, MAX31730_REG_TEMP_MIN))
		return -ENODEV;

	for (i = 0; i < 4; i++) {
		if (max31730_check_reg_temp(client, MAX31730_REG_TEMP + i * 2))
			return -ENODEV;
		if (max31730_check_reg_temp(client,
					    MAX31730_REG_TEMP_MAX + i * 2))
			return -ENODEV;
	}

	strlcpy(info->type, "max31730", I2C_NAME_SIZE);

	return 0;
}

static int __maybe_unused max31730_suspend(struct device *dev)
{
	struct max31730_data *data = dev_get_drvdata(dev);

	return max31730_write_config(data, MAX31730_STOP, 0);
}

static int __maybe_unused max31730_resume(struct device *dev)
{
	struct max31730_data *data = dev_get_drvdata(dev);

	return max31730_write_config(data, 0, MAX31730_STOP);
}

static SIMPLE_DEV_PM_OPS(max31730_pm_ops, max31730_suspend, max31730_resume);

static struct i2c_driver max31730_driver = {
	.class		= I2C_CLASS_HWMON,
	.driver = {
		.name	= "max31730",
		.of_match_table = of_match_ptr(max31730_of_match),
		.pm	= &max31730_pm_ops,
	},
	.probe_new	= max31730_probe,
	.id_table	= max31730_ids,
	.detect		= max31730_detect,
	.address_list	= normal_i2c,
};

module_i2c_driver(max31730_driver);

MODULE_AUTHOR("Guenter Roeck <linux@roeck-us.net>");
MODULE_DESCRIPTION("MAX31730 driver");
MODULE_LICENSE("GPL");
