g_mbus_config was supposed to indicate all supported lane numbers, not only the number of those currently in active use. Since the TC358743 can dynamically reduce the number of active lanes if the required bandwidth allows for it, report all lane numbers up to the connected number of lanes as supported in pdata mode. In device tree mode, do not report lane count and clock mode at all, as the receiver driver can determine these from the device tree. To allow communicating the number of currently active lanes, use the newly added g_csi_active_lanes() video op. Signed-off-by: Philipp Zabel <p.zabel@xxxxxxxxxxxxxx> --- Changes since v3: - Use g_csi_active_lanes instead of storing the number of active lanes in mbus_config flags. --- drivers/media/i2c/tc358743.c | 44 ++++++++++++++++++++++++++---------- 1 file changed, 32 insertions(+), 12 deletions(-) diff --git a/drivers/media/i2c/tc358743.c b/drivers/media/i2c/tc358743.c index dbbab75f135e..c2db6419a4b4 100644 --- a/drivers/media/i2c/tc358743.c +++ b/drivers/media/i2c/tc358743.c @@ -1607,23 +1607,31 @@ static int tc358743_g_mbus_config(struct v4l2_subdev *sd, { struct tc358743_state *state = to_state(sd); + if (state->csi_lanes_in_use > state->bus.num_data_lanes) + return -EINVAL; + cfg->type = V4L2_MBUS_CSI2_DPHY; + cfg->flags = 0; - /* Support for non-continuous CSI-2 clock is missing in the driver */ - cfg->flags = V4L2_MBUS_CSI2_CONTINUOUS_CLOCK; + /* In DT mode, there is no need to report the number of data lanes */ + if (sd->dev->of_node) + return 0; - switch (state->csi_lanes_in_use) { - case 1: - cfg->flags |= V4L2_MBUS_CSI2_1_LANE; - break; - case 2: - cfg->flags |= V4L2_MBUS_CSI2_2_LANE; - break; + /* Support for non-continuous CSI-2 clock is missing in pdata mode */ + cfg->flags |= V4L2_MBUS_CSI2_CONTINUOUS_CLOCK; + + switch (state->bus.num_data_lanes) { + case 4: + cfg->flags |= V4L2_MBUS_CSI2_LANES; + /* fallthrough */ case 3: cfg->flags |= V4L2_MBUS_CSI2_3_LANE; - break; - case 4: - cfg->flags |= V4L2_MBUS_CSI2_4_LANE; + /* fallthrough */ + case 2: + cfg->flags |= V4L2_MBUS_CSI2_2_LANE; + /* fallthrough */ + case 1: + cfg->flags |= V4L2_MBUS_CSI2_1_LANE; break; default: return -EINVAL; @@ -1632,6 +1640,16 @@ static int tc358743_g_mbus_config(struct v4l2_subdev *sd, return 0; } +static int tc358743_g_csi_active_lanes(struct v4l2_subdev *sd, + u32 *lanes) +{ + struct tc358743_state *state = to_state(sd); + + *lanes = state->csi_lanes_in_use; + + return 0; +} + static int tc358743_s_stream(struct v4l2_subdev *sd, int enable) { enable_stream(sd, enable); @@ -1838,6 +1856,7 @@ static const struct v4l2_subdev_video_ops tc358743_video_ops = { .query_dv_timings = tc358743_query_dv_timings, .g_mbus_config = tc358743_g_mbus_config, .s_stream = tc358743_s_stream, + .g_csi_active_lanes = tc358743_g_csi_active_lanes, }; static const struct v4l2_subdev_pad_ops tc358743_pad_ops = { @@ -2052,6 +2071,7 @@ static int tc358743_probe(struct i2c_client *client) if (pdata) { state->pdata = *pdata; state->bus.flags = V4L2_MBUS_CSI2_CONTINUOUS_CLOCK; + state->bus.num_data_lanes = 4; } else { err = tc358743_probe_of(state); if (err == -ENODEV) -- 2.20.1