charging hw bq25601充电驱动笔记
#include "../bq25601.h"
/* ============================================================ // */
/* Define */
/* ============================================================ // */
#define STATUS_OK 0
#define STATUS_FAIL 1
#define STATUS_UNSUPPORTED -1
#define GETARRAYNUM(array) (sizeof(array)/sizeof(array[0]))
/* ============================================================ // */
/* Global variable */
/* ============================================================ // */
const unsigned int VBAT_CV_VTH[] = {//充电电压(下面调用函数会获取最接近的充电电压)
3856000, 3888000, 3920000, 3952000,
3984000, 4016000, 4048000, 4080000,
4112000, 4144000, 4176000, 4208000,
4240000, 4272000, 4304000, 4336000,
4368000, 4400000, 4432000, 4464000,
4496000, 4528000, 4560000, 4592000,
4624000
};
const unsigned int CS_VTH[] = { //充电电流(下面调用函数会获取最接近的充电电流)
0,
6000, 12000, 18000, 24000,
30000, 36000, 42000, 48000,
54000, 60000, 66000, 72000,
78000, 84000, 90000, 96000,
102000, 108000, 114000, 120000,
126000, 132000, 138000, 144000,
150000, 156000, 162000, 168000,
174000, 180000, 186000, 192000,
198000, 204000, 210000, 216000,
222000, 228000, 234000, 240000,
246000, 252000, 258000, 264000,
270000, 276000, 282000, 288000,
294000, 300000
};
const unsigned int INPUT_CS_VTH[] = {//输入电流(下面调用函数会获取最接近的输入电流)
10000, 20000, 30000, 40000,
50000, 60000, 70000, 80000,
90000, 100000, 110000, 120000,
130000, 140000, 150000, 160000,
170000, 180000, 190000, 200000,
210000, 220000, 230000, 240000,
250000, 260000, 270000, 280000,
290000, 300000, 310000, 320000,
CHARGE_CURRENT_MAX
};
const unsigned int VCDT_HV_VTH[] = {高压检测的时的电压 (下面调用函数会获取最接近的高压检测的时的电压,pmic最高支持10.5V的充电电压,超过10.5V会停止充电或者不使能pmic的高压检测功能在static unsigned int charging_hw_init(void *data)函数中加上 pmic_set_register_value(PMIC_RG_VCDT_HV_EN, 0);Pmic high pressure detection is not enabled*/)
BATTERY_VOLT_04_200000_V, BATTERY_VOLT_04_250000_V, BATTERY_VOLT_04_300000_V,
BATTERY_VOLT_04_350000_V,
BATTERY_VOLT_04_400000_V, BATTERY_VOLT_04_450000_V, BATTERY_VOLT_04_500000_V,
BATTERY_VOLT_04_550000_V,
BATTERY_VOLT_04_600000_V, BATTERY_VOLT_06_000000_V, BATTERY_VOLT_06_500000_V,
BATTERY_VOLT_07_000000_V,
BATTERY_VOLT_07_500000_V, BATTERY_VOLT_08_500000_V, BATTERY_VOLT_09_500000_V,
BATTERY_VOLT_10_500000_V
};
#ifdef CONFIG_MTK_DUAL_INPUT_CHARGER_SUPPORT
#ifndef CUST_GPIO_VIN_SEL
#define CUST_GPIO_VIN_SEL 18
#endif
#if !defined(MTK_AUXADC_IRQ_SUPPORT)
#define SW_POLLING_PERIOD 100 /* 100 ms */
#define MSEC_TO_NSEC(x) (x * 1000000UL)
static DEFINE_MUTEX(diso_polling_mutex);
static DECLARE_WAIT_QUEUE_HEAD(diso_polling_thread_wq);
static struct hrtimer diso_kthread_timer;
static kal_bool diso_thread_timeout = KAL_FALSE;
static struct delayed_work diso_polling_work;
static void diso_polling_handler(struct work_struct *work);
static DISO_Polling_Data DISO_Polling;
#endif
int g_diso_state = 0;
int vin_sel_gpio_number = (CUST_GPIO_VIN_SEL | 0x80000000);
static char *DISO_state_s[8] = {
"IDLE",
"OTG_ONLY",
"USB_ONLY",
"USB_WITH_OTG",
"DC_ONLY",
"DC_WITH_OTG",
"DC_WITH_USB",
"DC_USB_OTG",
};
#endif
/* ============================================================ // */
/* function prototype 函数原型*/
/* ============================================================ // */
/* ============================================================ // */
/* extern variable 外部变量*/
/* ============================================================ // */
/* ============================================================ // */
/* extern function 外部函数*/
/* ============================================================ // */
static unsigned int charging_error;
static unsigned int charging_get_error_state(void);
static unsigned int charging_set_error_state(void *data);
/* ============================================================ // */
unsigned int charging_value_to_parameter(const unsigned int *parameter, const unsigned int array_size,
const unsigned int val) //充电值到参数
{
unsigned int temp_param;
if (val < array_size) {
temp_param = parameter[val];
} else {
battery_log(BAT_LOG_CRTI, "Can't find the parameter \r\n");
temp_param = parameter[0];
}
return temp_param;
}
unsigned int charging_parameter_to_value(const unsigned int *parameter, const unsigned int array_size,
const unsigned int val)//充电参数至值
{
unsigned int i;
battery_log(BAT_LOG_FULL, "array_size = %d \r\n", array_size);
for (i = 0; i < array_size; i++) {
if (val == *(parameter + i))
return i;
}
battery_log(BAT_LOG_CRTI, "NO register value match. val=%d\r\n", val);
return 0;
}
static unsigned int bmt_find_closest_level(const unsigned int *pList, unsigned int number,
unsigned int level) //bmt找到最接近的水平
{
unsigned int i, temp_param;
unsigned int max_value_in_last_element;
if (pList[0] < pList[1])
max_value_in_last_element = KAL_TRUE;
else
max_value_in_last_element = KAL_FALSE;
if (max_value_in_last_element == KAL_TRUE) {
/* max value in the last element 最后一个元素的最大值 */
for (i = (number - 1); i != 0; i--) {
if (pList[i] <= level)
return pList[i];
}
battery_log(BAT_LOG_CRTI, "Can't find closest level, small value first \r\n");
temp_param = pList[0];
} else {
/* max value in the first element 第一个元素的最大值*/
for (i = 0; i < number; i++) {
if (pList[i] <= level)
return pList[i];
}
battery_log(BAT_LOG_CRTI, "Can't find closest level, large value first \r\n");
temp_param = pList[number - 1];
}
return temp_param;
}
static unsigned int charging_hw_init(void *data) //充电硬件初始化
{
//一些寄存器的初始化
unsigned int status = STATUS_OK;
bq25601_set_en_hiz(0x0);
bq25601_set_vindpm(0x5); //VIN DPM check 4.4V //VIN DPM 核对是否是4.4V
bq25601_set_reg_rst(0x0);
bq25601_set_wdt_rst(0x1); //Kick watchdog 复位看门狗
bq25601_set_sys_min(0x4); //Minimum system voltage 3.4V 设置最小系统电压是3.4V
bq25601_set_iprechg(0x7); //Precharge current 480mA 预先充电电流 480mA
bq25601_set_iterm(0x4); //Termination current 240mA 终止充电电流 240mA
if (batt_cust_data.high_battery_voltage_support) //如果支持高压
bq25601_set_vreg(0xF); /* VREG 4.352V(4336) */ 调整电压 4.352V
else
bq25601_set_vreg(0xB); /* VREG 4.208V */否则调整电压 4.208V
bq25601_set_min_vbat_sel(0x0); //BATLOWV 2.8V 设置低压 2.8V
bq25601_set_vrechg(0x0); //VRECHG 0.1V (4.108V) VRECHG:以及再充电阈值 4.108V
bq25601_set_en_term(0x1); //Enable termination 停止使能
bq25601_set_watchdog(0x1); //WDT 40s 监视定时器 40S
bq25601_set_en_timer(0x0); //Disable charge timer 禁用充电定时器
bq25601_set_ovp(0x0); //0x01//Battery overvoltage Protection 6.5v 电池过电压保护 6.5V
//bq25601_set_boostv(0x2); //Boost Regulation Voltage 5.15v 提高调节电压 5.15v
bq25601_set_vindpm_int_mask(0x0); //Mask VINDPM INT pulse 屏蔽VINDPM INT脉冲
bq25601_set_iindpm_int_mask(0x0); //Mask IINDPM INT pulse 屏蔽IINDPM INT脉冲
bq25601_set_batfet_rst_en(0x0); //复位使能
#ifdef CONFIG_MTK_DUAL_INPUT_CHARGER_SUPPORT //如果支持双攻充电输入
mt_set_gpio_mode(vin_sel_gpio_number, 0); /* 0:GPIO mode */ 设置GPIO模式
mt_set_gpio_dir(vin_sel_gpio_number, 0); /* 0: input, 1: output */ 设置输入模式
#endif
return status;
}
static unsigned int charging_dump_register(void *data) //遍历读取bq25601所有保存在寄存器的值
{
battery_log(BAT_LOG_FULL, "charging_dump_register\r\n");
bq25601_dump_register();
return STATUS_OK;
}
void bq25601_dump_register(void)//读bq25601所有保存在寄存器的值
{
int i = 0;
battery_log(BAT_LOG_FULL, "[bq25601] ");
for (i = 0; i < bq25601_REG_NUM; i++) {
bq25601_read_byte(i, &bq25601_reg[i]);
battery_log(BAT_LOG_CRTI, "bq25601_reg[0x%x]=0x%x\n", i, bq25601_reg[i]);
}
battery_log(BAT_LOG_FULL, "\n");
}
static unsigned int charging_enable(void *data) //充电使能
{
unsigned int status = STATUS_OK;
unsigned int enable = *(unsigned int *) (data); //强制类型转换成 unsigned int
unsigned int bootmode = 0;
printk("1111charging_enable\r\n");
if (KAL_TRUE == enable) {如果传进来的值为1
bq25601_set_en_hiz(0x0);
bq25601_set_chg_config(0x1); /* charger enable *///充电使能
} else {否侧
#if defined(CONFIG_USB_MTK_HDRC_HCD) //如果定义usb这个宏
if (mt_usb_is_device()) {
#endif
bq25601_set_chg_config(0x0); //充电失能
if (charging_get_error_state()) { //返回一个错误状态
battery_log(BAT_LOG_CRTI, "[charging_enable] bq25601_set_en_hiz(0x1)\n");
bq25601_set_en_hiz(0x1); /* disable power path */ 启用HIZ模式0-禁用(默认)1-启用
}
#if defined(CONFIG_USB_MTK_HDRC_HCD) //如果定义usb这个宏
}
#endif
bootmode = get_boot_mode(); //获取boot这个状态
if ((bootmode == META_BOOT) || (bootmode == ADVMETA_BOOT))
bq25601_set_en_hiz(0x1); // 启用HIZ模式0-禁用(默认)1-启用
#if defined(CONFIG_MTK_DUAL_INPUT_CHARGER_SUPPORT)
bq25601_set_chg_config(0x0); //0-电荷禁用1-电荷启用 默认:充电电池(1) 注意:1 在电荷cE引脚在拉低和chg_config是1这两种情况下,电荷启用。
bq25601_set_en_hiz(0x1); /* disable power path */启用HIZ模式0-禁用(默认)1-启用
#endif
}
return status;
}
static unsigned int charging_set_cv_voltage(void *data) //设置工作电压
{
unsigned int status = STATUS_OK;
unsigned int array_size;
unsigned int set_cv_voltage;
unsigned short register_value;
unsigned int cv_value = *(unsigned int *) (data);
static short pre_register_value = -1;
if (batt_cust_data.high_battery_voltage_support) {
cv_value = 4352000;
}
/* use nearest value 使用最近的值 */
if (BATTERY_VOLT_04_200000_V == cv_value)
cv_value = 4208000;
array_size = GETARRAYNUM(VBAT_CV_VTH); //获取vth数组个数
set_cv_voltage = bmt_find_closest_level(VBAT_CV_VTH, array_size, cv_value); //bmt找到最接近的水平
register_value = charging_parameter_to_value(VBAT_CV_VTH, array_size, set_cv_voltage); //充电参数转化成值
bq25601_set_vreg(register_value);
/* Tg |512 mV T |256 mV | 128 mV gT64 mVgT 32 mV g
充电电压抵消:3.856 V范围:3.856 V至4.624 V (11000)
默认值:4.208 V (01011)特殊的价值:(01111):4.352 V注:超过11000 (4.624 V)的值夹紧,注册值11000 (4.624 V) */
/* for jeita recharging issue 为jeita充电问题 */
if (pre_register_value != register_value)
bq25601_set_chg_config(1); //0-电荷禁用1-电荷启用 默认:充电电池(1)
//注意:1 在电荷cE引脚在拉低和chg_config是1这两种情况下,电荷启用。
pre_register_value = register_value;
return status;
}
static unsigned int charging_get_current(void *data)//获取充电电流
{
unsigned int status = STATUS_OK;
/* unsigned int array_size; */
/* unsigned char reg_value; */
unsigned char ret_val = 0;
//unsigned char ret_force_20pct = 0;
/* Get current level 读寄存器2 得到当前电流电平*/
bq25601_read_interface(bq25601_CON2, &ret_val, CON2_ICHG_MASK, CON2_ICHG_SHIFT);
/* Get Force 20% option */
//bq25601_read_interface(bq25601_CON2, &ret_force_20pct, CON2_FORCE_20PCT_MASK,
//CON2_FORCE_20PCT_SHIFT);
/* Parsing 分析*/
ret_val = ret_val * 60;
//if (ret_force_20pct == 0) {
/* Get current level */
/* array_size = GETARRAYNUM(CS_VTH); */
/* *(unsigned int *)data = charging_value_to_parameter(CS_VTH,array_size,reg_value); */
*(unsigned int *) data = ret_val;
//} else {
/* Get current level */
/* array_size = GETARRAYNUM(CS_VTH_20PCT); */
/* *(unsigned int *)data = charging_value_to_parameter(CS_VTH,array_size,reg_value); */
/* return (int)(ret_val<<1)/10; */
//*(unsigned int *) data = (int)(ret_val << 1) / 10;
//}
时
return status;
}
static unsigned int charging_set_current(void *data)//设置充电电流
{
unsigned int status = STATUS_OK;
unsigned int set_chr_current;
unsigned int array_size;
unsigned int register_value;
unsigned int current_value = *(unsigned int *) data;
array_size = GETARRAYNUM(CS_VTH); //获取vth数组个数
set_chr_current = bmt_find_closest_level(CS_VTH, array_size, current_value); //bmt找到最接近的水平
register_value = charging_parameter_to_value(CS_VTH, array_size, set_chr_current); //充电参数转化成值
printk("[%s] register_value = 0x%x \n", __func__, register_value);
bq25601_set_ichg(register_value);//设置充电电流其中有个充电电流曲线
return status;
}
static unsigned int charging_set_input_current(void *data) //设置输入电流
{
unsigned int status = STATUS_OK;
unsigned int current_value = *(unsigned int *) data;
unsigned int set_chr_current;
unsigned int array_size;
unsigned int register_value;
array_size = GETARRAYNUM(INPUT_CS_VTH);//获取vth数组个数
set_chr_current = bmt_find_closest_level(INPUT_CS_VTH, array_size, current_value);//bmt找到最接近的水平
register_value = charging_parameter_to_value(INPUT_CS_VTH, array_size, set_chr_current);//充电参数转化成值
printk("[%s] register_value = 0x%x \n", __func__, register_value);
bq25601_set_iindpm(register_value); //设置极限电流 其中有个极限电流 曲线
return status;
}
static unsigned int charging_get_charging_status(void *data) //得到充电状态
{
unsigned int status = STATUS_OK;
unsigned int ret_val;
ret_val = bq25601_get_chrg_stat(); //充电状态:00-Not充电 01-Pre-charge(< VBATLOw) 10-Fast充电 11充电终止
if (ret_val == 0x3)
*(unsigned int *) data = KAL_TRUE;
else
*(unsigned int *) data = KAL_FALSE;
return status;
}
static unsigned int charging_reset_watch_dog_timer(void *data) //复位看门狗
{
unsigned int status = STATUS_OK;
battery_log(BAT_LOG_FULL, "charging_reset_watch_dog_timer\r\n");
bq25601_set_wdt_rst(0x1); /* Kick watchdog */ 默认:正常(0)回到0后,1 看门狗定时器重置
return status;
}
static unsigned int charging_set_hv_threshold(void *data) //设置电压极限值
{
unsigned int status = STATUS_OK;
unsigned int set_hv_voltage;
unsigned int array_size;
unsigned short register_value;
unsigned int voltage = *(unsigned int *)(data);
array_size = GETARRAYNUM(VCDT_HV_VTH);//获取vth数组个数
set_hv_voltage = bmt_find_closest_level(VCDT_HV_VTH, array_size, voltage); //bmt找到最接近的水平
register_value = charging_parameter_to_value(VCDT_HV_VTH, array_size, set_hv_voltage); //充电参数转化成值
upmu_set_rg_vcdt_hv_vth(register_value);
return status;
}
static unsigned int charging_get_hv_status(void *data) //获取电压的状态
{
unsigned int status = STATUS_OK;
#if defined(CONFIG_POWER_EXT) || defined(CONFIG_MTK_FPGA)
*(kal_bool *) (data) = 0;
pr_notice("[charging_get_hv_status] charger ok for bring up.\n");
#else
*(kal_bool *)(data) = upmu_get_rgs_vcdt_hv_det();
#endif
return status;
}
static unsigned int charging_get_battery_status(void *data) //得到充电电池状态
{
unsigned int status = STATUS_OK;
unsigned int val = 0;
battery_log(BAT_LOG_FULL, "[charging_get_battery_status] BATON_TDET_EN = %d\n", val);
upmu_set_baton_tdet_en(1);
upmu_set_rg_baton_en(1);
*(kal_bool *)(data) = upmu_get_rgs_baton_undet();
return status;
}
static unsigned int charging_get_charger_det_status(void *data)//得到充电det的状态
{
unsigned int status = STATUS_OK;
*(kal_bool *)(data) = upmu_get_rgs_chrdet();
return status;
}
static unsigned int charging_get_charger_type(void *data) //得到充电类型
{
unsigned int status = STATUS_OK;
#if defined(CONFIG_POWER_EXT) || defined(CONFIG_MTK_FPGA)
*(CHARGER_TYPE *) (data) = STANDARD_HOST;
#else
*(CHARGER_TYPE *) (data) = hw_charging_get_charger_type();
#endif
return status;
}
static unsigned int charging_set_platform_reset(void *data) //设置平台复位状态
{
unsigned int status = STATUS_OK;
#if defined(CONFIG_POWER_EXT) || defined(CONFIG_MTK_FPGA)
#else
battery_log(BAT_LOG_CRTI, "charging_set_platform_reset\n");
kernel_restart("battery service reboot system");
/* arch_reset(0,NULL); */
#endif
return status;
}
static unsigned int charging_get_platform_boot_mode(void *data) //得到平台boot的模式
{
unsigned int status = STATUS_OK;
#if defined(CONFIG_POWER_EXT) || defined(CONFIG_MTK_FPGA)
#else
*(unsigned int *) (data) = get_boot_mode();
battery_log(BAT_LOG_CRTI, "get_boot_mode=%d\n", get_boot_mode());
#endif
return status;
}
static unsigned int charging_set_power_off(void *data)//设置电池电源关闭
{
unsigned int status = STATUS_OK;
#if defined(CONFIG_POWER_EXT) || defined(CONFIG_MTK_FPGA)
#else
battery_log(BAT_LOG_CRTI, "charging_set_power_off\n");
kernel_power_off();
#endif
return status;
}
static unsigned int charging_set_ta_current_pattern(void *data)//设置电池充电电流的模式
{
unsigned int increase = *(unsigned int *) (data);
unsigned int charging_status = KAL_FALSE;
BATTERY_VOLTAGE_ENUM cv_voltage = BATTERY_VOLT_04_200000_V;
if (batt_cust_data.high_battery_voltage_support)
cv_voltage = BATTERY_VOLT_04_340000_V;
charging_get_charging_status(&charging_status); //获取充电状态
if (KAL_FALSE == charging_status) {
charging_set_cv_voltage(&cv_voltage); /* Set CV 设置cv电压*/
bq25601_set_ichg(0x9); /* Set charging current 500ma 设置充电电流为500ma */
bq25601_set_chg_config(0x1); /* Enable Charging使能充电 */
}
if (increase == KAL_TRUE) { //输入极限电流设置
bq25601_set_iindpm(0x0); /* 100mA */
msleep(85);
bq25601_set_iindpm(0x4); /* 500mA */
battery_log(BAT_LOG_FULL, "mtk_ta_increase() on 1");
msleep(85);
bq25601_set_iindpm(0x0); /* 100mA */
battery_log(BAT_LOG_FULL, "mtk_ta_increase() off 1");
msleep(85);
bq25601_set_iindpm(0x4); /* 500mA */
battery_log(BAT_LOG_FULL, "mtk_ta_increase() on 2");
msleep(85);
bq25601_set_iindpm(0x0); /* 100mA */
battery_log(BAT_LOG_FULL, "mtk_ta_increase() off 2");
msleep(85);
bq25601_set_iindpm(0x4); /* 500mA */
battery_log(BAT_LOG_FULL, "mtk_ta_increase() on 3");
msleep(281);
bq25601_set_iindpm(0x0); /* 100mA */
battery_log(BAT_LOG_FULL, "mtk_ta_increase() off 3");
msleep(85);
bq25601_set_iindpm(0x4); /* 500mA */
battery_log(BAT_LOG_FULL, "mtk_ta_increase() on 4");
msleep(281);
bq25601_set_iindpm(0x0); /* 100mA */
battery_log(BAT_LOG_FULL, "mtk_ta_increase() off 4");
msleep(85);
bq25601_set_iindpm(0x4); /* 500mA */
battery_log(BAT_LOG_FULL, "mtk_ta_increase() on 5");
msleep(281);
bq25601_set_iindpm(0x0); /* 100mA */
battery_log(BAT_LOG_FULL, "mtk_ta_increase() off 5");
msleep(85);
bq25601_set_iindpm(0x4); /* 500mA */
battery_log(BAT_LOG_FULL, "mtk_ta_increase() on 6");
msleep(485);
bq25601_set_iindpm(0x0); /* 100mA */
battery_log(BAT_LOG_FULL, "mtk_ta_increase() off 6");
msleep(50);
battery_log(BAT_LOG_CRTI, "mtk_ta_increase() end\n");
bq25601_set_iindpm(0x4); /* 500mA */
msleep(200);
} else {
bq25601_set_iindpm(0x0); /* 100mA */
msleep(85);
bq25601_set_iindpm(0x4); /* 500mA */
battery_log(BAT_LOG_FULL, "mtk_ta_decrease() on 1");
msleep(281);
bq25601_set_iindpm(0x0); /* 100mA */
battery_log(BAT_LOG_FULL, "mtk_ta_decrease() off 1");
msleep(85);
bq25601_set_iindpm(0x4); /* 500mA */
battery_log(BAT_LOG_FULL, "mtk_ta_decrease() on 2");
msleep(281);
bq25601_set_iindpm(0x0); /* 100mA */
battery_log(BAT_LOG_FULL, "mtk_ta_decrease() off 2");
msleep(85);
bq25601_set_iindpm(0x4); /* 500mA */
battery_log(BAT_LOG_FULL, "mtk_ta_decrease() on 3");
msleep(281);
bq25601_set_iindpm(0x0); /* 100mA */
battery_log(BAT_LOG_FULL, "mtk_ta_decrease() off 3");
msleep(85);
bq25601_set_iindpm(0x4); /* 500mA */
battery_log(BAT_LOG_FULL, "mtk_ta_decrease() on 4");
msleep(85);
bq25601_set_iindpm(0x0); /* 100mA */
battery_log(BAT_LOG_FULL, "mtk_ta_decrease() off 4");
msleep(85);
bq25601_set_iindpm(0x4); /* 500mA */
battery_log(BAT_LOG_FULL, "mtk_ta_decrease() on 5");
msleep(85);
bq25601_set_iindpm(0x0); /* 100mA */
battery_log(BAT_LOG_FULL, "mtk_ta_decrease() off 5");
msleep(85);
bq25601_set_iindpm(0x4); /* 500mA */
battery_log(BAT_LOG_FULL, "mtk_ta_decrease() on 6");
msleep(485);
bq25601_set_iindpm(0x0); /* 100mA */
battery_log(BAT_LOG_FULL, "mtk_ta_decrease() off 6");
msleep(50);
battery_log(BAT_LOG_CRTI, "mtk_ta_decrease() end\n");
bq25601_set_iindpm(0x4); /* 500mA */
}
return STATUS_OK;
}
static unsigned int charging_diso_init(void *data) //初始化DISO结构体
{
unsigned int status = STATUS_OK;
#if defined(CONFIG_MTK_DUAL_INPUT_CHARGER_SUPPORT)
DISO_ChargerStruct *pDISO_data = (DISO_ChargerStruct *) data;
/* Initialization DISO Struct 初始化DISO结构体*/
pDISO_data->diso_state.cur_otg_state = DISO_OFFLINE; //otg状态
pDISO_data->diso_state.cur_vusb_state = DISO_OFFLINE;//vusb状态
pDISO_data->diso_state.cur_vdc_state = DISO_OFFLINE;//vdc状态
pDISO_data->diso_state.pre_otg_state = DISO_OFFLINE;//前置otg状态
pDISO_data->diso_state.pre_vusb_state = DISO_OFFLINE;//前置vusb状态
pDISO_data->diso_state.pre_vdc_state = DISO_OFFLINE;//前置vdc状态
pDISO_data->chr_get_diso_state = KAL_FALSE;
pDISO_data->hv_voltage = VBUS_MAX_VOLTAGE;
hrtimer_init(&diso_kthread_timer, CLOCK_MONOTONIC, HRTIMER_MODE_REL);//hr计时器初始化
diso_kthread_timer.function = diso_kthread_hrtimer_func; //diso内核线程函数
INIT_DELAYED_WORK(&diso_polling_work, diso_polling_handler); //初始化等待队列
kthread_run(diso_thread_kthread, NULL, "diso_thread_kthread"); //开一个diso的内核线程
battery_log(BAT_LOG_CRTI, "[%s] done\n", __func__);
#if defined(MTK_DISCRETE_SWITCH) && defined(MTK_DSC_USE_EINT)
battery_log(BAT_LOG_CRTI, "[diso_eint]vdc eint irq registitation\n");
mt_eint_set_hw_debounce(CUST_EINT_VDC_NUM, CUST_EINT_VDC_DEBOUNCE_CN);
mt_eint_registration(CUST_EINT_VDC_NUM, CUST_EINTF_TRIGGER_LOW, vdc_eint_handler, 0);
mt_eint_mask(CUST_EINT_VDC_NUM);
#endif
#endif
return status;
}
enum hrtimer_restart diso_kthread_hrtimer_func(struct hrtimer *timer) //diso内核线程函数
{
diso_thread_timeout = KAL_TRUE;
wake_up(&diso_polling_thread_wq); //轮询事件若有事件则唤醒等待队列
return HRTIMER_NORESTART;
}
int diso_thread_kthread(void *x) //diso内核线程函数启动
{
/* Run on a process content 在流程内容上运行*/
while (1) {
wait_event(diso_polling_thread_wq, (diso_thread_timeout == KAL_TRUE));
diso_thread_timeout = KAL_FALSE;
mutex_lock(&diso_polling_mutex);
_get_polling_state();//得到轮询状态事件
if (DISO_Polling.vdc_polling_measure.notify_irq_en ||
DISO_Polling.vusb_polling_measure.notify_irq_en)
hrtimer_start(&diso_kthread_timer,
ktime_set(0, MSEC_TO_NSEC(SW_POLLING_PERIOD)),
HRTIMER_MODE_REL);
else
hrtimer_cancel(&diso_kthread_timer);
mutex_unlock(&diso_polling_mutex);
}
return 0;
}
s
static void _get_polling_state(void)//得到轮询状态
{
int vdc_vol = 0, vusb_vol = 0;
int vdc_vol_dir = -1;
int vusb_vol_dir = -1;
DISO_polling_channel *VDC_Polling = &DISO_Polling.vdc_polling_measure;
DISO_polling_channel *VUSB_Polling = &DISO_Polling.vusb_polling_measure;
vdc_vol = diso_get_current_voltage(AP_AUXADC_DISO_VDC_CHANNEL); //得到VDC当前电压
vdc_vol =
(R_DISO_DC_PULL_UP + R_DISO_DC_PULL_DOWN) * 100 * vdc_vol / (R_DISO_DC_PULL_DOWN) / 100;
vusb_vol = diso_get_current_voltage(AP_AUXADC_DISO_VUSB_CHANNEL);//得到VUSB当前电压
vusb_vol =
(R_DISO_VBUS_PULL_UP +
R_DISO_VBUS_PULL_DOWN) * 100 * vusb_vol / (R_DISO_VBUS_PULL_DOWN) / 100;
VDC_Polling->preVoltage = VDC_Polling->curVoltage;
VUSB_Polling->preVoltage = VUSB_Polling->curVoltage;
VDC_Polling->curVoltage = vdc_vol;
VUSB_Polling->curVoltage = vusb_vol;
if (DISO_Polling.reset_polling) {
DISO_Polling.reset_polling = KAL_FALSE;
VDC_Polling->preVoltage = vdc_vol;
VUSB_Polling->preVoltage = vusb_vol;
if (vdc_vol > 1000)
vdc_vol_dir = DISO_IRQ_RISING;
else
vdc_vol_dir = DISO_IRQ_FALLING;
if (vusb_vol > 1000)
vusb_vol_dir = DISO_IRQ_RISING;
else
vusb_vol_dir = DISO_IRQ_FALLING;
} else {
/* get voltage direction 得到电压方向 */
vdc_vol_dir = _get_irq_direction(VDC_Polling->preVoltage, VDC_Polling->curVoltage); //得到电压方向
vusb_vol_dir =
_get_irq_direction(VUSB_Polling->preVoltage, VUSB_Polling->curVoltage);
}
if (VDC_Polling->notify_irq_en && (vdc_vol_dir == VDC_Polling->notify_irq)) {
schedule_delayed_work(&diso_polling_work, 10 * HZ / 1000); /* 10ms */
battery_log(BAT_LOG_CRTI, "[%s] ready to trig VDC irq, irq: %d\n",
__func__, VDC_Polling->notify_irq);
} else if (VUSB_Polling->notify_irq_en && (vusb_vol_dir == VUSB_Polling->notify_irq)) {
schedule_delayed_work(&diso_polling_work, 10 * HZ / 1000);
battery_log(BAT_LOG_CRTI, "[%s] ready to trig VUSB irq, irq: %d\n",
__func__, VUSB_Polling->notify_irq);
} else if ((vdc_vol == 0) && (vusb_vol == 0)) {
VDC_Polling->notify_irq_en = 0;
VUSB_Polling->notify_irq_en = 0;
}
}
static unsigned int diso_get_current_voltage(int Channel)//得到当前电压
{
int ret = 0, data[4], i, ret_value = 0, ret_temp = 0, times = 5;
if (IMM_IsAdcInitReady() == 0) {
battery_log(BAT_LOG_CRTI, "[DISO] AUXADC is not ready");
return 0;
}
i = times;
while (i--) {
ret_value = IMM_GetOneChannelValue(Channel, data, &ret_temp);
if (ret_value == 0) {
ret += ret_temp;
} else {
times = times > 1 ? times - 1 : 1;
battery_log(BAT_LOG_CRTI, "[diso_get_current_voltage] ret_value=%d, times=%d\n",
ret_value, times);
}
}
ret = ret * 1500 / 4096;
ret = ret / times;
return ret;
}
int _get_irq_direction(int pre_vol, int cur_vol)//得到中断电压方向
{
int ret = -1;
/* threshold 阈值1000mv */
if ((cur_vol - pre_vol) > 1000)
ret = DISO_IRQ_RISING;
x
else if ((pre_vol - cur_vol) > 1000)
ret = DISO_IRQ_FALLING;
return ret;
}
tatic void diso_polling_handler(struct work_struct *work) //等待队列处理的事件
{
int trigger_channel = -1;
int trigger_flag = -1;
if (DISO_Polling.vdc_polling_measure.notify_irq_en)
trigger_channel = AP_AUXADC_DISO_VDC_CHANNEL;
else if (DISO_Polling.vusb_polling_measure.notify_irq_en)
trigger_channel = AP_AUXADC_DISO_VUSB_CHANNEL;
battery_log(BAT_LOG_CRTI, "[DISO]auxadc handler triggered\n");
switch (trigger_channel) {
case AP_AUXADC_DISO_VDC_CHANNEL:
trigger_flag = DISO_Polling.vdc_polling_measure.notify_irq;
battery_log(BAT_LOG_CRTI, "[DISO]VDC IRQ triggered, channel ==%d, flag ==%d\n", trigger_channel,
trigger_flag);
#ifdef MTK_DISCRETE_SWITCH /*for DSC DC plugin handle 用于DSC DC插件处理事件*/
set_vdc_auxadc_irq(DISO_IRQ_DISABLE, 0); //dc中断处理事件
set_vusb_auxadc_irq(DISO_IRQ_DISABLE, 0);//usb中断处理事件
set_vusb_auxadc_irq(DISO_IRQ_ENABLE, DISO_IRQ_FALLING);//使能usb事件
if (trigger_flag == DISO_IRQ_RISING) {
DISO_data.diso_state.pre_vusb_state = DISO_ONLINE;
DISO_data.diso_state.pre_vdc_state = DISO_OFFLINE;
DISO_data.diso_state.pre_otg_state = DISO_OFFLINE;
DISO_data.diso_state.cur_vusb_state = DISO_ONLINE;
DISO_data.diso_state.cur_vdc_state = DISO_ONLINE;
DISO_data.diso_state.cur_otg_state = DISO_OFFLINE;
battery_log(BAT_LOG_CRTI, " cur diso_state is %s!\n", DISO_state_s[2]);
}
#else /* for load switch OTG leakage handle 用于负载开关OTG泄漏手柄*/
set_vdc_auxadc_irq(DISO_IRQ_ENABLE, (~trigger_flag) & 0x1);
if (trigger_flag == DISO_IRQ_RISING) {
DISO_data.diso_state.pre_vusb_state = DISO_OFFLINE;
DISO_data.diso_state.pre_vdc_state = DISO_OFFLINE;
DISO_data.diso_state.pre_otg_state = DISO_ONLINE;
DISO_data.diso_state.cur_vusb_state = DISO_OFFLINE;
DISO_data.diso_state.cur_vdc_state = DISO_ONLINE;
DISO_data.diso_state.cur_otg_state = DISO_ONLINE;
battery_log(BAT_LOG_CRTI, " cur diso_state is %s!\n", DISO_state_s[5]);
} else if (trigger_flag == DISO_IRQ_FALLING) {
DISO_data.diso_state.pre_vusb_state = DISO_OFFLINE;
DISO_data.diso_state.pre_vdc_state = DISO_ONLINE;
DISO_data.diso_state.pre_otg_state = DISO_ONLINE;
DISO_data.diso_state.cur_vusb_state = DISO_OFFLINE;
DISO_data.diso_state.cur_vdc_state = DISO_OFFLINE;
DISO_data.diso_state.cur_otg_state = DISO_ONLINE;
battery_log(BAT_LOG_CRTI, " cur diso_state is %s!\n", DISO_state_s[1]);
} else
battery_log(BAT_LOG_CRTI, "[%s] wrong trigger flag!\n", __func__);
#endif
break;
case AP_AUXADC_DISO_VUSB_CHANNEL:
trigger_flag = DISO_Polling.vusb_polling_measure.notify_irq;
battery_log(BAT_LOG_CRTI, "[DISO]VUSB IRQ triggered, channel ==%d, flag ==%d\n", trigger_channel,
trigger_flag);
set_vdc_auxadc_irq(DISO_IRQ_DISABLE, 0);
set_vusb_auxadc_irq(DISO_IRQ_DISABLE, 0);
if (trigger_flag == DISO_IRQ_FALLING) {
DISO_data.diso_state.pre_vusb_state = DISO_ONLINE;
DISO_data.diso_state.pre_vdc_state = DISO_ONLINE;
DISO_data.diso_state.pre_otg_state = DISO_OFFLINE;
DISO_data.diso_state.cur_vusb_state = DISO_OFFLINE;
DISO_data.diso_state.cur_vdc_state = DISO_ONLINE;
DISO_data.diso_state.cur_otg_state = DISO_OFFLINE;
battery_log(BAT_LOG_CRTI, " cur diso_state is %s!\n", DISO_state_s[4]);
} else if (trigger_flag == DISO_IRQ_RISING) {
DISO_data.diso_state.pre_vusb_state = DISO_OFFLINE;
DISO_data.diso_state.pre_vdc_state = DISO_ONLINE;
DISO_data.diso_state.pre_otg_state = DISO_OFFLINE;
DISO_data.diso_state.cur_vusb_state = DISO_ONLINE;
DISO_data.diso_state.cur_vdc_state = DISO_ONLINE;
DISO_data.diso_state.cur_otg_state = DISO_OFFLINE;
battery_log(BAT_LOG_CRTI, " cur diso_state is %s!\n", DISO_state_s[6]);
} else
battery_log(BAT_LOG_CRTI, "[%s] wrong trigger flag!\n", __func__);
set_vusb_auxadc_irq(DISO_IRQ_ENABLE, (~trigger_flag) & 0x1);
break;
default:
set_vdc_auxadc_irq(DISO_IRQ_DISABLE, 0);
set_vusb_auxadc_irq(DISO_IRQ_DISABLE, 0);
battery_log(BAT_LOG_CRTI, "[DISO]VUSB auxadc IRQ triggered ERROR OR TEST\n");
return; /* in error or unexecpt state just return在错误或不称职的状态下才返回 */
}
g_diso_state = *(int *)&DISO_data.diso_state;
battery_log(BAT_LOG_CRTI, "[DISO]g_diso_state: 0x%x\n", g_diso_state);
DISO_data.irq_callback_func(0, NULL);
}
#if defined(CONFIG_MTK_DUAL_INPUT_CHARGER_SUPPORT)
void set_vusb_auxadc_irq(bool enable, bool flag) //usb中断处理事件
{
hrtimer_cancel(&diso_kthread_timer);
DISO_Polling.reset_polling = KAL_TRUE;
DISO_Polling.vusb_polling_measure.notify_irq_en = enable;
DISO_Polling.vusb_polling_measure.notify_irq = flag;
hrtimer_start(&diso_kthread_timer, ktime_set(0, MSEC_TO_NSEC(SW_POLLING_PERIOD)),
HRTIMER_MODE_REL);
battery_log(BAT_LOG_FULL, " [%s] enable: %d, flag: %d!\n", __func__, enable, flag);
}
void set_vdc_auxadc_irq(bool enable, bool flag)//dc中断处理事件
{
hrtimer_cancel(&diso_kthread_timer);
DISO_Polling.reset_polling = KAL_TRUE;
DISO_Polling.vdc_polling_measure.notify_irq_en = enable;
DISO_Polling.vdc_polling_measure.notify_irq = flag;
hrtimer_start(&diso_kthread_timer, ktime_set(0, MSEC_TO_NSEC(SW_POLLING_PERIOD)),
HRTIMER_MODE_REL);
battery_log(BAT_LOG_FULL, " [%s] enable: %d, flag: %d!\n", __func__, enable, flag);
}
#if defined(MTK_DISCRETE_SWITCH) && defined(MTK_DSC_USE_EINT)
void vdc_eint_handler(void) //中断处理
{
battery_log(BAT_LOG_CRTI, "[diso_eint] vdc eint irq triger\n");
DISO_data.diso_state.cur_vdc_state = DISO_ONLINE;
mt_eint_mask(CUST_EINT_VDC_NUM);
do_chrdet_int_task();
}
#endif
static void _get_diso_interrupt_state(void) //得到diso中断状态
{
int vol = 0;
int diso_state = 0;
int check_times = 30;
kal_bool vin_state = KAL_FALSE;
#ifndef VIN_SEL_FLAG
mdelay(AUXADC_CHANNEL_DELAY_PERIOD);
#endif
vol = diso_get_current_voltage(AP_AUXADC_DISO_VDC_CHANNEL);
vol = (R_DISO_DC_PULL_UP + R_DISO_DC_PULL_DOWN) * 100 * vol / (R_DISO_DC_PULL_DOWN) / 100;
battery_log(BAT_LOG_CRTI, "[DISO] Current DC voltage mV = %d\n", vol);
#ifdef VIN_SEL_FLAG
/* set gpio mode for kpoc issue as DWS has no default setting 为kpoc问题设置gpio模式,因为DWS没有默认设置*/
mt_set_gpio_mode(vin_sel_gpio_number, 0); /* 0:GPIO mode */
mt_set_gpio_dir(vin_sel_gpio_number, 0); /* 0: input, 1: output */
if (vol > VDC_MIN_VOLTAGE / 1000 && vol < VDC_MAX_VOLTAGE / 1000) {
/* make sure load switch already switch done 确保负载开关已经完成 */
do {
check_times--;
#ifdef VIN_SEL_FLAG_DEFAULT_LOW
vin_state = mt_get_gpio_in(vin_sel_gpio_number);
#else
vin_state = mt_get_gpio_in(vin_sel_gpio_number);
vin_state = (~vin_state) & 0x1;
#endif
if (!vin_state)
mdelay(5);
} while ((!vin_state) && check_times);
battery_log(BAT_LOG_CRTI, "[DISO] i==%d gpio_state= %d\n",
check_times, mt_get_gpio_in(vin_sel_gpio_number));
if (0 == check_times)
diso_state &= ~0x4; /* SET DC bit as 0 */
else
diso_state |= 0x4; /* SET DC bit as 1 */
} else {
diso_state &= ~0x4; /* SET DC bit as 0 */
}
#else
/* force delay for switching as no flag for check switching done 强制延迟切换作为没有标志的检查切换完成*/
mdelay(SWITCH_RISING_TIMING + LOAD_SWITCH_TIMING_MARGIN);
if (vol > VDC_MIN_VOLTAGE / 1000 && vol < VDC_MAX_VOLTAGE / 1000)
diso_state |= 0x4; /* SET DC bit as 1 */
else
diso_state &= ~0x4; /* SET DC bit as 0 */
#endif
vol = diso_get_current_voltage(AP_AUXADC_DISO_VUSB_CHANNEL);
vol =
(R_DISO_VBUS_PULL_UP +
R_DISO_VBUS_PULL_DOWN) * 100 * vol / (R_DISO_VBUS_PULL_DOWN) / 100;
battery_log(BAT_LOG_CRTI, "[DISO] Current VBUS voltage mV = %d\n", vol);
if (vol > VBUS_MIN_VOLTAGE / 1000 && vol < VBUS_MAX_VOLTAGE / 1000) {
if (!mt_usb_is_device()) {
diso_state |= 0x1; /* SET OTG bit as 1 */
diso_state &= ~0x2; /* SET VBUS bit as 0 */
} else {
diso_state &= ~0x1; /* SET OTG bit as 0 */
diso_state |= 0x2; /* SET VBUS bit as 1; */
}
} else {
diso_state &= 0x4; /* SET OTG and VBUS bit as 0 */
}
battery_log(BAT_LOG_CRTI, "[DISO] DISO_STATE==0x%x\n", diso_state);
g_diso_state = diso_state;
}
#endif
static unsigned int charging_get_diso_state(void *data)//获取diso 电池状态
{
unsigned int status = STATUS_OK;
#if defined(CONFIG_MTK_DUAL_INPUT_CHARGER_SUPPORT)
int diso_state = 0x0;
DISO_ChargerStruct *pDISO_data = (DISO_ChargerStruct *) data;
_get_diso_interrupt_state();
diso_state = g_diso_state;
battery_log(BAT_LOG_CRTI, "[do_chrdet_int_task] current diso state is %s!\n", DISO_state_s[diso_state]);
if (((diso_state >> 1) & 0x3) != 0x0) {
switch (diso_state) {
case USB_ONLY:
set_vdc_auxadc_irq(DISO_IRQ_DISABLE, 0);
set_vusb_auxadc_irq(DISO_IRQ_DISABLE, 0);
#ifdef MTK_DISCRETE_SWITCH
#ifdef MTK_DSC_USE_EINT
mt_eint_unmask(CUST_EINT_VDC_NUM);
#else
set_vdc_auxadc_irq(DISO_IRQ_ENABLE, 1);
#endif
#endif
pDISO_data->diso_state.cur_vusb_state = DISO_ONLINE;
pDISO_data->diso_state.cur_vdc_state = DISO_OFFLINE;
pDISO_data->diso_state.cur_otg_state = DISO_OFFLINE;
break;
case DC_ONLY:
set_vdc_auxadc_irq(DISO_IRQ_DISABLE, 0);
set_vusb_auxadc_irq(DISO_IRQ_DISABLE, 0);
set_vusb_auxadc_irq(DISO_IRQ_ENABLE, DISO_IRQ_RISING);
pDISO_data->diso_state.cur_vusb_state = DISO_OFFLINE;
pDISO_data->diso_state.cur_vdc_state = DISO_ONLINE;
pDISO_data->diso_state.cur_otg_state = DISO_OFFLINE;
break;
case DC_WITH_USB:
set_vdc_auxadc_irq(DISO_IRQ_DISABLE, 0);
set_vusb_auxadc_irq(DISO_IRQ_DISABLE, 0);
set_vusb_auxadc_irq(DISO_IRQ_ENABLE, DISO_IRQ_FALLING);
pDISO_data->diso_state.cur_vusb_state = DISO_ONLINE;
pDISO_data->diso_state.cur_vdc_state = DISO_ONLINE;
pDISO_data->diso_state.cur_otg_state = DISO_OFFLINE;
break;
case DC_WITH_OTG:
set_vdc_auxadc_irq(DISO_IRQ_DISABLE, 0);
set_vusb_auxadc_irq(DISO_IRQ_DISABLE, 0);
pDISO_data->diso_state.cur_vusb_state = DISO_OFFLINE;
pDISO_data->diso_state.cur_vdc_state = DISO_ONLINE;
pDISO_data->diso_state.cur_otg_state = DISO_ONLINE;
break;
default: /* OTG only also can trigger vcdt IRQ OTG也只能触发vcdt IRQ */
pDISO_data->diso_state.cur_vusb_state = DISO_OFFLINE;
pDISO_data->diso_state.cur_vdc_state = DISO_OFFLINE;
pDISO_data->diso_state.cur_otg_state = DISO_ONLINE;
battery_log(BAT_LOG_CRTI, " switch load vcdt irq triggerd by OTG Boost!\n");
break; /* OTG plugin no need battery sync action OTG插件不需要电池同步动作*/
}
}
if (DISO_ONLINE == pDISO_data->diso_state.cur_vdc_state)
pDISO_data->hv_voltage = VDC_MAX_VOLTAGE;
else
pDISO_data->hv_voltage = VBUS_MAX_VOLTAGE;
#endif
return status;
}
static unsigned int charging_get_error_state(void)//得到充电错误状态
{
return charging_error;
}
static unsigned int charging_set_error_state(void *data) //设置充电错误状态
{
unsigned int status = STATUS_OK;
charging_error = *(unsigned int *) (data);
return status;
}
static unsigned int charging_set_vbus_ovp_en(void *data)//充电设置使能
{
return STATUS_OK;
}
static unsigned int charging_set_vindpm(void *data)//设置电池vindpm
{
return STATUS_OK;
}
下面就是mtk 充电中提供一个函数指针chr_control_interface指向下面的函数接口,从而实现各个功能
/*
* FUNCTION 函数
* Internal_chr_control_handler
*
* DESCRIPTION 描述
* This function is called to set the charger hw 调用此功能设置充电器hw
*
*
* CALLS 电话
*
* PARAMETERS 参数
* None 没有
*
* RETURNS 返回
*
*
* GLOBALS AFFECTED 全局的影响
* None 没有
*/
static unsigned int(*charging_func[CHARGING_CMD_NUMBER]) (void *data);
signed int chr_control_interface(CHARGING_CTRL_CMD cmd, void *data) //调用此功能设置充电器hw
{
static signed int init = -1;
if (init == -1) {
init = 0;
charging_func[CHARGING_CMD_INIT] = charging_hw_init; //充电硬件初始化
charging_func[CHARGING_CMD_DUMP_REGISTER] = charging_dump_register;//遍历读取bq25601所有保存在寄存器的值
charging_func[CHARGING_CMD_ENABLE] = charging_enable;//充电使能
charging_func[CHARGING_CMD_SET_CV_VOLTAGE] = charging_set_cv_voltage;//设置工作电压
charging_func[CHARGING_CMD_GET_CURRENT] = charging_get_current;//获取充电电流
charging_func[CHARGING_CMD_SET_CURRENT] = charging_set_current;//设置充电电流
charging_func[CHARGING_CMD_SET_INPUT_CURRENT] = charging_set_input_current; //设置输入电流
charging_func[CHARGING_CMD_GET_CHARGING_STATUS] = charging_get_charging_status;//得到充电状态
charging_func[CHARGING_CMD_RESET_WATCH_DOG_TIMER] = charging_reset_watch_dog_timer;//复位看门狗
charging_func[CHARGING_CMD_SET_HV_THRESHOLD] = charging_set_hv_threshold;//设置电压极限值
charging_func[CHARGING_CMD_GET_HV_STATUS] = charging_get_hv_status;//获取电压的状态
charging_func[CHARGING_CMD_GET_BATTERY_STATUS] = charging_get_battery_status;//得到充电电池状态
charging_func[CHARGING_CMD_GET_CHARGER_DET_STATUS] = charging_get_charger_det_status;//得到充电det的状态
charging_func[CHARGING_CMD_GET_CHARGER_TYPE] = charging_get_charger_type;//得到充电类型
charging_func[CHARGING_CMD_SET_PLATFORM_RESET] = charging_set_platform_reset;//设置平台复位状态
charging_func[CHARGING_CMD_GET_PLATFORM_BOOT_MODE] = charging_get_platform_boot_mode; //得到平台boot的模式
charging_func[CHARGING_CMD_SET_POWER_OFF] = charging_set_power_off;//设置电池电源关闭
charging_func[CHARGING_CMD_SET_TA_CURRENT_PATTERN] = charging_set_ta_current_pattern;//设置电池充电电流的模式
charging_func[CHARGING_CMD_SET_ERROR_STATE] = charging_set_error_state;//设置充电错误状态
charging_func[CHARGING_CMD_DISO_INIT] = charging_diso_init; //初始化DISO结构体
charging_func[CHARGING_CMD_GET_DISO_STATE] = charging_get_diso_state;//获取diso 电池状态
charging_func[CHARGING_CMD_SET_VBUS_OVP_EN] = charging_set_vbus_ovp_en;//充电设置使能
charging_func[CHARGING_CMD_SET_VINDPM] = charging_set_vindpm;//设置电池vindpm
}
if (cmd < CHARGING_CMD_NUMBER) {
if (charging_func[cmd] != NULL)
return charging_func[cmd](data);
}
pr_debug("[%s]UNSUPPORT Function: %d\n", __func__, cmd);
return STATUS_UNSUPPORTED;
}