11a189b97SRussell King #ifndef __LINUX_PWM_H 21a189b97SRussell King #define __LINUX_PWM_H 31a189b97SRussell King 40bcf168bSTushar Behera #include <linux/err.h> 5d1cd2142SJonathan Richardson #include <linux/mutex.h> 67299ab70SThierry Reding #include <linux/of.h> 77299ab70SThierry Reding 81a189b97SRussell King struct pwm_device; 962099abfSThierry Reding struct seq_file; 101a189b97SRussell King 11557fe99dSSascha Hauer #if IS_ENABLED(CONFIG_PWM) 121a189b97SRussell King /* 131a189b97SRussell King * pwm_request - request a PWM device 141a189b97SRussell King */ 151a189b97SRussell King struct pwm_device *pwm_request(int pwm_id, const char *label); 161a189b97SRussell King 171a189b97SRussell King /* 181a189b97SRussell King * pwm_free - free a PWM device 191a189b97SRussell King */ 201a189b97SRussell King void pwm_free(struct pwm_device *pwm); 211a189b97SRussell King 221a189b97SRussell King /* 231a189b97SRussell King * pwm_config - change a PWM device configuration 241a189b97SRussell King */ 251a189b97SRussell King int pwm_config(struct pwm_device *pwm, int duty_ns, int period_ns); 261a189b97SRussell King 271a189b97SRussell King /* 281a189b97SRussell King * pwm_enable - start a PWM output toggling 291a189b97SRussell King */ 301a189b97SRussell King int pwm_enable(struct pwm_device *pwm); 311a189b97SRussell King 321a189b97SRussell King /* 331a189b97SRussell King * pwm_disable - stop a PWM output toggling 341a189b97SRussell King */ 351a189b97SRussell King void pwm_disable(struct pwm_device *pwm); 360bcf168bSTushar Behera #else 370bcf168bSTushar Behera static inline struct pwm_device *pwm_request(int pwm_id, const char *label) 380bcf168bSTushar Behera { 390bcf168bSTushar Behera return ERR_PTR(-ENODEV); 400bcf168bSTushar Behera } 411a189b97SRussell King 420bcf168bSTushar Behera static inline void pwm_free(struct pwm_device *pwm) 430bcf168bSTushar Behera { 440bcf168bSTushar Behera } 450bcf168bSTushar Behera 460bcf168bSTushar Behera static inline int pwm_config(struct pwm_device *pwm, int duty_ns, int period_ns) 470bcf168bSTushar Behera { 480bcf168bSTushar Behera return -EINVAL; 490bcf168bSTushar Behera } 500bcf168bSTushar Behera 510bcf168bSTushar Behera static inline int pwm_enable(struct pwm_device *pwm) 520bcf168bSTushar Behera { 530bcf168bSTushar Behera return -EINVAL; 540bcf168bSTushar Behera } 550bcf168bSTushar Behera 560bcf168bSTushar Behera static inline void pwm_disable(struct pwm_device *pwm) 570bcf168bSTushar Behera { 580bcf168bSTushar Behera } 590bcf168bSTushar Behera #endif 600bcf168bSTushar Behera 610c2498f1SSascha Hauer struct pwm_chip; 620c2498f1SSascha Hauer 630aa0869cSPhilip, Avinash /** 640aa0869cSPhilip, Avinash * enum pwm_polarity - polarity of a PWM signal 650aa0869cSPhilip, Avinash * @PWM_POLARITY_NORMAL: a high signal for the duration of the duty- 660aa0869cSPhilip, Avinash * cycle, followed by a low signal for the remainder of the pulse 670aa0869cSPhilip, Avinash * period 680aa0869cSPhilip, Avinash * @PWM_POLARITY_INVERSED: a low signal for the duration of the duty- 690aa0869cSPhilip, Avinash * cycle, followed by a high signal for the remainder of the pulse 700aa0869cSPhilip, Avinash * period 710aa0869cSPhilip, Avinash */ 720aa0869cSPhilip, Avinash enum pwm_polarity { 730aa0869cSPhilip, Avinash PWM_POLARITY_NORMAL, 740aa0869cSPhilip, Avinash PWM_POLARITY_INVERSED, 750aa0869cSPhilip, Avinash }; 760aa0869cSPhilip, Avinash 77*e39c0df1SBoris Brezillon /** 78*e39c0df1SBoris Brezillon * struct pwm_args - board-dependent PWM arguments 79*e39c0df1SBoris Brezillon * @period: reference period 80*e39c0df1SBoris Brezillon * @polarity: reference polarity 81*e39c0df1SBoris Brezillon * 82*e39c0df1SBoris Brezillon * This structure describes board-dependent arguments attached to a PWM 83*e39c0df1SBoris Brezillon * device. These arguments are usually retrieved from the PWM lookup table or 84*e39c0df1SBoris Brezillon * device tree. 85*e39c0df1SBoris Brezillon * 86*e39c0df1SBoris Brezillon * Do not confuse this with the PWM state: PWM arguments represent the initial 87*e39c0df1SBoris Brezillon * configuration that users want to use on this PWM device rather than the 88*e39c0df1SBoris Brezillon * current PWM hardware state. 89*e39c0df1SBoris Brezillon */ 90*e39c0df1SBoris Brezillon struct pwm_args { 91*e39c0df1SBoris Brezillon unsigned int period; 92*e39c0df1SBoris Brezillon enum pwm_polarity polarity; 93*e39c0df1SBoris Brezillon }; 94*e39c0df1SBoris Brezillon 95f051c466SThierry Reding enum { 96f051c466SThierry Reding PWMF_REQUESTED = 1 << 0, 97f051c466SThierry Reding PWMF_ENABLED = 1 << 1, 9876abbddeSH Hartley Sweeten PWMF_EXPORTED = 1 << 2, 99f051c466SThierry Reding }; 100f051c466SThierry Reding 10104883802SThierry Reding /** 10204883802SThierry Reding * struct pwm_device - PWM channel object 10304883802SThierry Reding * @label: name of the PWM device 10404883802SThierry Reding * @flags: flags associated with the PWM device 10504883802SThierry Reding * @hwpwm: per-chip relative index of the PWM device 10604883802SThierry Reding * @pwm: global index of the PWM device 10704883802SThierry Reding * @chip: PWM chip providing this PWM device 10804883802SThierry Reding * @chip_data: chip-private data associated with the PWM device 109d1cd2142SJonathan Richardson * @lock: used to serialize accesses to the PWM device where necessary 11004883802SThierry Reding * @period: period of the PWM signal (in nanoseconds) 11104883802SThierry Reding * @duty_cycle: duty cycle of the PWM signal (in nanoseconds) 11204883802SThierry Reding * @polarity: polarity of the PWM signal 113*e39c0df1SBoris Brezillon * @args: PWM arguments 11404883802SThierry Reding */ 115f051c466SThierry Reding struct pwm_device { 116f051c466SThierry Reding const char *label; 117f051c466SThierry Reding unsigned long flags; 118f051c466SThierry Reding unsigned int hwpwm; 119f051c466SThierry Reding unsigned int pwm; 120f051c466SThierry Reding struct pwm_chip *chip; 121f051c466SThierry Reding void *chip_data; 122d1cd2142SJonathan Richardson struct mutex lock; 123f051c466SThierry Reding 1246bc7064aSThierry Reding unsigned int period; 1256bc7064aSThierry Reding unsigned int duty_cycle; 12676abbddeSH Hartley Sweeten enum pwm_polarity polarity; 127*e39c0df1SBoris Brezillon 128*e39c0df1SBoris Brezillon struct pwm_args args; 129f051c466SThierry Reding }; 130f051c466SThierry Reding 1315c31252cSBoris Brezillon static inline bool pwm_is_enabled(const struct pwm_device *pwm) 1325c31252cSBoris Brezillon { 1335c31252cSBoris Brezillon return test_bit(PWMF_ENABLED, &pwm->flags); 1345c31252cSBoris Brezillon } 1355c31252cSBoris Brezillon 136f051c466SThierry Reding static inline void pwm_set_period(struct pwm_device *pwm, unsigned int period) 137f051c466SThierry Reding { 138f051c466SThierry Reding if (pwm) 139f051c466SThierry Reding pwm->period = period; 140f051c466SThierry Reding } 141f051c466SThierry Reding 142a1cf4217SBoris Brezillon static inline unsigned int pwm_get_period(const struct pwm_device *pwm) 143f051c466SThierry Reding { 144f051c466SThierry Reding return pwm ? pwm->period : 0; 145f051c466SThierry Reding } 146f051c466SThierry Reding 14776abbddeSH Hartley Sweeten static inline void pwm_set_duty_cycle(struct pwm_device *pwm, unsigned int duty) 14876abbddeSH Hartley Sweeten { 14976abbddeSH Hartley Sweeten if (pwm) 15076abbddeSH Hartley Sweeten pwm->duty_cycle = duty; 15176abbddeSH Hartley Sweeten } 15276abbddeSH Hartley Sweeten 153a1cf4217SBoris Brezillon static inline unsigned int pwm_get_duty_cycle(const struct pwm_device *pwm) 15476abbddeSH Hartley Sweeten { 15576abbddeSH Hartley Sweeten return pwm ? pwm->duty_cycle : 0; 15676abbddeSH Hartley Sweeten } 15776abbddeSH Hartley Sweeten 1580aa0869cSPhilip, Avinash /* 1590aa0869cSPhilip, Avinash * pwm_set_polarity - configure the polarity of a PWM signal 1600aa0869cSPhilip, Avinash */ 1610aa0869cSPhilip, Avinash int pwm_set_polarity(struct pwm_device *pwm, enum pwm_polarity polarity); 1620aa0869cSPhilip, Avinash 163011e7631SBoris Brezillon static inline enum pwm_polarity pwm_get_polarity(const struct pwm_device *pwm) 164011e7631SBoris Brezillon { 165011e7631SBoris Brezillon return pwm ? pwm->polarity : PWM_POLARITY_NORMAL; 166011e7631SBoris Brezillon } 167011e7631SBoris Brezillon 168*e39c0df1SBoris Brezillon static inline void pwm_get_args(const struct pwm_device *pwm, 169*e39c0df1SBoris Brezillon struct pwm_args *args) 170*e39c0df1SBoris Brezillon { 171*e39c0df1SBoris Brezillon *args = pwm->args; 172*e39c0df1SBoris Brezillon } 173*e39c0df1SBoris Brezillon 174*e39c0df1SBoris Brezillon static inline void pwm_apply_args(struct pwm_device *pwm) 175*e39c0df1SBoris Brezillon { 176*e39c0df1SBoris Brezillon pwm_set_period(pwm, pwm->args.period); 177*e39c0df1SBoris Brezillon pwm_set_polarity(pwm, pwm->args.polarity); 178*e39c0df1SBoris Brezillon } 179*e39c0df1SBoris Brezillon 1800c2498f1SSascha Hauer /** 1810c2498f1SSascha Hauer * struct pwm_ops - PWM controller operations 1820c2498f1SSascha Hauer * @request: optional hook for requesting a PWM 1830c2498f1SSascha Hauer * @free: optional hook for freeing a PWM 1840c2498f1SSascha Hauer * @config: configure duty cycles and period length for this PWM 1850aa0869cSPhilip, Avinash * @set_polarity: configure the polarity of this PWM 1860c2498f1SSascha Hauer * @enable: enable PWM output toggling 1870c2498f1SSascha Hauer * @disable: disable PWM output toggling 18862099abfSThierry Reding * @dbg_show: optional routine to show contents in debugfs 1890c2498f1SSascha Hauer * @owner: helps prevent removal of modules exporting active PWMs 1900c2498f1SSascha Hauer */ 1910c2498f1SSascha Hauer struct pwm_ops { 1926bc7064aSThierry Reding int (*request)(struct pwm_chip *chip, struct pwm_device *pwm); 1936bc7064aSThierry Reding void (*free)(struct pwm_chip *chip, struct pwm_device *pwm); 1946bc7064aSThierry Reding int (*config)(struct pwm_chip *chip, struct pwm_device *pwm, 195f051c466SThierry Reding int duty_ns, int period_ns); 1966bc7064aSThierry Reding int (*set_polarity)(struct pwm_chip *chip, struct pwm_device *pwm, 1970aa0869cSPhilip, Avinash enum pwm_polarity polarity); 1986bc7064aSThierry Reding int (*enable)(struct pwm_chip *chip, struct pwm_device *pwm); 1996bc7064aSThierry Reding void (*disable)(struct pwm_chip *chip, struct pwm_device *pwm); 20062099abfSThierry Reding #ifdef CONFIG_DEBUG_FS 2016bc7064aSThierry Reding void (*dbg_show)(struct pwm_chip *chip, struct seq_file *s); 20262099abfSThierry Reding #endif 2030c2498f1SSascha Hauer struct module *owner; 2040c2498f1SSascha Hauer }; 2050c2498f1SSascha Hauer 2060c2498f1SSascha Hauer /** 207f051c466SThierry Reding * struct pwm_chip - abstract a PWM controller 208f051c466SThierry Reding * @dev: device providing the PWMs 209f051c466SThierry Reding * @list: list node for internal use 210f051c466SThierry Reding * @ops: callbacks for this PWM controller 211f051c466SThierry Reding * @base: number of first PWM controlled by this chip 212f051c466SThierry Reding * @npwm: number of PWMs controlled by this chip 213f051c466SThierry Reding * @pwms: array of PWM devices allocated by the framework 21404883802SThierry Reding * @of_xlate: request a PWM device given a device tree PWM specifier 21504883802SThierry Reding * @of_pwm_n_cells: number of cells expected in the device tree PWM specifier 2166e69ab13SFlorian Vaussard * @can_sleep: must be true if the .config(), .enable() or .disable() 2176e69ab13SFlorian Vaussard * operations may sleep 2180c2498f1SSascha Hauer */ 2190c2498f1SSascha Hauer struct pwm_chip { 220f051c466SThierry Reding struct device *dev; 221f051c466SThierry Reding struct list_head list; 222f051c466SThierry Reding const struct pwm_ops *ops; 223f051c466SThierry Reding int base; 224f051c466SThierry Reding unsigned int npwm; 225f051c466SThierry Reding 226f051c466SThierry Reding struct pwm_device *pwms; 2277299ab70SThierry Reding 2287299ab70SThierry Reding struct pwm_device * (*of_xlate)(struct pwm_chip *pc, 2297299ab70SThierry Reding const struct of_phandle_args *args); 2307299ab70SThierry Reding unsigned int of_pwm_n_cells; 2316e69ab13SFlorian Vaussard bool can_sleep; 2320c2498f1SSascha Hauer }; 2330c2498f1SSascha Hauer 2340bcf168bSTushar Behera #if IS_ENABLED(CONFIG_PWM) 235f051c466SThierry Reding int pwm_set_chip_data(struct pwm_device *pwm, void *data); 236f051c466SThierry Reding void *pwm_get_chip_data(struct pwm_device *pwm); 237f051c466SThierry Reding 238b6a00faeSTim Kryger int pwmchip_add_with_polarity(struct pwm_chip *chip, 239b6a00faeSTim Kryger enum pwm_polarity polarity); 2400c2498f1SSascha Hauer int pwmchip_add(struct pwm_chip *chip); 2410c2498f1SSascha Hauer int pwmchip_remove(struct pwm_chip *chip); 242f051c466SThierry Reding struct pwm_device *pwm_request_from_chip(struct pwm_chip *chip, 243f051c466SThierry Reding unsigned int index, 244f051c466SThierry Reding const char *label); 2458138d2ddSThierry Reding 24683af2402SPhilip, Avinash struct pwm_device *of_pwm_xlate_with_flags(struct pwm_chip *pc, 24783af2402SPhilip, Avinash const struct of_phandle_args *args); 24883af2402SPhilip, Avinash 249d4c0c470SPeter Ujfalusi struct pwm_device *pwm_get(struct device *dev, const char *con_id); 2508eb96127SPeter Ujfalusi struct pwm_device *of_pwm_get(struct device_node *np, const char *con_id); 2518138d2ddSThierry Reding void pwm_put(struct pwm_device *pwm); 2528138d2ddSThierry Reding 253d4c0c470SPeter Ujfalusi struct pwm_device *devm_pwm_get(struct device *dev, const char *con_id); 254261a5eddSPeter Ujfalusi struct pwm_device *devm_of_pwm_get(struct device *dev, struct device_node *np, 255261a5eddSPeter Ujfalusi const char *con_id); 2566354316dSAlexandre Courbot void devm_pwm_put(struct device *dev, struct pwm_device *pwm); 2576e69ab13SFlorian Vaussard 2586e69ab13SFlorian Vaussard bool pwm_can_sleep(struct pwm_device *pwm); 2590bcf168bSTushar Behera #else 2600bcf168bSTushar Behera static inline int pwm_set_chip_data(struct pwm_device *pwm, void *data) 2610bcf168bSTushar Behera { 2620bcf168bSTushar Behera return -EINVAL; 2630bcf168bSTushar Behera } 2640bcf168bSTushar Behera 2650bcf168bSTushar Behera static inline void *pwm_get_chip_data(struct pwm_device *pwm) 2660bcf168bSTushar Behera { 2670bcf168bSTushar Behera return NULL; 2680bcf168bSTushar Behera } 2690bcf168bSTushar Behera 2700bcf168bSTushar Behera static inline int pwmchip_add(struct pwm_chip *chip) 2710bcf168bSTushar Behera { 2720bcf168bSTushar Behera return -EINVAL; 2730bcf168bSTushar Behera } 2740bcf168bSTushar Behera 275b6a00faeSTim Kryger static inline int pwmchip_add_inversed(struct pwm_chip *chip) 276b6a00faeSTim Kryger { 277b6a00faeSTim Kryger return -EINVAL; 278b6a00faeSTim Kryger } 279b6a00faeSTim Kryger 2800bcf168bSTushar Behera static inline int pwmchip_remove(struct pwm_chip *chip) 2810bcf168bSTushar Behera { 2820bcf168bSTushar Behera return -EINVAL; 2830bcf168bSTushar Behera } 2840bcf168bSTushar Behera 2850bcf168bSTushar Behera static inline struct pwm_device *pwm_request_from_chip(struct pwm_chip *chip, 2860bcf168bSTushar Behera unsigned int index, 2870bcf168bSTushar Behera const char *label) 2880bcf168bSTushar Behera { 2890bcf168bSTushar Behera return ERR_PTR(-ENODEV); 2900bcf168bSTushar Behera } 2910bcf168bSTushar Behera 2920bcf168bSTushar Behera static inline struct pwm_device *pwm_get(struct device *dev, 2930bcf168bSTushar Behera const char *consumer) 2940bcf168bSTushar Behera { 2950bcf168bSTushar Behera return ERR_PTR(-ENODEV); 2960bcf168bSTushar Behera } 2970bcf168bSTushar Behera 2988eb96127SPeter Ujfalusi static inline struct pwm_device *of_pwm_get(struct device_node *np, 2998eb96127SPeter Ujfalusi const char *con_id) 3008eb96127SPeter Ujfalusi { 3018eb96127SPeter Ujfalusi return ERR_PTR(-ENODEV); 3028eb96127SPeter Ujfalusi } 3038eb96127SPeter Ujfalusi 3040bcf168bSTushar Behera static inline void pwm_put(struct pwm_device *pwm) 3050bcf168bSTushar Behera { 3060bcf168bSTushar Behera } 3070bcf168bSTushar Behera 3080bcf168bSTushar Behera static inline struct pwm_device *devm_pwm_get(struct device *dev, 3090bcf168bSTushar Behera const char *consumer) 3100bcf168bSTushar Behera { 3110bcf168bSTushar Behera return ERR_PTR(-ENODEV); 3120bcf168bSTushar Behera } 3130bcf168bSTushar Behera 314261a5eddSPeter Ujfalusi static inline struct pwm_device *devm_of_pwm_get(struct device *dev, 315261a5eddSPeter Ujfalusi struct device_node *np, 316261a5eddSPeter Ujfalusi const char *con_id) 317261a5eddSPeter Ujfalusi { 318261a5eddSPeter Ujfalusi return ERR_PTR(-ENODEV); 319261a5eddSPeter Ujfalusi } 320261a5eddSPeter Ujfalusi 3210bcf168bSTushar Behera static inline void devm_pwm_put(struct device *dev, struct pwm_device *pwm) 3220bcf168bSTushar Behera { 3230bcf168bSTushar Behera } 3246e69ab13SFlorian Vaussard 3256e69ab13SFlorian Vaussard static inline bool pwm_can_sleep(struct pwm_device *pwm) 3266e69ab13SFlorian Vaussard { 3276e69ab13SFlorian Vaussard return false; 3286e69ab13SFlorian Vaussard } 3290bcf168bSTushar Behera #endif 3306354316dSAlexandre Courbot 3318138d2ddSThierry Reding struct pwm_lookup { 3328138d2ddSThierry Reding struct list_head list; 3338138d2ddSThierry Reding const char *provider; 3348138d2ddSThierry Reding unsigned int index; 3358138d2ddSThierry Reding const char *dev_id; 3368138d2ddSThierry Reding const char *con_id; 3373796ce1dSAlexandre Belloni unsigned int period; 3383796ce1dSAlexandre Belloni enum pwm_polarity polarity; 3398138d2ddSThierry Reding }; 3408138d2ddSThierry Reding 34142844029SAlexandre Belloni #define PWM_LOOKUP(_provider, _index, _dev_id, _con_id, _period, _polarity) \ 3428138d2ddSThierry Reding { \ 3438138d2ddSThierry Reding .provider = _provider, \ 3448138d2ddSThierry Reding .index = _index, \ 3458138d2ddSThierry Reding .dev_id = _dev_id, \ 3468138d2ddSThierry Reding .con_id = _con_id, \ 34742844029SAlexandre Belloni .period = _period, \ 34842844029SAlexandre Belloni .polarity = _polarity \ 3498138d2ddSThierry Reding } 3508138d2ddSThierry Reding 3510bcf168bSTushar Behera #if IS_ENABLED(CONFIG_PWM) 3528138d2ddSThierry Reding void pwm_add_table(struct pwm_lookup *table, size_t num); 353efb0de55SShobhit Kumar void pwm_remove_table(struct pwm_lookup *table, size_t num); 3540bcf168bSTushar Behera #else 3550bcf168bSTushar Behera static inline void pwm_add_table(struct pwm_lookup *table, size_t num) 3560bcf168bSTushar Behera { 3570bcf168bSTushar Behera } 358efb0de55SShobhit Kumar 359efb0de55SShobhit Kumar static inline void pwm_remove_table(struct pwm_lookup *table, size_t num) 360efb0de55SShobhit Kumar { 361efb0de55SShobhit Kumar } 3620c2498f1SSascha Hauer #endif 3630c2498f1SSascha Hauer 36476abbddeSH Hartley Sweeten #ifdef CONFIG_PWM_SYSFS 36576abbddeSH Hartley Sweeten void pwmchip_sysfs_export(struct pwm_chip *chip); 36676abbddeSH Hartley Sweeten void pwmchip_sysfs_unexport(struct pwm_chip *chip); 36776abbddeSH Hartley Sweeten #else 36876abbddeSH Hartley Sweeten static inline void pwmchip_sysfs_export(struct pwm_chip *chip) 36976abbddeSH Hartley Sweeten { 37076abbddeSH Hartley Sweeten } 37176abbddeSH Hartley Sweeten 37276abbddeSH Hartley Sweeten static inline void pwmchip_sysfs_unexport(struct pwm_chip *chip) 37376abbddeSH Hartley Sweeten { 37476abbddeSH Hartley Sweeten } 37576abbddeSH Hartley Sweeten #endif /* CONFIG_PWM_SYSFS */ 37676abbddeSH Hartley Sweeten 3775243ef8bSMark Vels #endif /* __LINUX_PWM_H */ 378