前两天,我的机器一直可以进行USB充电,而且都充满了。就没太在意USB充电的问题。
但是最近,经常发现USB充不了电。于是用cat /proc/driver/deb2416x看一下寄存器配置,果然发现负责USB充电电流的寄存器2的值不对。
但是一直没找到哪个地方能设置这个值,因为这个值在模块初始化的时候会进行设置,之后代码里没有任何地方操作该寄存器。
问了下老大,他说应该是看门狗超时造成的。起初我不相信,因为其他的寄存器的值都是正确的。唯独寄存器2不对。但是其他寄存器都有恢复操作(在一个work里面进行设置,每20秒执行一次,也进行看门狗复位)。
其实,在这个work里面,也有对寄存器2的检查操作。但是检测的部分太少了,如果该寄存器的其他位改变了,那么还就真充不了电了。
先看看如何改代码
--- a/drivers/power/bq2416x_charger.c
+++ b/drivers/power/bq2416x_charger.c
@@ -353,16 +353,18 @@ static int bq2416x_check_reg02(struct bq2416x_device_info *di, int force)
}
}
else {
- if ((!(Reg2Val & 0x4)) || force) {
- //Reg2Val &= ~(1<<7);
- //Reg2Val |= (1<<2);
#ifdef USE_USB_CHARGER
- bq2416x_write_byte(di, 0x5c, Reg2Add);
+#define USB_CURRENT 0x5c
#else
- bq2416x_write_byte(di, 0x0c, Reg2Add);
+#define USB_CURRENT 0x0c
#endif
+ if ((Reg2Val != (USB_CURRENT | 0x80)) || force) { //这里需要改为判断当前的值是否与预期一致
+ //Reg2Val &= ~(1<<7);
+ //Reg2Val |= (1<<2);
+ bq2416x_write_byte(di, USB_CURRENT, Reg2Add);
}
}
+ return 0;
}
这样修改之后,一旦发生复位,则需要在20秒(因为work是20秒执行一次)内恢复。
看看文档上讲什么情况下才会复位:
DEFAULT mode is used when I2C communication is not available. DEFAULT mode is entered in the following
situations:
1. When the charger is enabled and VBAT< VBATGD before I2C communication is established
2. When the watchdog timer expires without a reset from the I2C interface and the safety timer has not expired.
3. When the device comes out of any fault condition (sleep mode, OVP, faulty adapter mode, etc.) before I2C
communication is established
看样子是第2种情况。
每隔20秒对watchdog复位一次,为什么还会出现这种情况呢???
有一种情况,那就是休眠。休眠的时候,肯定不会进行watchdog feed了,因为这个时候work都不工作了。但是硬件并没有断电。它认为你没有对watchdog复位(30秒内没reset,该值可以通过配寄存器设置),于是把所有寄存器恢复只default。
这样修改之后,在唤醒或插入USB线(插入USB肯定会唤醒机器),20秒内可以恢复至充电状态,其实,也可以修改resume函数,直接shedule这个work,里面的 delay参数传入0即可。这样就可以做到你一旦插入USB,则立刻进入充电状态。