* [RESEND PATCH v2 5/7] drm/vc4: Document VEC DT binding
From: Boris Brezillon @ 2016-12-02 13:48 UTC (permalink / raw)
To: David Airlie, Daniel Vetter,
dri-devel-PD4FTy7X32lNgt0PjOBp9y5qC8QIuHrW
Cc: Florian Fainelli, Ray Jui, Scott Branden,
bcm-kernel-feedback-list-dY08KVG/lbpWk0Htik3J/w, Stephen Warren,
Lee Jones, Eric Anholt,
linux-rpi-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r, Rob Herring,
Pawel Moll, Mark Rutland, Ian Campbell, Kumar Gala,
devicetree-u79uwXL29TY76Z2rM5mHXA,
linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r,
Boris Brezillon
In-Reply-To: <1480686493-4813-1-git-send-email-boris.brezillon-wi1+55ScJUtKEb57/3fJTNBPR1lH4CV8@public.gmane.org>
Document the DT binding for the VEC (Video EnCoder) IP.
Signed-off-by: Boris Brezillon <boris.brezillon-wi1+55ScJUtKEb57/3fJTNBPR1lH4CV8@public.gmane.org>
---
Documentation/devicetree/bindings/display/brcm,bcm-vc4.txt | 14 ++++++++++++++
1 file changed, 14 insertions(+)
diff --git a/Documentation/devicetree/bindings/display/brcm,bcm-vc4.txt b/Documentation/devicetree/bindings/display/brcm,bcm-vc4.txt
index a5ea451e67fc..e2768703ac2b 100644
--- a/Documentation/devicetree/bindings/display/brcm,bcm-vc4.txt
+++ b/Documentation/devicetree/bindings/display/brcm,bcm-vc4.txt
@@ -43,6 +43,13 @@ Required properties for DPI:
- port: Port node with a single endpoint connecting to the panel
device, as defined in [1]
+Required properties for VEC:
+- compatible: Should be "brcm,bcm2835-vec"
+- reg: Physical base address and length of the registers
+- clocks: The core clock the unit runs on
+- interrupts: The interrupt number
+ See bindings/interrupt-controller/brcm,bcm2835-armctrl-ic.txt
+
Required properties for V3D:
- compatible: Should be "brcm,bcm2835-v3d"
- reg: Physical base address and length of the V3D's registers
@@ -92,6 +99,13 @@ dpi: dpi@7e208000 {
};
};
+vec: vec@7e806000 {
+ compatible = "brcm,bcm2835-vec";
+ reg = <0x7e806000 0x1000>;
+ clocks = <&clocks BCM2835_CLOCK_VEC>;
+ interrupts = <2 27>;
+};
+
v3d: v3d@7ec00000 {
compatible = "brcm,bcm2835-v3d";
reg = <0x7ec00000 0x1000>;
--
2.7.4
--
To unsubscribe from this list: send the line "unsubscribe devicetree" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
^ permalink raw reply related
* [RESEND PATCH v2 6/7] ARM: bcm/dt: Add VEC node in bcm283x.dtsi
From: Boris Brezillon @ 2016-12-02 13:48 UTC (permalink / raw)
To: David Airlie, Daniel Vetter,
dri-devel-PD4FTy7X32lNgt0PjOBp9y5qC8QIuHrW
Cc: Florian Fainelli, Ray Jui, Scott Branden,
bcm-kernel-feedback-list-dY08KVG/lbpWk0Htik3J/w, Stephen Warren,
Lee Jones, Eric Anholt,
linux-rpi-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r, Rob Herring,
Pawel Moll, Mark Rutland, Ian Campbell, Kumar Gala,
devicetree-u79uwXL29TY76Z2rM5mHXA,
linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r,
Boris Brezillon
In-Reply-To: <1480686493-4813-1-git-send-email-boris.brezillon-wi1+55ScJUtKEb57/3fJTNBPR1lH4CV8@public.gmane.org>
Add the VEC (Video EnCoder) node definition in bcm283x.dtsi.
Signed-off-by: Boris Brezillon <boris.brezillon-wi1+55ScJUtKEb57/3fJTNBPR1lH4CV8@public.gmane.org>
---
arch/arm/boot/dts/bcm283x.dtsi | 8 ++++++++
1 file changed, 8 insertions(+)
diff --git a/arch/arm/boot/dts/bcm283x.dtsi b/arch/arm/boot/dts/bcm283x.dtsi
index 46d46d894a44..44a9c0539437 100644
--- a/arch/arm/boot/dts/bcm283x.dtsi
+++ b/arch/arm/boot/dts/bcm283x.dtsi
@@ -266,6 +266,14 @@
status = "disabled";
};
+ vec: vec@7e806000 {
+ compatible = "brcm,bcm2835-vec";
+ reg = <0x7e806000 0x1000>;
+ clocks = <&clocks BCM2835_CLOCK_VEC>;
+ interrupts = <2 27>;
+ status = "disabled";
+ };
+
pixelvalve@7e807000 {
compatible = "brcm,bcm2835-pixelvalve2";
reg = <0x7e807000 0x100>;
--
2.7.4
--
To unsubscribe from this list: send the line "unsubscribe devicetree" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
^ permalink raw reply related
* [RESEND PATCH v2 7/7] ARM: bcm/dt: Enable the VEC IP on all RaspberryPi boards
From: Boris Brezillon @ 2016-12-02 13:48 UTC (permalink / raw)
To: David Airlie, Daniel Vetter,
dri-devel-PD4FTy7X32lNgt0PjOBp9y5qC8QIuHrW
Cc: Florian Fainelli, Ray Jui, Scott Branden,
bcm-kernel-feedback-list-dY08KVG/lbpWk0Htik3J/w, Stephen Warren,
Lee Jones, Eric Anholt,
linux-rpi-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r, Rob Herring,
Pawel Moll, Mark Rutland, Ian Campbell, Kumar Gala,
devicetree-u79uwXL29TY76Z2rM5mHXA,
linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r,
Boris Brezillon
In-Reply-To: <1480686493-4813-1-git-send-email-boris.brezillon-wi1+55ScJUtKEb57/3fJTNBPR1lH4CV8@public.gmane.org>
Enable the VEC IP on all RaspberryPi boards.
Signed-off-by: Boris Brezillon <boris.brezillon-wi1+55ScJUtKEb57/3fJTNBPR1lH4CV8@public.gmane.org>
---
arch/arm/boot/dts/bcm2835-rpi.dtsi | 5 +++++
1 file changed, 5 insertions(+)
diff --git a/arch/arm/boot/dts/bcm2835-rpi.dtsi b/arch/arm/boot/dts/bcm2835-rpi.dtsi
index e9b47b2bbc33..8893240da5f6 100644
--- a/arch/arm/boot/dts/bcm2835-rpi.dtsi
+++ b/arch/arm/boot/dts/bcm2835-rpi.dtsi
@@ -84,3 +84,8 @@
power-domains = <&power RPI_POWER_DOMAIN_HDMI>;
status = "okay";
};
+
+&vec {
+ power-domains = <&power RPI_POWER_DOMAIN_VEC>;
+ status = "okay";
+};
--
2.7.4
--
To unsubscribe from this list: send the line "unsubscribe devicetree" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
^ permalink raw reply related
* Re: [PATCH v5 11/14] ASoC: add simple-graph-card document
From: Rob Herring @ 2016-12-02 13:50 UTC (permalink / raw)
To: Kuninori Morimoto
Cc: Mark Brown, Linux-ALSA, Liam Girdwood, Simon, Laurent, Guennadi,
Grant Likely, Frank Rowand, Linux-DT, Linux-Kernel
In-Reply-To: <874m2swcbx.wl%kuninori.morimoto.gx-zM6kxYcvzFBBDgjK7y7TUQ@public.gmane.org>
On Mon, Nov 28, 2016 at 02:47:57AM +0000, Kuninori Morimoto wrote:
>
> From: Kuninori Morimoto <kuninori.morimoto.gx-zM6kxYcvzFBBDgjK7y7TUQ@public.gmane.org>
>
> Signed-off-by: Kuninori Morimoto <kuninori.morimoto.gx-zM6kxYcvzFBBDgjK7y7TUQ@public.gmane.org>
> ---
> .../bindings/sound/simple-graph-card.txt | 67 ++++++++++++++++++++++
> 1 file changed, 67 insertions(+)
> create mode 100644 Documentation/devicetree/bindings/sound/simple-graph-card.txt
>
> diff --git a/Documentation/devicetree/bindings/sound/simple-graph-card.txt b/Documentation/devicetree/bindings/sound/simple-graph-card.txt
> new file mode 100644
> index 0000000..3d4c5a8
> --- /dev/null
> +++ b/Documentation/devicetree/bindings/sound/simple-graph-card.txt
> @@ -0,0 +1,67 @@
> +Simple-Graph-Card:
There's nothing simple about this. graph-audio-card or audio-card-graph.
> +
> +Simple-Graph-Card specifies audio DAI connections of SoC <-> codec.
> +It is based on common bindings for device graphs.
> +see ${LINUX}/Documentation/devicetree/bindings/graph.txt
> +
> +Basically, Simple-Graph-Card property is same as Simple-Card.
> +see ${LINUX}/Documentation/devicetree/bindings/sound/simple-card.txt
> +
> +Below are same as Simple-Card.
> +
> +- simple-audio-card,name
> +- simple-audio-card,widgets
> +- simple-audio-card,routing
> +- simple-audio-card,mclk-fs
> +- simple-audio-card,hp-det-gpio
> +- simple-audio-card,mic-det-gpio
> +- simple-audio-card,format
> +- simple-audio-card,frame-master
> +- simple-audio-card,bitclock-master
> +- simple-audio-card,bitclock-inversion
> +- simple-audio-card,frame-inversion
> +- simple-audio-card,mclk-fs
> +- simple-audio-card,dai-tdm-slot-num
> +- simple-audio-card,dai-tdm-slot-width
The simple-audio-card prefix is pointless. It's fine to reuse, but don't
add to it.
> +- clocks / system-clock-frequency
> +
> +In Simple-Graph-Card, above properties need in CPU side port on DT.
> +And it needs to have "compatible" property too.
> +In addition, CPU side driver needs to call asoc_simple_card_try_to_probe_graph_card().
> +It will probe specified Card driver if it could find "compatible" property on port.
> +Otherwise, it will do nothing.
> +
> +Required properties:
> +
> +- compatible : "asoc-simple-graph-card";
> +- type : "sound";
> +
> +Example
> +
> +ak4643: codec@12 {
> + compatible = "asahi-kasei,ak4643";
> + ...
> + port {
> + type = "sound";
> + ak4643_port: endpoint {
> + remote-endpoint = <&rcar_ak4643_port>;
> + ...
> + };
> + };
> +};
> +
> +rcar_sound {
> + ...
> + port {
> + compatible = "asoc-simple-graph-card";
Do you have an example where you'd have multiple ports? If not, this
should go up a level.
> +
> + simple-audio-card,format = "left_j";
> + simple-audio-card,bitclock-master = <&ak4643_port>;
> + simple-audio-card,frame-master = <&ak4643_port>;
If you follow video-interfaces.txt, these should all go in the endpoint
node.
> + type = "sound";
> + rcar_ak4643_port: endpoint {
> + remote-endpoint = <&ak4643_port>;
> + ...
> + };
> + };
> +};
> --
> 1.9.1
>
--
To unsubscribe from this list: send the line "unsubscribe devicetree" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
^ permalink raw reply
* [PATCH 0/3] Enable ADC on STM32
From: Fabrice Gasnier @ 2016-12-02 13:56 UTC (permalink / raw)
To: alexandre.torgue, mcoquelin.stm32, linux, mark.rutland, robh+dt
Cc: devicetree, linux-arm-kernel, linux-kernel
Enable minimal configuration and device tree to support ADC on STM32,
using ADC driver: https://lwn.net/Articles/706445/
Simple test on stm32f429i-eval board, using on-board potentiometer:
- cd /sys/bus/iio/devices/iio\:device0/
- cat in_voltage8_raw
Fabrice Gasnier (3):
ARM: configs: stm32: enable ADC driver
ARM: dts: stm32: Add ADC support to stm32f429
ARM: dts: stm32: enable ADC on stm32f429i-eval board
arch/arm/boot/dts/stm32429i-eval.dts | 25 ++++++++++++++++++
arch/arm/boot/dts/stm32f429.dtsi | 49 ++++++++++++++++++++++++++++++++++++
arch/arm/configs/stm32_defconfig | 5 ++++
3 files changed, 79 insertions(+)
--
1.9.1
^ permalink raw reply
* [PATCH 1/3] ARM: configs: stm32: enable ADC driver
From: Fabrice Gasnier @ 2016-12-02 13:57 UTC (permalink / raw)
To: alexandre.torgue-qxv4g6HH51o,
mcoquelin.stm32-Re5JQEeQqe8AvxtiuMwx3w,
linux-I+IVW8TIWO2tmTQ+vhA3Yw, mark.rutland-5wv7dgnIgG8,
robh+dt-DgEjT+Ai2ygdnm+yROfE0A
Cc: devicetree-u79uwXL29TY76Z2rM5mHXA,
linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r,
linux-kernel-u79uwXL29TY76Z2rM5mHXA
In-Reply-To: <1480687022-12851-1-git-send-email-fabrice.gasnier-qxv4g6HH51o@public.gmane.org>
ADC driver depends on REGULATOR and IIO that are not yet selected.
Current hardware boards (like stm32f429i-eval) is using fixed
regulators.
Signed-off-by: Fabrice Gasnier <fabrice.gasnier-qxv4g6HH51o@public.gmane.org>
---
arch/arm/configs/stm32_defconfig | 5 +++++
1 file changed, 5 insertions(+)
diff --git a/arch/arm/configs/stm32_defconfig b/arch/arm/configs/stm32_defconfig
index a60b5cb..92ccc3c 100644
--- a/arch/arm/configs/stm32_defconfig
+++ b/arch/arm/configs/stm32_defconfig
@@ -49,6 +49,8 @@ CONFIG_SERIAL_STM32=y
CONFIG_SERIAL_STM32_CONSOLE=y
# CONFIG_HW_RANDOM is not set
# CONFIG_HWMON is not set
+CONFIG_REGULATOR=y
+CONFIG_REGULATOR_FIXED_VOLTAGE=y
# CONFIG_USB_SUPPORT is not set
CONFIG_NEW_LEDS=y
CONFIG_LEDS_CLASS=y
@@ -57,6 +59,9 @@ CONFIG_LEDS_TRIGGERS=y
CONFIG_LEDS_TRIGGER_HEARTBEAT=y
CONFIG_DMADEVICES=y
CONFIG_STM32_DMA=y
+CONFIG_IIO=y
+CONFIG_STM32_ADC_CORE=y
+CONFIG_STM32_ADC=y
# CONFIG_FILE_LOCKING is not set
# CONFIG_DNOTIFY is not set
# CONFIG_INOTIFY_USER is not set
--
1.9.1
--
To unsubscribe from this list: send the line "unsubscribe devicetree" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
^ permalink raw reply related
* [PATCH 2/3] ARM: dts: stm32: Add ADC support to stm32f429
From: Fabrice Gasnier @ 2016-12-02 13:57 UTC (permalink / raw)
To: alexandre.torgue, mcoquelin.stm32, linux, mark.rutland, robh+dt
Cc: devicetree, linux-arm-kernel, linux-kernel
In-Reply-To: <1480687022-12851-1-git-send-email-fabrice.gasnier@st.com>
Add ADC support & pinctrl analog phandle (adc3_in8) to stm32f429.
Signed-off-by: Fabrice Gasnier <fabrice.gasnier@st.com>
---
arch/arm/boot/dts/stm32f429.dtsi | 49 ++++++++++++++++++++++++++++++++++++++++
1 file changed, 49 insertions(+)
diff --git a/arch/arm/boot/dts/stm32f429.dtsi b/arch/arm/boot/dts/stm32f429.dtsi
index 3dd47eb..be1d970 100644
--- a/arch/arm/boot/dts/stm32f429.dtsi
+++ b/arch/arm/boot/dts/stm32f429.dtsi
@@ -172,6 +172,49 @@
status = "disabled";
};
+ adc: adc@40012000 {
+ compatible = "st,stm32f4-adc-core";
+ reg = <0x40012000 0x400>;
+ interrupts = <18>;
+ clocks = <&rcc 0 168>;
+ clock-names = "adc";
+ interrupt-controller;
+ #interrupt-cells = <1>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ status = "disabled";
+
+ adc1: adc@0 {
+ compatible = "st,stm32f4-adc";
+ #io-channel-cells = <1>;
+ reg = <0x0>;
+ clocks = <&rcc 0 168>;
+ interrupt-parent = <&adc>;
+ interrupts = <0>;
+ status = "disabled";
+ };
+
+ adc2: adc@100 {
+ compatible = "st,stm32f4-adc";
+ #io-channel-cells = <1>;
+ reg = <0x100>;
+ clocks = <&rcc 0 169>;
+ interrupt-parent = <&adc>;
+ interrupts = <1>;
+ status = "disabled";
+ };
+
+ adc3: adc@200 {
+ compatible = "st,stm32f4-adc";
+ #io-channel-cells = <1>;
+ reg = <0x200>;
+ clocks = <&rcc 0 170>;
+ interrupt-parent = <&adc>;
+ interrupts = <2>;
+ status = "disabled";
+ };
+ };
+
syscfg: system-config@40013800 {
compatible = "syscon";
reg = <0x40013800 0x400>;
@@ -334,6 +377,12 @@
slew-rate = <2>;
};
};
+
+ adc3_in8_pin: adc@200 {
+ pins {
+ pinmux = <STM32F429_PF10_FUNC_ANALOG>;
+ };
+ };
};
rcc: rcc@40023810 {
--
1.9.1
^ permalink raw reply related
* [PATCH 3/3] ARM: dts: stm32: enable ADC on stm32f429i-eval board
From: Fabrice Gasnier @ 2016-12-02 13:57 UTC (permalink / raw)
To: alexandre.torgue, mcoquelin.stm32, linux, mark.rutland, robh+dt
Cc: devicetree, linux-arm-kernel, linux-kernel
In-Reply-To: <1480687022-12851-1-git-send-email-fabrice.gasnier@st.com>
Enable analog to digital converter on stm32f429i-eval board.
It has on-board potentimeter wired to ADC3 in8 analog pin and
uses fixed regulator to provide reference voltage.
Signed-off-by: Fabrice Gasnier <fabrice.gasnier@st.com>
---
arch/arm/boot/dts/stm32429i-eval.dts | 25 +++++++++++++++++++++++++
1 file changed, 25 insertions(+)
diff --git a/arch/arm/boot/dts/stm32429i-eval.dts b/arch/arm/boot/dts/stm32429i-eval.dts
index 13c7cd2..6be0a24 100644
--- a/arch/arm/boot/dts/stm32429i-eval.dts
+++ b/arch/arm/boot/dts/stm32429i-eval.dts
@@ -65,6 +65,20 @@
serial0 = &usart1;
};
+ regulators {
+ compatible = "simple-bus";
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ reg_vref: regulator@0 {
+ compatible = "regulator-fixed";
+ reg = <0>;
+ regulator-name = "vref";
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ };
+ };
+
leds {
compatible = "gpio-leds";
green {
@@ -123,3 +137,14 @@
pinctrl-names = "default";
status = "okay";
};
+
+&adc {
+ pinctrl-names = "default";
+ pinctrl-0 = <&adc3_in8_pin>;
+ vref-supply = <®_vref>;
+ status = "okay";
+ adc3: adc@200 {
+ st,adc-channels = <8>;
+ status = "okay";
+ };
+};
--
1.9.1
^ permalink raw reply related
* Re: [PATCH v3 6/7] IIO: add STM32 timer trigger driver
From: Lee Jones @ 2016-12-02 13:57 UTC (permalink / raw)
To: Benjamin Gaignard
Cc: robh+dt-DgEjT+Ai2ygdnm+yROfE0A, mark.rutland-5wv7dgnIgG8,
alexandre.torgue-qxv4g6HH51o, devicetree-u79uwXL29TY76Z2rM5mHXA,
linux-kernel-u79uwXL29TY76Z2rM5mHXA,
thierry.reding-Re5JQEeQqe8AvxtiuMwx3w,
linux-pwm-u79uwXL29TY76Z2rM5mHXA, jic23-DgEjT+Ai2ygdnm+yROfE0A,
knaack.h-Mmb7MZpHnFY, lars-Qo5EllUWu/uELgA04lAiVw,
pmeerw-jW+XmwGofnusTnJN9+BGXg, linux-iio-u79uwXL29TY76Z2rM5mHXA,
linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r,
fabrice.gasnier-qxv4g6HH51o, gerald.baeza-qxv4g6HH51o,
arnaud.pouliquen-qxv4g6HH51o,
linus.walleij-QSEj5FYQhm4dnm+yROfE0A,
linaro-kernel-cunTk1MwBs8s++Sfvej+rw, Benjamin Gaignard
In-Reply-To: <1480673842-20804-7-git-send-email-benjamin.gaignard-qxv4g6HH51o@public.gmane.org>
On Fri, 02 Dec 2016, Benjamin Gaignard wrote:
> Timers IPs can be used to generate triggers for other IPs like
> DAC, ADC or other timers.
> Each trigger may result of timer internals signals like counter enable,
> reset or edge, this configuration could be done through "master_mode"
> device attribute.
>
> A timer device could be triggered by other timers, we use the trigger
> name and is_stm32_iio_timer_trigger() function to distinguish them
> and configure IP input switch.
>
> Timer may also decide on which event (edge, level) they could
> be activated by a trigger, this configuration is done by writing in
> "slave_mode" device attribute.
>
> Since triggers could also be used by DAC or ADC their names are defined
> in include/dt-bindings/iio/timer/st,stm32-iio-timer.h so those IPs will be able
> to configure themselves in valid_trigger function
>
> Trigger have a "sampling_frequency" attribute which allow to configure
> timer sampling frequency without using pwm interface
>
> version 3:
> - change compatible to "st,stm32-timer-trigger"
> - fix attributes access right
> - use string instead of int for master_mode and slave_mode
> - document device attributes in sysfs-bus-iio-timer-stm32
>
> version 2:
> - keep only one compatible
> - use st,input-triggers-names and st,output-triggers-names
> to know which triggers are accepted and/or create by the device
>
> Signed-off-by: Benjamin Gaignard <benjamin.gaignard-qxv4g6HH51o@public.gmane.org>
> ---
> .../ABI/testing/sysfs-bus-iio-timer-stm32 | 47 ++
> drivers/iio/Kconfig | 2 +-
> drivers/iio/Makefile | 1 +
> drivers/iio/timer/Kconfig | 15 +
> drivers/iio/timer/Makefile | 1 +
> drivers/iio/timer/stm32-timer-trigger.c | 477 +++++++++++++++++++++
> drivers/iio/trigger/Kconfig | 1 -
> .../iio/timer/st,stm32-timer-triggers.h | 60 +++
> include/linux/iio/timer/stm32-timer-trigger.h | 16 +
> 9 files changed, 618 insertions(+), 2 deletions(-)
> create mode 100644 Documentation/ABI/testing/sysfs-bus-iio-timer-stm32
> create mode 100644 drivers/iio/timer/Kconfig
> create mode 100644 drivers/iio/timer/Makefile
> create mode 100644 drivers/iio/timer/stm32-timer-trigger.c
> create mode 100644 include/dt-bindings/iio/timer/st,stm32-timer-triggers.h
> create mode 100644 include/linux/iio/timer/stm32-timer-trigger.h
>
> diff --git a/Documentation/ABI/testing/sysfs-bus-iio-timer-stm32 b/Documentation/ABI/testing/sysfs-bus-iio-timer-stm32
> new file mode 100644
> index 0000000..b70bb2a
> --- /dev/null
> +++ b/Documentation/ABI/testing/sysfs-bus-iio-timer-stm32
> @@ -0,0 +1,47 @@
> +What: /sys/bus/iio/devices/iio:deviceX/master_mode_available
> +KernelVersion: 4.10
> +Contact: benjamin.gaignard-qxv4g6HH51o@public.gmane.org
> +Description:
> + Reading returns the list possible master modes which are:
> + - "reset" : The UG bit from the TIMx_EGR register is used as trigger output (TRGO).
> + - "enable" : The Counter Enable signal CNT_EN is used as trigger output.
> + - "update" : The update event is selected as trigger output.
> + For instance a master timer can then be used as a prescaler for a slave timer.
> + - "compare_pulse" : The trigger output send a positive pulse when the CC1IF flag is to be set.
> + - "OC1REF" : OC1REF signal is used as trigger output.
> + - "OC2REF" : OC2REF signal is used as trigger output.
> + - "OC3REF" : OC3REF signal is used as trigger output.
> + - "OC4REF" : OC4REF signal is used as trigger output.
> +
> +What: /sys/bus/iio/devices/iio:deviceX/master_mode
> +KernelVersion: 4.10
> +Contact: benjamin.gaignard-qxv4g6HH51o@public.gmane.org
> +Description:
> + Reading returns the current master modes.
> + Writing set the master mode
> +
> +What: /sys/bus/iio/devices/iio:deviceX/slave_mode_available
> +KernelVersion: 4.10
> +Contact: benjamin.gaignard-qxv4g6HH51o@public.gmane.org
> +Description:
> + Reading returns the list possible slave modes which are:
> + - "disabled" : The prescaler is clocked directly by the internal clock.
> + - "encoder_1" : Counter counts up/down on TI2FP1 edge depending on TI1FP2 level.
> + - "encoder_2" : Counter counts up/down on TI1FP2 edge depending on TI2FP1 level.
> + - "encoder_3" : Counter counts up/down on both TI1FP1 and TI2FP2 edges depending
> + on the level of the other input.
> + - "reset" : Rising edge of the selected trigger input reinitializes the counter
> + and generates an update of the registers.
> + - "gated" : The counter clock is enabled when the trigger input is high.
> + The counter stops (but is not reset) as soon as the trigger becomes low.
> + Both start and stop of the counter are controlled.
> + - "trigger" : The counter starts at a rising edge of the trigger TRGI (but it is not
> + reset). Only the start of the counter is controlled.
> + - "external_clock": Rising edges of the selected trigger (TRGI) clock the counter.
> +
> +What: /sys/bus/iio/devices/iio:deviceX/slave_mode
> +KernelVersion: 4.10
> +Contact: benjamin.gaignard-qxv4g6HH51o@public.gmane.org
> +Description:
> + Reading returns the current slave mode.
> + Writing set the slave mode
> diff --git a/drivers/iio/Kconfig b/drivers/iio/Kconfig
> index 6743b18..2de2a80 100644
> --- a/drivers/iio/Kconfig
> +++ b/drivers/iio/Kconfig
> @@ -90,5 +90,5 @@ source "drivers/iio/potentiometer/Kconfig"
> source "drivers/iio/pressure/Kconfig"
> source "drivers/iio/proximity/Kconfig"
> source "drivers/iio/temperature/Kconfig"
> -
> +source "drivers/iio/timer/Kconfig"
> endif # IIO
> diff --git a/drivers/iio/Makefile b/drivers/iio/Makefile
> index 87e4c43..b797c08 100644
> --- a/drivers/iio/Makefile
> +++ b/drivers/iio/Makefile
> @@ -32,4 +32,5 @@ obj-y += potentiometer/
> obj-y += pressure/
> obj-y += proximity/
> obj-y += temperature/
> +obj-y += timer/
> obj-y += trigger/
> diff --git a/drivers/iio/timer/Kconfig b/drivers/iio/timer/Kconfig
> new file mode 100644
> index 0000000..149a917
> --- /dev/null
> +++ b/drivers/iio/timer/Kconfig
> @@ -0,0 +1,15 @@
> +#
> +# Timers drivers
> +
> +menu "Timers"
> +
> +config IIO_STM32_TIMER_TRIGGER
> + tristate "stm32 timer trigger"
"STM32 Timer Trigger"
> + depends on ARCH_STM32
> + depends on OF
Are these build or run time dependencies?
If they are only run-time, add "|| COMPILE_TEST".
> + select IIO_TRIGGERED_EVENT
> + select MFD_STM32_GP_TIMER
> + help
> + Select this option to enable stm32 timer trigger
> +
> +endmenu
> diff --git a/drivers/iio/timer/Makefile b/drivers/iio/timer/Makefile
> new file mode 100644
> index 0000000..4ad95ec9
> --- /dev/null
> +++ b/drivers/iio/timer/Makefile
> @@ -0,0 +1 @@
> +obj-$(CONFIG_IIO_STM32_TIMER_TRIGGER) += stm32-timer-trigger.o
> diff --git a/drivers/iio/timer/stm32-timer-trigger.c b/drivers/iio/timer/stm32-timer-trigger.c
> new file mode 100644
> index 0000000..0c51601
> --- /dev/null
> +++ b/drivers/iio/timer/stm32-timer-trigger.c
> @@ -0,0 +1,477 @@
> +/*
> + * stm32-iio-timer.c
Swap this out for a description.
Filenames have a habit of becoming out-of-date.
> + * Copyright (C) STMicroelectronics 2016
'\n'
> + * Author: Benjamin Gaignard <benjamin.gaignard-qxv4g6HH51o@public.gmane.org> for STMicroelectronics.
You don't need to put the "for" bit. That's just what we do when
Linaro are writing drivers for other companies. Your email address
says enough.
> + * License terms: GNU General Public License (GPL), version 2
> + */
> +
> +#include <linux/iio/iio.h>
> +#include <linux/iio/sysfs.h>
> +#include <linux/iio/timer/stm32-timer-trigger.h>
> +#include <linux/iio/trigger.h>
> +#include <linux/iio/triggered_event.h>
> +#include <linux/interrupt.h>
> +#include <linux/mfd/stm32-gptimer.h>
> +#include <linux/module.h>
> +#include <linux/platform_device.h>
> +
> +#define DRIVER_NAME "stm32-timer-trigger"
Just use the name in the correct places. Defining device names is an
ugly practice IMHO.
> +#define MAX_MODES 8
> +
> +struct stm32_timer_trigger_dev {
> + struct device *dev;
> + struct regmap *regmap;
> + struct clk *clk;
> + int irq;
> + bool own_timer;
> + unsigned int sampling_frequency;
> + struct iio_trigger *active_trigger;
> +};
> +
> +static ssize_t _store_frequency(struct device *dev,
What's with the '_' naming scheme?
> + struct device_attribute *attr,
> + const char *buf, size_t len)
> +{
> + struct iio_trigger *trig = to_iio_trigger(dev);
> + struct stm32_timer_trigger_dev *stm32 = iio_trigger_get_drvdata(trig);
> + unsigned int freq;
> + int ret;
> +
> + ret = kstrtouint(buf, 10, &freq);
> + if (ret)
> + return ret;
No bounds checking required?
> + stm32->sampling_frequency = freq;
Where is this value placed into the registers?
> + return len;
> +}
> +
> +static ssize_t _read_frequency(struct device *dev,
> + struct device_attribute *attr, char *buf)
> +{
> + struct iio_trigger *trig = to_iio_trigger(dev);
> + struct stm32_timer_trigger_dev *stm32 = iio_trigger_get_drvdata(trig);
> + unsigned long long freq = stm32->sampling_frequency;
> + u32 psc, arr, cr1;
> +
> + regmap_read(stm32->regmap, TIM_CR1, &cr1);
> + regmap_read(stm32->regmap, TIM_PSC, &psc);
> + regmap_read(stm32->regmap, TIM_ARR, &arr);
> +
> + if (psc && arr && (cr1 & TIM_CR1_CEN)) {
> + freq = (unsigned long long)clk_get_rate(stm32->clk);
> + do_div(freq, psc);
> + do_div(freq, arr);
> + }
> +
> + return sprintf(buf, "%d\n", (unsigned int)freq);
> +}
> +
> +static IIO_DEV_ATTR_SAMP_FREQ(0660, _read_frequency, _store_frequency);
> +
> +static struct attribute *stm32_trigger_attrs[] = {
> + &iio_dev_attr_sampling_frequency.dev_attr.attr,
> + NULL,
> +};
> +
> +static const struct attribute_group stm32_trigger_attr_group = {
> + .attrs = stm32_trigger_attrs,
> +};
> +
> +static const struct attribute_group *stm32_trigger_attr_groups[] = {
> + &stm32_trigger_attr_group,
> + NULL,
> +};
A lot of generic code here.
Are there macros that could help with this?
> +static char *master_mode_table[] = {
> + "reset",
> + "enable",
> + "update",
> + "compare_pulse",
> + "OC1REF",
> + "OC2REF",
> + "OC3REF",
> + "OC4REF"
> +};
> +
> +static
Why the line break here?
[and the ones below]
> +ssize_t _show_master_mode(struct device *dev,
> + struct device_attribute *attr, char *buf)
> +{
> + struct iio_dev *indio_dev = dev_to_iio_dev(dev);
> + struct stm32_timer_trigger_dev *stm32 = iio_priv(indio_dev);
> + u32 cr2;
> +
> + regmap_read(stm32->regmap, TIM_CR2, &cr2);
> + cr2 = (cr2 >> 4) & 0x7;
Define these SHIFT and MASK values.
> + return snprintf(buf, PAGE_SIZE, "%s\n", master_mode_table[cr2]);
> +}
> +
> +static
> +ssize_t _store_master_mode(struct device *dev,
> + struct device_attribute *attr,
> + const char *buf, size_t len)
> +{
> + struct iio_dev *indio_dev = dev_to_iio_dev(dev);
> + struct stm32_timer_trigger_dev *stm32 = iio_priv(indio_dev);
> + int i;
> +
> + for (i = 0; i < ARRAY_SIZE(master_mode_table); i++) {
> + if (!strncmp(master_mode_table[i], buf,
> + strlen(master_mode_table[i]))) {
> + regmap_update_bits(stm32->regmap, TIM_CR2,
> + TIM_CR2_MMS, i << 4);
Define all of the SHIFT and MASK values in this set.
> + return len;
> + }
> + }
> +
> + return -EINVAL;
> +}
> +
> +static IIO_CONST_ATTR(master_mode_available,
> + "reset enable update compare_pulse OC1REF OC2REF OC3REF OC4REF");
> +
> +static IIO_DEVICE_ATTR(master_mode, 0660,
> + _show_master_mode,
> + _store_master_mode,
> + 0);
> +
> +static char *slave_mode_table[] = {
> + "disabled",
> + "encoder_1",
> + "encoder_2",
> + "encoder_3",
> + "reset",
> + "gated",
> + "trigger",
> + "external_clock",
> +};
> +
> +static
> +ssize_t _show_slave_mode(struct device *dev,
> + struct device_attribute *attr, char *buf)
> +{
> + struct iio_dev *indio_dev = dev_to_iio_dev(dev);
> + struct stm32_timer_trigger_dev *stm32 = iio_priv(indio_dev);
> + u32 smcr;
> +
> + regmap_read(stm32->regmap, TIM_SMCR, &smcr);
> + smcr &= 0x7;
> +
> + return snprintf(buf, PAGE_SIZE, "%s\n", slave_mode_table[smcr]);
> +}
> +
> +static
> +ssize_t _store_slave_mode(struct device *dev,
> + struct device_attribute *attr,
> + const char *buf, size_t len)
> +{
> + struct iio_dev *indio_dev = dev_to_iio_dev(dev);
> + struct stm32_timer_trigger_dev *stm32 = iio_priv(indio_dev);
> + int i;
> +
> + for (i = 0; i < ARRAY_SIZE(slave_mode_table); i++) {
> + if (!strncmp(slave_mode_table[i], buf,
> + strlen(slave_mode_table[i]))) {
> + regmap_update_bits(stm32->regmap,
> + TIM_SMCR, TIM_SMCR_SMS, i);
> + return len;
> + }
> + }
> +
> + return -EINVAL;
> +}
> +
> +static IIO_CONST_ATTR(slave_mode_available,
> + "disabled encoder_1 encoder_2 encoder_3 reset gated trigger external_clock");
> +
> +static IIO_DEVICE_ATTR(slave_mode, 0660,
> + _show_slave_mode,
> + _store_slave_mode,
> + 0);
> +
> +static struct attribute *stm32_timer_attrs[] = {
> + &iio_dev_attr_master_mode.dev_attr.attr,
> + &iio_const_attr_master_mode_available.dev_attr.attr,
> + &iio_dev_attr_slave_mode.dev_attr.attr,
> + &iio_const_attr_slave_mode_available.dev_attr.attr,
> + NULL,
> +};
> +
> +static const struct attribute_group stm32_timer_attr_group = {
> + .attrs = stm32_timer_attrs,
> +};
> +
> +static int stm32_timer_start(struct stm32_timer_trigger_dev *stm32)
> +{
> + unsigned long long prd, div;
> + int prescaler = 0;
> + u32 max_arr = 0xFFFF, cr1;
Since this is const, it'll be better of as a define.
> + if (stm32->sampling_frequency == 0)
> + return 0;
Is this okay? Or is this an error?
> + /* Period and prescaler values depends of clock rate */
> + div = (unsigned long long)clk_get_rate(stm32->clk);
> +
> + do_div(div, stm32->sampling_frequency);
> +
> + prd = div;
> +
> + while (div > max_arr) {
> + prescaler++;
> + div = prd;
> + do_div(div, (prescaler + 1));
> + }
> + prd = div;
Best to place a comment here. Saves the reader having to work it out.
> + if (prescaler > MAX_TIM_PSC) {
> + dev_err(stm32->dev, "prescaler exceeds the maximum value\n");
> + return -EINVAL;
> + }
> +
> + /* Check that we own the timer */
> + regmap_read(stm32->regmap, TIM_CR1, &cr1);
> + if ((cr1 & TIM_CR1_CEN) && !stm32->own_timer)
> + return -EBUSY;
What happens if the timer is already enabled and you do own it?
I guess this *re*-starts it?
> + if (!stm32->own_timer) {
> + stm32->own_timer = true;
> + clk_enable(stm32->clk);
> + }
At the very least you're going to require some shared locking here.
At best you should have a shared "device held" flag.
> + regmap_write(stm32->regmap, TIM_PSC, prescaler);
> + regmap_write(stm32->regmap, TIM_ARR, prd - 1);
> + regmap_update_bits(stm32->regmap, TIM_CR1, TIM_CR1_ARPE, TIM_CR1_ARPE);
> +
> + /* Force master mode to update mode */
> + regmap_update_bits(stm32->regmap, TIM_CR2, TIM_CR2_MMS, 0x20);
> +
> + /* Make sure that registers are updated */
> + regmap_update_bits(stm32->regmap, TIM_EGR, TIM_EGR_UG, TIM_EGR_UG);
> +
> + /* Enable interrupt */
> + regmap_write(stm32->regmap, TIM_SR, 0);
> + regmap_update_bits(stm32->regmap, TIM_DIER, TIM_DIER_UIE, TIM_DIER_UIE);
> +
> + /* Enable controller */
> + regmap_update_bits(stm32->regmap, TIM_CR1, TIM_CR1_CEN, TIM_CR1_CEN);
> +
> + return 0;
> +}
> +
> +static int stm32_timer_stop(struct stm32_timer_trigger_dev *stm32)
> +{
> + if (!stm32->own_timer)
> + return 0;
> +
> + /* Stop timer */
> + regmap_update_bits(stm32->regmap, TIM_DIER, TIM_DIER_UIE, 0);
> + regmap_update_bits(stm32->regmap, TIM_CR1, TIM_CR1_CEN, 0);
> + regmap_write(stm32->regmap, TIM_PSC, 0);
> + regmap_write(stm32->regmap, TIM_ARR, 0);
> +
> + clk_disable(stm32->clk);
> +
> + stm32->own_timer = false;
> + stm32->active_trigger = NULL;
> +
> + return 0;
> +}
> +
> +static int stm32_set_trigger_state(struct iio_trigger *trig, bool state)
> +{
> + struct stm32_timer_trigger_dev *stm32 = iio_trigger_get_drvdata(trig);
> +
> + stm32->active_trigger = trig;
> +
> + if (state)
> + return stm32_timer_start(stm32);
> + else
> + return stm32_timer_stop(stm32);
> +}
> +
> +static irqreturn_t stm32_timer_irq_handler(int irq, void *private)
> +{
> + struct stm32_timer_trigger_dev *stm32 = private;
> + u32 sr;
> +
> + regmap_read(stm32->regmap, TIM_SR, &sr);
> + regmap_write(stm32->regmap, TIM_SR, 0);
> +
> + if ((sr & TIM_SR_UIF) && stm32->active_trigger)
> + iio_trigger_poll(stm32->active_trigger);
> +
> + return IRQ_HANDLED;
> +}
> +
> +static const struct iio_trigger_ops timer_trigger_ops = {
> + .owner = THIS_MODULE,
> + .set_trigger_state = stm32_set_trigger_state,
> +};
> +
> +static int stm32_setup_iio_triggers(struct stm32_timer_trigger_dev *stm32)
> +{
> + int ret;
> + struct property *p;
> + const char *cur = NULL;
> +
> + p = of_find_property(stm32->dev->of_node,
> + "st,output-triggers-names", NULL);
> +
> + while ((cur = of_prop_next_string(p, cur)) != NULL) {
> + struct iio_trigger *trig;
> +
> + trig = devm_iio_trigger_alloc(stm32->dev, "%s", cur);
> + if (!trig)
> + return -ENOMEM;
> +
> + trig->dev.parent = stm32->dev->parent;
> + trig->ops = &timer_trigger_ops;
> + trig->dev.groups = stm32_trigger_attr_groups;
> + iio_trigger_set_drvdata(trig, stm32);
> +
> + ret = devm_iio_trigger_register(stm32->dev, trig);
> + if (ret)
> + return ret;
> + }
> +
> + return 0;
> +}
> +
> +/**
> + * is_stm32_timer_trigger
> + * @trig: trigger to be checked
> + *
> + * return true if the trigger is a valid stm32 iio timer trigger
> + * either return false
> + */
> +bool is_stm32_timer_trigger(struct iio_trigger *trig)
> +{
> + return (trig->ops == &timer_trigger_ops);
> +}
> +EXPORT_SYMBOL(is_stm32_timer_trigger);
> +
> +static int stm32_validate_trigger(struct iio_dev *indio_dev,
> + struct iio_trigger *trig)
> +{
> + struct stm32_timer_trigger_dev *dev = iio_priv(indio_dev);
> + int ret;
> +
> + if (!is_stm32_timer_trigger(trig))
> + return -EINVAL;
> +
> + ret = of_property_match_string(dev->dev->of_node,
> + "st,input-triggers-names",
> + trig->name);
> +
> + if (ret < 0)
> + return ret;
> +
> + regmap_update_bits(dev->regmap, TIM_SMCR, TIM_SMCR_TS, ret << 4);
> +
> + return 0;
> +}
> +
> +static const struct iio_info stm32_trigger_info = {
> + .driver_module = THIS_MODULE,
> + .validate_trigger = stm32_validate_trigger,
> + .attrs = &stm32_timer_attr_group,
> +};
> +
> +static struct stm32_timer_trigger_dev *stm32_setup_iio_device(struct device *dev)
> +{
> + struct iio_dev *indio_dev;
> + int ret;
> + indio_dev = devm_iio_device_alloc(dev, sizeof(struct stm32_timer_trigger_dev));
Did you run checkpatch.pl?
> + if (!indio_dev)
> + return NULL;
> +
> + indio_dev->name = dev_name(dev);
> + indio_dev->dev.parent = dev;
> + indio_dev->info = &stm32_trigger_info;
> + indio_dev->modes = INDIO_EVENT_TRIGGERED;
> + indio_dev->num_channels = 0;
> + indio_dev->dev.of_node = dev->of_node;
> +
> + ret = iio_triggered_event_setup(indio_dev,
> + NULL,
> + stm32_timer_irq_handler);
> + if (ret)
> + return NULL;
Return ERR_PTR(ret).
> + ret = devm_iio_device_register(dev, indio_dev);
> + if (ret) {
> + iio_triggered_event_cleanup(indio_dev);
> + return NULL;
Return ERR_PTR(ret).
> + }
> +
> + return iio_priv(indio_dev);
> +}
> +
> +static int stm32_timer_trigger_probe(struct platform_device *pdev)
> +{
> + struct device *dev = &pdev->dev;
> + struct stm32_timer_trigger_dev *stm32;
> + struct stm32_gptimer_dev *mfd = dev_get_drvdata(pdev->dev.parent);
> + int ret;
> +
> + stm32 = stm32_setup_iio_device(dev);
> + if (!stm32)
> + return -ENOMEM;
Return stm32.
> + stm32->dev = dev;
> + stm32->regmap = mfd->regmap;
> + stm32->clk = mfd->clk;
> +
> + stm32->irq = platform_get_irq(pdev, 0);
> + if (stm32->irq < 0)
> + return -EINVAL;
return stm32->irq.
> + ret = devm_request_irq(stm32->dev, stm32->irq,
> + stm32_timer_irq_handler, IRQF_SHARED,
> + "timer_event", stm32);
> + if (ret)
> + return ret;
> +
> + ret = stm32_setup_iio_triggers(stm32);
> + if (ret)
> + return ret;
> +
> + platform_set_drvdata(pdev, stm32);
> +
> + return 0;
> +}
> +
> +static int stm32_timer_trigger_remove(struct platform_device *pdev)
> +{
> + struct stm32_timer_trigger_dev *stm32 = platform_get_drvdata(pdev);
> +
> + iio_triggered_event_cleanup((struct iio_dev *)stm32);
> +
> + return 0;
> +}
> +
> +static const struct of_device_id stm32_trig_of_match[] = {
> + {
> + .compatible = "st,stm32-timer-trigger",
> + },
> +};
Make this one line.
{ .compatible = "st,stm32-timer-trigger" },
> +MODULE_DEVICE_TABLE(of, stm32_trig_of_match);
> +
> +static struct platform_driver stm32_timer_trigger_driver = {
> + .probe = stm32_timer_trigger_probe,
> + .remove = stm32_timer_trigger_remove,
> + .driver = {
> + .name = DRIVER_NAME,
Yuk!
> + .of_match_table = stm32_trig_of_match,
> + },
> +};
> +module_platform_driver(stm32_timer_trigger_driver);
> +
> +MODULE_ALIAS("platform:" DRIVER_NAME);
> +MODULE_DESCRIPTION("STMicroelectronics STM32 timer trigger driver");
> +MODULE_LICENSE("GPL");
I thought this was "GPL v2"?
> diff --git a/drivers/iio/trigger/Kconfig b/drivers/iio/trigger/Kconfig
> index 809b2e7..f2af4fe 100644
> --- a/drivers/iio/trigger/Kconfig
> +++ b/drivers/iio/trigger/Kconfig
> @@ -46,5 +46,4 @@ config IIO_SYSFS_TRIGGER
>
> To compile this driver as a module, choose M here: the
> module will be called iio-trig-sysfs.
> -
> endmenu
> diff --git a/include/dt-bindings/iio/timer/st,stm32-timer-triggers.h b/include/dt-bindings/iio/timer/st,stm32-timer-triggers.h
> new file mode 100644
> index 0000000..a13db63
> --- /dev/null
> +++ b/include/dt-bindings/iio/timer/st,stm32-timer-triggers.h
> @@ -0,0 +1,60 @@
> +/*
> + * st,stm32-timer-triggers.h
> + * Copyright (C) STMicroelectronics 2016
> + * Author: Benjamin Gaignard <benjamin.gaignard-qxv4g6HH51o@public.gmane.org> for STMicroelectronics.
> + * License terms: GNU General Public License (GPL), version 2
> + */
Same comments as the top header.
> +#ifndef _DT_BINDINGS_STM32_TIMER_TRIGGERS_H_
> +#define _DT_BINDINGS_STM32_TIMER_TRIGGERS_H_
> +
> +#define TIM1_TRGO "tim1_trgo"
> +#define TIM1_CH1 "tim1_ch1"
> +#define TIM1_CH2 "tim1_ch2"
> +#define TIM1_CH3 "tim1_ch3"
> +#define TIM1_CH4 "tim1_ch4"
> +
> +#define TIM2_TRGO "tim2_trgo"
> +#define TIM2_CH1 "tim2_ch1"
> +#define TIM2_CH2 "tim2_ch2"
> +#define TIM2_CH3 "tim2_ch3"
> +#define TIM2_CH4 "tim2_ch4"
> +
> +#define TIM3_TRGO "tim3_trgo"
> +#define TIM3_CH1 "tim3_ch1"
> +#define TIM3_CH2 "tim3_ch2"
> +#define TIM3_CH3 "tim3_ch3"
> +#define TIM3_CH4 "tim3_ch4"
> +
> +#define TIM4_TRGO "tim4_trgo"
> +#define TIM4_CH1 "tim4_ch1"
> +#define TIM4_CH2 "tim4_ch2"
> +#define TIM4_CH3 "tim4_ch3"
> +#define TIM4_CH4 "tim4_ch4"
> +
> +#define TIM5_TRGO "tim5_trgo"
> +#define TIM5_CH1 "tim5_ch1"
> +#define TIM5_CH2 "tim5_ch2"
> +#define TIM5_CH3 "tim5_ch3"
> +#define TIM5_CH4 "tim5_ch4"
> +
> +#define TIM6_TRGO "tim6_trgo"
> +
> +#define TIM7_TRGO "tim7_trgo"
> +
> +#define TIM8_TRGO "tim8_trgo"
> +#define TIM8_CH1 "tim8_ch1"
> +#define TIM8_CH2 "tim8_ch2"
> +#define TIM8_CH3 "tim8_ch3"
> +#define TIM8_CH4 "tim8_ch4"
> +
> +#define TIM9_TRGO "tim9_trgo"
> +#define TIM9_CH1 "tim9_ch1"
> +#define TIM9_CH2 "tim9_ch2"
> +
> +#define TIM12_TRGO "tim12_trgo"
> +#define TIM12_CH1 "tim12_ch1"
> +#define TIM12_CH2 "tim12_ch2"
Grim!
uint8 valid_timers[] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 12 };
uint8 valid_channels[] = { 0, 1, 2, 3, 4 };
> +#endif
> diff --git a/include/linux/iio/timer/stm32-timer-trigger.h b/include/linux/iio/timer/stm32-timer-trigger.h
> new file mode 100644
> index 0000000..c22fb3b
> --- /dev/null
> +++ b/include/linux/iio/timer/stm32-timer-trigger.h
> @@ -0,0 +1,16 @@
> +/*
> + * stm32-timer-trigger.h
> + * Copyright (C) STMicroelectronics 2016
> + * Author: Benjamin Gaignard <benjamin.gaignard-qxv4g6HH51o@public.gmane.org> for STMicroelectronics.
> + * License terms: GNU General Public License (GPL), version 2
> + */
Same comments as the top header.
> +#ifndef _STM32_TIMER_TRIGGER_H_
> +#define _STM32_TIMER_TRIGGER_H_
> +
> +#include <dt-bindings/iio/timer/st,stm32-timer-triggers.h>
> +
> +bool is_stm32_timer_trigger(struct iio_trigger *trig);
> +
> +#endif
--
Lee Jones
Linaro STMicroelectronics Landing Team Lead
Linaro.org │ Open source software for ARM SoCs
Follow Linaro: Facebook | Twitter | Blog
--
To unsubscribe from this list: send the line "unsubscribe devicetree" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
^ permalink raw reply
* Re: [PATCH v3 5/7] IIO: add bindings for stm32 timer trigger driver
From: Lee Jones @ 2016-12-02 13:59 UTC (permalink / raw)
To: Benjamin Gaignard
Cc: robh+dt-DgEjT+Ai2ygdnm+yROfE0A, mark.rutland-5wv7dgnIgG8,
alexandre.torgue-qxv4g6HH51o, devicetree-u79uwXL29TY76Z2rM5mHXA,
linux-kernel-u79uwXL29TY76Z2rM5mHXA,
thierry.reding-Re5JQEeQqe8AvxtiuMwx3w,
linux-pwm-u79uwXL29TY76Z2rM5mHXA, jic23-DgEjT+Ai2ygdnm+yROfE0A,
knaack.h-Mmb7MZpHnFY, lars-Qo5EllUWu/uELgA04lAiVw,
pmeerw-jW+XmwGofnusTnJN9+BGXg, linux-iio-u79uwXL29TY76Z2rM5mHXA,
linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r,
fabrice.gasnier-qxv4g6HH51o, gerald.baeza-qxv4g6HH51o,
arnaud.pouliquen-qxv4g6HH51o,
linus.walleij-QSEj5FYQhm4dnm+yROfE0A,
linaro-kernel-cunTk1MwBs8s++Sfvej+rw, Benjamin Gaignard
In-Reply-To: <1480673842-20804-6-git-send-email-benjamin.gaignard-qxv4g6HH51o@public.gmane.org>
On Fri, 02 Dec 2016, Benjamin Gaignard wrote:
> Define bindings for stm32 timer trigger
>
> version 3:
> - change file name
> - add cross reference with mfd bindings
>
> version 2:
> - only keep one compatible
> - add DT parameters to set lists of the triggers:
> one list describe the triggers created by the device
> another one give the triggers accepted by the device
>
> Signed-off-by: Benjamin Gaignard <benjamin.gaignard-qxv4g6HH51o@public.gmane.org>
> ---
> .../bindings/iio/timer/stm32-timer-trigger.txt | 39 ++++++++++++++++++++++
> 1 file changed, 39 insertions(+)
> create mode 100644 Documentation/devicetree/bindings/iio/timer/stm32-timer-trigger.txt
>
> diff --git a/Documentation/devicetree/bindings/iio/timer/stm32-timer-trigger.txt b/Documentation/devicetree/bindings/iio/timer/stm32-timer-trigger.txt
> new file mode 100644
> index 0000000..858816d
> --- /dev/null
> +++ b/Documentation/devicetree/bindings/iio/timer/stm32-timer-trigger.txt
> @@ -0,0 +1,39 @@
> +timer trigger bindings for STM32
> +
> +Must be a sub-node of STM32 general purpose timer driver
> +Parent node properties are describe in ../mfd/stm32-general-purpose-timer.txt
> +
> +Required parameters:
> +- compatible: must be "st,stm32-iio-timer"
> +- interrupts: Interrupt for this device
> + See ../interrupt-controller/st,stm32-exti.txt
> +
> +Optional parameters:
> +- st,input-triggers-names: List of the possible input triggers for
> + the device
> +- st,output-triggers-names: List of the possible output triggers for
> + the device
> +
> +Possible triggers are defined in include/dt-bindings/iio/timer/st,stm32-timer-trigger.h
> +
> +Example:
> + gptimer1: gptimer1@40010000 {
> + compatible = "st,stm32-gptimer";
> + reg = <0x40010000 0x400>;
> + clocks = <&rcc 0 160>;
> + clock-names = "clk_int";
> +
> + timer1@0 {
> + compatible = "st,stm32-timer-trigger";
> + interrupts = <27>;
> + st,input-triggers-names = TIM5_TRGO,
> + TIM2_TRGO,
> + TIM4_TRGO,
> + TIM3_TRGO;
> + st,output-triggers-names = TIM1_TRGO,
> + TIM1_CH1,
> + TIM1_CH2,
> + TIM1_CH3,
> + TIM1_CH4;
I see why you've done it like this now ... because it makes things
easier for you in the driver, since the IIO subsystem matches on names
such as these.
BUT, this is a Linux-implementation-ism. Just use pairs of integers
and create the Linux-ism strings in the driver.
> + };
> + };
--
Lee Jones
Linaro STMicroelectronics Landing Team Lead
Linaro.org │ Open source software for ARM SoCs
Follow Linaro: Facebook | Twitter | Blog
^ permalink raw reply
* [PATCH 0/8] Add support for STM32 RTC
From: Amelie Delaunay @ 2016-12-02 14:09 UTC (permalink / raw)
To: a.zummo-BfzFCNDTiLLj+vYz1yj4TQ,
alexandre.belloni-wi1+55ScJUtKEb57/3fJTNBPR1lH4CV8,
robh+dt-DgEjT+Ai2ygdnm+yROfE0A, mark.rutland-5wv7dgnIgG8,
mcoquelin.stm32-Re5JQEeQqe8AvxtiuMwx3w,
alexandre.torgue-qxv4g6HH51o, linux-I+IVW8TIWO2tmTQ+vhA3Yw
Cc: rtc-linux-/JYPxA39Uh5TLH3MbocFFw,
devicetree-u79uwXL29TY76Z2rM5mHXA,
linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r,
linux-kernel-u79uwXL29TY76Z2rM5mHXA,
gabriel.fernandez-qxv4g6HH51o, amelie.delaunay-qxv4g6HH51o
This patchset adds support for the STM32 Real-Time Clock.
This RTC is an independent BCD timer/counter and provides a time-of-day
clock/calendar with programmable alarm interrupt.
RTC calendar can be driven by three clock sources LSE, LSI or HSE.
Amelie Delaunay (8):
ARM: dts: stm32: set HSE_RTC clock frequency to 1 MHz on stm32f429
dt-bindings: document the STM32 RTC bindings
rtc: add STM32 RTC driver
ARM: dts: stm32: Add STM32 RTC support for STM32F429 MCU
ARM: dts: stm32: enable RTC on stm32f429-disco
ARM: dts: stm32: enable RTC on stm32f469-disco
ARM: dts: stm32: enable RTC on stm32429i-eval
ARM: configs: stm32: Add STM32 RTC support in STM32 defconfig
.../devicetree/bindings/rtc/st,stm32-rtc.txt | 31 +
arch/arm/boot/dts/stm32429i-eval.dts | 4 +
arch/arm/boot/dts/stm32f429-disco.dts | 6 +
arch/arm/boot/dts/stm32f429.dtsi | 16 +
arch/arm/boot/dts/stm32f469-disco.dts | 4 +
arch/arm/configs/stm32_defconfig | 2 +
drivers/rtc/Kconfig | 10 +
drivers/rtc/Makefile | 1 +
drivers/rtc/rtc-stm32.c | 777 +++++++++++++++++++++
9 files changed, 851 insertions(+)
create mode 100644 Documentation/devicetree/bindings/rtc/st,stm32-rtc.txt
create mode 100644 drivers/rtc/rtc-stm32.c
--
1.9.1
--
You received this message because you are subscribed to "rtc-linux".
Membership options at http://groups.google.com/group/rtc-linux .
Please read http://groups.google.com/group/rtc-linux/web/checklist
before submitting a driver.
---
You received this message because you are subscribed to the Google Groups "rtc-linux" group.
To unsubscribe from this group and stop receiving emails from it, send an email to rtc-linux+unsubscribe-/JYPxA39Uh5TLH3MbocFF+G/Ez6ZCGd0@public.gmane.org
For more options, visit https://groups.google.com/d/optout.
^ permalink raw reply
* [PATCH 1/8] ARM: dts: stm32: set HSE_RTC clock frequency to 1 MHz on stm32f429
From: Amelie Delaunay @ 2016-12-02 14:09 UTC (permalink / raw)
To: a.zummo-BfzFCNDTiLLj+vYz1yj4TQ,
alexandre.belloni-wi1+55ScJUtKEb57/3fJTNBPR1lH4CV8,
robh+dt-DgEjT+Ai2ygdnm+yROfE0A, mark.rutland-5wv7dgnIgG8,
mcoquelin.stm32-Re5JQEeQqe8AvxtiuMwx3w,
alexandre.torgue-qxv4g6HH51o, linux-I+IVW8TIWO2tmTQ+vhA3Yw
Cc: rtc-linux-/JYPxA39Uh5TLH3MbocFFw,
devicetree-u79uwXL29TY76Z2rM5mHXA,
linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r,
linux-kernel-u79uwXL29TY76Z2rM5mHXA,
gabriel.fernandez-qxv4g6HH51o, amelie.delaunay-qxv4g6HH51o
In-Reply-To: <1480687801-19525-2-git-send-email-amelie.delaunay-qxv4g6HH51o@public.gmane.org>
This patch set HSE_RTC clock frequency to 1 MHz, as the clock supplied to
the RTC must be 1 MHz.
Signed-off-by: Amelie Delaunay <amelie.delaunay-qxv4g6HH51o@public.gmane.org>
---
arch/arm/boot/dts/stm32f429.dtsi | 2 ++
1 file changed, 2 insertions(+)
diff --git a/arch/arm/boot/dts/stm32f429.dtsi b/arch/arm/boot/dts/stm32f429.dtsi
index b077f99..d195ccf 100644
--- a/arch/arm/boot/dts/stm32f429.dtsi
+++ b/arch/arm/boot/dts/stm32f429.dtsi
@@ -371,6 +371,8 @@
reg = <0x40023800 0x400>;
clocks = <&clk_hse>, <&clk_i2s_ckin>;
st,syscfg = <&pwrcfg>;
+ assigned-clocks = <&rcc 1 CLK_HSE_RTC>;
+ assigned-clock-rates = <1000000>;
};
dma1: dma-controller@40026000 {
--
1.9.1
--
You received this message because you are subscribed to "rtc-linux".
Membership options at http://groups.google.com/group/rtc-linux .
Please read http://groups.google.com/group/rtc-linux/web/checklist
before submitting a driver.
---
You received this message because you are subscribed to the Google Groups "rtc-linux" group.
To unsubscribe from this group and stop receiving emails from it, send an email to rtc-linux+unsubscribe-/JYPxA39Uh5TLH3MbocFF+G/Ez6ZCGd0@public.gmane.org
For more options, visit https://groups.google.com/d/optout.
^ permalink raw reply related
* [PATCH 2/8] dt-bindings: document the STM32 RTC bindings
From: Amelie Delaunay @ 2016-12-02 14:09 UTC (permalink / raw)
To: a.zummo-BfzFCNDTiLLj+vYz1yj4TQ,
alexandre.belloni-wi1+55ScJUtKEb57/3fJTNBPR1lH4CV8,
robh+dt-DgEjT+Ai2ygdnm+yROfE0A, mark.rutland-5wv7dgnIgG8,
mcoquelin.stm32-Re5JQEeQqe8AvxtiuMwx3w,
alexandre.torgue-qxv4g6HH51o, linux-I+IVW8TIWO2tmTQ+vhA3Yw
Cc: rtc-linux-/JYPxA39Uh5TLH3MbocFFw,
devicetree-u79uwXL29TY76Z2rM5mHXA,
linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r,
linux-kernel-u79uwXL29TY76Z2rM5mHXA,
gabriel.fernandez-qxv4g6HH51o, amelie.delaunay-qxv4g6HH51o
In-Reply-To: <1480687801-19525-2-git-send-email-amelie.delaunay-qxv4g6HH51o@public.gmane.org>
This patch adds documentation of device tree bindings for the STM32 RTC.
Signed-off-by: Amelie Delaunay <amelie.delaunay-qxv4g6HH51o@public.gmane.org>
---
.../devicetree/bindings/rtc/st,stm32-rtc.txt | 31 ++++++++++++++++++++++
1 file changed, 31 insertions(+)
create mode 100644 Documentation/devicetree/bindings/rtc/st,stm32-rtc.txt
diff --git a/Documentation/devicetree/bindings/rtc/st,stm32-rtc.txt b/Documentation/devicetree/bindings/rtc/st,stm32-rtc.txt
new file mode 100644
index 0000000..4578838
--- /dev/null
+++ b/Documentation/devicetree/bindings/rtc/st,stm32-rtc.txt
@@ -0,0 +1,31 @@
+STM32 Real Time Clock
+
+Required properties:
+- compatible: "st,stm32-rtc".
+- reg: address range of rtc register set.
+- clocks: reference to the clock entry ck_rtc.
+- clock-names: name of the clock used. Should be "ck_rtc".
+- interrupt-parent: phandle for the interrupt controller.
+- interrupts: rtc alarm interrupt.
+- interrupt-names: rtc alarm interrupt name, should be "alarm".
+- st,syscfg: phandle for pwrcfg, mandatory to disable/enable backup domain
+ (RTC registers) write protection.
+
+Optional properties (to override default ck_rtc parent clock):
+- assigned-clocks: reference to the ck_rtc clock entry.
+- assigned-clock-parents: phandle of the new parent clock of ck_rtc.
+
+Example:
+
+ rtc: rtc@40002800 {
+ compatible = "st,stm32-rtc";
+ reg = <0x40002800 0x400>;
+ clocks = <&rcc 1 CLK_RTC>;
+ clock-names = "ck_rtc";
+ assigned-clocks = <&rcc 1 CLK_RTC>;
+ assigned-clock-parents = <&rcc 1 CLK_LSE>;
+ interrupt-parent = <&exti>;
+ interrupts = <17 1>;
+ interrupt-names = "alarm";
+ st,syscfg = <&pwrcfg>;
+ };
--
1.9.1
--
You received this message because you are subscribed to "rtc-linux".
Membership options at http://groups.google.com/group/rtc-linux .
Please read http://groups.google.com/group/rtc-linux/web/checklist
before submitting a driver.
---
You received this message because you are subscribed to the Google Groups "rtc-linux" group.
To unsubscribe from this group and stop receiving emails from it, send an email to rtc-linux+unsubscribe-/JYPxA39Uh5TLH3MbocFF+G/Ez6ZCGd0@public.gmane.org
For more options, visit https://groups.google.com/d/optout.
^ permalink raw reply related
* [PATCH 3/8] rtc: add STM32 RTC driver
From: Amelie Delaunay @ 2016-12-02 14:09 UTC (permalink / raw)
To: a.zummo-BfzFCNDTiLLj+vYz1yj4TQ,
alexandre.belloni-wi1+55ScJUtKEb57/3fJTNBPR1lH4CV8,
robh+dt-DgEjT+Ai2ygdnm+yROfE0A, mark.rutland-5wv7dgnIgG8,
mcoquelin.stm32-Re5JQEeQqe8AvxtiuMwx3w,
alexandre.torgue-qxv4g6HH51o, linux-I+IVW8TIWO2tmTQ+vhA3Yw
Cc: rtc-linux-/JYPxA39Uh5TLH3MbocFFw,
devicetree-u79uwXL29TY76Z2rM5mHXA,
linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r,
linux-kernel-u79uwXL29TY76Z2rM5mHXA,
gabriel.fernandez-qxv4g6HH51o, amelie.delaunay-qxv4g6HH51o
In-Reply-To: <1480687801-19525-2-git-send-email-amelie.delaunay-qxv4g6HH51o@public.gmane.org>
This patch adds support for the STM32 RTC.
Signed-off-by: Amelie Delaunay <amelie.delaunay-qxv4g6HH51o@public.gmane.org>
---
drivers/rtc/Kconfig | 10 +
drivers/rtc/Makefile | 1 +
drivers/rtc/rtc-stm32.c | 777 ++++++++++++++++++++++++++++++++++++++++++++++++
3 files changed, 788 insertions(+)
create mode 100644 drivers/rtc/rtc-stm32.c
diff --git a/drivers/rtc/Kconfig b/drivers/rtc/Kconfig
index e859d14..dd8b218 100644
--- a/drivers/rtc/Kconfig
+++ b/drivers/rtc/Kconfig
@@ -1706,6 +1706,16 @@ config RTC_DRV_PIC32
This driver can also be built as a module. If so, the module
will be called rtc-pic32
+config RTC_DRV_STM32
+ tristate "STM32 On-Chip RTC"
+ depends on ARCH_STM32
+ help
+ If you say yes here you get support for the STM32 On-Chip
+ Real Time Clock.
+
+ This driver can also be built as a module, if so, the module
+ will be called "rtc-stm32".
+
comment "HID Sensor RTC drivers"
config RTC_DRV_HID_SENSOR_TIME
diff --git a/drivers/rtc/Makefile b/drivers/rtc/Makefile
index 1ac694a..87bd9cc 100644
--- a/drivers/rtc/Makefile
+++ b/drivers/rtc/Makefile
@@ -144,6 +144,7 @@ obj-$(CONFIG_RTC_DRV_SNVS) += rtc-snvs.o
obj-$(CONFIG_RTC_DRV_SPEAR) += rtc-spear.o
obj-$(CONFIG_RTC_DRV_STARFIRE) += rtc-starfire.o
obj-$(CONFIG_RTC_DRV_STK17TA8) += rtc-stk17ta8.o
+obj-$(CONFIG_RTC_DRV_STM32) += rtc-stm32.o
obj-$(CONFIG_RTC_DRV_STMP) += rtc-stmp3xxx.o
obj-$(CONFIG_RTC_DRV_ST_LPC) += rtc-st-lpc.o
obj-$(CONFIG_RTC_DRV_SUN4V) += rtc-sun4v.o
diff --git a/drivers/rtc/rtc-stm32.c b/drivers/rtc/rtc-stm32.c
new file mode 100644
index 0000000..9e710ff
--- /dev/null
+++ b/drivers/rtc/rtc-stm32.c
@@ -0,0 +1,777 @@
+/*
+ * Copyright (C) Amelie Delaunay 2015
+ * Author: Amelie Delaunay <adelaunay.stm32-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
+ * License terms: GNU General Public License (GPL), version 2
+ */
+
+#include <linux/bcd.h>
+#include <linux/clk.h>
+#include <linux/init.h>
+#include <linux/io.h>
+#include <linux/iopoll.h>
+#include <linux/ioport.h>
+#include <linux/kernel.h>
+#include <linux/mfd/syscon.h>
+#include <linux/module.h>
+#include <linux/of.h>
+#include <linux/of_device.h>
+#include <linux/platform_device.h>
+#include <linux/regmap.h>
+#include <linux/rtc.h>
+#include <linux/spinlock.h>
+
+#define DRIVER_NAME "stm32_rtc"
+
+/* STM32 RTC registers */
+#define STM32_RTC_TR 0x00
+#define STM32_RTC_DR 0x04
+#define STM32_RTC_CR 0x08
+#define STM32_RTC_ISR 0x0C
+#define STM32_RTC_PRER 0x10
+#define STM32_RTC_ALRMAR 0x1C
+#define STM32_RTC_WPR 0x24
+
+/* STM32_RTC_TR bit fields */
+#define STM32_RTC_TR_SEC_SHIFT 0
+#define STM32_RTC_TR_SEC GENMASK(6, 0)
+#define STM32_RTC_TR_MIN_SHIFT 8
+#define STM32_RTC_TR_MIN GENMASK(14, 8)
+#define STM32_RTC_TR_HOUR_SHIFT 16
+#define STM32_RTC_TR_HOUR GENMASK(21, 16)
+
+/* STM32_RTC_DR bit fields */
+#define STM32_RTC_DR_DATE_SHIFT 0
+#define STM32_RTC_DR_DATE GENMASK(5, 0)
+#define STM32_RTC_DR_MONTH_SHIFT 8
+#define STM32_RTC_DR_MONTH GENMASK(11, 8)
+#define STM32_RTC_DR_WDAY_SHIFT 13
+#define STM32_RTC_DR_WDAY GENMASK(15, 13)
+#define STM32_RTC_DR_YEAR_SHIFT 16
+#define STM32_RTC_DR_YEAR GENMASK(23, 16)
+
+/* STM32_RTC_CR bit fields */
+#define STM32_RTC_CR_FMT BIT(6)
+#define STM32_RTC_CR_ALRAE BIT(8)
+#define STM32_RTC_CR_ALRAIE BIT(12)
+
+/* STM32_RTC_ISR bit fields */
+#define STM32_RTC_ISR_ALRAWF BIT(0)
+#define STM32_RTC_ISR_INITS BIT(4)
+#define STM32_RTC_ISR_RSF BIT(5)
+#define STM32_RTC_ISR_INITF BIT(6)
+#define STM32_RTC_ISR_INIT BIT(7)
+#define STM32_RTC_ISR_ALRAF BIT(8)
+
+/* STM32_RTC_PRER bit fields */
+#define STM32_RTC_PRER_PRED_S_SHIFT 0
+#define STM32_RTC_PRER_PRED_S GENMASK(14, 0)
+#define STM32_RTC_PRER_PRED_A_SHIFT 16
+#define STM32_RTC_PRER_PRED_A GENMASK(22, 16)
+
+/* STM32_RTC_ALRMAR and STM32_RTC_ALRMBR bit fields */
+#define STM32_RTC_ALRMXR_SEC_SHIFT 0
+#define STM32_RTC_ALRMXR_SEC GENMASK(6, 0)
+#define STM32_RTC_ALRMXR_SEC_MASK BIT(7)
+#define STM32_RTC_ALRMXR_MIN_SHIFT 8
+#define STM32_RTC_ALRMXR_MIN GENMASK(14, 8)
+#define STM32_RTC_ALRMXR_MIN_MASK BIT(15)
+#define STM32_RTC_ALRMXR_HOUR_SHIFT 16
+#define STM32_RTC_ALRMXR_HOUR GENMASK(21, 16)
+#define STM32_RTC_ALRMXR_PM BIT(22)
+#define STM32_RTC_ALRMXR_HOUR_MASK BIT(23)
+#define STM32_RTC_ALRMXR_DATE_SHIFT 24
+#define STM32_RTC_ALRMXR_DATE GENMASK(29, 24)
+#define STM32_RTC_ALRMXR_WDSEL BIT(30)
+#define STM32_RTC_ALRMXR_WDAY_SHIFT 24
+#define STM32_RTC_ALRMXR_WDAY GENMASK(27, 24)
+#define STM32_RTC_ALRMXR_DATE_MASK BIT(31)
+
+/* STM32_RTC_WPR key constants */
+#define RTC_WPR_1ST_KEY 0xCA
+#define RTC_WPR_2ND_KEY 0x53
+#define RTC_WPR_WRONG_KEY 0xFF
+
+/*
+ * RTC registers are protected agains parasitic write access.
+ * PWR_CR_DBP bit must be set to enable write access to RTC registers.
+ */
+/* STM32_PWR_CR */
+#define PWR_CR 0x00
+/* STM32_PWR_CR bit field */
+#define PWR_CR_DBP BIT(8)
+
+static struct regmap *dbp;
+
+struct stm32_rtc {
+ struct rtc_device *rtc_dev;
+ void __iomem *base;
+ struct clk *pclk;
+ struct clk *ck_rtc;
+ unsigned int clksrc;
+ spinlock_t lock; /* Protects registers accesses */
+ int irq_alarm;
+ struct regmap *pwrcr;
+};
+
+static inline unsigned int stm32_rtc_readl(struct stm32_rtc *rtc,
+ unsigned int offset)
+{
+ return readl_relaxed(rtc->base + offset);
+}
+
+static inline void stm32_rtc_writel(struct stm32_rtc *rtc,
+ unsigned int offset, unsigned int value)
+{
+ writel_relaxed(value, rtc->base + offset);
+}
+
+static void stm32_rtc_wpr_unlock(struct stm32_rtc *rtc)
+{
+// if (dbp)
+// regmap_update_bits(dbp, PWR_CR, PWR_CR_DBP, PWR_CR_DBP);
+
+ stm32_rtc_writel(rtc, STM32_RTC_WPR, RTC_WPR_1ST_KEY);
+ stm32_rtc_writel(rtc, STM32_RTC_WPR, RTC_WPR_2ND_KEY);
+}
+
+static void stm32_rtc_wpr_lock(struct stm32_rtc *rtc)
+{
+ stm32_rtc_writel(rtc, STM32_RTC_WPR, RTC_WPR_WRONG_KEY);
+
+// if (dbp)
+// regmap_update_bits(dbp, PWR_CR, PWR_CR_DBP, ~PWR_CR_DBP);
+}
+
+static int stm32_rtc_enter_init_mode(struct stm32_rtc *rtc)
+{
+ unsigned int isr = stm32_rtc_readl(rtc, STM32_RTC_ISR);
+
+ if (!(isr & STM32_RTC_ISR_INITF)) {
+ isr |= STM32_RTC_ISR_INIT;
+ stm32_rtc_writel(rtc, STM32_RTC_ISR, isr);
+
+ return readl_relaxed_poll_timeout_atomic(
+ rtc->base + STM32_RTC_ISR,
+ isr, (isr & STM32_RTC_ISR_INITF),
+ 10, 100000);
+ }
+
+ return 0;
+}
+
+static void stm32_rtc_exit_init_mode(struct stm32_rtc *rtc)
+{
+ unsigned int isr = stm32_rtc_readl(rtc, STM32_RTC_ISR);
+
+ isr &= ~STM32_RTC_ISR_INIT;
+ stm32_rtc_writel(rtc, STM32_RTC_ISR, isr);
+}
+
+static int stm32_rtc_wait_sync(struct stm32_rtc *rtc)
+{
+ unsigned int isr;
+
+ isr = stm32_rtc_readl(rtc, STM32_RTC_ISR);
+
+ isr &= ~STM32_RTC_ISR_RSF;
+ stm32_rtc_writel(rtc, STM32_RTC_ISR, isr);
+
+ /* Wait the registers to be synchronised */
+ return readl_relaxed_poll_timeout_atomic(rtc->base + STM32_RTC_ISR,
+ isr,
+ (isr & STM32_RTC_ISR_RSF),
+ 10, 100000);
+}
+
+static irqreturn_t stm32_rtc_alarm_irq(int irq, void *dev_id)
+{
+ struct stm32_rtc *rtc = (struct stm32_rtc *)dev_id;
+ unsigned long irqflags, events = 0;
+ unsigned int isr, cr;
+
+ spin_lock_irqsave(&rtc->lock, irqflags);
+
+ isr = stm32_rtc_readl(rtc, STM32_RTC_ISR);
+ cr = stm32_rtc_readl(rtc, STM32_RTC_CR);
+
+ if ((isr & STM32_RTC_ISR_ALRAF) &&
+ (cr & STM32_RTC_CR_ALRAIE)) {
+ /* Alarm A flag - Alarm interrupt */
+ events |= RTC_IRQF | RTC_AF;
+ isr &= ~STM32_RTC_ISR_ALRAF;
+ }
+
+ /* Clear event irqflags, otherwise new events won't be received */
+ stm32_rtc_writel(rtc, STM32_RTC_ISR, isr);
+
+ spin_unlock_irqrestore(&rtc->lock, irqflags);
+
+ if (events) {
+ dev_info(&rtc->rtc_dev->dev, "Alarm occurred\n");
+
+ /* Pass event to the kernel */
+ rtc_update_irq(rtc->rtc_dev, 1, events);
+ return IRQ_HANDLED;
+ } else {
+ return IRQ_NONE;
+ }
+}
+
+/* Convert rtc_time structure from bin to bcd format */
+static void tm2bcd(struct rtc_time *tm)
+{
+ tm->tm_sec = bin2bcd(tm->tm_sec);
+ tm->tm_min = bin2bcd(tm->tm_min);
+ tm->tm_hour = bin2bcd(tm->tm_hour);
+
+ tm->tm_mday = bin2bcd(tm->tm_mday);
+ tm->tm_mon = bin2bcd(tm->tm_mon + 1);
+ tm->tm_year = bin2bcd(tm->tm_year - 100);
+ /*
+ * Number of days since Sunday
+ * - on kernel side, 0=Sunday...6=Saturday
+ * - on rtc side, 0=invalid,1=Monday...7=Sunday
+ */
+ tm->tm_wday = (!tm->tm_wday) ? 7 : tm->tm_wday;
+}
+
+/* Convert rtc_time structure from bcd to bin format */
+static void bcd2tm(struct rtc_time *tm)
+{
+ tm->tm_sec = bcd2bin(tm->tm_sec);
+ tm->tm_min = bcd2bin(tm->tm_min);
+ tm->tm_hour = bcd2bin(tm->tm_hour);
+
+ tm->tm_mday = bcd2bin(tm->tm_mday);
+ tm->tm_mon = bcd2bin(tm->tm_mon) - 1;
+ tm->tm_year = bcd2bin(tm->tm_year) + 100;
+ /*
+ * Number of days since Sunday
+ * - on kernel side, 0=Sunday...6=Saturday
+ * - on rtc side, 0=invalid,1=Monday...7=Sunday
+ */
+ tm->tm_wday %= 7;
+}
+
+static int stm32_rtc_read_time(struct device *dev, struct rtc_time *tm)
+{
+ struct stm32_rtc *rtc = dev_get_drvdata(dev);
+ unsigned int tr, dr;
+ unsigned long irqflags;
+
+ spin_lock_irqsave(&rtc->lock, irqflags);
+
+ /* Time and Date in BCD format */
+ tr = stm32_rtc_readl(rtc, STM32_RTC_TR);
+ dr = stm32_rtc_readl(rtc, STM32_RTC_DR);
+
+ spin_unlock_irqrestore(&rtc->lock, irqflags);
+
+ tm->tm_sec = (tr & STM32_RTC_TR_SEC) >> STM32_RTC_TR_SEC_SHIFT;
+ tm->tm_min = (tr & STM32_RTC_TR_MIN) >> STM32_RTC_TR_MIN_SHIFT;
+ tm->tm_hour = (tr & STM32_RTC_TR_HOUR) >> STM32_RTC_TR_HOUR_SHIFT;
+
+ tm->tm_mday = (dr & STM32_RTC_DR_DATE) >> STM32_RTC_DR_DATE_SHIFT;
+ tm->tm_mon = (dr & STM32_RTC_DR_MONTH) >> STM32_RTC_DR_MONTH_SHIFT;
+ tm->tm_year = (dr & STM32_RTC_DR_YEAR) >> STM32_RTC_DR_YEAR_SHIFT;
+ tm->tm_wday = (dr & STM32_RTC_DR_WDAY) >> STM32_RTC_DR_WDAY_SHIFT;
+
+ /* We don't report tm_yday and tm_isdst */
+
+ bcd2tm(tm);
+
+ if (rtc_valid_tm(tm) < 0) {
+ dev_err(dev, "%s: rtc_time is not valid.\n", __func__);
+ return -EINVAL;
+ }
+
+ return 0;
+}
+
+static int stm32_rtc_set_time(struct device *dev, struct rtc_time *tm)
+{
+ struct stm32_rtc *rtc = dev_get_drvdata(dev);
+ unsigned int tr, dr;
+ unsigned long irqflags;
+ int ret = 0;
+
+ if (rtc_valid_tm(tm) < 0) {
+ dev_err(dev, "%s: rtc_time is not valid.\n", __func__);
+ return -EINVAL;
+ }
+
+ tm2bcd(tm);
+
+ /* Time in BCD format */
+ tr = ((tm->tm_sec << STM32_RTC_TR_SEC_SHIFT) & STM32_RTC_TR_SEC) |
+ ((tm->tm_min << STM32_RTC_TR_MIN_SHIFT) & STM32_RTC_TR_MIN) |
+ ((tm->tm_hour << STM32_RTC_TR_HOUR_SHIFT) & STM32_RTC_TR_HOUR);
+
+ /* Date in BCD format */
+ dr = ((tm->tm_mday << STM32_RTC_DR_DATE_SHIFT) & STM32_RTC_DR_DATE) |
+ ((tm->tm_mon << STM32_RTC_DR_MONTH_SHIFT) & STM32_RTC_DR_MONTH) |
+ ((tm->tm_year << STM32_RTC_DR_YEAR_SHIFT) & STM32_RTC_DR_YEAR) |
+ ((tm->tm_wday << STM32_RTC_DR_WDAY_SHIFT) & STM32_RTC_DR_WDAY);
+
+ spin_lock_irqsave(&rtc->lock, irqflags);
+
+ stm32_rtc_wpr_unlock(rtc);
+
+ ret = stm32_rtc_enter_init_mode(rtc);
+ if (ret) {
+ dev_err(dev, "Can't enter in init mode. Set time aborted.\n");
+ goto end;
+ }
+
+ stm32_rtc_writel(rtc, STM32_RTC_TR, tr);
+ stm32_rtc_writel(rtc, STM32_RTC_DR, dr);
+
+ stm32_rtc_exit_init_mode(rtc);
+
+ ret = stm32_rtc_wait_sync(rtc);
+end:
+ stm32_rtc_wpr_lock(rtc);
+
+ spin_unlock_irqrestore(&rtc->lock, irqflags);
+
+ return ret;
+}
+
+static int stm32_rtc_read_alarm(struct device *dev, struct rtc_wkalrm *alrm)
+{
+ struct stm32_rtc *rtc = dev_get_drvdata(dev);
+ struct rtc_time *tm = &alrm->time;
+ unsigned int alrmar, cr, isr;
+ unsigned long irqflags;
+
+ spin_lock_irqsave(&rtc->lock, irqflags);
+
+ alrmar = stm32_rtc_readl(rtc, STM32_RTC_ALRMAR);
+ cr = stm32_rtc_readl(rtc, STM32_RTC_CR);
+ isr = stm32_rtc_readl(rtc, STM32_RTC_ISR);
+
+ spin_unlock_irqrestore(&rtc->lock, irqflags);
+
+ if (alrmar & STM32_RTC_ALRMXR_DATE_MASK) {
+ /*
+ * Date/day don't care in Alarm comparison so alarm triggers
+ * every day
+ */
+ tm->tm_mday = -1;
+ tm->tm_wday = -1;
+ } else {
+ if (alrmar & STM32_RTC_ALRMXR_WDSEL) {
+ /* Alarm is set to a day of week */
+ tm->tm_mday = -1;
+ tm->tm_wday = (alrmar & STM32_RTC_ALRMXR_WDAY) >>
+ STM32_RTC_ALRMXR_WDAY_SHIFT;
+ tm->tm_wday %= 7;
+ } else {
+ /* Alarm is set to a day of month */
+ tm->tm_wday = -1;
+ tm->tm_mday = (alrmar & STM32_RTC_ALRMXR_DATE) >>
+ STM32_RTC_ALRMXR_DATE_SHIFT;
+ }
+ }
+
+ if (alrmar & STM32_RTC_ALRMXR_HOUR_MASK) {
+ /* Hours don't care in Alarm comparison */
+ tm->tm_hour = -1;
+ } else {
+ tm->tm_hour = (alrmar & STM32_RTC_ALRMXR_HOUR) >>
+ STM32_RTC_ALRMXR_HOUR_SHIFT;
+ if (alrmar & STM32_RTC_ALRMXR_PM)
+ tm->tm_hour += 12;
+ }
+
+ if (alrmar & STM32_RTC_ALRMXR_MIN_MASK) {
+ /* Minutes don't care in Alarm comparison */
+ tm->tm_min = -1;
+ } else {
+ tm->tm_min = (alrmar & STM32_RTC_ALRMXR_MIN) >>
+ STM32_RTC_ALRMXR_MIN_SHIFT;
+ }
+
+ if (alrmar & STM32_RTC_ALRMXR_SEC_MASK) {
+ /* Seconds don't care in Alarm comparison */
+ tm->tm_sec = -1;
+ } else {
+ tm->tm_sec = (alrmar & STM32_RTC_ALRMXR_SEC) >>
+ STM32_RTC_ALRMXR_SEC_SHIFT;
+ }
+
+ bcd2tm(tm);
+
+ alrm->enabled = (cr & STM32_RTC_CR_ALRAE) ? 1 : 0;
+ alrm->pending = (isr & STM32_RTC_ISR_ALRAF) ? 1 : 0;
+
+ return 0;
+}
+
+static int stm32_rtc_alarm_irq_enable(struct device *dev, unsigned int enabled)
+{
+ struct stm32_rtc *rtc = dev_get_drvdata(dev);
+ unsigned long irqflags;
+ unsigned int isr, cr;
+
+ cr = stm32_rtc_readl(rtc, STM32_RTC_CR);
+
+ spin_lock_irqsave(&rtc->lock, irqflags);
+
+ stm32_rtc_wpr_unlock(rtc);
+
+ /* We expose Alarm A to the kernel */
+ if (enabled)
+ cr |= (STM32_RTC_CR_ALRAIE | STM32_RTC_CR_ALRAE);
+ else
+ cr &= ~(STM32_RTC_CR_ALRAIE | STM32_RTC_CR_ALRAE);
+ stm32_rtc_writel(rtc, STM32_RTC_CR, cr);
+
+ /* Clear event irqflags, otherwise new events won't be received */
+ isr = stm32_rtc_readl(rtc, STM32_RTC_ISR);
+ isr &= ~STM32_RTC_ISR_ALRAF;
+ stm32_rtc_writel(rtc, STM32_RTC_ISR, isr);
+
+ stm32_rtc_wpr_lock(rtc);
+
+ spin_unlock_irqrestore(&rtc->lock, irqflags);
+
+ return 0;
+}
+
+static int stm32_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *alrm)
+{
+ struct stm32_rtc *rtc = dev_get_drvdata(dev);
+ struct rtc_time *tm = &alrm->time;
+ unsigned long irqflags;
+ unsigned int cr, isr, alrmar;
+ int ret = 0;
+
+ if (rtc_valid_tm(tm)) {
+ dev_err(dev, "Alarm time not valid.\n");
+ return -EINVAL;
+ }
+
+ tm2bcd(tm);
+
+ spin_lock_irqsave(&rtc->lock, irqflags);
+
+ stm32_rtc_wpr_unlock(rtc);
+
+ /* Disable Alarm */
+ cr = stm32_rtc_readl(rtc, STM32_RTC_CR);
+ cr &= ~STM32_RTC_CR_ALRAE;
+ stm32_rtc_writel(rtc, STM32_RTC_CR, cr);
+
+ /* Poll Alarm write flag to be sure that Alarm update is allowed */
+ ret = readl_relaxed_poll_timeout_atomic(rtc->base + STM32_RTC_ISR,
+ isr,
+ (isr & STM32_RTC_ISR_ALRAWF),
+ 10, 100);
+
+ if (ret) {
+ dev_err(dev, "Alarm update not allowed\n");
+ goto end;
+ }
+
+ alrmar = 0;
+
+ if (tm->tm_mday < 0 && tm->tm_wday < 0) {
+ /*
+ * Date/day don't care in Alarm comparison so alarm triggers
+ * every day
+ */
+ alrmar |= STM32_RTC_ALRMXR_DATE_MASK;
+ } else {
+ if (tm->tm_mday > 0) {
+ /* Date is selected (ignoring wday) */
+ alrmar |= (tm->tm_mday << STM32_RTC_ALRMXR_DATE_SHIFT) &
+ STM32_RTC_ALRMXR_DATE;
+ } else {
+ /* Day of week is selected */
+ int wday = (tm->tm_wday == 0) ? 7 : tm->tm_wday;
+
+ alrmar |= STM32_RTC_ALRMXR_WDSEL;
+ alrmar |= (wday << STM32_RTC_ALRMXR_WDAY_SHIFT) &
+ STM32_RTC_ALRMXR_WDAY;
+ }
+ }
+
+ if (tm->tm_hour < 0) {
+ /* Hours don't care in Alarm comparison */
+ alrmar |= STM32_RTC_ALRMXR_HOUR_MASK;
+ } else {
+ /* 24-hour format */
+ alrmar &= ~STM32_RTC_ALRMXR_PM;
+ alrmar |= (tm->tm_hour << STM32_RTC_ALRMXR_HOUR_SHIFT) &
+ STM32_RTC_ALRMXR_HOUR;
+ }
+
+ if (tm->tm_min < 0) {
+ /* Minutes don't care in Alarm comparison */
+ alrmar |= STM32_RTC_ALRMXR_MIN_MASK;
+ } else {
+ alrmar |= (tm->tm_min << STM32_RTC_ALRMXR_MIN_SHIFT) &
+ STM32_RTC_ALRMXR_MIN;
+ }
+
+ if (tm->tm_sec < 0) {
+ /* Seconds don't care in Alarm comparison */
+ alrmar |= STM32_RTC_ALRMXR_SEC_MASK;
+ } else {
+ alrmar |= (tm->tm_sec << STM32_RTC_ALRMXR_SEC_SHIFT) &
+ STM32_RTC_ALRMXR_SEC;
+ }
+
+ /* Write to Alarm register */
+ stm32_rtc_writel(rtc, STM32_RTC_ALRMAR, alrmar);
+
+ if (alrm->enabled)
+ stm32_rtc_alarm_irq_enable(dev, 1);
+ else
+ stm32_rtc_alarm_irq_enable(dev, 0);
+
+end:
+ stm32_rtc_wpr_lock(rtc);
+
+ spin_unlock_irqrestore(&rtc->lock, irqflags);
+
+ return ret;
+}
+
+static const struct rtc_class_ops stm32_rtc_ops = {
+ .read_time = stm32_rtc_read_time,
+ .set_time = stm32_rtc_set_time,
+ .read_alarm = stm32_rtc_read_alarm,
+ .set_alarm = stm32_rtc_set_alarm,
+ .alarm_irq_enable = stm32_rtc_alarm_irq_enable,
+};
+
+#ifdef CONFIG_OF
+static const struct of_device_id stm32_rtc_of_match[] = {
+ { .compatible = "st,stm32-rtc" },
+ {}
+};
+MODULE_DEVICE_TABLE(of, stm32_rtc_of_match);
+#endif
+
+static int stm32_rtc_init(struct platform_device *pdev,
+ struct stm32_rtc *rtc)
+{
+ unsigned int prer, pred_a, pred_s, pred_a_max, pred_s_max, cr;
+ unsigned int rate;
+ unsigned long irqflags;
+ int ret = 0;
+
+ rate = clk_get_rate(rtc->ck_rtc);
+
+ /* Find prediv_a and prediv_s to obtain the 1Hz calendar clock */
+ pred_a_max = STM32_RTC_PRER_PRED_A >> STM32_RTC_PRER_PRED_A_SHIFT;
+ pred_s_max = STM32_RTC_PRER_PRED_S >> STM32_RTC_PRER_PRED_S_SHIFT;
+
+ for (pred_a = pred_a_max; pred_a >= 0; pred_a--) {
+ pred_s = (rate / (pred_a + 1)) - 1;
+
+ if (((pred_s + 1) * (pred_a + 1)) == rate)
+ break;
+ }
+
+ /*
+ * Can't find a 1Hz, so give priority to RTC power consumption
+ * by choosing the higher possible value for prediv_a
+ */
+ if ((pred_s > pred_s_max) || (pred_a > pred_a_max)) {
+ pred_a = pred_a_max;
+ pred_s = (rate / (pred_a + 1)) - 1;
+
+ dev_warn(&pdev->dev, "ck_rtc is %s\n",
+ (rate - ((pred_a + 1) * (pred_s + 1)) < 0) ?
+ "fast" : "slow");
+ }
+
+ spin_lock_irqsave(&rtc->lock, irqflags);
+
+ stm32_rtc_wpr_unlock(rtc);
+
+ ret = stm32_rtc_enter_init_mode(rtc);
+ if (ret) {
+ dev_err(&pdev->dev,
+ "Can't enter in init mode. Prescaler config failed.\n");
+ goto end;
+ }
+
+ prer = (pred_s << STM32_RTC_PRER_PRED_S_SHIFT) & STM32_RTC_PRER_PRED_S;
+ stm32_rtc_writel(rtc, STM32_RTC_PRER, prer);
+ prer |= (pred_a << STM32_RTC_PRER_PRED_A_SHIFT) & STM32_RTC_PRER_PRED_A;
+ stm32_rtc_writel(rtc, STM32_RTC_PRER, prer);
+
+ /* Force 24h time format */
+ cr = stm32_rtc_readl(rtc, STM32_RTC_CR);
+ cr &= ~STM32_RTC_CR_FMT;
+ stm32_rtc_writel(rtc, STM32_RTC_CR, cr);
+
+ stm32_rtc_exit_init_mode(rtc);
+
+ ret = stm32_rtc_wait_sync(rtc);
+
+ if (stm32_rtc_readl(rtc, STM32_RTC_ISR) & STM32_RTC_ISR_INITS)
+ dev_warn(&pdev->dev, "Date/Time must be initialized\n");
+end:
+ stm32_rtc_wpr_lock(rtc);
+
+ spin_unlock_irqrestore(&rtc->lock, irqflags);
+
+ return ret;
+}
+
+static int stm32_rtc_probe(struct platform_device *pdev)
+{
+ struct stm32_rtc *rtc;
+ struct resource *res;
+ int ret;
+
+ rtc = devm_kzalloc(&pdev->dev, sizeof(*rtc), GFP_KERNEL);
+ if (!rtc)
+ return -ENOMEM;
+
+ res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+ rtc->base = devm_ioremap_resource(&pdev->dev, res);
+ if (IS_ERR(rtc->base))
+ return PTR_ERR(rtc->base);
+
+ dbp = syscon_regmap_lookup_by_phandle(pdev->dev.of_node, "st,syscfg");
+ if (IS_ERR(dbp)) {
+ dev_err(&pdev->dev, "no st,syscfg\n");
+ return PTR_ERR(dbp);
+ }
+
+ spin_lock_init(&rtc->lock);
+
+ rtc->ck_rtc = devm_clk_get(&pdev->dev, "ck_rtc");
+ if (IS_ERR(rtc->ck_rtc)) {
+ dev_err(&pdev->dev, "no ck_rtc clock");
+ return PTR_ERR(rtc->ck_rtc);
+ }
+
+ ret = clk_prepare_enable(rtc->ck_rtc);
+ if (ret)
+ return ret;
+
+ if (dbp)
+ regmap_update_bits(dbp, PWR_CR, PWR_CR_DBP, PWR_CR_DBP);
+
+ ret = stm32_rtc_init(pdev, rtc);
+ if (ret)
+ goto err;
+
+ rtc->irq_alarm = platform_get_irq_byname(pdev, "alarm");
+ if (rtc->irq_alarm <= 0) {
+ dev_err(&pdev->dev, "no alarm irq\n");
+ ret = -ENOENT;
+ goto err;
+ }
+
+ platform_set_drvdata(pdev, rtc);
+
+ device_init_wakeup(&pdev->dev, true);
+
+ rtc->rtc_dev = devm_rtc_device_register(&pdev->dev, pdev->name,
+ &stm32_rtc_ops, THIS_MODULE);
+ if (IS_ERR(rtc->rtc_dev)) {
+ ret = PTR_ERR(rtc->rtc_dev);
+ dev_err(&pdev->dev, "rtc device registration failed, err=%d\n",
+ ret);
+ goto err;
+ }
+
+ /* Handle RTC alarm interrupts */
+ ret = devm_request_irq(&pdev->dev, rtc->irq_alarm,
+ stm32_rtc_alarm_irq, IRQF_TRIGGER_RISING,
+ dev_name(&rtc->rtc_dev->dev), rtc);
+ if (ret) {
+ dev_err(&pdev->dev, "IRQ%d (alarm interrupt) already claimed\n",
+ rtc->irq_alarm);
+ goto err;
+ }
+
+ return 0;
+err:
+ clk_disable_unprepare(rtc->ck_rtc);
+
+ if (dbp)
+ regmap_update_bits(dbp, PWR_CR, PWR_CR_DBP, ~PWR_CR_DBP);
+
+ device_init_wakeup(&pdev->dev, false);
+
+ return ret;
+}
+
+static int __exit stm32_rtc_remove(struct platform_device *pdev)
+{
+ struct stm32_rtc *rtc = platform_get_drvdata(pdev);
+ unsigned int cr;
+
+ /* Disable interrupts */
+ stm32_rtc_wpr_unlock(rtc);
+ cr = stm32_rtc_readl(rtc, STM32_RTC_CR);
+ cr &= ~STM32_RTC_CR_ALRAIE;
+ stm32_rtc_writel(rtc, STM32_RTC_CR, cr);
+ stm32_rtc_wpr_lock(rtc);
+
+ clk_disable_unprepare(rtc->ck_rtc);
+
+ /* Enable backup domain write protection */
+ if (dbp)
+ regmap_update_bits(dbp, PWR_CR, PWR_CR_DBP, ~PWR_CR_DBP);
+
+ device_init_wakeup(&pdev->dev, false);
+
+ return 0;
+}
+
+#ifdef CONFIG_PM_SLEEP
+static int stm32_rtc_suspend(struct device *dev)
+{
+ struct stm32_rtc *rtc = dev_get_drvdata(dev);
+
+ if (device_may_wakeup(dev))
+ return enable_irq_wake(rtc->irq_alarm);
+
+ return 0;
+}
+
+static int stm32_rtc_resume(struct device *dev)
+{
+ struct stm32_rtc *rtc = dev_get_drvdata(dev);
+ int ret = 0;
+
+ ret = stm32_rtc_wait_sync(rtc);
+ if (ret < 0)
+ return ret;
+
+ if (device_may_wakeup(dev))
+ return disable_irq_wake(rtc->irq_alarm);
+
+ return ret;
+}
+#endif
+
+static SIMPLE_DEV_PM_OPS(stm32_rtc_pm_ops,
+ stm32_rtc_suspend, stm32_rtc_resume);
+
+static struct platform_driver stm32_rtc_driver = {
+ .probe = stm32_rtc_probe,
+ .remove = stm32_rtc_remove,
+ .driver = {
+ .name = DRIVER_NAME,
+ .pm = &stm32_rtc_pm_ops,
+ .of_match_table = stm32_rtc_of_match,
+ },
+};
+
+module_platform_driver(stm32_rtc_driver);
+
+MODULE_ALIAS("platform:" DRIVER_NAME);
+MODULE_AUTHOR("Amelie Delaunay <amelie.delaunay-qxv4g6HH51o@public.gmane.org>");
+MODULE_DESCRIPTION("STMicroelectronics STM32 Real Time Clock driver");
+MODULE_LICENSE("GPL v2");
--
1.9.1
--
You received this message because you are subscribed to "rtc-linux".
Membership options at http://groups.google.com/group/rtc-linux .
Please read http://groups.google.com/group/rtc-linux/web/checklist
before submitting a driver.
---
You received this message because you are subscribed to the Google Groups "rtc-linux" group.
To unsubscribe from this group and stop receiving emails from it, send an email to rtc-linux+unsubscribe-/JYPxA39Uh5TLH3MbocFF+G/Ez6ZCGd0@public.gmane.org
For more options, visit https://groups.google.com/d/optout.
^ permalink raw reply related
* [PATCH 4/8] ARM: dts: stm32: Add STM32 RTC support for STM32F429 MCU
From: Amelie Delaunay @ 2016-12-02 14:09 UTC (permalink / raw)
To: a.zummo-BfzFCNDTiLLj+vYz1yj4TQ,
alexandre.belloni-wi1+55ScJUtKEb57/3fJTNBPR1lH4CV8,
robh+dt-DgEjT+Ai2ygdnm+yROfE0A, mark.rutland-5wv7dgnIgG8,
mcoquelin.stm32-Re5JQEeQqe8AvxtiuMwx3w,
alexandre.torgue-qxv4g6HH51o, linux-I+IVW8TIWO2tmTQ+vhA3Yw
Cc: rtc-linux-/JYPxA39Uh5TLH3MbocFFw,
devicetree-u79uwXL29TY76Z2rM5mHXA,
linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r,
linux-kernel-u79uwXL29TY76Z2rM5mHXA,
gabriel.fernandez-qxv4g6HH51o, amelie.delaunay-qxv4g6HH51o
In-Reply-To: <1480687801-19525-2-git-send-email-amelie.delaunay-qxv4g6HH51o@public.gmane.org>
This patch adds STM32 RTC bindings for STM32F429.
Signed-off-by: Amelie Delaunay <amelie.delaunay-qxv4g6HH51o@public.gmane.org>
---
arch/arm/boot/dts/stm32f429.dtsi | 14 ++++++++++++++
1 file changed, 14 insertions(+)
diff --git a/arch/arm/boot/dts/stm32f429.dtsi b/arch/arm/boot/dts/stm32f429.dtsi
index d195ccf..d181025 100644
--- a/arch/arm/boot/dts/stm32f429.dtsi
+++ b/arch/arm/boot/dts/stm32f429.dtsi
@@ -125,6 +125,20 @@
status = "disabled";
};
+ rtc: rtc@40002800 {
+ compatible = "st,stm32-rtc";
+ reg = <0x40002800 0x400>;
+ clocks = <&rcc 1 CLK_RTC>;
+ clock-names = "ck_rtc";
+ assigned-clocks = <&rcc 1 CLK_RTC>;
+ assigned-clock-parents = <&rcc 1 CLK_LSE>;
+ interrupt-parent = <&exti>;
+ interrupts = <17 1>;
+ interrupt-names = "alarm";
+ st,syscfg = <&pwrcfg>;
+ status = "disabled";
+ };
+
usart2: serial@40004400 {
compatible = "st,stm32-usart", "st,stm32-uart";
reg = <0x40004400 0x400>;
--
1.9.1
--
You received this message because you are subscribed to "rtc-linux".
Membership options at http://groups.google.com/group/rtc-linux .
Please read http://groups.google.com/group/rtc-linux/web/checklist
before submitting a driver.
---
You received this message because you are subscribed to the Google Groups "rtc-linux" group.
To unsubscribe from this group and stop receiving emails from it, send an email to rtc-linux+unsubscribe-/JYPxA39Uh5TLH3MbocFF+G/Ez6ZCGd0@public.gmane.org
For more options, visit https://groups.google.com/d/optout.
^ permalink raw reply related
* [PATCH 5/8] ARM: dts: stm32: enable RTC on stm32f429-disco
From: Amelie Delaunay @ 2016-12-02 14:09 UTC (permalink / raw)
To: a.zummo-BfzFCNDTiLLj+vYz1yj4TQ,
alexandre.belloni-wi1+55ScJUtKEb57/3fJTNBPR1lH4CV8,
robh+dt-DgEjT+Ai2ygdnm+yROfE0A, mark.rutland-5wv7dgnIgG8,
mcoquelin.stm32-Re5JQEeQqe8AvxtiuMwx3w,
alexandre.torgue-qxv4g6HH51o, linux-I+IVW8TIWO2tmTQ+vhA3Yw
Cc: rtc-linux-/JYPxA39Uh5TLH3MbocFFw,
devicetree-u79uwXL29TY76Z2rM5mHXA,
linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r,
linux-kernel-u79uwXL29TY76Z2rM5mHXA,
gabriel.fernandez-qxv4g6HH51o, amelie.delaunay-qxv4g6HH51o
In-Reply-To: <1480687801-19525-2-git-send-email-amelie.delaunay-qxv4g6HH51o@public.gmane.org>
This patch enables RTC on stm32f429-disco with LSI as clock source because
X2 crystal for LSE is not fitted by default.
Signed-off-by: Amelie Delaunay <amelie.delaunay-qxv4g6HH51o@public.gmane.org>
---
arch/arm/boot/dts/stm32f429-disco.dts | 6 ++++++
1 file changed, 6 insertions(+)
diff --git a/arch/arm/boot/dts/stm32f429-disco.dts b/arch/arm/boot/dts/stm32f429-disco.dts
index b6e63d8..49eddf6 100644
--- a/arch/arm/boot/dts/stm32f429-disco.dts
+++ b/arch/arm/boot/dts/stm32f429-disco.dts
@@ -94,6 +94,12 @@
clock-frequency = <8000000>;
};
+&rtc {
+ assigned-clocks = <&rcc 1 CLK_RTC>;
+ assigned-clock-parents = <&rcc 1 CLK_LSI>;
+ status = "okay";
+};
+
&usart1 {
pinctrl-0 = <&usart1_pins_a>;
pinctrl-names = "default";
--
1.9.1
--
You received this message because you are subscribed to "rtc-linux".
Membership options at http://groups.google.com/group/rtc-linux .
Please read http://groups.google.com/group/rtc-linux/web/checklist
before submitting a driver.
---
You received this message because you are subscribed to the Google Groups "rtc-linux" group.
To unsubscribe from this group and stop receiving emails from it, send an email to rtc-linux+unsubscribe-/JYPxA39Uh5TLH3MbocFF+G/Ez6ZCGd0@public.gmane.org
For more options, visit https://groups.google.com/d/optout.
^ permalink raw reply related
* [PATCH 6/8] ARM: dts: stm32: enable RTC on stm32f469-disco
From: Amelie Delaunay @ 2016-12-02 14:09 UTC (permalink / raw)
To: a.zummo-BfzFCNDTiLLj+vYz1yj4TQ,
alexandre.belloni-wi1+55ScJUtKEb57/3fJTNBPR1lH4CV8,
robh+dt-DgEjT+Ai2ygdnm+yROfE0A, mark.rutland-5wv7dgnIgG8,
mcoquelin.stm32-Re5JQEeQqe8AvxtiuMwx3w,
alexandre.torgue-qxv4g6HH51o, linux-I+IVW8TIWO2tmTQ+vhA3Yw
Cc: rtc-linux-/JYPxA39Uh5TLH3MbocFFw,
devicetree-u79uwXL29TY76Z2rM5mHXA,
linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r,
linux-kernel-u79uwXL29TY76Z2rM5mHXA,
gabriel.fernandez-qxv4g6HH51o, amelie.delaunay-qxv4g6HH51o
In-Reply-To: <1480687801-19525-2-git-send-email-amelie.delaunay-qxv4g6HH51o@public.gmane.org>
This patch enables RTC on stm32f469-disco with default LSE clock source.
Signed-off-by: Amelie Delaunay <amelie.delaunay-qxv4g6HH51o@public.gmane.org>
---
arch/arm/boot/dts/stm32f469-disco.dts | 4 ++++
1 file changed, 4 insertions(+)
diff --git a/arch/arm/boot/dts/stm32f469-disco.dts b/arch/arm/boot/dts/stm32f469-disco.dts
index 8a163d7..af57dd5 100644
--- a/arch/arm/boot/dts/stm32f469-disco.dts
+++ b/arch/arm/boot/dts/stm32f469-disco.dts
@@ -78,6 +78,10 @@
clock-frequency = <8000000>;
};
+&rtc {
+ status = "okay";
+};
+
&usart3 {
status = "okay";
};
--
1.9.1
--
You received this message because you are subscribed to "rtc-linux".
Membership options at http://groups.google.com/group/rtc-linux .
Please read http://groups.google.com/group/rtc-linux/web/checklist
before submitting a driver.
---
You received this message because you are subscribed to the Google Groups "rtc-linux" group.
To unsubscribe from this group and stop receiving emails from it, send an email to rtc-linux+unsubscribe-/JYPxA39Uh5TLH3MbocFF+G/Ez6ZCGd0@public.gmane.org
For more options, visit https://groups.google.com/d/optout.
^ permalink raw reply related
* [PATCH 7/8] ARM: dts: stm32: enable RTC on stm32429i-eval
From: Amelie Delaunay @ 2016-12-02 14:10 UTC (permalink / raw)
To: a.zummo-BfzFCNDTiLLj+vYz1yj4TQ,
alexandre.belloni-wi1+55ScJUtKEb57/3fJTNBPR1lH4CV8,
robh+dt-DgEjT+Ai2ygdnm+yROfE0A, mark.rutland-5wv7dgnIgG8,
mcoquelin.stm32-Re5JQEeQqe8AvxtiuMwx3w,
alexandre.torgue-qxv4g6HH51o, linux-I+IVW8TIWO2tmTQ+vhA3Yw
Cc: rtc-linux-/JYPxA39Uh5TLH3MbocFFw,
devicetree-u79uwXL29TY76Z2rM5mHXA,
linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r,
linux-kernel-u79uwXL29TY76Z2rM5mHXA,
gabriel.fernandez-qxv4g6HH51o, amelie.delaunay-qxv4g6HH51o
In-Reply-To: <1480687801-19525-2-git-send-email-amelie.delaunay-qxv4g6HH51o@public.gmane.org>
This patch enables RTC on stm32429i-eval with default LSE clock source.
Signed-off-by: Amelie Delaunay <amelie.delaunay-qxv4g6HH51o@public.gmane.org>
---
arch/arm/boot/dts/stm32429i-eval.dts | 4 ++++
1 file changed, 4 insertions(+)
diff --git a/arch/arm/boot/dts/stm32429i-eval.dts b/arch/arm/boot/dts/stm32429i-eval.dts
index 8b158f9..5007da9 100644
--- a/arch/arm/boot/dts/stm32429i-eval.dts
+++ b/arch/arm/boot/dts/stm32429i-eval.dts
@@ -134,6 +134,10 @@
};
};
+&rtc {
+ status = "okay";
+};
+
&usart1 {
pinctrl-0 = <&usart1_pins_a>;
pinctrl-names = "default";
--
1.9.1
--
You received this message because you are subscribed to "rtc-linux".
Membership options at http://groups.google.com/group/rtc-linux .
Please read http://groups.google.com/group/rtc-linux/web/checklist
before submitting a driver.
---
You received this message because you are subscribed to the Google Groups "rtc-linux" group.
To unsubscribe from this group and stop receiving emails from it, send an email to rtc-linux+unsubscribe-/JYPxA39Uh5TLH3MbocFF+G/Ez6ZCGd0@public.gmane.org
For more options, visit https://groups.google.com/d/optout.
^ permalink raw reply related
* [PATCH 8/8] ARM: configs: stm32: Add STM32 RTC support in STM32 defconfig
From: Amelie Delaunay @ 2016-12-02 14:10 UTC (permalink / raw)
To: a.zummo-BfzFCNDTiLLj+vYz1yj4TQ,
alexandre.belloni-wi1+55ScJUtKEb57/3fJTNBPR1lH4CV8,
robh+dt-DgEjT+Ai2ygdnm+yROfE0A, mark.rutland-5wv7dgnIgG8,
mcoquelin.stm32-Re5JQEeQqe8AvxtiuMwx3w,
alexandre.torgue-qxv4g6HH51o, linux-I+IVW8TIWO2tmTQ+vhA3Yw
Cc: rtc-linux-/JYPxA39Uh5TLH3MbocFFw,
devicetree-u79uwXL29TY76Z2rM5mHXA,
linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r,
linux-kernel-u79uwXL29TY76Z2rM5mHXA,
gabriel.fernandez-qxv4g6HH51o, amelie.delaunay-qxv4g6HH51o
In-Reply-To: <1480687801-19525-2-git-send-email-amelie.delaunay-qxv4g6HH51o@public.gmane.org>
This patch adds STM32 RTC support in stm32_defconfig file.
Signed-off-by: Amelie Delaunay <amelie.delaunay-qxv4g6HH51o@public.gmane.org>
---
arch/arm/configs/stm32_defconfig | 2 ++
1 file changed, 2 insertions(+)
diff --git a/arch/arm/configs/stm32_defconfig b/arch/arm/configs/stm32_defconfig
index e7b56d4..71f9787 100644
--- a/arch/arm/configs/stm32_defconfig
+++ b/arch/arm/configs/stm32_defconfig
@@ -59,6 +59,8 @@ CONFIG_LEDS_CLASS=y
CONFIG_LEDS_GPIO=y
CONFIG_LEDS_TRIGGERS=y
CONFIG_LEDS_TRIGGER_HEARTBEAT=y
+CONFIG_RTC_CLASS=y
+CONFIG_RTC_DRV_STM32=y
CONFIG_DMADEVICES=y
CONFIG_STM32_DMA=y
# CONFIG_FILE_LOCKING is not set
--
1.9.1
--
You received this message because you are subscribed to "rtc-linux".
Membership options at http://groups.google.com/group/rtc-linux .
Please read http://groups.google.com/group/rtc-linux/web/checklist
before submitting a driver.
---
You received this message because you are subscribed to the Google Groups "rtc-linux" group.
To unsubscribe from this group and stop receiving emails from it, send an email to rtc-linux+unsubscribe-/JYPxA39Uh5TLH3MbocFF+G/Ez6ZCGd0@public.gmane.org
For more options, visit https://groups.google.com/d/optout.
^ permalink raw reply related
* Re: [resend v2: PATCH 1/2] dt-bindings: Document the hi3660 reset bindings
From: Philipp Zabel @ 2016-12-02 14:10 UTC (permalink / raw)
To: Arnd Bergmann
Cc: linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r, zhangfei,
devicetree-u79uwXL29TY76Z2rM5mHXA
In-Reply-To: <5982682.vMJxVociDa@wuerfel>
Am Freitag, den 02.12.2016, 13:32 +0100 schrieb Arnd Bergmann:
> On Friday, December 2, 2016 8:21:33 AM CET zhangfei wrote:
> > Hi, Arnd
> >
> > On 2016年12月01日 20:05, Arnd Bergmann wrote:
> > > On Thursday, December 1, 2016 8:48:40 AM CET Zhangfei Gao wrote:
> > >> + hisi,reset-bits = <0x20 0x8 /* 0: i2c0 */
> > >> + 0x20 0x10 /* 1: i2c1 */
> > >> + 0x20 0x20 /* 2: i2c2 */
> > >> + 0x20 0x8000000>; /* 3: i2c6 */
> > >> + };
> > >> +
> > >> +Specifying reset lines connected to IP modules
> > >> +==============================================
> > >> +example:
> > >> +
> > >> + i2c0: i2c@..... {
> > >> + ...
> > >> + resets = <&iomcu_rst 0>;
> > >> + ...
> > >> + };
> > > I don't really like this approach, since now the information is
> > > in two places. Why not put the data into the reset specifier
> > > directly when it is used?
>From my point of view, with the binding above, all reset controller
register/bit layout information is in a single place and can be easily
compared to a list in the reference manual, whereas with your suggestion
the description of the reset controller register layout is spread
throughout one or even several dtsi files.
Also, since no two reset controllers are exactly the same, we get a
proliferation of different slightly phandle argument meanings.
> > Any example, still not understand.
> > They are consumer and provider.
>
> I mean in the i2c node, have
>
> i2c0: i2c@..... {
> ...
> resets = <&iomcu_rst 0x20 0x8>;
> ...
> }
There already are a few drivers that use this, and I fear people having
to change their bindings because new flags are needed that have not been
previously thought of.
regards
Philipp
--
To unsubscribe from this list: send the line "unsubscribe devicetree" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
^ permalink raw reply
* [PATCH 5/6] net: stmmac: add support for independent DMA pbl for tx/rx
From: Niklas Cassel @ 2016-12-02 14:11 UTC (permalink / raw)
To: Rob Herring, Mark Rutland, Jonathan Corbet, Giuseppe Cavallaro,
Alexandre Torgue, David S. Miller, Phil Reid, Eric Engestrom,
Joachim Eastwood, Gabriel Fernandez, Vincent Palatin
Cc: Niklas Cassel, netdev, devicetree, linux-kernel, linux-doc
In-Reply-To: <1480687910-9690-1-git-send-email-niklass@axis.com>
From: Niklas Cassel <niklas.cassel@axis.com>
GMAC and newer supports independent programmable burst lengths for
DMA tx/rx. Add new optional devicetree properties representing this.
To be backwards compatible, snps,pbl will still be valid, but
snps,txpbl/snps,rxpbl will override the value in snps,pbl if set.
If the IP is synthesized to use the AXI interface, there is a register
and a matching DT property inside the optional stmmac-axi-config DT node
for controlling burst lengths, named snps,blen.
However, using this register, it is not possible to control tx and rx
independently. Also, this register is not available if the IP was
synthesized with, e.g., the AHB interface.
Signed-off-by: Niklas Cassel <niklas.cassel@axis.com>
---
Documentation/devicetree/bindings/net/stmmac.txt | 6 +++++-
Documentation/networking/stmmac.txt | 19 +++++++++++++------
drivers/net/ethernet/stmicro/stmmac/dwmac1000_dma.c | 12 ++++++------
drivers/net/ethernet/stmicro/stmmac/dwmac4_dma.c | 12 +++++++-----
drivers/net/ethernet/stmicro/stmmac/stmmac_platform.c | 2 ++
include/linux/stmmac.h | 2 ++
6 files changed, 35 insertions(+), 18 deletions(-)
diff --git a/Documentation/devicetree/bindings/net/stmmac.txt b/Documentation/devicetree/bindings/net/stmmac.txt
index b95ff998ba73..8080038ff1b2 100644
--- a/Documentation/devicetree/bindings/net/stmmac.txt
+++ b/Documentation/devicetree/bindings/net/stmmac.txt
@@ -34,7 +34,11 @@ Optional properties:
platforms.
- tx-fifo-depth: See ethernet.txt file in the same directory
- rx-fifo-depth: See ethernet.txt file in the same directory
-- snps,pbl Programmable Burst Length
+- snps,pbl Programmable Burst Length (tx and rx)
+- snps,txpbl Tx Programmable Burst Length. Only for GMAC and newer.
+ If set, DMA tx will use this value rather than snps,pbl.
+- snps,rxpbl Rx Programmable Burst Length. Only for GMAC and newer.
+ If set, DMA rx will use this value rather than snps,pbl.
- snps,aal Address-Aligned Beats
- snps,fixed-burst Program the DMA to use the fixed burst mode
- snps,mixed-burst Program the DMA to use the mixed burst mode
diff --git a/Documentation/networking/stmmac.txt b/Documentation/networking/stmmac.txt
index e226f8925c9e..82c8e496b4bb 100644
--- a/Documentation/networking/stmmac.txt
+++ b/Documentation/networking/stmmac.txt
@@ -154,7 +154,8 @@ Where:
o pbl: the Programmable Burst Length is maximum number of beats to
be transferred in one DMA transaction.
GMAC also enables the 4xPBL by default.
- o fixed_burst/mixed_burst/burst_len
+ o txpbl/rxpbl: GMAC and newer supports independent DMA pbl for tx/rx.
+ o fixed_burst/mixed_burst/aal
o clk_csr: fixed CSR Clock range selection.
o has_gmac: uses the GMAC core.
o enh_desc: if sets the MAC will use the enhanced descriptor structure.
@@ -206,16 +207,22 @@ tuned according to the HW capabilities.
struct stmmac_dma_cfg {
int pbl;
+ int txpbl;
+ int rxpbl;
int fixed_burst;
- int burst_len_supported;
+ int mixed_burst;
+ bool aal;
};
Where:
- o pbl: Programmable Burst Length
+ o pbl: Programmable Burst Length (tx and rx)
+ o txpbl: Transmit Programmable Burst Length. Only for GMAC and newer.
+ If set, DMA tx will use this value rather than pbl.
+ o rxpbl: Receive Programmable Burst Length. Only for GMAC and newer.
+ If set, DMA rx will use this value rather than pbl.
o fixed_burst: program the DMA to use the fixed burst mode
- o burst_len: this is the value we put in the register
- supported values are provided as macros in
- linux/stmmac.h header file.
+ o mixed_burst: program the DMA to use the mixed burst mode
+ o aal: Address-Aligned Beats
---
diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac1000_dma.c b/drivers/net/ethernet/stmicro/stmmac/dwmac1000_dma.c
index 01d0d0f315e5..1dd34fb4c1a9 100644
--- a/drivers/net/ethernet/stmicro/stmmac/dwmac1000_dma.c
+++ b/drivers/net/ethernet/stmicro/stmmac/dwmac1000_dma.c
@@ -87,20 +87,20 @@ static void dwmac1000_dma_init(void __iomem *ioaddr,
u32 dma_tx, u32 dma_rx, int atds)
{
u32 value = readl(ioaddr + DMA_BUS_MODE);
+ int txpbl = dma_cfg->txpbl ?: dma_cfg->pbl;
+ int rxpbl = dma_cfg->rxpbl ?: dma_cfg->pbl;
/*
* Set the DMA PBL (Programmable Burst Length) mode.
*
* Note: before stmmac core 3.50 this mode bit was 4xPBL, and
* post 3.5 mode bit acts as 8*PBL.
- *
- * This configuration doesn't take care about the Separate PBL
- * so only the bits: 13-8 are programmed with the PBL passed from the
- * platform.
*/
value |= DMA_BUS_MODE_MAXPBL;
- value &= ~DMA_BUS_MODE_PBL_MASK;
- value |= (dma_cfg->pbl << DMA_BUS_MODE_PBL_SHIFT);
+ value |= DMA_BUS_MODE_USP;
+ value &= ~(DMA_BUS_MODE_PBL_MASK | DMA_BUS_MODE_RPBL_MASK);
+ value |= (txpbl << DMA_BUS_MODE_PBL_SHIFT);
+ value |= (rxpbl << DMA_BUS_MODE_RPBL_SHIFT);
/* Set the Fixed burst mode */
if (dma_cfg->fixed_burst)
diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac4_dma.c b/drivers/net/ethernet/stmicro/stmmac/dwmac4_dma.c
index 0946546d6dcd..0bf47825bfeb 100644
--- a/drivers/net/ethernet/stmicro/stmmac/dwmac4_dma.c
+++ b/drivers/net/ethernet/stmicro/stmmac/dwmac4_dma.c
@@ -69,11 +69,14 @@ static void dwmac4_dma_axi(void __iomem *ioaddr, struct stmmac_axi *axi)
writel(value, ioaddr + DMA_SYS_BUS_MODE);
}
-static void dwmac4_dma_init_channel(void __iomem *ioaddr, int pbl,
+static void dwmac4_dma_init_channel(void __iomem *ioaddr,
+ struct stmmac_dma_cfg *dma_cfg,
u32 dma_tx_phy, u32 dma_rx_phy,
u32 channel)
{
u32 value;
+ int txpbl = dma_cfg->txpbl ?: dma_cfg->pbl;
+ int rxpbl = dma_cfg->rxpbl ?: dma_cfg->pbl;
/* set PBL for each channels. Currently we affect same configuration
* on each channel
@@ -83,11 +86,11 @@ static void dwmac4_dma_init_channel(void __iomem *ioaddr, int pbl,
writel(value, ioaddr + DMA_CHAN_CONTROL(channel));
value = readl(ioaddr + DMA_CHAN_TX_CONTROL(channel));
- value = value | (pbl << DMA_BUS_MODE_PBL_SHIFT);
+ value = value | (txpbl << DMA_BUS_MODE_PBL_SHIFT);
writel(value, ioaddr + DMA_CHAN_TX_CONTROL(channel));
value = readl(ioaddr + DMA_CHAN_RX_CONTROL(channel));
- value = value | (pbl << DMA_BUS_MODE_RPBL_SHIFT);
+ value = value | (rxpbl << DMA_BUS_MODE_RPBL_SHIFT);
writel(value, ioaddr + DMA_CHAN_RX_CONTROL(channel));
/* Mask interrupts by writing to CSR7 */
@@ -118,8 +121,7 @@ static void dwmac4_dma_init(void __iomem *ioaddr,
writel(value, ioaddr + DMA_SYS_BUS_MODE);
for (i = 0; i < DMA_CHANNEL_NB_MAX; i++)
- dwmac4_dma_init_channel(ioaddr, dma_cfg->pbl,
- dma_tx, dma_rx, i);
+ dwmac4_dma_init_channel(ioaddr, dma_cfg, dma_tx, dma_rx, i);
}
static void _dwmac4_dump_dma_regs(void __iomem *ioaddr, u32 channel)
diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_platform.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_platform.c
index 05b8c33effd5..29faff42a5ea 100644
--- a/drivers/net/ethernet/stmicro/stmmac/stmmac_platform.c
+++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_platform.c
@@ -312,6 +312,8 @@ stmmac_probe_config_dt(struct platform_device *pdev, const char **mac)
plat->dma_cfg = dma_cfg;
of_property_read_u32(np, "snps,pbl", &dma_cfg->pbl);
+ of_property_read_u32(np, "snps,txpbl", &dma_cfg->txpbl);
+ of_property_read_u32(np, "snps,rxpbl", &dma_cfg->rxpbl);
dma_cfg->aal = of_property_read_bool(np, "snps,aal");
dma_cfg->fixed_burst = of_property_read_bool(np, "snps,fixed-burst");
diff --git a/include/linux/stmmac.h b/include/linux/stmmac.h
index 705840e0438f..c8a7c6b278da 100644
--- a/include/linux/stmmac.h
+++ b/include/linux/stmmac.h
@@ -88,6 +88,8 @@ struct stmmac_mdio_bus_data {
struct stmmac_dma_cfg {
int pbl;
+ int txpbl;
+ int rxpbl;
int fixed_burst;
int mixed_burst;
bool aal;
--
2.1.4
^ permalink raw reply related
* [PATCH 6/6] net: smmac: allow configuring lower pbl values
From: Niklas Cassel @ 2016-12-02 14:13 UTC (permalink / raw)
To: Rob Herring, Mark Rutland, Jonathan Corbet, Giuseppe Cavallaro,
Alexandre Torgue, David S. Miller, Phil Reid, Eric Engestrom,
Vincent Palatin, Andreas Färber, Gabriel Fernandez,
Joachim Eastwood
Cc: Niklas Cassel, netdev, devicetree, linux-kernel, linux-doc
From: Niklas Cassel <niklas.cassel@axis.com>
The driver currently always sets the PBLx8/PBLx4 bit, which means that
the pbl values configured via the pbl/txpbl/rxpbl DT properties are
always multiplied by 8/4 in the hardware.
In order to allow the DT to configure lower pbl values, while at the
same time not changing behavior of any existing device trees using the
pbl/txpbl/rxpbl settings, add a property to disable the multiplication
of the pbl by 8/4 in the hardware.
Suggested-by: Rabin Vincent <rabinv@axis.com>
Signed-off-by: Niklas Cassel <niklas.cassel@axis.com>
---
Documentation/devicetree/bindings/net/stmmac.txt | 2 ++
Documentation/networking/stmmac.txt | 5 ++++-
drivers/net/ethernet/stmicro/stmmac/dwmac1000_dma.c | 3 ++-
drivers/net/ethernet/stmicro/stmmac/dwmac4_dma.c | 3 ++-
drivers/net/ethernet/stmicro/stmmac/stmmac_pci.c | 2 ++
drivers/net/ethernet/stmicro/stmmac/stmmac_platform.c | 1 +
include/linux/stmmac.h | 1 +
7 files changed, 14 insertions(+), 3 deletions(-)
diff --git a/Documentation/devicetree/bindings/net/stmmac.txt b/Documentation/devicetree/bindings/net/stmmac.txt
index 8080038ff1b2..128da752fec9 100644
--- a/Documentation/devicetree/bindings/net/stmmac.txt
+++ b/Documentation/devicetree/bindings/net/stmmac.txt
@@ -39,6 +39,8 @@ Optional properties:
If set, DMA tx will use this value rather than snps,pbl.
- snps,rxpbl Rx Programmable Burst Length. Only for GMAC and newer.
If set, DMA rx will use this value rather than snps,pbl.
+- snps,no-pbl-x8 Don't multiply the pbl/txpbl/rxpbl values by 8.
+ For core rev < 3.50, don't multiply the values by 4.
- snps,aal Address-Aligned Beats
- snps,fixed-burst Program the DMA to use the fixed burst mode
- snps,mixed-burst Program the DMA to use the mixed burst mode
diff --git a/Documentation/networking/stmmac.txt b/Documentation/networking/stmmac.txt
index 82c8e496b4bb..d3376c5fbcf0 100644
--- a/Documentation/networking/stmmac.txt
+++ b/Documentation/networking/stmmac.txt
@@ -153,8 +153,9 @@ Where:
o dma_cfg: internal DMA parameters
o pbl: the Programmable Burst Length is maximum number of beats to
be transferred in one DMA transaction.
- GMAC also enables the 4xPBL by default.
+ GMAC also enables the 4xPBL by default. (8xPBL for GMAC 3.50 and newer)
o txpbl/rxpbl: GMAC and newer supports independent DMA pbl for tx/rx.
+ o pblx8: Enable 8xPBL (4xPBL for core rev < 3.50). Enabled by default.
o fixed_burst/mixed_burst/aal
o clk_csr: fixed CSR Clock range selection.
o has_gmac: uses the GMAC core.
@@ -209,6 +210,7 @@ struct stmmac_dma_cfg {
int pbl;
int txpbl;
int rxpbl;
+ bool pblx8;
int fixed_burst;
int mixed_burst;
bool aal;
@@ -220,6 +222,7 @@ Where:
If set, DMA tx will use this value rather than pbl.
o rxpbl: Receive Programmable Burst Length. Only for GMAC and newer.
If set, DMA rx will use this value rather than pbl.
+ o pblx8: Enable 8xPBL (4xPBL for core rev < 3.50). Enabled by default.
o fixed_burst: program the DMA to use the fixed burst mode
o mixed_burst: program the DMA to use the mixed burst mode
o aal: Address-Aligned Beats
diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac1000_dma.c b/drivers/net/ethernet/stmicro/stmmac/dwmac1000_dma.c
index 1dd34fb4c1a9..1d313af647b4 100644
--- a/drivers/net/ethernet/stmicro/stmmac/dwmac1000_dma.c
+++ b/drivers/net/ethernet/stmicro/stmmac/dwmac1000_dma.c
@@ -96,7 +96,8 @@ static void dwmac1000_dma_init(void __iomem *ioaddr,
* Note: before stmmac core 3.50 this mode bit was 4xPBL, and
* post 3.5 mode bit acts as 8*PBL.
*/
- value |= DMA_BUS_MODE_MAXPBL;
+ if (dma_cfg->pblx8)
+ value |= DMA_BUS_MODE_MAXPBL;
value |= DMA_BUS_MODE_USP;
value &= ~(DMA_BUS_MODE_PBL_MASK | DMA_BUS_MODE_RPBL_MASK);
value |= (txpbl << DMA_BUS_MODE_PBL_SHIFT);
diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac4_dma.c b/drivers/net/ethernet/stmicro/stmmac/dwmac4_dma.c
index 0bf47825bfeb..0f7110d19a4a 100644
--- a/drivers/net/ethernet/stmicro/stmmac/dwmac4_dma.c
+++ b/drivers/net/ethernet/stmicro/stmmac/dwmac4_dma.c
@@ -82,7 +82,8 @@ static void dwmac4_dma_init_channel(void __iomem *ioaddr,
* on each channel
*/
value = readl(ioaddr + DMA_CHAN_CONTROL(channel));
- value = value | DMA_BUS_MODE_PBL;
+ if (dma_cfg->pblx8)
+ value = value | DMA_BUS_MODE_PBL;
writel(value, ioaddr + DMA_CHAN_CONTROL(channel));
value = readl(ioaddr + DMA_CHAN_TX_CONTROL(channel));
diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_pci.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_pci.c
index 56c8a2342c14..a2831773431a 100644
--- a/drivers/net/ethernet/stmicro/stmmac/stmmac_pci.c
+++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_pci.c
@@ -81,6 +81,7 @@ static void stmmac_default_data(struct plat_stmmacenet_data *plat)
plat->mdio_bus_data->phy_mask = 0;
plat->dma_cfg->pbl = 32;
+ plat->dma_cfg->pblx8 = true;
/* TODO: AXI */
/* Set default value for multicast hash bins */
@@ -115,6 +116,7 @@ static int quark_default_data(struct plat_stmmacenet_data *plat,
plat->mdio_bus_data->phy_mask = 0;
plat->dma_cfg->pbl = 16;
+ plat->dma_cfg->pblx8 = true;
plat->dma_cfg->fixed_burst = 1;
/* AXI (TODO) */
diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_platform.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_platform.c
index 29faff42a5ea..3a713862f0a3 100644
--- a/drivers/net/ethernet/stmicro/stmmac/stmmac_platform.c
+++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_platform.c
@@ -314,6 +314,7 @@ stmmac_probe_config_dt(struct platform_device *pdev, const char **mac)
of_property_read_u32(np, "snps,pbl", &dma_cfg->pbl);
of_property_read_u32(np, "snps,txpbl", &dma_cfg->txpbl);
of_property_read_u32(np, "snps,rxpbl", &dma_cfg->rxpbl);
+ dma_cfg->pblx8 = !of_property_read_bool(np, "snps,no-pbl-x8");
dma_cfg->aal = of_property_read_bool(np, "snps,aal");
dma_cfg->fixed_burst = of_property_read_bool(np, "snps,fixed-burst");
diff --git a/include/linux/stmmac.h b/include/linux/stmmac.h
index c8a7c6b278da..05a8243017b0 100644
--- a/include/linux/stmmac.h
+++ b/include/linux/stmmac.h
@@ -90,6 +90,7 @@ struct stmmac_dma_cfg {
int pbl;
int txpbl;
int rxpbl;
+ bool pblx8;
int fixed_burst;
int mixed_burst;
bool aal;
--
2.1.4
^ permalink raw reply related
* Re: [PATCH v2 2/3] ARM: dts: sunxi: add support for Orange Pi Zero board
From: Icenowy Zheng @ 2016-12-02 14:22 UTC (permalink / raw)
To: Maxime Ripard, André Przywara
Cc: Mark Rutland, devicetree@vger.kernel.org, Vishnu Patekar,
Arnd Bergmann, Jonathan Corbet, linux-doc@vger.kernel.org,
Russell King, linux-kernel@vger.kernel.org, Hans de Goede,
Chen-Yu Tsai, linux-arm-kernel@lists.infradead.org
In-Reply-To: <20161201093619.gs6lmoxtlptp2jr6@lukather>
01.12.2016, 17:36, "Maxime Ripard" <maxime.ripard@free-electrons.com>:
> On Mon, Nov 28, 2016 at 12:29:07AM +0000, André Przywara wrote:
>> > Something more interesting happened.
>> >
>> > Xunlong made a add-on board for Orange Pi Zero, which exposes the
>> > two USB Controllers exported at expansion bus as USB Type-A
>> > connectors.
>> >
>> > Also it exposes a analog A/V jack and a microphone.
>> >
>> > Should I enable {e,o}hci{2.3} in the device tree?
>>
>> Actually we should do this regardless of this extension board. The USB
>> pins are not multiplexed and are exposed on user accessible pins (just
>> not soldered, but that's a detail), so I think they qualify for DT
>> enablement. And even if a user can't use them, it doesn't hurt to have
>> them (since they are not multiplexed).
>
> My main concern about this is that we'll leave regulators enabled by
> default, for a minority of users. And that minority will prevent to do
> a proper power management when the times come since we'll have to keep
> that behaviour forever.
I think these users can add a 'fdt set /xxx/xxx status "disabled" ' .
>
> Maxime
>
> --
> Maxime Ripard, Free Electrons
> Embedded Linux and Kernel engineering
> http://free-electrons.com
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
^ permalink raw reply
* Re: [PATCH v3 3/7] PWM: add pwm-stm32 DT bindings
From: Lee Jones @ 2016-12-02 14:23 UTC (permalink / raw)
To: Benjamin Gaignard
Cc: robh+dt-DgEjT+Ai2ygdnm+yROfE0A, mark.rutland-5wv7dgnIgG8,
alexandre.torgue-qxv4g6HH51o, devicetree-u79uwXL29TY76Z2rM5mHXA,
linux-kernel-u79uwXL29TY76Z2rM5mHXA,
thierry.reding-Re5JQEeQqe8AvxtiuMwx3w,
linux-pwm-u79uwXL29TY76Z2rM5mHXA, jic23-DgEjT+Ai2ygdnm+yROfE0A,
knaack.h-Mmb7MZpHnFY, lars-Qo5EllUWu/uELgA04lAiVw,
pmeerw-jW+XmwGofnusTnJN9+BGXg, linux-iio-u79uwXL29TY76Z2rM5mHXA,
linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r,
fabrice.gasnier-qxv4g6HH51o, gerald.baeza-qxv4g6HH51o,
arnaud.pouliquen-qxv4g6HH51o,
linus.walleij-QSEj5FYQhm4dnm+yROfE0A,
linaro-kernel-cunTk1MwBs8s++Sfvej+rw, Benjamin Gaignard
In-Reply-To: <1480673842-20804-4-git-send-email-benjamin.gaignard-qxv4g6HH51o@public.gmane.org>
On Fri, 02 Dec 2016, Benjamin Gaignard wrote:
> Define bindings for pwm-stm32
>
> version 2:
> - use parameters instead of compatible of handle the hardware configuration
>
> Signed-off-by: Benjamin Gaignard <benjamin.gaignard-qxv4g6HH51o@public.gmane.org>
> ---
> .../devicetree/bindings/pwm/pwm-stm32.txt | 38 ++++++++++++++++++++++
> 1 file changed, 38 insertions(+)
> create mode 100644 Documentation/devicetree/bindings/pwm/pwm-stm32.txt
>
> diff --git a/Documentation/devicetree/bindings/pwm/pwm-stm32.txt b/Documentation/devicetree/bindings/pwm/pwm-stm32.txt
> new file mode 100644
> index 0000000..575b9fb
> --- /dev/null
> +++ b/Documentation/devicetree/bindings/pwm/pwm-stm32.txt
> @@ -0,0 +1,38 @@
> +STMicroelectronics PWM driver bindings for STM32
> +
> +Must be a sub-node of STM32 general purpose timer driver
> +Parent node properties are describe in ../mfd/stm32-general-purpose-timer.txt
> +
> +Required parameters:
> +- compatible: Must be "st,stm32-pwm"
> +- pinctrl-names: Set to "default".
> +- pinctrl-0: List of phandles pointing to pin configuration nodes
> + for PWM module.
> + For Pinctrl properties, please refer to [1].
> +
> +Optional parameters:
> +- st,breakinput: Set if the hardware have break input capabilities
> +- st,breakinput-polarity: Set break input polarity. Default is 0
> + The value define the active polarity:
> + - 0 (active LOW)
> + - 1 (active HIGH)
> +- st,breakinput-polarity-high
Then assume the default if the property is not present.
> +- st,pwm-num-chan: Number of available PWM channels. Default is 0.
What's the point in having a PWM device with no channels?
Best to make this a compulsory property.
> +- st,32bits-counter: Set if the hardware have a 32 bits counter
> +- st,complementary: Set if the hardware have complementary output channels
> +
> +[1] Documentation/devicetree/bindings/pinctrl/pinctrl-bindings.txt
Use relative path.
../pinctrl/pinctrl-bindings.txt
> +Example:
> + gptimer1: gptimer1@40010000 {
> + compatible = "st,stm32-gptimer";
> + reg = <0x40010000 0x400>;
> + clocks = <&rcc 0 160>;
> + clock-names = "clk_int";
> +
> + pwm1@0 {
Don't number the node name.
pwm@xx
> + compatible = "st,stm32-pwm";
> + st,pwm-num-chan = <4>;
> + st,breakinput;
> + st,complementary;
> + };
> + };
--
Lee Jones
Linaro STMicroelectronics Landing Team Lead
Linaro.org │ Open source software for ARM SoCs
Follow Linaro: Facebook | Twitter | Blog
^ permalink raw reply
* Re: [PATCH v3 5/7] IIO: add bindings for stm32 timer trigger driver
From: Benjamin Gaignard @ 2016-12-02 14:23 UTC (permalink / raw)
To: Lee Jones
Cc: robh+dt, Mark Rutland, alexandre.torgue, devicetree,
Linux Kernel Mailing List, Thierry Reding, linux-pwm,
Jonathan Cameron, knaack.h, Lars-Peter Clausen,
Peter Meerwald-Stadler, linux-iio, linux-arm-kernel,
Fabrice Gasnier, Gerald Baeza, Arnaud Pouliquen, Linus Walleij,
Linaro Kernel Mailman List, Benjamin Gaignard
In-Reply-To: <20161202135904.GN2683@dell>
2016-12-02 14:59 GMT+01:00 Lee Jones <lee.jones@linaro.org>:
> On Fri, 02 Dec 2016, Benjamin Gaignard wrote:
>
>> Define bindings for stm32 timer trigger
>>
>> version 3:
>> - change file name
>> - add cross reference with mfd bindings
>>
>> version 2:
>> - only keep one compatible
>> - add DT parameters to set lists of the triggers:
>> one list describe the triggers created by the device
>> another one give the triggers accepted by the device
>>
>> Signed-off-by: Benjamin Gaignard <benjamin.gaignard@st.com>
>> ---
>> .../bindings/iio/timer/stm32-timer-trigger.txt | 39 ++++++++++++++++++++++
>> 1 file changed, 39 insertions(+)
>> create mode 100644 Documentation/devicetree/bindings/iio/timer/stm32-timer-trigger.txt
>>
>> diff --git a/Documentation/devicetree/bindings/iio/timer/stm32-timer-trigger.txt b/Documentation/devicetree/bindings/iio/timer/stm32-timer-trigger.txt
>> new file mode 100644
>> index 0000000..858816d
>> --- /dev/null
>> +++ b/Documentation/devicetree/bindings/iio/timer/stm32-timer-trigger.txt
>> @@ -0,0 +1,39 @@
>> +timer trigger bindings for STM32
>> +
>> +Must be a sub-node of STM32 general purpose timer driver
>> +Parent node properties are describe in ../mfd/stm32-general-purpose-timer.txt
>> +
>> +Required parameters:
>> +- compatible: must be "st,stm32-iio-timer"
>> +- interrupts: Interrupt for this device
>> + See ../interrupt-controller/st,stm32-exti.txt
>> +
>> +Optional parameters:
>> +- st,input-triggers-names: List of the possible input triggers for
>> + the device
>> +- st,output-triggers-names: List of the possible output triggers for
>> + the device
>> +
>> +Possible triggers are defined in include/dt-bindings/iio/timer/st,stm32-timer-trigger.h
>> +
>> +Example:
>> + gptimer1: gptimer1@40010000 {
>> + compatible = "st,stm32-gptimer";
>> + reg = <0x40010000 0x400>;
>> + clocks = <&rcc 0 160>;
>> + clock-names = "clk_int";
>> +
>> + timer1@0 {
>> + compatible = "st,stm32-timer-trigger";
>> + interrupts = <27>;
>> + st,input-triggers-names = TIM5_TRGO,
>> + TIM2_TRGO,
>> + TIM4_TRGO,
>> + TIM3_TRGO;
>> + st,output-triggers-names = TIM1_TRGO,
>> + TIM1_CH1,
>> + TIM1_CH2,
>> + TIM1_CH3,
>> + TIM1_CH4;
>
> I see why you've done it like this now ... because it makes things
> easier for you in the driver, since the IIO subsystem matches on names
> such as these.
>
> BUT, this is a Linux-implementation-ism. Just use pairs of integers
> and create the Linux-ism strings in the driver.
The goal is not to make things easier in driver but to be able to share
the triggers names with other drivers like DAC or ADC.
If each driver have to create it own triggers names it will more difficult
to keep them coherent than it they share the same definitions
>
>> + };
>> + };
>
> --
> Lee Jones
> Linaro STMicroelectronics Landing Team Lead
> Linaro.org │ Open source software for ARM SoCs
> Follow Linaro: Facebook | Twitter | Blog
^ permalink raw reply
page: next (older) | prev (newer) | latest
- recent:[subjects (threaded)|topics (new)|topics (active)]
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox