Devicetree
 help / color / mirror / Atom feed
* [PATCH v2 2/4] dt-bindings: Add vendor prefix for Adafruit
From: David Lechner @ 2018-05-25 19:36 UTC (permalink / raw)
  To: dri-devel, devicetree
  Cc: Mark Rutland, limor, David Lechner, linux-kernel, Rob Herring,
	Nitin Patil
In-Reply-To: <20180525193623.15533-1-david@lechnology.com>

This adds a device tree vendor prefix for Adafruit Industries, LLC.

Signed-off-by: David Lechner <david@lechnology.com>
---
 Documentation/devicetree/bindings/vendor-prefixes.txt | 1 +
 1 file changed, 1 insertion(+)

diff --git a/Documentation/devicetree/bindings/vendor-prefixes.txt b/Documentation/devicetree/bindings/vendor-prefixes.txt
index b5f978a4cac6..4d2ba7f52059 100644
--- a/Documentation/devicetree/bindings/vendor-prefixes.txt
+++ b/Documentation/devicetree/bindings/vendor-prefixes.txt
@@ -8,6 +8,7 @@ abracon	Abracon Corporation
 actions	Actions Semiconductor Co., Ltd.
 active-semi	Active-Semi International Inc
 ad	Avionic Design GmbH
+adafruit	Adafruit Industries, LLC
 adapteva	Adapteva, Inc.
 adaptrum	Adaptrum, Inc.
 adh	AD Holdings Plc.
-- 
2.17.0

_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

^ permalink raw reply related

* [PATCH v2 1/4] MAINTAINERS: fix path to ilitek, ili9225 device tree bindings
From: David Lechner @ 2018-05-25 19:36 UTC (permalink / raw)
  To: dri-devel, devicetree
  Cc: Mark Rutland, limor, David Lechner, linux-kernel, Rob Herring,
	Nitin Patil
In-Reply-To: <20180525193623.15533-1-david@lechnology.com>

This fixes the path to the ilitek,ili9225 device tree binding file.

Signed-off-by: David Lechner <david@lechnology.com>
Reviewed-by: Noralf Trønnes <noralf@tronnes.org>
---
 MAINTAINERS | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/MAINTAINERS b/MAINTAINERS
index 334a00350922..bc219de9cbee 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -4478,7 +4478,7 @@ DRM DRIVER FOR ILITEK ILI9225 PANELS
 M:	David Lechner <david@lechnology.com>
 S:	Maintained
 F:	drivers/gpu/drm/tinydrm/ili9225.c
-F:	Documentation/devicetree/bindings/display/ili9225.txt
+F:	Documentation/devicetree/bindings/display/ilitek,ili9225.txt
 
 DRM DRIVER FOR INTEL I810 VIDEO CARDS
 S:	Orphan / Obsolete
-- 
2.17.0

_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

^ permalink raw reply related

* [PATCH v2 0/4] drm/tinydrm: new dirver for ILI9341 displays
From: David Lechner @ 2018-05-25 19:36 UTC (permalink / raw)
  To: dri-devel, devicetree
  Cc: Mark Rutland, limor, David Lechner, linux-kernel, Rob Herring,
	Nitin Patil

This series adds a new tinydrm driver for the Ilitek ILI9341 controller and
a 2.4" display panel that uses this controller.

A few things to note here:
* The datasheet for this display[1] doesn't have a vendor mentioned on it
  anywhere, so I have used "adafruit" as the vendor prefix. If someone has a
  better suggestion, please speak up.
* The MAINTAINERS patch for ili9225 is included so we don't end up with a merge
  conflict later on.

v2 changes:
* change vendor prefix from "noname" to "adafruit"
* new patch for "adafruit" vendor prefix
* minor style changes
* drop regulator from driver (instead of adding to DT bindings)

[1]: https://cdn-learn.adafruit.com/assets/assets/000/046/879/original/SPEC-YX240QV29-T_Rev.A__1_.pdf


David Lechner (4):
  MAINTAINERS: fix path to ilitek,ili9225 device tree bindings
  dt-bindings: Add vendor prefix for Adafruit
  dt-bindings: new binding for Ilitek ILI9341 display panels
  drm/tinydrm: new driver for ILI9341 display panels

 .../bindings/display/ilitek,ili9341.txt       |  27 ++
 .../devicetree/bindings/vendor-prefixes.txt   |   1 +
 MAINTAINERS                                   |   8 +-
 drivers/gpu/drm/tinydrm/Kconfig               |  10 +
 drivers/gpu/drm/tinydrm/Makefile              |   1 +
 drivers/gpu/drm/tinydrm/ili9341.c             | 233 ++++++++++++++++++
 6 files changed, 279 insertions(+), 1 deletion(-)
 create mode 100644 Documentation/devicetree/bindings/display/ilitek,ili9341.txt
 create mode 100644 drivers/gpu/drm/tinydrm/ili9341.c

-- 
2.17.0

_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

^ permalink raw reply

* Re: [PATCH v2] arm64: dts: apq8096-db820c: Removed bt-en-1-8v regulator
From: Bjorn Andersson @ 2018-05-25 19:32 UTC (permalink / raw)
  To: Thierry Escande
  Cc: Andy Gross, David Brown, Rob Herring, Mark Rutland,
	Catalin Marinas, Will Deacon, Niklas Cassel, linux-arm-msm,
	devicetree, linux-kernel
In-Reply-To: <20180524180155.24839-1-thierry.escande@linaro.org>

On Thu 24 May 11:01 PDT 2018, Thierry Escande wrote:

> This patch removes the unused bt-en-1-8v regulator and moves the
> bt_en_gios claim to the pm8994_gpios node.
> 
> This bt_en_gpio could have been moved to the bluetooth serial node but
> instead this node declares an 'enable' gpio addressing the bt_en_gpio.
> This is needed by the Qualcomm QCA6174 WLAN/BT combo chip that needs to
> have the bt_en_gpio claimed even if only WLAN is used.
> 
> Signed-off-by: Thierry Escande <thierry.escande@linaro.org>

Reviewed-by: Bjorn Andersson <bjorn.andersson@linaro.org>

Regards,
Bjorn

> ---
> 
> Change in v2:
> - Rebased on top of [1] posted a few days ago:
> 
> [1] https://lkml.org/lkml/2018/5/22/949
>     "arm64: dts: fix regulator property name for wlan pcie endpoint"
>     
> 
>  arch/arm64/boot/dts/qcom/apq8096-db820c-pmic-pins.dtsi |  2 +-
>  arch/arm64/boot/dts/qcom/apq8096-db820c.dtsi           | 14 --------------
>  2 files changed, 1 insertion(+), 15 deletions(-)
> 
> diff --git a/arch/arm64/boot/dts/qcom/apq8096-db820c-pmic-pins.dtsi b/arch/arm64/boot/dts/qcom/apq8096-db820c-pmic-pins.dtsi
> index 6167af955659..a6ad3d7fe655 100644
> --- a/arch/arm64/boot/dts/qcom/apq8096-db820c-pmic-pins.dtsi
> +++ b/arch/arm64/boot/dts/qcom/apq8096-db820c-pmic-pins.dtsi
> @@ -4,7 +4,7 @@
>  &pm8994_gpios {
>  
>  	pinctrl-names = "default";
> -	pinctrl-0 = <&ls_exp_gpio_f>;
> +	pinctrl-0 = <&ls_exp_gpio_f &bt_en_gpios>;
>  
>  	ls_exp_gpio_f: pm8994_gpio5 {
>  		pinconf {
> diff --git a/arch/arm64/boot/dts/qcom/apq8096-db820c.dtsi b/arch/arm64/boot/dts/qcom/apq8096-db820c.dtsi
> index 7ca6e78def55..2c026b8af792 100644
> --- a/arch/arm64/boot/dts/qcom/apq8096-db820c.dtsi
> +++ b/arch/arm64/boot/dts/qcom/apq8096-db820c.dtsi
> @@ -171,19 +171,6 @@
>  			pinctrl-0 = <&usb2_vbus_det_gpio>;
>  		};
>  
> -		bt_en: bt-en-1-8v {
> -			pinctrl-names = "default";
> -			pinctrl-0 = <&bt_en_gpios>;
> -			compatible = "regulator-fixed";
> -			regulator-name = "bt-en-regulator";
> -			regulator-min-microvolt = <1800000>;
> -			regulator-max-microvolt = <1800000>;
> -
> -			/* WLAN card specific delay */
> -			startup-delay-us = <70000>;
> -			enable-active-high;
> -		};
> -
>  		wlan_en: wlan-en-1-8v {
>  			pinctrl-names = "default";
>  			pinctrl-0 = <&wlan_en_gpios>;
> @@ -204,7 +191,6 @@
>  				status = "okay";
>  				perst-gpio = <&msmgpio 35 GPIO_ACTIVE_LOW>;
>  				vddpe-3v3-supply = <&wlan_en>;
> -				vddpe1-supply = <&bt_en>;
>  			};
>  
>  			pcie@608000 {
> -- 
> 2.14.1
> 

^ permalink raw reply

* Re: [PATCH] arm64: dts: fix regulator property name for wlan pcie endpoint
From: Bjorn Andersson @ 2018-05-25 19:32 UTC (permalink / raw)
  To: Niklas Cassel
  Cc: Andy Gross, David Brown, Rob Herring, Mark Rutland,
	Catalin Marinas, Will Deacon, linux-arm-msm, linux-soc,
	devicetree, linux-arm-kernel, linux-kernel
In-Reply-To: <20180522195758.24607-1-niklas.cassel@linaro.org>

On Tue 22 May 12:57 PDT 2018, Niklas Cassel wrote:

> The property name vddpe-supply is not included in
> Documentation/devicetree/bindings/pci/qcom,pcie.txt
> nor in the pcie-qcom PCIe Root Complex driver.
> 
> This property name was used in an initial patchset for pcie-qcom,
> but was renamed in a later revision.
> 
> Therefore, the regulator is currently never enabled, leaving us with
> unoperational wlan.
> 
> Fix this by using the correct regulator property name, so that wlan
> comes up correctly.
> 
> Fixes: 1c8ca74a2ea1 ("arm64: dts: apq8096-db820c: Enable wlan and bt en pins")
> Signed-off-by: Niklas Cassel <niklas.cassel@linaro.org>

Reviewed-by: Bjorn Andersson <bjorn.andersson@linaro.org>

Regards,
Bjorn

> ---
> Bluetooth needs a similar patch, but since bluetooth needs some more
> work, submit this right now, so we at least have working wlan.
> 
>  arch/arm64/boot/dts/qcom/apq8096-db820c.dtsi | 2 +-
>  1 file changed, 1 insertion(+), 1 deletion(-)
> 
> diff --git a/arch/arm64/boot/dts/qcom/apq8096-db820c.dtsi b/arch/arm64/boot/dts/qcom/apq8096-db820c.dtsi
> index 818bf0efd501..804268f54f37 100644
> --- a/arch/arm64/boot/dts/qcom/apq8096-db820c.dtsi
> +++ b/arch/arm64/boot/dts/qcom/apq8096-db820c.dtsi
> @@ -203,7 +203,7 @@
>  			pcie@600000 {
>  				status = "okay";
>  				perst-gpio = <&msmgpio 35 GPIO_ACTIVE_LOW>;
> -				vddpe-supply = <&wlan_en>;
> +				vddpe-3v3-supply = <&wlan_en>;
>  				vddpe1-supply = <&bt_en>;
>  			};
>  
> -- 
> 2.17.0
> 
> --
> To unsubscribe from this list: send the line "unsubscribe linux-arm-msm" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html

^ permalink raw reply

* RE: [PATCH v6 09/11] firmware: xilinx: Add debugfs for clock control APIs
From: Jolly Shah @ 2018-05-25 19:23 UTC (permalink / raw)
  To: Sudeep Holla, ard.biesheuvel@linaro.org, mingo@kernel.org,
	gregkh@linuxfoundation.org, matt@codeblueprint.co.uk,
	hkallweit1@gmail.com, keescook@chromium.org,
	dmitry.torokhov@gmail.com, mturquette@baylibre.com,
	sboyd@codeaurora.org, michal.simek@xilinx.com, robh+dt@kernel.org,
	mark.rutland@arm.com, linux-clk@vger.kernel.org
  Cc: Rajan Vaja, linux-arm-kernel@lists.infradead.org,
	linux-kernel@vger.kernel.org, devicetree@vger.kernel.org
In-Reply-To: <6579fdce-6845-70d5-1dc1-64d52debef19@arm.com>

Hi Sudeep,

> -----Original Message-----
> From: Sudeep Holla [mailto:sudeep.holla@arm.com]
> Sent: Tuesday, May 15, 2018 1:58 AM
> To: Jolly Shah <JOLLYS@xilinx.com>; ard.biesheuvel@linaro.org;
> mingo@kernel.org; gregkh@linuxfoundation.org; matt@codeblueprint.co.uk;
> hkallweit1@gmail.com; keescook@chromium.org;
> dmitry.torokhov@gmail.com; mturquette@baylibre.com;
> sboyd@codeaurora.org; michal.simek@xilinx.com; robh+dt@kernel.org;
> mark.rutland@arm.com; linux-clk@vger.kernel.org
> Cc: Sudeep Holla <sudeep.holla@arm.com>; Rajan Vaja <RAJANV@xilinx.com>;
> linux-arm-kernel@lists.infradead.org; linux-kernel@vger.kernel.org;
> devicetree@vger.kernel.org
> Subject: Re: [PATCH v6 09/11] firmware: xilinx: Add debugfs for clock control
> APIs
> 
> 
> 
> On 14/05/18 20:18, Jolly Shah wrote:
> > Hi Sudeep,
> 
> [..]
> 
> >>
> >> As I mentioned in earlier patch, I don't see the need for this
> >> debugfs interface. Clock lay has read-only interface in debugfs
> >> already. Also if you want to debug clocks, you can do so using the
> >> driver which uses these clocks. Do you really want to manage clocks
> >> in user-space ? The whole idea of EEMI kind of interface is to
> >> abstract and hide the fine details even from non-trusted rich OS like
> >> Linux kernel, but by providing this you are doing exactly opposite.
> >
> > No we don't want to manage clocks in user-space. This debugfs is meant
> > for developer who wants to debug APIs behavior in case something
> > doesn't work as expected. Debugfs should be off by default in
> > production images.
> >
> 
> Good that it's not used in production image. The clock layer has
> *sufficient* debugfs support that will *help in debugging*. So please drop this
> Xilinx specific clock debugfs.
> 
> --
> Regards,
> Sudeep

Ok. Will remove them in next version. Let me know if rest changes look ok and I can submit final version with suggested minor changes.

Thanks,
Jolly Shah



^ permalink raw reply

* [PATCH v2] arm64: dts: qcom: msm8996: Move UFS_GDSC to UFS HCD
From: Bjorn Andersson @ 2018-05-25 18:45 UTC (permalink / raw)
  To: Andy Gross, Manu Gautam, Vivek Gautam
  Cc: linux-arm-msm, linux-soc, devicetree, linux-arm-kernel,
	linux-kernel
In-Reply-To: <20180524223122.12601-1-bjorn.andersson@linaro.org>

The UFS_GDSC backs the resources needed by the UFS HCD, rather than the
PHY. This results in the UFS HCD occationally failing to enable some of
its clocks.

Move the UFS_GDSC reference to the UFS HCD node instead, to correct
this.

Signed-off-by: Bjorn Andersson <bjorn.andersson@linaro.org>
---

Changes since v1:
- Dropped UFS_GDSC from phy node

 arch/arm64/boot/dts/qcom/msm8996.dtsi | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/arch/arm64/boot/dts/qcom/msm8996.dtsi b/arch/arm64/boot/dts/qcom/msm8996.dtsi
index 380e14591686..8c7f9ca25b53 100644
--- a/arch/arm64/boot/dts/qcom/msm8996.dtsi
+++ b/arch/arm64/boot/dts/qcom/msm8996.dtsi
@@ -654,8 +654,6 @@
 			clocks = <&rpmcc RPM_SMD_LN_BB_CLK>,
 				 <&gcc GCC_UFS_CLKREF_CLK>;
 			status = "disabled";
-
-			power-domains = <&gcc UFS_GDSC>;
 		};
 
 		ufshc@624000 {
@@ -674,6 +672,8 @@
 			vccq-max-microamp = <450000>;
 			vccq2-max-microamp = <450000>;
 
+			power-domains = <&gcc UFS_GDSC>;
+
 			clock-names =
 				"core_clk_src",
 				"core_clk",
-- 
2.17.0

^ permalink raw reply related

* Re: [PATCH] arm64: dts: qcom: msm8996: Use UFS_GDSC for UFS
From: Bjorn Andersson @ 2018-05-25 18:35 UTC (permalink / raw)
  To: Vivek Gautam
  Cc: Andy Gross, Manu Gautam, linux-arm-msm, linux-soc, devicetree,
	linux-arm-kernel, open list
In-Reply-To: <CAFp+6iH5bS5rmqZ1oy09COb2Rzuz6zbN7pFwxz0WTJNOYTTbkg@mail.gmail.com>

On Fri 25 May 05:51 PDT 2018, Vivek Gautam wrote:

> Hi Bjorn,
> 
> On Fri, May 25, 2018 at 4:01 AM, Bjorn Andersson
> <bjorn.andersson@linaro.org> wrote:
> > The UFS host controller occationally (20%) fails to enable
> > gcc_ufs_axi_clk because the UFS GDSC is not enabled. In most cases it's
> > enabled through the UFS phy driver, but to make sure it's enabled let's
> > enable it directly from the UFS host controller directly as well.
> >
> > Signed-off-by: Bjorn Andersson <bjorn.andersson@linaro.org>
> > ---
> >  arch/arm64/boot/dts/qcom/msm8996.dtsi | 2 ++
> >  1 file changed, 2 insertions(+)
> >
> > diff --git a/arch/arm64/boot/dts/qcom/msm8996.dtsi b/arch/arm64/boot/dts/qcom/msm8996.dtsi
> > index 380e14591686..03c7904bda14 100644
> > --- a/arch/arm64/boot/dts/qcom/msm8996.dtsi
> > +++ b/arch/arm64/boot/dts/qcom/msm8996.dtsi
> > @@ -674,6 +674,8 @@
> >                         vccq-max-microamp = <450000>;
> >                         vccq2-max-microamp = <450000>;
> >
> > +                       power-domains = <&gcc UFS_GDSC>;
> > +
> 
> We shouldn't need power-domain with the phy. UFS_GDSC should
> be attached to the controller, as the phy is powered up only after
> the controller is power-up, and during collapse too, we turn off
> the phy first.

Afaict you're right, it should only be needed by the resources for the
HCD.

> Can you try testing keeping UFS_GDSC only with ufs controller and
> remove it from the ufs-phy node? We are doing same on the 4.14 release
> branch too for db820.

I test booted this 10 times, with 100% success :)

> I apologize to have missed this in your patch for ufs-related dt nodes.
> Can we please fix this now?

I'll send a v2, that moves the power-domain to the HCD, rather than just
adding it there too. Thanks for the quick review!

Regards,
Bjorn

^ permalink raw reply

* Re: [PATCH v11 00/27] ARM: davinci: convert to common clock framework​
From: David Lechner @ 2018-05-25 18:21 UTC (permalink / raw)
  To: Sekhar Nori, linux-clk, devicetree, linux-arm-kernel
  Cc: Michael Turquette, Stephen Boyd, Rob Herring, Mark Rutland,
	Kevin Hilman, Bartosz Golaszewski, Adam Ford, linux-kernel
In-Reply-To: <850a0ec9-53aa-02a5-ecbd-e068b13b2764@ti.com>

On 05/22/2018 04:38 AM, Sekhar Nori wrote:
> Hi David,
> 
> On Friday 18 May 2018 10:18 PM, David Lechner wrote:
>> This series converts mach-davinci to use the common clock framework.
>>
>> The series works like this, the first 3 patches fix some issues with the clock
>> drivers that have already been accepted into the mainline kernel.
>>
>> Then, starting with "ARM: davinci: pass clock as parameter to
>> davinci_timer_init()", we get the mach code ready for the switch by adding the
>> code needed for the new clock drivers and adding #ifndef CONFIG_COMMON_CLK
>> around the legacy clocks so that we can switch easily between the old and the
>> new.
>>
>> "ARM: davinci: switch to common clock framework" actually flips the switch
>> to start using the new clock drivers. Then the next 8 patches remove all
>> of the old clock code.
>>
>> The final four patches add device tree clock support to the one SoC that
>> supports it.
>>
>> This series has been tested on TI OMAP-L138 LCDK (both device tree and legacy
>> board file).
> 
> If you do end up sending a v12, you can leave out the mach-davinci
> portions unless there are any changes you need to make. I will pick them
> up from this series once the driver dependencies are merged.
> 
> I do hope the drivers/clk/* changes can be merged from v4.18.
> 

I have resent all of the clk patches (including all of the ones I listed as
dependencies in addition to the three remaining in this series) under the
cover "clk: davinci: outstanding fixes​".

I also found that we need to add power-domains properties to the PWM nodes
in "ARM: dts: da850: Add clocks". I probably should just take your advice
and just globally added them even if they are not documented for some types
ofnodes.

^ permalink raw reply

* [PATCH v2 2/2] clk: Add driver for MAX9485
From: Daniel Mack @ 2018-05-25 18:20 UTC (permalink / raw)
  To: mturquette, sboyd; +Cc: linux-clk, robh, devicetree, Daniel Mack, Daniel Mack
In-Reply-To: <20180525182058.25969-1-daniel@zonque.org>

From: Daniel Mack <zonque@gmail.com>

This patch adds a driver for MAX9485, a programmable audio clock generator.

The device requires a 27.000 MHz clock input. It can provide a gated
buffered output of its input clock and two gated outputs of a PLL that can
generate one out of 16 discrete frequencies. There is only one PLL however,
so the two gated outputs will always have the same frequency but they can
be switched individually.

The driver for this device exposes 4 clocks in total:

- MAX9485_MCLKOUT:      A gated, buffered output of the input clock
- MAX9485_CLKOUT:       A PLL that can be configured to 16 different
			discrete frequencies
- MAX9485_CLKOUT[1,2]:  Two gated outputs for MAX9485_CLKOUT

Some PLL output frequencies can be achieved with different register
settings. The driver will select the one with lowest jitter in such cases.

Signed-off-by: Daniel Mack <daniel@zonque.org>
---
 drivers/clk/Kconfig       |   8 +
 drivers/clk/Makefile      |   1 +
 drivers/clk/clk-max9485.c | 408 ++++++++++++++++++++++++++++++++++++++++++++++
 3 files changed, 417 insertions(+)
 create mode 100644 drivers/clk/clk-max9485.c

diff --git a/drivers/clk/Kconfig b/drivers/clk/Kconfig
index 34968a381d0f..f8ab54c41d16 100644
--- a/drivers/clk/Kconfig
+++ b/drivers/clk/Kconfig
@@ -45,6 +45,14 @@ config COMMON_CLK_MAX77686
 	  This driver supports Maxim 77620/77686/77802 crystal oscillator
 	  clock.
 
+config COMMON_CLK_MAX9485
+	tristate "Clock driver for Maxim 9485 Programmable Clock Generator"
+	depends on I2C
+	depends on OF
+	depends on GPIOLIB || COMPILE_TEST
+	---help---
+	  This driver supports Maxim 9485 Programmable Audio Clock Generator
+
 config COMMON_CLK_RK808
 	tristate "Clock driver for RK805/RK808/RK818"
 	depends on MFD_RK808
diff --git a/drivers/clk/Makefile b/drivers/clk/Makefile
index de6d06ac790b..27417ba3c1df 100644
--- a/drivers/clk/Makefile
+++ b/drivers/clk/Makefile
@@ -31,6 +31,7 @@ obj-$(CONFIG_COMMON_CLK_ASPEED)		+= clk-aspeed.o
 obj-$(CONFIG_ARCH_HIGHBANK)		+= clk-highbank.o
 obj-$(CONFIG_CLK_HSDK)			+= clk-hsdk-pll.o
 obj-$(CONFIG_COMMON_CLK_MAX77686)	+= clk-max77686.o
+obj-$(CONFIG_COMMON_CLK_MAX9485)	+= clk-max9485.o
 obj-$(CONFIG_ARCH_MOXART)		+= clk-moxart.o
 obj-$(CONFIG_ARCH_NOMADIK)		+= clk-nomadik.o
 obj-$(CONFIG_ARCH_NSPIRE)		+= clk-nspire.o
diff --git a/drivers/clk/clk-max9485.c b/drivers/clk/clk-max9485.c
new file mode 100644
index 000000000000..9bbf2fee49c5
--- /dev/null
+++ b/drivers/clk/clk-max9485.c
@@ -0,0 +1,408 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * clk-max9485.c: MAX9485 Programmable Audio Clock Generator
+ *
+ * (c) 2018 Daniel Mack <daniel@zonque.org>
+ *
+ * References:
+ *   MAX9485 Datasheet
+ *     http://www.maximintegrated.com/datasheet/index.mvp/id/4421
+ *
+ * This program is free software; you can redistribute  it and/or modify it
+ * under  the terms of  the GNU General  Public License as published by the
+ * Free Software Foundation;  either version 2 of the  License, or (at your
+ * option) any later version.
+ */
+
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/clkdev.h>
+#include <linux/clk.h>
+#include <linux/clk-provider.h>
+#include <linux/err.h>
+#include <linux/errno.h>
+#include <linux/gpio/consumer.h>
+#include <linux/i2c.h>
+#include <linux/regulator/consumer.h>
+
+#include <dt-bindings/clock/maxim,max9485.h>
+
+#define MAX9485_INPUT_FREQ 27000000UL
+#define MAX9485_NUM_CLKS 4
+
+/* This chip has only one register of 8 bit width. */
+
+enum {
+	MAX9485_FS_12KHZ	= 0 << 0,
+	MAX9485_FS_32KHZ	= 1 << 0,
+	MAX9485_FS_44_1KHZ	= 2 << 0,
+	MAX9485_FS_48KHZ	= 3 << 0,
+};
+
+enum {
+	MAX9485_SCALE_256	= 0 << 2,
+	MAX9485_SCALE_384	= 1 << 2,
+	MAX9485_SCALE_768	= 2 << 2,
+};
+
+#define MAX9485_DOUBLE		BIT(4)
+#define MAX9485_CLKOUT1_ENABLE	BIT(5)
+#define MAX9485_CLKOUT2_ENABLE	BIT(6)
+#define MAX9485_MCLK_ENABLE	BIT(7)
+#define MAX9485_FREQ_MASK	0x1f
+
+struct max9485_rate {
+	unsigned long out;
+	u8 reg_value;
+};
+
+/*
+ * Ordered by frequency. For frequency the hardware can generate with
+ * multiple settings, only the one with lowest jitter is listed.
+ */
+static const struct max9485_rate max9485_rates[] = {
+	{  3072000, MAX9485_FS_12KHZ   | MAX9485_SCALE_256 },
+	{  4608000, MAX9485_FS_12KHZ   | MAX9485_SCALE_384 },
+	{  8192000, MAX9485_FS_32KHZ   | MAX9485_SCALE_256 },
+	{  9126000, MAX9485_FS_12KHZ   | MAX9485_SCALE_768 },
+	{ 11289600, MAX9485_FS_44_1KHZ | MAX9485_SCALE_256 },
+	{ 12288000, MAX9485_FS_48KHZ   | MAX9485_SCALE_256 },
+	{ 16384000, MAX9485_FS_32KHZ   | MAX9485_SCALE_256 | MAX9485_DOUBLE },
+	{ 16934400, MAX9485_FS_44_1KHZ | MAX9485_SCALE_384 },
+	{ 18384000, MAX9485_FS_48KHZ   | MAX9485_SCALE_384 },
+	{ 22579200, MAX9485_FS_44_1KHZ | MAX9485_SCALE_256 | MAX9485_DOUBLE },
+	{ 24576000, MAX9485_FS_48KHZ   | MAX9485_SCALE_256 | MAX9485_DOUBLE },
+	{ 33868800, MAX9485_FS_44_1KHZ | MAX9485_SCALE_384 | MAX9485_DOUBLE },
+	{ 36864000, MAX9485_FS_48KHZ   | MAX9485_SCALE_384 | MAX9485_DOUBLE },
+	{ 49152000, MAX9485_FS_32KHZ   | MAX9485_SCALE_768 | MAX9485_DOUBLE },
+	{ 67737600, MAX9485_FS_44_1KHZ | MAX9485_SCALE_768 | MAX9485_DOUBLE },
+	{ 73728000, MAX9485_FS_48KHZ   | MAX9485_SCALE_768 | MAX9485_DOUBLE },
+	{ } /* sentinel */
+};
+
+struct max9485_driver_data;
+
+struct max9485_clk_hw {
+	struct clk_hw hw;
+	struct clk_init_data init;
+	u8 enable_bit;
+	struct max9485_driver_data *drvdata;
+};
+
+struct max9485_driver_data {
+	struct clk *xclk;
+	struct i2c_client *client;
+	u8 reg_value;
+	unsigned long clkout_rate;
+	struct regulator *supply;
+	struct gpio_desc *reset_gpio;
+	struct max9485_clk_hw hw[MAX9485_NUM_CLKS];
+
+	struct {
+		struct clk_hw_onecell_data data;
+		struct clk_hw *hw[MAX9485_NUM_CLKS];
+	} onecell;
+};
+
+static int max9485_update_bits(struct max9485_driver_data *drvdata,
+			       u8 mask, u8 value)
+{
+	int ret;
+
+	drvdata->reg_value &= ~mask;
+	drvdata->reg_value |= value;
+
+	dev_dbg(&drvdata->client->dev,
+		"updating mask %02x value %02x -> %02x\n",
+		mask, value, drvdata->reg_value);
+
+	ret = i2c_master_send(drvdata->client,
+			      &drvdata->reg_value,
+			      sizeof(drvdata->reg_value));
+
+	return (ret < 0) ? ret : 0;
+}
+
+static int max9485_clk_prepare(struct clk_hw *hw)
+{
+	struct max9485_clk_hw *clk_hw =
+		container_of(hw, struct max9485_clk_hw, hw);
+
+	return max9485_update_bits(clk_hw->drvdata,
+				   clk_hw->enable_bit,
+				   clk_hw->enable_bit);
+}
+
+static void max9485_clk_unprepare(struct clk_hw *hw)
+{
+	struct max9485_clk_hw *clk_hw =
+		container_of(hw, struct max9485_clk_hw, hw);
+
+	max9485_update_bits(clk_hw->drvdata, clk_hw->enable_bit, 0);
+}
+
+/*
+ * MCLK OUT
+ */
+
+/* The MCLK output can only provide the same rate as the input clock */
+static unsigned long max9485_mclkout_recalc_rate(struct clk_hw *hw,
+						 unsigned long parent_rate)
+{
+	return MAX9485_INPUT_FREQ;
+}
+
+/*
+ * CLKOUT - configurable clock output
+ */
+static int max9485_clkout_set_rate(struct clk_hw *hw, unsigned long rate,
+				   unsigned long parent_rate)
+{
+	const struct max9485_rate *entry;
+	struct max9485_clk_hw *clk_hw =
+		container_of(hw, struct max9485_clk_hw, hw);
+
+	for (entry = max9485_rates; entry->out != 0; entry++)
+		if (entry->out == rate)
+			break;
+
+	if (entry->out == 0)
+		return -EINVAL;
+
+	clk_hw->drvdata->clkout_rate = rate;
+
+	return max9485_update_bits(clk_hw->drvdata,
+				   MAX9485_FREQ_MASK,
+				   entry->reg_value);
+}
+
+static long max9485_clkout_round_rate(struct clk_hw *hw, unsigned long rate,
+				      unsigned long *parent_rate)
+{
+	const struct max9485_rate *curr, *prev = NULL;
+
+	for (curr = max9485_rates; curr->out != 0; curr++) {
+		/* Exact matches */
+		if (curr->out == rate)
+			return rate;
+
+		/*
+		 * Find the first entry that has a frequency higher than the
+		 * requested one.
+		 */
+		if (curr->out > rate) {
+			unsigned int mid;
+
+			/*
+			 * If this is the first entry, clamp the value to the
+			 * lowest possible frequency.
+			 */
+			if (!prev)
+				return curr->out;
+
+			/*
+			 * Otherwise, determine whether the previous entry or
+			 * current one is closer.
+			 */
+			mid = prev->out + ((curr->out - prev->out) / 2);
+
+			return (mid > rate) ? prev->out : curr->out;
+		}
+
+		prev = curr;
+	}
+
+	/* If the last entry was still too high, clamp the value */
+	return prev->out;
+}
+
+static unsigned long max9485_clkout_recalc_rate(struct clk_hw *hw,
+						unsigned long parent_rate)
+{
+	struct max9485_clk_hw *clk_hw =
+		container_of(hw, struct max9485_clk_hw, hw);
+
+	return clk_hw->drvdata->clkout_rate;
+}
+
+struct max9485_clk {
+	const char *name;
+	int parent_index;
+	const struct clk_ops ops;
+	u8 enable_bit;
+};
+
+static const struct max9485_clk max9485_clks[MAX9485_NUM_CLKS] = {
+	[MAX9485_MCLKOUT] = {
+		.name = "mclkout",
+		.parent_index = -1,
+		.enable_bit = MAX9485_MCLK_ENABLE,
+		.ops = {
+			.prepare	= max9485_clk_prepare,
+			.unprepare	= max9485_clk_unprepare,
+			.recalc_rate	= max9485_mclkout_recalc_rate,
+		},
+	},
+	[MAX9485_CLKOUT] = {
+		.name = "clkout",
+		.parent_index = -1,
+		.ops = {
+			.set_rate	= max9485_clkout_set_rate,
+			.round_rate	= max9485_clkout_round_rate,
+			.recalc_rate	= max9485_clkout_recalc_rate,
+		},
+	},
+	[MAX9485_CLKOUT1] = {
+		.name = "clkout1",
+		.parent_index = MAX9485_CLKOUT,
+		.enable_bit = MAX9485_CLKOUT1_ENABLE,
+		.ops = {
+			.prepare	= max9485_clk_prepare,
+			.unprepare	= max9485_clk_unprepare,
+			.recalc_rate	= max9485_clkout_recalc_rate,
+		},
+	},
+	[MAX9485_CLKOUT2] = {
+		.name = "clkout2",
+		.parent_index = MAX9485_CLKOUT,
+		.enable_bit = MAX9485_CLKOUT2_ENABLE,
+		.ops = {
+			.prepare	= max9485_clk_prepare,
+			.unprepare	= max9485_clk_unprepare,
+			.recalc_rate	= max9485_clkout_recalc_rate,
+		},
+	},
+};
+
+static int max9485_i2c_probe(struct i2c_client *client,
+			     const struct i2c_device_id *id)
+{
+	struct max9485_driver_data *drvdata;
+	struct device *dev = &client->dev;
+	unsigned long freq;
+	int i, ret;
+
+	drvdata = devm_kzalloc(dev, sizeof(*drvdata), GFP_KERNEL);
+	if (drvdata == NULL)
+		return -ENOMEM;
+
+	drvdata->xclk = devm_clk_get(dev, "xclk");
+	if (IS_ERR(drvdata->xclk))
+		return PTR_ERR(drvdata->xclk);
+
+	freq = clk_get_rate(drvdata->xclk);
+	if (freq != MAX9485_INPUT_FREQ) {
+		dev_err(dev, "Illegal xclk frequency of %ld\n", freq);
+		return -EINVAL;
+	}
+
+	drvdata->supply = devm_regulator_get(dev, "vdd");
+	if (IS_ERR(drvdata->supply))
+		return PTR_ERR(drvdata->supply);
+
+	ret = regulator_enable(drvdata->supply);
+	if (ret < 0)
+		return ret;
+
+	drvdata->reset_gpio =
+		devm_gpiod_get_optional(dev, "reset", GPIOD_OUT_HIGH);
+	if (IS_ERR(drvdata->reset_gpio))
+		return PTR_ERR(drvdata->reset_gpio);
+
+	i2c_set_clientdata(client, drvdata);
+	drvdata->client = client;
+
+	for (i = 0; i < MAX9485_NUM_CLKS; i++) {
+		int parent_index = max9485_clks[i].parent_index;
+		const char *name;
+
+		if (of_property_read_string_index(dev->of_node,
+						  "clock-output-names",
+						  i, &name) == 0)
+			drvdata->hw[i].init.name = name;
+		else
+			drvdata->hw[i].init.name = max9485_clks[i].name;
+
+		drvdata->hw[i].init.ops = &max9485_clks[i].ops;
+		drvdata->hw[i].init.flags = CLK_IS_BASIC;
+
+		if (parent_index > 0) {
+			drvdata->hw[i].init.parent_names =
+				&drvdata->hw[parent_index].init.name;
+			drvdata->hw[i].init.num_parents = 1;
+			drvdata->hw[i].init.flags |= CLK_SET_RATE_PARENT;
+		}
+
+		drvdata->hw[i].enable_bit = max9485_clks[i].enable_bit;
+		drvdata->hw[i].hw.init = &drvdata->hw[i].init;
+		drvdata->hw[i].drvdata = drvdata;
+
+		ret = devm_clk_hw_register(dev, &drvdata->hw[i].hw);
+		if (ret < 0)
+			return ret;
+
+		drvdata->onecell.hw[i] = &drvdata->hw[i].hw;
+	}
+
+	drvdata->onecell.data.num = MAX9485_NUM_CLKS;
+
+	return devm_of_clk_add_hw_provider(dev, of_clk_hw_onecell_get,
+					   &drvdata->onecell.data);
+}
+
+static int __maybe_unused max9485_suspend(struct device *dev)
+{
+	struct i2c_client *client = to_i2c_client(dev);
+	struct max9485_driver_data *drvdata = i2c_get_clientdata(client);
+
+	if (drvdata->reset_gpio)
+		gpiod_set_value_cansleep(drvdata->reset_gpio, 0);
+
+	return 0;
+}
+
+static int __maybe_unused max9485_resume(struct device *dev)
+{
+	struct i2c_client *client = to_i2c_client(dev);
+	struct max9485_driver_data *drvdata = i2c_get_clientdata(client);
+	int ret;
+
+	if (drvdata->reset_gpio)
+		gpiod_set_value_cansleep(drvdata->reset_gpio, 0);
+
+	ret = i2c_master_send(client, &drvdata->reg_value,
+			      sizeof(drvdata->reg_value));
+
+	return (ret < 0) ? ret : 0;
+}
+
+static const struct dev_pm_ops max9485_pm_ops = {
+	SET_SYSTEM_SLEEP_PM_OPS(max9485_suspend, max9485_resume)
+};
+
+static const struct of_device_id max9485_dt_ids[] = {
+	{ .compatible = "maxim,max9485", },
+	{ }
+};
+MODULE_DEVICE_TABLE(of, max9485_dt_ids);
+
+static const struct i2c_device_id max9485_i2c_ids[] = {
+	{ .name = "max9485", },
+	{ }
+};
+MODULE_DEVICE_TABLE(i2c, max9485_i2c_ids);
+
+static struct i2c_driver max9485_driver = {
+	.driver = {
+		.name		= "max9485",
+		.pm		= &max9485_pm_ops,
+		.of_match_table	= max9485_dt_ids,
+	},
+	.probe = max9485_i2c_probe,
+	.id_table = max9485_i2c_ids,
+};
+module_i2c_driver(max9485_driver);
+
+MODULE_AUTHOR("Daniel Mack <daniel@zonque.org>");
+MODULE_DESCRIPTION("MAX9485 Programmable Audio Clock Generator");
+MODULE_LICENSE("GPL v2");
-- 
2.14.3

^ permalink raw reply related

* [PATCH v2 1/2] dts: clk: add devicetree bindings for MAX9485
From: Daniel Mack @ 2018-05-25 18:20 UTC (permalink / raw)
  To: mturquette, sboyd; +Cc: linux-clk, robh, devicetree, Daniel Mack
In-Reply-To: <20180525182058.25969-1-daniel@zonque.org>

This patch adds the devicetree bindings for MAX9485, a programmable audio
clock generator.

Signed-off-by: Daniel Mack <daniel@zonque.org>
---
 .../devicetree/bindings/clock/maxim,max9485.txt    | 59 ++++++++++++++++++++++
 include/dt-bindings/clock/maxim,max9485.h          | 18 +++++++
 2 files changed, 77 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/clock/maxim,max9485.txt
 create mode 100644 include/dt-bindings/clock/maxim,max9485.h

diff --git a/Documentation/devicetree/bindings/clock/maxim,max9485.txt b/Documentation/devicetree/bindings/clock/maxim,max9485.txt
new file mode 100644
index 000000000000..61bec1100a94
--- /dev/null
+++ b/Documentation/devicetree/bindings/clock/maxim,max9485.txt
@@ -0,0 +1,59 @@
+Devicetree bindings for Maxim MAX9485 Programmable Audio Clock Generator
+
+This device exposes 4 clocks in total:
+
+- MAX9485_MCLKOUT: 	A gated, buffered output of the input clock of 27 MHz
+- MAX9485_CLKOUT:	A PLL that can be configured to 16 different discrete
+			frequencies
+- MAX9485_CLKOUT[1,2]:	Two gated outputs for MAX9485_CLKOUT
+
+MAX9485_CLKOUT[1,2] are children of MAX9485_CLKOUT which upchain all rate set
+requests.
+
+Required properties:
+- compatible:	"maxim,max9485"
+- clocks:	Input clock, must provice 27.000 MHz
+- clock-names:	Must be set to "xclk"
+- #clock-cells: From common clock binding; shall be set to 1
+
+Optional properties:
+- reset-gpios:		GPIO descriptor connected to the #RESET input pin
+- vdd-supply:		A regulator node for Vdd
+- clock-output-names:	Name of output clocks, as defined in common clock
+			bindings
+
+If not explicitly set, the output names are "mclkout", "clkout", "clkout1"
+and "clkout2".
+
+Clocks are defined as preprocessor macros in the dt-binding header.
+
+Example:
+
+	#include <dt-bindings/clock/maxim,max9485.h>
+
+	xo-27mhz: xo-27mhz {
+		compatible = "fixed-clock";
+		#clock-cells = <0>;
+		clock-frequency = <27000000>;
+	};
+
+	&i2c0 {
+		max9485: audio-clock@63 {
+			reg = <0x63>;
+			compatible = "maxim,max9485";
+			clock-names = "xclk";
+			clocks = <&xo-27mhz>;
+			reset-gpios = <&gpio 1 GPIO_ACTIVE_HIGH>;
+			vdd-supply = <&3v3-reg>;
+			#clock-cells = <1>;
+		};
+	};
+
+	// Clock consumer node
+
+	foo@0 {
+		compatible = "bar,foo";
+		/* ... */
+		clock-names = "foo-input-clk";
+		clocks = <&max9485 MAX9485_CLKOUT1>;
+	};
diff --git a/include/dt-bindings/clock/maxim,max9485.h b/include/dt-bindings/clock/maxim,max9485.h
new file mode 100644
index 000000000000..185b09ce1869
--- /dev/null
+++ b/include/dt-bindings/clock/maxim,max9485.h
@@ -0,0 +1,18 @@
+/*
+ * Copyright (C) 2018 Daniel Mack
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ */
+
+#ifndef __DT_BINDINGS_MAX9485_CLK_H
+#define __DT_BINDINGS_MAX9485_CLK_H
+
+#define MAX9485_MCLKOUT	0
+#define MAX9485_CLKOUT	1
+#define MAX9485_CLKOUT1	2
+#define MAX9485_CLKOUT2	3
+
+#endif /* __DT_BINDINGS_MAX9485_CLK_H */
-- 
2.14.3

^ permalink raw reply related

* [PATCH v2 0/2] clk: Add driver for MAX9485
From: Daniel Mack @ 2018-05-25 18:20 UTC (permalink / raw)
  To: mturquette, sboyd; +Cc: linux-clk, robh, devicetree, Daniel Mack

This is v2 of the driver for Maxim's MAX9485 programmable audio clock
generator.

v1 → v2:

* Now served as two patches, one for the DT bits, and one for the actual
  implementation. The DT bits are put in the 1st patch because the
  implementation depends on the shared header file.

* Added support for suspend/resume


Daniel Mack (2):
  dts: clk: add devicetree bindings for MAX9485
  clk: Add driver for MAX9485

 .../devicetree/bindings/clock/maxim,max9485.txt    |  59 +++
 drivers/clk/Kconfig                                |   8 +
 drivers/clk/Makefile                               |   1 +
 drivers/clk/clk-max9485.c                          | 408 +++++++++++++++++++++
 include/dt-bindings/clock/maxim,max9485.h          |  18 +
 5 files changed, 494 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/clock/maxim,max9485.txt
 create mode 100644 drivers/clk/clk-max9485.c
 create mode 100644 include/dt-bindings/clock/maxim,max9485.h

-- 
2.14.3

^ permalink raw reply

* Re: [PATCH 1/2] dt-bindings: iio: adc: Add DT binding document for PMIC5 ADC
From: Siddartha Mohanadoss @ 2018-05-25 18:18 UTC (permalink / raw)
  To: Rob Herring
  Cc: Jonathan Cameron, linux-iio, devicetree, Hartmut Knaack,
	Lars-Peter Clausen, Peter Meerwald-Stadler, cdevired, rphani,
	sivaa
In-Reply-To: <20180522205413.GA28348@rob-hp-laptop>

Hi Rob,

Thanks for the comments.


On 05/22/2018 01:54 PM, Rob Herring wrote:
> On Tue, May 15, 2018 at 04:57:03PM -0700, Siddartha Mohanadoss wrote:
>> Hi Jonathan,
>>
>> Thanks for the comments.
>>
>>
>> On 05/12/2018 03:15 AM, Jonathan Cameron wrote:
>>> On Tue,  8 May 2018 14:38:21 -0700
>>> Siddartha Mohanadoss <smohanad@codeaurora.org> wrote:
>>>
>>>> PMIC5 ADC has support for clients to measure voltage and current
>>>> on inputs connected to the PMIC. Clients include reading voltage
>>>> phone power and on board system thermistors for thermal management.
>>>> ADC5 on certain PMIC has support to read battery current.
>>>>
>>>> This change adds documentation.
>>>>
>>>> Signed-off-by: Siddartha Mohanadoss <smohanad@codeaurora.org>
>>> Hi Siddartha,
>>>
>>> Some complexity in here!  Anyhow, a few comments inline and we will definitely
>>> be wanting guidance from the devicetree people for this one.
>>>
>>> Jonathan
>>>
>>>> ---
>>>>    .../devicetree/bindings/iio/adc/qcom,spmi-adc5.txt | 137 +++++++++++++++++++++
>>>>    1 file changed, 137 insertions(+)
>>>>    create mode 100644 Documentation/devicetree/bindings/iio/adc/qcom,spmi-adc5.txt
>>>>
>>>> diff --git a/Documentation/devicetree/bindings/iio/adc/qcom,spmi-adc5.txt b/Documentation/devicetree/bindings/iio/adc/qcom,spmi-adc5.txt
>>>> new file mode 100644
>>>> index 0000000..c9268ba
>>>> --- /dev/null
>>>> +++ b/Documentation/devicetree/bindings/iio/adc/qcom,spmi-adc5.txt
>>>> @@ -0,0 +1,137 @@
>>>> +Qualcomm Technologies Inc. SPMI PMIC5 voltage and current ADC
>>>> +
>>>> +SPMI PMIC5 voltage ADC (ADC) provides interface to clients to read
>>>> +voltage. The VADC is a 16-bit sigma-delta ADC.
>>>> +
>>>> +ADC node:
>>>> +
>>>> +- compatible:
>>>> +    Usage: required
>>>> +    Value type: <string>
>>>> +    Definition: Should contain "qcom,spmi-adc5" for PMIC5 ADC driver.
>>>> +		Should contain "qcom,spmi-adc-rev2" for PMIC refresh ADC driver.
> Chip specific compatible strings please unless you convince me there are
> a large number of chips per above compatible.

The above compatible property supports at least 5 different PMIC's each 
so far,
hence split it as a separate property to address the differences.

>
> Bindings are for hardware, not drivers.
>
>>>> +
>>>> +- reg:
>>>> +    Usage: required
>>>> +    Value type: <prop-encoded-array>
>>>> +    Definition: VADC base address and length in the SPMI PMIC register map.
>>>> +
>>>> +- #address-cells:
>>>> +    Usage: required
>>>> +    Value type: <u32>
>>>> +    Definition: Must be one. Child node 'reg' property should define ADC
>>>> +            channel number.
>>>> +
>>>> +- #size-cells:
>>>> +    Usage: required
>>>> +    Value type: <u32>
>>>> +    Definition: Must be zero.
>>>> +
>>>> +- #io-channel-cells:
>>>> +    Usage: required
>>>> +    Value type: <u32>
>>>> +    Definition: Must be one. For details about IIO bindings see:
>>>> +            Documentation/devicetree/bindings/iio/iio-bindings.txt
>>>> +
>>>> +- interrupts:
>>>> +    Usage: optional
>>>> +    Value type: <prop-encoded-array>
>>>> +    Definition: End of conversion interrupt.
>>>> +
>>>> +Channel node properties:
>>>> +
>>>> +- reg:
>>>> +    Usage: required
>>>> +    Value type: <u32>
>>>> +    Definition: ADC channel number.
>>>> +            See include/dt-bindings/iio/qcom,spmi-vadc.h
>>>> +
>>>> +- label:
>>>> +    Usage: required
>>>> +    Value type: <empty>
>>>> +    Definition: ADC datasheet channel name.
>>>> +            For thermistor inputs connected to generic AMUX or GPIO inputs
>>>> +            these can vary across platform for the same pins. Hence select
>>>> +            the datasheet name for this channel.
> Why do you need this? If the name comes from a datasheet list, then
> perhaps you should list the exact string here. Otherwise, there's a lot
> left to the user in terms of capitalization, etc.

I will fix the comment. The label property name used is from the 
schematics for the
respective platform and not the data sheet. Some of the channel names on 
the PMIC
datasheet are generic such as ADC_AMUX_THM1 and ADC_GPIO1. Depending on the
platform these pins can be connected to measure different thermistors or 
inputs
across the platforms.

>
>>>> +
>>>> +- qcom,pre-scaling:
>>>> +    Usage: required
>>>> +    Value type: <u32 array>
>>>> +    Definition: Used for scaling the channel input signal before the signal is
>>>> +            fed to VADC. The configuration for this node is to know the
>>>> +            pre-determined ratio and use it for post scaling. Select one from
>>>> +            the following options.
>>>> +            <1 1>, <1 3>, <1 4>, <1 6>, <1 20>, <1 8>, <10 81>, <1 10>
>>>> +            If property is not found default value depending on chip will be used.
>>>> +
>>>> +- qcom,decimation:
>>>> +    Usage: optional
>>>> +    Value type: <u32>
>>>> +    Definition: This parameter is used to decrease ADC sampling rate.
>>>> +            Quicker measurements can be made by reducing decimation ratio.
>>>> +            For PMIC5 ADC, combined two step decimation values are 250, 420 and 840.
>>>> +            If property is not found, default value of 840 will be used.
>>> The odd indenting here needs sorting.  Mixture of spaces and tabs at the moment.
>> Ok, will take a look.
>>> Hmm. In someways this is a policy decision so should be pushed up to userspace,
>>> but given the 'right' value will be somewhat dependent on what you are doing
>>> with the channel and what is wired to it, it could arguably have a 'right' value
>>> for a given circuit.  This is really just the sampling frequency wrapped
>>> up in decimation of something, I'm guessing some input clock?
>> Yes. It's number of samples collected over a 4.8MHz clock.
>> The only reason to update this value would be if client wants to get
>> the conversion results back sooner. Hence left this as an optional property.
>>> Let's see what the Device-tree people think on this one!  Personally I have
>>> never really minded devicetree providing sensible defaults.  We can put
>>> control on these things later, if there is a usecase for changing them.
> I don't have a problem with this in DT, though my first thought was it
> should be common. Then after reading some on decimation, I'm not sure it
> would always just be a single 32-bit value?

For this PMIC family, the decimation and fast averaging are common 
settings used
across all the channels. In this case the decimation ratio values 
specified are
programmed as an index to select the above decimation value. Not sure if 
i answered
the question. Please let me know if this needs further clarification.

>
>>>> +	    For PMIC refresh ADC, supported decimation values are 256, 512, 1024.
>>>> +	    If property is not found, default value of 1024 will be used.
>>>> +
>>>> +- qcom,ratiometric:
>>>> +    Usage: optional
>>>> +    Value type: <empty>
>>>> +    Definition: Channel calibration type. If this property is specified
>>>> +            VADC will use the VDD reference (1.875V) and GND for channel
>>>> +            calibration. If property is not found, channel will be
>>>> +            calibrated with 0V and 1.25V reference channels, also
>>>> +            known as absolute calibration.
>>>> +
>>>> +- qcom,hw-settle-time:
>>>> +    Usage: optional
>>>> +    Value type: <u32>
>>>> +    Definition: Time between AMUX getting configured and the ADC starting
>>>> +            conversion.
>>>> +	    For PMIC5, delay = 15us for value 0,
>>>> +			100us * (value) for values 0 < value < 11, and
>>>> +            		2ms * (value - 10) otherwise.
>>>> +            Valid values are: 15, 100, 200, 300, 400, 500, 600, 700, 800,
>>> This description is very confusing given the different uses of 'value'
>>> None of the values you have allowed is less than 11 so the first condition
>>> doesn't apply.
>> The 'value' is an index programmed in the hardware to achieve the
>> hardware settling delay specified under valid values. I will update the
>> documentation here.
>>>> +            900 us and 1, 2, 4, 6, 8, 10 ms
>>>> +            If property is not found, channel will use 15us.
>>>> +	    For PMIC rev2, delay = 100us * (value) for values 0 < value < 11, and
>>>> +			2ms * (value - 10) otherwise.
>>>> +            Valid values are: 0, 100, 200, 300, 400, 500, 600, 700, 800,
>>>> +            900 us and 1, 2, 4, 6, 8, 10 ms
>>>> +            If property is not found, channel will use 0 us.
>>>> +
>>>> +- qcom,avg-samples:
>>>> +    Usage: optional
>>>> +    Value type: <u32>
>>>> +    Definition: Number of samples to be used for measurement.
>>>> +            Averaging provides the option to obtain a single measurement
>>>> +            from the ADC that is an average of multiple samples. The value
>>>> +            selected is 2^(value).
>>>> +            Valid values are: 1, 2, 4, 8, 16
>>>> +            If property is not found, 1 sample will be used.
>>> As with decimation, this is arguably not a feature of the hardware, but
>>> a software decision...
> We already have a common property for touchscreens and vendor properties
> for a few ADCs, so we should define a common one.
>
> Now, sadly, I've just found that all these properties are already
> defined in bindings/iio/adc/qcom,spmi-vadc.txt. Why didn't you add these
> compatibles to the existing binding. Then we're not reviewing the same
> thing again...

I figured it would be easier for the client to follow and cleaner to 
separate it
out for a per family otherwise it needs a separate definition for each 
of the
property based on the PMIC type.

The earlier PMIC ADC family has capability to specify the decimation
and fast averaging for each channel. On PMIC5 ADC these two
properties are common across all channels and are required to be
programmed only once. The hardware settling delays have
differences within the family. I do not have a preference either way, i can
try and merge these with the existing bindings for the next patch revision
and based on the comments i can either revert or use the existing one.

>
> Rob
> --
> To unsubscribe from this list: send the line "unsubscribe linux-iio" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html

^ permalink raw reply

* Re: [PATCH v2 1/8] driver core: make deferring probe after init optional
From: Rob Herring @ 2018-05-25 17:35 UTC (permalink / raw)
  To: Robin Murphy
  Cc: Greg Kroah-Hartman, Linus Walleij, Alexander Graf,
	Bjorn Andersson, Rafael J. Wysocki, Kevin Hilman, Ulf Hansson,
	Joerg Roedel, Mark Brown, Frank Rowand,
	linux-kernel@vger.kernel.org, devicetree,
	Architecture Mailman List,
	moderated list:ARM/FREESCALE IMX / MXC ARM ARCHITECTURE
In-Reply-To: <92e3be10-e65a-99e9-6ef7-f11ded6a35f9@arm.com>

On Fri, May 25, 2018 at 7:20 AM, Robin Murphy <robin.murphy@arm.com> wrote:
> On 24/05/18 21:57, Rob Herring wrote:
>>
>> On Thu, May 24, 2018 at 2:00 PM, Greg Kroah-Hartman
>> <gregkh@linuxfoundation.org> wrote:
>>>
>>> On Thu, May 24, 2018 at 12:50:17PM -0500, Rob Herring wrote:
>>>>
>>>> Deferred probe will currently wait forever on dependent devices to
>>>> probe,
>>>> but sometimes a driver will never exist. It's also not always critical
>>>> for
>>>> a driver to exist. Platforms can rely on default configuration from the
>>>> bootloader or reset defaults for things such as pinctrl and power
>>>> domains.
>>>> This is often the case with initial platform support until various
>>>> drivers
>>>> get enabled. There's at least 2 scenarios where deferred probe can
>>>> render
>>>> a platform broken. Both involve using a DT which has more devices and
>>>> dependencies than the kernel supports. The 1st case is a driver may be
>>>> disabled in the kernel config. The 2nd case is the kernel version may
>>>> simply not have the dependent driver. This can happen if using a newer
>>>> DT
>>>> (provided by firmware perhaps) with a stable kernel version.
>>>>
>>>> Subsystems or drivers may opt-in to this behavior by calling
>>>> driver_deferred_probe_check_init_done() instead of just returning
>>>> -EPROBE_DEFER. They may use additional information from DT or kernel's
>>>> config to decide whether to continue to defer probe or not.
>>>>
>>>> Cc: Alexander Graf <agraf@suse.de>
>>>> Signed-off-by: Rob Herring <robh@kernel.org>
>>>> ---
>>>>   drivers/base/dd.c      | 17 +++++++++++++++++
>>>>   include/linux/device.h |  2 ++
>>>>   2 files changed, 19 insertions(+)
>>>>
>>>> diff --git a/drivers/base/dd.c b/drivers/base/dd.c
>>>> index c9f54089429b..d6034718da6f 100644
>>>> --- a/drivers/base/dd.c
>>>> +++ b/drivers/base/dd.c
>>>> @@ -226,6 +226,16 @@ void device_unblock_probing(void)
>>>>        driver_deferred_probe_trigger();
>>>>   }
>>>>
>>>> +int driver_deferred_probe_check_init_done(struct device *dev, bool
>>>> optional)
>>>> +{
>>>> +     if (optional && initcalls_done) {
>>>
>>>
>>> Wait, what's the "optional" mess here?
>>
>>
>> My intent was that subsystems just always call this function and never
>> return EPROBE_DEFER themselves. Then the driver core can make
>> decisions as to what to do (such as the timeout added in the next
>> patch). Or it can print common error/debug messages. So optional is a
>> hint to allow subsystems per device control.
>
>
> Maybe just driver_defer_probe() might be a more descriptive name? To me,
> calling "foo_check_x()" with a parameter that says "I don't actually care
> about x" is the really unintuitive bit.

All the other (though static or internal to driver core) functions are
prefixed driver_deferred_probe_* so I was trying to remain consistent
there. You're right though, with the timeout it's not just whether
initcalls are done. It's really "get the return value depending on the
core's deferred probe state". So perhaps one of these:

driver_deferred_probe_get_return_val()
driver_deferred_probe_handle_return()

The other option would be a more straight-forward functions that just
returns a bool on whether to continue deferring and leave the return
code handling to the caller:

if (driver_deferred_probe_enabled_for_builtin(dev))
  return -EPROBE_DEFER;
else
  return -ENODEV;

The pinctrl case would look like this:

builtin_only = of_property_read_bool(np_pctldev, "pinctrl-use-default");
if (builtin_only && driver_deferred_probe_enabled_for_builtin(dev))
  return -EPROBE_DEFER;
else if (!builtin_only && driver_deferred_probe_enabled(dev))
  return -EPROBE_DEFER;
else
  return -ENODEV;

I still prefer the former, picking the bike shed color is easier with
the latter.

>>>
>>> The caller knows this value, so why do you need to even pass it in here?
>>
>>
>> Because regardless of the value, we always stop deferring when/if we
>> hit the timeout and the caller doesn't know about the timeout. If we
>> get rid of it, we'd need functions for both init done and for deferred
>> timeout.
>>
>>> And bool values that are not obvious are horrid.  I had to go look this
>>> up when reading the later patches that just passed "true" in this
>>> variable as I had no idea what that meant.
>>
>>
>> Perhaps inverting it and calling it "keep_deferring" would be better.
>> However, the flag is ignored if we have timed out.
>
>
> Perhaps an enum (or bitmask of named flags) then? That would allow the most
> readability at callsites, plus it seems quite likely that we may want
> intermediate degrees of "deferral strictness" eventually.

A bitmask is just 32 booleans stuffed into one parameter which I can
guess Greg's opinion on.

I can't really think of other flags we might need here. If we added
some userspace trigger saying module loading is done, I don't think
we'd need that to be per caller.

Rob

^ permalink raw reply

* Re: [PATCH] ASoC: ssm2602: Fix ADC powerup sequencing
From: Mark Brown @ 2018-05-25 17:24 UTC (permalink / raw)
  To: Philipp Zabel
  Cc: Mark Rutland, Rob Herring, Linux-ALSA, Lars-Peter Clausen,
	devicetree, Sascha Hauer, Marco Felsch, Liam Girdwood, kernel
In-Reply-To: <1527261489.4938.9.camel@pengutronix.de>


[-- Attachment #1.1: Type: text/plain, Size: 1621 bytes --]

On Fri, May 25, 2018 at 05:18:09PM +0200, Philipp Zabel wrote:
> On Fri, 2018-05-25 at 15:52 +0100, Mark Brown wrote:
> > On Fri, May 25, 2018 at 01:42:53PM +0200, Marco Felsch wrote:

> > > Also the formula for the delay time (t = C × 25,000/3.5) depends only on
> > > the capacity size.

> > Why not just have the user specify the capacitance of the capacitor on
> > the rail which they can directly read from the schematic rather than
> > forcing them to do the calcualtion?  That seems a bit clearer and more
> > user friendly (plus if someone decides the spec was wrong it's easier to
> > roll out fixes).

> The exact capacitance may not be known or vary above the nominal value
> because of cheap components, and the formula from the datasheet is just
> a guideline.

That variability is going to apply just as much to the charge time
calculations/measurements as it is to the initial capacitance value -
the results are going to be very much garbage in, garbage out.

> I'd expect the usual method to set this delay to be semi-empirical:
> "start from the value calculated from datasheet and schematics and then
> increase until no more audio artifacts on a representative sample of
> boards".
> I think it is be better to specify a delay that works than a bogus
> capacitance value that happens to correspond to a delay that works.

If this is varying so drastically per board/system that it's relevant
then we're already into problematic territory.  For most devices we just
have a number for the part, not something that varies so wildly that
each system needs to configure it.

[-- Attachment #1.2: signature.asc --]
[-- Type: application/pgp-signature, Size: 488 bytes --]

[-- Attachment #2: Type: text/plain, Size: 0 bytes --]



^ permalink raw reply

* [PATCH v4 6/6] tty/serial: atmel: changed the driver to work under at91-usart mfd
From: Radu Pirea @ 2018-05-25 17:19 UTC (permalink / raw)
  To: broonie, nicolas.ferre, alexandre.belloni, lee.jones,
	richard.genoud, robh+dt, mark.rutland, gregkh
  Cc: linux-spi, linux-arm-kernel, linux-kernel, devicetree,
	linux-serial, Radu Pirea
In-Reply-To: <20180525171941.26766-1-radu.pirea@microchip.com>

This patch modifies the place where resources and device tree properties
are searched.

Signed-off-by: Radu Pirea <radu.pirea@microchip.com>
---
 drivers/tty/serial/Kconfig        |  1 +
 drivers/tty/serial/atmel_serial.c | 40 +++++++++++++++++--------------
 2 files changed, 23 insertions(+), 18 deletions(-)

diff --git a/drivers/tty/serial/Kconfig b/drivers/tty/serial/Kconfig
index 3682fd3e960c..25e55332f8b1 100644
--- a/drivers/tty/serial/Kconfig
+++ b/drivers/tty/serial/Kconfig
@@ -119,6 +119,7 @@ config SERIAL_ATMEL
 	depends on ARCH_AT91 || COMPILE_TEST
 	select SERIAL_CORE
 	select SERIAL_MCTRL_GPIO if GPIOLIB
+	select MFD_AT91_USART
 	help
 	  This enables the driver for the on-chip UARTs of the Atmel
 	  AT91 processors.
diff --git a/drivers/tty/serial/atmel_serial.c b/drivers/tty/serial/atmel_serial.c
index df46a9e88c34..740c7d7f4a0c 100644
--- a/drivers/tty/serial/atmel_serial.c
+++ b/drivers/tty/serial/atmel_serial.c
@@ -193,8 +193,8 @@ static struct console atmel_console;
 
 #if defined(CONFIG_OF)
 static const struct of_device_id atmel_serial_dt_ids[] = {
-	{ .compatible = "atmel,at91rm9200-usart" },
-	{ .compatible = "atmel,at91sam9260-usart" },
+	{ .compatible = "atmel,at91rm9200-usart-serial" },
+	{ .compatible = "atmel,at91sam9260-usart-serial" },
 	{ /* sentinel */ }
 };
 #endif
@@ -915,6 +915,7 @@ static void atmel_tx_dma(struct uart_port *port)
 static int atmel_prepare_tx_dma(struct uart_port *port)
 {
 	struct atmel_uart_port *atmel_port = to_atmel_uart_port(port);
+	struct device *mfd_dev = port->dev->parent;
 	dma_cap_mask_t		mask;
 	struct dma_slave_config config;
 	int ret, nent;
@@ -922,7 +923,7 @@ static int atmel_prepare_tx_dma(struct uart_port *port)
 	dma_cap_zero(mask);
 	dma_cap_set(DMA_SLAVE, mask);
 
-	atmel_port->chan_tx = dma_request_slave_channel(port->dev, "tx");
+	atmel_port->chan_tx = dma_request_slave_channel(mfd_dev, "tx");
 	if (atmel_port->chan_tx == NULL)
 		goto chan_err;
 	dev_info(port->dev, "using %s for tx DMA transfers\n",
@@ -1093,6 +1094,7 @@ static void atmel_rx_from_dma(struct uart_port *port)
 static int atmel_prepare_rx_dma(struct uart_port *port)
 {
 	struct atmel_uart_port *atmel_port = to_atmel_uart_port(port);
+	struct device *mfd_dev = port->dev->parent;
 	struct dma_async_tx_descriptor *desc;
 	dma_cap_mask_t		mask;
 	struct dma_slave_config config;
@@ -1104,7 +1106,7 @@ static int atmel_prepare_rx_dma(struct uart_port *port)
 	dma_cap_zero(mask);
 	dma_cap_set(DMA_CYCLIC, mask);
 
-	atmel_port->chan_rx = dma_request_slave_channel(port->dev, "rx");
+	atmel_port->chan_rx = dma_request_slave_channel(mfd_dev, "rx");
 	if (atmel_port->chan_rx == NULL)
 		goto chan_err;
 	dev_info(port->dev, "using %s for rx DMA transfers\n",
@@ -1631,7 +1633,7 @@ static void atmel_tasklet_tx_func(unsigned long data)
 static void atmel_init_property(struct atmel_uart_port *atmel_port,
 				struct platform_device *pdev)
 {
-	struct device_node *np = pdev->dev.of_node;
+	struct device_node *np = pdev->dev.parent->of_node;
 
 	/* DMA/PDC usage specification */
 	if (of_property_read_bool(np, "atmel,use-dma-rx")) {
@@ -2222,8 +2224,8 @@ static const char *atmel_type(struct uart_port *port)
  */
 static void atmel_release_port(struct uart_port *port)
 {
-	struct platform_device *pdev = to_platform_device(port->dev);
-	int size = pdev->resource[0].end - pdev->resource[0].start + 1;
+	struct platform_device *mpdev = to_platform_device(port->dev->parent);
+	int size = resource_size(mpdev->resource);
 
 	release_mem_region(port->mapbase, size);
 
@@ -2238,8 +2240,8 @@ static void atmel_release_port(struct uart_port *port)
  */
 static int atmel_request_port(struct uart_port *port)
 {
-	struct platform_device *pdev = to_platform_device(port->dev);
-	int size = pdev->resource[0].end - pdev->resource[0].start + 1;
+	struct platform_device *mpdev = to_platform_device(port->dev->parent);
+	int size = resource_size(mpdev->resource);
 
 	if (!request_mem_region(port->mapbase, size, "atmel_serial"))
 		return -EBUSY;
@@ -2341,27 +2343,28 @@ static int atmel_init_port(struct atmel_uart_port *atmel_port,
 {
 	int ret;
 	struct uart_port *port = &atmel_port->uart;
+	struct platform_device *mpdev = to_platform_device(pdev->dev.parent);
 
 	atmel_init_property(atmel_port, pdev);
 	atmel_set_ops(port);
 
-	uart_get_rs485_mode(&pdev->dev, &port->rs485);
+	uart_get_rs485_mode(&mpdev->dev, &port->rs485);
 
 	port->iotype		= UPIO_MEM;
 	port->flags		= UPF_BOOT_AUTOCONF | UPF_IOREMAP;
 	port->ops		= &atmel_pops;
 	port->fifosize		= 1;
 	port->dev		= &pdev->dev;
-	port->mapbase	= pdev->resource[0].start;
-	port->irq	= pdev->resource[1].start;
+	port->mapbase		= mpdev->resource[0].start;
+	port->irq		= mpdev->resource[1].start;
 	port->rs485_config	= atmel_config_rs485;
-	port->membase	= NULL;
+	port->membase		= NULL;
 
 	memset(&atmel_port->rx_ring, 0, sizeof(atmel_port->rx_ring));
 
 	/* for console, the clock could already be configured */
 	if (!atmel_port->clk) {
-		atmel_port->clk = clk_get(&pdev->dev, "usart");
+		atmel_port->clk = clk_get(&mpdev->dev, "usart");
 		if (IS_ERR(atmel_port->clk)) {
 			ret = PTR_ERR(atmel_port->clk);
 			atmel_port->clk = NULL;
@@ -2652,11 +2655,13 @@ static int atmel_serial_resume(struct platform_device *pdev)
 static void atmel_serial_probe_fifos(struct atmel_uart_port *atmel_port,
 				     struct platform_device *pdev)
 {
+	struct device *dev = pdev->dev.parent;
+
 	atmel_port->fifo_size = 0;
 	atmel_port->rts_low = 0;
 	atmel_port->rts_high = 0;
 
-	if (of_property_read_u32(pdev->dev.of_node,
+	if (of_property_read_u32(dev->of_node,
 				 "atmel,fifo-size",
 				 &atmel_port->fifo_size))
 		return;
@@ -2694,11 +2699,10 @@ static void atmel_serial_probe_fifos(struct atmel_uart_port *atmel_port,
 static int atmel_serial_probe(struct platform_device *pdev)
 {
 	struct atmel_uart_port *atmel_port;
-	struct device_node *np = pdev->dev.of_node;
+	struct device_node *np = pdev->dev.parent->of_node;
 	void *data;
 	int ret = -ENODEV;
 	bool rs485_enabled;
-
 	BUILD_BUG_ON(ATMEL_SERIAL_RINGSIZE & (ATMEL_SERIAL_RINGSIZE - 1));
 
 	ret = of_alias_get_id(np, "serial");
@@ -2845,7 +2849,7 @@ static struct platform_driver atmel_serial_driver = {
 	.suspend	= atmel_serial_suspend,
 	.resume		= atmel_serial_resume,
 	.driver		= {
-		.name			= "atmel_usart",
+		.name			= "atmel_usart_serial",
 		.of_match_table		= of_match_ptr(atmel_serial_dt_ids),
 	},
 };
-- 
2.17.0

^ permalink raw reply related

* [PATCH v4 5/6] spi: at91-usart: add driver for at91-usart as spi
From: Radu Pirea @ 2018-05-25 17:19 UTC (permalink / raw)
  To: broonie, nicolas.ferre, alexandre.belloni, lee.jones,
	richard.genoud, robh+dt, mark.rutland, gregkh
  Cc: linux-spi, linux-arm-kernel, linux-kernel, devicetree,
	linux-serial, Radu Pirea
In-Reply-To: <20180525171941.26766-1-radu.pirea@microchip.com>

This is the driver for at91-usart in spi mode. The USART IP can be configured
to work in many modes and one of them is SPI.

The driver was tested on sama5d3-xplained and sama5d4-xplained boards with
enc28j60 ethernet controller as slave.

Signed-off-by: Radu Pirea <radu.pirea@microchip.com>
---
 drivers/spi/Kconfig          |   9 +
 drivers/spi/Makefile         |   1 +
 drivers/spi/spi-at91-usart.c | 431 +++++++++++++++++++++++++++++++++++
 3 files changed, 441 insertions(+)
 create mode 100644 drivers/spi/spi-at91-usart.c

diff --git a/drivers/spi/Kconfig b/drivers/spi/Kconfig
index 6fb0347a24f2..1a002a32d7aa 100644
--- a/drivers/spi/Kconfig
+++ b/drivers/spi/Kconfig
@@ -77,6 +77,15 @@ config SPI_ATMEL
 	  This selects a driver for the Atmel SPI Controller, present on
 	  many AT91 (ARM) chips.
 
+config SPI_AT91_USART
+	tristate "Atmel USART Controller SPI driver"
+	depends on HAS_DMA
+	depends on (ARCH_AT91 || COMPILE_TEST)
+	select MFD_AT91_USART
+	help
+	  This selects a driver for the AT91 USART Controller as SPI Master,
+	  present on AT91 and SAMA5 SoC series.
+
 config SPI_AU1550
 	tristate "Au1550/Au1200/Au1300 SPI Controller"
 	depends on MIPS_ALCHEMY
diff --git a/drivers/spi/Makefile b/drivers/spi/Makefile
index 34c5f2832ddf..fb6cb42f4eaa 100644
--- a/drivers/spi/Makefile
+++ b/drivers/spi/Makefile
@@ -15,6 +15,7 @@ obj-$(CONFIG_SPI_LOOPBACK_TEST)		+= spi-loopback-test.o
 obj-$(CONFIG_SPI_ALTERA)		+= spi-altera.o
 obj-$(CONFIG_SPI_ARMADA_3700)		+= spi-armada-3700.o
 obj-$(CONFIG_SPI_ATMEL)			+= spi-atmel.o
+obj-$(CONFIG_SPI_AT91_USART)		+= spi-at91-usart.o
 obj-$(CONFIG_SPI_ATH79)			+= spi-ath79.o
 obj-$(CONFIG_SPI_AU1550)		+= spi-au1550.o
 obj-$(CONFIG_SPI_AXI_SPI_ENGINE)	+= spi-axi-spi-engine.o
diff --git a/drivers/spi/spi-at91-usart.c b/drivers/spi/spi-at91-usart.c
new file mode 100644
index 000000000000..3ca0fab6691e
--- /dev/null
+++ b/drivers/spi/spi-at91-usart.c
@@ -0,0 +1,431 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Driver for AT91 USART Controllers as SPI
+ *
+ * Copyright (C) 2018 Microchip Technology Inc.
+ * Author: Radu Pirea <radu.pirea@microchip.com>
+ */
+
+#include <linux/clk.h>
+#include <linux/delay.h>
+#include <linux/interrupt.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/of_gpio.h>
+#include <linux/platform_device.h>
+
+#include <linux/spi/spi.h>
+
+#define US_CR			0x00
+#define US_MR			0x04
+#define US_IER			0x08
+#define US_IDR			0x0C
+#define US_CSR			0x14
+#define US_RHR			0x18
+#define US_THR			0x1C
+#define US_BRGR			0x20
+#define US_VERSION		0xFC
+
+#define US_CR_RSTRX		BIT(2)
+#define US_CR_RSTTX		BIT(3)
+#define US_CR_RXEN		BIT(4)
+#define US_CR_RXDIS		BIT(5)
+#define US_CR_TXEN		BIT(6)
+#define US_CR_TXDIS		BIT(7)
+
+#define US_MR_SPI_MASTER	0x0E
+#define US_MR_CHRL		GENMASK(7, 6)
+#define US_MR_CPHA		BIT(8)
+#define US_MR_CPOL		BIT(16)
+#define US_MR_CLKO		BIT(18)
+#define US_MR_WRDBT		BIT(20)
+#define US_MR_LOOP		BIT(15)
+
+#define US_IR_RXRDY		BIT(0)
+#define US_IR_TXRDY		BIT(1)
+#define US_IR_OVRE		BIT(5)
+
+#define US_BRGR_SIZE		BIT(16)
+
+#define US_MIN_CLK_DIV		0x06
+#define US_MAX_CLK_DIV		BIT(16)
+
+#define US_RESET		(US_CR_RSTRX | US_CR_RSTTX)
+#define US_DISABLE		(US_CR_RXDIS | US_CR_TXDIS)
+#define US_ENABLE		(US_CR_RXEN | US_CR_TXEN)
+#define US_OVRE_RXRDY_IRQS	(US_IR_OVRE | US_IR_RXRDY)
+
+#define US_INIT			(US_MR_SPI_MASTER | US_MR_CHRL | US_MR_CLKO | \
+				US_MR_WRDBT)
+
+/* Register access macros */
+#define spi_readl(port, reg) \
+	readl_relaxed((port)->regs + US_##reg)
+#define spi_writel(port, reg, value) \
+	writel_relaxed((value), (port)->regs + US_##reg)
+
+#define spi_readb(port, reg) \
+	readb_relaxed((port)->regs + US_##reg)
+#define spi_writeb(port, reg, value) \
+	writeb_relaxed((value), (port)->regs + US_##reg)
+
+struct at91_usart_spi {
+	struct spi_transfer	*current_transfer;
+	void __iomem		*regs;
+	struct device		*dev;
+	struct clk		*clk;
+
+	/*used in interrupt to protect data reading*/
+	spinlock_t		lock;
+
+	int			irq;
+	unsigned int		current_tx_remaining_bytes;
+	unsigned int		current_rx_remaining_bytes;
+	int			done_status;
+
+	u32			spi_clk;
+	u32			status;
+
+	bool			xfer_failed;
+};
+
+static inline u32 at91_usart_spi_tx_ready(struct at91_usart_spi *aus)
+{
+	return aus->status & US_IR_TXRDY;
+}
+
+static inline u32 at91_usart_spi_rx_ready(struct at91_usart_spi *aus)
+{
+	return aus->status & US_IR_RXRDY;
+}
+
+static inline u32 at91_usart_spi_check_overrun(struct at91_usart_spi *aus)
+{
+	return aus->status & US_IR_OVRE;
+}
+
+static inline u32 at91_usart_spi_read_status(struct at91_usart_spi *aus)
+{
+	aus->status = spi_readl(aus, CSR);
+	return aus->status;
+}
+
+static inline void at91_usart_spi_tx(struct at91_usart_spi *aus)
+{
+	unsigned int len = aus->current_transfer->len;
+	unsigned int remaining = aus->current_tx_remaining_bytes;
+	const u8  *tx_buf = aus->current_transfer->tx_buf;
+
+	if (remaining)
+		if (at91_usart_spi_tx_ready(aus)) {
+			spi_writeb(aus, THR, tx_buf[len - remaining]);
+			aus->current_tx_remaining_bytes--;
+		}
+}
+
+static inline void at91_usart_spi_rx(struct at91_usart_spi *aus)
+{
+	int len = aus->current_transfer->len;
+	int remaining = aus->current_rx_remaining_bytes;
+	u8  *rx_buf = aus->current_transfer->rx_buf;
+
+	if (remaining) {
+		rx_buf[len - remaining] = spi_readb(aus, RHR);
+		aus->current_rx_remaining_bytes--;
+	}
+}
+
+static inline void
+at91_usart_spi_set_xfer_speed(struct at91_usart_spi *aus,
+			      struct spi_transfer *xfer)
+{
+	spi_writel(aus, BRGR,
+		   DIV_ROUND_UP(aus->spi_clk, xfer->speed_hz));
+}
+
+static irqreturn_t at91_usart_spi_interrupt(int irq, void *dev_id)
+{
+	struct spi_controller *controller = dev_id;
+	struct at91_usart_spi *aus = spi_master_get_devdata(controller);
+
+	spin_lock(&aus->lock);
+	at91_usart_spi_read_status(aus);
+
+	if (at91_usart_spi_check_overrun(aus)) {
+		aus->xfer_failed = true;
+		aus->done_status = -EIO;
+		spi_writel(aus, IDR, US_IR_OVRE | US_IR_RXRDY);
+		spin_unlock(&aus->lock);
+		return IRQ_HANDLED;
+	}
+
+	if (at91_usart_spi_rx_ready(aus)) {
+		at91_usart_spi_rx(aus);
+		spin_unlock(&aus->lock);
+		return IRQ_HANDLED;
+	}
+
+	spin_unlock(&aus->lock);
+
+	return IRQ_NONE;
+}
+
+static int at91_usart_spi_setup(struct spi_device *spi)
+{
+	struct at91_usart_spi *aus = spi_master_get_devdata(spi->controller);
+	u32 *ausd = spi->controller_state;
+	unsigned int mr = spi_readl(aus, MR);
+	u8 bits = spi->bits_per_word;
+
+	if (bits != 8) {
+		dev_dbg(&spi->dev, "Only 8 bits per word are supported\n");
+		return -EINVAL;
+	}
+
+	if (spi->mode & SPI_CPOL)
+		mr |= US_MR_CPOL;
+	else
+		mr &= ~US_MR_CPOL;
+
+	if (spi->mode & SPI_CPHA)
+		mr |= US_MR_CPHA;
+	else
+		mr &= ~US_MR_CPHA;
+
+	if (spi->mode & SPI_LOOP)
+		mr |= US_MR_LOOP;
+	else
+		mr &= ~US_MR_LOOP;
+
+	if (!ausd) {
+		ausd = kzalloc(sizeof(*ausd), GFP_KERNEL);
+		if (!ausd)
+			return -ENOMEM;
+
+		spi->controller_state = ausd;
+	}
+
+	*ausd = mr;
+
+	dev_dbg(&spi->dev,
+		"setup: bpw %u mode 0x%x -> mr %d %08x\n",
+		bits, spi->mode, spi->chip_select, mr);
+
+	return 0;
+}
+
+int at91_usart_spi_transfer_one(struct spi_controller *ctlr,
+				struct spi_device *spi,
+				struct spi_transfer *xfer)
+{
+	struct at91_usart_spi *aus = spi_master_get_devdata(ctlr);
+
+	at91_usart_spi_set_xfer_speed(aus, xfer);
+	aus->done_status = 0;
+	aus->xfer_failed = false;
+	aus->current_transfer = xfer;
+	aus->current_tx_remaining_bytes = xfer->len;
+	aus->current_rx_remaining_bytes = xfer->len;
+
+	while ((aus->current_tx_remaining_bytes ||
+		aus->current_rx_remaining_bytes) && !aus->xfer_failed) {
+		at91_usart_spi_read_status(aus);
+		at91_usart_spi_tx(aus);
+		cpu_relax();
+	}
+	if (aus->xfer_failed) {
+		dev_err(aus->dev, "Overrun!\n");
+		return -EIO;
+	}
+
+	return 0;
+}
+
+int at91_usart_spi_prepare_message(struct spi_controller *ctlr,
+				   struct spi_message *message)
+{
+	struct at91_usart_spi *aus = spi_master_get_devdata(ctlr);
+	struct spi_device *spi = message->spi;
+	u32 *ausd = spi->controller_state;
+
+	spi_writel(aus, CR, US_ENABLE);
+	spi_writel(aus, IER, US_OVRE_RXRDY_IRQS);
+	spi_writel(aus, MR, *ausd);
+
+	return 0;
+}
+
+int at91_usart_spi_unprepare_message(struct spi_controller *ctlr,
+				     struct spi_message *message)
+{
+	struct at91_usart_spi *aus = spi_master_get_devdata(ctlr);
+
+	spi_writel(aus, CR, US_RESET | US_DISABLE);
+	spi_writel(aus, IDR, US_OVRE_RXRDY_IRQS);
+	return 0;
+}
+
+static void at91_usart_spi_cleanup(struct spi_device *spi)
+{
+	struct at91_usart_spi_device *ausd = spi->controller_state;
+
+	spi->controller_state = NULL;
+	kfree(ausd);
+}
+
+static void at91_usart_spi_init(struct at91_usart_spi *aus)
+{
+	spi_writel(aus, MR, US_INIT);
+	spi_writel(aus, CR, US_RESET | US_DISABLE);
+}
+
+static int at91_usart_gpio_setup(struct platform_device *pdev)
+{
+	struct device_node	*np = pdev->dev.parent->of_node;
+	int			i;
+	int			ret = 0;
+	int			nb = 0;
+
+	if (!np)
+		return -EINVAL;
+
+	nb = of_gpio_named_count(np, "cs-gpios");
+	for (i = 0; i < nb; i++) {
+		int cs_gpio = of_get_named_gpio(np, "cs-gpios", i);
+
+		if (cs_gpio < 0)
+			return cs_gpio;
+
+		if (gpio_is_valid(cs_gpio)) {
+			ret = devm_gpio_request_one(&pdev->dev, cs_gpio,
+						    GPIOF_DIR_OUT,
+						    dev_name(&pdev->dev));
+			if (ret)
+				return ret;
+		}
+	}
+
+	return 0;
+}
+
+static int at91_usart_spi_probe(struct platform_device *pdev)
+{
+	struct resource *regs;
+	struct spi_controller *controller;
+	struct at91_usart_spi *aus;
+	struct clk *clk;
+	int irq;
+	int ret;
+
+	regs = platform_get_resource(to_platform_device(pdev->dev.parent),
+				     IORESOURCE_MEM, 0);
+	if (!regs)
+		return -EINVAL;
+
+	irq = platform_get_irq(to_platform_device(pdev->dev.parent), 0);
+	if (irq < 0)
+		return irq;
+
+	clk = devm_clk_get(pdev->dev.parent, "usart");
+	if (IS_ERR(clk))
+		return PTR_ERR(clk);
+
+	ret = -ENOMEM;
+	controller = spi_alloc_master(&pdev->dev, sizeof(*aus));
+	if (!controller)
+		goto at91_usart_spi_probe_fail;
+
+	ret = at91_usart_gpio_setup(pdev);
+	if (ret)
+		goto at91_usart_spi_probe_fail;
+
+	controller->mode_bits = SPI_CPOL | SPI_CPHA | SPI_LOOP | SPI_CS_HIGH;
+	controller->dev.of_node = pdev->dev.parent->of_node;
+	controller->bits_per_word_mask = SPI_BPW_MASK(8);
+	controller->setup = at91_usart_spi_setup;
+	controller->flags = SPI_MASTER_MUST_RX | SPI_MASTER_MUST_TX;
+	controller->transfer_one = at91_usart_spi_transfer_one;
+	controller->prepare_message = at91_usart_spi_prepare_message;
+	controller->unprepare_message = at91_usart_spi_unprepare_message;
+	controller->cleanup = at91_usart_spi_cleanup;
+	controller->max_speed_hz = DIV_ROUND_UP(clk_get_rate(clk),
+						US_MIN_CLK_DIV);
+	controller->min_speed_hz = DIV_ROUND_UP(clk_get_rate(clk),
+						US_MAX_CLK_DIV);
+	platform_set_drvdata(pdev, controller);
+
+	aus = spi_master_get_devdata(controller);
+
+	aus->dev = &pdev->dev;
+	aus->regs = devm_ioremap_resource(&pdev->dev, regs);
+	if (IS_ERR(aus->regs)) {
+		ret = PTR_ERR(aus->regs);
+		goto at91_usart_spi_probe_fail;
+	}
+
+	aus->irq = irq;
+	aus->clk = clk;
+
+	ret = devm_request_irq(&pdev->dev, irq, at91_usart_spi_interrupt, 0,
+			       dev_name(&pdev->dev), controller);
+	if (ret)
+		goto at91_usart_spi_probe_fail;
+
+	ret = clk_prepare_enable(clk);
+	if (ret)
+		goto at91_usart_spi_probe_fail;
+
+	aus->spi_clk = clk_get_rate(clk);
+	at91_usart_spi_init(aus);
+
+	spin_lock_init(&aus->lock);
+	ret = devm_spi_register_master(&pdev->dev, controller);
+	if (ret)
+		goto fail_register_master;
+
+	dev_info(&pdev->dev,
+		 "Atmel USART SPI Controller version 0x%x at 0x%08lx (irq %d)\n",
+		 spi_readl(aus, VERSION),
+		 (unsigned long)regs->start, irq);
+
+	return 0;
+
+fail_register_master:
+	clk_disable_unprepare(clk);
+at91_usart_spi_probe_fail:
+	spi_master_put(controller);
+	return ret;
+}
+
+static int at91_usart_spi_remove(struct platform_device *pdev)
+{
+	struct spi_master *master = platform_get_drvdata(pdev);
+	struct at91_usart_spi *aus = spi_master_get_devdata(master);
+
+	clk_disable_unprepare(aus->clk);
+
+	return 0;
+}
+
+static const struct of_device_id at91_usart_spi_dt_ids[] = {
+	{ .compatible = "microchip,sama5d3-usart-spi"},
+	{ .compatible = "microchip,sama5d4-usart-spi"},
+	{ .compatible = "microchip,at91sam9g45-usart-spi"},
+	{ /* sentinel */}
+};
+
+MODULE_DEVICE_TABLE(of, at91_usart_spi_dt_ids);
+
+static struct platform_driver at91_usart_spi_driver = {
+	.driver = {
+		.name = "at91_usart_spi",
+		.of_match_table = of_match_ptr(at91_usart_spi_dt_ids),
+	},
+	.probe = at91_usart_spi_probe,
+	.remove = at91_usart_spi_remove, };
+module_platform_driver(at91_usart_spi_driver);
+
+MODULE_DESCRIPTION("Microchip AT91 USART SPI Controller driver");
+MODULE_AUTHOR("Radu Pirea <radu.pirea@microchip.com>");
+MODULE_LICENSE("GPL v2");
+MODULE_ALIAS("platform:at91_usart_spi");
-- 
2.17.0

^ permalink raw reply related

* [PATCH v4 4/6] MAINTAINERS: add at91 usart spi driver
From: Radu Pirea @ 2018-05-25 17:19 UTC (permalink / raw)
  To: broonie, nicolas.ferre, alexandre.belloni, lee.jones,
	richard.genoud, robh+dt, mark.rutland, gregkh
  Cc: linux-spi, linux-arm-kernel, linux-kernel, devicetree,
	linux-serial, Radu Pirea
In-Reply-To: <20180525171941.26766-1-radu.pirea@microchip.com>

Added entry for at91 usart mfd driver.

Signed-off-by: Radu Pirea <radu.pirea@microchip.com>
---
 MAINTAINERS | 7 +++++++
 1 file changed, 7 insertions(+)

diff --git a/MAINTAINERS b/MAINTAINERS
index 12203d07c6af..dae31df711fb 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -9201,6 +9201,13 @@ F:	drivers/mfd/at91-usart.c
 F:	include/dt-bindings/mfd/at91-usart.h
 F:	Documentation/devicetree/bindings/mfd/atmel-usart.txt
 
+MICROCHIP AT91 USART SPI DRIVER
+M:	Radu Pirea <radu.pirea@microchip.com>
+L:	linux-spi@vger.kernel.org
+S:	Supported
+F:	drivers/spi/spi-at91-usart.c
+F:	Documentation/devicetree/bindings/mfd/atmel-usart.txt
+
 MICROCHIP KSZ SERIES ETHERNET SWITCH DRIVER
 M:	Woojung Huh <Woojung.Huh@microchip.com>
 M:	Microchip Linux Driver Support <UNGLinuxDriver@microchip.com>
-- 
2.17.0

^ permalink raw reply related

* [PATCH v4 3/6] mfd: at91-usart: added mfd driver for usart
From: Radu Pirea @ 2018-05-25 17:19 UTC (permalink / raw)
  To: broonie, nicolas.ferre, alexandre.belloni, lee.jones,
	richard.genoud, robh+dt, mark.rutland, gregkh
  Cc: linux-spi, linux-arm-kernel, linux-kernel, devicetree,
	linux-serial, Radu Pirea
In-Reply-To: <20180525171941.26766-1-radu.pirea@microchip.com>

This mfd driver is just a wrapper over atmel_serial driver and
spi-at91-usart driver. Selection of one of the drivers is based on a
property from device tree. If the property is not specified, the default
driver is atmel_serial.

Signed-off-by: Radu Pirea <radu.pirea@microchip.com>
---
 drivers/mfd/Kconfig                  | 10 ++++
 drivers/mfd/Makefile                 |  1 +
 drivers/mfd/at91-usart.c             | 75 ++++++++++++++++++++++++++++
 include/dt-bindings/mfd/at91-usart.h | 17 +++++++
 4 files changed, 103 insertions(+)
 create mode 100644 drivers/mfd/at91-usart.c
 create mode 100644 include/dt-bindings/mfd/at91-usart.h

diff --git a/drivers/mfd/Kconfig b/drivers/mfd/Kconfig
index b860eb5aa194..de99b79061b7 100644
--- a/drivers/mfd/Kconfig
+++ b/drivers/mfd/Kconfig
@@ -99,6 +99,16 @@ config MFD_AAT2870_CORE
 	  additional drivers must be enabled in order to use the
 	  functionality of the device.
 
+config MFD_AT91_USART
+	tristate "AT91 USART Driver"
+	select MFD_CORE
+	depends on OF
+	help
+	  Select this to get support for AT91 USART IP. This is a wrapper
+	  over at91-usart-serial driver and usart-spi-driver. Only one function
+	  can be used at a time. The choice is done at boot time by the probe
+	  function of this MFD driver according to a device tree property.
+
 config MFD_ATMEL_FLEXCOM
 	tristate "Atmel Flexcom (Flexible Serial Communication Unit)"
 	select MFD_CORE
diff --git a/drivers/mfd/Makefile b/drivers/mfd/Makefile
index d9d2cf0d32ef..db1332aa96db 100644
--- a/drivers/mfd/Makefile
+++ b/drivers/mfd/Makefile
@@ -185,6 +185,7 @@ obj-$(CONFIG_MFD_SPMI_PMIC)	+= qcom-spmi-pmic.o
 obj-$(CONFIG_TPS65911_COMPARATOR)	+= tps65911-comparator.o
 obj-$(CONFIG_MFD_TPS65090)	+= tps65090.o
 obj-$(CONFIG_MFD_AAT2870_CORE)	+= aat2870-core.o
+obj-$(CONFIG_MFD_AT91_USART)	+= at91-usart.o
 obj-$(CONFIG_MFD_ATMEL_FLEXCOM)	+= atmel-flexcom.o
 obj-$(CONFIG_MFD_ATMEL_HLCDC)	+= atmel-hlcdc.o
 obj-$(CONFIG_MFD_ATMEL_SMC)	+= atmel-smc.o
diff --git a/drivers/mfd/at91-usart.c b/drivers/mfd/at91-usart.c
new file mode 100644
index 000000000000..0535a256a3c0
--- /dev/null
+++ b/drivers/mfd/at91-usart.c
@@ -0,0 +1,75 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Driver for AT91 USART
+ *
+ * Copyright (C) 2018 Microchip Technology
+ *
+ * Author: Radu Pirea <radu.pirea@microchip.com>
+ *
+ */
+
+#include <dt-bindings/mfd/at91-usart.h>
+
+#include <linux/err.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/mfd/core.h>
+#include <linux/of.h>
+#include <linux/of_platform.h>
+#include <linux/pinctrl/pinctrl.h>
+#include <linux/platform_device.h>
+#include <linux/slab.h>
+#include <linux/types.h>
+
+static struct mfd_cell at91_usart_spi_subdev = {
+		.name = "at91_usart_spi",
+		.of_compatible = "microchip,at91sam9g45-usart-spi",
+	};
+
+static struct mfd_cell at91_usart_serial_subdev = {
+		.name = "atmel_usart_serial",
+		.of_compatible = "atmel,at91rm9200-usart-serial",
+	};
+
+static int at91_usart_mode_probe(struct platform_device *pdev)
+{
+	struct device_node *np = pdev->dev.of_node;
+	struct mfd_cell cell;
+	u32 opmode;
+	int err;
+
+	err = of_property_read_u32(np, "atmel,usart-mode", &opmode);
+
+	switch (opmode) {
+	case AT91_USART_MODE_SPI:
+		cell = at91_usart_spi_subdev;
+		break;
+	case AT91_USART_MODE_SERIAL:
+	default:
+		cell = at91_usart_serial_subdev;
+	}
+
+	return mfd_add_devices(&pdev->dev, PLATFORM_DEVID_AUTO, &cell, 1,
+			      NULL, 0, NULL);
+}
+
+static const struct of_device_id at91_usart_mode_of_match[] = {
+	{ .compatible = "atmel,at91rm9200-usart" },
+	{ .compatible = "atmel,at91sam9260-usart" },
+	{ /* sentinel */ }
+};
+MODULE_DEVICE_TABLE(of, at91_flexcom_of_match);
+
+static struct platform_driver at91_usart_mfd = {
+	.probe	= at91_usart_mode_probe,
+	.driver	= {
+		.name		= "at91_usart_mode",
+		.of_match_table	= at91_usart_mode_of_match,
+	},
+};
+
+module_platform_driver(at91_usart_mfd);
+
+MODULE_AUTHOR("Radu Pirea <radu.pirea@microchip.com>");
+MODULE_DESCRIPTION("AT91 USART MFD driver");
+MODULE_LICENSE("GPL v2");
diff --git a/include/dt-bindings/mfd/at91-usart.h b/include/dt-bindings/mfd/at91-usart.h
new file mode 100644
index 000000000000..ac811628a42d
--- /dev/null
+++ b/include/dt-bindings/mfd/at91-usart.h
@@ -0,0 +1,17 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * This header provides macros for AT91 USART DT bindings.
+ *
+ * Copyright (C) 2018 Microchip Technology
+ *
+ * Author: Radu Pirea <radu.pirea@microchip.com>
+ *
+ */
+
+#ifndef __DT_BINDINGS_AT91_USART_H__
+#define __DT_BINDINGS_AT91_USART_H__
+
+#define AT91_USART_MODE_SERIAL	1
+#define AT91_USART_MODE_SPI	2
+
+#endif /* __DT_BINDINGS_AT91_USART_H__ */
-- 
2.17.0

^ permalink raw reply related

* [PATCH v4 2/6] dt-bindings: add binding for atmel-usart in SPI mode
From: Radu Pirea @ 2018-05-25 17:19 UTC (permalink / raw)
  To: broonie, nicolas.ferre, alexandre.belloni, lee.jones,
	richard.genoud, robh+dt, mark.rutland, gregkh
  Cc: linux-spi, linux-arm-kernel, linux-kernel, devicetree,
	linux-serial, Radu Pirea
In-Reply-To: <20180525171941.26766-1-radu.pirea@microchip.com>

This patch moves the bindings for serial from serial/atmel-usart.txt to
mfd/atmel-usart.txt and adds bindings for USART in SPI mode.

Signed-off-by: Radu Pirea <radu.pirea@microchip.com>
---
 .../bindings/{serial => mfd}/atmel-usart.txt  | 25 +++++++++++++++++--
 1 file changed, 23 insertions(+), 2 deletions(-)
 rename Documentation/devicetree/bindings/{serial => mfd}/atmel-usart.txt (76%)

diff --git a/Documentation/devicetree/bindings/serial/atmel-usart.txt b/Documentation/devicetree/bindings/mfd/atmel-usart.txt
similarity index 76%
rename from Documentation/devicetree/bindings/serial/atmel-usart.txt
rename to Documentation/devicetree/bindings/mfd/atmel-usart.txt
index 7c0d6b2f53e4..3b9e18642c3b 100644
--- a/Documentation/devicetree/bindings/serial/atmel-usart.txt
+++ b/Documentation/devicetree/bindings/mfd/atmel-usart.txt
@@ -1,6 +1,6 @@
 * Atmel Universal Synchronous Asynchronous Receiver/Transmitter (USART)
 
-Required properties:
+Required properties for USART:
 - compatible: Should be "atmel,<chip>-usart" or "atmel,<chip>-dbgu"
   The compatible <chip> indicated will be the first SoC to support an
   additional mode or an USART new feature.
@@ -11,7 +11,13 @@ Required properties:
 	Required elements: "usart"
 - clocks: phandles to input clocks.
 
-Optional properties:
+Required properties for USART in SPI mode:
+- #size-cells      : Must be <0>
+- #address-cells   : Must be <1>
+- cs-gpios: chipselects (internal cs not supported)
+- atmel,usart-mode : Must be <USART_MODE_SPI> (found in dt-bindings/mfd/at91-usart.h)
+
+Optional properties in serial mode:
 - atmel,use-dma-rx: use of PDC or DMA for receiving data
 - atmel,use-dma-tx: use of PDC or DMA for transmitting data
 - {rts,cts,dtr,dsr,rng,dcd}-gpios: specify a GPIO for RTS/CTS/DTR/DSR/RI/DCD line respectively.
@@ -62,3 +68,18 @@ Example:
 		dma-names = "tx", "rx";
 		atmel,fifo-size = <32>;
 	};
+
+- SPI mode:
+	#include <dt-bindings/mfd/at91-usart.h>
+
+	spi0: spi@f001c000 {
+		#address-cells = <1>;
+		#size-cells = <0>;
+		compatible = "atmel,at91rm9200-usart", "atmel,at91sam9260-usart";
+		atmel,usart-mode = <USART_MODE_SPI>;
+		reg = <0xf001c000 0x100>;
+		interrupts = <12 IRQ_TYPE_LEVEL_HIGH>;
+		clocks = <&usart0_clk>;
+		clock-names = "usart";
+		cs-gpios = <&pioB 3 0>;
+	};
-- 
2.17.0

^ permalink raw reply related

* [PATCH v4 1/6] MAINTAINERS: add at91 usart mfd driver
From: Radu Pirea @ 2018-05-25 17:19 UTC (permalink / raw)
  To: broonie, nicolas.ferre, alexandre.belloni, lee.jones,
	richard.genoud, robh+dt, mark.rutland, gregkh
  Cc: linux-spi, linux-arm-kernel, linux-kernel, devicetree,
	linux-serial, Radu Pirea
In-Reply-To: <20180525171941.26766-1-radu.pirea@microchip.com>

Added entry for at91 usart mfd driver.

Signed-off-by: Radu Pirea <radu.pirea@microchip.com>
---
 MAINTAINERS | 9 +++++++++
 1 file changed, 9 insertions(+)

diff --git a/MAINTAINERS b/MAINTAINERS
index 8e2a2fddbd19..12203d07c6af 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -9160,6 +9160,7 @@ M:	Richard Genoud <richard.genoud@gmail.com>
 S:	Maintained
 F:	drivers/tty/serial/atmel_serial.c
 F:	drivers/tty/serial/atmel_serial.h
+F:	Documentation/devicetree/bindings/mfd/atmel-usart.txt
 
 MICROCHIP / ATMEL DMA DRIVER
 M:	Ludovic Desroches <ludovic.desroches@microchip.com>
@@ -9192,6 +9193,14 @@ S:	Supported
 F:	drivers/mtd/nand/raw/atmel/*
 F:	Documentation/devicetree/bindings/mtd/atmel-nand.txt
 
+MICROCHIP AT91 USART MFD DRIVER
+M:	Radu Pirea <radu.pirea@microchip.com>
+L:	linux-kernel@vger.kernel.org
+S:	Supported
+F:	drivers/mfd/at91-usart.c
+F:	include/dt-bindings/mfd/at91-usart.h
+F:	Documentation/devicetree/bindings/mfd/atmel-usart.txt
+
 MICROCHIP KSZ SERIES ETHERNET SWITCH DRIVER
 M:	Woojung Huh <Woojung.Huh@microchip.com>
 M:	Microchip Linux Driver Support <UNGLinuxDriver@microchip.com>
-- 
2.17.0

^ permalink raw reply related

* [PATCH v4 0/6] Driver for at91 usart in spi mode
From: Radu Pirea @ 2018-05-25 17:19 UTC (permalink / raw)
  To: broonie, nicolas.ferre, alexandre.belloni, lee.jones,
	richard.genoud, robh+dt, mark.rutland, gregkh
  Cc: linux-spi, linux-arm-kernel, linux-kernel, devicetree,
	linux-serial, Radu Pirea

Hello,

This is the second version of driver. I added a mfd driver which by
default probes atmel_serial driver and if in dt is specified to probe
the spi driver, then the spi-at91-usart driver will be probed. The
compatible for atmel_serial is now the compatible for at91-usart mfd
driver and compatilbe for atmel_serial driver was changed in order to
keep the bindings for serial as they are.

Changes in v1:
- added spi-at91-usart driver

Changes in v2:
- added at91-usart mfd driver
- modified spi-at91-usart driver to work as mfd driver child
- modified atmel_serial driver to work as mfd driver child

Changes in v3:
- fixed spi slaves probing

Changes in v4:
- modified the spi driver to use cs gpio support form spi subsystem
- fixed dma transfers for serial driver
- squashed binding for spi and serial and moved them to mfd/atmel-usart.txt


Radu Pirea (6):
  MAINTAINERS: add at91 usart mfd driver
  dt-bindings: add binding for atmel-usart in SPI mode
  mfd: at91-usart: added mfd driver for usart
  MAINTAINERS: add at91 usart spi driver
  spi: at91-usart: add driver for at91-usart as spi
  tty/serial: atmel: changed the driver to work under at91-usart mfd

 .../bindings/{serial => mfd}/atmel-usart.txt  |  25 +-
 MAINTAINERS                                   |  16 +
 drivers/mfd/Kconfig                           |  10 +
 drivers/mfd/Makefile                          |   1 +
 drivers/mfd/at91-usart.c                      |  75 +++
 drivers/spi/Kconfig                           |   9 +
 drivers/spi/Makefile                          |   1 +
 drivers/spi/spi-at91-usart.c                  | 431 ++++++++++++++++++
 drivers/tty/serial/Kconfig                    |   1 +
 drivers/tty/serial/atmel_serial.c             |  40 +-
 include/dt-bindings/mfd/at91-usart.h          |  17 +
 11 files changed, 606 insertions(+), 20 deletions(-)
 rename Documentation/devicetree/bindings/{serial => mfd}/atmel-usart.txt (76%)
 create mode 100644 drivers/mfd/at91-usart.c
 create mode 100644 drivers/spi/spi-at91-usart.c
 create mode 100644 include/dt-bindings/mfd/at91-usart.h

-- 
2.17.0

^ permalink raw reply

* Re: [PATCH v1 1/4] soc: Add TmFifo driver for Mellanox BlueField Soc
From: Robin Murphy @ 2018-05-25 17:14 UTC (permalink / raw)
  To: Liming Sun, Olof Johansson, Arnd Bergmann, David Woods
  Cc: devicetree, linux-arm-kernel
In-Reply-To: <b143b40446c1870fb8d422b364ead95d54552be9.1527264077.git.lsun@mellanox.com>

On 25/05/18 17:06, Liming Sun wrote:
[...]
> diff --git a/drivers/soc/mellanox/tmfifo.c b/drivers/soc/mellanox/tmfifo.c
> new file mode 100644
> index 0000000..a3303d1
> --- /dev/null
> +++ b/drivers/soc/mellanox/tmfifo.c
> @@ -0,0 +1,1265 @@
> +// SPDX-License-Identifier: GPL-2.0

This tag doesn't match the included license text...

> +/*
> + * Copyright (c) 2018, Mellanox Technologies. All rights reserved.
> + *
> + * This software is available to you under a choice of one of two
> + * licenses.  You may choose to be licensed under the terms of the GNU
> + * General Public License (GPL) Version 2, available from the file
> + * COPYING in the main directory of this source tree, or the
> + * OpenIB.org BSD license below:
> + *
> + *     Redistribution and use in source and binary forms, with or
> + *     without modification, are permitted provided that the following
> + *     conditions are met:
> + *
> + *      - Redistributions of source code must retain the above
> + *        copyright notice, this list of conditions and the following
> + *        disclaimer.
> + *
> + *      - Redistributions in binary form must reproduce the above
> + *        copyright notice, this list of conditions and the following
> + *        disclaimer in the documentation and/or other materials
> + *        provided with the distribution.
> + *
> + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
> + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
> + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
> + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
> + * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
> + * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
> + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
> + * SOFTWARE.
> + */

[...]
> +/* Several utility macros to get/set the register fields. */
> +#define TMFIFO_GET_FIELD(reg, field) \
> +	(((reg) >> field##_SHIFT) & ((1UL << field##_WIDTH) - 1))
> +
> +#define TMFIFO_SET_FIELD(reg, field, value) ({ \
> +	u64 _mask = ((1UL << field##_WIDTH) - 1) << field##_SHIFT; \
> +	((reg) & ~_mask) | (((value) << field##_SHIFT) & _mask); \
> +})

There's no need to reinvent <linux/bitfield.h>

[...]
> +MODULE_DESCRIPTION("Mellanox BlueField SoC TMFIFO Driver");
> +MODULE_AUTHOR("Mellanox Technologies, Ltd");
> +MODULE_LICENSE("GPL");

...and this implies yet another different license (since it indicates 
"GPLv2 or later")

> +MODULE_VERSION("0.7");
> diff --git a/drivers/soc/mellanox/tmfifo_regs.h b/drivers/soc/mellanox/tmfifo_regs.h
> new file mode 100644
> index 0000000..b07f353
> --- /dev/null
> +++ b/drivers/soc/mellanox/tmfifo_regs.h
> @@ -0,0 +1,112 @@
> +// SPDX-License-Identifier: GPL-2.0

Again, this doesn't match the included text. Also, the SPDX comment 
style is /* */ for headers.

> +/*
> + * Copyright (c) 2018, Mellanox Technologies. All rights reserved.
> + *
> + * This software is available to you under a choice of one of two
> + * licenses.  You may choose to be licensed under the terms of the GNU
> + * General Public License (GPL) Version 2, available from the file
> + * COPYING in the main directory of this source tree, or the
> + * OpenIB.org BSD license below:
> + *
> + *     Redistribution and use in source and binary forms, with or
> + *     without modification, are permitted provided that the following
> + *     conditions are met:
> + *
> + *      - Redistributions of source code must retain the above
> + *        copyright notice, this list of conditions and the following
> + *        disclaimer.
> + *
> + *      - Redistributions in binary form must reproduce the above
> + *        copyright notice, this list of conditions and the following
> + *        disclaimer in the documentation and/or other materials
> + *        provided with the distribution.
> + *
> + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
> + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
> + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
> + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
> + * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
> + * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
> + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
> + * SOFTWARE.
> + */

[...]
> +#ifdef __ASSEMBLER__
> +#define _64bit(x) x
> +#else /* __ASSEMBLER__ */
> +#ifdef __tile__
> +#define _64bit(x) x ## UL
> +#else /* __tile__ */
> +#define _64bit(x) x ## ULL
> +#endif /* __tile__ */
> +#endif /* __ASSEMBLER */
> +
> +#ifdef __KERNEL__
> +#include <linux/types.h>
> +#else
> +#include <stdint.h>
> +#endif
> +
> +#ifndef __DOXYGEN__

Given that this is a private header under drivers/, is any of that lot 
necessary?

Robin.

^ permalink raw reply

* Re: [PATCH] ARM: dts: imx51-zii-rdu1: Make sure SD1_WP is low
From: Andrey Smirnov @ 2018-05-25 16:59 UTC (permalink / raw)
  To: Lucas Stach
  Cc: Shawn Guo, Nikita Yushchenko, Fabio Estevam, Chris Healy,
	Rob Herring, linux-arm-kernel,
	open list:OPEN FIRMWARE AND FLATTENED DEVICE TREE BINDINGS,
	linux-kernel
In-Reply-To: <1527257797.3472.8.camel@pengutronix.de>

On Fri, May 25, 2018 at 7:16 AM, Lucas Stach <l.stach@pengutronix.de> wrote:
> Am Donnerstag, den 24.05.2018, 20:01 -0700 schrieb Andrey Smirnov:
>> Make sure that MX51_PAD_GPIO1_1 does not remain configure as
>> ALT0/SD1_WP (it is out of reset). This is needed because of external
>> pull-up resistor attached to that pad that, when left unchanged, will
>> drive SD1_WP high preventing eSDHC1/eMMC from working correctly.
>>
>> To fix that add a pinmux configuration line configureing the pad to
>> function as a GPIO. While we are at it, add a corresponding input GPIO
>> hog in an effort to minimize current consumption.
>
> Enabling the input part of the pad also consumes (a small amount of)
> power, if you are after minimizing power consumption, better configure
> the pin as output and drive it in the pull direction.
>

Sure, sounds good, will do in v2.

>>
>> > Cc: Nikita Yushchenko <nikita.yoush@cogentembedded.com>
>> > Cc: Shawn Guo <shawnguo@kernel.org>
>> > Cc: Fabio Estevam <fabio.estevam@nxp.com>
>> > Cc: Lucas Stach <l.stach@pengutronix.de>
>> > Cc: Chris Healy <cphealy@gmail.com>
>> > Cc: Rob Herring <robh+dt@kernel.org>
>> Cc: linux-arm-kernel@lists.infradead.org
>> Cc: devicetree@vger.kernel.org
>> Cc: linux-kernel@vger.kernel.org
>> > Signed-off-by: Andrey Smirnov <andrew.smirnov@gmail.com>
>> ---
>>  arch/arm/boot/dts/imx51-zii-rdu1.dts | 28 ++++++++++++++++++++++++++++
>>  1 file changed, 28 insertions(+)
>>
>> diff --git a/arch/arm/boot/dts/imx51-zii-rdu1.dts b/arch/arm/boot/dts/imx51-zii-rdu1.dts
>> index df9eca94d812..d484e7e46b27 100644
>> --- a/arch/arm/boot/dts/imx51-zii-rdu1.dts
>> +++ b/arch/arm/boot/dts/imx51-zii-rdu1.dts
>> @@ -476,6 +476,17 @@
>> >     status = "okay";
>>  };
>>
>> +&gpio1 {
>> > +   unused-sd3-wp-gpio {
>> > +           /*
>> > +            * See pinctrl_esdhc1 below for more details on this
>> > +            */
>> > +           gpio-hog;
>> > +           gpios = <1 GPIO_ACTIVE_HIGH>;
>> > +           input;
>> > +   };
>> +};
>> +
>>  &i2c2 {
>> >     pinctrl-names = "default";
>> >     pinctrl-0 = <&pinctrl_i2c2>;
>> @@ -660,6 +671,23 @@
>> > >                   MX51_PAD_SD1_DATA1__SD1_DATA1           0x20d5
>> > >                   MX51_PAD_SD1_DATA2__SD1_DATA2           0x20d5
>> > >                   MX51_PAD_SD1_DATA3__SD1_DATA3           0x20d5
>> > +                   /*
>> > +                    * GPIO1_1 is not directly used by eSDHC1 in
>> > +                    * any capacity, but earlier versions of RDU1
>> > +                    * used that pin as WP GPIO for eSDHC3 and
>> > +                    * because of that that pad has an external
>> > +                    * pull-up resistor. This is problematic
>> > +                    * because out of reset the pad is configured
>> > +                    * as ALT0 which serves as SD1_WP, which, when
>> > +                    * pulled high by and external pull-up, will
>> > +                    * inhibit execution of any write request to
>> > +                    * attached eMMC device.
>> > +                    *
>> > +                    * To avoid this problem we configure the pad
>> > +                    * to ALT1/GPIO and avoid driving SD1_WP
>> +                      * signal high.
>
> Applying the patch complains about whitespace damage in the above 2
> lines.
>

My bad, sorry about that, will fix in v2.

Thanks,
Andrey Smirnov

^ permalink raw reply

* [PATCH 3/3] arm64: dts: Update Stingray clock DT nodes
From: Ray Jui @ 2018-05-25 16:45 UTC (permalink / raw)
  To: Michael Turquette, Stephen Boyd, Rob Herring, Mark Rutland
  Cc: linux-clk, linux-kernel, bcm-kernel-feedback-list, devicetree,
	linux-arm-kernel, Pramod Kumar, Ray Jui
In-Reply-To: <1527266717-8406-1-git-send-email-ray.jui@broadcom.com>

Update clock output names in the Stingray clock DT nodes so they match
the binding document and the latest ASIC datasheet. Also add entries
for LCPLL2

Signed-off-by: Pramod Kumar <pramod.kumar@broadcom.com>
Signed-off-by: Ray Jui <ray.jui@broadcom.com>
---
 .../boot/dts/broadcom/stingray/stingray-clock.dtsi | 26 ++++++++++++++++------
 1 file changed, 19 insertions(+), 7 deletions(-)

diff --git a/arch/arm64/boot/dts/broadcom/stingray/stingray-clock.dtsi b/arch/arm64/boot/dts/broadcom/stingray/stingray-clock.dtsi
index 3a4d452..10a106a 100644
--- a/arch/arm64/boot/dts/broadcom/stingray/stingray-clock.dtsi
+++ b/arch/arm64/boot/dts/broadcom/stingray/stingray-clock.dtsi
@@ -52,12 +52,24 @@
 			reg = <0x0001d104 0x32>,
 			      <0x0001c854 0x4>;
 			clocks = <&osc>;
-			clock-output-names = "genpll0", "clk_125", "clk_scr",
+			clock-output-names = "genpll0", "clk_125m", "clk_scr",
 					     "clk_250", "clk_pcie_axi",
 					     "clk_paxc_axi_x2",
 					     "clk_paxc_axi";
 		};
 
+		genpll2: genpll2@1d1ac {
+			#clock-cells = <1>;
+			compatible = "brcm,sr-genpll2";
+			reg = <0x0001d1ac 0x32>,
+			      <0x0001c854 0x4>;
+			clocks = <&osc>;
+			clock-output-names = "genpll2", "clk_nic",
+					     "clk_ts_500_ref", "clk_125_nitro",
+					     "clk_chimp", "clk_nic_flash",
+					     "clk_fs";
+		};
+
 		genpll3: genpll3@1d1e0 {
 			#clock-cells = <1>;
 			compatible = "brcm,sr-genpll3";
@@ -75,8 +87,8 @@
 			      <0x0001c854 0x4>;
 			clocks = <&osc>;
 			clock-output-names = "genpll4", "clk_ccn",
-					     "clk_tpiu_pll", "noc_clk",
-					     "pll_chclk_fs4",
+					     "clk_tpiu_pll", "clk_noc",
+					     "clk_chclk_fs4",
 					     "clk_bridge_fscpu";
 		};
 
@@ -86,8 +98,8 @@
 			reg = <0x0001d248 0x32>,
 			      <0x0001c870 0x4>;
 			clocks = <&osc>;
-			clock-output-names = "genpll5", "fs4_hf_clk",
-					     "crypto_ae_clk", "raid_ae_clk";
+			clock-output-names = "genpll5", "clk_fs4_hf",
+					     "clk_crypto_ae", "clk_raid_ae";
 		};
 
 		lcpll0: lcpll0@1d0c4 {
@@ -107,9 +119,9 @@
 			reg = <0x0001d138 0x3c>,
 			      <0x0001c870 0x4>;
 			clocks = <&osc>;
-			clock-output-names = "lcpll1", "clk_wanpn",
+			clock-output-names = "lcpll1", "clk_wan",
 					     "clk_usb_ref",
-					     "timesync_evt_clk";
+					     "clk_crmu_ts";
 		};
 
 		hsls_clk: hsls_clk {
-- 
2.1.4

^ permalink raw reply related


This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox