From 5f17e24bea60b696815d2c6cb578e1e23f61cd57 Mon Sep 17 00:00:00 2001 From: Phil Elwell Date: Wed, 12 Nov 2014 17:07:02 +0000 Subject: [PATCH 064/114] Adding Device Tree support for some RPi audio cards --- arch/arm/boot/dts/Makefile | 2 + arch/arm/boot/dts/bcm2708-rpi-b-plus.dts | 81 +++++++++++++++++++++++++ arch/arm/boot/dts/bcm2708-rpi-b.dts | 19 +++++- arch/arm/boot/dts/bcm2708.dtsi | 18 ++++-- arch/arm/boot/dts/hifiberry-dac-overlay.dts | 34 +++++++++++ arch/arm/boot/dts/hifiberry-dacplus-overlay.dts | 39 ++++++++++++ arch/arm/boot/dts/hifiberry-digi-overlay.dts | 39 ++++++++++++ arch/arm/boot/dts/iqaudio-dac-overlay.dts | 39 ++++++++++++ arch/arm/boot/dts/iqaudio-dacplus-overlay.dts | 39 ++++++++++++ sound/soc/bcm/hifiberry_dac.c | 22 +++++++ sound/soc/bcm/hifiberry_dacplus.c | 22 +++++++ sound/soc/bcm/hifiberry_digi.c | 22 +++++++ sound/soc/bcm/iqaudio-dac.c | 16 +++++ sound/soc/codecs/pcm5102a.c | 7 +++ 14 files changed, 393 insertions(+), 6 deletions(-) create mode 100644 arch/arm/boot/dts/bcm2708-rpi-b-plus.dts create mode 100644 arch/arm/boot/dts/hifiberry-dac-overlay.dts create mode 100644 arch/arm/boot/dts/hifiberry-dacplus-overlay.dts create mode 100644 arch/arm/boot/dts/hifiberry-digi-overlay.dts create mode 100644 arch/arm/boot/dts/iqaudio-dac-overlay.dts create mode 100644 arch/arm/boot/dts/iqaudio-dacplus-overlay.dts --- a/arch/arm/boot/dts/Makefile +++ b/arch/arm/boot/dts/Makefile @@ -54,6 +54,7 @@ dtb-$(CONFIG_ARCH_AT91) += at91-sama5d4e dtb-$(CONFIG_ARCH_ATLAS6) += atlas6-evb.dtb dtb-$(CONFIG_ARCH_AXXIA) += axm5516-amarillo.dtb dtb-$(CONFIG_BCM2708_DT) += bcm2708-rpi-b.dtb +dtb-$(CONFIG_BCM2708_DT) += bcm2708-rpi-b-plus.dtb dtb-$(CONFIG_ARCH_BCM2835) += bcm2835-rpi-b.dtb dtb-$(CONFIG_ARCH_BCM_5301X) += bcm4708-netgear-r6250.dtb dtb-$(CONFIG_ARCH_BCM_63XX) += bcm963138dvt.dtb @@ -520,6 +521,7 @@ dtb-$(CONFIG_ARCH_MEDIATEK) += mt6589-aq targets += dtbs dtbs_install targets += $(dtb-y) + endif # *.dtb used to be generated in the directory above. Clean out the --- /dev/null +++ b/arch/arm/boot/dts/bcm2708-rpi-b-plus.dts @@ -0,0 +1,81 @@ +/dts-v1/; + +/include/ "bcm2708.dtsi" + +/ { + compatible = "brcm,bcm2708"; + model = "Raspberry Pi Model B+"; + + aliases { + spi0 = &spi0; + i2c0 = &i2c0; + i2c1 = &i2c1; + i2s = &i2s; + gpio = &gpio; + sound = &sound; + }; + + sound: sound { + }; +}; + +&gpio { + spi0_pins: spi0_pins { + brcm,pins = <7 8 9 10 11>; + brcm,function = <4>; /* alt0 */ + }; + + i2c0_pins: i2c0 { + brcm,pins = <0 1>; + brcm,function = <4>; + }; + + i2c1_pins: i2c1 { + brcm,pins = <2 3>; + brcm,function = <4>; + }; + + i2s_pins: i2s { + brcm,pins = <18 19 20 21>; + brcm,function = <4>; /* alt0 */ + }; +}; + +&spi0 { + pinctrl-names = "default"; + pinctrl-0 = <&spi0_pins>; + + spidev@0{ + compatible = "spidev"; + reg = <0>; /* CE0 */ + #address-cells = <1>; + #size-cells = <0>; + spi-max-frequency = <500000>; + }; + + spidev@1{ + compatible = "spidev"; + reg = <1>; /* CE1 */ + #address-cells = <1>; + #size-cells = <0>; + spi-max-frequency = <500000>; + }; +}; + +&i2c0 { + pinctrl-names = "default"; + pinctrl-0 = <&i2c0_pins>; + clock-frequency = <100000>; +}; + +&i2c1 { + pinctrl-names = "default"; + pinctrl-0 = <&i2c1_pins>; + clock-frequency = <100000>; +}; + +&i2s { + #sound-dai-cells = <0>; + pinctrl-names = "default"; + pinctrl-0 = <&i2s_pins>; +}; --- a/arch/arm/boot/dts/bcm2708-rpi-b.dts +++ b/arch/arm/boot/dts/bcm2708-rpi-b.dts @@ -4,12 +4,18 @@ / { compatible = "brcm,bcm2708"; - model = "Raspberry Pi"; + model = "Raspberry Pi Model B"; aliases { spi0 = &spi0; i2c0 = &i2c0; i2c1 = &i2c1; + i2s = &i2s; + gpio = &gpio; + sound = &sound; + }; + + sound: sound { }; }; @@ -28,6 +34,11 @@ brcm,pins = <2 3>; brcm,function = <4>; }; + + i2s_pins: i2s { + brcm,pins = <28 29 30 31>; + brcm,function = <4>; /* alt0 */ + }; }; &spi0 { @@ -62,3 +73,9 @@ pinctrl-0 = <&i2c1_pins>; clock-frequency = <100000>; }; + +&i2s { + #sound-dai-cells = <0>; + pinctrl-names = "default"; + pinctrl-0 = <&i2s_pins>; +}; --- a/arch/arm/boot/dts/bcm2708.dtsi +++ b/arch/arm/boot/dts/bcm2708.dtsi @@ -7,11 +7,8 @@ interrupt-parent = <&intc>; chosen { - /* - bootargs must be 1024 characters long because the - VC bootloader can't expand it - */ - bootargs = "console=ttyAMA0 "; + /* No padding required - the boot loader can do that. */ + bootargs = ""; }; soc { @@ -39,6 +36,17 @@ #interrupt-cells = <2>; }; + i2s: i2s@7e203000 { + compatible = "brcm,bcm2708-i2s"; + reg = <0x7e203000 0x20>, + <0x7e101098 0x02>; + + //dmas = <&dma 2>, + // <&dma 3>; + dma-names = "tx", "rx"; + status = "disabled"; + }; + spi0: spi@7e204000 { compatible = "brcm,bcm2708-spi"; reg = <0x7e204000 0x1000>; --- /dev/null +++ b/arch/arm/boot/dts/hifiberry-dac-overlay.dts @@ -0,0 +1,34 @@ +// Definitions for HiFiBerry DAC +/dts-v1/; +/plugin/; + +/ { + compatible = "brcm,bcm2708"; + + fragment@0 { + target = <&sound>; + __overlay__ { + compatible = "hifiberry,hifiberry-dac"; + i2s-controller = <&i2s>; + status = "okay"; + }; + }; + + fragment@1 { + target = <&i2s>; + __overlay__ { + status = "okay"; + }; + }; + + fragment@2 { + target-path = "/"; + __overlay__ { + pcm5102a-codec { + #sound-dai-cells = <0>; + compatible = "ti,pcm5102a"; + status = "okay"; + }; + }; + }; +}; --- /dev/null +++ b/arch/arm/boot/dts/hifiberry-dacplus-overlay.dts @@ -0,0 +1,39 @@ +// Definitions for HiFiBerry DAC+ +/dts-v1/; +/plugin/; + +/ { + compatible = "brcm,bcm2708"; + + fragment@0 { + target = <&sound>; + __overlay__ { + compatible = "hifiberry,hifiberry-dacplus"; + i2s-controller = <&i2s>; + status = "okay"; + }; + }; + + fragment@1 { + target = <&i2s>; + __overlay__ { + status = "okay"; + }; + }; + + fragment@2 { + target = <&i2c1>; + __overlay__ { + #address-cells = <1>; + #size-cells = <0>; + status = "okay"; + + pcm5122@4d { + #sound-dai-cells = <0>; + compatible = "ti,pcm5122"; + reg = <0x4d>; + status = "okay"; + }; + }; + }; +}; --- /dev/null +++ b/arch/arm/boot/dts/hifiberry-digi-overlay.dts @@ -0,0 +1,39 @@ +// Definitions for HiFiBerry Digi +/dts-v1/; +/plugin/; + +/ { + compatible = "brcm,bcm2708"; + + fragment@0 { + target = <&sound>; + __overlay__ { + compatible = "hifiberry,hifiberry-digi"; + i2s-controller = <&i2s>; + status = "okay"; + }; + }; + + fragment@1 { + target = <&i2s>; + __overlay__ { + status = "okay"; + }; + }; + + fragment@2 { + target = <&i2c1>; + __overlay__ { + #address-cells = <1>; + #size-cells = <0>; + status = "okay"; + + wm8804@3b { + #sound-dai-cells = <0>; + compatible = "wlf,wm8804"; + reg = <0x3b>; + status = "okay"; + }; + }; + }; +}; --- /dev/null +++ b/arch/arm/boot/dts/iqaudio-dac-overlay.dts @@ -0,0 +1,39 @@ +// Definitions for IQaudIO DAC +/dts-v1/; +/plugin/; + +/ { + compatible = "brcm,bcm2708"; + + fragment@0 { + target = <&sound>; + __overlay__ { + compatible = "iqaudio,iqaudio-dac"; + i2s-controller = <&i2s>; + status = "okay"; + }; + }; + + fragment@1 { + target = <&i2s>; + __overlay__ { + status = "okay"; + }; + }; + + fragment@2 { + target = <&i2c1>; + __overlay__ { + #address-cells = <1>; + #size-cells = <0>; + status = "okay"; + + pcm5122@4c { + #sound-dai-cells = <0>; + compatible = "ti,pcm5122"; + reg = <0x4c>; + status = "okay"; + }; + }; + }; +}; --- /dev/null +++ b/arch/arm/boot/dts/iqaudio-dacplus-overlay.dts @@ -0,0 +1,39 @@ +// Definitions for IQaudIO DAC+ +/dts-v1/; +/plugin/; + +/ { + compatible = "brcm,bcm2708"; + + fragment@0 { + target = <&sound>; + __overlay__ { + compatible = "iqaudio,iqaudio-dac"; + i2s-controller = <&i2s>; + status = "okay"; + }; + }; + + fragment@1 { + target = <&i2s>; + __overlay__ { + status = "okay"; + }; + }; + + fragment@2 { + target = <&i2c1>; + __overlay__ { + #address-cells = <1>; + #size-cells = <0>; + status = "okay"; + + pcm5122@4c { + #sound-dai-cells = <0>; + compatible = "ti,pcm5122"; + reg = <0x4c>; + status = "okay"; + }; + }; + }; +}; --- a/sound/soc/bcm/hifiberry_dac.c +++ b/sound/soc/bcm/hifiberry_dac.c @@ -72,6 +72,21 @@ static int snd_rpi_hifiberry_dac_probe(s int ret = 0; snd_rpi_hifiberry_dac.dev = &pdev->dev; + + if (pdev->dev.of_node) { + struct device_node *i2s_node; + struct snd_soc_dai_link *dai = &snd_rpi_hifiberry_dac_dai[0]; + i2s_node = of_parse_phandle(pdev->dev.of_node, + "i2s-controller", 0); + + if (i2s_node) { + dai->cpu_dai_name = NULL; + dai->cpu_of_node = i2s_node; + dai->platform_name = NULL; + dai->platform_of_node = i2s_node; + } + } + ret = snd_soc_register_card(&snd_rpi_hifiberry_dac); if (ret) dev_err(&pdev->dev, "snd_soc_register_card() failed: %d\n", ret); @@ -84,10 +99,17 @@ static int snd_rpi_hifiberry_dac_remove( return snd_soc_unregister_card(&snd_rpi_hifiberry_dac); } +static const struct of_device_id snd_rpi_hifiberry_dac_of_match[] = { + { .compatible = "hifiberry,hifiberry-dac", }, + {}, +}; +MODULE_DEVICE_TABLE(of, snd_rpi_hifiberry_dac_of_match); + static struct platform_driver snd_rpi_hifiberry_dac_driver = { .driver = { .name = "snd-hifiberry-dac", .owner = THIS_MODULE, + .of_match_table = snd_rpi_hifiberry_dac_of_match, }, .probe = snd_rpi_hifiberry_dac_probe, .remove = snd_rpi_hifiberry_dac_remove, --- a/sound/soc/bcm/hifiberry_dacplus.c +++ b/sound/soc/bcm/hifiberry_dacplus.c @@ -90,6 +90,21 @@ static int snd_rpi_hifiberry_dacplus_pro int ret = 0; snd_rpi_hifiberry_dacplus.dev = &pdev->dev; + + if (pdev->dev.of_node) { + struct device_node *i2s_node; + struct snd_soc_dai_link *dai = &snd_rpi_hifiberry_dacplus_dai[0]; + i2s_node = of_parse_phandle(pdev->dev.of_node, + "i2s-controller", 0); + + if (i2s_node) { + dai->cpu_dai_name = NULL; + dai->cpu_of_node = i2s_node; + dai->platform_name = NULL; + dai->platform_of_node = i2s_node; + } + } + ret = snd_soc_register_card(&snd_rpi_hifiberry_dacplus); if (ret) dev_err(&pdev->dev, @@ -103,10 +118,17 @@ static int snd_rpi_hifiberry_dacplus_rem return snd_soc_unregister_card(&snd_rpi_hifiberry_dacplus); } +static const struct of_device_id snd_rpi_hifiberry_dacplus_of_match[] = { + { .compatible = "hifiberry,hifiberry-dacplus", }, + {}, +}; +MODULE_DEVICE_TABLE(of, snd_rpi_hifiberry_dacplus_of_match); + static struct platform_driver snd_rpi_hifiberry_dacplus_driver = { .driver = { .name = "snd-rpi-hifiberry-dacplus", .owner = THIS_MODULE, + .of_match_table = snd_rpi_hifiberry_dacplus_of_match, }, .probe = snd_rpi_hifiberry_dacplus_probe, .remove = snd_rpi_hifiberry_dacplus_remove, --- a/sound/soc/bcm/hifiberry_digi.c +++ b/sound/soc/bcm/hifiberry_digi.c @@ -125,6 +125,21 @@ static int snd_rpi_hifiberry_digi_probe( int ret = 0; snd_rpi_hifiberry_digi.dev = &pdev->dev; + + if (pdev->dev.of_node) { + struct device_node *i2s_node; + struct snd_soc_dai_link *dai = &snd_rpi_hifiberry_digi_dai[0]; + i2s_node = of_parse_phandle(pdev->dev.of_node, + "i2s-controller", 0); + + if (i2s_node) { + dai->cpu_dai_name = NULL; + dai->cpu_of_node = i2s_node; + dai->platform_name = NULL; + dai->platform_of_node = i2s_node; + } + } + ret = snd_soc_register_card(&snd_rpi_hifiberry_digi); if (ret) dev_err(&pdev->dev, "snd_soc_register_card() failed: %d\n", ret); @@ -137,10 +152,17 @@ static int snd_rpi_hifiberry_digi_remove return snd_soc_unregister_card(&snd_rpi_hifiberry_digi); } +static const struct of_device_id snd_rpi_hifiberry_digi_of_match[] = { + { .compatible = "hifiberry,hifiberry-digi", }, + {}, +}; +MODULE_DEVICE_TABLE(of, snd_rpi_hifiberry_digi_of_match); + static struct platform_driver snd_rpi_hifiberry_digi_driver = { .driver = { .name = "snd-hifiberry-digi", .owner = THIS_MODULE, + .of_match_table = snd_rpi_hifiberry_digi_of_match, }, .probe = snd_rpi_hifiberry_digi_probe, .remove = snd_rpi_hifiberry_digi_remove, --- a/sound/soc/bcm/iqaudio-dac.c +++ b/sound/soc/bcm/iqaudio-dac.c @@ -76,6 +76,21 @@ static int snd_rpi_iqaudio_dac_probe(str int ret = 0; snd_rpi_iqaudio_dac.dev = &pdev->dev; + + if (pdev->dev.of_node) { + struct device_node *i2s_node; + struct snd_soc_dai_link *dai = &snd_rpi_iqaudio_dac_dai[0]; + i2s_node = of_parse_phandle(pdev->dev.of_node, + "i2s-controller", 0); + + if (i2s_node) { + dai->cpu_dai_name = NULL; + dai->cpu_of_node = i2s_node; + dai->platform_name = NULL; + dai->platform_of_node = i2s_node; + } + } + ret = snd_soc_register_card(&snd_rpi_iqaudio_dac); if (ret) dev_err(&pdev->dev, @@ -93,6 +108,7 @@ static const struct of_device_id iqaudio { .compatible = "iqaudio,iqaudio-dac", }, {}, }; +MODULE_DEVICE_TABLE(of, iqaudio_of_match); static struct platform_driver snd_rpi_iqaudio_dac_driver = { .driver = { --- a/sound/soc/codecs/pcm5102a.c +++ b/sound/soc/codecs/pcm5102a.c @@ -47,12 +47,19 @@ static int pcm5102a_remove(struct platfo return 0; } +static const struct of_device_id pcm5102a_of_match[] = { + { .compatible = "ti,pcm5102a", }, + { } +}; +MODULE_DEVICE_TABLE(of, pcm5102a_of_match); + static struct platform_driver pcm5102a_codec_driver = { .probe = pcm5102a_probe, .remove = pcm5102a_remove, .driver = { .name = "pcm5102a-codec", .owner = THIS_MODULE, + .of_match_table = pcm5102a_of_match, }, };