// 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.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 * const 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" },
	{ }
};
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;
	}

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

	return 0;
}

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

	return max31730_write_config(data, MAX31730_STOP, 0);
}

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

	return max31730_write_config(data, 0, MAX31730_STOP);
}

static DEFINE_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	= pm_sleep_ptr(&max31730_pm_ops),
	},
	.probe		= 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");
