OSDN Git Service

drm/panel-sony-acx424akp: Modernize backlight handling
authorLinus Walleij <linus.walleij@linaro.org>
Thu, 15 Jul 2021 09:28:08 +0000 (11:28 +0200)
committerLinus Walleij <linus.walleij@linaro.org>
Wed, 28 Jul 2021 21:46:18 +0000 (23:46 +0200)
This converts the internal backlight in the Sony ACX424AKP
driver to do it the canonical way:

- Assign the panel->backlight during probe.
- Let the panel framework handle the backlight.
- Make the backlight .set_brightness() turn the backlight
  off completely if blank.
- Fix some dev_err_probe() use cases along the way.

Tested on the U8500 HREF520 reference design.

Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
Reviewed-by: Sam Ravnborg <sam@ravnborg.org>
Link: https://patchwork.freedesktop.org/patch/msgid/20210715092808.1100106-1-linus.walleij@linaro.org
drivers/gpu/drm/panel/panel-sony-acx424akp.c

index 95659a4..9536d56 100644 (file)
@@ -40,7 +40,6 @@
 struct acx424akp {
        struct drm_panel panel;
        struct device *dev;
-       struct backlight_device *bl;
        struct regulator *supply;
        struct gpio_desc *reset_gpio;
        bool video_mode;
@@ -102,6 +101,18 @@ static int acx424akp_set_brightness(struct backlight_device *bl)
        u8 par;
        int ret;
 
+       if (backlight_is_blank(bl)) {
+               /* Disable backlight */
+               par = 0x00;
+               ret = mipi_dsi_dcs_write(dsi, MIPI_DCS_WRITE_CONTROL_DISPLAY,
+                                        &par, 1);
+               if (ret) {
+                       dev_err(acx->dev, "failed to disable display backlight (%d)\n", ret);
+                       return ret;
+               }
+               return 0;
+       }
+
        /* Calculate the PWM duty cycle in n/256's */
        pwm_ratio = max(((duty_ns * 256) / period_ns) - 1, 1);
        pwm_div = max(1,
@@ -172,6 +183,12 @@ static const struct backlight_ops acx424akp_bl_ops = {
        .update_status = acx424akp_set_brightness,
 };
 
+static const struct backlight_properties acx424akp_bl_props = {
+       .type = BACKLIGHT_RAW,
+       .brightness = 512,
+       .max_brightness = 1023,
+};
+
 static int acx424akp_read_id(struct acx424akp *acx)
 {
        struct mipi_dsi_device *dsi = to_mipi_dsi_device(acx->dev);
@@ -310,8 +327,6 @@ static int acx424akp_prepare(struct drm_panel *panel)
                }
        }
 
-       acx->bl->props.power = FB_BLANK_NORMAL;
-
        return 0;
 
 err_power_off:
@@ -323,18 +338,8 @@ static int acx424akp_unprepare(struct drm_panel *panel)
 {
        struct acx424akp *acx = panel_to_acx424akp(panel);
        struct mipi_dsi_device *dsi = to_mipi_dsi_device(acx->dev);
-       u8 par;
        int ret;
 
-       /* Disable backlight */
-       par = 0x00;
-       ret = mipi_dsi_dcs_write(dsi, MIPI_DCS_WRITE_CONTROL_DISPLAY,
-                                &par, 1);
-       if (ret) {
-               dev_err(acx->dev, "failed to disable display backlight (%d)\n", ret);
-               return ret;
-       }
-
        ret = mipi_dsi_dcs_set_display_off(dsi);
        if (ret) {
                dev_err(acx->dev, "failed to turn display off (%d)\n", ret);
@@ -350,36 +355,10 @@ static int acx424akp_unprepare(struct drm_panel *panel)
        msleep(85);
 
        acx424akp_power_off(acx);
-       acx->bl->props.power = FB_BLANK_POWERDOWN;
-
-       return 0;
-}
-
-static int acx424akp_enable(struct drm_panel *panel)
-{
-       struct acx424akp *acx = panel_to_acx424akp(panel);
-
-       /*
-        * The backlight is on as long as the display is on
-        * so no use to call backlight_enable() here.
-        */
-       acx->bl->props.power = FB_BLANK_UNBLANK;
 
        return 0;
 }
 
-static int acx424akp_disable(struct drm_panel *panel)
-{
-       struct acx424akp *acx = panel_to_acx424akp(panel);
-
-       /*
-        * The backlight is on as long as the display is on
-        * so no use to call backlight_disable() here.
-        */
-       acx->bl->props.power = FB_BLANK_NORMAL;
-
-       return 0;
-}
 
 static int acx424akp_get_modes(struct drm_panel *panel,
                               struct drm_connector *connector)
@@ -409,10 +388,8 @@ static int acx424akp_get_modes(struct drm_panel *panel,
 }
 
 static const struct drm_panel_funcs acx424akp_drm_funcs = {
-       .disable = acx424akp_disable,
        .unprepare = acx424akp_unprepare,
        .prepare = acx424akp_prepare,
-       .enable = acx424akp_enable,
        .get_modes = acx424akp_get_modes,
 };
 
@@ -458,25 +435,18 @@ static int acx424akp_probe(struct mipi_dsi_device *dsi)
        /* This asserts RESET by default */
        acx->reset_gpio = devm_gpiod_get_optional(dev, "reset",
                                                  GPIOD_OUT_HIGH);
-       if (IS_ERR(acx->reset_gpio)) {
-               ret = PTR_ERR(acx->reset_gpio);
-               if (ret != -EPROBE_DEFER)
-                       dev_err(dev, "failed to request GPIO (%d)\n", ret);
-               return ret;
-       }
+       if (IS_ERR(acx->reset_gpio))
+               return dev_err_probe(dev, PTR_ERR(acx->reset_gpio),
+                                    "failed to request GPIO\n");
 
        drm_panel_init(&acx->panel, dev, &acx424akp_drm_funcs,
                       DRM_MODE_CONNECTOR_DSI);
 
-       acx->bl = devm_backlight_device_register(dev, "acx424akp", dev, acx,
-                                                &acx424akp_bl_ops, NULL);
-       if (IS_ERR(acx->bl)) {
-               dev_err(dev, "failed to register backlight device\n");
-               return PTR_ERR(acx->bl);
-       }
-       acx->bl->props.max_brightness = 1023;
-       acx->bl->props.brightness = 512;
-       acx->bl->props.power = FB_BLANK_POWERDOWN;
+       acx->panel.backlight = devm_backlight_device_register(dev, "acx424akp", dev, acx,
+                                       &acx424akp_bl_ops, &acx424akp_bl_props);
+       if (IS_ERR(acx->panel.backlight))
+               return dev_err_probe(dev, PTR_ERR(acx->panel.backlight),
+                                    "failed to register backlight device\n");
 
        drm_panel_add(&acx->panel);