Sxmo:Oneplus6

From postmarketOS

Here are some tips and tricks to ease the use of sxmo on the Oneplus6/T

Sound issues

Sxmo images seem come with pipewire by default.

At the moment pipewire does not seem to work well (see https://gitlab.com/postmarketOS/pmaports/-/issues/1534). Sound volume is low and saturated (as if there were some too low gains as well as saturated ones on the sound path). NOTE: SOLVED there is a new hack which maybe keep pipewire audio stable and fixes low volume and crackling issues:

https://gitlab.com/sdm845-mainline/linux/-/issues/48



Following is not needed anymore:

To get better results it is advised to switch back to pulse (sxmo supports alsa/pulse/pipewire). You can do so by removing the constraint on pipewire and installing pulseaudio :

$ sudo apk del sxmo-common-audio-pipewire
$ sudo apk add sxmo-common-audio-pulse

If you use pmbootstrap to generate your image, you can add sxmo-common-audio-pulse to your extra packages, it will generate a correct image.

Sometimes sound stops to work in calls, it can sometimes be solved by reloading ucm files :

$ sudo alsaucm reload

Calls

Once sound problems are solved you should be able to make calls.

But as there is no proximity sensor (yet), when receiving calls, the screen stays black.

A workaround is to add sxmo_wm.sh dpms off to sxmo_hook_ring.sh .

Beware that it does not (intentionaly) turns on the touchscreen, you'll have to answer using the physical button.

You can now also use the Proximity Sensor.

Lisgd

Oneplus6 and Oneplus6t have round corners, and corner gestures might not work very well.

To fix this, change $LISGD_EDGE_SIZE variable in

~/.config/sxmo/hooks/sxmo_hook_lisgdstart.sh

to -2.0.



One workaround is to recompile lisgd increasing edgesizes increasing it to 100 seems to work. Here is a diff of the changes that works for me.

diff --git a/config.def.h b/config.def.h
index d07f50d..feb6003 100644
--- a/config.def.h
+++ b/config.def.h
@@ -16,10 +16,10 @@ unsigned int degreesleniency = 15;
 unsigned int timeoutms = 800;
 unsigned int orientation = 0;
 unsigned int verbose = 0;
-double edgesizeleft = 50.0;
-double edgesizetop = 50.0;
-double edgesizeright = 50.0;
-double edgesizebottom = 50.0;
+double edgesizeleft = 100.0;
+double edgesizetop = 100.0;
+double edgesizeright = 100.0;
+double edgesizebottom = 100.0;
 char *device = "/dev/input/touchscreen";
 
 //Gestures can also be specified interactively from the command line using -g

(and the -s argument of lisgd).

Working around the notch

This can be done playing with gaps. On my OP6T, using SXMO_SWAY_SCALE=1 (my personal preference), the bar can be defined this way in .config/sxmo/sway

bar {
    position top
    gaps 30 30 0 40
    height 46
     
    # When the status_command prints a new line to stdout, swaybar updates.
    # The default just shows the current date and time.
    status_command sxmo_status_watch.sh -o pango
    swaybar_command /home/florent/bin/swaybar
     
     
    pango_markup enabled
     
    colors {
        statusline #ffffff
        background #00000000
        inactive_workspace #32323200 #32323200 #5c5c5c
        font "sxmo" 22
    }                                                                                                                          
}  

Then, to update the bars when rotating the screen you can use sxmo_rotate_hook.sh

case $1 in
normal)
    swaymsg bar bar-0 gaps 30 30 0 40
    swaymsg bar bar-0 height 46
    swaymsg gaps left all set 0
    swaymsg gaps right all set 0
    ;;
left)
    swaymsg bar bar-0 gaps 0 80 0 80
    swaymsg bar bar-0 height 40
    swaymsg gaps left all set 0
    swaymsg gaps right all set 80
    ;;
right)
    swaymsg bar bar-0 gaps 0 80 0 80
    swaymsg bar bar-0 height 40
    swaymsg gaps left all set 80
    swaymsg gaps right all set 0
    ;;
esac

There is, however, another approach by filling in some useless items in the notch area.

First:

cp /usr/share/sxmo/default_hooks/sxmo_hook_statusbar.sh ~/.config/sxmo/hooks/


then add a few ooooo between the battery and the wifi symbol just above the line containing sxmobar -a -f "$fgcolor" -b "$bgcolor" -t "$style" \

with adding this line to the hook:

sxmobar -a notch 22 oooooooooo

Then disable tray icons in swaybar:

nano ~/.config/sxmo/sway

Scroll down to the Status Bar: section and just below position top add tray_output none


Then reboot and enjoy.

The tristate button

Tristate button support has been included in the kernel and can be queried with evtest.

Here is what you can expect.

$ evtest 
No device specified, trying to scan all of /dev/input/event*
Not running as root, no devices may be available.
Available devices:
/dev/input/event0:	pm8941_pwrkey
/dev/input/event1:	Alert slider
/dev/input/event2:	Hall effect sensor
/dev/input/event3:	Volume keys
/dev/input/event4:	Synaptics S3706B
/dev/input/event5:	spmi_haptics
/dev/input/event6:	OnePlus 6T Headset Jack
Select the device event number [0-6]: 1
Input driver version is 1.0.1
Input device ID: bus 0x19 vendor 0x1 product 0x1 version 0x100
Input device name: "Alert slider"
Supported events:
  Event type 0 (EV_SYN)
  Event type 3 (EV_ABS)
    Event code 34 (?)
      Value      2
      Min        0
      Max        0
Properties:
Testing ... (interrupt to exit)
Event: time 1690117156.021495, type 3 (EV_ABS), code 34 (?), value 1
Event: time 1690117156.021495, -------------- SYN_REPORT ------------
Event: time 1690117159.236794, type 3 (EV_ABS), code 34 (?), value 0
Event: time 1690117159.236794, -------------- SYN_REPORT ------------
Event: time 1690117161.762579, type 3 (EV_ABS), code 34 (?), value 1
Event: time 1690117161.762579, -------------- SYN_REPORT ------------
Event: time 1690117162.771358, type 3 (EV_ABS), code 34 (?), value 2

The button reports as EV_ABS number 34 on /dev/input/event1 and gives current value.

Here is a little C code to query the value :

#include <stdio.h>
#include <linux/input.h>
#include <fcntl.h>
    
int main (int argc, char **argv)                                                               
{   
    int fd;
    int abs[6] = {0};
    
    if ((fd = open("/dev/input/event1", O_RDONLY)) < 0) {
        perror("evtest");
    }  
    
    ioctl(fd, EVIOCGABS(34), abs);
    printf("%d\n", abs[0]);
    
    return abs[0];
}

Save it as testsw.c and then compile with gcc testsw.c -o testsw

You can then use it directly in you bash scripts, for instance to test for the middle position :

$ test $(testsw) -eq 1 && echo middle

Using tristate to prevent locking

Once you have the testsw binary, you can query tristate button state before doing an action.

If you want to prevent locking when tristate is up (testsw returns 0), modify the suspend_disabled function from sxmo_hook_block_suspend.sh

suspend_disabled() {
    test $(testsw) -eq 0 || test -e "$XDG_CACHE_HOME/sxmo/sxmo.nosuspend"
}  

You can, using the same principle, prevent the phone from ringing, or do both (creating three profiles, one for each position).

Vibration

You need to modify the hooks for vibraton to work. In fact default hooks does not set the second argument of sxmo_vibrate. To perceive something it needs to be set at least to 1000, 20000 is ok.

So to vibrate during 1s you should use :

$ sxmo_vibrate 10000 20000

There is now a $SXMO_VIBRATE_STRENGTH variable to tune the second argument, so this should not be an issue anymore ;)

Proximity Sensor

Thanks to the work by Dylan Van Assche [1], sensor core is now supported on SDM845. So it is possible to access the data from accelerometer, magnetometer, light sensor and proximity sensor. The latter is essential during calls so lets try to benefit from this work.

Everything has been installed in latest base system, you'll have to add iio-sensors-proxy, it can access the sensors as if they were from the iio subsystem.

Once installed, proxymity sensor can be installed using monitor-sensor. Unfortunately it can only be run as root. But you should get something like that :

$ sudo monitor-sensor --proximity
    Waiting for iio-sensor-proxy to appear
+++ iio-sensor-proxy appeared
=== Has proximity sensor (near: 0)
    Proximity value changed: 1
    Proximity value changed: 0
    Proximity value changed: 1
    Proximity value changed: 0

Now, to integrate that to sxmo, you'll have to use a custom sxmo_proximitylock.sh[2], in this script, The analysis of the iio sensor device file has been replaced by the analysis of the output of monitor-sensor, if it outputs Proximity value changed: 1 that is because something is near ;). Here is the part that does the job (I'm certain it could be better, this is only a poc and I wanted to stick with the original sxmo logic) :

stdbuf -o L sudo monitor-sensor --proximity >> "$tmp" &
EVENTMONITORPID=$!
    
tail -f "$tmp" | while read -r line; do
    if echo "$line" | grep -q ".*Proximity value.*1"; then
        near
    elif echo "$line" | grep -q ".*Proximity value.*0"; then
        far
    elif echo "$line" | grep -q "=== Has proximity.*1"; then
        near
    elif echo "$line" | grep -q "=== Has proximity.*0"; then
        far
    fi
done &

Beware, as the scripts runs monitor-sensor using sudo you'll have to grant permission to use monitor-sensor with sudo without using password, it is a big caveheat but should be solved quickly. Here is the kind of line you have to write in your sudoers file :

%wheel ALL=(ALL) NOPASSWD:/usr/bin/monitor-sensor

The same logic should be applicable to the accelerometer events to enable autorotation, here is an implementation[3].

Wake From Suspend

Oneplus6 can wake from calls and sms, but as explained in the wiki page it has some issues as the processor is awaken by any event from the modem and they should be filtered (it should be possible ...).

On other DE this might cause issues if the screen is turned of. But on sxmo this is not the case. So it seems safe to let the modem wake the phone by issuing (as root) :

# echo enabled > /sys/bus/rpmsg/devices/4080000.remoteproc:glink-edge.IPCRTR.-1.-1/power/wakeup

As we want this to be enabled at startup you can write a script in /etc/local.d. Mine is called 50-enable-wake-from-suspend.start and contains :

#!/bin/sh
echo enabled > /sys/bus/rpmsg/devices/4080000.remoteproc:glink-edge.IPCRTR.-1.-1/power/wakeup

I've been using this past week and it has worked well ... The phone wakes (from the log) but not the screen !

Leds

Oneplus6 has a notification led. It is accessible from /sys/class/leds where you'll find three nodes :

$ ls
rgb:status  white:flash  yellow:flash

White led works just fine if you enable the torch (it is the same as in the pinephone). But rgb works differently as it comes as one node with two controls : multi_intensity and brightness. To get a blue led, you'll have to write :

$ echo 255 0 0 > multi_intensity
$ echo 511 > brightness

Here is a modified version of sxmo_led.sh[4] that uses the logic found on #op6.

You'll have to give the input user access to the leds control, this can be done with an udev script :

$ cat /etc/udev/rules.d/99-custom-led-permissions.rules 
SUBSYSTEM=="leds", ACTION=="add", RUN+="/bin/chgrp -R input /sys%p", RUN+="/bin/chmod -R g=u /sys%p"
SUBSYSTEM=="leds", ACTION=="change", ENV{TRIGGER}!="none", RUN+="/bin/chgrp -R input /sys%p", RUN+="/bin/chmod -R g=u /sys%p"