From patchwork Mon Aug 29 15:58:40 2011 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: =?utf-8?q?Heiko_St=C3=BCbner?= X-Patchwork-Id: 1108562 Received: from smtp1.linux-foundation.org (smtp1.linux-foundation.org [140.211.169.13]) by demeter2.kernel.org (8.14.4/8.14.4) with ESMTP id p7TG1SnA010344 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=FAIL) for ; Mon, 29 Aug 2011 16:01:53 GMT Received: from daredevil.linux-foundation.org (localhost [127.0.0.1]) by smtp1.linux-foundation.org (8.14.2/8.13.5/Debian-3ubuntu1.1) with ESMTP id p7TFwkoe025428; Mon, 29 Aug 2011 08:58:47 -0700 Received: from s15407518.onlinehome-server.info (s15407518.onlinehome-server.info [82.165.136.167]) by smtp1.linux-foundation.org (8.14.2/8.13.5/Debian-3ubuntu1.1) with ESMTP id p7TFwgBe025410 (version=TLSv1/SSLv3 cipher=AES256-SHA bits=256 verify=NO) for ; Mon, 29 Aug 2011 08:58:44 -0700 Received: from 91-64-128-49-dynip.superkabel.de ([91.64.128.49] helo=marty.localnet) by s15407518.onlinehome-server.info with esmtpa (Exim 4.69) (envelope-from ) id 1Qy4ET-0002Ld-02; Mon, 29 Aug 2011 17:58:41 +0200 From: Heiko =?iso-8859-1?q?St=FCbner?= To: Mark Brown , Liam Girdwood Date: Mon, 29 Aug 2011 17:58:40 +0200 User-Agent: KMail/1.13.5 (Linux/2.6.37-2-686; KDE/4.4.5; i686; ; ) References: <201108291755.15701.heiko@sntech.de> In-Reply-To: <201108291755.15701.heiko@sntech.de> MIME-Version: 1.0 Message-Id: <201108291758.40459.heiko@sntech.de> Received-SPF: pass (localhost is always allowed.) X-Spam-Status: No, hits=-3.591 required=5 tests=AWL, BAYES_00, OSDL_HEADER_SUBJECT_BRACKETED X-Spam-Checker-Version: SpamAssassin 3.2.4-osdl_revision__1.47__ X-MIMEDefang-Filter: lf$Revision: 1.188 $ X-Scanned-By: MIMEDefang 2.63 on 140.211.169.21 Cc: linux-pm@lists.linux-foundation.org, Philipp Zabel Subject: [linux-pm] [PATCH 3/4] bq24022: Keep track of gpio states X-BeenThere: linux-pm@lists.linux-foundation.org X-Mailman-Version: 2.1.9 Precedence: list List-Id: Linux power management List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Sender: linux-pm-bounces@lists.linux-foundation.org Errors-To: linux-pm-bounces@lists.linux-foundation.org X-Greylist: IP, sender and recipient auto-whitelisted, not delayed by milter-greylist-4.2.6 (demeter2.kernel.org [140.211.167.43]); Mon, 29 Aug 2011 16:01:53 +0000 (UTC) gpio_get_value is not definied for output-gpios and can therefore not be used for the is_enabled and get_current_limit methods of the bq24022. This patch introduces a private struct to keep track of the values set. Signed-off-by: Heiko Stuebner Acked-by: Mark Brown --- drivers/regulator/bq24022.c | 67 +++++++++++++++++++++++++++++------------- 1 files changed, 46 insertions(+), 21 deletions(-) diff --git a/drivers/regulator/bq24022.c b/drivers/regulator/bq24022.c index 7bd906c..f75cd07 100644 --- a/drivers/regulator/bq24022.c +++ b/drivers/regulator/bq24022.c @@ -15,56 +15,69 @@ #include #include #include +#include #include #include #include +struct bq24022 { + struct regulator_dev *rdev; + + int gpio_nce; + int gpio_iset2; + + int state_nce; + int state_iset2; +}; static int bq24022_set_current_limit(struct regulator_dev *rdev, int min_uA, int max_uA) { - struct bq24022_mach_info *pdata = rdev_get_drvdata(rdev); + struct bq24022 *bq = rdev_get_drvdata(rdev); dev_dbg(rdev_get_dev(rdev), "setting current limit to %s mA\n", max_uA >= 500000 ? "500" : "100"); /* REVISIT: maybe return error if min_uA != 0 ? */ - gpio_set_value(pdata->gpio_iset2, max_uA >= 500000); + bq->state_iset2 = (max_uA >= 500000); + gpio_set_value(bq->gpio_iset2, bq->state_iset2); return 0; } static int bq24022_get_current_limit(struct regulator_dev *rdev) { - struct bq24022_mach_info *pdata = rdev_get_drvdata(rdev); + struct bq24022 *bq = rdev_get_drvdata(rdev); - return gpio_get_value(pdata->gpio_iset2) ? 500000 : 100000; + return bq->state_iset2 ? 500000 : 100000; } static int bq24022_enable(struct regulator_dev *rdev) { - struct bq24022_mach_info *pdata = rdev_get_drvdata(rdev); + struct bq24022 *bq = rdev_get_drvdata(rdev); dev_dbg(rdev_get_dev(rdev), "enabling charger\n"); - gpio_set_value(pdata->gpio_nce, 0); + gpio_set_value(bq->gpio_nce, 0); + bq->state_nce = 0; return 0; } static int bq24022_disable(struct regulator_dev *rdev) { - struct bq24022_mach_info *pdata = rdev_get_drvdata(rdev); + struct bq24022 *bq = rdev_get_drvdata(rdev); dev_dbg(rdev_get_dev(rdev), "disabling charger\n"); - gpio_set_value(pdata->gpio_nce, 1); + gpio_set_value(bq->gpio_nce, 1); + bq->state_nce = 1; return 0; } static int bq24022_is_enabled(struct regulator_dev *rdev) { - struct bq24022_mach_info *pdata = rdev_get_drvdata(rdev); + struct bq24022 *bq = rdev_get_drvdata(rdev); - return !gpio_get_value(pdata->gpio_nce); + return !bq->state_nce; } static struct regulator_ops bq24022_ops = { @@ -85,12 +98,18 @@ static struct regulator_desc bq24022_desc = { static int __init bq24022_probe(struct platform_device *pdev) { struct bq24022_mach_info *pdata = pdev->dev.platform_data; - struct regulator_dev *bq24022; + struct bq24022 *bq; int ret; if (!pdata || !pdata->gpio_nce || !pdata->gpio_iset2) return -EINVAL; + bq = kzalloc(sizeof(struct bq24022), GFP_KERNEL); + if (!bq) { + dev_err(&pdev->dev, "cannot allocate memory\n"); + return -ENOMEM; + } + ret = gpio_request(pdata->gpio_nce, "ncharge_en"); if (ret) { dev_err(&pdev->dev, "couldn't request nCE GPIO: %d\n", @@ -103,27 +122,32 @@ static int __init bq24022_probe(struct platform_device *pdev) pdata->gpio_iset2); goto err_iset2; } + + /* set initial current to 100mA and disable regulator */ ret = gpio_direction_output(pdata->gpio_iset2, 0); if (ret) { dev_err(&pdev->dev, "couldn't set ISET2 GPIO: %d\n", pdata->gpio_iset2); goto err_reg; } + bq->gpio_iset2 = pdata->gpio_iset2; ret = gpio_direction_output(pdata->gpio_nce, 1); if (ret) { dev_err(&pdev->dev, "couldn't set nCE GPIO: %d\n", pdata->gpio_nce); goto err_reg; } + bq->gpio_nce = pdata->gpio_nce; + bq->state_nce = 1; - bq24022 = regulator_register(&bq24022_desc, &pdev->dev, - pdata->init_data, pdata); - if (IS_ERR(bq24022)) { + bq->rdev = regulator_register(&bq24022_desc, &pdev->dev, + pdata->init_data, bq); + if (IS_ERR(bq->rdev)) { dev_err(&pdev->dev, "couldn't register regulator\n"); - ret = PTR_ERR(bq24022); + ret = PTR_ERR(bq->rdev); goto err_reg; } - platform_set_drvdata(pdev, bq24022); + platform_set_drvdata(pdev, bq); dev_dbg(&pdev->dev, "registered regulator\n"); return 0; @@ -137,12 +161,13 @@ err_ce: static int __devexit bq24022_remove(struct platform_device *pdev) { - struct bq24022_mach_info *pdata = pdev->dev.platform_data; - struct regulator_dev *bq24022 = platform_get_drvdata(pdev); + struct bq24022 *bq = platform_get_drvdata(pdev); - regulator_unregister(bq24022); - gpio_free(pdata->gpio_iset2); - gpio_free(pdata->gpio_nce); + regulator_unregister(bq->rdev); + gpio_free(bq->gpio_iset2); + gpio_free(bq->gpio_nce); + + kfree(bq); return 0; }