diff options
author | Sakari Ailus <sakari.ailus@linux.intel.com> | 2018-07-18 16:33:45 +0300 |
---|---|---|
committer | Mauro Carvalho Chehab <mchehab+samsung@kernel.org> | 2018-10-04 23:11:10 +0300 |
commit | 276565ed7e48453e16ff6b95774bd70843ec4eb1 (patch) | |
tree | 2906534b968e40320029c06b0211b040471fa60e /drivers/media/v4l2-core | |
parent | 175b18b82df8d1f475d6fc55fd0d2d4787824b08 (diff) | |
download | linux-276565ed7e48453e16ff6b95774bd70843ec4eb1.tar.xz |
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')
-rw-r--r-- | drivers/media/v4l2-core/v4l2-fwnode.c | 65 |
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; |