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,27 +40,30 @@ struct mlxreg_io_priv_data {
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,6 +87,19 @@ mlxreg_io_get_reg(void *regmap, struct mlxreg_core_data *data, u32 in_val,
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 );
102
+ }
86
103
}
87
104
88
105
access_error :
@@ -99,7 +116,8 @@ mlxreg_io_attr_show(struct device *dev, struct device_attribute *attr,
99
116
u32 regval = 0 ;
100
117
int ret ;
101
118
102
- ret = mlxreg_io_get_reg (priv -> pdata -> regmap , data , 0 , true, & regval );
119
+ ret = mlxreg_io_get_reg (priv -> pdata -> regmap , data , 0 , true,
120
+ priv -> regsize , & regval );
103
121
if (ret )
104
122
goto access_error ;
105
123
@@ -128,7 +146,7 @@ mlxreg_io_attr_store(struct device *dev, struct device_attribute *attr,
128
146
return ret ;
129
147
130
148
ret = mlxreg_io_get_reg (priv -> pdata -> regmap , data , input_val , false,
131
- & regval );
149
+ priv -> regsize , & regval );
132
150
if (ret )
133
151
goto access_error ;
134
152
@@ -207,6 +225,9 @@ static int mlxreg_io_probe(struct platform_device *pdev)
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 ) {
0 commit comments