From patchwork Tue Oct 7 13:55:34 2014 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: =?utf-8?q?Lothar_Wa=C3=9Fmann?= X-Patchwork-Id: 397320 Return-Path: X-Original-To: incoming-imx@patchwork.ozlabs.org Delivered-To: patchwork-incoming-imx@bilbo.ozlabs.org Received: from bombadil.infradead.org (bombadil.infradead.org [IPv6:2001:1868:205::9]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 2592214007B for ; Wed, 8 Oct 2014 00:58:54 +1100 (EST) 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 1XbVFm-0004YT-AV; Tue, 07 Oct 2014 13:56:38 +0000 Received: from mail.karo-electronics.de ([81.173.242.67]) by bombadil.infradead.org with esmtps (Exim 4.80.1 #2 (Red Hat Linux)) id 1XbVFS-00043I-BZ for linux-arm-kernel@lists.infradead.org; Tue, 07 Oct 2014 13:56:19 +0000 From: =?UTF-8?q?Lothar=20Wa=C3=9Fmann?= To: linux-pwm@vger.kernel.org Subject: [PATCHv5 3/3] pwm: imx: support output polarity inversion Date: Tue, 7 Oct 2014 15:55:34 +0200 Message-Id: <1412690134-13712-4-git-send-email-LW@KARO-electronics.de> X-Mailer: git-send-email 1.7.10.4 In-Reply-To: <1412690134-13712-1-git-send-email-LW@KARO-electronics.de> References: <1412690134-13712-1-git-send-email-LW@KARO-electronics.de> MIME-Version: 1.0 X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20141007_065618_786114_A3EBB59B X-CRM114-Status: GOOD ( 13.72 ) X-Spam-Score: -0.7 (/) X-Spam-Report: SpamAssassin version 3.4.0 on bombadil.infradead.org summary: Content analysis details: (-0.7 points) pts rule name description ---- ---------------------- -------------------------------------------------- -0.7 RCVD_IN_DNSWL_LOW RBL: Sender listed at http://www.dnswl.org/, low trust [81.173.242.67 listed in list.dnswl.org] -0.0 T_RP_MATCHES_RCVD Envelope sender domain matches handover relay domain Cc: Sascha Hauer , Thierry Reding , Shawn Guo , linux-arm-kernel@lists.infradead.org, =?UTF-8?q?Lothar=20Wa=C3=9Fmann?= X-BeenThere: linux-arm-kernel@lists.infradead.org X-Mailman-Version: 2.1.18-1 Precedence: list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Sender: "linux-arm-kernel" Errors-To: linux-arm-kernel-bounces+incoming-imx=patchwork.ozlabs.org@lists.infradead.org List-Id: linux-imx-kernel.lists.patchwork.ozlabs.org The i.MX pwm unit on i.MX27 and newer SoCs provides a configurable output polarity. This patch adds support to utilize this feature where available. Signed-off-by: Lothar Waßmann Acked-by: Shawn Guo Reviewed-by: Sascha Hauer --- drivers/pwm/pwm-imx.c | 39 ++++++++++++++++++++++++++++++++++++--- 1 file changed, 36 insertions(+), 3 deletions(-) diff --git a/drivers/pwm/pwm-imx.c b/drivers/pwm/pwm-imx.c index f8b5f10..57aac836 100644 --- a/drivers/pwm/pwm-imx.c +++ b/drivers/pwm/pwm-imx.c @@ -179,6 +179,9 @@ static int imx_pwm_config_v2(struct pwm_chip *chip, if (enable) cr |= MX3_PWMCR_EN; + if (pwm->polarity == PWM_POLARITY_INVERSED) + cr |= MX3_PWMCR_POUTC; + writel(cr, imx->mmio_base + MX3_PWMCR); return 0; @@ -196,6 +199,11 @@ static void imx_pwm_set_enable_v2(struct pwm_chip *chip, bool enable) else val &= ~MX3_PWMCR_EN; + if (chip->pwms[0].polarity == PWM_POLARITY_INVERSED) + val |= MX3_PWMCR_POUTC; + else + val &= ~MX3_PWMCR_POUTC; + writel(val, imx->mmio_base + MX3_PWMCR); } @@ -239,27 +247,49 @@ static void imx_pwm_disable(struct pwm_chip *chip, struct pwm_device *pwm) clk_disable_unprepare(imx->clk_per); } -static struct pwm_ops imx_pwm_ops = { +static int imx_pwm_set_polarity(struct pwm_chip *chip, struct pwm_device *pwm, + enum pwm_polarity polarity) +{ + struct imx_chip *imx = to_imx_chip(chip); + + dev_dbg(imx->chip.dev, "%s: polarity set to %s\n", __func__, + polarity == PWM_POLARITY_INVERSED ? "inverted" : "normal"); + + return 0; +} + +static struct pwm_ops imx_pwm_ops_v1 = { .enable = imx_pwm_enable, .disable = imx_pwm_disable, .config = imx_pwm_config, .owner = THIS_MODULE, }; +static struct pwm_ops imx_pwm_ops_v2 = { + .enable = imx_pwm_enable, + .disable = imx_pwm_disable, + .set_polarity = imx_pwm_set_polarity, + .config = imx_pwm_config, + .owner = THIS_MODULE, +}; + struct imx_pwm_data { int (*config)(struct pwm_chip *chip, struct pwm_device *pwm, int duty_ns, int period_ns); void (*set_enable)(struct pwm_chip *chip, bool enable); + struct pwm_ops *pwm_ops; }; static struct imx_pwm_data imx_pwm_data_v1 = { .config = imx_pwm_config_v1, .set_enable = imx_pwm_set_enable_v1, + .pwm_ops = &imx_pwm_ops_v1, }; static struct imx_pwm_data imx_pwm_data_v2 = { .config = imx_pwm_config_v2, .set_enable = imx_pwm_set_enable_v2, + .pwm_ops = &imx_pwm_ops_v2, }; static const struct of_device_id imx_pwm_dt_ids[] = { @@ -281,6 +311,10 @@ static int imx_pwm_probe(struct platform_device *pdev) if (!of_id) return -ENODEV; + data = of_id->data; + if (data->pwm_ops->set_polarity) + dev_dbg(&pdev->dev, "PWM supports output inversion\n"); + imx = devm_kzalloc(&pdev->dev, sizeof(*imx), GFP_KERNEL); if (imx == NULL) return -ENOMEM; @@ -299,7 +333,7 @@ static int imx_pwm_probe(struct platform_device *pdev) return PTR_ERR(imx->clk_ipg); } - imx->chip.ops = &imx_pwm_ops; + imx->chip.ops = data->pwm_ops; imx->chip.dev = &pdev->dev; imx->chip.base = -1; imx->chip.npwm = 1; @@ -310,7 +344,6 @@ static int imx_pwm_probe(struct platform_device *pdev) if (IS_ERR(imx->mmio_base)) return PTR_ERR(imx->mmio_base); - data = of_id->data; imx->config = data->config; imx->set_enable = data->set_enable;