電池bq15601 充電ic驅動i2c子系統 筆記
阿新 • • 發佈:2018-12-24
電池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; /**********************************************************