15
15
#define DRVNAME "liquidctl" /* FIXME for upstream (hid x usb, hwmon x other) */
16
16
#define DEVNAME_KRAKEN_GEN3 "kraken" /* FIXME not descriptive for user-space */
17
17
18
- /* FIXME generalize temp and fan data */
19
18
struct liquidctl_device_data {
20
19
struct hid_device * hid_dev ;
21
20
struct device * hwmon_dev ;
22
- long temp1 ;
23
- long fan1 ;
24
- long fan2 ;
21
+
22
+ int temp_count ;
23
+ int fan_count ;
24
+ const char * const * temp_label ;
25
+ const char * const * fan_label ;
26
+ long * temp_in ;
27
+ long * fan_in ;
25
28
};
26
29
27
30
static umode_t liquidctl_is_visible (const void * data ,
@@ -38,31 +41,14 @@ static int liquidctl_read(struct device *dev, enum hwmon_sensor_types type,
38
41
39
42
switch (type ) {
40
43
case hwmon_temp :
41
- switch (attr ) {
42
- case hwmon_temp_input :
43
- * val = ldata -> temp1 ;
44
- break ;
45
- default :
44
+ if (attr != hwmon_temp_input || channel >= ldata -> temp_count )
46
45
return - EINVAL ;
47
- }
46
+ * val = ldata -> temp_in [ channel ];
48
47
break ;
49
48
case hwmon_fan :
50
- switch (attr ) {
51
- case hwmon_fan_input :
52
- switch (channel ) {
53
- case 0 :
54
- * val = ldata -> fan1 ;
55
- break ;
56
- case 1 :
57
- * val = ldata -> fan2 ;
58
- break ;
59
- default :
60
- return - EINVAL ;
61
- }
62
- break ;
63
- default :
49
+ if (attr != hwmon_fan_input || channel >= ldata -> fan_count )
64
50
return - EINVAL ;
65
- }
51
+ * val = ldata -> fan_in [ channel ];
66
52
break ;
67
53
default :
68
54
return - EINVAL ;
@@ -74,50 +60,59 @@ static int liquidctl_read_string(struct device *dev,
74
60
enum hwmon_sensor_types type , u32 attr ,
75
61
int channel , const char * * str )
76
62
{
63
+ struct liquidctl_device_data * ldata = dev_get_drvdata (dev );
64
+
77
65
switch (type ) {
78
66
case hwmon_temp :
79
- switch (attr ) {
80
- case hwmon_temp_label :
81
- * str = "Coolant" ;
82
- break ;
83
- default :
67
+ if (attr != hwmon_temp_label || channel >= ldata -> temp_count ||
68
+ !ldata -> temp_label [channel ])
84
69
return - EINVAL ;
85
- }
70
+ * str = ldata -> temp_label [ channel ];
86
71
break ;
87
72
case hwmon_fan :
88
- switch (attr ) {
89
- case hwmon_fan_label :
90
- * str = "Pump" ;
91
- break ;
92
- default :
73
+ if (attr != hwmon_fan_label || channel >= ldata -> fan_count ||
74
+ !ldata -> fan_label [channel ])
93
75
return - EINVAL ;
94
- }
76
+ * str = ldata -> fan_label [ channel ];
95
77
break ;
96
78
default :
97
79
return - EINVAL ;
98
80
}
99
81
return 0 ;
100
82
}
101
83
84
+ # define KRAKEN_TEMP_COUNT 1
85
+
86
+ static const char * const kraken_temp_label [] = {
87
+ "Coolant" ,
88
+ };
89
+
102
90
static const u32 liquidctl_temp_config [] = {
103
91
HWMON_T_INPUT | HWMON_T_LABEL ,
104
92
0
105
93
};
106
94
107
- static const u32 liquidctl_fan_config [] = {
95
+ # define KRAKEN_FAN_COUNT 2
96
+
97
+ static const u32 kraken_fan_config [] = {
108
98
HWMON_F_INPUT ,
109
99
HWMON_F_INPUT | HWMON_F_LABEL ,
110
100
0
111
101
};
112
102
103
+ static const char * const kraken_fan_label [] = {
104
+ NULL ,
105
+ "Pump" ,
106
+ };
107
+
113
108
static const struct hwmon_channel_info liquidctl_temp = {
114
109
.type = hwmon_temp ,
115
110
.config = liquidctl_temp_config ,
116
111
};
117
112
118
- static const struct hwmon_channel_info liquidctl_fan = {
113
+ static const struct hwmon_channel_info kraken_fan = {
119
114
.type = hwmon_fan ,
120
- .config = liquidctl_fan_config ,
115
+ .config = kraken_fan_config ,
121
116
};
122
117
123
118
static const struct hwmon_ops liquidctl_hwmon_ops = {
@@ -128,7 +123,7 @@ static const struct hwmon_ops liquidctl_hwmon_ops = {
128
123
129
124
static const struct hwmon_channel_info * kraken_info [] = {
130
125
& liquidctl_temp ,
131
- & liquidctl_fan ,
126
+ & kraken_fan ,
132
127
NULL
133
128
};
134
129
@@ -147,15 +142,19 @@ static int liquidctl_raw_event(struct hid_device *hdev,
147
142
/* print_hex_dump(KERN_DEBUG, DRVNAME, DUMP_PREFIX_OFFSET, 16, 4, data, */
148
143
/* size, false); */
149
144
145
+ /* FIXME correctly check this is the report we want */
150
146
if (size < 32 ) {
151
147
hid_err (hdev , "message too short: %d\n" , size );
152
148
return - EINVAL ;
153
149
}
154
150
155
- /* FIXME add lock */
156
- ldata -> temp1 = data [1 ] * 1000 + data [2 ] * 100 ;
157
- ldata -> fan1 = be16_to_cpup ((__be16 * )(data + 3 ));
158
- ldata -> fan2 = be16_to_cpup ((__be16 * )(data + 5 ));
151
+ /* TODO do we need a lock, is long store atomic on *all* platforms? */
152
+ do {
153
+ /* TODO new devices */
154
+ ldata -> temp_in [0 ] = data [1 ] * 1000 + data [2 ] * 100 ;
155
+ ldata -> fan_in [0 ] = be16_to_cpup ((__be16 * )(data + 3 ));
156
+ ldata -> fan_in [1 ] = be16_to_cpup ((__be16 * )(data + 5 ));
157
+ } while (false);
159
158
return 0 ;
160
159
}
161
160
@@ -179,7 +178,25 @@ static int liquidctl_probe(struct hid_device *hdev,
179
178
if (!ldata )
180
179
return - ENOMEM ;
181
180
182
- hid_info (hdev , "device: " DEVNAME_KRAKEN_GEN3 "\n" );
181
+ do {
182
+ /* TODO new devices */
183
+ hid_info (hdev , "device: " DEVNAME_KRAKEN_GEN3 "\n" );
184
+ ldata -> temp_count = KRAKEN_TEMP_COUNT ;
185
+ ldata -> fan_count = KRAKEN_FAN_COUNT ;
186
+ ldata -> temp_label = kraken_temp_label ;
187
+ ldata -> fan_label = kraken_fan_label ;
188
+ } while (false);
189
+
190
+ ldata -> temp_in = devm_kcalloc (& hdev -> dev , ldata -> temp_count ,
191
+ sizeof (* ldata -> temp_in ), GFP_KERNEL );
192
+ if (!ldata -> temp_in )
193
+ return - ENOMEM ;
194
+
195
+ ldata -> fan_in = devm_kcalloc (& hdev -> dev , ldata -> fan_count ,
196
+ sizeof (* ldata -> fan_in ), GFP_KERNEL );
197
+ if (!ldata -> fan_in )
198
+ return - ENOMEM ;
199
+
183
200
ldata -> hid_dev = hdev ;
184
201
hid_set_drvdata (hdev , ldata );
185
202
0 commit comments