// SPDX-License-Identifier: GPL-2.0-or-later
/*
 * Hardware monitoring driver for Texas Instruments TPS53679
 *
 * Copyright (c) 2017 Mellanox Technologies. All rights reserved.
 * Copyright (c) 2017 Vadim Pasternak <vadimp@mellanox.com>
 */

#include <linux/bits.h>
#include <linux/err.h>
#include <linux/i2c.h>
#include <linux/init.h>
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/of_device.h>
#include "pmbus.h"

enum chips {
	tps53647, tps53667, tps53679, tps53681, tps53688
};

#define TPS53647_PAGE_NUM		1

#define TPS53679_PROT_VR12_5MV		0x01 /* VR12.0 mode, 5-mV DAC */
#define TPS53679_PROT_VR12_5_10MV	0x02 /* VR12.5 mode, 10-mV DAC */
#define TPS53679_PROT_VR13_10MV		0x04 /* VR13.0 mode, 10-mV DAC */
#define TPS53679_PROT_IMVP8_5MV		0x05 /* IMVP8 mode, 5-mV DAC */
#define TPS53679_PROT_VR13_5MV		0x07 /* VR13.0 mode, 5-mV DAC */
#define TPS53679_PAGE_NUM		2

#define TPS53681_DEVICE_ID		0x81

#define TPS53681_PMBUS_REVISION		0x33

#define TPS53681_MFR_SPECIFIC_20	0xe4	/* Number of phases, per page */

static int tps53679_identify_mode(struct i2c_client *client,
				  struct pmbus_driver_info *info)
{
	u8 vout_params;
	int i, ret;

	for (i = 0; i < info->pages; i++) {
		/* Read the register with VOUT scaling value.*/
		ret = pmbus_read_byte_data(client, i, PMBUS_VOUT_MODE);
		if (ret < 0)
			return ret;

		vout_params = ret & GENMASK(4, 0);

		switch (vout_params) {
		case TPS53679_PROT_VR13_10MV:
		case TPS53679_PROT_VR12_5_10MV:
			info->vrm_version[i] = vr13;
			break;
		case TPS53679_PROT_VR13_5MV:
		case TPS53679_PROT_VR12_5MV:
		case TPS53679_PROT_IMVP8_5MV:
			info->vrm_version[i] = vr12;
			break;
		default:
			return -EINVAL;
		}
	}

	return 0;
}

static int tps53679_identify_phases(struct i2c_client *client,
				    struct pmbus_driver_info *info)
{
	int ret;

	/* On TPS53681, only channel A provides per-phase output current */
	ret = pmbus_read_byte_data(client, 0, TPS53681_MFR_SPECIFIC_20);
	if (ret < 0)
		return ret;
	info->phases[0] = (ret & 0x07) + 1;

	return 0;
}

static int tps53679_identify_chip(struct i2c_client *client,
				  u8 revision, u16 id)
{
	u8 buf[I2C_SMBUS_BLOCK_MAX];
	int ret;

	ret = pmbus_read_byte_data(client, 0, PMBUS_REVISION);
	if (ret < 0)
		return ret;
	if (ret != revision) {
		dev_err(&client->dev, "Unexpected PMBus revision 0x%x\n", ret);
		return -ENODEV;
	}

	ret = i2c_smbus_read_block_data(client, PMBUS_IC_DEVICE_ID, buf);
	if (ret < 0)
		return ret;
	if (ret != 1 || buf[0] != id) {
		dev_err(&client->dev, "Unexpected device ID 0x%x\n", buf[0]);
		return -ENODEV;
	}
	return 0;
}

/*
 * Common identification function for chips with multi-phase support.
 * Since those chips have special configuration registers, we want to have
 * some level of reassurance that we are really talking with the chip
 * being probed. Check PMBus revision and chip ID.
 */
static int tps53679_identify_multiphase(struct i2c_client *client,
					struct pmbus_driver_info *info,
					int pmbus_rev, int device_id)
{
	int ret;

	ret = tps53679_identify_chip(client, pmbus_rev, device_id);
	if (ret < 0)
		return ret;

	ret = tps53679_identify_mode(client, info);
	if (ret < 0)
		return ret;

	return tps53679_identify_phases(client, info);
}

static int tps53679_identify(struct i2c_client *client,
			     struct pmbus_driver_info *info)
{
	return tps53679_identify_mode(client, info);
}

static int tps53681_identify(struct i2c_client *client,
			     struct pmbus_driver_info *info)
{
	return tps53679_identify_multiphase(client, info,
					    TPS53681_PMBUS_REVISION,
					    TPS53681_DEVICE_ID);
}

static int tps53681_read_word_data(struct i2c_client *client, int page,
				   int phase, int reg)
{
	/*
	 * For reading the total output current (READ_IOUT) for all phases,
	 * the chip datasheet is a bit vague. It says "PHASE must be set to
	 * FFh to access all phases simultaneously. PHASE may also be set to
	 * 80h readack (!) the total phase current".
	 * Experiments show that the command does _not_ report the total
	 * current for all phases if the phase is set to 0xff. Instead, it
	 * appears to report the current of one of the phases. Override phase
	 * parameter with 0x80 when reading the total output current on page 0.
	 */
	if (reg == PMBUS_READ_IOUT && page == 0 && phase == 0xff)
		return pmbus_read_word_data(client, page, 0x80, reg);
	return -ENODATA;
}

static struct pmbus_driver_info tps53679_info = {
	.format[PSC_VOLTAGE_IN] = linear,
	.format[PSC_VOLTAGE_OUT] = vid,
	.format[PSC_TEMPERATURE] = linear,
	.format[PSC_CURRENT_OUT] = linear,
	.format[PSC_POWER] = linear,
	.func[0] = PMBUS_HAVE_VIN | PMBUS_HAVE_IIN | PMBUS_HAVE_PIN |
		PMBUS_HAVE_STATUS_INPUT |
		PMBUS_HAVE_VOUT | PMBUS_HAVE_STATUS_VOUT |
		PMBUS_HAVE_IOUT | PMBUS_HAVE_STATUS_IOUT |
		PMBUS_HAVE_TEMP | PMBUS_HAVE_STATUS_TEMP |
		PMBUS_HAVE_POUT,
	.func[1] = PMBUS_HAVE_VOUT | PMBUS_HAVE_STATUS_VOUT |
		PMBUS_HAVE_IOUT | PMBUS_HAVE_STATUS_IOUT |
		PMBUS_HAVE_TEMP | PMBUS_HAVE_STATUS_TEMP |
		PMBUS_HAVE_POUT,
	.pfunc[0] = PMBUS_HAVE_IOUT,
	.pfunc[1] = PMBUS_HAVE_IOUT,
	.pfunc[2] = PMBUS_HAVE_IOUT,
	.pfunc[3] = PMBUS_HAVE_IOUT,
	.pfunc[4] = PMBUS_HAVE_IOUT,
	.pfunc[5] = PMBUS_HAVE_IOUT,
};

static int tps53679_probe(struct i2c_client *client,
			  const struct i2c_device_id *id)
{
	struct device *dev = &client->dev;
	struct pmbus_driver_info *info;
	enum chips chip_id;

	if (dev->of_node)
		chip_id = (enum chips)of_device_get_match_data(dev);
	else
		chip_id = id->driver_data;

	info = devm_kmemdup(dev, &tps53679_info, sizeof(*info), GFP_KERNEL);
	if (!info)
		return -ENOMEM;

	switch (chip_id) {
	case tps53647:
	case tps53667:
		info->pages = TPS53647_PAGE_NUM;
		info->identify = tps53679_identify;
		break;
	case tps53679:
	case tps53688:
		info->pages = TPS53679_PAGE_NUM;
		info->identify = tps53679_identify;
		break;
	case tps53681:
		info->pages = TPS53679_PAGE_NUM;
		info->phases[0] = 6;
		info->identify = tps53681_identify;
		info->read_word_data = tps53681_read_word_data;
		break;
	default:
		return -ENODEV;
	}

	return pmbus_do_probe(client, id, info);
}

static const struct i2c_device_id tps53679_id[] = {
	{"tps53647", tps53647},
	{"tps53667", tps53667},
	{"tps53679", tps53679},
	{"tps53681", tps53681},
	{"tps53688", tps53688},
	{}
};

MODULE_DEVICE_TABLE(i2c, tps53679_id);

static const struct of_device_id __maybe_unused tps53679_of_match[] = {
	{.compatible = "ti,tps53647", .data = (void *)tps53647},
	{.compatible = "ti,tps53667", .data = (void *)tps53667},
	{.compatible = "ti,tps53679", .data = (void *)tps53679},
	{.compatible = "ti,tps53681", .data = (void *)tps53681},
	{.compatible = "ti,tps53688", .data = (void *)tps53688},
	{}
};
MODULE_DEVICE_TABLE(of, tps53679_of_match);

static struct i2c_driver tps53679_driver = {
	.driver = {
		.name = "tps53679",
		.of_match_table = of_match_ptr(tps53679_of_match),
	},
	.probe = tps53679_probe,
	.remove = pmbus_do_remove,
	.id_table = tps53679_id,
};

module_i2c_driver(tps53679_driver);

MODULE_AUTHOR("Vadim Pasternak <vadimp@mellanox.com>");
MODULE_DESCRIPTION("PMBus driver for Texas Instruments TPS53679");
MODULE_LICENSE("GPL");
