Merge "qpnp-fg-gen3: add support to configure ki coefficients during discharge"
This commit is contained in:
commit
580442d0a6
3 changed files with 200 additions and 0 deletions
|
@ -222,6 +222,36 @@ First Level Node - FG Gen3 device
|
|||
Definition: A boolean property that when defined holds SOC at 100% when
|
||||
the battery is full.
|
||||
|
||||
- qcom,ki-coeff-soc-dischg:
|
||||
Usage: optional
|
||||
Value type: <prop-encoded-array>
|
||||
Definition: Array of monotonic SOC threshold values to change the ki
|
||||
coefficient for medium discharge current during discharge.
|
||||
This should be defined in the ascending order and in the
|
||||
range of 0-100. Array limit is set to 3.
|
||||
|
||||
- qcom,ki-coeff-med-dischg:
|
||||
Usage: optional
|
||||
Value type: <prop-encoded-array>
|
||||
Definition: Array of ki coefficient values for medium discharge current
|
||||
during discharge. These values will be applied when the
|
||||
monotonic SOC goes below the SOC threshold specified under
|
||||
qcom,ki-coeff-soc-dischg. Array limit is set to 3. This
|
||||
property should be specified if qcom,ki-coeff-soc-dischg
|
||||
is specified to make it fully functional. Value has no
|
||||
unit. Allowed range is 0 to 62200 in micro units.
|
||||
|
||||
- qcom,ki-coeff-hi-dischg:
|
||||
Usage: optional
|
||||
Value type: <prop-encoded-array>
|
||||
Definition: Array of ki coefficient values for high discharge current
|
||||
during discharge. These values will be applied when the
|
||||
monotonic SOC goes below the SOC threshold specified under
|
||||
qcom,ki-coeff-soc-dischg. Array limit is set to 3. This
|
||||
property should be specified if qcom,ki-coeff-soc-dischg
|
||||
is specified to make it fully functional. Value has no
|
||||
unit. Allowed range is 0 to 62200 in micro units.
|
||||
|
||||
==========================================================
|
||||
Second Level Nodes - Peripherals managed by FG Gen3 driver
|
||||
==========================================================
|
||||
|
@ -252,6 +282,9 @@ pmicobalt_fg: qpnp,fg {
|
|||
qcom,pmic-revid = <&pmicobalt_revid>;
|
||||
io-channels = <&pmicobalt_rradc 3>;
|
||||
io-channel-names = "rradc_batt_id";
|
||||
qcom,ki-coeff-soc-dischg = <30 60 90>;
|
||||
qcom,ki-coeff-med-dischg = <800 1000 1400>;
|
||||
qcom,ki-coeff-hi-dischg = <1200 1500 2100>;
|
||||
status = "okay";
|
||||
|
||||
qcom,fg-batt-soc@4000 {
|
||||
|
|
|
@ -61,6 +61,9 @@
|
|||
#define BUCKET_COUNT 8
|
||||
#define BUCKET_SOC_PCT (256 / BUCKET_COUNT)
|
||||
|
||||
#define KI_COEFF_MAX 62200
|
||||
#define KI_COEFF_SOC_LEVELS 3
|
||||
|
||||
/* Debug flag definitions */
|
||||
enum fg_debug_flag {
|
||||
FG_IRQ = BIT(0), /* Show interrupts */
|
||||
|
@ -139,6 +142,8 @@ enum fg_sram_param_id {
|
|||
FG_SRAM_CHG_TERM_CURR,
|
||||
FG_SRAM_DELTA_SOC_THR,
|
||||
FG_SRAM_RECHARGE_SOC_THR,
|
||||
FG_SRAM_KI_COEFF_MED_DISCHG,
|
||||
FG_SRAM_KI_COEFF_HI_DISCHG,
|
||||
FG_SRAM_MAX,
|
||||
};
|
||||
|
||||
|
@ -198,6 +203,9 @@ struct fg_dt_props {
|
|||
int cl_min_cap_limit;
|
||||
int jeita_hyst_temp;
|
||||
int batt_temp_delta;
|
||||
int ki_coeff_soc[KI_COEFF_SOC_LEVELS];
|
||||
int ki_coeff_med_dischg[KI_COEFF_SOC_LEVELS];
|
||||
int ki_coeff_hi_dischg[KI_COEFF_SOC_LEVELS];
|
||||
};
|
||||
|
||||
/* parameters from battery profile */
|
||||
|
@ -275,6 +283,7 @@ struct fg_chip {
|
|||
bool fg_restarting;
|
||||
bool charge_full;
|
||||
bool recharge_soc_adjusted;
|
||||
bool ki_coeff_dischg_en;
|
||||
struct completion soc_update;
|
||||
struct completion soc_ready;
|
||||
struct delayed_work profile_load_work;
|
||||
|
|
|
@ -36,6 +36,12 @@
|
|||
#define SYS_TERM_CURR_OFFSET 0
|
||||
#define VBATT_FULL_WORD 7
|
||||
#define VBATT_FULL_OFFSET 0
|
||||
#define KI_COEFF_MED_DISCHG_WORD 9
|
||||
#define KI_COEFF_MED_DISCHG_OFFSET 3
|
||||
#define KI_COEFF_HI_DISCHG_WORD 10
|
||||
#define KI_COEFF_HI_DISCHG_OFFSET 0
|
||||
#define KI_COEFF_LOW_DISCHG_WORD 10
|
||||
#define KI_COEFF_LOW_DISCHG_OFFSET 2
|
||||
#define DELTA_SOC_THR_WORD 12
|
||||
#define DELTA_SOC_THR_OFFSET 3
|
||||
#define RECHARGE_SOC_THR_WORD 14
|
||||
|
@ -88,6 +94,12 @@
|
|||
#define ALG_FLAGS_OFFSET 1
|
||||
|
||||
/* v2 SRAM address and offset in ascending order */
|
||||
#define KI_COEFF_LOW_DISCHG_v2_WORD 9
|
||||
#define KI_COEFF_LOW_DISCHG_v2_OFFSET 3
|
||||
#define KI_COEFF_MED_DISCHG_v2_WORD 10
|
||||
#define KI_COEFF_MED_DISCHG_v2_OFFSET 0
|
||||
#define KI_COEFF_HI_DISCHG_v2_WORD 10
|
||||
#define KI_COEFF_HI_DISCHG_v2_OFFSET 1
|
||||
#define DELTA_SOC_THR_v2_WORD 13
|
||||
#define DELTA_SOC_THR_v2_OFFSET 0
|
||||
#define RECHARGE_SOC_THR_v2_WORD 14
|
||||
|
@ -173,6 +185,12 @@ static struct fg_sram_param pmicobalt_v1_sram_params[] = {
|
|||
ESR_TIMER_CHG_MAX_OFFSET, 2, 1, 1, 0, fg_encode_default, NULL),
|
||||
PARAM(ESR_TIMER_CHG_INIT, ESR_TIMER_CHG_INIT_WORD,
|
||||
ESR_TIMER_CHG_INIT_OFFSET, 2, 1, 1, 0, fg_encode_default, NULL),
|
||||
PARAM(KI_COEFF_MED_DISCHG, KI_COEFF_MED_DISCHG_WORD,
|
||||
KI_COEFF_MED_DISCHG_OFFSET, 1, 1000, 244141, 0,
|
||||
fg_encode_default, NULL),
|
||||
PARAM(KI_COEFF_HI_DISCHG, KI_COEFF_HI_DISCHG_WORD,
|
||||
KI_COEFF_HI_DISCHG_OFFSET, 1, 1000, 244141, 0,
|
||||
fg_encode_default, NULL),
|
||||
};
|
||||
|
||||
static struct fg_sram_param pmicobalt_v2_sram_params[] = {
|
||||
|
@ -222,6 +240,12 @@ static struct fg_sram_param pmicobalt_v2_sram_params[] = {
|
|||
ESR_TIMER_CHG_MAX_OFFSET, 2, 1, 1, 0, fg_encode_default, NULL),
|
||||
PARAM(ESR_TIMER_CHG_INIT, ESR_TIMER_CHG_INIT_WORD,
|
||||
ESR_TIMER_CHG_INIT_OFFSET, 2, 1, 1, 0, fg_encode_default, NULL),
|
||||
PARAM(KI_COEFF_MED_DISCHG, KI_COEFF_MED_DISCHG_v2_WORD,
|
||||
KI_COEFF_MED_DISCHG_v2_OFFSET, 1, 1000, 244141, 0,
|
||||
fg_encode_default, NULL),
|
||||
PARAM(KI_COEFF_HI_DISCHG, KI_COEFF_HI_DISCHG_v2_WORD,
|
||||
KI_COEFF_HI_DISCHG_v2_OFFSET, 1, 1000, 244141, 0,
|
||||
fg_encode_default, NULL),
|
||||
};
|
||||
|
||||
static struct fg_alg_flag pmicobalt_v1_alg_flags[] = {
|
||||
|
@ -1124,6 +1148,60 @@ out:
|
|||
mutex_unlock(&chip->cl.lock);
|
||||
}
|
||||
|
||||
#define KI_COEFF_MED_DISCHG_DEFAULT 1500
|
||||
#define KI_COEFF_HI_DISCHG_DEFAULT 2200
|
||||
static int fg_adjust_ki_coeff_dischg(struct fg_chip *chip)
|
||||
{
|
||||
int rc, i, msoc;
|
||||
int ki_coeff_med = KI_COEFF_MED_DISCHG_DEFAULT;
|
||||
int ki_coeff_hi = KI_COEFF_HI_DISCHG_DEFAULT;
|
||||
u8 val;
|
||||
|
||||
if (!chip->ki_coeff_dischg_en)
|
||||
return 0;
|
||||
|
||||
rc = fg_get_prop_capacity(chip, &msoc);
|
||||
if (rc < 0) {
|
||||
pr_err("Error in getting capacity, rc=%d\n", rc);
|
||||
return rc;
|
||||
}
|
||||
|
||||
if (chip->status == POWER_SUPPLY_STATUS_DISCHARGING) {
|
||||
for (i = KI_COEFF_SOC_LEVELS - 1; i >= 0; i--) {
|
||||
if (msoc < chip->dt.ki_coeff_soc[i]) {
|
||||
ki_coeff_med = chip->dt.ki_coeff_med_dischg[i];
|
||||
ki_coeff_hi = chip->dt.ki_coeff_hi_dischg[i];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fg_encode(chip->sp, FG_SRAM_KI_COEFF_MED_DISCHG, ki_coeff_med, &val);
|
||||
rc = fg_sram_write(chip,
|
||||
chip->sp[FG_SRAM_KI_COEFF_MED_DISCHG].addr_word,
|
||||
chip->sp[FG_SRAM_KI_COEFF_MED_DISCHG].addr_byte, &val,
|
||||
chip->sp[FG_SRAM_KI_COEFF_MED_DISCHG].len,
|
||||
FG_IMA_DEFAULT);
|
||||
if (rc < 0) {
|
||||
pr_err("Error in writing ki_coeff_med, rc=%d\n", rc);
|
||||
return rc;
|
||||
}
|
||||
|
||||
fg_encode(chip->sp, FG_SRAM_KI_COEFF_HI_DISCHG, ki_coeff_hi, &val);
|
||||
rc = fg_sram_write(chip,
|
||||
chip->sp[FG_SRAM_KI_COEFF_HI_DISCHG].addr_word,
|
||||
chip->sp[FG_SRAM_KI_COEFF_HI_DISCHG].addr_byte, &val,
|
||||
chip->sp[FG_SRAM_KI_COEFF_HI_DISCHG].len,
|
||||
FG_IMA_DEFAULT);
|
||||
if (rc < 0) {
|
||||
pr_err("Error in writing ki_coeff_hi, rc=%d\n", rc);
|
||||
return rc;
|
||||
}
|
||||
|
||||
fg_dbg(chip, FG_STATUS, "Wrote ki_coeff_med %d ki_coeff_hi %d\n",
|
||||
ki_coeff_med, ki_coeff_hi);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int fg_charge_full_update(struct fg_chip *chip)
|
||||
{
|
||||
union power_supply_propval prop = {0, };
|
||||
|
@ -1298,6 +1376,7 @@ static void status_change_work(struct work_struct *work)
|
|||
schedule_work(&chip->cycle_count_work);
|
||||
|
||||
fg_cap_learning_update(chip);
|
||||
|
||||
rc = fg_charge_full_update(chip);
|
||||
if (rc < 0)
|
||||
pr_err("Error in charge_full_update, rc=%d\n", rc);
|
||||
|
@ -1306,6 +1385,9 @@ static void status_change_work(struct work_struct *work)
|
|||
if (rc < 0)
|
||||
pr_err("Error in adjusting recharge_soc, rc=%d\n", rc);
|
||||
|
||||
rc = fg_adjust_ki_coeff_dischg(chip);
|
||||
if (rc < 0)
|
||||
pr_err("Error in adjusting ki_coeff_dischg, rc=%d\n", rc);
|
||||
out:
|
||||
pm_relax(chip->dev);
|
||||
}
|
||||
|
@ -2138,6 +2220,10 @@ static irqreturn_t fg_delta_soc_irq_handler(int irq, void *data)
|
|||
if (rc < 0)
|
||||
pr_err("Error in charge_full_update, rc=%d\n", rc);
|
||||
|
||||
rc = fg_adjust_ki_coeff_dischg(chip);
|
||||
if (rc < 0)
|
||||
pr_err("Error in adjusting ki_coeff_dischg, rc=%d\n", rc);
|
||||
|
||||
return IRQ_HANDLED;
|
||||
}
|
||||
|
||||
|
@ -2298,6 +2384,73 @@ static int fg_register_interrupts(struct fg_chip *chip)
|
|||
return 0;
|
||||
}
|
||||
|
||||
static int fg_parse_ki_coefficients(struct fg_chip *chip)
|
||||
{
|
||||
struct device_node *node = chip->dev->of_node;
|
||||
int rc, i;
|
||||
|
||||
rc = of_property_count_elems_of_size(node, "qcom,ki-coeff-soc-dischg",
|
||||
sizeof(u32));
|
||||
if (rc != KI_COEFF_SOC_LEVELS)
|
||||
return 0;
|
||||
|
||||
rc = of_property_read_u32_array(node, "qcom,ki-coeff-soc-dischg",
|
||||
chip->dt.ki_coeff_soc, KI_COEFF_SOC_LEVELS);
|
||||
if (rc < 0) {
|
||||
pr_err("Error in reading ki-coeff-soc-dischg, rc=%d\n",
|
||||
rc);
|
||||
return rc;
|
||||
}
|
||||
|
||||
rc = of_property_count_elems_of_size(node, "qcom,ki-coeff-med-dischg",
|
||||
sizeof(u32));
|
||||
if (rc != KI_COEFF_SOC_LEVELS)
|
||||
return 0;
|
||||
|
||||
rc = of_property_read_u32_array(node, "qcom,ki-coeff-med-dischg",
|
||||
chip->dt.ki_coeff_med_dischg, KI_COEFF_SOC_LEVELS);
|
||||
if (rc < 0) {
|
||||
pr_err("Error in reading ki-coeff-med-dischg, rc=%d\n",
|
||||
rc);
|
||||
return rc;
|
||||
}
|
||||
|
||||
rc = of_property_count_elems_of_size(node, "qcom,ki-coeff-hi-dischg",
|
||||
sizeof(u32));
|
||||
if (rc != KI_COEFF_SOC_LEVELS)
|
||||
return 0;
|
||||
|
||||
rc = of_property_read_u32_array(node, "qcom,ki-coeff-hi-dischg",
|
||||
chip->dt.ki_coeff_hi_dischg, KI_COEFF_SOC_LEVELS);
|
||||
if (rc < 0) {
|
||||
pr_err("Error in reading ki-coeff-hi-dischg, rc=%d\n",
|
||||
rc);
|
||||
return rc;
|
||||
}
|
||||
|
||||
for (i = 0; i < KI_COEFF_SOC_LEVELS; i++) {
|
||||
if (chip->dt.ki_coeff_soc[i] < 0 ||
|
||||
chip->dt.ki_coeff_soc[i] > FULL_CAPACITY) {
|
||||
pr_err("Error in ki_coeff_soc_dischg values\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (chip->dt.ki_coeff_med_dischg[i] < 0 ||
|
||||
chip->dt.ki_coeff_med_dischg[i] > KI_COEFF_MAX) {
|
||||
pr_err("Error in ki_coeff_med_dischg values\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (chip->dt.ki_coeff_med_dischg[i] < 0 ||
|
||||
chip->dt.ki_coeff_med_dischg[i] > KI_COEFF_MAX) {
|
||||
pr_err("Error in ki_coeff_med_dischg values\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
}
|
||||
chip->ki_coeff_dischg_en = true;
|
||||
return 0;
|
||||
}
|
||||
|
||||
#define DEFAULT_CUTOFF_VOLT_MV 3200
|
||||
#define DEFAULT_EMPTY_VOLT_MV 3100
|
||||
#define DEFAULT_CHG_TERM_CURR_MA 100
|
||||
|
@ -2562,6 +2715,11 @@ static int fg_parse_dt(struct fg_chip *chip)
|
|||
|
||||
chip->dt.hold_soc_while_full = of_property_read_bool(node,
|
||||
"qcom,hold-soc-while-full");
|
||||
|
||||
rc = fg_parse_ki_coefficients(chip);
|
||||
if (rc < 0)
|
||||
pr_err("Error in parsing Ki coefficients, rc=%d\n", rc);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
Loading…
Add table
Reference in a new issue