Skip to content

Commit 63b0cd3

Browse files
jwrdegoedemchehab
authored andcommitted
media: ov2680: Add bus-cfg / endpoint property verification
Verify that the number of CSI lanes and link-frequency specified in the endpoint fwnode are correct. Signed-off-by: Hans de Goede <[email protected]> Signed-off-by: Sakari Ailus <[email protected]> Signed-off-by: Mauro Carvalho Chehab <[email protected]>
1 parent 34f9eff commit 63b0cd3

File tree

1 file changed

+47
-13
lines changed

1 file changed

+47
-13
lines changed

drivers/media/i2c/ov2680.c

Lines changed: 47 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@
2525
#include <media/v4l2-cci.h>
2626
#include <media/v4l2-common.h>
2727
#include <media/v4l2-ctrls.h>
28+
#include <media/v4l2-fwnode.h>
2829
#include <media/v4l2-subdev.h>
2930

3031
#define OV2680_CHIP_ID 0x2680
@@ -1008,6 +1009,9 @@ static int ov2680_check_id(struct ov2680_dev *sensor)
10081009

10091010
static int ov2680_parse_dt(struct ov2680_dev *sensor)
10101011
{
1012+
struct v4l2_fwnode_endpoint bus_cfg = {
1013+
.bus_type = V4L2_MBUS_CSI2_DPHY,
1014+
};
10111015
struct device *dev = sensor->dev;
10121016
struct fwnode_handle *ep_fwnode;
10131017
struct gpio_desc *gpio;
@@ -1023,7 +1027,10 @@ static int ov2680_parse_dt(struct ov2680_dev *sensor)
10231027
return dev_err_probe(dev, -EPROBE_DEFER,
10241028
"waiting for fwnode graph endpoint\n");
10251029

1030+
ret = v4l2_fwnode_endpoint_alloc_parse(ep_fwnode, &bus_cfg);
10261031
fwnode_handle_put(ep_fwnode);
1032+
if (ret)
1033+
return ret;
10271034

10281035
/*
10291036
* 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)
10381045
ret = PTR_ERR_OR_ZERO(gpio);
10391046
if (ret < 0) {
10401047
dev_dbg(dev, "error while getting reset gpio: %d\n", ret);
1041-
return ret;
1048+
goto out_free_bus_cfg;
10421049
}
10431050

10441051
sensor->pwdn_gpio = gpio;
10451052

10461053
sensor->xvclk = devm_clk_get_optional(dev, "xvclk");
10471054
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;
10501058
}
10511059

10521060
/*
@@ -1060,14 +1068,17 @@ static int ov2680_parse_dt(struct ov2680_dev *sensor)
10601068
*/
10611069
ret = fwnode_property_read_u32(dev_fwnode(dev), "clock-frequency",
10621070
&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+
}
10651075

10661076
if (!ret && sensor->xvclk) {
10671077
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+
}
10711082
}
10721083

10731084
sensor->xvclk_freq = rate ?: clk_get_rate(sensor->xvclk);
@@ -1077,10 +1088,12 @@ static int ov2680_parse_dt(struct ov2680_dev *sensor)
10771088
break;
10781089
}
10791090

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+
}
10841097

10851098
sensor->pll_mult = ov2680_pll_multipliers[i];
10861099

@@ -1091,7 +1104,28 @@ static int ov2680_parse_dt(struct ov2680_dev *sensor)
10911104
sensor->pixel_rate = sensor->link_freq[0] * 2;
10921105
do_div(sensor->pixel_rate, 10);
10931106

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;
10951129
}
10961130

10971131
static int ov2680_probe(struct i2c_client *client)

0 commit comments

Comments
 (0)