drm/msm/sde: fix backlight node for multi display
Update backlight node to generic name to support
multiple display usecase. Remove the separate
backlight file and keep it part of connector
module.
Change-Id: I2c6beb1a27f919c5c201f95133749fdf1d27ddd8
Signed-off-by: Dhaval Patel <pdhaval@codeaurora.org>
diff --git a/drivers/gpu/drm/msm/sde/sde_connector.c b/drivers/gpu/drm/msm/sde/sde_connector.c
index 59db57a..01c2402 100644
--- a/drivers/gpu/drm/msm/sde/sde_connector.c
+++ b/drivers/gpu/drm/msm/sde/sde_connector.c
@@ -15,7 +15,10 @@
#include "sde_kms.h"
#include "sde_connector.h"
-#include "sde_backlight.h"
+#include <linux/backlight.h>
+#include "dsi_drm.h"
+
+#define BL_NODE_NAME_SIZE 32
static const struct drm_prop_enum_list e_topology_name[] = {
{SDE_RM_TOPOLOGY_UNKNOWN, "sde_unknown"},
@@ -32,6 +35,86 @@
{SDE_RM_TOPCTL_PPSPLIT, "ppsplit"}
};
+static int sde_backlight_device_update_status(struct backlight_device *bd)
+{
+ int brightness;
+ struct dsi_display *display;
+ struct sde_connector *c_conn;
+ int bl_lvl;
+
+ brightness = bd->props.brightness;
+
+ if ((bd->props.power != FB_BLANK_UNBLANK) ||
+ (bd->props.state & BL_CORE_FBBLANK) ||
+ (bd->props.state & BL_CORE_SUSPENDED))
+ brightness = 0;
+
+ c_conn = bl_get_data(bd);
+ display = (struct dsi_display *) c_conn->display;
+ if (brightness > display->panel->bl_config.bl_max_level)
+ brightness = display->panel->bl_config.bl_max_level;
+
+ /* map UI brightness into driver backlight level with rounding */
+ bl_lvl = mult_frac(brightness, display->panel->bl_config.bl_max_level,
+ display->panel->bl_config.brightness_max_level);
+
+ if (!bl_lvl && brightness)
+ bl_lvl = 1;
+
+ if (c_conn->ops.set_backlight)
+ c_conn->ops.set_backlight(c_conn->display, bl_lvl);
+
+ return 0;
+}
+
+static int sde_backlight_device_get_brightness(struct backlight_device *bd)
+{
+ return 0;
+}
+
+static const struct backlight_ops sde_backlight_device_ops = {
+ .update_status = sde_backlight_device_update_status,
+ .get_brightness = sde_backlight_device_get_brightness,
+};
+
+static int sde_backlight_setup(struct sde_connector *c_conn)
+{
+ struct backlight_device *bl_device;
+ struct backlight_properties props;
+ struct dsi_display *display;
+ struct dsi_backlight_config *bl_config;
+ static int display_count;
+ char bl_node_name[BL_NODE_NAME_SIZE];
+
+ if (!c_conn) {
+ SDE_ERROR("invalid param\n");
+ return -EINVAL;
+ } else if (c_conn->connector_type != DRM_MODE_CONNECTOR_DSI) {
+ return 0;
+ }
+
+ memset(&props, 0, sizeof(props));
+ props.type = BACKLIGHT_RAW;
+ props.power = FB_BLANK_UNBLANK;
+
+ display = (struct dsi_display *) c_conn->display;
+ bl_config = &display->panel->bl_config;
+ props.max_brightness = bl_config->brightness_max_level;
+ props.brightness = bl_config->brightness_max_level;
+ snprintf(bl_node_name, BL_NODE_NAME_SIZE, "panel%u-backlight",
+ display_count);
+ bl_device = backlight_device_register(bl_node_name, c_conn->base.kdev,
+ c_conn, &sde_backlight_device_ops, &props);
+ if (IS_ERR_OR_NULL(bl_device)) {
+ SDE_ERROR("Failed to register backlight: %ld\n",
+ PTR_ERR(bl_device));
+ return -ENODEV;
+ }
+ display_count++;
+
+ return 0;
+}
+
int sde_connector_get_info(struct drm_connector *connector,
struct msm_display_info *info)
{
@@ -532,12 +615,10 @@
goto error_cleanup_fence;
}
- if (c_conn->ops.set_backlight) {
- rc = sde_backlight_setup(&c_conn->base);
- if (rc) {
- pr_err("failed to setup backlight, rc=%d\n", rc);
- goto error_cleanup_fence;
- }
+ rc = sde_backlight_setup(c_conn);
+ if (rc) {
+ SDE_ERROR("failed to setup backlight, rc=%d\n", rc);
+ goto error_cleanup_fence;
}
/* create properties */