Message ID | 20220715112607.591-14-peterwu.pub@gmail.com (mailing list archive) |
---|---|
State | Handled Elsewhere |
Headers | show |
Series | Add MediaTek MT6370 PMIC support | expand |
Il 15/07/22 13:26, ChiaEn Wu ha scritto: > From: ChiaEn Wu <chiaen_wu@richtek.com> > > MediaTek MT6370 is a SubPMIC consisting of a single cell battery charger > with ADC monitoring, RGB LEDs, dual channel flashlight, WLED backlight > driver, display bias voltage supply, one general purpose LDO, and the > USB Type-C & PD controller complies with the latest USB Type-C and PD > standards. > > This adds support for MediaTek MT6370 Backlight driver. It's commonly used > to drive the display WLED. There are 4 channels inside, and each channel > supports up to 30mA of current capability with 2048 current steps in > exponential or linear mapping curves. > > Signed-off-by: ChiaEn Wu <chiaen_wu@richtek.com> Hello ChiaEn, I propose to move this one to drivers/leds (or drivers/pwm) and, instead of registering a backlight device, register a PWM device. This way you will be able to reuse the generic backlight-pwm driver, as you'd be feeding the PWM device exposed by this driver to the generic one: this will most importantly make it easy to chain it with MTK_DISP_PWM (mtk-pwm-disp) with a devicetree that looks like... pwmleds-disp { compatible = "pwm-leds"; disp_led: disp-pwm { label = "backlight-pwm"; pwms = <&pwm0 0 500000>; max-brightness = <1024>; }; }; backlight_lcd0: backlight { compatible = "led-backlight"; leds = <&disp_led>, <&pmic_bl_led>; default-brightness-level = <300>; }; Regards, Angelo
On Fri, Jul 15, 2022 at 02:38:45PM +0200, AngeloGioacchino Del Regno wrote: > Il 15/07/22 13:26, ChiaEn Wu ha scritto: > > From: ChiaEn Wu <chiaen_wu@richtek.com> > > > > MediaTek MT6370 is a SubPMIC consisting of a single cell battery charger > > with ADC monitoring, RGB LEDs, dual channel flashlight, WLED backlight > > driver, display bias voltage supply, one general purpose LDO, and the > > USB Type-C & PD controller complies with the latest USB Type-C and PD > > standards. > > > > This adds support for MediaTek MT6370 Backlight driver. It's commonly used > > to drive the display WLED. There are 4 channels inside, and each channel > > supports up to 30mA of current capability with 2048 current steps in > > exponential or linear mapping curves. > > > > Signed-off-by: ChiaEn Wu <chiaen_wu@richtek.com> > > Hello ChiaEn, > > I propose to move this one to drivers/leds (or drivers/pwm) and, instead of > registering a backlight device, register a PWM device. > > This way you will be able to reuse the generic backlight-pwm driver, as you'd > be feeding the PWM device exposed by this driver to the generic one: this will > most importantly make it easy to chain it with MTK_DISP_PWM (mtk-pwm-disp) > with a devicetree that looks like... Out of interest, does MT6370 have the same structure for backlights as the prior systems using mtk-pwm-disp or was mtk-pwm-disp simply a normal(-ish) PWM that relied on something on the board for all the constant current driver hardware? > > pwmleds-disp { > compatible = "pwm-leds"; > > disp_led: disp-pwm { > label = "backlight-pwm"; > pwms = <&pwm0 0 500000>; > max-brightness = <1024>; > }; > }; > > backlight_lcd0: backlight { > compatible = "led-backlight"; > leds = <&disp_led>, <&pmic_bl_led>; > default-brightness-level = <300>; > }; I think this proposal has to start with the devicetree bindings rather than the driver. Instead I think the question is: does this proposal result in DT bindings that better describe the underlying hardware? This device has lots of backlight centric features (OCP, OVP, single control with multiple outputs, exponential curves, etc) and its not clear where they would fit into the "PWM" bindings. Come to think of it I'm also a little worried also about the whole linear versus exponential curve thing since I thought LED drivers were required to use exponential curves. Daniel.
Il 15/07/22 18:29, Daniel Thompson ha scritto: > On Fri, Jul 15, 2022 at 02:38:45PM +0200, AngeloGioacchino Del Regno wrote: >> Il 15/07/22 13:26, ChiaEn Wu ha scritto: >>> From: ChiaEn Wu <chiaen_wu@richtek.com> >>> >>> MediaTek MT6370 is a SubPMIC consisting of a single cell battery charger >>> with ADC monitoring, RGB LEDs, dual channel flashlight, WLED backlight >>> driver, display bias voltage supply, one general purpose LDO, and the >>> USB Type-C & PD controller complies with the latest USB Type-C and PD >>> standards. >>> >>> This adds support for MediaTek MT6370 Backlight driver. It's commonly used >>> to drive the display WLED. There are 4 channels inside, and each channel >>> supports up to 30mA of current capability with 2048 current steps in >>> exponential or linear mapping curves. >>> >>> Signed-off-by: ChiaEn Wu <chiaen_wu@richtek.com> >> >> Hello ChiaEn, >> >> I propose to move this one to drivers/leds (or drivers/pwm) and, instead of >> registering a backlight device, register a PWM device. >> >> This way you will be able to reuse the generic backlight-pwm driver, as you'd >> be feeding the PWM device exposed by this driver to the generic one: this will >> most importantly make it easy to chain it with MTK_DISP_PWM (mtk-pwm-disp) >> with a devicetree that looks like... > > Out of interest, does MT6370 have the same structure for backlights as the prior > systems using mtk-pwm-disp or was mtk-pwm-disp simply a normal(-ish) PWM > that relied on something on the board for all the constant current > driver hardware? > > As per my understanding, mtk-pwm-disp is chained to other multimedia features of the display block of MediaTek SoCs, such as the AAL (adaptive ambient light), CABC (content adaptive backlight control) etc, other than being a normal(ish) PWM... that's the reason of my request. Moreover, in the end, this PMIC's backlight controller is just a "fancy" PWM controller, with OCP/OVP. >> >> pwmleds-disp { >> compatible = "pwm-leds"; >> >> disp_led: disp-pwm { >> label = "backlight-pwm"; >> pwms = <&pwm0 0 500000>; >> max-brightness = <1024>; >> }; >> }; >> >> backlight_lcd0: backlight { >> compatible = "led-backlight"; >> leds = <&disp_led>, <&pmic_bl_led>; >> default-brightness-level = <300>; >> }; > > I think this proposal has to start with the devicetree bindings rather > than the driver. Instead I think the question is: does this proposal > result in DT bindings that better describe the underlying hardware? > From how I understand it - yes: we have a fancy PWM (&pwm0) that we use to control display backlight (backlight-pwm)... Obviously, here we're not talking about OLEDs, but LCDs, where the backlight is made of multiple strings of WhiteLED (effectively, a "pwm-leds" controlled "led-backlight"). Using PWM will also allow for a little more fine-grained board specific configuration, as I think that this PMIC (and/or variants of it) will be used in completely different form factors: I think that's going to be both smartphones and tablets/laptops... and I want to avoid vendor properties to configure the PWM part in a somehow different way. > This device has lots of backlight centric features (OCP, OVP, single > control with multiple outputs, exponential curves, etc) and its not > clear where they would fit into the "PWM" bindings. > For OCP and OVP, the only bindings that fit would be regulators, but that's not a regulator... and that's about it - I don't really have arguments for that. What I really want to see here is usage of "generic" drivers like led_bl and/or pwm_bl as to get some "standardization" around with all the benefits that this carries. > Come to think of it I'm also a little worried also about the whole linear > versus exponential curve thing since I thought LED drivers were required > to use exponential curves. > That probably depends on how the controller interprets the data, I guess, but I agree with you on this thought. Regards, Angelo
On Mon, Jul 18, 2022 at 4:27 PM AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com> wrote: > <snip> > >> > >> Hello ChiaEn, > >> > >> I propose to move this one to drivers/leds (or drivers/pwm) and, instead of > >> registering a backlight device, register a PWM device. > >> > >> This way you will be able to reuse the generic backlight-pwm driver, as you'd > >> be feeding the PWM device exposed by this driver to the generic one: this will > >> most importantly make it easy to chain it with MTK_DISP_PWM (mtk-pwm-disp) > >> with a devicetree that looks like... > > > > Out of interest, does MT6370 have the same structure for backlights as the prior > > systems using mtk-pwm-disp or was mtk-pwm-disp simply a normal(-ish) PWM > > that relied on something on the board for all the constant current > > driver hardware? > > > > > > As per my understanding, mtk-pwm-disp is chained to other multimedia features of > the display block of MediaTek SoCs, such as the AAL (adaptive ambient light), > CABC (content adaptive backlight control) etc, other than being a normal(ish) > PWM... that's the reason of my request. > > Moreover, in the end, this PMIC's backlight controller is just a "fancy" PWM > controller, with OCP/OVP. > > >> > >> pwmleds-disp { > >> compatible = "pwm-leds"; > >> > >> disp_led: disp-pwm { > >> label = "backlight-pwm"; > >> pwms = <&pwm0 0 500000>; > >> max-brightness = <1024>; > >> }; > >> }; > >> > >> backlight_lcd0: backlight { > >> compatible = "led-backlight"; > >> leds = <&disp_led>, <&pmic_bl_led>; > >> default-brightness-level = <300>; > >> }; > > > > I think this proposal has to start with the devicetree bindings rather > > than the driver. Instead I think the question is: does this proposal > > result in DT bindings that better describe the underlying hardware? > > > > From how I understand it - yes: we have a fancy PWM (&pwm0) that we use > to control display backlight (backlight-pwm)... > > Obviously, here we're not talking about OLEDs, but LCDs, where the backlight > is made of multiple strings of WhiteLED (effectively, a "pwm-leds" controlled > "led-backlight"). > > Using PWM will also allow for a little more fine-grained board specific > configuration, as I think that this PMIC (and/or variants of it) will be > used in completely different form factors: I think that's going to be both > smartphones and tablets/laptops... and I want to avoid vendor properties > to configure the PWM part in a somehow different way. > > > This device has lots of backlight centric features (OCP, OVP, single > > control with multiple outputs, exponential curves, etc) and its not > > clear where they would fit into the "PWM" bindings. > > > > For OCP and OVP, the only bindings that fit would be regulators, but that's > not a regulator... and that's about it - I don't really have arguments for > that. > > What I really want to see here is usage of "generic" drivers like led_bl > and/or pwm_bl as to get some "standardization" around with all the benefits > that this carries. > > > Come to think of it I'm also a little worried also about the whole linear > > versus exponential curve thing since I thought LED drivers were required > > to use exponential curves. > > > > That probably depends on how the controller interprets the data, I guess, > but I agree with you on this thought. Hi Angelo, MT6370 is just a SubPMIC, not an SoC, and is applied in cellular telephones, tablet PCs, and portable instruments. And the PWM mode of the MT6370 backlight driver is optional, and not must be enabled. From our perspective, this MT6370 backlight driver is not the same as mtk-pwm-disp related driver. Thanks! > > Regards, > Angelo
diff --git a/drivers/video/backlight/Kconfig b/drivers/video/backlight/Kconfig index a003e02..846dbe7 100644 --- a/drivers/video/backlight/Kconfig +++ b/drivers/video/backlight/Kconfig @@ -268,6 +268,18 @@ config BACKLIGHT_MAX8925 If you have a LCD backlight connected to the WLED output of MAX8925 WLED output, say Y here to enable this driver. +config BACKLIGHT_MT6370 + tristate "MediaTek MT6370 Backlight Driver" + depends on MFD_MT6370 + help + This enables support for Mediatek MT6370 Backlight driver. + It's commonly used to drive the display WLED. There are 4 channels + inside, and each channel supports up to 30mA of current capability + with 2048 current steps in exponential or linear mapping curves. + + This driver can also be built as a module. If so, the module + will be called "mt6370-backlight". + config BACKLIGHT_APPLE tristate "Apple Backlight Driver" depends on X86 && ACPI diff --git a/drivers/video/backlight/Makefile b/drivers/video/backlight/Makefile index cae2c83..e815f3f 100644 --- a/drivers/video/backlight/Makefile +++ b/drivers/video/backlight/Makefile @@ -44,6 +44,7 @@ obj-$(CONFIG_BACKLIGHT_LP855X) += lp855x_bl.o obj-$(CONFIG_BACKLIGHT_LP8788) += lp8788_bl.o obj-$(CONFIG_BACKLIGHT_LV5207LP) += lv5207lp.o obj-$(CONFIG_BACKLIGHT_MAX8925) += max8925_bl.o +obj-$(CONFIG_BACKLIGHT_MT6370) += mt6370-backlight.o obj-$(CONFIG_BACKLIGHT_OMAP1) += omap1_bl.o obj-$(CONFIG_BACKLIGHT_PANDORA) += pandora_bl.o obj-$(CONFIG_BACKLIGHT_PCF50633) += pcf50633-backlight.o diff --git a/drivers/video/backlight/mt6370-backlight.c b/drivers/video/backlight/mt6370-backlight.c new file mode 100644 index 0000000..ba00a8f --- /dev/null +++ b/drivers/video/backlight/mt6370-backlight.c @@ -0,0 +1,339 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* + * Copyright (C) 2022 Richtek Technology Corp. + * + * Author: ChiaEn Wu <chiaen_wu@richtek.com> + */ + +#include <linux/backlight.h> +#include <linux/bitfield.h> +#include <linux/bits.h> +#include <linux/gpio/consumer.h> +#include <linux/kernel.h> +#include <linux/minmax.h> +#include <linux/mod_devicetable.h> +#include <linux/module.h> +#include <linux/platform_device.h> +#include <linux/regmap.h> + +#define MT6370_REG_DEV_INFO 0x100 +#define MT6370_REG_BL_EN 0x1A0 +#define MT6370_REG_BL_BSTCTRL 0x1A1 +#define MT6370_REG_BL_PWM 0x1A2 +#define MT6370_REG_BL_DIM2 0x1A4 + +#define MT6370_VENID_MASK GENMASK(7, 4) +#define MT6370_BL_EXT_EN_MASK BIT(7) +#define MT6370_BL_EN_MASK BIT(6) +#define MT6370_BL_CONFIG_MASK BIT(0) +#define MT6370_BL_CH_MASK GENMASK(5, 2) +#define MT6370_BL_DIM2_MASK GENMASK(2, 0) +#define MT6370_BL_DUMMY_6372_MASK GENMASK(2, 0) +#define MT6370_BL_DIM2_6372_SHIFT 3 +#define MT6370_BL_PWM_EN_MASK BIT(7) +#define MT6370_BL_PWM_HYS_EN_MASK BIT(2) +#define MT6370_BL_PWM_HYS_SEL_MASK GENMASK(1, 0) +#define MT6370_BL_OVP_EN_MASK BIT(7) +#define MT6370_BL_OVP_SEL_MASK GENMASK(6, 5) +#define MT6370_BL_OC_EN_MASK BIT(3) +#define MT6370_BL_OC_SEL_MASK GENMASK(2, 1) + +#define MT6370_BL_PWM_HYS_TH_MIN_STEP 1 +#define MT6370_BL_PWM_HYS_TH_MAX_STEP 64 +#define MT6370_BL_OVP_MIN_UV 17000000 +#define MT6370_BL_OVP_MAX_UV 29000000 +#define MT6370_BL_OVP_STEP_UV 4000000 +#define MT6370_BL_OCP_MIN_UA 900000 +#define MT6370_BL_OCP_MAX_UA 1800000 +#define MT6370_BL_OCP_STEP_UA 300000 +#define MT6370_BL_MAX_BRIGHTNESS 2048 +#define MT6370_BL_MAX_CH 15 + +enum { + MT6370_VID_COMMON = 0, + MT6370_VID_6372, +}; + +struct mt6370_priv { + int vid_type; + struct backlight_device *bl; + struct device *dev; + struct gpio_desc *enable_gpio; + struct regmap *regmap; +}; + +static int mt6370_bl_update_status(struct backlight_device *bl_dev) +{ + struct mt6370_priv *priv = bl_get_data(bl_dev); + int brightness = backlight_get_brightness(bl_dev); + unsigned int enable_val; + u8 brightness_val[2]; + int ret; + + if (brightness) { + brightness_val[0] = (brightness - 1) & MT6370_BL_DIM2_MASK; + brightness_val[1] = (brightness - 1) >> fls(MT6370_BL_DIM2_MASK); + + /* + * To make MT6372 using 14 bits to control the brightness + * backward compatible with 11 bits brightness control + * (like MT6370 and MT6371 do), we left shift the value + * and pad with 1 to remaining bits. Hence, the MT6372's + * backlight brightness will be almost the same as MT6370's + * and MT6371's. + */ + if (priv->vid_type == MT6370_VID_6372) { + brightness_val[0] <<= MT6370_BL_DIM2_6372_SHIFT; + brightness_val[0] |= MT6370_BL_DUMMY_6372_MASK; + } + + ret = regmap_raw_write(priv->regmap, MT6370_REG_BL_DIM2, + brightness_val, sizeof(brightness_val)); + if (ret) + return ret; + } + + gpiod_set_value(priv->enable_gpio, brightness ? 1 : 0); + + enable_val = brightness ? MT6370_BL_EN_MASK : 0; + return regmap_update_bits(priv->regmap, MT6370_REG_BL_EN, + MT6370_BL_EN_MASK, enable_val); +} + +static int mt6370_bl_get_brightness(struct backlight_device *bl_dev) +{ + struct mt6370_priv *priv = bl_get_data(bl_dev); + unsigned int enable; + u8 brightness_val[2]; + int brightness, ret; + + ret = regmap_read(priv->regmap, MT6370_REG_BL_EN, &enable); + if (ret) + return ret; + + if (!(enable & MT6370_BL_EN_MASK)) + return 0; + + ret = regmap_raw_read(priv->regmap, MT6370_REG_BL_DIM2, + brightness_val, sizeof(brightness_val)); + if (ret) + return ret; + + if (priv->vid_type == MT6370_VID_6372) + brightness_val[0] >>= MT6370_BL_DIM2_6372_SHIFT; + + brightness = brightness_val[1] << fls(MT6370_BL_DIM2_MASK); + brightness += brightness_val[0] & MT6370_BL_DIM2_MASK; + + return brightness + 1; +} + +static const struct backlight_ops mt6370_bl_ops = { + .options = BL_CORE_SUSPENDRESUME, + .update_status = mt6370_bl_update_status, + .get_brightness = mt6370_bl_get_brightness, +}; + +static int mt6370_init_backlight_properties(struct mt6370_priv *priv, + struct backlight_properties *props) +{ + struct device *dev = priv->dev; + u8 prop_val; + u32 brightness, ovp_uV, ocp_uA; + unsigned int mask, val; + int ret; + + /* Vendor optional properties */ + val = 0; + if (device_property_read_bool(dev, "mediatek,bled-pwm-enable")) + val |= MT6370_BL_PWM_EN_MASK; + + if (device_property_read_bool(dev, "mediatek,bled-pwm-hys-enable")) + val |= MT6370_BL_PWM_HYS_EN_MASK; + + ret = device_property_read_u8(dev, + "mediatek,bled-pwm-hys-input-th-steps", + &prop_val); + if (!ret) { + prop_val = clamp_val(prop_val, + MT6370_BL_PWM_HYS_TH_MIN_STEP, + MT6370_BL_PWM_HYS_TH_MAX_STEP); + prop_val = prop_val <= 1 ? 0 : + prop_val <= 4 ? 1 : + prop_val <= 16 ? 2 : 3; + val |= prop_val << (ffs(MT6370_BL_PWM_HYS_SEL_MASK) - 1); + } + + ret = regmap_update_bits(priv->regmap, MT6370_REG_BL_PWM, + val, val); + if (ret) + return ret; + + val = 0; + if (device_property_read_bool(dev, "mediatek,bled-ovp-shutdown")) + val |= MT6370_BL_OVP_EN_MASK; + + ret = device_property_read_u32(dev, "mediatek,bled-ovp-microvolt", + &ovp_uV); + if (!ret) { + ovp_uV = clamp_val(ovp_uV, MT6370_BL_OVP_MIN_UV, + MT6370_BL_OVP_MAX_UV); + ovp_uV = DIV_ROUND_UP(ovp_uV - MT6370_BL_OVP_MIN_UV, + MT6370_BL_OVP_STEP_UV); + val |= ovp_uV << (ffs(MT6370_BL_OVP_SEL_MASK) - 1); + } + + if (device_property_read_bool(dev, "mediatek,bled-ocp-shutdown")) + val |= MT6370_BL_OC_EN_MASK; + + ret = device_property_read_u32(dev, "mediatek,bled-ocp-microamp", + &ocp_uA); + if (!ret) { + ocp_uA = clamp_val(ocp_uA, MT6370_BL_OCP_MIN_UA, + MT6370_BL_OCP_MAX_UA); + ocp_uA = DIV_ROUND_UP(ocp_uA - MT6370_BL_OCP_MIN_UA, + MT6370_BL_OCP_STEP_UA); + val |= ocp_uA << (ffs(MT6370_BL_OC_SEL_MASK) - 1); + } + + ret = regmap_update_bits(priv->regmap, MT6370_REG_BL_BSTCTRL, + val, val); + if (ret) + return ret; + + /* Common properties */ + ret = device_property_read_u32(dev, "max-brightness", &brightness); + if (ret) + brightness = MT6370_BL_MAX_BRIGHTNESS; + + props->max_brightness = min_t(u32, brightness, MT6370_BL_MAX_BRIGHTNESS); + + ret = device_property_read_u32(dev, "default-brightness", &brightness); + if (ret) + brightness = props->max_brightness; + + props->brightness = min_t(u32, brightness, props->max_brightness); + + ret = device_property_read_u8(dev, "mediatek,bled-channel-use", + &prop_val); + if (ret) { + dev_err(dev, "mediatek,bled-channel-use DT property missing\n"); + return ret; + } + + if (!prop_val || prop_val > MT6370_BL_MAX_CH) { + dev_err(dev, + "No channel specified or over than upper bound (%d)\n", + prop_val); + return -EINVAL; + } + + mask = MT6370_BL_EXT_EN_MASK | MT6370_BL_CH_MASK; + val = prop_val << (ffs(MT6370_BL_CH_MASK) - 1); + + if (priv->enable_gpio) + val |= MT6370_BL_EXT_EN_MASK; + + return regmap_update_bits(priv->regmap, MT6370_REG_BL_EN, mask, val); +} + +static int mt6370_check_vendor_info(struct mt6370_priv *priv) +{ + /* + * MT6372 uses 14 bits to control the brightness but MT6370 and MT6371 + * use 11 bits. They are different so we have to use this function to + * check the vendor ID and use different methods to calculate the + * brightness. + */ + unsigned int dev_info, vid; + int ret; + + ret = regmap_read(priv->regmap, MT6370_REG_DEV_INFO, &dev_info); + if (ret) + return ret; + + vid = FIELD_GET(MT6370_VENID_MASK, dev_info); + if (vid == 0x9 || vid == 0xb) + priv->vid_type = MT6370_VID_6372; + else + priv->vid_type = MT6370_VID_COMMON; + + return 0; +} + +static int mt6370_bl_probe(struct platform_device *pdev) +{ + struct backlight_properties props = { + .type = BACKLIGHT_RAW, + .scale = BACKLIGHT_SCALE_LINEAR, + }; + struct device *dev = &pdev->dev; + struct mt6370_priv *priv; + int ret; + + priv = devm_kzalloc(&pdev->dev, sizeof(*priv), GFP_KERNEL); + if (!priv) + return -ENOMEM; + + priv->dev = dev; + + priv->regmap = dev_get_regmap(dev->parent, NULL); + if (!priv->regmap) + return dev_err_probe(dev, -ENODEV, "Failed to get regmap\n"); + + ret = mt6370_check_vendor_info(priv); + if (ret) + return dev_err_probe(dev, ret, "Failed to check vendor info\n"); + + priv->enable_gpio = devm_gpiod_get_optional(dev, "enable", + GPIOD_OUT_HIGH); + if (IS_ERR(priv->enable_gpio)) + dev_err(dev, "Failed to get 'enable' gpio\n"); + + ret = mt6370_init_backlight_properties(priv, &props); + if (ret) + return dev_err_probe(dev, ret, + "Failed to init backlight properties\n"); + + priv->bl = devm_backlight_device_register(dev, pdev->name, dev, priv, + &mt6370_bl_ops, &props); + if (IS_ERR(priv->bl)) + return dev_err_probe(dev, PTR_ERR(priv->bl), + "Failed to register backlight\n"); + + backlight_update_status(priv->bl); + platform_set_drvdata(pdev, priv); + + return 0; +} + +static int mt6370_bl_remove(struct platform_device *pdev) +{ + struct mt6370_priv *priv = platform_get_drvdata(pdev); + struct backlight_device *bl_dev = priv->bl; + + bl_dev->props.brightness = 0; + backlight_update_status(priv->bl); + + return 0; +} + +static const struct of_device_id __maybe_unused mt6370_bl_of_match[] = { + { .compatible = "mediatek,mt6370-backlight", }, + {} +}; +MODULE_DEVICE_TABLE(of, mt6370_bl_of_match); + +static struct platform_driver mt6370_bl_driver = { + .driver = { + .name = "mt6370-backlight", + .of_match_table = mt6370_bl_of_match, + }, + .probe = mt6370_bl_probe, + .remove = mt6370_bl_remove, +}; +module_platform_driver(mt6370_bl_driver); + +MODULE_AUTHOR("ChiaEn Wu <chiaen_wu@richtek.com>"); +MODULE_DESCRIPTION("MediaTek MT6370 Backlight Driver"); +MODULE_LICENSE("GPL v2");