• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // SPDX-License-Identifier: GPL-2.0-or-later
2 /*
3  * A simple sysfs interface for the generic PWM framework
4  *
5  * Copyright (C) 2013 H Hartley Sweeten <hsweeten@visionengravers.com>
6  *
7  * Based on previous work by Lars Poeschel <poeschel@lemonage.de>
8  */
9 
10 #include <linux/device.h>
11 #include <linux/mutex.h>
12 #include <linux/err.h>
13 #include <linux/slab.h>
14 #include <linux/kdev_t.h>
15 #include <linux/pwm.h>
16 
17 struct pwm_export {
18     struct device child;
19     struct pwm_device *pwm;
20     struct mutex lock;
21     struct pwm_state suspend;
22 };
23 
child_to_pwm_export(struct device * child)24 static struct pwm_export *child_to_pwm_export(struct device *child)
25 {
26     return container_of(child, struct pwm_export, child);
27 }
28 
child_to_pwm_device(struct device * child)29 static struct pwm_device *child_to_pwm_device(struct device *child)
30 {
31     struct pwm_export *export = child_to_pwm_export(child);
32 
33     return export->pwm;
34 }
35 
period_show(struct device * child,struct device_attribute * attr,char * buf)36 static ssize_t period_show(struct device *child, struct device_attribute *attr, char *buf)
37 {
38     const struct pwm_device *pwm = child_to_pwm_device(child);
39     struct pwm_state state;
40 
41     pwm_get_state(pwm, &state);
42 
43     return sprintf(buf, "%llu\n", state.period);
44 }
45 
period_store(struct device * child,struct device_attribute * attr,const char * buf,size_t size)46 static ssize_t period_store(struct device *child, struct device_attribute *attr, const char *buf, size_t size)
47 {
48     struct pwm_export *export = child_to_pwm_export(child);
49     struct pwm_device *pwm = export->pwm;
50     struct pwm_state state;
51     u64 val;
52     int ret;
53 
54     ret = kstrtou64(buf, 0, &val);
55     if (ret) {
56         return ret;
57     }
58 
59     mutex_lock(&export->lock);
60     pwm_get_state(pwm, &state);
61     state.period = val;
62     ret = pwm_apply_state(pwm, &state);
63     mutex_unlock(&export->lock);
64 
65     return ret ?: size;
66 }
67 
duty_cycle_show(struct device * child,struct device_attribute * attr,char * buf)68 static ssize_t duty_cycle_show(struct device *child, struct device_attribute *attr, char *buf)
69 {
70     const struct pwm_device *pwm = child_to_pwm_device(child);
71     struct pwm_state state;
72 
73     pwm_get_state(pwm, &state);
74 
75     return sprintf(buf, "%llu\n", state.duty_cycle);
76 }
77 
duty_cycle_store(struct device * child,struct device_attribute * attr,const char * buf,size_t size)78 static ssize_t duty_cycle_store(struct device *child, struct device_attribute *attr, const char *buf, size_t size)
79 {
80     struct pwm_export *export = child_to_pwm_export(child);
81     struct pwm_device *pwm = export->pwm;
82     struct pwm_state state;
83     u64 val;
84     int ret;
85 
86     ret = kstrtou64(buf, 0, &val);
87     if (ret) {
88         return ret;
89     }
90 
91     mutex_lock(&export->lock);
92     pwm_get_state(pwm, &state);
93     state.duty_cycle = val;
94     ret = pwm_apply_state(pwm, &state);
95     mutex_unlock(&export->lock);
96 
97     return ret ?: size;
98 }
99 
100 #ifdef CONFIG_PWM_ROCKCHIP_ONESHOT
oneshot_count_show(struct device * child,struct device_attribute * attr,char * buf)101 static ssize_t oneshot_count_show(struct device *child, struct device_attribute *attr, char *buf)
102 {
103     const struct pwm_device *pwm = child_to_pwm_device(child);
104     struct pwm_state state;
105 
106     pwm_get_state(pwm, &state);
107 
108     return sprintf(buf, "%llu\n", state.oneshot_count);
109 }
110 
oneshot_count_store(struct device * child,struct device_attribute * attr,const char * buf,size_t size)111 static ssize_t oneshot_count_store(struct device *child, struct device_attribute *attr, const char *buf, size_t size)
112 {
113     struct pwm_export *export = child_to_pwm_export(child);
114     struct pwm_device *pwm = export->pwm;
115     struct pwm_state state;
116     unsigned int val;
117     int ret;
118 
119     ret = kstrtouint(buf, 0, &val);
120     if (ret) {
121         return ret;
122     }
123 
124     mutex_lock(&export->lock);
125     pwm_get_state(pwm, &state);
126     state.oneshot_count = val;
127     ret = pwm_apply_state(pwm, &state);
128     mutex_unlock(&export->lock);
129 
130     return ret ?: size;
131 }
132 #endif
133 
enable_show(struct device * child,struct device_attribute * attr,char * buf)134 static ssize_t enable_show(struct device *child, struct device_attribute *attr, char *buf)
135 {
136     const struct pwm_device *pwm = child_to_pwm_device(child);
137     struct pwm_state state;
138 
139     pwm_get_state(pwm, &state);
140 
141     return sprintf(buf, "%d\n", state.enabled);
142 }
143 
enable_store(struct device * child,struct device_attribute * attr,const char * buf,size_t size)144 static ssize_t enable_store(struct device *child, struct device_attribute *attr, const char *buf, size_t size)
145 {
146     struct pwm_export *export = child_to_pwm_export(child);
147     struct pwm_device *pwm = export->pwm;
148     struct pwm_state state;
149     int val, ret;
150 
151     ret = kstrtoint(buf, 0, &val);
152     if (ret) {
153         return ret;
154     }
155 
156     mutex_lock(&export->lock);
157 
158     pwm_get_state(pwm, &state);
159 
160     switch (val) {
161         case 0:
162             state.enabled = false;
163             break;
164         case 1:
165             state.enabled = true;
166             break;
167         default:
168             ret = -EINVAL;
169             goto unlock;
170     }
171 
172     ret = pwm_apply_state(pwm, &state);
173 
174 unlock:
175     mutex_unlock(&export->lock);
176     return ret ?: size;
177 }
178 
polarity_show(struct device * child,struct device_attribute * attr,char * buf)179 static ssize_t polarity_show(struct device *child, struct device_attribute *attr, char *buf)
180 {
181     const struct pwm_device *pwm = child_to_pwm_device(child);
182     const char *polarity = "unknown";
183     struct pwm_state state;
184 
185     pwm_get_state(pwm, &state);
186 
187     switch (state.polarity) {
188         case PWM_POLARITY_NORMAL:
189             polarity = "normal";
190             break;
191 
192         case PWM_POLARITY_INVERSED:
193             polarity = "inversed";
194             break;
195     }
196 
197     return sprintf(buf, "%s\n", polarity);
198 }
199 
polarity_store(struct device * child,struct device_attribute * attr,const char * buf,size_t size)200 static ssize_t polarity_store(struct device *child, struct device_attribute *attr, const char *buf, size_t size)
201 {
202     struct pwm_export *export = child_to_pwm_export(child);
203     struct pwm_device *pwm = export->pwm;
204     enum pwm_polarity polarity;
205     struct pwm_state state;
206     int ret;
207 
208     if (sysfs_streq(buf, "normal")) {
209         polarity = PWM_POLARITY_NORMAL;
210     } else if (sysfs_streq(buf, "inversed")) {
211         polarity = PWM_POLARITY_INVERSED;
212     } else {
213         return -EINVAL;
214     }
215 
216     mutex_lock(&export->lock);
217     pwm_get_state(pwm, &state);
218     state.polarity = polarity;
219     ret = pwm_apply_state(pwm, &state);
220     mutex_unlock(&export->lock);
221 
222     return ret ?: size;
223 }
224 
capture_show(struct device * child,struct device_attribute * attr,char * buf)225 static ssize_t capture_show(struct device *child, struct device_attribute *attr, char *buf)
226 {
227     struct pwm_device *pwm = child_to_pwm_device(child);
228     struct pwm_capture result;
229     int ret;
230 
231     ret = pwm_capture(pwm, &result, jiffies_to_msecs(HZ));
232     if (ret) {
233         return ret;
234     }
235 
236     return sprintf(buf, "%u %u\n", result.period, result.duty_cycle);
237 }
238 
239 static DEVICE_ATTR_RW(period);
240 static DEVICE_ATTR_RW(duty_cycle);
241 #ifdef CONFIG_PWM_ROCKCHIP_ONESHOT
242 static DEVICE_ATTR_RW(oneshot_count);
243 #endif
244 static DEVICE_ATTR_RW(enable);
245 static DEVICE_ATTR_RW(polarity);
246 static DEVICE_ATTR_RO(capture);
247 
248 static struct attribute *pwm_attrs[] = {&dev_attr_period.attr,        &dev_attr_duty_cycle.attr,
249 #ifdef CONFIG_PWM_ROCKCHIP_ONESHOT
250                                         &dev_attr_oneshot_count.attr,
251 #endif
252                                         &dev_attr_enable.attr,        &dev_attr_polarity.attr,
253                                         &dev_attr_capture.attr,       NULL};
254 ATTRIBUTE_GROUPS(pwm);
255 
pwm_export_release(struct device * child)256 static void pwm_export_release(struct device *child)
257 {
258     struct pwm_export *export = child_to_pwm_export(child);
259 
260     kfree(export);
261 }
262 
pwm_export_child(struct device * parent,struct pwm_device * pwm)263 static int pwm_export_child(struct device *parent, struct pwm_device *pwm)
264 {
265     struct pwm_export *export;
266     char *pwm_prop[2];
267     int ret;
268 
269     if (test_and_set_bit(PWMF_EXPORTED, &pwm->flags)) {
270         return -EBUSY;
271     }
272 
273     export = kzalloc(sizeof(*export), GFP_KERNEL);
274     if (!export) {
275         clear_bit(PWMF_EXPORTED, &pwm->flags);
276         return -ENOMEM;
277     }
278 
279     export->pwm = pwm;
280     mutex_init(&export->lock);
281 
282     export->child.release = pwm_export_release;
283     export->child.parent = parent;
284     export->child.devt = MKDEV(0, 0);
285     export->child.groups = pwm_groups;
286     dev_set_name(&export->child, "pwm%u", pwm->hwpwm);
287 
288     ret = device_register(&export->child);
289     if (ret) {
290         clear_bit(PWMF_EXPORTED, &pwm->flags);
291         put_device(&export->child);
292         export = NULL;
293         return ret;
294     }
295     pwm_prop[0] = kasprintf(GFP_KERNEL, "EXPORT=pwm%u", pwm->hwpwm);
296     pwm_prop[1] = NULL;
297     kobject_uevent_env(&parent->kobj, KOBJ_CHANGE, pwm_prop);
298     kfree(pwm_prop[0]);
299 
300     return 0;
301 }
302 
pwm_unexport_match(struct device * child,void * data)303 static int pwm_unexport_match(struct device *child, void *data)
304 {
305     return child_to_pwm_device(child) == data;
306 }
307 
pwm_unexport_child(struct device * parent,struct pwm_device * pwm)308 static int pwm_unexport_child(struct device *parent, struct pwm_device *pwm)
309 {
310     struct device *child;
311     char *pwm_prop[2];
312 
313     if (!test_and_clear_bit(PWMF_EXPORTED, &pwm->flags)) {
314         return -ENODEV;
315     }
316 
317     child = device_find_child(parent, pwm, pwm_unexport_match);
318     if (!child) {
319         return -ENODEV;
320     }
321 
322     pwm_prop[0] = kasprintf(GFP_KERNEL, "UNEXPORT=pwm%u", pwm->hwpwm);
323     pwm_prop[1] = NULL;
324     kobject_uevent_env(&parent->kobj, KOBJ_CHANGE, pwm_prop);
325     kfree(pwm_prop[0]);
326 
327     /* for device_find_child() */
328     put_device(child);
329     device_unregister(child);
330     pwm_put(pwm);
331 
332     return 0;
333 }
334 
export_store(struct device * parent,struct device_attribute * attr,const char * buf,size_t len)335 static ssize_t export_store(struct device *parent, struct device_attribute *attr, const char *buf, size_t len)
336 {
337     struct pwm_chip *chip = dev_get_drvdata(parent);
338     struct pwm_device *pwm;
339     unsigned int hwpwm;
340     int ret;
341 
342     ret = kstrtouint(buf, 0, &hwpwm);
343     if (ret < 0) {
344         return ret;
345     }
346 
347     if (hwpwm >= chip->npwm) {
348         return -ENODEV;
349     }
350 
351     pwm = pwm_request_from_chip(chip, hwpwm, "sysfs");
352     if (IS_ERR(pwm)) {
353         return PTR_ERR(pwm);
354     }
355 
356     ret = pwm_export_child(parent, pwm);
357     if (ret < 0) {
358         pwm_put(pwm);
359     }
360 
361     return ret ?: len;
362 }
363 static DEVICE_ATTR_WO(export);
364 
unexport_store(struct device * parent,struct device_attribute * attr,const char * buf,size_t len)365 static ssize_t unexport_store(struct device *parent, struct device_attribute *attr, const char *buf, size_t len)
366 {
367     struct pwm_chip *chip = dev_get_drvdata(parent);
368     unsigned int hwpwm;
369     int ret;
370 
371     ret = kstrtouint(buf, 0, &hwpwm);
372     if (ret < 0) {
373         return ret;
374     }
375 
376     if (hwpwm >= chip->npwm) {
377         return -ENODEV;
378     }
379 
380     ret = pwm_unexport_child(parent, &chip->pwms[hwpwm]);
381 
382     return ret ?: len;
383 }
384 static DEVICE_ATTR_WO(unexport);
385 
npwm_show(struct device * parent,struct device_attribute * attr,char * buf)386 static ssize_t npwm_show(struct device *parent, struct device_attribute *attr, char *buf)
387 {
388     const struct pwm_chip *chip = dev_get_drvdata(parent);
389 
390     return sprintf(buf, "%u\n", chip->npwm);
391 }
392 static DEVICE_ATTR_RO(npwm);
393 
394 static struct attribute *pwm_chip_attrs[] = {
395     &dev_attr_export.attr,
396     &dev_attr_unexport.attr,
397     &dev_attr_npwm.attr,
398     NULL,
399 };
400 ATTRIBUTE_GROUPS(pwm_chip);
401 
402 /* takes export->lock on success */
pwm_class_get_state(struct device * parent,struct pwm_device * pwm,struct pwm_state * state)403 static struct pwm_export *pwm_class_get_state(struct device *parent, struct pwm_device *pwm, struct pwm_state *state)
404 {
405     struct device *child;
406     struct pwm_export *export;
407 
408     if (!test_bit(PWMF_EXPORTED, &pwm->flags)) {
409         return NULL;
410     }
411 
412     child = device_find_child(parent, pwm, pwm_unexport_match);
413     if (!child) {
414         return NULL;
415     }
416 
417     export = child_to_pwm_export(child);
418     put_device(child); /* for device_find_child() */
419 
420     mutex_lock(&export->lock);
421     pwm_get_state(pwm, state);
422 
423     return export;
424 }
425 
pwm_class_apply_state(struct pwm_export * export,struct pwm_device * pwm,struct pwm_state * state)426 static int pwm_class_apply_state(struct pwm_export *export, struct pwm_device *pwm, struct pwm_state *state)
427 {
428     int ret = pwm_apply_state(pwm, state);
429 
430     /* release lock taken in pwm_class_get_state */
431     mutex_unlock(&export->lock);
432 
433     return ret;
434 }
435 
pwm_class_resume_npwm(struct device * parent,unsigned int npwm)436 static int pwm_class_resume_npwm(struct device *parent, unsigned int npwm)
437 {
438     struct pwm_chip *chip = dev_get_drvdata(parent);
439     unsigned int i;
440     int ret = 0;
441 
442     for (i = 0; i < npwm; i++) {
443         struct pwm_device *pwm = &chip->pwms[i];
444         struct pwm_state state;
445         struct pwm_export *export;
446 
447         export = pwm_class_get_state(parent, pwm, &state);
448         if (!export) {
449             continue;
450         }
451 
452         state.enabled = export->suspend.enabled;
453         ret = pwm_class_apply_state(export, pwm, &state);
454         if (ret < 0) {
455             break;
456         }
457     }
458 
459     return ret;
460 }
461 
pwm_class_suspend(struct device * parent)462 static int __maybe_unused pwm_class_suspend(struct device *parent)
463 {
464     struct pwm_chip *chip = dev_get_drvdata(parent);
465     unsigned int i;
466     int ret = 0;
467 
468     for (i = 0; i < chip->npwm; i++) {
469         struct pwm_device *pwm = &chip->pwms[i];
470         struct pwm_state state;
471         struct pwm_export *export;
472 
473         export = pwm_class_get_state(parent, pwm, &state);
474         if (!export) {
475             continue;
476         }
477 
478         export->suspend = state;
479         state.enabled = false;
480         ret = pwm_class_apply_state(export, pwm, &state);
481         if (ret < 0) {
482             /*
483              * roll back the PWM devices that were disabled by
484              * this suspend function.
485              */
486             pwm_class_resume_npwm(parent, i);
487             break;
488         }
489     }
490 
491     return ret;
492 }
493 
pwm_class_resume(struct device * parent)494 static int __maybe_unused pwm_class_resume(struct device *parent)
495 {
496     struct pwm_chip *chip = dev_get_drvdata(parent);
497 
498     return pwm_class_resume_npwm(parent, chip->npwm);
499 }
500 
501 static SIMPLE_DEV_PM_OPS(pwm_class_pm_ops, pwm_class_suspend, pwm_class_resume);
502 
503 static struct class pwm_class = {
504     .name = "pwm",
505     .owner = THIS_MODULE,
506     .dev_groups = pwm_chip_groups,
507     .pm = &pwm_class_pm_ops,
508 };
509 
pwmchip_sysfs_match(struct device * parent,const void * data)510 static int pwmchip_sysfs_match(struct device *parent, const void *data)
511 {
512     return dev_get_drvdata(parent) == data;
513 }
514 
pwmchip_sysfs_export(struct pwm_chip * chip)515 void pwmchip_sysfs_export(struct pwm_chip *chip)
516 {
517     struct device *parent;
518 
519     /*
520      * If device_create() fails the pwm_chip is still usable by
521      * the kernel it's just not exported.
522      */
523     parent = device_create(&pwm_class, chip->dev, MKDEV(0, 0), chip, "pwmchip%d", chip->base);
524     if (IS_ERR(parent)) {
525         dev_warn(chip->dev, "device_create failed for pwm_chip sysfs export\n");
526     }
527 }
528 
pwmchip_sysfs_unexport(struct pwm_chip * chip)529 void pwmchip_sysfs_unexport(struct pwm_chip *chip)
530 {
531     struct device *parent;
532     unsigned int i;
533 
534     parent = class_find_device(&pwm_class, NULL, chip, pwmchip_sysfs_match);
535     if (!parent) {
536         return;
537     }
538 
539     for (i = 0; i < chip->npwm; i++) {
540         struct pwm_device *pwm = &chip->pwms[i];
541 
542         if (test_bit(PWMF_EXPORTED, &pwm->flags)) {
543             pwm_unexport_child(parent, pwm);
544         }
545     }
546 
547     put_device(parent);
548     device_unregister(parent);
549 }
550 
pwm_sysfs_init(void)551 static int __init pwm_sysfs_init(void)
552 {
553     return class_register(&pwm_class);
554 }
555 subsys_initcall(pwm_sysfs_init);
556