Linux kernel DRM driver and userspace tools for the MacroSilicon MS9132 USB display adapter, as found in the Mars Gaming ML-VISION360 AIO liquid cooler with a 480x480 IPS LCD panel.
| Component | Details |
|---|---|
| Product | Mars Gaming ML-VISION360 AIO Cooler |
| Display | 480x480 IPS LCD panel |
| Chip | MacroSilicon MS9132 USB-to-Display adapter |
| USB VID:PID | 345f:9132 (USB 3.0) / 534d:6021 or 534d:0821 (USB 2.0) |
| Interface | USB 3.0 SuperSpeed (also works on USB 2.0 with workaround) |
| Connection | Internal USB header (appears as USB display adapter) |
.
├── README.md # This file
├── PROTOCOL.md # Full MS9132 USB protocol documentation
├── USB2_WORKAROUND.md # USB 2.0 flow control workaround details
├── kernel-driver/ # Linux DRM kernel module (ms912x)
│ ├── ms912x.h
│ ├── ms912x_drv.c
│ ├── ms912x_connector.c
│ ├── ms912x_registers.c
│ ├── ms912x_transfer.c
│ ├── Makefile
│ └── dkms.conf
├── python-tools/ # Standalone Python tools (no kernel driver needed)
│ ├── send_image.py # Send a static image to the LCD
│ ├── cpu_monitor.py # Live CPU/GPU temperature display
│ └── requirements.txt
└── systemd/
└── mlvision-lcd.service # Systemd service for auto-start on boot
# Install dependencies
pip install pyusb numpy pillow
# Send an image to the LCD
sudo python3 python-tools/send_image.py /path/to/image.png
# Live CPU/GPU temperature monitor
sudo python3 python-tools/cpu_monitor.py# Build and install via DKMS
cd kernel-driver
sudo dkms add .
sudo dkms build ms912x/0.1
sudo dkms install ms912x/0.1
# Load the module
sudo modprobe ms912x
# The display will appear as a DRM device (check xrandr)
xrandr --listmonitors# Copy the service file
sudo cp systemd/mlvision-lcd.service /etc/systemd/system/
# Edit ExecStart path if needed, then enable
sudo systemctl daemon-reload
sudo systemctl enable --now mlvision-lcd.service
# Check status
sudo systemctl status mlvision-lcd- Frame buffer resolution: 800x600 (mode
0x4200), downscaled by the panel to 480x480 - Pixel format: UYVY 4:2:2 (code
0x2200) - BT.601 limited-range YCbCr - USB 2.0 limitation: Bulk endpoint FIFO holds only 2 packets (1024 bytes). Requires register toggle + CLEAR_HALT after each chunk. See USB2_WORKAROUND.md.
- Frame structure: 8-byte header + UYVY pixel data + 8-byte EOF marker
- Display timeout: The chip reverts to a "Welcome" screen if no frame data arrives within a few seconds. Continuous frame sending is required.
The 800x600 frame buffer is internally downscaled by the MS9132 to fit the 480x480 panel. The visible area does not map 1:1 to frame coordinates:
| Parameter | Value |
|---|---|
| Visible frame region (approx.) | x: 500-780, y: 100-400 |
| Visible center in frame coords | ~(635, 250) |
| Visible width in frame pixels | ~280 |
| Scale factor | ~1.7x (250 frame px -> 480 panel px) |
To display a 480x480 image centered on the panel, resize it to ~250x250 and place it at approximately (510, 125) in the 800x600 frame buffer.
| Resolution | Hz | Mode Code | Pixel Format |
|---|---|---|---|
| 640x480 | 60 | 0x4000 | UYVY |
| 720x480 | 60 | 0x0200 | UYVY |
| 720x576 | 60 | 0x1100 | UYVY |
| 800x600 | 60 | 0x4200 | UYVY |
| 1024x768 | 60 | 0x4700 | UYVY |
| 1152x864 | 60 | 0x4c00 | UYVY |
| 1280x600 | 60 | 0x4e00 | UYVY |
| 1280x720 | 60 | 0x4f00 | UYVY |
| 1280x768 | 60 | 0x5400 | UYVY |
| 1280x800 | 60 | 0x5700 | UYVY |
| 1280x960 | 60 | 0x5b00 | UYVY |
| 1280x1024 | 60 | 0x6000 | UYVY |
| 1360x768 | 60 | 0x6400 | UYVY |
| 1366x768 | 60 | 0x6600 | UYVY |
| 1400x1050 | 60 | 0x6700 | UYVY |
| 1440x900 | 60 | 0x6b00 | UYVY |
| 1600x1200 | 60 | 0x7300 | UYVY |
| 1680x1050 | 60 | 0x7800 | UYVY |
| 1920x1080 | 60 | 0x8100 | UYVY |
The protocol was reverse-engineered by capturing USB traffic from the Windows driver using Wireshark. See PROTOCOL.md for the full protocol documentation.
- USB 2.0 performance: Each full 800x600 frame takes ~7.5 seconds due to the 1024-byte chunk + rearm overhead. USB 3.0 transfers are near-instantaneous.
- Horizontal line artifacts: Faint horizontal lines may be visible on the LCD. This appears to be a panel characteristic or timing issue.
- No hotplug detection: Connector polling is disabled to avoid conflicts between EDID reads and USB 2.0 bulk transfers on the shared HID endpoint.
Kernel driver: GPL-2.0-only Python tools: MIT