xref: /linux-6.15/include/linux/pwm.h (revision 8eb96127)
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 
100bcf168bSTushar Behera #if IS_ENABLED(CONFIG_PWM) || IS_ENABLED(CONFIG_HAVE_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,
79f051c466SThierry Reding };
80f051c466SThierry Reding 
81f051c466SThierry Reding struct pwm_device {
82f051c466SThierry Reding 	const char		*label;
83f051c466SThierry Reding 	unsigned long		flags;
84f051c466SThierry Reding 	unsigned int		hwpwm;
85f051c466SThierry Reding 	unsigned int		pwm;
86f051c466SThierry Reding 	struct pwm_chip		*chip;
87f051c466SThierry Reding 	void			*chip_data;
88f051c466SThierry Reding 
89f051c466SThierry Reding 	unsigned int		period; /* in nanoseconds */
90f051c466SThierry Reding };
91f051c466SThierry Reding 
92f051c466SThierry Reding static inline void pwm_set_period(struct pwm_device *pwm, unsigned int period)
93f051c466SThierry Reding {
94f051c466SThierry Reding 	if (pwm)
95f051c466SThierry Reding 		pwm->period = period;
96f051c466SThierry Reding }
97f051c466SThierry Reding 
98f051c466SThierry Reding static inline unsigned int pwm_get_period(struct pwm_device *pwm)
99f051c466SThierry Reding {
100f051c466SThierry Reding 	return pwm ? pwm->period : 0;
101f051c466SThierry Reding }
102f051c466SThierry Reding 
1030aa0869cSPhilip, Avinash /*
1040aa0869cSPhilip, Avinash  * pwm_set_polarity - configure the polarity of a PWM signal
1050aa0869cSPhilip, Avinash  */
1060aa0869cSPhilip, Avinash int pwm_set_polarity(struct pwm_device *pwm, enum pwm_polarity polarity);
1070aa0869cSPhilip, Avinash 
1080c2498f1SSascha Hauer /**
1090c2498f1SSascha Hauer  * struct pwm_ops - PWM controller operations
1100c2498f1SSascha Hauer  * @request: optional hook for requesting a PWM
1110c2498f1SSascha Hauer  * @free: optional hook for freeing a PWM
1120c2498f1SSascha Hauer  * @config: configure duty cycles and period length for this PWM
1130aa0869cSPhilip, Avinash  * @set_polarity: configure the polarity of this PWM
1140c2498f1SSascha Hauer  * @enable: enable PWM output toggling
1150c2498f1SSascha Hauer  * @disable: disable PWM output toggling
11662099abfSThierry Reding  * @dbg_show: optional routine to show contents in debugfs
1170c2498f1SSascha Hauer  * @owner: helps prevent removal of modules exporting active PWMs
1180c2498f1SSascha Hauer  */
1190c2498f1SSascha Hauer struct pwm_ops {
120f051c466SThierry Reding 	int			(*request)(struct pwm_chip *chip,
121f051c466SThierry Reding 					   struct pwm_device *pwm);
122f051c466SThierry Reding 	void			(*free)(struct pwm_chip *chip,
123f051c466SThierry Reding 					struct pwm_device *pwm);
124f051c466SThierry Reding 	int			(*config)(struct pwm_chip *chip,
125f051c466SThierry Reding 					  struct pwm_device *pwm,
126f051c466SThierry Reding 					  int duty_ns, int period_ns);
1270aa0869cSPhilip, Avinash 	int			(*set_polarity)(struct pwm_chip *chip,
1280aa0869cSPhilip, Avinash 					  struct pwm_device *pwm,
1290aa0869cSPhilip, Avinash 					  enum pwm_polarity polarity);
130f051c466SThierry Reding 	int			(*enable)(struct pwm_chip *chip,
131f051c466SThierry Reding 					  struct pwm_device *pwm);
132f051c466SThierry Reding 	void			(*disable)(struct pwm_chip *chip,
133f051c466SThierry Reding 					   struct pwm_device *pwm);
13462099abfSThierry Reding #ifdef CONFIG_DEBUG_FS
13562099abfSThierry Reding 	void			(*dbg_show)(struct pwm_chip *chip,
13662099abfSThierry Reding 					    struct seq_file *s);
13762099abfSThierry Reding #endif
1380c2498f1SSascha Hauer 	struct module		*owner;
1390c2498f1SSascha Hauer };
1400c2498f1SSascha Hauer 
1410c2498f1SSascha Hauer /**
142f051c466SThierry Reding  * struct pwm_chip - abstract a PWM controller
143f051c466SThierry Reding  * @dev: device providing the PWMs
144f051c466SThierry Reding  * @list: list node for internal use
145f051c466SThierry Reding  * @ops: callbacks for this PWM controller
146f051c466SThierry Reding  * @base: number of first PWM controlled by this chip
147f051c466SThierry Reding  * @npwm: number of PWMs controlled by this chip
148f051c466SThierry Reding  * @pwms: array of PWM devices allocated by the framework
1490c2498f1SSascha Hauer  */
1500c2498f1SSascha Hauer struct pwm_chip {
151f051c466SThierry Reding 	struct device		*dev;
152f051c466SThierry Reding 	struct list_head	list;
153f051c466SThierry Reding 	const struct pwm_ops	*ops;
154f051c466SThierry Reding 	int			base;
155f051c466SThierry Reding 	unsigned int		npwm;
156f051c466SThierry Reding 
157f051c466SThierry Reding 	struct pwm_device	*pwms;
1587299ab70SThierry Reding 
1597299ab70SThierry Reding 	struct pwm_device *	(*of_xlate)(struct pwm_chip *pc,
1607299ab70SThierry Reding 					    const struct of_phandle_args *args);
1617299ab70SThierry Reding 	unsigned int		of_pwm_n_cells;
1620c2498f1SSascha Hauer };
1630c2498f1SSascha Hauer 
1640bcf168bSTushar Behera #if IS_ENABLED(CONFIG_PWM)
165f051c466SThierry Reding int pwm_set_chip_data(struct pwm_device *pwm, void *data);
166f051c466SThierry Reding void *pwm_get_chip_data(struct pwm_device *pwm);
167f051c466SThierry Reding 
1680c2498f1SSascha Hauer int pwmchip_add(struct pwm_chip *chip);
1690c2498f1SSascha Hauer int pwmchip_remove(struct pwm_chip *chip);
170f051c466SThierry Reding struct pwm_device *pwm_request_from_chip(struct pwm_chip *chip,
171f051c466SThierry Reding 					 unsigned int index,
172f051c466SThierry Reding 					 const char *label);
1738138d2ddSThierry Reding 
17483af2402SPhilip, Avinash struct pwm_device *of_pwm_xlate_with_flags(struct pwm_chip *pc,
17583af2402SPhilip, Avinash 		const struct of_phandle_args *args);
17683af2402SPhilip, Avinash 
177d4c0c470SPeter Ujfalusi struct pwm_device *pwm_get(struct device *dev, const char *con_id);
178*8eb96127SPeter Ujfalusi struct pwm_device *of_pwm_get(struct device_node *np, const char *con_id);
1798138d2ddSThierry Reding void pwm_put(struct pwm_device *pwm);
1808138d2ddSThierry Reding 
181d4c0c470SPeter Ujfalusi struct pwm_device *devm_pwm_get(struct device *dev, const char *con_id);
1826354316dSAlexandre Courbot void devm_pwm_put(struct device *dev, struct pwm_device *pwm);
1830bcf168bSTushar Behera #else
1840bcf168bSTushar Behera static inline int pwm_set_chip_data(struct pwm_device *pwm, void *data)
1850bcf168bSTushar Behera {
1860bcf168bSTushar Behera 	return -EINVAL;
1870bcf168bSTushar Behera }
1880bcf168bSTushar Behera 
1890bcf168bSTushar Behera static inline void *pwm_get_chip_data(struct pwm_device *pwm)
1900bcf168bSTushar Behera {
1910bcf168bSTushar Behera 	return NULL;
1920bcf168bSTushar Behera }
1930bcf168bSTushar Behera 
1940bcf168bSTushar Behera static inline int pwmchip_add(struct pwm_chip *chip)
1950bcf168bSTushar Behera {
1960bcf168bSTushar Behera 	return -EINVAL;
1970bcf168bSTushar Behera }
1980bcf168bSTushar Behera 
1990bcf168bSTushar Behera static inline int pwmchip_remove(struct pwm_chip *chip)
2000bcf168bSTushar Behera {
2010bcf168bSTushar Behera 	return -EINVAL;
2020bcf168bSTushar Behera }
2030bcf168bSTushar Behera 
2040bcf168bSTushar Behera static inline struct pwm_device *pwm_request_from_chip(struct pwm_chip *chip,
2050bcf168bSTushar Behera 						       unsigned int index,
2060bcf168bSTushar Behera 						       const char *label)
2070bcf168bSTushar Behera {
2080bcf168bSTushar Behera 	return ERR_PTR(-ENODEV);
2090bcf168bSTushar Behera }
2100bcf168bSTushar Behera 
2110bcf168bSTushar Behera static inline struct pwm_device *pwm_get(struct device *dev,
2120bcf168bSTushar Behera 					 const char *consumer)
2130bcf168bSTushar Behera {
2140bcf168bSTushar Behera 	return ERR_PTR(-ENODEV);
2150bcf168bSTushar Behera }
2160bcf168bSTushar Behera 
217*8eb96127SPeter Ujfalusi static inline struct pwm_device *of_pwm_get(struct device_node *np,
218*8eb96127SPeter Ujfalusi 					    const char *con_id)
219*8eb96127SPeter Ujfalusi {
220*8eb96127SPeter Ujfalusi 	return ERR_PTR(-ENODEV);
221*8eb96127SPeter Ujfalusi }
222*8eb96127SPeter Ujfalusi 
2230bcf168bSTushar Behera static inline void pwm_put(struct pwm_device *pwm)
2240bcf168bSTushar Behera {
2250bcf168bSTushar Behera }
2260bcf168bSTushar Behera 
2270bcf168bSTushar Behera static inline struct pwm_device *devm_pwm_get(struct device *dev,
2280bcf168bSTushar Behera 					      const char *consumer)
2290bcf168bSTushar Behera {
2300bcf168bSTushar Behera 	return ERR_PTR(-ENODEV);
2310bcf168bSTushar Behera }
2320bcf168bSTushar Behera 
2330bcf168bSTushar Behera static inline void devm_pwm_put(struct device *dev, struct pwm_device *pwm)
2340bcf168bSTushar Behera {
2350bcf168bSTushar Behera }
2360bcf168bSTushar Behera #endif
2376354316dSAlexandre Courbot 
2388138d2ddSThierry Reding struct pwm_lookup {
2398138d2ddSThierry Reding 	struct list_head list;
2408138d2ddSThierry Reding 	const char *provider;
2418138d2ddSThierry Reding 	unsigned int index;
2428138d2ddSThierry Reding 	const char *dev_id;
2438138d2ddSThierry Reding 	const char *con_id;
2448138d2ddSThierry Reding };
2458138d2ddSThierry Reding 
2468138d2ddSThierry Reding #define PWM_LOOKUP(_provider, _index, _dev_id, _con_id)	\
2478138d2ddSThierry Reding 	{						\
2488138d2ddSThierry Reding 		.provider = _provider,			\
2498138d2ddSThierry Reding 		.index = _index,			\
2508138d2ddSThierry Reding 		.dev_id = _dev_id,			\
2518138d2ddSThierry Reding 		.con_id = _con_id,			\
2528138d2ddSThierry Reding 	}
2538138d2ddSThierry Reding 
2540bcf168bSTushar Behera #if IS_ENABLED(CONFIG_PWM)
2558138d2ddSThierry Reding void pwm_add_table(struct pwm_lookup *table, size_t num);
2560bcf168bSTushar Behera #else
2570bcf168bSTushar Behera static inline void pwm_add_table(struct pwm_lookup *table, size_t num)
2580bcf168bSTushar Behera {
2590bcf168bSTushar Behera }
2600c2498f1SSascha Hauer #endif
2610c2498f1SSascha Hauer 
2625243ef8bSMark Vels #endif /* __LINUX_PWM_H */
263