Return-Path: Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1752195AbcJALsQ (ORCPT ); Sat, 1 Oct 2016 07:48:16 -0400 Received: from mail-db5eur01on0099.outbound.protection.outlook.com ([104.47.2.99]:7254 "EHLO EUR01-DB5-obe.outbound.protection.outlook.com" rhost-flags-OK-OK-OK-FAIL) by vger.kernel.org with ESMTP id S1752019AbcJALr4 (ORCPT ); Sat, 1 Oct 2016 07:47:56 -0400 Authentication-Results: spf=none (sender IP is ) smtp.mailfrom=bhuvanchandra.dv@toradex.com; From: Bhuvanchandra DV To: , CC: , , , , , , , , , , Lothar Wassmann , Bhuvanchandra DV Subject: [PATCH v2 3/6] pwm: imx: support output polarity inversion Date: Sat, 1 Oct 2016 15:42:32 +0530 Message-ID: <20161001101235.24598-4-bhuvanchandra.dv@toradex.com> X-Mailer: git-send-email 2.9.2 In-Reply-To: <20161001101235.24598-1-bhuvanchandra.dv@toradex.com> References: <20161001101235.24598-1-bhuvanchandra.dv@toradex.com> MIME-Version: 1.0 Content-Type: text/plain; charset="UTF-8" Content-Transfer-Encoding: 8bit X-Originating-IP: [115.115.243.34] X-ClientProxiedBy: PN1PR01CA0050.INDPRD01.PROD.OUTLOOK.COM (2a01:111:e400:5a3d::22) To AM3PR05MB1396.eurprd05.prod.outlook.com (2a01:111:e400:5871::11) X-MS-Office365-Filtering-Correlation-Id: bae01f3f-fa78-4abf-83c0-08d3e9e3cce0 X-Microsoft-Exchange-Diagnostics: 1;AM3PR05MB1396;2:Fbg/4Ct4IfUd+NdB/8ZhPEzGqci4Qmy/o3j8tNc8bQU0DkDwBgka1aOD8HKTtXg10ml34+ulhmmBJApyeM7i+seSg6Kb4PPY23+og7r0w7JLohtBkSgq21vXM1WA6Uxp3695qvUIVYCy97KRhN5wPKWEm0uDfZJGM1Y9h+WKwU31taOudONW8tZn7PE0LMVF;3:DuWV/G7wHxngEbgOMhHYixDvBQDqN/b5WkEDFz9Yh3MDSXgZiO0A2v1YTdUGVRCsbRz3Avwj5K2fg6mJAR1GAJVDFHqrSY9OiO1FA3+B3aDmYgUgg5rJYfE8zspTmRaF;25:MbM0VN8H6V1FzhQKCxqWYPVfWXM6TPl/AfzwFO+xMxYdE80lzUvNo+eH+9D+T93rd7kjvL1NM3BRgfx1t7lMluBekXtnelcAe1VPHV55BL8JHhDAzQ0lARCyKQyep1msu5Hl/1R19RrGI1qIneZJhs1bIWy2M1NqRcWp701hVN1YRLc7FT8+mf3CFqpF8q8vR+UPoIE4u+lbEjzS9utN5ocagAgAUkA3RSu264DQkcAmY+VSoJTPDeMMDQgGwZbAL14iE44Vrs/+YZL7gHm5NkUdj/lKKw9cwVFhLIMasLdgUtwRvUY3pADQLrz9YFoAiiA8XcBLV2GRnvPHfpXg+AUplEaN73ETsAL/2oyveVQB1WnI47oKpJmm6zjBT/gjBVkbH5uDdI/p/f/d4/UJPfnkksLG8XJLqRswS7TKRZs= X-Microsoft-Antispam: UriScan:;BCL:0;PCL:0;RULEID:;SRVR:AM3PR05MB1396; X-Microsoft-Exchange-Diagnostics: 1;AM3PR05MB1396;31:+6bnqVS021pvQzR1uVlNgFpYjrOQ6ori2lo4SaShOn7Ger8CuaaUA5QuWPIGlhFUdyNJI1774xLIvXyenvhuZlPXIPLM5C6HMvvRlQEb+D2J0vQgAkndBo9OhOOCo8Q9k9JQXxtfZL3YwNMiZiVN8R0rCdv4Bvpk6vBFM+HaGeFZtWayT9XXM+jGLB+1RwZZpdDXFzf2xbYQSwen1wTOaL6PqyRRu5dGB60Fwx5A30I=;20:AcQP2QrNuZ6DuUNZE2s83CHkWJBpjcCJcDyWdwdTOkKvkd40e6Q8JtmOSnU4u+gIDNMN0jhV6GIc9NUP5XeCsbZF4CCuH3tqbL7S3k8kXkL/VhijXGZVmVcQZw2NG3DIMHcwMfbo3VbV/cX4yjw2UhLQCGpfZM59ne1ztfrBblq6SnuEgda602R3SRfTW6chCfQFgtxIySCWPiGJrp6gvh1T3EXh0vN7iabbSz7lu405JDHLp8V3fbR6aZAyfkyeKXu+VW5pLd95fkB+q032k6ppK4+RzXD3J+zSEeoRu4NJ7tci0Xm2Pab8nOfYVxhr0IBPnw33khYscEObcK0vrA== X-Microsoft-Antispam-PRVS: X-Exchange-Antispam-Report-Test: UriScan:(7411616537696); X-Exchange-Antispam-Report-CFA-Test: BCL:0;PCL:0;RULEID:(6040176)(601004)(2401047)(8121501046)(5005006)(10201501046)(3002001);SRVR:AM3PR05MB1396;BCL:0;PCL:0;RULEID:;SRVR:AM3PR05MB1396; X-Microsoft-Exchange-Diagnostics: 1;AM3PR05MB1396;4:OKCmhXbXdySUvGO46Fp8LxBoWHQq7vrnQnD+Yvo3E5Jx4XbJBmaSugsOCLL3RE6oeY+mZfYGig38aJeLYfty1/DdjBg922vmBmQP6Aq/HTsFHqgtFe41MDx3CDqS53g/7BtnofOjv/OqW4ZHMsuoHt2s9+waAgFxu4QvFiYbEwqRoTUR9Jq1yUm/I/0/eWqcPu83A4P2zZPzqk9naIKDWhyg9UcOzWAGFuIt9W2oYklGuIPkovFgOl+Wg7zvWGN9M0RtCIZ+oNIwJADr66NOZ2mqfs5qffxk4FTk62Ou7HC/RZ3dDUfHM7vphy7hh06Ni7m7SSupOtdyErdaypPxl7EarkrFA7A7BBDDCcX9e/r1XvwTJxUvyQYDstxQwqW/i2BKEoQHsj5oeezZPBUL4qK6pblU36UTdLbCPirZ/ZgdetTxJ65LOaT3l0/8x8GG X-Forefront-PRVS: 00826B6158 X-Forefront-Antispam-Report: SFV:NSPM;SFS:(10019020)(4630300001)(6009001)(7916002)(199003)(189002)(7416002)(5820100001)(92566002)(36756003)(47776003)(189998001)(6666003)(305945005)(2870700001)(68736007)(229853001)(5001770100001)(97736004)(66066001)(4326007)(33646002)(105586002)(5660300001)(50226002)(106356001)(8666005)(2906002)(586003)(2950100002)(107886002)(50466002)(1076002)(76176999)(81156014)(50986999)(81166006)(7736002)(6116002)(3846002)(23676002)(42186005)(7846002)(8676002)(53416004)(101416001)(69596002)(86362001)(19580395003)(4001430100002)(19580405001)(7059030);DIR:OUT;SFP:1102;SCL:1;SRVR:AM3PR05MB1396;H:tdx-in-nb-0014.toradex.int;FPR:;SPF:None;PTR:InfoNoRecords;A:1;MX:1;LANG:en; X-Microsoft-Exchange-Diagnostics: =?utf-8?B?MTtBTTNQUjA1TUIxMzk2OzIzOmE0Vm9XeW5hREdoblB6SDZ3TVRMQUI1V2k0?= =?utf-8?B?b0llM0RDeWpkOWdydGlhMjVTQlhQWWVjSGI2TEVuYi9Vc3BNSlYwQi9Takxm?= =?utf-8?B?OUdSVTNnTk4xRlROZU5jb0ljaTE4TndYd2hDVnphUEcyd0FUeVhad1NJNEtw?= =?utf-8?B?cjJOenIxR054RjR0aHpBRFhPcDVDaFRMUmhpZHM3OXZaV09FSkpXSUJIcFZk?= =?utf-8?B?VEl6a1JKVFU5MnA4RGMxMmtPRU5pOCs5bUsvbGVVSWZ0UjJmUHFGM2JOVzBs?= =?utf-8?B?b3YrQjNUcW5BWllPZ0ticU01UC9mVWsxVHIya1dWNmdoZTVMNnA1S1V2dGRH?= =?utf-8?B?VGh5Z0VWV3d0M2xac0pqdzAwV3V3K0xMR0kwU2Z6eEF0blozUmVkYjFDOEVs?= =?utf-8?B?d3hldGNhTTZJVThaYW1QeTU0NTllbUtua1lqRWxIRkhreHdPY0FXOTNLUmQy?= =?utf-8?B?OFVLenJBTU9ERWVnN1laeSs1cms3WjN4YS9nSDg2UWV6NXRRRnBSOVlPL2M2?= =?utf-8?B?clpsMmRKZXo2WTh3a3RxOExWNFh6MDdIQjZWMngzR1lGbGdvdmw0eStqS0R1?= =?utf-8?B?MjY5UU5UNys5Y0xIS0FJcGVCQUFsUWhxOE1aZmw1Z0dMMnNTMVFrUTI1TjBP?= =?utf-8?B?eWZrWW1JSStZWS9WS1l6ak5xNjJybWlPMlFBTXdyaUNpQ1VDMzE2cnRxSVBL?= =?utf-8?B?Yzd4dzFvK2ZYTzZEcFRlTmpta1dacHNCSlJrRDFnMTlWQ0pEYUpBVmc4eXla?= =?utf-8?B?RFIyN01pRTB3WExzdStOT3BJWFUwN1RrV0pCeDNaNmt4NXFZUmxyc0N1TDQy?= =?utf-8?B?S2pmMjhobmg2VjRRRHREdGxLTVV0NFhUaHNtQk5VejlMUllKcjBXWjNGUmRT?= =?utf-8?B?WWNEa082M2FNR1grc1lCeVFMZEVjTGxmM2RxdVM1dVZFcm9Wb0dTMDJqMDcv?= =?utf-8?B?VzVSNmxHSUxBZnI3UkVBOHpmOVUyOGJZTlVrTjg1a1VBWlI1MVM1RXJBNTVz?= =?utf-8?B?bkF1VG1DaGhIZC9QODh5aDlZMFlJSHljWlA2V1dLOExueWxsUWVmU3VvdmFR?= =?utf-8?B?Z3hyZ3N3S095TTRsUkJpWUZmdUo0WVNCWkVyMjRjbDJDK2VDUE5uMTBkR0ZL?= =?utf-8?B?YmlmU29rTjhlaVN5YWw4NlpjSmxzU0dvMTdjTWhvNTg4R1hGdjkyL3d5MUgv?= =?utf-8?B?NjJVZHFDOHZqbTBpTWVDYW5YUXJsK1d5NmdSUGpDblk5b0tFa3E0STdhNE1O?= =?utf-8?B?OTJkQThZMy96V3VaTWsxUXI1VGpya1NORy9ja1hRUlRXRHEzMnc2RzNzaEpO?= =?utf-8?B?cEZhNFRPQ2NEWTFidytnTWlQamtDYWUzcVdHNGNlSlpMcTNKYVZHbXZ1djZy?= =?utf-8?B?TFZ2Y2Nlc2F4M3ZYV0FSaXh6OHdBS3Vqd05HKzF6WVo5Z3hrazFYM1F0SGpS?= =?utf-8?B?b1V2cUV3RFczQ3I3ZkF3ZkQ2S0lwc0pJMHBSUHpyaSt4MGZxUHYzSk13Rk1K?= =?utf-8?B?RXhyRXdtRlJhKzAzTGNGbkczSkhRTGk1d1FkOUtmSW0yTmQrQXVodDFjSUpL?= =?utf-8?B?L1A0MDVqVEZkZlc3Y2N4alFwWmp2YVJEQ2doNTZuNGxhbnVMQjV1ditGMjI4?= =?utf-8?B?TXR2U29ZRGVleWJOdWtkajZ6NEtGVkJoRlhtVnRrTVlTQ1F1eUY4UVRYRS8w?= =?utf-8?Q?YWixZukRnuBnswnvbzWGYjhjbNQGN8y/ZX6xP/7?= X-Microsoft-Exchange-Diagnostics: 1;AM3PR05MB1396;6:6V2cJlMzICf4rqe1SftIwmroUoqlsy3IHnAxVlOmXz+2Cm7vwXHF9sU2LKh4vxIQThx07CzULdPMPIQh1CD0fjNs7HIqe+v9HirOYqQ2S7wNvsGzN/oE1UKdTKuBcRifZ4DbK+Av5k+4x6SpMBT+edeOr3q7zy4K1V+dhk6sBEDFa8fY+0lX88Z+nqJbU/zoGE4fvpn6ZiMGqJB5pK0aecYCRVkstzgnougdGW8P4z5WVT4Fp7vVJYMAZT6+MR4rzIlhaAh3Ng5+HUjAkVO6DwnMhnIjh6ZW+Bd47M2wfuE=;5:Tnzo7/O401J665dwMxB2lo0OBuh6Cjzyspv+rBjpOw7Ru7uRBDUXSIx9r4mKXtrHDZNnP+NXp2mbfd9Pt8DZxR9YoBp2gMPe5ywQ7lqWqNF716KZ5xP7zuWMjpqO7vNBbiYzP2sveHbP0tWvtGWMFQ==;24:CMKgj4kUEXswHlA4/uuBnybGsBnftFFjUeL98L7giLT7JiQj8SsW87TcaFEjG3nVRmUNBuyW5BUWcx9qVZb9u7TTpHGZzzqMrCT9eUaVVeE=;7:hUHmCg+2Iiad5qbUsnLbqB2R66onrP+0HtY8LmDgBT5rshJRM0mpAIXcp57+5BdY5eB6M3p0AAukNlxx0LC1sd85qWeF6CCsLfX7ztffiGmRfu8goLPohv1z1mlTblV6bDJSZoofKBZ8jsBhrZcdygcVbiC8q6UnkN8h7gIlI0pca4QzzItE1aatiKi79zEgDrfU9UFG1Me9WiH5HpOdegu2SaPbEY9ya+Mrm/FVqfKrHZamgTCy7dJ91XHczHvW02ie61ervnme7LnaG6tW+UBEuVjSDYZwPD+4u7HYM72D11gw90lh2O3vPB6oonrB SpamDiagnosticOutput: 1:99 SpamDiagnosticMetadata: NSPM X-OriginatorOrg: toradex.com X-MS-Exchange-CrossTenant-OriginalArrivalTime: 01 Oct 2016 10:14:56.8122 (UTC) X-MS-Exchange-CrossTenant-FromEntityHeader: Hosted X-MS-Exchange-Transport-CrossTenantHeadersStamped: AM3PR05MB1396 Sender: linux-kernel-owner@vger.kernel.org List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Length: 5140 Lines: 161 From: Lothar Wassmann 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 Signed-off-by: Lukasz Majewski Signed-off-by: Bhuvanchandra DV Acked-by: Shawn Guo Reviewed-by: Sascha Hauer --- Documentation/devicetree/bindings/pwm/imx-pwm.txt | 6 +-- drivers/pwm/pwm-imx.c | 51 +++++++++++++++++++++-- 2 files changed, 51 insertions(+), 6 deletions(-) diff --git a/Documentation/devicetree/bindings/pwm/imx-pwm.txt b/Documentation/devicetree/bindings/pwm/imx-pwm.txt index e00c2e9..c61bdf8 100644 --- a/Documentation/devicetree/bindings/pwm/imx-pwm.txt +++ b/Documentation/devicetree/bindings/pwm/imx-pwm.txt @@ -6,8 +6,8 @@ Required properties: - "fsl,imx1-pwm" for PWM compatible with the one integrated on i.MX1 - "fsl,imx27-pwm" for PWM compatible with the one integrated on i.MX27 - reg: physical base address and length of the controller's registers -- #pwm-cells: should be 2. See pwm.txt in this directory for a description of - the cells format. +- #pwm-cells: 2 for i.MX1 and 3 for i.MX27 and newer SoCs. See pwm.txt + in this directory for a description of the cells format. - clocks : Clock specifiers for both ipg and per clocks. - clock-names : Clock names should include both "ipg" and "per" See the clock consumer binding, @@ -17,7 +17,7 @@ See the clock consumer binding, Example: pwm1: pwm@53fb4000 { - #pwm-cells = <2>; + #pwm-cells = <3>; compatible = "fsl,imx53-pwm", "fsl,imx27-pwm"; reg = <0x53fb4000 0x4000>; clocks = <&clks IMX5_CLK_PWM1_IPG_GATE>, diff --git a/drivers/pwm/pwm-imx.c b/drivers/pwm/pwm-imx.c index d600fd5..c37d223 100644 --- a/drivers/pwm/pwm-imx.c +++ b/drivers/pwm/pwm-imx.c @@ -38,6 +38,7 @@ #define MX3_PWMCR_DOZEEN (1 << 24) #define MX3_PWMCR_WAITEN (1 << 23) #define MX3_PWMCR_DBGEN (1 << 22) +#define MX3_PWMCR_POUTC (1 << 18) #define MX3_PWMCR_CLKSRC_IPG_HIGH (2 << 16) #define MX3_PWMCR_CLKSRC_IPG (1 << 16) #define MX3_PWMCR_SWR (1 << 3) @@ -180,6 +181,9 @@ static int imx_pwm_config_v2(struct pwm_chip *chip, if (enable) cr |= MX3_PWMCR_EN; + if (pwm->args.polarity == PWM_POLARITY_INVERSED) + cr |= MX3_PWMCR_POUTC; + writel(cr, imx->mmio_base + MX3_PWMCR); return 0; @@ -240,27 +244,62 @@ 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); + u32 val; + + if (polarity == pwm->args.polarity) + return 0; + + val = readl(imx->mmio_base + MX3_PWMCR); + + if (polarity == PWM_POLARITY_INVERSED) + val |= MX3_PWMCR_POUTC; + else + val &= ~MX3_PWMCR_POUTC; + + writel(val, imx->mmio_base + MX3_PWMCR); + + 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[] = { @@ -282,6 +321,8 @@ static int imx_pwm_probe(struct platform_device *pdev) if (!of_id) return -ENODEV; + data = of_id->data; + imx = devm_kzalloc(&pdev->dev, sizeof(*imx), GFP_KERNEL); if (imx == NULL) return -ENOMEM; @@ -300,18 +341,22 @@ 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; imx->chip.can_sleep = true; + if (data->pwm_ops->set_polarity) { + dev_dbg(&pdev->dev, "PWM supports output inversion\n"); + imx->chip.of_xlate = of_pwm_xlate_with_flags; + imx->chip.of_pwm_n_cells = 3; + } r = platform_get_resource(pdev, IORESOURCE_MEM, 0); imx->mmio_base = devm_ioremap_resource(&pdev->dev, r); 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; -- 2.9.2