* 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
page: next (older) | prev (newer) | latest
- recent:[subjects (threaded)|topics (new)|topics (active)]
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox