Add Framework laptop controls and monitoring with hardware-aware discovery
This commit is contained in:
@@ -0,0 +1,184 @@
|
||||
# Framework Laptop Tools
|
||||
|
||||
Experimental native desktop/tray controls for **Framework Laptop 13 Pro
|
||||
(Intel Core Ultra Series 3)**. Other Framework models are not yet validated.
|
||||
Install `framework-laptop-tools`, then open **Framework Laptop Tools** from the
|
||||
application menu or Fedora Tools settings. Installation changes no hardware
|
||||
settings. Hardware changes require administrator authorisation.
|
||||
|
||||
The window has Monitor, Lighting, Cooling, Battery, CPU, Tray icon and Preferences
|
||||
tabs.
|
||||
Bounded hardware settings use sliders with numeric fields for precise entry.
|
||||
All settings tabs share a **Save and Apply / Undo changes** bar. Editing stages
|
||||
changes without writing hardware, tray settings, sampling intervals or autostart.
|
||||
The bar stays visible across tabs. Save applies all pending settings with one
|
||||
administrator authorisation for hardware changes; Undo discards all unsaved edits.
|
||||
Successful saves become the new Undo baseline. If a hardware operation fails,
|
||||
earlier operations may already have applied; remaining edits stay pending.
|
||||
CPU slider bounds are read from Linux's hardware-frequency limits.
|
||||
|
||||
The Monitor page has CPU/GPU frequency, fan RPM, temperature and battery graphs.
|
||||
The battery heading shows full capacity, health and cycle count when available.
|
||||
Capacity calculated from charge capacity and nominal voltage is approximate.
|
||||
Temperature labels distinguish CPU-area/board sensors from die readings;
|
||||
raw sysfs paths remain available in tooltips. CPU frequency is Linux's reported
|
||||
average across CPU policies, not an instantaneous measurement of every core.
|
||||
GPU GT domains are shown separately rather than assuming they are identical.
|
||||
Click a coloured legend to toggle its series. Hidden series remain in the legend,
|
||||
greyed out and crossed out. Main temperature sensors are shown first; additional
|
||||
sensors are in a collapsed section that remembers their selections, not its open
|
||||
state. NVMe composite is the drive's overall reported temperature; numbered NVMe
|
||||
sensors are device-specific. Memory (SPD) measures the memory module, while EC
|
||||
area sensors are separate from processor/module readings.
|
||||
Each graph starts with blue. Further colours maximise their minimum OKLab distance
|
||||
from enabled colours within a readable candidate palette. Enabling a line assigns
|
||||
its colour; existing enabled lines keep theirs. Disabled colours are released.
|
||||
|
||||
Axes use round ticks and relative ages, with units below the vertical axes.
|
||||
Hover draws a guide at the same timestamp on every graph, even when their
|
||||
time spans differ. The tooltip still describes only the graph under the pointer.
|
||||
Hover for timestamps and the nearest
|
||||
available readings; no readings are invented across gaps or sleep. Battery charge
|
||||
uses the left percentage axis and rate the right watts axis (positive charging,
|
||||
negative discharging). Blue-grey bands mark logind-observed sleep; faint red bands
|
||||
mark observed charger connection. Plug changes during sleep are unknown, so AC
|
||||
bands are not extended through sleep. There is no history from before app startup.
|
||||
History is bounded to 600 samples per series and kept only while the app runs.
|
||||
|
||||
Sampling choices are 0.5/1/2/4 seconds for frequencies and temperatures, and
|
||||
15/30/60/120 seconds for the battery graph. Tray autostart is optional.
|
||||
Closing the window leaves monitoring in the tray; Quit exits the application.
|
||||
The Tray icon tab selects a normal icon, a history graph, or a number. Sources
|
||||
include CPU usage, CPU/GPU frequency, temperatures, charge level and battery rate.
|
||||
Sensor graphs share Monitor's history, including gaps, regardless of which
|
||||
sensor is selected for the tray. CPU usage also retains 600 samples. Switching
|
||||
readings or resuming from sleep does not clear history. Frequency numbers use
|
||||
GHz; the hover tooltip includes the full reading and unit. The tray has optional
|
||||
borders, a transparent or coloured background, line and fill colours, and optional
|
||||
area fill (including adjustable opacity). Frequency ceilings and temperature
|
||||
ranges are saved per sensor; battery rate also has adjustable bounds (initially
|
||||
−75–75 W), while percentages use 0–100.
|
||||
Outside readings can follow the inner edge, optionally in a different colour,
|
||||
or be hidden. The line remains inside the border when a border is enabled.
|
||||
Colour buttons show the opaque RGB swatch and label opacity separately, so a
|
||||
translucent fill is not mistaken for a darker RGB colour.
|
||||
Plasma applies its own hover highlight to tray icons; the app does not patch
|
||||
the system tray to suppress that effect.
|
||||
|
||||
## Controls and limits
|
||||
|
||||
- Keyboard brightness: 0–100%. **Use Fn+Space to leave or enter Auto mode.**
|
||||
The inspected 13 Pro firmware does not expose a host command to change that
|
||||
mode; its ambient-light logic overrides manual percentage changes in Auto.
|
||||
- Power-button brightness: 1–100%, or firmware Auto. This is the illuminated
|
||||
power button surrounding the fingerprint reader, not its authentication.
|
||||
The Automatic brightness checkbox disables the slider; both mode and brightness
|
||||
are staged until Save and Apply. Unchecking it allows a fixed brightness to be selected.
|
||||
- Fan: firmware Auto, manual duty, or a four-point curve. Manual values
|
||||
range from 0–100%, including fan off. Manual speeds below 30% show a warning.
|
||||
Saving manual or curve speeds below 30% also requires explicit confirmation.
|
||||
Four editable temperatures must increase between 20 and 85 °C, reaching 100%
|
||||
duty at the final point. Speeds between points are interpolated. The hottest EC sensor
|
||||
drives the curve. Speed increases immediately and decreases gradually.
|
||||
The privileged worker returns to Auto on suspend, reboot, a sensor fault,
|
||||
high temperatures, watchdog timeout or service exit. It does not change
|
||||
thermal warning/shutdown thresholds. Overrides remain active with the GUI closed.
|
||||
Saving an override writes `/etc/framework-laptop-tools/fan.json` and enables
|
||||
the worker at boot and after sleep. Sleep still stops the worker and restores
|
||||
Auto first. Failure restores Auto without a restart loop;
|
||||
saved settings are retried at the next boot/resume or explicit Save and Apply.
|
||||
Legacy temporary overrides are still recognised until stopped, but newly saved
|
||||
overrides always persist; installation itself does not enable them.
|
||||
Selecting firmware Auto removes saved settings and disables automatic startup.
|
||||
Do not combine with another fan controller.
|
||||
- Battery charge limit: 50–100%, stored by the firmware. Charge-power settings
|
||||
convert watts to a current limit using present battery voltage; actual watts
|
||||
vary with voltage and system/charger limits. Zero restores firmware defaults.
|
||||
This is **battery charging power**, not wall power or total laptop power.
|
||||
Charge current has no read-back command in the interface used here.
|
||||
The C-rate used by some other utilities expresses current relative to battery
|
||||
capacity: 1 C means 4.64 A for a 4.64 Ah battery, not a fixed number of watts.
|
||||
- CPU: minimum/maximum frequency, governor and energy preference, with optional
|
||||
separate battery/AC profiles. Frequency bounds are clamped per policy: a
|
||||
requested 4.5 GHz maximum does not restrict a P-core to a slower core's
|
||||
3.3 GHz ceiling. These are bounds, not guaranteed clock speeds.
|
||||
On Intel hybrid systems, kernel `cpu_core`/`cpu_atom` PMU membership identifies
|
||||
P-core and E-core policy groups, each with independent overrides. E-core limits
|
||||
clamp to each E-core's own ceiling, including lower-power E-cores. If the kernel
|
||||
cannot identify the groups unambiguously, a single shared range is offered.
|
||||
|
||||
Lighting and battery readings refresh on entry and every two seconds while their
|
||||
tab is visible. Unsaved edits are protected. Undo restores the unedited snapshot;
|
||||
normal live refresh then resumes. Charge-current limits cannot be read back, so
|
||||
their initial draft is firmware default, not a claim about current hardware state.
|
||||
Graph legend toggles remain immediate viewing controls, separate from staged
|
||||
settings tabs.
|
||||
|
||||
Battery time remaining/full uses UPower when available. Time to a custom charge
|
||||
limit is approximate, based on present current; charging taper makes it less
|
||||
accurate near full. No estimate is displayed when the needed readings are absent.
|
||||
|
||||
## Saved CPU profiles
|
||||
|
||||
CPU editing is staged. Splitting copies the shared values into both columns;
|
||||
battery is on the left and AC on the right. Joining uses the battery column.
|
||||
The hidden AC draft remains recoverable by splitting again until **Save and
|
||||
apply** commits the joined profile. Shared configurations store only one copy.
|
||||
**Undo changes** restores the last saved configuration. Background
|
||||
firmware refreshes do not overwrite a dirty CPU draft.
|
||||
|
||||
Frequency bounds, governor and energy preference are independent. Frequency
|
||||
overriding is unchecked by default, and both dropdowns default to **auto**.
|
||||
Auto means this tool never writes that attribute; it is not a preset or reset.
|
||||
Saving all-Auto profiles with frequency overriding off stops/disables the CPU
|
||||
service. Existing CPU limits are left unchanged, including when giving up a
|
||||
previous override, switching to an Auto power-source profile, or uninstalling.
|
||||
There is no TuneD reload or blanket restoration that could disturb another
|
||||
controller. Avoid assigning the same setting to multiple controllers.
|
||||
|
||||
The top of the CPU page always shows live Linux values, independently of the
|
||||
draft below. The frequency sliders are disabled when their override is unchecked;
|
||||
governor and EPP remain independently selectable. Tooltip explanations replace
|
||||
the longer instructions formerly at the bottom of the page.
|
||||
|
||||
Explicit overrides apply at boot, resume, power-source changes and successful
|
||||
TuneD profile changes after two seconds for the transition to settle. No TuneD
|
||||
dependency is required. The service works with the GUI closed; configuration is
|
||||
root-owned at `/etc/framework-laptop-tools/cpu.json`. Earlier all-or-nothing configurations
|
||||
are converted to independent overrides while preserving whether they were enabled.
|
||||
|
||||
With active Intel HWP, the Performance governor forces performance EPP and rejects
|
||||
other EPP values. For an explicitly selected Performance governor, this tool uses
|
||||
Powersave when the selected EPP (or the live EPP when Auto) is incompatible. The
|
||||
dropdown retains the user's choice and displays a warning. With EPP on Auto, the
|
||||
service observes EPP changes and reevaluates that explicit governor choice.
|
||||
|
||||
If governor is Auto and the live Performance governor blocks an explicitly chosen
|
||||
non-performance EPP, applying fails with a clear message: choose Powersave or leave
|
||||
EPP on Auto. It does not silently take over the Auto governor. Explicit governor
|
||||
changes can themselves affect EPP inside the kernel; Auto does not undo those
|
||||
kernel side effects. Linux does not provide independent control of every combination.
|
||||
|
||||
Thermal, power and boost limits still apply. Powersave on active Intel HWP allows
|
||||
dynamic clocks and boost; it does not mean locking the CPU at minimum frequency.
|
||||
|
||||
## Interfaces
|
||||
|
||||
No firmware patch, raw port I/O, downloaded executable, or third-party service
|
||||
is used. Monitoring reads Linux sysfs and UPower. A restricted KAuth helper
|
||||
uses sysfs and `/dev/cros_ec` for documented EC commands. Model checks are
|
||||
repeated in the privileged helper, not just in the GUI.
|
||||
|
||||
References:
|
||||
|
||||
- [Framework's hardware library and CLI](https://github.com/FrameworkComputer/framework-system)
|
||||
- [13 Pro keyboard firmware](https://github.com/FrameworkComputer/EmbeddedController/blob/fwk-sakura-20260429/zephyr/program/framework/src/keyboard_customization_13.c)
|
||||
- [Framework LED commands](https://github.com/FrameworkComputer/EmbeddedController/blob/fwk-sakura-20260429/zephyr/program/framework/src/led.c)
|
||||
- [Linux EC hardware monitor](https://www.kernel.org/doc/html/latest/hwmon/cros_ec_hwmon.html)
|
||||
- [Linux CPU frequency controls](https://www.kernel.org/doc/html/latest/admin-guide/pm/cpufreq.html)
|
||||
- [Intel governor and EPP behaviour](https://www.kernel.org/doc/html/latest/admin-guide/pm/intel_pstate.html)
|
||||
- [TuneD profile documentation](https://tuned-project.org/docs/manual.html)
|
||||
- [Linux battery units](https://www.kernel.org/doc/html/latest/power/power_supply_class.html)
|
||||
- [Framework Control](https://github.com/ozturkkl/framework-control) and
|
||||
[framework-tool-tui](https://github.com/grouzen/framework-tool-tui) provide
|
||||
useful interface references; their code is not bundled here.
|
||||
Reference in New Issue
Block a user