<div dir="ltr"><br><div class="gmail_extra"><br><div class="gmail_quote">On Thu, Oct 27, 2016 at 4:40 PM, Jaghathiswari Rankappagounder Natarajan <span dir="ltr"><<a href="mailto:jaghu@google.com" target="_blank">jaghu@google.com</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">Support to give all the common information required by all the PWM channels.<br>
<br></blockquote><div><br></div><div>This description doesn't help me understand what problem you are solving. From Section 2, Describe Your Changes, of <a href="https://www.kernel.org/doc/Documentation/SubmittingPatches">https://www.kernel.org/doc/Documentation/SubmittingPatches</a>: "Convince the reviewer that there is a problem worth fixing and that it makes sense for them to read past the first paragraph." I suggest reading that whole section.</div><div> </div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">
Signed-off-by: Jaghathiswari Rankappagounder Natarajan <<a href="mailto:jaghu@google.com">jaghu@google.com</a>><br>
---<br>
.../bindings/hwmon/aspeed_pwm_<wbr>controller.txt | 33 +++<br>
drivers/hwmon/Kconfig | 5 +<br>
drivers/hwmon/Makefile | 2 +-<br>
drivers/hwmon/aspeed_pwm.h | 159 ++++++++++++++<br>
drivers/hwmon/aspeed_pwm_<wbr>controller.c | 237 +++++++++++++++++++++<br>
5 files changed, 435 insertions(+), 1 deletion(-)<br>
create mode 100644 Documentation/devicetree/<wbr>bindings/hwmon/aspeed_pwm_<wbr>controller.txt<br>
create mode 100644 drivers/hwmon/aspeed_pwm.h<br>
create mode 100644 drivers/hwmon/aspeed_pwm_<wbr>controller.c<br>
<br>
diff --git a/Documentation/devicetree/<wbr>bindings/hwmon/aspeed_pwm_<wbr>controller.txt b/Documentation/devicetree/<wbr>bindings/hwmon/aspeed_pwm_<wbr>controller.txt<br>
new file mode 100644<br>
index 0000000..2b5c895<br>
--- /dev/null<br>
+++ b/Documentation/devicetree/<wbr>bindings/hwmon/aspeed_pwm_<wbr>controller.txt<br></blockquote><div><br></div><div>Per <a href="https://www.kernel.org/doc/Documentation/devicetree/bindings/submitting-patches.txt">https://www.kernel.org/doc/Documentation/devicetree/bindings/submitting-patches.txt</a>, the binding documentation updates should be a separate patch.</div><div> </div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">
@@ -0,0 +1,33 @@<br>
+Aspeed PWM controller driver<br>
</blockquote><div><br></div><div>You're implying that there is only one PWM controller they have _and_ _will_ ever use. Including AST2400/2500 in the description puts some reasonable bounds and directs people to the correct SoCs that will have documentation in their datasheets.</div><div> </div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">+<br>
+Required properties:<br>
+- reg : address and length of the register set for the device.<br>
+- #address-cells : should be 1.<br>
+- #size-cells : should be 1.<br>
+- compatible : should be "aspeed-pwm-controller".<br></blockquote><div><br></div><div>I thought the format was "<manufacturer>,<chip>-<device>" so "aspeed,ast2500-pwm"</div><div> </div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">
+- clock_enable : option to enable PWM and fan tach clock. should be 1.<br>
+- clock_source : option for clock source selection. 0 indicates 24MHz clock<br>
+ and 1 indicates MCLK.<br>
+- typem_pwm_clock : This array contains 3 values. The first value indicates<br>
+ the type M PWM clock division L bit. The second value indicates type M PWM<br>
+ clock divison H bit. The third value indicates type M PWM period bit.<br></blockquote><div><br></div><div>I have no idea what any of this means. What is type M clock division? How do I determine the L, H, and period bits?</div><div> </div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">
+<br>
+Optional properties:<br>
+- typen_pwm_clock : This array contains 3 values. The first value indicates<br>
+ the type N PWM clock division L bit. The second value indicates type N PWM<br>
+ clock division H bit. The third value indicates type N PWM period bit.<br>
+- typeo_pwm_clock : This array contains 3 values. The first value indicates<br>
+ the type O PWM clock division L bit. The second value indicates type O PWM<br>
+ clock divison H bit. The third value indicates type O PWM period bit.<br>
+<br>
+Examples:<br>
+<br>
+pwm_controller {<br>
+ #address-cells = <1>;<br>
+ #size-cells = <1>;<br>
+ reg = <0x1E786000 0x78>;<br>
+ compatible = "aspeed-pwm-controller";<br>
+ clock_enable = /bits/ 8 <0x01>;<br>
+ clock_source = /bits/ 8 <0x00>;<br>
+ typem_pwm_clock = <5 0 95>;<br>
+};<br>
diff --git a/drivers/hwmon/Kconfig b/drivers/hwmon/Kconfig<br>
index d4de8d5..59d6ea4 100644<br>
--- a/drivers/hwmon/Kconfig<br>
+++ b/drivers/hwmon/Kconfig<br>
@@ -1803,6 +1803,11 @@ config SENSORS_WM8350<br>
This driver can also be built as a module. If so, the module<br>
will be called wm8350-hwmon.<br>
<br>
+config ASPEED_PWM_CONTROLLER<br>
+ tristate "Aspeed PWM controller"<br>
+ help<br>
+ This driver provides support for ASPEED PWM controller.<br>
+<br>
config SENSORS_ULTRA45<br>
tristate "Sun Ultra45 PIC16F747"<br>
depends on SPARC64<br>
diff --git a/drivers/hwmon/Makefile b/drivers/hwmon/Makefile<br>
index 4455478..83156f8 100644<br>
--- a/drivers/hwmon/Makefile<br>
+++ b/drivers/hwmon/Makefile<br>
@@ -164,7 +164,7 @@ obj-$(CONFIG_SENSORS_<wbr>W83L785TS) += w83l785ts.o<br>
obj-$(CONFIG_SENSORS_<wbr>W83L786NG) += w83l786ng.o<br>
obj-$(CONFIG_SENSORS_WM831X) += wm831x-hwmon.o<br>
obj-$(CONFIG_SENSORS_WM8350) += wm8350-hwmon.o<br>
-<br>
+obj-$(CONFIG_ASPEED_PWM_<wbr>CONTROLLER) += aspeed_pwm_controller.o<br>
obj-$(CONFIG_PMBUS) += pmbus/<br>
<br>
ccflags-$(CONFIG_HWMON_DEBUG_<wbr>CHIP) := -DDEBUG<br>
diff --git a/drivers/hwmon/aspeed_pwm.h b/drivers/hwmon/aspeed_pwm.h<br>
new file mode 100644<br>
index 0000000..b3dd6b1<br>
--- /dev/null<br>
+++ b/drivers/hwmon/aspeed_pwm.h<br>
@@ -0,0 +1,159 @@<br>
+/*<br>
+ * Aspeed PWM header file<br>
+ * * Copyright (c) 2016 Google, Inc<br>
+ *<br>
+ * * This program is free software; you can redistribute it and/or modify<br>
+ * * it under the terms of the GNU General Public License version 2 as<br>
+ * * published by the Free Software Foundation.<br>
+ *<br>
+ */<br>
+<br>
+#ifndef __ASPEED_PWM_H<br>
+#define __ASPEED_PWM_H __FILE__<br>
+<br>
+/* AST PWM & FAN Register Definition */<br>
+#define AST_PTCR_CTRL 0x00<br>
+#define AST_PTCR_CLK_CTRL 0x04<br>
+#define AST_PTCR_DUTY0_CTRL 0x08<br>
+#define AST_PTCR_DUTY1_CTRL 0x0c<br>
+#define AST_PTCR_TYPEM_CTRL0 0x10<br>
+#define AST_PTCR_TYPEM_CTRL1 0x14<br>
+#define AST_PTCR_TYPEN_CTRL0 0x18<br>
+#define AST_PTCR_TYPEN_CTRL1 0x1c<br>
+#define AST_PTCR_TACH_SOURCE 0x20<br>
+#define AST_PTCR_TRIGGER 0x28<br>
+#define AST_PTCR_RESULT 0x2c<br>
+#define AST_PTCR_INTR_CTRL 0x30<br>
+#define AST_PTCR_INTR_STS 0x34<br>
+#define AST_PTCR_TYPEM_LIMIT 0x38<br>
+#define AST_PTCR_TYPEN_LIMIT 0x3C<br>
+#define AST_PTCR_CTRL_EXT 0x40<br>
+#define AST_PTCR_CLK_EXT_CTRL 0x44<br>
+#define AST_PTCR_DUTY2_CTRL 0x48<br>
+#define AST_PTCR_DUTY3_CTRL 0x4c<br>
+#define AST_PTCR_TYPEO_CTRL0 0x50<br>
+#define AST_PTCR_TYPEO_CTRL1 0x54<br>
+#define AST_PTCR_TACH_SOURCE_EXT 0x60<br>
+#define AST_PTCR_TYPEO_LIMIT 0x78<br>
+<br>
+/* COMMON Definition */<br>
+#define PWM_TYPE_M 0x0<br>
+#define PWM_TYPE_N 0x1<br>
+#define PWM_TYPE_O 0x2<br>
+<br>
+#define PWMA 0x0<br>
+#define PWMB 0x1<br>
+#define PWMC 0x2<br>
+#define PWMD 0x3<br>
+#define PWME 0x4<br>
+#define PWMF 0x5<br>
+#define PWMG 0x6<br>
+#define PWMH 0x7<br>
+<br>
+#define DUTY_CTRL_PWM2_FALL_POINT (24)<br>
+#define DUTY_CTRL_PWM2_FALL_POINT_MASK (0xff<<24)<br>
+#define DUTY_CTRL_PWM2_RISE_POINT (16)<br>
+#define DUTY_CTRL_PWM2_RISE_POINT_MASK (0xff<<16)<br>
+#define DUTY_CTRL_PWM1_FALL_POINT (8)<br>
+#define DUTY_CTRL_PWM1_FALL_POINT_MASK (0xff<<8)<br>
+#define DUTY_CTRL_PWM1_RISE_POINT (0)<br>
+#define DUTY_CTRL_PWM1_RISE_POINT_MASK (0xff)<br>
+<br>
+/* AST_PTCR_CTRL : 0x00 - General Control Register */<br>
+#define AST_PTCR_CTRL_SET_PWMD_TYPE(x) ((x & 0x1) << 15 | \<br>
+ (x & 0x2) << 6)<br>
+#define AST_PTCR_CTRL_GET_PWMD_TYPE(x) (((x & (0x1 << 7)) >> 6) | \<br>
+ ((x & (0x1 << 15)) >> 15))<br>
+#define AST_PTCR_CTRL_SET_PWMD_TYPE_<wbr>MASK ((0x1 << 7) | (0x1 << 15))<br>
+<br>
+#define AST_PTCR_CTRL_SET_PWMC_TYPE(x) ((x & 0x1) << 14 | \<br>
+ (x & 0x2) << 5)<br>
+#define AST_PTCR_CTRL_GET_PWMC_TYPE(x) (((x & (0x1 << 6)) >> 5) | \<br>
+ ((x & (0x1 << 14)) >> 14))<br>
+#define AST_PTCR_CTRL_SET_PWMC_TYPE_<wbr>MASK ((0x1 << 6) | (0x1 << 14))<br>
+<br>
+#define AST_PTCR_CTRL_SET_PWMB_TYPE(x) ((x & 0x1) << 13 | \<br>
+ (x & 0x2) << 4)<br>
+#define AST_PTCR_CTRL_GET_PWMB_TYPE(x) (((x & (0x1 << 5)) >> 4) | \<br>
+ ((x & (0x1 << 13)) >> 13))<br>
+#define AST_PTCR_CTRL_SET_PWMB_TYPE_<wbr>MASK ((0x1 << 5) | (0x1 << 13))<br>
+<br>
+#define AST_PTCR_CTRL_SET_PWMA_TYPE(x) ((x & 0x1) << 12 | \<br>
+ (x & 0x2) << 3)<br>
+#define AST_PTCR_CTRL_GET_PWMA_TYPE(x) (((x & (0x1 << 4)) >> 3) | \<br>
+ ((x & (0x1 << 12)) >> 12))<br>
+#define AST_PTCR_CTRL_SET_PWMA_TYPE_<wbr>MASK ((0x1 << 4) | (0x1 << 12))<br>
+<br>
+#define AST_PTCR_CTRL_PWMD (11)<br>
+#define AST_PTCR_CTRL_PWMD_EN (0x1 << 11)<br>
+#define AST_PTCR_CTRL_PWMC (10)<br>
+#define AST_PTCR_CTRL_PWMC_EN (0x1 << 10)<br>
+#define AST_PTCR_CTRL_PWMB (9)<br>
+#define AST_PTCR_CTRL_PWMB_EN (0x1 << 9)<br>
+#define AST_PTCR_CTRL_PWMA (8)<br>
+#define AST_PTCR_CTRL_PWMA_EN (0x1 << 8)<br>
+<br>
+/*0:24Mhz, 1:MCLK */<br>
+#define AST_PTCR_CTRL_CLK_SRC 0x2<br>
+#define AST_PTCR_CTRL_CLK_EN 0x1<br>
+<br>
+/* AST_PTCR_CLK_CTRL : 0x04 - Clock Control Register */<br>
+/* TYPE N */<br>
+#define AST_PTCR_CLK_CTRL_TYPEN_UNIT (24)<br>
+#define AST_PTCR_CLK_CTRL_TYPEN_UNIT_<wbr>MASK (0xff << 24)<br>
+#define AST_PTCR_CLK_CTRL_TYPEN_H (20)<br>
+#define AST_PTCR_CLK_CTRL_TYPEN_H_MASK (0xf << 20)<br>
+#define AST_PTCR_CLK_CTRL_TYPEN_L (16)<br>
+#define AST_PTCR_CLK_CTRL_TYPEN_L_MASK (0xf << 16)<br>
+/* TYPE M */<br>
+#define AST_PTCR_CLK_CTRL_TYPEM_UNIT (8)<br>
+#define AST_PTCR_CLK_CTRL_TYPEM_UNIT_<wbr>MASK (0xff << 8)<br>
+#define AST_PTCR_CLK_CTRL_TYPEM_H (4)<br>
+#define AST_PTCR_CLK_CTRL_TYPEM_H_MASK (0xf << 4)<br>
+#define AST_PTCR_CLK_CTRL_TYPEM_L (0)<br>
+#define AST_PTCR_CLK_CTRL_TYPEM_L_MASK (0xf)<br>
+<br>
+/* AST_PTCR_CTRL_EXT : 0x40 - General Control Extension #1 Register */<br>
+#define AST_PTCR_CTRL_SET_PWMH_TYPE(x) ((x & 0x1) << 15 | \<br>
+ (x & 0x2) << 6)<br>
+#define AST_PTCR_CTRL_GET_PWMH_TYPE(x) (((x & (0x1 << 7)) >> 6) | \<br>
+ ((x & (0x1 << 15)) >> 15))<br>
+#define AST_PTCR_CTRL_SET_PWMH_TYPE_<wbr>MASK ((0x1 << 7) | (0x1 << 15))<br>
+<br>
+#define AST_PTCR_CTRL_SET_PWMG_TYPE(x) ((x & 0x1) << 14 | \<br>
+ (x & 0x2) << 5)<br>
+#define AST_PTCR_CTRL_GET_PWMG_TYPE(x) (((x & (0x1 << 6)) >> 5) | \<br>
+ ((x & (0x1 << 14)) >> 14))<br>
+#define AST_PTCR_CTRL_SET_PWMG_TYPE_<wbr>MASK ((0x1 << 6) | (0x1 << 14))<br>
+<br>
+#define AST_PTCR_CTRL_SET_PWMF_TYPE(x) ((x & 0x1) << 13 | \<br>
+ (x & 0x2) << 4)<br>
+#define AST_PTCR_CTRL_GET_PWMF_TYPE(x) (((x & (0x1 << 5)) >> 4) | \<br>
+ ((x & (0x1 << 13)) >> 13))<br>
+#define AST_PTCR_CTRL_SET_PWMF_TYPE_<wbr>MASK ((0x1 << 5) | (0x1 << 13))<br>
+<br>
+#define AST_PTCR_CTRL_SET_PWME_TYPE(x) ((x & 0x1) << 12 | \<br>
+ (x & 0x2) << 3)<br>
+#define AST_PTCR_CTRL_GET_PWME_TYPE(x) (((x & (0x1 << 4)) >> 3) | \<br>
+ ((x & (0x1 << 12)) >> 12))<br>
+#define AST_PTCR_CTRL_SET_PWME_TYPE_<wbr>MASK ((0x1 << 4) | (0x1 << 12))<br>
+<br>
+#define AST_PTCR_CTRL_PWMH (11)<br>
+#define AST_PTCR_CTRL_PWMH_EN (0x1 << 11)<br>
+#define AST_PTCR_CTRL_PWMG (10)<br>
+#define AST_PTCR_CTRL_PWMG_EN (0x1 << 10)<br>
+#define AST_PTCR_CTRL_PWMF (9)<br>
+#define AST_PTCR_CTRL_PWMF_EN (0x1 << 9)<br>
+#define AST_PTCR_CTRL_PWME (8)<br>
+#define AST_PTCR_CTRL_PWME_EN (0x1 << 8)<br>
+<br>
+/* AST_PTCR_CLK_EXT_CTRL : 0x44 - Clock Control Extension #1 Register */<br>
+/* TYPE O */<br>
+#define AST_PTCR_CLK_CTRL_TYPEO_UNIT (8)<br>
+#define AST_PTCR_CLK_CTRL_TYPEO_UNIT_<wbr>MASK (0xff << 8)<br>
+#define AST_PTCR_CLK_CTRL_TYPEO_H (4)<br>
+#define AST_PTCR_CLK_CTRL_TYPEO_H_MASK (0xf << 4)<br>
+#define AST_PTCR_CLK_CTRL_TYPEO_L (0)<br>
+#define AST_PTCR_CLK_CTRL_TYPEO_L_MASK (0xf)<br>
+<br>
+#endif /* __ASPEED_PWM_H */<br>
diff --git a/drivers/hwmon/aspeed_pwm_<wbr>controller.c b/drivers/hwmon/aspeed_pwm_<wbr>controller.c<br>
new file mode 100644<br>
index 0000000..f846132<br>
--- /dev/null<br>
+++ b/drivers/hwmon/aspeed_pwm_<wbr>controller.c<br>
@@ -0,0 +1,237 @@<br>
+/*<br>
+ * Aspeed PWM controller driver<br>
+ * * Copyright (c) 2016 Google, Inc<br>
+ *<br>
+ * * This program is free software; you can redistribute it and/or modify<br>
+ * * it under the terms of the GNU General Public License version 2 as<br>
+ * * published by the Free Software Foundation.<br>
+ *<br>
+ */<br>
+<br>
+#include <linux/platform_device.h><br>
+#include <linux/kernel.h><br>
+#include <linux/module.h><br>
+#include <linux/of_platform.h><br>
+#include <linux/of_device.h><br>
+#include <linux/io.h><br>
+<br>
+#include "aspeed_pwm.h"<br>
+<br>
+struct ast_pwm_controller_data {<br>
+ void __iomem *base;<br>
+};<br>
+<br>
+static inline void<br>
+ast_pwm_controller_write(<wbr>struct ast_pwm_controller_data *priv, u32 val, u32 reg)<br>
+{<br>
+ writel(val, priv->base + reg);<br>
+}<br>
+<br>
+static inline u32<br>
+ast_pwm_controller_read(<wbr>struct ast_pwm_controller_data *priv, u32 reg)<br>
+{<br>
+ u32 val = readl(priv->base + reg);<br>
+ return val;<br>
+}<br>
+<br>
+static void<br>
+ast_set_pwm_clock_enable(<wbr>struct ast_pwm_controller_data *priv, u8 val)<br>
+{<br>
+ if (val) {<br>
+ ast_pwm_controller_write(priv,<br>
+ ast_pwm_controller_read(priv, AST_PTCR_CTRL) |<br>
+ AST_PTCR_CTRL_CLK_EN, AST_PTCR_CTRL);<br>
+ } else {<br>
+ ast_pwm_controller_write(priv,<br>
+ ast_pwm_controller_read(priv, AST_PTCR_CTRL) &<br>
+ ~AST_PTCR_CTRL_CLK_EN, AST_PTCR_CTRL);<br>
+ }<br>
+}<br>
+<br>
+static void<br>
+ast_set_pwm_clock_source(<wbr>struct ast_pwm_controller_data *priv, u8 val)<br>
+{<br>
+ if (val) {<br>
+ ast_pwm_controller_write(priv,<br>
+ ast_pwm_controller_read(priv, AST_PTCR_CTRL) |<br>
+ AST_PTCR_CTRL_CLK_SRC, AST_PTCR_CTRL);<br>
+ } else {<br>
+ ast_pwm_controller_write(priv,<br>
+ ast_pwm_controller_read(priv, AST_PTCR_CTRL) &<br>
+ ~AST_PTCR_CTRL_CLK_SRC, AST_PTCR_CTRL);<br>
+ }<br>
+}<br>
+<br>
+static void<br>
+ast_set_pwm_clock_division_h(<wbr>struct ast_pwm_controller_data *priv,<br>
+ u8 pwm_type, u8 div_high)<br>
+{<br>
+ switch (pwm_type) {<br>
+ case PWM_TYPE_M:<br>
+ ast_pwm_controller_write(priv,<br>
+ (ast_pwm_controller_read(priv, AST_PTCR_CLK_CTRL) &<br>
+ ~AST_PTCR_CLK_CTRL_TYPEM_H_<wbr>MASK) |<br>
+ (div_high << AST_PTCR_CLK_CTRL_TYPEM_H),<br>
+ AST_PTCR_CLK_CTRL);<br>
+ break;<br>
+ case PWM_TYPE_N:<br>
+ ast_pwm_controller_write(priv,<br>
+ (ast_pwm_controller_read(priv, AST_PTCR_CLK_CTRL) &<br>
+ ~AST_PTCR_CLK_CTRL_TYPEN_H_<wbr>MASK) |<br>
+ (div_high << AST_PTCR_CLK_CTRL_TYPEN_H),<br>
+ AST_PTCR_CLK_CTRL);<br>
+ break;<br>
+ case PWM_TYPE_O:<br>
+ ast_pwm_controller_write(priv,<br>
+ (ast_pwm_controller_read(priv, AST_PTCR_CLK_EXT_CTRL) &<br>
+ ~AST_PTCR_CLK_CTRL_TYPEO_H_<wbr>MASK) |<br>
+ (div_high << AST_PTCR_CLK_CTRL_TYPEO_H),<br>
+ AST_PTCR_CLK_EXT_CTRL);<br>
+ break;<br>
+ }<br>
+}<br>
+<br>
+static void<br>
+ast_set_pwm_clock_division_l(<wbr>struct ast_pwm_controller_data *priv,<br>
+ u8 pwm_type, u8 div_low)<br>
+{<br>
+ switch (pwm_type) {<br>
+ case PWM_TYPE_M:<br>
+ ast_pwm_controller_write(priv,<br>
+ (ast_pwm_controller_read(priv, AST_PTCR_CLK_CTRL) &<br>
+ ~AST_PTCR_CLK_CTRL_TYPEM_L_<wbr>MASK) |<br>
+ (div_low << AST_PTCR_CLK_CTRL_TYPEM_L),<br>
+ AST_PTCR_CLK_CTRL);<br>
+ break;<br>
+ case PWM_TYPE_N:<br>
+ ast_pwm_controller_write(priv,<br>
+ (ast_pwm_controller_read(priv, AST_PTCR_CLK_CTRL) &<br>
+ ~AST_PTCR_CLK_CTRL_TYPEN_L_<wbr>MASK) |<br>
+ (div_low << AST_PTCR_CLK_CTRL_TYPEN_L),<br>
+ AST_PTCR_CLK_CTRL);<br>
+ break;<br>
+ case PWM_TYPE_O:<br>
+ ast_pwm_controller_write(priv,<br>
+ (ast_pwm_controller_read(priv, AST_PTCR_CLK_EXT_CTRL) &<br>
+ ~AST_PTCR_CLK_CTRL_TYPEO_L_<wbr>MASK) |<br>
+ (div_low << AST_PTCR_CLK_CTRL_TYPEO_L),<br>
+ AST_PTCR_CLK_EXT_CTRL);<br>
+ break;<br>
+ }<br>
+}<br>
+<br>
+static void<br>
+ast_set_pwm_clock_unit(struct ast_pwm_controller_data *priv, u8 pwm_type,<br>
+ u8 unit)<br>
+{<br>
+ switch (pwm_type) {<br>
+ case PWM_TYPE_M:<br>
+ ast_pwm_controller_write(priv,<br>
+ (ast_pwm_controller_read(priv, AST_PTCR_CLK_CTRL) &<br>
+ ~AST_PTCR_CLK_CTRL_TYPEM_UNIT_<wbr>MASK) |<br>
+ (unit << AST_PTCR_CLK_CTRL_TYPEM_UNIT),<br>
+ AST_PTCR_CLK_CTRL);<br>
+ break;<br>
+ case PWM_TYPE_N:<br>
+ ast_pwm_controller_write(priv,<br>
+ (ast_pwm_controller_read(priv, AST_PTCR_CLK_CTRL) &<br>
+ ~AST_PTCR_CLK_CTRL_TYPEN_UNIT_<wbr>MASK) |<br>
+ (unit << AST_PTCR_CLK_CTRL_TYPEN_UNIT),<br>
+ AST_PTCR_CLK_CTRL);<br>
+ break;<br>
+ case PWM_TYPE_O:<br>
+ ast_pwm_controller_write(priv,<br>
+ (ast_pwm_controller_read(priv, AST_PTCR_CLK_EXT_CTRL) &<br>
+ ~AST_PTCR_CLK_CTRL_TYPEO_UNIT_<wbr>MASK) |<br>
+ (unit << AST_PTCR_CLK_CTRL_TYPEO_UNIT),<br>
+ AST_PTCR_CLK_EXT_CTRL);<br>
+ break;<br>
+ }<br>
+}<br>
+<br>
+static int<br>
+aspeed_pwm_controller_probe(<wbr>struct platform_device *pdev)<br>
+{<br>
+ u32 buf[3];<br>
+ int err;<br>
+ struct device_node *np;<br>
+ struct resource *res;<br>
+ u8 val;<br>
+ struct ast_pwm_controller_data *priv;<br>
+<br>
+ np = pdev->dev.of_node;<br>
+<br>
+ priv = devm_kzalloc(&pdev->dev, sizeof(*priv), GFP_KERNEL);<br>
+ if (!priv)<br>
+ return -ENOMEM;<br>
+<br>
+ res = platform_get_resource(pdev, IORESOURCE_MEM, 0);<br>
+<br>
+ priv->base = devm_ioremap(&pdev->dev, res->start, resource_size(res));<br>
+ if (!priv->base)<br>
+ return -ENOMEM;<br>
+<br>
+ err = of_property_read_u8(np, "clock_enable", &val);<br>
+ if (!err) {<br>
+ ast_set_pwm_clock_enable(priv, val);<br>
+ } else {<br>
+ return err;<br>
+ }<br>
+ err = of_property_read_u8(np, "clock_source", &val);<br>
+ if (!err) {<br>
+ ast_set_pwm_clock_source(priv, val);<br>
+ } else {<br>
+ return err;<br>
+ }<br>
+<br>
+ err = of_property_read_u32_array(np, "typem_pwm_clock", buf, 3);<br>
+ if (!err) {<br>
+ ast_set_pwm_clock_division_l(<wbr>priv, PWM_TYPE_M, buf[0]);<br>
+ ast_set_pwm_clock_division_h(<wbr>priv, PWM_TYPE_M, buf[1]);<br>
+ ast_set_pwm_clock_unit(priv, PWM_TYPE_M, buf[2]);<br>
+ }<br>
+<br>
+ err = of_property_read_u32_array(np, "typen_pwm_clock", buf, 3);<br>
+ if (!err) {<br>
+ ast_set_pwm_clock_division_l(<wbr>priv, PWM_TYPE_N, buf[0]);<br>
+ ast_set_pwm_clock_division_h(<wbr>priv, PWM_TYPE_N, buf[1]);<br>
+ ast_set_pwm_clock_unit(priv, PWM_TYPE_N, buf[2]);<br>
+ }<br>
+<br>
+ err = of_property_read_u32_array(np, "typeo_pwm_clock", buf, 3);<br>
+ if (!err) {<br>
+ ast_set_pwm_clock_division_l(<wbr>priv, PWM_TYPE_O, buf[0]);<br>
+ ast_set_pwm_clock_division_h(<wbr>priv, PWM_TYPE_O, buf[1]);<br>
+ ast_set_pwm_clock_unit(priv, PWM_TYPE_O, buf[2]);<br>
+ }<br>
+<br>
+ return 0;<br>
+}<br>
+<br>
+static int<br>
+aspeed_pwm_controller_remove(<wbr>struct platform_device *pdev)<br>
+{<br>
+ return 0;<br>
+}<br>
+<br>
+static const struct of_device_id of_pwm_controller_match_table[<wbr>] = {<br>
+ { .compatible = "aspeed-pwm-controller", },<br>
+ {},<br>
+};<br>
+MODULE_DEVICE_TABLE(of, of_pwm_controller_match_table)<wbr>;<br>
+<br>
+static struct platform_driver aspeed_pwm_controller_driver = {<br>
+ .probe = aspeed_pwm_controller_probe,<br>
+ .remove = aspeed_pwm_controller_remove,<br>
+ .driver = {<br>
+ .name = "aspeed_pwm_controller",<br>
+ .owner = THIS_MODULE,<br>
+ .of_match_table = of_pwm_controller_match_table,<br>
+ },<br>
+};<br>
+<br>
+module_platform_driver(<wbr>aspeed_pwm_controller_driver);<br>
+<br>
+MODULE_AUTHOR("Jaghathiswari Rankappagounder Natarajan <<a href="mailto:jaghu@google.com">jaghu@google.com</a>>");<br>
+MODULE_DESCRIPTION("ASPEED PWM controller driver");<br>
+MODULE_LICENSE("GPL");<br>
--<br>
2.8.0.rc3.226.g39d4020<br>
<br>
______________________________<wbr>_________________<br>
openbmc mailing list<br>
<a href="mailto:openbmc@lists.ozlabs.org">openbmc@lists.ozlabs.org</a><br>
<a href="https://lists.ozlabs.org/listinfo/openbmc" rel="noreferrer" target="_blank">https://lists.ozlabs.org/<wbr>listinfo/openbmc</a><br>
</blockquote></div><br></div></div>