diff --git a/OpenRGB.cpp b/OpenRGB.cpp index 2682da83..07fae9c2 100644 --- a/OpenRGB.cpp +++ b/OpenRGB.cpp @@ -88,6 +88,33 @@ void DetectNuvotonI2CBusses() } /* DetectNuvotonI2CBusses() */ +/******************************************************************************************\ +* * +* DetectNvAPII2CBusses (Windows) * +* * +* Detects available NVidia NvAPI I2C adapters and enumerates * +* i2c_smbus_interface objects for them. Only enumerates the first bus for each GPU * +* * +\******************************************************************************************/ + +void DetectNvAPII2CBusses() +{ + static NV_PHYSICAL_GPU_HANDLE gpu_handles[64]; + static NV_S32 gpu_count = 0; + + NV_STATUS initialize = NvAPI_Initialize(); + + NvAPI_EnumPhysicalGPUs(gpu_handles, &gpu_count); + + for(NV_S32 gpu_idx = 0; gpu_idx < gpu_count; gpu_idx++) + { + i2c_smbus_nvapi * nvapi_bus = new i2c_smbus_nvapi(gpu_handles[gpu_idx]); + + sprintf(nvapi_bus->device_name, "NVidia NvAPI I2C on GPU %d", gpu_idx); + + busses.push_back(nvapi_bus); + } +} /* DetectNvAPII2CBusses() */ /******************************************************************************************\ * * @@ -171,9 +198,9 @@ void DetectI2CBusses() // Detect Nuvoton Super IO SMBus adapters DetectNuvotonI2CBusses(); - i2c_smbus_nvapi * nvapi_bus = new i2c_smbus_nvapi(); - strcpy(nvapi_bus->device_name, "NVAPI Bus"); - busses.push_back(nvapi_bus); + // Detect NVidia NvAPI I2C adapters + DetectNvAPII2CBusses(); + } /* DetectI2CBusses() */ #else /* WIN32 */ diff --git a/OpenRGB.pro b/OpenRGB.pro index aad78b7a..7e0205b0 100644 --- a/OpenRGB.pro +++ b/OpenRGB.pro @@ -209,11 +209,11 @@ win32:INCLUDEPATH += \ wmi/ \ win32:SOURCES += \ + dependencies/NVFC/nvapi.cpp \ i2c_smbus/i2c_smbus_i801.cpp \ i2c_smbus/i2c_smbus_nct6775.cpp \ i2c_smbus/i2c_smbus_nvapi.cpp \ i2c_smbus/i2c_smbus_piix4.cpp \ - i2c_smbus/nvapi.cpp \ serial_port/find_usb_serial_port_win.cpp \ wmi/wmi.cpp \ RGBController/OpenRazerWindowsDetect.cpp \ @@ -221,8 +221,10 @@ win32:SOURCES += \ win32:HEADERS += \ dependencies/inpout32_1501/Win32/inpout32.h \ + dependencies/NVFC/nvapi.h \ i2c_smbus/i2c_smbus_i801.h \ i2c_smbus/i2c_smbus_nct6775.h \ + i2c_smbus/i2c_smbus_nvapi.h \ i2c_smbus/i2c_smbus_piix4.h \ wmi/wmi.h \ RGBController/RGBController_OpenRazerWindows.h \ diff --git a/i2c_smbus/nvapi.cpp b/dependencies/NVFC/nvapi.cpp similarity index 100% rename from i2c_smbus/nvapi.cpp rename to dependencies/NVFC/nvapi.cpp diff --git a/i2c_smbus/nvapi.h b/dependencies/NVFC/nvapi.h similarity index 100% rename from i2c_smbus/nvapi.h rename to dependencies/NVFC/nvapi.h diff --git a/i2c_smbus/i2c_smbus_nvapi.cpp b/i2c_smbus/i2c_smbus_nvapi.cpp index d63279d8..1d2273b5 100644 --- a/i2c_smbus/i2c_smbus_nvapi.cpp +++ b/i2c_smbus/i2c_smbus_nvapi.cpp @@ -7,16 +7,10 @@ \*-----------------------------------------*/ #include "i2c_smbus_nvapi.h" -#include "nvapi.h" -static NV_PHYSICAL_GPU_HANDLE gpu_handles[64]; -static NV_S32 gpu_count = 0; - -i2c_smbus_nvapi::i2c_smbus_nvapi() +i2c_smbus_nvapi::i2c_smbus_nvapi(NV_PHYSICAL_GPU_HANDLE handle) { - NV_STATUS initialize = NvAPI_Initialize(); - - NvAPI_EnumPhysicalGPUs(gpu_handles, &gpu_count); + this->handle = handle; } s32 i2c_smbus_nvapi::i2c_smbus_xfer(u8 addr, char read_write, u8 command, int size, i2c_smbus_data* data) @@ -27,61 +21,81 @@ s32 i2c_smbus_nvapi::i2c_smbus_xfer(u8 addr, char read_write, u8 command, int si uint8_t data_buf[8]; uint8_t chip_addr; + // Set up chip register address to command, one byte in length chip_addr = command; - i2c_data.i2c_reg_address = &chip_addr; i2c_data.reg_addr_size = 1; + // Set up data buffer, zero bytes in length i2c_data.data = data_buf; i2c_data.size = 0; + // Always use GPU port 1 - this is where RGB controllers are attached i2c_data.is_ddc_port = 0; i2c_data.port_id = 1; i2c_data.is_port_id_set = 1; + // Use default speed i2c_data.i2c_speed = 0xFFFF; i2c_data.i2c_speed_khz = NV_I2C_SPEED::NVAPI_I2C_SPEED_DEFAULT; - + // Load device address i2c_data.i2c_dev_address = (addr << 1) | read_write; switch (size) { case I2C_SMBUS_QUICK: + // This is not supported by the driver it seems i2c_data.reg_addr_size = 0; i2c_data.size = 0; break; + case I2C_SMBUS_BYTE: + // One byte of data with no register address i2c_data.reg_addr_size = 0; data_buf[0] = command; i2c_data.size = 1; break; + case I2C_SMBUS_BYTE_DATA: + // One byte of data with one byte of register address data_buf[0] = data->byte; i2c_data.size = 1; break; + case I2C_SMBUS_WORD_DATA: + // One word of data with one byte of register address data_buf[0] = (data->word & 0x00ff); data_buf[1] = (data->word & 0xff00) >> 8; i2c_data.size = 2; break; + + // Not supported case I2C_SMBUS_BLOCK_DATA: - chip_addr = command; - i2c_data.size = 0; + return -1; break; + default: return -1; } + // Perform read or write if(read_write == I2C_SMBUS_WRITE) { - ret = NvAPI_I2CWriteEx(gpu_handles[0], &i2c_data, &unknown); + ret = NvAPI_I2CWriteEx(handle, &i2c_data, &unknown); } else { - ret = NvAPI_I2CReadEx(gpu_handles[0], &i2c_data, &unknown); + ret = NvAPI_I2CReadEx(handle, &i2c_data, &unknown); - data->byte = i2c_data.data[0]; + if(i2c_data.size == 1) + { + data->byte = i2c_data.data[0]; + } + else + { + data->word = (i2c_data.data[0] | (i2c_data.data[1] << 8)); + } } return(ret); diff --git a/i2c_smbus/i2c_smbus_nvapi.h b/i2c_smbus/i2c_smbus_nvapi.h index c0284ce6..269da746 100644 --- a/i2c_smbus/i2c_smbus_nvapi.h +++ b/i2c_smbus/i2c_smbus_nvapi.h @@ -8,14 +8,17 @@ \*-----------------------------------------*/ #include "i2c_smbus.h" +#include "nvapi.h" #pragma once class i2c_smbus_nvapi : public i2c_smbus_interface { public: - i2c_smbus_nvapi(); + i2c_smbus_nvapi(NV_PHYSICAL_GPU_HANDLE handle); private: s32 i2c_smbus_xfer(u8 addr, char read_write, u8 command, int size, i2c_smbus_data* data); -}; \ No newline at end of file + + NV_PHYSICAL_GPU_HANDLE handle; +};