11a189b97SRussell King #ifndef __LINUX_PWM_H 21a189b97SRussell King #define __LINUX_PWM_H 31a189b97SRussell King 40bcf168bSTushar Behera #include <linux/err.h> 57299ab70SThierry Reding #include <linux/of.h> 67299ab70SThierry Reding 71a189b97SRussell King struct pwm_device; 862099abfSThierry Reding struct seq_file; 91a189b97SRussell King 10557fe99dSSascha Hauer #if IS_ENABLED(CONFIG_PWM) 111a189b97SRussell King /* 121a189b97SRussell King * pwm_request - request a PWM device 131a189b97SRussell King */ 141a189b97SRussell King struct pwm_device *pwm_request(int pwm_id, const char *label); 151a189b97SRussell King 161a189b97SRussell King /* 171a189b97SRussell King * pwm_free - free a PWM device 181a189b97SRussell King */ 191a189b97SRussell King void pwm_free(struct pwm_device *pwm); 201a189b97SRussell King 211a189b97SRussell King /* 221a189b97SRussell King * pwm_config - change a PWM device configuration 231a189b97SRussell King */ 241a189b97SRussell King int pwm_config(struct pwm_device *pwm, int duty_ns, int period_ns); 251a189b97SRussell King 261a189b97SRussell King /* 271a189b97SRussell King * pwm_enable - start a PWM output toggling 281a189b97SRussell King */ 291a189b97SRussell King int pwm_enable(struct pwm_device *pwm); 301a189b97SRussell King 311a189b97SRussell King /* 321a189b97SRussell King * pwm_disable - stop a PWM output toggling 331a189b97SRussell King */ 341a189b97SRussell King void pwm_disable(struct pwm_device *pwm); 350bcf168bSTushar Behera #else 360bcf168bSTushar Behera static inline struct pwm_device *pwm_request(int pwm_id, const char *label) 370bcf168bSTushar Behera { 380bcf168bSTushar Behera return ERR_PTR(-ENODEV); 390bcf168bSTushar Behera } 401a189b97SRussell King 410bcf168bSTushar Behera static inline void pwm_free(struct pwm_device *pwm) 420bcf168bSTushar Behera { 430bcf168bSTushar Behera } 440bcf168bSTushar Behera 450bcf168bSTushar Behera static inline int pwm_config(struct pwm_device *pwm, int duty_ns, int period_ns) 460bcf168bSTushar Behera { 470bcf168bSTushar Behera return -EINVAL; 480bcf168bSTushar Behera } 490bcf168bSTushar Behera 500bcf168bSTushar Behera static inline int pwm_enable(struct pwm_device *pwm) 510bcf168bSTushar Behera { 520bcf168bSTushar Behera return -EINVAL; 530bcf168bSTushar Behera } 540bcf168bSTushar Behera 550bcf168bSTushar Behera static inline void pwm_disable(struct pwm_device *pwm) 560bcf168bSTushar Behera { 570bcf168bSTushar Behera } 580bcf168bSTushar Behera #endif 590bcf168bSTushar Behera 600c2498f1SSascha Hauer struct pwm_chip; 610c2498f1SSascha Hauer 620aa0869cSPhilip, Avinash /** 630aa0869cSPhilip, Avinash * enum pwm_polarity - polarity of a PWM signal 640aa0869cSPhilip, Avinash * @PWM_POLARITY_NORMAL: a high signal for the duration of the duty- 650aa0869cSPhilip, Avinash * cycle, followed by a low signal for the remainder of the pulse 660aa0869cSPhilip, Avinash * period 670aa0869cSPhilip, Avinash * @PWM_POLARITY_INVERSED: a low signal for the duration of the duty- 680aa0869cSPhilip, Avinash * cycle, followed by a high signal for the remainder of the pulse 690aa0869cSPhilip, Avinash * period 700aa0869cSPhilip, Avinash */ 710aa0869cSPhilip, Avinash enum pwm_polarity { 720aa0869cSPhilip, Avinash PWM_POLARITY_NORMAL, 730aa0869cSPhilip, Avinash PWM_POLARITY_INVERSED, 740aa0869cSPhilip, Avinash }; 750aa0869cSPhilip, Avinash 76f051c466SThierry Reding enum { 77f051c466SThierry Reding PWMF_REQUESTED = 1 << 0, 78f051c466SThierry Reding PWMF_ENABLED = 1 << 1, 7976abbddeSH Hartley Sweeten PWMF_EXPORTED = 1 << 2, 80f051c466SThierry Reding }; 81f051c466SThierry Reding 82f051c466SThierry Reding struct pwm_device { 83f051c466SThierry Reding const char *label; 84f051c466SThierry Reding unsigned long flags; 85f051c466SThierry Reding unsigned int hwpwm; 86f051c466SThierry Reding unsigned int pwm; 87f051c466SThierry Reding struct pwm_chip *chip; 88f051c466SThierry Reding void *chip_data; 89f051c466SThierry Reding 90f051c466SThierry Reding unsigned int period; /* in nanoseconds */ 9176abbddeSH Hartley Sweeten unsigned int duty_cycle; /* in nanoseconds */ 9276abbddeSH Hartley Sweeten enum pwm_polarity polarity; 93f051c466SThierry Reding }; 94f051c466SThierry Reding 955c31252cSBoris Brezillon static inline bool pwm_is_enabled(const struct pwm_device *pwm) 965c31252cSBoris Brezillon { 975c31252cSBoris Brezillon return test_bit(PWMF_ENABLED, &pwm->flags); 985c31252cSBoris Brezillon } 995c31252cSBoris Brezillon 100f051c466SThierry Reding static inline void pwm_set_period(struct pwm_device *pwm, unsigned int period) 101f051c466SThierry Reding { 102f051c466SThierry Reding if (pwm) 103f051c466SThierry Reding pwm->period = period; 104f051c466SThierry Reding } 105f051c466SThierry Reding 106a1cf4217SBoris Brezillon static inline unsigned int pwm_get_period(const struct pwm_device *pwm) 107f051c466SThierry Reding { 108f051c466SThierry Reding return pwm ? pwm->period : 0; 109f051c466SThierry Reding } 110f051c466SThierry Reding 11176abbddeSH Hartley Sweeten static inline void pwm_set_duty_cycle(struct pwm_device *pwm, unsigned int duty) 11276abbddeSH Hartley Sweeten { 11376abbddeSH Hartley Sweeten if (pwm) 11476abbddeSH Hartley Sweeten pwm->duty_cycle = duty; 11576abbddeSH Hartley Sweeten } 11676abbddeSH Hartley Sweeten 117a1cf4217SBoris Brezillon static inline unsigned int pwm_get_duty_cycle(const struct pwm_device *pwm) 11876abbddeSH Hartley Sweeten { 11976abbddeSH Hartley Sweeten return pwm ? pwm->duty_cycle : 0; 12076abbddeSH Hartley Sweeten } 12176abbddeSH Hartley Sweeten 1220aa0869cSPhilip, Avinash /* 1230aa0869cSPhilip, Avinash * pwm_set_polarity - configure the polarity of a PWM signal 1240aa0869cSPhilip, Avinash */ 1250aa0869cSPhilip, Avinash int pwm_set_polarity(struct pwm_device *pwm, enum pwm_polarity polarity); 1260aa0869cSPhilip, Avinash 127*011e7631SBoris Brezillon static inline enum pwm_polarity pwm_get_polarity(const struct pwm_device *pwm) 128*011e7631SBoris Brezillon { 129*011e7631SBoris Brezillon return pwm ? pwm->polarity : PWM_POLARITY_NORMAL; 130*011e7631SBoris Brezillon } 131*011e7631SBoris Brezillon 1320c2498f1SSascha Hauer /** 1330c2498f1SSascha Hauer * struct pwm_ops - PWM controller operations 1340c2498f1SSascha Hauer * @request: optional hook for requesting a PWM 1350c2498f1SSascha Hauer * @free: optional hook for freeing a PWM 1360c2498f1SSascha Hauer * @config: configure duty cycles and period length for this PWM 1370aa0869cSPhilip, Avinash * @set_polarity: configure the polarity of this PWM 1380c2498f1SSascha Hauer * @enable: enable PWM output toggling 1390c2498f1SSascha Hauer * @disable: disable PWM output toggling 14062099abfSThierry Reding * @dbg_show: optional routine to show contents in debugfs 1410c2498f1SSascha Hauer * @owner: helps prevent removal of modules exporting active PWMs 1420c2498f1SSascha Hauer */ 1430c2498f1SSascha Hauer struct pwm_ops { 144f051c466SThierry Reding int (*request)(struct pwm_chip *chip, 145f051c466SThierry Reding struct pwm_device *pwm); 146f051c466SThierry Reding void (*free)(struct pwm_chip *chip, 147f051c466SThierry Reding struct pwm_device *pwm); 148f051c466SThierry Reding int (*config)(struct pwm_chip *chip, 149f051c466SThierry Reding struct pwm_device *pwm, 150f051c466SThierry Reding int duty_ns, int period_ns); 1510aa0869cSPhilip, Avinash int (*set_polarity)(struct pwm_chip *chip, 1520aa0869cSPhilip, Avinash struct pwm_device *pwm, 1530aa0869cSPhilip, Avinash enum pwm_polarity polarity); 154f051c466SThierry Reding int (*enable)(struct pwm_chip *chip, 155f051c466SThierry Reding struct pwm_device *pwm); 156f051c466SThierry Reding void (*disable)(struct pwm_chip *chip, 157f051c466SThierry Reding struct pwm_device *pwm); 15862099abfSThierry Reding #ifdef CONFIG_DEBUG_FS 15962099abfSThierry Reding void (*dbg_show)(struct pwm_chip *chip, 16062099abfSThierry Reding struct seq_file *s); 16162099abfSThierry Reding #endif 1620c2498f1SSascha Hauer struct module *owner; 1630c2498f1SSascha Hauer }; 1640c2498f1SSascha Hauer 1650c2498f1SSascha Hauer /** 166f051c466SThierry Reding * struct pwm_chip - abstract a PWM controller 167f051c466SThierry Reding * @dev: device providing the PWMs 168f051c466SThierry Reding * @list: list node for internal use 169f051c466SThierry Reding * @ops: callbacks for this PWM controller 170f051c466SThierry Reding * @base: number of first PWM controlled by this chip 171f051c466SThierry Reding * @npwm: number of PWMs controlled by this chip 172f051c466SThierry Reding * @pwms: array of PWM devices allocated by the framework 1736e69ab13SFlorian Vaussard * @can_sleep: must be true if the .config(), .enable() or .disable() 1746e69ab13SFlorian Vaussard * operations may sleep 1750c2498f1SSascha Hauer */ 1760c2498f1SSascha Hauer struct pwm_chip { 177f051c466SThierry Reding struct device *dev; 178f051c466SThierry Reding struct list_head list; 179f051c466SThierry Reding const struct pwm_ops *ops; 180f051c466SThierry Reding int base; 181f051c466SThierry Reding unsigned int npwm; 182f051c466SThierry Reding 183f051c466SThierry Reding struct pwm_device *pwms; 1847299ab70SThierry Reding 1857299ab70SThierry Reding struct pwm_device * (*of_xlate)(struct pwm_chip *pc, 1867299ab70SThierry Reding const struct of_phandle_args *args); 1877299ab70SThierry Reding unsigned int of_pwm_n_cells; 1886e69ab13SFlorian Vaussard bool can_sleep; 1890c2498f1SSascha Hauer }; 1900c2498f1SSascha Hauer 1910bcf168bSTushar Behera #if IS_ENABLED(CONFIG_PWM) 192f051c466SThierry Reding int pwm_set_chip_data(struct pwm_device *pwm, void *data); 193f051c466SThierry Reding void *pwm_get_chip_data(struct pwm_device *pwm); 194f051c466SThierry Reding 195b6a00faeSTim Kryger int pwmchip_add_with_polarity(struct pwm_chip *chip, 196b6a00faeSTim Kryger enum pwm_polarity polarity); 1970c2498f1SSascha Hauer int pwmchip_add(struct pwm_chip *chip); 1980c2498f1SSascha Hauer int pwmchip_remove(struct pwm_chip *chip); 199f051c466SThierry Reding struct pwm_device *pwm_request_from_chip(struct pwm_chip *chip, 200f051c466SThierry Reding unsigned int index, 201f051c466SThierry Reding const char *label); 2028138d2ddSThierry Reding 20383af2402SPhilip, Avinash struct pwm_device *of_pwm_xlate_with_flags(struct pwm_chip *pc, 20483af2402SPhilip, Avinash const struct of_phandle_args *args); 20583af2402SPhilip, Avinash 206d4c0c470SPeter Ujfalusi struct pwm_device *pwm_get(struct device *dev, const char *con_id); 2078eb96127SPeter Ujfalusi struct pwm_device *of_pwm_get(struct device_node *np, const char *con_id); 2088138d2ddSThierry Reding void pwm_put(struct pwm_device *pwm); 2098138d2ddSThierry Reding 210d4c0c470SPeter Ujfalusi struct pwm_device *devm_pwm_get(struct device *dev, const char *con_id); 211261a5eddSPeter Ujfalusi struct pwm_device *devm_of_pwm_get(struct device *dev, struct device_node *np, 212261a5eddSPeter Ujfalusi const char *con_id); 2136354316dSAlexandre Courbot void devm_pwm_put(struct device *dev, struct pwm_device *pwm); 2146e69ab13SFlorian Vaussard 2156e69ab13SFlorian Vaussard bool pwm_can_sleep(struct pwm_device *pwm); 2160bcf168bSTushar Behera #else 2170bcf168bSTushar Behera static inline int pwm_set_chip_data(struct pwm_device *pwm, void *data) 2180bcf168bSTushar Behera { 2190bcf168bSTushar Behera return -EINVAL; 2200bcf168bSTushar Behera } 2210bcf168bSTushar Behera 2220bcf168bSTushar Behera static inline void *pwm_get_chip_data(struct pwm_device *pwm) 2230bcf168bSTushar Behera { 2240bcf168bSTushar Behera return NULL; 2250bcf168bSTushar Behera } 2260bcf168bSTushar Behera 2270bcf168bSTushar Behera static inline int pwmchip_add(struct pwm_chip *chip) 2280bcf168bSTushar Behera { 2290bcf168bSTushar Behera return -EINVAL; 2300bcf168bSTushar Behera } 2310bcf168bSTushar Behera 232b6a00faeSTim Kryger static inline int pwmchip_add_inversed(struct pwm_chip *chip) 233b6a00faeSTim Kryger { 234b6a00faeSTim Kryger return -EINVAL; 235b6a00faeSTim Kryger } 236b6a00faeSTim Kryger 2370bcf168bSTushar Behera static inline int pwmchip_remove(struct pwm_chip *chip) 2380bcf168bSTushar Behera { 2390bcf168bSTushar Behera return -EINVAL; 2400bcf168bSTushar Behera } 2410bcf168bSTushar Behera 2420bcf168bSTushar Behera static inline struct pwm_device *pwm_request_from_chip(struct pwm_chip *chip, 2430bcf168bSTushar Behera unsigned int index, 2440bcf168bSTushar Behera const char *label) 2450bcf168bSTushar Behera { 2460bcf168bSTushar Behera return ERR_PTR(-ENODEV); 2470bcf168bSTushar Behera } 2480bcf168bSTushar Behera 2490bcf168bSTushar Behera static inline struct pwm_device *pwm_get(struct device *dev, 2500bcf168bSTushar Behera const char *consumer) 2510bcf168bSTushar Behera { 2520bcf168bSTushar Behera return ERR_PTR(-ENODEV); 2530bcf168bSTushar Behera } 2540bcf168bSTushar Behera 2558eb96127SPeter Ujfalusi static inline struct pwm_device *of_pwm_get(struct device_node *np, 2568eb96127SPeter Ujfalusi const char *con_id) 2578eb96127SPeter Ujfalusi { 2588eb96127SPeter Ujfalusi return ERR_PTR(-ENODEV); 2598eb96127SPeter Ujfalusi } 2608eb96127SPeter Ujfalusi 2610bcf168bSTushar Behera static inline void pwm_put(struct pwm_device *pwm) 2620bcf168bSTushar Behera { 2630bcf168bSTushar Behera } 2640bcf168bSTushar Behera 2650bcf168bSTushar Behera static inline struct pwm_device *devm_pwm_get(struct device *dev, 2660bcf168bSTushar Behera const char *consumer) 2670bcf168bSTushar Behera { 2680bcf168bSTushar Behera return ERR_PTR(-ENODEV); 2690bcf168bSTushar Behera } 2700bcf168bSTushar Behera 271261a5eddSPeter Ujfalusi static inline struct pwm_device *devm_of_pwm_get(struct device *dev, 272261a5eddSPeter Ujfalusi struct device_node *np, 273261a5eddSPeter Ujfalusi const char *con_id) 274261a5eddSPeter Ujfalusi { 275261a5eddSPeter Ujfalusi return ERR_PTR(-ENODEV); 276261a5eddSPeter Ujfalusi } 277261a5eddSPeter Ujfalusi 2780bcf168bSTushar Behera static inline void devm_pwm_put(struct device *dev, struct pwm_device *pwm) 2790bcf168bSTushar Behera { 2800bcf168bSTushar Behera } 2816e69ab13SFlorian Vaussard 2826e69ab13SFlorian Vaussard static inline bool pwm_can_sleep(struct pwm_device *pwm) 2836e69ab13SFlorian Vaussard { 2846e69ab13SFlorian Vaussard return false; 2856e69ab13SFlorian Vaussard } 2860bcf168bSTushar Behera #endif 2876354316dSAlexandre Courbot 2888138d2ddSThierry Reding struct pwm_lookup { 2898138d2ddSThierry Reding struct list_head list; 2908138d2ddSThierry Reding const char *provider; 2918138d2ddSThierry Reding unsigned int index; 2928138d2ddSThierry Reding const char *dev_id; 2938138d2ddSThierry Reding const char *con_id; 2943796ce1dSAlexandre Belloni unsigned int period; 2953796ce1dSAlexandre Belloni enum pwm_polarity polarity; 2968138d2ddSThierry Reding }; 2978138d2ddSThierry Reding 29842844029SAlexandre Belloni #define PWM_LOOKUP(_provider, _index, _dev_id, _con_id, _period, _polarity) \ 2998138d2ddSThierry Reding { \ 3008138d2ddSThierry Reding .provider = _provider, \ 3018138d2ddSThierry Reding .index = _index, \ 3028138d2ddSThierry Reding .dev_id = _dev_id, \ 3038138d2ddSThierry Reding .con_id = _con_id, \ 30442844029SAlexandre Belloni .period = _period, \ 30542844029SAlexandre Belloni .polarity = _polarity \ 3068138d2ddSThierry Reding } 3078138d2ddSThierry Reding 3080bcf168bSTushar Behera #if IS_ENABLED(CONFIG_PWM) 3098138d2ddSThierry Reding void pwm_add_table(struct pwm_lookup *table, size_t num); 310efb0de55SShobhit Kumar void pwm_remove_table(struct pwm_lookup *table, size_t num); 3110bcf168bSTushar Behera #else 3120bcf168bSTushar Behera static inline void pwm_add_table(struct pwm_lookup *table, size_t num) 3130bcf168bSTushar Behera { 3140bcf168bSTushar Behera } 315efb0de55SShobhit Kumar 316efb0de55SShobhit Kumar static inline void pwm_remove_table(struct pwm_lookup *table, size_t num) 317efb0de55SShobhit Kumar { 318efb0de55SShobhit Kumar } 3190c2498f1SSascha Hauer #endif 3200c2498f1SSascha Hauer 32176abbddeSH Hartley Sweeten #ifdef CONFIG_PWM_SYSFS 32276abbddeSH Hartley Sweeten void pwmchip_sysfs_export(struct pwm_chip *chip); 32376abbddeSH Hartley Sweeten void pwmchip_sysfs_unexport(struct pwm_chip *chip); 32476abbddeSH Hartley Sweeten #else 32576abbddeSH Hartley Sweeten static inline void pwmchip_sysfs_export(struct pwm_chip *chip) 32676abbddeSH Hartley Sweeten { 32776abbddeSH Hartley Sweeten } 32876abbddeSH Hartley Sweeten 32976abbddeSH Hartley Sweeten static inline void pwmchip_sysfs_unexport(struct pwm_chip *chip) 33076abbddeSH Hartley Sweeten { 33176abbddeSH Hartley Sweeten } 33276abbddeSH Hartley Sweeten #endif /* CONFIG_PWM_SYSFS */ 33376abbddeSH Hartley Sweeten 3345243ef8bSMark Vels #endif /* __LINUX_PWM_H */ 335