1 // SPDX-License-Identifier: GPL-2.0+
2 /*
3  * hwmon driver for Aquacomputer devices (D5 Next, Farbwerk 360)
4  *
5  * Aquacomputer devices send HID reports (with ID 0x01) every second to report
6  * sensor values.
7  *
8  * Copyright 2021 Aleksa Savic <savicaleksa83@gmail.com>
9  */
10 
11 #include <linux/debugfs.h>
12 #include <linux/hid.h>
13 #include <linux/hwmon.h>
14 #include <linux/jiffies.h>
15 #include <linux/module.h>
16 #include <linux/seq_file.h>
17 #include <asm/unaligned.h>
18 
19 #define USB_VENDOR_ID_AQUACOMPUTER	0x0c70
20 #define USB_PRODUCT_ID_D5NEXT		0xf00e
21 #define USB_PRODUCT_ID_FARBWERK360	0xf010
22 
23 enum kinds { d5next, farbwerk360 };
24 
25 static const char *const aqc_device_names[] = {
26 	[d5next] = "d5next",
27 	[farbwerk360] = "farbwerk360"
28 };
29 
30 #define DRIVER_NAME			"aquacomputer_d5next"
31 
32 #define STATUS_REPORT_ID		0x01
33 #define STATUS_UPDATE_INTERVAL		(2 * HZ)	/* In seconds */
34 #define SERIAL_FIRST_PART		3
35 #define SERIAL_SECOND_PART		5
36 #define FIRMWARE_VERSION		13
37 
38 /* Register offsets for the D5 Next pump */
39 #define D5NEXT_POWER_CYCLES		24
40 
41 #define D5NEXT_COOLANT_TEMP		87
42 
43 #define D5NEXT_PUMP_SPEED		116
44 #define D5NEXT_FAN_SPEED		103
45 
46 #define D5NEXT_PUMP_POWER		114
47 #define D5NEXT_FAN_POWER		101
48 
49 #define D5NEXT_PUMP_VOLTAGE		110
50 #define D5NEXT_FAN_VOLTAGE		97
51 #define D5NEXT_5V_VOLTAGE		57
52 
53 #define D5NEXT_PUMP_CURRENT		112
54 #define D5NEXT_FAN_CURRENT		99
55 
56 /* Register offsets for the Farbwerk 360 RGB controller */
57 #define FARBWERK360_NUM_SENSORS		4
58 #define FARBWERK360_SENSOR_START		0x32
59 #define FARBWERK360_SENSOR_SIZE		0x02
60 #define FARBWERK360_SENSOR_DISCONNECTED	0x7FFF
61 
62 /* Labels for D5 Next */
63 #define L_D5NEXT_COOLANT_TEMP		"Coolant temp"
64 
65 static const char *const label_d5next_speeds[] = {
66 	"Pump speed",
67 	"Fan speed"
68 };
69 
70 static const char *const label_d5next_power[] = {
71 	"Pump power",
72 	"Fan power"
73 };
74 
75 static const char *const label_d5next_voltages[] = {
76 	"Pump voltage",
77 	"Fan voltage",
78 	"+5V voltage"
79 };
80 
81 static const char *const label_d5next_current[] = {
82 	"Pump current",
83 	"Fan current"
84 };
85 
86 /* Labels for Farbwerk 360 temperature sensors */
87 static const char *const label_temp_sensors[] = {
88 	"Sensor 1",
89 	"Sensor 2",
90 	"Sensor 3",
91 	"Sensor 4"
92 };
93 
94 struct aqc_data {
95 	struct hid_device *hdev;
96 	struct device *hwmon_dev;
97 	struct dentry *debugfs;
98 	enum kinds kind;
99 	const char *name;
100 
101 	/* General info, same across all devices */
102 	u32 serial_number[2];
103 	u16 firmware_version;
104 
105 	/* D5 Next specific - how many times the device was powered on */
106 	u32 power_cycles;
107 
108 	/* Sensor values */
109 	s32 temp_input[4];
110 	u16 speed_input[2];
111 	u32 power_input[2];
112 	u16 voltage_input[3];
113 	u16 current_input[2];
114 
115 	unsigned long updated;
116 };
117 
118 static umode_t aqc_is_visible(const void *data, enum hwmon_sensor_types type, u32 attr,
119 			      int channel)
120 {
121 	const struct aqc_data *priv = data;
122 
123 	switch (type) {
124 	case hwmon_temp:
125 		switch (priv->kind) {
126 		case d5next:
127 			if (channel == 0)
128 				return 0444;
129 			break;
130 		case farbwerk360:
131 			return 0444;
132 		default:
133 			break;
134 		}
135 		break;
136 	case hwmon_fan:
137 	case hwmon_power:
138 	case hwmon_in:
139 	case hwmon_curr:
140 		switch (priv->kind) {
141 		case d5next:
142 			return 0444;
143 		default:
144 			break;
145 		}
146 		break;
147 	default:
148 		break;
149 	}
150 
151 	return 0;
152 }
153 
154 static int aqc_read(struct device *dev, enum hwmon_sensor_types type, u32 attr,
155 		    int channel, long *val)
156 {
157 	struct aqc_data *priv = dev_get_drvdata(dev);
158 
159 	if (time_after(jiffies, priv->updated + STATUS_UPDATE_INTERVAL))
160 		return -ENODATA;
161 
162 	switch (type) {
163 	case hwmon_temp:
164 		if (priv->temp_input[channel] == -ENODATA)
165 			return -ENODATA;
166 
167 		*val = priv->temp_input[channel];
168 		break;
169 	case hwmon_fan:
170 		*val = priv->speed_input[channel];
171 		break;
172 	case hwmon_power:
173 		*val = priv->power_input[channel];
174 		break;
175 	case hwmon_in:
176 		*val = priv->voltage_input[channel];
177 		break;
178 	case hwmon_curr:
179 		*val = priv->current_input[channel];
180 		break;
181 	default:
182 		return -EOPNOTSUPP;
183 	}
184 
185 	return 0;
186 }
187 
188 static int aqc_read_string(struct device *dev, enum hwmon_sensor_types type, u32 attr,
189 			   int channel, const char **str)
190 {
191 	struct aqc_data *priv = dev_get_drvdata(dev);
192 
193 	switch (type) {
194 	case hwmon_temp:
195 		switch (priv->kind) {
196 		case d5next:
197 			*str = L_D5NEXT_COOLANT_TEMP;
198 			break;
199 		case farbwerk360:
200 			*str = label_temp_sensors[channel];
201 			break;
202 		default:
203 			break;
204 		}
205 		break;
206 	case hwmon_fan:
207 		switch (priv->kind) {
208 		case d5next:
209 			*str = label_d5next_speeds[channel];
210 			break;
211 		default:
212 			break;
213 		}
214 		break;
215 	case hwmon_power:
216 		switch (priv->kind) {
217 		case d5next:
218 			*str = label_d5next_power[channel];
219 			break;
220 		default:
221 			break;
222 		}
223 		break;
224 	case hwmon_in:
225 		switch (priv->kind) {
226 		case d5next:
227 			*str = label_d5next_voltages[channel];
228 			break;
229 		default:
230 			break;
231 		}
232 		break;
233 	case hwmon_curr:
234 		switch (priv->kind) {
235 		case d5next:
236 			*str = label_d5next_current[channel];
237 			break;
238 		default:
239 			break;
240 		}
241 		break;
242 	default:
243 		return -EOPNOTSUPP;
244 	}
245 
246 	return 0;
247 }
248 
249 static const struct hwmon_ops aqc_hwmon_ops = {
250 	.is_visible = aqc_is_visible,
251 	.read = aqc_read,
252 	.read_string = aqc_read_string,
253 };
254 
255 static const struct hwmon_channel_info *aqc_info[] = {
256 	HWMON_CHANNEL_INFO(temp,
257 			   HWMON_T_INPUT | HWMON_T_LABEL,
258 			   HWMON_T_INPUT | HWMON_T_LABEL,
259 			   HWMON_T_INPUT | HWMON_T_LABEL,
260 			   HWMON_T_INPUT | HWMON_T_LABEL),
261 	HWMON_CHANNEL_INFO(fan,
262 			   HWMON_F_INPUT | HWMON_F_LABEL,
263 			   HWMON_F_INPUT | HWMON_F_LABEL),
264 	HWMON_CHANNEL_INFO(power,
265 			   HWMON_P_INPUT | HWMON_P_LABEL,
266 			   HWMON_P_INPUT | HWMON_P_LABEL),
267 	HWMON_CHANNEL_INFO(in,
268 			   HWMON_I_INPUT | HWMON_I_LABEL,
269 			   HWMON_I_INPUT | HWMON_I_LABEL,
270 			   HWMON_I_INPUT | HWMON_I_LABEL),
271 	HWMON_CHANNEL_INFO(curr,
272 			   HWMON_C_INPUT | HWMON_C_LABEL,
273 			   HWMON_C_INPUT | HWMON_C_LABEL),
274 	NULL
275 };
276 
277 static const struct hwmon_chip_info aqc_chip_info = {
278 	.ops = &aqc_hwmon_ops,
279 	.info = aqc_info,
280 };
281 
282 static int aqc_raw_event(struct hid_device *hdev, struct hid_report *report, u8 *data,
283 			 int size)
284 {
285 	int i, sensor_value;
286 	struct aqc_data *priv;
287 
288 	if (report->id != STATUS_REPORT_ID)
289 		return 0;
290 
291 	priv = hid_get_drvdata(hdev);
292 
293 	/* Info provided with every report */
294 	priv->serial_number[0] = get_unaligned_be16(data + SERIAL_FIRST_PART);
295 	priv->serial_number[1] = get_unaligned_be16(data + SERIAL_SECOND_PART);
296 	priv->firmware_version = get_unaligned_be16(data + FIRMWARE_VERSION);
297 
298 	/* Sensor readings */
299 	switch (priv->kind) {
300 	case d5next:
301 		priv->power_cycles = get_unaligned_be32(data + D5NEXT_POWER_CYCLES);
302 
303 		priv->temp_input[0] = get_unaligned_be16(data + D5NEXT_COOLANT_TEMP) * 10;
304 
305 		priv->speed_input[0] = get_unaligned_be16(data + D5NEXT_PUMP_SPEED);
306 		priv->speed_input[1] = get_unaligned_be16(data + D5NEXT_FAN_SPEED);
307 
308 		priv->power_input[0] = get_unaligned_be16(data + D5NEXT_PUMP_POWER) * 10000;
309 		priv->power_input[1] = get_unaligned_be16(data + D5NEXT_FAN_POWER) * 10000;
310 
311 		priv->voltage_input[0] = get_unaligned_be16(data + D5NEXT_PUMP_VOLTAGE) * 10;
312 		priv->voltage_input[1] = get_unaligned_be16(data + D5NEXT_FAN_VOLTAGE) * 10;
313 		priv->voltage_input[2] = get_unaligned_be16(data + D5NEXT_5V_VOLTAGE) * 10;
314 
315 		priv->current_input[0] = get_unaligned_be16(data + D5NEXT_PUMP_CURRENT);
316 		priv->current_input[1] = get_unaligned_be16(data + D5NEXT_FAN_CURRENT);
317 		break;
318 	case farbwerk360:
319 		/* Temperature sensor readings */
320 		for (i = 0; i < FARBWERK360_NUM_SENSORS; i++) {
321 			sensor_value = get_unaligned_be16(data + FARBWERK360_SENSOR_START +
322 							  i * FARBWERK360_SENSOR_SIZE);
323 			if (sensor_value == FARBWERK360_SENSOR_DISCONNECTED)
324 				priv->temp_input[i] = -ENODATA;
325 			else
326 				priv->temp_input[i] = sensor_value * 10;
327 		}
328 		break;
329 	default:
330 		break;
331 	}
332 
333 	priv->updated = jiffies;
334 
335 	return 0;
336 }
337 
338 #ifdef CONFIG_DEBUG_FS
339 
340 static int serial_number_show(struct seq_file *seqf, void *unused)
341 {
342 	struct aqc_data *priv = seqf->private;
343 
344 	seq_printf(seqf, "%05u-%05u\n", priv->serial_number[0], priv->serial_number[1]);
345 
346 	return 0;
347 }
348 DEFINE_SHOW_ATTRIBUTE(serial_number);
349 
350 static int firmware_version_show(struct seq_file *seqf, void *unused)
351 {
352 	struct aqc_data *priv = seqf->private;
353 
354 	seq_printf(seqf, "%u\n", priv->firmware_version);
355 
356 	return 0;
357 }
358 DEFINE_SHOW_ATTRIBUTE(firmware_version);
359 
360 static int power_cycles_show(struct seq_file *seqf, void *unused)
361 {
362 	struct aqc_data *priv = seqf->private;
363 
364 	seq_printf(seqf, "%u\n", priv->power_cycles);
365 
366 	return 0;
367 }
368 DEFINE_SHOW_ATTRIBUTE(power_cycles);
369 
370 static void aqc_debugfs_init(struct aqc_data *priv)
371 {
372 	char name[64];
373 
374 	scnprintf(name, sizeof(name), "%s_%s-%s", "aquacomputer", priv->name,
375 		  dev_name(&priv->hdev->dev));
376 
377 	priv->debugfs = debugfs_create_dir(name, NULL);
378 	debugfs_create_file("serial_number", 0444, priv->debugfs, priv, &serial_number_fops);
379 	debugfs_create_file("firmware_version", 0444, priv->debugfs, priv, &firmware_version_fops);
380 
381 	if (priv->kind == d5next)
382 		debugfs_create_file("power_cycles", 0444, priv->debugfs, priv, &power_cycles_fops);
383 }
384 
385 #else
386 
387 static void aqc_debugfs_init(struct aqc_data *priv)
388 {
389 }
390 
391 #endif
392 
393 static int aqc_probe(struct hid_device *hdev, const struct hid_device_id *id)
394 {
395 	struct aqc_data *priv;
396 	int ret;
397 
398 	priv = devm_kzalloc(&hdev->dev, sizeof(*priv), GFP_KERNEL);
399 	if (!priv)
400 		return -ENOMEM;
401 
402 	priv->hdev = hdev;
403 	hid_set_drvdata(hdev, priv);
404 
405 	priv->updated = jiffies - STATUS_UPDATE_INTERVAL;
406 
407 	ret = hid_parse(hdev);
408 	if (ret)
409 		return ret;
410 
411 	ret = hid_hw_start(hdev, HID_CONNECT_HIDRAW);
412 	if (ret)
413 		return ret;
414 
415 	ret = hid_hw_open(hdev);
416 	if (ret)
417 		goto fail_and_stop;
418 
419 	switch (hdev->product) {
420 	case USB_PRODUCT_ID_D5NEXT:
421 		priv->kind = d5next;
422 		break;
423 	case USB_PRODUCT_ID_FARBWERK360:
424 		priv->kind = farbwerk360;
425 		break;
426 	default:
427 		break;
428 	}
429 
430 	priv->name = aqc_device_names[priv->kind];
431 
432 	priv->hwmon_dev = hwmon_device_register_with_info(&hdev->dev, priv->name, priv,
433 							  &aqc_chip_info, NULL);
434 
435 	if (IS_ERR(priv->hwmon_dev)) {
436 		ret = PTR_ERR(priv->hwmon_dev);
437 		goto fail_and_close;
438 	}
439 
440 	aqc_debugfs_init(priv);
441 
442 	return 0;
443 
444 fail_and_close:
445 	hid_hw_close(hdev);
446 fail_and_stop:
447 	hid_hw_stop(hdev);
448 	return ret;
449 }
450 
451 static void aqc_remove(struct hid_device *hdev)
452 {
453 	struct aqc_data *priv = hid_get_drvdata(hdev);
454 
455 	debugfs_remove_recursive(priv->debugfs);
456 	hwmon_device_unregister(priv->hwmon_dev);
457 
458 	hid_hw_close(hdev);
459 	hid_hw_stop(hdev);
460 }
461 
462 static const struct hid_device_id aqc_table[] = {
463 	{ HID_USB_DEVICE(USB_VENDOR_ID_AQUACOMPUTER, USB_PRODUCT_ID_D5NEXT) },
464 	{ HID_USB_DEVICE(USB_VENDOR_ID_AQUACOMPUTER, USB_PRODUCT_ID_FARBWERK360) },
465 	{ }
466 };
467 
468 MODULE_DEVICE_TABLE(hid, aqc_table);
469 
470 static struct hid_driver aqc_driver = {
471 	.name = DRIVER_NAME,
472 	.id_table = aqc_table,
473 	.probe = aqc_probe,
474 	.remove = aqc_remove,
475 	.raw_event = aqc_raw_event,
476 };
477 
478 static int __init aqc_init(void)
479 {
480 	return hid_register_driver(&aqc_driver);
481 }
482 
483 static void __exit aqc_exit(void)
484 {
485 	hid_unregister_driver(&aqc_driver);
486 }
487 
488 /* Request to initialize after the HID bus to ensure it's not being loaded before */
489 late_initcall(aqc_init);
490 module_exit(aqc_exit);
491 
492 MODULE_LICENSE("GPL");
493 MODULE_AUTHOR("Aleksa Savic <savicaleksa83@gmail.com>");
494 MODULE_DESCRIPTION("Hwmon driver for Aquacomputer devices");
495