From: Mario Limonciello <[email protected]> Expose SSD130x contrast through the connector LUMINANCE property when DRM_LUMINANCE is enabled. Program contrast directly and retain the backlight class interface when BACKLIGHT_CLASS_DEVICE is enabled.
Reviewed-by: Javier Martinez Canillas <[email protected]> Signed-off-by: Mario Limonciello <[email protected]> --- v10: * Guard the backlight operations and registration with BACKLIGHT_CLASS_DEVICE * Fix Kconfig recursive issue * Add the Reviewed-by tag --- drivers/gpu/drm/solomon/Kconfig | 2 +- drivers/gpu/drm/solomon/ssd130x.c | 79 ++++++++++++++++++++++++++++++--------- 2 files changed, 62 insertions(+), 19 deletions(-) diff --git a/drivers/gpu/drm/solomon/Kconfig b/drivers/gpu/drm/solomon/Kconfig index 400a6cab3a671..76852246eb9c2 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 + depends on DRM_LUMINANCE || BACKLIGHT_CLASS_DEVICE = y || !BACKLIGHT_CLASS_DEVICE 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 ee43cf0da8792..aaf2b194273ba 100644 --- a/drivers/gpu/drm/solomon/ssd130x.c +++ b/drivers/gpu/drm/solomon/ssd130x.c @@ -1853,7 +1853,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; @@ -1879,7 +1880,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; @@ -1904,7 +1906,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; @@ -1929,7 +1932,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; @@ -1943,7 +1947,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); @@ -1980,8 +1985,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 = { @@ -2015,23 +2056,13 @@ static const struct drm_driver ssd130x_drm_driver = { .fops = &ssd130x_fops, }; +#if IS_ENABLED(CONFIG_BACKLIGHT_CLASS_DEVICE) 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) @@ -2066,6 +2097,7 @@ static const struct backlight_ops ssd130xfb_bl_ops[] = { .update_status = ssd135x_update_bl, }, }; +#endif static void ssd130x_parse_properties(struct ssd130x_device *ssd130x) { @@ -2213,6 +2245,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) { @@ -2245,7 +2284,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; +#if IS_ENABLED(CONFIG_BACKLIGHT_CLASS_DEVICE) struct backlight_device *bl; +#endif struct drm_device *drm; int ret; @@ -2270,6 +2311,7 @@ struct ssd130x_device *ssd130x_probe(struct device *dev, struct regmap *regmap) if (ret) return ERR_PTR(ret); +#if IS_ENABLED(CONFIG_BACKLIGHT_CLASS_DEVICE) bl = devm_backlight_device_register(dev, dev_name(dev), dev, ssd130x, &ssd130xfb_bl_ops[ssd130x->device_info->family_id], NULL); @@ -2280,6 +2322,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.53.0
