Skip to content

Commit db95f01

Browse files
Generalize temperature and fan channels
This is in preparation for new devices. On the other hand, the code is now more fragile (even if cleaner), since there a few different lists, arrays and counts can get out of sync.
1 parent ec48e37 commit db95f01

File tree

1 file changed

+63
-46
lines changed

1 file changed

+63
-46
lines changed

liquidctl.c

Lines changed: 63 additions & 46 deletions
Original file line numberDiff line numberDiff line change
@@ -15,13 +15,16 @@
1515
#define DRVNAME "liquidctl" /* FIXME for upstream (hid x usb, hwmon x other) */
1616
#define DEVNAME_KRAKEN_GEN3 "kraken" /* FIXME not descriptive for user-space */
1717

18-
/* FIXME generalize temp and fan data */
1918
struct liquidctl_device_data {
2019
struct hid_device *hid_dev;
2120
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;
2528
};
2629

2730
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,
3841

3942
switch (type) {
4043
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)
4645
return -EINVAL;
47-
}
46+
*val = ldata->temp_in[channel];
4847
break;
4948
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)
6450
return -EINVAL;
65-
}
51+
*val = ldata->fan_in[channel];
6652
break;
6753
default:
6854
return -EINVAL;
@@ -74,50 +60,59 @@ static int liquidctl_read_string(struct device *dev,
7460
enum hwmon_sensor_types type, u32 attr,
7561
int channel, const char **str)
7662
{
63+
struct liquidctl_device_data *ldata = dev_get_drvdata(dev);
64+
7765
switch (type) {
7866
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])
8469
return -EINVAL;
85-
}
70+
*str = ldata->temp_label[channel];
8671
break;
8772
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])
9375
return -EINVAL;
94-
}
76+
*str = ldata->fan_label[channel];
9577
break;
9678
default:
9779
return -EINVAL;
9880
}
9981
return 0;
10082
}
10183

84+
# define KRAKEN_TEMP_COUNT 1
85+
86+
static const char *const kraken_temp_label[] = {
87+
"Coolant",
88+
};
89+
10290
static const u32 liquidctl_temp_config[] = {
10391
HWMON_T_INPUT | HWMON_T_LABEL,
10492
0
10593
};
10694

107-
static const u32 liquidctl_fan_config[] = {
95+
# define KRAKEN_FAN_COUNT 2
96+
97+
static const u32 kraken_fan_config[] = {
10898
HWMON_F_INPUT,
10999
HWMON_F_INPUT | HWMON_F_LABEL,
110100
0
111101
};
112102

103+
static const char *const kraken_fan_label[] = {
104+
NULL,
105+
"Pump",
106+
};
107+
113108
static const struct hwmon_channel_info liquidctl_temp = {
114109
.type = hwmon_temp,
115110
.config = liquidctl_temp_config,
116111
};
117112

118-
static const struct hwmon_channel_info liquidctl_fan = {
113+
static const struct hwmon_channel_info kraken_fan = {
119114
.type = hwmon_fan,
120-
.config = liquidctl_fan_config,
115+
.config = kraken_fan_config,
121116
};
122117

123118
static const struct hwmon_ops liquidctl_hwmon_ops = {
@@ -128,7 +123,7 @@ static const struct hwmon_ops liquidctl_hwmon_ops = {
128123

129124
static const struct hwmon_channel_info *kraken_info[] = {
130125
&liquidctl_temp,
131-
&liquidctl_fan,
126+
&kraken_fan,
132127
NULL
133128
};
134129

@@ -147,15 +142,19 @@ static int liquidctl_raw_event(struct hid_device *hdev,
147142
/* print_hex_dump(KERN_DEBUG, DRVNAME, DUMP_PREFIX_OFFSET, 16, 4, data, */
148143
/* size, false); */
149144

145+
/* FIXME correctly check this is the report we want */
150146
if (size < 32) {
151147
hid_err(hdev, "message too short: %d\n", size);
152148
return -EINVAL;
153149
}
154150

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);
159158
return 0;
160159
}
161160

@@ -179,7 +178,25 @@ static int liquidctl_probe(struct hid_device *hdev,
179178
if (!ldata)
180179
return -ENOMEM;
181180

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+
183200
ldata->hid_dev = hdev;
184201
hid_set_drvdata(hdev, ldata);
185202

0 commit comments

Comments
 (0)