rear imx363 is at 0x1a on blueline, shipped in r162 on edge with the rotation fix; blueline-camera 1-1 owns the userspace half. fingerprint row catches up to its own task doc: wall down, protocol recovered.
8 KiB
TASK 46 — Camera
Status: front pair proven on glass 2026-07-29. Rear IMX363 wired
(c7784b716), answers at 0x1a (8fc7623a3), rotation corrected
(457a667bd) — all three on blueline, shipped as
linux-blueline-7.1.1.r162.g457a667bd3eb-1 on edge. Userspace half shipped as
blueline-camera 1-1. Left: exposure/gain controls and a fresh acceptance pass
on glass. Repos: Fimeg/linux-blueline (canonical kernel), Pixel3Arch
(DT, packages).
THE FRONT CAMERA WORKS — first frame captured 2026-07-29
No reboot, no new kernel, no DT change. On the running kernel
(7.1.1-sdm845-g2bb09876e66a) the whole front path was already live and
nobody had tried it: qcom_camss and imx355 loaded, /dev/media0 +
/dev/video0..13, and both front sensors bound and linked
ENABLED,IMMUTABLE — imx355 17-001a -> msm_csiphy1, imx355 17-0010 ->
msm_csiphy2. The sensor advertises exactly one format,
SRGGB10_1X10/3280x2464.
Captured a real 10,131,968-byte frame off /dev/video0 and debayered it: a
ceiling, a curtain rail with the curtains drawn, a doorframe, a smoke
detector. Correct geometry, correct colour, sane noise. This device has now
produced a camera image.
The exact recipe (RDI raw path, no ISP)
M=/dev/media0
media-ctl -d $M -l '"msm_csiphy1":1 -> "msm_csid0":0 [1]'
media-ctl -d $M -l '"msm_csid0":1 -> "msm_vfe0_rdi0":0 [1]'
F='[fmt:SRGGB10_1X10/3280x2464]'
for p in '"imx355 17-001a":0' '"msm_csiphy1":0' '"msm_csiphy1":1' \
'"msm_csid0":0' '"msm_csid0":1' '"msm_vfe0_rdi0":0' '"msm_vfe0_rdi0":1'; do
media-ctl -d $M -V "$p $F"
done
v4l2-ctl -d /dev/video0 --set-fmt-video=width=3280,height=2464,pixelformat=pRAA
v4l2-ctl -d /dev/video0 --stream-mmap --stream-count=1 --stream-to=/tmp/frame.raw
Gotchas that cost time, so they are written down:
- The node is Video Capture Multiplanar.
RG10is rejected; the format that matches SRGGB10 ispRAA(10-bit Bayer RGRG/GBGB Packed). - The row stride is 4112, not 4100. 3280 px x 10 bits = 4100 bytes of payload; the driver pads each row to 4112. Reshaping by 4100 shears the image diagonally and looks like a broken sensor.
- MIPI RAW10 packing: 4 pixels per 5 bytes — bytes 0-3 are the high 8 bits,
byte 4 packs the four low bit-pairs, pixel
itaking(b4 >> 2i) & 3. - Black level is ~64 in 10-bit (the
0x10floor visible in a raw hexdump). Subtract it before scaling or everything is a flat grey field. cam/qcam(libcamera) are NOT installed.media-ctlandv4l2-ctlare. There is no auto-exposure running, so the frame is whatever the sensor's power-on defaults give — dark indoors, and that is expected, not a fault.
What this changes
The rear path is finished and shipped (see status). The userspace half is done
too: blueline-camera 1-1 — libcamera's simple-pipeline soft-ISP exported
through PipeWire, so a portal consumer sees a real camera — built by Pixel3Arch
CI and published into the shared multi-producer edge archive. Recipe:
Pixel3Arch/pkgs/blueline-camera. Remaining: exposure/gain controls
(v4l2-ctl --list-ctrls on the sensor subdev), a fresh acceptance pass on
glass for the rear path, then TASK-12's face-auth question.
What was actually missing
A first pass at this said blueline's DT declared no camera at all. Wrong — that
grep only looked at sdm845-google-blueline.dts, and the camera lives in the
sdm845-google-common.dtsi it includes. The real state:
| Piece | State |
|---|---|
| CAMSS driver (Titan 170 ISP) | present, CONFIG_VIDEO_QCOM_CAMSS=m |
imx363.c / imx355.c |
present, both =m |
| Front IMX355 ×2 (CCI1, CSIPHY1+2, ports 1/2) | already declared, with regulators, reset pins and shared MCLK2 |
| Rear IMX363 (CCI0, CSIPHY0, port 0) | was absent — added c7784b716 |
So the front half had been done and the rear was never finished. CSIPHY0 and CCI master 0 sat unused with the driver built and enabled.
What was added (kernel c7784b716, branch mic-race-fix)
Read off the downstream DTBO's cam-sensor@0 (~/pixel3-work/dtbo_9.dts),
which is the same source the front pair's numbers came from — every front value
in the tree matches its downstream node exactly, which is what made the rear
ones trustworthy:
- MCLK0 gpio13, RESET0 gpio80, VANA0 gpio16 (a GPIO switch off BOB, same shape as both front avdd regulators)
vdig→vreg_s3a_1p35,vif→vreg_lvs1_1p8,vana→ newcamera_rear_avdd- 24 MHz MCLK and a 636 MHz link frequency — what the driver's 24 MHz table expects; the front pair runs 19.2 MHz because the imx355 driver wants that
camssport@0 →csiphy0, 4 lanes
Verified by compiling the DTB: 117,471 bytes, no new warnings, every phandle and lane value correct in the decompiled output.
The one guess in it — ANSWERED 2026-08-01, and it cost the front camera
The slave address. 0x10 was Xiaomi beryllium's for the same IMX363, and the
address is in neither the downstream DTBO nor the eeprom node cam-sensor@0
points at (qcom,eeprom@1, phandle 0x25, cci-master = <0x00> — confirms CCI0,
carries no slave-addr). On glass, 0x10 NACKs:
imx363: 4 lanes
imx363 16-0010: Error reading reg 0x0016: -6
imx363 16-0010: failed to read chip id 363
-ENXIO, and imx363_probe() calls imx363_power_on() before
imx363_identify_module(), so the rail, reset and MCLK were all exercised and
nothing answered. Moved to 0x1a (8fc7623a3), the remaining candidate —
landed on blueline, which also carries the rotation fix. Trap with a date:
on 2026-08-20 both local kernel clones read that commit as missing, because
their origin points at the sibling checkout and neither had ever fetched the
forge branches. Fetch from Fimeg/linux-blueline before declaring a commit
lost. mic-race-fix still sits at the 0x10 state and is superseded by
blueline; fold or delete it.
The expensive lesson is what a failed sensor probe does to the others.
camss_subdev_notifier_complete() creates every sensor→csiphy link, and
.complete only fires once all declared async subdevs have bound. The rear
sensor never bound, so the notifier never completed, so no sensor links were
created — the front pair stayed registered (entity 235/237) with 0 links
each, and the working front camera stopped working. Adding a broken sensor is
not a contained failure on this driver.
Practical consequence: never leave a non-probing sensor node enabled. A DTB with
the rear status = "disabled" is kept on the device as
/boot/dtbs/sdm845-google-blueline.dtb.rear-off for exactly this — it restores
the front camera in one cp and a reboot.
The DTB is loaded separately by extlinux (fdt /boot/dtbs/...), so testing an
address costs a DTB build and a reboot, not a kernel rebuild.
Acceptance
media-ctl -penumerates a pipeline and the rear sensor probes.v4l2-ctlstreams a frame off it.- A still lands on disk. Colour and tuning are not acceptance — libcamera needs a tuning file and there is none for this unit.
The driver is a WIP snapshot, and that is the next lever
imx363.c in our tree carries commented-out register writes, a commented-out
19.2 MHz link-frequency table, and a literal // NOT SURE HOW TO FIND THIS VALUE against the 636 MHz entry. Two modes only (4032×3024, 1920×1080), no
lens/actuator support — so no autofocus, though the downstream node has an
actuator and an eeprom on the same bus.
Casey has a Matrix conversation with Dylan Van Assche pointing at a newer commit with "all the possible fixes, focus and more". It is not in mainline or linux-next (both checked directly, 404), not in linux-media patchwork, and not on the branches of his GitLab fork or the sdm845-mainline group repo. Get the link from that conversation rather than re-searching — it is the difference between two modes and a working camera.
Connects to
TASK-12 (face auth wants the front sensors, already wired), TASK-40 (a camera stream is the sharpest inference-tiering case on the device), TASK-20 (where captured media would land).