[PATCH v4 08/15] media: ov2740: support 288 MHz link frequency
From: Maurizio Casciano
Date: Fri Aug 28 2026 - 12:22:47 EST
The Lenovo Yoga Book YB1-X91 front camera uses two CSI-2 lanes at a
288 MHz link frequency. Add the matching PLL configuration and mode
timing.
Reuse the existing 1932x1092 crop and mode register list so the Bayer
order remains SGRBG across link frequencies. Cropping the CSI-2
receiver output to a smaller processed frame is a userspace pipeline
decision.
Link: https://lore.kernel.org/linux-media/apFzAc5XfV9gQpXS@kekkonen.localdomain/
Link: https://lore.kernel.org/linux-media/apF0Cds9fnqQ7XRg@kekkonen.localdomain/
Signed-off-by: Maurizio Casciano <mauriziocasciano7@xxxxxxxxx>
Assisted-by: Codex:gpt-5.6-sol sparse
---
drivers/media/i2c/ov2740.c | 45 +++++++++++++++++++++++++++++++++++---
1 file changed, 42 insertions(+), 3 deletions(-)
diff --git a/drivers/media/i2c/ov2740.c b/drivers/media/i2c/ov2740.c
index 18bb3ac9701f..c67fcbad5bdb 100644
--- a/drivers/media/i2c/ov2740.c
+++ b/drivers/media/i2c/ov2740.c
@@ -12,14 +12,16 @@
#include <linux/regmap.h>
#include <linux/regulator/consumer.h>
#include <linux/unaligned.h>
+#include <linux/units.h>
#include <media/v4l2-ctrls.h>
#include <media/v4l2-device.h>
#include <media/v4l2-fwnode.h>
-#define OV2740_LINK_FREQ_360MHZ 360000000ULL
-#define OV2740_LINK_FREQ_180MHZ 180000000ULL
+#define OV2740_LINK_FREQ_360MHZ (360 * HZ_PER_MHZ)
+#define OV2740_LINK_FREQ_288MHZ (288 * HZ_PER_MHZ)
+#define OV2740_LINK_FREQ_180MHZ (180 * HZ_PER_MHZ)
#define OV2740_SCLK 72000000LL
-#define OV2740_MCLK 19200000
+#define OV2740_MCLK (192 * HZ_PER_MHZ / 10)
#define OV2740_DATA_LANES 2
#define OV2740_RGB_DEPTH 10
@@ -91,6 +93,7 @@ struct nvm_data {
enum {
OV2740_LINK_FREQ_360MHZ_INDEX,
+ OV2740_LINK_FREQ_288MHZ_INDEX,
OV2740_LINK_FREQ_180MHZ_INDEX,
};
@@ -142,6 +145,14 @@ static const struct ov2740_reg mipi_data_rate_720mbps[] = {
{0x0312, 0x11},
};
+static const struct ov2740_reg mipi_data_rate_576mbps[] = {
+ {0x0302, 0x1e},
+ {0x0303, 0x00},
+ {0x030d, 0x1e},
+ {0x030e, 0x02},
+ {0x0312, 0x01},
+};
+
static const struct ov2740_reg mipi_data_rate_360mbps[] = {
{0x0302, 0x4b},
{0x0303, 0x01},
@@ -468,6 +479,7 @@ static const char * const ov2740_test_pattern_menu[] = {
static const s64 link_freq_menu_items[] = {
OV2740_LINK_FREQ_360MHZ,
+ OV2740_LINK_FREQ_288MHZ,
OV2740_LINK_FREQ_180MHZ,
};
@@ -478,6 +490,12 @@ static const struct ov2740_link_freq_config link_freq_configs[] = {
.regs = mipi_data_rate_720mbps,
}
},
+ [OV2740_LINK_FREQ_288MHZ_INDEX] = {
+ .reg_list = {
+ .num_of_regs = ARRAY_SIZE(mipi_data_rate_576mbps),
+ .regs = mipi_data_rate_576mbps,
+ }
+ },
[OV2740_LINK_FREQ_180MHZ_INDEX] = {
.reg_list = {
.num_of_regs = ARRAY_SIZE(mipi_data_rate_360mbps),
@@ -502,6 +520,22 @@ static const struct ov2740_mode supported_modes_360mhz[] = {
},
};
+static const struct ov2740_mode supported_modes_288mhz[] = {
+ {
+ .width = 1932,
+ .height = 1092,
+ .hts = 2160,
+ .vts_min = 1776,
+ .vts_def = 1776,
+ .vts_max = 32767,
+ .reg_list = {
+ .num_of_regs = ARRAY_SIZE(mode_1932x1092_regs_360mhz),
+ .regs = mode_1932x1092_regs_360mhz,
+ },
+ .link_freq_index = OV2740_LINK_FREQ_288MHZ_INDEX,
+ },
+};
+
static const struct ov2740_mode supported_modes_180mhz[] = {
{
.width = 1932,
@@ -1178,6 +1212,11 @@ static int ov2740_check_hwcfg(struct ov2740 *ov2740)
ov2740->supported_modes_count =
ARRAY_SIZE(supported_modes_360mhz);
break;
+ case OV2740_LINK_FREQ_288MHZ_INDEX:
+ ov2740->supported_modes = supported_modes_288mhz;
+ ov2740->supported_modes_count =
+ ARRAY_SIZE(supported_modes_288mhz);
+ break;
case OV2740_LINK_FREQ_180MHZ_INDEX:
ov2740->supported_modes = supported_modes_180mhz;
ov2740->supported_modes_count =
--
2.53.0