.. | .. |
---|
30 | 30 | * @mlxreg_io_dev_attr: sysfs sensor device attribute array; |
---|
31 | 31 | * @group: sysfs attribute group; |
---|
32 | 32 | * @groups: list of sysfs attribute group for hwmon registration; |
---|
| 33 | + * @regsize: size of a register value; |
---|
33 | 34 | */ |
---|
34 | 35 | struct mlxreg_io_priv_data { |
---|
35 | 36 | struct platform_device *pdev; |
---|
.. | .. |
---|
39 | 40 | struct sensor_device_attribute mlxreg_io_dev_attr[MLXREG_IO_ATT_NUM]; |
---|
40 | 41 | struct attribute_group group; |
---|
41 | 42 | const struct attribute_group *groups[2]; |
---|
| 43 | + int regsize; |
---|
42 | 44 | }; |
---|
43 | 45 | |
---|
44 | 46 | static int |
---|
45 | 47 | mlxreg_io_get_reg(void *regmap, struct mlxreg_core_data *data, u32 in_val, |
---|
46 | | - bool rw_flag, u32 *regval) |
---|
| 48 | + bool rw_flag, int regsize, u32 *regval) |
---|
47 | 49 | { |
---|
48 | | - int ret; |
---|
| 50 | + int i, val, ret; |
---|
49 | 51 | |
---|
50 | 52 | ret = regmap_read(regmap, data->reg, regval); |
---|
51 | 53 | if (ret) |
---|
52 | 54 | goto access_error; |
---|
53 | 55 | |
---|
54 | 56 | /* |
---|
55 | | - * There are three kinds of attributes: single bit, full register's |
---|
56 | | - * bits and bit sequence. For the first kind field mask indicates which |
---|
57 | | - * bits are not related and field bit is set zero. For the second kind |
---|
58 | | - * field mask is set to zero and field bit is set with all bits one. |
---|
59 | | - * No special handling for such kind of attributes - pass value as is. |
---|
60 | | - * For the third kind, field mask indicates which bits are related and |
---|
61 | | - * field bit is set to the first bit number (from 1 to 32) is the bit |
---|
62 | | - * sequence. |
---|
| 57 | + * There are four kinds of attributes: single bit, full register's |
---|
| 58 | + * bits, bit sequence, bits in few registers For the first kind field |
---|
| 59 | + * mask indicates which bits are not related and field bit is set zero. |
---|
| 60 | + * For the second kind field mask is set to zero and field bit is set |
---|
| 61 | + * with all bits one. No special handling for such kind of attributes - |
---|
| 62 | + * pass value as is. For the third kind, the field mask indicates which |
---|
| 63 | + * bits are related and the field bit is set to the first bit number |
---|
| 64 | + * (from 1 to 32) is the bit sequence. For the fourth kind - the number |
---|
| 65 | + * of registers which should be read for getting an attribute are |
---|
| 66 | + * specified through 'data->regnum' field. |
---|
63 | 67 | */ |
---|
64 | 68 | if (!data->bit) { |
---|
65 | 69 | /* Single bit. */ |
---|
.. | .. |
---|
83 | 87 | /* Clear relevant bits and set them to new value. */ |
---|
84 | 88 | *regval = (*regval & ~data->mask) | in_val; |
---|
85 | 89 | } |
---|
| 90 | + } else { |
---|
| 91 | + /* |
---|
| 92 | + * Some attributes could occupied few registers in case regmap |
---|
| 93 | + * bit size is 8 or 16. Compose such attributes from 'regnum' |
---|
| 94 | + * registers. Such attributes contain read-only data. |
---|
| 95 | + */ |
---|
| 96 | + for (i = 1; i < data->regnum; i++) { |
---|
| 97 | + ret = regmap_read(regmap, data->reg + i, &val); |
---|
| 98 | + if (ret) |
---|
| 99 | + goto access_error; |
---|
| 100 | + |
---|
| 101 | + *regval |= rol32(val, regsize * i * 8); |
---|
| 102 | + } |
---|
86 | 103 | } |
---|
87 | 104 | |
---|
88 | 105 | access_error: |
---|
.. | .. |
---|
99 | 116 | u32 regval = 0; |
---|
100 | 117 | int ret; |
---|
101 | 118 | |
---|
102 | | - ret = mlxreg_io_get_reg(priv->pdata->regmap, data, 0, true, ®val); |
---|
| 119 | + ret = mlxreg_io_get_reg(priv->pdata->regmap, data, 0, true, |
---|
| 120 | + priv->regsize, ®val); |
---|
103 | 121 | if (ret) |
---|
104 | 122 | goto access_error; |
---|
105 | 123 | |
---|
.. | .. |
---|
128 | 146 | return ret; |
---|
129 | 147 | |
---|
130 | 148 | ret = mlxreg_io_get_reg(priv->pdata->regmap, data, input_val, false, |
---|
131 | | - ®val); |
---|
| 149 | + priv->regsize, ®val); |
---|
132 | 150 | if (ret) |
---|
133 | 151 | goto access_error; |
---|
134 | 152 | |
---|
.. | .. |
---|
207 | 225 | } |
---|
208 | 226 | |
---|
209 | 227 | priv->pdev = pdev; |
---|
| 228 | + priv->regsize = regmap_get_val_bytes(priv->pdata->regmap); |
---|
| 229 | + if (priv->regsize < 0) |
---|
| 230 | + return priv->regsize; |
---|
210 | 231 | |
---|
211 | 232 | err = mlxreg_io_attr_init(priv); |
---|
212 | 233 | if (err) { |
---|