2626#define IMX415_PIXEL_ARRAY_WIDTH 3864
2727#define IMX415_PIXEL_ARRAY_HEIGHT 2192
2828#define IMX415_PIXEL_ARRAY_VBLANK 58
29+ #define IMX415_EXPOSURE_OFFSET 8
2930
3031#define IMX415_NUM_CLK_PARAM_REGS 11
3132
5152#define IMX415_OUTSEL CCI_REG8(0x30c0)
5253#define IMX415_DRV CCI_REG8(0x30c1)
5354#define IMX415_VMAX CCI_REG24_LE(0x3024)
55+ #define IMX415_VMAX_MAX 0xfffff
5456#define IMX415_HMAX CCI_REG16_LE(0x3028)
5557#define IMX415_SHR0 CCI_REG24_LE(0x3050)
5658#define IMX415_GAIN_PCG_0 CCI_REG16_LE(0x3090)
@@ -447,7 +449,6 @@ static const struct imx415_clk_params imx415_clk_params[] = {
447449
448450/* all-pixel 2-lane 720 Mbps 15.74 Hz mode */
449451static const struct cci_reg_sequence imx415_mode_2_720 [] = {
450- { IMX415_VMAX , 0x08CA },
451452 { IMX415_HMAX , 0x07F0 },
452453 { IMX415_LANEMODE , IMX415_LANEMODE_2 },
453454 { IMX415_TCLKPOST , 0x006F },
@@ -463,7 +464,6 @@ static const struct cci_reg_sequence imx415_mode_2_720[] = {
463464
464465/* all-pixel 2-lane 1440 Mbps 30.01 Hz mode */
465466static const struct cci_reg_sequence imx415_mode_2_1440 [] = {
466- { IMX415_VMAX , 0x08CA },
467467 { IMX415_HMAX , 0x042A },
468468 { IMX415_LANEMODE , IMX415_LANEMODE_2 },
469469 { IMX415_TCLKPOST , 0x009F },
@@ -479,7 +479,6 @@ static const struct cci_reg_sequence imx415_mode_2_1440[] = {
479479
480480/* all-pixel 4-lane 891 Mbps 30 Hz mode */
481481static const struct cci_reg_sequence imx415_mode_4_891 [] = {
482- { IMX415_VMAX , 0x08CA },
483482 { IMX415_HMAX , 0x044C },
484483 { IMX415_LANEMODE , IMX415_LANEMODE_4 },
485484 { IMX415_TCLKPOST , 0x007F },
@@ -600,6 +599,7 @@ struct imx415 {
600599 struct v4l2_ctrl * vblank ;
601600 struct v4l2_ctrl * hflip ;
602601 struct v4l2_ctrl * vflip ;
602+ struct v4l2_ctrl * exposure ;
603603
604604 unsigned int cur_mode ;
605605 unsigned int num_data_lanes ;
@@ -730,17 +730,37 @@ static int imx415_s_ctrl(struct v4l2_ctrl *ctrl)
730730 ctrls );
731731 const struct v4l2_mbus_framefmt * format ;
732732 struct v4l2_subdev_state * state ;
733+ u32 exposure_max ;
733734 unsigned int vmax ;
734735 unsigned int flip ;
735736 int ret ;
736737
737- if (!pm_runtime_get_if_in_use (sensor -> dev ))
738- return 0 ;
739-
740738 state = v4l2_subdev_get_locked_active_state (& sensor -> subdev );
741739 format = v4l2_subdev_state_get_format (state , 0 );
742740
741+ if (ctrl -> id == V4L2_CID_VBLANK ) {
742+ exposure_max = format -> height + ctrl -> val -
743+ IMX415_EXPOSURE_OFFSET ;
744+ __v4l2_ctrl_modify_range (sensor -> exposure ,
745+ sensor -> exposure -> minimum ,
746+ exposure_max , sensor -> exposure -> step ,
747+ sensor -> exposure -> default_value );
748+ }
749+
750+ if (!pm_runtime_get_if_in_use (sensor -> dev ))
751+ return 0 ;
752+
743753 switch (ctrl -> id ) {
754+ case V4L2_CID_VBLANK :
755+ ret = cci_write (sensor -> regmap , IMX415_VMAX ,
756+ format -> height + ctrl -> val , NULL );
757+ if (ret )
758+ return ret ;
759+ /*
760+ * Deliberately fall through as exposure is set based on VMAX
761+ * which has just changed.
762+ */
763+ fallthrough ;
744764 case V4L2_CID_EXPOSURE :
745765 /* clamp the exposure value to VMAX. */
746766 vmax = format -> height + sensor -> vblank -> cur .val ;
@@ -787,7 +807,8 @@ static int imx415_ctrls_init(struct imx415 *sensor)
787807 u64 pixel_rate = supported_modes [sensor -> cur_mode ].pixel_rate ;
788808 u64 lane_rate = supported_modes [sensor -> cur_mode ].lane_rate ;
789809 u32 exposure_max = IMX415_PIXEL_ARRAY_HEIGHT +
790- IMX415_PIXEL_ARRAY_VBLANK - 8 ;
810+ IMX415_PIXEL_ARRAY_VBLANK -
811+ IMX415_EXPOSURE_OFFSET ;
791812 u32 hblank ;
792813 unsigned int i ;
793814 int ret ;
@@ -816,8 +837,9 @@ static int imx415_ctrls_init(struct imx415 *sensor)
816837 if (ctrl )
817838 ctrl -> flags |= V4L2_CTRL_FLAG_READ_ONLY ;
818839
819- v4l2_ctrl_new_std (& sensor -> ctrls , & imx415_ctrl_ops , V4L2_CID_EXPOSURE ,
820- 4 , exposure_max , 1 , exposure_max );
840+ sensor -> exposure = v4l2_ctrl_new_std (& sensor -> ctrls , & imx415_ctrl_ops ,
841+ V4L2_CID_EXPOSURE , 4 ,
842+ exposure_max , 1 , exposure_max );
821843
822844 v4l2_ctrl_new_std (& sensor -> ctrls , & imx415_ctrl_ops ,
823845 V4L2_CID_ANALOGUE_GAIN , IMX415_AGAIN_MIN ,
@@ -834,16 +856,9 @@ static int imx415_ctrls_init(struct imx415 *sensor)
834856 sensor -> vblank = v4l2_ctrl_new_std (& sensor -> ctrls , & imx415_ctrl_ops ,
835857 V4L2_CID_VBLANK ,
836858 IMX415_PIXEL_ARRAY_VBLANK ,
837- IMX415_PIXEL_ARRAY_VBLANK , 1 ,
838- IMX415_PIXEL_ARRAY_VBLANK );
839- if (sensor -> vblank )
840- sensor -> vblank -> flags |= V4L2_CTRL_FLAG_READ_ONLY ;
859+ IMX415_VMAX_MAX - IMX415_PIXEL_ARRAY_HEIGHT ,
860+ 1 , IMX415_PIXEL_ARRAY_VBLANK );
841861
842- /*
843- * The pixel rate used here is a virtual value and can be used for
844- * calculating the frame rate together with hblank. It may not
845- * necessarily be the physically correct pixel clock.
846- */
847862 v4l2_ctrl_new_std (& sensor -> ctrls , NULL , V4L2_CID_PIXEL_RATE , pixel_rate ,
848863 pixel_rate , 1 , pixel_rate );
849864
0 commit comments