pwm: add sysfs interface
Subsystems (2)
PATCH v2 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
|-- npwn (r/o) number of PWM channels in this PWM chip
|-- pwmX/ for each exported PWM channel (per PWM chip)
| |-- duty_ns (r/w) duty cycle (in nanoseconds)
| |-- enable (r/w) enable/disable PWM
| |-- period_ns (r/w) period (in nanoseconds)
| `-- polarity (r/w) polarity of PWM
`-- unexport (w/o) return a PWM channel to the kernel---
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.
Documentation/ABI/testing/sysfs-class-pwm | 80 +++++++ Documentation/pwm.txt | 39 ++++ drivers/pwm/Kconfig | 12 + drivers/pwm/Makefile | 1 + drivers/pwm/core.c | 25 ++- drivers/pwm/pwm-sysfs.c | 350 ++++++++++++++++++++++++++++++ include/linux/pwm.h | 28 +++ 7 files changed, 533 insertions(+), 2 deletions(-) create mode 100644 Documentation/ABI/testing/sysfs-class-pwm create mode 100644 drivers/pwm/pwm-sysfs.c
Documentation/ABI/testing/sysfs-class-pwm new file +80 -0
@@ -0,0 +1,80 @@ +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 PWM channel number. + +What: /sys/class/pwm/pwmchipN/pwmX/period_ns +Date: May 2013 +KernelVersion: 3.11 +Contact: H Hartley Sweeten <[email protected]> +Description: + Sets the PWM period in nanoseconds. + +What: /sys/class/pwm/pwmchipN/pwmX/duty_ns +Date: May 2013 +KernelVersion: 3.11 +Contact: H Hartley Sweeten <[email protected]> +Description: + Sets the PWM duty cycle in nanoseconds, default is half the + /sys/class/pwm/pwmchipN/pwmX/period_ns. + +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. + 0 is normal polarity + 1 is inversed polarity + +What: /sys/class/pwm/pwmchipN/pwmX/enable +Date: May 2013 +KernelVersion: 3.11 +Contact: H Hartley Sweeten <[email protected]> +Description: + Enables/disables the PWM. + 0 is disabled + 1 is enabled
Documentation/pwm.txt +39 -0
@@ -45,6 +45,45 @@ 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 +----------------------------------- + +You have to enable CONFIG_PWM_SYSFS in your kernel configuration to use +the sysfs interface. 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 PWM chip specific from 0 to npwn-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 channel number +that was exported. The following properties will then be available: + +period_ns - The total period of the PWM (read/write). + Value is in nanoseconds and is the sum of the active and inactive + time of the PWM. If duty_ns is zero when this property is written + it will be automatically set to half the period_ns. + +duty_ns - The active time of the PWM (read/write). + Value is in nanoseconds and must be less than the period_ns. + +polarity - Changes the polarity of the PWM (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. + 0 - normal polarity + 1 - inversed polarity + +enable - Enables/disables the PWM (read/write). + 0 - disabled + 1 - enabled + Implementing a PWM driver -------------------------
drivers/pwm/Kconfig +12 -0
@@ -28,6 +28,18 @@ menuconfig PWM if PWM +config PWM_SYSFS + bool "/sys/class/pwm/... (sysfs interface)" + depends on SYSFS + help + Say Y here to provide a sysfs interface to control PWMs. + + For every instance of a PWM device there is a pwmchipN directory + created in /sys/class/pwm. Use the export attribute to request + a PWM to be accessible from userspace and the unexport attribute + to return the PWM to the kernel. Each exported PWM will have a + pwmX directory in the pwmchipN it is associated with. + 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) += pwm-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 = 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/pwm-sysfs.c new file +350 -0
350 lines not on this page · raw message
include/linux/pwm.h +28 -0
@@ -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,10 @@ struct pwm_device {struct pwm_chip *chip;void *chip_data; +struct device *dev;/* for sysfs export */ unsigned int period;/* in nanoseconds */ +unsigned int duty;/* in nanoseconds */ +enum pwm_polarity polarity; };static inline void pwm_set_period (struct pwm_device *pwm,unsigned int period)
@@ -100,6 +104,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 = duty; +} + +static inline unsigned int pwm_get_duty_cycle (struct pwm_device *pwm) +{ +return pwm ? pwm->duty :0 ; +} +/* * pwm_set_polarity - configure the polarity of a PWM signal */
@@ -278,4 +293,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
Quoted 34 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 |-- npwn (r/o) number of PWM channels in this PWM chip |-- pwmX/ for each exported PWM channel (per PWM chip) | |-- duty_ns (r/w) duty cycle (in nanoseconds) | |-- enable (r/w) enable/disable PWM | |-- period_ns (r/w) period (in nanoseconds) | `-- polarity (r/w) polarity of PWM `-- 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]>---
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.Documentation/ABI/testing/sysfs-class-pwm | 80 +++++++ Documentation/pwm.txt | 39 ++++ drivers/pwm/Kconfig | 12 + drivers/pwm/Makefile | 1 + drivers/pwm/core.c | 25 ++- drivers/pwm/pwm-sysfs.c | 350 ++++++++++++++++++++++++++++++ include/linux/pwm.h | 28 +++ 7 files changed, 533 insertions(+), 2 deletions(-) create mode 100644 Documentation/ABI/testing/sysfs-class-pwm create mode 100644 drivers/pwm/pwm-sysfs.c
<snip>
Quoted 1 line
drivers/pwm/pwm-sysfs.c +0
-0
<snip>
drivers/pwm/pwm-sysfs.c line 336
Quoted 9 lines
drivers/pwm/pwm-sysfs.c +9
-0+void pwmchip_sysfs_export (struct pwm_chip *chip) +{ +/* +* If device_create() fails the pwm_chip is still usable by +* the kernel its just not exported. +*/ + chip->dev =device_create (&pwm_class, chip->dev,MKDEV (0 ,0 ), chip, +"pwmchip%d" , chip->base); +}
I just realized this will not work.
chip->dev is initialized by the PWM driver before calling pwmchip_add().
I'll post a v3 shortly.
Regards,
Hartley