// SPDX-License-Identifier: GPL-2.0-only
/*
 * SolidRun DPU driver for control plane
 *
 * Copyright (C) 2022-2023 SolidRun
 *
 * Author: Alvaro Karsz <alvaro.karsz@solid-run.com>
 *
 */
#include <linux/hwmon.h>

#include "snet_vdpa.h"

/* Monitor offsets */
#define SNET_MON_TMP0_IN_OFF      0x00
#define SNET_MON_TMP0_MAX_OFF     0x08
#define SNET_MON_TMP0_CRIT_OFF    0x10
#define SNET_MON_TMP1_IN_OFF      0x18
#define SNET_MON_TMP1_CRIT_OFF    0x20
#define SNET_MON_CURR_IN_OFF      0x28
#define SNET_MON_CURR_MAX_OFF     0x30
#define SNET_MON_CURR_CRIT_OFF    0x38
#define SNET_MON_PWR_IN_OFF       0x40
#define SNET_MON_VOLT_IN_OFF      0x48
#define SNET_MON_VOLT_CRIT_OFF    0x50
#define SNET_MON_VOLT_LCRIT_OFF   0x58

static void snet_hwmon_read_reg(struct psnet *psnet, u32 reg, long *out)
{
	*out = psnet_read64(psnet, psnet->cfg.hwmon_off + reg);
}

static umode_t snet_howmon_is_visible(const void *data,
				      enum hwmon_sensor_types type,
				      u32 attr, int channel)
{
	return 0444;
}

static int snet_howmon_read(struct device *dev, enum hwmon_sensor_types type,
			    u32 attr, int channel, long *val)
{
	struct psnet *psnet = dev_get_drvdata(dev);
	int ret = 0;

	switch (type) {
	case hwmon_in:
		switch (attr) {
		case hwmon_in_lcrit:
			snet_hwmon_read_reg(psnet, SNET_MON_VOLT_LCRIT_OFF, val);
			break;
		case hwmon_in_crit:
			snet_hwmon_read_reg(psnet, SNET_MON_VOLT_CRIT_OFF, val);
			break;
		case hwmon_in_input:
			snet_hwmon_read_reg(psnet, SNET_MON_VOLT_IN_OFF, val);
			break;
		default:
			ret = -EOPNOTSUPP;
			break;
		}
		break;

	case hwmon_power:
		switch (attr) {
		case hwmon_power_input:
			snet_hwmon_read_reg(psnet, SNET_MON_PWR_IN_OFF, val);
			break;

		default:
			ret = -EOPNOTSUPP;
			break;
		}
		break;

	case hwmon_curr:
		switch (attr) {
		case hwmon_curr_input:
			snet_hwmon_read_reg(psnet, SNET_MON_CURR_IN_OFF, val);
			break;
		case hwmon_curr_max:
			snet_hwmon_read_reg(psnet, SNET_MON_CURR_MAX_OFF, val);
			break;
		case hwmon_curr_crit:
			snet_hwmon_read_reg(psnet, SNET_MON_CURR_CRIT_OFF, val);
			break;
		default:
			ret = -EOPNOTSUPP;
			break;
		}
		break;

	case hwmon_temp:
		switch (attr) {
		case hwmon_temp_input:
			if (channel == 0)
				snet_hwmon_read_reg(psnet, SNET_MON_TMP0_IN_OFF, val);
			else
				snet_hwmon_read_reg(psnet, SNET_MON_TMP1_IN_OFF, val);
			break;
		case hwmon_temp_max:
			if (channel == 0)
				snet_hwmon_read_reg(psnet, SNET_MON_TMP0_MAX_OFF, val);
			else
				ret = -EOPNOTSUPP;
			break;
		case hwmon_temp_crit:
			if (channel == 0)
				snet_hwmon_read_reg(psnet, SNET_MON_TMP0_CRIT_OFF, val);
			else
				snet_hwmon_read_reg(psnet, SNET_MON_TMP1_CRIT_OFF, val);
			break;

		default:
			ret = -EOPNOTSUPP;
			break;
		}
		break;

	default:
		ret = -EOPNOTSUPP;
		break;
	}
	return ret;
}

static int snet_hwmon_read_string(struct device *dev,
				  enum hwmon_sensor_types type, u32 attr,
				  int channel, const char **str)
{
	int ret = 0;

	switch (type) {
	case hwmon_in:
		*str = "main_vin";
		break;
	case hwmon_power:
		*str = "soc_pin";
		break;
	case hwmon_curr:
		*str = "soc_iin";
		break;
	case hwmon_temp:
		if (channel == 0)
			*str = "power_stage_temp";
		else
			*str = "ic_junction_temp";
		break;
	default:
		ret = -EOPNOTSUPP;
		break;
	}
	return ret;
}

static const struct hwmon_ops snet_hwmon_ops = {
	.is_visible = snet_howmon_is_visible,
	.read = snet_howmon_read,
	.read_string = snet_hwmon_read_string
};

static const struct hwmon_channel_info *snet_hwmon_info[] = {
	HWMON_CHANNEL_INFO(temp, HWMON_T_INPUT | HWMON_T_MAX | HWMON_T_CRIT | HWMON_T_LABEL,
			   HWMON_T_INPUT | HWMON_T_CRIT | HWMON_T_LABEL),
	HWMON_CHANNEL_INFO(power, HWMON_P_INPUT | HWMON_P_LABEL),
	HWMON_CHANNEL_INFO(curr, HWMON_C_INPUT | HWMON_C_MAX | HWMON_C_CRIT | HWMON_C_LABEL),
	HWMON_CHANNEL_INFO(in, HWMON_I_INPUT | HWMON_I_CRIT | HWMON_I_LCRIT | HWMON_I_LABEL),
			   NULL
};

static const struct hwmon_chip_info snet_hwmono_info = {
	.ops = &snet_hwmon_ops,
	.info = snet_hwmon_info,
};

/* Create an HW monitor device */
void psnet_create_hwmon(struct pci_dev *pdev)
{
	struct device *hwmon;
	struct psnet *psnet = pci_get_drvdata(pdev);

	snprintf(psnet->hwmon_name, SNET_NAME_SIZE, "snet_%s", pci_name(pdev));
	hwmon = devm_hwmon_device_register_with_info(&pdev->dev, psnet->hwmon_name, psnet,
						     &snet_hwmono_info, NULL);
	/* The monitor is not mandatory, Just alert user in case of an error */
	if (IS_ERR(hwmon))
		SNET_WARN(pdev, "Failed to create SNET hwmon, error %ld\n", PTR_ERR(hwmon));
}
