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


static int max17055_get_status(struct max17042_chip *chip, int *status)
{
	int ret, avg_current;
	u32 data, vcell_data, soc_data;
	int real_vcell, real_avg_curr, real_soc;

	/* 1. Проверяем физическое подключение внешнего источника питания */
	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;
		
		/* ГАРАНТИРОВАННЫЙ ВОЗВРАТ ПОРОГОВ ПРИ ОТКЛЮЧЕНИИ КАБЕЛЯ:
		 * Возвращаем заводской порог 95% для следующего цикла нормальной зарядки
		 * и сбрасываем защелку конечного автомата. До этого момента (пока статус FULL
		 * и кабель подключен) порог удерживается заниженным, сохраняя стабильные 100%. */
		if (chip->scale_synced) {
			regmap_write(chip->regmap, MAX17047_FullSOCThr, 0x5F00); /* Возврат на 95% */
			chip->scale_synced = false;
		}
		return 0;
	}

	/* По умолчанию выставляем статус активной зарядки */
	*status = POWER_SUPPLY_STATUS_CHARGING;

	/* 2. Считываем и переводим физические параметры из регистров MAX17055 */
	if (regmap_read(chip->regmap, MAX17042_VCELL, &vcell_data) < 0 ||
	    regmap_read(chip->regmap, MAX17042_AvgCurrent, &data) < 0 ||
	    regmap_read(chip->regmap, MAX17042_RepSOC, &soc_data) < 0) {
		return -EIO;
	}

	real_vcell = vcell_data * 78125 / 1000000; /* Напряжение в мВ (примерно 4225 мВ) */
	real_avg_curr = sign_extend32(data, 15) * 1562500 / chip->pdata->r_sns; /* Ток в мА */
	real_soc = soc_data >> 8; /* Текущее целое значение отображаемых процентов */

	/* Вывод лога для контроля параметров в dmesg */
	printk("%s: VCELL=%d mV, AvgCurrent=%d mA, RepSOC=%d%%\n", 
		__FUNCTION__, real_vcell, real_avg_curr, real_soc);

	/* 3. ГАРАНТИРОВАННЫЙ ТРИГГЕР АДАПТАЦИИ ПОД ИЗНОС БАТАРЕИ
	 * Срабатывает СТРОГО 1 РАЗ за сессию зарядки при выполнении 4-х условий:
	 *   - Напряжение на банке вышло на стадию CV (>= 4.21В)
	 *   - Средний ток честно упал ниже 195 мА (основной заряд завершен)
	 *   - Батарея успела набрать хотя бы 85% емкости (защита от ложного срабатывания на пустом АКБ)
	 *   - Коррекция в этом цикле еще не выполнялась (!chip->scale_synced)
	 */
	if (real_vcell >= 4210 && real_avg_curr > 0 && real_avg_curr < 195 && real_soc >= 85 && !chip->scale_synced) {
		
		/* Вычисляем индивидуальный адаптивный порог: текущий застрявший SOC минус 2% безопасности */
		int target_soc_threshold = real_soc - 2;
		if (target_soc_threshold > 95) target_soc_threshold = 95;
		if (target_soc_threshold < 80) target_soc_threshold = 80; /* Ограничение снизу */

		u16 raw_thr_value = (target_soc_threshold << 8) & 0xFF00;

		dev_info(&chip->client->dev, 
			 "ModelGauge m5: Battery aging detected. Shifting FullSOCThr to %d%%\n", 
			 target_soc_threshold);

		/* Фиксируем скорректированный порог и взводим защелку */
		regmap_write(chip->regmap, MAX17047_FullSOCThr, raw_thr_value);
		chip->scale_synced = true; 
	}

	/* 4. ПРОВЕРКА СТАТУСА FULL (АППАРАТНЫЙ ВАРИАНТ)
	 * Читаем регистр STATUS (0x00) и проверяем 10-й бит FQ (маска 0x0400) */
	ret = regmap_read(chip->regmap, MAX17042_STATUS, &data);
	if (ret == 0 && (data & 0x0400)) {
		printk("%s: !!! STATUS FULL FROM HARDWARE FQ BIT !!!\n", __FUNCTION__);
		*status = POWER_SUPPLY_STATUS_FULL;
		return 0;
	}

	/* 5. ПРОВЕРКА СТАТУСА FULL (ПРОГРАММНЫЙ ДУБЛЕР)
	 * Защита от наводок чарджера и шумов земли. Если шкала благодаря нашей адаптации 
	 * успешно дошла до 100%, напряжение стабильно на плато, а средний ток заряда 
	 * находится в минимальных пределах, принудительно отдаем операционной системе статус FULL.
	 */
	if (*status == POWER_SUPPLY_STATUS_CHARGING && real_soc >= 100 && real_vcell >= 4210 && real_avg_curr > 0 && real_avg_curr < 195) {
		printk("%s: !!! SCALE REACHED 100%% AND CV PLATEAU. FORCING FULL STATUS !!!\n", __FUNCTION__);
		*status = POWER_SUPPLY_STATUS_FULL;
		return 0;
	}

	return 0;
}