Skip to content

Instantly share code, notes, and snippets.

@Ferdi265
Last active October 18, 2025 21:51
Show Gist options
  • Select an option

  • Save Ferdi265/d79f879b635c31c0dfdf7cd9dba510e9 to your computer and use it in GitHub Desktop.

Select an option

Save Ferdi265/d79f879b635c31c0dfdf7cd9dba510e9 to your computer and use it in GitHub Desktop.
Onda Oliver Book A1 -- Getting Arch Linux to Work properly
# /etc/X11/xorg.conf.d/10-monitors.conf
# rotate monitor correctly on X11
Section "Monitor"
Identifier "DSI-1"
Option "Rotate" "right"
EndSection
# rotate touchscreen input correctly on X11
Section "InputClass"
Identifier "Touchscreen DSI-1"
MatchIsTouchscreen "on"
MatchDevicePath "/dev/input/event*"
MatchDriver "libinput"
Option "TransformationMatrix" "0 1 0 -1 0 1 0 0 1"
EndSection
# /etc/X11/xorg.conf.d/20-touchpad.conf
# enable touchpad tapping on X11
Section "InputClass"
Identifier "Touchpad"
MatchIsTouchpad "on"
MatchDevicePath "/dev/input/event*"
Driver "libinput"
Option "Tapping" "on"
EndSection
# /etc/sddm.conf.d/10-virtualkbd.conf
# if you want a virtual keyboard in X11 SDDM
# don't use this if you use Wayland SDDM
[General]
InputMethod=qtvirtualkeyboard
# /etc/sddm.conf.d/10-wayland.conf
# if you want Wayland SDDM
# don't use this if you use X11 SDDM
[General]
DisplayServer=wayland
GreeterEnvironment=QT_WAYLAND_SHELL_INTEGRATION=layer-shell
[Wayland]
CompositorCommand=kwin_wayland --drm --no-lockscreen --no-global-shortcuts --locale1 --inputmethod maliit-keyboard
# /etc/udev/hwdb.d/70-accelerometer.hwdb
# needs package iio-sensor-proxy
sensor:modalias:acpi:KIOX0009*:dmi:*:svnOndaTLCGmbH:pnOliverBookA1:*
ACCEL_MOUNT_MATRIX=0, 1, 0; 1, 0, 0; 0, 0, 1
# /etc/udev/rules.d/70-touchscreen.rules
# calibration matrix for touchscreen to scale it to the whole screen and fix orientation
ACTION=="add", SUBSYSTEM=="input", ENV{ID_PATH}=="pci-0000:00:17.2-platform-i2c_designware-3", ENV{LIBINPUT_CALIBRATION_MATRIX}="0 2.7 0 2.1 0 0"
# /etc/systemd/system/fix-mode.service
# fix graphical glitches at boot; resetting the CRTC makes the next modeset work
[Unit]
Description=Fix DRM Mode
DefaultDependencies=no
Before=getty@tty1.service
Before=sddm.service
Before=plymouth-start.service
[Service]
Type=oneshot
ExecStart=/usr/local/bin/yeet DSI-1
[Install]
WantedBy=multi-user.target
# /etc/default/grub
# quiet splash ... enable plymouth boot screen
# video ... rotate the panel on plymouth/wayland
# fbcon ... rotate the panel on tty
# i915.modeset ... disable modesetting, for initial install to set things up
GRUB_CMDLINE_LINUX_DEFAULT="quiet splash video=DSI-1:panel_orientation=right_side_up fbcon=rotate:1"
#GRUB_CMDLINE_LINUX_DEFAULT="i915.modeset=0 fbcon=rotate:1"
# /var/lib/sddm/.config/kcminputrc
# copy over from ~/.config/kcminputrc after configuring
# /usr/lib/firmware/silead/mssl1680.fw
# copy over from https://github.com/Ferdi265/gsl-firmware at firmware/linux/silead/gsl1680-onda-oliver-book.fw
// /usr/local/bin/yeet
// needs package libdrm
// compile with gcc -Os -ldrm -I/usr/include/libdrm/ -o yeet yeet.c
#include <fcntl.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <xf86drm.h>
#include <xf86drmMode.h>
#include <sys/ioctl.h>
#include <linux/kd.h>
uint64_t get_property_value(int drm_fd, uint32_t object_id,
uint32_t object_type, const char *prop_name) {
drmModeObjectProperties *props =
drmModeObjectGetProperties(drm_fd, object_id, object_type);
for (uint32_t i = 0; i < props->count_props; i++) {
drmModePropertyRes *prop = drmModeGetProperty(drm_fd, props->props[i]);
uint64_t val = props->prop_values[i];
if (strcmp(prop->name, prop_name) == 0) {
drmModeFreeProperty(prop);
drmModeFreeObjectProperties(props);
return val;
}
drmModeFreeProperty(prop);
}
printf("Failed to find property %s\n", prop_name);
exit(1);
}
void add_property(int drm_fd, drmModeAtomicReq *req, uint32_t object_id,
uint32_t object_type, const char *prop_name, uint64_t value) {
uint32_t prop_id = 0;
drmModeObjectProperties *props =
drmModeObjectGetProperties(drm_fd, object_id, object_type);
for (uint32_t i = 0; i < props->count_props; i++) {
drmModePropertyRes *prop = drmModeGetProperty(drm_fd, props->props[i]);
if (strcmp(prop->name, prop_name) == 0) {
prop_id = prop->prop_id;
break;
}
}
if (prop_id == 0) {
printf("Failed to find property %s\n", prop_name);
exit(1);
}
drmModeAtomicAddProperty(req, object_id, prop_id, value);
}
char * get_connector_name(drmModeConnector *conn) {
const char *type_name = drmModeGetConnectorTypeName(conn->connector_type);
if (type_name == NULL) return NULL;
char *str = NULL;
asprintf(&str, "%s-%d", type_name, conn->connector_type_id);
return str;
}
int main(int argc, char *argv[]) {
if (argc != 2) {
printf("usage: yeet <CONNECTOR>\n");
return 1;
}
char *conn_name = argv[1];
printf("Opening DRM fd\n");
int drm_fd = open("/dev/dri/card1", O_RDWR | O_NONBLOCK);
if (drm_fd < 0) {
perror("open failed");
return 1;
}
if (drmSetClientCap(drm_fd, DRM_CLIENT_CAP_UNIVERSAL_PLANES, 1) != 0) {
perror("drmSetClientCap(UNIVERSAL_PLANES) failed");
return 1;
}
if (drmSetClientCap(drm_fd, DRM_CLIENT_CAP_ATOMIC, 1) != 0) {
perror("drmSetClientCap(ATOMIC) failed");
return 1;
}
printf("Finding connector %s\n", conn_name);
drmModeRes *resources = drmModeGetResources(drm_fd);
drmModeConnector *conn = NULL;
drmModeCrtc *crtc = NULL;
for (int i = 0; i < resources->count_connectors; i++) {
uint32_t conn_id = resources->connectors[i];
conn = drmModeGetConnector(drm_fd, conn_id);
if (conn->connection != DRM_MODE_CONNECTED) {
drmModeFreeConnector(conn);
conn = NULL;
continue;
}
char *name = get_connector_name(conn);
if (name == NULL || strcmp(name, conn_name) != 0) {
free(name);
drmModeFreeConnector(conn);
conn = NULL;
continue;
}
uint64_t crtc_id = get_property_value(drm_fd, conn_id, DRM_MODE_OBJECT_CONNECTOR, "CRTC_ID");
crtc = drmModeGetCrtc(drm_fd, crtc_id);
if (crtc == NULL) {
printf("Connector %s has no CRTC\n", name);
free(name);
drmModeFreeConnector(conn);
conn = NULL;
return 1;
}
printf("Connector %s has CRTC %zd\n", name, crtc_id);
free(name);
break;
}
drmModeFreeResources(resources);
// Yeet the CRTC
printf("Yeeting the CRTC\n");
drmModeAtomicReq *req = drmModeAtomicAlloc();
add_property(drm_fd, req, conn->connector_id, DRM_MODE_OBJECT_CONNECTOR, "CRTC_ID", 0);
add_property(drm_fd, req, crtc->crtc_id, DRM_MODE_OBJECT_CRTC, "MODE_ID", 0);
add_property(drm_fd, req, crtc->crtc_id, DRM_MODE_OBJECT_CRTC, "ACTIVE", 0);
uint32_t flags = DRM_MODE_ATOMIC_ALLOW_MODESET;
int ret = drmModeAtomicCommit(drm_fd, req, flags, NULL);
if (ret != 0) {
printf("Failed to yeet the CRTC\n");
return 1;
}
printf("Restoring text mode\n");
int fd = open("/dev/tty", O_RDWR | O_NOCTTY);
ioctl(fd, KDSETMODE, KD_TEXT);
return 0;
}
@Ferdi265
Copy link
Author

Ferdi265 commented Jan 24, 2025

I just updated my own Arch Linux system on the Oliver book, and it seems the yeet hack is less reliable than it was previously: It's not enough any more to have it start before SDDM. Manually switching to tty2, logging in as root, and running yeet, then switching back to tty1 fixes the screen, but automatically starting it before SDDM no longer works (yeet claims no errors, but the screen stays broken).

The touchpad also doesn't work until the keyboard attachment is disconnected/reconnected once, something that wasn't like this before the update. Sound still doesn't work,.

I'll see if I can make this work again.

@gborzi22
Copy link

@Ferdi265 In fact I had to modify fix-mode to start after lightdm. As for sound, alsamixer reports sof-essx8336 on my system it worked once I installed sof-firmware.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment