/*---------------------------------------------------------*\ | super_io_pawnio.cpp | | | | Functions for interfacing with Super-IO using PawnIO | | | | Stephen Horvath (Steve-Tech) 05 May 2025 | | | | This file is part of the OpenRGB project | | SPDX-License-Identifier: GPL-2.0-or-later | \*---------------------------------------------------------*/ #include "super_io.h" #include #include "PawnIOLib.h" #include "i2c_smbus_pawnio.h" static HANDLE pawnio_handle = NULL; static int pawnio_chip_type = 0; static int addr_to_pawnio(int addr) { switch (addr) { case 0x2E: return 0; case 0x4E: return 1; default: return -1; } } /******************************************************************************************\ * * * pawnio_superio_enter * * * * Put the Super IO chip into Extended Function Mode * * * \******************************************************************************************/ void superio_enter(int ioreg) { HRESULT status; SIZE_T return_size; if (pawnio_handle == NULL) { status = i2c_smbus_pawnio::start_pawnio("superio", &pawnio_handle); if (status != S_OK) { // TODO: Figure out how to handle errors return; } } if (pawnio_chip_type == 0) { int in_reg = addr_to_pawnio(ioreg); if (in_reg == -1) { return; } const SIZE_T in_size = 1; ULONG64 in[in_size] = {(ULONG64)in_reg}; const SIZE_T out_size = 1; ULONG64 out[out_size]; status = pawnio_execute(pawnio_handle, "ioctl_detect", in, in_size, out, out_size, &return_size); if (status != S_OK || out[0] == 0) { return; } pawnio_chip_type = (int)out[0]; } pawnio_execute(pawnio_handle, "ioctl_enter", NULL, 0, NULL, 0, &return_size); } /******************************************************************************************\ * * * pawnio_superio_outb * * * * Write a byte to the Super IO configuration register * * * \******************************************************************************************/ void superio_outb([[maybe_unused]] int ioreg, int reg, int val) { const SIZE_T in_size = 2; ULONG64 in[in_size] = {(ULONG64)reg, (ULONG64)val}; SIZE_T return_size; pawnio_execute(pawnio_handle, "ioctl_write", in, in_size, NULL, 0, &return_size); } /******************************************************************************************\ * * * pawnio_superio_inb * * * * Read a byte from the Super IO configuration register * * * \******************************************************************************************/ int superio_inb([[maybe_unused]] int ioreg, int reg) { const SIZE_T in_size = 1; ULONG64 in[in_size] = {(ULONG64)reg}; const SIZE_T out_size = 1; ULONG64 out[out_size]; SIZE_T return_size; HRESULT status = pawnio_execute(pawnio_handle, "ioctl_read", in, in_size, out, out_size, &return_size); if (status != S_OK) { return -1; } return (int)out[0]; }