From ad012360c3587d1242b6341531ca162c9b7155a5 Mon Sep 17 00:00:00 2001 From: Luxferre Date: Mon, 19 Oct 2026 23:51:09 +0300 Subject: [PATCH] feat(camera): add bananarchy-photo CLI, Sxmo menu integration, and multi-capture ISPIF/VFE0 reset --- MANUAL.md | 46 +++-- README.md | 2 +- overlay/rootfs/usr/bin/bananarchy-photo | 187 ++++++++++++++++++ .../applications/bananarchy-photo.desktop | 8 + .../sxmo/default_hooks/sxmo_hook_apps.sh | 1 + .../default_hooks/sxmo_hook_contextmenu.sh | 23 ++- .../camera/msm8905-cam.ko | Bin 17088 -> 17568 bytes .../camera/msm8905-cam.ko.zst | Bin 7732 -> 7958 bytes scripts/build-kernel-audio.sh | 62 ++++-- src/msm8905-cam/msm8905-cam.c | 45 ++++- 10 files changed, 322 insertions(+), 52 deletions(-) create mode 100755 overlay/rootfs/usr/bin/bananarchy-photo create mode 100644 overlay/rootfs/usr/share/applications/bananarchy-photo.desktop diff --git a/MANUAL.md b/MANUAL.md index 254022e..ce7e295 100644 --- a/MANUAL.md +++ b/MANUAL.md @@ -35,8 +35,9 @@ This manual covers flashing, operating, and customizing **Bananarchy Linux** (`v - 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/`) & SY7807 torch LED (`src/leds-msm8905-torch/`)**: +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`. @@ -45,7 +46,7 @@ This manual covers flashing, operating, and customizing **Bananarchy Linux** (`v - **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**: `v4l-utils` (`v4l2-ctl`), `i2c-tools`, `ffmpeg`, `mpv`, `imv` + - **Hardware & media utilities**: `bananarchy-photo`, `v4l-utils` (`v4l2-ctl`), `i2c-tools`, `ffmpeg`, `mpv`, `imv` --- @@ -235,22 +236,37 @@ You can switch between **vertical (`splitv`, one under another)**, **horizontal ## 5. Camera, audio, flashlight & cellular modem reference -### 5.1 Taking photos with the rear camera (`/dev/video0`) +### 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`). -To capture a photo to `~/photo.jpg` (or `.png`), stream a frame with `v4l2-ctl` and encode it with `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 -``` -- **Viewing photos on the phone**: run `imv ~/photo.jpg` or `mpv ~/photo.jpg`. -- **Why `v4l2-ctl` + `ffmpeg -f rawvideo` is used**: 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. +- **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 diff --git a/README.md b/README.md index d00183c..a174988 100644 --- a/README.md +++ b/README.md @@ -6,7 +6,7 @@ See [The Bananarchy Manifesto](./MANIFESTO.md) for the rationale behind this entire project. -Bananarchy targets the **Sxmo (`sxmo-de-sway`)** environment exclusively, tuned for 1:1 native `240x320` resolution, enlarged high-contrast typography, sub-115 MB idle RAM footprint on 512 MB devices, full Qualcomm QDSP6/Q6Voice audio (loudspeaker, earpiece speaker, and internal/headset microphones with PM8909 WCD analog codec 2.8V micbias and +6 dB EAR PA gain), GSM/WCDMA/LTE modem routing (`ModemManager` + `q6voiced`), rear 2MP camera support (`msm8905-cam` V4L2 driver for GalaxyCore `GC2395` + MSM8909 `CAMSS` on `/dev/video0`), pre-integrated **Bantam** AI agent (`https://code.luxferre.top/luxferre/bantam-cpp`), a complete on-device development & scripting stack (`git`, `gcc`/`g++`, `make`, `nano`, `janet` + `jpm`, `perl` + `IO::Socket::SSL`, `tcl` + `tcllib`/`tcl-tls`/`sqlite-tcl`, `sqlite`, `i2c-tools`, `v4l-utils`), and a custom **6-mode `fcitx5-t9` input engine** supporting lowercase, one-shot Shift, Caps Lock, all 32 ASCII punctuation symbols, terminal control codes (`^A`-`^Z`, `Esc`, `Tab`, `F1`-`F12`), and direct numeric entry. +Bananarchy targets the **Sxmo (`sxmo-de-sway`)** environment exclusively, tuned for 1:1 native `240x320` resolution, enlarged high-contrast typography, sub-115 MB idle RAM footprint on 512 MB devices, full Qualcomm QDSP6/Q6Voice audio (loudspeaker, earpiece speaker, and internal/headset microphones with PM8909 WCD analog codec 2.8V micbias and +6 dB EAR PA gain), GSM/WCDMA/LTE modem routing (`ModemManager` + `q6voiced`), rear 2MP camera support (`msm8905-cam` V4L2 driver for GalaxyCore `GC2395` + MSM8909 `CAMSS` on `/dev/video0` and `bananarchy-photo` CLI/Sxmo app), pre-integrated **Bantam** AI agent (`https://code.luxferre.top/luxferre/bantam-cpp`), a complete on-device development & scripting stack (`git`, `gcc`/`g++`, `make`, `nano`, `janet` + `jpm`, `perl` + `IO::Socket::SSL`, `tcl` + `tcllib`/`tcl-tls`/`sqlite-tcl`, `sqlite`, `i2c-tools`, `v4l-utils`), and a custom **6-mode `fcitx5-t9` input engine** supporting lowercase, one-shot Shift, Caps Lock, all 32 ASCII punctuation symbols, terminal control codes (`^A`-`^Z`, `Esc`, `Tab`, `F1`-`F12`), and direct numeric entry. The current Bananarchy version is `v0.0.1`. diff --git a/overlay/rootfs/usr/bin/bananarchy-photo b/overlay/rootfs/usr/bin/bananarchy-photo new file mode 100755 index 0000000..898581f --- /dev/null +++ b/overlay/rootfs/usr/bin/bananarchy-photo @@ -0,0 +1,187 @@ +#!/bin/sh +# Bananarchy rear camera photo capture utility and Sxmo menu wrapper +# Captures 800x600 24-bit RGB frames from /dev/video0 (msm8905-cam / GC2395) +# via v4l2-ctl and encodes JPEG/PNG images via ffmpeg -f rawvideo. + +set -eu + +DEV="/dev/video0" +USE_FLASH=0 +VIEW_AFTER=0 +MENU_MODE=0 +OUT_FILE="" + +usage() { + cat <<'EOF' +Usage: bananarchy-photo [options] [output_file] + +Options: + -d, --device V4L2 video device (default: /dev/video0) + -f, --flash Enable rear flashlight (white:torch) during capture + -v, --view Open captured photo in imv after saving + -m, --menu Open interactive Sxmo camera menu + -h, --help Show this help message + +If output_file is omitted, saves to ~/Pictures/photo-YYYYMMDD-HHMMSS.jpg. +EOF +} + +while [ $# -gt 0 ]; do + case "$1" in + -d|--device) + DEV="$2" + shift 2 + ;; + -f|--flash) + USE_FLASH=1 + shift + ;; + -v|--view) + VIEW_AFTER=1 + shift + ;; + -m|--menu) + MENU_MODE=1 + shift + ;; + -h|--help) + usage + exit 0 + ;; + --) + shift + break + ;; + -*) + echo "bananarchy-photo: unknown option: $1" >&2 + usage >&2 + exit 1 + ;; + *) + OUT_FILE="$1" + shift + ;; + esac +done + +if [ $# -gt 0 ] && [ -z "$OUT_FILE" ]; then + OUT_FILE="$1" +fi + +get_pictures_dir() { + pic_dir="${XDG_PICTURES_DIR:-$HOME/Pictures}" + mkdir -p "$pic_dir" + printf "%s\n" "$pic_dir" +} + +notify_msg() { + if command -v sxmo_notify_user.sh >/dev/null 2>&1 && [ -n "${WAYLAND_DISPLAY:-}" ]; then + sxmo_notify_user.sh -t 2000 "$1" >/dev/null 2>&1 || true + fi +} + +take_photo() { + flash_flag="$1" + target_path="$2" + + if [ -z "$target_path" ]; then + pic_dir="$(get_pictures_dir)" + target_path="$pic_dir/photo-$(date +%Y%m%d-%H%M%S).jpg" + else + mkdir -p "$(dirname "$target_path")" + fi + + if [ ! -e "$DEV" ]; then + echo "bananarchy-photo: camera device $DEV not found" >&2 + notify_msg "Camera $DEV not found" + return 1 + fi + + prev_torch="" + if [ "$flash_flag" -eq 1 ] && [ -w /sys/class/leds/white:torch/brightness ]; then + prev_torch="$(cat /sys/class/leds/white:torch/brightness 2>/dev/null || echo 0)" + echo 1 > /sys/class/leds/white:torch/brightness 2>/dev/null || true + sleep 0.15 + fi + + frame_tmp="/tmp/bananarchy-frame-$$.rgb" + rc=0 + + v4l2-ctl -d "$DEV" \ + --set-fmt-video=width=800,height=600,pixelformat=RGB3 \ + --stream-mmap --stream-count=1 --stream-to="$frame_tmp" >/dev/null 2>&1 || rc=$? + + if [ "$flash_flag" -eq 1 ] && [ -n "$prev_torch" ] && [ -w /sys/class/leds/white:torch/brightness ]; then + echo "$prev_torch" > /sys/class/leds/white:torch/brightness 2>/dev/null || true + fi + + if [ "$rc" -ne 0 ] || [ ! -s "$frame_tmp" ]; then + rm -f "$frame_tmp" + echo "bananarchy-photo: failed to capture frame from $DEV" >&2 + notify_msg "Photo capture failed" + return 1 + fi + + if ! ffmpeg -hide_banner -loglevel error \ + -f rawvideo -pixel_format rgb24 -video_size 800x600 \ + -i "$frame_tmp" -frames:v 1 -y "$target_path"; then + rm -f "$frame_tmp" + echo "bananarchy-photo: ffmpeg failed to encode $target_path" >&2 + notify_msg "Photo encoding failed" + return 1 + fi + + rm -f "$frame_tmp" + printf "%s\n" "$target_path" + notify_msg "Saved $(basename "$target_path")" + + if [ "$VIEW_AFTER" -eq 1 ] && [ -n "${WAYLAND_DISPLAY:-}" ] && command -v imv >/dev/null 2>&1; then + imv "$target_path" >/dev/null 2>&1 & + fi + return 0 +} + +run_menu() { + if [ -f /usr/share/sxmo/default_hooks/sxmo_hook_icons.sh ]; then + # shellcheck disable=SC1091 + . /usr/share/sxmo/default_hooks/sxmo_hook_icons.sh + fi + ic_cam="${icon_cam:-*}" + ic_fll="${icon_fll:-*}" + ic_img="${icon_img:-*}" + ic_cls="${icon_cls:-x}" + + choice="$(printf "%s\n" \ + "$ic_cam Take photo" \ + "$ic_fll Take photo (flash)" \ + "$ic_img View photos" \ + "$ic_cls Close" | sxmo_dmenu.sh -p "Camera" || true)" + + case "$choice" in + *"Take photo (flash)"*) + VIEW_AFTER=1 + take_photo 1 "" + ;; + *"Take photo"*) + VIEW_AFTER=1 + take_photo 0 "" + ;; + *"View photos"*) + pic_dir="$(get_pictures_dir)" + if ls "$pic_dir"/*.jpg "$pic_dir"/*.png >/dev/null 2>&1; then + imv "$pic_dir" >/dev/null 2>&1 & + else + notify_msg "No photos in $pic_dir" + fi + ;; + *) + exit 0 + ;; + esac +} + +if [ "$MENU_MODE" -eq 1 ]; then + run_menu +else + take_photo "$USE_FLASH" "$OUT_FILE" +fi diff --git a/overlay/rootfs/usr/share/applications/bananarchy-photo.desktop b/overlay/rootfs/usr/share/applications/bananarchy-photo.desktop new file mode 100644 index 0000000..b43765e --- /dev/null +++ b/overlay/rootfs/usr/share/applications/bananarchy-photo.desktop @@ -0,0 +1,8 @@ +[Desktop Entry] +Name=Camera +Comment=Bananarchy rear camera photo capture +Exec=bananarchy-photo --menu +Icon=camera-photo +Terminal=false +Type=Application +Categories=Graphics;Photography; diff --git a/overlay/rootfs/usr/share/sxmo/default_hooks/sxmo_hook_apps.sh b/overlay/rootfs/usr/share/sxmo/default_hooks/sxmo_hook_apps.sh index 5e1e257..2ff9555 100755 --- a/overlay/rootfs/usr/share/sxmo/default_hooks/sxmo_hook_apps.sh +++ b/overlay/rootfs/usr/share/sxmo/default_hooks/sxmo_hook_apps.sh @@ -38,6 +38,7 @@ write_line_app badwolf "$icon_glb Badwolf" "badwolf" write_line_app baobab "$icon_pie Baobab" "baobab" write_line_app bluetuith "$icon_bth Bluetuith" "sxmo_terminal.sh bluetuith" write_line_app calcurse "$icon_clk Calcurse" "sxmo_terminal.sh calcurse" +write_line_app bananarchy-photo "$icon_cam Camera" "bananarchy-photo --menu" write_line_app celluloid "$icon_mvi Celluloid" "celluloid" write_line_app chatty "$icon_msg Chatty" "chatty" ([ -z "$WAYLAND_DISPLAY" ] && command -v clipmenu >/dev/null) && \ diff --git a/overlay/rootfs/usr/share/sxmo/default_hooks/sxmo_hook_contextmenu.sh b/overlay/rootfs/usr/share/sxmo/default_hooks/sxmo_hook_contextmenu.sh index 1d3bfa8..cc2a635 100755 --- a/overlay/rootfs/usr/share/sxmo/default_hooks/sxmo_hook_contextmenu.sh +++ b/overlay/rootfs/usr/share/sxmo/default_hooks/sxmo_hook_contextmenu.sh @@ -180,13 +180,14 @@ case "$WMCLASS" in *imv*) # imv CHOICES=" - $icon_arr Next ^ 1 ^ sxmo_type -k Right - $icon_arl Previous ^ 1 ^ sxmo_type -k Left - $icon_zmi Zoom in ^ 1 ^ sxmo_type -k i - $icon_zmo Zoom out ^ 1 ^ sxmo_type -k minus - $icon_exp Zoom to fit ^ 1 ^ sxmo_type -k r - $icon_ror Rotate ^ 1 ^ sxmo_type -M ctrl r - $icon_inf Toggle filename ^ 1 ^ sxmo_type -k d + $icon_arr Next ^ 1 ^ sxmo_type.sh -k Right + $icon_arl Previous ^ 1 ^ sxmo_type.sh -k Left + $icon_zmi Zoom in ^ 1 ^ sxmo_type.sh -k i + $icon_zmo Zoom out ^ 1 ^ sxmo_type.sh -k minus + $icon_exp Zoom to fit ^ 1 ^ sxmo_type.sh -k r + $icon_ror Rotate ^ 1 ^ sxmo_type.sh -M ctrl r + $icon_inf Toggle filename ^ 1 ^ sxmo_type.sh -k d + $icon_cls Quit ^ 0 ^ sxmo_type.sh -k q " WINNAME=Imv ;; @@ -818,7 +819,13 @@ case "$WMCLASS" in rfkill list bluetooth -no ID,SOFT,HARD | grep -vq " blocked" && printf %b "$icon_bth Bluetooth ^ 1 ^ sxmo_bluetoothmenu.sh" ) - $(command -v megapixels >/dev/null && echo "$icon_cam Camera ^ 0 ^ GDK_SCALE=2 megapixels") + $( + if command -v bananarchy-photo >/dev/null; then + echo "$icon_cam Camera ^ 0 ^ bananarchy-photo --menu" + elif command -v megapixels >/dev/null; then + echo "$icon_cam Camera ^ 0 ^ GDK_SCALE=2 megapixels" + fi + ) $( if brightness="$(brightnessctl -l -m | grep -e "white:torch" -e "white:flash" | cut -d ',' -f 3)" && [ -n "$brightness" ]; then printf "%s Flashlight " "$icon_fll" diff --git a/prebuilt/kernel-6.12.1-msm8916/camera/msm8905-cam.ko b/prebuilt/kernel-6.12.1-msm8916/camera/msm8905-cam.ko index ecc2879f2583e3083e8b6ce31fdf21e965ab7125..64afdf5f99ef8a9f339a77832c04766e55aeb2d2 100644 GIT binary patch delta 4106 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 M2}@R&OBpx+2MW4WzyJUM diff --git a/prebuilt/kernel-6.12.1-msm8916/camera/msm8905-cam.ko.zst b/prebuilt/kernel-6.12.1-msm8916/camera/msm8905-cam.ko.zst index 677b22bd07064293c96b4c987043d712e3efd301..9d4df1c7e65e6774f5403c19619da405b2de198f 100644 GIT binary patch literal 7958 zcmV+xAL-yIwJ-f-phHFY0P4M+TwNf}LF0@8_rN*Slr&>88Nyk`&MZI9TuU+s+L@k* zlk!=W&#hFQH&FYhGRoai_cp7dJlglRzch}0^)4=;XNR#$5__%|eS{%+zx;j&bM*uvuXlHzqP zzFYXa!n4Ywh(^L?Oau#H8Y~uOPPYK%B=G5?REWEi9HU%fq8{(cD6_$Yo(c z=xoMpVQq`BmIIfC1+f{BzR0dI8!9HlBomEWthEFdXXVqnD{u_$;y6b4I7|xxr>nmd+>6 zaim8W_{WVOE67$jU3TY(k@MW_DZ^!R{LqIHQv!=14i@?_R<8H;L6h??yA#8PiWRkv zb8wMT-1@w+{Uk=}FLk=g=(Kj7S9n6db{zr`$_F)2{Sd~W4})ey#aMLItPY^v1f6k( zJ1A_ZoD@&!{DKCZ&vCP7kT&AP+sPT^vN%|5s92HCBG91kf(V_@F@*}^nL@>o&SwpZ zMA9oWg*Kn0&SXZ~ zFdGV5>a<3q(|nzSSm!iGXQ%7u>sD?D2P$SX^;Y4~n|iBeZT@QNt#Z=lui9*uQ*YH1 zlQ;EN1!;4N+dR82-bU(utC)yV#3BI|GcFU+N}E>zD>CVDq6v_rr_IMsMJbwPf)6=< z6zvg9yEpVjrXR9+yTKOOAGXK@#1?fztUgZJD$})cn-@R<+sGslNFv zMFdw}yiJxOg6kflGTQu=&geMxzEwIk?+#z;e4hH|+nkQBUq-j^?f~nATx0!vlP}qj&~FEWd3Q2x6wzx&S=dRqNdJf3Y}5x`d1oA ziYL1XI^+6T8i)u$y9vs2{V2@V=Y64zw`qOe7h8y$TWHQ~A(5psk0(060MeO=T|Z3A z!bwdO>#>`dr7mwAxqcKua|_LyEhN6S5S`Ka-@;+`-?2~ikL@irt;tOr@%IMTC!H~F&^kpma^Ja)_D zCTZ!iJ2*N$&E^3ubxUSv3u||UJ2+DBn`H~vZy{Q`-dD;M?%=pIC~k9(AUS>*H-?O( zN>`ZUh0ammPdRMuPduRI7S=BHo2k>cQ;w0&HB#S4>YQWR9K>x-ukW-17aW~eQa=W{ z*|T)n9B+MInk+>OQL*b^Y<9iAkKAmqblDs@ItRa>#Ee>>H`eB__7hs_G`&t|H2Udv z3x=J|o_E zZgPU`Ha*oTdY#Q{!SPx3(a&tC{rf2=$bO0m(YZxyH`TtMew}M~;V~b0=?-hKfjjKY zpvXwJpU7ERL;9hvKYJ52QYxwUb%ILqI{kGvyXbt%=v>75ztsDpK(CO)t20xT)cdMH z>V2u`Vlaf(FLMRGPKnniUg~|5Xmk2DpJff^S+@ByKB$4Jr-kHUY8EYvOUzNH0G-i7 zQ-i4mhsU}fKvTQnuhAi=EFJRM(jf=Q7KV?S06kJV!(yPk?-K0^PNhQ*mOA9K)gqnL z+5A6aM?p(>7W~v(HDouT<$eH7?R}-%94uLFKFbEQbbUa-q0n;MfWGJi9ieP!q#w$k zvm~Eo3&Tkl7gT}}{5N!v|A&8t5IJQDk%OfB0`o19mu_pm2m~EnJ_L{57ZBebozy96 zLvyUNjxKEz6mKZA+)(FTe~>n3(w(7a057(kRw+3h+w6qfJR@06(C|Se^}bd1@RYHK z=-FnUBZ{|J+GZXmC=!31+9@!&=%EkUQB1RC!D&U8A;h5RtTv;#&F2)7%O0LZdx)kw zJ#E@7#O@~~k|O(K?xATGSxoLBdYxfibT)B2Sn+GOt{WUF+-(^uOby8>a?gD&l(E43GA%WYeCdKuSpu_dYctXpm z_pNF=U)u=@xy|XQ1&7CaHbEm@rQWxTE`GNnOA$FxF^M5@SrqRbVn}rUUGGbSwuQsE zHXPuI%hZA=c9dD^dSBNK9%d7rR-1^HJ9u6ri2&4Q)CVj#fT<|5Xv-a@BbFu16_zXL z3d;<1Xt20IhKe?u6ev2t#8|GNB$g#i5=#nB6)rm?u`FR?ELWni%bHl{^H{DpjaZh* zqsyLSk^Ldtj8sBB+HR1;7~^qAKmw($@QK(KJuD6BPColePYp>p~4n{VSboPo`ck zLTCuGDCBN%ntHu7IUOB&K%33g)awO`mngJ0zbwMWEnHF4*&MgnbtdL5B-V5$#Vts3j-i_4lYw1qR7%j#gAXWvgT+0^TW ziW5{$Oub%uFa!jwT z-&JBXtUwinFPoU7WIJ7o>o3oLMEb`|y|0umenoIY{rcvm-l``{_6mmBP_ZJZx5~Gn zVntbsU;vfdRK+~OjRqqGTz03mg{e@G%ffot!W3m; zJ?Lzv8!9GSUu031&T9~TF?g27Ji6#skoDSZ?M4^VZ}!xo^C=S)!n&Aq!e(pbhKkK} zuHnsun)*K^3nyI`EoCq&E|Y1x!6bTU3`50c%Gp6@9qf8vFD;OduJA0k(7emU;|DI2 zj}F{m5<_|bE(>fZQl?uj3zYgf?`CT^n_YD_yUNHUjGIkgE-Qq$&^&Xt&@_3r&}5k@ zw$LnfYL+fr!l?5LXfs(~WP_|NTx%{{!g$WOERIpf_`F-VzQ~>|U0knOLEH|e-%RPZ zF#TSVe&djS<50UB>dxjPvf6GmT{XS>mGGH#Rc2Jm9&QRBs`CJ0W* z00|>H096AIhNB@J7bWRs>IxMhe1O8VsxPEKoOdx`jU-3T! z@tB(*p)^UraS!1te$s^jj643DC=m7i*kB&VmG+E6tZ5yDX(2yMR^m;~`>*Kjz^#tCHoyIebNPAbxzqX^w3;&4WJikDQ?H`f&AA{^4mHa;e=^u6Q z$Nw_^vHTx%6*$Jp-*s|zlKjaSVm!F-6ujn#h{__-lA z)%L$VTfRC*|Ms*zzu)|V2Tn>n*}F1 zFv!5pTlnGQKl#7rfBAprXEFP0w)`d%zd8I_Q9o<_S+73^i64gPhbjNn(_e1+OD2D5 z^pjLSDdi`hep1L!rauY$M=Jjq{73X3SwEin@ARMb|EJIqp!K|QM1`ZF6KCt`cuO=~ zZ+8OMovQlQbEX22)5Z^tpB|u}9veGuIU=^5Pd&0j-Pw3QqT+V^a6ENYamVq~BZVF| zihyj~5F)ZMRHH`?6jG?sLkQi$>*anv^~lZlyH7om^A(*yvLF{upR)#vLr4W6DxAAr z@20aYv9N>J%K_J%@Agx12j0{oJ>Tq1qIC1wcs8D`#|~dl3AkjtZ02K!`s1m$obFXH zJggm<5@2S~kTA-i$yvo4SU_uReumXV@%)9`F7Cf;a!3l3jcPmEo3xL_cVTSgvK zeTCk9b>6%zzFtxVc}X>UNoDksO21(dcDS$ID{+RdDuI(CDjR(N{sC zuU>wYYrd+LK^hH21;-3TDfRS{csUx*ruvkCK1h~$Ih~J+ThiTlIV3?S2}sa0htdsb z+x>F8vq%8vnp3*{f2#x}I-L+o0upqGZHGHyK|nox9Gxg?0||->>6|zcdMYk=#OH{L z^Eq*c|9UN z8_bq7(&OQP?RqyE{^!{FdPzW=ZoQA76aD!SI&C>4y&p7eK6Pg!I(;_v=&XSw21Mi| zh&2%PvnUG2{1ElmWC@NNi2BVDm`H-82BLme1%gsoO01folo%q+kjsimaKu2=UuIDf z9Ebl)9YHBsft6A)<3$l*^76FukGOxGkch)>>C^((Y49!+QHD;7 zZ!_B3Ln5(w{or-Zcn?_}ed1GGAk{bT`gz>h%#>k*hZ~*BXtPs!!_7S;k<3-=AE7*` z^~dNKF4N}R`a^JMPCviWKi~QZK$B-D^9<9p@aq{6S?g!vDQ49Ak%r`KKgEh-c6%6; z>FmNVF7_~Hr1Q;K;ysKN>3kE@W^@IkbBodSzFgWDzH0pn*cN!HXFrRDJFLM5ZJxoj zeyBYpgS7dCIj{4M7!yxOA-PuCKH&kNWbl^Y6I{xztPz6*J{~RUMSqfJk@OT5pBn*Zj1RPs* zIA2lZzyM!Jn+y&new18}{@U{YL@%n7Nvj)If^L|YB5x=m;ijmFmot8H_6NZ(^WVjd z`9BC|g#T3F(vX}F2($rt>TcJ&_1wtK2K>=z;fIgkZ%EI9y7fqwcsUs^M+2wJEe%nD zJzmdmJsqu=#LMA&yPgO2{P=*sp0DRfa5vpR3H)+*rQW@NIF5M47~>I-c*G;d7~>IR zJYtMu{IQk4HS&x$lGI)NnhBQgmpL_iy zmtTe+uz#HL&w%|S5q}S!fAqjFL)1Tm=N~JOcX0ZLy#8@G0!Q6g`+*4gW0?IzK|hhs z|Ks(KuRjO&k2ik~&p*y6K?LF#^7`=(zwGs6B!2;3xYv(`e%?!c{pWHfZsoVV{wwhx zV9FnZ_{WI)ks|QJfWhEFdi_`OpRkkXztV5S2lMeDjR5=q`bXd?@-hnY`p@J~dJzd? zlnVVQy#AyA?)6{iH^2)AhQlL(*MGzMe_;Qi`jxIw`D3uZ1rdLY=WpSG|MvP@MBrC? z{ViBO?e()*S=9a_FBV=ui}bI(eik#o?)BSzv6-pa@`XkR2o+8y5+;*51pejd!s|D2 zKMeMpLVg&}Zz4%a!NiIPLPA)Hn0d-ll#)>dp@3Pbq6FAFTQ@ROWJd6$`v+k3_k{lR zMuzqGUOy|#U*uKfRpeC!CI>KA{vxjx=Z68p%)peZ2&|sIY;pRFypCRfIV+9O-v(xL zzWy56U)KCJJT1IvU_bfgr{Vd@Eq{?$3ojM0pG4wU!Sj^#bgF(EkF@f7oB-^?MTFx>ITDEl0chvkjsBfVm+w6==h)OEe-hb(aGgQI&4C zn-LoAHy#bhTk73*v?U%98jZJfL{)uBI^9wd&B)KTqXBuUPgUyOXh8MX1JaVLy&F*d z?bO|aY~0lKr|xn5-GMn?j)p`9F70Tv)wWZ8z1)93Akb#p;Z6gp zL}*7;+|{2=)u}$-(r@k2lGt=Aj<)mJ?(?a%BPx#eB5m2N=WPUYp4 zZnhmQsdwPgdK=J&JEG!rIa?CVh|-N_XHmGB3aLYh-5wgA(Hi=M6#aibiH-wv#m5D zKj6~J%h8DFY)5=5keBGy7ZMcz~5_r z8p-;w$+{T!;nsw1UtP0lens2K!YkimFZ?n91b@!eq z#H_~b`~v6{TulY7vrKIG6~Z}ptS|Glp+p#I*K2v)Fq*QqHpEXcqEBOUP1NT@%vy*} z;!rDT1PQW{q1FjC@t?zE7K=P)i=!>3?F*VAM1QO>p;g-#Ka+SUO*Iv*?(wz@oohmB zaVq4j;$l`uFD$E6VZss7VA70F+s&$rmW%qtz_bwuj*=YVNT(pJM8Z6J3!G&orqjM> zm{`82k8NCo%cj9nB7+jO4EKCJAscAMUC!^>KE#ECVwi3cjd<&W*EERYCltP#m`%xc zY9Qh8|CP4BRfzqp6f-g4nb3ILvu93?xU0bpMQ%W|w^Opo>I(daW)&ZW zE#w-R7O?iK0hw<(4byq>+aX=j?@*Z}c=D#Ru|LcyG{0lpFqix71AHK|h1L}r=6xO@ zh5aJuA$mIQTNxelWzplm^`iVI(T5&{4Uva6)dq1`p;CYV53t$Hi@R@_vT5LT)n?Q1 zP9#xqnmB0+BxAsX#m>Ox}eLH4V>6T?RuC z7$>X_V}0QU;--g|j9YVe)Wu*+cfTV2(;up)DQ)Lr&@am21Hr`4GU5b)YE^;9FUYLu z&e;HEo;zDp>2*(s7Dn!$x41Q3{rsRLc=LBzPB!Zihb zgQ_uO^y6}G(=u;;^|>=u5KxsY@)t=GV-2Gnf_;1I2VzyA@1n9vOO51mOCW+ z;F+aD=dXb6cOnk03;mSA@S?g?r>AM7Q)BXsWdxsQ(yv9#Cz>b6 z4;23niU4rr{73X0WsT>tA2_bc6BXZ^w$^xk34sP`CVWorxj1x2vf4>c2q%|N_;ezV zla9sgOs7`tb1@8|U&dHrR)G?%*yBz&xGLMoP^b3+a4DJJr;bZMm^Ce(HXeJA>PgNv-g z`*-u4FLC!q9r}~r8c>`AzeDPQqV=jL>9Dx8*>;EiU}y!5bWiBf@t=7k#u&8z5YG{5 za`gvpK|if)%jo+!ZJM?*G~F{eUb9~)*MIOHgxaxC!Mb1hii#mj#}%QU?w^P*+I!#r z5aCw~6Mx7FOJl+xM)(6Jqe6J|s^6lC_yIQEo(7xreSnvEL1r!`L9P5FJ3CK(LHql4 zCCA6D*H1tEfPXRN@>M23PNy3J+D}LK&tI9U1oxJS|2cU7q@go`)AzV>j*R+kANT`j zcfa@9jk9%2eE32qa&I(YxI%}I@tnVw z2VJB&C5J(kV_Pt;#lTP^R8Ufba78UP*ygZ)49A zN~)FAIWw+w*e4~}0*DL8(_V`@J*+0y-fhZgQ~m7r=0V$YMk%MiUqS5P zfq0J{9Il2lJIIpms-vSbTkc><t{j~0;{MbFeGe=e4N2+_FCW#sl}L6)H{`H^HsUDLDV~? zN{uWWNEoucqBc8NV>`u)M3}P8CaFaltV?Iphz$iLbwwT@5V%}YISlCW6BGz#Y?h%UHo;S9sz(D<^M%5UN(ysH6EA(mC9{ilF zfI&(~kOln^TH7hMo}ylbe)g18#tr6>u$^pLT%j|K7j!noy_!JU1SZ}$m_Y8T1IBiW z5$XKF3;HsK(AgAQxEPu(T=>x0q&ba8T2%sRvpMQ~0?}_ND7mGet2UdXCTW1^d;)bw z&-y`N8jsp6dnv_E5UCopwD~bn?^FzZx>Kx32UG_r=ygWNocEQ&JwowbpRT_F8ZXZD zHh`?rFOIhjCh4xO8LHFE*5M>IN^5B}UuPiJ8HLfA>H7Jah0B@Y6f25)r)c0sy;HI_ zUlsLE-O%Q%+FX)R?-Z4C7xhjVX)}u3EW2h;1NFXBQSiWGiGT|kcWKx}n^gc~mxON6 z1=zvU=3^$die3r8haEqQmdHxGw)5&m7;Qdc z+%}x(=AkU1*r*#y?APXtI-B3Y^EUY;b&->-U(`jur<`~FGP=ldi}RG(!IEePheBvc zgY)@;7EhQRJkj>(*ZH-j%|R=>o>17;#kiFiQdubF*qQ*8x_X@t#r&x&9BxD0q+}T`5;&RKb|4GC}MK&L5e~Dq}vci5zbpOj3$Tx+Ywa(fOw< ze5uj$QSUp|=2D~j<+Bh0R5g2=EJOg+Ej(}9e3j0p81=qW8ZGY%PwH%%`sLefC~g&Q$zpG6xZjmNYsKvCgk8Xxa9>G*rP8)?!aH4#j?qWDX)) z_U|cw79wiU;+n@Uc{~Lr-8E;1M&H^woTO&OPL;WSn^vz^bq%&>Q?~OWVm^K4( zo6+kt4bd_~XLZ!CG49nQ-F3&?p0|~S2p>|bdK!CGuiqQ@3MAci#|)i;-&A5nZOl3& z#{p7Z$jE=3<71407?A)&su!JOh_3h5(yDM3>tDdGz)3CpS1?>53{JFJ_QLv|ws17k zX7k0o&OBmKP#KS88X3c=Wjb%5&k+|m02nj;Ph0r6S$3_maLtx-&TJ{=%9ZjJYhLG4 z%4JNTEdd*%Hh<*`X^8zvxZZbzxE#*XY9)3$18to}3$gY&58a)*=dQ|=MGAVX~NbMMC|8BA|vYTQ@ zbdJH=QfS{zzs|I$aF`FAbcHZD;R<<75EU8ircp-HSU(MY^gCT&b{be=uhC!Ua*NJp zjLt09|DoRZ2tA~RSLdZEsP|0))cab|EYJhiAM?a{jSjCrJk2j2`NKK#MlRKVw5iS2kpmWkUvz?Ftul0eGNv zhQa9YzEHF$xRebUNZOE1R(teO=kmV@n}?HhWxz+hQzzI`PI5n>MSEYUHUr63o4<N*oF`Q>_I7KHM`sml;w}FyPvR&b$djldt2>u+}$p6FtLWqp6gvh|rRib=b z?$#QOXQvCX7b zX)_aUvus>Ru@gjU3s0gg90qM+DdY-YqtTOQI~CDn3(K-Kf~G~IG#Z_Swrt_~64hyY5tQm)9f`6BCoab@PC-q+kxusFF8-PLSDhd-u0@{#qv zTWoO5`afukT*h5b4E2jHlycPhyc+`uPOyF&edOOxMf^6CtcvRgfRO8dHJxonMJcHF z)uP$IfO_8^vJg>&RFqf~cRlgOA=X6a-}SyQXi@l!8v_EUxJxX!V)Gy)UGM9Hva8S7=92}I!rT=H@1~d$>z}zP z&@j}m(wRmj>gD2t5hzf>(vuQQQ7@MzXb|;sVIl`2+I%wVm9Nav4xErE0{ z@m@<*=Q8iLr0HD7_F5XzZ^hVad9>G3<_3fCZfYIbO*TfZUjth9N4-0+f$JCBtYTf{ zZ!`LRCHBG)sU7U0&6CaaDz2Y2fAQ!S5B0uKn*9slcKY?pL%mb&5kl-B!*+@hLA_JG z?Gz)*LWB%bu9Pd~K7sFrHvgqamyq*=y9)K7Svf!Kpn9Vbl`<>!<*qrb9YlkG+!fZt z4x;A@>p|xdUFl2%o@aqyY20IrW&u~Py{a{uMZZ^5NM|z!7=$%zGl0FSF+q`?F)$CQp*{gb!ZHRkCU+x-&cd#^VcCajUcCcKPEq1UZ zHCmGHdPCIt^|Pa>XIJ2A2UVK8-VjY0chw_%ZTC>e=I3}~74r!)S+NCpH%{IH;yms>!kO;wXL-m47lnag+3UR{=ITd6% za$bOP!f3*{qsCQ#@slzmj8U}0y`qATfAK$y;4m*QUSI+<+;8m^Tnf|Y;f=@)6SB6!dX;YCbhc! z*j*+4xCN`3AA101_~RU2qas%>T*FnZ1M%Y--a3xqtpk4yeCxj-E8wl)e#`{7aGDx8 z$;YK%rRB#dsJ|-8kALK!%<|)%+)qCF@eBP)p&!4DS^nGLt$&KQZvMyemRs~E@z#%c ztNcf%{~i$f$D{u})cm8+e;P)d{|TV|A`<^uF#5$O{|9jNi#Yh=|C?VV|HIq`uJQ4A zeN=rM|FMQhLv&#P;F>W8rol7f3o!<-e88|??qes1>i-Qs4oNMo{pay<c=wwnf|Z--wa~%qnbIGm_Wpbd8_eqJEhr;r!#-5E=_x?DKnvn ziNj~dhv&zK2L}%uE=f(-OPTOUb+z4j_-?yYO>ZY*DCoy|;`l)V(NJuJ7!VSE0Quzj z0TSb}k9doN{z>k*khMnEZ;J?03fjvy0?m|*I3JX@}&bOMhZ5BF1XJ)1AR z{bx&+@Om=SNs_Hs+tqfpA3S=zq@PmlMzSD0Qr|AM;c}mP(OKoZ+;|b8WkbAa*{Eu) zLMUIQjMKohuDsB30elf@t|G}RV^AFNICUC)3dP~&0Z&v&r`oVHofts(>Upj!~>&p`pv_3ULdL7OaD@3h@S0SDiIinKdWb*GVZOC#7U3 zrHW2U37wQePqIc%va*wG(MeY5B#T}JlwAcZx(Y~i6)@q&1)Iol4`1n9KU452Ywif>H(Diso zzgkXx5FqpP@d+|(xFtLxJGEY_s|}gGT1vzmK}YOoCc$fKN|PzeoawSZUzLBoK(Fr~graKs-I^YPQ)3r;Z?wUMhD*WXGCod8e8NF$gX;#Jp>c?3^cazPLHlHeu4&S<eVb3#77mB( z^?}zp<1Jiq^oMU@0aU-d>(_B*vN9%$98TV}nTed?;Nb7yhDnA?#|>^FcKOXF+^U($fokcBrT^kv8XaWJ zZwjrLLJs`LSm+0#=!XI>*gxpTiG~_fbD*IUXP}Y$#}~YU2SGDA899}O%mI?dT1*fr zguD^C4BGz>$vE;6Ni{+jpct~KafBUgz<46!qzFI1|Ca&d$$y|15bjHVN=R_M->>%D zr8*tY#`7h%+RwLxf{-9S9}=Gba_XBX?Qljn+|DhBQ$mvdcsrikc)1x5X@|S74j@{*Sq&8|}!CMNz~e7O^N|QN$QyEMkmBj9G|3ZsKQ&I^vI?{trYC z#2*9wGU5yI$FM(!_#W}cHUBBri2tkj0U-XD`d#90h&f`6xDsKoAR37>#2#V`@kbmI z#~cza{t6PqA)cya9GId2o2W@NBeEao;2fNTb8rsM!8tew=a7&i8e!!ZBECoziM;+% z%TItM{uPj3Nq{{0f#iN5qtSoD>mPys8`wX>M)SYX`Nx^D99KW?^^015bqMy0M*Jec zesPF@Naq(j@T*V12s*z=fs6ywkL2}>Lh&c&MB0CJ&H$0Bd;GH`ERcu2mQKN`ueZsQM`%2_WHlXKQrR5G5l*h z{V444hX4yf2Zh)FC%*|Zb^a&)OIm=npo0Pku>Y?g1RW(W0<7@*ALU1SB{5Qj2K_)@ z|Ia`7`j7J?;57p_L#Kq_@00s|j{HeQFoOOV?1ypl$8>%e=5KrbFjjxk>!HMWpZUMaV!I1|^Pclnv z6B!2tC_Il9!T~l9!T~DPErVmArT} z{+Hj2%nPa7LDkfy3Z`GltH|poWn|I$)8PCx=Ift<{p8F)qm#m`1^dS?e@o{dtN4|? zQh5ENmEQ&IACdT7==|ddsx%!zN0=4hDX#E|XRyo&I`Aub8G-!=`iaI>er8j_jsheI+;f3=&cG)t3gHQSQe?6%$Pw^QQTbTg%0lG$vh#3W67NV%L6 z(rk&ZrknkCX)jIU*=E1g$NSBks65**_32XGRi)l+iH(>054Xe3nxsD^-E5}TbZL)= zyRY~A)oQxinWVR;zFL|~dpjkc%9}Z<<qPOJ_{d+w4wMo3Hot&2DJ|aK0zm zel=aX!zI~jx)~DhKPC0GU+u;uz2$H(H6B&69-4v5LqU+w3crAc1rRod0kobA3OwcpIf%jIe_mG|?_W>;&voe~fCv!~8f)i%5Ba4zhW zX0zFyAep5$9Fz1myX|mDIi(vTtg$|0$`n^v2uGka$mj zxSk6$wWdpw_WqOm*?73we{Qw3=QCu)bKCh08S(g>^nN}%hKzU~G-Sl{979Gt$1!BY z^AU!Ocn&mV#PgHLkfI?WK8$#-)^s`~B_u7RJtw_XNeKxO5>Ho4dq1C(UaHhWY{-b` zKSM@5_Zc$cIfsmRp3Cu6U9YCj0)yYELODt17(+&(kr9!RCTR{*3lItfQ5H*=9ugoi z$xI0`hYYetL_|a+Nm*qS(j0pcAWT7p&8Z_IKQ&wvntopKA!M{FkZ5HjS{$RWmGmfvf3YK`9fym1i& z!8VWTfON$BsV*{E|7d-Kbsd)Bk%9r627WN# zw_!fX(=2M|;wxsPa-=)_$hpaWfB_6$x!JFFvJaOS9%E%^`V3=F02?pYv#Tp7@>eC` zwAlQFH^K$3CGOW*SYjY2eAN8EMA&Iv&S`FZvZRrP4dT9lfgAuYfyjFhD>Hcoge|Vy zwj9kJGJ96F|4r%zqmPbED73Z7p(cma^B;nfi#~E>AFp`h^L@}09k0?U>+Hu@@vT*1iy6&6B?}L)_Rf;CO?7umrfp0$2%0C!(WL8{uQ1F`ist7Z3Rw_n&Pp1+WB*G*Wdz*HK`ZbP~VA@rnU#LXQ4=O#&4Ynk7QUh_MlD zy_)FIirWtJzNHW|FcFSoHGHR^P#Gf_Um4Rux`0U-eQ2ha0!HZ#u95Ifv!h<<;&(rn za$U6q!mtG0Sj;;`eKH~GLI+2Je6v92)ibtFSO%}pvb$eV6(_F|Gq6P!Pb?6MI;JlR zK5`>k0V-7EptIh0`bnMjk{TXPy~%j1GDXyrisw}HDo3yiM)os>4}Ggm6{yq@WC2@x zREOZH_Ee5BqZy`RrrEWR%7hj1R305iaN3QI!*eFnh?Fpie~9NXX7a;7Hg2FBA%8Sp z4|8)Yo8y?_Do27`vMHxVUB14nXc{agJea(wH&kg^m&w8U<;RbBdfFL38?D+=KdkVx zA`)XB3$tJ;wn+dDRF~GNxX{|Pr2_%T^cgCL)7|$kO5ZPHW&0MpqTV}o*dbk^*A%~OdDc9vvkCqA5`OrOG)U>k_e)5Ck6=dr|r=+)rN z#VM{vwJQYUWsbI@ZL<~@%uwRCM(gv@U^*jT`Aa;jRiB?PJgcAIIbP(F1;5yH<|Lp7 z2!Z|Yt9Srfxt2g379C~>^OI+CSJqiSXxh=azON$MnAmv;{Sg`Ka^6Zaxxq`soy+HG z2Be3*9EIxOR%XtSzc>trb|(A=-;nvL%K6RJVJ~i|MH}Hb4>)^14!-PGe zxJMmFR^o{Xb_MFQ7h7DB5(vdv6}=HRp=9Yv@uRQ(Ecsf^JUCDES*QKyb0A^6(sDJ&#KNChdL+4eDf# zW^UV#SN>y>=Z-+9#1k-kjS-}X2ju#{M3*V}Z>jI_Z`hysV+1d6H9>TkZxl`Wx&dA# zj`_*g?{{w5_yKeJrsA1B<~x1jUdL#^V^eZk*zU0M^-~6+2QkD(ASUQwGKGPI|i<)^>Q{e u3nYREfUQB8_20PH-oUV1w={16*Wv^WAM$wNDIU>vEI$k%{bvHSR&rP}lSS(Q diff --git a/scripts/build-kernel-audio.sh b/scripts/build-kernel-audio.sh index b2ca409..c3a0c0d 100755 --- a/scripts/build-kernel-audio.sh +++ b/scripts/build-kernel-audio.sh @@ -10,6 +10,13 @@ fi KERNEL_TAG="v6.12.1-msm8916" KERNEL_URL="https://github.com/msm8916-mainline/linux/archive/refs/tags/${KERNEL_TAG}.tar.gz" +KERNEL_CACHE_DIR="${KERNEL_CACHE_DIR:-/tmp/linux-msm8916}" +DOCKER_CACHE_ARGS="" +if [ -d "$KERNEL_CACHE_DIR" ]; then + DOCKER_CACHE_ARGS="-v $KERNEL_CACHE_DIR:/kcache" +fi + +# shellcheck disable=SC2086 exec docker run --rm --network=host \ -e HOST_UID="$(id -u)" \ -e HOST_GID="$(id -g)" \ @@ -17,6 +24,7 @@ exec docker run --rm --network=host \ -e KERNEL_URL="$KERNEL_URL" \ -v "$BASE_DIR:/bananarchy" \ -v "$ROOTFS_DIR:/target-rootfs:ro" \ + $DOCKER_CACHE_ARGS \ alpine:3.24 sh -eu -c ' cat > /etc/apk/repositories </dev/null; then + echo "[2/5] Applying Bananarchy QDSP6/Q6Voice and MSM8905/MSM8909 DTS patches..." + patch -p1 < /bananarchy/patches/kernel/0001-msm8909-qdsp6-voice-sound-nokia-argon-6.12.patch + fi + if [ ! -f include/config/auto.conf ]; then + echo "[3/5] Preparing kernel configuration..." + cp /bananarchy/patches/kernel/config-bananarchy-msm8909.armv7 .config + make ARCH=arm CROSS_COMPILE=armv7-alpine-linux-musleabihf- olddefconfig + make ARCH=arm CROSS_COMPILE=armv7-alpine-linux-musleabihf- modules_prepare + fi else - echo "[1/5] Downloading Linux ${KERNEL_TAG}..." - curl -sSL "$KERNEL_URL" -o linux.tar.gz - cp linux.tar.gz "$CACHE_TAR" || true + mkdir -p /tmp/kbuild + CACHE_TAR="/bananarchy/prebuilt/kernel-6.12.1-msm8916/linux-${KERNEL_TAG#v}.tar.gz" + cd /tmp/kbuild + if [ -f "$CACHE_TAR" ] && [ "$(wc -c < "$CACHE_TAR")" -gt 1000000 ]; then + echo "[1/5] Using cached Linux ${KERNEL_TAG} tarball..." + cp "$CACHE_TAR" linux.tar.gz + else + echo "[1/5] Downloading Linux ${KERNEL_TAG}..." + curl -f -sSL "$KERNEL_URL" -o linux.tar.gz + cp linux.tar.gz "$CACHE_TAR" || true + fi + tar -xzf linux.tar.gz + cd "linux-${KERNEL_TAG#v}" + + echo "[2/5] Applying Bananarchy QDSP6/Q6Voice and MSM8905/MSM8909 DTS patches..." + patch -p1 < /bananarchy/patches/kernel/0001-msm8909-qdsp6-voice-sound-nokia-argon-6.12.patch + + echo "[3/5] Preparing kernel configuration and Module.symvers..." + cp /bananarchy/patches/kernel/config-bananarchy-msm8909.armv7 .config + make ARCH=arm CROSS_COMPILE=armv7-alpine-linux-musleabihf- olddefconfig + make ARCH=arm CROSS_COMPILE=armv7-alpine-linux-musleabihf- modules_prepare fi - tar -xzf linux.tar.gz - cd "linux-${KERNEL_TAG#v}" - - echo "[2/5] Applying Bananarchy QDSP6/Q6Voice and MSM8905/MSM8909 DTS patches..." - patch -p1 < /bananarchy/patches/kernel/0001-msm8909-qdsp6-voice-sound-nokia-argon-6.12.patch - - echo "[3/5] Preparing kernel configuration and Module.symvers..." - cp /bananarchy/patches/kernel/config-bananarchy-msm8909.armv7 .config - make ARCH=arm CROSS_COMPILE=armv7-alpine-linux-musleabihf- olddefconfig - make ARCH=arm CROSS_COMPILE=armv7-alpine-linux-musleabihf- modules_prepare echo "[4/5] Building QDSP6/Q6Voice sound modules, torch LED module, camera module, and Nokia MSM8905/MSM8909 DTBs..." make ARCH=arm CROSS_COMPILE=armv7-alpine-linux-musleabihf- -j"$(nproc)" \ diff --git a/src/msm8905-cam/msm8905-cam.c b/src/msm8905-cam/msm8905-cam.c index 980d1b8..b68b259 100644 --- a/src/msm8905-cam/msm8905-cam.c +++ b/src/msm8905-cam/msm8905-cam.c @@ -320,6 +320,9 @@ static int msm8905_cam_hw_init(struct msm8905_cam_dev *cam) u16 chip_id; u32 r; + if (cam->hw_initialized) + return 0; + /* 1. Ensure PM8909 LDO6 (1.8V) and LDO17 (2.85V) are enabled */ if (cam->usid1_regmap) { regmap_update_bits(cam->usid1_regmap, PM8909_LDO6_EN_CTL, @@ -497,6 +500,29 @@ static int msm8905_cam_capture_rgb(struct msm8905_cam_dev *cam, u8 *dst_rgb) return ret; } + /* Ensure GC2395 stream and VFE0 WM0/RDI0 are idle before resetting ISPIF */ + gc2395_write_reg(cam, 0xfeU, 0x00U); + gc2395_write_reg(cam, 0xedU, 0x00U); + cam_w32(cam->camss_base, VFE0_BASE + 0x04cU, 0x00000000U); + cam_w32(cam->camss_base, VFE0_BASE + 0x6fcU, 0x00000000U); + wmb(); + + /* Reset ISPIF cleanly for this frame */ + cam_w32(cam->camss_base, ISPIF_BASE + 0x008U, 0x00001ff9U); + usleep_range(1000, 1500); + cam_w32(cam->camss_base, ISPIF_BASE + 0x008U, 0x00000000U); + usleep_range(1000, 1500); + cam_w32(cam->camss_base, ISPIF_BASE + 0x200U, 0x00000040U); + cam_w32(cam->camss_base, ISPIF_BASE + 0x230U, 0xffffffffU); + cam_w32(cam->camss_base, ISPIF_BASE + 0x234U, 0xffffffffU); + cam_w32(cam->camss_base, ISPIF_BASE + 0x238U, 0xffffffffU); + cam_w32(cam->camss_base, ISPIF_BASE + 0x01cU, 0x00000001U); + cam_w32(cam->camss_base, ISPIF_BASE + 0x208U, 0xffffffffU); + cam_w32(cam->camss_base, ISPIF_BASE + 0x20cU, 0xffffffffU); + cam_w32(cam->camss_base, ISPIF_BASE + 0x210U, 0xffffffffU); + cam_w32(cam->camss_base, ISPIF_BASE + 0x244U, 0x00000000U); + cam_w32(cam->camss_base, ISPIF_BASE + 0x264U, 0x00000001U); + /* Program WM0 PING & PONG to raw_dma_phys and arm single frame */ cam_w32(cam->camss_base, VFE0_BASE + 0x050U, (u32)cam->raw_dma_phys); cam_w32(cam->camss_base, VFE0_BASE + 0x054U, (u32)cam->raw_dma_phys); @@ -529,21 +555,21 @@ static int msm8905_cam_capture_rgb(struct msm8905_cam_dev *cam, u8 *dst_rgb) usleep_range(2000, 3000); } - /* Immediately stop WM0, ISPIF RDI0, and GC2395 stream to prevent overflow */ - cam_w32(cam->camss_base, ISPIF_BASE + 0x248U, 0xaaaaaaaaU); + /* Stop GC2395 stream, WM0, and RDI0 cleanly */ + gc2395_write_reg(cam, 0xfeU, 0x00U); + gc2395_write_reg(cam, 0xedU, 0x00U); cam_w32(cam->camss_base, VFE0_BASE + 0x04cU, 0x00000000U); + cam_w32(cam->camss_base, VFE0_BASE + 0x6fcU, 0x00000000U); cam_w32(cam->camss_base, VFE0_BASE + 0x024U, 0xffffffffU); cam_w32(cam->camss_base, VFE0_BASE + 0x028U, 0xffffffffU); cam_w32(cam->camss_base, VFE0_BASE + 0x018U, 0x00000001U); + cam_w32(cam->camss_base, ISPIF_BASE + 0x008U, 0x00001ff9U); + usleep_range(500, 1000); + cam_w32(cam->camss_base, ISPIF_BASE + 0x008U, 0x00000000U); wmb(); - gc2395_write_reg(cam, 0xfeU, 0x00U); - gc2395_write_reg(cam, 0xedU, 0x00U); - - if (!(irq0 & 0x00000040U)) { - cam->hw_initialized = false; + if (!(irq0 & 0x00000040U)) return -ETIMEDOUT; - } msm8905_cam_demosaic(cam->raw_dma_buf, dst_rgb); cam->sequence++; @@ -751,8 +777,9 @@ static int msm8905_cam_dqbuf(struct file *file, void *priv, b->field = V4L2_FIELD_NONE; b->sequence = cam->sequence; b->memory = V4L2_MEMORY_MMAP; + b->m.offset = idx * PAGE_ALIGN(CAM_OUT_FRAME_BYTES); b->length = CAM_OUT_FRAME_BYTES; - ktime_get_ts64((struct timespec64 *)&b->timestamp); + v4l2_buffer_set_timestamp(b, ktime_get_ns()); return 0; }