// SPDX-License-Identifier: GPL-2.0+
/*
 * Mellanox register access driver
 *
 * Copyright (C) 2018 Mellanox Technologies
 * Copyright (C) 2018 Vadim Pasternak <vadimp@mellanox.com>
 */

#include <linux/bitops.h>
#include <linux/device.h>
#include <linux/hwmon.h>
#include <linux/hwmon-sysfs.h>
#include <linux/module.h>
#include <linux/of_device.h>
#include <linux/platform_data/mlxreg.h>
#include <linux/platform_device.h>
#include <linux/regmap.h>

/* Attribute parameters. */
#define MLXREG_IO_ATT_SIZE	10
#define MLXREG_IO_ATT_NUM	48

/**
 * struct mlxreg_io_priv_data - driver's private data:
 *
 * @pdev: platform device;
 * @pdata: platform data;
 * @hwmon: hwmon device;
 * @mlxreg_io_attr: sysfs attributes array;
 * @mlxreg_io_dev_attr: sysfs sensor device attribute array;
 * @group: sysfs attribute group;
 * @groups: list of sysfs attribute group for hwmon registration;
 * @regsize: size of a register value;
 */
struct mlxreg_io_priv_data {
	struct platform_device *pdev;
	struct mlxreg_core_platform_data *pdata;
	struct device *hwmon;
	struct attribute *mlxreg_io_attr[MLXREG_IO_ATT_NUM + 1];
	struct sensor_device_attribute mlxreg_io_dev_attr[MLXREG_IO_ATT_NUM];
	struct attribute_group group;
	const struct attribute_group *groups[2];
	int regsize;
};

static int
mlxreg_io_get_reg(void *regmap, struct mlxreg_core_data *data, u32 in_val,
		  bool rw_flag, int regsize, u32 *regval)
{
	int i, val, ret;

	ret = regmap_read(regmap, data->reg, regval);
	if (ret)
		goto access_error;

	/*
	 * There are four kinds of attributes: single bit, full register's
	 * bits, bit sequence, bits in few registers For the first kind field
	 * mask indicates which bits are not related and field bit is set zero.
	 * For the second kind field mask is set to zero and field bit is set
	 * with all bits one. No special handling for such kind of attributes -
	 * pass value as is. For the third kind, the field mask indicates which
	 * bits are related and the field bit is set to the first bit number
	 * (from 1 to 32) is the bit sequence. For the fourth kind - the number
	 * of registers which should be read for getting an attribute are
	 * specified through 'data->regnum' field.
	 */
	if (!data->bit) {
		/* Single bit. */
		if (rw_flag) {
			/* For show: expose effective bit value as 0 or 1. */
			*regval = !!(*regval & ~data->mask);
		} else {
			/* For store: set effective bit value. */
			*regval &= data->mask;
			if (in_val)
				*regval |= ~data->mask;
		}
	} else if (data->mask) {
		/* Bit sequence. */
		if (rw_flag) {
			/* For show: mask and shift right. */
			*regval = ror32(*regval & data->mask, (data->bit - 1));
		} else {
			/* For store: shift to the position and mask. */
			in_val = rol32(in_val, data->bit - 1) & data->mask;
			/* Clear relevant bits and set them to new value. */
			*regval = (*regval & ~data->mask) | in_val;
		}
	} else {
		/*
		 * Some attributes could occupied few registers in case regmap
		 * bit size is 8 or 16. Compose such attributes from 'regnum'
		 * registers. Such attributes contain read-only data.
		 */
		for (i = 1; i < data->regnum; i++) {
			ret = regmap_read(regmap, data->reg + i, &val);
			if (ret)
				goto access_error;

			*regval |= rol32(val, regsize * i);
		}
	}

access_error:
	return ret;
}

static ssize_t
mlxreg_io_attr_show(struct device *dev, struct device_attribute *attr,
		    char *buf)
{
	struct mlxreg_io_priv_data *priv = dev_get_drvdata(dev);
	int index = to_sensor_dev_attr(attr)->index;
	struct mlxreg_core_data *data = priv->pdata->data + index;
	u32 regval = 0;
	int ret;

	ret = mlxreg_io_get_reg(priv->pdata->regmap, data, 0, true,
				priv->regsize, &regval);
	if (ret)
		goto access_error;

	return sprintf(buf, "%u\n", regval);

access_error:
	return ret;
}

static ssize_t
mlxreg_io_attr_store(struct device *dev, struct device_attribute *attr,
		     const char *buf, size_t len)
{
	struct mlxreg_io_priv_data *priv = dev_get_drvdata(dev);
	int index = to_sensor_dev_attr(attr)->index;
	struct mlxreg_core_data *data = priv->pdata->data + index;
	u32 input_val, regval;
	int ret;

	if (len > MLXREG_IO_ATT_SIZE)
		return -EINVAL;

	/* Convert buffer to input value. */
	ret = kstrtou32(buf, len, &input_val);
	if (ret)
		return ret;

	ret = mlxreg_io_get_reg(priv->pdata->regmap, data, input_val, false,
				priv->regsize, &regval);
	if (ret)
		goto access_error;

	ret = regmap_write(priv->pdata->regmap, data->reg, regval);
	if (ret)
		goto access_error;

	return len;

access_error:
	dev_err(&priv->pdev->dev, "Bus access error\n");
	return ret;
}

static struct device_attribute mlxreg_io_devattr_rw = {
	.show	= mlxreg_io_attr_show,
	.store	= mlxreg_io_attr_store,
};

static int mlxreg_io_attr_init(struct mlxreg_io_priv_data *priv)
{
	int i;

	priv->group.attrs = devm_kcalloc(&priv->pdev->dev,
					 priv->pdata->counter,
					 sizeof(struct attribute *),
					 GFP_KERNEL);
	if (!priv->group.attrs)
		return -ENOMEM;

	for (i = 0; i < priv->pdata->counter; i++) {
		priv->mlxreg_io_attr[i] =
				&priv->mlxreg_io_dev_attr[i].dev_attr.attr;
		memcpy(&priv->mlxreg_io_dev_attr[i].dev_attr,
		       &mlxreg_io_devattr_rw, sizeof(struct device_attribute));

		/* Set attribute name as a label. */
		priv->mlxreg_io_attr[i]->name =
				devm_kasprintf(&priv->pdev->dev, GFP_KERNEL,
					       priv->pdata->data[i].label);

		if (!priv->mlxreg_io_attr[i]->name) {
			dev_err(&priv->pdev->dev, "Memory allocation failed for sysfs attribute %d.\n",
				i + 1);
			return -ENOMEM;
		}

		priv->mlxreg_io_dev_attr[i].dev_attr.attr.mode =
						priv->pdata->data[i].mode;
		priv->mlxreg_io_dev_attr[i].dev_attr.attr.name =
					priv->mlxreg_io_attr[i]->name;
		priv->mlxreg_io_dev_attr[i].index = i;
		sysfs_attr_init(&priv->mlxreg_io_dev_attr[i].dev_attr.attr);
	}

	priv->group.attrs = priv->mlxreg_io_attr;
	priv->groups[0] = &priv->group;
	priv->groups[1] = NULL;

	return 0;
}

static int mlxreg_io_probe(struct platform_device *pdev)
{
	struct mlxreg_io_priv_data *priv;
	int err;

	priv = devm_kzalloc(&pdev->dev, sizeof(*priv), GFP_KERNEL);
	if (!priv)
		return -ENOMEM;

	priv->pdata = dev_get_platdata(&pdev->dev);
	if (!priv->pdata) {
		dev_err(&pdev->dev, "Failed to get platform data.\n");
		return -EINVAL;
	}

	priv->pdev = pdev;
	priv->regsize = regmap_get_val_bytes(priv->pdata->regmap);
	if (priv->regsize < 0)
		return priv->regsize;

	err = mlxreg_io_attr_init(priv);
	if (err) {
		dev_err(&priv->pdev->dev, "Failed to allocate attributes: %d\n",
			err);
		return err;
	}

	priv->hwmon = devm_hwmon_device_register_with_groups(&pdev->dev,
							     "mlxreg_io",
							      priv,
							      priv->groups);
	if (IS_ERR(priv->hwmon)) {
		dev_err(&pdev->dev, "Failed to register hwmon device %ld\n",
			PTR_ERR(priv->hwmon));
		return PTR_ERR(priv->hwmon);
	}

	dev_set_drvdata(&pdev->dev, priv);

	return 0;
}

static struct platform_driver mlxreg_io_driver = {
	.driver = {
	    .name = "mlxreg-io",
	},
	.probe = mlxreg_io_probe,
};

module_platform_driver(mlxreg_io_driver);

MODULE_AUTHOR("Vadim Pasternak <vadimp@mellanox.com>");
MODULE_DESCRIPTION("Mellanox regmap I/O access driver");
MODULE_LICENSE("GPL");
MODULE_ALIAS("platform:mlxreg-io");
