Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0+
0002 /*
0003  * hwmon driver for Aquacomputer devices (D5 Next, Farbwerk, Farbwerk 360, Octo,
0004  * Quadro)
0005  *
0006  * Aquacomputer devices send HID reports (with ID 0x01) every second to report
0007  * sensor values.
0008  *
0009  * Copyright 2021 Aleksa Savic <savicaleksa83@gmail.com>
0010  * Copyright 2022 Jack Doan <me@jackdoan.com>
0011  */
0012 
0013 #include <linux/crc16.h>
0014 #include <linux/debugfs.h>
0015 #include <linux/hid.h>
0016 #include <linux/hwmon.h>
0017 #include <linux/jiffies.h>
0018 #include <linux/module.h>
0019 #include <linux/mutex.h>
0020 #include <linux/seq_file.h>
0021 #include <asm/unaligned.h>
0022 
0023 #define USB_VENDOR_ID_AQUACOMPUTER  0x0c70
0024 #define USB_PRODUCT_ID_FARBWERK     0xf00a
0025 #define USB_PRODUCT_ID_QUADRO       0xf00d
0026 #define USB_PRODUCT_ID_D5NEXT       0xf00e
0027 #define USB_PRODUCT_ID_FARBWERK360  0xf010
0028 #define USB_PRODUCT_ID_OCTO     0xf011
0029 
0030 enum kinds { d5next, farbwerk, farbwerk360, octo, quadro };
0031 
0032 static const char *const aqc_device_names[] = {
0033     [d5next] = "d5next",
0034     [farbwerk] = "farbwerk",
0035     [farbwerk360] = "farbwerk360",
0036     [octo] = "octo",
0037     [quadro] = "quadro"
0038 };
0039 
0040 #define DRIVER_NAME         "aquacomputer_d5next"
0041 
0042 #define STATUS_REPORT_ID        0x01
0043 #define STATUS_UPDATE_INTERVAL      (2 * HZ)    /* In seconds */
0044 #define SERIAL_FIRST_PART       3
0045 #define SERIAL_SECOND_PART      5
0046 #define FIRMWARE_VERSION        13
0047 
0048 #define CTRL_REPORT_ID          0x03
0049 
0050 /* The HID report that the official software always sends
0051  * after writing values, currently same for all devices
0052  */
0053 #define SECONDARY_CTRL_REPORT_ID    0x02
0054 #define SECONDARY_CTRL_REPORT_SIZE  0x0B
0055 
0056 static u8 secondary_ctrl_report[] = {
0057     0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x34, 0xC6
0058 };
0059 
0060 /* Register offsets for all Aquacomputer devices */
0061 #define AQC_TEMP_SENSOR_SIZE        0x02
0062 #define AQC_TEMP_SENSOR_DISCONNECTED    0x7FFF
0063 #define AQC_FAN_PERCENT_OFFSET      0x00
0064 #define AQC_FAN_VOLTAGE_OFFSET      0x02
0065 #define AQC_FAN_CURRENT_OFFSET      0x04
0066 #define AQC_FAN_POWER_OFFSET        0x06
0067 #define AQC_FAN_SPEED_OFFSET        0x08
0068 
0069 /* Register offsets for the D5 Next pump */
0070 #define D5NEXT_POWER_CYCLES     0x18
0071 #define D5NEXT_COOLANT_TEMP     0x57
0072 #define D5NEXT_NUM_FANS         2
0073 #define D5NEXT_NUM_SENSORS      1
0074 #define D5NEXT_PUMP_OFFSET      0x6c
0075 #define D5NEXT_FAN_OFFSET       0x5f
0076 #define D5NEXT_5V_VOLTAGE       0x39
0077 #define D5NEXT_12V_VOLTAGE      0x37
0078 #define D5NEXT_CTRL_REPORT_SIZE     0x329
0079 static u8 d5next_sensor_fan_offsets[] = { D5NEXT_PUMP_OFFSET, D5NEXT_FAN_OFFSET };
0080 
0081 /* Pump and fan speed registers in D5 Next control report (from 0-100%) */
0082 static u16 d5next_ctrl_fan_offsets[] = { 0x97, 0x42 };
0083 
0084 /* Register offsets for the Farbwerk RGB controller */
0085 #define FARBWERK_NUM_SENSORS        4
0086 #define FARBWERK_SENSOR_START       0x2f
0087 
0088 /* Register offsets for the Farbwerk 360 RGB controller */
0089 #define FARBWERK360_NUM_SENSORS     4
0090 #define FARBWERK360_SENSOR_START    0x32
0091 
0092 /* Register offsets for the Octo fan controller */
0093 #define OCTO_POWER_CYCLES       0x18
0094 #define OCTO_NUM_FANS           8
0095 #define OCTO_NUM_SENSORS        4
0096 #define OCTO_SENSOR_START       0x3D
0097 #define OCTO_CTRL_REPORT_SIZE       0x65F
0098 static u8 octo_sensor_fan_offsets[] = { 0x7D, 0x8A, 0x97, 0xA4, 0xB1, 0xBE, 0xCB, 0xD8 };
0099 
0100 /* Fan speed registers in Octo control report (from 0-100%) */
0101 static u16 octo_ctrl_fan_offsets[] = { 0x5B, 0xB0, 0x105, 0x15A, 0x1AF, 0x204, 0x259, 0x2AE };
0102 
0103 /* Register offsets for the Quadro fan controller */
0104 #define QUADRO_POWER_CYCLES     0x18
0105 #define QUADRO_NUM_FANS         4
0106 #define QUADRO_NUM_SENSORS      4
0107 #define QUADRO_SENSOR_START     0x34
0108 #define QUADRO_CTRL_REPORT_SIZE     0x3c1
0109 #define QUADRO_FLOW_SENSOR_OFFSET   0x6e
0110 static u8 quadro_sensor_fan_offsets[] = { 0x70, 0x7D, 0x8A, 0x97 };
0111 
0112 /* Fan speed registers in Quadro control report (from 0-100%) */
0113 static u16 quadro_ctrl_fan_offsets[] = { 0x37, 0x8c, 0xe1, 0x136 };
0114 
0115 /* Labels for D5 Next */
0116 static const char *const label_d5next_temp[] = {
0117     "Coolant temp"
0118 };
0119 
0120 static const char *const label_d5next_speeds[] = {
0121     "Pump speed",
0122     "Fan speed"
0123 };
0124 
0125 static const char *const label_d5next_power[] = {
0126     "Pump power",
0127     "Fan power"
0128 };
0129 
0130 static const char *const label_d5next_voltages[] = {
0131     "Pump voltage",
0132     "Fan voltage",
0133     "+5V voltage",
0134     "+12V voltage"
0135 };
0136 
0137 static const char *const label_d5next_current[] = {
0138     "Pump current",
0139     "Fan current"
0140 };
0141 
0142 /* Labels for Farbwerk, Farbwerk 360 and Octo and Quadro temperature sensors */
0143 static const char *const label_temp_sensors[] = {
0144     "Sensor 1",
0145     "Sensor 2",
0146     "Sensor 3",
0147     "Sensor 4"
0148 };
0149 
0150 /* Labels for Octo and Quadro (except speed) */
0151 static const char *const label_fan_speed[] = {
0152     "Fan 1 speed",
0153     "Fan 2 speed",
0154     "Fan 3 speed",
0155     "Fan 4 speed",
0156     "Fan 5 speed",
0157     "Fan 6 speed",
0158     "Fan 7 speed",
0159     "Fan 8 speed"
0160 };
0161 
0162 static const char *const label_fan_power[] = {
0163     "Fan 1 power",
0164     "Fan 2 power",
0165     "Fan 3 power",
0166     "Fan 4 power",
0167     "Fan 5 power",
0168     "Fan 6 power",
0169     "Fan 7 power",
0170     "Fan 8 power"
0171 };
0172 
0173 static const char *const label_fan_voltage[] = {
0174     "Fan 1 voltage",
0175     "Fan 2 voltage",
0176     "Fan 3 voltage",
0177     "Fan 4 voltage",
0178     "Fan 5 voltage",
0179     "Fan 6 voltage",
0180     "Fan 7 voltage",
0181     "Fan 8 voltage"
0182 };
0183 
0184 static const char *const label_fan_current[] = {
0185     "Fan 1 current",
0186     "Fan 2 current",
0187     "Fan 3 current",
0188     "Fan 4 current",
0189     "Fan 5 current",
0190     "Fan 6 current",
0191     "Fan 7 current",
0192     "Fan 8 current"
0193 };
0194 
0195 /* Labels for Quadro fan speeds */
0196 static const char *const label_quadro_speeds[] = {
0197     "Fan 1 speed",
0198     "Fan 2 speed",
0199     "Fan 3 speed",
0200     "Fan 4 speed",
0201     "Flow speed [dL/h]"
0202 };
0203 
0204 struct aqc_data {
0205     struct hid_device *hdev;
0206     struct device *hwmon_dev;
0207     struct dentry *debugfs;
0208     struct mutex mutex; /* Used for locking access when reading and writing PWM values */
0209     enum kinds kind;
0210     const char *name;
0211 
0212     int buffer_size;
0213     u8 *buffer;
0214     int checksum_start;
0215     int checksum_length;
0216     int checksum_offset;
0217 
0218     int num_fans;
0219     u8 *fan_sensor_offsets;
0220     u16 *fan_ctrl_offsets;
0221     int num_temp_sensors;
0222     int temp_sensor_start_offset;
0223     u16 power_cycle_count_offset;
0224     u8 flow_sensor_offset;
0225 
0226     /* General info, same across all devices */
0227     u32 serial_number[2];
0228     u16 firmware_version;
0229 
0230     /* How many times the device was powered on, if available */
0231     u32 power_cycles;
0232 
0233     /* Sensor values */
0234     s32 temp_input[4];
0235     u16 speed_input[8];
0236     u32 power_input[8];
0237     u16 voltage_input[8];
0238     u16 current_input[8];
0239 
0240     /* Label values */
0241     const char *const *temp_label;
0242     const char *const *speed_label;
0243     const char *const *power_label;
0244     const char *const *voltage_label;
0245     const char *const *current_label;
0246 
0247     unsigned long updated;
0248 };
0249 
0250 /* Converts from centi-percent */
0251 static int aqc_percent_to_pwm(u16 val)
0252 {
0253     return DIV_ROUND_CLOSEST(val * 255, 100 * 100);
0254 }
0255 
0256 /* Converts to centi-percent */
0257 static int aqc_pwm_to_percent(long val)
0258 {
0259     if (val < 0 || val > 255)
0260         return -EINVAL;
0261 
0262     return DIV_ROUND_CLOSEST(val * 100 * 100, 255);
0263 }
0264 
0265 /* Expects the mutex to be locked */
0266 static int aqc_get_ctrl_data(struct aqc_data *priv)
0267 {
0268     int ret;
0269 
0270     memset(priv->buffer, 0x00, priv->buffer_size);
0271     ret = hid_hw_raw_request(priv->hdev, CTRL_REPORT_ID, priv->buffer, priv->buffer_size,
0272                  HID_FEATURE_REPORT, HID_REQ_GET_REPORT);
0273     if (ret < 0)
0274         ret = -ENODATA;
0275 
0276     return ret;
0277 }
0278 
0279 /* Expects the mutex to be locked */
0280 static int aqc_send_ctrl_data(struct aqc_data *priv)
0281 {
0282     int ret;
0283     u16 checksum;
0284 
0285     /* Init and xorout value for CRC-16/USB is 0xffff */
0286     checksum = crc16(0xffff, priv->buffer + priv->checksum_start, priv->checksum_length);
0287     checksum ^= 0xffff;
0288 
0289     /* Place the new checksum at the end of the report */
0290     put_unaligned_be16(checksum, priv->buffer + priv->checksum_offset);
0291 
0292     /* Send the patched up report back to the device */
0293     ret = hid_hw_raw_request(priv->hdev, CTRL_REPORT_ID, priv->buffer, priv->buffer_size,
0294                  HID_FEATURE_REPORT, HID_REQ_SET_REPORT);
0295     if (ret < 0)
0296         return ret;
0297 
0298     /* The official software sends this report after every change, so do it here as well */
0299     ret = hid_hw_raw_request(priv->hdev, SECONDARY_CTRL_REPORT_ID, secondary_ctrl_report,
0300                  SECONDARY_CTRL_REPORT_SIZE, HID_FEATURE_REPORT,
0301                  HID_REQ_SET_REPORT);
0302     return ret;
0303 }
0304 
0305 /* Refreshes the control buffer and returns value at offset */
0306 static int aqc_get_ctrl_val(struct aqc_data *priv, int offset)
0307 {
0308     int ret;
0309 
0310     mutex_lock(&priv->mutex);
0311 
0312     ret = aqc_get_ctrl_data(priv);
0313     if (ret < 0)
0314         goto unlock_and_return;
0315 
0316     ret = get_unaligned_be16(priv->buffer + offset);
0317 
0318 unlock_and_return:
0319     mutex_unlock(&priv->mutex);
0320     return ret;
0321 }
0322 
0323 static int aqc_set_ctrl_val(struct aqc_data *priv, int offset, long val)
0324 {
0325     int ret;
0326 
0327     mutex_lock(&priv->mutex);
0328 
0329     ret = aqc_get_ctrl_data(priv);
0330     if (ret < 0)
0331         goto unlock_and_return;
0332 
0333     put_unaligned_be16((u16)val, priv->buffer + offset);
0334 
0335     ret = aqc_send_ctrl_data(priv);
0336 
0337 unlock_and_return:
0338     mutex_unlock(&priv->mutex);
0339     return ret;
0340 }
0341 
0342 static umode_t aqc_is_visible(const void *data, enum hwmon_sensor_types type, u32 attr, int channel)
0343 {
0344     const struct aqc_data *priv = data;
0345 
0346     switch (type) {
0347     case hwmon_temp:
0348         if (channel < priv->num_temp_sensors)
0349             return 0444;
0350         break;
0351     case hwmon_pwm:
0352         if (priv->fan_ctrl_offsets && channel < priv->num_fans) {
0353             switch (attr) {
0354             case hwmon_pwm_input:
0355                 return 0644;
0356             default:
0357                 break;
0358             }
0359         }
0360         break;
0361     case hwmon_fan:
0362         switch (priv->kind) {
0363         case quadro:
0364             /* Special case to support flow sensor */
0365             if (channel < priv->num_fans + 1)
0366                 return 0444;
0367             break;
0368         default:
0369             if (channel < priv->num_fans)
0370                 return 0444;
0371             break;
0372         }
0373         break;
0374     case hwmon_power:
0375     case hwmon_curr:
0376         if (channel < priv->num_fans)
0377             return 0444;
0378         break;
0379     case hwmon_in:
0380         switch (priv->kind) {
0381         case d5next:
0382             /* Special case to support +5V and +12V voltage sensors */
0383             if (channel < priv->num_fans + 2)
0384                 return 0444;
0385             break;
0386         default:
0387             if (channel < priv->num_fans)
0388                 return 0444;
0389             break;
0390         }
0391         break;
0392     default:
0393         break;
0394     }
0395 
0396     return 0;
0397 }
0398 
0399 static int aqc_read(struct device *dev, enum hwmon_sensor_types type, u32 attr,
0400             int channel, long *val)
0401 {
0402     int ret;
0403     struct aqc_data *priv = dev_get_drvdata(dev);
0404 
0405     if (time_after(jiffies, priv->updated + STATUS_UPDATE_INTERVAL))
0406         return -ENODATA;
0407 
0408     switch (type) {
0409     case hwmon_temp:
0410         if (priv->temp_input[channel] == -ENODATA)
0411             return -ENODATA;
0412 
0413         *val = priv->temp_input[channel];
0414         break;
0415     case hwmon_fan:
0416         *val = priv->speed_input[channel];
0417         break;
0418     case hwmon_power:
0419         *val = priv->power_input[channel];
0420         break;
0421     case hwmon_pwm:
0422         if (priv->fan_ctrl_offsets) {
0423             ret = aqc_get_ctrl_val(priv, priv->fan_ctrl_offsets[channel]);
0424             if (ret < 0)
0425                 return ret;
0426 
0427             *val = aqc_percent_to_pwm(ret);
0428         }
0429         break;
0430     case hwmon_in:
0431         *val = priv->voltage_input[channel];
0432         break;
0433     case hwmon_curr:
0434         *val = priv->current_input[channel];
0435         break;
0436     default:
0437         return -EOPNOTSUPP;
0438     }
0439 
0440     return 0;
0441 }
0442 
0443 static int aqc_read_string(struct device *dev, enum hwmon_sensor_types type, u32 attr,
0444                int channel, const char **str)
0445 {
0446     struct aqc_data *priv = dev_get_drvdata(dev);
0447 
0448     switch (type) {
0449     case hwmon_temp:
0450         *str = priv->temp_label[channel];
0451         break;
0452     case hwmon_fan:
0453         *str = priv->speed_label[channel];
0454         break;
0455     case hwmon_power:
0456         *str = priv->power_label[channel];
0457         break;
0458     case hwmon_in:
0459         *str = priv->voltage_label[channel];
0460         break;
0461     case hwmon_curr:
0462         *str = priv->current_label[channel];
0463         break;
0464     default:
0465         return -EOPNOTSUPP;
0466     }
0467 
0468     return 0;
0469 }
0470 
0471 static int aqc_write(struct device *dev, enum hwmon_sensor_types type, u32 attr, int channel,
0472              long val)
0473 {
0474     int ret, pwm_value;
0475     struct aqc_data *priv = dev_get_drvdata(dev);
0476 
0477     switch (type) {
0478     case hwmon_pwm:
0479         switch (attr) {
0480         case hwmon_pwm_input:
0481             if (priv->fan_ctrl_offsets) {
0482                 pwm_value = aqc_pwm_to_percent(val);
0483                 if (pwm_value < 0)
0484                     return pwm_value;
0485 
0486                 ret = aqc_set_ctrl_val(priv, priv->fan_ctrl_offsets[channel],
0487                                pwm_value);
0488                 if (ret < 0)
0489                     return ret;
0490             }
0491             break;
0492         default:
0493             break;
0494         }
0495         break;
0496     default:
0497         return -EOPNOTSUPP;
0498     }
0499 
0500     return 0;
0501 }
0502 
0503 static const struct hwmon_ops aqc_hwmon_ops = {
0504     .is_visible = aqc_is_visible,
0505     .read = aqc_read,
0506     .read_string = aqc_read_string,
0507     .write = aqc_write
0508 };
0509 
0510 static const struct hwmon_channel_info *aqc_info[] = {
0511     HWMON_CHANNEL_INFO(temp,
0512                HWMON_T_INPUT | HWMON_T_LABEL,
0513                HWMON_T_INPUT | HWMON_T_LABEL,
0514                HWMON_T_INPUT | HWMON_T_LABEL,
0515                HWMON_T_INPUT | HWMON_T_LABEL),
0516     HWMON_CHANNEL_INFO(fan,
0517                HWMON_F_INPUT | HWMON_F_LABEL,
0518                HWMON_F_INPUT | HWMON_F_LABEL,
0519                HWMON_F_INPUT | HWMON_F_LABEL,
0520                HWMON_F_INPUT | HWMON_F_LABEL,
0521                HWMON_F_INPUT | HWMON_F_LABEL,
0522                HWMON_F_INPUT | HWMON_F_LABEL,
0523                HWMON_F_INPUT | HWMON_F_LABEL,
0524                HWMON_F_INPUT | HWMON_F_LABEL),
0525     HWMON_CHANNEL_INFO(power,
0526                HWMON_P_INPUT | HWMON_P_LABEL,
0527                HWMON_P_INPUT | HWMON_P_LABEL,
0528                HWMON_P_INPUT | HWMON_P_LABEL,
0529                HWMON_P_INPUT | HWMON_P_LABEL,
0530                HWMON_P_INPUT | HWMON_P_LABEL,
0531                HWMON_P_INPUT | HWMON_P_LABEL,
0532                HWMON_P_INPUT | HWMON_P_LABEL,
0533                HWMON_P_INPUT | HWMON_P_LABEL),
0534     HWMON_CHANNEL_INFO(pwm,
0535                HWMON_PWM_INPUT,
0536                HWMON_PWM_INPUT,
0537                HWMON_PWM_INPUT,
0538                HWMON_PWM_INPUT,
0539                HWMON_PWM_INPUT,
0540                HWMON_PWM_INPUT,
0541                HWMON_PWM_INPUT,
0542                HWMON_PWM_INPUT),
0543     HWMON_CHANNEL_INFO(in,
0544                HWMON_I_INPUT | HWMON_I_LABEL,
0545                HWMON_I_INPUT | HWMON_I_LABEL,
0546                HWMON_I_INPUT | HWMON_I_LABEL,
0547                HWMON_I_INPUT | HWMON_I_LABEL,
0548                HWMON_I_INPUT | HWMON_I_LABEL,
0549                HWMON_I_INPUT | HWMON_I_LABEL,
0550                HWMON_I_INPUT | HWMON_I_LABEL,
0551                HWMON_I_INPUT | HWMON_I_LABEL),
0552     HWMON_CHANNEL_INFO(curr,
0553                HWMON_C_INPUT | HWMON_C_LABEL,
0554                HWMON_C_INPUT | HWMON_C_LABEL,
0555                HWMON_C_INPUT | HWMON_C_LABEL,
0556                HWMON_C_INPUT | HWMON_C_LABEL,
0557                HWMON_C_INPUT | HWMON_C_LABEL,
0558                HWMON_C_INPUT | HWMON_C_LABEL,
0559                HWMON_C_INPUT | HWMON_C_LABEL,
0560                HWMON_C_INPUT | HWMON_C_LABEL),
0561     NULL
0562 };
0563 
0564 static const struct hwmon_chip_info aqc_chip_info = {
0565     .ops = &aqc_hwmon_ops,
0566     .info = aqc_info,
0567 };
0568 
0569 static int aqc_raw_event(struct hid_device *hdev, struct hid_report *report, u8 *data, int size)
0570 {
0571     int i, sensor_value;
0572     struct aqc_data *priv;
0573 
0574     if (report->id != STATUS_REPORT_ID)
0575         return 0;
0576 
0577     priv = hid_get_drvdata(hdev);
0578 
0579     /* Info provided with every report */
0580     priv->serial_number[0] = get_unaligned_be16(data + SERIAL_FIRST_PART);
0581     priv->serial_number[1] = get_unaligned_be16(data + SERIAL_SECOND_PART);
0582     priv->firmware_version = get_unaligned_be16(data + FIRMWARE_VERSION);
0583 
0584     /* Temperature sensor readings */
0585     for (i = 0; i < priv->num_temp_sensors; i++) {
0586         sensor_value = get_unaligned_be16(data +
0587                           priv->temp_sensor_start_offset +
0588                           i * AQC_TEMP_SENSOR_SIZE);
0589         if (sensor_value == AQC_TEMP_SENSOR_DISCONNECTED)
0590             priv->temp_input[i] = -ENODATA;
0591         else
0592             priv->temp_input[i] = sensor_value * 10;
0593     }
0594 
0595     /* Fan speed and related readings */
0596     for (i = 0; i < priv->num_fans; i++) {
0597         priv->speed_input[i] =
0598             get_unaligned_be16(data + priv->fan_sensor_offsets[i] + AQC_FAN_SPEED_OFFSET);
0599         priv->power_input[i] =
0600             get_unaligned_be16(data + priv->fan_sensor_offsets[i] +
0601                        AQC_FAN_POWER_OFFSET) * 10000;
0602         priv->voltage_input[i] =
0603             get_unaligned_be16(data + priv->fan_sensor_offsets[i] +
0604                        AQC_FAN_VOLTAGE_OFFSET) * 10;
0605         priv->current_input[i] =
0606             get_unaligned_be16(data + priv->fan_sensor_offsets[i] + AQC_FAN_CURRENT_OFFSET);
0607     }
0608 
0609     if (priv->power_cycle_count_offset != 0)
0610         priv->power_cycles = get_unaligned_be32(data + priv->power_cycle_count_offset);
0611 
0612     /* Special-case sensor readings */
0613     switch (priv->kind) {
0614     case d5next:
0615         priv->voltage_input[2] = get_unaligned_be16(data + D5NEXT_5V_VOLTAGE) * 10;
0616         priv->voltage_input[3] = get_unaligned_be16(data + D5NEXT_12V_VOLTAGE) * 10;
0617         break;
0618     case quadro:
0619         priv->speed_input[4] = get_unaligned_be16(data + priv->flow_sensor_offset);
0620         break;
0621     default:
0622         break;
0623     }
0624 
0625     priv->updated = jiffies;
0626 
0627     return 0;
0628 }
0629 
0630 #ifdef CONFIG_DEBUG_FS
0631 
0632 static int serial_number_show(struct seq_file *seqf, void *unused)
0633 {
0634     struct aqc_data *priv = seqf->private;
0635 
0636     seq_printf(seqf, "%05u-%05u\n", priv->serial_number[0], priv->serial_number[1]);
0637 
0638     return 0;
0639 }
0640 DEFINE_SHOW_ATTRIBUTE(serial_number);
0641 
0642 static int firmware_version_show(struct seq_file *seqf, void *unused)
0643 {
0644     struct aqc_data *priv = seqf->private;
0645 
0646     seq_printf(seqf, "%u\n", priv->firmware_version);
0647 
0648     return 0;
0649 }
0650 DEFINE_SHOW_ATTRIBUTE(firmware_version);
0651 
0652 static int power_cycles_show(struct seq_file *seqf, void *unused)
0653 {
0654     struct aqc_data *priv = seqf->private;
0655 
0656     seq_printf(seqf, "%u\n", priv->power_cycles);
0657 
0658     return 0;
0659 }
0660 DEFINE_SHOW_ATTRIBUTE(power_cycles);
0661 
0662 static void aqc_debugfs_init(struct aqc_data *priv)
0663 {
0664     char name[64];
0665 
0666     scnprintf(name, sizeof(name), "%s_%s-%s", "aquacomputer", priv->name,
0667           dev_name(&priv->hdev->dev));
0668 
0669     priv->debugfs = debugfs_create_dir(name, NULL);
0670     debugfs_create_file("serial_number", 0444, priv->debugfs, priv, &serial_number_fops);
0671     debugfs_create_file("firmware_version", 0444, priv->debugfs, priv, &firmware_version_fops);
0672 
0673     if (priv->power_cycle_count_offset != 0)
0674         debugfs_create_file("power_cycles", 0444, priv->debugfs, priv, &power_cycles_fops);
0675 }
0676 
0677 #else
0678 
0679 static void aqc_debugfs_init(struct aqc_data *priv)
0680 {
0681 }
0682 
0683 #endif
0684 
0685 static int aqc_probe(struct hid_device *hdev, const struct hid_device_id *id)
0686 {
0687     struct aqc_data *priv;
0688     int ret;
0689 
0690     priv = devm_kzalloc(&hdev->dev, sizeof(*priv), GFP_KERNEL);
0691     if (!priv)
0692         return -ENOMEM;
0693 
0694     priv->hdev = hdev;
0695     hid_set_drvdata(hdev, priv);
0696 
0697     priv->updated = jiffies - STATUS_UPDATE_INTERVAL;
0698 
0699     ret = hid_parse(hdev);
0700     if (ret)
0701         return ret;
0702 
0703     ret = hid_hw_start(hdev, HID_CONNECT_HIDRAW);
0704     if (ret)
0705         return ret;
0706 
0707     ret = hid_hw_open(hdev);
0708     if (ret)
0709         goto fail_and_stop;
0710 
0711     switch (hdev->product) {
0712     case USB_PRODUCT_ID_D5NEXT:
0713         priv->kind = d5next;
0714 
0715         priv->num_fans = D5NEXT_NUM_FANS;
0716         priv->fan_sensor_offsets = d5next_sensor_fan_offsets;
0717         priv->fan_ctrl_offsets = d5next_ctrl_fan_offsets;
0718         priv->num_temp_sensors = D5NEXT_NUM_SENSORS;
0719         priv->temp_sensor_start_offset = D5NEXT_COOLANT_TEMP;
0720         priv->power_cycle_count_offset = D5NEXT_POWER_CYCLES;
0721         priv->buffer_size = D5NEXT_CTRL_REPORT_SIZE;
0722 
0723         priv->temp_label = label_d5next_temp;
0724         priv->speed_label = label_d5next_speeds;
0725         priv->power_label = label_d5next_power;
0726         priv->voltage_label = label_d5next_voltages;
0727         priv->current_label = label_d5next_current;
0728         break;
0729     case USB_PRODUCT_ID_FARBWERK:
0730         priv->kind = farbwerk;
0731 
0732         priv->num_fans = 0;
0733         priv->num_temp_sensors = FARBWERK_NUM_SENSORS;
0734         priv->temp_sensor_start_offset = FARBWERK_SENSOR_START;
0735         priv->temp_label = label_temp_sensors;
0736         break;
0737     case USB_PRODUCT_ID_FARBWERK360:
0738         priv->kind = farbwerk360;
0739 
0740         priv->num_fans = 0;
0741         priv->num_temp_sensors = FARBWERK360_NUM_SENSORS;
0742         priv->temp_sensor_start_offset = FARBWERK360_SENSOR_START;
0743         priv->temp_label = label_temp_sensors;
0744         break;
0745     case USB_PRODUCT_ID_OCTO:
0746         priv->kind = octo;
0747 
0748         priv->num_fans = OCTO_NUM_FANS;
0749         priv->fan_sensor_offsets = octo_sensor_fan_offsets;
0750         priv->fan_ctrl_offsets = octo_ctrl_fan_offsets;
0751         priv->num_temp_sensors = OCTO_NUM_SENSORS;
0752         priv->temp_sensor_start_offset = OCTO_SENSOR_START;
0753         priv->power_cycle_count_offset = OCTO_POWER_CYCLES;
0754         priv->buffer_size = OCTO_CTRL_REPORT_SIZE;
0755 
0756         priv->temp_label = label_temp_sensors;
0757         priv->speed_label = label_fan_speed;
0758         priv->power_label = label_fan_power;
0759         priv->voltage_label = label_fan_voltage;
0760         priv->current_label = label_fan_current;
0761         break;
0762     case USB_PRODUCT_ID_QUADRO:
0763         priv->kind = quadro;
0764 
0765         priv->num_fans = QUADRO_NUM_FANS;
0766         priv->fan_sensor_offsets = quadro_sensor_fan_offsets;
0767         priv->fan_ctrl_offsets = quadro_ctrl_fan_offsets;
0768         priv->num_temp_sensors = QUADRO_NUM_SENSORS;
0769         priv->temp_sensor_start_offset = QUADRO_SENSOR_START;
0770         priv->power_cycle_count_offset = QUADRO_POWER_CYCLES;
0771         priv->buffer_size = QUADRO_CTRL_REPORT_SIZE;
0772         priv->flow_sensor_offset = QUADRO_FLOW_SENSOR_OFFSET;
0773 
0774         priv->temp_label = label_temp_sensors;
0775         priv->speed_label = label_quadro_speeds;
0776         priv->power_label = label_fan_power;
0777         priv->voltage_label = label_fan_voltage;
0778         priv->current_label = label_fan_current;
0779         break;
0780     default:
0781         break;
0782     }
0783 
0784     if (priv->buffer_size != 0) {
0785         priv->checksum_start = 0x01;
0786         priv->checksum_length = priv->buffer_size - 3;
0787         priv->checksum_offset = priv->buffer_size - 2;
0788     }
0789 
0790     priv->name = aqc_device_names[priv->kind];
0791 
0792     priv->buffer = devm_kzalloc(&hdev->dev, priv->buffer_size, GFP_KERNEL);
0793     if (!priv->buffer) {
0794         ret = -ENOMEM;
0795         goto fail_and_close;
0796     }
0797 
0798     mutex_init(&priv->mutex);
0799 
0800     priv->hwmon_dev = hwmon_device_register_with_info(&hdev->dev, priv->name, priv,
0801                               &aqc_chip_info, NULL);
0802 
0803     if (IS_ERR(priv->hwmon_dev)) {
0804         ret = PTR_ERR(priv->hwmon_dev);
0805         goto fail_and_close;
0806     }
0807 
0808     aqc_debugfs_init(priv);
0809 
0810     return 0;
0811 
0812 fail_and_close:
0813     hid_hw_close(hdev);
0814 fail_and_stop:
0815     hid_hw_stop(hdev);
0816     return ret;
0817 }
0818 
0819 static void aqc_remove(struct hid_device *hdev)
0820 {
0821     struct aqc_data *priv = hid_get_drvdata(hdev);
0822 
0823     debugfs_remove_recursive(priv->debugfs);
0824     hwmon_device_unregister(priv->hwmon_dev);
0825 
0826     hid_hw_close(hdev);
0827     hid_hw_stop(hdev);
0828 }
0829 
0830 static const struct hid_device_id aqc_table[] = {
0831     { HID_USB_DEVICE(USB_VENDOR_ID_AQUACOMPUTER, USB_PRODUCT_ID_D5NEXT) },
0832     { HID_USB_DEVICE(USB_VENDOR_ID_AQUACOMPUTER, USB_PRODUCT_ID_FARBWERK) },
0833     { HID_USB_DEVICE(USB_VENDOR_ID_AQUACOMPUTER, USB_PRODUCT_ID_FARBWERK360) },
0834     { HID_USB_DEVICE(USB_VENDOR_ID_AQUACOMPUTER, USB_PRODUCT_ID_OCTO) },
0835     { HID_USB_DEVICE(USB_VENDOR_ID_AQUACOMPUTER, USB_PRODUCT_ID_QUADRO) },
0836     { }
0837 };
0838 
0839 MODULE_DEVICE_TABLE(hid, aqc_table);
0840 
0841 static struct hid_driver aqc_driver = {
0842     .name = DRIVER_NAME,
0843     .id_table = aqc_table,
0844     .probe = aqc_probe,
0845     .remove = aqc_remove,
0846     .raw_event = aqc_raw_event,
0847 };
0848 
0849 static int __init aqc_init(void)
0850 {
0851     return hid_register_driver(&aqc_driver);
0852 }
0853 
0854 static void __exit aqc_exit(void)
0855 {
0856     hid_unregister_driver(&aqc_driver);
0857 }
0858 
0859 /* Request to initialize after the HID bus to ensure it's not being loaded before */
0860 late_initcall(aqc_init);
0861 module_exit(aqc_exit);
0862 
0863 MODULE_LICENSE("GPL");
0864 MODULE_AUTHOR("Aleksa Savic <savicaleksa83@gmail.com>");
0865 MODULE_AUTHOR("Jack Doan <me@jackdoan.com>");
0866 MODULE_DESCRIPTION("Hwmon driver for Aquacomputer devices");