xref: /linux-6.15/include/linux/pwm.h (revision 83af2402)
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 
174*83af2402SPhilip, Avinash struct pwm_device *of_pwm_xlate_with_flags(struct pwm_chip *pc,
175*83af2402SPhilip, Avinash 		const struct of_phandle_args *args);
176*83af2402SPhilip, Avinash 
1778138d2ddSThierry Reding struct pwm_device *pwm_get(struct device *dev, const char *consumer);
1788138d2ddSThierry Reding void pwm_put(struct pwm_device *pwm);
1798138d2ddSThierry Reding 
1806354316dSAlexandre Courbot struct pwm_device *devm_pwm_get(struct device *dev, const char *consumer);
1816354316dSAlexandre Courbot void devm_pwm_put(struct device *dev, struct pwm_device *pwm);
1820bcf168bSTushar Behera #else
1830bcf168bSTushar Behera static inline int pwm_set_chip_data(struct pwm_device *pwm, void *data)
1840bcf168bSTushar Behera {
1850bcf168bSTushar Behera 	return -EINVAL;
1860bcf168bSTushar Behera }
1870bcf168bSTushar Behera 
1880bcf168bSTushar Behera static inline void *pwm_get_chip_data(struct pwm_device *pwm)
1890bcf168bSTushar Behera {
1900bcf168bSTushar Behera 	return NULL;
1910bcf168bSTushar Behera }
1920bcf168bSTushar Behera 
1930bcf168bSTushar Behera static inline int pwmchip_add(struct pwm_chip *chip)
1940bcf168bSTushar Behera {
1950bcf168bSTushar Behera 	return -EINVAL;
1960bcf168bSTushar Behera }
1970bcf168bSTushar Behera 
1980bcf168bSTushar Behera static inline int pwmchip_remove(struct pwm_chip *chip)
1990bcf168bSTushar Behera {
2000bcf168bSTushar Behera 	return -EINVAL;
2010bcf168bSTushar Behera }
2020bcf168bSTushar Behera 
2030bcf168bSTushar Behera static inline struct pwm_device *pwm_request_from_chip(struct pwm_chip *chip,
2040bcf168bSTushar Behera 						       unsigned int index,
2050bcf168bSTushar Behera 						       const char *label)
2060bcf168bSTushar Behera {
2070bcf168bSTushar Behera 	return ERR_PTR(-ENODEV);
2080bcf168bSTushar Behera }
2090bcf168bSTushar Behera 
2100bcf168bSTushar Behera static inline struct pwm_device *pwm_get(struct device *dev,
2110bcf168bSTushar Behera 					 const char *consumer)
2120bcf168bSTushar Behera {
2130bcf168bSTushar Behera 	return ERR_PTR(-ENODEV);
2140bcf168bSTushar Behera }
2150bcf168bSTushar Behera 
2160bcf168bSTushar Behera static inline void pwm_put(struct pwm_device *pwm)
2170bcf168bSTushar Behera {
2180bcf168bSTushar Behera }
2190bcf168bSTushar Behera 
2200bcf168bSTushar Behera static inline struct pwm_device *devm_pwm_get(struct device *dev,
2210bcf168bSTushar Behera 					      const char *consumer)
2220bcf168bSTushar Behera {
2230bcf168bSTushar Behera 	return ERR_PTR(-ENODEV);
2240bcf168bSTushar Behera }
2250bcf168bSTushar Behera 
2260bcf168bSTushar Behera static inline void devm_pwm_put(struct device *dev, struct pwm_device *pwm)
2270bcf168bSTushar Behera {
2280bcf168bSTushar Behera }
2290bcf168bSTushar Behera #endif
2306354316dSAlexandre Courbot 
2318138d2ddSThierry Reding struct pwm_lookup {
2328138d2ddSThierry Reding 	struct list_head list;
2338138d2ddSThierry Reding 	const char *provider;
2348138d2ddSThierry Reding 	unsigned int index;
2358138d2ddSThierry Reding 	const char *dev_id;
2368138d2ddSThierry Reding 	const char *con_id;
2378138d2ddSThierry Reding };
2388138d2ddSThierry Reding 
2398138d2ddSThierry Reding #define PWM_LOOKUP(_provider, _index, _dev_id, _con_id)	\
2408138d2ddSThierry Reding 	{						\
2418138d2ddSThierry Reding 		.provider = _provider,			\
2428138d2ddSThierry Reding 		.index = _index,			\
2438138d2ddSThierry Reding 		.dev_id = _dev_id,			\
2448138d2ddSThierry Reding 		.con_id = _con_id,			\
2458138d2ddSThierry Reding 	}
2468138d2ddSThierry Reding 
2470bcf168bSTushar Behera #if IS_ENABLED(CONFIG_PWM)
2488138d2ddSThierry Reding void pwm_add_table(struct pwm_lookup *table, size_t num);
2490bcf168bSTushar Behera #else
2500bcf168bSTushar Behera static inline void pwm_add_table(struct pwm_lookup *table, size_t num)
2510bcf168bSTushar Behera {
2520bcf168bSTushar Behera }
2530c2498f1SSascha Hauer #endif
2540c2498f1SSascha Hauer 
2555243ef8bSMark Vels #endif /* __LINUX_PWM_H */
256