// 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 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,
			 const struct i2c_device_id *id)
{
	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 = 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");
