From bfb0dc391361ce60789859e44f1401bf481bc2ea Mon Sep 17 00:00:00 2001 From: Antoine Martin Date: Sat, 22 Apr 2023 21:10:37 -0400 Subject: [PATCH] rm-utils: new aport --- user/rm-utils/APKBUILD | 40 +++++++ user/rm-utils/battery-monitor.sh | 37 +++++++ user/rm-utils/epdc-init-auto.c | 126 +++++++++++++++++++++ user/rm-utils/epdc-show-bitmap.c | 184 +++++++++++++++++++++++++++++++ user/rm-utils/xorg.conf | 62 +++++++++++ 5 files changed, 449 insertions(+) create mode 100644 user/rm-utils/APKBUILD create mode 100644 user/rm-utils/battery-monitor.sh create mode 100644 user/rm-utils/epdc-init-auto.c create mode 100644 user/rm-utils/epdc-show-bitmap.c create mode 100644 user/rm-utils/xorg.conf diff --git a/user/rm-utils/APKBUILD b/user/rm-utils/APKBUILD new file mode 100644 index 0000000..b2a89c8 --- /dev/null +++ b/user/rm-utils/APKBUILD @@ -0,0 +1,40 @@ +# Maintainer: Antoine Martin (ayakael) +# Contributor: Antoine Martin (ayakael) + +[ "$CBUILD" != "$CHOST" ] && _cross="-$CARCH" || _cross="" + +pkgname=rm-utils +pkgver=0.0.1 +pkgrel=0 +pkgdesc="Utility files for reMarkable tablet" +arch="all" +url="http://www.davisr.me/projects/parabola-rm/" +license="GPL-3.0-only" +makedepends="gcc$_cross u-boot-rm-dev" +options="!check" # No testsuite +builddir="$srcdir" +source=" + battery-monitor.sh + epdc-init-auto.c + epdc-show-bitmap.c + xorg.conf +" + +builddir() { + $CC -c epdc-init-auto.c -o epdc-init-auto + $CC -c epdc-show-bitmap.c -o epdc-show-bitmap +} + +package() { + install -vDm755 battery-monitor.sh -t "$pkgdir"/usr/bin/battery-monitor + install -vDm755 epdc-show-bitmap -t "$pkgdir"/usr/bin/epdc-show-bitmap + install -vDm755 epdc-init-auto -t "$pkgdir"/usr/bin/epdc-init-auto + install -vDm644 xorg.conf -t "$pkgdir"/etc/defaults/xorg.conf +} + +sha512sums=" +7f0e6cb276357983b76c37c81a91c0d278dbec16d8982a97618f2217ef5e4d706211d921af6c79db3aad912d50aaed8cf5ce67f52a1081f61585eb97322c8deb battery-monitor.sh +50813c5c2e888e106416dd0b5b515c8a145da23343992b29ee8ad325a72a7b4bd464824636ea66c95f16df20f357646bf8e9e1ed66367f8b540b50dc608495d6 epdc-init-auto.c +274ba66666628ec12ee32e2054d7fd2d3ebcccb144784934f645472d482ed0d56777ebd87a342dd121c6e753e8efc776d9c340e4f54ac3b0fb460afbdb0020fe epdc-show-bitmap.c +e14a61751e4c830652e7a849b9d596c6bc213fed87ba3f9f7c3df0d5fe35ddf28bde7de2fa977c0321639503ceff5abffd0d856380eacce24389fd50eaf3372a xorg.conf +" diff --git a/user/rm-utils/battery-monitor.sh b/user/rm-utils/battery-monitor.sh new file mode 100644 index 0000000..fb5dbc7 --- /dev/null +++ b/user/rm-utils/battery-monitor.sh @@ -0,0 +1,37 @@ +#!/usr/bin/env bash +# +# battery-monitor.sh +# Prints the state of charge of the tablet's battery +# +# Parabola-rM is a free operating system for the reMarakble tablet. +# Copyright (C) 2020 +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. + +# Path for Linux 4.9 +battpath="/sys/class/power_supply/bq27441-0" + +chargenow="$(cat $battpath/charge_now)" +chargefull="$(cat $battpath/charge_full)" +status="$(cat $battpath/status)" + +chargepct="$(echo $chargenow $chargefull \ + | awk '{printf "%f", $1 / $2 * 100}' \ + | cut -d'.' -f1)" +symbol="" +if [[ "Charging" == "$status" ]]; then + symbol=$'\u26a1' # Lightning symbol +fi + +echo "${symbol}${chargepct}%" diff --git a/user/rm-utils/epdc-init-auto.c b/user/rm-utils/epdc-init-auto.c new file mode 100644 index 0000000..a309fad --- /dev/null +++ b/user/rm-utils/epdc-init-auto.c @@ -0,0 +1,126 @@ +/* + epdc-init-auto.c + Initializes the EPDC framebuffer into a deferred-IO automatic-update + mode + + Parabola-rM is a free operating system for the reMarakble tablet. + Copyright (C) 2020 Davis Remmel + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . +*/ + +#include +#include +#include +#include +#include +#include +#include "mxcfb.h" +#include + +int main() +{ + int ret; + int fb = open("/dev/fb0", O_RDWR); + struct fb_var_screeninfo vinfo; + ret = ioctl(fb, FBIOGET_VSCREENINFO, &vinfo); + if (0 != ret) { + fprintf(stderr, "FBIOGET_VSCREENINFO failed with error " + "%d, aborting\n", ret); + return 1; + } + + vinfo.xres = 1872; + vinfo.yres = 1404; + vinfo.pixclock = 160000000; + vinfo.left_margin = 32; + vinfo.right_margin = 326; + vinfo.upper_margin = 4; + vinfo.lower_margin = 12; + vinfo.hsync_len = 44; + vinfo.vsync_len = 1; + vinfo.sync = 0; + vinfo.vmode = FB_VMODE_NONINTERLACED; + vinfo.accel_flags = 0; + vinfo.activate = FB_ACTIVATE_FORCE; + + // Put screen info. Sometimes this fails when trying to set the + // pixclock. This may be a bug in the driver's arithmetic. + ret = ioctl(fb, FBIOPUT_VSCREENINFO, &vinfo); + if (0 != ret) { + fprintf(stderr, "FBIOPUT_VSCREENINFO failed with error " + "%d, attempting to reset pixclock\n", ret); + vinfo.pixclock = 6250; + ioctl(fb, FBIOPUT_VSCREENINFO, &vinfo); + vinfo.pixclock = 160000000; + ret = ioctl(fb, FBIOPUT_VSCREENINFO, &vinfo); + if (0 != ret) { + fprintf(stderr, "FBIOPUT_VSCREENINFO failed " + "with error %d, aborting\n", ret); + return 1; + } + } + + // Pull the screeninfo agian + ret = ioctl(fb, FBIOGET_VSCREENINFO, &vinfo); + if (0 != ret) { + fprintf(stderr, "FBIOGET_VSCREENINFO failed with error " + "%d, aborting\n", ret); + return 1; + } + + printf("x:%d y:%d activate:%d bpp:%d rotate:%d hsync_len:%d" + "vsync_len: %d sync:%d\n", + vinfo.xres, vinfo.yres, vinfo.activate, + vinfo.bits_per_pixel, vinfo.rotate, vinfo.hsync_len, + vinfo.vsync_len, vinfo.sync); + + struct fb_fix_screeninfo finfo; + ret = ioctl(fb, FBIOGET_FSCREENINFO, &finfo); + if (0 != ret) { + fprintf(stderr, "FBIOGET_FSCREENINFO failed with error " + "%d, aborting\n", ret); + return 1; + } + + // In case the EPDC wasn't accessible + ret = ioctl(fb, MXCFB_ENABLE_EPDC_ACCESS); + if (0 != ret) { + fprintf(stderr, "MXCFB_ENABLE_EPDC_ACCESS failed with " + "error %d, aborting\n", ret); + return 1; + } + + // Set auto update mode + __u32 aumode = AUTO_UPDATE_MODE_AUTOMATIC_MODE; + ret = ioctl(fb, MXCFB_SET_AUTO_UPDATE_MODE, &aumode); + if (0 != ret) { + fprintf(stderr, "MXCFB_SET_AUTO_UPDATE_MODE failed " + "with error %d, aborting\n", ret); + return 1; + } + + // Queue-and-merge is best-performing + __u32 uscheme = UPDATE_SCHEME_QUEUE_AND_MERGE; + ret = ioctl(fb, MXCFB_SET_UPDATE_SCHEME, &uscheme); + if (0 != ret) { + fprintf(stderr, "MXCFB_SET_UPDATE_SCHEME failed with " + "error %d, aborting\n", ret); + return 1; + } + + close(fb); + return 0; +} + diff --git a/user/rm-utils/epdc-show-bitmap.c b/user/rm-utils/epdc-show-bitmap.c new file mode 100644 index 0000000..196e39b --- /dev/null +++ b/user/rm-utils/epdc-show-bitmap.c @@ -0,0 +1,184 @@ +/* +epdc-show-bitmap.c +Displays a raw image to the EPDC framebuffer + +Parabola-rM is a free operating system for the reMarakble tablet. +Copyright (C) 2020 Davis Remmel + +This program is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program. If not, see . +*/ + +#include +#include +#include +#include +#include +#include +#include "mxcfb.h" +#include +#include +#include +#include + +int main(int argc, char *argv[]) { + if (argc < 2) { + printf("Must pass an image as an argument.\n"); + return 1; + } + + int ret; + int fb = open("/dev/fb0", O_RDWR); + struct fb_var_screeninfo vinfo; + ret = ioctl(fb, FBIOGET_VSCREENINFO, &vinfo); + if (0 != ret) { + printf("FBIOGET_VSCREENINFO failed with error %d" + ", aborting\n", ret); + return 1; + } + + vinfo.xres = 1872; + vinfo.yres = 1404; + vinfo.pixclock = 160000000; + vinfo.left_margin = 32; + vinfo.right_margin = 326; + vinfo.upper_margin = 4; + vinfo.lower_margin = 12; + vinfo.hsync_len = 44; + vinfo.vsync_len = 1; + vinfo.sync = 0; + vinfo.vmode = FB_VMODE_NONINTERLACED; + vinfo.accel_flags = 0; + vinfo.activate = FB_ACTIVATE_FORCE; + + // Put screen info. Sometimes this fails when trying to set the + // pixclock. This may be a bug in the driver's arithmetic. + ret = ioctl(fb, FBIOPUT_VSCREENINFO, &vinfo); + if (0 != ret) { + fprintf(stderr, "FBIOPUT_VSCREENINFO failed with error " + "%d, attempting To reset pixclock\n", ret); + vinfo.pixclock = 6250; + ioctl(fb, FBIOPUT_VSCREENINFO, &vinfo); + vinfo.pixclock = 160000000; + ret = ioctl(fb, FBIOPUT_VSCREENINFO, &vinfo); + if (0 != ret) { + fprintf(stderr, "FBIOPUT_VSCREENINFO failed " + "with error %d, aborting\n", ret); + return 1; + } + } + + printf("x:%d y:%d activate:%d bpp:%d rotate:%d hsync_len:%d" + "vsync_len: %d sync:%d\n", + vinfo.xres, vinfo.yres, vinfo.activate, + vinfo.bits_per_pixel, vinfo.rotate, vinfo.hsync_len, + vinfo.vsync_len, vinfo.sync); + + struct fb_fix_screeninfo finfo; + ret = ioctl(fb, FBIOGET_FSCREENINFO, &finfo); + if (0 != ret) { + fprintf(stderr, "FBIOGET_FSCREENINFO failed with error " + "%d, aborting\n", ret); + return 1; + } + + // In case the EPDC wasn't accessible + ret = ioctl(fb, MXCFB_ENABLE_EPDC_ACCESS); + if (0 != ret) { + fprintf(stderr, "MXCFB_ENABLE_EPDC_ACCESS failed with " + "error %d, aborting\n", ret); + return 1; + } + + // Set to partial mode to control update parameters + __u32 aumode = AUTO_UPDATE_MODE_REGION_MODE; + ret = ioctl(fb, MXCFB_SET_AUTO_UPDATE_MODE, &aumode); + if (0 != ret) { + fprintf(stderr, "MXCFB_SET_AUTO_UPDATE_MODE failed " + "with error %d, aborting\n", ret); + return 1; + } + + + // No artifacts in display output + __u32 uscheme = UPDATE_SCHEME_SNAPSHOT; + ret = ioctl(fb, MXCFB_SET_UPDATE_SCHEME, &uscheme); + if (0 != ret) { + fprintf(stderr, "MXCFB_SET_UPDATE_SCHEME failed with " + "error %d, aborting\n", ret); + return 1; + } + + // Set up update (same region for all writes, gets reused) + struct mxcfb_update_data bupdate; + bupdate.update_region.left = 0; + bupdate.update_region.top = 0; + bupdate.update_region.width = 1872; + bupdate.update_region.height = 1404; + bupdate.waveform_mode = WAVEFORM_MODE_AUTO; + bupdate.update_mode = UPDATE_MODE_FULL; + bupdate.update_marker = 0; + bupdate.temp = TEMP_USE_AMBIENT; + bupdate.flags = 0; + + struct mxcfb_update_marker_data updm; + updm.update_marker = 0; + + // mmap to framebuffer + int buflength = vinfo.yres_virtual * finfo.line_length; + printf("buflength %d\n", buflength); + char * region = mmap(0, buflength, PROT_READ | PROT_WRITE, + MAP_SHARED, fb, (off_t)0); + if (region == MAP_FAILED) { + fprintf(stderr, "map failed!\n"); + return 1; + } + + // Write black + memset(region, 0x00, buflength); + ioctl(fb, MXCFB_SEND_UPDATE, &bupdate); + ioctl(fb, MXCFB_WAIT_FOR_UPDATE_COMPLETE, &updm); + + // Write white + memset(region, 0xff, buflength); + ioctl(fb, MXCFB_SEND_UPDATE, &bupdate); + ioctl(fb, MXCFB_WAIT_FOR_UPDATE_COMPLETE, &updm); + + // Write image + FILE *pattern = fopen(argv[1], "rb"); + fseek(pattern, 0, SEEK_END); + long psize = ftell(pattern); + printf("psize is %d\n", psize); + fseek(pattern, 0, SEEK_SET); + + if (psize != buflength) { + fprintf(stderr, "Image must match framebuffer size\n"); + return 1; + } + + char *buffer = malloc(psize); + fread(buffer, psize, 1, pattern); + fclose(pattern); + + memcpy(region, buffer, psize); + ret = ioctl(fb, MXCFB_SEND_UPDATE, &bupdate); + ioctl(fb, MXCFB_WAIT_FOR_UPDATE_COMPLETE, &updm); + if (0 != ret) { + fprintf(stderr, "MXCFB_SEND_UPDATE failed with error " + "%d, aborting\n", ret); + return 1; + } + + close(fb); + return 0; +} diff --git a/user/rm-utils/xorg.conf b/user/rm-utils/xorg.conf new file mode 100644 index 0000000..8ebf064 --- /dev/null +++ b/user/rm-utils/xorg.conf @@ -0,0 +1,62 @@ +Section "ServerLayout" + Identifier "reMarkable Tablet RM100" + Screen 0 "Screen0" + InputDevice "wacom" "CorePointer" +EndSection + +Section "ServerFlags" + Option "BlankTime" "0" + Option "StandbyTime" "0" + Option "SuspendTime" "0" + Option "OffTime" "0" +EndSection + +Section "Monitor" + Identifier "Monitor0" + DisplaySize 210 158 # mm, sets DPI + Modeline "1872x1404_30.00" 104.26 1872 1960 2152 2432 1404 1405 \ + 1408 1429 -HSync +Vsync + Option "PreferredMode" "1872x1404_30.00" +EndSection + +Section "Screen" + Identifier "Screen0" + Monitor "Monitor0" + Device "epdc0" + DefaultDepth 16 + SubSection "Display" + Depth 16 + Modes "1872x1404_30.00" + EndSubSection +EndSection + +Section "Device" + Identifier "epdc0" + Driver "fbdev" + Option "fbdev" "/dev/fb0" + Option "Rotate" "CW" +EndSection + +Section "InputDevice" + Identifier "wacom" + Driver "evdev" + Option "Protocol" "Auto" + Option "Device" "/dev/input/event0" + Option "SwapAxes" "1" + Option "InvertY" "1" +EndSection + +Section "InputClass" + Identifier "touchscreen" + MatchIsTouchscreen "on" + MatchDevicePath "/dev/input/event1" + Driver "libinput" + Option "CalibrationMatrix" "-1 0 1 0 -1 1 0 0 1" # Rot 180 +EndSection + +Section "InputClass" + Identifier "facialbuttons" + MatchIsKeyboard "on" + MatchDevicePath "/dev/input/event2" + Driver "libinput" +EndSection