Commit 86148190 authored by Vadim Pasternak's avatar Vadim Pasternak Committed by Andy Shevchenko

platform/mellanox: mlxreg-io: Add support for complex attributes

Add support for attributes composed from few registers.
Such attributes could occupy from 2 to 4 sequential registers.
For word size register space complex attributes can occupy up to two
registers, for byte size - up to four. These attributes can carry, for
example, CPLD or FPGA versioning, power consuming info, etcetera.
Such registers contain read-only data.
Signed-off-by: default avatarVadim Pasternak <vadimp@mellanox.com>
Signed-off-by: default avatarAndy Shevchenko <andriy.shevchenko@linux.intel.com>
parent ae1aabf4
...@@ -30,6 +30,7 @@ ...@@ -30,6 +30,7 @@
* @mlxreg_io_dev_attr: sysfs sensor device attribute array; * @mlxreg_io_dev_attr: sysfs sensor device attribute array;
* @group: sysfs attribute group; * @group: sysfs attribute group;
* @groups: list of sysfs attribute group for hwmon registration; * @groups: list of sysfs attribute group for hwmon registration;
* @regsize: size of a register value;
*/ */
struct mlxreg_io_priv_data { struct mlxreg_io_priv_data {
struct platform_device *pdev; struct platform_device *pdev;
...@@ -39,27 +40,30 @@ struct mlxreg_io_priv_data { ...@@ -39,27 +40,30 @@ struct mlxreg_io_priv_data {
struct sensor_device_attribute mlxreg_io_dev_attr[MLXREG_IO_ATT_NUM]; struct sensor_device_attribute mlxreg_io_dev_attr[MLXREG_IO_ATT_NUM];
struct attribute_group group; struct attribute_group group;
const struct attribute_group *groups[2]; const struct attribute_group *groups[2];
int regsize;
}; };
static int static int
mlxreg_io_get_reg(void *regmap, struct mlxreg_core_data *data, u32 in_val, mlxreg_io_get_reg(void *regmap, struct mlxreg_core_data *data, u32 in_val,
bool rw_flag, u32 *regval) bool rw_flag, int regsize, u32 *regval)
{ {
int ret; int i, val, ret;
ret = regmap_read(regmap, data->reg, regval); ret = regmap_read(regmap, data->reg, regval);
if (ret) if (ret)
goto access_error; goto access_error;
/* /*
* There are three kinds of attributes: single bit, full register's * There are four kinds of attributes: single bit, full register's
* bits and bit sequence. For the first kind field mask indicates which * bits, bit sequence, bits in few registers For the first kind field
* bits are not related and field bit is set zero. For the second kind * mask indicates which bits are not related and field bit is set zero.
* field mask is set to zero and field bit is set with all bits one. * For the second kind field mask is set to zero and field bit is set
* No special handling for such kind of attributes - pass value as is. * with all bits one. No special handling for such kind of attributes -
* For the third kind, field mask indicates which bits are related and * pass value as is. For the third kind, the field mask indicates which
* field bit is set to the first bit number (from 1 to 32) is the bit * bits are related and the field bit is set to the first bit number
* sequence. * (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) { if (!data->bit) {
/* Single bit. */ /* Single bit. */
...@@ -83,6 +87,19 @@ mlxreg_io_get_reg(void *regmap, struct mlxreg_core_data *data, u32 in_val, ...@@ -83,6 +87,19 @@ mlxreg_io_get_reg(void *regmap, struct mlxreg_core_data *data, u32 in_val,
/* Clear relevant bits and set them to new value. */ /* Clear relevant bits and set them to new value. */
*regval = (*regval & ~data->mask) | in_val; *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: access_error:
...@@ -99,7 +116,8 @@ mlxreg_io_attr_show(struct device *dev, struct device_attribute *attr, ...@@ -99,7 +116,8 @@ mlxreg_io_attr_show(struct device *dev, struct device_attribute *attr,
u32 regval = 0; u32 regval = 0;
int ret; int ret;
ret = mlxreg_io_get_reg(priv->pdata->regmap, data, 0, true, &regval); ret = mlxreg_io_get_reg(priv->pdata->regmap, data, 0, true,
priv->regsize, &regval);
if (ret) if (ret)
goto access_error; goto access_error;
...@@ -128,7 +146,7 @@ mlxreg_io_attr_store(struct device *dev, struct device_attribute *attr, ...@@ -128,7 +146,7 @@ mlxreg_io_attr_store(struct device *dev, struct device_attribute *attr,
return ret; return ret;
ret = mlxreg_io_get_reg(priv->pdata->regmap, data, input_val, false, ret = mlxreg_io_get_reg(priv->pdata->regmap, data, input_val, false,
&regval); priv->regsize, &regval);
if (ret) if (ret)
goto access_error; goto access_error;
...@@ -207,6 +225,9 @@ static int mlxreg_io_probe(struct platform_device *pdev) ...@@ -207,6 +225,9 @@ static int mlxreg_io_probe(struct platform_device *pdev)
} }
priv->pdev = pdev; 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); err = mlxreg_io_attr_init(priv);
if (err) { if (err) {
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment