// SPDX-License-Identifier: GPL-2.0-or-later
/*
 * Hardware monitoring driver for PIM4006, PIM4328 and PIM4820
 *
 * Copyright (c) 2021 Flextronics International Sweden AB
 */

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

enum chips { pim4006, pim4328, pim4820 };

struct pim4328_data {
	enum chips id;
	struct pmbus_driver_info info;
};

#define to_pim4328_data(x)  container_of(x, struct pim4328_data, info)

/* PIM4006 and PIM4328 */
#define PIM4328_MFR_READ_VINA		0xd3
#define PIM4328_MFR_READ_VINB		0xd4

/* PIM4006 */
#define PIM4328_MFR_READ_IINA		0xd6
#define PIM4328_MFR_READ_IINB		0xd7
#define PIM4328_MFR_FET_CHECKSTATUS	0xd9

/* PIM4328 */
#define PIM4328_MFR_STATUS_BITS		0xd5

/* PIM4820 */
#define PIM4328_MFR_READ_STATUS		0xd0

static const struct i2c_device_id pim4328_id[] = {
	{"bmr455", pim4328},
	{"pim4006", pim4006},
	{"pim4106", pim4006},
	{"pim4206", pim4006},
	{"pim4306", pim4006},
	{"pim4328", pim4328},
	{"pim4406", pim4006},
	{"pim4820", pim4820},
	{}
};
MODULE_DEVICE_TABLE(i2c, pim4328_id);

static int pim4328_read_word_data(struct i2c_client *client, int page,
				  int phase, int reg)
{
	int ret;

	if (page > 0)
		return -ENXIO;

	if (phase == 0xff)
		return -ENODATA;

	switch (reg) {
	case PMBUS_READ_VIN:
		ret = pmbus_read_word_data(client, page, phase,
					   phase == 0 ? PIM4328_MFR_READ_VINA
						      : PIM4328_MFR_READ_VINB);
		break;
	case PMBUS_READ_IIN:
		ret = pmbus_read_word_data(client, page, phase,
					   phase == 0 ? PIM4328_MFR_READ_IINA
						      : PIM4328_MFR_READ_IINB);
		break;
	default:
		ret = -ENODATA;
	}

	return ret;
}

static int pim4328_read_byte_data(struct i2c_client *client, int page, int reg)
{
	const struct pmbus_driver_info *info = pmbus_get_driver_info(client);
	struct pim4328_data *data = to_pim4328_data(info);
	int ret, status;

	if (page > 0)
		return -ENXIO;

	switch (reg) {
	case PMBUS_STATUS_BYTE:
		ret = pmbus_read_byte_data(client, page, PMBUS_STATUS_BYTE);
		if (ret < 0)
			return ret;
		if (data->id == pim4006) {
			status = pmbus_read_word_data(client, page, 0xff,
						      PIM4328_MFR_FET_CHECKSTATUS);
			if (status < 0)
				return status;
			if (status & 0x0630) /* Input UV */
				ret |= PB_STATUS_VIN_UV;
		} else if (data->id == pim4328) {
			status = pmbus_read_byte_data(client, page,
						      PIM4328_MFR_STATUS_BITS);
			if (status < 0)
				return status;
			if (status & 0x04) /* Input UV */
				ret |= PB_STATUS_VIN_UV;
			if (status & 0x40) /* Output UV */
				ret |= PB_STATUS_NONE_ABOVE;
		} else if (data->id == pim4820) {
			status = pmbus_read_byte_data(client, page,
						      PIM4328_MFR_READ_STATUS);
			if (status < 0)
				return status;
			if (status & 0x05) /* Input OV or OC */
				ret |= PB_STATUS_NONE_ABOVE;
			if (status & 0x1a) /* Input UV */
				ret |= PB_STATUS_VIN_UV;
			if (status & 0x40) /* OT */
				ret |= PB_STATUS_TEMPERATURE;
		}
		break;
	default:
		ret = -ENODATA;
	}

	return ret;
}

static int pim4328_probe(struct i2c_client *client)
{
	int status;
	u8 device_id[I2C_SMBUS_BLOCK_MAX + 1];
	const struct i2c_device_id *mid;
	struct pim4328_data *data;
	struct pmbus_driver_info *info;
	struct pmbus_platform_data *pdata;
	struct device *dev = &client->dev;

	if (!i2c_check_functionality(client->adapter,
				     I2C_FUNC_SMBUS_READ_BYTE_DATA
				     | I2C_FUNC_SMBUS_BLOCK_DATA))
		return -ENODEV;

	data = devm_kzalloc(&client->dev, sizeof(struct pim4328_data),
			    GFP_KERNEL);
	if (!data)
		return -ENOMEM;

	status = i2c_smbus_read_block_data(client, PMBUS_MFR_MODEL, device_id);
	if (status < 0) {
		dev_err(&client->dev, "Failed to read Manufacturer Model\n");
		return status;
	}
	for (mid = pim4328_id; mid->name[0]; mid++) {
		if (!strncasecmp(mid->name, device_id, strlen(mid->name)))
			break;
	}
	if (!mid->name[0]) {
		dev_err(&client->dev, "Unsupported device\n");
		return -ENODEV;
	}

	if (strcmp(client->name, mid->name))
		dev_notice(&client->dev,
			   "Device mismatch: Configured %s, detected %s\n",
			   client->name, mid->name);

	data->id = mid->driver_data;
	info = &data->info;
	info->pages = 1;
	info->read_byte_data = pim4328_read_byte_data;
	info->read_word_data = pim4328_read_word_data;

	pdata = devm_kzalloc(dev, sizeof(struct pmbus_platform_data),
			     GFP_KERNEL);
	if (!pdata)
		return -ENOMEM;
	dev->platform_data = pdata;
	pdata->flags = PMBUS_NO_CAPABILITY | PMBUS_NO_WRITE_PROTECT;

	switch (data->id) {
	case pim4006:
		info->phases[0] = 2;
		info->func[0] = PMBUS_PHASE_VIRTUAL | PMBUS_HAVE_VIN
			| PMBUS_HAVE_TEMP | PMBUS_HAVE_IOUT;
		info->pfunc[0] = PMBUS_HAVE_VIN | PMBUS_HAVE_IIN;
		info->pfunc[1] = PMBUS_HAVE_VIN | PMBUS_HAVE_IIN;
		break;
	case pim4328:
		info->phases[0] = 2;
		info->func[0] = PMBUS_PHASE_VIRTUAL
			| PMBUS_HAVE_VCAP | PMBUS_HAVE_VIN
			| PMBUS_HAVE_TEMP | PMBUS_HAVE_IOUT;
		info->pfunc[0] = PMBUS_HAVE_VIN;
		info->pfunc[1] = PMBUS_HAVE_VIN;
		info->format[PSC_VOLTAGE_IN] = direct;
		info->format[PSC_TEMPERATURE] = direct;
		info->format[PSC_CURRENT_OUT] = direct;
		pdata->flags |= PMBUS_USE_COEFFICIENTS_CMD;
		break;
	case pim4820:
		info->func[0] = PMBUS_HAVE_VIN | PMBUS_HAVE_TEMP
			| PMBUS_HAVE_IIN;
		info->format[PSC_VOLTAGE_IN] = direct;
		info->format[PSC_TEMPERATURE] = direct;
		info->format[PSC_CURRENT_IN] = direct;
		pdata->flags |= PMBUS_USE_COEFFICIENTS_CMD;
		break;
	default:
		return -ENODEV;
	}

	return pmbus_do_probe(client, info);
}

static struct i2c_driver pim4328_driver = {
	.driver = {
		   .name = "pim4328",
		   },
	.probe_new = pim4328_probe,
	.id_table = pim4328_id,
};

module_i2c_driver(pim4328_driver);

MODULE_AUTHOR("Erik Rosen <erik.rosen@metormote.com>");
MODULE_DESCRIPTION("PMBus driver for PIM4006, PIM4328, PIM4820 power interface modules");
MODULE_LICENSE("GPL");
MODULE_IMPORT_NS(PMBUS);
