Devicetree
 help / color / mirror / Atom feed
* Re: [PATCH v7 1/2] mtd: nand: add tango NFC dt bindings doc
From: Rob Herring @ 2016-10-31  2:45 UTC (permalink / raw)
  To: Marc Gonzalez
  Cc: linux-mtd, Boris Brezillon, Richard Weinberger, DT, Mark Rutland,
	Mason, Sebastian Frias
In-Reply-To: <580F5B06.6030608-y1yR0Z3OICC7zZZRDBGcUA@public.gmane.org>

On Tue, Oct 25, 2016 at 03:15:50PM +0200, Marc Gonzalez wrote:
> Add the tango NAND Flash Controller dt bindings documentation.
> 
> Signed-off-by: Marc Gonzalez <marc_gonzalez-y1yR0Z3OICC7zZZRDBGcUA@public.gmane.org>
> ---
>  Documentation/devicetree/bindings/mtd/tango-nand.txt | 38 ++++++++++++++++++++++++++++++
>  1 file changed, 38 insertions(+)

Acked-by: Rob Herring <robh-DgEjT+Ai2ygdnm+yROfE0A@public.gmane.org>
--
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 2/6] arm: dts: ls1021a: update MSI node
From: Rob Herring @ 2016-10-31  2:42 UTC (permalink / raw)
  To: Minghuan Lian
  Cc: linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r,
	linux-kernel-u79uwXL29TY76Z2rM5mHXA,
	devicetree-u79uwXL29TY76Z2rM5mHXA, Shawn Guo, Marc Zyngier,
	Mingkai Hu, Stuart Yoder, Yang-Leo Li, Scott Wood
In-Reply-To: <1477398945-22774-2-git-send-email-Minghuan.Lian-3arQi8VN3Tc@public.gmane.org>

On Tue, Oct 25, 2016 at 08:35:41PM +0800, Minghuan Lian wrote:
> 1. Change compatible to "fsl,ls-scfg-msi"

That is obvious from the diff. Write your commit message to answer the 
question Why?

This also breaks compatibility with old DTBs.

> 2. Move two MSI dts node into the parent node "msi-controller".
> So a PCIe device can request the MSI from the two MSI controllers.
> 
> Signed-off-by: Minghuan Lian <Minghuan.Lian-3arQi8VN3Tc@public.gmane.org>
> ---
>  arch/arm/boot/dts/ls1021a.dtsi | 28 ++++++++++++++++------------
>  1 file changed, 16 insertions(+), 12 deletions(-)
> 
> diff --git a/arch/arm/boot/dts/ls1021a.dtsi b/arch/arm/boot/dts/ls1021a.dtsi
> index 368e219..7a3b510 100644
> --- a/arch/arm/boot/dts/ls1021a.dtsi
> +++ b/arch/arm/boot/dts/ls1021a.dtsi
> @@ -119,18 +119,22 @@
>  
>  		};
>  
> -		msi1: msi-controller@1570e00 {
> -			compatible = "fsl,1s1021a-msi";
> -			reg = <0x0 0x1570e00 0x0 0x8>;
> +		msi: msi-controller {
> +			compatible = "fsl,ls-scfg-msi";
> +			#address-cells = <2>;
> +			#size-cells = <2>;
> +			ranges;
>  			msi-controller;
> -			interrupts =  <GIC_SPI 179 IRQ_TYPE_LEVEL_HIGH>;
> -		};
>  
> -		msi2: msi-controller@1570e08 {
> -			compatible = "fsl,1s1021a-msi";
> -			reg = <0x0 0x1570e08 0x0 0x8>;
> -			msi-controller;
> -			interrupts = <GIC_SPI 180 IRQ_TYPE_LEVEL_HIGH>;
> +			msi0@1570e00 {
> +				reg = <0x0 0x1570e00 0x0 0x8>;
> +				interrupts = <GIC_SPI 179 IRQ_TYPE_LEVEL_HIGH>;
> +			};
> +
> +			msi1@1570e08 {
> +				reg = <0x0 0x1570e08 0x0 0x8>;
> +				interrupts = <GIC_SPI 180 IRQ_TYPE_LEVEL_HIGH>;
> +			};
>  		};
>  
>  		ifc: ifc@1530000 {
> @@ -643,7 +647,7 @@
>  			bus-range = <0x0 0xff>;
>  			ranges = <0x81000000 0x0 0x00000000 0x40 0x00010000 0x0 0x00010000   /* downstream I/O */
>  				  0x82000000 0x0 0x40000000 0x40 0x40000000 0x0 0x40000000>; /* non-prefetchable memory */
> -			msi-parent = <&msi1>;
> +			msi-parent = <&msi>;
>  			#interrupt-cells = <1>;
>  			interrupt-map-mask = <0 0 0 7>;
>  			interrupt-map = <0000 0 0 1 &gic GIC_SPI 91  IRQ_TYPE_LEVEL_HIGH>,
> @@ -666,7 +670,7 @@
>  			bus-range = <0x0 0xff>;
>  			ranges = <0x81000000 0x0 0x00000000 0x48 0x00010000 0x0 0x00010000   /* downstream I/O */
>  				  0x82000000 0x0 0x40000000 0x48 0x40000000 0x0 0x40000000>; /* non-prefetchable memory */
> -			msi-parent = <&msi2>;
> +			msi-parent = <&msi>;
>  			#interrupt-cells = <1>;
>  			interrupt-map-mask = <0 0 0 7>;
>  			interrupt-map = <0000 0 0 1 &gic GIC_SPI 92  IRQ_TYPE_LEVEL_HIGH>,
> -- 
> 1.9.1
> 
--
To unsubscribe from this list: send the line "unsubscribe devicetree" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

^ permalink raw reply

* Re: [PATCH v9 2/4] soc: mediatek: Init MT8173 scpsys driver earlier
From: James Liao @ 2016-10-31  2:08 UTC (permalink / raw)
  To: Matthias Brugger, Yong Wu
  Cc: Sascha Hauer, Rob Herring, Kevin Hilman, Daniel Kurtz,
	srv_heupstream, devicetree, linux-kernel, linux-arm-kernel,
	linux-mediatek
In-Reply-To: <14a1ebb2-fda2-278b-b2f0-8f9c6ff6a83d@gmail.com>

On Mon, 2016-10-31 at 01:08 +0100, Matthias Brugger wrote:
> Hi James,
> 
> On 10/20/2016 10:56 AM, James Liao wrote:
> > Some power domain comsumers may init before module_init.
> > So the power domain provider (scpsys) need to be initialized
> > earlier too.
> >
> > Take an example for our IOMMU (M4U) and SMI. SMI is a bridge
> > between IOMMU and multimedia HW. SMI is responsible to
> > enable/disable iommu and help transfer data for each multimedia
> > HW. Both of them have to wait until the power and clocks are
> > enabled.
> >
> > So scpsys driver should be initialized before SMI, and SMI should
> > be initialized before IOMMU, and then init IOMMU consumers
> > (display/vdec/venc/camera etc.).
> >
> > IOMMU is subsys_init by default. So we need to init scpsys driver
> > before subsys_init.
> >
> > Signed-off-by: James Liao <jamesjj.liao@mediatek.com>
> > Reviewed-by: Kevin Hilman <khilman@baylibre.com>
> > ---
> 
> I didn't applied this patch for now.
> I answered you in v7 of this series [1]. I would prefer to see if we can 
> fix that otherwise.
> 
> Would be great if you or Yong could provide some feedback.
> 
> Thanks,
> Matthias
> 
> [1] https://patchwork.kernel.org/patch/9397405/
> 
> >  drivers/soc/mediatek/mtk-scpsys.c | 19 ++++++++++++++++++-
> >  1 file changed, 18 insertions(+), 1 deletion(-)
> >
> > diff --git a/drivers/soc/mediatek/mtk-scpsys.c b/drivers/soc/mediatek/mtk-scpsys.c
> > index fa9ee69..dd7a07d 100644
> > --- a/drivers/soc/mediatek/mtk-scpsys.c
> > +++ b/drivers/soc/mediatek/mtk-scpsys.c
> > @@ -613,4 +613,21 @@ static int scpsys_probe(struct platform_device *pdev)
> >  		.of_match_table = of_match_ptr(of_scpsys_match_tbl),
> >  	},
> >  };
> > -builtin_platform_driver(scpsys_drv);
> > +
> > +static int __init scpsys_drv_init(void)
> > +{
> > +	return platform_driver_register(&scpsys_drv);
> > +}
> > +
> > +/*
> > + * There are some Mediatek drivers which depend on the power domain driver need
> > + * to probe in earlier initcall levels. So scpsys driver also need to probe
> > + * earlier.
> > + *
> > + * IOMMU(M4U) and SMI drivers for example. SMI is a bridge between IOMMU and
> > + * multimedia HW. IOMMU depends on SMI, and SMI is a power domain consumer,
> > + * so the proper probe sequence should be scpsys -> SMI -> IOMMU driver.
> > + * IOMMU drivers are initialized during subsys_init by default, so we need to
> > + * move SMI and scpsys drivers to subsys_init or earlier init levels.
> > + */
> > +subsys_initcall(scpsys_drv_init);
> >

Hi Matthias,

I got it, thanks.


Hi Yong,

Is this patch still needed on latest kernel for IOMMU driver? Or we have
other solutions for IOMMU driver init?


Best regards,

James

^ permalink raw reply

* Re: [PATCH 2/2] clk: hisilicon: add CRG driver for Hi3516CV300 SoC
From: Jiancheng Xue @ 2016-10-31  2:05 UTC (permalink / raw)
  To: Hao Zhang
  Cc: Michael Turquette, Stephen Boyd, robh+dt, Mark Rutland, open list,
	open list:COMMON CLK FRAMEWORK,
	open list:OPEN FIRMWARE AND FLATTENED DEVICE TREE BINDINGS,
	bin.chen, elder, hermit.wangheming, yanhaifeng, wenpan,
	howell.yang
In-Reply-To: <CAJeuY78oNx_RqOX8yRJOJTM+W2nCbpFYY9OmYgK3TG1hpW_CRg@mail.gmail.com>



在 2016/10/29 19:36, Hao Zhang 写道:
> Hi, is there any mainline kernel or uboot for hisilicon hi3520dv200 or
> hi3520dv300? just want some base support to boot , anything close to
> mainline is ok :)
> 
Sorry. I wasn't engaged in hi3520d project. I have no detailed information about it.
As far as I know, most of HiSilicon products include a written offer document. You
can check it out and apply for the source code following the instructions.

Regards,
Jiancheng

> 2016-10-29 14:13 GMT+08:00 Jiancheng Xue <xuejiancheng@hisilicon.com>:
>> Add CRG driver for Hi3516CV300 SoC. CRG(Clock and Reset
>> Generator) module generates clock and reset signals used
>> by other module blocks on SoC.
>>
>> Signed-off-by: Pan Wen <wenpan@hisilicon.com>
>> ---
>>  drivers/clk/hisilicon/Kconfig                 |   8 +
>>  drivers/clk/hisilicon/Makefile                |   1 +
>>  drivers/clk/hisilicon/crg-hi3516cv300.c       | 330 ++++++++++++++++++++++++++
>>  include/dt-bindings/clock/hi3516cv300-clock.h |  48 ++++
>>  4 files changed, 387 insertions(+)
>>  create mode 100644 drivers/clk/hisilicon/crg-hi3516cv300.c
>>  create mode 100644 include/dt-bindings/clock/hi3516cv300-clock.h
>>
>> diff --git a/drivers/clk/hisilicon/Kconfig b/drivers/clk/hisilicon/Kconfig
>> index c41b6d2..f80773b 100644
>> --- a/drivers/clk/hisilicon/Kconfig
>> +++ b/drivers/clk/hisilicon/Kconfig
>> @@ -1,3 +1,11 @@
>> +config COMMON_CLK_HI3516CV300
>> +       tristate "HI3516CV300 Clock Driver"
>> +       depends on ARCH_HISI || COMPILE_TEST
>> +       select RESET_HISI
>> +       default ARCH_HISI
>> +       help
>> +         Build the clock driver for hi3516cv300.
>> +
>>  config COMMON_CLK_HI3519
>>         tristate "Hi3519 Clock Driver"
>>         depends on ARCH_HISI || COMPILE_TEST
>> diff --git a/drivers/clk/hisilicon/Makefile b/drivers/clk/hisilicon/Makefile
>> index 5819891..4eec5e5 100644
>> --- a/drivers/clk/hisilicon/Makefile
>> +++ b/drivers/clk/hisilicon/Makefile
>> @@ -7,6 +7,7 @@ obj-y   += clk.o clkgate-separated.o clkdivider-hi6220.o
>>  obj-$(CONFIG_ARCH_HI3xxx)      += clk-hi3620.o
>>  obj-$(CONFIG_ARCH_HIP04)       += clk-hip04.o
>>  obj-$(CONFIG_ARCH_HIX5HD2)     += clk-hix5hd2.o
>> +obj-$(CONFIG_COMMON_CLK_HI3516CV300)   += crg-hi3516cv300.o
>>  obj-$(CONFIG_COMMON_CLK_HI3519)        += clk-hi3519.o
>>  obj-$(CONFIG_COMMON_CLK_HI3798CV200)   += crg-hi3798cv200.o
>>  obj-$(CONFIG_COMMON_CLK_HI6220)        += clk-hi6220.o
>> diff --git a/drivers/clk/hisilicon/crg-hi3516cv300.c b/drivers/clk/hisilicon/crg-hi3516cv300.c
>> new file mode 100644
>> index 0000000..2007123
>> --- /dev/null
>> +++ b/drivers/clk/hisilicon/crg-hi3516cv300.c
>> @@ -0,0 +1,330 @@
>> +/*
>> + * Hi3516CV300 Clock and Reset Generator Driver
>> + *
>> + * Copyright (c) 2016 HiSilicon Technologies Co., Ltd.
>> + *
>> + * This program is free software; you can redistribute it and/or modify
>> + * it under the terms of the GNU General Public License as published by
>> + * the Free Software Foundation; either version 2 of the License, or
>> + * (at your option) any later version.
>> + *
>> + * 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 <dt-bindings/clock/hi3516cv300-clock.h>
>> +#include <linux/clk-provider.h>
>> +#include <linux/module.h>
>> +#include <linux/of_device.h>
>> +#include <linux/platform_device.h>
>> +#include "clk.h"
>> +#include "crg.h"
>> +#include "reset.h"
>> +
>> +/* hi3516CV300 core CRG */
>> +#define HI3516CV300_INNER_CLK_OFFSET   64
>> +#define HI3516CV300_FIXED_3M           65
>> +#define HI3516CV300_FIXED_6M           66
>> +#define HI3516CV300_FIXED_24M          67
>> +#define HI3516CV300_FIXED_49P5         68
>> +#define HI3516CV300_FIXED_50M          69
>> +#define HI3516CV300_FIXED_83P3M                70
>> +#define HI3516CV300_FIXED_99M          71
>> +#define HI3516CV300_FIXED_100M         72
>> +#define HI3516CV300_FIXED_148P5M       73
>> +#define HI3516CV300_FIXED_198M         74
>> +#define HI3516CV300_FIXED_297M         75
>> +#define HI3516CV300_UART_MUX           76
>> +#define HI3516CV300_FMC_MUX            77
>> +#define HI3516CV300_MMC0_MUX           78
>> +#define HI3516CV300_MMC1_MUX           79
>> +#define HI3516CV300_MMC2_MUX           80
>> +#define HI3516CV300_MMC3_MUX           81
>> +#define HI3516CV300_PWM_MUX            82
>> +#define HI3516CV300_CRG_NR_CLKS                128
>> +
>> +static const struct hisi_fixed_rate_clock hi3516cv300_fixed_rate_clks[] = {
>> +       { HI3516CV300_FIXED_3M, "3m", NULL, 0, 3000000, },
>> +       { HI3516CV300_FIXED_6M, "6m", NULL, 0, 6000000, },
>> +       { HI3516CV300_FIXED_24M, "24m", NULL, 0, 24000000, },
>> +       { HI3516CV300_FIXED_49P5, "49.5m", NULL, 0, 49500000, },
>> +       { HI3516CV300_FIXED_50M, "50m", NULL, 0, 50000000, },
>> +       { HI3516CV300_FIXED_83P3M, "83.3m", NULL, 0, 83300000, },
>> +       { HI3516CV300_FIXED_99M, "99m", NULL, 0, 99000000, },
>> +       { HI3516CV300_FIXED_100M, "100m", NULL, 0, 100000000, },
>> +       { HI3516CV300_FIXED_148P5M, "148.5m", NULL, 0, 148500000, },
>> +       { HI3516CV300_FIXED_198M, "198m", NULL, 0, 198000000, },
>> +       { HI3516CV300_FIXED_297M, "297m", NULL, 0, 297000000, },
>> +       { HI3516CV300_APB_CLK, "apb", NULL, 0, 50000000, },
>> +};
>> +
>> +static const char *const uart_mux_p[] = {"24m", "6m"};
>> +static const char *const fmc_mux_p[] = {
>> +       "24m", "83.3m", "148.5m", "198m", "297m"
>> +};
>> +static const char *const mmc_mux_p[] = {"49.5m"};
>> +static const char *const mmc2_mux_p[] = {"99m", "49.5m"};
>> +static const char *const pwm_mux_p[] = {"3m", "50m", "24m", "24m"};
>> +
>> +static u32 uart_mux_table[] = {0, 1};
>> +static u32 fmc_mux_table[] = {0, 1, 2, 3, 4};
>> +static u32 mmc_mux_table[] = {0};
>> +static u32 mmc2_mux_table[] = {0, 2};
>> +static u32 pwm_mux_table[] = {0, 1, 2, 3};
>> +
>> +static const struct hisi_mux_clock hi3516cv300_mux_clks[] = {
>> +       { HI3516CV300_UART_MUX, "uart_mux", uart_mux_p, ARRAY_SIZE(uart_mux_p),
>> +               CLK_SET_RATE_PARENT, 0xe4, 19, 1, 0, uart_mux_table, },
>> +       { HI3516CV300_FMC_MUX, "fmc_mux", fmc_mux_p, ARRAY_SIZE(fmc_mux_p),
>> +               CLK_SET_RATE_PARENT, 0xc0, 2, 3, 0, fmc_mux_table, },
>> +       { HI3516CV300_MMC0_MUX, "mmc0_mux", mmc_mux_p, ARRAY_SIZE(mmc_mux_p),
>> +               CLK_SET_RATE_PARENT, 0xc4, 4, 2, 0, mmc_mux_table, },
>> +       { HI3516CV300_MMC1_MUX, "mmc1_mux", mmc_mux_p, ARRAY_SIZE(mmc_mux_p),
>> +               CLK_SET_RATE_PARENT, 0xc4, 12, 2, 0, mmc_mux_table, },
>> +       { HI3516CV300_MMC2_MUX, "mmc2_mux", mmc2_mux_p, ARRAY_SIZE(mmc2_mux_p),
>> +               CLK_SET_RATE_PARENT, 0xc4, 20, 2, 0, mmc2_mux_table, },
>> +       { HI3516CV300_MMC3_MUX, "mmc3_mux", mmc_mux_p, ARRAY_SIZE(mmc_mux_p),
>> +               CLK_SET_RATE_PARENT, 0xc8, 4, 2, 0, mmc_mux_table, },
>> +       { HI3516CV300_PWM_MUX, "pwm_mux", pwm_mux_p, ARRAY_SIZE(pwm_mux_p),
>> +               CLK_SET_RATE_PARENT, 0x38, 2, 2, 0, pwm_mux_table, },
>> +};
>> +
>> +static const struct hisi_gate_clock hi3516cv300_gate_clks[] = {
>> +
>> +       { HI3516CV300_UART0_CLK, "clk_uart0", "uart_mux", CLK_SET_RATE_PARENT,
>> +               0xe4, 15, 0, },
>> +       { HI3516CV300_UART1_CLK, "clk_uart1", "uart_mux", CLK_SET_RATE_PARENT,
>> +               0xe4, 16, 0, },
>> +       { HI3516CV300_UART2_CLK, "clk_uart2", "uart_mux", CLK_SET_RATE_PARENT,
>> +               0xe4, 17, 0, },
>> +
>> +       { HI3516CV300_SPI0_CLK, "clk_spi0", "100m", CLK_SET_RATE_PARENT,
>> +               0xe4, 13, 0, },
>> +       { HI3516CV300_SPI1_CLK, "clk_spi1", "100m", CLK_SET_RATE_PARENT,
>> +               0xe4, 14, 0, },
>> +
>> +       { HI3516CV300_FMC_CLK, "clk_fmc", "fmc_mux", CLK_SET_RATE_PARENT,
>> +               0xc0, 1, 0, },
>> +       { HI3516CV300_MMC0_CLK, "clk_mmc0", "mmc0_mux", CLK_SET_RATE_PARENT,
>> +               0xc4, 1, 0, },
>> +       { HI3516CV300_MMC1_CLK, "clk_mmc1", "mmc1_mux", CLK_SET_RATE_PARENT,
>> +               0xc4, 9, 0, },
>> +       { HI3516CV300_MMC2_CLK, "clk_mmc2", "mmc2_mux", CLK_SET_RATE_PARENT,
>> +               0xc4, 17, 0, },
>> +       { HI3516CV300_MMC3_CLK, "clk_mmc3", "mmc3_mux", CLK_SET_RATE_PARENT,
>> +               0xc8, 1, 0, },
>> +
>> +       { HI3516CV300_ETH_CLK, "clk_eth", NULL, 0, 0xec, 1, 0, },
>> +
>> +       { HI3516CV300_DMAC_CLK, "clk_dmac", NULL, 0, 0xd8, 5, 0, },
>> +       { HI3516CV300_PWM_CLK, "clk_pwm", "pwm_mux", CLK_SET_RATE_PARENT,
>> +               0x38, 1, 0, },
>> +
>> +       { HI3516CV300_USB2_BUS_CLK, "clk_usb2_bus", NULL, 0, 0xb8, 0, 0, },
>> +       { HI3516CV300_USB2_OHCI48M_CLK, "clk_usb2_ohci48m", NULL, 0,
>> +               0xb8, 1, 0, },
>> +       { HI3516CV300_USB2_OHCI12M_CLK, "clk_usb2_ohci12m", NULL, 0,
>> +               0xb8, 2, 0, },
>> +       { HI3516CV300_USB2_OTG_UTMI_CLK, "clk_usb2_otg_utmi", NULL, 0,
>> +               0xb8, 3, 0, },
>> +       { HI3516CV300_USB2_HST_PHY_CLK, "clk_usb2_hst_phy", NULL, 0,
>> +               0xb8, 4, 0, },
>> +       { HI3516CV300_USB2_UTMI0_CLK, "clk_usb2_utmi0", NULL, 0, 0xb8, 5, 0, },
>> +       { HI3516CV300_USB2_PHY_CLK, "clk_usb2_phy", NULL, 0, 0xb8, 7, 0, },
>> +};
>> +
>> +static struct hisi_clock_data *hi3516cv300_clk_register(
>> +               struct platform_device *pdev)
>> +{
>> +       struct hisi_clock_data *clk_data;
>> +       int ret;
>> +
>> +       clk_data = hisi_clk_alloc(pdev, HI3516CV300_CRG_NR_CLKS);
>> +       if (!clk_data)
>> +               return ERR_PTR(-ENOMEM);
>> +
>> +       ret = hisi_clk_register_fixed_rate(hi3516cv300_fixed_rate_clks,
>> +                       ARRAY_SIZE(hi3516cv300_fixed_rate_clks), clk_data);
>> +       if (ret)
>> +               return ERR_PTR(ret);
>> +
>> +       ret = hisi_clk_register_mux(hi3516cv300_mux_clks,
>> +                       ARRAY_SIZE(hi3516cv300_mux_clks), clk_data);
>> +       if (ret)
>> +               goto unregister_fixed_rate;
>> +
>> +       ret = hisi_clk_register_gate(hi3516cv300_gate_clks,
>> +                       ARRAY_SIZE(hi3516cv300_gate_clks), clk_data);
>> +       if (ret)
>> +               goto unregister_mux;
>> +
>> +       ret = of_clk_add_provider(pdev->dev.of_node,
>> +                       of_clk_src_onecell_get, &clk_data->clk_data);
>> +       if (ret)
>> +               goto unregister_gate;
>> +
>> +       return clk_data;
>> +
>> +unregister_gate:
>> +       hisi_clk_unregister_gate(hi3516cv300_gate_clks,
>> +                               ARRAY_SIZE(hi3516cv300_gate_clks), clk_data);
>> +unregister_mux:
>> +       hisi_clk_unregister_mux(hi3516cv300_mux_clks,
>> +                       ARRAY_SIZE(hi3516cv300_mux_clks), clk_data);
>> +unregister_fixed_rate:
>> +       hisi_clk_unregister_fixed_rate(hi3516cv300_fixed_rate_clks,
>> +                       ARRAY_SIZE(hi3516cv300_fixed_rate_clks), clk_data);
>> +       return ERR_PTR(ret);
>> +}
>> +
>> +static void hi3516cv300_clk_unregister(struct platform_device *pdev)
>> +{
>> +       struct hisi_crg_dev *crg = platform_get_drvdata(pdev);
>> +
>> +       of_clk_del_provider(pdev->dev.of_node);
>> +
>> +       hisi_clk_unregister_gate(hi3516cv300_gate_clks,
>> +                       ARRAY_SIZE(hi3516cv300_gate_clks), crg->clk_data);
>> +       hisi_clk_unregister_mux(hi3516cv300_mux_clks,
>> +                       ARRAY_SIZE(hi3516cv300_mux_clks), crg->clk_data);
>> +       hisi_clk_unregister_fixed_rate(hi3516cv300_fixed_rate_clks,
>> +                       ARRAY_SIZE(hi3516cv300_fixed_rate_clks), crg->clk_data);
>> +}
>> +
>> +static const struct hisi_crg_funcs hi3516cv300_crg_funcs = {
>> +       .register_clks = hi3516cv300_clk_register,
>> +       .unregister_clks = hi3516cv300_clk_unregister,
>> +};
>> +
>> +/* hi3516CV300 sysctrl CRG */
>> +#define HI3516CV300_SYSCTRL_NR_CLKS 16
>> +
>> +static const char *wdt_mux_p[] __initconst = { "3m", "apb" };
>> +static u32 wdt_mux_table[] = {0, 1};
>> +
>> +static const struct hisi_mux_clock hi3516cv300_sysctrl_mux_clks[] = {
>> +       { HI3516CV300_WDT_CLK, "wdt", wdt_mux_p, ARRAY_SIZE(wdt_mux_p),
>> +               CLK_SET_RATE_PARENT, 0x0, 23, 1, 0, wdt_mux_table, },
>> +};
>> +
>> +static struct hisi_clock_data *hi3516cv300_sysctrl_clk_register(
>> +               struct platform_device *pdev)
>> +{
>> +       struct hisi_clock_data *clk_data;
>> +       int ret;
>> +
>> +       clk_data = hisi_clk_alloc(pdev, HI3516CV300_SYSCTRL_NR_CLKS);
>> +       if (!clk_data)
>> +               return ERR_PTR(-ENOMEM);
>> +
>> +       ret = hisi_clk_register_mux(hi3516cv300_sysctrl_mux_clks,
>> +                       ARRAY_SIZE(hi3516cv300_sysctrl_mux_clks), clk_data);
>> +       if (ret)
>> +               return ERR_PTR(ret);
>> +
>> +
>> +       ret = of_clk_add_provider(pdev->dev.of_node,
>> +                       of_clk_src_onecell_get, &clk_data->clk_data);
>> +       if (ret)
>> +               goto unregister_mux;
>> +
>> +       return clk_data;
>> +
>> +unregister_mux:
>> +       hisi_clk_unregister_mux(hi3516cv300_sysctrl_mux_clks,
>> +                       ARRAY_SIZE(hi3516cv300_sysctrl_mux_clks), clk_data);
>> +       return ERR_PTR(ret);
>> +}
>> +
>> +static void hi3516cv300_sysctrl_clk_unregister(struct platform_device *pdev)
>> +{
>> +       struct hisi_crg_dev *crg = platform_get_drvdata(pdev);
>> +
>> +       of_clk_del_provider(pdev->dev.of_node);
>> +
>> +       hisi_clk_unregister_mux(hi3516cv300_sysctrl_mux_clks,
>> +                       ARRAY_SIZE(hi3516cv300_sysctrl_mux_clks),
>> +                       crg->clk_data);
>> +}
>> +
>> +static const struct hisi_crg_funcs hi3516cv300_sysctrl_funcs = {
>> +       .register_clks = hi3516cv300_sysctrl_clk_register,
>> +       .unregister_clks = hi3516cv300_sysctrl_clk_unregister,
>> +};
>> +
>> +static const struct of_device_id hi3516cv300_crg_match_table[] = {
>> +       {
>> +               .compatible = "hisilicon,hi3516cv300-crg",
>> +               .data = &hi3516cv300_crg_funcs
>> +       },
>> +       {
>> +               .compatible = "hisilicon,hi3516cv300-sysctrl",
>> +               .data = &hi3516cv300_sysctrl_funcs
>> +       },
>> +       { }
>> +};
>> +MODULE_DEVICE_TABLE(of, hi3516cv300_crg_match_table);
>> +
>> +static int hi3516cv300_crg_probe(struct platform_device *pdev)
>> +{
>> +       struct hisi_crg_dev *crg;
>> +
>> +       crg = devm_kmalloc(&pdev->dev, sizeof(*crg), GFP_KERNEL);
>> +       if (!crg)
>> +               return -ENOMEM;
>> +
>> +       crg->funcs = of_device_get_match_data(&pdev->dev);
>> +       if (!crg->funcs)
>> +               return -ENOENT;
>> +
>> +       crg->rstc = hisi_reset_init(pdev);
>> +       if (!crg->rstc)
>> +               return -ENOMEM;
>> +
>> +       crg->clk_data = crg->funcs->register_clks(pdev);
>> +       if (IS_ERR(crg->clk_data)) {
>> +               hisi_reset_exit(crg->rstc);
>> +               return PTR_ERR(crg->clk_data);
>> +       }
>> +
>> +       platform_set_drvdata(pdev, crg);
>> +       return 0;
>> +}
>> +
>> +static int hi3516cv300_crg_remove(struct platform_device *pdev)
>> +{
>> +       struct hisi_crg_dev *crg = platform_get_drvdata(pdev);
>> +
>> +       hisi_reset_exit(crg->rstc);
>> +       crg->funcs->unregister_clks(pdev);
>> +       return 0;
>> +}
>> +
>> +static struct platform_driver hi3516cv300_crg_driver = {
>> +       .probe          = hi3516cv300_crg_probe,
>> +       .remove         = hi3516cv300_crg_remove,
>> +       .driver         = {
>> +               .name   = "hi3516cv300-crg",
>> +               .of_match_table = hi3516cv300_crg_match_table,
>> +       },
>> +};
>> +
>> +static int __init hi3516cv300_crg_init(void)
>> +{
>> +       return platform_driver_register(&hi3516cv300_crg_driver);
>> +}
>> +core_initcall(hi3516cv300_crg_init);
>> +
>> +static void __exit hi3516cv300_crg_exit(void)
>> +{
>> +       platform_driver_unregister(&hi3516cv300_crg_driver);
>> +}
>> +module_exit(hi3516cv300_crg_exit);
>> +
>> +MODULE_LICENSE("GPL v2");
>> +MODULE_DESCRIPTION("HiSilicon Hi3516CV300 CRG Driver");
>> diff --git a/include/dt-bindings/clock/hi3516cv300-clock.h b/include/dt-bindings/clock/hi3516cv300-clock.h
>> new file mode 100644
>> index 0000000..5ba51b8
>> --- /dev/null
>> +++ b/include/dt-bindings/clock/hi3516cv300-clock.h
>> @@ -0,0 +1,48 @@
>> +/*
>> + * Copyright (c) 2016 HiSilicon Technologies Co., Ltd.
>> + *
>> + * This program is free software; you can redistribute it and/or modify
>> + * it under the terms of the GNU General Public License as published by
>> + * the Free Software Foundation; either version 2 of the License, or
>> + * (at your option) any later version.
>> + *
>> + * 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/>.
>> + */
>> +
>> +#ifndef __DTS_HI3516CV300_CLOCK_H
>> +#define __DTS_HI3516CV300_CLOCK_H
>> +
>> +/* hi3516CV300 core CRG */
>> +#define HI3516CV300_APB_CLK            0
>> +#define HI3516CV300_UART0_CLK          1
>> +#define HI3516CV300_UART1_CLK          2
>> +#define HI3516CV300_UART2_CLK          3
>> +#define HI3516CV300_SPI0_CLK           4
>> +#define HI3516CV300_SPI1_CLK           5
>> +#define HI3516CV300_FMC_CLK            6
>> +#define HI3516CV300_MMC0_CLK           7
>> +#define HI3516CV300_MMC1_CLK           8
>> +#define HI3516CV300_MMC2_CLK           9
>> +#define HI3516CV300_MMC3_CLK           10
>> +#define HI3516CV300_ETH_CLK            11
>> +#define HI3516CV300_ETH_MACIF_CLK      12
>> +#define HI3516CV300_DMAC_CLK           13
>> +#define HI3516CV300_PWM_CLK            14
>> +#define HI3516CV300_USB2_BUS_CLK       15
>> +#define HI3516CV300_USB2_OHCI48M_CLK   16
>> +#define HI3516CV300_USB2_OHCI12M_CLK   17
>> +#define HI3516CV300_USB2_OTG_UTMI_CLK  18
>> +#define HI3516CV300_USB2_HST_PHY_CLK   19
>> +#define HI3516CV300_USB2_UTMI0_CLK     20
>> +#define HI3516CV300_USB2_PHY_CLK       21
>> +
>> +/* hi3516CV300 sysctrl CRG */
>> +#define HI3516CV300_WDT_CLK            1
>> +
>> +#endif /* __DTS_HI3516CV300_CLOCK_H */
>> --
>> 1.9.1
>>
>> --
>> To unsubscribe from this list: send the line "unsubscribe devicetree" in
>> the body of a message to majordomo@vger.kernel.org
>> More majordomo info at  http://vger.kernel.org/majordomo-info.html
> 
> .
> 

^ permalink raw reply

* Re: [PATCH 4/6] dt-bindings: qcom: Add msm899(2/4) bindings
From: Rob Herring @ 2016-10-31  1:43 UTC (permalink / raw)
  To: Jeremy McNicoll
  Cc: linux-arm-msm-u79uwXL29TY76Z2rM5mHXA,
	linux-soc-u79uwXL29TY76Z2rM5mHXA,
	devicetree-u79uwXL29TY76Z2rM5mHXA,
	andy.gross-QSEj5FYQhm4dnm+yROfE0A, sboyd-sgV2jX0FEOL9JmXXK+q4OQ,
	arnd-r2nGTMty4D4, bjorn.andersson-QSEj5FYQhm4dnm+yROfE0A,
	mark.rutland-5wv7dgnIgG8, michael.scott-QSEj5FYQhm4dnm+yROfE0A
In-Reply-To: <1477394221-30963-5-git-send-email-jeremymc-H+wXaHxf7aLQT0dZR+AlfA@public.gmane.org>

On Tue, Oct 25, 2016 at 04:16:59AM -0700, Jeremy McNicoll wrote:
> From: Jeremy McNicoll <jmcnicol-H+wXaHxf7aLQT0dZR+AlfA@public.gmane.org>
> 
> Signed-off-by: Jeremy McNicoll <jeremymc-H+wXaHxf7aLQT0dZR+AlfA@public.gmane.org>
> ---
>  Documentation/devicetree/bindings/arm/qcom.txt | 2 ++
>  1 file changed, 2 insertions(+)

Acked-by: Rob Herring <robh-DgEjT+Ai2ygdnm+yROfE0A@public.gmane.org>
--
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 v1 1/3] dt-bindings: Document Broadcom OTP controller driver
From: Rob Herring @ 2016-10-31  1:38 UTC (permalink / raw)
  To: Jonathan Richardson
  Cc: Srinivas Kandagatla, Maxime Ripard, linux-arm-kernel,
	linux-kernel, devicetree, Mark Rutland, Scott Branden, Ray Jui,
	bcm-kernel-feedback-list, Jonathan Richardson, Scott Branden,
	Oza Pawandeep
In-Reply-To: <1477336324-10543-2-git-send-email-jonathan.richardson@broadcom.com>

On Mon, Oct 24, 2016 at 12:12:02PM -0700, Jonathan Richardson wrote:
> From: Jonathan Richardson <jonathar@broadcom.com>
> 
> Reviewed-by: Ray Jui <ray.jui@broadcom.com>
> Tested-by: Jonathan Richardson <jonathan.richardson@broadcom.com>
> Signed-off-by: Scott Branden <scott.branden@broadcom.com>
> Signed-off-by: Oza Pawandeep <oza@broadcom.com>
> Signed-off-by: Jonathan Richardson <jonathan.richardson@broadcom.com>
> ---
>  Documentation/devicetree/bindings/nvmem/brcm,ocotp.txt | 17 +++++++++++++++++
>  1 file changed, 17 insertions(+)
>  create mode 100644 Documentation/devicetree/bindings/nvmem/brcm,ocotp.txt
> 
> diff --git a/Documentation/devicetree/bindings/nvmem/brcm,ocotp.txt b/Documentation/devicetree/bindings/nvmem/brcm,ocotp.txt
> new file mode 100644
> index 0000000..6462e12
> --- /dev/null
> +++ b/Documentation/devicetree/bindings/nvmem/brcm,ocotp.txt
> @@ -0,0 +1,17 @@
> +Broadcom OTP memory controller
> +
> +Required Properties:
> +- compatible: "brcm,ocotp" for the first generation Broadcom OTPC which is used
> +  in Cygnus and supports 32 bit read/write. Use "brcm,ocotp-v2" for the second
> +  generation Broadcom OTPC which is used in SoC's such as Stingray and supports
> +  64-bit read/write.

These should be SoC specific. While I'd guess this block is simple 
enough, having the SoC can define what all the bits are. Yes, there is a 
binding to define those, but you may not use that.


> +- reg: Base address of the OTP controller.
> +- brcm,ocotp-size: Amount of memory available, in 32 bit words
> +
> +Example:
> +
> +otp: otp@0301c800 {
> +	compatible = "brcm,ocotp";
> +	reg = <0x0301c800 0x2c>;
> +	brcm,ocotp-size = <2048>;
> +};
> -- 
> 1.9.1
> 

^ permalink raw reply

* [PATCH 16/17] ASoC: add simple-graph-scu-card document
From: Kuninori Morimoto @ 2016-10-31  1:21 UTC (permalink / raw)
  To: Rob Herring, Mark Brown
  Cc: Linux-ALSA, Liam Girdwood, Simon, Laurent, Guennadi, Grant Likely,
	Frank Rowand, Linux-DT, Linux-Kernel
In-Reply-To: <87pomhba6r.wl%kuninori.morimoto.gx@renesas.com>


From: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>

Signed-off-by: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
---
 .../bindings/sound/simple-graph-scu-card.txt       | 63 ++++++++++++++++++++++
 1 file changed, 63 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/sound/simple-graph-scu-card.txt

diff --git a/Documentation/devicetree/bindings/sound/simple-graph-scu-card.txt b/Documentation/devicetree/bindings/sound/simple-graph-scu-card.txt
new file mode 100644
index 0000000..b5cfcac
--- /dev/null
+++ b/Documentation/devicetree/bindings/sound/simple-graph-scu-card.txt
@@ -0,0 +1,63 @@
+Simple-Graph-SCU-Card:
+
+Simple-Graph-SCU-Card specifies audio DAI connections of SoC <-> codec.
+It is based on common bindings for device graphs.
+see ${LINUX}/Documentation/devicetree/bindings/graph.txt
+
+Basically, Simple-Graph-SCU-Card is same as Simple-Card / Simple-Graph-Card.
+see ${LINUX}/Documentation/devicetree/bindings/sound/simple-card.txt
+    ${LINUX}/Documentation/devicetree/bindings/sound/simple-graph-card.txt
+
+Main difference is that Simple-Graph-SCU-Card can use multi CPU.
+
+Required properties:
+
+- compatible				: "asoc-simple-graph-scu-card";
+- simple-audio-card,routing		: see simple-card.txt
+
+Example
+
+ak4643: codec@12 {
+	compatible = "asahi-kasei,ak4643";
+	...
+	port {
+		ak4643_fe: endpoint@0 {
+			remote-endpoint = <&rsnd_fe>;
+			...
+		};
+		ak4643_be: endpoint@1 {
+			remote-endpoint = <&rsnd_be>;
+			...
+		};
+	};
+};
+
+rcar_sound {
+	...
+	ports {
+		compatible = "asoc-simple-graph-scu-card";
+		simple-audio-card,name = "graph-sound";
+		simple-audio-card,format = "left_j";
+		simple-audio-card,bitclock-master = <&rsnd_fe>;
+		simple-audio-card,frame-master = <&rsnd_fe>;
+		simple-audio-card,convert-rate = <48000>;
+		simple-audio-card,convert-channels = <2>;
+		simple-audio-card,prefix = "ak4642";
+		simple-audio-card,routing =
+				"ak4642 Playback", "DAI0 Playback",
+				"ak4642 Playback", "DAI1 Playback";
+
+		port@0 {
+			rsnd_fe: endpoint@0 {
+				remote-endpoint = <&ak4643_fe>;
+				...
+			};
+		};
+		port@1 {
+			rsnd_be: endpoint@1 {
+				remote-endpoint = <&ak4643_be>;
+				...
+			};
+		};
+	};
+};
-- 
1.9.1

^ permalink raw reply related

* [PATCH 17/17] ASoC: add simple-graph-scu-card support
From: Kuninori Morimoto @ 2016-10-31  1:20 UTC (permalink / raw)
  To: Rob Herring, Mark Brown
  Cc: Linux-ALSA, Liam Girdwood, Simon, Laurent, Guennadi, Grant Likely,
	Frank Rowand, Linux-DT, Linux-Kernel
In-Reply-To: <87pomhba6r.wl%kuninori.morimoto.gx@renesas.com>


From: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>

graph base DT binding are used on V4L2, and ALSA SoC is using different
style of DT. In case of simple case, ALSA SoC supports simple-card
driver.
In the future, V4L2 / ALSA will support HDMI, and then, DT bindings
between V4L2 / ALSA should be merged somehow.
Sometimes, we would like to use DPCM base simple-card on graph base DT.
This patch adds graph base DT binding of simple-scu-card

Signed-off-by: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
---
 sound/soc/generic/Kconfig                 |   8 +
 sound/soc/generic/Makefile                |   2 +
 sound/soc/generic/simple-graph-scu-card.c | 417 ++++++++++++++++++++++++++++++
 3 files changed, 427 insertions(+)
 create mode 100644 sound/soc/generic/simple-graph-scu-card.c

diff --git a/sound/soc/generic/Kconfig b/sound/soc/generic/Kconfig
index efefabd..fc11828 100644
--- a/sound/soc/generic/Kconfig
+++ b/sound/soc/generic/Kconfig
@@ -21,3 +21,11 @@ config SND_SIMPLE_GRAPH_CARD
 	select SND_SIMPLE_CARD_UTILS
 	help
 	  This option enables generic simple Graph sound card support
+
+config SND_SIMPLE_GRAPH_SCU_CARD
+	tristate "ASoC Simple Graph SCU sound card support"
+	depends on OF
+	select SND_SIMPLE_CARD_UTILS
+	help
+	  This option enables generic simple Graph SCU sound card support.
+	  It supports DPCM of multi CPU single Codec ststem.
diff --git a/sound/soc/generic/Makefile b/sound/soc/generic/Makefile
index 94eb6f1..fd75b55 100644
--- a/sound/soc/generic/Makefile
+++ b/sound/soc/generic/Makefile
@@ -2,8 +2,10 @@ snd-soc-simple-card-utils-objs	:= simple-card-utils.o
 snd-soc-simple-card-objs	:= simple-card.o
 snd-soc-simple-scu-card-objs	:= simple-scu-card.o
 snd-soc-simple-graph-card-objs	:= simple-graph-card.o
+snd-soc-simple-graph-scu-card-objs	:= simple-graph-scu-card.o
 
 obj-$(CONFIG_SND_SIMPLE_CARD_UTILS)	+= snd-soc-simple-card-utils.o
 obj-$(CONFIG_SND_SIMPLE_CARD)		+= snd-soc-simple-card.o
 obj-$(CONFIG_SND_SIMPLE_SCU_CARD)	+= snd-soc-simple-scu-card.o
 obj-$(CONFIG_SND_SIMPLE_GRAPH_CARD)	+= snd-soc-simple-graph-card.o
+obj-$(CONFIG_SND_SIMPLE_GRAPH_SCU_CARD)	+= snd-soc-simple-graph-scu-card.o
diff --git a/sound/soc/generic/simple-graph-scu-card.c b/sound/soc/generic/simple-graph-scu-card.c
new file mode 100644
index 0000000..39a5019
--- /dev/null
+++ b/sound/soc/generic/simple-graph-scu-card.c
@@ -0,0 +1,417 @@
+/*
+ * ASoC simple graph SCU sound card support
+ *
+ * Copyright (C) 2016 Renesas Solutions Corp.
+ * Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
+ *
+ * based on
+ *	${LINUX}/sound/soc/generic/simple-graph-card.c
+ *	${LINUX}/sound/soc/generic/simple-scu-card.c
+ *
+ * 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.
+ */
+#include <linux/clk.h>
+#include <linux/device.h>
+#include <linux/gpio.h>
+#include <linux/module.h>
+#include <linux/of.h>
+#include <linux/of_device.h>
+#include <linux/of_gpio.h>
+#include <linux/of_graph.h>
+#include <linux/platform_device.h>
+#include <linux/string.h>
+#include <sound/jack.h>
+#include <sound/simple_card_utils.h>
+
+struct simple_card_data {
+	struct snd_soc_card snd_card;
+	struct snd_soc_codec_conf codec_conf;
+	struct asoc_simple_dai *dai_props;
+	struct snd_soc_dai_link *dai_link;
+	u32 convert_rate;
+	u32 convert_channels;
+};
+
+#define simple_priv_to_dev(priv) ((priv)->snd_card.dev)
+#define simple_priv_to_link(priv, i) ((priv)->snd_card.dai_link + (i))
+#define simple_priv_to_props(priv, i) ((priv)->dai_props + (i))
+
+#define PREFIX	"simple-audio-card,"
+
+static int asoc_simple_card_startup(struct snd_pcm_substream *substream)
+{
+	struct snd_soc_pcm_runtime *rtd = substream->private_data;
+	struct simple_card_data *priv =	snd_soc_card_get_drvdata(rtd->card);
+	struct asoc_simple_dai *dai_props =
+		simple_priv_to_props(priv, rtd->num);
+
+	return clk_prepare_enable(dai_props->clk);
+}
+
+static void asoc_simple_card_shutdown(struct snd_pcm_substream *substream)
+{
+	struct snd_soc_pcm_runtime *rtd = substream->private_data;
+	struct simple_card_data *priv =	snd_soc_card_get_drvdata(rtd->card);
+	struct asoc_simple_dai *dai_props =
+		simple_priv_to_props(priv, rtd->num);
+
+	clk_disable_unprepare(dai_props->clk);
+}
+
+static struct snd_soc_ops asoc_simple_card_ops = {
+	.startup = asoc_simple_card_startup,
+	.shutdown = asoc_simple_card_shutdown,
+};
+
+static int asoc_simple_card_dai_init(struct snd_soc_pcm_runtime *rtd)
+{
+	struct simple_card_data *priv =	snd_soc_card_get_drvdata(rtd->card);
+	struct snd_soc_dai *dai;
+	struct snd_soc_dai_link *dai_link;
+	struct asoc_simple_dai *dai_props;
+	int num = rtd->num;
+
+	dai_link	= simple_priv_to_link(priv, num);
+	dai_props	= simple_priv_to_props(priv, num);
+	dai		= dai_link->dynamic ?
+				rtd->cpu_dai :
+				rtd->codec_dai;
+
+	return asoc_simple_card_init_dai(dai, dai_props);
+}
+
+static int asoc_simple_card_be_hw_params_fixup(struct snd_soc_pcm_runtime *rtd,
+					       struct snd_pcm_hw_params *params)
+{
+	struct simple_card_data *priv = snd_soc_card_get_drvdata(rtd->card);
+	struct snd_interval *rate = hw_param_interval(params,
+						      SNDRV_PCM_HW_PARAM_RATE);
+	struct snd_interval *channels = hw_param_interval(params,
+							  SNDRV_PCM_HW_PARAM_CHANNELS);
+
+	if (priv->convert_rate)
+		rate->min =
+		rate->max = priv->convert_rate;
+
+	if (priv->convert_channels)
+		channels->min =
+		channels->max = priv->convert_channels;
+
+	return 0;
+}
+
+static int asoc_simple_card_dai_link_of(struct device_node *port,
+					struct device_node *ep,
+					struct simple_card_data *priv,
+					unsigned int daifmt,
+					int idx, int is_fe)
+{
+	struct device *dev = simple_priv_to_dev(priv);
+	struct snd_soc_dai_link *dai_link = simple_priv_to_link(priv, idx);
+	struct asoc_simple_dai *dai_props = simple_priv_to_props(priv, idx);
+	int ret;
+
+	if (is_fe) {
+		/* BE is dummy */
+		dai_link->codec_of_node		= NULL;
+		dai_link->codec_dai_name	= "snd-soc-dummy-dai";
+		dai_link->codec_name		= "snd-soc-dummy";
+
+		/* FE settings */
+		dai_link->dynamic		= 1;
+		dai_link->dpcm_merged_format	= 1;
+
+		ret = asoc_simple_card_parse_graph_cpu(ep, dai_link);
+		if (ret)
+			return ret;
+
+		ret = asoc_simple_card_parse_clk_cpu(ep, dai_link, dai_props);
+		if (ret < 0)
+			return ret;
+
+		ret = asoc_simple_card_set_dailink_name(dev, dai_link,
+							"fe.%s",
+							dai_link->cpu_dai_name);
+		if (ret < 0)
+			return ret;
+
+		/* snd_card.num_links includes Codec */
+		asoc_simple_card_canonicalize_cpu(dai_link,
+					(priv->snd_card.num_links -1) == 1);
+	} else {
+		/* FE is dummy */
+		dai_link->cpu_of_node		= NULL;
+		dai_link->cpu_dai_name		= "snd-soc-dummy-dai";
+		dai_link->cpu_name		= "snd-soc-dummy";
+
+		/* BE settings */
+		dai_link->no_pcm		= 1;
+		dai_link->be_hw_params_fixup	= asoc_simple_card_be_hw_params_fixup;
+
+		ret = asoc_simple_card_parse_graph_codec(ep, dai_link);
+		if (ret < 0)
+			return ret;
+
+		ret = asoc_simple_card_parse_clk_codec(ep, dai_link, dai_props);
+		if (ret < 0)
+			return ret;
+
+		ret = asoc_simple_card_set_dailink_name(dev, dai_link,
+							"be.%s",
+							dai_link->codec_dai_name);
+		if (ret < 0)
+			return ret;
+
+		snd_soc_of_parse_audio_prefix_from_node(&priv->snd_card,
+							port,
+							&priv->codec_conf,
+							dai_link->codec_of_node,
+							PREFIX "prefix");
+	}
+
+	ret = snd_soc_of_parse_tdm_slot(ep,
+					&dai_props->tx_slot_mask,
+					&dai_props->rx_slot_mask,
+					&dai_props->slots,
+					&dai_props->slot_width);
+	if (ret)
+		return ret;
+
+	ret = asoc_simple_card_canonicalize_dailink(dai_link);
+	if (ret < 0)
+		return ret;
+
+	dai_link->dai_fmt		= daifmt;
+	dai_link->dpcm_playback		= 1;
+	dai_link->dpcm_capture		= 1;
+	dai_link->ops			= &asoc_simple_card_ops;
+	dai_link->init			= asoc_simple_card_dai_init;
+
+	dev_dbg(dev, "\t%s / %04x / %d\n",
+		dai_link->name,
+		dai_link->dai_fmt,
+		dai_props->sysclk);
+
+	return 0;
+}
+
+static int asoc_simple_card_parse_of(struct device_node *node,
+				     struct simple_card_data *priv)
+{
+	struct device *dev = simple_priv_to_dev(priv);
+	struct device *cpu_dev = dev->parent;
+	struct device_node *ports = of_graph_get_top_port(cpu_dev);
+	struct snd_soc_card *card = &priv->snd_card;
+	struct device_node *port, *cpu_ep, *r_cpu_ep, *codec_ep;
+	unsigned int daifmt = 0;
+	int i, ret, done;
+
+	if (!node)
+		return -EINVAL;
+
+	ret = snd_soc_of_parse_audio_routing_from_node(&priv->snd_card,
+						       ports, PREFIX "routing");
+	if (ret)
+		return ret;
+
+	/* sampling rate convert */
+	of_property_read_u32(ports, PREFIX "convert-rate",
+			     &priv->convert_rate);
+
+	/* channels transfer */
+	of_property_read_u32(ports, PREFIX "convert-channels",
+			     &priv->convert_channels);
+
+	/*
+	 * it supports multi CPU, single CODEC only here.
+	 */
+
+	/* find 1st codec */
+	done = 0;
+	for_each_of_port(node, port) {
+		/* keep for_each for of_node_get/of_node_put */
+		if (done)
+			continue;
+
+		for_each_of_endpoint_in_port(port, cpu_ep) {
+			/* keep for_each for of_node_get/of_node_put */
+			if (done)
+				continue;
+
+			codec_ep = of_graph_get_remote_endpoint(cpu_ep);
+			r_cpu_ep = of_graph_get_remote_endpoint(codec_ep);
+			of_node_put(codec_ep);
+			of_node_put(r_cpu_ep);
+			if (cpu_ep != r_cpu_ep) {
+				ret = -EINVAL;
+				goto parse_of_err;
+			}
+
+			ret = asoc_simple_card_parse_daifmt(dev,
+							    ports, codec_ep,
+							    PREFIX, &daifmt);
+			if (ret < 0)
+				goto parse_of_err;
+
+			done = 1;
+		}
+	}
+
+	/* Front-End (= CPU) */
+	i = 0;
+	for_each_of_port(node, port) {
+		for_each_of_endpoint_in_port(port, cpu_ep) {
+			ret = asoc_simple_card_dai_link_of(
+				port, cpu_ep, priv, daifmt, i, 1);
+			if (ret < 0)
+				goto parse_of_err;
+			i++;
+		}
+	}
+
+	/* Back-End (= Codec) */
+	done = 0;
+	for_each_of_port(node, port) {
+		/* keep for_each for of_node_get/of_node_put */
+		if (done)
+			continue;
+
+		for_each_of_endpoint_in_port(port, cpu_ep) {
+			/* keep for_each for of_node_get/of_node_put */
+			if (done)
+				continue;
+
+			codec_ep = of_graph_get_remote_endpoint(cpu_ep);
+			r_cpu_ep = of_graph_get_remote_endpoint(codec_ep);
+			of_node_put(codec_ep);
+			of_node_put(r_cpu_ep);
+			if (cpu_ep != r_cpu_ep) {
+				ret = -EINVAL;
+				goto parse_of_err;
+			}
+
+			ret = asoc_simple_card_dai_link_of(
+				port, codec_ep, priv, daifmt, i, 0);
+			if (ret < 0)
+				goto parse_of_err;
+			i++;
+
+			done = 1;
+		}
+	}
+
+	ret = asoc_simple_card_parse_card_name(card, ports, PREFIX);
+	if (ret)
+		return ret;
+
+	dev_dbg(dev, "New card: %s\n",
+		priv->snd_card.name ? priv->snd_card.name : "");
+	dev_dbg(dev, "convert_rate     %d\n", priv->convert_rate);
+	dev_dbg(dev, "convert_channels %d\n", priv->convert_channels);
+
+	return 0;
+parse_of_err:
+	of_node_put(port);
+	of_node_put(cpu_ep);
+
+	return ret;
+}
+
+static int asoc_simple_card_probe(struct platform_device *pdev)
+{
+	struct simple_card_data *priv;
+	struct snd_soc_dai_link *dai_link;
+	struct asoc_simple_dai *dai_props;
+	struct device *dev = &pdev->dev;
+	struct device *cpu_dev = pdev->dev.parent;
+	struct device_node *cpu_node = cpu_dev->of_node;
+	struct asoc_simple_graph_card_info *info = pdev->dev.platform_data;
+	int num, ret;
+
+	/* Allocate the private data and the DAI link array */
+	priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL);
+	if (!priv)
+		return -ENOMEM;
+
+	/* it supports multi CPU, single CODEC only here */
+	num = info->endpoint_num + 1; /* +1 for Codec */
+
+	dai_props = devm_kzalloc(dev, sizeof(*dai_props) * num, GFP_KERNEL);
+	dai_link  = devm_kzalloc(dev, sizeof(*dai_link)  * num, GFP_KERNEL);
+	if (!dai_props || !dai_link)
+		return -ENOMEM;
+
+	priv->dai_props			= dai_props;
+	priv->dai_link			= dai_link;
+
+	/* Init snd_soc_card */
+	priv->snd_card.owner		= THIS_MODULE;
+	priv->snd_card.dev		= dev;
+	priv->snd_card.dai_link		= priv->dai_link;
+	priv->snd_card.num_links	= num;
+	priv->snd_card.codec_conf	= &priv->codec_conf;
+	priv->snd_card.num_configs	= 1;
+
+	ret = asoc_simple_card_parse_of(cpu_node, priv);
+	if (ret < 0) {
+		if (ret != -EPROBE_DEFER)
+			dev_err(dev, "parse error %d\n", ret);
+		goto err;
+	}
+
+	/*
+	 * FIXME
+	 *
+	 * This driver is assuming that it will be called from
+	 * asoc_simple_card_try_to_probe_graph_card() which
+	 * is using platform_device_register_full().
+	 * This means it is not came from DT. But this driver itself
+	 * will be used as part of ALSA SoC (= sound card).
+	 * Because of these background, it might fail in
+	 * snd_pcm_lib_malloc_pages() on .hw_params.
+	 * Because, noone cares its dma_ops, and result of get_dma_ops()
+	 * is based on its architecture.
+	 * So, it should call arch_setup_dma_ops() from somewhere,
+	 * otherwise, for example, ARM is no problem, but ARM64 will be fail.
+	 * But, of_platform_device_xxx() are not good solution today.
+	 * This driver calls it by itself here. Please fixme
+	 * see also
+	 * linux/sound/soc/generic/simple-card-utils.c ::
+	 *	asoc_simple_card_try_to_probe_graph_card()
+	 */
+	of_dma_configure(dev, dev->of_node);
+
+	snd_soc_card_set_drvdata(&priv->snd_card, priv);
+
+	ret = devm_snd_soc_register_card(dev, &priv->snd_card);
+	if (ret >= 0)
+		return ret;
+err:
+	asoc_simple_card_clean_reference(&priv->snd_card);
+
+	return ret;
+}
+
+static int asoc_simple_card_remove(struct platform_device *pdev)
+{
+	struct snd_soc_card *card = platform_get_drvdata(pdev);
+	struct simple_card_data *priv = snd_soc_card_get_drvdata(card);
+
+	return asoc_simple_card_clean_reference(&priv->snd_card);
+}
+
+static struct platform_driver asoc_simple_card = {
+	.driver = {
+		.name = "asoc-simple-graph-scu-card",
+	},
+	.probe = asoc_simple_card_probe,
+	.remove = asoc_simple_card_remove,
+};
+module_platform_driver(asoc_simple_card);
+
+MODULE_ALIAS("platform:asoc-simple-graph-scu-card");
+MODULE_LICENSE("GPL v2");
+MODULE_DESCRIPTION("ASoC Simple Graph SCU Sound Card");
+MODULE_AUTHOR("Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>");
-- 
1.9.1

^ permalink raw reply related

* [PATCH 15/17] ASoC: add simple-graph-card support
From: Kuninori Morimoto @ 2016-10-31  1:20 UTC (permalink / raw)
  To: Rob Herring, Mark Brown
  Cc: Linux-ALSA, Liam Girdwood, Simon, Laurent, Guennadi, Grant Likely,
	Frank Rowand, Linux-DT, Linux-Kernel
In-Reply-To: <87pomhba6r.wl%kuninori.morimoto.gx@renesas.com>


From: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>

graph base DT binding are used on V4L2, and ALSA SoC is using different
style of DT. In case of simple case, ALSA SoC supports simple-card
driver.
In the future, V4L2 / ALSA will support HDMI, and then, DT bindings
between V4L2 / ALSA should be merged somehow.
This patch adds graph base DT binding with simple-card style

Signed-off-by: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
---
 sound/soc/generic/Kconfig             |   7 +
 sound/soc/generic/Makefile            |   2 +
 sound/soc/generic/simple-graph-card.c | 462 ++++++++++++++++++++++++++++++++++
 3 files changed, 471 insertions(+)
 create mode 100644 sound/soc/generic/simple-graph-card.c

diff --git a/sound/soc/generic/Kconfig b/sound/soc/generic/Kconfig
index d023959..efefabd 100644
--- a/sound/soc/generic/Kconfig
+++ b/sound/soc/generic/Kconfig
@@ -14,3 +14,10 @@ config SND_SIMPLE_SCU_CARD
 	help
 	  This option enables generic simple SCU sound card support.
 	  It supports DPCM of multi CPU single Codec system.
+
+config SND_SIMPLE_GRAPH_CARD
+	tristate "ASoC Simple Graph sound card support"
+	depends on OF
+	select SND_SIMPLE_CARD_UTILS
+	help
+	  This option enables generic simple Graph sound card support
diff --git a/sound/soc/generic/Makefile b/sound/soc/generic/Makefile
index ee750f3..94eb6f1 100644
--- a/sound/soc/generic/Makefile
+++ b/sound/soc/generic/Makefile
@@ -1,7 +1,9 @@
 snd-soc-simple-card-utils-objs	:= simple-card-utils.o
 snd-soc-simple-card-objs	:= simple-card.o
 snd-soc-simple-scu-card-objs	:= simple-scu-card.o
+snd-soc-simple-graph-card-objs	:= simple-graph-card.o
 
 obj-$(CONFIG_SND_SIMPLE_CARD_UTILS)	+= snd-soc-simple-card-utils.o
 obj-$(CONFIG_SND_SIMPLE_CARD)		+= snd-soc-simple-card.o
 obj-$(CONFIG_SND_SIMPLE_SCU_CARD)	+= snd-soc-simple-scu-card.o
+obj-$(CONFIG_SND_SIMPLE_GRAPH_CARD)	+= snd-soc-simple-graph-card.o
diff --git a/sound/soc/generic/simple-graph-card.c b/sound/soc/generic/simple-graph-card.c
new file mode 100644
index 0000000..a98b13f
--- /dev/null
+++ b/sound/soc/generic/simple-graph-card.c
@@ -0,0 +1,462 @@
+/*
+ * ASoC simple graph sound card support
+ *
+ * Copyright (C) 2016 Renesas Solutions Corp.
+ * Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
+ *
+ * based on ${LINUX}/sound/soc/generic/simple-card.c
+ *
+ * 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.
+ */
+#include <linux/clk.h>
+#include <linux/device.h>
+#include <linux/gpio.h>
+#include <linux/module.h>
+#include <linux/of.h>
+#include <linux/of_device.h>
+#include <linux/of_gpio.h>
+#include <linux/of_graph.h>
+#include <linux/platform_device.h>
+#include <linux/string.h>
+#include <sound/jack.h>
+#include <sound/simple_card_utils.h>
+
+struct asoc_simple_jack {
+	struct snd_soc_jack jack;
+	struct snd_soc_jack_pin pin;
+	struct snd_soc_jack_gpio gpio;
+};
+
+struct simple_card_data {
+	struct snd_soc_card snd_card;
+	struct simple_dai_props {
+		struct asoc_simple_dai cpu_dai;
+		struct asoc_simple_dai codec_dai;
+		unsigned int mclk_fs;
+	} *dai_props;
+	struct asoc_simple_jack hp_jack;
+	struct asoc_simple_jack mic_jack;
+	struct snd_soc_dai_link *dai_link;
+	unsigned int mclk_fs;
+};
+
+#define simple_priv_to_dev(priv) ((priv)->snd_card.dev)
+#define simple_priv_to_link(priv, i) ((priv)->snd_card.dai_link + (i))
+#define simple_priv_to_props(priv, i) ((priv)->dai_props + (i))
+
+#define PREFIX	"simple-audio-card,"
+
+#define asoc_simple_card_init_hp(card, node, sjack, prefix)	\
+	asoc_simple_card_init_jack(card, node, sjack, 1, prefix)
+#define asoc_simple_card_init_mic(card, node, sjack, prefix)	\
+	asoc_simple_card_init_jack(card, node, sjack, 0, prefix)
+static int asoc_simple_card_init_jack(struct snd_soc_card *card,
+				      struct device_node *node,
+				      struct asoc_simple_jack *sjack,
+				      int is_hp, char *prefix)
+{
+	enum of_gpio_flags flags;
+	char prop[128];
+	char *pin_name;
+	char *gpio_name;
+	int mask;
+	int det;
+
+	sjack->gpio.gpio = -ENOENT;
+
+	if (is_hp) {
+		snprintf(prop, sizeof(prop), "%shp-det-gpio", prefix);
+		pin_name	= "Headphones";
+		gpio_name	= "Headphone detection";
+		mask		= SND_JACK_HEADPHONE;
+	} else {
+		snprintf(prop, sizeof(prop), "%smic-det-gpio", prefix);
+		pin_name	= "Mic Jack";
+		gpio_name	= "Mic detection";
+		mask		= SND_JACK_MICROPHONE;
+	}
+
+	det = of_get_named_gpio_flags(node, prop, 0, &flags);
+	if (det == -EPROBE_DEFER)
+		return -EPROBE_DEFER;
+
+	if (gpio_is_valid(det)) {
+		sjack->pin.pin		= pin_name;
+		sjack->pin.mask		= mask;
+
+		sjack->gpio.name	= gpio_name;
+		sjack->gpio.report	= mask;
+		sjack->gpio.gpio	= det;
+		sjack->gpio.invert	= !!(flags & OF_GPIO_ACTIVE_LOW);
+		sjack->gpio.debounce_time = 150;
+
+		snd_soc_card_jack_new(card, pin_name, mask,
+				      &sjack->jack,
+				      &sjack->pin, 1);
+
+		snd_soc_jack_add_gpios(&sjack->jack, 1,
+				       &sjack->gpio);
+	}
+
+	return 0;
+}
+
+static void asoc_simple_card_remove_jack(struct asoc_simple_jack *sjack)
+{
+	if (gpio_is_valid(sjack->gpio.gpio))
+		snd_soc_jack_free_gpios(&sjack->jack, 1, &sjack->gpio);
+}
+
+static int asoc_simple_card_startup(struct snd_pcm_substream *substream)
+{
+	struct snd_soc_pcm_runtime *rtd = substream->private_data;
+	struct simple_card_data *priv =	snd_soc_card_get_drvdata(rtd->card);
+	struct simple_dai_props *dai_props =
+		simple_priv_to_props(priv, rtd->num);
+	int ret;
+
+	ret = clk_prepare_enable(dai_props->cpu_dai.clk);
+	if (ret)
+		return ret;
+
+	ret = clk_prepare_enable(dai_props->codec_dai.clk);
+	if (ret)
+		clk_disable_unprepare(dai_props->cpu_dai.clk);
+
+	return ret;
+}
+
+static void asoc_simple_card_shutdown(struct snd_pcm_substream *substream)
+{
+	struct snd_soc_pcm_runtime *rtd = substream->private_data;
+	struct simple_card_data *priv =	snd_soc_card_get_drvdata(rtd->card);
+	struct simple_dai_props *dai_props =
+		simple_priv_to_props(priv, rtd->num);
+
+	clk_disable_unprepare(dai_props->cpu_dai.clk);
+
+	clk_disable_unprepare(dai_props->codec_dai.clk);
+}
+
+static int asoc_simple_card_hw_params(struct snd_pcm_substream *substream,
+				      struct snd_pcm_hw_params *params)
+{
+	struct snd_soc_pcm_runtime *rtd = substream->private_data;
+	struct snd_soc_dai *codec_dai = rtd->codec_dai;
+	struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
+	struct simple_card_data *priv = snd_soc_card_get_drvdata(rtd->card);
+	struct simple_dai_props *dai_props =
+		simple_priv_to_props(priv, rtd->num);
+	unsigned int mclk, mclk_fs = 0;
+	int ret = 0;
+
+	if (priv->mclk_fs)
+		mclk_fs = priv->mclk_fs;
+	else if (dai_props->mclk_fs)
+		mclk_fs = dai_props->mclk_fs;
+
+	if (mclk_fs) {
+		mclk = params_rate(params) * mclk_fs;
+		ret = snd_soc_dai_set_sysclk(codec_dai, 0, mclk,
+					     SND_SOC_CLOCK_IN);
+		if (ret && ret != -ENOTSUPP)
+			goto err;
+
+		ret = snd_soc_dai_set_sysclk(cpu_dai, 0, mclk,
+					     SND_SOC_CLOCK_OUT);
+		if (ret && ret != -ENOTSUPP)
+			goto err;
+	}
+	return 0;
+err:
+	return ret;
+}
+
+static struct snd_soc_ops asoc_simple_card_ops = {
+	.startup = asoc_simple_card_startup,
+	.shutdown = asoc_simple_card_shutdown,
+	.hw_params = asoc_simple_card_hw_params,
+};
+
+static int asoc_simple_card_dai_init(struct snd_soc_pcm_runtime *rtd)
+{
+	struct simple_card_data *priv =	snd_soc_card_get_drvdata(rtd->card);
+	struct device *dev = simple_priv_to_dev(priv);
+	struct device *cpu_dev = dev->parent;
+	struct snd_soc_dai *codec = rtd->codec_dai;
+	struct snd_soc_dai *cpu = rtd->cpu_dai;
+	struct snd_soc_card *card = rtd->card;
+	struct simple_dai_props *dai_props =
+		simple_priv_to_props(priv, rtd->num);
+	struct device_node *cpu_port = of_graph_get_top_port(cpu_dev);
+	int ret;
+
+	ret = asoc_simple_card_init_dai(codec, &dai_props->codec_dai);
+	if (ret < 0)
+		return ret;
+
+	ret = asoc_simple_card_init_dai(cpu, &dai_props->cpu_dai);
+	if (ret < 0)
+		return ret;
+
+	ret = asoc_simple_card_init_hp(card, cpu_port, &priv->hp_jack, PREFIX);
+	if (ret < 0)
+		return ret;
+
+	ret = asoc_simple_card_init_mic(card, cpu_port, &priv->hp_jack, PREFIX);
+	if (ret < 0)
+		return ret;
+
+	return 0;
+}
+
+static int asoc_simple_card_dai_link_of(struct device_node *cpu_ep,
+					struct simple_card_data *priv,
+					int idx)
+{
+	struct device *dev = simple_priv_to_dev(priv);
+	struct snd_soc_dai_link *dai_link = simple_priv_to_link(priv, idx);
+	struct simple_dai_props *dai_props = simple_priv_to_props(priv, idx);
+	struct asoc_simple_dai *cpu_dai = &dai_props->cpu_dai;
+	struct asoc_simple_dai *codec_dai = &dai_props->codec_dai;
+	struct device_node *cpu_port;
+	struct device_node *cpu_remote_ep;
+	struct device_node *codec_ep;
+	int ret;
+
+	codec_ep	= of_graph_get_remote_endpoint(cpu_ep);
+	cpu_remote_ep	= of_graph_get_remote_endpoint(codec_ep);
+
+	if (cpu_ep != cpu_remote_ep) {
+		dev_err(dev, "endpoint parse error\n");
+		ret = -EINVAL;
+		goto dai_link_of_err;
+	}
+
+	cpu_port	= cpu_ep->parent;
+
+	ret = asoc_simple_card_parse_daifmt(dev, cpu_port, codec_ep,
+					    PREFIX, &dai_link->dai_fmt);
+	if (ret < 0)
+		goto dai_link_of_err;
+
+	of_property_read_u32(cpu_port, "mclk-fs", &dai_props->mclk_fs);
+
+	ret = asoc_simple_card_parse_graph_cpu(cpu_ep, dai_link);
+	if (ret < 0)
+		goto dai_link_of_err;
+
+	ret = asoc_simple_card_parse_graph_codec(codec_ep, dai_link);
+	if (ret < 0)
+		goto dai_link_of_err;
+
+	ret = snd_soc_of_parse_tdm_slot(cpu_ep,
+					&cpu_dai->tx_slot_mask,
+					&cpu_dai->rx_slot_mask,
+					&cpu_dai->slots,
+					&cpu_dai->slot_width);
+	if (ret < 0)
+		goto dai_link_of_err;
+
+	ret = snd_soc_of_parse_tdm_slot(codec_ep,
+					&codec_dai->tx_slot_mask,
+					&codec_dai->rx_slot_mask,
+					&codec_dai->slots,
+					&codec_dai->slot_width);
+	if (ret < 0)
+		goto dai_link_of_err;
+
+	ret = asoc_simple_card_parse_clk_cpu(cpu_ep, dai_link, cpu_dai);
+	if (ret < 0)
+		goto dai_link_of_err;
+
+	ret = asoc_simple_card_parse_clk_codec(codec_ep, dai_link, codec_dai);
+	if (ret < 0)
+		goto dai_link_of_err;
+
+	ret = asoc_simple_card_canonicalize_dailink(dai_link);
+	if (ret < 0)
+		goto dai_link_of_err;
+
+	ret = asoc_simple_card_set_dailink_name(dev, dai_link,
+						"%s-%s",
+						dai_link->cpu_dai_name,
+						dai_link->codec_dai_name);
+	if (ret < 0)
+		goto dai_link_of_err;
+
+	dai_link->ops = &asoc_simple_card_ops;
+	dai_link->init = asoc_simple_card_dai_init;
+
+	dev_dbg(dev, "\tname : %s\n", dai_link->stream_name);
+	dev_dbg(dev, "\tformat : %04x\n", dai_link->dai_fmt);
+	dev_dbg(dev, "\tcpu : %s / %d\n",
+		dai_link->cpu_dai_name,
+		dai_props->cpu_dai.sysclk);
+	dev_dbg(dev, "\tcodec : %s / %d\n",
+		dai_link->codec_dai_name,
+		dai_props->codec_dai.sysclk);
+
+	asoc_simple_card_canonicalize_cpu(dai_link,
+					  priv->snd_card.num_links == 1);
+
+dai_link_of_err:
+	of_node_put(codec_ep);
+	of_node_put(cpu_remote_ep);
+
+	return ret;
+}
+
+static int asoc_simple_card_parse_of(struct device_node *node,
+				     struct simple_card_data *priv)
+{
+	struct device *dev = simple_priv_to_dev(priv);
+	struct device *cpu_dev = dev->parent;
+	struct device_node *top_port = of_graph_get_top_port(cpu_dev);
+	struct snd_soc_card *card = &priv->snd_card;
+	struct device_node *port, *ep;
+	int i = 0, ret;
+
+	if (!node)
+		return -EINVAL;
+
+	for_each_of_port(node, port) {
+		/* The off-codec widgets */
+		if (of_property_read_bool(port, PREFIX "widgets")) {
+			ret = snd_soc_of_parse_audio_simple_widgets_from_node(
+				&priv->snd_card,
+				port, PREFIX "widgets");
+			if (ret)
+				return ret;
+		}
+
+		/* DAPM routes */
+		if (of_property_read_bool(port, PREFIX "routing")) {
+			ret = snd_soc_of_parse_audio_routing_from_node(
+				&priv->snd_card,
+				port, PREFIX "routing");
+			if (ret)
+				return ret;
+		}
+
+		/* Factor to mclk, used in hw_params() */
+		of_property_read_u32(port, PREFIX "mclk-fs", &priv->mclk_fs);
+
+		for_each_of_endpoint_in_port(port, ep) {
+			ret = asoc_simple_card_dai_link_of(ep, priv, i);
+			if (ret < 0) {
+				of_node_put(ep);
+				return ret;
+			}
+			i++;
+		}
+	}
+
+	ret = asoc_simple_card_parse_card_name(card, top_port, PREFIX);
+	if (ret)
+		return ret;
+
+	return 0;
+}
+
+static int asoc_simple_card_probe(struct platform_device *pdev)
+{
+	struct simple_card_data *priv;
+	struct snd_soc_dai_link *dai_link;
+	struct simple_dai_props *dai_props;
+	struct device *dev = &pdev->dev;
+	struct device *cpu_dev = pdev->dev.parent;
+	struct device_node *cpu_node = cpu_dev->of_node;
+	struct asoc_simple_graph_card_info *info = pdev->dev.platform_data;
+	int num, ret;
+
+	if (!info)
+		return -EINVAL;
+
+	/* Allocate the private data and the DAI link array */
+	priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL);
+	if (!priv)
+		return -ENOMEM;
+
+	num = info->endpoint_num;
+
+	dai_props = devm_kzalloc(dev, sizeof(*dai_props) * num, GFP_KERNEL);
+	dai_link  = devm_kzalloc(dev, sizeof(*dai_link)  * num, GFP_KERNEL);
+	if (!dai_props || !dai_link)
+		return -ENOMEM;
+
+	priv->dai_props			= dai_props;
+	priv->dai_link			= dai_link;
+
+	/* Init snd_soc_card */
+	priv->snd_card.owner		= THIS_MODULE;
+	priv->snd_card.dev		= dev;
+	priv->snd_card.dai_link		= priv->dai_link;
+	priv->snd_card.num_links	= num;
+
+	ret = asoc_simple_card_parse_of(cpu_node, priv);
+	if (ret < 0) {
+		if (ret != -EPROBE_DEFER)
+			dev_err(dev, "parse error %d\n", ret);
+		goto err;
+	}
+
+	/*
+	 * FIXME
+	 *
+	 * This driver is assuming that it will be called from
+	 * asoc_simple_card_try_to_probe_graph_card() which
+	 * is using platform_device_register_full().
+	 * This means it is not came from DT. But this driver itself
+	 * will be used as part of ALSA SoC (= sound card).
+	 * Because of these background, it might fail in
+	 * snd_pcm_lib_malloc_pages() on .hw_params.
+	 * Because, noone cares its dma_ops, and result of get_dma_ops()
+	 * is based on its architecture.
+	 * So, it should call arch_setup_dma_ops() from somewhere,
+	 * otherwise, for example, ARM is no problem, but ARM64 will be fail.
+	 * But, of_platform_device_xxx() are not good solution today.
+	 * This driver calls it by itself here. Please fixme
+	 * see also
+	 * linux/sound/soc/generic/simple-card-utils.c ::
+	 *	asoc_simple_card_try_to_probe_graph_card()
+	 */
+	of_dma_configure(dev, dev->of_node);
+
+	snd_soc_card_set_drvdata(&priv->snd_card, priv);
+
+	ret = devm_snd_soc_register_card(dev, &priv->snd_card);
+	if (ret >= 0)
+		return ret;
+err:
+	asoc_simple_card_clean_reference(&priv->snd_card);
+
+	return ret;
+}
+
+static int asoc_simple_card_remove(struct platform_device *pdev)
+{
+	struct snd_soc_card *card = platform_get_drvdata(pdev);
+	struct simple_card_data *priv = snd_soc_card_get_drvdata(card);
+
+	asoc_simple_card_remove_jack(&priv->hp_jack);
+	asoc_simple_card_remove_jack(&priv->mic_jack);
+
+	return asoc_simple_card_clean_reference(&priv->snd_card);
+}
+
+static struct platform_driver asoc_simple_card = {
+	.driver = {
+		.name = "asoc-simple-graph-card",
+	},
+	.probe = asoc_simple_card_probe,
+	.remove = asoc_simple_card_remove,
+};
+module_platform_driver(asoc_simple_card);
+
+MODULE_ALIAS("platform:asoc-simple-graph-card");
+MODULE_LICENSE("GPL v2");
+MODULE_DESCRIPTION("ASoC Simple Graph Sound Card");
+MODULE_AUTHOR("Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>");
-- 
1.9.1

^ permalink raw reply related

* [PATCH 14/17] ASoC: add simple-graph-card document
From: Kuninori Morimoto @ 2016-10-31  1:19 UTC (permalink / raw)
  To: Rob Herring, Mark Brown
  Cc: Linux-ALSA, Liam Girdwood, Simon, Laurent, Guennadi, Grant Likely,
	Frank Rowand, Linux-DT, Linux-Kernel
In-Reply-To: <87pomhba6r.wl%kuninori.morimoto.gx@renesas.com>


From: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>

Signed-off-by: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
---
 .../bindings/sound/simple-graph-card.txt           | 62 ++++++++++++++++++++++
 1 file changed, 62 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/sound/simple-graph-card.txt

diff --git a/Documentation/devicetree/bindings/sound/simple-graph-card.txt b/Documentation/devicetree/bindings/sound/simple-graph-card.txt
new file mode 100644
index 0000000..967cd56
--- /dev/null
+++ b/Documentation/devicetree/bindings/sound/simple-graph-card.txt
@@ -0,0 +1,62 @@
+Simple-Graph-Card:
+
+Simple-Graph-Card specifies audio DAI connections of SoC <-> codec.
+It is based on common bindings for device graphs.
+see ${LINUX}/Documentation/devicetree/bindings/graph.txt
+
+Basically, Simple-Graph-Card is same as Simple-Card, but using graph style.
+see ${LINUX}/Documentation/devicetree/bindings/sound/simple-card.txt
+
+Below are same as Simple-Card.
+
+- simple-audio-card,name
+- simple-audio-card,widgets
+- simple-audio-card,routing
+- simple-audio-card,mclk-fs
+- simple-audio-card,hp-det-gpio
+- simple-audio-card,mic-det-gpio
+- simple-audio-card,format
+- simple-audio-card,frame-master
+- simple-audio-card,bitclock-master
+- simple-audio-card,bitclock-inversion
+- simple-audio-card,frame-inversion
+- simple-audio-card,mclk-fs
+- simple-audio-card,dai-tdm-slot-num
+- simple-audio-card,dai-tdm-slot-width
+- clocks / system-clock-frequency
+
+This Simple-Graph-Card should be located as CPU driver's port[s].
+And then, CPU driver need to probe it by itself.
+
+Required properties:
+
+- compatible				: "asoc-simple-graph-card";
+
+Example
+
+ak4643: codec@12 {
+	compatible = "asahi-kasei,ak4643";
+	...
+	port {
+		ak4643_port: endpoint {
+			remote-endpoint = <&rcar_ak4643_port>;
+			clocks = <&audio_clock>;
+		};
+	};
+};
+
+rcar_sound {
+	...
+	port {
+		compatible = "asoc-simple-graph-card";
+
+		simple-audio-card,format = "left_j";
+		simple-audio-card,bitclock-master = <&ak4643_port>;
+		simple-audio-card,frame-master = <&ak4643_port>;
+
+		rcar_ak4643_port: endpoint {
+			remote-endpoint = <&ak4643_port>;
+			...
+		};
+	};
+};
-- 
1.9.1

^ permalink raw reply related

* [PATCH 13/17] ASoC: simple-card-utils: adjust for graph on asoc_simple_card_parse_card_name
From: Kuninori Morimoto @ 2016-10-31  1:19 UTC (permalink / raw)
  To: Rob Herring, Mark Brown
  Cc: Linux-ALSA, Liam Girdwood, Simon, Laurent, Guennadi, Grant Likely,
	Frank Rowand, Linux-DT, Linux-Kernel
In-Reply-To: <87pomhba6r.wl%kuninori.morimoto.gx@renesas.com>

From: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>

It is assuming that the card related information is located on
"card" node, but graph case doesn't have it.
This patch adds node parameter to adjust for graph support

Signed-off-by: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
---
 include/sound/simple_card_utils.h     | 1 +
 sound/soc/generic/simple-card-utils.c | 3 ++-
 sound/soc/generic/simple-card.c       | 2 +-
 sound/soc/generic/simple-scu-card.c   | 2 +-
 4 files changed, 5 insertions(+), 3 deletions(-)

diff --git a/include/sound/simple_card_utils.h b/include/sound/simple_card_utils.h
index 7006150..afca6bd 100644
--- a/include/sound/simple_card_utils.h
+++ b/include/sound/simple_card_utils.h
@@ -36,6 +36,7 @@ int asoc_simple_card_set_dailink_name(struct device *dev,
 				      struct snd_soc_dai_link *dai_link,
 				      const char *fmt, ...);
 int asoc_simple_card_parse_card_name(struct snd_soc_card *card,
+				     struct device_node *node,
 				     char *prefix);
 
 #define asoc_simple_card_parse_clk_cpu(node, dai_link, simple_dai)		\
diff --git a/sound/soc/generic/simple-card-utils.c b/sound/soc/generic/simple-card-utils.c
index 85120f5..604f1f9 100644
--- a/sound/soc/generic/simple-card-utils.c
+++ b/sound/soc/generic/simple-card-utils.c
@@ -81,6 +81,7 @@ int asoc_simple_card_set_dailink_name(struct device *dev,
 EXPORT_SYMBOL_GPL(asoc_simple_card_set_dailink_name);
 
 int asoc_simple_card_parse_card_name(struct snd_soc_card *card,
+				     struct device_node *node,
 				     char *prefix)
 {
 	char prop[128];
@@ -89,7 +90,7 @@ int asoc_simple_card_parse_card_name(struct snd_soc_card *card,
 	snprintf(prop, sizeof(prop), "%sname", prefix);
 
 	/* Parse the card name from DT */
-	ret = snd_soc_of_parse_card_name(card, prop);
+	ret = snd_soc_of_parse_card_name_from_node(card, node, prop);
 	if (ret < 0)
 		return ret;
 
diff --git a/sound/soc/generic/simple-card.c b/sound/soc/generic/simple-card.c
index f608f8d2..342ff53 100644
--- a/sound/soc/generic/simple-card.c
+++ b/sound/soc/generic/simple-card.c
@@ -401,7 +401,7 @@ static int asoc_simple_card_parse_of(struct device_node *node,
 			goto card_parse_end;
 	}
 
-	ret = asoc_simple_card_parse_card_name(&priv->snd_card, PREFIX);
+	ret = asoc_simple_card_parse_card_name(&priv->snd_card, NULL, PREFIX);
 	if (ret < 0)
 		goto card_parse_end;
 
diff --git a/sound/soc/generic/simple-scu-card.c b/sound/soc/generic/simple-scu-card.c
index 348e9a7..a8164a2 100644
--- a/sound/soc/generic/simple-scu-card.c
+++ b/sound/soc/generic/simple-scu-card.c
@@ -239,7 +239,7 @@ static int asoc_simple_card_parse_of(struct device_node *node,
 		i++;
 	}
 
-	ret = asoc_simple_card_parse_card_name(&priv->snd_card, PREFIX);
+	ret = asoc_simple_card_parse_card_name(&priv->snd_card, NULL, PREFIX);
 	if (ret < 0)
 		return ret;
 
-- 
1.9.1

^ permalink raw reply related

* [PATCH 12/17] ASoC: simple-card-utils: add asoc_simple_card_try_to_probe_graph_card()
From: Kuninori Morimoto @ 2016-10-31  1:19 UTC (permalink / raw)
  To: Rob Herring, Mark Brown
  Cc: Linux-ALSA, Liam Girdwood, Simon, Laurent, Guennadi, Grant Likely,
	Frank Rowand, Linux-DT, Linux-Kernel
In-Reply-To: <87pomhba6r.wl%kuninori.morimoto.gx-zM6kxYcvzFBBDgjK7y7TUQ@public.gmane.org>

From: Kuninori Morimoto <kuninori.morimoto.gx-zM6kxYcvzFBBDgjK7y7TUQ@public.gmane.org>

If CPU/Platform side driver probes successfully, and if it is supporting
both previous normal sound card style and graph style DT, it can call
asoc_simple_card_try_to_probe_graph_card().
It checks graph style DT, and do nothing if it was non graph style DT,
or register new simple-graph-card driver if graph style DT.

Signed-off-by: Kuninori Morimoto <kuninori.morimoto.gx-zM6kxYcvzFBBDgjK7y7TUQ@public.gmane.org>
---
 include/sound/simple_card_utils.h     |  8 +++++++
 sound/soc/generic/simple-card-utils.c | 45 +++++++++++++++++++++++++++++++++++
 2 files changed, 53 insertions(+)

diff --git a/include/sound/simple_card_utils.h b/include/sound/simple_card_utils.h
index 4b58954..7006150 100644
--- a/include/sound/simple_card_utils.h
+++ b/include/sound/simple_card_utils.h
@@ -22,6 +22,10 @@ struct asoc_simple_dai {
 	struct clk *clk;
 };
 
+struct asoc_simple_graph_card_info {
+	int endpoint_num; /* sound endpoint number */
+};
+
 int asoc_simple_card_parse_daifmt(struct device *dev,
 				  struct device_node *node,
 				  struct device_node *codec,
@@ -78,4 +82,8 @@ void asoc_simple_card_canonicalize_cpu(struct snd_soc_dai_link *dai_link,
 
 int asoc_simple_card_clean_reference(struct snd_soc_card *card);
 
+void asoc_simple_card_try_to_probe_graph_card(struct device *dev,
+				struct asoc_simple_graph_card_info *info);
+
+
 #endif /* __SIMPLE_CARD_CORE_H */
diff --git a/sound/soc/generic/simple-card-utils.c b/sound/soc/generic/simple-card-utils.c
index 373ada3..85120f5 100644
--- a/sound/soc/generic/simple-card-utils.c
+++ b/sound/soc/generic/simple-card-utils.c
@@ -8,6 +8,7 @@
  * published by the Free Software Foundation.
  */
 #include <linux/clk.h>
+#include <linux/dma-mapping.h>
 #include <linux/module.h>
 #include <linux/of.h>
 #include <linux/of_graph.h>
@@ -285,6 +286,50 @@ int asoc_simple_card_clean_reference(struct snd_soc_card *card)
 }
 EXPORT_SYMBOL_GPL(asoc_simple_card_clean_reference);
 
+void asoc_simple_card_try_to_probe_graph_card(struct device *dev,
+				struct asoc_simple_graph_card_info *info)
+{
+	struct platform_device_info pdevinfo;
+	struct device_node *node;
+	const char *compatible;
+	int ret;
+
+	node = of_graph_get_top_port(dev);
+	if (!node || !info)
+		/*
+		 * It doesn't have graph base sound DT, or its infomation.
+		 * Do nothing here, It assumes that system has
+		 * normal sound card.
+		 */
+		return;
+
+	ret = of_property_read_string(node, "compatible", &compatible);
+	if (ret < 0)
+		goto probe_err;
+
+	/*
+	 * FIXME
+	 *
+	 * It should use of_platform_xxx() instead of
+	 * platform_device_register_full() ? but there is no solution.
+	 * see also
+	 * linux/sound/soc/generic/simple-graph-card.c :: asoc_simple_card_probe
+	 */
+
+	memset(&pdevinfo, 0, sizeof(pdevinfo));
+	pdevinfo.parent		= dev;
+	pdevinfo.id		= PLATFORM_DEVID_AUTO;
+	pdevinfo.name		= compatible;
+	pdevinfo.dma_mask	= DMA_BIT_MASK(32);
+	pdevinfo.data		= info;
+	pdevinfo.size_data	= sizeof(*info);
+	platform_device_register_full(&pdevinfo);
+
+probe_err:
+	of_node_put(node);
+}
+EXPORT_SYMBOL_GPL(asoc_simple_card_try_to_probe_graph_card);
+
 /* Module information */
 MODULE_AUTHOR("Kuninori Morimoto <kuninori.morimoto.gx-zM6kxYcvzFBBDgjK7y7TUQ@public.gmane.org>");
 MODULE_DESCRIPTION("ALSA SoC Simple Card Utils");
-- 
1.9.1

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

^ permalink raw reply related

* [PATCH 11/17] ASoC: simple-card-utils: add asoc_simple_card_parse_graph_dai()
From: Kuninori Morimoto @ 2016-10-31  1:18 UTC (permalink / raw)
  To: Rob Herring, Mark Brown
  Cc: Linux-ALSA, Liam Girdwood, Simon, Laurent, Guennadi, Grant Likely,
	Frank Rowand, Linux-DT, Linux-Kernel
In-Reply-To: <87pomhba6r.wl%kuninori.morimoto.gx-zM6kxYcvzFBBDgjK7y7TUQ@public.gmane.org>

From: Kuninori Morimoto <kuninori.morimoto.gx-zM6kxYcvzFBBDgjK7y7TUQ@public.gmane.org>

simple-card already has asoc_simple_card_parse_dai(),
but graph base parsing needs graph specific version of it.

Signed-off-by: Kuninori Morimoto <kuninori.morimoto.gx-zM6kxYcvzFBBDgjK7y7TUQ@public.gmane.org>
---
 include/sound/simple_card_utils.h     | 10 +++++++
 sound/soc/generic/simple-card-utils.c | 50 +++++++++++++++++++++++++++++++++++
 2 files changed, 60 insertions(+)

diff --git a/include/sound/simple_card_utils.h b/include/sound/simple_card_utils.h
index fd641255..4b58954 100644
--- a/include/sound/simple_card_utils.h
+++ b/include/sound/simple_card_utils.h
@@ -59,6 +59,16 @@ int asoc_simple_card_parse_dai(struct device_node *node,
 				  const char *cells_name,
 				  int *is_single_links);
 
+#define asoc_simple_card_parse_graph_cpu(ep, dai_link)			\
+	asoc_simple_card_parse_graph_dai(ep, &dai_link->cpu_of_node,	\
+					 &dai_link->cpu_dai_name)
+#define asoc_simple_card_parse_graph_codec(ep, dai_link)		\
+	asoc_simple_card_parse_graph_dai(ep, &dai_link->codec_of_node,	\
+					 &dai_link->codec_dai_name)
+int asoc_simple_card_parse_graph_dai(struct device_node *ep,
+				     struct device_node **endpoint_np,
+				     const char **dai_name);
+
 int asoc_simple_card_init_dai(struct snd_soc_dai *dai,
 			      struct asoc_simple_dai *simple_dai);
 
diff --git a/sound/soc/generic/simple-card-utils.c b/sound/soc/generic/simple-card-utils.c
index e5b80f5..373ada3 100644
--- a/sound/soc/generic/simple-card-utils.c
+++ b/sound/soc/generic/simple-card-utils.c
@@ -10,6 +10,7 @@
 #include <linux/clk.h>
 #include <linux/module.h>
 #include <linux/of.h>
+#include <linux/of_graph.h>
 #include <sound/simple_card_utils.h>
 
 int asoc_simple_card_parse_daifmt(struct device *dev,
@@ -164,6 +165,55 @@ int asoc_simple_card_parse_dai(struct device_node *node,
 }
 EXPORT_SYMBOL_GPL(asoc_simple_card_parse_dai);
 
+int asoc_simple_card_parse_graph_dai(struct device_node *ep,
+				     struct device_node **dai_of_node,
+				     const char **dai_name)
+{
+	struct device_node *node, *port, *endpoint;
+	int i, id;
+
+	if (!ep)
+		return 0;
+
+	/*
+	 * of_graph_get_port_parent() will call
+	 * of_node_put(). So, call of_node_get() here
+	 */
+	of_node_get(ep);
+	node = of_graph_get_port_parent(ep);
+
+	i = 0;
+	id = -1;
+	for_each_of_port(node, port) {
+		for_each_of_endpoint_in_port(port, endpoint) {
+			if (endpoint == ep)
+				id = i;
+			i++;
+		}
+	}
+	if (id < 0)
+		return -ENODEV;
+
+	/* Get dai->name */
+	if (dai_name) {
+		struct of_phandle_args args;
+		int ret;
+
+		args.np		= node;
+		args.args[0]	= id;
+		args.args_count	= (i > 1);
+
+		ret = snd_soc_get_dai_name(&args, dai_name);
+		if (ret < 0)
+			return ret;
+	}
+
+	*dai_of_node = node;
+
+	return 0;
+}
+EXPORT_SYMBOL_GPL(asoc_simple_card_parse_graph_dai);
+
 int asoc_simple_card_init_dai(struct snd_soc_dai *dai,
 			      struct asoc_simple_dai *simple_dai)
 {
-- 
1.9.1

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

^ permalink raw reply related

* [PATCH 10/17] of_graph: add of_graph_get_port/endpoint_count()
From: Kuninori Morimoto @ 2016-10-31  1:18 UTC (permalink / raw)
  To: Rob Herring, Mark Brown
  Cc: Linux-ALSA, Liam Girdwood, Simon, Laurent, Guennadi, Grant Likely,
	Frank Rowand, Linux-DT, Linux-Kernel
In-Reply-To: <87pomhba6r.wl%kuninori.morimoto.gx-zM6kxYcvzFBBDgjK7y7TUQ@public.gmane.org>


From: Kuninori Morimoto <kuninori.morimoto.gx-zM6kxYcvzFBBDgjK7y7TUQ@public.gmane.org>

OF graph want to count its port/endpoint number, same as
of_get_child_count(). This patch adds these functions.

Signed-off-by: Kuninori Morimoto <kuninori.morimoto.gx-zM6kxYcvzFBBDgjK7y7TUQ@public.gmane.org>
---
 drivers/of/base.c        | 24 ++++++++++++++++++++++++
 include/linux/of_graph.h |  8 ++++++++
 2 files changed, 32 insertions(+)

diff --git a/drivers/of/base.c b/drivers/of/base.c
index b11f533..e795d0f 100644
--- a/drivers/of/base.c
+++ b/drivers/of/base.c
@@ -2584,3 +2584,27 @@ struct device_node *of_graph_get_remote_port(const struct device_node *node)
 	return of_get_next_parent(np);
 }
 EXPORT_SYMBOL(of_graph_get_remote_port);
+
+int of_graph_get_port_count(const struct device_node *np)
+{
+	struct device_node *port;
+	int num = 0;
+
+	for_each_of_port(np, port)
+		num++;
+
+	return num;
+}
+EXPORT_SYMBOL(of_graph_get_port_count);
+
+int of_graph_get_endpoint_count(const struct device_node *np)
+{
+	struct device_node *port, *endpoint;
+	int num = 0;
+
+	for_each_of_endpoint(np, port, endpoint)
+		num++;
+
+	return num;
+}
+EXPORT_SYMBOL(of_graph_get_endpoint_count);
diff --git a/include/linux/of_graph.h b/include/linux/of_graph.h
index 3de036f..c060a7c 100644
--- a/include/linux/of_graph.h
+++ b/include/linux/of_graph.h
@@ -54,6 +54,8 @@ struct of_endpoint {
 #ifdef CONFIG_OF
 int of_graph_parse_endpoint(const struct device_node *node,
 				struct of_endpoint *endpoint);
+int of_graph_get_port_count(const struct device_node *np);
+int of_graph_get_endpoint_count(const struct device_node *np);
 struct device_node *of_graph_get_port_by_id(struct device_node *node, u32 id);
 struct device_node *of_graph_get_top_port(struct device *dev);
 struct device_node *of_graph_get_next_port(const struct device_node *parent,
@@ -79,6 +81,12 @@ static inline int of_graph_parse_endpoint(const struct device_node *node,
 	return -ENOSYS;
 }
 
+static inline int of_graph_get_endpoint_count(const struct device_node *np,
+					      char *type)
+{
+	return 0;
+}
+
 static inline struct device_node *of_graph_get_port_by_id(
 					struct device_node *node, u32 id)
 {
-- 
1.9.1

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

^ permalink raw reply related

* [PATCH 09/17] of_graph: add for_each_of_port() / for_each_of_endpoint_in_port()
From: Kuninori Morimoto @ 2016-10-31  1:18 UTC (permalink / raw)
  To: Rob Herring, Mark Brown
  Cc: Linux-ALSA, Liam Girdwood, Simon, Laurent, Guennadi, Grant Likely,
	Frank Rowand, Linux-DT, Linux-Kernel
In-Reply-To: <87pomhba6r.wl%kuninori.morimoto.gx@renesas.com>

From: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>

OF graph is used mainly from V4L2, but ALSA needs to use it. It already
has for_each_endpoint_of_node() which is for-loop for each endpoint.
But, ALSA needs for-loop for each port[s], and for-loop for each
endpoint of inside port[s]. This patch adds for_each_of_port()
and for_each_of_endpoint_in_port() for this purpose.

And it also adds for_each_of_endpoint() which is similar to
for_each_endpoint_of_node(). The difference is it can catch port
handle during for-loop.

Signed-off-by: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
---
 drivers/of/base.c        | 64 ++++++++++++++++++++++++++++++++++++++++++++++++
 include/linux/of_graph.h | 29 ++++++++++++++++++++++
 2 files changed, 93 insertions(+)

diff --git a/drivers/of/base.c b/drivers/of/base.c
index e49eb28..b11f533 100644
--- a/drivers/of/base.c
+++ b/drivers/of/base.c
@@ -2354,6 +2354,70 @@ struct device_node *of_graph_get_top_port(struct device *dev)
 EXPORT_SYMBOL(of_graph_get_top_port);
 
 /**
+ * of_graph_get_next_port() - get next port node
+ * @parent: pointer to the parent device node
+ * @prev: previous endpoint node, or NULL to get first
+ *
+ * Return: An 'endpoint' node pointer with refcount incremented. Refcount
+ * of the passed @prev node is decremented.
+ */
+struct device_node *of_graph_get_next_port(const struct device_node *parent,
+					   struct device_node *prev)
+{
+	struct device_node *port;
+	struct device_node *node;
+
+	if (!parent)
+		return NULL;
+
+	node = of_get_child_by_name(parent, "ports");
+	if (node)
+		parent = node;
+
+	/*
+	 * Start by locating the port node. If no previous endpoint is specified
+	 * search for the first port node, otherwise get the previous endpoint
+	 * parent port node.
+	 */
+	if (!prev) {
+		port = of_get_child_by_name(parent, "port");
+		if (!port)
+			pr_err("%s(): no port node found in %s\n",
+			       __func__, parent->full_name);
+	} else {
+		do {
+			port = of_get_next_child(parent, prev);
+			if (!port)
+				break;
+		} while (of_node_cmp(port->name, "port"));
+	}
+
+	of_node_put(node);
+
+	return port;
+}
+EXPORT_SYMBOL(of_graph_get_next_port);
+
+/**
+ * of_graph_get_next_endpoint_in_port() - get next endpoint node in port
+ * @parent: pointer to the parent device node
+ * @prev: previous endpoint node, or NULL to get first
+ *
+ * Return: An 'endpoint' node pointer with refcount incremented. Refcount
+ * of the passed @prev node is decremented.
+ */
+struct device_node *of_graph_get_next_endpoint_in_port(
+			const struct device_node *port,
+			struct device_node *prev)
+{
+	if (!port)
+		return NULL;
+
+	return of_get_next_child(port, prev);
+}
+EXPORT_SYMBOL(of_graph_get_next_endpoint_in_port);
+
+/**
  * of_graph_get_next_endpoint() - get next endpoint node
  * @parent: pointer to the parent device node
  * @prev: previous endpoint node, or NULL to get first
diff --git a/include/linux/of_graph.h b/include/linux/of_graph.h
index ee823c6..3de036f 100644
--- a/include/linux/of_graph.h
+++ b/include/linux/of_graph.h
@@ -30,6 +30,16 @@ struct of_endpoint {
 	const struct device_node *local_node;
 };
 
+#define for_each_of_port(parent, port) \
+	for (port = of_graph_get_next_port(parent, NULL); port != NULL; \
+	     port = of_graph_get_next_port(parent, port))
+#define for_each_of_endpoint_in_port(port, ep) \
+	for (ep = of_graph_get_next_endpoint_in_port(port, NULL); ep != NULL; \
+	     ep = of_graph_get_next_endpoint_in_port(port, ep))
+#define for_each_of_endpoint(parent, port, ep) \
+	for_each_of_port(parent, port) \
+		for_each_of_endpoint_in_port(port, ep)
+
 /**
  * for_each_endpoint_of_node - iterate over every endpoint in a device node
  * @parent: parent device node containing ports and endpoints
@@ -46,6 +56,11 @@ int of_graph_parse_endpoint(const struct device_node *node,
 				struct of_endpoint *endpoint);
 struct device_node *of_graph_get_port_by_id(struct device_node *node, u32 id);
 struct device_node *of_graph_get_top_port(struct device *dev);
+struct device_node *of_graph_get_next_port(const struct device_node *parent,
+					struct device_node *prev);
+struct device_node *of_graph_get_next_endpoint_in_port(
+	const struct device_node *port,
+	struct device_node *prev);
 struct device_node *of_graph_get_next_endpoint(const struct device_node *parent,
 					struct device_node *previous);
 struct device_node *of_graph_get_endpoint_by_regs(
@@ -70,6 +85,20 @@ static inline struct device_node *of_graph_get_port_by_id(
 	return NULL;
 }
 
+static inline struct device_node *of_graph_get_next_port(
+					const struct device_node *parent,
+					struct device_node *prev)
+{
+	return NULL;
+}
+
+static inline struct device_node *of_graph_get_next_endpoint_in_port(
+					const struct device_node *port,
+					struct device_node *prev)
+{
+	return NULL;
+}
+
 static inline struct device_node *of_graph_get_next_endpoint(
 					const struct device_node *parent,
 					struct device_node *previous)
-- 
1.9.1

^ permalink raw reply related

* [PATCH 08/17] of_graph: add of_graph_get_top_port()
From: Kuninori Morimoto @ 2016-10-31  1:18 UTC (permalink / raw)
  To: Rob Herring, Mark Brown
  Cc: Linux-ALSA, Liam Girdwood, Simon, Laurent, Guennadi, Grant Likely,
	Frank Rowand, Linux-DT, Linux-Kernel
In-Reply-To: <87pomhba6r.wl%kuninori.morimoto.gx@renesas.com>


From: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>

driver want to get top level of port[s] node. This patch adds
of_graph_get_top_port() for this purpose

Signed-off-by: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
---
 drivers/of/base.c        | 24 ++++++++++++++++++++++++
 include/linux/of_graph.h |  2 ++
 2 files changed, 26 insertions(+)

diff --git a/drivers/of/base.c b/drivers/of/base.c
index fed0b023..e49eb28 100644
--- a/drivers/of/base.c
+++ b/drivers/of/base.c
@@ -2330,6 +2330,30 @@ struct device_node *of_graph_get_port_by_id(struct device_node *parent, u32 id)
 EXPORT_SYMBOL(of_graph_get_port_by_id);
 
 /**
+ * of_graph_get_top_port() - get the top port node
+ * @dev: pointer to the device
+ *
+ * Return: A 'port' node pointer with refcount incremented. The caller
+ * has to use of_node_put() on it when done.
+ */
+struct device_node *of_graph_get_top_port(struct device *dev)
+{
+	struct device_node *np = dev->of_node;
+	struct device_node *node;
+
+	node = of_get_child_by_name(np, "ports");
+	if (node)
+		return node;
+
+	node = of_get_child_by_name(np, "port");
+	if (node)
+		return node;
+
+	return NULL;
+}
+EXPORT_SYMBOL(of_graph_get_top_port);
+
+/**
  * of_graph_get_next_endpoint() - get next endpoint node
  * @parent: pointer to the parent device node
  * @prev: previous endpoint node, or NULL to get first
diff --git a/include/linux/of_graph.h b/include/linux/of_graph.h
index 80ced0c..ee823c6 100644
--- a/include/linux/of_graph.h
+++ b/include/linux/of_graph.h
@@ -14,6 +14,7 @@
 #ifndef __LINUX_OF_GRAPH_H
 #define __LINUX_OF_GRAPH_H
 
+#include <linux/device.h>
 #include <linux/types.h>
 #include <linux/errno.h>
 
@@ -44,6 +45,7 @@ struct of_endpoint {
 int of_graph_parse_endpoint(const struct device_node *node,
 				struct of_endpoint *endpoint);
 struct device_node *of_graph_get_port_by_id(struct device_node *node, u32 id);
+struct device_node *of_graph_get_top_port(struct device *dev);
 struct device_node *of_graph_get_next_endpoint(const struct device_node *parent,
 					struct device_node *previous);
 struct device_node *of_graph_get_endpoint_by_regs(
-- 
1.9.1

^ permalink raw reply related

* [PATCH 07/17] of_graph: add of_graph_get_port_parent()
From: Kuninori Morimoto @ 2016-10-31  1:17 UTC (permalink / raw)
  To: Rob Herring, Mark Brown
  Cc: Linux-ALSA, Liam Girdwood, Simon, Laurent, Guennadi, Grant Likely,
	Frank Rowand, Linux-DT, Linux-Kernel
In-Reply-To: <87pomhba6r.wl%kuninori.morimoto.gx@renesas.com>


From: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>

Linux kernel already has of_graph_get_remote_port_parent(),
but, sometimes we want to get own port parent.
This patch adds of_graph_get_port_parent()

Signed-off-by: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
---
 drivers/of/base.c        | 30 ++++++++++++++++++++++--------
 include/linux/of_graph.h |  7 +++++++
 2 files changed, 29 insertions(+), 8 deletions(-)

diff --git a/drivers/of/base.c b/drivers/of/base.c
index 810acf4..fed0b023 100644
--- a/drivers/of/base.c
+++ b/drivers/of/base.c
@@ -2439,6 +2439,27 @@ struct device_node *of_graph_get_remote_endpoint(const struct device_node *node)
 EXPORT_SYMBOL(of_graph_get_remote_endpoint);
 
 /**
+ * of_graph_get_port_parent() - get port's parent node
+ * @node: pointer to a local endpoint device_node
+ *
+ * Return: device node associated with endpoint node linked
+ *	   to @node. Use of_node_put() on it when done.
+ */
+struct device_node *of_graph_get_port_parent(struct device_node *node)
+{
+	unsigned int depth;
+
+	/* Walk 3 levels up only if there is 'ports' node. */
+	for (depth = 3; depth && node; depth--) {
+		node = of_get_next_parent(node);
+		if (depth == 2 && of_node_cmp(node->name, "ports"))
+			break;
+	}
+	return node;
+}
+EXPORT_SYMBOL(of_graph_get_port_parent);
+
+/**
  * of_graph_get_remote_port_parent() - get remote port's parent node
  * @node: pointer to a local endpoint device_node
  *
@@ -2449,18 +2470,11 @@ struct device_node *of_graph_get_remote_port_parent(
 			       const struct device_node *node)
 {
 	struct device_node *np;
-	unsigned int depth;
 
 	/* Get remote endpoint node. */
 	np = of_graph_get_remote_endpoint(node);
 
-	/* Walk 3 levels up only if there is 'ports' node. */
-	for (depth = 3; depth && np; depth--) {
-		np = of_get_next_parent(np);
-		if (depth == 2 && of_node_cmp(np->name, "ports"))
-			break;
-	}
-	return np;
+	return of_graph_get_port_parent(np);
 }
 EXPORT_SYMBOL(of_graph_get_remote_port_parent);
 
diff --git a/include/linux/of_graph.h b/include/linux/of_graph.h
index d9d6d9c..80ced0c 100644
--- a/include/linux/of_graph.h
+++ b/include/linux/of_graph.h
@@ -50,6 +50,7 @@ struct device_node *of_graph_get_endpoint_by_regs(
 		const struct device_node *parent, int port_reg, int reg);
 struct device_node *of_graph_get_remote_endpoint(
 					const struct device_node *node);
+struct device_node *of_graph_get_port_parent(struct device_node *node);
 struct device_node *of_graph_get_remote_port_parent(
 					const struct device_node *node);
 struct device_node *of_graph_get_remote_port(const struct device_node *node);
@@ -86,6 +87,12 @@ static inline struct device_node *of_graph_get_remote_endpoint(
 	return NULL;
 }
 
+static inline struct device_node *of_graph_get_port_parent(
+	struct device_node *node)
+{
+	return NULL;
+}
+
 static inline struct device_node *of_graph_get_remote_port_parent(
 					const struct device_node *node)
 {
-- 
1.9.1

^ permalink raw reply related

* [PATCH 06/17] of_graph: add of_graph_get_remote_endpoint()
From: Kuninori Morimoto @ 2016-10-31  1:17 UTC (permalink / raw)
  To: Rob Herring, Mark Brown
  Cc: Linux-ALSA, Liam Girdwood, Simon, Laurent, Guennadi, Grant Likely,
	Frank Rowand, Linux-DT, Linux-Kernel
In-Reply-To: <87pomhba6r.wl%kuninori.morimoto.gx@renesas.com>


From: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>

It should use same method to get same result.
To getting remote-endpoint node,
let's use of_graph_get_remote_endpoint()

Signed-off-by: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
---
 drivers/of/base.c        | 18 ++++++++++++++++--
 include/linux/of_graph.h |  8 ++++++++
 2 files changed, 24 insertions(+), 2 deletions(-)

diff --git a/drivers/of/base.c b/drivers/of/base.c
index d687e6d..810acf4 100644
--- a/drivers/of/base.c
+++ b/drivers/of/base.c
@@ -2425,6 +2425,20 @@ struct device_node *of_graph_get_endpoint_by_regs(
 EXPORT_SYMBOL(of_graph_get_endpoint_by_regs);
 
 /**
+ * of_graph_get_remote_endpoint() - get remote endpoint node
+ * @node: pointer to a local endpoint device_node
+ *
+ * Return: Remote endpoint node associated with remote endpoint node linked
+ *	   to @node. Use of_node_put() on it when done.
+ */
+struct device_node *of_graph_get_remote_endpoint(const struct device_node *node)
+{
+	/* Get remote endpoint node. */
+	return of_parse_phandle(node, "remote-endpoint", 0);
+}
+EXPORT_SYMBOL(of_graph_get_remote_endpoint);
+
+/**
  * of_graph_get_remote_port_parent() - get remote port's parent node
  * @node: pointer to a local endpoint device_node
  *
@@ -2438,7 +2452,7 @@ struct device_node *of_graph_get_remote_port_parent(
 	unsigned int depth;
 
 	/* Get remote endpoint node. */
-	np = of_parse_phandle(node, "remote-endpoint", 0);
+	np = of_graph_get_remote_endpoint(node);
 
 	/* Walk 3 levels up only if there is 'ports' node. */
 	for (depth = 3; depth && np; depth--) {
@@ -2462,7 +2476,7 @@ struct device_node *of_graph_get_remote_port(const struct device_node *node)
 	struct device_node *np;
 
 	/* Get remote endpoint node. */
-	np = of_parse_phandle(node, "remote-endpoint", 0);
+	np = of_graph_get_remote_endpoint(node);
 	if (!np)
 		return NULL;
 	return of_get_next_parent(np);
diff --git a/include/linux/of_graph.h b/include/linux/of_graph.h
index bb3a5a2..d9d6d9c 100644
--- a/include/linux/of_graph.h
+++ b/include/linux/of_graph.h
@@ -48,6 +48,8 @@ struct device_node *of_graph_get_next_endpoint(const struct device_node *parent,
 					struct device_node *previous);
 struct device_node *of_graph_get_endpoint_by_regs(
 		const struct device_node *parent, int port_reg, int reg);
+struct device_node *of_graph_get_remote_endpoint(
+					const struct device_node *node);
 struct device_node *of_graph_get_remote_port_parent(
 					const struct device_node *node);
 struct device_node *of_graph_get_remote_port(const struct device_node *node);
@@ -78,6 +80,12 @@ static inline struct device_node *of_graph_get_endpoint_by_regs(
 	return NULL;
 }
 
+static inline struct device_node *of_graph_get_remote_endpoint(
+					const struct device_node *node)
+{
+	return NULL;
+}
+
 static inline struct device_node *of_graph_get_remote_port_parent(
 					const struct device_node *node)
 {
-- 
1.9.1

^ permalink raw reply related

* [PATCH 05/17] ASoC: soc-core: snd_soc_get_dai_name() become non static
From: Kuninori Morimoto @ 2016-10-31  1:17 UTC (permalink / raw)
  To: Rob Herring, Mark Brown
  Cc: Linux-ALSA, Liam Girdwood, Simon, Laurent, Guennadi, Grant Likely,
	Frank Rowand, Linux-DT, Linux-Kernel
In-Reply-To: <87pomhba6r.wl%kuninori.morimoto.gx@renesas.com>

From: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>

snd_soc_get_dai_name() is used from snd_soc_of_get_dai_name(),
and it is assuming that DT is using "sound-dai" / "#sound-dai-cells".
But graph base DT is using "remote-endpoint". This patch makes
snd_soc_get_dai_name() non static for graph support.

Signed-off-by: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
---
 include/sound/soc.h  | 2 ++
 sound/soc/soc-core.c | 3 ++-
 2 files changed, 4 insertions(+), 1 deletion(-)

diff --git a/include/sound/soc.h b/include/sound/soc.h
index 60ac25d..218e3fb 100644
--- a/include/sound/soc.h
+++ b/include/sound/soc.h
@@ -1677,6 +1677,8 @@ unsigned int snd_soc_of_parse_daifmt(struct device_node *np,
 				     const char *prefix,
 				     struct device_node **bitclkmaster,
 				     struct device_node **framemaster);
+int snd_soc_get_dai_name(struct of_phandle_args *args,
+			 const char **dai_name);
 int snd_soc_of_get_dai_name(struct device_node *of_node,
 			    const char **dai_name);
 int snd_soc_of_get_dai_link_codecs(struct device *dev,
diff --git a/sound/soc/soc-core.c b/sound/soc/soc-core.c
index 8371488..6f911f4 100644
--- a/sound/soc/soc-core.c
+++ b/sound/soc/soc-core.c
@@ -3794,7 +3794,7 @@ unsigned int snd_soc_of_parse_daifmt(struct device_node *np,
 }
 EXPORT_SYMBOL_GPL(snd_soc_of_parse_daifmt);
 
-static int snd_soc_get_dai_name(struct of_phandle_args *args,
+int snd_soc_get_dai_name(struct of_phandle_args *args,
 				const char **dai_name)
 {
 	struct snd_soc_component *pos;
@@ -3846,6 +3846,7 @@ static int snd_soc_get_dai_name(struct of_phandle_args *args,
 	mutex_unlock(&client_mutex);
 	return ret;
 }
+EXPORT_SYMBOL_GPL(snd_soc_get_dai_name);
 
 int snd_soc_of_get_dai_name(struct device_node *of_node,
 			    const char **dai_name)
-- 
1.9.1

^ permalink raw reply related

* [PATCH 04/17] ASoC: soc-core: adjust for graph on snd_soc_of_parse_audio_prefix
From: Kuninori Morimoto @ 2016-10-31  1:16 UTC (permalink / raw)
  To: Rob Herring, Mark Brown
  Cc: Linux-ALSA, Liam Girdwood, Simon, Laurent, Guennadi, Grant Likely,
	Frank Rowand, Linux-DT, Linux-Kernel
In-Reply-To: <87pomhba6r.wl%kuninori.morimoto.gx-zM6kxYcvzFBBDgjK7y7TUQ@public.gmane.org>

From: Kuninori Morimoto <kuninori.morimoto.gx-zM6kxYcvzFBBDgjK7y7TUQ@public.gmane.org>

It is assuming that the card related information is located on
"card" node, but graph case doesn't have it.
This patch adds node parameter to adjust for graph support

Signed-off-by: Kuninori Morimoto <kuninori.morimoto.gx-zM6kxYcvzFBBDgjK7y7TUQ@public.gmane.org>
---
 include/sound/soc.h  | 6 +++++-
 sound/soc/soc-core.c | 9 ++++++---
 2 files changed, 11 insertions(+), 4 deletions(-)

diff --git a/include/sound/soc.h b/include/sound/soc.h
index f276f69..60ac25d 100644
--- a/include/sound/soc.h
+++ b/include/sound/soc.h
@@ -1658,7 +1658,11 @@ int snd_soc_of_parse_tdm_slot(struct device_node *np,
 			      unsigned int *rx_mask,
 			      unsigned int *slots,
 			      unsigned int *slot_width);
-void snd_soc_of_parse_audio_prefix(struct snd_soc_card *card,
+#define snd_soc_of_parse_audio_prefix(card, codec_conf, of_node, propname) \
+	snd_soc_of_parse_audio_prefix_from_node(card, NULL, codec_conf, \
+						of_node, propname)
+void snd_soc_of_parse_audio_prefix_from_node(struct snd_soc_card *card,
+				   struct device_node *np,
 				   struct snd_soc_codec_conf *codec_conf,
 				   struct device_node *of_node,
 				   const char *propname);
diff --git a/sound/soc/soc-core.c b/sound/soc/soc-core.c
index 79a1045..8371488 100644
--- a/sound/soc/soc-core.c
+++ b/sound/soc/soc-core.c
@@ -3599,15 +3599,18 @@ int snd_soc_of_parse_tdm_slot(struct device_node *np,
 }
 EXPORT_SYMBOL_GPL(snd_soc_of_parse_tdm_slot);
 
-void snd_soc_of_parse_audio_prefix(struct snd_soc_card *card,
+void snd_soc_of_parse_audio_prefix_from_node(struct snd_soc_card *card,
+				   struct device_node *np,
 				   struct snd_soc_codec_conf *codec_conf,
 				   struct device_node *of_node,
 				   const char *propname)
 {
-	struct device_node *np = card->dev->of_node;
 	const char *str;
 	int ret;
 
+	if (!np)
+		np = card->dev->of_node;
+
 	ret = of_property_read_string(np, propname, &str);
 	if (ret < 0) {
 		/* no prefix is not error */
@@ -3617,7 +3620,7 @@ void snd_soc_of_parse_audio_prefix(struct snd_soc_card *card,
 	codec_conf->of_node	= of_node;
 	codec_conf->name_prefix	= str;
 }
-EXPORT_SYMBOL_GPL(snd_soc_of_parse_audio_prefix);
+EXPORT_SYMBOL_GPL(snd_soc_of_parse_audio_prefix_from_node);
 
 int snd_soc_of_parse_audio_routing_from_node(struct snd_soc_card *card,
 				   struct device_node *np,
-- 
1.9.1

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

^ permalink raw reply related

* [PATCH 03/17] ASoC: soc-core: adjust for graph on snd_soc_of_parse_audio_routing
From: Kuninori Morimoto @ 2016-10-31  1:16 UTC (permalink / raw)
  To: Rob Herring, Mark Brown
  Cc: Linux-ALSA, Liam Girdwood, Simon, Laurent, Guennadi, Grant Likely,
	Frank Rowand, Linux-DT, Linux-Kernel
In-Reply-To: <87pomhba6r.wl%kuninori.morimoto.gx@renesas.com>

From: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>

It is assuming that the card related information is located on
"card" node, but graph case doesn't have it.
This patch adds node parameter to adjust for graph support

Signed-off-by: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
---
 include/sound/soc.h  | 9 +++++++--
 sound/soc/soc-core.c | 9 ++++++---
 2 files changed, 13 insertions(+), 5 deletions(-)

diff --git a/include/sound/soc.h b/include/sound/soc.h
index a091c66..f276f69 100644
--- a/include/sound/soc.h
+++ b/include/sound/soc.h
@@ -1662,8 +1662,13 @@ void snd_soc_of_parse_audio_prefix(struct snd_soc_card *card,
 				   struct snd_soc_codec_conf *codec_conf,
 				   struct device_node *of_node,
 				   const char *propname);
-int snd_soc_of_parse_audio_routing(struct snd_soc_card *card,
-				   const char *propname);
+
+#define snd_soc_of_parse_audio_routing(card, propname) \
+	snd_soc_of_parse_audio_routing_from_node(card, NULL, propname)
+int snd_soc_of_parse_audio_routing_from_node(struct snd_soc_card *card,
+					     struct device_node *np,
+					     const char *propname);
+
 unsigned int snd_soc_of_parse_daifmt(struct device_node *np,
 				     const char *prefix,
 				     struct device_node **bitclkmaster,
diff --git a/sound/soc/soc-core.c b/sound/soc/soc-core.c
index e56ea42..79a1045 100644
--- a/sound/soc/soc-core.c
+++ b/sound/soc/soc-core.c
@@ -3619,14 +3619,17 @@ void snd_soc_of_parse_audio_prefix(struct snd_soc_card *card,
 }
 EXPORT_SYMBOL_GPL(snd_soc_of_parse_audio_prefix);
 
-int snd_soc_of_parse_audio_routing(struct snd_soc_card *card,
+int snd_soc_of_parse_audio_routing_from_node(struct snd_soc_card *card,
+				   struct device_node *np,
 				   const char *propname)
 {
-	struct device_node *np = card->dev->of_node;
 	int num_routes;
 	struct snd_soc_dapm_route *routes;
 	int i, ret;
 
+	if (!np)
+		np = card->dev->of_node;
+
 	num_routes = of_property_count_strings(np, propname);
 	if (num_routes < 0 || num_routes & 1) {
 		dev_err(card->dev,
@@ -3673,7 +3676,7 @@ int snd_soc_of_parse_audio_routing(struct snd_soc_card *card,
 
 	return 0;
 }
-EXPORT_SYMBOL_GPL(snd_soc_of_parse_audio_routing);
+EXPORT_SYMBOL_GPL(snd_soc_of_parse_audio_routing_from_node);
 
 unsigned int snd_soc_of_parse_daifmt(struct device_node *np,
 				     const char *prefix,
-- 
1.9.1

^ permalink raw reply related

* [PATCH 02/17] ASoC: soc-core: adjust for graph on snd_soc_of_parse_audio_simple_widgets
From: Kuninori Morimoto @ 2016-10-31  1:15 UTC (permalink / raw)
  To: Rob Herring, Mark Brown
  Cc: Linux-ALSA, Liam Girdwood, Simon, Laurent, Guennadi, Grant Likely,
	Frank Rowand, Linux-DT, Linux-Kernel
In-Reply-To: <87pomhba6r.wl%kuninori.morimoto.gx@renesas.com>

From: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>

It is assuming that the card related information is located on
"card" node, but graph case doesn't have it.
This patch adds node parameter to adjust for graph support

Signed-off-by: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
---
 include/sound/soc.h  | 8 ++++++--
 sound/soc/soc-core.c | 9 ++++++---
 2 files changed, 12 insertions(+), 5 deletions(-)

diff --git a/include/sound/soc.h b/include/sound/soc.h
index 7fff456..a091c66 100644
--- a/include/sound/soc.h
+++ b/include/sound/soc.h
@@ -1647,8 +1647,12 @@ static inline struct snd_soc_platform *snd_soc_kcontrol_platform(
 int snd_soc_of_parse_card_name_from_node(struct snd_soc_card *card,
 					 struct device_node *np,
 					 const char *propname);
-int snd_soc_of_parse_audio_simple_widgets(struct snd_soc_card *card,
-					  const char *propname);
+#define snd_soc_of_parse_audio_simple_widgets(card, propname)\
+	snd_soc_of_parse_audio_simple_widgets_from_node(card, NULL, propname)
+int snd_soc_of_parse_audio_simple_widgets_from_node(struct snd_soc_card *card,
+						    struct device_node *np,
+						    const char *propname);
+
 int snd_soc_of_parse_tdm_slot(struct device_node *np,
 			      unsigned int *tx_mask,
 			      unsigned int *rx_mask,
diff --git a/sound/soc/soc-core.c b/sound/soc/soc-core.c
index 088a158..e56ea42 100644
--- a/sound/soc/soc-core.c
+++ b/sound/soc/soc-core.c
@@ -3462,14 +3462,17 @@ int snd_soc_of_parse_card_name_from_node(struct snd_soc_card *card,
 	SND_SOC_DAPM_SPK("Speaker", NULL),
 };
 
-int snd_soc_of_parse_audio_simple_widgets(struct snd_soc_card *card,
+int snd_soc_of_parse_audio_simple_widgets_from_node(struct snd_soc_card *card,
+					  struct device_node *np,
 					  const char *propname)
 {
-	struct device_node *np = card->dev->of_node;
 	struct snd_soc_dapm_widget *widgets;
 	const char *template, *wname;
 	int i, j, num_widgets, ret;
 
+	if (!np)
+		np = card->dev->of_node;
+
 	num_widgets = of_property_count_strings(np, propname);
 	if (num_widgets < 0) {
 		dev_err(card->dev,
@@ -3540,7 +3543,7 @@ int snd_soc_of_parse_audio_simple_widgets(struct snd_soc_card *card,
 
 	return 0;
 }
-EXPORT_SYMBOL_GPL(snd_soc_of_parse_audio_simple_widgets);
+EXPORT_SYMBOL_GPL(snd_soc_of_parse_audio_simple_widgets_from_node);
 
 static int snd_soc_of_get_slot_mask(struct device_node *np,
 				    const char *prop_name,
-- 
1.9.1

^ permalink raw reply related

* [PATCH 01/17] ASoC: soc-core: adjust for graph on snd_soc_of_parse_card_name
From: Kuninori Morimoto @ 2016-10-31  1:15 UTC (permalink / raw)
  To: Rob Herring, Mark Brown
  Cc: Linux-ALSA, Liam Girdwood, Simon, Laurent, Guennadi, Grant Likely,
	Frank Rowand, Linux-DT, Linux-Kernel
In-Reply-To: <87pomhba6r.wl%kuninori.morimoto.gx@renesas.com>

From: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>

It is assuming that the card related information is located on
"card" node, but graph case doesn't have it.
This patch adds node parameter to adjust for graph support

Signed-off-by: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
---
 include/sound/soc.h  |  7 +++++--
 sound/soc/soc-core.c | 11 ++++++-----
 2 files changed, 11 insertions(+), 7 deletions(-)

diff --git a/include/sound/soc.h b/include/sound/soc.h
index 91a8a03..7fff456 100644
--- a/include/sound/soc.h
+++ b/include/sound/soc.h
@@ -1642,8 +1642,11 @@ static inline struct snd_soc_platform *snd_soc_kcontrol_platform(
 int snd_soc_util_init(void);
 void snd_soc_util_exit(void);
 
-int snd_soc_of_parse_card_name(struct snd_soc_card *card,
-			       const char *propname);
+#define snd_soc_of_parse_card_name(card, propname) \
+	snd_soc_of_parse_card_name_from_node(card, NULL, propname)
+int snd_soc_of_parse_card_name_from_node(struct snd_soc_card *card,
+					 struct device_node *np,
+					 const char *propname);
 int snd_soc_of_parse_audio_simple_widgets(struct snd_soc_card *card,
 					  const char *propname);
 int snd_soc_of_parse_tdm_slot(struct device_node *np,
diff --git a/sound/soc/soc-core.c b/sound/soc/soc-core.c
index c0bbcd9..088a158 100644
--- a/sound/soc/soc-core.c
+++ b/sound/soc/soc-core.c
@@ -3424,10 +3424,10 @@ void snd_soc_unregister_codec(struct device *dev)
 EXPORT_SYMBOL_GPL(snd_soc_unregister_codec);
 
 /* Retrieve a card's name from device tree */
-int snd_soc_of_parse_card_name(struct snd_soc_card *card,
-			       const char *propname)
+int snd_soc_of_parse_card_name_from_node(struct snd_soc_card *card,
+					 struct device_node *np,
+					 const char *propname)
 {
-	struct device_node *np;
 	int ret;
 
 	if (!card->dev) {
@@ -3435,7 +3435,8 @@ int snd_soc_of_parse_card_name(struct snd_soc_card *card,
 		return -EINVAL;
 	}
 
-	np = card->dev->of_node;
+	if (!np)
+		np = card->dev->of_node;
 
 	ret = of_property_read_string_index(np, propname, 0, &card->name);
 	/*
@@ -3452,7 +3453,7 @@ int snd_soc_of_parse_card_name(struct snd_soc_card *card,
 
 	return 0;
 }
-EXPORT_SYMBOL_GPL(snd_soc_of_parse_card_name);
+EXPORT_SYMBOL_GPL(snd_soc_of_parse_card_name_from_node);
 
 static const struct snd_soc_dapm_widget simple_widgets[] = {
 	SND_SOC_DAPM_MIC("Microphone", NULL),
-- 
1.9.1

^ permalink raw reply related

* [PATCH 0/17 v2] ASoC: add OF graph base simple-card
From: Kuninori Morimoto @ 2016-10-31  1:14 UTC (permalink / raw)
  To: Rob Herring, Mark Brown
  Cc: Linux-ALSA, Liam Girdwood, Simon, Laurent, Guennadi, Grant Likely,
	Frank Rowand, Linux-DT, Linux-Kernel


Hi Rob, Mark

These are v2 of OF graph base simple-card patch-set.
 1) -  5) : soc-core prepare for OF graph base simple-card
 6) - 10) : OF graph new feature
11) - 17) : OF graph base simple-card (depends on above 2 patch-set)

This series removed "type = xxx" property from v1 patch series.
but, still have property on port/endpoint

Kuninori Morimoto (17):
       1) ASoC: soc-core: adjust for graph on snd_soc_of_parse_card_name
       2) ASoC: soc-core: adjust for graph on snd_soc_of_parse_audio_simple_widgets
       3) ASoC: soc-core: adjust for graph on snd_soc_of_parse_audio_routing
       4) ASoC: soc-core: adjust for graph on snd_soc_of_parse_audio_prefix
       5) ASoC: soc-core: snd_soc_get_dai_name() become non static
       6) of_graph: add of_graph_get_remote_endpoint()
       7) of_graph: add of_graph_get_port_parent()
       8) of_graph: add of_graph_get_top_port()
       9) of_graph: add for_each_of_port() / for_each_of_endpoint_in_port()
      10) of_graph: add of_graph_get_port/endpoint_count()
      11) ASoC: simple-card-utils: add asoc_simple_card_parse_graph_dai()
      12) ASoC: simple-card-utils: add asoc_simple_card_try_to_probe_graph_card()
      13) ASoC: simple-card-utils: adjust for graph on asoc_simple_card_parse_card_name
      14) ASoC: add simple-graph-card document
      15) ASoC: add simple-graph-card support
      16) ASoC: add simple-graph-scu-card document
      17) ASoC: add simple-graph-scu-card support

 Documentation/devicetree/bindings/sound/simple-graph-card.txt     |  62 +++++++++++++
 Documentation/devicetree/bindings/sound/simple-graph-scu-card.txt |  63 +++++++++++++
 drivers/of/base.c                                                 | 160 ++++++++++++++++++++++++++++++---
 include/linux/of_graph.h                                          |  54 +++++++++++
 include/sound/simple_card_utils.h                                 |  19 ++++
 include/sound/soc.h                                               |  32 +++++--
 sound/soc/generic/Kconfig                                         |  15 ++++
 sound/soc/generic/Makefile                                        |   4 +
 sound/soc/generic/simple-card-utils.c                             |  98 +++++++++++++++++++-
 sound/soc/generic/simple-card.c                                   |   2 +-
 sound/soc/generic/simple-graph-card.c                             | 462 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 sound/soc/generic/simple-graph-scu-card.c                         | 417 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 sound/soc/generic/simple-scu-card.c                               |   2 +-
 sound/soc/soc-core.c                                              |  41 +++++----
 14 files changed, 1396 insertions(+), 35 deletions(-)

^ permalink raw reply

* Re: [PATCH] arm64: dts: mt8173: Fix auxadc node
From: Matthias Brugger @ 2016-10-31  0:15 UTC (permalink / raw)
  To: robh+dt-DgEjT+Ai2ygdnm+yROfE0A, mark.rutland-5wv7dgnIgG8,
	will.deacon-5wv7dgnIgG8, zhiyong.tao-NuS5LvNUpcJWk0Htik3J/w,
	s.hauer-bIcnvbaLZ9MEGnE8C9+IrQ
  Cc: djkurtz-F7+t8E8rja9g9hUCZPvPmw, p.zabel-bIcnvbaLZ9MEGnE8C9+IrQ,
	hans.verkuil-FYB4Gu1CFyUAvxtiuMwx3w,
	andrew-ct.chen-NuS5LvNUpcJWk0Htik3J/w,
	ck.hu-NuS5LvNUpcJWk0Htik3J/w, bayi.cheng-NuS5LvNUpcJWk0Htik3J/w,
	yong.wu-NuS5LvNUpcJWk0Htik3J/w,
	dawei.chien-NuS5LvNUpcJWk0Htik3J/w,
	chunfeng.yun-NuS5LvNUpcJWk0Htik3J/w,
	tiffany.lin-NuS5LvNUpcJWk0Htik3J/w,
	fan.chen-NuS5LvNUpcJWk0Htik3J/w,
	devicetree-u79uwXL29TY76Z2rM5mHXA,
	linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r,
	linux-kernel-u79uwXL29TY76Z2rM5mHXA,
	linux-mediatek-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r
In-Reply-To: <20161026141500.27105-1-matthias.bgg-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>



On 10/26/2016 04:15 PM, Matthias Brugger wrote:
> The devicetree node for mt8173-auxadc lacks the clock and
> io-channel-cells property. This leads to a non-working driver.
>
> 	mt6577-auxadc 11001000.auxadc: failed to get auxadc clock
> 	mt6577-auxadc: probe of 11001000.auxadc failed with error -2
>
> Fix these fields to get the device up and running.
>
> Fixes: 748c7d4de46a ("ARM64: dts: mt8173: Add thermal/auxadc device
> nodes")
> Signed-off-by: Matthias Brugger <matthias.bgg-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
> ---

Applied.
--
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


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