From 018d3c99b479a531abfaa0d870f395bf1e7b639c Mon Sep 17 00:00:00 2001 From: Ion Agorria Date: Sat, 19 Apr 2025 01:47:47 +0200 Subject: [PATCH] video: backlight: add Samsung CMC623 backlight PWM driver Add support for PWM backlight found in Samsung CMC623 image converter. Signed-off-by: Ion Agorria Reviewed-by: Svyatoslav Ryhel Signed-off-by: Svyatoslav Ryhel --- drivers/video/Kconfig | 7 ++ drivers/video/Makefile | 1 + drivers/video/cmc623_backlight.c | 124 +++++++++++++++++++++++++++++++ 3 files changed, 132 insertions(+) create mode 100644 drivers/video/cmc623_backlight.c diff --git a/drivers/video/Kconfig b/drivers/video/Kconfig index a02501583eb..b5777da5218 100644 --- a/drivers/video/Kconfig +++ b/drivers/video/Kconfig @@ -838,6 +838,13 @@ config BACKLIGHT_LP855x supported for now, PWM mode can be added if there will be any need in it. Supported backlight level range is from 0 to 255 with step of 1. +config BACKLIGHT_SAMSUNG_CMC623 + bool "Backlight Driver for Samsung CMC623" + depends on VIDEO_BRIDGE_SAMSUNG_CMC623 + help + Say Y to enable the backlight driver for Samsung CMC623 image converter + chip's PWM output to control backlight brightness. + source "drivers/video/ti/Kconfig" source "drivers/video/exynos/Kconfig" diff --git a/drivers/video/Makefile b/drivers/video/Makefile index 040333fb3a6..96c7ce7bb09 100644 --- a/drivers/video/Makefile +++ b/drivers/video/Makefile @@ -33,6 +33,7 @@ obj-$(CONFIG_BACKLIGHT_AAT2870) += aat2870_backlight.o obj-$(CONFIG_BACKLIGHT_LM3532) += lm3532_backlight.o obj-$(CONFIG_BACKLIGHT_LM3533) += lm3533_backlight.o obj-$(CONFIG_BACKLIGHT_LP855x) += lp855x_backlight.o +obj-$(CONFIG_BACKLIGHT_SAMSUNG_CMC623) += cmc623_backlight.o obj-${CONFIG_EXYNOS_FB} += exynos/ obj-${CONFIG_VIDEO_ROCKCHIP} += rockchip/ obj-${CONFIG_VIDEO_STM32} += stm32/ diff --git a/drivers/video/cmc623_backlight.c b/drivers/video/cmc623_backlight.c new file mode 100644 index 00000000000..84b01724a07 --- /dev/null +++ b/drivers/video/cmc623_backlight.c @@ -0,0 +1,124 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * Copyright (c) 2025 Ion Agorria + */ + +#define LOG_CATEGORY UCLASS_PANEL_BACKLIGHT + +#include +#include +#include +#include +#include +#include +#include + +#define CMC623_I2C_REG_SELBANK 0x00 +#define CMC623_I2C_REG_PWMCTRL 0xb4 +#define CMC623_I2C_REG_REGMASK 0x28 + +#define CMC623_BL_MIN_BRIGHTNESS 0 +#define CMC623_BL_DEF_BRIGHTNESS 50 +#define CMC623_BL_MAX_BRIGHTNESS 100 + +struct cmc623_backlight_priv { + struct gpio_desc enable_gpio; +}; + +static int cmc623_backlight_enable(struct udevice *dev) +{ + struct cmc623_backlight_priv *priv = dev_get_priv(dev); + + if (dm_gpio_is_valid(&priv->enable_gpio)) + dm_gpio_set_value(&priv->enable_gpio, 1); + + return 0; +} + +static int cmc623_i2c_write(struct udevice *dev, u8 reg, u16 value) +{ + u8 data[2]; + + data[0] = (value >> 8) & 0xff; + data[1] = value & 0xff; + + return dm_i2c_write(dev->parent, reg, data, 2); +} + +static int cmc623_backlight_set_brightness(struct udevice *dev, int percent) +{ + int ret; + u16 brightness; + + if (percent == BACKLIGHT_DEFAULT) + percent = CMC623_BL_DEF_BRIGHTNESS; + + if (percent < CMC623_BL_MIN_BRIGHTNESS) + percent = CMC623_BL_MIN_BRIGHTNESS; + + if (percent > CMC623_BL_MAX_BRIGHTNESS) + percent = CMC623_BL_MAX_BRIGHTNESS; + + brightness = 0x4000 | (percent << 4); + + ret = cmc623_i2c_write(dev, CMC623_I2C_REG_SELBANK, 0x0000); + if (ret) { + log_debug("%s: error at CMC623_I2C_REG_SELBANK (%d)\n", + __func__, ret); + return ret; + } + + ret = cmc623_i2c_write(dev, CMC623_I2C_REG_PWMCTRL, brightness); + if (ret) { + log_debug("%s: error at CMC623_I2C_REG_PWMCTRL (%d)\n", + __func__, ret); + return ret; + } + + ret = cmc623_i2c_write(dev, CMC623_I2C_REG_REGMASK, 0x0000); + if (ret) { + log_debug("%s: error at CMC623_I2C_REG_REGMASK (%d)\n", + __func__, ret); + return ret; + } + + return 0; +} + +static int cmc623_backlight_of_to_plat(struct udevice *dev) +{ + struct cmc623_backlight_priv *priv = dev_get_priv(dev); + + gpio_request_by_name(dev, "enable-gpios", 0, + &priv->enable_gpio, GPIOD_IS_OUT); + + return 0; +} + +static int cmc623_backlight_probe(struct udevice *dev) +{ + if (device_get_uclass_id(dev->parent) != UCLASS_VIDEO_BRIDGE) + return -EPROTONOSUPPORT; + + return 0; +} + +static const struct backlight_ops cmc623_backlight_ops = { + .enable = cmc623_backlight_enable, + .set_brightness = cmc623_backlight_set_brightness, +}; + +static const struct udevice_id cmc623_backlight_ids[] = { + { .compatible = "samsung,cmc623-backlight" }, + { } +}; + +U_BOOT_DRIVER(cmc623_backlight) = { + .name = "cmc623_backlight", + .id = UCLASS_PANEL_BACKLIGHT, + .of_match = cmc623_backlight_ids, + .of_to_plat = cmc623_backlight_of_to_plat, + .probe = cmc623_backlight_probe, + .ops = &cmc623_backlight_ops, + .priv_auto = sizeof(struct cmc623_backlight_priv), +};