cc2ed19fbee4531e0f2f8074dc876d8a9e00a769
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)
102 {
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;
115 }
117 static int ecap_pwm_config_period(struct pwm_device *p)
118 {
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;
132 }
134 static int ecap_pwm_config_duty(struct pwm_device *p)
135 {
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;
154 }
156 static int ecap_pwm_config(struct pwm_device *p,
157 struct pwm_config *c)
158 {
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;
186 }
188 static int ecap_pwm_request(struct pwm_device *p)
189 {
190 struct ecap_pwm *ep = to_ecap_pwm(p);
192 p->tick_hz = clk_get_rate(ep->clk);
193 return 0;
194 }
196 static int ecap_frequency_transition_cb(struct pwm_device *p)
197 {
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;
219 }
221 static int ecap_probe(struct platform_device *pdev)
222 {
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;
359 }
361 #ifdef CONFIG_PM
362 static int ecap_suspend(struct platform_device *pdev, pm_message_t state)
363 {
364 struct ecap_pwm *ep = platform_get_drvdata(pdev);
366 if (ep->clk->usecount > 0)
367 clk_disable(ep->clk);
369 return 0;
370 }
372 static int ecap_resume(struct platform_device *pdev)
373 {
374 struct ecap_pwm *ep = platform_get_drvdata(pdev);
376 clk_enable(ep->clk);
378 return 0;
379 }
381 #else
382 #define ecap_suspend NULL
383 #define ecap_resume NULL
384 #endif
386 static int __devexit ecap_remove(struct platform_device *pdev)
387 {
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;
423 }
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)
437 {
438 return platform_driver_register(&ecap_driver);
439 }
441 static void __exit ecap_exit(void)
442 {
443 platform_driver_unregister(&ecap_driver);
444 }
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");