// SPDX-License-Identifier: GPL-2.0-or-later
/*
 * Copyright 2019 Inspur Corp.
 */

#include <linux/debugfs.h>
#include <linux/device.h>
#include <linux/fs.h>
#include <linux/i2c.h>
#include <linux/module.h>
#include <linux/pmbus.h>
#include <linux/hwmon-sysfs.h>

#include "pmbus.h"

#define IPSPS_REG_VENDOR_ID	0x99
#define IPSPS_REG_MODEL		0x9A
#define IPSPS_REG_FW_VERSION	0x9B
#define IPSPS_REG_PN		0x9C
#define IPSPS_REG_SN		0x9E
#define IPSPS_REG_HW_VERSION	0xB0
#define IPSPS_REG_MODE		0xFC

#define MODE_ACTIVE		0x55
#define MODE_STANDBY		0x0E
#define MODE_REDUNDANCY		0x00

#define MODE_ACTIVE_STRING		"active"
#define MODE_STANDBY_STRING		"standby"
#define MODE_REDUNDANCY_STRING		"redundancy"

enum ipsps_index {
	vendor,
	model,
	fw_version,
	part_number,
	serial_number,
	hw_version,
	mode,
	num_regs,
};

static const u8 ipsps_regs[num_regs] = {
	[vendor] = IPSPS_REG_VENDOR_ID,
	[model] = IPSPS_REG_MODEL,
	[fw_version] = IPSPS_REG_FW_VERSION,
	[part_number] = IPSPS_REG_PN,
	[serial_number] = IPSPS_REG_SN,
	[hw_version] = IPSPS_REG_HW_VERSION,
	[mode] = IPSPS_REG_MODE,
};

static ssize_t ipsps_string_show(struct device *dev,
				 struct device_attribute *devattr,
				 char *buf)
{
	u8 reg;
	int rc;
	char *p;
	char data[I2C_SMBUS_BLOCK_MAX + 1];
	struct i2c_client *client = to_i2c_client(dev->parent);
	struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr);

	reg = ipsps_regs[attr->index];
	rc = i2c_smbus_read_block_data(client, reg, data);
	if (rc < 0)
		return rc;

	/* filled with printable characters, ending with # */
	p = memscan(data, '#', rc);
	*p = '\0';

	return sysfs_emit(buf, "%s\n", data);
}

static ssize_t ipsps_fw_version_show(struct device *dev,
				     struct device_attribute *devattr,
				     char *buf)
{
	u8 reg;
	int rc;
	u8 data[I2C_SMBUS_BLOCK_MAX] = { 0 };
	struct i2c_client *client = to_i2c_client(dev->parent);
	struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr);

	reg = ipsps_regs[attr->index];
	rc = i2c_smbus_read_block_data(client, reg, data);
	if (rc < 0)
		return rc;

	if (rc != 6)
		return -EPROTO;

	return sysfs_emit(buf, "%u.%02u%u-%u.%02u\n",
			  data[1], data[2]/* < 100 */, data[3]/*< 10*/,
			  data[4], data[5]/* < 100 */);
}

static ssize_t ipsps_mode_show(struct device *dev,
			       struct device_attribute *devattr, char *buf)
{
	u8 reg;
	int rc;
	struct i2c_client *client = to_i2c_client(dev->parent);
	struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr);

	reg = ipsps_regs[attr->index];
	rc = i2c_smbus_read_byte_data(client, reg);
	if (rc < 0)
		return rc;

	switch (rc) {
	case MODE_ACTIVE:
		return sysfs_emit(buf, "[%s] %s %s\n",
				  MODE_ACTIVE_STRING,
				  MODE_STANDBY_STRING, MODE_REDUNDANCY_STRING);
	case MODE_STANDBY:
		return sysfs_emit(buf, "%s [%s] %s\n",
				  MODE_ACTIVE_STRING,
				  MODE_STANDBY_STRING, MODE_REDUNDANCY_STRING);
	case MODE_REDUNDANCY:
		return sysfs_emit(buf, "%s %s [%s]\n",
				  MODE_ACTIVE_STRING,
				  MODE_STANDBY_STRING, MODE_REDUNDANCY_STRING);
	default:
		return sysfs_emit(buf, "unspecified\n");
	}
}

static ssize_t ipsps_mode_store(struct device *dev,
				struct device_attribute *devattr,
				const char *buf, size_t count)
{
	u8 reg;
	int rc;
	struct i2c_client *client = to_i2c_client(dev->parent);
	struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr);

	reg = ipsps_regs[attr->index];
	if (sysfs_streq(MODE_STANDBY_STRING, buf)) {
		rc = i2c_smbus_write_byte_data(client, reg,
					       MODE_STANDBY);
		if (rc < 0)
			return rc;
		return count;
	} else if (sysfs_streq(MODE_ACTIVE_STRING, buf)) {
		rc = i2c_smbus_write_byte_data(client, reg,
					       MODE_ACTIVE);
		if (rc < 0)
			return rc;
		return count;
	}

	return -EINVAL;
}

static SENSOR_DEVICE_ATTR_RO(vendor, ipsps_string, vendor);
static SENSOR_DEVICE_ATTR_RO(model, ipsps_string, model);
static SENSOR_DEVICE_ATTR_RO(part_number, ipsps_string, part_number);
static SENSOR_DEVICE_ATTR_RO(serial_number, ipsps_string, serial_number);
static SENSOR_DEVICE_ATTR_RO(hw_version, ipsps_string, hw_version);
static SENSOR_DEVICE_ATTR_RO(fw_version, ipsps_fw_version, fw_version);
static SENSOR_DEVICE_ATTR_RW(mode, ipsps_mode, mode);

static struct attribute *ipsps_attrs[] = {
	&sensor_dev_attr_vendor.dev_attr.attr,
	&sensor_dev_attr_model.dev_attr.attr,
	&sensor_dev_attr_part_number.dev_attr.attr,
	&sensor_dev_attr_serial_number.dev_attr.attr,
	&sensor_dev_attr_hw_version.dev_attr.attr,
	&sensor_dev_attr_fw_version.dev_attr.attr,
	&sensor_dev_attr_mode.dev_attr.attr,
	NULL,
};

ATTRIBUTE_GROUPS(ipsps);

static struct pmbus_driver_info ipsps_info = {
	.pages = 1,
	.func[0] = PMBUS_HAVE_VIN | PMBUS_HAVE_VOUT | PMBUS_HAVE_IOUT |
		PMBUS_HAVE_IIN | PMBUS_HAVE_POUT | PMBUS_HAVE_PIN |
		PMBUS_HAVE_FAN12 | PMBUS_HAVE_TEMP | PMBUS_HAVE_TEMP2 |
		PMBUS_HAVE_TEMP3 | PMBUS_HAVE_STATUS_VOUT |
		PMBUS_HAVE_STATUS_IOUT | PMBUS_HAVE_STATUS_INPUT |
		PMBUS_HAVE_STATUS_TEMP | PMBUS_HAVE_STATUS_FAN12,
	.groups = ipsps_groups,
};

static struct pmbus_platform_data ipsps_pdata = {
	.flags = PMBUS_SKIP_STATUS_CHECK,
};

static int ipsps_probe(struct i2c_client *client)
{
	client->dev.platform_data = &ipsps_pdata;
	return pmbus_do_probe(client, &ipsps_info);
}

static const struct i2c_device_id ipsps_id[] = {
	{ "ipsps1", 0 },
	{}
};
MODULE_DEVICE_TABLE(i2c, ipsps_id);

#ifdef CONFIG_OF
static const struct of_device_id ipsps_of_match[] = {
	{ .compatible = "inspur,ipsps1" },
	{}
};
MODULE_DEVICE_TABLE(of, ipsps_of_match);
#endif

static struct i2c_driver ipsps_driver = {
	.driver = {
		.name = "inspur-ipsps",
		.of_match_table = of_match_ptr(ipsps_of_match),
	},
	.probe_new = ipsps_probe,
	.id_table = ipsps_id,
};

module_i2c_driver(ipsps_driver);

MODULE_AUTHOR("John Wang");
MODULE_DESCRIPTION("PMBus driver for Inspur Power System power supplies");
MODULE_LICENSE("GPL");
MODULE_IMPORT_NS(PMBUS);
