Use the TXA routing information to configure the number of active CSI-2 data lanes. When routing AFE through TXA limit the number of data lanes to 1, while in the canonical HDMI->TXA routing use all the physically available ones. The number of lanes collected from the 'data-lanes' DT property is now used as a the number of physically available data lanes, while the 'num_lanes' variable contains the number of active ones. Signed-off-by: Jacopo Mondi <jacopo+renesas@xxxxxxxxxx> --- drivers/media/i2c/adv748x/adv748x-core.c | 19 ++++++++++++++++++- drivers/media/i2c/adv748x/adv748x.h | 1 + 2 files changed, 19 insertions(+), 1 deletion(-) diff --git a/drivers/media/i2c/adv748x/adv748x-core.c b/drivers/media/i2c/adv748x/adv748x-core.c index 02135741b1a6..f91c7b83f1bf 100644 --- a/drivers/media/i2c/adv748x/adv748x-core.c +++ b/drivers/media/i2c/adv748x/adv748x-core.c @@ -350,6 +350,8 @@ static int adv748x_link_setup(struct media_entity *entity, struct adv748x_csi2 *tx = adv748x_sd_to_csi2(sd); bool enable = flags & MEDIA_LNK_FL_ENABLED; u8 csi4_in_sel = 0; + u8 num_lanes; + int ret; /* Refuse to enable multiple links to the same TX at the same time. */ if (enable && tx->src) @@ -373,10 +375,23 @@ static int adv748x_link_setup(struct media_entity *entity, csi4_in_sel |= ADV748X_IO_10_CSI4_IN_SEL_AFE; else csi4_in_sel |= ADV748X_IO_10_CSI1_EN; + + num_lanes = 1; } - if (state->hdmi.tx) + if (state->hdmi.tx) { csi4_in_sel |= ADV748X_IO_10_CSI4_EN; + num_lanes = tx->available_lanes; + } + + /* Update the number of active lanes if it has changed. */ + if (num_lanes != tx->num_lanes) { + tx->num_lanes = num_lanes; + ret = adv748x_write(state, tx->page, 0x00, + 0x80 | tx->num_lanes); + if (ret) + return ret; + } state->csi4_in_sel = csi4_in_sel; @@ -608,6 +623,7 @@ static int adv748x_parse_csi2_lanes(struct adv748x_state *state, } state->txa.num_lanes = num_lanes; + state->txa.available_lanes = num_lanes; adv_dbg(state, "TXA: using %u lanes\n", state->txa.num_lanes); } @@ -619,6 +635,7 @@ static int adv748x_parse_csi2_lanes(struct adv748x_state *state, } state->txb.num_lanes = num_lanes; + state->txb.available_lanes = num_lanes; adv_dbg(state, "TXB: using %u lanes\n", state->txb.num_lanes); } diff --git a/drivers/media/i2c/adv748x/adv748x.h b/drivers/media/i2c/adv748x/adv748x.h index 27c116d09284..6e5c2cb421fe 100644 --- a/drivers/media/i2c/adv748x/adv748x.h +++ b/drivers/media/i2c/adv748x/adv748x.h @@ -80,6 +80,7 @@ struct adv748x_csi2 { unsigned int page; unsigned int port; unsigned int num_lanes; + unsigned int available_lanes; struct media_pad pads[ADV748X_CSI2_NR_PADS]; struct v4l2_ctrl_handler ctrl_hdl; -- 2.21.0