From: Siarhei Volkau <lis8...@gmail.com> This patch introduce the sun6i PWM driver itself: - sun6i channels register and field map, - sun6i prescaler table, - DT bindings for A31 SoC, - documentation update.
Signed-off-by: Siarhei Volkau <lis8...@gmail.com> --- .../devicetree/bindings/pwm/pwm-sun4i.txt | 3 +- drivers/pwm/pwm-sun4i.c | 95 +++++++++++++++++++++- 2 files changed, 95 insertions(+), 3 deletions(-) diff --git a/Documentation/devicetree/bindings/pwm/pwm-sun4i.txt b/Documentation/devicetree/bindings/pwm/pwm-sun4i.txt index f1cbeef..109b997 100644 --- a/Documentation/devicetree/bindings/pwm/pwm-sun4i.txt +++ b/Documentation/devicetree/bindings/pwm/pwm-sun4i.txt @@ -1,10 +1,11 @@ -Allwinner sun4i and sun7i SoC PWM controller +Allwinner sunxi SoC PWM controller Required properties: - compatible: should be one of: - "allwinner,sun4i-a10-pwm" - "allwinner,sun5i-a10s-pwm" - "allwinner,sun5i-a13-pwm" + - "allwinner,sun6i-a31-pwm" - "allwinner,sun7i-a20-pwm" - "allwinner,sun8i-h3-pwm" - reg: physical base address and length of the controller's registers diff --git a/drivers/pwm/pwm-sun4i.c b/drivers/pwm/pwm-sun4i.c index a179a53..e474303 100644 --- a/drivers/pwm/pwm-sun4i.c +++ b/drivers/pwm/pwm-sun4i.c @@ -1,7 +1,8 @@ /* - * Driver for Allwinner sun4i Pulse Width Modulation Controller + * Driver for Allwinner sunxi Pulse Width Modulation Controller * * Copyright (C) 2014 Alexandre Belloni <alexandre.bell...@free-electrons.com> + * Copyright (C) 2017 Siarhei Volkau <lis8...@gmail.com> * * Licensed under GPLv2. */ @@ -48,6 +49,12 @@ #define SUNXI_MAX_PWM_CHANNELS 4 +#define SUN6I_PWMCH_OFFS 0x10 +#define SUN6I_CH_CTL_OFFS 0x0 +#define SUN6I_CH_PRD_OFFS 0x4 +#define SUN6I_PWM_CTL_REG(ch) (SUN6I_PWMCH_OFFS * (ch) + SUN6I_CH_CTL_OFFS) +#define SUN6I_PWM_PRD_REG(ch) (SUN6I_PWMCH_OFFS * (ch) + SUN6I_CH_PRD_OFFS) + /* regmap fields */ enum { /* Used bit fields in control register */ @@ -79,6 +86,25 @@ static const u32 sun4i_prescaler_table[] = { 0, /* Actually 1 but tested separately */ }; +static const u32 sun6i_prescaler_table[] = { + 1, + 2, + 4, + 8, + 16, + 32, + 64, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, +}; + struct sunxi_pwmch_data { unsigned int ctl_reg; unsigned int prd_reg; @@ -339,6 +365,54 @@ static const struct sunxi_pwmch_data sun4i_pwm_chan1_data = { }, }; +static const struct sunxi_pwmch_data sun6i_pwm_chan0_data = { + .ctl_reg = SUN6I_PWM_CTL_REG(0), + .prd_reg = SUN6I_PWM_PRD_REG(0), + .enable_bits = PWM_EN | PWM_CLK_GATING, + .fields = { + [FIELD_PRESCALER] = REG_FIELD(SUN6I_PWM_CTL_REG(0), 0, 3), + [FIELD_POLARITY] = REG_FIELD(SUN6I_PWM_CTL_REG(0), 5, 5), + [FIELD_CLK_GATING] = REG_FIELD(SUN6I_PWM_CTL_REG(0), 6, 6), + [FIELD_READY] = REG_FIELD(SUN6I_PWM_CTL_REG(0), 28, 28), + }, +}; + +static const struct sunxi_pwmch_data sun6i_pwm_chan1_data = { + .ctl_reg = SUN6I_PWM_CTL_REG(1), + .prd_reg = SUN6I_PWM_PRD_REG(1), + .enable_bits = PWM_EN | PWM_CLK_GATING, + .fields = { + [FIELD_PRESCALER] = REG_FIELD(SUN6I_PWM_CTL_REG(1), 0, 3), + [FIELD_POLARITY] = REG_FIELD(SUN6I_PWM_CTL_REG(1), 5, 5), + [FIELD_CLK_GATING] = REG_FIELD(SUN6I_PWM_CTL_REG(1), 6, 6), + [FIELD_READY] = REG_FIELD(SUN6I_PWM_CTL_REG(1), 28, 28), + }, +}; + +static const struct sunxi_pwmch_data sun6i_pwm_chan2_data = { + .ctl_reg = SUN6I_PWM_CTL_REG(2), + .prd_reg = SUN6I_PWM_PRD_REG(2), + .enable_bits = PWM_EN | PWM_CLK_GATING, + .fields = { + [FIELD_PRESCALER] = REG_FIELD(SUN6I_PWM_CTL_REG(2), 0, 3), + [FIELD_POLARITY] = REG_FIELD(SUN6I_PWM_CTL_REG(2), 5, 5), + [FIELD_CLK_GATING] = REG_FIELD(SUN6I_PWM_CTL_REG(2), 6, 6), + [FIELD_READY] = REG_FIELD(SUN6I_PWM_CTL_REG(2), 28, 28), + }, +}; + +static const struct sunxi_pwmch_data sun6i_pwm_chan3_data = { + .ctl_reg = SUN6I_PWM_CTL_REG(3), + .prd_reg = SUN6I_PWM_PRD_REG(3), + .enable_bits = PWM_EN | PWM_CLK_GATING, + .fields = { + [FIELD_PRESCALER] = REG_FIELD(SUN6I_PWM_CTL_REG(3), 0, 3), + [FIELD_POLARITY] = REG_FIELD(SUN6I_PWM_CTL_REG(3), 5, 5), + [FIELD_CLK_GATING] = REG_FIELD(SUN6I_PWM_CTL_REG(3), 6, 6), + [FIELD_READY] = REG_FIELD(SUN6I_PWM_CTL_REG(3), 28, 28), + }, +}; + static const struct sun4i_pwm_data sun4i_pwm_data_a10 = { .has_prescaler_bypass = false, .has_rdy = false, @@ -371,6 +445,19 @@ static const struct sun4i_pwm_data sun4i_pwm_data_a13 = { } }; +static const struct sun4i_pwm_data sun6i_pwm_data_a31 = { + .has_prescaler_bypass = false, + .has_rdy = true, + .npwm = 4, + .prescaler_table = sun6i_prescaler_table, + .chan_data = { + &sun6i_pwm_chan0_data, + &sun6i_pwm_chan1_data, + &sun6i_pwm_chan2_data, + &sun6i_pwm_chan3_data, + } +}; + static const struct sun4i_pwm_data sun4i_pwm_data_a20 = { .has_prescaler_bypass = true, .has_rdy = true, @@ -403,6 +490,9 @@ static const struct of_device_id sun4i_pwm_dt_ids[] = { .compatible = "allwinner,sun5i-a13-pwm", .data = &sun4i_pwm_data_a13, }, { + .compatible = "allwinner,sun6i-a31-pwm", + .data = &sun6i_pwm_data_a31, + }, { .compatible = "allwinner,sun7i-a20-pwm", .data = &sun4i_pwm_data_a20, }, { @@ -544,5 +634,6 @@ module_platform_driver(sun4i_pwm_driver); MODULE_ALIAS("platform:sun4i-pwm"); MODULE_AUTHOR("Alexandre Belloni <alexandre.bell...@free-electrons.com>"); -MODULE_DESCRIPTION("Allwinner sun4i PWM driver"); +MODULE_AUTHOR("Siarhei Volkau <lis8...@gmail.com>"); +MODULE_DESCRIPTION("Allwinner sunxi PWM driver"); MODULE_LICENSE("GPL v2"); -- 2.4.11 -- You received this message because you are subscribed to the Google Groups "linux-sunxi" group. To unsubscribe from this group and stop receiving emails from it, send an email to linux-sunxi+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/d/optout.