From patchwork Wed Mar 30 20:03:50 2016 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Boris BREZILLON X-Patchwork-Id: 8858821 Return-Path: X-Original-To: patchwork-linux-rockchip@patchwork.kernel.org Delivered-To: patchwork-parsemail@patchwork1.web.kernel.org Received: from mail.kernel.org (mail.kernel.org [198.145.29.136]) by patchwork1.web.kernel.org (Postfix) with ESMTP id E09709F442 for ; Fri, 15 Apr 2016 20:59:02 +0000 (UTC) Received: from mail.kernel.org (localhost [127.0.0.1]) by mail.kernel.org (Postfix) with ESMTP id F09302034A for ; Fri, 15 Apr 2016 20:59:01 +0000 (UTC) Received: from bombadil.infradead.org (bombadil.infradead.org [198.137.202.9]) (using TLSv1.2 with cipher AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPS id 10E3C200E1 for ; Fri, 15 Apr 2016 20:59:01 +0000 (UTC) Received: from localhost ([127.0.0.1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.80.1 #2 (Red Hat Linux)) id 1arApQ-0000nB-Ml; Fri, 15 Apr 2016 20:59:00 +0000 Received: from down.free-electrons.com ([37.187.137.238] helo=mail.free-electrons.com) by bombadil.infradead.org with esmtp (Exim 4.80.1 #2 (Red Hat Linux)) id 1alMNA-00067f-QH; Wed, 30 Mar 2016 20:05:52 +0000 Received: by mail.free-electrons.com (Postfix, from userid 110) id AD1961836; Wed, 30 Mar 2016 22:05:31 +0200 (CEST) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on mail.kernel.org X-Spam-Level: X-Spam-Status: No, score=-5.2 required=5.0 tests=BAYES_00, RCVD_IN_DNSWL_MED, RP_MATCHES_RCVD, UNPARSEABLE_RELAY autolearn=unavailable version=3.3.1 Received: from localhost.localdomain (LFbn-1-2159-240.w90-76.abo.wanadoo.fr [90.76.216.240]) by mail.free-electrons.com (Postfix) with ESMTPSA id 2AB61184B; Wed, 30 Mar 2016 22:05:04 +0200 (CEST) From: Boris Brezillon To: Thierry Reding , linux-pwm@vger.kernel.org Subject: [PATCH v5 27/46] regulator: pwm: adjust PWM config at probe time Date: Wed, 30 Mar 2016 22:03:50 +0200 Message-Id: <1459368249-13241-28-git-send-email-boris.brezillon@free-electrons.com> X-Mailer: git-send-email 2.5.0 In-Reply-To: <1459368249-13241-1-git-send-email-boris.brezillon@free-electrons.com> References: <1459368249-13241-1-git-send-email-boris.brezillon@free-electrons.com> X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20160330_130549_364607_6C79D693 X-CRM114-Status: GOOD ( 16.33 ) X-Spam-Score: -2.9 (--) X-Mailman-Approved-At: Fri, 15 Apr 2016 13:58:40 -0700 X-BeenThere: linux-rockchip@lists.infradead.org X-Mailman-Version: 2.1.20 Precedence: list List-Id: Upstream kernel work for Rockchip platforms List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Milo Kim , Kamil Debski , Heiko Stuebner , linux-doc@vger.kernel.org, David Airlie , Mike Turquette , linux-fbdev@vger.kernel.org, dri-devel@lists.freedesktop.org, linux-kernel@vger.kernel.org, linux-sunxi@googlegroups.com, Alexandre Belloni , Daniel Vetter , Lee Jones , linux-clk@vger.kernel.org, linux-leds@vger.kernel.org, Boris Brezillon , Krzysztof Kozlowski , linux-samsung-soc@vger.kernel.org, Alexander Shiyan , Jonathan Corbet , Robert Jarzmik , lm-sensors@lm-sensors.org, linux-rockchip@lists.infradead.org, Chen-Yu Tsai , Tomi Valkeinen , linux-input@vger.kernel.org, Jean-Christophe Plagniol-Villard , intel-gfx@lists.freedesktop.org, Guenter Roeck , Jean Delvare , Joachim Eastwood , Bryan Wu , Jani Nikula , Mark Brown , Jacek Anaszewski , linux-arm-kernel@lists.infradead.org, Thomas Petazzoni , Ryan Mallon , Jingoo Han , Dmitry Torokhov , Stephen Boyd , Liam Girdwood , Hartley Sweeten , Richard Purdie , Kukjin Kim , Daniel Vetter , Maxime Ripard MIME-Version: 1.0 Sender: "Linux-rockchip" Errors-To: linux-rockchip-bounces+patchwork-linux-rockchip=patchwork.kernel.org@lists.infradead.org X-Virus-Scanned: ClamAV using ClamSMTP The PWM attached to a PWM regulator device might have been previously configured by the bootloader. Make sure the bootloader and linux config are in sync, and adjust the PWM config if that's not the case. Signed-off-by: Boris Brezillon Acked-by: Mark Brown --- drivers/regulator/pwm-regulator.c | 50 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 50 insertions(+) diff --git a/drivers/regulator/pwm-regulator.c b/drivers/regulator/pwm-regulator.c index 9154c47..9590fb0 100644 --- a/drivers/regulator/pwm-regulator.c +++ b/drivers/regulator/pwm-regulator.c @@ -240,6 +240,52 @@ static int pwm_regulator_init_continuous(struct platform_device *pdev, return 0; } +static int pwm_regulator_adjust_pwm_config(struct pwm_regulator_data *drvdata) +{ + struct pwm_state pstate = { }; + struct pwm_args pargs = { }; + + pwm_get_args(drvdata->pwm, &pargs); + pwm_get_state(drvdata->pwm, &pstate); + + /* + * if the current period is zero this either means the PWM driver + * does not support initial state retrieval or the PWM was not + * configured. + * In any case, we setup the new period and poloarity, and assign a + * duty_cycle of 0. + */ + if (!pstate.period) { + pstate.duty_cycle = 0; + pstate.period = pargs.period; + pstate.polarity = pargs.polarity; + + return pwm_apply_state(drvdata->pwm, &pstate); + } + + /* + * Adjust the PWM dutycycle/period based on the period value provided + * in PWM args. + */ + if (pargs.period != pstate.period) { + u64 dutycycle = (u64)pstate.duty_cycle * pargs.period; + + do_div(dutycycle, pstate.period); + pstate.duty_cycle = dutycycle; + pstate.period = pargs.period; + } + + /* + * If the polarity changed, we should also change the dutycycle value. + */ + if (pargs.polarity != pstate.polarity) { + pstate.polarity = pargs.polarity; + pstate.duty_cycle = pstate.period - pstate.duty_cycle; + } + + return pwm_apply_state(drvdata->pwm, &pstate); +} + static int pwm_regulator_probe(struct platform_device *pdev) { const struct regulator_init_data *init_data; @@ -283,6 +329,10 @@ static int pwm_regulator_probe(struct platform_device *pdev) return PTR_ERR(drvdata->pwm); } + ret = pwm_regulator_adjust_pwm_config(drvdata); + if (ret) + return ret; + regulator = devm_regulator_register(&pdev->dev, &drvdata->desc, &config); if (IS_ERR(regulator)) {