aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Documentation/devicetree/bindings/pwm/pwm-meson.txt23
-rw-r--r--Documentation/devicetree/bindings/pwm/pwm-mtk-disp.txt3
-rw-r--r--Documentation/devicetree/bindings/pwm/pwm-st.txt8
-rw-r--r--Documentation/devicetree/bindings/pwm/pwm-sun4i.txt1
-rw-r--r--drivers/pwm/Kconfig9
-rw-r--r--drivers/pwm/Makefile1
-rw-r--r--drivers/pwm/core.c2
-rw-r--r--drivers/pwm/pwm-berlin.c84
-rw-r--r--drivers/pwm/pwm-cros-ec.c4
-rw-r--r--drivers/pwm/pwm-lpc18xx-sct.c12
-rw-r--r--drivers/pwm/pwm-meson.c529
-rw-r--r--drivers/pwm/pwm-mtk-disp.c87
-rw-r--r--drivers/pwm/pwm-samsung.c15
-rw-r--r--drivers/pwm/pwm-sti.c483
-rw-r--r--drivers/pwm/pwm-sun4i.c9
-rw-r--r--drivers/pwm/pwm-tipwmss.c19
-rw-r--r--drivers/pwm/pwm-twl.c16
-rw-r--r--drivers/pwm/sysfs.c18
-rw-r--r--include/linux/pwm.h5
19 files changed, 1183 insertions, 145 deletions
diff --git a/Documentation/devicetree/bindings/pwm/pwm-meson.txt b/Documentation/devicetree/bindings/pwm/pwm-meson.txt
new file mode 100644
index 000000000000..5376a4468cb6
--- /dev/null
+++ b/Documentation/devicetree/bindings/pwm/pwm-meson.txt
@@ -0,0 +1,23 @@
1Amlogic Meson PWM Controller
2============================
3
4Required properties:
5- compatible: Shall contain "amlogic,meson8b-pwm" or "amlogic,meson-gxbb-pwm".
6- #pwm-cells: Should be 3. See pwm.txt in this directory for a description of
7 the cells format.
8
9Optional properties:
10- clocks: Could contain one or two parents clocks phandle for each of the two
11 PWM channels.
12- clock-names: Could contain at least the "clkin0" and/or "clkin1" names.
13
14Example:
15
16 pwm_ab: pwm@8550 {
17 compatible = "amlogic,meson-gxbb-pwm";
18 reg = <0x0 0x08550 0x0 0x10>;
19 #pwm-cells = <3>;
20 status = "disabled";
21 clocks = <&xtal>, <&xtal>;
22 clock-names = "clkin0", "clkin1";
23 }
diff --git a/Documentation/devicetree/bindings/pwm/pwm-mtk-disp.txt b/Documentation/devicetree/bindings/pwm/pwm-mtk-disp.txt
index f8f59baf6b67..6f8af2bcc7b7 100644
--- a/Documentation/devicetree/bindings/pwm/pwm-mtk-disp.txt
+++ b/Documentation/devicetree/bindings/pwm/pwm-mtk-disp.txt
@@ -2,8 +2,9 @@ MediaTek display PWM controller
2 2
3Required properties: 3Required properties:
4 - compatible: should be "mediatek,<name>-disp-pwm": 4 - compatible: should be "mediatek,<name>-disp-pwm":
5 - "mediatek,mt8173-disp-pwm": found on mt8173 SoC. 5 - "mediatek,mt2701-disp-pwm": found on mt2701 SoC.
6 - "mediatek,mt6595-disp-pwm": found on mt6595 SoC. 6 - "mediatek,mt6595-disp-pwm": found on mt6595 SoC.
7 - "mediatek,mt8173-disp-pwm": found on mt8173 SoC.
7 - reg: physical base address and length of the controller's registers. 8 - reg: physical base address and length of the controller's registers.
8 - #pwm-cells: must be 2. See pwm.txt in this directory for a description of 9 - #pwm-cells: must be 2. See pwm.txt in this directory for a description of
9 the cell format. 10 the cell format.
diff --git a/Documentation/devicetree/bindings/pwm/pwm-st.txt b/Documentation/devicetree/bindings/pwm/pwm-st.txt
index 84d2fb807d3c..19fce774cafa 100644
--- a/Documentation/devicetree/bindings/pwm/pwm-st.txt
+++ b/Documentation/devicetree/bindings/pwm/pwm-st.txt
@@ -13,13 +13,14 @@ Required parameters:
13- pinctrl-0: List of phandles pointing to pin configuration nodes 13- pinctrl-0: List of phandles pointing to pin configuration nodes
14 for PWM module. 14 for PWM module.
15 For Pinctrl properties, please refer to [1]. 15 For Pinctrl properties, please refer to [1].
16- clock-names: Set to "pwm". 16- clock-names: Valid entries are "pwm" and/or "capture".
17- clocks: phandle of the clock used by the PWM module. 17- clocks: phandle of the clock used by the PWM module.
18 For Clk properties, please refer to [2]. 18 For Clk properties, please refer to [2].
19- interrupts: IRQ for the Capture device
19 20
20Optional properties: 21Optional properties:
21- st,pwm-num-chan: Number of available channels. If not passed, the driver 22- st,pwm-num-chan: Number of available PWM channels. Default is 0.
22 will consider single channel by default. 23- st,capture-num-chan: Number of available Capture channels. Default is 0.
23 24
24[1] Documentation/devicetree/bindings/pinctrl/pinctrl-bindings.txt 25[1] Documentation/devicetree/bindings/pinctrl/pinctrl-bindings.txt
25[2] Documentation/devicetree/bindings/clock/clock-bindings.txt 26[2] Documentation/devicetree/bindings/clock/clock-bindings.txt
@@ -38,4 +39,5 @@ pwm1: pwm@fe510000 {
38 clocks = <&clk_sysin>; 39 clocks = <&clk_sysin>;
39 clock-names = "pwm"; 40 clock-names = "pwm";
40 st,pwm-num-chan = <4>; 41 st,pwm-num-chan = <4>;
42 st,capture-num-chan = <2>;
41}; 43};
diff --git a/Documentation/devicetree/bindings/pwm/pwm-sun4i.txt b/Documentation/devicetree/bindings/pwm/pwm-sun4i.txt
index cf6068b8e974..f1cbeefb3087 100644
--- a/Documentation/devicetree/bindings/pwm/pwm-sun4i.txt
+++ b/Documentation/devicetree/bindings/pwm/pwm-sun4i.txt
@@ -6,6 +6,7 @@ Required properties:
6 - "allwinner,sun5i-a10s-pwm" 6 - "allwinner,sun5i-a10s-pwm"
7 - "allwinner,sun5i-a13-pwm" 7 - "allwinner,sun5i-a13-pwm"
8 - "allwinner,sun7i-a20-pwm" 8 - "allwinner,sun7i-a20-pwm"
9 - "allwinner,sun8i-h3-pwm"
9 - reg: physical base address and length of the controller's registers 10 - reg: physical base address and length of the controller's registers
10 - #pwm-cells: should be 3. See pwm.txt in this directory for a description of 11 - #pwm-cells: should be 3. See pwm.txt in this directory for a description of
11 the cells format. 12 the cells format.
diff --git a/drivers/pwm/Kconfig b/drivers/pwm/Kconfig
index 80a566a00d04..bf0128899c09 100644
--- a/drivers/pwm/Kconfig
+++ b/drivers/pwm/Kconfig
@@ -262,6 +262,15 @@ config PWM_LPSS_PLATFORM
262 To compile this driver as a module, choose M here: the module 262 To compile this driver as a module, choose M here: the module
263 will be called pwm-lpss-platform. 263 will be called pwm-lpss-platform.
264 264
265config PWM_MESON
266 tristate "Amlogic Meson PWM driver"
267 depends on ARCH_MESON
268 help
269 The platform driver for Amlogic Meson PWM controller.
270
271 To compile this driver as a module, choose M here: the module
272 will be called pwm-meson.
273
265config PWM_MTK_DISP 274config PWM_MTK_DISP
266 tristate "MediaTek display PWM driver" 275 tristate "MediaTek display PWM driver"
267 depends on ARCH_MEDIATEK || COMPILE_TEST 276 depends on ARCH_MEDIATEK || COMPILE_TEST
diff --git a/drivers/pwm/Makefile b/drivers/pwm/Makefile
index feef1dd29f73..1194c54efcc2 100644
--- a/drivers/pwm/Makefile
+++ b/drivers/pwm/Makefile
@@ -24,6 +24,7 @@ obj-$(CONFIG_PWM_LPC32XX) += pwm-lpc32xx.o
24obj-$(CONFIG_PWM_LPSS) += pwm-lpss.o 24obj-$(CONFIG_PWM_LPSS) += pwm-lpss.o
25obj-$(CONFIG_PWM_LPSS_PCI) += pwm-lpss-pci.o 25obj-$(CONFIG_PWM_LPSS_PCI) += pwm-lpss-pci.o
26obj-$(CONFIG_PWM_LPSS_PLATFORM) += pwm-lpss-platform.o 26obj-$(CONFIG_PWM_LPSS_PLATFORM) += pwm-lpss-platform.o
27obj-$(CONFIG_PWM_MESON) += pwm-meson.o
27obj-$(CONFIG_PWM_MTK_DISP) += pwm-mtk-disp.o 28obj-$(CONFIG_PWM_MTK_DISP) += pwm-mtk-disp.o
28obj-$(CONFIG_PWM_MXS) += pwm-mxs.o 29obj-$(CONFIG_PWM_MXS) += pwm-mxs.o
29obj-$(CONFIG_PWM_OMAP_DMTIMER) += pwm-omap-dmtimer.o 30obj-$(CONFIG_PWM_OMAP_DMTIMER) += pwm-omap-dmtimer.o
diff --git a/drivers/pwm/core.c b/drivers/pwm/core.c
index 0dbd29e287db..172ef8245811 100644
--- a/drivers/pwm/core.c
+++ b/drivers/pwm/core.c
@@ -339,6 +339,8 @@ int pwmchip_remove(struct pwm_chip *chip)
339 unsigned int i; 339 unsigned int i;
340 int ret = 0; 340 int ret = 0;
341 341
342 pwmchip_sysfs_unexport_children(chip);
343
342 mutex_lock(&pwm_lock); 344 mutex_lock(&pwm_lock);
343 345
344 for (i = 0; i < chip->npwm; i++) { 346 for (i = 0; i < chip->npwm; i++) {
diff --git a/drivers/pwm/pwm-berlin.c b/drivers/pwm/pwm-berlin.c
index 65108129d505..01339c152ab0 100644
--- a/drivers/pwm/pwm-berlin.c
+++ b/drivers/pwm/pwm-berlin.c
@@ -16,6 +16,7 @@
16#include <linux/module.h> 16#include <linux/module.h>
17#include <linux/platform_device.h> 17#include <linux/platform_device.h>
18#include <linux/pwm.h> 18#include <linux/pwm.h>
19#include <linux/slab.h>
19 20
20#define BERLIN_PWM_EN 0x0 21#define BERLIN_PWM_EN 0x0
21#define BERLIN_PWM_ENABLE BIT(0) 22#define BERLIN_PWM_ENABLE BIT(0)
@@ -27,6 +28,13 @@
27#define BERLIN_PWM_TCNT 0xc 28#define BERLIN_PWM_TCNT 0xc
28#define BERLIN_PWM_MAX_TCNT 65535 29#define BERLIN_PWM_MAX_TCNT 65535
29 30
31struct berlin_pwm_channel {
32 u32 enable;
33 u32 ctrl;
34 u32 duty;
35 u32 tcnt;
36};
37
30struct berlin_pwm_chip { 38struct berlin_pwm_chip {
31 struct pwm_chip chip; 39 struct pwm_chip chip;
32 struct clk *clk; 40 struct clk *clk;
@@ -55,6 +63,25 @@ static inline void berlin_pwm_writel(struct berlin_pwm_chip *chip,
55 writel_relaxed(value, chip->base + channel * 0x10 + offset); 63 writel_relaxed(value, chip->base + channel * 0x10 + offset);
56} 64}
57 65
66static int berlin_pwm_request(struct pwm_chip *chip, struct pwm_device *pwm)
67{
68 struct berlin_pwm_channel *channel;
69
70 channel = kzalloc(sizeof(*channel), GFP_KERNEL);
71 if (!channel)
72 return -ENOMEM;
73
74 return pwm_set_chip_data(pwm, channel);
75}
76
77static void berlin_pwm_free(struct pwm_chip *chip, struct pwm_device *pwm)
78{
79 struct berlin_pwm_channel *channel = pwm_get_chip_data(pwm);
80
81 pwm_set_chip_data(pwm, NULL);
82 kfree(channel);
83}
84
58static int berlin_pwm_config(struct pwm_chip *chip, struct pwm_device *pwm_dev, 85static int berlin_pwm_config(struct pwm_chip *chip, struct pwm_device *pwm_dev,
59 int duty_ns, int period_ns) 86 int duty_ns, int period_ns)
60{ 87{
@@ -137,6 +164,8 @@ static void berlin_pwm_disable(struct pwm_chip *chip,
137} 164}
138 165
139static const struct pwm_ops berlin_pwm_ops = { 166static const struct pwm_ops berlin_pwm_ops = {
167 .request = berlin_pwm_request,
168 .free = berlin_pwm_free,
140 .config = berlin_pwm_config, 169 .config = berlin_pwm_config,
141 .set_polarity = berlin_pwm_set_polarity, 170 .set_polarity = berlin_pwm_set_polarity,
142 .enable = berlin_pwm_enable, 171 .enable = berlin_pwm_enable,
@@ -204,12 +233,67 @@ static int berlin_pwm_remove(struct platform_device *pdev)
204 return ret; 233 return ret;
205} 234}
206 235
236#ifdef CONFIG_PM_SLEEP
237static int berlin_pwm_suspend(struct device *dev)
238{
239 struct berlin_pwm_chip *pwm = dev_get_drvdata(dev);
240 unsigned int i;
241
242 for (i = 0; i < pwm->chip.npwm; i++) {
243 struct berlin_pwm_channel *channel;
244
245 channel = pwm_get_chip_data(&pwm->chip.pwms[i]);
246 if (!channel)
247 continue;
248
249 channel->enable = berlin_pwm_readl(pwm, i, BERLIN_PWM_ENABLE);
250 channel->ctrl = berlin_pwm_readl(pwm, i, BERLIN_PWM_CONTROL);
251 channel->duty = berlin_pwm_readl(pwm, i, BERLIN_PWM_DUTY);
252 channel->tcnt = berlin_pwm_readl(pwm, i, BERLIN_PWM_TCNT);
253 }
254
255 clk_disable_unprepare(pwm->clk);
256
257 return 0;
258}
259
260static int berlin_pwm_resume(struct device *dev)
261{
262 struct berlin_pwm_chip *pwm = dev_get_drvdata(dev);
263 unsigned int i;
264 int ret;
265
266 ret = clk_prepare_enable(pwm->clk);
267 if (ret)
268 return ret;
269
270 for (i = 0; i < pwm->chip.npwm; i++) {
271 struct berlin_pwm_channel *channel;
272
273 channel = pwm_get_chip_data(&pwm->chip.pwms[i]);
274 if (!channel)
275 continue;
276
277 berlin_pwm_writel(pwm, i, channel->ctrl, BERLIN_PWM_CONTROL);
278 berlin_pwm_writel(pwm, i, channel->duty, BERLIN_PWM_DUTY);
279 berlin_pwm_writel(pwm, i, channel->tcnt, BERLIN_PWM_TCNT);
280 berlin_pwm_writel(pwm, i, channel->enable, BERLIN_PWM_ENABLE);
281 }
282
283 return 0;
284}
285#endif
286
287static SIMPLE_DEV_PM_OPS(berlin_pwm_pm_ops, berlin_pwm_suspend,
288 berlin_pwm_resume);
289
207static struct platform_driver berlin_pwm_driver = { 290static struct platform_driver berlin_pwm_driver = {
208 .probe = berlin_pwm_probe, 291 .probe = berlin_pwm_probe,
209 .remove = berlin_pwm_remove, 292 .remove = berlin_pwm_remove,
210 .driver = { 293 .driver = {
211 .name = "berlin-pwm", 294 .name = "berlin-pwm",
212 .of_match_table = berlin_pwm_match, 295 .of_match_table = berlin_pwm_match,
296 .pm = &berlin_pwm_pm_ops,
213 }, 297 },
214}; 298};
215module_platform_driver(berlin_pwm_driver); 299module_platform_driver(berlin_pwm_driver);
diff --git a/drivers/pwm/pwm-cros-ec.c b/drivers/pwm/pwm-cros-ec.c
index 99b9acc1a420..f6ca4e8c6253 100644
--- a/drivers/pwm/pwm-cros-ec.c
+++ b/drivers/pwm/pwm-cros-ec.c
@@ -38,7 +38,7 @@ static int cros_ec_pwm_set_duty(struct cros_ec_device *ec, u8 index, u16 duty)
38 struct { 38 struct {
39 struct cros_ec_command msg; 39 struct cros_ec_command msg;
40 struct ec_params_pwm_set_duty params; 40 struct ec_params_pwm_set_duty params;
41 } buf; 41 } __packed buf;
42 struct ec_params_pwm_set_duty *params = &buf.params; 42 struct ec_params_pwm_set_duty *params = &buf.params;
43 struct cros_ec_command *msg = &buf.msg; 43 struct cros_ec_command *msg = &buf.msg;
44 44
@@ -65,7 +65,7 @@ static int __cros_ec_pwm_get_duty(struct cros_ec_device *ec, u8 index,
65 struct ec_params_pwm_get_duty params; 65 struct ec_params_pwm_get_duty params;
66 struct ec_response_pwm_get_duty resp; 66 struct ec_response_pwm_get_duty resp;
67 }; 67 };
68 } buf; 68 } __packed buf;
69 struct ec_params_pwm_get_duty *params = &buf.params; 69 struct ec_params_pwm_get_duty *params = &buf.params;
70 struct ec_response_pwm_get_duty *resp = &buf.resp; 70 struct ec_response_pwm_get_duty *resp = &buf.resp;
71 struct cros_ec_command *msg = &buf.msg; 71 struct cros_ec_command *msg = &buf.msg;
diff --git a/drivers/pwm/pwm-lpc18xx-sct.c b/drivers/pwm/pwm-lpc18xx-sct.c
index 19dc64cab2f0..d7f5f7de030d 100644
--- a/drivers/pwm/pwm-lpc18xx-sct.c
+++ b/drivers/pwm/pwm-lpc18xx-sct.c
@@ -413,14 +413,18 @@ static int lpc18xx_pwm_probe(struct platform_device *pdev)
413 } 413 }
414 414
415 for (i = 0; i < lpc18xx_pwm->chip.npwm; i++) { 415 for (i = 0; i < lpc18xx_pwm->chip.npwm; i++) {
416 struct lpc18xx_pwm_data *data;
417
416 pwm = &lpc18xx_pwm->chip.pwms[i]; 418 pwm = &lpc18xx_pwm->chip.pwms[i];
417 pwm->chip_data = devm_kzalloc(lpc18xx_pwm->dev, 419
418 sizeof(struct lpc18xx_pwm_data), 420 data = devm_kzalloc(lpc18xx_pwm->dev, sizeof(*data),
419 GFP_KERNEL); 421 GFP_KERNEL);
420 if (!pwm->chip_data) { 422 if (!data) {
421 ret = -ENOMEM; 423 ret = -ENOMEM;
422 goto remove_pwmchip; 424 goto remove_pwmchip;
423 } 425 }
426
427 pwm_set_chip_data(pwm, data);
424 } 428 }
425 429
426 platform_set_drvdata(pdev, lpc18xx_pwm); 430 platform_set_drvdata(pdev, lpc18xx_pwm);
diff --git a/drivers/pwm/pwm-meson.c b/drivers/pwm/pwm-meson.c
new file mode 100644
index 000000000000..381871b2bb46
--- /dev/null
+++ b/drivers/pwm/pwm-meson.c
@@ -0,0 +1,529 @@
1/*
2 * This file is provided under a dual BSD/GPLv2 license. When using or
3 * redistributing this file, you may do so under either license.
4 *
5 * GPL LICENSE SUMMARY
6 *
7 * Copyright (c) 2016 BayLibre, SAS.
8 * Author: Neil Armstrong <narmstrong@baylibre.com>
9 * Copyright (C) 2014 Amlogic, Inc.
10 *
11 * This program is free software; you can redistribute it and/or modify
12 * it under the terms of version 2 of the GNU General Public License as
13 * published by the Free Software Foundation.
14 *
15 * This program is distributed in the hope that it will be useful, but
16 * WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
18 * General Public License for more details.
19 *
20 * You should have received a copy of the GNU General Public License
21 * along with this program; if not, see <http://www.gnu.org/licenses/>.
22 * The full GNU General Public License is included in this distribution
23 * in the file called COPYING.
24 *
25 * BSD LICENSE
26 *
27 * Copyright (c) 2016 BayLibre, SAS.
28 * Author: Neil Armstrong <narmstrong@baylibre.com>
29 * Copyright (C) 2014 Amlogic, Inc.
30 *
31 * Redistribution and use in source and binary forms, with or without
32 * modification, are permitted provided that the following conditions
33 * are met:
34 *
35 * * Redistributions of source code must retain the above copyright
36 * notice, this list of conditions and the following disclaimer.
37 * * Redistributions in binary form must reproduce the above copyright
38 * notice, this list of conditions and the following disclaimer in
39 * the documentation and/or other materials provided with the
40 * distribution.
41 * * Neither the name of Intel Corporation nor the names of its
42 * contributors may be used to endorse or promote products derived
43 * from this software without specific prior written permission.
44 *
45 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
46 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
47 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
48 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
49 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
50 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
51 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
52 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
53 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
54 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
55 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
56 */
57
58#include <linux/clk.h>
59#include <linux/clk-provider.h>
60#include <linux/err.h>
61#include <linux/io.h>
62#include <linux/kernel.h>
63#include <linux/module.h>
64#include <linux/of.h>
65#include <linux/of_device.h>
66#include <linux/platform_device.h>
67#include <linux/pwm.h>
68#include <linux/slab.h>
69#include <linux/spinlock.h>
70
71#define REG_PWM_A 0x0
72#define REG_PWM_B 0x4
73#define PWM_HIGH_SHIFT 16
74
75#define REG_MISC_AB 0x8
76#define MISC_B_CLK_EN BIT(23)
77#define MISC_A_CLK_EN BIT(15)
78#define MISC_CLK_DIV_MASK 0x7f
79#define MISC_B_CLK_DIV_SHIFT 16
80#define MISC_A_CLK_DIV_SHIFT 8
81#define MISC_B_CLK_SEL_SHIFT 6
82#define MISC_A_CLK_SEL_SHIFT 4
83#define MISC_CLK_SEL_WIDTH 2
84#define MISC_B_EN BIT(1)
85#define MISC_A_EN BIT(0)
86
87static const unsigned int mux_reg_shifts[] = {
88 MISC_A_CLK_SEL_SHIFT,
89 MISC_B_CLK_SEL_SHIFT
90};
91
92struct meson_pwm_channel {
93 unsigned int hi;
94 unsigned int lo;
95 u8 pre_div;
96
97 struct pwm_state state;
98
99 struct clk *clk_parent;
100 struct clk_mux mux;
101 struct clk *clk;
102};
103
104struct meson_pwm_data {
105 const char * const *parent_names;
106};
107
108struct meson_pwm {
109 struct pwm_chip chip;
110 const struct meson_pwm_data *data;
111 void __iomem *base;
112 u8 inverter_mask;
113 spinlock_t lock;
114};
115
116static inline struct meson_pwm *to_meson_pwm(struct pwm_chip *chip)
117{
118 return container_of(chip, struct meson_pwm, chip);
119}
120
121static int meson_pwm_request(struct pwm_chip *chip, struct pwm_device *pwm)
122{
123 struct meson_pwm_channel *channel = pwm_get_chip_data(pwm);
124 struct device *dev = chip->dev;
125 int err;
126
127 if (!channel)
128 return -ENODEV;
129
130 if (channel->clk_parent) {
131 err = clk_set_parent(channel->clk, channel->clk_parent);
132 if (err < 0) {
133 dev_err(dev, "failed to set parent %s for %s: %d\n",
134 __clk_get_name(channel->clk_parent),
135 __clk_get_name(channel->clk), err);
136 return err;
137 }
138 }
139
140 err = clk_prepare_enable(channel->clk);
141 if (err < 0) {
142 dev_err(dev, "failed to enable clock %s: %d\n",
143 __clk_get_name(channel->clk), err);
144 return err;
145 }
146
147 chip->ops->get_state(chip, pwm, &channel->state);
148
149 return 0;
150}
151
152static void meson_pwm_free(struct pwm_chip *chip, struct pwm_device *pwm)
153{
154 struct meson_pwm_channel *channel = pwm_get_chip_data(pwm);
155
156 if (channel)
157 clk_disable_unprepare(channel->clk);
158}
159
160static int meson_pwm_calc(struct meson_pwm *meson,
161 struct meson_pwm_channel *channel, unsigned int id,
162 unsigned int duty, unsigned int period)
163{
164 unsigned int pre_div, cnt, duty_cnt;
165 unsigned long fin_freq = -1, fin_ns;
166
167 if (~(meson->inverter_mask >> id) & 0x1)
168 duty = period - duty;
169
170 if (period == channel->state.period &&
171 duty == channel->state.duty_cycle)
172 return 0;
173
174 fin_freq = clk_get_rate(channel->clk);
175 if (fin_freq == 0) {
176 dev_err(meson->chip.dev, "invalid source clock frequency\n");
177 return -EINVAL;
178 }
179
180 dev_dbg(meson->chip.dev, "fin_freq: %lu Hz\n", fin_freq);
181 fin_ns = NSEC_PER_SEC / fin_freq;
182
183 /* Calc pre_div with the period */
184 for (pre_div = 0; pre_div < MISC_CLK_DIV_MASK; pre_div++) {
185 cnt = DIV_ROUND_CLOSEST(period, fin_ns * (pre_div + 1));
186 dev_dbg(meson->chip.dev, "fin_ns=%lu pre_div=%u cnt=%u\n",
187 fin_ns, pre_div, cnt);
188 if (cnt <= 0xffff)
189 break;
190 }
191
192 if (pre_div == MISC_CLK_DIV_MASK) {
193 dev_err(meson->chip.dev, "unable to get period pre_div\n");
194 return -EINVAL;
195 }
196
197 dev_dbg(meson->chip.dev, "period=%u pre_div=%u cnt=%u\n", period,
198 pre_div, cnt);
199
200 if (duty == period) {
201 channel->pre_div = pre_div;
202 channel->hi = cnt;
203 channel->lo = 0;
204 } else if (duty == 0) {
205 channel->pre_div = pre_div;
206 channel->hi = 0;
207 channel->lo = cnt;
208 } else {
209 /* Then check is we can have the duty with the same pre_div */
210 duty_cnt = DIV_ROUND_CLOSEST(duty, fin_ns * (pre_div + 1));
211 if (duty_cnt > 0xffff) {
212 dev_err(meson->chip.dev, "unable to get duty cycle\n");
213 return -EINVAL;
214 }
215
216 dev_dbg(meson->chip.dev, "duty=%u pre_div=%u duty_cnt=%u\n",
217 duty, pre_div, duty_cnt);
218
219 channel->pre_div = pre_div;
220 channel->hi = duty_cnt;
221 channel->lo = cnt - duty_cnt;
222 }
223
224 return 0;
225}
226
227static void meson_pwm_enable(struct meson_pwm *meson,
228 struct meson_pwm_channel *channel,
229 unsigned int id)
230{
231 u32 value, clk_shift, clk_enable, enable;
232 unsigned int offset;
233
234 switch (id) {
235 case 0:
236 clk_shift = MISC_A_CLK_DIV_SHIFT;
237 clk_enable = MISC_A_CLK_EN;
238 enable = MISC_A_EN;
239 offset = REG_PWM_A;
240 break;
241
242 case 1:
243 clk_shift = MISC_B_CLK_DIV_SHIFT;
244 clk_enable = MISC_B_CLK_EN;
245 enable = MISC_B_EN;
246 offset = REG_PWM_B;
247 break;
248
249 default:
250 return;
251 }
252
253 value = readl(meson->base + REG_MISC_AB);
254 value &= ~(MISC_CLK_DIV_MASK << clk_shift);
255 value |= channel->pre_div << clk_shift;
256 value |= clk_enable;
257 writel(value, meson->base + REG_MISC_AB);
258
259 value = (channel->hi << PWM_HIGH_SHIFT) | channel->lo;
260 writel(value, meson->base + offset);
261
262 value = readl(meson->base + REG_MISC_AB);
263 value |= enable;
264 writel(value, meson->base + REG_MISC_AB);
265}
266
267static void meson_pwm_disable(struct meson_pwm *meson, unsigned int id)
268{
269 u32 value, enable;
270
271 switch (id) {
272 case 0:
273 enable = MISC_A_EN;
274 break;
275
276 case 1:
277 enable = MISC_B_EN;
278 break;
279
280 default:
281 return;
282 }
283
284 value = readl(meson->base + REG_MISC_AB);
285 value &= ~enable;
286 writel(value, meson->base + REG_MISC_AB);
287}
288
289static int meson_pwm_apply(struct pwm_chip *chip, struct pwm_device *pwm,
290 struct pwm_state *state)
291{
292 struct meson_pwm_channel *channel = pwm_get_chip_data(pwm);
293 struct meson_pwm *meson = to_meson_pwm(chip);
294 unsigned long flags;
295 int err = 0;
296
297 if (!state)
298 return -EINVAL;
299
300 spin_lock_irqsave(&meson->lock, flags);
301
302 if (!state->enabled) {
303 meson_pwm_disable(meson, pwm->hwpwm);
304 channel->state.enabled = false;
305
306 goto unlock;
307 }
308
309 if (state->period != channel->state.period ||
310 state->duty_cycle != channel->state.duty_cycle ||
311 state->polarity != channel->state.polarity) {
312 if (channel->state.enabled) {
313 meson_pwm_disable(meson, pwm->hwpwm);
314 channel->state.enabled = false;
315 }
316
317 if (state->polarity != channel->state.polarity) {
318 if (state->polarity == PWM_POLARITY_NORMAL)
319 meson->inverter_mask |= BIT(pwm->hwpwm);
320 else
321 meson->inverter_mask &= ~BIT(pwm->hwpwm);
322 }
323
324 err = meson_pwm_calc(meson, channel, pwm->hwpwm,
325 state->duty_cycle, state->period);
326 if (err < 0)
327 goto unlock;
328
329 channel->state.polarity = state->polarity;
330 channel->state.period = state->period;
331 channel->state.duty_cycle = state->duty_cycle;
332 }
333
334 if (state->enabled && !channel->state.enabled) {
335 meson_pwm_enable(meson, channel, pwm->hwpwm);
336 channel->state.enabled = true;
337 }
338
339unlock:
340 spin_unlock_irqrestore(&meson->lock, flags);
341 return err;
342}
343
344static void meson_pwm_get_state(struct pwm_chip *chip, struct pwm_device *pwm,
345 struct pwm_state *state)
346{
347 struct meson_pwm *meson = to_meson_pwm(chip);
348 u32 value, mask;
349
350 if (!state)
351 return;
352
353 switch (pwm->hwpwm) {
354 case 0:
355 mask = MISC_A_EN;
356 break;
357
358 case 1:
359 mask = MISC_B_EN;
360 break;
361
362 default:
363 return;
364 }
365
366 value = readl(meson->base + REG_MISC_AB);
367 state->enabled = (value & mask) != 0;
368}
369
370static const struct pwm_ops meson_pwm_ops = {
371 .request = meson_pwm_request,
372 .free = meson_pwm_free,
373 .apply = meson_pwm_apply,
374 .get_state = meson_pwm_get_state,
375 .owner = THIS_MODULE,
376};
377
378static const char * const pwm_meson8b_parent_names[] = {
379 "xtal", "vid_pll", "fclk_div4", "fclk_div3"
380};
381
382static const struct meson_pwm_data pwm_meson8b_data = {
383 .parent_names = pwm_meson8b_parent_names,
384};
385
386static const char * const pwm_gxbb_parent_names[] = {
387 "xtal", "hdmi_pll", "fclk_div4", "fclk_div3"
388};
389
390static const struct meson_pwm_data pwm_gxbb_data = {
391 .parent_names = pwm_gxbb_parent_names,
392};
393
394static const struct of_device_id meson_pwm_matches[] = {
395 { .compatible = "amlogic,meson8b-pwm", .data = &pwm_meson8b_data },
396 { .compatible = "amlogic,meson-gxbb-pwm", .data = &pwm_gxbb_data },
397 {},
398};
399MODULE_DEVICE_TABLE(of, meson_pwm_matches);
400
401static int meson_pwm_init_channels(struct meson_pwm *meson,
402 struct meson_pwm_channel *channels)
403{
404 struct device *dev = meson->chip.dev;
405 struct device_node *np = dev->of_node;
406 struct clk_init_data init;
407 unsigned int i;
408 char name[255];
409 int err;
410
411 for (i = 0; i < meson->chip.npwm; i++) {
412 struct meson_pwm_channel *channel = &channels[i];
413
414 snprintf(name, sizeof(name), "%s#mux%u", np->full_name, i);
415
416 init.name = name;
417 init.ops = &clk_mux_ops;
418 init.flags = CLK_IS_BASIC;
419 init.parent_names = meson->data->parent_names;
420 init.num_parents = 1 << MISC_CLK_SEL_WIDTH;
421
422 channel->mux.reg = meson->base + REG_MISC_AB;
423 channel->mux.shift = mux_reg_shifts[i];
424 channel->mux.mask = BIT(MISC_CLK_SEL_WIDTH) - 1;
425 channel->mux.flags = 0;
426 channel->mux.lock = &meson->lock;
427 channel->mux.table = NULL;
428 channel->mux.hw.init = &init;
429
430 channel->clk = devm_clk_register(dev, &channel->mux.hw);
431 if (IS_ERR(channel->clk)) {
432 err = PTR_ERR(channel->clk);
433 dev_err(dev, "failed to register %s: %d\n", name, err);
434 return err;
435 }
436
437 snprintf(name, sizeof(name), "clkin%u", i);
438
439 channel->clk_parent = devm_clk_get(dev, name);
440 if (IS_ERR(channel->clk_parent)) {
441 err = PTR_ERR(channel->clk_parent);
442 if (err == -EPROBE_DEFER)
443 return err;
444
445 channel->clk_parent = NULL;
446 }
447 }
448
449 return 0;
450}
451
452static void meson_pwm_add_channels(struct meson_pwm *meson,
453 struct meson_pwm_channel *channels)
454{
455 unsigned int i;
456
457 for (i = 0; i < meson->chip.npwm; i++)
458 pwm_set_chip_data(&meson->chip.pwms[i], &channels[i]);
459}
460
461static int meson_pwm_probe(struct platform_device *pdev)
462{
463 struct meson_pwm_channel *channels;
464 struct meson_pwm *meson;
465 struct resource *regs;
466 int err;
467
468 meson = devm_kzalloc(&pdev->dev, sizeof(*meson), GFP_KERNEL);
469 if (!meson)
470 return -ENOMEM;
471
472 regs = platform_get_resource(pdev, IORESOURCE_MEM, 0);
473 meson->base = devm_ioremap_resource(&pdev->dev, regs);
474 if (IS_ERR(meson->base))
475 return PTR_ERR(meson->base);
476
477 meson->chip.dev = &pdev->dev;
478 meson->chip.ops = &meson_pwm_ops;
479 meson->chip.base = -1;
480 meson->chip.npwm = 2;
481 meson->chip.of_xlate = of_pwm_xlate_with_flags;
482 meson->chip.of_pwm_n_cells = 3;
483
484 meson->data = of_device_get_match_data(&pdev->dev);
485 meson->inverter_mask = BIT(meson->chip.npwm) - 1;
486
487 channels = devm_kcalloc(&pdev->dev, meson->chip.npwm, sizeof(*meson),
488 GFP_KERNEL);
489 if (!channels)
490 return -ENOMEM;
491
492 err = meson_pwm_init_channels(meson, channels);
493 if (err < 0)
494 return err;
495
496 err = pwmchip_add(&meson->chip);
497 if (err < 0) {
498 dev_err(&pdev->dev, "failed to register PWM chip: %d\n", err);
499 return err;
500 }
501
502 meson_pwm_add_channels(meson, channels);
503
504 platform_set_drvdata(pdev, meson);
505
506 return 0;
507}
508
509static int meson_pwm_remove(struct platform_device *pdev)
510{
511 struct meson_pwm *meson = platform_get_drvdata(pdev);
512
513 return pwmchip_remove(&meson->chip);
514}
515
516static struct platform_driver meson_pwm_driver = {
517 .driver = {
518 .name = "meson-pwm",
519 .of_match_table = meson_pwm_matches,
520 },
521 .probe = meson_pwm_probe,
522 .remove = meson_pwm_remove,
523};
524module_platform_driver(meson_pwm_driver);
525
526MODULE_ALIAS("platform:meson-pwm");
527MODULE_DESCRIPTION("Amlogic Meson PWM Generator driver");
528MODULE_AUTHOR("Neil Armstrong <narmstrong@baylibre.com>");
529MODULE_LICENSE("Dual BSD/GPL");
diff --git a/drivers/pwm/pwm-mtk-disp.c b/drivers/pwm/pwm-mtk-disp.c
index 0ad3385298c0..893940d45f0d 100644
--- a/drivers/pwm/pwm-mtk-disp.c
+++ b/drivers/pwm/pwm-mtk-disp.c
@@ -18,30 +18,40 @@
18#include <linux/io.h> 18#include <linux/io.h>
19#include <linux/module.h> 19#include <linux/module.h>
20#include <linux/of.h> 20#include <linux/of.h>
21#include <linux/of_device.h>
21#include <linux/platform_device.h> 22#include <linux/platform_device.h>
22#include <linux/pwm.h> 23#include <linux/pwm.h>
23#include <linux/slab.h> 24#include <linux/slab.h>
24 25
25#define DISP_PWM_EN 0x00 26#define DISP_PWM_EN 0x00
26#define PWM_ENABLE_MASK BIT(0)
27 27
28#define DISP_PWM_COMMIT 0x08
29#define PWM_COMMIT_MASK BIT(0)
30
31#define DISP_PWM_CON_0 0x10
32#define PWM_CLKDIV_SHIFT 16 28#define PWM_CLKDIV_SHIFT 16
33#define PWM_CLKDIV_MAX 0x3ff 29#define PWM_CLKDIV_MAX 0x3ff
34#define PWM_CLKDIV_MASK (PWM_CLKDIV_MAX << PWM_CLKDIV_SHIFT) 30#define PWM_CLKDIV_MASK (PWM_CLKDIV_MAX << PWM_CLKDIV_SHIFT)
35 31
36#define DISP_PWM_CON_1 0x14
37#define PWM_PERIOD_BIT_WIDTH 12 32#define PWM_PERIOD_BIT_WIDTH 12
38#define PWM_PERIOD_MASK ((1 << PWM_PERIOD_BIT_WIDTH) - 1) 33#define PWM_PERIOD_MASK ((1 << PWM_PERIOD_BIT_WIDTH) - 1)
39 34
40#define PWM_HIGH_WIDTH_SHIFT 16 35#define PWM_HIGH_WIDTH_SHIFT 16
41#define PWM_HIGH_WIDTH_MASK (0x1fff << PWM_HIGH_WIDTH_SHIFT) 36#define PWM_HIGH_WIDTH_MASK (0x1fff << PWM_HIGH_WIDTH_SHIFT)
42 37
38struct mtk_pwm_data {
39 u32 enable_mask;
40 unsigned int con0;
41 u32 con0_sel;
42 unsigned int con1;
43
44 bool has_commit;
45 unsigned int commit;
46 unsigned int commit_mask;
47
48 unsigned int bls_debug;
49 u32 bls_debug_mask;
50};
51
43struct mtk_disp_pwm { 52struct mtk_disp_pwm {
44 struct pwm_chip chip; 53 struct pwm_chip chip;
54 const struct mtk_pwm_data *data;
45 struct clk *clk_main; 55 struct clk *clk_main;
46 struct clk *clk_mm; 56 struct clk *clk_mm;
47 void __iomem *base; 57 void __iomem *base;
@@ -106,12 +116,21 @@ static int mtk_disp_pwm_config(struct pwm_chip *chip, struct pwm_device *pwm,
106 return err; 116 return err;
107 } 117 }
108 118
109 mtk_disp_pwm_update_bits(mdp, DISP_PWM_CON_0, PWM_CLKDIV_MASK, 119 mtk_disp_pwm_update_bits(mdp, mdp->data->con0,
120 PWM_CLKDIV_MASK,
110 clk_div << PWM_CLKDIV_SHIFT); 121 clk_div << PWM_CLKDIV_SHIFT);
111 mtk_disp_pwm_update_bits(mdp, DISP_PWM_CON_1, 122 mtk_disp_pwm_update_bits(mdp, mdp->data->con1,
112 PWM_PERIOD_MASK | PWM_HIGH_WIDTH_MASK, value); 123 PWM_PERIOD_MASK | PWM_HIGH_WIDTH_MASK,
113 mtk_disp_pwm_update_bits(mdp, DISP_PWM_COMMIT, PWM_COMMIT_MASK, 1); 124 value);
114 mtk_disp_pwm_update_bits(mdp, DISP_PWM_COMMIT, PWM_COMMIT_MASK, 0); 125
126 if (mdp->data->has_commit) {
127 mtk_disp_pwm_update_bits(mdp, mdp->data->commit,
128 mdp->data->commit_mask,
129 mdp->data->commit_mask);
130 mtk_disp_pwm_update_bits(mdp, mdp->data->commit,
131 mdp->data->commit_mask,
132 0x0);
133 }
115 134
116 clk_disable(mdp->clk_mm); 135 clk_disable(mdp->clk_mm);
117 clk_disable(mdp->clk_main); 136 clk_disable(mdp->clk_main);
@@ -134,7 +153,8 @@ static int mtk_disp_pwm_enable(struct pwm_chip *chip, struct pwm_device *pwm)
134 return err; 153 return err;
135 } 154 }
136 155
137 mtk_disp_pwm_update_bits(mdp, DISP_PWM_EN, PWM_ENABLE_MASK, 1); 156 mtk_disp_pwm_update_bits(mdp, DISP_PWM_EN, mdp->data->enable_mask,
157 mdp->data->enable_mask);
138 158
139 return 0; 159 return 0;
140} 160}
@@ -143,7 +163,8 @@ static void mtk_disp_pwm_disable(struct pwm_chip *chip, struct pwm_device *pwm)
143{ 163{
144 struct mtk_disp_pwm *mdp = to_mtk_disp_pwm(chip); 164 struct mtk_disp_pwm *mdp = to_mtk_disp_pwm(chip);
145 165
146 mtk_disp_pwm_update_bits(mdp, DISP_PWM_EN, PWM_ENABLE_MASK, 0); 166 mtk_disp_pwm_update_bits(mdp, DISP_PWM_EN, mdp->data->enable_mask,
167 0x0);
147 168
148 clk_disable(mdp->clk_mm); 169 clk_disable(mdp->clk_mm);
149 clk_disable(mdp->clk_main); 170 clk_disable(mdp->clk_main);
@@ -166,6 +187,8 @@ static int mtk_disp_pwm_probe(struct platform_device *pdev)
166 if (!mdp) 187 if (!mdp)
167 return -ENOMEM; 188 return -ENOMEM;
168 189
190 mdp->data = of_device_get_match_data(&pdev->dev);
191
169 r = platform_get_resource(pdev, IORESOURCE_MEM, 0); 192 r = platform_get_resource(pdev, IORESOURCE_MEM, 0);
170 mdp->base = devm_ioremap_resource(&pdev->dev, r); 193 mdp->base = devm_ioremap_resource(&pdev->dev, r);
171 if (IS_ERR(mdp->base)) 194 if (IS_ERR(mdp->base))
@@ -200,6 +223,19 @@ static int mtk_disp_pwm_probe(struct platform_device *pdev)
200 223
201 platform_set_drvdata(pdev, mdp); 224 platform_set_drvdata(pdev, mdp);
202 225
226 /*
227 * For MT2701, disable double buffer before writing register
228 * and select manual mode and use PWM_PERIOD/PWM_HIGH_WIDTH.
229 */
230 if (!mdp->data->has_commit) {
231 mtk_disp_pwm_update_bits(mdp, mdp->data->bls_debug,
232 mdp->data->bls_debug_mask,
233 mdp->data->bls_debug_mask);
234 mtk_disp_pwm_update_bits(mdp, mdp->data->con0,
235 mdp->data->con0_sel,
236 mdp->data->con0_sel);
237 }
238
203 return 0; 239 return 0;
204 240
205disable_clk_mm: 241disable_clk_mm:
@@ -221,9 +257,30 @@ static int mtk_disp_pwm_remove(struct platform_device *pdev)
221 return ret; 257 return ret;
222} 258}
223 259
260static const struct mtk_pwm_data mt2701_pwm_data = {
261 .enable_mask = BIT(16),
262 .con0 = 0xa8,
263 .con0_sel = 0x2,
264 .con1 = 0xac,
265 .has_commit = false,
266 .bls_debug = 0xb0,
267 .bls_debug_mask = 0x3,
268};
269
270static const struct mtk_pwm_data mt8173_pwm_data = {
271 .enable_mask = BIT(0),
272 .con0 = 0x10,
273 .con0_sel = 0x0,
274 .con1 = 0x14,
275 .has_commit = true,
276 .commit = 0x8,
277 .commit_mask = 0x1,
278};
279
224static const struct of_device_id mtk_disp_pwm_of_match[] = { 280static const struct of_device_id mtk_disp_pwm_of_match[] = {
225 { .compatible = "mediatek,mt8173-disp-pwm" }, 281 { .compatible = "mediatek,mt2701-disp-pwm", .data = &mt2701_pwm_data},
226 { .compatible = "mediatek,mt6595-disp-pwm" }, 282 { .compatible = "mediatek,mt6595-disp-pwm", .data = &mt8173_pwm_data},
283 { .compatible = "mediatek,mt8173-disp-pwm", .data = &mt8173_pwm_data},
227 { } 284 { }
228}; 285};
229MODULE_DEVICE_TABLE(of, mtk_disp_pwm_of_match); 286MODULE_DEVICE_TABLE(of, mtk_disp_pwm_of_match);
diff --git a/drivers/pwm/pwm-samsung.c b/drivers/pwm/pwm-samsung.c
index ada2d326dc3e..f113cda47032 100644
--- a/drivers/pwm/pwm-samsung.c
+++ b/drivers/pwm/pwm-samsung.c
@@ -193,9 +193,18 @@ static unsigned long pwm_samsung_calc_tin(struct samsung_pwm_chip *chip,
193 * divider settings and choose the lowest divisor that can generate 193 * divider settings and choose the lowest divisor that can generate
194 * frequencies lower than requested. 194 * frequencies lower than requested.
195 */ 195 */
196 for (div = variant->div_base; div < 4; ++div) 196 if (variant->bits < 32) {
197 if ((rate >> (variant->bits + div)) < freq) 197 /* Only for s3c24xx */
198 break; 198 for (div = variant->div_base; div < 4; ++div)
199 if ((rate >> (variant->bits + div)) < freq)
200 break;
201 } else {
202 /*
203 * Other variants have enough counter bits to generate any
204 * requested rate, so no need to check higher divisors.
205 */
206 div = variant->div_base;
207 }
199 208
200 pwm_samsung_set_divisor(chip, chan, BIT(div)); 209 pwm_samsung_set_divisor(chip, chan, BIT(div));
201 210
diff --git a/drivers/pwm/pwm-sti.c b/drivers/pwm/pwm-sti.c
index 92abbd56b9f7..dd82dc840af9 100644
--- a/drivers/pwm/pwm-sti.c
+++ b/drivers/pwm/pwm-sti.c
@@ -1,8 +1,10 @@
1/* 1/*
2 * PWM device driver for ST SoCs. 2 * PWM device driver for ST SoCs
3 * Author: Ajit Pal Singh <ajitpal.singh@st.com> 3 *
4 * Copyright (C) 2013-2016 STMicroelectronics (R&D) Limited
4 * 5 *
5 * Copyright (C) 2013-2014 STMicroelectronics (R&D) Limited 6 * Author: Ajit Pal Singh <ajitpal.singh@st.com>
7 * Lee Jones <lee.jones@linaro.org>
6 * 8 *
7 * This program is free software; you can redistribute it and/or modify 9 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by 10 * it under the terms of the GNU General Public License as published by
@@ -11,6 +13,7 @@
11 */ 13 */
12 14
13#include <linux/clk.h> 15#include <linux/clk.h>
16#include <linux/interrupt.h>
14#include <linux/math64.h> 17#include <linux/math64.h>
15#include <linux/mfd/syscon.h> 18#include <linux/mfd/syscon.h>
16#include <linux/module.h> 19#include <linux/module.h>
@@ -18,43 +21,82 @@
18#include <linux/platform_device.h> 21#include <linux/platform_device.h>
19#include <linux/pwm.h> 22#include <linux/pwm.h>
20#include <linux/regmap.h> 23#include <linux/regmap.h>
24#include <linux/sched.h>
21#include <linux/slab.h> 25#include <linux/slab.h>
22#include <linux/time.h> 26#include <linux/time.h>
27#include <linux/wait.h>
28
29#define PWM_OUT_VAL(x) (0x00 + (4 * (x))) /* Device's Duty Cycle register */
30#define PWM_CPT_VAL(x) (0x10 + (4 * (x))) /* Capture value */
31#define PWM_CPT_EDGE(x) (0x30 + (4 * (x))) /* Edge to capture on */
23 32
24#define STI_DS_REG(ch) (4 * (ch)) /* Channel's Duty Cycle register */ 33#define STI_PWM_CTRL 0x50 /* Control/Config register */
25#define STI_PWMCR 0x50 /* Control/Config register */ 34#define STI_INT_EN 0x54 /* Interrupt Enable/Disable register */
26#define STI_INTEN 0x54 /* Interrupt Enable/Disable register */ 35#define STI_INT_STA 0x58 /* Interrupt Status register */
27#define PWM_PRESCALE_LOW_MASK 0x0f 36#define PWM_INT_ACK 0x5c
28#define PWM_PRESCALE_HIGH_MASK 0xf0 37#define PWM_PRESCALE_LOW_MASK 0x0f
38#define PWM_PRESCALE_HIGH_MASK 0xf0
39#define PWM_CPT_EDGE_MASK 0x03
40#define PWM_INT_ACK_MASK 0x1ff
41
42#define STI_MAX_CPT_DEVS 4
43#define CPT_DC_MAX 0xff
29 44
30/* Regfield IDs */ 45/* Regfield IDs */
31enum { 46enum {
47 /* Bits in PWM_CTRL*/
32 PWMCLK_PRESCALE_LOW, 48 PWMCLK_PRESCALE_LOW,
33 PWMCLK_PRESCALE_HIGH, 49 PWMCLK_PRESCALE_HIGH,
34 PWM_EN, 50 CPTCLK_PRESCALE,
35 PWM_INT_EN, 51
52 PWM_OUT_EN,
53 PWM_CPT_EN,
54
55 PWM_CPT_INT_EN,
56 PWM_CPT_INT_STAT,
36 57
37 /* Keep last */ 58 /* Keep last */
38 MAX_REGFIELDS 59 MAX_REGFIELDS
39}; 60};
40 61
62/*
63 * Each capture input can be programmed to detect rising-edge, falling-edge,
64 * either edge or neither egde.
65 */
66enum sti_cpt_edge {
67 CPT_EDGE_DISABLED,
68 CPT_EDGE_RISING,
69 CPT_EDGE_FALLING,
70 CPT_EDGE_BOTH,
71};
72
73struct sti_cpt_ddata {
74 u32 snapshot[3];
75 unsigned int index;
76 struct mutex lock;
77 wait_queue_head_t wait;
78};
79
41struct sti_pwm_compat_data { 80struct sti_pwm_compat_data {
42 const struct reg_field *reg_fields; 81 const struct reg_field *reg_fields;
43 unsigned int num_chan; 82 unsigned int pwm_num_devs;
83 unsigned int cpt_num_devs;
44 unsigned int max_pwm_cnt; 84 unsigned int max_pwm_cnt;
45 unsigned int max_prescale; 85 unsigned int max_prescale;
46}; 86};
47 87
48struct sti_pwm_chip { 88struct sti_pwm_chip {
49 struct device *dev; 89 struct device *dev;
50 struct clk *clk; 90 struct clk *pwm_clk;
51 unsigned long clk_rate; 91 struct clk *cpt_clk;
52 struct regmap *regmap; 92 struct regmap *regmap;
53 struct sti_pwm_compat_data *cdata; 93 struct sti_pwm_compat_data *cdata;
54 struct regmap_field *prescale_low; 94 struct regmap_field *prescale_low;
55 struct regmap_field *prescale_high; 95 struct regmap_field *prescale_high;
56 struct regmap_field *pwm_en; 96 struct regmap_field *pwm_out_en;
57 struct regmap_field *pwm_int_en; 97 struct regmap_field *pwm_cpt_en;
98 struct regmap_field *pwm_cpt_int_en;
99 struct regmap_field *pwm_cpt_int_stat;
58 struct pwm_chip chip; 100 struct pwm_chip chip;
59 struct pwm_device *cur; 101 struct pwm_device *cur;
60 unsigned long configured; 102 unsigned long configured;
@@ -64,10 +106,13 @@ struct sti_pwm_chip {
64}; 106};
65 107
66static const struct reg_field sti_pwm_regfields[MAX_REGFIELDS] = { 108static const struct reg_field sti_pwm_regfields[MAX_REGFIELDS] = {
67 [PWMCLK_PRESCALE_LOW] = REG_FIELD(STI_PWMCR, 0, 3), 109 [PWMCLK_PRESCALE_LOW] = REG_FIELD(STI_PWM_CTRL, 0, 3),
68 [PWMCLK_PRESCALE_HIGH] = REG_FIELD(STI_PWMCR, 11, 14), 110 [PWMCLK_PRESCALE_HIGH] = REG_FIELD(STI_PWM_CTRL, 11, 14),
69 [PWM_EN] = REG_FIELD(STI_PWMCR, 9, 9), 111 [CPTCLK_PRESCALE] = REG_FIELD(STI_PWM_CTRL, 4, 8),
70 [PWM_INT_EN] = REG_FIELD(STI_INTEN, 0, 0), 112 [PWM_OUT_EN] = REG_FIELD(STI_PWM_CTRL, 9, 9),
113 [PWM_CPT_EN] = REG_FIELD(STI_PWM_CTRL, 10, 10),
114 [PWM_CPT_INT_EN] = REG_FIELD(STI_INT_EN, 1, 4),
115 [PWM_CPT_INT_STAT] = REG_FIELD(STI_INT_STA, 1, 4),
71}; 116};
72 117
73static inline struct sti_pwm_chip *to_sti_pwmchip(struct pwm_chip *chip) 118static inline struct sti_pwm_chip *to_sti_pwmchip(struct pwm_chip *chip)
@@ -82,61 +127,68 @@ static int sti_pwm_get_prescale(struct sti_pwm_chip *pc, unsigned long period,
82 unsigned int *prescale) 127 unsigned int *prescale)
83{ 128{
84 struct sti_pwm_compat_data *cdata = pc->cdata; 129 struct sti_pwm_compat_data *cdata = pc->cdata;
85 unsigned long val; 130 unsigned long clk_rate;
131 unsigned long value;
86 unsigned int ps; 132 unsigned int ps;
87 133
134 clk_rate = clk_get_rate(pc->pwm_clk);
135 if (!clk_rate) {
136 dev_err(pc->dev, "failed to get clock rate\n");
137 return -EINVAL;
138 }
139
88 /* 140 /*
89 * prescale = ((period_ns * clk_rate) / (10^9 * (max_pwm_count + 1)) - 1 141 * prescale = ((period_ns * clk_rate) / (10^9 * (max_pwm_cnt + 1)) - 1
90 */ 142 */
91 val = NSEC_PER_SEC / pc->clk_rate; 143 value = NSEC_PER_SEC / clk_rate;
92 val *= cdata->max_pwm_cnt + 1; 144 value *= cdata->max_pwm_cnt + 1;
93 145
94 if (period % val) { 146 if (period % value)
95 return -EINVAL; 147 return -EINVAL;
96 } else { 148
97 ps = period / val - 1; 149 ps = period / value - 1;
98 if (ps > cdata->max_prescale) 150 if (ps > cdata->max_prescale)
99 return -EINVAL; 151 return -EINVAL;
100 } 152
101 *prescale = ps; 153 *prescale = ps;
102 154
103 return 0; 155 return 0;
104} 156}
105 157
106/* 158/*
107 * For STiH4xx PWM IP, the PWM period is fixed to 256 local clock cycles. 159 * For STiH4xx PWM IP, the PWM period is fixed to 256 local clock cycles. The
108 * The only way to change the period (apart from changing the PWM input clock) 160 * only way to change the period (apart from changing the PWM input clock) is
109 * is to change the PWM clock prescaler. 161 * to change the PWM clock prescaler.
110 * The prescaler is of 8 bits, so 256 prescaler values and hence 162 *
111 * 256 possible period values are supported (for a particular clock rate). 163 * The prescaler is of 8 bits, so 256 prescaler values and hence 256 possible
112 * The requested period will be applied only if it matches one of these 164 * period values are supported (for a particular clock rate). The requested
113 * 256 values. 165 * period will be applied only if it matches one of these 256 values.
114 */ 166 */
115static int sti_pwm_config(struct pwm_chip *chip, struct pwm_device *pwm, 167static int sti_pwm_config(struct pwm_chip *chip, struct pwm_device *pwm,
116 int duty_ns, int period_ns) 168 int duty_ns, int period_ns)
117{ 169{
118 struct sti_pwm_chip *pc = to_sti_pwmchip(chip); 170 struct sti_pwm_chip *pc = to_sti_pwmchip(chip);
119 struct sti_pwm_compat_data *cdata = pc->cdata; 171 struct sti_pwm_compat_data *cdata = pc->cdata;
172 unsigned int ncfg, value, prescale = 0;
120 struct pwm_device *cur = pc->cur; 173 struct pwm_device *cur = pc->cur;
121 struct device *dev = pc->dev; 174 struct device *dev = pc->dev;
122 unsigned int prescale = 0, pwmvalx;
123 int ret;
124 unsigned int ncfg;
125 bool period_same = false; 175 bool period_same = false;
176 int ret;
126 177
127 ncfg = hweight_long(pc->configured); 178 ncfg = hweight_long(pc->configured);
128 if (ncfg) 179 if (ncfg)
129 period_same = (period_ns == pwm_get_period(cur)); 180 period_same = (period_ns == pwm_get_period(cur));
130 181
131 /* Allow configuration changes if one of the 182 /*
132 * following conditions satisfy. 183 * Allow configuration changes if one of the following conditions
133 * 1. No channels have been configured. 184 * satisfy.
134 * 2. Only one channel has been configured and the new request 185 * 1. No devices have been configured.
135 * is for the same channel. 186 * 2. Only one device has been configured and the new request is for
136 * 3. Only one channel has been configured and the new request is 187 * the same device.
137 * for a new channel and period of the new channel is same as 188 * 3. Only one device has been configured and the new request is for
138 * the current configured period. 189 * a new device and period of the new device is same as the current
139 * 4. More than one channels are configured and period of the new 190 * configured period.
191 * 4. More than one devices are configured and period of the new
140 * requestis the same as the current period. 192 * requestis the same as the current period.
141 */ 193 */
142 if (!ncfg || 194 if (!ncfg ||
@@ -144,7 +196,11 @@ static int sti_pwm_config(struct pwm_chip *chip, struct pwm_device *pwm,
144 ((ncfg == 1) && (pwm->hwpwm != cur->hwpwm) && period_same) || 196 ((ncfg == 1) && (pwm->hwpwm != cur->hwpwm) && period_same) ||
145 ((ncfg > 1) && period_same)) { 197 ((ncfg > 1) && period_same)) {
146 /* Enable clock before writing to PWM registers. */ 198 /* Enable clock before writing to PWM registers. */
147 ret = clk_enable(pc->clk); 199 ret = clk_enable(pc->pwm_clk);
200 if (ret)
201 return ret;
202
203 ret = clk_enable(pc->cpt_clk);
148 if (ret) 204 if (ret)
149 return ret; 205 return ret;
150 206
@@ -153,15 +209,15 @@ static int sti_pwm_config(struct pwm_chip *chip, struct pwm_device *pwm,
153 if (ret) 209 if (ret)
154 goto clk_dis; 210 goto clk_dis;
155 211
156 ret = 212 value = prescale & PWM_PRESCALE_LOW_MASK;
157 regmap_field_write(pc->prescale_low, 213
158 prescale & PWM_PRESCALE_LOW_MASK); 214 ret = regmap_field_write(pc->prescale_low, value);
159 if (ret) 215 if (ret)
160 goto clk_dis; 216 goto clk_dis;
161 217
162 ret = 218 value = (prescale & PWM_PRESCALE_HIGH_MASK) >> 4;
163 regmap_field_write(pc->prescale_high, 219
164 (prescale & PWM_PRESCALE_HIGH_MASK) >> 4); 220 ret = regmap_field_write(pc->prescale_high, value);
165 if (ret) 221 if (ret)
166 goto clk_dis; 222 goto clk_dis;
167 } 223 }
@@ -172,25 +228,26 @@ static int sti_pwm_config(struct pwm_chip *chip, struct pwm_device *pwm,
172 * PWM pulse = (max_pwm_count + 1) local cycles, 228 * PWM pulse = (max_pwm_count + 1) local cycles,
173 * that is continuous pulse: signal never goes low. 229 * that is continuous pulse: signal never goes low.
174 */ 230 */
175 pwmvalx = cdata->max_pwm_cnt * duty_ns / period_ns; 231 value = cdata->max_pwm_cnt * duty_ns / period_ns;
176 232
177 ret = regmap_write(pc->regmap, STI_DS_REG(pwm->hwpwm), pwmvalx); 233 ret = regmap_write(pc->regmap, PWM_OUT_VAL(pwm->hwpwm), value);
178 if (ret) 234 if (ret)
179 goto clk_dis; 235 goto clk_dis;
180 236
181 ret = regmap_field_write(pc->pwm_int_en, 0); 237 ret = regmap_field_write(pc->pwm_cpt_int_en, 0);
182 238
183 set_bit(pwm->hwpwm, &pc->configured); 239 set_bit(pwm->hwpwm, &pc->configured);
184 pc->cur = pwm; 240 pc->cur = pwm;
185 241
186 dev_dbg(dev, "prescale:%u, period:%i, duty:%i, pwmvalx:%u\n", 242 dev_dbg(dev, "prescale:%u, period:%i, duty:%i, value:%u\n",
187 prescale, period_ns, duty_ns, pwmvalx); 243 prescale, period_ns, duty_ns, value);
188 } else { 244 } else {
189 return -EINVAL; 245 return -EINVAL;
190 } 246 }
191 247
192clk_dis: 248clk_dis:
193 clk_disable(pc->clk); 249 clk_disable(pc->pwm_clk);
250 clk_disable(pc->cpt_clk);
194 return ret; 251 return ret;
195} 252}
196 253
@@ -201,23 +258,30 @@ static int sti_pwm_enable(struct pwm_chip *chip, struct pwm_device *pwm)
201 int ret = 0; 258 int ret = 0;
202 259
203 /* 260 /*
204 * Since we have a common enable for all PWM channels, 261 * Since we have a common enable for all PWM devices, do not enable if
205 * do not enable if already enabled. 262 * already enabled.
206 */ 263 */
207 mutex_lock(&pc->sti_pwm_lock); 264 mutex_lock(&pc->sti_pwm_lock);
265
208 if (!pc->en_count) { 266 if (!pc->en_count) {
209 ret = clk_enable(pc->clk); 267 ret = clk_enable(pc->pwm_clk);
268 if (ret)
269 goto out;
270
271 ret = clk_enable(pc->cpt_clk);
210 if (ret) 272 if (ret)
211 goto out; 273 goto out;
212 274
213 ret = regmap_field_write(pc->pwm_en, 1); 275 ret = regmap_field_write(pc->pwm_out_en, 1);
214 if (ret) { 276 if (ret) {
215 dev_err(dev, "failed to enable PWM device:%d\n", 277 dev_err(dev, "failed to enable PWM device %u: %d\n",
216 pwm->hwpwm); 278 pwm->hwpwm, ret);
217 goto out; 279 goto out;
218 } 280 }
219 } 281 }
282
220 pc->en_count++; 283 pc->en_count++;
284
221out: 285out:
222 mutex_unlock(&pc->sti_pwm_lock); 286 mutex_unlock(&pc->sti_pwm_lock);
223 return ret; 287 return ret;
@@ -228,13 +292,17 @@ static void sti_pwm_disable(struct pwm_chip *chip, struct pwm_device *pwm)
228 struct sti_pwm_chip *pc = to_sti_pwmchip(chip); 292 struct sti_pwm_chip *pc = to_sti_pwmchip(chip);
229 293
230 mutex_lock(&pc->sti_pwm_lock); 294 mutex_lock(&pc->sti_pwm_lock);
295
231 if (--pc->en_count) { 296 if (--pc->en_count) {
232 mutex_unlock(&pc->sti_pwm_lock); 297 mutex_unlock(&pc->sti_pwm_lock);
233 return; 298 return;
234 } 299 }
235 regmap_field_write(pc->pwm_en, 0);
236 300
237 clk_disable(pc->clk); 301 regmap_field_write(pc->pwm_out_en, 0);
302
303 clk_disable(pc->pwm_clk);
304 clk_disable(pc->cpt_clk);
305
238 mutex_unlock(&pc->sti_pwm_lock); 306 mutex_unlock(&pc->sti_pwm_lock);
239} 307}
240 308
@@ -245,7 +313,90 @@ static void sti_pwm_free(struct pwm_chip *chip, struct pwm_device *pwm)
245 clear_bit(pwm->hwpwm, &pc->configured); 313 clear_bit(pwm->hwpwm, &pc->configured);
246} 314}
247 315
316static int sti_pwm_capture(struct pwm_chip *chip, struct pwm_device *pwm,
317 struct pwm_capture *result, unsigned long timeout)
318{
319 struct sti_pwm_chip *pc = to_sti_pwmchip(chip);
320 struct sti_pwm_compat_data *cdata = pc->cdata;
321 struct sti_cpt_ddata *ddata = pwm_get_chip_data(pwm);
322 struct device *dev = pc->dev;
323 unsigned int effective_ticks;
324 unsigned long long high, low;
325 int ret;
326
327 if (pwm->hwpwm >= cdata->cpt_num_devs) {
328 dev_err(dev, "device %u is not valid\n", pwm->hwpwm);
329 return -EINVAL;
330 }
331
332 mutex_lock(&ddata->lock);
333 ddata->index = 0;
334
335 /* Prepare capture measurement */
336 regmap_write(pc->regmap, PWM_CPT_EDGE(pwm->hwpwm), CPT_EDGE_RISING);
337 regmap_field_write(pc->pwm_cpt_int_en, BIT(pwm->hwpwm));
338
339 /* Enable capture */
340 ret = regmap_field_write(pc->pwm_cpt_en, 1);
341 if (ret) {
342 dev_err(dev, "failed to enable PWM capture %u: %d\n",
343 pwm->hwpwm, ret);
344 goto out;
345 }
346
347 ret = wait_event_interruptible_timeout(ddata->wait, ddata->index > 1,
348 msecs_to_jiffies(timeout));
349
350 regmap_write(pc->regmap, PWM_CPT_EDGE(pwm->hwpwm), CPT_EDGE_DISABLED);
351
352 if (ret == -ERESTARTSYS)
353 goto out;
354
355 switch (ddata->index) {
356 case 0:
357 case 1:
358 /*
359 * Getting here could mean:
360 * - input signal is constant of less than 1 Hz
361 * - there is no input signal at all
362 *
363 * In such case the frequency is rounded down to 0
364 */
365 result->period = 0;
366 result->duty_cycle = 0;
367
368 break;
369
370 case 2:
371 /* We have everying we need */
372 high = ddata->snapshot[1] - ddata->snapshot[0];
373 low = ddata->snapshot[2] - ddata->snapshot[1];
374
375 effective_ticks = clk_get_rate(pc->cpt_clk);
376
377 result->period = (high + low) * NSEC_PER_SEC;
378 result->period /= effective_ticks;
379
380 result->duty_cycle = high * NSEC_PER_SEC;
381 result->duty_cycle /= effective_ticks;
382
383 break;
384
385 default:
386 dev_err(dev, "internal error\n");
387 break;
388 }
389
390out:
391 /* Disable capture */
392 regmap_field_write(pc->pwm_cpt_en, 0);
393
394 mutex_unlock(&ddata->lock);
395 return ret;
396}
397
248static const struct pwm_ops sti_pwm_ops = { 398static const struct pwm_ops sti_pwm_ops = {
399 .capture = sti_pwm_capture,
249 .config = sti_pwm_config, 400 .config = sti_pwm_config,
250 .enable = sti_pwm_enable, 401 .enable = sti_pwm_enable,
251 .disable = sti_pwm_disable, 402 .disable = sti_pwm_disable,
@@ -253,17 +404,98 @@ static const struct pwm_ops sti_pwm_ops = {
253 .owner = THIS_MODULE, 404 .owner = THIS_MODULE,
254}; 405};
255 406
407static irqreturn_t sti_pwm_interrupt(int irq, void *data)
408{
409 struct sti_pwm_chip *pc = data;
410 struct device *dev = pc->dev;
411 struct sti_cpt_ddata *ddata;
412 int devicenum;
413 unsigned int cpt_int_stat;
414 unsigned int reg;
415 int ret = IRQ_NONE;
416
417 ret = regmap_field_read(pc->pwm_cpt_int_stat, &cpt_int_stat);
418 if (ret)
419 return ret;
420
421 while (cpt_int_stat) {
422 devicenum = ffs(cpt_int_stat) - 1;
423
424 ddata = pwm_get_chip_data(&pc->chip.pwms[devicenum]);
425
426 /*
427 * Capture input:
428 * _______ _______
429 * | | | |
430 * __| |_________________| |________
431 * ^0 ^1 ^2
432 *
433 * Capture start by the first available rising edge. When a
434 * capture event occurs, capture value (CPT_VALx) is stored,
435 * index incremented, capture edge changed.
436 *
437 * After the capture, if the index > 1, we have collected the
438 * necessary data so we signal the thread waiting for it and
439 * disable the capture by setting capture edge to none
440 */
441
442 regmap_read(pc->regmap,
443 PWM_CPT_VAL(devicenum),
444 &ddata->snapshot[ddata->index]);
445
446 switch (ddata->index) {
447 case 0:
448 case 1:
449 regmap_read(pc->regmap, PWM_CPT_EDGE(devicenum), &reg);
450 reg ^= PWM_CPT_EDGE_MASK;
451 regmap_write(pc->regmap, PWM_CPT_EDGE(devicenum), reg);
452
453 ddata->index++;
454 break;
455
456 case 2:
457 regmap_write(pc->regmap,
458 PWM_CPT_EDGE(devicenum),
459 CPT_EDGE_DISABLED);
460 wake_up(&ddata->wait);
461 break;
462
463 default:
464 dev_err(dev, "Internal error\n");
465 }
466
467 cpt_int_stat &= ~BIT_MASK(devicenum);
468
469 ret = IRQ_HANDLED;
470 }
471
472 /* Just ACK everything */
473 regmap_write(pc->regmap, PWM_INT_ACK, PWM_INT_ACK_MASK);
474
475 return ret;
476}
477
256static int sti_pwm_probe_dt(struct sti_pwm_chip *pc) 478static int sti_pwm_probe_dt(struct sti_pwm_chip *pc)
257{ 479{
258 struct device *dev = pc->dev; 480 struct device *dev = pc->dev;
259 const struct reg_field *reg_fields; 481 const struct reg_field *reg_fields;
260 struct device_node *np = dev->of_node; 482 struct device_node *np = dev->of_node;
261 struct sti_pwm_compat_data *cdata = pc->cdata; 483 struct sti_pwm_compat_data *cdata = pc->cdata;
262 u32 num_chan; 484 u32 num_devs;
485 int ret;
486
487 ret = of_property_read_u32(np, "st,pwm-num-chan", &num_devs);
488 if (!ret)
489 cdata->pwm_num_devs = num_devs;
490
491 ret = of_property_read_u32(np, "st,capture-num-chan", &num_devs);
492 if (!ret)
493 cdata->cpt_num_devs = num_devs;
263 494
264 of_property_read_u32(np, "st,pwm-num-chan", &num_chan); 495 if (!cdata->pwm_num_devs && !cdata->cpt_num_devs) {
265 if (num_chan) 496 dev_err(dev, "No channels configured\n");
266 cdata->num_chan = num_chan; 497 return -EINVAL;
498 }
267 499
268 reg_fields = cdata->reg_fields; 500 reg_fields = cdata->reg_fields;
269 501
@@ -277,15 +509,26 @@ static int sti_pwm_probe_dt(struct sti_pwm_chip *pc)
277 if (IS_ERR(pc->prescale_high)) 509 if (IS_ERR(pc->prescale_high))
278 return PTR_ERR(pc->prescale_high); 510 return PTR_ERR(pc->prescale_high);
279 511
280 pc->pwm_en = devm_regmap_field_alloc(dev, pc->regmap,
281 reg_fields[PWM_EN]);
282 if (IS_ERR(pc->pwm_en))
283 return PTR_ERR(pc->pwm_en);
284 512
285 pc->pwm_int_en = devm_regmap_field_alloc(dev, pc->regmap, 513 pc->pwm_out_en = devm_regmap_field_alloc(dev, pc->regmap,
286 reg_fields[PWM_INT_EN]); 514 reg_fields[PWM_OUT_EN]);
287 if (IS_ERR(pc->pwm_int_en)) 515 if (IS_ERR(pc->pwm_out_en))
288 return PTR_ERR(pc->pwm_int_en); 516 return PTR_ERR(pc->pwm_out_en);
517
518 pc->pwm_cpt_en = devm_regmap_field_alloc(dev, pc->regmap,
519 reg_fields[PWM_CPT_EN]);
520 if (IS_ERR(pc->pwm_cpt_en))
521 return PTR_ERR(pc->pwm_cpt_en);
522
523 pc->pwm_cpt_int_en = devm_regmap_field_alloc(dev, pc->regmap,
524 reg_fields[PWM_CPT_INT_EN]);
525 if (IS_ERR(pc->pwm_cpt_int_en))
526 return PTR_ERR(pc->pwm_cpt_int_en);
527
528 pc->pwm_cpt_int_stat = devm_regmap_field_alloc(dev, pc->regmap,
529 reg_fields[PWM_CPT_INT_STAT]);
530 if (PTR_ERR_OR_ZERO(pc->pwm_cpt_int_stat))
531 return PTR_ERR(pc->pwm_cpt_int_stat);
289 532
290 return 0; 533 return 0;
291} 534}
@@ -302,7 +545,8 @@ static int sti_pwm_probe(struct platform_device *pdev)
302 struct sti_pwm_compat_data *cdata; 545 struct sti_pwm_compat_data *cdata;
303 struct sti_pwm_chip *pc; 546 struct sti_pwm_chip *pc;
304 struct resource *res; 547 struct resource *res;
305 int ret; 548 unsigned int i;
549 int irq, ret;
306 550
307 pc = devm_kzalloc(dev, sizeof(*pc), GFP_KERNEL); 551 pc = devm_kzalloc(dev, sizeof(*pc), GFP_KERNEL);
308 if (!pc) 552 if (!pc)
@@ -323,14 +567,28 @@ static int sti_pwm_probe(struct platform_device *pdev)
323 if (IS_ERR(pc->regmap)) 567 if (IS_ERR(pc->regmap))
324 return PTR_ERR(pc->regmap); 568 return PTR_ERR(pc->regmap);
325 569
570 irq = platform_get_irq(pdev, 0);
571 if (irq < 0) {
572 dev_err(&pdev->dev, "Failed to obtain IRQ\n");
573 return irq;
574 }
575
576 ret = devm_request_irq(&pdev->dev, irq, sti_pwm_interrupt, 0,
577 pdev->name, pc);
578 if (ret < 0) {
579 dev_err(&pdev->dev, "Failed to request IRQ\n");
580 return ret;
581 }
582
326 /* 583 /*
327 * Setup PWM data with default values: some values could be replaced 584 * Setup PWM data with default values: some values could be replaced
328 * with specific ones provided from Device Tree. 585 * with specific ones provided from Device Tree.
329 */ 586 */
330 cdata->reg_fields = &sti_pwm_regfields[0]; 587 cdata->reg_fields = sti_pwm_regfields;
331 cdata->max_prescale = 0xff; 588 cdata->max_prescale = 0xff;
332 cdata->max_pwm_cnt = 255; 589 cdata->max_pwm_cnt = 255;
333 cdata->num_chan = 1; 590 cdata->pwm_num_devs = 0;
591 cdata->cpt_num_devs = 0;
334 592
335 pc->cdata = cdata; 593 pc->cdata = cdata;
336 pc->dev = dev; 594 pc->dev = dev;
@@ -341,36 +599,64 @@ static int sti_pwm_probe(struct platform_device *pdev)
341 if (ret) 599 if (ret)
342 return ret; 600 return ret;
343 601
344 pc->clk = of_clk_get_by_name(dev->of_node, "pwm"); 602 if (!cdata->pwm_num_devs)
345 if (IS_ERR(pc->clk)) { 603 goto skip_pwm;
604
605 pc->pwm_clk = of_clk_get_by_name(dev->of_node, "pwm");
606 if (IS_ERR(pc->pwm_clk)) {
346 dev_err(dev, "failed to get PWM clock\n"); 607 dev_err(dev, "failed to get PWM clock\n");
347 return PTR_ERR(pc->clk); 608 return PTR_ERR(pc->pwm_clk);
348 } 609 }
349 610
350 pc->clk_rate = clk_get_rate(pc->clk); 611 ret = clk_prepare(pc->pwm_clk);
351 if (!pc->clk_rate) { 612 if (ret) {
352 dev_err(dev, "failed to get clock rate\n"); 613 dev_err(dev, "failed to prepare clock\n");
353 return -EINVAL; 614 return ret;
354 } 615 }
355 616
356 ret = clk_prepare(pc->clk); 617skip_pwm:
618 if (!cdata->cpt_num_devs)
619 goto skip_cpt;
620
621 pc->cpt_clk = of_clk_get_by_name(dev->of_node, "capture");
622 if (IS_ERR(pc->cpt_clk)) {
623 dev_err(dev, "failed to get PWM capture clock\n");
624 return PTR_ERR(pc->cpt_clk);
625 }
626
627 ret = clk_prepare(pc->cpt_clk);
357 if (ret) { 628 if (ret) {
358 dev_err(dev, "failed to prepare clock\n"); 629 dev_err(dev, "failed to prepare clock\n");
359 return ret; 630 return ret;
360 } 631 }
361 632
633skip_cpt:
362 pc->chip.dev = dev; 634 pc->chip.dev = dev;
363 pc->chip.ops = &sti_pwm_ops; 635 pc->chip.ops = &sti_pwm_ops;
364 pc->chip.base = -1; 636 pc->chip.base = -1;
365 pc->chip.npwm = pc->cdata->num_chan; 637 pc->chip.npwm = pc->cdata->pwm_num_devs;
366 pc->chip.can_sleep = true; 638 pc->chip.can_sleep = true;
367 639
368 ret = pwmchip_add(&pc->chip); 640 ret = pwmchip_add(&pc->chip);
369 if (ret < 0) { 641 if (ret < 0) {
370 clk_unprepare(pc->clk); 642 clk_unprepare(pc->pwm_clk);
643 clk_unprepare(pc->cpt_clk);
371 return ret; 644 return ret;
372 } 645 }
373 646
647 for (i = 0; i < cdata->cpt_num_devs; i++) {
648 struct sti_cpt_ddata *ddata;
649
650 ddata = devm_kzalloc(dev, sizeof(*ddata), GFP_KERNEL);
651 if (!ddata)
652 return -ENOMEM;
653
654 init_waitqueue_head(&ddata->wait);
655 mutex_init(&ddata->lock);
656
657 pwm_set_chip_data(&pc->chip.pwms[i], ddata);
658 }
659
374 platform_set_drvdata(pdev, pc); 660 platform_set_drvdata(pdev, pc);
375 661
376 return 0; 662 return 0;
@@ -381,10 +667,11 @@ static int sti_pwm_remove(struct platform_device *pdev)
381 struct sti_pwm_chip *pc = platform_get_drvdata(pdev); 667 struct sti_pwm_chip *pc = platform_get_drvdata(pdev);
382 unsigned int i; 668 unsigned int i;
383 669
384 for (i = 0; i < pc->cdata->num_chan; i++) 670 for (i = 0; i < pc->cdata->pwm_num_devs; i++)
385 pwm_disable(&pc->chip.pwms[i]); 671 pwm_disable(&pc->chip.pwms[i]);
386 672
387 clk_unprepare(pc->clk); 673 clk_unprepare(pc->pwm_clk);
674 clk_unprepare(pc->cpt_clk);
388 675
389 return pwmchip_remove(&pc->chip); 676 return pwmchip_remove(&pc->chip);
390} 677}
diff --git a/drivers/pwm/pwm-sun4i.c b/drivers/pwm/pwm-sun4i.c
index 03a99a53c39e..b0803f6c64d9 100644
--- a/drivers/pwm/pwm-sun4i.c
+++ b/drivers/pwm/pwm-sun4i.c
@@ -284,6 +284,12 @@ static const struct sun4i_pwm_data sun4i_pwm_data_a20 = {
284 .npwm = 2, 284 .npwm = 2,
285}; 285};
286 286
287static const struct sun4i_pwm_data sun4i_pwm_data_h3 = {
288 .has_prescaler_bypass = true,
289 .has_rdy = true,
290 .npwm = 1,
291};
292
287static const struct of_device_id sun4i_pwm_dt_ids[] = { 293static const struct of_device_id sun4i_pwm_dt_ids[] = {
288 { 294 {
289 .compatible = "allwinner,sun4i-a10-pwm", 295 .compatible = "allwinner,sun4i-a10-pwm",
@@ -298,6 +304,9 @@ static const struct of_device_id sun4i_pwm_dt_ids[] = {
298 .compatible = "allwinner,sun7i-a20-pwm", 304 .compatible = "allwinner,sun7i-a20-pwm",
299 .data = &sun4i_pwm_data_a20, 305 .data = &sun4i_pwm_data_a20,
300 }, { 306 }, {
307 .compatible = "allwinner,sun8i-h3-pwm",
308 .data = &sun4i_pwm_data_h3,
309 }, {
301 /* sentinel */ 310 /* sentinel */
302 }, 311 },
303}; 312};
diff --git a/drivers/pwm/pwm-tipwmss.c b/drivers/pwm/pwm-tipwmss.c
index 829f4991c96f..7fa85a1604da 100644
--- a/drivers/pwm/pwm-tipwmss.c
+++ b/drivers/pwm/pwm-tipwmss.c
@@ -34,7 +34,6 @@ static int pwmss_probe(struct platform_device *pdev)
34 struct device_node *node = pdev->dev.of_node; 34 struct device_node *node = pdev->dev.of_node;
35 35
36 pm_runtime_enable(&pdev->dev); 36 pm_runtime_enable(&pdev->dev);
37 pm_runtime_get_sync(&pdev->dev);
38 37
39 /* Populate all the child nodes here... */ 38 /* Populate all the child nodes here... */
40 ret = of_platform_populate(node, NULL, NULL, &pdev->dev); 39 ret = of_platform_populate(node, NULL, NULL, &pdev->dev);
@@ -46,31 +45,13 @@ static int pwmss_probe(struct platform_device *pdev)
46 45
47static int pwmss_remove(struct platform_device *pdev) 46static int pwmss_remove(struct platform_device *pdev)
48{ 47{
49 pm_runtime_put_sync(&pdev->dev);
50 pm_runtime_disable(&pdev->dev); 48 pm_runtime_disable(&pdev->dev);
51 return 0; 49 return 0;
52} 50}
53 51
54#ifdef CONFIG_PM_SLEEP
55static int pwmss_suspend(struct device *dev)
56{
57 pm_runtime_put_sync(dev);
58 return 0;
59}
60
61static int pwmss_resume(struct device *dev)
62{
63 pm_runtime_get_sync(dev);
64 return 0;
65}
66#endif
67
68static SIMPLE_DEV_PM_OPS(pwmss_pm_ops, pwmss_suspend, pwmss_resume);
69
70static struct platform_driver pwmss_driver = { 52static struct platform_driver pwmss_driver = {
71 .driver = { 53 .driver = {
72 .name = "pwmss", 54 .name = "pwmss",
73 .pm = &pwmss_pm_ops,
74 .of_match_table = pwmss_of_match, 55 .of_match_table = pwmss_of_match,
75 }, 56 },
76 .probe = pwmss_probe, 57 .probe = pwmss_probe,
diff --git a/drivers/pwm/pwm-twl.c b/drivers/pwm/pwm-twl.c
index 04f76725d591..7a993b056638 100644
--- a/drivers/pwm/pwm-twl.c
+++ b/drivers/pwm/pwm-twl.c
@@ -269,6 +269,22 @@ static void twl6030_pwm_disable(struct pwm_chip *chip, struct pwm_device *pwm)
269 goto out; 269 goto out;
270 } 270 }
271 271
272 val |= TWL6030_PWM_TOGGLE(pwm->hwpwm, TWL6030_PWMXEN);
273
274 ret = twl_i2c_write_u8(TWL6030_MODULE_ID1, val, TWL6030_TOGGLE3_REG);
275 if (ret < 0) {
276 dev_err(chip->dev, "%s: Failed to disable PWM\n", pwm->label);
277 goto out;
278 }
279
280 val &= ~TWL6030_PWM_TOGGLE(pwm->hwpwm, TWL6030_PWMXEN);
281
282 ret = twl_i2c_write_u8(TWL6030_MODULE_ID1, val, TWL6030_TOGGLE3_REG);
283 if (ret < 0) {
284 dev_err(chip->dev, "%s: Failed to disable PWM\n", pwm->label);
285 goto out;
286 }
287
272 twl->twl6030_toggle3 = val; 288 twl->twl6030_toggle3 = val;
273out: 289out:
274 mutex_unlock(&twl->mutex); 290 mutex_unlock(&twl->mutex);
diff --git a/drivers/pwm/sysfs.c b/drivers/pwm/sysfs.c
index 18ed725594c3..0296d8178ae2 100644
--- a/drivers/pwm/sysfs.c
+++ b/drivers/pwm/sysfs.c
@@ -409,6 +409,24 @@ void pwmchip_sysfs_unexport(struct pwm_chip *chip)
409 } 409 }
410} 410}
411 411
412void pwmchip_sysfs_unexport_children(struct pwm_chip *chip)
413{
414 struct device *parent;
415 unsigned int i;
416
417 parent = class_find_device(&pwm_class, NULL, chip,
418 pwmchip_sysfs_match);
419 if (!parent)
420 return;
421
422 for (i = 0; i < chip->npwm; i++) {
423 struct pwm_device *pwm = &chip->pwms[i];
424
425 if (test_bit(PWMF_EXPORTED, &pwm->flags))
426 pwm_unexport_child(parent, pwm);
427 }
428}
429
412static int __init pwm_sysfs_init(void) 430static int __init pwm_sysfs_init(void)
413{ 431{
414 return class_register(&pwm_class); 432 return class_register(&pwm_class);
diff --git a/include/linux/pwm.h b/include/linux/pwm.h
index f1bbae014889..2c6c5114c089 100644
--- a/include/linux/pwm.h
+++ b/include/linux/pwm.h
@@ -641,6 +641,7 @@ static inline void pwm_remove_table(struct pwm_lookup *table, size_t num)
641#ifdef CONFIG_PWM_SYSFS 641#ifdef CONFIG_PWM_SYSFS
642void pwmchip_sysfs_export(struct pwm_chip *chip); 642void pwmchip_sysfs_export(struct pwm_chip *chip);
643void pwmchip_sysfs_unexport(struct pwm_chip *chip); 643void pwmchip_sysfs_unexport(struct pwm_chip *chip);
644void pwmchip_sysfs_unexport_children(struct pwm_chip *chip);
644#else 645#else
645static inline void pwmchip_sysfs_export(struct pwm_chip *chip) 646static inline void pwmchip_sysfs_export(struct pwm_chip *chip)
646{ 647{
@@ -649,6 +650,10 @@ static inline void pwmchip_sysfs_export(struct pwm_chip *chip)
649static inline void pwmchip_sysfs_unexport(struct pwm_chip *chip) 650static inline void pwmchip_sysfs_unexport(struct pwm_chip *chip)
650{ 651{
651} 652}
653
654static inline void pwmchip_sysfs_unexport_children(struct pwm_chip *chip)
655{
656}
652#endif /* CONFIG_PWM_SYSFS */ 657#endif /* CONFIG_PWM_SYSFS */
653 658
654#endif /* __LINUX_PWM_H */ 659#endif /* __LINUX_PWM_H */