pwm.h 5.9 KB
Newer Older
R
Russell King 已提交
1 2 3
#ifndef __LINUX_PWM_H
#define __LINUX_PWM_H

4
#include <linux/err.h>
T
Thierry Reding 已提交
5 6
#include <linux/of.h>

R
Russell King 已提交
7
struct pwm_device;
T
Thierry Reding 已提交
8
struct seq_file;
R
Russell King 已提交
9

10
#if IS_ENABLED(CONFIG_PWM) || IS_ENABLED(CONFIG_HAVE_PWM)
R
Russell King 已提交
11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34
/*
 * pwm_request - request a PWM device
 */
struct pwm_device *pwm_request(int pwm_id, const char *label);

/*
 * pwm_free - free a PWM device
 */
void pwm_free(struct pwm_device *pwm);

/*
 * pwm_config - change a PWM device configuration
 */
int pwm_config(struct pwm_device *pwm, int duty_ns, int period_ns);

/*
 * pwm_enable - start a PWM output toggling
 */
int pwm_enable(struct pwm_device *pwm);

/*
 * pwm_disable - stop a PWM output toggling
 */
void pwm_disable(struct pwm_device *pwm);
35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58
#else
static inline struct pwm_device *pwm_request(int pwm_id, const char *label)
{
	return ERR_PTR(-ENODEV);
}

static inline void pwm_free(struct pwm_device *pwm)
{
}

static inline int pwm_config(struct pwm_device *pwm, int duty_ns, int period_ns)
{
	return -EINVAL;
}

static inline int pwm_enable(struct pwm_device *pwm)
{
	return -EINVAL;
}

static inline void pwm_disable(struct pwm_device *pwm)
{
}
#endif
R
Russell King 已提交
59

S
Sascha Hauer 已提交
60 61
struct pwm_chip;

62 63 64 65 66 67 68 69 70 71 72 73 74 75
/**
 * enum pwm_polarity - polarity of a PWM signal
 * @PWM_POLARITY_NORMAL: a high signal for the duration of the duty-
 * cycle, followed by a low signal for the remainder of the pulse
 * period
 * @PWM_POLARITY_INVERSED: a low signal for the duration of the duty-
 * cycle, followed by a high signal for the remainder of the pulse
 * period
 */
enum pwm_polarity {
	PWM_POLARITY_NORMAL,
	PWM_POLARITY_INVERSED,
};

76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102
enum {
	PWMF_REQUESTED = 1 << 0,
	PWMF_ENABLED = 1 << 1,
};

struct pwm_device {
	const char		*label;
	unsigned long		flags;
	unsigned int		hwpwm;
	unsigned int		pwm;
	struct pwm_chip		*chip;
	void			*chip_data;

	unsigned int		period; /* in nanoseconds */
};

static inline void pwm_set_period(struct pwm_device *pwm, unsigned int period)
{
	if (pwm)
		pwm->period = period;
}

static inline unsigned int pwm_get_period(struct pwm_device *pwm)
{
	return pwm ? pwm->period : 0;
}

103 104 105 106 107
/*
 * pwm_set_polarity - configure the polarity of a PWM signal
 */
int pwm_set_polarity(struct pwm_device *pwm, enum pwm_polarity polarity);

S
Sascha Hauer 已提交
108 109 110 111 112
/**
 * struct pwm_ops - PWM controller operations
 * @request: optional hook for requesting a PWM
 * @free: optional hook for freeing a PWM
 * @config: configure duty cycles and period length for this PWM
113
 * @set_polarity: configure the polarity of this PWM
S
Sascha Hauer 已提交
114 115
 * @enable: enable PWM output toggling
 * @disable: disable PWM output toggling
T
Thierry Reding 已提交
116
 * @dbg_show: optional routine to show contents in debugfs
S
Sascha Hauer 已提交
117 118 119
 * @owner: helps prevent removal of modules exporting active PWMs
 */
struct pwm_ops {
120 121 122 123 124 125 126
	int			(*request)(struct pwm_chip *chip,
					   struct pwm_device *pwm);
	void			(*free)(struct pwm_chip *chip,
					struct pwm_device *pwm);
	int			(*config)(struct pwm_chip *chip,
					  struct pwm_device *pwm,
					  int duty_ns, int period_ns);
127 128 129
	int			(*set_polarity)(struct pwm_chip *chip,
					  struct pwm_device *pwm,
					  enum pwm_polarity polarity);
130 131 132 133
	int			(*enable)(struct pwm_chip *chip,
					  struct pwm_device *pwm);
	void			(*disable)(struct pwm_chip *chip,
					   struct pwm_device *pwm);
T
Thierry Reding 已提交
134 135 136 137
#ifdef CONFIG_DEBUG_FS
	void			(*dbg_show)(struct pwm_chip *chip,
					    struct seq_file *s);
#endif
S
Sascha Hauer 已提交
138 139 140 141
	struct module		*owner;
};

/**
142 143 144 145 146 147 148
 * struct pwm_chip - abstract a PWM controller
 * @dev: device providing the PWMs
 * @list: list node for internal use
 * @ops: callbacks for this PWM controller
 * @base: number of first PWM controlled by this chip
 * @npwm: number of PWMs controlled by this chip
 * @pwms: array of PWM devices allocated by the framework
S
Sascha Hauer 已提交
149 150
 */
struct pwm_chip {
151 152 153 154 155 156 157
	struct device		*dev;
	struct list_head	list;
	const struct pwm_ops	*ops;
	int			base;
	unsigned int		npwm;

	struct pwm_device	*pwms;
T
Thierry Reding 已提交
158 159 160 161

	struct pwm_device *	(*of_xlate)(struct pwm_chip *pc,
					    const struct of_phandle_args *args);
	unsigned int		of_pwm_n_cells;
S
Sascha Hauer 已提交
162 163
};

164
#if IS_ENABLED(CONFIG_PWM)
165 166 167
int pwm_set_chip_data(struct pwm_device *pwm, void *data);
void *pwm_get_chip_data(struct pwm_device *pwm);

S
Sascha Hauer 已提交
168 169
int pwmchip_add(struct pwm_chip *chip);
int pwmchip_remove(struct pwm_chip *chip);
170 171 172
struct pwm_device *pwm_request_from_chip(struct pwm_chip *chip,
					 unsigned int index,
					 const char *label);
173

174 175 176
struct pwm_device *of_pwm_xlate_with_flags(struct pwm_chip *pc,
		const struct of_phandle_args *args);

177
struct pwm_device *pwm_get(struct device *dev, const char *con_id);
178 179
void pwm_put(struct pwm_device *pwm);

180
struct pwm_device *devm_pwm_get(struct device *dev, const char *con_id);
181
void devm_pwm_put(struct device *dev, struct pwm_device *pwm);
182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229
#else
static inline int pwm_set_chip_data(struct pwm_device *pwm, void *data)
{
	return -EINVAL;
}

static inline void *pwm_get_chip_data(struct pwm_device *pwm)
{
	return NULL;
}

static inline int pwmchip_add(struct pwm_chip *chip)
{
	return -EINVAL;
}

static inline int pwmchip_remove(struct pwm_chip *chip)
{
	return -EINVAL;
}

static inline struct pwm_device *pwm_request_from_chip(struct pwm_chip *chip,
						       unsigned int index,
						       const char *label)
{
	return ERR_PTR(-ENODEV);
}

static inline struct pwm_device *pwm_get(struct device *dev,
					 const char *consumer)
{
	return ERR_PTR(-ENODEV);
}

static inline void pwm_put(struct pwm_device *pwm)
{
}

static inline struct pwm_device *devm_pwm_get(struct device *dev,
					      const char *consumer)
{
	return ERR_PTR(-ENODEV);
}

static inline void devm_pwm_put(struct device *dev, struct pwm_device *pwm)
{
}
#endif
230

231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246
struct pwm_lookup {
	struct list_head list;
	const char *provider;
	unsigned int index;
	const char *dev_id;
	const char *con_id;
};

#define PWM_LOOKUP(_provider, _index, _dev_id, _con_id)	\
	{						\
		.provider = _provider,			\
		.index = _index,			\
		.dev_id = _dev_id,			\
		.con_id = _con_id,			\
	}

247
#if IS_ENABLED(CONFIG_PWM)
248
void pwm_add_table(struct pwm_lookup *table, size_t num);
249 250 251 252
#else
static inline void pwm_add_table(struct pwm_lookup *table, size_t num)
{
}
S
Sascha Hauer 已提交
253 254
#endif

M
Mark Vels 已提交
255
#endif /* __LINUX_PWM_H */