Re: [PATCH v2 5/7] counter: add FlexTimer Module Quadrature decoder counter driver

2019-03-11 Thread Patrick Havelange
On Thu, Mar 7, 2019 at 12:32 PM William Breathitt Gray
 wrote:
> > +/*
> > + * take mutex
> > + * call ftm_clear_write_protection
> > + * update settings
> > + * call ftm_set_write_protection
> > + * release mutex
> > + */
>
> Jonathan mentioned it before in the previous review, and I think I agree
> too, that this comment block is superfluous: the context of this code is
> simple enough that the function call order is naturally obvious (i.e.
> write protection must be cleared before settings are modified).
>
> The only important thing to mention here is that the mutex must be held
> before the write protection state is modified so a comment along the
> following lines should suffice:
>
> /* hold mutex before modifying write protection state */

I think that keeping the more verbose comments is better. You directly see
what operations are needed, and is a good reminder, especially if you
are not familiar with the driver.
I'll use your comment on the next version if you insist (see below for
why new versoion).

> > +static void ftm_quaddec_disable(struct ftm_quaddec *ftm)
> > +{
> > + ftm_write(ftm, FTM_MODE, 0);
> > +}
>
> The ftm_quaddec_disable function is only used for cleanup when the
> driver is being removed. Is disabling the FTM counter on removal
> actually something we need to do?

It might provide some power-saving, so I would keep that function.

>
> While it's true that the register will keep updating, since the driver
> is no longer loaded, we don't care about that register value. Once we
> take control of the hardware again (by reloading our driver or via a new
> one), we reinitialize the counter and set the count value back to 0
> anyway -- so whatever value the register had no longer matters.
>
Indeed the previous values at start do not matter. It's there just to
shut down the device properly.
This discussion made me verify again the specs and in its current form
the disable doesn't even work at all :
 - That register should be written with write protection disabled (duh!)
 - It doesn't even stop the FTM from running, the clock must be
disabled for that.

So I'll probably provide a fix for that (in some days/weeks).

> > +
> > +enum ftm_quaddec_count_function {
> > + FTM_QUADDEC_COUNT_ENCODER_MODE_1,
> > +};
>
> The FlexTimer Module supports more than just a quadrature counter mode
> doesn't it?
>
> We should keep this initial patch simple since we are still introducing
> the Counter subsystem, but it'll be nice to add support in the future
> for the other counter modes such as single-edge capture.

yes it provides more features, those are in a backlog ;). I would
prefer if this simple version(I mean, with the disable/shutdown fixed)
of the driver could be merged already before extending support.

>
> > +
> > +static struct counter_signal ftm_quaddec_signals[] = {
> > + {
> > + .id = 0,
> > + .name = "Channel 1 Quadrature A"
> > + },
> > + {
> > + .id = 1,
> > + .name = "Channel 1 Quadrature B"
> > + }
> > +};
>
> If possible, these names should match the FTM datasheet naming
> convention. The reason is to make it easier for users to match the
> input signals described in the datasheet with the Signal data provided
> by the Generic Counter interface.
>
> I think the FTM datasheet describes these signals as "Phase A" and
> "Phase B", so perhaps "Channel 1 Phase A" and "Channel 1 Phase B" may be
> more appropriate names in this case.

I'll verify those,

> > +static int ftm_quaddec_remove(struct platform_device *pdev)
> > +{
> > + struct ftm_quaddec *ftm = platform_get_drvdata(pdev);
> > +
> > + counter_unregister(>counter);
> > +
> > + ftm_quaddec_disable(ftm);
> > +
> > + return 0;
> > +}
>
> If the ftm_quaddec_disable is not necessary, then we can eliminate the
> ftm_quaddec_remove function as well by replacing the counter_register
> call with a devm_counter_register call.

yes, but as stated before, I would keep it for potential energy saving.

Thanks for your feedback :)


[PATCH v2 7/7] LS1021A: dtsi: add ftm quad decoder entries

2019-03-06 Thread Patrick Havelange
Add the 4 Quadrature counters for this board.

Signed-off-by: Patrick Havelange 
Reviewed-by: Esben Haabendal 
---
Changes v2
 - None
---
 arch/arm/boot/dts/ls1021a.dtsi | 28 
 1 file changed, 28 insertions(+)

diff --git a/arch/arm/boot/dts/ls1021a.dtsi b/arch/arm/boot/dts/ls1021a.dtsi
index ed0941292172..0168fb62590a 100644
--- a/arch/arm/boot/dts/ls1021a.dtsi
+++ b/arch/arm/boot/dts/ls1021a.dtsi
@@ -433,6 +433,34 @@
status = "disabled";
};
 
+   counter0: counter@29d {
+   compatible = "fsl,ftm-quaddec";
+   reg = <0x0 0x29d 0x0 0x1>;
+   big-endian;
+   status = "disabled";
+   };
+
+   counter1: counter@29e {
+   compatible = "fsl,ftm-quaddec";
+   reg = <0x0 0x29e 0x0 0x1>;
+   big-endian;
+   status = "disabled";
+   };
+
+   counter2: counter@29f {
+   compatible = "fsl,ftm-quaddec";
+   reg = <0x0 0x29f 0x0 0x1>;
+   big-endian;
+   status = "disabled";
+   };
+
+   counter3: counter@2a0 {
+   compatible = "fsl,ftm-quaddec";
+   reg = <0x0 0x2a0 0x0 0x1>;
+   big-endian;
+   status = "disabled";
+   };
+
gpio0: gpio@230 {
compatible = "fsl,ls1021a-gpio", "fsl,qoriq-gpio";
reg = <0x0 0x230 0x0 0x1>;
-- 
2.19.1



[PATCH v2 6/7] counter: ftm-quaddec: Documentation: Add specific counter sysfs documentation

2019-03-06 Thread Patrick Havelange
This adds documentation for the specific prescaler entry.

Signed-off-by: Patrick Havelange 
---
Changes v2
 - Add doc for prescaler entry
---
 .../ABI/testing/sysfs-bus-counter-ftm-quaddec| 16 
 1 file changed, 16 insertions(+)
 create mode 100644 Documentation/ABI/testing/sysfs-bus-counter-ftm-quaddec

diff --git a/Documentation/ABI/testing/sysfs-bus-counter-ftm-quaddec 
b/Documentation/ABI/testing/sysfs-bus-counter-ftm-quaddec
new file mode 100644
index ..2da629d6d485
--- /dev/null
+++ b/Documentation/ABI/testing/sysfs-bus-counter-ftm-quaddec
@@ -0,0 +1,16 @@
+What:  /sys/bus/counter/devices/counterX/countY/prescaler_available
+KernelVersion: 5.1
+Contact:   linux-...@vger.kernel.org
+Description:
+   Discrete set of available values for the respective Count Y
+   configuration are listed in this file. Values are delimited by
+   newline characters.
+
+What:  /sys/bus/counter/devices/counterX/countY/prescaler
+KernelVersion: 5.1
+Contact:   linux-...@vger.kernel.org
+Description:
+   Configure the prescaler value associated with Count Y.
+   On the FlexTimer, the counter clock source passes through a
+   prescaler that is a 7-bit counter. This acts like a clock
+   divider.
-- 
2.19.1



[PATCH v2 5/7] counter: add FlexTimer Module Quadrature decoder counter driver

2019-03-06 Thread Patrick Havelange
This driver exposes the counter for the quadrature decoder of the
FlexTimer Module, present in the LS1021A soc.

Signed-off-by: Patrick Havelange 
---
Changes v2
 - Rebased on new counter subsystem
 - Cleaned up included headers
 - Use devm_ioremap()
 - Correct order of devm_ and unmanaged resources
---
 drivers/counter/Kconfig   |   9 +
 drivers/counter/Makefile  |   1 +
 drivers/counter/ftm-quaddec.c | 356 ++
 3 files changed, 366 insertions(+)
 create mode 100644 drivers/counter/ftm-quaddec.c

diff --git a/drivers/counter/Kconfig b/drivers/counter/Kconfig
index 87c491a19c63..233ac305d878 100644
--- a/drivers/counter/Kconfig
+++ b/drivers/counter/Kconfig
@@ -48,4 +48,13 @@ config STM32_LPTIMER_CNT
  To compile this driver as a module, choose M here: the
  module will be called stm32-lptimer-cnt.
 
+config FTM_QUADDEC
+   tristate "Flex Timer Module Quadrature decoder driver"
+   help
+ Select this option to enable the Flex Timer Quadrature decoder
+ driver.
+
+ To compile this driver as a module, choose M here: the
+ module will be called ftm-quaddec.
+
 endif # COUNTER
diff --git a/drivers/counter/Makefile b/drivers/counter/Makefile
index 5589976d37f8..0c9e622a6bea 100644
--- a/drivers/counter/Makefile
+++ b/drivers/counter/Makefile
@@ -7,3 +7,4 @@ obj-$(CONFIG_COUNTER) += counter.o
 obj-$(CONFIG_104_QUAD_8)   += 104-quad-8.o
 obj-$(CONFIG_STM32_TIMER_CNT)  += stm32-timer-cnt.o
 obj-$(CONFIG_STM32_LPTIMER_CNT)+= stm32-lptimer-cnt.o
+obj-$(CONFIG_FTM_QUADDEC)  += ftm-quaddec.o
diff --git a/drivers/counter/ftm-quaddec.c b/drivers/counter/ftm-quaddec.c
new file mode 100644
index ..1bc9e075a386
--- /dev/null
+++ b/drivers/counter/ftm-quaddec.c
@@ -0,0 +1,356 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Flex Timer Module Quadrature decoder
+ *
+ * This module implements a driver for decoding the FTM quadrature
+ * of ex. a LS1021A
+ */
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+struct ftm_quaddec {
+   struct counter_device counter;
+   struct platform_device *pdev;
+   void __iomem *ftm_base;
+   bool big_endian;
+   struct mutex ftm_quaddec_mutex;
+};
+
+static void ftm_read(struct ftm_quaddec *ftm, uint32_t offset, uint32_t *data)
+{
+   if (ftm->big_endian)
+   *data = ioread32be(ftm->ftm_base + offset);
+   else
+   *data = ioread32(ftm->ftm_base + offset);
+}
+
+static void ftm_write(struct ftm_quaddec *ftm, uint32_t offset, uint32_t data)
+{
+   if (ftm->big_endian)
+   iowrite32be(data, ftm->ftm_base + offset);
+   else
+   iowrite32(data, ftm->ftm_base + offset);
+}
+
+/*
+ * take mutex
+ * call ftm_clear_write_protection
+ * update settings
+ * call ftm_set_write_protection
+ * release mutex
+ */
+static void ftm_clear_write_protection(struct ftm_quaddec *ftm)
+{
+   uint32_t flag;
+
+   /* First see if it is enabled */
+   ftm_read(ftm, FTM_FMS, );
+
+   if (flag & FTM_FMS_WPEN) {
+   ftm_read(ftm, FTM_MODE, );
+   ftm_write(ftm, FTM_MODE, flag | FTM_MODE_WPDIS);
+   }
+}
+
+static void ftm_set_write_protection(struct ftm_quaddec *ftm)
+{
+   ftm_write(ftm, FTM_FMS, FTM_FMS_WPEN);
+}
+
+static void ftm_reset_counter(struct ftm_quaddec *ftm)
+{
+   /* Reset hardware counter to CNTIN */
+   ftm_write(ftm, FTM_CNT, 0x0);
+}
+
+static void ftm_quaddec_init(struct ftm_quaddec *ftm)
+{
+   ftm_clear_write_protection(ftm);
+
+   /*
+* Do not write in the region from the CNTIN register through the
+* PWMLOAD register when FTMEN = 0.
+*/
+   ftm_write(ftm, FTM_MODE, FTM_MODE_FTMEN);
+   ftm_write(ftm, FTM_CNTIN, 0x);
+   ftm_write(ftm, FTM_MOD, 0x);
+   ftm_write(ftm, FTM_CNT, 0x0);
+   ftm_write(ftm, FTM_SC, FTM_SC_PS_1);
+
+   /* Select quad mode */
+   ftm_write(ftm, FTM_QDCTRL, FTM_QDCTRL_QUADEN);
+
+   /* Unused features and reset to default section */
+   ftm_write(ftm, FTM_POL, 0x0);
+   ftm_write(ftm, FTM_FLTCTRL, 0x0);
+   ftm_write(ftm, FTM_SYNCONF, 0x0);
+   ftm_write(ftm, FTM_SYNC, 0x);
+
+   /* Lock the FTM */
+   ftm_set_write_protection(ftm);
+}
+
+static void ftm_quaddec_disable(struct ftm_quaddec *ftm)
+{
+   ftm_write(ftm, FTM_MODE, 0);
+}
+
+static int ftm_quaddec_get_prescaler(struct counter_device *counter,
+struct counter_count *count,
+size_t *cnt_mode)
+{
+   struct ftm_quaddec *ftm = counter->priv;
+   uint32_t scflags;
+
+   ftm_read(ftm, FTM_SC, );
+
+   *cnt_mode = scflags & FTM_SC_PS_MASK;
+
+   return 0;
+}
+
+static int ftm_quaddec_set_prescaler(struct counter_device *counter,
+

[PATCH v2 4/7] dt-bindings: counter: ftm-quaddec

2019-03-06 Thread Patrick Havelange
FlexTimer quadrature decoder driver.

Signed-off-by: Patrick Havelange 
Reviewed-by: Esben Haabendal 
---
Changes v2
 - None
---
 .../bindings/counter/ftm-quaddec.txt   | 18 ++
 1 file changed, 18 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/counter/ftm-quaddec.txt

diff --git a/Documentation/devicetree/bindings/counter/ftm-quaddec.txt 
b/Documentation/devicetree/bindings/counter/ftm-quaddec.txt
new file mode 100644
index ..4d18cd722074
--- /dev/null
+++ b/Documentation/devicetree/bindings/counter/ftm-quaddec.txt
@@ -0,0 +1,18 @@
+FlexTimer Quadrature decoder counter
+
+This driver exposes a simple counter for the quadrature decoder mode.
+
+Required properties:
+- compatible:  Must be "fsl,ftm-quaddec".
+- reg: Must be set to the memory region of the flextimer.
+
+Optional property:
+- big-endian:  Access the device registers in big-endian mode.
+
+Example:
+   counter0: counter@29d {
+   compatible = "fsl,ftm-quaddec";
+   reg = <0x0 0x29d 0x0 0x1>;
+   big-endian;
+   status = "disabled";
+   };
-- 
2.19.1



[PATCH v2 3/7] drivers/clocksource: timer-fsl-ftm: use common header for FlexTimer #defines

2019-03-06 Thread Patrick Havelange
Common #defines have been moved to "linux/fsl/ftm.h". Thus making use of
this file.
Also FTM_SC_CLK_SHIFT has been renamed to FTM_SC_CLK_MASK_SHIFT.

Signed-off-by: Patrick Havelange 
Reviewed-by: Esben Haabendal 
---
Changes v2
 - None
---
 drivers/clocksource/timer-fsl-ftm.c | 15 ++-
 1 file changed, 2 insertions(+), 13 deletions(-)

diff --git a/drivers/clocksource/timer-fsl-ftm.c 
b/drivers/clocksource/timer-fsl-ftm.c
index 846d18daf893..e1c34b2f53a5 100644
--- a/drivers/clocksource/timer-fsl-ftm.c
+++ b/drivers/clocksource/timer-fsl-ftm.c
@@ -19,20 +19,9 @@
 #include 
 #include 
 #include 
+#include 
 
-#define FTM_SC 0x00
-#define FTM_SC_CLK_SHIFT   3
-#define FTM_SC_CLK_MASK(0x3 << FTM_SC_CLK_SHIFT)
-#define FTM_SC_CLK(c)  ((c) << FTM_SC_CLK_SHIFT)
-#define FTM_SC_PS_MASK 0x7
-#define FTM_SC_TOIEBIT(6)
-#define FTM_SC_TOF BIT(7)
-
-#define FTM_CNT0x04
-#define FTM_MOD0x08
-#define FTM_CNTIN  0x4C
-
-#define FTM_PS_MAX 7
+#define FTM_SC_CLK(c)  ((c) << FTM_SC_CLK_MASK_SHIFT)
 
 struct ftm_clock_device {
void __iomem *clksrc_base;
-- 
2.19.1



[PATCH v2 2/7] drivers/pwm: pwm-fsl-ftm: use common header for FlexTimer #defines

2019-03-06 Thread Patrick Havelange
This also fixes the wrong value for the previously defined
FTM_MODE_INIT macro (it was not used).

Signed-off-by: Patrick Havelange 
Reviewed-by: Esben Haabendal 
---
Changes v2
 - None
---
 drivers/pwm/pwm-fsl-ftm.c | 44 +--
 1 file changed, 1 insertion(+), 43 deletions(-)

diff --git a/drivers/pwm/pwm-fsl-ftm.c b/drivers/pwm/pwm-fsl-ftm.c
index 883378d055c6..f21ea1b97116 100644
--- a/drivers/pwm/pwm-fsl-ftm.c
+++ b/drivers/pwm/pwm-fsl-ftm.c
@@ -22,51 +22,9 @@
 #include 
 #include 
 #include 
+#include 
 
-#define FTM_SC 0x00
-#define FTM_SC_CLK_MASK_SHIFT  3
-#define FTM_SC_CLK_MASK(3 << FTM_SC_CLK_MASK_SHIFT)
 #define FTM_SC_CLK(c)  (((c) + 1) << FTM_SC_CLK_MASK_SHIFT)
-#define FTM_SC_PS_MASK 0x7
-
-#define FTM_CNT0x04
-#define FTM_MOD0x08
-
-#define FTM_CSC_BASE   0x0C
-#define FTM_CSC_MSBBIT(5)
-#define FTM_CSC_MSABIT(4)
-#define FTM_CSC_ELSB   BIT(3)
-#define FTM_CSC_ELSA   BIT(2)
-#define FTM_CSC(_channel)  (FTM_CSC_BASE + ((_channel) * 8))
-
-#define FTM_CV_BASE0x10
-#define FTM_CV(_channel)   (FTM_CV_BASE + ((_channel) * 8))
-
-#define FTM_CNTIN  0x4C
-#define FTM_STATUS 0x50
-
-#define FTM_MODE   0x54
-#define FTM_MODE_FTMEN BIT(0)
-#define FTM_MODE_INIT  BIT(2)
-#define FTM_MODE_PWMSYNC   BIT(3)
-
-#define FTM_SYNC   0x58
-#define FTM_OUTINIT0x5C
-#define FTM_OUTMASK0x60
-#define FTM_COMBINE0x64
-#define FTM_DEADTIME   0x68
-#define FTM_EXTTRIG0x6C
-#define FTM_POL0x70
-#define FTM_FMS0x74
-#define FTM_FILTER 0x78
-#define FTM_FLTCTRL0x7C
-#define FTM_QDCTRL 0x80
-#define FTM_CONF   0x84
-#define FTM_FLTPOL 0x88
-#define FTM_SYNCONF0x8C
-#define FTM_INVCTRL0x90
-#define FTM_SWOCTRL0x94
-#define FTM_PWMLOAD0x98
 
 enum fsl_pwm_clk {
FSL_PWM_CLK_SYS,
-- 
2.19.1



[PATCH v2 1/7] include/fsl: add common FlexTimer #defines in a separate header.

2019-03-06 Thread Patrick Havelange
Several files are/will be using the same #defines to use the Flextimer
module. Regroup them in a common file.

Signed-off-by: Patrick Havelange 
Reviewed-by: Esben Haabendal 
---
Changes v2
 - Commit message
---
 include/linux/fsl/ftm.h | 88 +
 1 file changed, 88 insertions(+)
 create mode 100644 include/linux/fsl/ftm.h

diff --git a/include/linux/fsl/ftm.h b/include/linux/fsl/ftm.h
new file mode 100644
index ..d59011acf66c
--- /dev/null
+++ b/include/linux/fsl/ftm.h
@@ -0,0 +1,88 @@
+// SPDX-License-Identifier: GPL-2.0
+#ifndef __FSL_FTM_H__
+#define __FSL_FTM_H__
+
+#define FTM_SC   0x0 /* Status And Control */
+#define FTM_CNT  0x4 /* Counter */
+#define FTM_MOD  0x8 /* Modulo */
+
+#define FTM_CNTIN0x4C /* Counter Initial Value */
+#define FTM_STATUS   0x50 /* Capture And Compare Status */
+#define FTM_MODE 0x54 /* Features Mode Selection */
+#define FTM_SYNC 0x58 /* Synchronization */
+#define FTM_OUTINIT  0x5C /* Initial State For Channels Output */
+#define FTM_OUTMASK  0x60 /* Output Mask */
+#define FTM_COMBINE  0x64 /* Function For Linked Channels */
+#define FTM_DEADTIME 0x68 /* Deadtime Insertion Control */
+#define FTM_EXTTRIG  0x6C /* FTM External Trigger */
+#define FTM_POL  0x70 /* Channels Polarity */
+#define FTM_FMS  0x74 /* Fault Mode Status */
+#define FTM_FILTER   0x78 /* Input Capture Filter Control */
+#define FTM_FLTCTRL  0x7C /* Fault Control */
+#define FTM_QDCTRL   0x80 /* Quadrature Decoder Control And Status */
+#define FTM_CONF 0x84 /* Configuration */
+#define FTM_FLTPOL   0x88 /* FTM Fault Input Polarity */
+#define FTM_SYNCONF  0x8C /* Synchronization Configuration */
+#define FTM_INVCTRL  0x90 /* FTM Inverting Control */
+#define FTM_SWOCTRL  0x94 /* FTM Software Output Control */
+#define FTM_PWMLOAD  0x98 /* FTM PWM Load */
+
+#define FTM_SC_CLK_MASK_SHIFT  3
+#define FTM_SC_CLK_MASK(3 << FTM_SC_CLK_MASK_SHIFT)
+#define FTM_SC_TOF 0x80
+#define FTM_SC_TOIE0x40
+#define FTM_SC_CPWMS   0x20
+#define FTM_SC_CLKS0x18
+#define FTM_SC_PS_10x0
+#define FTM_SC_PS_20x1
+#define FTM_SC_PS_40x2
+#define FTM_SC_PS_80x3
+#define FTM_SC_PS_16   0x4
+#define FTM_SC_PS_32   0x5
+#define FTM_SC_PS_64   0x6
+#define FTM_SC_PS_128  0x7
+#define FTM_SC_PS_MASK 0x7
+
+#define FTM_MODE_FAULTIE   0x80
+#define FTM_MODE_FAULTM0x60
+#define FTM_MODE_CAPTEST   0x10
+#define FTM_MODE_PWMSYNC   0x8
+#define FTM_MODE_WPDIS 0x4
+#define FTM_MODE_INIT  0x2
+#define FTM_MODE_FTMEN 0x1
+
+/* NXP Errata: The PHAFLTREN and PHBFLTREN bits are tide to zero internally
+ * and these bits cannot be set. Flextimer cannot use Filter in
+ * Quadrature Decoder Mode.
+ * https://community.nxp.com/thread/467648#comment-1010319
+ */
+#define FTM_QDCTRL_PHAFLTREN   0x80
+#define FTM_QDCTRL_PHBFLTREN   0x40
+#define FTM_QDCTRL_PHAPOL  0x20
+#define FTM_QDCTRL_PHBPOL  0x10
+#define FTM_QDCTRL_QUADMODE0x8
+#define FTM_QDCTRL_QUADDIR 0x4
+#define FTM_QDCTRL_TOFDIR  0x2
+#define FTM_QDCTRL_QUADEN  0x1
+
+#define FTM_FMS_FAULTF 0x80
+#define FTM_FMS_WPEN   0x40
+#define FTM_FMS_FAULTIN0x10
+#define FTM_FMS_FAULTF30x8
+#define FTM_FMS_FAULTF20x4
+#define FTM_FMS_FAULTF10x2
+#define FTM_FMS_FAULTF00x1
+
+#define FTM_CSC_BASE   0xC
+#define FTM_CSC_MSB0x20
+#define FTM_CSC_MSA0x10
+#define FTM_CSC_ELSB   0x8
+#define FTM_CSC_ELSA   0x4
+#define FTM_CSC(_channel)  (FTM_CSC_BASE + ((_channel) * 8))
+
+#define FTM_CV_BASE0x10
+#define FTM_CV(_channel)   (FTM_CV_BASE + ((_channel) * 8))
+
+#define FTM_PS_MAX 7
+
+#endif
-- 
2.19.1



[PATCH v2 0/7] FlexTimer Module Quadrature decoder counter

2019-03-06 Thread Patrick Havelange
This patch serie is to be applied on top of 
https://patchwork.kernel.org/project/linux-iio/list/?series=147
(a more recent version of the serie is available here : 
https://gitlab.com/vilhelmgray/iio/tree/generic_counter_v10 )

Main changes in v2: 
The code is a bit simpler, thanks to more use of devm_* functions.
The polling/32bit signed version has been dropped, as not needed and
no other driver is doing that.


Patrick Havelange (7):
  include/fsl: add common FlexTimer #defines in a separate header.
  drivers/pwm: pwm-fsl-ftm: use common header for FlexTimer #defines
  drivers/clocksource: timer-fsl-ftm: use common header for FlexTimer
#defines
  dt-bindings: counter: ftm-quaddec
  counter: add FlexTimer Module Quadrature decoder counter driver
  counter: ftm-quaddec: Documentation: Add specific counter sysfs
documentation
  LS1021A: dtsi: add ftm quad decoder entries

 .../ABI/testing/sysfs-bus-counter-ftm-quaddec |  16 +
 .../bindings/counter/ftm-quaddec.txt  |  18 +
 arch/arm/boot/dts/ls1021a.dtsi|  28 ++
 drivers/clocksource/timer-fsl-ftm.c   |  15 +-
 drivers/counter/Kconfig   |   9 +
 drivers/counter/Makefile  |   1 +
 drivers/counter/ftm-quaddec.c | 356 ++
 drivers/pwm/pwm-fsl-ftm.c |  44 +--
 include/linux/fsl/ftm.h   |  88 +
 9 files changed, 519 insertions(+), 56 deletions(-)
 create mode 100644 Documentation/ABI/testing/sysfs-bus-counter-ftm-quaddec
 create mode 100644 Documentation/devicetree/bindings/counter/ftm-quaddec.txt
 create mode 100644 drivers/counter/ftm-quaddec.c
 create mode 100644 include/linux/fsl/ftm.h

-- 
2.19.1



Re: [PATCH 5/8] iio/counter: add FlexTimer Module Quadrature decoder counter driver

2019-03-04 Thread Patrick Havelange
On Wed, Feb 20, 2019 at 5:42 PM Jonathan Cameron  wrote:
[skipped]
> > +
> > +struct ftm_quaddec {
> > + struct platform_device *pdev;
> > + void __iomem *ftm_base;
> > + bool big_endian;
>
> I'm curious. What is the benefit of running in big endian mode?

It is based on the same behaviour as in drivers/clocksource/timer-fsl-ftm.c
The FlexTimer itself on the board I'm testing it with is working in
big endian mode, so this mode is required.

> > +static ssize_t ftm_write_reset(struct iio_dev *indio_dev,
> > + uintptr_t private,
> > + struct iio_chan_spec const *chan,
> > + const char *buf, size_t len)
> > +{
> > + struct ftm_quaddec *ftm = iio_priv(indio_dev);
> > +
> > + /* Only "counter reset" is supported for now */
> > + if (!sysfs_streq(buf, "0")) {
> > + dev_warn(>pdev->dev, "Reset only accepts '0'\n");
> > + return -EINVAL;
>
> Why not just make the channel attribute itself writeable given we are
> setting it to 0?

Good idea, I'll see if this can be applied in the new subsystem.

[skipped]

All other comments are Acked.


Re: [PATCH 5/8] iio/counter: add FlexTimer Module Quadrature decoder counter driver

2019-02-22 Thread Patrick Havelange
Hi Jonathan,

Thanks for your comments, I'll make a new version of the patch based
on your input.

William, I'll rebase the next version on top of your branch.

I'm glad the counter subsystem effort is progressing :)


Patrick Havelange.

On Thu, Feb 21, 2019 at 9:27 AM William Breathitt Gray
 wrote:
>
> On Thu, Feb 21, 2019 at 10:09:54AM +0900, William Breathitt Gray wrote:
> > On Wed, Feb 20, 2019 at 04:41:54PM +, Jonathan Cameron wrote:
> > > On Mon, 18 Feb 2019 15:03:18 +0100
> > > Patrick Havelange  wrote:
> > >
> > > > This driver exposes the counter for the quadrature decoder of the
> > > > FlexTimer Module, present in the LS1021A soc.
> > > >
> > > > Signed-off-by: Patrick Havelange 
> > > > Reviewed-by: Esben Haabendal 
> > > Given you cc'd William, I'm guessing you know about the counter
> > > subsystem effort.  I would really rather not take any drivers
> > > into IIO if we have any hope of getting that upstreamed soon
> > > (which I personally think we do and should!).  The reason is
> > > we end up having to maintain old ABI just because someone might be using
> > > it and it makes the drivers very messy.
> > >
> > > I'll review as is though as may be there are some elements that will
> > > cross over.
> > >
> > > Comments inline.  William: Looks like a straight forward conversion if
> > > it makes sense to get this lined up as part of your initial submission?
> > > You have quite a few drivers so I wouldn't have said it needs to be there
> > > at the start, but good to have it soon after.
> > >
> > > Jonathan
> >
> > I agree, we should try to merge this as part of Counter subsystem
> > introduction rather than as another IIO Counter driver. As we determined
> > when adding support for the STM32 timers, the existing IIO Counter API
> > is fundamentally unsuitable for representing counter devices. So
> > regardless of how a new Counter API is merged, the existing IIO Counter
> > API must be deprecated.
> >
> > Patrick, I apologize for the confusion this has caused. Would you be
> > able to convert this driver to use the proposed Counter subsystem API
> > from this patchset that I believe you encountered before:
> > https://marc.info/?l=linux-arm-kernel=153229982404051
> >
> > Although it was last updated in October, I believe you should be able to
> > rebase that Counter subsystem introduction patchset cleanly on top of
> > the IIO tree (if there are any merge conflicts send me an email). Take a
> > look at the generic-counter.rst file under the Documentation/driver-api/
> > directory for an overview of the API; the counter drivers under the
> > drivers/counter/ directory also make good references.
> >
> > If you have any difficulties understanding the API, or any other
> > troubles, don't hesitate to ask. Hopefully, I've made the documentation
> > clear enough to make the conversion of this driver quick and easy -- and
> > if not, then it's something I need to fix, so let me know. :-)
> >
> > William Breathitt Gray
>
> Patrick,
>
> It looks like there were some minor conflicts with the v9 patchset, so
> I've rebased it on top of the latest iio tree testing branch and
> resolved the conflicts in my personal repository. Please pull from my
> personal repository at https://gitlab.com/vilhelmgray/iio.git and base
> your patches on top of the generic_counter_v10 branch.
>
> William Breathitt Gray


[PATCH 8/8] iio/counter/ftm-quaddec: add handling of under/overflow of the counter.

2019-02-18 Thread Patrick Havelange
This is implemented by polling the counter value. A new parameter
"poll-interval" can be set in the device tree, or can be changed
at runtime. The reason for the polling is to avoid interrupts flooding.
If the quadrature input is going up and down around the overflow value
(or around 0), the interrupt will be triggering all the time. Thus,
polling is an easy way to handle overflow in a consistent way.
Polling can still be disabled by setting poll-interval to 0.

Signed-off-by: Patrick Havelange 
Reviewed-by: Esben Haabendal 
---
 drivers/iio/counter/ftm-quaddec.c | 199 +-
 1 file changed, 193 insertions(+), 6 deletions(-)

diff --git a/drivers/iio/counter/ftm-quaddec.c 
b/drivers/iio/counter/ftm-quaddec.c
index ca7e55a9ab3f..3a0395c3ef33 100644
--- a/drivers/iio/counter/ftm-quaddec.c
+++ b/drivers/iio/counter/ftm-quaddec.c
@@ -25,11 +25,33 @@
 
 struct ftm_quaddec {
struct platform_device *pdev;
+   struct delayed_work delayedcounterwork;
void __iomem *ftm_base;
bool big_endian;
+
+   /* Offset added to the counter to adjust for overflows of the
+* 16 bit HW counter. Only the 16 MSB are set.
+*/
+   uint32_t counteroffset;
+
+   /* Store the counter on each read, this is used to detect
+* if the counter readout if we over or underflow
+*/
+   uint8_t lastregion;
+
+   /* Poll-interval, in ms before delayed work must poll counter */
+   uint16_t poll_interval;
+
struct mutex ftm_quaddec_mutex;
 };
 
+struct counter_result {
+   /* 16 MSB are from the counteroffset
+* 16 LSB are from the hardware counter
+*/
+   uint32_t value;
+};
+
 #define HASFLAGS(flag, bits) ((flag & bits) ? 1 : 0)
 
 #define DEFAULT_POLL_INTERVAL100 /* in msec */
@@ -74,8 +96,75 @@ static void ftm_set_write_protection(struct ftm_quaddec *ftm)
ftm_write(ftm, FTM_FMS, FTM_FMS_WPEN);
 }
 
+/* must be called with mutex locked */
+static void ftm_work_reschedule(struct ftm_quaddec *ftm)
+{
+   cancel_delayed_work(>delayedcounterwork);
+   if (ftm->poll_interval > 0)
+   schedule_delayed_work(>delayedcounterwork,
+  msecs_to_jiffies(ftm->poll_interval));
+}
+
+/* Reports the hardware counter added the offset counter.
+ *
+ * The quadrature decodes does not use interrupts, because it cannot be
+ * guaranteed that the counter won't flip between 0x and 0x at a high
+ * rate, causing Real Time performance degration. Instead the counter must be
+ * read frequently enough - the assumption is 150 KHz input can be handled with
+ * 100 ms read cycles.
+ */
+static void ftm_work_counter(struct ftm_quaddec *ftm,
+struct counter_result *returndata)
+{
+   /* only 16bits filled in*/
+   uint32_t hwcounter;
+   uint8_t currentregion;
+
+   mutex_lock(>ftm_quaddec_mutex);
+
+   ftm_read(ftm, FTM_CNT, );
+
+   /* Divide the counter in four regions:
+*   0x-0x4000-0x8000-0xC000-0x
+* When the hwcounter changes between region 0 and 3 there is an
+* over/underflow
+*/
+   currentregion = hwcounter / 0x4000;
+
+   if (ftm->lastregion == 3 && currentregion == 0)
+   ftm->counteroffset += 0x1;
+
+   if (ftm->lastregion == 0 && currentregion == 3)
+   ftm->counteroffset -= 0x1;
+
+   ftm->lastregion = currentregion;
+
+   if (returndata)
+   returndata->value = ftm->counteroffset + hwcounter;
+
+   ftm_work_reschedule(ftm);
+
+   mutex_unlock(>ftm_quaddec_mutex);
+}
+
+/* wrapper around the real function */
+static void ftm_work_counter_delay(struct work_struct *workptr)
+{
+   struct delayed_work *work;
+   struct ftm_quaddec *ftm;
+
+   work = container_of(workptr, struct delayed_work, work);
+   ftm = container_of(work, struct ftm_quaddec, delayedcounterwork);
+
+   ftm_work_counter(ftm, NULL);
+}
+
+/* must be called with mutex locked */
 static void ftm_reset_counter(struct ftm_quaddec *ftm)
 {
+   ftm->counteroffset = 0;
+   ftm->lastregion = 0;
+
/* Reset hardware counter to CNTIN */
ftm_write(ftm, FTM_CNT, 0x0);
 }
@@ -110,18 +199,91 @@ static int ftm_quaddec_read_raw(struct iio_dev *indio_dev,
int *val, int *val2, long mask)
 {
struct ftm_quaddec *ftm = iio_priv(indio_dev);
-   uint32_t counter;
+   struct counter_result counter;
 
switch (mask) {
case IIO_CHAN_INFO_RAW:
-   ftm_read(ftm, FTM_CNT, );
-   *val = counter;
+   case IIO_CHAN_INFO_PROCESSED:
+   ftm_work_counter(ftm, );
+   if (mask == IIO_CHAN_INFO_RAW)
+   counter.value &= 0x;
+
+   *val = counter.value;
+
return IIO_VAL_INT

[PATCH 4/8] dt-bindings: iio/counter: ftm-quaddec

2019-02-18 Thread Patrick Havelange
FlexTimer quadrature decoder driver.

Signed-off-by: Patrick Havelange 
Reviewed-by: Esben Haabendal 
---
 .../bindings/iio/counter/ftm-quaddec.txt   | 18 ++
 1 file changed, 18 insertions(+)
 create mode 100644 
Documentation/devicetree/bindings/iio/counter/ftm-quaddec.txt

diff --git a/Documentation/devicetree/bindings/iio/counter/ftm-quaddec.txt 
b/Documentation/devicetree/bindings/iio/counter/ftm-quaddec.txt
new file mode 100644
index ..4d18cd722074
--- /dev/null
+++ b/Documentation/devicetree/bindings/iio/counter/ftm-quaddec.txt
@@ -0,0 +1,18 @@
+FlexTimer Quadrature decoder counter
+
+This driver exposes a simple counter for the quadrature decoder mode.
+
+Required properties:
+- compatible:  Must be "fsl,ftm-quaddec".
+- reg: Must be set to the memory region of the flextimer.
+
+Optional property:
+- big-endian:  Access the device registers in big-endian mode.
+
+Example:
+   counter0: counter@29d {
+   compatible = "fsl,ftm-quaddec";
+   reg = <0x0 0x29d 0x0 0x1>;
+   big-endian;
+   status = "disabled";
+   };
-- 
2.17.1



[PATCH 7/8] dt-bindings: iio/counter: ftm-quaddec: add poll-interval parameter

2019-02-18 Thread Patrick Havelange
New optional parameter supported by updated driver.

Signed-off-by: Patrick Havelange 
Reviewed-by: Esben Haabendal 
---
 .../devicetree/bindings/iio/counter/ftm-quaddec.txt   | 8 +++-
 1 file changed, 7 insertions(+), 1 deletion(-)

diff --git a/Documentation/devicetree/bindings/iio/counter/ftm-quaddec.txt 
b/Documentation/devicetree/bindings/iio/counter/ftm-quaddec.txt
index 4d18cd722074..60554e6c4367 100644
--- a/Documentation/devicetree/bindings/iio/counter/ftm-quaddec.txt
+++ b/Documentation/devicetree/bindings/iio/counter/ftm-quaddec.txt
@@ -6,8 +6,14 @@ Required properties:
 - compatible:  Must be "fsl,ftm-quaddec".
 - reg: Must be set to the memory region of the flextimer.
 
-Optional property:
+Optional properties:
 - big-endian:  Access the device registers in big-endian mode.
+- poll-intervalPoll interval time in milliseconds for detecting
+   the under/overflow of the counter. Default value
+   is 100.
+   A value of 0 disables polling. This value can also
+   be set at runtime, but not to less than this initial
+   value (except 0 for disabling).
 
 Example:
counter0: counter@29d {
-- 
2.17.1



[PATCH 6/8] LS1021A: dtsi: add ftm quad decoder entries

2019-02-18 Thread Patrick Havelange
Add the 4 Quadrature counters for this board.

Signed-off-by: Patrick Havelange 
Reviewed-by: Esben Haabendal 
---
 arch/arm/boot/dts/ls1021a.dtsi | 28 
 1 file changed, 28 insertions(+)

diff --git a/arch/arm/boot/dts/ls1021a.dtsi b/arch/arm/boot/dts/ls1021a.dtsi
index ed0941292172..0168fb62590a 100644
--- a/arch/arm/boot/dts/ls1021a.dtsi
+++ b/arch/arm/boot/dts/ls1021a.dtsi
@@ -433,6 +433,34 @@
status = "disabled";
};
 
+   counter0: counter@29d {
+   compatible = "fsl,ftm-quaddec";
+   reg = <0x0 0x29d 0x0 0x1>;
+   big-endian;
+   status = "disabled";
+   };
+
+   counter1: counter@29e {
+   compatible = "fsl,ftm-quaddec";
+   reg = <0x0 0x29e 0x0 0x1>;
+   big-endian;
+   status = "disabled";
+   };
+
+   counter2: counter@29f {
+   compatible = "fsl,ftm-quaddec";
+   reg = <0x0 0x29f 0x0 0x1>;
+   big-endian;
+   status = "disabled";
+   };
+
+   counter3: counter@2a0 {
+   compatible = "fsl,ftm-quaddec";
+   reg = <0x0 0x2a0 0x0 0x1>;
+   big-endian;
+   status = "disabled";
+   };
+
gpio0: gpio@230 {
compatible = "fsl,ls1021a-gpio", "fsl,qoriq-gpio";
reg = <0x0 0x230 0x0 0x1>;
-- 
2.17.1



[PATCH 2/8] drivers/pwm: pwm-fsl-ftm: use common header for FlexTimer #defines

2019-02-18 Thread Patrick Havelange
This also fixes the wrong value for the previously defined
FTM_MODE_INIT macro (it was not used).

Signed-off-by: Patrick Havelange 
Reviewed-by: Esben Haabendal 
---
 drivers/pwm/pwm-fsl-ftm.c | 44 +--
 1 file changed, 1 insertion(+), 43 deletions(-)

diff --git a/drivers/pwm/pwm-fsl-ftm.c b/drivers/pwm/pwm-fsl-ftm.c
index 883378d055c6..f21ea1b97116 100644
--- a/drivers/pwm/pwm-fsl-ftm.c
+++ b/drivers/pwm/pwm-fsl-ftm.c
@@ -22,51 +22,9 @@
 #include 
 #include 
 #include 
+#include 
 
-#define FTM_SC 0x00
-#define FTM_SC_CLK_MASK_SHIFT  3
-#define FTM_SC_CLK_MASK(3 << FTM_SC_CLK_MASK_SHIFT)
 #define FTM_SC_CLK(c)  (((c) + 1) << FTM_SC_CLK_MASK_SHIFT)
-#define FTM_SC_PS_MASK 0x7
-
-#define FTM_CNT0x04
-#define FTM_MOD0x08
-
-#define FTM_CSC_BASE   0x0C
-#define FTM_CSC_MSBBIT(5)
-#define FTM_CSC_MSABIT(4)
-#define FTM_CSC_ELSB   BIT(3)
-#define FTM_CSC_ELSA   BIT(2)
-#define FTM_CSC(_channel)  (FTM_CSC_BASE + ((_channel) * 8))
-
-#define FTM_CV_BASE0x10
-#define FTM_CV(_channel)   (FTM_CV_BASE + ((_channel) * 8))
-
-#define FTM_CNTIN  0x4C
-#define FTM_STATUS 0x50
-
-#define FTM_MODE   0x54
-#define FTM_MODE_FTMEN BIT(0)
-#define FTM_MODE_INIT  BIT(2)
-#define FTM_MODE_PWMSYNC   BIT(3)
-
-#define FTM_SYNC   0x58
-#define FTM_OUTINIT0x5C
-#define FTM_OUTMASK0x60
-#define FTM_COMBINE0x64
-#define FTM_DEADTIME   0x68
-#define FTM_EXTTRIG0x6C
-#define FTM_POL0x70
-#define FTM_FMS0x74
-#define FTM_FILTER 0x78
-#define FTM_FLTCTRL0x7C
-#define FTM_QDCTRL 0x80
-#define FTM_CONF   0x84
-#define FTM_FLTPOL 0x88
-#define FTM_SYNCONF0x8C
-#define FTM_INVCTRL0x90
-#define FTM_SWOCTRL0x94
-#define FTM_PWMLOAD0x98
 
 enum fsl_pwm_clk {
FSL_PWM_CLK_SYS,
-- 
2.17.1



[PATCH 1/8] include/fsl: add common FlexTimer #defines in a separate header.

2019-02-18 Thread Patrick Havelange
Signed-off-by: Patrick Havelange 
Reviewed-by: Esben Haabendal 
---
 include/linux/fsl/ftm.h | 88 +
 1 file changed, 88 insertions(+)
 create mode 100644 include/linux/fsl/ftm.h

diff --git a/include/linux/fsl/ftm.h b/include/linux/fsl/ftm.h
new file mode 100644
index ..d59011acf66c
--- /dev/null
+++ b/include/linux/fsl/ftm.h
@@ -0,0 +1,88 @@
+// SPDX-License-Identifier: GPL-2.0
+#ifndef __FSL_FTM_H__
+#define __FSL_FTM_H__
+
+#define FTM_SC   0x0 /* Status And Control */
+#define FTM_CNT  0x4 /* Counter */
+#define FTM_MOD  0x8 /* Modulo */
+
+#define FTM_CNTIN0x4C /* Counter Initial Value */
+#define FTM_STATUS   0x50 /* Capture And Compare Status */
+#define FTM_MODE 0x54 /* Features Mode Selection */
+#define FTM_SYNC 0x58 /* Synchronization */
+#define FTM_OUTINIT  0x5C /* Initial State For Channels Output */
+#define FTM_OUTMASK  0x60 /* Output Mask */
+#define FTM_COMBINE  0x64 /* Function For Linked Channels */
+#define FTM_DEADTIME 0x68 /* Deadtime Insertion Control */
+#define FTM_EXTTRIG  0x6C /* FTM External Trigger */
+#define FTM_POL  0x70 /* Channels Polarity */
+#define FTM_FMS  0x74 /* Fault Mode Status */
+#define FTM_FILTER   0x78 /* Input Capture Filter Control */
+#define FTM_FLTCTRL  0x7C /* Fault Control */
+#define FTM_QDCTRL   0x80 /* Quadrature Decoder Control And Status */
+#define FTM_CONF 0x84 /* Configuration */
+#define FTM_FLTPOL   0x88 /* FTM Fault Input Polarity */
+#define FTM_SYNCONF  0x8C /* Synchronization Configuration */
+#define FTM_INVCTRL  0x90 /* FTM Inverting Control */
+#define FTM_SWOCTRL  0x94 /* FTM Software Output Control */
+#define FTM_PWMLOAD  0x98 /* FTM PWM Load */
+
+#define FTM_SC_CLK_MASK_SHIFT  3
+#define FTM_SC_CLK_MASK(3 << FTM_SC_CLK_MASK_SHIFT)
+#define FTM_SC_TOF 0x80
+#define FTM_SC_TOIE0x40
+#define FTM_SC_CPWMS   0x20
+#define FTM_SC_CLKS0x18
+#define FTM_SC_PS_10x0
+#define FTM_SC_PS_20x1
+#define FTM_SC_PS_40x2
+#define FTM_SC_PS_80x3
+#define FTM_SC_PS_16   0x4
+#define FTM_SC_PS_32   0x5
+#define FTM_SC_PS_64   0x6
+#define FTM_SC_PS_128  0x7
+#define FTM_SC_PS_MASK 0x7
+
+#define FTM_MODE_FAULTIE   0x80
+#define FTM_MODE_FAULTM0x60
+#define FTM_MODE_CAPTEST   0x10
+#define FTM_MODE_PWMSYNC   0x8
+#define FTM_MODE_WPDIS 0x4
+#define FTM_MODE_INIT  0x2
+#define FTM_MODE_FTMEN 0x1
+
+/* NXP Errata: The PHAFLTREN and PHBFLTREN bits are tide to zero internally
+ * and these bits cannot be set. Flextimer cannot use Filter in
+ * Quadrature Decoder Mode.
+ * https://community.nxp.com/thread/467648#comment-1010319
+ */
+#define FTM_QDCTRL_PHAFLTREN   0x80
+#define FTM_QDCTRL_PHBFLTREN   0x40
+#define FTM_QDCTRL_PHAPOL  0x20
+#define FTM_QDCTRL_PHBPOL  0x10
+#define FTM_QDCTRL_QUADMODE0x8
+#define FTM_QDCTRL_QUADDIR 0x4
+#define FTM_QDCTRL_TOFDIR  0x2
+#define FTM_QDCTRL_QUADEN  0x1
+
+#define FTM_FMS_FAULTF 0x80
+#define FTM_FMS_WPEN   0x40
+#define FTM_FMS_FAULTIN0x10
+#define FTM_FMS_FAULTF30x8
+#define FTM_FMS_FAULTF20x4
+#define FTM_FMS_FAULTF10x2
+#define FTM_FMS_FAULTF00x1
+
+#define FTM_CSC_BASE   0xC
+#define FTM_CSC_MSB0x20
+#define FTM_CSC_MSA0x10
+#define FTM_CSC_ELSB   0x8
+#define FTM_CSC_ELSA   0x4
+#define FTM_CSC(_channel)  (FTM_CSC_BASE + ((_channel) * 8))
+
+#define FTM_CV_BASE0x10
+#define FTM_CV(_channel)   (FTM_CV_BASE + ((_channel) * 8))
+
+#define FTM_PS_MAX 7
+
+#endif
-- 
2.17.1



[PATCH 3/8] drivers/clocksource: timer-fsl-ftm: use common header for FlexTimer #defines

2019-02-18 Thread Patrick Havelange
Signed-off-by: Patrick Havelange 
Reviewed-by: Esben Haabendal 
---
 drivers/clocksource/timer-fsl-ftm.c | 15 ++-
 1 file changed, 2 insertions(+), 13 deletions(-)

diff --git a/drivers/clocksource/timer-fsl-ftm.c 
b/drivers/clocksource/timer-fsl-ftm.c
index 846d18daf893..e1c34b2f53a5 100644
--- a/drivers/clocksource/timer-fsl-ftm.c
+++ b/drivers/clocksource/timer-fsl-ftm.c
@@ -19,20 +19,9 @@
 #include 
 #include 
 #include 
+#include 
 
-#define FTM_SC 0x00
-#define FTM_SC_CLK_SHIFT   3
-#define FTM_SC_CLK_MASK(0x3 << FTM_SC_CLK_SHIFT)
-#define FTM_SC_CLK(c)  ((c) << FTM_SC_CLK_SHIFT)
-#define FTM_SC_PS_MASK 0x7
-#define FTM_SC_TOIEBIT(6)
-#define FTM_SC_TOF BIT(7)
-
-#define FTM_CNT0x04
-#define FTM_MOD0x08
-#define FTM_CNTIN  0x4C
-
-#define FTM_PS_MAX 7
+#define FTM_SC_CLK(c)  ((c) << FTM_SC_CLK_MASK_SHIFT)
 
 struct ftm_clock_device {
void __iomem *clksrc_base;
-- 
2.17.1



[PATCH 5/8] iio/counter: add FlexTimer Module Quadrature decoder counter driver

2019-02-18 Thread Patrick Havelange
This driver exposes the counter for the quadrature decoder of the
FlexTimer Module, present in the LS1021A soc.

Signed-off-by: Patrick Havelange 
Reviewed-by: Esben Haabendal 
---
 drivers/iio/counter/Kconfig   |  10 +
 drivers/iio/counter/Makefile  |   1 +
 drivers/iio/counter/ftm-quaddec.c | 294 ++
 3 files changed, 305 insertions(+)
 create mode 100644 drivers/iio/counter/ftm-quaddec.c

diff --git a/drivers/iio/counter/Kconfig b/drivers/iio/counter/Kconfig
index bf1e559ad7cd..4641cb2e752a 100644
--- a/drivers/iio/counter/Kconfig
+++ b/drivers/iio/counter/Kconfig
@@ -31,4 +31,14 @@ config STM32_LPTIMER_CNT
 
  To compile this driver as a module, choose M here: the
  module will be called stm32-lptimer-cnt.
+
+config FTM_QUADDEC
+   tristate "Flex Timer Module Quadrature decoder driver"
+   help
+ Select this option to enable the Flex Timer Quadrature decoder
+ driver.
+
+ To compile this driver as a module, choose M here: the
+ module will be called ftm-quaddec.
+
 endmenu
diff --git a/drivers/iio/counter/Makefile b/drivers/iio/counter/Makefile
index 1b9a896eb488..757c1f4196af 100644
--- a/drivers/iio/counter/Makefile
+++ b/drivers/iio/counter/Makefile
@@ -6,3 +6,4 @@
 
 obj-$(CONFIG_104_QUAD_8)   += 104-quad-8.o
 obj-$(CONFIG_STM32_LPTIMER_CNT)+= stm32-lptimer-cnt.o
+obj-$(CONFIG_FTM_QUADDEC)  += ftm-quaddec.o
diff --git a/drivers/iio/counter/ftm-quaddec.c 
b/drivers/iio/counter/ftm-quaddec.c
new file mode 100644
index ..ca7e55a9ab3f
--- /dev/null
+++ b/drivers/iio/counter/ftm-quaddec.c
@@ -0,0 +1,294 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Flex Timer Module Quadrature decoder
+ *
+ * This module implements a driver for decoding the FTM quadrature
+ * of ex. a LS1021A
+ */
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+struct ftm_quaddec {
+   struct platform_device *pdev;
+   void __iomem *ftm_base;
+   bool big_endian;
+   struct mutex ftm_quaddec_mutex;
+};
+
+#define HASFLAGS(flag, bits) ((flag & bits) ? 1 : 0)
+
+#define DEFAULT_POLL_INTERVAL100 /* in msec */
+
+static void ftm_read(struct ftm_quaddec *ftm, uint32_t offset, uint32_t *data)
+{
+   if (ftm->big_endian)
+   *data = ioread32be(ftm->ftm_base + offset);
+   else
+   *data = ioread32(ftm->ftm_base + offset);
+}
+
+static void ftm_write(struct ftm_quaddec *ftm, uint32_t offset, uint32_t data)
+{
+   if (ftm->big_endian)
+   iowrite32be(data, ftm->ftm_base + offset);
+   else
+   iowrite32(data, ftm->ftm_base + offset);
+}
+
+/* take mutex
+ * call ftm_clear_write_protection
+ * update settings
+ * call ftm_set_write_protection
+ * release mutex
+ */
+static void ftm_clear_write_protection(struct ftm_quaddec *ftm)
+{
+   uint32_t flag;
+
+   /* First see if it is enabled */
+   ftm_read(ftm, FTM_FMS, );
+
+   if (flag & FTM_FMS_WPEN) {
+   ftm_read(ftm, FTM_MODE, );
+   ftm_write(ftm, FTM_MODE, flag | FTM_MODE_WPDIS);
+   }
+}
+
+static void ftm_set_write_protection(struct ftm_quaddec *ftm)
+{
+   ftm_write(ftm, FTM_FMS, FTM_FMS_WPEN);
+}
+
+static void ftm_reset_counter(struct ftm_quaddec *ftm)
+{
+   /* Reset hardware counter to CNTIN */
+   ftm_write(ftm, FTM_CNT, 0x0);
+}
+
+static void ftm_quaddec_init(struct ftm_quaddec *ftm)
+{
+   ftm_clear_write_protection(ftm);
+
+   /* Do not write in the region from the CNTIN register through the
+* PWMLOAD register when FTMEN = 0.
+*/
+   ftm_write(ftm, FTM_MODE, FTM_MODE_FTMEN); /* enable FTM */
+   ftm_write(ftm, FTM_CNTIN, 0x); /* zero init value */
+   ftm_write(ftm, FTM_MOD, 0x);/* max overflow value */
+   ftm_write(ftm, FTM_CNT, 0x0);   /* reset counter value */
+   ftm_write(ftm, FTM_SC, FTM_SC_PS_1);/* prescale with x1 */
+   /* Select quad mode */
+   ftm_write(ftm, FTM_QDCTRL, FTM_QDCTRL_QUADEN);
+
+   /* Unused features and reset to default section */
+   ftm_write(ftm, FTM_POL, 0x0); /* polarity is active high */
+   ftm_write(ftm, FTM_FLTCTRL, 0x0); /* all faults disabled */
+   ftm_write(ftm, FTM_SYNCONF, 0x0); /* disable all sync */
+   ftm_write(ftm, FTM_SYNC, 0x);
+
+   /* Lock the FTM */
+   ftm_set_write_protection(ftm);
+}
+
+static int ftm_quaddec_read_raw(struct iio_dev *indio_dev,
+   struct iio_chan_spec const *chan,
+   int *val, int *val2, long mask)
+{
+   struct ftm_quaddec *ftm = iio_priv(indio_dev);
+   uint32_t counter;
+
+   switch (mask) {
+   case IIO_CHAN_INFO_RAW:
+   ftm_read(ftm, FTM_CNT, );
+   *v