media: Add OmniVision OV32C4 sensor driver
Get series with b4
b4 am [email protected]Versions newest first · linked by author and title
- v4 Latest3 patches 9 repliesIn review
- v33 patches 1 replySuperseded
- v23 patches 4 repliesSuperseded
Earlier versions · 1
| Version | Posted | Patches | Replies | Status |
|---|---|---|---|---|
| v1 | 3 patches | 6 replies | Superseded |
Patches in v4 No applies recorded yet
| # | Subject and files | Size | Replies | Applied |
|---|---|---|---|---|
| 1/3 | dt-bindings: media: i2c: Add OmniVision OV32C4Documentation/ | +105 | 4 replies | |
| 2/3 | media: i2c: Add driver for OmniVision OV32C4MAINTAINERS drivers/ drivers/ +1 more | +2735 | 4 replies | |
| 3/3 | media: ipu-bridge: Add OmniVision OV32C4drivers/ | +25 | 0 replies |
Reviews trailers per patch
1 of 3 patches has a Reviewed-by or Acked-by.
| Patch | Conor Dooley |
|---|---|
| 1/3 | A-b |
| 2/3 | |
| 3/3 |
Trailers given in replies are filled; those carried in the patches from earlier versions are outlined with dashes.
Cover letter [PATCH v4 0/3] media: Add OmniVision OV32C4 sensor driver
Hi,
v4 of the OV32C4 sensor driver. v3 is at
https://lore.kernel.org/linux-media/[email protected]/
The one open question from v1 and v2 was the second I2C address - the write to 0x3e that the sensor needs before its main address answers - and whether it belongs in a sensor driver. v3 could only say what it was not. This version answers it with a measurement, and the design follows from the answer.
The question that decides it is whether the block behind 0x3e lives and dies with the sensor. Measured on the machine, polling 0x3e and 0x36 every 0.5 ms through a runtime power cycle and lining the polls up with the kernel's regulator, gpio and i2c tracepoints:
- sensor off (AVDD disabled, reset asserted): 0x3e NACKs, as does 0x36
- AVDD on at t=1.0 ms, settled 3.5 ms; reset released 8.9 ms
- 0x3e first ACK at 10.1 ms, reading 0x1001 = 0x00; between AVDD and the reset release it did not answer
- the driver's 0x1001 = 0x04 at 30.1 ms; 0x36 first ACK at 30.6 ms
- reset asserted and AVDD off at 4000.8 ms: 0x3e gone by 4001.9 ms,
0x36 by 4003.0 ms
So it is unreachable without power, appears only once the sensor's own reset is released, forgets the value written to it over a power cycle, and disappears with the sensor. It has no ACPI device of its own, 0x300a there reads zero (it is not an alias of the main map), and 0x36 has nothing at 0x1000. The same register pair exists in OV08X40 at that sensor's main address, named AO_STANDBY (0x1000) and MS_SELECT (0x1001, 0x04 for streaming) in ov08x40.c. The vendor Windows driver writes it from the sensor driver as well, once, after reset and before the chip id read, and never reads it back. I take all of that to mean the block is part of the sensor and the sensor driver is its owner.
What changed accordingly:
- The driver claims the second address with devm_i2c_new_dummy_device() and writes it through a CCI regmap of its own; the bare i2c_transfer() is gone.
- ipu-bridge no longer instantiates a VCM for this sensor. The SSDB says vcmtype 2 and the bridge would put a dw9714 on 0x3e; dw9714 has no id register and binds to anything, and that client would hold the address the sensor driver needs. Patch 3 carries the exception, so patches 2 and 3 go together.
Two smaller things turned up while re-reading the driver for this:
- The 10 ms after the software reset was a busy wait. The reset sat in the mode table with a delay_us, and regmap_multi_reg_write() turns that into udelay() on a regmap without can_sleep, which the CCI one is. The driver now issues the stream-off and the reset itself and sleeps; the table is the vendor's sequence minus those two entries.
- power_on() returned 0 when the enable write failed. It now fails and undoes the clock, the supply and the reset.
The power-up timing, your "0 and 5 ms" on v1: I did not follow it then, and I think I do now - nothing after the supply, because the regulator core waits for it, and 5 ms after reset. The measurement above agrees:
the block answers about 1 ms after reset release and the main address within 1 ms of the enable write. v4 uses 0, 5 ms and 1 ms, verified over a cold boot, 20 runtime power cycles and 15 stream starts without a failure.
Where the numbers come from, stated plainly this time, because v3 said both "copied 1:1" and "measured by me" about the same table:
From the vendor Windows driver (ov32c4.sys, FileVersion 70.26100.2.18255):
- the mode register table (1787 writes, at file offset 0x31300), of which the driver drops the first two entries, stream-off and reset, and issues them itself;
- the 400 MHz link frequency, carried there as bits per second;
- the chip id 0x563243;
- the write of 0x04 to 0x1001 at the second address;
- the registers the controls use (exposure 0x3500, analogue gain 0x3508, digital gain 0x350a, VTS 0x380e) and the rule exposure_max = VTS - 32.
Measured on the sensor:
- the chip id, the register meanings above and the exposure rule,
confirmed against what the chip reports;
- the gain ranges: analogue exactly proportional between 0x100 and
0x7c0 (1x to 7.75x, 0x100 being the power-up value), digital
proportional with 1024 as unity, clipping to black one step above
16383 - the obvious donor, ov13b10 on the same registers, puts
analogue unity at 0x80, which is wrong here;
- the timings: 320000000 / (4080 * 2614) = 30.005 fps against a
measured 30.00; the power-up sequence as above;
- flips preserve the Bayer order, so the media bus code never changes
and the crop compensation ov13b10 does would introduce the shift it
undoes there;
- the 6560x4928 array and 6528x4896 active area, from the window
registers of the table, agreeing with the vendor's product brief;- the second address, as above.
The rest of the series is as before. It adds a driver for the OmniVision OV32C4, a 32 megapixel RGBC CMOS image sensor. It ships as the under-display camera in the Lenovo Yoga Slim 9 14ILL10, where it is enumerated through ACPI (_HID "OVTI32C4") and feeds an Intel IPU7. The driver supports 3264x1840 at 30 fps, 10-bit Bayer, 4 CSI-2 lanes at a 400 MHz link frequency, with exposure, analogue gain, digital gain, vblank, hblank and flip controls, runtime PM and .get_selection. Tested on that machine: the sensor probes, streams at a measured 30.00 fps, frames arrive complete, and the full path to a processed image runs through libcamera's software ISP. The driver has what libcamera's sensor driver requirements ask for: the five mandatory controls, the crop selection targets, flips that keep the Bayer order, and the orientation and rotation properties.
v4l2-compliance on the subdev, kernel 7.0.0-38:
Total for device /dev/v4l-subdev4: 46, Succeeded: 46, Failed: 0, Warnings: 0
Static checks: checkpatch.pl --strict, sparse (C=1), W=1 and dt_binding_check.
The series applies to media_stage.git; base-commit is below.
Thanks,
Robert
Robert Bozik (3):
dt-bindings: media: i2c: Add OmniVision OV32C4
media: i2c: Add driver for OmniVision OV32C4
media: ipu-bridge: Add OmniVision OV32C4
.../bindings/media/i2c/ovti,ov32c4.yaml | 105 + MAINTAINERS | 8 + drivers/media/i2c/Kconfig | 10 + drivers/media/i2c/Makefile | 1 + drivers/media/i2c/ov32c4.c | 2716 +++++++++++++++++ drivers/media/pci/intel/ipu-bridge.c | 26 +- 6 files changed, 2865 insertions(+), 1 deletion(-) create mode 100644 Documentation/devicetree/bindings/media/i2c/ovti,ov32c4.yaml create mode 100644 drivers/media/i2c/ov32c4.c
base-commit: 4900cad020c0580dfb1be27776ff10a4ef110cfa
Signature · 1 line
2.53.0