pwm: add sysfs interface
Subsystems (2)
PATCH v5 1/1 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---
v5: * rename the 'duty' attribute to 'duty_cycle'
* make the Kconfig option hidden and enabled when CONFIG_SYSFS is enabled
* use sysfs_streq() in pwm_polarity_store()
v4: * address a number of issues pointed out by Thierry Reding
- fix some typos and wording issues in the Documentation
- rename the new source file to sysfs.c
- rename some of the variables in sysfs.c to clarify them
- fix the period store so it does not change the duty cycle
- change the polarity attribute to use a string representation
- add a warning message is the pwmchip_sysfs_export() fails
v3: * fix an issue with the export/unexport of the PWM chip
v2: * add API documentation and update Documentation/pwm.txt
* fix some issues pointed out by Ryan Mallon
* add the pwm attributes to dev.groups so they are created when the device is registered for the exported PWM
v1: * Based on previous work by Lars Poecshel
Documentation/ABI/testing/sysfs-class-pwm | 79 +++++++ Documentation/pwm.txt | 37 ++++ drivers/pwm/Kconfig | 4 + drivers/pwm/Makefile | 1 + drivers/pwm/core.c | 25 ++- drivers/pwm/sysfs.c | 352 ++++++++++++++++++++++++++++++ include/linux/pwm.h | 29 ++- 7 files changed, 524 insertions(+), 3 deletions(-) create mode 100644 Documentation/ABI/testing/sysfs-class-pwm create mode 100644 drivers/pwm/sysfs.c
Documentation/ABI/testing/sysfs-class-pwm new file +79 -0
@@ -0,0 +1,79 @@ +What: /sys/class/pwm/ +Date: May 2013 +KernelVersion: 3.11 +Contact: H Hartley Sweeten <[email protected]> +Description: + The pwm/ class sub-directory belongs to the Generic PWM + Framework and provides a sysfs interface for using PWM + channels. + +What: /sys/class/pwm/pwmchipN/ +Date: May 2013 +KernelVersion: 3.11 +Contact: H Hartley Sweeten <[email protected]> +Description: + A /sys/class/pwm/pwmchipN directory is created for each + probed PWM controller/chip where N is the base of the + PWM chip. + +What: /sys/class/pwm/pwmchipN/npwm +Date: May 2013 +KernelVersion: 3.11 +Contact: H Hartley Sweeten <[email protected]> +Description: + The number of PWM channels supported by the PWM chip. + +What: /sys/class/pwm/pwmchipN/export +Date: May 2013 +KernelVersion: 3.11 +Contact: H Hartley Sweeten <[email protected]> +Description: + Exports a PWM channel from the PWM chip for sysfs control. + Value is between 0 and /sys/class/pwm/pwmchipN/npwm - 1. + +What: /sys/class/pwm/pwmchipN/unexport +Date: May 2013 +KernelVersion: 3.11 +Contact: H Hartley Sweeten <[email protected]> +Description: + Unexports a PWM channel. + +What: /sys/class/pwm/pwmchipN/pwmX +Date: May 2013 +KernelVersion: 3.11 +Contact: H Hartley Sweeten <[email protected]> +Description: + A /sys/class/pwm/pwmchipN/pwmX directory is created for + each exported PWM channel where X is the exported PWM + channel number. + +What: /sys/class/pwm/pwmchipN/pwmX/period +Date: May 2013 +KernelVersion: 3.11 +Contact: H Hartley Sweeten <[email protected]> +Description: + Sets the PWM signal period in nanoseconds. + +What: /sys/class/pwm/pwmchipN/pwmX/duty_cycle +Date: May 2013 +KernelVersion: 3.11 +Contact: H Hartley Sweeten <[email protected]> +Description: + Sets the PWM signal duty cycle in nanoseconds. + +What: /sys/class/pwm/pwmchipN/pwmX/polarity +Date: May 2013 +KernelVersion: 3.11 +Contact: H Hartley Sweeten <[email protected]> +Description: + Sets the output polarity of the PWM signal to "normal" or + "inversed". + +What: /sys/class/pwm/pwmchipN/pwmX/enable +Date: May 2013 +KernelVersion: 3.11 +Contact: H Hartley Sweeten <[email protected]> +Description: + Enable/disable the PWM signal. + 0 is disabled + 1 is enabled
Documentation/pwm.txt +37 -0
@@ -45,6 +45,43 @@ int pwm_config(struct pwm_device *pwm, int duty_ns, int period_ns); To start/stop toggling the PWM output use pwm_enable()/pwm_disable(). +Using PWMs with the sysfs interface +----------------------------------- + +If CONFIG_SYSFS is enabled in your kernel configuration a simple sysfs +interface is provided to use the PWMs from userspace. It is exposed at +/sys/class/pwm/. Each probed PWM controller/chip will be exported as +pwmchipN, where N is the base of the PWM chip. Inside the directory you +will find: + +npwm - The number of PWM channels this chip supports (read-only). + +export - Exports a PWM channel for use with sysfs (write-only). + +unexport - Unexports a PWM channel from sysfs (write-only). + +The PWM channels are numbered using a per-chip index from 0 to npwm-1. + +When a PWM channel is exported a pwmX directory will be created in the +pwmchipN directory it is associated with, where X is the number of the +channel that was exported. The following properties will then be available: + +period - The total period of the PWM signal (read/write). + Value is in nanoseconds and is the sum of the active and inactive + time of the PWM. + +duty_cycle - The active time of the PWM signal (read/write). + Value is in nanoseconds and must be less than the period. + +polarity - Changes the polarity of the PWM signal (read/write). + Writes to this property only work if the PWM chip supports changing + the polarity. The polarity can only be changed if the PWM is not + enabled. Value is the string "normal" or "inversed". + +enable - Enable/disable the PWM signal (read/write). + 0 - disabled + 1 - enabled + Implementing a PWM driver -------------------------
drivers/pwm/Kconfig +4 -0
@@ -28,6 +28,10 @@ menuconfig PWM if PWM +config PWM_SYSFS + bool + default y if SYSFS + config PWM_AB8500 tristate "AB8500 PWM support" depends on AB8500_CORE && ARCH_U8500
drivers/pwm/Makefile +1 -0
@@ -1,4 +1,5 @@ obj-$(CONFIG_PWM) += core.o +obj-$(CONFIG_PWM_SYSFS) += sysfs.o obj-$(CONFIG_PWM_AB8500) += pwm-ab8500.o obj-$(CONFIG_PWM_ATMEL_TCB) += pwm-atmel-tcb.o obj-$(CONFIG_PWM_BFIN) += pwm-bfin.o
drivers/pwm/core.c +23 -2
@@ -274,6 +274,8 @@ int pwmchip_add(struct pwm_chip *chip)if (IS_ENABLED (CONFIG_OF ))of_pwmchip_add (chip); +pwmchip_sysfs_export (chip); + out:mutex_unlock (&pwm_lock);return ret;
@@ -310,6 +312,8 @@ int pwmchip_remove(struct pwm_chip *chip)free_pwms (chip); +pwmchip_sysfs_unexport (chip); + out:mutex_unlock (&pwm_lock);return ret;
@@ -402,10 +406,19 @@ EXPORT_SYMBOL_GPL(pwm_free);*/ int pwm_config (struct pwm_device *pwm,int duty_ns,int period_ns) { +int err; +if (!pwm || duty_ns <0 || period_ns <=0 || duty_ns > period_ns)return -EINVAL ; -return pwm->chip->ops->config (pwm->chip, pwm, duty_ns, period_ns); + err = pwm->chip->ops->config (pwm->chip, pwm, duty_ns, period_ns); +if (err) +return err; + + pwm->duty_cycle = duty_ns; + pwm->period = period_ns; + +return 0 ; }EXPORT_SYMBOL_GPL (pwm_config);
@@ -418,6 +431,8 @@ EXPORT_SYMBOL_GPL(pwm_config);*/ int pwm_set_polarity (struct pwm_device *pwm,enum pwm_polarity polarity) { +int err; +if (!pwm || !pwm->chip->ops)return -EINVAL ;
@@ -427,7 +442,13 @@ int pwm_set_polarity(struct pwm_device *pwm, enum pwm_polarity polarity)if (test_bit (PWMF_ENABLED , &pwm->flags))return -EBUSY ; -return pwm->chip->ops->set_polarity (pwm->chip, pwm, polarity); + err = pwm->chip->ops->set_polarity (pwm->chip, pwm, polarity); +if (err) +return err; + + pwm->polarity = polarity; + +return 0 ; }EXPORT_SYMBOL_GPL (pwm_set_polarity);
drivers/pwm/sysfs.c new file +352 -0
352 lines not on this page · raw message
include/linux/pwm.h +28 -1
@@ -76,6 +76,7 @@ enum pwm_polarity {enum {PWMF_REQUESTED =1 <<0 ,PWMF_ENABLED =1 <<1 , +PWMF_EXPORTED =1 <<2 , };struct pwm_device {
@@ -86,7 +87,9 @@ struct pwm_device {struct pwm_chip *chip;void *chip_data; -unsigned int period;/* in nanoseconds */ +unsigned int period;/* in nanoseconds */ +unsigned int duty_cycle;/* in nanoseconds */ +enum pwm_polarity polarity; };static inline void pwm_set_period (struct pwm_device *pwm,unsigned int period)
@@ -100,6 +103,17 @@ static inline unsigned int pwm_get_period(struct pwm_device *pwm)return pwm ? pwm->period :0 ; } +static inline void pwm_set_duty_cycle (struct pwm_device *pwm,unsigned int duty) +{ +if (pwm) + pwm->duty_cycle = duty; +} + +static inline unsigned int pwm_get_duty_cycle (struct pwm_device *pwm) +{ +return pwm ? pwm->duty_cycle :0 ; +} +/* * pwm_set_polarity - configure the polarity of a PWM signal */
@@ -278,4 +292,17 @@ static inline void pwm_add_table(struct pwm_lookup *table, size_t num) }#endif +#ifdef CONFIG_PWM_SYSFS +void pwmchip_sysfs_export (struct pwm_chip *chip); +void pwmchip_sysfs_unexport (struct pwm_chip *chip); +#else +static inline void pwmchip_sysfs_export (struct pwm_chip *chip) +{ +} + +static inline void pwmchip_sysfs_unexport (struct pwm_chip *chip) +{ +} +#endif /* CONFIG_PWM_SYSFS */ +#endif /* __LINUX_PWM_H */
Signature · 1 line
1.8.1.4
Thierry Reding
AppliedQuoted 28 lines · H Hartley Sweeten
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 kernelSigned-off-by H Hartley Sweeten <[email protected]>Cc Thierry Reding <[email protected]>Cc Lars Poeschel <[email protected]>Cc Ryan Mallon <[email protected]>Cc Rob Landley <[email protected]>---
v5: * rename the 'duty' attribute to 'duty_cycle'
* make theKconfigoption hidden and enabled whenCONFIG_SYSFSis enabled
* usesysfs_streq()inpwm_polarity_store()
v4: * address a number of issues pointed out by Thierry Reding
- fix some typos and wording issues in the Documentation
- rename the new source file tosysfs.c
- rename some of the variables insysfs.cto clarify them
- fix the period store so it does not change the duty cycle
Quoted 8 lines
- change the polarity attribute to use a string representation
- add a warning message is thepwmchip_sysfs_export()fails
v3: * fix an issue with the export/unexport of the PWM chip
v2: * add API documentation and updateDocumentation/pwm.txt
* fix some issues pointed out by Ryan Mallon
* add the pwm attributes to dev.groups so they are created when the device is registered for the exported PWM
v1: * Based on previous work by Lars Poecshel
Applied, thanks.
Thierry