@@ -419,6 +419,17 @@ struct ds5_sensor {
419419 const struct ds5_format * formats ;
420420 unsigned int n_formats ;
421421 int pipe_id ;
422+ int last_pipe_id ;
423+ u16 pipe_data_type1 ;
424+ u16 pipe_data_type2 ;
425+ u32 pipe_vc_id ;
426+ bool pipe_configured ;
427+ u16 cached_dt_value ;
428+ u16 cached_md_value ;
429+ u16 cached_override_value ;
430+ u16 cached_fps_value ;
431+ u16 cached_width_value ;
432+ u16 cached_height_value ;
422433};
423434
424435#ifdef CONFIG_TEGRA_CAMERA_PLATFORM
@@ -536,6 +547,8 @@ static int ds5_write(struct ds5 *state, u16 reg, u16 val)
536547{
537548 int ret ;
538549 u8 value [2 ];
550+ int retry ;
551+ int delay_ms = 10 ;
539552
540553 value [1 ] = val >> 8 ;
541554 value [0 ] = val & 0x00FF ;
@@ -544,7 +557,28 @@ static int ds5_write(struct ds5 *state, u16 reg, u16 val)
544557 "%s(): writing to register: 0x%04x, value1: 0x%x, value2:0x%x\n" ,
545558 __func__ , reg , value [1 ], value [0 ]);
546559
547- ret = regmap_raw_write (state -> regmap , reg , value , sizeof (value ));
560+ for (retry = 0 ; retry < 3 ; retry ++ ) {
561+ ret = regmap_raw_write (state -> regmap , reg , value , sizeof (value ));
562+ if (ret == 0 )
563+ break ;
564+
565+ /* Retry only on timeout/remote IO errors */
566+ if (ret != - ETIMEDOUT && ret != - EREMOTEIO ) {
567+ dev_err (& state -> client -> dev ,
568+ "%s(): i2c write failed %d, 0x%04x = 0x%x\n" ,
569+ __func__ , ret , reg , val );
570+ return ret ;
571+ }
572+
573+ if (retry < 2 ) {
574+ dev_dbg (& state -> client -> dev ,
575+ "%s(): retry %d after %dms delay, 0x%04x\n" ,
576+ __func__ , retry + 1 , delay_ms , reg );
577+ msleep (delay_ms );
578+ delay_ms *= 2 ;
579+ }
580+ }
581+
548582 if (ret < 0 )
549583 dev_err (& state -> client -> dev ,
550584 "%s(): i2c write failed %d, 0x%04x = 0x%x\n" ,
@@ -560,7 +594,32 @@ static int ds5_write(struct ds5 *state, u16 reg, u16 val)
560594static int ds5_raw_write (struct ds5 * state , u16 reg ,
561595 const void * val , size_t val_len )
562596{
563- int ret = regmap_raw_write (state -> regmap , reg , val , val_len );
597+ int ret ;
598+ int retry ;
599+ int delay_ms = 10 ;
600+
601+ for (retry = 0 ; retry < 3 ; retry ++ ) {
602+ ret = regmap_raw_write (state -> regmap , reg , val , val_len );
603+ if (ret == 0 )
604+ break ;
605+
606+ /* Retry only on timeout/remote IO errors */
607+ if (ret != - ETIMEDOUT && ret != - EREMOTEIO ) {
608+ dev_err (& state -> client -> dev ,
609+ "%s(): i2c raw write failed %d, %04x size(%d) bytes\n" ,
610+ __func__ , ret , reg , (int )val_len );
611+ return ret ;
612+ }
613+
614+ if (retry < 2 ) {
615+ dev_dbg (& state -> client -> dev ,
616+ "%s(): retry %d after %dms delay, 0x%04x\n" ,
617+ __func__ , retry + 1 , delay_ms , reg );
618+ msleep (delay_ms );
619+ delay_ms *= 2 ;
620+ }
621+ }
622+
564623 if (ret < 0 )
565624 dev_err (& state -> client -> dev ,
566625 "%s(): i2c raw write failed %d, %04x size(%d) bytes\n" ,
@@ -576,7 +635,31 @@ static int ds5_raw_write(struct ds5 *state, u16 reg,
576635
577636static int ds5_read (struct ds5 * state , u16 reg , u16 * val )
578637{
579- int ret = regmap_raw_read (state -> regmap , reg , val , 2 );
638+ int ret ;
639+ int retry ;
640+ int delay_ms = 10 ;
641+
642+ for (retry = 0 ; retry < 3 ; retry ++ ) {
643+ ret = regmap_raw_read (state -> regmap , reg , val , 2 );
644+ if (ret == 0 )
645+ break ;
646+
647+ /* Retry only on timeout/remote IO errors */
648+ if (ret != - ETIMEDOUT && ret != - EREMOTEIO ) {
649+ dev_err (& state -> client -> dev , "%s(): i2c read failed %d, 0x%04x\n" ,
650+ __func__ , ret , reg );
651+ return ret ;
652+ }
653+
654+ if (retry < 2 ) {
655+ dev_dbg (& state -> client -> dev ,
656+ "%s(): retry %d after %dms delay, 0x%04x\n" ,
657+ __func__ , retry + 1 , delay_ms , reg );
658+ msleep (delay_ms );
659+ delay_ms *= 2 ;
660+ }
661+ }
662+
580663 if (ret < 0 )
581664 dev_err (& state -> client -> dev , "%s(): i2c read failed %d, 0x%04x\n" ,
582665 __func__ , ret , reg );
@@ -1827,6 +1910,11 @@ static int ds5_configure(struct ds5 *state)
18271910 u16 data_type1 , data_type2 ;
18281911#endif
18291912 u16 dt_addr , md_addr , override_addr , fps_addr , width_addr , height_addr ;
1913+ u16 dt_value = 0 ;
1914+ u16 md_value = 0 ;
1915+ u16 fps_value = 0 ;
1916+ u16 width_value = 0 ;
1917+ u16 height_value = 0 ;
18301918 int ret ;
18311919
18321920 if (state -> is_depth ) {
@@ -1878,14 +1966,31 @@ static int ds5_configure(struct ds5 *state)
18781966 data_type2 = state -> is_imu ? 0x00 : md_fmt ;
18791967
18801968 vc_id = state -> g_ctx .dst_vc ;
1881-
1882- ret = ds5_setup_pipeline (state , data_type1 , data_type2 , sensor -> pipe_id ,
1883- vc_id );
1884- // reset data path when switching to Y12I
1885- if (state -> is_y8 && data_type1 == GMSL_CSI_DT_RGB_888 )
1886- max9296_reset_oneshot (state -> dser_dev );
1887- if (ret < 0 )
1888- return ret ;
1969+ if (!sensor -> pipe_configured ||
1970+ sensor -> pipe_id != sensor -> last_pipe_id ||
1971+ sensor -> pipe_data_type1 != data_type1 ||
1972+ sensor -> pipe_data_type2 != data_type2 ||
1973+ sensor -> pipe_vc_id != vc_id ) {
1974+ ret = ds5_setup_pipeline (state , data_type1 , data_type2 ,
1975+ sensor -> pipe_id , vc_id );
1976+ // reset data path when switching to Y12I
1977+ if (state -> is_y8 && data_type1 == GMSL_CSI_DT_RGB_888 )
1978+ max9296_reset_oneshot (state -> dser_dev );
1979+ if (ret < 0 )
1980+ return ret ;
1981+ sensor -> pipe_configured = true;
1982+ sensor -> last_pipe_id = sensor -> pipe_id ;
1983+ sensor -> pipe_data_type1 = data_type1 ;
1984+ sensor -> pipe_data_type2 = data_type2 ;
1985+ sensor -> pipe_vc_id = vc_id ;
1986+ dev_warn (& state -> client -> dev ,
1987+ "pipe %d configured (dt1=0x%x dt2=0x%x vc=%u)\n" ,
1988+ sensor -> pipe_id , data_type1 , data_type2 , vc_id );
1989+ } else {
1990+ dev_warn (& state -> client -> dev ,
1991+ "pipe %d already configured (dt1=0x%x dt2=0x%x vc=%u)\n" ,
1992+ sensor -> pipe_id , data_type1 , data_type2 , vc_id );
1993+ }
18891994#endif
18901995
18911996 fmt = sensor -> streaming ? sensor -> config .format -> data_type : 0 ;
@@ -1895,55 +2000,72 @@ static int ds5_configure(struct ds5 *state)
18952000 * Set IR stream Y8I data type as 0x32
18962001 */
18972002 if (state -> is_depth && fmt != 0 )
1898- ret = ds5_write ( state , dt_addr , 0x31 ) ;
2003+ dt_value = 0x31 ;
18992004 else if (state -> is_y8 && fmt != 0 &&
19002005 sensor -> config .format -> data_type == GMSL_CSI_DT_YUV422_8 ) {
1901- if (sensor -> config .format -> mbus_code == MEDIA_BUS_FMT_VYUY8_1X16 )
1902- {
1903- /* This is the custom Y8I format -
1904- * telling FW to enable "etMipiDataType_UserDefined3_R8L8"
1905- */
1906- ret = ds5_write (state , dt_addr , GMSL_CSI_DT_CUSTOM_Y8I_16 );
2006+ if (sensor -> config .format -> mbus_code == MEDIA_BUS_FMT_VYUY8_1X16 ) {
2007+ dt_value = GMSL_CSI_DT_CUSTOM_Y8I_16 ;
19072008 } else if (sensor -> config .format -> mbus_code == MEDIA_BUS_FMT_YUYV8_1X16 ) {
1908- /* This is the custom RGB through IR format -
1909- * telling FW to enable "etMipiDataType_UserDefined0_IR_RGB"
1910- */
1911- ret = ds5_write (state , dt_addr , GMSL_CSI_DT_CUSTOM_IR_RGB_16 );
2009+ dt_value = GMSL_CSI_DT_CUSTOM_IR_RGB_16 ;
19122010 } else {
19132011 dev_err (sensor -> sd .dev , "%s(): Illegal mbus_code %u for IR sensor\n" ,
19142012 __func__ , sensor -> config .format -> mbus_code );
19152013 return - EINVAL ;
19162014 }
19172015 } else {
1918- ret = ds5_write ( state , dt_addr , fmt ) ;
2016+ dt_value = fmt ;
19192017 }
1920- if (ret < 0 )
1921- return ret ;
19222018
1923- ret = ds5_write (state , md_addr , (vc_id << 8 ) | md_fmt );
1924- if (ret < 0 )
1925- return ret ;
2019+ if (sensor -> cached_dt_value != dt_value ) {
2020+ ret = ds5_write (state , dt_addr , dt_value );
2021+ if (ret < 0 )
2022+ return ret ;
2023+ sensor -> cached_dt_value = dt_value ;
2024+ }
2025+
2026+ md_value = (vc_id << 8 ) | md_fmt ;
2027+ if (sensor -> cached_md_value != md_value ) {
2028+ ret = ds5_write (state , md_addr , md_value );
2029+ if (ret < 0 )
2030+ return ret ;
2031+ sensor -> cached_md_value = md_value ;
2032+ }
19262033
19272034 if (!sensor -> streaming )
19282035 return ret ;
19292036
19302037 if (override_addr != 0 ) {
1931- ret = ds5_write (state , override_addr , fmt );
2038+ if (sensor -> cached_override_value != fmt ) {
2039+ ret = ds5_write (state , override_addr , fmt );
2040+ if (ret < 0 )
2041+ return ret ;
2042+ sensor -> cached_override_value = fmt ;
2043+ }
2044+ }
2045+
2046+ fps_value = sensor -> config .framerate ;
2047+ if (sensor -> cached_fps_value != fps_value ) {
2048+ ret = ds5_write (state , fps_addr , fps_value );
19322049 if (ret < 0 )
19332050 return ret ;
2051+ sensor -> cached_fps_value = fps_value ;
19342052 }
19352053
1936- ret = ds5_write ( state , fps_addr , sensor -> config .framerate ) ;
1937- if (ret < 0 )
1938- return ret ;
1939-
1940- ret = ds5_write ( state , width_addr , sensor -> config . resolution -> width ) ;
1941- if ( ret < 0 )
1942- return ret ;
2054+ width_value = sensor -> config .resolution -> width ;
2055+ if (sensor -> cached_width_value != width_value ) {
2056+ ret = ds5_write ( state , width_addr , width_value ) ;
2057+ if ( ret < 0 )
2058+ return ret ;
2059+ sensor -> cached_width_value = width_value ;
2060+ }
19432061
1944- ret = ds5_write (state , height_addr , sensor -> config .resolution -> height );
1945- if (ret < 0 )
1946- return ret ;
2062+ height_value = sensor -> config .resolution -> height ;
2063+ if (sensor -> cached_height_value != height_value ) {
2064+ ret = ds5_write (state , height_addr , height_value );
2065+ if (ret < 0 )
2066+ return ret ;
2067+ sensor -> cached_height_value = height_value ;
2068+ }
19472069
19482070 return 0 ;
19492071}
@@ -4751,6 +4873,8 @@ static int ds5_mux_s_stream(struct v4l2_subdev *sd, int on)
47514873 ret = - (ENOSR );
47524874 goto restore_s_state ;
47534875 }
4876+ sensor -> pipe_configured = false;
4877+ sensor -> last_pipe_id = sensor -> pipe_id ;
47544878#endif
47554879
47564880 ret = ds5_configure (state );
@@ -4815,6 +4939,8 @@ static int ds5_mux_s_stream(struct v4l2_subdev *sd, int on)
48154939 if (max9296_release_pipe (state -> dser_dev , sensor -> pipe_id ) < 0 )
48164940 dev_warn (& state -> client -> dev , "release pipe failed\n" );
48174941 sensor -> pipe_id = -1 ;
4942+ sensor -> last_pipe_id = -1 ;
4943+ sensor -> pipe_configured = false;
48184944#else
48194945#ifdef CONFIG_VIDEO_INTEL_IPU6
48204946 d4xx_reset_oneshot (state );
@@ -4839,6 +4965,8 @@ static int ds5_mux_s_stream(struct v4l2_subdev *sd, int on)
48394965 if (max9296_release_pipe (state -> dser_dev , sensor -> pipe_id ) < 0 )
48404966 dev_warn (& state -> client -> dev , "release pipe failed\n" );
48414967 sensor -> pipe_id = -1 ;
4968+ sensor -> last_pipe_id = -1 ;
4969+ sensor -> pipe_configured = false;
48424970 }
48434971#endif
48444972
0 commit comments