[3/5] drm/panel: nt36523: Add DCS backlight support
Commit Message
This chip supports controlling the backlight via DCS commands, on at
least some panels. Add support for doing so.
Note this may only concern the NT36523*W* variant. Nobody knows, really,
there's no docs.
Signed-off-by: Konrad Dybcio <konrad.dybcio@linaro.org>
---
drivers/gpu/drm/panel/panel-novatek-nt36523.c | 67 +++++++++++++++++++++++++--
1 file changed, 64 insertions(+), 3 deletions(-)
Comments
On Wed, Apr 12, 2023 at 09:46:00PM +0200, Konrad Dybcio wrote:
> This chip supports controlling the backlight via DCS commands, on at
> least some panels. Add support for doing so.
>
> Note this may only concern the NT36523*W* variant. Nobody knows, really,
> there's no docs.
>
> Signed-off-by: Konrad Dybcio <konrad.dybcio@linaro.org>
> ---
> drivers/gpu/drm/panel/panel-novatek-nt36523.c | 67 +++++++++++++++++++++++++--
> 1 file changed, 64 insertions(+), 3 deletions(-)
>
> diff --git a/drivers/gpu/drm/panel/panel-novatek-nt36523.c b/drivers/gpu/drm/panel/panel-novatek-nt36523.c
> index d30dbbfb67b1..3c81ec014eef 100644
> --- a/drivers/gpu/drm/panel/panel-novatek-nt36523.c
> +++ b/drivers/gpu/drm/panel/panel-novatek-nt36523.c
> @@ -5,6 +5,7 @@
> * Copyright (c) 2022, 2023 Jianhua Lu <lujianhua000@gmail.com>
> */
>
> +
[..]
> +static struct backlight_device *nt36523_create_backlight(struct mipi_dsi_device *dsi)
> +{
> + struct device *dev = &dsi->dev;
> + const struct backlight_properties props = {
> + .type = BACKLIGHT_RAW,
> + .brightness = 512,
> + .max_brightness = 4095,
Please set the missing scale property of backlight. Daniel said: "Unknown is never correct for
new drivers."
See https://lore.kernel.org/lkml/Y6SIWoVFX%2FOlNO0n@aspen.lan/
Otherwise,
Reviewed-by: Jianhua Lu <lujianhua000@gmail.com>
> + };
> +
> + return devm_backlight_device_register(dev, dev_name(dev), dev, dsi,
> + &nt36523_bl_ops, &props);
> +}
> +
> static int nt36523_probe(struct mipi_dsi_device *dsi)
> {
> struct device *dev = &dsi->dev;
> @@ -730,9 +784,16 @@ static int nt36523_probe(struct mipi_dsi_device *dsi)
> mipi_dsi_set_drvdata(dsi, pinfo);
> drm_panel_init(&pinfo->panel, dev, &nt36523_panel_funcs, DRM_MODE_CONNECTOR_DSI);
>
> - ret = drm_panel_of_backlight(&pinfo->panel);
> - if (ret)
> - return dev_err_probe(dev, ret, "failed to get backlight\n");
> + if (pinfo->desc->has_dcs_backlight) {
> + pinfo->panel.backlight = nt36523_create_backlight(dsi);
> + if (IS_ERR(pinfo->panel.backlight))
> + return dev_err_probe(dev, PTR_ERR(pinfo->panel.backlight),
> + "Failed to create backlight\n");
> + } else {
> + ret = drm_panel_of_backlight(&pinfo->panel);
> + if (ret)
> + return dev_err_probe(dev, ret, "Failed to get backlight\n");
> + }
>
> drm_panel_add(&pinfo->panel);
>
>
> --
> 2.40.0
>
On Wed, Apr 12, 2023 at 9:46 PM Konrad Dybcio <konrad.dybcio@linaro.org> wrote:
> This chip supports controlling the backlight via DCS commands, on at
> least some panels. Add support for doing so.
>
> Note this may only concern the NT36523*W* variant. Nobody knows, really,
> there's no docs.
>
> Signed-off-by: Konrad Dybcio <konrad.dybcio@linaro.org>
Reviewed-by: Linus Walleij <linus.walleij@linaro.org>
Yours,
Linus Walleij
@@ -5,6 +5,7 @@
* Copyright (c) 2022, 2023 Jianhua Lu <lujianhua000@gmail.com>
*/
+#include <linux/backlight.h>
#include <linux/delay.h>
#include <linux/gpio/consumer.h>
#include <linux/module.h>
@@ -53,6 +54,7 @@ struct panel_desc {
int (*init_sequence)(struct panel_info *pinfo);
bool is_dual_dsi;
+ bool has_dcs_backlight;
};
static inline struct panel_info *to_panel_info(struct drm_panel *panel)
@@ -679,6 +681,58 @@ static const struct drm_panel_funcs nt36523_panel_funcs = {
.get_modes = nt36523_get_modes,
};
+static int nt36523_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 nt36523_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 nt36523_bl_ops = {
+ .update_status = nt36523_bl_update_status,
+ .get_brightness = nt36523_bl_get_brightness,
+};
+
+static struct backlight_device *nt36523_create_backlight(struct mipi_dsi_device *dsi)
+{
+ struct device *dev = &dsi->dev;
+ const struct backlight_properties props = {
+ .type = BACKLIGHT_RAW,
+ .brightness = 512,
+ .max_brightness = 4095,
+ };
+
+ return devm_backlight_device_register(dev, dev_name(dev), dev, dsi,
+ &nt36523_bl_ops, &props);
+}
+
static int nt36523_probe(struct mipi_dsi_device *dsi)
{
struct device *dev = &dsi->dev;
@@ -730,9 +784,16 @@ static int nt36523_probe(struct mipi_dsi_device *dsi)
mipi_dsi_set_drvdata(dsi, pinfo);
drm_panel_init(&pinfo->panel, dev, &nt36523_panel_funcs, DRM_MODE_CONNECTOR_DSI);
- ret = drm_panel_of_backlight(&pinfo->panel);
- if (ret)
- return dev_err_probe(dev, ret, "failed to get backlight\n");
+ if (pinfo->desc->has_dcs_backlight) {
+ pinfo->panel.backlight = nt36523_create_backlight(dsi);
+ if (IS_ERR(pinfo->panel.backlight))
+ return dev_err_probe(dev, PTR_ERR(pinfo->panel.backlight),
+ "Failed to create backlight\n");
+ } else {
+ ret = drm_panel_of_backlight(&pinfo->panel);
+ if (ret)
+ return dev_err_probe(dev, ret, "Failed to get backlight\n");
+ }
drm_panel_add(&pinfo->panel);