Expose SSD130x contrast through the connector LUMINANCE property when DRM_LUMINANCE is enabled. Program contrast directly and retain the backlight class interface otherwise.
Signed-off-by: Mario Limonciello <[email protected]> --- drivers/gpu/drm/solomon/Kconfig | 2 +- drivers/gpu/drm/solomon/ssd130x.c | 79 +++++++++++++++++++++++-------- 2 files changed, 61 insertions(+), 20 deletions(-) diff --git a/drivers/gpu/drm/solomon/Kconfig b/drivers/gpu/drm/solomon/Kconfig index 400a6cab3a671..f0d52bc71cdfc 100644 --- a/drivers/gpu/drm/solomon/Kconfig +++ b/drivers/gpu/drm/solomon/Kconfig @@ -1,7 +1,7 @@ config DRM_SSD130X tristate "DRM support for Solomon SSD13xx OLED displays" depends on DRM && MMU - select BACKLIGHT_CLASS_DEVICE + select BACKLIGHT_CLASS_DEVICE if !DRM_LUMINANCE select DRM_CLIENT_SELECTION select DRM_GEM_SHMEM_HELPER select DRM_KMS_HELPER diff --git a/drivers/gpu/drm/solomon/ssd130x.c b/drivers/gpu/drm/solomon/ssd130x.c index 324467ae9309f..8aec74ecdcb6d 100644 --- a/drivers/gpu/drm/solomon/ssd130x.c +++ b/drivers/gpu/drm/solomon/ssd130x.c @@ -1831,7 +1831,8 @@ static void ssd130x_encoder_atomic_enable(struct drm_encoder *encoder, ssd130x_write_cmd(ssd130x, 1, SSD13XX_DISPLAY_ON); - backlight_enable(ssd130x->bl_dev); + if (ssd130x->bl_dev) + backlight_enable(ssd130x->bl_dev); return; @@ -1857,7 +1858,8 @@ static void ssd132x_encoder_atomic_enable(struct drm_encoder *encoder, ssd130x_write_cmd(ssd130x, 1, SSD13XX_DISPLAY_ON); - backlight_enable(ssd130x->bl_dev); + if (ssd130x->bl_dev) + backlight_enable(ssd130x->bl_dev); return; @@ -1882,7 +1884,8 @@ static void ssd133x_encoder_atomic_enable(struct drm_encoder *encoder, ssd130x_write_cmd(ssd130x, 1, SSD13XX_DISPLAY_ON); - backlight_enable(ssd130x->bl_dev); + if (ssd130x->bl_dev) + backlight_enable(ssd130x->bl_dev); return; @@ -1907,7 +1910,8 @@ static void ssd135x_encoder_atomic_enable(struct drm_encoder *encoder, ssd130x_write_cmd(ssd130x, 1, SSD13XX_DISPLAY_ON); - backlight_enable(ssd130x->bl_dev); + if (ssd130x->bl_dev) + backlight_enable(ssd130x->bl_dev); return; @@ -1921,7 +1925,8 @@ static void ssd130x_encoder_atomic_disable(struct drm_encoder *encoder, struct drm_device *drm = encoder->dev; struct ssd130x_device *ssd130x = drm_to_ssd130x(drm); - backlight_disable(ssd130x->bl_dev); + if (ssd130x->bl_dev) + backlight_disable(ssd130x->bl_dev); ssd130x_write_cmd(ssd130x, 1, SSD13XX_DISPLAY_OFF); @@ -1958,8 +1963,44 @@ static int ssd130x_connector_get_modes(struct drm_connector *connector) return drm_connector_helper_get_modes_fixed(connector, &ssd130x->mode); } +static int ssd130x_set_luminance_value(struct ssd130x_device *ssd130x, + unsigned int luminance) +{ + int ret; + + ssd130x->contrast = luminance; + + switch (ssd130x->device_info->family_id) { + case SSD133X_FAMILY: + return ssd133x_set_contrast(ssd130x, luminance); + case SSD135X_FAMILY: + return ssd135x_set_contrast(ssd130x, luminance); + default: + ret = ssd130x_write_cmd(ssd130x, 1, SSD13XX_CONTRAST); + if (ret < 0) + return ret; + return ssd130x_write_cmd(ssd130x, 1, luminance); + } +} + +static void ssd130x_connector_set_luminance(const struct drm_connector_state *conn_state) +{ + struct ssd130x_device *ssd130x = drm_to_ssd130x(conn_state->connector->dev); + + ssd130x_set_luminance_value(ssd130x, conn_state->luminance); +} + +static void ssd130x_connector_disable_luminance(const struct drm_connector_state *conn_state) +{ + struct ssd130x_device *ssd130x = drm_to_ssd130x(conn_state->connector->dev); + + ssd130x_set_luminance_value(ssd130x, 0); +} + static const struct drm_connector_helper_funcs ssd130x_connector_helper_funcs = { .get_modes = ssd130x_connector_get_modes, + .set_luminance = ssd130x_connector_set_luminance, + .disable_luminance = ssd130x_connector_disable_luminance, }; static const struct drm_connector_funcs ssd130x_connector_funcs = { @@ -1996,20 +2037,9 @@ static const struct drm_driver ssd130x_drm_driver = { static int ssd130x_update_bl(struct backlight_device *bdev) { struct ssd130x_device *ssd130x = bl_get_data(bdev); - int brightness = backlight_get_brightness(bdev); - int ret; - - ssd130x->contrast = brightness; - - ret = ssd130x_write_cmd(ssd130x, 1, SSD13XX_CONTRAST); - if (ret < 0) - return ret; - ret = ssd130x_write_cmd(ssd130x, 1, ssd130x->contrast); - if (ret < 0) - return ret; - - return 0; + return ssd130x_set_luminance_value(ssd130x, + backlight_get_brightness(bdev)); } static int ssd133x_update_bl(struct backlight_device *bdev) @@ -2030,7 +2060,7 @@ static int ssd135x_update_bl(struct backlight_device *bdev) return ssd135x_set_contrast(ssd130x, ssd130x->contrast); } -static const struct backlight_ops ssd130xfb_bl_ops[] = { +static const struct backlight_ops ssd130xfb_bl_ops[] __maybe_unused = { [SSD130X_FAMILY] = { .update_status = ssd130x_update_bl, }, @@ -2191,6 +2221,13 @@ static int ssd130x_init_modeset(struct ssd130x_device *ssd130x) } drm_connector_helper_add(connector, &ssd130x_connector_helper_funcs); + if (IS_ENABLED(CONFIG_DRM_LUMINANCE)) { + ret = drm_connector_attach_luminance_property(connector, 0, + MAX_CONTRAST, + ssd130x->contrast); + if (ret) + return ret; + } ret = drm_connector_attach_encoder(connector, encoder); if (ret) { @@ -2223,7 +2260,9 @@ static int ssd130x_get_resources(struct ssd130x_device *ssd130x) struct ssd130x_device *ssd130x_probe(struct device *dev, struct regmap *regmap) { struct ssd130x_device *ssd130x; +#ifndef CONFIG_DRM_LUMINANCE struct backlight_device *bl; +#endif struct drm_device *drm; int ret; @@ -2248,6 +2287,7 @@ struct ssd130x_device *ssd130x_probe(struct device *dev, struct regmap *regmap) if (ret) return ERR_PTR(ret); +#ifndef CONFIG_DRM_LUMINANCE bl = devm_backlight_device_register(dev, dev_name(dev), dev, ssd130x, &ssd130xfb_bl_ops[ssd130x->device_info->family_id], NULL); @@ -2258,6 +2298,7 @@ struct ssd130x_device *ssd130x_probe(struct device *dev, struct regmap *regmap) bl->props.brightness = ssd130x->contrast; bl->props.max_brightness = MAX_CONTRAST; ssd130x->bl_dev = bl; +#endif ret = ssd130x_init_modeset(ssd130x); if (ret) -- 2.43.0
