eCAP:PWM: Add device driver support for eCAP module
[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>
26 #define TIMER_CTR_REG                   0x0
27 #define CAPTURE_2_REG                   0x0c
28 #define CAPTURE_3_REG                   0x10
29 #define CAPTURE_4_REG                   0x14
30 #define CAPTURE_CTRL2_REG               0x2A
32 #define ECTRL2_SYNCOSEL_MASK            (0x03 << 6)
34 #define ECTRL2_MDSL_ECAP                BIT(9)
35 #define ECTRL2_CTRSTP_FREERUN           BIT(4)
36 #define ECTRL2_PLSL_LOW                 BIT(10)
37 #define ECTRL2_SYNC_EN                  BIT(5)
39 struct ecap_pwm {
40         struct pwm_device pwm;
41         struct pwm_device_ops ops;
42         spinlock_t      lock;
43         struct clk      *clk;
44         int     clk_enabled;
45         void __iomem    *mmio_base;
46 };
48 static inline struct ecap_pwm *to_ecap_pwm(const struct pwm_device *p)
49 {
50         return pwm_get_drvdata(p);
51 }
53 static int ecap_pwm_stop(struct pwm_device *p)
54 {
55         unsigned long flags;
56         struct ecap_pwm *ep = to_ecap_pwm(p);
58         clk_enable(ep->clk);
60         spin_lock_irqsave(&ep->lock, flags);
61         __raw_writew(__raw_readw(ep->mmio_base + CAPTURE_CTRL2_REG) &
62                 ~BIT(4), ep->mmio_base + CAPTURE_CTRL2_REG);
63         spin_unlock_irqrestore(&ep->lock, flags);
65         clk_disable(ep->clk);
66         if (ep->clk_enabled) {
67                 clk_disable(ep->clk);
68                 ep->clk_enabled = 0;
69         }
70         clear_bit(FLAG_RUNNING, &p->flags);
72         return 0;
73 }
75 static int ecap_pwm_start(struct pwm_device *p)
76 {
77         int ret = 0;
78         unsigned long flags;
79         struct ecap_pwm *ep = to_ecap_pwm(p);
81         clk_enable(ep->clk);
82         spin_lock_irqsave(&ep->lock, flags);
83         __raw_writew(__raw_readw(ep->mmio_base + CAPTURE_CTRL2_REG) |
84                 BIT(4), ep->mmio_base + CAPTURE_CTRL2_REG);
85         spin_unlock_irqrestore(&ep->lock, flags);
87         clk_disable(ep->clk);
88         if (!ep->clk_enabled) {
89                 ret = clk_enable(ep->clk);
90                 if (ret)
91                         return ret;
92                 ep->clk_enabled = 1;
93         }
94         set_bit(FLAG_RUNNING, &p->flags);
96         return ret;
97 }
99 static int ecap_pwm_set_polarity(struct pwm_device *p, char pol)
101         unsigned long flags;
102         struct ecap_pwm *ep = to_ecap_pwm(p);
104         clk_enable(ep->clk);
106         spin_lock_irqsave(&ep->lock, flags);
107          __raw_writew((__raw_readw(ep->mmio_base + CAPTURE_CTRL2_REG) &
108                  ~BIT(10)) | (!pol << 10), ep->mmio_base + CAPTURE_CTRL2_REG);
109         spin_unlock_irqrestore(&ep->lock, flags);
111         clk_disable(ep->clk);
112         return 0;
115 static int ecap_pwm_config_period(struct pwm_device *p)
117         unsigned long flags;
118         struct ecap_pwm *ep = to_ecap_pwm(p);
120          clk_enable(ep->clk);
122         spin_lock_irqsave(&ep->lock, flags);
123         __raw_writel((p->period_ticks) - 1, ep->mmio_base + CAPTURE_3_REG);
124         __raw_writew(ECTRL2_MDSL_ECAP | ECTRL2_SYNCOSEL_MASK |
125                  ECTRL2_CTRSTP_FREERUN, ep->mmio_base + CAPTURE_CTRL2_REG);
126         spin_unlock_irqrestore(&ep->lock, flags);
128         clk_disable(ep->clk);
129         return 0;
132 static int ecap_pwm_config_duty(struct pwm_device *p)
134         unsigned long flags;
135         struct ecap_pwm *ep = to_ecap_pwm(p);
137         clk_enable(ep->clk);
139         spin_lock_irqsave(&ep->lock, flags);
140         __raw_writew(ECTRL2_MDSL_ECAP | ECTRL2_SYNCOSEL_MASK |
141          ECTRL2_CTRSTP_FREERUN, ep->mmio_base + CAPTURE_CTRL2_REG);
142         if (p->duty_ticks > 0) {
143                 __raw_writel(p->duty_ticks, ep->mmio_base + CAPTURE_4_REG);
144         } else {
145         __raw_writel(p->duty_ticks, ep->mmio_base + CAPTURE_2_REG);
146         __raw_writel(0, ep->mmio_base + TIMER_CTR_REG);
147         }
148         spin_unlock_irqrestore(&ep->lock, flags);
150         clk_disable(ep->clk);
151         return 0;
154 static int ecap_pwm_config(struct pwm_device *p,
155                                 struct pwm_config *c)
157         int ret = 0;
158         switch (c->config_mask) {
160         case BIT(PWM_CONFIG_DUTY_TICKS):
161                 p->duty_ticks = c->duty_ticks;
162                 ret = ecap_pwm_config_duty(p);
163                 break;
165         case BIT(PWM_CONFIG_PERIOD_TICKS):
166                 p->period_ticks = c->period_ticks;
167                 ret = ecap_pwm_config_period(p);
168                 break;
170         case BIT(PWM_CONFIG_POLARITY):
171                 ret = ecap_pwm_set_polarity(p, c->polarity);
172                 break;
174         case BIT(PWM_CONFIG_START):
175                 ret = ecap_pwm_start(p);
176                 break;
178         case BIT(PWM_CONFIG_STOP):
179                 ret = ecap_pwm_stop(p);
180                 break;
181         }
183         return ret;
186 static int ecap_pwm_request(struct pwm_device *p)
188         struct ecap_pwm *ep = to_ecap_pwm(p);
190         p->tick_hz = clk_get_rate(ep->clk);
191         return 0;
194 static int ecap_frequency_transition_cb(struct pwm_device *p)
196         struct ecap_pwm *ep = to_ecap_pwm(p);
197         unsigned long duty_ns;
199         p->tick_hz = clk_get_rate(ep->clk);
200         duty_ns = p->duty_ns;
201         if (pwm_is_running(p)) {
202                 pwm_stop(p);
203                 pwm_set_duty_ns(p, 0);
204                 pwm_set_period_ns(p, p->period_ns);
205                 pwm_set_duty_ns(p, duty_ns);
206                 pwm_start(p);
207         } else {
208                 pwm_set_duty_ns(p, 0);
209                 pwm_set_period_ns(p, p->period_ns);
210                 pwm_set_duty_ns(p, duty_ns);
211         }
212                 return 0;
215 static int __init ecap_probe(struct platform_device *pdev)
217         struct ecap_pwm *ep = NULL;
218         struct resource *r;
219         int ret = 0;
221         ep = kzalloc(sizeof(*ep), GFP_KERNEL);
222         if (!ep) {
223                 dev_err(&pdev->dev, "failed to allocate memory\n");
224                 ret = -ENOMEM;
225                 goto err_ecap_pwm_alloc;
226         }
228         ep->clk = clk_get(&pdev->dev, "ecap");
229         if (IS_ERR(ep->clk)) {
230                 ret = PTR_ERR(ep->clk);
231                 goto err_free;
232         }
234         spin_lock_init(&ep->lock);
235         ep->ops.config = ecap_pwm_config;
236         ep->ops.request = ecap_pwm_request;
237         ep->ops.freq_transition_notifier_cb = ecap_frequency_transition_cb;
238         r = platform_get_resource(pdev, IORESOURCE_MEM, 0);
239         if (!r) {
240                 dev_err(&pdev->dev, "no memory resource defined\n");
241                 ret = -ENODEV;
242                 goto err_free_clk;
243         }
245         r = request_mem_region(r->start, resource_size(r), pdev->name);
246         if (!r) {
247                 dev_err(&pdev->dev, "failed to request memory resource\n");
248                 ret = -EBUSY;
249                 goto err_free_clk;
250         }
252         ep->mmio_base = ioremap(r->start, resource_size(r));
253         if (!ep->mmio_base) {
254                 dev_err(&pdev->dev, "failed to ioremap() registers\n");
255                 ret = -ENODEV;
256                 goto err_free_mem;
257         }
259         ep->pwm.ops = &ep->ops;
260         pwm_set_drvdata(&ep->pwm, ep);
261         ret =  pwm_register(&ep->pwm, &pdev->dev, -1);
262         platform_set_drvdata(pdev, ep);
263         return 0;
265 err_free_mem:
266         release_mem_region(r->start, resource_size(r));
267 err_free_clk:
268         clk_put(ep->clk);
269 err_free:
270         kfree(ep);
271 err_ecap_pwm_alloc:
272         return ret;
275 #ifdef CONFIG_PM
276 static int ecap_suspend(struct platform_device *pdev, pm_message_t state)
278         struct ecap_pwm *ep = platform_get_drvdata(pdev);
280         if (ep->clk->usecount > 0)
281                 clk_disable(ep->clk);
283         return 0;
286 static int ecap_resume(struct platform_device *pdev)
288         struct ecap_pwm *ep = platform_get_drvdata(pdev);
290         clk_enable(ep->clk);
292         return 0;
295 #else
296 #define ecap_suspend NULL
297 #define ecap_resume NULL
298 #endif
300 static int __devexit ecap_remove(struct platform_device *pdev)
302         struct ecap_pwm *ep = platform_get_drvdata(pdev);
303         struct resource *r;
305         pwm_unregister(&ep->pwm);
306         iounmap(ep->mmio_base);
307         r = platform_get_resource(pdev, IORESOURCE_MEM, 0);
308         release_mem_region(r->start, resource_size(r));
309         platform_set_drvdata(pdev, NULL);
310         clk_put(ep->clk);
311         kfree(ep);
313         return 0;
316 static struct platform_driver ecap_driver = {
317         .driver = {
318                 .name   = "ecap",
319                 .owner  = THIS_MODULE,
320         },
321         .probe          = ecap_probe,
322         .remove         = __devexit_p(ecap_remove),
323         .suspend        = ecap_suspend,
324         .resume         = ecap_resume,
325 };
327 static int __init ecap_init(void)
329         return platform_driver_register(&ecap_driver);
332 static void __exit ecap_exit(void)
334         platform_driver_unregister(&ecap_driver);
337 module_init(ecap_init);
338 module_exit(ecap_exit);
340 MODULE_AUTHOR("Texas Instruments");
341 MODULE_DESCRIPTION("Driver for Davinci eCAP peripheral");
342 MODULE_LICENSE("GPL v2");
343 MODULE_ALIAS("platform:ecap");