Skip to content

Commit 76abbdd

Browse files
H Hartley Sweetenthierryreding
H Hartley Sweeten
authored andcommitted
pwm: Add sysfs interface
Add a simple sysfs interface to the generic PWM framework. /sys/class/pwm/ `-- pwmchipN/ for each PWM chip |-- export (w/o) ask the kernel to export a PWM channel |-- npwm (r/o) number of PWM channels in this PWM chip |-- pwmX/ for each exported PWM channel | |-- duty_cycle (r/w) duty cycle (in nanoseconds) | |-- enable (r/w) enable/disable PWM | |-- period (r/w) period (in nanoseconds) | `-- polarity (r/w) polarity of PWM (normal/inversed) `-- unexport (w/o) return a PWM channel to the kernel Based on work by Lars Poeschel. Signed-off-by: H Hartley Sweeten <hsweeten@visionengravers.com> Cc: Thierry Reding <thierry.reding@gmail.com> Cc: Lars Poeschel <poeschel@lemonage.de> Cc: Ryan Mallon <rmallon@gmail.com> Cc: Rob Landley <rob@landley.net> Signed-off-by: Thierry Reding <thierry.reding@gmail.com>
1 parent 3dd0a90 commit 76abbdd

File tree

7 files changed

+524
-3
lines changed

7 files changed

+524
-3
lines changed
+79
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,79 @@
1+
What: /sys/class/pwm/
2+
Date: May 2013
3+
KernelVersion: 3.11
4+
Contact: H Hartley Sweeten <hsweeten@visionengravers.com>
5+
Description:
6+
The pwm/ class sub-directory belongs to the Generic PWM
7+
Framework and provides a sysfs interface for using PWM
8+
channels.
9+
10+
What: /sys/class/pwm/pwmchipN/
11+
Date: May 2013
12+
KernelVersion: 3.11
13+
Contact: H Hartley Sweeten <hsweeten@visionengravers.com>
14+
Description:
15+
A /sys/class/pwm/pwmchipN directory is created for each
16+
probed PWM controller/chip where N is the base of the
17+
PWM chip.
18+
19+
What: /sys/class/pwm/pwmchipN/npwm
20+
Date: May 2013
21+
KernelVersion: 3.11
22+
Contact: H Hartley Sweeten <hsweeten@visionengravers.com>
23+
Description:
24+
The number of PWM channels supported by the PWM chip.
25+
26+
What: /sys/class/pwm/pwmchipN/export
27+
Date: May 2013
28+
KernelVersion: 3.11
29+
Contact: H Hartley Sweeten <hsweeten@visionengravers.com>
30+
Description:
31+
Exports a PWM channel from the PWM chip for sysfs control.
32+
Value is between 0 and /sys/class/pwm/pwmchipN/npwm - 1.
33+
34+
What: /sys/class/pwm/pwmchipN/unexport
35+
Date: May 2013
36+
KernelVersion: 3.11
37+
Contact: H Hartley Sweeten <hsweeten@visionengravers.com>
38+
Description:
39+
Unexports a PWM channel.
40+
41+
What: /sys/class/pwm/pwmchipN/pwmX
42+
Date: May 2013
43+
KernelVersion: 3.11
44+
Contact: H Hartley Sweeten <hsweeten@visionengravers.com>
45+
Description:
46+
A /sys/class/pwm/pwmchipN/pwmX directory is created for
47+
each exported PWM channel where X is the exported PWM
48+
channel number.
49+
50+
What: /sys/class/pwm/pwmchipN/pwmX/period
51+
Date: May 2013
52+
KernelVersion: 3.11
53+
Contact: H Hartley Sweeten <hsweeten@visionengravers.com>
54+
Description:
55+
Sets the PWM signal period in nanoseconds.
56+
57+
What: /sys/class/pwm/pwmchipN/pwmX/duty_cycle
58+
Date: May 2013
59+
KernelVersion: 3.11
60+
Contact: H Hartley Sweeten <hsweeten@visionengravers.com>
61+
Description:
62+
Sets the PWM signal duty cycle in nanoseconds.
63+
64+
What: /sys/class/pwm/pwmchipN/pwmX/polarity
65+
Date: May 2013
66+
KernelVersion: 3.11
67+
Contact: H Hartley Sweeten <hsweeten@visionengravers.com>
68+
Description:
69+
Sets the output polarity of the PWM signal to "normal" or
70+
"inversed".
71+
72+
What: /sys/class/pwm/pwmchipN/pwmX/enable
73+
Date: May 2013
74+
KernelVersion: 3.11
75+
Contact: H Hartley Sweeten <hsweeten@visionengravers.com>
76+
Description:
77+
Enable/disable the PWM signal.
78+
0 is disabled
79+
1 is enabled

Documentation/pwm.txt

+37
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,43 @@ int pwm_config(struct pwm_device *pwm, int duty_ns, int period_ns);
4545

4646
To start/stop toggling the PWM output use pwm_enable()/pwm_disable().
4747

48+
Using PWMs with the sysfs interface
49+
-----------------------------------
50+
51+
If CONFIG_SYSFS is enabled in your kernel configuration a simple sysfs
52+
interface is provided to use the PWMs from userspace. It is exposed at
53+
/sys/class/pwm/. Each probed PWM controller/chip will be exported as
54+
pwmchipN, where N is the base of the PWM chip. Inside the directory you
55+
will find:
56+
57+
npwm - The number of PWM channels this chip supports (read-only).
58+
59+
export - Exports a PWM channel for use with sysfs (write-only).
60+
61+
unexport - Unexports a PWM channel from sysfs (write-only).
62+
63+
The PWM channels are numbered using a per-chip index from 0 to npwm-1.
64+
65+
When a PWM channel is exported a pwmX directory will be created in the
66+
pwmchipN directory it is associated with, where X is the number of the
67+
channel that was exported. The following properties will then be available:
68+
69+
period - The total period of the PWM signal (read/write).
70+
Value is in nanoseconds and is the sum of the active and inactive
71+
time of the PWM.
72+
73+
duty_cycle - The active time of the PWM signal (read/write).
74+
Value is in nanoseconds and must be less than the period.
75+
76+
polarity - Changes the polarity of the PWM signal (read/write).
77+
Writes to this property only work if the PWM chip supports changing
78+
the polarity. The polarity can only be changed if the PWM is not
79+
enabled. Value is the string "normal" or "inversed".
80+
81+
enable - Enable/disable the PWM signal (read/write).
82+
0 - disabled
83+
1 - enabled
84+
4885
Implementing a PWM driver
4986
-------------------------
5087

drivers/pwm/Kconfig

+4
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,10 @@ menuconfig PWM
2828

2929
if PWM
3030

31+
config PWM_SYSFS
32+
bool
33+
default y if SYSFS
34+
3135
config PWM_AB8500
3236
tristate "AB8500 PWM support"
3337
depends on AB8500_CORE && ARCH_U8500

drivers/pwm/Makefile

+1
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
obj-$(CONFIG_PWM) += core.o
2+
obj-$(CONFIG_PWM_SYSFS) += sysfs.o
23
obj-$(CONFIG_PWM_AB8500) += pwm-ab8500.o
34
obj-$(CONFIG_PWM_ATMEL_TCB) += pwm-atmel-tcb.o
45
obj-$(CONFIG_PWM_BFIN) += pwm-bfin.o

drivers/pwm/core.c

+23-2
Original file line numberDiff line numberDiff line change
@@ -274,6 +274,8 @@ int pwmchip_add(struct pwm_chip *chip)
274274
if (IS_ENABLED(CONFIG_OF))
275275
of_pwmchip_add(chip);
276276

277+
pwmchip_sysfs_export(chip);
278+
277279
out:
278280
mutex_unlock(&pwm_lock);
279281
return ret;
@@ -310,6 +312,8 @@ int pwmchip_remove(struct pwm_chip *chip)
310312

311313
free_pwms(chip);
312314

315+
pwmchip_sysfs_unexport(chip);
316+
313317
out:
314318
mutex_unlock(&pwm_lock);
315319
return ret;
@@ -402,10 +406,19 @@ EXPORT_SYMBOL_GPL(pwm_free);
402406
*/
403407
int pwm_config(struct pwm_device *pwm, int duty_ns, int period_ns)
404408
{
409+
int err;
410+
405411
if (!pwm || duty_ns < 0 || period_ns <= 0 || duty_ns > period_ns)
406412
return -EINVAL;
407413

408-
return pwm->chip->ops->config(pwm->chip, pwm, duty_ns, period_ns);
414+
err = pwm->chip->ops->config(pwm->chip, pwm, duty_ns, period_ns);
415+
if (err)
416+
return err;
417+
418+
pwm->duty_cycle = duty_ns;
419+
pwm->period = period_ns;
420+
421+
return 0;
409422
}
410423
EXPORT_SYMBOL_GPL(pwm_config);
411424

@@ -418,6 +431,8 @@ EXPORT_SYMBOL_GPL(pwm_config);
418431
*/
419432
int pwm_set_polarity(struct pwm_device *pwm, enum pwm_polarity polarity)
420433
{
434+
int err;
435+
421436
if (!pwm || !pwm->chip->ops)
422437
return -EINVAL;
423438

@@ -427,7 +442,13 @@ int pwm_set_polarity(struct pwm_device *pwm, enum pwm_polarity polarity)
427442
if (test_bit(PWMF_ENABLED, &pwm->flags))
428443
return -EBUSY;
429444

430-
return pwm->chip->ops->set_polarity(pwm->chip, pwm, polarity);
445+
err = pwm->chip->ops->set_polarity(pwm->chip, pwm, polarity);
446+
if (err)
447+
return err;
448+
449+
pwm->polarity = polarity;
450+
451+
return 0;
431452
}
432453
EXPORT_SYMBOL_GPL(pwm_set_polarity);
433454

0 commit comments

Comments
 (0)