Skip to content
 
 

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

1,465,054 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Raspberry Pi Linux kernel for ClockworkPi cyberdecks

Fork of the Raspberry Pi Linux kernel with device-tree overlays and driver tweaks for uConsole, DevTerm, and related ClockworkPi hardware. The patches below are meant for any board in this family that uses the same drivers and PMICs, not only one model. Based on work by ak-rex, with additional changes maintained here.

What this tree adds

  • ClockworkPi-oriented support — overlays and integration for CM4/CM5 and classic Pi builds where applicable.
  • Upstream-aligned base — tracks the Raspberry Pi kernel tree; changes are kept as small, reviewable patches on top.
  • Hardware-focused tweaks — backlight steps, PMIC/battery behavior, and infrared timing tuned for real devices (not generic defaults).

Custom changes (this fork)

1. OCP8178 backlight — 21 brightness steps (was 10)

The OCP8178 one-wire backlight driver (used on several ClockworkPi LCD setups) originally exposed only 10 usable levels (MAX_BRIGHTNESS_VALUE 9 plus off), which made the panel jump in coarse steps.

  • What changed: MAX_BRIGHTNESS_VALUE is raised to 21 (22 hardware indices including 0), with a new lookup table mapping each step to chip register values. Steps are spread across the 0–31 hardware range so the UI can approximate about 5% per step from minimum to maximum useful brightness.
  • Why: Finer control in dim environments and when avoiding “too bright / too dark” with only a few levels.

2. AXP PMIC battery driver (AXP228 path) — what changed for you

These edits are in the AXP20x battery driver (axp20x_battery.c) and the small regmap update in axp20x.c needed so the fuel gauge can be used the way below. The battery appears in sysfs as axp20x-battery:

/sys/class/power_supply/axp20x-battery/

Design (*_design) vs live gauge readings

  • charge_full_design and energy_full_design are not live measurements from the fuel gauge. They are the nominal design values the kernel keeps for “how big the pack should be”: what you put in the device tree—either baked into the overlay or overridden from config.txt (charge_full_design_uah, energy_full_design_uwh). If you only set charge in the overlay/config, energy design is estimated in the driver (see probe below). Those numbers drive percentage and energy_now math. In this fork, both sysfs files report the same internal design energy figure (in µWh); the name charge_full_design follows the kernel ABI, but the value matches energy_full_design here.
  • charge_full and charge_now are operational values from the PMIC’s fuel gauge (µAh). charge_now is the remaining charge estimate. charge_full is the full-charge capacity the PMIC currently holds in its fuel-gauge state—it may have been programmed (device tree, sysfs write, or earlier calibration) or learned by the chip; it is not the same thing as the static *_design numbers above.

Other sysfs files

File Meaning (plain language)
charge_full Current full-capacity figure stored in the PMIC fuel gauge (µAh): whatever the chip is using now—set (DT, sysfs, or prior learn) or auto-estimated by the gauge. Writable — writing µAh programs that stored value (runtime, same family of effect as design charge from DT).
charge_now Remaining charge from the gauge (µAh).
charge_full_design See above: design baseline (µWh in this driver), from overlay/config or estimate.
energy_full_design Same design energy in µWh as above, from overlay/config or estimate.

Calibration (calibrate)

  • Sysfs: /sys/class/power_supply/axp20x-battery/calibrate
  • Read: Raw bits from the PMIC coulomb / calibration control register (which calibration-related flags are set).
  • Write: 1 turns on only the full-capacity re-learn enable bit on the AXP228 (AXP228_FULL_CAPACITY_CALIBRATE_EN). 0 clears that bit. In this fork, enabling calibration no longer sets the extra AXP228_CAPACITY_CALIBRATE bit in the same register that the previous code toggled together with it—so you avoid flipping that second path when you only want full-capacity learning.

Boot behaviour added in probe

  • If the device tree gives charge-full-design-microamp-hours, that value is written into the PMIC and checked against what can be read back.
  • If it does not, the driver reads the design charge already stored in the PMIC and logs it.
  • energy-full-design-microwatt-hours from the device tree is used when present; otherwise energy design is estimated from the design charge using 3.7 V as a typical average cell voltage (charge_design_uAh × 37 / 10 → µWh).

Other changes in the same patch

  • Power key (PEK): instant power-on on a short press—the PMIC is configured so you no longer need to hold the button for about a second to turn the device on (other PEK timing bits are set in the same register write as in the patch).
  • Overlay clockworkpi-custom-battery-overlay was removed; capacity is tuned via the main ClockworkPi overlays and parameters below.

Setting battery capacity from config.txt

The ClockworkPi overlays keep design capacity properties at 0 in the .dts (no baked-in pack size) so nothing assumes a default mAh/Wh. Set charge_full_design_uah when you know your pack’s design charge; otherwise the driver falls back to the PMIC / estimate behaviour described in Boot behaviour above.

energy_full_design_uwh has little practical benefit in normal use: the driver already derives design energy from the charge figure when you do not set it, and day-to-day behaviour does not depend on tuning both separately. You can omit it and only pass charge_full_design_uah.

ClockworkPi overlays expose those parameters so you can match your pack without rebuilding. Example for uConsole CM5 — set design charge to 6.9 Ah (6900000 µAh):

dtoverlay=clockworkpi-uconsole-cm5,charge_full_design_uah=6900000

Use the overlay name that matches your board (clockworkpi-uconsole, clockworkpi-devterm, CM5 variants, etc.). You only need a second line if you insist on supplying design energy manually (usually unnecessary):

dtoverlay=clockworkpi-uconsole-cm5,charge_full_design_uah=6900000,energy_full_design_uwh=25530000

Applying a new capacity value: The PMIC may keep the old design capacity until it loses all power. A normal shutdown or reboot is often not enough—the chip can stay alive from the cells. Remove the battery cells (full disconnect), wait a moment, reinsert, then boot. The same caveat applies if you write a new value to charge_full in sysfs: it may not visibly stick until after that kind of full power cycle.


Building and deploying

Follow the standard Raspberry Pi kernel build workflow (cross-compile or native), install modules/kernel image as for your board (CM4/CM5 vs Pi 4, etc.), and enable the appropriate dtoverlay= for your ClockworkPi device in config.txt. Override battery parameters if your pack differs from the default overlay values.

For upstream history and base kernel documentation, see raspberrypi/linux and the original ak-rex/ClockworkPi-linux project.


Prebuilt kernel (APT on GitHub Pages)

GitHub Actions cross-builds an arm64 kernel (bcm2712_defconfig + 4K pages) into Debian packages:

  • linux-image-<release>-clockworkpi — modules, DTBs, and a postinst hook that installs drop-in boot images
  • linux-headers-<release>-clockworkpi — headers for out-of-tree modules
  • linux-image-clockworkpimetapackage that always depends on the latest image (so apt upgrade works)

Successful runs on branch clockworkpi-7.2.y-live (or manual workflow_dispatch) publish a signed APT repository on GitHub Pages and attach the same .deb files to a GitHub Release.

What URL
APT / download page https://clusterm.github.io/ClockworkPi-linux/
APT base https://clusterm.github.io/ClockworkPi-linux/apt/
Repository https://github.com/ClusterM/ClockworkPi-linux/
Workflow runs & artifacts Actions

Install from APT (recommended)

Warning: Have a backup of /boot/firmware (or another way to recover the boot partition). A mismatched kernel/modules pair can prevent boot until you restore it.

curl -fsSL https://clusterm.github.io/ClockworkPi-linux/apt/key.gpg \
  | sudo gpg --dearmor -o /usr/share/keyrings/clockworkpi-linux.gpg
echo "deb [signed-by=/usr/share/keyrings/clockworkpi-linux.gpg arch=arm64] https://clusterm.github.io/ClockworkPi-linux/apt stable main" \
  | sudo tee /etc/apt/sources.list.d/clockworkpi-linux.list
sudo apt update
sudo apt install linux-image-clockworkpi
sudo reboot

Later updates:

sudo apt update && sudo apt upgrade
sudo reboot

Keep your ClockworkPi dtoverlay= (and other hardware) lines in /boot/firmware/config.txt. The package does not edit that file for boot selection.

What the package does on install

The linux-image-*-clockworkpi postinst hook (when /boot/firmware exists):

  1. Copies the kernel to the firmware defaults: kernel_2712.img (CM5 / Pi 5) and kernel8.img (CM4 / Pi 4), plus a versioned kernel-<release>.img
  2. Refreshes Broadcom .dtb files and overlays/
  3. Does not add kernel= / initramfs to config.txt (bootloader defaults are enough)

One-time setup: if config.txt still has custom kernel=… lines (old manual installs), delete those lines (and any leftover # BEGIN/END clockworkpi-kernel block from earlier package versions). After that, upgrades only overwrite kernel_2712.img / kernel8.img.

Debian linux-image-*+deb13-arm64 packages

Stock Debian/Raspberry Pi OS linux-image-*deb13* packages may still be installed. They put files under /boot/vmlinuz-* and large initrds, but they do not control firmware boot unless you enable KERNEL=auto in /etc/default/raspi-firmware. This project's packages intentionally do not Conflict/Replace them. You can apt purge old unused *deb13* kernels to reclaim disk space if you want.

Rollback

  1. Boot an older image if you kept kernel-<oldrelease>.img, or restore a backup of /boot/firmware.
  2. Or install a previous version still kept in the APT pool (last few builds are retained), then reboot.

CI note (maintainers)

Publishing the signed APT repo requires the repository secret APT_GPG_PRIVATE_KEY (armored private key). Optional: APT_GPG_PASSPHRASE. Without the secret, live/Pages publish fails on purpose so an unsigned repo is never uploaded.

About

Raspberry Pi kernel builds with tweaks for the uConsole and other ClockworkPi cyberdecks by @ak-rex and me

Resources

Stars

2 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages