Implement drm_edp_backlight_get_level() to read the current backlight brightness level from eDP DPCD registers via AUX channel.
Signed-off-by: Aaron Ma <[email protected]> --- v1 -> v2: Use drm_err. drivers/gpu/drm/display/drm_dp_helper.c | 52 +++++++++++++++++++++++++ include/drm/display/drm_dp_helper.h | 1 + 2 files changed, 53 insertions(+) diff --git a/drivers/gpu/drm/display/drm_dp_helper.c b/drivers/gpu/drm/display/drm_dp_helper.c index 1ecc3df7e3167..16da5df805aa5 100644 --- a/drivers/gpu/drm/display/drm_dp_helper.c +++ b/drivers/gpu/drm/display/drm_dp_helper.c @@ -3945,6 +3945,58 @@ int drm_dp_pcon_convert_rgb_to_ycbcr(struct drm_dp_aux *aux, u8 color_spc) } EXPORT_SYMBOL(drm_dp_pcon_convert_rgb_to_ycbcr); +/** + * drm_edp_backlight_get_level - Get the backlight level of eDP DPCD via AUX + * @aux: The DP aux device + * @bl: Backlight capability info from the panel + * + * Reads the current backlight brightness level from luminance mode + * (24-bit value in nits) or DPCD AUX mode(16-bit and 8-bit modes). + * + * Returns: Current backlight level. + */ +u32 drm_edp_backlight_get_level(struct drm_dp_aux *aux, const struct drm_edp_backlight_info *bl) +{ + int ret; + u8 buf[3] = { 0 }; + u32 level = 0; + + if (!(bl->aux_set || bl->luminance_set)) + return 0; + + if (bl->luminance_set) { + ret = drm_dp_dpcd_read(aux, DP_EDP_PANEL_TARGET_LUMINANCE_VALUE, buf, sizeof(buf)); + if (ret < 0) { + drm_err(aux->drm_dev, + "%s: Failed to read luminance value: %d\n", + aux->name, ret); + return 0; + } + level = (buf[2] << 16 | buf[1] << 8 | buf[0]) / 1000; + } else if (bl->lsb_reg_used) { + ret = drm_dp_dpcd_read(aux, DP_EDP_BACKLIGHT_BRIGHTNESS_MSB, buf, 2); + if (ret < 0) { + drm_err(aux->drm_dev, + "%s: Failed to read backlight level: %d\n", + aux->name, ret); + return 0; + } + level = buf[0] << 8 | buf[1]; + } else { + ret = drm_dp_dpcd_read(aux, DP_EDP_BACKLIGHT_BRIGHTNESS_MSB, buf, 1); + if (ret < 0) { + drm_err(aux->drm_dev, + "%s: Failed to read backlight level: %d\n", + aux->name, ret); + return 0; + } + level = buf[0]; + } + + return level; +} +EXPORT_SYMBOL(drm_edp_backlight_get_level); + /** * drm_edp_backlight_set_level() - Set the backlight level of an eDP panel via AUX * @aux: The DP AUX channel to use diff --git a/include/drm/display/drm_dp_helper.h b/include/drm/display/drm_dp_helper.h index 87caa4f1fdb86..0b045a47ae573 100644 --- a/include/drm/display/drm_dp_helper.h +++ b/include/drm/display/drm_dp_helper.h @@ -864,6 +864,7 @@ drm_edp_backlight_init(struct drm_dp_aux *aux, struct drm_edp_backlight_info *bl u32 max_luminance, u16 driver_pwm_freq_hz, const u8 edp_dpcd[EDP_DISPLAY_CTL_CAP_SIZE], u32 *current_level, u8 *current_mode, bool need_luminance); +u32 drm_edp_backlight_get_level(struct drm_dp_aux *aux, const struct drm_edp_backlight_info *bl); int drm_edp_backlight_set_level(struct drm_dp_aux *aux, const struct drm_edp_backlight_info *bl, u32 level); int drm_edp_backlight_enable(struct drm_dp_aux *aux, const struct drm_edp_backlight_info *bl, -- 2.43.0
