generic: rtl8366: add common rtl8366_sw_{get,set}_vlan_ports functions
[openwrt.git] / target / linux / generic / files / drivers / pwm / pwm.c
1 /*
2 * drivers/pwm/pwm.c
3 *
4 * Copyright (C) 2010 Bill Gatliff <bgat@billgatliff.com>
5 *
6 * This program is free software; you may redistribute and/or modify
7 * it under the terms of the GNU General Public License version 2 as
8 * published by the Free Software Foundation.
9 *
10 * This program is distributed in the hope that it will be useful, but
11 * WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 * General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
18 * USA
19 */
20
21 #include <linux/kernel.h>
22 #include <linux/module.h>
23 #include <linux/init.h>
24 #include <linux/device.h>
25 #include <linux/spinlock.h>
26 #include <linux/fs.h>
27 #include <linux/completion.h>
28 #include <linux/workqueue.h>
29 #include <linux/list.h>
30 #include <linux/sched.h>
31 #include <linux/slab.h> /*kcalloc, kfree since 2.6.34 */
32 #include <linux/pwm/pwm.h>
33
34 static int __pwm_create_sysfs(struct pwm_device *pwm);
35
36 static const char *REQUEST_SYSFS = "sysfs";
37 static LIST_HEAD(pwm_device_list);
38 static DEFINE_MUTEX(device_list_mutex);
39 static struct class pwm_class;
40 static struct workqueue_struct *pwm_handler_workqueue;
41
42 int pwm_register(struct pwm_device *pwm)
43 {
44 struct pwm_channel *p;
45 int wchan;
46 int ret;
47
48 spin_lock_init(&pwm->list_lock);
49
50 p = kcalloc(pwm->nchan, sizeof(*p), GFP_KERNEL);
51 if (!p)
52 return -ENOMEM;
53
54 for (wchan = 0; wchan < pwm->nchan; wchan++) {
55 spin_lock_init(&p[wchan].lock);
56 init_completion(&p[wchan].complete);
57 p[wchan].chan = wchan;
58 p[wchan].pwm = pwm;
59 }
60
61 pwm->channels = p;
62
63 mutex_lock(&device_list_mutex);
64
65 list_add_tail(&pwm->list, &pwm_device_list);
66 ret = __pwm_create_sysfs(pwm);
67 if (ret) {
68 mutex_unlock(&device_list_mutex);
69 goto err_create_sysfs;
70 }
71
72 mutex_unlock(&device_list_mutex);
73
74 dev_info(pwm->dev, "%d channel%s\n", pwm->nchan,
75 pwm->nchan > 1 ? "s" : "");
76 return 0;
77
78 err_create_sysfs:
79 kfree(p);
80
81 return ret;
82 }
83 EXPORT_SYMBOL(pwm_register);
84
85 static int __match_device(struct device *dev, void *data)
86 {
87 return dev_get_drvdata(dev) == data;
88 }
89
90 int pwm_unregister(struct pwm_device *pwm)
91 {
92 int wchan;
93 struct device *dev;
94
95 mutex_lock(&device_list_mutex);
96
97 for (wchan = 0; wchan < pwm->nchan; wchan++) {
98 if (pwm->channels[wchan].flags & BIT(FLAG_REQUESTED)) {
99 mutex_unlock(&device_list_mutex);
100 return -EBUSY;
101 }
102 }
103
104 for (wchan = 0; wchan < pwm->nchan; wchan++) {
105 dev = class_find_device(&pwm_class, NULL,
106 &pwm->channels[wchan],
107 __match_device);
108 if (dev) {
109 put_device(dev);
110 device_unregister(dev);
111 }
112 }
113
114 kfree(pwm->channels);
115 list_del(&pwm->list);
116 mutex_unlock(&device_list_mutex);
117
118 return 0;
119 }
120 EXPORT_SYMBOL(pwm_unregister);
121
122 static struct pwm_device *
123 __pwm_find_device(const char *bus_id)
124 {
125 struct pwm_device *p;
126
127 list_for_each_entry(p, &pwm_device_list, list) {
128 if (!strcmp(bus_id, p->bus_id))
129 return p;
130 }
131 return NULL;
132 }
133
134 static int
135 __pwm_request_channel(struct pwm_channel *p,
136 const char *requester)
137 {
138 int ret;
139
140 if (test_and_set_bit(FLAG_REQUESTED, &p->flags))
141 return -EBUSY;
142
143 if (p->pwm->request) {
144 ret = p->pwm->request(p);
145 if (ret) {
146 clear_bit(FLAG_REQUESTED, &p->flags);
147 return ret;
148 }
149 }
150
151 p->requester = requester;
152 if (!strcmp(requester, REQUEST_SYSFS))
153 p->pid = current->pid;
154
155 return 0;
156 }
157
158 struct pwm_channel *
159 pwm_request(const char *bus_id,
160 int chan,
161 const char *requester)
162 {
163 struct pwm_device *p;
164 int ret;
165
166 mutex_lock(&device_list_mutex);
167
168 p = __pwm_find_device(bus_id);
169 if (!p || chan >= p->nchan)
170 goto err_no_device;
171
172 if (!try_module_get(p->owner))
173 goto err_module_get_failed;
174
175 ret = __pwm_request_channel(&p->channels[chan], requester);
176 if (ret)
177 goto err_request_failed;
178
179 mutex_unlock(&device_list_mutex);
180 return &p->channels[chan];
181
182 err_request_failed:
183 module_put(p->owner);
184 err_module_get_failed:
185 err_no_device:
186 mutex_unlock(&device_list_mutex);
187 return NULL;
188 }
189 EXPORT_SYMBOL(pwm_request);
190
191 void pwm_free(struct pwm_channel *p)
192 {
193 mutex_lock(&device_list_mutex);
194
195 if (!test_and_clear_bit(FLAG_REQUESTED, &p->flags))
196 goto done;
197
198 pwm_stop(p);
199 pwm_unsynchronize(p, NULL);
200 pwm_set_handler(p, NULL, NULL);
201
202 if (p->pwm->free)
203 p->pwm->free(p);
204 module_put(p->pwm->owner);
205 done:
206 mutex_unlock(&device_list_mutex);
207 }
208 EXPORT_SYMBOL(pwm_free);
209
210 unsigned long pwm_ns_to_ticks(struct pwm_channel *p,
211 unsigned long nsecs)
212 {
213 unsigned long long ticks;
214
215 ticks = nsecs;
216 ticks *= p->tick_hz;
217 do_div(ticks, 1000000000);
218 return ticks;
219 }
220 EXPORT_SYMBOL(pwm_ns_to_ticks);
221
222 unsigned long pwm_ticks_to_ns(struct pwm_channel *p,
223 unsigned long ticks)
224 {
225 unsigned long long ns;
226
227 if (!p->tick_hz)
228 return 0;
229
230 ns = ticks;
231 ns *= 1000000000UL;
232 do_div(ns, p->tick_hz);
233 return ns;
234 }
235 EXPORT_SYMBOL(pwm_ticks_to_ns);
236
237 static void
238 pwm_config_ns_to_ticks(struct pwm_channel *p,
239 struct pwm_channel_config *c)
240 {
241 if (c->config_mask & PWM_CONFIG_PERIOD_NS) {
242 c->period_ticks = pwm_ns_to_ticks(p, c->period_ns);
243 c->config_mask &= ~PWM_CONFIG_PERIOD_NS;
244 c->config_mask |= PWM_CONFIG_PERIOD_TICKS;
245 }
246
247 if (c->config_mask & PWM_CONFIG_DUTY_NS) {
248 c->duty_ticks = pwm_ns_to_ticks(p, c->duty_ns);
249 c->config_mask &= ~PWM_CONFIG_DUTY_NS;
250 c->config_mask |= PWM_CONFIG_DUTY_TICKS;
251 }
252 }
253
254 static void
255 pwm_config_percent_to_ticks(struct pwm_channel *p,
256 struct pwm_channel_config *c)
257 {
258 if (c->config_mask & PWM_CONFIG_DUTY_PERCENT) {
259 if (c->config_mask & PWM_CONFIG_PERIOD_TICKS)
260 c->duty_ticks = c->period_ticks;
261 else
262 c->duty_ticks = p->period_ticks;
263
264 c->duty_ticks *= c->duty_percent;
265 c->duty_ticks /= 100;
266 c->config_mask &= ~PWM_CONFIG_DUTY_PERCENT;
267 c->config_mask |= PWM_CONFIG_DUTY_TICKS;
268 }
269 }
270
271 int pwm_config_nosleep(struct pwm_channel *p,
272 struct pwm_channel_config *c)
273 {
274 if (!p->pwm->config_nosleep)
275 return -EINVAL;
276
277 pwm_config_ns_to_ticks(p, c);
278 pwm_config_percent_to_ticks(p, c);
279
280 return p->pwm->config_nosleep(p, c);
281 }
282 EXPORT_SYMBOL(pwm_config_nosleep);
283
284 int pwm_config(struct pwm_channel *p,
285 struct pwm_channel_config *c)
286 {
287 int ret = 0;
288
289 if (unlikely(!p->pwm->config))
290 return -EINVAL;
291
292 pwm_config_ns_to_ticks(p, c);
293 pwm_config_percent_to_ticks(p, c);
294
295 switch (c->config_mask & (PWM_CONFIG_PERIOD_TICKS
296 | PWM_CONFIG_DUTY_TICKS)) {
297 case PWM_CONFIG_PERIOD_TICKS:
298 if (p->duty_ticks > c->period_ticks) {
299 ret = -EINVAL;
300 goto err;
301 }
302 break;
303 case PWM_CONFIG_DUTY_TICKS:
304 if (p->period_ticks < c->duty_ticks) {
305 ret = -EINVAL;
306 goto err;
307 }
308 break;
309 case PWM_CONFIG_DUTY_TICKS | PWM_CONFIG_PERIOD_TICKS:
310 if (c->duty_ticks > c->period_ticks) {
311 ret = -EINVAL;
312 goto err;
313 }
314 break;
315 default:
316 break;
317 }
318
319 err:
320 dev_dbg(p->pwm->dev, "%s: config_mask %d period_ticks %lu duty_ticks %lu"
321 " polarity %d duty_ns %lu period_ns %lu duty_percent %d\n",
322 __func__, c->config_mask, c->period_ticks, c->duty_ticks,
323 c->polarity, c->duty_ns, c->period_ns, c->duty_percent);
324
325 if (ret)
326 return ret;
327 return p->pwm->config(p, c);
328 }
329 EXPORT_SYMBOL(pwm_config);
330
331 int pwm_set_period_ns(struct pwm_channel *p,
332 unsigned long period_ns)
333 {
334 struct pwm_channel_config c = {
335 .config_mask = PWM_CONFIG_PERIOD_TICKS,
336 .period_ticks = pwm_ns_to_ticks(p, period_ns),
337 };
338
339 return pwm_config(p, &c);
340 }
341 EXPORT_SYMBOL(pwm_set_period_ns);
342
343 unsigned long pwm_get_period_ns(struct pwm_channel *p)
344 {
345 return pwm_ticks_to_ns(p, p->period_ticks);
346 }
347 EXPORT_SYMBOL(pwm_get_period_ns);
348
349 int pwm_set_duty_ns(struct pwm_channel *p,
350 unsigned long duty_ns)
351 {
352 struct pwm_channel_config c = {
353 .config_mask = PWM_CONFIG_DUTY_TICKS,
354 .duty_ticks = pwm_ns_to_ticks(p, duty_ns),
355 };
356 return pwm_config(p, &c);
357 }
358 EXPORT_SYMBOL(pwm_set_duty_ns);
359
360 unsigned long pwm_get_duty_ns(struct pwm_channel *p)
361 {
362 return pwm_ticks_to_ns(p, p->duty_ticks);
363 }
364 EXPORT_SYMBOL(pwm_get_duty_ns);
365
366 int pwm_set_duty_percent(struct pwm_channel *p,
367 int percent)
368 {
369 struct pwm_channel_config c = {
370 .config_mask = PWM_CONFIG_DUTY_PERCENT,
371 .duty_percent = percent,
372 };
373 return pwm_config(p, &c);
374 }
375 EXPORT_SYMBOL(pwm_set_duty_percent);
376
377 int pwm_set_polarity(struct pwm_channel *p,
378 int active_high)
379 {
380 struct pwm_channel_config c = {
381 .config_mask = PWM_CONFIG_POLARITY,
382 .polarity = active_high,
383 };
384 return pwm_config(p, &c);
385 }
386 EXPORT_SYMBOL(pwm_set_polarity);
387
388 int pwm_start(struct pwm_channel *p)
389 {
390 struct pwm_channel_config c = {
391 .config_mask = PWM_CONFIG_START,
392 };
393 return pwm_config(p, &c);
394 }
395 EXPORT_SYMBOL(pwm_start);
396
397 int pwm_stop(struct pwm_channel *p)
398 {
399 struct pwm_channel_config c = {
400 .config_mask = PWM_CONFIG_STOP,
401 };
402 return pwm_config(p, &c);
403 }
404 EXPORT_SYMBOL(pwm_stop);
405
406 int pwm_synchronize(struct pwm_channel *p,
407 struct pwm_channel *to_p)
408 {
409 if (p->pwm != to_p->pwm) {
410 /* TODO: support cross-device synchronization */
411 return -EINVAL;
412 }
413
414 if (!p->pwm->synchronize)
415 return -EINVAL;
416
417 return p->pwm->synchronize(p, to_p);
418 }
419 EXPORT_SYMBOL(pwm_synchronize);
420
421 int pwm_unsynchronize(struct pwm_channel *p,
422 struct pwm_channel *from_p)
423 {
424 if (from_p && (p->pwm != from_p->pwm)) {
425 /* TODO: support cross-device synchronization */
426 return -EINVAL;
427 }
428
429 if (!p->pwm->unsynchronize)
430 return -EINVAL;
431
432 return p->pwm->unsynchronize(p, from_p);
433 }
434 EXPORT_SYMBOL(pwm_unsynchronize);
435
436 static void pwm_handler(struct work_struct *w)
437 {
438 struct pwm_channel *p = container_of(w, struct pwm_channel,
439 handler_work);
440 if (p->handler && p->handler(p, p->handler_data))
441 pwm_stop(p);
442 }
443
444 static void __pwm_callback(struct pwm_channel *p)
445 {
446 queue_work(pwm_handler_workqueue, &p->handler_work);
447 dev_dbg(p->pwm->dev, "handler %p scheduled with data %p\n",
448 p->handler, p->handler_data);
449 }
450
451 int pwm_set_handler(struct pwm_channel *p,
452 pwm_handler_t handler,
453 void *data)
454 {
455 if (p->pwm->set_callback) {
456 p->handler_data = data;
457 p->handler = handler;
458 INIT_WORK(&p->handler_work, pwm_handler);
459 return p->pwm->set_callback(p, handler ? __pwm_callback : NULL);
460 }
461 return -EINVAL;
462 }
463 EXPORT_SYMBOL(pwm_set_handler);
464
465 static ssize_t pwm_run_store(struct device *dev,
466 struct device_attribute *attr,
467 const char *buf,
468 size_t len)
469 {
470 struct pwm_channel *p = dev_get_drvdata(dev);
471 if (sysfs_streq(buf, "1"))
472 pwm_start(p);
473 else if (sysfs_streq(buf, "0"))
474 pwm_stop(p);
475 return len;
476 }
477 static DEVICE_ATTR(run, 0200, NULL, pwm_run_store);
478
479 static ssize_t pwm_duty_ns_show(struct device *dev,
480 struct device_attribute *attr,
481 char *buf)
482 {
483 struct pwm_channel *p = dev_get_drvdata(dev);
484 return sprintf(buf, "%lu\n", pwm_get_duty_ns(p));
485 }
486
487 static ssize_t pwm_duty_ns_store(struct device *dev,
488 struct device_attribute *attr,
489 const char *buf,
490 size_t len)
491 {
492 unsigned long duty_ns;
493 struct pwm_channel *p = dev_get_drvdata(dev);
494
495 if (1 == sscanf(buf, "%lu", &duty_ns))
496 pwm_set_duty_ns(p, duty_ns);
497 return len;
498 }
499 static DEVICE_ATTR(duty_ns, 0644, pwm_duty_ns_show, pwm_duty_ns_store);
500
501 static ssize_t pwm_period_ns_show(struct device *dev,
502 struct device_attribute *attr,
503 char *buf)
504 {
505 struct pwm_channel *p = dev_get_drvdata(dev);
506 return sprintf(buf, "%lu\n", pwm_get_period_ns(p));
507 }
508
509 static ssize_t pwm_period_ns_store(struct device *dev,
510 struct device_attribute *attr,
511 const char *buf,
512 size_t len)
513 {
514 unsigned long period_ns;
515 struct pwm_channel *p = dev_get_drvdata(dev);
516
517 if (1 == sscanf(buf, "%lu", &period_ns))
518 pwm_set_period_ns(p, period_ns);
519 return len;
520 }
521 static DEVICE_ATTR(period_ns, 0644, pwm_period_ns_show, pwm_period_ns_store);
522
523 static ssize_t pwm_polarity_show(struct device *dev,
524 struct device_attribute *attr,
525 char *buf)
526 {
527 struct pwm_channel *p = dev_get_drvdata(dev);
528 return sprintf(buf, "%d\n", p->active_high ? 1 : 0);
529 }
530
531 static ssize_t pwm_polarity_store(struct device *dev,
532 struct device_attribute *attr,
533 const char *buf,
534 size_t len)
535 {
536 int polarity;
537 struct pwm_channel *p = dev_get_drvdata(dev);
538
539 if (1 == sscanf(buf, "%d", &polarity))
540 pwm_set_polarity(p, polarity);
541 return len;
542 }
543 static DEVICE_ATTR(polarity, 0644, pwm_polarity_show, pwm_polarity_store);
544
545 static ssize_t pwm_request_show(struct device *dev,
546 struct device_attribute *attr,
547 char *buf)
548 {
549 struct pwm_channel *p = dev_get_drvdata(dev);
550 mutex_lock(&device_list_mutex);
551 __pwm_request_channel(p, REQUEST_SYSFS);
552 mutex_unlock(&device_list_mutex);
553
554 if (p->pid)
555 return sprintf(buf, "%s %d\n", p->requester, p->pid);
556 else
557 return sprintf(buf, "%s\n", p->requester);
558 }
559
560 static ssize_t pwm_request_store(struct device *dev,
561 struct device_attribute *attr,
562 const char *buf,
563 size_t len)
564 {
565 struct pwm_channel *p = dev_get_drvdata(dev);
566 pwm_free(p);
567 return len;
568 }
569 static DEVICE_ATTR(request, 0644, pwm_request_show, pwm_request_store);
570
571 static const struct attribute *pwm_attrs[] =
572 {
573 &dev_attr_run.attr,
574 &dev_attr_polarity.attr,
575 &dev_attr_duty_ns.attr,
576 &dev_attr_period_ns.attr,
577 &dev_attr_request.attr,
578 NULL,
579 };
580
581 static const struct attribute_group pwm_device_attr_group = {
582 .attrs = (struct attribute **)pwm_attrs,
583 };
584
585 static int __pwm_create_sysfs(struct pwm_device *pwm)
586 {
587 int ret = 0;
588 struct device *dev;
589 int wchan;
590
591 for (wchan = 0; wchan < pwm->nchan; wchan++) {
592 dev = device_create(&pwm_class, pwm->dev, MKDEV(0, 0),
593 pwm->channels + wchan,
594 "%s:%d", pwm->bus_id, wchan);
595 if (!dev)
596 goto err_dev_create;
597 ret = sysfs_create_group(&dev->kobj, &pwm_device_attr_group);
598 if (ret)
599 goto err_dev_create;
600 }
601
602 return ret;
603
604 err_dev_create:
605 for (wchan = 0; wchan < pwm->nchan; wchan++) {
606 dev = class_find_device(&pwm_class, NULL,
607 &pwm->channels[wchan],
608 __match_device);
609 if (dev) {
610 put_device(dev);
611 device_unregister(dev);
612 }
613 }
614
615 return ret;
616 }
617
618 static struct class_attribute pwm_class_attrs[] = {
619 __ATTR_NULL,
620 };
621
622 static struct class pwm_class = {
623 .name = "pwm",
624 .owner = THIS_MODULE,
625
626 .class_attrs = pwm_class_attrs,
627 };
628
629 static int __init pwm_init(void)
630 {
631 int ret;
632
633 /* TODO: how to deal with devices that register very early? */
634 pr_err("%s\n", __func__);
635 ret = class_register(&pwm_class);
636 if (ret < 0)
637 return ret;
638
639 pwm_handler_workqueue = create_workqueue("pwmd");
640
641 return 0;
642 }
643 postcore_initcall(pwm_init);
This page took 0.072777 seconds and 5 git commands to generate.