[PATCH 4/4] drm/bridge: lontium-lt9611c: Add DSI port selection via DT property

From: Mohit Dsor

Date: Wed Jun 10 2026 - 17:18:05 EST


Some board designs connect only DSI port B, or both DSI ports A and B,
to the LT9611C. Add support for a 'lontium,port-select' DT property that
allows the board DTS to specify which DSI port(s) the chip should use:

0 = PORT_SELECT_A (default, single DSI port A)
1 = PORT_SELECT_B (single DSI port B)
2 = PORT_SELECT_AB (dual DSI ports A+B)

When the property is absent the driver defaults to PORT_SELECT_A (0),
preserving backward compatibility with existing DTS files.

The selected port is programmed into the chip via lt9611c_select_port()
during probe, after the chip ID has been verified.

Signed-off-by: Mohit Dsor <mohit.dsor@xxxxxxxxxxxxxxxx>
---
drivers/gpu/drm/bridge/lontium-lt9611c.c | 44 ++++++++++++++++++++++++++++++++
1 file changed, 44 insertions(+)

diff --git a/drivers/gpu/drm/bridge/lontium-lt9611c.c b/drivers/gpu/drm/bridge/lontium-lt9611c.c
index fe51f4978546..5d67bb7391fb 100644
--- a/drivers/gpu/drm/bridge/lontium-lt9611c.c
+++ b/drivers/gpu/drm/bridge/lontium-lt9611c.c
@@ -41,6 +41,12 @@ enum lt9611_chip_type {
CHIP_LT9611UXD,
};

+enum lt9611c_PORT_SELECT {
+ PORT_SELECT_A = 0,
+ PORT_SELECT_B = 1,
+ PORT_SELECT_AB = 2,
+};
+
struct lt9611c {
struct device *dev;
struct i2c_client *client;
@@ -60,6 +66,8 @@ struct lt9611c {
enum lt9611_chip_type chip_type;
/* HDMI cable connection status */
bool hdmi_connected;
+ /* Selected DSI port configuration */
+ int selected_port;
};

DECLARE_CRC8_TABLE(lt9611c_crc8_table);
@@ -115,6 +123,34 @@ static int lt9611c_read_write_flow(struct lt9611c *lt9611c, u8 *params,
return_count);
}

+static int lt9611c_select_port(struct lt9611c *lt9611c, int port_select)
+{
+ int ret;
+ u8 set_port_select_cmd[6] = {0x57, 0x4d, 0x31, 0x3a, 0x01, 0xc0};
+ u8 set_port_select_ret[5];
+
+ if (port_select == PORT_SELECT_B) {
+ set_port_select_cmd[5] = 0x40;
+ } else if (port_select == PORT_SELECT_AB) {
+ set_port_select_cmd[4] = 0x02;
+ set_port_select_cmd[5] = 0xd0;
+ } else if (port_select != PORT_SELECT_A) {
+ return -EINVAL;
+ }
+
+ /* MCU must be running (0xe0ee=0x00) for lt9611c_read_write_flow */
+ guard(mutex)(&lt9611c->ocm_lock);
+
+ ret = lt9611c_read_write_flow(lt9611c, set_port_select_cmd,
+ ARRAY_SIZE(set_port_select_cmd),
+ set_port_select_ret,
+ ARRAY_SIZE(set_port_select_ret));
+ if (ret < 0 || set_port_select_ret[4] == 0)
+ return ret < 0 ? ret : -EIO;
+
+ return 0;
+}
+
static void lt9611c_config_parameters(struct lt9611c *lt9611c)
{
const struct reg_sequence seq_write_paras[] = {
@@ -924,6 +960,10 @@ static int lt9611c_parse_dt(struct device *dev,

lt9611c->dsi1_node = of_graph_get_remote_node(dev->of_node, 1, -1);

+ if (of_property_read_u32(dev->of_node, "lontium,port-select",
+ &lt9611c->selected_port))
+ lt9611c->selected_port = 0;
+
return drm_of_find_panel_or_bridge(dev->of_node, 2, -1, NULL, &lt9611c->bridge.next_bridge);
}

@@ -1070,6 +1110,10 @@ static int lt9611c_probe(struct i2c_client *client)

lt9611c_reset(lt9611c);

+ ret = lt9611c_select_port(lt9611c, lt9611c->selected_port);
+ if (ret < 0)
+ dev_err(lt9611c->dev, "failed to select port %d\n", lt9611c->selected_port);
+
lt9611c_lock(lt9611c);

ret = lt9611c_read_chipid(lt9611c);

--
2.34.1