summaryrefslogtreecommitdiff
path: root/drivers/media/v4l2-core/v4l2-fwnode.c
diff options
context:
space:
mode:
authorSakari Ailus <sakari.ailus@linux.intel.com>2018-07-18 09:33:45 -0400
committerMauro Carvalho Chehab <mchehab+samsung@kernel.org>2018-10-04 16:11:10 -0400
commit276565ed7e48453e16ff6b95774bd70843ec4eb1 (patch)
tree2906534b968e40320029c06b0211b040471fa60e /drivers/media/v4l2-core/v4l2-fwnode.c
parent175b18b82df8d1f475d6fc55fd0d2d4787824b08 (diff)
media: v4l: fwnode: Read lane inversion information despite lane numbering
Read the lane inversion independently of whether the "data-lanes" property exists. This makes sense since the caller may pass the number of lanes as the default configuration while the lane inversion configuration may still be available in firmware. Signed-off-by: Sakari Ailus <sakari.ailus@linux.intel.com> Tested-by: Steve Longerbeam <steve_longerbeam@mentor.com> Tested-by: Jacopo Mondi <jacopo+renesas@jmondi.org> Signed-off-by: Mauro Carvalho Chehab <mchehab+samsung@kernel.org>
Diffstat (limited to 'drivers/media/v4l2-core/v4l2-fwnode.c')
-rw-r--r--drivers/media/v4l2-core/v4l2-fwnode.c65
1 files changed, 35 insertions, 30 deletions
diff --git a/drivers/media/v4l2-core/v4l2-fwnode.c b/drivers/media/v4l2-core/v4l2-fwnode.c
index 2d0d2facf20f..d6d78230cdf8 100644
--- a/drivers/media/v4l2-core/v4l2-fwnode.c
+++ b/drivers/media/v4l2-core/v4l2-fwnode.c
@@ -43,26 +43,31 @@ enum v4l2_fwnode_bus_type {
};
static int v4l2_fwnode_endpoint_parse_csi2_bus(struct fwnode_handle *fwnode,
- struct v4l2_fwnode_endpoint *vep)
+ struct v4l2_fwnode_endpoint *vep,
+ enum v4l2_fwnode_bus_type bus_type)
{
struct v4l2_fwnode_bus_mipi_csi2 *bus = &vep->bus.mipi_csi2;
bool have_clk_lane = false;
unsigned int flags = 0, lanes_used = 0;
+ u32 array[1 + V4L2_FWNODE_CSI2_MAX_DATA_LANES];
+ unsigned int num_data_lanes = 0;
unsigned int i;
u32 v;
int rval;
+ if (bus_type == V4L2_FWNODE_BUS_TYPE_CSI2_DPHY)
+ num_data_lanes = min_t(u32, bus->num_data_lanes,
+ V4L2_FWNODE_CSI2_MAX_DATA_LANES);
+
rval = fwnode_property_read_u32_array(fwnode, "data-lanes", NULL, 0);
if (rval > 0) {
- u32 array[1 + V4L2_FWNODE_CSI2_MAX_DATA_LANES];
-
- bus->num_data_lanes =
+ num_data_lanes =
min_t(int, V4L2_FWNODE_CSI2_MAX_DATA_LANES, rval);
fwnode_property_read_u32_array(fwnode, "data-lanes", array,
- bus->num_data_lanes);
+ num_data_lanes);
- for (i = 0; i < bus->num_data_lanes; i++) {
+ for (i = 0; i < num_data_lanes; i++) {
if (lanes_used & BIT(array[i]))
pr_warn("duplicated lane %u in data-lanes\n",
array[i]);
@@ -71,30 +76,27 @@ static int v4l2_fwnode_endpoint_parse_csi2_bus(struct fwnode_handle *fwnode,
bus->data_lanes[i] = array[i];
pr_debug("lane %u position %u\n", i, array[i]);
}
+ }
- rval = fwnode_property_read_u32_array(fwnode,
- "lane-polarities", NULL,
- 0);
- if (rval > 0) {
- if (rval != 1 + bus->num_data_lanes /* clock+data */) {
- pr_warn("invalid number of lane-polarities entries (need %u, got %u)\n",
- 1 + bus->num_data_lanes, rval);
- return -EINVAL;
- }
+ rval = fwnode_property_read_u32_array(fwnode, "lane-polarities", NULL,
+ 0);
+ if (rval > 0) {
+ if (rval != 1 + num_data_lanes /* clock+data */) {
+ pr_warn("invalid number of lane-polarities entries (need %u, got %u)\n",
+ 1 + num_data_lanes, rval);
+ return -EINVAL;
+ }
- fwnode_property_read_u32_array(fwnode,
- "lane-polarities", array,
- 1 + bus->num_data_lanes);
+ fwnode_property_read_u32_array(fwnode, "lane-polarities", array,
+ 1 + num_data_lanes);
- for (i = 0; i < 1 + bus->num_data_lanes; i++) {
- bus->lane_polarities[i] = array[i];
- pr_debug("lane %u polarity %sinverted",
- i, array[i] ? "" : "not ");
- }
- } else {
- pr_debug("no lane polarities defined, assuming not inverted\n");
+ for (i = 0; i < 1 + num_data_lanes; i++) {
+ bus->lane_polarities[i] = array[i];
+ pr_debug("lane %u polarity %sinverted",
+ i, array[i] ? "" : "not ");
}
-
+ } else {
+ pr_debug("no lane polarities defined, assuming not inverted\n");
}
if (!fwnode_property_read_u32(fwnode, "clock-lanes", &v)) {
@@ -114,10 +116,11 @@ static int v4l2_fwnode_endpoint_parse_csi2_bus(struct fwnode_handle *fwnode,
flags |= V4L2_MBUS_CSI2_CONTINUOUS_CLOCK;
}
- if (lanes_used || have_clk_lane ||
- (flags & ~V4L2_MBUS_CSI2_CONTINUOUS_CLOCK)) {
+ if (bus_type == V4L2_FWNODE_BUS_TYPE_CSI2_DPHY || lanes_used ||
+ have_clk_lane || (flags & ~V4L2_MBUS_CSI2_CONTINUOUS_CLOCK)) {
bus->flags = flags;
vep->bus_type = V4L2_MBUS_CSI2_DPHY;
+ bus->num_data_lanes = num_data_lanes;
}
return 0;
@@ -268,7 +271,8 @@ static int __v4l2_fwnode_endpoint_parse(struct fwnode_handle *fwnode,
switch (bus_type) {
case V4L2_FWNODE_BUS_TYPE_GUESS:
- rval = v4l2_fwnode_endpoint_parse_csi2_bus(fwnode, vep);
+ rval = v4l2_fwnode_endpoint_parse_csi2_bus(fwnode, vep,
+ bus_type);
if (rval)
return rval;
@@ -284,7 +288,8 @@ static int __v4l2_fwnode_endpoint_parse(struct fwnode_handle *fwnode,
break;
case V4L2_FWNODE_BUS_TYPE_CSI2_DPHY:
vep->bus_type = V4L2_MBUS_CSI2_DPHY;
- rval = v4l2_fwnode_endpoint_parse_csi2_bus(fwnode, vep);
+ rval = v4l2_fwnode_endpoint_parse_csi2_bus(fwnode, vep,
+ bus_type);
if (rval)
return rval;