// 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/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
 * @reg:		regulator info for the power supply of the device
 * @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;
	struct regulator	*reg;
	u32			r_sense_uohm;
	u32			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,
				   u32 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_alarm:
			*val = st->alert_threshold_ua;
			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_alarm:
			adm1177_write_alert_thr(st, val);
			return 0;
		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_alarm:
			if (st->r_sense_uohm)
				return 0644;
			return 0;
		}
		break;
	default:
		break;
	}
	return 0;
}

static const struct hwmon_channel_info *adm1177_info[] = {
	HWMON_CHANNEL_INFO(curr,
			   HWMON_C_INPUT | HWMON_C_MAX_ALARM),
	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 void adm1177_remove(void *data)
{
	struct adm1177_state *st = data;

	regulator_disable(st->reg);
}

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

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

	st->client = client;

	st->reg = devm_regulator_get_optional(&client->dev, "vref");
	if (IS_ERR(st->reg)) {
		if (PTR_ERR(st->reg) == -EPROBE_DEFER)
			return -EPROBE_DEFER;

		st->reg = NULL;
	} else {
		ret = regulator_enable(st->reg);
		if (ret)
			return ret;
		ret = devm_add_action_or_reset(&client->dev, adm1177_remove,
					       st);
		if (ret)
			return ret;
	}

	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",
				     &alert_threshold_ua)) {
		if (st->r_sense_uohm)
			/*
			 * set maximum default value from datasheet based on
			 * shunt-resistor
			 */
			alert_threshold_ua = div_u64(105840000000,
						     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)
		adm1177_write_alert_thr(st, alert_threshold_ua);

	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", 0},
	{}
};
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 = {
	.class = I2C_CLASS_HWMON,
	.driver = {
		.name = "adm1177",
		.of_match_table = adm1177_dt_ids,
	},
	.probe_new = 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");
