qcom: qnovo: restart pulse train in stall state
There are a couple of cases where qnovo charging fails, 1. pulse train enable command register fails to write through, or 2. pulse engine fails to start and pulse train timer PTTIME does not start counting. In either case, qnovo charging will stop. Here is the fix, Write register twice when enabling pulse train, and restart pulse train if PTTIME does not increase. Change-Id: Ic235f8f2bc67fe577e42848ef623870c25b68256 Signed-off-by: Harry Yang <harryy@codeaurora.org> Signed-off-by: Abhijeet Dharmapurikar <adharmap@codeaurora.org>
This commit is contained in:
parent
cbff20cc9a
commit
2aced65bf8
1 changed files with 62 additions and 0 deletions
|
@ -20,6 +20,7 @@
|
|||
#include <linux/of_irq.h>
|
||||
#include <linux/qpnp/qpnp-revid.h>
|
||||
#include <linux/pmic-voter.h>
|
||||
#include <linux/delay.h>
|
||||
|
||||
#define QNOVO_REVISION1 0x00
|
||||
#define QNOVO_REVISION2 0x01
|
||||
|
@ -124,6 +125,8 @@
|
|||
#define USB_READY_VOTER "USB_READY_VOTER"
|
||||
#define DC_READY_VOTER "DC_READY_VOTER"
|
||||
|
||||
#define PT_RESTART_VOTER "PT_RESTART_VOTER"
|
||||
|
||||
struct qnovo_dt_props {
|
||||
bool external_rsense;
|
||||
struct device_node *revid_dev_node;
|
||||
|
@ -161,6 +164,8 @@ struct qnovo {
|
|||
int dc_present;
|
||||
struct delayed_work usb_debounce_work;
|
||||
struct delayed_work dc_debounce_work;
|
||||
|
||||
struct delayed_work ptrain_restart_work;
|
||||
};
|
||||
|
||||
static int debug_mask;
|
||||
|
@ -354,6 +359,11 @@ static int pt_dis_votable_cb(struct votable *votable, void *data, int disable,
|
|||
struct qnovo *chip = data;
|
||||
int rc;
|
||||
|
||||
if (disable) {
|
||||
cancel_delayed_work_sync(&chip->ptrain_restart_work);
|
||||
vote(chip->awake_votable, PT_RESTART_VOTER, false, 0);
|
||||
}
|
||||
|
||||
rc = qnovo_masked_write(chip, QNOVO_PTRAIN_EN, QNOVO_PTRAIN_EN_BIT,
|
||||
(bool)disable ? 0 : QNOVO_PTRAIN_EN_BIT);
|
||||
if (rc < 0) {
|
||||
|
@ -362,6 +372,12 @@ static int pt_dis_votable_cb(struct votable *votable, void *data, int disable,
|
|||
return rc;
|
||||
}
|
||||
|
||||
if (!disable) {
|
||||
vote(chip->awake_votable, PT_RESTART_VOTER, true, 0);
|
||||
schedule_delayed_work(&chip->ptrain_restart_work,
|
||||
msecs_to_jiffies(20));
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -1311,6 +1327,51 @@ static void status_change_work(struct work_struct *work)
|
|||
qnovo_update_status(chip);
|
||||
}
|
||||
|
||||
static void ptrain_restart_work(struct work_struct *work)
|
||||
{
|
||||
struct qnovo *chip = container_of(work,
|
||||
struct qnovo, ptrain_restart_work.work);
|
||||
u8 pt_t1, pt_t2;
|
||||
int rc;
|
||||
|
||||
rc = qnovo_read(chip, QNOVO_PTTIME_STS, &pt_t1, 1);
|
||||
if (rc < 0) {
|
||||
dev_err(chip->dev, "Couldn't read QNOVO_PTTIME_STS rc = %d\n",
|
||||
rc);
|
||||
goto clean_up;
|
||||
}
|
||||
|
||||
/* pttime increments every 2 seconds */
|
||||
msleep(2100);
|
||||
|
||||
rc = qnovo_read(chip, QNOVO_PTTIME_STS, &pt_t2, 1);
|
||||
if (rc < 0) {
|
||||
dev_err(chip->dev, "Couldn't read QNOVO_PTTIME_STS rc = %d\n",
|
||||
rc);
|
||||
goto clean_up;
|
||||
}
|
||||
|
||||
if (pt_t1 != pt_t2)
|
||||
goto clean_up;
|
||||
|
||||
/* Toggle pt enable to restart pulse train */
|
||||
rc = qnovo_masked_write(chip, QNOVO_PTRAIN_EN, QNOVO_PTRAIN_EN_BIT, 0);
|
||||
if (rc < 0) {
|
||||
dev_err(chip->dev, "Couldn't disable pulse train rc=%d\n", rc);
|
||||
goto clean_up;
|
||||
}
|
||||
msleep(1000);
|
||||
rc = qnovo_masked_write(chip, QNOVO_PTRAIN_EN, QNOVO_PTRAIN_EN_BIT,
|
||||
QNOVO_PTRAIN_EN_BIT);
|
||||
if (rc < 0) {
|
||||
dev_err(chip->dev, "Couldn't enable pulse train rc=%d\n", rc);
|
||||
goto clean_up;
|
||||
}
|
||||
|
||||
clean_up:
|
||||
vote(chip->awake_votable, PT_RESTART_VOTER, false, 0);
|
||||
}
|
||||
|
||||
static int qnovo_notifier_call(struct notifier_block *nb,
|
||||
unsigned long ev, void *v)
|
||||
{
|
||||
|
@ -1564,6 +1625,7 @@ static int qnovo_probe(struct platform_device *pdev)
|
|||
INIT_WORK(&chip->status_change_work, status_change_work);
|
||||
INIT_DELAYED_WORK(&chip->dc_debounce_work, dc_debounce_work);
|
||||
INIT_DELAYED_WORK(&chip->usb_debounce_work, usb_debounce_work);
|
||||
INIT_DELAYED_WORK(&chip->ptrain_restart_work, ptrain_restart_work);
|
||||
|
||||
rc = qnovo_hw_init(chip);
|
||||
if (rc < 0) {
|
||||
|
|
Loading…
Add table
Reference in a new issue