On Mon Aug 3 11:20:34 2026 +0530, Shravan Chippa wrote:
> Add 222 MHz link frequency support and refactor clock registers into
> per-frequency register lists. Introduce imx334_clk_params to map each
> link frequency to its register set and supported resolution range.
> Make the link frequency control writable so userspace can select the
> desired operating point.
> 
> Signed-off-by: Shravan Chippa <[email protected]>
> Signed-off-by: Sakari Ailus <[email protected]>

Patch committed.

Thanks,
Sakari Ailus

 drivers/media/i2c/imx334.c | 132 ++++++++++++++++++++++++++++++++++++++-------
 1 file changed, 112 insertions(+), 20 deletions(-)

---

diff --git a/drivers/media/i2c/imx334.c b/drivers/media/i2c/imx334.c
index 553a16b84f4d..fb036873859c 100644
--- a/drivers/media/i2c/imx334.c
+++ b/drivers/media/i2c/imx334.c
@@ -109,6 +109,7 @@
 /* CSI2 HW configuration */
 #define IMX334_LINK_FREQ_891M          891000000
 #define IMX334_LINK_FREQ_445M          445500000
+#define IMX334_LINK_FREQ_222M          222750000
 #define IMX334_NUM_DATA_LANES          4
 
 #define IMX334_REG_MIN                 0x00
@@ -154,7 +155,6 @@ struct imx334_reg_list {
  * @vblank_min: Minimal vertical blanking in lines
  * @vblank_max: Maximum vertical blanking in lines
  * @pclk: Sensor pixel clock
- * @link_freq_idx: Link frequency index
  * @reg_list: Register list for sensor mode
  */
 struct imx334_mode {
@@ -165,7 +165,28 @@ struct imx334_mode {
        u32 vblank_min;
        u32 vblank_max;
        u64 pclk;
-       u32 link_freq_idx;
+       struct imx334_reg_list reg_list;
+};
+
+/**
+ * struct imx334_clk_params - imx334 sensor clock parameters
+ * @data_rate_per_lane: Data rate per lane in bits per second
+ * @link_freq: Link frequency in Hz
+ * @width_max: Maximum image width in pixels
+ * @height_max: Maximum image height in pixels
+ * @width_min: Minimum image width in pixels
+ * @height_min: Minimum image height in pixels
+ * @default_mode: Pointer to the default sensor mode
+ * @reg_list: Register list for clock configuration
+ */
+struct imx334_clk_params {
+       u32 data_rate_per_lane;
+       u32 link_freq;
+       u32 width_max;
+       u32 height_max;
+       u32 width_min;
+       u32 height_min;
+       const struct imx334_mode *default_mode;
        struct imx334_reg_list reg_list;
 };
 
@@ -216,6 +237,7 @@ struct imx334 {
 static const s64 link_freq[] = {
        IMX334_LINK_FREQ_891M,
        IMX334_LINK_FREQ_445M,
+       IMX334_LINK_FREQ_222M,
 };
 
 /* Sensor common mode registers values */
@@ -233,13 +255,6 @@ static const struct cci_reg_sequence common_mode_regs[] = {
        { IMX334_REG_UNREAD_PARAM6,     0x0008 },
        { IMX334_REG_XVS_XHS_OUTSEL,    0x20 },
        { IMX334_REG_XVS_XHS_DRV,       0x0f },
-       { IMX334_REG_BCWAIT_TIME,       0x3b },
-       { IMX334_REG_CPWAIT_TIME,       0x2a },
-       { IMX334_REG_INCKSEL1,          0x0129 },
-       { IMX334_REG_INCKSEL2,          0x06 },
-       { IMX334_REG_INCKSEL3,          0xa0 },
-       { IMX334_REG_INCKSEL4,          0x7e },
-       { IMX334_REG_SYS_MODE,          0x02 },
        { IMX334_REG_HADD_VADD,         0x00 },
        { IMX334_REG_VALID_EXPAND,      0x03 },
        { IMX334_REG_TCYCLE,            0x00 },
@@ -397,6 +412,39 @@ static const struct cci_reg_sequence mode_3840x2160_regs[] 
= {
        { IMX334_REG_TPLX,              0x005f },
 };
 
+/* Data rate 1782Mbps per lane and 891Mhz link frequency */
+static const struct cci_reg_sequence link_freq_891m_regs[] = {
+       { IMX334_REG_BCWAIT_TIME,       0x3b },
+       { IMX334_REG_CPWAIT_TIME,       0x2a },
+       { IMX334_REG_INCKSEL1,          0x0129 },
+       { IMX334_REG_INCKSEL2,          0x02 },
+       { IMX334_REG_INCKSEL3,          0xa0 },
+       { IMX334_REG_INCKSEL4,          0x7e },
+       { IMX334_REG_SYS_MODE,          0x00 },
+};
+
+/* Data rate 891Mbps per lane and 445Mhz link frequency */
+static const struct cci_reg_sequence link_freq_445m_regs[] = {
+       { IMX334_REG_BCWAIT_TIME,       0x3b },
+       { IMX334_REG_CPWAIT_TIME,       0x2a },
+       { IMX334_REG_INCKSEL1,          0x0129 },
+       { IMX334_REG_INCKSEL2,          0x06 },
+       { IMX334_REG_INCKSEL3,          0xa0 },
+       { IMX334_REG_INCKSEL4,          0x7e },
+       { IMX334_REG_SYS_MODE,          0x02 },
+};
+
+/* Data rate 445Mbps per lane and 222Mhz link frequency */
+static const struct cci_reg_sequence link_freq_222m_regs[] = {
+       { IMX334_REG_BCWAIT_TIME,       0x3b },
+       { IMX334_REG_CPWAIT_TIME,       0x2a },
+       { IMX334_REG_INCKSEL1,          0x0129 },
+       { IMX334_REG_INCKSEL2,          0x0a },
+       { IMX334_REG_INCKSEL3,          0xa0 },
+       { IMX334_REG_INCKSEL4,          0x7e },
+       { IMX334_REG_SYS_MODE,          0x02 },
+};
+
 static const char * const imx334_test_pattern_menu[] = {
        "Disabled",
        "Vertical Color Bars",
@@ -442,7 +490,6 @@ static const struct imx334_mode supported_modes[] = {
                .vblank_min = 90,
                .vblank_max = 132840,
                .pclk = 594000000,
-               .link_freq_idx = 0,
                .reg_list = {
                        .num_of_regs = ARRAY_SIZE(mode_3840x2160_regs),
                        .regs = mode_3840x2160_regs,
@@ -455,7 +502,6 @@ static const struct imx334_mode supported_modes[] = {
                .vblank_min = 45,
                .vblank_max = 132840,
                .pclk = 297000000,
-               .link_freq_idx = 1,
                .reg_list = {
                        .num_of_regs = ARRAY_SIZE(mode_1920x1080_regs),
                        .regs = mode_1920x1080_regs,
@@ -468,7 +514,6 @@ static const struct imx334_mode supported_modes[] = {
                .vblank_min = 45,
                .vblank_max = 132840,
                .pclk = 297000000,
-               .link_freq_idx = 1,
                .reg_list = {
                        .num_of_regs = ARRAY_SIZE(mode_1280x720_regs),
                        .regs = mode_1280x720_regs,
@@ -481,7 +526,6 @@ static const struct imx334_mode supported_modes[] = {
                .vblank_min = 45,
                .vblank_max = 132840,
                .pclk = 297000000,
-               .link_freq_idx = 1,
                .reg_list = {
                        .num_of_regs = ARRAY_SIZE(mode_640x480_regs),
                        .regs = mode_640x480_regs,
@@ -489,6 +533,46 @@ static const struct imx334_mode supported_modes[] = {
        },
 };
 
+static const struct imx334_clk_params imx334_clk_params[] = {
+       {
+               .data_rate_per_lane = 1782000000,
+               .link_freq = IMX334_LINK_FREQ_891M,
+               .width_max = 3840,
+               .height_max = 2160,
+               .width_min = 3840,
+               .height_min = 2160,
+               .default_mode = &supported_modes[0], /* 3840x2160 */
+               .reg_list = {
+                       .num_of_regs = ARRAY_SIZE(link_freq_891m_regs),
+                       .regs = link_freq_891m_regs,
+               },
+       }, {
+               .data_rate_per_lane = 891000000,
+               .link_freq = IMX334_LINK_FREQ_445M,
+               .width_max = 1920,
+               .height_max = 1080,
+               .width_min = 640,
+               .height_min = 480,
+               .default_mode = &supported_modes[1], /* 1920x1080 */
+               .reg_list = {
+                       .num_of_regs = ARRAY_SIZE(link_freq_445m_regs),
+                       .regs = link_freq_445m_regs,
+               },
+       }, {
+               .data_rate_per_lane = 445500000,
+               .link_freq = IMX334_LINK_FREQ_222M,
+               .width_max = 1920,
+               .height_max = 1080,
+               .width_min = 640,
+               .height_min = 480,
+               .default_mode = &supported_modes[1], /* 1920x1080 */
+               .reg_list = {
+                       .num_of_regs = ARRAY_SIZE(link_freq_222m_regs),
+                       .regs = link_freq_222m_regs,
+               },
+       }
+};
+
 /**
  * to_imx334() - imv334 V4L2 sub-device to imx334 device.
  * @subdev: pointer to imx334 V4L2 sub-device
@@ -512,10 +596,6 @@ static int imx334_update_controls(struct imx334 *imx334,
 {
        int ret;
 
-       ret = __v4l2_ctrl_s_ctrl(imx334->link_freq_ctrl, mode->link_freq_idx);
-       if (ret)
-               return ret;
-
        ret = __v4l2_ctrl_modify_range(imx334->pclk_ctrl, mode->pclk,
                                       mode->pclk, 1, mode->pclk);
        if (ret)
@@ -746,6 +826,7 @@ static int imx334_set_pad_format(struct v4l2_subdev *sd,
 {
        struct imx334 *imx334 = to_imx334(sd);
        const struct imx334_mode *mode;
+       const struct imx334_clk_params *clk_params;
        int ret = 0;
 
        mode = v4l2_find_nearest_size(supported_modes,
@@ -753,6 +834,11 @@ static int imx334_set_pad_format(struct v4l2_subdev *sd,
                                      width, height,
                                      fmt->format.width, fmt->format.height);
 
+       clk_params = &imx334_clk_params[imx334->link_freq_ctrl->val];
+       if (mode->width > clk_params->width_max || mode->height > 
clk_params->height_max ||
+           mode->width < clk_params->width_min || mode->height < 
clk_params->height_min)
+               mode = clk_params->default_mode;
+
        imx334_fill_pad_format(imx334, mode, fmt);
        fmt->format.code = imx334_get_format_code(imx334, fmt->format.code);
 
@@ -824,6 +910,15 @@ static int imx334_enable_streams(struct v4l2_subdev *sd,
                goto err_rpm_put;
        }
 
+       /* Write sensor link freq registers */
+       reg_list = &imx334_clk_params[imx334->link_freq_ctrl->val].reg_list;
+       ret = cci_multi_reg_write(imx334->cci, reg_list->regs,
+                                 reg_list->num_of_regs, NULL);
+       if (ret) {
+               dev_err(imx334->dev, "fail to write initial registers\n");
+               goto err_rpm_put;
+       }
+
        /* Write sensor mode registers */
        reg_list = &imx334->cur_mode->reg_list;
        ret = cci_multi_reg_write(imx334->cci, reg_list->regs,
@@ -1096,9 +1191,6 @@ static int imx334_init_controls(struct imx334 *imx334)
                                                        
__ffs(imx334->link_freq_bitmap),
                                                        link_freq);
 
-       if (imx334->link_freq_ctrl)
-               imx334->link_freq_ctrl->flags |= V4L2_CTRL_FLAG_READ_ONLY;
-
        imx334->hblank_ctrl = v4l2_ctrl_new_std(ctrl_hdlr,
                                                &imx334_ctrl_ops,
                                                V4L2_CID_HBLANK,
_______________________________________________
linuxtv-commits mailing list -- [email protected]
To unsubscribe send an email to [email protected]

Reply via email to