4 * Copyright (C) 2010 Bill Gatliff <bgat@billgatliff.com>
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.
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.
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
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>
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>
34 static int __pwm_create_sysfs(struct pwm_device *pwm);
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;
42 int pwm_register(struct pwm_device *pwm)
44 struct pwm_channel *p;
48 spin_lock_init(&pwm->list_lock);
50 p = kcalloc(pwm->nchan, sizeof(*p), GFP_KERNEL);
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;
63 mutex_lock(&device_list_mutex);
65 list_add_tail(&pwm->list, &pwm_device_list);
66 ret = __pwm_create_sysfs(pwm);
68 mutex_unlock(&device_list_mutex);
69 goto err_create_sysfs;
72 mutex_unlock(&device_list_mutex);
74 dev_info(pwm->dev, "%d channel%s\n", pwm->nchan,
75 pwm->nchan > 1 ? "s" : "");
83 EXPORT_SYMBOL(pwm_register);
85 static int __match_device(struct device *dev, void *data)
87 return dev_get_drvdata(dev) == data;
90 int pwm_unregister(struct pwm_device *pwm)
95 mutex_lock(&device_list_mutex);
97 for (wchan = 0; wchan < pwm->nchan; wchan++) {
98 if (pwm->channels[wchan].flags & BIT(FLAG_REQUESTED)) {
99 mutex_unlock(&device_list_mutex);
104 for (wchan = 0; wchan < pwm->nchan; wchan++) {
105 dev = class_find_device(&pwm_class, NULL,
106 &pwm->channels[wchan],
110 device_unregister(dev);
114 kfree(pwm->channels);
115 list_del(&pwm->list);
116 mutex_unlock(&device_list_mutex);
120 EXPORT_SYMBOL(pwm_unregister);
122 static struct pwm_device *
123 __pwm_find_device(const char *bus_id)
125 struct pwm_device *p;
127 list_for_each_entry(p, &pwm_device_list, list) {
128 if (!strcmp(bus_id, p->bus_id))
135 __pwm_request_channel(struct pwm_channel *p,
136 const char *requester)
140 if (test_and_set_bit(FLAG_REQUESTED, &p->flags))
143 if (p->pwm->request) {
144 ret = p->pwm->request(p);
146 clear_bit(FLAG_REQUESTED, &p->flags);
151 p->requester = requester;
152 if (!strcmp(requester, REQUEST_SYSFS))
153 p->pid = current->pid;
159 pwm_request(const char *bus_id,
161 const char *requester)
163 struct pwm_device *p;
166 mutex_lock(&device_list_mutex);
168 p = __pwm_find_device(bus_id);
169 if (!p || chan >= p->nchan)
172 if (!try_module_get(p->owner))
173 goto err_module_get_failed;
175 ret = __pwm_request_channel(&p->channels[chan], requester);
177 goto err_request_failed;
179 mutex_unlock(&device_list_mutex);
180 return &p->channels[chan];
183 module_put(p->owner);
184 err_module_get_failed:
186 mutex_unlock(&device_list_mutex);
189 EXPORT_SYMBOL(pwm_request);
191 void pwm_free(struct pwm_channel *p)
193 mutex_lock(&device_list_mutex);
195 if (!test_and_clear_bit(FLAG_REQUESTED, &p->flags))
199 pwm_unsynchronize(p, NULL);
200 pwm_set_handler(p, NULL, NULL);
204 module_put(p->pwm->owner);
206 mutex_unlock(&device_list_mutex);
208 EXPORT_SYMBOL(pwm_free);
210 unsigned long pwm_ns_to_ticks(struct pwm_channel *p,
213 unsigned long long ticks;
217 do_div(ticks, 1000000000);
220 EXPORT_SYMBOL(pwm_ns_to_ticks);
222 unsigned long pwm_ticks_to_ns(struct pwm_channel *p,
225 unsigned long long ns;
232 do_div(ns, p->tick_hz);
235 EXPORT_SYMBOL(pwm_ticks_to_ns);
238 pwm_config_ns_to_ticks(struct pwm_channel *p,
239 struct pwm_channel_config *c)
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;
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;
255 pwm_config_percent_to_ticks(struct pwm_channel *p,
256 struct pwm_channel_config *c)
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;
262 c->duty_ticks = p->period_ticks;
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;
271 int pwm_config_nosleep(struct pwm_channel *p,
272 struct pwm_channel_config *c)
274 if (!p->pwm->config_nosleep)
277 pwm_config_ns_to_ticks(p, c);
278 pwm_config_percent_to_ticks(p, c);
280 return p->pwm->config_nosleep(p, c);
282 EXPORT_SYMBOL(pwm_config_nosleep);
284 int pwm_config(struct pwm_channel *p,
285 struct pwm_channel_config *c)
289 if (unlikely(!p->pwm->config))
292 pwm_config_ns_to_ticks(p, c);
293 pwm_config_percent_to_ticks(p, c);
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) {
303 case PWM_CONFIG_DUTY_TICKS:
304 if (p->period_ticks < c->duty_ticks) {
309 case PWM_CONFIG_DUTY_TICKS | PWM_CONFIG_PERIOD_TICKS:
310 if (c->duty_ticks > c->period_ticks) {
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);
327 return p->pwm->config(p, c);
329 EXPORT_SYMBOL(pwm_config);
331 int pwm_set_period_ns(struct pwm_channel *p,
332 unsigned long period_ns)
334 struct pwm_channel_config c = {
335 .config_mask = PWM_CONFIG_PERIOD_TICKS,
336 .period_ticks = pwm_ns_to_ticks(p, period_ns),
339 return pwm_config(p, &c);
341 EXPORT_SYMBOL(pwm_set_period_ns);
343 unsigned long pwm_get_period_ns(struct pwm_channel *p)
345 return pwm_ticks_to_ns(p, p->period_ticks);
347 EXPORT_SYMBOL(pwm_get_period_ns);
349 int pwm_set_duty_ns(struct pwm_channel *p,
350 unsigned long duty_ns)
352 struct pwm_channel_config c = {
353 .config_mask = PWM_CONFIG_DUTY_TICKS,
354 .duty_ticks = pwm_ns_to_ticks(p, duty_ns),
356 return pwm_config(p, &c);
358 EXPORT_SYMBOL(pwm_set_duty_ns);
360 unsigned long pwm_get_duty_ns(struct pwm_channel *p)
362 return pwm_ticks_to_ns(p, p->duty_ticks);
364 EXPORT_SYMBOL(pwm_get_duty_ns);
366 int pwm_set_duty_percent(struct pwm_channel *p,
369 struct pwm_channel_config c = {
370 .config_mask = PWM_CONFIG_DUTY_PERCENT,
371 .duty_percent = percent,
373 return pwm_config(p, &c);
375 EXPORT_SYMBOL(pwm_set_duty_percent);
377 int pwm_set_polarity(struct pwm_channel *p,
380 struct pwm_channel_config c = {
381 .config_mask = PWM_CONFIG_POLARITY,
382 .polarity = active_high,
384 return pwm_config(p, &c);
386 EXPORT_SYMBOL(pwm_set_polarity);
388 int pwm_start(struct pwm_channel *p)
390 struct pwm_channel_config c = {
391 .config_mask = PWM_CONFIG_START,
393 return pwm_config(p, &c);
395 EXPORT_SYMBOL(pwm_start);
397 int pwm_stop(struct pwm_channel *p)
399 struct pwm_channel_config c = {
400 .config_mask = PWM_CONFIG_STOP,
402 return pwm_config(p, &c);
404 EXPORT_SYMBOL(pwm_stop);
406 int pwm_synchronize(struct pwm_channel *p,
407 struct pwm_channel *to_p)
409 if (p->pwm != to_p->pwm) {
410 /* TODO: support cross-device synchronization */
414 if (!p->pwm->synchronize)
417 return p->pwm->synchronize(p, to_p);
419 EXPORT_SYMBOL(pwm_synchronize);
421 int pwm_unsynchronize(struct pwm_channel *p,
422 struct pwm_channel *from_p)
424 if (from_p && (p->pwm != from_p->pwm)) {
425 /* TODO: support cross-device synchronization */
429 if (!p->pwm->unsynchronize)
432 return p->pwm->unsynchronize(p, from_p);
434 EXPORT_SYMBOL(pwm_unsynchronize);
436 static void pwm_handler(struct work_struct *w)
438 struct pwm_channel *p = container_of(w, struct pwm_channel,
440 if (p->handler && p->handler(p, p->handler_data))
444 static void __pwm_callback(struct pwm_channel *p)
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);
451 int pwm_set_handler(struct pwm_channel *p,
452 pwm_handler_t handler,
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);
463 EXPORT_SYMBOL(pwm_set_handler);
465 static ssize_t pwm_run_store(struct device *dev,
466 struct device_attribute *attr,
470 struct pwm_channel *p = dev_get_drvdata(dev);
471 if (sysfs_streq(buf, "1"))
473 else if (sysfs_streq(buf, "0"))
477 static DEVICE_ATTR(run, 0200, NULL, pwm_run_store);
479 static ssize_t pwm_duty_ns_show(struct device *dev,
480 struct device_attribute *attr,
483 struct pwm_channel *p = dev_get_drvdata(dev);
484 return sprintf(buf, "%lu\n", pwm_get_duty_ns(p));
487 static ssize_t pwm_duty_ns_store(struct device *dev,
488 struct device_attribute *attr,
492 unsigned long duty_ns;
493 struct pwm_channel *p = dev_get_drvdata(dev);
495 if (1 == sscanf(buf, "%lu", &duty_ns))
496 pwm_set_duty_ns(p, duty_ns);
499 static DEVICE_ATTR(duty_ns, 0644, pwm_duty_ns_show, pwm_duty_ns_store);
501 static ssize_t pwm_period_ns_show(struct device *dev,
502 struct device_attribute *attr,
505 struct pwm_channel *p = dev_get_drvdata(dev);
506 return sprintf(buf, "%lu\n", pwm_get_period_ns(p));
509 static ssize_t pwm_period_ns_store(struct device *dev,
510 struct device_attribute *attr,
514 unsigned long period_ns;
515 struct pwm_channel *p = dev_get_drvdata(dev);
517 if (1 == sscanf(buf, "%lu", &period_ns))
518 pwm_set_period_ns(p, period_ns);
521 static DEVICE_ATTR(period_ns, 0644, pwm_period_ns_show, pwm_period_ns_store);
523 static ssize_t pwm_polarity_show(struct device *dev,
524 struct device_attribute *attr,
527 struct pwm_channel *p = dev_get_drvdata(dev);
528 return sprintf(buf, "%d\n", p->active_high ? 1 : 0);
531 static ssize_t pwm_polarity_store(struct device *dev,
532 struct device_attribute *attr,
537 struct pwm_channel *p = dev_get_drvdata(dev);
539 if (1 == sscanf(buf, "%d", &polarity))
540 pwm_set_polarity(p, polarity);
543 static DEVICE_ATTR(polarity, 0644, pwm_polarity_show, pwm_polarity_store);
545 static ssize_t pwm_request_show(struct device *dev,
546 struct device_attribute *attr,
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);
555 return sprintf(buf, "%s %d\n", p->requester, p->pid);
557 return sprintf(buf, "%s\n", p->requester);
560 static ssize_t pwm_request_store(struct device *dev,
561 struct device_attribute *attr,
565 struct pwm_channel *p = dev_get_drvdata(dev);
569 static DEVICE_ATTR(request, 0644, pwm_request_show, pwm_request_store);
571 static const struct attribute *pwm_attrs[] =
574 &dev_attr_polarity.attr,
575 &dev_attr_duty_ns.attr,
576 &dev_attr_period_ns.attr,
577 &dev_attr_request.attr,
581 static const struct attribute_group pwm_device_attr_group = {
582 .attrs = (struct attribute **)pwm_attrs,
585 static int __pwm_create_sysfs(struct pwm_device *pwm)
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);
597 ret = sysfs_create_group(&dev->kobj, &pwm_device_attr_group);
605 for (wchan = 0; wchan < pwm->nchan; wchan++) {
606 dev = class_find_device(&pwm_class, NULL,
607 &pwm->channels[wchan],
611 device_unregister(dev);
618 static struct class_attribute pwm_class_attrs[] = {
622 static struct class pwm_class = {
624 .owner = THIS_MODULE,
626 .class_attrs = pwm_class_attrs,
629 static int __init pwm_init(void)
633 /* TODO: how to deal with devices that register very early? */
634 pr_err("%s\n", __func__);
635 ret = class_register(&pwm_class);
639 pwm_handler_workqueue = create_workqueue("pwmd");
643 postcore_initcall(pwm_init);