[PATCH v4 0/5] media: ov02c10: get_selection and 26 MHz clock support
From: Felipe Calliari
Date: Sun Oct 25 2026 - 23:51:50 EST
Some Raptor Lake laptops, e.g. the Samsung Galaxy Book3 series, feed the
OV02C10 a 26 MHz external clock, which the driver rejects at probe
today. This series adds support for it, together with two small changes
found along the way.
Patches 1, 2 and 4 are unchanged from v3, apart from a rebase onto the
chip ID change in next. Patch 3 moves the PLL block of the per-lane
tables into a table tied to the link frequency, keeping every register
write. Patch 5 adds a 26 MHz PLL table as a second link frequency, and
picks the link frequency listed by the firmware that the external clock
can produce.
With the other PLL registers as set by the common mode table, the link
frequency is mclk * M / 19.2, M being the OP and VT PLL multipliers,
which are set to the same value. The 19.2 MHz table uses M = 400. At
26 MHz an exact 400 MHz would need M = 295.38, so patch 5 uses M = 295
(0x0127): 399.479167 MHz, advertised as such, with a pixel rate of
159.791666 MHz on two lanes. M = 296 would give 400.833333 MHz. Getting
exactly 400 MHz from 26 MHz needs a divider with a factor of 13. I have
no PLL documentation for this sensor. Sweeping 0x0301, 0x0303, 0x0313
and 0x031c around their table values only gave coarse steps, no output
or no change, so I don't think such a divider is available.
Tested on a Samsung Galaxy Book3 Ultra (Raptor Lake, two CSI-2 lanes,
26 MHz clock):
With v4, backported to the running 7.2.11 kernel:
- The firmware lists both link frequencies. link_frequency reads
399479167 (menu item 1) and pixel_rate 159791666.
- The PLL registers read back while streaming are 0x0301 = 0x08,
0x0303 = 0x05, 0x0304/0x0305 = 0x01/0x27, 0x0313 = 0x40,
0x0315/0x0316 = 0x01/0x27 and 0x031c = 0x4f.
- A 300 frame capture runs at 30.014 fps, with the same skipped
sequence number 1 and single "Frame sync error" at stream start as
v3.
With v3, which writes the same registers:
- link_frequency reads 399479167 and pixel_rate 159791666.
- I rewrote VTS over i2c while streaming and fitted the frame period,
from buffer timestamps, against four VTS values from 2360 to 4600
lines. That gives a line time of 14268.73 ns for an HTS of 2280,
i.e. a pixel rate of 159.7899 MHz, 11 ppm below the advertised
value. The intercept is -0.02 lines.
- At the default VTS, a 60 s capture runs at 30.014 fps. No frames are
dropped, apart from sequence number 1, which is skipped at every
stream start with or without this series. 30.014 fps is below the
30.105 fps that hblank, vblank and pixel_rate describe. The cause is
not the PLL: with the exposure at its maximum (VTS - 8) the sensor
stretches the frame to exposure + 15 lines. That is a separate issue,
which I'll look at on its own.
- A single CSI-2 "Frame sync error" is logged at stream start, as it is
with the unmodified tables.
The 19.2 MHz path is untested, as I have no such hardware. It writes
the same values to the same registers as before. Only the per-lane
registers other than 0x3016 are now written after the PLL registers.
Changes in v4:
- Rebased onto next, which narrowed the chip ID check. Patch 2 had a
context conflict there.
- Patch 3: tie the PLL table to the link frequency through a
link_freq_configs[] array, not to the external clock (Sakari). Leave
the common table alone, 0x0303 = 0x06 and 0x0305 = 0xe0 included,
and only move the "plls" block of the per-lane tables (Sakari).
- Patch 5: record the external clock rate each link frequency needs in
link_freq_configs[], and pick the link frequency from the firmware
list and the clock rate. This replaces the external clock check in
probe.
v3: https://lore.kernel.org/linux-media/20260923234100.318151-1-calliarifelipe@xxxxxxxxx/
v2: https://lore.kernel.org/linux-media/20260923144257.119076-1-calliarifelipe@xxxxxxxxx/
v1: https://lore.kernel.org/linux-media/20260905030732.39196-1-calliarifelipe@xxxxxxxxx/
Felipe Calliari (5):
media: ov02c10: Drop duplicate register write
media: ov02c10: Implement get_selection
media: ov02c10: Split the PLL registers off the mode tables
media: ipu-bridge: Add the OV02C10 26 MHz link frequency
media: ov02c10: Add support for a 26 MHz external clock
drivers/media/i2c/ov02c10.c | 122 +++++++++++++++++++++++----
drivers/media/pci/intel/ipu-bridge.c | 2 +-
2 files changed, 105 insertions(+), 19 deletions(-)
base-commit: d7e7bca7169873b46e857c025c10f3336c1258d8
--
2.56.0