Fixes for using the Retroid Dual Screen (RDS) add-on with the Ayn Odin 3. It corrects the inverted touch axis and stops the touch and screen/video from cutting out — both applied automatically at boot.
| Problem | Status | How |
|---|---|---|
| Touch Y-axis is inverted (press top, registers bottom; X is fine) | ✅ Fixed | rds_yflip virtual touchscreen, Y-flipped, bound to the RDS display |
| Touch and screen/video cut out after ~1 min idle (had to replug) | ✅ Fixed | pin USB power so the RDS never runtime-autosuspends — this was the real cause of both the touch and the screen/video dropping |
Why the axis isn't a one-line setting: the RDS panel reports Y inverted in hardware — a vertical mirror, which cannot be undone by a display rotation (180° flips both axes), an IDC file (no axis-invert key), or a devicetree flag (the panel is USB-HID, not a DT device). It must be flipped in user space before Android sees it. Full write-up: docs/how-it-works.md.
A Magisk service runs at every boot and:
- Pins USB power — disables runtime autosuspend on all USB devices and re-pins on replug, so the RDS touch panel and its DisplayPort video (same USB-C cable) never cut out. (Root cause: the RDS USB device defaults to a 60 s autosuspend delay; the kernel suspends it after 60 s idle, killing touch + video until a replug.)
- Corrects the touch axis — a tiny native daemon (
rds_yflip, ~11 KB) grabs the RDS panel (EVIOCGRAB) and re-emits auinputvirtual touchscreen with Y flipped, bound to the RDS display via an IDC. It self-attaches on RDS replug and is restarted if it ever exits.
- ✅ Correct touch on the RDS second screen
- ✅ No more touch/video cut-out
- ✅ Survives reboot and RDS unplug/replug
- ✅ No app changes, no recompiled ROM, negligible overhead
- Ayn Odin 3 with the Retroid Dual Screen add-on
- Root via Magisk
- For the ADB install method: a computer with
adb
⚠️ The RDS shares the Odin 3's USB-C port. Plugging in a USB cable for ADB disconnects the RDS (display and touch). Do ADB work over Wireless debugging while the RDS is attached — see Connecting over Wi-Fi.
- Build the flashable zip (or just zip the
magisk-module/folder contents):scripts/build-magisk-zip.sh # produces odin3-rds-touch-fix-magisk.zip - Copy it to the Odin, open Magisk → Modules → Install from storage, pick the zip.
- With the RDS connected, reboot. Both fixes activate on boot; the module auto-detects your RDS display, so no per-device config is needed.
With the RDS connected and the device reachable over Wireless ADB:
scripts/install-adb.sh # or: scripts/install-adb.sh <ip:port>Pushes the binary, writes the display-bound IDC, installs both service.d boot
scripts (USB pin + remapper), and starts everything immediately — no reboot needed
to test.
The prebuilt binary in prebuilt/rds_yflip is a dynamic aarch64 executable using
only /system libraries, so it runs on a stock Odin 3. To rebuild, in a normal
Termux session on the device:
pkg install -y clang
clang -O2 -o rds_yflip src/rds_yflip.cThen place it at prebuilt/rds_yflip (Option B) or magisk-module/rds_yflip
(Option A) and reinstall. (Only the axis daemon is compiled; the USB pin is a shell
script.)
After install, touch the RDS: top→bottom should track correctly, and touch should no longer cut out when idle. Over Wi-Fi ADB:
adb shell su -c 'pgrep -x rds_yflip' # remapper PID = running
adb shell su -c 'pgrep -f usbpin.sh' # USB-pin loop = running
adb shell su -c 'sh /data/adb/.../tools/usb-status.sh' # or push tools/usb-status.sh
adb shell su -c 'tail /data/local/tmp/rds_yflip.log' # "grabbed /dev/input/eventN"tools/usb-status.sh should show the RDS device (vid=222a) as ctrl=on status=active asd=-1.
- Magisk module: remove it in the Magisk app and reboot.
- ADB install:
scripts/uninstall-adb.sh [ip:port].
The screen/video cut-out and the touch cut-out turned out to be the same root cause — USB autosuspend on the shared USB-C cable — so the USB-pin fix resolves both. (An earlier theory blamed a display-group doze / DP link that won't re-train; that was never reproduced once autosuspend was pinned.)
If you ever do see the RDS drop despite the pin, tools/rds_dpwatch.sh (install as a
boot service) and tools/rds_capture_now.sh (run at the moment of a drop) capture DP
link status + dmesg + logcat to /data/local/tmp/ for diagnosis — open an issue with
the output. For reference, moving the RDS to its own display group (extend/desktop
mode) is not viable on this ROM: force_desktop_mode_on_external_displays=1
crashes, and the Android 15 desktop-windowing flags are read-only.
USB disconnects the RDS, and classic adb tcpip 5555 resets on reboot, so use
Android 11+ Wireless debugging:
adb pair <ip>:<pairingPort> # Settings → Developer options → Wireless debugging → Pair (6-digit code)
adb connect <ip>:<connectPort> # the IP:port shown on the Wireless debugging screen| Symptom | Fix |
|---|---|
| Touch became an axis swap ("X is Y") | The IDC's touch.orientationAware isn't 0, or the IDC wasn't applied. Reinstall; ensure /data/system/devices/idc/Vendor_222a_Product_0002.idc exists and the daemon restarted after it was written. |
| Touch does nothing on the RDS | Virtual device not bound to the RDS display. Make sure the RDS was connected when the IDC was written; reconnect and reboot. |
| Still inverted after reboot | Daemon didn't start. tail /data/local/tmp/rds_yflip.log; confirm the Magisk service / service.d script is present. |
| Touch/video still cuts out | Check pgrep -f usbpin.sh and tools/usb-status.sh — the RDS device should be ctrl=on. |
| Pad/keys dead in a game (not touch) | Unrelated: check the Odin isn't in gamepad-to-mouse mode (settings get system global_gamepad_to_mouse_mode, toggled by L3). |
| Your panel needs X inverted or axes swapped | Pass --invert-x / --swap-xy in the boot service (see Tuning). |
Do not kill the daemon with
pkill -f rds_yflip—-fmatches your own command line (which contains "rds_yflip") and kills your shell. Usepkill -x rds_yflip.
src/rds_yflip.c axis remapper source (MIT)
prebuilt/rds_yflip prebuilt aarch64 binary (system-libs only)
magisk-module/ flashable Magisk module — service.sh (boot), usbpin.sh, rds_yflip, IDC
scripts/ install/uninstall/build helpers + rds_usbpin.sh
tools/ usb-status.sh + screen-dropout diagnostics (rds_dpwatch.sh, rds_capture_now.sh)
docs/how-it-works.md deep dive: diagnosis + design
Prebuilt binary SHA-256:
b006e310ffcc73b23c6617147331eee8141ec64fc7db07461cbcc8802f350349
- Verified on an Ayn Odin 3 (Android 15, Magisk) with the Retroid Dual Screen.
RDS touch panel id is
222a:0001. - The Y-inversion and the USB-autosuspend behaviour appear to be properties of the
RDS hardware/firmware, so both fixes should apply to any Odin 3 + RDS. Other hosts
exposing the same panel may work too (adjust
--vid/--pidif needed). - The USB pin disables runtime autosuspend on all USB devices (a tiny idle-power cost) — the simplest reliable way to keep the RDS alive.
- Community tool, not affiliated with Ayn or Retroid. Use at your own risk; root mods can affect your device. LICENSE (MIT).
Issues and PRs welcome — confirmations on other ROM versions, a real fix for the
screen-doze dropout, a proper --swap-xy range swap, and packaging improvements.