feat(camera): add bananarchy-photo CLI, Sxmo menu integration, and multi-capture ISPIF/VFE0 reset

This commit is contained in:
Luxferre
2026-10-19 23:51:09 +03:00
parent a14a7aa543
commit ad012360c3
10 changed files with 322 additions and 52 deletions
+31 -15
View File
@@ -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
+1 -1
View File
@@ -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`.
+187
View File
@@ -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 <dev> 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
@@ -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;
@@ -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) && \
@@ -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"
Binary file not shown.
+43 -19
View File
@@ -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 <<EOF
https://mirror.nura.eco/postmarketos/v26.06
@@ -46,27 +54,43 @@ EOF
g++-armv7 \
binutils-armv7
mkdir -p /tmp/kbuild /bananarchy/prebuilt/kernel-6.12.1-msm8916
CACHE_TAR="/bananarchy/prebuilt/kernel-6.12.1-msm8916/linux-${KERNEL_TAG#v}.tar.gz"
cd /tmp/kbuild
if [ -f "$CACHE_TAR" ]; then
echo "[1/5] Using cached Linux ${KERNEL_TAG} tarball..."
cp "$CACHE_TAR" linux.tar.gz
mkdir -p /bananarchy/prebuilt/kernel-6.12.1-msm8916
if [ -d /kcache ] && [ -f /kcache/Makefile ]; then
echo "[1/5] Using cached kernel tree in /kcache..."
cd /kcache
if ! grep -q "Q6VOICE_PATH_VOICE" include/dt-bindings/sound/qcom,q6voice.h 2>/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)" \
+36 -9
View File
@@ -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;
}