aboutsummaryrefslogtreecommitdiffstats
path: root/arch/arm/plat-mxc/pwm.c
diff options
context:
space:
mode:
Diffstat (limited to 'arch/arm/plat-mxc/pwm.c')
-rw-r--r--arch/arm/plat-mxc/pwm.c24
1 files changed, 19 insertions, 5 deletions
diff --git a/arch/arm/plat-mxc/pwm.c b/arch/arm/plat-mxc/pwm.c
index 7a61ef8f471..8d4fdb0f1c3 100644
--- a/arch/arm/plat-mxc/pwm.c
+++ b/arch/arm/plat-mxc/pwm.c
@@ -32,6 +32,9 @@
32#define MX3_PWMSAR 0x0C /* PWM Sample Register */ 32#define MX3_PWMSAR 0x0C /* PWM Sample Register */
33#define MX3_PWMPR 0x10 /* PWM Period Register */ 33#define MX3_PWMPR 0x10 /* PWM Period Register */
34#define MX3_PWMCR_PRESCALER(x) (((x - 1) & 0xFFF) << 4) 34#define MX3_PWMCR_PRESCALER(x) (((x - 1) & 0xFFF) << 4)
35#define MX3_PWMCR_DOZEEN (1 << 24)
36#define MX3_PWMCR_WAITEN (1 << 23)
37#define MX3_PWMCR_DBGEN (1 << 22)
35#define MX3_PWMCR_CLKSRC_IPG_HIGH (2 << 16) 38#define MX3_PWMCR_CLKSRC_IPG_HIGH (2 << 16)
36#define MX3_PWMCR_CLKSRC_IPG (1 << 16) 39#define MX3_PWMCR_CLKSRC_IPG (1 << 16)
37#define MX3_PWMCR_EN (1 << 0) 40#define MX3_PWMCR_EN (1 << 0)
@@ -74,10 +77,21 @@ int pwm_config(struct pwm_device *pwm, int duty_ns, int period_ns)
74 do_div(c, period_ns); 77 do_div(c, period_ns);
75 duty_cycles = c; 78 duty_cycles = c;
76 79
80 /*
81 * according to imx pwm RM, the real period value should be
82 * PERIOD value in PWMPR plus 2.
83 */
84 if (period_cycles > 2)
85 period_cycles -= 2;
86 else
87 period_cycles = 0;
88
77 writel(duty_cycles, pwm->mmio_base + MX3_PWMSAR); 89 writel(duty_cycles, pwm->mmio_base + MX3_PWMSAR);
78 writel(period_cycles, pwm->mmio_base + MX3_PWMPR); 90 writel(period_cycles, pwm->mmio_base + MX3_PWMPR);
79 91
80 cr = MX3_PWMCR_PRESCALER(prescale) | MX3_PWMCR_EN; 92 cr = MX3_PWMCR_PRESCALER(prescale) |
93 MX3_PWMCR_DOZEEN | MX3_PWMCR_WAITEN |
94 MX3_PWMCR_DBGEN | MX3_PWMCR_EN;
81 95
82 if (cpu_is_mx25()) 96 if (cpu_is_mx25())
83 cr |= MX3_PWMCR_CLKSRC_IPG; 97 cr |= MX3_PWMCR_CLKSRC_IPG;
@@ -214,14 +228,14 @@ static int __devinit mxc_pwm_probe(struct platform_device *pdev)
214 goto err_free_clk; 228 goto err_free_clk;
215 } 229 }
216 230
217 r = request_mem_region(r->start, r->end - r->start + 1, pdev->name); 231 r = request_mem_region(r->start, resource_size(r), pdev->name);
218 if (r == NULL) { 232 if (r == NULL) {
219 dev_err(&pdev->dev, "failed to request memory resource\n"); 233 dev_err(&pdev->dev, "failed to request memory resource\n");
220 ret = -EBUSY; 234 ret = -EBUSY;
221 goto err_free_clk; 235 goto err_free_clk;
222 } 236 }
223 237
224 pwm->mmio_base = ioremap(r->start, r->end - r->start + 1); 238 pwm->mmio_base = ioremap(r->start, resource_size(r));
225 if (pwm->mmio_base == NULL) { 239 if (pwm->mmio_base == NULL) {
226 dev_err(&pdev->dev, "failed to ioremap() registers\n"); 240 dev_err(&pdev->dev, "failed to ioremap() registers\n");
227 ret = -ENODEV; 241 ret = -ENODEV;
@@ -236,7 +250,7 @@ static int __devinit mxc_pwm_probe(struct platform_device *pdev)
236 return 0; 250 return 0;
237 251
238err_free_mem: 252err_free_mem:
239 release_mem_region(r->start, r->end - r->start + 1); 253 release_mem_region(r->start, resource_size(r));
240err_free_clk: 254err_free_clk:
241 clk_put(pwm->clk); 255 clk_put(pwm->clk);
242err_free: 256err_free:
@@ -260,7 +274,7 @@ static int __devexit mxc_pwm_remove(struct platform_device *pdev)
260 iounmap(pwm->mmio_base); 274 iounmap(pwm->mmio_base);
261 275
262 r = platform_get_resource(pdev, IORESOURCE_MEM, 0); 276 r = platform_get_resource(pdev, IORESOURCE_MEM, 0);
263 release_mem_region(r->start, r->end - r->start + 1); 277 release_mem_region(r->start, resource_size(r));
264 278
265 clk_put(pwm->clk); 279 clk_put(pwm->clk);
266 280