A companion media player firmware for Cadence.
  • Dart 78.7%
  • Rust 15.8%
  • C 2%
  • C++ 1.5%
  • Shell 0.7%
  • Other 1.2%
Find a file
Repository files (latest commit first)
Filename Latest commit message Latest commit date
Chris Hendrickson 2a76da51a7
All checks were successful
CI / Analyze and test Tempo app (push) Successful in 43s
CI / Analyze and test tempod (push) Successful in 43s
CI / Analyze and test Toolbox (push) Successful in 42s
CI / Decide what changed (push) Successful in 7s
CI / Build tempod for the Y2 (push) Successful in 14s
CI / Fetch cadenced release (push) Successful in 21s
CI / Build splash images (push) Successful in 10s
CI / Build Tempo app for the Y2 (push) Successful in 1m16s
CI / Build kernel for the Y2 (push) Successful in 7m11s
CI / Build Recovery images (push) Successful in 8m2s
CI / Build Toolbox for macOS (push) Successful in 1m14s
CI / Build Toolbox for Linux (push) Successful in 7m47s
CI / Build rootfs for the Y2 (push) Successful in 15m41s
CI / Assemble firmware image (push) Successful in 11m19s
CI / Publish release from tag (push) Successful in 1m43s
Staple the macOS bundle only when this run built it
On a cache hit the notarised disk image is restored without the bundle
beside it, and the runner's pipefail shell turned the missing bundle into
a failed release job.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
2026-09-11 15:00:50 -04:00
.cargo Initial public Tempo source 2026-09-09 16:48:48 -04:00
.forgejo Staple the macOS bundle only when this run built it 2026-09-11 15:00:50 -04:00
.vscode Initial public Tempo source 2026-09-09 16:48:48 -04:00
app Set the player up on its first run, with a keyboard for the wheel 2026-09-11 11:24:59 -04:00
assets Initial public Tempo source 2026-09-09 16:48:48 -04:00
daemon Hash the setup's password in the broker, and add a clock op 2026-09-11 11:14:10 -04:00
docs Run CI in the shared toolbox image and build nothing twice for the same inputs 2026-09-11 13:37:23 -04:00
packages Keep the tool's own Dart root out of the SDK processes it starts 2026-09-11 14:02:04 -04:00
platform Run CI in the shared toolbox image and build nothing twice for the same inputs 2026-09-11 13:37:23 -04:00
toolbox Set the player up from the flasher: Device Setup in the Toolbox, written by Recovery 2026-09-11 12:52:53 -04:00
.env.device.example Initial public Tempo source 2026-09-09 16:48:48 -04:00
.env.example Initial public Tempo source 2026-09-09 16:48:48 -04:00
.fvmrc Initial public Tempo source 2026-09-09 16:48:48 -04:00
.gitattributes Initial public Tempo source 2026-09-09 16:48:48 -04:00
.gitignore Ship the image with its account locked, and drop the credential overlay 2026-09-11 10:55:29 -04:00
.gitmodules Initial public Tempo source 2026-09-09 16:48:48 -04:00
.markdownlint.json Initial public Tempo source 2026-09-09 16:48:48 -04:00
.mcp.json Initial public Tempo source 2026-09-09 16:48:48 -04:00
.prettierignore Initial public Tempo source 2026-09-09 16:48:48 -04:00
.prettierrc.json Initial public Tempo source 2026-09-09 16:48:48 -04:00
Cargo.lock Hash the setup's password in the broker, and add a clock op 2026-09-11 11:14:10 -04:00
Cargo.toml Initial public Tempo source 2026-09-09 16:48:48 -04:00
config.yaml Run CI in the shared toolbox image and build nothing twice for the same inputs 2026-09-11 13:37:23 -04:00
LICENSE Initial public Tempo source 2026-09-09 16:48:48 -04:00
pubspec.lock Bring the player to 0.9.0: Cadence, Recovery, and a pipeline 2026-09-11 08:24:29 -04:00
pubspec.yaml Bring the player to 0.9.0: Cadence, Recovery, and a pipeline 2026-09-11 08:24:29 -04:00
README.md Ship the image with its account locked, and drop the credential overlay 2026-09-11 10:55:29 -04:00
rustfmt.toml Initial public Tempo source 2026-09-09 16:48:48 -04:00

Tempo

A Linux based media player firmware for the Innioasis Y2.

Tempo turns a MediaTek music player into a small, open Linux device, with a player interface that feels like it belongs on a finished product rather than a hobby flash. It runs mainline Linux and a Debian userland, draws its UI with Flutter on the device's own GPU, and drives it all from the Y2's click wheel.

It installs onto stock hardware with no case opening and no soldering. Normal installation preserves the MediaTek boot chain so it can be used for recovery.

The media library is Cadence, a separate project whose daemon Tempo supervises on the device. The full documentation starts at docs/index.md, which routes readers by what they want to do: install Tempo on a Y2, build or change it, or port to the same hardware.

Features

  • Real Linux underneath. Mainline Linux with a Debian armhf userland, so you get apt, systemd, ssh, and the rest of a normal Linux system on a device that shipped locked to a 2014 Android kernel.
  • A fluid, GPU-drawn interface. The UI is a Flutter app rendered on the Y2's Mali GPU through the lima driver, not smeared onto the framebuffer by the CPU.
  • Click-wheel navigation that feels right. An iPod-style input grammar (jog the wheel to move, press to select, hold buttons as chords) with Cupertino-style overscroll, so scrolling long song lists feels natural instead of mechanical.
  • A boot that looks finished. An animated splash comes up under the vendor bootloader and holds, animating, all the way until the interface paints its first real frame. No black gaps, no flicker, no console spew.
  • Recovery tools. Toolbox provides explicit backup, restore and installation operations. Preloader writes are disabled by default and require a separate acknowledgement. Make and retain a complete backup before installation.
  • Made to be hacked on. A USB serial console and USB networking mean you can ssh straight into the device, and a desktop emulator runs the exact same interface so you can build and test the UI without the hardware in hand.
  • Shared device services. The on-device daemon owns battery and card monitoring, library scans, settings, radio control and Bluetooth playback commands, independently of the player interface.

The device

The Innioasis Y2 is a click-wheel media player built on a MediaTek MT6582: a quad-core Cortex-A7 with about 992 MB of RAM, a 480×360 DSI panel, a Mali-400 GPU, and a capacitive click wheel. Stock, it runs an old Android or a community Rockbox build. Tempo replaces that software wholesale while using every one of those pieces of hardware.

Project status

Tempo is undergoing release preparation. Hardware bring-up works on the Y2; Toolbox hardware parity and platform validation are still in progress. The reorganized runtime has passed sustained audio/video checks on the Y2. Release validation is ongoing; review the component documentation for current platform support.

Repository layout

Directory Owner and purpose
app/ Device Flutter app, pinned flutter-pi embedder, patches and engine pairing.
toolbox/app/ Toolbox Flutter UI and emulator, using mocked device services. Desktop uses a second native window in the same process; mobile uses a route.
toolbox/cli/ Native command-line presentation for shared Toolbox operations.
daemon/ Dart service host, media database, settings and radio operations; private Rust hardware core under native/.
packages/tempo_core/ Player UI and service interfaces shared by the app and emulator.
packages/player_api/, packages/daemon_client/ Player contracts and daemon transports.
packages/toolbox_core/, packages/tempo_usb/ Shared device-operation policy, transports and native/Wasm USB engine.
packages/tempo_build/ Repository configuration, SDK discovery and Dart build/development commands.
packages/tempo_kms/ Native display library.
platform/ Kernel, rootfs, production Bluetooth bootstrap, firmware, splash and cross toolchain.
build/ Generated app, Toolbox, OS and Rust products; final image sets under build/dist/.

This public source repository excludes historical reverse-engineering material. Toolbox imports legacy scatter ROMs directly; no external SP Flash Tool installation is needed.

The kernel lives in our Linux fork, on tempo/innioasis-y2, based on the tested Linux v6.12 revision. The platform/kernel/linux submodule pins its exact commit; builds no longer apply a patch stack. See kernel development.

The app and shared Dart packages use the root pub workspace. Toolbox keeps its own SDK resolution; do not change the device Flutter pin without checking its engine/AOT pairing. The daemon compiler has a separate explicit version in config.yaml. The root Cargo workspace contains the daemon native core and tempo_kms; the USB engine and archived demos have independent workspaces.

Development

Shared operations live behind toolbox dev; toolbox dev --help lists the areas, and toolbox dev os rootfs --help lists a component's commands. Component tool/*.dart entry points call the same APIs. There is no Just dependency. The image carries no credentials: the device's first run sets them.

Development command overrides are listed in .env.example; player and daemon service overrides are in .env.device.example.

The host tooling contract is Dart and Podman. Additional language runtimes and build tools belong in the container; Python, Node and other container tools are allowed. Git and standard Linux utilities provide checkout/authentication support. The complete firmware build currently runs on Linux x64. Bootstrap provisions the pinned Flutter SDKs and Git LFS client; FVM is not required. SDKs live in build/sdks/flutter/, and Toolbox independently uses toolbox/app/.fvmrc.

Linux Toolbox GUI/CLI builds, native Rust builds, and browser tests run inside Podman. Toolbox can copy a pinned Linux SDK cache or fetch its pinned SDK in the container. Bootstrap resolves package dependencies with the host's Git; the Cadence client and media packages come from the public Cadence repository, and the firmware build downloads the pinned cadenced release bundle.

Rootfs build, stage and shell use privileged rootful Linux Podman with sudo/root access. The container supplies debootstrap, QEMU and filesystem tools. TEMPO_ROOTFS_HOST=1 retains the original host path for compatibility. Rootfs operations and distribution packaging share an exclusive checkout lock. Device deployment keeps host SSH and its agent/network configuration. macOS, Windows and mobile native builds still require their platform SDKs; Linux container checks do not validate those platforms.

From a clean checkout, run the pure Dart CLI from its own package directory:

cd toolbox/cli
dart run bin/toolbox.dart dev bootstrap
cd ../..
build/toolbox/cli/toolbox dev build

The import is optional when local configuration is already present. Existing configuration is preserved. Set an SSH public key or your own password in the configuration; do not use the example password. Bootstrap checks rootful Podman mounting and ARM execution, initializes submodules, hydrates required firmware blobs, resolves dependencies and compiles the CLI. Rerun it after fixing a failed prerequisite; completed SDK downloads are reused. Add --build to bootstrap to run the full build immediately afterwards.

dev build builds the app, daemon, rootfs and kernel in dependency order and writes build/dist/tempo.y2-firmware for the installer, alongside SPFT images. It rebuilds the configured rootfs image and does not access the device. toolbox dev workspace analyze and toolbox dev workspace test run the development checks. Individual component commands remain available.

Bluetooth initialization uses the bundled stock modem firmware, generated protocol structures, and a temporary RAM filesystem. No device captures are required or included; see radio initialization. Rootfs staging requires a complete verified ARM daemon bundle, including its native libraries. toolbox dev os rootfs stage updates an existing image. Use toolbox dev device for running hardware and toolbox dev emulator run for the mocked emulator. See daemon setup, Toolbox, and recovery.

Installation

Use Toolbox's Backup & Restore workflow. Create and retain a complete backup, then choose Flash a firmware, select a .y2-firmware package, review the options and connect the player when prompted. Toolbox can start Tempo Recovery in RAM on a powered-off player. Keep readback verification enabled for a checked installation. Preloader writes are disabled by default.

See Toolbox for supported platforms and Tempo Recovery for the transfer environment.