Skip to content
umer936Public
forked from rhgndf/ms912x

About

MacroSilicon USB to VGA/HDMI adapter (534d:6021) Linux DRM driver

Resources

Stars

0 stars

Watchers

0 watching

Forks

 
 

Repository files navigation

ms912x driver for Linux

Linux DRM/KMS driver for MacroSilicon USB-to-VGA/HDMI adapters.

Supported USB IDs:

  • 534d:6021 and alternate ID 534d:0821 (USB 2)
  • 345f:9132 (USB 3 capable; may negotiate a USB 2 link)

This branch targets current DRM APIs. The 0.3.x series was built and exercised on Fedora 44 with kernel 7.1.13-200.fc44.x86_64, including GNOME framebuffer imports. GNOME 50 mode switching was verified at 800x600, 1024x768, 1280x720, and 1440x900. Other kernels need their own build/runtime validation. For Linux 6.1, use the kernel-6.1 branch instead.

Build and install

Install a compiler, make, DKMS, and the development headers matching the running kernel. On Fedora:

sudo dnf install gcc make dkms "kernel-devel-$(uname -r)"
make -j"$(getconf _NPROCESSORS_ONLN)" W=1
sudo dkms install .
sudo install -m 644 99-ms912x.rules /etc/udev/rules.d/
sudo udevadm control --reload-rules

Save your work and reboot to activate the installed module and power-management rule. DKMS rebuilds the module for kernel updates when matching headers are available; newer kernel APIs may still require driver changes. Secure Boot systems must enroll the DKMS signing key before loading an out-of-tree module.

Verify the installed and loaded versions separately:

dkms status
modinfo -F version ms912x
cat /sys/module/ms912x/version
journalctl -k -b --no-pager | grep ms912x

make KVER=<kernel-release> builds for another installed kernel. For development, sh insmod.sh builds and loads the local module without installing it persistently. It refuses to unload a module held open by a compositor; never force an unload.

To roll back, keep the previous DKMS source/version, remove ms912x/0.3.2 with sudo dkms remove ms912x/0.3.2 --all, reinstall the previous version with sudo dkms install ms912x/<previous-version>, then reboot.

Optional aligned widescreen mode

Version 0.3.2 adds extra_mode_1360x768=1, disabled by default. It offers the standard 1360x768@60 timing even if absent from EDID, without replacing EDID or duplicating an existing mode. This mode was visually verified on a Samsung S20B350 with the tested 345f:9132 adapter. Its aspect ratio is within 0.4% of 16:9 and its 16-pixel-aligned width avoids the corruption seen at 1366x768.

After testing your monitor, install ms912x-widescreen.conf in /etc/modprobe.d/, reload the driver or reboot, and select 1360x768 in Display Settings. Kernel/GNOME may label the standard timing as 60.015 Hz. If the driver loads from an initramfs, regenerate that image after changing the module configuration. To undo this, remove the configuration and reload/reboot; no monitor firmware is changed.

The Samsung accepted the 1366x768 colour-bar probe but its normal desktop was scrambled; it rejected the 1920x1080 probe. Successful USB transfers alone do not prove a display mode works. Neither candidate is added by this option.

Invisible cursor on GNOME/Wayland

The adapter has no hardware cursor plane. GNOME should draw a software cursor, but mixed-GPU configurations may leave it invisible. The optional workaround below was verified with GNOME 50. It forces software cursors on all outputs in this user's session, not just the USB display:

mkdir -p ~/.config/environment.d
cp 90-ms912x-cursor.conf ~/.config/environment.d/

Log out and back in (or reboot) to activate it. This is a compositor workaround, not hardware-cursor support in the driver, and DKMS does not install it automatically. To undo it, remove the installed file, run systemctl --user unset-environment MUTTER_DEBUG_DISABLE_HW_CURSORS, and log out/in.

Transfer design

  • One approximately 8 MiB vmalloc snapshot buffer holds the largest supported rectangle; a 16 KiB DMA-capable USB buffer and 8 KiB scanline buffer are reused. There are no scatter-gather tables or asynchronous frame workers.
  • XRGB8888 is converted to limited-range BT.601 UYVY before USB transmission, so changes to the source framebuffer cannot mix pixels from different frames.
  • Each dirty rectangle has one protocol header and one terminator, even when split into many 16 KiB USB fragments. Version 0.2.0 incorrectly treated transport chunks as separate display updates, contributing to visible strip artifacts.
  • Dirty rectangles are aligned to 16-pixel hardware blocks. The final block is padded from the last visible pixel, without reading beyond the framebuffer row.
  • Control messages, EDID reads, modesets, and uploads are serialized. DRM unplug guards prevent USB access after disconnect, and DRM manages buffer lifetimes.
  • Modesets wait for firmware to report the requested width, height, and refresh rate rather than uploading pixels immediately after the control command.
  • Short transfers and control failures are reported. Only a zero-byte endpoint stall is retried after clearing the halt; partially transmitted packets are not blindly replayed. An incomplete upload stops streaming and schedules one USB reset/re-modeset attempt. Recovery is limited to one attempt per failure streak to avoid endless resets. A successful full repaint re-arms recovery.

Tests

On Linux, with Python 3 and a C compiler (Fedora additionally needs libasan and libubsan), run python3 tests/run.py. The tests compile the actual transfer code with mocked kernel/USB APIs and AddressSanitizer/UndefinedBehaviorSanitizer. They cover color conversion, framebuffer pitch, right-edge padding, clipping, maximum dimensions, single-rectangle framing across fragments, snapshot isolation, allocation failures, short writes, and stalls. They do not replace physical display, suspend/resume, or USB-unplug testing.

re_notes/test-display.py is an opt-in PyUSB hardware diagnostic for colour bars, mode readback, and continuous frame transfers. Stop the desktop and unload the display module before using it; restore the module/session afterward. A stale USB decoder may need a device reset before testing. The script never automatically unbinds the display driver. Its experimental 1600x900 choices are probes, not advertised driver modes. Firmware IDs are documented in the upstream mode investigation.

Known limitations

  • Only the resolutions and refresh rates in ms912x_mode_list are supported; unsupported modes are rejected, not silently replaced with another resolution.
  • The tested 345f:9132 unit ignored both documented 1600x900 mode IDs (0x6f00 and 0x7000) and retained its previous timing. A monitor advertising 1600x900 in EDID does not make that mode work in the adapter firmware. It is therefore deliberately not advertised by this driver.
  • Connector type is currently reported as HDMI, and connection status remains connected while the USB adapter is present because hardware status reads can flap during streaming. Monitor-side hotplug detection is not implemented.
  • A 60 Hz display mode does not imply 60 full-frame USB uploads per second. USB 2 bandwidth and CPU color conversion limit refresh performance. Sending one rectangle fixes strip framing but does not provide hardware-vblank synchronization or guarantee tear-free video. Lower resolutions and small dirty regions are faster.
  • Repeated -110 timeouts, especially USB descriptor-read errors, can indicate cable, power, or link problems. Check lsusb -t, try a direct USB 3 port and a suitable cable, and keep adapter autosuspend disabled using the supplied rule.

The protocol was reverse-engineered from Wireshark captures and device registers; see re_notes/ for the original investigation.

About

MacroSilicon USB to VGA/HDMI adapter (534d:6021) Linux DRM driver

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages