2021–12–12:
Pinephone Keyboard – p-boot landscape mode
I've been tuning my pinephone for use with the keyboard. First thing that
needed to be done was to switch and optimize everything to work well in
landscape mode.
I've started with p-boot, which can now render its virtual console in rotated
by 90 degrees. Everything else is the same. Background bitmaps just need to be
laid out and re-rendered so that they look nice when looked at in landscape
mode, but they are loaded the same as before.
I'll try adding keyboard support to p-boot in the future, too. It might be
useful in case you'll want to change kernel parameters, or whatever.
The rest of the system also needs some optimizations. Linux virtual console
can be rotated from get go by using kernel parameter
fbcon=rotate:1
. Default console font is also way too small for use
with the keyboard. Due to the layout of human body :), you'll be looking at the
display from further away than when using a touch interface, so text needs to be
larger. Use of some larger font than default 8×16 one is warranted. I enabled
SUN12×22 in my kernel, and my final boot argument for fbcon looks is now
fbcon=rotate:1,font:SUN12x22
.
Xorg X server to work in landscape mode needs some tweeks too. First display
outout to DSI-1 needs to be rotated via
xrandr --output DSI-1 --rotate right
and separately touchscreen
input needs to be transformed using some transformation matrix so that it
matches the display output rotation via
xinput set-prop 'pointer:Goodix Capacitive TouchScreen' 'Coordinate Transformation Matrix' 0 1 0 -1 0 1 0 0 1
.
I've put these commands to my .xsession
file, so that they are
applied at the start of each X session.
If you'd like to use Firefox with touch input, it's a good idea to add
export MOZ_USE_XINPUT2=1
to your X session too. Firefox will then
be able to recognize Goodix Capacitive TouchScreen as a touch input device, and
act accordingly. Tuning Firefox is another chapter itself. By default it uses
some physics based scrolling, which works really badly on Pinephone, so this
needs to be disabled. Force enabling GPU acceleration of layer composition, is
also not a terrible idea.
So far my system setup looks like this: https://megous.com/dl/tmp/ppkb-test.mp4
More chargers, more issues
Having two chargers and batteries chained together in a phone creates some
new issues.
First is that the phone is powered from the keyboard charger internally and
not over USB connector, so normal, USB based charger type detection and current
limit setting does not work.
The second issue is that both chargers act as power supply and battery
charger at once, and they both have some automatic behavior that may lead to
suboptimal results when left on their own.
On other dual battery devices, strategy for charging and taking power from
multiple batteries is likely handled by some embedded controller. On Pinephone,
this is not handled by anything. Some software needs to be written to monitor
the chargers and correct their settings based on their current status.
For example let's say both batteries are discharged. What should happen when
you connect the keyboard to the USB power supply? What I'd like to happen
is this:
- Phone's internal battery is charged as fast as possible
- When the internal battery is fully charged, keyboard battery starts
charging, while still supplying enough power to the phone so that internal
battery doesn't start discharging, until both batteries are fully charged.
What happens instead:
- Phone doesn't detect anything on USB port so the input power limit is left
at default 2.5W, this leads to very slow charging
- Keyboard charger starts charging the keyboard battery at max speed, because
it can take 10W from USB power supply, and the phone is only taking 2.5W
- After keyboard battery is fully charged, phone battery will still keep
charging only very slowly
When you disconnect the USB cable, the keyboard charger will now supply power
for both charging the phone battery, and for phone's other power needs. This is
not very efficient. It would be best if the internal battery had absolute
priority if it's not fully charged, because powering the phone from internal
battery is more efficient. It's also not very necessary to move charge from
keyboard battery to phone battery all the time. Due to pinephone design there
needs to be some charge in internal battery for the modem and wifi to work, but
it does not need to be kept at 100%. Shifting charge between batteries should
only be necessary when the internal battery charge drops bellow 30% so that
it's kept between 30% and 35% for example.
It would be more efficient to disable the phone's battery charging when the
charge is high enough, but still use the keyboard battery to supply power to the
phone, until keyboard battery charge gets very low. Then the system should
switch to using the phone battery.
All this needs to be managed by some userspace daemon, yet to be written,
because it will not happen automatically and automatic behavior will be annoying
and sub-optimal.
There will also be some need for user interaction, because the keyboard
battery charger is controlled by the button on the side of the keyboard. This
button enables the keyboard power output to the phone. Without user pressing it
it's not possible to power the phone from the keyboard. So the power management
daemon will have to have some way to notify the user about the status of the
keyboard charger and the need to press the button in some situations, to wake
the keyboard power management circuitry.