audio-lnx: Initial change for techpack of audio drivers.
Add snapshot for audio drivers for SDM targets. The code is
migrated from msm-4.9 kernel at the below cutoff -
(74ff856e8d6: "net: ipc_router: Add dynamic enable/disable
wakeup source feature")
This changes are done for new techpack addition
for audio kernel. Migrate all audio kernel drivers
to this techpack.
Change-Id: I33d580af3ba86a5cb777583efc5d4cdaf2882d93
Signed-off-by: Asish Bhattacharya <asishb@codeaurora.org>
diff --git a/sound/soc/msm/qdsp6v2/audio_slimslave.c b/sound/soc/msm/qdsp6v2/audio_slimslave.c
new file mode 100644
index 0000000..e9ecfd5
--- /dev/null
+++ b/sound/soc/msm/qdsp6v2/audio_slimslave.c
@@ -0,0 +1,177 @@
+/* Copyright (c) 2013-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/init.h>
+#include <linux/module.h>
+#include <linux/fs.h>
+#include <linux/device.h>
+#include <linux/mutex.h>
+#include <linux/miscdevice.h>
+#include <sound/audio_slimslave.h>
+#include <linux/slimbus/slimbus.h>
+#include <linux/pm_runtime.h>
+
+static struct slim_device *slim;
+static int vote_count;
+struct mutex suspend_lock;
+bool suspend;
+
+static int audio_slim_open(struct inode *inode, struct file *file)
+{
+ pr_debug("%s:\n", __func__);
+
+ if (vote_count) {
+ pr_debug("%s: unvote: vote_count=%d\n", __func__, vote_count);
+ pm_runtime_mark_last_busy(slim->dev.parent);
+ pm_runtime_put(slim->dev.parent);
+ vote_count--;
+ }
+ return 0;
+};
+
+static int audio_slim_release(struct inode *inode, struct file *file)
+{
+ pr_debug("%s:\n", __func__);
+
+ if (vote_count) {
+ pr_debug("%s: unvote: vote_count=%d\n", __func__, vote_count);
+ pm_runtime_mark_last_busy(slim->dev.parent);
+ pm_runtime_put(slim->dev.parent);
+ vote_count--;
+ } else {
+ pr_debug("%s: vote: vote_count=%d\n", __func__, vote_count);
+ pm_runtime_get_sync(slim->dev.parent);
+ vote_count++;
+ }
+ return 0;
+};
+
+static long audio_slim_ioctl(struct file *file, unsigned int cmd,
+ unsigned long u_arg)
+{
+ switch (cmd) {
+ case AUDIO_SLIMSLAVE_VOTE:
+ mutex_lock(&suspend_lock);
+ if (!vote_count && !suspend) {
+ pr_debug("%s:AUDIO_SLIMSLAVE_VOTE\n", __func__);
+ pm_runtime_get_sync(slim->dev.parent);
+ vote_count++;
+ } else {
+ pr_err("%s:Invalid vote: vote_count=%d suspend=%d\n",
+ __func__, vote_count, suspend);
+ }
+ mutex_unlock(&suspend_lock);
+ break;
+ case AUDIO_SLIMSLAVE_UNVOTE:
+ mutex_lock(&suspend_lock);
+ if (vote_count && !suspend) {
+ pr_debug("%s:AUDIO_SLIMSLAVE_UNVOTE\n", __func__);
+ pm_runtime_mark_last_busy(slim->dev.parent);
+ pm_runtime_put(slim->dev.parent);
+ vote_count--;
+ } else {
+ pr_err("%s:Invalid unvote: vote_count=%d suspend=%d\n",
+ __func__, vote_count, suspend);
+ }
+ mutex_unlock(&suspend_lock);
+ break;
+ default:
+ pr_debug("%s: Invalid ioctl cmd: %d\n", __func__, cmd);
+ break;
+ }
+ return 0;
+}
+
+static const struct file_operations audio_slimslave_fops = {
+ .open = audio_slim_open,
+ .unlocked_ioctl = audio_slim_ioctl,
+ .release = audio_slim_release,
+};
+
+struct miscdevice audio_slimslave_misc = {
+ .minor = MISC_DYNAMIC_MINOR,
+ .name = AUDIO_SLIMSLAVE_IOCTL_NAME,
+ .fops = &audio_slimslave_fops,
+};
+
+static int audio_slimslave_probe(struct slim_device *audio_slim)
+{
+ pr_debug("%s:\n", __func__);
+
+ mutex_init(&suspend_lock);
+ suspend = false;
+ slim = audio_slim;
+ misc_register(&audio_slimslave_misc);
+ return 0;
+}
+
+static int audio_slimslave_remove(struct slim_device *audio_slim)
+{
+ pr_debug("%s:\n", __func__);
+
+ misc_deregister(&audio_slimslave_misc);
+ return 0;
+}
+
+static int audio_slimslave_resume(struct slim_device *audio_slim)
+{
+ pr_debug("%s:\n", __func__);
+
+ mutex_lock(&suspend_lock);
+ suspend = false;
+ mutex_unlock(&suspend_lock);
+ return 0;
+}
+
+static int audio_slimslave_suspend(struct slim_device *audio_slim,
+ pm_message_t pmesg)
+{
+ pr_debug("%s:\n", __func__);
+
+ mutex_lock(&suspend_lock);
+ suspend = true;
+ mutex_unlock(&suspend_lock);
+ return 0;
+}
+
+static const struct slim_device_id audio_slimslave_dt_match[] = {
+ {"audio-slimslave", 0},
+ {}
+};
+
+static struct slim_driver audio_slimslave_driver = {
+ .driver = {
+ .name = "audio-slimslave",
+ .owner = THIS_MODULE,
+ },
+ .probe = audio_slimslave_probe,
+ .remove = audio_slimslave_remove,
+ .id_table = audio_slimslave_dt_match,
+ .resume = audio_slimslave_resume,
+ .suspend = audio_slimslave_suspend,
+};
+
+static int __init audio_slimslave_init(void)
+{
+ return slim_driver_register(&audio_slimslave_driver);
+}
+module_init(audio_slimslave_init);
+
+static void __exit audio_slimslave_exit(void)
+{
+
+}
+module_exit(audio_slimslave_exit);
+
+/* Module information */
+MODULE_DESCRIPTION("Audio side Slimbus slave driver");
+MODULE_LICENSE("GPL v2");