Merge "smb138x-charger: enable the watchdog timer when parallel is enabled"
This commit is contained in:
commit
70a39ffcf9
4 changed files with 104 additions and 22 deletions
|
@ -2949,6 +2949,19 @@ irqreturn_t smblib_handle_switcher_power_ok(int irq, void *data)
|
||||||
return IRQ_HANDLED;
|
return IRQ_HANDLED;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
irqreturn_t smblib_handle_wdog_bark(int irq, void *data)
|
||||||
|
{
|
||||||
|
struct smb_irq_data *irq_data = data;
|
||||||
|
struct smb_charger *chg = irq_data->parent_data;
|
||||||
|
int rc;
|
||||||
|
|
||||||
|
rc = smblib_write(chg, BARK_BITE_WDOG_PET_REG, BARK_BITE_WDOG_PET_BIT);
|
||||||
|
if (rc < 0)
|
||||||
|
smblib_err(chg, "Couldn't pet the dog rc=%d\n", rc);
|
||||||
|
|
||||||
|
return IRQ_HANDLED;
|
||||||
|
}
|
||||||
|
|
||||||
/***************
|
/***************
|
||||||
* Work Queues *
|
* Work Queues *
|
||||||
***************/
|
***************/
|
||||||
|
|
|
@ -262,6 +262,7 @@ irqreturn_t smblib_handle_usb_typec_change(int irq, void *data);
|
||||||
irqreturn_t smblib_handle_dc_plugin(int irq, void *data);
|
irqreturn_t smblib_handle_dc_plugin(int irq, void *data);
|
||||||
irqreturn_t smblib_handle_high_duty_cycle(int irq, void *data);
|
irqreturn_t smblib_handle_high_duty_cycle(int irq, void *data);
|
||||||
irqreturn_t smblib_handle_switcher_power_ok(int irq, void *data);
|
irqreturn_t smblib_handle_switcher_power_ok(int irq, void *data);
|
||||||
|
irqreturn_t smblib_handle_wdog_bark(int irq, void *data);
|
||||||
|
|
||||||
int smblib_get_prop_input_suspend(struct smb_charger *chg,
|
int smblib_get_prop_input_suspend(struct smb_charger *chg,
|
||||||
union power_supply_propval *val);
|
union power_supply_propval *val);
|
||||||
|
|
|
@ -897,7 +897,7 @@ enum {
|
||||||
#define BITE_WDOG_INT_EN_BIT BIT(5)
|
#define BITE_WDOG_INT_EN_BIT BIT(5)
|
||||||
#define SFT_AFTER_WDOG_IRQ_MASK GENMASK(4, 3)
|
#define SFT_AFTER_WDOG_IRQ_MASK GENMASK(4, 3)
|
||||||
#define WDOG_IRQ_SFT_BIT BIT(2)
|
#define WDOG_IRQ_SFT_BIT BIT(2)
|
||||||
#define WDOG_OPTION_BIT BIT(1)
|
#define WDOG_TIMER_EN_ON_PLUGIN_BIT BIT(1)
|
||||||
#define WDOG_TIMER_EN_BIT BIT(0)
|
#define WDOG_TIMER_EN_BIT BIT(0)
|
||||||
|
|
||||||
#define MISC_CFG_REG (MISC_BASE + 0x52)
|
#define MISC_CFG_REG (MISC_BASE + 0x52)
|
||||||
|
|
|
@ -192,11 +192,13 @@ static int smb138x_usb_get_prop(struct power_supply *psy,
|
||||||
pr_err("get prop %d is not supported\n", prop);
|
pr_err("get prop %d is not supported\n", prop);
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (rc < 0) {
|
if (rc < 0) {
|
||||||
pr_debug("Couldn't get prop %d rc = %d\n", prop, rc);
|
pr_debug("Couldn't get prop %d rc = %d\n", prop, rc);
|
||||||
return -ENODATA;
|
return -ENODATA;
|
||||||
}
|
}
|
||||||
return 0;
|
|
||||||
|
return rc;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int smb138x_usb_set_prop(struct power_supply *psy,
|
static int smb138x_usb_set_prop(struct power_supply *psy,
|
||||||
|
@ -319,11 +321,13 @@ static int smb138x_batt_get_prop(struct power_supply *psy,
|
||||||
pr_err("batt power supply get prop %d not supported\n", prop);
|
pr_err("batt power supply get prop %d not supported\n", prop);
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (rc < 0) {
|
if (rc < 0) {
|
||||||
pr_debug("Couldn't get prop %d rc = %d\n", prop, rc);
|
pr_debug("Couldn't get prop %d rc = %d\n", prop, rc);
|
||||||
return -ENODATA;
|
return -ENODATA;
|
||||||
}
|
}
|
||||||
return 0;
|
|
||||||
|
return rc;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int smb138x_batt_set_prop(struct power_supply *psy,
|
static int smb138x_batt_set_prop(struct power_supply *psy,
|
||||||
|
@ -457,11 +461,37 @@ static int smb138x_parallel_get_prop(struct power_supply *psy,
|
||||||
prop);
|
prop);
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (rc < 0) {
|
if (rc < 0) {
|
||||||
pr_debug("Couldn't get prop %d rc = %d\n", prop, rc);
|
pr_debug("Couldn't get prop %d rc = %d\n", prop, rc);
|
||||||
return -ENODATA;
|
return -ENODATA;
|
||||||
}
|
}
|
||||||
return 0;
|
|
||||||
|
return rc;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int smb138x_set_parallel_suspend(struct smb138x *chip, bool suspend)
|
||||||
|
{
|
||||||
|
struct smb_charger *chg = &chip->chg;
|
||||||
|
int rc = 0;
|
||||||
|
|
||||||
|
rc = smblib_masked_write(chg, WD_CFG_REG, WDOG_TIMER_EN_BIT,
|
||||||
|
suspend ? 0 : WDOG_TIMER_EN_BIT);
|
||||||
|
if (rc < 0) {
|
||||||
|
pr_err("Couldn't %s watchdog rc=%d\n",
|
||||||
|
suspend ? "disable" : "enable", rc);
|
||||||
|
suspend = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
rc = smblib_masked_write(chg, USBIN_CMD_IL_REG, USBIN_SUSPEND_BIT,
|
||||||
|
suspend ? USBIN_SUSPEND_BIT : 0);
|
||||||
|
if (rc < 0) {
|
||||||
|
pr_err("Couldn't %s parallel charger rc=%d\n",
|
||||||
|
suspend ? "suspend" : "resume", rc);
|
||||||
|
return rc;
|
||||||
|
}
|
||||||
|
|
||||||
|
return rc;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int smb138x_parallel_set_prop(struct power_supply *psy,
|
static int smb138x_parallel_set_prop(struct power_supply *psy,
|
||||||
|
@ -474,7 +504,7 @@ static int smb138x_parallel_set_prop(struct power_supply *psy,
|
||||||
|
|
||||||
switch (prop) {
|
switch (prop) {
|
||||||
case POWER_SUPPLY_PROP_INPUT_SUSPEND:
|
case POWER_SUPPLY_PROP_INPUT_SUSPEND:
|
||||||
rc = smblib_set_usb_suspend(chg, val->intval);
|
rc = smb138x_set_parallel_suspend(chip, (bool)val->intval);
|
||||||
break;
|
break;
|
||||||
case POWER_SUPPLY_PROP_VOLTAGE_MAX:
|
case POWER_SUPPLY_PROP_VOLTAGE_MAX:
|
||||||
rc = smblib_set_charge_param(chg, &chg->param.fv, val->intval);
|
rc = smblib_set_charge_param(chg, &chg->param.fv, val->intval);
|
||||||
|
@ -620,7 +650,7 @@ static int smb138x_init_vconn_regulator(struct smb138x *chip)
|
||||||
static int smb138x_init_hw(struct smb138x *chip)
|
static int smb138x_init_hw(struct smb138x *chip)
|
||||||
{
|
{
|
||||||
struct smb_charger *chg = &chip->chg;
|
struct smb_charger *chg = &chip->chg;
|
||||||
int rc;
|
int rc = 0;
|
||||||
|
|
||||||
/* votes must be cast before configuring software control */
|
/* votes must be cast before configuring software control */
|
||||||
vote(chg->usb_suspend_votable,
|
vote(chg->usb_suspend_votable,
|
||||||
|
@ -772,6 +802,7 @@ static int smb138x_determine_initial_status(struct smb138x *chip)
|
||||||
struct smb138x_irq_info {
|
struct smb138x_irq_info {
|
||||||
const char *name;
|
const char *name;
|
||||||
const irq_handler_t handler;
|
const irq_handler_t handler;
|
||||||
|
const bool wake;
|
||||||
const struct storm_watch storm_data;
|
const struct storm_watch storm_data;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -908,7 +939,8 @@ static const struct smb138x_irq_info smb138x_irqs[] = {
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
.name = "wdog-bark",
|
.name = "wdog-bark",
|
||||||
.handler = smblib_handle_debug,
|
.handler = smblib_handle_wdog_bark,
|
||||||
|
.wake = true,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
.name = "aicl-fail",
|
.name = "aicl-fail",
|
||||||
|
@ -953,7 +985,7 @@ static int smb138x_request_interrupt(struct smb138x *chip,
|
||||||
const char *irq_name)
|
const char *irq_name)
|
||||||
{
|
{
|
||||||
struct smb_charger *chg = &chip->chg;
|
struct smb_charger *chg = &chip->chg;
|
||||||
int rc, irq, irq_index;
|
int rc = 0, irq, irq_index;
|
||||||
struct smb_irq_data *irq_data;
|
struct smb_irq_data *irq_data;
|
||||||
|
|
||||||
irq = of_irq_get_byname(node, irq_name);
|
irq = of_irq_get_byname(node, irq_name);
|
||||||
|
@ -968,6 +1000,9 @@ static int smb138x_request_interrupt(struct smb138x *chip,
|
||||||
return irq_index;
|
return irq_index;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!smb138x_irqs[irq_index].handler)
|
||||||
|
return 0;
|
||||||
|
|
||||||
irq_data = devm_kzalloc(chg->dev, sizeof(*irq_data), GFP_KERNEL);
|
irq_data = devm_kzalloc(chg->dev, sizeof(*irq_data), GFP_KERNEL);
|
||||||
if (!irq_data)
|
if (!irq_data)
|
||||||
return -ENOMEM;
|
return -ENOMEM;
|
||||||
|
@ -984,6 +1019,9 @@ static int smb138x_request_interrupt(struct smb138x *chip,
|
||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (smb138x_irqs[irq_index].wake)
|
||||||
|
enable_irq_wake(irq);
|
||||||
|
|
||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1001,7 +1039,7 @@ static int smb138x_request_interrupts(struct smb138x *chip)
|
||||||
prop, name) {
|
prop, name) {
|
||||||
rc = smb138x_request_interrupt(chip, child, name);
|
rc = smb138x_request_interrupt(chip, child, name);
|
||||||
if (rc < 0) {
|
if (rc < 0) {
|
||||||
pr_err("Coudn't request interrupt %s rc=%d\n",
|
pr_err("Couldn't request interrupt %s rc=%d\n",
|
||||||
name, rc);
|
name, rc);
|
||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
|
@ -1092,7 +1130,7 @@ static int smb138x_slave_probe(struct smb138x *chip)
|
||||||
rc = smblib_init(chg);
|
rc = smblib_init(chg);
|
||||||
if (rc < 0) {
|
if (rc < 0) {
|
||||||
pr_err("Couldn't initialize smblib rc=%d\n", rc);
|
pr_err("Couldn't initialize smblib rc=%d\n", rc);
|
||||||
return rc;
|
goto cleanup;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (chip->wa_flags & OOB_COMP_WA_BIT) {
|
if (chip->wa_flags & OOB_COMP_WA_BIT) {
|
||||||
|
@ -1102,7 +1140,7 @@ static int smb138x_slave_probe(struct smb138x *chip)
|
||||||
if (rc < 0) {
|
if (rc < 0) {
|
||||||
dev_err(chg->dev,
|
dev_err(chg->dev,
|
||||||
"Couldn't configure the oob comp threh rc = %d\n", rc);
|
"Couldn't configure the oob comp threh rc = %d\n", rc);
|
||||||
return rc;
|
goto cleanup;
|
||||||
}
|
}
|
||||||
|
|
||||||
rc = smblib_masked_write(chg, SMB2CHG_MISC_ENG_SDCDC_CFG6,
|
rc = smblib_masked_write(chg, SMB2CHG_MISC_ENG_SDCDC_CFG6,
|
||||||
|
@ -1110,22 +1148,41 @@ static int smb138x_slave_probe(struct smb138x *chip)
|
||||||
if (rc < 0) {
|
if (rc < 0) {
|
||||||
dev_err(chg->dev,
|
dev_err(chg->dev,
|
||||||
"Couldn't configure the sdcdc cfg 6 reg rc = %d\n", rc);
|
"Couldn't configure the sdcdc cfg 6 reg rc = %d\n", rc);
|
||||||
return rc;
|
goto cleanup;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* suspend usb input */
|
/* enable watchdog bark and bite interrupts, and disable the watchdog */
|
||||||
rc = smblib_set_usb_suspend(chg, true);
|
rc = smblib_masked_write(chg, WD_CFG_REG, WDOG_TIMER_EN_BIT
|
||||||
|
| WDOG_TIMER_EN_ON_PLUGIN_BIT | BITE_WDOG_INT_EN_BIT
|
||||||
|
| BARK_WDOG_INT_EN_BIT,
|
||||||
|
BITE_WDOG_INT_EN_BIT | BARK_WDOG_INT_EN_BIT);
|
||||||
if (rc < 0) {
|
if (rc < 0) {
|
||||||
pr_err("Couldn't suspend USB input rc=%d\n", rc);
|
pr_err("Couldn't configure the watchdog rc=%d\n", rc);
|
||||||
return rc;
|
goto cleanup;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* disable charging when watchdog bites */
|
||||||
|
rc = smblib_masked_write(chg, SNARL_BARK_BITE_WD_CFG_REG,
|
||||||
|
BITE_WDOG_DISABLE_CHARGING_CFG_BIT,
|
||||||
|
BITE_WDOG_DISABLE_CHARGING_CFG_BIT);
|
||||||
|
if (rc < 0) {
|
||||||
|
pr_err("Couldn't configure the watchdog bite rc=%d\n", rc);
|
||||||
|
goto cleanup;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* suspend parallel charging */
|
||||||
|
rc = smb138x_set_parallel_suspend(chip, true);
|
||||||
|
if (rc < 0) {
|
||||||
|
pr_err("Couldn't suspend parallel charging rc=%d\n", rc);
|
||||||
|
goto cleanup;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* initialize FCC to 0 */
|
/* initialize FCC to 0 */
|
||||||
rc = smblib_set_charge_param(chg, &chg->param.fcc, 0);
|
rc = smblib_set_charge_param(chg, &chg->param.fcc, 0);
|
||||||
if (rc < 0) {
|
if (rc < 0) {
|
||||||
pr_err("Couldn't set 0 FCC rc=%d\n", rc);
|
pr_err("Couldn't set 0 FCC rc=%d\n", rc);
|
||||||
return rc;
|
goto cleanup;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* enable the charging path */
|
/* enable the charging path */
|
||||||
|
@ -1134,7 +1191,7 @@ static int smb138x_slave_probe(struct smb138x *chip)
|
||||||
CHARGING_ENABLE_CMD_BIT);
|
CHARGING_ENABLE_CMD_BIT);
|
||||||
if (rc < 0) {
|
if (rc < 0) {
|
||||||
dev_err(chg->dev, "Couldn't enable charging rc=%d\n", rc);
|
dev_err(chg->dev, "Couldn't enable charging rc=%d\n", rc);
|
||||||
return rc;
|
goto cleanup;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* configure charge enable for software control; active high */
|
/* configure charge enable for software control; active high */
|
||||||
|
@ -1143,7 +1200,7 @@ static int smb138x_slave_probe(struct smb138x *chip)
|
||||||
if (rc < 0) {
|
if (rc < 0) {
|
||||||
dev_err(chg->dev, "Couldn't configure charge enable source rc=%d\n",
|
dev_err(chg->dev, "Couldn't configure charge enable source rc=%d\n",
|
||||||
rc);
|
rc);
|
||||||
return rc;
|
goto cleanup;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* enable parallel current sensing */
|
/* enable parallel current sensing */
|
||||||
|
@ -1152,16 +1209,27 @@ static int smb138x_slave_probe(struct smb138x *chip)
|
||||||
if (rc < 0) {
|
if (rc < 0) {
|
||||||
dev_err(chg->dev, "Couldn't enable parallel current sensing rc=%d\n",
|
dev_err(chg->dev, "Couldn't enable parallel current sensing rc=%d\n",
|
||||||
rc);
|
rc);
|
||||||
return rc;
|
goto cleanup;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* keep at the end of probe, ready to serve before notifying others */
|
|
||||||
rc = smb138x_init_parallel_psy(chip);
|
rc = smb138x_init_parallel_psy(chip);
|
||||||
if (rc < 0) {
|
if (rc < 0) {
|
||||||
pr_err("Couldn't initialize parallel psy rc=%d\n", rc);
|
pr_err("Couldn't initialize parallel psy rc=%d\n", rc);
|
||||||
return rc;
|
goto cleanup;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
rc = smb138x_request_interrupts(chip);
|
||||||
|
if (rc < 0) {
|
||||||
|
pr_err("Couldn't request interrupts rc=%d\n", rc);
|
||||||
|
goto cleanup;
|
||||||
|
}
|
||||||
|
|
||||||
|
return rc;
|
||||||
|
|
||||||
|
cleanup:
|
||||||
|
smblib_deinit(chg);
|
||||||
|
if (chip->parallel_psy)
|
||||||
|
power_supply_unregister(chip->parallel_psy);
|
||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Add table
Reference in a new issue