static irqreturn_t smb347_interrupt(int irq, void *data) { struct smb347_charger *smb = data; int stat_c, irqstat_e, irqstat_c; irqreturn_t ret = IRQ_NONE; stat_c = smb347_read(smb, STAT_C); if (stat_c < 0) { dev_warn(&smb->client->dev, "reading STAT_C failed\n"); return IRQ_NONE; } irqstat_c = smb347_read(smb, IRQSTAT_C); if (irqstat_c < 0) { dev_warn(&smb->client->dev, "reading IRQSTAT_C failed\n"); return IRQ_NONE; } irqstat_e = smb347_read(smb, IRQSTAT_E); if (irqstat_e < 0) { dev_warn(&smb->client->dev, "reading IRQSTAT_E failed\n"); return IRQ_NONE; } if (stat_c & STAT_C_CHARGER_ERROR) { dev_err(&smb->client->dev, "error in charger, disabling charging\n"); smb347_charging_disable(smb); power_supply_changed(&smb->battery); ret = IRQ_HANDLED; } if (irqstat_c & (IRQSTAT_C_TERMINATION_IRQ | IRQSTAT_C_TAPER_IRQ)) { if (irqstat_c & IRQSTAT_C_TERMINATION_STAT) power_supply_changed(&smb->battery); ret = IRQ_HANDLED; } if (irqstat_e & (IRQSTAT_E_USBIN_UV_IRQ | IRQSTAT_E_DCIN_UV_IRQ)) { if (smb347_update_status(smb) > 0) { smb347_update_online(smb); power_supply_changed(&smb->mains); power_supply_changed(&smb->usb); } ret = IRQ_HANDLED; } return ret; }
static int smb347_update_online(struct smb347_charger *smb) { int ret; if (smb347_is_online(smb)) { ret = smb347_charging_enable(smb); if (ret < 0) dev_err(&smb->client->dev, "failed to enable charging\n"); } else { ret = smb347_charging_disable(smb); if (ret < 0) dev_err(&smb->client->dev, "failed to disable charging\n"); } return ret; }
static int smb347_update_online(struct smb347_charger *smb) { int ret; /* * Depending on whether valid power source is connected or not, we * disable or enable the charging. We do it manually because it * depends on how the platform has configured the valid inputs. */ if (smb347_is_online(smb)) { ret = smb347_charging_enable(smb); if (ret < 0) dev_err(&smb->client->dev, "failed to enable charging\n"); } else { ret = smb347_charging_disable(smb); if (ret < 0) dev_err(&smb->client->dev, "failed to disable charging\n"); } return ret; }
static irqreturn_t smb347_interrupt(int irq, void *data) { struct smb347_charger *smb = data; int stat_c, irqstat_e, irqstat_c; irqreturn_t ret = IRQ_NONE; stat_c = smb347_read(smb, STAT_C); if (stat_c < 0) { dev_warn(&smb->client->dev, "reading STAT_C failed\n"); return IRQ_NONE; } irqstat_c = smb347_read(smb, IRQSTAT_C); if (irqstat_c < 0) { dev_warn(&smb->client->dev, "reading IRQSTAT_C failed\n"); return IRQ_NONE; } irqstat_e = smb347_read(smb, IRQSTAT_E); if (irqstat_e < 0) { dev_warn(&smb->client->dev, "reading IRQSTAT_E failed\n"); return IRQ_NONE; } /* * If we get charger error we report the error back to user and * disable charging. */ if (stat_c & STAT_C_CHARGER_ERROR) { dev_err(&smb->client->dev, "error in charger, disabling charging\n"); smb347_charging_disable(smb); power_supply_changed(&smb->battery); ret = IRQ_HANDLED; } /* * If we reached the termination current the battery is charged and * we can update the status now. Charging is automatically * disabled by the hardware. */ if (irqstat_c & (IRQSTAT_C_TERMINATION_IRQ | IRQSTAT_C_TAPER_IRQ)) { if (irqstat_c & IRQSTAT_C_TERMINATION_STAT) power_supply_changed(&smb->battery); ret = IRQ_HANDLED; } /* * If we got an under voltage interrupt it means that AC/USB input * was disconnected. */ if (irqstat_e & (IRQSTAT_E_USBIN_UV_IRQ | IRQSTAT_E_DCIN_UV_IRQ)) ret = IRQ_HANDLED; if (smb347_update_status(smb) > 0) { smb347_update_online(smb); power_supply_changed(&smb->mains); power_supply_changed(&smb->usb); ret = IRQ_HANDLED; } return ret; }
static irqreturn_t smb347_interrupt(int irq, void *data) { struct smb347_charger *smb = data; int stat_c, t; u8 irqstat[6]; irqreturn_t ret = IRQ_NONE; t = i2c_smbus_read_i2c_block_data(smb->client, IRQSTAT_A, 6, irqstat); if (t < 0) { dev_warn(&smb->client->dev, "reading IRQSTAT registers failed\n"); return IRQ_NONE; } stat_c = smb347_read(smb, STAT_C); if (stat_c < 0) { dev_warn(&smb->client->dev, "reading STAT_C failed\n"); return IRQ_NONE; } pr_debug("%s: stat c=%x irq a=%x b=%x c=%x d=%x e=%x f=%x\n", __func__, stat_c, irqstat[0], irqstat[1], irqstat[2], irqstat[3], irqstat[4], irqstat[5]); /* * If we get charger error we report the error back to user and * disable charging. */ if (stat_c & STAT_C_CHARGER_ERROR) { dev_err(&smb->client->dev, "error in charger, disabling charging\n"); smb347_charging_disable(smb); power_supply_changed(&smb->battery); ret = IRQ_HANDLED; } else if (((stat_c & STAT_C_CHG_STATUS) || (irqstat[2] & (IRQSTAT_C_TERMINATION_IRQ | IRQSTAT_C_TERMINATION_STAT))) && !smb->is_fully_charged) { dev_info(&smb->client->dev, "charge terminated"); smb->is_fully_charged = true; smb347_charging_disable(smb); power_supply_changed(&smb->battery); ret = IRQ_HANDLED; } if (irqstat[2] & IRQSTAT_C_TAPER_IRQ) ret = IRQ_HANDLED; /* * If we got an under voltage interrupt it means that AC/USB input * was disconnected. */ if (irqstat[4] & (IRQSTAT_E_USBIN_UV_IRQ | IRQSTAT_E_DCIN_UV_IRQ)) ret = IRQ_HANDLED; if (smb347_update_status(smb) > 0) { smb347_update_online(smb); power_supply_changed(&smb->mains); power_supply_changed(&smb->usb); ret = IRQ_HANDLED; } return ret; }