From patchwork Thu Sep 27 20:08:55 2012 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Mathieu Poirier X-Patchwork-Id: 11812 Return-Path: X-Original-To: patchwork@peony.canonical.com Delivered-To: patchwork@peony.canonical.com Received: from fiordland.canonical.com (fiordland.canonical.com [91.189.94.145]) by peony.canonical.com (Postfix) with ESMTP id EF36D24140 for ; Thu, 27 Sep 2012 20:10:16 +0000 (UTC) Received: from mail-ie0-f180.google.com (mail-ie0-f180.google.com [209.85.223.180]) by fiordland.canonical.com (Postfix) with ESMTP id A3438A18968 for ; Thu, 27 Sep 2012 20:10:16 +0000 (UTC) Received: by mail-ie0-f180.google.com with SMTP id e10so5234855iej.11 for ; Thu, 27 Sep 2012 13:10:16 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20120113; h=x-forwarded-to:x-forwarded-for:delivered-to:received-spf:from:to :subject:date:message-id:x-mailer:in-reply-to:references :x-gm-message-state; bh=F63B21xq3ScomCz2aZ3xs2sS0S7d5ZbKCu+pWjfkahw=; b=bRV3mlaxBLfS4kd2jSf0yhg+bYSUre7iUeoH25OYaoMwgporIX9J5B4lrp+g7AkUym uuyP9v5oM6PaSiMn9jYEfSyD7xEAHOC4K52TVf4oqbTWOvgUQsi5xO6Lx4WAHe4iXVyk FMlj4M0agKvY2v8a88ouAeRWujGwm9oJWgwLqtNPwave4UlDHCzUVlZhwlEIHGdgF+H7 LvaZ20O076w2fe1K+johYG6nZ9Z5H8RopOEDG1q91I1Ms4eOp7XdgYKCXITuGMhuTGp4 Utr8WCto/YJsVDAoBgLvV7Z0Y2CALBIFTIOyasGU0tSSLCVCMW6TY53LmhZhf+hbOQKU LbkQ== Received: by 10.50.7.212 with SMTP id l20mr4642622iga.43.1348776616375; Thu, 27 Sep 2012 13:10:16 -0700 (PDT) X-Forwarded-To: linaro-patchwork@canonical.com X-Forwarded-For: patch@linaro.org linaro-patchwork@canonical.com Delivered-To: patches@linaro.org Received: by 10.50.184.232 with SMTP id ex8csp436361igc; Thu, 27 Sep 2012 13:10:14 -0700 (PDT) Received: by 10.68.212.161 with SMTP id nl1mr14634298pbc.84.1348776613949; Thu, 27 Sep 2012 13:10:13 -0700 (PDT) Received: from mail-pa0-f50.google.com (mail-pa0-f50.google.com [209.85.220.50]) by mx.google.com with ESMTPS id vn9si8390651pbc.17.2012.09.27.13.10.13 (version=TLSv1/SSLv3 cipher=OTHER); Thu, 27 Sep 2012 13:10:13 -0700 (PDT) Received-SPF: neutral (google.com: 209.85.220.50 is neither permitted nor denied by best guess record for domain of mathieu.poirier@linaro.org) client-ip=209.85.220.50; Authentication-Results: mx.google.com; spf=neutral (google.com: 209.85.220.50 is neither permitted nor denied by best guess record for domain of mathieu.poirier@linaro.org) smtp.mail=mathieu.poirier@linaro.org Received: by mail-pa0-f50.google.com with SMTP id hz11so1847989pad.37 for ; Thu, 27 Sep 2012 13:10:13 -0700 (PDT) Received: by 10.68.134.97 with SMTP id pj1mr14547642pbb.55.1348776611948; Thu, 27 Sep 2012 13:10:11 -0700 (PDT) Received: from localhost.localdomain (S0106002369de4dac.cg.shawcable.net. [70.73.24.112]) by mx.google.com with ESMTPS id sa2sm1587890pbc.4.2012.09.27.13.10.08 (version=TLSv1/SSLv3 cipher=OTHER); Thu, 27 Sep 2012 13:10:10 -0700 (PDT) From: mathieu.poirier@linaro.org To: patches@linaro.org Subject: [PATCH 38/57] power: l9540: Charge only mode fixes Date: Thu, 27 Sep 2012 14:08:55 -0600 Message-Id: <1348776554-10019-39-git-send-email-mathieu.poirier@linaro.org> X-Mailer: git-send-email 1.7.5.4 In-Reply-To: <1348776554-10019-1-git-send-email-mathieu.poirier@linaro.org> References: <1348776554-10019-1-git-send-email-mathieu.poirier@linaro.org> X-Gm-Message-State: ALoCoQn22M5k6LLUg2zIrlnsIbMN2SfM5sp/Fpadt0muUQJKMvkFmPoThg8E394DGDxfh6RzJew1 From: Rupesh Kumar Fix for: charging not getting enabled in charge only mode by external charger. Signed-off-by: Rupesh Kumar Signed-off-by: Mathieu Poirier Reviewed-by: Marcus COOPER Reviewed-by: Michel JAOUEN Reviewed-by: Philippe LANGLAIS Reviewed-by: Philippe LANGLAIS --- drivers/power/ab8500_charger.c | 42 +++++++++++++++++++++++++++++ drivers/power/abx500_chargalg.c | 14 +++++++++ include/linux/mfd/abx500/ux500_chargalg.h | 2 + 3 files changed, 58 insertions(+), 0 deletions(-) diff --git a/drivers/power/ab8500_charger.c b/drivers/power/ab8500_charger.c index 70e7c5e..ebeb068 100644 --- a/drivers/power/ab8500_charger.c +++ b/drivers/power/ab8500_charger.c @@ -15,6 +15,7 @@ #include #include #include +#include #include #include #include @@ -94,6 +95,10 @@ #define AB8500_SW_CONTROL_FALLBACK 0x03 /* Wait for enumeration before charging in us */ #define WAIT_ACA_RID_ENUMERATION (5 * 1000) +/*External charger control*/ +#define AB8500_SYS_CHARGER_CONTROL_REG 0x52 +#define EXTERNAL_CHARGER_DISABLE_REG_VAL 0x03 +#define EXTERNAL_CHARGER_ENABLE_REG_VAL 0x07 /* UsbLineStatus register - usb types */ enum ab8500_charger_link_status { @@ -1672,6 +1677,29 @@ static int ab8500_charger_usb_en(struct ux500_charger *charger, return ret; } +static int ab8500_external_charger_prepare(struct notifier_block *charger_nb, + unsigned long event, void *data) +{ + int ret; + struct device *dev = data; + /*Toggle External charger control pin*/ + ret = abx500_set_register_interruptible(dev, AB8500_SYS_CTRL1_BLOCK, + AB8500_SYS_CHARGER_CONTROL_REG, + EXTERNAL_CHARGER_DISABLE_REG_VAL); + if (ret < 0) { + dev_err(dev, "write reg failed %d\n", ret); + goto out; + } + ret = abx500_set_register_interruptible(dev, AB8500_SYS_CTRL1_BLOCK, + AB8500_SYS_CHARGER_CONTROL_REG, + EXTERNAL_CHARGER_ENABLE_REG_VAL); + if (ret < 0) + dev_err(dev, "Write reg failed %d\n", ret); + +out: + return ret; +} + /** * ab8500_charger_usb_check_enable() - enable usb charging * @charger: pointer to the ux500_charger structure @@ -3201,6 +3229,10 @@ static int ab8500_charger_suspend(struct platform_device *pdev, #define ab8500_charger_resume NULL #endif +static struct notifier_block charger_nb = { + .notifier_call = ab8500_external_charger_prepare, +}; + static int __devexit ab8500_charger_remove(struct platform_device *pdev) { struct ab8500_charger *di = platform_get_drvdata(pdev); @@ -3233,6 +3265,11 @@ static int __devexit ab8500_charger_remove(struct platform_device *pdev) /* Delete the work queue */ destroy_workqueue(di->charger_wq); + /*Unregister external charger enable notifier*/ + if (!di->ac_chg.enabled) + blocking_notifier_chain_unregister( + &charger_notifier_list, &charger_nb); + flush_scheduled_work(); if (di->usb_chg.enabled) power_supply_unregister(&di->usb_chg.psy); @@ -3307,6 +3344,11 @@ static int __devinit ab8500_charger_probe(struct platform_device *pdev) di->ac_chg.enabled = di->pdata->ac_enabled; di->ac_chg.external = false; + /*notifier for external charger enabling*/ + if (!di->ac_chg.enabled) + blocking_notifier_chain_register( + &charger_notifier_list, &charger_nb); + /* USB supply */ /* power_supply base class */ di->usb_chg.psy.name = "ab8500_usb"; diff --git a/drivers/power/abx500_chargalg.c b/drivers/power/abx500_chargalg.c index 9568f63..3ca00dd 100644 --- a/drivers/power/abx500_chargalg.c +++ b/drivers/power/abx500_chargalg.c @@ -24,6 +24,7 @@ #include #include #include +#include /* Watchdog kick interval */ #define CHG_WD_INTERVAL (6 * HZ) @@ -255,6 +256,9 @@ static enum power_supply_property abx500_chargalg_props[] = { POWER_SUPPLY_PROP_HEALTH, }; +/*External charger prepare notifier*/ +BLOCKING_NOTIFIER_HEAD(charger_notifier_list); + /** * abx500_chargalg_safety_timer_expired() - Expiration of the safety timer * @data: pointer to the abx500_chargalg structure @@ -508,6 +512,8 @@ static int abx500_chargalg_kick_watchdog(struct abx500_chargalg *di) static int abx500_chargalg_ac_en(struct abx500_chargalg *di, int enable, int vset, int iset) { + static int ab8500_chargalg_ex_ac_enable_toggle; + if (!di->ac_chg || !di->ac_chg->ops.enable) return -ENXIO; @@ -520,6 +526,14 @@ static int abx500_chargalg_ac_en(struct abx500_chargalg *di, int enable, di->chg_info.ac_iset = iset; di->chg_info.ac_vset = vset; + /*enable external charger*/ + if (enable && di->ac_chg->external && + !ab8500_chargalg_ex_ac_enable_toggle) { + blocking_notifier_call_chain(&charger_notifier_list, + 0, di->dev); + ab8500_chargalg_ex_ac_enable_toggle++; + } + return di->ac_chg->ops.enable(di->ac_chg, enable, vset, iset); } diff --git a/include/linux/mfd/abx500/ux500_chargalg.h b/include/linux/mfd/abx500/ux500_chargalg.h index 110d12f..fa831f1 100644 --- a/include/linux/mfd/abx500/ux500_chargalg.h +++ b/include/linux/mfd/abx500/ux500_chargalg.h @@ -41,4 +41,6 @@ struct ux500_charger { bool external; }; +extern struct blocking_notifier_head charger_notifier_list; + #endif