cachepc-linux

Fork of AMDESE/linux with modifications for CachePC side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-linux
Log | Files | Refs | README | LICENSE | sfeed.txt

aquacomputer_d5next.c (20600B)


      1// SPDX-License-Identifier: GPL-2.0+
      2/*
      3 * hwmon driver for Aquacomputer devices (D5 Next, Farbwerk, Farbwerk 360, Octo)
      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 * Copyright 2022 Jack Doan <me@jackdoan.com>
     10 */
     11
     12#include <linux/crc16.h>
     13#include <linux/debugfs.h>
     14#include <linux/hid.h>
     15#include <linux/hwmon.h>
     16#include <linux/jiffies.h>
     17#include <linux/module.h>
     18#include <linux/mutex.h>
     19#include <linux/seq_file.h>
     20#include <asm/unaligned.h>
     21
     22#define USB_VENDOR_ID_AQUACOMPUTER	0x0c70
     23#define USB_PRODUCT_ID_FARBWERK		0xf00a
     24#define USB_PRODUCT_ID_D5NEXT		0xf00e
     25#define USB_PRODUCT_ID_FARBWERK360	0xf010
     26#define USB_PRODUCT_ID_OCTO		0xf011
     27
     28enum kinds { d5next, farbwerk, farbwerk360, octo };
     29
     30static const char *const aqc_device_names[] = {
     31	[d5next] = "d5next",
     32	[farbwerk] = "farbwerk",
     33	[farbwerk360] = "farbwerk360",
     34	[octo] = "octo"
     35};
     36
     37#define DRIVER_NAME			"aquacomputer_d5next"
     38
     39#define STATUS_REPORT_ID		0x01
     40#define STATUS_UPDATE_INTERVAL		(2 * HZ)	/* In seconds */
     41#define SERIAL_FIRST_PART		3
     42#define SERIAL_SECOND_PART		5
     43#define FIRMWARE_VERSION		13
     44
     45#define CTRL_REPORT_ID			0x03
     46
     47/* The HID report that the official software always sends
     48 * after writing values, currently same for all devices
     49 */
     50#define SECONDARY_CTRL_REPORT_ID	0x02
     51#define SECONDARY_CTRL_REPORT_SIZE	0x0B
     52
     53static u8 secondary_ctrl_report[] = {
     54	0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x34, 0xC6
     55};
     56
     57/* Register offsets for the D5 Next pump */
     58#define D5NEXT_POWER_CYCLES		24
     59
     60#define D5NEXT_COOLANT_TEMP		87
     61
     62#define D5NEXT_PUMP_SPEED		116
     63#define D5NEXT_FAN_SPEED		103
     64
     65#define D5NEXT_PUMP_POWER		114
     66#define D5NEXT_FAN_POWER		101
     67
     68#define D5NEXT_PUMP_VOLTAGE		110
     69#define D5NEXT_FAN_VOLTAGE		97
     70#define D5NEXT_5V_VOLTAGE		57
     71
     72#define D5NEXT_PUMP_CURRENT		112
     73#define D5NEXT_FAN_CURRENT		99
     74
     75/* Register offsets for the Farbwerk RGB controller */
     76#define FARBWERK_NUM_SENSORS		4
     77#define FARBWERK_SENSOR_START		0x2f
     78#define FARBWERK_SENSOR_SIZE		0x02
     79#define FARBWERK_SENSOR_DISCONNECTED	0x7FFF
     80
     81/* Register offsets for the Farbwerk 360 RGB controller */
     82#define FARBWERK360_NUM_SENSORS		4
     83#define FARBWERK360_SENSOR_START	0x32
     84#define FARBWERK360_SENSOR_SIZE		0x02
     85#define FARBWERK360_SENSOR_DISCONNECTED	0x7FFF
     86
     87/* Register offsets for the Octo fan controller */
     88#define OCTO_POWER_CYCLES		0x18
     89#define OCTO_NUM_FANS			8
     90#define OCTO_FAN_PERCENT_OFFSET		0x00
     91#define OCTO_FAN_VOLTAGE_OFFSET		0x02
     92#define OCTO_FAN_CURRENT_OFFSET		0x04
     93#define OCTO_FAN_POWER_OFFSET		0x06
     94#define OCTO_FAN_SPEED_OFFSET		0x08
     95
     96static u8 octo_sensor_fan_offsets[] = { 0x7D, 0x8A, 0x97, 0xA4, 0xB1, 0xBE, 0xCB, 0xD8 };
     97
     98#define OCTO_NUM_SENSORS		4
     99#define OCTO_SENSOR_START		0x3D
    100#define OCTO_SENSOR_SIZE		0x02
    101#define OCTO_SENSOR_DISCONNECTED	0x7FFF
    102
    103#define OCTO_CTRL_REPORT_SIZE			0x65F
    104#define OCTO_CTRL_REPORT_CHECKSUM_OFFSET	0x65D
    105#define OCTO_CTRL_REPORT_CHECKSUM_START		0x01
    106#define OCTO_CTRL_REPORT_CHECKSUM_LENGTH	0x65C
    107
    108/* Fan speed registers in Octo control report (from 0-100%) */
    109static u16 octo_ctrl_fan_offsets[] = { 0x5B, 0xB0, 0x105, 0x15A, 0x1AF, 0x204, 0x259, 0x2AE };
    110
    111/* Labels for D5 Next */
    112static const char *const label_d5next_temp[] = {
    113	"Coolant temp"
    114};
    115
    116static const char *const label_d5next_speeds[] = {
    117	"Pump speed",
    118	"Fan speed"
    119};
    120
    121static const char *const label_d5next_power[] = {
    122	"Pump power",
    123	"Fan power"
    124};
    125
    126static const char *const label_d5next_voltages[] = {
    127	"Pump voltage",
    128	"Fan voltage",
    129	"+5V voltage"
    130};
    131
    132static const char *const label_d5next_current[] = {
    133	"Pump current",
    134	"Fan current"
    135};
    136
    137/* Labels for Farbwerk, Farbwerk 360 and Octo temperature sensors */
    138static const char *const label_temp_sensors[] = {
    139	"Sensor 1",
    140	"Sensor 2",
    141	"Sensor 3",
    142	"Sensor 4"
    143};
    144
    145/* Labels for Octo */
    146static const char *const label_fan_speed[] = {
    147	"Fan 1 speed",
    148	"Fan 2 speed",
    149	"Fan 3 speed",
    150	"Fan 4 speed",
    151	"Fan 5 speed",
    152	"Fan 6 speed",
    153	"Fan 7 speed",
    154	"Fan 8 speed"
    155};
    156
    157static const char *const label_fan_power[] = {
    158	"Fan 1 power",
    159	"Fan 2 power",
    160	"Fan 3 power",
    161	"Fan 4 power",
    162	"Fan 5 power",
    163	"Fan 6 power",
    164	"Fan 7 power",
    165	"Fan 8 power"
    166};
    167
    168static const char *const label_fan_voltage[] = {
    169	"Fan 1 voltage",
    170	"Fan 2 voltage",
    171	"Fan 3 voltage",
    172	"Fan 4 voltage",
    173	"Fan 5 voltage",
    174	"Fan 6 voltage",
    175	"Fan 7 voltage",
    176	"Fan 8 voltage"
    177};
    178
    179static const char *const label_fan_current[] = {
    180	"Fan 1 current",
    181	"Fan 2 current",
    182	"Fan 3 current",
    183	"Fan 4 current",
    184	"Fan 5 current",
    185	"Fan 6 current",
    186	"Fan 7 current",
    187	"Fan 8 current"
    188};
    189
    190struct aqc_data {
    191	struct hid_device *hdev;
    192	struct device *hwmon_dev;
    193	struct dentry *debugfs;
    194	struct mutex mutex;	/* Used for locking access when reading and writing PWM values */
    195	enum kinds kind;
    196	const char *name;
    197
    198	int buffer_size;
    199	u8 *buffer;
    200	int checksum_start;
    201	int checksum_length;
    202	int checksum_offset;
    203
    204	/* General info, same across all devices */
    205	u32 serial_number[2];
    206	u16 firmware_version;
    207
    208	/* How many times the device was powered on */
    209	u32 power_cycles;
    210
    211	/* Sensor values */
    212	s32 temp_input[4];
    213	u16 speed_input[8];
    214	u32 power_input[8];
    215	u16 voltage_input[8];
    216	u16 current_input[8];
    217
    218	/* Label values */
    219	const char *const *temp_label;
    220	const char *const *speed_label;
    221	const char *const *power_label;
    222	const char *const *voltage_label;
    223	const char *const *current_label;
    224
    225	unsigned long updated;
    226};
    227
    228/* Converts from centi-percent */
    229static int aqc_percent_to_pwm(u16 val)
    230{
    231	return DIV_ROUND_CLOSEST(val * 255, 100 * 100);
    232}
    233
    234/* Converts to centi-percent */
    235static int aqc_pwm_to_percent(long val)
    236{
    237	if (val < 0 || val > 255)
    238		return -EINVAL;
    239
    240	return DIV_ROUND_CLOSEST(val * 100 * 100, 255);
    241}
    242
    243/* Expects the mutex to be locked */
    244static int aqc_get_ctrl_data(struct aqc_data *priv)
    245{
    246	int ret;
    247
    248	memset(priv->buffer, 0x00, priv->buffer_size);
    249	ret = hid_hw_raw_request(priv->hdev, CTRL_REPORT_ID, priv->buffer, priv->buffer_size,
    250				 HID_FEATURE_REPORT, HID_REQ_GET_REPORT);
    251	if (ret < 0)
    252		ret = -ENODATA;
    253
    254	return ret;
    255}
    256
    257/* Expects the mutex to be locked */
    258static int aqc_send_ctrl_data(struct aqc_data *priv)
    259{
    260	int ret;
    261	u16 checksum;
    262
    263	/* Init and xorout value for CRC-16/USB is 0xffff */
    264	checksum = crc16(0xffff, priv->buffer + priv->checksum_start, priv->checksum_length);
    265	checksum ^= 0xffff;
    266
    267	/* Place the new checksum at the end of the report */
    268	put_unaligned_be16(checksum, priv->buffer + priv->checksum_offset);
    269
    270	/* Send the patched up report back to the device */
    271	ret = hid_hw_raw_request(priv->hdev, CTRL_REPORT_ID, priv->buffer, priv->buffer_size,
    272				 HID_FEATURE_REPORT, HID_REQ_SET_REPORT);
    273	if (ret < 0)
    274		return ret;
    275
    276	/* The official software sends this report after every change, so do it here as well */
    277	ret = hid_hw_raw_request(priv->hdev, SECONDARY_CTRL_REPORT_ID, secondary_ctrl_report,
    278				 SECONDARY_CTRL_REPORT_SIZE, HID_FEATURE_REPORT,
    279				 HID_REQ_SET_REPORT);
    280	return ret;
    281}
    282
    283/* Refreshes the control buffer and returns value at offset */
    284static int aqc_get_ctrl_val(struct aqc_data *priv, int offset)
    285{
    286	int ret;
    287
    288	mutex_lock(&priv->mutex);
    289
    290	ret = aqc_get_ctrl_data(priv);
    291	if (ret < 0)
    292		goto unlock_and_return;
    293
    294	ret = get_unaligned_be16(priv->buffer + offset);
    295
    296unlock_and_return:
    297	mutex_unlock(&priv->mutex);
    298	return ret;
    299}
    300
    301static int aqc_set_ctrl_val(struct aqc_data *priv, int offset, long val)
    302{
    303	int ret;
    304
    305	mutex_lock(&priv->mutex);
    306
    307	ret = aqc_get_ctrl_data(priv);
    308	if (ret < 0)
    309		goto unlock_and_return;
    310
    311	put_unaligned_be16((u16)val, priv->buffer + offset);
    312
    313	ret = aqc_send_ctrl_data(priv);
    314
    315unlock_and_return:
    316	mutex_unlock(&priv->mutex);
    317	return ret;
    318}
    319
    320static umode_t aqc_is_visible(const void *data, enum hwmon_sensor_types type, u32 attr, int channel)
    321{
    322	const struct aqc_data *priv = data;
    323
    324	switch (type) {
    325	case hwmon_temp:
    326		switch (priv->kind) {
    327		case d5next:
    328			if (channel == 0)
    329				return 0444;
    330			break;
    331		case farbwerk:
    332		case farbwerk360:
    333		case octo:
    334			return 0444;
    335		default:
    336			break;
    337		}
    338		break;
    339	case hwmon_pwm:
    340		switch (priv->kind) {
    341		case octo:
    342			switch (attr) {
    343			case hwmon_pwm_input:
    344				return 0644;
    345			default:
    346				break;
    347			}
    348			break;
    349		default:
    350			break;
    351		}
    352		break;
    353	case hwmon_fan:
    354	case hwmon_power:
    355	case hwmon_curr:
    356		switch (priv->kind) {
    357		case d5next:
    358			if (channel < 2)
    359				return 0444;
    360			break;
    361		case octo:
    362			return 0444;
    363		default:
    364			break;
    365		}
    366		break;
    367	case hwmon_in:
    368		switch (priv->kind) {
    369		case d5next:
    370			if (channel < 3)
    371				return 0444;
    372			break;
    373		case octo:
    374			return 0444;
    375		default:
    376			break;
    377		}
    378		break;
    379	default:
    380		break;
    381	}
    382
    383	return 0;
    384}
    385
    386static int aqc_read(struct device *dev, enum hwmon_sensor_types type, u32 attr,
    387		    int channel, long *val)
    388{
    389	int ret;
    390	struct aqc_data *priv = dev_get_drvdata(dev);
    391
    392	if (time_after(jiffies, priv->updated + STATUS_UPDATE_INTERVAL))
    393		return -ENODATA;
    394
    395	switch (type) {
    396	case hwmon_temp:
    397		if (priv->temp_input[channel] == -ENODATA)
    398			return -ENODATA;
    399
    400		*val = priv->temp_input[channel];
    401		break;
    402	case hwmon_fan:
    403		*val = priv->speed_input[channel];
    404		break;
    405	case hwmon_power:
    406		*val = priv->power_input[channel];
    407		break;
    408	case hwmon_pwm:
    409		switch (priv->kind) {
    410		case octo:
    411			ret = aqc_get_ctrl_val(priv, octo_ctrl_fan_offsets[channel]);
    412			if (ret < 0)
    413				return ret;
    414
    415			*val = aqc_percent_to_pwm(ret);
    416			break;
    417		default:
    418			break;
    419		}
    420		break;
    421	case hwmon_in:
    422		*val = priv->voltage_input[channel];
    423		break;
    424	case hwmon_curr:
    425		*val = priv->current_input[channel];
    426		break;
    427	default:
    428		return -EOPNOTSUPP;
    429	}
    430
    431	return 0;
    432}
    433
    434static int aqc_read_string(struct device *dev, enum hwmon_sensor_types type, u32 attr,
    435			   int channel, const char **str)
    436{
    437	struct aqc_data *priv = dev_get_drvdata(dev);
    438
    439	switch (type) {
    440	case hwmon_temp:
    441		*str = priv->temp_label[channel];
    442		break;
    443	case hwmon_fan:
    444		*str = priv->speed_label[channel];
    445		break;
    446	case hwmon_power:
    447		*str = priv->power_label[channel];
    448		break;
    449	case hwmon_in:
    450		*str = priv->voltage_label[channel];
    451		break;
    452	case hwmon_curr:
    453		*str = priv->current_label[channel];
    454		break;
    455	default:
    456		return -EOPNOTSUPP;
    457	}
    458
    459	return 0;
    460}
    461
    462static int aqc_write(struct device *dev, enum hwmon_sensor_types type, u32 attr, int channel,
    463		     long val)
    464{
    465	int ret, pwm_value;
    466	struct aqc_data *priv = dev_get_drvdata(dev);
    467
    468	switch (type) {
    469	case hwmon_pwm:
    470		switch (attr) {
    471		case hwmon_pwm_input:
    472			switch (priv->kind) {
    473			case octo:
    474				pwm_value = aqc_pwm_to_percent(val);
    475				if (pwm_value < 0)
    476					return pwm_value;
    477
    478				ret = aqc_set_ctrl_val(priv, octo_ctrl_fan_offsets[channel],
    479						       pwm_value);
    480				if (ret < 0)
    481					return ret;
    482				break;
    483			default:
    484				break;
    485			}
    486			break;
    487		default:
    488			break;
    489		}
    490		break;
    491	default:
    492		return -EOPNOTSUPP;
    493	}
    494
    495	return 0;
    496}
    497
    498static const struct hwmon_ops aqc_hwmon_ops = {
    499	.is_visible = aqc_is_visible,
    500	.read = aqc_read,
    501	.read_string = aqc_read_string,
    502	.write = aqc_write
    503};
    504
    505static const struct hwmon_channel_info *aqc_info[] = {
    506	HWMON_CHANNEL_INFO(temp,
    507			   HWMON_T_INPUT | HWMON_T_LABEL,
    508			   HWMON_T_INPUT | HWMON_T_LABEL,
    509			   HWMON_T_INPUT | HWMON_T_LABEL,
    510			   HWMON_T_INPUT | HWMON_T_LABEL),
    511	HWMON_CHANNEL_INFO(fan,
    512			   HWMON_F_INPUT | HWMON_F_LABEL,
    513			   HWMON_F_INPUT | HWMON_F_LABEL,
    514			   HWMON_F_INPUT | HWMON_F_LABEL,
    515			   HWMON_F_INPUT | HWMON_F_LABEL,
    516			   HWMON_F_INPUT | HWMON_F_LABEL,
    517			   HWMON_F_INPUT | HWMON_F_LABEL,
    518			   HWMON_F_INPUT | HWMON_F_LABEL,
    519			   HWMON_F_INPUT | HWMON_F_LABEL),
    520	HWMON_CHANNEL_INFO(power,
    521			   HWMON_P_INPUT | HWMON_P_LABEL,
    522			   HWMON_P_INPUT | HWMON_P_LABEL,
    523			   HWMON_P_INPUT | HWMON_P_LABEL,
    524			   HWMON_P_INPUT | HWMON_P_LABEL,
    525			   HWMON_P_INPUT | HWMON_P_LABEL,
    526			   HWMON_P_INPUT | HWMON_P_LABEL,
    527			   HWMON_P_INPUT | HWMON_P_LABEL,
    528			   HWMON_P_INPUT | HWMON_P_LABEL),
    529	HWMON_CHANNEL_INFO(pwm,
    530			   HWMON_PWM_INPUT,
    531			   HWMON_PWM_INPUT,
    532			   HWMON_PWM_INPUT,
    533			   HWMON_PWM_INPUT,
    534			   HWMON_PWM_INPUT,
    535			   HWMON_PWM_INPUT,
    536			   HWMON_PWM_INPUT,
    537			   HWMON_PWM_INPUT),
    538	HWMON_CHANNEL_INFO(in,
    539			   HWMON_I_INPUT | HWMON_I_LABEL,
    540			   HWMON_I_INPUT | HWMON_I_LABEL,
    541			   HWMON_I_INPUT | HWMON_I_LABEL,
    542			   HWMON_I_INPUT | HWMON_I_LABEL,
    543			   HWMON_I_INPUT | HWMON_I_LABEL,
    544			   HWMON_I_INPUT | HWMON_I_LABEL,
    545			   HWMON_I_INPUT | HWMON_I_LABEL,
    546			   HWMON_I_INPUT | HWMON_I_LABEL),
    547	HWMON_CHANNEL_INFO(curr,
    548			   HWMON_C_INPUT | HWMON_C_LABEL,
    549			   HWMON_C_INPUT | HWMON_C_LABEL,
    550			   HWMON_C_INPUT | HWMON_C_LABEL,
    551			   HWMON_C_INPUT | HWMON_C_LABEL,
    552			   HWMON_C_INPUT | HWMON_C_LABEL,
    553			   HWMON_C_INPUT | HWMON_C_LABEL,
    554			   HWMON_C_INPUT | HWMON_C_LABEL,
    555			   HWMON_C_INPUT | HWMON_C_LABEL),
    556	NULL
    557};
    558
    559static const struct hwmon_chip_info aqc_chip_info = {
    560	.ops = &aqc_hwmon_ops,
    561	.info = aqc_info,
    562};
    563
    564static int aqc_raw_event(struct hid_device *hdev, struct hid_report *report, u8 *data, int size)
    565{
    566	int i, sensor_value;
    567	struct aqc_data *priv;
    568
    569	if (report->id != STATUS_REPORT_ID)
    570		return 0;
    571
    572	priv = hid_get_drvdata(hdev);
    573
    574	/* Info provided with every report */
    575	priv->serial_number[0] = get_unaligned_be16(data + SERIAL_FIRST_PART);
    576	priv->serial_number[1] = get_unaligned_be16(data + SERIAL_SECOND_PART);
    577	priv->firmware_version = get_unaligned_be16(data + FIRMWARE_VERSION);
    578
    579	/* Sensor readings */
    580	switch (priv->kind) {
    581	case d5next:
    582		priv->power_cycles = get_unaligned_be32(data + D5NEXT_POWER_CYCLES);
    583
    584		priv->temp_input[0] = get_unaligned_be16(data + D5NEXT_COOLANT_TEMP) * 10;
    585
    586		priv->speed_input[0] = get_unaligned_be16(data + D5NEXT_PUMP_SPEED);
    587		priv->speed_input[1] = get_unaligned_be16(data + D5NEXT_FAN_SPEED);
    588
    589		priv->power_input[0] = get_unaligned_be16(data + D5NEXT_PUMP_POWER) * 10000;
    590		priv->power_input[1] = get_unaligned_be16(data + D5NEXT_FAN_POWER) * 10000;
    591
    592		priv->voltage_input[0] = get_unaligned_be16(data + D5NEXT_PUMP_VOLTAGE) * 10;
    593		priv->voltage_input[1] = get_unaligned_be16(data + D5NEXT_FAN_VOLTAGE) * 10;
    594		priv->voltage_input[2] = get_unaligned_be16(data + D5NEXT_5V_VOLTAGE) * 10;
    595
    596		priv->current_input[0] = get_unaligned_be16(data + D5NEXT_PUMP_CURRENT);
    597		priv->current_input[1] = get_unaligned_be16(data + D5NEXT_FAN_CURRENT);
    598		break;
    599	case farbwerk:
    600		/* Temperature sensor readings */
    601		for (i = 0; i < FARBWERK_NUM_SENSORS; i++) {
    602			sensor_value = get_unaligned_be16(data + FARBWERK_SENSOR_START +
    603							  i * FARBWERK_SENSOR_SIZE);
    604			if (sensor_value == FARBWERK_SENSOR_DISCONNECTED)
    605				priv->temp_input[i] = -ENODATA;
    606			else
    607				priv->temp_input[i] = sensor_value * 10;
    608		}
    609		break;
    610	case farbwerk360:
    611		/* Temperature sensor readings */
    612		for (i = 0; i < FARBWERK360_NUM_SENSORS; i++) {
    613			sensor_value = get_unaligned_be16(data + FARBWERK360_SENSOR_START +
    614							  i * FARBWERK360_SENSOR_SIZE);
    615			if (sensor_value == FARBWERK360_SENSOR_DISCONNECTED)
    616				priv->temp_input[i] = -ENODATA;
    617			else
    618				priv->temp_input[i] = sensor_value * 10;
    619		}
    620		break;
    621	case octo:
    622		priv->power_cycles = get_unaligned_be32(data + OCTO_POWER_CYCLES);
    623
    624		/* Fan speed and related readings */
    625		for (i = 0; i < OCTO_NUM_FANS; i++) {
    626			priv->speed_input[i] =
    627			    get_unaligned_be16(data + octo_sensor_fan_offsets[i] +
    628					       OCTO_FAN_SPEED_OFFSET);
    629			priv->power_input[i] =
    630			    get_unaligned_be16(data + octo_sensor_fan_offsets[i] +
    631					       OCTO_FAN_POWER_OFFSET) * 10000;
    632			priv->voltage_input[i] =
    633			    get_unaligned_be16(data + octo_sensor_fan_offsets[i] +
    634					       OCTO_FAN_VOLTAGE_OFFSET) * 10;
    635			priv->current_input[i] =
    636			    get_unaligned_be16(data + octo_sensor_fan_offsets[i] +
    637					       OCTO_FAN_CURRENT_OFFSET);
    638		}
    639
    640		/* Temperature sensor readings */
    641		for (i = 0; i < OCTO_NUM_SENSORS; i++) {
    642			sensor_value = get_unaligned_be16(data + OCTO_SENSOR_START +
    643							  i * OCTO_SENSOR_SIZE);
    644			if (sensor_value == OCTO_SENSOR_DISCONNECTED)
    645				priv->temp_input[i] = -ENODATA;
    646			else
    647				priv->temp_input[i] = sensor_value * 10;
    648		}
    649		break;
    650	default:
    651		break;
    652	}
    653
    654	priv->updated = jiffies;
    655
    656	return 0;
    657}
    658
    659#ifdef CONFIG_DEBUG_FS
    660
    661static int serial_number_show(struct seq_file *seqf, void *unused)
    662{
    663	struct aqc_data *priv = seqf->private;
    664
    665	seq_printf(seqf, "%05u-%05u\n", priv->serial_number[0], priv->serial_number[1]);
    666
    667	return 0;
    668}
    669DEFINE_SHOW_ATTRIBUTE(serial_number);
    670
    671static int firmware_version_show(struct seq_file *seqf, void *unused)
    672{
    673	struct aqc_data *priv = seqf->private;
    674
    675	seq_printf(seqf, "%u\n", priv->firmware_version);
    676
    677	return 0;
    678}
    679DEFINE_SHOW_ATTRIBUTE(firmware_version);
    680
    681static int power_cycles_show(struct seq_file *seqf, void *unused)
    682{
    683	struct aqc_data *priv = seqf->private;
    684
    685	seq_printf(seqf, "%u\n", priv->power_cycles);
    686
    687	return 0;
    688}
    689DEFINE_SHOW_ATTRIBUTE(power_cycles);
    690
    691static void aqc_debugfs_init(struct aqc_data *priv)
    692{
    693	char name[64];
    694
    695	scnprintf(name, sizeof(name), "%s_%s-%s", "aquacomputer", priv->name,
    696		  dev_name(&priv->hdev->dev));
    697
    698	priv->debugfs = debugfs_create_dir(name, NULL);
    699	debugfs_create_file("serial_number", 0444, priv->debugfs, priv, &serial_number_fops);
    700	debugfs_create_file("firmware_version", 0444, priv->debugfs, priv, &firmware_version_fops);
    701
    702	switch (priv->kind) {
    703	case d5next:
    704	case octo:
    705		debugfs_create_file("power_cycles", 0444, priv->debugfs, priv, &power_cycles_fops);
    706		break;
    707	default:
    708		break;
    709	}
    710}
    711
    712#else
    713
    714static void aqc_debugfs_init(struct aqc_data *priv)
    715{
    716}
    717
    718#endif
    719
    720static int aqc_probe(struct hid_device *hdev, const struct hid_device_id *id)
    721{
    722	struct aqc_data *priv;
    723	int ret;
    724
    725	priv = devm_kzalloc(&hdev->dev, sizeof(*priv), GFP_KERNEL);
    726	if (!priv)
    727		return -ENOMEM;
    728
    729	priv->hdev = hdev;
    730	hid_set_drvdata(hdev, priv);
    731
    732	priv->updated = jiffies - STATUS_UPDATE_INTERVAL;
    733
    734	ret = hid_parse(hdev);
    735	if (ret)
    736		return ret;
    737
    738	ret = hid_hw_start(hdev, HID_CONNECT_HIDRAW);
    739	if (ret)
    740		return ret;
    741
    742	ret = hid_hw_open(hdev);
    743	if (ret)
    744		goto fail_and_stop;
    745
    746	switch (hdev->product) {
    747	case USB_PRODUCT_ID_D5NEXT:
    748		priv->kind = d5next;
    749
    750		priv->temp_label = label_d5next_temp;
    751		priv->speed_label = label_d5next_speeds;
    752		priv->power_label = label_d5next_power;
    753		priv->voltage_label = label_d5next_voltages;
    754		priv->current_label = label_d5next_current;
    755		break;
    756	case USB_PRODUCT_ID_FARBWERK:
    757		priv->kind = farbwerk;
    758
    759		priv->temp_label = label_temp_sensors;
    760		break;
    761	case USB_PRODUCT_ID_FARBWERK360:
    762		priv->kind = farbwerk360;
    763
    764		priv->temp_label = label_temp_sensors;
    765		break;
    766	case USB_PRODUCT_ID_OCTO:
    767		priv->kind = octo;
    768		priv->buffer_size = OCTO_CTRL_REPORT_SIZE;
    769		priv->checksum_start = OCTO_CTRL_REPORT_CHECKSUM_START;
    770		priv->checksum_length = OCTO_CTRL_REPORT_CHECKSUM_LENGTH;
    771		priv->checksum_offset = OCTO_CTRL_REPORT_CHECKSUM_OFFSET;
    772
    773		priv->temp_label = label_temp_sensors;
    774		priv->speed_label = label_fan_speed;
    775		priv->power_label = label_fan_power;
    776		priv->voltage_label = label_fan_voltage;
    777		priv->current_label = label_fan_current;
    778		break;
    779	default:
    780		break;
    781	}
    782
    783	priv->name = aqc_device_names[priv->kind];
    784
    785	priv->buffer = devm_kzalloc(&hdev->dev, priv->buffer_size, GFP_KERNEL);
    786	if (!priv->buffer) {
    787		ret = -ENOMEM;
    788		goto fail_and_close;
    789	}
    790
    791	mutex_init(&priv->mutex);
    792
    793	priv->hwmon_dev = hwmon_device_register_with_info(&hdev->dev, priv->name, priv,
    794							  &aqc_chip_info, NULL);
    795
    796	if (IS_ERR(priv->hwmon_dev)) {
    797		ret = PTR_ERR(priv->hwmon_dev);
    798		goto fail_and_close;
    799	}
    800
    801	aqc_debugfs_init(priv);
    802
    803	return 0;
    804
    805fail_and_close:
    806	hid_hw_close(hdev);
    807fail_and_stop:
    808	hid_hw_stop(hdev);
    809	return ret;
    810}
    811
    812static void aqc_remove(struct hid_device *hdev)
    813{
    814	struct aqc_data *priv = hid_get_drvdata(hdev);
    815
    816	debugfs_remove_recursive(priv->debugfs);
    817	hwmon_device_unregister(priv->hwmon_dev);
    818
    819	hid_hw_close(hdev);
    820	hid_hw_stop(hdev);
    821}
    822
    823static const struct hid_device_id aqc_table[] = {
    824	{ HID_USB_DEVICE(USB_VENDOR_ID_AQUACOMPUTER, USB_PRODUCT_ID_D5NEXT) },
    825	{ HID_USB_DEVICE(USB_VENDOR_ID_AQUACOMPUTER, USB_PRODUCT_ID_FARBWERK) },
    826	{ HID_USB_DEVICE(USB_VENDOR_ID_AQUACOMPUTER, USB_PRODUCT_ID_FARBWERK360) },
    827	{ HID_USB_DEVICE(USB_VENDOR_ID_AQUACOMPUTER, USB_PRODUCT_ID_OCTO) },
    828	{ }
    829};
    830
    831MODULE_DEVICE_TABLE(hid, aqc_table);
    832
    833static struct hid_driver aqc_driver = {
    834	.name = DRIVER_NAME,
    835	.id_table = aqc_table,
    836	.probe = aqc_probe,
    837	.remove = aqc_remove,
    838	.raw_event = aqc_raw_event,
    839};
    840
    841static int __init aqc_init(void)
    842{
    843	return hid_register_driver(&aqc_driver);
    844}
    845
    846static void __exit aqc_exit(void)
    847{
    848	hid_unregister_driver(&aqc_driver);
    849}
    850
    851/* Request to initialize after the HID bus to ensure it's not being loaded before */
    852late_initcall(aqc_init);
    853module_exit(aqc_exit);
    854
    855MODULE_LICENSE("GPL");
    856MODULE_AUTHOR("Aleksa Savic <savicaleksa83@gmail.com>");
    857MODULE_AUTHOR("Jack Doan <me@jackdoan.com>");
    858MODULE_DESCRIPTION("Hwmon driver for Aquacomputer devices");