[PATCH v3 07/10] pwm: atmel: add pwm capabilities

2018-02-22 Thread Claudiu Beznea
Add pwm capabilities for Atmel/Microchip PWM controllers.

Signed-off-by: Claudiu Beznea 
---
 drivers/pwm/pwm-atmel.c | 80 -
 1 file changed, 52 insertions(+), 28 deletions(-)

diff --git a/drivers/pwm/pwm-atmel.c b/drivers/pwm/pwm-atmel.c
index 530d7dc5f1b5..d2482fe28cfa 100644
--- a/drivers/pwm/pwm-atmel.c
+++ b/drivers/pwm/pwm-atmel.c
@@ -65,11 +65,16 @@ struct atmel_pwm_registers {
u8 duty_upd;
 };
 
+struct atmel_pwm_data {
+   struct atmel_pwm_registers regs;
+   struct pwm_caps caps;
+};
+
 struct atmel_pwm_chip {
struct pwm_chip chip;
struct clk *clk;
void __iomem *base;
-   const struct atmel_pwm_registers *regs;
+   const struct atmel_pwm_data *data;
 
unsigned int updated_pwms;
/* ISR is cleared when read, ensure only one thread does that */
@@ -150,15 +155,15 @@ static void atmel_pwm_update_cdty(struct pwm_chip *chip, 
struct pwm_device *pwm,
struct atmel_pwm_chip *atmel_pwm = to_atmel_pwm_chip(chip);
u32 val;
 
-   if (atmel_pwm->regs->duty_upd ==
-   atmel_pwm->regs->period_upd) {
+   if (atmel_pwm->data->regs.duty_upd ==
+   atmel_pwm->data->regs.period_upd) {
val = atmel_pwm_ch_readl(atmel_pwm, pwm->hwpwm, PWM_CMR);
val &= ~PWM_CMR_UPD_CDTY;
atmel_pwm_ch_writel(atmel_pwm, pwm->hwpwm, PWM_CMR, val);
}
 
atmel_pwm_ch_writel(atmel_pwm, pwm->hwpwm,
-   atmel_pwm->regs->duty_upd, cdty);
+   atmel_pwm->data->regs.duty_upd, cdty);
 }
 
 static void atmel_pwm_set_cprd_cdty(struct pwm_chip *chip,
@@ -168,9 +173,9 @@ static void atmel_pwm_set_cprd_cdty(struct pwm_chip *chip,
struct atmel_pwm_chip *atmel_pwm = to_atmel_pwm_chip(chip);
 
atmel_pwm_ch_writel(atmel_pwm, pwm->hwpwm,
-   atmel_pwm->regs->duty, cdty);
+   atmel_pwm->data->regs.duty, cdty);
atmel_pwm_ch_writel(atmel_pwm, pwm->hwpwm,
-   atmel_pwm->regs->period, cprd);
+   atmel_pwm->data->regs.period, cprd);
 }
 
 static void atmel_pwm_disable(struct pwm_chip *chip, struct pwm_device *pwm,
@@ -225,7 +230,7 @@ static int atmel_pwm_apply(struct pwm_chip *chip, struct 
pwm_device *pwm,
cstate.polarity == state->polarity &&
cstate.period == state->period) {
cprd = atmel_pwm_ch_readl(atmel_pwm, pwm->hwpwm,
- atmel_pwm->regs->period);
+ atmel_pwm->data->regs.period);
atmel_pwm_calculate_cdty(state, cprd, );
atmel_pwm_update_cdty(chip, pwm, cdty);
return 0;
@@ -272,32 +277,51 @@ static int atmel_pwm_apply(struct pwm_chip *chip, struct 
pwm_device *pwm,
return 0;
 }
 
+static void atmel_pwm_get_caps(struct pwm_chip *chip, struct pwm_device *pwm,
+  struct pwm_caps *caps)
+{
+   struct atmel_pwm_chip *atmel_pwm = to_atmel_pwm_chip(chip);
+
+   *caps = atmel_pwm->data->caps;
+}
+
 static const struct pwm_ops atmel_pwm_ops = {
.apply = atmel_pwm_apply,
+   .get_caps = atmel_pwm_get_caps,
.owner = THIS_MODULE,
 };
 
-static const struct atmel_pwm_registers atmel_pwm_regs_v1 = {
-   .period = PWMV1_CPRD,
-   .period_upd = PWMV1_CUPD,
-   .duty   = PWMV1_CDTY,
-   .duty_upd   = PWMV1_CUPD,
+static const struct atmel_pwm_data atmel_pwm_data_v1 = {
+   .regs = {
+   .period = PWMV1_CPRD,
+   .period_upd = PWMV1_CUPD,
+   .duty   = PWMV1_CDTY,
+   .duty_upd   = PWMV1_CUPD,
+   },
+   .caps = {
+   .modes = PWM_MODE(NORMAL),
+   },
 };
 
-static const struct atmel_pwm_registers atmel_pwm_regs_v2 = {
-   .period = PWMV2_CPRD,
-   .period_upd = PWMV2_CPRDUPD,
-   .duty   = PWMV2_CDTY,
-   .duty_upd   = PWMV2_CDTYUPD,
+static const struct atmel_pwm_data atmel_pwm_data_v2 = {
+   .regs = {
+   .period = PWMV2_CPRD,
+   .period_upd = PWMV2_CPRDUPD,
+   .duty   = PWMV2_CDTY,
+   .duty_upd   = PWMV2_CDTYUPD,
+   },
+   .caps = {
+   .modes = PWM_MODE(NORMAL) | PWM_MODE(COMPLEMENTARY),
+   },
 };
 
 static const struct platform_device_id atmel_pwm_devtypes[] = {
{
.name = "at91sam9rl-pwm",
-   .driver_data = (kernel_ulong_t)_pwm_regs_v1,
+   .driver_data = (kernel_ulong_t)_pwm_data_v1,
}, {
.name = "sama5d3-pwm",
-   .driver_data = (kernel_ulong_t)_pwm_regs_v2,
+   .driver_data = 

[PATCH v3 07/10] pwm: atmel: add pwm capabilities

2018-02-22 Thread Claudiu Beznea
Add pwm capabilities for Atmel/Microchip PWM controllers.

Signed-off-by: Claudiu Beznea 
---
 drivers/pwm/pwm-atmel.c | 80 -
 1 file changed, 52 insertions(+), 28 deletions(-)

diff --git a/drivers/pwm/pwm-atmel.c b/drivers/pwm/pwm-atmel.c
index 530d7dc5f1b5..d2482fe28cfa 100644
--- a/drivers/pwm/pwm-atmel.c
+++ b/drivers/pwm/pwm-atmel.c
@@ -65,11 +65,16 @@ struct atmel_pwm_registers {
u8 duty_upd;
 };
 
+struct atmel_pwm_data {
+   struct atmel_pwm_registers regs;
+   struct pwm_caps caps;
+};
+
 struct atmel_pwm_chip {
struct pwm_chip chip;
struct clk *clk;
void __iomem *base;
-   const struct atmel_pwm_registers *regs;
+   const struct atmel_pwm_data *data;
 
unsigned int updated_pwms;
/* ISR is cleared when read, ensure only one thread does that */
@@ -150,15 +155,15 @@ static void atmel_pwm_update_cdty(struct pwm_chip *chip, 
struct pwm_device *pwm,
struct atmel_pwm_chip *atmel_pwm = to_atmel_pwm_chip(chip);
u32 val;
 
-   if (atmel_pwm->regs->duty_upd ==
-   atmel_pwm->regs->period_upd) {
+   if (atmel_pwm->data->regs.duty_upd ==
+   atmel_pwm->data->regs.period_upd) {
val = atmel_pwm_ch_readl(atmel_pwm, pwm->hwpwm, PWM_CMR);
val &= ~PWM_CMR_UPD_CDTY;
atmel_pwm_ch_writel(atmel_pwm, pwm->hwpwm, PWM_CMR, val);
}
 
atmel_pwm_ch_writel(atmel_pwm, pwm->hwpwm,
-   atmel_pwm->regs->duty_upd, cdty);
+   atmel_pwm->data->regs.duty_upd, cdty);
 }
 
 static void atmel_pwm_set_cprd_cdty(struct pwm_chip *chip,
@@ -168,9 +173,9 @@ static void atmel_pwm_set_cprd_cdty(struct pwm_chip *chip,
struct atmel_pwm_chip *atmel_pwm = to_atmel_pwm_chip(chip);
 
atmel_pwm_ch_writel(atmel_pwm, pwm->hwpwm,
-   atmel_pwm->regs->duty, cdty);
+   atmel_pwm->data->regs.duty, cdty);
atmel_pwm_ch_writel(atmel_pwm, pwm->hwpwm,
-   atmel_pwm->regs->period, cprd);
+   atmel_pwm->data->regs.period, cprd);
 }
 
 static void atmel_pwm_disable(struct pwm_chip *chip, struct pwm_device *pwm,
@@ -225,7 +230,7 @@ static int atmel_pwm_apply(struct pwm_chip *chip, struct 
pwm_device *pwm,
cstate.polarity == state->polarity &&
cstate.period == state->period) {
cprd = atmel_pwm_ch_readl(atmel_pwm, pwm->hwpwm,
- atmel_pwm->regs->period);
+ atmel_pwm->data->regs.period);
atmel_pwm_calculate_cdty(state, cprd, );
atmel_pwm_update_cdty(chip, pwm, cdty);
return 0;
@@ -272,32 +277,51 @@ static int atmel_pwm_apply(struct pwm_chip *chip, struct 
pwm_device *pwm,
return 0;
 }
 
+static void atmel_pwm_get_caps(struct pwm_chip *chip, struct pwm_device *pwm,
+  struct pwm_caps *caps)
+{
+   struct atmel_pwm_chip *atmel_pwm = to_atmel_pwm_chip(chip);
+
+   *caps = atmel_pwm->data->caps;
+}
+
 static const struct pwm_ops atmel_pwm_ops = {
.apply = atmel_pwm_apply,
+   .get_caps = atmel_pwm_get_caps,
.owner = THIS_MODULE,
 };
 
-static const struct atmel_pwm_registers atmel_pwm_regs_v1 = {
-   .period = PWMV1_CPRD,
-   .period_upd = PWMV1_CUPD,
-   .duty   = PWMV1_CDTY,
-   .duty_upd   = PWMV1_CUPD,
+static const struct atmel_pwm_data atmel_pwm_data_v1 = {
+   .regs = {
+   .period = PWMV1_CPRD,
+   .period_upd = PWMV1_CUPD,
+   .duty   = PWMV1_CDTY,
+   .duty_upd   = PWMV1_CUPD,
+   },
+   .caps = {
+   .modes = PWM_MODE(NORMAL),
+   },
 };
 
-static const struct atmel_pwm_registers atmel_pwm_regs_v2 = {
-   .period = PWMV2_CPRD,
-   .period_upd = PWMV2_CPRDUPD,
-   .duty   = PWMV2_CDTY,
-   .duty_upd   = PWMV2_CDTYUPD,
+static const struct atmel_pwm_data atmel_pwm_data_v2 = {
+   .regs = {
+   .period = PWMV2_CPRD,
+   .period_upd = PWMV2_CPRDUPD,
+   .duty   = PWMV2_CDTY,
+   .duty_upd   = PWMV2_CDTYUPD,
+   },
+   .caps = {
+   .modes = PWM_MODE(NORMAL) | PWM_MODE(COMPLEMENTARY),
+   },
 };
 
 static const struct platform_device_id atmel_pwm_devtypes[] = {
{
.name = "at91sam9rl-pwm",
-   .driver_data = (kernel_ulong_t)_pwm_regs_v1,
+   .driver_data = (kernel_ulong_t)_pwm_data_v1,
}, {
.name = "sama5d3-pwm",
-   .driver_data = (kernel_ulong_t)_pwm_regs_v2,
+   .driver_data = (kernel_ulong_t)_pwm_data_v2,
}, {