电池bq15601 充电ic驱动i2c子系统 笔记
/* module_init(bq25601_init); */
/* module_exit(bq25601_exit); */
subsys_initcall(bq25601_subsys_init);
MODULE_LICENSE("GPL");
MODULE_DESCRIPTION("I2C bq25601 Driver");
static int __init bq25601_subsys_init(void) //回调内核一开机就会自动调用
{
int ret = 0;
//检测i2c上的电池bq25601_driver驱动
if (i2c_add_driver(&bq25601_driver) != 0)
battery_log(BAT_LOG_CRTI, "[bq24261_init] failed to register bq24261 i2c driver.\n");
else
battery_log(BAT_LOG_CRTI, "[bq24261_init] Success to register bq24261 i2c driver.\n");
/* bq25601 user space access interface 用户空间通道接口*///注册平台设备dev和平台驱动drvier
ret = platform_device_register(&bq25601_user_space_device);//注册平台设备dev
if (ret) {
battery_log(BAT_LOG_CRTI, "****[bq25601_init] Unable to device register(%d)\n", ret);
return ret;
}
ret = platform_driver_register(&bq25601_user_space_driver);//注册平台驱动drvier
if (ret) {
battery_log(BAT_LOG_CRTI, "****[bq25601_init] Unable to register driver (%d)\n", ret);
return ret;
}
return 0;
}
struct platform_device bq25601_user_space_device = {
.name = "bq25601-user", //用于匹配
.id = -1,
};
static struct platform_driver bq25601_user_space_driver = {
.probe = bq25601_user_space_probe,
.driver = {
.name = "bq25601-user",//用于匹配
},
};
static int bq25601_user_space_probe(struct platform_device *dev)
{
int ret_device_file = 0;
battery_log(BAT_LOG_CRTI, "******** bq25601_user_space_probe!! ********\n");
ret_device_file = device_create_file(&(dev->dev), &dev_attr_bq25601_access);
return 0;
}
static DEVICE_ATTR(bq25601_access, 0664, show_bq25601_access, store_bq25601_access); /* 664 */
/**********************************************************
*
* [platform_driver API] 平台设备驱动api
*
*********************************************************/
unsigned char g_reg_value_bq25601 = 0;
static ssize_t show_bq25601_access(struct device *dev, struct device_attribute *attr, char *buf)
{
battery_log(BAT_LOG_CRTI, "[show_bq25601_access] 0x%x\n", g_reg_value_bq25601);
return sprintf(buf, "%u\n", g_reg_value_bq25601);
}
static ssize_t store_bq25601_access(struct device *dev, struct device_attribute *attr,
const char *buf, size_t size)
{
int ret = 0;
char *pvalue = NULL, *addr, *val;
unsigned int reg_value = 0;
unsigned int reg_address = 0;
battery_log(BAT_LOG_CRTI, "[store_bq25601_access]\n");
if (buf != NULL && size != 0) {
battery_log(BAT_LOG_CRTI, "[store_bq25601_access] buf is %s and size is %zu\n", buf, size);
/*reg_address = kstrtoul(buf, 16, &pvalue);*/
pvalue = (char *)buf;
if (size > 3) {
addr = strsep(&pvalue, " "); //取地址
ret = kstrtou32(addr, 16, (unsigned int *)®_address);
} else
ret = kstrtou32(pvalue, 16, (unsigned int *)®_address);
if (size > 3) {
val = strsep(&pvalue, " "); //取值
ret = kstrtou32(val, 16, (unsigned int *)®_value);
battery_log(BAT_LOG_CRTI,
"[store_bq25601_access] write bq25601 reg 0x%x with value 0x%x !\n",
reg_address, reg_value);
//参数1 寄存器的地址,参数2寄存器的 值 参数3 用于清零 参数4 移位的个数
//使能配置寄存器,通过i2c读值在写值
ret = bq25601_config_interface(reg_address, reg_value, 0xFF, 0x0);
} else {参数1 寄存器的地址,参数2寄存器的 值 参数3 用于清零 参数4 移位的个数
//读寄存器的值
ret = bq25601_read_interface(reg_address, &g_reg_value_bq25601, 0xFF, 0x0);
battery_log(BAT_LOG_CRTI,
"[store_bq25601_access] read bq25601 reg 0x%x with value 0x%x !\n",
reg_address, g_reg_value_bq25601);
battery_log(BAT_LOG_CRTI,
"[store_bq25601_access] Please use \"cat bq25601_access\" to get value\r\n");
}
}
return size;
}
/**********************************************************
*
* [Internal Function]
*
*********************************************************/
void bq25601_hw_component_detect(void) //硬件探测通过i2c寻址
{
unsigned int ret = 0;
unsigned char val = 0;
ret = bq25601_read_interface(0x0B, &val, 0xF, 0x3);
if (val == 0)
g_bq25601_hw_exist = 0;
else
g_bq25601_hw_exist = 1;
battery_log(BAT_LOG_CRTI, "[bq25601_hw_component_detect] exist=%d, Reg[0x0b][3-6]=0x%x\n", g_bq25601_hw_exist, val);
}
int is_bq25601_exist(void)
{
battery_log(BAT_LOG_CRTI, "[is_bq25601_exist] g_bq25601_hw_exist=%d\n", g_bq25601_hw_exist);
return g_bq25601_hw_exist;
}
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 void bq25601_parse_customer_setting(void)//解析充电状态客制化
{
#ifdef CONFIG_OF
struct pinctrl *pinctrl;
struct pinctrl_state *ptrl_chren_low;
pinctrl = devm_pinctrl_get(&new_client->dev);
if (IS_ERR(pinctrl)) {
battery_log(BAT_LOG_CRTI, "[%s]Cannot find drvvbus pinctrl, err=%d\n",
__func__, (int)PTR_ERR(pinctrl));
return;
}
ptrl_chren_low = pinctrl_lookup_state(pinctrl, "chren_low");
if (IS_ERR(ptrl_chren_low)) {
battery_log(BAT_LOG_CRTI, "[%s]Cannot find chren_low state, err=%d\n",
__func__, (int)PTR_ERR(ptrl_chren_low));
return;
}
pinctrl_select_state(pinctrl, ptrl_chren_low);
devm_pinctrl_put(pinctrl);
battery_log(BAT_LOG_CRTI, "[%s]pinctrl_select_state success\n", __func__);
#endif
}
static int bq25601_driver_probe(struct i2c_client *client, const struct i2c_device_id *id)
{
int err = 0;
battery_log(BAT_LOG_CRTI, "[bq25601_driver_probe]\n");
client->addr = 0x6b;
//为new_client 分配一个内存空间
new_client = kmalloc(sizeof(struct i2c_client), GFP_KERNEL);
if (!new_client) {
err = -ENOMEM;
goto exit;
}
memset(new_client, 0, sizeof(struct i2c_client));//清空new_client这个空间
new_client = client;//把传进去的client保存
//elink_charge_init(client);
/* --------------------- */
bq25601_hw_component_detect(); //硬件探测通过i2c寻址
bq25601_dump_register();//读bq25601所有保存在寄存器的值
chargin_hw_init_done = KAL_TRUE; //将充电硬件初始化的标志置位
bq25601_parse_customer_setting();//解析充电状态客制化
return 0;
exit:
return err;
}
/**********************************************************
*
* [Internal Function]
*
*********************************************************/
/* CON0---------------------------------------------------- */
void bq25601_set_en_hiz(unsigned int val) //使能
{
启用HIZ模式0-禁用(默认)1-启用
unsigned int ret = 0;
printk("1111 bq25601_set_en_hiz\r\n");
ret = bq25601_config_interface((unsigned char) (bq25601_CON0),
(unsigned char) (val),
(unsigned char) (CON0_EN_HIZ_MASK),
(unsigned char) (CON0_EN_HIZ_SHIFT)
);
}
void bq25601_set_ichg_mon(unsigned int val)
{
unsigned int ret = 0;
ret = bq25601_config_interface((unsigned char) (bq25601_CON0),
(unsigned char) (val),
(unsigned char) (CON0_ICHG_MON_MASK),
(unsigned char) (CON0_ICHG_MON_SHIFT)
);
}
void bq25601_set_iindpm(unsigned int val)
{
输入电流限制马抵消:100范围:100 mA (000000) -3.2 A (11111)默认:2400毫安(10111),
最大输入电流限制,不典型。输入源检测完成后,IINDPM位自动改变,PSEL = Hi = 500 mA PSEL = Lo= 2.4
主机在输入源检测完成后,可以重写IINDPM寄存器位。
unsigned int ret = 0;
ret = bq25601_config_interface((unsigned char) (bq25601_CON0),
(unsigned char) (val),
(unsigned char) (CON0_IINDPM_MASK),
(unsigned char) (CON0_IINDPM_SHIFT)
);
}
/* CON1---------------------------------------------------- */
void bq25601_set_pfm_dis(unsigned int val)
{
评论默认值:0 -启用
unsigned int ret=0;
ret=bq25601_config_interface( (unsigned char)(bq25601_CON1),
(unsigned char)(val),
(unsigned char)(CON1_PFM_DIS_MASK),
(unsigned char)(CON1_PFM_DIS_SHIFT)
);
}
void bq25601_set_wdt_rst(unsigned int val)
{默认:正常(0)回到0后,看门狗定时器重置
unsigned int ret=0;
ret=bq25601_config_interface( (unsigned char)(bq25601_CON1),
(unsigned char)(val),
(unsigned char)(CON1_WDT_RST_MASK),
(unsigned char)(CON1_WDT_RST_SHIFT)
);
}
void bq25601_set_otg_config(unsigned int val)
{默认:OTG禁用(0)1。OTG配置将超越。在CHG配置中启用充电功能
unsigned int ret=0;
ret=bq25601_config_interface( (unsigned char)(bq25601_CON1),
(unsigned char)(val),
(unsigned char)(CON1_OTG_CONFIG_MASK),
(unsigned char)(CON1_OTG_CONFIG_SHIFT)
);
}
void bq25601_set_chg_config(unsigned int val)
{0-电荷禁用1-电荷启用 默认:充电电池(1)
注意:1。在电荷cE引脚在拉低和chg_config是1这两种情况下,电荷启用。
unsigned int ret=0;
ret=bq25601_config_interface( (unsigned char)(bq25601_CON1),
(unsigned char)(val),
(unsigned char)(CON1_CHG_CONFIG_MASK),
(unsigned char)(CON1_CHG_CONFIG_SHIFT)
);
}
void bq25601_set_sys_min(unsigned int val)
{
系统最小电压
1000:2.6 v| 001:2.8 v|010: 3V 1011: 3.2V 100: 3.4 V 101: 3.5 V 110: 3.6 V| 111:3.7 v|默认值:3.5 V (101)
unsigned int ret=0;
ret=bq25601_config_interface( (unsigned char)(bq25601_CON1),
(unsigned char)(val),
(unsigned char)(CON1_SYS_MIN_MASK),
(unsigned char)(CON1_SYS_MIN_SHIFT)
);
}
void bq25601_set_min_vbat_sel(unsigned int val)
{
0-2.8 V蝙蝠坠落,圣通过再保险1-2.5 V蝙蝠坠落
OTG模式的最小电池电压。默认下降 2.8 V (0);
上升阈值 3.0 V (0)
unsigned int ret=0;
ret=bq25601_config_interface( (unsigned char)(bq25601_CON1),
(unsigned char)(val),
(unsigned char)(CON1_MIN_VBAT_SEL_MASK),
(unsigned char)(CON1_MIN_VBAT_SEL_SHIFT)
);
}
/* CON2---------------------------------------------------- */
void bq25601_set_boost_lim(unsigned int val)
{默认值:1.2 A (1)•
列出的当前限制选项是。最小电流限制规格。
unsigned int ret=0;
ret=bq25601_config_interface( (unsigned char)(bq25601_CON2),
(unsigned char)(val),
(unsigned char)(CON2_BOOST_LIM_MASK),
(unsigned char)(CON2_BOOST_LIM_SHIFT)
);
}
void bq25601_set_q1_fullon(unsigned int val)
{
当IINDPM <700mA(更准确)时0-使用较高的Q1 RDSON值1-使用较低的Q1 RDSON值(更有效)
在boost模式下,总是使用全场效应晶体管,而这个位没有任何影响-使用较低的Q1 alwavs(效率更高)
unsigned int ret=0;
ret=bq25601_config_interface( (unsigned char)(bq25601_CON2),
(unsigned char)(val),
(unsigned char)(CON2_Q1_FULLON_MASK),
(unsigned char)(CON2_Q1_FULLON_SHIFT)
);
}
void bq25601_set_ichg(unsigned int val)
{
快速充电电流默认值:2040mA(100010)
范围:0mA (0000000)-3000 mA (110010)
注意:ICHG = 0 mA禁用电荷。
ICHG > 3000ma(110010夹紧注册值3000ma (110010))
unsigned int ret=0;
ret=bq25601_config_interface( (unsigned char)(bq25601_CON2),
(unsigned char)(val),
(unsigned char)(CON2_ICHG_MASK),
(unsigned char)(CON2_ICHG_SHIFT)
);
}
/* CON3---------------------------------------------------- */
void bq25601_set_iprechg(unsigned int val)
{
预先充电电流默认值:180ma (0010)抵消:60ma
注:IPRECHG> 780 mA夹紧到780 mA (1100)
unsigned int ret=0;
ret=bq25601_config_interface( (unsigned char)(bq25601_CON3),
(unsigned char)(val),
(unsigned char)(CON3_IPRECHG_MASK),
(unsigned char)(CON3_IPRECHG_SHIFT)
);
}
void bq25601_set_iterm(unsigned int val)
{
终止充电电流默认值:180ma (0010)抵消:60ma
unsigned int ret=0;
ret=bq25601_config_interface( (unsigned char)(bq25601_CON3),
(unsigned char)(val),
(unsigned char)(CON3_ITERM_MASK),
(unsigned char)(CON3_ITERM_SHIFT)
);
}
/* CON4---------------------------------------------------- */
void bq25601_set_vreg(unsigned int val)
{
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)
unsigned int ret=0;
ret=bq25601_config_interface( (unsigned char)(bq25601_CON4),
(unsigned char)(val),
(unsigned char)(CON4_VREG_MASK),
(unsigned char)(CON4_VREG_SHIFT)
);
}
void bq25601_set_topoff_timer(unsigned int val)
{
满足终止条件后的延长时间。当禁用时,当满足终止条件时充电终止
00-Disabled(默认)101 - 15分钟10 - 30分钟11-45分钟
unsigned int ret=0;
ret=bq25601_config_interface( (unsigned char)(bq25601_CON4),
(unsigned char)(val),
(unsigned char)(CON4_TOPOFF_TIMER_MASK),
(unsigned char)(CON4_TOPOFF_TIMER_SHIFT)
);
}
void bq25601_set_vrechg(unsigned int val)
{
充值阈值默认值:100mV (0)
unsigned int ret=0;
ret=bq25601_config_interface( (unsigned char)(bq25601_CON4),
(unsigned char)(val),
(unsigned char)(CON4_VRECHG_MASK),
(unsigned char)(CON4_VRECHG_SHIFT)
);
}
/* CON5---------------------------------------------------- */
void bq25601_set_en_term(unsigned int val)
{0-禁用1-启用默认:启用终止(1)
unsigned int ret=0;
ret=bq25601_config_interface( (unsigned char)(bq25601_CON5),
(unsigned char)(val),
(unsigned char)(CON5_EN_TERM_MASK),
(unsigned char)(CON5_EN_TERM_SHIFT)
);
}
void bq25601_set_watchdog(unsigned int val)
{
00-禁用定时器,01-40 s, 10 80 s。11-160 s默认值:40 s (01)
unsigned int ret=0;
ret=bq25601_config_interface( (unsigned char)(bq25601_CON5),
(unsigned char)(val),
(unsigned char)(CON5_WATCHDOG_MASK),
(unsigned char)(CON5_WATCHDOG_SHIFT)
);
}
void bq25601_set_en_timer(unsigned int val)
{
| 0 -禁用
1启用快速充电和预充电计时器 默认值:使(1)
unsigned int ret=0;
unsigned int ret=0;
ret=bq25601_config_interface( (unsigned char)(bq25601_CON5),
(unsigned char)(val),
(unsigned char)(CON5_EN_TIMER_MASK),
(unsigned char)(CON5_EN_TIMER_SHIFT)
);
}
void bq25601_set_chg_timer(unsigned int val)
{
0-5小时
1-10小时 默认值:10小时(1)
ret=bq25601_config_interface( (unsigned char)(bq25601_CON5),
(unsigned char)(val),
(unsigned char)(CON5_CHG_TIMER_MASK),
(unsigned char)(CON5_CHG_TIMER_SHIFT)
);
}
void bq25601_set_treg(unsigned int val)
{
热调节阈值: 0-90°C 1 - 110°C
默认值:110°C(1)
unsigned int ret=0;
ret=bq25601_config_interface( (unsigned char)(bq25601_CON5),
(unsigned char)(val),
(unsigned char)(CON5_TREG_MASK),
(unsigned char)(CON5_TREG_SHIFT)
);
}
void bq25601_set_jeita_iset(unsigned int val)
{
0 -50% lCHG
1-20% ICHG 默认值:20%(1)
unsigned int ret=0;
ret=bq25601_config_interface( (unsigned char)(bq25601_CON5),
(unsigned char)(val),
(unsigned char)(CON5_JEITA_ISET_MASK),
(unsigned char)(CON5_JEITA_ISET_SHIFT)
);
}
/* CON6---------------------------------------------------- */
void bq25601_set_ovp(unsigned int val)
{
默认值 6.5v 01
VAC OVP阈值:00-55V
01-6.5 V (5-V输入)
10-10.5 V (9-V输入)
11 14v (12-V输入)
unsigned int ret=0;
ret=bq25601_config_interface( (unsigned char)(bq25601_CON6),
(unsigned char)(val),
(unsigned char)(CON6_OVP_MASK),
(unsigned char)(CON6_OVP_SHIFT)
);
}
void bq25601_set_boostv(unsigned int val)
{
提升调节电压:00-4.85V 01 - 5.00 v 10 - 5.15 v 11 - 5.30 v
unsigned int ret=0;
ret=bq25601_config_interface( (unsigned char)(bq25601_CON6),
(unsigned char)(val),
(unsigned char)(CON6_BOOSTV_MASK),
(unsigned char)(CON6_BOOSTV_SHIFT)
);
}
void bq25601_set_vindpm(unsigned int val)
{
800 MV 400 MV 200 MV 100 MV
绝对VINDPM阈值。抵消:3.9 V范围:3.9 V (0000)-5.4 (1111)у默认值:4.5 v(0110)
unsigned int ret=0;
ret=bq25601_config_interface( (unsigned char)(bq25601_CON6),
(unsigned char)(val),
(unsigned char)(CON6_VINDPM_MASK),
(unsigned char)(CON6_VINDPM_SHIFT)
);
}
/* CON7---------------------------------------------------- */
void bq25601_set_iindet_en(unsigned int val)
{
0-没有输入电流限制 1 检测当VBUS存在时,力输入电流极限检测 输入检测完成后返回0
unsigned int ret=0;
ret=bq25601_config_interface( (unsigned char)(bq25601_CON7),
(unsigned char)(val),
(unsigned char)(CON7_IINDET_EN_MASK),
(unsigned char)(CON7_IINDET_EN_SHIFT)
);
}
void bq25601_set_tmr2x_en(unsigned int val)
{
0-Disable一1 -在输入DPM (V和I)或JEITA cool或heat requlation期间,安全计时器减慢2倍
unsigned int ret=0;
ret=bq25601_config_interface( (unsigned char)(bq25601_CON7),
(unsigned char)(val),
(unsigned char)(CON7_TMR2X_EN_MASK),
(unsigned char)(CON7_TMR2X_EN_SHIFT)
);
}
void bq25601_set_batfet_disable(unsigned int val)
{
O -允许Q4开启,1 -关闭第04ith默认:允许Q4开启(0)推迟时间
unsigned int ret=0;
ret=bq25601_config_interface( (unsigned char)(bq25601_CON7),
(unsigned char)(val),
(unsigned char)(CON7_BATFET_Disable_MASK),
(unsigned char)(CON7_BATFET_Disable_SHIFT)
);
}
void bq25601_set_jeita_vset(unsigned int val)
{
0 将充电电压设置为4.1v 1 将充电电压设置为VREG
unsigned int ret=0;
ret=bq25601_config_interface( (unsigned char)(bq25601_CON7),
(unsigned char)(val),
(unsigned char)(CON7_JEITA_VSET_MASK),
(unsigned char)(CON7_JEITA_VSET_SHIFT)
);
}
void bq25601_set_batfet_dly(unsigned int val)
{
0 当BATFET DIS位被设置时,立即关闭BATEET
1 当BATEFT DIS位被设置时 ,在延时(typ。10秒
)后关闭BATFET,
-
默认值:1在t后关闭BATFET,(typ。10秒
)当当BATEFT DIS位被设置时
unsigned int ret=0;
ret=bq25601_config_interface( (unsigned char)(bq25601_CON7),
(unsigned char)(val),
(unsigned char)(CON7_BATFET_DLY_MASK),
(unsigned char)(CON7_BATFET_DLY_SHIFT)
);
}
void bq25601_set_batfet_rst_en(unsigned int val)
{
0-禁用BATFET复位函数1-启用BATFET复位函数默认值:1启用BATFET复位功能。
unsigned int ret=0;
ret=bq25601_config_interface( (unsigned char)(bq25601_CON7),
(unsigned char)(val),
(unsigned char)(CON7_BATFET_RST_EN_MASK),
(unsigned char)(CON7_BATFET_RST_EN_SHIFT)
);
}
void bq25601_set_vdpm_bat_track(unsigned int val)
{
00 -禁用功能(注册设置VINDPM) 0 1 - vbat + 200 mv 10 - vbat + 250 mv 11 - vbat + 300 mv
设置VINDPM以跟踪BAT电压。
实际的VINDPM在寄存器值和VBAT+ VDPM
unsigned int ret=0;
ret=bq25601_config_interface( (unsigned char)(bq25601_CON7),
(unsigned char)(val),
(unsigned char)(CON7_VDPM_BAT_TRACK_MASK),
(unsigned char)(CON7_VDPM_BAT_TRACK_SHIFT)
);
}
/* CON8---------------------------------------------------- */
unsigned int bq25601_get_system_status_con8(void)
{
系统状态位
unsigned int ret=0;
unsigned char val=0;
ret=bq25601_read_interface( (unsigned char)(bq25601_CON8),
(&val),
(unsigned char)(0xFF),
(unsigned char)(0x0)
);
return val;
}
unsigned int bq25601_get_vbus_stat(void)
{
通风装置状态寄存器
000:没有输入
001:USB主机SDP(500毫安)→PSEL HIGH
010:2.4适配器→PSEL低
111:OTG
软件当前限制在IINDPM寄存器中报告
unsigned int ret=0;
unsigned char val=0;
ret=bq25601_read_interface( (unsigned char)(bq25601_CON8),
(&val),
(unsigned char)(CON8_VBUS_STAT_MASK),
(unsigned char)(CON8_VBUS_STAT_SHIFT)
);
return val;
}
unsigned int bq25601_get_chrg_stat(void)
{
充电状态:00-Not充电 01-Pre-charge(< VBATLOw) 10-Fast充电 11充电终止
unsigned int ret=0;
unsigned char val=0;
ret=bq25601_read_interface( (unsigned char)(bq25601_CON8),
(&val),
(unsigned char)(CON8_CHRG_STAT_MASK),
(unsigned char)(CON8_CHRG_STAT_SHIFT)
);
return val;
}
unsigned int bq25601_get_pg_stat(void)
{
功率良好状态:0-功率不好 1 能力好
unsigned int ret=0;
unsigned char val=0;
ret=bq25601_read_interface( (unsigned char)(bq25601_CON8),
(&val),
(unsigned char)(CON8_PG_STAT_MASK),
(unsigned char)(CON8_PG_STAT_SHIFT)
);
return val;
}
unsigned int bq25601_get_therm_stat(void)
{
0 不是在其他mai监管中
1-在其他mai监管中
unsigned int ret=0;
unsigned char val=0;
ret=bq25601_read_interface( (unsigned char)(bq25601_CON8),
(&val),
(unsigned char)(CON8_THERM_STAT_MASK),
(unsigned char)(CON8_THERM_STAT_SHIFT)
);
return val;
}
unsigned int bq25601_get_vsys_stat(void)
{
0-非VSYSMin射频监管中(BAT > VSYSMin)
1- VSYSMin射频监管中(BAT <VSYSMin)
unsigned int ret=0;
unsigned char val=0;
ret=bq25601_read_interface( (unsigned char)(bq25601_CON8),
(&val),
(unsigned char)(CON8_VSYS_STAT_MASK),
(unsigned char)(CON8_VSYS_STAT_SHIFT)
);
return val;
}
/* CON9---------------------------------------------------- */
unsigned int bq25601_get_system_status_con9(void)
{
得到系统状态
unsigned int ret=0;
unsigned char val=0;
ret=bq25601_read_interface( (unsigned char)(bq25601_CON9),
(&val),
(unsigned char)(0xFF),
(unsigned char)(0x0)
);
return val;
}
/* CON10---------------------------------------------------- */
unsigned int bq25601_get_system_status_con10(void)
{
得到系统状态
unsigned int ret=0;
unsigned char val=0;
ret=bq25601_read_interface( (unsigned char)(bq25601_CON10),
(&val),
(unsigned char)(0xFF),
(unsigned char)(0x0)
);
return val;
}
void bq25601_set_vindpm_int_mask(unsigned int val)
{
0-Not VINDPM。1 VINDPM
unsigned int ret=0;
ret=bq25601_config_interface( (unsigned char)(bq25601_CON10),
(val),
(unsigned char)(CON10_VINDPM_INT_MASK),
(unsigned char)(CON10_VINDPM_INT_SHIFT)
);
}
void bq25601_set_iindpm_int_mask(unsigned int val)
{
0-Not in IINDPM. 1-in IINDPMI
unsigned int ret=0;
ret=bq25601_config_interface( (unsigned char)(bq25601_CON10),
(val),
(unsigned char)(CON10_IINDPM_INT_MASK),
(unsigned char)(CON10_IINDPM_INT_SHIFT)
);
}
/* CON11---------------------------------------------------- */
unsigned int bq25601_get_system_status_con11(void)
{
获取系统状态
unsigned int ret=0;
unsigned char val=0;
ret=bq25601_read_interface( (unsigned char)(bq25601_CON11),
(&val),
(unsigned char)(0xFF),
(unsigned char)(0x0)
);
return val;
}
void bq25601_set_reg_rst(unsigned int val)
{
寄存器复位
0保持当前寄存器设置
1-Reset to default寄存器值和reset safety timer
注意:在寄存器重置完成后,位重置为0
unsigned int ret=0;
ret=bq25601_config_interface( (unsigned char)(bq25601_CON11),
(val),
(unsigned char)(CON11_REG_RST_MASK),
(unsigned char)(CON11_REG_RST_SHIFT)
);
}
/**********************************************************
*
* [Read / Write Function]
*
*********************************************************/
unsigned int bq25601_read_interface(unsigned char RegNum, unsigned char *val, unsigned char MASK,
unsigned char SHIFT)
{
unsigned char bq25601_reg = 0;
int ret = 0;
battery_log(BAT_LOG_FULL, "--------------------------------------------------\n");
ret = bq25601_read_byte(RegNum, &bq25601_reg);
battery_log(BAT_LOG_FULL, "[bq25601_read_interface] Reg[%x]=0x%x\n", RegNum, bq25601_reg);
bq25601_reg &= (MASK << SHIFT);
*val = (bq25601_reg >> SHIFT);
battery_log(BAT_LOG_FULL, "[bq25601_read_interface] val=0x%x\n", *val);
return ret;
}
unsigned int bq25601_config_interface(unsigned char RegNum, unsigned char val, unsigned char MASK,
unsigned char SHIFT)
{
unsigned char bq25601_reg = 0;
int ret = 0;
battery_log(BAT_LOG_FULL, "--------------------------------------------------\n");
printk("11111bq25601_config_interface\r\n");
ret = bq25601_read_byte(RegNum, &bq25601_reg);
battery_log(BAT_LOG_FULL, "[bq25601_config_interface] Reg[%x]=0x%x\n", RegNum, bq25601_reg);
bq25601_reg &= ~(MASK << SHIFT);
bq25601_reg |= (val << SHIFT);
ret = bq25601_write_byte(RegNum, bq25601_reg);
battery_log(BAT_LOG_FULL, "[bq25601_config_interface] write Reg[%x]=0x%x\n", RegNum, bq25601_reg);
/* Check */
/* bq25601_read_byte(RegNum, &bq25601_reg); */
/* battery_log(BAT_LOG_FULL, "[bq25601_config_interface] Check Reg[%x]=0x%x\n", RegNum, bq25601_reg); */
return ret;
}
/* write one register directly */ //直接写一个寄存器
unsigned int bq25601_reg_config_interface(unsigned char RegNum, unsigned char val)
{
unsigned int ret = 0;
ret = bq25601_write_byte(RegNum, val);
return ret;
}
/**********************************************************
*
* [I2C Function For Read/Write bq25601]
*
*********************************************************/
int bq25601_read_byte(unsigned char cmd, unsigned char *returnData)
{
char readData = 0;
int ret = 0;
struct i2c_msg msg[2];
struct i2c_adapter *adap = new_client->adapter;
printk("1111bq25601_read_byte\r\n");
mutex_lock(&bq25601_i2c_access);
msg[0].addr = new_client->addr;
msg[0].flags = 0;
msg[0].len = 1;
msg[0].buf = &cmd;
msg[1].addr = new_client->addr;
msg[1].flags = I2C_M_RD;
msg[1].len = 1;
msg[1].buf = &readData;
ret = i2c_transfer(adap, msg, 2);
if (ret < 0) {
mutex_unlock(&bq25601_i2c_access);
return 0;
}
*returnData = readData;
mutex_unlock(&bq25601_i2c_access);
return 1;
}
int bq25601_write_byte(unsigned char cmd, unsigned char writeData)
{
char write_data[2] = { 0 };
int ret = 0;
struct i2c_msg msg;
struct i2c_adapter *adap = new_client->adapter;
mutex_lock(&bq25601_i2c_access);
write_data[0] = cmd;
write_data[1] = writeData;
msg.addr = new_client->addr;
msg.flags = 0;
msg.len = 2;
msg.buf = (char *)write_data;
ret = i2c_transfer(adap, &msg, 1);
if (ret < 0) {
mutex_unlock(&bq25601_i2c_access);
return 0;
}
mutex_unlock(&bq25601_i2c_access);
return 1;
}
/**********************************************************
*
* [I2C Slave Setting]
*
*********************************************************/
#define bq25601_SLAVE_ADDR_WRITE 0xD6
#define bq25601_SLAVE_ADDR_READ 0xD7
static struct i2c_client *new_client;
static const struct i2c_device_id bq25601_i2c_id[] = { {"bq25601", 0}, {} };
kal_bool chargin_hw_init_done = KAL_FALSE;
static int bq25601_driver_probe(struct i2c_client *client, const struct i2c_device_id *id);
#ifdef CONFIG_OF
static const struct of_device_id bq25601_of_match[] = {
{.compatible = "bq25601",},
{},
};
MODULE_DEVICE_TABLE(of, bq25601_of_match);
#endif
static struct i2c_driver bq25601_driver = {
.driver = {
.name = "bq25601",
#ifdef CONFIG_OF
.of_match_table = bq25601_of_match,
#endif
},
.probe = bq25601_driver_probe,
.id_table = bq25601_i2c_id,
};
/**********************************************************
*
* [Global Variable]
*
*********************************************************/
unsigned char bq25601_reg[bq25601_REG_NUM] = { 0 };
static DEFINE_MUTEX(bq25601_i2c_access);
int g_bq25601_hw_exist = 0;
/**********************************************************