/*
 * drivers/hwmon/nsa320-hwmon.c
 *
 * ZyXEL NSA320 Media Servers
 * hardware monitoring
 *
 * Copyright (C) 2016 Adam Baker <linux@baker-net.org.uk>
 * based on a board file driver
 * Copyright (C) 2012 Peter Schildmann <linux@schildmann.info>
 *
 * This program is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License v2 as published by the
 * Free Software Foundation.
 *
 * This program is distributed in the hope that it will be useful, but WITHOUT
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
 * more details.
 */

#include <linux/bitops.h>
#include <linux/delay.h>
#include <linux/err.h>
#include <linux/gpio/consumer.h>
#include <linux/hwmon.h>
#include <linux/hwmon-sysfs.h>
#include <linux/jiffies.h>
#include <linux/module.h>
#include <linux/mutex.h>
#include <linux/of.h>
#include <linux/of_device.h>
#include <linux/of_platform.h>
#include <linux/platform_device.h>

/* Tests for error return values rely upon this value being < 0x80 */
#define MAGIC_NUMBER 0x55

/*
 * The Zyxel hwmon MCU is a Holtek HT46R065 that is factory programmed
 * to perform temperature and fan speed monitoring. It is read by taking
 * the active pin low. The 32 bit output word is then clocked onto the
 * data line. The MSB of the data word is a magic nuber to indicate it
 * has been read correctly, the next byte is the fan speed (in hundreds
 * of RPM) and the last two bytes are the temperature (in tenths of a
 * degree)
 */

struct nsa320_hwmon {
	struct mutex		update_lock;	/* lock GPIO operations */
	unsigned long		last_updated;	/* jiffies */
	unsigned long		mcu_data;
	struct gpio_desc	*act;
	struct gpio_desc	*clk;
	struct gpio_desc	*data;
};

enum nsa320_inputs {
	NSA320_TEMP = 0,
	NSA320_FAN = 1,
};

static const char * const nsa320_input_names[] = {
	[NSA320_TEMP] = "System Temperature",
	[NSA320_FAN] = "Chassis Fan",
};

/*
 * Although this protocol looks similar to SPI the long delay
 * between the active (aka chip select) signal and the shorter
 * delay between clock pulses are needed for reliable operation.
 * The delays provided are taken from the manufacturer kernel,
 * testing suggest they probably incorporate a reasonable safety
 * margin. (The single device tested became unreliable if the
 * delay was reduced to 1/10th of this value.)
 */
static s32 nsa320_hwmon_update(struct device *dev)
{
	u32 mcu_data;
	u32 mask;
	struct nsa320_hwmon *hwmon = dev_get_drvdata(dev);

	mutex_lock(&hwmon->update_lock);

	mcu_data = hwmon->mcu_data;

	if (time_after(jiffies, hwmon->last_updated + HZ) || mcu_data == 0) {
		gpiod_set_value(hwmon->act, 1);
		msleep(100);

		mcu_data = 0;
		for (mask = BIT(31); mask; mask >>= 1) {
			gpiod_set_value(hwmon->clk, 0);
			usleep_range(100, 200);
			gpiod_set_value(hwmon->clk, 1);
			usleep_range(100, 200);
			if (gpiod_get_value(hwmon->data))
				mcu_data |= mask;
		}

		gpiod_set_value(hwmon->act, 0);
		dev_dbg(dev, "Read raw MCU data %08x\n", mcu_data);

		if ((mcu_data >> 24) != MAGIC_NUMBER) {
			dev_dbg(dev, "Read invalid MCU data %08x\n", mcu_data);
			mcu_data = -EIO;
		} else {
			hwmon->mcu_data = mcu_data;
			hwmon->last_updated = jiffies;
		}
	}

	mutex_unlock(&hwmon->update_lock);

	return mcu_data;
}

static ssize_t show_label(struct device *dev,
			  struct device_attribute *attr, char *buf)
{
	int channel = to_sensor_dev_attr(attr)->index;

	return sprintf(buf, "%s\n", nsa320_input_names[channel]);
}

static ssize_t temp1_input_show(struct device *dev,
				struct device_attribute *attr, char *buf)
{
	s32 mcu_data = nsa320_hwmon_update(dev);

	if (mcu_data < 0)
		return mcu_data;

	return sprintf(buf, "%d\n", (mcu_data & 0xffff) * 100);
}

static ssize_t fan1_input_show(struct device *dev,
			       struct device_attribute *attr, char *buf)
{
	s32 mcu_data = nsa320_hwmon_update(dev);

	if (mcu_data < 0)
		return mcu_data;

	return sprintf(buf, "%d\n", ((mcu_data & 0xff0000) >> 16) * 100);
}

static SENSOR_DEVICE_ATTR(temp1_label, S_IRUGO, show_label, NULL, NSA320_TEMP);
static DEVICE_ATTR_RO(temp1_input);
static SENSOR_DEVICE_ATTR(fan1_label, S_IRUGO, show_label, NULL, NSA320_FAN);
static DEVICE_ATTR_RO(fan1_input);

static struct attribute *nsa320_attrs[] = {
	&sensor_dev_attr_temp1_label.dev_attr.attr,
	&dev_attr_temp1_input.attr,
	&sensor_dev_attr_fan1_label.dev_attr.attr,
	&dev_attr_fan1_input.attr,
	NULL
};

ATTRIBUTE_GROUPS(nsa320);

static const struct of_device_id of_nsa320_hwmon_match[] = {
	{ .compatible = "zyxel,nsa320-mcu", },
	{ },
};

static int nsa320_hwmon_probe(struct platform_device *pdev)
{
	struct nsa320_hwmon	*hwmon;
	struct device		*classdev;

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

	/* Look up the GPIO pins to use */
	hwmon->act = devm_gpiod_get(&pdev->dev, "act", GPIOD_OUT_LOW);
	if (IS_ERR(hwmon->act))
		return PTR_ERR(hwmon->act);

	hwmon->clk = devm_gpiod_get(&pdev->dev, "clk", GPIOD_OUT_HIGH);
	if (IS_ERR(hwmon->clk))
		return PTR_ERR(hwmon->clk);

	hwmon->data = devm_gpiod_get(&pdev->dev, "data", GPIOD_IN);
	if (IS_ERR(hwmon->data))
		return PTR_ERR(hwmon->data);

	mutex_init(&hwmon->update_lock);

	classdev = devm_hwmon_device_register_with_groups(&pdev->dev,
					"nsa320", hwmon, nsa320_groups);

	return PTR_ERR_OR_ZERO(classdev);

}

/* All allocations use devres so remove() is not needed. */

static struct platform_driver nsa320_hwmon_driver = {
	.probe = nsa320_hwmon_probe,
	.driver = {
		.name = "nsa320-hwmon",
		.of_match_table = of_match_ptr(of_nsa320_hwmon_match),
	},
};

module_platform_driver(nsa320_hwmon_driver);

MODULE_DEVICE_TABLE(of, of_nsa320_hwmon_match);
MODULE_AUTHOR("Peter Schildmann <linux@schildmann.info>");
MODULE_AUTHOR("Adam Baker <linux@baker-net.org.uk>");
MODULE_DESCRIPTION("NSA320 Hardware Monitoring");
MODULE_LICENSE("GPL v2");
MODULE_ALIAS("platform:nsa320-hwmon");
