diff --git a/drivers/media/i2c/tc358743.c b/drivers/media/i2c/tc358743.c index 8ca6d67a2b3e18160af314e13ff9eb6e7f54ce72..46ea2d034580a29365ffa9b230605f49c86983fd 100644 --- a/drivers/media/i2c/tc358743.c +++ b/drivers/media/i2c/tc358743.c @@ -1609,11 +1609,20 @@ static int tc358743_get_mbus_config(struct v4l2_subdev *sd, struct v4l2_mbus_config *cfg) { struct tc358743_state *state = to_state(sd); + const u32 mask = V4L2_MBUS_CSI2_LANE_MASK; + + if (state->csi_lanes_in_use > state->bus.num_data_lanes) + return -EINVAL; cfg->type = V4L2_MBUS_CSI2_DPHY; + cfg->flags = (state->csi_lanes_in_use << __ffs(mask)) & mask; + + /* In DT mode, only report the number of active lanes */ + if (sd->dev->of_node) + return 0; - /* Support for non-continuous CSI-2 clock is missing in the driver */ - cfg->flags = V4L2_MBUS_CSI2_CONTINUOUS_CLOCK; + /* Support for non-continuous CSI-2 clock is missing in pdate mode */ + cfg->flags |= V4L2_MBUS_CSI2_CONTINUOUS_CLOCK; switch (state->csi_lanes_in_use) { case 1: @@ -2055,6 +2064,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) diff --git a/include/media/v4l2-mediabus.h b/include/media/v4l2-mediabus.h index c20e2dc6d4320d821f4dc19d37afee524bd82610..396fb88266be04f7d5db20a3b8c4c7cc61853175 100644 --- a/include/media/v4l2-mediabus.h +++ b/include/media/v4l2-mediabus.h @@ -92,6 +92,14 @@ V4L2_MBUS_CSI2_CHANNEL_1 | \ V4L2_MBUS_CSI2_CHANNEL_2 | \ V4L2_MBUS_CSI2_CHANNEL_3) +/* + * Number of lanes in use, 0 == use all available lanes (default) + * + * This is a temporary fix for devices that need to reduce the number of active + * lanes for certain modes, until g_mbus_config() can be replaced with a better + * solution. + */ +#define V4L2_MBUS_CSI2_LANE_MASK (0xf << 10) /** * enum v4l2_mbus_type - media bus type