1-
21// SPDX-License-Identifier: GPL-2.0
32/*
43 * ds5.c - Intel(R) RealSense(TM) D4XX camera driver
@@ -470,6 +469,14 @@ enum {
470469struct v4l2_mbus_framefmt ds5_ffmts [NR_OF_DS5_PADS ];
471470#endif
472471
472+ #ifdef CONFIG_VIDEO_D4XX_SERDES
473+ struct serdes_state {
474+ bool isolated ;
475+ int bus_nr ;
476+ int addr ;
477+ };
478+ #endif
479+
473480struct ds5 {
474481 struct { struct ds5_sensor sensor ; } depth ;
475482 struct { struct ds5_sensor sensor ; } ir ;
@@ -500,6 +507,7 @@ struct ds5 {
500507 struct device * dser_dev ;
501508 struct i2c_client * ser_i2c ;
502509 struct i2c_client * dser_i2c ;
510+ struct serdes_state dser_st ;
503511#endif
504512#ifdef CONFIG_VIDEO_INTEL_IPU6
505513#define NR_OF_CSI2_BE_SOC_STREAMS 16
@@ -3152,6 +3160,7 @@ static int ds5_board_setup(struct ds5 *state)
31523160 int err = 0 ;
31533161 int i ;
31543162 char suffix = pdata -> suffix ;
3163+
31553164 static struct max9295_pdata max9295_pdata = {
31563165 .is_prim_ser = 1 , // todo: configurable
31573166 .def_addr = 0x40 , // todo: configurable
@@ -3174,16 +3183,27 @@ static int ds5_board_setup(struct ds5 *state)
31743183
31753184 i2c_info_des .addr = pdata -> subdev_info [0 ].board_info .addr ; //0x48, 0x4a, 0x68, 0x6a
31763185
3186+ state -> dser_st .bus_nr = bus ;
3187+ state -> dser_st .addr = i2c_info_des .addr ;
3188+
31773189 /* look for already registered max9296, use same context if found */
31783190 for (i = 0 ; i < MAX_DEV_NUM ; i ++ ) {
3179- if (serdes_inited [i ] && serdes_inited [i ]-> dser_i2c ) {
3180- dev_info (dev , "MAX9296 found device on %d@0x%x\n" ,
3181- serdes_inited [i ]-> dser_i2c -> adapter -> nr , serdes_inited [i ]-> dser_i2c -> addr );
3182- if (bus == serdes_inited [i ]-> dser_i2c -> adapter -> nr
3183- && serdes_inited [i ]-> dser_i2c -> addr == i2c_info_des .addr ) {
3191+ if (serdes_inited [i ]) {
3192+ if ( serdes_inited [i ]-> dser_st .isolated
3193+ && bus == serdes_inited [i ]-> dser_st .bus_nr
3194+ && serdes_inited [i ]-> dser_st .addr == i2c_info_des .addr ) {
3195+
3196+ dev_info (dev , "Isolate unresponsive sensor/serializer AGGREGATED on MAX9296 device 0x%x\n" ,
3197+ i2c_info_des .addr );
3198+ state -> aggregated = 1 ;
3199+ break ;
3200+ } else if ( serdes_inited [i ]-> dser_i2c
3201+ && bus == serdes_inited [i ]-> dser_i2c -> adapter -> nr
3202+ && serdes_inited [i ]-> dser_i2c -> addr == i2c_info_des .addr ) {
31843203 dev_info (dev , "MAX9296 AGGREGATION found device on 0x%x\n" , i2c_info_des .addr );
31853204 state -> dser_i2c = serdes_inited [i ]-> dser_i2c ;
31863205 state -> aggregated = 1 ;
3206+ break ;
31873207 }
31883208 }
31893209 }
@@ -3296,6 +3316,7 @@ static int ds5_gmsl_serdes_setup(struct ds5 *state)
32963316{
32973317 int err = 0 ;
32983318 int des_err = 0 ;
3319+ int ser_err = 0 ;
32993320 struct device * dev ;
33003321
33013322 if (!state || !state -> ser_dev || !state -> dser_dev || !state -> client )
@@ -3317,17 +3338,19 @@ static int ds5_gmsl_serdes_setup(struct ds5 *state)
33173338 goto error ;
33183339 }
33193340 msleep (100 );
3320- err = max9295_setup_control (state -> ser_dev );
33213341
3322- /* proceed even if ser setup failed, to setup deser correctly */
3323- if (err )
3324- dev_err (dev , "gmsl serializer setup failed\n" );
3342+ ser_err = max9295_setup_control (state -> ser_dev );
3343+ /* if ser setup failed, graceful deser setup fallback */
3344+ if (ser_err ) {
3345+ dev_warn (dev , "gmsl serializer invalid source\n" );
3346+ err = - ENOTSUPP ;
3347+ }
33253348
33263349 des_err = max9296_setup_control (state -> dser_dev , & state -> client -> dev );
33273350 if (des_err ) {
3328- dev_err (dev , "gmsl deserializer setup failed\n" );
3351+ dev_warn (dev , "gmsl deserializer setup failed\n" );
33293352 /* overwrite err only if deser setup also failed */
3330- err = des_err ;
3353+ err = ( err == - ENOTSUPP ) ? err : des_err ;
33313354 }
33323355
33333356error :
@@ -3372,7 +3395,7 @@ static int ds5_i2c_addr_setting(struct i2c_client *c, struct ds5 *state)
33723395 c -> addr = des_addr [i ];
33733396 dev_info (& c -> dev , "Set max9296@%d-0x%x Link reset\n" ,
33743397 c_bus , c -> addr );
3375- ds5_write_8 (state , 0x1000 , 0x40 ); // reset link
3398+ ds5_write_8 (state , 0x1000 , 0x40 ); // sensor reset link
33763399 }
33773400 }
33783401 // restore original slave address
@@ -3386,23 +3409,34 @@ static int ds5_serdes_setup(struct ds5 *state)
33863409 int ret = 0 ;
33873410 struct i2c_client * c = state -> client ;
33883411#ifdef CONFIG_VIDEO_INTEL_IPU6
3389- int i = 0 , c_bus = 0 ;
3412+ int i = 0 , c_bus = -1 ;
33903413 int c_bus_new = c -> adapter -> nr ;
33913414
33923415 for (i = 0 ; i < MAX_DEV_NUM ; i ++ ) {
3416+ #ifdef CONFIG_VIDEO_D4XX_SERDES
3417+ if (serdes_inited [i ] && serdes_inited [i ]-> dser_st .isolated ) {
3418+ c_bus = serdes_inited [i ]-> dser_st .bus_nr ;
3419+ if (c_bus == c -> adapter -> nr ) {
3420+ dev_info (& c -> dev , "Already configured Isolated camera for bus %d\n" , c_bus );
3421+ c_bus_new = -1 ;
3422+ break ;
3423+ }
3424+ } else if (serdes_inited [i ] && serdes_inited [i ]-> dser_i2c ) {
3425+ #else
33933426 if (serdes_inited [i ] && serdes_inited [i ]-> dser_i2c ) {
3427+ #endif
33943428 c_bus = serdes_inited [i ]-> dser_i2c -> adapter -> nr ;
33953429 if (c_bus == c -> adapter -> nr ) {
3396- dev_info (& c -> dev , "Already configured multiple camera for bus %d\n" , c_bus );
3397- c_bus_new = 0 ;
3430+ dev_info (& c -> dev , "Already configured Addressable camera for bus %d\n" , c_bus );
3431+ c_bus_new = -1 ;
33983432 break ;
33993433 }
34003434 } else {
34013435 break ;
34023436 }
34033437 }
34043438
3405- if (c_bus_new ) {
3439+ if (c_bus_new >= 0 ) {
34063440 dev_info (& c -> dev , "Apply multiple camera i2c addr setting for bus %d\n" , c_bus_new );
34073441 ret = ds5_i2c_addr_setting (c , state );
34083442 if (ret ) {
@@ -3422,7 +3456,7 @@ static int ds5_serdes_setup(struct ds5 *state)
34223456 /* Pair sensor to serializer dev */
34233457 ret = max9295_sdev_pair (state -> ser_dev , & state -> g_ctx );
34243458 if (ret ) {
3425- dev_err (& c -> dev , "gmsl ser pairing failed\n" );
3459+ dev_err (& c -> dev , "gmsl serializer pairing failed\n" );
34263460 return ret ;
34273461 }
34283462
@@ -3435,7 +3469,16 @@ static int ds5_serdes_setup(struct ds5 *state)
34353469
34363470 ret = ds5_gmsl_serdes_setup (state );
34373471 if (ret ) {
3438- dev_err (& c -> dev , "%s gmsl serdes setup failed\n" , __func__ );
3472+ if (ret == - ENOTSUPP ) {
3473+ dev_warn (& c -> dev , "graceful fallback, gmsl serdes setup\n" );
3474+ if (c_bus_new >= 0 )
3475+ dev_info (& c -> dev , "Unresponding serializer on Newly initialized bus %d\n" ,
3476+ c_bus_new );
3477+ else
3478+ dev_info (& c -> dev , "Unresponding serializer on Already initialized bus %d\n" ,
3479+ state -> dser_i2c -> adapter -> nr );
3480+ } else
3481+ dev_err (& c -> dev , "%s gmsl serdes setup failed\n" , __func__ );
34393482 return ret ;
34403483 }
34413484
@@ -5569,6 +5612,10 @@ static int ds5_probe(struct i2c_client *c)
55695612 mutex_init (& state -> lock );
55705613
55715614 state -> client = c ;
5615+
5616+ #ifdef CONFIG_VIDEO_D4XX_SERDES
5617+ state -> dser_st .isolated = false;
5618+ #endif
55725619 dev_warn (& c -> dev , "Probing driver for D45x\n" );
55735620#if LINUX_VERSION_CODE < KERNEL_VERSION (6 , 1 , 0 )
55745621 state -> variant = ds5_variants + id -> driver_data ;
@@ -5600,8 +5647,12 @@ static int ds5_probe(struct i2c_client *c)
56005647
56015648#ifdef CONFIG_VIDEO_D4XX_SERDES
56025649 ret = ds5_serdes_setup (state );
5603- if (ret < 0 )
5650+ if (ret < 0 ) {
5651+ if (ret == - ENOTSUPP )
5652+ dev_warn (& c -> dev , "max9295 communication failed : %d\n" , ret );
56045653 goto e_regulator ;
5654+
5655+ }
56055656#endif
56065657#ifdef CONFIG_VIDEO_INTEL_IPU6
56075658#endif //CONFIG_VIDEO_INTEL_IPU6
@@ -5693,14 +5744,54 @@ static int ds5_probe(struct i2c_client *c)
56935744e_chardev :
56945745 if (state -> dfu_dev .ds5_class )
56955746 ds5_chrdev_remove (state );
5747+
56965748e_regulator :
56975749 if (state -> vcc )
56985750 regulator_disable (state -> vcc );
56995751#ifdef CONFIG_VIDEO_D4XX_SERDES
5700- if (state -> ser_i2c )
5752+ int i ;
5753+ int c_bus = c -> adapter -> nr ;
5754+ bool graceful_fallback = false;
5755+ for (i = 0 ; i < MAX_DEV_NUM ; i ++ ) {
5756+ if (serdes_inited [i ]
5757+ && serdes_inited [i ] != state
5758+ && state -> dser_i2c
5759+ && c_bus == serdes_inited [i ]-> dser_st .bus_nr
5760+ && state -> dser_i2c -> addr == serdes_inited [i ]-> dser_st .addr
5761+ && serdes_inited [i ]-> dser_st .isolated ) {
5762+
5763+ dev_info (& c -> dev , "Cleanup unresponsive sensor/serializer Isolated on bus %d\n" ,
5764+ c_bus );
5765+ graceful_fallback = true;
5766+ }
5767+ }
5768+
5769+ if (!state -> g_ctx .serdev_found )
5770+ dev_warn (& c -> dev , "graceful fallback due to unresponsive max9295, isolated SerDes %s single-link\n" ,
5771+ state -> g_ctx .serdes_csi_link == GMSL_SERDES_CSI_LINK_A ? "GMSL A" : "GMSL B" );
5772+ else
5773+ dev_warn (& c -> dev , "graceful fallback due to unresponsive d4xx, isolated SerDes %s single-link\n" ,
5774+ state -> g_ctx .serdes_csi_link == GMSL_SERDES_CSI_LINK_A ? "GMSL A" : "GMSL B" );
5775+
5776+ mutex_lock (& serdes_lock__ );
5777+ if (state -> ser_i2c ) {
5778+ dev_info (& c -> dev , "remove unresponding serializer i2c device 0x%x\n" ,
5779+ state -> ser_i2c -> addr );
57015780 i2c_unregister_device (state -> ser_i2c );
5702- if (state -> dser_i2c && !state -> aggregated )
5781+ }
5782+ if (state -> dser_i2c && !state -> aggregated ) {
5783+ dev_info (& c -> dev , "remove unresponding %s single-link deserializer i2c device 0x%x\n" ,
5784+ state -> g_ctx .serdes_csi_link == GMSL_SERDES_CSI_LINK_A ? "GMSL A" : "GMSL B" ,
5785+ state -> dser_i2c -> addr );
57035786 i2c_unregister_device (state -> dser_i2c );
5787+ state -> dser_st .isolated = true;
5788+ } else if (state -> dser_i2c && graceful_fallback ) {
5789+ dev_info (& c -> dev , "remove unresponding %s single-link deserializer i2c device 0x%x\n" ,
5790+ state -> g_ctx .serdes_csi_link == GMSL_SERDES_CSI_LINK_A ? "GMSL A" : "GMSL B" ,
5791+ state -> dser_i2c -> addr );
5792+ i2c_unregister_device (state -> dser_i2c );
5793+ }
5794+ mutex_unlock (& serdes_lock__ );
57045795#endif
57055796 return ret ;
57065797}
@@ -5715,7 +5806,17 @@ static void ds5_remove(struct i2c_client *c)
57155806#ifdef CONFIG_VIDEO_D4XX_SERDES
57165807 int i , ret ;
57175808 int c_bus = c -> adapter -> nr ;
5809+ bool graceful_fallback = false;
57185810 for (i = 0 ; i < MAX_DEV_NUM ; i ++ ) {
5811+ if (serdes_inited [i ] && state -> dser_i2c
5812+ && c_bus == serdes_inited [i ]-> dser_st .bus_nr
5813+ && state -> dser_i2c -> addr == serdes_inited [i ]-> dser_st .addr
5814+ && serdes_inited [i ]-> dser_st .isolated ) {
5815+
5816+ dev_info (& c -> dev , "Cleanup unresponsive sensor/serializer Isolated on bus %d\n" ,
5817+ c_bus );
5818+ graceful_fallback = true;
5819+ }
57195820 if (serdes_inited [i ] && serdes_inited [i ] == state ) {
57205821 serdes_inited [i ] = NULL ;
57215822 mutex_lock (& serdes_lock__ );
@@ -5727,6 +5828,7 @@ static void ds5_remove(struct i2c_client *c)
57275828 if (state -> dser_i2c ) {
57285829 dev_info (& c -> dev , "ignore 9296 reset control, already remove for bus %d\n" , c_bus );
57295830 } else {
5831+ dev_info (& c -> dev , "trigger 9296 reset control on bus %d\n" , c_bus );
57305832 ret = max9296_reset_control (state -> dser_dev ,
57315833 state -> g_ctx .s_dev );
57325834 if (ret )
@@ -5741,6 +5843,7 @@ static void ds5_remove(struct i2c_client *c)
57415843 if (state -> dser_i2c ) {
57425844 dev_info (& c -> dev , "ignore 9296 unregister sdev, already remove for bus %d\n" , c_bus );
57435845 } else {
5846+ dev_info (& c -> dev , "unregister 9296 sdev on bus %d\n" , c_bus );
57445847 ret = max9296_sdev_unregister (state -> dser_dev ,
57455848 state -> g_ctx .s_dev );
57465849 if (ret )
@@ -5749,15 +5852,26 @@ static void ds5_remove(struct i2c_client *c)
57495852
57505853 max9296_power_off (state -> dser_dev );
57515854 }
5752-
57535855 mutex_unlock (& serdes_lock__ );
57545856 break ;
57555857 }
57565858 }
5757- if (state -> ser_i2c )
5859+ if (state -> ser_i2c && !state -> dser_st .isolated ) {
5860+ dev_info (& c -> dev , "remove unresponding serializer i2c device 0x%x\n" ,
5861+ state -> ser_i2c -> addr );
57585862 i2c_unregister_device (state -> ser_i2c );
5759- if (state -> dser_i2c && !state -> aggregated )
5863+ }
5864+ if (state -> dser_i2c && !state -> aggregated && !state -> dser_st .isolated ) {
57605865 i2c_unregister_device (state -> dser_i2c );
5866+ dev_info (& c -> dev , "remove unresponding %s single-link deserializer i2c device 0x%x\n" ,
5867+ state -> g_ctx .serdes_csi_link == GMSL_SERDES_CSI_LINK_A ? "GMSL A" : "GMSL B" ,
5868+ state -> dser_i2c -> addr );
5869+ } else if (state -> dser_i2c && graceful_fallback ) {
5870+ dev_info (& c -> dev , "remove unresponding %s single-link deserializer i2c device 0x%x\n" ,
5871+ state -> g_ctx .serdes_csi_link == GMSL_SERDES_CSI_LINK_A ? "GMSL A" : "GMSL B" ,
5872+ state -> dser_i2c -> addr );
5873+ i2c_unregister_device (state -> dser_i2c );
5874+ }
57615875#endif
57625876#ifndef CONFIG_TEGRA_CAMERA_PLATFORM
57635877 state -> is_depth = 1 ;
5826594058275941 Qingwu Zhang <[email protected] >,\n\ 58285942 Evgeni Raikhel <[email protected] >,\n\ 5829- Shikun Ding <[email protected] >" );
5943+ Shikun Ding <[email protected] >,\n\ 5944+ Florent Pirou <[email protected] >" );
58305945MODULE_AUTHOR (
"Dmitry Perchanov <[email protected] >" );
58315946MODULE_LICENSE ("GPL v2" );
58325947MODULE_VERSION ("1.0.1.21" );
0 commit comments