xref: /linux-6.15/include/linux/pwm.h (revision 0bcf168b)
11a189b97SRussell King #ifndef __LINUX_PWM_H
21a189b97SRussell King #define __LINUX_PWM_H
31a189b97SRussell King 
4*0bcf168bSTushar 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 
10*0bcf168bSTushar 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);
35*0bcf168bSTushar Behera #else
36*0bcf168bSTushar Behera static inline struct pwm_device *pwm_request(int pwm_id, const char *label)
37*0bcf168bSTushar Behera {
38*0bcf168bSTushar Behera 	return ERR_PTR(-ENODEV);
39*0bcf168bSTushar Behera }
401a189b97SRussell King 
41*0bcf168bSTushar Behera static inline void pwm_free(struct pwm_device *pwm)
42*0bcf168bSTushar Behera {
43*0bcf168bSTushar Behera }
44*0bcf168bSTushar Behera 
45*0bcf168bSTushar Behera static inline int pwm_config(struct pwm_device *pwm, int duty_ns, int period_ns)
46*0bcf168bSTushar Behera {
47*0bcf168bSTushar Behera 	return -EINVAL;
48*0bcf168bSTushar Behera }
49*0bcf168bSTushar Behera 
50*0bcf168bSTushar Behera static inline int pwm_enable(struct pwm_device *pwm)
51*0bcf168bSTushar Behera {
52*0bcf168bSTushar Behera 	return -EINVAL;
53*0bcf168bSTushar Behera }
54*0bcf168bSTushar Behera 
55*0bcf168bSTushar Behera static inline void pwm_disable(struct pwm_device *pwm)
56*0bcf168bSTushar Behera {
57*0bcf168bSTushar Behera }
58*0bcf168bSTushar Behera #endif
59*0bcf168bSTushar 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 
164*0bcf168bSTushar 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 
1748138d2ddSThierry Reding struct pwm_device *pwm_get(struct device *dev, const char *consumer);
1758138d2ddSThierry Reding void pwm_put(struct pwm_device *pwm);
1768138d2ddSThierry Reding 
1776354316dSAlexandre Courbot struct pwm_device *devm_pwm_get(struct device *dev, const char *consumer);
1786354316dSAlexandre Courbot void devm_pwm_put(struct device *dev, struct pwm_device *pwm);
179*0bcf168bSTushar Behera #else
180*0bcf168bSTushar Behera static inline int pwm_set_chip_data(struct pwm_device *pwm, void *data)
181*0bcf168bSTushar Behera {
182*0bcf168bSTushar Behera 	return -EINVAL;
183*0bcf168bSTushar Behera }
184*0bcf168bSTushar Behera 
185*0bcf168bSTushar Behera static inline void *pwm_get_chip_data(struct pwm_device *pwm)
186*0bcf168bSTushar Behera {
187*0bcf168bSTushar Behera 	return NULL;
188*0bcf168bSTushar Behera }
189*0bcf168bSTushar Behera 
190*0bcf168bSTushar Behera static inline int pwmchip_add(struct pwm_chip *chip)
191*0bcf168bSTushar Behera {
192*0bcf168bSTushar Behera 	return -EINVAL;
193*0bcf168bSTushar Behera }
194*0bcf168bSTushar Behera 
195*0bcf168bSTushar Behera static inline int pwmchip_remove(struct pwm_chip *chip)
196*0bcf168bSTushar Behera {
197*0bcf168bSTushar Behera 	return -EINVAL;
198*0bcf168bSTushar Behera }
199*0bcf168bSTushar Behera 
200*0bcf168bSTushar Behera static inline struct pwm_device *pwm_request_from_chip(struct pwm_chip *chip,
201*0bcf168bSTushar Behera 						       unsigned int index,
202*0bcf168bSTushar Behera 						       const char *label)
203*0bcf168bSTushar Behera {
204*0bcf168bSTushar Behera 	return ERR_PTR(-ENODEV);
205*0bcf168bSTushar Behera }
206*0bcf168bSTushar Behera 
207*0bcf168bSTushar Behera static inline struct pwm_device *pwm_get(struct device *dev,
208*0bcf168bSTushar Behera 					 const char *consumer)
209*0bcf168bSTushar Behera {
210*0bcf168bSTushar Behera 	return ERR_PTR(-ENODEV);
211*0bcf168bSTushar Behera }
212*0bcf168bSTushar Behera 
213*0bcf168bSTushar Behera static inline void pwm_put(struct pwm_device *pwm)
214*0bcf168bSTushar Behera {
215*0bcf168bSTushar Behera }
216*0bcf168bSTushar Behera 
217*0bcf168bSTushar Behera static inline struct pwm_device *devm_pwm_get(struct device *dev,
218*0bcf168bSTushar Behera 					      const char *consumer)
219*0bcf168bSTushar Behera {
220*0bcf168bSTushar Behera 	return ERR_PTR(-ENODEV);
221*0bcf168bSTushar Behera }
222*0bcf168bSTushar Behera 
223*0bcf168bSTushar Behera static inline void devm_pwm_put(struct device *dev, struct pwm_device *pwm)
224*0bcf168bSTushar Behera {
225*0bcf168bSTushar Behera }
226*0bcf168bSTushar Behera #endif
2276354316dSAlexandre Courbot 
2288138d2ddSThierry Reding struct pwm_lookup {
2298138d2ddSThierry Reding 	struct list_head list;
2308138d2ddSThierry Reding 	const char *provider;
2318138d2ddSThierry Reding 	unsigned int index;
2328138d2ddSThierry Reding 	const char *dev_id;
2338138d2ddSThierry Reding 	const char *con_id;
2348138d2ddSThierry Reding };
2358138d2ddSThierry Reding 
2368138d2ddSThierry Reding #define PWM_LOOKUP(_provider, _index, _dev_id, _con_id)	\
2378138d2ddSThierry Reding 	{						\
2388138d2ddSThierry Reding 		.provider = _provider,			\
2398138d2ddSThierry Reding 		.index = _index,			\
2408138d2ddSThierry Reding 		.dev_id = _dev_id,			\
2418138d2ddSThierry Reding 		.con_id = _con_id,			\
2428138d2ddSThierry Reding 	}
2438138d2ddSThierry Reding 
244*0bcf168bSTushar Behera #if IS_ENABLED(CONFIG_PWM)
2458138d2ddSThierry Reding void pwm_add_table(struct pwm_lookup *table, size_t num);
246*0bcf168bSTushar Behera #else
247*0bcf168bSTushar Behera static inline void pwm_add_table(struct pwm_lookup *table, size_t num)
248*0bcf168bSTushar Behera {
249*0bcf168bSTushar Behera }
2500c2498f1SSascha Hauer #endif
2510c2498f1SSascha Hauer 
2525243ef8bSMark Vels #endif /* __LINUX_PWM_H */
253