Publish LumaOps source
This commit is contained in:
@@ -0,0 +1,41 @@
|
||||
/*---------------------------------------------------------*\
|
||||
| ENESMBusInterface.h |
|
||||
| |
|
||||
| ENE SMBus interface |
|
||||
| |
|
||||
| Adam Honse (CalcProgrammer1) 21 Nov 2021 |
|
||||
| |
|
||||
| This file is part of the OpenRGB project |
|
||||
| SPDX-License-Identifier: GPL-2.0-or-later |
|
||||
\*---------------------------------------------------------*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <string>
|
||||
|
||||
typedef unsigned short ene_register;
|
||||
typedef unsigned char ene_dev_id;
|
||||
typedef unsigned int ene_interface_type;
|
||||
|
||||
/*-----------------------------------------*\
|
||||
| Known interface types |
|
||||
\*-----------------------------------------*/
|
||||
enum
|
||||
{
|
||||
ENE_INTERFACE_TYPE_I2C_SMBUS,
|
||||
ENE_INTERFACE_TYPE_SPECTRIX_S40G,
|
||||
ENE_INTERFACE_TYPE_ROG_ARION,
|
||||
};
|
||||
|
||||
class ENESMBusInterface
|
||||
{
|
||||
public:
|
||||
virtual ~ENESMBusInterface() = default;
|
||||
|
||||
virtual ene_interface_type GetInterfaceType() = 0;
|
||||
virtual std::string GetLocation() = 0;
|
||||
virtual int GetMaxBlock() = 0;
|
||||
virtual unsigned char ENERegisterRead(ene_dev_id dev, ene_register reg) = 0;
|
||||
virtual void ENERegisterWrite(ene_dev_id dev, ene_register reg, unsigned char val) = 0;
|
||||
virtual void ENERegisterWriteBlock(ene_dev_id dev, ene_register reg, unsigned char * data, unsigned char sz) = 0;
|
||||
};
|
||||
@@ -0,0 +1,96 @@
|
||||
/*---------------------------------------------------------*\
|
||||
| ENESMBusInterface_ROGArion.cpp |
|
||||
| |
|
||||
| ENE SMBus interface for ASUS ROG Arion |
|
||||
| |
|
||||
| Adam Honse (CalcProgrammer1) 17 Sep 2023 |
|
||||
| |
|
||||
| This file is part of the OpenRGB project |
|
||||
| SPDX-License-Identifier: GPL-2.0-or-later |
|
||||
\*---------------------------------------------------------*/
|
||||
|
||||
#include "ENESMBusInterface_ROGArion.h"
|
||||
|
||||
ENESMBusInterface_ROGArion::ENESMBusInterface_ROGArion(scsi_device* dev_handle, char* dev_path)
|
||||
{
|
||||
scsi_dev = dev_handle;
|
||||
path = dev_path;
|
||||
}
|
||||
|
||||
ENESMBusInterface_ROGArion::~ENESMBusInterface_ROGArion()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
ene_interface_type ENESMBusInterface_ROGArion::GetInterfaceType()
|
||||
{
|
||||
return(ENE_INTERFACE_TYPE_ROG_ARION);
|
||||
}
|
||||
|
||||
std::string ENESMBusInterface_ROGArion::GetLocation()
|
||||
{
|
||||
std::string str(path.begin(), path.end());
|
||||
return("SCSI: " + str);
|
||||
}
|
||||
|
||||
int ENESMBusInterface_ROGArion::GetMaxBlock()
|
||||
{
|
||||
return(24);
|
||||
}
|
||||
|
||||
unsigned char ENESMBusInterface_ROGArion::ENERegisterRead(ene_dev_id /*dev*/, ene_register /*reg*/)
|
||||
{
|
||||
/*-----------------------------------------------------------------------------*\
|
||||
| This interface does not support reading |
|
||||
\*-----------------------------------------------------------------------------*/
|
||||
return( 0 );
|
||||
}
|
||||
|
||||
void ENESMBusInterface_ROGArion::ENERegisterWrite(ene_dev_id /*dev*/, ene_register reg, unsigned char val)
|
||||
{
|
||||
SendPacket(reg, &val, sizeof(unsigned char));
|
||||
}
|
||||
|
||||
void ENESMBusInterface_ROGArion::ENERegisterWriteBlock(ene_dev_id /*dev*/, ene_register reg, unsigned char * data, unsigned char sz)
|
||||
{
|
||||
SendPacket(reg, data, sz);
|
||||
}
|
||||
|
||||
void ENESMBusInterface_ROGArion::SendPacket
|
||||
(
|
||||
ene_register reg,
|
||||
unsigned char * packet,
|
||||
unsigned char packet_sz
|
||||
)
|
||||
{
|
||||
/*-----------------------------------------------------------------------------*\
|
||||
| Create buffer to hold CDB |
|
||||
\*-----------------------------------------------------------------------------*/
|
||||
unsigned char cdb[16] = {0};
|
||||
cdb[0] = 0xEC;
|
||||
cdb[1] = 0x41;
|
||||
cdb[2] = 0x53;
|
||||
cdb[3] = ((reg >> 8) & 0x00FF);
|
||||
cdb[4] = ( reg & 0x00FF );
|
||||
cdb[5] = 0x00;
|
||||
cdb[6] = 0x00;
|
||||
cdb[7] = 0x00;
|
||||
cdb[8] = 0x00;
|
||||
cdb[9] = 0x00;
|
||||
cdb[10] = 0x00;
|
||||
cdb[11] = 0x00;
|
||||
cdb[12] = 0x00;
|
||||
cdb[13] = packet_sz;
|
||||
cdb[14] = 0x00;
|
||||
cdb[15] = 0x00;
|
||||
|
||||
/*-----------------------------------------------------------------------------*\
|
||||
| Create buffer to hold sense data |
|
||||
\*-----------------------------------------------------------------------------*/
|
||||
unsigned char sense[32] = {0};
|
||||
|
||||
/*-----------------------------------------------------------------------------*\
|
||||
| Write SCSI packet |
|
||||
\*-----------------------------------------------------------------------------*/
|
||||
scsi_write(scsi_dev, packet, packet_sz, cdb, 16, sense, 32);
|
||||
}
|
||||
@@ -0,0 +1,40 @@
|
||||
/*---------------------------------------------------------*\
|
||||
| ENESMBusInterface_ROGArion.h |
|
||||
| |
|
||||
| ENE SMBus interface for ASUS ROG Arion |
|
||||
| |
|
||||
| Adam Honse (CalcProgrammer1) 17 Sep 2023 |
|
||||
| |
|
||||
| This file is part of the OpenRGB project |
|
||||
| SPDX-License-Identifier: GPL-2.0-or-later |
|
||||
\*---------------------------------------------------------*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "ENESMBusInterface.h"
|
||||
#include "scsiapi.h"
|
||||
|
||||
class ENESMBusInterface_ROGArion : public ENESMBusInterface
|
||||
{
|
||||
public:
|
||||
ENESMBusInterface_ROGArion(scsi_device* dev_handle, char* dev_path);
|
||||
~ENESMBusInterface_ROGArion();
|
||||
|
||||
ene_interface_type GetInterfaceType();
|
||||
std::string GetLocation();
|
||||
int GetMaxBlock();
|
||||
unsigned char ENERegisterRead(ene_dev_id dev, ene_register reg);
|
||||
void ENERegisterWrite(ene_dev_id dev, ene_register reg, unsigned char val);
|
||||
void ENERegisterWriteBlock(ene_dev_id dev, ene_register reg, unsigned char * data, unsigned char sz);
|
||||
|
||||
private:
|
||||
scsi_device* scsi_dev;
|
||||
std::string path;
|
||||
|
||||
void SendPacket
|
||||
(
|
||||
ene_register reg,
|
||||
unsigned char * packet,
|
||||
unsigned char packet_sz
|
||||
);
|
||||
};
|
||||
+215
@@ -0,0 +1,215 @@
|
||||
/*---------------------------------------------------------*\
|
||||
| ENESMBusInterface_SpectrixS40G_Linux.cpp |
|
||||
| |
|
||||
| ENE SMBus interface for XPG Spectrix S40G (Linux) |
|
||||
| |
|
||||
| Adam Honse (CalcProgrammer1) 21 Nov 2021 |
|
||||
| |
|
||||
| This file is part of the OpenRGB project |
|
||||
| SPDX-License-Identifier: GPL-2.0-or-later |
|
||||
\*---------------------------------------------------------*/
|
||||
|
||||
#include <cstdint>
|
||||
#include <cstring>
|
||||
#include <sys/ioctl.h>
|
||||
#include "ENESMBusInterface_SpectrixS40G_Linux.h"
|
||||
|
||||
/*---------------------------------------------------------------------*\
|
||||
| Functions for submitting NVME admin passthrough command taken from |
|
||||
| libnvme: https://github.com/linux-nvme/libnvme |
|
||||
\*---------------------------------------------------------------------*/
|
||||
|
||||
#define NVME_IOCTL_ADMIN_CMD _IOWR('N', 0x41, struct nvme_passthru_cmd)
|
||||
|
||||
struct nvme_passthru_cmd
|
||||
{
|
||||
uint8_t opcode;
|
||||
uint8_t flags;
|
||||
uint16_t rsvd1;
|
||||
uint32_t nsid;
|
||||
uint32_t cdw2;
|
||||
uint32_t cdw3;
|
||||
uint64_t metadata;
|
||||
uint64_t addr;
|
||||
uint32_t metadata_len;
|
||||
uint32_t data_len;
|
||||
uint32_t cdw10;
|
||||
uint32_t cdw11;
|
||||
uint32_t cdw12;
|
||||
uint32_t cdw13;
|
||||
uint32_t cdw14;
|
||||
uint32_t cdw15;
|
||||
uint32_t timeout_ms;
|
||||
uint32_t result;
|
||||
};
|
||||
|
||||
static int nvme_submit_passthru(int fd, unsigned long ioctl_cmd,
|
||||
struct nvme_passthru_cmd *cmd, uint32_t *result)
|
||||
{
|
||||
int err = ioctl(fd, ioctl_cmd, cmd);
|
||||
|
||||
if (err >= 0 && result)
|
||||
*result = cmd->result;
|
||||
return err;
|
||||
}
|
||||
|
||||
static int nvme_passthru(int fd, unsigned long ioctl_cmd, uint8_t opcode,
|
||||
uint8_t flags, uint16_t rsvd, uint32_t nsid, uint32_t cdw2,
|
||||
uint32_t cdw3, uint32_t cdw10, uint32_t cdw11, uint32_t cdw12,
|
||||
uint32_t cdw13, uint32_t cdw14, uint32_t cdw15, uint32_t data_len,
|
||||
void *data, uint32_t metadata_len, void *metadata,
|
||||
uint32_t timeout_ms, uint32_t *result)
|
||||
{
|
||||
struct nvme_passthru_cmd cmd = {
|
||||
.opcode = opcode,
|
||||
.flags = flags,
|
||||
.rsvd1 = rsvd,
|
||||
.nsid = nsid,
|
||||
.cdw2 = cdw2,
|
||||
.cdw3 = cdw3,
|
||||
.metadata = (uint64_t)(uintptr_t)metadata,
|
||||
.addr = (uint64_t)(uintptr_t)data,
|
||||
.metadata_len = metadata_len,
|
||||
.data_len = data_len,
|
||||
.cdw10 = cdw10,
|
||||
.cdw11 = cdw11,
|
||||
.cdw12 = cdw12,
|
||||
.cdw13 = cdw13,
|
||||
.cdw14 = cdw14,
|
||||
.cdw15 = cdw15,
|
||||
.timeout_ms = timeout_ms,
|
||||
.result = 0,
|
||||
};
|
||||
|
||||
return nvme_submit_passthru(fd, ioctl_cmd, &cmd, result);
|
||||
}
|
||||
|
||||
int nvme_admin_passthru(int fd, uint8_t opcode, uint8_t flags, uint16_t rsvd,
|
||||
uint32_t nsid, uint32_t cdw2, uint32_t cdw3, uint32_t cdw10,
|
||||
uint32_t cdw11, uint32_t cdw12, uint32_t cdw13, uint32_t cdw14,
|
||||
uint32_t cdw15, uint32_t data_len, void *data,
|
||||
uint32_t metadata_len, void *metadata, uint32_t timeout_ms,
|
||||
uint32_t *result)
|
||||
{
|
||||
return nvme_passthru(fd, NVME_IOCTL_ADMIN_CMD, opcode, flags, rsvd,
|
||||
nsid, cdw2, cdw3, cdw10, cdw11, cdw12, cdw13,
|
||||
cdw14, cdw15, data_len, data, metadata_len,
|
||||
metadata, timeout_ms, result);
|
||||
}
|
||||
|
||||
/*---------------------------------------------------------------------*\
|
||||
| ENESMBusInterface_SpectrixS40G implementation |
|
||||
\*---------------------------------------------------------------------*/
|
||||
|
||||
ENESMBusInterface_SpectrixS40G::ENESMBusInterface_SpectrixS40G(int fd, char* path)
|
||||
{
|
||||
this->nvme_fd = fd;
|
||||
this->path = path;
|
||||
}
|
||||
|
||||
ENESMBusInterface_SpectrixS40G::~ENESMBusInterface_SpectrixS40G()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
ene_interface_type ENESMBusInterface_SpectrixS40G::GetInterfaceType()
|
||||
{
|
||||
return(ENE_INTERFACE_TYPE_SPECTRIX_S40G);
|
||||
}
|
||||
|
||||
std::string ENESMBusInterface_SpectrixS40G::GetLocation()
|
||||
{
|
||||
return("NVMe: " + path);
|
||||
}
|
||||
|
||||
int ENESMBusInterface_SpectrixS40G::GetMaxBlock()
|
||||
{
|
||||
return(24);
|
||||
}
|
||||
|
||||
unsigned char ENESMBusInterface_SpectrixS40G::ENERegisterRead(ene_dev_id dev, ene_register reg)
|
||||
{
|
||||
struct nvme_passthru_cmd cfg;
|
||||
|
||||
memset(&cfg, 0, sizeof(nvme_passthru_cmd));
|
||||
|
||||
unsigned short corrected_reg = ((reg << 8) & 0xFF00) | ((reg >> 8) & 0x00FF);
|
||||
|
||||
cfg.opcode = 0xFA;
|
||||
cfg.cdw12 = (corrected_reg << 16) | (dev << 1);
|
||||
cfg.cdw13 = 0x81100001;
|
||||
cfg.data_len = 1;
|
||||
|
||||
unsigned char data[1];
|
||||
unsigned char metadata[1];
|
||||
unsigned int result;
|
||||
|
||||
/*-----------------------------------------------------------------------------*\
|
||||
| Send the command to the device |
|
||||
\*-----------------------------------------------------------------------------*/
|
||||
nvme_admin_passthru(nvme_fd, cfg.opcode, cfg.flags, cfg.rsvd1,
|
||||
cfg.nsid, cfg.cdw2, cfg.cdw3, cfg.cdw10,
|
||||
cfg.cdw11, cfg.cdw12, cfg.cdw13, cfg.cdw14,
|
||||
cfg.cdw15, cfg.data_len, data, cfg.metadata_len,
|
||||
metadata, cfg.timeout_ms, &result);
|
||||
|
||||
return(data[0]);
|
||||
}
|
||||
|
||||
void ENESMBusInterface_SpectrixS40G::ENERegisterWrite(ene_dev_id dev, ene_register reg, unsigned char val)
|
||||
{
|
||||
struct nvme_passthru_cmd cfg;
|
||||
|
||||
memset(&cfg, 0, sizeof(nvme_passthru_cmd));
|
||||
|
||||
unsigned short corrected_reg = ((reg << 8) & 0xFF00) | ((reg >> 8) & 0x00FF);
|
||||
|
||||
cfg.opcode = 0xFB;
|
||||
cfg.cdw12 = (corrected_reg << 16) | (dev << 1);
|
||||
cfg.cdw13 = 0x01100001;
|
||||
cfg.data_len = 1;
|
||||
|
||||
unsigned char data[1];
|
||||
|
||||
data[0] = val;
|
||||
|
||||
unsigned char metadata[1];
|
||||
unsigned int result;
|
||||
|
||||
/*-----------------------------------------------------------------------------*\
|
||||
| Send the command to the device |
|
||||
\*-----------------------------------------------------------------------------*/
|
||||
nvme_admin_passthru(nvme_fd, cfg.opcode, cfg.flags, cfg.rsvd1,
|
||||
cfg.nsid, cfg.cdw2, cfg.cdw3, cfg.cdw10,
|
||||
cfg.cdw11, cfg.cdw12, cfg.cdw13, cfg.cdw14,
|
||||
cfg.cdw15, cfg.data_len, data, cfg.metadata_len,
|
||||
metadata, cfg.timeout_ms, &result);
|
||||
|
||||
}
|
||||
|
||||
void ENESMBusInterface_SpectrixS40G::ENERegisterWriteBlock(ene_dev_id dev, ene_register reg, unsigned char * data, unsigned char sz)
|
||||
{
|
||||
struct nvme_passthru_cmd cfg;
|
||||
|
||||
memset(&cfg, 0, sizeof(nvme_passthru_cmd));
|
||||
|
||||
unsigned short corrected_reg = ((reg << 8) & 0xFF00) | ((reg >> 8) & 0x00FF);
|
||||
|
||||
cfg.opcode = 0xFB;
|
||||
cfg.cdw12 = (corrected_reg << 16) | (dev << 1);
|
||||
cfg.cdw13 = 0x03100000 | sz;
|
||||
cfg.data_len = sz;
|
||||
|
||||
unsigned char metadata[1];
|
||||
unsigned int result;
|
||||
|
||||
/*-----------------------------------------------------------------------------*\
|
||||
| Send the command to the device |
|
||||
\*-----------------------------------------------------------------------------*/
|
||||
nvme_admin_passthru(nvme_fd, cfg.opcode, cfg.flags, cfg.rsvd1,
|
||||
cfg.nsid, cfg.cdw2, cfg.cdw3, cfg.cdw10,
|
||||
cfg.cdw11, cfg.cdw12, cfg.cdw13, cfg.cdw14,
|
||||
cfg.cdw15, cfg.data_len, data, cfg.metadata_len,
|
||||
metadata, cfg.timeout_ms, &result);
|
||||
|
||||
}
|
||||
+32
@@ -0,0 +1,32 @@
|
||||
/*---------------------------------------------------------*\
|
||||
| ENESMBusInterface_SpectrixS40G_Linux.h |
|
||||
| |
|
||||
| ENE SMBus interface for XPG Spectrix S40G (Linux) |
|
||||
| |
|
||||
| Adam Honse (CalcProgrammer1) 21 Nov 2021 |
|
||||
| |
|
||||
| This file is part of the OpenRGB project |
|
||||
| SPDX-License-Identifier: GPL-2.0-or-later |
|
||||
\*---------------------------------------------------------*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "ENESMBusInterface.h"
|
||||
|
||||
class ENESMBusInterface_SpectrixS40G : public ENESMBusInterface
|
||||
{
|
||||
public:
|
||||
ENESMBusInterface_SpectrixS40G(int fd, char* path);
|
||||
~ENESMBusInterface_SpectrixS40G();
|
||||
|
||||
ene_interface_type GetInterfaceType();
|
||||
std::string GetLocation();
|
||||
int GetMaxBlock();
|
||||
unsigned char ENERegisterRead(ene_dev_id dev, ene_register reg);
|
||||
void ENERegisterWrite(ene_dev_id dev, ene_register reg, unsigned char val);
|
||||
void ENERegisterWriteBlock(ene_dev_id dev, ene_register reg, unsigned char * data, unsigned char sz);
|
||||
|
||||
private:
|
||||
int nvme_fd;
|
||||
std::string path;
|
||||
};
|
||||
+261
@@ -0,0 +1,261 @@
|
||||
/*---------------------------------------------------------*\
|
||||
| ENESMBusInterface_SpectrixS40G_Windows.cpp |
|
||||
| |
|
||||
| ENE SMBus interface for XPG Spectrix S40G (Windows) |
|
||||
| |
|
||||
| Adam Honse (CalcProgrammer1) 21 Nov 2021 |
|
||||
| |
|
||||
| This file is part of the OpenRGB project |
|
||||
| SPDX-License-Identifier: GPL-2.0-or-later |
|
||||
\*---------------------------------------------------------*/
|
||||
|
||||
#include <windows.h>
|
||||
#include <fileapi.h>
|
||||
#include <nvme.h>
|
||||
#include <winioctl.h>
|
||||
|
||||
#include "ENESMBusInterface_SpectrixS40G_Windows.h"
|
||||
#include "StringUtils.h"
|
||||
|
||||
ENESMBusInterface_SpectrixS40G::ENESMBusInterface_SpectrixS40G(HANDLE fd, wchar_t* path)
|
||||
{
|
||||
this->nvme_fd = fd;
|
||||
this->path = path;
|
||||
}
|
||||
|
||||
ENESMBusInterface_SpectrixS40G::~ENESMBusInterface_SpectrixS40G()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
ene_interface_type ENESMBusInterface_SpectrixS40G::GetInterfaceType()
|
||||
{
|
||||
return(ENE_INTERFACE_TYPE_SPECTRIX_S40G);
|
||||
}
|
||||
|
||||
std::string ENESMBusInterface_SpectrixS40G::GetLocation()
|
||||
{
|
||||
return("NVMe: " + StringUtils::wstring_to_string(path));
|
||||
}
|
||||
|
||||
int ENESMBusInterface_SpectrixS40G::GetMaxBlock()
|
||||
{
|
||||
return(24);
|
||||
}
|
||||
|
||||
unsigned char ENESMBusInterface_SpectrixS40G::ENERegisterRead(ene_dev_id dev, ene_register reg)
|
||||
{
|
||||
if(nvme_fd != INVALID_HANDLE_VALUE)
|
||||
{
|
||||
/*-----------------------------------------------------------------------------*\
|
||||
| Create buffer to hold STORAGE_PROTOCOL_COMMAND |
|
||||
| Size must be enough for the STORAGE_PROTOCOL_COMMAND struct plus the command |
|
||||
| data. Subtract sizeof(DWORD) as the Command field in the structure overlaps |
|
||||
| the actual command data. |
|
||||
\*-----------------------------------------------------------------------------*/
|
||||
unsigned char buffer[sizeof(STORAGE_PROTOCOL_COMMAND) + (sizeof(DWORD) * 34) - sizeof(DWORD)] = {0};
|
||||
|
||||
/*-----------------------------------------------------------------------------*\
|
||||
| Create STORAGE_PROTOCOL_COMMAND pointer and point it to the buffer |
|
||||
\*-----------------------------------------------------------------------------*/
|
||||
PSTORAGE_PROTOCOL_COMMAND command = (PSTORAGE_PROTOCOL_COMMAND)buffer;
|
||||
|
||||
/*-----------------------------------------------------------------------------*\
|
||||
| Fill in STORAGE_PROTOCOL_COMMAND structure |
|
||||
\*-----------------------------------------------------------------------------*/
|
||||
command->Version = STORAGE_PROTOCOL_STRUCTURE_VERSION;
|
||||
command->Length = sizeof(STORAGE_PROTOCOL_COMMAND);
|
||||
command->ProtocolType = ProtocolTypeNvme;
|
||||
command->Flags = STORAGE_PROTOCOL_COMMAND_FLAG_ADAPTER_REQUEST;
|
||||
command->ReturnStatus = 0x00000000;
|
||||
command->ErrorCode = 0x00000000;
|
||||
command->CommandLength = STORAGE_PROTOCOL_COMMAND_LENGTH_NVME;
|
||||
command->ErrorInfoLength = 0x00000040;
|
||||
command->DataToDeviceTransferLength = 0x00000000;
|
||||
command->DataFromDeviceTransferLength = 0x00000001;
|
||||
command->TimeOutValue = 0x00000001;
|
||||
command->ErrorInfoOffset = 0x00000090;
|
||||
command->DataToDeviceBufferOffset = 0x00000000;
|
||||
command->DataFromDeviceBufferOffset = 0x000000D0;
|
||||
command->CommandSpecific = STORAGE_PROTOCOL_SPECIFIC_NVME_ADMIN_COMMAND;
|
||||
command->Reserved0 = 0x00000000;
|
||||
command->FixedProtocolReturnData = 0x00000000;
|
||||
command->Reserved1[0] = 0x00000000;
|
||||
command->Reserved1[1] = 0x00000000;
|
||||
command->Reserved1[2] = 0x00000000;
|
||||
|
||||
/*-----------------------------------------------------------------------------*\
|
||||
| Create ENE Register Write command, filling in the appropriate register and |
|
||||
| value |
|
||||
\*-----------------------------------------------------------------------------*/
|
||||
PNVME_COMMAND CommandValue = (PNVME_COMMAND)command->Command;
|
||||
|
||||
unsigned short corrected_reg = ((reg << 8) & 0xFF00) | ((reg >> 8) & 0x00FF);
|
||||
|
||||
CommandValue->CDW0.OPC = 0xFA;
|
||||
CommandValue->u.GENERAL.CDW12 = (corrected_reg << 16) | (dev << 1);
|
||||
CommandValue->u.GENERAL.CDW13 = 0x81100001;
|
||||
|
||||
DWORD ExtraValue[18] = { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
|
||||
0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 };
|
||||
|
||||
/*-----------------------------------------------------------------------------*\
|
||||
| Send the STORAGE_PROTOCOL_COMMAND to the device |
|
||||
\*-----------------------------------------------------------------------------*/
|
||||
DWORD bytesreturned = 0;
|
||||
DeviceIoControl(nvme_fd, IOCTL_STORAGE_PROTOCOL_COMMAND, buffer, sizeof(buffer), buffer, sizeof(buffer), &bytesreturned, (LPOVERLAPPED)0x0);
|
||||
|
||||
/*-----------------------------------------------------------------------------*\
|
||||
| Copy the ENE Register Write extra data into the STORAGE_PROTOCOL_COMMAND |
|
||||
| buffer |
|
||||
\*-----------------------------------------------------------------------------*/
|
||||
memcpy(ExtraValue, &command->Command + sizeof(NVME_COMMAND), sizeof(ExtraValue));
|
||||
|
||||
return((unsigned char)ExtraValue[16]);
|
||||
}
|
||||
|
||||
return(0);
|
||||
}
|
||||
|
||||
void ENESMBusInterface_SpectrixS40G::ENERegisterWrite(ene_dev_id dev, ene_register reg, unsigned char val)
|
||||
{
|
||||
if(nvme_fd != INVALID_HANDLE_VALUE)
|
||||
{
|
||||
/*-----------------------------------------------------------------------------*\
|
||||
| Create buffer to hold STORAGE_PROTOCOL_COMMAND |
|
||||
| Size must be enough for the STORAGE_PROTOCOL_COMMAND struct plus the command |
|
||||
| data. Subtract sizeof(DWORD) as the Command field in the structure overlaps |
|
||||
| the actual command data. |
|
||||
\*-----------------------------------------------------------------------------*/
|
||||
unsigned char buffer[sizeof(STORAGE_PROTOCOL_COMMAND) + (sizeof(DWORD) * 34) - sizeof(DWORD)];
|
||||
|
||||
/*-----------------------------------------------------------------------------*\
|
||||
| Create STORAGE_PROTOCOL_COMMAND pointer and point it to the buffer |
|
||||
\*-----------------------------------------------------------------------------*/
|
||||
PSTORAGE_PROTOCOL_COMMAND command = (PSTORAGE_PROTOCOL_COMMAND)buffer;
|
||||
|
||||
/*-----------------------------------------------------------------------------*\
|
||||
| Fill in STORAGE_PROTOCOL_COMMAND structure |
|
||||
\*-----------------------------------------------------------------------------*/
|
||||
command->Version = STORAGE_PROTOCOL_STRUCTURE_VERSION;
|
||||
command->Length = sizeof(STORAGE_PROTOCOL_COMMAND);
|
||||
command->ProtocolType = ProtocolTypeNvme;
|
||||
command->Flags = STORAGE_PROTOCOL_COMMAND_FLAG_ADAPTER_REQUEST;
|
||||
command->ReturnStatus = 0x00000000;
|
||||
command->ErrorCode = 0x00000000;
|
||||
command->CommandLength = STORAGE_PROTOCOL_COMMAND_LENGTH_NVME;
|
||||
command->ErrorInfoLength = 0x00000040;
|
||||
command->DataToDeviceTransferLength = 0x00000001;
|
||||
command->DataFromDeviceTransferLength = 0x00000000;
|
||||
command->TimeOutValue = 0x00000001;
|
||||
command->ErrorInfoOffset = 0x00000090;
|
||||
command->DataToDeviceBufferOffset = 0x000000D0;
|
||||
command->DataFromDeviceBufferOffset = 0x00000000;
|
||||
command->CommandSpecific = STORAGE_PROTOCOL_SPECIFIC_NVME_ADMIN_COMMAND;
|
||||
command->Reserved0 = 0x00000000;
|
||||
command->FixedProtocolReturnData = 0x00000000;
|
||||
command->Reserved1[0] = 0x00000000;
|
||||
command->Reserved1[1] = 0x00000000;
|
||||
command->Reserved1[2] = 0x00000000;
|
||||
|
||||
/*-----------------------------------------------------------------------------*\
|
||||
| Create ENE Register Write command, filling in the appropriate register and |
|
||||
| value |
|
||||
\*-----------------------------------------------------------------------------*/
|
||||
PNVME_COMMAND CommandValue = (PNVME_COMMAND)command->Command;
|
||||
|
||||
unsigned short corrected_reg = ((reg << 8) & 0xFF00) | ((reg >> 8) & 0x00FF);
|
||||
|
||||
CommandValue->CDW0.OPC = 0xFB;
|
||||
CommandValue->u.GENERAL.CDW12 = (corrected_reg << 16) | (dev << 1);
|
||||
CommandValue->u.GENERAL.CDW13 = 0x01100001;
|
||||
|
||||
DWORD ExtraValue[18] = { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
|
||||
0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 };
|
||||
|
||||
ExtraValue[16] = val;
|
||||
|
||||
/*-----------------------------------------------------------------------------*\
|
||||
| Copy the ENE Register Write extra data into the STORAGE_PROTOCOL_COMMAND |
|
||||
| buffer |
|
||||
\*-----------------------------------------------------------------------------*/
|
||||
memcpy(&command->Command + sizeof(NVME_COMMAND), ExtraValue, sizeof(ExtraValue));
|
||||
|
||||
/*-----------------------------------------------------------------------------*\
|
||||
| Send the STORAGE_PROTOCOL_COMMAND to the device |
|
||||
\*-----------------------------------------------------------------------------*/
|
||||
DeviceIoControl(nvme_fd, IOCTL_STORAGE_PROTOCOL_COMMAND, buffer, sizeof(buffer), buffer, sizeof(buffer), 0x0, (LPOVERLAPPED)0x0);
|
||||
}
|
||||
}
|
||||
|
||||
void ENESMBusInterface_SpectrixS40G::ENERegisterWriteBlock(ene_dev_id dev, ene_register reg, unsigned char * data, unsigned char sz)
|
||||
{
|
||||
if(nvme_fd != INVALID_HANDLE_VALUE)
|
||||
{
|
||||
/*-----------------------------------------------------------------------------*\
|
||||
| Create buffer to hold STORAGE_PROTOCOL_COMMAND |
|
||||
| Size must be enough for the STORAGE_PROTOCOL_COMMAND struct plus the command |
|
||||
| data. Subtract sizeof(DWORD) as the Command field in the structure overlaps |
|
||||
| the actual command data. |
|
||||
\*-----------------------------------------------------------------------------*/
|
||||
unsigned char buffer[sizeof(STORAGE_PROTOCOL_COMMAND) + (sizeof(DWORD) * 39) - sizeof(DWORD)];
|
||||
|
||||
/*-----------------------------------------------------------------------------*\
|
||||
| Create STORAGE_PROTOCOL_COMMAND pointer and point it to the buffer |
|
||||
\*-----------------------------------------------------------------------------*/
|
||||
PSTORAGE_PROTOCOL_COMMAND command = (PSTORAGE_PROTOCOL_COMMAND)buffer;
|
||||
|
||||
/*-----------------------------------------------------------------------------*\
|
||||
| Fill in STORAGE_PROTOCOL_COMMAND structure |
|
||||
\*-----------------------------------------------------------------------------*/
|
||||
command->Version = STORAGE_PROTOCOL_STRUCTURE_VERSION;
|
||||
command->Length = sizeof(STORAGE_PROTOCOL_COMMAND);
|
||||
command->ProtocolType = ProtocolTypeNvme;
|
||||
command->Flags = STORAGE_PROTOCOL_COMMAND_FLAG_ADAPTER_REQUEST;
|
||||
command->ReturnStatus = 0x00000000;
|
||||
command->ErrorCode = 0x00000000;
|
||||
command->CommandLength = STORAGE_PROTOCOL_COMMAND_LENGTH_NVME;
|
||||
command->ErrorInfoLength = 0x00000040;
|
||||
command->DataToDeviceTransferLength = sz;
|
||||
command->DataFromDeviceTransferLength = 0x00000000;
|
||||
command->TimeOutValue = 0x00000001;
|
||||
command->ErrorInfoOffset = 0x00000090;
|
||||
command->DataToDeviceBufferOffset = 0x000000D0;
|
||||
command->DataFromDeviceBufferOffset = 0x00000000;
|
||||
command->CommandSpecific = STORAGE_PROTOCOL_SPECIFIC_NVME_ADMIN_COMMAND;
|
||||
command->Reserved0 = 0x00000000;
|
||||
command->FixedProtocolReturnData = 0x00000000;
|
||||
command->Reserved1[0] = 0x00000000;
|
||||
command->Reserved1[1] = 0x00000000;
|
||||
command->Reserved1[2] = 0x00000000;
|
||||
|
||||
/*-----------------------------------------------------------------------------*\
|
||||
| Create ENE Register Write Block command, filling in the appropriate register |
|
||||
| and value |
|
||||
\*-----------------------------------------------------------------------------*/
|
||||
PNVME_COMMAND CommandValue = (PNVME_COMMAND)command->Command;
|
||||
|
||||
unsigned short corrected_reg = ((reg << 8) & 0xFF00) | ((reg >> 8) & 0x00FF);
|
||||
|
||||
CommandValue->CDW0.OPC = 0xFB;
|
||||
CommandValue->u.GENERAL.CDW12 = (corrected_reg << 16) | (dev << 1);
|
||||
CommandValue->u.GENERAL.CDW13 = 0x03100000 | sz;
|
||||
|
||||
DWORD ExtraValue[23] = { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
|
||||
0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
|
||||
0x00000000, 0x00000000, 0x00000000 };
|
||||
|
||||
memcpy(&ExtraValue[16], data, sz);
|
||||
|
||||
/*-----------------------------------------------------------------------------*\
|
||||
| Copy the ENE Register Write Block extra data into the |
|
||||
| STORAGE_PROTOCOL_COMMAND buffer |
|
||||
\*-----------------------------------------------------------------------------*/
|
||||
memcpy(&command->Command + sizeof(NVME_COMMAND), ExtraValue, sizeof(ExtraValue));
|
||||
|
||||
/*-----------------------------------------------------------------------------*\
|
||||
| Send the STORAGE_PROTOCOL_COMMAND to the device |
|
||||
\*-----------------------------------------------------------------------------*/
|
||||
DeviceIoControl(nvme_fd, IOCTL_STORAGE_PROTOCOL_COMMAND, buffer, sizeof(buffer), buffer, sizeof(buffer), 0x0, (LPOVERLAPPED)0x0);
|
||||
}
|
||||
}
|
||||
+33
@@ -0,0 +1,33 @@
|
||||
/*---------------------------------------------------------*\
|
||||
| ENESMBusInterface_SpectrixS40G_Windows.h |
|
||||
| |
|
||||
| ENE SMBus interface for XPG Spectrix S40G (Windows) |
|
||||
| |
|
||||
| Adam Honse (CalcProgrammer1) 21 Nov 2021 |
|
||||
| |
|
||||
| This file is part of the OpenRGB project |
|
||||
| SPDX-License-Identifier: GPL-2.0-or-later |
|
||||
\*---------------------------------------------------------*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <windows.h>
|
||||
#include "ENESMBusInterface.h"
|
||||
|
||||
class ENESMBusInterface_SpectrixS40G : public ENESMBusInterface
|
||||
{
|
||||
public:
|
||||
ENESMBusInterface_SpectrixS40G(HANDLE fd, wchar_t* path);
|
||||
~ENESMBusInterface_SpectrixS40G();
|
||||
|
||||
ene_interface_type GetInterfaceType();
|
||||
std::string GetLocation();
|
||||
int GetMaxBlock();
|
||||
unsigned char ENERegisterRead(ene_dev_id dev, ene_register reg);
|
||||
void ENERegisterWrite(ene_dev_id dev, ene_register reg, unsigned char val);
|
||||
void ENERegisterWriteBlock(ene_dev_id dev, ene_register reg, unsigned char * data, unsigned char sz);
|
||||
|
||||
private:
|
||||
HANDLE nvme_fd;
|
||||
std::wstring path;
|
||||
};
|
||||
@@ -0,0 +1,72 @@
|
||||
/*---------------------------------------------------------*\
|
||||
| ENESMBusInterface_i2c_smbus.cpp |
|
||||
| |
|
||||
| ENE SMBus interface for I2C/SMBus |
|
||||
| |
|
||||
| Adam Honse (CalcProgrammer1) 21 Nov 2021 |
|
||||
| |
|
||||
| This file is part of the OpenRGB project |
|
||||
| SPDX-License-Identifier: GPL-2.0-or-later |
|
||||
\*---------------------------------------------------------*/
|
||||
|
||||
#include "ENESMBusInterface_i2c_smbus.h"
|
||||
|
||||
ENESMBusInterface_i2c_smbus::ENESMBusInterface_i2c_smbus(i2c_smbus_interface* bus)
|
||||
{
|
||||
this->bus = bus;
|
||||
}
|
||||
|
||||
ENESMBusInterface_i2c_smbus::~ENESMBusInterface_i2c_smbus()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
ene_interface_type ENESMBusInterface_i2c_smbus::GetInterfaceType()
|
||||
{
|
||||
return(ENE_INTERFACE_TYPE_I2C_SMBUS);
|
||||
}
|
||||
|
||||
std::string ENESMBusInterface_i2c_smbus::GetLocation()
|
||||
{
|
||||
std::string return_string(bus->device_name);
|
||||
return("I2C: " + return_string);
|
||||
}
|
||||
|
||||
int ENESMBusInterface_i2c_smbus::GetMaxBlock()
|
||||
{
|
||||
return(3);
|
||||
}
|
||||
|
||||
unsigned char ENESMBusInterface_i2c_smbus::ENERegisterRead(ene_dev_id dev, ene_register reg)
|
||||
{
|
||||
//Write ENE register
|
||||
bus->i2c_smbus_write_word_data(dev, 0x00, ((reg << 8) & 0xFF00) | ((reg >> 8) & 0x00FF));
|
||||
|
||||
//Read ENE value
|
||||
return(bus->i2c_smbus_read_byte_data(dev, 0x81));
|
||||
}
|
||||
|
||||
void ENESMBusInterface_i2c_smbus::ENERegisterWrite(ene_dev_id dev, ene_register reg, unsigned char val)
|
||||
{
|
||||
//Write ENE register
|
||||
bus->i2c_smbus_write_word_data(dev, 0x00, ((reg << 8) & 0xFF00) | ((reg >> 8) & 0x00FF));
|
||||
|
||||
//Write ENE value
|
||||
bus->i2c_smbus_write_byte_data(dev, 0x01, val);
|
||||
}
|
||||
|
||||
void ENESMBusInterface_i2c_smbus::ENERegisterWriteBlock(ene_dev_id dev, ene_register reg, unsigned char * data, unsigned char sz)
|
||||
{
|
||||
//Write ENE register
|
||||
bus->i2c_smbus_write_word_data(dev, 0x00, ((reg << 8) & 0xFF00) | ((reg >> 8) & 0x00FF));
|
||||
|
||||
//Write ENE block data
|
||||
if(bus->i2c_smbus_write_block_data(dev, 0x03, sz, data) == -1)
|
||||
{
|
||||
//Fall back to individual byte operations if the block operation fails
|
||||
for(unsigned int block_byte = 0; block_byte < sz; block_byte++)
|
||||
{
|
||||
bus->i2c_smbus_write_byte_data(dev, 0x01, data[block_byte]);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,32 @@
|
||||
/*---------------------------------------------------------*\
|
||||
| ENESMBusInterface_i2c_smbus.h |
|
||||
| |
|
||||
| ENE SMBus interface for I2C/SMBus |
|
||||
| |
|
||||
| Adam Honse (CalcProgrammer1) 21 Nov 2021 |
|
||||
| |
|
||||
| This file is part of the OpenRGB project |
|
||||
| SPDX-License-Identifier: GPL-2.0-or-later |
|
||||
\*---------------------------------------------------------*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "ENESMBusInterface.h"
|
||||
#include "i2c_smbus.h"
|
||||
|
||||
class ENESMBusInterface_i2c_smbus : public ENESMBusInterface
|
||||
{
|
||||
public:
|
||||
ENESMBusInterface_i2c_smbus(i2c_smbus_interface* bus);
|
||||
~ENESMBusInterface_i2c_smbus();
|
||||
|
||||
ene_interface_type GetInterfaceType();
|
||||
std::string GetLocation();
|
||||
int GetMaxBlock();
|
||||
unsigned char ENERegisterRead(ene_dev_id dev, ene_register reg);
|
||||
void ENERegisterWrite(ene_dev_id dev, ene_register reg, unsigned char val);
|
||||
void ENERegisterWriteBlock(ene_dev_id dev, ene_register reg, unsigned char * data, unsigned char sz);
|
||||
|
||||
private:
|
||||
i2c_smbus_interface * bus;
|
||||
};
|
||||
Reference in New Issue
Block a user