Add support for nuvoton ma35d1 pwm controller
Subsystems (3)
v3 cover Add support for nuvoton ma35d1 pwm controller
This patch series adds pwm driver for the nuvoton ma35d1 ARMv8 SoC. It includes DT binding documentation and the ma35d1 pwm driver.
v3:
- Update nuvoton,ma35d1-pwm.yaml
- Add maintainers entry
- Increse "#pwm-cells" to 3
- Update ma35d1 pwm driver
- Make include header and macros definitions organized alphabetically
- Rename macros REG_PWM_XXXX to MA35D1_REG_PWM_XXXX
- Add macros for register address
v2 resend:
- Remove wrong 'Reviewed-by' tags.
v2:
- Update nuvoton,ma35d1-pwm.yaml
- Fix 'maxItems' of 'reg' to 1.
- Remove unused label
- Update ma35d1 pwm driver
- Remove MODULE_ALIAS()
- Add chip->atomic = true
Chi-Wen Weng (2):
Add dt-bindings for Nuvoton MA35D1 SoC PWM controller.
pwm: Add Nuvoton MA35D1 PWM controller support
.../bindings/pwm/nuvoton,ma35d1-pwm.yaml | 45 +++++ drivers/pwm/Kconfig | 9 + drivers/pwm/Makefile | 1 + drivers/pwm/pwm-ma35d1.c | 179 ++++++++++++++++++ 4 files changed, 234 insertions(+) create mode 100644 Documentation/devicetree/bindings/pwm/nuvoton,ma35d1-pwm.yaml create mode 100644 drivers/pwm/pwm-ma35d1.c
Signature · 1 line
2.25.1
PATCH v3 1/2 dt-bindings: pwm: nuvoton: Add MA35D1 pwm
Add dt-bindings for Nuvoton MA35D1 SoC PWM controller.
--- .../bindings/pwm/nuvoton,ma35d1-pwm.yaml | 45 +++++++++++++++++++ 1 file changed, 45 insertions(+) create mode 100644 Documentation/devicetree/bindings/pwm/nuvoton,ma35d1-pwm.yaml
Documentation/devicetree/bindings/pwm/nuvoton,ma35d1-pwm.yaml new file +45 -0
@@ -0,0 +1,45 @@ +# SPDX-License-Identifier: GPL-2.0-only OR BSD-2-Clause +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/pwm/nuvoton,ma35d1-pwm.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: Nuvoton MA35D1 PWM controller + +maintainers: + - Chi-Wen Weng <[email protected]> + +allOf: + - $ref: pwm.yaml# + +properties: + compatible: + enum: + - nuvoton,ma35d1-pwm + + reg: + maxItems: 1 + + clocks: + maxItems: 1 + + "#pwm-cells": + const: 3 + +required: + - compatible + - reg + - clocks + +additionalProperties: false + +examples: + - | + #include <dt-bindings/clock/nuvoton,ma35d1-clk.h> + + pwm@40580000 { + compatible = "nuvoton,ma35d1-pwm"; + reg = <0x40580000 0x400>; + clocks = <&clk EPWM0_GATE>; + #pwm-cells = <3>; + };
Signature · 1 line
2.25.1
PATCH v3 2/2 pwm: Add Nuvoton MA35D1 PWM controller support
In reply to Chi-Wen WengThis commit adds a generic PWM framework driver for Nuvoton MA35D1 PWM controller.
--- drivers/pwm/Kconfig | 9 ++ drivers/pwm/Makefile | 1 + drivers/pwm/pwm-ma35d1.c | 179 +++++++++++++++++++++++++++++++++++++++ 3 files changed, 189 insertions(+) create mode 100644 drivers/pwm/pwm-ma35d1.c
drivers/pwm/Kconfig +9 -0
@@ -411,6 +411,15 @@ config PWM_LPSS_PLATFORM To compile this driver as a module, choose M here: the module will be called pwm-lpss-platform. +config PWM_MA35D1 + tristate "Nuvoton MA35D1 PWM support" + depends on ARCH_MA35 || COMPILE_TEST + help + Generic PWM framework driver for Nuvoton MA35D1. + + To compile this driver as a module, choose M here: the module + will be called pwm-ma35d1. + config PWM_MESON tristate "Amlogic Meson PWM driver" depends on ARCH_MESON || COMPILE_TEST
drivers/pwm/Makefile +1 -0
@@ -36,6 +36,7 @@ obj-$(CONFIG_PWM_LPC32XX) += pwm-lpc32xx.o obj-$(CONFIG_PWM_LPSS) += pwm-lpss.o obj-$(CONFIG_PWM_LPSS_PCI) += pwm-lpss-pci.o obj-$(CONFIG_PWM_LPSS_PLATFORM) += pwm-lpss-platform.o +obj-$(CONFIG_PWM_MA35D1) += pwm-ma35d1.o obj-$(CONFIG_PWM_MESON) += pwm-meson.o obj-$(CONFIG_PWM_MEDIATEK) += pwm-mediatek.o obj-$(CONFIG_PWM_MICROCHIP_CORE) += pwm-microchip-core.o
drivers/pwm/pwm-ma35d1.c new file +179 -0
179 lines not on this page · raw message
Signature · 1 line
2.25.1
Re: [PATCH v3 2/2] pwm: Add Nuvoton MA35D1 PWM controller support
Quoted 3 lines · Chi-Wen Weng
This commit adds a generic PWM framework driver for Nuvoton MA35D1 PWM controller.
Signed-off-by Chi-Wen Weng <[email protected]>
Uwe Kleine-König
maintainerRe: [PATCH v3 2/2] pwm: Add Nuvoton MA35D1 PWM controller support
In reply to Chi-Wen WengHello,
drivers/pwm/pwm-ma35d1.c line 6
Quoted 13 lines · Chi-Wen Weng
[...]
drivers/pwm/pwm-ma35d1.c new file +6
-0@@ -0,0 +1,179 @@ +// SPDX-License-Identifier: GPL-2.0 +/* +* Driver for the Nuvoton MA35D1 PWM controller +* +* Copyright (C) 2024 Nuvoton Corporation +* Chi-Wen Weng <[email protected]>
Please add some information here about the hardware. The idea is to get some info about the device's capabilities. Please stick to the format that many other drivers are using such that
sed -rn '/Limitations:/,/\*\/?$/p' drivers/pwm/pwm-ma35d1.c
emits the info for your driver. Things to mention are: possible glitches during .apply(); behaviour of the pin when the PWM is disabled (constant signal? High-Z?)
Also a link to a reference manual would be awesome.
Quoted 18 lines
drivers/pwm/pwm-ma35d1.c new file +18
-0+*/ + +#include <linux/clk.h> +#include <linux/io.h> +#include <linux/math64.h> +#include <linux/mod_devicetable.h> +#include <linux/module.h> +#include <linux/platform_device.h> +#include <linux/pwm.h> + +/* The following are registers address offset for MA35D1 PWM controller */ +#define MA35D1_REG_PWM_CTL0 (0x00) +#define MA35D1_REG_PWM_CNTEN (0x20) +#define MA35D1_REG_PWM_PERIOD0 (0x30) +#define MA35D1_REG_PWM_CMPDAT0 (0x50) +#define MA35D1_REG_PWM_WGCTL0 (0xB0) +#define MA35D1_REG_PWM_POLCTL (0xD4) +#define MA35D1_REG_PWM_POEN (0xD8)
drivers/pwm/pwm-ma35d1.c line 34
Quoted 10 lines
drivers/pwm/pwm-ma35d1.c new file +10
-0+ +/* The following are register address of MA35D1 PWM controller */ +#define MA35D1_PWM_CH_REG_SIZE 4 +#define MA35D1_PWM_CMPDAT0_ADDR (base, ch) ((base) + MA35D1_REG_PWM_CMPDAT0 + \ + ((ch) * MA35D1_PWM_CH_REG_SIZE)) +#define MA35D1_PWM_CNTEN_ADDR (base) ((base) + MA35D1_REG_PWM_CNTEN) +#define MA35D1_PWM_PERIOD0_ADDR (base, ch) ((base) + MA35D1_REG_PWM_PERIOD0 + \ + ((ch) * MA35D1_PWM_CH_REG_SIZE)) +#define MA35D1_PWM_POEN_ADDR (base) ((base) + MA35D1_REG_PWM_POEN) +#define MA35D1_PWM_POLCTL_ADDR (base) ((base) + MA35D1_REG_PWM_POLCTL)
I would drop the base part in these defines and add them to the above list sorted by address.
So something like:
#define MA35D1_REG_PWM_CTL0 0x00
#define MA35D1_REG_PWM_CNTEN 0x20
#define MA35D1_REG_PWM_PERIOD(ch) (0x30 + 4 * (ch))
#define MA35D1_REG_PWM_CMPDAT(ch) (0x50 + 4 * (ch))
#define MA35D1_REG_PWM_WGCTL0 0xB0
#define MA35D1_REG_PWM_POLCTL 0xD4
#define MA35D1_REG_PWM_POEN 0xD8
To make up for the missing base, I'd create wrappers for readl and writel à la:
static u32 nuvoton_pwm_readl(struct nuvoton_pwm *nvtpwm, unsigned int offset); static void nuvoton_pwm_writel(struct nuvoton_pwm *nvtpwm, unsigned int offset, u32 value);
As you see I wouldn't use a define for 4, because IMHO that hurts readability. But I don't feel strong here.
drivers/pwm/pwm-ma35d1.c line 37
Quoted 2 lines
drivers/pwm/pwm-ma35d1.c new file +2
-0+#define MA35D1_PWM_MAX_COUNT 0xFFFF +#define MA35D1_PWM_TOTAL_CHANNELS 6
s/TOTAL/NUM/
drivers/pwm/pwm-ma35d1.c line 41
Quoted 4 lines
drivers/pwm/pwm-ma35d1.c new file +4
-0+ +struct nuvoton_pwm { +void __iomem *base; +u64 clkrate;
clk_get_rate() returns an unsigned long value. Please stick to that for .clkrate as there is no use to double the size of this struct on 32-bit platforms just to store zeros and padding.
drivers/pwm/pwm-ma35d1.c line 47
Quoted 6 lines
drivers/pwm/pwm-ma35d1.c new file +6
-0+}; + +static inline struct nuvoton_pwm *to_nuvoton_pwm (struct pwm_chip *chip) +{ +return pwmchip_get_drvdata (chip); +}
I slightly prefer nuvoton_pwm_from_chip() for this function's name to have the same function prefix for all functions here.
Quoted 21 lines
drivers/pwm/pwm-ma35d1.c new file +21
-0+ +static int nuvoton_pwm_apply (struct pwm_chip *chip,struct pwm_device *pwm, +const struct pwm_state *state) +{ +struct nuvoton_pwm *nvtpwm; +u32 ch = pwm->hwpwm; + + nvtpwm =to_nuvoton_pwm (chip); +if (state->enabled) { +u64 duty_cycles, period_cycles; + +/* Calculate the duty and period cycles */ + duty_cycles =mul_u64_u64_div_u64 (nvtpwm->clkrate, + state->duty_cycle,NSEC_PER_SEC ); +if (duty_cycles >MA35D1_PWM_MAX_COUNT ) + duty_cycles =MA35D1_PWM_MAX_COUNT ; + + period_cycles =mul_u64_u64_div_u64 (nvtpwm->clkrate, + state->period,NSEC_PER_SEC ); +if (period_cycles >MA35D1_PWM_MAX_COUNT ) + period_cycles =MA35D1_PWM_MAX_COUNT ;
drivers/pwm/pwm-ma35d1.c line 78
Quoted 10 lines
drivers/pwm/pwm-ma35d1.c new file +10
-0+ +/* Write the duty and period cycles to registers */ +writel (duty_cycles,MA35D1_PWM_CMPDAT0_ADDR (nvtpwm->base, ch)); +writel (period_cycles,MA35D1_PWM_PERIOD0_ADDR (nvtpwm->base, ch)); +/* Enable counter */ +writel (readl (MA35D1_PWM_CNTEN_ADDR (nvtpwm->base)) |BIT (ch), +MA35D1_PWM_CNTEN_ADDR (nvtpwm->base)); +/* Enable output */ +writel (readl (MA35D1_PWM_POEN_ADDR (nvtpwm->base)) |BIT (ch), +MA35D1_PWM_POEN_ADDR (nvtpwm->base));
Can this result in glitches? E.g. is it possible to see a waveform with the old period_cycles but the new duty_cycles output? If you switch polarity, do you see the new settings with the wrong polarity for some time? Setup polarity before enabling the counter and output? Maybe only enable the counter when the output is enabled to be sure to emit the first edge with the correct timing?
drivers/pwm/pwm-ma35d1.c line 85
Quoted 7 lines
drivers/pwm/pwm-ma35d1.c new file +7
-0+ }else { +/* Disable counter */ +writel (readl (MA35D1_PWM_CNTEN_ADDR (nvtpwm->base)) & ~BIT (ch), +MA35D1_PWM_CNTEN_ADDR (nvtpwm->base)); +/* Disable output */ +writel (readl (MA35D1_PWM_POEN_ADDR (nvtpwm->base)) & ~BIT (ch), +MA35D1_PWM_POEN_ADDR (nvtpwm->base));
Maybe add another wrapper for this kind of rmw operation. Also I suggest to introduce a name for BIT(ch) here such that this can become:
nuvoton_pwm_rmw(nvtpwm, MA35D1_REG_PWM_POEN, MA35D1_REG_PWM_POEN_EN(ch), 0);
(Assuming "EN0" is the name of the bit for channel 0 in MA35D1_REG_PWM_POEN.)
drivers/pwm/pwm-ma35d1.c line 94
Quoted 9 lines
drivers/pwm/pwm-ma35d1.c new file +9
-0+ } + +/* Set polarity state to register */ +if (state->polarity ==PWM_POLARITY_NORMAL ) +writel (readl (MA35D1_PWM_POLCTL_ADDR (nvtpwm->base)) & ~BIT (ch), +MA35D1_PWM_POLCTL_ADDR (nvtpwm->base)); +else +writel (readl (MA35D1_PWM_POLCTL_ADDR (nvtpwm->base)) |BIT (ch), +MA35D1_PWM_POLCTL_ADDR (nvtpwm->base));
You can skip setting up period if !state->enabled.
Quoted 15 lines
drivers/pwm/pwm-ma35d1.c new file +14
-0+return 0 ; +} + + +static int nuvoton_pwm_probe (struct platform_device *pdev) +{ +struct pwm_chip *chip; +struct nuvoton_pwm *nvtpwm; +struct clk *clk; +int ret; + + chip =devm_pwmchip_alloc (&pdev->dev,MA35D1_PWM_TOTAL_CHANNELS ,sizeof (*nvtpwm)); +if (IS_ERR (chip)) +return PTR_ERR (chip);
drivers/pwm/pwm-ma35d1.c line 146
Quoted 10 lines
drivers/pwm/pwm-ma35d1.c new file +10
-0+ + nvtpwm =to_nuvoton_pwm (chip); + + nvtpwm->base =devm_platform_ioremap_resource (pdev,0 ); +if (IS_ERR (nvtpwm->base)) +return PTR_ERR (nvtpwm->base); + + clk =devm_clk_get_enabled (&pdev->dev,NULL ); +if (IS_ERR (clk)) +return dev_err_probe (&pdev->dev,PTR_ERR (clk),"unable to get the clock" );
Please start all error messages with a capital letter and end them with \n.
devm_clk_rate_exclusive_get(&pdev->dev, clk) here please.
drivers/pwm/pwm-ma35d1.c line 150
Quoted 4 lines
drivers/pwm/pwm-ma35d1.c new file +4
-0+ + nvtpwm->clkrate =clk_get_rate (clk); +if (nvtpwm->clkrate >NSEC_PER_SEC ) +return dev_err_probe (&pdev->dev, -EINVAL ,"pwm clock out of range" );
return dev_err_probe(&pdev->dev, -EINVAL, "PWM clock out of range (%lu)\n", nvtpwm->clkrate);
drivers/pwm/pwm-ma35d1.c line 160
Quoted 10 lines
drivers/pwm/pwm-ma35d1.c new file +10
-0+ + chip->ops = &nuvoton_pwm_ops; + chip->atomic = true; + + ret =devm_pwmchip_add (&pdev->dev, chip); +if (ret <0 ) +return dev_err_probe (&pdev->dev, ret,"unable to add pwm chip" ); + +return 0 ; +}
Best regards
Uwe
Re: [PATCH v3 2/2] pwm: Add Nuvoton MA35D1 PWM controller support
Hi Uwe,
Thanks for your reply.
Quoted 20 lines · Uwe Kleine-König
Hello,
drivers/pwm/pwm-ma35d1.c line 6
Quoted 13 lines · Chi-Wen Weng
[...]
drivers/pwm/pwm-ma35d1.c new file +6
-0@@ -0,0 +1,179 @@ +// SPDX-License-Identifier: GPL-2.0 +/* +* Driver for the Nuvoton MA35D1 PWM controller +* +* Copyright (C) 2024 Nuvoton Corporation +* Chi-Wen Weng <[email protected]> Please add some information here about the hardware. The idea is to get some info about the device's capabilities. Please stick to the format that many other drivers are using such that
Quoted 7 lines
sed -rn '/Limitations:/,/\*\/?$/p' drivers/pwm/pwm-ma35d1.cemits the info for your driver. Things to mention are: possible glitches during .apply(); behaviour of the pin when the PWM is disabled (constant signal? High-Z?)
Also a link to a reference manual would be awesome.
Okay, I will add the information into driver.
Quoted 41 lines
Quoted 18 lines
drivers/pwm/pwm-ma35d1.c new file +18
-0+*/ + +#include <linux/clk.h> +#include <linux/io.h> +#include <linux/math64.h> +#include <linux/mod_devicetable.h> +#include <linux/module.h> +#include <linux/platform_device.h> +#include <linux/pwm.h> + +/* The following are registers address offset for MA35D1 PWM controller */ +#define MA35D1_REG_PWM_CTL0 (0x00) +#define MA35D1_REG_PWM_CNTEN (0x20) +#define MA35D1_REG_PWM_PERIOD0 (0x30) +#define MA35D1_REG_PWM_CMPDAT0 (0x50) +#define MA35D1_REG_PWM_WGCTL0 (0xB0) +#define MA35D1_REG_PWM_POLCTL (0xD4) +#define MA35D1_REG_PWM_POEN (0xD8)drivers/pwm/pwm-ma35d1.c line 34
Quoted 10 lines
drivers/pwm/pwm-ma35d1.c new file +10
-0+ +/* The following are register address of MA35D1 PWM controller */ +#define MA35D1_PWM_CH_REG_SIZE 4 +#define MA35D1_PWM_CMPDAT0_ADDR (base, ch) ((base) + MA35D1_REG_PWM_CMPDAT0 + \ + ((ch) * MA35D1_PWM_CH_REG_SIZE)) +#define MA35D1_PWM_CNTEN_ADDR (base) ((base) + MA35D1_REG_PWM_CNTEN) +#define MA35D1_PWM_PERIOD0_ADDR (base, ch) ((base) + MA35D1_REG_PWM_PERIOD0 + \ + ((ch) * MA35D1_PWM_CH_REG_SIZE)) +#define MA35D1_PWM_POEN_ADDR (base) ((base) + MA35D1_REG_PWM_POEN) +#define MA35D1_PWM_POLCTL_ADDR (base) ((base) + MA35D1_REG_PWM_POLCTL)I would drop the base part in these defines and add them to the above list sorted by address.
So something like:
#define
MA35D1_REG_PWM_CTL00x00
#defineMA35D1_REG_PWM_CNTEN0x20
#defineMA35D1_REG_PWM_PERIOD(ch)(0x30+ 4 * (ch))
#defineMA35D1_REG_PWM_CMPDAT(ch)(0x50+ 4 * (ch))
#defineMA35D1_REG_PWM_WGCTL00xB0
#defineMA35D1_REG_PWM_POLCTL0xD4
#defineMA35D1_REG_PWM_POEN0xD8
Quoted 8 lines
To make up for the missing base, I'd create wrappers for readl and writel à la:
static u32 nuvoton_pwm_readl(struct nuvoton_pwm *nvtpwm, unsigned int offset); static void nuvoton_pwm_writel(struct nuvoton_pwm *nvtpwm, unsigned int offset, u32 value);As you see I wouldn't use a define for 4, because IMHO that hurts readability. But I don't feel strong here.
It really can let my driver more readable. Thanks.
Quoted 4 lines
drivers/pwm/pwm-ma35d1.c line 37
Quoted 3 lines
drivers/pwm/pwm-ma35d1.c new file +2
-0+#define MA35D1_PWM_MAX_COUNT 0xFFFF +#define MA35D1_PWM_TOTAL_CHANNELS 6s/TOTAL/NUM/
Okay, I will modify it in next version.
Quoted 7 lines
drivers/pwm/pwm-ma35d1.c line 41
Quoted 4 lines
drivers/pwm/pwm-ma35d1.c new file +4
-0+ +struct nuvoton_pwm { +void __iomem *base; +u64 clkrate;
clk_get_rate()returns an unsigned long value. Please stick to that for .clkrate as there is no use to double the size of this struct on 32-bit platforms just to store zeros and padding.
Okay, I will modify it in next version.
Quoted 8 lines
drivers/pwm/pwm-ma35d1.c line 47
Quoted 6 lines
drivers/pwm/pwm-ma35d1.c new file +6
-0+}; + +static inline struct nuvoton_pwm *to_nuvoton_pwm (struct pwm_chip *chip) +{ +return pwmchip_get_drvdata (chip); +}I slightly prefer
nuvoton_pwm_from_chip()for this function's name to have the same function prefix for all functions here.
Okay, I will modify it in next version.
Quoted 29 lines
Quoted 29 lines
drivers/pwm/pwm-ma35d1.c new file +29
-0+ +static int nuvoton_pwm_apply (struct pwm_chip *chip,struct pwm_device *pwm, +const struct pwm_state *state) +{ +struct nuvoton_pwm *nvtpwm; +u32 ch = pwm->hwpwm; + + nvtpwm =to_nuvoton_pwm (chip); +if (state->enabled) { +u64 duty_cycles, period_cycles; + +/* Calculate the duty and period cycles */ + duty_cycles =mul_u64_u64_div_u64 (nvtpwm->clkrate, + state->duty_cycle,NSEC_PER_SEC ); +if (duty_cycles >MA35D1_PWM_MAX_COUNT ) + duty_cycles =MA35D1_PWM_MAX_COUNT ; + + period_cycles =mul_u64_u64_div_u64 (nvtpwm->clkrate, + state->period,NSEC_PER_SEC ); +if (period_cycles >MA35D1_PWM_MAX_COUNT ) + period_cycles =MA35D1_PWM_MAX_COUNT ; + +/* Write the duty and period cycles to registers */ +writel (duty_cycles,MA35D1_PWM_CMPDAT0_ADDR (nvtpwm->base, ch)); +writel (period_cycles,MA35D1_PWM_PERIOD0_ADDR (nvtpwm->base, ch)); +/* Enable counter */ +writel (readl (MA35D1_PWM_CNTEN_ADDR (nvtpwm->base)) |BIT (ch), +MA35D1_PWM_CNTEN_ADDR (nvtpwm->base)); +/* Enable output */
Quoted 8 lines
drivers/pwm/pwm-ma35d1.c line 77
Quoted 2 lines
drivers/pwm/pwm-ma35d1.c new file +2
-0+writel (readl (MA35D1_PWM_POEN_ADDR (nvtpwm->base)) |BIT (ch), +MA35D1_PWM_POEN_ADDR (nvtpwm->base));Can this result in glitches? E.g. is it possible to see a waveform with the old
period_cyclesbut the newduty_cyclesoutput? If you switch polarity, do you see the new settings with the wrong polarity for some time? Setup polarity before enabling the counter and output? Maybe only enable the counter when the output is enabled to be sure to emit the first edge with the correct timing?
Yes, enable counter should be after the output is enabled. Will fix in next version.
Quoted 10 lines
drivers/pwm/pwm-ma35d1.c line 85
Quoted 7 lines
drivers/pwm/pwm-ma35d1.c new file +7
-0+ }else { +/* Disable counter */ +writel (readl (MA35D1_PWM_CNTEN_ADDR (nvtpwm->base)) & ~BIT (ch), +MA35D1_PWM_CNTEN_ADDR (nvtpwm->base)); +/* Disable output */ +writel (readl (MA35D1_PWM_POEN_ADDR (nvtpwm->base)) & ~BIT (ch), +MA35D1_PWM_POEN_ADDR (nvtpwm->base));Maybe add another wrapper for this kind of rmw operation. Also I suggest to introduce a name for BIT(ch) here such that this can become:
Quoted 4 lines
nuvoton_pwm_rmw(nvtpwm, MA35D1_REG_PWM_POEN, MA35D1_REG_PWM_POEN_EN(ch), 0);(Assuming "EN0" is the name of the bit for channel 0 in
MA35D1_REG_PWM_POEN.)
Okay, I will modify it next version.
Quoted 10 lines
drivers/pwm/pwm-ma35d1.c line 94
Quoted 9 lines
drivers/pwm/pwm-ma35d1.c new file +9
-0+ } + +/* Set polarity state to register */ +if (state->polarity ==PWM_POLARITY_NORMAL ) +writel (readl (MA35D1_PWM_POLCTL_ADDR (nvtpwm->base)) & ~BIT (ch), +MA35D1_PWM_POLCTL_ADDR (nvtpwm->base)); +else +writel (readl (MA35D1_PWM_POLCTL_ADDR (nvtpwm->base)) |BIT (ch), +MA35D1_PWM_POLCTL_ADDR (nvtpwm->base));You can skip setting up period if !state->enabled.
Yes, it should be skip if !state->enabled.
Quoted 28 lines
Quoted 15 lines
drivers/pwm/pwm-ma35d1.c new file +14
-0+return 0 ; +} + + +static int nuvoton_pwm_probe (struct platform_device *pdev) +{ +struct pwm_chip *chip; +struct nuvoton_pwm *nvtpwm; +struct clk *clk; +int ret; + + chip =devm_pwmchip_alloc (&pdev->dev,MA35D1_PWM_TOTAL_CHANNELS ,sizeof (*nvtpwm)); +if (IS_ERR (chip)) +return PTR_ERR (chip);drivers/pwm/pwm-ma35d1.c line 146
Quoted 10 lines
drivers/pwm/pwm-ma35d1.c new file +10
-0+ + nvtpwm =to_nuvoton_pwm (chip); + + nvtpwm->base =devm_platform_ioremap_resource (pdev,0 ); +if (IS_ERR (nvtpwm->base)) +return PTR_ERR (nvtpwm->base); + + clk =devm_clk_get_enabled (&pdev->dev,NULL ); +if (IS_ERR (clk)) +return dev_err_probe (&pdev->dev,PTR_ERR (clk),"unable to get the clock" );Please start all error messages with a capital letter and end them with \n.
Quoted 1 line
devm_clk_rate_exclusive_get(&pdev->dev, clk)here please.
Okay, I will modify it in next version.
Quoted 5 lines
drivers/pwm/pwm-ma35d1.c line 150
Quoted 4 lines
drivers/pwm/pwm-ma35d1.c new file +4
-0+ + nvtpwm->clkrate =clk_get_rate (clk); +if (nvtpwm->clkrate >NSEC_PER_SEC ) +return dev_err_probe (&pdev->dev, -EINVAL ,"pwm clock out of range" );return dev_err_probe(&pdev->dev, -EINVAL, "PWM clock out of range (%lu)\n", nvtpwm->clkrate);
Okay, I will modify it in next version.
Quoted 4 lines
Quoted 4 lines
drivers/pwm/pwm-ma35d1.c new file +4
-0+ + chip->ops = &nuvoton_pwm_ops; + chip->atomic = true; +
Quoted 8 lines
drivers/pwm/pwm-ma35d1.c line 160
Quoted 6 lines
drivers/pwm/pwm-ma35d1.c new file +6
-0+ ret =devm_pwmchip_add (&pdev->dev, chip); +if (ret <0 ) +return dev_err_probe (&pdev->dev, ret,"unable to add pwm chip" ); + +return 0 ; +}Best regards
Uwe
Thanks.
Chi-Wen Weng