diff options
author | Thierry Reding <thierry.reding@avionic-design.de> | 2012-08-31 02:29:24 -0400 |
---|---|---|
committer | Thierry Reding <thierry.reding@avionic-design.de> | 2012-10-05 14:56:41 -0400 |
commit | 79c11b6fa0b225ac165e79e821d50e70f563645f (patch) | |
tree | 05a7b6a2a87f05780b2a12a2e821c44336d73e75 /drivers/pwm | |
parent | 5384e27317016bd30aa7a7a7513f76ce7caa3b09 (diff) |
pwm: Move PUV3 PWM driver to PWM framework
This commit moves the driver to drivers/pwm and converts it to the new
PWM framework.
Signed-off-by: Thierry Reding <thierry.reding@avionic-design.de>
Tested-by: Qin Rui <qinrui@mprc.pku.edu.cn>
Acked-by: Guan Xuetao <gxt@mprc.pku.edu.cn>
Diffstat (limited to 'drivers/pwm')
-rw-r--r-- | drivers/pwm/Kconfig | 11 | ||||
-rw-r--r-- | drivers/pwm/Makefile | 1 | ||||
-rw-r--r-- | drivers/pwm/pwm-puv3.c | 161 |
3 files changed, 172 insertions, 1 deletions
diff --git a/drivers/pwm/Kconfig b/drivers/pwm/Kconfig index 99a738182bf5..d954c72e242e 100644 --- a/drivers/pwm/Kconfig +++ b/drivers/pwm/Kconfig | |||
@@ -1,6 +1,6 @@ | |||
1 | menuconfig PWM | 1 | menuconfig PWM |
2 | bool "Pulse-Width Modulation (PWM) Support" | 2 | bool "Pulse-Width Modulation (PWM) Support" |
3 | depends on !MACH_JZ4740 && !PUV3_PWM | 3 | depends on !MACH_JZ4740 |
4 | help | 4 | help |
5 | Generic Pulse-Width Modulation (PWM) support. | 5 | Generic Pulse-Width Modulation (PWM) support. |
6 | 6 | ||
@@ -76,6 +76,15 @@ config PWM_MXS | |||
76 | To compile this driver as a module, choose M here: the module | 76 | To compile this driver as a module, choose M here: the module |
77 | will be called pwm-mxs. | 77 | will be called pwm-mxs. |
78 | 78 | ||
79 | config PWM_PUV3 | ||
80 | tristate "PKUnity NetBook-0916 PWM support" | ||
81 | depends on ARCH_PUV3 | ||
82 | help | ||
83 | Generic PWM framework driver for PKUnity NetBook-0916. | ||
84 | |||
85 | To compile this driver as a module, choose M here: the module | ||
86 | will be called pwm-puv3. | ||
87 | |||
79 | config PWM_PXA | 88 | config PWM_PXA |
80 | tristate "PXA PWM support" | 89 | tristate "PXA PWM support" |
81 | depends on ARCH_PXA | 90 | depends on ARCH_PXA |
diff --git a/drivers/pwm/Makefile b/drivers/pwm/Makefile index bebc6ff904b9..360aad8fa3ae 100644 --- a/drivers/pwm/Makefile +++ b/drivers/pwm/Makefile | |||
@@ -4,6 +4,7 @@ obj-$(CONFIG_PWM_BFIN) += pwm-bfin.o | |||
4 | obj-$(CONFIG_PWM_IMX) += pwm-imx.o | 4 | obj-$(CONFIG_PWM_IMX) += pwm-imx.o |
5 | obj-$(CONFIG_PWM_LPC32XX) += pwm-lpc32xx.o | 5 | obj-$(CONFIG_PWM_LPC32XX) += pwm-lpc32xx.o |
6 | obj-$(CONFIG_PWM_MXS) += pwm-mxs.o | 6 | obj-$(CONFIG_PWM_MXS) += pwm-mxs.o |
7 | obj-$(CONFIG_PWM_PUV3) += pwm-puv3.o | ||
7 | obj-$(CONFIG_PWM_PXA) += pwm-pxa.o | 8 | obj-$(CONFIG_PWM_PXA) += pwm-pxa.o |
8 | obj-$(CONFIG_PWM_SAMSUNG) += pwm-samsung.o | 9 | obj-$(CONFIG_PWM_SAMSUNG) += pwm-samsung.o |
9 | obj-$(CONFIG_PWM_TEGRA) += pwm-tegra.o | 10 | obj-$(CONFIG_PWM_TEGRA) += pwm-tegra.o |
diff --git a/drivers/pwm/pwm-puv3.c b/drivers/pwm/pwm-puv3.c new file mode 100644 index 000000000000..2a93f37c46ad --- /dev/null +++ b/drivers/pwm/pwm-puv3.c | |||
@@ -0,0 +1,161 @@ | |||
1 | /* | ||
2 | * linux/arch/unicore32/kernel/pwm.c | ||
3 | * | ||
4 | * Code specific to PKUnity SoC and UniCore ISA | ||
5 | * | ||
6 | * Maintained by GUAN Xue-tao <gxt@mprc.pku.edu.cn> | ||
7 | * Copyright (C) 2001-2010 Guan Xuetao | ||
8 | * | ||
9 | * This program is free software; you can redistribute it and/or modify | ||
10 | * it under the terms of the GNU General Public License version 2 as | ||
11 | * published by the Free Software Foundation. | ||
12 | */ | ||
13 | |||
14 | #include <linux/module.h> | ||
15 | #include <linux/kernel.h> | ||
16 | #include <linux/platform_device.h> | ||
17 | #include <linux/slab.h> | ||
18 | #include <linux/err.h> | ||
19 | #include <linux/clk.h> | ||
20 | #include <linux/io.h> | ||
21 | #include <linux/pwm.h> | ||
22 | |||
23 | #include <asm/div64.h> | ||
24 | #include <mach/hardware.h> | ||
25 | |||
26 | struct puv3_pwm_chip { | ||
27 | struct pwm_chip chip; | ||
28 | void __iomem *base; | ||
29 | struct clk *clk; | ||
30 | bool enabled; | ||
31 | }; | ||
32 | |||
33 | static inline struct puv3_pwm_chip *to_puv3(struct pwm_chip *chip) | ||
34 | { | ||
35 | return container_of(chip, struct puv3_pwm_chip, chip); | ||
36 | } | ||
37 | |||
38 | /* | ||
39 | * period_ns = 10^9 * (PRESCALE + 1) * (PV + 1) / PWM_CLK_RATE | ||
40 | * duty_ns = 10^9 * (PRESCALE + 1) * DC / PWM_CLK_RATE | ||
41 | */ | ||
42 | static int puv3_pwm_config(struct pwm_chip *chip, struct pwm_device *pwm, | ||
43 | int duty_ns, int period_ns) | ||
44 | { | ||
45 | unsigned long period_cycles, prescale, pv, dc; | ||
46 | struct puv3_pwm_chip *puv3 = to_puv3(chip); | ||
47 | unsigned long long c; | ||
48 | |||
49 | c = clk_get_rate(puv3->clk); | ||
50 | c = c * period_ns; | ||
51 | do_div(c, 1000000000); | ||
52 | period_cycles = c; | ||
53 | |||
54 | if (period_cycles < 1) | ||
55 | period_cycles = 1; | ||
56 | |||
57 | prescale = (period_cycles - 1) / 1024; | ||
58 | pv = period_cycles / (prescale + 1) - 1; | ||
59 | |||
60 | if (prescale > 63) | ||
61 | return -EINVAL; | ||
62 | |||
63 | if (duty_ns == period_ns) | ||
64 | dc = OST_PWMDCCR_FDCYCLE; | ||
65 | else | ||
66 | dc = (pv + 1) * duty_ns / period_ns; | ||
67 | |||
68 | /* | ||
69 | * NOTE: the clock to PWM has to be enabled first | ||
70 | * before writing to the registers | ||
71 | */ | ||
72 | clk_prepare_enable(puv3->clk); | ||
73 | |||
74 | writel(prescale, puv3->base + OST_PWM_PWCR); | ||
75 | writel(pv - dc, puv3->base + OST_PWM_DCCR); | ||
76 | writel(pv, puv3->base + OST_PWM_PCR); | ||
77 | |||
78 | clk_disable_unprepare(puv3->clk); | ||
79 | |||
80 | return 0; | ||
81 | } | ||
82 | |||
83 | static int puv3_pwm_enable(struct pwm_chip *chip, struct pwm_device *pwm) | ||
84 | { | ||
85 | struct puv3_pwm_chip *puv3 = to_puv3(chip); | ||
86 | |||
87 | return clk_prepare_enable(puv3->clk); | ||
88 | } | ||
89 | |||
90 | static void puv3_pwm_disable(struct pwm_chip *chip, struct pwm_device *pwm) | ||
91 | { | ||
92 | struct puv3_pwm_chip *puv3 = to_puv3(chip); | ||
93 | |||
94 | clk_disable_unprepare(puv3->clk); | ||
95 | } | ||
96 | |||
97 | static const struct pwm_ops puv3_pwm_ops = { | ||
98 | .config = puv3_pwm_config, | ||
99 | .enable = puv3_pwm_enable, | ||
100 | .disable = puv3_pwm_disable, | ||
101 | .owner = THIS_MODULE, | ||
102 | }; | ||
103 | |||
104 | static int __devinit pwm_probe(struct platform_device *pdev) | ||
105 | { | ||
106 | struct puv3_pwm_chip *puv3; | ||
107 | struct resource *r; | ||
108 | int ret; | ||
109 | |||
110 | puv3 = devm_kzalloc(&pdev->dev, sizeof(*puv3), GFP_KERNEL); | ||
111 | if (puv3 == NULL) { | ||
112 | dev_err(&pdev->dev, "failed to allocate memory\n"); | ||
113 | return -ENOMEM; | ||
114 | } | ||
115 | |||
116 | puv3->clk = devm_clk_get(&pdev->dev, "OST_CLK"); | ||
117 | if (IS_ERR(puv3->clk)) | ||
118 | return PTR_ERR(puv3->clk); | ||
119 | |||
120 | r = platform_get_resource(pdev, IORESOURCE_MEM, 0); | ||
121 | if (r == NULL) { | ||
122 | dev_err(&pdev->dev, "no memory resource defined\n"); | ||
123 | return -ENODEV; | ||
124 | } | ||
125 | |||
126 | puv3->base = devm_request_and_ioremap(&pdev->dev, r); | ||
127 | if (puv3->base == NULL) | ||
128 | return -EADDRNOTAVAIL; | ||
129 | |||
130 | puv3->chip.dev = &pdev->dev; | ||
131 | puv3->chip.ops = &puv3_pwm_ops; | ||
132 | puv3->chip.base = -1; | ||
133 | puv3->chip.npwm = 1; | ||
134 | |||
135 | ret = pwmchip_add(&puv3->chip); | ||
136 | if (ret < 0) { | ||
137 | dev_err(&pdev->dev, "pwmchip_add() failed: %d\n", ret); | ||
138 | return ret; | ||
139 | } | ||
140 | |||
141 | platform_set_drvdata(pdev, puv3); | ||
142 | return 0; | ||
143 | } | ||
144 | |||
145 | static int __devexit pwm_remove(struct platform_device *pdev) | ||
146 | { | ||
147 | struct puv3_pwm_chip *puv3 = platform_get_drvdata(pdev); | ||
148 | |||
149 | return pwmchip_remove(&puv3->chip); | ||
150 | } | ||
151 | |||
152 | static struct platform_driver puv3_pwm_driver = { | ||
153 | .driver = { | ||
154 | .name = "PKUnity-v3-PWM", | ||
155 | }, | ||
156 | .probe = pwm_probe, | ||
157 | .remove = __devexit_p(pwm_remove), | ||
158 | }; | ||
159 | module_platform_driver(puv3_pwm_driver); | ||
160 | |||
161 | MODULE_LICENSE("GPL v2"); | ||