25
25
#include <media/v4l2-cci.h>
26
26
#include <media/v4l2-common.h>
27
27
#include <media/v4l2-ctrls.h>
28
+ #include <media/v4l2-fwnode.h>
28
29
#include <media/v4l2-subdev.h>
29
30
30
31
#define OV2680_CHIP_ID 0x2680
@@ -1008,6 +1009,9 @@ static int ov2680_check_id(struct ov2680_dev *sensor)
1008
1009
1009
1010
static int ov2680_parse_dt (struct ov2680_dev * sensor )
1010
1011
{
1012
+ struct v4l2_fwnode_endpoint bus_cfg = {
1013
+ .bus_type = V4L2_MBUS_CSI2_DPHY ,
1014
+ };
1011
1015
struct device * dev = sensor -> dev ;
1012
1016
struct fwnode_handle * ep_fwnode ;
1013
1017
struct gpio_desc * gpio ;
@@ -1023,7 +1027,10 @@ static int ov2680_parse_dt(struct ov2680_dev *sensor)
1023
1027
return dev_err_probe (dev , - EPROBE_DEFER ,
1024
1028
"waiting for fwnode graph endpoint\n" );
1025
1029
1030
+ ret = v4l2_fwnode_endpoint_alloc_parse (ep_fwnode , & bus_cfg );
1026
1031
fwnode_handle_put (ep_fwnode );
1032
+ if (ret )
1033
+ return ret ;
1027
1034
1028
1035
/*
1029
1036
* The pin we want is named XSHUTDN in the datasheet. Linux sensor
@@ -1038,15 +1045,16 @@ static int ov2680_parse_dt(struct ov2680_dev *sensor)
1038
1045
ret = PTR_ERR_OR_ZERO (gpio );
1039
1046
if (ret < 0 ) {
1040
1047
dev_dbg (dev , "error while getting reset gpio: %d\n" , ret );
1041
- return ret ;
1048
+ goto out_free_bus_cfg ;
1042
1049
}
1043
1050
1044
1051
sensor -> pwdn_gpio = gpio ;
1045
1052
1046
1053
sensor -> xvclk = devm_clk_get_optional (dev , "xvclk" );
1047
1054
if (IS_ERR (sensor -> xvclk )) {
1048
- dev_err (dev , "xvclk clock missing or invalid\n" );
1049
- return PTR_ERR (sensor -> xvclk );
1055
+ ret = dev_err_probe (dev , PTR_ERR (sensor -> xvclk ),
1056
+ "xvclk clock missing or invalid\n" );
1057
+ goto out_free_bus_cfg ;
1050
1058
}
1051
1059
1052
1060
/*
@@ -1060,14 +1068,17 @@ static int ov2680_parse_dt(struct ov2680_dev *sensor)
1060
1068
*/
1061
1069
ret = fwnode_property_read_u32 (dev_fwnode (dev ), "clock-frequency" ,
1062
1070
& rate );
1063
- if (ret && !sensor -> xvclk )
1064
- return dev_err_probe (dev , ret , "invalid clock config\n" );
1071
+ if (ret && !sensor -> xvclk ) {
1072
+ dev_err_probe (dev , ret , "invalid clock config\n" );
1073
+ goto out_free_bus_cfg ;
1074
+ }
1065
1075
1066
1076
if (!ret && sensor -> xvclk ) {
1067
1077
ret = clk_set_rate (sensor -> xvclk , rate );
1068
- if (ret )
1069
- return dev_err_probe (dev , ret ,
1070
- "failed to set clock rate\n" );
1078
+ if (ret ) {
1079
+ dev_err_probe (dev , ret , "failed to set clock rate\n" );
1080
+ goto out_free_bus_cfg ;
1081
+ }
1071
1082
}
1072
1083
1073
1084
sensor -> xvclk_freq = rate ?: clk_get_rate (sensor -> xvclk );
@@ -1077,10 +1088,12 @@ static int ov2680_parse_dt(struct ov2680_dev *sensor)
1077
1088
break ;
1078
1089
}
1079
1090
1080
- if (i == ARRAY_SIZE (ov2680_xvclk_freqs ))
1081
- return dev_err_probe (dev , - EINVAL ,
1082
- "unsupported xvclk frequency %d Hz\n" ,
1083
- sensor -> xvclk_freq );
1091
+ if (i == ARRAY_SIZE (ov2680_xvclk_freqs )) {
1092
+ ret = dev_err_probe (dev , - EINVAL ,
1093
+ "unsupported xvclk frequency %d Hz\n" ,
1094
+ sensor -> xvclk_freq );
1095
+ goto out_free_bus_cfg ;
1096
+ }
1084
1097
1085
1098
sensor -> pll_mult = ov2680_pll_multipliers [i ];
1086
1099
@@ -1091,7 +1104,28 @@ static int ov2680_parse_dt(struct ov2680_dev *sensor)
1091
1104
sensor -> pixel_rate = sensor -> link_freq [0 ] * 2 ;
1092
1105
do_div (sensor -> pixel_rate , 10 );
1093
1106
1094
- return 0 ;
1107
+ /* Verify bus cfg */
1108
+ if (bus_cfg .bus .mipi_csi2 .num_data_lanes != 1 ) {
1109
+ ret = dev_err_probe (dev , - EINVAL ,
1110
+ "only a 1-lane CSI2 config is supported" );
1111
+ goto out_free_bus_cfg ;
1112
+ }
1113
+
1114
+ for (i = 0 ; i < bus_cfg .nr_of_link_frequencies ; i ++ )
1115
+ if (bus_cfg .link_frequencies [i ] == sensor -> link_freq [0 ])
1116
+ break ;
1117
+
1118
+ if (bus_cfg .nr_of_link_frequencies == 0 ||
1119
+ bus_cfg .nr_of_link_frequencies == i ) {
1120
+ ret = dev_err_probe (dev , - EINVAL ,
1121
+ "supported link freq %lld not found\n" ,
1122
+ sensor -> link_freq [0 ]);
1123
+ goto out_free_bus_cfg ;
1124
+ }
1125
+
1126
+ out_free_bus_cfg :
1127
+ v4l2_fwnode_endpoint_free (& bus_cfg );
1128
+ return ret ;
1095
1129
}
1096
1130
1097
1131
static int ov2680_probe (struct i2c_client * client )
0 commit comments