mirror of
https://github.com/openwrt/openwrt.git
synced 2024-12-26 17:01:14 +00:00
7d7aa2fd92
This change makes the names of Broadcom targets consistent by using the common notation based on SoC/CPU ID (which is used internally anyway), bcmXXXX instead of brcmXXXX. This is even used for target TITLE in make menuconfig already, only the short target name used brcm so far. Despite, since subtargets range from bcm2708 to bcm2711, it seems appropriate to use bcm27xx instead of bcm2708 (again, as already done for BOARDNAME). This also renames the packages brcm2708-userland and brcm2708-gpu-fw. Signed-off-by: Adrian Schmutzler <freifunk@adrianschmutzler.de> Acked-by: Álvaro Fernández Rojas <noltari@gmail.com>
377 lines
11 KiB
Diff
377 lines
11 KiB
Diff
From 930c49de8674acda0f143f7bc182ed2fad8c4f9d Mon Sep 17 00:00:00 2001
|
|
From: IQaudIO <gordon@iqaudio.com>
|
|
Date: Mon, 13 May 2019 21:53:05 +0100
|
|
Subject: [PATCH] Added IQaudIO Pi-Codec board support (#2969)
|
|
|
|
Add support for the IQaudIO Pi-Codec board.
|
|
|
|
Signed-off-by: Gordon <gordon@iqaudio.com>
|
|
---
|
|
arch/arm/boot/dts/overlays/Makefile | 1 +
|
|
arch/arm/boot/dts/overlays/README | 6 +
|
|
.../dts/overlays/iqaudio-codec-overlay.dts | 42 +++
|
|
sound/soc/bcm/Kconfig | 7 +
|
|
sound/soc/bcm/Makefile | 2 +
|
|
sound/soc/bcm/iqaudio-codec.c | 250 ++++++++++++++++++
|
|
9 files changed, 311 insertions(+)
|
|
create mode 100644 arch/arm/boot/dts/overlays/iqaudio-codec-overlay.dts
|
|
create mode 100644 sound/soc/bcm/iqaudio-codec.c
|
|
|
|
--- a/arch/arm/boot/dts/overlays/Makefile
|
|
+++ b/arch/arm/boot/dts/overlays/Makefile
|
|
@@ -68,6 +68,7 @@ dtbo-$(CONFIG_ARCH_BCM2835) += \
|
|
i2c1-bcm2708.dtbo \
|
|
i2s-gpio28-31.dtbo \
|
|
ilitek251x.dtbo \
|
|
+ iqaudio-codec.dtbo \
|
|
iqaudio-dac.dtbo \
|
|
iqaudio-dacplus.dtbo \
|
|
iqaudio-digi-wm8804-audio.dtbo \
|
|
--- a/arch/arm/boot/dts/overlays/README
|
|
+++ b/arch/arm/boot/dts/overlays/README
|
|
@@ -1160,6 +1160,12 @@ Params: interrupt GPIO use
|
|
touchscreen (in pixels)
|
|
|
|
|
|
+Name: iqaudio-codec
|
|
+Info: Configures the IQaudio Codec audio card
|
|
+Load: dtoverlay=iqaudio-codec
|
|
+Params: <None>
|
|
+
|
|
+
|
|
Name: iqaudio-dac
|
|
Info: Configures the IQaudio DAC audio card
|
|
Load: dtoverlay=iqaudio-dac,<param>
|
|
--- /dev/null
|
|
+++ b/arch/arm/boot/dts/overlays/iqaudio-codec-overlay.dts
|
|
@@ -0,0 +1,42 @@
|
|
+// Definitions for IQaudIO CODEC
|
|
+/dts-v1/;
|
|
+/plugin/;
|
|
+
|
|
+/ {
|
|
+ compatible = "brcm,bcm2708";
|
|
+
|
|
+ fragment@0 {
|
|
+ target = <&i2s>;
|
|
+ __overlay__ {
|
|
+ status = "okay";
|
|
+ };
|
|
+ };
|
|
+
|
|
+ fragment@1 {
|
|
+ target = <&i2c1>;
|
|
+ __overlay__ {
|
|
+ #address-cells = <1>;
|
|
+ #size-cells = <0>;
|
|
+ status = "okay";
|
|
+
|
|
+ da2713@1a {
|
|
+ #sound-dai-cells = <0>;
|
|
+ compatible = "dlg,da7213";
|
|
+ reg = <0x1a>;
|
|
+ status = "okay";
|
|
+ };
|
|
+ };
|
|
+ };
|
|
+
|
|
+ fragment@2 {
|
|
+ target = <&sound>;
|
|
+ iqaudio_dac: __overlay__ {
|
|
+ compatible = "iqaudio,iqaudio-codec";
|
|
+ i2s-controller = <&i2s>;
|
|
+ status = "okay";
|
|
+ };
|
|
+ };
|
|
+
|
|
+ __overrides__ {
|
|
+ };
|
|
+};
|
|
--- a/sound/soc/bcm/Kconfig
|
|
+++ b/sound/soc/bcm/Kconfig
|
|
@@ -108,6 +108,13 @@ config SND_BCM2708_SOC_JUSTBOOM_DIGI
|
|
help
|
|
Say Y or M if you want to add support for JustBoom Digi.
|
|
|
|
+config SND_BCM2708_SOC_IQAUDIO_CODEC
|
|
+ tristate "Support for IQaudIO-CODEC"
|
|
+ depends on SND_BCM2708_SOC_I2S || SND_BCM2835_SOC_I2S
|
|
+ select SND_SOC_DA7213
|
|
+ help
|
|
+ Say Y or M if you want to add support for IQaudIO-CODEC.
|
|
+
|
|
config SND_BCM2708_SOC_IQAUDIO_DAC
|
|
tristate "Support for IQaudIO-DAC"
|
|
depends on SND_BCM2708_SOC_I2S || SND_BCM2835_SOC_I2S
|
|
--- a/sound/soc/bcm/Makefile
|
|
+++ b/sound/soc/bcm/Makefile
|
|
@@ -18,6 +18,7 @@ snd-soc-hifiberry-dacplusadc-objs := hif
|
|
snd-soc-justboom-dac-objs := justboom-dac.o
|
|
snd-soc-rpi-cirrus-objs := rpi-cirrus.o
|
|
snd-soc-rpi-proto-objs := rpi-proto.o
|
|
+snd-soc-iqaudio-codec-objs := iqaudio-codec.o
|
|
snd-soc-iqaudio-dac-objs := iqaudio-dac.o
|
|
snd-soc-i-sabre-q2m-objs := i-sabre-q2m.o
|
|
snd-soc-audioinjector-pi-soundcard-objs := audioinjector-pi-soundcard.o
|
|
@@ -42,6 +43,7 @@ obj-$(CONFIG_SND_BCM2708_SOC_HIFIBERRY_D
|
|
obj-$(CONFIG_SND_BCM2708_SOC_JUSTBOOM_DAC) += snd-soc-justboom-dac.o
|
|
obj-$(CONFIG_SND_BCM2708_SOC_RPI_CIRRUS) += snd-soc-rpi-cirrus.o
|
|
obj-$(CONFIG_SND_BCM2708_SOC_RPI_PROTO) += snd-soc-rpi-proto.o
|
|
+obj-$(CONFIG_SND_BCM2708_SOC_IQAUDIO_CODEC) += snd-soc-iqaudio-codec.o
|
|
obj-$(CONFIG_SND_BCM2708_SOC_IQAUDIO_DAC) += snd-soc-iqaudio-dac.o
|
|
obj-$(CONFIG_SND_BCM2708_SOC_I_SABRE_Q2M) += snd-soc-i-sabre-q2m.o
|
|
obj-$(CONFIG_SND_AUDIOINJECTOR_PI_SOUNDCARD) += snd-soc-audioinjector-pi-soundcard.o
|
|
--- /dev/null
|
|
+++ b/sound/soc/bcm/iqaudio-codec.c
|
|
@@ -0,0 +1,250 @@
|
|
+/*
|
|
+ * ASoC Driver for IQaudIO Raspberry Pi Codec board
|
|
+ *
|
|
+ * Author: Gordon Garrity <gordon@iqaudio.com>
|
|
+ * (C) Copyright IQaudio Limited, 2017-2019
|
|
+ *
|
|
+ * This program is free software; you can redistribute it and/or
|
|
+ * modify it under the terms of the GNU General Public License
|
|
+ * version 2 as published by the Free Software Foundation.
|
|
+ *
|
|
+ * This program is distributed in the hope that it will be useful, but
|
|
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
+ * General Public License for more details.
|
|
+ */
|
|
+
|
|
+#include <linux/module.h>
|
|
+#include <linux/gpio/consumer.h>
|
|
+#include <linux/platform_device.h>
|
|
+
|
|
+#include <sound/core.h>
|
|
+#include <sound/pcm.h>
|
|
+#include <sound/pcm_params.h>
|
|
+#include <sound/soc.h>
|
|
+#include <sound/jack.h>
|
|
+
|
|
+#include <linux/acpi.h>
|
|
+#include <linux/slab.h>
|
|
+#include "../codecs/da7213.h"
|
|
+
|
|
+static int pll_out = DA7213_PLL_FREQ_OUT_90316800;
|
|
+
|
|
+static int snd_rpi_iqaudio_pll_control(struct snd_soc_dapm_widget *w,
|
|
+ struct snd_kcontrol *k, int event)
|
|
+{
|
|
+ int ret = 0;
|
|
+ struct snd_soc_dapm_context *dapm = w->dapm;
|
|
+ struct snd_soc_card *card = dapm->card;
|
|
+ struct snd_soc_pcm_runtime *rtd =
|
|
+ snd_soc_get_pcm_runtime(card, card->dai_link[0].name);
|
|
+ struct snd_soc_dai *codec_dai = rtd->codec_dai;
|
|
+
|
|
+ if (SND_SOC_DAPM_EVENT_OFF(event)) {
|
|
+ ret = snd_soc_dai_set_pll(codec_dai, 0, DA7213_SYSCLK_MCLK, 0,
|
|
+ 0);
|
|
+ if (ret)
|
|
+ dev_err(card->dev, "Failed to bypass PLL: %d\n", ret);
|
|
+ } else if (SND_SOC_DAPM_EVENT_ON(event)) {
|
|
+ ret = snd_soc_dai_set_pll(codec_dai, 0, DA7213_SYSCLK_PLL, 0,
|
|
+ pll_out);
|
|
+ if (ret)
|
|
+ dev_err(card->dev, "Failed to enable PLL: %d\n", ret);
|
|
+ }
|
|
+
|
|
+ return ret;
|
|
+}
|
|
+
|
|
+static int snd_rpi_iqaudio_post_dapm_event(struct snd_soc_dapm_widget *w,
|
|
+ struct snd_kcontrol *kcontrol,
|
|
+ int event)
|
|
+{
|
|
+ switch (event) {
|
|
+ case SND_SOC_DAPM_POST_PMU:
|
|
+ /* Delay for mic bias ramp */
|
|
+ msleep(1000);
|
|
+ break;
|
|
+ default:
|
|
+ break;
|
|
+ }
|
|
+
|
|
+ return 0;
|
|
+}
|
|
+
|
|
+static const struct snd_soc_dapm_widget dapm_widgets[] = {
|
|
+ SND_SOC_DAPM_HP("HP Jack", NULL),
|
|
+ SND_SOC_DAPM_MIC("MIC Jack", NULL),
|
|
+ SND_SOC_DAPM_MIC("Onboard MIC", NULL),
|
|
+ SND_SOC_DAPM_LINE("AUX Jack", NULL),
|
|
+ SND_SOC_DAPM_SUPPLY("PLL Control", SND_SOC_NOPM, 0, 0,
|
|
+ snd_rpi_iqaudio_pll_control,
|
|
+ SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
|
|
+ SND_SOC_DAPM_POST("Post Power Up Event", snd_rpi_iqaudio_post_dapm_event),
|
|
+};
|
|
+
|
|
+static const struct snd_soc_dapm_route audio_map[] = {
|
|
+ {"HP Jack", NULL, "HPL"},
|
|
+ {"HP Jack", NULL, "HPR"},
|
|
+ {"HP Jack", NULL, "PLL Control"},
|
|
+
|
|
+ {"AUX Jack", NULL, "AUXR"},
|
|
+ {"AUX Jack", NULL, "AUXL"},
|
|
+ {"AUX Jack", NULL, "PLL Control"},
|
|
+
|
|
+ /* Assume Mic1 is linked to Headset and Mic2 to on-board mic */
|
|
+ {"MIC Jack", NULL, "MIC1"},
|
|
+ {"MIC Jack", NULL, "PLL Control"},
|
|
+ {"Onboard MIC", NULL, "MIC2"},
|
|
+ {"Onboard MIC", NULL, "PLL Control"},
|
|
+};
|
|
+
|
|
+/* machine stream operations */
|
|
+
|
|
+static int snd_rpi_iqaudio_codec_init(struct snd_soc_pcm_runtime *rtd)
|
|
+{
|
|
+ struct snd_soc_dai *codec_dai = rtd->codec_dai;
|
|
+ struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
|
|
+ int ret;
|
|
+
|
|
+ /* Set bclk ratio to align with codec's BCLK rate */
|
|
+ ret = snd_soc_dai_set_bclk_ratio(cpu_dai, 64);
|
|
+ if (ret) {
|
|
+ dev_err(rtd->dev, "Failed to set CPU BLCK ratio\n");
|
|
+ return ret;
|
|
+ }
|
|
+
|
|
+ /* Set MCLK frequency to codec, onboard 11.2896MHz clock */
|
|
+ return snd_soc_dai_set_sysclk(codec_dai, DA7213_CLKSRC_MCLK, 11289600,
|
|
+ SND_SOC_CLOCK_OUT);
|
|
+}
|
|
+
|
|
+static int snd_rpi_iqaudio_codec_hw_params(struct snd_pcm_substream *substream,
|
|
+ struct snd_pcm_hw_params *params)
|
|
+{
|
|
+ struct snd_soc_pcm_runtime *rtd = substream->private_data;
|
|
+ unsigned int samplerate = params_rate(params);
|
|
+
|
|
+ switch (samplerate) {
|
|
+ case 8000:
|
|
+ case 16000:
|
|
+ case 32000:
|
|
+ case 48000:
|
|
+ case 96000:
|
|
+ pll_out = DA7213_PLL_FREQ_OUT_98304000;
|
|
+ return 0;
|
|
+ case 44100:
|
|
+ case 88200:
|
|
+ pll_out = DA7213_PLL_FREQ_OUT_90316800;
|
|
+ return 0;
|
|
+ default:
|
|
+ dev_err(rtd->dev,"Unsupported samplerate %d\n", samplerate);
|
|
+ return -EINVAL;
|
|
+ }
|
|
+}
|
|
+
|
|
+static const struct snd_soc_ops snd_rpi_iqaudio_codec_ops = {
|
|
+ .hw_params = snd_rpi_iqaudio_codec_hw_params,
|
|
+};
|
|
+
|
|
+
|
|
+static struct snd_soc_dai_link snd_rpi_iqaudio_codec_dai[] = {
|
|
+{
|
|
+ .cpu_dai_name = "bcm2708-i2s.0",
|
|
+ .codec_dai_name = "da7213-hifi",
|
|
+ .platform_name = "bmc2708-i2s.0",
|
|
+ .codec_name = "da7213.1-001a",
|
|
+ .dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF |
|
|
+ SND_SOC_DAIFMT_CBM_CFM,
|
|
+ .init = snd_rpi_iqaudio_codec_init,
|
|
+ .ops = &snd_rpi_iqaudio_codec_ops,
|
|
+ .symmetric_rates = 1,
|
|
+ .symmetric_channels = 1,
|
|
+ .symmetric_samplebits = 1,
|
|
+},
|
|
+};
|
|
+
|
|
+/* audio machine driver */
|
|
+static struct snd_soc_card snd_rpi_iqaudio_codec = {
|
|
+ .owner = THIS_MODULE,
|
|
+ .dai_link = snd_rpi_iqaudio_codec_dai,
|
|
+ .num_links = ARRAY_SIZE(snd_rpi_iqaudio_codec_dai),
|
|
+ .dapm_widgets = dapm_widgets,
|
|
+ .num_dapm_widgets = ARRAY_SIZE(dapm_widgets),
|
|
+ .dapm_routes = audio_map,
|
|
+ .num_dapm_routes = ARRAY_SIZE(audio_map),
|
|
+};
|
|
+
|
|
+static int snd_rpi_iqaudio_codec_probe(struct platform_device *pdev)
|
|
+{
|
|
+ int ret = 0;
|
|
+
|
|
+ snd_rpi_iqaudio_codec.dev = &pdev->dev;
|
|
+
|
|
+ if (pdev->dev.of_node) {
|
|
+ struct device_node *i2s_node;
|
|
+ struct snd_soc_card *card = &snd_rpi_iqaudio_codec;
|
|
+ struct snd_soc_dai_link *dai = &snd_rpi_iqaudio_codec_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;
|
|
+ }
|
|
+
|
|
+ if (of_property_read_string(pdev->dev.of_node, "card_name",
|
|
+ &card->name))
|
|
+ card->name = "IQaudIOCODEC";
|
|
+
|
|
+ if (of_property_read_string(pdev->dev.of_node, "dai_name",
|
|
+ &dai->name))
|
|
+ dai->name = "IQaudIO CODEC";
|
|
+
|
|
+ if (of_property_read_string(pdev->dev.of_node,
|
|
+ "dai_stream_name", &dai->stream_name))
|
|
+ dai->stream_name = "IQaudIO CODEC HiFi v1.1";
|
|
+
|
|
+ }
|
|
+
|
|
+ ret = snd_soc_register_card(&snd_rpi_iqaudio_codec);
|
|
+ if (ret) {
|
|
+ if (ret != -EPROBE_DEFER)
|
|
+ dev_err(&pdev->dev,
|
|
+ "snd_soc_register_card() failed: %d\n", ret);
|
|
+ return ret;
|
|
+ }
|
|
+
|
|
+ return 0;
|
|
+}
|
|
+
|
|
+static int snd_rpi_iqaudio_codec_remove(struct platform_device *pdev)
|
|
+{
|
|
+ return snd_soc_unregister_card(&snd_rpi_iqaudio_codec);
|
|
+}
|
|
+
|
|
+static const struct of_device_id iqaudio_of_match[] = {
|
|
+ { .compatible = "iqaudio,iqaudio-codec", },
|
|
+ {},
|
|
+};
|
|
+
|
|
+MODULE_DEVICE_TABLE(of, iqaudio_of_match);
|
|
+
|
|
+static struct platform_driver snd_rpi_iqaudio_codec_driver = {
|
|
+ .driver = {
|
|
+ .name = "snd-rpi-iqaudio-codec",
|
|
+ .owner = THIS_MODULE,
|
|
+ .of_match_table = iqaudio_of_match,
|
|
+ },
|
|
+ .probe = snd_rpi_iqaudio_codec_probe,
|
|
+ .remove = snd_rpi_iqaudio_codec_remove,
|
|
+};
|
|
+
|
|
+
|
|
+
|
|
+module_platform_driver(snd_rpi_iqaudio_codec_driver);
|
|
+
|
|
+MODULE_AUTHOR("Gordon Garrity <gordon@iqaudio.com>");
|
|
+MODULE_DESCRIPTION("ASoC Driver for IQaudIO CODEC");
|
|
+MODULE_LICENSE("GPL v2");
|