mirror of
https://github.com/hardkernel/linux.git
synced 2026-06-07 19:30:30 +09:00
pwm: rockchip: Support pwm oneshot mode for specified number of cycles.
The oneshot_count value should be less than PWM_ONESHOT_COUNT_MAX. If oneshot_count == 0, this pwm channel works in continuous mode. Signed-off-by: Steven Liu <steven.liu@rock-chips.com> Change-Id: I45857fb5762e0365cce5278502479c580638e40c
This commit is contained in:
@@ -369,6 +369,12 @@ config PWM_ROCKCHIP
|
||||
Generic PWM framework driver for the PWM controller found on
|
||||
Rockchip SoCs.
|
||||
|
||||
config PWM_ROCKCHIP_ONESHOT
|
||||
bool "Rockchip PWM oneshot mode support"
|
||||
depends on PWM_ROCKCHIP
|
||||
help
|
||||
Support Rockchip pwm oneshot mode for specified number of cycles.
|
||||
|
||||
config PWM_SAMSUNG
|
||||
tristate "Samsung PWM support"
|
||||
depends on PLAT_SAMSUNG || ARCH_EXYNOS
|
||||
|
||||
@@ -34,6 +34,9 @@
|
||||
#define PWM_LOCK_EN (1 << 6)
|
||||
#define PWM_LP_DISABLE (0 << 8)
|
||||
|
||||
#define PWM_ONESHOT_COUNT_SHIFT 24
|
||||
#define PWM_ONESHOT_COUNT_MAX 256
|
||||
|
||||
struct rockchip_pwm_chip {
|
||||
struct pwm_chip chip;
|
||||
struct clk *clk;
|
||||
@@ -45,6 +48,7 @@ struct rockchip_pwm_chip {
|
||||
unsigned long clk_rate;
|
||||
bool vop_pwm_en; /* indicate voppwm mirror register state */
|
||||
bool center_aligned;
|
||||
bool oneshot;
|
||||
};
|
||||
|
||||
struct rockchip_pwm_regs {
|
||||
@@ -141,6 +145,19 @@ static void rockchip_pwm_config(struct pwm_chip *chip, struct pwm_device *pwm,
|
||||
ctrl &= ~PWM_ENABLE;
|
||||
}
|
||||
|
||||
#ifdef CONFIG_PWM_ROCKCHIP_ONESHOT
|
||||
if (state->oneshot_count > PWM_ONESHOT_COUNT_MAX) {
|
||||
pc->oneshot = false;
|
||||
dev_err(chip->dev, "Oneshot_count value overflow.\n");
|
||||
} else if (state->oneshot_count > 0) {
|
||||
pc->oneshot = true;
|
||||
ctrl |= (state->oneshot_count - 1) << PWM_ONESHOT_COUNT_SHIFT;
|
||||
} else {
|
||||
pc->oneshot = false;
|
||||
ctrl |= PWM_CONTINUOUS;
|
||||
}
|
||||
#endif
|
||||
|
||||
if (pc->data->supports_lock) {
|
||||
ctrl |= PWM_LOCK_EN;
|
||||
writel_relaxed(ctrl, pc->base + pc->data->regs.ctrl);
|
||||
@@ -192,10 +209,13 @@ static int rockchip_pwm_enable(struct pwm_chip *chip,
|
||||
val |= PWM_OUTPUT_CENTER;
|
||||
}
|
||||
|
||||
if (enable)
|
||||
if (enable) {
|
||||
val |= enable_conf;
|
||||
else
|
||||
if (pc->oneshot)
|
||||
val &= ~PWM_CONTINUOUS;
|
||||
} else {
|
||||
val &= ~enable_conf;
|
||||
}
|
||||
|
||||
writel_relaxed(val, pc->base + pc->data->regs.ctrl);
|
||||
if (pc->data->vop_pwm)
|
||||
@@ -243,7 +263,7 @@ static int rockchip_pwm_apply(struct pwm_chip *chip, struct pwm_device *pwm,
|
||||
*/
|
||||
rockchip_pwm_get_state(chip, pwm, state);
|
||||
|
||||
if (state->enabled)
|
||||
if (state->enabled || pc->oneshot)
|
||||
ret = pinctrl_select_state(pc->pinctrl, pc->active_state);
|
||||
out:
|
||||
clk_disable(pc->pclk);
|
||||
|
||||
@@ -84,6 +84,9 @@ struct pwm_state {
|
||||
enum pwm_polarity polarity;
|
||||
enum pwm_output_type output_type;
|
||||
struct pwm_output_pattern *output_pattern;
|
||||
#ifdef CONFIG_PWM_ROCKCHIP_ONESHOT
|
||||
u64 oneshot_count;
|
||||
#endif /* CONFIG_PWM_ROCKCHIP_ONESHOT */
|
||||
bool enabled;
|
||||
};
|
||||
|
||||
|
||||
Reference in New Issue
Block a user