0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
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)
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
0051
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
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
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
0082 static u16 d5next_ctrl_fan_offsets[] = { 0x97, 0x42 };
0083
0084
0085 #define FARBWERK_NUM_SENSORS 4
0086 #define FARBWERK_SENSOR_START 0x2f
0087
0088
0089 #define FARBWERK360_NUM_SENSORS 4
0090 #define FARBWERK360_SENSOR_START 0x32
0091
0092
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
0101 static u16 octo_ctrl_fan_offsets[] = { 0x5B, 0xB0, 0x105, 0x15A, 0x1AF, 0x204, 0x259, 0x2AE };
0102
0103
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
0113 static u16 quadro_ctrl_fan_offsets[] = { 0x37, 0x8c, 0xe1, 0x136 };
0114
0115
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
0143 static const char *const label_temp_sensors[] = {
0144 "Sensor 1",
0145 "Sensor 2",
0146 "Sensor 3",
0147 "Sensor 4"
0148 };
0149
0150
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
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;
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
0227 u32 serial_number[2];
0228 u16 firmware_version;
0229
0230
0231 u32 power_cycles;
0232
0233
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
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
0251 static int aqc_percent_to_pwm(u16 val)
0252 {
0253 return DIV_ROUND_CLOSEST(val * 255, 100 * 100);
0254 }
0255
0256
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
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
0280 static int aqc_send_ctrl_data(struct aqc_data *priv)
0281 {
0282 int ret;
0283 u16 checksum;
0284
0285
0286 checksum = crc16(0xffff, priv->buffer + priv->checksum_start, priv->checksum_length);
0287 checksum ^= 0xffff;
0288
0289
0290 put_unaligned_be16(checksum, priv->buffer + priv->checksum_offset);
0291
0292
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
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
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
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
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
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
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
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
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
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");