diff options
Diffstat (limited to 'arch/arm/plat-mxc/pwm.c')
-rw-r--r-- | arch/arm/plat-mxc/pwm.c | 24 |
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 | ||
238 | err_free_mem: | 252 | err_free_mem: |
239 | release_mem_region(r->start, r->end - r->start + 1); | 253 | release_mem_region(r->start, resource_size(r)); |
240 | err_free_clk: | 254 | err_free_clk: |
241 | clk_put(pwm->clk); | 255 | clk_put(pwm->clk); |
242 | err_free: | 256 | err_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 | ||