]> rtime.felk.cvut.cz Git - sojka/nv-tegra/linux-3.10.git/commitdiff
asoc: tegra: add tegra machine driver
authorArun Kannan <akannan@nvidia.com>
Wed, 19 Mar 2014 19:48:09 +0000 (12:48 -0700)
committerBharat Nihalani <bnihalani@nvidia.com>
Tue, 15 Apr 2014 04:20:14 +0000 (21:20 -0700)
Add base machine driver for Tegra platforms
without codec.

Bug 1448381

Change-Id: Ibd391b878abadacaebd5ee1ee2d38a2eec5d526c
Signed-off-by: Arun Kannan <akannan@nvidia.com>
Reviewed-on: http://git-master/r/385846
Reviewed-by: Bharat Nihalani <bnihalani@nvidia.com>
Tested-by: Bharat Nihalani <bnihalani@nvidia.com>
sound/soc/tegra/Kconfig
sound/soc/tegra/Makefile
sound/soc/tegra/tegra_dummy_machine.c [new file with mode: 0644]

index 4bef390da0521060d6d32f8cedef4bd3a15f0d1d..31652893fcd68f1009038a216881e4c7c8347a82 100644 (file)
@@ -385,3 +385,13 @@ config SND_SOC_TEGRA_DMIC_REV1
          Say Y or M here if you want to add support for SoC audio on Tegra
          boards using the DMIC_REV1 codec. Currently, only supported board is
          E1664 (dolak).
+
+config SND_SOC_TEGRA_DUMMY
+       tristate "SoC Audio support for Tegra boards that doesn't use codecs"
+       depends on SND_SOC_TEGRA
+       select SND_SOC_TEGRA30_SPDIF if !ARCH_TEGRA_2x_SOC
+       select SND_SOC_SPDIF
+       help
+         Say Y or M here if you want to add support for SoC audio on Tegra
+         boards that doesn't use codecs (like SPDIF).
+         One such board is a customer board called Sandman.
index 5fa017bd8bf1be577303315bc46032c589b28875..0434fa19132eeec57830fa7e3eabab669000a314 100644 (file)
@@ -45,6 +45,7 @@ snd-soc-tegra-vcm-objs := tegra_vcm.o
 snd-soc-tegra-cs42l73-objs := tegra_cs42l73.o
 snd-soc-tegra-max98090-objs := tegra_max98090.o
 snd-soc-tegra-dmic-rev1-objs := tegra_dmic_rev1.o
+snd-soc-tegra-dummy-objs := tegra_dummy_machine.o
 
 obj-$(CONFIG_SND_SOC_TEGRA_WM8753) += snd-soc-tegra-wm8753.o
 obj-$(CONFIG_SND_SOC_TEGRA_WM8903) += snd-soc-tegra-wm8903.o
@@ -63,3 +64,4 @@ obj-$(CONFIG_SND_SOC_TEGRA_P852) += snd-soc-tegra-vcm.o
 obj-$(CONFIG_SND_SOC_TEGRA_CS42L73) += snd-soc-tegra-cs42l73.o
 obj-$(CONFIG_SND_SOC_TEGRA_MAX98090) += snd-soc-tegra-max98090.o
 obj-$(CONFIG_SND_SOC_TEGRA_DMIC_REV1) += snd-soc-tegra-dmic-rev1.o
+obj-$(CONFIG_SND_SOC_TEGRA_DUMMY) += snd-soc-tegra-dummy.o
diff --git a/sound/soc/tegra/tegra_dummy_machine.c b/sound/soc/tegra/tegra_dummy_machine.c
new file mode 100644 (file)
index 0000000..e0660f6
--- /dev/null
@@ -0,0 +1,214 @@
+/*
+ * tegra_dummy_machine.c - Tegra machine ASoC driver for boards
+ * that doesn't have codecs.
+ *
+ * Copyright (c) 2014, NVIDIA CORPORATION. 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 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.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA
+ *
+ */
+
+#include <linux/module.h>
+#include <linux/slab.h>
+
+#include <sound/soc.h>
+
+#include "tegra_asoc_utils.h"
+
+#define DRV_NAME "tegra-snd-dummy"
+
+#define DAI_LINK_SPDIF         0
+#define NUM_DAI_LINKS          1
+
+struct tegra_dummy_machine {
+       struct tegra_asoc_utils_data util_data;
+       struct snd_soc_card *pcard;
+};
+
+static int tegra_dummy_machine_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_card *card = rtd->card;
+       struct tegra_dummy_machine *machine = snd_soc_card_get_drvdata(card);
+       int srate, mclk, min_mclk;
+       int err;
+
+       srate = params_rate(params);
+       switch (srate) {
+       case 11025:
+       case 22050:
+       case 44100:
+       case 88200:
+               mclk = 11289600;
+               break;
+       case 8000:
+       case 16000:
+       case 32000:
+       case 48000:
+       case 64000:
+       case 96000:
+               mclk = 12288000;
+               break;
+       default:
+               return -EINVAL;
+       }
+       min_mclk = 128 * srate;
+
+       err = tegra_asoc_utils_set_rate(&machine->util_data, srate, mclk);
+       if (err < 0) {
+               if (!(machine->util_data.set_mclk % min_mclk))
+                       mclk = machine->util_data.set_mclk;
+               else {
+                       dev_err(card->dev, "Can't configure clocks\n");
+                       return err;
+               }
+       }
+
+       tegra_asoc_utils_lock_clk_rate(&machine->util_data, 1);
+
+       return 0;
+}
+
+static int tegra_hw_free(struct snd_pcm_substream *substream)
+{
+       struct snd_soc_pcm_runtime *rtd = substream->private_data;
+       struct snd_soc_card *card = rtd->card;
+       struct tegra_dummy_machine *machine = snd_soc_card_get_drvdata(card);
+
+       tegra_asoc_utils_lock_clk_rate(&machine->util_data, 0);
+
+       return 0;
+}
+
+static struct snd_soc_ops tegra_dummy_machine_ops = {
+       .hw_params = tegra_dummy_machine_hw_params,
+       .hw_free = tegra_hw_free,
+};
+
+static struct snd_soc_dai_link tegra_dummy_machine_dai[NUM_DAI_LINKS] = {
+       [DAI_LINK_SPDIF] = {
+               .name = "SPDIF",
+               .stream_name = "SPDIF PCM",
+               .codec_name = "spdif-dit.0",
+               .platform_name = "tegra30-spdif",
+               .cpu_dai_name = "tegra30-spdif",
+               .codec_dai_name = "dit-hifi",
+               .ops = &tegra_dummy_machine_ops,
+       },
+};
+
+static struct snd_soc_card snd_soc_tegra_dummy_machine = {
+       .name = "tegra-dummy",
+       .owner = THIS_MODULE,
+       .dai_link = tegra_dummy_machine_dai,
+       .num_links = ARRAY_SIZE(tegra_dummy_machine_dai),
+       .fully_routed = true,
+};
+
+
+static int tegra_dummy_machine_driver_probe(struct platform_device *pdev)
+{
+       struct snd_soc_card *card = &snd_soc_tegra_dummy_machine;
+       struct tegra_dummy_machine *machine;
+       int ret;
+
+       machine = kzalloc(sizeof(struct tegra_dummy_machine), GFP_KERNEL);
+       if (!machine) {
+               dev_err(&pdev->dev, "Can't allocate tegra_dummy_machine struct\n");
+               return -ENOMEM;
+       }
+
+       machine->pcard = card;
+
+       ret = tegra_asoc_utils_init(&machine->util_data, &pdev->dev, card);
+       if (ret)
+               goto err_free_machine;
+
+       card->dev = &pdev->dev;
+       platform_set_drvdata(pdev, card);
+       snd_soc_card_set_drvdata(card, machine);
+
+       ret = snd_soc_register_card(card);
+       if (ret) {
+               dev_err(&pdev->dev, "snd_soc_register_card failed (%d)\n",
+                       ret);
+               goto err_unregister_switch;
+       }
+
+       if (!card->instantiated) {
+               ret = -ENODEV;
+               dev_err(&pdev->dev, "sound card not instantiated (%d)\n",
+                       ret);
+               goto err_unregister_card;
+       }
+
+       return 0;
+
+err_unregister_card:
+       snd_soc_unregister_card(card);
+err_unregister_switch:
+       tegra_asoc_utils_fini(&machine->util_data);
+err_free_machine:
+       kfree(machine);
+
+       return ret;
+}
+
+static int tegra_dummy_machine_driver_remove(struct platform_device *pdev)
+{
+       struct snd_soc_card *card = platform_get_drvdata(pdev);
+       struct tegra_dummy_machine *machine = snd_soc_card_get_drvdata(card);
+
+       snd_soc_unregister_card(card);
+
+       tegra_asoc_utils_fini(&machine->util_data);
+
+       kfree(machine);
+
+       return 0;
+}
+
+static const struct of_device_id tegra_dummy_machine_of_match[] = {
+       { .compatible = "nvidia,tegra-audio-dummy", },
+       {},
+};
+
+static struct platform_driver tegra_dummy_machine_driver = {
+       .driver = {
+               .name = DRV_NAME,
+               .owner = THIS_MODULE,
+               .pm = &snd_soc_pm_ops,
+               .of_match_table = tegra_dummy_machine_of_match,
+       },
+       .probe = tegra_dummy_machine_driver_probe,
+       .remove = tegra_dummy_machine_driver_remove,
+};
+
+static int __init tegra_dummy_machine_modinit(void)
+{
+       return platform_driver_register(&tegra_dummy_machine_driver);
+}
+module_init(tegra_dummy_machine_modinit);
+
+static void __exit tegra_dummy_machine_modexit(void)
+{
+       platform_driver_unregister(&tegra_dummy_machine_driver);
+}
+module_exit(tegra_dummy_machine_modexit);
+
+MODULE_AUTHOR("Arun Kannan <akannan@nvidia.com>");
+MODULE_DESCRIPTION("Tegra+dummy machine ASoC driver");
+MODULE_LICENSE("GPL");
+MODULE_ALIAS("platform:" DRV_NAME);