unplugged-kernel/drivers/misc/mediatek/pmic/mt6370/mt6370_pmu_bled.c

646 lines
18 KiB
C

// SPDX-License-Identifier: GPL-2.0
/*
* Copyright (c) 2019 MediaTek Inc.
*/
#include <linux/module.h>
#include <linux/init.h>
#include <linux/kernel.h>
#include <linux/platform_device.h>
#include <linux/of.h>
#include <linux/leds.h>
#include "../../flashlight/richtek/rtfled.h"
#include "inc/mt6370_pmu.h"
#include "inc/mt6370_pmu_bled.h"
#define MT6370_PMU_BLED_DRV_VERSION "1.0.2_MTK"
struct mt6370_pmu_bled_data {
struct rt_fled_dev base;
struct mt6370_pmu_chip *chip;
struct device *dev;
struct platform_device *mt_flash_dev;
};
static uint8_t bled_init_data[] = {
0x42, /* MT6370_PMU_REG_BLEN */
0x89, /* MT6370_PMU_REG_BLBSTCTRL */
0x00, /* MT6370_PMU_REG_BLPWM */
0x00, /* MT6370_PMU_REG_BLCTRL */
0x00, /* MT6370_PMU_REG_BLDIM2 */
0x00, /* MT6370_PMU_REG_BLDIM1 */
0x00, /* MT6370_PMU_REG_BLAFH */
0x00, /* MT6370_PMU_REG_BLFL */
0x8C, /* MT6370_PMU_REG_BLFLTO */
0x80, /* MT6370_PMU_REG_BLTORCTRL */
0xFF, /* MT6370_PMU_REG_BLSTRBCTRL */
0x00, /* MT6370_PMU_REG_BLAVG */
};
static int mt6370_bled_fled_set_mode(struct rt_fled_dev *fled_dev,
enum flashlight_mode mode)
{
struct mt6370_pmu_bled_data *bled_data =
(struct mt6370_pmu_bled_data *)fled_dev;
int ret = 0;
switch (mode) {
case FLASHLIGHT_MODE_OFF:
ret = mt6370_pmu_reg_update_bits(bled_data->chip,
MT6370_PMU_REG_BLFL, MT6370_BLFLMODE_MASK,
0 << MT6370_BLFLMODE_SHFT);
break;
case FLASHLIGHT_MODE_TORCH:
ret = mt6370_pmu_reg_update_bits(bled_data->chip,
MT6370_PMU_REG_BLFL, MT6370_BLFLMODE_MASK,
2 << MT6370_BLFLMODE_SHFT);
break;
case FLASHLIGHT_MODE_FLASH:
break;
default:
ret = -EINVAL;
break;
}
return ret;
}
static int mt6370_bled_fled_get_mode(struct rt_fled_dev *fled_dev)
{
struct mt6370_pmu_bled_data *bled_data =
(struct mt6370_pmu_bled_data *)fled_dev;
int ret = 0;
ret = mt6370_pmu_reg_read(bled_data->chip, MT6370_PMU_REG_BLFL);
if (ret < 0)
return ret;
ret &= MT6370_BLFLMODE_MASK;
ret >>= MT6370_BLFLMODE_SHFT;
switch (ret) {
case 0:
ret = FLASHLIGHT_MODE_OFF;
break;
case 1:
ret = FLASHLIGHT_MODE_FLASH;
break;
case 2:
case 3:
ret = FLASHLIGHT_MODE_TORCH;
break;
default:
ret = -EINVAL;
break;
}
return ret;
}
static int mt6370_bled_fled_strobe(struct rt_fled_dev *fled_dev)
{
struct mt6370_pmu_bled_data *bled_data =
(struct mt6370_pmu_bled_data *)fled_dev;
int ret = 0;
ret = mt6370_bled_fled_set_mode(fled_dev, FLASHLIGHT_MODE_OFF);
if (ret < 0)
return ret;
return mt6370_pmu_reg_update_bits(bled_data->chip,
MT6370_PMU_REG_BLFL, MT6370_BLFLMODE_MASK,
1 << MT6370_BLFLMODE_SHFT);
}
static int mt6370_bled_fled_torch_current_list(struct rt_fled_dev *fled_dev,
int selector)
{
if (selector >= 256)
return -EINVAL;
return 117 * selector;
}
static int mt6370_bled_fled_strobe_current_list(struct rt_fled_dev *fled_dev,
int selector)
{
if (selector >= 256)
return -EINVAL;
return 117 * selector;
}
static int mt6370_bled_fled_timeout_level_list(struct rt_fled_dev *fled_dev,
int selector)
{
return -EINVAL;
}
static int mt6370_bled_fled_lv_protection_list(struct rt_fled_dev *fled_dev,
int selector)
{
return -EINVAL;
}
static int mt6370_bled_fled_strobe_timeout_list(struct rt_fled_dev *fled_dev,
int selector)
{
if (selector >= 128)
return -EINVAL;
return 16 * selector;
}
static int mt6370_bled_fled_set_torch_current_sel(struct rt_fled_dev *fled_dev,
int selector)
{
struct mt6370_pmu_bled_data *bled_data =
(struct mt6370_pmu_bled_data *)fled_dev;
if (selector >= 256)
return -EINVAL;
return mt6370_pmu_reg_write(bled_data->chip,
MT6370_PMU_REG_BLTORCTRL, selector);
}
static int mt6370_bled_fled_set_strobe_current_sel(struct rt_fled_dev *fled_dev,
int selector)
{
struct mt6370_pmu_bled_data *bled_data =
(struct mt6370_pmu_bled_data *)fled_dev;
if (selector >= 256)
return -EINVAL;
return mt6370_pmu_reg_write(bled_data->chip,
MT6370_PMU_REG_BLSTRBCTRL, selector);
}
static int mt6370_bled_fled_set_timeout_level_sel(struct rt_fled_dev *fled_dev,
int selector)
{
return -EINVAL;
}
static int mt6370_bled_fled_set_lv_protection_sel(struct rt_fled_dev *fled_dev,
int selector)
{
return -EINVAL;
}
static int mt6370_bled_fled_set_strobe_timeout_sel(struct rt_fled_dev *fled_dev,
int selector)
{
struct mt6370_pmu_bled_data *bled_data =
(struct mt6370_pmu_bled_data *)fled_dev;
if (selector >= 128)
return -EINVAL;
return mt6370_pmu_reg_update_bits(bled_data->chip,
MT6370_PMU_REG_BLFLTO, MT6370_BLSTRB_TOMASK, selector);
}
static int mt6370_bled_fled_get_torch_current_sel(struct rt_fled_dev *fled_dev)
{
struct mt6370_pmu_bled_data *bled_data =
(struct mt6370_pmu_bled_data *)fled_dev;
return mt6370_pmu_reg_read(bled_data->chip, MT6370_PMU_REG_BLTORCTRL);
}
static int mt6370_bled_fled_get_strobe_current_sel(struct rt_fled_dev *fled_dev)
{
struct mt6370_pmu_bled_data *bled_data =
(struct mt6370_pmu_bled_data *)fled_dev;
return mt6370_pmu_reg_read(bled_data->chip, MT6370_PMU_REG_BLSTRBCTRL);
}
static int mt6370_bled_fled_get_timeout_level_sel(struct rt_fled_dev *fled_dev)
{
return -EINVAL;
}
static int mt6370_bled_fled_get_lv_protection_sel(struct rt_fled_dev *fled_dev)
{
return -EINVAL;
}
static int mt6370_bled_fled_get_strobe_timeout_sel(struct rt_fled_dev *fled_dev)
{
struct mt6370_pmu_bled_data *bled_data =
(struct mt6370_pmu_bled_data *)fled_dev;
int ret = 0;
ret = mt6370_pmu_reg_read(bled_data->chip, MT6370_PMU_REG_BLFLTO);
return (ret < 0 ? ret : ret & MT6370_BLSTRB_TOMASK);
}
static void mt6370_bled_fled_shutdown(struct rt_fled_dev *fled_dev)
{
mt6370_bled_fled_set_mode(fled_dev, FLASHLIGHT_MODE_OFF);
}
static struct rt_fled_hal mt6370_bledfl_hal = {
.rt_hal_fled_set_mode = mt6370_bled_fled_set_mode,
.rt_hal_fled_get_mode = mt6370_bled_fled_get_mode,
.rt_hal_fled_strobe = mt6370_bled_fled_strobe,
.rt_hal_fled_torch_current_list = mt6370_bled_fled_torch_current_list,
.rt_hal_fled_strobe_current_list = mt6370_bled_fled_strobe_current_list,
.rt_hal_fled_timeout_level_list = mt6370_bled_fled_timeout_level_list,
.rt_hal_fled_lv_protection_list = mt6370_bled_fled_lv_protection_list,
.rt_hal_fled_strobe_timeout_list = mt6370_bled_fled_strobe_timeout_list,
.rt_hal_fled_set_torch_current_sel =
mt6370_bled_fled_set_torch_current_sel,
.rt_hal_fled_set_strobe_current_sel =
mt6370_bled_fled_set_strobe_current_sel,
.rt_hal_fled_set_timeout_level_sel =
mt6370_bled_fled_set_timeout_level_sel,
.rt_hal_fled_set_lv_protection_sel =
mt6370_bled_fled_set_lv_protection_sel,
.rt_hal_fled_set_strobe_timeout_sel =
mt6370_bled_fled_set_strobe_timeout_sel,
.rt_hal_fled_get_torch_current_sel =
mt6370_bled_fled_get_torch_current_sel,
.rt_hal_fled_get_strobe_current_sel =
mt6370_bled_fled_get_strobe_current_sel,
.rt_hal_fled_get_timeout_level_sel =
mt6370_bled_fled_get_timeout_level_sel,
.rt_hal_fled_get_lv_protection_sel =
mt6370_bled_fled_get_lv_protection_sel,
.rt_hal_fled_get_strobe_timeout_sel =
mt6370_bled_fled_get_strobe_timeout_sel,
.rt_hal_fled_shutdown = mt6370_bled_fled_shutdown,
};
static const struct flashlight_properties mt6370_bledfl_props = {
.type = FLASHLIGHT_TYPE_LED,
.torch_brightness = 128, /* default torch brightness 15mA */
.torch_max_brightness = 255,
.strobe_brightness = 255, /* default strobe brightness 30mA */
.strobe_max_brightness = 255,
.strobe_timeout = 208, /* default strobe timeout 208mS */
.alias_name = "mt6370_pmu_bled",
};
static void mt6370_pmu_bled_bright_set(struct led_classdev *led_cdev,
enum led_brightness brightness)
{
struct mt6370_pmu_bled_data *bled_data =
dev_get_drvdata(led_cdev->dev->parent);
struct mt6370_pmu_bled_platdata *pdata =
dev_get_platdata(bled_data->dev);
uint8_t chip_vid = bled_data->chip->chip_vid;
uint32_t bright = (pdata->max_bled_brightness << 8) / 255;
int ret = 0;
dev_dbg(led_cdev->dev, "%s: %d\n", __func__, brightness);
bright = (bright * brightness) >> 8;
if (chip_vid == MT6372_VENDOR_ID || chip_vid == MT6372C_VENDOR_ID)
ret = mt6370_pmu_reg_update_bits(bled_data->chip,
MT6370_PMU_REG_BLDIM2,
0x3F,
(bright & 0x7) << 3);
else
ret = mt6370_pmu_reg_update_bits(bled_data->chip,
MT6370_PMU_REG_BLDIM2,
MT6370_DIM2_MASK,
(bright & 0x7));
if (ret < 0)
goto out_bright_set;
ret = mt6370_pmu_reg_write(bled_data->chip, MT6370_PMU_REG_BLDIM1,
(bright >> 3) & MT6370_DIM_MASK);
if (ret < 0)
goto out_bright_set;
/* if choose external enable pin, no effect even config this bit */
ret = mt6370_pmu_reg_update_bits(bled_data->chip, MT6370_PMU_REG_BLEN,
MT6370_BLED_EN,
brightness > 0 ?
MT6370_BLED_EN : ~MT6370_BLED_EN);
if (ret < 0)
goto out_bright_set;
return;
out_bright_set:
dev_err(led_cdev->dev, "%s error %d\n", __func__, ret);
}
static struct led_classdev mt6370_pmu_bled_dev = {
.name = "mt6370_pmu_bled",
.brightness_set = mt6370_pmu_bled_bright_set,
};
static irqreturn_t mt6370_pmu_bled_ocp_irq_handler(int irq, void *data)
{
struct mt6370_pmu_bled_data *bled_data = data;
dev_notice(bled_data->dev, "%s\n", __func__);
return IRQ_HANDLED;
}
static irqreturn_t mt6370_pmu_bled_ovp_irq_handler(int irq, void *data)
{
struct mt6370_pmu_bled_data *bled_data = data;
dev_notice(bled_data->dev, "%s\n", __func__);
return IRQ_HANDLED;
}
static struct mt6370_pmu_irq_desc mt6370_bled_irq_desc[] = {
MT6370_PMU_IRQDESC(bled_ocp),
MT6370_PMU_IRQDESC(bled_ovp),
};
static void mt6370_pmu_bled_irq_register(struct platform_device *pdev)
{
struct resource *res;
int i, ret = 0;
for (i = 0; i < ARRAY_SIZE(mt6370_bled_irq_desc); i++) {
if (!mt6370_bled_irq_desc[i].name)
continue;
res = platform_get_resource_byname(pdev, IORESOURCE_IRQ,
mt6370_bled_irq_desc[i].name);
if (!res)
continue;
ret = devm_request_threaded_irq(&pdev->dev, res->start, NULL,
mt6370_bled_irq_desc[i].irq_handler,
IRQF_TRIGGER_FALLING,
mt6370_bled_irq_desc[i].name,
platform_get_drvdata(pdev));
if (ret < 0) {
dev_err(&pdev->dev, "request %s irq fail\n", res->name);
continue;
}
mt6370_bled_irq_desc[i].irq = res->start;
}
}
static int mt6370_pmu_bled_init_blmode_ctrl(
struct mt6370_pmu_bled_data *bled_data)
{
struct mt6370_pmu_bled_platdata *pdata = dev_get_platdata(
bled_data->dev);
u8 data = 0;
data |= (pdata->bled_curr_scale
<< MT6370_BLED_CURR_SCALESHFT);
data |= (pdata->pwm_lpf_coef << MT6370_PWM_LPF_COEFSHFT);
data |= (pdata->pwm_lpf_en << MT6370_PWM_LPF_ENSHFT);
data |= (pdata->bled_curr_mode
<< MT6370_BLED_CURR_MODESHFT);
return mt6370_pmu_reg_write(bled_data->chip,
MT6370_PMU_REG_BLMODECTRL, data);
}
static inline int mt6370_pmu_bled_init_register(
struct mt6370_pmu_bled_data *bled_data)
{
int ret = 0;
if (bled_data->chip->chip_rev <= 1)
bled_init_data[1] |= MT6370_BLED_OVOCSHDNDIS;
ret = mt6370_pmu_reg_block_write(bled_data->chip, MT6370_PMU_REG_BLEN,
ARRAY_SIZE(bled_init_data), bled_init_data);
ret |= mt6370_pmu_bled_init_blmode_ctrl(bled_data);
return ret;
}
static inline int mt6370_pmu_bled_parse_initdata(
struct mt6370_pmu_bled_data *bled_data)
{
struct mt6370_pmu_bled_platdata *pdata = dev_get_platdata(
bled_data->dev);
uint8_t chip_vid = bled_data->chip->chip_vid;
uint32_t bright = (pdata->max_bled_brightness << 8) / 255;
if (pdata->ext_en_pin) {
bled_init_data[0] &= ~(MT6370_BLED_EN | MT6370_BLED_EXTEN);
bled_init_data[0] |= MT6370_BLED_EXTEN;
}
bled_init_data[0] |= (pdata->chan_en << MT6370_BLED_CHANENSHFT);
if (!pdata->map_linear)
bled_init_data[0] &= ~(MT6370_BLED_MAPLINEAR);
bled_init_data[1] |= (pdata->bl_ovp_level << MT6370_BLED_OVPSHFT);
bled_init_data[1] |= (pdata->bl_ocp_level << MT6370_BLED_OCPSHFT);
bled_init_data[2] |= (pdata->use_pwm << MT6370_BLED_PWMSHIFT);
bled_init_data[2] |= (pdata->pwm_fsample << MT6370_BLED_PWMFSHFT);
bled_init_data[2] |= (pdata->pwm_deglitch << MT6370_BLED_PWMDSHFT);
bled_init_data[2] |= (pdata->pwm_hys_en << MT6370_BLED_PWMHESHFT);
bled_init_data[2] |= (pdata->pwm_hys << MT6370_BLED_PWMHSHFT);
bled_init_data[3] |= (pdata->bled_ramptime << MT6370_BLED_RAMPTSHFT);
bright = (bright * 255) >> 8;
/* Set bled dimension 11 or 14 bits */
if (chip_vid == MT6372_VENDOR_ID || chip_vid == MT6372C_VENDOR_ID)
bled_init_data[4] |= ((bright & 0x7) << 3);
else
bled_init_data[4] |= (bright & 0x7);
bled_init_data[5] |= ((bright >> 3) & 0xFF);
bled_init_data[7] |= (pdata->bled_flash_ramp << MT6370_BLFLRAMP_SHFT);
bled_init_data[10] |= (pdata->pwm_avg_cycle);
if (pdata->bled_name)
mt6370_pmu_bled_dev.name = pdata->bled_name;
return 0;
}
static inline int mt_parse_dt(struct device *dev)
{
struct mt6370_pmu_bled_platdata *pdata = dev_get_platdata(dev);
struct device_node *np = dev->of_node;
const char *name;
u32 tmp = 0;
if (of_property_read_bool(np, "mt,ext_en_pin"))
pdata->ext_en_pin = 1;
if (of_property_read_u32(np, "mt,chan_en", &tmp) < 0)
pdata->chan_en = 0x0; /* default 4 channel disable */
else
pdata->chan_en = tmp;
if (of_property_read_bool(np, "mt,map_linear"))
pdata->map_linear = 1;
if (of_property_read_u32(np, "mt,bl_ovp_level", &tmp) < 0)
pdata->bl_ovp_level = 0x3; /* default 29V */
else
pdata->bl_ovp_level = tmp;
if (of_property_read_u32(np, "mt,bl_ocp_level", &tmp) < 0)
pdata->bl_ocp_level = 0x2; /* default 1500mA */
else
pdata->bl_ocp_level = tmp;
if (of_property_read_bool(np, "mt,use_pwm"))
pdata->use_pwm = 1;
if (of_property_read_u32(np, "mt,pwm_fsample", &tmp) < 0)
pdata->pwm_fsample = 0x1; /* 4MHz */
else
pdata->pwm_fsample = tmp;
if (of_property_read_u32(np, "mt,pwm_deglitch", &tmp) < 0)
pdata->pwm_deglitch = 0x1;
else
pdata->pwm_deglitch = tmp;
if (of_property_read_u32(np, "mt,pwm_hys_en", &tmp) < 0)
pdata->pwm_hys_en = 0x1;
else
pdata->pwm_hys_en = tmp;
if (of_property_read_u32(np, "mt,pwm_hys", &tmp) < 0)
pdata->pwm_hys = 0x0; /* 1 bit */
else
pdata->pwm_hys = tmp;
if (of_property_read_u32(np, "mt,pwm_avg_cycle", &tmp) < 0)
pdata->pwm_avg_cycle = 0;
else
pdata->pwm_avg_cycle = tmp;
if (of_property_read_u32(np, "mt,bled_ramptime", &tmp) < 0)
pdata->bled_ramptime = 0x3; /* default 1ms */
else
pdata->bled_ramptime = tmp;
if (of_property_read_u32(np, "mt,bled_flash_ramp", &tmp) < 0)
pdata->bled_flash_ramp = 0x1;
else
pdata->bled_flash_ramp = tmp;
if (of_property_read_u32(np, "mt,max_bled_brightness", &tmp) < 0)
pdata->max_bled_brightness = 1024;
else
pdata->max_bled_brightness = tmp;
if (of_property_read_u32(np, "mt,bled_curr_scale", &tmp) < 0)
pdata->bled_curr_scale = 0x0;
else
pdata->bled_curr_scale = tmp;
pr_info("bled_curr_scale = %d\n", pdata->bled_curr_scale);
if (of_property_read_u32(np, "mt,pwm_lpf_coef", &tmp) < 0)
pdata->pwm_lpf_coef = 0x0;
else
pdata->pwm_lpf_coef = tmp;
if (of_property_read_bool(np, "mt,pwm_lpf_en"))
pdata->pwm_lpf_en = 1;
if (of_property_read_bool(np, "mt,bled_curr_mode"))
pdata->bled_curr_mode = 1;
if (of_property_read_string(np, "mt,bled_name", &name) < 0)
pdata->bled_name = "mt6370_pmu_bled";
else
pdata->bled_name = name;
return 0;
}
static int mt6370_pmu_bled_probe(struct platform_device *pdev)
{
struct mt6370_pmu_bled_platdata *pdata = dev_get_platdata(&pdev->dev);
struct mt6370_pmu_bled_data *bled_data;
bool use_dt = pdev->dev.of_node;
int ret = 0;
pr_info("%s: (%s)\n", __func__, MT6370_PMU_BLED_DRV_VERSION);
bled_data = devm_kzalloc(&pdev->dev, sizeof(*bled_data), GFP_KERNEL);
if (!bled_data)
return -ENOMEM;
if (use_dt) {
/* DTS used */
pdata = devm_kzalloc(&pdev->dev, sizeof(*pdata), GFP_KERNEL);
if (!pdata) {
ret = -ENOMEM;
goto out_pdata;
}
pdev->dev.platform_data = pdata;
ret = mt_parse_dt(&pdev->dev);
if (ret < 0) {
devm_kfree(&pdev->dev, pdata);
goto out_pdata;
}
} else {
if (!pdata) {
ret = -EINVAL;
goto out_pdata;
}
}
bled_data->chip = dev_get_drvdata(pdev->dev.parent);
bled_data->dev = &pdev->dev;
platform_set_drvdata(pdev, bled_data);
ret = mt6370_pmu_bled_parse_initdata(bled_data);
if (ret < 0)
goto out_init_data;
ret = mt6370_pmu_bled_init_register(bled_data);
if (ret < 0)
goto out_init_reg;
if (pdata->use_pwm)
mt6370_pmu_bled_dev.default_trigger = "backlight";
mt6370_pmu_bled_dev.brightness = LED_FULL;
ret = led_classdev_register(bled_data->dev, &mt6370_pmu_bled_dev);
if (ret < 0) {
dev_err(&pdev->dev, "register leddev fail\n");
goto out_led_register;
}
bled_data->base.init_props = &mt6370_bledfl_props;
bled_data->base.hal = &mt6370_bledfl_hal;
bled_data->base.name = kstrndup(pdata->bled_name,
strlen(pdata->bled_name), GFP_KERNEL);
bled_data->base.chip_name = "mt6370_pmu_bled";
bled_data->mt_flash_dev =
platform_device_register_resndata(bled_data->dev,
"rt-flash-led", 2, NULL, 0,
NULL, 0);
if (IS_ERR(bled_data->mt_flash_dev)) {
dev_err(&pdev->dev, "register mt_flash_dev fail\n");
goto out_mt_flash_register;
}
mt6370_pmu_bled_irq_register(pdev);
dev_info(&pdev->dev, "%s successfully\n", __func__);
return 0;
out_mt_flash_register:
led_classdev_unregister(&mt6370_pmu_bled_dev);
out_led_register:
out_init_reg:
out_init_data:
out_pdata:
devm_kfree(&pdev->dev, bled_data);
return ret;
}
static int mt6370_pmu_bled_remove(struct platform_device *pdev)
{
struct mt6370_pmu_bled_data *bled_data = platform_get_drvdata(pdev);
platform_device_unregister(bled_data->mt_flash_dev);
led_classdev_unregister(&mt6370_pmu_bled_dev);
dev_info(bled_data->dev, "%s successfully\n", __func__);
return 0;
}
static const struct of_device_id mt_ofid_table[] = {
{ .compatible = "mediatek,mt6370_pmu_bled", },
{ },
};
MODULE_DEVICE_TABLE(of, mt_ofid_table);
static const struct platform_device_id mt_id_table[] = {
{ "mt6370_pmu_bled", 0},
{ },
};
MODULE_DEVICE_TABLE(platform, mt_id_table);
static struct platform_driver mt6370_pmu_bled = {
.driver = {
.name = "mt6370_pmu_bled",
.owner = THIS_MODULE,
.of_match_table = of_match_ptr(mt_ofid_table),
},
.probe = mt6370_pmu_bled_probe,
.remove = mt6370_pmu_bled_remove,
.id_table = mt_id_table,
};
module_platform_driver(mt6370_pmu_bled);
MODULE_LICENSE("GPL v2");
MODULE_DESCRIPTION("MediaTek MT6370 PMU Bled");
MODULE_VERSION(MT6370_PMU_BLED_DRV_VERSION);
/*
* Release Note
* 1.0.2_MTK
* (1) Add support for MT6372
*
* 1.0.1_MTK
* (1) Remove typedef
*
* 1.0.0_MTK
* (1) Initial Release
*/