mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git
synced 2024-09-05 10:29:37 +00:00
![Linus Torvalds](/assets/img/avatar_default.png)
A new driver has been added to support the PWM mode of the timer counter blocks found on Atmel AT91 SoCs. The VT8500 driver now supports changing the PWM signal polarity and the TI drivers (EHRPWM and ECAP) gained suspend and resume functionality. User drivers can now query the core for whether access to a PWM device will sleep (if the PWM chip is on a slow bus such as I2C or SPI). The pwm-backlight driver now handles the backlight BL_CORE_FBBLANK state in addition to the FB layer's blanking states. To round things off, a few fixes and cleanups are also included. -----BEGIN PGP SIGNATURE----- Version: GnuPG v2.0.19 (GNU/Linux) iQIcBAABAgAGBQJRKxfbAAoJEN0jrNd/PrOhcwEP/0plVf30QDMhcan1GR3l+jmK 3Q/cCNIWEZ75mRu+FtVYKUOduxkCOHR6LM4C2ScGnnpsS/X5oitc45FrblIwQaEI UeWVxDqI+pEp+rCdYVCND4lih60FJU0Cct0zZL2db4D4idF+8FRChhzwzSXhajnj ZZqz782Y2ig3YTLHtVGT1pp61DKxdu1Gz4U+fxo4G1/fnkquCYDzbCQovcmPSnnF gYB8hfxgT9JIt2cHrK6eKCHBF/4GToU+x5zDV2Ub15C2K/UQ+qgw82yl8MNd/ZS5 rFA06iW3icnJRRc8u6hu9WVjNVNTBrUqUlFhctNB01d5jF4R6uR6aEvovT9xe8NW Wa5v5WrjnL6SWpZVwb/3kwwJmkeU9zKESQt5KUw3VKnT8yr2BfxcH1gJIiuW6wK7 uYqknAvt2rwMEGzaKZJmQH682wNMxpJirs8hG9VjJc/v7AOnk6586HbRupAq8wWZ qK4n1Fto9RCg+b6e/hDId7+mN1GEcA5B8BOotPQ6ud+cinDZBKSbCSHhQG2LQ++F m81BbL82H2R2ICRoYNA74/bKq5OVOFFqHLHg5bUrG7ikdNbYOTK/4dF9qSS7DnT3 Bi6WnKpOtfpWbHBnDunP2vBFo3f+gXmbLJdgarxk7mneV8wp0GY6TYI1awWn0hI9 82JP3yiK5kW2JZv92o0H =Fcxi -----END PGP SIGNATURE----- Merge tag 'for-3.9-rc1' of git://gitorious.org/linux-pwm/linux-pwm Pull PWM changes from Thierry Reding: "A new driver has been added to support the PWM mode of the timer counter blocks found on Atmel AT91 SoCs. The VT8500 driver now supports changing the PWM signal polarity and the TI drivers (EHRPWM and ECAP) gained suspend and resume functionality. User drivers can now query the core for whether access to a PWM device will sleep (if the PWM chip is on a slow bus such as I2C or SPI). The pwm-backlight driver now handles the backlight BL_CORE_FBBLANK state in addition to the FB layer's blanking states. To round things off, a few fixes and cleanups are also included" * tag 'for-3.9-rc1' of git://gitorious.org/linux-pwm/linux-pwm: pwm: twl: Use to_twl() instead of container_of() pwm: tegra: assume CONFIG_OF pwm_backlight: Validate dft_brightness in main probe function pwm: Export pwm_{set,get}_chip_data() pwm: Make Kconfig entries more consistent pwm: Add can_sleep property to drivers pwm: Add pwm_can_sleep() as exported API to users pwm-backlight: handle BL_CORE_FBBLANK state pwm: pwm-tiecap: Low power sleep support pwm: pwm-tiehrpwm: Low power sleep support pwm: pwm-tiehrpwm: Update the clock handling of pwm-tiehrpwm driver pwm: vt8500: Add polarity support pwm: vt8500: Register write busy test performed incorrectly pwm: atmel: add Timer Counter Block PWM driver
281 lines
6.6 KiB
C
281 lines
6.6 KiB
C
#ifndef __LINUX_PWM_H
|
|
#define __LINUX_PWM_H
|
|
|
|
#include <linux/err.h>
|
|
#include <linux/of.h>
|
|
|
|
struct pwm_device;
|
|
struct seq_file;
|
|
|
|
#if IS_ENABLED(CONFIG_PWM) || IS_ENABLED(CONFIG_HAVE_PWM)
|
|
/*
|
|
* 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);
|
|
#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
|
|
|
|
struct pwm_chip;
|
|
|
|
/**
|
|
* 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,
|
|
};
|
|
|
|
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;
|
|
}
|
|
|
|
/*
|
|
* pwm_set_polarity - configure the polarity of a PWM signal
|
|
*/
|
|
int pwm_set_polarity(struct pwm_device *pwm, enum pwm_polarity polarity);
|
|
|
|
/**
|
|
* 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
|
|
* @set_polarity: configure the polarity of this PWM
|
|
* @enable: enable PWM output toggling
|
|
* @disable: disable PWM output toggling
|
|
* @dbg_show: optional routine to show contents in debugfs
|
|
* @owner: helps prevent removal of modules exporting active PWMs
|
|
*/
|
|
struct pwm_ops {
|
|
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 (*set_polarity)(struct pwm_chip *chip,
|
|
struct pwm_device *pwm,
|
|
enum pwm_polarity polarity);
|
|
int (*enable)(struct pwm_chip *chip,
|
|
struct pwm_device *pwm);
|
|
void (*disable)(struct pwm_chip *chip,
|
|
struct pwm_device *pwm);
|
|
#ifdef CONFIG_DEBUG_FS
|
|
void (*dbg_show)(struct pwm_chip *chip,
|
|
struct seq_file *s);
|
|
#endif
|
|
struct module *owner;
|
|
};
|
|
|
|
/**
|
|
* 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
|
|
* @can_sleep: must be true if the .config(), .enable() or .disable()
|
|
* operations may sleep
|
|
*/
|
|
struct pwm_chip {
|
|
struct device *dev;
|
|
struct list_head list;
|
|
const struct pwm_ops *ops;
|
|
int base;
|
|
unsigned int npwm;
|
|
|
|
struct pwm_device *pwms;
|
|
|
|
struct pwm_device * (*of_xlate)(struct pwm_chip *pc,
|
|
const struct of_phandle_args *args);
|
|
unsigned int of_pwm_n_cells;
|
|
bool can_sleep;
|
|
};
|
|
|
|
#if IS_ENABLED(CONFIG_PWM)
|
|
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);
|
|
|
|
struct pwm_device *of_pwm_xlate_with_flags(struct pwm_chip *pc,
|
|
const struct of_phandle_args *args);
|
|
|
|
struct pwm_device *pwm_get(struct device *dev, const char *con_id);
|
|
struct pwm_device *of_pwm_get(struct device_node *np, const char *con_id);
|
|
void pwm_put(struct pwm_device *pwm);
|
|
|
|
struct pwm_device *devm_pwm_get(struct device *dev, const char *con_id);
|
|
struct pwm_device *devm_of_pwm_get(struct device *dev, struct device_node *np,
|
|
const char *con_id);
|
|
void devm_pwm_put(struct device *dev, struct pwm_device *pwm);
|
|
|
|
bool pwm_can_sleep(struct pwm_device *pwm);
|
|
#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 struct pwm_device *of_pwm_get(struct device_node *np,
|
|
const char *con_id)
|
|
{
|
|
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 struct pwm_device *devm_of_pwm_get(struct device *dev,
|
|
struct device_node *np,
|
|
const char *con_id)
|
|
{
|
|
return ERR_PTR(-ENODEV);
|
|
}
|
|
|
|
static inline void devm_pwm_put(struct device *dev, struct pwm_device *pwm)
|
|
{
|
|
}
|
|
|
|
static inline bool pwm_can_sleep(struct pwm_device *pwm)
|
|
{
|
|
return false;
|
|
}
|
|
#endif
|
|
|
|
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, \
|
|
}
|
|
|
|
#if IS_ENABLED(CONFIG_PWM)
|
|
void pwm_add_table(struct pwm_lookup *table, size_t num);
|
|
#else
|
|
static inline void pwm_add_table(struct pwm_lookup *table, size_t num)
|
|
{
|
|
}
|
|
#endif
|
|
|
|
#endif /* __LINUX_PWM_H */
|