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


static int max17055_get_status(struct max17042_chip *chip, int *status)
{
	int ret, avg_current;
	u32 data, vcell_data, soc_data, curr_data;
	int real_vcell, real_avg_curr, real_curr, real_soc;
	
	/* Значения по умолчанию (fallbacks) на случай, если pdata пуст */
	int dts_ichg_term_ma = 150; 
	int dts_vmax_mv = 4250; 

	/* 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% при отключении кабеля */
		if (chip->scale_synced) {
			regmap_write(chip->regmap, MAX17047_FullSOCThr, 0x5F00);
			chip->scale_synced = false;
		}
		return 0;
	}

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

	/* ДИНАМИЧЕСКИЙ СБОР ПАРАМЕТРОВ ТОКА ИЗ DTS */
	if (chip->pdata && chip->pdata->ichg_term) {
		if (chip->pdata->ichg_term > 5000)
			dts_ichg_term_ma = chip->pdata->ichg_term / 1000; /* Перевод из мкА в мА */
		else
			dts_ichg_term_ma = chip->pdata->ichg_term;
	}
	/* Ток отсечки: значение DTS + 10 мА запаса на пульсации */
	int current_trigger_threshold = dts_ichg_term_ma + 10;

	/* ДИНАМИЧЕСКИЙ СБОР ПАРАМЕТРОВ НАПРЯЖЕНИЯ ИЗ DTS */
	if (chip->pdata && chip->pdata->vmax > 0) {
		/* Если vmax в pdata заполнено из свойства "maxim,over-volt" */
		dts_vmax_mv = chip->pdata->vmax; 
	}
	/* Порог детекции CV-плато: Максимум из DTS минус 40 мВ (например, 4250 - 40 = 4210 мВ) */
	int voltage_cv_threshold = dts_vmax_mv - 40;


	/* 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_Current, &curr_data) < 0 || 
	    regmap_read(chip->regmap, MAX17042_RepSOC, &soc_data) < 0) {
		return -EIO;
	}

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

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

	/* 3. ГАРАНТИРОВАННЫЙ ТРИГГЕР АДАПТАЦИИ ПОД ИЗНОС БАТАРЕИ */
	if (real_vcell >= voltage_cv_threshold && 
	    real_avg_curr > 0 && real_avg_curr < current_trigger_threshold && 
	    real_curr > 0 && real_curr < current_trigger_threshold && 
	    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 (АППАРАТНЫЙ ВАРИАНТ) */
	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 (ПРОГРАММНЫЙ ДУБЛЕР) */
	if (*status == POWER_SUPPLY_STATUS_CHARGING && real_soc >= 100 && 
	    real_vcell >= voltage_cv_threshold && 
	    real_avg_curr > 0 && real_avg_curr < current_trigger_threshold &&
	    real_curr > 0 && real_curr < current_trigger_threshold) {
		printk("%s: !!! SCALE REACHED 100%% AND CV PLATEAU. FORCING FULL STATUS !!!\n", __FUNCTION__);
		*status = POWER_SUPPLY_STATUS_FULL;
		return 0;
	}

	return 0;
}