// SPDX-License-Identifier: GPL-2.0-or-later
/*
 * Support for the FTS Systemmonitoring Chip "Teutates"
 *
 * Copyright (C) 2016 Fujitsu Technology Solutions GmbH,
 *		  Thilo Cestonaro <thilo.cestonaro@ts.fujitsu.com>
 */
#include <linux/err.h>
#include <linux/hwmon.h>
#include <linux/i2c.h>
#include <linux/init.h>
#include <linux/jiffies.h>
#include <linux/math.h>
#include <linux/module.h>
#include <linux/slab.h>
#include <linux/watchdog.h>

#define FTS_DEVICE_ID_REG		0x0000
#define FTS_DEVICE_REVISION_REG		0x0001
#define FTS_DEVICE_STATUS_REG		0x0004
#define FTS_SATELLITE_STATUS_REG	0x0005
#define FTS_EVENT_STATUS_REG		0x0006
#define FTS_GLOBAL_CONTROL_REG		0x0007

#define FTS_DEVICE_DETECT_REG_1		0x0C
#define FTS_DEVICE_DETECT_REG_2		0x0D
#define FTS_DEVICE_DETECT_REG_3		0x0E

#define FTS_SENSOR_EVENT_REG		0x0010

#define FTS_FAN_EVENT_REG		0x0014
#define FTS_FAN_PRESENT_REG		0x0015

#define FTS_POWER_ON_TIME_COUNTER_A	0x007A
#define FTS_POWER_ON_TIME_COUNTER_B	0x007B
#define FTS_POWER_ON_TIME_COUNTER_C	0x007C

#define FTS_PAGE_SELECT_REG		0x007F

#define FTS_WATCHDOG_TIME_PRESET	0x000B
#define FTS_WATCHDOG_CONTROL		0x5081

#define FTS_NO_FAN_SENSORS		0x08
#define FTS_NO_TEMP_SENSORS		0x10
#define FTS_NO_VOLT_SENSORS		0x04

#define FTS_FAN_SOURCE_INVALID		0xff

static const unsigned short normal_i2c[] = { 0x73, I2C_CLIENT_END };

static const struct i2c_device_id fts_id[] = {
	{ .name = "ftsteutates" },
	{ }
};
MODULE_DEVICE_TABLE(i2c, fts_id);

enum WATCHDOG_RESOLUTION {
	seconds = 1,
	minutes = 60
};

struct fts_data {
	struct i2c_client *client;
	unsigned long last_updated; /* in jiffies */
	struct watchdog_device wdd;
	enum WATCHDOG_RESOLUTION resolution;
	bool valid; /* false until following fields are valid */

	u8 volt[FTS_NO_VOLT_SENSORS];

	u8 temp_input[FTS_NO_TEMP_SENSORS];
	u8 temp_alarm;

	u8 fan_present;
	u8 fan_input[FTS_NO_FAN_SENSORS]; /* in rps */
	u8 fan_source[FTS_NO_FAN_SENSORS];
	u8 fan_alarm;
};

#define FTS_REG_FAN_INPUT(idx) ((idx) + 0x20)
#define FTS_REG_FAN_SOURCE(idx) ((idx) + 0x30)
#define FTS_REG_FAN_CONTROL(idx) (((idx) << 16) + 0x4881)

#define FTS_REG_TEMP_INPUT(idx) ((idx) + 0x40)
#define FTS_REG_TEMP_CONTROL(idx) (((idx) << 16) + 0x0681)

#define FTS_REG_VOLT(idx) ((idx) + 0x18)

/*****************************************************************************/
/* I2C Helper functions							     */
/*****************************************************************************/
static int fts_read_byte(struct i2c_client *client, unsigned short reg)
{
	int ret;
	unsigned char page = reg >> 8;

	dev_dbg(&client->dev, "page select - page: 0x%.02x\n", page);
	ret = i2c_smbus_write_byte_data(client, FTS_PAGE_SELECT_REG, page);
	if (ret < 0)
		return ret;

	reg &= 0xFF;
	ret = i2c_smbus_read_byte_data(client, reg);
	dev_dbg(&client->dev, "read - reg: 0x%.02x: val: 0x%.02x\n", reg, ret);
	return ret;
}

static int fts_write_byte(struct i2c_client *client, unsigned short reg,
			  unsigned char value)
{
	int ret;
	unsigned char page = reg >> 8;

	dev_dbg(&client->dev, "page select - page: 0x%.02x\n", page);
	ret = i2c_smbus_write_byte_data(client, FTS_PAGE_SELECT_REG, page);
	if (ret < 0)
		return ret;

	reg &= 0xFF;
	dev_dbg(&client->dev,
		"write - reg: 0x%.02x: val: 0x%.02x\n", reg, value);
	ret = i2c_smbus_write_byte_data(client, reg, value);
	return ret;
}

/*****************************************************************************/
/* Data Updater Helper function						     */
/*****************************************************************************/
static int fts_update_device(struct fts_data *data)
{
	int i, err;

	if (!time_after(jiffies, data->last_updated + 2 * HZ) && data->valid)
		return 0;

	err = fts_read_byte(data->client, FTS_DEVICE_STATUS_REG);
	if (err < 0)
		return err;

	data->valid = !!(err & 0x02); /* Data not ready yet */
	if (unlikely(!data->valid))
		return -EAGAIN;

	err = fts_read_byte(data->client, FTS_FAN_PRESENT_REG);
	if (err < 0)
		return err;
	data->fan_present = err;

	err = fts_read_byte(data->client, FTS_FAN_EVENT_REG);
	if (err < 0)
		return err;
	data->fan_alarm = err;

	for (i = 0; i < FTS_NO_FAN_SENSORS; i++) {
		if (data->fan_present & BIT(i)) {
			err = fts_read_byte(data->client, FTS_REG_FAN_INPUT(i));
			if (err < 0)
				return err;
			data->fan_input[i] = err;

			err = fts_read_byte(data->client,
					    FTS_REG_FAN_SOURCE(i));
			if (err < 0)
				return err;
			data->fan_source[i] = err;
		} else {
			data->fan_input[i] = 0;
			data->fan_source[i] = FTS_FAN_SOURCE_INVALID;
		}
	}

	err = fts_read_byte(data->client, FTS_SENSOR_EVENT_REG);
	if (err < 0)
		return err;
	data->temp_alarm = err;

	for (i = 0; i < FTS_NO_TEMP_SENSORS; i++) {
		err = fts_read_byte(data->client, FTS_REG_TEMP_INPUT(i));
		if (err < 0)
			return err;
		data->temp_input[i] = err;
	}

	for (i = 0; i < FTS_NO_VOLT_SENSORS; i++) {
		err = fts_read_byte(data->client, FTS_REG_VOLT(i));
		if (err < 0)
			return err;
		data->volt[i] = err;
	}
	data->last_updated = jiffies;
	return 0;
}

/*****************************************************************************/
/* Watchdog functions							     */
/*****************************************************************************/
static int fts_wd_set_resolution(struct fts_data *data,
				 enum WATCHDOG_RESOLUTION resolution)
{
	int ret;

	if (data->resolution == resolution)
		return 0;

	ret = fts_read_byte(data->client, FTS_WATCHDOG_CONTROL);
	if (ret < 0)
		return ret;

	if ((resolution == seconds && ret & BIT(1)) ||
	    (resolution == minutes && (ret & BIT(1)) == 0)) {
		data->resolution = resolution;
		return 0;
	}

	if (resolution == seconds)
		ret |= BIT(1);
	else
		ret &= ~BIT(1);

	ret = fts_write_byte(data->client, FTS_WATCHDOG_CONTROL, ret);
	if (ret < 0)
		return ret;

	data->resolution = resolution;
	return ret;
}

static int fts_wd_set_timeout(struct watchdog_device *wdd, unsigned int timeout)
{
	struct fts_data *data;
	enum WATCHDOG_RESOLUTION resolution = seconds;
	int ret;

	data = watchdog_get_drvdata(wdd);
	/* switch watchdog resolution to minutes if timeout does not fit
	 * into a byte
	 */
	if (timeout > 0xFF) {
		timeout = DIV_ROUND_UP(timeout, 60) * 60;
		resolution = minutes;
	}

	ret = fts_wd_set_resolution(data, resolution);
	if (ret < 0)
		return ret;

	wdd->timeout = timeout;
	return 0;
}

static int fts_wd_start(struct watchdog_device *wdd)
{
	struct fts_data *data = watchdog_get_drvdata(wdd);

	return fts_write_byte(data->client, FTS_WATCHDOG_TIME_PRESET,
			      wdd->timeout / (u8)data->resolution);
}

static int fts_wd_stop(struct watchdog_device *wdd)
{
	struct fts_data *data;

	data = watchdog_get_drvdata(wdd);
	return fts_write_byte(data->client, FTS_WATCHDOG_TIME_PRESET, 0);
}

static const struct watchdog_info fts_wd_info = {
	.options = WDIOF_SETTIMEOUT | WDIOF_KEEPALIVEPING | WDIOF_MAGICCLOSE,
	.identity = "FTS Teutates Hardware Watchdog",
};

static const struct watchdog_ops fts_wd_ops = {
	.owner = THIS_MODULE,
	.start = fts_wd_start,
	.stop = fts_wd_stop,
	.set_timeout = fts_wd_set_timeout,
};

static int fts_watchdog_init(struct fts_data *data)
{
	int timeout, ret;

	watchdog_set_drvdata(&data->wdd, data);

	timeout = fts_read_byte(data->client, FTS_WATCHDOG_TIME_PRESET);
	if (timeout < 0)
		return timeout;

	/* watchdog not running, set timeout to a default of 60 sec. */
	if (timeout == 0) {
		ret = fts_wd_set_resolution(data, seconds);
		if (ret < 0)
			return ret;
		data->wdd.timeout = 60;
	} else {
		ret = fts_read_byte(data->client, FTS_WATCHDOG_CONTROL);
		if (ret < 0)
			return ret;

		data->resolution = ret & BIT(1) ? seconds : minutes;
		data->wdd.timeout = timeout * (u8)data->resolution;
		set_bit(WDOG_HW_RUNNING, &data->wdd.status);
	}

	/* Register our watchdog part */
	data->wdd.info = &fts_wd_info;
	data->wdd.ops = &fts_wd_ops;
	data->wdd.parent = &data->client->dev;
	data->wdd.min_timeout = 1;

	/* max timeout 255 minutes. */
	data->wdd.max_hw_heartbeat_ms = 0xFF * 60 * MSEC_PER_SEC;

	return devm_watchdog_register_device(&data->client->dev, &data->wdd);
}

static umode_t fts_is_visible(const void *devdata, enum hwmon_sensor_types type, u32 attr,
			      int channel)
{
	switch (type) {
	case hwmon_temp:
		switch (attr) {
		case hwmon_temp_input:
		case hwmon_temp_fault:
			return 0444;
		case hwmon_temp_alarm:
			return 0644;
		default:
			break;
		}
		break;
	case hwmon_fan:
		switch (attr) {
		case hwmon_fan_input:
		case hwmon_fan_fault:
			return 0444;
		case hwmon_fan_alarm:
			return 0644;
		default:
			break;
		}
		break;
	case hwmon_pwm:
	case hwmon_in:
		return 0444;
	default:
		break;
	}

	return 0;
}

static int fts_read(struct device *dev, enum hwmon_sensor_types type, u32 attr, int channel,
		    long *val)
{
	struct fts_data *data = dev_get_drvdata(dev);
	int ret = fts_update_device(data);

	if (ret < 0)
		return ret;

	switch (type) {
	case hwmon_temp:
		switch (attr) {
		case hwmon_temp_input:
			*val = (data->temp_input[channel] - 64) * 1000;

			return 0;
		case hwmon_temp_alarm:
			*val = !!(data->temp_alarm & BIT(channel));

			return 0;
		case hwmon_temp_fault:
			/* 00h Temperature = Sensor Error */;
			*val = (data->temp_input[channel] == 0);

			return 0;
		default:
			break;
		}
		break;
	case hwmon_fan:
		switch (attr) {
		case hwmon_fan_input:
			*val = data->fan_input[channel] * 60;

			return 0;
		case hwmon_fan_alarm:
			*val = !!(data->fan_alarm & BIT(channel));

			return 0;
		case hwmon_fan_fault:
			*val = !(data->fan_present & BIT(channel));

			return 0;
		default:
			break;
		}
		break;
	case hwmon_pwm:
		switch (attr) {
		case hwmon_pwm_auto_channels_temp: {
			u8 fan_source = data->fan_source[channel];

			if (fan_source == FTS_FAN_SOURCE_INVALID || fan_source >= BITS_PER_LONG)
				*val = 0;
			else
				*val = BIT(fan_source);

			return 0;
		}
		default:
			break;
		}
		break;
	case hwmon_in:
		switch (attr) {
		case hwmon_in_input:
			*val = DIV_ROUND_CLOSEST(data->volt[channel] * 3300, 255);

			return 0;
		default:
			break;
		}
		break;
	default:
		break;
	}

	return -EOPNOTSUPP;
}

static int fts_write(struct device *dev, enum hwmon_sensor_types type, u32 attr, int channel,
		     long val)
{
	struct fts_data *data = dev_get_drvdata(dev);
	int ret = fts_update_device(data);

	if (ret < 0)
		return ret;

	switch (type) {
	case hwmon_temp:
		switch (attr) {
		case hwmon_temp_alarm:
			if (val)
				return -EINVAL;

			ret = fts_read_byte(data->client, FTS_REG_TEMP_CONTROL(channel));
			if (ret < 0)
				return ret;
			ret = fts_write_byte(data->client, FTS_REG_TEMP_CONTROL(channel),
					     ret | 0x1);
			if (ret < 0)
				return ret;
			data->valid = false;
			return 0;
		default:
			break;
		}
		break;
	case hwmon_fan:
		switch (attr) {
		case hwmon_fan_alarm:
			if (val)
				return -EINVAL;

			ret = fts_read_byte(data->client, FTS_REG_FAN_CONTROL(channel));
			if (ret < 0)
				return ret;
			ret = fts_write_byte(data->client, FTS_REG_FAN_CONTROL(channel),
					     ret | 0x1);
			if (ret < 0)
				return ret;
			data->valid = false;
			return 0;
		default:
			break;
		}
		break;
	default:
		break;
	}

	return -EOPNOTSUPP;
}

static const struct hwmon_ops fts_ops = {
	.is_visible = fts_is_visible,
	.read = fts_read,
	.write = fts_write,
};

static const struct hwmon_channel_info * const fts_info[] = {
	HWMON_CHANNEL_INFO(chip, HWMON_C_REGISTER_TZ),
	HWMON_CHANNEL_INFO(temp,
			   HWMON_T_INPUT | HWMON_T_ALARM | HWMON_T_FAULT,
			   HWMON_T_INPUT | HWMON_T_ALARM | HWMON_T_FAULT,
			   HWMON_T_INPUT | HWMON_T_ALARM | HWMON_T_FAULT,
			   HWMON_T_INPUT | HWMON_T_ALARM | HWMON_T_FAULT,
			   HWMON_T_INPUT | HWMON_T_ALARM | HWMON_T_FAULT,
			   HWMON_T_INPUT | HWMON_T_ALARM | HWMON_T_FAULT,
			   HWMON_T_INPUT | HWMON_T_ALARM | HWMON_T_FAULT,
			   HWMON_T_INPUT | HWMON_T_ALARM | HWMON_T_FAULT,
			   HWMON_T_INPUT | HWMON_T_ALARM | HWMON_T_FAULT,
			   HWMON_T_INPUT | HWMON_T_ALARM | HWMON_T_FAULT,
			   HWMON_T_INPUT | HWMON_T_ALARM | HWMON_T_FAULT,
			   HWMON_T_INPUT | HWMON_T_ALARM | HWMON_T_FAULT,
			   HWMON_T_INPUT | HWMON_T_ALARM | HWMON_T_FAULT,
			   HWMON_T_INPUT | HWMON_T_ALARM | HWMON_T_FAULT,
			   HWMON_T_INPUT | HWMON_T_ALARM | HWMON_T_FAULT,
			   HWMON_T_INPUT | HWMON_T_ALARM | HWMON_T_FAULT
			   ),
	HWMON_CHANNEL_INFO(fan,
			   HWMON_F_INPUT | HWMON_F_ALARM | HWMON_F_FAULT,
			   HWMON_F_INPUT | HWMON_F_ALARM | HWMON_F_FAULT,
			   HWMON_F_INPUT | HWMON_F_ALARM | HWMON_F_FAULT,
			   HWMON_F_INPUT | HWMON_F_ALARM | HWMON_F_FAULT,
			   HWMON_F_INPUT | HWMON_F_ALARM | HWMON_F_FAULT,
			   HWMON_F_INPUT | HWMON_F_ALARM | HWMON_F_FAULT,
			   HWMON_F_INPUT | HWMON_F_ALARM | HWMON_F_FAULT,
			   HWMON_F_INPUT | HWMON_F_ALARM | HWMON_F_FAULT
			   ),
	HWMON_CHANNEL_INFO(pwm,
			   HWMON_PWM_AUTO_CHANNELS_TEMP,
			   HWMON_PWM_AUTO_CHANNELS_TEMP,
			   HWMON_PWM_AUTO_CHANNELS_TEMP,
			   HWMON_PWM_AUTO_CHANNELS_TEMP,
			   HWMON_PWM_AUTO_CHANNELS_TEMP,
			   HWMON_PWM_AUTO_CHANNELS_TEMP,
			   HWMON_PWM_AUTO_CHANNELS_TEMP,
			   HWMON_PWM_AUTO_CHANNELS_TEMP
			   ),
	HWMON_CHANNEL_INFO(in,
			   HWMON_I_INPUT,
			   HWMON_I_INPUT,
			   HWMON_I_INPUT,
			   HWMON_I_INPUT
			   ),
	NULL
};

static const struct hwmon_chip_info fts_chip_info = {
	.ops = &fts_ops,
	.info = fts_info,
};

/*****************************************************************************/
/* Module initialization / remove functions				     */
/*****************************************************************************/
static int fts_detect(struct i2c_client *client,
		      struct i2c_board_info *info)
{
	int val;

	/* detection works with revision greater or equal to 0x2b */
	val = i2c_smbus_read_byte_data(client, FTS_DEVICE_REVISION_REG);
	if (val < 0x2b)
		return -ENODEV;

	/* Device Detect Regs must have 0x17 0x34 and 0x54 */
	val = i2c_smbus_read_byte_data(client, FTS_DEVICE_DETECT_REG_1);
	if (val != 0x17)
		return -ENODEV;

	val = i2c_smbus_read_byte_data(client, FTS_DEVICE_DETECT_REG_2);
	if (val != 0x34)
		return -ENODEV;

	val = i2c_smbus_read_byte_data(client, FTS_DEVICE_DETECT_REG_3);
	if (val != 0x54)
		return -ENODEV;

	/*
	 * 0x10 == Baseboard Management Controller, 0x01 == Teutates
	 * Device ID Reg needs to be 0x11
	 */
	val = i2c_smbus_read_byte_data(client, FTS_DEVICE_ID_REG);
	if (val != 0x11)
		return -ENODEV;

	strscpy(info->type, fts_id[0].name, I2C_NAME_SIZE);
	info->flags = 0;
	return 0;
}

static int fts_probe(struct i2c_client *client)
{
	u8 revision;
	struct fts_data *data;
	int err;
	s8 deviceid;
	struct device *hwmon_dev;

	if (client->addr != 0x73)
		return -ENODEV;

	/* Baseboard Management Controller check */
	deviceid = i2c_smbus_read_byte_data(client, FTS_DEVICE_ID_REG);
	if (deviceid > 0 && (deviceid & 0xF0) == 0x10) {
		switch (deviceid & 0x0F) {
		case 0x01:
			break;
		default:
			dev_dbg(&client->dev,
				"No Baseboard Management Controller\n");
			return -ENODEV;
		}
	} else {
		dev_dbg(&client->dev, "No fujitsu board\n");
		return -ENODEV;
	}

	data = devm_kzalloc(&client->dev, sizeof(struct fts_data),
			    GFP_KERNEL);
	if (!data)
		return -ENOMEM;

	data->client = client;
	dev_set_drvdata(&client->dev, data);

	err = i2c_smbus_read_byte_data(client, FTS_DEVICE_REVISION_REG);
	if (err < 0)
		return err;
	revision = err;

	hwmon_dev = devm_hwmon_device_register_with_info(&client->dev, "ftsteutates", data,
							 &fts_chip_info, NULL);
	if (IS_ERR(hwmon_dev))
		return PTR_ERR(hwmon_dev);

	err = fts_watchdog_init(data);
	if (err)
		return err;

	dev_info(&client->dev, "Detected FTS Teutates chip, revision: %d.%d\n",
		 (revision & 0xF0) >> 4, revision & 0x0F);
	return 0;
}

/*****************************************************************************/
/* Module Details							     */
/*****************************************************************************/
static struct i2c_driver fts_driver = {
	.class = I2C_CLASS_HWMON,
	.driver = {
		.name = "ftsteutates",
	},
	.id_table = fts_id,
	.probe = fts_probe,
	.detect = fts_detect,
	.address_list = normal_i2c,
};

module_i2c_driver(fts_driver);

MODULE_AUTHOR("Thilo Cestonaro <thilo.cestonaro@ts.fujitsu.com>");
MODULE_DESCRIPTION("FTS Teutates driver");
MODULE_LICENSE("GPL");
