Skip to content

Instantly share code, notes, and snippets.

@Ferdi265
Last active October 5, 2023 15:07
Show Gist options
  • Save Ferdi265/d79f879b635c31c0dfdf7cd9dba510e9 to your computer and use it in GitHub Desktop.
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 Oct 2, 2023

The race condition in fix-mode can be fixed by adding this patch to seatd. The issue is that seatd doesn't start up fast enough and doesn't notify systemd that it is running, leading to fix-mode not finding a seat.

The use of sway in fix-mode can also be replaced with a stripped-down version of the simple example program from wlroots that doesn't render anything and exits once it renders its first frame. This can likely be stripped down even more.

@Ferdi265
Copy link
Author

Ferdi265 commented Oct 2, 2023

Race condition and dependencies fixed in latest version. Now only needs a simple C program (yeet) and libdrm.

@Ferdi265
Copy link
Author

Ferdi265 commented Oct 5, 2023

Added Accelerometer transformation Matrix

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