power: qcom: Add hold soc while full feature to QG driver
If hold soc while full feature is defined, hold soc at 100% till
recharge or discharge event is triggered.
Also, fix the return handling from poll-event.
CRs-Fixed: 2190528
Change-Id: I6d602622f4504af44d65bccd54582e33be6169ef
Signed-off-by: Vamshi Krishna B V <vbv@codeaurora.org>
Signed-off-by: Anirudh Ghayal <aghayal@codeaurora.org>
diff --git a/drivers/power/supply/qcom/qpnp-qg.c b/drivers/power/supply/qcom/qpnp-qg.c
index 56233f5..ba733a8 100644
--- a/drivers/power/supply/qcom/qpnp-qg.c
+++ b/drivers/power/supply/qcom/qpnp-qg.c
@@ -531,8 +531,7 @@
qg_scale_soc(chip, false);
/* update parameters to SDAM */
- chip->sdam_data[SDAM_SOC] =
- chip->udata.param[QG_SOC].data;
+ chip->sdam_data[SDAM_SOC] = chip->msoc;
chip->sdam_data[SDAM_OCV_UV] =
chip->udata.param[QG_OCV_UV].data;
chip->sdam_data[SDAM_RBAT_MOHM] =
@@ -891,6 +890,7 @@
#define DEBUG_BATT_SOC 67
#define BATT_MISSING_SOC 50
#define EMPTY_SOC 0
+#define FULL_SOC 100
static int qg_get_battery_capacity(struct qpnp_qg *chip, int *soc)
{
if (is_debug_batt_id(chip)) {
@@ -903,6 +903,11 @@
return 0;
}
+ if (chip->charge_full) {
+ *soc = FULL_SOC;
+ return 0;
+ }
+
*soc = chip->msoc;
return 0;
@@ -1038,13 +1043,58 @@
.property_is_writeable = qg_property_is_writeable,
};
+#define DEFAULT_RECHARGE_SOC 95
static int qg_charge_full_update(struct qpnp_qg *chip)
{
+ union power_supply_propval prop = {0, };
+ int rc, recharge_soc, health;
vote(chip->good_ocv_irq_disable_votable,
QG_INIT_STATE_IRQ_DISABLE, !chip->charge_done, 0);
- /* TODO: add hold-soc-at-full logic */
+ if (!chip->dt.hold_soc_while_full)
+ goto out;
+
+ rc = power_supply_get_property(chip->batt_psy,
+ POWER_SUPPLY_PROP_HEALTH, &prop);
+ if (rc < 0) {
+ pr_err("Failed to get battery health, rc=%d\n", rc);
+ goto out;
+ }
+ health = prop.intval;
+
+ rc = power_supply_get_property(chip->batt_psy,
+ POWER_SUPPLY_PROP_RECHARGE_SOC, &prop);
+ if (rc < 0 || prop.intval < 0) {
+ pr_debug("Failed to get recharge-soc\n");
+ recharge_soc = DEFAULT_RECHARGE_SOC;
+ }
+ recharge_soc = prop.intval;
+
+ qg_dbg(chip, QG_DEBUG_STATUS, "msoc=%d recharge_soc=%d health=%d charge_full=%d\n",
+ chip->msoc, recharge_soc,
+ health, chip->charge_full);
+ if (chip->charge_done && !chip->charge_full) {
+ if (chip->msoc >= 99 && health == POWER_SUPPLY_HEALTH_GOOD) {
+ chip->charge_full = true;
+ qg_dbg(chip, QG_DEBUG_STATUS, "Setting charge_full (0->1) @ msoc=%d\n",
+ chip->msoc);
+ } else {
+ qg_dbg(chip, QG_DEBUG_STATUS, "Terminated charging @ msoc=%d\n",
+ chip->msoc);
+ }
+ } else if ((!chip->charge_done || chip->msoc < recharge_soc)
+ && chip->charge_full) {
+ /*
+ * If recharge has started or discharged below
+ * recharge_soc, set charge_full as false.
+ */
+
+ qg_dbg(chip, QG_DEBUG_STATUS, "msoc=%d recharge_soc=%d charge_full (1->0)\n",
+ chip->msoc, recharge_soc);
+ chip->charge_full = false;
+ }
+out:
return 0;
}
@@ -1113,6 +1163,9 @@
else
chip->charge_done = prop.intval;
+ qg_dbg(chip, QG_DEBUG_STATUS, "charge_status=%d charge_done=%d\n",
+ chip->charge_status, chip->charge_done);
+
rc = qg_parallel_status_update(chip);
if (rc < 0)
pr_err("Failed to update parallel-status, rc=%d\n", rc);
@@ -1188,7 +1241,7 @@
/* non-blocking access, return */
if (!chip->data_ready && (file->f_flags & O_NONBLOCK))
- return -EAGAIN;
+ return 0;
/* blocking access wait on data_ready */
if (!(file->f_flags & O_NONBLOCK)) {
@@ -1274,14 +1327,12 @@
static unsigned int qg_device_poll(struct file *file, poll_table *wait)
{
struct qpnp_qg *chip = file->private_data;
- unsigned int mask;
+ unsigned int mask = 0;
poll_wait(file, &chip->qg_wait_q, wait);
if (chip->data_ready)
mask = POLLIN | POLLRDNORM;
- else
- mask = POLLERR;
return mask;
}
@@ -2069,6 +2120,9 @@
else
chip->dt.ignore_shutdown_soc_secs = temp;
+ chip->dt.hold_soc_while_full = of_property_read_bool(node,
+ "qcom,hold-soc-while-full");
+
rc = of_property_read_u32(node, "qcom,rbat-conn-mohm", &temp);
if (rc < 0)
chip->dt.rbat_conn_mohm = 0;