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 void __iomem *mmio_base;
46 u8 version;
47 void __iomem *config_mem_base;
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, v;
58 struct ecap_pwm *ep = to_ecap_pwm(p);
60 /* Trying to stop a non-running PWM, not allowed */
61 if (!pwm_is_running(p))
62 return -EPERM;
64 spin_lock_irqsave(&ep->lock, flags);
65 v = readw(ep->mmio_base + CAPTURE_CTRL2_REG);
66 v &= ~BIT(4);
67 writew(v, ep->mmio_base + CAPTURE_CTRL2_REG);
68 spin_unlock_irqrestore(&ep->lock, flags);
70 /* For PWM clock should be disabled on stop */
71 clk_disable(ep->clk);
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, v;
81 struct ecap_pwm *ep = to_ecap_pwm(p);
83 /* Trying to start a running PWM, not allowed */
84 if (pwm_is_running(p))
85 return -EPERM;
87 /* For PWM clock should be enabled on start */
88 clk_enable(ep->clk);
90 spin_lock_irqsave(&ep->lock, flags);
91 v = readw(ep->mmio_base + CAPTURE_CTRL2_REG);
92 v |= BIT(4);
93 writew(v, ep->mmio_base + CAPTURE_CTRL2_REG);
94 spin_unlock_irqrestore(&ep->lock, flags);
95 set_bit(FLAG_RUNNING, &p->flags);
97 return ret;
98 }
100 static int ecap_pwm_set_polarity(struct pwm_device *p, char pol)
101 {
102 unsigned long flags, v;
103 struct ecap_pwm *ep = to_ecap_pwm(p);
105 clk_enable(ep->clk);
107 spin_lock_irqsave(&ep->lock, flags);
108 v = readw(ep->mmio_base + CAPTURE_CTRL2_REG);
109 v &= ~BIT(10);
110 v |= (!pol << 10);
111 writew(v, ep->mmio_base + CAPTURE_CTRL2_REG);
112 spin_unlock_irqrestore(&ep->lock, flags);
114 clk_disable(ep->clk);
115 return 0;
116 }
118 static int ecap_pwm_config_period(struct pwm_device *p)
119 {
120 unsigned long flags;
121 struct ecap_pwm *ep = to_ecap_pwm(p);
123 clk_enable(ep->clk);
125 spin_lock_irqsave(&ep->lock, flags);
126 writel((p->period_ticks) - 1, ep->mmio_base + CAPTURE_3_REG);
127 writew(ECTRL2_MDSL_ECAP | ECTRL2_SYNCOSEL_MASK | ECTRL2_CTRSTP_FREERUN,
128 ep->mmio_base + CAPTURE_CTRL2_REG);
129 spin_unlock_irqrestore(&ep->lock, flags);
131 clk_disable(ep->clk);
132 return 0;
133 }
135 static int ecap_pwm_config_duty(struct pwm_device *p)
136 {
137 unsigned long flags;
138 struct ecap_pwm *ep = to_ecap_pwm(p);
140 clk_enable(ep->clk);
142 spin_lock_irqsave(&ep->lock, flags);
143 writew(ECTRL2_MDSL_ECAP | ECTRL2_SYNCOSEL_MASK | ECTRL2_CTRSTP_FREERUN,
144 ep->mmio_base + CAPTURE_CTRL2_REG);
145 if (p->duty_ticks > 0) {
146 writel(p->duty_ticks, ep->mmio_base + CAPTURE_4_REG);
147 } else {
148 writel(p->duty_ticks, ep->mmio_base + CAPTURE_2_REG);
149 writel(0, ep->mmio_base + TIMER_CTR_REG);
150 }
151 spin_unlock_irqrestore(&ep->lock, flags);
153 clk_disable(ep->clk);
154 return 0;
155 }
157 static int ecap_pwm_config(struct pwm_device *p,
158 struct pwm_config *c)
159 {
160 int ret = 0;
161 switch (c->config_mask) {
163 case BIT(PWM_CONFIG_DUTY_TICKS):
164 p->duty_ticks = c->duty_ticks;
165 ret = ecap_pwm_config_duty(p);
166 break;
168 case BIT(PWM_CONFIG_PERIOD_TICKS):
169 p->period_ticks = c->period_ticks;
170 ret = ecap_pwm_config_period(p);
171 break;
173 case BIT(PWM_CONFIG_POLARITY):
174 ret = ecap_pwm_set_polarity(p, c->polarity);
175 break;
177 case BIT(PWM_CONFIG_START):
178 ret = ecap_pwm_start(p);
179 break;
181 case BIT(PWM_CONFIG_STOP):
182 ret = ecap_pwm_stop(p);
183 break;
184 }
186 return ret;
187 }
189 static int ecap_pwm_request(struct pwm_device *p)
190 {
191 struct ecap_pwm *ep = to_ecap_pwm(p);
193 p->tick_hz = clk_get_rate(ep->clk);
194 return 0;
195 }
197 static int ecap_frequency_transition_cb(struct pwm_device *p)
198 {
199 struct ecap_pwm *ep = to_ecap_pwm(p);
200 unsigned long duty_ns, rate;
202 rate = clk_get_rate(ep->clk);
203 if (rate == p->tick_hz)
204 return 0;
205 p->tick_hz = rate;
207 duty_ns = p->duty_ns;
208 if (pwm_is_running(p)) {
209 pwm_stop(p);
210 pwm_set_duty_ns(p, 0);
211 pwm_set_period_ns(p, p->period_ns);
212 pwm_set_duty_ns(p, duty_ns);
213 pwm_start(p);
214 } else {
215 pwm_set_duty_ns(p, 0);
216 pwm_set_period_ns(p, p->period_ns);
217 pwm_set_duty_ns(p, duty_ns);
218 }
219 return 0;
220 }
222 static int ecap_probe(struct platform_device *pdev)
223 {
224 struct ecap_pwm *ep = NULL;
225 struct resource *r;
226 int ret = 0;
227 int val;
228 char con_id[PWM_CON_ID_STRING_LENGTH] = "epwmss";
229 struct pwmss_platform_data *pdata = (&pdev->dev)->platform_data;
231 ep = kzalloc(sizeof(*ep), GFP_KERNEL);
233 if (!ep) {
234 dev_err(&pdev->dev, "failed to allocate memory\n");
235 return -ENOMEM;
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_clk_get;
249 }
251 if (ep->version == PWM_VERSION_1) {
252 r = platform_get_resource(pdev, IORESOURCE_MEM, 0);
254 if (!r) {
255 dev_err(&pdev->dev, "no memory resource defined\n");
256 ret = -ENOMEM;
257 goto err_get_resource;
258 }
260 ep->config_mem_base = ioremap(r->start, resource_size(r));
262 if (!ep->config_mem_base) {
264 dev_err(&pdev->dev, "failed to ioremap() registers\n");
265 ret = -ENOMEM;
266 goto err_get_resource;
267 }
269 clk_enable(ep->clk);
270 val = readw(ep->config_mem_base + PWMSS_CLKCONFIG);
271 val |= BIT(ECAP_CLK_EN);
272 writew(val, ep->config_mem_base + PWMSS_CLKCONFIG);
273 clk_disable(ep->clk);
274 }
276 spin_lock_init(&ep->lock);
277 ep->ops.config = ecap_pwm_config;
278 ep->ops.request = ecap_pwm_request;
279 ep->ops.freq_transition_notifier_cb = ecap_frequency_transition_cb;
281 if (ep->version == PWM_VERSION_1)
282 r = platform_get_resource(pdev, IORESOURCE_MEM, 1);
283 else
284 r = platform_get_resource(pdev, IORESOURCE_MEM, 0);
286 if (!r) {
287 dev_err(&pdev->dev, "no memory resource defined\n");
288 ret = -ENODEV;
289 goto err_request_mem;
290 }
292 r = request_mem_region(r->start, resource_size(r), pdev->name);
293 if (!r) {
294 dev_err(&pdev->dev, "failed to request memory resource\n");
295 ret = -EBUSY;
296 goto err_request_mem;
297 }
299 ep->mmio_base = ioremap(r->start, resource_size(r));
300 if (!ep->mmio_base) {
301 dev_err(&pdev->dev, "failed to ioremap() registers\n");
302 ret = -ENODEV;
303 goto err_ioremap;
304 }
306 ep->pwm.ops = &ep->ops;
307 pwm_set_drvdata(&ep->pwm, ep);
308 ret = pwm_register(&ep->pwm, &pdev->dev, -1);
309 platform_set_drvdata(pdev, ep);
310 return 0;
312 err_ioremap:
313 release_mem_region(r->start, resource_size(r));
314 err_request_mem:
315 if (ep->version == PWM_VERSION_1) {
316 iounmap(ep->config_mem_base);
317 ep->config_mem_base = NULL;
318 }
319 err_get_resource:
320 clk_put(ep->clk);
321 err_clk_get:
322 kfree(ep);
323 return ret;
324 }
326 #ifdef CONFIG_PM
327 static int ecap_suspend(struct platform_device *pdev, pm_message_t state)
328 {
329 struct ecap_pwm *ep = platform_get_drvdata(pdev);
331 if (ep->clk->usecount > 0)
332 clk_disable(ep->clk);
334 return 0;
335 }
337 static int ecap_resume(struct platform_device *pdev)
338 {
339 struct ecap_pwm *ep = platform_get_drvdata(pdev);
341 clk_enable(ep->clk);
343 return 0;
344 }
346 #else
347 #define ecap_suspend NULL
348 #define ecap_resume NULL
349 #endif
351 static int __devexit ecap_remove(struct platform_device *pdev)
352 {
353 struct ecap_pwm *ep = platform_get_drvdata(pdev);
354 struct resource *r;
355 struct pwmss_platform_data *pdata;
356 int val;
358 if (ep->version == PWM_VERSION_1) {
359 pdata = (&pdev->dev)->platform_data;
360 val = readw(ep->config_mem_base + PWMSS_CLKCONFIG);
361 val &= ~BIT(ECAP_CLK_EN);
362 writew(val, ep->config_mem_base + PWMSS_CLKCONFIG);
363 iounmap(ep->config_mem_base);
364 ep->config_mem_base = NULL;
365 }
367 pwm_unregister(&ep->pwm);
368 iounmap(ep->mmio_base);
370 if (ep->version == PWM_VERSION_1)
371 r = platform_get_resource(pdev, IORESOURCE_MEM, 1);
372 else
373 r = platform_get_resource(pdev, IORESOURCE_MEM, 0);
374 release_mem_region(r->start, resource_size(r));
375 platform_set_drvdata(pdev, NULL);
376 clk_put(ep->clk);
377 kfree(ep);
379 return 0;
380 }
382 static struct platform_driver ecap_driver = {
383 .driver = {
384 .name = "ecap",
385 .owner = THIS_MODULE,
386 },
387 .probe = ecap_probe,
388 .remove = __devexit_p(ecap_remove),
389 .suspend = ecap_suspend,
390 .resume = ecap_resume,
391 };
393 static int __init ecap_init(void)
394 {
395 return platform_driver_register(&ecap_driver);
396 }
398 static void __exit ecap_exit(void)
399 {
400 platform_driver_unregister(&ecap_driver);
401 }
403 module_init(ecap_init);
404 module_exit(ecap_exit);
406 MODULE_AUTHOR("Texas Instruments");
407 MODULE_DESCRIPTION("Driver for Davinci eCAP peripheral");
408 MODULE_LICENSE("GPL v2");
409 MODULE_ALIAS("platform:ecap");