The LT9211 LVDS TX output driver current (RG_MLTX_HSDRV_ISEL) was previously hardcoded to 0x8 (~25 uA), which may not be optimal for all board layouts.
The hardware supports 16 discrete current levels starting at 12.5 uA with a step of 1.5625 uA. These are exposed as rounded integer microamp values in the lookup table. Add support for the 'drive-strength-microamp' DT property. A lookup table maps the sixteen supported microamp values (12..36 uA) to the corresponding register field. Defaults to 25 uA when the property is absent, preserving the existing behaviour. Signed-off-by: Boerge Struempfel <[email protected]> --- drivers/gpu/drm/bridge/lontium-lt9211.c | 28 ++++++++++++++++++++++++- 1 file changed, 27 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/drm/bridge/lontium-lt9211.c b/drivers/gpu/drm/bridge/lontium-lt9211.c index 03fc8fd10f20..402c639ac515 100644 --- a/drivers/gpu/drm/bridge/lontium-lt9211.c +++ b/drivers/gpu/drm/bridge/lontium-lt9211.c @@ -40,6 +40,11 @@ /* DSI lane count - 0 means 4 lanes ; 1, 2, 3 means 1, 2, 3 lanes. */ #define REG_DSI_LANE_COUNT(n) ((n) & 3) +/* Maps register value (index) to drive-strength-microamp DT property value */ +static const u32 lt9211_hsdrv_microamp[] = { + 12, 14, 16, 17, 19, 20, 22, 23, 25, 27, 28, 30, 31, 33, 34, 36 +}; + struct lt9211 { struct drm_bridge bridge; struct device *dev; @@ -50,6 +55,7 @@ struct lt9211 { struct regulator *vccio; bool lvds_dual_link; bool lvds_dual_link_even_odd_swap; + u8 lvds_hsdrv_isel; }; static const struct regmap_range lt9211_rw_ranges[] = { @@ -374,7 +380,8 @@ static int lt9211_configure_tx(struct lt9211 *ctx, bool jeida, /* BIT(7) is LVDS dual-port */ { 0x823b, 0x38 | (ctx->lvds_dual_link ? BIT(7) : 0) }, { 0x823e, 0x92 }, - { 0x823f, 0x48 }, + /* bits 3:0: RG_MLTX_HSDRV_ISEL, LVDS TX driver current */ + { 0x823f, 0x40 | ctx->lvds_hsdrv_isel }, { 0x8240, 0x31 }, { 0x8243, 0x80 }, { 0x8244, 0x00 }, @@ -629,7 +636,9 @@ static int lt9211_parse_dt(struct lt9211 *ctx) struct device *dev = ctx->dev; struct drm_panel *panel; int dual_link; + u32 microamp; int ret; + int i; ctx->vccio = devm_regulator_get(dev, "vccio"); if (IS_ERR(ctx->vccio)) @@ -666,6 +675,23 @@ static int lt9211_parse_dt(struct lt9211 *ctx) ctx->panel_bridge = panel_bridge; + ctx->lvds_hsdrv_isel = 8; /* default: 25 uA */ + ret = of_property_read_u32(dev->of_node, "drive-strength-microamp", + µamp); + if (!ret) { + for (i = 0; i < ARRAY_SIZE(lt9211_hsdrv_microamp); i++) { + if (lt9211_hsdrv_microamp[i] == microamp) { + ctx->lvds_hsdrv_isel = i; + break; + } + } + if (i == ARRAY_SIZE(lt9211_hsdrv_microamp)) { + dev_err(dev, "Invalid drive-strength-microamp value %u\n", + microamp); + return -EINVAL; + } + } + return 0; } -- 2.54.0
