#include "aio.h" #include "log.h" #include static const uint8_t buf_size = 32; // needs 32 bc of overflow issue on these aios? static void aio_post(libusb_device_handle *dev, uint8_t *req, const int req_len, uint8_t *resp, const int resp_len) { libusb_bulk_transfer(dev, 0x01, req, req_len, NULL, 1000); libusb_bulk_transfer(dev, 0x81, resp, resp_len, NULL, 1000); } static float aio_get_water_temp(libusb_device_handle* aio) { uint8_t req = 0xa9; uint8_t resp[buf_size]; aio_post(aio, &req, sizeof(req), resp, 6); return (float)resp[3] + (float)resp[4] / 10.0f; } static uint16_t aio_get_pump_speed(libusb_device_handle* aio) { uint8_t req = 0x31; uint8_t resp[buf_size]; aio_post(aio, &req, sizeof(req), resp, 5); return resp[3] << 8 | resp[4]; } static enum aio_pump_mode_t aio_get_pump_mode(libusb_device_handle* aio) { uint8_t req = 0x33; uint8_t resp[buf_size]; aio_post(aio, &req, sizeof(req), resp, 4); return (enum aio_pump_mode_t)resp[3]; } static void aio_get_fan_speed(libusb_device_handle* aio, uint16_t *speeds) { uint8_t req[2] = {0x41}; uint8_t resp[buf_size]; for (uint8_t i = 0; i < 2; i++) { req[1] = i; aio_post(aio, req, sizeof(req), resp, 6); speeds[i] = resp[4] << 8 | resp[5]; } } void aio_detect(struct aio_t *aio) { libusb_init(NULL); aio->handle = libusb_open_device_with_vid_pid(NULL, CORSAIR_VID, AIO_PID); if (aio->handle == NULL) { applog(LOG_ERR, "Can't open AIO USB device %x:%x", CORSAIR_VID, AIO_PID); return; } /* detach kernel driver if attached */ if (libusb_kernel_driver_active(aio->handle, 0)) libusb_detach_kernel_driver(aio->handle, 0); const int ret = libusb_claim_interface(aio->handle, 0); if (ret == 0) applog(LOG_INF, "found Corsair AIO device at %04x:%04x", CORSAIR_VID, AIO_PID); else applog(LOG_ERR, "failed to claim AIO device"); } void aio_update(struct aio_t *aio) { if (aio->handle == NULL) return; aio->water_temp = aio_get_water_temp(aio->handle); aio->pump_speed = aio_get_pump_speed(aio->handle); aio->mode = aio_get_pump_mode(aio->handle); aio_get_fan_speed(aio->handle, aio->fan_speed); } void aio_close(const struct aio_t *aio) { libusb_release_interface(aio->handle, 0); libusb_attach_kernel_driver(aio->handle, 0); /* reattach so liquidctl still works */ libusb_close(aio->handle); libusb_exit(NULL); applog(LOG_INF, "AIO device closed"); }