ASoc-msm: Modify ASM drivers to invoke ION APIs

Create ION client and allocate buffers based on
the client handle and free the buffers when no
more needed

Change-Id: I00be9dbd3e8f5eff286d8f1bc0d61656866bf360
Signed-off-by: Swaminathan Sathappan <Swami@codeaurora.org>
diff --git a/include/sound/q6asm.h b/include/sound/q6asm.h
index d08f528..0fabc5b 100644
--- a/include/sound/q6asm.h
+++ b/include/sound/q6asm.h
@@ -15,6 +15,9 @@
 #include <mach/qdsp6v2/apr.h>
 #include <mach/msm_subsystem_map.h>
 #include <sound/apr_audio.h>
+#ifdef CONFIG_MSM_MULTIMEDIA_USE_ION
+#include <linux/ion.h>
+#endif
 
 #define IN                      0x000
 #define OUT                     0x001
@@ -94,10 +97,15 @@
 struct audio_buffer {
 	dma_addr_t phys;
 	void       *data;
-	struct msm_mapped_buffer *mem_buffer;
 	uint32_t   used;
 	uint32_t   size;/* size of buffer */
 	uint32_t   actual_size; /* actual number of bytes read by DSP */
+#ifdef CONFIG_MSM_MULTIMEDIA_USE_ION
+	struct ion_handle *handle;
+	struct ion_client *client;
+#else
+	struct msm_mapped_buffer *mem_buffer;
+#endif
 };
 
 struct audio_aio_write_param {
diff --git a/sound/soc/msm/qdsp6/q6asm.c b/sound/soc/msm/qdsp6/q6asm.c
index d822af5..73de89e 100644
--- a/sound/soc/msm/qdsp6/q6asm.c
+++ b/sound/soc/msm/qdsp6/q6asm.c
@@ -240,6 +240,13 @@
 
 		while (cnt >= 0) {
 			if (port->buf[cnt].data) {
+#ifdef CONFIG_MSM_MULTIMEDIA_USE_ION
+				ion_unmap_kernel(port->buf[cnt].client,
+						port->buf[cnt].handle);
+				ion_free(port->buf[cnt].client,
+						port->buf[cnt].handle);
+				ion_client_destroy(port->buf[cnt].client);
+#else
 				pr_debug("%s:data[%p]phys[%p][%p] cnt[%d]"
 					 "mem_buffer[%p]\n",
 					__func__, (void *)port->buf[cnt].data,
@@ -259,6 +266,7 @@
 				free_contiguous_memory_by_paddr(
 					port->buf[cnt].phys);
 
+#endif
 				port->buf[cnt].data = NULL;
 				port->buf[cnt].phys = 0;
 				--(port->max_buf_cnt);
@@ -295,6 +303,19 @@
 	}
 
 	if (port->buf[0].data) {
+#ifdef CONFIG_MSM_MULTIMEDIA_USE_ION
+		ion_unmap_kernel(port->buf[0].client, port->buf[0].handle);
+		ion_free(port->buf[0].client, port->buf[0].handle);
+		ion_client_destroy(port->buf[0].client);
+		pr_debug("%s:data[%p]phys[%p][%p]"
+			", client[%p] handle[%p]\n",
+			__func__,
+			(void *)port->buf[0].data,
+			(void *)port->buf[0].phys,
+			(void *)&port->buf[0].phys,
+			(void *)port->buf[0].client,
+			(void *)port->buf[0].handle);
+#else
 		pr_debug("%s:data[%p]phys[%p][%p]"
 			"mem_buffer[%p]\n",
 			__func__,
@@ -313,6 +334,7 @@
 					" failed\n", __func__);
 		}
 		free_contiguous_memory_by_paddr(port->buf[0].phys);
+#endif
 	}
 
 	while (cnt >= 0) {
@@ -465,6 +487,9 @@
 	int cnt = 0;
 	int rc = 0;
 	struct audio_buffer *buf;
+#ifdef CONFIG_MSM_MULTIMEDIA_USE_ION
+	int len;
+#endif
 
 	if (!(ac) || ((dir != IN) && (dir != OUT)))
 		return -EINVAL;
@@ -494,6 +519,50 @@
 		while (cnt < bufcnt) {
 			if (bufsz > 0) {
 				if (!buf[cnt].data) {
+#ifdef CONFIG_MSM_MULTIMEDIA_USE_ION
+					buf[cnt].client = msm_ion_client_create
+						(UINT_MAX, "audio_client");
+					if (IS_ERR_OR_NULL((void *)
+						buf[cnt].client)) {
+						pr_err("%s: ION create client"
+						" for AUDIO failed\n",
+						__func__);
+						goto fail;
+					}
+					buf[cnt].handle = ion_alloc
+						(buf[cnt].client, bufsz, SZ_4K,
+						(0x1 << ION_AUDIO_HEAP_ID));
+					if (IS_ERR_OR_NULL((void *)
+						buf[cnt].handle)) {
+						pr_err("%s: ION memory"
+					" allocation for AUDIO failed\n",
+							__func__);
+						goto fail;
+					}
+
+					rc = ion_phys(buf[cnt].client,
+						buf[cnt].handle,
+						(ion_phys_addr_t *)
+						&buf[cnt].phys,
+						(size_t *)&len);
+					if (rc) {
+						pr_err("%s: ION Get Physical"
+						" for AUDIO failed, rc = %d\n",
+							__func__, rc);
+						goto fail;
+					}
+
+					buf[cnt].data = ion_map_kernel
+					(buf[cnt].client, buf[cnt].handle,
+							 0);
+					if (IS_ERR_OR_NULL((void *)
+						buf[cnt].data)) {
+						pr_err("%s: ION memory"
+				" mapping for AUDIO failed\n", __func__);
+						goto fail;
+					}
+					memset((void *)buf[cnt].data, 0, bufsz);
+#else
 					unsigned int flags = 0;
 					buf[cnt].phys =
 					allocate_contiguous_ebi_nomap(bufsz,
@@ -526,16 +595,15 @@
 						mutex_unlock(&ac->cmd_lock);
 						goto fail;
 					}
+#endif
 					buf[cnt].used = 1;
 					buf[cnt].size = bufsz;
 					buf[cnt].actual_size = bufsz;
-					pr_debug("%s data[%p]phys[%p][%p]"
-						 "mem_buffer[%p]\n",
+					pr_debug("%s data[%p]phys[%p][%p]\n",
 						__func__,
 					   (void *)buf[cnt].data,
 					   (void *)buf[cnt].phys,
-					   (void *)&buf[cnt].phys,
-					   (void *)buf[cnt].mem_buffer);
+					   (void *)&buf[cnt].phys);
 					cnt++;
 				}
 			}
@@ -562,9 +630,12 @@
 {
 	int cnt = 0;
 	int rc = 0;
-	int flags = 0;
 	struct audio_buffer *buf;
-
+#ifdef CONFIG_MSM_MULTIMEDIA_USE_ION
+	int len;
+#else
+	int flags = 0;
+#endif
 	if (!(ac) || ((dir != IN) && (dir != OUT)))
 		return -EINVAL;
 
@@ -590,6 +661,35 @@
 
 	ac->port[dir].buf = buf;
 
+#ifdef CONFIG_MSM_MULTIMEDIA_USE_ION
+	buf[0].client = msm_ion_client_create(UINT_MAX, "audio_client");
+	if (IS_ERR_OR_NULL((void *)buf[0].client)) {
+		pr_err("%s: ION create client for AUDIO failed\n", __func__);
+		goto fail;
+	}
+	buf[0].handle = ion_alloc(buf[0].client, bufsz * bufcnt, SZ_4K,
+				  (0x1 << ION_AUDIO_HEAP_ID));
+	if (IS_ERR_OR_NULL((void *) buf[0].handle)) {
+		pr_err("%s: ION memory allocation for AUDIO failed\n",
+			__func__);
+		goto fail;
+	}
+
+	rc = ion_phys(buf[0].client, buf[0].handle,
+		  (ion_phys_addr_t *)&buf[0].phys, (size_t *)&len);
+	if (rc) {
+		pr_err("%s: ION Get Physical for AUDIO failed, rc = %d\n",
+			__func__, rc);
+		goto fail;
+	}
+
+	buf[0].data = ion_map_kernel(buf[0].client, buf[0].handle, 0);
+	if (IS_ERR_OR_NULL((void *) buf[0].data)) {
+		pr_err("%s: ION memory mapping for AUDIO failed\n", __func__);
+		goto fail;
+	}
+	memset((void *)buf[0].data, 0, (bufsz * bufcnt));
+#else
 	buf[0].phys = allocate_contiguous_ebi_nomap(bufsz * bufcnt,
 						SZ_4K);
 	if (!buf[0].phys) {
@@ -612,6 +712,7 @@
 		goto fail;
 	}
 	buf[0].data = buf[0].mem_buffer->vaddr;
+#endif
 	if (!buf[0].data) {
 		pr_err("%s:invalid vaddr,"
 			" iomap failed\n", __func__);