// SPDX-License-Identifier: GPL-2.0
/*
 * ADM1177 Hot Swap Controller and Digital Power Monitor with Soft Start Pin
 *
 * Copyright 2015-2019 Analog Devices Inc.
 */

#include <linux/bits.h>
#include <linux/device.h>
#include <linux/hwmon.h>
#include <linux/i2c.h>
#include <linux/init.h>
#include <linux/math64.h>
#include <linux/minmax.h>
#include <linux/module.h>
#include <linux/regulator/consumer.h>

/*  Command Byte Operations */
#define ADM1177_CMD_V_CONT	BIT(0)
#define ADM1177_CMD_I_CONT	BIT(2)
#define ADM1177_CMD_VRANGE	BIT(4)

/* Extended Register */
#define ADM1177_REG_ALERT_TH	2

#define ADM1177_BITS		12

/**
 * struct adm1177_state - driver instance specific data
 * @client:		pointer to i2c client
 * @r_sense_uohm:	current sense resistor value
 * @alert_threshold_ua:	current limit for shutdown
 * @vrange_high:	internal voltage divider
 */
struct adm1177_state {
	struct i2c_client	*client;
	u32			r_sense_uohm;
	u64			alert_threshold_ua;
	bool			vrange_high;
};

static int adm1177_read_raw(struct adm1177_state *st, u8 num, u8 *data)
{
	return i2c_master_recv(st->client, data, num);
}

static int adm1177_write_cmd(struct adm1177_state *st, u8 cmd)
{
	return i2c_smbus_write_byte(st->client, cmd);
}

static int adm1177_write_alert_thr(struct adm1177_state *st,
				   u64 alert_threshold_ua)
{
	u64 val;
	int ret;

	val = 0xFFULL * alert_threshold_ua * st->r_sense_uohm;
	val = div_u64(val, 105840000U);
	val = div_u64(val, 1000U);
	if (val > 0xFF)
		val = 0xFF;

	ret = i2c_smbus_write_byte_data(st->client, ADM1177_REG_ALERT_TH,
					val);
	if (ret)
		return ret;

	st->alert_threshold_ua = alert_threshold_ua;
	return 0;
}

static int adm1177_read(struct device *dev, enum hwmon_sensor_types type,
			u32 attr, int channel, long *val)
{
	struct adm1177_state *st = dev_get_drvdata(dev);
	u8 data[3];
	long dummy;
	int ret;

	switch (type) {
	case hwmon_curr:
		switch (attr) {
		case hwmon_curr_input:
			ret = adm1177_read_raw(st, 3, data);
			if (ret < 0)
				return ret;
			dummy = (data[1] << 4) | (data[2] & 0xF);
			/*
			 * convert to milliamperes
			 * ((105.84mV / 4096) x raw) / senseResistor(ohm)
			 */
			*val = div_u64((105840000ull * dummy),
				       4096 * st->r_sense_uohm);
			return 0;
		case hwmon_curr_max:
			*val = div_u64(st->alert_threshold_ua, 1000);
			return 0;
		default:
			return -EOPNOTSUPP;
		}
	case hwmon_in:
		ret = adm1177_read_raw(st, 3, data);
		if (ret < 0)
			return ret;
		dummy = (data[0] << 4) | (data[2] >> 4);
		/*
		 * convert to millivolts based on resistor devision
		 * (V_fullscale / 4096) * raw
		 */
		if (st->vrange_high)
			dummy *= 26350;
		else
			dummy *= 6650;

		*val = DIV_ROUND_CLOSEST(dummy, 4096);
		return 0;
	default:
		return -EOPNOTSUPP;
	}
}

static int adm1177_write(struct device *dev, enum hwmon_sensor_types type,
			 u32 attr, int channel, long val)
{
	struct adm1177_state *st = dev_get_drvdata(dev);

	switch (type) {
	case hwmon_curr:
		switch (attr) {
		case hwmon_curr_max:
			val = clamp_val(val, 0,
					div_u64(105840000ULL, st->r_sense_uohm));
			return adm1177_write_alert_thr(st, (u64)val * 1000);
		default:
			return -EOPNOTSUPP;
		}
	default:
		return -EOPNOTSUPP;
	}
}

static umode_t adm1177_is_visible(const void *data,
				  enum hwmon_sensor_types type,
				  u32 attr, int channel)
{
	const struct adm1177_state *st = data;

	switch (type) {
	case hwmon_in:
		switch (attr) {
		case hwmon_in_input:
			return 0444;
		}
		break;
	case hwmon_curr:
		switch (attr) {
		case hwmon_curr_input:
			if (st->r_sense_uohm)
				return 0444;
			return 0;
		case hwmon_curr_max:
			if (st->r_sense_uohm)
				return 0644;
			return 0;
		}
		break;
	default:
		break;
	}
	return 0;
}

static const struct hwmon_channel_info * const adm1177_info[] = {
	HWMON_CHANNEL_INFO(curr,
			   HWMON_C_INPUT | HWMON_C_MAX),
	HWMON_CHANNEL_INFO(in,
			   HWMON_I_INPUT),
	NULL
};

static const struct hwmon_ops adm1177_hwmon_ops = {
	.is_visible = adm1177_is_visible,
	.read = adm1177_read,
	.write = adm1177_write,
};

static const struct hwmon_chip_info adm1177_chip_info = {
	.ops = &adm1177_hwmon_ops,
	.info = adm1177_info,
};

static int adm1177_probe(struct i2c_client *client)
{
	struct device *dev = &client->dev;
	struct device *hwmon_dev;
	struct adm1177_state *st;
	u64 alert_threshold_ua;
	u32 prop;
	int ret;

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

	st->client = client;

	ret = devm_regulator_get_enable_optional(&client->dev, "vref");
	if (ret == -EPROBE_DEFER)
		return -EPROBE_DEFER;

	if (device_property_read_u32(dev, "shunt-resistor-micro-ohms",
				     &st->r_sense_uohm))
		st->r_sense_uohm = 0;
	if (!device_property_read_u32(dev, "adi,shutdown-threshold-microamp",
				      &prop)) {
		alert_threshold_ua = prop;
	} else if (st->r_sense_uohm) {
		/*
		 * set maximum default value from datasheet based on
		 * shunt-resistor
		 */
		alert_threshold_ua = div_u64(105840000000ULL,
					     st->r_sense_uohm);
	} else {
		alert_threshold_ua = 0;
	}
	st->vrange_high = device_property_read_bool(dev,
						    "adi,vrange-high-enable");
	if (alert_threshold_ua && st->r_sense_uohm) {
		ret = adm1177_write_alert_thr(st, alert_threshold_ua);
		if (ret)
			return ret;
	}

	ret = adm1177_write_cmd(st, ADM1177_CMD_V_CONT |
				    ADM1177_CMD_I_CONT |
				    (st->vrange_high ? 0 : ADM1177_CMD_VRANGE));
	if (ret)
		return ret;

	hwmon_dev =
		devm_hwmon_device_register_with_info(dev, client->name, st,
						     &adm1177_chip_info, NULL);
	return PTR_ERR_OR_ZERO(hwmon_dev);
}

static const struct i2c_device_id adm1177_id[] = {
	{"adm1177"},
	{}
};
MODULE_DEVICE_TABLE(i2c, adm1177_id);

static const struct of_device_id adm1177_dt_ids[] = {
	{ .compatible = "adi,adm1177" },
	{},
};
MODULE_DEVICE_TABLE(of, adm1177_dt_ids);

static struct i2c_driver adm1177_driver = {
	.driver = {
		.name = "adm1177",
		.of_match_table = adm1177_dt_ids,
	},
	.probe = adm1177_probe,
	.id_table = adm1177_id,
};
module_i2c_driver(adm1177_driver);

MODULE_AUTHOR("Beniamin Bia <beniamin.bia@analog.com>");
MODULE_AUTHOR("Michael Hennerich <michael.hennerich@analog.com>");
MODULE_DESCRIPTION("Analog Devices ADM1177 ADC driver");
MODULE_LICENSE("GPL v2");
