From f38be5119ed942df82b57c28dee69429706b5e0d Mon Sep 17 00:00:00 2001 From: Adam Honse Date: Wed, 19 Feb 2020 14:26:49 -0600 Subject: [PATCH] MSI-RGB driver based on https://github.com/nagisa/msi-rgb --- .../MSIRGBController/MSIRGBController.cpp | 99 +++++++++++++++++++ .../MSIRGBController/MSIRGBController.h | 56 +++++++++++ .../MSIRGBControllerDetect.cpp | 42 ++++++++ OpenRGB.cpp | 2 + OpenRGB.pro | 6 ++ RGBController/RGBController_MSIRGB.cpp | 70 +++++++++++++ RGBController/RGBController_MSIRGB.h | 27 +++++ super_io/super_io.cpp | 8 +- 8 files changed, 306 insertions(+), 4 deletions(-) create mode 100644 Controllers/MSIRGBController/MSIRGBController.cpp create mode 100644 Controllers/MSIRGBController/MSIRGBController.h create mode 100644 Controllers/MSIRGBController/MSIRGBControllerDetect.cpp create mode 100644 RGBController/RGBController_MSIRGB.cpp create mode 100644 RGBController/RGBController_MSIRGB.h diff --git a/Controllers/MSIRGBController/MSIRGBController.cpp b/Controllers/MSIRGBController/MSIRGBController.cpp new file mode 100644 index 00000000..1a0c247d --- /dev/null +++ b/Controllers/MSIRGBController/MSIRGBController.cpp @@ -0,0 +1,99 @@ +/*-----------------------------------------*\ +| MSIRGBController.cpp | +| | +| Driver for MSI-RGB lighting controller | +| | +| Logic adapted from: | +| https://github.com/nagisa/msi-rgb | +| | +| Adam Honse (CalcProgrammer1) 2/11/2020 | +\*-----------------------------------------*/ + +#include "MSIRGBController.h" +#include "super_io.h" + +MSIRGBController::MSIRGBController(int sioaddr) +{ + msi_sioaddr = sioaddr; + + /*-----------------------------------------------------*\ + | This setup step isn't well documented | + | Without this, pulsing does not work | + \*-----------------------------------------------------*/ + superio_outb(msi_sioaddr, SIO_REG_LOGDEV, 0x09); + + int val_at_2c = superio_inb(msi_sioaddr, 0x2C); + + val_at_2c &= 0b11110111; + val_at_2c |= 0b00010000; + + superio_outb(msi_sioaddr, 0x2C, val_at_2c); + + + /*-----------------------------------------------------*\ + | Set logical device register to RGB controller | + \*-----------------------------------------------------*/ + superio_outb(msi_sioaddr, SIO_REG_LOGDEV, MSI_SIO_LOGDEV_RGB); + + /*-----------------------------------------------------*\ + | Test if RGB is enabled. If it is not, enable it. | + \*-----------------------------------------------------*/ + int enable = superio_inb(msi_sioaddr, MSI_SIO_RGB_REG_ENABLE); + + if((enable & MSI_SIO_RGB_ENABLE_MASK) != MSI_SIO_RGB_ENABLE_MASK) + { + superio_outb(msi_sioaddr, MSI_SIO_RGB_REG_ENABLE, MSI_SIO_RGB_ENABLE_MASK & (enable & !MSI_SIO_RGB_ENABLE_MASK)); + } + + /*-----------------------------------------------------*\ + | Lighting enabled, no pulsing or blinking | + \*-----------------------------------------------------*/ + superio_outb(msi_sioaddr, MSI_SIO_RGB_REG_CFG_1, 0x00); + + /*-----------------------------------------------------*\ + | Lighting enabled, RGB non-inverted, header on | + \*-----------------------------------------------------*/ + superio_outb(msi_sioaddr, MSI_SIO_RGB_REG_CFG_3, 0xE2); +} + +MSIRGBController::~MSIRGBController() +{ + +} + +void MSIRGBController::SetColor(unsigned char red, unsigned char green, unsigned char blue) +{ + /*-----------------------------------------------------*\ + | The MSI RGB controller uses 4 bits per color rather | + | than 8. Shift the values by 4 so that the 4 most | + | significant bits of each color are the new color value| + \*-----------------------------------------------------*/ + red = red >> 4; + green = green >> 4; + blue = blue >> 4; + + /*-----------------------------------------------------*\ + | Set logical device register to RGB controller | + \*-----------------------------------------------------*/ + superio_outb(msi_sioaddr, SIO_REG_LOGDEV, MSI_SIO_LOGDEV_RGB); + + /*-----------------------------------------------------*\ + | Write the colors to the color sequence registers | + | Only static mode is supported right now - all colors | + | are the same. | + \*-----------------------------------------------------*/ + superio_outb(msi_sioaddr, MSI_SIO_RGB_REG_RED_1_0, (red | (red << 4))); + superio_outb(msi_sioaddr, MSI_SIO_RGB_REG_RED_3_2, (red | (red << 4))); + superio_outb(msi_sioaddr, MSI_SIO_RGB_REG_RED_5_4, (red | (red << 4))); + superio_outb(msi_sioaddr, MSI_SIO_RGB_REG_RED_7_6, (red | (red << 4))); + + superio_outb(msi_sioaddr, MSI_SIO_RGB_REG_GREEN_1_0, (green | (green << 4))); + superio_outb(msi_sioaddr, MSI_SIO_RGB_REG_GREEN_3_2, (green | (green << 4))); + superio_outb(msi_sioaddr, MSI_SIO_RGB_REG_GREEN_5_4, (green | (green << 4))); + superio_outb(msi_sioaddr, MSI_SIO_RGB_REG_GREEN_7_6, (green | (green << 4))); + + superio_outb(msi_sioaddr, MSI_SIO_RGB_REG_BLUE_1_0, (blue | (blue << 4))); + superio_outb(msi_sioaddr, MSI_SIO_RGB_REG_BLUE_3_2, (blue | (blue << 4))); + superio_outb(msi_sioaddr, MSI_SIO_RGB_REG_BLUE_5_4, (blue | (blue << 4))); + superio_outb(msi_sioaddr, MSI_SIO_RGB_REG_BLUE_7_6, (blue | (blue << 4))); +} \ No newline at end of file diff --git a/Controllers/MSIRGBController/MSIRGBController.h b/Controllers/MSIRGBController/MSIRGBController.h new file mode 100644 index 00000000..8ea7179d --- /dev/null +++ b/Controllers/MSIRGBController/MSIRGBController.h @@ -0,0 +1,56 @@ +/*-----------------------------------------*\ +| MSIRGBController.h | +| | +| Definitions and types for MSI-RGB | +| lighting controller | +| | +| Logic adapted from: | +| https://github.com/nagisa/msi-rgb | +| | +| Adam Honse (CalcProgrammer1) 2/11/2020 | +\*-----------------------------------------*/ + +#include + +#pragma once + +#define MSI_SIO_LOGDEV_RGB 0x12 + +enum +{ + MSI_SIO_RGB_REG_ENABLE = 0xE0, + MSI_SIO_RGB_REG_CFG_1 = 0xE4, + MSI_SIO_RGB_REG_RED_1_0 = 0xF0, + MSI_SIO_RGB_REG_RED_3_2 = 0xF1, + MSI_SIO_RGB_REG_RED_5_4 = 0xF2, + MSI_SIO_RGB_REG_RED_7_6 = 0xF3, + MSI_SIO_RGB_REG_GREEN_1_0 = 0xF4, + MSI_SIO_RGB_REG_GREEN_3_2 = 0xF5, + MSI_SIO_RGB_REG_GREEN_5_4 = 0xF6, + MSI_SIO_RGB_REG_GREEN_7_6 = 0xF7, + MSI_SIO_RGB_REG_BLUE_1_0 = 0xF8, + MSI_SIO_RGB_REG_BLUE_3_2 = 0xF9, + MSI_SIO_RGB_REG_BLUE_5_4 = 0xFA, + MSI_SIO_RGB_REG_BLUE_7_6 = 0xFB, + MSI_SIO_RGB_REG_CFG_2 = 0xFE, + MSI_SIO_RGB_REG_CFG_3 = 0xFF, +}; + +#define MSI_SIO_RGB_ENABLE_MASK 0xE0 + +class MSIRGBController +{ +public: + MSIRGBController(int sioaddr); + ~MSIRGBController(); + + std::string GetDeviceName(); + std::string GetDeviceLocation(); + + unsigned int GetMode(); + void SetMode(unsigned char new_mode, unsigned char new_speed); + + void SetColor(unsigned char red, unsigned char green, unsigned char blue); +private: + int msi_sioaddr; +}; \ No newline at end of file diff --git a/Controllers/MSIRGBController/MSIRGBControllerDetect.cpp b/Controllers/MSIRGBController/MSIRGBControllerDetect.cpp new file mode 100644 index 00000000..c353ddaa --- /dev/null +++ b/Controllers/MSIRGBController/MSIRGBControllerDetect.cpp @@ -0,0 +1,42 @@ +#include "MSIRGBController.h" +#include "RGBController.h" +#include "RGBController_MSIRGB.h" +#include "super_io.h" +#include +#include +#include + +/******************************************************************************************\ +* * +* DetectMSIRGBControllers * +* * +* Detect MSI-RGB compatible Super-IO chips. * +* * +\******************************************************************************************/ + +void DetectMSIRGBControllers(std::vector &rgb_controllers) +{ + int sio_addrs[2] = {0x2E, 0x4E}; + + for(int sioaddr_idx = 0; sioaddr_idx < 2; sioaddr_idx++) + { + int sioaddr = sio_addrs[sioaddr_idx]; + + superio_enter(sioaddr); + + int val = (superio_inb(sioaddr, SIO_REG_DEVID) << 8) | superio_inb(sioaddr, SIO_REG_DEVID + 1); + + printf("Super IO DevID: %04X", val); + + switch (val & SIO_ID_MASK) + { + case SIO_NCT6795_ID: + case SIO_NCT6797_ID: + MSIRGBController* new_msi = new MSIRGBController(sioaddr); + RGBController_MSIRGB* new_rgb = new RGBController_MSIRGB(new_msi); + + rgb_controllers.push_back(new_rgb); + break; + } + } +} /* DetectMSIRGBControllers() */ diff --git a/OpenRGB.cpp b/OpenRGB.cpp index 6d066d41..e7cc95f9 100644 --- a/OpenRGB.cpp +++ b/OpenRGB.cpp @@ -260,6 +260,7 @@ void DetectHyperXControllers(std::vector &busses, std::vec void DetectPatriotViperControllers(std::vector &busses, std::vector &rgb_controllers); void DetectPolychromeControllers(std::vector& busses, std::vector& rgb_controllers); void DetectRGBFusionControllers(std::vector& busses, std::vector& rgb_controllers); +void DetectMSIRGBControllers(std::vector &rgb_controllers); void DetectLEDStripControllers(std::vector &rgb_controllers); void DetectHue2Controllers(std::vector &rgb_controllers); void DetectHuePlusControllers(std::vector &rgb_controllers); @@ -296,6 +297,7 @@ void DetectRGBControllers(void) DetectPatriotViperControllers(busses, rgb_controllers); DetectPolychromeControllers(busses, rgb_controllers); DetectRGBFusionControllers(busses, rgb_controllers); + DetectMSIRGBControllers(rgb_controllers); DetectLEDStripControllers(rgb_controllers); DetectHue2Controllers(rgb_controllers); diff --git a/OpenRGB.pro b/OpenRGB.pro index 5a8b2903..61acc68e 100644 --- a/OpenRGB.pro +++ b/OpenRGB.pro @@ -26,6 +26,7 @@ INCLUDEPATH += \ Controllers/HyperXKeyboardController/ \ Controllers/LEDStripController/ \ Controllers/MSI3ZoneController/ \ + Controllers/MSIRGBController/ \ Controllers/PatriotViperController/ \ Controllers/PolychromeController/ \ Controllers/PoseidonZRGBController/ \ @@ -78,6 +79,8 @@ SOURCES += \ Controllers/LEDStripController/LEDStripControllerDetect.cpp \ Controllers/MSI3ZoneController/MSI3ZoneController.cpp \ Controllers/MSI3ZoneController/MSI3ZoneControllerDetect.cpp \ + Controllers/MSIRGBController/MSIRGBController.cpp \ + Controllers/MSIRGBController/MSIRGBControllerDetect.cpp \ Controllers/PatriotViperController/PatriotViperController.cpp \ Controllers/PatriotViperController/PatriotViperControllerDetect.cpp \ Controllers/PolychromeController/PolychromeController.cpp \ @@ -107,6 +110,7 @@ SOURCES += \ RGBController/RGBController_E131.cpp \ RGBController/RGBController_LEDStrip.cpp \ RGBController/RGBController_MSI3Zone.cpp \ + RGBController/RGBController_MSIRGB.cpp \ RGBController/RGBController_PatriotViper.cpp \ RGBController/RGBController_Polychrome.cpp \ RGBController/RGBController_PoseidonZRGB.cpp \ @@ -140,6 +144,7 @@ HEADERS += \ Controllers/HyperXKeyboardController/HyperXKeyboardController.h \ Controllers/LEDStripController/LEDStripController.h \ Controllers/MSI3ZoneController/MSI3ZoneController.h \ + Controllers/MSIRGBController/MSIRGBController.h \ Controllers/PatriotViperController/PatriotViperController.h \ Controllers/PolychromeController/PolychromeController.h \ Controllers/PoseidonZRGBController/PoseidonZRGBController.h \ @@ -161,6 +166,7 @@ HEADERS += \ RGBController/RGBController_HyperXKeyboard.h \ RGBController/RGBController_LEDStrip.h \ RGBController/RGBController_MSI3Zone.h \ + RGBController/RGBController_MSIRGB.h \ RGBController/RGBController_PatriotViper.h \ RGBController/RGBController_Polychrome.h \ RGBController/RGBController_PoseidonZRGB.h \ diff --git a/RGBController/RGBController_MSIRGB.cpp b/RGBController/RGBController_MSIRGB.cpp new file mode 100644 index 00000000..d53c26c1 --- /dev/null +++ b/RGBController/RGBController_MSIRGB.cpp @@ -0,0 +1,70 @@ +/*-----------------------------------------*\ +| RGBController_MSIRGB.cpp | +| | +| Generic RGB Interface for MSI-RGB | +| | +| Adam Honse (CalcProgrammer1) 2/14/2020 | +\*-----------------------------------------*/ + +#include "RGBController_MSIRGB.h" + +RGBController_MSIRGB::RGBController_MSIRGB(MSIRGBController* msi_ptr) +{ + msi = msi_ptr; + + mode Direct; + Direct.name = "Direct"; + Direct.value = 0; + Direct.flags = MODE_FLAG_HAS_PER_LED_COLOR; + Direct.color_mode = MODE_COLORS_PER_LED; + modes.push_back(Direct); + + led msi_led; + msi_led.name = "MSI LED"; + leds.push_back(msi_led); + + zone msi_zone; + msi_zone.name = "MSI Zone"; + msi_zone.type = ZONE_TYPE_SINGLE; + std::vector msi_zone_map; + msi_zone_map.push_back(0); + msi_zone.map.push_back(msi_zone_map); + zones.push_back(msi_zone); + + colors.push_back(0x00000000); +} + +RGBController_MSIRGB::~RGBController_MSIRGB() +{ + +} + +void RGBController_MSIRGB::UpdateLEDs() +{ + RGBColor color = colors[0]; + unsigned char red = RGBGetRValue(color); + unsigned char grn = RGBGetGValue(color); + unsigned char blu = RGBGetBValue(color); + + msi->SetColor(red, grn, blu); +} + +void RGBController_MSIRGB::UpdateZoneLEDs(int zone) +{ + UpdateLEDs(); +} + +void RGBController_MSIRGB::UpdateSingleLED(int led) +{ + UpdateLEDs(); +} + +void RGBController_MSIRGB::SetCustomMode() +{ + +} + +void RGBController_MSIRGB::UpdateMode() +{ + +} diff --git a/RGBController/RGBController_MSIRGB.h b/RGBController/RGBController_MSIRGB.h new file mode 100644 index 00000000..f3d1ef21 --- /dev/null +++ b/RGBController/RGBController_MSIRGB.h @@ -0,0 +1,27 @@ +/*-----------------------------------------*\ +| RGBController_MSIRGB.h | +| | +| Generic RGB Interface for MSI-RGB | +| | +| Adam Honse (CalcProgrammer1) 2/14/2020 | +\*-----------------------------------------*/ + +#pragma once +#include "RGBController.h" +#include "MSIRGBController.h" + +class RGBController_MSIRGB : public RGBController +{ +public: + RGBController_MSIRGB(MSIRGBController* msi_ptr); + ~RGBController_MSIRGB(); + void UpdateLEDs(); + void UpdateZoneLEDs(int zone); + void UpdateSingleLED(int led); + + void SetCustomMode(); + void UpdateMode(); + +private: + MSIRGBController* msi; +}; \ No newline at end of file diff --git a/super_io/super_io.cpp b/super_io/super_io.cpp index bfe46ca0..44e32db6 100644 --- a/super_io/super_io.cpp +++ b/super_io/super_io.cpp @@ -36,9 +36,9 @@ void superio_enter(int ioreg) #else unsigned char temp = 0x87; dev_port_fd = open("/dev/port", O_RDWR, "rw"); - lseek(dev_port_fd, ioreg, SEEK_CUR); + lseek(dev_port_fd, ioreg, SEEK_SET); write(dev_port_fd, &temp, 1); - lseek(dev_port_fd, ioreg, SEEK_CUR); + lseek(dev_port_fd, ioreg, SEEK_SET); write(dev_port_fd, &temp, 1); close(dev_port_fd); #endif @@ -60,7 +60,7 @@ void superio_outb(int ioreg, int reg, int val) Out32(ioreg + 1, val); #else dev_port_fd = open("/dev/port", O_RDWR, "rw"); - lseek(dev_port_fd, ioreg, SEEK_CUR); + lseek(dev_port_fd, ioreg, SEEK_SET); write(dev_port_fd, ®, 1); write(dev_port_fd, &val, 1); close(dev_port_fd); @@ -84,7 +84,7 @@ int superio_inb(int ioreg, int reg) #else unsigned char temp; dev_port_fd = open("/dev/port", O_RDWR, "rw"); - lseek(dev_port_fd, ioreg, SEEK_CUR); + lseek(dev_port_fd, ioreg, SEEK_SET); write(dev_port_fd, ®, 1); read(dev_port_fd, &temp, 1); close(dev_port_fd);