Files
bananarchy/MANUAL.md
T

306 lines
21 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# Bananarchy Linux — user, flashing & customization manual
![Bananarchy Banner](artwork/banner-800x240.png)
This manual covers flashing, operating, and customizing **Bananarchy Linux** (`v0.0.1`, Sxmo `240x320` native edition) on **Qualcomm MSM8905 / MSM8909** Nokia feature phones:
- **Nokia 8110 4G (`nokia-argon`)**
- **Nokia 2720 Flip (`nokia-beatles`)**
- **Nokia 800 Tough (`nokia-tough` / `nokia-coconut`)**
- **Nokia 8000 4G (`nokia-sparkler`)** & **Nokia 6300 4G (`nokia-leo`)**
---
## 1. What is prepared in this workspace
### 1.1 System images (`images/`)
- `images/bananarchy-nokia-argon.img` (linked as `images/nokia-argon-sxmo.img`) — raw partitioned image (`256 MiB` `ext2` `pmOS_boot` + `ext4` `pmOS_root`) ready for EDL flashing to `userdata` or raw `dd` to a microSD card.
- `images/bananarchy-nokia-argon.sparse.img` (linked as `images/nokia-argon-sxmo.sparse.img`) — Android sparse image for `fastboot flash userdata`.
- `images/boot-bananarchy-nokia-argon.img` (linked as `images/boot-nokia-argon-sxmo.img`) — standalone Android `boot.img` with Linux `6.12.1-msm8916`, initramfs, and appended DTB.
- Additional device images (`bananarchy-nokia-beatles.img`, `bananarchy-nokia-tough.img`, `bananarchy-nokia-sparkler.img`) can be generated at any time via `./rebuild-image.sh <device> --mkinitfs`.
### 1.2 Bootloader & EDL programmer (`bootloader/`)
- `bootloader/lk2nd-msm8909.img` — secondary bootloader (`lk2nd`) providing Fastboot and `extlinux` boot discovery for MSM8905/MSM8909 devices.
- `bootloader/loaders/8110.mbn` — signed Qualcomm Sahara/Firehose programmer (`05c6:9008`).
### 1.3 Integrated hardware & UX tweaks
1. **Native 1:1 `240x320` resolution, cross-compiled Xlibre, `Fira Code` ligatures & ultra-low-latency Sxmo X11 UI**:
- **Cross-compiled Xlibre (`X11Libre/xserver` 25.2.0)**: compiled specifically for ARMv7 Cortex-A7 (`-O2 -march=armv7-a -mtune=cortex-a7 -mfpu=neon-vfpv4 -mfloat-abi=hard -fno-plt -fomit-frame-pointer`) with all 3D/GLX/Glamor/VGA/DGA/XVideo bloat stripped out, rootless `elogind` device management, and `modesetting` KMS + `ShadowFB` (`drmModeDirtyFB` partial rectangle SPI updates) with automatic software cursor fallback on `/dev/dri/card0` (`panel-mipi-dbi`).
- **Non-Nerd `Fira Code` with OpenType ligatures**: `Fira Code` (`font-fira-code`) is configured as the primary system and terminal font across Fontconfig, Xft, `st`, `dmenu`, `dwm`, `conky`, and `dunst`, with `DejaVu SansM Nerd Font` used strictly as a fallback for Private Use Area icon glyphs.
- **Patched `sxmo-st` (`st`) with HarfBuzz ligatures & XIM**: patched with `libharfbuzz` (`hb.c`/`hb.h`) shaping (`liga`, `calt`, `clig`, `dlig`) so multi-character programming operators (`->`, `=>`, `!=`, `<=`, `>=`, `===`, `::`, `//`, `/*`) render as continuous ligatures at `pixelsize=18`, alongside full `XIM` (`fcitx5-t9`) input support.
- **Patched `sxmo-dmenu` (`dmenu`) (`< 15 ms` startup)**: full-width `240x320` 9-line vertical menu (`lineheight = 26`, positioned flush at `Y = 24` right below the 24px `dwm` bar) with a `#383838` top search bar, `#005577` prompt badge, `#1c1c1c` item list, `XIM` (`XSetLocaleModifiers("")`, `XSetICFocus`, `Xutf8LookupString`) for live `fcitx5-t9` search filtering and `#` mode switching, C-level focus preservation (`prevfocuswin`), and direct Nokia keypad bindings.
- **Patched `sxmo-dwm` (`dwm`) (`< 2 ms` display wake/unlock)**: configured for `240x320` (`bh = 24`, `#323232` top bar, `#005577` active tag/border, vertical `bstack` layout default, overflow-protected Pango status bar rendering keeping the right-aligned clock always visible). Directly polls `/dev/input/by-path/platform-gpio-keys-event` (`SW_LID`) and intercepts locked-state wake keys (`XF86PowerOff`, `XF86PickupPhone`, `XF86KbdLcdMenu1`, `XF86KbdLcdMenu2`) in C to toggle `/sys/class/backlight/backlight/brightness` and `/sys/class/leds/white:kbd_backlight/brightness` in `< 2 ms` before running Sxmo state hooks asynchronously.
2. **Multi-mode `fcitx5-t9` keypad engine (`src/fcitx5-t9/`)**:
- Supports 6 input modes cycled with `#` (`XF86NumericPound`): `abc`, `Abc`, `ABC`, `Sym`, `Ctl`, and `123`, updating the live top-bar status indicator (`[abc]`, `[Abc]`, `[ABC]`, `[Sym]`, `[Ctl]`, `[123]`) in real time.
- Locks the candidate popup bar to the bottom of the screen (`X = 1, Y = 290, W = 238, H = 30`) with fixed-width 28-character monospace formatting (`Fira Code 9.5`), so neither the popup window nor individual letters ever jump when cycling through candidates.
- Includes instant case toggling during preedit, full 32-character ASCII punctuation/symbol entry, terminal control sequences (`^A`–`^Z`, `Esc`, `Tab`, `F1`–`F12`), and a `550ms` long-press `*` `Ctrl+` modifier latch.
3. **Bantam AI agent (`prebuilt/bantam/bantam`)**:
- Fetched from the latest `master` branch of `https://code.luxferre.top/luxferre/bantam-cpp`, cross-compiled for `armv7`, and installed to `/usr/bin/bantam` and `/usr/local/bin/bantam` (with no default `.bantam.cfg` pre-created).
4. **Mainline 6.12.1-msm8916 QDSP6 audio (loudspeaker, earpiece, MEMS & headset mics), voice call & LTE modem stack**:
- Patched `q6core`, `q6afe`, `q6afe-dai`, `q6voice-dai`, `q6mvm`, and device trees (`VoiceMMode1` DAI + PM8909 WCD codec).
- Automatic PM8909 WCD analog codec register initialization at boot (`CDC_A_MICB_1_VAL` `0xf141 = 0x60` for 2.8V internal MEMS microphone bias, and `CDC_A_RX_EAR_CTL` `0xf1c0 |= 0x20` for +6 dB earpiece PA gain).
- WirePlumber `50-s16le.lua` (`S16LE` sample format enforcement), ALSA UCM2 profiles (`qdsp6.conf`, `HiFi.conf`, and `VoiceCall.conf`), `q6voiced` (`card=0, device=2`), `sxmo_audio.sh` / `sxmo_modemaudio.sh` PipeWire UCM profile switching, `sxmo_ob.sh` (`WOB_DISABLE_PLEDGE=1`), `rmtfs`, `msm-modem-uim-selection`, `msm8909-modem-wwan-port`, and `ModemManager` (`mmcli`).
5. **Rear 2MP camera (`src/msm8905-cam/` & `bananarchy-photo`) & SY7807 torch LED (`src/leds-msm8905-torch/`)**:
- `msm8905-cam.ko`: powers PM8909 LDOs (`L2` 1.2V, `L6` 1.8V, `L17` 2.85V) and `CAMSS_MCLK0` (24 MHz on GPIO 26), configures the GalaxyCore `GC2395` MIPI CSI-2 sensor (`blsp_i2c3` `0x37`) and MSM8909 `CAMSS` (`CSIPHY0 -> CSID0 -> ISPIF -> VFE0 RDI0 -> VBIF -> CMA`), and exposes `/dev/video0` (`800x600` 24-bit `RGB3` V4L2 capture device).
- `bananarchy-photo`: CLI and Sxmo menu camera utility (`Camera` in the Sxmo System and Apps menus) supporting instant JPEG/PNG photo capture, optional flash (`-f`), and `imv` photo viewing (`-v`).
- `leds-msm8905-torch.ko`: exposes `/sys/class/leds/white:torch` (`GPIO 31`), configures WCD micbias/earpiece registers at boot, and hooks PM8909 `PON` clean shutdown.
6. **Memory & swap tuning for 512 MB RAM**:
- `384 MiB` ZSTD-compressed `zram0` swap (priority `100`) + `512 MiB` `/swapfile` (priority `10`), with `vm.swappiness=100` and `vm.page-cluster=0`.
7. **Preinstalled on-device development & scripting stack**:
- **C / C++ toolchain & CLI utilities**: `gcc`, `g++`, `musl-dev`, `make`, `git`, GNU `coreutils`, `nano` (default `$EDITOR`, configured system-wide via `/etc/nanorc` equivalent to `nano -FEDSMAGic/max%_T2`), `ed`, GNU `less` (default `$PAGER="less -RXF"`), `rlwrap`
- **Janet**: `janet`, `janet-dev`, `jpm` (Janet package manager)
- **Perl**: `perl`, `perl-io-socket-ssl` (`IO::Socket::SSL`)
- **Tcl & SQLite**: `tcl`, `tcl-lib` (`tcllib`), `tcl-tls`, `sqlite` (`sqlite3`), `sqlite-tcl` (`tcl-sqlite`)
- **Hardware & media utilities**: `bananarchy-photo`, `v4l-utils` (`v4l2-ctl`), `i2c-tools`, `ffmpeg`, `mpv`, `imv`
---
## 2. Flashing instructions
### Method A: Automated USB EDL flasher (recommended)
Run the automated EDL flasher from the repository root on your host machine:
```bash
sudo ./flash-edl.sh
```
*(To flash another target device image, pass its codename, e.g. `sudo ./flash-edl.sh nokia-sparkler`.)*
The script will:
1. Temporarily pause host `ModemManager` so it does not interfere with `05c6:9008`.
2. Wait for the phone to appear in Qualcomm EDL mode (`05c6:9008`):
- **Button combo**: power off the phone, hold **D-Pad up + D-Pad down**, and plug in the USB cable.
- **EDL cable**: hold the EDL cable button while plugging in USB.
- **From ADB / Fastboot**: the script automatically sends `adb reboot edl` or `fastboot oem edl` if detected.
3. Upload `bootloader/loaders/8110.mbn` via Sahara and connect to eMMC via Firehose.
4. Back up `gpt.bin`, `fsc`, `fsg`, `modemst1`, `modemst2`, `persist`, and `boot` into `./backup/` (if not already backed up).
5. Flash `lk2nd-msm8909.img` to `boot`, flash `images/bananarchy-<device>.img` to `userdata`, clear the stock `system` superblock, and reboot into Bananarchy Linux.
---
### Method B: Fastboot flashing (once `lk2nd` is installed)
1. Hold **D-Pad up** while powering on the phone to enter `lk2nd` Fastboot mode.
2. Flash the sparse system image to `userdata`:
```bash
fastboot flash userdata ./images/bananarchy-nokia-argon.sparse.img
fastboot erase system
fastboot reboot
```
---
### Method C: Booting from a microSD card
`lk2nd` automatically checks the microSD card for a `pmOS_boot` partition before internal eMMC:
```bash
sudo dd if=./images/bananarchy-nokia-argon.img of=/dev/sdX bs=4M status=progress conv=fsync
```
---
## 3. Keypad controls & multi-mode T9 input guide
### 3.1 Global Sxmo keypad controls (`240x320`)
| Physical key | Linux keysym / event | Action in Sxmo |
| :--- | :--- | :--- |
| **Left softkey** | `XF86KbdLcdMenu1` (`KEY_MENU`) | Open **System menu**, close open menu, or wake & unlock when locked |
| **Right softkey / Back** | `XF86KbdLcdMenu2` / `BackSpace` (`KEY_BACK`) | Open **App context menu** (or close menu if open); in apps/T9 preedit acts as `BackSpace` |
| **Call (green)** | `XF86PickupPhone` (`KEY_SEND`) | Wake & unlock when locked, confirm (`Return`) in menus, or: **1×** answer call / **App context menu**, **2×** **Focus next window**, **3×** **Toggle tiling layout** (`vertical` -> `horizontal` -> `tabbed`) |
| **End / Power (red)** | `XF86PowerOff` | Wake & unlock when locked, close open menu, or: **1×** **Power menu** (`space` shutter in Megapixels), **2×** cycle screen state, **3×** (or hold `400ms`) launch new terminal |
| **D-Pad up / down** | `Up` / `Down` | Navigate menus/apps; in T9 preedit: toggle letter case (`a` ↔ `A`) or jump `+4` / `-4` candidates; in idle `Ctl` mode: `Page_Up` / `Page_Down` |
| **D-Pad left / right** | `Left` / `Right` | Move cursor; in T9 preedit: step back 1 candidate (`Left`) / commit candidate (`Right`); in idle `Ctl` mode: `Home` / `End` |
| **Center OK** | `Return` (`KEY_OK`) | Confirm / Enter, or commit active T9 preedit candidate immediately |
| **Slider close / open** | `SW_LID` (`lid:on` / `lid:off`) | **Close**: close open menu, turn off keypad backlight, and lock/turn screen off; **Open**: restore keypad backlight, unlock, and turn screen on |
> **Waking & unlocking after screen fade**:
> When the screen turns off after inactivity (or when the slider is closed), you can wake and unlock the phone in a single action by either:
> - **Opening the slider** (`SW_LID` off), or
> - Pressing **End / Power (red)**, **Left softkey**, **Right softkey**, or **Call (green)** once.
#### 3.1.1 Window tiling modes & switching combos
By default, Sxmo `dwm` is configured with the **vertical bottom-stack (`bstack`, `TTT`)** layout as default, so opening multiple `st` terminals stacks them **vertically (one terminal under another)** to maximize line width on the `240x320` portrait screen.
You can switch between **vertical stack (`TTT`, `bstack`)**, **horizontal tile (`[]=`, `tile`)**, **deck (`[D]`, `deck`)**, and **fullscreen monocle (`[M]`, `monocle`)** layouts — as well as switch focus between open terminals — using any of the following combos:
1. **Direct physical keypad combos**:
- **Triple-press Call (green) (`3× Call`)**: cycles the current DWM layout (`TTT` -> `[]=` -> `[D]` -> `[M]` -> `TTT`).
- **Double-press Call (green) (`2× Call`)**: switches focus to the next open window/terminal (`Super+j`).
- **Triple-press End / Power (red) (`3× End`)**: opens a new `st` terminal (with HarfBuzz `Fira Code` ligature support) tiled in the active layout.
2. **External keyboard / `xdotool` (`MODKEY` = `Mod4` / `Super`)**:
- `Mod4+space`: cycle layout (`TTT` -> `[]=` -> `[D]` -> `[M]`)
- `Mod4+Shift+slash`: vertical stack layout (`bstack`, `TTT`)
- `Mod4+slash`: horizontal tile layout (`tile`, `[]=`)
- `Mod4+m`: fullscreen monocle layout (`monocle`, `[M]`)
- `Mod4+Up` / `Mod4+Down` (or `Mod4+k` / `Mod4+j`): move focus between tiled windows
- `Mod4+Shift+k` / `Mod4+Shift+j`: move focused window up/down in the stack
- `Mod4+1`..`4`: switch to workspace tag `1`..`4`
- `Mod4+Shift+q`: close focused window
### 3.2 Multi-mode `fcitx5-t9` keypad reference
- **Short-press `#`** *(when no character is in preedit)*: cycles through the 6 input modes (`abc` -> `Abc` -> `ABC` -> `Sym` -> `Ctl` -> `123` -> `abc`), displaying a `1500ms` preedit status banner (`[Mode: abc]`, `[Mode: Abc]`, `[Mode: ABC]`, `[Mode: Sym]`, `[Mode: Ctl]`, `[Mode: 123]`).
- **Auto-commit timeout**: `1500ms` for keys with `<= 10` candidates, or `1800ms` for keys with `> 10` candidates (`1` and `*` in `abc`/`Abc`/`ABC`, `*` in `Sym`, `9` in `Ctl`). Pressing a different key immediately commits the active candidate.
- **While a candidate is highlighted (`[item]`) in preedit**:
- Press **`#`** or **D-Pad `Up`**: toggles letter case (`a` <-> `A`) on the fly without changing mode, or jumps forward **`+4` candidates** for non-alphabetic items.
- Press **D-Pad `Down`**: toggles letter case (`a` <-> `A`) for alphabetic items, or jumps backward **`-4` candidates** for non-alphabetic items.
- Press **D-Pad `Left`**: steps backward **1 candidate** on the same key.
- Press **D-Pad `Right`** or **Center `OK` (`Return`)**: commits the highlighted candidate immediately.
- Press **`BackSpace`**: cancels the uncommitted preedit candidate without deleting previously committed text.
- **Long-press (`>= 550ms`)**:
- **Hold `0`–`9`**: commits the digit (`0`–`9`) immediately in any mode.
- **Hold `*`**:
- In `123` mode: commits a decimal point (`.`) immediately.
- In all other modes: toggles a one-shot **`Ctrl+` modifier latch** (`[Ctrl+ LATCH ON]` / `[Ctrl+ LATCH OFF]`; mode prefix shows `+^`, e.g. `abc+^`). The next committed key (`a`–`z`, `[`, `\`, `]`, `^`/`6`, `_`/`-`) is sent as `Ctrl+<key>`.
- **Hold `#`**: commits a literal `#` character immediately in any mode.
#### Modes 1–3: `abc` (lowercase), `Abc` (one-shot Shift), `ABC` (Caps Lock)
*(In `Abc` and `ABC` modes, uppercase letters precede the digit and lowercase letters on keys `2`–`9`. In `Abc` mode, committing an alphabetic character automatically reverts to `abc`.)*
| Key | Tap sequence (`abc` mode) |
| :--- | :--- |
| **`1`** | `.` `,` `-` `_` `!` `?` `/` `@` `:` `;` `'` `"` `+` `=` `*` `#` `$` `%` `^` `&` `(` `)` `[` `]` `{` `}` `<` `>` `\|` `\` `~` `` ` `` `1` |
| **`2`** | `a` `b` `c` `2` `A` `B` `C` |
| **`3`** | `d` `e` `f` `3` `D` `E` `F` |
| **`4`** | `g` `h` `i` `4` `G` `H` `I` |
| **`5`** | `j` `k` `l` `5` `J` `K` `L` |
| **`6`** | `m` `n` `o` `6` `M` `N` `O` |
| **`7`** | `p` `q` `r` `s` `7` `P` `Q` `R` `S` |
| **`8`** | `t` `u` `v` `8` `T` `U` `V` |
| **`9`** | `w` `x` `y` `z` `9` `W` `X` `Y` `Z` |
| **`0`** | `Space` (`SPC`) `0` `Ent` (`Return`) `Tab` |
| **`*`** | `*` `#` `+` `-` `=` `_` `/` `\` `\|` `~` `` ` `` `@` `$` `%` `^` `&` `(` `)` `[` `]` `{` `}` `<` `>` `'` `"` `.` `,` `!` `?` `:` `;` `Tab` `Esc` `^C` `^D` `^Z` *(hold 450ms for `Ctrl+` latch)* |
#### Mode 4: `Sym` (grouped ASCII punctuation, symbols & special keys)
| Key | Symbols / keys |
| :--- | :--- |
| **`1`** | `.` `,` `!` `?` `:` `;` `-` `_` `1` |
| **`2`** | `@` `#` `$` `%` `^` `&` `2` |
| **`3`** | `(` `)` `[` `]` `{` `}` `<` `>` `3` |
| **`4`** | `+` `-` `*` `/` `=` `_` `4` |
| **`5`** | `\|` `\` `~` `` ` `` `'` `"` `5` |
| **`6`** | `'` `"` `` ` `` `~` `^` `6` |
| **`7`** | `/` `\` `\|` `_` `-` `+` `7` |
| **`8`** | `<` `>` `!` `=` `?` `&` `8` |
| **`9`** | `$` `%` `^` `&` `*` `#` `@` `9` |
| **`0`** | `Space` (`SPC`) `0` `Tab` `Ent` (`Return`) `Esc` |
| **`*`** | `*` `#` `+` `-` `=` `_` `/` `\` `\|` `~` `` ` `` `@` `$` `%` `^` `&` `(` `)` `[` `]` `{` `}` `<` `>` `'` `"` `.` `,` `!` `?` `:` `;` |
#### Mode 5: `Ctl` (terminal control characters, navigation & function keys)
- **Direct D-Pad navigation** *(when no preedit candidate is active in `Ctl` mode)*:
- **D-Pad `Up` / `Down`**: sends `Page_Up` (`PgUp`) / `Page_Down` (`PgDn`) immediately.
- **D-Pad `Left` / `Right`**: sends `Home` / `End` immediately.
- **Keypad multi-tap**:
| Key | Control sequences / special keys |
| :--- | :--- |
| **`1`** | `Esc` `Tab` `Del` `Ins` `Bksp` |
| **`2`** | `^C` `^D` `^Z` `^X` `^\` |
| **`3`** | `^A` `^E` `^U` `^K` `^W` |
| **`4`** | `^R` `^L` `^P` `^N` `^G` |
| **`5`** | `^S` `^Q` `^O` `^T` `^Y` |
| **`6`** | `^B` `^F` `^V` `^H` `^[` `^]` `^^` `^_` |
| **`7`** | `PgUp` `PgDn` `Home` `End` |
| **`8`** | `Up` `Down` `Left` `Right` |
| **`9`** | `F1` `F2` `F3` `F4` `F5` `F6` `F7` `F8` `F9` `F10` `F11` `F12` |
| **`0`** | `Space` (`SPC`) `Tab` `Ent` (`Return`) `Esc` |
| **`*`** | `Esc` `Tab` `^C` `^D` `^Z` `^X` `^L` `^R` `^W` |
#### Mode 6: `123` (instant numeric entry)
| Key | Action |
| :--- | :--- |
| **`0`–`9`** | Commits digit `0`–`9` immediately on single tap |
| **`*`** | Commits `*` immediately on single tap; **hold `450ms`** to commit `.` (decimal point) |
| **`#`** | **Short-press**: cycle back to `abc` mode; **hold `450ms`**: commit `#` |
---
## 4. Default credentials, USB SSH & Bantam AI agent
- **Username**: `user`
- **Password**: `147147` (`doas` and `sudo` enabled, with passwordless `doas` configured for `wheel` in `/etc/doas.d/50-sxmo.conf`)
- **USB networking SSH**:
```bash
ssh user@172.16.42.1
```
- **Bantam AI agent**:
Run `bantam` in the terminal (`st`) or over SSH. Configure your endpoint/API key via environment variables or `~/.bantam.cfg` when needed.
---
## 5. Camera, audio, flashlight & cellular modem reference
### 5.1 Taking photos with the rear camera (`bananarchy-photo` & `/dev/video0`)
The `msm8905-cam` kernel module drives the rear 2MP GalaxyCore `GC2395` sensor through MSM8909 `CAMSS` (`CSIPHY0 -> CSID0 -> ISPIF -> VFE0 -> VBIF`) and registers `/dev/video0` (`800x600` 24-bit `RGB3`).
- **From the Sxmo keypad UI**:
Open the **System menu** (`Left softkey`) or **Apps menu** (`Left softkey` -> `Apps`) and select **Camera** (`bananarchy-photo --menu`). From the Camera menu you can:
- **Take photo**: capture a photo to `~/Pictures/photo-YYYYMMDD-HHMMSS.jpg` and immediately open it in `imv`.
- **Take photo (flash)**: turn on the rear flashlight (`white:torch`), capture a photo, restore the flashlight state, and open the photo in `imv`.
- **View photos**: browse all saved photos in `~/Pictures` using `imv` (press `Right softkey` inside `imv` to navigate, zoom, rotate, or quit).
- **From the CLI (`bananarchy-photo`)**:
```bash
# Capture to ~/Pictures/photo-YYYYMMDD-HHMMSS.jpg and print path
bananarchy-photo
# Capture with rear LED flash enabled and open in imv
bananarchy-photo -f -v
# Capture to a custom JPEG or PNG file path
bananarchy-photo ~/my-shot.png
```
- **Direct low-level capture (`v4l2-ctl` + `ffmpeg -f rawvideo`)**:
```bash
v4l2-ctl -d /dev/video0 \
--set-fmt-video=width=800,height=600,pixelformat=RGB3 \
--stream-mmap --stream-count=1 --stream-to=/tmp/frame.rgb && \
ffmpeg -hide_banner -loglevel error \
-f rawvideo -pixel_format rgb24 -video_size 800x600 \
-i /tmp/frame.rgb -frames:v 1 -y ~/photo.jpg && \
rm -f /tmp/frame.rgb
```
- **Why `v4l2-ctl` + `ffmpeg -f rawvideo` is used under the hood**: Alpine's `libavdevice` links against `libv4l2.so.0`, whose `v4l2_mmap` wrapper on 32-bit ARM (`musl` 64-bit `off_t`) misaligns variadic `syscall(SYS_mmap2, ...)` arguments. Capturing via `v4l2-ctl` and encoding via `ffmpeg -f rawvideo` bypasses `libv4l2` completely.
### 5.2 Switching speakers (loudspeaker vs. earpiece) & recording microphone audio
Both the rear loudspeaker (`Speaker` / `SPK_OUT`) and the front earpiece speaker (`Earpiece` / `EAR`, boosted by +6 dB in `CDC_A_RX_EAR_CTL`), as well as the internal MEMS microphone (`Mic1` / `AMIC3`, biased at 2.8V in `CDC_A_MICB_1_VAL`) and 3.5mm headset microphone (`Mic2` / `AMIC2`), are managed through PipeWire/WirePlumber and `sxmo_audio.sh`:
- **List available audio outputs (`Speaker`, `Earpiece`, `Headphones`)**:
```bash
sxmo_audio.sh out list
```
- **Switch active output to the rear loudspeaker**:
```bash
sxmo_audio.sh out set "Speaker"
```
- **Switch active output to the front earpiece speaker**:
```bash
sxmo_audio.sh out set "Earpiece"
```
- **Record from the internal MEMS microphone (`Mic1`)**:
```bash
pw-record --rate=48000 --channels=1 --format=s16 ~/recording.wav
```
### 5.3 Flashlight (`white:torch`) & keypad backlight (`white:kbd_backlight`)
- **Turn rear flashlight on / off**:
```bash
brightnessctl -d white:torch set 1
brightnessctl -d white:torch set 0
```
- **Set keypad backlight brightness (`0`–`255`)**:
```bash
brightnessctl -d white:kbd_backlight set 255
```
### 5.4 GSM / WCDMA / LTE modem & voice calls (`ModemManager` & `q6voiced`)
- **Inspect modem registration, operator, and signal quality**:
```bash
mmcli -m any
```
- **Place or manage voice calls and SMS**:
Use the Sxmo **Phone** / **Texts** menu (`Left softkey`) or `mmcli -m any --voice-list-calls` / `mmcli -m any --messaging-list-sms`. In-call audio is automatically routed between the modem (`VoiceMMode1`) and the PM8909 WCD codec by the `q6voiced` service and `sxmo_modemaudio.sh`.