Loading drivers/power/qpnp-smbcharger.c +108 −27 Original line number Diff line number Diff line Loading @@ -116,7 +116,10 @@ struct smbchg_chip { int dcin_uv_irq; int usbin_uv_irq; int src_detect_irq; int otg_fail_irq; int otg_oc_irq; int aicl_done_irq; int usbid_change_irq; int chg_inhibit_irq; int chg_error_irq; Loading Loading @@ -286,6 +289,24 @@ out: return rc; } #define RID_STS 0xB #define RID_MASK 0xF static bool is_otg_present(struct smbchg_chip *chip) { int rc; u8 reg; rc = smbchg_read(chip, ®, chip->usb_chgpth_base + RID_STS, 1); if (rc < 0) { pr_err("Couldn't read usb rid status rc = %d\n", rc); return false; } pr_debug("RID_STS = %02x\n", reg); return (reg & RID_MASK) == 0; } #define USBIN_9V BIT(5) #define USBIN_UNREG BIT(4) #define USBIN_LV BIT(3) Loading Loading @@ -1786,6 +1807,25 @@ static irqreturn_t src_detect_handler(int irq, void *_chip) return IRQ_HANDLED; } /** * otg_oc_handler() - called when the usb otg goes over current */ static irqreturn_t otg_oc_handler(int irq, void *_chip) { pr_debug("triggered\n"); return IRQ_HANDLED; } /** * otg_fail_handler() - called when the usb otg fails * (when vbat < OTG UVLO threshold) */ static irqreturn_t otg_fail_handler(int irq, void *_chip) { pr_debug("triggered\n"); return IRQ_HANDLED; } /** * aicl_done_handler() - called when the usb AICL algorithm is finished * and a current is set. Loading @@ -1801,6 +1841,33 @@ static irqreturn_t aicl_done_handler(int irq, void *_chip) return IRQ_HANDLED; } /** * usbid_change_handler() - called when the usb RID changes. * This is used mostly for detecting OTG */ static irqreturn_t usbid_change_handler(int irq, void *_chip) { struct smbchg_chip *chip = _chip; bool otg_present; pr_debug("triggered\n"); /* * After the falling edge of the usbid change interrupt occurs, * there may still be some time before the ADC conversion for USB RID * finishes in the fuel gauge. * * Sleep for a bit to wait for the conversion to finish and the USB RID * status register to be updated before trying to detect OTG insertions. */ usleep_range(5000, 20000); otg_present = is_otg_present(chip); if (chip->usb_psy) power_supply_set_usb_otg(chip->usb_psy, otg_present ? 1 : 0); return IRQ_HANDLED; } static irqreturn_t chg_inhibit_handler(int irq, void *_chip) { /* Loading Loading @@ -1834,6 +1901,7 @@ static int determine_initial_status(struct smbchg_chip *chip) batt_cool_handler(0, chip); batt_cold_handler(0, chip); chg_term_handler(0, chip); usbid_change_handler(0, chip); chip->usb_present = is_usb_present(chip); chip->dc_present = is_dc_present(chip); Loading Loading @@ -2339,7 +2407,7 @@ static int smb_parse_dt(struct smbchg_chip *chip) #define SMBCHG_USB_CHGPTH_SUBTYPE 0x4 #define SMBCHG_DC_CHGPTH_SUBTYPE 0x5 #define SMBCHG_MISC_SUBTYPE 0x7 #define REQUEST_IRQ(chip, resource, irq_num, irq_name, irq_handler, rc) \ #define REQUEST_IRQ(chip, resource, irq_num, irq_name, irq_handler, flags, rc)\ do { \ irq_num = spmi_get_irq_byname(chip->spmi, \ resource, irq_name); \ Loading @@ -2348,9 +2416,8 @@ do { \ return -ENXIO; \ } \ rc = devm_request_threaded_irq(chip->dev, \ irq_num, NULL, irq_handler, \ IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING \ | IRQF_ONESHOT, irq_name, chip); \ irq_num, NULL, irq_handler, flags, irq_name, \ chip); \ if (rc < 0) { \ dev_err(chip->dev, "Unable to request " irq_name " irq: %d\n",\ rc); \ Loading @@ -2365,6 +2432,8 @@ static int smbchg_request_irqs(struct smbchg_chip *chip) struct spmi_resource *spmi_resource; u8 subtype; struct spmi_device *spmi = chip->spmi; unsigned long flags = IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING | IRQF_ONESHOT; spmi_for_each_container_dev(spmi_resource, chip->spmi) { if (!spmi_resource) { Loading @@ -2391,34 +2460,34 @@ static int smbchg_request_irqs(struct smbchg_chip *chip) switch (subtype) { case SMBCHG_CHGR_SUBTYPE: REQUEST_IRQ(chip, spmi_resource, chip->chg_error_irq, "chg-error", chg_error_handler, rc); "chg-error", chg_error_handler, flags, rc); REQUEST_IRQ(chip, spmi_resource, chip->taper_irq, "chg-taper-thr", taper_handler, rc); "chg-taper-thr", taper_handler, flags, rc); REQUEST_IRQ(chip, spmi_resource, chip->chg_term_irq, "chg-tcc-thr", chg_term_handler, rc); "chg-tcc-thr", chg_term_handler, flags, rc); REQUEST_IRQ(chip, spmi_resource, chip->chg_inhibit_irq, "chg-inhibit", chg_inhibit_handler, rc); "chg-inhibit", chg_inhibit_handler, flags, rc); REQUEST_IRQ(chip, spmi_resource, chip->recharge_irq, "chg-rechg-thr", recharge_handler, rc); "chg-rechg-thr", recharge_handler, flags, rc); REQUEST_IRQ(chip, spmi_resource, chip->fastchg_irq, "chg-p2f-thr", fastchg_handler, rc); "chg-p2f-thr", fastchg_handler, flags, rc); enable_irq_wake(chip->chg_term_irq); enable_irq_wake(chip->chg_error_irq); enable_irq_wake(chip->fastchg_irq); break; case SMBCHG_BAT_IF_SUBTYPE: REQUEST_IRQ(chip, spmi_resource, chip->batt_hot_irq, "batt-hot", batt_hot_handler, rc); "batt-hot", batt_hot_handler, flags, rc); REQUEST_IRQ(chip, spmi_resource, chip->batt_warm_irq, "batt-warm", batt_warm_handler, rc); "batt-warm", batt_warm_handler, flags, rc); REQUEST_IRQ(chip, spmi_resource, chip->batt_cool_irq, "batt-cool", batt_cool_handler, rc); "batt-cool", batt_cool_handler, flags, rc); REQUEST_IRQ(chip, spmi_resource, chip->batt_cold_irq, "batt-cold", batt_cold_handler, rc); "batt-cold", batt_cold_handler, flags, rc); REQUEST_IRQ(chip, spmi_resource, chip->batt_missing_irq, "batt-missing", batt_pres_handler, rc); "batt-missing", batt_pres_handler, flags, rc); REQUEST_IRQ(chip, spmi_resource, chip->vbat_low_irq, "batt-low", vbat_low_handler, rc); "batt-low", vbat_low_handler, flags, rc); enable_irq_wake(chip->batt_hot_irq); enable_irq_wake(chip->batt_warm_irq); enable_irq_wake(chip->batt_cool_irq); Loading @@ -2428,30 +2497,42 @@ static int smbchg_request_irqs(struct smbchg_chip *chip) break; case SMBCHG_USB_CHGPTH_SUBTYPE: REQUEST_IRQ(chip, spmi_resource, chip->usbin_uv_irq, "usbin-uv", usbin_uv_handler, rc); "usbin-uv", usbin_uv_handler, flags, rc); REQUEST_IRQ(chip, spmi_resource, chip->src_detect_irq, "usbin-src-det", src_detect_handler, rc); src_detect_handler, flags, rc); REQUEST_IRQ(chip, spmi_resource, chip->otg_fail_irq, "otg-fail", otg_fail_handler, flags, rc); REQUEST_IRQ(chip, spmi_resource, chip->otg_oc_irq, "otg-oc", otg_oc_handler, (IRQF_TRIGGER_RISING | IRQF_ONESHOT), rc); REQUEST_IRQ(chip, spmi_resource, chip->aicl_done_irq, "aicl-done", aicl_done_handler, rc); aicl_done_handler, flags, rc); REQUEST_IRQ(chip, spmi_resource, chip->usbid_change_irq, "usbid-change", usbid_change_handler, (IRQF_TRIGGER_FALLING | IRQF_ONESHOT), rc); enable_irq_wake(chip->usbin_uv_irq); enable_irq_wake(chip->src_detect_irq); enable_irq_wake(chip->otg_fail_irq); enable_irq_wake(chip->otg_oc_irq); enable_irq_wake(chip->usbid_change_irq); break; case SMBCHG_DC_CHGPTH_SUBTYPE: REQUEST_IRQ(chip, spmi_resource, chip->dcin_uv_irq, "dcin-uv", dcin_uv_handler, rc); "dcin-uv", dcin_uv_handler, flags, rc); enable_irq_wake(chip->dcin_uv_irq); break; case SMBCHG_MISC_SUBTYPE: REQUEST_IRQ(chip, spmi_resource, chip->power_ok_irq, "power-ok", power_ok_handler, rc); "power-ok", power_ok_handler, flags, rc); REQUEST_IRQ(chip, spmi_resource, chip->chg_hot_irq, "temp-shutdown", chg_hot_handler, rc); "temp-shutdown", chg_hot_handler, flags, rc); REQUEST_IRQ(chip, spmi_resource, chip->safety_timeout_irq, "safety-timeout", safety_timeout_handler, rc); safety_timeout_handler, flags, rc); enable_irq_wake(chip->chg_hot_irq); enable_irq_wake(chip->safety_timeout_irq); break; Loading Loading
drivers/power/qpnp-smbcharger.c +108 −27 Original line number Diff line number Diff line Loading @@ -116,7 +116,10 @@ struct smbchg_chip { int dcin_uv_irq; int usbin_uv_irq; int src_detect_irq; int otg_fail_irq; int otg_oc_irq; int aicl_done_irq; int usbid_change_irq; int chg_inhibit_irq; int chg_error_irq; Loading Loading @@ -286,6 +289,24 @@ out: return rc; } #define RID_STS 0xB #define RID_MASK 0xF static bool is_otg_present(struct smbchg_chip *chip) { int rc; u8 reg; rc = smbchg_read(chip, ®, chip->usb_chgpth_base + RID_STS, 1); if (rc < 0) { pr_err("Couldn't read usb rid status rc = %d\n", rc); return false; } pr_debug("RID_STS = %02x\n", reg); return (reg & RID_MASK) == 0; } #define USBIN_9V BIT(5) #define USBIN_UNREG BIT(4) #define USBIN_LV BIT(3) Loading Loading @@ -1786,6 +1807,25 @@ static irqreturn_t src_detect_handler(int irq, void *_chip) return IRQ_HANDLED; } /** * otg_oc_handler() - called when the usb otg goes over current */ static irqreturn_t otg_oc_handler(int irq, void *_chip) { pr_debug("triggered\n"); return IRQ_HANDLED; } /** * otg_fail_handler() - called when the usb otg fails * (when vbat < OTG UVLO threshold) */ static irqreturn_t otg_fail_handler(int irq, void *_chip) { pr_debug("triggered\n"); return IRQ_HANDLED; } /** * aicl_done_handler() - called when the usb AICL algorithm is finished * and a current is set. Loading @@ -1801,6 +1841,33 @@ static irqreturn_t aicl_done_handler(int irq, void *_chip) return IRQ_HANDLED; } /** * usbid_change_handler() - called when the usb RID changes. * This is used mostly for detecting OTG */ static irqreturn_t usbid_change_handler(int irq, void *_chip) { struct smbchg_chip *chip = _chip; bool otg_present; pr_debug("triggered\n"); /* * After the falling edge of the usbid change interrupt occurs, * there may still be some time before the ADC conversion for USB RID * finishes in the fuel gauge. * * Sleep for a bit to wait for the conversion to finish and the USB RID * status register to be updated before trying to detect OTG insertions. */ usleep_range(5000, 20000); otg_present = is_otg_present(chip); if (chip->usb_psy) power_supply_set_usb_otg(chip->usb_psy, otg_present ? 1 : 0); return IRQ_HANDLED; } static irqreturn_t chg_inhibit_handler(int irq, void *_chip) { /* Loading Loading @@ -1834,6 +1901,7 @@ static int determine_initial_status(struct smbchg_chip *chip) batt_cool_handler(0, chip); batt_cold_handler(0, chip); chg_term_handler(0, chip); usbid_change_handler(0, chip); chip->usb_present = is_usb_present(chip); chip->dc_present = is_dc_present(chip); Loading Loading @@ -2339,7 +2407,7 @@ static int smb_parse_dt(struct smbchg_chip *chip) #define SMBCHG_USB_CHGPTH_SUBTYPE 0x4 #define SMBCHG_DC_CHGPTH_SUBTYPE 0x5 #define SMBCHG_MISC_SUBTYPE 0x7 #define REQUEST_IRQ(chip, resource, irq_num, irq_name, irq_handler, rc) \ #define REQUEST_IRQ(chip, resource, irq_num, irq_name, irq_handler, flags, rc)\ do { \ irq_num = spmi_get_irq_byname(chip->spmi, \ resource, irq_name); \ Loading @@ -2348,9 +2416,8 @@ do { \ return -ENXIO; \ } \ rc = devm_request_threaded_irq(chip->dev, \ irq_num, NULL, irq_handler, \ IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING \ | IRQF_ONESHOT, irq_name, chip); \ irq_num, NULL, irq_handler, flags, irq_name, \ chip); \ if (rc < 0) { \ dev_err(chip->dev, "Unable to request " irq_name " irq: %d\n",\ rc); \ Loading @@ -2365,6 +2432,8 @@ static int smbchg_request_irqs(struct smbchg_chip *chip) struct spmi_resource *spmi_resource; u8 subtype; struct spmi_device *spmi = chip->spmi; unsigned long flags = IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING | IRQF_ONESHOT; spmi_for_each_container_dev(spmi_resource, chip->spmi) { if (!spmi_resource) { Loading @@ -2391,34 +2460,34 @@ static int smbchg_request_irqs(struct smbchg_chip *chip) switch (subtype) { case SMBCHG_CHGR_SUBTYPE: REQUEST_IRQ(chip, spmi_resource, chip->chg_error_irq, "chg-error", chg_error_handler, rc); "chg-error", chg_error_handler, flags, rc); REQUEST_IRQ(chip, spmi_resource, chip->taper_irq, "chg-taper-thr", taper_handler, rc); "chg-taper-thr", taper_handler, flags, rc); REQUEST_IRQ(chip, spmi_resource, chip->chg_term_irq, "chg-tcc-thr", chg_term_handler, rc); "chg-tcc-thr", chg_term_handler, flags, rc); REQUEST_IRQ(chip, spmi_resource, chip->chg_inhibit_irq, "chg-inhibit", chg_inhibit_handler, rc); "chg-inhibit", chg_inhibit_handler, flags, rc); REQUEST_IRQ(chip, spmi_resource, chip->recharge_irq, "chg-rechg-thr", recharge_handler, rc); "chg-rechg-thr", recharge_handler, flags, rc); REQUEST_IRQ(chip, spmi_resource, chip->fastchg_irq, "chg-p2f-thr", fastchg_handler, rc); "chg-p2f-thr", fastchg_handler, flags, rc); enable_irq_wake(chip->chg_term_irq); enable_irq_wake(chip->chg_error_irq); enable_irq_wake(chip->fastchg_irq); break; case SMBCHG_BAT_IF_SUBTYPE: REQUEST_IRQ(chip, spmi_resource, chip->batt_hot_irq, "batt-hot", batt_hot_handler, rc); "batt-hot", batt_hot_handler, flags, rc); REQUEST_IRQ(chip, spmi_resource, chip->batt_warm_irq, "batt-warm", batt_warm_handler, rc); "batt-warm", batt_warm_handler, flags, rc); REQUEST_IRQ(chip, spmi_resource, chip->batt_cool_irq, "batt-cool", batt_cool_handler, rc); "batt-cool", batt_cool_handler, flags, rc); REQUEST_IRQ(chip, spmi_resource, chip->batt_cold_irq, "batt-cold", batt_cold_handler, rc); "batt-cold", batt_cold_handler, flags, rc); REQUEST_IRQ(chip, spmi_resource, chip->batt_missing_irq, "batt-missing", batt_pres_handler, rc); "batt-missing", batt_pres_handler, flags, rc); REQUEST_IRQ(chip, spmi_resource, chip->vbat_low_irq, "batt-low", vbat_low_handler, rc); "batt-low", vbat_low_handler, flags, rc); enable_irq_wake(chip->batt_hot_irq); enable_irq_wake(chip->batt_warm_irq); enable_irq_wake(chip->batt_cool_irq); Loading @@ -2428,30 +2497,42 @@ static int smbchg_request_irqs(struct smbchg_chip *chip) break; case SMBCHG_USB_CHGPTH_SUBTYPE: REQUEST_IRQ(chip, spmi_resource, chip->usbin_uv_irq, "usbin-uv", usbin_uv_handler, rc); "usbin-uv", usbin_uv_handler, flags, rc); REQUEST_IRQ(chip, spmi_resource, chip->src_detect_irq, "usbin-src-det", src_detect_handler, rc); src_detect_handler, flags, rc); REQUEST_IRQ(chip, spmi_resource, chip->otg_fail_irq, "otg-fail", otg_fail_handler, flags, rc); REQUEST_IRQ(chip, spmi_resource, chip->otg_oc_irq, "otg-oc", otg_oc_handler, (IRQF_TRIGGER_RISING | IRQF_ONESHOT), rc); REQUEST_IRQ(chip, spmi_resource, chip->aicl_done_irq, "aicl-done", aicl_done_handler, rc); aicl_done_handler, flags, rc); REQUEST_IRQ(chip, spmi_resource, chip->usbid_change_irq, "usbid-change", usbid_change_handler, (IRQF_TRIGGER_FALLING | IRQF_ONESHOT), rc); enable_irq_wake(chip->usbin_uv_irq); enable_irq_wake(chip->src_detect_irq); enable_irq_wake(chip->otg_fail_irq); enable_irq_wake(chip->otg_oc_irq); enable_irq_wake(chip->usbid_change_irq); break; case SMBCHG_DC_CHGPTH_SUBTYPE: REQUEST_IRQ(chip, spmi_resource, chip->dcin_uv_irq, "dcin-uv", dcin_uv_handler, rc); "dcin-uv", dcin_uv_handler, flags, rc); enable_irq_wake(chip->dcin_uv_irq); break; case SMBCHG_MISC_SUBTYPE: REQUEST_IRQ(chip, spmi_resource, chip->power_ok_irq, "power-ok", power_ok_handler, rc); "power-ok", power_ok_handler, flags, rc); REQUEST_IRQ(chip, spmi_resource, chip->chg_hot_irq, "temp-shutdown", chg_hot_handler, rc); "temp-shutdown", chg_hot_handler, flags, rc); REQUEST_IRQ(chip, spmi_resource, chip->safety_timeout_irq, "safety-timeout", safety_timeout_handler, rc); safety_timeout_handler, flags, rc); enable_irq_wake(chip->chg_hot_irq); enable_irq_wake(chip->safety_timeout_irq); break; Loading