// SPDX-License-Identifier: GPL-2.0
/*
 * Fan Control HDL CORE driver
 *
 * Copyright 2019 Analog Devices Inc.
 */
#include <linux/adi-axi-common.h>
#include <linux/bits.h>
#include <linux/clk.h>
#include <linux/hwmon.h>
#include <linux/hwmon-sysfs.h>
#include <linux/interrupt.h>
#include <linux/io.h>
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/platform_device.h>
#include <linux/property.h>

/* register map */
#define ADI_REG_RSTN		0x0080
#define ADI_REG_PWM_WIDTH	0x0084
#define ADI_REG_TACH_PERIOD	0x0088
#define ADI_REG_TACH_TOLERANCE	0x008c
#define ADI_REG_PWM_PERIOD	0x00c0
#define ADI_REG_TACH_MEASUR	0x00c4
#define ADI_REG_TEMPERATURE	0x00c8
#define ADI_REG_TEMP_00_H	0x0100
#define ADI_REG_TEMP_25_L	0x0104
#define ADI_REG_TEMP_25_H	0x0108
#define ADI_REG_TEMP_50_L	0x010c
#define ADI_REG_TEMP_50_H	0x0110
#define ADI_REG_TEMP_75_L	0x0114
#define ADI_REG_TEMP_75_H	0x0118
#define ADI_REG_TEMP_100_L	0x011c

#define ADI_REG_IRQ_MASK	0x0040
#define ADI_REG_IRQ_PENDING	0x0044
#define ADI_REG_IRQ_SRC		0x0048

/* IRQ sources */
#define ADI_IRQ_SRC_PWM_CHANGED		BIT(0)
#define ADI_IRQ_SRC_TACH_ERR		BIT(1)
#define ADI_IRQ_SRC_TEMP_INCREASE	BIT(2)
#define ADI_IRQ_SRC_NEW_MEASUR		BIT(3)
#define ADI_IRQ_SRC_MASK		GENMASK(3, 0)
#define ADI_IRQ_MASK_OUT_ALL		0xFFFFFFFFU

#define SYSFS_PWM_MAX			255

struct axi_fan_control_data {
	void __iomem *base;
	struct device *hdev;
	unsigned long clk_rate;
	int irq;
	/* pulses per revolution */
	u32 ppr;
	bool hw_pwm_req;
	bool update_tacho_params;
	u8 fan_fault;
};

static inline void axi_iowrite(const u32 val, const u32 reg,
			       const struct axi_fan_control_data *ctl)
{
	iowrite32(val, ctl->base + reg);
}

static inline u32 axi_ioread(const u32 reg,
			     const struct axi_fan_control_data *ctl)
{
	return ioread32(ctl->base + reg);
}

/*
 * The core calculates the temperature as:
 *	T = /raw * 509.3140064 / 65535) - 280.2308787
 */
static ssize_t axi_fan_control_show(struct device *dev, struct device_attribute *da, char *buf)
{
	struct axi_fan_control_data *ctl = dev_get_drvdata(dev);
	struct sensor_device_attribute *attr = to_sensor_dev_attr(da);
	u32 temp = axi_ioread(attr->index, ctl);

	temp = DIV_ROUND_CLOSEST_ULL(temp * 509314ULL, 65535) - 280230;

	return sysfs_emit(buf, "%u\n", temp);
}

static ssize_t axi_fan_control_store(struct device *dev, struct device_attribute *da,
				     const char *buf, size_t count)
{
	struct axi_fan_control_data *ctl = dev_get_drvdata(dev);
	struct sensor_device_attribute *attr = to_sensor_dev_attr(da);
	u32 temp;
	int ret;

	ret = kstrtou32(buf, 10, &temp);
	if (ret)
		return ret;

	temp = DIV_ROUND_CLOSEST_ULL((temp + 280230) * 65535ULL, 509314);
	axi_iowrite(temp, attr->index, ctl);

	return count;
}

static long axi_fan_control_get_pwm_duty(const struct axi_fan_control_data *ctl)
{
	u32 pwm_width = axi_ioread(ADI_REG_PWM_WIDTH, ctl);
	u32 pwm_period = axi_ioread(ADI_REG_PWM_PERIOD, ctl);
	/*
	 * PWM_PERIOD is a RO register set by the core. It should never be 0.
	 * For now we are trusting the HW...
	 */
	return DIV_ROUND_CLOSEST(pwm_width * SYSFS_PWM_MAX, pwm_period);
}

static int axi_fan_control_set_pwm_duty(const long val,
					struct axi_fan_control_data *ctl)
{
	u32 pwm_period = axi_ioread(ADI_REG_PWM_PERIOD, ctl);
	u32 new_width;
	long __val = clamp_val(val, 0, SYSFS_PWM_MAX);

	new_width = DIV_ROUND_CLOSEST(__val * pwm_period, SYSFS_PWM_MAX);

	axi_iowrite(new_width, ADI_REG_PWM_WIDTH, ctl);

	return 0;
}

static long axi_fan_control_get_fan_rpm(const struct axi_fan_control_data *ctl)
{
	const u32 tach = axi_ioread(ADI_REG_TACH_MEASUR, ctl);

	if (tach == 0)
		/* should we return error, EAGAIN maybe? */
		return 0;
	/*
	 * The tacho period should be:
	 *      TACH = 60/(ppr * rpm), where rpm is revolutions per second
	 *      and ppr is pulses per revolution.
	 * Given the tacho period, we can multiply it by the input clock
	 * so that we know how many clocks we need to have this period.
	 * From this, we can derive the RPM value.
	 */
	return DIV_ROUND_CLOSEST(60 * ctl->clk_rate, ctl->ppr * tach);
}

static int axi_fan_control_read_temp(struct device *dev, u32 attr, long *val)
{
	struct axi_fan_control_data *ctl = dev_get_drvdata(dev);
	long raw_temp;

	switch (attr) {
	case hwmon_temp_input:
		raw_temp = axi_ioread(ADI_REG_TEMPERATURE, ctl);
		/*
		 * The formula for the temperature is:
		 *      T = (ADC * 501.3743 / 2^bits) - 273.6777
		 * It's multiplied by 1000 to have millidegrees as
		 * specified by the hwmon sysfs interface.
		 */
		*val = ((raw_temp * 501374) >> 16) - 273677;
		return 0;
	default:
		return -ENOTSUPP;
	}
}

static int axi_fan_control_read_fan(struct device *dev, u32 attr, long *val)
{
	struct axi_fan_control_data *ctl = dev_get_drvdata(dev);

	switch (attr) {
	case hwmon_fan_fault:
		*val = ctl->fan_fault;
		/* clear it now */
		ctl->fan_fault = 0;
		return 0;
	case hwmon_fan_input:
		*val = axi_fan_control_get_fan_rpm(ctl);
		return 0;
	default:
		return -ENOTSUPP;
	}
}

static int axi_fan_control_read_pwm(struct device *dev, u32 attr, long *val)
{
	struct axi_fan_control_data *ctl = dev_get_drvdata(dev);

	switch (attr) {
	case hwmon_pwm_input:
		*val = axi_fan_control_get_pwm_duty(ctl);
		return 0;
	default:
		return -ENOTSUPP;
	}
}

static int axi_fan_control_write_pwm(struct device *dev, u32 attr, long val)
{
	struct axi_fan_control_data *ctl = dev_get_drvdata(dev);

	switch (attr) {
	case hwmon_pwm_input:
		return axi_fan_control_set_pwm_duty(val, ctl);
	default:
		return -ENOTSUPP;
	}
}

static int axi_fan_control_read_labels(struct device *dev,
				       enum hwmon_sensor_types type,
				       u32 attr, int channel, const char **str)
{
	switch (type) {
	case hwmon_fan:
		*str = "FAN";
		return 0;
	case hwmon_temp:
		*str = "SYSMON4";
		return 0;
	default:
		return -ENOTSUPP;
	}
}

static int axi_fan_control_read(struct device *dev,
				enum hwmon_sensor_types type,
				u32 attr, int channel, long *val)
{
	switch (type) {
	case hwmon_fan:
		return axi_fan_control_read_fan(dev, attr, val);
	case hwmon_pwm:
		return axi_fan_control_read_pwm(dev, attr, val);
	case hwmon_temp:
		return axi_fan_control_read_temp(dev, attr, val);
	default:
		return -ENOTSUPP;
	}
}

static int axi_fan_control_write(struct device *dev,
				 enum hwmon_sensor_types type,
				 u32 attr, int channel, long val)
{
	switch (type) {
	case hwmon_pwm:
		return axi_fan_control_write_pwm(dev, attr, val);
	default:
		return -ENOTSUPP;
	}
}

static umode_t axi_fan_control_fan_is_visible(const u32 attr)
{
	switch (attr) {
	case hwmon_fan_input:
	case hwmon_fan_fault:
	case hwmon_fan_label:
		return 0444;
	default:
		return 0;
	}
}

static umode_t axi_fan_control_pwm_is_visible(const u32 attr)
{
	switch (attr) {
	case hwmon_pwm_input:
		return 0644;
	default:
		return 0;
	}
}

static umode_t axi_fan_control_temp_is_visible(const u32 attr)
{
	switch (attr) {
	case hwmon_temp_input:
	case hwmon_temp_label:
		return 0444;
	default:
		return 0;
	}
}

static umode_t axi_fan_control_is_visible(const void *data,
					  enum hwmon_sensor_types type,
					  u32 attr, int channel)
{
	switch (type) {
	case hwmon_fan:
		return axi_fan_control_fan_is_visible(attr);
	case hwmon_pwm:
		return axi_fan_control_pwm_is_visible(attr);
	case hwmon_temp:
		return axi_fan_control_temp_is_visible(attr);
	default:
		return 0;
	}
}

/*
 * This core has two main ways of changing the PWM duty cycle. It is done,
 * either by a request from userspace (writing on pwm1_input) or by the
 * core itself. When the change is done by the core, it will use predefined
 * parameters to evaluate the tach signal and, on that case we cannot set them.
 * On the other hand, when the request is done by the user, with some arbitrary
 * value that the core does not now about, we have to provide the tach
 * parameters so that, the core can evaluate the signal. On the IRQ handler we
 * distinguish this by using the ADI_IRQ_SRC_TEMP_INCREASE interrupt. This tell
 * us that the CORE requested a new duty cycle. After this, there is 5s delay
 * on which the core waits for the fan rotation speed to stabilize. After this
 * we get ADI_IRQ_SRC_PWM_CHANGED irq where we will decide if we need to set
 * the tach parameters or not on the next tach measurement cycle (corresponding
 * already to the ney duty cycle) based on the %ctl->hw_pwm_req flag.
 */
static irqreturn_t axi_fan_control_irq_handler(int irq, void *data)
{
	struct axi_fan_control_data *ctl = (struct axi_fan_control_data *)data;
	u32 irq_pending = axi_ioread(ADI_REG_IRQ_PENDING, ctl);
	u32 clear_mask;

	if (irq_pending & ADI_IRQ_SRC_TEMP_INCREASE)
		/* hardware requested a new pwm */
		ctl->hw_pwm_req = true;

	if (irq_pending & ADI_IRQ_SRC_PWM_CHANGED) {
		/*
		 * if the pwm changes on behalf of software,
		 * we need to provide new tacho parameters to the core.
		 * Wait for the next measurement for that...
		 */
		if (!ctl->hw_pwm_req) {
			ctl->update_tacho_params = true;
		} else {
			ctl->hw_pwm_req = false;
			hwmon_notify_event(ctl->hdev, hwmon_pwm,
					   hwmon_pwm_input, 0);
		}
	}

	if (irq_pending & ADI_IRQ_SRC_NEW_MEASUR) {
		if (ctl->update_tacho_params) {
			u32 new_tach = axi_ioread(ADI_REG_TACH_MEASUR, ctl);
			/* get 25% tolerance */
			u32 tach_tol = DIV_ROUND_CLOSEST(new_tach * 25, 100);

			/* set new tacho parameters */
			axi_iowrite(new_tach, ADI_REG_TACH_PERIOD, ctl);
			axi_iowrite(tach_tol, ADI_REG_TACH_TOLERANCE, ctl);
			ctl->update_tacho_params = false;
		}
	}

	if (irq_pending & ADI_IRQ_SRC_TACH_ERR)
		ctl->fan_fault = 1;

	/* clear all interrupts */
	clear_mask = irq_pending & ADI_IRQ_SRC_MASK;
	axi_iowrite(clear_mask, ADI_REG_IRQ_PENDING, ctl);

	return IRQ_HANDLED;
}

static int axi_fan_control_init(struct axi_fan_control_data *ctl,
				const struct device *dev)
{
	int ret;

	/* get fan pulses per revolution */
	ret = device_property_read_u32(dev, "pulses-per-revolution", &ctl->ppr);
	if (ret)
		return ret;

	/* 1, 2 and 4 are the typical and accepted values */
	if (ctl->ppr != 1 && ctl->ppr != 2 && ctl->ppr != 4)
		return -EINVAL;
	/*
	 * Enable all IRQs
	 */
	axi_iowrite(ADI_IRQ_MASK_OUT_ALL &
		    ~(ADI_IRQ_SRC_NEW_MEASUR | ADI_IRQ_SRC_TACH_ERR |
		      ADI_IRQ_SRC_PWM_CHANGED | ADI_IRQ_SRC_TEMP_INCREASE),
		    ADI_REG_IRQ_MASK, ctl);

	/* bring the device out of reset */
	axi_iowrite(0x01, ADI_REG_RSTN, ctl);

	return ret;
}

static const struct hwmon_channel_info * const axi_fan_control_info[] = {
	HWMON_CHANNEL_INFO(pwm, HWMON_PWM_INPUT),
	HWMON_CHANNEL_INFO(fan, HWMON_F_INPUT | HWMON_F_FAULT | HWMON_F_LABEL),
	HWMON_CHANNEL_INFO(temp, HWMON_T_INPUT | HWMON_T_LABEL),
	NULL
};

static const struct hwmon_ops axi_fan_control_hwmon_ops = {
	.is_visible = axi_fan_control_is_visible,
	.read = axi_fan_control_read,
	.write = axi_fan_control_write,
	.read_string = axi_fan_control_read_labels,
};

static const struct hwmon_chip_info axi_chip_info = {
	.ops = &axi_fan_control_hwmon_ops,
	.info = axi_fan_control_info,
};

/* temperature threshold below which PWM should be 0% */
static SENSOR_DEVICE_ATTR_RW(pwm1_auto_point1_temp_hyst, axi_fan_control, ADI_REG_TEMP_00_H);
/* temperature threshold above which PWM should be 25% */
static SENSOR_DEVICE_ATTR_RW(pwm1_auto_point1_temp, axi_fan_control, ADI_REG_TEMP_25_L);
/* temperature threshold below which PWM should be 25% */
static SENSOR_DEVICE_ATTR_RW(pwm1_auto_point2_temp_hyst, axi_fan_control, ADI_REG_TEMP_25_H);
/* temperature threshold above which PWM should be 50% */
static SENSOR_DEVICE_ATTR_RW(pwm1_auto_point2_temp, axi_fan_control, ADI_REG_TEMP_50_L);
/* temperature threshold below which PWM should be 50% */
static SENSOR_DEVICE_ATTR_RW(pwm1_auto_point3_temp_hyst, axi_fan_control, ADI_REG_TEMP_50_H);
/* temperature threshold above which PWM should be 75% */
static SENSOR_DEVICE_ATTR_RW(pwm1_auto_point3_temp, axi_fan_control, ADI_REG_TEMP_75_L);
/* temperature threshold below which PWM should be 75% */
static SENSOR_DEVICE_ATTR_RW(pwm1_auto_point4_temp_hyst, axi_fan_control, ADI_REG_TEMP_75_H);
/* temperature threshold above which PWM should be 100% */
static SENSOR_DEVICE_ATTR_RW(pwm1_auto_point4_temp, axi_fan_control, ADI_REG_TEMP_100_L);

static struct attribute *axi_fan_control_attrs[] = {
	&sensor_dev_attr_pwm1_auto_point1_temp_hyst.dev_attr.attr,
	&sensor_dev_attr_pwm1_auto_point1_temp.dev_attr.attr,
	&sensor_dev_attr_pwm1_auto_point2_temp_hyst.dev_attr.attr,
	&sensor_dev_attr_pwm1_auto_point2_temp.dev_attr.attr,
	&sensor_dev_attr_pwm1_auto_point3_temp_hyst.dev_attr.attr,
	&sensor_dev_attr_pwm1_auto_point3_temp.dev_attr.attr,
	&sensor_dev_attr_pwm1_auto_point4_temp_hyst.dev_attr.attr,
	&sensor_dev_attr_pwm1_auto_point4_temp.dev_attr.attr,
	NULL,
};
ATTRIBUTE_GROUPS(axi_fan_control);

static int axi_fan_control_probe(struct platform_device *pdev)
{
	struct axi_fan_control_data *ctl;
	struct clk *clk;
	const unsigned int *id;
	const char *name = "axi_fan_control";
	u32 version;
	int ret;

	id = device_get_match_data(&pdev->dev);
	if (!id)
		return -EINVAL;

	ctl = devm_kzalloc(&pdev->dev, sizeof(*ctl), GFP_KERNEL);
	if (!ctl)
		return -ENOMEM;

	ctl->base = devm_platform_ioremap_resource(pdev, 0);
	if (IS_ERR(ctl->base))
		return PTR_ERR(ctl->base);

	clk = devm_clk_get_enabled(&pdev->dev, NULL);
	if (IS_ERR(clk))
		return dev_err_probe(&pdev->dev, PTR_ERR(clk),
				     "clk_get failed\n");

	ctl->clk_rate = clk_get_rate(clk);
	if (!ctl->clk_rate)
		return -EINVAL;

	version = axi_ioread(ADI_AXI_REG_VERSION, ctl);
	if (ADI_AXI_PCORE_VER_MAJOR(version) !=
	    ADI_AXI_PCORE_VER_MAJOR((*id)))
		return dev_err_probe(&pdev->dev, -ENODEV,
				     "Major version mismatch. Expected %d.%.2d.%c, Reported %d.%.2d.%c\n",
				     ADI_AXI_PCORE_VER_MAJOR(*id),
				     ADI_AXI_PCORE_VER_MINOR(*id),
				     ADI_AXI_PCORE_VER_PATCH(*id),
				     ADI_AXI_PCORE_VER_MAJOR(version),
				     ADI_AXI_PCORE_VER_MINOR(version),
				     ADI_AXI_PCORE_VER_PATCH(version));

	ret = axi_fan_control_init(ctl, &pdev->dev);
	if (ret)
		return dev_err_probe(&pdev->dev, ret,
				     "Failed to initialize device\n");

	ctl->hdev = devm_hwmon_device_register_with_info(&pdev->dev,
							 name,
							 ctl,
							 &axi_chip_info,
							 axi_fan_control_groups);

	if (IS_ERR(ctl->hdev))
		return PTR_ERR(ctl->hdev);

	ctl->irq = platform_get_irq(pdev, 0);
	if (ctl->irq < 0)
		return ctl->irq;

	ret = devm_request_threaded_irq(&pdev->dev, ctl->irq, NULL,
					axi_fan_control_irq_handler,
					IRQF_ONESHOT | IRQF_TRIGGER_HIGH,
					NULL, ctl);
	if (ret)
		return ret;

	return 0;
}

static const u32 version_1_0_0 = ADI_AXI_PCORE_VER(1, 0, 'a');

static const struct of_device_id axi_fan_control_of_match[] = {
	{ .compatible = "adi,axi-fan-control-1.00.a",
		.data = (void *)&version_1_0_0},
	{},
};
MODULE_DEVICE_TABLE(of, axi_fan_control_of_match);

static struct platform_driver axi_fan_control_driver = {
	.driver = {
		.name = "axi_fan_control_driver",
		.of_match_table = axi_fan_control_of_match,
	},
	.probe = axi_fan_control_probe,
};
module_platform_driver(axi_fan_control_driver);

MODULE_AUTHOR("Nuno Sa <nuno.sa@analog.com>");
MODULE_DESCRIPTION("Analog Devices Fan Control HDL CORE driver");
MODULE_LICENSE("GPL");
