aboutsummaryrefslogtreecommitdiff
path: root/include/linux/pwm.h
diff options
context:
space:
mode:
authorThierry Reding <thierry.reding@avionic-design.de>2011-12-14 11:12:23 +0100
committerThierry Reding <thierry.reding@avionic-design.de>2012-06-15 12:56:52 +0200
commitf051c466cf690ac661d713d3ceb56b4efcecc853 (patch)
tree15291a08d3ec44e8ab81c44370e1ac2bbb366ec5 /include/linux/pwm.h
parent0c2498f1660878339350bea8d18550b1b87ca055 (diff)
pwm: Allow chips to support multiple PWMs
Many PWM controllers provide access to more than a single PWM output and may even share some resource among them. Allowing a PWM chip to provide multiple PWM devices enables better sharing of those resources. As a side-effect this change allows easy integration with the device tree where a given PWM can be looked up based on the PWM chip's phandle and a corresponding index. This commit modifies the PWM core to support multiple PWMs per struct pwm_chip. It achieves this in a similar way to how gpiolib works, by allowing PWM ranges to be requested dynamically (pwm_chip.base == -1) or starting at a given offset (pwm_chip.base >= 0). A chip specifies how many PWMs it controls using the npwm member. Each of the functions in the pwm_ops structure gets an additional argument that specified the PWM number (it can be converted to a per-chip index by subtracting the chip's base). The total maximum number of PWM devices is currently fixed to 1024 while the data is actually stored in a radix tree, thus saving resources if not all of them are used. Reviewed-by: Mark Brown <broonie@opensource.wolfsonmicro.com> Reviewed-by: Shawn Guo <shawn.guo@linaro.org> [eric@eukrea.com: fix error handling in pwmchip_add] Signed-off-by: Eric BĂ©nard <eric@eukrea.com> Signed-off-by: Thierry Reding <thierry.reding@avionic-design.de>
Diffstat (limited to 'include/linux/pwm.h')
-rw-r--r--include/linux/pwm.h71
1 files changed, 58 insertions, 13 deletions
diff --git a/include/linux/pwm.h b/include/linux/pwm.h
index 1f308a13105f..57103911f4c7 100644
--- a/include/linux/pwm.h
+++ b/include/linux/pwm.h
@@ -31,6 +31,33 @@ void pwm_disable(struct pwm_device *pwm);
#ifdef CONFIG_PWM
struct pwm_chip;
+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;
+}
+
/**
* struct pwm_ops - PWM controller operations
* @request: optional hook for requesting a PWM
@@ -41,29 +68,47 @@ struct pwm_chip;
* @owner: helps prevent removal of modules exporting active PWMs
*/
struct pwm_ops {
- int (*request)(struct pwm_chip *chip);
- void (*free)(struct pwm_chip *chip);
- int (*config)(struct pwm_chip *chip, int duty_ns,
- int period_ns);
- int (*enable)(struct pwm_chip *chip);
- void (*disable)(struct pwm_chip *chip);
+ 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);
+ int (*enable)(struct pwm_chip *chip,
+ struct pwm_device *pwm);
+ void (*disable)(struct pwm_chip *chip,
+ struct pwm_device *pwm);
struct module *owner;
};
/**
- * struct pwm_chip - abstract a PWM
- * @pwm_id: global PWM device index
- * @label: PWM device label
- * @ops: controller operations
+ * 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
*/
struct pwm_chip {
- int pwm_id;
- const char *label;
- struct pwm_ops *ops;
+ struct device *dev;
+ struct list_head list;
+ const struct pwm_ops *ops;
+ int base;
+ unsigned int npwm;
+
+ struct pwm_device *pwms;
};
+int pwm_set_chip_data(struct pwm_device *pwm, void *data);
+void *pwm_get_chip_data(struct pwm_device *pwm);
+
int pwmchip_add(struct pwm_chip *chip);
int pwmchip_remove(struct pwm_chip *chip);
+struct pwm_device *pwm_request_from_chip(struct pwm_chip *chip,
+ unsigned int index,
+ const char *label);
#endif
#endif /* __LINUX_PWM_H */