Загрузка данных


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;
}