Skip to content

Cameras ​

Both cameras work with Harmattan's own camera stack, unchanged: the viewfinder at 30 fps with exposure, white balance and autofocus, switching between the cameras, stills up to 8 Mpixel, 720p video at 30 fps, and the flash. The OMAP3 ISP is mainline's driver with the 2011 interfaces Harmattan's binaries use; the sensors, the lens and the flash run on Nokia's own drivers.

The hardware ​

PartBusDriverNotes
Main camera, 8 MpixelCSI-2 (CSI2A on CSIPHY2, two data lanes), I2C2 0x10, moved to 0x37Nokia's smiappsmiapp-003 (Sony imx125) or smiapp-004 (Toshiba), by module; XCLKA 9.6 MHz
LensI2C2 0x0eNokia's ad58xxAD5836, AD5817 or BU8051GWZ, by module
FlashI2C2 0x30Nokia's as3645a (a V4L2 subdev)strobed by the sensor; its probe also turns off the red indicator NOLO leaves lit
Front cameraCSI-1 (CCP2 on CSIPHY1), I2C2 0x10Nokia's smiapptcm8500md or vw6558, mounted 180 degrees; XCLKB 10.8 MHz

Both sensors answer at 0x10 until the main one is moved, so, as in Nokia's board file, the main sensor and lens (XCLKA) and the front sensor (XCLKB) are never powered together. Both camera modules take their analog supply from VAUX3 (2.8 V).

The sensor modes are Nokia's register lists, read from the phone's own firmware files (/lib/firmware/smiapp-sensor-*.bin, smia-sensor-*.bin). Harmattan's 3A tuning (/etc/omapcam/) is calibrated against those modes.

Harmattan's camera stack ​

camera-ui, and Qt apps through QtMultimedia and camerabin2, drive GStreamer's subdevsrc2 with libgstcamera2, which sets the ISP pipeline up through the media controller and V4L2. The 3A library libomap3camd reads the ISP's statistics and sets exposure, gain and focus. The viewfinder goes into omapfb's video memory (an Xv plane) or into GPU textures; stills and video are encoded on the DSP through gst-dsp (see DSP and video).

What Harmattan's binaries expect, and where the kernel gives it to them:

Harmattan expectsCommit
Nokia's media controller ioctls from before the merge, _IOWR('M', 1..4)814959c57
entity ids 1, 2, 3... in registration order, used as list indices (6.18's are sparse)814959c57
VIDIOC_DQEVENT with Nokia's 120-byte struct v4l2_eventb2effda7c
fields it leaves uninitialised: which in enumerations, the frame interval's pad9426ffc1a
viewfinder buffers as user pointers into omapfb's VRAM (PFN mappings, 32-byte aligned)d2c81db51, 062c59031
the CCDC's per-frame V4L2_EVENT_OMAP3ISP_HS_VS, the ISP's private ioctls, Nokia's gamma bitsd8dbc76c7
the sensor at /sys/devices/platform/i2c_omap.2/i2c-2/2-0037/{nvm,ident}df99de755, Nokia's driver
subdev names camd matches (smiapp-003, ad5817 2-000e, as3645a 2-0030...), Nokia's sensor controlsNokia's drivers (eea14b1ac)

How a still is taken ​

The viewfinder stops and the pipeline runs briefly; the raw frame goes from CSI2A to memory; then three memory-to-memory passes take it back through the CCP2 receiver's memory input into the CCDC, the preview engine (with the 3A's parameters) and the resizer, each pass its own STREAMON/STREAMOFF. The YUV still then goes to the DSP's JPEG encoder. An 8 Mpixel still maps three 15.9 MiB frames and more into the DSP's address space at once; the DSP bridge's pool for user buffers is 256 MiB, as Nokia's, for that (35585001c).

The commits ​

CommitWhat
814959c57, b2effda7c, 9426ffc1a, d2c81db51Harmattan's media, event, subdev and user pointer interfaces (above)
d8dbc76c7omap3isp with Harmattan's interfaces: the HS_VS event, the D-PHY timing from the sensor's link frequency, one IOMMU mapping per buffer, statistics stamped with the wall clock, L3 held while streaming (omap3_l3 holder isp)
eea14b1acNokia's smiapp, ad58xx and as3645a on the 6.18 APIs, with the board file's glue (drivers/media/i2c/nokia-camera)
b152ccc33the DT: both modules, the lens, the flash, both ISP ports
ea7919a99, d793f1183the ISP built in; the sensor, lens and flash drivers modules (smiapp, ad58xx, as3645a) that udev loads once the root is up, so the firmware comes from the phone, as stock
1b2c8963fmainline bug: the histogram's buffers were allocated for a NULL device; the first histogram set-up oopsed
062c59031mainline bug: a PFN user pointer was mapped from its page's start; each frame landed up to a page early
74d9d3a45the CSI2 video port at least as fast as the link; the preview engine had finished one frame a second
d2e537990mainline bug: the time32 statistics request ran on a zeroed struct, so the 3A got nothing (a black viewfinder)
f9ce98a51several video nodes streaming in one pipeline: switching cameras or taking a still freed the pipeline twice
6a190206bthe CSI-1 receiver set up as Nokia's driver did: the front camera
fe27ef0a9the main sensor's scaled DPCM8 modes not offered (below)
e1792b9bfthe ISP's IOMMU powered only while the ISP is in use; it held the CAM domain on, and the CPU never left C1

Outside the kernel, the SGX driver (osfunc.c in pvr_sgx_rm696) takes a PFN mapping's addresses from the page tables: 6.18 no longer keeps the PFN in the mapping, and the GPU read from physical address 0 when an app put the viewfinder in GPU textures (an L3 error, a panic).

Checking it ​

sh
dmesg | grep -i "smiapp\|ad58\|as3645\|omap3isp"
lsmod | grep "smiapp\|ad58xx\|as3645a"
ls /dev/media0 /dev/video* /dev/v4l-subdev*
cat /sys/devices/platform/i2c_omap.2/i2c-2/2-0037/ident   # the main sensor
cat /sys/kernel/debug/omap3_l3                            # the isp hold while streaming

The build kit's tests/camera/ has the tools used for the port: ispcap (captures with Harmattan's interfaces: front camera, raw, DPCM and memory-to-memory modes), camabi.py (compares Nokia's camera headers with 6.18's), smiafw.py (dumps a sensor's register lists), uyvy2ppm.py.

Limitations ​

  • The main sensor's scaled DPCM8 modes (2728x2048, 3144x1772) are switched off when the firmware is read (... DPCM8 mode with sensor scaling disabled in the log). In them the sensor codes the first pixels of each odd line against the line two above, which the CCP2 memory input can't decompress: stills came out with colour streaks, and Nokia's stack most likely had them too. Harmattan picks another mode instead; camera-ui's resolutions never used these.
  • gst-dsp doesn't check its DSP memory reservations (userspace): with a smaller pool an 8 Mpixel still made the DSP fault. The 256 MiB pool makes them succeed.
  • In one stream, a memory-to-memory pipeline's second single-shot frame never comes (6.18 counts the modules as started). Harmattan runs one frame per stream, so only test tools see it.
  • An app started from a shell instead of through Harmattan may get "dsp open failed" while camera-ui's prestarted instance holds the DSP (the bridge's access policy); start it again.
  • camera-ui refuses to start ("cannot use camera while usb is connected") when MyDocs isn't writable.
  • Measure speed on a normal kernel: with DMA API debugging the DSP bridge's cache work cost 30 ms a frame and recording fell to about 19 fps.