// SPDX-License-Identifier: GPL-2.0
/*
 * Synaptics AS370 SoC Hardware Monitoring Driver
 *
 * Copyright (C) 2018 Synaptics Incorporated
 * Author: Jisheng Zhang <jszhang@kernel.org>
 */

#include <linux/bitops.h>
#include <linux/hwmon.h>
#include <linux/init.h>
#include <linux/io.h>
#include <linux/module.h>
#include <linux/of_device.h>

#define CTRL		0x0
#define  PD		BIT(0)
#define  EN		BIT(1)
#define  T_SEL		BIT(2)
#define  V_SEL		BIT(3)
#define  NMOS_SEL	BIT(8)
#define  PMOS_SEL	BIT(9)
#define STS		0x4
#define  BN_MASK	GENMASK(11, 0)
#define  EOC		BIT(12)

struct as370_hwmon {
	void __iomem *base;
};

static void init_pvt(struct as370_hwmon *hwmon)
{
	u32 val;
	void __iomem *addr = hwmon->base + CTRL;

	val = PD;
	writel_relaxed(val, addr);
	val |= T_SEL;
	writel_relaxed(val, addr);
	val |= EN;
	writel_relaxed(val, addr);
	val &= ~PD;
	writel_relaxed(val, addr);
}

static int as370_hwmon_read(struct device *dev, enum hwmon_sensor_types type,
			    u32 attr, int channel, long *temp)
{
	int val;
	struct as370_hwmon *hwmon = dev_get_drvdata(dev);

	switch (attr) {
	case hwmon_temp_input:
		val = readl_relaxed(hwmon->base + STS) & BN_MASK;
		*temp = DIV_ROUND_CLOSEST(val * 251802, 4096) - 85525;
		break;
	default:
		return -EOPNOTSUPP;
	}

	return 0;
}

static umode_t
as370_hwmon_is_visible(const void *data, enum hwmon_sensor_types type,
		       u32 attr, int channel)
{
	if (type != hwmon_temp)
		return 0;

	switch (attr) {
	case hwmon_temp_input:
		return 0444;
	default:
		return 0;
	}
}

static const struct hwmon_channel_info *as370_hwmon_info[] = {
	HWMON_CHANNEL_INFO(temp, HWMON_T_INPUT),
	NULL
};

static const struct hwmon_ops as370_hwmon_ops = {
	.is_visible = as370_hwmon_is_visible,
	.read = as370_hwmon_read,
};

static const struct hwmon_chip_info as370_chip_info = {
	.ops = &as370_hwmon_ops,
	.info = as370_hwmon_info,
};

static int as370_hwmon_probe(struct platform_device *pdev)
{
	struct device *hwmon_dev;
	struct as370_hwmon *hwmon;
	struct device *dev = &pdev->dev;

	hwmon = devm_kzalloc(dev, sizeof(*hwmon), GFP_KERNEL);
	if (!hwmon)
		return -ENOMEM;

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

	init_pvt(hwmon);

	hwmon_dev = devm_hwmon_device_register_with_info(dev,
							 "as370",
							 hwmon,
							 &as370_chip_info,
							 NULL);
	return PTR_ERR_OR_ZERO(hwmon_dev);
}

static const struct of_device_id as370_hwmon_match[] = {
	{ .compatible = "syna,as370-hwmon" },
	{},
};
MODULE_DEVICE_TABLE(of, as370_hwmon_match);

static struct platform_driver as370_hwmon_driver = {
	.probe = as370_hwmon_probe,
	.driver = {
		.name = "as370-hwmon",
		.of_match_table = as370_hwmon_match,
	},
};
module_platform_driver(as370_hwmon_driver);

MODULE_AUTHOR("Jisheng Zhang<jszhang@kernel.org>");
MODULE_DESCRIPTION("Synaptics AS370 SoC hardware monitor");
MODULE_LICENSE("GPL v2");
