Загрузка данных
static int max17055_get_status(struct max17042_chip *chip, int *status)
{
int ret, avg_current;
u32 data;
/* Check if the external power source (Type-C / Adapter) is connected */
ret = power_supply_am_i_supplied(chip->battery);
if (ret < 0) {
*status = POWER_SUPPLY_STATUS_UNKNOWN;
return 0;
}
if (ret == 0) {
*status = POWER_SUPPLY_STATUS_DISCHARGING;
return 0;
}
/*
* FOR MAX17055: Read the FStat hardware register (0x3D).
* If the ModelGauge m5 EZ algorithm detects a true end of charge
* based on current drop and voltage stability, it will set the FQ bit (0x0200).
* This allows the battery to be set to FULL even if the battery is worn out and there is current noise.
*/
ret = regmap_read(chip->regmap, MAX17042_ICHGTerm, &data);
printk("%s(%d) MAX17042_ICHGTerm=0x%X\n",__FUNCTION__,__LINE__,data);
ret = regmap_read(chip->regmap, MAX17047_FullSOCThr, &data);
printk("%s(%d) MAX17047_FullSOCThr=0x%X\n",__FUNCTION__,__LINE__,data);
ret = regmap_read(chip->regmap, MAX17042_Current, &data);
printk("%s(%d) MAX17042_Current=0x%X\n",__FUNCTION__,__LINE__,data);
ret = regmap_read(chip->regmap, MAX17042_AvgCurrent, &data);
printk("%s(%d) MAX17042_AvgCurrent=0x%X\n",__FUNCTION__,__LINE__,data);
ret = regmap_read(chip->regmap, MAX17042_VCELL, &data);
printk("%s(%d) MAX17042_VCELL=0x%X\n",__FUNCTION__,__LINE__,data);
ret = regmap_read(chip->regmap, MAX17042_VFSOC, &data);
printk("%s(%d) MAX17042_VFSOC=0x%X\n",__FUNCTION__,__LINE__,data);
ret = regmap_read(chip->regmap, MAX17042_RepSOC, &data);
printk("%s(%d) MAX17042_RepSOC=0x%X\n",__FUNCTION__,__LINE__,data);
ret = regmap_read(chip->regmap, 0x3D, &data); /* 0x3D = MAX17055_FStat */
printk("%s(%d) MAX17055_FStat=0x%X\n",__FUNCTION__,__LINE__,data);
if (ret < 0)
return ret;
if (data & 0x0200) { /* Бит 9 (FQ) — Full Qualified */
u32 soc_data;
int current_soc = 0;
/* Статус FULL гарантирован аппаратно в любом случае */
*status = POWER_SUPPLY_STATUS_FULL;
/* 1. Читаем текущий процент заряда из регистра RepSOC (0x06) */
if (regmap_read(chip->regmap, MAX17042_RepSOC, &soc_data) == 0) {
current_soc = soc_data >> 8; /* MSB содержит целое значение процентов */
}
/* ТРИГГЕР СИНХРОНИЗАЦИИ (Срабатывает СТРОГО ОДИН РАЗ за цикл зарядки):
* Пишем в регистры только если шкала еще отстает (< 100%) И в ОС статус еще НЕ стал FULL.
* Также страхуемся порогом емкости (>= 80%), чтобы исключить ложные шумы на пустом АКБ. */
if (current_soc >= 80 && current_soc < 100 && !chip->scale_synced) {
int real_learned_repcap = 0;
dev_info(&chip->client->dev,
"ModelGauge m5: Absolute EOC Trigger! Syncing scales %d%% -> 100%% \n",
current_soc);
if (regmap_read(chip->regmap, MAX17042_RepCap, &real_learned_repcap) == 0 && real_learned_repcap > 0) {
/* 2. ПРАВИЛЬНЫЙ ПЕРЕСЧЁТ: Принудительно перезаписываем регистры ПОЛНОЙ емкости.
* Объявляем реально набранные кулоны новым 100%-ным объемом FullCAP.
* Это мгновенно скорректирует POWER_SUPPLY_CHARGE_FULL в uevent под ~9200000. */
regmap_write(chip->regmap, MAX17042_FullCAP, real_learned_repcap);
regmap_write(chip->regmap, MAX17042_FullCAPNom, real_learned_repcap);
}
/* Принудительно выставляем 100% в регистр отображаемого заряда RepSOC (0x06) */
regmap_write(chip->regmap, MAX17042_RepSOC, 0x6400);
/* Синхронизируем регистр VFSOC (0xFF) для стабилизации внутренней модели */
regmap_write(chip->regmap, 0xFF, 0x6400);
/* Взводим флаг — синхронизация успешно выполнена! */
chip->scale_synced = true;
}
printk("%s(%d)!!! STATUS FULL from FQ!!!\n",__FUNCTION__,__LINE__);
return 0;
}
/*
* If the hardware full charge flag is not yet set, determine the status
* by the average current (AvgCurrent) direction if current measurement is active.
*/
if (!chip->pdata->enable_current_sense) {
*status = POWER_SUPPLY_STATUS_CHARGING;
return 0;
}
ret = regmap_read(chip->regmap, MAX17042_AvgCurrent, &data);
if (ret < 0)
return ret;
avg_current = sign_extend32(data, 15);
avg_current *= 1562500 / chip->pdata->r_sns;
/* Since the Firefly board has ground noise (around +40..50 mA),
* a pure zero cannot be detected. If the average charging current drops below 60 mA,
* but the FQ flag has not yet been set, we consider charging to be stopped (Not Charging). */
if (avg_current > 0) /* Current greater than +10 mA - active charging is in progress */
*status = POWER_SUPPLY_STATUS_CHARGING;
else
{
*status = POWER_SUPPLY_STATUS_DISCHARGING;
chip->scale_synced = false;
}
return 0;
}