189189/* Initial number of frames to skip to avoid possible garbage */
190190#define ADV7180_NUM_OF_SKIP_FRAMES 2
191191
192+ enum adv7180_link_freq_idx {
193+ INTERLACED_IDX ,
194+ I2P_IDX ,
195+ };
196+
197+ static const s64 adv7180_link_freqs [] = {
198+ [INTERLACED_IDX ] = 108000000 ,
199+ [I2P_IDX ] = 216000000 ,
200+ };
201+
192202static int dbg_input ;
193203module_param (dbg_input , int , 0644 );
194204MODULE_PARM_DESC (dbg_input , "Input number (0-31)" );
@@ -229,6 +239,7 @@ struct adv7180_state {
229239 const struct adv7180_chip_info * chip_info ;
230240 enum v4l2_field field ;
231241 bool force_bt656_4 ;
242+ struct v4l2_ctrl * link_freq ;
232243};
233244#define to_adv7180_sd (_ctrl ) (&container_of(_ctrl->handler, \
234245 struct adv7180_state, \
@@ -625,6 +636,9 @@ static int adv7180_s_ctrl(struct v4l2_ctrl *ctrl)
625636
626637 if (ret )
627638 return ret ;
639+ if (ctrl -> flags & V4L2_CTRL_FLAG_READ_ONLY )
640+ goto unlock ;
641+
628642 val = ctrl -> val ;
629643 switch (ctrl -> id ) {
630644 case V4L2_CID_BRIGHTNESS :
@@ -666,6 +680,7 @@ static int adv7180_s_ctrl(struct v4l2_ctrl *ctrl)
666680 ret = - EINVAL ;
667681 }
668682
683+ unlock :
669684 mutex_unlock (& state -> mutex );
670685 return ret ;
671686}
@@ -686,7 +701,7 @@ static const struct v4l2_ctrl_config adv7180_ctrl_fast_switch = {
686701
687702static int adv7180_init_controls (struct adv7180_state * state )
688703{
689- v4l2_ctrl_handler_init (& state -> ctrl_hdl , 4 );
704+ v4l2_ctrl_handler_init (& state -> ctrl_hdl , 5 );
690705
691706 v4l2_ctrl_new_std (& state -> ctrl_hdl , & adv7180_ctrl_ops ,
692707 V4L2_CID_BRIGHTNESS , ADV7180_BRI_MIN ,
@@ -712,6 +727,17 @@ static int adv7180_init_controls(struct adv7180_state *state)
712727 test_pattern_menu );
713728 }
714729
730+ if (state -> chip_info -> flags & ADV7180_FLAG_MIPI_CSI2 ) {
731+ state -> link_freq =
732+ v4l2_ctrl_new_int_menu (& state -> ctrl_hdl ,
733+ & adv7180_ctrl_ops ,
734+ V4L2_CID_LINK_FREQ ,
735+ ARRAY_SIZE (adv7180_link_freqs ) - 1 ,
736+ 0 , adv7180_link_freqs );
737+ if (state -> link_freq )
738+ state -> link_freq -> flags |= V4L2_CTRL_FLAG_READ_ONLY ;
739+ }
740+
715741 state -> sd .ctrl_handler = & state -> ctrl_hdl ;
716742 if (state -> ctrl_hdl .error ) {
717743 int err = state -> ctrl_hdl .error ;
@@ -839,7 +865,16 @@ static int adv7180_set_pad_format(struct v4l2_subdev *sd,
839865 ret = adv7180_mbus_fmt (sd , & format -> format );
840866
841867 if (format -> which == V4L2_SUBDEV_FORMAT_ACTIVE ) {
842- state -> field = format -> format .field ;
868+ if (state -> field != format -> format .field ) {
869+ state -> field = format -> format .field ;
870+ adv7180_set_power (state , false);
871+ adv7180_set_field_mode (state );
872+ adv7180_set_power (state , true);
873+ if (state -> chip_info -> flags & ADV7180_FLAG_MIPI_CSI2 )
874+ __v4l2_ctrl_s_ctrl (state -> link_freq ,
875+ (state -> field == V4L2_FIELD_NONE ) ?
876+ I2P_IDX : INTERLACED_IDX );
877+ }
843878 } else {
844879 framefmt = v4l2_subdev_state_get_format (sd_state , 0 );
845880 * framefmt = format -> format ;
0 commit comments