megi's PinePhone Development Log RSS

Surgenons in Gaza Surgeons in Gaza

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:

  1. Phone's internal battery is charged as fast as possible
  2. 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:

  1. 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
  2. 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
  3. 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.