aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLinux Build Service Account <lnxbuild@localhost>2014-03-26 20:17:01 -0700
committerGerrit - the friendly Code Review server <code-review@localhost>2014-03-26 20:16:59 -0700
commitdf85eeadbc456f93c29cea2b3129e3088f21e9e4 (patch)
tree4ded30f6f36dad955ed5d3fe436b1e3e5ea6b3ac
parentec51a6ba3797147064215ce783dc28d7f3166ad2 (diff)
parent1a9d42e5b7b29e7c93f4ed1d1c73f8a91b634c87 (diff)
Merge "ASoC: msm: Add machine driver support for plutonium"
-rw-r--r--Documentation/devicetree/bindings/sound/qcom-audio-dev.txt13
-rw-r--r--sound/soc/msm/Kconfig15
-rw-r--r--sound/soc/msm/Makefile4
-rw-r--r--sound/soc/msm/msmplutonium.c347
4 files changed, 379 insertions, 0 deletions
diff --git a/Documentation/devicetree/bindings/sound/qcom-audio-dev.txt b/Documentation/devicetree/bindings/sound/qcom-audio-dev.txt
index 3e314fed47e..47c82d89d14 100644
--- a/Documentation/devicetree/bindings/sound/qcom-audio-dev.txt
+++ b/Documentation/devicetree/bindings/sound/qcom-audio-dev.txt
@@ -1091,3 +1091,16 @@ sound {
pinctrl-2 = <&pmx_pri_mi2s_sleep &pmx_quad_mi2s_active>;
pinctrl-3 = <&pmx_pri_mi2s_sleep &pmx_quad_mi2s_sleep>;
};
+
+* MSMPLUTONIUM ASoC Machine driver
+
+Required properties:
+- compatible : "qcom,msmplutonium-audio-tomtom"
+- qcom,model : The user-visible name of this sound card.
+
+Example:
+
+ sound {
+ compatible = "qcom,msmplutonium-asoc-snd";
+ qcom,model = "msmplutonium-tomtom-snd-card";
+ };
diff --git a/sound/soc/msm/Kconfig b/sound/soc/msm/Kconfig
index f0a02d50a48..9695e4614a8 100644
--- a/sound/soc/msm/Kconfig
+++ b/sound/soc/msm/Kconfig
@@ -268,4 +268,19 @@ config SND_SOC_MDM9630
help
To add support for SoC audio on MDM9630 boards.
+config SND_SOC_MSMPLUTONIUM
+ tristate "SoC Machine driver for MSMPLUTONIUM boards"
+ depends on ARCH_MSMPLUTONIUM
+ select SND_SOC_QDSP6V2
+ select SND_SOC_MSM_STUB
+ select SND_SOC_MSM_HOSTLESS_PCM
+ select SND_DYNAMIC_MINORS
+ select MSM_QDSP6_APRV2
+ help
+ To add support for SoC audio on MSMPLUTONIUM.
+ This will enable sound soc drivers which
+ interfaces with DSP, also it will enable
+ the machine drivers and the corresponding
+ DAI-links.
+
endmenu
diff --git a/sound/soc/msm/Makefile b/sound/soc/msm/Makefile
index 06fc318b12c..239df33dc84 100644
--- a/sound/soc/msm/Makefile
+++ b/sound/soc/msm/Makefile
@@ -86,3 +86,7 @@ obj-$(CONFIG_SND_SOC_MDM9630) += snd-soc-mdm9630.o
# for MSM 8x16 sound card driver
snd-soc-msm8x16-objs := msm8x16.o
obj-$(CONFIG_SND_SOC_MSM8X16) += snd-soc-msm8x16.o
+
+# for MSM PLUTONIUM sound card driver
+snd-soc-msmplutonium-objs := msmplutonium.o
+obj-$(CONFIG_SND_SOC_MSMPLUTONIUM) += snd-soc-msmplutonium.o
diff --git a/sound/soc/msm/msmplutonium.c b/sound/soc/msm/msmplutonium.c
new file mode 100644
index 00000000000..b67187791ad
--- /dev/null
+++ b/sound/soc/msm/msmplutonium.c
@@ -0,0 +1,347 @@
+/* Copyright (c) 2014, The Linux Foundation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only 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/clk.h>
+#include <linux/delay.h>
+#include <linux/gpio.h>
+#include <linux/of_gpio.h>
+#include <linux/platform_device.h>
+#include <linux/slab.h>
+#include <linux/qpnp/clkdiv.h>
+#include <linux/regulator/consumer.h>
+#include <linux/io.h>
+#include <linux/module.h>
+#include <sound/core.h>
+#include <sound/soc.h>
+#include <sound/soc-dapm.h>
+#include <sound/pcm.h>
+#include <sound/jack.h>
+#include <sound/q6afe-v2.h>
+#include <sound/pcm_params.h>
+#include "qdsp6v2/msm-pcm-routing-v2.h"
+#include "qdsp6v2/q6core.h"
+
+#define DRV_NAME "msmplutonium-asoc-snd"
+
+struct msm_auxpcm_gpio {
+ unsigned gpio_no;
+ const char *gpio_name;
+};
+
+
+struct msm_auxpcm_ctrl {
+ struct msm_auxpcm_gpio *pin_data;
+ u32 cnt;
+ void __iomem *mux;
+};
+
+struct msmplutonium_asoc_mach_data {
+ struct msm_auxpcm_ctrl *pri_auxpcm_ctrl;
+};
+
+
+static int msm_auxpcm_be_params_fixup(struct snd_soc_pcm_runtime *rtd,
+ struct snd_pcm_hw_params *params)
+{
+ return 0;
+}
+
+
+static int msm_prim_auxpcm_startup(struct snd_pcm_substream *substream)
+{
+ return 0;
+}
+
+static void msm_prim_auxpcm_shutdown(struct snd_pcm_substream *substream)
+{
+}
+
+static struct snd_soc_ops msm_pri_auxpcm_be_ops = {
+ .startup = msm_prim_auxpcm_startup,
+ .shutdown = msm_prim_auxpcm_shutdown,
+};
+
+#define SAMPLING_RATE_48KHZ 48000
+static int msm_slim_0_rx_ch = 1;
+static int msm_slim_0_tx_ch = 1;
+static int slim0_rx_sample_rate = SAMPLING_RATE_48KHZ;
+static int slim0_rx_bit_format = SNDRV_PCM_FORMAT_S16_LE;
+
+static inline int param_is_mask(int p)
+{
+ return ((p >= SNDRV_PCM_HW_PARAM_FIRST_MASK) &&
+ (p <= SNDRV_PCM_HW_PARAM_LAST_MASK));
+}
+
+static inline struct snd_mask *param_to_mask(struct snd_pcm_hw_params *p, int n)
+{
+ return &(p->masks[n - SNDRV_PCM_HW_PARAM_FIRST_MASK]);
+}
+
+static void param_set_mask(struct snd_pcm_hw_params *p, int n, unsigned bit)
+{
+ if (bit >= SNDRV_MASK_MAX)
+ return;
+ if (param_is_mask(n)) {
+ struct snd_mask *m = param_to_mask(p, n);
+ m->bits[0] = 0;
+ m->bits[1] = 0;
+ m->bits[bit >> 5] |= (1 << (bit & 31));
+ }
+}
+
+
+static int msm_slim_0_rx_be_hw_params_fixup(struct snd_soc_pcm_runtime *rtd,
+ struct snd_pcm_hw_params *params)
+{
+ 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);
+
+ pr_debug("%s()\n", __func__);
+ param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT,
+ slim0_rx_bit_format);
+ rate->min = rate->max = slim0_rx_sample_rate;
+ channels->min = channels->max = msm_slim_0_rx_ch;
+
+ pr_debug("%s: format = %d, rate = %d, channels = %d\n",
+ __func__, params_format(params), params_rate(params),
+ msm_slim_0_rx_ch);
+
+ return 0;
+}
+
+static int msm_slim_0_tx_be_hw_params_fixup(struct snd_soc_pcm_runtime *rtd,
+ struct snd_pcm_hw_params *params)
+{
+ 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);
+
+ pr_debug("%s()\n", __func__);
+ param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT,
+ slim0_rx_bit_format);
+ rate->min = rate->max = 48000;
+ channels->min = channels->max = msm_slim_0_tx_ch;
+
+ return 0;
+}
+
+static int msmplutonium_snd_startup(struct snd_pcm_substream *substream)
+{
+ pr_debug("%s(): substream = %s stream = %d\n", __func__,
+ substream->name, substream->stream);
+ return 0;
+}
+
+static int msm_snd_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 *cpu_dai = rtd->cpu_dai;
+ unsigned int rx_ch[] = {144, 145, 146, 147, 148, 149, 150,
+ 151, 152, 153, 154, 155, 156};
+ unsigned int tx_ch[] = {128, 129, 130, 131, 132, 133,
+ 134, 135, 136, 137, 138, 139,
+ 140, 141, 142, 143};
+ int ret = -EINVAL;
+
+ if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
+ ret = snd_soc_dai_set_channel_map(cpu_dai, 0, 0,
+ msm_slim_0_rx_ch, rx_ch);
+ if (ret < 0)
+ pr_err("%s: RX failed to set cpu chan map error %d\n",
+ __func__, ret);
+ } else {
+ ret = snd_soc_dai_set_channel_map(cpu_dai, 0, 0,
+ msm_slim_0_tx_ch, tx_ch);
+ if (ret < 0)
+ pr_err("%s: TX failed to set cpu chan map error %d\n",
+ __func__, ret);
+
+ }
+ return ret;
+}
+
+static void msmplutonium_snd_shudown(struct snd_pcm_substream *substream)
+{
+ pr_debug("%s(): substream = %s stream = %d\n", __func__,
+ substream->name, substream->stream);
+
+}
+
+static struct snd_soc_ops msmplutonium_be_ops = {
+ .startup = msmplutonium_snd_startup,
+ .hw_params = msm_snd_hw_params,
+ .shutdown = msmplutonium_snd_shudown,
+};
+
+
+/* Digital audio interface glue - connects codec <---> CPU */
+static struct snd_soc_dai_link msmplutonium_common_dai_links[] = {
+ /* FrontEnd DAI Links */
+ {
+ .name = "MSMplutonium Media1",
+ .stream_name = "MultiMedia1",
+ .cpu_dai_name = "MultiMedia1",
+ .platform_name = "msm-pcm-dsp.0",
+ .dynamic = 1,
+ .trigger = {SND_SOC_DPCM_TRIGGER_POST,
+ SND_SOC_DPCM_TRIGGER_POST},
+ .codec_dai_name = "snd-soc-dummy-dai",
+ .codec_name = "snd-soc-dummy",
+ .ignore_suspend = 1,
+ /* this dainlink has playback support */
+ .ignore_pmdown_time = 1,
+ .be_id = MSM_FRONTEND_DAI_MULTIMEDIA1
+ },
+ /* Primary AUX PCM Backend DAI Links */
+ {
+ .name = LPASS_BE_AUXPCM_RX,
+ .stream_name = "AUX PCM Playback",
+ .cpu_dai_name = "msm-dai-q6-auxpcm.1",
+ .platform_name = "msm-pcm-routing",
+ .codec_name = "msm-stub-codec.1",
+ .codec_dai_name = "msm-stub-rx",
+ .no_pcm = 1,
+ .be_id = MSM_BACKEND_DAI_AUXPCM_RX,
+ .be_hw_params_fixup = msm_auxpcm_be_params_fixup,
+ .ops = &msm_pri_auxpcm_be_ops,
+ .ignore_pmdown_time = 1,
+ .ignore_suspend = 1,
+ /* this dainlink has playback support */
+ },
+ {
+ .name = LPASS_BE_AUXPCM_TX,
+ .stream_name = "AUX PCM Capture",
+ .cpu_dai_name = "msm-dai-q6-auxpcm.1",
+ .platform_name = "msm-pcm-routing",
+ .codec_name = "msm-stub-codec.1",
+ .codec_dai_name = "msm-stub-tx",
+ .no_pcm = 1,
+ .be_id = MSM_BACKEND_DAI_AUXPCM_TX,
+ .be_hw_params_fixup = msm_auxpcm_be_params_fixup,
+ .ops = &msm_pri_auxpcm_be_ops,
+ .ignore_suspend = 1,
+ },
+ /* Backend DAI Links */
+ {
+ .name = LPASS_BE_SLIMBUS_0_RX,
+ .stream_name = "Slimbus Playback",
+ .cpu_dai_name = "msm-dai-q6-dev.16384",
+ .platform_name = "msm-pcm-routing",
+ .codec_name = "msm-stub-codec.1",
+ .codec_dai_name = "msm-stub-rx",
+ .no_pcm = 1,
+ .be_id = MSM_BACKEND_DAI_SLIMBUS_0_RX,
+ .be_hw_params_fixup = msm_slim_0_rx_be_hw_params_fixup,
+ .ignore_pmdown_time = 1, /* dai link has playback support */
+ .ignore_suspend = 1,
+ .ops = &msmplutonium_be_ops,
+ },
+ {
+ .name = LPASS_BE_SLIMBUS_0_TX,
+ .stream_name = "Slimbus Capture",
+ .cpu_dai_name = "msm-dai-q6-dev.16385",
+ .platform_name = "msm-pcm-routing",
+ .codec_name = "msm-stub-codec.1",
+ .codec_dai_name = "msm-stub-tx",
+ .no_pcm = 1,
+ .be_id = MSM_BACKEND_DAI_SLIMBUS_0_TX,
+ .be_hw_params_fixup = msm_slim_0_tx_be_hw_params_fixup,
+ .ignore_suspend = 1,
+ .ops = &msmplutonium_be_ops,
+ },
+
+
+};
+
+struct snd_soc_card snd_soc_card_msmplutonium = {
+ .name = "msmplutonium-tomtom-snd-card",
+};
+
+
+
+static int msmplutonium_asoc_machine_probe(struct platform_device *pdev)
+{
+ struct snd_soc_card *card = &snd_soc_card_msmplutonium;
+ struct msmplutonium_asoc_mach_data *pdata;
+ int ret;
+ if (!pdev->dev.of_node) {
+ dev_err(&pdev->dev, "No platform supplied from device tree\n");
+ return -EINVAL;
+ }
+
+ pdata = devm_kzalloc(&pdev->dev,
+ sizeof(struct msmplutonium_asoc_mach_data), GFP_KERNEL);
+ if (!pdata) {
+ dev_err(&pdev->dev, "Can't allocate msmplutonium_asoc_mach_data\n");
+ return -ENOMEM;
+ }
+
+ card->dev = &pdev->dev;
+ platform_set_drvdata(pdev, card);
+ snd_soc_card_set_drvdata(card, pdata);
+
+ ret = snd_soc_of_parse_card_name(card, "qcom,model");
+ if (ret)
+ goto err;
+
+ card->dai_link = msmplutonium_common_dai_links;
+ card->num_links = ARRAY_SIZE(msmplutonium_common_dai_links);
+
+ ret = snd_soc_register_card(card);
+ if (ret) {
+ dev_err(&pdev->dev, "snd_soc_register_card failed (%d)\n",
+ ret);
+ goto err;
+ }
+
+ return 0;
+err:
+ devm_kfree(&pdev->dev, pdata);
+ return ret;
+}
+
+static int msmplutonium_asoc_machine_remove(struct platform_device *pdev)
+{
+ struct snd_soc_card *card = platform_get_drvdata(pdev);
+ snd_soc_unregister_card(card);
+ return 0;
+}
+
+static const struct of_device_id msmplutonium_asoc_machine_of_match[] = {
+ { .compatible = "qcom,msmplutonium-asoc-snd", },
+ {},
+};
+
+static struct platform_driver msmplutonium_asoc_machine_driver = {
+ .driver = {
+ .name = DRV_NAME,
+ .owner = THIS_MODULE,
+ .pm = &snd_soc_pm_ops,
+ .of_match_table = msmplutonium_asoc_machine_of_match,
+ },
+ .probe = msmplutonium_asoc_machine_probe,
+ .remove = msmplutonium_asoc_machine_remove,
+};
+module_platform_driver(msmplutonium_asoc_machine_driver);
+
+MODULE_DESCRIPTION("ALSA SoC msm");
+MODULE_LICENSE("GPL v2");
+MODULE_ALIAS("platform:" DRV_NAME);
+MODULE_DEVICE_TABLE(of, msmplutonium_asoc_machine_of_match);