123 lines
3.3 KiB
C
123 lines
3.3 KiB
C
// SPDX-License-Identifier: GPL-2.0
|
|
/*
|
|
* Copyright (c) 2019 MediaTek Inc.
|
|
* Author: Samuel Hsieh <samuel.hsieh@mediatek.com>
|
|
*/
|
|
|
|
#include <linux/module.h>
|
|
#include <linux/of.h>
|
|
#include <linux/platform_device.h>
|
|
#include "mtk_ccci_common.h"
|
|
#include "mtk_md_power_throttling.h"
|
|
#include "mtk_low_battery_throttling.h"
|
|
#include "mtk_battery_oc_throttling.h"
|
|
|
|
#define MD_TX_REDUCE 6
|
|
|
|
struct md_priv {
|
|
u32 lbat_md_reduce_tx;
|
|
u32 oc_md_reduce_tx;
|
|
};
|
|
|
|
static struct md_priv md_priv;
|
|
static int isThreeLevel;
|
|
|
|
#if IS_ENABLED(CONFIG_MTK_LOW_BATTERY_POWER_THROTTLING)
|
|
static void md_pt_low_battery_cb(enum LOW_BATTERY_LEVEL_TAG level)
|
|
{
|
|
unsigned int md_throttle_cmd;
|
|
int ret, intensity = 0;
|
|
|
|
if (isThreeLevel) {
|
|
if (level != LOW_BATTERY_LEVEL_0 && level != LOW_BATTERY_LEVEL_1)
|
|
intensity = md_priv.lbat_md_reduce_tx;
|
|
} else {
|
|
if (level != LOW_BATTERY_LEVEL_0)
|
|
intensity = md_priv.lbat_md_reduce_tx;
|
|
}
|
|
md_throttle_cmd = TMC_CTRL_CMD_TX_POWER | level << 8 |
|
|
PT_LOW_BATTERY_VOLTAGE << 16 | intensity << 24;
|
|
ret = exec_ccci_kern_func(ID_THROTTLING_CFG, (char *)&md_throttle_cmd, 4);
|
|
if (ret)
|
|
pr_notice("%s: error, ret=%d, cmd=0x%x l=%d\n", __func__, ret,
|
|
md_throttle_cmd, level);
|
|
}
|
|
#endif
|
|
|
|
#if IS_ENABLED(CONFIG_MTK_BATTERY_OC_POWER_THROTTLING)
|
|
static void md_pt_over_current_cb(enum BATTERY_OC_LEVEL_TAG level)
|
|
{
|
|
unsigned int md_throttle_cmd;
|
|
int ret, intensity;
|
|
|
|
if (level <= BATTERY_OC_LEVEL_1) {
|
|
if (level != BATTERY_OC_LEVEL_0)
|
|
intensity = md_priv.oc_md_reduce_tx;
|
|
else
|
|
intensity = 0;
|
|
|
|
md_throttle_cmd = TMC_CTRL_CMD_TX_POWER | level << 8 | PT_OVER_CURRENT << 16 |
|
|
intensity << 24;
|
|
ret = exec_ccci_kern_func(ID_THROTTLING_CFG,
|
|
(char *)&md_throttle_cmd, 4);
|
|
if (ret)
|
|
pr_notice("%s: error, ret=%d, cmd=0x%x l=%d\n", __func__, ret,
|
|
md_throttle_cmd, level);
|
|
}
|
|
}
|
|
#endif
|
|
|
|
static int mtk_md_power_throttling_probe(struct platform_device *pdev)
|
|
{
|
|
struct device_node *np = pdev->dev.of_node;
|
|
int ret;
|
|
|
|
md_priv.lbat_md_reduce_tx = MD_TX_REDUCE;
|
|
md_priv.oc_md_reduce_tx = MD_TX_REDUCE;
|
|
|
|
ret = of_property_read_u32(np, "lbat_md_reduce_tx", &md_priv.lbat_md_reduce_tx);
|
|
if (ret < 0)
|
|
pr_notice("%s: get lbat md tx reduce fail %d\n", __func__, ret);
|
|
|
|
ret = of_property_read_u32(np, "oc_md_reduce_tx", &md_priv.oc_md_reduce_tx);
|
|
if (ret)
|
|
pr_notice("get oc md tx reduce fail ret=%d\n", ret);
|
|
|
|
#if IS_ENABLED(CONFIG_MTK_LOW_BATTERY_POWER_THROTTLING)
|
|
ret = register_low_battery_notify(&md_pt_low_battery_cb, LOW_BATTERY_PRIO_MD);
|
|
if (ret == 3)
|
|
isThreeLevel = 1;
|
|
#endif
|
|
|
|
#if IS_ENABLED(CONFIG_MTK_BATTERY_OC_POWER_THROTTLING)
|
|
register_battery_oc_notify(&md_pt_over_current_cb, BATTERY_OC_PRIO_MD);
|
|
#endif
|
|
|
|
return 0;
|
|
}
|
|
|
|
static int mtk_md_power_throttling_remove(struct platform_device *pdev)
|
|
{
|
|
return 0;
|
|
}
|
|
|
|
static const struct of_device_id md_power_throttling_of_match[] = {
|
|
{ .compatible = "mediatek,md-power-throttling", },
|
|
{},
|
|
};
|
|
MODULE_DEVICE_TABLE(of, md_power_throttling_of_match);
|
|
|
|
static struct platform_driver md_power_throttling_driver = {
|
|
.probe = mtk_md_power_throttling_probe,
|
|
.remove = mtk_md_power_throttling_remove,
|
|
.driver = {
|
|
.name = "mtk-md_power_throttling",
|
|
.of_match_table = md_power_throttling_of_match,
|
|
},
|
|
};
|
|
module_platform_driver(md_power_throttling_driver);
|
|
|
|
|
|
MODULE_AUTHOR("Samuel Hsieh");
|
|
MODULE_DESCRIPTION("MTK modem power throttling driver");
|
|
MODULE_LICENSE("GPL");
|