6565#define OV9282_REG_MIPI_CTRL00 0x4800
6666#define OV9282_GATED_CLOCK BIT(5)
6767
68+ /* Trigger mode registers */
69+ #define OV9282_REG_POWER_CTRL 0x4F00
70+ #define OV9282_REG_LOW_POWER_MODE_CTRL 0x3030
71+ #define OV9282_REG_NUM_FRAME_ON_TRIG 0x303F
72+ #define OV9282_REG_SLEEP_PERIOD_CTRL0 0x302C
73+ #define OV9282_REG_SLEEP_PERIOD_CTRL3 0x302F
74+ #define OV9282_REG_TIMING_23 0x3823
75+
6876/* Input clock rate */
6977#define OV9282_INCLK_RATE 24000000
7078
@@ -187,6 +195,7 @@ struct ov9282 {
187195 const struct ov9282_mode * cur_mode ;
188196 u32 code ;
189197 struct mutex mutex ;
198+ int trigger_mode ;
190199};
191200
192201static const s64 link_freq [] = {
@@ -947,6 +956,56 @@ static int ov9282_get_selection(struct v4l2_subdev *sd,
947956 return - EINVAL ;
948957}
949958
959+ /**
960+ * ov9282_apply_trigger_config() - Configure sensor for FSIN external trigger mode
961+ * @ov9282: pointer to ov9282 device
962+ *
963+ * Return: 0 on success, error code otherwise.
964+ */
965+ static int ov9282_apply_trigger_config (struct ov9282 * ov9282 )
966+ {
967+ int ret ;
968+
969+ ret = ov9282_write_reg (ov9282 , OV9282_REG_MODE_SELECT , 1 , OV9282_MODE_STANDBY );
970+ if (ret )
971+ return ret ;
972+
973+ /* Low power mode */
974+ ret = ov9282_write_reg (ov9282 , OV9282_REG_POWER_CTRL , 1 , 0x01 );
975+ if (ret )
976+ return ret ;
977+
978+ /* External trigger snapshot */
979+ ret = ov9282_write_reg (ov9282 , OV9282_REG_LOW_POWER_MODE_CTRL , 1 , 0x04 );
980+ if (ret )
981+ return ret ;
982+
983+ /* 1 frame per trigger */
984+ ret = ov9282_write_reg (ov9282 , OV9282_REG_NUM_FRAME_ON_TRIG , 1 , 0x01 );
985+ if (ret )
986+ return ret ;
987+
988+ ret = ov9282_write_reg (ov9282 , OV9282_REG_SLEEP_PERIOD_CTRL0 , 1 , 0x00 );
989+ if (ret )
990+ return ret ;
991+
992+ ret = ov9282_write_reg (ov9282 , OV9282_REG_SLEEP_PERIOD_CTRL3 , 1 , 0x7F );
993+ if (ret )
994+ return ret ;
995+
996+ /* No auto wake */
997+ ret = ov9282_write_reg (ov9282 , OV9282_REG_TIMING_23 , 1 , 0x00 );
998+ if (ret )
999+ return ret ;
1000+
1001+ /* stay standby mode and wait for trigger signal */
1002+ ret = ov9282_write_reg (ov9282 , OV9282_REG_MODE_SELECT , 1 , OV9282_MODE_STANDBY );
1003+ if (ret )
1004+ return ret ;
1005+
1006+ return 0 ;
1007+ }
1008+
9501009/**
9511010 * ov9282_start_streaming() - Start sensor stream
9521011 * @ov9282: pointer to ov9282 device
@@ -964,13 +1023,12 @@ static int ov9282_start_streaming(struct ov9282 *ov9282)
9641023 {OV9282_REG_ANA_CORE_2 , OV9282_ANA_CORE2_RAW8 },
9651024 }
9661025 };
967- const struct ov9282_reg_list * reg_list ;
1026+ struct ov9282_reg_list * reg_list ;
9681027 int bitdepth_index ;
9691028 int ret ;
9701029
9711030 /* Write common registers */
972- ret = ov9282_write_regs (ov9282 , common_regs_list .regs ,
973- common_regs_list .num_of_regs );
1031+ ret = ov9282_write_regs (ov9282 , common_regs_list .regs , common_regs_list .num_of_regs );
9741032 if (ret ) {
9751033 dev_err (ov9282 -> dev , "fail to write common registers" );
9761034 return ret ;
@@ -992,15 +1050,24 @@ static int ov9282_start_streaming(struct ov9282 *ov9282)
9921050 }
9931051
9941052 /* Setup handler will write actual exposure and gain */
995- ret = __v4l2_ctrl_handler_setup (ov9282 -> sd .ctrl_handler );
1053+ ret = __v4l2_ctrl_handler_setup (ov9282 -> sd .ctrl_handler );
9961054 if (ret ) {
9971055 dev_err (ov9282 -> dev , "fail to setup handler" );
9981056 return ret ;
9991057 }
10001058
1059+ /* Configure FSIN external trigger mode */
1060+ if (ov9282 -> trigger_mode > 0 ) {
1061+ ret = ov9282_apply_trigger_config (ov9282 );
1062+ if (ret ) {
1063+ dev_err (ov9282 -> dev , "failed to config external trigger mode" );
1064+ return ret ;
1065+ }
1066+ return 0 ;
1067+ }
1068+
10011069 /* Start streaming */
1002- ret = ov9282_write_reg (ov9282 , OV9282_REG_MODE_SELECT ,
1003- 1 , OV9282_MODE_STREAMING );
1070+ ret = ov9282_write_reg (ov9282 , OV9282_REG_MODE_SELECT , 1 , OV9282_MODE_STREAMING );
10041071 if (ret ) {
10051072 dev_err (ov9282 -> dev , "fail to start streaming" );
10061073 return ret ;
@@ -1392,6 +1459,7 @@ static int ov9282_probe(struct i2c_client *client)
13921459{
13931460 struct ov9282 * ov9282 ;
13941461 int ret ;
1462+ u32 trig_mod ;
13951463
13961464 ov9282 = devm_kzalloc (& client -> dev , sizeof (* ov9282 ), GFP_KERNEL );
13971465 if (!ov9282 )
@@ -1431,6 +1499,9 @@ static int ov9282_probe(struct i2c_client *client)
14311499 ov9282 -> code = MEDIA_BUS_FMT_Y10_1X10 ;
14321500 ov9282 -> vblank = ov9282 -> cur_mode -> vblank ;
14331501
1502+ ret = of_property_read_u32 (client -> dev .of_node , "trigger-mode" , & trig_mod );
1503+ ov9282 -> trigger_mode = (ret == 0 ) ? trig_mod : -1 ;
1504+
14341505 ret = ov9282_init_controls (ov9282 );
14351506 if (ret ) {
14361507 dev_err (ov9282 -> dev , "failed to init controls: %d" , ret );
0 commit comments