Big Picture
imx708.c
is a Linux kernel driver for the Sony IMX708 camera sensor,
used by Raspberry Pi Camera Module 3 style hardware. It is an I2C driver
that registers a V4L2 sub-device, programs sensor registers, exposes
camera controls, and lets a CSI-2 receiver capture the image stream.
The module itself does not create a normal user-facing /dev/video0
capture device. It creates the sensor side of a media graph. A platform CSI
receiver driver, such as Raspberry Pi Unicam, binds to the other side of the
graph and becomes the capture device.
Ordinary Linux Kernel Driver Parts
These parts would look familiar in many non-camera kernel drivers:
-
I2C registration:
struct i2c_driver imx708_i2c_driverandmodule_i2c_driver()register the driver with the I2C core. -
Device-tree matching:
compatible = "sony,imx708"is the string Linux uses to bind the DT node to this driver. -
Probe/remove:
imx708_probe()allocates state, reads firmware properties, gets clocks/regulators/GPIOs, identifies the chip, and registers with subsystems. -
I2C register access:
imx708_read_reg(),imx708_write_reg(), andimx708_write_regs()perform raw register transactions. -
Power resources:
imx708_power_on()enables the regulator bulk, prepares the 24 MHz input clock, drives reset, and waits for the sensor to become usable. -
Runtime PM: the
dev_pm_opsblock connects system suspend/resume and runtime power transitions.
The ordinary kernel skeleton gives Linux a way to instantiate the device, allocate private state, claim hardware resources, and cleanly unload the module. None of that is camera-specific. A temperature sensor, EEPROM, or GPIO expander would also have a match table, probe function, remove function, I2C transfers, clocks, regulators, and power-management callbacks.
Parts Specific to V4L2 and Media Controller
The V4L2-specific layer makes the chip visible as a camera sensor entity,
not merely as an I2C peripheral. The main state object,
struct imx708,
embeds struct v4l2_subdev, two media pads, a V4L2 control
handler, and current media-bus format state.
A camera sensor is only one entity in a capture pipeline. The V4L2 media
controller model describes that pipeline as connected entities: sensor,
optional lens/VCM, CSI-2 receiver, ISP, scaler, and video node. This driver
registers the IMX708 as a v4l2_subdev because the sensor is
controlled by V4L2 but does not itself DMA frames into memory.
-
Sub-device operations are collected in
imx708_subdev_ops. The video op starts and stops streaming; pad ops enumerate formats, set formats, report frame sizes, and expose crop/native-size selection. -
Media pads are initialized in probe as two source pads:
IMAGE_PADfor Bayer pixels andMETADATA_PADfor embedded sensor data. -
Controls are created in
imx708_init_controls(): pixel rate, link frequency, blanking, exposure, analog/digital gain, flips, test pattern, color balance notification, and wide dynamic range. -
Streaming is V4L2-driven. When userspace enables the pipeline,
imx708_set_stream()powers the device and callsimx708_start_streaming(), which writes common registers, the selected mode table, link-frequency registers, user controls, and finallyIMX708_REG_MODE_SELECT. -
Hardware graph parsing is done by
imx708_check_hwcfg(). It reads the firmware endpoint as CSI-2 D-PHY, checks that the lane count is 2 or 4, and accepts only link frequencies listed by the driver.
Why V4L2 Needs All These Functions
V4L2 separates camera control into several smaller contracts because each part of a camera pipeline has different responsibilities. The sensor driver must answer questions from the capture driver and from userspace before streaming starts, then must program the chip consistently when the final format and controls are chosen.
-
enum_mbus_codetells the pipeline which wire formats the sensor can output. For this driver the image pad exposes 10-bit Bayer orders such asMEDIA_BUS_FMT_SRGGB10_1X10; the metadata pad exposesMEDIA_BUS_FMT_SENSOR_DATA. -
enum_frame_sizereports the supported sizes for a given media bus code. Without this, the receiver and userspace would not know that 4608x2592, 2304x1296, and 1536x864 are the meaningful choices. -
get_fmtandset_fmtimplement negotiation. The caller asks for a format; the sensor driver chooses the nearest supported mode, stores it as active state, and updates blanking/exposure limits. -
get_selectionexplains crop geometry. The driver can report native sensor size, active pixel-array bounds, default crop, and the crop rectangle used by the current mode. -
s_streamis the decisive start/stop callback. It is where the V4L2 pipeline says "now the links are configured; actually start sending CSI-2 packets." -
v4l2_ctrl_handlergives userspace a standard control API for exposure, gain, blanking, flips, HDR, test patterns, and link frequency. The callbackimx708_set_ctrl()translates those generic V4L2 controls into IMX708 register writes.
This is why the driver has both abstract V4L2 functions and concrete I2C writes. V4L2 speaks in formats, pads, controls, crops, and streams; the sensor understands register addresses and values. The driver is the translator.
Sensor Modes
Most of the C file is sensor knowledge: register tables and mode metadata. The driver supports 10-bit Bayer output with non-HDR and HDR tables.
Each struct imx708_mode
records dimensions, crop rectangle, line length, vertical blanking, pixel
rate, exposure rules, and whether the mode is HDR or full-resolution
Quad Bayer re-mosaic. The mode arrays start at
supported_modes_10bit_no_hdr
and supported_modes_10bit_hdr.
I2C Registers, Addresses, and Meaning
The IMX708 is configured by writing 16-bit register addresses over I2C.
The helper imx708_write_reg()
sends the high byte and low byte of the address, followed by one or two
data bytes. The mode tables are long lists of these address/value pairs.
| Address | Driver symbol | Meaning in this driver |
|---|---|---|
0x0016 |
IMX708_REG_CHIP_ID |
Read during probe. The expected 16-bit value is 0x0708. |
0x0000 |
module ID read | Read after chip ID. The value is used to label wide/noir variants in the subdevice name. |
0x0100 |
IMX708_REG_MODE_SELECT |
0x00 puts the sensor in standby; 0x01 starts streaming. |
0x0101 |
IMX708_REG_ORIENTATION |
Horizontal and vertical flip bits. The driver also changes Bayer order to match flips. |
0x0340 |
IMX708_REG_FRAME_LENGTH |
Frame length in lines. V4L2 vertical blanking updates this value. |
0x0342 |
IMX708_REG_LINE_LENGTH |
Line length in pixels/clocks. V4L2 horizontal blanking writes this timing value. |
0x0202 |
IMX708_REG_EXPOSURE |
Main exposure/coarse integration time. In HDR mode it represents the longest exposure. |
0x0204 |
IMX708_REG_ANALOG_GAIN |
Main analog gain. In HDR mode it is the gain for the longest exposure. |
0x020e |
IMX708_REG_DIGITAL_GAIN |
Digital gain, written from V4L2_CID_DIGITAL_GAIN. |
0x0224, 0x3116 |
IMX708_REG_SHT_EXPOSURE, IMX708_REG_MID_EXPOSURE |
Short and middle exposure registers used by the HDR mode tables. |
0x0216, 0x3118 |
IMX708_REG_SHT_ANALOG_GAIN, IMX708_REG_MID_ANALOG_GAIN |
Short and middle analog gain registers used with HDR exposure ratios. |
0x0600 |
IMX708_REG_TEST_PATTERN |
Enables disabled, color bars, solid color, grey bars, or PN9 test patterns. |
0x0602-0x0608 |
test pattern colors | Red, green-red, blue, and green-blue test-pattern color components. |
0x0b90, 0x0b92 |
red/blue color balance | Written by the custom V4L2_CID_NOTIFY_GAINS control. |
0x3100 |
IMX708_LONG_EXP_SHIFT_REG |
Long-exposure shift value used when frame length must exceed a 16-bit register. |
0x7b10, 0x7c00 |
PDAF gain bases | Base addresses for left/right phase-detect autofocus correction gains. |
0xc428, 0xc429 |
QBC correction | Enable and strength for Quad Bayer broken-line correction in full-resolution mode. |
The huge mode tables include many additional Sony-specific PLL, crop, binning, CSI output, and image-processing registers. The driver treats those as known-good recipes: choose a mode, write the table, then apply the current V4L2 controls on top.
How the Driver Gets the Sensor ID
The sensor ID path is
imx708_identify_module().
Probe powers the sensor first because the ID register cannot be read while
the chip is off. Then the driver reads register 0x0016 as a
16-bit value and compares it with 0x0708.
ret = imx708_read_reg(imx708, IMX708_REG_CHIP_ID,
IMX708_REG_VALUE_16BIT, &val);
if (val != IMX708_CHIP_ID)
return -EIO;
The low-level read uses a two-message I2C transaction. First it writes the
16-bit register address, then it performs an I2C read for the requested
number of bytes. For the chip ID, the address bytes are 0x00
and 0x16, and the driver expects the returned data to decode
as 0x0708.
After that, the driver also reads 0x0000. This is not the main
chip ID check. It is used as a camera module ID; the code logs it and uses
bits in that value to append _wide and _noir to
the V4L2 sub-device name.
From a running Linux system, the normal way to see this is through kernel logs, because the driver reads the ID during probe:
dmesg | grep -i imx708
To read it manually with I2C tools, the overlay must already have powered
the camera rail and selected the correct camera I2C bus. The sensor address
is 0x1a. On the correct bus, a 16-bit-address register read
would conceptually target register 0x0016; the exact command
depends on whether your I2C utility supports 16-bit register addresses.
If the kernel driver is bound, unbind it or avoid manual probing while the
camera stack is active.
Device Tree Parts
The overlay is split into
imx708-overlay.dts
and the included
imx708.dtsi.
The overlay connects Raspberry Pi board symbols to the sensor node and CSI
receiver. The included DTSI describes the actual sensor and focus motor.
-
imx708@1acreates an I2C device at address0x1awithcompatible = "sony,imx708". -
clock-names = "inclk"matches the driver'sdevm_clk_get(dev, "inclk")call. -
The supply names
vana1,vana2,vdig, andvddlmatch the driver's regulator list. -
The sensor endpoint declares CSI-2 wiring:
data-lanes = <1 2 3 4>andlink-frequencies = 450000000. -
fragment@101enables the CSI receiver endpoint and connects it back tocam_endpointwithremote-endpoint. -
__overrides__provides Raspberry Pi overlay parameters such ascam0,rotation,orientation,vcm, andlink-frequency.
Build and Install
The repository Makefile builds the kernel object against the running kernel headers and has a rule for compiling the overlay.
sudo apt install raspberrypi-kernel-headers build-essential device-tree-compiler dkms
cd imx708-v4l2-driver-4lane_dkms
make
make imx708-overlay.dtbo
After a successful build, the important outputs are normally:
imx708.ko: the loadable kernel module.imx708-overlay.dtbo: the compiled Raspberry Pi overlay blob.
Install the module into the current kernel's extra modules directory, install the overlay into Raspberry Pi's overlay directory, then refresh module dependency metadata.
sudo install -D -m 644 imx708.ko /lib/modules/$(uname -r)/extra/imx708.ko
sudo depmod -a
sudo install -m 644 imx708-overlay.dtbo /boot/overlays/imx708.dtbo
On some newer Raspberry Pi OS images the firmware partition is mounted at
/boot/firmware. In that case, install the overlay here instead:
sudo install -m 644 imx708-overlay.dtbo /boot/firmware/overlays/imx708.dtbo
Enable the overlay in the boot config. The usual Raspberry Pi pattern is:
camera_auto_detect=0
dtoverlay=imx708
If the module should be managed by DKMS, the existing dkms.conf
builds imx708.ko and runs dkms.postinst, which compiles
and installs imx708.dtbo.
Runtime Checks
After rebooting with the overlay enabled, confirm that the module and media graph are present:
lsmod | grep imx708
dmesg | grep -i imx708
media-ctl -p
v4l2-ctl --list-devices
If probe fails, the first places to check are the I2C address, the 24 MHz
inclk, regulator names, lane count, and link frequency. Those
are exactly the properties that imx708_probe() and
imx708_check_hwcfg() require before the V4L2 sub-device is
registered.