// SPDX-License-Identifier: GPL-2.0-or-later
/*
 * Driver for TI ADC128D818 System Monitor with Temperature Sensor
 *
 * Copyright (c) 2014 Guenter Roeck
 *
 * Derived from lm80.c
 * Copyright (C) 1998, 1999  Frodo Looijaard <frodol@dds.nl>
 *			     and Philip Edelbrock <phil@netroedge.com>
 */

#include <linux/module.h>
#include <linux/slab.h>
#include <linux/jiffies.h>
#include <linux/i2c.h>
#include <linux/hwmon.h>
#include <linux/hwmon-sysfs.h>
#include <linux/err.h>
#include <linux/regulator/consumer.h>
#include <linux/mutex.h>
#include <linux/bitops.h>
#include <linux/of.h>

/* Addresses to scan
 * The chip also supports addresses 0x35..0x37. Don't scan those addresses
 * since they are also used by some EEPROMs, which may result in false
 * positives.
 */
static const unsigned short normal_i2c[] = {
	0x1d, 0x1e, 0x1f, 0x2d, 0x2e, 0x2f, I2C_CLIENT_END };

/* registers */
#define ADC128_REG_IN_MAX(nr)		(0x2a + (nr) * 2)
#define ADC128_REG_IN_MIN(nr)		(0x2b + (nr) * 2)
#define ADC128_REG_IN(nr)		(0x20 + (nr))

#define ADC128_REG_TEMP			0x27
#define ADC128_REG_TEMP_MAX		0x38
#define ADC128_REG_TEMP_HYST		0x39

#define ADC128_REG_CONFIG		0x00
#define ADC128_REG_ALARM		0x01
#define ADC128_REG_MASK			0x03
#define ADC128_REG_CONV_RATE		0x07
#define ADC128_REG_ONESHOT		0x09
#define ADC128_REG_SHUTDOWN		0x0a
#define ADC128_REG_CONFIG_ADV		0x0b
#define ADC128_REG_BUSY_STATUS		0x0c

#define ADC128_REG_MAN_ID		0x3e
#define ADC128_REG_DEV_ID		0x3f

/* No. of voltage entries in adc128_attrs */
#define ADC128_ATTR_NUM_VOLT		(8 * 4)

/* Voltage inputs visible per operation mode */
static const u8 num_inputs[] = { 7, 8, 4, 6 };

struct adc128_data {
	struct i2c_client *client;
	struct regulator *regulator;
	int vref;		/* Reference voltage in mV */
	struct mutex update_lock;
	u8 mode;		/* Operation mode */
	bool valid;		/* true if following fields are valid */
	unsigned long last_updated;	/* In jiffies */

	u16 in[3][8];		/* Register value, normalized to 12 bit
				 * 0: input voltage
				 * 1: min limit
				 * 2: max limit
				 */
	s16 temp[3];		/* Register value, normalized to 9 bit
				 * 0: sensor 1: limit 2: hyst
				 */
	u8 alarms;		/* alarm register value */
};

static struct adc128_data *adc128_update_device(struct device *dev)
{
	struct adc128_data *data = dev_get_drvdata(dev);
	struct i2c_client *client = data->client;
	struct adc128_data *ret = data;
	int i, rv;

	mutex_lock(&data->update_lock);

	if (time_after(jiffies, data->last_updated + HZ) || !data->valid) {
		for (i = 0; i < num_inputs[data->mode]; i++) {
			rv = i2c_smbus_read_word_swapped(client,
							 ADC128_REG_IN(i));
			if (rv < 0)
				goto abort;
			data->in[0][i] = rv >> 4;

			rv = i2c_smbus_read_byte_data(client,
						      ADC128_REG_IN_MIN(i));
			if (rv < 0)
				goto abort;
			data->in[1][i] = rv << 4;

			rv = i2c_smbus_read_byte_data(client,
						      ADC128_REG_IN_MAX(i));
			if (rv < 0)
				goto abort;
			data->in[2][i] = rv << 4;
		}

		if (data->mode != 1) {
			rv = i2c_smbus_read_word_swapped(client,
							 ADC128_REG_TEMP);
			if (rv < 0)
				goto abort;
			data->temp[0] = rv >> 7;

			rv = i2c_smbus_read_byte_data(client,
						      ADC128_REG_TEMP_MAX);
			if (rv < 0)
				goto abort;
			data->temp[1] = rv << 1;

			rv = i2c_smbus_read_byte_data(client,
						      ADC128_REG_TEMP_HYST);
			if (rv < 0)
				goto abort;
			data->temp[2] = rv << 1;
		}

		rv = i2c_smbus_read_byte_data(client, ADC128_REG_ALARM);
		if (rv < 0)
			goto abort;
		data->alarms |= rv;

		data->last_updated = jiffies;
		data->valid = true;
	}
	goto done;

abort:
	ret = ERR_PTR(rv);
	data->valid = false;
done:
	mutex_unlock(&data->update_lock);
	return ret;
}

static ssize_t adc128_in_show(struct device *dev,
			      struct device_attribute *attr, char *buf)
{
	struct adc128_data *data = adc128_update_device(dev);
	int index = to_sensor_dev_attr_2(attr)->index;
	int nr = to_sensor_dev_attr_2(attr)->nr;
	int val;

	if (IS_ERR(data))
		return PTR_ERR(data);

	val = DIV_ROUND_CLOSEST(data->in[index][nr] * data->vref, 4095);
	return sprintf(buf, "%d\n", val);
}

static ssize_t adc128_in_store(struct device *dev,
			       struct device_attribute *attr, const char *buf,
			       size_t count)
{
	struct adc128_data *data = dev_get_drvdata(dev);
	int index = to_sensor_dev_attr_2(attr)->index;
	int nr = to_sensor_dev_attr_2(attr)->nr;
	u8 reg, regval;
	long val;
	int err;

	err = kstrtol(buf, 10, &val);
	if (err < 0)
		return err;

	mutex_lock(&data->update_lock);
	/* 10 mV LSB on limit registers */
	regval = clamp_val(DIV_ROUND_CLOSEST(val, 10), 0, 255);
	data->in[index][nr] = regval << 4;
	reg = index == 1 ? ADC128_REG_IN_MIN(nr) : ADC128_REG_IN_MAX(nr);
	i2c_smbus_write_byte_data(data->client, reg, regval);
	mutex_unlock(&data->update_lock);

	return count;
}

static ssize_t adc128_temp_show(struct device *dev,
				struct device_attribute *attr, char *buf)
{
	struct adc128_data *data = adc128_update_device(dev);
	int index = to_sensor_dev_attr(attr)->index;
	int temp;

	if (IS_ERR(data))
		return PTR_ERR(data);

	temp = sign_extend32(data->temp[index], 8);
	return sprintf(buf, "%d\n", temp * 500);/* 0.5 degrees C resolution */
}

static ssize_t adc128_temp_store(struct device *dev,
				 struct device_attribute *attr,
				 const char *buf, size_t count)
{
	struct adc128_data *data = dev_get_drvdata(dev);
	int index = to_sensor_dev_attr(attr)->index;
	long val;
	int err;
	s8 regval;

	err = kstrtol(buf, 10, &val);
	if (err < 0)
		return err;

	mutex_lock(&data->update_lock);
	regval = clamp_val(DIV_ROUND_CLOSEST(val, 1000), -128, 127);
	data->temp[index] = regval << 1;
	i2c_smbus_write_byte_data(data->client,
				  index == 1 ? ADC128_REG_TEMP_MAX
					     : ADC128_REG_TEMP_HYST,
				  regval);
	mutex_unlock(&data->update_lock);

	return count;
}

static ssize_t adc128_alarm_show(struct device *dev,
				 struct device_attribute *attr, char *buf)
{
	struct adc128_data *data = adc128_update_device(dev);
	int mask = 1 << to_sensor_dev_attr(attr)->index;
	u8 alarms;

	if (IS_ERR(data))
		return PTR_ERR(data);

	/*
	 * Clear an alarm after reporting it to user space. If it is still
	 * active, the next update sequence will set the alarm bit again.
	 */
	alarms = data->alarms;
	data->alarms &= ~mask;

	return sprintf(buf, "%u\n", !!(alarms & mask));
}

static umode_t adc128_is_visible(struct kobject *kobj,
				 struct attribute *attr, int index)
{
	struct device *dev = container_of(kobj, struct device, kobj);
	struct adc128_data *data = dev_get_drvdata(dev);

	if (index < ADC128_ATTR_NUM_VOLT) {
		/* Voltage, visible according to num_inputs[] */
		if (index >= num_inputs[data->mode] * 4)
			return 0;
	} else {
		/* Temperature, visible if not in mode 1 */
		if (data->mode == 1)
			return 0;
	}

	return attr->mode;
}

static SENSOR_DEVICE_ATTR_2_RO(in0_input, adc128_in, 0, 0);
static SENSOR_DEVICE_ATTR_2_RW(in0_min, adc128_in, 0, 1);
static SENSOR_DEVICE_ATTR_2_RW(in0_max, adc128_in, 0, 2);

static SENSOR_DEVICE_ATTR_2_RO(in1_input, adc128_in, 1, 0);
static SENSOR_DEVICE_ATTR_2_RW(in1_min, adc128_in, 1, 1);
static SENSOR_DEVICE_ATTR_2_RW(in1_max, adc128_in, 1, 2);

static SENSOR_DEVICE_ATTR_2_RO(in2_input, adc128_in, 2, 0);
static SENSOR_DEVICE_ATTR_2_RW(in2_min, adc128_in, 2, 1);
static SENSOR_DEVICE_ATTR_2_RW(in2_max, adc128_in, 2, 2);

static SENSOR_DEVICE_ATTR_2_RO(in3_input, adc128_in, 3, 0);
static SENSOR_DEVICE_ATTR_2_RW(in3_min, adc128_in, 3, 1);
static SENSOR_DEVICE_ATTR_2_RW(in3_max, adc128_in, 3, 2);

static SENSOR_DEVICE_ATTR_2_RO(in4_input, adc128_in, 4, 0);
static SENSOR_DEVICE_ATTR_2_RW(in4_min, adc128_in, 4, 1);
static SENSOR_DEVICE_ATTR_2_RW(in4_max, adc128_in, 4, 2);

static SENSOR_DEVICE_ATTR_2_RO(in5_input, adc128_in, 5, 0);
static SENSOR_DEVICE_ATTR_2_RW(in5_min, adc128_in, 5, 1);
static SENSOR_DEVICE_ATTR_2_RW(in5_max, adc128_in, 5, 2);

static SENSOR_DEVICE_ATTR_2_RO(in6_input, adc128_in, 6, 0);
static SENSOR_DEVICE_ATTR_2_RW(in6_min, adc128_in, 6, 1);
static SENSOR_DEVICE_ATTR_2_RW(in6_max, adc128_in, 6, 2);

static SENSOR_DEVICE_ATTR_2_RO(in7_input, adc128_in, 7, 0);
static SENSOR_DEVICE_ATTR_2_RW(in7_min, adc128_in, 7, 1);
static SENSOR_DEVICE_ATTR_2_RW(in7_max, adc128_in, 7, 2);

static SENSOR_DEVICE_ATTR_RO(temp1_input, adc128_temp, 0);
static SENSOR_DEVICE_ATTR_RW(temp1_max, adc128_temp, 1);
static SENSOR_DEVICE_ATTR_RW(temp1_max_hyst, adc128_temp, 2);

static SENSOR_DEVICE_ATTR_RO(in0_alarm, adc128_alarm, 0);
static SENSOR_DEVICE_ATTR_RO(in1_alarm, adc128_alarm, 1);
static SENSOR_DEVICE_ATTR_RO(in2_alarm, adc128_alarm, 2);
static SENSOR_DEVICE_ATTR_RO(in3_alarm, adc128_alarm, 3);
static SENSOR_DEVICE_ATTR_RO(in4_alarm, adc128_alarm, 4);
static SENSOR_DEVICE_ATTR_RO(in5_alarm, adc128_alarm, 5);
static SENSOR_DEVICE_ATTR_RO(in6_alarm, adc128_alarm, 6);
static SENSOR_DEVICE_ATTR_RO(in7_alarm, adc128_alarm, 7);
static SENSOR_DEVICE_ATTR_RO(temp1_max_alarm, adc128_alarm, 7);

static struct attribute *adc128_attrs[] = {
	&sensor_dev_attr_in0_alarm.dev_attr.attr,
	&sensor_dev_attr_in0_input.dev_attr.attr,
	&sensor_dev_attr_in0_max.dev_attr.attr,
	&sensor_dev_attr_in0_min.dev_attr.attr,
	&sensor_dev_attr_in1_alarm.dev_attr.attr,
	&sensor_dev_attr_in1_input.dev_attr.attr,
	&sensor_dev_attr_in1_max.dev_attr.attr,
	&sensor_dev_attr_in1_min.dev_attr.attr,
	&sensor_dev_attr_in2_alarm.dev_attr.attr,
	&sensor_dev_attr_in2_input.dev_attr.attr,
	&sensor_dev_attr_in2_max.dev_attr.attr,
	&sensor_dev_attr_in2_min.dev_attr.attr,
	&sensor_dev_attr_in3_alarm.dev_attr.attr,
	&sensor_dev_attr_in3_input.dev_attr.attr,
	&sensor_dev_attr_in3_max.dev_attr.attr,
	&sensor_dev_attr_in3_min.dev_attr.attr,
	&sensor_dev_attr_in4_alarm.dev_attr.attr,
	&sensor_dev_attr_in4_input.dev_attr.attr,
	&sensor_dev_attr_in4_max.dev_attr.attr,
	&sensor_dev_attr_in4_min.dev_attr.attr,
	&sensor_dev_attr_in5_alarm.dev_attr.attr,
	&sensor_dev_attr_in5_input.dev_attr.attr,
	&sensor_dev_attr_in5_max.dev_attr.attr,
	&sensor_dev_attr_in5_min.dev_attr.attr,
	&sensor_dev_attr_in6_alarm.dev_attr.attr,
	&sensor_dev_attr_in6_input.dev_attr.attr,
	&sensor_dev_attr_in6_max.dev_attr.attr,
	&sensor_dev_attr_in6_min.dev_attr.attr,
	&sensor_dev_attr_in7_alarm.dev_attr.attr,
	&sensor_dev_attr_in7_input.dev_attr.attr,
	&sensor_dev_attr_in7_max.dev_attr.attr,
	&sensor_dev_attr_in7_min.dev_attr.attr,
	&sensor_dev_attr_temp1_input.dev_attr.attr,
	&sensor_dev_attr_temp1_max.dev_attr.attr,
	&sensor_dev_attr_temp1_max_alarm.dev_attr.attr,
	&sensor_dev_attr_temp1_max_hyst.dev_attr.attr,
	NULL
};

static const struct attribute_group adc128_group = {
	.attrs = adc128_attrs,
	.is_visible = adc128_is_visible,
};
__ATTRIBUTE_GROUPS(adc128);

static int adc128_detect(struct i2c_client *client, struct i2c_board_info *info)
{
	int man_id, dev_id;

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

	man_id = i2c_smbus_read_byte_data(client, ADC128_REG_MAN_ID);
	dev_id = i2c_smbus_read_byte_data(client, ADC128_REG_DEV_ID);
	if (man_id != 0x01 || dev_id != 0x09)
		return -ENODEV;

	/* Check unused bits for confirmation */
	if (i2c_smbus_read_byte_data(client, ADC128_REG_CONFIG) & 0xf4)
		return -ENODEV;
	if (i2c_smbus_read_byte_data(client, ADC128_REG_CONV_RATE) & 0xfe)
		return -ENODEV;
	if (i2c_smbus_read_byte_data(client, ADC128_REG_ONESHOT) & 0xfe)
		return -ENODEV;
	if (i2c_smbus_read_byte_data(client, ADC128_REG_SHUTDOWN) & 0xfe)
		return -ENODEV;
	if (i2c_smbus_read_byte_data(client, ADC128_REG_CONFIG_ADV) & 0xf8)
		return -ENODEV;
	if (i2c_smbus_read_byte_data(client, ADC128_REG_BUSY_STATUS) & 0xfc)
		return -ENODEV;

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

	return 0;
}

static int adc128_init_client(struct adc128_data *data)
{
	struct i2c_client *client = data->client;
	int err;

	/*
	 * Reset chip to defaults.
	 * This makes most other initializations unnecessary.
	 */
	err = i2c_smbus_write_byte_data(client, ADC128_REG_CONFIG, 0x80);
	if (err)
		return err;

	/* Set operation mode, if non-default */
	if (data->mode != 0) {
		err = i2c_smbus_write_byte_data(client,
						ADC128_REG_CONFIG_ADV,
						data->mode << 1);
		if (err)
			return err;
	}

	/* Start monitoring */
	err = i2c_smbus_write_byte_data(client, ADC128_REG_CONFIG, 0x01);
	if (err)
		return err;

	/* If external vref is selected, configure the chip to use it */
	if (data->regulator) {
		err = i2c_smbus_write_byte_data(client,
						ADC128_REG_CONFIG_ADV, 0x01);
		if (err)
			return err;
	}

	return 0;
}

static int adc128_probe(struct i2c_client *client,
			const struct i2c_device_id *id)
{
	struct device *dev = &client->dev;
	struct regulator *regulator;
	struct device *hwmon_dev;
	struct adc128_data *data;
	int err, vref;

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

	/* vref is optional. If specified, is used as chip reference voltage */
	regulator = devm_regulator_get_optional(dev, "vref");
	if (!IS_ERR(regulator)) {
		data->regulator = regulator;
		err = regulator_enable(regulator);
		if (err < 0)
			return err;
		vref = regulator_get_voltage(regulator);
		if (vref < 0) {
			err = vref;
			goto error;
		}
		data->vref = DIV_ROUND_CLOSEST(vref, 1000);
	} else {
		data->vref = 2560;	/* 2.56V, in mV */
	}

	/* Operation mode is optional. If unspecified, keep current mode */
	if (of_property_read_u8(dev->of_node, "ti,mode", &data->mode) == 0) {
		if (data->mode > 3) {
			dev_err(dev, "invalid operation mode %d\n",
				data->mode);
			err = -EINVAL;
			goto error;
		}
	} else {
		err = i2c_smbus_read_byte_data(client, ADC128_REG_CONFIG_ADV);
		if (err < 0)
			goto error;
		data->mode = (err >> 1) & ADC128_REG_MASK;
	}

	data->client = client;
	i2c_set_clientdata(client, data);
	mutex_init(&data->update_lock);

	/* Initialize the chip */
	err = adc128_init_client(data);
	if (err < 0)
		goto error;

	hwmon_dev = devm_hwmon_device_register_with_groups(dev, client->name,
							   data, adc128_groups);
	if (IS_ERR(hwmon_dev)) {
		err = PTR_ERR(hwmon_dev);
		goto error;
	}

	return 0;

error:
	if (data->regulator)
		regulator_disable(data->regulator);
	return err;
}

static int adc128_remove(struct i2c_client *client)
{
	struct adc128_data *data = i2c_get_clientdata(client);

	if (data->regulator)
		regulator_disable(data->regulator);

	return 0;
}

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

static const struct of_device_id __maybe_unused adc128_of_match[] = {
	{ .compatible = "ti,adc128d818" },
	{ },
};
MODULE_DEVICE_TABLE(of, adc128_of_match);

static struct i2c_driver adc128_driver = {
	.class		= I2C_CLASS_HWMON,
	.driver = {
		.name	= "adc128d818",
		.of_match_table = of_match_ptr(adc128_of_match),
	},
	.probe		= adc128_probe,
	.remove		= adc128_remove,
	.id_table	= adc128_id,
	.detect		= adc128_detect,
	.address_list	= normal_i2c,
};

module_i2c_driver(adc128_driver);

MODULE_AUTHOR("Guenter Roeck");
MODULE_DESCRIPTION("Driver for ADC128D818");
MODULE_LICENSE("GPL");
