Devicetree
 help / color / mirror / Atom feed
* Re: [PATCH 6/6] ARM: configs: keystone_defconfig: Enable few peripheral drivers
From: santosh.shilimkar-QHcLZuEGTsvQT0dZR+AlfA @ 2017-12-03  4:00 UTC (permalink / raw)
  To: Vignesh R, Santosh Shilimkar
  Cc: Rob Herring, linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r,
	devicetree-u79uwXL29TY76Z2rM5mHXA,
	linux-kernel-u79uwXL29TY76Z2rM5mHXA
In-Reply-To: <20171123075154.3938-7-vigneshr-l0cyMroinI0@public.gmane.org>

On 11/22/17 11:51 PM, Vignesh R wrote:
> Enable drivers for QSPI, LEDS, gpio-decoder that are present on 66AK2G EVM
> and 66AK2G ICE boards.
> 
> Signed-off-by: Vignesh R <vigneshr-l0cyMroinI0@public.gmane.org>
> ---
Please submit a patch also to enable all these peripherals
in multi-v7 config. Just enable all remainder
options enabled in keystone config also in multi-v7.

Am pushing this series to next now.

Regards,
Santosh
--
To unsubscribe from this list: send the line "unsubscribe devicetree" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

^ permalink raw reply

* Re: [RESEND PATCH 2/4] ARM: dts: keystone: Add generic compatible string for I2C EEPROM
From: santosh.shilimkar @ 2017-12-03  3:57 UTC (permalink / raw)
  To: Javier Martinez Canillas, linux-kernel
  Cc: Mark Rutland, devicetree, arnd, Russell King, Rob Herring, arm,
	Santosh Shilimkar, olof, linux-arm-kernel
In-Reply-To: <20171124162750.18756-2-javierm@redhat.com>

On 11/24/17 8:27 AM, Javier Martinez Canillas wrote:
> The at24 driver allows to register I2C EEPROM chips using different vendor
> and devices, but the I2C subsystem does not take the vendor into account
> when matching using the I2C table since it only has device entries.
> 
> But when matching using an OF table, both the vendor and device has to be
> taken into account so the driver defines only a set of compatible strings
> using the "atmel" vendor as a generic fallback for compatible I2C devices.
> 
> So add this generic fallback to the device node compatible string to make
> the device to match the driver using the OF device ID table.
> 
> Signed-off-by: Javier Martinez Canillas <javierm@redhat.com>
> ---
> 
Applied

^ permalink raw reply

* Re: [PATCH v3] usb: xhci: allow imod-interval to be configurable
From: Chunfeng Yun @ 2017-12-03  3:51 UTC (permalink / raw)
  To: Adam Wallis
  Cc: Greg Kroah-Hartman, Rob Herring, Mark Rutland, Matthias Brugger,
	Mathias Nyman, linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r,
	linux-usb-u79uwXL29TY76Z2rM5mHXA,
	devicetree-u79uwXL29TY76Z2rM5mHXA,
	linux-mediatek-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r,
	timur-sgV2jX0FEOL9JmXXK+q4OQ
In-Reply-To: <1512143059-25674-1-git-send-email-awallis-sgV2jX0FEOL9JmXXK+q4OQ@public.gmane.org>

On Fri, 2017-12-01 at 10:44 -0500, Adam Wallis wrote:
> The xHCI driver currently has the IMOD set to 160, which
> translates to an IMOD interval of 40,000ns (160 * 250)ns
> 
> Commit 0cbd4b34cda9 ("xhci: mediatek: support MTK xHCI host controller")
> introduced a QUIRK for the MTK platform to adjust this interval to 20,
> which translates to an IMOD interval of 5,000ns (20 * 250)ns. This is
> due to the fact that the MTK controller IMOD interval is 8 times
> as much as defined in xHCI spec.
> 
> Instead of adding more quirk bits for additional platforms, this patch
> introduces the ability for vendors to set the IMOD_INTERVAL as is
> optimal for their platform. By using device_property_read_u32() on
> "imod-interval", the IMOD INTERVAL can be specified in nano seconds. If
> no interval is specified, the default of 40,000ns (IMOD=160) will be
> used.
> 
> No bounds checking has been implemented due to the fact that a vendor
> may have violated the spec and would need to specify a value outside of
> the max 8,000 IRQs/second limit specified in the xHCI spec.
> 
> Signed-off-by: Adam Wallis <awallis-sgV2jX0FEOL9JmXXK+q4OQ@public.gmane.org>
> ---
> changes from v2:
>   * Added PCI default value [Mathias]
>   * Removed xhci-mtk.h from xhci-plat.c [Chunfeng Yun]
>   * Removed MTK quirk from xhci-plat and moved logic to xhci-mtk [Chunfeng]
>   * Updated bindings Documentation to use proper units [Rob Herring]
>   * Added imod-interval description and example to MTK binding documentation
> changes from v1:
>   * Removed device_property_read_u32() per suggestion from greg k-h
>   * Used ER_IRQ_INTERVAL_MASK in place of (u16) cast
> 
>  Documentation/devicetree/bindings/usb/mediatek,mtk-xhci.txt | 2 ++
>  Documentation/devicetree/bindings/usb/usb-xhci.txt          | 1 +
>  drivers/usb/host/xhci-mtk.c                                 | 9 +++++++++
>  drivers/usb/host/xhci-pci.c                                 | 3 +++
>  drivers/usb/host/xhci-plat.c                                | 4 ++++
>  drivers/usb/host/xhci.c                                     | 7 ++-----
>  drivers/usb/host/xhci.h                                     | 2 ++
>  7 files changed, 23 insertions(+), 5 deletions(-)
> 
> diff --git a/Documentation/devicetree/bindings/usb/mediatek,mtk-xhci.txt b/Documentation/devicetree/bindings/usb/mediatek,mtk-xhci.txt
> index 3059596..45bbf18 100644
> --- a/Documentation/devicetree/bindings/usb/mediatek,mtk-xhci.txt
> +++ b/Documentation/devicetree/bindings/usb/mediatek,mtk-xhci.txt
> @@ -46,6 +46,7 @@ Optional properties:
>   - pinctrl-names : a pinctrl state named "default" must be defined
>   - pinctrl-0 : pin control group
>  	See: Documentation/devicetree/bindings/pinctrl/pinctrl-bindings.txt
> + - imod-interval: Default interval is 5000ns
>  
>  Example:
>  usb30: usb@11270000 {
> @@ -66,6 +67,7 @@ usb30: usb@11270000 {
>  	usb3-lpm-capable;
>  	mediatek,syscon-wakeup = <&pericfg>;
>  	mediatek,wakeup-src = <1>;
> +	imod-interval = <10000>;
>  };
>  
>  2nd: dual-role mode with xHCI driver
> diff --git a/Documentation/devicetree/bindings/usb/usb-xhci.txt b/Documentation/devicetree/bindings/usb/usb-xhci.txt
> index ae6e484..89b68f1 100644
> --- a/Documentation/devicetree/bindings/usb/usb-xhci.txt
> +++ b/Documentation/devicetree/bindings/usb/usb-xhci.txt
> @@ -29,6 +29,7 @@ Optional properties:
>    - usb2-lpm-disable: indicate if we don't want to enable USB2 HW LPM
>    - usb3-lpm-capable: determines if platform is USB3 LPM capable
>    - quirk-broken-port-ped: set if the controller has broken port disable mechanism
> +  - imod-interval: Default interval is 40000ns
>  
>  Example:
>  	usb@f0931000 {
> diff --git a/drivers/usb/host/xhci-mtk.c b/drivers/usb/host/xhci-mtk.c
> index b62a1d2..278ea3b 100644
> --- a/drivers/usb/host/xhci-mtk.c
> +++ b/drivers/usb/host/xhci-mtk.c
> @@ -674,6 +674,15 @@ static int xhci_mtk_probe(struct platform_device *pdev)
>  
>  	xhci = hcd_to_xhci(hcd);
>  	xhci->main_hcd = hcd;
> +
> +	/*
> +	 * imod_interval is the interrupt modulation value in nanoseconds.
> +	 * The increment interval is 8 times as much as that defined in
> +	 * the xHCI spec on MTK's controller.
> +	 */
> +	xhci->imod_interval = 5000;
> +	device_property_read_u32(dev, "imod-interval", &xhci->imod_interval);
> +
>  	xhci->shared_hcd = usb_create_shared_hcd(driver, dev,
>  			dev_name(dev), hcd);
>  	if (!xhci->shared_hcd) {
> diff --git a/drivers/usb/host/xhci-pci.c b/drivers/usb/host/xhci-pci.c
> index 7ef1274..efbe57b 100644
> --- a/drivers/usb/host/xhci-pci.c
> +++ b/drivers/usb/host/xhci-pci.c
> @@ -234,6 +234,9 @@ static int xhci_pci_setup(struct usb_hcd *hcd)
>  	if (!xhci->sbrn)
>  		pci_read_config_byte(pdev, XHCI_SBRN_OFFSET, &xhci->sbrn);
>  
> +	/* imod_interval is the interrupt modulation value in nanoseconds. */
> +	xhci->imod_interval = 40000;
> +
>  	retval = xhci_gen_setup(hcd, xhci_pci_quirks);
>  	if (retval)
>  		return retval;
> diff --git a/drivers/usb/host/xhci-plat.c b/drivers/usb/host/xhci-plat.c
> index 09f164f..b78be87 100644
> --- a/drivers/usb/host/xhci-plat.c
> +++ b/drivers/usb/host/xhci-plat.c
> @@ -269,6 +269,10 @@ static int xhci_plat_probe(struct platform_device *pdev)
>  	if (device_property_read_bool(&pdev->dev, "quirk-broken-port-ped"))
>  		xhci->quirks |= XHCI_BROKEN_PORT_PED;
>  
> +	/* imod_interval is the interrupt modulation value in nanoseconds. */
> +	xhci->imod_interval = 40000;
> +	device_property_read_u32(sysdev, "imod-interval", &xhci->imod_interval);
> +
>  	hcd->usb_phy = devm_usb_get_phy_by_phandle(sysdev, "usb-phy", 0);
>  	if (IS_ERR(hcd->usb_phy)) {
>  		ret = PTR_ERR(hcd->usb_phy);
> diff --git a/drivers/usb/host/xhci.c b/drivers/usb/host/xhci.c
> index 2424d30..0b7755b 100644
> --- a/drivers/usb/host/xhci.c
> +++ b/drivers/usb/host/xhci.c
> @@ -586,11 +586,8 @@ int xhci_run(struct usb_hcd *hcd)
>  			"// Set the interrupt modulation register");
>  	temp = readl(&xhci->ir_set->irq_control);
>  	temp &= ~ER_IRQ_INTERVAL_MASK;
> -	/*
> -	 * the increment interval is 8 times as much as that defined
> -	 * in xHCI spec on MTK's controller
> -	 */
> -	temp |= (u32) ((xhci->quirks & XHCI_MTK_HOST) ? 20 : 160);
> +	temp |= (xhci->imod_interval / 250) & ER_IRQ_INTERVAL_MASK;
> +
>  	writel(temp, &xhci->ir_set->irq_control);
>  
>  	/* Set the HCD state before we enable the irqs */
> diff --git a/drivers/usb/host/xhci.h b/drivers/usb/host/xhci.h
> index 99a014a..2a4177b 100644
> --- a/drivers/usb/host/xhci.h
> +++ b/drivers/usb/host/xhci.h
> @@ -1717,6 +1717,8 @@ struct xhci_hcd {
>  	u8		max_interrupters;
>  	u8		max_ports;
>  	u8		isoc_threshold;
> +	/* imod_interval in ns (I * 250ns) */
> +	u32		imod_interval;
>  	int		event_ring_max;
>  	/* 4KB min, 128MB max */
>  	int		page_size;

Tested-by: Chunfeng Yun <chunfeng.yun-NuS5LvNUpcJWk0Htik3J/w@public.gmane.org>

Thanks



--
To unsubscribe from this list: send the line "unsubscribe devicetree" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

^ permalink raw reply

* Re: [PATCH net-next v4 2/2] net: ethernet: socionext: add AVE ethernet driver
From: kbuild test robot @ 2017-12-03  3:37 UTC (permalink / raw)
  Cc: kbuild-all-JC7UmRfGjtg, netdev-u79uwXL29TY76Z2rM5mHXA,
	Andrew Lunn, Florian Fainelli, Rob Herring, Mark Rutland,
	linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r,
	linux-kernel-u79uwXL29TY76Z2rM5mHXA,
	devicetree-u79uwXL29TY76Z2rM5mHXA, Masahiro Yamada,
	Masami Hiramatsu, Jassi Brar, Kunihiko Hayashi
In-Reply-To: <1512090230-27594-3-git-send-email-hayashi.kunihiko-uWyLwvC0a2jby3iVrkZq2A@public.gmane.org>

[-- Attachment #1: Type: text/plain, Size: 1523 bytes --]

Hi Kunihiko,

Thank you for the patch! Perhaps something to improve:

[auto build test WARNING on net-next/master]

url:    https://github.com/0day-ci/linux/commits/Kunihiko-Hayashi/dt-bindings-net-add-DT-bindings-for-Socionext-UniPhier-AVE/20171203-095248
config: alpha-allyesconfig (attached as .config)
compiler: alpha-linux-gnu-gcc (Debian 7.2.0-11) 7.2.0
reproduce:
        wget https://raw.githubusercontent.com/intel/lkp-tests/master/sbin/make.cross -O ~/bin/make.cross
        chmod +x ~/bin/make.cross
        # save the attached .config to linux build tree
        make.cross ARCH=alpha 

All warnings (new ones prefixed by >>):

   drivers/net/ethernet/socionext/sni_ave.c: In function 'ave_pfsel_set_promisc':
>> drivers/net/ethernet/socionext/sni_ave.c:172:27: warning: large integer implicitly truncated to unsigned type [-Woverflow]
    #define AVE_PFMBYTE_MASK0 (~GENMASK(7, 6))
                              ^
>> drivers/net/ethernet/socionext/sni_ave.c:1046:9: note: in expansion of macro 'AVE_PFMBYTE_MASK0'
     writel(AVE_PFMBYTE_MASK0, priv->base + AVE_PFMBYTE(entry));
            ^~~~~~~~~~~~~~~~~

vim +172 drivers/net/ethernet/socionext/sni_ave.c

   170	
   171	/* Packet filter */
 > 172	#define AVE_PFMBYTE_MASK0	(~GENMASK(7, 6))
   173	#define AVE_PFMBYTE_MASK1	GENMASK(25, 0)
   174	#define AVE_PFMBIT_MASK		GENMASK(15, 0)
   175	

---
0-DAY kernel test infrastructure                Open Source Technology Center
https://lists.01.org/pipermail/kbuild-all                   Intel Corporation

[-- Attachment #2: .config.gz --]
[-- Type: application/gzip, Size: 52634 bytes --]

^ permalink raw reply

* Re: [PATCH v3] usb: xhci: allow imod-interval to be configurable
From: Chunfeng Yun @ 2017-12-03  3:22 UTC (permalink / raw)
  To: Adam Wallis
  Cc: Greg Kroah-Hartman, Rob Herring, Mark Rutland, Matthias Brugger,
	Mathias Nyman, linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r,
	linux-usb-u79uwXL29TY76Z2rM5mHXA,
	devicetree-u79uwXL29TY76Z2rM5mHXA,
	linux-mediatek-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r,
	timur-sgV2jX0FEOL9JmXXK+q4OQ
In-Reply-To: <1512143059-25674-1-git-send-email-awallis-sgV2jX0FEOL9JmXXK+q4OQ@public.gmane.org>

On Fri, 2017-12-01 at 10:44 -0500, Adam Wallis wrote:
> The xHCI driver currently has the IMOD set to 160, which
> translates to an IMOD interval of 40,000ns (160 * 250)ns
> 
> Commit 0cbd4b34cda9 ("xhci: mediatek: support MTK xHCI host controller")
> introduced a QUIRK for the MTK platform to adjust this interval to 20,
> which translates to an IMOD interval of 5,000ns (20 * 250)ns. This is
> due to the fact that the MTK controller IMOD interval is 8 times
> as much as defined in xHCI spec.
> 
> Instead of adding more quirk bits for additional platforms, this patch
> introduces the ability for vendors to set the IMOD_INTERVAL as is
> optimal for their platform. By using device_property_read_u32() on
> "imod-interval", the IMOD INTERVAL can be specified in nano seconds. If
> no interval is specified, the default of 40,000ns (IMOD=160) will be
> used.
> 
> No bounds checking has been implemented due to the fact that a vendor
> may have violated the spec and would need to specify a value outside of
> the max 8,000 IRQs/second limit specified in the xHCI spec.
> 
> Signed-off-by: Adam Wallis <awallis-sgV2jX0FEOL9JmXXK+q4OQ@public.gmane.org>
> ---
> changes from v2:
>   * Added PCI default value [Mathias]
>   * Removed xhci-mtk.h from xhci-plat.c [Chunfeng Yun]
>   * Removed MTK quirk from xhci-plat and moved logic to xhci-mtk [Chunfeng]
>   * Updated bindings Documentation to use proper units [Rob Herring]
>   * Added imod-interval description and example to MTK binding documentation
> changes from v1:
>   * Removed device_property_read_u32() per suggestion from greg k-h
>   * Used ER_IRQ_INTERVAL_MASK in place of (u16) cast
> 
>  Documentation/devicetree/bindings/usb/mediatek,mtk-xhci.txt | 2 ++
>  Documentation/devicetree/bindings/usb/usb-xhci.txt          | 1 +
>  drivers/usb/host/xhci-mtk.c                                 | 9 +++++++++
>  drivers/usb/host/xhci-pci.c                                 | 3 +++
>  drivers/usb/host/xhci-plat.c                                | 4 ++++
>  drivers/usb/host/xhci.c                                     | 7 ++-----
>  drivers/usb/host/xhci.h                                     | 2 ++
>  7 files changed, 23 insertions(+), 5 deletions(-)
> 
> diff --git a/Documentation/devicetree/bindings/usb/mediatek,mtk-xhci.txt b/Documentation/devicetree/bindings/usb/mediatek,mtk-xhci.txt
> index 3059596..45bbf18 100644
> --- a/Documentation/devicetree/bindings/usb/mediatek,mtk-xhci.txt
> +++ b/Documentation/devicetree/bindings/usb/mediatek,mtk-xhci.txt
> @@ -46,6 +46,7 @@ Optional properties:
>   - pinctrl-names : a pinctrl state named "default" must be defined
>   - pinctrl-0 : pin control group
>  	See: Documentation/devicetree/bindings/pinctrl/pinctrl-bindings.txt
> + - imod-interval: Default interval is 5000ns
I think, as Rob suggested before, recommend to have a unit suffix
appended to the property name.
s/imod-interval/imod-interval-ns
 
>  
>  Example:
>  usb30: usb@11270000 {
> @@ -66,6 +67,7 @@ usb30: usb@11270000 {
>  	usb3-lpm-capable;
>  	mediatek,syscon-wakeup = <&pericfg>;
>  	mediatek,wakeup-src = <1>;
> +	imod-interval = <10000>;
>  };
>  
>  2nd: dual-role mode with xHCI driver
> diff --git a/Documentation/devicetree/bindings/usb/usb-xhci.txt b/Documentation/devicetree/bindings/usb/usb-xhci.txt
> index ae6e484..89b68f1 100644
> --- a/Documentation/devicetree/bindings/usb/usb-xhci.txt
> +++ b/Documentation/devicetree/bindings/usb/usb-xhci.txt
> @@ -29,6 +29,7 @@ Optional properties:
>    - usb2-lpm-disable: indicate if we don't want to enable USB2 HW LPM
>    - usb3-lpm-capable: determines if platform is USB3 LPM capable
>    - quirk-broken-port-ped: set if the controller has broken port disable mechanism
> +  - imod-interval: Default interval is 40000ns
>  
>  Example:
>  	usb@f0931000 {
> diff --git a/drivers/usb/host/xhci-mtk.c b/drivers/usb/host/xhci-mtk.c
> index b62a1d2..278ea3b 100644
> --- a/drivers/usb/host/xhci-mtk.c
> +++ b/drivers/usb/host/xhci-mtk.c
> @@ -674,6 +674,15 @@ static int xhci_mtk_probe(struct platform_device *pdev)
>  
>  	xhci = hcd_to_xhci(hcd);
>  	xhci->main_hcd = hcd;
> +
> +	/*
> +	 * imod_interval is the interrupt modulation value in nanoseconds.
> +	 * The increment interval is 8 times as much as that defined in
> +	 * the xHCI spec on MTK's controller.
> +	 */
> +	xhci->imod_interval = 5000;
> +	device_property_read_u32(dev, "imod-interval", &xhci->imod_interval);
> +
>  	xhci->shared_hcd = usb_create_shared_hcd(driver, dev,
>  			dev_name(dev), hcd);
>  	if (!xhci->shared_hcd) {
> diff --git a/drivers/usb/host/xhci-pci.c b/drivers/usb/host/xhci-pci.c
> index 7ef1274..efbe57b 100644
> --- a/drivers/usb/host/xhci-pci.c
> +++ b/drivers/usb/host/xhci-pci.c
> @@ -234,6 +234,9 @@ static int xhci_pci_setup(struct usb_hcd *hcd)
>  	if (!xhci->sbrn)
>  		pci_read_config_byte(pdev, XHCI_SBRN_OFFSET, &xhci->sbrn);
>  
> +	/* imod_interval is the interrupt modulation value in nanoseconds. */
> +	xhci->imod_interval = 40000;
> +
>  	retval = xhci_gen_setup(hcd, xhci_pci_quirks);
>  	if (retval)
>  		return retval;
> diff --git a/drivers/usb/host/xhci-plat.c b/drivers/usb/host/xhci-plat.c
> index 09f164f..b78be87 100644
> --- a/drivers/usb/host/xhci-plat.c
> +++ b/drivers/usb/host/xhci-plat.c
> @@ -269,6 +269,10 @@ static int xhci_plat_probe(struct platform_device *pdev)
>  	if (device_property_read_bool(&pdev->dev, "quirk-broken-port-ped"))
>  		xhci->quirks |= XHCI_BROKEN_PORT_PED;
>  
> +	/* imod_interval is the interrupt modulation value in nanoseconds. */
> +	xhci->imod_interval = 40000;
> +	device_property_read_u32(sysdev, "imod-interval", &xhci->imod_interval);
> +
>  	hcd->usb_phy = devm_usb_get_phy_by_phandle(sysdev, "usb-phy", 0);
>  	if (IS_ERR(hcd->usb_phy)) {
>  		ret = PTR_ERR(hcd->usb_phy);
> diff --git a/drivers/usb/host/xhci.c b/drivers/usb/host/xhci.c
> index 2424d30..0b7755b 100644
> --- a/drivers/usb/host/xhci.c
> +++ b/drivers/usb/host/xhci.c
> @@ -586,11 +586,8 @@ int xhci_run(struct usb_hcd *hcd)
>  			"// Set the interrupt modulation register");
>  	temp = readl(&xhci->ir_set->irq_control);
>  	temp &= ~ER_IRQ_INTERVAL_MASK;
> -	/*
> -	 * the increment interval is 8 times as much as that defined
> -	 * in xHCI spec on MTK's controller
> -	 */
> -	temp |= (u32) ((xhci->quirks & XHCI_MTK_HOST) ? 20 : 160);
> +	temp |= (xhci->imod_interval / 250) & ER_IRQ_INTERVAL_MASK;
> +
>  	writel(temp, &xhci->ir_set->irq_control);
>  
>  	/* Set the HCD state before we enable the irqs */
> diff --git a/drivers/usb/host/xhci.h b/drivers/usb/host/xhci.h
> index 99a014a..2a4177b 100644
> --- a/drivers/usb/host/xhci.h
> +++ b/drivers/usb/host/xhci.h
> @@ -1717,6 +1717,8 @@ struct xhci_hcd {
>  	u8		max_interrupters;
>  	u8		max_ports;
>  	u8		isoc_threshold;
> +	/* imod_interval in ns (I * 250ns) */
> +	u32		imod_interval;
>  	int		event_ring_max;
>  	/* 4KB min, 128MB max */
>  	int		page_size;


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

^ permalink raw reply

* Re: [PATCH 3/6] arm: dts: marvell: Add missing #phy-cells to usb-nop-xceiv
From: Olof Johansson @ 2017-12-03  0:49 UTC (permalink / raw)
  To: Andrew Lunn
  Cc: Rob Herring, devicetree-u79uwXL29TY76Z2rM5mHXA,
	linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r,
	arm-DgEjT+Ai2ygdnm+yROfE0A, Jason Cooper, Gregory Clement,
	Sebastian Hesselbarth
In-Reply-To: <20171121205622.GE30040-g2DYL2Zd6BY@public.gmane.org>

On Tue, Nov 21, 2017 at 09:56:22PM +0100, Andrew Lunn wrote:
> On Thu, Nov 09, 2017 at 04:26:11PM -0600, Rob Herring wrote:
> > "usb-nop-xceiv" is using the phy binding, but is missing #phy-cells
> > property. This is probably because the binding was the precursor to the phy
> > binding.
> > 
> > Fixes the following warning in Marvell dts files:
> > 
> > Warning (phys_property): Missing property '#phy-cells' in node ...
> > 
> > Signed-off-by: Rob Herring <robh-DgEjT+Ai2ygdnm+yROfE0A@public.gmane.org>
> 
> Reviewed-by: Andrew Lunn <andrew-g2DYL2Zd6BY@public.gmane.org>

I didn't see this come in before -rc1 and in current fixes, so given the acks
I've applied it directly now.


-Olof
--
To unsubscribe from this list: send the line "unsubscribe devicetree" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

^ permalink raw reply

* Re: [PATCH] arm64: dts: sort vendor subdirectories in Makefile alphabetically
From: Olof Johansson @ 2017-12-03  0:28 UTC (permalink / raw)
  To: Masahiro Yamada
  Cc: arm, Arnd Bergmann, devicetree, linux-kernel, Rob Herring,
	Will Deacon, Mark Rutland, Catalin Marinas, linux-arm-kernel
In-Reply-To: <1510974603-7463-1-git-send-email-yamada.masahiro@socionext.com>

On Sat, Nov 18, 2017 at 12:10:03PM +0900, Masahiro Yamada wrote:
> The list is almost sorted.  Move "lg" up to complete it.
> 
> Signed-off-by: Masahiro Yamada <yamada.masahiro@socionext.com>

Applied to fixes, thanks.


-Olof

^ permalink raw reply

* Re: [alsa-devel] [PATCH 1/2] dt-bindings: trivial: add tfa9879 device
From: Fabio Estevam @ 2017-12-02 21:17 UTC (permalink / raw)
  To: Peter Rosin
  Cc: linux-kernel, Mark Rutland,
	devicetree-u79uwXL29TY76Z2rM5mHXA@public.gmane.org,
	alsa-devel-K7yf7f+aM1XWsZ/bQMPhNw@public.gmane.org, Liam Girdwood,
	Mark Brown, Takashi Iwai, Nicolas Ferre, Russell King,
	Rob Herring, Alexandre Belloni,
	linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r@public.gmane.org
In-Reply-To: <20171201224425.5477-2-peda-koto5C5qi+TLoDKTGw+V6w@public.gmane.org>

On Fri, Dec 1, 2017 at 8:44 PM, Peter Rosin <peda-koto5C5qi+TLoDKTGw+V6w@public.gmane.org> wrote:
> Add record for NXP TFA9879 Mono BTL Class D audio amplifier.
>
> Signed-off-by: Peter Rosin <peda-koto5C5qi+TLoDKTGw+V6w@public.gmane.org>
> ---
>  Documentation/devicetree/bindings/trivial-devices.txt | 1 +
>  1 file changed, 1 insertion(+)
>
> diff --git a/Documentation/devicetree/bindings/trivial-devices.txt b/Documentation/devicetree/bindings/trivial-devices.txt
> index af284fbd4d23..4cf30ce4e71f 100644
> --- a/Documentation/devicetree/bindings/trivial-devices.txt
> +++ b/Documentation/devicetree/bindings/trivial-devices.txt
> @@ -157,6 +157,7 @@ nxp,pcf2127         Real-time clock
>  nxp,pcf2129            Real-time clock
>  nxp,pcf8563            Real-time clock/calendar
>  nxp,pcf85063           Tiny Real-Time Clock
> +nxp,tfa9879            Mono BTL Class D audio amplifier

This is already described at Documentation/devicetree/bindings/sound/tfa9879.txt
--
To unsubscribe from this list: send the line "unsubscribe devicetree" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

^ permalink raw reply

* Re: [PATCH 14/17] ARM: dts: Add missing gpu node and binding for omap4
From: Tony Lindgren @ 2017-12-02 17:00 UTC (permalink / raw)
  To: Adam Ford
  Cc: Rob Herring, linux-omap-u79uwXL29TY76Z2rM5mHXA,
	Benoît Cousson, devicetree-u79uwXL29TY76Z2rM5mHXA,
	Mark Rutland, Tomi Valkeinen
In-Reply-To: <CAHCN7xL81vq+eUX_mPr7jrxTMBygqLST15okF5hipQDAP0j2PQ-JsoAwUIsXosN+BqQ9rBEUg@public.gmane.org>

* Adam Ford <aford173-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org> [171202 00:20]:
> On Mon, Sep 11, 2017 at 4:50 PM, Rob Herring <robh-DgEjT+Ai2ygdnm+yROfE0A@public.gmane.org> wrote:
> > On Wed, Aug 30, 2017 at 08:19:50AM -0700, Tony Lindgren wrote:
> >> On omap4 we're missing the PowerVR SGX GPU node with it's related
> >> "ti,hwmods" property that the SoC interconnect code needs.
> >>
> >> Note that this will only show up as a bug with "doesn't have
> >> mpu register target base" boot errors when the legacy platform
> >> data is removed.
> >>
> >> Cc: Mark Rutland <mark.rutland-5wv7dgnIgG8@public.gmane.org>
> >> Cc: Rob Herring <robh+dt-DgEjT+Ai2ygdnm+yROfE0A@public.gmane.org>
> >> Cc: Tomi Valkeinen <tomi.valkeinen-l0cyMroinI0@public.gmane.org>
> >> Signed-off-by: Tony Lindgren <tony-4v6yS6AI5VpBDgjK7y7TUQ@public.gmane.org>
> >> ---
> 
> Out of curiosity, is anything being done with this?  I'm really
> interested to see the PVR working in a modern kernel.  I'd like to
> help more, but I am afraid I don't fully understand the interconnects
> and how the driver componenets interact with the omap processor.
> 
> Please let me know if there are sub-tasks that I can assist.

Well the powervr node should use a powervr generic binding that
does not yet exist. I think the TI tree binding could be easily
modified for a generic binding. So first doing a binding patch
for powervr and Cc dt list and SoC maintainers with powervr on
them would help.

And then eventually the powervr generic node should be a child
node under the "target-module" node in the dtsi file. See what
we have for gpu target-module@56000000 in omap4.dtsi.

Note that the interconnect target module does not yet work for
omap3 as the clocks are different. I'll be posting patches for
the clocks over next few weeks.

Regards,

Tony
--
To unsubscribe from this list: send the line "unsubscribe devicetree" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

^ permalink raw reply

* Re: [PATCH v2 22/35] nds32: Device tree support
From: Greentime Hu @ 2017-12-02 16:47 UTC (permalink / raw)
  To: Rob Herring
  Cc: Greentime, linux-kernel-u79uwXL29TY76Z2rM5mHXA@public.gmane.org,
	Arnd Bergmann, linux-arch-u79uwXL29TY76Z2rM5mHXA@public.gmane.org,
	Thomas Gleixner, Jason Cooper, Marc Zyngier, netdev, Vincent Chen,
	devicetree-u79uwXL29TY76Z2rM5mHXA@public.gmane.org, Al Viro,
	David Howells, Will Deacon, Daniel Lezcano,
	linux-serial-u79uwXL29TY76Z2rM5mHXA@public.gmane.org,
	Vincent Chen
In-Reply-To: <CAL_Jsq+c4vt4-royBuTxAj+AY2wFHMugyyy41S5YP-QXyF2gbQ-JsoAwUIsXosN+BqQ9rBEUg@public.gmane.org>

2017-11-28 3:07 GMT+08:00 Rob Herring <robh+dt-DgEjT+Ai2ygdnm+yROfE0A@public.gmane.org>:
> On Mon, Nov 27, 2017 at 6:28 AM, Greentime Hu <green.hu-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org> wrote:
>> From: Greentime Hu <greentime-MUIXKm3Oiri1Z/+hSey0Gg@public.gmane.org>
>>
>> This patch adds support for device tree.
>>
>> Signed-off-by: Vincent Chen <vincentc-MUIXKm3Oiri1Z/+hSey0Gg@public.gmane.org>
>> Signed-off-by: Greentime Hu <greentime-MUIXKm3Oiri1Z/+hSey0Gg@public.gmane.org>
>> ---
>>  arch/nds32/boot/dts/Makefile   |    8 ++++++
>>  arch/nds32/boot/dts/ae3xx.dts  |   55 ++++++++++++++++++++++++++++++++++++
>>  arch/nds32/boot/dts/ag101p.dts |   60 ++++++++++++++++++++++++++++++++++++++++
>>  arch/nds32/kernel/devtree.c    |   45 ++++++++++++++++++++++++++++++
>>  4 files changed, 168 insertions(+)
>>  create mode 100644 arch/nds32/boot/dts/Makefile
>>  create mode 100644 arch/nds32/boot/dts/ae3xx.dts
>>  create mode 100644 arch/nds32/boot/dts/ag101p.dts
>>  create mode 100644 arch/nds32/kernel/devtree.c
>>
>> diff --git a/arch/nds32/boot/dts/Makefile b/arch/nds32/boot/dts/Makefile
>> new file mode 100644
>> index 0000000..d31faa8
>> --- /dev/null
>> +++ b/arch/nds32/boot/dts/Makefile
>> @@ -0,0 +1,8 @@
>> +ifneq '$(CONFIG_NDS32_BUILTIN_DTB)' '""'
>
> Built-in dtb's are really for legacy bootloader cases where the
> bootloader doesn't understand dtbs. Do you have that here?
>
> Plus, I don't see any code here to handle the built-in dtb.

As you mentioned in the next thread, it is handled in head.S
We would like to keep it because we debug kernel through gdb without
bootloader very often.

>> +BUILTIN_DTB := $(patsubst "%",%,$(CONFIG_NDS32_BUILTIN_DTB)).dtb.o
>> +else
>> +BUILTIN_DTB :=
>> +endif
>> +obj-$(CONFIG_OF) += $(BUILTIN_DTB)
>> +
>> +clean-files := *.dtb *.dtb.S
>> diff --git a/arch/nds32/boot/dts/ae3xx.dts b/arch/nds32/boot/dts/ae3xx.dts
>> new file mode 100644
>> index 0000000..4181060
>> --- /dev/null
>> +++ b/arch/nds32/boot/dts/ae3xx.dts
>> @@ -0,0 +1,55 @@
>> +/dts-v1/;
>> +/ {
>> +       compatible = "nds32 ae3xx";
>
> This compatible needs to be documented and is not valid. Needs to be
> in the form "vendor,board-name" without spaces.

Sorry I forgot to check this.
I will provide a document in bindings like
"Documentation/devicetree/bindings/nds32/andestech-boards".

>> +       #address-cells = <1>;
>> +       #size-cells = <1>;
>> +       interrupt-parent = <&intc>;
>> +
>> +       chosen {
>> +               bootargs = "earlycon console=ttyS0,38400n8 debug loglevel=7";
>> +               stdout-path = &serial0;
>> +       };
>> +
>> +       memory@0 {
>> +               device_type = "memory";
>> +               reg = <0x00000000 0x40000000>;
>> +       };
>> +
>> +       cpu {
>> +               device_type = "cpu";
>> +               compatible = "andestech,n13", "andestech,nds32v3";
>> +               clock-frequency = <60000000>;
>> +       };
>> +
>> +       intc: interrupt-controller {
>> +               compatible = "andestech,ativic32";
>> +               #interrupt-cells = <1>;
>> +               interrupt-controller;
>> +       };
>> +
>> +       serial0: serial@f0300000 {
>> +               compatible = "andestech,uart16550", "ns16550a";
>> +               reg = <0xf0300000 0x1000>;
>> +               interrupts = <8>;
>> +               clock-frequency = <14745600>;
>> +               reg-shift = <2>;
>> +               reg-offset = <32>;
>> +               no-loopback-test = <1>;
>> +       };
>> +
>> +       timer0: timer@f0400000 {
>> +               compatible = "andestech,atcpit100";
>> +               reg = <0xf0400000 0x1000>;
>> +               interrupts = <2>;
>> +               clock-frequency = <30000000>;
>> +               cycle-count-offset = <0x38>;
>> +               cycle-count-down;
>> +       };
>> +
>> +       mac0: mac@e0100000 {
>
> ethernet@...
>
>> +               compatible = "andestech,atmac100";
>> +               reg = <0xe0100000 0x1000>;
>> +               interrupts = <18>;
>> +       };
>> +
>> +};
>> diff --git a/arch/nds32/boot/dts/ag101p.dts b/arch/nds32/boot/dts/ag101p.dts
>> new file mode 100644
>> index 0000000..f1cb540
>> --- /dev/null
>> +++ b/arch/nds32/boot/dts/ag101p.dts
>> @@ -0,0 +1,60 @@
>> +/dts-v1/;
>> +/ {
>> +       compatible = "nds32 ag101p";
>
> Same here.

Sorry I forgot to check this.
I will provide a document in bindings like
"Documentation/devicetree/bindings/nds32/andestech-boards".

>> +       #address-cells = <1>;
>> +       #size-cells = <1>;
>> +       interrupt-parent = <&intc>;
>> +
>> +       chosen {
>> +               bootargs = "earlycon console=ttyS0,38400n8 debug loglevel=7";
>> +               stdout-path = &serial0;
>> +       };
>> +
>> +       memory@0 {
>> +               device_type = "memory";
>> +               reg = <0x00000000 0x40000000>;
>> +       };
>> +
>> +       cpu@0 {
>> +               device_type = "cpu";
>> +               compatible = "andestech,n13";
>> +               clock-frequency = <60000000>;
>> +               next-level-cache = <&L2>;
>> +       };
>> +
>> +       intc: interrupt-controller {
>> +               compatible = "andestech,ativic32";
>> +               #interrupt-cells = <2>;
>> +               interrupt-controller;
>> +       };
>> +
>> +       serial0: serial@99600000 {
>> +               compatible = "andestech,uart16550", "ns16550a";
>> +               reg = <0x99600000 0x1000>;
>> +               interrupts = <7 4>;
>> +               clock-frequency = <14745600>;
>> +               reg-shift = <2>;
>> +               no-loopback-test = <1>;
>> +       };
>> +
>> +       timer0: timer@98400000 {
>> +               compatible = "andestech,atftmr010";
>> +               reg = <0x98400000 0x1000>;
>> +               interrupts = <19 4>;
>> +               clock-frequency = <15000000>;
>> +               cycle-count-offset = <0x20>;
>> +       };
>> +
>> +       mac0: mac@90900000 {
>> +               compatible = "andestech,atmac100";
>> +               reg = <0x90900000 0x1000>;
>> +               interrupts = <25 4>;
>> +       };
>> +
>> +       L2: l2-cache {
>> +               compatible = "andestech,atl2c";
>> +               reg = <0x90f00000 0x1000>;
>> +               cache-unified;
>> +               cache-level = <2>;
>> +       };
>> +};
>> diff --git a/arch/nds32/kernel/devtree.c b/arch/nds32/kernel/devtree.c
>> new file mode 100644
>> index 0000000..2af0f1c
>> --- /dev/null
>> +++ b/arch/nds32/kernel/devtree.c
>> @@ -0,0 +1,45 @@
>> +/*
>> + * Copyright (C) 2005-2017 Andes Technology Corporation
>> + *
>> + * 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.
>> + *
>> + * This program is distributed in the hope that it will be useful,
>> + * but WITHOUT ANY WARRANTY; without even the implied warranty of
>> + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
>> + * GNU General Public License for more details.
>> + *
>> + * You should have received a copy of the GNU General Public License
>> + * along with this program.  If not, see <http://www.gnu.org/licenses/>.
>> + */
>> +
>> +#include <linux/memblock.h>
>> +#include <linux/of_fdt.h>
>> +#include <linux/bootmem.h>
>> +
>> +void __init early_init_dt_add_memory_arch(u64 base, u64 size)
>> +{
>> +       size &= PAGE_MASK;
>> +       memblock_add_node(base, size, 0);
>> +}
>> +
>> +void *__init early_init_dt_alloc_memory_arch(u64 size, u64 align)
>> +{
>> +       return alloc_bootmem_align(size, align);
>> +}
>
> You should be able to use the default functions for these 2.

Thanks. I will remove these 2 functions to use default ones.

>> +
>> +void __init early_init_devtree(void *params)
>> +{
>> +       if (!params || !early_init_dt_scan(params)) {
>> +               pr_crit("\n"
>> +                       "Error: invalid device tree blob at (virtual address 0x%p)\n"
>> +                       "The dtb must be 8-byte aligned and must not exceed 8 KB in size\n"
>
> Why the size limit? That's pretty small for a DT.

Thanks. I will update it in the next version patch.

>> +                       "\nPlease check your bootloader.", params);
>> +
>> +               while (true)
>> +                       cpu_relax();
>
> Might as well use BUG_ON here if you're not going to continue. It's
> generally better to WARN and continue on otherwise the messages aren't
> visible until the console is up. However, if you have DT errors this
> early, there's not much you can really do here.

Yup. Maybe we shall hang in here for user to know he use a wrong DT.
I will change it to BUG_ON(1).

>> +       }
>> +
>> +       dump_stack_set_arch_desc("%s (DT)", of_flat_dt_get_machine_name());
>> +}
>> --
>> 1.7.9.5
>>
--
To unsubscribe from this list: send the line "unsubscribe devicetree" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

^ permalink raw reply

* Re: [PATCH v4 00/10] add pinmuxing support for pins in AXP209 and AXP813 PMICs
From: Linus Walleij @ 2017-12-02 16:00 UTC (permalink / raw)
  To: Quentin Schulz
  Cc: Rob Herring, Mark Rutland, Chen-Yu Tsai, Russell King,
	Maxime Ripard, Lee Jones, linux-gpio,
	open list:OPEN FIRMWARE AND FLATTENED DEVICE TREE BINDINGS,
	linux-kernel@vger.kernel.org, Linux ARM, Thomas Petazzoni,
	linux-sunxi
In-Reply-To: <cover.3ff63fdf302c6bda02ea7d160ad2aa5afee0899d.1512135804.git-series.quentin.schulz@free-electrons.com>

On Fri, Dec 1, 2017 at 2:44 PM, Quentin Schulz
<quentin.schulz@free-electrons.com> wrote:

> The AXP209 and AXP813 PMICs have several pins (respectively 3 and 2) that can
> be used either as GPIOs or for other purposes (ADC or LDO here).
>
> We already have a GPIO driver for the GPIO use of those pins on the AXP209.
> Let's "upgrade" this driver to support all the functions these pins can have.
>
> Then we add support to this driver for the AXP813 which is slighlty different
> (basically a different offset in two registers and one less pin).
>
> I suggest patches 1 to 8 go through Linus's tree and 9 and 10 via Maxime or
> Chen-Yu's tree.
>
> v4:

Looks overall good. As soon as Maxime is happy with everything I will
happily apply 1-8 to the pinctrl tree and then pull it to GPIO as well to
avoid clashes.

I think there were some minor comments but it seems almost finished.

Yours,
Linus Walleij

^ permalink raw reply

* Re: [PATCH v4 09/10] ARM: dtsi: axp81x: add GPIO DT node
From: Linus Walleij @ 2017-12-02 15:58 UTC (permalink / raw)
  To: Quentin Schulz
  Cc: Rob Herring, Mark Rutland, Chen-Yu Tsai, Russell King,
	Maxime Ripard, Lee Jones, linux-gpio-u79uwXL29TY76Z2rM5mHXA,
	open list:OPEN FIRMWARE AND FLATTENED DEVICE TREE BINDINGS,
	linux-kernel-u79uwXL29TY76Z2rM5mHXA@public.gmane.org, Linux ARM,
	Thomas Petazzoni, linux-sunxi
In-Reply-To: <af90c57ebf97c8f5504a4b5b1dad3638bedadfef.1512135804.git-series.quentin.schulz-wi1+55ScJUtKEb57/3fJTNBPR1lH4CV8@public.gmane.org>

On Fri, Dec 1, 2017 at 2:44 PM, Quentin Schulz
<quentin.schulz-wi1+55ScJUtKEb57/3fJTNBPR1lH4CV8@public.gmane.org> wrote:

> This adds DT node for the GPIO/pinctrl part present in AXP813/AXP818.
>
> Signed-off-by: Quentin Schulz <quentin.schulz-wi1+55ScJUtKEb57/3fJTNBPR1lH4CV8@public.gmane.org>

Acked-by: Linus Walleij <linus.walleij-QSEj5FYQhm4dnm+yROfE0A@public.gmane.org>

Please apply this through ARM SoC.

Yours,
Linus Walleij

^ permalink raw reply

* Re: [PATCH v4 08/10] mfd: axp20x: add pinctrl cell for AXP813
From: Linus Walleij @ 2017-12-02 15:57 UTC (permalink / raw)
  To: Quentin Schulz, Lee Jones
  Cc: Rob Herring, Mark Rutland, Chen-Yu Tsai, Russell King,
	Maxime Ripard, linux-gpio-u79uwXL29TY76Z2rM5mHXA,
	open list:OPEN FIRMWARE AND FLATTENED DEVICE TREE BINDINGS,
	linux-kernel-u79uwXL29TY76Z2rM5mHXA@public.gmane.org, Linux ARM,
	Thomas Petazzoni, linux-sunxi
In-Reply-To: <e0b4ce746c052b78f08dff54d0ad7ce7ebc611ab.1512135804.git-series.quentin.schulz-wi1+55ScJUtKEb57/3fJTNBPR1lH4CV8@public.gmane.org>

On Fri, Dec 1, 2017 at 2:44 PM, Quentin Schulz
<quentin.schulz-wi1+55ScJUtKEb57/3fJTNBPR1lH4CV8@public.gmane.org> wrote:

> As GPIO/pinctrl driver now supports AXP813, add a cell for it.
>
> Signed-off-by: Quentin Schulz <quentin.schulz-wi1+55ScJUtKEb57/3fJTNBPR1lH4CV8@public.gmane.org>
> Acked-by: Maxime Ripard <maxime.ripard-wi1+55ScJUtKEb57/3fJTNBPR1lH4CV8@public.gmane.org>

Acked-by: Linus Walleij <linus.walleij-QSEj5FYQhm4dnm+yROfE0A@public.gmane.org>

It doesn't seem to have any dependencies so I guess Lee can simply
apply this separately.

Yours,
Linus Walleij

^ permalink raw reply

* Re: [PATCH v4 03/10] dt-bindings: gpio: gpio-axp209: add pinctrl features
From: Linus Walleij @ 2017-12-02 15:55 UTC (permalink / raw)
  To: Quentin Schulz
  Cc: Rob Herring, Mark Rutland, Chen-Yu Tsai, Russell King,
	Maxime Ripard, Lee Jones, linux-gpio-u79uwXL29TY76Z2rM5mHXA,
	open list:OPEN FIRMWARE AND FLATTENED DEVICE TREE BINDINGS,
	linux-kernel-u79uwXL29TY76Z2rM5mHXA@public.gmane.org, Linux ARM,
	Thomas Petazzoni, linux-sunxi
In-Reply-To: <7fdc42fd2d3572069292ebe1376bb446beb4d8a9.1512135804.git-series.quentin.schulz-wi1+55ScJUtKEb57/3fJTNBPR1lH4CV8@public.gmane.org>

On Fri, Dec 1, 2017 at 2:44 PM, Quentin Schulz
<quentin.schulz-wi1+55ScJUtKEb57/3fJTNBPR1lH4CV8@public.gmane.org> wrote:

> The X-Powers AXP209 has 3 GPIOs. GPIO0/1 can each act either as a GPIO,
> an ADC or a LDO regulator. GPIO2 can only act as a GPIO.
>
> This adds the pinctrl features to the driver so GPIO0/1 can be used as
> ADC or LDO regulator.
>
> Signed-off-by: Quentin Schulz <quentin.schulz-wi1+55ScJUtKEb57/3fJTNBPR1lH4CV8@public.gmane.org>
> Acked-by: Rob Herring <robh-DgEjT+Ai2ygdnm+yROfE0A@public.gmane.org>

Please add a reference to the generic pinctrl bindings and state that you
use them and how.

pinctrl/pinctrl-bindings.txt

> +The GPIOs can be muxed to other functions and therefore, must be a subnode of
> +axp_gpio.
> +
> +Example:
> +
> +&axp_gpio {
> +       gpio0_adc: gpio0-adc {
> +               pins = "GPIO0";
> +               function = "adc";
> +       };
> +};

So write explicitly that this driver employs the per-pin muxing pattern.

Yours,
Linus Walleij

^ permalink raw reply

* Re: [PATCH] dt-bindings: pinctrl: uniphier: add UniPhier pinctrl binding
From: Linus Walleij @ 2017-12-02 15:32 UTC (permalink / raw)
  To: Masahiro Yamada
  Cc: linux-gpio, Mauro Carvalho Chehab,
	open list:OPEN FIRMWARE AND FLATTENED DEVICE TREE BINDINGS,
	Randy Dunlap, linux-kernel@vger.kernel.org, David S. Miller,
	Rob Herring, Greg Kroah-Hartman, Mark Rutland, Linux ARM
In-Reply-To: <1511855386-10421-1-git-send-email-yamada.masahiro@socionext.com>

On Tue, Nov 28, 2017 at 8:49 AM, Masahiro Yamada
<yamada.masahiro@socionext.com> wrote:

> The driver has been in the tree for a while, but its binding document
> is missing.  Hence, here it is.
>
> Signed-off-by: Masahiro Yamada <yamada.masahiro@socionext.com>

Patch applied with Rob's ACK.

Yours,
Linus Walleij

^ permalink raw reply

* Re: [PATCH v2 3/4] ARM: dts: koelsch: Convert to named i2c-gpio bindings
From: Linus Walleij @ 2017-12-02 15:26 UTC (permalink / raw)
  To: Geert Uytterhoeven
  Cc: Simon Horman, Magnus Damm, Wolfram Sang, Linux-Renesas, Linux ARM,
	linux-i2c,
	open list:OPEN FIRMWARE AND FLATTENED DEVICE TREE BINDINGS
In-Reply-To: <1512046646-15253-4-git-send-email-geert+renesas@glider.be>

On Thu, Nov 30, 2017 at 1:57 PM, Geert Uytterhoeven
<geert+renesas@glider.be> wrote:

> Commits 7d29f509d2cfd807 ("dt-bindings: i2c: i2c-gpio: Add support for
> named gpios") and 05c74778858d7d99 ("i2c: gpio: Add support for named
> gpios in DT") introduced named i2c-gpio DT bindings, and deprecated the
> more error-prone unnamed variant.
>
> Switch to the new bindings, and add the missing GPIO_OPEN_DRAIN I/O
> flags, which were implicitly assumed before.
>
> Signed-off-by: Geert Uytterhoeven <geert+renesas@glider.be>

Reviewed-by: Linus Walleij <linus.walleij@linaro.org>

Yours,
Linus Walleij

^ permalink raw reply

* Re: [PATCH v2 1/4] ARM: dts: armadillo800eva: Convert to named i2c-gpio bindings
From: Linus Walleij @ 2017-12-02 15:26 UTC (permalink / raw)
  To: Geert Uytterhoeven
  Cc: Simon Horman, Magnus Damm, Wolfram Sang, Linux-Renesas, Linux ARM,
	linux-i2c,
	open list:OPEN FIRMWARE AND FLATTENED DEVICE TREE BINDINGS
In-Reply-To: <1512046646-15253-2-git-send-email-geert+renesas@glider.be>

On Thu, Nov 30, 2017 at 1:57 PM, Geert Uytterhoeven
<geert+renesas@glider.be> wrote:

> Commits 7d29f509d2cfd807 ("dt-bindings: i2c: i2c-gpio: Add support for
> named gpios") and 05c74778858d7d99 ("i2c: gpio: Add support for named
> gpios in DT") introduced named i2c-gpio DT bindings, and deprecated the
> more error-prone unnamed variant.
>
> Switch to the new bindings, and add the missing GPIO_OPEN_DRAIN I/O
> flags, which were implicitly assumed before.
>
> The latter gets rid of the message:
>
>     gpio-208 (?): enforced open drain please flag it properly in DT/ACPI DSDT/board file
>     gpio-91 (?): enforced open drain please flag it properly in DT/ACPI DSDT/board file
>
> Signed-off-by: Geert Uytterhoeven <geert+renesas@glider.be>

Reviewed-by: Linus Walleij <linus.walleij@linaro.org>

Yours,
Linus Walleij

^ permalink raw reply

* Re: [PATCH v2 4/4] ARM: dts: alt: Convert to named i2c-gpio bindings
From: Linus Walleij @ 2017-12-02 15:25 UTC (permalink / raw)
  To: Geert Uytterhoeven
  Cc: Simon Horman, Magnus Damm, Wolfram Sang, Linux-Renesas, Linux ARM,
	linux-i2c,
	open list:OPEN FIRMWARE AND FLATTENED DEVICE TREE BINDINGS
In-Reply-To: <1512046646-15253-5-git-send-email-geert+renesas@glider.be>

On Thu, Nov 30, 2017 at 1:57 PM, Geert Uytterhoeven
<geert+renesas@glider.be> wrote:

> Commits 7d29f509d2cfd807 ("dt-bindings: i2c: i2c-gpio: Add support for
> named gpios") and 05c74778858d7d99 ("i2c: gpio: Add support for named
> gpios in DT") introduced named i2c-gpio DT bindings, and deprecated the
> more error-prone unnamed variant.
>
> Switch to the new bindings, and add the missing GPIO_OPEN_DRAIN I/O
> flags, which were implicitly assumed before.
>
> Signed-off-by: Geert Uytterhoeven <geert+renesas@glider.be>

Reviewed-by: Linus Walleij <linus.walleij@linaro.org>

Yours,
Linus Walleij

^ permalink raw reply

* Re: [PATCH v2 2/4] ARM: dts: lager: Convert to named i2c-gpio bindings
From: Linus Walleij @ 2017-12-02 15:25 UTC (permalink / raw)
  To: Geert Uytterhoeven
  Cc: Simon Horman, Magnus Damm, Wolfram Sang, Linux-Renesas, Linux ARM,
	linux-i2c-u79uwXL29TY76Z2rM5mHXA,
	open list:OPEN FIRMWARE AND FLATTENED DEVICE TREE BINDINGS
In-Reply-To: <1512046646-15253-3-git-send-email-geert+renesas-gXvu3+zWzMSzQB+pC5nmwQ@public.gmane.org>

On Thu, Nov 30, 2017 at 1:57 PM, Geert Uytterhoeven
<geert+renesas-gXvu3+zWzMSzQB+pC5nmwQ@public.gmane.org> wrote:

> Commits 7d29f509d2cfd807 ("dt-bindings: i2c: i2c-gpio: Add support for
> named gpios") and 05c74778858d7d99 ("i2c: gpio: Add support for named
> gpios in DT") introduced named i2c-gpio DT bindings, and deprecated the
> more error-prone unnamed variant.
>
> Switch to the new bindings, and add the missing GPIO_OPEN_DRAIN I/O
> flags, which were implicitly assumed before.
>
> Signed-off-by: Geert Uytterhoeven <geert+renesas-gXvu3+zWzMSzQB+pC5nmwQ@public.gmane.org>

Reviewed-by: Linus Walleij <linus.walleij-QSEj5FYQhm4dnm+yROfE0A@public.gmane.org>

Yours,
Linus Walleij
--
To unsubscribe from this list: send the line "unsubscribe devicetree" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

^ permalink raw reply

* Re: [PATCH v4 2/2] gpio: aspeed: Add support for reset tolerance
From: Linus Walleij @ 2017-12-02 15:22 UTC (permalink / raw)
  To: Andrew Jeffery
  Cc: linux-gpio, Rob Herring, Mark Rutland, Frank Rowand, Joel Stanley,
	Charles Keepax, Laxman Dewangan, Ryan Chen,
	linux-kernel@vger.kernel.org,
	open list:OPEN FIRMWARE AND FLATTENED DEVICE TREE BINDINGS,
	OpenBMC Maillist, linux-aspeed
In-Reply-To: <20171130035525.29653-3-andrew@aj.id.au>

On Thu, Nov 30, 2017 at 4:55 AM, Andrew Jeffery <andrew@aj.id.au> wrote:

> Use the new pinconf parameter for state persistence to expose the
> associated capability of the Aspeed GPIO controller.
>
> Signed-off-by: Andrew Jeffery <andrew@aj.id.au>
> Reviewed-by: Joel Stanley <joel@jms.id.au>

Patch applied.

Yours,
Linus Walleij

^ permalink raw reply

* Re: [PATCH v4 1/2] gpio: gpiolib: Generalise state persistence beyond sleep
From: Linus Walleij @ 2017-12-02 15:20 UTC (permalink / raw)
  To: Andrew Jeffery
  Cc: linux-gpio, Rob Herring, Mark Rutland, Frank Rowand, Joel Stanley,
	Charles Keepax, Laxman Dewangan, Ryan Chen,
	linux-kernel@vger.kernel.org,
	open list:OPEN FIRMWARE AND FLATTENED DEVICE TREE BINDINGS,
	OpenBMC Maillist, linux-aspeed
In-Reply-To: <20171130035525.29653-2-andrew@aj.id.au>

On Thu, Nov 30, 2017 at 4:55 AM, Andrew Jeffery <andrew@aj.id.au> wrote:

> General support for state persistence is added to gpiolib with the
> introduction of a new pinconf parameter to propagate the request to
> hardware. The existing persistence support for sleep is adapted to
> include hardware support if the GPIO driver provides it. Persistence
> continues to be enabled by default; in-kernel consumers can opt out, but
> userspace (currently) does not have a choice.
>
> The *_SLEEP_MAY_LOSE_VALUE and *_SLEEP_MAINTAIN_VALUE symbols are
> renamed, dropping the SLEEP prefix to reflect that the concept is no
> longer sleep-specific.  I feel that renaming to just *_MAY_LOSE_VALUE
> could initially be misinterpreted, so I've further changed the symbols
> to *_TRANSITORY and *_PERSISTENT to address this.
>
> The sysfs interface is modified only to keep consistency with the
> chardev interface in enforcing persistence for userspace exports.
>
> Signed-off-by: Andrew Jeffery <andrew@aj.id.au>
> Reviewed-by: Charles Keepax <ckeepax@opensource.cirrus.com>
> Acked-by: Rob Herring <robh@kernel.org>

Nice work, patch applied!

> diff --git a/drivers/gpio/gpiolib-sysfs.c b/drivers/gpio/gpiolib-sysfs.c
> index 3f454eaf2101..0bd472ffb072 100644
> --- a/drivers/gpio/gpiolib-sysfs.c
> +++ b/drivers/gpio/gpiolib-sysfs.c
> @@ -474,11 +474,15 @@ static ssize_t export_store(struct class *class,
>                         status = -ENODEV;
>                 goto done;
>         }
> -       status = gpiod_export(desc, true);
> -       if (status < 0)
> -               gpiod_free(desc);
> -       else
> -               set_bit(FLAG_SYSFS, &desc->flags);
> +
> +       status = gpiod_set_transitory(desc, false);
> +       if (!status) {
> +               status = gpiod_export(desc, true);
> +               if (status < 0)
> +                       gpiod_free(desc);
> +               else
> +                       set_bit(FLAG_SYSFS, &desc->flags);
> +       }

Part of me just wanna drop this hunk of the patch and let
the old sysfs ABI rot.

But I guess that is especially malevolent so I will abstain.


Yours,
Linus Walleij

^ permalink raw reply

* Re: [PATCH v6 13/13] ASoC: stm32: add DFSDM DAI support
From: Jonathan Cameron @ 2017-12-02 15:09 UTC (permalink / raw)
  To: Arnaud Pouliquen
  Cc: Rob Herring, Mark Rutland, Hartmut Knaack, Lars-Peter Clausen,
	Peter Meerwald-Stadler, Jaroslav Kysela, Takashi Iwai,
	Liam Girdwood, Mark Brown, devicetree-u79uwXL29TY76Z2rM5mHXA,
	linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r,
	linux-iio-u79uwXL29TY76Z2rM5mHXA,
	alsa-devel-K7yf7f+aM1XWsZ/bQMPhNw, Maxime Coquelin,
	Alexandre Torgue
In-Reply-To: <1512150020-20335-14-git-send-email-arnaud.pouliquen-qxv4g6HH51o@public.gmane.org>

On Fri, 1 Dec 2017 18:40:20 +0100
Arnaud Pouliquen <arnaud.pouliquen-qxv4g6HH51o@public.gmane.org> wrote:

> Add driver to handle DAI interface for PDM microphones connected
> to Digital Filter for Sigma Delta Modulators IP.
> 
> Signed-off-by: Arnaud Pouliquen <arnaud.pouliquen-qxv4g6HH51o@public.gmane.org>

include tied up with the move of that enum in the earlier patch.
Other than that the IIO stuff looks fine to me.

Mark, given this set is moderately invasive on the IIO side and
should just drop in cleanly on the sound side of things, either
I could take it via IIO or one of us can do an immutable branch
and we take it through both trees.

Don't mind which but if I'm either taking the series or doing
an immutable branch I'll obviously be waiting on your review!

Also need time for Rob to check the updating bindings.

Anyhow, it's coming together reasonably nicely in the end.
Good work Arnaud!

Jonathan
> ---
> V5 to V6 update:
>  fix build warning
>  
>  sound/soc/stm/Kconfig        |  11 ++
>  sound/soc/stm/Makefile       |   3 +
>  sound/soc/stm/stm32_adfsdm.c | 386 +++++++++++++++++++++++++++++++++++++++++++
>  3 files changed, 400 insertions(+)
>  create mode 100644 sound/soc/stm/stm32_adfsdm.c
> 
> diff --git a/sound/soc/stm/Kconfig b/sound/soc/stm/Kconfig
> index 3398e6c..a78f770 100644
> --- a/sound/soc/stm/Kconfig
> +++ b/sound/soc/stm/Kconfig
> @@ -28,4 +28,15 @@ config SND_SOC_STM32_SPDIFRX
>  	help
>  	  Say Y if you want to enable S/PDIF capture for STM32
>  
> +config SND_SOC_STM32_DFSDM
> +	tristate "SoC Audio support for STM32 DFSDM"
> +	depends on (ARCH_STM32 && OF && STM32_DFSDM_ADC) || COMPILE_TEST
> +	depends on SND_SOC
> +	select SND_SOC_GENERIC_DMAENGINE_PCM
> +	select SND_SOC_DMIC
> +	select IIO_BUFFER_CB
> +	help
> +	  Select this option to enable the STM32 Digital Filter
> +	  for Sigma Delta Modulators (DFSDM) driver used
> +	  in various STM32 series for digital microphone capture.
>  endmenu
> diff --git a/sound/soc/stm/Makefile b/sound/soc/stm/Makefile
> index 4ed22e6..53e90e6 100644
> --- a/sound/soc/stm/Makefile
> +++ b/sound/soc/stm/Makefile
> @@ -12,3 +12,6 @@ obj-$(CONFIG_SND_SOC_STM32_I2S) += snd-soc-stm32-i2s.o
>  # SPDIFRX
>  snd-soc-stm32-spdifrx-objs := stm32_spdifrx.o
>  obj-$(CONFIG_SND_SOC_STM32_SPDIFRX) += snd-soc-stm32-spdifrx.o
> +
> +#DFSDM
> +obj-$(CONFIG_SND_SOC_STM32_DFSDM) += stm32_adfsdm.o
> diff --git a/sound/soc/stm/stm32_adfsdm.c b/sound/soc/stm/stm32_adfsdm.c
> new file mode 100644
> index 0000000..890ec24
> --- /dev/null
> +++ b/sound/soc/stm/stm32_adfsdm.c
> @@ -0,0 +1,386 @@
> +/*
> + * This file is part of STM32 DFSDM ASoC DAI driver
> + *
> + * Copyright (C) 2017, STMicroelectronics - All Rights Reserved
> + * Authors: Arnaud Pouliquen <arnaud.pouliquen-qxv4g6HH51o@public.gmane.org>
> + *          Olivier Moysan <olivier.moysan-qxv4g6HH51o@public.gmane.org>
> + *
> + * License terms: GPL V2.0.
> + *
> + * 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.
> + *
> + * This program is distributed in the hope that it will be useful, but
> + * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
> + * or FITNESS FOR A PARTICULAR PURPOSE.
> + * See the GNU General Public License for more details.
> + *
> + * You should have received a copy of the GNU General Public License along with
> + * this program. If not, see <http://www.gnu.org/licenses/>.
> + */
> +
> +#include <linux/clk.h>
> +#include <linux/module.h>
> +#include <linux/platform_device.h>
> +#include <linux/slab.h>
> +
> +#include <linux/iio/iio.h>

I missed this before but a consumer should not need to include iio.h.
I would guess it was about that enum that I want you to move to types.h?

> +#include <linux/iio/consumer.h>
> +#include <linux/iio/adc/stm32-dfsdm-adc.h>
> +
> +#include <sound/pcm.h>
> +#include <sound/soc.h>
> +
> +#define STM32_ADFSDM_DRV_NAME "stm32-adfsdm"
> +
> +#define DFSDM_MAX_PERIOD_SIZE	(PAGE_SIZE / 2)
> +#define DFSDM_MAX_PERIODS	6
> +
> +struct stm32_adfsdm_priv {
> +	struct snd_soc_dai_driver dai_drv;
> +	struct snd_pcm_substream *substream;
> +	struct device *dev;
> +
> +	/* IIO */
> +	struct iio_channel *iio_ch;
> +	struct iio_cb_buffer *iio_cb;
> +	bool iio_active;
> +
> +	/* PCM buffer */
> +	unsigned char *pcm_buff;
> +	unsigned int pos;
> +	bool allocated;
> +};
> +
> +struct stm32_adfsdm_data {
> +	unsigned int rate;	/* SNDRV_PCM_RATE value */
> +	unsigned int freq;	/* frequency in Hz */
> +};
> +
> +static const struct snd_pcm_hardware stm32_adfsdm_pcm_hw = {
> +	.info = SNDRV_PCM_INFO_INTERLEAVED | SNDRV_PCM_INFO_BLOCK_TRANSFER |
> +	    SNDRV_PCM_INFO_PAUSE,
> +	.formats = SNDRV_PCM_FMTBIT_S32_LE,
> +
> +	.rate_min = 8000,
> +	.rate_max = 32000,
> +
> +	.channels_min = 1,
> +	.channels_max = 1,
> +
> +	.periods_min = 2,
> +	.periods_max = DFSDM_MAX_PERIODS,
> +
> +	.period_bytes_max = DFSDM_MAX_PERIOD_SIZE,
> +	.buffer_bytes_max = DFSDM_MAX_PERIODS * DFSDM_MAX_PERIOD_SIZE
> +};
> +
> +static void stm32_adfsdm_shutdown(struct snd_pcm_substream *substream,
> +				  struct snd_soc_dai *dai)
> +{
> +	struct stm32_adfsdm_priv *priv = snd_soc_dai_get_drvdata(dai);
> +
> +	if (priv->iio_active) {
> +		iio_channel_stop_all_cb(priv->iio_cb);
> +		priv->iio_active = false;
> +	}
> +}
> +
> +static int stm32_adfsdm_dai_prepare(struct snd_pcm_substream *substream,
> +				    struct snd_soc_dai *dai)
> +{
> +	struct stm32_adfsdm_priv *priv = snd_soc_dai_get_drvdata(dai);
> +	int ret;
> +
> +	ret = iio_write_channel_attribute(priv->iio_ch,
> +					  substream->runtime->rate, 0,
> +					  IIO_CHAN_INFO_SAMP_FREQ);
> +	if (ret < 0) {
> +		dev_err(dai->dev, "%s: Failed to set %d sampling rate\n",
> +			__func__, substream->runtime->rate);
> +		return ret;
> +	}
> +
> +	if (!priv->iio_active) {
> +		ret = iio_channel_start_all_cb(priv->iio_cb);
> +		if (!ret)
> +			priv->iio_active = true;
> +		else
> +			dev_err(dai->dev, "%s: IIO channel start failed (%d)\n",
> +				__func__, ret);
> +	}
> +
> +	return ret;
> +}
> +
> +static int stm32_adfsdm_set_sysclk(struct snd_soc_dai *dai, int clk_id,
> +				   unsigned int freq, int dir)
> +{
> +	struct stm32_adfsdm_priv *priv = snd_soc_dai_get_drvdata(dai);
> +	ssize_t size;
> +
> +	dev_dbg(dai->dev, "%s: Enter for freq %d\n", __func__, freq);
> +
> +	/* Set IIO frequency if CODEC is master as clock comes from SPI_IN*/
> +	if (dir == SND_SOC_CLOCK_IN) {
> +		char str_freq[10];
> +
> +		snprintf(str_freq, sizeof(str_freq), "%d\n", freq);
> +		size = iio_write_channel_ext_info(priv->iio_ch, "spi_clk_freq",
> +						  str_freq, sizeof(str_freq));
> +		if (size != sizeof(str_freq)) {
> +			dev_err(dai->dev, "%s: Failed to set SPI clock\n",
> +				__func__);
> +			return -EINVAL;
> +		}
> +	}
> +	return 0;
> +}
> +
> +static const struct snd_soc_dai_ops stm32_adfsdm_dai_ops = {
> +	.shutdown = stm32_adfsdm_shutdown,
> +	.prepare = stm32_adfsdm_dai_prepare,
> +	.set_sysclk = stm32_adfsdm_set_sysclk,
> +};
> +
> +static const struct snd_soc_dai_driver stm32_adfsdm_dai = {
> +	.capture = {
> +		    .channels_min = 1,
> +		    .channels_max = 1,
> +		    .formats = SNDRV_PCM_FMTBIT_S32_LE,
> +		    .rates = (SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_16000 |
> +			      SNDRV_PCM_RATE_32000),
> +		    },
> +	.ops = &stm32_adfsdm_dai_ops,
> +};
> +
> +static const struct snd_soc_component_driver stm32_adfsdm_dai_component = {
> +	.name = "stm32_dfsdm_audio",
> +};
> +
> +static int stm32_afsdm_pcm_cb(const void *data, size_t size, void *private)
> +{
> +	struct stm32_adfsdm_priv *priv = private;
> +	struct snd_soc_pcm_runtime *rtd = priv->substream->private_data;
> +	u8 *pcm_buff = priv->pcm_buff;
> +	u8 *src_buff = (u8 *)data;
> +	unsigned int buff_size = snd_pcm_lib_buffer_bytes(priv->substream);
> +	unsigned int period_size = snd_pcm_lib_period_bytes(priv->substream);
> +	unsigned int old_pos = priv->pos;
> +	unsigned int cur_size = size;
> +
> +	dev_dbg(rtd->dev, "%s: buff_add :%p, pos = %d, size = %lu\n",
> +		__func__, &pcm_buff[priv->pos], priv->pos, size);
> +
> +	if ((priv->pos + size) > buff_size) {
> +		memcpy(&pcm_buff[priv->pos], src_buff, buff_size - priv->pos);
> +		cur_size -= buff_size - priv->pos;
> +		priv->pos = 0;
> +	}
> +
> +	memcpy(&pcm_buff[priv->pos], &src_buff[size - cur_size], cur_size);
> +	priv->pos = (priv->pos + cur_size) % buff_size;
> +
> +	if (cur_size != size || (old_pos && (old_pos % period_size < size)))
> +		snd_pcm_period_elapsed(priv->substream);
> +
> +	return 0;
> +}
> +
> +static int stm32_adfsdm_trigger(struct snd_pcm_substream *substream, int cmd)
> +{
> +	struct snd_soc_pcm_runtime *rtd = substream->private_data;
> +	struct stm32_adfsdm_priv *priv =
> +		snd_soc_dai_get_drvdata(rtd->cpu_dai);
> +
> +	switch (cmd) {
> +	case SNDRV_PCM_TRIGGER_START:
> +	case SNDRV_PCM_TRIGGER_RESUME:
> +		priv->pos = 0;
> +		return stm32_dfsdm_get_buff_cb(priv->iio_ch->indio_dev,
> +					stm32_afsdm_pcm_cb, priv);
> +	case SNDRV_PCM_TRIGGER_SUSPEND:
> +	case SNDRV_PCM_TRIGGER_STOP:
> +		return stm32_dfsdm_release_buff_cb(priv->iio_ch->indio_dev);
> +	default:
> +		return -EINVAL;
> +	}
> +
> +	return 0;
> +}
> +
> +static int stm32_adfsdm_pcm_open(struct snd_pcm_substream *substream)
> +{
> +	struct snd_soc_pcm_runtime *rtd = substream->private_data;
> +	struct stm32_adfsdm_priv *priv = snd_soc_dai_get_drvdata(rtd->cpu_dai);
> +	int ret;
> +
> +	ret =  snd_soc_set_runtime_hwparams(substream, &stm32_adfsdm_pcm_hw);
> +	if (!ret)
> +		priv->substream = substream;
> +
> +	return ret;
> +}
> +
> +static int stm32_adfsdm_pcm_close(struct snd_pcm_substream *substream)
> +{
> +	struct snd_soc_pcm_runtime *rtd = substream->private_data;
> +	struct stm32_adfsdm_priv *priv =
> +		snd_soc_dai_get_drvdata(rtd->cpu_dai);
> +
> +	snd_pcm_lib_free_pages(substream);
> +	priv->substream = NULL;
> +
> +	return 0;
> +}
> +
> +static snd_pcm_uframes_t stm32_adfsdm_pcm_pointer(
> +					    struct snd_pcm_substream *substream)
> +{
> +	struct snd_soc_pcm_runtime *rtd = substream->private_data;
> +	struct stm32_adfsdm_priv *priv =
> +		snd_soc_dai_get_drvdata(rtd->cpu_dai);
> +
> +	return bytes_to_frames(substream->runtime, priv->pos);
> +}
> +
> +static int stm32_adfsdm_pcm_hw_params(struct snd_pcm_substream *substream,
> +				      struct snd_pcm_hw_params *params)
> +{
> +	struct snd_soc_pcm_runtime *rtd = substream->private_data;
> +	struct stm32_adfsdm_priv *priv =
> +		snd_soc_dai_get_drvdata(rtd->cpu_dai);
> +	int ret;
> +
> +	ret =  snd_pcm_lib_malloc_pages(substream, params_buffer_bytes(params));
> +	if (ret < 0)
> +		return ret;
> +	priv->pcm_buff = substream->runtime->dma_area;
> +
> +	return iio_channel_cb_set_buffer_watermark(priv->iio_cb,
> +						   params_period_size(params));
> +}
> +
> +static int stm32_adfsdm_pcm_hw_free(struct snd_pcm_substream *substream)
> +{
> +	snd_pcm_lib_free_pages(substream);
> +
> +	return 0;
> +}
> +
> +static struct snd_pcm_ops stm32_adfsdm_pcm_ops = {
> +	.open		= stm32_adfsdm_pcm_open,
> +	.close		= stm32_adfsdm_pcm_close,
> +	.hw_params	= stm32_adfsdm_pcm_hw_params,
> +	.hw_free	= stm32_adfsdm_pcm_hw_free,
> +	.trigger	= stm32_adfsdm_trigger,
> +	.pointer	= stm32_adfsdm_pcm_pointer,
> +};
> +
> +static int stm32_adfsdm_pcm_new(struct snd_soc_pcm_runtime *rtd)
> +{
> +	struct snd_pcm *pcm = rtd->pcm;
> +	struct stm32_adfsdm_priv *priv =
> +		snd_soc_dai_get_drvdata(rtd->cpu_dai);
> +	unsigned int size = DFSDM_MAX_PERIODS * DFSDM_MAX_PERIOD_SIZE;
> +	int ret;
> +
> +	/*
> +	 * FIXME :
> +	 * A platform as been registered per DAI.
> +	 * In soc_new_pcm function, pcm_new callback is called for each
> +	 * component of the sound card. So if n dai links are created this
> +	 * function is called n times.
> +	 */
> +	if (priv->allocated)
> +		return 0;
> +
> +	ret = snd_pcm_lib_preallocate_pages_for_all(pcm, SNDRV_DMA_TYPE_DEV,
> +						    priv->dev, size, size);
> +	if (!ret)
> +		priv->allocated = true;
> +
> +	return ret;
> +}
> +
> +static void stm32_adfsdm_pcm_free(struct snd_pcm *pcm)
> +{
> +	struct snd_pcm_substream *substream;
> +	struct snd_soc_pcm_runtime *rtd;
> +	struct stm32_adfsdm_priv *priv;
> +
> +	substream = pcm->streams[SNDRV_PCM_STREAM_CAPTURE].substream;
> +	if (substream) {
> +		rtd = substream->private_data;
> +		priv = snd_soc_dai_get_drvdata(rtd->cpu_dai);
> +
> +		snd_pcm_lib_preallocate_free_for_all(pcm);
> +		priv->allocated = false;
> +	}
> +}
> +
> +static struct snd_soc_platform_driver stm32_adfsdm_soc_platform = {
> +	.ops		= &stm32_adfsdm_pcm_ops,
> +	.pcm_new	= stm32_adfsdm_pcm_new,
> +	.pcm_free	= stm32_adfsdm_pcm_free,
> +};
> +
> +static const struct of_device_id stm32_adfsdm_of_match[] = {
> +	{.compatible = "st,stm32h7-dfsdm-dai"},
> +	{}
> +};
> +MODULE_DEVICE_TABLE(of, stm32_adfsdm_of_match);
> +
> +static int stm32_adfsdm_probe(struct platform_device *pdev)
> +{
> +	struct stm32_adfsdm_priv *priv;
> +	int ret;
> +
> +	priv = devm_kzalloc(&pdev->dev, sizeof(*priv), GFP_KERNEL);
> +	if (!priv)
> +		return -ENOMEM;
> +
> +	priv->dev = &pdev->dev;
> +	priv->dai_drv = stm32_adfsdm_dai;
> +
> +	dev_set_drvdata(&pdev->dev, priv);
> +
> +	ret = devm_snd_soc_register_component(&pdev->dev,
> +					      &stm32_adfsdm_dai_component,
> +					      &priv->dai_drv, 1);
> +	if (ret < 0)
> +		return ret;
> +
> +	/* Associate iio channel */
> +	priv->iio_ch  = devm_iio_channel_get_all(&pdev->dev);
> +	if (IS_ERR(priv->iio_ch))
> +		return PTR_ERR(priv->iio_ch);
> +
> +	priv->iio_cb = iio_channel_get_all_cb(&pdev->dev, NULL, NULL);
> +	if (IS_ERR(priv->iio_cb))
> +		return PTR_ERR(priv->iio_ch);
> +
> +	ret = devm_snd_soc_register_platform(&pdev->dev,
> +					     &stm32_adfsdm_soc_platform);
> +	if (ret < 0)
> +		dev_err(&pdev->dev, "%s: Failed to register PCM platform\n",
> +			__func__);
> +
> +	return ret;
> +}
> +
> +static struct platform_driver stm32_adfsdm_driver = {
> +	.driver = {
> +		   .name = STM32_ADFSDM_DRV_NAME,
> +		   .of_match_table = stm32_adfsdm_of_match,
> +		   },
> +	.probe = stm32_adfsdm_probe,
> +};
> +
> +module_platform_driver(stm32_adfsdm_driver);
> +
> +MODULE_DESCRIPTION("stm32 DFSDM DAI driver");
> +MODULE_AUTHOR("Arnaud Pouliquen <arnaud.pouliquen-qxv4g6HH51o@public.gmane.org>");
> +MODULE_LICENSE("GPL v2");
> +MODULE_ALIAS("platform:" STM32_ADFSDM_DRV_NAME);

--
To unsubscribe from this list: send the line "unsubscribe devicetree" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

^ permalink raw reply

* Re: [PATCH v6 09/13] IIO: ADC: add STM32 DFSDM sigma delta ADC support
From: Jonathan Cameron @ 2017-12-02 14:58 UTC (permalink / raw)
  To: Arnaud Pouliquen
  Cc: Rob Herring, Mark Rutland, Hartmut Knaack, Lars-Peter Clausen,
	Peter Meerwald-Stadler, Jaroslav Kysela, Takashi Iwai,
	Liam Girdwood, Mark Brown, devicetree-u79uwXL29TY76Z2rM5mHXA,
	linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r,
	linux-iio-u79uwXL29TY76Z2rM5mHXA,
	alsa-devel-K7yf7f+aM1XWsZ/bQMPhNw, Maxime Coquelin,
	Alexandre Torgue
In-Reply-To: <1512150020-20335-10-git-send-email-arnaud.pouliquen-qxv4g6HH51o@public.gmane.org>

On Fri, 1 Dec 2017 18:40:16 +0100
Arnaud Pouliquen <arnaud.pouliquen-qxv4g6HH51o@public.gmane.org> wrote:

> Add DFSDM driver to handle sigma delta ADC.
> 
> Signed-off-by: Arnaud Pouliquen <arnaud.pouliquen-qxv4g6HH51o@public.gmane.org>

A couple of really small nitpicks if you are respinning.

Reviewed-by: Jonathan Cameron <Jonathan.Cameron-hv44wF8Li93QT0dZR+AlfA@public.gmane.org>

> ---
>  drivers/iio/adc/Kconfig           |  13 +
>  drivers/iio/adc/Makefile          |   1 +
>  drivers/iio/adc/stm32-dfsdm-adc.c | 741 ++++++++++++++++++++++++++++++++++++++
>  3 files changed, 755 insertions(+)
>  create mode 100644 drivers/iio/adc/stm32-dfsdm-adc.c
> 
> diff --git a/drivers/iio/adc/Kconfig b/drivers/iio/adc/Kconfig
> index b729ae0..98ca30b 100644
> --- a/drivers/iio/adc/Kconfig
> +++ b/drivers/iio/adc/Kconfig
> @@ -677,6 +677,19 @@ config STM32_DFSDM_CORE
>  	  This driver can also be built as a module.  If so, the module
>  	  will be called stm32-dfsdm-core.
>  
> +config STM32_DFSDM_ADC
> +	tristate "STMicroelectronics STM32 dfsdm adc"
> +	depends on (ARCH_STM32 && OF) || COMPILE_TEST
> +	select STM32_DFSDM_CORE
> +	select REGMAP_MMIO
> +	select IIO_BUFFER_HW_CONSUMER
> +	help
> +	  Select this option to support ADCSigma delta modulator for
> +	  STMicroelectronics STM32 digital filter for sigma delta converter.
> +
> +	  This driver can also be built as a module.  If so, the module
> +	  will be called stm32-dfsdm-adc.
> +
>  config STX104
>  	tristate "Apex Embedded Systems STX104 driver"
>  	depends on PC104 && X86 && ISA_BUS_API
> diff --git a/drivers/iio/adc/Makefile b/drivers/iio/adc/Makefile
> index b52d0a0..c4f5d15 100644
> --- a/drivers/iio/adc/Makefile
> +++ b/drivers/iio/adc/Makefile
> @@ -64,6 +64,7 @@ obj-$(CONFIG_SUN4I_GPADC) += sun4i-gpadc-iio.o
>  obj-$(CONFIG_STM32_ADC_CORE) += stm32-adc-core.o
>  obj-$(CONFIG_STM32_ADC) += stm32-adc.o
>  obj-$(CONFIG_STM32_DFSDM_CORE) += stm32-dfsdm-core.o
> +obj-$(CONFIG_STM32_DFSDM_ADC) += stm32-dfsdm-adc.o
>  obj-$(CONFIG_TI_ADC081C) += ti-adc081c.o
>  obj-$(CONFIG_TI_ADC0832) += ti-adc0832.o
>  obj-$(CONFIG_TI_ADC084S021) += ti-adc084s021.o
> diff --git a/drivers/iio/adc/stm32-dfsdm-adc.c b/drivers/iio/adc/stm32-dfsdm-adc.c
> new file mode 100644
> index 0000000..f9419ab
> --- /dev/null
> +++ b/drivers/iio/adc/stm32-dfsdm-adc.c
> @@ -0,0 +1,741 @@
> +/*
> + * This file is the ADC part of the STM32 DFSDM driver
> + *
> + * Copyright (C) 2017, STMicroelectronics - All Rights Reserved
> + * Author: Arnaud Pouliquen <arnaud.pouliquen-qxv4g6HH51o@public.gmane.org>.
> + *
> + * License type: GPL V2.0.
> + *
> + * 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.
> + *
> + * This program is distributed in the hope that it will be useful, but
> + * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
> + * or FITNESS FOR A PARTICULAR PURPOSE.
> + * See the GNU General Public License for more details.
> + *
> + * You should have received a copy of the GNU General Public License along with
> + * this program. If not, see <http://www.gnu.org/licenses/>.
> + */
> +
> +#include <linux/interrupt.h>
> +#include <linux/iio/buffer.h>
> +#include <linux/iio/hw-consumer.h>
> +#include <linux/iio/iio.h>
> +#include <linux/iio/sysfs.h>
> +#include <linux/module.h>
> +#include <linux/of.h>
> +#include <linux/platform_device.h>
> +#include <linux/regmap.h>
> +#include <linux/slab.h>
> +
> +#include "stm32-dfsdm.h"
> +
> +/* Conversion timeout */
> +#define DFSDM_TIMEOUT_US 100000
> +#define DFSDM_TIMEOUT (msecs_to_jiffies(DFSDM_TIMEOUT_US / 1000))
> +
> +/* Oversampling attribute default */
> +#define DFSDM_DEFAULT_OVERSAMPLING  100
> +
> +/* Oversampling max values */
> +#define DFSDM_MAX_INT_OVERSAMPLING 256
> +#define DFSDM_MAX_FL_OVERSAMPLING 1024
> +
> +/* Max sample resolutions */
> +#define DFSDM_MAX_RES BIT(31)
> +#define DFSDM_DATA_RES BIT(23)
> +
> +enum sd_converter_type {
> +	DFSDM_AUDIO,
> +	DFSDM_IIO,
> +};
> +
> +struct stm32_dfsdm_dev_data {
> +	int type;
> +	int (*init)(struct iio_dev *indio_dev);
> +	unsigned int num_channels;
> +	const struct regmap_config *regmap_cfg;
> +};
> +
> +struct stm32_dfsdm_adc {
> +	struct stm32_dfsdm *dfsdm;
> +	const struct stm32_dfsdm_dev_data *dev_data;
> +	unsigned int fl_id;
> +	unsigned int ch_id;
> +
> +	/* ADC specific */
> +	unsigned int oversamp;
> +	struct iio_hw_consumer *hwc;
> +	struct completion completion;
> +	u32 *buffer;
> +
> +};
> +
> +struct stm32_dfsdm_str2field {
> +	const char	*name;
> +	unsigned int	val;
> +};
> +
> +/* DFSDM channel serial interface type */
> +static const struct stm32_dfsdm_str2field stm32_dfsdm_chan_type[] = {
> +	{ "SPI_R", 0 }, /* SPI with data on rising edge */
> +	{ "SPI_F", 1 }, /* SPI with data on falling edge */
> +	{ "MANCH_R", 2 }, /* Manchester codec, rising edge = logic 0 */
> +	{ "MANCH_F", 3 }, /* Manchester codec, falling edge = logic 1 */
> +	{},
> +};
> +
> +/* DFSDM channel clock source */
> +static const struct stm32_dfsdm_str2field stm32_dfsdm_chan_src[] = {
> +	/* External SPI clock (CLKIN x) */
> +	{ "CLKIN", DFSDM_CHANNEL_SPI_CLOCK_EXTERNAL },
> +	/* Internal SPI clock (CLKOUT) */
> +	{ "CLKOUT", DFSDM_CHANNEL_SPI_CLOCK_INTERNAL },
> +	/* Internal SPI clock divided by 2 (falling edge) */
> +	{ "CLKOUT_F", DFSDM_CHANNEL_SPI_CLOCK_INTERNAL_DIV2_FALLING },
> +	/* Internal SPI clock divided by 2 (falling edge) */
> +	{ "CLKOUT_R", DFSDM_CHANNEL_SPI_CLOCK_INTERNAL_DIV2_RISING },
> +	{},
> +};
> +
> +static int stm32_dfsdm_str2val(const char *str,
> +			       const struct stm32_dfsdm_str2field *list)
> +{
> +	const struct stm32_dfsdm_str2field *p = list;
> +
> +	for (p = list; p && p->name; p++)
> +		if (!strcmp(p->name, str))
> +			return p->val;
> +
> +	return -EINVAL;
> +}
> +
> +static int stm32_dfsdm_set_osrs(struct stm32_dfsdm_filter *fl,
> +				unsigned int fast, unsigned int oversamp)
> +{
> +	unsigned int i, d, fosr, iosr;
> +	u64 res;
> +	s64 delta;
> +	unsigned int m = 1;	/* multiplication factor */
> +	unsigned int p = fl->ford;	/* filter order (ford) */
> +
> +	pr_debug("%s: Requested oversampling: %d\n",  __func__, oversamp);
> +	/*
> +	 * This function tries to compute filter oversampling and integrator
> +	 * oversampling, base on oversampling ratio requested by user.
> +	 *
> +	 * Decimation d depends on the filter order and the oversampling ratios.
> +	 * ford: filter order
> +	 * fosr: filter over sampling ratio
> +	 * iosr: integrator over sampling ratio
> +	 */
> +	if (fl->ford == DFSDM_FASTSINC_ORDER) {
> +		m = 2;
> +		p = 2;
> +	}
> +
> +	/*
> +	 * Look for filter and integrator oversampling ratios which allows
> +	 * to reach 24 bits data output resolution.
> +	 * Leave as soon as if exact resolution if reached.
> +	 * Otherwise the higher resolution below 32 bits is kept.
> +	 */
> +	for (fosr = 1; fosr <= DFSDM_MAX_FL_OVERSAMPLING; fosr++) {
> +		for (iosr = 1; iosr <= DFSDM_MAX_INT_OVERSAMPLING; iosr++) {
> +			if (fast)
> +				d = fosr * iosr;
> +			else if (fl->ford == DFSDM_FASTSINC_ORDER)
> +				d = fosr * (iosr + 3) + 2;
> +			else
> +				d = fosr * (iosr - 1 + p) + p;
> +
> +			if (d > oversamp)
> +				break;
> +			else if (d != oversamp)
> +				continue;
> +			/*
> +			 * Check resolution (limited to signed 32 bits)
> +			 *   res <= 2^31
> +			 * Sincx filters:
> +			 *   res = m * fosr^p x iosr (with m=1, p=ford)
> +			 * FastSinc filter
> +			 *   res = m * fosr^p x iosr (with m=2, p=2)
> +			 */
> +			res = fosr;
> +			for (i = p - 1; i > 0; i--) {
> +				res = res * (u64)fosr;
> +				if (res > DFSDM_MAX_RES)
> +					break;
> +			}
> +			if (res > DFSDM_MAX_RES)
> +				continue;
> +			res = res * (u64)m * (u64)iosr;
> +			if (res > DFSDM_MAX_RES)
> +				continue;
> +
> +			delta = res - DFSDM_DATA_RES;
> +
> +			if (res >= fl->res) {
> +				fl->res = res;
> +				fl->fosr = fosr;
> +				fl->iosr = iosr;
> +				fl->fast = fast;
> +				pr_debug("%s: fosr = %d, iosr = %d\n",
> +					 __func__, fl->fosr, fl->iosr);
> +			}
> +
> +			if (!delta)
> +				return 0;
> +		}
> +	}
> +
> +	if (!fl->fosr)
> +		return -EINVAL;
> +
> +	return 0;
> +}
> +
> +static int stm32_dfsdm_start_channel(struct stm32_dfsdm *dfsdm,
> +				     unsigned int ch_id)
> +{
> +	return regmap_update_bits(dfsdm->regmap, DFSDM_CHCFGR1(ch_id),
> +				  DFSDM_CHCFGR1_CHEN_MASK,
> +				  DFSDM_CHCFGR1_CHEN(1));
> +}
> +
> +static void stm32_dfsdm_stop_channel(struct stm32_dfsdm *dfsdm,
> +				     unsigned int ch_id)
> +{
> +	regmap_update_bits(dfsdm->regmap, DFSDM_CHCFGR1(ch_id),
> +			   DFSDM_CHCFGR1_CHEN_MASK, DFSDM_CHCFGR1_CHEN(0));
> +}
> +
> +static int stm32_dfsdm_chan_configure(struct stm32_dfsdm *dfsdm,
> +				      struct stm32_dfsdm_channel *ch)
> +{
> +	unsigned int id = ch->id;
> +	struct regmap *regmap = dfsdm->regmap;
> +	int ret;
> +
> +	ret = regmap_update_bits(regmap, DFSDM_CHCFGR1(id),
> +				 DFSDM_CHCFGR1_SITP_MASK,
> +				 DFSDM_CHCFGR1_SITP(ch->type));
> +	if (ret < 0)
> +		return ret;
> +	ret = regmap_update_bits(regmap, DFSDM_CHCFGR1(id),
> +				 DFSDM_CHCFGR1_SPICKSEL_MASK,
> +				 DFSDM_CHCFGR1_SPICKSEL(ch->src));
> +	if (ret < 0)
> +		return ret;
> +	return regmap_update_bits(regmap, DFSDM_CHCFGR1(id),
> +				  DFSDM_CHCFGR1_CHINSEL_MASK,
> +				  DFSDM_CHCFGR1_CHINSEL(ch->alt_si));
> +}
> +
> +static int stm32_dfsdm_start_filter(struct stm32_dfsdm *dfsdm,
> +				    unsigned int fl_id)
> +{
> +	int ret;
> +
> +	/* Enable filter */
> +	ret = regmap_update_bits(dfsdm->regmap, DFSDM_CR1(fl_id),
> +				 DFSDM_CR1_DFEN_MASK, DFSDM_CR1_DFEN(1));
> +	if (ret < 0)
> +		return ret;
> +
> +	/* Start conversion */
> +	return regmap_update_bits(dfsdm->regmap, DFSDM_CR1(fl_id),
> +				  DFSDM_CR1_RSWSTART_MASK,
> +				  DFSDM_CR1_RSWSTART(1));
> +}
> +
> +void stm32_dfsdm_stop_filter(struct stm32_dfsdm *dfsdm, unsigned int fl_id)
> +{
> +	/* Disable conversion */
> +	regmap_update_bits(dfsdm->regmap, DFSDM_CR1(fl_id),
> +			   DFSDM_CR1_DFEN_MASK, DFSDM_CR1_DFEN(0));
> +}
> +
> +static int stm32_dfsdm_filter_configure(struct stm32_dfsdm *dfsdm,
> +					unsigned int fl_id, unsigned int ch_id)
> +{
> +	struct regmap *regmap = dfsdm->regmap;
> +	struct stm32_dfsdm_filter *fl = &dfsdm->fl_list[fl_id];
> +	int ret;
> +
> +	/* Average integrator oversampling */
> +	ret = regmap_update_bits(regmap, DFSDM_FCR(fl_id), DFSDM_FCR_IOSR_MASK,
> +				 DFSDM_FCR_IOSR(fl->iosr - 1));
> +	if (ret)
> +		return ret;
> +
> +	/* Filter order and Oversampling */
> +	ret = regmap_update_bits(regmap, DFSDM_FCR(fl_id), DFSDM_FCR_FOSR_MASK,
> +				 DFSDM_FCR_FOSR(fl->fosr - 1));
> +	if (ret)
> +		return ret;
> +
> +	ret = regmap_update_bits(regmap, DFSDM_FCR(fl_id), DFSDM_FCR_FORD_MASK,
> +				 DFSDM_FCR_FORD(fl->ford));
> +	if (ret)
> +		return ret;
> +
> +	/* No scan mode supported for the moment */
> +	ret = regmap_update_bits(regmap, DFSDM_CR1(fl_id), DFSDM_CR1_RCH_MASK,
> +				 DFSDM_CR1_RCH(ch_id));
> +	if (ret)
> +		return ret;
> +
> +	return regmap_update_bits(regmap, DFSDM_CR1(fl_id),
> +				  DFSDM_CR1_RSYNC_MASK,
> +				  DFSDM_CR1_RSYNC(fl->sync_mode));
> +}
> +
> +int stm32_dfsdm_channel_parse_of(struct stm32_dfsdm *dfsdm,
> +				 struct iio_dev *indio_dev,
> +				 struct iio_chan_spec *ch)
> +{
> +	struct stm32_dfsdm_channel *df_ch;
> +	const char *of_str;
> +	int chan_idx = ch->scan_index;
> +	int ret, val;
> +
> +	ret = of_property_read_u32_index(indio_dev->dev.of_node,
> +					 "st,adc-channels", chan_idx,
> +					 &ch->channel);
> +	if (ret < 0) {
> +		dev_err(&indio_dev->dev,
> +			" Error parsing 'st,adc-channels' for idx %d\n",
> +			chan_idx);
> +		return ret;
> +	}
> +	if (ch->channel >= dfsdm->num_chs) {
> +		dev_err(&indio_dev->dev,
> +			" Error bad channel number %d (max = %d)\n",
> +			ch->channel, dfsdm->num_chs);
> +		return -EINVAL;
> +	}
> +
> +	ret = of_property_read_string_index(indio_dev->dev.of_node,
> +					    "st,adc-channel-names", chan_idx,
> +					    &ch->datasheet_name);
> +	if (ret < 0) {
> +		dev_err(&indio_dev->dev,
> +			" Error parsing 'st,adc-channel-names' for idx %d\n",
> +			chan_idx);
> +		return ret;
> +	}
> +
> +	df_ch =  &dfsdm->ch_list[ch->channel];
> +	df_ch->id = ch->channel;
> +
> +	ret = of_property_read_string_index(indio_dev->dev.of_node,
> +					    "st,adc-channel-types", chan_idx,
> +					    &of_str);
> +	if (!ret) {
> +		val  = stm32_dfsdm_str2val(of_str, stm32_dfsdm_chan_type);
> +		if (val < 0)
> +			return val;
> +	} else {
> +		val = 0;
> +	}
> +	df_ch->type = val;
> +
> +	ret = of_property_read_string_index(indio_dev->dev.of_node,
> +					    "st,adc-channel-clk-src", chan_idx,
> +					    &of_str);
> +	if (!ret) {
> +		val  = stm32_dfsdm_str2val(of_str, stm32_dfsdm_chan_src);
> +		if (val < 0)
> +			return val;
> +	} else {
> +		val = 0;
> +	}
> +	df_ch->src = val;
> +
> +	ret = of_property_read_u32_index(indio_dev->dev.of_node,
> +					 "st,adc-alt-channel", chan_idx,
> +					 &df_ch->alt_si);
> +	if (ret < 0)
> +		df_ch->alt_si = 0;
> +
> +	return 0;
> +}
> +
> +static int stm32_dfsdm_start_conv(struct stm32_dfsdm_adc *adc, bool dma)
> +{
> +	struct regmap *regmap = adc->dfsdm->regmap;
> +	int ret;
> +
> +	ret = stm32_dfsdm_start_channel(adc->dfsdm, adc->ch_id);
> +	if (ret < 0)
> +		return ret;
> +
> +	ret = stm32_dfsdm_filter_configure(adc->dfsdm, adc->fl_id,
> +					   adc->ch_id);
> +	if (ret < 0)
> +		goto stop_channels;
> +
> +	ret = stm32_dfsdm_start_filter(adc->dfsdm, adc->fl_id);
> +	if (ret < 0)
> +		goto stop_channels;
> +
> +	return 0;
> +
> +stop_channels:
> +	regmap_update_bits(regmap, DFSDM_CR1(adc->fl_id),
> +			   DFSDM_CR1_RDMAEN_MASK, 0);
> +
> +	regmap_update_bits(regmap, DFSDM_CR1(adc->fl_id),
> +			   DFSDM_CR1_RCONT_MASK, 0);
> +	stm32_dfsdm_stop_channel(adc->dfsdm, adc->fl_id);
> +
> +	return ret;
> +}
> +
> +static void stm32_dfsdm_stop_conv(struct stm32_dfsdm_adc *adc)
> +{
> +	struct regmap *regmap = adc->dfsdm->regmap;
> +
> +	stm32_dfsdm_stop_filter(adc->dfsdm, adc->fl_id);
> +
> +	/* Clean conversion options */
> +	regmap_update_bits(regmap, DFSDM_CR1(adc->fl_id),
> +			   DFSDM_CR1_RDMAEN_MASK, 0);
> +
> +	regmap_update_bits(regmap, DFSDM_CR1(adc->fl_id),
> +			   DFSDM_CR1_RCONT_MASK, 0);
> +
> +	stm32_dfsdm_stop_channel(adc->dfsdm, adc->ch_id);
> +}
> +
> +static int stm32_dfsdm_single_conv(struct iio_dev *indio_dev,
> +				   const struct iio_chan_spec *chan, int *res)
> +{
> +	struct stm32_dfsdm_adc *adc = iio_priv(indio_dev);
> +	long timeout;
> +	int ret;
> +
> +	reinit_completion(&adc->completion);
> +
> +	adc->buffer = res;
> +
> +	ret = stm32_dfsdm_start_dfsdm(adc->dfsdm);
> +	if (ret < 0)
> +		return ret;
> +
> +	ret = regmap_update_bits(adc->dfsdm->regmap, DFSDM_CR2(adc->fl_id),
> +				 DFSDM_CR2_REOCIE_MASK, DFSDM_CR2_REOCIE(1));
> +	if (ret < 0)
> +		goto stop_dfsdm;
> +
> +	ret = stm32_dfsdm_start_conv(adc, false);
> +	if (ret < 0) {
> +		regmap_update_bits(adc->dfsdm->regmap, DFSDM_CR2(adc->fl_id),
> +				   DFSDM_CR2_REOCIE_MASK, DFSDM_CR2_REOCIE(0));
> +		goto stop_dfsdm;
> +	}
> +
> +	timeout = wait_for_completion_interruptible_timeout(&adc->completion,
> +							    DFSDM_TIMEOUT);
> +
> +	/* Mask IRQ for regular conversion achievement*/
> +	regmap_update_bits(adc->dfsdm->regmap, DFSDM_CR2(adc->fl_id),
> +			   DFSDM_CR2_REOCIE_MASK, DFSDM_CR2_REOCIE(0));
> +
> +	if (timeout == 0)
> +		ret = -ETIMEDOUT;
> +	else if (timeout < 0)
> +		ret = timeout;
> +	else
> +		ret = IIO_VAL_INT;
> +
> +	stm32_dfsdm_stop_conv(adc);
> +
> +stop_dfsdm:
> +	stm32_dfsdm_stop_dfsdm(adc->dfsdm);
> +
> +	return ret;
> +}
> +
> +static int stm32_dfsdm_write_raw(struct iio_dev *indio_dev,
> +				 struct iio_chan_spec const *chan,
> +				 int val, int val2, long mask)
> +{
> +	struct stm32_dfsdm_adc *adc = iio_priv(indio_dev);
> +	struct stm32_dfsdm_filter *fl = &adc->dfsdm->fl_list[adc->fl_id];
> +	int ret = -EINVAL;
> +
> +	if (mask == IIO_CHAN_INFO_OVERSAMPLING_RATIO) {
> +		ret = stm32_dfsdm_set_osrs(fl, 0, val);
> +		if (!ret)
> +			adc->oversamp = val;
> +	}
> +
> +	return ret;
> +}
> +
> +static int stm32_dfsdm_read_raw(struct iio_dev *indio_dev,
> +				struct iio_chan_spec const *chan, int *val,
> +				int *val2, long mask)
> +{
> +	struct stm32_dfsdm_adc *adc = iio_priv(indio_dev);
> +	int ret;
> +
> +	switch (mask) {
> +	case IIO_CHAN_INFO_RAW:
> +		ret = iio_hw_consumer_enable(adc->hwc);
> +		if (ret < 0) {
> +			dev_err(&indio_dev->dev,
> +				"%s: IIO enable failed (channel %d)\n",
> +				__func__, chan->channel);
> +			return ret;
> +		}
> +		ret = stm32_dfsdm_single_conv(indio_dev, chan, val);
> +		iio_hw_consumer_disable(adc->hwc);
> +		if (ret < 0) {
> +			dev_err(&indio_dev->dev,
> +				"%s: Conversion failed (channel %d)\n",
> +				__func__, chan->channel);
> +			return ret;
> +		}
> +		return IIO_VAL_INT;
> +
> +	case IIO_CHAN_INFO_OVERSAMPLING_RATIO:
> +		*val = adc->oversamp;
> +
> +		return IIO_VAL_INT;
> +	}
> +
> +	return -EINVAL;
> +}
> +
> +static const struct iio_info stm32_dfsdm_info_adc = {
> +	.read_raw = stm32_dfsdm_read_raw,
> +	.write_raw = stm32_dfsdm_write_raw,
> +};
> +
> +static irqreturn_t stm32_dfsdm_irq(int irq, void *arg)
> +{
> +	struct stm32_dfsdm_adc *adc = arg;
> +	struct iio_dev *indio_dev = iio_priv_to_dev(adc);
> +	struct regmap *regmap = adc->dfsdm->regmap;
> +	unsigned int status, int_en;
> +
> +	regmap_read(regmap, DFSDM_ISR(adc->fl_id), &status);
> +	regmap_read(regmap, DFSDM_CR2(adc->fl_id), &int_en);
> +
> +	if (status & DFSDM_ISR_REOCF_MASK) {
> +		/* Read the data register clean the IRQ status */
> +		regmap_read(regmap, DFSDM_RDATAR(adc->fl_id), adc->buffer);
> +		complete(&adc->completion);
> +	}
> +
> +	if (status & DFSDM_ISR_ROVRF_MASK) {
> +		if (int_en & DFSDM_CR2_ROVRIE_MASK)
> +			dev_warn(&indio_dev->dev, "Overrun detected\n");
> +		regmap_update_bits(regmap, DFSDM_ICR(adc->fl_id),
> +				   DFSDM_ICR_CLRROVRF_MASK,
> +				   DFSDM_ICR_CLRROVRF_MASK);
> +	}
> +
> +	return IRQ_HANDLED;
> +}
> +
> +static int stm32_dfsdm_adc_chan_init_one(struct iio_dev *indio_dev,
> +					 struct iio_chan_spec *ch)
> +{
> +	struct stm32_dfsdm_adc *adc = iio_priv(indio_dev);
> +	int ret;
> +
> +	ret = stm32_dfsdm_channel_parse_of(adc->dfsdm, indio_dev, ch);
> +	if (ret < 0)
> +		return ret;
> +
> +	ch->type = IIO_VOLTAGE;
> +	ch->indexed = 1;
> +
> +	/*
> +	 * IIO_CHAN_INFO_RAW: used to compute regular conversion
> +	 * IIO_CHAN_INFO_OVERSAMPLING_RATIO: used to set oversampling
> +	 */
> +	ch->info_mask_separate = BIT(IIO_CHAN_INFO_RAW);
> +	ch->info_mask_shared_by_all = BIT(IIO_CHAN_INFO_OVERSAMPLING_RATIO);
> +
> +	ch->scan_type.sign = 'u';
> +	ch->scan_type.realbits = 24;
> +	ch->scan_type.storagebits = 32;
> +	adc->ch_id = ch->channel;
> +
> +	return stm32_dfsdm_chan_configure(adc->dfsdm,
> +					  &adc->dfsdm->ch_list[ch->channel]);
> +}
> +
> +static int stm32_dfsdm_adc_init(struct iio_dev *indio_dev)
> +{
> +	struct iio_chan_spec *ch;
> +	struct stm32_dfsdm_adc *adc = iio_priv(indio_dev);
> +	int num_ch;
> +	int ret, chan_idx;
> +
> +	adc->oversamp = DFSDM_DEFAULT_OVERSAMPLING;
> +	ret = stm32_dfsdm_set_osrs(&adc->dfsdm->fl_list[adc->fl_id], 0,
> +				   adc->oversamp);
> +	if (ret < 0)
> +		return ret;
> +
> +	num_ch = of_property_count_u32_elems(indio_dev->dev.of_node,
> +					     "st,adc-channels");
> +	if (num_ch < 0 || num_ch > adc->dfsdm->num_chs) {
> +		dev_err(&indio_dev->dev, "Bad st,adc-channels\n");
> +		return num_ch < 0 ? num_ch : -EINVAL;
> +	}
> +
> +	/* Bind to SD modulator IIO device */
> +	adc->hwc = devm_iio_hw_consumer_alloc(&indio_dev->dev);
> +	if (IS_ERR(adc->hwc))
> +		return -EPROBE_DEFER;
> +
> +	ch = devm_kcalloc(&indio_dev->dev, num_ch, sizeof(*ch),
> +			  GFP_KERNEL);
> +	if (!ch)
> +		return -ENOMEM;
> +
> +	for (chan_idx = 0; chan_idx < num_ch; chan_idx++) {
> +		ch->scan_index = chan_idx;
> +		ret = stm32_dfsdm_adc_chan_init_one(indio_dev, ch);
> +		if (ret < 0) {
> +			dev_err(&indio_dev->dev, "Channels init failed\n");
> +			return ret;
> +		}
> +	}
> +
> +	indio_dev->num_channels = num_ch;
> +	indio_dev->channels = ch;
> +
> +	init_completion(&adc->completion);
> +
> +	return 0;
> +}
> +
> +static const struct stm32_dfsdm_dev_data stm32h7_dfsdm_adc_data = {
> +	.type = DFSDM_IIO,
> +	.init = stm32_dfsdm_adc_init,
> +};
> +
> +static const struct of_device_id stm32_dfsdm_adc_match[] = {
> +	{ .compatible = "st,stm32-dfsdm-adc",
Slightly odd alignment, I'd drop .compatible onto a new line as well..

> +		.data = &stm32h7_dfsdm_adc_data,
> +	},
> +	{}
> +};
> +
> +static int stm32_dfsdm_adc_probe(struct platform_device *pdev)
> +{
> +	struct device *dev = &pdev->dev;
> +	struct stm32_dfsdm_adc *adc;
> +	struct device_node *np = dev->of_node;
> +	const struct stm32_dfsdm_dev_data *dev_data;
> +	struct iio_dev *iio;
> +	const struct of_device_id *of_id;
> +	char *name;
> +	int ret, irq, val;
> +
> +	of_id = of_match_node(stm32_dfsdm_adc_match, np);
> +	if (!of_id->data) {
> +		dev_err(&pdev->dev, "Data associated to device is missing\n");
> +		return -EINVAL;
> +	}
> +
> +	dev_data = (const struct stm32_dfsdm_dev_data *)of_id->data;
> +
> +	iio = devm_iio_device_alloc(dev, sizeof(*adc));
> +	if (IS_ERR(iio)) {
> +		dev_err(dev, "%s: Failed to allocate IIO\n", __func__);
> +		return PTR_ERR(iio);
> +	}
> +
> +	adc = iio_priv(iio);
> +	if (IS_ERR(adc)) {
> +		dev_err(dev, "%s: Failed to allocate ADC\n", __func__);
> +		return PTR_ERR(adc);
> +	}
> +	adc->dfsdm = dev_get_drvdata(dev->parent);
> +
> +	iio->dev.parent = dev;
> +	iio->dev.of_node = np;
> +	iio->modes = INDIO_DIRECT_MODE | INDIO_BUFFER_SOFTWARE;
> +
> +	platform_set_drvdata(pdev, adc);
> +
> +	ret = of_property_read_u32(dev->of_node, "reg", &adc->fl_id);
> +	if (ret != 0) {
> +		dev_err(dev, "Missing reg property\n");
> +		return -EINVAL;
> +	}
> +
> +	name = devm_kzalloc(dev, sizeof("dfsdm-adc0"), GFP_KERNEL);
> +	if (!name)
> +		return -ENOMEM;
> +	iio->info = &stm32_dfsdm_info_adc;
> +	snprintf(name, sizeof("dfsdm-adc0"), "dfsdm-adc%d", adc->fl_id);
> +	iio->name = name;
> +
> +	/*
> +	 * In a first step IRQs generated for channels are not treated.
> +	 * So IRQ associated to filter instance 0 is dedicated to the Filter 0.
> +	 */
> +	irq = platform_get_irq(pdev, 0);
> +	ret = devm_request_irq(dev, irq, stm32_dfsdm_irq,
> +			       0, pdev->name, adc);
> +	if (ret < 0) {
> +		dev_err(dev, "Failed to request IRQ\n");
> +		return ret;
> +	}
> +
> +	ret = of_property_read_u32(dev->of_node, "st,filter-order", &val);
> +	if (ret < 0) {
> +		dev_err(dev, "Failed to set filter order\n");
> +		return ret;
> +	}
> +
> +	adc->dfsdm->fl_list[adc->fl_id].ford = val;
> +
> +	ret = of_property_read_u32(dev->of_node, "st,filter0-sync", &val);
> +	if (!ret)
> +		adc->dfsdm->fl_list[adc->fl_id].sync_mode = val;
> +
> +	adc->dev_data = dev_data;
> +	ret = dev_data->init(iio);
> +	if (ret < 0)
> +		return ret;
> +
> +	return iio_device_register(iio);
> +}
> +
> +static int stm32_dfsdm_adc_remove(struct platform_device *pdev)
> +{
> +	struct stm32_dfsdm_adc *adc = platform_get_drvdata(pdev);
> +	struct iio_dev *indio_dev = iio_priv_to_dev(adc);
> +
> +	iio_device_unregister(indio_dev);
> +
> +	return 0;
> +}
> +
> +static struct platform_driver stm32_dfsdm_adc_driver = {
> +	.driver = {
> +		.name = "stm32-dfsdm-adc",
> +		.of_match_table = stm32_dfsdm_adc_match,
> +	},
> +	.probe = stm32_dfsdm_adc_probe,
> +	.remove = stm32_dfsdm_adc_remove,
> +

Real nitpick but no blank line here!

> +};
> +module_platform_driver(stm32_dfsdm_adc_driver);
> +
> +MODULE_DESCRIPTION("STM32 sigma delta ADC");
> +MODULE_AUTHOR("Arnaud Pouliquen <arnaud.pouliquen-qxv4g6HH51o@public.gmane.org>");
> +MODULE_LICENSE("GPL v2");

--
To unsubscribe from this list: send the line "unsubscribe devicetree" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

^ permalink raw reply

* Re: [PATCH v6 07/13] IIO: add DT bindings for stm32 DFSDM filter
From: Jonathan Cameron @ 2017-12-02 14:55 UTC (permalink / raw)
  To: Arnaud Pouliquen
  Cc: Rob Herring, Mark Rutland, Hartmut Knaack, Lars-Peter Clausen,
	Peter Meerwald-Stadler, Jaroslav Kysela, Takashi Iwai,
	Liam Girdwood, Mark Brown, devicetree-u79uwXL29TY76Z2rM5mHXA,
	linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r,
	linux-iio-u79uwXL29TY76Z2rM5mHXA,
	alsa-devel-K7yf7f+aM1XWsZ/bQMPhNw, Maxime Coquelin,
	Alexandre Torgue
In-Reply-To: <1512150020-20335-8-git-send-email-arnaud.pouliquen-qxv4g6HH51o@public.gmane.org>

On Fri, 1 Dec 2017 18:40:14 +0100
Arnaud Pouliquen <arnaud.pouliquen-qxv4g6HH51o@public.gmane.org> wrote:

> Add bindings that describes STM32 Digital Filter for Sigma Delta
> Modulators. DFSDM allows to connect sigma delta
> modulators.
> 
> Signed-off-by: Arnaud Pouliquen <arnaud.pouliquen-qxv4g6HH51o@public.gmane.org>
> Acked-by: Rob Herring <robh-DgEjT+Ai2ygdnm+yROfE0A@public.gmane.org>

Acked-by: Jonathan Cameron <Jonathan.Cameron-hv44wF8Li93QT0dZR+AlfA@public.gmane.org>

> ---
>  .../bindings/iio/adc/st,stm32-dfsdm-adc.txt        | 127 +++++++++++++++++++++
>  1 file changed, 127 insertions(+)
>  create mode 100644 Documentation/devicetree/bindings/iio/adc/st,stm32-dfsdm-adc.txt
> 
> diff --git a/Documentation/devicetree/bindings/iio/adc/st,stm32-dfsdm-adc.txt b/Documentation/devicetree/bindings/iio/adc/st,stm32-dfsdm-adc.txt
> new file mode 100644
> index 0000000..4a42d76
> --- /dev/null
> +++ b/Documentation/devicetree/bindings/iio/adc/st,stm32-dfsdm-adc.txt
> @@ -0,0 +1,127 @@
> +STMicroelectronics STM32 DFSDM ADC device driver
> +
> +
> +STM32 DFSDM ADC is a sigma delta analog-to-digital converter dedicated to
> +interface external sigma delta modulators to STM32 micro controllers.
> +It is mainly targeted for:
> +- Sigma delta modulators (motor control, metering...)
> +- PDM microphones (audio digital microphone)
> +
> +It features up to 8 serial digital interfaces (SPI or Manchester) and
> +up to 4 filters on stm32h7.
> +
> +Each child node match with a filter instance.
> +
> +Contents of a STM32 DFSDM root node:
> +------------------------------------
> +Required properties:
> +- compatible: Should be "st,stm32h7-dfsdm".
> +- reg: Offset and length of the DFSDM block register set.
> +- clocks: IP and serial interfaces clocking. Should be set according
> +		to rcc clock ID and "clock-names".
> +- clock-names: Input clock name "dfsdm" must be defined,
> +		"audio" is optional. If defined CLKOUT is based on the audio
> +		clock, else "dfsdm" is used.
> +- #interrupt-cells = <1>;
> +- #address-cells = <1>;
> +- #size-cells = <0>;
> +
> +Optional properties:
> +- spi-max-frequency: Requested only for SPI master mode.
> +		  SPI clock OUT frequency (Hz). This clock must be set according
> +		  to "clock" property. Frequency must be a multiple of the rcc
> +		  clock frequency. If not, SPI CLKOUT frequency will not be
> +		  accurate.
> +
> +Contents of a STM32 DFSDM child nodes:
> +--------------------------------------
> +
> +Required properties:
> +- compatible: Must be:
> +	"st,stm32-dfsdm-adc" for sigma delta ADCs
> +	"st,stm32-dfsdm-dmic" for audio digital microphone.
> +- reg: Specifies the DFSDM filter instance used.
> +- interrupts: IRQ lines connected to each DFSDM filter instance.
> +- st,adc-channels:	List of single-ended channels muxed for this ADC.
> +			valid values:
> +				"st,stm32h7-dfsdm" compatibility: 0 to 7.
> +- st,adc-channel-names:	List of single-ended channel names.
> +- st,filter-order:  SinC filter order from 0 to 5.
> +			0: FastSinC
> +			[1-5]: order 1 to 5.
> +			For audio purpose it is recommended to use order 3 to 5.
> +- #io-channel-cells = <1>: See the IIO bindings section "IIO consumers".
> +
> +Required properties for "st,stm32-dfsdm-adc" compatibility:
> +- io-channels: From common IIO binding. Used to pipe external sigma delta
> +		modulator or internal ADC output to DFSDM channel.
> +		This is not required for "st,stm32-dfsdm-pdm" compatibility as
> +		PDM microphone is binded in Audio DT node.
> +
> +Required properties for "st,stm32-dfsdm-pdm" compatibility:
> +- #sound-dai-cells: Must be set to 0.
> +- dma: DMA controller phandle and DMA request line associated to the
> +		filter instance (specified by the field "reg")
> +- dma-names: Must be "rx"
> +
> +Optional properties:
> +- st,adc-channel-types:	Single-ended channel input type.
> +			- "SPI_R": SPI with data on rising edge (default)
> +			- "SPI_F": SPI with data on falling edge
> +			- "MANCH_R": manchester codec, rising edge = logic 0
> +			- "MANCH_F": manchester codec, falling edge = logic 1
> +- st,adc-channel-clk-src: Conversion clock source.
> +			  - "CLKIN": external SPI clock (CLKIN x)
> +			  - "CLKOUT": internal SPI clock (CLKOUT) (default)
> +			  - "CLKOUT_F": internal SPI clock divided by 2 (falling edge).
> +			  - "CLKOUT_R": internal SPI clock divided by 2 (rising edge).
> +
> +- st,adc-alt-channel: Must be defined if two sigma delta modulator are
> +			  connected on same SPI input.
> +			  If not set, channel n is connected to SPI input n.
> +			  If set, channel n is connected to SPI input n + 1.
> +
> +- st,filter0-sync: Set to 1 to synchronize with DFSDM filter instance 0.
> +		   Used for multi microphones synchronization.
> +
> +Example of a sigma delta adc connected on DFSDM SPI port 0
> +and a pdm microphone connected on DFSDM SPI port 1:
> +
> +	ads1202: simple_sd_adc@0 {
> +		compatible = "ads1202";
> +		#io-channel-cells = <1>;
> +	};
> +
> +	dfsdm: dfsdm@40017000 {
> +		compatible = "st,stm32h7-dfsdm";
> +		reg = <0x40017000 0x400>;
> +		clocks = <&rcc DFSDM1_CK>;
> +		clock-names = "dfsdm";
> +		#address-cells = <1>;
> +		#size-cells = <0>;
> +
> +		dfsdm_adc0: dfsdm-adc@0 {
> +			compatible = "st,stm32-dfsdm-adc";
> +			#io-channel-cells = <1>;
> +			reg = <0>;
> +			interrupts = <110>;
> +			st,adc-channels = <0>;
> +			st,adc-channel-names = "sd_adc0";
> +			st,adc-channel-types = "SPI_F";
> +			st,adc-channel-clk-src = "CLKOUT";
> +			io-channels = <&ads1202 0>;
> +			st,filter-order = <3>;
> +		};
> +		dfsdm_pdm1: dfsdm-pdm@1 {
> +			compatible = "st,stm32-dfsdm-dmic";
> +			reg = <1>;
> +			interrupts = <111>;
> +			dmas = <&dmamux1 102 0x400 0x00>;
> +			dma-names = "rx";
> +			st,adc-channels = <1>;
> +			st,adc-channel-names = "dmic1";
> +			st,adc-channel-types = "SPI_R";
> +			st,adc-channel-clk-src = "CLKOUT";
> +			st,filter-order = <5>;
> +		};
> +	}

^ permalink raw reply

* Re: [PATCH v6 06/13] IIO: ADC: add sigma delta modulator support
From: Jonathan Cameron @ 2017-12-02 14:54 UTC (permalink / raw)
  To: Arnaud Pouliquen
  Cc: Rob Herring, Mark Rutland, Hartmut Knaack, Lars-Peter Clausen,
	Peter Meerwald-Stadler, Jaroslav Kysela, Takashi Iwai,
	Liam Girdwood, Mark Brown, devicetree-u79uwXL29TY76Z2rM5mHXA,
	linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r,
	linux-iio-u79uwXL29TY76Z2rM5mHXA,
	alsa-devel-K7yf7f+aM1XWsZ/bQMPhNw, Maxime Coquelin,
	Alexandre Torgue
In-Reply-To: <1512150020-20335-7-git-send-email-arnaud.pouliquen-qxv4g6HH51o@public.gmane.org>

On Fri, 1 Dec 2017 18:40:13 +0100
Arnaud Pouliquen <arnaud.pouliquen-qxv4g6HH51o@public.gmane.org> wrote:

> Add generic driver to support sigma delta modulators.
> Typically, this device is hardware connected to
> an IIO device in charge of the conversion. Devices are
> bonded through the hardware consumer API.
> 
> Signed-off-by: Arnaud Pouliquen <arnaud.pouliquen-qxv4g6HH51o@public.gmane.org>
I love this little one ;) Smallest IIO driver yet!
Doesn't technically 'do' anything but that's not the point.

Acked-by: Jonathan Cameron <Jonathan.Cameron-hv44wF8Li93QT0dZR+AlfA@public.gmane.org>

> ---
>  drivers/iio/adc/Kconfig            | 12 ++++++
>  drivers/iio/adc/Makefile           |  1 +
>  drivers/iio/adc/sd_adc_modulator.c | 81 ++++++++++++++++++++++++++++++++++++++
>  3 files changed, 94 insertions(+)
>  create mode 100644 drivers/iio/adc/sd_adc_modulator.c
> 
> diff --git a/drivers/iio/adc/Kconfig b/drivers/iio/adc/Kconfig
> index 5762565..c5db62f 100644
> --- a/drivers/iio/adc/Kconfig
> +++ b/drivers/iio/adc/Kconfig
> @@ -626,6 +626,18 @@ config SPEAR_ADC
>  	  To compile this driver as a module, choose M here: the
>  	  module will be called spear_adc.
>  
> +config SD_ADC_MODULATOR
> +	tristate "Generic sigma delta modulator"
> +	depends on OF
> +	select IIO_BUFFER
> +	select IIO_TRIGGERED_BUFFER
> +	help
> +	  Select this option to enables sigma delta modulator. This driver can
> +	  support generic sigma delta modulators.
> +
> +	  This driver can also be built as a module.  If so, the module
> +	  will be called sd_adc_modulator.
> +
>  config STM32_ADC_CORE
>  	tristate "STMicroelectronics STM32 adc core"
>  	depends on ARCH_STM32 || COMPILE_TEST
> diff --git a/drivers/iio/adc/Makefile b/drivers/iio/adc/Makefile
> index 9874e05..d800325 100644
> --- a/drivers/iio/adc/Makefile
> +++ b/drivers/iio/adc/Makefile
> @@ -81,3 +81,4 @@ obj-$(CONFIG_VF610_ADC) += vf610_adc.o
>  obj-$(CONFIG_VIPERBOARD_ADC) += viperboard_adc.o
>  xilinx-xadc-y := xilinx-xadc-core.o xilinx-xadc-events.o
>  obj-$(CONFIG_XILINX_XADC) += xilinx-xadc.o
> +obj-$(CONFIG_SD_ADC_MODULATOR) += sd_adc_modulator.o
> diff --git a/drivers/iio/adc/sd_adc_modulator.c b/drivers/iio/adc/sd_adc_modulator.c
> new file mode 100644
> index 0000000..08bd7b6
> --- /dev/null
> +++ b/drivers/iio/adc/sd_adc_modulator.c
> @@ -0,0 +1,81 @@
> +/*
> + * Generic sigma delta modulator driver
> + *
> + * Copyright (C) 2017, STMicroelectronics - All Rights Reserved
> + * Author: Arnaud Pouliquen <arnaud.pouliquen-qxv4g6HH51o@public.gmane.org>.
> + *
> + * License type: GPLv2
> + *
> + * 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.
> + *
> + * This program is distributed in the hope that it will be useful, but
> + * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
> + * or FITNESS FOR A PARTICULAR PURPOSE.
> + * See the GNU General Public License for more details.
> + *
> + * You should have received a copy of the GNU General Public License along with
> + * this program. If not, see <http://www.gnu.org/licenses/>.
> + */
> +
> +#include <linux/iio/iio.h>
> +#include <linux/iio/triggered_buffer.h>
> +#include <linux/module.h>
> +#include <linux/of_device.h>
> +
> +static const struct iio_info iio_sd_mod_iio_info;
> +
> +static const struct iio_chan_spec iio_sd_mod_ch = {
> +	.type = IIO_VOLTAGE,
> +	.indexed = 1,
> +	.scan_type = {
> +		.sign = 'u',
> +		.realbits = 1,
> +		.shift = 0,
> +	},
> +};
> +
> +static int iio_sd_mod_probe(struct platform_device *pdev)
> +{
> +	struct device *dev = &pdev->dev;
> +	struct iio_dev *iio;
> +
> +	iio = devm_iio_device_alloc(dev, 0);
> +	if (!iio)
> +		return -ENOMEM;
> +
> +	iio->dev.parent = dev;
> +	iio->dev.of_node = dev->of_node;
> +	iio->name = dev_name(dev);
> +	iio->info = &iio_sd_mod_iio_info;
> +	iio->modes = INDIO_BUFFER_HARDWARE;
> +
> +	iio->num_channels = 1;
> +	iio->channels = &iio_sd_mod_ch;
> +
> +	platform_set_drvdata(pdev, iio);
> +
> +	return devm_iio_device_register(&pdev->dev, iio);
> +}
> +
> +static const struct of_device_id sd_adc_of_match[] = {
> +	{ .compatible = "sd-modulator" },
> +	{ .compatible = "ads1201" },
> +	{ }
> +};
> +MODULE_DEVICE_TABLE(of, sd_adc_of_match);
> +
> +static struct platform_driver iio_sd_mod_adc = {
> +	.driver = {
> +		.name = "iio_sd_adc_mod",
> +		.of_match_table = of_match_ptr(sd_adc_of_match),
> +	},
> +	.probe = iio_sd_mod_probe,
> +};
> +
> +module_platform_driver(iio_sd_mod_adc);
> +
> +MODULE_DESCRIPTION("Basic sigma delta modulator");
> +MODULE_AUTHOR("Arnaud Pouliquen <arnaud.pouliquen-qxv4g6HH51o@public.gmane.org>");
> +MODULE_LICENSE("GPL v2");

^ permalink raw reply


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