]> Gitweb @ Texas Instruments - Open Source Git Repositories - git.TI.com/gitweb - sitara-epos/sitara-epos-kernel.git/blob - drivers/pwm/ecap.c
cc2ed19fbee4531e0f2f8074dc876d8a9e00a769
[sitara-epos/sitara-epos-kernel.git] / drivers / pwm / ecap.c
1 /*
2  * eCAP driver for PWM output generation
3  *
4  * Copyright (C) 2010 Texas Instruments Incorporated - http://www.ti.com/
5  *
6  * This program is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU General Public License as
8  * published by the Free Software Foundation version 2.
9  *
10  * This program is distributed .as is. WITHOUT ANY WARRANTY of any
11  * kind, whether express or implied; without even the implied warranty
12  * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13  * GNU General Public License for more details.
14  */
15 #include <linux/module.h>
16 #include <linux/kernel.h>
17 #include <linux/platform_device.h>
18 #include <linux/err.h>
19 #include <linux/clk.h>
20 #include <linux/io.h>
21 #include <linux/pwm/pwm.h>
22 #include <linux/slab.h>
24 #include <plat/clock.h>
25 #include <plat/config_pwm.h>
27 #define TIMER_CTR_REG                   0x0
28 #define CAPTURE_2_REG                   0x0c
29 #define CAPTURE_3_REG                   0x10
30 #define CAPTURE_4_REG                   0x14
31 #define CAPTURE_CTRL2_REG               0x2A
33 #define ECTRL2_SYNCOSEL_MASK            (0x03 << 6)
35 #define ECTRL2_MDSL_ECAP                BIT(9)
36 #define ECTRL2_CTRSTP_FREERUN           BIT(4)
37 #define ECTRL2_PLSL_LOW                 BIT(10)
38 #define ECTRL2_SYNC_EN                  BIT(5)
40 struct ecap_pwm {
41         struct pwm_device pwm;
42         struct pwm_device_ops ops;
43         spinlock_t      lock;
44         struct clk      *clk;
45         int     clk_enabled;
46         void __iomem    *mmio_base;
47         u8 version;
48 };
50 static inline struct ecap_pwm *to_ecap_pwm(const struct pwm_device *p)
51 {
52         return pwm_get_drvdata(p);
53 }
55 static int ecap_pwm_stop(struct pwm_device *p)
56 {
57         unsigned long flags;
58         struct ecap_pwm *ep = to_ecap_pwm(p);
60         clk_enable(ep->clk);
62         spin_lock_irqsave(&ep->lock, flags);
63         __raw_writew(__raw_readw(ep->mmio_base + CAPTURE_CTRL2_REG) &
64                 ~BIT(4), ep->mmio_base + CAPTURE_CTRL2_REG);
65         spin_unlock_irqrestore(&ep->lock, flags);
67         clk_disable(ep->clk);
68         if (ep->clk_enabled) {
69                 clk_disable(ep->clk);
70                 ep->clk_enabled = 0;
71         }
72         clear_bit(FLAG_RUNNING, &p->flags);
74         return 0;
75 }
77 static int ecap_pwm_start(struct pwm_device *p)
78 {
79         int ret = 0;
80         unsigned long flags;
81         struct ecap_pwm *ep = to_ecap_pwm(p);
83         clk_enable(ep->clk);
84         spin_lock_irqsave(&ep->lock, flags);
85         __raw_writew(__raw_readw(ep->mmio_base + CAPTURE_CTRL2_REG) |
86                 BIT(4), ep->mmio_base + CAPTURE_CTRL2_REG);
87         spin_unlock_irqrestore(&ep->lock, flags);
89         clk_disable(ep->clk);
90         if (!ep->clk_enabled) {
91                 ret = clk_enable(ep->clk);
92                 if (ret)
93                         return ret;
94                 ep->clk_enabled = 1;
95         }
96         set_bit(FLAG_RUNNING, &p->flags);
98         return ret;
99 }
101 static int ecap_pwm_set_polarity(struct pwm_device *p, char pol)
103         unsigned long flags;
104         struct ecap_pwm *ep = to_ecap_pwm(p);
106         clk_enable(ep->clk);
108         spin_lock_irqsave(&ep->lock, flags);
109          __raw_writew((__raw_readw(ep->mmio_base + CAPTURE_CTRL2_REG) &
110                  ~BIT(10)) | (!pol << 10), ep->mmio_base + CAPTURE_CTRL2_REG);
111         spin_unlock_irqrestore(&ep->lock, flags);
113         clk_disable(ep->clk);
114         return 0;
117 static int ecap_pwm_config_period(struct pwm_device *p)
119         unsigned long flags;
120         struct ecap_pwm *ep = to_ecap_pwm(p);
122          clk_enable(ep->clk);
124         spin_lock_irqsave(&ep->lock, flags);
125         __raw_writel((p->period_ticks) - 1, ep->mmio_base + CAPTURE_3_REG);
126         __raw_writew(ECTRL2_MDSL_ECAP | ECTRL2_SYNCOSEL_MASK |
127                  ECTRL2_CTRSTP_FREERUN, ep->mmio_base + CAPTURE_CTRL2_REG);
128         spin_unlock_irqrestore(&ep->lock, flags);
130         clk_disable(ep->clk);
131         return 0;
134 static int ecap_pwm_config_duty(struct pwm_device *p)
136         unsigned long flags;
137         struct ecap_pwm *ep = to_ecap_pwm(p);
139         clk_enable(ep->clk);
141         spin_lock_irqsave(&ep->lock, flags);
142         __raw_writew(ECTRL2_MDSL_ECAP | ECTRL2_SYNCOSEL_MASK |
143          ECTRL2_CTRSTP_FREERUN, ep->mmio_base + CAPTURE_CTRL2_REG);
144         if (p->duty_ticks > 0) {
145                 __raw_writel(p->duty_ticks, ep->mmio_base + CAPTURE_4_REG);
146         } else {
147         __raw_writel(p->duty_ticks, ep->mmio_base + CAPTURE_2_REG);
148         __raw_writel(0, ep->mmio_base + TIMER_CTR_REG);
149         }
150         spin_unlock_irqrestore(&ep->lock, flags);
152         clk_disable(ep->clk);
153         return 0;
156 static int ecap_pwm_config(struct pwm_device *p,
157                                 struct pwm_config *c)
159         int ret = 0;
160         switch (c->config_mask) {
162         case BIT(PWM_CONFIG_DUTY_TICKS):
163                 p->duty_ticks = c->duty_ticks;
164                 ret = ecap_pwm_config_duty(p);
165                 break;
167         case BIT(PWM_CONFIG_PERIOD_TICKS):
168                 p->period_ticks = c->period_ticks;
169                 ret = ecap_pwm_config_period(p);
170                 break;
172         case BIT(PWM_CONFIG_POLARITY):
173                 ret = ecap_pwm_set_polarity(p, c->polarity);
174                 break;
176         case BIT(PWM_CONFIG_START):
177                 ret = ecap_pwm_start(p);
178                 break;
180         case BIT(PWM_CONFIG_STOP):
181                 ret = ecap_pwm_stop(p);
182                 break;
183         }
185         return ret;
188 static int ecap_pwm_request(struct pwm_device *p)
190         struct ecap_pwm *ep = to_ecap_pwm(p);
192         p->tick_hz = clk_get_rate(ep->clk);
193         return 0;
196 static int ecap_frequency_transition_cb(struct pwm_device *p)
198         struct ecap_pwm *ep = to_ecap_pwm(p);
199         unsigned long duty_ns, rate;
201         rate = clk_get_rate(ep->clk);
202         if (rate == p->tick_hz)
203                 return 0;
204         p->tick_hz = rate;
206         duty_ns = p->duty_ns;
207         if (pwm_is_running(p)) {
208                 pwm_stop(p);
209                 pwm_set_duty_ns(p, 0);
210                 pwm_set_period_ns(p, p->period_ns);
211                 pwm_set_duty_ns(p, duty_ns);
212                 pwm_start(p);
213         } else {
214                 pwm_set_duty_ns(p, 0);
215                 pwm_set_period_ns(p, p->period_ns);
216                 pwm_set_duty_ns(p, duty_ns);
217         }
218                 return 0;
221 static int ecap_probe(struct platform_device *pdev)
223         struct ecap_pwm *ep = NULL;
224         struct resource *r;
225         int ret = 0;
226         int val;
227         char con_id[PWM_CON_ID_STRING_LENGTH] = "epwmss";
228         struct pwmss_platform_data *pdata = (&pdev->dev)->platform_data;
230         ep = kzalloc(sizeof(*ep), GFP_KERNEL);
232         if (!ep) {
233                 dev_err(&pdev->dev, "failed to allocate memory\n");
234                 ret = -ENOMEM;
235                 goto err_mem_failure;
236         }
238         ep->version = pdata->version;
240         if (ep->version == PWM_VERSION_1) {
241                 sprintf(con_id, "%s%d_%s", con_id, pdev->id, "fck");
242                 ep->clk = clk_get(&pdev->dev, con_id);
243         } else
244                 ep->clk = clk_get(&pdev->dev, "ecap");
246         if (IS_ERR(ep->clk)) {
247                 ret = PTR_ERR(ep->clk);
248                 goto err_clock_failure;
249         }
251         if (ep->version == PWM_VERSION_1) {
252                 down(&pdata->config_semaphore);
253                 r = platform_get_resource(pdev, IORESOURCE_MEM, 0);
255                 if (!r) {
256                         dev_err(&pdev->dev, "no memory resource defined\n");
257                         ret = -ENOMEM;
258                         up(&pdata->config_semaphore);
259                         goto err_resource_mem_failure;
260                 }
262                 r = request_mem_region(r->start, resource_size(r), pdev->name);
264                 if (!r) {
266                         if (pdata->config_mem_base) {
267                                 goto set_bit;
268                         } else {
269                                 dev_err(&pdev->dev,
270                                         "failed to request memory resource\n");
271                                 ret = -EBUSY;
272                                 up(&pdata->config_semaphore);
273                                 goto err_request_mem_failure;
274                         }
275                 }
277                 pdata->config_mem_base = ioremap(r->start, resource_size(r));
279                 if (!pdata->config_mem_base) {
281                         dev_err(&pdev->dev, "failed to ioremap() registers\n");
282                         ret = -ENODEV;
283                         up(&pdata->config_semaphore);
284                         goto err_free_mem_config;
285                 }
287 set_bit:
288                 pdata->pwmss_module_usage_count++;
289                 clk_enable(ep->clk);
290                 val = __raw_readw(pdata->config_mem_base + PWMSS_CLKCONFIG);
291                 val |= BIT(ECAP_CLK_EN);
292                 __raw_writew(val, pdata->config_mem_base + PWMSS_CLKCONFIG);
293                 clk_disable(ep->clk);
294                 up(&pdata->config_semaphore);
295         }
297         spin_lock_init(&ep->lock);
298         ep->ops.config = ecap_pwm_config;
299         ep->ops.request = ecap_pwm_request;
300         ep->ops.freq_transition_notifier_cb = ecap_frequency_transition_cb;
302         if (ep->version == PWM_VERSION_1)
303                 r = platform_get_resource(pdev, IORESOURCE_MEM, 1);
304         else
305                 r = platform_get_resource(pdev, IORESOURCE_MEM, 0);
307         if (!r) {
308                 dev_err(&pdev->dev, "no memory resource defined\n");
309                 ret = -ENODEV;
310                 goto err_resource_mem2_failiure;
311         }
313         r = request_mem_region(r->start, resource_size(r), pdev->name);
314         if (!r) {
315                 dev_err(&pdev->dev, "failed to request memory resource\n");
316                 ret = -EBUSY;
317                 goto err_request_mem2_failure;
318         }
320         ep->mmio_base = ioremap(r->start, resource_size(r));
321         if (!ep->mmio_base) {
322                 dev_err(&pdev->dev, "failed to ioremap() registers\n");
323                 ret = -ENODEV;
324                 goto err_free_mem2;
325         }
327         ep->pwm.ops = &ep->ops;
328         pwm_set_drvdata(&ep->pwm, ep);
329         ret =  pwm_register(&ep->pwm, &pdev->dev, -1);
330         platform_set_drvdata(pdev, ep);
331         return 0;
333 err_free_mem2:
334         release_mem_region(r->start, resource_size(r));
335 err_request_mem2_failure:
336 err_resource_mem2_failiure:
337         if (ep->version == PWM_VERSION_1) {
338                 down(&pdata->config_semaphore);
339                 pdata->pwmss_module_usage_count--;
341                 if (!pdata->pwmss_module_usage_count) {
342                         iounmap(pdata->config_mem_base);
343                         pdata->config_mem_base = NULL;
344                 }
345                 up(&pdata->config_semaphore);
346         }
347 err_free_mem_config:
348         if (ep->version == PWM_VERSION_1) {
349                 r = platform_get_resource(pdev, IORESOURCE_MEM, 0);
350                 release_mem_region(r->start, resource_size(r));
351         }
352 err_request_mem_failure:
353 err_resource_mem_failure:
354         clk_put(ep->clk);
355 err_clock_failure:
356         kfree(ep);
357 err_mem_failure:
358         return ret;
361 #ifdef CONFIG_PM
362 static int ecap_suspend(struct platform_device *pdev, pm_message_t state)
364         struct ecap_pwm *ep = platform_get_drvdata(pdev);
366         if (ep->clk->usecount > 0)
367                 clk_disable(ep->clk);
369         return 0;
372 static int ecap_resume(struct platform_device *pdev)
374         struct ecap_pwm *ep = platform_get_drvdata(pdev);
376         clk_enable(ep->clk);
378         return 0;
381 #else
382 #define ecap_suspend NULL
383 #define ecap_resume NULL
384 #endif
386 static int __devexit ecap_remove(struct platform_device *pdev)
388         struct ecap_pwm *ep = platform_get_drvdata(pdev);
389         struct resource *r;
390         struct pwmss_platform_data *pdata;
391         int val;
393         if (ep->version == PWM_VERSION_1) {
394                 pdata = (&pdev->dev)->platform_data;
395                 down(&pdata->config_semaphore);
396                 pdata->pwmss_module_usage_count--;
397                 val = __raw_readw(pdata->config_mem_base + PWMSS_CLKCONFIG);
398                 val &= ~BIT(ECAP_CLK_EN);
399                 __raw_writew(val, pdata->config_mem_base + PWMSS_CLKCONFIG);
401                 if (!pdata->pwmss_module_usage_count) {
402                         iounmap(pdata->config_mem_base);
403                         pdata->config_mem_base = NULL;
404                         r = platform_get_resource(pdev, IORESOURCE_MEM, 0);
405                         release_mem_region(r->start, resource_size(r));
406                 }
407                 up(&pdata->config_semaphore);
408         }
410         pwm_unregister(&ep->pwm);
411         iounmap(ep->mmio_base);
413         if (ep->version == PWM_VERSION_1)
414                 r = platform_get_resource(pdev, IORESOURCE_MEM, 1);
415         else
416                 r = platform_get_resource(pdev, IORESOURCE_MEM, 0);
417         release_mem_region(r->start, resource_size(r));
418         platform_set_drvdata(pdev, NULL);
419         clk_put(ep->clk);
420         kfree(ep);
422         return 0;
425 static struct platform_driver ecap_driver = {
426         .driver = {
427                 .name   = "ecap",
428                 .owner  = THIS_MODULE,
429         },
430         .probe          = ecap_probe,
431         .remove         = __devexit_p(ecap_remove),
432         .suspend        = ecap_suspend,
433         .resume         = ecap_resume,
434 };
436 static int __init ecap_init(void)
438         return platform_driver_register(&ecap_driver);
441 static void __exit ecap_exit(void)
443         platform_driver_unregister(&ecap_driver);
446 module_init(ecap_init);
447 module_exit(ecap_exit);
449 MODULE_AUTHOR("Texas Instruments");
450 MODULE_DESCRIPTION("Driver for Davinci eCAP peripheral");
451 MODULE_LICENSE("GPL v2");
452 MODULE_ALIAS("platform:ecap");