summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNoralf Trønnes <noralf@tronnes.org>2015-05-21 13:24:35 +0200
committerNoralf Trønnes <noralf@tronnes.org>2015-05-21 13:24:35 +0200
commite21bb15f8f84d25c411f5b9d6f723fd7da1f344f (patch)
tree67b912863d739c5f04c00c3043117dbfddb2759d
parente72ad4baf37e44f32adda600b20f443c56130bcf (diff)
downloadlinux-e21bb15f8f84d25c411f5b9d6f723fd7da1f344f.tar.gz
BCM270x: Add onboard sound device to Device Tree
Add Device Tree support to alsa driver. Add device to Device Tree. Don't add platform devices when booting in DT mode. Signed-off-by: Noralf Trønnes <noralf@tronnes.org>
-rw-r--r--arch/arm/boot/dts/bcm2708-rpi-b-plus.dts4
-rw-r--r--arch/arm/boot/dts/bcm2708-rpi-b.dts4
-rw-r--r--[-rwxr-xr-x]arch/arm/boot/dts/bcm2708-rpi-cm.dtsi4
-rw-r--r--arch/arm/boot/dts/bcm2708_common.dtsi7
-rw-r--r--arch/arm/boot/dts/bcm2709-rpi-2-b.dts4
-rw-r--r--arch/arm/mach-bcm2708/bcm2708.c2
-rw-r--r--arch/arm/mach-bcm2709/bcm2709.c2
-rw-r--r--sound/arm/Kconfig3
-rw-r--r--[-rwxr-xr-x]sound/arm/bcm2835.c91
9 files changed, 118 insertions, 3 deletions
diff --git a/arch/arm/boot/dts/bcm2708-rpi-b-plus.dts b/arch/arm/boot/dts/bcm2708-rpi-b-plus.dts
index 9a8fed03ada7..6323c5b8158e 100644
--- a/arch/arm/boot/dts/bcm2708-rpi-b-plus.dts
+++ b/arch/arm/boot/dts/bcm2708-rpi-b-plus.dts
@@ -53,6 +53,10 @@
status = "okay";
};
+&audio {
+ status = "okay";
+};
+
&spi0 {
pinctrl-names = "default";
pinctrl-0 = <&spi0_pins>;
diff --git a/arch/arm/boot/dts/bcm2708-rpi-b.dts b/arch/arm/boot/dts/bcm2708-rpi-b.dts
index cf67ec94e91c..e1fe6a4d37f4 100644
--- a/arch/arm/boot/dts/bcm2708-rpi-b.dts
+++ b/arch/arm/boot/dts/bcm2708-rpi-b.dts
@@ -53,6 +53,10 @@
status = "okay";
};
+&audio {
+ status = "okay";
+};
+
&spi0 {
pinctrl-names = "default";
pinctrl-0 = <&spi0_pins>;
diff --git a/arch/arm/boot/dts/bcm2708-rpi-cm.dtsi b/arch/arm/boot/dts/bcm2708-rpi-cm.dtsi
index 815a3a4b2d96..1c2cfcfa0bb4 100755..100644
--- a/arch/arm/boot/dts/bcm2708-rpi-cm.dtsi
+++ b/arch/arm/boot/dts/bcm2708-rpi-cm.dtsi
@@ -34,6 +34,10 @@
status = "okay";
};
+&audio {
+ status = "okay";
+};
+
/ {
__overrides__ {
act_led_gpio = <&act_led>,"gpios:4";
diff --git a/arch/arm/boot/dts/bcm2708_common.dtsi b/arch/arm/boot/dts/bcm2708_common.dtsi
index 2d9bcd8ac97d..4bf6960e4176 100644
--- a/arch/arm/boot/dts/bcm2708_common.dtsi
+++ b/arch/arm/boot/dts/bcm2708_common.dtsi
@@ -3,6 +3,13 @@
/ {
interrupt-parent = <&intc>;
+ /* Onboard audio */
+ audio: audio {
+ compatible = "brcm,bcm2835-audio";
+ brcm,pwm-channels = <8>;
+ status = "disabled";
+ };
+
soc: soc {
compatible = "simple-bus";
#address-cells = <1>;
diff --git a/arch/arm/boot/dts/bcm2709-rpi-2-b.dts b/arch/arm/boot/dts/bcm2709-rpi-2-b.dts
index 1c865de5daf7..921add1d82d3 100644
--- a/arch/arm/boot/dts/bcm2709-rpi-2-b.dts
+++ b/arch/arm/boot/dts/bcm2709-rpi-2-b.dts
@@ -53,6 +53,10 @@
status = "okay";
};
+&audio {
+ status = "okay";
+};
+
&spi0 {
pinctrl-names = "default";
pinctrl-0 = <&spi0_pins>;
diff --git a/arch/arm/mach-bcm2708/bcm2708.c b/arch/arm/mach-bcm2708/bcm2708.c
index 81cc9885de43..e451187011c3 100644
--- a/arch/arm/mach-bcm2708/bcm2708.c
+++ b/arch/arm/mach-bcm2708/bcm2708.c
@@ -964,7 +964,7 @@ void __init bcm2708_init(void)
#endif
bcm2708_init_led();
for (i = 0; i < ARRAY_SIZE(bcm2708_alsa_devices); i++)
- bcm_register_device(&bcm2708_alsa_devices[i]);
+ bcm_register_device_dt(&bcm2708_alsa_devices[i]);
bcm_register_device_dt(&bcm2708_spi_device);
diff --git a/arch/arm/mach-bcm2709/bcm2709.c b/arch/arm/mach-bcm2709/bcm2709.c
index 528bf6e18e5d..06c2c74310c6 100644
--- a/arch/arm/mach-bcm2709/bcm2709.c
+++ b/arch/arm/mach-bcm2709/bcm2709.c
@@ -987,7 +987,7 @@ void __init bcm2709_init(void)
#endif
bcm2709_init_led();
for (i = 0; i < ARRAY_SIZE(bcm2708_alsa_devices); i++)
- bcm_register_device(&bcm2708_alsa_devices[i]);
+ bcm_register_device_dt(&bcm2708_alsa_devices[i]);
bcm_register_device_dt(&bcm2708_spi_device);
diff --git a/sound/arm/Kconfig b/sound/arm/Kconfig
index ada7ba2c951d..fcbe9d745e11 100644
--- a/sound/arm/Kconfig
+++ b/sound/arm/Kconfig
@@ -41,7 +41,8 @@ config SND_PXA2XX_AC97
config SND_BCM2835
tristate "BCM2835 ALSA driver"
- depends on (ARCH_BCM2708 || ARCH_BCM2709) && BCM2708_VCHIQ && SND
+ depends on (ARCH_BCM2708 || ARCH_BCM2709 || ARCH_BCM2835) \
+ && BCM2708_VCHIQ && SND
select SND_PCM
help
Say Y or M if you want to support BCM2835 Alsa pcm card driver
diff --git a/sound/arm/bcm2835.c b/sound/arm/bcm2835.c
index 7ed5079e44ca..6b545e786c56 100755..100644
--- a/sound/arm/bcm2835.c
+++ b/sound/arm/bcm2835.c
@@ -17,6 +17,7 @@
#include <linux/init.h>
#include <linux/slab.h>
#include <linux/module.h>
+#include <linux/of.h>
#include "bcm2835.h"
@@ -81,6 +82,86 @@ static int snd_bcm2835_create(struct snd_card *card,
return 0;
}
+static int snd_bcm2835_alsa_probe_dt(struct platform_device *pdev)
+{
+ struct device *dev = &pdev->dev;
+ bcm2835_chip_t *chip;
+ struct snd_card *card;
+ u32 numchans;
+ int err, i;
+
+ err = of_property_read_u32(dev->of_node, "brcm,pwm-channels",
+ &numchans);
+ if (err) {
+ dev_err(dev, "Failed to get DT property 'brcm,pwm-channels'");
+ return err;
+ }
+
+ if (numchans == 0 || numchans > MAX_SUBSTREAMS) {
+ numchans = MAX_SUBSTREAMS;
+ dev_warn(dev, "Illegal 'brcm,pwm-channels' value, will use %u\n",
+ numchans);
+ }
+
+ err = snd_card_new(NULL, -1, NULL, THIS_MODULE, 0, &card);
+ if (err) {
+ dev_err(dev, "Failed to create soundcard structure\n");
+ return err;
+ }
+
+ snd_card_set_dev(card, dev);
+ strcpy(card->driver, "bcm2835");
+ strcpy(card->shortname, "bcm2835 ALSA");
+ sprintf(card->longname, "%s", card->shortname);
+
+ err = snd_bcm2835_create(card, pdev, &chip);
+ if (err < 0) {
+ dev_err(dev, "Failed to create bcm2835 chip\n");
+ goto err_free;
+ }
+
+ err = snd_bcm2835_new_pcm(chip);
+ if (err < 0) {
+ dev_err(dev, "Failed to create new bcm2835 pcm device\n");
+ goto err_free;
+ }
+
+ err = snd_bcm2835_new_spdif_pcm(chip);
+ if (err < 0) {
+ dev_err(dev, "Failed to create new bcm2835 spdif pcm device\n");
+ goto err_free;
+ }
+
+ err = snd_bcm2835_new_ctl(chip);
+ if (err < 0) {
+ dev_err(dev, "Failed to create new bcm2835 ctl\n");
+ goto err_free;
+ }
+
+ for (i = 0; i < numchans; i++) {
+ chip->avail_substreams |= (1 << i);
+ chip->pdev[i] = pdev;
+ }
+
+ err = snd_card_register(card);
+ if (err) {
+ dev_err(dev, "Failed to register bcm2835 ALSA card \n");
+ goto err_free;
+ }
+
+ g_card = card;
+ g_chip = chip;
+ platform_set_drvdata(pdev, card);
+ audio_info("bcm2835 ALSA card created with %u channels\n", numchans);
+
+ return 0;
+
+err_free:
+ snd_card_free(card);
+
+ return err;
+}
+
static int snd_bcm2835_alsa_probe(struct platform_device *pdev)
{
static int dev;
@@ -88,6 +169,9 @@ static int snd_bcm2835_alsa_probe(struct platform_device *pdev)
struct snd_card *card;
int err;
+ if (pdev->dev.of_node)
+ return snd_bcm2835_alsa_probe_dt(pdev);
+
if (dev >= MAX_SUBSTREAMS)
return -ENODEV;
@@ -224,6 +308,12 @@ static int snd_bcm2835_alsa_resume(struct platform_device *pdev)
#endif
+static const struct of_device_id snd_bcm2835_of_match_table[] = {
+ { .compatible = "brcm,bcm2835-audio", },
+ {},
+};
+MODULE_DEVICE_TABLE(of, snd_bcm2835_of_match_table);
+
static struct platform_driver bcm2835_alsa0_driver = {
.probe = snd_bcm2835_alsa_probe,
.remove = snd_bcm2835_alsa_remove,
@@ -234,6 +324,7 @@ static struct platform_driver bcm2835_alsa0_driver = {
.driver = {
.name = "bcm2835_AUD0",
.owner = THIS_MODULE,
+ .of_match_table = snd_bcm2835_of_match_table,
},
};