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__);