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:
Steven Liu
2020-10-20 15:19:21 +08:00
committed by Tao Huang
parent c83c32522f
commit ea419b14d6
3 changed files with 31 additions and 2 deletions

View File

@@ -408,6 +408,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 && NO_GKI
help
Support Rockchip pwm oneshot mode for specified number of cycles.
config PWM_SAMSUNG
tristate "Samsung PWM support"
depends on PLAT_SAMSUNG || ARCH_S5PV210 || ARCH_EXYNOS || COMPILE_TEST

View File

@@ -30,6 +30,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;
@@ -39,6 +42,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 {
@@ -130,6 +134,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);
@@ -181,10 +198,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)

View File

@@ -71,6 +71,9 @@ struct pwm_state {
u64 duty_cycle;
enum pwm_polarity polarity;
enum pwm_output_type output_type;
#ifdef CONFIG_PWM_ROCKCHIP_ONESHOT
u64 oneshot_count;
#endif /* CONFIG_PWM_ROCKCHIP_ONESHOT */
bool enabled;
};