工具/软件:
您好的团队、
我们是否有 适用于 BQ25180的基于内核6.1.55的 Linux 代码?
谢谢、
Leo
This thread has been locked.
If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.
尊敬的 TI:
我粘贴 bq2518x_set_precharacter_current 的代码:
------------------------------------------------------------
#define BQ2518X_PERCENTAGE 100
静态 int bq2518x_SET_PRECHARGE_CURRENT (结构 bq2518x_device *bq2518x、
整型值)
{
内部 ret;
unsigned int icharge_value;
unsigned int times_of_icharge;
icharge_value = bq2518x_get_const_charge_Current (bq2518x);
Times_of_icharge =(icharge_value / val)* BQ2518X_percentage;
开关(Times_of_icharge){
用例 BQ2518X_TIME_OF_ICHARGE01:
RET = regMAP_UPDATE_BITS (bq2518x->regmap、BQ2518X_CHARGERCTRL0、
BQ2518X_IPRECHG_MASK、(BQ2518X_TIME_OF_1X_TERM |
BQ2518X_Termination_CURRENT_PERCENT05));
休息;
用例 BQ2518X_TIME_OF_ICHARGE02:
RET = regMAP_UPDATE_BITS (bq2518x->regmap、BQ2518X_CHARGERCTRL0、
BQ2518X_IPRECHG_MASK、(BQ2518X_TIME_OF_1X_TERM |
BQ2518X_TERMINATION_CURRENT_PERCENT10));
休息;
用例 BQ2518X_TIME_OF_ICHARGE03:
RET = regMAP_UPDATE_BITS (bq2518x->regmap、BQ2518X_CHARGERCTRL0、
BQ2518X_IPRECHG_MASK、(BQ2518X_TIME_OF_1X_TERM |
BQ2518X_TERMINATION_CURRENT_PERCENT20));
休息;
用例 BQ2518X_TIME_OF_ICHARGE04:
RET = regMAP_UPDATE_BITS (bq2518x->regmap、BQ2518X_CHARGERCTRL0、
BQ2518X_IPRECHG_MASK、(BQ2518X_TIME_OF_2X_TERM |
BQ2518X_TERMINATION_CURRENT_PERCENT20));
休息;
默认值:
RET =-EVAL;
休息;
}
返回 ret;
}
------------------------------------------------------------
我不明白为什么 Times_of_icharge =(icharge 值/ val)* 100在2518x 驱动程序中? 因此、times_of_icharge 的值不能与 BQ2518X_TIME_OF_ICHARGE01 ~ BQ2518X_TIME_OF_ICHARGE04 (5/10/20/40)匹配、因此 ret =-EIINVAL 且加载驱动程序失败。
您能否帮助确认并解释此问题的原因? 因此,我不确定在 DTS 中配置什么值以确保驱动程序可以正常运行。
WNC/Jason
您好 Leo、
我们为 Linux 内核5.15开发的 BQ25180驱动程序。 它可以在6.1.55上正常工作、但由于内核 API 更改、可能会出现兼容性问题。
BQ2518x 驱动程序: e2e.ti.com/.../bq2518x_5F00_driver.tar.gz2
我建议尝试编译它以检查兼容性。 如果您遇到任何问题、请告诉我。
此致、
Alec
您好 Jason、
问题似乎与 Times_of_icharge 计算有关。
如果 val 配置为表示 DTS 中的预充电电流、则正确的计算方法应为:
Times_of_icharge =(val / icharge_value)* BQ2518X_percentage;
例如、如果您希望预充电电流为1A 快速充电电流的5%(其中 icharge_value = 1,000,000uA)、则计算结果为:
Times_of_icharge =(50,000uA / 1,000,000uA)* 100 = 5%
这将与 BQ2518X_TIME_OF_ICHARGE01匹配、并 正确设置预充电电流。
我建议修改如上所示的计算、以确保正确配置预充电电流。
如果不进行此调整、Times_of_icharge 似乎不会产生 有效值(5、10、20或40)。
请告诉我这是否有效以及您是否仍然遇到任何问题。
此致、
Alec
尊敬的 Alec:
1. 您提供的 BQ2518x 驱动程序无法在内核6.1.55下编译、因为 内核5.15 和内核6.1.55之间的 POWER_SUPPLY_GET_BATTERY_INFO 定义不同。 我不确定是否还有其他潜在问题。
2.#define BQ2518X_PERCENTAGE 100
静态 int bq2518x_SET_PRECHARGE_CURRENT (结构 bq2518x_device *bq2518x、int val)
{
内部 ret;
unsigned int icharge_value;
unsigned int times_of_icharge;
Times_of_icharge =(icharge_value / val)* BQ2518X_percentage
用例 BQ2518X_TIME_OF_ICHARGE01//5
用例 BQ2518X_TIME_OF_ICHARGE02 //10
用例 BQ2518X_TIME_OF_ICHARGE03 //20
用例 BQ2518X_TIME_OF_ICHARGE04 //40
默认值:
RET =-EVAL;
...........
无论 icharge_value 和 val 的值 是什么、Times_of_icharge 都是大于100或0的整数、而不是5/10/20/40。 所以 RET =-EVAL 和加载驱动程序失败。
您能告诉我您的电子邮件并在线与团队讨论吗?
谢谢!
WNC/Jason
您好 Jason、
感谢您的更新以及指出 power_SUPPLY_GET_BATTERY_INFO 的定义在不同内核版本之间发生了变化。 此更改可能会影响驱动程序编译、但我需要更多详细信息来确认它是中断更改还是存在另一个潜在问题。
您能否提供专门提到 POWER_SUPPLY_GET_BATTERY_INFO 问题的错误日志或编译消息?
澄清一下、用于计算 Times_of_icharge 的表达式可能会导致大于5、10、20或40的值。 为避免这种情况、我建议翻转括号内的表达式、如下所示:
times_of_icharge = (val / icharge_value) * BQ2518X_PERCENTAGE;
我将通过私人消息发送我的电子邮件给您、以便我们可以离线继续讨论。
此致、
Alec
尊敬的 Alec:
我修复了由 power_SUPPLY_GET_BATTERY_INFO 引起的编译问题 、引用内核6.1.55中的2515x 驱动程序。
--------------------------------
静态 int bq2518x_SET_PRECHARGE_CURRENT (结构 bq2518x_device *bq2518x、
整型值)
{
内部 ret;
unsigned int icharge_value;
unsigned int times_of_icharge;
icharge_value = bq2518x_get_const_charge_Current (bq2518x);
Times_of_icharge =(val / icharge_value)* BQ2518X_percentage;
printk ("icharge_value=%d、val=%d、times_of_icharge=%d、%s、%d\n"、icharge_value、val、times_of_icharge、__func__、__line__);
--------------------------------
调试信息: .icharge_value=770、val=50000、 times_of_icharge=6400
我的 DTS 配置 如下:
--------------------------------
BAT:电池{
兼容="简单电池";
恒定充电电流最大微安=<1000000>;
预充电电流微安=<50000>;
恒定充电电压最大微伏=<4650000>;
};
&lpi2c1{
#address-cells =<1>;
#size-cells =<0>;
时钟频率=< 400000>;
pinctrl-names ="default"、"sleep";
pinctrl-0 =<&pinctrl_lpi2c1>;
pinctrl-1 =<&pinctrl_lpi2c1>;
状态="正常";
...........
bq25180:充电器@6a{
兼容="ti、bq25180";
reg =<0x6A>;
Monitored-Battery =<&bat>;
输入电流限值微安=<1000000>;
};
};
--------------------------------
由于我的 DTS 配置不正确、Times_of_icharge 的值是否无效?
顺便说一下、 电流 和电压的单位是 DTS 和驱动器 micro 还是 milli? 似乎单位不统一。 例如
#define BQ2518X_ICHG_MAX_UA 1000
#define BQ2518X_VBAT_REG_MAX 4650000
现在我有一个严重的问题:电池无法充电。 是否与上述问题有关? 你能帮助一些建议来解决这个问题.
当前 属性:
root@imx93-14x14-LPDDR4X-EVK:~# cat /sys/devices/platform soc@0/44000000.bus/44340000.i2c/i2c-0/0-006a/power_supply/bq2518x-mains/uevent
POWER_SUPPLY_NAME=bq2518x-MAIN
POWER_SUPPLY_TYPE=MAIN
POWER_SUPPLY_ONLINE=1
POWER_SUPPLY_STATUS=未充电
POWER_SUPPLY_HEALTH_GOOD
POWER_SUPPLY_INPUT_CURRENT_LIMIT=1100000
POWER_SUPPLY_MODEL_NAME=bq25180
POWER_SUPPLY_MANUFACTURER =德州仪器(TI)
POWER_SUPPLY_CONSTANT_CHARGE_VOLTAGE=3500000
POWER_SUPPLY_CONSTANT_CHARGE_CURRENT=370
POWER_SUPPLY_PRECHARGE_CURRENT = 18
您好 Jason、
感谢您的更新。 我很高兴听到编译问题已得到解决。
times_of_icharge 的值是否无效、因为我的 DTS 配置不正确?
根据 DTS 配置、正确设置了50mA 预充电电流 val = 50,000。 但是、似乎将 icharge_value = 770设置为 mA、而 DTS 将充电电流定义为1,000,000uA。
问题可能是驱动程序中未正确设置 icharge_value、或者 DTS 与驱动程序代码之间存在一些不一致。 尽管 DTS 为充电电流指定了1,000,000,000、但驱动器读数似乎为770mA (即770,000uA)。 此差异导致 Times_of_icharge 计算不正确。
我建议仔细检查从 DTS 传递到驱动程序的 icharge_value。 似乎驱动器可能无法正确地解释 DTS 中的恒定充电电流值。 正确设置该值后、Times_of_icharge 计算应按预期工作。
BTW、 是电流 和电压的单位、以 DTS 和驱动器微或毫秒为单位? 似乎单位不统一。 如
在 Linux 内核电源等级中、电流和电压的单位应该始终是微控制器。 您的 DTS 似乎对电流使用了微安、这是正确的。
现在我有一个严重的问题:电池无法充电。 是否与上述问题有关? 您可以提供一些解决问题的建议。
此问题 可能与 DTS 配置或驱动程序问题有关。 解决驱动程序问题后、我们可以确定电池充电问题是否与此相关、或者是否完全是其他问题。 在电池未充电时、如果您能提供器件的寄存器转储、将会很有帮助。 这将有助于更深入地了解硬件级别的情况。 如果解决驱动程序问题后电池仍无法充电、我们可以采取进一步措施来调查该问题。
此致、
Alec
尊敬的 Alec:
感谢您的支持!
DTS 配置的值与显示的值不同、因为驱动程序会将其转换、然后显示它(电压与电流类似)。 代码如下:
--------------------------------
静态 int bq2518x_get_const_charge_current (结构 bq2518x_device *bq2518x)
{.......
RET = regMAP_Read (bq2518x->regmap、BQ2518X_ICHG_CTRL、&ichgctrl);
IF (RET)
返回 ret;
ichg_code = ichgctrl & BQ2518X_ICHG_MASK;
if ((ichg_code + BQ2518X_ICHG_MIN_STEP)<= BQ2518X_ICHG_LIMIT)
ichg = ichg_code + BQ2518X_ICHG_MIN_STEP;
暴露
ICHG = BQ2518X_ICHG_MAX_START +((ICHG_CODE - BQ2518X_ICHG_MAX_COMPARE)
* BQ2518X_ICHG_MAX_STEP);
返回 ichg;
}
静态 int bq2518x_set_const_charge_current (结构 bq2518x_device *bq2518x、
整型值)
{.......
如果(val > BQ2518X_ICHG_MAX_UA || val < BQ2518X_ICHG_MIN_UA){
return -EINVAL;
}
bq2518x_set_charge_disable (bq2518x、1);
RET = regMAP_UPDATE_BITS (bq2518x->regmap、BQ2518X_ICHG_CTRL、
BQ2518X_ICHG_MASK、VAL);
IF (RET)
返回 ret;
返回 bq2518x_set_charge_disable (bq2518x、0);
}
--------------------------------
我的测试:
回波1000000 >/sys/devices/platform / soc@0/44000000.bus/44340000.i2c/i2c-0/0-006a/power_supply/bq2518x-mains/constant_charge_current
Cat /sys/devices/platform soc@0/44000000.bus/44340000.i2c/i2c-0/0-006a/power_Supply/bq2518x-mains/constant_charge_current
POWER_SUPPLY_CONSTANT_CHARGE_CURRENT=370
回波1000 >/sys/devices/platform / soc@0/44000000.bus/44340000.i2c/i2c-0/0-006a/power_supply/bq2518x-mains/constant_charge_current
Cat /sys/devices/platform soc@0/44000000.bus/44340000.i2c/i2c-0/0-006a/power_Supply/bq2518x-mains/constant_charge_current
POWER_SUPPLY_CONSTANT_CHARGE_CURRENT=770
i2cdump -y -f 0 0x6a
root@imx93-14x14-LPDDR4X-EVK:~# i2cdump -y -f 0 0x6a
未指定大小(使用字节数据访问)
0 1 2 3 4 5 6 7 8 9 a b c d e f 0123456789abcdef
00: ` 00 00 7f 20 56 87 07 11 60 00 c0 ff ff ff ff f !@B.@ V ??? ....
10:FF ff ff ff ff ff ff FF 和 FF FF 和 FF FF ....
20:FF ff ff ff ff ff ff ff ff ff ff ff ff ff FF 和 FF FF 和 FF FF ....
您好 Jason、
我看到这里发生了什么。
驱动器不会将物理电流值(以 uA 为单位)转换为适当的寄存器代码。 相反、它会将该值直接写入寄存器。 稍后、当回读时、"get"函数会使用特定公式将该7位寄存器代码(范围为0-127)转换回物理电流。
"设置"功能中的驾驶员范围检查使用:
这意味着驱动器不会将写入的值馈入以 uA 为单位的物理电流;它会将该值视为 ICHG 代码(寄存器值)。
当您读回当前值时、过程如下所示:
例如:
寄存器字段使用7位掩码(BQ2518X_ICHG_MASK = 0x7f)、因此仅存储任何写入值的最低7位。 换句话说、任何大于127的数字都将除以128后减至其余数、这在数学上相当于取128模数。
例如:
这就是您在寄存器中看到值64和104的原因、"get"函数分别将其转换为370和770。 本质上、回传值不会从 uA 转换为适当的寄存器代码;只是被减少到0到127之间的数字。
此致、
Alec
尊敬的 Alec:
您能否帮助更新驱动程序以解决上述问题? 现在、我是通过 i2cset 命令写入寄存器、否则如果它是由 DTS 配置的、 驱动程序运行后寄存器值将与数据表不匹配、例如:
静态 int bq2518x_set_batt_reg (结构 bq2518x_device *bq2518x、int val)
{
INT VBAT_reg_code;
内部 ret;
如果(val > BQ2518X_VBAT_REG_MAX || val < BQ2518X_VBAT_REG_MIN)
return -EINVAL;
RET = regMAP_Read (bq2518x->regmap、BQ2518X_VBAT_CTRL、&VBAT_reg_code);
IF (RET)
返回 ret;
vbat_reg_code =((val - BQ2518X_VBAT_BASE_VOLT)/ BQ2518X_VBAT_STEP_UV)
(vbat_reg_code 和 BQ2518X_PG_MODE);
返回 regmap_write (bq2518x->regmap、BQ2518X_VBAT_CTRL、VBAT_reg_code);
}
您好 Jason、
我更新了 set 函数、以正确地将物理电流值(以 mA 为单位)转换为硬件预期的寄存器代码(ichg_code)。 更新后的命名现在反映了这些值以 mA 为单位。 以下是新的 SET 函数代码:
#define BQ2518X_ICHG_MIN_MA 5
#define BQ2518X_ICHG_MAX_MA 1000
#define BQ2518X_ICHG_MIN_STEP 5
#define BQ2518X_ICHG_LIMIT 35
#define BQ2518X_ICHG_MAX_START 40
#define BQ2518X_ICHG_MAX_COMPARE 31
#define BQ2518X_ICHG_MAX_STEP 10
static int bq2518x_set_const_charge_current(struct bq2518x_device *bq2518x, int val)
{
int ret;
int ichg_code;
if (val < BQ2518X_ICHG_MIN_MA || val > BQ2518X_ICHG_MAX_MA)
return -EINVAL;
if (val <= BQ2518X_ICHG_LIMIT) {
ichg_code = val - BQ2518X_ICHG_MIN_STEP;
} else {
ichg_code = ((val - BQ2518X_ICHG_MAX_START) / BQ2518X_ICHG_MAX_STEP) + BQ2518X_ICHG_MAX_COMPARE;
}
ichg_code &= BQ2518X_ICHG_MASK;
ret = bq2518x_set_charge_disable(bq2518x, 1);
if (ret)
return ret;
ret = regmap_update_bits(bq2518x->regmap, BQ2518X_ICHG_CTRL, BQ2518X_ICHG_MASK, ichg_code);
if (ret)
return ret;
return bq2518x_set_charge_disable(bq2518x, 0);
}
请测试此更新的代码并告诉我它是否解决了问题。
此致、
Alec
您好 Alec、
1.我更新了 bq2518x_SET_CONST_CHARGE_CURRENT 的函数、但最终寄存器值不是我想要的值。 您能告诉我如何 配置 DTS 以确保寄存器值如下:

我的 DTS 的当前配置如下:
BAT:电池{
兼容="简单电池";
恒定充电电流最大微安=<1000>;
预充电电流微安=<5000>;
恒定充电电压最大微伏=<4200000>;
};
...............
bq25180:充电器@6a{
兼容="ti、bq25180";
reg =<0x6A>;
Monitored-Battery =<&bat>;
输入电流限值微安=<1000000>;
};
"bq2518x_set_charge_disable"的功能似乎有问题 、您在上面提供的代码中也使用了该功能。
静态 int bq2518x_set_charge_disable (结构 bq2518x_device *bq2518x、int val)
{
if (val)
VAL = 0;
暴露
VAL = BQ2518X_CHG_DIS;
返回 regmap_update_bits (bq2518x->regmap、BQ2518X_ICHG_CTRL、
BQ2518X_CHG_DIS_MASK、val);
}
----------------------------------------------------
RET = bq2518x_SET_CHARGE_DISABLE (bq2518x、1);
RET = regMAP_UPDATE_BITS (bq2518x->regmap、BQ2518X_ICHG_CTRL、BQ2518X_ICHG_MASK、ichg_code);
返回 bq2518x_set_charge_disable (bq2518x、0);
----------------------------------------------------
bq2518x_SET_CHARGE_DISABLE (bq2518x、1) 将0设置为寄存器 BQ2518X_ICHG_CTRL 的位(7)。 这意味着电池充电已启用。
bq2518x_SET_CHARGE_DISABLE (bq2518x、0)表示 电池充电已禁用。 逻辑似乎不正确吗?

3.我更新了默认值、并注释"bq2518x_HW_INIT_" 、但寄存器值仍在修改、例如 BQ2518X_ICHG_CTRL、 BQ2518X_CHARGERCTRL1、BQ2518X_IC_CTRL 和 BQ2518X_IC_CTRL。 您能告诉我、 除了 "bq2518x_hw_init"外、还有哪里更改了寄存器的值?

您好 Jason、
即使您注释掉 bq2518x_hw_init()、regmap 默认缓存仍然适用。 该驱动程序具有一个由"默认"寄存器值(bq25180_reg_defaults[])组成的数组、并且 无论 bq2518x_hw_init ()是否被调用、regmap 都会将这些值写入探测器上的硬件。 这也解释了为什么您仍然看到寄存器相对于其真正的器件默认值发生了变化。
完成以下更改后、您应该能够看到适合您配置的正确寄存器值:
1.充电禁用
默认情况下、位7 (CHG_DIS)=1表示"禁用"、但驱动器的 逻辑被反转。
static int bq2518x_set_charge_disable(struct bq2518x_device *bq2518x, int val)
{
if (val)
val = BQ2518X_CHG_DIS;
else
val = 0;
return regmap_update_bits(bq2518x->regmap, BQ2518X_ICHG_CTRL, BQ2518X_CHG_DIS_MASK, val);
}
这会反转逻辑、因此通过1会真正禁用充电。
2.恒定充电电流
之前、代码直接编写了 val、假设这是寄存器代码。 现在、我们除以1000、将 DTS 值(uA)转换为 mA、然后计算寄存器代码。
static int bq2518x_set_const_charge_current(struct bq2518x_device *bq2518x, int val)
{
int ret;
val /= 1000;
...
return ret;
}
3.预充电电流
之前、该函数没有将 uA 转换为 mA、而分数公式被反转。
static int bq2518x_set_precharge_current(struct bq2518x_device *bq2518x, int val)
{
int ret;
unsigned int icharge_value;
unsigned int times_of_icharge;
val /= 1000;
icharge_value = bq2518x_get_const_charge_current(bq2518x);
times_of_icharge = (val / icharge_value) * BQ2518X_PERCENTAGE;
...
return ret;
}
DTS 示例
bat: battery {
compatible = "simple-battery";
constant-charge-voltage-max-microvolt = <4200000>;
constant-charge-current-max-microamp = <1000000>;
precharge-current-microamp = <100000>;
};
bq25180: charger@6b {
compatible = "ti,bq25180";
reg = <0x6a>;
monitored-battery = <&battery>;
input-current-limit-microamp = <1000000>;
};
如果这样可以解决您的问题、或者您还有其他问题、请告诉我。
此致、
Alec
您好 Alec、
在进行上述更改后、 寄存器值如下所示

不过、我期望的值如下所示:

请帮助检查 DTS 配置是否正确。 如何配置以获取所需的寄存器值?
BAT:电池{
兼容="简单电池";
恒定充电电压最大微伏=<4200000>;
恒定充电电流最大微安=<1000000>;
预充电电流微安=<1000000>;
};
bq25180:充电器@6B{
兼容="ti、bq25180";
reg =<0x6A>;
Monitored-Battery =<&BATTERY>;
输入电流限值微安=<1000000>;
};
您好 Jason、
感谢您的耐心等待我们完成这项工作。
Reg0x4、Reg0x6、Reg0x7和 Reg0x8似乎未正确设置、这意味着 ICHG、BATOCP、看门狗和 ILIM 未按预期配置。
修复 Reg0x8 (ILIM 位):
static int bq2518x_set_ilim_lvl(struct bq2518x_device *bq2518x, int val)
{
int i = 0;
unsigned int array_size = ARRAY_SIZE(bq2518x_ilim_lvl_values);
for (i = array_size - 1; i > 0; i--) {
if (val >= bq2518x_ilim_lvl_values[i])
break;
}
return regmap_update_bits(bq2518x->regmap, BQ2518X_TMR_ILIM, BQ2518X_ILIM_MASK, i);
}
FIX Reg0x4 (ICHG 位):
ret = power_supply_get_battery_info(bq2518x->battery, &bat_info);
我认为、这会导致驱动程序从电池节点(bq2518x->battery)读取实际定义的电池属性(例如、恒定充电电流最大微安)。 如果此问题修复了 Reg0x4、请告诉我。
修复 Reg0x7 (看门狗位):
修复 Reg0x6 (BATOCP 位):
有几个选项可用于配置 Reg0x6中的 BATOCP 位。 但是、最简单的选项可能是向驱动程序添加以下函数:
#define BQ2518X_BATOCP_MASK 0xc0
#define BQ2518X_BATOCP_1500MA BIT(7)
static int bq2518x_set_batocp_1500ma(struct bq2518x_device *bq2518x)
{
return regmap_update_bits(bq2518x->regmap, BQ2518X_CHARGERCTRL1, BQ2518X_BATOCP_MASK, BQ2518X_BATOCP_1500MA);
}
然后、我们可以在"bq2518x_hw_init ()"中调用此函数:
static int bq2518x_hw_init(struct bq2518x_device *bq2518x)
{
int ret;
/* Disable watchdog timers */
/* Set ILIM */
/* ... */
ret = bq2518x_set_batocp_1500ma(bq2518x);
if (ret)
return ret;
/* ... */
}
如果这些更改按预期配置寄存器、请告诉我、我们可以从中进行配置。
此致、
Alec
尊敬的 Alec:
感谢您的支持!
根据您建议的更改、 寄存器值如下所示:
仅电池电源

Reg0x4、Reg0x6、Reg0x7和 Reg0x8似乎设置正确,但 Reg0x3似乎不正确。
我当前的 DTS 配置:
BAT:电池{
兼容="简单电池";
恒定充电电流最大微安=<1000000>;
预充电电流微安=<1000000>;
恒定充电电压最大微伏=<4200000>;
};
bq25180:充电器@6a{
兼容="ti、bq25180";
reg =<0x6A>;
Monitored-Battery =<&bat>;
输入电流限制微安=<110000>;
};
CAT /sys/devices/platform soc@0/44000000.bus/44340000.i2c/i2c-0/0-006a/power_Supply/bq2518x-main/uevent
POWER_SUPPLY_NAME=bq2518x-MAIN
POWER_SUPPLY_TYPE=MAIN
POWER_SUPPLY_ONLINE=0
POWER_SUPPLY_STATUS=DISCHARGE
POWER_SUPPLY_HEALTH_GOOD
POWER_SUPPLY_INPUT_CURRENT_LIMIT=1100000
POWER_SUPPLY_MODEL_NAME=bq25180
POWER_SUPPLY_MANUFACTURER =德州仪器(TI)
POWER_SUPPLY_CONSTANT_CHARGE_VOLTAGE=3500000
POWER_SUPPLY_CONSTANT_CHARGE_CURRENT=370
POWER_SUPPLY_PRECHARGE_CURRENT = 18
CAT /sys/devices/platform soc@0/44000000.bus/44340000.i2c/i2c-0/0-006a/power_Supply/bq2518x-battery/uevent
POWER_SUPPLY_NAME=bq2518x-battery
POWER_SUPPLY_TYPE=Battery
POWER_SUPPLY_CONSTANT_CHARGE_CURRENT_MAX=1000000
POWER_SUPPLY_CONSTANT_CHARGE_VOLTAGE_MAX=4200000
外部电源+电池

CAT /sys/devices/platform soc@0/44000000.bus/44340000.i2c/i2c-0/0-006a/power_Supply/bq2518x-main/uevent
POWER_SUPPLY_NAME=bq2518x-MAIN
POWER_SUPPLY_TYPE=MAIN
POWER_SUPPLY_ONLINE=1
POWER_SUPPLY_STATUS=未充电
POWER_SUPPLY_HEALTH_GOOD
POWER_SUPPLY_INPUT_CURRENT_LIMIT=1100000
POWER_SUPPLY_MODEL_NAME=bq25180
POWER_SUPPLY_MANUFACTURER =德州仪器(TI)
POWER_SUPPLY_CONSTANT_CHARGE_VOLTAGE=3500000
POWER_SUPPLY_CONSTANT_CHARGE_CURRENT=370
POWER_SUPPLY_PRECHARGE_CURRENT = 18
仅 外部电源

CAT /sys/devices/platform soc@0/44000000.bus/44340000.i2c/i2c-0/0-006a/power_Supply/bq2518x-main/uevent
POWER_SUPPLY_NAME=bq2518x-MAIN
POWER_SUPPLY_TYPE=MAIN
POWER_SUPPLY_ONLINE=1
POWER_SUPPLY_STATUS=正在充电
POWER_SUPPLY_HEALTH_GOOD
POWER_SUPPLY_INPUT_CURRENT_LIMIT=1100000
POWER_SUPPLY_MODEL_NAME=bq25180
POWER_SUPPLY_MANUFACTURER =德州仪器(TI)
POWER_SUPPLY_CONSTANT_CHARGE_VOLTAGE=3500000
POWER_SUPPLY_CONSTANT_CHARGE_CURRENT=370
POWER_SUPPLY_PRECHARGE_CURRENT = 18
最后如上所述、power_supply_status 不正确吗? 顺便说一句, 如何检查电池的剩余电量和触发充电的条件?
您好 Jason、
我很高兴听到最近的修复现在正确设置了这些寄存器。
关于 Reg0x3、当前逻辑未正确清除所有位、这就是我们看到0x00的原因。 以下是一个更新的函数、可保留位7并正确设置低位:
static int bq2518x_set_batt_reg(struct bq2518x_device *bq2518x, int val)
{
int vbat_reg_code;
int ret;
if (val > BQ2518X_VBAT_REG_MAX || val < BQ2518X_VBAT_REG_MIN)
return -EINVAL;
ret = regmap_read(bq2518x->, BQ2518X_VBAT_CTRL, &vbat_reg_code);
if (ret)
return ret;
vbat_reg_code = (vbat_reg_code & BQ2518X_PG_MODE) | (((val - BQ2518X_VBAT_BASE_VOLT) / BQ2518X_VBAT_STEP_UV) & ~BQ2518X_PG_MODE);
return regmap_write(bq2518x->regmap, BQ2518X_VBAT_CTRL, vbat_reg_code);
}
做出此更改后、Reg0x3应反映预期的电池调节电压、而不是0x00。
至于 POWER_SUPPLY_STATUS、在每种情况下都是正确的。 当不存在电池时、充电器可能会报告"恒定电压"或"充电完成"、这就解释了为什么 POWER_SUPPLY_STATUS=Charging 只是在连接输入源的情况下进行充电。 BQ25180可以指示充电状态和故障、但不会测量电池的充电状态。 要获得准确的电池电量百分比或剩余容量、需要单独的电量监测计 IC。
请告诉我此更新是否解决了 Reg0x3问题。
此致、
Alec
您好 Jason、
没问题 —感谢更新。 当您禁用脚本时、Reg0x4、Reg0x5、Reg0x6和 Reg0x8看起来仍然不处于所需的值。
寄存器0x5:
尝试将预充电电流屏蔽更改为:
#define BQ2518X_IPRECHG_MASK 0x70
我认为该掩码只应更新 IPRECHG 和 ITERM 位。
寄存器0x4:
确保在 bq2518x_set_const_charge_current ()中除以1000 (即 val /= 1000;)、因此 DTS 中的1000000uA 变为1000mA。
寄存器0x6:
确保使用带掩码0xC0的 regmap_update_bits()来设置 BATOCP 位。
寄存器0x8:
确保在 ILIM = 1.1A 的情况下、DTS 设置输入电流限制微安=<1100000>。 另外、请确保 bq2518x_SET_ILIM_lvl ()使用 regmap_update_bits ()只更改位[2:0]。
如果您可以共享更新后的函数(例如 bq2518x_SET_CONST_CHARGE_CURRENT ()、bq2518x_SET_PRECHARGE_CURRENT ()等)、我可以快速确认该逻辑。 如果您有任何问题 、请告诉我、我随时为您提供帮助。
此致、
Alec
您好 Alec、
附加我当前的 DTS 配置:
BAT:电池{
兼容="简单电池";
恒定充电电流最大微安=<1000000>;
预充电电流微安=<1000000>;
恒定充电电压最大微伏=<4200000>;
};
bq25180:充电器@6a{
兼容="ti、bq25180";
reg =<0x6A>;
Monitored-Battery =<&bat>;
输入电流限制微安=<110000>;
};
谢谢。
您好 Jason、
不是问题! 非常感谢您在整个过程中的耐心和协作!
您说得对—bq2518x_set_precham_current ()存在整数除法问题。
目前,bq2518x_SET_PRECHARGE_CURRENT ()具有以下特性:
Times_of_icharge =(val / icharge_value)* 100;
由于 val 和 icharge_value 都是整数、因此(100 / 1000)变为0而不是0.1。 这会导致 Times_of_icharge 为零、函数返回错误。 若要解决此问题、只需先乘以、然后除以:
times_of_icharge = (val * BQ2518X_PERCENTAGE) / icharge_value;
这应导致(100 * 100)/ 1000 = 10、从而正确地提供10%的预充电。 然后切换语句应选择适当的分数(5%、10%、20%、40%)、而不是返回-EVAL。
告诉我这样是否解决了预充电电流问题-如果出现任何问题、我们随时乐意提供帮助。
此致、
Alec
您好 Jason、
感谢您的耐心。
如果您可以在每次函数调用后在 bq2518x_hw_init ()中添加调试打印语句来更新 Reg0x06或 Reg0x08、那么这会很有帮助。 例如:
ret = bq2518x_set_batocp_1500ma(bq2518x);
dev_info(bq2518x->dev, "bq2518x_set_batocp_1500ma ret=%d\n", ret);
if (!ret) {
unsigned int reg_val;
regmap_read(bq2518x->regmap, BQ2518X_CHARGERCTRL1, ®_val);
dev_info(bq2518x->dev, "CHARGERCTRL1 (Reg0x06) after BATOCP=0x%x\n", reg_val);
}
...
ret = bq2518x_set_ilim_lvl(bq2518x, bq2518x->init_data.ilim);
dev_info(bq2518x->dev, "bq2518x_set_ilim_lvl ret=%d\n", ret);
if (!ret) {
unsigned int reg_val;
regmap_read(bq2518x->regmap, BQ2518X_TMR_ILIM, ®_val);
dev_info(bq2518x->dev, "TMR_ILIM (Reg0x08) after ILIM=0x%x\n", reg_val);
}
如果寄存器在每次调用后立即显示正确的值、但稍后恢复、则意味着其他东西会覆盖它们。 如果它们根本不显示更新的位、我们就知道呼叫没有成功或被跳过。
关于电池温度、BQ25180没有集成 ADC 来报告温度(以度为单位)。 相反、它会监测 TS 引脚(通常连接到电池包的热敏电阻)并在 STAT1 (Reg0x01、位[4:3])中报告离散温度状态。 这些状态位报告电池是热电池、冷电池、温电池、凉电池还是正常电池、但充电器无法提供准确的温度值。 如果需要更精确的温度测量、则需要专用的电量监测计或外部 ADC 来读取 TS 引脚电压。
请告诉我您在日志中找到的内容。
此致、
Alec
您好 Jason、
查看驱动程序后、在 bq2518x_hw_init ()完成后、没有代码可写入 Reg0x06 (CHARGERCTRL1)或 Reg0x08 (TMR_ILIM)。 这意味着其他东西会更改这些寄存器中的值。
检查是否有任何可能写入这些寄存器的自定义脚本或 i2cset 命令。 如果使用 CONFIG_REGMAP_DEBUG 编译内核、则可以在内核日志(dmesg)中看到每个寄存器的读取/写入。 这应该有助于我们确定是什么写入这些值。
如果您在日志中发现任何可疑写入、请告诉我。
此致、
Alec
您好 Jason、
I 从 STAT 寄存器注意到器件处于 TS HOT 和 DPPM 状态。 您是否可以尝试删除输入源、然后再次读取寄存器?
另外、您能否将 bq2518x_disable_watchdog_timers ()重新添加到 hw_init ()中、看看这样是否会阻止寄存器复位?
最后、我对您的 reg_defaults 数组很好奇、您能否也分享这些值?
此致、
Alec
您好 Alec、
我将 bq2518x_disable_watchdog_timers ()添加回 hw_init () ,并删除输入源,然后 读取寄存器: 
我的 reg_defaults 数组:
静态常量结构体 reg_default bq25180_reg_defaults[]={
{BQ2518X_STAT0、0x0}、
{BQ2518X_STAT1、0x0}、
{BQ2518X_VBAT_CTRL、0x46}、
{BQ2518X_ICHG_CTRL、0x7F}、
{BQ2518X_CHARGERCTRL0、0x2C}、
{BQ2518X_CHARGERCTRL1、0x96}、
{BQ2518X_IC_CTRL、0x84}、
{BQ2518X_TMR_ILIM、0x4F}、
{BQ2518X_SHIP_RST、0x11}、
{BQ2518X_SYS_REG、0x40}、
{BQ2518X_TS_CONTROL、0x0}、
{BQ2518X_MASK_ID、0xC0}、
};
谢谢。
您好 Jason、
感谢您共享寄存器。 Reg0x06和 Reg0x08似乎仍被某些内容覆盖。
没有任何内容应该覆盖驱动器中的 Reg0x06和 Reg0x08。 我建议您搜索代码库和脚本、以查找对这些寄存器或充电器的 I2C 地址(0x6A)的任何引用。
如果您找到任何涉及 CHARGERCTRL1 (Reg0x06)或 TMR_ILIM (Reg0x08)的内容、请告诉我。 我怀疑这是导致意外恢复的原因。
此致、
Alec
您好 Alec、
感谢您的支持。
我的脚本已被禁用、没有找到任何 引用 CHARGERCTRL1 (Reg0x06)或 TMR_ILIM (Reg0x08)的内容。 但我发现 Reg0x06和 Reg0x08 显然已复位。 我认为、如果 两个寄存器 在其他位置进行了修改、它们 不会恰好设置为0x56、0x4d。 您能告诉我 什么机制可以重置它们吗? 或任何其他建议?
谢谢。
您好 Alec、
我尝试 在连接适配器时写入 ILIM 和 BATOCP 、然后读回它们、它们保持配置的值而不是复位。
我认为当看门狗计时器 到期时、寄存器会复位为"reg_default"。 但是、"reg_defaults"中 Reg0x06和 Reg0x08的默认值 为0x96和0x4F。 另一方面、Reg0x06 和 Reg0x08的复位值在数据表中定义为0x56和0x4D。 这是否意味着 硬件复位了 Reg0x06和 Reg0x08? 您能考虑什么会触发硬件重置吗?
我 在代码库中找不到任何提及 CHARGERCTRL1 (Reg0x06)或 TMR_ILIM (Reg0x08)的内容、您能给我一些解决此问题的建议吗?
谢谢。
您好 Jason、
感谢您提供的信息。
另一方面、Reg0x06 和 Reg0x08的复位值在数据表中定义为0x56和0x4D。 这是否意味着 硬件复位了 Reg0x06和 Reg0x08? 您能考虑什么会触发硬件重置吗?
是的、假设 Reg0x06和 Reg0x08被重置为硬件默认值(0x56和0x4D)、而不是 reg_defaults (0x96和0x4F)、似乎它们正在由硬件复位。 BQ25180可以通过几种方式将其寄存器复位为默认值:
此致、
Alec
尊敬的 Alec:
我很抱歉 因为 一个紧急项目而延迟更新。 但现在我要重新调试 BQ25180驱动器。
我 在代码库中找不到任何引用 CHARGERCTRL1 (Reg0x06)或 TMR_ILIM (Reg0x08)的内容、也找不到覆盖这些寄存器的任何内容。 我想知道 如果复位 是由看门狗引起的、为什么其他寄存器不复位?
我尝试 配置 Reg0x09[bit0设置 为0, bit7设置为0, bit4-3设置为00, bit6-5设置为00]以避免重置, 但 问题仍然没有解决。
您能给我一些解决这个问题的建议吗?
我尝试了以下测试:
i2cdump -y -f 0 0x6a

CAT /sys/devices/platform soc@0/44000000.bus/44340000.i2c/i2c-0/0-006a/power_Supply/bq2518x-main/uevent

POWER_SUPPLY_INPUT_CURRENT_LIMIT_=1100000、
指令似乎不会动态刷新、因此打印的信息与寄存器值不匹配。
回波1100000 >/sys/devices/platform / soc@0/44000000.bus/44340000.i2c/i2c-0/0-006a/power_supply/bq2518x-mains/input_current_limit
i2cdump -y -f 0 0x6a

回波700000 >/sys/devices/platform / soc@0/44000000.bus/44340000.i2c/i2c-0/0-006a/power_supply/bq2518x-mains/input_current_limit

回波1100000 >/sys/devices/platform / soc@0/44000000.bus/44340000.i2c/i2c-0/0-006a/power_supply/bq2518x-mains/input_current_limit

尊敬的 Jason:
感谢您提供的所有信息。
您是否可以尝试使用以下内容修改 bq2518x_set_ILIM_lvl()? 它对 TMR_ILIM 寄存器执行读取-修改-写入操作、从而确保仅更新 ILIM 位、同时保留其他位。
static int bq2518x_set_ilim_lvl(struct bq2518x_device *bq2518x, int val)
{
int ret, i = 0, tmr_val;
unsigned int array_size = ARRAY_SIZE(bq2518x_ilim_lvl_values);
for (i = array_size - 1; i > 0; i--) {
if (val >= bq2518x_ilim_lvl_values[i])
break;
}
ret = regmap_read(bq2518x->regmap, BQ2518X_TMR_ILIM, &tmr_val);
if (ret)
return ret;
tmr_val = (tmr_val & ~BQ2518X_ILIM_MASK) | (i & BQ2518X_ILIM_MASK);
return regmap_write(bq2518x->regmap, BQ2518X_TMR_ILIM, tmr_val);
}
如果这允许正确设置 ILIM、请告诉我。
此致、
Alec
尊敬的 Jason:
很棒! 我很高兴听到 ILIM 现在被正确设置。
要解决 Reg0x06问题、请尝试修改 bq2518x_set_batocp_1500ma ()、进行以下更改。
static int bq2518x_set_batocp_1500mA(struct bq2518x_device *bq2518x)
{
int ret, reg_val;
ret = regmap_read(bq2518x->regmap, BQ2518X_CHARGERCTRL1, ®_val);
if (ret)
return ret;
reg_val = (reg_val & ~BQ2518X_BATOCP_MASK) | (BQ2518X_BATOCP_1500MA & BQ2518X_BATOCP_MASK);
return regmap_write(bq2518x->regmap, BQ2518X_CHARGERCTRL1, reg_val);
}
与 ILIM 修复类似、此更新执行读取-修改-写入操作、因此仅更新 BATOCP 位、同时保留寄存器中的其他位。
如果这样可以解决问题、请告诉我。
此致、
Alec
尊敬的 Alec:
感谢您的专业支持。 我很高兴告诉您、Reg06问题已在您的上次更改中得到解决。
我还有一些问题需要您的帮助。
1. 我使用 i2cset 命令设置寄存器值、然后执行"cat /sys/devices/platform soc@0/44000000.bus/44340000.i2c/i2c-0/0-006a/power_Supply/bq2518x-main/uevent"。 我发现"cat"结果没有及时更新。
相反、我发现"echo 4200000 >/sys/devices/platform / soc@0/44000000.bus/44340000.i2c/i2c-0/0-006a/power_supply/bq2518x-main/constant_charge_voltage"、则寄存器值已在时间上更新。
我担心"cat"结果没有及时更新、就像现在、 当电池长时间工作且连接了输入源时、我从未看到 POWER_SUPPLY_STATUS 的"充电"状态。 因此、我 无法判断 POWER_SUPPLY_STATUS 现在是否为。
2.正如您上次所说的、我需要从 STAT (Reg0x01、位[4:3])寄存器中读取电池温度。 但我 在移除输入源后发现 Reg01=00。 输入源是否必须连接到 Read Reg01? 您能 帮助解释这些值的含义吗? 如何检查电池是热的、冷的、暖的、凉的还是正常的?
谢谢。
尊敬的 Jason:
我很高兴现在所有寄存器都设置正确! 感谢您的耐心等待。
1.感谢您指出这一点。 CHG_STAT 字段由 STAT0寄存器(Reg0x00)中的位6-5表示。 当前实现会将该值移位4位、从而使这些位不对齐。 为了正确地将两位值提取到最低有效位(位置0和1)、我们需要右移5位。 此变化可确保位6移动到位置1、位5移动到位置0、从而为充电状态生成适当的数值。
请更改驱动程序中的以下行:
#define BQ2518X_CHG_STAT_STEP 4
最终目的
#define BQ2518X_CHG_STAT_STEP 5
此调整应使驱动器能够从 STAT0寄存器正确解释充电状态。
如果这样可以解决问题、请告诉我。
2.这种行为是预期的。 BQ25180可监测受 NTC 和任何外部电阻器补偿网络影响的 TS 引脚电压、以确定电池是冷电池、凉电池、暖电池、热电池还是正常电池。 仅当连接输入源时(即充电期间)才会主动监测电池温度。 要测试固件是否正确识别电池温度状态、您可以将 TS 引脚偏置到高于或低于数据表中指定的电压阈值(有关更多详细信息、请参阅 BQ25180数据表的第8.3.13.1节)。
此致、
Alec