[PATCH 4/4] drm/panel: himax-hx83102: Add support for DSI DCS backlight control
From: Val Packett
Date: Tue Feb 17 2026 - 02:02:51 EST
The HTF065H045 panel based on the HX83102 controller does use DCS
commands for controlling backlight brightness. Make the driver fall back
to DCS when no external backlight has been defined in the device tree,
like many other drivers do.
Signed-off-by: Val Packett <val@xxxxxxxxxxxx>
---
drivers/gpu/drm/panel/panel-himax-hx83102.c | 65 +++++++++++++++++++++
1 file changed, 65 insertions(+)
diff --git a/drivers/gpu/drm/panel/panel-himax-hx83102.c b/drivers/gpu/drm/panel/panel-himax-hx83102.c
index 34e0e956db48..8b2a68ee851e 100644
--- a/drivers/gpu/drm/panel/panel-himax-hx83102.c
+++ b/drivers/gpu/drm/panel/panel-himax-hx83102.c
@@ -7,6 +7,7 @@
* Based on drivers/gpu/drm/panel/panel-himax-hx8394.c
*/
+#include <linux/backlight.h>
#include <linux/delay.h>
#include <linux/gpio/consumer.h>
#include <linux/module.h>
@@ -76,6 +77,8 @@ struct hx83102_panel_desc {
unsigned int height_mm;
} size;
+ bool has_backlight;
+
int (*init)(struct hx83102 *ctx);
};
@@ -913,6 +916,7 @@ static const struct hx83102_panel_desc holitech_htf065h045_desc = {
.width_mm = 68,
.height_mm = 151,
},
+ .has_backlight = true,
.init = holitech_htf065h045_init,
};
@@ -1049,6 +1053,59 @@ static const struct drm_panel_funcs hx83102_drm_funcs = {
.get_orientation = hx83102_get_orientation,
};
+static int hx83102_bl_update_status(struct backlight_device *bl)
+{
+ struct mipi_dsi_device *dsi = bl_get_data(bl);
+ u16 brightness = backlight_get_brightness(bl);
+ int ret;
+
+ dsi->mode_flags &= ~MIPI_DSI_MODE_LPM;
+
+ ret = mipi_dsi_dcs_set_display_brightness_large(dsi, brightness);
+ if (ret < 0)
+ return ret;
+
+ dsi->mode_flags |= MIPI_DSI_MODE_LPM;
+
+ return 0;
+}
+
+static int hx83102_bl_get_brightness(struct backlight_device *bl)
+{
+ struct mipi_dsi_device *dsi = bl_get_data(bl);
+ u16 brightness;
+ int ret;
+
+ dsi->mode_flags &= ~MIPI_DSI_MODE_LPM;
+
+ ret = mipi_dsi_dcs_get_display_brightness_large(dsi, &brightness);
+ if (ret < 0)
+ return ret;
+
+ dsi->mode_flags |= MIPI_DSI_MODE_LPM;
+
+ return brightness;
+}
+
+static const struct backlight_ops hx83102_bl_ops = {
+ .update_status = hx83102_bl_update_status,
+ .get_brightness = hx83102_bl_get_brightness,
+};
+
+static struct backlight_device *
+hx83102_create_dcs_backlight(struct mipi_dsi_device *dsi)
+{
+ struct device *dev = &dsi->dev;
+ const struct backlight_properties props = {
+ .type = BACKLIGHT_RAW,
+ .brightness = 4095,
+ .max_brightness = 4095,
+ };
+
+ return devm_backlight_device_register(dev, dev_name(dev), dev, dsi,
+ &hx83102_bl_ops, &props);
+}
+
static int hx83102_panel_add(struct hx83102 *ctx)
{
struct device *dev = &ctx->dsi->dev;
@@ -1080,6 +1137,14 @@ static int hx83102_panel_add(struct hx83102 *ctx)
if (err)
return err;
+ /* Use DSI-based backlight as fallback if available */
+ if (ctx->desc->has_backlight && !ctx->base.backlight) {
+ ctx->base.backlight = hx83102_create_dcs_backlight(ctx->dsi);
+ if (IS_ERR(ctx->base.backlight))
+ return dev_err_probe(dev, PTR_ERR(ctx->base.backlight),
+ "Failed to create backlight\n");
+ }
+
ctx->base.funcs = &hx83102_drm_funcs;
ctx->base.dev = &ctx->dsi->dev;
--
2.52.0