Add support for PWM push-pull mode. This is only supported by SAMA5D2 SoCs.

Signed-off-by: Claudiu Beznea <claudiu.bez...@microchip.com>
---
 drivers/pwm/pwm-atmel.c | 40 ++++++++++++++++++++++++++++++++++++----
 1 file changed, 36 insertions(+), 4 deletions(-)

diff --git a/drivers/pwm/pwm-atmel.c b/drivers/pwm/pwm-atmel.c
index d2482fe28cfa..da4b58c1ecf2 100644
--- a/drivers/pwm/pwm-atmel.c
+++ b/drivers/pwm/pwm-atmel.c
@@ -33,8 +33,11 @@
 
 #define PWM_CMR                        0x0
 /* Bit field in CMR */
-#define PWM_CMR_CPOL           (1 << 9)
-#define PWM_CMR_UPD_CDTY       (1 << 10)
+#define PWM_CMR_CPOL           BIT(9)
+#define PWM_CMR_UPD_CDTY       BIT(10)
+#define PWM_CMR_DTHI           BIT(17)
+#define PWM_CMR_DTLI           BIT(18)
+#define PWM_CMR_PPM            BIT(19)
 #define PWM_CMR_CPRE_MSK       0xF
 
 /* The following registers for PWM v1 */
@@ -219,16 +222,19 @@ static int atmel_pwm_apply(struct pwm_chip *chip, struct 
pwm_device *pwm,
 {
        struct atmel_pwm_chip *atmel_pwm = to_atmel_pwm_chip(chip);
        struct pwm_state cstate;
+       struct pwm_caps caps;
        unsigned long cprd, cdty;
        u32 pres, val;
        int ret;
 
        pwm_get_state(pwm, &cstate);
+       pwm_get_caps(chip, pwm, &caps);
 
        if (state->enabled) {
                if (cstate.enabled &&
                    cstate.polarity == state->polarity &&
-                   cstate.period == state->period) {
+                   cstate.period == state->period &&
+                   cstate.mode == state->mode) {
                        cprd = atmel_pwm_ch_readl(atmel_pwm, pwm->hwpwm,
                                                  atmel_pwm->data->regs.period);
                        atmel_pwm_calculate_cdty(state, cprd, &cdty);
@@ -263,6 +269,18 @@ static int atmel_pwm_apply(struct pwm_chip *chip, struct 
pwm_device *pwm,
                        val &= ~PWM_CMR_CPOL;
                else
                        val |= PWM_CMR_CPOL;
+
+               /* PWM mode. */
+               if (caps.modes & PWM_MODE(PUSH_PULL)) {
+                       if (state->mode == PWM_MODE(PUSH_PULL)) {
+                               val |= PWM_CMR_PPM | PWM_CMR_DTLI;
+                               val &= ~PWM_CMR_DTHI;
+                       } else {
+                               val &= ~(PWM_CMR_PPM | PWM_CMR_DTLI |
+                                        PWM_CMR_DTHI);
+                       }
+               }
+
                atmel_pwm_ch_writel(atmel_pwm, pwm->hwpwm, PWM_CMR, val);
                atmel_pwm_set_cprd_cdty(chip, pwm, cprd, cdty);
                mutex_lock(&atmel_pwm->isr_lock);
@@ -315,6 +333,20 @@ static const struct atmel_pwm_data atmel_pwm_data_v2 = {
        },
 };
 
+static const struct atmel_pwm_data atmel_pwm_data_v3 = {
+       .regs = {
+               .period         = PWMV2_CPRD,
+               .period_upd     = PWMV2_CPRDUPD,
+               .duty           = PWMV2_CDTY,
+               .duty_upd       = PWMV2_CDTYUPD,
+       },
+       .caps = {
+               .modes = PWM_MODE(NORMAL) |
+                        PWM_MODE(COMPLEMENTARY) |
+                        PWM_MODE(PUSH_PULL),
+       },
+};
+
 static const struct platform_device_id atmel_pwm_devtypes[] = {
        {
                .name = "at91sam9rl-pwm",
@@ -337,7 +369,7 @@ static const struct of_device_id atmel_pwm_dt_ids[] = {
                .data = &atmel_pwm_data_v2,
        }, {
                .compatible = "atmel,sama5d2-pwm",
-               .data = &atmel_pwm_data_v2,
+               .data = &atmel_pwm_data_v3,
        }, {
                /* sentinel */
        },
-- 
2.7.4

_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

Reply via email to